# frozen_string_literal: true class PlaceProxyOrder def initialize(proxy_order, summarizer, logger, stock_changes_loader) @proxy_order = proxy_order @subscription = proxy_order.subscription @summarizer = summarizer @logger = logger @stock_changes_loader = stock_changes_loader @order = nil end def call return unless place_order summarizer.record_order(order) return summarizer.record_issue(:complete, order) if order.completed? load_changes return handle_empty_order if empty_order? order.process_payments! if order.payment_required? move_to_completion send_placement_email rescue StandardError => e summarizer.record_and_log_error(:processing, order, e.message) Alert.raise_with_record(e, order) end private attr_reader :proxy_order, :subscription, :summarizer, :logger, :stock_changes_loader, :changes attr_accessor :order def place_order proxy_order.with_lock do return if proxy_order.placed_at.present? initialise_order end end def initialise_order logger.info("Placing Order for Proxy Order #{proxy_order.id}") self.order = proxy_order.initialise_order! if order.nil? summarizer.record_subscription_issue(subscription) return false end mark_as_processed true rescue StandardError => e Alert.raise(e, { proxy_order: { subscription:, proxy_order: } }) false end def mark_as_processed proxy_order.update_column(:placed_at, Time.zone.now) end def load_changes @changes = stock_changes_loader.call(order) end def empty_order? order.line_items.where('quantity > 0').empty? end def handle_empty_order order.reload.all_adjustments.destroy_all order.update_order! send_empty_email end def send_empty_email summarizer.record_issue(:empty, order) SubscriptionMailer.empty_email(order, changes).deliver_now end def move_to_completion Orders::WorkflowService.new(order).complete! end def send_placement_email summarizer.record_issue(:changes, order) if changes.present? summarizer.record_success(order) if changes.blank? SubscriptionMailer.placement_email(order, changes).deliver_now end end