diff --git a/app/assets/javascripts/admin/bulk_product_update.js.coffee b/app/assets/javascripts/admin/bulk_product_update.js.coffee index e0d67d1747..db1d078d73 100644 --- a/app/assets/javascripts/admin/bulk_product_update.js.coffee +++ b/app/assets/javascripts/admin/bulk_product_update.js.coffee @@ -6,7 +6,7 @@ angular.module("ofn.admin").controller "AdminProductEditCtrl", [ style: {} $scope.columns = - supplier: {name: "Supplier", visible: true} + producer: {name: "Producer", visible: true} name: {name: "Name", visible: true} unit: {name: "Unit", visible: true} price: {name: "Price", visible: true} @@ -17,7 +17,7 @@ angular.module("ofn.admin").controller "AdminProductEditCtrl", [ $scope.variant_unit_options = VariantUnitManager.variantUnitOptions() $scope.filterableColumns = [ - { name: "Supplier", db_column: "supplier_name" }, + { name: "Producer", db_column: "producer_name" }, { name: "Name", db_column: "name" } ] @@ -57,21 +57,20 @@ angular.module("ofn.admin").controller "AdminProductEditCtrl", [ if $scope.spree_api_key_ok $http.defaults.headers.common["X-Spree-Token"] = spree_api_key dataFetcher("/api/enterprises/managed?template=bulk_index&q[is_primary_producer_eq]=true").then (data) -> - $scope.suppliers = data - # Need to have suppliers before we get products so we can match suppliers to product.supplier + $scope.producers = data + # Need to have producers before we get products so we can match producers to product.producer $scope.fetchProducts() else if authorise_api_reponse.hasOwnProperty("error") $scope.api_error_msg = authorise_api_reponse("error") else api_error_msg = "You don't have an API key yet. An attempt was made to generate one, but you are currently not authorised, please contact your site administrator for access." - $scope.fetchProducts = -> # WARNING: returns a promise $scope.loading = true queryString = $scope.currentFilters.reduce (qs,f) -> return qs + "q[#{f.property.db_column}_#{f.predicate.predicate}]=#{f.value};" , "" - return dataFetcher("/api/products/managed?template=bulk_index;page=1;per_page=500;#{queryString}").then (data) -> + return dataFetcher("/api/products/bulk_products?page=1;per_page=500;#{queryString}").then (data) -> $scope.resetProducts data $scope.loading = false @@ -88,15 +87,15 @@ angular.module("ofn.admin").controller "AdminProductEditCtrl", [ $scope.unpackProduct = (product) -> $scope.displayProperties ||= {} $scope.displayProperties[product.id] ||= showVariants: false - $scope.matchSupplier product + $scope.matchProducer product $scope.loadVariantUnit product - $scope.matchSupplier = (product) -> - for i of $scope.suppliers - supplier = $scope.suppliers[i] - if angular.equals(supplier, product.supplier) - product.supplier = supplier + $scope.matchProducer = (product) -> + for i of $scope.producers + producer = $scope.producers[i] + if angular.equals(producer.id, product.producer) + product.producer = producer break @@ -252,7 +251,7 @@ angular.module("ofn.admin").controller "AdminProductEditCtrl", [ $scope.hasVariants = (product) -> - Object.keys(product.variants).length > 0 + product.variants.length > 0 $scope.hasUnit = (product) -> @@ -397,8 +396,8 @@ filterSubmitProducts = (productsToFilter) -> if product.hasOwnProperty("name") filteredProduct.name = product.name hasUpdatableProperty = true - if product.hasOwnProperty("supplier") - filteredProduct.supplier_id = product.supplier.id + if product.hasOwnProperty("producer") + filteredProduct.supplier_id = product.producer.id hasUpdatableProperty = true if product.hasOwnProperty("price") filteredProduct.price = product.price diff --git a/app/controllers/spree/api/products_controller_decorator.rb b/app/controllers/spree/api/products_controller_decorator.rb index 77c1aa6632..8e3c8f9c84 100644 --- a/app/controllers/spree/api/products_controller_decorator.rb +++ b/app/controllers/spree/api/products_controller_decorator.rb @@ -7,6 +7,10 @@ Spree::Api::ProductsController.class_eval do respond_with(@products, default_template: :index) end + def bulk_products + @products = product_scope.ransack(params[:q]).result.managed_by(current_api_user).page(params[:page]).per(params[:per_page]) + render text: ActiveModel::ArraySerializer.new(@products, each_serializer: Spree::Api::ProductSerializer).to_json + end def soft_delete authorize! :delete, Spree::Product diff --git a/app/serializers/spree/api/product_serializer.rb b/app/serializers/spree/api/product_serializer.rb new file mode 100644 index 0000000000..91afb85564 --- /dev/null +++ b/app/serializers/spree/api/product_serializer.rb @@ -0,0 +1,30 @@ +class Spree::Api::ProductSerializer < ActiveModel::Serializer + attributes :id, :name, :variant_unit, :variant_unit_scale, :variant_unit_name, :on_demand + + attributes :taxon_ids, :on_hand, :price, :available_on, :permalink_live + + has_one :supplier, key: :producer, embed: :id + has_many :variants, key: :variants, embed: :ids#, serializer: Spree::Api::VariantSerializer + has_one :master, serializer: Spree::Api::VariantSerializer + + # Infinity is not a valid JSON object, but Rails encodes it anyway + def taxon_ids + object.taxons.map{ |t| t.id }.join(",") + end + + def on_hand + object.on_hand.nil? ? 0 : object.on_hand.to_f.finite? ? object.on_hand : "On demand" + end + + def price + object.price.nil? ? '0.0' : object.price + end + + def available_on + object.available_on.blank? ? "" : object.available_on.strftime("%F %T") + end + + def permalink_live + object.permalink + end +end \ No newline at end of file diff --git a/app/serializers/spree/api/variant_serializer.rb b/app/serializers/spree/api/variant_serializer.rb new file mode 100644 index 0000000000..67a696bdcc --- /dev/null +++ b/app/serializers/spree/api/variant_serializer.rb @@ -0,0 +1,13 @@ +class Spree::Api::VariantSerializer < ActiveModel::Serializer + attributes :id, :options_text, :unit_value, :unit_description, :on_demand, :display_as, :display_name + + attributes :on_hand, :price + + def on_hand + object.on_hand.nil? ? 0 : ( object.on_hand.to_f.finite? ? object.on_hand : "On demand" ) + end + + def price + object.price.nil? ? 0.to_f : object.price + end +end \ No newline at end of file diff --git a/app/views/spree/admin/products/bulk_edit.html.haml b/app/views/spree/admin/products/bulk_edit.html.haml index d1cdd6324f..39014dae64 100644 --- a/app/views/spree/admin/products/bulk_edit.html.haml +++ b/app/views/spree/admin/products/bulk_edit.html.haml @@ -104,7 +104,7 @@ %thead %tr %th.left-actions - %th{ 'ng-show' => 'columns.supplier.visible' } Supplier + %th{ 'ng-show' => 'columns.producer.visible' } Supplier %th{ 'ng-show' => 'columns.name.visible' } Name %th{ 'ng-show' => 'columns.unit.visible' } Unit / Value %th{ 'ng-show' => 'columns.unit.visible' } Display As @@ -120,8 +120,8 @@ %td.left-actions %a{ 'ofn-toggle-variants' => 'true', :class => "view-variants icon-chevron-right", 'ng-show' => 'hasVariants(product)' } %a{ :class => "add-variant icon-plus-sign", 'ng-click' => "addVariant(product)", 'ng-show' => "!hasVariants(product) && hasUnit(product)" } - %td.supplier{ 'ng-show' => 'columns.supplier.visible' } - %select.select2{ 'ng-model' => 'product.supplier', :name => 'supplier', 'ofn-track-product' => 'supplier', 'ng-options' => 's.name for s in suppliers' } + %td.producer{ 'ng-show' => 'columns.producer.visible' } + %select.select2{ 'ng-model' => 'product.producer', :name => 'producer', 'ofn-track-product' => 'producer', 'ng-options' => 'producer.name for producer in producers' } %td{ 'ng-show' => 'columns.name.visible' } %input{ 'ng-model' => "product.name", :name => 'product_name', 'ofn-track-product' => 'name', :type => 'text' } %td.unit{ 'ng-show' => 'columns.unit.visible' } @@ -150,7 +150,7 @@ %td.left-actions %a{ :class => "variant-item icon-caret-right", 'ng-hide' => "$last" } %a{ :class => "add-variant icon-plus-sign", 'ng-click' => "addVariant(product)", 'ng-show' => "$last" } - %td{ 'ng-show' => 'columns.supplier.visible' } + %td{ 'ng-show' => 'columns.producer.visible' } %td{ 'ng-show' => 'columns.name.visible' } %input{ 'ng-model' => 'variant.display_name', :name => 'variant_display_name', 'ofn-track-variant' => 'display_name', :type => 'text', placeholder: "{{ product.name }}" } %td.unit_value{ 'ng-show' => 'columns.unit.visible' } diff --git a/config/routes.rb b/config/routes.rb index 75516552a4..af70141639 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -116,6 +116,7 @@ Spree::Core::Engine.routes.prepend do resources :products do get :managed, on: :collection + get :bulk_products, on: :collection delete :soft_delete resources :variants do diff --git a/spec/serializers/spree/product_serializer_spec.rb b/spec/serializers/spree/product_serializer_spec.rb new file mode 100644 index 0000000000..bbb65c1c7e --- /dev/null +++ b/spec/serializers/spree/product_serializer_spec.rb @@ -0,0 +1,7 @@ +describe Spree::Api::ProductSerializer do + let(:product) { create(:simple_product) } + it "serializes a product" do + serializer = Spree::Api::ProductSerializer.new product + serializer.to_json.should match product.name + end +end \ No newline at end of file diff --git a/spec/serializers/spree/variant_serializer_spec.rb b/spec/serializers/spree/variant_serializer_spec.rb new file mode 100644 index 0000000000..891298541f --- /dev/null +++ b/spec/serializers/spree/variant_serializer_spec.rb @@ -0,0 +1,7 @@ +describe Spree::Api::VariantSerializer do + let(:variant) { create(:variant) } + it "serializes a variant" do + serializer = Spree::Api::VariantSerializer.new variant + serializer.to_json.should match variant.name + end +end \ No newline at end of file