Module: ProblematicDeliveriesHelper
- Defined in:
- app/helpers/problematic_deliveries_helper.rb
Overview
View helper: problematic-delivery badges and tooltips — the warehouse
"Problematic Deliveries" tab plus the delivery-level icon badges shown
beside the tracking-status icons (warehouse rows, delivery show heading).
Constant Summary collapse
- PROBLEMATIC_REASON_BADGES =
Presentation per ProblematicDeliverySweep reason: Font Awesome icon, the
short badge label, and the prose phrase used in tooltips and the digest.Colour is deliberately NOT here — it comes from
ProblematicDeliverySweep.severity, because no_pickup_scan is yellow or
red depending on the parcel's age, not on the reason alone. { exception: { icon: 'triangle-exclamation', label: 'Carrier exception', phrase: 'carrier exception with no delivered scan' }, pickup_in_lieu: { icon: 'location-dot', label: 'Left at pickup point', phrase: 'delivered to a pickup location instead of the address' }, no_pickup_scan: { icon: 'truck-ramp-box', label: 'No pickup scan', phrase: 'marked shipped but never scanned into carrier custody' }, overdue_no_delivery: { icon: 'clock', label: 'Overdue', phrase: 'past estimated delivery with no delivered scan' } }.freeze
- PROBLEMATIC_SEVERITY_BADGES =
Presentation per ProblematicDeliverySweep.severity. Bootstrap's
warningneedstext-darkto clear contrast, per DESIGN.crm.md.The word is not decoration: DESIGN.crm.md forbids conveying state with
colour alone, so every badge renders its severity as text beside the
colour and the icon. { critical: { classes: 'bg-danger', word: 'Critical', icon: 'circle-exclamation' }, warning: { classes: 'bg-warning text-dark', word: 'Warning', icon: 'triangle-exclamation' } }.freeze
Instance Method Summary collapse
-
#problematic_delivery_badges(delivery, size: nil, events_by_number: nil) ⇒ ActiveSupport::SafeBuffer?
One icon badge per unique problematic reason across the delivery's parcels, rendered with the same markup/tooltip machinery as the tracking-status badges so they sit naturally beside them.
-
#problematic_reason_label(reason) ⇒ String
Short badge text, e.g.
-
#problematic_reason_tooltip(reason, tracking_numbers: []) ⇒ String
Tooltip text for a problematic-delivery reason badge.
-
#problematic_severity_badge(shipment, reason) ⇒ ActiveSupport::SafeBuffer
The warehouse tab's Problem cell: one badge carrying severity colour, severity word, and the reason, e.g.
-
#rma_return_badge(delivery, size: nil) ⇒ ActiveSupport::SafeBuffer?
"Return" badge for the outbound return-label half of an Rma.
Instance Method Details
#problematic_delivery_badges(delivery, size: nil, events_by_number: nil) ⇒ ActiveSupport::SafeBuffer?
One icon badge per unique problematic reason across the delivery's
parcels, rendered with the same markup/tooltip machinery as the
tracking-status badges so they sit naturally beside them. Reasons come
from ProblematicDeliverySweep.badge_reason (the sweep/tab criteria),
so a badge disappears exactly when the row would leave the warehouse
Problematic Deliveries tab (delivered scan, dismissal, 30-day age-out).
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'app/helpers/problematic_deliveries_helper.rb', line 115 def problematic_delivery_badges(delivery, size: nil, events_by_number: nil) return nil unless delivery by_reason = delivery.shipments .select { |s| s.tracking_number.present? } .group_by { |s| ProblematicDeliverySweep.badge_reason(s, events: events_by_number&.dig(s.tracking_number)) } by_reason.delete(nil) return nil if by_reason.empty? badges = by_reason.map do |reason, shipments| style = PROBLEMATIC_REASON_BADGES.fetch(reason) # Worst case wins the colour: one critical parcel among several makes # the delivery's badge red, rather than averaging down to yellow. severity = if shipments.any? { |s| ProblematicDeliverySweep.severity(s, reason) == :critical } :critical else :warning end badge = ShipmentEventStatusSummary::Badge.new( kind: :problematic, state: reason, color: severity == :critical ? :danger : :warning, icon: style[:icon], tooltip: problematic_reason_tooltip(reason, tracking_numbers: shipments.map(&:tracking_number)), event_time: nil ) render_tracking_status_badge(badge, size: size) end safe_join(badges) end |
#problematic_reason_label(reason) ⇒ String
Returns short badge text, e.g. "No pickup scan".
37 38 39 |
# File 'app/helpers/problematic_deliveries_helper.rb', line 37 def problematic_reason_label(reason) PROBLEMATIC_REASON_BADGES.dig(reason.to_sym, :label) || reason.to_s.humanize end |
#problematic_reason_tooltip(reason, tracking_numbers: []) ⇒ String
Tooltip text for a problematic-delivery reason badge.
46 47 48 49 50 51 |
# File 'app/helpers/problematic_deliveries_helper.rb', line 46 def problematic_reason_tooltip(reason, tracking_numbers: []) phrase = PROBLEMATIC_REASON_BADGES.dig(reason.to_sym, :phrase) || reason.to_s.humanize.downcase tooltip = "Problematic delivery: #{phrase}" tooltip += " — #{tracking_numbers.join(', ')}" if tracking_numbers.present? tooltip end |
#problematic_severity_badge(shipment, reason) ⇒ ActiveSupport::SafeBuffer
The warehouse tab's Problem cell: one badge carrying severity colour,
severity word, and the reason, e.g. a red "Critical · Carrier exception".
59 60 61 62 63 64 65 66 67 |
# File 'app/helpers/problematic_deliveries_helper.rb', line 59 def problematic_severity_badge(shipment, reason) severity = ProblematicDeliverySweep.severity(shipment, reason) style = PROBLEMATIC_SEVERITY_BADGES.fetch(severity) tag.span(class: "badge #{style[:classes]} bs-tooltip", data: { placement: 'bottom' }, title: problematic_reason_tooltip(reason, tracking_numbers: [shipment.tracking_number])) do safe_join([fa_icon(style[:icon]), " #{style[:word]} · #{problematic_reason_label(reason)}"]) end end |
#rma_return_badge(delivery, size: nil) ⇒ ActiveSupport::SafeBuffer?
"Return" badge for the outbound return-label half of an Rma.
These deliveries sit in the same warehouse lists and the same
Problematic Deliveries tab as paid outbound orders, but they are a
different job with a different owner: a return label we issued that the
customer may legitimately never use (they shipped it themselves, used
another carrier, or no return was needed). Staff need to tell the two
apart at a glance rather than reading the missing order number — on
2026-07-30, 7 of the 8 aged no-scan Canada rows were RMA returns and
only DE794814 (SO728353) was a real sales order.
Rendered through the same ShipmentEventStatusSummary::Badge machinery
as the tracking-status and problematic badges so it sits naturally in
the same icon row.
87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'app/helpers/problematic_deliveries_helper.rb', line 87 def rma_return_badge(delivery, size: nil) return nil unless delivery&.is_rma_return? rma = delivery.rma_for_return badge = ShipmentEventStatusSummary::Badge.new( kind: :rma_return, state: :rma_return, color: :info, icon: 'arrow-rotate-left', tooltip: "RMA return label#{" — RMA##{rma.id}" if rma}: outbound return label, not a customer order", event_time: nil ) render_tracking_status_badge(badge, size: size) end |