Class: ShippingCost

Inherits:
ApplicationRecord show all
Defined in:
app/models/shipping_cost.rb

Overview

== Schema Information

Table name: shipping_costs
Database name: primary

id :integer not null, primary key
cod :boolean default(FALSE)
cost :decimal(8, 2) default(0.0), not null
description_override :string
insured_value :decimal(8, 2)
is_free_ground_shipping :boolean default(FALSE)
rate_data :jsonb
saturday_delivery :boolean default(FALSE)
service_options_charges :decimal(8, 2) default(0.0), not null
signature_confirmation :boolean default(FALSE)
transportation_charges :decimal(8, 2) default(0.0), not null
created_at :datetime
updated_at :datetime
delivery_id :integer
shipping_account_number_id :integer
shipping_option_id :integer

Indexes

idx_delivery_id_shipping_option_id (delivery_id,shipping_option_id)
index_shipping_costs_on_delivery_id (delivery_id) USING hash
index_shipping_costs_on_shipping_option_id (shipping_option_id)

Foreign Keys

fk_rails_... (shipping_option_id => shipping_options.id) ON DELETE => cascade
shipping_costs_delivery_id_fk (delivery_id => deliveries.id) ON DELETE => cascade

Constant Summary

Constants included from Models::Schedulable

Models::Schedulable::SIMPLE_FORM_OPTIONS

Instance Attribute Summary collapse

Belongs to collapse

Has many collapse

Delegated Instance Attributes collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from ApplicationRecord

ransackable_associations, ransackable_attributes, ransackable_scopes, ransortable_attributes, #to_relation

Methods included from Models::Schedulable

config

Methods included from Models::AfterCommittable

#after_commit

Methods included from Models::EventPublishable

#publish_event

Instance Attribute Details

#costBigDecimal (readonly)

Returns:

  • (BigDecimal)

Validations:



55
# File 'app/models/shipping_cost.rb', line 55

validates :cost, numericality: true

Class Method Details

.amzbs_onlyActiveRecord::Relation<ShippingCost>

A relation of ShippingCosts that are amzbs only. Active Record Scope

Returns:

See Also:



99
# File 'app/models/shipping_cost.rb', line 99

scope :amzbs_only, -> { joins(:shipping_option).where(shipping_options: { carrier: 'AmazonSeller' }) }

.override_onlyActiveRecord::Relation<ShippingCost>

A relation of ShippingCosts that are override only. Active Record Scope

Returns:

See Also:



97
# File 'app/models/shipping_cost.rb', line 97

scope :override_only, -> { joins(:shipping_option).where(shipping_options: { name: 'override' }) }

.skip_3rd_partyActiveRecord::Relation<ShippingCost>

A relation of ShippingCosts that are skip 3rd party. Active Record Scope

Returns:

See Also:



93
# File 'app/models/shipping_cost.rb', line 93

scope :skip_3rd_party, -> { joins(:shipping_option).where.not(shipping_options: { is_third_party_only: true }) }

.skip_canadapostActiveRecord::Relation<ShippingCost>

A relation of ShippingCosts that are skip canadapost. Active Record Scope

Returns:

See Also:



95
# File 'app/models/shipping_cost.rb', line 95

scope :skip_canadapost, -> { joins(:shipping_option).where("shipping_options.carrier IS NULL OR shipping_options.carrier <> 'Canadapost'") }

.skip_freightActiveRecord::Relation<ShippingCost>

A relation of ShippingCosts that are skip freight. Active Record Scope

Returns:

See Also:



94
# File 'app/models/shipping_cost.rb', line 94

scope :skip_freight, -> { joins(:shipping_option).where("shipping_options.carrier IS NULL OR shipping_options.carrier <> 'UPSFreight'") }

.skip_overrideActiveRecord::Relation<ShippingCost>

A relation of ShippingCosts that are skip override. Active Record Scope

Returns:

See Also:



92
# File 'app/models/shipping_cost.rb', line 92

scope :skip_override, -> { joins(:shipping_option).where.not(shipping_options: { name: 'override' }) }

.supportedActiveRecord::Relation<ShippingCost>

A relation of ShippingCosts that are supported. Active Record Scope

Returns:

See Also:



96
# File 'app/models/shipping_cost.rb', line 96

