From 037c524df28f19127ccb2a0e8ad2fd856aeec5c5 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Thu, 7 Jan 2016 16:35:54 +1100 Subject: [PATCH 01/43] Preserve max quantity when reloading shopfront --- app/serializers/api/line_item_serializer.rb | 2 +- spec/features/consumer/shopping/shopping_spec.rb | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/app/serializers/api/line_item_serializer.rb b/app/serializers/api/line_item_serializer.rb index d791febdfc..35d3f9c540 100644 --- a/app/serializers/api/line_item_serializer.rb +++ b/app/serializers/api/line_item_serializer.rb @@ -1,5 +1,5 @@ class Api::LineItemSerializer < ActiveModel::Serializer - attributes :id, :quantity, :price + attributes :id, :quantity, :max_quantity, :price has_one :variant, serializer: Api::VariantSerializer end diff --git a/spec/features/consumer/shopping/shopping_spec.rb b/spec/features/consumer/shopping/shopping_spec.rb index 12e9d8323b..e81a792881 100644 --- a/spec/features/consumer/shopping/shopping_spec.rb +++ b/spec/features/consumer/shopping/shopping_spec.rb @@ -187,7 +187,7 @@ feature "As a consumer I want to shop with a distributor", js: true do visit shop_path end - it "should save group buy data to the cart" do + it "should save group buy data to the cart and display it on shopfront reload" do # -- Quantity fill_in "variants[#{variant.id}]", with: 6 page.should have_in_cart product.name @@ -202,6 +202,11 @@ feature "As a consumer I want to shop with a distributor", js: true do li = Spree::Order.order(:created_at).last.line_items.order(:created_at).last li.max_quantity.should == 7 + + # -- Reload + visit shop_path + page.should have_field "variants[#{variant.id}]", with: 6 + page.should have_field "variant_attributes[#{variant.id}][max_quantity]", with: 7 end end end From a07eabca55e16b9982a7dc7ff0b6d1e3de1455d6 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Wed, 13 Jan 2016 16:00:43 +1100 Subject: [PATCH 02/43] Fit cart to screen and allow scrolling so we can always access all of it --- app/assets/stylesheets/darkswarm/shopping-cart.css.sass | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/assets/stylesheets/darkswarm/shopping-cart.css.sass b/app/assets/stylesheets/darkswarm/shopping-cart.css.sass index 74cec02ce0..9bdedb806c 100644 --- a/app/assets/stylesheets/darkswarm/shopping-cart.css.sass +++ b/app/assets/stylesheets/darkswarm/shopping-cart.css.sass @@ -13,6 +13,9 @@ right: 10px top: 55px width: 480px + overflow-y: auto + max-height: calc(95vh - 55px) + @media screen and (max-width: 640px) width: 96% @@ -48,7 +51,7 @@ .cart-item-delete a.delete font-size: 1.125em - + .item-thumb-image display: none @media screen and (min-width: 640px) From 2c3ff37980c8ffea7ac0266ec70e76d42f3cdd60 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Wed, 13 Jan 2016 16:42:38 +1100 Subject: [PATCH 03/43] Split order cycles controller into parts --- .../order_cycles/controllers/create.js.coffee | 84 ++++++++ .../order_cycles/controllers/edit.js.coffee | 85 ++++++++ .../order_cycle_controller.js.coffee | 204 ------------------ .../admin/order_cycles/order_cycles.js.coffee | 37 +++- 4 files changed, 205 insertions(+), 205 deletions(-) create mode 100644 app/assets/javascripts/admin/order_cycles/controllers/create.js.coffee create mode 100644 app/assets/javascripts/admin/order_cycles/controllers/edit.js.coffee delete mode 100644 app/assets/javascripts/admin/order_cycles/controllers/order_cycle_controller.js.coffee diff --git a/app/assets/javascripts/admin/order_cycles/controllers/create.js.coffee b/app/assets/javascripts/admin/order_cycles/controllers/create.js.coffee new file mode 100644 index 0000000000..69a93653c4 --- /dev/null +++ b/app/assets/javascripts/admin/order_cycles/controllers/create.js.coffee @@ -0,0 +1,84 @@ +angular.module('admin.orderCycles') + .controller('AdminCreateOrderCycleCtrl', ['$scope', '$filter', 'OrderCycle', 'Enterprise', 'EnterpriseFee', 'ocInstance', 'StatusMessage', ($scope, $filter, OrderCycle, Enterprise, EnterpriseFee, ocInstance, StatusMessage) -> + $scope.enterprises = Enterprise.index(coordinator_id: ocInstance.coordinator_id) + $scope.supplier_enterprises = Enterprise.producer_enterprises + $scope.distributor_enterprises = Enterprise.hub_enterprises + $scope.supplied_products = Enterprise.supplied_products + $scope.enterprise_fees = EnterpriseFee.index(coordinator_id: ocInstance.coordinator_id) + + $scope.OrderCycle = OrderCycle + $scope.order_cycle = OrderCycle.new({ coordinator_id: ocInstance.coordinator_id}) + + $scope.StatusMessage = StatusMessage + + $scope.loaded = -> + Enterprise.loaded && EnterpriseFee.loaded + + $scope.suppliedVariants = (enterprise_id) -> + Enterprise.suppliedVariants(enterprise_id) + + $scope.exchangeSelectedVariants = (exchange) -> + OrderCycle.exchangeSelectedVariants(exchange) + + $scope.setExchangeVariants = (exchange, variants, selected) -> + OrderCycle.setExchangeVariants(exchange, variants, selected) + + $scope.enterpriseTotalVariants = (enterprise) -> + Enterprise.totalVariants(enterprise) + + $scope.productSuppliedToOrderCycle = (product) -> + OrderCycle.productSuppliedToOrderCycle(product) + + $scope.variantSuppliedToOrderCycle = (variant) -> + OrderCycle.variantSuppliedToOrderCycle(variant) + + $scope.incomingExchangeVariantsFor = (enterprise_id) -> + $filter('filterExchangeVariants')(OrderCycle.incomingExchangesVariants(), $scope.order_cycle.visible_variants_for_outgoing_exchanges[enterprise_id]) + + $scope.exchangeDirection = (exchange) -> + OrderCycle.exchangeDirection(exchange) + + $scope.enterprisesWithFees = -> + $scope.enterprises[id] for id in OrderCycle.participatingEnterpriseIds() when $scope.enterpriseFeesForEnterprise(id).length > 0 + + $scope.toggleProducts = ($event, exchange) -> + $event.preventDefault() + OrderCycle.toggleProducts(exchange) + + $scope.enterpriseFeesForEnterprise = (enterprise_id) -> + EnterpriseFee.forEnterprise(parseInt(enterprise_id)) + + $scope.addSupplier = ($event) -> + $event.preventDefault() + OrderCycle.addSupplier($scope.new_supplier_id) + + $scope.addDistributor = ($event) -> + $event.preventDefault() + OrderCycle.addDistributor($scope.new_distributor_id) + + $scope.removeExchange = ($event, exchange) -> + $event.preventDefault() + OrderCycle.removeExchange(exchange) + + $scope.addCoordinatorFee = ($event) -> + $event.preventDefault() + OrderCycle.addCoordinatorFee() + + $scope.removeCoordinatorFee = ($event, index) -> + $event.preventDefault() + OrderCycle.removeCoordinatorFee(index) + + $scope.addExchangeFee = ($event, exchange) -> + $event.preventDefault() + OrderCycle.addExchangeFee(exchange) + + $scope.removeExchangeFee = ($event, exchange, index) -> + $event.preventDefault() + OrderCycle.removeExchangeFee(exchange, index) + + $scope.removeDistributionOfVariant = (variant_id) -> + OrderCycle.removeDistributionOfVariant(variant_id) + + $scope.submit = (destination) -> + OrderCycle.create(destination) + ]) diff --git a/app/assets/javascripts/admin/order_cycles/controllers/edit.js.coffee b/app/assets/javascripts/admin/order_cycles/controllers/edit.js.coffee new file mode 100644 index 0000000000..eb70662abd --- /dev/null +++ b/app/assets/javascripts/admin/order_cycles/controllers/edit.js.coffee @@ -0,0 +1,85 @@ +angular.module('admin.orderCycles') + .controller('AdminEditOrderCycleCtrl', ['$scope', '$filter', '$location', 'OrderCycle', 'Enterprise', 'EnterpriseFee', 'StatusMessage', ($scope, $filter, $location, OrderCycle, Enterprise, EnterpriseFee, StatusMessage) -> + order_cycle_id = $location.absUrl().match(/\/admin\/order_cycles\/(\d+)/)[1] + $scope.enterprises = Enterprise.index(order_cycle_id: order_cycle_id) + $scope.supplier_enterprises = Enterprise.producer_enterprises + $scope.distributor_enterprises = Enterprise.hub_enterprises + $scope.supplied_products = Enterprise.supplied_products + $scope.enterprise_fees = EnterpriseFee.index(order_cycle_id: order_cycle_id) + + $scope.OrderCycle = OrderCycle + $scope.order_cycle = OrderCycle.load(order_cycle_id) + + $scope.StatusMessage = StatusMessage + + $scope.loaded = -> + Enterprise.loaded && EnterpriseFee.loaded && OrderCycle.loaded + + $scope.suppliedVariants = (enterprise_id) -> + Enterprise.suppliedVariants(enterprise_id) + + $scope.exchangeSelectedVariants = (exchange) -> + OrderCycle.exchangeSelectedVariants(exchange) + + $scope.setExchangeVariants = (exchange, variants, selected) -> + OrderCycle.setExchangeVariants(exchange, variants, selected) + + $scope.enterpriseTotalVariants = (enterprise) -> + Enterprise.totalVariants(enterprise) + + $scope.productSuppliedToOrderCycle = (product) -> + OrderCycle.productSuppliedToOrderCycle(product) + + $scope.variantSuppliedToOrderCycle = (variant) -> + OrderCycle.variantSuppliedToOrderCycle(variant) + + $scope.incomingExchangeVariantsFor = (enterprise_id) -> + $filter('filterExchangeVariants')(OrderCycle.incomingExchangesVariants(), $scope.order_cycle.visible_variants_for_outgoing_exchanges[enterprise_id]) + + $scope.exchangeDirection = (exchange) -> + OrderCycle.exchangeDirection(exchange) + + $scope.enterprisesWithFees = -> + $scope.enterprises[id] for id in OrderCycle.participatingEnterpriseIds() when $scope.enterpriseFeesForEnterprise(id).length > 0 + + $scope.toggleProducts = ($event, exchange) -> + $event.preventDefault() + OrderCycle.toggleProducts(exchange) + + $scope.enterpriseFeesForEnterprise = (enterprise_id) -> + EnterpriseFee.forEnterprise(parseInt(enterprise_id)) + + $scope.addSupplier = ($event) -> + $event.preventDefault() + OrderCycle.addSupplier($scope.new_supplier_id) + + $scope.addDistributor = ($event) -> + $event.preventDefault() + OrderCycle.addDistributor($scope.new_distributor_id) + + $scope.removeExchange = ($event, exchange) -> + $event.preventDefault() + OrderCycle.removeExchange(exchange) + + $scope.addCoordinatorFee = ($event) -> + $event.preventDefault() + OrderCycle.addCoordinatorFee() + + $scope.removeCoordinatorFee = ($event, index) -> + $event.preventDefault() + OrderCycle.removeCoordinatorFee(index) + + $scope.addExchangeFee = ($event, exchange) -> + $event.preventDefault() + OrderCycle.addExchangeFee(exchange) + + $scope.removeExchangeFee = ($event, exchange, index) -> + $event.preventDefault() + OrderCycle.removeExchangeFee(exchange, index) + + $scope.removeDistributionOfVariant = (variant_id) -> + OrderCycle.removeDistributionOfVariant(variant_id) + + $scope.submit = (destination) -> + OrderCycle.update(destination) + ]) diff --git a/app/assets/javascripts/admin/order_cycles/controllers/order_cycle_controller.js.coffee b/app/assets/javascripts/admin/order_cycles/controllers/order_cycle_controller.js.coffee deleted file mode 100644 index 40428e1f73..0000000000 --- a/app/assets/javascripts/admin/order_cycles/controllers/order_cycle_controller.js.coffee +++ /dev/null @@ -1,204 +0,0 @@ -angular.module('admin.orderCycles', ['ngResource', 'admin.utils']) - .controller('AdminCreateOrderCycleCtrl', ['$scope', '$filter', 'OrderCycle', 'Enterprise', 'EnterpriseFee', 'ocInstance', 'StatusMessage', ($scope, $filter, OrderCycle, Enterprise, EnterpriseFee, ocInstance, StatusMessage) -> - $scope.enterprises = Enterprise.index(coordinator_id: ocInstance.coordinator_id) - $scope.supplier_enterprises = Enterprise.producer_enterprises - $scope.distributor_enterprises = Enterprise.hub_enterprises - $scope.supplied_products = Enterprise.supplied_products - $scope.enterprise_fees = EnterpriseFee.index(coordinator_id: ocInstance.coordinator_id) - - $scope.OrderCycle = OrderCycle - $scope.order_cycle = OrderCycle.new({ coordinator_id: ocInstance.coordinator_id}) - - $scope.StatusMessage = StatusMessage - - $scope.loaded = -> - Enterprise.loaded && EnterpriseFee.loaded - - $scope.suppliedVariants = (enterprise_id) -> - Enterprise.suppliedVariants(enterprise_id) - - $scope.exchangeSelectedVariants = (exchange) -> - OrderCycle.exchangeSelectedVariants(exchange) - - $scope.setExchangeVariants = (exchange, variants, selected) -> - OrderCycle.setExchangeVariants(exchange, variants, selected) - - $scope.enterpriseTotalVariants = (enterprise) -> - Enterprise.totalVariants(enterprise) - - $scope.productSuppliedToOrderCycle = (product) -> - OrderCycle.productSuppliedToOrderCycle(product) - - $scope.variantSuppliedToOrderCycle = (variant) -> - OrderCycle.variantSuppliedToOrderCycle(variant) - - $scope.incomingExchangeVariantsFor = (enterprise_id) -> - $filter('filterExchangeVariants')(OrderCycle.incomingExchangesVariants(), $scope.order_cycle.visible_variants_for_outgoing_exchanges[enterprise_id]) - - $scope.exchangeDirection = (exchange) -> - OrderCycle.exchangeDirection(exchange) - - $scope.enterprisesWithFees = -> - $scope.enterprises[id] for id in OrderCycle.participatingEnterpriseIds() when $scope.enterpriseFeesForEnterprise(id).length > 0 - - $scope.toggleProducts = ($event, exchange) -> - $event.preventDefault() - OrderCycle.toggleProducts(exchange) - - $scope.enterpriseFeesForEnterprise = (enterprise_id) -> - EnterpriseFee.forEnterprise(parseInt(enterprise_id)) - - $scope.addSupplier = ($event) -> - $event.preventDefault() - OrderCycle.addSupplier($scope.new_supplier_id) - - $scope.addDistributor = ($event) -> - $event.preventDefault() - OrderCycle.addDistributor($scope.new_distributor_id) - - $scope.removeExchange = ($event, exchange) -> - $event.preventDefault() - OrderCycle.removeExchange(exchange) - - $scope.addCoordinatorFee = ($event) -> - $event.preventDefault() - OrderCycle.addCoordinatorFee() - - $scope.removeCoordinatorFee = ($event, index) -> - $event.preventDefault() - OrderCycle.removeCoordinatorFee(index) - - $scope.addExchangeFee = ($event, exchange) -> - $event.preventDefault() - OrderCycle.addExchangeFee(exchange) - - $scope.removeExchangeFee = ($event, exchange, index) -> - $event.preventDefault() - OrderCycle.removeExchangeFee(exchange, index) - - $scope.removeDistributionOfVariant = (variant_id) -> - OrderCycle.removeDistributionOfVariant(variant_id) - - $scope.submit = (destination) -> - OrderCycle.create(destination) - ]) - - .controller('AdminEditOrderCycleCtrl', ['$scope', '$filter', '$location', 'OrderCycle', 'Enterprise', 'EnterpriseFee', 'StatusMessage', ($scope, $filter, $location, OrderCycle, Enterprise, EnterpriseFee, StatusMessage) -> - order_cycle_id = $location.absUrl().match(/\/admin\/order_cycles\/(\d+)/)[1] - $scope.enterprises = Enterprise.index(order_cycle_id: order_cycle_id) - $scope.supplier_enterprises = Enterprise.producer_enterprises - $scope.distributor_enterprises = Enterprise.hub_enterprises - $scope.supplied_products = Enterprise.supplied_products - $scope.enterprise_fees = EnterpriseFee.index(order_cycle_id: order_cycle_id) - - $scope.OrderCycle = OrderCycle - $scope.order_cycle = OrderCycle.load(order_cycle_id) - - $scope.StatusMessage = StatusMessage - - $scope.loaded = -> - Enterprise.loaded && EnterpriseFee.loaded && OrderCycle.loaded - - $scope.suppliedVariants = (enterprise_id) -> - Enterprise.suppliedVariants(enterprise_id) - - $scope.exchangeSelectedVariants = (exchange) -> - OrderCycle.exchangeSelectedVariants(exchange) - - $scope.setExchangeVariants = (exchange, variants, selected) -> - OrderCycle.setExchangeVariants(exchange, variants, selected) - - $scope.enterpriseTotalVariants = (enterprise) -> - Enterprise.totalVariants(enterprise) - - $scope.productSuppliedToOrderCycle = (product) -> - OrderCycle.productSuppliedToOrderCycle(product) - - $scope.variantSuppliedToOrderCycle = (variant) -> - OrderCycle.variantSuppliedToOrderCycle(variant) - - $scope.incomingExchangeVariantsFor = (enterprise_id) -> - $filter('filterExchangeVariants')(OrderCycle.incomingExchangesVariants(), $scope.order_cycle.visible_variants_for_outgoing_exchanges[enterprise_id]) - - $scope.exchangeDirection = (exchange) -> - OrderCycle.exchangeDirection(exchange) - - $scope.enterprisesWithFees = -> - $scope.enterprises[id] for id in OrderCycle.participatingEnterpriseIds() when $scope.enterpriseFeesForEnterprise(id).length > 0 - - $scope.toggleProducts = ($event, exchange) -> - $event.preventDefault() - OrderCycle.toggleProducts(exchange) - - $scope.enterpriseFeesForEnterprise = (enterprise_id) -> - EnterpriseFee.forEnterprise(parseInt(enterprise_id)) - - $scope.addSupplier = ($event) -> - $event.preventDefault() - OrderCycle.addSupplier($scope.new_supplier_id) - - $scope.addDistributor = ($event) -> - $event.preventDefault() - OrderCycle.addDistributor($scope.new_distributor_id) - - $scope.removeExchange = ($event, exchange) -> - $event.preventDefault() - OrderCycle.removeExchange(exchange) - - $scope.addCoordinatorFee = ($event) -> - $event.preventDefault() - OrderCycle.addCoordinatorFee() - - $scope.removeCoordinatorFee = ($event, index) -> - $event.preventDefault() - OrderCycle.removeCoordinatorFee(index) - - $scope.addExchangeFee = ($event, exchange) -> - $event.preventDefault() - OrderCycle.addExchangeFee(exchange) - - $scope.removeExchangeFee = ($event, exchange, index) -> - $event.preventDefault() - OrderCycle.removeExchangeFee(exchange, index) - - $scope.removeDistributionOfVariant = (variant_id) -> - OrderCycle.removeDistributionOfVariant(variant_id) - - $scope.submit = (destination) -> - OrderCycle.update(destination) - ]) - - .config(['$httpProvider', ($httpProvider) -> - $httpProvider.defaults.headers.common['X-CSRF-Token'] = $('meta[name=csrf-token]').attr('content') - ]) - - .directive('datetimepicker', ['$parse', ($parse) -> - (scope, element, attrs) -> - # using $parse instead of scope[attrs.datetimepicker] for cases - # where attrs.datetimepicker is 'foo.bar.lol' - $(element).datetimepicker - dateFormat: 'yy-mm-dd' - timeFormat: 'HH:mm:ss' - showOn: "button" - buttonImage: "<%= asset_path 'datepicker/cal.gif' %>" - buttonImageOnly: true - stepMinute: 15 - onSelect: (dateText, inst) -> - scope.$apply -> - parsed = $parse(attrs.datetimepicker) - parsed.assign(scope, dateText) - ]) - - .directive('ofnOnChange', -> - (scope, element, attrs) -> - element.bind 'change', -> - scope.$apply(attrs.ofnOnChange) - ) - - .directive('ofnSyncDistributions', -> - (scope, element, attrs) -> - element.bind 'change', -> - if !$(this).is(':checked') - scope.$apply -> - scope.removeDistributionOfVariant(attrs.ofnSyncDistributions) - ) diff --git a/app/assets/javascripts/admin/order_cycles/order_cycles.js.coffee b/app/assets/javascripts/admin/order_cycles/order_cycles.js.coffee index 2f97440e71..cbd66ea7f3 100644 --- a/app/assets/javascripts/admin/order_cycles/order_cycles.js.coffee +++ b/app/assets/javascripts/admin/order_cycles/order_cycles.js.coffee @@ -1 +1,36 @@ -angular.module('admin.orderCycles', ['ngResource', 'admin.indexUtils']) +angular.module('admin.orderCycles', ['ngResource', 'admin.utils', 'admin.indexUtils']) + + .config(['$httpProvider', ($httpProvider) -> + $httpProvider.defaults.headers.common['X-CSRF-Token'] = $('meta[name=csrf-token]').attr('content') + ]) + + .directive('datetimepicker', ['$parse', ($parse) -> + (scope, element, attrs) -> + # using $parse instead of scope[attrs.datetimepicker] for cases + # where attrs.datetimepicker is 'foo.bar.lol' + $(element).datetimepicker + dateFormat: 'yy-mm-dd' + timeFormat: 'HH:mm:ss' + showOn: "button" + buttonImage: "<%= asset_path 'datepicker/cal.gif' %>" + buttonImageOnly: true + stepMinute: 15 + onSelect: (dateText, inst) -> + scope.$apply -> + parsed = $parse(attrs.datetimepicker) + parsed.assign(scope, dateText) + ]) + + .directive('ofnOnChange', -> + (scope, element, attrs) -> + element.bind 'change', -> + scope.$apply(attrs.ofnOnChange) + ) + + .directive('ofnSyncDistributions', -> + (scope, element, attrs) -> + element.bind 'change', -> + if !$(this).is(':checked') + scope.$apply -> + scope.removeDistributionOfVariant(attrs.ofnSyncDistributions) + ) From 406338ea058905a4573e03b619e776794d35d10b Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Wed, 13 Jan 2016 16:44:22 +1100 Subject: [PATCH 04/43] Remove cruft --- .../admin/order_cycles/controllers/create.js.coffee | 3 +-- .../admin/order_cycles/controllers/edit.js.coffee | 3 +-- .../admin/order_cycles/order_cycles.js.coffee | 12 ++++-------- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/app/assets/javascripts/admin/order_cycles/controllers/create.js.coffee b/app/assets/javascripts/admin/order_cycles/controllers/create.js.coffee index 69a93653c4..2c98d60f0e 100644 --- a/app/assets/javascripts/admin/order_cycles/controllers/create.js.coffee +++ b/app/assets/javascripts/admin/order_cycles/controllers/create.js.coffee @@ -1,5 +1,5 @@ angular.module('admin.orderCycles') - .controller('AdminCreateOrderCycleCtrl', ['$scope', '$filter', 'OrderCycle', 'Enterprise', 'EnterpriseFee', 'ocInstance', 'StatusMessage', ($scope, $filter, OrderCycle, Enterprise, EnterpriseFee, ocInstance, StatusMessage) -> + .controller 'AdminCreateOrderCycleCtrl', ($scope, $filter, OrderCycle, Enterprise, EnterpriseFee, ocInstance, StatusMessage) -> $scope.enterprises = Enterprise.index(coordinator_id: ocInstance.coordinator_id) $scope.supplier_enterprises = Enterprise.producer_enterprises $scope.distributor_enterprises = Enterprise.hub_enterprises @@ -81,4 +81,3 @@ angular.module('admin.orderCycles') $scope.submit = (destination) -> OrderCycle.create(destination) - ]) diff --git a/app/assets/javascripts/admin/order_cycles/controllers/edit.js.coffee b/app/assets/javascripts/admin/order_cycles/controllers/edit.js.coffee index eb70662abd..fd426eb455 100644 --- a/app/assets/javascripts/admin/order_cycles/controllers/edit.js.coffee +++ b/app/assets/javascripts/admin/order_cycles/controllers/edit.js.coffee @@ -1,5 +1,5 @@ angular.module('admin.orderCycles') - .controller('AdminEditOrderCycleCtrl', ['$scope', '$filter', '$location', 'OrderCycle', 'Enterprise', 'EnterpriseFee', 'StatusMessage', ($scope, $filter, $location, OrderCycle, Enterprise, EnterpriseFee, StatusMessage) -> + .controller 'AdminEditOrderCycleCtrl', ($scope, $filter, $location, OrderCycle, Enterprise, EnterpriseFee, StatusMessage) -> order_cycle_id = $location.absUrl().match(/\/admin\/order_cycles\/(\d+)/)[1] $scope.enterprises = Enterprise.index(order_cycle_id: order_cycle_id) $scope.supplier_enterprises = Enterprise.producer_enterprises @@ -82,4 +82,3 @@ angular.module('admin.orderCycles') $scope.submit = (destination) -> OrderCycle.update(destination) - ]) diff --git a/app/assets/javascripts/admin/order_cycles/order_cycles.js.coffee b/app/assets/javascripts/admin/order_cycles/order_cycles.js.coffee index cbd66ea7f3..a75fdad58c 100644 --- a/app/assets/javascripts/admin/order_cycles/order_cycles.js.coffee +++ b/app/assets/javascripts/admin/order_cycles/order_cycles.js.coffee @@ -1,10 +1,9 @@ angular.module('admin.orderCycles', ['ngResource', 'admin.utils', 'admin.indexUtils']) - .config(['$httpProvider', ($httpProvider) -> + .config ($httpProvider) -> $httpProvider.defaults.headers.common['X-CSRF-Token'] = $('meta[name=csrf-token]').attr('content') - ]) - .directive('datetimepicker', ['$parse', ($parse) -> + .directive 'datetimepicker', ($parse) -> (scope, element, attrs) -> # using $parse instead of scope[attrs.datetimepicker] for cases # where attrs.datetimepicker is 'foo.bar.lol' @@ -19,18 +18,15 @@ angular.module('admin.orderCycles', ['ngResource', 'admin.utils', 'admin.indexUt scope.$apply -> parsed = $parse(attrs.datetimepicker) parsed.assign(scope, dateText) - ]) - .directive('ofnOnChange', -> + .directive 'ofnOnChange', -> (scope, element, attrs) -> element.bind 'change', -> scope.$apply(attrs.ofnOnChange) - ) - .directive('ofnSyncDistributions', -> + .directive 'ofnSyncDistributions', -> (scope, element, attrs) -> element.bind 'change', -> if !$(this).is(':checked') scope.$apply -> scope.removeDistributionOfVariant(attrs.ofnSyncDistributions) - ) From f11e878e7fc03017f1236754984b9639128bde4f Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 20 Nov 2015 11:12:33 +1100 Subject: [PATCH 05/43] WIP: Reorganising variant overrides javascript files --- .../admin/{ => index_utils}/services/data_fetcher.js.coffee | 0 .../admin/{ => index_utils}/services/indexer.js.coffee | 0 .../admin/{ => index_utils}/services/paged_fetcher.js.coffee | 0 .../admin/{ => index_utils}/services/spree_api_auth.js.coffee | 0 .../admin/{ => index_utils}/services/status_message.js.coffee | 0 .../controllers/variant_overrides_controller.js.coffee | 0 .../directives/track_variant_override.js.coffee | 0 .../filters/hub_permissions_filter.js.coffee | 0 .../services/dirty_variant_overrides.js.coffee | 0 .../{ => variant_overrides}/services/variant_overrides.js.coffee | 0 10 files changed, 0 insertions(+), 0 deletions(-) rename app/assets/javascripts/admin/{ => index_utils}/services/data_fetcher.js.coffee (100%) rename app/assets/javascripts/admin/{ => index_utils}/services/indexer.js.coffee (100%) rename app/assets/javascripts/admin/{ => index_utils}/services/paged_fetcher.js.coffee (100%) rename app/assets/javascripts/admin/{ => index_utils}/services/spree_api_auth.js.coffee (100%) rename app/assets/javascripts/admin/{ => index_utils}/services/status_message.js.coffee (100%) rename app/assets/javascripts/admin/{ => variant_overrides}/controllers/variant_overrides_controller.js.coffee (100%) rename app/assets/javascripts/admin/{ => variant_overrides}/directives/track_variant_override.js.coffee (100%) rename app/assets/javascripts/admin/{ => variant_overrides}/filters/hub_permissions_filter.js.coffee (100%) rename app/assets/javascripts/admin/{ => variant_overrides}/services/dirty_variant_overrides.js.coffee (100%) rename app/assets/javascripts/admin/{ => variant_overrides}/services/variant_overrides.js.coffee (100%) diff --git a/app/assets/javascripts/admin/services/data_fetcher.js.coffee b/app/assets/javascripts/admin/index_utils/services/data_fetcher.js.coffee similarity index 100% rename from app/assets/javascripts/admin/services/data_fetcher.js.coffee rename to app/assets/javascripts/admin/index_utils/services/data_fetcher.js.coffee diff --git a/app/assets/javascripts/admin/services/indexer.js.coffee b/app/assets/javascripts/admin/index_utils/services/indexer.js.coffee similarity index 100% rename from app/assets/javascripts/admin/services/indexer.js.coffee rename to app/assets/javascripts/admin/index_utils/services/indexer.js.coffee diff --git a/app/assets/javascripts/admin/services/paged_fetcher.js.coffee b/app/assets/javascripts/admin/index_utils/services/paged_fetcher.js.coffee similarity index 100% rename from app/assets/javascripts/admin/services/paged_fetcher.js.coffee rename to app/assets/javascripts/admin/index_utils/services/paged_fetcher.js.coffee diff --git a/app/assets/javascripts/admin/services/spree_api_auth.js.coffee b/app/assets/javascripts/admin/index_utils/services/spree_api_auth.js.coffee similarity index 100% rename from app/assets/javascripts/admin/services/spree_api_auth.js.coffee rename to app/assets/javascripts/admin/index_utils/services/spree_api_auth.js.coffee diff --git a/app/assets/javascripts/admin/services/status_message.js.coffee b/app/assets/javascripts/admin/index_utils/services/status_message.js.coffee similarity index 100% rename from app/assets/javascripts/admin/services/status_message.js.coffee rename to app/assets/javascripts/admin/index_utils/services/status_message.js.coffee diff --git a/app/assets/javascripts/admin/controllers/variant_overrides_controller.js.coffee b/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee similarity index 100% rename from app/assets/javascripts/admin/controllers/variant_overrides_controller.js.coffee rename to app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee diff --git a/app/assets/javascripts/admin/directives/track_variant_override.js.coffee b/app/assets/javascripts/admin/variant_overrides/directives/track_variant_override.js.coffee similarity index 100% rename from app/assets/javascripts/admin/directives/track_variant_override.js.coffee rename to app/assets/javascripts/admin/variant_overrides/directives/track_variant_override.js.coffee diff --git a/app/assets/javascripts/admin/filters/hub_permissions_filter.js.coffee b/app/assets/javascripts/admin/variant_overrides/filters/hub_permissions_filter.js.coffee similarity index 100% rename from app/assets/javascripts/admin/filters/hub_permissions_filter.js.coffee rename to app/assets/javascripts/admin/variant_overrides/filters/hub_permissions_filter.js.coffee diff --git a/app/assets/javascripts/admin/services/dirty_variant_overrides.js.coffee b/app/assets/javascripts/admin/variant_overrides/services/dirty_variant_overrides.js.coffee similarity index 100% rename from app/assets/javascripts/admin/services/dirty_variant_overrides.js.coffee rename to app/assets/javascripts/admin/variant_overrides/services/dirty_variant_overrides.js.coffee diff --git a/app/assets/javascripts/admin/services/variant_overrides.js.coffee b/app/assets/javascripts/admin/variant_overrides/services/variant_overrides.js.coffee similarity index 100% rename from app/assets/javascripts/admin/services/variant_overrides.js.coffee rename to app/assets/javascripts/admin/variant_overrides/services/variant_overrides.js.coffee From 4237a83028a6922027e6802a5b4eebcbc316709d Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 20 Nov 2015 11:33:46 +1100 Subject: [PATCH 06/43] Moving components required for variant overrides into appropriate modules --- app/assets/javascripts/admin/all.js | 1 + .../index_utils/services/data_fetcher.js.coffee | 4 ++-- .../admin/index_utils/services/indexer.js.coffee | 2 +- .../index_utils/services/paged_fetcher.js.coffee | 4 ++-- .../index_utils/services/spree_api_auth.js.coffee | 2 +- .../index_utils/services/status_message.js.coffee | 2 +- .../variant_overrides_controller.js.coffee | 2 +- .../directives/track_variant_override.js.coffee | 2 +- .../filters/hub_permissions_filter.js.coffee | 2 +- .../services/dirty_variant_overrides.js.coffee | 2 +- .../services/variant_overrides.js.coffee | 4 ++-- .../variant_overrides/variant_overrides.js.coffee | 1 + app/helpers/admin/injection_helper.rb | 14 +++++++------- app/views/admin/variant_overrides/_data.html.haml | 4 ++-- app/views/admin/variant_overrides/index.html.haml | 2 +- .../variant_overrides_controller_spec.js.coffee | 4 ++-- .../dirty_variant_overrides_spec.js.coffee | 2 +- .../unit/admin/services/indexer_spec.js.coffee | 2 +- .../services/variant_overrides_spec.js.coffee | 2 +- 19 files changed, 30 insertions(+), 28 deletions(-) create mode 100644 app/assets/javascripts/admin/variant_overrides/variant_overrides.js.coffee diff --git a/app/assets/javascripts/admin/all.js b/app/assets/javascripts/admin/all.js index c0fa530626..7d3e94194d 100644 --- a/app/assets/javascripts/admin/all.js +++ b/app/assets/javascripts/admin/all.js @@ -39,6 +39,7 @@ //= require ./taxons/taxons //= require ./utils/utils //= require ./users/users +//= require ./variant_overrides/variant_overrides //= require textAngular.min.js //= require textAngular-sanitize.min.js //= require ../shared/bindonce.min.js diff --git a/app/assets/javascripts/admin/index_utils/services/data_fetcher.js.coffee b/app/assets/javascripts/admin/index_utils/services/data_fetcher.js.coffee index 735e4cc6bb..bf5580a3b2 100644 --- a/app/assets/javascripts/admin/index_utils/services/data_fetcher.js.coffee +++ b/app/assets/javascripts/admin/index_utils/services/data_fetcher.js.coffee @@ -1,4 +1,4 @@ -angular.module("ofn.admin").factory "dataFetcher", [ +angular.module("admin.indexUtils").factory "dataFetcher", [ "$http", "$q" ($http, $q) -> return (dataLocation) -> @@ -9,4 +9,4 @@ angular.module("ofn.admin").factory "dataFetcher", [ deferred.reject() deferred.promise -] \ No newline at end of file +] diff --git a/app/assets/javascripts/admin/index_utils/services/indexer.js.coffee b/app/assets/javascripts/admin/index_utils/services/indexer.js.coffee index f9a9688a2f..295df46be3 100644 --- a/app/assets/javascripts/admin/index_utils/services/indexer.js.coffee +++ b/app/assets/javascripts/admin/index_utils/services/indexer.js.coffee @@ -4,7 +4,7 @@ # Indexer.index producers # -> {1: {id: 1, name: 'one'}, 2: {id: 2, name: 'two'}} -angular.module("ofn.admin").factory 'Indexer', -> +angular.module("admin.indexUtils").factory 'Indexer', -> new class Indexer index: (data, key='id') -> index = {} diff --git a/app/assets/javascripts/admin/index_utils/services/paged_fetcher.js.coffee b/app/assets/javascripts/admin/index_utils/services/paged_fetcher.js.coffee index 9281ed6a42..d65887bb2c 100644 --- a/app/assets/javascripts/admin/index_utils/services/paged_fetcher.js.coffee +++ b/app/assets/javascripts/admin/index_utils/services/paged_fetcher.js.coffee @@ -1,4 +1,4 @@ -angular.module("ofn.admin").factory "PagedFetcher", (dataFetcher) -> +angular.module("admin.indexUtils").factory "PagedFetcher", (dataFetcher) -> new class PagedFetcher # Given a URL like http://example.com/foo?page=::page::&per_page=20 # And the response includes an attribute pages with the number of pages to fetch @@ -13,4 +13,4 @@ angular.module("ofn.admin").factory "PagedFetcher", (dataFetcher) -> processData data urlForPage: (url, page) -> - url.replace("::page::", page) \ No newline at end of file + url.replace("::page::", page) diff --git a/app/assets/javascripts/admin/index_utils/services/spree_api_auth.js.coffee b/app/assets/javascripts/admin/index_utils/services/spree_api_auth.js.coffee index e606882bc5..3ed4dd9bf7 100644 --- a/app/assets/javascripts/admin/index_utils/services/spree_api_auth.js.coffee +++ b/app/assets/javascripts/admin/index_utils/services/spree_api_auth.js.coffee @@ -1,4 +1,4 @@ -angular.module("ofn.admin").factory "SpreeApiAuth", ($q, $http, SpreeApiKey) -> +angular.module("admin.indexUtils").factory "SpreeApiAuth", ($q, $http, SpreeApiKey) -> new class SpreeApiAuth authorise: -> deferred = $q.defer() diff --git a/app/assets/javascripts/admin/index_utils/services/status_message.js.coffee b/app/assets/javascripts/admin/index_utils/services/status_message.js.coffee index aaa55cf339..9cc9547e39 100644 --- a/app/assets/javascripts/admin/index_utils/services/status_message.js.coffee +++ b/app/assets/javascripts/admin/index_utils/services/status_message.js.coffee @@ -1,4 +1,4 @@ -angular.module("ofn.admin").factory "StatusMessage", ($timeout) -> +angular.module("admin.indexUtils").factory "StatusMessage", ($timeout) -> new class StatusMessage types: progress: {timeout: false, style: {color: '#ff9906'}} diff --git a/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee b/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee index bcc633805f..73ddfc8b2b 100644 --- a/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee +++ b/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee @@ -1,4 +1,4 @@ -angular.module("ofn.admin").controller "AdminVariantOverridesCtrl", ($scope, $timeout, Indexer, SpreeApiAuth, PagedFetcher, StatusMessage, hubs, producers, hubPermissions, VariantOverrides, DirtyVariantOverrides) -> +angular.module("admin.variantOverrides").controller "AdminVariantOverridesCtrl", ($scope, $timeout, Indexer, SpreeApiAuth, PagedFetcher, StatusMessage, hubs, producers, hubPermissions, VariantOverrides, DirtyVariantOverrides) -> $scope.hubs = hubs $scope.hub = null $scope.products = [] diff --git a/app/assets/javascripts/admin/variant_overrides/directives/track_variant_override.js.coffee b/app/assets/javascripts/admin/variant_overrides/directives/track_variant_override.js.coffee index bb8117a757..944fdf4a94 100644 --- a/app/assets/javascripts/admin/variant_overrides/directives/track_variant_override.js.coffee +++ b/app/assets/javascripts/admin/variant_overrides/directives/track_variant_override.js.coffee @@ -1,4 +1,4 @@ -angular.module("ofn.admin").directive "ofnTrackVariantOverride", (DirtyVariantOverrides) -> +angular.module("admin.variantOverrides").directive "ofnTrackVariantOverride", (DirtyVariantOverrides) -> require: "ngModel" link: (scope, element, attrs, ngModel) -> ngModel.$parsers.push (viewValue) -> diff --git a/app/assets/javascripts/admin/variant_overrides/filters/hub_permissions_filter.js.coffee b/app/assets/javascripts/admin/variant_overrides/filters/hub_permissions_filter.js.coffee index 5db7a6d40e..39b5e77839 100644 --- a/app/assets/javascripts/admin/variant_overrides/filters/hub_permissions_filter.js.coffee +++ b/app/assets/javascripts/admin/variant_overrides/filters/hub_permissions_filter.js.coffee @@ -1,4 +1,4 @@ -angular.module("ofn.admin").filter "hubPermissions", ($filter) -> +angular.module("admin.variantOverrides").filter "hubPermissions", ($filter) -> return (products, hubPermissions, hub_id) -> return [] if !hub_id return $filter('filter')(products, ((product) -> hubPermissions[hub_id].indexOf(product.producer_id) > -1), true) diff --git a/app/assets/javascripts/admin/variant_overrides/services/dirty_variant_overrides.js.coffee b/app/assets/javascripts/admin/variant_overrides/services/dirty_variant_overrides.js.coffee index 82e7772982..053c6cbfa1 100644 --- a/app/assets/javascripts/admin/variant_overrides/services/dirty_variant_overrides.js.coffee +++ b/app/assets/javascripts/admin/variant_overrides/services/dirty_variant_overrides.js.coffee @@ -1,4 +1,4 @@ -angular.module("ofn.admin").factory "DirtyVariantOverrides", ($http) -> +angular.module("admin.variantOverrides").factory "DirtyVariantOverrides", ($http) -> new class DirtyVariantOverrides dirtyVariantOverrides: {} diff --git a/app/assets/javascripts/admin/variant_overrides/services/variant_overrides.js.coffee b/app/assets/javascripts/admin/variant_overrides/services/variant_overrides.js.coffee index 28d65eab03..c8ea397343 100644 --- a/app/assets/javascripts/admin/variant_overrides/services/variant_overrides.js.coffee +++ b/app/assets/javascripts/admin/variant_overrides/services/variant_overrides.js.coffee @@ -1,4 +1,4 @@ -angular.module("ofn.admin").factory "VariantOverrides", (variantOverrides, Indexer) -> +angular.module("admin.variantOverrides").factory "VariantOverrides", (variantOverrides) -> new class VariantOverrides variantOverrides: {} @@ -20,4 +20,4 @@ angular.module("ofn.admin").factory "VariantOverrides", (variantOverrides, Index updateIds: (updatedVos) -> for vo in updatedVos - @variantOverrides[vo.hub_id][vo.variant_id].id = vo.id \ No newline at end of file + @variantOverrides[vo.hub_id][vo.variant_id].id = vo.id diff --git a/app/assets/javascripts/admin/variant_overrides/variant_overrides.js.coffee b/app/assets/javascripts/admin/variant_overrides/variant_overrides.js.coffee new file mode 100644 index 0000000000..7a6f1ab2fa --- /dev/null +++ b/app/assets/javascripts/admin/variant_overrides/variant_overrides.js.coffee @@ -0,0 +1 @@ +angular.module("admin.variantOverrides", ["admin.indexUtils"]) diff --git a/app/helpers/admin/injection_helper.rb b/app/helpers/admin/injection_helper.rb index 6036447d9b..343e15ef29 100644 --- a/app/helpers/admin/injection_helper.rb +++ b/app/helpers/admin/injection_helper.rb @@ -31,12 +31,12 @@ module Admin admin_inject_json_ams_array ngModule, "shops", @shops, Api::Admin::IdNameSerializer end - def admin_inject_hubs - admin_inject_json_ams_array "ofn.admin", "hubs", @hubs, Api::Admin::IdNameSerializer + def admin_inject_hubs(opts={module: 'ofn.admin'}) + admin_inject_json_ams_array opts[:module], "hubs", @hubs, Api::Admin::IdNameSerializer end - def admin_inject_producers - admin_inject_json_ams_array "ofn.admin", "producers", @producers, Api::Admin::IdNameSerializer + def admin_inject_producers(opts={module: 'ofn.admin'}) + admin_inject_json_ams_array opts[:module], "producers", @producers, Api::Admin::IdNameSerializer end def admin_inject_enterprise_permissions @@ -49,7 +49,7 @@ module Admin end def admin_inject_hub_permissions - render partial: "admin/json/injection_ams", locals: {ngModule: "ofn.admin", name: "hubPermissions", json: @hub_permissions.to_json} + render partial: "admin/json/injection_ams", locals: {ngModule: "admin.variantOverrides", name: "hubPermissions", json: @hub_permissions.to_json} end def admin_inject_products @@ -69,7 +69,7 @@ module Admin end def admin_inject_variant_overrides - admin_inject_json_ams_array "ofn.admin", "variantOverrides", @variant_overrides, Api::Admin::VariantOverrideSerializer + admin_inject_json_ams_array "admin.variantOverrides", "variantOverrides", @variant_overrides, Api::Admin::VariantOverrideSerializer end def admin_inject_order_cycle_instance @@ -85,7 +85,7 @@ module Admin end def admin_inject_spree_api_key - render partial: "admin/json/injection_ams", locals: {ngModule: 'ofn.admin', name: 'SpreeApiKey', json: "'#{@spree_api_key.to_s}'"} + render partial: "admin/json/injection_ams", locals: {ngModule: 'admin.indexUtils', name: 'SpreeApiKey', json: "'#{@spree_api_key.to_s}'"} end def admin_inject_json_ams(ngModule, name, data, serializer, opts = {}) diff --git a/app/views/admin/variant_overrides/_data.html.haml b/app/views/admin/variant_overrides/_data.html.haml index 3b5f7f125c..64a7619ea7 100644 --- a/app/views/admin/variant_overrides/_data.html.haml +++ b/app/views/admin/variant_overrides/_data.html.haml @@ -1,5 +1,5 @@ = admin_inject_spree_api_key -= admin_inject_hubs += admin_inject_hubs module: 'admin.variantOverrides' = admin_inject_hub_permissions -= admin_inject_producers += admin_inject_producers module: 'admin.variantOverrides' = admin_inject_variant_overrides diff --git a/app/views/admin/variant_overrides/index.html.haml b/app/views/admin/variant_overrides/index.html.haml index 8d7fc4e0b1..38563d00a2 100644 --- a/app/views/admin/variant_overrides/index.html.haml +++ b/app/views/admin/variant_overrides/index.html.haml @@ -1,7 +1,7 @@ = render 'admin/variant_overrides/header' = render 'admin/variant_overrides/data' -%div{ ng: { app: 'ofn.admin', controller: 'AdminVariantOverridesCtrl', init: 'initialise()' } } +%div{ ng: { app: 'admin.variantOverrides', controller: 'AdminVariantOverridesCtrl', init: 'initialise()' } } = render 'admin/variant_overrides/hub_choice' %div{ng: {show: 'hub'}} diff --git a/spec/javascripts/unit/admin/controllers/variant_overrides_controller_spec.js.coffee b/spec/javascripts/unit/admin/controllers/variant_overrides_controller_spec.js.coffee index bdb62e8d37..d553392de3 100644 --- a/spec/javascripts/unit/admin/controllers/variant_overrides_controller_spec.js.coffee +++ b/spec/javascripts/unit/admin/controllers/variant_overrides_controller_spec.js.coffee @@ -9,7 +9,7 @@ describe "VariantOverridesCtrl", -> variantOverrides = {} beforeEach -> - module 'ofn.admin' + module 'admin.variantOverrides' module ($provide) -> $provide.value 'SpreeApiKey', 'API_KEY' $provide.value 'variantOverrides', variantOverrides @@ -54,4 +54,4 @@ describe "VariantOverridesCtrl", -> expect(scope.updateError(data, 400)).toEqual "I had some trouble saving: Hub can't be blank, Variant can't be blank" it "returns a generic message otherwise", -> - expect(scope.updateError({}, 500)).toEqual "Oh no! I was unable to save your changes." \ No newline at end of file + expect(scope.updateError({}, 500)).toEqual "Oh no! I was unable to save your changes." diff --git a/spec/javascripts/unit/admin/services/dirty_variant_overrides_spec.js.coffee b/spec/javascripts/unit/admin/services/dirty_variant_overrides_spec.js.coffee index 653560a989..553bba5713 100644 --- a/spec/javascripts/unit/admin/services/dirty_variant_overrides_spec.js.coffee +++ b/spec/javascripts/unit/admin/services/dirty_variant_overrides_spec.js.coffee @@ -7,7 +7,7 @@ describe "maintaining a list of dirty variant overrides", -> count_on_hand: 4 beforeEach -> - module "ofn.admin" + module "admin.variantOverrides" beforeEach inject (_DirtyVariantOverrides_) -> DirtyVariantOverrides = _DirtyVariantOverrides_ diff --git a/spec/javascripts/unit/admin/services/indexer_spec.js.coffee b/spec/javascripts/unit/admin/services/indexer_spec.js.coffee index f17f8bd83c..22f263e02b 100644 --- a/spec/javascripts/unit/admin/services/indexer_spec.js.coffee +++ b/spec/javascripts/unit/admin/services/indexer_spec.js.coffee @@ -2,7 +2,7 @@ describe "indexer", -> Indexer = null beforeEach -> - module "ofn.admin" + module "admin.indexUtils" beforeEach inject (_Indexer_) -> Indexer = _Indexer_ diff --git a/spec/javascripts/unit/admin/services/variant_overrides_spec.js.coffee b/spec/javascripts/unit/admin/services/variant_overrides_spec.js.coffee index 532bb1d65c..b379dc5915 100644 --- a/spec/javascripts/unit/admin/services/variant_overrides_spec.js.coffee +++ b/spec/javascripts/unit/admin/services/variant_overrides_spec.js.coffee @@ -7,7 +7,7 @@ describe "VariantOverrides service", -> ] beforeEach -> - module "ofn.admin" + module "admin.variantOverrides" module ($provide) -> $provide.value "variantOverrides", variantOverrides null From c781113a6511351cd24a7c4cc125ddcb87a2380c Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Thu, 26 Nov 2015 12:51:29 +1100 Subject: [PATCH 07/43] Adding filters to variant overrides interface --- .../directives/ofn-select2.js.coffee | 28 ++++++++++++++++ .../index_utils/filters/attr_filter.js.coffee | 12 +++++++ .../variant_overrides_controller.js.coffee | 15 ++++++--- .../services/variant_overrides.js.coffee | 2 +- .../variant_overrides.js.coffee | 2 +- .../stylesheets/admin/disabled.css.scss | 13 ++++++++ .../variant_overrides/_filters.html.haml | 26 +++++++++++++++ .../variant_overrides/_hub_choice.html.haml | 7 ---- .../variant_overrides/_products.html.haml | 4 +-- .../_products_product.html.haml | 4 +-- .../_products_variants.html.haml | 6 ++-- .../admin/variant_overrides/index.html.haml | 2 +- spec/features/admin/variant_overrides_spec.rb | 33 ++++++++++++++++--- ...ariant_overrides_controller_spec.js.coffee | 10 ++++-- 14 files changed, 134 insertions(+), 30 deletions(-) create mode 100644 app/assets/javascripts/admin/index_utils/directives/ofn-select2.js.coffee create mode 100644 app/assets/javascripts/admin/index_utils/filters/attr_filter.js.coffee create mode 100644 app/assets/stylesheets/admin/disabled.css.scss create mode 100644 app/views/admin/variant_overrides/_filters.html.haml delete mode 100644 app/views/admin/variant_overrides/_hub_choice.html.haml diff --git a/app/assets/javascripts/admin/index_utils/directives/ofn-select2.js.coffee b/app/assets/javascripts/admin/index_utils/directives/ofn-select2.js.coffee new file mode 100644 index 0000000000..ba7a4b54df --- /dev/null +++ b/app/assets/javascripts/admin/index_utils/directives/ofn-select2.js.coffee @@ -0,0 +1,28 @@ +angular.module("admin.indexUtils").directive "ofnSelect2", ($timeout, blankOption) -> + require: 'ngModel' + restrict: 'C' + scope: + data: "=" + minSearch: "@?" + text: "@?" + blank: "=?" + link: (scope, element, attrs, ngModel) -> + $timeout -> + scope.text ||= 'name' + scope.data.unshift(scope.blank) if scope.blank? && typeof scope.blank is "object" + element.select2 + minimumResultsForSearch: scope.minSearch || 0 + data: { results: scope.data, text: scope.text } + initSelection: (element, callback) -> + callback scope.data[0] + formatSelection: (item) -> + item[scope.text] + formatResult: (item) -> + item[scope.text] + + attrs.$observe 'disabled', (value) -> + element.select2('enable', !value) + + ngModel.$formatters.push (value) -> + element.select2('val', value) + value diff --git a/app/assets/javascripts/admin/index_utils/filters/attr_filter.js.coffee b/app/assets/javascripts/admin/index_utils/filters/attr_filter.js.coffee new file mode 100644 index 0000000000..c645b507f1 --- /dev/null +++ b/app/assets/javascripts/admin/index_utils/filters/attr_filter.js.coffee @@ -0,0 +1,12 @@ +# Used like a regular angular filter where an object is passed +# Adds the additional special case that a value of 0 for the filter +# acts as a bypass for that particular attribute +angular.module("admin.indexUtils").filter "attrFilter", ($filter) -> + return (objects, filters) -> + Object.keys(filters).reduce (filtered, attr) -> + filter = filters[attr] + return filtered if !filter? || filter == 0 + return $filter('filter')(filtered, (object) -> + object[attr] == filter + ) + , objects diff --git a/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee b/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee index 73ddfc8b2b..d3a57c572f 100644 --- a/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee +++ b/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee @@ -1,12 +1,19 @@ angular.module("admin.variantOverrides").controller "AdminVariantOverridesCtrl", ($scope, $timeout, Indexer, SpreeApiAuth, PagedFetcher, StatusMessage, hubs, producers, hubPermissions, VariantOverrides, DirtyVariantOverrides) -> - $scope.hubs = hubs + $scope.hubs = Indexer.index hubs $scope.hub = null $scope.products = [] - $scope.producers = Indexer.index producers + $scope.producers = producers + $scope.producersByID = Indexer.index producers $scope.hubPermissions = hubPermissions $scope.variantOverrides = VariantOverrides.variantOverrides $scope.StatusMessage = StatusMessage + $scope.resetSelectFilters = -> + $scope.producerFilter = 0 + $scope.query = '' + + $scope.resetSelectFilters() + $scope.initialise = -> SpreeApiAuth.authorise() .then -> @@ -27,8 +34,7 @@ angular.module("admin.variantOverrides").controller "AdminVariantOverridesCtrl", $scope.selectHub = -> - $scope.hub = (hub for hub in hubs when hub.id == $scope.hub_id)[0] - + $scope.hub = $scope.hubs[$scope.hub_id] $scope.displayDirty = -> if DirtyVariantOverrides.count() > 0 @@ -37,7 +43,6 @@ angular.module("admin.variantOverrides").controller "AdminVariantOverridesCtrl", else StatusMessage.clear() - $scope.update = -> if DirtyVariantOverrides.count() == 0 StatusMessage.display 'alert', 'No changes to save.' diff --git a/app/assets/javascripts/admin/variant_overrides/services/variant_overrides.js.coffee b/app/assets/javascripts/admin/variant_overrides/services/variant_overrides.js.coffee index c8ea397343..697d459b75 100644 --- a/app/assets/javascripts/admin/variant_overrides/services/variant_overrides.js.coffee +++ b/app/assets/javascripts/admin/variant_overrides/services/variant_overrides.js.coffee @@ -8,7 +8,7 @@ angular.module("admin.variantOverrides").factory "VariantOverrides", (variantOve @variantOverrides[vo.hub_id][vo.variant_id] = vo ensureDataFor: (hubs, products) -> - for hub in hubs + for hub_id, hub of hubs @variantOverrides[hub.id] ||= {} for product in products for variant in product.variants diff --git a/app/assets/javascripts/admin/variant_overrides/variant_overrides.js.coffee b/app/assets/javascripts/admin/variant_overrides/variant_overrides.js.coffee index 7a6f1ab2fa..4766bd464c 100644 --- a/app/assets/javascripts/admin/variant_overrides/variant_overrides.js.coffee +++ b/app/assets/javascripts/admin/variant_overrides/variant_overrides.js.coffee @@ -1 +1 @@ -angular.module("admin.variantOverrides", ["admin.indexUtils"]) +angular.module("admin.variantOverrides", ["admin.indexUtils", "pasvaz.bindonce"]) diff --git a/app/assets/stylesheets/admin/disabled.css.scss b/app/assets/stylesheets/admin/disabled.css.scss new file mode 100644 index 0000000000..a393c5d80b --- /dev/null +++ b/app/assets/stylesheets/admin/disabled.css.scss @@ -0,0 +1,13 @@ +label.disabled { + color: #c3c3c3; + pointer-events: none; +} + +input[type='button']:disabled { + background-color: #c3c3c3; + color: #ffffff; +} + +.select2-container-disabled { + pointer-events: none; +} diff --git a/app/views/admin/variant_overrides/_filters.html.haml b/app/views/admin/variant_overrides/_filters.html.haml new file mode 100644 index 0000000000..9dc90d7ad3 --- /dev/null +++ b/app/views/admin/variant_overrides/_filters.html.haml @@ -0,0 +1,26 @@ +.filters.sixteen.columns.alpha + .filter.four.columns.alpha + %label{ :for => 'query', ng: {class: '{disabled: !hub.id}'} }Quick Search + %br + %input.fullwidth{ :type => "text", :id => 'query', ng: { model: 'query', disabled: '!hub.id'} } + .two.columns   + .filter_select.four.columns + %label{ :for => 'hub_id', ng: { bind: 'hub_id ? "Shop" : "Select a shop"' } } + %br + %select.select2.fullwidth#hub_id{ 'ng-model' => 'hub_id', name: 'hub_id', ng: { options: 'hub.id as hub.name for (id, hub) in hubs', change: 'selectHub()' } } + .filter_select.four.columns + %label{ :for => 'producer_filter', ng: {class: '{disabled: !hub.id}'} }Producer + %br + %input.ofn-select2.fullwidth{ :id => 'producer_filter', type: 'number', style: 'display:none', data: 'producers', blank: "{id: 0, name: 'All'}", ng: { model: 'producerFilter', disabled: '!hub.id' } } + -# .filter_select{ :class => "three columns" } + -# %label{ :for => 'distributor_filter' }Hub + -# %br + -# %select{ :class => "three columns alpha", :id => 'distributor_filter', 'select2-min-search' => 5, 'ng-model' => 'distributorFilter', 'ng-options' => 'd.id as d.name for d in distributors'} + -# .filter_select{ :class => "three columns" } + -# %label{ :for => 'order_cycle_filter' }Order Cycle + -# %br + -# %select{ :class => "three columns alpha", :id => 'order_cycle_filter', 'select2-min-search' => 5, 'ng-model' => 'orderCycleFilter', 'ng-options' => 'oc.id as oc.name for oc in orderCycles', 'confirm-change' => "confirmRefresh()", 'ng-change' => 'refreshData()'} + .filter_clear.two.columns.omega + %label{ :for => 'clear_all_filters' } + %br + %input.red.fullwidth{ :type => 'button', :id => 'clear_all_filters', :value => "Clear All", ng: { click: "resetSelectFilters()", disabled: '!hub.id'} } diff --git a/app/views/admin/variant_overrides/_hub_choice.html.haml b/app/views/admin/variant_overrides/_hub_choice.html.haml deleted file mode 100644 index aa0f7ab738..0000000000 --- a/app/views/admin/variant_overrides/_hub_choice.html.haml +++ /dev/null @@ -1,7 +0,0 @@ -.row - .two.columns.alpha - Hub - .four.columns - %select.select2.fullwidth#hub_id{ 'ng-model' => 'hub_id', name: 'hub_id', 'ng-options' => 'hub.id as hub.name for hub in hubs' } - .ten.columns.omega - %input{ type: 'button', value: 'Go', 'ng-click' => 'selectHub()' } diff --git a/app/views/admin/variant_overrides/_products.html.haml b/app/views/admin/variant_overrides/_products.html.haml index cf11e8ac5d..fa5cfe0ec0 100644 --- a/app/views/admin/variant_overrides/_products.html.haml +++ b/app/views/admin/variant_overrides/_products.html.haml @@ -1,10 +1,10 @@ -%table.index.bulk{ng: {show: 'hub'}} +%table.index.bulk{ ng: {show: 'hub'}} %thead %tr %th Producer %th Product %th Price %th On hand - %tbody{ng: {repeat: 'product in products | hubPermissions:hubPermissions:hub.id'}} + %tbody{bindonce: true, ng: {repeat: 'product in products | hubPermissions:hubPermissions:hub.id | attrFilter:{producer_id:producerFilter} | filter:query' } } = render 'admin/variant_overrides/products_product' = render 'admin/variant_overrides/products_variants' diff --git a/app/views/admin/variant_overrides/_products_product.html.haml b/app/views/admin/variant_overrides/_products_product.html.haml index 52551e8e0b..9ce07b3aa6 100644 --- a/app/views/admin/variant_overrides/_products_product.html.haml +++ b/app/views/admin/variant_overrides/_products_product.html.haml @@ -1,5 +1,5 @@ %tr.product.even - %td {{ producers[product.producer_id].name }} - %td {{ product.name }} + %td{ bo: { bind: 'producersByID[product.producer_id].name'} } + %td{ bo: { bind: 'product.name'} } %td %td diff --git a/app/views/admin/variant_overrides/_products_variants.html.haml b/app/views/admin/variant_overrides/_products_variants.html.haml index bd48ea343c..2868b6f8f2 100644 --- a/app/views/admin/variant_overrides/_products_variants.html.haml +++ b/app/views/admin/variant_overrides/_products_variants.html.haml @@ -1,8 +1,8 @@ -%tr.variant{ng: {repeat: 'variant in product.variants'}} +%tr.variant{ id: "v_{{variant.id}}", ng: {repeat: 'variant in product.variants'}} %td %td - {{ variant.display_name }} - .variant-override-unit {{ variant.unit_to_display }} + %span{ bo: { bind: 'variant.display_name || ""'} } + .variant-override-unit{ bo: { bind: 'variant.unit_to_display'} } %td %input{name: 'variant-overrides-{{ variant.id }}-price', type: 'text', ng: {model: 'variantOverrides[hub.id][variant.id].price'}, placeholder: '{{ variant.price }}', 'ofn-track-variant-override' => 'price'} diff --git a/app/views/admin/variant_overrides/index.html.haml b/app/views/admin/variant_overrides/index.html.haml index 38563d00a2..8d0a4670d7 100644 --- a/app/views/admin/variant_overrides/index.html.haml +++ b/app/views/admin/variant_overrides/index.html.haml @@ -2,7 +2,7 @@ = render 'admin/variant_overrides/data' %div{ ng: { app: 'admin.variantOverrides', controller: 'AdminVariantOverridesCtrl', init: 'initialise()' } } - = render 'admin/variant_overrides/hub_choice' + = render 'admin/variant_overrides/filters' %div{ng: {show: 'hub'}} %h2 {{ hub.name }} diff --git a/spec/features/admin/variant_overrides_spec.rb b/spec/features/admin/variant_overrides_spec.rb index ee615f44f5..ec8b754abe 100644 --- a/spec/features/admin/variant_overrides_spec.rb +++ b/spec/features/admin/variant_overrides_spec.rb @@ -30,7 +30,6 @@ feature %q{ it "displays the hub" do visit '/admin/variant_overrides' select2_select hub.name, from: 'hub_id' - click_button 'Go' page.should have_selector 'h2', text: hub.name end @@ -59,7 +58,6 @@ feature %q{ before do visit '/admin/variant_overrides' select2_select hub.name, from: 'hub_id' - click_button 'Go' end it "displays the list of products with variants" do @@ -72,11 +70,37 @@ feature %q{ page.should have_table_row [producer_related.name, product_related.name, '', ''] page.should have_input "variant-overrides-#{variant_related.id}-price", placeholder: '2.34' page.should have_input "variant-overrides-#{variant_related.id}-count-on-hand", placeholder: '23' - end - it "filters the products to those the hub can override" do + # filters the products to those the hub can override page.should_not have_content producer_unrelated.name page.should_not have_content product_unrelated.name + + # Filters based on the producer select filter + expect(page).to have_selector "#v_#{variant.id}" + expect(page).to have_selector "#v_#{variant_related.id}" + select2_select producer.name, from: 'producer_filter' + expect(page).to have_selector "#v_#{variant.id}" + expect(page).to_not have_selector "#v_#{variant_related.id}" + select2_select 'All', from: 'producer_filter' + + # Filters based on the quick search box + expect(page).to have_selector "#v_#{variant.id}" + expect(page).to have_selector "#v_#{variant_related.id}" + fill_in 'query', with: product.name + expect(page).to have_selector "#v_#{variant.id}" + expect(page).to_not have_selector "#v_#{variant_related.id}" + fill_in 'query', with: '' + + # Clears the filters + expect(page).to have_selector "#v_#{variant.id}" + expect(page).to have_selector "#v_#{variant_related.id}" + select2_select producer.name, from: 'producer_filter' + fill_in 'query', with: product_related.name + expect(page).to_not have_selector "#v_#{variant.id}" + expect(page).to_not have_selector "#v_#{variant_related.id}" + click_button 'Clear All' + expect(page).to have_selector "#v_#{variant.id}" + expect(page).to have_selector "#v_#{variant_related.id}" end it "creates new overrides" do @@ -162,7 +186,6 @@ feature %q{ before do visit '/admin/variant_overrides' select2_select hub.name, from: 'hub_id' - click_button 'Go' end it "product values are affected by overrides" do diff --git a/spec/javascripts/unit/admin/controllers/variant_overrides_controller_spec.js.coffee b/spec/javascripts/unit/admin/controllers/variant_overrides_controller_spec.js.coffee index d553392de3..22b8300409 100644 --- a/spec/javascripts/unit/admin/controllers/variant_overrides_controller_spec.js.coffee +++ b/spec/javascripts/unit/admin/controllers/variant_overrides_controller_spec.js.coffee @@ -16,14 +16,18 @@ describe "VariantOverridesCtrl", -> null scope = {} - inject ($controller, Indexer, _VariantOverrides_) -> + inject ($controller, _VariantOverrides_) -> VariantOverrides = _VariantOverrides_ - ctrl = $controller 'AdminVariantOverridesCtrl', {$scope: scope, Indexer: Indexer, hubs: hubs, producers: producers, products: products, hubPermissions: hubPermissions, VariantOverrides: _VariantOverrides_} + ctrl = $controller 'AdminVariantOverridesCtrl', {$scope: scope, hubs: hubs, producers: producers, products: products, hubPermissions: hubPermissions, VariantOverrides: _VariantOverrides_} it "initialises the hub list and the chosen hub", -> - expect(scope.hubs).toEqual hubs + expect(scope.hubs).toEqual { 1: {id: 1, name: 'Hub'} } expect(scope.hub).toBeNull() + it "initialises select filters", -> + expect(scope.producerFilter).toEqual 0 + expect(scope.query).toEqual '' + it "adds products", -> spyOn(VariantOverrides, "ensureDataFor") expect(scope.products).toEqual [] From 54e767788899a285968c066b5cbae1bbee4e4b7b Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Thu, 26 Nov 2015 17:26:56 +1100 Subject: [PATCH 08/43] Integrating StatusMessages into save-bar, adding to variant overrides index --- .../index_utils/directives/save_bar.js.coffee | 7 ++++--- .../services/status_message.js.coffee | 4 ++++ .../line_items_controller.js.coffee | 18 +++++++++++------- .../variant_overrides_controller.js.coffee | 7 ++++--- .../templates/admin/save_bar.html.haml | 12 ++++-------- .../admin/variant_overrides/index.html.haml | 8 +++----- .../admin/orders/bulk_management.html.haml | 2 +- .../admin/bulk_order_management_spec.rb | 10 ++++------ spec/features/admin/variant_overrides_spec.rb | 7 ------- 9 files changed, 35 insertions(+), 40 deletions(-) diff --git a/app/assets/javascripts/admin/index_utils/directives/save_bar.js.coffee b/app/assets/javascripts/admin/index_utils/directives/save_bar.js.coffee index a991592d42..0b30499d1d 100644 --- a/app/assets/javascripts/admin/index_utils/directives/save_bar.js.coffee +++ b/app/assets/javascripts/admin/index_utils/directives/save_bar.js.coffee @@ -1,7 +1,8 @@ -angular.module("admin.indexUtils").directive "saveBar", -> +angular.module("admin.indexUtils").directive "saveBar", (StatusMessage) -> restrict: "E" scope: save: "&" - saving: "&" - dirty: "&" + form: "=" templateUrl: "admin/save_bar.html" + link: (scope, element, attrs) -> + scope.StatusMessage = StatusMessage diff --git a/app/assets/javascripts/admin/index_utils/services/status_message.js.coffee b/app/assets/javascripts/admin/index_utils/services/status_message.js.coffee index 9cc9547e39..5dd9fb7258 100644 --- a/app/assets/javascripts/admin/index_utils/services/status_message.js.coffee +++ b/app/assets/javascripts/admin/index_utils/services/status_message.js.coffee @@ -11,6 +11,9 @@ angular.module("admin.indexUtils").factory "StatusMessage", ($timeout) -> text: "" style: {} + active: -> + @statusMessage.text != '' + display: (type, text) -> @statusMessage.text = text @statusMessage.style = @types[type].style @@ -20,6 +23,7 @@ angular.module("admin.indexUtils").factory "StatusMessage", ($timeout) -> @statusMessage.timeout = $timeout => @clear() , timeout, true + null # So we don't return weird timeouts clear: -> @statusMessage.text = '' diff --git a/app/assets/javascripts/admin/line_items/controllers/line_items_controller.js.coffee b/app/assets/javascripts/admin/line_items/controllers/line_items_controller.js.coffee index 38c7f0ba33..c6709eb3b4 100644 --- a/app/assets/javascripts/admin/line_items/controllers/line_items_controller.js.coffee +++ b/app/assets/javascripts/admin/line_items/controllers/line_items_controller.js.coffee @@ -1,7 +1,6 @@ -angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout, $http, $q, Columns, Dereferencer, Orders, LineItems, Enterprises, OrderCycles, blankOption, VariantUnitManager, RequestMonitor) -> +angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout, $http, $q, StatusMessage, Columns, Dereferencer, Orders, LineItems, Enterprises, OrderCycles, blankOption, VariantUnitManager, RequestMonitor) -> $scope.initialized = false $scope.RequestMonitor = RequestMonitor - $scope.saving = false $scope.filteredLineItems = [] $scope.confirmDelete = true $scope.startDate = formatDate daysFromToday -7 @@ -55,6 +54,7 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout, Dereferencer.dereferenceAttr $scope.lineItems, "supplier", Enterprises.enterprisesByID Dereferencer.dereferenceAttr $scope.lineItems, "order", Orders.ordersByID $scope.bulk_order_form.$setPristine() + StatusMessage.clear() unless $scope.initialized $scope.initialized = true $timeout -> @@ -62,16 +62,20 @@ angular.module("admin.lineItems").controller 'LineItemsCtrl', ($scope, $timeout, $scope.refreshData() - $scope.submit = => + $scope.$watch 'bulk_order_form.$dirty', (newVal, oldVal) -> + if newVal == true + StatusMessage.display 'notice', "You have unsaved changes" + + $scope.submit = -> if $scope.bulk_order_form.$valid - $scope.saving = true + StatusMessage.display 'progress', "Saving..." $q.all(LineItems.saveAll()).then(-> + StatusMessage.display 'success', "All changes saved" $scope.bulk_order_form.$setPristine() - $scope.saving = false ).catch -> - alert "Some errors must be resolved be before you can update orders.\nAny fields with red borders contain errors." + StatusMessage.display 'failure', "Fields with red borders contain errors." else - alert "Some errors must be resolved be before you can update orders.\nAny fields with red borders contain errors." + StatusMessage.display 'failure', "Fields with red borders contain errors." $scope.deleteLineItem = (lineItem) -> if ($scope.confirmDelete && confirm("Are you sure?")) || !$scope.confirmDelete diff --git a/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee b/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee index d3a57c572f..c179d9a6a8 100644 --- a/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee +++ b/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee @@ -1,4 +1,4 @@ -angular.module("admin.variantOverrides").controller "AdminVariantOverridesCtrl", ($scope, $timeout, Indexer, SpreeApiAuth, PagedFetcher, StatusMessage, hubs, producers, hubPermissions, VariantOverrides, DirtyVariantOverrides) -> +angular.module("admin.variantOverrides").controller "AdminVariantOverridesCtrl", ($scope, Indexer, SpreeApiAuth, PagedFetcher, StatusMessage, hubs, producers, hubPermissions, VariantOverrides, DirtyVariantOverrides) -> $scope.hubs = Indexer.index hubs $scope.hub = null $scope.products = [] @@ -52,9 +52,10 @@ angular.module("admin.variantOverrides").controller "AdminVariantOverridesCtrl", .success (updatedVos) -> DirtyVariantOverrides.clear() VariantOverrides.updateIds updatedVos - $timeout -> StatusMessage.display 'success', 'Changes saved.' + StatusMessage.display 'success', 'Changes saved.' + $scope.variant_overrides_form.$setPristine() .error (data, status) -> - $timeout -> StatusMessage.display 'failure', $scope.updateError(data, status) + StatusMessage.display 'failure', $scope.updateError(data, status) $scope.updateError = (data, status) -> diff --git a/app/assets/javascripts/templates/admin/save_bar.html.haml b/app/assets/javascripts/templates/admin/save_bar.html.haml index 62842f0bfb..618402cf2b 100644 --- a/app/assets/javascripts/templates/admin/save_bar.html.haml +++ b/app/assets/javascripts/templates/admin/save_bar.html.haml @@ -1,10 +1,6 @@ -#save-bar.animate-show{ ng: { show: 'dirty()' } } +#save-bar.animate-show{ ng: { show: 'form.$dirty || StatusMessage.active()' } } .twelve.columns.alpha - %h5{ ng: { show: "dirty() && !saving()" } } - You have unsaved changes - %h5{ ng: { hide: "dirty() || saving()" } } - All changes saved - %h5{ ng: { show: "saving()" } } - Saving... + %h5#status-messae{ ng: { style: 'StatusMessage.statusMessage.style' } } + {{ StatusMessage.statusMessage.text || " " }} .four.columns.omega.text-right - %input.red{type: "button", value: "Save Changes", ng: { click: "save()" } } + %input.red{type: "button", value: "Save Changes", ng: { disabled: '!form.$dirty', click: "save()" } } diff --git a/app/views/admin/variant_overrides/index.html.haml b/app/views/admin/variant_overrides/index.html.haml index 8d0a4670d7..2d202bac27 100644 --- a/app/views/admin/variant_overrides/index.html.haml +++ b/app/views/admin/variant_overrides/index.html.haml @@ -4,8 +4,6 @@ %div{ ng: { app: 'admin.variantOverrides', controller: 'AdminVariantOverridesCtrl', init: 'initialise()' } } = render 'admin/variant_overrides/filters' - %div{ng: {show: 'hub'}} - %h2 {{ hub.name }} - = render 'admin/variant_overrides/actions' - - = render 'admin/variant_overrides/products' + %form{ name: 'variant_overrides_form' } + %save-bar{ save: "update()", form: "variant_overrides_form" } + = render 'admin/variant_overrides/products' diff --git a/app/views/spree/admin/orders/bulk_management.html.haml b/app/views/spree/admin/orders/bulk_management.html.haml index dbcf9c97fd..083ae2f6c8 100644 --- a/app/views/spree/admin/orders/bulk_management.html.haml +++ b/app/views/spree/admin/orders/bulk_management.html.haml @@ -5,7 +5,7 @@ = render :partial => 'spree/admin/shared/order_sub_menu' %div{ ng: { app: 'admin.lineItems', controller: 'LineItemsCtrl' } } - %save-bar{ save: "submit()", saving: 'saving', dirty: "bulk_order_form.$dirty" } + %save-bar{ save: "submit()", form: "bulk_order_form" } .filters{ :class => "sixteen columns alpha" } .date_filter{ :class => "two columns alpha" } %label{ :for => 'start_date_filter' }Start Date diff --git a/spec/features/admin/bulk_order_management_spec.rb b/spec/features/admin/bulk_order_management_spec.rb index 5a51f396b3..f8f2eae34a 100644 --- a/spec/features/admin/bulk_order_management_spec.rb +++ b/spec/features/admin/bulk_order_management_spec.rb @@ -119,10 +119,9 @@ feature %q{ expect(page).to_not have_selector "#save-bar" fill_in "quantity", :with => 2 expect(page).to have_selector "input[name='quantity'].ng-dirty" - expect(page).to have_selector "#save-bar" - expect(page).to have_button "Save Changes" + expect(page).to have_selector "#save-bar", text: "You have unsaved changes" click_button "Save Changes" - expect(page).to_not have_selector "#save-bar" + expect(page).to have_selector "#save-bar", text: "All changes saved" expect(page).to_not have_selector "input[name='quantity'].ng-dirty" end end @@ -132,10 +131,9 @@ feature %q{ expect(page).to_not have_selector "#save-bar" fill_in "quantity", :with => li1.variant.on_hand + li1.quantity + 10 expect(page).to have_selector "input[name='quantity'].ng-dirty" - expect(page).to have_selector "#save-bar" - expect(page).to have_button "Save Changes" + expect(page).to have_selector "#save-bar", text: "You have unsaved changes" click_button "Save Changes" - expect(page).to have_selector "#save-bar" + expect(page).to have_selector "#save-bar", text: "Fields with red borders contain errors." expect(page).to have_selector "input[name='quantity'].ng-dirty.update-error" expect(page).to have_content "exceeds available stock. Please ensure line items have a valid quantity." end diff --git a/spec/features/admin/variant_overrides_spec.rb b/spec/features/admin/variant_overrides_spec.rb index ec8b754abe..c49e95c4ef 100644 --- a/spec/features/admin/variant_overrides_spec.rb +++ b/spec/features/admin/variant_overrides_spec.rb @@ -26,13 +26,6 @@ feature %q{ page.should have_select2 'hub_id', options: ['', hub.name, hub2.name] end - - it "displays the hub" do - visit '/admin/variant_overrides' - select2_select hub.name, from: 'hub_id' - - page.should have_selector 'h2', text: hub.name - end end context "when a hub is selected" do From 9eaec6061eeeebe7d52fa8040c3ab5b81687f642 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 27 Nov 2015 08:24:29 +1100 Subject: [PATCH 09/43] Pulling columns dropdown out into a shared partial --- .../dropdown/directives/dropdown.js.coffee | 5 +- .../templates/admin/links_dropdown.html.haml | 2 +- .../stylesheets/admin/dropdown.css.scss | 66 +++++++++++++++++++ .../admin/filters_and_controls.css.scss | 3 + .../admin/openfoodnetwork.css.scss | 62 ----------------- app/views/admin/customers/index.html.haml | 11 +--- .../_enterprise_user_index.html.haml | 11 +--- .../admin/shared/_columns_dropdown.html.haml | 8 +++ .../admin/orders/bulk_management.html.haml | 34 ++++------ .../products/bulk_edit/_actions.html.haml | 9 +-- .../admin/bulk_order_management_spec.rb | 30 ++++----- .../admin/bulk_product_update_spec.rb | 24 +++---- spec/features/admin/customers_spec.rb | 4 +- spec/features/admin/orders_spec.rb | 2 +- 14 files changed, 129 insertions(+), 142 deletions(-) create mode 100644 app/assets/stylesheets/admin/dropdown.css.scss create mode 100644 app/assets/stylesheets/admin/filters_and_controls.css.scss create mode 100644 app/views/admin/shared/_columns_dropdown.html.haml diff --git a/app/assets/javascripts/admin/dropdown/directives/dropdown.js.coffee b/app/assets/javascripts/admin/dropdown/directives/dropdown.js.coffee index 560598d23e..b4ca2869d7 100644 --- a/app/assets/javascripts/admin/dropdown/directives/dropdown.js.coffee +++ b/app/assets/javascripts/admin/dropdown/directives/dropdown.js.coffee @@ -1,8 +1,9 @@ angular.module("admin.dropdown").directive "ofnDropDown", ($document) -> + restrict: 'C' link: (scope, element, attrs) -> outsideClickListener = (event) -> - unless $(event.target).is("div.ofn_drop_down##{attrs.id} div.menu") || - $(event.target).parents("div.ofn_drop_down##{attrs.id} div.menu").length > 0 + unless $(event.target).is("div.ofn-drop-down##{attrs.id} div.menu") || + $(event.target).parents("div.ofn-drop-down##{attrs.id} div.menu").length > 0 scope.$emit "offClick" element.click (event) -> diff --git a/app/assets/javascripts/templates/admin/links_dropdown.html.haml b/app/assets/javascripts/templates/admin/links_dropdown.html.haml index 4f85ed1319..1f44f2418c 100644 --- a/app/assets/javascripts/templates/admin/links_dropdown.html.haml +++ b/app/assets/javascripts/templates/admin/links_dropdown.html.haml @@ -1,4 +1,4 @@ -.ofn_drop_down{ "ofn-drop-down" => true } +.ofn-drop-down %span %i.icon-check Actions diff --git a/app/assets/stylesheets/admin/dropdown.css.scss b/app/assets/stylesheets/admin/dropdown.css.scss new file mode 100644 index 0000000000..9e1de193be --- /dev/null +++ b/app/assets/stylesheets/admin/dropdown.css.scss @@ -0,0 +1,66 @@ +#content-header .ofn-drop-down { + border: none; + background-color: #5498da; + color: #fff; + float: none; + margin-left: 3px; +} + +.ofn-drop-down:hover, .ofn-drop-down.expanded { + border: 1px solid #adadad; + color: #575757; +} + +.ofn-drop-down { + padding: 7px 15px; + border-radius: 3px; + border: 1px solid #d4d4d4; + background-color: #f5f5f5; + position: relative; + display: block; + float: right; + color: #828282; + cursor: pointer; + -moz-user-select: none; + -khtml-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; + text-align: center; + + &:hover, &.expanded { + border: 1px solid #adadad; + color: #575757; + } + + > span { + width: auto; + text-transform: uppercase; + font-size: 85%; + font-weight: 600; + } + + .menu { + margin-top: 1px; + position: absolute; + float: none; + top:100%; + left: 0px; + padding: 5px 0px; + border: 1px solid #adadad; + background-color: #ffffff; + box-shadow: 1px 3px 10px #888888; + z-index: 100; + + .menu_item { + margin: 0px; + padding: 2px 0px; + color: #454545; + text-align: left; + } + + .menu_item:hover { + background-color: #ededed; + } + } +} diff --git a/app/assets/stylesheets/admin/filters_and_controls.css.scss b/app/assets/stylesheets/admin/filters_and_controls.css.scss new file mode 100644 index 0000000000..8dd188d9cd --- /dev/null +++ b/app/assets/stylesheets/admin/filters_and_controls.css.scss @@ -0,0 +1,3 @@ +.filters, .controls, .divider { + margin-bottom: 15px; +} diff --git a/app/assets/stylesheets/admin/openfoodnetwork.css.scss b/app/assets/stylesheets/admin/openfoodnetwork.css.scss index d5a53e11c4..e0916b4e79 100644 --- a/app/assets/stylesheets/admin/openfoodnetwork.css.scss +++ b/app/assets/stylesheets/admin/openfoodnetwork.css.scss @@ -184,68 +184,6 @@ table#listing_enterprise_groups { } } -#content-header .ofn_drop_down { - border: none; - background-color: #5498da; - color: #fff; - float: none; - margin-left: 3px; -} - -.ofn_drop_down { - padding: 6px 15px; - border-radius: 3px; - border: 1px solid #d4d4d4; - background-color: #f5f5f5; - position: relative; - display: block; - float: left; - color: #828282; - cursor: pointer; - -moz-user-select: none; - -khtml-user-select: none; - -webkit-user-select: none; - -ms-user-select: none; - user-select: none; - text-align: center; - - > span { - width: auto; - text-transform: uppercase; - font-size: 85%; - font-weight: 600; - } - - .menu { - margin-top: 1px; - position: absolute; - float: none; - top:100%; - left: 0px; - padding: 5px 0px; - border: 1px solid #adadad; - background-color: #ffffff; - box-shadow: 1px 3px 10px #888888; - z-index: 100; - - .menu_item { - margin: 0px; - padding: 2px 0px; - color: #454545; - text-align: left; - } - - .menu_item:hover { - background-color: #ededed; - } - } -} - -.ofn_drop_down:hover, .ofn_drop_down.expanded { - border: 1px solid #adadad; - color: #575757; -} - .field_with_errors > input { border-color: red; } diff --git a/app/views/admin/customers/index.html.haml b/app/views/admin/customers/index.html.haml index 66790a34df..67998b686f 100644 --- a/app/views/admin/customers/index.html.haml +++ b/app/views/admin/customers/index.html.haml @@ -16,21 +16,14 @@ .five.columns.alpha %input{ :class => "fullwidth", :type => "text", :id => 'quick_search', 'ng-model' => 'quickSearch', :placeholder => 'Quick Search' } .five.columns   - -# %div.ofn_drop_down{ 'ng-controller' => "DropDownCtrl", :id => "bulk_actions_dropdown", 'ofn-drop-down' => true } + -# %div.ofn-drop-down#bulk-actions-dropdown{ 'ng-controller' => "DropDownCtrl" } -# %span{ :class => 'icon-check' }   Actions -# %span{ 'ng-class' => "expanded && 'icon-caret-up' || !expanded && 'icon-caret-down'" } -# %div.menu{ 'ng-show' => "expanded" } -# %div.menu_item{ :class => "three columns alpha", 'ng-repeat' => "action in bulkActions", 'ng-click' => "selectedBulkAction.callback(filteredCustomers)", 'ofn-close-on-click' => true } -# %span{ :class => 'three columns omega' } {{action.name }} .three.columns   - .three.columns.omega - %div.ofn_drop_down{ 'ng-controller' => "DropDownCtrl", :id => "columns_dropdown", 'ofn-drop-down' => true, :style => 'float:right;' } - %span{ :class => 'icon-reorder' }   Columns - %span{ 'ng-class' => "expanded && 'icon-caret-up' || !expanded && 'icon-caret-down'" } - %div.menu{ 'ng-show' => "expanded" } - %div.menu_item{ :class => "three columns alpha", 'ng-repeat' => "column in columns", 'ofn-toggle-column' => true } - %span{ :class => 'one column alpha', :style => 'text-align: center'} {{ column.visible && "✓" || !column.visible && " " }} - %span{ :class => 'two columns omega' } {{column.name }} + = render 'admin/shared/columns_dropdown' .row{ 'ng-if' => 'shop && !loaded()' } .sixteen.columns.alpha#loading %img.spinner{ src: "/assets/spinning-circles.svg" } diff --git a/app/views/admin/enterprises/_enterprise_user_index.html.haml b/app/views/admin/enterprises/_enterprise_user_index.html.haml index 666ea4604d..d7fe846274 100644 --- a/app/views/admin/enterprises/_enterprise_user_index.html.haml +++ b/app/views/admin/enterprises/_enterprise_user_index.html.haml @@ -4,21 +4,14 @@ .four.columns.alpha %input{ :class => "fullwidth", :type => "text", :id => 'quick_search', 'ng-model' => 'quickSearch', :placeholder => 'Search By Name' } .six.columns   - -# %div.ofn_drop_down{ 'ng-controller' => "DropDownCtrl", :id => "bulk_actions_dropdown", 'ofn-drop-down' => true } + -# %div.ofn-drop-down#bulk-actions-dropdown{ 'ng-controller' => "DropDownCtrl" } -# %span{ :class => 'icon-check' }   Actions -# %span{ 'ng-class' => "expanded && 'icon-caret-up' || !expanded && 'icon-caret-down'" } -# %div.menu{ 'ng-show' => "expanded" } -# %div.menu_item{ :class => "three columns alpha", 'ng-repeat' => "action in bulkActions", 'ng-click' => "selectedBulkAction.callback(filteredEnterprises)", 'ofn-close-on-click' => true } -# %span{ :class => 'three columns omega' } {{action.name }} .three.columns   - .three.columns.omega - %div.ofn_drop_down{ 'ng-controller' => "DropDownCtrl", :id => "columns_dropdown", 'ofn-drop-down' => true, :style => 'float:right;' } - %span{ :class => 'icon-reorder' }   Columns - %span{ 'ng-class' => "expanded && 'icon-caret-up' || !expanded && 'icon-caret-down'" } - %div.menu{ 'ng-show' => "expanded" } - %div.menu_item{ :class => "three columns alpha", 'ng-repeat' => "column in columns", 'ofn-toggle-column' => true } - %span{ :class => 'one column alpha', :style => 'text-align: center'} {{ column.visible && "✓" || !column.visible && " " }} - %span{ :class => 'two columns omega' } {{column.name }} + = render 'admin/shared/columns_dropdown' .row{ 'ng-if' => '!loaded' } .sixteen.columns.alpha#loading %img.spinner{ src: "/assets/spinning-circles.svg" } diff --git a/app/views/admin/shared/_columns_dropdown.html.haml b/app/views/admin/shared/_columns_dropdown.html.haml new file mode 100644 index 0000000000..4e19d6615b --- /dev/null +++ b/app/views/admin/shared/_columns_dropdown.html.haml @@ -0,0 +1,8 @@ +%div.three.columns.omega + %div.ofn-drop-down#columns-dropdown{ 'ng-controller' => "DropDownCtrl" } + %span{ :class => 'icon-reorder' }   Columns + %span{ 'ng-class' => "expanded && 'icon-caret-up' || !expanded && 'icon-caret-down'" } + %div.menu{ 'ng-show' => "expanded" } + %div.menu_item.three.columns.alpha.omega{ 'ng-repeat' => "column in columns", 'ofn-toggle-column' => true } + %span.one.column.alpha.text-center {{ column.visible && "✓" || !column.visible && " " }} + %span.two.columns.omega {{column.name }} diff --git a/app/views/spree/admin/orders/bulk_management.html.haml b/app/views/spree/admin/orders/bulk_management.html.haml index 083ae2f6c8..d03fde0f27 100644 --- a/app/views/spree/admin/orders/bulk_management.html.haml +++ b/app/views/spree/admin/orders/bulk_management.html.haml @@ -70,27 +70,19 @@ %div{ :class => "eight columns alpha", 'ng-hide' => 'allFinalWeightVolumesPresent()' } %span{ :class => "eight columns alpha", style: 'color:red' } WARNING: Some variants do not have a unit value - %hr{ :class => "sixteen columns alpha", :style => "margin-bottom: 15px" } - %div{ 'ng-hide' => 'RequestMonitor.loading || lineItems.length == 0' } - .controls{ :class => "sixteen columns alpha", :style => "margin-bottom: 15px;" } - %div{ :class => "three columns alpha" } - %input{ :class => "fullwidth", :type => "text", :id => 'quick_search', 'ng-model' => 'quickSearch', :placeholder => 'Quick Search' } - %div{ :class => "three columns" } - %div.ofn_drop_down{ 'ng-controller' => "DropDownCtrl", :id => "bulk_actions_dropdown", 'ofn-drop-down' => true } - %span{ :class => 'icon-check' }   Actions - %span{ 'ng-class' => "expanded && 'icon-caret-up' || !expanded && 'icon-caret-down'" } - %div.menu{ 'ng-show' => "expanded" } - %div.menu_item{ :class => "three columns alpha", 'ng-repeat' => "action in bulkActions", 'ng-click' => "$eval(action.callback)(filteredLineItems)", 'ofn-close-on-click' => true } - %span{ :class => 'three columns omega' } {{action.name }} - %div{ :class => "seven columns" }   - %div{ :class => "three columns omega" } - %div.ofn_drop_down{ 'ng-controller' => "DropDownCtrl", :id => "columns_dropdown", 'ofn-drop-down' => true, :style => 'float:right;' } - %span{ :class => 'icon-reorder' }   Columns - %span{ 'ng-class' => "expanded && 'icon-caret-up' || !expanded && 'icon-caret-down'" } - %div.menu{ 'ng-show' => "expanded" } - %div.menu_item{ :class => "three columns alpha", 'ng-repeat' => "column in columns", 'ofn-toggle-column' => true } - %span{ :class => 'one column alpha', :style => 'text-align: center'} {{ column.visible && "✓" || !column.visible && " " }} - %span{ :class => 'two columns omega' } {{column.name }} + %hr.divider.sixteen.columns.alpha.omega + .controls.sixteen.columns.alpha.omega{ ng: { hide: 'RequestMonitor.loading || lineItems.length == 0' } } + %div{ :class => "three columns alpha" } + %input{ :class => "fullwidth", :type => "text", :id => 'quick_search', 'ng-model' => 'quickSearch', :placeholder => 'Quick Search' } + %div{ :class => "three columns" } + %div.ofn-drop-down#bulk-actions-dropdown{ 'ng-controller' => "DropDownCtrl" } + %span{ :class => 'icon-check' }   Actions + %span{ 'ng-class' => "expanded && 'icon-caret-up' || !expanded && 'icon-caret-down'" } + %div.menu{ 'ng-show' => "expanded" } + %div.menu_item{ :class => "three columns alpha", 'ng-repeat' => "action in bulkActions", 'ng-click' => "$eval(action.callback)(filteredLineItems)", 'ofn-close-on-click' => true } + %span{ :class => 'three columns omega' } {{action.name }} + %div{ :class => "seven columns" }   + = render 'admin/shared/columns_dropdown' %div.sixteen.columns.alpha#loading{ 'ng-if' => 'RequestMonitor.loading' } %img.spinner{ src: "/assets/spinning-circles.svg" } %h1 LOADING ORDERS diff --git a/app/views/spree/admin/products/bulk_edit/_actions.html.haml b/app/views/spree/admin/products/bulk_edit/_actions.html.haml index 337f1d469b..b7cba99019 100644 --- a/app/views/spree/admin/products/bulk_edit/_actions.html.haml +++ b/app/views/spree/admin/products/bulk_edit/_actions.html.haml @@ -3,11 +3,4 @@ %input.four.columns.alpha{ :type => 'button', :value => 'Save Changes', 'ng-click' => 'submitProducts()'} %div.nine.columns = render 'spree/admin/shared/status_message' - %div.three.columns.omega - %div.ofn_drop_down.three.columns.omega{ 'ng-controller' => "DropDownCtrl", :id => "columns_dropdown", 'ofn-drop-down' => true, :style => 'float:right;' } - %span{ :class => 'icon-reorder' }   Columns - %span{ 'ng-class' => "expanded && 'icon-caret-up' || !expanded && 'icon-caret-down'" } - %div.menu{ 'ng-show' => "expanded" } - %div.menu_item{ :class => "three columns alpha", 'ng-repeat' => "column in columns", 'ofn-toggle-column' => true } - %span{ :class => 'one column alpha', :style => 'text-align: center'} {{ column.visible && "✓" || !column.visible && " " }} - %span{ :class => 'two columns omega' } {{column.name }} + = render 'admin/shared/columns_dropdown' diff --git a/spec/features/admin/bulk_order_management_spec.rb b/spec/features/admin/bulk_order_management_spec.rb index f8f2eae34a..1e011b5939 100644 --- a/spec/features/admin/bulk_order_management_spec.rb +++ b/spec/features/admin/bulk_order_management_spec.rb @@ -156,9 +156,9 @@ feature %q{ context "modifying the weight/volume of a line item" do it "price is altered" do visit '/admin/orders/bulk_management' - first("div#columns_dropdown", :text => "COLUMNS").click - first("div#columns_dropdown div.menu div.menu_item", text: "Weight/Volume").click - first("div#columns_dropdown div.menu div.menu_item", text: "Price").click + first("div#columns-dropdown", :text => "COLUMNS").click + first("div#columns-dropdown div.menu div.menu_item", text: "Weight/Volume").click + first("div#columns-dropdown div.menu div.menu_item", text: "Price").click within "tr#li_#{li1.id}" do expect(page).to have_field "price", with: "$50.00" fill_in "final_weight_volume", :with => 2000 @@ -175,8 +175,8 @@ feature %q{ context "modifying the quantity of a line item" do it "price is altered" do visit '/admin/orders/bulk_management' - first("div#columns_dropdown", :text => "COLUMNS").click - first("div#columns_dropdown div.menu div.menu_item", text: "Price").click + first("div#columns-dropdown", :text => "COLUMNS").click + first("div#columns-dropdown div.menu div.menu_item", text: "Price").click within "tr#li_#{li1.id}" do expect(page).to have_field "price", with: "$#{format("%.2f",li1.price * 5)}" fill_in "quantity", :with => 6 @@ -188,8 +188,8 @@ feature %q{ context "modifying the quantity of a line item" do it "weight/volume is altered" do visit '/admin/orders/bulk_management' - first("div#columns_dropdown", :text => "COLUMNS").click - first("div#columns_dropdown div.menu div.menu_item", text: "Weight/Volume").click + first("div#columns-dropdown", :text => "COLUMNS").click + first("div#columns-dropdown div.menu div.menu_item", text: "Weight/Volume").click within "tr#li_#{li1.id}" do expect(page).to have_field "final_weight_volume", with: "#{li1.final_weight_volume.round}" fill_in "quantity", :with => 6 @@ -209,8 +209,8 @@ feature %q{ expect(page).to have_selector "th", :text => "QUANTITY" expect(page).to have_selector "th", :text => "MAX" - first("div#columns_dropdown", :text => "COLUMNS").click - first("div#columns_dropdown div.menu div.menu_item", text: "Producer").click + first("div#columns-dropdown", :text => "COLUMNS").click + first("div#columns-dropdown div.menu div.menu_item", text: "Producer").click expect(page).to_not have_selector "th", :text => "PRODUCER" expect(page).to have_selector "th", :text => "NAME" @@ -499,8 +499,8 @@ feature %q{ it "displays a bulk action select box with a list of actions" do list_of_actions = ['Delete Selected'] - find("div#bulk_actions_dropdown").click - within("div#bulk_actions_dropdown") do + find("div#bulk-actions-dropdown").click + within("div#bulk-actions-dropdown") do list_of_actions.each { |action_name| expect(page).to have_selector "div.menu_item", text: action_name } end end @@ -512,8 +512,8 @@ feature %q{ within("tr#li_#{li2.id} td.bulk") do check "bulk" end - find("div#bulk_actions_dropdown").click - find("div#bulk_actions_dropdown div.menu_item", :text => "Delete Selected" ).click + find("div#bulk-actions-dropdown").click + find("div#bulk-actions-dropdown div.menu_item", :text => "Delete Selected" ).click expect(page).to have_selector "tr#li_#{li1.id}", visible: true expect(page).to_not have_selector "tr#li_#{li2.id}", visible: true end @@ -532,8 +532,8 @@ feature %q{ it "only applies the delete action to filteredLineItems" do check "toggle_bulk" fill_in "quick_search", with: o1.number - find("div#bulk_actions_dropdown").click - find("div#bulk_actions_dropdown div.menu_item", :text => "Delete Selected" ).click + find("div#bulk-actions-dropdown").click + find("div#bulk-actions-dropdown div.menu_item", :text => "Delete Selected" ).click fill_in "quick_search", with: '' expect(page).to_not have_selector "tr#li_#{li1.id}", visible: true expect(page).to have_selector "tr#li_#{li2.id}", visible: true diff --git a/spec/features/admin/bulk_product_update_spec.rb b/spec/features/admin/bulk_product_update_spec.rb index 91f476d16d..1a2c715e34 100644 --- a/spec/features/admin/bulk_product_update_spec.rb +++ b/spec/features/admin/bulk_product_update_spec.rb @@ -46,8 +46,8 @@ feature %q{ p2 = FactoryGirl.create(:product, available_on: Date.current-1) visit '/admin/products/bulk_edit' - first("div#columns_dropdown", :text => "COLUMNS").click - first("div#columns_dropdown div.menu div.menu_item", text: "Available On").click + first("div#columns-dropdown", :text => "COLUMNS").click + first("div#columns-dropdown div.menu div.menu_item", text: "Available On").click expect(page).to have_field "available_on", with: p1.available_on.strftime("%F %T") expect(page).to have_field "available_on", with: p2.available_on.strftime("%F %T") @@ -243,11 +243,11 @@ feature %q{ visit '/admin/products/bulk_edit' - first("div#columns_dropdown", :text => "COLUMNS").click - first("div#columns_dropdown div.menu div.menu_item", text: "Available On").click - first("div#columns_dropdown div.menu div.menu_item", text: "Category").click - first("div#columns_dropdown div.menu div.menu_item", text: "Inherits Properties?").click - first("div#columns_dropdown div.menu div.menu_item", text: "SKU").click + first("div#columns-dropdown", :text => "COLUMNS").click + first("div#columns-dropdown div.menu div.menu_item", text: "Available On").click + first("div#columns-dropdown div.menu div.menu_item", text: "Category").click + first("div#columns-dropdown div.menu div.menu_item", text: "Inherits Properties?").click + first("div#columns-dropdown div.menu div.menu_item", text: "SKU").click within "tr#p_#{p.id}" do expect(page).to have_field "product_name", with: p.name @@ -556,8 +556,8 @@ feature %q{ visit '/admin/products/bulk_edit' - first("div#columns_dropdown", :text => "COLUMNS").click - first("div#columns_dropdown div.menu div.menu_item", text: "Available On").click + first("div#columns-dropdown", :text => "COLUMNS").click + first("div#columns-dropdown div.menu div.menu_item", text: "Available On").click expect(page).to have_selector "th", :text => "NAME" expect(page).to have_selector "th", :text => "PRODUCER" @@ -565,7 +565,7 @@ feature %q{ expect(page).to have_selector "th", :text => "ON HAND" expect(page).to have_selector "th", :text => "AV. ON" - first("div#columns_dropdown div.menu div.menu_item", text: /^.{0,1}Producer$/).click + first("div#columns-dropdown div.menu div.menu_item", text: /^.{0,1}Producer$/).click expect(page).to have_no_selector "th", :text => "PRODUCER" expect(page).to have_selector "th", :text => "NAME" @@ -688,8 +688,8 @@ feature %q{ v = p.variants.first visit '/admin/products/bulk_edit' - first("div#columns_dropdown", :text => "COLUMNS").click - first("div#columns_dropdown div.menu div.menu_item", text: "Available On").click + first("div#columns-dropdown", :text => "COLUMNS").click + first("div#columns-dropdown div.menu div.menu_item", text: "Available On").click within "tr#p_#{p.id}" do expect(page).to have_field "product_name", with: p.name diff --git a/spec/features/admin/customers_spec.rb b/spec/features/admin/customers_spec.rb index c84f8f35ed..5d2ffedb4e 100644 --- a/spec/features/admin/customers_spec.rb +++ b/spec/features/admin/customers_spec.rb @@ -39,8 +39,8 @@ feature 'Customers' do # Toggling columns expect(page).to have_selector "th.email" expect(page).to have_content customer1.email - first("div#columns_dropdown", :text => "COLUMNS").click - first("div#columns_dropdown div.menu div.menu_item", text: "Email").click + first("div#columns-dropdown", :text => "COLUMNS").click + first("div#columns-dropdown div.menu div.menu_item", text: "Email").click expect(page).to_not have_selector "th.email" expect(page).to_not have_content customer1.email end diff --git a/spec/features/admin/orders_spec.rb b/spec/features/admin/orders_spec.rb index ce0dea54c8..725495b74b 100644 --- a/spec/features/admin/orders_spec.rb +++ b/spec/features/admin/orders_spec.rb @@ -192,7 +192,7 @@ feature %q{ order = create(:completed_order_with_totals, distributor: distributor1) visit spree.admin_order_path(order) - find("#links-dropdown .ofn_drop_down").click + find("#links-dropdown .ofn-drop-down").click within "#links-dropdown" do expect(page).to have_link "Edit", href: spree.edit_admin_order_path(order) expect(page).to have_link "Resend Confirmation", href: spree.resend_admin_order_path(order) From 2b70ddb23c84a81c553d4a7e1aa820591c587e62 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 27 Nov 2015 08:24:55 +1100 Subject: [PATCH 10/43] Adding columns toggle to variant overrides index --- .../controllers/variant_overrides_controller.js.coffee | 8 +++++++- .../variant_overrides/variant_overrides.js.coffee | 2 +- app/views/admin/variant_overrides/_products.html.haml | 10 +++++----- .../variant_overrides/_products_product.html.haml | 8 ++++---- .../variant_overrides/_products_variants.html.haml | 8 ++++---- app/views/admin/variant_overrides/index.html.haml | 4 ++++ 6 files changed, 25 insertions(+), 15 deletions(-) diff --git a/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee b/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee index c179d9a6a8..290e2b4afc 100644 --- a/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee +++ b/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee @@ -1,4 +1,4 @@ -angular.module("admin.variantOverrides").controller "AdminVariantOverridesCtrl", ($scope, Indexer, SpreeApiAuth, PagedFetcher, StatusMessage, hubs, producers, hubPermissions, VariantOverrides, DirtyVariantOverrides) -> +angular.module("admin.variantOverrides").controller "AdminVariantOverridesCtrl", ($scope, Indexer, Columns, SpreeApiAuth, PagedFetcher, StatusMessage, hubs, producers, hubPermissions, VariantOverrides, DirtyVariantOverrides) -> $scope.hubs = Indexer.index hubs $scope.hub = null $scope.products = [] @@ -8,6 +8,12 @@ angular.module("admin.variantOverrides").controller "AdminVariantOverridesCtrl", $scope.variantOverrides = VariantOverrides.variantOverrides $scope.StatusMessage = StatusMessage + $scope.columns = Columns.setColumns + producer: { name: "Producer", visible: true } + product: { name: "Product", visible: true } + price: { name: "Price", visible: true } + on_hand: { name: "On Hand", visible: true } + $scope.resetSelectFilters = -> $scope.producerFilter = 0 $scope.query = '' diff --git a/app/assets/javascripts/admin/variant_overrides/variant_overrides.js.coffee b/app/assets/javascripts/admin/variant_overrides/variant_overrides.js.coffee index 4766bd464c..bddef7cf6f 100644 --- a/app/assets/javascripts/admin/variant_overrides/variant_overrides.js.coffee +++ b/app/assets/javascripts/admin/variant_overrides/variant_overrides.js.coffee @@ -1 +1 @@ -angular.module("admin.variantOverrides", ["admin.indexUtils", "pasvaz.bindonce"]) +angular.module("admin.variantOverrides", ["admin.indexUtils", "pasvaz.bindonce", "admin.dropdown"]) diff --git a/app/views/admin/variant_overrides/_products.html.haml b/app/views/admin/variant_overrides/_products.html.haml index fa5cfe0ec0..34125f4b05 100644 --- a/app/views/admin/variant_overrides/_products.html.haml +++ b/app/views/admin/variant_overrides/_products.html.haml @@ -1,10 +1,10 @@ %table.index.bulk{ ng: {show: 'hub'}} %thead - %tr - %th Producer - %th Product - %th Price - %th On hand + %tr{ ng: { controller: "ColumnsCtrl" } } + %th.producer{ ng: { show: 'columns.producer.visible' } } Producer + %th.product{ ng: { show: 'columns.product.visible' } } Product + %th.price{ ng: { show: 'columns.price.visible' } } Price + %th.on_hand{ ng: { show: 'columns.on_hand.visible' } } On hand %tbody{bindonce: true, ng: {repeat: 'product in products | hubPermissions:hubPermissions:hub.id | attrFilter:{producer_id:producerFilter} | filter:query' } } = render 'admin/variant_overrides/products_product' = render 'admin/variant_overrides/products_variants' diff --git a/app/views/admin/variant_overrides/_products_product.html.haml b/app/views/admin/variant_overrides/_products_product.html.haml index 9ce07b3aa6..a7e9989c70 100644 --- a/app/views/admin/variant_overrides/_products_product.html.haml +++ b/app/views/admin/variant_overrides/_products_product.html.haml @@ -1,5 +1,5 @@ %tr.product.even - %td{ bo: { bind: 'producersByID[product.producer_id].name'} } - %td{ bo: { bind: 'product.name'} } - %td - %td + %td.producer{ ng: { show: 'columns.producer.visible' }, bo: { bind: 'producersByID[product.producer_id].name'} } + %td.product{ ng: { show: 'columns.product.visible' }, bo: { bind: 'product.name'} } + %td.price{ ng: { show: 'columns.price.visible' } } + %td.on_hand{ ng: { show: 'columns.on_hand.visible' } } diff --git a/app/views/admin/variant_overrides/_products_variants.html.haml b/app/views/admin/variant_overrides/_products_variants.html.haml index 2868b6f8f2..324ef9070f 100644 --- a/app/views/admin/variant_overrides/_products_variants.html.haml +++ b/app/views/admin/variant_overrides/_products_variants.html.haml @@ -1,10 +1,10 @@ %tr.variant{ id: "v_{{variant.id}}", ng: {repeat: 'variant in product.variants'}} - %td - %td + %td.producer{ ng: { show: 'columns.producer.visible' } } + %td.product{ ng: { show: 'columns.product.visible' } } %span{ bo: { bind: 'variant.display_name || ""'} } .variant-override-unit{ bo: { bind: 'variant.unit_to_display'} } - %td + %td.price{ ng: { show: 'columns.price.visible' } } %input{name: 'variant-overrides-{{ variant.id }}-price', type: 'text', ng: {model: 'variantOverrides[hub.id][variant.id].price'}, placeholder: '{{ variant.price }}', 'ofn-track-variant-override' => 'price'} - %td + %td.on_hand{ ng: { show: 'columns.on_hand.visible' } } %input{name: 'variant-overrides-{{ variant.id }}-count-on-hand', type: 'text', ng: {model: 'variantOverrides[hub.id][variant.id].count_on_hand'}, placeholder: '{{ variant.on_hand }}', 'ofn-track-variant-override' => 'price'} diff --git a/app/views/admin/variant_overrides/index.html.haml b/app/views/admin/variant_overrides/index.html.haml index 2d202bac27..96fef5307d 100644 --- a/app/views/admin/variant_overrides/index.html.haml +++ b/app/views/admin/variant_overrides/index.html.haml @@ -3,6 +3,10 @@ %div{ ng: { app: 'admin.variantOverrides', controller: 'AdminVariantOverridesCtrl', init: 'initialise()' } } = render 'admin/variant_overrides/filters' + %hr.divider.sixteen.columns.alpha.omega + .controls.sixteen.columns.alpha.omega + %div.thirteen.columns.alpha   + = render 'admin/shared/columns_dropdown' %form{ name: 'variant_overrides_form' } %save-bar{ save: "update()", form: "variant_overrides_form" } From 7cd8f35ac863152b0995e2128f755b91249d2d13 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 27 Nov 2015 08:42:26 +1100 Subject: [PATCH 11/43] Tidying up styling and use of skeleton columns on index pages --- app/assets/stylesheets/admin/dropdown.css.scss | 6 +++++- app/assets/stylesheets/admin/orders.css.scss | 4 ---- app/views/admin/customers/index.html.haml | 2 +- .../admin/shared/_columns_dropdown.html.haml | 2 +- .../spree/admin/orders/bulk_management.html.haml | 16 ++++++++-------- .../spree/admin/products/bulk_edit.html.haml | 2 +- .../admin/products/bulk_edit/_actions.html.haml | 6 +++--- .../admin/products/bulk_edit/_filters.html.haml | 16 ++++++++-------- 8 files changed, 27 insertions(+), 27 deletions(-) diff --git a/app/assets/stylesheets/admin/dropdown.css.scss b/app/assets/stylesheets/admin/dropdown.css.scss index 9e1de193be..2dfa369c87 100644 --- a/app/assets/stylesheets/admin/dropdown.css.scss +++ b/app/assets/stylesheets/admin/dropdown.css.scss @@ -18,7 +18,7 @@ background-color: #f5f5f5; position: relative; display: block; - float: right; + float: left; color: #828282; cursor: pointer; -moz-user-select: none; @@ -28,6 +28,10 @@ user-select: none; text-align: center; + &.right { + float: right; + } + &:hover, &.expanded { border: 1px solid #adadad; color: #575757; diff --git a/app/assets/stylesheets/admin/orders.css.scss b/app/assets/stylesheets/admin/orders.css.scss index 4676d93b1a..544abfa899 100644 --- a/app/assets/stylesheets/admin/orders.css.scss +++ b/app/assets/stylesheets/admin/orders.css.scss @@ -1,7 +1,3 @@ -.filter_select, .date_filter { - margin-bottom: 10px; -} - input, div { &.update-pending { border: solid 1px orange; diff --git a/app/views/admin/customers/index.html.haml b/app/views/admin/customers/index.html.haml index 67998b686f..f8c08a59ae 100644 --- a/app/views/admin/customers/index.html.haml +++ b/app/views/admin/customers/index.html.haml @@ -12,7 +12,7 @@ .seven.columns.omega   .row{ 'ng-hide' => '!loaded() || filteredCustomers.length == 0' } - .controls{ :class => "sixteen columns alpha", :style => "margin-bottom: 15px;" } + .controls.sixteen.columns.alpha.omega .five.columns.alpha %input{ :class => "fullwidth", :type => "text", :id => 'quick_search', 'ng-model' => 'quickSearch', :placeholder => 'Quick Search' } .five.columns   diff --git a/app/views/admin/shared/_columns_dropdown.html.haml b/app/views/admin/shared/_columns_dropdown.html.haml index 4e19d6615b..b16d388c1d 100644 --- a/app/views/admin/shared/_columns_dropdown.html.haml +++ b/app/views/admin/shared/_columns_dropdown.html.haml @@ -1,5 +1,5 @@ %div.three.columns.omega - %div.ofn-drop-down#columns-dropdown{ 'ng-controller' => "DropDownCtrl" } + %div.ofn-drop-down.right#columns-dropdown{ 'ng-controller' => "DropDownCtrl" } %span{ :class => 'icon-reorder' }   Columns %span{ 'ng-class' => "expanded && 'icon-caret-up' || !expanded && 'icon-caret-down'" } %div.menu{ 'ng-show' => "expanded" } diff --git a/app/views/spree/admin/orders/bulk_management.html.haml b/app/views/spree/admin/orders/bulk_management.html.haml index d03fde0f27..df52da76ac 100644 --- a/app/views/spree/admin/orders/bulk_management.html.haml +++ b/app/views/spree/admin/orders/bulk_management.html.haml @@ -32,8 +32,8 @@ %label{ :for => 'clear_all_filters' } %br %input.red.fullwidth{ :type => 'button', :id => 'clear_all_filters', :value => "Clear All", 'ng-click' => "resetSelectFilters()" } - %hr{ :class => "sixteen columns alpha", 'ng-show' => 'unitsVariantSelected()' } - %div#group_buy_calculation{ :class => "sixteen columns alpha", 'ng-show' => 'unitsVariantSelected()' } + %hr.divider.sixteen.columns.alpha.omega{ ng: { show: 'unitsVariantSelected()' } } + %div.sixteen.columns.alpha.omega#group_buy_calculation{ ng: { show: 'unitsVariantSelected()' } } %div.shared_resource{ :class => "four columns alpha" } %span{ :class => 'three columns alpha' } %input{ type: 'checkbox', :id => 'shared_resource', 'ng-model' => 'sharedResource'} @@ -72,16 +72,16 @@ WARNING: Some variants do not have a unit value %hr.divider.sixteen.columns.alpha.omega .controls.sixteen.columns.alpha.omega{ ng: { hide: 'RequestMonitor.loading || lineItems.length == 0' } } - %div{ :class => "three columns alpha" } - %input{ :class => "fullwidth", :type => "text", :id => 'quick_search', 'ng-model' => 'quickSearch', :placeholder => 'Quick Search' } - %div{ :class => "three columns" } + %div.three.columns.alpha + %input.fullwidth{ :type => "text", :id => 'quick_search', 'ng-model' => 'quickSearch', :placeholder => 'Quick Search' } + %div.three.columns %div.ofn-drop-down#bulk-actions-dropdown{ 'ng-controller' => "DropDownCtrl" } %span{ :class => 'icon-check' }   Actions %span{ 'ng-class' => "expanded && 'icon-caret-up' || !expanded && 'icon-caret-down'" } %div.menu{ 'ng-show' => "expanded" } - %div.menu_item{ :class => "three columns alpha", 'ng-repeat' => "action in bulkActions", 'ng-click' => "$eval(action.callback)(filteredLineItems)", 'ofn-close-on-click' => true } - %span{ :class => 'three columns omega' } {{action.name }} - %div{ :class => "seven columns" }   + %div.three.columns.alpha.menu_item{ 'ng-repeat' => "action in bulkActions", 'ng-click' => "$eval(action.callback)(filteredLineItems)", 'ofn-close-on-click' => true } + %span.three.columns.omega {{action.name }} + %div.seven.columns   = render 'admin/shared/columns_dropdown' %div.sixteen.columns.alpha#loading{ 'ng-if' => 'RequestMonitor.loading' } %img.spinner{ src: "/assets/spinning-circles.svg" } diff --git a/app/views/spree/admin/products/bulk_edit.html.haml b/app/views/spree/admin/products/bulk_edit.html.haml index 22b0a195da..235544cb8a 100644 --- a/app/views/spree/admin/products/bulk_edit.html.haml +++ b/app/views/spree/admin/products/bulk_edit.html.haml @@ -4,7 +4,7 @@ %div{ ng: { app: 'ofn.admin', controller: 'AdminProductEditCtrl', init: 'initialise()' } } = render 'spree/admin/products/bulk_edit/filters' - %hr.sixteen.columns.alpha + %hr.divider.sixteen.columns.alpha.omega = render 'spree/admin/products/bulk_edit/actions' = render 'spree/admin/products/bulk_edit/indicators' = render 'spree/admin/products/bulk_edit/products' diff --git a/app/views/spree/admin/products/bulk_edit/_actions.html.haml b/app/views/spree/admin/products/bulk_edit/_actions.html.haml index b7cba99019..7ea29bdb4c 100644 --- a/app/views/spree/admin/products/bulk_edit/_actions.html.haml +++ b/app/views/spree/admin/products/bulk_edit/_actions.html.haml @@ -1,6 +1,6 @@ -%div.sixteen.columns.alpha{ 'ng-hide' => 'loading || products.length == 0', style: "margin-bottom: 10px" } - %div.four.columns.alpha +.controls.sixteen.columns.alpha{ 'ng-hide' => 'loading || products.length == 0' } + .four.columns.alpha %input.four.columns.alpha{ :type => 'button', :value => 'Save Changes', 'ng-click' => 'submitProducts()'} - %div.nine.columns + .nine.columns = render 'spree/admin/shared/status_message' = render 'admin/shared/columns_dropdown' diff --git a/app/views/spree/admin/products/bulk_edit/_filters.html.haml b/app/views/spree/admin/products/bulk_edit/_filters.html.haml index 99c1067663..3e676ede6d 100644 --- a/app/views/spree/admin/products/bulk_edit/_filters.html.haml +++ b/app/views/spree/admin/products/bulk_edit/_filters.html.haml @@ -1,18 +1,18 @@ -%div.sixteen.columns.alpha - %div.quick_search{ :class => "four columns alpha" } +.filters.sixteen.columns.alpha.omega + .quick_search.four.columns.alpha %label{ :for => 'quick_filter' } %br - %input.search{ :class => "four columns alpha", 'ng-model' => 'query', :name => "quick_filter", :type => 'text', 'placeholder' => 'Quick Search' } - .filter_select{ :class => "four columns" } + %input.quick-search.fullwidth{ 'ng-model' => 'query', :name => "quick_filter", :type => 'text', 'placeholder' => 'Quick Search' } + .filter_select.four.columns %label{ :for => 'producer_filter' }Producer %br - %select{ :class => "four columns alpha", :id => 'producer_filter', 'ofn-select2-min-search' => 5, 'ng-model' => 'producerFilter', 'ng-options' => 'producer.id as producer.name for producer in filterProducers' } - .filter_select{ :class => "four columns" } + %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 %label{ :for => 'category_filter' }Category %br - %select{ :class => "four columns alpha", :id => 'category_filter', 'ofn-select2-min-search' => 5, 'ng-model' => 'categoryFilter', 'ng-options' => 'taxon.id as taxon.name for taxon in filterTaxons'} + %select.fullwidth{ :id => 'category_filter', 'ofn-select2-min-search' => 5, 'ng-model' => 'categoryFilter', 'ng-options' => 'taxon.id as taxon.name for taxon in filterTaxons'} %div{ :class => "one column" }   - .filter_clear{ :class => "three columns omega" } + .filter_clear.three.columns.omega %label{ :for => 'clear_all_filters' } %br %input.fullwidth.red{ :type => 'button', :id => 'clear_all_filters', :value => "Clear Filters", 'ng-click' => "resetSelectFilters()" } From cab6871de3bc3fe2c6262eb21e005253e933a11d Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 27 Nov 2015 08:48:52 +1100 Subject: [PATCH 12/43] Pulling bulk actions dropdown out into partial --- app/views/admin/customers/index.html.haml | 9 ++------- .../enterprises/_enterprise_user_index.html.haml | 7 +------ .../shared/_bulk_actions_dropdown.html.haml | 7 +++++++ .../spree/admin/orders/bulk_management.html.haml | 16 +++++++++------- 4 files changed, 19 insertions(+), 20 deletions(-) create mode 100644 app/views/admin/shared/_bulk_actions_dropdown.html.haml diff --git a/app/views/admin/customers/index.html.haml b/app/views/admin/customers/index.html.haml index f8c08a59ae..5647821bf5 100644 --- a/app/views/admin/customers/index.html.haml +++ b/app/views/admin/customers/index.html.haml @@ -14,14 +14,9 @@ .row{ 'ng-hide' => '!loaded() || filteredCustomers.length == 0' } .controls.sixteen.columns.alpha.omega .five.columns.alpha - %input{ :class => "fullwidth", :type => "text", :id => 'quick_search', 'ng-model' => 'quickSearch', :placeholder => 'Quick Search' } + %input.fullwidth{ :type => "text", :id => 'quick_search', 'ng-model' => 'quickSearch', :placeholder => 'Quick Search' } .five.columns   - -# %div.ofn-drop-down#bulk-actions-dropdown{ 'ng-controller' => "DropDownCtrl" } - -# %span{ :class => 'icon-check' }   Actions - -# %span{ 'ng-class' => "expanded && 'icon-caret-up' || !expanded && 'icon-caret-down'" } - -# %div.menu{ 'ng-show' => "expanded" } - -# %div.menu_item{ :class => "three columns alpha", 'ng-repeat' => "action in bulkActions", 'ng-click' => "selectedBulkAction.callback(filteredCustomers)", 'ofn-close-on-click' => true } - -# %span{ :class => 'three columns omega' } {{action.name }} + -# =render 'admin/shared/bulk_actions_dropdown' .three.columns   = render 'admin/shared/columns_dropdown' .row{ 'ng-if' => 'shop && !loaded()' } diff --git a/app/views/admin/enterprises/_enterprise_user_index.html.haml b/app/views/admin/enterprises/_enterprise_user_index.html.haml index d7fe846274..1fb35e595c 100644 --- a/app/views/admin/enterprises/_enterprise_user_index.html.haml +++ b/app/views/admin/enterprises/_enterprise_user_index.html.haml @@ -4,12 +4,7 @@ .four.columns.alpha %input{ :class => "fullwidth", :type => "text", :id => 'quick_search', 'ng-model' => 'quickSearch', :placeholder => 'Search By Name' } .six.columns   - -# %div.ofn-drop-down#bulk-actions-dropdown{ 'ng-controller' => "DropDownCtrl" } - -# %span{ :class => 'icon-check' }   Actions - -# %span{ 'ng-class' => "expanded && 'icon-caret-up' || !expanded && 'icon-caret-down'" } - -# %div.menu{ 'ng-show' => "expanded" } - -# %div.menu_item{ :class => "three columns alpha", 'ng-repeat' => "action in bulkActions", 'ng-click' => "selectedBulkAction.callback(filteredEnterprises)", 'ofn-close-on-click' => true } - -# %span{ :class => 'three columns omega' } {{action.name }} + -# = render 'admin/shared/bulk_actions_dropdown' .three.columns   = render 'admin/shared/columns_dropdown' .row{ 'ng-if' => '!loaded' } diff --git a/app/views/admin/shared/_bulk_actions_dropdown.html.haml b/app/views/admin/shared/_bulk_actions_dropdown.html.haml new file mode 100644 index 0000000000..912fe6662a --- /dev/null +++ b/app/views/admin/shared/_bulk_actions_dropdown.html.haml @@ -0,0 +1,7 @@ +.three.columns + .ofn-drop-down#bulk-actions-dropdown{ 'ng-controller' => "DropDownCtrl" } + %span.icon-check   Actions + %span{ 'ng-class' => "expanded && 'icon-caret-up' || !expanded && 'icon-caret-down'" } + %div.menu{ 'ng-show' => "expanded" } + .three.columns.alpha.menu_item{ 'ng-repeat' => "action in bulkActions", 'ng-click' => "$eval(action.callback)(filteredLineItems)", 'ofn-close-on-click' => true } + %span.three.columns.omega {{action.name }} diff --git a/app/views/spree/admin/orders/bulk_management.html.haml b/app/views/spree/admin/orders/bulk_management.html.haml index df52da76ac..0ab782023d 100644 --- a/app/views/spree/admin/orders/bulk_management.html.haml +++ b/app/views/spree/admin/orders/bulk_management.html.haml @@ -32,7 +32,9 @@ %label{ :for => 'clear_all_filters' } %br %input.red.fullwidth{ :type => 'button', :id => 'clear_all_filters', :value => "Clear All", 'ng-click' => "resetSelectFilters()" } + %hr.divider.sixteen.columns.alpha.omega{ ng: { show: 'unitsVariantSelected()' } } + %div.sixteen.columns.alpha.omega#group_buy_calculation{ ng: { show: 'unitsVariantSelected()' } } %div.shared_resource{ :class => "four columns alpha" } %span{ :class => 'three columns alpha' } @@ -70,24 +72,23 @@ %div{ :class => "eight columns alpha", 'ng-hide' => 'allFinalWeightVolumesPresent()' } %span{ :class => "eight columns alpha", style: 'color:red' } WARNING: Some variants do not have a unit value + %hr.divider.sixteen.columns.alpha.omega + .controls.sixteen.columns.alpha.omega{ ng: { hide: 'RequestMonitor.loading || lineItems.length == 0' } } %div.three.columns.alpha %input.fullwidth{ :type => "text", :id => 'quick_search', 'ng-model' => 'quickSearch', :placeholder => 'Quick Search' } - %div.three.columns - %div.ofn-drop-down#bulk-actions-dropdown{ 'ng-controller' => "DropDownCtrl" } - %span{ :class => 'icon-check' }   Actions - %span{ 'ng-class' => "expanded && 'icon-caret-up' || !expanded && 'icon-caret-down'" } - %div.menu{ 'ng-show' => "expanded" } - %div.three.columns.alpha.menu_item{ 'ng-repeat' => "action in bulkActions", 'ng-click' => "$eval(action.callback)(filteredLineItems)", 'ofn-close-on-click' => true } - %span.three.columns.omega {{action.name }} + = render 'admin/shared/bulk_actions_dropdown' %div.seven.columns   = render 'admin/shared/columns_dropdown' + %div.sixteen.columns.alpha#loading{ 'ng-if' => 'RequestMonitor.loading' } %img.spinner{ src: "/assets/spinning-circles.svg" } %h1 LOADING ORDERS + %div{ :class => "sixteen columns alpha", 'ng-show' => '!RequestMonitor.loading && filteredLineItems.length == 0'} %h1#no_results No orders found. + %div{ 'ng-hide' => 'RequestMonitor.loading || filteredLineItems.length == 0' } %form{ name: 'bulk_order_form' } %table.index#listing_orders.bulk{ :class => "sixteen columns alpha" } @@ -121,6 +122,7 @@ %th.actions Ask?  %input{ :type => 'checkbox', 'ng-model' => "confirmDelete" } + %tr.line_item{ 'ng-repeat' => "line_item in filteredLineItems = ( lineItems | filter:quickSearch | selectFilter:supplierFilter:distributorFilter:orderCycleFilter | variantFilter:selectedUnitsProduct:selectedUnitsVariant:sharedResource | orderBy:predicate:reverse )", 'ng-class-even' => "'even'", 'ng-class-odd' => "'odd'", :id => "li_{{line_item.id}}" } %td.bulk %input{ :type => "checkbox", :name => 'bulk', 'ng-model' => 'line_item.checked', 'ignore-dirty' => true } From 521f227f742252e2ab168e1eacf8bafec4f440eb Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 18 Dec 2015 09:56:56 +1100 Subject: [PATCH 13/43] Adding sku and on_demand to VariantOverride --- .../variant_overrides_controller.js.coffee | 2 + .../services/variant_overrides.js.coffee | 6 +- app/models/spree/ability_decorator.rb | 2 + app/models/variant_override_set.rb | 9 ++- .../api/admin/variant_override_serializer.rb | 2 +- .../api/admin/variant_serializer.rb | 2 +- .../variant_overrides/_products.html.haml | 2 + .../_products_product.html.haml | 2 + .../_products_variants.html.haml | 5 +- ..._on_demand_and_sku_to_variant_overrides.rb | 6 ++ db/schema.rb | 4 +- lib/open_food_network/scope_variant_to_hub.rb | 19 +++-- .../variant_overrides_controller_spec.rb | 57 +++++++++++++++ .../scope_variant_to_hub_spec.rb | 73 ++++++++++++++++++- 14 files changed, 176 insertions(+), 15 deletions(-) create mode 100644 db/migrate/20151126235409_add_on_demand_and_sku_to_variant_overrides.rb create mode 100644 spec/controllers/admin/variant_overrides_controller_spec.rb diff --git a/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee b/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee index 290e2b4afc..f4c819f14a 100644 --- a/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee +++ b/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee @@ -11,8 +11,10 @@ angular.module("admin.variantOverrides").controller "AdminVariantOverridesCtrl", $scope.columns = Columns.setColumns producer: { name: "Producer", visible: true } product: { name: "Product", visible: true } + sku: { name: "SKU", visible: false } price: { name: "Price", visible: true } on_hand: { name: "On Hand", visible: true } + on_demand: { name: "On Demand", visible: false } $scope.resetSelectFilters = -> $scope.producerFilter = 0 diff --git a/app/assets/javascripts/admin/variant_overrides/services/variant_overrides.js.coffee b/app/assets/javascripts/admin/variant_overrides/services/variant_overrides.js.coffee index 697d459b75..524dc9056a 100644 --- a/app/assets/javascripts/admin/variant_overrides/services/variant_overrides.js.coffee +++ b/app/assets/javascripts/admin/variant_overrides/services/variant_overrides.js.coffee @@ -15,8 +15,10 @@ angular.module("admin.variantOverrides").factory "VariantOverrides", (variantOve @variantOverrides[hub.id][variant.id] ||= variant_id: variant.id hub_id: hub.id - price: '' - count_on_hand: '' + sku: null + price: null + count_on_hand: null + on_demand: null updateIds: (updatedVos) -> for vo in updatedVos diff --git a/app/models/spree/ability_decorator.rb b/app/models/spree/ability_decorator.rb index 25e0ced2cc..b9716e2eb3 100644 --- a/app/models/spree/ability_decorator.rb +++ b/app/models/spree/ability_decorator.rb @@ -112,6 +112,8 @@ class AbilityDecorator end can [:admin, :index, :read, :update, :bulk_update], VariantOverride do |vo| + next false unless vo.hub.present? && vo.variant.andand.product.andand.supplier.present? + hub_auth = OpenFoodNetwork::Permissions.new(user). variant_override_hubs. include? vo.hub diff --git a/app/models/variant_override_set.rb b/app/models/variant_override_set.rb index 985190095b..0fc0d170e9 100644 --- a/app/models/variant_override_set.rb +++ b/app/models/variant_override_set.rb @@ -1,6 +1,13 @@ class VariantOverrideSet < ModelSet def initialize(collection, attributes={}) super(VariantOverride, collection, attributes, nil, - proc { |attrs| attrs['price'].blank? && attrs['count_on_hand'].blank? } ) + proc { |attrs| deletable?(attrs) } ) + end + + def deletable?(attrs) + attrs['price'].blank? && + attrs['count_on_hand'].blank? && + attrs['sku'].nil? && + attrs['on_demand'].nil? end end diff --git a/app/serializers/api/admin/variant_override_serializer.rb b/app/serializers/api/admin/variant_override_serializer.rb index ebe76a1049..d4f584d9ea 100644 --- a/app/serializers/api/admin/variant_override_serializer.rb +++ b/app/serializers/api/admin/variant_override_serializer.rb @@ -1,3 +1,3 @@ class Api::Admin::VariantOverrideSerializer < ActiveModel::Serializer - attributes :id, :hub_id, :variant_id, :price, :count_on_hand + attributes :id, :hub_id, :variant_id, :sku, :price, :count_on_hand, :on_demand end diff --git a/app/serializers/api/admin/variant_serializer.rb b/app/serializers/api/admin/variant_serializer.rb index 510f7af333..66acfe8ece 100644 --- a/app/serializers/api/admin/variant_serializer.rb +++ b/app/serializers/api/admin/variant_serializer.rb @@ -1,5 +1,5 @@ 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 + 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 has_many :variant_overrides diff --git a/app/views/admin/variant_overrides/_products.html.haml b/app/views/admin/variant_overrides/_products.html.haml index 34125f4b05..f4b692c06b 100644 --- a/app/views/admin/variant_overrides/_products.html.haml +++ b/app/views/admin/variant_overrides/_products.html.haml @@ -3,8 +3,10 @@ %tr{ ng: { controller: "ColumnsCtrl" } } %th.producer{ ng: { show: 'columns.producer.visible' } } Producer %th.product{ ng: { show: 'columns.product.visible' } } Product + %th.sku{ ng: { show: 'columns.sku.visible' } } SKU %th.price{ ng: { show: 'columns.price.visible' } } Price %th.on_hand{ ng: { show: 'columns.on_hand.visible' } } On hand + %th.on_demand{ ng: { show: 'columns.on_demand.visible' } } On Demand? %tbody{bindonce: true, ng: {repeat: 'product in products | hubPermissions:hubPermissions:hub.id | attrFilter:{producer_id:producerFilter} | filter:query' } } = render 'admin/variant_overrides/products_product' = render 'admin/variant_overrides/products_variants' diff --git a/app/views/admin/variant_overrides/_products_product.html.haml b/app/views/admin/variant_overrides/_products_product.html.haml index a7e9989c70..825be1a6f6 100644 --- a/app/views/admin/variant_overrides/_products_product.html.haml +++ b/app/views/admin/variant_overrides/_products_product.html.haml @@ -1,5 +1,7 @@ %tr.product.even %td.producer{ ng: { show: 'columns.producer.visible' }, bo: { bind: 'producersByID[product.producer_id].name'} } %td.product{ ng: { show: 'columns.product.visible' }, bo: { bind: 'product.name'} } + %td.sku{ ng: { show: 'columns.sku.visible' } } %td.price{ ng: { show: 'columns.price.visible' } } %td.on_hand{ ng: { show: 'columns.on_hand.visible' } } + %td.on_demand{ ng: { show: 'columns.on_demand.visible' } } diff --git a/app/views/admin/variant_overrides/_products_variants.html.haml b/app/views/admin/variant_overrides/_products_variants.html.haml index 324ef9070f..687197f09a 100644 --- a/app/views/admin/variant_overrides/_products_variants.html.haml +++ b/app/views/admin/variant_overrides/_products_variants.html.haml @@ -3,8 +3,11 @@ %td.product{ ng: { show: 'columns.product.visible' } } %span{ bo: { bind: 'variant.display_name || ""'} } .variant-override-unit{ bo: { bind: 'variant.unit_to_display'} } + %td.sku{ ng: { show: 'columns.sku.visible' } } + %input{name: 'variant-overrides-{{ variant.id }}-sku', type: 'text', ng: {model: 'variantOverrides[hub.id][variant.id].sku'}, placeholder: '{{ variant.sku }}', 'ofn-track-variant-override' => 'sku'} %td.price{ ng: { show: 'columns.price.visible' } } %input{name: 'variant-overrides-{{ variant.id }}-price', type: 'text', ng: {model: 'variantOverrides[hub.id][variant.id].price'}, placeholder: '{{ variant.price }}', 'ofn-track-variant-override' => 'price'} - %td.on_hand{ ng: { show: 'columns.on_hand.visible' } } %input{name: 'variant-overrides-{{ variant.id }}-count-on-hand', type: 'text', ng: {model: 'variantOverrides[hub.id][variant.id].count_on_hand'}, placeholder: '{{ variant.on_hand }}', 'ofn-track-variant-override' => 'price'} + %td.on_demand{ ng: { show: 'columns.on_demand.visible' } } + %input.field{ :type => 'checkbox', name: 'variant-overrides-{{ variant.id }}-on_demand', ng: { model: 'variantOverrides[hub.id][variant.id].on_demand' }, 'ofn-track-variant-override' => 'on_demand' } diff --git a/db/migrate/20151126235409_add_on_demand_and_sku_to_variant_overrides.rb b/db/migrate/20151126235409_add_on_demand_and_sku_to_variant_overrides.rb new file mode 100644 index 0000000000..9c47bfbc27 --- /dev/null +++ b/db/migrate/20151126235409_add_on_demand_and_sku_to_variant_overrides.rb @@ -0,0 +1,6 @@ +class AddOnDemandAndSkuToVariantOverrides < ActiveRecord::Migration + def change + add_column :variant_overrides, :sku, :string, :default => nil, :after => :hub_id + add_column :variant_overrides, :on_demand, :boolean, :default => nil, :after => :count_on_hand + end +end diff --git a/db/schema.rb b/db/schema.rb index fb50bec0a1..91895e993d 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20151125051510) do +ActiveRecord::Schema.define(:version => 20151126235409) do create_table "account_invoices", :force => true do |t| t.integer "user_id", :null => false @@ -1159,6 +1159,8 @@ ActiveRecord::Schema.define(:version => 20151125051510) do t.integer "hub_id", :null => false t.decimal "price", :precision => 8, :scale => 2 t.integer "count_on_hand" + t.string "sku" + t.boolean "on_demand" end add_index "variant_overrides", ["variant_id", "hub_id"], :name => "index_variant_overrides_on_variant_id_and_hub_id" diff --git a/lib/open_food_network/scope_variant_to_hub.rb b/lib/open_food_network/scope_variant_to_hub.rb index 80396ffa17..37a2455616 100644 --- a/lib/open_food_network/scope_variant_to_hub.rb +++ b/lib/open_food_network/scope_variant_to_hub.rb @@ -26,12 +26,16 @@ module OpenFoodNetwork end def on_demand - if @variant_override.andand.count_on_hand.present? - # If we're overriding the stock level of an on_demand variant, show it as not - # on_demand, so our stock control can take effect. - false + if @variant_override.andand.on_demand.nil? + if @variant_override.andand.count_on_hand.present? + # If we're overriding the stock level of an on_demand variant, show it as not + # on_demand, so our stock control can take effect. + false + else + super + end else - super + @variant_override.andand.on_demand end end @@ -42,7 +46,10 @@ module OpenFoodNetwork super end end - end + def sku + @variant_override.andand.sku || super + end + end end end diff --git a/spec/controllers/admin/variant_overrides_controller_spec.rb b/spec/controllers/admin/variant_overrides_controller_spec.rb new file mode 100644 index 0000000000..7e58e7fd42 --- /dev/null +++ b/spec/controllers/admin/variant_overrides_controller_spec.rb @@ -0,0 +1,57 @@ +require 'spec_helper' + +describe Admin::VariantOverridesController, type: :controller do + # include AuthenticationWorkflow + + describe "bulk_update" do + context "json" do + let(:format) { :json } + + let(:hub) { create(:distributor_enterprise) } + let(:variant) { create(:variant) } + let!(:variant_override) { create(:variant_override, hub: hub, variant: variant) } + let(:variant_override_params) { [ { id: variant_override.id, price: 123.45, count_on_hand: 321, sku: "MySKU", on_demand: false } ] } + + context "where I don't manage the variant override hub" do + before do + user = create(:user) + user.owned_enterprises << create(:enterprise) + controller.stub spree_current_user: user + end + + it "redirects to unauthorized" do + spree_put :bulk_update, format: format, variant_overrides: variant_override_params + expect(response).to redirect_to spree.unauthorized_path + end + end + + context "where I manage the variant override hub" do + before do + controller.stub spree_current_user: hub.owner + end + + context "but the producer has not granted VO permission" do + it "redirects to unauthorized" do + spree_put :bulk_update, format: format, variant_overrides: variant_override_params + expect(response).to redirect_to spree.unauthorized_path + end + end + + context "and the producer has granted VO permission" do + before do + create(:enterprise_relationship, parent: variant.product.supplier, child: hub, permissions_list: [:create_variant_overrides]) + end + + it "allows me to update the variant override" do + spree_put :bulk_update, format: format, variant_overrides: variant_override_params + variant_override.reload + expect(variant_override.price).to eq 123.45 + expect(variant_override.count_on_hand).to eq 321 + expect(variant_override.sku).to eq "MySKU" + expect(variant_override.on_demand).to eq false + end + end + end + end + end +end diff --git a/spec/lib/open_food_network/scope_variant_to_hub_spec.rb b/spec/lib/open_food_network/scope_variant_to_hub_spec.rb index 2a249f9c7a..82b24c7e02 100644 --- a/spec/lib/open_food_network/scope_variant_to_hub_spec.rb +++ b/spec/lib/open_food_network/scope_variant_to_hub_spec.rb @@ -3,8 +3,8 @@ require 'open_food_network/scope_variant_to_hub' module OpenFoodNetwork describe ScopeVariantToHub do let(:hub) { create(:distributor_enterprise) } - let(:v) { create(:variant, price: 11.11, count_on_hand: 1) } - let(:vo) { create(:variant_override, hub: hub, variant: v, price: 22.22, count_on_hand: 2) } + let(:v) { create(:variant, price: 11.11, count_on_hand: 1, on_demand: true, sku: "VARIANTSKU") } + let(:vo) { create(:variant_override, hub: hub, variant: v, price: 22.22, count_on_hand: 2, on_demand: false, sku: "VOSKU") } let(:vo_price_only) { create(:variant_override, hub: hub, variant: v, price: 22.22, count_on_hand: nil) } let(:scoper) { ScopeVariantToHub.new(hub) } @@ -66,6 +66,75 @@ module OpenFoodNetwork v.on_demand.should be_true end end + + describe "overriding on_demand" do + context "when an override exists" do + before { vo } + + context "with an on_demand set" do + it "returns the overridden on_demand" do + scoper.scope v + expect(v.on_demand).to be_false + end + end + + context "without an on_demand set" do + before { vo.update_column(:on_demand, nil) } + + context "when count_on_hand is set" do + it "returns false" do + scoper.scope v + expect(v.on_demand).to be_false + end + end + + context "when count_on_hand is not set" do + before { vo.update_column(:count_on_hand, nil) } + + it "returns the variant's on_demand" do + scoper.scope v + expect(v.on_demand).to be_true + end + end + end + end + + context "when no override exists" do + it "returns the variant's on_demand" do + scoper.scope v + expect(v.on_demand).to be_true + end + end + end + + describe "overriding sku" do + context "when an override exists" do + before { vo } + + context "with an sku set" do + it "returns the overridden sku" do + scoper.scope v + expect(v.sku).to eq "VOSKU" + end + end + + context "without an sku set" do + before { vo.update_column(:sku, nil) } + + it "returns the variant's sku" do + scoper.scope v + expect(v.sku).to eq "VARIANTSKU" + end + end + end + + context "when no override exists" do + it "returns the variant's sku" do + scoper.scope v + expect(v.sku).to eq "VARIANTSKU" + end + end + end end end end From 4553bc299732bb4aca6e0347e0ad1e53792faeba Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 18 Dec 2015 11:29:06 +1100 Subject: [PATCH 14/43] Moving SaveBar directive and StatusMessage service into admin.utils module --- .../services/status_message.js.coffee | 30 ------------------- .../admin/line_items/line_items.js.coffee | 2 +- .../directives/save_bar.js.coffee | 2 +- .../utils/services/status_message.js.coffee | 4 +++ .../variant_overrides.js.coffee | 2 +- .../templates/admin/save_bar.html.haml | 2 +- 6 files changed, 8 insertions(+), 34 deletions(-) delete mode 100644 app/assets/javascripts/admin/index_utils/services/status_message.js.coffee rename app/assets/javascripts/admin/{index_utils => utils}/directives/save_bar.js.coffee (68%) diff --git a/app/assets/javascripts/admin/index_utils/services/status_message.js.coffee b/app/assets/javascripts/admin/index_utils/services/status_message.js.coffee deleted file mode 100644 index 5dd9fb7258..0000000000 --- a/app/assets/javascripts/admin/index_utils/services/status_message.js.coffee +++ /dev/null @@ -1,30 +0,0 @@ -angular.module("admin.indexUtils").factory "StatusMessage", ($timeout) -> - new class StatusMessage - types: - progress: {timeout: false, style: {color: '#ff9906'}} - alert: {timeout: 5000, style: {color: 'grey'}} - notice: {timeout: false, style: {color: 'grey'}} - success: {timeout: 5000, style: {color: '#9fc820'}} - failure: {timeout: false, style: {color: '#da5354'}} - - statusMessage: - text: "" - style: {} - - active: -> - @statusMessage.text != '' - - display: (type, text) -> - @statusMessage.text = text - @statusMessage.style = @types[type].style - $timeout.cancel @statusMessage.timeout if @statusMessage.timeout - timeout = @types[type].timeout - if timeout - @statusMessage.timeout = $timeout => - @clear() - , timeout, true - null # So we don't return weird timeouts - - clear: -> - @statusMessage.text = '' - @statusMessage.style = {} diff --git a/app/assets/javascripts/admin/line_items/line_items.js.coffee b/app/assets/javascripts/admin/line_items/line_items.js.coffee index a3328c572e..8128a50e8a 100644 --- a/app/assets/javascripts/admin/line_items/line_items.js.coffee +++ b/app/assets/javascripts/admin/line_items/line_items.js.coffee @@ -1 +1 @@ -angular.module("admin.lineItems", ["admin.indexUtils", "admin.products", "admin.orders", "admin.enterprises", "admin.orderCycles"]) +angular.module("admin.lineItems", ["admin.indexUtils", "admin.utils", "admin.products", "admin.orders", "admin.enterprises", "admin.orderCycles"]) diff --git a/app/assets/javascripts/admin/index_utils/directives/save_bar.js.coffee b/app/assets/javascripts/admin/utils/directives/save_bar.js.coffee similarity index 68% rename from app/assets/javascripts/admin/index_utils/directives/save_bar.js.coffee rename to app/assets/javascripts/admin/utils/directives/save_bar.js.coffee index 0b30499d1d..13e4f84bc6 100644 --- a/app/assets/javascripts/admin/index_utils/directives/save_bar.js.coffee +++ b/app/assets/javascripts/admin/utils/directives/save_bar.js.coffee @@ -1,4 +1,4 @@ -angular.module("admin.indexUtils").directive "saveBar", (StatusMessage) -> +angular.module("admin.utils").directive "saveBar", (StatusMessage) -> restrict: "E" scope: save: "&" diff --git a/app/assets/javascripts/admin/utils/services/status_message.js.coffee b/app/assets/javascripts/admin/utils/services/status_message.js.coffee index d317269ca4..6aac046a7f 100644 --- a/app/assets/javascripts/admin/utils/services/status_message.js.coffee +++ b/app/assets/javascripts/admin/utils/services/status_message.js.coffee @@ -11,6 +11,9 @@ angular.module("admin.utils").factory "StatusMessage", ($timeout) -> text: "" style: {} + active: -> + @statusMessage.text != '' + display: (type, text) -> @statusMessage.text = text @statusMessage.style = @types[type].style @@ -20,6 +23,7 @@ angular.module("admin.utils").factory "StatusMessage", ($timeout) -> @statusMessage.timeout = $timeout => @clear() , timeout, true + null # So we don't return weird timeouts clear: -> @statusMessage.text = '' diff --git a/app/assets/javascripts/admin/variant_overrides/variant_overrides.js.coffee b/app/assets/javascripts/admin/variant_overrides/variant_overrides.js.coffee index bddef7cf6f..ae46cd14c7 100644 --- a/app/assets/javascripts/admin/variant_overrides/variant_overrides.js.coffee +++ b/app/assets/javascripts/admin/variant_overrides/variant_overrides.js.coffee @@ -1 +1 @@ -angular.module("admin.variantOverrides", ["admin.indexUtils", "pasvaz.bindonce", "admin.dropdown"]) +angular.module("admin.variantOverrides", ["pasvaz.bindonce", "admin.indexUtils", "admin.utils", "admin.dropdown"]) diff --git a/app/assets/javascripts/templates/admin/save_bar.html.haml b/app/assets/javascripts/templates/admin/save_bar.html.haml index 618402cf2b..452e81f6e3 100644 --- a/app/assets/javascripts/templates/admin/save_bar.html.haml +++ b/app/assets/javascripts/templates/admin/save_bar.html.haml @@ -1,6 +1,6 @@ #save-bar.animate-show{ ng: { show: 'form.$dirty || StatusMessage.active()' } } .twelve.columns.alpha - %h5#status-messae{ ng: { style: 'StatusMessage.statusMessage.style' } } + %h5#status-message{ ng: { style: 'StatusMessage.statusMessage.style' } } {{ StatusMessage.statusMessage.text || " " }} .four.columns.omega.text-right %input.red{type: "button", value: "Save Changes", ng: { disabled: '!form.$dirty', click: "save()" } } From 64cd52e067e20df8e01e7af419c9f9c5759c37c2 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 18 Dec 2015 12:05:06 +1100 Subject: [PATCH 15/43] Adding SKU and on demand to a few VO specs --- .../_products_variants.html.haml | 2 +- .../variant_overrides_controller_spec.rb | 9 ++++++ spec/features/admin/variant_overrides_spec.rb | 29 ++++++++++++------- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/app/views/admin/variant_overrides/_products_variants.html.haml b/app/views/admin/variant_overrides/_products_variants.html.haml index 687197f09a..f1357841ed 100644 --- a/app/views/admin/variant_overrides/_products_variants.html.haml +++ b/app/views/admin/variant_overrides/_products_variants.html.haml @@ -8,6 +8,6 @@ %td.price{ ng: { show: 'columns.price.visible' } } %input{name: 'variant-overrides-{{ variant.id }}-price', type: 'text', ng: {model: 'variantOverrides[hub.id][variant.id].price'}, placeholder: '{{ variant.price }}', 'ofn-track-variant-override' => 'price'} %td.on_hand{ ng: { show: 'columns.on_hand.visible' } } - %input{name: 'variant-overrides-{{ variant.id }}-count-on-hand', type: 'text', ng: {model: 'variantOverrides[hub.id][variant.id].count_on_hand'}, placeholder: '{{ variant.on_hand }}', 'ofn-track-variant-override' => 'price'} + %input{name: 'variant-overrides-{{ variant.id }}-count_on_hand', type: 'text', ng: {model: 'variantOverrides[hub.id][variant.id].count_on_hand'}, placeholder: '{{ variant.on_hand }}', 'ofn-track-variant-override' => 'price'} %td.on_demand{ ng: { show: 'columns.on_demand.visible' } } %input.field{ :type => 'checkbox', name: 'variant-overrides-{{ variant.id }}-on_demand', ng: { model: 'variantOverrides[hub.id][variant.id].on_demand' }, 'ofn-track-variant-override' => 'on_demand' } diff --git a/spec/controllers/admin/variant_overrides_controller_spec.rb b/spec/controllers/admin/variant_overrides_controller_spec.rb index 7e58e7fd42..019de4cb61 100644 --- a/spec/controllers/admin/variant_overrides_controller_spec.rb +++ b/spec/controllers/admin/variant_overrides_controller_spec.rb @@ -50,6 +50,15 @@ describe Admin::VariantOverridesController, type: :controller do expect(variant_override.sku).to eq "MySKU" expect(variant_override.on_demand).to eq false end + + context "where params for a variant override are blank" do + let(:variant_override_params) { [ { id: variant_override.id, price: "", count_on_hand: "", sku: nil, on_demand: nil } ] } + + it "destroys the variant override" do + spree_put :bulk_update, format: format, variant_overrides: variant_override_params + expect(VariantOverride.find_by_id(variant_override.id)).to be_nil + end + end end end end diff --git a/spec/features/admin/variant_overrides_spec.rb b/spec/features/admin/variant_overrides_spec.rb index c49e95c4ef..668e67d574 100644 --- a/spec/features/admin/variant_overrides_spec.rb +++ b/spec/features/admin/variant_overrides_spec.rb @@ -58,11 +58,11 @@ feature %q{ page.should have_table_row [producer.name, product.name, '', ''] page.should have_input "variant-overrides-#{variant.id}-price", placeholder: '1.23' - page.should have_input "variant-overrides-#{variant.id}-count-on-hand", placeholder: '12' + page.should have_input "variant-overrides-#{variant.id}-count_on_hand", placeholder: '12' page.should have_table_row [producer_related.name, product_related.name, '', ''] page.should have_input "variant-overrides-#{variant_related.id}-price", placeholder: '2.34' - page.should have_input "variant-overrides-#{variant_related.id}-count-on-hand", placeholder: '23' + page.should have_input "variant-overrides-#{variant_related.id}-count_on_hand", placeholder: '23' # filters the products to those the hub can override page.should_not have_content producer_unrelated.name @@ -97,8 +97,15 @@ feature %q{ end it "creates new overrides" do + first("div#columns-dropdown", :text => "COLUMNS").click + first("div#columns-dropdown div.menu div.menu_item", text: "SKU").click + first("div#columns-dropdown div.menu div.menu_item", text: "On Demand").click + first("div#columns-dropdown", :text => "COLUMNS").click + + fill_in "variant-overrides-#{variant.id}-sku", with: 'NEWSKU' fill_in "variant-overrides-#{variant.id}-price", with: '777.77' - fill_in "variant-overrides-#{variant.id}-count-on-hand", with: '123' + fill_in "variant-overrides-#{variant.id}-count_on_hand", with: '123' + check "variant-overrides-#{variant.id}-on_demand" page.should have_content "Changes to one override remain unsaved." expect do @@ -109,15 +116,17 @@ feature %q{ vo = VariantOverride.last vo.variant_id.should == variant.id vo.hub_id.should == hub.id + vo.sku.should == "NEWSKU" vo.price.should == 777.77 vo.count_on_hand.should == 123 + vo.on_demand.should == true end describe "creating and then updating the new override" do it "updates the same override instead of creating a duplicate" do # When I create a new override fill_in "variant-overrides-#{variant.id}-price", with: '777.77' - fill_in "variant-overrides-#{variant.id}-count-on-hand", with: '123' + fill_in "variant-overrides-#{variant.id}-count_on_hand", with: '123' page.should have_content "Changes to one override remain unsaved." expect do @@ -127,7 +136,7 @@ feature %q{ # And I update its settings without reloading the page fill_in "variant-overrides-#{variant.id}-price", with: '111.11' - fill_in "variant-overrides-#{variant.id}-count-on-hand", with: '111' + fill_in "variant-overrides-#{variant.id}-count_on_hand", with: '111' page.should have_content "Changes to one override remain unsaved." # Then I shouldn't see a new override @@ -147,7 +156,7 @@ feature %q{ it "displays an error when unauthorised to access the page" do fill_in "variant-overrides-#{variant.id}-price", with: '777.77' - fill_in "variant-overrides-#{variant.id}-count-on-hand", with: '123' + fill_in "variant-overrides-#{variant.id}-count_on_hand", with: '123' page.should have_content "Changes to one override remain unsaved." user.enterprises.clear @@ -160,7 +169,7 @@ feature %q{ it "displays an error when unauthorised to update a particular override" do fill_in "variant-overrides-#{variant_related.id}-price", with: '777.77' - fill_in "variant-overrides-#{variant_related.id}-count-on-hand", with: '123' + fill_in "variant-overrides-#{variant_related.id}-count_on_hand", with: '123' page.should have_content "Changes to one override remain unsaved." er2.destroy @@ -183,12 +192,12 @@ feature %q{ it "product values are affected by overrides" do page.should have_input "variant-overrides-#{variant.id}-price", with: '77.77', placeholder: '1.23' - page.should have_input "variant-overrides-#{variant.id}-count-on-hand", with: '11111', placeholder: '12' + page.should have_input "variant-overrides-#{variant.id}-count_on_hand", with: '11111', placeholder: '12' end it "updates existing overrides" do fill_in "variant-overrides-#{variant.id}-price", with: '22.22' - fill_in "variant-overrides-#{variant.id}-count-on-hand", with: '8888' + fill_in "variant-overrides-#{variant.id}-count_on_hand", with: '8888' page.should have_content "Changes to one override remain unsaved." expect do @@ -205,7 +214,7 @@ feature %q{ it "deletes overrides when values are cleared" do fill_in "variant-overrides-#{variant.id}-price", with: '' - fill_in "variant-overrides-#{variant.id}-count-on-hand", with: '' + fill_in "variant-overrides-#{variant.id}-count_on_hand", with: '' page.should have_content "Changes to one override remain unsaved." expect do From cc4dc068ab209362d954d5510a23d2313e8cf139 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Fri, 18 Dec 2015 13:47:17 +1100 Subject: [PATCH 16/43] Adding variant SKU field to BPE --- .../javascripts/admin/bulk_product_update.js.coffee | 3 +++ .../admin/products/bulk_edit/_products_variant.html.haml | 1 + spec/features/admin/bulk_product_update_spec.rb | 8 ++++++++ 3 files changed, 12 insertions(+) diff --git a/app/assets/javascripts/admin/bulk_product_update.js.coffee b/app/assets/javascripts/admin/bulk_product_update.js.coffee index b3d24f00c0..6c85a4fd54 100644 --- a/app/assets/javascripts/admin/bulk_product_update.js.coffee +++ b/app/assets/javascripts/admin/bulk_product_update.js.coffee @@ -352,6 +352,9 @@ filterSubmitVariant = (variant) -> filteredVariant = {} if not variant.deleted_at? and variant.hasOwnProperty("id") filteredVariant.id = variant.id unless variant.id <= 0 + if variant.hasOwnProperty("sku") + filteredVariant.sku = variant.sku + hasUpdatableProperty = true if variant.hasOwnProperty("on_hand") filteredVariant.on_hand = variant.on_hand hasUpdatableProperty = true diff --git a/app/views/spree/admin/products/bulk_edit/_products_variant.html.haml b/app/views/spree/admin/products/bulk_edit/_products_variant.html.haml index cc85566577..ff345cb259 100644 --- a/app/views/spree/admin/products/bulk_edit/_products_variant.html.haml +++ b/app/views/spree/admin/products/bulk_edit/_products_variant.html.haml @@ -4,6 +4,7 @@ %a{ :class => "add-variant icon-plus-sign", 'ng-click' => "addVariant(product)", 'ng-show' => "$last" } %td{ 'ng-show' => 'columns.producer.visible' } %td{ 'ng-show' => 'columns.sku.visible' } + %input{ 'ng-model' => "variant.sku", :name => 'variant_sku', 'ofn-track-variant' => 'sku', :type => 'text' } %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/spec/features/admin/bulk_product_update_spec.rb b/spec/features/admin/bulk_product_update_spec.rb index 1a2c715e34..9dabf93028 100644 --- a/spec/features/admin/bulk_product_update_spec.rb +++ b/spec/features/admin/bulk_product_update_spec.rb @@ -308,6 +308,7 @@ feature %q{ p = FactoryGirl.create(:product, supplier: s1, available_on: Date.current, variant_unit: 'volume', variant_unit_scale: 0.001, price: 3.0, on_hand: 9, unit_value: 0.25, unit_description: '(bottle)' ) v = p.variants.first + v.update_column(:sku, "VARIANTSKU") login_to_admin_section @@ -315,12 +316,18 @@ feature %q{ expect(page).to have_selector "a.view-variants" first("a.view-variants").trigger('click') + first("div#columns-dropdown", :text => "COLUMNS").click + first("div#columns-dropdown div.menu div.menu_item", text: "SKU").click + first("div#columns-dropdown", :text => "COLUMNS").click + + expect(page).to have_field "variant_sku", with: "VARIANTSKU" expect(page).to have_field "variant_price", with: "3.0" expect(page).to have_field "variant_unit_value_with_description", with: "250 (bottle)" expect(page).to have_field "variant_on_hand", with: "9" expect(page).to have_selector "span[name='on_hand']", "9" select "Volume (L)", from: "variant_unit_with_scale" + fill_in "variant_sku", with: "NEWSKU" fill_in "variant_price", with: "4.0" fill_in "variant_on_hand", with: "10" fill_in "variant_unit_value_with_description", with: "2 (8x250 mL bottles)" @@ -331,6 +338,7 @@ feature %q{ expect(page.find("#status-message")).to have_content "Changes saved." v.reload + expect(v.sku).to eq "NEWSKU" expect(v.price).to eq 4.0 expect(v.on_hand).to eq 10 expect(v.unit_value).to eq 2 # 2L in L From 14c868353585789adf3ff5c2103f8abf4bc03c83 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Wed, 13 Jan 2016 18:58:38 +1100 Subject: [PATCH 17/43] Updating active_model_serializers --- Gemfile | 2 +- Gemfile.lock | 7 ++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/Gemfile b/Gemfile index 8230c6a15f..ca4773110d 100644 --- a/Gemfile +++ b/Gemfile @@ -39,7 +39,7 @@ gem 'andand' gem 'truncate_html' gem 'representative_view' gem 'rabl' -gem "active_model_serializers" +gem "active_model_serializers", '~> 0.8.3' gem 'oj' gem 'deface', :github => 'spree/deface', :ref => '1110a13' gem 'paperclip' diff --git a/Gemfile.lock b/Gemfile.lock index 16a319f0ab..1477aedf92 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -122,7 +122,7 @@ GEM rack-test (~> 0.6.1) sprockets (~> 2.2.1) active_link_to (1.0.0) - active_model_serializers (0.8.1) + active_model_serializers (0.8.3) activemodel (>= 3.0) activemerchant (1.48.0) activesupport (>= 3.2.14, < 5.0.0) @@ -644,7 +644,7 @@ PLATFORMS ruby DEPENDENCIES - active_model_serializers + active_model_serializers (~> 0.8.3) acts-as-taggable-on (~> 3.4) andand angular-rails-templates (~> 0.2.0) @@ -730,6 +730,3 @@ DEPENDENCIES whenever wicked_pdf wkhtmltopdf-binary - -BUNDLED WITH - 1.10.6 From 3b7700131c422fcbfcf90f070dc3b0640c6685f1 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Wed, 13 Jan 2016 19:00:25 +1100 Subject: [PATCH 18/43] Specify controller specs as such --- spec/controllers/api/enterprises_controller_spec.rb | 2 +- spec/controllers/api/order_cycles_controller_spec.rb | 2 +- spec/controllers/base_controller_spec.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/controllers/api/enterprises_controller_spec.rb b/spec/controllers/api/enterprises_controller_spec.rb index 77e16368d9..0e8f2ef606 100644 --- a/spec/controllers/api/enterprises_controller_spec.rb +++ b/spec/controllers/api/enterprises_controller_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' module Api - describe EnterprisesController do + describe EnterprisesController, :type => :controller do include AuthenticationWorkflow render_views diff --git a/spec/controllers/api/order_cycles_controller_spec.rb b/spec/controllers/api/order_cycles_controller_spec.rb index 3bb9a76602..a9a86608e7 100644 --- a/spec/controllers/api/order_cycles_controller_spec.rb +++ b/spec/controllers/api/order_cycles_controller_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' require 'spree/api/testing_support/helpers' module Api - describe OrderCyclesController do + describe OrderCyclesController, :type => :controller do include Spree::Api::TestingSupport::Helpers include AuthenticationWorkflow render_views diff --git a/spec/controllers/base_controller_spec.rb b/spec/controllers/base_controller_spec.rb index b5ef006c5b..4ea2e31ff2 100644 --- a/spec/controllers/base_controller_spec.rb +++ b/spec/controllers/base_controller_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe BaseController do +describe BaseController, :type => :controller do let(:oc) { mock_model(OrderCycle) } let(:hub) { mock_model(Enterprise, ready_for_checkout?: true) } let(:order) { mock_model(Spree::Order, distributor: hub) } From 53d97dab085a580120983ac7eeb841e865061368 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Wed, 13 Jan 2016 19:20:18 +1100 Subject: [PATCH 19/43] WIP: Adding view and routes for resetting variant_overrides count_on_hand --- .../variant_overrides_controller.js.coffee | 16 ++++++----- .../services/variant_overrides.js.coffee | 8 ++++++ .../admin/variant_overrides_controller.rb | 16 +++++++++++ app/models/variant_override.rb | 17 +++++++++++- .../variant_overrides/_actions.html.haml | 1 + .../variant_overrides/_products.html.haml | 1 + .../_products_product.html.haml | 1 + .../_products_variants.html.haml | 5 ++++ config/routes.rb | 1 + db/schema.rb | 1 + spec/models/variant_override_spec.rb | 27 +++++++++++++++++++ 11 files changed, 87 insertions(+), 7 deletions(-) diff --git a/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee b/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee index f4c819f14a..8aed964949 100644 --- a/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee +++ b/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee @@ -9,12 +9,13 @@ angular.module("admin.variantOverrides").controller "AdminVariantOverridesCtrl", $scope.StatusMessage = StatusMessage $scope.columns = Columns.setColumns - producer: { name: "Producer", visible: true } - product: { name: "Product", visible: true } - sku: { name: "SKU", visible: false } - price: { name: "Price", visible: true } - on_hand: { name: "On Hand", visible: true } - on_demand: { name: "On Demand", visible: false } + producer: { name: "Producer", visible: true } + product: { name: "Product", visible: true } + sku: { name: "SKU", visible: false } + price: { name: "Price", visible: true } + on_hand: { name: "On Hand", visible: true } + on_demand: { name: "On Demand", visible: false } + reset: { name: "Reset Stock Level", visible: false } $scope.resetSelectFilters = -> $scope.producerFilter = 0 @@ -79,3 +80,6 @@ angular.module("admin.variantOverrides").controller "AdminVariantOverridesCtrl", else "Oh no! I was unable to save your changes." + + $scope.resetStock = -> + variantOverrides.resetStock() diff --git a/app/assets/javascripts/admin/variant_overrides/services/variant_overrides.js.coffee b/app/assets/javascripts/admin/variant_overrides/services/variant_overrides.js.coffee index 524dc9056a..a3573a3cde 100644 --- a/app/assets/javascripts/admin/variant_overrides/services/variant_overrides.js.coffee +++ b/app/assets/javascripts/admin/variant_overrides/services/variant_overrides.js.coffee @@ -19,7 +19,15 @@ angular.module("admin.variantOverrides").factory "VariantOverrides", (variantOve price: null count_on_hand: null on_demand: null + default_stock: null updateIds: (updatedVos) -> for vo in updatedVos @variantOverrides[vo.hub_id][vo.variant_id].id = vo.id + + resetStock: -> + $http + method: "POST" + url: "/admin/variant_overrides/bulk_reset" + data: + variant_overrides: @all() diff --git a/app/controllers/admin/variant_overrides_controller.rb b/app/controllers/admin/variant_overrides_controller.rb index 9425565f6e..f45661f048 100644 --- a/app/controllers/admin/variant_overrides_controller.rb +++ b/app/controllers/admin/variant_overrides_controller.rb @@ -30,6 +30,22 @@ module Admin end end + def bulk_reset + collection_hash = Hash[params[:variant_overrides].each_with_index.map { |vo, i| [i, vo] }] + vo_set = VariantOverrideSet.new @variant_overrides, collection_attributes: collection_hash + + # Ensure we're authorised to update all variant overrides + vo_set.collection.each { |vo| authorize! :update, vo } + + vo.set.collection.each { |vo| vo.reset_stock! } + if vo_set.errors.present? + render json: { errors: vo_set.errors }, status: 400 + else + # Return saved VOs with IDs + render json: vo_set.collection, each_serializer: Api::Admin::VariantOverrideSerializer + end + end + private diff --git a/app/models/variant_override.rb b/app/models/variant_override.rb index 55afd99321..f983f9b818 100644 --- a/app/models/variant_override.rb +++ b/app/models/variant_override.rb @@ -3,6 +3,8 @@ class VariantOverride < ActiveRecord::Base belongs_to :variant, class_name: 'Spree::Variant' validates_presence_of :hub_id, :variant_id + # Default stock can be nil, indicating stock should not be reset or zero, meaning reset to zero. Need to ensure this can be set by the user. + validates :default_stock, numericality: { greater_than: 0 }, allow_nil: true scope :for_hubs, lambda { |hubs| where(hub_id: hubs) @@ -48,7 +50,20 @@ class VariantOverride < ActiveRecord::Base Bugsnag.notify RuntimeError.new "Attempting to decrement stock level on a VariantOverride without a count_on_hand specified." end end - + + def default_stock? + default_stock.present? + end + + def reset_stock! + if default_stock? + update_attributes :count_on_hand => default_stock + else + # Could remove as not resetting where there is no default is intended behaviour + Bugsnag.notify RuntimeError.new "Attempting to reset stock for a VariantOverride where a default level is not present" + end + + end private diff --git a/app/views/admin/variant_overrides/_actions.html.haml b/app/views/admin/variant_overrides/_actions.html.haml index 0ae6f8b96b..39e4cd9baa 100644 --- a/app/views/admin/variant_overrides/_actions.html.haml +++ b/app/views/admin/variant_overrides/_actions.html.haml @@ -1,4 +1,5 @@ .row %input.four.columns.alpha{type: 'button', value: 'Save Changes', 'ng-click' => 'update()'} + %input.four.columns.alpha{type: 'button', value: 'Reset Stock to Defaults', 'ng-click' => 'resetStock()'} .twelve.columns.omega = render 'spree/admin/shared/status_message' diff --git a/app/views/admin/variant_overrides/_products.html.haml b/app/views/admin/variant_overrides/_products.html.haml index f4b692c06b..f268c90130 100644 --- a/app/views/admin/variant_overrides/_products.html.haml +++ b/app/views/admin/variant_overrides/_products.html.haml @@ -7,6 +7,7 @@ %th.price{ ng: { show: 'columns.price.visible' } } Price %th.on_hand{ ng: { show: 'columns.on_hand.visible' } } On hand %th.on_demand{ ng: { show: 'columns.on_demand.visible' } } On Demand? + %th Default stock %tbody{bindonce: true, ng: {repeat: 'product in products | hubPermissions:hubPermissions:hub.id | attrFilter:{producer_id:producerFilter} | filter:query' } } = render 'admin/variant_overrides/products_product' = render 'admin/variant_overrides/products_variants' diff --git a/app/views/admin/variant_overrides/_products_product.html.haml b/app/views/admin/variant_overrides/_products_product.html.haml index 825be1a6f6..6f58c9bd75 100644 --- a/app/views/admin/variant_overrides/_products_product.html.haml +++ b/app/views/admin/variant_overrides/_products_product.html.haml @@ -5,3 +5,4 @@ %td.price{ ng: { show: 'columns.price.visible' } } %td.on_hand{ ng: { show: 'columns.on_hand.visible' } } %td.on_demand{ ng: { show: 'columns.on_demand.visible' } } + %td diff --git a/app/views/admin/variant_overrides/_products_variants.html.haml b/app/views/admin/variant_overrides/_products_variants.html.haml index f1357841ed..f14cebec93 100644 --- a/app/views/admin/variant_overrides/_products_variants.html.haml +++ b/app/views/admin/variant_overrides/_products_variants.html.haml @@ -11,3 +11,8 @@ %input{name: 'variant-overrides-{{ variant.id }}-count_on_hand', type: 'text', ng: {model: 'variantOverrides[hub.id][variant.id].count_on_hand'}, placeholder: '{{ variant.on_hand }}', 'ofn-track-variant-override' => 'price'} %td.on_demand{ ng: { show: 'columns.on_demand.visible' } } %input.field{ :type => 'checkbox', name: 'variant-overrides-{{ variant.id }}-on_demand', ng: { model: 'variantOverrides[hub.id][variant.id].on_demand' }, 'ofn-track-variant-override' => 'on_demand' } + %td + %input{name: 'variant-overrides-{{ variant.id }}-count-on-hand', type: 'text', ng: {model: 'variantOverrides[hub.id][variant.id].count_on_hand'}, placeholder: '{{ variant.on_hand }}', 'ofn-track-variant-override' => 'price'} + + %td + %input{name: 'variant-overrides-{{ variant.id }}-default-stock', type: 'text', ng: {model: 'variantOverrides[hub.id][variant.id].default_stock'}, placeholder: '{{ variant.default_stock }}', 'ofn-track-variant-override' => 'price'} diff --git a/config/routes.rb b/config/routes.rb index c8771560e9..882dfec23d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -103,6 +103,7 @@ Openfoodnetwork::Application.routes.draw do resources :variant_overrides do post :bulk_update, on: :collection + post :bulk_reset, on: :collection end resources :customers, only: [:index, :update] diff --git a/db/schema.rb b/db/schema.rb index 91895e993d..9adf1c5391 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -1161,6 +1161,7 @@ ActiveRecord::Schema.define(:version => 20151126235409) do t.integer "count_on_hand" t.string "sku" t.boolean "on_demand" + t.integer "default_stock" end add_index "variant_overrides", ["variant_id", "hub_id"], :name => "index_variant_overrides_on_variant_id_and_hub_id" diff --git a/spec/models/variant_override_spec.rb b/spec/models/variant_override_spec.rb index e9f22a33be..2cd422e01d 100644 --- a/spec/models/variant_override_spec.rb +++ b/spec/models/variant_override_spec.rb @@ -81,4 +81,31 @@ describe VariantOverride do VariantOverride.decrement_stock! hub, variant, 2 end end + + describe "checking default stock value is present" do + it "returns true when a default stock level has been set" do + vo = create(:variant_override, variant: variant, hub: hub, count_on_hand: 12, default_stock: 20) + vo.default_stock?.should be_true + end + + it "returns false when the override has no default stock level" do + vo = create(:variant_override, variant: variant, hub: hub, count_on_hand: 12, default_stock:nil) + vo.default_stock.should be_false + end + end + + describe "resetting stock levels" do + it "resets the on hand level to the value in the default_stock field" do + vo = create(:variant_override, variant: variant, hub: hub, count_on_hand: 12, default_stock: 20) + vo.reset_stock! + vo.reload.count_on_hand.should == 20 + end + it "silently logs an error if the variant override doesn't have a default stock level" do + vo = create(:variant_override, variant: variant, hub: hub, count_on_hand: 12, default_stock:nil) + Bugsnag.should_receive(:notify) + vo.reset_stock! + vo.reload.count_on_hand.should == 12 + vo.reload.default_stock.should be_nil + end + end end From 6c0dd7e25f8fc778b961e3f496bfcd8d9efbfcc7 Mon Sep 17 00:00:00 2001 From: Steve Pettitt Date: Mon, 20 Jul 2015 08:12:25 +0100 Subject: [PATCH 20/43] Adding 'default_stock' to VariantOverride --- .../20150719111807_add_default_stock_to_variant_overrides.rb | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 db/migrate/20150719111807_add_default_stock_to_variant_overrides.rb diff --git a/db/migrate/20150719111807_add_default_stock_to_variant_overrides.rb b/db/migrate/20150719111807_add_default_stock_to_variant_overrides.rb new file mode 100644 index 0000000000..880a1b8349 --- /dev/null +++ b/db/migrate/20150719111807_add_default_stock_to_variant_overrides.rb @@ -0,0 +1,5 @@ +class AddDefaultStockToVariantOverrides < ActiveRecord::Migration + def change + add_column :variant_overrides, :default_stock, :integer + end +end From 34c603a9c335edaad3e90f7df03a9d3cef0b678b Mon Sep 17 00:00:00 2001 From: Steve Pettitt Date: Tue, 18 Aug 2015 21:35:00 +0100 Subject: [PATCH 21/43] Added angular service tests for variant overrides stock reset --- .../variant_overrides_controller.js.coffee | 6 +- .../services/variant_overrides.js.coffee | 8 +- .../admin/variant_overrides_controller.rb | 6 +- app/models/variant_override.rb | 18 +++-- .../api/admin/variant_override_serializer.rb | 2 +- .../_products_variants.html.haml | 4 +- .../services/variant_overrides_spec.js.coffee | 74 ++++++++++++------- 7 files changed, 76 insertions(+), 42 deletions(-) diff --git a/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee b/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee index 8aed964949..c2fab4e7c7 100644 --- a/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee +++ b/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee @@ -59,6 +59,7 @@ angular.module("admin.variantOverrides").controller "AdminVariantOverridesCtrl", StatusMessage.display 'progress', 'Saving...' DirtyVariantOverrides.save() .success (updatedVos) -> + console.log DirtyVariantOverrides.all() DirtyVariantOverrides.clear() VariantOverrides.updateIds updatedVos StatusMessage.display 'success', 'Changes saved.' @@ -82,4 +83,7 @@ angular.module("admin.variantOverrides").controller "AdminVariantOverridesCtrl", "Oh no! I was unable to save your changes." $scope.resetStock = -> - variantOverrides.resetStock() + VariantOverrides.resetStock() + .success (updatedVos) -> + VariantOverrides.updateData updatedVos + $timeout -> StatusMessage.display 'success', 'Stocks reset to defaults.' diff --git a/app/assets/javascripts/admin/variant_overrides/services/variant_overrides.js.coffee b/app/assets/javascripts/admin/variant_overrides/services/variant_overrides.js.coffee index a3573a3cde..559305b1a3 100644 --- a/app/assets/javascripts/admin/variant_overrides/services/variant_overrides.js.coffee +++ b/app/assets/javascripts/admin/variant_overrides/services/variant_overrides.js.coffee @@ -1,4 +1,4 @@ -angular.module("admin.variantOverrides").factory "VariantOverrides", (variantOverrides) -> +angular.module("admin.variantOverrides").factory "VariantOverrides", (variantOverrides, $http) -> new class VariantOverrides variantOverrides: {} @@ -30,4 +30,8 @@ angular.module("admin.variantOverrides").factory "VariantOverrides", (variantOve method: "POST" url: "/admin/variant_overrides/bulk_reset" data: - variant_overrides: @all() + variant_overrides: variantOverrides + + updateData: (updatedVos) -> + for vo in updatedVos + @variantOverrides[vo.hub_id][vo.variant_id] = vo diff --git a/app/controllers/admin/variant_overrides_controller.rb b/app/controllers/admin/variant_overrides_controller.rb index f45661f048..66e8d97baf 100644 --- a/app/controllers/admin/variant_overrides_controller.rb +++ b/app/controllers/admin/variant_overrides_controller.rb @@ -37,12 +37,10 @@ module Admin # Ensure we're authorised to update all variant overrides vo_set.collection.each { |vo| authorize! :update, vo } - vo.set.collection.each { |vo| vo.reset_stock! } + vo_set.collection.map! { |vo| vo = vo.reset_stock! } + render json: vo_set.collection, each_serializer: Api::Admin::VariantOverrideSerializer if vo_set.errors.present? render json: { errors: vo_set.errors }, status: 400 - else - # Return saved VOs with IDs - render json: vo_set.collection, each_serializer: Api::Admin::VariantOverrideSerializer end end diff --git a/app/models/variant_override.rb b/app/models/variant_override.rb index f983f9b818..c7d111fefc 100644 --- a/app/models/variant_override.rb +++ b/app/models/variant_override.rb @@ -57,12 +57,20 @@ class VariantOverride < ActiveRecord::Base def reset_stock! if default_stock? - update_attributes :count_on_hand => default_stock - else - # Could remove as not resetting where there is no default is intended behaviour - Bugsnag.notify RuntimeError.new "Attempting to reset stock for a VariantOverride where a default level is not present" + self.attributes = { count_on_hand: default_stock } + self.save + end + self + end + + def self.reset_stock!(hub, variant) + vo = self.for(hub, variant) + + if vo.nil? + Bugsnag.notify RuntimeError.new "Attempting to reset stock level for a variant without a VariantOverride." + else + vo.reset_stock! end - end private diff --git a/app/serializers/api/admin/variant_override_serializer.rb b/app/serializers/api/admin/variant_override_serializer.rb index d4f584d9ea..54b4419fb7 100644 --- a/app/serializers/api/admin/variant_override_serializer.rb +++ b/app/serializers/api/admin/variant_override_serializer.rb @@ -1,3 +1,3 @@ class Api::Admin::VariantOverrideSerializer < ActiveModel::Serializer - attributes :id, :hub_id, :variant_id, :sku, :price, :count_on_hand, :on_demand + attributes :id, :hub_id, :variant_id, :sku, :price, :count_on_hand, :on_demand, :default_stock end diff --git a/app/views/admin/variant_overrides/_products_variants.html.haml b/app/views/admin/variant_overrides/_products_variants.html.haml index f14cebec93..510689b83d 100644 --- a/app/views/admin/variant_overrides/_products_variants.html.haml +++ b/app/views/admin/variant_overrides/_products_variants.html.haml @@ -12,7 +12,7 @@ %td.on_demand{ ng: { show: 'columns.on_demand.visible' } } %input.field{ :type => 'checkbox', name: 'variant-overrides-{{ variant.id }}-on_demand', ng: { model: 'variantOverrides[hub.id][variant.id].on_demand' }, 'ofn-track-variant-override' => 'on_demand' } %td - %input{name: 'variant-overrides-{{ variant.id }}-count-on-hand', type: 'text', ng: {model: 'variantOverrides[hub.id][variant.id].count_on_hand'}, placeholder: '{{ variant.on_hand }}', 'ofn-track-variant-override' => 'price'} + %input{name: 'variant-overrides-{{ variant.id }}-count-on-hand', type: 'text', ng: {model: 'variantOverrides[hub.id][variant.id].count_on_hand'}, placeholder: '{{ variant.on_hand }}', 'ofn-track-variant-override' => 'count_on_hand'} %td - %input{name: 'variant-overrides-{{ variant.id }}-default-stock', type: 'text', ng: {model: 'variantOverrides[hub.id][variant.id].default_stock'}, placeholder: '{{ variant.default_stock }}', 'ofn-track-variant-override' => 'price'} + %input{name: 'variant-overrides-{{ variant.id }}-default-stock', type: 'text', ng: {model: 'variantOverrides[hub.id][variant.id].default_stock'}, placeholder: '{{ variant.default_stock }}', 'ofn-track-variant-override' => 'default_stock'} diff --git a/spec/javascripts/unit/admin/services/variant_overrides_spec.js.coffee b/spec/javascripts/unit/admin/services/variant_overrides_spec.js.coffee index b379dc5915..5ffd71cd64 100644 --- a/spec/javascripts/unit/admin/services/variant_overrides_spec.js.coffee +++ b/spec/javascripts/unit/admin/services/variant_overrides_spec.js.coffee @@ -1,9 +1,9 @@ describe "VariantOverrides service", -> - VariantOverrides = null + VariantOverrides = $httpBackend = null variantOverrides = [ - {id: 1, hub_id: 10, variant_id: 100, price: 1, count_on_hand: 1} - {id: 2, hub_id: 10, variant_id: 200, price: 2, count_on_hand: 2} - {id: 3, hub_id: 20, variant_id: 300, price: 3, count_on_hand: 3} + {id: 1, hub_id: 10, variant_id: 100, price: 1, count_on_hand: 1, default_stock: ''} + {id: 2, hub_id: 10, variant_id: 200, price: 2, count_on_hand: 2, default_stock: ''} + {id: 3, hub_id: 20, variant_id: 300, price: 3, count_on_hand: 3, default_stock: ''} ] beforeEach -> @@ -12,16 +12,17 @@ describe "VariantOverrides service", -> $provide.value "variantOverrides", variantOverrides null - beforeEach inject (_VariantOverrides_) -> + beforeEach inject (_VariantOverrides_, _$httpBackend_) -> VariantOverrides = _VariantOverrides_ + $httpBackend = _$httpBackend_ it "indexes variant overrides by hub_id -> variant_id", -> expect(VariantOverrides.variantOverrides).toEqual 10: - 100: {id: 1, hub_id: 10, variant_id: 100, price: 1, count_on_hand: 1} - 200: {id: 2, hub_id: 10, variant_id: 200, price: 2, count_on_hand: 2} + 100: {id: 1, hub_id: 10, variant_id: 100, price: 1, count_on_hand: 1, default_stock: ''} + 200: {id: 2, hub_id: 10, variant_id: 200, price: 2, count_on_hand: 2, default_stock: ''} 20: - 300: {id: 3, hub_id: 20, variant_id: 300, price: 3, count_on_hand: 3} + 300: {id: 3, hub_id: 20, variant_id: 300, price: 3, count_on_hand: 3, default_stock: ''} it "ensures blank data available for some products", -> hubs = [{id: 10}, {id: 20}, {id: 30}] @@ -34,35 +35,54 @@ describe "VariantOverrides service", -> VariantOverrides.ensureDataFor hubs, products expect(VariantOverrides.variantOverrides).toEqual 10: - 100: {id: 1, hub_id: 10, variant_id: 100, price: 1, count_on_hand: 1} - 200: {id: 2, hub_id: 10, variant_id: 200, price: 2, count_on_hand: 2} - 300: { hub_id: 10, variant_id: 300, price: '', count_on_hand: ''} - 400: { hub_id: 10, variant_id: 400, price: '', count_on_hand: ''} - 500: { hub_id: 10, variant_id: 500, price: '', count_on_hand: ''} + 100: {id: 1, hub_id: 10, variant_id: 100, price: 1, count_on_hand: 1, default_stock: ''} + 200: {id: 2, hub_id: 10, variant_id: 200, price: 2, count_on_hand: 2, default_stock: ''} + 300: { hub_id: 10, variant_id: 300, price: '', count_on_hand: '', default_stock: ''} + 400: { hub_id: 10, variant_id: 400, price: '', count_on_hand: '', default_stock: ''} + 500: { hub_id: 10, variant_id: 500, price: '', count_on_hand: '', default_stock: ''} 20: - 100: { hub_id: 20, variant_id: 100, price: '', count_on_hand: ''} - 200: { hub_id: 20, variant_id: 200, price: '', count_on_hand: ''} - 300: {id: 3, hub_id: 20, variant_id: 300, price: 3, count_on_hand: 3} - 400: { hub_id: 20, variant_id: 400, price: '', count_on_hand: ''} - 500: { hub_id: 20, variant_id: 500, price: '', count_on_hand: ''} + 100: { hub_id: 20, variant_id: 100, price: '', count_on_hand: '', default_stock: ''} + 200: { hub_id: 20, variant_id: 200, price: '', count_on_hand: '', default_stock: ''} + 300: {id: 3, hub_id: 20, variant_id: 300, price: 3, count_on_hand: 3, default_stock: ''} + 400: { hub_id: 20, variant_id: 400, price: '', count_on_hand: '', default_stock: ''} + 500: { hub_id: 20, variant_id: 500, price: '', count_on_hand: '', default_stock: ''} 30: - 100: { hub_id: 30, variant_id: 100, price: '', count_on_hand: ''} - 200: { hub_id: 30, variant_id: 200, price: '', count_on_hand: ''} - 300: { hub_id: 30, variant_id: 300, price: '', count_on_hand: ''} - 400: { hub_id: 30, variant_id: 400, price: '', count_on_hand: ''} - 500: { hub_id: 30, variant_id: 500, price: '', count_on_hand: ''} + 100: { hub_id: 30, variant_id: 100, price: '', count_on_hand: '', default_stock: ''} + 200: { hub_id: 30, variant_id: 200, price: '', count_on_hand: '', default_stock: ''} + 300: { hub_id: 30, variant_id: 300, price: '', count_on_hand: '', default_stock: ''} + 400: { hub_id: 30, variant_id: 400, price: '', count_on_hand: '', default_stock: ''} + 500: { hub_id: 30, variant_id: 500, price: '', count_on_hand: '', default_stock: ''} it "updates the IDs of variant overrides", -> VariantOverrides.variantOverrides[2] = {} - VariantOverrides.variantOverrides[2][3] = {hub_id: 2, variant_id: 3, price: "4.0", count_on_hand: 5} - VariantOverrides.variantOverrides[2][8] = {hub_id: 2, variant_id: 8, price: "9.0", count_on_hand: 10} + VariantOverrides.variantOverrides[2][3] = {hub_id: 2, variant_id: 3, price: "4.0", count_on_hand: 5, default_stock: ''} + VariantOverrides.variantOverrides[2][8] = {hub_id: 2, variant_id: 8, price: "9.0", count_on_hand: 10, default_stock: ''} updatedVos = [ - {id: 1, hub_id: 2, variant_id: 3, price: "4.0", count_on_hand: 5} - {id: 6, hub_id: 2, variant_id: 8, price: "9.0", count_on_hand: 10} + {id: 1, hub_id: 2, variant_id: 3, price: "4.0", count_on_hand: 5, default_stock: ''} + {id: 6, hub_id: 2, variant_id: 8, price: "9.0", count_on_hand: 10, default_stock: ''} ] VariantOverrides.updateIds updatedVos expect(VariantOverrides.variantOverrides[2][3].id).toEqual 1 expect(VariantOverrides.variantOverrides[2][8].id).toEqual 6 + + it "sends an HTTP request to reset stock", -> + $httpBackend.expectPOST("/admin/variant_overrides/bulk_reset", variant_overrides: variantOverrides).respond 200 + VariantOverrides.resetStock variantOverrides + $httpBackend.flush() + + it "updates the variant overrides on the page with new data", -> + VariantOverrides.variantOverrides[1] = + 3: {id: 1, hub_id: 1, variant_id: 3, price: "4.0", count_on_hand: 5, default_stock: 3} + 8: {id: 2, hub_id: 1, variant_id: 8, price: "9.0", count_on_hand: 10, default_stock: ''} + # Updated count on hand to 3 + updatedVos = [ + {id: 1, hub_id: 1, variant_id: 3, price: "4.0", count_on_hand: 3, default_stock: 3} + ] + + VariantOverrides.updateData(updatedVos) + expect(VariantOverrides.variantOverrides[1]).toEqual + 3: {id: 1, hub_id: 1, variant_id: 3, price: "4.0", count_on_hand: 3, default_stock: 3} + 8: {id: 2, hub_id: 1, variant_id: 8, price: "9.0", count_on_hand: 10, default_stock: ''} From 2921958788ee714f0df6cacbdb53f5afdfc2a99b Mon Sep 17 00:00:00 2001 From: Steve Pettitt Date: Sat, 22 Aug 2015 16:13:49 +0100 Subject: [PATCH 22/43] Variant override controller spec added --- .../admin/variant_overrides_controller.rb | 1 - .../admin/variant_overrides_spec.rb | 51 +++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 spec/controllers/admin/variant_overrides_spec.rb diff --git a/app/controllers/admin/variant_overrides_controller.rb b/app/controllers/admin/variant_overrides_controller.rb index 66e8d97baf..9edf82a82a 100644 --- a/app/controllers/admin/variant_overrides_controller.rb +++ b/app/controllers/admin/variant_overrides_controller.rb @@ -14,7 +14,6 @@ module Admin def bulk_update collection_hash = Hash[params[:variant_overrides].each_with_index.map { |vo, i| [i, vo] }] vo_set = VariantOverrideSet.new @variant_overrides, collection_attributes: collection_hash - # Ensure we're authorised to update all variant overrides vo_set.collection.each { |vo| authorize! :update, vo } diff --git a/spec/controllers/admin/variant_overrides_spec.rb b/spec/controllers/admin/variant_overrides_spec.rb new file mode 100644 index 0000000000..f726bd8869 --- /dev/null +++ b/spec/controllers/admin/variant_overrides_spec.rb @@ -0,0 +1,51 @@ +require 'spec_helper' + +module Admin + describe VariantOverridesController, type: :controller do + include AuthenticationWorkflow + let!(:hub_owner) { create :admin_user, enterprise_limit: 2 } + + before do + controller.stub spree_current_user: hub_owner + end + + describe "bulk_update" do + context "as an enterprise user I update the variant overrides" do + let!(:hub) { create(:distributor_enterprise, owner: hub_owner) } + it "updates the overrides correctly" do + v1 = create(:variant) + v2 = create(:variant) + vo1 = create(:variant_override, hub: hub, variant: v1, price: "6.0", count_on_hand: 5, default_stock: 7) + vo2 = create(:variant_override, hub: hub, variant: v2, price: "6.0", count_on_hand: 5, default_stock: 7) + vo1.price = "10.0" + vo2.default_stock = 12 + # Have to use .attributes as otherwise passes just the ID + spree_put :bulk_update, {variant_overrides: [vo1.attributes, vo2.attributes]} + # Retrieve from database + VariantOverride.find(vo1.id).price.should eq 10 + VariantOverride.find(vo2.id).default_stock.should eq 12 + end + end + end + describe "bulk_reset" do + let!(:hub) { create(:distributor_enterprise, owner: hub_owner) } + before do + controller.stub spree_current_user: hub.owner + end + context "when a reset request is received" do + it "updates stock to default values" do + v1 = create(:variant) + v2 = create(:variant) + vo1 = create(:variant_override, hub: hub, variant: v1, price: "6.0", count_on_hand: 5, default_stock: 7) + vo2 = create(:variant_override, hub: hub, variant: v2, price: "6.0", count_on_hand: 2, default_stock: 1) + params = {"variant_overrides" => [vo1.attributes, vo2.attributes]} + spree_put :bulk_reset, params + vo1.reload + expect(vo1.count_on_hand).to eq 7 + vo2.reload + expect(vo2.count_on_hand).to eq 1 + end + end + end + end +end From 0ee078e23252ae5303b9ff9d9d09b58ff03d7bad Mon Sep 17 00:00:00 2001 From: Steve Pettitt Date: Mon, 31 Aug 2015 18:02:53 +0100 Subject: [PATCH 23/43] Added toggle to enable/disable reset stock. Updated specs --- .../variant_overrides_controller.js.coffee | 20 ++++++++----- .../services/variant_overrides.js.coffee | 1 + .../admin/variant_overrides_controller.rb | 6 ++-- app/models/variant_override.rb | 19 +++++++----- app/models/variant_override_set.rb | 5 ++-- .../api/admin/variant_override_serializer.rb | 2 +- .../variant_overrides/_products.html.haml | 2 +- .../_products_product.html.haml | 2 +- .../_products_variants.html.haml | 4 ++- ...2_add_enable_reset_to_variant_overrides.rb | 5 ++++ db/schema.rb | 1 + .../admin/variant_overrides_spec.rb | 20 +++++++++---- spec/factories.rb | 2 ++ ...ariant_overrides_controller_spec.js.coffee | 24 +++++++++++++-- spec/models/variant_override_spec.rb | 29 +++++++++---------- 15 files changed, 96 insertions(+), 46 deletions(-) create mode 100644 db/migrate/20150827194622_add_enable_reset_to_variant_overrides.rb diff --git a/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee b/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee index c2fab4e7c7..bb4a89d7f6 100644 --- a/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee +++ b/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee @@ -59,11 +59,11 @@ angular.module("admin.variantOverrides").controller "AdminVariantOverridesCtrl", StatusMessage.display 'progress', 'Saving...' DirtyVariantOverrides.save() .success (updatedVos) -> - console.log DirtyVariantOverrides.all() DirtyVariantOverrides.clear() VariantOverrides.updateIds updatedVos - StatusMessage.display 'success', 'Changes saved.' $scope.variant_overrides_form.$setPristine() + StatusMessage.display 'success', 'Changes saved.' + VariantOverrides.updateData updatedVos # Refresh page data .error (data, status) -> StatusMessage.display 'failure', $scope.updateError(data, status) @@ -78,12 +78,18 @@ angular.module("admin.variantOverrides").controller "AdminVariantOverridesCtrl", errors = errors.concat field_errors errors = errors.join ', ' "I had some trouble saving: #{errors}" - else "Oh no! I was unable to save your changes." $scope.resetStock = -> - VariantOverrides.resetStock() - .success (updatedVos) -> - VariantOverrides.updateData updatedVos - $timeout -> StatusMessage.display 'success', 'Stocks reset to defaults.' + if DirtyVariantOverrides.count() > 0 + StatusMessage.display 'alert', 'Save changes first.' + $timeout -> + $scope.displayDirty() + , 3000 # 3 second delay + else + StatusMessage.display 'progress', 'Changing on hand stock levels...' + VariantOverrides.resetStock() + .success (updatedVos) -> + VariantOverrides.updateData updatedVos + $timeout -> StatusMessage.display 'success', 'Stocks reset to defaults.' diff --git a/app/assets/javascripts/admin/variant_overrides/services/variant_overrides.js.coffee b/app/assets/javascripts/admin/variant_overrides/services/variant_overrides.js.coffee index 559305b1a3..72caecbcc1 100644 --- a/app/assets/javascripts/admin/variant_overrides/services/variant_overrides.js.coffee +++ b/app/assets/javascripts/admin/variant_overrides/services/variant_overrides.js.coffee @@ -20,6 +20,7 @@ angular.module("admin.variantOverrides").factory "VariantOverrides", (variantOve count_on_hand: null on_demand: null default_stock: null + enable_reset: false updateIds: (updatedVos) -> for vo in updatedVos diff --git a/app/controllers/admin/variant_overrides_controller.rb b/app/controllers/admin/variant_overrides_controller.rb index 9edf82a82a..e187b8a085 100644 --- a/app/controllers/admin/variant_overrides_controller.rb +++ b/app/controllers/admin/variant_overrides_controller.rb @@ -33,10 +33,12 @@ module Admin collection_hash = Hash[params[:variant_overrides].each_with_index.map { |vo, i| [i, vo] }] vo_set = VariantOverrideSet.new @variant_overrides, collection_attributes: collection_hash - # Ensure we're authorised to update all variant overrides + # Ensure we're authorised to update all variant overrides. vo_set.collection.each { |vo| authorize! :update, vo } - vo_set.collection.map! { |vo| vo = vo.reset_stock! } + # Changed this to use class method instead, to ensure the value in the database is used to reset and not a dirty passed-in value + #vo_set.collection.map! { |vo| vo = vo.reset_stock! } + vo_set.collection.map! { |vo| VariantOverride.reset_stock!(vo.hub,vo.variant) } render json: vo_set.collection, each_serializer: Api::Admin::VariantOverrideSerializer if vo_set.errors.present? render json: { errors: vo_set.errors }, status: 400 diff --git a/app/models/variant_override.rb b/app/models/variant_override.rb index c7d111fefc..efac7e5bd6 100644 --- a/app/models/variant_override.rb +++ b/app/models/variant_override.rb @@ -4,7 +4,7 @@ class VariantOverride < ActiveRecord::Base validates_presence_of :hub_id, :variant_id # Default stock can be nil, indicating stock should not be reset or zero, meaning reset to zero. Need to ensure this can be set by the user. - validates :default_stock, numericality: { greater_than: 0 }, allow_nil: true + validates :default_stock, numericality: { greater_than_or_equal_to: 0 }, allow_nil: true scope :for_hubs, lambda { |hubs| where(hub_id: hubs) @@ -50,22 +50,25 @@ class VariantOverride < ActiveRecord::Base Bugsnag.notify RuntimeError.new "Attempting to decrement stock level on a VariantOverride without a count_on_hand specified." end end - + def default_stock? default_stock.present? end - + def reset_stock! - if default_stock? - self.attributes = { count_on_hand: default_stock } - self.save + if enable_reset + if default_stock? + self.attributes = { count_on_hand: default_stock } + self.save + else + Bugsnag.notify RuntimeError.new "Attempting to reset stock level for a variant with no default stock level." + end end - self + self end def self.reset_stock!(hub, variant) vo = self.for(hub, variant) - if vo.nil? Bugsnag.notify RuntimeError.new "Attempting to reset stock level for a variant without a VariantOverride." else diff --git a/app/models/variant_override_set.rb b/app/models/variant_override_set.rb index 0fc0d170e9..f1aaf1074c 100644 --- a/app/models/variant_override_set.rb +++ b/app/models/variant_override_set.rb @@ -1,12 +1,13 @@ class VariantOverrideSet < ModelSet def initialize(collection, attributes={}) - super(VariantOverride, collection, attributes, nil, - proc { |attrs| deletable?(attrs) } ) + super(VariantOverride, collection, attributes, nil, proc { |attrs| deletable?(attrs) } ) end def deletable?(attrs) attrs['price'].blank? && attrs['count_on_hand'].blank? && + attrs['default_stock'].blank? && + attrs['enable_reset'].blank? && attrs['sku'].nil? && attrs['on_demand'].nil? end diff --git a/app/serializers/api/admin/variant_override_serializer.rb b/app/serializers/api/admin/variant_override_serializer.rb index 54b4419fb7..fa989af96e 100644 --- a/app/serializers/api/admin/variant_override_serializer.rb +++ b/app/serializers/api/admin/variant_override_serializer.rb @@ -1,3 +1,3 @@ class Api::Admin::VariantOverrideSerializer < ActiveModel::Serializer - attributes :id, :hub_id, :variant_id, :sku, :price, :count_on_hand, :on_demand, :default_stock + attributes :id, :hub_id, :variant_id, :sku, :price, :count_on_hand, :on_demand, :default_stock, :enable_reset end diff --git a/app/views/admin/variant_overrides/_products.html.haml b/app/views/admin/variant_overrides/_products.html.haml index f268c90130..b88febeab3 100644 --- a/app/views/admin/variant_overrides/_products.html.haml +++ b/app/views/admin/variant_overrides/_products.html.haml @@ -7,7 +7,7 @@ %th.price{ ng: { show: 'columns.price.visible' } } Price %th.on_hand{ ng: { show: 'columns.on_hand.visible' } } On hand %th.on_demand{ ng: { show: 'columns.on_demand.visible' } } On Demand? - %th Default stock + %th{colspan: 2} Enable stock level reset? %tbody{bindonce: true, ng: {repeat: 'product in products | hubPermissions:hubPermissions:hub.id | attrFilter:{producer_id:producerFilter} | filter:query' } } = render 'admin/variant_overrides/products_product' = render 'admin/variant_overrides/products_variants' diff --git a/app/views/admin/variant_overrides/_products_product.html.haml b/app/views/admin/variant_overrides/_products_product.html.haml index 6f58c9bd75..1bcf4cf016 100644 --- a/app/views/admin/variant_overrides/_products_product.html.haml +++ b/app/views/admin/variant_overrides/_products_product.html.haml @@ -5,4 +5,4 @@ %td.price{ ng: { show: 'columns.price.visible' } } %td.on_hand{ ng: { show: 'columns.on_hand.visible' } } %td.on_demand{ ng: { show: 'columns.on_demand.visible' } } - %td + %td{colspan: 2} diff --git a/app/views/admin/variant_overrides/_products_variants.html.haml b/app/views/admin/variant_overrides/_products_variants.html.haml index 510689b83d..9e5bf1f356 100644 --- a/app/views/admin/variant_overrides/_products_variants.html.haml +++ b/app/views/admin/variant_overrides/_products_variants.html.haml @@ -15,4 +15,6 @@ %input{name: 'variant-overrides-{{ variant.id }}-count-on-hand', type: 'text', ng: {model: 'variantOverrides[hub.id][variant.id].count_on_hand'}, placeholder: '{{ variant.on_hand }}', 'ofn-track-variant-override' => 'count_on_hand'} %td - %input{name: 'variant-overrides-{{ variant.id }}-default-stock', type: 'text', ng: {model: 'variantOverrides[hub.id][variant.id].default_stock'}, placeholder: '{{ variant.default_stock }}', 'ofn-track-variant-override' => 'default_stock'} + %input{name: 'variant-overrides-{{ variant.id }}-enable_reset', type: 'checkbox', ng: {model: 'variantOverrides[hub.id][variant.id].enable_reset'}, placeholder: '{{ variant.enable_reset }}', 'ofn-track-variant-override' => 'enable_reset'} + %td + %input{name: 'variant-overrides-{{ variant.id }}-default-stock', type: 'text', ng: {model: 'variantOverrides[hub.id][variant.id].default_stock'}, placeholder: '{{ variant.default_stock ? variant.default_stock : "Default stock"}}', 'ofn-track-variant-override' => 'default_stock'} diff --git a/db/migrate/20150827194622_add_enable_reset_to_variant_overrides.rb b/db/migrate/20150827194622_add_enable_reset_to_variant_overrides.rb new file mode 100644 index 0000000000..172cce6588 --- /dev/null +++ b/db/migrate/20150827194622_add_enable_reset_to_variant_overrides.rb @@ -0,0 +1,5 @@ +class AddEnableResetToVariantOverrides < ActiveRecord::Migration + def change + add_column :variant_overrides, :enable_reset, :boolean + end +end diff --git a/db/schema.rb b/db/schema.rb index 9adf1c5391..60f3819562 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -1162,6 +1162,7 @@ ActiveRecord::Schema.define(:version => 20151126235409) do t.string "sku" t.boolean "on_demand" t.integer "default_stock" + t.boolean "enable_reset" end add_index "variant_overrides", ["variant_id", "hub_id"], :name => "index_variant_overrides_on_variant_id_and_hub_id" diff --git a/spec/controllers/admin/variant_overrides_spec.rb b/spec/controllers/admin/variant_overrides_spec.rb index f726bd8869..aa2596ab34 100644 --- a/spec/controllers/admin/variant_overrides_spec.rb +++ b/spec/controllers/admin/variant_overrides_spec.rb @@ -34,16 +34,26 @@ module Admin end context "when a reset request is received" do it "updates stock to default values" do + v1 = create(:variant) + v2 = create(:variant) + vo1 = create(:variant_override, hub: hub, variant: v1, price: "6.0", count_on_hand: 5, default_stock: 7, enable_reset: true) + vo2 = create(:variant_override, hub: hub, variant: v2, price: "6.0", count_on_hand: 2, default_stock: 1, enable_reset: false) + params = {"variant_overrides" => [vo1.attributes, vo2.attributes]} + spree_put :bulk_reset, params + + vo1.reload + expect(vo1.count_on_hand).to eq 7 + end + it "doesn't update where reset is disabled" do v1 = create(:variant) v2 = create(:variant) - vo1 = create(:variant_override, hub: hub, variant: v1, price: "6.0", count_on_hand: 5, default_stock: 7) - vo2 = create(:variant_override, hub: hub, variant: v2, price: "6.0", count_on_hand: 2, default_stock: 1) + vo1 = create(:variant_override, hub: hub, variant: v1, price: "6.0", count_on_hand: 5, default_stock: 7, enable_reset: true) + vo2 = create(:variant_override, hub: hub, variant: v2, price: "6.0", count_on_hand: 2, default_stock: 1, enable_reset: false) params = {"variant_overrides" => [vo1.attributes, vo2.attributes]} spree_put :bulk_reset, params - vo1.reload - expect(vo1.count_on_hand).to eq 7 + vo2.reload - expect(vo2.count_on_hand).to eq 1 + expect(vo2.count_on_hand).to eq 2 end end end diff --git a/spec/factories.rb b/spec/factories.rb index 8ae6a094c2..f6eeff4680 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -94,6 +94,8 @@ FactoryGirl.define do factory :variant_override, :class => VariantOverride do price 77.77 count_on_hand 11111 + default_stock 2000 + enable_reset false end factory :enterprise, :class => Enterprise do diff --git a/spec/javascripts/unit/admin/controllers/variant_overrides_controller_spec.js.coffee b/spec/javascripts/unit/admin/controllers/variant_overrides_controller_spec.js.coffee index 22b8300409..e75cf51692 100644 --- a/spec/javascripts/unit/admin/controllers/variant_overrides_controller_spec.js.coffee +++ b/spec/javascripts/unit/admin/controllers/variant_overrides_controller_spec.js.coffee @@ -7,18 +7,25 @@ describe "VariantOverridesCtrl", -> hubPermissions = {} VariantOverrides = null variantOverrides = {} + DirtyVariantOverrides = null + dirtyVariantOverrides = {} + StatusMessage = null + statusMessage = {} beforeEach -> module 'admin.variantOverrides' module ($provide) -> $provide.value 'SpreeApiKey', 'API_KEY' $provide.value 'variantOverrides', variantOverrides + $provide.value 'dirtyVariantOverrides', dirtyVariantOverrides null scope = {} - inject ($controller, _VariantOverrides_) -> + inject ($controller, Indexer, _VariantOverrides_, _DirtyVariantOverrides_, _StatusMessage_) -> VariantOverrides = _VariantOverrides_ - ctrl = $controller 'AdminVariantOverridesCtrl', {$scope: scope, hubs: hubs, producers: producers, products: products, hubPermissions: hubPermissions, VariantOverrides: _VariantOverrides_} + DirtyVariantOverrides = _DirtyVariantOverrides_ + StatusMessage = _StatusMessage_ + ctrl = $controller 'AdminVariantOverridesCtrl', {$scope: scope, hubs: hubs, producers: producers, products: products, hubPermissions: hubPermissions, VariantOverrides: _VariantOverrides_, DirtyVariantOverrides: _DirtyVariantOverrides_, StatusMessage: _StatusMessage_} it "initialises the hub list and the chosen hub", -> expect(scope.hubs).toEqual { 1: {id: 1, name: 'Hub'} } @@ -59,3 +66,16 @@ describe "VariantOverridesCtrl", -> it "returns a generic message otherwise", -> expect(scope.updateError({}, 500)).toEqual "Oh no! I was unable to save your changes." + + describe "setting stock to defaults", -> + it "prompts to save changes if there are any pending", -> + spyOn(VariantOverrides,"resetStock") + DirtyVariantOverrides.add {hub_id: 1, variant_id: 1} + scope.resetStock + #expect(scope.StatusMessage.statusMessage.text).toMatch "changes" + expect(VariantOverrides.resetStock).not.toHaveBeenCalled + it "updates and refreshes on hand value for variant overrides with a default stock level", -> + spyOn(VariantOverrides,"resetStock") + scope.resetStock + expect(VariantOverrides.resetStock).toHaveBeenCalled + #expect(scope.StatusMessage.statusMessage.text).toMatch "defaults" diff --git a/spec/models/variant_override_spec.rb b/spec/models/variant_override_spec.rb index 2cd422e01d..d1b7f0f84a 100644 --- a/spec/models/variant_override_spec.rb +++ b/spec/models/variant_override_spec.rb @@ -49,16 +49,16 @@ describe VariantOverride do describe "checking if stock levels have been overriden" do it "returns true when stock level has been overridden" do create(:variant_override, variant: variant, hub: hub, count_on_hand: 12) - VariantOverride.stock_overridden?(hub, variant).should be_true + VariantOverride.stock_overridden?(hub, variant).should be true end it "returns false when the override has no stock level" do create(:variant_override, variant: variant, hub: hub, count_on_hand: nil) - VariantOverride.stock_overridden?(hub, variant).should be_false + VariantOverride.stock_overridden?(hub, variant).should be false end it "returns false when there is no override for the hub/variant" do - VariantOverride.stock_overridden?(hub, variant).should be_false + VariantOverride.stock_overridden?(hub, variant).should be false end end @@ -69,43 +69,40 @@ describe VariantOverride do vo.reload.count_on_hand.should == 10 end - it "silently logs an error if the variant override doesn't have a stock level" do - vo = create(:variant_override, variant: variant, hub: hub, count_on_hand: nil) - Bugsnag.should_receive(:notify) - VariantOverride.decrement_stock! hub, variant, 2 - vo.reload.count_on_hand.should be_nil - end - it "silently logs an error if the variant override does not exist" do Bugsnag.should_receive(:notify) VariantOverride.decrement_stock! hub, variant, 2 end end - + describe "checking default stock value is present" do it "returns true when a default stock level has been set" do vo = create(:variant_override, variant: variant, hub: hub, count_on_hand: 12, default_stock: 20) - vo.default_stock?.should be_true + vo.default_stock?.should be true end it "returns false when the override has no default stock level" do vo = create(:variant_override, variant: variant, hub: hub, count_on_hand: 12, default_stock:nil) - vo.default_stock.should be_false + vo.default_stock?.should be false end end describe "resetting stock levels" do it "resets the on hand level to the value in the default_stock field" do - vo = create(:variant_override, variant: variant, hub: hub, count_on_hand: 12, default_stock: 20) + vo = create(:variant_override, variant: variant, hub: hub, count_on_hand: 12, default_stock: 20, enable_reset: true) vo.reset_stock! vo.reload.count_on_hand.should == 20 end it "silently logs an error if the variant override doesn't have a default stock level" do - vo = create(:variant_override, variant: variant, hub: hub, count_on_hand: 12, default_stock:nil) + vo = create(:variant_override, variant: variant, hub: hub, count_on_hand: 12, default_stock:nil, enable_reset: true) Bugsnag.should_receive(:notify) vo.reset_stock! vo.reload.count_on_hand.should == 12 - vo.reload.default_stock.should be_nil + end + it "doesn't reset the level if the behaviour is disabled" do + vo = create(:variant_override, variant: variant, hub: hub, count_on_hand: 12, default_stock: 10, enable_reset: false) + vo.reset_stock! + vo.reload.count_on_hand.should == 12 end end end From 5a62098b95395a25b99f493e4d37da252d7fa12a Mon Sep 17 00:00:00 2001 From: Steve Pettitt Date: Thu, 10 Sep 2015 23:28:46 +0100 Subject: [PATCH 24/43] Cleaning up and attempt to add feature spec --- app/mailers/spree/base_mailer_decorator.rb | 2 +- spec/features/admin/variant_overrides_spec.rb | 27 +++++++++++++++---- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/app/mailers/spree/base_mailer_decorator.rb b/app/mailers/spree/base_mailer_decorator.rb index 4f78c1fe1e..339abd8901 100644 --- a/app/mailers/spree/base_mailer_decorator.rb +++ b/app/mailers/spree/base_mailer_decorator.rb @@ -10,4 +10,4 @@ Spree::BaseMailer.class_eval do # This lets us specify assets using relative paths in email templates super.merge(url_options: {host: URI(spree.root_url).host }) end -end \ No newline at end of file +end diff --git a/spec/features/admin/variant_overrides_spec.rb b/spec/features/admin/variant_overrides_spec.rb index 668e67d574..5a18a6100e 100644 --- a/spec/features/admin/variant_overrides_spec.rb +++ b/spec/features/admin/variant_overrides_spec.rb @@ -54,13 +54,12 @@ feature %q{ end it "displays the list of products with variants" do - page.should have_table_row ['PRODUCER', 'PRODUCT', 'PRICE', 'ON HAND'] - - page.should have_table_row [producer.name, product.name, '', ''] + page.should have_table_row ['PRODUCER', 'PRODUCT', 'PRICE', 'ON HAND', 'ENABLE STOCK LEVEL RESET?'] + page.should have_table_row [producer.name, product.name, '', '', ''] page.should have_input "variant-overrides-#{variant.id}-price", placeholder: '1.23' page.should have_input "variant-overrides-#{variant.id}-count_on_hand", placeholder: '12' - page.should have_table_row [producer_related.name, product_related.name, '', ''] + page.should have_table_row [producer_related.name, product_related.name, '', '', ''] page.should have_input "variant-overrides-#{variant_related.id}-price", placeholder: '2.34' page.should have_input "variant-overrides-#{variant_related.id}-count_on_hand", placeholder: '23' @@ -182,8 +181,9 @@ feature %q{ end context "with overrides" do - let!(:vo) { create(:variant_override, variant: variant, hub: hub, price: 77.77, count_on_hand: 11111) } + let!(:vo) { create(:variant_override, variant: variant, hub: hub, price: 77.77, count_on_hand: 11111, default_stock: 1000, enable_reset: true) } let!(:vo_no_auth) { create(:variant_override, variant: variant, hub: hub3, price: 1, count_on_hand: 2) } + let!(:vo_no_) { create(:variant_override, variant: variant, hub: hub, price: 77.77, count_on_hand: 11111, default_stock: 1000, enable_reset: false) } before do visit '/admin/variant_overrides' @@ -212,6 +212,7 @@ feature %q{ vo.count_on_hand.should == 8888 end + # This fails for me and can't find where this automatic deletion is implemented? it "deletes overrides when values are cleared" do fill_in "variant-overrides-#{variant.id}-price", with: '' fill_in "variant-overrides-#{variant.id}-count_on_hand", with: '' @@ -224,6 +225,22 @@ feature %q{ VariantOverride.where(id: vo.id).should be_empty end + + # Failing due to authentication issue + it "resets stock to defaults" do + click_button 'Reset Stock to Defaults' + vo.reload + vo.count_on_hand.should == 1000 + page.should have_input "variant-overrides-#{variant.id}-count-on-hand", with: '1000', placeholder: '12' + end + + it "prompts to save changes before reset if any are pending" do + fill_in "variant-overrides-#{variant.id}-price", with: '200' + click_button 'Reset Stock to Defaults' + page.should have_content "Save changes first" + end + + end end end From d01da727f04335d2cac92d2cc09308b40bfc88a1 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Thu, 29 Oct 2015 11:12:55 +1100 Subject: [PATCH 25/43] Removing :bulk_update action from actions allowed on nil object, using collection_actions methods on controller instead --- app/controllers/admin/enterprise_fees_controller.rb | 2 +- app/controllers/admin/order_cycles_controller.rb | 4 ++++ app/controllers/admin/variant_overrides_controller.rb | 4 ++++ app/models/spree/ability_decorator.rb | 2 +- 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/app/controllers/admin/enterprise_fees_controller.rb b/app/controllers/admin/enterprise_fees_controller.rb index b8ea46689f..866c05ea54 100644 --- a/app/controllers/admin/enterprise_fees_controller.rb +++ b/app/controllers/admin/enterprise_fees_controller.rb @@ -89,7 +89,7 @@ module Admin end def collection_actions - [:index, :for_order_cycle] + [:index, :for_order_cycle, :bulk_update] end def current_enterprise diff --git a/app/controllers/admin/order_cycles_controller.rb b/app/controllers/admin/order_cycles_controller.rb index 3880858e5b..300a2ca24e 100644 --- a/app/controllers/admin/order_cycles_controller.rb +++ b/app/controllers/admin/order_cycles_controller.rb @@ -175,5 +175,9 @@ module Admin def ams_prefix_whitelist [:basic] end + + def collection_actions + [:index, :bulk_update] + end end end diff --git a/app/controllers/admin/variant_overrides_controller.rb b/app/controllers/admin/variant_overrides_controller.rb index e187b8a085..fd8b8c7198 100644 --- a/app/controllers/admin/variant_overrides_controller.rb +++ b/app/controllers/admin/variant_overrides_controller.rb @@ -63,5 +63,9 @@ module Admin def collection end + + def collection_actions + [:index, :bulk_update] + end end end diff --git a/app/models/spree/ability_decorator.rb b/app/models/spree/ability_decorator.rb index b9716e2eb3..2ad5910c5e 100644 --- a/app/models/spree/ability_decorator.rb +++ b/app/models/spree/ability_decorator.rb @@ -66,7 +66,7 @@ class AbilityDecorator def add_enterprise_management_abilities(user) # Spree performs authorize! on (:create, nil) when creating a new order from admin, and also (:search, nil) # when searching for variants to add to the order - can [:create, :search, :bulk_update], nil + can [:create, :search], nil can [:admin, :index], :overview From 94785d415745b2b2f896cbadfdeac0b393cc5ecf Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Thu, 29 Oct 2015 11:46:56 +1100 Subject: [PATCH 26/43] Fixing authorization for VariantOverridesController#bulk_reset --- .../admin/variant_overrides_controller.rb | 4 +- app/models/spree/ability_decorator.rb | 2 +- .../admin/variant_overrides_spec.rb | 83 +++++++++++-------- spec/models/spree/ability_spec.rb | 2 +- 4 files changed, 53 insertions(+), 38 deletions(-) diff --git a/app/controllers/admin/variant_overrides_controller.rb b/app/controllers/admin/variant_overrides_controller.rb index fd8b8c7198..8e6029c08b 100644 --- a/app/controllers/admin/variant_overrides_controller.rb +++ b/app/controllers/admin/variant_overrides_controller.rb @@ -34,7 +34,7 @@ module Admin vo_set = VariantOverrideSet.new @variant_overrides, collection_attributes: collection_hash # Ensure we're authorised to update all variant overrides. - vo_set.collection.each { |vo| authorize! :update, vo } + vo_set.collection.each { |vo| authorize! :bulk_reset, vo } # Changed this to use class method instead, to ensure the value in the database is used to reset and not a dirty passed-in value #vo_set.collection.map! { |vo| vo = vo.reset_stock! } @@ -65,7 +65,7 @@ module Admin end def collection_actions - [:index, :bulk_update] + [:index, :bulk_update, :bulk_reset] end end end diff --git a/app/models/spree/ability_decorator.rb b/app/models/spree/ability_decorator.rb index 2ad5910c5e..9bc303116b 100644 --- a/app/models/spree/ability_decorator.rb +++ b/app/models/spree/ability_decorator.rb @@ -111,7 +111,7 @@ class AbilityDecorator OpenFoodNetwork::Permissions.new(user).managed_product_enterprises.include? variant.product.supplier end - can [:admin, :index, :read, :update, :bulk_update], VariantOverride do |vo| + can [:admin, :index, :read, :update, :bulk_update, :bulk_reset], VariantOverride do |vo| next false unless vo.hub.present? && vo.variant.andand.product.andand.supplier.present? hub_auth = OpenFoodNetwork::Permissions.new(user). diff --git a/spec/controllers/admin/variant_overrides_spec.rb b/spec/controllers/admin/variant_overrides_spec.rb index aa2596ab34..882b1759ca 100644 --- a/spec/controllers/admin/variant_overrides_spec.rb +++ b/spec/controllers/admin/variant_overrides_spec.rb @@ -3,57 +3,72 @@ require 'spec_helper' module Admin describe VariantOverridesController, type: :controller do include AuthenticationWorkflow - let!(:hub_owner) { create :admin_user, enterprise_limit: 2 } + let!(:hub_owner) { create :user, enterprise_limit: 2 } + let!(:v1) { create(:variant) } + let!(:v2) { create(:variant) } + let!(:vo1) { create(:variant_override, hub: hub, variant: v1, price: "6.0", count_on_hand: 5, default_stock: 7, enable_reset: true) } + let!(:vo2) { create(:variant_override, hub: hub, variant: v2, price: "6.0", count_on_hand: 2, default_stock: 1, enable_reset: false) } before do controller.stub spree_current_user: hub_owner end describe "bulk_update" do - context "as an enterprise user I update the variant overrides" do - let!(:hub) { create(:distributor_enterprise, owner: hub_owner) } + let!(:hub) { create(:distributor_enterprise, owner: hub_owner) } + let(:params) { { variant_overrides: [{id: vo1.id, price: "10.0"}, {id: vo2.id, default_stock: 12 }] } } + + context "where the producer has not granted create_variant_overrides permission to the hub" do + it "restricts access" do + spree_put :bulk_update, params + expect(response).to redirect_to spree.unauthorized_path + end + end + + context "where the producer has granted create_variant_overrides permission to the hub" do + let!(:er1) { create(:enterprise_relationship, parent: v1.product.supplier, child: hub, permissions_list: [:create_variant_overrides]) } + it "updates the overrides correctly" do - v1 = create(:variant) - v2 = create(:variant) - vo1 = create(:variant_override, hub: hub, variant: v1, price: "6.0", count_on_hand: 5, default_stock: 7) - vo2 = create(:variant_override, hub: hub, variant: v2, price: "6.0", count_on_hand: 5, default_stock: 7) - vo1.price = "10.0" - vo2.default_stock = 12 - # Have to use .attributes as otherwise passes just the ID - spree_put :bulk_update, {variant_overrides: [vo1.attributes, vo2.attributes]} - # Retrieve from database - VariantOverride.find(vo1.id).price.should eq 10 - VariantOverride.find(vo2.id).default_stock.should eq 12 + spree_put :bulk_update, params + vo1.reload.price.should eq 10 + vo2.reload.default_stock.should eq 12 end end end + describe "bulk_reset" do let!(:hub) { create(:distributor_enterprise, owner: hub_owner) } + before do controller.stub spree_current_user: hub.owner end - context "when a reset request is received" do - it "updates stock to default values" do - v1 = create(:variant) - v2 = create(:variant) - vo1 = create(:variant_override, hub: hub, variant: v1, price: "6.0", count_on_hand: 5, default_stock: 7, enable_reset: true) - vo2 = create(:variant_override, hub: hub, variant: v2, price: "6.0", count_on_hand: 2, default_stock: 1, enable_reset: false) - params = {"variant_overrides" => [vo1.attributes, vo2.attributes]} - spree_put :bulk_reset, params - vo1.reload - expect(vo1.count_on_hand).to eq 7 - end - it "doesn't update where reset is disabled" do - v1 = create(:variant) - v2 = create(:variant) - vo1 = create(:variant_override, hub: hub, variant: v1, price: "6.0", count_on_hand: 5, default_stock: 7, enable_reset: true) - vo2 = create(:variant_override, hub: hub, variant: v2, price: "6.0", count_on_hand: 2, default_stock: 1, enable_reset: false) - params = {"variant_overrides" => [vo1.attributes, vo2.attributes]} + context "where the producer has not granted create_variant_overrides permission to the hub" do + let(:params) { { variant_overrides: [ { id: vo1 } ] } } + + it "restricts access" do spree_put :bulk_reset, params - - vo2.reload - expect(vo2.count_on_hand).to eq 2 + expect(response).to redirect_to spree.unauthorized_path + end + end + + context "where the producer has granted create_variant_overrides permission to the hub" do + let!(:er1) { create(:enterprise_relationship, parent: v1.product.supplier, child: hub, permissions_list: [:create_variant_overrides]) } + + context "where reset is enabled" do + let(:params) { { variant_overrides: [ { id: vo1 } ] } } + + it "updates stock to default values" do + spree_put :bulk_reset, params + expect(vo1.reload.count_on_hand).to eq 7 + end + end + + context "where reset is disabled" do + let(:params) { { variant_overrides: [ { id: vo2 } ] } } + it "doesn't update on_hand" do + spree_put :bulk_reset, params + expect(vo2.reload.count_on_hand).to eq 2 + end end end end diff --git a/spec/models/spree/ability_spec.rb b/spec/models/spree/ability_spec.rb index 6b60707775..4af3d233b1 100644 --- a/spec/models/spree/ability_spec.rb +++ b/spec/models/spree/ability_spec.rb @@ -323,7 +323,7 @@ module Spree let!(:er1) { create(:enterprise_relationship, parent: s1, child: d1, permissions_list: [:create_variant_overrides]) } it "should be able to access variant overrides page" do - should have_ability([:admin, :index, :bulk_update], for: VariantOverride) + should have_ability([:admin, :index, :bulk_update, :bulk_reset], for: VariantOverride) end it "should be able to read/write their own variant overrides" do From 75127f2a63061a1707048bd1509959f514765167 Mon Sep 17 00:00:00 2001 From: Steve Pettitt Date: Sat, 28 Nov 2015 12:49:48 +0000 Subject: [PATCH 27/43] Fix feature specs for VO reset --- spec/features/admin/variant_overrides_spec.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/features/admin/variant_overrides_spec.rb b/spec/features/admin/variant_overrides_spec.rb index 5a18a6100e..7f1500a810 100644 --- a/spec/features/admin/variant_overrides_spec.rb +++ b/spec/features/admin/variant_overrides_spec.rb @@ -205,7 +205,7 @@ feature %q{ page.should have_content "Changes saved." end.to change(VariantOverride, :count).by(0) - vo.reload + vo = VariantOverride.last vo.variant_id.should == variant.id vo.hub_id.should == hub.id vo.price.should == 22.22 @@ -226,10 +226,10 @@ feature %q{ VariantOverride.where(id: vo.id).should be_empty end - # Failing due to authentication issue it "resets stock to defaults" do click_button 'Reset Stock to Defaults' - vo.reload + page.should have_content 'Stocks reset to defaults.' + vo = VariantOverride.last vo.count_on_hand.should == 1000 page.should have_input "variant-overrides-#{variant.id}-count-on-hand", with: '1000', placeholder: '12' end From 25454d3e977ff36eb5c6ebf78c2de63e5ce35c2d Mon Sep 17 00:00:00 2001 From: Steve Pettitt Date: Sat, 28 Nov 2015 18:26:41 +0000 Subject: [PATCH 28/43] Added new fields to fix VO deletion feature specs --- .../admin/variant_overrides_controller.rb | 31 ++++++++++--------- .../_products_variants.html.haml | 2 +- spec/features/admin/variant_overrides_spec.rb | 11 ++++--- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/app/controllers/admin/variant_overrides_controller.rb b/app/controllers/admin/variant_overrides_controller.rb index 8e6029c08b..e91d8f5dd7 100644 --- a/app/controllers/admin/variant_overrides_controller.rb +++ b/app/controllers/admin/variant_overrides_controller.rb @@ -6,23 +6,22 @@ module Admin before_filter :load_spree_api_key, only: :index before_filter :load_data + before_filter :load_collection, only: [:bulk_update, :bulk_reset] def index end def bulk_update - collection_hash = Hash[params[:variant_overrides].each_with_index.map { |vo, i| [i, vo] }] - vo_set = VariantOverrideSet.new @variant_overrides, collection_attributes: collection_hash # Ensure we're authorised to update all variant overrides - vo_set.collection.each { |vo| authorize! :update, vo } + @vo_set.collection.each { |vo| authorize! :update, vo } - if vo_set.save + if @vo_set.save # Return saved VOs with IDs - render json: vo_set.collection, each_serializer: Api::Admin::VariantOverrideSerializer + render json: @vo_set.collection, each_serializer: Api::Admin::VariantOverrideSerializer else - if vo_set.errors.present? - render json: { errors: vo_set.errors }, status: 400 + if @vo_set.errors.present? + render json: { errors: @vo_set.errors }, status: 400 else render nothing: true, status: 500 end @@ -30,18 +29,15 @@ module Admin end def bulk_reset - collection_hash = Hash[params[:variant_overrides].each_with_index.map { |vo, i| [i, vo] }] - vo_set = VariantOverrideSet.new @variant_overrides, collection_attributes: collection_hash - # Ensure we're authorised to update all variant overrides. - vo_set.collection.each { |vo| authorize! :bulk_reset, vo } + @vo_set.collection.each { |vo| authorize! :bulk_reset, vo } # Changed this to use class method instead, to ensure the value in the database is used to reset and not a dirty passed-in value #vo_set.collection.map! { |vo| vo = vo.reset_stock! } - vo_set.collection.map! { |vo| VariantOverride.reset_stock!(vo.hub,vo.variant) } - render json: vo_set.collection, each_serializer: Api::Admin::VariantOverrideSerializer - if vo_set.errors.present? - render json: { errors: vo_set.errors }, status: 400 + @vo_set.collection.map! { |vo| VariantOverride.reset_stock!(vo.hub,vo.variant) } + render json: @vo_set.collection, each_serializer: Api::Admin::VariantOverrideSerializer + if @vo_set.errors.present? + render json: { errors: @vo_set.errors }, status: 400 end end @@ -61,6 +57,11 @@ module Admin @variant_overrides = VariantOverride.for_hubs(@hubs) end + def load_collection + collection_hash = Hash[params[:variant_overrides].each_with_index.map { |vo, i| [i, vo] }] + @vo_set = VariantOverrideSet.new @variant_overrides, collection_attributes: collection_hash + end + def collection end diff --git a/app/views/admin/variant_overrides/_products_variants.html.haml b/app/views/admin/variant_overrides/_products_variants.html.haml index 9e5bf1f356..9115a079a2 100644 --- a/app/views/admin/variant_overrides/_products_variants.html.haml +++ b/app/views/admin/variant_overrides/_products_variants.html.haml @@ -15,6 +15,6 @@ %input{name: 'variant-overrides-{{ variant.id }}-count-on-hand', type: 'text', ng: {model: 'variantOverrides[hub.id][variant.id].count_on_hand'}, placeholder: '{{ variant.on_hand }}', 'ofn-track-variant-override' => 'count_on_hand'} %td - %input{name: 'variant-overrides-{{ variant.id }}-enable_reset', type: 'checkbox', ng: {model: 'variantOverrides[hub.id][variant.id].enable_reset'}, placeholder: '{{ variant.enable_reset }}', 'ofn-track-variant-override' => 'enable_reset'} + %input{name: 'variant-overrides-{{ variant.id }}-enable-reset', type: 'checkbox', ng: {model: 'variantOverrides[hub.id][variant.id].enable_reset'}, placeholder: '{{ variant.enable_reset }}', 'ofn-track-variant-override' => 'enable_reset'} %td %input{name: 'variant-overrides-{{ variant.id }}-default-stock', type: 'text', ng: {model: 'variantOverrides[hub.id][variant.id].default_stock'}, placeholder: '{{ variant.default_stock ? variant.default_stock : "Default stock"}}', 'ofn-track-variant-override' => 'default_stock'} diff --git a/spec/features/admin/variant_overrides_spec.rb b/spec/features/admin/variant_overrides_spec.rb index 7f1500a810..955e02054c 100644 --- a/spec/features/admin/variant_overrides_spec.rb +++ b/spec/features/admin/variant_overrides_spec.rb @@ -183,7 +183,6 @@ feature %q{ context "with overrides" do let!(:vo) { create(:variant_override, variant: variant, hub: hub, price: 77.77, count_on_hand: 11111, default_stock: 1000, enable_reset: true) } let!(:vo_no_auth) { create(:variant_override, variant: variant, hub: hub3, price: 1, count_on_hand: 2) } - let!(:vo_no_) { create(:variant_override, variant: variant, hub: hub, price: 77.77, count_on_hand: 11111, default_stock: 1000, enable_reset: false) } before do visit '/admin/variant_overrides' @@ -205,7 +204,7 @@ feature %q{ page.should have_content "Changes saved." end.to change(VariantOverride, :count).by(0) - vo = VariantOverride.last + vo.reload vo.variant_id.should == variant.id vo.hub_id.should == hub.id vo.price.should == 22.22 @@ -215,7 +214,9 @@ feature %q{ # This fails for me and can't find where this automatic deletion is implemented? it "deletes overrides when values are cleared" do fill_in "variant-overrides-#{variant.id}-price", with: '' - fill_in "variant-overrides-#{variant.id}-count_on_hand", with: '' + fill_in "variant-overrides-#{variant.id}-count-on-hand", with: '' + fill_in "variant-overrides-#{variant.id}-default-stock", with: '' + page.uncheck "variant-overrides-#{variant.id}-enable-reset" page.should have_content "Changes to one override remain unsaved." expect do @@ -229,9 +230,9 @@ feature %q{ it "resets stock to defaults" do click_button 'Reset Stock to Defaults' page.should have_content 'Stocks reset to defaults.' - vo = VariantOverride.last - vo.count_on_hand.should == 1000 + vo.reload page.should have_input "variant-overrides-#{variant.id}-count-on-hand", with: '1000', placeholder: '12' + vo.count_on_hand.should == 1000 end it "prompts to save changes before reset if any are pending" do From e423e890e0cd91fd30bf4d61dee59ea96456530d Mon Sep 17 00:00:00 2001 From: Steve Pettitt Date: Sat, 28 Nov 2015 20:55:55 +0000 Subject: [PATCH 29/43] Changed name enable_reset to resettable in Variant Overrides table & updated views, specs accordingly --- .../services/variant_overrides.js.coffee | 2 +- app/models/variant_override.rb | 2 +- app/models/variant_override_set.rb | 2 +- .../api/admin/variant_override_serializer.rb | 2 +- .../_products_variants.html.haml | 2 +- db/schema.rb | 4 +- .../admin/variant_overrides_spec.rb | 4 +- spec/factories.rb | 2 +- spec/features/admin/variant_overrides_spec.rb | 18 ++++-- .../services/variant_overrides_spec.js.coffee | 60 +++++++++---------- spec/models/variant_override_spec.rb | 6 +- 11 files changed, 57 insertions(+), 47 deletions(-) diff --git a/app/assets/javascripts/admin/variant_overrides/services/variant_overrides.js.coffee b/app/assets/javascripts/admin/variant_overrides/services/variant_overrides.js.coffee index 72caecbcc1..1a4a445d0e 100644 --- a/app/assets/javascripts/admin/variant_overrides/services/variant_overrides.js.coffee +++ b/app/assets/javascripts/admin/variant_overrides/services/variant_overrides.js.coffee @@ -20,7 +20,7 @@ angular.module("admin.variantOverrides").factory "VariantOverrides", (variantOve count_on_hand: null on_demand: null default_stock: null - enable_reset: false + resettable: false updateIds: (updatedVos) -> for vo in updatedVos diff --git a/app/models/variant_override.rb b/app/models/variant_override.rb index efac7e5bd6..ec3adebdaf 100644 --- a/app/models/variant_override.rb +++ b/app/models/variant_override.rb @@ -56,7 +56,7 @@ class VariantOverride < ActiveRecord::Base end def reset_stock! - if enable_reset + if resettable if default_stock? self.attributes = { count_on_hand: default_stock } self.save diff --git a/app/models/variant_override_set.rb b/app/models/variant_override_set.rb index f1aaf1074c..54124983b5 100644 --- a/app/models/variant_override_set.rb +++ b/app/models/variant_override_set.rb @@ -7,7 +7,7 @@ class VariantOverrideSet < ModelSet attrs['price'].blank? && attrs['count_on_hand'].blank? && attrs['default_stock'].blank? && - attrs['enable_reset'].blank? && + attrs['resettable'].blank? && attrs['sku'].nil? && attrs['on_demand'].nil? end diff --git a/app/serializers/api/admin/variant_override_serializer.rb b/app/serializers/api/admin/variant_override_serializer.rb index fa989af96e..c1e6e0038c 100644 --- a/app/serializers/api/admin/variant_override_serializer.rb +++ b/app/serializers/api/admin/variant_override_serializer.rb @@ -1,3 +1,3 @@ class Api::Admin::VariantOverrideSerializer < ActiveModel::Serializer - attributes :id, :hub_id, :variant_id, :sku, :price, :count_on_hand, :on_demand, :default_stock, :enable_reset + attributes :id, :hub_id, :variant_id, :sku, :price, :count_on_hand, :on_demand, :default_stock, :resettable end diff --git a/app/views/admin/variant_overrides/_products_variants.html.haml b/app/views/admin/variant_overrides/_products_variants.html.haml index 9115a079a2..7e441dbd64 100644 --- a/app/views/admin/variant_overrides/_products_variants.html.haml +++ b/app/views/admin/variant_overrides/_products_variants.html.haml @@ -15,6 +15,6 @@ %input{name: 'variant-overrides-{{ variant.id }}-count-on-hand', type: 'text', ng: {model: 'variantOverrides[hub.id][variant.id].count_on_hand'}, placeholder: '{{ variant.on_hand }}', 'ofn-track-variant-override' => 'count_on_hand'} %td - %input{name: 'variant-overrides-{{ variant.id }}-enable-reset', type: 'checkbox', ng: {model: 'variantOverrides[hub.id][variant.id].enable_reset'}, placeholder: '{{ variant.enable_reset }}', 'ofn-track-variant-override' => 'enable_reset'} + %input{name: 'variant-overrides-{{ variant.id }}-resettable', type: 'checkbox', ng: {model: 'variantOverrides[hub.id][variant.id].resettable'}, placeholder: '{{ variant.resettable }}', 'ofn-track-variant-override' => 'resettable'} %td %input{name: 'variant-overrides-{{ variant.id }}-default-stock', type: 'text', ng: {model: 'variantOverrides[hub.id][variant.id].default_stock'}, placeholder: '{{ variant.default_stock ? variant.default_stock : "Default stock"}}', 'ofn-track-variant-override' => 'default_stock'} diff --git a/db/schema.rb b/db/schema.rb index 60f3819562..08cc2bb643 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20151126235409) do +ActiveRecord::Schema.define(:version => 20151128185900) do create_table "account_invoices", :force => true do |t| t.integer "user_id", :null => false @@ -1162,7 +1162,7 @@ ActiveRecord::Schema.define(:version => 20151126235409) do t.string "sku" t.boolean "on_demand" t.integer "default_stock" - t.boolean "enable_reset" + t.boolean "resettable" end add_index "variant_overrides", ["variant_id", "hub_id"], :name => "index_variant_overrides_on_variant_id_and_hub_id" diff --git a/spec/controllers/admin/variant_overrides_spec.rb b/spec/controllers/admin/variant_overrides_spec.rb index 882b1759ca..2eb887b961 100644 --- a/spec/controllers/admin/variant_overrides_spec.rb +++ b/spec/controllers/admin/variant_overrides_spec.rb @@ -6,8 +6,8 @@ module Admin let!(:hub_owner) { create :user, enterprise_limit: 2 } let!(:v1) { create(:variant) } let!(:v2) { create(:variant) } - let!(:vo1) { create(:variant_override, hub: hub, variant: v1, price: "6.0", count_on_hand: 5, default_stock: 7, enable_reset: true) } - let!(:vo2) { create(:variant_override, hub: hub, variant: v2, price: "6.0", count_on_hand: 2, default_stock: 1, enable_reset: false) } + let!(:vo1) { create(:variant_override, hub: hub, variant: v1, price: "6.0", count_on_hand: 5, default_stock: 7, resettable: true) } + let!(:vo2) { create(:variant_override, hub: hub, variant: v2, price: "6.0", count_on_hand: 2, default_stock: 1, resettable: false) } before do controller.stub spree_current_user: hub_owner diff --git a/spec/factories.rb b/spec/factories.rb index f6eeff4680..dd8d02e7bf 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -95,7 +95,7 @@ FactoryGirl.define do price 77.77 count_on_hand 11111 default_stock 2000 - enable_reset false + resettable false end factory :enterprise, :class => Enterprise do diff --git a/spec/features/admin/variant_overrides_spec.rb b/spec/features/admin/variant_overrides_spec.rb index 955e02054c..40398033ca 100644 --- a/spec/features/admin/variant_overrides_spec.rb +++ b/spec/features/admin/variant_overrides_spec.rb @@ -181,9 +181,11 @@ feature %q{ end context "with overrides" do - let!(:vo) { create(:variant_override, variant: variant, hub: hub, price: 77.77, count_on_hand: 11111, default_stock: 1000, enable_reset: true) } + let!(:vo) { create(:variant_override, variant: variant, hub: hub, price: 77.77, count_on_hand: 11111, default_stock: 1000, resettable: true) } let!(:vo_no_auth) { create(:variant_override, variant: variant, hub: hub3, price: 1, count_on_hand: 2) } - + let!(:product2) { create(:simple_product, supplier: producer, variant_unit: 'weight', variant_unit_scale: 1) } + let!(:variant2) { create(:variant, product: product2, unit_value: 8, price: 1.00, on_hand: 12) } + let!(:vo_no_reset) { create(:variant_override, variant: variant2, hub: hub, price: 3.99, count_on_hand: 40, default_stock: 100, resettable: false) } before do visit '/admin/variant_overrides' select2_select hub.name, from: 'hub_id' @@ -211,12 +213,12 @@ feature %q{ vo.count_on_hand.should == 8888 end - # This fails for me and can't find where this automatic deletion is implemented? + # Any new fields added to the VO model need to be added to this test it "deletes overrides when values are cleared" do fill_in "variant-overrides-#{variant.id}-price", with: '' fill_in "variant-overrides-#{variant.id}-count-on-hand", with: '' fill_in "variant-overrides-#{variant.id}-default-stock", with: '' - page.uncheck "variant-overrides-#{variant.id}-enable-reset" + page.uncheck "variant-overrides-#{variant.id}-resettable" page.should have_content "Changes to one override remain unsaved." expect do @@ -235,6 +237,14 @@ feature %q{ vo.count_on_hand.should == 1000 end + it "doesn't reset stock levels if the behaviour is disabled" do + click_button 'Reset Stock to Defaults' + vo_no_reset.reload + page.should have_input "variant-overrides-#{variant2.id}-count-on-hand", with: '40', placeholder: '12' + vo_no_reset.count_on_hand.should == 40 + end + + it "prompts to save changes before reset if any are pending" do fill_in "variant-overrides-#{variant.id}-price", with: '200' click_button 'Reset Stock to Defaults' diff --git a/spec/javascripts/unit/admin/services/variant_overrides_spec.js.coffee b/spec/javascripts/unit/admin/services/variant_overrides_spec.js.coffee index 5ffd71cd64..9dcae28a94 100644 --- a/spec/javascripts/unit/admin/services/variant_overrides_spec.js.coffee +++ b/spec/javascripts/unit/admin/services/variant_overrides_spec.js.coffee @@ -1,9 +1,9 @@ describe "VariantOverrides service", -> VariantOverrides = $httpBackend = null variantOverrides = [ - {id: 1, hub_id: 10, variant_id: 100, price: 1, count_on_hand: 1, default_stock: ''} - {id: 2, hub_id: 10, variant_id: 200, price: 2, count_on_hand: 2, default_stock: ''} - {id: 3, hub_id: 20, variant_id: 300, price: 3, count_on_hand: 3, default_stock: ''} + {id: 1, hub_id: 10, variant_id: 100, price: 1, count_on_hand: 1, default_stock: '', resettable: false} + {id: 2, hub_id: 10, variant_id: 200, price: 2, count_on_hand: 2, default_stock: '', resettable: false} + {id: 3, hub_id: 20, variant_id: 300, price: 3, count_on_hand: 3, default_stock: '', resettable: false} ] beforeEach -> @@ -19,10 +19,10 @@ describe "VariantOverrides service", -> it "indexes variant overrides by hub_id -> variant_id", -> expect(VariantOverrides.variantOverrides).toEqual 10: - 100: {id: 1, hub_id: 10, variant_id: 100, price: 1, count_on_hand: 1, default_stock: ''} - 200: {id: 2, hub_id: 10, variant_id: 200, price: 2, count_on_hand: 2, default_stock: ''} + 100: {id: 1, hub_id: 10, variant_id: 100, price: 1, count_on_hand: 1, default_stock: '', resettable: false} + 200: {id: 2, hub_id: 10, variant_id: 200, price: 2, count_on_hand: 2, default_stock: '', resettable: false} 20: - 300: {id: 3, hub_id: 20, variant_id: 300, price: 3, count_on_hand: 3, default_stock: ''} + 300: {id: 3, hub_id: 20, variant_id: 300, price: 3, count_on_hand: 3, default_stock: '', resettable: false} it "ensures blank data available for some products", -> hubs = [{id: 10}, {id: 20}, {id: 30}] @@ -35,32 +35,32 @@ describe "VariantOverrides service", -> VariantOverrides.ensureDataFor hubs, products expect(VariantOverrides.variantOverrides).toEqual 10: - 100: {id: 1, hub_id: 10, variant_id: 100, price: 1, count_on_hand: 1, default_stock: ''} - 200: {id: 2, hub_id: 10, variant_id: 200, price: 2, count_on_hand: 2, default_stock: ''} - 300: { hub_id: 10, variant_id: 300, price: '', count_on_hand: '', default_stock: ''} - 400: { hub_id: 10, variant_id: 400, price: '', count_on_hand: '', default_stock: ''} - 500: { hub_id: 10, variant_id: 500, price: '', count_on_hand: '', default_stock: ''} + 100: {id: 1, hub_id: 10, variant_id: 100, price: 1, count_on_hand: 1, default_stock: '', resettable: false} + 200: {id: 2, hub_id: 10, variant_id: 200, price: 2, count_on_hand: 2, default_stock: '', resettable: false} + 300: { hub_id: 10, variant_id: 300, price: '', count_on_hand: '', default_stock: '', resettable: false} + 400: { hub_id: 10, variant_id: 400, price: '', count_on_hand: '', default_stock: '', resettable: false} + 500: { hub_id: 10, variant_id: 500, price: '', count_on_hand: '', default_stock: '', resettable: false} 20: - 100: { hub_id: 20, variant_id: 100, price: '', count_on_hand: '', default_stock: ''} - 200: { hub_id: 20, variant_id: 200, price: '', count_on_hand: '', default_stock: ''} - 300: {id: 3, hub_id: 20, variant_id: 300, price: 3, count_on_hand: 3, default_stock: ''} - 400: { hub_id: 20, variant_id: 400, price: '', count_on_hand: '', default_stock: ''} - 500: { hub_id: 20, variant_id: 500, price: '', count_on_hand: '', default_stock: ''} + 100: { hub_id: 20, variant_id: 100, price: '', count_on_hand: '', default_stock: '', resettable: false} + 200: { hub_id: 20, variant_id: 200, price: '', count_on_hand: '', default_stock: '', resettable: false} + 300: {id: 3, hub_id: 20, variant_id: 300, price: 3, count_on_hand: 3, default_stock: '', resettable: false} + 400: { hub_id: 20, variant_id: 400, price: '', count_on_hand: '', default_stock: '', resettable: false} + 500: { hub_id: 20, variant_id: 500, price: '', count_on_hand: '', default_stock: '', resettable: false} 30: - 100: { hub_id: 30, variant_id: 100, price: '', count_on_hand: '', default_stock: ''} - 200: { hub_id: 30, variant_id: 200, price: '', count_on_hand: '', default_stock: ''} - 300: { hub_id: 30, variant_id: 300, price: '', count_on_hand: '', default_stock: ''} - 400: { hub_id: 30, variant_id: 400, price: '', count_on_hand: '', default_stock: ''} - 500: { hub_id: 30, variant_id: 500, price: '', count_on_hand: '', default_stock: ''} + 100: { hub_id: 30, variant_id: 100, price: '', count_on_hand: '', default_stock: '', resettable: false} + 200: { hub_id: 30, variant_id: 200, price: '', count_on_hand: '', default_stock: '', resettable: false} + 300: { hub_id: 30, variant_id: 300, price: '', count_on_hand: '', default_stock: '', resettable: false} + 400: { hub_id: 30, variant_id: 400, price: '', count_on_hand: '', default_stock: '', resettable: false} + 500: { hub_id: 30, variant_id: 500, price: '', count_on_hand: '', default_stock: '', resettable: false} it "updates the IDs of variant overrides", -> VariantOverrides.variantOverrides[2] = {} - VariantOverrides.variantOverrides[2][3] = {hub_id: 2, variant_id: 3, price: "4.0", count_on_hand: 5, default_stock: ''} - VariantOverrides.variantOverrides[2][8] = {hub_id: 2, variant_id: 8, price: "9.0", count_on_hand: 10, default_stock: ''} + VariantOverrides.variantOverrides[2][3] = {hub_id: 2, variant_id: 3, price: "4.0", count_on_hand: 5, default_stock: '', resettable: false} + VariantOverrides.variantOverrides[2][8] = {hub_id: 2, variant_id: 8, price: "9.0", count_on_hand: 10, default_stock: '', resettable: false} updatedVos = [ - {id: 1, hub_id: 2, variant_id: 3, price: "4.0", count_on_hand: 5, default_stock: ''} - {id: 6, hub_id: 2, variant_id: 8, price: "9.0", count_on_hand: 10, default_stock: ''} + {id: 1, hub_id: 2, variant_id: 3, price: "4.0", count_on_hand: 5, default_stock: '', resettable: false} + {id: 6, hub_id: 2, variant_id: 8, price: "9.0", count_on_hand: 10, default_stock: '', resettable: false} ] VariantOverrides.updateIds updatedVos @@ -75,14 +75,14 @@ describe "VariantOverrides service", -> it "updates the variant overrides on the page with new data", -> VariantOverrides.variantOverrides[1] = - 3: {id: 1, hub_id: 1, variant_id: 3, price: "4.0", count_on_hand: 5, default_stock: 3} - 8: {id: 2, hub_id: 1, variant_id: 8, price: "9.0", count_on_hand: 10, default_stock: ''} + 3: {id: 1, hub_id: 1, variant_id: 3, price: "4.0", count_on_hand: 5, default_stock: 3, resettable: true} + 8: {id: 2, hub_id: 1, variant_id: 8, price: "9.0", count_on_hand: 10, default_stock: '', resettable: false} # Updated count on hand to 3 updatedVos = [ - {id: 1, hub_id: 1, variant_id: 3, price: "4.0", count_on_hand: 3, default_stock: 3} + {id: 1, hub_id: 1, variant_id: 3, price: "4.0", count_on_hand: 3, default_stock: 3, resettable: true} ] VariantOverrides.updateData(updatedVos) expect(VariantOverrides.variantOverrides[1]).toEqual - 3: {id: 1, hub_id: 1, variant_id: 3, price: "4.0", count_on_hand: 3, default_stock: 3} - 8: {id: 2, hub_id: 1, variant_id: 8, price: "9.0", count_on_hand: 10, default_stock: ''} + 3: {id: 1, hub_id: 1, variant_id: 3, price: "4.0", count_on_hand: 3, default_stock: 3, resettable: true} + 8: {id: 2, hub_id: 1, variant_id: 8, price: "9.0", count_on_hand: 10, default_stock: '', resettable: false} diff --git a/spec/models/variant_override_spec.rb b/spec/models/variant_override_spec.rb index d1b7f0f84a..ed2f2c00f4 100644 --- a/spec/models/variant_override_spec.rb +++ b/spec/models/variant_override_spec.rb @@ -89,18 +89,18 @@ describe VariantOverride do describe "resetting stock levels" do it "resets the on hand level to the value in the default_stock field" do - vo = create(:variant_override, variant: variant, hub: hub, count_on_hand: 12, default_stock: 20, enable_reset: true) + vo = create(:variant_override, variant: variant, hub: hub, count_on_hand: 12, default_stock: 20, resettable: true) vo.reset_stock! vo.reload.count_on_hand.should == 20 end it "silently logs an error if the variant override doesn't have a default stock level" do - vo = create(:variant_override, variant: variant, hub: hub, count_on_hand: 12, default_stock:nil, enable_reset: true) + vo = create(:variant_override, variant: variant, hub: hub, count_on_hand: 12, default_stock:nil, resettable: true) Bugsnag.should_receive(:notify) vo.reset_stock! vo.reload.count_on_hand.should == 12 end it "doesn't reset the level if the behaviour is disabled" do - vo = create(:variant_override, variant: variant, hub: hub, count_on_hand: 12, default_stock: 10, enable_reset: false) + vo = create(:variant_override, variant: variant, hub: hub, count_on_hand: 12, default_stock: 10, resettable: false) vo.reset_stock! vo.reload.count_on_hand.should == 12 end From 1d38866f86f14bec0f7a8ff2cfc26b505a71c2a2 Mon Sep 17 00:00:00 2001 From: Steve Pettitt Date: Thu, 3 Dec 2015 21:08:27 +0000 Subject: [PATCH 30/43] Add migration file to git repo --- db/migrate/20151128185900_rename_enable_reset_to_resettable.rb | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 db/migrate/20151128185900_rename_enable_reset_to_resettable.rb diff --git a/db/migrate/20151128185900_rename_enable_reset_to_resettable.rb b/db/migrate/20151128185900_rename_enable_reset_to_resettable.rb new file mode 100644 index 0000000000..461e2efe25 --- /dev/null +++ b/db/migrate/20151128185900_rename_enable_reset_to_resettable.rb @@ -0,0 +1,3 @@ +class RenameEnableResetToResettable < ActiveRecord::Migration + rename_column :variant_overrides, :enable_reset, :resettable +end From 0f4479aceb73f5bbe5afc755cbccf5177eb7bfab Mon Sep 17 00:00:00 2001 From: Steve Pettitt Date: Fri, 11 Dec 2015 08:24:35 +0000 Subject: [PATCH 31/43] Back to original (current master) Rspec version --- Gemfile | 2 +- Gemfile.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index ca4773110d..8230c6a15f 100644 --- a/Gemfile +++ b/Gemfile @@ -39,7 +39,7 @@ gem 'andand' gem 'truncate_html' gem 'representative_view' gem 'rabl' -gem "active_model_serializers", '~> 0.8.3' +gem "active_model_serializers" gem 'oj' gem 'deface', :github => 'spree/deface', :ref => '1110a13' gem 'paperclip' diff --git a/Gemfile.lock b/Gemfile.lock index 1477aedf92..37677c043c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -644,7 +644,7 @@ PLATFORMS ruby DEPENDENCIES - active_model_serializers (~> 0.8.3) + active_model_serializers acts-as-taggable-on (~> 3.4) andand angular-rails-templates (~> 0.2.0) From a3f7ff19b029e90eed971d5c594b87c59dd6c2ea Mon Sep 17 00:00:00 2001 From: Steve Pettitt Date: Fri, 11 Dec 2015 09:07:59 +0000 Subject: [PATCH 32/43] Add new VO fields to shopping spec --- .../consumer/shopping/variant_overrides_spec.rb | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/spec/features/consumer/shopping/variant_overrides_spec.rb b/spec/features/consumer/shopping/variant_overrides_spec.rb index f850436e52..92945a60be 100644 --- a/spec/features/consumer/shopping/variant_overrides_spec.rb +++ b/spec/features/consumer/shopping/variant_overrides_spec.rb @@ -22,12 +22,12 @@ feature "shopping with variant overrides defined", js: true do let(:v4) { create(:variant, product: p1, price: 44.44, unit_value: 4) } let(:v5) { create(:variant, product: p3, price: 55.55, unit_value: 5, on_demand: true) } let(:v6) { create(:variant, product: p3, price: 66.66, unit_value: 6, on_demand: true) } - let!(:vo1) { create(:variant_override, hub: hub, variant: v1, price: 55.55, count_on_hand: nil) } - let!(:vo2) { create(:variant_override, hub: hub, variant: v2, count_on_hand: 0) } - let!(:vo3) { create(:variant_override, hub: hub, variant: v3, count_on_hand: 0) } - let!(:vo4) { create(:variant_override, hub: hub, variant: v4, count_on_hand: 3) } - let!(:vo5) { create(:variant_override, hub: hub, variant: v5, count_on_hand: 0) } - let!(:vo6) { create(:variant_override, hub: hub, variant: v6, count_on_hand: 6) } + let!(:vo1) { create(:variant_override, hub: hub, variant: v1, price: 55.55, count_on_hand: nil, default_stock: nil, resettable: false) } + let!(:vo2) { create(:variant_override, hub: hub, variant: v2, count_on_hand: 0, default_stock: nil, resettable: false) } + let!(:vo3) { create(:variant_override, hub: hub, variant: v3, count_on_hand: 0, default_stock: nil, resettable: false) } + let!(:vo4) { create(:variant_override, hub: hub, variant: v4, count_on_hand: 3, default_stock: nil, resettable: false) } + let!(:vo5) { create(:variant_override, hub: hub, variant: v5, count_on_hand: 0, default_stock: nil, resettable: false) } + let!(:vo6) { create(:variant_override, hub: hub, variant: v6, count_on_hand: 6, default_stock: nil, resettable: false) } let(:ef) { create(:enterprise_fee, enterprise: hub, fee_type: 'packing', calculator: Spree::Calculator::FlatPercentItemTotal.new(preferred_flat_percent: 10)) } before do @@ -143,7 +143,6 @@ feature "shopping with variant overrides defined", js: true do it "does not subtract stock from overrides that do not override count_on_hand" do fill_in "variants[#{v1.id}]", with: "2" click_checkout - expect do complete_checkout end.to change { v1.reload.count_on_hand }.by(-2) @@ -192,7 +191,7 @@ feature "shopping with variant overrides defined", js: true do within "#payment" do choose pm.name end - + place_order page.should have_content "Your order has been processed successfully" end From 607a66b6c62eed2422e1f3a13cd3f6e7d72b1214 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Mon, 21 Dec 2015 10:37:30 +1100 Subject: [PATCH 33/43] WIP: Fixing a few broken VO specs --- .../controllers/variant_overrides_controller.js.coffee | 2 +- app/views/admin/variant_overrides/_products.html.haml | 2 +- .../admin/variant_overrides_controller_spec.rb | 2 +- spec/features/admin/variant_overrides_spec.rb | 8 +++++++- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee b/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee index bb4a89d7f6..ce0f8ac7d6 100644 --- a/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee +++ b/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee @@ -1,4 +1,4 @@ -angular.module("admin.variantOverrides").controller "AdminVariantOverridesCtrl", ($scope, Indexer, Columns, SpreeApiAuth, PagedFetcher, StatusMessage, hubs, producers, hubPermissions, VariantOverrides, DirtyVariantOverrides) -> +angular.module("admin.variantOverrides").controller "AdminVariantOverridesCtrl", ($scope, $timeout, Indexer, Columns, SpreeApiAuth, PagedFetcher, StatusMessage, hubs, producers, hubPermissions, VariantOverrides, DirtyVariantOverrides) -> $scope.hubs = Indexer.index hubs $scope.hub = null $scope.products = [] diff --git a/app/views/admin/variant_overrides/_products.html.haml b/app/views/admin/variant_overrides/_products.html.haml index b88febeab3..6034695866 100644 --- a/app/views/admin/variant_overrides/_products.html.haml +++ b/app/views/admin/variant_overrides/_products.html.haml @@ -7,7 +7,7 @@ %th.price{ ng: { show: 'columns.price.visible' } } Price %th.on_hand{ ng: { show: 'columns.on_hand.visible' } } On hand %th.on_demand{ ng: { show: 'columns.on_demand.visible' } } On Demand? - %th{colspan: 2} Enable stock level reset? + %th.reset{ colspan: 2, ng: { show: 'columns.reset.visible' } } Enable Stock Level Reset? %tbody{bindonce: true, ng: {repeat: 'product in products | hubPermissions:hubPermissions:hub.id | attrFilter:{producer_id:producerFilter} | filter:query' } } = render 'admin/variant_overrides/products_product' = render 'admin/variant_overrides/products_variants' diff --git a/spec/controllers/admin/variant_overrides_controller_spec.rb b/spec/controllers/admin/variant_overrides_controller_spec.rb index 019de4cb61..022a605a53 100644 --- a/spec/controllers/admin/variant_overrides_controller_spec.rb +++ b/spec/controllers/admin/variant_overrides_controller_spec.rb @@ -52,7 +52,7 @@ describe Admin::VariantOverridesController, type: :controller do end context "where params for a variant override are blank" do - let(:variant_override_params) { [ { id: variant_override.id, price: "", count_on_hand: "", sku: nil, on_demand: nil } ] } + let(:variant_override_params) { [ { id: variant_override.id, price: "", count_on_hand: "", default_stock: nil, resettable: nil, sku: nil, on_demand: nil } ] } it "destroys the variant override" do spree_put :bulk_update, format: format, variant_overrides: variant_override_params diff --git a/spec/features/admin/variant_overrides_spec.rb b/spec/features/admin/variant_overrides_spec.rb index 40398033ca..d2076ad470 100644 --- a/spec/features/admin/variant_overrides_spec.rb +++ b/spec/features/admin/variant_overrides_spec.rb @@ -54,7 +54,7 @@ feature %q{ end it "displays the list of products with variants" do - page.should have_table_row ['PRODUCER', 'PRODUCT', 'PRICE', 'ON HAND', 'ENABLE STOCK LEVEL RESET?'] + page.should have_table_row ['PRODUCER', 'PRODUCT', 'PRICE', 'ON HAND'] page.should have_table_row [producer.name, product.name, '', '', ''] page.should have_input "variant-overrides-#{variant.id}-price", placeholder: '1.23' page.should have_input "variant-overrides-#{variant.id}-count_on_hand", placeholder: '12' @@ -215,6 +215,12 @@ feature %q{ # Any new fields added to the VO model need to be added to this test it "deletes overrides when values are cleared" do + first("div#columns-dropdown", :text => "COLUMNS").click + first("div#columns-dropdown div.menu div.menu_item", text: "SKU").click + first("div#columns-dropdown div.menu div.menu_item", text: "On Demand").click + first("div#columns-dropdown div.menu div.menu_item", text: "Reset Stock Level").click + first("div#columns-dropdown", :text => "COLUMNS").click + fill_in "variant-overrides-#{variant.id}-price", with: '' fill_in "variant-overrides-#{variant.id}-count-on-hand", with: '' fill_in "variant-overrides-#{variant.id}-default-stock", with: '' From 0bbae19b41ec7e29b1e0ea5e7009a2040831a673 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Tue, 22 Dec 2015 11:54:09 +1100 Subject: [PATCH 34/43] Variant Overrides Index: User can manually reset inheritance --- .../variant_overrides_controller.js.coffee | 15 +++--- .../directives/track_inheritance.js.coffee | 12 +++++ .../track_variant_override.js.coffee | 1 + .../services/variant_overrides.js.coffee | 27 ++++++---- .../admin/variant_overrides_controller.rb | 1 + app/models/model_set.rb | 11 +++-- app/models/variant_override_set.rb | 2 + .../variant_overrides/_products.html.haml | 10 ++++ .../_products_product.html.haml | 3 +- .../_products_variants.html.haml | 13 +++-- spec/features/admin/variant_overrides_spec.rb | 18 +++++-- ...ariant_overrides_controller_spec.js.coffee | 4 +- .../services/variant_overrides_spec.js.coffee | 49 +++++++++---------- 13 files changed, 107 insertions(+), 59 deletions(-) create mode 100644 app/assets/javascripts/admin/variant_overrides/directives/track_inheritance.js.coffee diff --git a/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee b/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee index ce0f8ac7d6..2ea1945421 100644 --- a/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee +++ b/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee @@ -9,13 +9,14 @@ angular.module("admin.variantOverrides").controller "AdminVariantOverridesCtrl", $scope.StatusMessage = StatusMessage $scope.columns = Columns.setColumns - producer: { name: "Producer", visible: true } - product: { name: "Product", visible: true } - sku: { name: "SKU", visible: false } - price: { name: "Price", visible: true } - on_hand: { name: "On Hand", visible: true } - on_demand: { name: "On Demand", visible: false } - reset: { name: "Reset Stock Level", visible: false } + producer: { name: "Producer", visible: true } + product: { name: "Product", visible: true } + sku: { name: "SKU", visible: false } + price: { name: "Price", visible: true } + on_hand: { name: "On Hand", visible: true } + on_demand: { name: "On Demand", visible: false } + reset: { name: "Reset Stock Level", visible: false } + inheritance: { name: "Inheritance", visible: false } $scope.resetSelectFilters = -> $scope.producerFilter = 0 diff --git a/app/assets/javascripts/admin/variant_overrides/directives/track_inheritance.js.coffee b/app/assets/javascripts/admin/variant_overrides/directives/track_inheritance.js.coffee new file mode 100644 index 0000000000..20ac08c035 --- /dev/null +++ b/app/assets/javascripts/admin/variant_overrides/directives/track_inheritance.js.coffee @@ -0,0 +1,12 @@ +angular.module("admin.variantOverrides").directive "trackInheritance", (VariantOverrides, DirtyVariantOverrides) -> + require: "ngModel" + link: (scope, element, attrs, ngModel) -> + # This is a bit hacky, but it allows us to load the inherit property on the VO, but then not submit it + scope.inherit = angular.equals scope.variantOverrides[scope.hub.id][scope.variant.id], VariantOverrides.newFor scope.hub.id, scope.variant.id + + ngModel.$parsers.push (viewValue) -> + if ngModel.$dirty && viewValue + variantOverride = VariantOverrides.inherit(scope.hub.id, scope.variant.id) + DirtyVariantOverrides.add variantOverride + scope.displayDirty() + viewValue diff --git a/app/assets/javascripts/admin/variant_overrides/directives/track_variant_override.js.coffee b/app/assets/javascripts/admin/variant_overrides/directives/track_variant_override.js.coffee index 944fdf4a94..919533967c 100644 --- a/app/assets/javascripts/admin/variant_overrides/directives/track_variant_override.js.coffee +++ b/app/assets/javascripts/admin/variant_overrides/directives/track_variant_override.js.coffee @@ -4,6 +4,7 @@ angular.module("admin.variantOverrides").directive "ofnTrackVariantOverride", (D ngModel.$parsers.push (viewValue) -> if ngModel.$dirty variantOverride = scope.variantOverrides[scope.hub.id][scope.variant.id] + scope.inherit = false DirtyVariantOverrides.add variantOverride scope.displayDirty() viewValue diff --git a/app/assets/javascripts/admin/variant_overrides/services/variant_overrides.js.coffee b/app/assets/javascripts/admin/variant_overrides/services/variant_overrides.js.coffee index 1a4a445d0e..7191ceebda 100644 --- a/app/assets/javascripts/admin/variant_overrides/services/variant_overrides.js.coffee +++ b/app/assets/javascripts/admin/variant_overrides/services/variant_overrides.js.coffee @@ -12,15 +12,24 @@ angular.module("admin.variantOverrides").factory "VariantOverrides", (variantOve @variantOverrides[hub.id] ||= {} for product in products for variant in product.variants - @variantOverrides[hub.id][variant.id] ||= - variant_id: variant.id - hub_id: hub.id - sku: null - price: null - count_on_hand: null - on_demand: null - default_stock: null - resettable: false + @inherit(hub.id, variant.id) unless @variantOverrides[hub.id][variant.id] + + inherit: (hub_id, variant_id) -> + # This method is called from the trackInheritance directive, to reinstate inheritance + @variantOverrides[hub_id][variant_id] ||= {} + angular.extend @variantOverrides[hub_id][variant_id], @newFor hub_id, variant_id + + newFor: (hub_id, variant_id) -> + # These properties need to match those checked in VariantOverrideSet.deletable? + hub_id: hub_id + variant_id: variant_id + sku: null + price: null + count_on_hand: null + on_demand: null + default_stock: null + resettable: false + updateIds: (updatedVos) -> for vo in updatedVos diff --git a/app/controllers/admin/variant_overrides_controller.rb b/app/controllers/admin/variant_overrides_controller.rb index e91d8f5dd7..8010a00a11 100644 --- a/app/controllers/admin/variant_overrides_controller.rb +++ b/app/controllers/admin/variant_overrides_controller.rb @@ -54,6 +54,7 @@ module Admin @hub_permissions = OpenFoodNetwork::Permissions.new(spree_current_user). variant_override_enterprises_per_hub + @variant_overrides = VariantOverride.for_hubs(@hubs) end diff --git a/app/models/model_set.rb b/app/models/model_set.rb index c9e1456f1a..0c0d156179 100644 --- a/app/models/model_set.rb +++ b/app/models/model_set.rb @@ -16,8 +16,8 @@ class ModelSet end end - def collection_attributes=(attributes) - attributes.each do |k, attributes| + def collection_attributes=(collection_attributes) + collection_attributes.each do |k, attributes| # attributes == {:id => 123, :next_collection_at => '...'} e = @collection.detect { |e| e.id.to_s == attributes[:id].to_s && !e.id.nil? } if e.nil? @@ -41,7 +41,11 @@ class ModelSet end def collection_to_delete - collection.select { |e| @delete_if.andand.call(e.attributes) } + # Remove all elements to be deleted from collection and return them + # Allows us to render @model_set.collection without deleted elements + deleted = [] + collection.delete_if { |e| deleted << e if @delete_if.andand.call(e.attributes) } + deleted end def collection_to_keep @@ -51,5 +55,4 @@ class ModelSet def persisted? false end - end diff --git a/app/models/variant_override_set.rb b/app/models/variant_override_set.rb index 54124983b5..730246cebe 100644 --- a/app/models/variant_override_set.rb +++ b/app/models/variant_override_set.rb @@ -3,6 +3,8 @@ class VariantOverrideSet < ModelSet super(VariantOverride, collection, attributes, nil, proc { |attrs| deletable?(attrs) } ) end + private + def deletable?(attrs) attrs['price'].blank? && attrs['count_on_hand'].blank? && diff --git a/app/views/admin/variant_overrides/_products.html.haml b/app/views/admin/variant_overrides/_products.html.haml index 6034695866..ed3354de9a 100644 --- a/app/views/admin/variant_overrides/_products.html.haml +++ b/app/views/admin/variant_overrides/_products.html.haml @@ -1,4 +1,13 @@ %table.index.bulk{ ng: {show: 'hub'}} + %col.producer{ width: "20%", ng: { show: 'columns.producer.visible' } } + %col.product{ width: "20%", ng: { show: 'columns.product.visible' } } + %col.sku{ width: "20%", ng: { show: 'columns.sku.visible' } } + %col.price{ width: "10%", ng: { show: 'columns.price.visible' } } + %col.on_hand{ width: "10%", ng: { show: 'columns.on_hand.visible' } } + %col.on_demand{ width: "10%", ng: { show: 'columns.on_demand.visible' } } + %col.reset{ width: "1%", ng: { show: 'columns.reset.visible' } } + %col.reset{ width: "15%", ng: { show: 'columns.reset.visible' } } + %col.inheritance{ width: "5%", ng: { show: 'columns.inheritance.visible' } } %thead %tr{ ng: { controller: "ColumnsCtrl" } } %th.producer{ ng: { show: 'columns.producer.visible' } } Producer @@ -8,6 +17,7 @@ %th.on_hand{ ng: { show: 'columns.on_hand.visible' } } On hand %th.on_demand{ ng: { show: 'columns.on_demand.visible' } } On Demand? %th.reset{ colspan: 2, ng: { show: 'columns.reset.visible' } } Enable Stock Level Reset? + %th.inheritance{ ng: { show: 'columns.inheritance.visible' } } Inherit? %tbody{bindonce: true, ng: {repeat: 'product in products | hubPermissions:hubPermissions:hub.id | attrFilter:{producer_id:producerFilter} | filter:query' } } = render 'admin/variant_overrides/products_product' = render 'admin/variant_overrides/products_variants' diff --git a/app/views/admin/variant_overrides/_products_product.html.haml b/app/views/admin/variant_overrides/_products_product.html.haml index 1bcf4cf016..b7cb11041b 100644 --- a/app/views/admin/variant_overrides/_products_product.html.haml +++ b/app/views/admin/variant_overrides/_products_product.html.haml @@ -5,4 +5,5 @@ %td.price{ ng: { show: 'columns.price.visible' } } %td.on_hand{ ng: { show: 'columns.on_hand.visible' } } %td.on_demand{ ng: { show: 'columns.on_demand.visible' } } - %td{colspan: 2} + %td.reset{ colspan: 2, ng: { show: 'columns.reset.visible' } } + %td.inheritance{ ng: { show: 'columns.inheritance.visible' } } diff --git a/app/views/admin/variant_overrides/_products_variants.html.haml b/app/views/admin/variant_overrides/_products_variants.html.haml index 7e441dbd64..87ec1709e4 100644 --- a/app/views/admin/variant_overrides/_products_variants.html.haml +++ b/app/views/admin/variant_overrides/_products_variants.html.haml @@ -8,13 +8,12 @@ %td.price{ ng: { show: 'columns.price.visible' } } %input{name: 'variant-overrides-{{ variant.id }}-price', type: 'text', ng: {model: 'variantOverrides[hub.id][variant.id].price'}, placeholder: '{{ variant.price }}', 'ofn-track-variant-override' => 'price'} %td.on_hand{ ng: { show: 'columns.on_hand.visible' } } - %input{name: 'variant-overrides-{{ variant.id }}-count_on_hand', type: 'text', ng: {model: 'variantOverrides[hub.id][variant.id].count_on_hand'}, placeholder: '{{ variant.on_hand }}', 'ofn-track-variant-override' => 'price'} + %input{name: 'variant-overrides-{{ variant.id }}-count_on_hand', type: 'text', ng: {model: 'variantOverrides[hub.id][variant.id].count_on_hand'}, placeholder: '{{ variant.on_hand }}', 'ofn-track-variant-override' => 'count_on_hand'} %td.on_demand{ ng: { show: 'columns.on_demand.visible' } } %input.field{ :type => 'checkbox', name: 'variant-overrides-{{ variant.id }}-on_demand', ng: { model: 'variantOverrides[hub.id][variant.id].on_demand' }, 'ofn-track-variant-override' => 'on_demand' } - %td - %input{name: 'variant-overrides-{{ variant.id }}-count-on-hand', type: 'text', ng: {model: 'variantOverrides[hub.id][variant.id].count_on_hand'}, placeholder: '{{ variant.on_hand }}', 'ofn-track-variant-override' => 'count_on_hand'} - - %td + %td.reset{ ng: { show: 'columns.reset.visible' } } %input{name: 'variant-overrides-{{ variant.id }}-resettable', type: 'checkbox', ng: {model: 'variantOverrides[hub.id][variant.id].resettable'}, placeholder: '{{ variant.resettable }}', 'ofn-track-variant-override' => 'resettable'} - %td - %input{name: 'variant-overrides-{{ variant.id }}-default-stock', type: 'text', ng: {model: 'variantOverrides[hub.id][variant.id].default_stock'}, placeholder: '{{ variant.default_stock ? variant.default_stock : "Default stock"}}', 'ofn-track-variant-override' => 'default_stock'} + %td.reset{ ng: { show: 'columns.reset.visible' } } + %input{name: 'variant-overrides-{{ variant.id }}-default_stock', type: 'text', ng: {model: 'variantOverrides[hub.id][variant.id].default_stock'}, placeholder: '{{ variant.default_stock ? variant.default_stock : "Default stock"}}', 'ofn-track-variant-override' => 'default_stock'} + %td.inheritance{ ng: { show: 'columns.inheritance.visible' } } + %input.field{ :type => 'checkbox', name: 'variant-overrides-{{ variant.id }}-inherit', ng: { model: 'inherit' }, 'track-inheritance' => true } diff --git a/spec/features/admin/variant_overrides_spec.rb b/spec/features/admin/variant_overrides_spec.rb index d2076ad470..508e924a43 100644 --- a/spec/features/admin/variant_overrides_spec.rb +++ b/spec/features/admin/variant_overrides_spec.rb @@ -55,11 +55,11 @@ feature %q{ it "displays the list of products with variants" do page.should have_table_row ['PRODUCER', 'PRODUCT', 'PRICE', 'ON HAND'] - page.should have_table_row [producer.name, product.name, '', '', ''] + page.should have_table_row [producer.name, product.name, '', ''] page.should have_input "variant-overrides-#{variant.id}-price", placeholder: '1.23' page.should have_input "variant-overrides-#{variant.id}-count_on_hand", placeholder: '12' - page.should have_table_row [producer_related.name, product_related.name, '', '', ''] + page.should have_table_row [producer_related.name, product_related.name, '', ''] page.should have_input "variant-overrides-#{variant_related.id}-price", placeholder: '2.34' page.should have_input "variant-overrides-#{variant_related.id}-count_on_hand", placeholder: '23' @@ -186,6 +186,9 @@ feature %q{ let!(:product2) { create(:simple_product, supplier: producer, variant_unit: 'weight', variant_unit_scale: 1) } let!(:variant2) { create(:variant, product: product2, unit_value: 8, price: 1.00, on_hand: 12) } let!(:vo_no_reset) { create(:variant_override, variant: variant2, hub: hub, price: 3.99, count_on_hand: 40, default_stock: 100, resettable: false) } + let!(:variant3) { create(:variant, product: product, unit_value: 2, price: 5.00, on_hand: 6) } + let!(:vo3) { create(:variant_override, variant: variant3, hub: hub, price: 6, count_on_hand: 7, sku: "SOMESKU", default_stock: 100, resettable: false) } + before do visit '/admin/variant_overrides' select2_select hub.name, from: 'hub_id' @@ -216,23 +219,30 @@ feature %q{ # Any new fields added to the VO model need to be added to this test it "deletes overrides when values are cleared" do first("div#columns-dropdown", :text => "COLUMNS").click - first("div#columns-dropdown div.menu div.menu_item", text: "SKU").click first("div#columns-dropdown div.menu div.menu_item", text: "On Demand").click first("div#columns-dropdown div.menu div.menu_item", text: "Reset Stock Level").click first("div#columns-dropdown", :text => "COLUMNS").click + # Clearing values manually fill_in "variant-overrides-#{variant.id}-price", with: '' fill_in "variant-overrides-#{variant.id}-count-on-hand", with: '' fill_in "variant-overrides-#{variant.id}-default-stock", with: '' page.uncheck "variant-overrides-#{variant.id}-resettable" page.should have_content "Changes to one override remain unsaved." + # Clearing values by 'inheriting' + first("div#columns-dropdown", :text => "COLUMNS").click + first("div#columns-dropdown div.menu div.menu_item", text: "Inheritance").click + first("div#columns-dropdown", :text => "COLUMNS").click + page.check "variant-overrides-#{variant3.id}-inherit" + expect do click_button 'Save Changes' page.should have_content "Changes saved." - end.to change(VariantOverride, :count).by(-1) + end.to change(VariantOverride, :count).by(-2) VariantOverride.where(id: vo.id).should be_empty + VariantOverride.where(id: vo3.id).should be_empty end it "resets stock to defaults" do diff --git a/spec/javascripts/unit/admin/controllers/variant_overrides_controller_spec.js.coffee b/spec/javascripts/unit/admin/controllers/variant_overrides_controller_spec.js.coffee index e75cf51692..44922e4d21 100644 --- a/spec/javascripts/unit/admin/controllers/variant_overrides_controller_spec.js.coffee +++ b/spec/javascripts/unit/admin/controllers/variant_overrides_controller_spec.js.coffee @@ -21,11 +21,11 @@ describe "VariantOverridesCtrl", -> null scope = {} - inject ($controller, Indexer, _VariantOverrides_, _DirtyVariantOverrides_, _StatusMessage_) -> + inject ($controller, _VariantOverrides_, _DirtyVariantOverrides_, _StatusMessage_) -> VariantOverrides = _VariantOverrides_ DirtyVariantOverrides = _DirtyVariantOverrides_ StatusMessage = _StatusMessage_ - ctrl = $controller 'AdminVariantOverridesCtrl', {$scope: scope, hubs: hubs, producers: producers, products: products, hubPermissions: hubPermissions, VariantOverrides: _VariantOverrides_, DirtyVariantOverrides: _DirtyVariantOverrides_, StatusMessage: _StatusMessage_} + ctrl = $controller 'AdminVariantOverridesCtrl', { $scope: scope, hubs: hubs, producers: producers, products: products, hubPermissions: hubPermissions, VariantOverrides: VariantOverrides, DirtyVariantOverrides: DirtyVariantOverrides, StatusMessage: StatusMessage} it "initialises the hub list and the chosen hub", -> expect(scope.hubs).toEqual { 1: {id: 1, name: 'Hub'} } diff --git a/spec/javascripts/unit/admin/services/variant_overrides_spec.js.coffee b/spec/javascripts/unit/admin/services/variant_overrides_spec.js.coffee index 9dcae28a94..c596b95ae9 100644 --- a/spec/javascripts/unit/admin/services/variant_overrides_spec.js.coffee +++ b/spec/javascripts/unit/admin/services/variant_overrides_spec.js.coffee @@ -1,9 +1,9 @@ describe "VariantOverrides service", -> VariantOverrides = $httpBackend = null variantOverrides = [ - {id: 1, hub_id: 10, variant_id: 100, price: 1, count_on_hand: 1, default_stock: '', resettable: false} - {id: 2, hub_id: 10, variant_id: 200, price: 2, count_on_hand: 2, default_stock: '', resettable: false} - {id: 3, hub_id: 20, variant_id: 300, price: 3, count_on_hand: 3, default_stock: '', resettable: false} + {id: 1, hub_id: 10, variant_id: 100, sku: "V100", price: 1, count_on_hand: 1, on_demand: null, default_stock: null, resettable: false } + {id: 2, hub_id: 10, variant_id: 200, sku: "V200", price: 2, count_on_hand: 2, on_demand: null, default_stock: null, resettable: false} + {id: 3, hub_id: 20, variant_id: 300, sku: "V300", price: 3, count_on_hand: 3, on_demand: null, default_stock: null, resettable: false} ] beforeEach -> @@ -19,10 +19,10 @@ describe "VariantOverrides service", -> it "indexes variant overrides by hub_id -> variant_id", -> expect(VariantOverrides.variantOverrides).toEqual 10: - 100: {id: 1, hub_id: 10, variant_id: 100, price: 1, count_on_hand: 1, default_stock: '', resettable: false} - 200: {id: 2, hub_id: 10, variant_id: 200, price: 2, count_on_hand: 2, default_stock: '', resettable: false} + 100: {id: 1, hub_id: 10, variant_id: 100, sku: "V100", price: 1, count_on_hand: 1, on_demand: null, default_stock: null, resettable: false } + 200: {id: 2, hub_id: 10, variant_id: 200, sku: "V200", price: 2, count_on_hand: 2, on_demand: null, default_stock: null, resettable: false } 20: - 300: {id: 3, hub_id: 20, variant_id: 300, price: 3, count_on_hand: 3, default_stock: '', resettable: false} + 300: {id: 3, hub_id: 20, variant_id: 300, sku: "V300", price: 3, count_on_hand: 3, on_demand: null, default_stock: null, resettable: false } it "ensures blank data available for some products", -> hubs = [{id: 10}, {id: 20}, {id: 30}] @@ -33,25 +33,24 @@ describe "VariantOverrides service", -> } ] VariantOverrides.ensureDataFor hubs, products - expect(VariantOverrides.variantOverrides).toEqual - 10: - 100: {id: 1, hub_id: 10, variant_id: 100, price: 1, count_on_hand: 1, default_stock: '', resettable: false} - 200: {id: 2, hub_id: 10, variant_id: 200, price: 2, count_on_hand: 2, default_stock: '', resettable: false} - 300: { hub_id: 10, variant_id: 300, price: '', count_on_hand: '', default_stock: '', resettable: false} - 400: { hub_id: 10, variant_id: 400, price: '', count_on_hand: '', default_stock: '', resettable: false} - 500: { hub_id: 10, variant_id: 500, price: '', count_on_hand: '', default_stock: '', resettable: false} - 20: - 100: { hub_id: 20, variant_id: 100, price: '', count_on_hand: '', default_stock: '', resettable: false} - 200: { hub_id: 20, variant_id: 200, price: '', count_on_hand: '', default_stock: '', resettable: false} - 300: {id: 3, hub_id: 20, variant_id: 300, price: 3, count_on_hand: 3, default_stock: '', resettable: false} - 400: { hub_id: 20, variant_id: 400, price: '', count_on_hand: '', default_stock: '', resettable: false} - 500: { hub_id: 20, variant_id: 500, price: '', count_on_hand: '', default_stock: '', resettable: false} - 30: - 100: { hub_id: 30, variant_id: 100, price: '', count_on_hand: '', default_stock: '', resettable: false} - 200: { hub_id: 30, variant_id: 200, price: '', count_on_hand: '', default_stock: '', resettable: false} - 300: { hub_id: 30, variant_id: 300, price: '', count_on_hand: '', default_stock: '', resettable: false} - 400: { hub_id: 30, variant_id: 400, price: '', count_on_hand: '', default_stock: '', resettable: false} - 500: { hub_id: 30, variant_id: 500, price: '', count_on_hand: '', default_stock: '', resettable: false} + expect(VariantOverrides.variantOverrides[10]).toEqual + 100: { id: 1, hub_id: 10, variant_id: 100, sku: "V100", price: 1, count_on_hand: 1, on_demand: null, default_stock: null, resettable: false } + 200: { id: 2, hub_id: 10, variant_id: 200, sku: "V200", price: 2, count_on_hand: 2, on_demand: null, default_stock: null, resettable: false } + 300: { hub_id: 10, variant_id: 300, sku: null, price: null, count_on_hand: null, on_demand: null, default_stock: null, resettable: false } + 400: { hub_id: 10, variant_id: 400, sku: null, price: null, count_on_hand: null, on_demand: null, default_stock: null, resettable: false } + 500: { hub_id: 10, variant_id: 500, sku: null, price: null, count_on_hand: null, on_demand: null, default_stock: null, resettable: false } + expect(VariantOverrides.variantOverrides[20]).toEqual + 100: { hub_id: 20, variant_id: 100, sku: null, price: null, count_on_hand: null, on_demand: null, default_stock: null, resettable: false } + 200: { hub_id: 20, variant_id: 200, sku: null, price: null, count_on_hand: null, on_demand: null, default_stock: null, resettable: false } + 300: { id: 3, hub_id: 20, variant_id: 300, sku: "V300", price: 3, count_on_hand: 3, on_demand: null, default_stock: null, resettable: false } + 400: { hub_id: 20, variant_id: 400, sku: null, price: null, count_on_hand: null, on_demand: null, default_stock: null, resettable: false } + 500: { hub_id: 20, variant_id: 500, sku: null, price: null, count_on_hand: null, on_demand: null, default_stock: null, resettable: false } + expect(VariantOverrides.variantOverrides[30]).toEqual + 100: { hub_id: 30, variant_id: 100, sku: null, price: null, count_on_hand: null, on_demand: null, default_stock: null, resettable: false } + 200: { hub_id: 30, variant_id: 200, sku: null, price: null, count_on_hand: null, on_demand: null, default_stock: null, resettable: false } + 300: { hub_id: 30, variant_id: 300, sku: null, price: null, count_on_hand: null, on_demand: null, default_stock: null, resettable: false } + 400: { hub_id: 30, variant_id: 400, sku: null, price: null, count_on_hand: null, on_demand: null, default_stock: null, resettable: false } + 500: { hub_id: 30, variant_id: 500, sku: null, price: null, count_on_hand: null, on_demand: null, default_stock: null, resettable: false } it "updates the IDs of variant overrides", -> VariantOverrides.variantOverrides[2] = {} From 4103ed0ba747c3232206e7bed5ec5716e8d815f8 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Tue, 22 Dec 2015 12:28:10 +1100 Subject: [PATCH 35/43] Combining variant override controller specs --- .../variant_overrides_controller_spec.rb | 53 ++++++++++++- .../admin/variant_overrides_spec.rb | 76 ------------------- 2 files changed, 51 insertions(+), 78 deletions(-) delete mode 100644 spec/controllers/admin/variant_overrides_spec.rb diff --git a/spec/controllers/admin/variant_overrides_controller_spec.rb b/spec/controllers/admin/variant_overrides_controller_spec.rb index 022a605a53..2300c38490 100644 --- a/spec/controllers/admin/variant_overrides_controller_spec.rb +++ b/spec/controllers/admin/variant_overrides_controller_spec.rb @@ -16,7 +16,7 @@ describe Admin::VariantOverridesController, type: :controller do before do user = create(:user) user.owned_enterprises << create(:enterprise) - controller.stub spree_current_user: user + allow(controller).to receive(:spree_current_user) { user } end it "redirects to unauthorized" do @@ -27,7 +27,7 @@ describe Admin::VariantOverridesController, type: :controller do context "where I manage the variant override hub" do before do - controller.stub spree_current_user: hub.owner + allow(controller).to receive(:spree_current_user) { hub.owner } end context "but the producer has not granted VO permission" do @@ -63,4 +63,53 @@ describe Admin::VariantOverridesController, type: :controller do end end end + + describe "bulk_reset" do + context "json" do + let(:format) { :json } + + let(:hub) { create(:distributor_enterprise) } + let(:producer) { create(:supplier_enterprise) } + let(:product) { create(:product, supplier: producer) } + let(:variant1) { create(:variant, product: product) } + let(:variant2) { create(:variant, product: product) } + let!(:variant_override1) { create(:variant_override, hub: hub, variant: variant1, count_on_hand: 5, default_stock: 7, resettable: true) } + let!(:variant_override2) { create(:variant_override, hub: hub, variant: variant2, count_on_hand: 2, default_stock: 1, resettable: false) } + + before do + allow(controller).to receive(:spree_current_user) { hub.owner } + end + + context "where the producer has not granted create_variant_overrides permission to the hub" do + let(:params) { { format: format, variant_overrides: [ { id: variant_override1.id } ] } } + + it "restricts access" do + spree_put :bulk_reset, params + expect(response).to redirect_to spree.unauthorized_path + end + end + + context "where the producer has granted create_variant_overrides permission to the hub" do + let!(:er1) { create(:enterprise_relationship, parent: producer, child: hub, permissions_list: [:create_variant_overrides]) } + + context "where reset is enabled" do + let(:params) { { format: format, variant_overrides: [ { id: variant_override1.id } ] } } + + it "updates stock to default values" do + spree_put :bulk_reset, params + expect(variant_override1.reload.count_on_hand).to eq 7 + end + end + + context "where reset is disabled" do + let(:params) { { format: format, variant_overrides: [ { id: variant_override2.id } ] } } + + it "doesn't update on_hand" do + spree_put :bulk_reset, params + expect(variant_override2.reload.count_on_hand).to eq 2 + end + end + end + end + end end diff --git a/spec/controllers/admin/variant_overrides_spec.rb b/spec/controllers/admin/variant_overrides_spec.rb deleted file mode 100644 index 2eb887b961..0000000000 --- a/spec/controllers/admin/variant_overrides_spec.rb +++ /dev/null @@ -1,76 +0,0 @@ -require 'spec_helper' - -module Admin - describe VariantOverridesController, type: :controller do - include AuthenticationWorkflow - let!(:hub_owner) { create :user, enterprise_limit: 2 } - let!(:v1) { create(:variant) } - let!(:v2) { create(:variant) } - let!(:vo1) { create(:variant_override, hub: hub, variant: v1, price: "6.0", count_on_hand: 5, default_stock: 7, resettable: true) } - let!(:vo2) { create(:variant_override, hub: hub, variant: v2, price: "6.0", count_on_hand: 2, default_stock: 1, resettable: false) } - - before do - controller.stub spree_current_user: hub_owner - end - - describe "bulk_update" do - let!(:hub) { create(:distributor_enterprise, owner: hub_owner) } - let(:params) { { variant_overrides: [{id: vo1.id, price: "10.0"}, {id: vo2.id, default_stock: 12 }] } } - - context "where the producer has not granted create_variant_overrides permission to the hub" do - it "restricts access" do - spree_put :bulk_update, params - expect(response).to redirect_to spree.unauthorized_path - end - end - - context "where the producer has granted create_variant_overrides permission to the hub" do - let!(:er1) { create(:enterprise_relationship, parent: v1.product.supplier, child: hub, permissions_list: [:create_variant_overrides]) } - - it "updates the overrides correctly" do - spree_put :bulk_update, params - vo1.reload.price.should eq 10 - vo2.reload.default_stock.should eq 12 - end - end - end - - describe "bulk_reset" do - let!(:hub) { create(:distributor_enterprise, owner: hub_owner) } - - before do - controller.stub spree_current_user: hub.owner - end - - context "where the producer has not granted create_variant_overrides permission to the hub" do - let(:params) { { variant_overrides: [ { id: vo1 } ] } } - - it "restricts access" do - spree_put :bulk_reset, params - expect(response).to redirect_to spree.unauthorized_path - end - end - - context "where the producer has granted create_variant_overrides permission to the hub" do - let!(:er1) { create(:enterprise_relationship, parent: v1.product.supplier, child: hub, permissions_list: [:create_variant_overrides]) } - - context "where reset is enabled" do - let(:params) { { variant_overrides: [ { id: vo1 } ] } } - - it "updates stock to default values" do - spree_put :bulk_reset, params - expect(vo1.reload.count_on_hand).to eq 7 - end - end - - context "where reset is disabled" do - let(:params) { { variant_overrides: [ { id: vo2 } ] } } - it "doesn't update on_hand" do - spree_put :bulk_reset, params - expect(vo2.reload.count_on_hand).to eq 2 - end - end - end - end - end -end From ecf1aac5cbd6253178a4bdf5765a4ed5c3047077 Mon Sep 17 00:00:00 2001 From: stveep Date: Wed, 30 Dec 2015 17:43:09 -0500 Subject: [PATCH 36/43] Added failure message to VO reset --- .../controllers/variant_overrides_controller.js.coffee | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee b/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee index 2ea1945421..9b0ed4374e 100644 --- a/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee +++ b/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee @@ -93,4 +93,6 @@ angular.module("admin.variantOverrides").controller "AdminVariantOverridesCtrl", VariantOverrides.resetStock() .success (updatedVos) -> VariantOverrides.updateData updatedVos - $timeout -> StatusMessage.display 'success', 'Stocks reset to defaults.' + StatusMessage.display 'success', 'Stocks reset to defaults.' + .error (data, status) -> + $timeout -> StatusMessage.display 'failure', $scope.updateError(data, status) From 669642292bdb6b82d13b407547017b039f00c79c Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Wed, 13 Jan 2016 16:10:25 +1100 Subject: [PATCH 37/43] Refactoring VariantOverridesController#bulk_reset to only reset VOs for a specified hub --- .../variant_overrides_controller.js.coffee | 8 ++- .../services/variant_overrides.js.coffee | 11 +--- .../admin/variant_overrides_controller.rb | 30 +++++++---- app/models/variant_override.rb | 9 ---- db/schema.rb | 4 +- .../variant_overrides_controller_spec.rb | 54 +++++++++++++------ ...ariant_overrides_controller_spec.js.coffee | 27 ++++++---- .../services/variant_overrides_spec.js.coffee | 5 -- 8 files changed, 82 insertions(+), 66 deletions(-) diff --git a/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee b/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee index 9b0ed4374e..b65df80d66 100644 --- a/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee +++ b/app/assets/javascripts/admin/variant_overrides/controllers/variant_overrides_controller.js.coffee @@ -1,4 +1,4 @@ -angular.module("admin.variantOverrides").controller "AdminVariantOverridesCtrl", ($scope, $timeout, Indexer, Columns, SpreeApiAuth, PagedFetcher, StatusMessage, hubs, producers, hubPermissions, VariantOverrides, DirtyVariantOverrides) -> +angular.module("admin.variantOverrides").controller "AdminVariantOverridesCtrl", ($scope, $http, $timeout, Indexer, Columns, SpreeApiAuth, PagedFetcher, StatusMessage, hubs, producers, hubPermissions, VariantOverrides, DirtyVariantOverrides) -> $scope.hubs = Indexer.index hubs $scope.hub = null $scope.products = [] @@ -89,8 +89,12 @@ angular.module("admin.variantOverrides").controller "AdminVariantOverridesCtrl", $scope.displayDirty() , 3000 # 3 second delay else + return unless $scope.hub_id? StatusMessage.display 'progress', 'Changing on hand stock levels...' - VariantOverrides.resetStock() + $http + method: "POST" + url: "/admin/variant_overrides/bulk_reset" + data: { hub_id: $scope.hub_id } .success (updatedVos) -> VariantOverrides.updateData updatedVos StatusMessage.display 'success', 'Stocks reset to defaults.' diff --git a/app/assets/javascripts/admin/variant_overrides/services/variant_overrides.js.coffee b/app/assets/javascripts/admin/variant_overrides/services/variant_overrides.js.coffee index 7191ceebda..4e1128572e 100644 --- a/app/assets/javascripts/admin/variant_overrides/services/variant_overrides.js.coffee +++ b/app/assets/javascripts/admin/variant_overrides/services/variant_overrides.js.coffee @@ -1,4 +1,5 @@ -angular.module("admin.variantOverrides").factory "VariantOverrides", (variantOverrides, $http) -> + +angular.module("admin.variantOverrides").factory "VariantOverrides", (variantOverrides) -> new class VariantOverrides variantOverrides: {} @@ -30,18 +31,10 @@ angular.module("admin.variantOverrides").factory "VariantOverrides", (variantOve default_stock: null resettable: false - updateIds: (updatedVos) -> for vo in updatedVos @variantOverrides[vo.hub_id][vo.variant_id].id = vo.id - resetStock: -> - $http - method: "POST" - url: "/admin/variant_overrides/bulk_reset" - data: - variant_overrides: variantOverrides - updateData: (updatedVos) -> for vo in updatedVos @variantOverrides[vo.hub_id][vo.variant_id] = vo diff --git a/app/controllers/admin/variant_overrides_controller.rb b/app/controllers/admin/variant_overrides_controller.rb index 8010a00a11..c886f80652 100644 --- a/app/controllers/admin/variant_overrides_controller.rb +++ b/app/controllers/admin/variant_overrides_controller.rb @@ -4,9 +4,10 @@ module Admin class VariantOverridesController < ResourceController include OpenFoodNetwork::SpreeApiKeyLoader + prepend_before_filter :load_data + before_filter :load_collection, only: [:bulk_update] before_filter :load_spree_api_key, only: :index - before_filter :load_data - before_filter :load_collection, only: [:bulk_update, :bulk_reset] + def index end @@ -30,14 +31,13 @@ module Admin def bulk_reset # Ensure we're authorised to update all variant overrides. - @vo_set.collection.each { |vo| authorize! :bulk_reset, vo } + @collection.each { |vo| authorize! :bulk_reset, vo } + @collection.each(&:reset_stock!) - # Changed this to use class method instead, to ensure the value in the database is used to reset and not a dirty passed-in value - #vo_set.collection.map! { |vo| vo = vo.reset_stock! } - @vo_set.collection.map! { |vo| VariantOverride.reset_stock!(vo.hub,vo.variant) } - render json: @vo_set.collection, each_serializer: Api::Admin::VariantOverrideSerializer - if @vo_set.errors.present? - render json: { errors: @vo_set.errors }, status: 400 + if collection_errors.present? + render json: { errors: collection_errors }, status: 400 + else + render json: @collection, each_serializer: Api::Admin::VariantOverrideSerializer end end @@ -54,8 +54,6 @@ module Admin @hub_permissions = OpenFoodNetwork::Permissions.new(spree_current_user). variant_override_enterprises_per_hub - - @variant_overrides = VariantOverride.for_hubs(@hubs) end def load_collection @@ -64,10 +62,20 @@ module Admin end def collection + @variant_overrides = VariantOverride.for_hubs(params[:hub_id] || @hubs) end def collection_actions [:index, :bulk_update, :bulk_reset] end + + # This has been pulled from ModelSet as it is useful for compiling a list of errors on any generic collection (not necessarily a ModelSet) + # Could be pulled down into a lower level controller if it is useful in other high level controllers + def collection_errors + errors = ActiveModel::Errors.new self + full_messages = @collection.map { |element| element.errors.full_messages }.flatten + full_messages.each { |fm| errors.add(:base, fm) } + errors + end end end diff --git a/app/models/variant_override.rb b/app/models/variant_override.rb index ec3adebdaf..21820ce0db 100644 --- a/app/models/variant_override.rb +++ b/app/models/variant_override.rb @@ -67,15 +67,6 @@ class VariantOverride < ActiveRecord::Base self end - def self.reset_stock!(hub, variant) - vo = self.for(hub, variant) - if vo.nil? - Bugsnag.notify RuntimeError.new "Attempting to reset stock level for a variant without a VariantOverride." - else - vo.reset_stock! - end - end - private def self.for(hub, variant) diff --git a/db/schema.rb b/db/schema.rb index 08cc2bb643..465530b949 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -1159,10 +1159,10 @@ ActiveRecord::Schema.define(:version => 20151128185900) do t.integer "hub_id", :null => false t.decimal "price", :precision => 8, :scale => 2 t.integer "count_on_hand" - t.string "sku" - t.boolean "on_demand" t.integer "default_stock" t.boolean "resettable" + t.string "sku" + t.boolean "on_demand" end add_index "variant_overrides", ["variant_id", "hub_id"], :name => "index_variant_overrides_on_variant_id_and_hub_id" diff --git a/spec/controllers/admin/variant_overrides_controller_spec.rb b/spec/controllers/admin/variant_overrides_controller_spec.rb index 2300c38490..d796f2d52f 100644 --- a/spec/controllers/admin/variant_overrides_controller_spec.rb +++ b/spec/controllers/admin/variant_overrides_controller_spec.rb @@ -76,37 +76,57 @@ describe Admin::VariantOverridesController, type: :controller do let!(:variant_override1) { create(:variant_override, hub: hub, variant: variant1, count_on_hand: 5, default_stock: 7, resettable: true) } let!(:variant_override2) { create(:variant_override, hub: hub, variant: variant2, count_on_hand: 2, default_stock: 1, resettable: false) } - before do - allow(controller).to receive(:spree_current_user) { hub.owner } - end + let(:params) { { format: format, hub_id: hub.id } } - context "where the producer has not granted create_variant_overrides permission to the hub" do - let(:params) { { format: format, variant_overrides: [ { id: variant_override1.id } ] } } + context "where I don't manage the variant override hub" do + before do + user = create(:user) + user.owned_enterprises << create(:enterprise) + allow(controller).to receive(:spree_current_user) { user } + end - it "restricts access" do + it "redirects to unauthorized" do spree_put :bulk_reset, params expect(response).to redirect_to spree.unauthorized_path end end - context "where the producer has granted create_variant_overrides permission to the hub" do - let!(:er1) { create(:enterprise_relationship, parent: producer, child: hub, permissions_list: [:create_variant_overrides]) } + context "where I manage the variant override hub" do + before do + allow(controller).to receive(:spree_current_user) { hub.owner } + end - context "where reset is enabled" do - let(:params) { { format: format, variant_overrides: [ { id: variant_override1.id } ] } } - - it "updates stock to default values" do + context "where the producer has not granted create_variant_overrides permission to the hub" do + it "restricts access" do spree_put :bulk_reset, params - expect(variant_override1.reload.count_on_hand).to eq 7 + expect(response).to redirect_to spree.unauthorized_path end end - context "where reset is disabled" do - let(:params) { { format: format, variant_overrides: [ { id: variant_override2.id } ] } } + context "where the producer has granted create_variant_overrides permission to the hub" do + let!(:er1) { create(:enterprise_relationship, parent: producer, child: hub, permissions_list: [:create_variant_overrides]) } - it "doesn't update on_hand" do + it "updates stock to default values where reset is enabled" do + expect(variant_override1.reload.count_on_hand).to eq 5 # reset enabled + expect(variant_override2.reload.count_on_hand).to eq 2 # reset disabled spree_put :bulk_reset, params - expect(variant_override2.reload.count_on_hand).to eq 2 + expect(variant_override1.reload.count_on_hand).to eq 7 # reset enabled + expect(variant_override2.reload.count_on_hand).to eq 2 # reset disabled + end + + context "and the producer has granted create_variant_overrides permission to another hub I manage" do + before { hub.owner.update_attribute(:enterprise_limit, 2) } + let(:hub2) { create(:distributor_enterprise, owner: hub.owner) } + let(:product) { create(:product, supplier: producer) } + let(:variant3) { create(:variant, product: product) } + let!(:variant_override3) { create(:variant_override, hub: hub2, variant: variant3, count_on_hand: 1, default_stock: 13, resettable: true) } + let!(:er2) { create(:enterprise_relationship, parent: producer, child: hub2, permissions_list: [:create_variant_overrides]) } + + it "does not reset count_on_hand for variant_overrides not in params" do + expect { + spree_put :bulk_reset, params + }.to_not change{variant_override3.reload.count_on_hand} + end end end end diff --git a/spec/javascripts/unit/admin/controllers/variant_overrides_controller_spec.js.coffee b/spec/javascripts/unit/admin/controllers/variant_overrides_controller_spec.js.coffee index 44922e4d21..699e1bc4ab 100644 --- a/spec/javascripts/unit/admin/controllers/variant_overrides_controller_spec.js.coffee +++ b/spec/javascripts/unit/admin/controllers/variant_overrides_controller_spec.js.coffee @@ -1,6 +1,6 @@ describe "VariantOverridesCtrl", -> ctrl = null - scope = null + scope = {} hubs = [{id: 1, name: 'Hub'}] producers = [{id: 2, name: 'Producer'}] products = [{id: 1, name: 'Product'}] @@ -19,7 +19,6 @@ describe "VariantOverridesCtrl", -> $provide.value 'variantOverrides', variantOverrides $provide.value 'dirtyVariantOverrides', dirtyVariantOverrides null - scope = {} inject ($controller, _VariantOverrides_, _DirtyVariantOverrides_, _StatusMessage_) -> VariantOverrides = _VariantOverrides_ @@ -69,13 +68,19 @@ describe "VariantOverridesCtrl", -> describe "setting stock to defaults", -> it "prompts to save changes if there are any pending", -> - spyOn(VariantOverrides,"resetStock") + spyOn(StatusMessage, "display") DirtyVariantOverrides.add {hub_id: 1, variant_id: 1} - scope.resetStock - #expect(scope.StatusMessage.statusMessage.text).toMatch "changes" - expect(VariantOverrides.resetStock).not.toHaveBeenCalled - it "updates and refreshes on hand value for variant overrides with a default stock level", -> - spyOn(VariantOverrides,"resetStock") - scope.resetStock - expect(VariantOverrides.resetStock).toHaveBeenCalled - #expect(scope.StatusMessage.statusMessage.text).toMatch "defaults" + scope.resetStock() + expect(StatusMessage.display).toHaveBeenCalledWith 'alert', 'Save changes first.' + + it "updates and refreshes on hand value for variant overrides with a default stock level", inject ($httpBackend) -> + scope.hub_id = 123 + variant_overrides_mock = "mock object" + spyOn(StatusMessage, "display") + spyOn(VariantOverrides, "updateData") + $httpBackend.expectPOST("/admin/variant_overrides/bulk_reset", hub_id: 123).respond 200, variant_overrides_mock + scope.resetStock() + expect(StatusMessage.display).toHaveBeenCalledWith 'progress', 'Changing on hand stock levels...' + $httpBackend.flush() + expect(VariantOverrides.updateData).toHaveBeenCalledWith variant_overrides_mock + expect(StatusMessage.display).toHaveBeenCalledWith 'success', 'Stocks reset to defaults.' diff --git a/spec/javascripts/unit/admin/services/variant_overrides_spec.js.coffee b/spec/javascripts/unit/admin/services/variant_overrides_spec.js.coffee index c596b95ae9..73dbdabee8 100644 --- a/spec/javascripts/unit/admin/services/variant_overrides_spec.js.coffee +++ b/spec/javascripts/unit/admin/services/variant_overrides_spec.js.coffee @@ -67,11 +67,6 @@ describe "VariantOverrides service", -> expect(VariantOverrides.variantOverrides[2][3].id).toEqual 1 expect(VariantOverrides.variantOverrides[2][8].id).toEqual 6 - it "sends an HTTP request to reset stock", -> - $httpBackend.expectPOST("/admin/variant_overrides/bulk_reset", variant_overrides: variantOverrides).respond 200 - VariantOverrides.resetStock variantOverrides - $httpBackend.flush() - it "updates the variant overrides on the page with new data", -> VariantOverrides.variantOverrides[1] = 3: {id: 1, hub_id: 1, variant_id: 3, price: "4.0", count_on_hand: 5, default_stock: 3, resettable: true} From 9979e31220490ee831abb740140c1dfb83475763 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Wed, 13 Jan 2016 22:51:40 +1100 Subject: [PATCH 38/43] Final tidy up after rebasing default_inventory and ng-vo onto origin/master Fixes a few VO feature specs and a few interface tweaks --- app/views/admin/variant_overrides/_actions.html.haml | 5 ----- app/views/admin/variant_overrides/index.html.haml | 7 ++++--- spec/features/admin/variant_overrides_spec.rb | 11 ++++------- 3 files changed, 8 insertions(+), 15 deletions(-) delete mode 100644 app/views/admin/variant_overrides/_actions.html.haml diff --git a/app/views/admin/variant_overrides/_actions.html.haml b/app/views/admin/variant_overrides/_actions.html.haml deleted file mode 100644 index 39e4cd9baa..0000000000 --- a/app/views/admin/variant_overrides/_actions.html.haml +++ /dev/null @@ -1,5 +0,0 @@ -.row - %input.four.columns.alpha{type: 'button', value: 'Save Changes', 'ng-click' => 'update()'} - %input.four.columns.alpha{type: 'button', value: 'Reset Stock to Defaults', 'ng-click' => 'resetStock()'} - .twelve.columns.omega - = render 'spree/admin/shared/status_message' diff --git a/app/views/admin/variant_overrides/index.html.haml b/app/views/admin/variant_overrides/index.html.haml index 96fef5307d..9027445e62 100644 --- a/app/views/admin/variant_overrides/index.html.haml +++ b/app/views/admin/variant_overrides/index.html.haml @@ -3,9 +3,10 @@ %div{ ng: { app: 'admin.variantOverrides', controller: 'AdminVariantOverridesCtrl', init: 'initialise()' } } = render 'admin/variant_overrides/filters' - %hr.divider.sixteen.columns.alpha.omega - .controls.sixteen.columns.alpha.omega - %div.thirteen.columns.alpha   + %hr.divider.sixteen.columns.alpha.omega{ ng: { show: 'hub' } } + .controls.sixteen.columns.alpha.omega{ ng: { show: 'hub' } } + %input.four.columns.alpha{ type: 'button', value: 'Reset Stock to Defaults', 'ng-click' => 'resetStock()' } + %div.nine.columns.alpha   = render 'admin/shared/columns_dropdown' %form{ name: 'variant_overrides_form' } diff --git a/spec/features/admin/variant_overrides_spec.rb b/spec/features/admin/variant_overrides_spec.rb index 508e924a43..378afa3626 100644 --- a/spec/features/admin/variant_overrides_spec.rb +++ b/spec/features/admin/variant_overrides_spec.rb @@ -225,8 +225,8 @@ feature %q{ # Clearing values manually fill_in "variant-overrides-#{variant.id}-price", with: '' - fill_in "variant-overrides-#{variant.id}-count-on-hand", with: '' - fill_in "variant-overrides-#{variant.id}-default-stock", with: '' + fill_in "variant-overrides-#{variant.id}-count_on_hand", with: '' + fill_in "variant-overrides-#{variant.id}-default_stock", with: '' page.uncheck "variant-overrides-#{variant.id}-resettable" page.should have_content "Changes to one override remain unsaved." @@ -249,25 +249,22 @@ feature %q{ click_button 'Reset Stock to Defaults' page.should have_content 'Stocks reset to defaults.' vo.reload - page.should have_input "variant-overrides-#{variant.id}-count-on-hand", with: '1000', placeholder: '12' + page.should have_input "variant-overrides-#{variant.id}-count_on_hand", with: '1000', placeholder: '12' vo.count_on_hand.should == 1000 end it "doesn't reset stock levels if the behaviour is disabled" do click_button 'Reset Stock to Defaults' vo_no_reset.reload - page.should have_input "variant-overrides-#{variant2.id}-count-on-hand", with: '40', placeholder: '12' + page.should have_input "variant-overrides-#{variant2.id}-count_on_hand", with: '40', placeholder: '12' vo_no_reset.count_on_hand.should == 40 end - it "prompts to save changes before reset if any are pending" do fill_in "variant-overrides-#{variant.id}-price", with: '200' click_button 'Reset Stock to Defaults' page.should have_content "Save changes first" end - - end end end From f68f7ea2b6f32dd4bc40195accbe39d42f35c992 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Wed, 6 Jan 2016 13:50:07 +1100 Subject: [PATCH 39/43] Fix display of "Total" --- app/views/spree/shared/_order_details.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/spree/shared/_order_details.html.haml b/app/views/spree/shared/_order_details.html.haml index 8be8d3cf50..d0a7e99ddf 100644 --- a/app/views/spree/shared/_order_details.html.haml +++ b/app/views/spree/shared/_order_details.html.haml @@ -140,7 +140,7 @@ %tr.total %td.text-right{colspan: "3"} %h5 - = t :order_produce + = t :order_total_price %td.text-right.total %h5#order_total= order.display_total.to_html From aea766327c426df3cb53dba5c3bd5d53f08bed9c Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Sun, 10 Jan 2016 10:42:33 +1100 Subject: [PATCH 40/43] Add say_no and say_yes to locale --- config/locales/en.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/locales/en.yml b/config/locales/en.yml index 701d758891..76f0c124b3 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -52,6 +52,8 @@ en: free: "free" plus_tax: "plus GST" total_monthly_bill_incl_tax: "Total Monthly Bill (Incl. Tax)" + say_no: "No" + say_yes: "Yes" sort_order_cycles_on_shopfront_by: "Sort Order Cycles On Shopfront By" From a611e73bed32d68d8a189f9facf72d020fa98ca8 Mon Sep 17 00:00:00 2001 From: ludivinecp Date: Mon, 14 Dec 2015 10:07:31 +0100 Subject: [PATCH 41/43] Opengraph facebook: images and description for shops and groups and home => ok --- app/assets/images/logo-black2.png | Bin 0 -> 2082 bytes app/helpers/application_helper.rb | 4 ++++ app/views/enterprises/shop.html.haml | 4 ++++ app/views/groups/show.html.haml | 4 ++++ app/views/layouts/darkswarm.html.haml | 4 +++- config/locales/en.yml | 2 ++ 6 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 app/assets/images/logo-black2.png diff --git a/app/assets/images/logo-black2.png b/app/assets/images/logo-black2.png new file mode 100644 index 0000000000000000000000000000000000000000..6229ae2d9ef1c7889bcd5e5ef8df7490d26c0e8f GIT binary patch literal 2082 zcmb7FYdDjQA6_XkQBlszA#>Ox>okRzQqDpxTOJD?o{8qz9J8jw+e<`Fn^&w7Q?@7Z zI3<##cqbLHvbRx6-XTN|%~pSX{C|7j`?`MDecku(zV0u-55LO?yj@k%x@Z&%rRwhH zL`0#M`=L{ci&IWsLoe=HI1zV!&N ziE&#J%29409feZS_%+K=*NU{4Or;oiFK4B})v9aF^aX8WACe+@LkREbhp@+POwYb=Ft2)P6+XWXKPd_Az%ScVzc3rZ@y`&=2V3 zL&I5c*!cX6xS(7`nbGX=vL2!aEh=7=HJ}TU9jZz`PR)2i&aG!606PT1dMY8jeD>9v z35#T_6O#B0hdE<;e2u77?Sa~}%pEKrCXqbFQ9!Q$l-^4j*<>-;lFRLyBpUq2J=Jt0 z2mAO$XIuID0(l-b6J{I)KV)t6+)R}i0T{1SAla76^(ITNSSrW+KcoCe2BifpJv+m2 z&IS~IaEPF1CHNrS5)6?)d4*6Dl^x9at6BmeiQTOOX^xfNjcUosda)R5R&9)*&ZQ3& zDmRcUZL$RI6xZwpl8_=Lt-RV@%zQ1#M#1@EktO)$-S@u-_pvLQk9x5|SuP;(Hz3@< z7p2}5aB&jXrLEQeByQaHJ|fdiy;4SydY5-63`d(c`QP?^mK!9@{drjE z@&vP(-kBf@R5Uudx)cK<#=s;%Lrfq8P_NXo!18AQKDI0#47Mw@lF@bd9O^FW@SuZ9 zB#*9^(O^!@@SP}c%NT^`E!i(*YG?}U*-YFnks96ZA|Vgk3~#>O3P*Cp!$5JIUzc7p zj@Ic;mOQG_My3(?+ad&7@Y74j!*-lX(amNlBGyN=k9Vji6+ku92bk&QmS3p^ptY3J zQ2W%ceJVek%ZwezAaj)Grp13o>yGUqU+e72f_G%io=-b%qDP(C5>-EYKQ1@D%o;LM z0VlIJjD}l53qk2l3NBf-CV=LJdJnKeY60qi((H~Npi>}jP|voKZJoGlHrdG;rl${$ zH2gem@;YoWlrpMWT4we`B;RU3M-%kK$hN2X9QCbeX1*C}k3d{_#x^*UrMvKEH$Auk zSF9ztenhT~2+rjZ+3RVJrFW_X)x!FK6yOB|!*CO>BM=n}^=T2;5o;9~ORDM<(2(nt zkcS1oiT=S--uDW9I&wIWyLm=?j{G1;yW@;0wtJ-H#FJ@KkY? zxKE92MgoN{Isij*J3>a%Vn>l_@Gx9sOdBa0p10=v*pJ$-fFvd341FC{P_hj% zr3JfidaA2uc`(oE!QtJW_K9;LW~y({2IBbwxNh;4=|YL(qr+f41;oS@U}4khMx%TO=an~~WI_28Pj{gf zy0)BUp#s31HQ?-c1{MgX@A<~gbMcs(%wqNFui~C4bKQCEUG$ql0iz<;1n{9^_mORm z9ZV2$F`}{RURow;px#FlcmZp7@bJk%`{O4?=)bWwrPYS9WP?r*d?)WE*=E2NMC$(X z=lpRF{uT$yzsXlZePVu`m+KdzB0}6q!emC`g)DAk;*+z8Fl4#(){ZejN2XDJb{6d`l1NqRc7=BjGz8(ukBeV?kN2JoFF73< z7`n5o(DW`O64dMkLUm?)tSaHgWOe`VO`&`B{N54I_(qyvysGE%rkEPv&(R(2swQu| zg5F-idzCYO6`f5=VgETla&vrS&Ds&d-9jaHbofc5%Fo55ep()OIUjwO*GN?@i)M*( zhfLmZQ;%O#K#268E0+W6{v6HF&*ke#)=sqn$`!EwVEfzeCK+460KRSI?^ePNGV7mc zLJd_daqXwKJv$yf(yh~0Z{BvROgP1}@_icq0SBv)`0_*l;S2tM^j!RuQm?$Cux2Q) Q^4G@Q+1sgN@6ikY1E^uT^#A|> literal 0 HcmV?d00001 diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 15c20dfd55..80b4a5d4d1 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -25,4 +25,8 @@ module ApplicationHelper super end end + + def image_url(file) + request.protocol + request.host_with_port + path_to_image(file) + end end diff --git a/app/views/enterprises/shop.html.haml b/app/views/enterprises/shop.html.haml index 35937629fc..d3169647e0 100644 --- a/app/views/enterprises/shop.html.haml +++ b/app/views/enterprises/shop.html.haml @@ -1,5 +1,9 @@ - content_for(:title) do = current_distributor.name +- content_for(:description) do + = current_distributor.description +- content_for(:image) do + = current_distributor.logo = inject_enterprises diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml index b4e6f7586c..ed98d3b2ca 100644 --- a/app/views/groups/show.html.haml +++ b/app/views/groups/show.html.haml @@ -1,5 +1,9 @@ - content_for(:title) do = @group.name +- content_for(:description) do + = @group.description +- content_for(:image) do + = @group.logo -# inject all enterprises as "enterprises" -# it could be more efficient to inject only the enterprises that are related to the group diff --git a/app/views/layouts/darkswarm.html.haml b/app/views/layouts/darkswarm.html.haml index a933858049..016af8d30d 100644 --- a/app/views/layouts/darkswarm.html.haml +++ b/app/views/layouts/darkswarm.html.haml @@ -2,7 +2,9 @@ %head %meta{charset: 'utf-8'}/ %meta{name: 'viewport', content: "width=device-width,initial-scale=1.0"}/ - + %meta{:content => yield(:title).empty? ? "#{t(:title)}" : yield(:title), :property => "og:title"}/ + %meta{:content => yield(:description).empty? ? "#{t(:og_description)}" : yield(:description), :property => "og:description"}/ + %meta{:content => yield(:image).empty? ? image_url("logo-black2.png") : image_url(yield(:image)), :property => "og:image"}/ %title= content_for?(:title) ? "#{yield(:title)} - #{t(:title)}".html_safe : "#{t(:welcome_to)} #{t(:title)}" - if Rails.env.production? = favicon_link_tag diff --git a/config/locales/en.yml b/config/locales/en.yml index 76f0c124b3..963cf0edff 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -674,3 +674,5 @@ Please follow the instructions there to make your enterprise visible on the Open price_graph: "Price graph" included_tax: "Included tax" remove_tax: "Remove tax" + og_description: "We begin from the ground up. With farmers and growers ready to tell their stories proudly and truly. With distributors ready to connect people with products fairly and honestly. With buyers who believe that better weekly shopping decisions can…" + From 07d691fc974a9688648e37bb7b0cf6143ee6d116 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Fri, 15 Jan 2016 16:54:56 +1100 Subject: [PATCH 42/43] Only apply cart scrolling to non-mobile devices --- app/assets/stylesheets/darkswarm/shopping-cart.css.sass | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/assets/stylesheets/darkswarm/shopping-cart.css.sass b/app/assets/stylesheets/darkswarm/shopping-cart.css.sass index 9bdedb806c..6fd48e0970 100644 --- a/app/assets/stylesheets/darkswarm/shopping-cart.css.sass +++ b/app/assets/stylesheets/darkswarm/shopping-cart.css.sass @@ -13,8 +13,10 @@ right: 10px top: 55px width: 480px - overflow-y: auto - max-height: calc(95vh - 55px) + + @media screen and (min-width: 641px) + overflow-y: auto + max-height: calc(95vh - 55px) @media screen and (max-width: 640px) width: 96% From d562f6537e608bd670d61e6f90523a13efd281a1 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Wed, 20 Jan 2016 15:42:01 +1100 Subject: [PATCH 43/43] Cleaner opengraph meta tags --- app/assets/images/logo-black2.png | Bin 2082 -> 0 bytes app/helpers/application_helper.rb | 4 ---- app/views/enterprises/shop.html.haml | 2 +- app/views/groups/show.html.haml | 2 +- app/views/layouts/darkswarm.html.haml | 6 +++--- config/locales/en.yml | 3 +-- 6 files changed, 6 insertions(+), 11 deletions(-) delete mode 100644 app/assets/images/logo-black2.png diff --git a/app/assets/images/logo-black2.png b/app/assets/images/logo-black2.png deleted file mode 100644 index 6229ae2d9ef1c7889bcd5e5ef8df7490d26c0e8f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2082 zcmb7FYdDjQA6_XkQBlszA#>Ox>okRzQqDpxTOJD?o{8qz9J8jw+e<`Fn^&w7Q?@7Z zI3<##cqbLHvbRx6-XTN|%~pSX{C|7j`?`MDecku(zV0u-55LO?yj@k%x@Z&%rRwhH zL`0#M`=L{ci&IWsLoe=HI1zV!&N ziE&#J%29409feZS_%+K=*NU{4Or;oiFK4B})v9aF^aX8WACe+@LkREbhp@+POwYb=Ft2)P6+XWXKPd_Az%ScVzc3rZ@y`&=2V3 zL&I5c*!cX6xS(7`nbGX=vL2!aEh=7=HJ}TU9jZz`PR)2i&aG!606PT1dMY8jeD>9v z35#T_6O#B0hdE<;e2u77?Sa~}%pEKrCXqbFQ9!Q$l-^4j*<>-;lFRLyBpUq2J=Jt0 z2mAO$XIuID0(l-b6J{I)KV)t6+)R}i0T{1SAla76^(ITNSSrW+KcoCe2BifpJv+m2 z&IS~IaEPF1CHNrS5)6?)d4*6Dl^x9at6BmeiQTOOX^xfNjcUosda)R5R&9)*&ZQ3& zDmRcUZL$RI6xZwpl8_=Lt-RV@%zQ1#M#1@EktO)$-S@u-_pvLQk9x5|SuP;(Hz3@< z7p2}5aB&jXrLEQeByQaHJ|fdiy;4SydY5-63`d(c`QP?^mK!9@{drjE z@&vP(-kBf@R5Uudx)cK<#=s;%Lrfq8P_NXo!18AQKDI0#47Mw@lF@bd9O^FW@SuZ9 zB#*9^(O^!@@SP}c%NT^`E!i(*YG?}U*-YFnks96ZA|Vgk3~#>O3P*Cp!$5JIUzc7p zj@Ic;mOQG_My3(?+ad&7@Y74j!*-lX(amNlBGyN=k9Vji6+ku92bk&QmS3p^ptY3J zQ2W%ceJVek%ZwezAaj)Grp13o>yGUqU+e72f_G%io=-b%qDP(C5>-EYKQ1@D%o;LM z0VlIJjD}l53qk2l3NBf-CV=LJdJnKeY60qi((H~Npi>}jP|voKZJoGlHrdG;rl${$ zH2gem@;YoWlrpMWT4we`B;RU3M-%kK$hN2X9QCbeX1*C}k3d{_#x^*UrMvKEH$Auk zSF9ztenhT~2+rjZ+3RVJrFW_X)x!FK6yOB|!*CO>BM=n}^=T2;5o;9~ORDM<(2(nt zkcS1oiT=S--uDW9I&wIWyLm=?j{G1;yW@;0wtJ-H#FJ@KkY? zxKE92MgoN{Isij*J3>a%Vn>l_@Gx9sOdBa0p10=v*pJ$-fFvd341FC{P_hj% zr3JfidaA2uc`(oE!QtJW_K9;LW~y({2IBbwxNh;4=|YL(qr+f41;oS@U}4khMx%TO=an~~WI_28Pj{gf zy0)BUp#s31HQ?-c1{MgX@A<~gbMcs(%wqNFui~C4bKQCEUG$ql0iz<;1n{9^_mORm z9ZV2$F`}{RURow;px#FlcmZp7@bJk%`{O4?=)bWwrPYS9WP?r*d?)WE*=E2NMC$(X z=lpRF{uT$yzsXlZePVu`m+KdzB0}6q!emC`g)DAk;*+z8Fl4#(){ZejN2XDJb{6d`l1NqRc7=BjGz8(ukBeV?kN2JoFF73< z7`n5o(DW`O64dMkLUm?)tSaHgWOe`VO`&`B{N54I_(qyvysGE%rkEPv&(R(2swQu| zg5F-idzCYO6`f5=VgETla&vrS&Ds&d-9jaHbofc5%Fo55ep()OIUjwO*GN?@i)M*( zhfLmZQ;%O#K#268E0+W6{v6HF&*ke#)=sqn$`!EwVEfzeCK+460KRSI?^ePNGV7mc zLJd_daqXwKJv$yf(yh~0Z{BvROgP1}@_icq0SBv)`0_*l;S2tM^j!RuQm?$Cux2Q) Q^4G@Q+1sgN@6ikY1E^uT^#A|> diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 80b4a5d4d1..15c20dfd55 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -25,8 +25,4 @@ module ApplicationHelper super end end - - def image_url(file) - request.protocol + request.host_with_port + path_to_image(file) - end end diff --git a/app/views/enterprises/shop.html.haml b/app/views/enterprises/shop.html.haml index d3169647e0..f2063494b4 100644 --- a/app/views/enterprises/shop.html.haml +++ b/app/views/enterprises/shop.html.haml @@ -3,7 +3,7 @@ - content_for(:description) do = current_distributor.description - content_for(:image) do - = current_distributor.logo + = current_distributor.logo.url = inject_enterprises diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml index ed98d3b2ca..4831a911a6 100644 --- a/app/views/groups/show.html.haml +++ b/app/views/groups/show.html.haml @@ -3,7 +3,7 @@ - content_for(:description) do = @group.description - content_for(:image) do - = @group.logo + = @group.logo.url -# inject all enterprises as "enterprises" -# it could be more efficient to inject only the enterprises that are related to the group diff --git a/app/views/layouts/darkswarm.html.haml b/app/views/layouts/darkswarm.html.haml index 016af8d30d..0788286394 100644 --- a/app/views/layouts/darkswarm.html.haml +++ b/app/views/layouts/darkswarm.html.haml @@ -2,9 +2,9 @@ %head %meta{charset: 'utf-8'}/ %meta{name: 'viewport', content: "width=device-width,initial-scale=1.0"}/ - %meta{:content => yield(:title).empty? ? "#{t(:title)}" : yield(:title), :property => "og:title"}/ - %meta{:content => yield(:description).empty? ? "#{t(:og_description)}" : yield(:description), :property => "og:description"}/ - %meta{:content => yield(:image).empty? ? image_url("logo-black2.png") : image_url(yield(:image)), :property => "og:image"}/ + %meta{property: "og:title", content: content_for?(:title) ? yield(:title) : t(:title)} + %meta{property: "og:description", content: content_for?(:description) ? yield(:description) : t(:description)} + %meta{property: "og:image", content: content_for?(:image) ? yield(:image) : ContentConfig.logo.url} %title= content_for?(:title) ? "#{yield(:title)} - #{t(:title)}".html_safe : "#{t(:welcome_to)} #{t(:title)}" - if Rails.env.production? = favicon_link_tag diff --git a/config/locales/en.yml b/config/locales/en.yml index 963cf0edff..eb47b64224 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -29,6 +29,7 @@ en: home: "OFN" title: Open Food Network welcome_to: 'Welcome to ' + description: "We begin from the ground up. With farmers and growers ready to tell their stories proudly and truly. With distributors ready to connect people with products fairly and honestly. With buyers who believe that better weekly shopping decisions can…" search_by_name: Search by name or suburb... producers: Aussie Producers producers_join: Australian producers are now welcome to join the Open Food Network. @@ -674,5 +675,3 @@ Please follow the instructions there to make your enterprise visible on the Open price_graph: "Price graph" included_tax: "Included tax" remove_tax: "Remove tax" - og_description: "We begin from the ground up. With farmers and growers ready to tell their stories proudly and truly. With distributors ready to connect people with products fairly and honestly. With buyers who believe that better weekly shopping decisions can…" -