Class: SpreeUberDirect::DeliveryStatusMapper
- Inherits:
-
Object
- Object
- SpreeUberDirect::DeliveryStatusMapper
- Defined in:
- app/services/spree_uber_direct/delivery_status_mapper.rb
Overview
Applies an Uber Direct delivery-status webhook event to the mapped Spree order — the Uber Direct analog of SpreeDoordash::DeliveryStatusMapper.
Uber's own status vocabulary (confirmed directly against the real
openapi.yaml shipped in uber/uber-direct-sdk, not assumed): pending,
pickup / pickup_complete, dropoff, delivered, canceled,
returned, plus shopping_completed for Courier Pick & Pack orders
(not used by this extension's own flow, but present in the schema).
No version/sequence field in Uber's payload either, same "don't gate on ordering" posture as both DoorDash's and Square's own status mappers — safety against duplicate processing comes entirely from WebhookEvent's idempotency key and from the state-guarded, idempotent operations below. Uber's own webhook ordering behavior across concurrent workers is unverified until actually observed live — flagged here rather than assumed, same precedent as every sibling status mapper's own comment.
Constant Summary collapse
- SHIP_STATUSES =
%w[delivered].freeze
- CANCEL_STATUSES =
%w[canceled returned].freeze
- LABEL_ONLY_STATUSES =
Real Uber lifecycle statuses with no Spree shipment_state equivalent — recorded as a friendly last_status label only, same "label vs. state transition" split as every sibling status mapper.
%w[pending pickup pickup_complete dropoff shopping_completed].freeze
Class Method Summary collapse
Instance Method Summary collapse
Class Method Details
.call ⇒ Object
26 |
# File 'app/services/spree_uber_direct/delivery_status_mapper.rb', line 26 def self.call(...) = new.call(...) |
Instance Method Details
#call(payload) ⇒ Object
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'app/services/spree_uber_direct/delivery_status_mapper.rb', line 28 def call(payload) mapping = SpreeUberDirect::DeliveryMapping.find_by(external_delivery_id: payload['delivery_id']) return unless mapping status = payload['status'] order = mapping.order data = payload['data'] || {} courier = data['courier'] || {} case status when *SHIP_STATUSES ship!(order) when *CANCEL_STATUSES cancel!(order) when *LABEL_ONLY_STATUSES # No Spree-side transition — last_status below is the only effect. end # tracking_url isn't confirmed present on the webhook payload itself # (the real Delivery Status Webhook reference documents delivery_id/ # status/data.courier/data.pickup/data.dropoff/batch_id/ # courier_imminent — tracking_url is a top-level field on the fuller # CreateDeliveryResp/GetDeliveryResp REST shapes, which webhooks # often trim). `.presence || mapping.tracking_url` means a missing # field here just keeps whatever DeliveryDispatcher already recorded # from the create_delivery response, rather than clobbering it with # nil — safe either way, verify the real key at M4's live test. mapping.update!( last_status: status || mapping.last_status, tracking_url: data['tracking_url'].presence || mapping.tracking_url, courier_name: courier['name'].presence || mapping.courier_name, courier_phone: courier['phone_number'].presence || mapping.courier_phone ) end |