Module: Crm::ShipmentsHelper

Defined in:
app/helpers/crm/shipments_helper.rb

Overview

View helpers for the CRM shipments screens: container-type icons and labels,
shipment contents dropdowns, uploads, audit badges, and command links.

See Also:

  • ShipmentsController

Instance Method Summary collapse

Instance Method Details

#container_type_icon(container_type) ⇒ String

Returns the Font Awesome icon name for a shipment container type.

Parameters:

  • container_type (String)

    container type name (e.g. 'pallet', 'box')

Returns:

  • (String)

    icon name ('pallet-alt' for pallets, 'box' otherwise)



22
23
24
# File 'app/helpers/crm/shipments_helper.rb', line 22

def container_type_icon(container_type)
  container_type == 'pallet' ? 'pallet-alt' : 'box'
end

#friendly_shipment_status(shipment) ⇒ String

Returns a human-friendly shipment status, annotated with the packaging
solution source for suggested shipments.

Parameters:

  • shipment (Shipment)

    shipment whose status to render

Returns:

  • (String)

    friendly status text



164
165
166
167
168
169
170
171
172
# File 'app/helpers/crm/shipments_helper.rb', line 164

def friendly_shipment_status(shipment)
  addendum = ""
  if shipment.state == 'suggested'
    packing_solution = Shipping::DeterminePackaging.new.process(delivery: shipment.delivery, is_freight: shipment.delivery.ships_ltl_freight?)
    packing_solution.source_type.to_s
    addendum = " (#{packing_solution.source_type.to_s.humanize.downcase})" if packing_solution.source_type.present?
  end
  "#{friendly_status(shipment.state)}#{addendum}"
end

Renders a badge showing a shipment's audit issue count, with a popover
listing the individual issues.

Parameters:

  • shipment (Shipment, nil)

    shipment to badge

Returns:

  • (String, nil)

    badge HTML, or nil when blank, voided, or issue-free



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'app/helpers/crm/shipments_helper.rb', line 133

def shipment_audit_link(shipment)
  return if shipment.blank?
  return if shipment.voided?

  audit = shipment.audit_result&.values
  return unless audit.present? && shipment.issues_count > 0

  badge_class = audit.size > 1 ? 'bg-danger' : 'bg-warning text-dark'
  issues_html = audit.map { |v| "#{v}" }.join('<br>')

  badge = (:a, shipment.issues_count,
    class: "badge #{badge_class} text-decoration-none",
    role: 'button',
    tabindex: 0,
    data: {
      bs_toggle: 'popover',
      bs_trigger: 'focus',
      bs_placement: 'bottom',
      bs_html: 'true',
      bs_content: issues_html
    },
    title: 'Shipping Issues')

  (:span, badge, data: { controller: 'popover' })
end

#shipment_command_options(shipment = @shipment, link_options = {}) ⇒ Array<String>

Builds the action links available for a shipment (view, edit, delete,
labels, manifest), filtered by state, delivery locks, and user role.

Parameters:

  • shipment (Shipment) (defaults to: @shipment)

    shipment to build links for (defaults to @shipment)

  • link_options (Hash) (defaults to: {})

    extra options forwarded to each link_to via with_options;
    the :return_path entry is extracted and passed as a param instead

Returns:

  • (Array<String>)

    rendered link HTML fragments



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'app/helpers/crm/shipments_helper.rb', line 107

def shipment_command_options(shipment = @shipment, link_options = {})
  # class: 'btn btn-outline-primary'
  links = []
  return_path = link_options.delete(:return_path)
  with_options(link_options) do |d|
    links << d.link_to("View #{shipment.container_type.capitalize}", shipment_path(shipment.id))
    if shipment.editable? && (!shipment.delivery&.locked_for_fba? || current_user.has_role?('admin'))
      links << d.link_to('Edit', edit_shipment_path(shipment, return_path: return_path))
      links << d.link_to('Delete', shipment_path(shipment, return_path: return_path), data: { turbo_confirm: 'Are you sure?', turbo_method: :delete }) unless shipment.delivery&.incorrectly_packaged_ups_canada_order
    end
    links << d.link_to('View Ship Label', upload_path(shipment.ship_label_pdf)) if shipment.ship_label_pdf
    links << d.link_to('View Bill of Lading', upload_path(shipment.bol_pdf)) if shipment.bol_pdf
    links << d.link_to('Manifest', upload_path(shipment.manifest.manifest_pdf)) if shipment.manifest.present? && shipment.manifest.manifest_pdf.present?
    links << d.link_to('Letter Format Label', upload_path(shipment.ship_label_pdf(true))) if shipment.ship_label_pdf(true)
    links << d.link_to('Carton/UCC-128 Label', carton_label_shipment_path(shipment.id, format: :pdf)) unless shipment.suggested? || shipment.delivery.nil?
    # links << :separator
    # links += available_events_links(shipment, { return_path: return_path })
  end
  links
