WIP: StandingOrderPlacementJob no longer scoped to an order cycle

This commit is contained in:
Rob Harrington
2016-12-22 17:23:10 +11:00
parent 514a462f7b
commit 0e50009875
4 changed files with 72 additions and 83 deletions

View File

@@ -1,12 +1,6 @@
class OrderCycleOpenCloseJob
def perform
recently_opened_order_cycles.each do |order_cycle|
proxy_orders = placeable_proxy_orders_for(order_cycle).all
if proxy_orders.any?
placeable_proxy_orders_for(order_cycle).update_all(placed_at: Time.now)
Delayed::Job.enqueue(StandingOrderPlacementJob.new(proxy_orders))
end
end
Delayed::Job.enqueue(StandingOrderPlacementJob.new)
recently_closed_order_cycles.each do |order_cycle|
proxy_orders = confirmable_proxy_orders_for(order_cycle).all
@@ -27,14 +21,7 @@ class OrderCycleOpenCloseJob
OrderCycle.closed.where('(orders_close_at BETWEEN (?) AND (?) OR updated_at BETWEEN (?) AND (?))', 10.minutes.ago, Time.now, 10.minutes.ago, Time.now)
end
def placeable_proxy_orders_for(order_cycle)
# Load proxy orders for standing orders whose begins at date may between now and the order cycle close date
# Does not load proxy orders for standing orders who ends_at date is before order_cycle close
ProxyOrder.not_canceled.where(order_cycle_id: order_cycle, placed_at: nil)
.where('begins_at < ? AND (ends_at IS NULL OR ends_at > ?)', order_cycle.orders_close_at, order_cycle.orders_close_at)
.joins(:standing_order).merge(StandingOrder.not_canceled.not_paused)
.readonly(false)
end
def confirmable_proxy_orders_for(order_cycle)
ProxyOrder.not_canceled.where(order_cycle_id: order_cycle, confirmed_at: nil).where('placed_at IS NOT NULL')

View File

@@ -1,12 +1,8 @@
class StandingOrderPlacementJob
attr_accessor :proxy_orders
def initialize(proxy_orders)
@proxy_orders = proxy_orders
end
def perform
proxy_orders.each do |proxy_order|
ids = proxy_orders.pluck(:id)
proxy_orders.update_all(placed_at: Time.now)
ProxyOrder.where(id: ids).each do |proxy_order|
proxy_order.initialise_order!
process(proxy_order.order)
end
@@ -14,6 +10,13 @@ class StandingOrderPlacementJob
private
def proxy_orders
# Loads proxy orders for open order cycles that have not been placed yet
ProxyOrder.not_canceled.where(placed_at: nil)
.joins(:order_cycle).merge(OrderCycle.active)
.joins(:standing_order).merge(StandingOrder.not_canceled.not_paused)
end
def process(order)
return if order.completed?
changes = cap_quantity_and_store_changes(order) unless order.completed?

View File

