mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-03-22 05:18:51 +00:00
84 lines
2.5 KiB
Ruby
84 lines
2.5 KiB
Ruby
require 'open_food_network/subscription_summarizer'
|
|
|
|
class SubscriptionPlacementJob
|
|
def perform
|
|
ids = proxy_orders.pluck(:id)
|
|
proxy_orders.update_all(placed_at: Time.zone.now)
|
|
ProxyOrder.where(id: ids).each do |proxy_order|
|
|
proxy_order.initialise_order!
|
|
process(proxy_order.order)
|
|
end
|
|
|
|
send_placement_summary_emails
|
|
end
|
|
|
|
private
|
|
|
|
delegate :record_order, :record_success, :record_issue, to: :summarizer
|
|
delegate :record_and_log_error, :send_placement_summary_emails, to: :summarizer
|
|
|
|
def summarizer
|
|
@summarizer ||= OpenFoodNetwork::SubscriptionSummarizer.new
|
|
end
|
|
|
|
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(:subscription).merge(Subscription.not_canceled.not_paused)
|
|
end
|
|
|
|
def process(order)
|
|
record_order(order)
|
|
return record_issue(:complete, order) if order.completed?
|
|
|
|
changes = cap_quantity_and_store_changes(order)
|
|
if order.line_items.where('quantity > 0').empty?
|
|
order.reload.adjustments.destroy_all
|
|
order.update!
|
|
return send_empty_email(order, changes)
|
|
end
|
|
|
|
move_to_completion(order)
|
|
send_placement_email(order, changes)
|
|
rescue StateMachine::InvalidTransition
|
|
record_and_log_error(:processing, order)
|
|
end
|
|
|
|
def cap_quantity_and_store_changes(order)
|
|
changes = {}
|
|
order.insufficient_stock_lines.each do |line_item|
|
|
changes[line_item.id] = line_item.quantity
|
|
line_item.cap_quantity_at_stock!
|
|
end
|
|
unavailable_stock_lines_for(order).each do |line_item|
|
|
changes[line_item.id] = changes[line_item.id] || line_item.quantity
|
|
line_item.update_attributes(quantity: 0)
|
|
end
|
|
changes
|
|
end
|
|
|
|
def move_to_completion(order)
|
|
until order.completed? do order.next! end
|
|
end
|
|
|
|
def unavailable_stock_lines_for(order)
|
|
order.line_items.where('variant_id NOT IN (?)', available_variants_for(order))
|
|
end
|
|
|
|
def available_variants_for(order)
|
|
OrderCycleDistributedVariants.new(order.order_cycle, order.distributor).available_variants
|
|
end
|
|
|
|
def send_placement_email(order, changes)
|
|
record_issue(:changes, order) if changes.present?
|
|
record_success(order) if changes.blank?
|
|
SubscriptionMailer.placement_email(order, changes).deliver
|
|
end
|
|
|
|
def send_empty_email(order, changes)
|
|
record_issue(:empty, order)
|
|
SubscriptionMailer.empty_email(order, changes).deliver
|
|
end
|
|
end
|