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 =
["box", "pallet", "cylinder", "crate"]
Constants included from Models::Auditable
Models::Auditable::ALWAYS_IGNORED
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::EventPublishable
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
132 133 134 |
# File 'app/models/warehouse_package.rb', line 132 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 ASC, volume ASC") } |
.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
91 92 93 94 95 |
# File 'app/models/warehouse_package.rb', line 91 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)
80 81 82 83 84 85 |
# File 'app/models/warehouse_package.rb', line 80 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 ASC, volume ASC") } |
.find_or_create_closest_package_within_tolerance(store_id, package_dims, tolerance = 0.1, short_desc = "", fake_stopgap = nil) ⇒ Object
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'app/models/warehouse_package.rb', line 144 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| if (whp.volume.to_f/target_vol - 1.0).abs < tolerance # found one close if (whp.length/sorted_dims[2] - 1.0).abs < tolerance and (whp.width/sorted_dims[1] - 1.0).abs < tolerance and (whp.height/sorted_dims[0] - 1.0).abs < tolerance warehouse_package = whp break end end end end unless warehouse_package 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}) end return warehouse_package end |
.flat_rate_package_types_for_select ⇒ Object
59 60 61 |
# File 'app/models/warehouse_package.rb', line 59 def self.flat_rate_package_types_for_select %w(FlatRatePaddedEnvelope FlatRateEnvelope MediumFlatRateBox RegionalRateBoxA LargeFlatRateBox SmallFlatRateEnvelope) end |
.options_for_select(store_id) ⇒ Object
55 56 57 |
# File 'app/models/warehouse_package.rb', line 55 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
136 137 138 139 140 141 142 |
# File 'app/models/warehouse_package.rb', line 136 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%
101 102 103 |
# File 'app/models/warehouse_package.rb', line 101 def can_contain?(warehouse_package, tolerance = 0.0) # fraction so 0.1 = within 10% return self.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%
111 112 113 114 115 |
# File 'app/models/warehouse_package.rb', line 111 def can_contain_dimensions?(dimensions, tolerance = 0.0) # fraction so 0.1 = within 10% dim_length, dim_width, dim_height = dimensions.sort_by{|d| d.to_f}.reverse contains = (dim_length*(1.0 - tolerance) <= self.length) && (dim_width*(1.0 - tolerance) <= self.width) && (dim_height*(1.0 - tolerance) <= self.height) return contains end |
#check_oversize?(carrier: nil) ⇒ Boolean
Check if this package is oversize for a specific carrier (or all carriers if nil)
73 74 75 |
# File 'app/models/warehouse_package.rb', line 73 def check_oversize?(carrier: nil) self.class.check_oversize?(shipping_dimensions_to_package, carrier:) end |
#container_type ⇒ Object
181 182 183 184 185 186 187 188 189 190 |
# File 'app/models/warehouse_package.rb', line 181 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%
97 98 99 |
# File 'app/models/warehouse_package.rb', line 97 def fits_inside?(warehouse_package, tolerance = 0.0) # fraction so 0.1 = within 10% return self.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%
105 106 107 108 109 |
# File 'app/models/warehouse_package.rb', line 105 def fits_inside_dimensions?(dimensions, tolerance = 0.0) # fraction so 0.1 = within 10% dim_length, dim_width, dim_height = dimensions.sort_by{|d| d}.reverse fits = (dim_length.to_f >= self.length*(1.0 - tolerance)) && (dim_width.to_f >= self.width*(1.0 - tolerance)) && (dim_height.to_f >= self.height*(1.0 - tolerance)) return fits end |
#girth ⇒ Object
173 174 175 |
# File 'app/models/warehouse_package.rb', line 173 def girth 2.0*(width+height) end |
#length_plus_girth ⇒ Object
177 178 179 |
# File 'app/models/warehouse_package.rb', line 177 def length_plus_girth (length + girth).ceil end |
#ok_to_destroy? ⇒ Boolean
63 64 65 |
# File 'app/models/warehouse_package.rb', line 63 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
117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'app/models/warehouse_package.rb', line 117 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+", "+self.description.to_s unless self.description.to_s.index(desc_prepend) self.is_oversize = check_oversize? end # just assume box geometry for now self.box_type ||= "box" return true end |
#shipping_dimensions_to_package ⇒ Object
67 68 69 |
# File 'app/models/warehouse_package.rb', line 67 def shipping_dimensions_to_package Shipping::Container.new(length: length, width: width, height: height, container_type: container_type) end |
#short_description ⇒ Object
167 168 169 170 171 |
# File 'app/models/warehouse_package.rb', line 167 def short_description d = [length, width, height].compact.map{|u| "#{u}\""}.join(' x ') d << " [Oversize]" if is_oversize d end |
#store ⇒ Store
40 |
# File 'app/models/warehouse_package.rb', line 40 belongs_to :store, optional: true |