scope :supported, -> { joins(:shipping_option).where.not(shipping_options: { is_third_party_only: true }).where.not(shipping_options: { carrier: nil }) }

.sww_onlyActiveRecord::Relation<ShippingCost>

A relation of ShippingCosts that are sww only. Active Record Scope

Returns:

See Also:



98
# File 'app/models/shipping_cost.rb', line 98

scope :sww_only, -> { joins(:shipping_option).where(shipping_options: { carrier: 'WalmartSeller' }) }

Instance Method Details

#amzbs_delivery_date_from_windowObject

Extracts a delivery date from the AMZBS delivery window when transit_days
fields are nil. Amazon's Shipping V2 API returns delivery windows for FedEx/UPS
PTP rates instead of transit days.



201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# File 'app/models/shipping_cost.rb', line 201

def amzbs_delivery_date_from_window
  return nil unless is_amzbs?

  window = rate_data&.dig('amz_delivery_window') || rate_data&.dig('raw', 'promise', 'deliveryWindow')
  # NOTE: `:'end'` quoted-symbol form rather than bare `:end` — the parser
  # parser-3.3.x used by Reek trips on a bare `:end`
  # symbol literal followed by a closing paren ("unexpected token tRPAREN").
  # Modern Ruby treats both forms identically; the quoted form is just
  # less ambiguous to the lookahead in legacy parser versions.
  end_date = window&.dig('end') || window&.dig(:end)
  return nil if end_date.blank?

  Time.zone.parse(end_date.to_s).to_date
rescue StandardError
  nil
end

#calculated_costObject

Customer-facing shipping charge for this option. Zero when the
carrier is billed to the customer's own (attached) account, so we
don't also invoice them for shipping; otherwise the quoted cost.



256
257
258
259
260
# File 'app/models/shipping_cost.rb', line 256

def calculated_cost
  return 0.0 if third_party_billed?

  cost
end

#carrier_estimated_delivery_dateObject

Returns the estimated delivery date from any carrier (SWW, AMZBS, or ShipEngine)



167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'app/models/shipping_cost.rb', line 167

def carrier_estimated_delivery_date
  return sww_estimated_delivery_date if is_sww? && sww_estimated_delivery.present?

  return estimated_delivery_date.to_date if estimated_delivery_date.present?

  transit_days = days_in_transit.presence || delivery_days.presence || sww_transit_days.presence || amz_transit_days.presence
  if transit_days.present?
    # transit_days counts BUSINESS days. Advance by working days — skipping
    # weekends AND the shipping company's holidays (via working_hours) — so a
    # Friday "+1" estimate doesn't land on a Saturday no carrier delivers.
    # ShipEngine rates already carry a real carrier date in
    # estimated_delivery_date (handled above); this is the fallback for rates
    # that only provide a transit-day count.
    company = delivery&.order&.company || Company.find_by(id: Company::USA)
    if company
      # Baseline ship date in the warehouse zone — prefer the order's
      # cutoff-aware `next_warehouse_ship_date` so an estimate quoted on
      # Saturday morning starts counting transit days from Monday, not
      # from "today". Falls back to today-in-warehouse-zone when there
      # is no order context (e.g. RMA rate quotes).
      baseline = delivery&.order&.next_warehouse_ship_date ||
                 Time.current.in_time_zone(company.working_hours_timezone).to_date
      return company.add_business_days(baseline, transit_days)
    end
  end

  amzbs_delivery_date_from_window
rescue StandardError
  nil
end

#days_commitmentvoid

This method returns an undefined value.



113
114
115
# File 'app/models/shipping_cost.rb', line 113

def days_commitment
  days_in_transit.presence || sww_transit_days.presence || amz_transit_days.presence || shipping_option.days_commitment
end

#deliveryDelivery?

Returns:



47
# File 'app/models/shipping_cost.rb', line 47

belongs_to :delivery, optional: true

#delivery_commitmentvoid

This method returns an undefined value.



118
119
120
121
122
123
124
125
126
127
128
# File 'app/models/shipping_cost.rb', line 118

