From 95a7fc8ef536bd1daf4ea7ecbb136bab277bf5a1 Mon Sep 17 00:00:00 2001 From: Rob Harrington Date: Thu, 10 Nov 2016 10:53:00 +1100 Subject: [PATCH] Initialisation and removal of standing order orders respects begins_at and ends_at contraints --- app/forms/standing_order_form.rb | 23 +++++++- app/models/standing_order_order.rb | 2 +- spec/forms/standing_order_form_spec.rb | 77 ++++++++++++++++++++------ 3 files changed, 81 insertions(+), 21 deletions(-) diff --git a/app/forms/standing_order_form.rb b/app/forms/standing_order_form.rb index 872a986b90..0736e2952a 100644 --- a/app/forms/standing_order_form.rb +++ b/app/forms/standing_order_form.rb @@ -6,7 +6,7 @@ class StandingOrderForm attr_accessor :standing_order, :params delegate :orders, :order_cycles, :bill_address, :ship_address, :standing_line_items, to: :standing_order - delegate :shop, :shop_id, :customer, :customer_id, to: :standing_order + delegate :shop, :shop_id, :customer, :customer_id, :begins_at, :ends_at, :standing_order_orders, to: :standing_order delegate :shipping_method, :shipping_method_id, :payment_method, :payment_method_id, to: :standing_order delegate :shipping_method_id_changed?, :shipping_method_id_was, :payment_method_id_changed?, :payment_method_id_was, to: :standing_order @@ -20,6 +20,7 @@ class StandingOrderForm @standing_order.assign_attributes(params) initialise_orders! + remove_obsolete_orders! orders.update_all(customer_id: customer_id, email: customer.andand.email, distributor_id: shop_id) @@ -95,7 +96,25 @@ class StandingOrderForm end def uninitialised_order_cycle_ids - order_cycles.pluck(:id) - orders.map(&:order_cycle_id) + not_closed_in_range_order_cycles.pluck(:id) - orders.map(&:order_cycle_id) + end + + def remove_obsolete_orders! + standing_order_orders.where(order_id: obsolete_orders).destroy_all + end + + def obsolete_orders + in_range_order_cycle_ids = in_range_order_cycles.pluck(:id) + return orders unless in_range_order_cycle_ids.any? + orders.where('order_cycle_id NOT IN (?)', in_range_order_cycle_ids) + end + + def not_closed_in_range_order_cycles + in_range_order_cycles.merge(OrderCycle.not_closed) + end + + def in_range_order_cycles + order_cycles.where('orders_close_at >= ? AND orders_close_at <= ?', begins_at, ends_at || 100.years.from_now) end def changed_standing_line_items diff --git a/app/models/standing_order_order.rb b/app/models/standing_order_order.rb index d610fb100f..0ecdfd32e3 100644 --- a/app/models/standing_order_order.rb +++ b/app/models/standing_order_order.rb @@ -1,4 +1,4 @@ class StandingOrderOrder < ActiveRecord::Base - belongs_to :order, class_name: 'Spree::Order' + belongs_to :order, class_name: 'Spree::Order', dependent: :destroy belongs_to :standing_order end diff --git a/spec/forms/standing_order_form_spec.rb b/spec/forms/standing_order_form_spec.rb index d910ac163a..4359deac0f 100644 --- a/spec/forms/standing_order_form_spec.rb +++ b/spec/forms/standing_order_form_spec.rb @@ -10,13 +10,15 @@ module OpenFoodNetwork let!(:variant2) { create(:variant, product: product2, unit_value: '1000', price: 6.00, option_values: []) } let!(:variant3) { create(:variant, product: product2, unit_value: '1000', price: 2.50, option_values: []) } let!(:enterprise_fee) { create(:enterprise_fee, amount: 1.75) } - let!(:order_cycle1) { create(:simple_order_cycle, coordinator: shop, orders_open_at: 3.weeks.ago, orders_close_at: 2.weeks.ago) } - let!(:order_cycle2) { create(:simple_order_cycle, coordinator: shop, orders_open_at: 2.days.from_now, orders_close_at: 9.days.from_now) } - let!(:order_cycle3) { create(:simple_order_cycle, coordinator: shop, orders_open_at: 9.days.from_now, orders_close_at: 16.days.from_now) } + let!(:order_cycle1) { create(:simple_order_cycle, coordinator: shop, orders_open_at: 9.days.ago, orders_close_at: 2.day.ago) } + let!(:order_cycle2) { create(:simple_order_cycle, coordinator: shop, orders_open_at: 2.day.ago, orders_close_at: 5.days.from_now) } + let!(:order_cycle3) { create(:simple_order_cycle, coordinator: shop, orders_open_at: 5.days.from_now, orders_close_at: 12.days.from_now) } + let!(:order_cycle4) { create(:simple_order_cycle, coordinator: shop, orders_open_at: 12.days.from_now, orders_close_at: 19.days.from_now) } let!(:outgoing_exchange1) { order_cycle1.exchanges.create(sender: shop, receiver: shop, variants: [variant1, variant2, variant3], enterprise_fees: [enterprise_fee]) } - let!(:outgoing_exchange2) { order_cycle2.exchanges.create(sender: shop, receiver: shop, variants: [variant1], enterprise_fees: [enterprise_fee]) } - let!(:outgoing_exchange3) { order_cycle3.exchanges.create(sender: shop, receiver: shop, variants: [variant1, variant2, variant3], enterprise_fees: []) } - let!(:schedule) { create(:schedule, order_cycles: [order_cycle1, order_cycle2, order_cycle3]) } + let!(:outgoing_exchange2) { order_cycle2.exchanges.create(sender: shop, receiver: shop, variants: [variant1, variant2, variant3], enterprise_fees: [enterprise_fee]) } + let!(:outgoing_exchange3) { order_cycle3.exchanges.create(sender: shop, receiver: shop, variants: [variant1, variant3], enterprise_fees: []) } + let!(:outgoing_exchange4) { order_cycle4.exchanges.create(sender: shop, receiver: shop, variants: [variant1, variant2, variant3], enterprise_fees: [enterprise_fee]) } + let!(:schedule) { create(:schedule, order_cycles: [order_cycle1, order_cycle2, order_cycle3, order_cycle4]) } let!(:payment_method) { create(:payment_method, distributors: [shop]) } let!(:shipping_method) { create(:shipping_method, distributors: [shop]) } let!(:address) { create(:address) } @@ -30,7 +32,8 @@ module OpenFoodNetwork ship_address_attributes: address.clone.attributes, payment_method_id: payment_method.id, shipping_method_id: shipping_method.id, - begins_at: 2.weeks.ago, + begins_at: 4.days.ago, + ends_at: 14.days.from_now, standing_line_items_attributes: [ {variant_id: variant1.id, quantity: 1}, {variant_id: variant2.id, quantity: 2}, @@ -43,19 +46,40 @@ module OpenFoodNetwork it "creates orders for each order cycle in the schedule" do form.save - expect(standing_order.orders.count).to be 3 + expect(standing_order.orders.count).to be 2 - # Add line items for variants that aren't yet available from the order cycle + # This order cycle has already closed, so no order is initialized order1 = standing_order.orders.find_by_order_cycle_id(order_cycle1.id) - expect(order1).to be_a Spree::Order - expect(order1.line_items.count).to be 3 - expect(order1.shipments.count).to be 1 - expect(order1.shipments.first.shipping_method).to eq shipping_method - expect(order1.payments.count).to be 1 - expect(order1.payments.first.payment_method).to eq payment_method - expect(order1.payments.first.state).to eq 'checkout' - expect(order1.total).to eq 42 - expect(order1.completed?).to be false + expect(order1).to be nil + + # Currently open order cycle, closing after begins_at and before ends_at + order2 = standing_order.orders.find_by_order_cycle_id(order_cycle2.id) + expect(order2).to be_a Spree::Order + expect(order2.line_items.count).to be 3 + expect(order2.shipments.count).to be 1 + expect(order2.shipments.first.shipping_method).to eq shipping_method + expect(order2.payments.count).to be 1 + expect(order2.payments.first.payment_method).to eq payment_method + expect(order2.payments.first.state).to eq 'checkout' + expect(order2.total).to eq 42 + expect(order2.completed?).to be false + + # Future order cycle, closing after begins_at and before ends_at + # Add line items for variants that aren't yet available from the order cycle + order3 = standing_order.orders.find_by_order_cycle_id(order_cycle3.id) + expect(order3).to be_a Spree::Order + expect(order3.line_items.count).to be 3 + expect(order3.shipments.count).to be 1 + expect(order3.shipments.first.shipping_method).to eq shipping_method + expect(order3.payments.count).to be 1 + expect(order3.payments.first.payment_method).to eq payment_method + expect(order3.payments.first.state).to eq 'checkout' + expect(order3.total).to eq 31.50 + expect(order3.completed?).to be false + + # Future order cycle closing after ends_at + order4 = standing_order.orders.find_by_order_cycle_id(order_cycle4.id) + expect(order4).to be nil end end @@ -138,6 +162,23 @@ module OpenFoodNetwork end end + describe "changing begins_at" do + let(:standing_order) { create(:standing_order_with_items, begins_at: Time.zone.now) } + let(:params) { { begins_at: 1.year.from_now, ends_at: 2.years.from_now } } + let(:form) { StandingOrderForm.new(standing_order, params) } + + before { form.send(:initialise_orders!) } + + it "removes orders outside the newly specified date range" do + expect(standing_order.reload.orders.count).to be 1 + form.save + expect(standing_order.reload.orders.count).to be 0 + form.params = { begins_at: 1.month.ago } + form.save + expect(standing_order.reload.orders.count).to be 1 + end + end + describe "changing the quantity of a line item" do let(:standing_order) { create(:standing_order_with_items) } let(:sli) { standing_order.standing_line_items.first }