diff --git a/app/jobs/standing_order_placement_job.rb b/app/jobs/standing_order_placement_job.rb index e7d609fb1c..829b57b249 100644 --- a/app/jobs/standing_order_placement_job.rb +++ b/app/jobs/standing_order_placement_job.rb @@ -18,7 +18,7 @@ class StandingOrderPlacementJob end def process(order) - while order.state != "complete" + until order.completed? if order.errors.any? Bugsnag.notify(RuntimeError.new("StandingOrderPlacementError"), { job: "StandingOrderPlacement", @@ -29,7 +29,7 @@ class StandingOrderPlacementJob }) break else - order.next + order.next! end end end diff --git a/app/models/order_cycle.rb b/app/models/order_cycle.rb index 9ddde06edd..62ca0e5082 100644 --- a/app/models/order_cycle.rb +++ b/app/models/order_cycle.rb @@ -118,6 +118,10 @@ class OrderCycle < ActiveRecord::Base ] end + def active? + orders_open_at < Time.zone.now && orders_close_at > Time.zone.now + end + def clone! oc = self.dup oc.name = "COPY OF #{oc.name}" diff --git a/app/models/spree/order_decorator.rb b/app/models/spree/order_decorator.rb index 6a43cc9a3a..227b6b0189 100644 --- a/app/models/spree/order_decorator.rb +++ b/app/models/spree/order_decorator.rb @@ -318,6 +318,13 @@ Spree::Order.class_eval do errors.add(:base, e.message) and return result end + # Override or Spree method. Used to prevent payments on standing orders from being processed in the normal way. + # ie. they are 'hidden' from processing logic until after the order cycle has closed. + def pending_payments + return [] if standing_order.present? && order_cycle.orders_close_at.andand > Time.now + payments.select {|p| p.state == "checkout"} # Original definition + end + private def shipping_address_from_distributor diff --git a/spec/jobs/standing_order_placement_job_spec.rb b/spec/jobs/standing_order_placement_job_spec.rb index d4a3460b98..27805393d7 100644 --- a/spec/jobs/standing_order_placement_job_spec.rb +++ b/spec/jobs/standing_order_placement_job_spec.rb @@ -30,15 +30,18 @@ describe StandingOrderPlacementJob do end describe "performing the job" do + let(:order) { standing_order1.orders.first } + before do form = StandingOrderForm.new(standing_order1) form.send(:initialise_orders!) + expect_any_instance_of(Spree::Payment).to_not receive(:process!) end - it "processes orders to completion" do - order = standing_order1.orders.first + it "moves orders to completion, but does not process the payment" do expect{job.perform}.to change{order.reload.completed_at}.from(nil) expect(order.completed_at).to be_within(5.seconds).of Time.now + expect(order.payments.first.state).to eq "checkout" end end end diff --git a/spec/models/spree/order_spec.rb b/spec/models/spree/order_spec.rb index 37732a7eb8..a071373551 100644 --- a/spec/models/spree/order_spec.rb +++ b/spec/models/spree/order_spec.rb @@ -781,4 +781,41 @@ describe Spree::Order do expect(order.checkout_steps).to_not include "confirm" end end + + describe "finding pending_payments" do + let!(:order) { create(:order, order_cycle: create(:simple_order_cycle, orders_close_at: nil) ) } + let!(:payment) { create(:payment, order: order, state: 'checkout') } + + context "when the order is not a standing order" do + it "returns the payments on the order" do + expect(order.reload.pending_payments).to eq [payment] + end + end + + context "when the order is a standing order" do + let!(:standing_order) { create(:standing_order, orders: [order]) } + + context "and order_cycle has no order_close_at set" do + it "returns the payments on the order" do + expect(order.reload.pending_payments).to eq [payment] + end + end + + context "and the order_cycle has closed" do + before { order.order_cycle.update_attributes(orders_close_at: 5.minutes.ago)} + + it "returns the payments on the order" do + expect(order.reload.pending_payments).to eq [payment] + end + end + + context "and the order_cycle has not yet closed" do + before { order.order_cycle.update_attributes(orders_close_at: 5.minutes.from_now)} + + it "returns an empty array" do + expect(order.reload.pending_payments).to eq [] + end + end + end + end end