Module: Order::ExpressHoldAlerting

Extended by:
ActiveSupport::Concern
Included in:
Order
Defined in:
app/models/order/express_hold_alerting.rb

Overview

Express-shipping-in-CR-hold alerting.

When a sales order the customer paid express shipping on sits in credit hold
as the warehouse cutoff approaches, it risks missing same-day dispatch — the
SO728222 lapse. This concern is the single source of truth for detecting that
situation and grading its urgency against the store-local warehouse cutoff.
It's consumed by three surfaces that must agree:

See Also:

  • — investigation of SO728222 (order 1388737)

Constant Summary collapse

PICKUP_CARRIER_ALIASES =

Escalation is anchored to the store-local carrier pickup time for the order's
express carrier (Store::CARRIER_PICKUP_TIMES) — the real "must be out the door"
deadline. These vary widely (US USPS 14:00 vs UPS 17:30), so a flat cutoff would
alert hours late for early-pickup carriers.

Two naming gaps we bridge below:

  • shipping_options.carrier is coarse ('FedEx'); the pickup map keys FedEx by tier.
    Every express FedEx option is the Express tier → alias 'FedEx' ⇒ 'FedExExpress'.
  • carriers with no pickup time on file (DHL, regional couriers, marketplace) fall
    back to DEFAULT_EXPRESS_CUTOFF.
    ponytail: carrier pickup drifts — CARRIER_PICKUP_TIMES and this default are the
    hand-tuned knobs; adjust them, not the code, when a carrier changes its schedule.
{ 'FedEx' => 'FedExExpress' }.freeze
DEFAULT_EXPRESS_CUTOFF =

Fallback cutoff for carriers with no pickup time on file.

'16:00:00'
EXPRESS_HOLD_WARN_MINUTES =

Minutes-to-cutoff thresholds for the two escalation levels.

120
EXPRESS_HOLD_URGENT_MINUTES =

Cutoff threshold (minutes) for the critical escalation level.

30

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.express_hold_candidatesActiveRecord::Relation<Order::ExpressHoldAlerting>

A relation of Order::ExpressHoldAlertings that are express hold candidates. Active Record Scope

Returns:

See Also:



42
# File 'app/models/order/express_hold_alerting.rb', line 42

scope :express_hold_candidates, -> { sales_orders.held.where(shipping_method: ShippingOption.express_names) }

Instance Method Details

#express_hold_cutoff_at(now = Time.current) ⇒ ActiveSupport::TimeWithZone?

Today's carrier pickup cutoff as a zoned Time, or nil when the warehouse is
closed today (weekend or company holiday) / no store.

Parameters:

  • now (Time) (defaults to: Time.current)

    reference time (defaults to now)

Returns:

  • (ActiveSupport::TimeWithZone, nil)


79
80
81
82
83
84
85
86
87
# File 'app/models/order/express_hold_alerting.rb', line 79

def express_hold_cutoff_at(now = Time.current)
  zone = store && ActiveSupport::TimeZone[store.time_zone_string]
  return nil unless zone

  local_today = now.in_time_zone(zone).to_date
  return nil unless warehouse_open_on?(local_today)

  zone.parse("#{local_today} #{express_pickup_cutoff}")
end

#express_hold_minutes_to_cutoff(now = Time.current) ⇒ Integer?

Whole minutes until today's warehouse cutoff in the store's local zone.
nil when the order has no store/zone or it's a weekend (nothing ships).

Parameters:

  • now (Time) (defaults to: Time.current)

    reference time (defaults to now)

Returns:

  • (Integer, nil)


68
69
70
71
72
73
# File 'app/models/order/express_hold_alerting.rb', line 68

def express_hold_minutes_to_cutoff(now = Time.current)
  cutoff = express_hold_cutoff_at(now)
  return nil unless cutoff

  ((cutoff - now) / 60.0).floor
end

#express_hold_urgency(now = Time.current) ⇒ Symbol

Escalation grade for right now: :none | :warning (orange) | :critical (red).
:warning inside the 2h window, :critical inside the final 30 minutes.

Parameters:

  • now (Time) (defaults to: Time.current)

    reference time (defaults to now)

Returns:

  • (Symbol)

    :none, :warning, or :critical



55
56
57
58
59
60
61
62
# File 'app/models/order/express_hold_alerting.rb', line 55

def express_hold_urgency(now = Time.current)
  return :none unless in_cr_hold? && is_sales_order? && express_shipping?

  mins = express_hold_minutes_to_cutoff(now)
  return :none if mins.nil? || mins <= 0 || mins > EXPRESS_HOLD_WARN_MINUTES

  mins <= EXPRESS_HOLD_URGENT_MINUTES ? :critical : :warning
end

#express_pickup_cutoffObject

Store-local "HH:MM:SS" pickup cutoff for this order's express carrier, or the
default when the carrier has no pickup time on file.



102
103
104
105
106
# File 'app/models/order/express_hold_alerting.rb', line 102

def express_pickup_cutoff
  carrier = ShippingOption.express_name_to_carrier[shipping_method]
  key = PICKUP_CARRIER_ALIASES.fetch(carrier, carrier)
  Store::CARRIER_PICKUP_TIMES.dig(store.name, key) || DEFAULT_EXPRESS_CUTOFF
end

#express_shipping?Boolean

True when the customer's preferred method is an express/expedited option
(days_commitment < 3.5 — the same threshold the app buckets as expedited/rush).

Returns:

  • (Boolean)


47
48
49
# File 'app/models/order/express_hold_alerting.rb', line 47

def express_shipping?
  shipping_method.present? && ShippingOption.express_names.include?(shipping_method)
end

#warehouse_open_on?(date) ⇒ Boolean

A shipping day for this store's warehouse: a weekday that isn't one of the
store company's holidays (Company#open_on_a_day? is true on a holiday). Only
reached for express + held orders, so the holiday lookup stays rare.

Parameters:

  • date (Date)

    date to check

Returns:

  • (Boolean)


94
95
96
97
98
# File 'app/models/order/express_hold_alerting.rb', line 94

def warehouse_open_on?(date)
  return false if date.on_weekend?

  !store.company&.open_on_a_day?(date)
end