Class: Delivery::PrintLabels

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

Overview

Assembles a delivery's printable documents (combined label PDF, SSCC carton
labels, operator-selected custom label uploads) and submits them to a
PrintNode print profile.

Extracted from DeliveriesController#handle_print_uploads so the ASYNCHRONOUS
label flows can print from their Sidekiq worker instead of a browser request.
Those flows hand off through a landing page (+complete_asynch_print_speedee+
/ +complete_asynch_print_bol+) that only loads while the operator is still
sitting on the job page — and a job can finish many minutes after it was
enqueued (the 2026-07-31 Sidekiq worker starvation held high at 11.6 min of
queue latency), by which time the operator has moved on, the redirect is never
followed, and the label never reaches the printer even though it rendered
fine. Printing from the worker takes the browser off the critical path.

Selecting no profile is a legitimate choice ("Download Label PDF" in the
ship-label form) — that path still belongs to the controller, which turns the
assembled uploads into a browser download.

Examples:

Delivery::PrintLabels.new(shipments: shipments, uploads: [pdf], intent: intent).process

Defined Under Namespace

Classes: Result

Instance Attribute Summary

Attributes inherited from BaseService

#options

Instance Method Summary collapse

Methods inherited from BaseService

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

Constructor Details

#initialize(shipments: [], uploads: [], intent: {}, generate_carton_labels: false) ⇒ PrintLabels

Returns a new instance of PrintLabels.

Parameters:

  • shipments (Enumerable<Shipment>) (defaults to: [])

    shipments to generate SSCC carton labels for

  • uploads (Array<Upload>) (defaults to: [])

    already-rendered documents to print

  • intent (Hash, nil) (defaults to: {})

    the operator's print selection — print_profile_id,
    container_label, upload_ids (string or symbol keys)

  • generate_carton_labels (Boolean) (defaults to: false)

    force SSCC generation regardless of
    the intent, for the explicit "Print carton labels" button whose form has
    no checkbox to read



54
55
56
57
58
59
60
# File 'app/services/delivery/print_labels.rb', line 54

def initialize(shipments: [], uploads: [], intent: {}, generate_carton_labels: false)
  super()
  @shipments = shipments
  @uploads = uploads
  @intent = (intent.presence || {}).with_indifferent_access
  @generate_carton_labels = generate_carton_labels
end

Instance Method Details

#processResult

Returns:



63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'app/services/delivery/print_labels.rb', line 63

def process
  documents = assemble
  return Result.new(uploads: documents, print_profile: nil, job_ids: []) if documents.blank?

  # find_by, not find: this runs from a Sidekiq worker where a profile deleted
  # between ship-label time and the job landing must degrade to "nothing
  # printed" (the caller warns) rather than kill a job whose labels are
  # already committed.
  profile = PrintProfile.find_by(id: @intent[:print_profile_id].presence)
  return Result.new(uploads: documents, print_profile: nil, job_ids: []) unless profile

  Result.new(uploads: documents, print_profile: profile,
             job_ids: documents.map { |upload| profile.print_upload(upload) })
end