Class: SpreeUberDirect::DeliveryDispatcher

Inherits:
Object
  • Object
show all
Defined in:
app/services/spree_uber_direct/delivery_dispatcher.rb

Overview

Dispatches a completed order to Uber Direct: creates the delivery against its already-open quote if one exists and hasn't expired, or requests a fresh quote and creates the delivery from that instead. Same accept-or-requote shape as SpreeDoordash::DeliveryDispatcher, for the identical reason — checkout can easily outlast a quote's validity window (Uber returns its own real expires per quote; see SpreeUberDirect::QuoteMapping#expired?).

Architecturally bigger than DoorDash's own accept_quote (which only needs the external_delivery_id, DoorDash already has everything else from the original quote request) — confirmed live against a real Sandbox 400: Uber's POST /deliveries wants a full DeliveryReq body (pickup/dropoff name+address+phone, manifest_items, manifest_total_value) even when a quote_id is also provided. Reuses AddressPayload (shared with Quote) rather than duplicating the formatting logic.

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.callObject



19
# File 'app/services/spree_uber_direct/delivery_dispatcher.rb', line 19

def self.call(...) = new.call(...)

Instance Method Details

#call(order) ⇒ Object



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'app/services/spree_uber_direct/delivery_dispatcher.rb', line 21

def call(order)
  quote_mapping = quote_mapping_for(order)
  return nil unless quote_mapping

  stock_location = pickup_location_for(order)
  return nil unless stock_location

  client = SpreeUberDirect::Client.for_store(order.store || Spree::Store.default)
  response = client.create_delivery(build_payload(order, stock_location, quote_mapping, robo_courier: robo_courier?(client)))

  persist_delivery!(order, response)
rescue SpreeUberDirect::Client::MissingCredentialsError, SpreeUberDirect::RequestError => e
  Rails.logger.error("[SpreeUberDirect] dispatch failed for order #{order.number}: #{e.message}")
  SpreeUberDirect::DeliveryMapping.find_or_initialize_by(order: order).mark_failed!(e)
  SpreeUberDirect::Alerting.capture(e, context: { area: 'dispatch', order_number: order.number })
  nil
end