Class: Delivery::Transitions::ToShippedHandler
- Inherits:
-
BaseService
- Object
- BaseService
- Delivery::Transitions::ToShippedHandler
- Includes:
- AfterCommitEverywhere
- Defined in:
- app/services/delivery/transitions/to_shipped_handler.rb
Overview
Handles all business logic after a delivery transitions to the 'shipped' state.
This is an AFTER_TRANSITION handler - the delivery state has already been
saved as 'shipped'. These are post-processing tasks that should not prevent
the shipment from being recorded.
== Execution Order (sync steps run in-process, then event triggers async work)
- handle_serial_numbers - Link serials to line items and update counts [sync]
- set_shipped_date - Record when the shipment left the warehouse [sync]
- update_order_status - Notify order that a delivery shipped [sync]
- update_line_item_quantities - Update qty_shipped on line items [sync]
- reset_order_discount - Recalculate order totals after shipment [sync]
↳ MUST complete before invoicing; keeping sync preserves ordering guarantee. - publish Events::DeliveryShipped (after_commit)
→ NotificationShippingTrackingHandler - Email customer with tracking info [async]
→ Delivery::InvoicingHandler - Enqueue invoice creation [async]
== Why After Transition?
These are all post-shipment housekeeping tasks. The shipment has physically
left the building - we're just updating records and notifying stakeholders.
If any of these fail, we don't want to "unship" the delivery.
== Why reset_order_discount stays synchronous
Invoicing must see correct discount totals. If reset ran as an async subscriber
alongside invoicing, a race condition would allow invoicing to snapshot stale
discount data. Keeping it synchronous in this handler guarantees ordering.
Instance Method Summary collapse
-
#initialize(delivery) ⇒ ToShippedHandler
constructor
A new instance of ToShippedHandler.
- #process ⇒ Object
Constructor Details
#initialize(delivery) ⇒ ToShippedHandler
Returns a new instance of ToShippedHandler.
39 40 41 42 43 |
# File 'app/services/delivery/transitions/to_shipped_handler.rb', line 39 def initialize(delivery) super() @delivery = delivery @order = delivery.order end |
Instance Method Details
#process ⇒ Object
45 46 47 48 49 50 51 52 53 54 |
# File 'app/services/delivery/transitions/to_shipped_handler.rb', line 45 def process logger.tagged("Delivery #{@delivery.id} ToShippedHandler") do handle_serial_numbers set_shipped_date update_order_status update_line_item_quantities reset_order_discount publish_delivery_shipped_event end end |