diff --git a/app/assets/javascripts/admin/bulk_product_update.js.coffee b/app/assets/javascripts/admin/bulk_product_update.js.coffee index 623ff54095..631a940d31 100644 --- a/app/assets/javascripts/admin/bulk_product_update.js.coffee +++ b/app/assets/javascripts/admin/bulk_product_update.js.coffee @@ -161,10 +161,10 @@ productsApp.controller "AdminBulkProductsCtrl", [ $scope.dirtyProducts = {} $scope.displayProperties ||= {} angular.forEach $scope.products, (product) -> - $scope.prepareProduct product + $scope.unpackProduct product - $scope.prepareProduct = (product) -> + $scope.unpackProduct = (product) -> $scope.displayProperties ||= {} $scope.displayProperties[product.id] ||= showVariants: false $scope.matchSupplier product @@ -237,7 +237,7 @@ productsApp.controller "AdminBulkProductsCtrl", [ id = data.product.id dataFetcher("/api/products/" + id + "?template=bulk_show").then (data) -> newProduct = data - $scope.prepareProduct newProduct + $scope.unpackProduct newProduct $scope.products.push newProduct @@ -262,10 +262,24 @@ productsApp.controller "AdminBulkProductsCtrl", [ $scope.submitProducts = -> + # Pack $scope.dirtyProducts, ensuring that the correct product info is sent to the server, + # then pack $scope.products, so they will match the list returned from the server + angular.forEach $scope.dirtyProducts, (product) -> + $scope.packProduct product + angular.forEach $scope.products, (product) -> + $scope.packProduct product + productsToSubmit = filterSubmitProducts($scope.dirtyProducts) $scope.updateProducts productsToSubmit + $scope.packProduct = (product) -> + if product.hasOwnProperty 'variant_unit_with_scale' + match = product.variant_unit_with_scale.match(/^([^_]+)_([\d\.]+)$/) + product.variant_unit = match[1] + product.variant_unit_scale = parseFloat(match[2]) + + $scope.productsWithoutDerivedAttributes = -> products = [] if $scope.products @@ -363,9 +377,8 @@ filterSubmitProducts = (productsToFilter) -> filteredProduct.price = product.price hasUpdatableProperty = true if product.hasOwnProperty("variant_unit_with_scale") - match = product.variant_unit_with_scale.match(/^([^_]+)_([\d\.]+)$/) - filteredProduct.variant_unit = match[1] - filteredProduct.variant_unit_scale = parseFloat(match[2]) + filteredProduct.variant_unit = product.variant_unit + filteredProduct.variant_unit_scale = product.variant_unit_scale hasUpdatableProperty = true if product.hasOwnProperty("on_hand") and filteredVariants.length == 0 #only update if no variants present filteredProduct.on_hand = product.on_hand diff --git a/spec/features/admin/bulk_product_update_spec.rb b/spec/features/admin/bulk_product_update_spec.rb index fe4a09740d..ff06549375 100644 --- a/spec/features/admin/bulk_product_update_spec.rb +++ b/spec/features/admin/bulk_product_update_spec.rb @@ -180,7 +180,7 @@ feature %q{ scenario "updating a product with no variants (except master)" do s1 = FactoryGirl.create(:supplier_enterprise) s2 = FactoryGirl.create(:supplier_enterprise) - p = FactoryGirl.create(:product, supplier: s1, available_on: Date.today) + p = FactoryGirl.create(:product, supplier: s1, available_on: Date.today, variant_unit: 'volume', variant_unit_scale: 1) p.price = 10.0 p.on_hand = 6; p.save! @@ -193,12 +193,14 @@ feature %q{ page.should have_select "supplier", selected: s1.name page.should have_field "available_on", with: p.available_on.strftime("%F %T") page.should have_field "price", with: "10.0" + page.should have_select "variant_unit_with_scale", selected: "Volume (L)" page.should have_field "on_hand", with: "6" fill_in "product_name", with: "Big Bag Of Potatoes" select(s2.name, :from => 'supplier') fill_in "available_on", with: (Date.today-3).strftime("%F %T") fill_in "price", with: "20" + select "Weight (kg)", from: "variant_unit_with_scale" fill_in "on_hand", with: "18" click_button 'Update' @@ -210,6 +212,7 @@ feature %q{ page.should have_select "supplier", selected: s2.name page.should have_field "available_on", with: (Date.today-3).strftime("%F %T") page.should have_field "price", with: "20.0" + page.should have_select "variant_unit_with_scale", selected: "Weight (kg)" page.should have_field "on_hand", with: "18" end diff --git a/spec/javascripts/unit/bulk_product_update_spec.js.coffee b/spec/javascripts/unit/bulk_product_update_spec.js.coffee index 2ef827f541..c42028a2b9 100644 --- a/spec/javascripts/unit/bulk_product_update_spec.js.coffee +++ b/spec/javascripts/unit/bulk_product_update_spec.js.coffee @@ -133,12 +133,12 @@ describe "filtering products", -> id: 1 variant_unit: 'weight' variant_unit_scale: 1 - variant_unit_with_scale: 'volume_1000' + variant_unit_with_scale: 'weight_1' expect(filterSubmitProducts([testProduct])).toEqual [ id: 1 - variant_unit: 'volume' - variant_unit_scale: 1000 + variant_unit: 'weight' + variant_unit_scale: 1 ] # TODO Not an exhaustive test, is there a better way to do this? @@ -173,14 +173,14 @@ describe "filtering products", -> variant_unit: 'volume' variant_unit_scale: 1 variant_unit_name: null - variant_unit_with_scale: 'weight_1000' + variant_unit_with_scale: 'volume_1' expect(filterSubmitProducts([testProduct])).toEqual [ id: 1 name: "TestProduct" supplier_id: 5 - variant_unit: 'weight' - variant_unit_scale: 1000 + variant_unit: 'volume' + variant_unit_scale: 1 available_on: new Date() variants_attributes: [ id: 1 @@ -280,7 +280,7 @@ describe "AdminBulkProductsCtrl", -> beforeEach -> ctrl "AdminBulkProductsCtrl", {$scope: scope} - spyOn scope, "prepareProduct" + spyOn scope, "unpackProduct" scope.products = {} scope.resetProducts [ { @@ -308,8 +308,8 @@ describe "AdminBulkProductsCtrl", -> it "resets dirtyProducts", -> expect(scope.dirtyProducts).toEqual {} - it "calls prepareProduct once for each product", -> - expect(scope.prepareProduct.calls.length).toEqual 2 + it "calls unpackProduct once for each product", -> + expect(scope.unpackProduct.calls.length).toEqual 2 describe 'preparing products', -> @@ -322,19 +322,19 @@ describe "AdminBulkProductsCtrl", -> it 'initialises display properties for the product', -> product = {id: 123} scope.displayProperties = {} - scope.prepareProduct product + scope.unpackProduct product expect(scope.displayProperties[123]).toEqual {showVariants: false} it 'calls matchSupplier for the product', -> product = {id: 123} scope.displayProperties = {} - scope.prepareProduct product + scope.unpackProduct product expect(scope.matchSupplier.calls.length).toEqual 1 it 'calls loadVariantUnit for the product', -> product = {id: 123} scope.displayProperties = {} - scope.prepareProduct product + scope.unpackProduct product expect(scope.loadVariantUnit.calls.length).toEqual 1 @@ -457,11 +457,33 @@ describe "AdminBulkProductsCtrl", -> describe "submitting products to be updated", -> - describe "preparing products for submit", -> + describe 'packing products', -> beforeEach -> ctrl "AdminBulkProductsCtrl", $scope: scope + it 'extracts variant_unit_with_scale into variant_unit and variant_unit_scale', -> + testProduct = + id: 1 + variant_unit: 'weight' + variant_unit_scale: 1 + variant_unit_with_scale: 'volume_1000' + + scope.packProduct(testProduct) + + expect(testProduct).toEqual + id: 1 + variant_unit: 'volume' + variant_unit_scale: 1000 + variant_unit_with_scale: 'volume_1000' + + + describe "filtering products", -> + beforeEach -> + ctrl "AdminBulkProductsCtrl", + $scope: scope + + spyOn scope, "packProduct" spyOn(window, "filterSubmitProducts").andReturn [ { id: 1 @@ -476,17 +498,23 @@ describe "AdminBulkProductsCtrl", -> scope.dirtyProducts = 1: id: 1 - + 2: + id: 2 + scope.products = + 1: + id: 1 2: id: 2 scope.submitProducts() + it 'packs all products and all dirty products', -> + expect(scope.packProduct.calls.length).toEqual 4 + it "filters returned dirty products", -> expect(filterSubmitProducts).toHaveBeenCalledWith 1: id: 1 - 2: id: 2 @@ -743,7 +771,7 @@ describe "AdminBulkProductsCtrl", -> httpBackend.flush() it "adds the newly created product to scope.products and matches supplier", -> - spyOn(scope, "prepareProduct").andCallThrough() + spyOn(scope, "unpackProduct").andCallThrough() scope.products = [ id: 13 permalink_live: "oranges" @@ -773,7 +801,7 @@ describe "AdminBulkProductsCtrl", -> scope.cloneProduct scope.products[0] httpBackend.flush() - expect(scope.prepareProduct).toHaveBeenCalledWith + expect(scope.unpackProduct).toHaveBeenCalledWith id: 17 name: "new_product" variant_unit_with_scale: null