Class: Shipping::PackageShipmentTracking
- Inherits:
-
BaseService
- Object
- BaseService
- Shipping::PackageShipmentTracking
- Defined in:
- app/services/shipping/package_shipment_tracking.rb
Defined Under Namespace
Classes: Result
Constant Summary collapse
- TRACKING_STATUS_CODES =
status_code
Value Description
UN Unknown
AC Accepted
IT In Transit
DE Delivered
EX Exception
AT Delivery Attempt
NY Not Yet In System
SP Delivered To Collection Location { 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
- RETRYABLE_EXCEPTIONS =
Exceptions to retry on - includes timeouts and transient ShipEngine errors
(Retryable::TIMEOUT_CLASSES + [ShipEngineRb::Exceptions::ShipEngineError]).freeze
Instance Method Summary collapse
-
#initialize(options = {}) ⇒ PackageShipmentTracking
constructor
A new instance of PackageShipmentTracking.
- #process(shipments) ⇒ Object
Methods inherited from BaseService
#log_debug, #log_error, #log_info, #log_warning, #logger, #options, #tagged_logger
Constructor Details
#initialize(options = {}) ⇒ PackageShipmentTracking
Returns a new instance of PackageShipmentTracking.
32 |
# File 'app/services/shipping/package_shipment_tracking.rb', line 32 def initialize( = {}); end |
Instance Method Details
#process(shipments) ⇒ Object
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 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/shipping/package_shipment_tracking.rb', line 37 def process(shipments) shipments_tracking_succeeded = [] shipments_tracking_failed = [] shipments_tracking_failed_msgs = [] shipments.each do |shipment| res = {} begin # Adding a bit of retry juice to throttle things # Retries on timeouts AND ShipEngine carrier errors (which can be transient) Retryable.retryable(tries: 3, sleep: lambda { |n| 4**n }, on: RETRYABLE_EXCEPTIONS) do |attempt_number, _exception| Rails.logger.warn "WyShipping.track_shipment(#{shipment.id}) attempt #{attempt_number}" if attempt_number > 1 res = WyShipping.track_shipment(shipment) end Rails.logger.info { "Shipping::PackageShipmentTracking process: shipment, ID: #{shipment.id}, WyShipping.track_shipment(shipment): #{res}" } if res[:status_code] == :ok tracking_result = res.dig(:tracking_result) tracking_state = TRACKING_STATUS_CODES[tracking_result.dig(:status_code).to_sym] if tracking_state && shipment.update(tracking_state: tracking_state) tracking_result_hash = { tracking_status: tracking_result.dig(:status_code), tracking_description: tracking_result.dig(:status_description), tracking_carrier_status: tracking_result.dig(:carrier_status_code), tracking_carrier_description: tracking_result.dig(:carrier_status_description) } tracking_result_hash[:estimated_delivery_date] = Date.parse(tracking_result.dig(:estimated_delivery_date)) if tracking_result.dig(:estimated_delivery_date) tracking_result_hash[:actual_delivery_date] = Date.parse(tracking_result.dig(:actual_delivery_date)) if tracking_result.dig(:actual_delivery_date) shipment.update(tracking_result_hash) shipments_tracking_succeeded << shipment else shipments_tracking_failed << shipment msg = shipment.errors_to_s msg += "tracking status of #{tracking_result.dig(:status_code)} not in defined shipping tracking states" unless tracking_state shipments_tracking_failed_msgs << msg end else shipments_tracking_failed << shipment shipments_tracking_failed_msgs << res[:status_message] end rescue StandardError => e # Catch ALL errors for this shipment - don't let one failure stop the batch Rails.logger.error "[PackageShipmentTracking] Failed to track shipment #{shipment.id}: #{e.class.name}: #{e.}" shipments_tracking_failed << shipment shipments_tracking_failed_msgs << "Shipment #{shipment.id}: #{e.class.name}: #{e.}" end end Result.new(shipments_tracking_succeeded:, shipments_tracking_failed:, shipments_tracking_failed_msgs:) end |