Class: Delivery::GenerateLabels

Inherits:
BaseService show all
Defined in:
app/services/delivery/generate_labels.rb

Overview

Buys carrier labels for a delivery via WyShipping and turns the result into
persisted state: shipment tracking numbers + label_complete transitions,
delivery-level PRO/BOL/pickup/cost fields, per-package label PDFs (including
RMA letter-format / paperless-QR variants), the LTL BOL, the commercial
invoice, the combined all-labels PDF, and finally the delivery's
ship_labeled transition.

Runs under a per-delivery advisory lock (non-blocking) so the
duplicate-label guard is atomic rather than check-then-act — two concurrent
buys can't both pass the guard and reach WyShipping (the SO728077
two-employees scenario, defect G).

Extracted from Delivery#generate_labels / #perform_generate_labels
(god-object decomposition); the model keeps a thin delegator.

Examples:

Delivery::GenerateLabels.new(delivery).process

Instance Attribute Summary

Attributes inherited from BaseService

#options

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from BaseService

#log_debug, #log_error, #log_info, #log_warning, #logger, #tagged_logger

Constructor Details

#initialize(delivery) ⇒ GenerateLabels

Returns a new instance of GenerateLabels.



29
30
31
32
# File 'app/services/delivery/generate_labels.rb', line 29

def initialize(delivery)
  super()
  @delivery = delivery
end

Class Method Details

.single_document_ltl?(carrier) ⇒ Boolean

Single-document LTL carriers return one label/BOL covering every pallet,
so every shipment row maps to labels[0]; everyone else gets a per-package
label at labels[j].

Returns:

  • (Boolean)


25
26
27
# File 'app/services/delivery/generate_labels.rb', line 25

def self.single_document_ltl?(carrier)
  (%w[UPSFreight Freightquote RlCarriers Saia YrcFreight] + ShippingOption::SHIPENGINE_LTL_CARRIERS).include?(carrier)
end

Instance Method Details

#processHash{Symbol => Object}

Returns :status_code / :status_message.

Returns:

  • (Hash{Symbol => Object})

    :status_code / :status_message



35
36
37
38
39
40
41
42
43
44
45
# File 'app/services/delivery/generate_labels.rb', line 35

def process
  lock_key = "delivery|#{delivery.id}|generate_labels"
  result = Delivery.with_advisory_lock(lock_key, timeout_seconds: 0) do
    delivery.reload # pick up a concurrent buy's committed label_complete shipments
    perform
  end
  return result unless result == false

  { status_code: :error,
    status_message: 'Label generation is already running for this delivery; please retry in a moment.' }
end