mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-03-01 02:03:22 +00:00
PI timestamps
This commit is contained in:
@@ -28,6 +28,7 @@ angular.module("ofn.admin").controller "AdminProductEditCtrl", ($scope, $timeout
|
||||
$scope.filterTaxons = [{id: "0", name: ""}].concat $scope.taxons
|
||||
$scope.producerFilter = "0"
|
||||
$scope.categoryFilter = "0"
|
||||
$scope.importDateFilter = ""
|
||||
$scope.products = BulkProducts.products
|
||||
$scope.filteredProducts = []
|
||||
$scope.currentFilters = []
|
||||
@@ -43,7 +44,7 @@ angular.module("ofn.admin").controller "AdminProductEditCtrl", ($scope, $timeout
|
||||
.catch (message) ->
|
||||
$scope.api_error_msg = message
|
||||
|
||||
$scope.$watchCollection '[query, producerFilter, categoryFilter]', ->
|
||||
$scope.$watchCollection '[query, producerFilter, categoryFilter, importDateFilter]', ->
|
||||
$scope.limit = 15 # Reset limit whenever searching
|
||||
|
||||
$scope.fetchProducts = ->
|
||||
@@ -91,6 +92,7 @@ angular.module("ofn.admin").controller "AdminProductEditCtrl", ($scope, $timeout
|
||||
$scope.query = ""
|
||||
$scope.producerFilter = "0"
|
||||
$scope.categoryFilter = "0"
|
||||
$scope.importDateFilter = "0"
|
||||
|
||||
$scope.editWarn = (product, variant) ->
|
||||
if (DirtyProducts.count() > 0 and confirm(t("unsaved_changes_confirmation"))) or (DirtyProducts.count() == 0)
|
||||
|
||||
@@ -4,6 +4,7 @@ require 'open_food_network/referer_parser'
|
||||
Spree::Admin::ProductsController.class_eval do
|
||||
include OpenFoodNetwork::SpreeApiKeyLoader
|
||||
include OrderCyclesHelper
|
||||
include EnterprisesHelper
|
||||
before_filter :load_form_data, :only => [:bulk_edit, :new, :create, :edit, :update]
|
||||
before_filter :load_spree_api_key, :only => [:bulk_edit, :variant_overrides]
|
||||
before_filter :strip_new_properties, only: [:create, :update]
|
||||
@@ -95,6 +96,21 @@ Spree::Admin::ProductsController.class_eval do
|
||||
def load_form_data
|
||||
@producers = OpenFoodNetwork::Permissions.new(spree_current_user).managed_product_enterprises.is_primary_producer.by_name
|
||||
@taxons = Spree::Taxon.order(:name)
|
||||
import_dates = [{id: '0', name: ''}]
|
||||
product_import_dates.map {|i| import_dates.push({id: i, name: i.to_formatted_s(:long)}) }
|
||||
@import_dates = import_dates.to_json
|
||||
end
|
||||
|
||||
def product_import_dates
|
||||
import_dates = Spree::Variant.
|
||||
select('spree_variants.import_date').
|
||||
joins(:product).
|
||||
where('spree_products.supplier_id IN (?)
|
||||
AND spree_variants.is_master = false
|
||||
AND spree_variants.import_date IS NOT NULL
|
||||
AND spree_variants.deleted_at IS NULL', editable_enterprises.collect(&:id))
|
||||
|
||||
import_dates.uniq.collect(&:import_date).sort.reverse
|
||||
end
|
||||
|
||||
def strip_new_properties
|
||||
|
||||
@@ -174,6 +174,15 @@ Spree::Product.class_eval do
|
||||
order_cycle.variants_distributed_by(distributor).where(product_id: self)
|
||||
end
|
||||
|
||||
def import_date
|
||||
# Get the most recent import_date of a product's variants
|
||||
imports = []
|
||||
variants.each do |v|
|
||||
imports.append(v) unless v.import_date.blank?
|
||||
end
|
||||
imports.sort_by(&:import_date).last.try(:import_date)
|
||||
end
|
||||
|
||||
# Build a product distribution for each distributor
|
||||
def build_product_distributions_for_user user
|
||||
Enterprise.is_distributor.managed_by(user).each do |distributor|
|
||||
|
||||
@@ -10,13 +10,12 @@ Spree::Variant.class_eval do
|
||||
remove_method :options_text if instance_methods(false).include? :options_text
|
||||
include OpenFoodNetwork::VariantAndLineItemNaming
|
||||
|
||||
|
||||
has_many :exchange_variants
|
||||
has_many :exchanges, through: :exchange_variants
|
||||
has_many :variant_overrides
|
||||
has_many :inventory_items
|
||||
|
||||
attr_accessible :unit_value, :unit_description, :images_attributes, :display_as, :display_name
|
||||
attr_accessible :unit_value, :unit_description, :images_attributes, :display_as, :display_name, :import_date
|
||||
accepts_nested_attributes_for :images
|
||||
|
||||
validates_presence_of :unit_value,
|
||||
@@ -30,7 +29,6 @@ Spree::Variant.class_eval do
|
||||
after_save :refresh_products_cache
|
||||
around_destroy :destruction
|
||||
|
||||
|
||||
scope :with_order_cycles_inner, joins(exchanges: :order_cycle)
|
||||
|
||||
scope :not_deleted, where(deleted_at: nil)
|
||||
@@ -117,7 +115,6 @@ Spree::Variant.class_eval do
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
def update_weight_from_unit_value
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
class Api::Admin::ProductSerializer < ActiveModel::Serializer
|
||||
attributes :id, :name, :sku, :variant_unit, :variant_unit_scale, :variant_unit_name, :on_demand, :inherits_properties
|
||||
|
||||
attributes :on_hand, :price, :available_on, :permalink_live, :tax_category_id, :image_url, :thumb_url
|
||||
attributes :on_hand, :price, :available_on, :permalink_live, :tax_category_id, :import_date, :image_url, :thumb_url
|
||||
|
||||
has_one :supplier, key: :producer_id, embed: :id
|
||||
has_one :primary_taxon, key: :category_id, embed: :id
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
class Api::Admin::VariantSerializer < ActiveModel::Serializer
|
||||
attributes :id, :options_text, :unit_value, :unit_description, :unit_to_display, :on_demand, :display_as, :display_name, :name_to_display, :sku
|
||||
attributes :on_hand, :price
|
||||
attributes :on_hand, :price, :import_date
|
||||
has_many :variant_overrides
|
||||
|
||||
def on_hand
|
||||
|
||||
@@ -1,16 +1,21 @@
|
||||
.filters.sixteen.columns.alpha.omega
|
||||
.quick_search.four.columns.alpha
|
||||
.quick_search.three.columns.alpha
|
||||
%label{ :for => 'quick_filter' }
|
||||
%br
|
||||
%input.quick-search.fullwidth{ 'ng-model' => 'query', :name => "quick_filter", :type => 'text', 'placeholder' => t('admin.quick_search') }
|
||||
.filter_select.four.columns
|
||||
.filter_select.three.columns
|
||||
%label{ :for => 'producer_filter' }= t 'producer'
|
||||
%br
|
||||
%select.fullwidth{ :id => 'producer_filter', 'ofn-select2-min-search' => 5, 'ng-model' => 'producerFilter', 'ng-options' => 'producer.id as producer.name for producer in filterProducers' }
|
||||
.filter_select.four.columns
|
||||
.filter_select.three.columns
|
||||
%label{ :for => 'category_filter' }= t 'category'
|
||||
%br
|
||||
%select.fullwidth{ :id => 'category_filter', 'ofn-select2-min-search' => 5, 'ng-model' => 'categoryFilter', 'ng-options' => 'taxon.id as taxon.name for taxon in filterTaxons'}
|
||||
.filter_select.three.columns
|
||||
%label{ :for => 'import_filter' } Import Date
|
||||
%br
|
||||
%select.fullwidth{ :id => 'import_date_filter', 'ofn-select2-min-search' => 5, 'ng-model' => 'importDateFilter', 'ng-init' => "import_dates = #{@import_dates}", 'ng-options' => 'import.id as import.name for import in import_dates'}
|
||||
|
||||
%div{ :class => "one column" }
|
||||
.filter_clear.three.columns.omega
|
||||
%label{ :for => 'clear_all_filters' }
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
= render 'spree/admin/products/bulk_edit/products_head'
|
||||
|
||||
%tbody{ 'ng-repeat' => 'product in filteredProducts = ( products | filter:query | producer: producerFilter | category: categoryFilter | limitTo:limit )', 'ng-class-even' => "'even'", 'ng-class-odd' => "'odd'" }
|
||||
%tbody{ 'ng-repeat' => 'product in filteredProducts = ( products | filter:query | producer: producerFilter | category: categoryFilter | filter: (importDateFilter != 0) && {import_date: importDateFilter} | limitTo:limit )', 'ng-class-even' => "'even'", 'ng-class-odd' => "'odd'" }
|
||||
|
||||
= render 'spree/admin/products/bulk_edit/products_product'
|
||||
= render 'spree/admin/products/bulk_edit/products_variant'
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
%col.tax_category{ ng: { show: 'columns.tax_category.visible' } }
|
||||
%col.inherits_properties{ ng: { show: 'columns.inherits_properties.visible' } }
|
||||
%col.available_on{ ng: { show: 'columns.available_on.visible' } }
|
||||
%col.import_date{ ng: { show: 'columns.import_date.visible' } }
|
||||
%col.actions
|
||||
%col.actions
|
||||
%col.actions
|
||||
@@ -35,6 +36,7 @@
|
||||
%th.tax_category{ 'ng-show' => 'columns.tax_category.visible' }=t('.tax_category')
|
||||
%th.inherits_properties{ 'ng-show' => 'columns.inherits_properties.visible' }=t('.inherits_properties?')
|
||||
%th.available_on{ 'ng-show' => 'columns.available_on.visible' }=t('.av_on')
|
||||
%th.import_date{ 'ng-show' => 'columns.import_date.visible' }=t('.import_date')
|
||||
%th.actions
|
||||
%th.actions
|
||||
%th.actions
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
%input{ 'ng-model' => 'product.inherits_properties', :name => 'inherits_properties', 'ofn-track-product' => 'inherits_properties', type: "checkbox" }
|
||||
%td.available_on{ 'ng-show' => 'columns.available_on.visible' }
|
||||
%input{ 'ng-model' => 'product.available_on', :name => 'available_on', 'ofn-track-product' => 'available_on', 'datetimepicker' => 'product.available_on', type: "text" }
|
||||
%td.import_date{ 'ng-show' => 'columns.import_date.visible' }
|
||||
%span {{(product.import_date | date:"MMMM dd, yyyy HH:mm") || ""}}
|
||||
%td.actions
|
||||
%a{ 'ng-click' => 'editWarn(product)', :class => "edit-product icon-edit no-text", 'ofn-with-tip' => t(:edit) }
|
||||
%td.actions
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
%td{ 'ng-show' => 'columns.tax_category.visible' }
|
||||
%td{ 'ng-show' => 'columns.inherits_properties.visible' }
|
||||
%td{ 'ng-show' => 'columns.available_on.visible' }
|
||||
%td{ 'ng-show' => 'columns.import_date.visible' }
|
||||
%span {{variant.import_date | date:"MMMM dd, yyyy HH:mm"}}
|
||||
%td.actions
|
||||
%a{ 'ng-click' => 'editWarn(product,variant)', :class => "edit-variant icon-edit no-text", 'ng-show' => "variantSaved(variant)", 'ofn-with-tip' => t(:edit) }
|
||||
%td.actions
|
||||
|
||||
@@ -459,6 +459,7 @@ en:
|
||||
inherits_properties?: Inherits Properties?
|
||||
available_on: Available On
|
||||
av_on: "Av. On"
|
||||
import_date: Imported
|
||||
upload_an_image: Upload an image
|
||||
product_search_keywords: Product Search Keywords
|
||||
product_search_tip: Type words to help search your products in the shops. Use space to separate each keyword.
|
||||
|
||||
@@ -264,6 +264,15 @@ en_GB:
|
||||
manages: manages
|
||||
products:
|
||||
unit_name_placeholder: 'eg. bunches'
|
||||
bulk_edit:
|
||||
unit: Unit
|
||||
display_as: Display As
|
||||
category: Category
|
||||
tax_category: Tax Category
|
||||
inherits_properties?: Inherits Properties?
|
||||
available_on: Available On
|
||||
av_on: "Av. On"
|
||||
import_date: Imported
|
||||
Search: Search
|
||||
properties:
|
||||
property_name: Property Name
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
class AddImportDateToSpreeVariants < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :spree_variants, :import_date, :datetime
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
class AddImportDateToVariantOverrides < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :variant_overrides, :import_date, :datetime
|
||||
end
|
||||
end
|
||||
@@ -1058,6 +1058,7 @@ ActiveRecord::Schema.define(:version => 20180316034336) do
|
||||
t.string "unit_description", :default => ""
|
||||
t.string "display_name"
|
||||
t.string "display_as"
|
||||
t.datetime "import_date"
|
||||
end
|
||||
|
||||
add_index "spree_variants", ["product_id"], :name => "index_variants_on_product_id"
|
||||
@@ -1176,6 +1177,7 @@ ActiveRecord::Schema.define(:version => 20180316034336) do
|
||||
t.string "sku"
|
||||
t.boolean "on_demand"
|
||||
t.datetime "permission_revoked_at"
|
||||
t.datetime "import_date"
|
||||
end
|
||||
|
||||
add_index "variant_overrides", ["variant_id", "hub_id"], :name => "index_variant_overrides_on_variant_id_and_hub_id"
|
||||
|
||||
@@ -68,7 +68,8 @@ module OpenFoodNetwork
|
||||
category: { name: I18n.t("#{node}.category"), visible: false },
|
||||
tax_category: { name: I18n.t("#{node}.tax_category"), visible: false },
|
||||
inherits_properties: { name: I18n.t("#{node}.inherits_properties?"), visible: false },
|
||||
available_on: { name: I18n.t("#{node}.available_on"), visible: false }
|
||||
available_on: { name: I18n.t("#{node}.available_on"), visible: false },
|
||||
import_date: { name: I18n.t("#{node}.import_date"), visible: false }
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user