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 Models::Schedulable
Models::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 Models::Schedulable
Methods included from Models::AfterCommittable
Methods included from Models::EventPublishable
Instance Attribute Details
#box_type ⇒ Object (readonly)
47 |
# File 'app/models/warehouse_package.rb', line 47 validates :description, :store, :length, :width, :height, :volume, :box_type, presence: true |
#description ⇒ Object (readonly)
47 |
# File 'app/models/warehouse_package.rb', line 47 validates :description, :store, :length, :width, :height, :volume, :box_type, presence: true |
#height ⇒ Object (readonly)
47 |
# File 'app/models/warehouse_package.rb', line 47 validates :description, :store, :length, :width, :height, :volume, :box_type, presence: true |
#length ⇒ Object (readonly)
47 |
# File 'app/models/warehouse_package.rb', line 47 validates :description, :store, :length, :width, :height, :volume, :box_type, presence: true |
#volume ⇒ Object (readonly)
47 |
# File 'app/models/warehouse_package.rb', line 47 validates :description, :store, :length, :width, :height, :volume, :box_type, presence: true |
#width ⇒ Object (readonly)
47 |
# File 'app/models/warehouse_package.rb', line 47 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
44 |
# File 'app/models/warehouse_package.rb', line 44 scope :active, -> { where("warehouse_packages.fake_stopgap IS NOT TRUE") } |
.box_type_options_for_select ⇒ Object
135 136 137 |
# File 'app/models/warehouse_package.rb', line 135 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
43 |
# File 'app/models/warehouse_package.rb', line 43 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
92 93 94 95 96 |
# File 'app/models/warehouse_package.rb', line 92 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)
81 82 83 84 85 86 |
# File 'app/models/warehouse_package.rb', line 81 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
45 |
# File 'app/models/warehouse_package.rb', line 45 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
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'app/models/warehouse_package.rb', line 147 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
60 61 62 |
# File 'app/models/warehouse_package.rb', line 60 def self.flat_rate_package_types_for_select %w[FlatRatePaddedEnvelope FlatRateEnvelope MediumFlatRateBox RegionalRateBoxA LargeFlatRateBox SmallFlatRateEnvelope] end |
.options_for_select(store_id) ⇒ Object
56 57 58 |
# File 'app/models/warehouse_package.rb', line 56 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
139 140 141 142 143 144 145 |
# File 'app/models/warehouse_package.rb', line 139 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%
104 105 106 |
# File 'app/models/warehouse_package.rb', line 104 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%
115 116 117 118 |
# File 'app/models/warehouse_package.rb', line 115 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)
74 75 76 |
# File 'app/models/warehouse_package.rb', line 74 def check_oversize?(carrier: nil) self.class.check_oversize?(shipping_dimensions_to_package, carrier:) end |
#container_type ⇒ Object
183 184 185 186 187 188 189 190 191 192 |
# File 'app/models/warehouse_package.rb', line 183 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%
99 100 101 |
# File 'app/models/warehouse_package.rb', line 99 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%
109 110 111 112 |
# File 'app/models/warehouse_package.rb', line 109 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
175 176 177 |
# File 'app/models/warehouse_package.rb', line 175 def girth 2.0 * (width + height) end |
#length_plus_girth ⇒ Object
179 180 181 |
# File 'app/models/warehouse_package.rb', line 179 def length_plus_girth (length + girth).ceil end |
#ok_to_destroy? ⇒ Boolean
64 65 66 |
# File 'app/models/warehouse_package.rb', line 64 def ok_to_destroy? packagings.blank? end |
#packagings ⇒ ActiveRecord::Relation<Packaging>
41 |
# File 'app/models/warehouse_package.rb', line 41 has_many :packagings, dependent: :destroy |
#set_dimensions_volume_and_box_type ⇒ Object
120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'app/models/warehouse_package.rb', line 120 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
68 69 70 |
# File 'app/models/warehouse_package.rb', line 68 def shipping_dimensions_to_package Shipping::Container.new(length: length, width: width, height: height, container_type: container_type) end |
#short_description ⇒ Object
169 170 171 172 173 |
# File 'app/models/warehouse_package.rb', line 169 def short_description d = [length, width, height].compact.map { |u| "#{u}\"" }.join(' x ') d << " [Oversize]" if is_oversize d end |