From 86d7453d2637508a6b387f6bc22e24f27aa468f6 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Wed, 14 Mar 2018 15:23:36 +1100 Subject: [PATCH] Ask user to confirm oc date change for open order cycles with subsciptions --- .../directives/change-warning.js.coffee | 19 +++++++++++++++++++ .../services/order_cycle.js.coffee | 1 + .../api/admin/index_order_cycle_serializer.rb | 6 +++++- .../api/admin/order_cycle_serializer.rb | 6 +++++- .../_name_and_timing_form.html.haml | 4 ++-- app/views/admin/order_cycles/_row.html.haml | 4 ++-- config/locales/en.yml | 4 ++++ spec/features/admin/order_cycles_spec.rb | 5 +++++ 8 files changed, 43 insertions(+), 6 deletions(-) create mode 100644 app/assets/javascripts/admin/order_cycles/directives/change-warning.js.coffee diff --git a/app/assets/javascripts/admin/order_cycles/directives/change-warning.js.coffee b/app/assets/javascripts/admin/order_cycles/directives/change-warning.js.coffee new file mode 100644 index 0000000000..8c7b84fb62 --- /dev/null +++ b/app/assets/javascripts/admin/order_cycles/directives/change-warning.js.coffee @@ -0,0 +1,19 @@ +angular.module("admin.orderCycles").directive "changeWarning", (ConfirmDialog) -> + restrict: "A" + scope: + orderCycle: '=changeWarning' + link: (scope, element, attrs) -> + acknowledged = false + count = scope.orderCycle.subscriptions_count + cancel = 'admin.order_cycles.date_warning.cancel' + proceed = 'admin.order_cycles.date_warning.proceed' + msg = t('admin.order_cycles.date_warning.msg', n: count) + options = { cancel: t(cancel), confirm: t(proceed) } + + element.focus -> + return if acknowledged + return if moment(scope.orderCycle.orders_close_at).isBefore() + return if count < 1 + ConfirmDialog.open('info', msg, options).then -> + acknowledged = true + element.siblings('img').trigger('click') diff --git a/app/assets/javascripts/admin/order_cycles/services/order_cycle.js.coffee b/app/assets/javascripts/admin/order_cycles/services/order_cycle.js.coffee index f35db6e3b5..59d9b4f994 100644 --- a/app/assets/javascripts/admin/order_cycles/services/order_cycle.js.coffee +++ b/app/assets/javascripts/admin/order_cycles/services/order_cycle.js.coffee @@ -209,6 +209,7 @@ angular.module('admin.orderCycles').factory 'OrderCycle', ($resource, $window, S delete order_cycle.editable_variants_for_incoming_exchanges delete order_cycle.editable_variants_for_outgoing_exchanges delete order_cycle.visible_variants_for_outgoing_exchanges + delete order_cycle.subscriptions_count order_cycle removeInactiveExchanges: (order_cycle) -> diff --git a/app/serializers/api/admin/index_order_cycle_serializer.rb b/app/serializers/api/admin/index_order_cycle_serializer.rb index 22d6d4445e..566d794c61 100644 --- a/app/serializers/api/admin/index_order_cycle_serializer.rb +++ b/app/serializers/api/admin/index_order_cycle_serializer.rb @@ -7,7 +7,7 @@ module Api attributes :id, :name, :orders_open_at, :orders_close_at, :status, :variant_count, :deletable attributes :coordinator, :producers, :shops, :viewing_as_coordinator - attributes :edit_path, :clone_path, :delete_path + attributes :edit_path, :clone_path, :delete_path, :subscriptions_count has_many :schedules, serializer: Api::Admin::IdNameSerializer @@ -61,6 +61,10 @@ module Api admin_order_cycle_path(object) end + def subscriptions_count + ProxyOrder.not_canceled.where(order_cycle_id: object.id).count + end + private def visible_enterprises diff --git a/app/serializers/api/admin/order_cycle_serializer.rb b/app/serializers/api/admin/order_cycle_serializer.rb index 9b5ff7a7cb..919ab9de1f 100644 --- a/app/serializers/api/admin/order_cycle_serializer.rb +++ b/app/serializers/api/admin/order_cycle_serializer.rb @@ -4,7 +4,7 @@ class Api::Admin::OrderCycleSerializer < ActiveModel::Serializer attributes :id, :name, :orders_open_at, :orders_close_at, :coordinator_id, :exchanges attributes :editable_variants_for_incoming_exchanges, :editable_variants_for_outgoing_exchanges attributes :visible_variants_for_outgoing_exchanges - attributes :viewing_as_coordinator, :schedule_ids + attributes :viewing_as_coordinator, :schedule_ids, :subscriptions_count has_many :coordinator_fees, serializer: Api::IdSerializer @@ -20,6 +20,10 @@ class Api::Admin::OrderCycleSerializer < ActiveModel::Serializer Enterprise.managed_by(options[:current_user]).include? object.coordinator end + def subscriptions_count + ProxyOrder.not_canceled.where(order_cycle_id: object.id).count + end + def exchanges scoped_exchanges = OpenFoodNetwork::OrderCyclePermissions.new(options[:current_user], object).visible_exchanges.by_enterprise_name ActiveModel::ArraySerializer.new(scoped_exchanges, {each_serializer: Api::Admin::ExchangeSerializer, current_user: options[:current_user] }) diff --git a/app/views/admin/order_cycles/_name_and_timing_form.html.haml b/app/views/admin/order_cycles/_name_and_timing_form.html.haml index 1b2ff05c21..842b12d5c3 100644 --- a/app/views/admin/order_cycles/_name_and_timing_form.html.haml +++ b/app/views/admin/order_cycles/_name_and_timing_form.html.haml @@ -10,7 +10,7 @@ = f.label :orders_open_at, t('.orders_open') .omega.six.columns - if viewing_as_coordinator_of?(@order_cycle) - = f.text_field :orders_open_at, 'datetimepicker' => 'order_cycle.orders_open_at', 'ng-model' => 'order_cycle.orders_open_at', 'ng-disabled' => '!loaded()' + = f.text_field :orders_open_at, 'datetimepicker' => 'order_cycle.orders_open_at', 'ng-model' => 'order_cycle.orders_open_at', 'ng-disabled' => '!loaded()', 'change-warning' => 'order_cycle' - else {{ order_cycle.orders_open_at }} @@ -23,7 +23,7 @@ = f.label :orders_close, t('.orders_close') .six.columns.omega - if viewing_as_coordinator_of?(@order_cycle) - = f.text_field :orders_close_at, 'datetimepicker' => 'order_cycle.orders_close_at', 'ng-model' => 'order_cycle.orders_close_at', 'ng-disabled' => '!loaded()' + = f.text_field :orders_close_at, 'datetimepicker' => 'order_cycle.orders_close_at', 'ng-model' => 'order_cycle.orders_close_at', 'ng-disabled' => '!loaded()', 'change-warning' => 'order_cycle' - else {{ order_cycle.orders_close_at }} diff --git a/app/views/admin/order_cycles/_row.html.haml b/app/views/admin/order_cycles/_row.html.haml index a2fb90df3b..40f40e5126 100644 --- a/app/views/admin/order_cycles/_row.html.haml +++ b/app/views/admin/order_cycles/_row.html.haml @@ -8,10 +8,10 @@ {{ schedule.name + ($last ? '' : ',') }} %span{ ng: { show: 'orderCycle.schedules.length == 0'}} None %td.orders_open_at{ ng: { show: 'columns.open.visible' } } - %input.datetimepicker{ id: 'oc{{::orderCycle.id}}_orders_open_at', name: 'oc{{::orderCycle.id}}[orders_open_at]', type: 'text', ng: { if: 'orderCycle.viewing_as_coordinator', model: 'orderCycle.orders_open_at' }, datetimepicker: 'orderCycle.orders_open_at' } + %input.datetimepicker{ id: 'oc{{::orderCycle.id}}_orders_open_at', name: 'oc{{::orderCycle.id}}[orders_open_at]', type: 'text', ng: { if: 'orderCycle.viewing_as_coordinator', model: 'orderCycle.orders_open_at' }, datetimepicker: 'orderCycle.orders_open_at', 'change-warning' => 'orderCycle' } %input{ id: 'oc{{::orderCycle.id}}_orders_open_at', name: 'oc{{::orderCycle.id}}[orders_open_at]', type: 'text', ng: { if: '!orderCycle.viewing_as_coordinator', model: 'orderCycle.orders_open_at'}, disabled: true } %td.orders_close_at{ ng: { show: 'columns.close.visible' } } - %input.datetimepicker{ id: 'oc{{::orderCycle.id}}_orders_close_at', name: 'oc{{::orderCycle.id}}[orders_close_at]', type: 'text', ng: { if: 'orderCycle.viewing_as_coordinator', model: 'orderCycle.orders_close_at' }, datetimepicker: 'orderCycle.orders_close_at' } + %input.datetimepicker{ id: 'oc{{::orderCycle.id}}_orders_close_at', name: 'oc{{::orderCycle.id}}[orders_close_at]', type: 'text', ng: { if: 'orderCycle.viewing_as_coordinator', model: 'orderCycle.orders_close_at' }, datetimepicker: 'orderCycle.orders_close_at', 'change-warning' => 'orderCycle' } %input{ id: 'oc{{::orderCycle.id}}_orders_close_at', name: 'oc{{::orderCycle.id}}[orders_close_at]', type: 'text', ng: { if: '!orderCycle.viewing_as_coordinator', model: 'orderCycle.orders_close_at'}, disabled: true } - unless simple_index diff --git a/config/locales/en.yml b/config/locales/en.yml index 707579765a..bc7399ef30 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -902,6 +902,10 @@ en: schedule_present: That order cycle is linked to a schedule and cannot be deleted. Please unlink or delete the schedule first. bulk_update: no_data: Hm, something went wrong. No order cycle data found. + date_warning: + msg: This order cycle is linked to %{n} open subscription orders. Changing this date now will not affect any orders which have already been placed, but should be avoided if possible. Are you sure you want to proceed? + cancel: Cancel + proceed: Proceed producer_properties: index: title: Producer Properties diff --git a/spec/features/admin/order_cycles_spec.rb b/spec/features/admin/order_cycles_spec.rb index eb6fe4bc73..30d49fd39f 100644 --- a/spec/features/admin/order_cycles_spec.rb +++ b/spec/features/admin/order_cycles_spec.rb @@ -24,6 +24,7 @@ feature %q{ oc7 = create(:simple_order_cycle, name: 'oc7', orders_open_at: 2.months.ago, orders_close_at: 5.weeks.ago) schedule1 = create(:schedule, name: 'Schedule1', order_cycles: [oc1, oc3]) + create(:proxy_order, subscription: create(:subscription, schedule: schedule1), order_cycle: oc1) # When I go to the admin order cycles page login_to_admin_section @@ -111,6 +112,10 @@ feature %q{ page.should have_selector "#listing_order_cycles tr.order-cycle-#{oc1.id}" page.should have_selector "#listing_order_cycles tr.order-cycle-#{oc2.id}" page.should have_selector "#listing_order_cycles tr.order-cycle-#{oc3.id}" + + # Attempting to edit dates of an open order cycle with active subscriptions + find("#oc#{oc1.id}_orders_open_at").click + expect(page).to have_selector "#confirm-dialog .message", text: I18n.t('admin.order_cycles.date_warning.msg', n: 1) end describe 'listing order cycles with other locales' do