def delivery_commitment
  if days_in_transit.present?
    "#{days_in_transit} business days."
  elsif sww_transit_days.present?
    "#{sww_transit_days} business days via Walmart."
  elsif amz_transit_days.present?
    "#{amz_transit_days} business days via Amazon."
  else
    shipping_option.delivery_commitment
  end
end

#descriptionvoid

This method returns an undefined value.



102
103
104
105
106
107
108
109
110
# File 'app/models/shipping_cost.rb', line 102

def description
  return description_override || shipping_option.description || 'Override' if is_override?

  desc = [description_override || shipping_option.description]
  desc << 'Saturday' if saturday_delivery
  desc << 'Signature Required' if signature_confirmation
  # desc << "Cust. Acct. #: #{shipping_account_number.account_number}" if shipping_account_number
  desc.join(', ')
end

#hide?Boolean

Returns:

  • (Boolean)


269
270
271
272
273
274
275
276
277
278
279
280
# File 'app/models/shipping_cost.rb', line 269

def hide?
  # Deactivated options (is_inactive) drop out of pickers, auto-select, and
  # www freight selection. Callers keep an already-*selected* hidden cost
  # visible so historical/in-flight deliveries still show what they're on.
  return true if shipping_option&.is_inactive?

  country_iso3_sym = shipping_option&.country_iso3&.to_sym
  Rails.logger.debug do
    "ShippingCost#hide? country_iso3_sym: #{country_iso3_sym}, shipping_option&.service_code: #{shipping_option&.service_code}, HIDE_SHIPPING_SERVICE_CODES[country_iso3_sym]: #{HIDE_SHIPPING_SERVICE_CODES[country_iso3_sym]}, HIDE_SHIPPING_SERVICE_CODES[country_iso3_sym]&.include?(shipping_option&.service_code): #{HIDE_SHIPPING_SERVICE_CODES[country_iso3_sym]&.include?(shipping_option&.service_code)}"
  end
  country_iso3_sym && HIDE_SHIPPING_SERVICE_CODES[country_iso3_sym]&.include?(shipping_option&.service_code)
end

#informationObject

Alias for Shipping_option#information

Returns:

  • (Object)

    Shipping_option#information

See Also:



218
# File 'app/models/shipping_cost.rb', line 218

delegate :information, to: :shipping_option

#is_amzbs?Boolean

Returns true if this is an Amazon Buy Shipping cost

Returns:

  • (Boolean)


136
137
138
# File 'app/models/shipping_cost.rb', line 136

def is_amzbs?
  shipping_option&.carrier == 'AmazonSeller' || amz_carrier_id.present?
end

#is_amzbs_ptp?Boolean

Returns true if this is an Amazon Buy Shipping pass-through (PTP) rate
using the seller's own linked carrier account (UPS, FedEx, USPS).
These rates provide A-to-Z Claims and OTDR protection.

Returns:

  • (Boolean)


152
153
154
# File 'app/models/shipping_cost.rb', line 152

def is_amzbs_ptp?
  is_amzbs? && amz_carrier_id.present? && amz_carrier_id != 'AMZN_US'
end

#is_beta?Boolean

Returns:

  • (Boolean)


226
227
228
# File 'app/models/shipping_cost.rb', line 226

def is_beta?
  shipping_option&.is_beta? || false
end

#is_curri?Boolean

Returns true if this is a Curri same-day courier cost. Drives the
admin-only selection lock in deliveries/_shipping_services during the
Curri beta (WyShipping::CURRI_ADMIN_ONLY) — deliberately carrier-scoped
rather than keyed on is_beta?, which 35 live ShipEngine LTL options also
carry and which ops select freely today.

Returns:

  • (Boolean)


145
146
147
# File 'app/models/shipping_cost.rb', line 145

def is_curri?
  shipping_option&.carrier == 'Curri'
end

#is_fedex_ca?Object

Alias for Shipping_option#is_fedex_ca?

Returns:

  • (Object)

    Shipping_option#is_fedex_ca?

See Also:



86
# File 'app/models/shipping_cost.rb', line 86

delegate :is_fedex_ca?, to: :shipping_option

#is_freightquote?Object

Alias for Shipping_option#is_freightquote?

Returns:

  • (Object)

    Shipping_option#is_freightquote?

See Also:



87
# File 'app/models/shipping_cost.rb', line 87

delegate :is_freightquote?, to: :shipping_option

