Class: WarehousePackage
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- WarehousePackage
- Includes:
- Models::Auditable
- Defined in:
- app/models/warehouse_package.rb
Overview
== Schema Information
Table name: warehouse_packages
Database name: primary
id :integer not null, primary key
box_type :string(255)
description :string(255)
fake_stopgap :boolean
flat_rate_package_type :string
height :float
is_oversize :boolean
length :float
packagings_count :integer default(0), not null
sort_order :integer
supplier_name :string
supplier_part_number :string
volume :float
width :float
created_at :datetime
updated_at :datetime
creator_id :integer
store_id :integer
updater_id :integer
Indexes
idx_height_store_id (height,store_id)
index_warehouse_packages_on_flat_rate_package_type (flat_rate_package_type)
index_warehouse_packages_on_is_oversize (is_oversize)
index_warehouse_packages_on_store_id (store_id)
Foreign Keys
warehouse_packages_store_id_fk (store_id => stores.id) ON DELETE => cascade
Constant Summary collapse
- BOXTYPES =
Boxtypes.
%w[box pallet cylinder crate].freeze
Constants included from Models::Auditable
Models::Auditable::ALWAYS_IGNORED
Constants included from Schedulable
Schedulable::SIMPLE_FORM_OPTIONS
Instance Attribute Summary collapse
- #box_type ⇒ Object readonly
- #description ⇒ Object readonly
- #height ⇒ Object readonly
- #length ⇒ Object readonly
- #volume ⇒ Object readonly
- #width ⇒ Object readonly
Belongs to collapse
Methods included from Models::Auditable
Has many collapse
Class Method Summary collapse
-
.active ⇒ ActiveRecord::Relation<WarehousePackage>
A relation of WarehousePackages that are active.
- .box_type_options_for_select ⇒ Object
-
.by_store_id ⇒ ActiveRecord::Relation<WarehousePackage>
A relation of WarehousePackages that are by store id.
-
.check_if_dimensions_oversize(dimensions, container_type = Shipment.container_types.keys.first, carrier: nil) ⇒ Object
Check if dimensions would be oversize for a specific carrier.
-
.check_oversize?(pkg, carrier: nil) ⇒ Boolean
Check if a package is oversize for a specific carrier (or all carriers if nil).
-
.default_sort ⇒ ActiveRecord::Relation<WarehousePackage>
A relation of WarehousePackages that are default sort.
- .find_or_create_closest_package_within_tolerance(store_id, package_dims, tolerance = 0.1, short_desc = "", fake_stopgap = nil) ⇒ Object
- .flat_rate_package_types_for_select ⇒ Object
- .options_for_select(store_id) ⇒ Object
- .sort_order_options_for_select ⇒ Object
Instance Method Summary collapse
-
#can_contain?(warehouse_package, tolerance = 0.0) ⇒ Boolean
fraction so 0.1 = within 10%.
-
#can_contain_dimensions?(dimensions, tolerance = 0.0) ⇒ Boolean
fraction so 0.1 = within 10%.
-
#check_oversize?(carrier: nil) ⇒ Boolean
Check if this package is oversize for a specific carrier (or all carriers if nil).
- #container_type ⇒ Object
-
#fits_inside?(warehouse_package, tolerance = 0.0) ⇒ Boolean
fraction so 0.1 = within 10%.
-
#fits_inside_dimensions?(dimensions, tolerance = 0.0) ⇒ Boolean
fraction so 0.1 = within 10%.
- #girth ⇒ Object
- #length_plus_girth ⇒ Object
- #ok_to_destroy? ⇒ Boolean
- #set_dimensions_volume_and_box_type ⇒ Object
- #shipping_dimensions_to_package ⇒ Object
- #short_description ⇒ Object
Methods included from Models::Auditable
#all_skipped_columns, #audit_reference_data, #should_not_save_version, #stamp_record
Methods inherited from ApplicationRecord
ransackable_associations, ransackable_attributes, ransackable_scopes, ransortable_attributes, #to_relation
Methods included from Schedulable
Methods included from Models::AfterCommittable
Methods included from Models::EventPublishable
Instance Attribute Details
#box_type ⇒ Object (readonly)
48 |
# File 'app/models/warehouse_package.rb', line 48 validates :description, :store, :length, :width, :height, :volume, :box_type, presence: true |
#description ⇒ Object (readonly)
48 |
# File 'app/models/warehouse_package.rb', line 48 validates :description, :store, :length, :width, :height, :volume, :box_type, presence: true |
#height ⇒ Object (readonly)
48 |
# File 'app/models/warehouse_package.rb', line 48 validates :description, :store, :length, :width, :height, :volume, :box_type, presence: true |
#length ⇒ Object (readonly)
48 |
# File 'app/models/warehouse_package.rb', line 48 validates :description, :store, :length, :width, :height, :volume, :box_type, presence: true |
#volume ⇒ Object (readonly)
48 |
# File 'app/models/warehouse_package.rb', line 48 validates :description, :store, :length, :width, :height, :volume, :box_type, presence: true |
#width ⇒ Object (readonly)
48 |
# File 'app/models/warehouse_package.rb', line 48 validates :description, :store, :length, :width, :height, :volume, :box_type, presence: true |
Class Method Details
.active ⇒ ActiveRecord::Relation<WarehousePackage>
A relation of WarehousePackages that are active. Active Record Scope
45 |
# File 'app/models/warehouse_package.rb', line 45 scope :active, -> { where("warehouse_packages.fake_stopgap IS NOT TRUE") } |
.box_type_options_for_select ⇒ Object
136 137 138 |
# File 'app/models/warehouse_package.rb', line 136 def self. BOXTYPES.map { |p| [p.humanize, p] } end |
.by_store_id ⇒ ActiveRecord::Relation<WarehousePackage>
A relation of WarehousePackages that are by store id. Active Record Scope
44 |
# File 'app/models/warehouse_package.rb', line 44 scope :by_store_id, ->(store_id) { where(store_id: store_id).order(:sort_order, :volume) } |
.check_if_dimensions_oversize(dimensions, container_type = Shipment.container_types.keys.first, carrier: nil) ⇒ Object
Check if dimensions would be oversize for a specific carrier
93 94 95 96 97 |
# File 'app/models/warehouse_package.rb', line 93 def self.check_if_dimensions_oversize(dimensions, container_type = Shipment.container_types.keys.first, carrier: nil) dim_length, dim_width, dim_height = dimensions.sort.reverse pkg = Shipping::Container.new(length: dim_length, width: dim_width, height: dim_height, container_type:) check_oversize?(pkg, carrier:) end |
.check_oversize?(pkg, carrier: nil) ⇒ Boolean
Check if a package is oversize for a specific carrier (or all carriers if nil)
82 83 84 85 86 87 |
# File 'app/models/warehouse_package.rb', line 82 def self.check_oversize?(pkg, carrier: nil) r = Shipping::PackageAuditor.new carriers = carrier.present? ? [carrier] : nil r.process(pkg, carriers:) r.oversize_conditions? end |
.default_sort ⇒ ActiveRecord::Relation<WarehousePackage>
A relation of WarehousePackages that are default sort. Active Record Scope
46 |
# File 'app/models/warehouse_package.rb', line 46 scope :default_sort, -> { order(:sort_order, :volume) } |
.find_or_create_closest_package_within_tolerance(store_id, package_dims, tolerance = 0.1, short_desc = "", fake_stopgap = nil) ⇒ Object
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'app/models/warehouse_package.rb', line 148 def self.find_or_create_closest_package_within_tolerance(store_id, package_dims, tolerance = 0.1, short_desc = "", fake_stopgap = nil) sorted_dims = package_dims.sort_by { |d| d.to_f.ceil } # find matching warehouse package in this store (assume length is longest dimension then width, then height) warehouse_package = WarehousePackage.by_store_id(store_id).where(length: sorted_dims[2].to_f, width: sorted_dims[1].to_f, height: sorted_dims[0].to_f).first unless warehouse_package # if no exact match, find closest warehouse package by volume and see if its dimensions are within tolerance of 10% target_vol = sorted_dims[2] * sorted_dims[1] * sorted_dims[0].to_f WarehousePackage.by_store_id(store_id).sort_by { |whp| whp.volume.to_f }.each_with_index do |whp, _i| next unless ((whp.volume.to_f / target_vol) - 1.0).abs < tolerance # found one close if (((whp.length / sorted_dims[2]) - 1.0).abs < tolerance) && (((whp.width / sorted_dims[1]) - 1.0).abs < tolerance) && (((whp.height / sorted_dims[0]) - 1.0).abs < tolerance) warehouse_package = whp break end end end warehouse_package ||= WarehousePackage.create({ description: "#{sorted_dims[2].to_i}x#{sorted_dims[1].to_i}x#{sorted_dims[0].to_i} #{short_desc}", store_id: store_id, length: sorted_dims[2].to_f, width: sorted_dims[1].to_f, height: sorted_dims[0].to_f, fake_stopgap: fake_stopgap }) warehouse_package end |
.flat_rate_package_types_for_select ⇒ Object
61 62 63 |
# File 'app/models/warehouse_package.rb', line 61 def self.flat_rate_package_types_for_select %w[FlatRatePaddedEnvelope FlatRateEnvelope MediumFlatRateBox RegionalRateBoxA LargeFlatRateBox SmallFlatRateEnvelope] end |
.options_for_select(store_id) ⇒ Object
57 58 59 |
# File 'app/models/warehouse_package.rb', line 57 def self.(store_id) WarehousePackage.active.by_store_id(store_id).sort_by { |p| [(p.flat_rate_package_type.present? ? 0 : 1), p.volume, p.description] }.map { |p| ["#{p.description}#{', oversize' if p.is_oversize}", p.id] } end |
.sort_order_options_for_select ⇒ Object
140 141 142 143 144 145 146 |
# File 'app/models/warehouse_package.rb', line 140 def self. num_arr = [] WarehousePackage.count.times do |i| num_arr << i end [["Autosort By Volume", nil]].concat(num_arr.map { |n| [n.to_s, n] }) end |
Instance Method Details
#can_contain?(warehouse_package, tolerance = 0.0) ⇒ Boolean
fraction so 0.1 = within 10%
105 106 107 |
# File 'app/models/warehouse_package.rb', line 105 def can_contain?(warehouse_package, tolerance = 0.0) can_contain_dimensions?([warehouse_package.length, warehouse_package.width, warehouse_package.height], tolerance) end |
#can_contain_dimensions?(dimensions, tolerance = 0.0) ⇒ Boolean
fraction so 0.1 = within 10%
116 117 118 119 |
# File 'app/models/warehouse_package.rb', line 116 def can_contain_dimensions?(dimensions, tolerance = 0.0) dim_length, dim_width, dim_height = dimensions.sort_by(&:to_f).reverse (dim_length * (1.0 - tolerance) <= length) && (dim_width * (1.0 - tolerance) <= width) && (dim_height * (1.0 - tolerance) <= height) end |
#check_oversize?(carrier: nil) ⇒ Boolean
Check if this package is oversize for a specific carrier (or all carriers if nil)
75 76 77 |
# File 'app/models/warehouse_package.rb', line 75 def check_oversize?(carrier: nil) self.class.check_oversize?(shipping_dimensions_to_package, carrier:) end |
#container_type ⇒ Object
184 185 186 187 188 189 190 191 192 193 |
# File 'app/models/warehouse_package.rb', line 184 def container_type # This method basically maps to Shipment container types if box_type == 'pallet' Shipment.container_types.keys[1] # 'pallet' elsif box_type == 'crate' Shipment.container_types.keys[2] # 'crate' else Shipment.container_types.keys.first # 'carton' end end |
#fits_inside?(warehouse_package, tolerance = 0.0) ⇒ Boolean
fraction so 0.1 = within 10%
100 101 102 |
# File 'app/models/warehouse_package.rb', line 100 def fits_inside?(warehouse_package, tolerance = 0.0) fits_inside_dimensions?([warehouse_package.length, warehouse_package.width, warehouse_package.height], tolerance) end |
#fits_inside_dimensions?(dimensions, tolerance = 0.0) ⇒ Boolean
fraction so 0.1 = within 10%
110 111 112 113 |
# File 'app/models/warehouse_package.rb', line 110 def fits_inside_dimensions?(dimensions, tolerance = 0.0) dim_length, dim_width, dim_height = dimensions.sort.reverse (dim_length.to_f >= length * (1.0 - tolerance)) && (dim_width.to_f >= width * (1.0 - tolerance)) && (dim_height.to_f >= height * (1.0 - tolerance)) end |
#girth ⇒ Object
176 177 178 |
# File 'app/models/warehouse_package.rb', line 176 def girth 2.0 * (width + height) end |
#length_plus_girth ⇒ Object
180 181 182 |
# File 'app/models/warehouse_package.rb', line 180 def length_plus_girth (length + girth).ceil end |
#ok_to_destroy? ⇒ Boolean
65 66 67 |
# File 'app/models/warehouse_package.rb', line 65 def ok_to_destroy? packagings.blank? end |
#packagings ⇒ ActiveRecord::Relation<Packaging>
42 |
# File 'app/models/warehouse_package.rb', line 42 has_many :packagings, dependent: :destroy |
#set_dimensions_volume_and_box_type ⇒ Object
121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'app/models/warehouse_package.rb', line 121 def set_dimensions_volume_and_box_type # always set largest dimension to length, then width, then height dims = [length, width, height].sort.map(&:presence).reverse if dims.size == 3 # we have complete dimensions self.length, self.width, self.height = dims self.volume = length * width * height desc_prepend = "#{length.round}x#{width.round}x#{height.round}" self.description = "#{desc_prepend}, #{description}" unless description.to_s.index(desc_prepend) self.is_oversize = check_oversize? end # just assume box geometry for now self.box_type ||= "box" true end |
#shipping_dimensions_to_package ⇒ Object
69 70 71 |
# File 'app/models/warehouse_package.rb', line 69 def shipping_dimensions_to_package Shipping::Container.new(length: length, width: width, height: height, container_type: container_type) end |
#short_description ⇒ Object
170 171 172 173 174 |
# File 'app/models/warehouse_package.rb', line 170 def short_description d = [length, width, height].compact.map { |u| "#{u}\"" }.join(' x ') d << " [Oversize]" if is_oversize d end |