Class: Order::AuthorizationSplitter

Inherits:
Object
  • Object
show all
Defined in:
app/services/order/authorization_splitter.rb

Overview

Allocates a parent order's existing authorization across a split-off child
order, once the child has committed delivery(ies) to attach payment to.

This is the payment half of Splitter, extracted so it can run in
two places:

  1. Synchronously inside Splitter when the child already has a
    delivery at split time (the in-stock case).
  2. Deferred, via AuthorizationSplitWorker, when the child's
    delivery is committed after the split finished (back-order / shipping
    quoted later) — the case where the authorization previously never
    followed the order.

@order is the parent (which holds the un-split authorization) and
@new_order is the child. The credit-card / PayPal / PO logic is unchanged
from the original splitter.

Defined Under Namespace

Classes: Result

Instance Method Summary collapse

Constructor Details

#initialize(parent, new_order, logger: Rails.logger) ⇒ AuthorizationSplitter

Returns a new instance of AuthorizationSplitter.

Parameters:

  • parent (Order)

    the order holding the original authorization

  • new_order (Order)

    the split-off child order to fund

  • logger (Logger) (defaults to: Rails.logger)


42
43
44
45
46
# File 'app/services/order/authorization_splitter.rb', line 42

def initialize(parent, new_order, logger: Rails.logger)
  @order = parent
  @new_order = new_order
  @logger = logger
end

Instance Method Details

#callBoolean, Result

Splits the parent's authorization onto the child's deliveries.

Returns:

  • (Boolean)

    true if an allocation was attempted, false when there was
    nothing to do (no child deliveries, or no authorized parent payment).

  • (Result)

    :split when the child ends up funded, :failed when a
    payment path ran but it's still underfunded, :noop when there was nothing
    to allocate. Callers must not advance the order's state on :noop/:failed.



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'app/services/order/authorization_splitter.rb', line 55

def call
  return Result.noop if @new_order.deliveries.blank?

  po_payment = @order.payments.all_authorized.where(category: [Payment::PO, Payment::VPO, Payment::CHECK, Payment::CASH]).first
  cc_payment = @order.payments.all_authorized.where(category: Payment::CREDIT_CARD).first
  paypal_payment = @order.payments.all_authorized.where(category: Payment::PAYPAL).first

  if po_payment
    attrs = {
      currency: po_payment.currency,
      category: po_payment.category,
      po_number: po_payment.po_number,
      amount: @new_order.total
    }
    Payment::OrderProcessor.new(@new_order, attrs).process
  elsif cc_payment && cc_payment.credit_card_vault.present?
    split_cc_payment(cc_payment)
  elsif paypal_payment
    split_paypal_payment(paypal_payment)
  else
    return Result.noop
  end

  # A path ran; report whether the child is actually covered now. (The
  # individual gateway paths swallow their own failures, so balance is the
  # reliable post-condition.)
  @new_order.reload
  @new_order.balance <= 0 ? Result.split : Result.failed
end