mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-24 20:36:49 +00:00
Adding job to send confirm emails for standing orders on order cycle close
This commit is contained in:
@@ -5,6 +5,12 @@ class OrderCycleOpenCloseJob
|
||||
order_cycles.each do |order_cycle|
|
||||
Delayed::Job.enqueue(StandingOrderPlacementJob.new(order_cycle))
|
||||
end
|
||||
|
||||
order_cycles = recently_closed_order_cycles.all
|
||||
recently_closed_order_cycles.update_all(standing_orders_confirmed_at: Time.now)
|
||||
order_cycles.each do |order_cycle|
|
||||
Delayed::Job.enqueue(StandingOrderConfirmJob.new(order_cycle))
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
@@ -17,4 +23,13 @@ class OrderCycleOpenCloseJob
|
||||
10.minutes.ago, Time.now, 10.minutes.ago, Time.now
|
||||
)
|
||||
end
|
||||
|
||||
def recently_closed_order_cycles
|
||||
return @recently_closed_order_cycles unless @recently_closed_order_cycles.nil?
|
||||
@recently_closed_order_cycles =
|
||||
OrderCycle.closed.where(
|
||||
'standing_orders_confirmed_at IS NULL AND (orders_close_at BETWEEN (?) AND (?) OR updated_at BETWEEN (?) AND (?))',
|
||||
10.minutes.ago, Time.now, 10.minutes.ago, Time.now
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
28
app/jobs/standing_order_confirm_job.rb
Normal file
28
app/jobs/standing_order_confirm_job.rb
Normal file
@@ -0,0 +1,28 @@
|
||||
class StandingOrderConfirmJob
|
||||
attr_accessor :order_cycle
|
||||
|
||||
def initialize(order_cycle)
|
||||
@order_cycle = order_cycle
|
||||
end
|
||||
|
||||
def perform
|
||||
orders.each do |order|
|
||||
process(order)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def orders
|
||||
Spree::Order.complete.where(order_cycle_id: order_cycle)
|
||||
.merge(StandingOrderOrder.not_canceled).joins(:standing_order_order).readonly(false)
|
||||
end
|
||||
|
||||
def process(order)
|
||||
send_confirm_email(order)
|
||||
end
|
||||
|
||||
def send_confirm_email(order)
|
||||
Spree::OrderMailer.standing_order_email(order.id, 'confirmation', {}).deliver
|
||||
end
|
||||
end
|
||||
@@ -6,6 +6,7 @@ class StandingOrderOrder < ActiveRecord::Base
|
||||
|
||||
scope :closed, -> { joins(order: :order_cycle).merge(OrderCycle.closed) }
|
||||
scope :not_closed, -> { joins(order: :order_cycle).merge(OrderCycle.not_closed) }
|
||||
scope :not_canceled, where('standing_order_orders.canceled_at IS NULL')
|
||||
|
||||
def state
|
||||
return 'canceled' if canceled?
|
||||
|
||||
@@ -17,16 +17,45 @@ describe OrderCycleOpenCloseJob do
|
||||
end
|
||||
end
|
||||
|
||||
describe "running the job" do
|
||||
let!(:order_cycle) { create(:simple_order_cycle, orders_open_at: 5.minutes.ago) }
|
||||
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) }
|
||||
let!(:order_cycle3) { create(:simple_order_cycle, orders_close_at: 9.minutes.ago, updated_at: 9.minutes.ago) }
|
||||
let!(:order_cycle4) { create(:simple_order_cycle, orders_close_at: 2.minutes.ago, standing_orders_confirmed_at: 1.minute.ago ) }
|
||||
let!(:order_cycle5) { create(:simple_order_cycle, orders_close_at: 1.minute.from_now) }
|
||||
|
||||
it "marks the order cycle as processed by setting standing_orders_placed_at" do
|
||||
expect{job.perform}.to change{order_cycle.reload.standing_orders_placed_at}
|
||||
expect(order_cycle.standing_orders_placed_at).to be_within(5.seconds).of Time.now
|
||||
it "returns unprocessed order cycles whose orders_close_at or updated_at date is within the past 10 minutes" do
|
||||
order_cycles = job.send(:recently_closed_order_cycles)
|
||||
expect(order_cycles).to include order_cycle2, order_cycle3
|
||||
expect(order_cycles).to_not include order_cycle1, order_cycle4, order_cycle5
|
||||
end
|
||||
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) }
|
||||
|
||||
it "marks the order cycle as processed by setting standing_orders_placed_at" do
|
||||
expect{job.perform}.to change{order_cycle.reload.standing_orders_placed_at}
|
||||
expect(order_cycle.standing_orders_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
|
||||
end
|
||||
|
||||
it "enqueues a StandingOrderPlacementJob for each recently opened order_cycle" do
|
||||
expect{job.perform}.to enqueue_job StandingOrderPlacementJob
|
||||
context "when an order cycle has just closed" do
|
||||
let!(:order_cycle) { create(:simple_order_cycle, orders_close_at: 5.minutes.ago) }
|
||||
|
||||
it "marks the order cycle as processed by setting standing_orders_placed_at" do
|
||||
expect{job.perform}.to change{order_cycle.reload.standing_orders_confirmed_at}
|
||||
expect(order_cycle.standing_orders_confirmed_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 StandingOrderConfirmJob
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
52
spec/jobs/standing_order_confirm_job_spec.rb
Normal file
52
spec/jobs/standing_order_confirm_job_spec.rb
Normal file
@@ -0,0 +1,52 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe StandingOrderConfirmJob do
|
||||
let(:shop) { create(:distributor_enterprise) }
|
||||
let(:order_cycle1) { create(:simple_order_cycle, coordinator: shop) }
|
||||
let(:order_cycle2) { create(:simple_order_cycle, coordinator: shop) }
|
||||
let(:schedule1) { create(:schedule, order_cycles: [order_cycle1, order_cycle2]) }
|
||||
let(:standing_order1) { create(:standing_order_with_items, shop: shop, schedule: schedule1) }
|
||||
let!(:job) { StandingOrderConfirmJob.new(order_cycle1) }
|
||||
|
||||
describe "finding standing_order orders for the specified order cycle" do
|
||||
let(:order1) { create(:order, order_cycle: order_cycle1) } # Incomplete + Linked + OC Matches
|
||||
let(:order2) { create(:order, order_cycle: order_cycle1, completed_at: 5.minutes.ago) } # Complete + Not-Linked + OC Matches
|
||||
let(:order3) { create(:order, order_cycle: order_cycle2, completed_at: 5.minutes.ago) } # Complete + Linked + OC Mismatch
|
||||
let(:order4) { create(:order, order_cycle: order_cycle1, completed_at: 5.minutes.ago) } # Complete + Linked + OC Matches + Cancelled
|
||||
let(:order5) { create(:order, order_cycle: order_cycle1, completed_at: 5.minutes.ago) } # Complete + Linked + OC Matches
|
||||
let(:cancelled_standing_order_order) { standing_order1.standing_order_orders.find_by_order_id(order4.id) }
|
||||
|
||||
before do
|
||||
standing_order1.orders = [order1, order3, order4, order5]
|
||||
cancelled_standing_order_order.update_attribute(:canceled_at, 1.minute.ago)
|
||||
end
|
||||
|
||||
it "only returns incomplete orders in the relevant order cycle that are linked to a standing order" do
|
||||
orders = job.send(:orders)
|
||||
expect(orders).to include order5
|
||||
expect(orders).to_not include order1, order2, order3, order4
|
||||
end
|
||||
end
|
||||
|
||||
describe "processing a standing order order" do
|
||||
let(:order) { standing_order1.orders.first }
|
||||
|
||||
before do
|
||||
form = StandingOrderForm.new(standing_order1)
|
||||
form.send(:initialise_orders!)
|
||||
while !standing_order1.orders.first.completed? do break unless order.next! end
|
||||
allow(job).to receive(:send_confirm_email).and_call_original
|
||||
Spree::MailMethod.create!(
|
||||
environment: Rails.env,
|
||||
preferred_mails_from: 'spree@example.com'
|
||||
)
|
||||
end
|
||||
|
||||
it "sends only a standing order confirm email, no regular confirmation emails" do
|
||||
ActionMailer::Base.deliveries.clear
|
||||
expect{job.send(:process, order)}.to_not enqueue_job ConfirmOrderJob
|
||||
expect(job).to have_received(:send_confirm_email).with(order).once
|
||||
expect(ActionMailer::Base.deliveries.count).to be 1
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user