@@ -3,19 +3,6 @@ require 'spec_helper'
describe OrderCycleOpenCloseJob do
let!(:job) { OrderCycleOpenCloseJob.new }
describe "finding recently opened order cycles" do
let!(:order_cycle1) { create(:simple_order_cycle, orders_open_at: 11.minutes.ago, updated_at: 11.minutes.ago) }
let!(:order_cycle2) { create(:simple_order_cycle, orders_open_at: 11.minutes.ago, updated_at: 9.minutes.ago) }
let!(:order_cycle3) { create(:simple_order_cycle, orders_open_at: 9.minutes.ago, updated_at: 9.minutes.ago) }
let!(:order_cycle4) { create(:simple_order_cycle, orders_open_at: 1.minute.from_now) }
it "returns unprocessed order cycles whose orders_open_at or updated_at date is within the past 10 minutes" do
order_cycles = job.send(:recently_opened_order_cycles)
expect(order_cycles).to include order_cycle2, order_cycle3
expect(order_cycles).to_not include order_cycle1, order_cycle4
end
end
describe "finding recently closed order cycles" do
let!(:order_cycle1) { create(:simple_order_cycle, orders_close_at: 11.minutes.ago, updated_at: 11.minutes.ago) }
let!(:order_cycle2) { create(:simple_order_cycle, orders_close_at: 11.minutes.ago, updated_at: 9.minutes.ago) }
@@ -29,32 +16,6 @@ describe OrderCycleOpenCloseJob do
end
end
describe "finding placeable proxy_orders for a particular order cycle" do
let(:shop) { create(:distributor_enterprise) }
let(:order_cycle1) { create(:simple_order_cycle, coordinator: shop, orders_close_at: 10.minutes.from_now) }
let(:order_cycle2) { create(:simple_order_cycle, coordinator: shop) }
let(:schedule) { create(:schedule, order_cycles: [order_cycle1, order_cycle2]) }
let(:standing_order1) { create(:standing_order, shop: shop, schedule: schedule, begins_at: 9.minutes.from_now, ends_at: 11.minutes.from_now) }
let(:standing_order2) { create(:standing_order, shop: shop, schedule: schedule, begins_at: 9.minutes.from_now, ends_at: 11.minutes.from_now, paused_at: 1.minute.ago) }
let(:standing_order3) { create(:standing_order, shop: shop, schedule: schedule, begins_at: 9.minutes.from_now, ends_at: 11.minutes.from_now, canceled_at: 1.minute.ago) }
let(:standing_order4) { create(:standing_order, shop: shop, schedule: schedule, begins_at: 11.minutes.from_now, ends_at: 20.minutes.from_now) }
let(:standing_order5) { create(:standing_order, shop: shop, schedule: schedule, begins_at: 1.minute.ago, ends_at: 9.minutes.from_now) }
let!(:proxy_order1) { create(:proxy_order, standing_order: standing_order1, order_cycle: order_cycle2) } # OC Mismatch
let!(:proxy_order2) { create(:proxy_order, standing_order: standing_order2, order_cycle: order_cycle1) } # Standing Order Paused
let!(:proxy_order3) { create(:proxy_order, standing_order: standing_order3, order_cycle: order_cycle1) } # Standing Order Cancelled
let!(:proxy_order4) { create(:proxy_order, standing_order: standing_order4, order_cycle: order_cycle1) } # Standing Order Begins after OC close
let!(:proxy_order5) { create(:proxy_order, standing_order: standing_order5, order_cycle: order_cycle1) } # Standing Order Ends before OC close
let!(:proxy_order6) { create(:proxy_order, standing_order: standing_order1, order_cycle: order_cycle1, canceled_at: 5.minutes.ago) } # Cancelled
let!(:proxy_order7) { create(:proxy_order, standing_order: standing_order1, order_cycle: order_cycle1, placed_at: 5.minutes.ago) } # Already placed
let!(:proxy_order8) { create(:proxy_order, standing_order: standing_order1, order_cycle: order_cycle1) } # OK
it "only returns not_canceled proxy_orders for the relevant order cycle" do
proxy_orders = job.send(:placeable_proxy_orders_for, order_cycle1)
expect(proxy_orders).to include proxy_order8
expect(proxy_orders).to_not include proxy_order1, proxy_order2, proxy_order3, proxy_order4, proxy_order5, proxy_order6, proxy_order7
end
end
describe "finding confirmable proxy orders for a particular order cycle" do
let(:shop) { create(:distributor_enterprise) }
let(:order_cycle1) { create(:simple_order_cycle, coordinator: shop, orders_close_at: 10.minutes.from_now) }
@@ -86,22 +47,8 @@ describe OrderCycleOpenCloseJob do
end
describe "running the job" do
context "when an order cycle has just opened" do
let!(:order_cycle) { create(:simple_order_cycle, orders_open_at: 5.minutes.ago) }
let!(:proxy_order) { create(:proxy_order, order_cycle: order_cycle) }
before do
allow(job).to receive(:placeable_proxy_orders_for) { ProxyOrder.where(id: proxy_order.id) }
end
it "marks placeable proxy_orders as processed by setting placed_at" do
expect{job.perform}.to change{proxy_order.reload.placed_at}
expect(proxy_order.placed_at).to be_within(5.seconds).of Time.now
end
it "enqueues a StandingOrderPlacementJob for each recently opened order_cycle" do
expect{job.perform}.to enqueue_job StandingOrderPlacementJob
end
it "enqueues a StandingOrderPlacementJob for each recently opened order_cycle" do
expect{job.perform}.to enqueue_job StandingOrderPlacementJob
end
context "when an order cycle has just closed" do