#is_override?Object

Alias for Shipping_option#is_override?

Returns:

  • (Object)

    Shipping_option#is_override?

See Also:



84
# File 'app/models/shipping_cost.rb', line 84

delegate :is_override?, to: :shipping_option

#is_shipengine_ltl?Boolean

Returns:

  • (Boolean)


221
222
223
# File 'app/models/shipping_cost.rb', line 221

def is_shipengine_ltl?
  shipping_option&.is_shipengine_ltl? || false
end

#is_sww?Boolean

Returns true if this is a Ship with Walmart shipping cost

Returns:

  • (Boolean)


131
132
133
# File 'app/models/shipping_cost.rb', line 131

def is_sww?
  shipping_option&.carrier == 'WalmartSeller' || sww_carrier_id.present?
end

#is_third_party_only?Object

Alias for Shipping_option#is_third_party_only?

Returns:

  • (Object)

    Shipping_option#is_third_party_only?

See Also:



85
# File 'app/models/shipping_cost.rb', line 85

delegate :is_third_party_only?, to: :shipping_option

#line_itemsActiveRecord::Relation<LineItem>

Returns:



52
# File 'app/models/shipping_cost.rb', line 52

has_many :line_items, dependent: :destroy

#nameObject

Alias for Shipping_option#name

Returns:

  • (Object)

    Shipping_option#name

See Also:



88
# File 'app/models/shipping_cost.rb', line 88

delegate :name, to: :shipping_option

#service_codeObject

Alias for Shipping_option#service_code

Returns:

  • (Object)

    Shipping_option#service_code

See Also:



89
# File 'app/models/shipping_cost.rb', line 89

delegate :service_code, to: :shipping_option

#set_line_items_pricevoid

This method returns an undefined value.



263
264
265
266
# File 'app/models/shipping_cost.rb', line 263

def set_line_items_price
  Rails.logger.debug { "set_line_items_price: self.name: #{name}, self.calculated_cost: #{calculated_cost}, self.id: #{id}" }
  line_items.shipping_only.update_all(price: calculated_cost, discounted_price: calculated_cost)
end

#shipping_account_numberShippingAccountNumber?

Returns:



49
# File 'app/models/shipping_cost.rb', line 49

belongs_to :shipping_account_number, optional: true

#shipping_optionShippingOption?

Returns:



45
# File 'app/models/shipping_cost.rb', line 45

belongs_to :shipping_option, optional: true

#sww_estimated_delivery_dateObject

Returns the estimated delivery date for SWW rates



157
158
159
160
161
162
163
164
# File 'app/models/shipping_cost.rb', line 157

def sww_estimated_delivery_date
  return nil unless is_sww?
  return nil if sww_estimated_delivery.blank?

  sww_estimated_delivery.to_date
rescue StandardError
  nil
end

#third_party_billed?Boolean

Single source of truth, at this layer, for "is the carrier billed to
the customer's own account (so we do NOT invoice them for shipping)?"

The decision is whether a ShippingAccountNumber is ATTACHED to this
option — i.e. it was selected (auto, when the owner's
bill_shipping_to_customer is the default, OR manually from the
rate-shop dropdown even when it is not). Selecting the account IS the
instruction to bill it; the attached SAN carries the account number
to bill. The owner's flag only governs the default selection upstream
and is intentionally NOT re-consulted here.

The carrier label (WyShipping.classify_third_party_billing), the
customer's quoted shipping charge (#calculated_cost), the invoice
reconciliation (Delivery#adjusted_actual_shipping_cost), and the
on-screen account labels all gate on this one predicate, so they can
never drift apart (the drift — label on one axis, invoice on another
— is what leaked the cost to WarmlyYours: SO723955, SO725940).

Returns:

  • (Boolean)


249
250
251
# File 'app/models/shipping_cost.rb', line 249

def third_party_billed?
  .present?
end

#to_partial_pathObject

Partial lives under app/views/deliveries/, not the conventional
app/views/shipping_costs/. Override so render shipping_cost
resolves correctly from any controller, not just the delivery views
that currently render it via the verbose render partial: ... form.



40
41
42
# File 'app/models/shipping_cost.rb', line 40

def to_partial_path
  'deliveries/shipping_cost'
end