From eaae16a486b0057ef5b6ea451174ab963ecdc7f1 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Wed, 2 Dec 2015 11:12:29 +1100 Subject: [PATCH 01/27] Copy orders/new template from Spree --- app/views/spree/admin/orders/new.html.haml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 app/views/spree/admin/orders/new.html.haml diff --git a/app/views/spree/admin/orders/new.html.haml b/app/views/spree/admin/orders/new.html.haml new file mode 100644 index 0000000000..9806056cac --- /dev/null +++ b/app/views/spree/admin/orders/new.html.haml @@ -0,0 +1,22 @@ +- content_for :page_title do + = t(:new) + +- content_for :page_actions do + %li= button_link_to t(:back_to_orders_list), spree.admin_orders_path, :icon => 'icon-arrow-left' + += render :partial => 'spree/admin/shared/order_tabs', :locals => { :current => 'Order Details' } + += csrf_meta_tags + +%div{"data-hook" => "admin_order_new_header"} + = render :partial => 'spree/shared/error_messages', :locals => { :target => @order } + += render :partial => 'add_product' + +- unless @order.line_items.any? + %div{"data-hook" => "admin_order_new_form"} + #order-form-wrapper + = render :partial => 'form' + +- content_for :head do + = javascript_tag 'var expand_variants = true;' From 742e2279aec07b3371640b9d5b4603b480873f95 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Wed, 2 Dec 2015 11:13:20 +1100 Subject: [PATCH 02/27] Tidy render partial calls --- app/views/spree/admin/orders/new.html.haml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/spree/admin/orders/new.html.haml b/app/views/spree/admin/orders/new.html.haml index 9806056cac..66b04a7aba 100644 --- a/app/views/spree/admin/orders/new.html.haml +++ b/app/views/spree/admin/orders/new.html.haml @@ -4,19 +4,19 @@ - content_for :page_actions do %li= button_link_to t(:back_to_orders_list), spree.admin_orders_path, :icon => 'icon-arrow-left' -= render :partial => 'spree/admin/shared/order_tabs', :locals => { :current => 'Order Details' } += render 'spree/admin/shared/order_tabs', :current => 'Order Details' = csrf_meta_tags %div{"data-hook" => "admin_order_new_header"} - = render :partial => 'spree/shared/error_messages', :locals => { :target => @order } + = render 'spree/shared/error_messages', :target => @order -= render :partial => 'add_product' += render 'add_product' - unless @order.line_items.any? %div{"data-hook" => "admin_order_new_form"} #order-form-wrapper - = render :partial => 'form' + = render 'form' - content_for :head do = javascript_tag 'var expand_variants = true;' From 47c23c986a60e6a0c0ad6c75af70b3efd74fb84c Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Wed, 2 Dec 2015 11:17:23 +1100 Subject: [PATCH 03/27] Move distribution fields from override to partial --- .../add_distribution_fields.html.haml.deface | 26 ------------------- .../orders/_distribution_fields.html.haml | 14 ++++++++++ app/views/spree/admin/orders/new.html.haml | 2 ++ 3 files changed, 16 insertions(+), 26 deletions(-) delete mode 100644 app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface create mode 100644 app/views/spree/admin/orders/_distribution_fields.html.haml diff --git a/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface b/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface deleted file mode 100644 index a0db4d2564..0000000000 --- a/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface +++ /dev/null @@ -1,26 +0,0 @@ -/ insert_before "[data-hook='admin_order_form_buttons']" - -%fieldset.no-border-bottom - %legend{align => 'center'} Distribution - - - if @order.complete? - .alpha.six.columns - %p - %b Distributor: - = f.object.distributor.andand.name || "None" - = f.hidden_field :distributor_id - .omega.six.columns - %p - %b Order cycle: - = f.object.order_cycle.andand.name || "None" - = f.hidden_field :order_cycle_id - - - else - .alpha.six.columns - .field - = f.label :distributor_id - = f.collection_select :distributor_id, Enterprise.is_distributor.managed_by(spree_current_user), :id, :name, include_blank: true - .omega.six.columns - .field - = f.label :order_cycle_id - = f.collection_select :order_cycle_id, OrderCycle.managed_by(spree_current_user), :id, :name, include_blank: true diff --git a/app/views/spree/admin/orders/_distribution_fields.html.haml b/app/views/spree/admin/orders/_distribution_fields.html.haml new file mode 100644 index 0000000000..01753e025b --- /dev/null +++ b/app/views/spree/admin/orders/_distribution_fields.html.haml @@ -0,0 +1,14 @@ +%fieldset.no-border-bottom + %legend{align: 'center'} Distribution + + .alpha.six.columns + .field + %label{for: "distributor_id"} Distributor + %select{id: "distributor_id", 'ng-model' => "", 'ng-options' => ''} + -#= f.collection_select :distributor_id, Enterprise.is_distributor.managed_by(spree_current_user), :id, :name, include_blank: true + + .omega.six.columns + .field + %label{for: "order_cycle_id"} Order Cycle + %select{id: "order_cycle_id", 'ng-model' => "", 'ng-options' => ''} + -#= f.collection_select :order_cycle_id, OrderCycle.managed_by(spree_current_user), :id, :name, include_blank: true diff --git a/app/views/spree/admin/orders/new.html.haml b/app/views/spree/admin/orders/new.html.haml index 66b04a7aba..d5b082e651 100644 --- a/app/views/spree/admin/orders/new.html.haml +++ b/app/views/spree/admin/orders/new.html.haml @@ -11,6 +11,8 @@ %div{"data-hook" => "admin_order_new_header"} = render 'spree/shared/error_messages', :target => @order += render 'distribution_fields' + = render 'add_product' - unless @order.line_items.any? From eb07680f1ff69c5a4262d90e29bf647202cc47ae Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Wed, 2 Dec 2015 13:27:51 +1100 Subject: [PATCH 04/27] Inject shops and order cycles --- .../spree/admin/orders_controller_decorator.rb | 8 ++++++++ app/helpers/admin/injection_helper.rb | 8 ++++++-- app/serializers/api/admin/order_cycle_serializer.rb | 2 ++ app/views/spree/admin/orders/new.html.haml | 3 +++ 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/app/controllers/spree/admin/orders_controller_decorator.rb b/app/controllers/spree/admin/orders_controller_decorator.rb index 1fe4458c55..39456aaf06 100644 --- a/app/controllers/spree/admin/orders_controller_decorator.rb +++ b/app/controllers/spree/admin/orders_controller_decorator.rb @@ -10,6 +10,8 @@ Spree::Admin::OrdersController.class_eval do # in an auth failure as the @order object is nil for collection actions before_filter :check_authorization, except: [:bulk_management, :managed] + before_filter :load_distribution_choices, only: :new + # After updating an order, the fees should be updated as well # Currently, adding or deleting line items does not trigger updating the # fees! This is a quick fix for that. @@ -19,6 +21,7 @@ Spree::Admin::OrdersController.class_eval do before_filter :require_distributor_abn, only: :invoice + respond_to :html, :json # Mostly the original Spree method, tweaked to allow us to ransack with completed_at in a sane way @@ -112,4 +115,9 @@ Spree::Admin::OrdersController.class_eval do respond_with(@order) { |format| format.html { redirect_to edit_admin_order_path(@order) } } end end + + def load_distribution_choices + @shops = Enterprise.is_distributor.managed_by(spree_current_user) + @order_cycles = OrderCycle.managed_by(spree_current_user) + end end diff --git a/app/helpers/admin/injection_helper.rb b/app/helpers/admin/injection_helper.rb index d341f1d801..aa45f4ac2b 100644 --- a/app/helpers/admin/injection_helper.rb +++ b/app/helpers/admin/injection_helper.rb @@ -25,8 +25,8 @@ module Admin admin_inject_json_ams_array "admin.shipping_methods", "shippingMethods", @shipping_methods, Api::Admin::IdNameSerializer end - def admin_inject_shops - admin_inject_json_ams_array "admin.customers", "shops", @shops, Api::Admin::IdNameSerializer + def admin_inject_shops(ngModule='admin.customers') + admin_inject_json_ams_array ngModule, "shops", @shops, Api::Admin::IdNameSerializer end def admin_inject_hubs @@ -74,6 +74,10 @@ module Admin render partial: "admin/json/injection_ams", locals: {ngModule: 'admin.orderCycles', name: 'ocInstance', json: "{coordinator_id: '#{@order_cycle.coordinator.id}'}"} end + def admin_inject_order_cycles + admin_inject_json_ams_array "admin.orders", "orderCycles", @order_cycles, Api::Admin::IdNameSerializer, current_user: spree_current_user + 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}'"} end diff --git a/app/serializers/api/admin/order_cycle_serializer.rb b/app/serializers/api/admin/order_cycle_serializer.rb index 01a681ca66..53b1a10c04 100644 --- a/app/serializers/api/admin/order_cycle_serializer.rb +++ b/app/serializers/api/admin/order_cycle_serializer.rb @@ -1,3 +1,5 @@ +require 'open_food_network/order_cycle_permissions' + 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 diff --git a/app/views/spree/admin/orders/new.html.haml b/app/views/spree/admin/orders/new.html.haml index d5b082e651..50b58ce62f 100644 --- a/app/views/spree/admin/orders/new.html.haml +++ b/app/views/spree/admin/orders/new.html.haml @@ -4,6 +4,9 @@ - content_for :page_actions do %li= button_link_to t(:back_to_orders_list), spree.admin_orders_path, :icon => 'icon-arrow-left' += admin_inject_shops 'admin.orders' += admin_inject_order_cycles + = render 'spree/admin/shared/order_tabs', :current => 'Order Details' = csrf_meta_tags From 2daceb1111249e045cb7d72a6742a3655ba07f90 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Fri, 4 Dec 2015 08:45:32 +1100 Subject: [PATCH 05/27] Angularise new order form --- .../controllers/orders_controller.js.coffee | 4 +++ .../add_distribution_fields.html.haml.deface | 29 +++++++++++++++++++ .../spree/admin/line_items/create.js.erb | 5 ++++ .../orders/_distribution_fields.html.haml | 14 --------- app/views/spree/admin/orders/new.html.haml | 13 ++++----- spec/features/admin/orders_spec.rb | 11 +++---- 6 files changed, 50 insertions(+), 26 deletions(-) create mode 100644 app/assets/javascripts/admin/orders/controllers/orders_controller.js.coffee create mode 100644 app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface create mode 100644 app/views/spree/admin/line_items/create.js.erb delete mode 100644 app/views/spree/admin/orders/_distribution_fields.html.haml diff --git a/app/assets/javascripts/admin/orders/controllers/orders_controller.js.coffee b/app/assets/javascripts/admin/orders/controllers/orders_controller.js.coffee new file mode 100644 index 0000000000..826bc6ed11 --- /dev/null +++ b/app/assets/javascripts/admin/orders/controllers/orders_controller.js.coffee @@ -0,0 +1,4 @@ +angular.module("admin.orders").controller "ordersCtrl", ($scope, $compile, shops, orderCycles) -> + $scope.$compile = $compile + $scope.shops = shops + $scope.orderCycles = orderCycles diff --git a/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface b/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface new file mode 100644 index 0000000000..a8e716769d --- /dev/null +++ b/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface @@ -0,0 +1,29 @@ +/ insert_before "[data-hook='admin_order_form_buttons']" + +%fieldset.no-border-bottom + %legend{align: 'center'} Distribution + + - if @order.complete? + .alpha.six.columns + %p + %b Distributor: + = f.object.distributor.andand.name || "None" + = f.hidden_field :distributor_id + .omega.six.columns + %p + %b Order cycle: + = f.object.order_cycle.andand.name || "None" + = f.hidden_field :order_cycle_id + + - else + .alpha.six.columns + .field + %label{for: "order_distributor_id"} Distributor + %select{id: "order_distributor_id", name: "order[distributor_id]", 'ng-model' => 'distributor_id'} + %option{"ng-repeat" => "shop in shops", "ng-value" => "shop.id", "ng-selected" => "distributor_id == shop.id", "ng-bind" => "shop.name"} + + .omega.six.columns + .field + %label{for: "order_order_cycle_id"} Order Cycle + %select{id: "order_order_cycle_id", name: "order[order_cycle_id]", 'ng-model' => 'order_cycle_id'} + %option{"ng-repeat" => "oc in orderCycles", "ng-value" => "oc.id", "ng-selected" => "order_cycle_id == oc.id", "ng-bind" => "oc.name"} diff --git a/app/views/spree/admin/line_items/create.js.erb b/app/views/spree/admin/line_items/create.js.erb new file mode 100644 index 0000000000..58afe5c8ef --- /dev/null +++ b/app/views/spree/admin/line_items/create.js.erb @@ -0,0 +1,5 @@ +// The admin order form contains angular directives, so it needs to be +// compiled before insertion into the DOM +var scope = angular.element("#order-form-wrapper").scope(); +$("#order-form-wrapper").html(scope.$compile('<%= escape_javascript(render :partial => "spree/admin/orders/form") %>')(scope)); +scope.$apply(); diff --git a/app/views/spree/admin/orders/_distribution_fields.html.haml b/app/views/spree/admin/orders/_distribution_fields.html.haml deleted file mode 100644 index 01753e025b..0000000000 --- a/app/views/spree/admin/orders/_distribution_fields.html.haml +++ /dev/null @@ -1,14 +0,0 @@ -%fieldset.no-border-bottom - %legend{align: 'center'} Distribution - - .alpha.six.columns - .field - %label{for: "distributor_id"} Distributor - %select{id: "distributor_id", 'ng-model' => "", 'ng-options' => ''} - -#= f.collection_select :distributor_id, Enterprise.is_distributor.managed_by(spree_current_user), :id, :name, include_blank: true - - .omega.six.columns - .field - %label{for: "order_cycle_id"} Order Cycle - %select{id: "order_cycle_id", 'ng-model' => "", 'ng-options' => ''} - -#= f.collection_select :order_cycle_id, OrderCycle.managed_by(spree_current_user), :id, :name, include_blank: true diff --git a/app/views/spree/admin/orders/new.html.haml b/app/views/spree/admin/orders/new.html.haml index 50b58ce62f..0404790595 100644 --- a/app/views/spree/admin/orders/new.html.haml +++ b/app/views/spree/admin/orders/new.html.haml @@ -14,14 +14,13 @@ %div{"data-hook" => "admin_order_new_header"} = render 'spree/shared/error_messages', :target => @order -= render 'distribution_fields' +%div{"ng-app" => "admin.orders", "ng-controller" => "ordersCtrl"} + = render 'add_product' -= render 'add_product' - -- unless @order.line_items.any? - %div{"data-hook" => "admin_order_new_form"} - #order-form-wrapper - = render 'form' + - unless @order.line_items.any? + %div{"data-hook" => "admin_order_new_form"} + #order-form-wrapper + = render 'form' - content_for :head do = javascript_tag 'var expand_variants = true;' diff --git a/spec/features/admin/orders_spec.rb b/spec/features/admin/orders_spec.rb index 575d37d7e7..ba085b1a89 100644 --- a/spec/features/admin/orders_spec.rb +++ b/spec/features/admin/orders_spec.rb @@ -22,23 +22,24 @@ feature %q{ end scenario "creating an order with distributor and order cycle", js: true, retry: 3 do - order_cycle = create(:order_cycle) - distributor = order_cycle.distributors.first - product = order_cycle.products.first + distributor = create(:distributor_enterprise) + product = create(:simple_product) + order_cycle = create(:simple_order_cycle, distributors: [distributor], variants: [product.variants.first]) login_to_admin_section visit '/admin/orders' click_link 'New Order' + select distributor.name, from: 'order_distributor_id' + select order_cycle.name, from: 'order_order_cycle_id' + page.should have_content 'ADD PRODUCT' targetted_select2_search product.name, from: '#add_variant_id', dropdown_css: '.select2-drop' click_link 'Add' page.has_selector? "table.index tbody[data-hook='admin_order_form_line_items'] tr" # Wait for JS page.should have_selector 'td', text: product.name - select distributor.name, from: 'order_distributor_id' - select order_cycle.name, from: 'order_order_cycle_id' click_button 'Update' page.should have_selector 'h1', text: 'Customer Details' From 815694de31e1f7efe2cbc7dd687bca406ca24101 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Fri, 4 Dec 2015 08:48:54 +1100 Subject: [PATCH 06/27] Move orders/edit template from Spree --- app/views/spree/admin/orders/edit.html.haml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 app/views/spree/admin/orders/edit.html.haml diff --git a/app/views/spree/admin/orders/edit.html.haml b/app/views/spree/admin/orders/edit.html.haml new file mode 100644 index 0000000000..d04243db30 --- /dev/null +++ b/app/views/spree/admin/orders/edit.html.haml @@ -0,0 +1,19 @@ += csrf_meta_tags + +- content_for :page_actions do + %li= event_links + %li= button_link_to t(:resend), resend_admin_order_url(@order), :method => :post, :icon => 'icon-email' + %li= button_link_to t(:back_to_orders_list), admin_orders_path, :icon => 'icon-arrow-left' + += render :partial => 'spree/admin/shared/order_tabs', :locals => { :current => 'Order Details' } +%div{"data-hook" => "admin_order_edit_header"} + = render :partial => 'spree/shared/error_messages', :locals => { :target => @order } + += render :partial => 'add_product' + +%div{"data-hook" => "admin_order_edit_form"} + #order-form-wrapper + = render :partial => 'form', :locals => { :order => @order } + +- content_for :head do + = javascript_tag 'var expand_variants = true;' From 6e7b6b5dfcfa7fb59e14a56d06b1abc2bf9a8f47 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Fri, 4 Dec 2015 08:50:38 +1100 Subject: [PATCH 07/27] Tidy render partial calls and hash syntax --- app/views/spree/admin/orders/edit.html.haml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/app/views/spree/admin/orders/edit.html.haml b/app/views/spree/admin/orders/edit.html.haml index d04243db30..a26dfdde4b 100644 --- a/app/views/spree/admin/orders/edit.html.haml +++ b/app/views/spree/admin/orders/edit.html.haml @@ -2,18 +2,19 @@ - content_for :page_actions do %li= event_links - %li= button_link_to t(:resend), resend_admin_order_url(@order), :method => :post, :icon => 'icon-email' - %li= button_link_to t(:back_to_orders_list), admin_orders_path, :icon => 'icon-arrow-left' + %li= button_link_to t(:resend), resend_admin_order_url(@order), method: :post, icon: 'icon-email' + %li= button_link_to t(:back_to_orders_list), admin_orders_path, icon: 'icon-arrow-left' + += render 'spree/admin/shared/order_tabs', current: 'Order Details' -= render :partial => 'spree/admin/shared/order_tabs', :locals => { :current => 'Order Details' } %div{"data-hook" => "admin_order_edit_header"} - = render :partial => 'spree/shared/error_messages', :locals => { :target => @order } + = render 'spree/shared/error_messages', target: @order -= render :partial => 'add_product' += render 'add_product' %div{"data-hook" => "admin_order_edit_form"} #order-form-wrapper - = render :partial => 'form', :locals => { :order => @order } + = render 'form', order: @order - content_for :head do = javascript_tag 'var expand_variants = true;' From cbaf2a0cb374654268aae2487adf8fc4b93a0e90 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Fri, 4 Dec 2015 09:03:44 +1100 Subject: [PATCH 08/27] Angularise edit order form --- .../orders/controllers/orders_controller.js.coffee | 5 ++++- .../spree/admin/orders_controller_decorator.rb | 2 +- app/views/spree/admin/orders/edit.html.haml | 12 ++++++++---- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/app/assets/javascripts/admin/orders/controllers/orders_controller.js.coffee b/app/assets/javascripts/admin/orders/controllers/orders_controller.js.coffee index 826bc6ed11..0b01bb48ee 100644 --- a/app/assets/javascripts/admin/orders/controllers/orders_controller.js.coffee +++ b/app/assets/javascripts/admin/orders/controllers/orders_controller.js.coffee @@ -1,4 +1,7 @@ -angular.module("admin.orders").controller "ordersCtrl", ($scope, $compile, shops, orderCycles) -> +angular.module("admin.orders").controller "ordersCtrl", ($scope, $compile, $attrs, shops, orderCycles) -> $scope.$compile = $compile $scope.shops = shops $scope.orderCycles = orderCycles + + $scope.distributor_id = $attrs.ofnDistributorId + $scope.order_cycle_id = $attrs.ofnOrderCycleId \ No newline at end of file diff --git a/app/controllers/spree/admin/orders_controller_decorator.rb b/app/controllers/spree/admin/orders_controller_decorator.rb index 39456aaf06..e6a48770b2 100644 --- a/app/controllers/spree/admin/orders_controller_decorator.rb +++ b/app/controllers/spree/admin/orders_controller_decorator.rb @@ -10,7 +10,7 @@ Spree::Admin::OrdersController.class_eval do # in an auth failure as the @order object is nil for collection actions before_filter :check_authorization, except: [:bulk_management, :managed] - before_filter :load_distribution_choices, only: :new + before_filter :load_distribution_choices, only: [:new, :edit] # After updating an order, the fees should be updated as well # Currently, adding or deleting line items does not trigger updating the diff --git a/app/views/spree/admin/orders/edit.html.haml b/app/views/spree/admin/orders/edit.html.haml index a26dfdde4b..4daddc2a2f 100644 --- a/app/views/spree/admin/orders/edit.html.haml +++ b/app/views/spree/admin/orders/edit.html.haml @@ -5,16 +5,20 @@ %li= button_link_to t(:resend), resend_admin_order_url(@order), method: :post, icon: 'icon-email' %li= button_link_to t(:back_to_orders_list), admin_orders_path, icon: 'icon-arrow-left' += admin_inject_shops 'admin.orders' += admin_inject_order_cycles + = render 'spree/admin/shared/order_tabs', current: 'Order Details' %div{"data-hook" => "admin_order_edit_header"} = render 'spree/shared/error_messages', target: @order -= render 'add_product' +%div{"ng-app" => "admin.orders", "ng-controller" => "ordersCtrl", "ofn-distributor-id" => @order.distributor_id, "ofn-order-cycle-id" => @order.order_cycle_id} + = render 'add_product' -%div{"data-hook" => "admin_order_edit_form"} - #order-form-wrapper - = render 'form', order: @order + %div{"data-hook" => "admin_order_edit_form"} + #order-form-wrapper + = render 'form', order: @order - content_for :head do = javascript_tag 'var expand_variants = true;' From 2081744cf6c465abaa90a65e5f5f399eed22276b Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Fri, 4 Dec 2015 09:07:40 +1100 Subject: [PATCH 09/27] Fix spec --- spec/features/admin/orders_spec.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/spec/features/admin/orders_spec.rb b/spec/features/admin/orders_spec.rb index ba085b1a89..fc978d1643 100644 --- a/spec/features/admin/orders_spec.rb +++ b/spec/features/admin/orders_spec.rb @@ -132,6 +132,9 @@ feature %q{ visit '/admin/orders' click_link 'New Order' + select distributor1.name, from: 'order_distributor_id' + select order_cycle1.name, from: 'order_order_cycle_id' + expect(page).to have_content 'ADD PRODUCT' targetted_select2_search product.name, from: '#add_variant_id', dropdown_css: '.select2-drop' @@ -145,8 +148,6 @@ feature %q{ expect(page).to have_select 'order_order_cycle_id', with_options: [order_cycle1.name] expect(page).to_not have_select 'order_order_cycle_id', with_options: [order_cycle2.name] - select distributor1.name, from: 'order_distributor_id' - select order_cycle1.name, from: 'order_order_cycle_id' click_button 'Update' expect(page).to have_selector 'h1', text: 'Customer Details' From c74463404d98c1fce30b9e9a9d68101a580a6f48 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Fri, 4 Dec 2015 12:16:45 +1100 Subject: [PATCH 10/27] Only show order cycle options that include the chosen distributor --- .../controllers/orders_controller.js.coffee | 6 +++- app/helpers/admin/injection_helper.rb | 2 +- .../add_distribution_fields.html.haml.deface | 2 +- .../api/admin/basic_order_cycle_serializer.rb | 8 ++++-- spec/features/admin/orders_spec.rb | 21 +++++++------- .../orders_controller_spec.js.coffee | 28 +++++++++++++++++++ 6 files changed, 52 insertions(+), 15 deletions(-) create mode 100644 spec/javascripts/unit/admin/orders/controllers/orders_controller_spec.js.coffee diff --git a/app/assets/javascripts/admin/orders/controllers/orders_controller.js.coffee b/app/assets/javascripts/admin/orders/controllers/orders_controller.js.coffee index 0b01bb48ee..e87501be42 100644 --- a/app/assets/javascripts/admin/orders/controllers/orders_controller.js.coffee +++ b/app/assets/javascripts/admin/orders/controllers/orders_controller.js.coffee @@ -4,4 +4,8 @@ angular.module("admin.orders").controller "ordersCtrl", ($scope, $compile, $attr $scope.orderCycles = orderCycles $scope.distributor_id = $attrs.ofnDistributorId - $scope.order_cycle_id = $attrs.ofnOrderCycleId \ No newline at end of file + $scope.order_cycle_id = $attrs.ofnOrderCycleId + + $scope.validOrderCycle = (oc, index, array) -> + distributor_ids = (d.id for d in oc.distributors) + distributor_ids.indexOf(parseInt($scope.distributor_id)) != -1 diff --git a/app/helpers/admin/injection_helper.rb b/app/helpers/admin/injection_helper.rb index aa45f4ac2b..490e3dc00b 100644 --- a/app/helpers/admin/injection_helper.rb +++ b/app/helpers/admin/injection_helper.rb @@ -75,7 +75,7 @@ module Admin end def admin_inject_order_cycles - admin_inject_json_ams_array "admin.orders", "orderCycles", @order_cycles, Api::Admin::IdNameSerializer, current_user: spree_current_user + admin_inject_json_ams_array "admin.orders", "orderCycles", @order_cycles, Api::Admin::BasicOrderCycleSerializer, current_user: spree_current_user end def admin_inject_spree_api_key diff --git a/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface b/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface index a8e716769d..e6754e37f0 100644 --- a/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface +++ b/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface @@ -26,4 +26,4 @@ .field %label{for: "order_order_cycle_id"} Order Cycle %select{id: "order_order_cycle_id", name: "order[order_cycle_id]", 'ng-model' => 'order_cycle_id'} - %option{"ng-repeat" => "oc in orderCycles", "ng-value" => "oc.id", "ng-selected" => "order_cycle_id == oc.id", "ng-bind" => "oc.name"} + %option{"ng-repeat" => "oc in orderCycles | filter:validOrderCycle", "ng-value" => "oc.id", "ng-selected" => "order_cycle_id == oc.id", "ng-bind" => "oc.name"} diff --git a/app/serializers/api/admin/basic_order_cycle_serializer.rb b/app/serializers/api/admin/basic_order_cycle_serializer.rb index e94795821a..5984a64ecb 100644 --- a/app/serializers/api/admin/basic_order_cycle_serializer.rb +++ b/app/serializers/api/admin/basic_order_cycle_serializer.rb @@ -5,10 +5,14 @@ class Api::Admin::BasicOrderCycleSerializer < ActiveModel::Serializer has_many :distributors, serializer: Api::Admin::IdNameSerializer def first_order - object.orders_open_at.strftime("%F") + object.orders_open_at.andand.strftime("%F") end def last_order - (object.orders_close_at + 1.day).strftime("%F") + if object.orders_close_at.present? + (object.orders_close_at + 1.day).strftime("%F") + else + nil + end end end diff --git a/spec/features/admin/orders_spec.rb b/spec/features/admin/orders_spec.rb index fc978d1643..fd312ba0c0 100644 --- a/spec/features/admin/orders_spec.rb +++ b/spec/features/admin/orders_spec.rb @@ -11,7 +11,7 @@ feature %q{ @user = create(:user) @product = create(:simple_product) @distributor = create(:distributor_enterprise, charges_sales_tax: true) - @order_cycle = create(:simple_order_cycle, distributors: [@distributor], variants: [@product.variants.first]) + @order_cycle = create(:simple_order_cycle, name: 'One', distributors: [@distributor], variants: [@product.variants.first]) @order = create(:order_with_totals_and_distribution, user: @user, distributor: @distributor, order_cycle: @order_cycle, state: 'complete', payment_state: 'balance_due') @@ -22,30 +22,31 @@ feature %q{ end scenario "creating an order with distributor and order cycle", js: true, retry: 3 do - distributor = create(:distributor_enterprise) - product = create(:simple_product) - order_cycle = create(:simple_order_cycle, distributors: [distributor], variants: [product.variants.first]) + create(:simple_order_cycle, name: 'Two') login_to_admin_section visit '/admin/orders' click_link 'New Order' - select distributor.name, from: 'order_distributor_id' - select order_cycle.name, from: 'order_order_cycle_id' + # When we select a distributor, it should limit order cycle selection to those for that distributor + page.should have_select 'order_order_cycle_id', options: [''] + select @distributor.name, from: 'order_distributor_id' + page.should have_select 'order_order_cycle_id', options: ['', 'One'] + select @order_cycle.name, from: 'order_order_cycle_id' page.should have_content 'ADD PRODUCT' - targetted_select2_search product.name, from: '#add_variant_id', dropdown_css: '.select2-drop' + targetted_select2_search @product.name, from: '#add_variant_id', dropdown_css: '.select2-drop' click_link 'Add' page.has_selector? "table.index tbody[data-hook='admin_order_form_line_items'] tr" # Wait for JS - page.should have_selector 'td', text: product.name + page.should have_selector 'td', text: @product.name click_button 'Update' page.should have_selector 'h1', text: 'Customer Details' o = Spree::Order.last - o.distributor.should == distributor - o.order_cycle.should == order_cycle + o.distributor.should == @distributor + o.order_cycle.should == @order_cycle end scenario "can add a product to an existing order", js: true, retry: 3 do diff --git a/spec/javascripts/unit/admin/orders/controllers/orders_controller_spec.js.coffee b/spec/javascripts/unit/admin/orders/controllers/orders_controller_spec.js.coffee new file mode 100644 index 0000000000..6259daa6e8 --- /dev/null +++ b/spec/javascripts/unit/admin/orders/controllers/orders_controller_spec.js.coffee @@ -0,0 +1,28 @@ +describe "ordersCtrl", -> + ctrl = null + scope = {} + attrs = {} + shops = [] + orderCycles = [ + {id: 10, distributors: [{id: 1, name: 'One'}]} + {id: 20, distributors: [{id: 2, name: 'Two'}]} + ] + + beforeEach -> + scope = {} + + module('admin.orders') + inject ($controller) -> + ctrl = $controller 'ordersCtrl', {$scope: scope, $attrs: attrs, shops: shops, orderCycles: orderCycles} + + + describe "finding valid order cycles for a distributor", -> + order_cycle = {id: 10, distributors: [{id: 1, name: 'One'}]} + + it "returns true when the order cycle includes the distributor", -> + scope.distributor_id = '1' + expect(scope.validOrderCycle(order_cycle, 1, [order_cycle])).toBe true + + it "returns false otherwise", -> + scope.distributor_id = '2' + expect(scope.validOrderCycle(order_cycle, 1, [order_cycle])).toBe false From 1026b81d0c60a8d99395df12b96d0f3097c78057 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Fri, 4 Dec 2015 12:24:46 +1100 Subject: [PATCH 11/27] Do not show order cycle choice until distributor is chosen --- .../admin/orders/_form/add_distribution_fields.html.haml.deface | 2 +- spec/features/admin/orders_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface b/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface index e6754e37f0..dfdb3de5d2 100644 --- a/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface +++ b/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface @@ -23,7 +23,7 @@ %option{"ng-repeat" => "shop in shops", "ng-value" => "shop.id", "ng-selected" => "distributor_id == shop.id", "ng-bind" => "shop.name"} .omega.six.columns - .field + .field{"ng-show" => "distributor_id"} %label{for: "order_order_cycle_id"} Order Cycle %select{id: "order_order_cycle_id", name: "order[order_cycle_id]", 'ng-model' => 'order_cycle_id'} %option{"ng-repeat" => "oc in orderCycles | filter:validOrderCycle", "ng-value" => "oc.id", "ng-selected" => "order_cycle_id == oc.id", "ng-bind" => "oc.name"} diff --git a/spec/features/admin/orders_spec.rb b/spec/features/admin/orders_spec.rb index fd312ba0c0..e0bcd9cd6f 100644 --- a/spec/features/admin/orders_spec.rb +++ b/spec/features/admin/orders_spec.rb @@ -30,7 +30,7 @@ feature %q{ click_link 'New Order' # When we select a distributor, it should limit order cycle selection to those for that distributor - page.should have_select 'order_order_cycle_id', options: [''] + page.should_not have_select 'order_order_cycle_id' select @distributor.name, from: 'order_distributor_id' page.should have_select 'order_order_cycle_id', options: ['', 'One'] select @order_cycle.name, from: 'order_order_cycle_id' From 3419198635671686e07dc038593786840b9965f0 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Fri, 4 Dec 2015 12:51:18 +1100 Subject: [PATCH 12/27] Disable distributors that do not have an order cycle --- .../admin/orders/controllers/orders_controller.js.coffee | 8 +++++++- .../_form/add_distribution_fields.html.haml.deface | 2 +- spec/features/admin/orders_spec.rb | 4 ++++ .../orders/controllers/orders_controller_spec.js.coffee | 9 +++++++++ 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/admin/orders/controllers/orders_controller.js.coffee b/app/assets/javascripts/admin/orders/controllers/orders_controller.js.coffee index e87501be42..797ee7c42f 100644 --- a/app/assets/javascripts/admin/orders/controllers/orders_controller.js.coffee +++ b/app/assets/javascripts/admin/orders/controllers/orders_controller.js.coffee @@ -7,5 +7,11 @@ angular.module("admin.orders").controller "ordersCtrl", ($scope, $compile, $attr $scope.order_cycle_id = $attrs.ofnOrderCycleId $scope.validOrderCycle = (oc, index, array) -> + $scope.orderCycleHasDistributor oc, parseInt($scope.distributor_id) + + $scope.distributorHasOrderCycles = (distributor) -> + (oc for oc in orderCycles when @orderCycleHasDistributor(oc, distributor.id)).length > 0 + + $scope.orderCycleHasDistributor = (oc, distributor_id) -> distributor_ids = (d.id for d in oc.distributors) - distributor_ids.indexOf(parseInt($scope.distributor_id)) != -1 + distributor_ids.indexOf(distributor_id) != -1 diff --git a/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface b/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface index dfdb3de5d2..af5013f040 100644 --- a/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface +++ b/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface @@ -20,7 +20,7 @@ .field %label{for: "order_distributor_id"} Distributor %select{id: "order_distributor_id", name: "order[distributor_id]", 'ng-model' => 'distributor_id'} - %option{"ng-repeat" => "shop in shops", "ng-value" => "shop.id", "ng-selected" => "distributor_id == shop.id", "ng-bind" => "shop.name"} + %option{"ng-repeat" => "shop in shops", "ng-value" => "shop.id", "ng-selected" => "distributor_id == shop.id", "ng-disabled" => "!distributorHasOrderCycles(shop)", "ng-bind" => "shop.name"} .omega.six.columns .field{"ng-show" => "distributor_id"} diff --git a/spec/features/admin/orders_spec.rb b/spec/features/admin/orders_spec.rb index e0bcd9cd6f..9eb811b191 100644 --- a/spec/features/admin/orders_spec.rb +++ b/spec/features/admin/orders_spec.rb @@ -22,6 +22,7 @@ feature %q{ end scenario "creating an order with distributor and order cycle", js: true, retry: 3 do + distributor_disabled = create(:distributor_enterprise) create(:simple_order_cycle, name: 'Two') login_to_admin_section @@ -29,6 +30,9 @@ feature %q{ visit '/admin/orders' click_link 'New Order' + # Distributors without an order cycle should be shown as disabled + page.should have_selector "option[value='#{distributor_disabled.id}'][disabled='disabled']" + # When we select a distributor, it should limit order cycle selection to those for that distributor page.should_not have_select 'order_order_cycle_id' select @distributor.name, from: 'order_distributor_id' diff --git a/spec/javascripts/unit/admin/orders/controllers/orders_controller_spec.js.coffee b/spec/javascripts/unit/admin/orders/controllers/orders_controller_spec.js.coffee index 6259daa6e8..718120e5e1 100644 --- a/spec/javascripts/unit/admin/orders/controllers/orders_controller_spec.js.coffee +++ b/spec/javascripts/unit/admin/orders/controllers/orders_controller_spec.js.coffee @@ -26,3 +26,12 @@ describe "ordersCtrl", -> it "returns false otherwise", -> scope.distributor_id = '2' expect(scope.validOrderCycle(order_cycle, 1, [order_cycle])).toBe false + + describe "checking if a distributor has order cycles", -> + it "returns true when it does", -> + distributor = {id: 1} + expect(scope.distributorHasOrderCycles(distributor)).toBe true + + it "returns false otherwise", -> + distributor = {id: 3} + expect(scope.distributorHasOrderCycles(distributor)).toBe false From 80ebaece2dddd7ad04dfe27bccf30dbf952b4de9 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Fri, 4 Dec 2015 12:54:00 +1100 Subject: [PATCH 13/27] Sort distribution choices by name --- app/controllers/spree/admin/orders_controller_decorator.rb | 4 ++-- app/models/order_cycle.rb | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/controllers/spree/admin/orders_controller_decorator.rb b/app/controllers/spree/admin/orders_controller_decorator.rb index e6a48770b2..082d6319b0 100644 --- a/app/controllers/spree/admin/orders_controller_decorator.rb +++ b/app/controllers/spree/admin/orders_controller_decorator.rb @@ -117,7 +117,7 @@ Spree::Admin::OrdersController.class_eval do end def load_distribution_choices - @shops = Enterprise.is_distributor.managed_by(spree_current_user) - @order_cycles = OrderCycle.managed_by(spree_current_user) + @shops = Enterprise.is_distributor.managed_by(spree_current_user).by_name + @order_cycles = OrderCycle.managed_by(spree_current_user).by_name end end diff --git a/app/models/order_cycle.rb b/app/models/order_cycle.rb index 302cf42a06..2488e3ac5b 100644 --- a/app/models/order_cycle.rb +++ b/app/models/order_cycle.rb @@ -24,6 +24,8 @@ class OrderCycle < ActiveRecord::Base scope :soonest_opening, lambda { upcoming.order('order_cycles.orders_open_at ASC') } + scope :by_name, order('name') + scope :distributing_product, lambda { |product| joins(:exchanges). merge(Exchange.outgoing). From 932ac45ea55afa7d48ea1dd841fb525953d9393b Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Fri, 4 Dec 2015 14:15:39 +1100 Subject: [PATCH 14/27] Do not show form until distribution has been chosen --- .../admin/orders/controllers/orders_controller.js.coffee | 3 +++ .../admin/orders/_form/hide_form_until_distribution.deface | 2 ++ app/views/spree/admin/orders/new.html.haml | 3 ++- 3 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 app/overrides/spree/admin/orders/_form/hide_form_until_distribution.deface diff --git a/app/assets/javascripts/admin/orders/controllers/orders_controller.js.coffee b/app/assets/javascripts/admin/orders/controllers/orders_controller.js.coffee index 797ee7c42f..a5ddc19115 100644 --- a/app/assets/javascripts/admin/orders/controllers/orders_controller.js.coffee +++ b/app/assets/javascripts/admin/orders/controllers/orders_controller.js.coffee @@ -15,3 +15,6 @@ angular.module("admin.orders").controller "ordersCtrl", ($scope, $compile, $attr $scope.orderCycleHasDistributor = (oc, distributor_id) -> distributor_ids = (d.id for d in oc.distributors) distributor_ids.indexOf(distributor_id) != -1 + + $scope.distributionChosen = -> + $scope.distributor_id && $scope.order_cycle_id diff --git a/app/overrides/spree/admin/orders/_form/hide_form_until_distribution.deface b/app/overrides/spree/admin/orders/_form/hide_form_until_distribution.deface new file mode 100644 index 0000000000..7fe5652aae --- /dev/null +++ b/app/overrides/spree/admin/orders/_form/hide_form_until_distribution.deface @@ -0,0 +1,2 @@ +add_to_attributes "table.index, [data-hook='admin_order_form_buttons']" +attributes "ng-show" => "distributionChosen()" diff --git a/app/views/spree/admin/orders/new.html.haml b/app/views/spree/admin/orders/new.html.haml index 0404790595..3c5466df14 100644 --- a/app/views/spree/admin/orders/new.html.haml +++ b/app/views/spree/admin/orders/new.html.haml @@ -15,7 +15,8 @@ = render 'spree/shared/error_messages', :target => @order %div{"ng-app" => "admin.orders", "ng-controller" => "ordersCtrl"} - = render 'add_product' + %div{"ng-show" => "distributionChosen()"} + = render 'add_product' - unless @order.line_items.any? %div{"data-hook" => "admin_order_new_form"} From 222b390b31392ab155bb1119a7fb8610c9399524 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Fri, 4 Dec 2015 15:00:52 +1100 Subject: [PATCH 15/27] Fix error display --- .../admin/orders_controller_decorator.rb | 2 +- spec/features/admin/orders_spec.rb | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/app/controllers/spree/admin/orders_controller_decorator.rb b/app/controllers/spree/admin/orders_controller_decorator.rb index 082d6319b0..4d336dfb4e 100644 --- a/app/controllers/spree/admin/orders_controller_decorator.rb +++ b/app/controllers/spree/admin/orders_controller_decorator.rb @@ -10,7 +10,7 @@ Spree::Admin::OrdersController.class_eval do # in an auth failure as the @order object is nil for collection actions before_filter :check_authorization, except: [:bulk_management, :managed] - before_filter :load_distribution_choices, only: [:new, :edit] + before_filter :load_distribution_choices, only: [:new, :edit, :update] # After updating an order, the fees should be updated as well # Currently, adding or deleting line items does not trigger updating the diff --git a/spec/features/admin/orders_spec.rb b/spec/features/admin/orders_spec.rb index 9eb811b191..6554c614a6 100644 --- a/spec/features/admin/orders_spec.rb +++ b/spec/features/admin/orders_spec.rb @@ -67,6 +67,28 @@ feature %q{ @order.line_items(true).map(&:product).should include @product end + scenario "displays error when incorrect distribution for products is chosen", js: true do + d = create(:distributor_enterprise) + oc = create(:simple_order_cycle, distributors: [d]) + + @order.state = 'cart'; @order.completed_at = nil; @order.save + + login_to_admin_section + visit '/admin/orders' + uncheck 'Only show complete orders' + click_button 'Filter Results' + + click_edit + + select d.name, from: 'order_distributor_id' + select oc.name, from: 'order_order_cycle_id' + + click_button 'Update And Recalculate Fees' + + page.should have_content "Distributor or order cycle cannot supply the products in your cart" + end + + scenario "can't add products to an order outside the order's hub and order cycle", js: true do product = create(:simple_product) From 60e971ad63845ed04e0495d3d35ec5f5a84598b1 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Thu, 10 Dec 2015 11:47:18 +1100 Subject: [PATCH 16/27] Take variant overrides into account for price when admin adds line item to order --- .../admin/line_items_controller_decorator.rb | 18 ++++++++++++++++++ .../spree/admin/line_items_controller_spec.rb | 17 +++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/app/controllers/spree/admin/line_items_controller_decorator.rb b/app/controllers/spree/admin/line_items_controller_decorator.rb index 2c224135ba..5e95681f95 100644 --- a/app/controllers/spree/admin/line_items_controller_decorator.rb +++ b/app/controllers/spree/admin/line_items_controller_decorator.rb @@ -17,6 +17,24 @@ Spree::Admin::LineItemsController.class_eval do end end + def create + variant = Spree::Variant.find(params[:line_item][:variant_id]) + OpenFoodNetwork::ScopeVariantToHub.new(@order.distributor).scope(variant) + + @line_item = @order.add_variant(variant, params[:line_item][:quantity].to_i) + + if @order.save + respond_with(@line_item) do |format| + format.html { render :partial => 'spree/admin/orders/form', :locals => { :order => @order.reload } } + end + else + respond_with(@line_item) do |format| + format.js { render :action => 'create', :locals => { :order => @order.reload } } + end + end + end + + private def load_order diff --git a/spec/controllers/spree/admin/line_items_controller_spec.rb b/spec/controllers/spree/admin/line_items_controller_spec.rb index 13a7723122..b874230863 100644 --- a/spec/controllers/spree/admin/line_items_controller_spec.rb +++ b/spec/controllers/spree/admin/line_items_controller_spec.rb @@ -126,6 +126,23 @@ describe Spree::Admin::LineItemsController do end end + describe "#create" do + let!(:variant) { create(:variant, price: 88) } + let!(:vo) { create(:variant_override, hub: distributor, variant: variant, price: 11.11) } + let!(:distributor) { create(:distributor_enterprise) } + let!(:order_cycle) { create(:simple_order_cycle, distributors: [distributor], variants: [variant]) } + let!(:order) { create(:order, distributor: distributor, order_cycle: order_cycle) } + let(:params) { { order_id: order.number, line_item: { variant_id: variant.id, quantity: 1 } } } + + before { login_as_admin } + + it "takes variant overrides into account for price" do + spree_post :create, params + + order.line_items(:reload).last.price.should == 11.11 + end + end + describe "#update" do let(:supplier) { create(:supplier_enterprise) } let(:distributor1) { create(:distributor_enterprise) } From 76d4fbccf990cdc8ff4b2e583a7cc2ae93902ed6 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Fri, 11 Dec 2015 07:38:53 +1100 Subject: [PATCH 17/27] Use select2 for order cycle selection --- .../admin/orders_controller_decorator.rb | 7 +++- .../add_distribution_fields.html.haml.deface | 4 +- .../spree/admin/line_items/create.js.erb | 1 + spec/features/admin/orders_spec.rb | 16 ++++---- spec/support/matchers/select2_matchers.rb | 40 ++++++++++++++++++- 5 files changed, 55 insertions(+), 13 deletions(-) diff --git a/app/controllers/spree/admin/orders_controller_decorator.rb b/app/controllers/spree/admin/orders_controller_decorator.rb index 4d336dfb4e..b5a2bb4f95 100644 --- a/app/controllers/spree/admin/orders_controller_decorator.rb +++ b/app/controllers/spree/admin/orders_controller_decorator.rb @@ -118,6 +118,11 @@ Spree::Admin::OrdersController.class_eval do def load_distribution_choices @shops = Enterprise.is_distributor.managed_by(spree_current_user).by_name - @order_cycles = OrderCycle.managed_by(spree_current_user).by_name + + ocs = OrderCycle.managed_by(spree_current_user) + @order_cycles = ocs.soonest_closing + + ocs.soonest_opening + + ocs.closed + + ocs.undated end end diff --git a/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface b/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface index af5013f040..08670edc55 100644 --- a/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface +++ b/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface @@ -19,11 +19,11 @@ .alpha.six.columns .field %label{for: "order_distributor_id"} Distributor - %select{id: "order_distributor_id", name: "order[distributor_id]", 'ng-model' => 'distributor_id'} + %select.fullwidth{id: "order_distributor_id", name: "order[distributor_id]", 'ng-model' => 'distributor_id'} %option{"ng-repeat" => "shop in shops", "ng-value" => "shop.id", "ng-selected" => "distributor_id == shop.id", "ng-disabled" => "!distributorHasOrderCycles(shop)", "ng-bind" => "shop.name"} .omega.six.columns .field{"ng-show" => "distributor_id"} %label{for: "order_order_cycle_id"} Order Cycle - %select{id: "order_order_cycle_id", name: "order[order_cycle_id]", 'ng-model' => 'order_cycle_id'} + %select.select2.fullwidth{id: "order_order_cycle_id", name: "order[order_cycle_id]", 'ng-model' => 'order_cycle_id'} %option{"ng-repeat" => "oc in orderCycles | filter:validOrderCycle", "ng-value" => "oc.id", "ng-selected" => "order_cycle_id == oc.id", "ng-bind" => "oc.name"} diff --git a/app/views/spree/admin/line_items/create.js.erb b/app/views/spree/admin/line_items/create.js.erb index 58afe5c8ef..f1644d2203 100644 --- a/app/views/spree/admin/line_items/create.js.erb +++ b/app/views/spree/admin/line_items/create.js.erb @@ -3,3 +3,4 @@ var scope = angular.element("#order-form-wrapper").scope(); $("#order-form-wrapper").html(scope.$compile('<%= escape_javascript(render :partial => "spree/admin/orders/form") %>')(scope)); scope.$apply(); +$('select.select2').select2({allowClear: true}); diff --git a/spec/features/admin/orders_spec.rb b/spec/features/admin/orders_spec.rb index 6554c614a6..d8dfa469a1 100644 --- a/spec/features/admin/orders_spec.rb +++ b/spec/features/admin/orders_spec.rb @@ -34,10 +34,10 @@ feature %q{ page.should have_selector "option[value='#{distributor_disabled.id}'][disabled='disabled']" # When we select a distributor, it should limit order cycle selection to those for that distributor - page.should_not have_select 'order_order_cycle_id' + page.should_not have_select2 'order_order_cycle_id' select @distributor.name, from: 'order_distributor_id' - page.should have_select 'order_order_cycle_id', options: ['', 'One'] - select @order_cycle.name, from: 'order_order_cycle_id' + page.should have_select2 'order_order_cycle_id', options: ['', 'One'] + select2_select @order_cycle.name, from: 'order_order_cycle_id' page.should have_content 'ADD PRODUCT' targetted_select2_search @product.name, from: '#add_variant_id', dropdown_css: '.select2-drop' @@ -81,7 +81,7 @@ feature %q{ click_edit select d.name, from: 'order_distributor_id' - select oc.name, from: 'order_order_cycle_id' + select2_select oc.name, from: 'order_order_cycle_id' click_button 'Update And Recalculate Fees' @@ -107,7 +107,7 @@ feature %q{ page.find('td.actions a.icon-edit').click page.should have_no_select 'order_distributor_id' - page.should have_no_select 'order_order_cycle_id' + page.should_not have_select2 'order_order_cycle_id' page.should have_selector 'p', text: "Distributor: #{@order.distributor.name}" page.should have_selector 'p', text: "Order cycle: None" @@ -160,7 +160,7 @@ feature %q{ click_link 'New Order' select distributor1.name, from: 'order_distributor_id' - select order_cycle1.name, from: 'order_order_cycle_id' + select2_select order_cycle1.name, from: 'order_order_cycle_id' expect(page).to have_content 'ADD PRODUCT' targetted_select2_search product.name, from: '#add_variant_id', dropdown_css: '.select2-drop' @@ -172,8 +172,8 @@ feature %q{ expect(page).to have_select 'order_distributor_id', with_options: [distributor1.name] expect(page).to_not have_select 'order_distributor_id', with_options: [distributor2.name] - expect(page).to have_select 'order_order_cycle_id', with_options: [order_cycle1.name] - expect(page).to_not have_select 'order_order_cycle_id', with_options: [order_cycle2.name] + expect(page).to have_select2 'order_order_cycle_id', with_options: [order_cycle1.name] + expect(page).to_not have_select2 'order_order_cycle_id', with_options: [order_cycle2.name] click_button 'Update' diff --git a/spec/support/matchers/select2_matchers.rb b/spec/support/matchers/select2_matchers.rb index cf67c7c7cb..e1f821753d 100644 --- a/spec/support/matchers/select2_matchers.rb +++ b/spec/support/matchers/select2_matchers.rb @@ -28,15 +28,43 @@ RSpec::Matchers.define :have_select2 do |id, options={}| end failure_message_for_should do |actual| - message = "expected to find select2 ##{@id}" + message = "expected to find select2 ##{@id}" message += " with #{@options.inspect}" if @options.any? message end match_for_should_not do |node| - raise "Not yet implemented" + @id, @options, @node = id, options, node + + #id = find_label_by_text(locator) + from = "#s2id_#{id}" + + results = [] + + results << node.has_no_selector?(from, wait: 1) + + # if results.all? + # results << selected_option_is(from, options[:selected]) if options.key? :selected + # end + + if results.none? + results << all_options_absent(from, options[:with_options]) if options.key? :with_options + #results << exact_options_present(from, options[:options]) if options.key? :options + #results << no_options_present(from, options[:without_options]) if options.key? :without_options + end + + if (options.keys & %i(selected options without_options)).any? + raise "Not yet implemented" + end + + results.any? end + failure_message_for_should_not do |actual| + message = "expected not to find select2 ##{@id}" + message += " with #{@options.inspect}" if @options.any? + message + end def all_options_present(from, options) with_select2_open(from) do @@ -46,6 +74,14 @@ RSpec::Matchers.define :have_select2 do |id, options={}| end end + def all_options_absent(from, options) + with_select2_open(from) do + options.all? do |option| + @node.has_no_selector? "div.select2-drop-active ul.select2-results li", text: option + end + end + end + def exact_options_present(from, options) with_select2_open(from) do @node.all("div.select2-drop-active ul.select2-results li").map(&:text) == options From e33ede0ec24980df26a346ddab986d32310bf63c Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Fri, 11 Dec 2015 10:30:55 +1100 Subject: [PATCH 18/27] Include order cycle status in new order form --- .../admin/orders/controllers/orders_controller.js.coffee | 2 ++ .../orders/_form/add_distribution_fields.html.haml.deface | 2 +- app/serializers/api/admin/basic_order_cycle_serializer.rb | 8 +++++++- spec/features/admin/orders_spec.rb | 6 +++--- .../orders/controllers/orders_controller_spec.js.coffee | 7 +++++-- 5 files changed, 18 insertions(+), 7 deletions(-) diff --git a/app/assets/javascripts/admin/orders/controllers/orders_controller.js.coffee b/app/assets/javascripts/admin/orders/controllers/orders_controller.js.coffee index a5ddc19115..6ad7f0bfb9 100644 --- a/app/assets/javascripts/admin/orders/controllers/orders_controller.js.coffee +++ b/app/assets/javascripts/admin/orders/controllers/orders_controller.js.coffee @@ -2,6 +2,8 @@ angular.module("admin.orders").controller "ordersCtrl", ($scope, $compile, $attr $scope.$compile = $compile $scope.shops = shops $scope.orderCycles = orderCycles + for oc in $scope.orderCycles + oc.name_and_status = "#{oc.name} (#{oc.status})" $scope.distributor_id = $attrs.ofnDistributorId $scope.order_cycle_id = $attrs.ofnOrderCycleId diff --git a/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface b/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface index 08670edc55..3fa7d3ea83 100644 --- a/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface +++ b/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface @@ -26,4 +26,4 @@ .field{"ng-show" => "distributor_id"} %label{for: "order_order_cycle_id"} Order Cycle %select.select2.fullwidth{id: "order_order_cycle_id", name: "order[order_cycle_id]", 'ng-model' => 'order_cycle_id'} - %option{"ng-repeat" => "oc in orderCycles | filter:validOrderCycle", "ng-value" => "oc.id", "ng-selected" => "order_cycle_id == oc.id", "ng-bind" => "oc.name"} + %option{"ng-repeat" => "oc in orderCycles | filter:validOrderCycle", "ng-value" => "oc.id", "ng-selected" => "order_cycle_id == oc.id", "ng-bind" => "oc.name_and_status"} diff --git a/app/serializers/api/admin/basic_order_cycle_serializer.rb b/app/serializers/api/admin/basic_order_cycle_serializer.rb index 5984a64ecb..3b3e29f83d 100644 --- a/app/serializers/api/admin/basic_order_cycle_serializer.rb +++ b/app/serializers/api/admin/basic_order_cycle_serializer.rb @@ -1,9 +1,15 @@ class Api::Admin::BasicOrderCycleSerializer < ActiveModel::Serializer - attributes :id, :name, :first_order, :last_order + include OrderCyclesHelper + + attributes :id, :name, :status, :first_order, :last_order has_many :suppliers, serializer: Api::Admin::IdNameSerializer has_many :distributors, serializer: Api::Admin::IdNameSerializer + def status + order_cycle_status_class object + end + def first_order object.orders_open_at.andand.strftime("%F") end diff --git a/spec/features/admin/orders_spec.rb b/spec/features/admin/orders_spec.rb index d8dfa469a1..cf1bf1c7ba 100644 --- a/spec/features/admin/orders_spec.rb +++ b/spec/features/admin/orders_spec.rb @@ -36,7 +36,7 @@ feature %q{ # When we select a distributor, it should limit order cycle selection to those for that distributor page.should_not have_select2 'order_order_cycle_id' select @distributor.name, from: 'order_distributor_id' - page.should have_select2 'order_order_cycle_id', options: ['', 'One'] + page.should have_select2 'order_order_cycle_id', options: ['', 'One (open)'] select2_select @order_cycle.name, from: 'order_order_cycle_id' page.should have_content 'ADD PRODUCT' @@ -172,8 +172,8 @@ feature %q{ expect(page).to have_select 'order_distributor_id', with_options: [distributor1.name] expect(page).to_not have_select 'order_distributor_id', with_options: [distributor2.name] - expect(page).to have_select2 'order_order_cycle_id', with_options: [order_cycle1.name] - expect(page).to_not have_select2 'order_order_cycle_id', with_options: [order_cycle2.name] + expect(page).to have_select2 'order_order_cycle_id', with_options: ["#{order_cycle1.name} (open)"] + expect(page).to_not have_select2 'order_order_cycle_id', with_options: ["#{order_cycle2.name} (open)"] click_button 'Update' diff --git a/spec/javascripts/unit/admin/orders/controllers/orders_controller_spec.js.coffee b/spec/javascripts/unit/admin/orders/controllers/orders_controller_spec.js.coffee index 718120e5e1..4ceeea277b 100644 --- a/spec/javascripts/unit/admin/orders/controllers/orders_controller_spec.js.coffee +++ b/spec/javascripts/unit/admin/orders/controllers/orders_controller_spec.js.coffee @@ -4,8 +4,8 @@ describe "ordersCtrl", -> attrs = {} shops = [] orderCycles = [ - {id: 10, distributors: [{id: 1, name: 'One'}]} - {id: 20, distributors: [{id: 2, name: 'Two'}]} + {id: 10, name: 'Ten', status: 'open', distributors: [{id: 1, name: 'One'}]} + {id: 20, name: 'Twenty', status: 'closed', distributors: [{id: 2, name: 'Two', status: 'closed'}]} ] beforeEach -> @@ -15,6 +15,9 @@ describe "ordersCtrl", -> inject ($controller) -> ctrl = $controller 'ordersCtrl', {$scope: scope, $attrs: attrs, shops: shops, orderCycles: orderCycles} + it "initialises name_and_status", -> + expect(scope.orderCycles[0].name_and_status).toEqual "Ten (open)" + expect(scope.orderCycles[1].name_and_status).toEqual "Twenty (closed)" describe "finding valid order cycles for a distributor", -> order_cycle = {id: 10, distributors: [{id: 1, name: 'One'}]} From 5579fa5e0b030947cad1d99981280c94ed1cae73 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Fri, 11 Dec 2015 12:08:45 +1100 Subject: [PATCH 19/27] Extract last used address finding into service object --- app/controllers/checkout_controller.rb | 8 ++- .../spree/checkout_controller_decorator.rb | 17 ++---- lib/open_food_network/last_used_address.rb | 28 +++++++++ .../last_used_address_spec.rb | 58 +++++++++++++++++++ 4 files changed, 99 insertions(+), 12 deletions(-) create mode 100644 lib/open_food_network/last_used_address.rb create mode 100644 spec/lib/open_food_network/last_used_address_spec.rb diff --git a/app/controllers/checkout_controller.rb b/app/controllers/checkout_controller.rb index b23a57ebde..1cffc05734 100644 --- a/app/controllers/checkout_controller.rb +++ b/app/controllers/checkout_controller.rb @@ -1,3 +1,5 @@ +require 'open_food_network/last_used_address' + class CheckoutController < Spree::CheckoutController layout 'darkswarm' @@ -129,7 +131,11 @@ class CheckoutController < Spree::CheckoutController def before_address associate_user - last_used_bill_address, last_used_ship_address = find_last_used_addresses(@order.email) + + lua = OpenFoodNetwork::LastUsedAddress.new(@order.email) + last_used_bill_address = lua.last_used_bill_address.andand.clone + last_used_ship_address = lua.last_used_ship_address.andand.clone + preferred_bill_address, preferred_ship_address = spree_current_user.bill_address, spree_current_user.ship_address if spree_current_user.respond_to?(:bill_address) && spree_current_user.respond_to?(:ship_address) @order.bill_address ||= preferred_bill_address || last_used_bill_address || Spree::Address.default @order.ship_address ||= preferred_ship_address || last_used_ship_address || Spree::Address.default diff --git a/app/controllers/spree/checkout_controller_decorator.rb b/app/controllers/spree/checkout_controller_decorator.rb index 061599870f..641e15f640 100644 --- a/app/controllers/spree/checkout_controller_decorator.rb +++ b/app/controllers/spree/checkout_controller_decorator.rb @@ -1,3 +1,5 @@ +require 'open_food_network/last_used_address' + Spree::CheckoutController.class_eval do include CheckoutHelper @@ -19,7 +21,10 @@ Spree::CheckoutController.class_eval do def before_address associate_user - last_used_bill_address, last_used_ship_address = find_last_used_addresses(@order.email) + lua = OpenFoodNetwork::LastUsedAddress.new(@order.email) + last_used_bill_address = lua.last_used_bill_address.andand.clone + last_used_ship_address = lua.last_used_ship_address.andand.clone + preferred_bill_address, preferred_ship_address = spree_current_user.bill_address, spree_current_user.ship_address if spree_current_user.respond_to?(:bill_address) && spree_current_user.respond_to?(:ship_address) @order.bill_address ||= preferred_bill_address || last_used_bill_address || Spree::Address.default @@ -29,14 +34,4 @@ Spree::CheckoutController.class_eval do def after_complete reset_order end - - def find_last_used_addresses(email) - past = Spree::Order.order("id desc").where(:email => email).where("state != 'cart'").limit(8) - if order = past.detect(&:bill_address) - bill_address = order.bill_address.clone if order.bill_address - ship_address = order.ship_address.clone if order.ship_address and order.shipping_method.andand.require_ship_address - end - - [bill_address, ship_address] - end end diff --git a/lib/open_food_network/last_used_address.rb b/lib/open_food_network/last_used_address.rb new file mode 100644 index 0000000000..66c06fceb6 --- /dev/null +++ b/lib/open_food_network/last_used_address.rb @@ -0,0 +1,28 @@ +module OpenFoodNetwork + class LastUsedAddress + def initialize(email) + @email = email + end + + def last_used_bill_address + recent_orders.detect(&:bill_address).andand.bill_address + end + + def last_used_ship_address + recent_orders.detect { |o| + o.ship_address && o.shipping_method.andand.require_ship_address + }.andand.ship_address + end + + + private + + def recent_orders + Spree::Order. + order("id DESC"). + where(email: @email). + where("state != 'cart'"). + limit(8) + end + end +end diff --git a/spec/lib/open_food_network/last_used_address_spec.rb b/spec/lib/open_food_network/last_used_address_spec.rb new file mode 100644 index 0000000000..edb3232e8a --- /dev/null +++ b/spec/lib/open_food_network/last_used_address_spec.rb @@ -0,0 +1,58 @@ +require 'open_food_network/last_used_address' + +module OpenFoodNetwork + describe LastUsedAddress do + let(:email) { 'test@example.com' } + let(:address) { 'address' } + + describe "last used bill address" do + let(:lua) { LastUsedAddress.new(email) } + let(:order_with_bill_address) { double(:order, bill_address: address) } + let(:order_without_bill_address) { double(:order, bill_address: nil) } + + it "returns the bill address when present" do + lua.stub(:recent_orders) { [order_with_bill_address] } + lua.last_used_bill_address.should == address + end + + it "returns nil when there's no order with a bill address" do + lua.stub(:recent_orders) { [order_without_bill_address] } + lua.last_used_bill_address.should be_nil + end + + it "returns nil when there are no recent orders" do + lua.stub(:recent_orders) { [] } + lua.last_used_bill_address.should be_nil + end + end + + describe "last used ship address" do + let(:lua) { LastUsedAddress.new(email) } + let(:pickup) { double(:shipping_method, require_ship_address: false) } + let(:delivery) { double(:shipping_method, require_ship_address: true) } + let(:order_with_ship_address) { double(:order, ship_address: address, shipping_method: delivery) } + let(:order_with_unrequired_ship_address) { double(:order, ship_address: address, shipping_method: pickup) } + let(:order_without_ship_address) { double(:order, ship_address: nil) } + + it "returns the ship address when present" do + lua.stub(:recent_orders) { [order_with_ship_address] } + lua.last_used_ship_address.should == address + end + + it "returns nil when the order doesn't require a ship address" do + lua.stub(:recent_orders) { [order_with_unrequired_ship_address] } + lua.last_used_ship_address.should be_nil + end + + it "returns nil when there's no order with a ship address" do + lua.stub(:recent_orders) { [order_without_ship_address] } + lua.last_used_ship_address.should be_nil + end + + it "returns nil when there are no recent orders" do + lua.stub(:recent_orders) { [] } + lua.last_used_ship_address.should be_nil + end + end + end +end From ae3061df80aa6f30358136d343938ef264db58c2 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Fri, 11 Dec 2015 12:38:20 +1100 Subject: [PATCH 20/27] All orders specs use JS --- spec/features/admin/orders_spec.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/spec/features/admin/orders_spec.rb b/spec/features/admin/orders_spec.rb index cf1bf1c7ba..12e218bc81 100644 --- a/spec/features/admin/orders_spec.rb +++ b/spec/features/admin/orders_spec.rb @@ -3,7 +3,7 @@ require "spec_helper" feature %q{ As an administrator I want to manage orders -} do +}, js: true do include AuthenticationWorkflow include WebHelper @@ -21,7 +21,7 @@ feature %q{ create :check_payment, order: @order, amount: @order.total end - scenario "creating an order with distributor and order cycle", js: true, retry: 3 do + scenario "creating an order with distributor and order cycle", retry: 3 do distributor_disabled = create(:distributor_enterprise) create(:simple_order_cycle, name: 'Two') @@ -53,7 +53,7 @@ feature %q{ o.order_cycle.should == @order_cycle end - scenario "can add a product to an existing order", js: true, retry: 3 do + scenario "can add a product to an existing order", retry: 3 do login_to_admin_section visit '/admin/orders' @@ -67,7 +67,7 @@ feature %q{ @order.line_items(true).map(&:product).should include @product end - scenario "displays error when incorrect distribution for products is chosen", js: true do + scenario "displays error when incorrect distribution for products is chosen" do d = create(:distributor_enterprise) oc = create(:simple_order_cycle, distributors: [d]) @@ -89,7 +89,7 @@ feature %q{ end - scenario "can't add products to an order outside the order's hub and order cycle", js: true do + scenario "can't add products to an order outside the order's hub and order cycle" do product = create(:simple_product) login_to_admin_section @@ -155,7 +155,7 @@ feature %q{ login_to_admin_as @enterprise_user end - scenario "creating an order with distributor and order cycle", js: true do + scenario "creating an order with distributor and order cycle" do visit '/admin/orders' click_link 'New Order' From 3f8d470d23d84b5e76ec1b03a3b346a80637f3af Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Fri, 11 Dec 2015 12:39:08 +1100 Subject: [PATCH 21/27] When admin associates user with an order, look up last used address --- .../admin/search_controller_decorator.rb | 9 +++++- app/serializers/api/admin/user_serializer.rb | 15 ++++++++++ spec/features/admin/orders_spec.rb | 30 +++++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/app/controllers/spree/admin/search_controller_decorator.rb b/app/controllers/spree/admin/search_controller_decorator.rb index f268f95820..6c5942934e 100644 --- a/app/controllers/spree/admin/search_controller_decorator.rb +++ b/app/controllers/spree/admin/search_controller_decorator.rb @@ -12,7 +12,14 @@ Spree::Admin::SearchController.class_eval do :bill_address_lastname_start => params[:q] }).result.limit(10) end - render :users + render :users end + + + def users_with_ams + users_without_ams + render json: @users, each_serializer: Api::Admin::UserSerializer + end + alias_method_chain :users, :ams end diff --git a/app/serializers/api/admin/user_serializer.rb b/app/serializers/api/admin/user_serializer.rb index 501cd75674..c080a8fd6a 100644 --- a/app/serializers/api/admin/user_serializer.rb +++ b/app/serializers/api/admin/user_serializer.rb @@ -1,3 +1,18 @@ +require 'open_food_network/last_used_address' + class Api::Admin::UserSerializer < ActiveModel::Serializer attributes :id, :email + + has_one :ship_address, serializer: Api::AddressSerializer + has_one :bill_address, serializer: Api::AddressSerializer + + def ship_address + object.ship_address || + OpenFoodNetwork::LastUsedAddress.new(object.email).last_used_ship_address + end + + def bill_address + object.bill_address || + OpenFoodNetwork::LastUsedAddress.new(object.email).last_used_bill_address + end end diff --git a/spec/features/admin/orders_spec.rb b/spec/features/admin/orders_spec.rb index 12e218bc81..29afad24d2 100644 --- a/spec/features/admin/orders_spec.rb +++ b/spec/features/admin/orders_spec.rb @@ -113,6 +113,36 @@ feature %q{ page.should have_selector 'p', text: "Order cycle: None" end + scenario "filling customer details" do + # Given a customer with an order, which includes their shipping and billing address + @order.ship_address = create(:address, lastname: 'Ship') + @order.bill_address = create(:address, lastname: 'Bill') + @order.shipping_method = create(:shipping_method, require_ship_address: true) + @order.save! + + # When I create a new order + login_to_admin_section + visit '/admin/orders' + click_link 'New Order' + select @distributor.name, from: 'order_distributor_id' + select2_select @order_cycle.name, from: 'order_order_cycle_id' + targetted_select2_search @product.name, from: '#add_variant_id', dropdown_css: '.select2-drop' + click_link 'Add' + page.has_selector? "table.index tbody[data-hook='admin_order_form_line_items'] tr" # Wait for JS + click_button 'Update' + within('h1.page-title') { page.should have_content "Customer Details" } + + # And I select that customer's email address and save the order + targetted_select2_search @order.user.email, from: '#customer_search', dropdown_css: '.select2-drop' + click_button 'Continue' + within('h1.page-title') { page.should have_content "Shipments" } + + # Then their addresses should be associated with the order + order = Spree::Order.last + order.ship_address.lastname.should == 'Ship' + order.bill_address.lastname.should == 'Bill' + end + scenario "capture multiple payments from the orders index page" do # d.cook: could also test for an order that has had payment voided, then a new check payment created but not yet captured. But it's not critical and I know it works anyway. From a3874d42af4cebf6c3c2fe87bb6a33e262b747da Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Fri, 11 Dec 2015 13:25:40 +1100 Subject: [PATCH 22/27] Spec moved to OpenFoodNetwork::LastUsedAddress --- spec/controllers/checkout_controller_spec.rb | 6 ------ 1 file changed, 6 deletions(-) diff --git a/spec/controllers/checkout_controller_spec.rb b/spec/controllers/checkout_controller_spec.rb index dd9e44c5be..ddacd0fdeb 100644 --- a/spec/controllers/checkout_controller_spec.rb +++ b/spec/controllers/checkout_controller_spec.rb @@ -52,12 +52,6 @@ describe CheckoutController do response.should be_success end - it "doesn't copy the previous shipping address from a pickup order" do - old_order = create(:order, bill_address: create(:address), ship_address: create(:address)) - Spree::Order.stub_chain(:order, :where, :where, :limit, :detect).and_return(old_order) - controller.send(:find_last_used_addresses, "email").last.should == nil - end - describe "building the order" do before do controller.stub(:current_distributor).and_return(distributor) From 6787709693851df5fb2809f7cf69da36f9d761dd Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Thu, 10 Dec 2015 11:57:37 +1100 Subject: [PATCH 23/27] LettuceShare report: total in unit value column and total blank --- lib/open_food_network/lettuce_share_report.rb | 2 +- spec/features/admin/reports_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/open_food_network/lettuce_share_report.rb b/lib/open_food_network/lettuce_share_report.rb index 1dc283eba8..a532c00983 100644 --- a/lib/open_food_network/lettuce_share_report.rb +++ b/lib/open_food_network/lettuce_share_report.rb @@ -25,8 +25,8 @@ module OpenFoodNetwork '', OptionValueNamer.new(variant).value, OptionValueNamer.new(variant).unit, - variant.price - gst(variant), variant.price, + '', gst(variant), grower_and_method(variant), variant.product.primary_taxon.name diff --git a/spec/features/admin/reports_spec.rb b/spec/features/admin/reports_spec.rb index 9a00fd6fde..b3f42df669 100644 --- a/spec/features/admin/reports_spec.rb +++ b/spec/features/admin/reports_spec.rb @@ -324,7 +324,7 @@ feature %q{ click_link 'LettuceShare' page.should have_table_row ['PRODUCT', 'Description', 'Qty', 'Pack Size', 'Unit', 'Unit Price', 'Total', 'GST incl.', 'Grower and growing method', 'Taxon'].map(&:upcase) - page.should have_table_row ['Product 2', '100g', '', '100', 'g', '99.0', '99.0', '0', 'Supplier Name (Organic - NASAA 12345)', 'Taxon Name'] + page.should have_table_row ['Product 2', '100g', '', '100', 'g', '99.0', '', '0', 'Supplier Name (Organic - NASAA 12345)', 'Taxon Name'] end end From 15ea64b4093639bcba89184cdcb955b82ef5cc3f Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Thu, 10 Dec 2015 13:44:00 +1100 Subject: [PATCH 24/27] Add SKU to LettuceShare report --- lib/open_food_network/lettuce_share_report.rb | 2 ++ spec/features/admin/reports_spec.rb | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/open_food_network/lettuce_share_report.rb b/lib/open_food_network/lettuce_share_report.rb index a532c00983..f629ba93ae 100644 --- a/lib/open_food_network/lettuce_share_report.rb +++ b/lib/open_food_network/lettuce_share_report.rb @@ -6,6 +6,7 @@ module OpenFoodNetwork [ "PRODUCT", "Description", + "SKU", "Qty", "Pack Size", "Unit", @@ -22,6 +23,7 @@ module OpenFoodNetwork [ variant.product.name, variant.full_name, + variant.sku, '', OptionValueNamer.new(variant).value, OptionValueNamer.new(variant).unit, diff --git a/spec/features/admin/reports_spec.rb b/spec/features/admin/reports_spec.rb index b3f42df669..dc4119422d 100644 --- a/spec/features/admin/reports_spec.rb +++ b/spec/features/admin/reports_spec.rb @@ -323,8 +323,8 @@ feature %q{ click_link 'Reports' click_link 'LettuceShare' - page.should have_table_row ['PRODUCT', 'Description', 'Qty', 'Pack Size', 'Unit', 'Unit Price', 'Total', 'GST incl.', 'Grower and growing method', 'Taxon'].map(&:upcase) - page.should have_table_row ['Product 2', '100g', '', '100', 'g', '99.0', '', '0', 'Supplier Name (Organic - NASAA 12345)', 'Taxon Name'] + page.should have_table_row ['PRODUCT', 'Description', 'SKU', 'Qty', 'Pack Size', 'Unit', 'Unit Price', 'Total', 'GST incl.', 'Grower and growing method', 'Taxon'].map(&:upcase) + page.should have_table_row ['Product 2', '100g', 'ABC', '', '100', 'g', '99.0', '', '0', 'Supplier Name (Organic - NASAA 12345)', 'Taxon Name'] end end From 1d46c2febdcd98b76e3b4ca96e1c05db9fd9cf3a Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Thu, 10 Dec 2015 17:39:35 +1100 Subject: [PATCH 25/27] LettuceShare report: display only if count_on_hand > 0 Use the inventory of a distributor if selected. --- app/models/spree/variant_decorator.rb | 11 ++++------- lib/open_food_network/lettuce_share_report.rb | 8 +++++++- .../products_and_inventory_report_base.rb | 8 ++------ .../products_and_inventory_report_spec.rb | 11 ++++++----- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/app/models/spree/variant_decorator.rb b/app/models/spree/variant_decorator.rb index b9c9420287..9084214ea7 100644 --- a/app/models/spree/variant_decorator.rb +++ b/app/models/spree/variant_decorator.rb @@ -26,18 +26,15 @@ Spree::Variant.class_eval do after_save :update_units scope :with_order_cycles_inner, joins(exchanges: :order_cycle) - scope :with_order_cycles_outer, joins('LEFT OUTER JOIN exchange_variants AS o_exchange_variants ON (o_exchange_variants.variant_id = spree_variants.id)'). - joins('LEFT OUTER JOIN exchanges AS o_exchanges ON (o_exchanges.id = o_exchange_variants.exchange_id)'). - joins('LEFT OUTER JOIN order_cycles AS o_order_cycles ON (o_order_cycles.id = o_exchanges.order_cycle_id)') scope :not_deleted, where(deleted_at: nil) scope :in_stock, where('spree_variants.count_on_hand > 0 OR spree_variants.on_demand=?', true) scope :in_distributor, lambda { |distributor| - with_order_cycles_outer. - where('o_exchanges.incoming = ? AND o_exchanges.receiver_id = ?', false, distributor). - select('DISTINCT spree_variants.*') + where(id: ExchangeVariant.select(:variant_id). + joins(:exchange). + where('exchanges.incoming = ? AND exchanges.receiver_id = ?', false, distributor) + ) } - scope :in_order_cycle, lambda { |order_cycle| with_order_cycles_inner. merge(Exchange.outgoing). diff --git a/lib/open_food_network/lettuce_share_report.rb b/lib/open_food_network/lettuce_share_report.rb index f629ba93ae..206db6be3e 100644 --- a/lib/open_food_network/lettuce_share_report.rb +++ b/lib/open_food_network/lettuce_share_report.rb @@ -19,7 +19,13 @@ module OpenFoodNetwork end def table - variants.map do |variant| + if params[:distributor_id].to_i > 0 + distributor = Enterprise.find(params[:distributor_id]) + scoper = OpenFoodNetwork::ScopeVariantToHub.new(distributor) + variants.each { |v| scoper.scope(v) } + end + variants.select { |v| v.count_on_hand > 0 } + .map do |variant| [ variant.product.name, variant.full_name, diff --git a/lib/open_food_network/products_and_inventory_report_base.rb b/lib/open_food_network/products_and_inventory_report_base.rb index df5b656848..63205d59a6 100644 --- a/lib/open_food_network/products_and_inventory_report_base.rb +++ b/lib/open_food_network/products_and_inventory_report_base.rb @@ -28,8 +28,6 @@ module OpenFoodNetwork end def filter(variants) - # NOTE: Ordering matters. - # filter_to_order_cycle and filter_to_distributor return arrays not relations filter_to_distributor filter_to_order_cycle filter_on_hand filter_to_supplier filter_not_deleted variants end @@ -56,9 +54,7 @@ module OpenFoodNetwork def filter_to_distributor(variants) if params[:distributor_id].to_i > 0 distributor = Enterprise.find params[:distributor_id] - variants.select do |v| - Enterprise.distributing_product(v.product_id).include? distributor - end + variants.in_distributor(distributor) else variants end @@ -67,7 +63,7 @@ module OpenFoodNetwork def filter_to_order_cycle(variants) if params[:order_cycle_id].to_i > 0 order_cycle = OrderCycle.find params[:order_cycle_id] - variants.select { |v| order_cycle.variants.include? v } + variants.where(id: order_cycle.variants) else variants end diff --git a/spec/lib/open_food_network/products_and_inventory_report_spec.rb b/spec/lib/open_food_network/products_and_inventory_report_spec.rb index 13796c10f6..d9c8754a43 100644 --- a/spec/lib/open_food_network/products_and_inventory_report_spec.rb +++ b/spec/lib/open_food_network/products_and_inventory_report_spec.rb @@ -124,15 +124,16 @@ module OpenFoodNetwork it "filters to a specific distributor" do distributor = create(:distributor_enterprise) product1 = create(:simple_product, supplier: supplier) - product2 = create(:simple_product, supplier: supplier, distributors: [distributor]) + product2 = create(:simple_product, supplier: supplier) + order_cycle = create(:simple_order_cycle, suppliers: [supplier], distributors: [distributor], variants: [product2.variants.first]) subject.stub(:params).and_return(distributor_id: distributor.id) subject.filter(variants).should == [product2.variants.first] end it "filters to a specific order cycle" do distributor = create(:distributor_enterprise) - product1 = create(:simple_product, supplier: supplier, distributors: [distributor]) - product2 = create(:simple_product, supplier: supplier, distributors: [distributor]) + product1 = create(:simple_product, supplier: supplier) + product2 = create(:simple_product, supplier: supplier) order_cycle = create(:simple_order_cycle, suppliers: [supplier], distributors: [distributor], variants: [product1.variants.first]) subject.stub(:params).and_return(order_cycle_id: order_cycle.id) @@ -141,8 +142,8 @@ module OpenFoodNetwork it "should do all the filters at once" do distributor = create(:distributor_enterprise) - product1 = create(:simple_product, supplier: supplier, distributors: [distributor]) - product2 = create(:simple_product, supplier: supplier, distributors: [distributor]) + product1 = create(:simple_product, supplier: supplier) + product2 = create(:simple_product, supplier: supplier) order_cycle = create(:simple_order_cycle, suppliers: [supplier], distributors: [distributor], variants: [product1.variants.first]) subject.stub(:params).and_return( From bb58473b90c6429866bd39093028192a9ae12f12 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Fri, 11 Dec 2015 13:03:15 +1100 Subject: [PATCH 26/27] Consider variant overrides in LettuceShare report --- lib/open_food_network/lettuce_share_report.rb | 1 + .../lettuce_share_report_spec.rb | 38 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/lib/open_food_network/lettuce_share_report.rb b/lib/open_food_network/lettuce_share_report.rb index 206db6be3e..8f862efee8 100644 --- a/lib/open_food_network/lettuce_share_report.rb +++ b/lib/open_food_network/lettuce_share_report.rb @@ -19,6 +19,7 @@ module OpenFoodNetwork end def table + variants = variants() if params[:distributor_id].to_i > 0 distributor = Enterprise.find(params[:distributor_id]) scoper = OpenFoodNetwork::ScopeVariantToHub.new(distributor) diff --git a/spec/lib/open_food_network/lettuce_share_report_spec.rb b/spec/lib/open_food_network/lettuce_share_report_spec.rb index a3a82b2f00..5b54a8aec8 100644 --- a/spec/lib/open_food_network/lettuce_share_report_spec.rb +++ b/spec/lib/open_food_network/lettuce_share_report_spec.rb @@ -27,5 +27,43 @@ module OpenFoodNetwork report.send(:gst, v).should == 0 end end + + describe "table" do + it "handles no items" do + report.send(:table).should eq [] + end + + describe "lists" do + let(:v2) { create(:variant) } + let(:v3) { create(:variant) } + let(:hub_address) { create(:address, :address1 => "distributor address", :city => 'The Shire', :zipcode => "1234") } + let(:hub) { create(:distributor_enterprise, :address => hub_address) } + let(:v2o) { create(:variant_override, hub: hub, variant: v2) } + let(:v3o) { create(:variant_override, hub: hub, variant: v3, count_on_hand: 0) } + + it "all items" do + report.stub(:variants) { [v, v2, v3] } + report.send(:table).count.should eq 3 + end + + it "only available items" do + report.stub(:variants) { [v, v2, v3] } + v.count_on_hand = 0 + report.send(:table).count.should eq 2 + end + + it "only available items considering overrides" do + # create the overrides + v2o + v3o + report.stub(:variants) { [v, v2, v3] } + report.stub(:params) { {distributor_id: hub.id} } + rows = report.send(:table) + rows.count.should eq 2 + rows[1][0].should eq v2.product.name + end + + end + end end end From 758b1f8e647cabf8e10e23b3e07f147c7c76bc5c Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Fri, 11 Dec 2015 14:37:47 +1100 Subject: [PATCH 27/27] using in_stock? to filter variants in lettuceshare report --- lib/open_food_network/lettuce_share_report.rb | 2 +- spec/lib/open_food_network/lettuce_share_report_spec.rb | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/open_food_network/lettuce_share_report.rb b/lib/open_food_network/lettuce_share_report.rb index 8f862efee8..97b1f058fc 100644 --- a/lib/open_food_network/lettuce_share_report.rb +++ b/lib/open_food_network/lettuce_share_report.rb @@ -25,7 +25,7 @@ module OpenFoodNetwork scoper = OpenFoodNetwork::ScopeVariantToHub.new(distributor) variants.each { |v| scoper.scope(v) } end - variants.select { |v| v.count_on_hand > 0 } + variants.select { |v| v.in_stock? } .map do |variant| [ variant.product.name, diff --git a/spec/lib/open_food_network/lettuce_share_report_spec.rb b/spec/lib/open_food_network/lettuce_share_report_spec.rb index 5b54a8aec8..258af03c90 100644 --- a/spec/lib/open_food_network/lettuce_share_report_spec.rb +++ b/spec/lib/open_food_network/lettuce_share_report_spec.rb @@ -36,6 +36,7 @@ module OpenFoodNetwork describe "lists" do let(:v2) { create(:variant) } let(:v3) { create(:variant) } + let(:v4) { create(:variant, count_on_hand: 0, on_demand: true) } let(:hub_address) { create(:address, :address1 => "distributor address", :city => 'The Shire', :zipcode => "1234") } let(:hub) { create(:distributor_enterprise, :address => hub_address) } let(:v2o) { create(:variant_override, hub: hub, variant: v2) } @@ -47,9 +48,9 @@ module OpenFoodNetwork end it "only available items" do - report.stub(:variants) { [v, v2, v3] } + report.stub(:variants) { [v, v2, v3, v4] } v.count_on_hand = 0 - report.send(:table).count.should eq 2 + report.send(:table).count.should eq 3 end it "only available items considering overrides" do