end

#shipment_container_type_for_select_with_iconsArray<Array(String, String)>

Builds container-type select options with a Font Awesome icon per type.

Returns:

  • (Array<Array(String, String)>)

    [icon label, container type] pairs for select options



11
12
13
14
15
16
# File 'app/helpers/crm/shipments_helper.rb', line 11

def shipment_container_type_for_select_with_icons
  Shipment.container_types_for_select.map do |ct|
    icon_symbol = container_type_icon(ct[1])
    [fa_icon(icon_symbol, text: ct[0]), ct[1]]
  end
end

#shipment_container_type_label(shipment) ⇒ String?

Renders an icon plus titleized container-type label for a shipment.

Parameters:

  • shipment (Shipment, nil)

    shipment to label

Returns:

  • (String, nil)

    HTML-safe icon label, or nil when shipment is blank



30
31
32
33
34
# File 'app/helpers/crm/shipments_helper.rb', line 30

def shipment_container_type_label(shipment)
  return if shipment.blank?

  fa_icon(container_type_icon(shipment.container_type), text: shipment.container_type&.titleize)
end

#shipment_contents_drop_down(shipment, main_link_class: nil) ⇒ String?

Renders a dropdown summarizing a shipment's contents by SKU and quantity,
or an icon when the shipment has no contents.

Parameters:

  • shipment (Shipment, nil)

    shipment whose contents to summarize

  • main_link_class (String, nil) (defaults to: nil)

    CSS class for the dropdown's main link

Returns:

  • (String, nil)

    rendered dropdown or icon HTML, or nil when shipment is blank



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'app/helpers/crm/shipments_helper.rb', line 42

def shipment_contents_drop_down(shipment, main_link_class: nil)
  return if shipment.blank?

  label = shipment.shipment_contents.sum(:quantity)
  if label.zero?
    if shipment.child_shipments.present?
      fa_icon('layer-plus', class: 'btn', title: 'Parent Shipment, see cartons for contents')
    else
      fa_icon('empty-set', class: 'btn text-danger')
    end
  else
    opts = {}
    opts[:main_link_class] = main_link_class if main_link_class
    render_simple_drop_down [label.to_s] + shipment.shipment_contents.joins(line_item: :item).order(Item[:sku]).group(Item[:sku]).sum(:quantity).map { |sku, quantity| { tag: :p, content: "#{quantity} - #{sku}", style: 'white-space:nowrap' } }, opts
  end
end

#shipment_description(shipment) ⇒ String

Renders a short shipment description: container-type label plus the last
four digits of the reference number.

Parameters:

  • shipment (Shipment)

    shipment to describe

Returns:

  • (String)

    HTML-safe description



96
97
98
# File 'app/helpers/crm/shipments_helper.rb', line 96

def shipment_description(shipment)
  "#{shipment_container_type_label(shipment)} ...#{shipment.reference_number&.last(4)}".html_safe
end

#uploads_for_shipment(shipment) ⇒ Array<Upload>

Collects a shipment's uploads sorted by category then newest first.

Parameters:

  • shipment (Shipment, nil)

    shipment whose uploads to list

Returns:

  • (Array<Upload>)

    sorted uploads (empty when shipment is blank)



63
64
65
66
67
# File 'app/helpers/crm/shipments_helper.rb', line 63

def uploads_for_shipment(shipment)
  uploads = []
  uploads += shipment.uploads.to_a if shipment.present?
  uploads.sort_by { |u| [u.category.to_s, -u.created_at.to_i] }
end

#uploads_for_shipment_dropdown(shipment) ⇒ String?

Renders a paperclip dropdown linking to each of a shipment's uploads.

Parameters:

  • shipment (Shipment, nil)

    shipment whose uploads to link

Returns:

  • (String, nil)

    rendered dropdown HTML, or nil when there are no uploads

See Also:



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'app/helpers/crm/shipments_helper.rb', line 74

def uploads_for_shipment_dropdown(shipment)
  links = [fa_icon('paperclip')]
  uploads_for_shipment(shipment).each do |psu|
    title = (:div, class: 'row') do
      concat (:div, psu.category.humanize.titleize, class: 'float-start') if psu.category
      concat tag.br
      concat (:p, render_datetime(psu.created_at), class: 'text-body-secondary')
    end
    links << link_to(title,
                upload_path(psu),
                target: '_blank', rel: "noopener noreferrer")
  end
  return unless links.size > 1

  render_simple_drop_down links
end