Class: WebhookProcessors::ShipengineProcessor
- Inherits:
-
Object
- Object
- WebhookProcessors::ShipengineProcessor
- Defined in:
- app/services/webhook_processors/shipengine_processor.rb
Overview
Processor for ShipEngine tracking webhook callbacks
Updates Shipment tracking status based on webhook events
Constant Summary collapse
- TRACKING_STATUS_CODES =
ShipEngine status codes mapped to our tracking states
Mirrors Shipping::PackageShipmentTracking::TRACKING_STATUS_CODES { 'UN' => 'unknown', 'AC' => 'accepted', 'IT' => 'in_transit', 'DE' => 'delivered', 'EX' => 'exception', 'AT' => 'delivery_attempt', 'NY' => 'not_yet_in_system', 'SP' => 'delivered_to_collection_location' }.freeze
- MOVEMENT_STATUS_CODES =
Status codes that indicate the carrier has actually accepted the package
(i.e., the package is past the "label created" stage).
AC = Accepted/label created — we do NOT book insurance on this event. %w[IT DE EX AT SP].freeze
Class Method Summary collapse
Instance Method Summary collapse
- #call ⇒ Object
-
#initialize(webhook_log) ⇒ ShipengineProcessor
constructor
A new instance of ShipengineProcessor.
Constructor Details
#initialize(webhook_log) ⇒ ShipengineProcessor
Returns a new instance of ShipengineProcessor.
30 31 32 33 34 |
# File 'app/services/webhook_processors/shipengine_processor.rb', line 30 def initialize(webhook_log) @webhook_log = webhook_log @data = webhook_log.data @tracking_data = @data['data'] || {} end |
Class Method Details
.call(webhook_log) ⇒ Object
26 27 28 |
# File 'app/services/webhook_processors/shipengine_processor.rb', line 26 def self.call(webhook_log) new(webhook_log).call end |
Instance Method Details
#call ⇒ Object
41 42 43 44 45 46 47 48 49 50 51 52 53 54 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 84 85 |
# File 'app/services/webhook_processors/shipengine_processor.rb', line 41 def call tracking_number = @tracking_data['tracking_number'] status_code = @tracking_data['status_code'] Rails.logger.info "[ShipengineProcessor] Processing tracking update: #{tracking_number} -> #{status_code}" shipment, rma = find_resources(tracking_number) # Persist per-scan ShipmentEvent rows regardless of whether the # tracking number resolves to a known Shipment — the audit trail is # worth keeping even when we can't link it. shipment_id stays null for # an external-only RMA or an unresolved number. events_persisted = persist_shipment_events(shipment) unless shipment || rma Rails.logger.warn "[ShipengineProcessor] No Shipment or RMA found for tracking: #{tracking_number}" return { status: 'not_found', reason: 'No Shipment or RMA found for tracking number', tracking_number: tracking_number, shipment_events_persisted: events_persisted } end if shipment result = update_shipment_tracking(shipment) Rails.logger.info "[ShipengineProcessor] Updated #{result[:shipments_updated] || 1} shipment(s) sharing tracking #{tracking_number} to #{result[:tracking_state]}" response = { status: result[:success] ? 'success' : 'failed', shipment_id: shipment.id, shipments_updated: result[:shipments_updated], tracking_number: tracking_number, tracking_state: result[:tracking_state], status_code: status_code, shipment_events_persisted: events_persisted, error: result[:error] }.compact response[:rma_tracking] = handle_rma_tracking(rma, tracking_number, status_code) if rma response else handle_rma_tracking(rma, tracking_number, status_code).merge( shipment_events_persisted: events_persisted ) end end |