View File

@@ -1,6 +1,64 @@
require 'spec_helper'
describe StandingOrderPlacementJob do
let(:job) { StandingOrderPlacementJob.new }
describe "finding proxy_orders that are ready to be placed" do
let(:shop) { create(:distributor_enterprise) }
let(:order_cycle1) { create(:simple_order_cycle, coordinator: shop, orders_open_at: 1.minute.ago, orders_close_at: 10.minutes.from_now) }
let(:order_cycle2) { create(:simple_order_cycle, coordinator: shop, orders_open_at: 10.minutes.ago, orders_close_at: 1.minute.ago) }
let(:schedule) { create(:schedule, order_cycles: [order_cycle1, order_cycle2]) }
let(:standing_order) { create(:standing_order, shop: shop, schedule: schedule) }
let!(:proxy_order) { create(:proxy_order, standing_order: standing_order, order_cycle: order_cycle1) } # OK
it "ignores proxy orders where the OC has closed" do
expect(job.send(:proxy_orders)).to include proxy_order
proxy_order.update_attributes!(order_cycle_id: order_cycle2.id)
expect(job.send(:proxy_orders)).to_not include proxy_order
end
it "ignores proxy orders for paused or cancelled standing orders" do
expect(job.send(:proxy_orders)).to include proxy_order
standing_order.update_attributes!(paused_at: 1.minute.ago)
expect(job.send(:proxy_orders)).to_not include proxy_order
standing_order.update_attributes!(paused_at: nil)
expect(job.send(:proxy_orders)).to include proxy_order
standing_order.update_attributes!(canceled_at: 1.minute.ago)
expect(job.send(:proxy_orders)).to_not include proxy_order
end
it "ignores proxy orders that have been marked as cancelled or placed" do
expect(job.send(:proxy_orders)).to include proxy_order
proxy_order.update_attributes!(canceled_at: 5.minutes.ago)
expect(job.send(:proxy_orders)).to_not include proxy_order
proxy_order.update_attributes!(canceled_at: nil)
expect(job.send(:proxy_orders)).to include proxy_order
proxy_order.update_attributes!(placed_at: 5.minutes.ago)
expect(job.send(:proxy_orders)).to_not include proxy_order
end
end
describe "performing the job" do
context "when unplaced proxy_orders exist" do
let!(:proxy_order) { create(:proxy_order) }
before do
allow(job).to receive(:proxy_orders) { ProxyOrder.where(id: proxy_order.id) }
allow(job).to receive(:process)
end
it "marks placeable proxy_orders as processed by setting placed_at" do
expect{job.perform}.to change{proxy_order.reload.placed_at}
expect(proxy_order.placed_at).to be_within(5.seconds).of Time.now
end
it "processes placeable proxy_orders" do
job.perform
expect(job).to have_received(:process).with(proxy_order.reload.order)
end
end
end
describe "checking that line items are available to purchase" do
let(:order_cycle) { create(:simple_order_cycle) }
let(:shop) { order_cycle.coordinator }
@@ -13,8 +71,6 @@ describe StandingOrderPlacementJob do
let!(:line_item2) { create(:line_item, order: order, variant: variant2, quantity: 3) }
let!(:line_item3) { create(:line_item, order: order, variant: variant3, quantity: 3) }
let!(:job) { StandingOrderPlacementJob.new(order_cycle) }
before { Spree::Config.set(:allow_backorders, false) }
context "when all items are available from the order cycle" do
@@ -68,8 +124,6 @@ describe StandingOrderPlacementJob do
let!(:order) { proxy_order.initialise_order! }
let(:changes) { {} }
let!(:job) { StandingOrderPlacementJob.new(proxy_order.order_cycle) }
before do
expect_any_instance_of(Spree::Payment).to_not receive(:process!)
allow(job).to receive(:cap_quantity_and_store_changes) { changes }
@@ -111,8 +165,6 @@ describe StandingOrderPlacementJob do
let(:mail_mock) { double(:mailer_mock) }
let(:changes) { double(:changes) }
let!(:job) { StandingOrderPlacementJob.new(proxy_order.order_cycle) }
before do
allow(Spree::OrderMailer).to receive(:standing_order_email) { mail_mock }
allow(mail_mock).to receive(:deliver)