diff --git a/app/assets/javascripts/admin/bulk_product_update.js.coffee b/app/assets/javascripts/admin/bulk_product_update.js.coffee index d32977b8c05..eae103015a2 100644 --- a/app/assets/javascripts/admin/bulk_product_update.js.coffee +++ b/app/assets/javascripts/admin/bulk_product_update.js.coffee @@ -187,9 +187,8 @@ angular.module("ofn.admin").controller "AdminProductEditCtrl", ($scope, $timeout product.variants.length > 0 - $scope.hasUnit = (product) -> - product.variant_unit_with_scale? - + $scope.hasUnit = (variant) -> + variant.variant_unit_with_scale? $scope.variantSaved = (variant) -> variant.hasOwnProperty('id') && variant.id > 0 @@ -242,32 +241,28 @@ angular.module("ofn.admin").controller "AdminProductEditCtrl", ($scope, $timeout $window.location = destination $scope.packProduct = (product) -> - if product.variant_unit_with_scale - match = product.variant_unit_with_scale.match(/^([^_]+)_([\d\.]+)$/) - if match - product.variant_unit = match[1] - product.variant_unit_scale = parseFloat(match[2]) - else - product.variant_unit = product.variant_unit_with_scale - product.variant_unit_scale = null - else - product.variant_unit = product.variant_unit_scale = null - - if product.variants for id, variant of product.variants - $scope.packVariant product, variant + $scope.packVariant variant + + $scope.packVariant = (variant) -> + if variant.variant_unit_with_scale + match = variant.variant_unit_with_scale.match(/^([^_]+)_([\d\.]+)$/) + if match + variant.variant_unit = match[1] + variant.variant_unit_scale = parseFloat(match[2]) + else + variant.variant_unit = variant.variant_unit_with_scale + variant.variant_unit_scale = null - $scope.packVariant = (product, variant) -> if variant.hasOwnProperty("unit_value_with_description") match = variant.unit_value_with_description.match(/^([\d\.\,]+(?= |$)|)( |)(.*)$/) if match - product = BulkProducts.find product.id variant.unit_value = parseFloat(match[1].replace(",", ".")) variant.unit_value = null if isNaN(variant.unit_value) - if variant.unit_value && product.variant_unit_scale - variant.unit_value = parseFloat(window.bigDecimal.multiply(variant.unit_value, product.variant_unit_scale, 2)) + if variant.unit_value && variant.variant_unit_scale + variant.unit_value = parseFloat(window.bigDecimal.multiply(variant.unit_value, variant.variant_unit_scale, 2)) variant.unit_description = match[3] $scope.incrementLimit = -> @@ -321,13 +316,6 @@ filterSubmitProducts = (productsToFilter) -> if product.hasOwnProperty("price") filteredProduct.price = product.price hasUpdatableProperty = true - if product.hasOwnProperty("variant_unit_with_scale") - filteredProduct.variant_unit = product.variant_unit - filteredProduct.variant_unit_scale = product.variant_unit_scale - hasUpdatableProperty = true - if product.hasOwnProperty("variant_unit_name") - filteredProduct.variant_unit_name = product.variant_unit_name - hasUpdatableProperty = true if product.hasOwnProperty("on_hand") and filteredVariants.length == 0 #only update if no variants present filteredProduct.on_hand = product.on_hand hasUpdatableProperty = true @@ -383,6 +371,14 @@ filterSubmitVariant = (variant) -> if variant.hasOwnProperty("producer_id") filteredVariant.supplier_id = variant.producer_id hasUpdatableProperty = true + if variant.hasOwnProperty("variant_unit_with_scale") + filteredVariant.variant_unit = variant.variant_unit + filteredVariant.variant_unit_scale = variant.variant_unit_scale + hasUpdatableProperty = true + if variant.hasOwnProperty("variant_unit_name") + filteredVariant.variant_unit_name = variant.variant_unit_name + hasUpdatableProperty = true + {filteredVariant: filteredVariant, hasUpdatableProperty: hasUpdatableProperty} diff --git a/app/assets/javascripts/admin/directives/display_as.js.coffee b/app/assets/javascripts/admin/directives/display_as.js.coffee index 375f1795eef..bb624113ba8 100644 --- a/app/assets/javascripts/admin/directives/display_as.js.coffee +++ b/app/assets/javascripts/admin/directives/display_as.js.coffee @@ -4,31 +4,30 @@ angular.module("ofn.admin").directive "ofnDisplayAs", (OptionValueNamer) -> scope.$watchCollection -> return [ scope.$eval(attrs.ofnDisplayAs).unit_value_with_description - scope.product.variant_unit_name - scope.product.variant_unit_with_scale + scope.variant.variant_unit_name + scope.variant.variant_unit_with_scale ] , -> [variant_unit, variant_unit_scale] = productUnitProperties() [unit_value, unit_description] = variantUnitProperties(variant_unit_scale) - variant_object = + variant_object = unit_value: unit_value unit_description: unit_description - product: - variant_unit_scale: variant_unit_scale - variant_unit: variant_unit - variant_unit_name: scope.product.variant_unit_name + variant_unit_scale: variant_unit_scale + variant_unit: variant_unit + variant_unit_name: scope.variant.variant_unit_name scope.placeholder_text = new OptionValueNamer(variant_object).name() productUnitProperties = -> # get relevant product properties - if scope.product.variant_unit_with_scale? - match = scope.product.variant_unit_with_scale.match(/^([^_]+)_([\d\.]+)$/) + if scope.variant.variant_unit_with_scale? + match = scope.variant.variant_unit_with_scale.match(/^([^_]+)_([\d\.]+)$/) if match variant_unit = match[1] variant_unit_scale = parseFloat(match[2]) else - variant_unit = scope.product.variant_unit_with_scale + variant_unit = scope.variant.variant_unit_with_scale variant_unit_scale = null else variant_unit = variant_unit_scale = null @@ -45,4 +44,4 @@ angular.module("ofn.admin").directive "ofnDisplayAs", (OptionValueNamer) -> unit_value = null if isNaN(unit_value) unit_value *= variant_unit_scale if unit_value && variant_unit_scale unit_description = match[3] - [unit_value, unit_description] \ No newline at end of file + [unit_value, unit_description] diff --git a/app/assets/javascripts/admin/directives/maintain_unit_scale.js.coffee b/app/assets/javascripts/admin/directives/maintain_unit_scale.js.coffee deleted file mode 100644 index 55306f6d778..00000000000 --- a/app/assets/javascripts/admin/directives/maintain_unit_scale.js.coffee +++ /dev/null @@ -1,8 +0,0 @@ -angular.module("ofn.admin").directive "ofnMaintainUnitScale", -> - require: "ngModel" - link: (scope, element, attrs, ngModel) -> - scope.$watch 'product.variant_unit_with_scale', (newValue, oldValue) -> - if not (oldValue == newValue) - # Triggers track-variant directive to track the unit_value, so that changes to the unit are passed to the server - ngModel.$setViewValue ngModel.$viewValue - \ No newline at end of file diff --git a/app/assets/javascripts/admin/directives/track_master.js.coffee b/app/assets/javascripts/admin/directives/track_master.js.coffee deleted file mode 100644 index be84e0b2046..00000000000 --- a/app/assets/javascripts/admin/directives/track_master.js.coffee +++ /dev/null @@ -1,8 +0,0 @@ -angular.module("ofn.admin").directive "ofnTrackMaster", (DirtyProducts) -> - require: "ngModel" - link: (scope, element, attrs, ngModel) -> - ngModel.$parsers.push (viewValue) -> - if ngModel.$dirty - DirtyProducts.addMasterProperty scope.product.id, scope.product.master.id, attrs.ofnTrackMaster, viewValue - scope.displayDirtyProducts() - viewValue diff --git a/app/views/spree/admin/products/index/_products_product.html.haml b/app/views/spree/admin/products/index/_products_product.html.haml index b5a778a043b..aa10e5e29ad 100644 --- a/app/views/spree/admin/products/index/_products_product.html.haml +++ b/app/views/spree/admin/products/index/_products_product.html.haml @@ -11,9 +11,6 @@ %td.name{ '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' } - %select.no-search{ "data-controller": "tom-select", '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.master.unit_value_with_description', :name => 'master_unit_value_with_description', 'ofn-track-master' => 'unit_value_with_description', :type => 'text', :placeholder => 'value', 'ng-show' => "!hasVariants(product) && hasUnit(product)", 'ofn-maintain-unit-scale' => true } - %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.display_as{ 'ng-show' => 'columns.unit.visible' } %td.price{ 'ng-show' => 'columns.price.visible' } %input{ 'ng-model' => 'product.price', 'ofn-decimal' => :true, :name => 'price', 'ofn-track-product' => 'price', :type => 'text', 'ng-hide' => 'hasVariants(product)' } diff --git a/app/views/spree/admin/products/index/_products_variant.html.haml b/app/views/spree/admin/products/index/_products_variant.html.haml index 8a5c2c03115..4aa5e13f78d 100644 --- a/app/views/spree/admin/products/index/_products_variant.html.haml +++ b/app/views/spree/admin/products/index/_products_variant.html.haml @@ -10,7 +10,9 @@ %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' } - %input{ 'ng-model' => 'variant.unit_value_with_description', :name => 'variant_unit_value_with_description', 'ofn-track-variant' => 'unit_value_with_description', :type => 'text', 'ofn-maintain-unit-scale' => true } + %select.no-search{ "data-controller": "tom-select", 'ng-model' => 'variant.variant_unit_with_scale', :name => 'variant_unit_with_scale', 'ofn-track-variant' => 'variant_unit_with_scale', 'ng-options' => 'unit[1] as unit[0] for unit in variant_unit_options' } + %input{ 'ng-model' => 'variant.unit_value_with_description', :name => 'variant_unit_value_with_description', 'ofn-track-variant' => 'unit_value_with_description', :type => 'text', :placeholder => 'value', 'ng-show' => "hasUnit(variant)" } + %input{ 'ng-model' => 'variant.variant_unit_name', :name => 'variant_unit_name', 'ofn-track-variant' => 'variant_unit_name', :placeholder => 'unit', 'ng-show' => "variant.variant_unit_with_scale == 'items'", :type => 'text' } %td.display_as{ 'ng-show' => 'columns.unit.visible' } %input{ 'ofn-display-as' => 'variant', 'ng-model' => 'variant.display_as', name: 'variant_display_as', 'ofn-track-variant' => 'display_as', type: 'text', placeholder: '{{ placeholder_text }}' } %td{ 'ng-show' => 'columns.price.visible' } diff --git a/spec/javascripts/unit/admin/bulk_product_update_spec.js.coffee b/spec/javascripts/unit/admin/bulk_product_update_spec.js.coffee index 70fe6dac589..532f569d69e 100644 --- a/spec/javascripts/unit/admin/bulk_product_update_spec.js.coffee +++ b/spec/javascripts/unit/admin/bulk_product_update_spec.js.coffee @@ -156,14 +156,20 @@ describe "filtering products for submission to database", -> it "returns variant_unit_with_scale as variant_unit and variant_unit_scale", -> testProduct = id: 1 - variant_unit: 'weight' - variant_unit_scale: 1 - variant_unit_with_scale: 'weight_1' + variants: [ + id: 1 + variant_unit: 'weight' + variant_unit_scale: 1 + variant_unit_with_scale: 'weight_1' + ] expect(filterSubmitProducts([testProduct])).toEqual [ id: 1 - variant_unit: 'weight' - variant_unit_scale: 1 + variants_attributes: [ + id: 1 + variant_unit: 'weight' + variant_unit_scale: 1 + ] ] it "returns stock properties of a product if no variant is provided", -> @@ -204,18 +210,15 @@ describe "filtering products for submission to database", -> display_as: "bottle" display_name: "nothing" producer_id: 5 + variant_unit: 'volume' + variant_unit_scale: 1 + variant_unit_name: 'loaf' + variant_unit_with_scale: 'volume_1' ] - variant_unit: 'volume' - variant_unit_scale: 1 - variant_unit_name: 'loaf' - variant_unit_with_scale: 'volume_1' expect(filterSubmitProducts([testProduct])).toEqual [ id: 1 name: "TestProduct" - variant_unit: 'volume' - variant_unit_scale: 1 - variant_unit_name: 'loaf' variants_attributes: [ id: 1 on_hand: 2 @@ -226,6 +229,9 @@ describe "filtering products for submission to database", -> display_as: "bottle" display_name: "nothing" supplier_id: 5 + variant_unit: 'volume' + variant_unit_scale: 1 + variant_unit_name: 'loaf' ] ] @@ -281,7 +287,6 @@ describe "AdminProductEditCtrl", -> $scope.initialise() expect($scope.q.query).toBe query - expect($scope.q.producerFilter).toBe producerFilter expect($scope.q.categoryFilter).toBe categoryFilter expect($scope.q.sorting).toBe sorting expect($scope.q.importDateFilter).toBe importDateFilter @@ -476,13 +481,13 @@ describe "AdminProductEditCtrl", -> describe "determining whether a product has a unit", -> it "returns true when it does", -> - product = - variant_unit_with_scale: 'weight_1000' - expect($scope.hasUnit(product)).toBe(true) + variant ={variant_unit_with_scale: 'weight_1000'} + + expect($scope.hasUnit(variant)).toBe(true) it "returns false when its unit is undefined", -> - product = {} - expect($scope.hasUnit(product)).toBe(false) + variant = {} + expect($scope.hasUnit(variant)).toBe(false) describe "determining whether a variant has been saved", -> @@ -505,174 +510,163 @@ describe "AdminProductEditCtrl", -> window.bigDecimal = jasmine.createSpyObj "bigDecimal", ["multiply"] window.bigDecimal.multiply.and.callFake (a, b, c) -> (a * b).toFixed(c) - it "extracts variant_unit_with_scale into variant_unit and variant_unit_scale", -> + it "packs each variant", -> + spyOn $scope, "packVariant" + testVariant = {id: 1} testProduct = id: 1 - variant_unit: 'weight' - variant_unit_scale: 1 - variant_unit_with_scale: 'volume_1000' + variants: {1: testVariant} $scope.packProduct(testProduct) - expect(testProduct).toEqual - id: 1 - variant_unit: 'volume' - variant_unit_scale: 1000 - variant_unit_with_scale: 'volume_1000' + expect($scope.packVariant).toHaveBeenCalledWith(testVariant) - it "extracts a null value into null variant_unit and variant_unit_scale", -> - testProduct = + describe "packing variants", -> + beforeEach -> + window.bigDecimal = jasmine.createSpyObj "bigDecimal", ["multiply"] + window.bigDecimal.multiply.and.callFake (a, b, c) -> (a * b).toFixed(c) + + it "extracts variant_unit_with_scale into variant_unit and variant_unit_scale", -> + testVariant = id: 1 variant_unit: 'weight' variant_unit_scale: 1 - variant_unit_with_scale: null + variant_unit_with_scale: 'volume_1000' - $scope.packProduct(testProduct) + $scope.packVariant(testVariant) - expect(testProduct).toEqual + expect(testVariant).toEqual id: 1 - variant_unit: null - variant_unit_scale: null - variant_unit_with_scale: null + variant_unit: 'volume' + variant_unit_scale: 1000 + variant_unit_with_scale: 'volume_1000' it "extracts when variant_unit_with_scale is 'items'", -> - testProduct = + testVariant = id: 1 variant_unit: 'weight' variant_unit_scale: 1 variant_unit_with_scale: 'items' - $scope.packProduct(testProduct) + $scope.packVariant(testVariant) - expect(testProduct).toEqual + expect(testVariant).toEqual id: 1 variant_unit: 'items' variant_unit_scale: null variant_unit_with_scale: 'items' - it "packs each variant", -> - spyOn $scope, "packVariant" - testVariant = {id: 1} - testProduct = - id: 1 - variants: {1: testVariant} - - $scope.packProduct(testProduct) - - expect($scope.packVariant).toHaveBeenCalledWith(testProduct, testVariant) - - describe "packing variants", -> - beforeEach -> - window.bigDecimal = jasmine.createSpyObj "bigDecimal", ["multiply"] - window.bigDecimal.multiply.and.callFake (a, b, c) -> (a * b).toFixed(c) - it "extracts unit_value and unit_description from unit_value_with_description", -> - testProduct = {id: 123, variant_unit_scale: 1.0} testVariant = {unit_value_with_description: "250.5 (bottle)"} - BulkProducts.products = [testProduct] - $scope.products = [testProduct] - $scope.packVariant(testProduct, testVariant) + + $scope.packVariant(testVariant) + expect(testVariant).toEqual unit_value: 250.5 unit_description: "(bottle)" unit_value_with_description: "250.5 (bottle)" it "extracts into unit_value when only a number is provided", -> - testProduct = {id: 123, variant_unit_scale: 1.0} - testVariant = {unit_value_with_description: "250.5"} - BulkProducts.products = [testProduct] - $scope.packVariant(testProduct, testVariant) + testVariant = {variant_unit_scale: 1.0, unit_value_with_description: "250.5"} + + $scope.packVariant(testVariant) + expect(testVariant).toEqual unit_value: 250.5 unit_description: '' unit_value_with_description: "250.5" + variant_unit_scale: 1.0 it "extracts into unit_description when only a string is provided", -> - testProduct = {id: 123} testVariant = {unit_value_with_description: "Medium"} - BulkProducts.products = [testProduct] - $scope.packVariant(testProduct, testVariant) + + $scope.packVariant(testVariant) + expect(testVariant).toEqual unit_value: null unit_description: 'Medium' unit_value_with_description: "Medium" it "extracts into unit_description when a string starting with a number is provided", -> - testProduct = {id: 123} testVariant = {unit_value_with_description: "1kg"} - BulkProducts.products = [testProduct] - $scope.packVariant(testProduct, testVariant) + + $scope.packVariant(testVariant) + expect(testVariant).toEqual unit_value: null unit_description: '1kg' unit_value_with_description: "1kg" it "sets blank values when no value provided", -> - testProduct = {id: 123} testVariant = {unit_value_with_description: ""} - BulkProducts.products = [testProduct] - $scope.packVariant(testProduct, testVariant) + + $scope.packVariant(testVariant) + expect(testVariant).toEqual unit_value: null unit_description: '' unit_value_with_description: "" it "sets nothing when the field is undefined", -> - testProduct = {id: 123} testVariant = {} - BulkProducts.products = [testProduct] - $scope.packVariant(testProduct, testVariant) - expect(testVariant).toEqual {} + + $scope.packVariant(testVariant) + + expect(testVariant).toEqual({}) it "sets zero when the field is zero", -> - testProduct = {id: 123, variant_unit_scale: 1.0} - testVariant = {unit_value_with_description: "0"} - BulkProducts.products = [testProduct] - $scope.packVariant(testProduct, testVariant) + testVariant = {variant_unit_scale: 1.0, unit_value_with_description: "0"} + + $scope.packVariant(testVariant) + expect(testVariant).toEqual unit_value: 0 unit_description: '' unit_value_with_description: "0" + variant_unit_scale: 1.0 it "converts value from chosen unit to base unit", -> - testProduct = {id: 123, variant_unit_scale: 1000} - testVariant = {unit_value_with_description: "250.5"} - BulkProducts.products = [testProduct] - $scope.packVariant(testProduct, testVariant) + testVariant = {variant_unit_scale: 1000, unit_value_with_description: "250.5"} + + $scope.packVariant(testVariant) + expect(testVariant).toEqual unit_value: 250500 unit_description: '' unit_value_with_description: "250.5" + variant_unit_scale: 1000 it "does not convert value when using a non-scaled unit", -> - testProduct = {id: 123} testVariant = {unit_value_with_description: "12"} - BulkProducts.products = [testProduct] - $scope.packVariant(testProduct, testVariant) + + $scope.packVariant(testVariant) + expect(testVariant).toEqual unit_value: 12 unit_description: '' unit_value_with_description: "12" it "converts unit_value into a float when a comma separated number is provided", -> - testProduct = {id: 123, variant_unit_scale: 1.0} - testVariant = {unit_value_with_description: "250,5"} - BulkProducts.products = [testProduct] - $scope.packVariant(testProduct, testVariant) + testVariant = {variant_unit_scale: 1.0, unit_value_with_description: "250,5"} + + $scope.packVariant(testVariant) + expect(testVariant).toEqual unit_value: 250.5 unit_description: '' unit_value_with_description: "250,5" + variant_unit_scale: 1.0 it "rounds off the unit_value upto 2 decimal places", -> - testProduct = {id: 123, variant_unit_scale: 1.0} - testVariant = {unit_value_with_description: "1234.567"} - BulkProducts.products = [testProduct] - $scope.packVariant(testProduct, testVariant) + testVariant = {variant_unit_scale: 1.0, unit_value_with_description: "1234.567"} + + $scope.packVariant(testVariant) + expect(testVariant).toEqual unit_value: 1234.57 unit_description: '' unit_value_with_description: "1234.567" + variant_unit_scale: 1.0 describe "filtering products", ->