diff --git a/app/assets/javascripts/admin/bulk_product_update.js.coffee b/app/assets/javascripts/admin/bulk_product_update.js.coffee index 14ff9557b4..6ef5b2a267 100644 --- a/app/assets/javascripts/admin/bulk_product_update.js.coffee +++ b/app/assets/javascripts/admin/bulk_product_update.js.coffee @@ -348,6 +348,10 @@ productEditModule.controller "AdminProductEditCtrl", [ $scope.resetProducts data $timeout -> $scope.displaySuccess() else + # console.log angular.toJson($scope.productsWithoutDerivedAttributes($scope.products)) + # console.log "---" + # console.log angular.toJson($scope.productsWithoutDerivedAttributes(data)) + # console.log "---" $scope.displayFailure "Product lists do not match." ).error (data, status) -> $scope.displayFailure "Server returned with error status: " + status @@ -365,6 +369,7 @@ productEditModule.controller "AdminProductEditCtrl", [ else $scope.setMessage $scope.updateStatusMessage, "No changes to update.", color: "grey", 3000 + $scope.packProduct = (product) -> if product.variant_unit_with_scale match = product.variant_unit_with_scale.match(/^([^_]+)_([\d\.]+)$/) @@ -401,9 +406,7 @@ productEditModule.controller "AdminProductEditCtrl", [ delete variant.unit_value_with_description # If we end up live-updating this field, we might want to reinstate its verification here delete variant.options_text - if product.master - delete product.master.unit_value_with_description - delete product.master.options_text + delete product.master products_filtered @@ -472,23 +475,24 @@ filterSubmitProducts = (productsToFilter) -> if productsToFilter instanceof Object angular.forEach productsToFilter, (product) -> if product.hasOwnProperty("id") - filteredProduct = {} + filteredProduct = {id: product.id} filteredVariants = [] + hasUpdatableProperty = false + if product.hasOwnProperty("variants") angular.forEach product.variants, (variant) -> result = filterSubmitVariant variant filteredVariant = result.filteredVariant - hasUpdatableProperty = result.hasUpdatableProperty - filteredVariants.push filteredVariant if hasUpdatableProperty + variantHasUpdatableProperty = result.hasUpdatableProperty + filteredVariants.push filteredVariant if variantHasUpdatableProperty - if product.hasOwnProperty("master") - result = filterSubmitVariant product.master - filteredMaster = result.filteredVariant - hasUpdatableProperty = result.hasUpdatableProperty - filteredProduct.master = filteredMaster if hasUpdatableProperty + if product.master?.hasOwnProperty("unit_value") + filteredProduct.unit_value = product.master.unit_value + hasUpdatableProperty = true + if product.master?.hasOwnProperty("unit_description") + filteredProduct.unit_description = product.master.unit_description + hasUpdatableProperty = true - hasUpdatableProperty = false - filteredProduct.id = product.id if product.hasOwnProperty("name") filteredProduct.name = product.name hasUpdatableProperty = true diff --git a/app/models/spree/product_decorator.rb b/app/models/spree/product_decorator.rb index 3f570bdd2f..33ccf73a81 100644 --- a/app/models/spree/product_decorator.rb +++ b/app/models/spree/product_decorator.rb @@ -11,8 +11,9 @@ Spree::Product.class_eval do has_many :distributors, :through => :product_distributions accepts_nested_attributes_for :product_distributions, :allow_destroy => true + delegate_belongs_to :master, :unit_value, :unit_description - attr_accessible :supplier_id, :distributor_ids, :product_distributions_attributes, :group_buy, :group_buy_unit_size, :variant_unit, :variant_unit_scale, :variant_unit_name, :notes + attr_accessible :supplier_id, :distributor_ids, :product_distributions_attributes, :group_buy, :group_buy_unit_size, :variant_unit, :variant_unit_scale, :variant_unit_name, :unit_value, :unit_description, :notes validates_presence_of :supplier diff --git a/app/views/spree/admin/products/bulk_edit.html.haml b/app/views/spree/admin/products/bulk_edit.html.haml index e2ae2dcee4..68e73e5da3 100644 --- a/app/views/spree/admin/products/bulk_edit.html.haml +++ b/app/views/spree/admin/products/bulk_edit.html.haml @@ -117,7 +117,9 @@ %input{ 'ng-model' => "product.name", :name => 'product_name', 'ofn-track-product' => 'name', :type => 'text' } %td.unit{ 'ng-show' => 'columns.unit.visible' } %select.select2{ 'ng-model' => 'product.variant_unit_with_scale', :name => 'variant_unit_with_scale', 'ofn-track-product' => 'variant_unit_with_scale', 'ng-options' => 'unit[1] as unit[0] for unit in variant_unit_options' } - %input{ 'ng-model' => 'product.variant_unit_name', :name => 'variant_unit_name', 'ofn-track-product' => 'variant_unit_name', 'ng-show' => "product.variant_unit_with_scale == 'items'", :type => 'text' } + %option{'value' => '', 'ng-hide' => "hasVariants(product)"} + %input{ 'ng-model' => 'product.master.unit_value_with_description', :name => 'master_unit_value_with_description', 'ofn-track-product' => 'master.unit_value_with_description', :type => 'text', :placeholder => 'value', 'ng-show' => "product.variant_unit_with_scale != undefined && !hasVariants(product)" } + %input{ 'ng-model' => 'product.variant_unit_name', :name => 'variant_unit_name', 'ofn-track-product' => 'variant_unit_name', :placeholder => 'unit', 'ng-show' => "product.variant_unit_with_scale == 'items'", :type => 'text' } %td{ 'ng-show' => 'columns.price.visible' } %input{ 'ng-model' => 'product.price', 'ofn-decimal' => :true, :name => 'price', 'ofn-track-product' => 'price', :type => 'text' } %td{ 'ng-show' => 'columns.on_hand.visible' } diff --git a/app/views/spree/api/products/bulk_show.v1.rabl b/app/views/spree/api/products/bulk_show.v1.rabl index 1f07d3d91f..6219bc193e 100644 --- a/app/views/spree/api/products/bulk_show.v1.rabl +++ b/app/views/spree/api/products/bulk_show.v1.rabl @@ -7,8 +7,11 @@ node( :on_hand ) { |p| p.on_hand.to_f.finite? ? p.on_hand : "On demand" } node( :available_on ) { |p| p.available_on.blank? ? "" : p.available_on.strftime("%F %T") } node( :permalink_live ) { |p| p.permalink } node( :supplier ) do |p| - partial 'spree/api/enterprises/bulk_show', :object => p.supplier + partial 'spree/api/enterprises/bulk_show', :object => p.supplier end node( :variants ) do |p| - partial 'spree/api/variants/bulk_index', :object => p.variants.order('id ASC') + partial 'spree/api/variants/bulk_index', :object => p.variants.order('id ASC') +end +node( :master ) do |p| + partial 'spree/api/variants/bulk_show', :object => p.master end diff --git a/spec/features/admin/bulk_product_update_spec.rb b/spec/features/admin/bulk_product_update_spec.rb index 352c3d14c7..fb57fa7254 100644 --- a/spec/features/admin/bulk_product_update_spec.rb +++ b/spec/features/admin/bulk_product_update_spec.rb @@ -295,7 +295,7 @@ feature %q{ page.should have_field "on_hand", with: "18" end - scenario "updating a product with an items variant unit" do + scenario "updating a product with a variant unit of 'items'" do p = FactoryGirl.create(:product, variant_unit: 'weight', variant_unit_scale: 1000) login_to_admin_section @@ -340,6 +340,48 @@ feature %q{ page.should have_field "variant_unit_value_with_description", with: "123 abc" end + describe "setting the master unit value for a product without variants" do + it "sets the master unit value" do + p = FactoryGirl.create(:product, variant_unit: nil, variant_unit_scale: nil) + + login_to_admin_section + + visit '/admin/products/bulk_edit' + + page.should have_select "variant_unit_with_scale", selected: '' + page.should_not have_field "master_unit_value_with_description", visible: true + + select "Weight (kg)", from: "variant_unit_with_scale" + fill_in "master_unit_value_with_description", with: '123 abc' + + click_button 'Update' + page.find("span#update-status-message").should have_content "Update complete" + + visit '/admin/products/bulk_edit' + + page.should have_select "variant_unit_with_scale", selected: "Weight (kg)" + page.should have_field "master_unit_value_with_description", with: "123 abc" + + p.reload + p.variant_unit.should == 'weight' + p.variant_unit_scale.should == 1000 + p.master.unit_value.should == 123000 + p.master.unit_description.should == 'abc' + end + + it "does not show the field when the product has variants" do + p = FactoryGirl.create(:product, variant_unit: nil, variant_unit_scale: nil) + v = FactoryGirl.create(:variant, product: p, unit_value: nil, unit_description: nil) + + login_to_admin_section + + visit '/admin/products/bulk_edit' + + select "Weight (kg)", from: "variant_unit_with_scale" + page.should_not have_field "master_unit_value_with_description", visible: true + end + end + scenario "updating a product with variants" do s1 = FactoryGirl.create(:supplier_enterprise) diff --git a/spec/javascripts/unit/bulk_product_update_spec.js.coffee b/spec/javascripts/unit/bulk_product_update_spec.js.coffee index bec7e8b8d3..604fb4e9b4 100644 --- a/spec/javascripts/unit/bulk_product_update_spec.js.coffee +++ b/spec/javascripts/unit/bulk_product_update_spec.js.coffee @@ -194,11 +194,9 @@ describe "filtering products for submission to database", -> variant_unit: 'volume' variant_unit_scale: 1 variant_unit_name: 'loaf' + unit_value: 250 + unit_description: "foo" available_on: available_on - master: - id: 2 - unit_value: 250 - unit_description: "foo" variants_attributes: [ id: 1 on_hand: 2 @@ -858,12 +856,11 @@ describe "AdminProductEditCtrl", -> } ] - it "returns master variant without the unit_value_with_description field", -> + it "removes the master variant", -> scope.products = [{id: 123, master: {id: 234, unit_value_with_description: 'foo'}}] expect(scope.productsWithoutDerivedAttributes(scope.products)).toEqual [ { id: 123 - master: {id: 234} } ]