Class: LineItem
Overview
== Schema Information
Table name: line_items
Database name: primary
id :integer not null, primary key
children_count :integer
cm_category :string(255)
description :text
destination_state_code :string(255)
discounted_price :decimal(10, 2) default(0.0), not null
edi_line_number :integer
edi_reference :string
edi_unit_cost :decimal(10, 2)
ignore_tax :boolean
origin_state_code :string(255)
price :decimal(10, 2) not null
qty_shipped :integer
quantity :integer not null
redemption_code :string(255)
resource_type :string(255)
reviewed :boolean default(FALSE), not null
sequence :integer
tax_class :string(255)
tax_only :boolean
tax_rate :decimal(10, 6)
tax_total :decimal(10, 2)
tax_type :string
taxable_amount :decimal(12, 2)
total_cogs :decimal(10, 4)
unit_cogs :decimal(10, 4)
created_at :datetime
updated_at :datetime
backup_catalog_item_id :integer
business_unit_id :integer
catalog_item_id :integer
creator_id :integer
credit_order_line_item_id :integer
credit_rma_item_id :integer
delivery_id :integer
item_id :integer
ledger_company_account_id :integer
legacy_iq_room_line_item_option_group_id :integer
parent_id :integer
replacement_rma_item_id :integer
resource_id :integer
resource_tax_rate_id :integer
room_configuration_id :integer
serial_number_id :integer
shipping_cost_id :integer
store_item_id :integer
updater_id :integer
Indexes
idx_catalog_item_id_delivery_id (catalog_item_id,delivery_id)
idx_delivery_id_item_id_tax_class (delivery_id,item_id,tax_class)
idx_resource_type_resource_id_ci_id (resource_type,resource_id,catalog_item_id)
index_line_items_on_credit_rma_item_id (credit_rma_item_id) WHERE (credit_rma_item_id IS NOT NULL) USING hash
index_line_items_on_delivery_id (delivery_id) WHERE (delivery_id IS NOT NULL) USING hash
index_line_items_on_parent_id (parent_id) USING hash
index_line_items_on_replacement_rma_item_id (replacement_rma_item_id) WHERE (replacement_rma_item_id IS NOT NULL) USING hash
index_line_items_on_resource_type_and_item_id (resource_type,item_id)
index_line_items_on_room_configuration_id (room_configuration_id) WHERE (room_configuration_id IS NOT NULL) USING hash
index_line_items_on_shipping_cost_id (shipping_cost_id) WHERE (shipping_cost_id IS NOT NULL) USING hash
line_items_delivery_id_dup_idx (resource_type,resource_id,item_id,delivery_id) UNIQUE WHERE ((tax_class)::text = 'shp'::text)
line_items_resource_id_index (resource_id)
Foreign Keys
fk_rails_... (catalog_item_id => catalog_items.id)
line_items_catalog_item_id_fk (catalog_item_id => catalog_items.id)
line_items_delivery_id_fk (delivery_id => deliveries.id) ON DELETE => nullify
line_items_room_configuration_id_fk (room_configuration_id => room_configurations.id) ON DELETE => nullify
line_items_shipping_costs_id_fk (shipping_cost_id => shipping_costs.id) ON DELETE => cascade
Constant Summary
collapse
- LINE_ITEM_TAX_CLASSES =
{ g: 'GOODS', svc: 'SERVICE', shp: 'FREIGHT', none: 'NONE' }.freeze
- LINE_ITEM_TAX_CLASSES_SORT_ORDER =
Line item tax classes sort order.
%i[g svc shp none].freeze
Models::InventoryCommittable::STATES_WITH_NO_EXPIRATION
Models::Auditable::ALWAYS_IGNORED
Constants included
from Schedulable
Schedulable::SIMPLE_FORM_OPTIONS
Instance Attribute Summary collapse
#do_not_calculate_tax
#destination_state, #origin_state, #resource_tax_rate
#creator, #updater
#reserved_serial_numbers
Delegated Instance Attributes
collapse
Class Method Summary
collapse
Instance Method Summary
collapse
#ancestors, #ancestors_ids, #children_and_roots, #descendants, #descendants_ids, #ensure_non_recursive_lineage, #family_members, #generate_full_name, #generate_full_name_array, #lineage, #lineage_array, #lineage_simple, #root, #root_id, #self_ancestors_and_descendants, #self_ancestors_and_descendants_ids, #self_and_ancestors, #self_and_ancestors_ids, #self_and_children, #self_and_descendants, #self_and_descendants_ids, #self_and_siblings, #self_and_siblings_ids, #siblings, #siblings_ids
#calculate_tax, #has_tax?, #is_international?, #set_initial_tax_rate, #update_tax_rate
#can_be_committed?, #can_be_uncommitted?, #commit_line_items, #determine_commit_expiration_date, #has_committed_line_items?, #uncommit_line_items
#all_reserved_serial_numbers, #all_reserved_serial_numbers_available?, #auto_reserve_serial_numbers, #available_serial_numbers, #commit_reserved_serial_numbers, #fully_reserved?, #kit_components_requires_reservation?, #link_serial_numbers, #rejoin_serial_numbers, #require_reservation?, #reservable_item, #reservable_store_item, #serial_numbers, #show_serial_number_toggle?, #skip_reservation_screen?, #split_serial_numbers, #total_reserved_serial_numbers, #uncommit_reserved_serial_numbers, #unlink_serial_numbers, #update_serial_numbers_shipped_count
#all_skipped_columns, #audit_reference_data, #should_not_save_version, #stamp_record
ransackable_associations, ransackable_attributes, ransackable_scopes, ransortable_attributes, #to_relation
config
#after_commit
#publish_event
Instance Attribute Details
#business_unit_id ⇒ Object
131
|
# File 'app/models/line_item.rb', line 131
validates :ledger_company_account_id, :business_unit_id, presence: { if: proc { |li| (li.cm_category == 'Misc') && li.linked_to_standalone_credit_memo } }
|
#cm_category ⇒ Object
130
|
# File 'app/models/line_item.rb', line 130
validates :cm_category, presence: { if: proc { |li| li.linked_to_credit_memo || li.linked_to_invoice } }
|
#discounted_price ⇒ Object
138
|
# File 'app/models/line_item.rb', line 138
validates :discounted_price, numericality: { equal_to: 0, if: :tax_only?, message: 'must be equal to 0 for tax only lines' }
|
#force_catalog_validation ⇒ Object
Returns the value of attribute force_catalog_validation.
222
223
224
|
# File 'app/models/line_item.rb', line 222
def force_catalog_validation
@force_catalog_validation
end
|
#item_id ⇒ Object
133
|
# File 'app/models/line_item.rb', line 133
validates :item_id, presence: { if: proc { |li| (li.cm_category == 'Item') && li.linked_to_standalone_invoice } }
|
#item_name ⇒ Object
Returns the value of attribute item_name.
222
223
224
|
# File 'app/models/line_item.rb', line 222
def item_name
@item_name
end
|
#ledger_company_account_id ⇒ Object
131
|
# File 'app/models/line_item.rb', line 131
validates :ledger_company_account_id, :business_unit_id, presence: { if: proc { |li| (li.cm_category == 'Misc') && li.linked_to_standalone_credit_memo } }
|
#original_delivery_id ⇒ Object
Returns the value of attribute original_delivery_id.
222
223
224
|
# File 'app/models/line_item.rb', line 222
def original_delivery_id
@original_delivery_id
end
|
#qty_available ⇒ Object
Returns the value of attribute qty_available.
222
223
224
|
# File 'app/models/line_item.rb', line 222
def qty_available
@qty_available
end
|
#quantity ⇒ Object
136
|
# File 'app/models/line_item.rb', line 136
validates :quantity, presence: true
|
#sku_override ⇒ Object
Returns the value of attribute sku_override.
222
223
224
|
# File 'app/models/line_item.rb', line 222
def sku_override
@sku_override
end
|
#tax_class ⇒ Object
132
|
# File 'app/models/line_item.rb', line 132
validates :tax_class, :taxable_amount, presence: { if: :linked_to_standalone_credit_memo_or_invoice }
|
#taxable_amount ⇒ Object
132
|
# File 'app/models/line_item.rb', line 132
validates :tax_class, :taxable_amount, presence: { if: :linked_to_standalone_credit_memo_or_invoice }
|
#unit_cogs ⇒ Object
134
|
# File 'app/models/line_item.rb', line 134
validates :unit_cogs, presence: { if: proc { |li| (li.cm_category == 'Item') && li.linked_to_invoice } }
|
Class Method Details
.accessories ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are accessories. Active Record Scope
156
|
# File 'app/models/line_item.rb', line 156
scope :accessories, -> { joins(:item).merge(Item.accessories) }
|
.availability_hash(line_items) ⇒ Object
554
555
556
557
558
559
560
561
562
563
564
565
|
# File 'app/models/line_item.rb', line 554
def self.availability_hash(line_items)
result = {}
line_items.each do |li|
next unless li.catalog_item
cat_item_id = li.catalog_item.id
result[cat_item_id] ||= { 'available' => li.catalog_item.qty_available, 'ordered' => 0, 'in_stock' => li.catalog_item.qty_available.positive? }
result[cat_item_id]['ordered'] += li.quantity
result[cat_item_id]['in_stock'] = false if result[cat_item_id]['ordered'] > result[cat_item_id]['available']
end
result
end
|
.bstock ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are bstock. Active Record Scope
210
|
# File 'app/models/line_item.rb', line 210
scope :bstock, -> { joins(:item).where(items: { condition: 'refurbished' }) }
|
.by_product_category_path ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are by product category path. Active Record Scope
193
|
# File 'app/models/line_item.rb', line 193
scope :by_product_category_path, ->(slug_path) { joins(:item).merge(Item.by_product_category_path(slug_path)) }
|
.by_product_category_url ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are by product category url. Active Record Scope
189
|
# File 'app/models/line_item.rb', line 189
scope :by_product_category_url, ->(url) { joins(:item).merge(Item.by_product_category_url(url)) }
|
.by_product_line_path ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are by product line path. Active Record Scope
192
|
# File 'app/models/line_item.rb', line 192
scope :by_product_line_path, ->(slug_path) { joins(:item).merge(Item.by_product_line_path(slug_path)) }
|
.by_product_line_url ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are by product line url. Active Record Scope
190
|
# File 'app/models/line_item.rb', line 190
scope :by_product_line_url, ->(url) { joins(:item).merge(Item.by_product_line_url(url)) }
|
.cold_leads ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are cold leads. Active Record Scope
175
|
# File 'app/models/line_item.rb', line 175
scope :cold_leads, -> { joins(:item).merge(Item.cold_leads) }
|
.collect_product_lines(line_items) ⇒ Object
260
261
262
|
# File 'app/models/line_item.rb', line 260
def self.collect_product_lines(line_items)
line_items.filter_map { |li| li&.item&.product_lines }.flatten.uniq
end
|
.compare(source_line_items, target_line_items) ⇒ Object
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
|
# File 'app/models/line_item.rb', line 400
def self.compare(source_line_items, target_line_items)
report = {}
all_matched_line_ids = []
source_line_items.each do |source_line|
matched_lines_in_target = target_line_items.select { |target_line| target_line.catalog_item_id == source_line.catalog_item_id }
if matched_lines_in_target.empty?
report[source_line] = { status: :not_found, note: 'No matching lines found in target', matching_line_ids: [] }
else
matched_line_ids = matched_lines_in_target.map(&:id)
all_matched_line_ids += matched_line_ids
report[source_line] = { status: :ok, note: "Found similar line at line id #{matched_line_ids.join(',')}", matching_line_ids: matched_line_ids }
end
end
leftover_line_ids = target_line_items.reject { |tl| all_matched_line_ids.include? tl.id }.map(&:id)
report['extra_lines'] = { status: :extra, note: "Found extra lines id #{leftover_line_ids.join(',')}", matching_line_ids: leftover_line_ids } unless leftover_line_ids.empty?
report
end
|
.controls ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are controls. Active Record Scope
157
|
# File 'app/models/line_item.rb', line 157
scope :controls, -> { joins(:item).merge(Item.controls) }
|
.countertop_heaters ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are countertop heaters. Active Record Scope
188
|
# File 'app/models/line_item.rb', line 188
scope :countertop_heaters, -> { joins(:item).merge(Item.countertop_heaters) }
|
.custom_mats ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are custom mats. Active Record Scope
187
|
# File 'app/models/line_item.rb', line 187
scope :custom_mats, -> { joins(:item).merge(Item.custom_mats) }
|
.dropship ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are dropship. Active Record Scope
169
|
# File 'app/models/line_item.rb', line 169
scope :dropship, -> { joins(:item).merge(Item.dropships) }
|
.easystats ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are easystats. Active Record Scope
165
|
# File 'app/models/line_item.rb', line 165
scope :easystats, -> { joins(:item).merge(Item.easystats) }
|
.electrical_plan_controls ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are electrical plan controls. Active Record Scope
.floor_heating_elements ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are floor heating elements. Active Record Scope
154
|
# File 'app/models/line_item.rb', line 154
scope :floor_heating_elements, -> { joins(:item).merge(Item.floor_heating_elements) }
|
.goods ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are goods. Active Record Scope
178
|
# File 'app/models/line_item.rb', line 178
scope :goods, -> { where(tax_class: 'g') }
|
.group_by_category(line_items) ⇒ Object
331
332
333
334
335
336
337
338
339
340
|
# File 'app/models/line_item.rb', line 331
def self.group_by_category(line_items)
line_items = line_items.to_a.sort_by(&:sort_priority)
all_items = line_items.group_by { |li| li.item&.product_category_name || 'Not Categorized' }
all_items.sort_by do |_name, items|
category_id = items.first&.item&.product_category_id
ProductCategoryConstants.priority_for(category_id)
end
end
|
.has_floor_sensor ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are has floor sensor. Active Record Scope
181
|
# File 'app/models/line_item.rb', line 181
scope :has_floor_sensor, -> { joins(:item).merge(Item.has_floor_sensor) }
|
.heating_elements ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are heating elements. Active Record Scope
151
|
# File 'app/models/line_item.rb', line 151
scope :heating_elements, -> { joins(:item).merge(Item.heating_elements) }
|
.install_kits ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are install kits. Active Record Scope
184
|
# File 'app/models/line_item.rb', line 184
scope :install_kits, -> { joins(:item).merge(Item.install_kits) }
|
.insulations ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are insulations. Active Record Scope
185
|
# File 'app/models/line_item.rb', line 185
scope :insulations, -> { joins(:item).merge(Item.insulations) }
|
.integration_kits ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are integration kits. Active Record Scope
167
|
# File 'app/models/line_item.rb', line 167
scope :integration_kits, -> { joins(:item).merge(Item.integration_kits) }
|
.inventory_check(container) ⇒ Object
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
|
# File 'app/models/line_item.rb', line 268
def self.inventory_check(container)
lines = container.line_items.non_shipping
.includes(:item, :direct_store_item, :inventory_commits, { catalog_item: :store_item })
return :none unless lines.all?(&:is_fulfillable?)
from_store_id = container.respond_to?(:from_store_id) ? container.from_store_id : nil
uncommitted_demand = Hash.new(0)
store_item_by_id = {}
lines.each do |li|
next unless li.catalog_item_id
next if li.quantity.negative?
next if li.dropship? && !li.single_origin_or_warehouse_pickup?
next if li.unlimited_inventory?
committed_quantity = li.inventory_commits.sum(&:quantity)
next if committed_quantity >= li.quantity
uncommitted_qty = li.quantity - committed_quantity
si = if from_store_id
StoreItem.where(store_id: from_store_id, item_id: li.item_id, location: 'AVAILABLE').first
else
li.store_item
end
next unless si
uncommitted_demand[si.id] += uncommitted_qty
store_item_by_id[si.id] ||= si
end
store_item_by_id.each do |si_id, si|
return :none if si.qty_available < uncommitted_demand[si_id]
end
:ok
end
|
.kits ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are kits. Active Record Scope
204
|
# File 'app/models/line_item.rb', line 204
scope :kits, -> { joins(:item).merge(Item.kits) }
|
.membranes ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are membranes. Active Record Scope
186
|
# File 'app/models/line_item.rb', line 186
scope :membranes, -> { joins(:item).merge(Item.membranes) }
|
.must_be_shipped_insured ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are must be shipped insured. Active Record Scope
194
|
# File 'app/models/line_item.rb', line 194
scope :must_be_shipped_insured, -> { with_associations.where('store_items.must_be_shipped_insured IS TRUE') }
|
.no_tax_class ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are no tax class. Active Record Scope
180
|
# File 'app/models/line_item.rb', line 180
scope :no_tax_class, -> { where(tax_class: 'none') }
|
.non_dropship ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are non dropship. Active Record Scope
170
|
# File 'app/models/line_item.rb', line 170
scope :non_dropship, -> { joins(:item).merge(Item.non_dropships) }
|
.non_shipping ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are non shipping. Active Record Scope
176
|
# File 'app/models/line_item.rb', line 176
scope :non_shipping, -> { where(tax_class: %w[g svc none]) }
|
.oj_programmable_tstats ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are oj programmable tstats. Active Record Scope
163
|
# File 'app/models/line_item.rb', line 163
scope :oj_programmable_tstats, -> { joins(:item).merge(Item.oj_programmable_tstats) }
|
.oj_tstats ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are oj tstats. Active Record Scope
162
|
# File 'app/models/line_item.rb', line 162
scope :oj_tstats, -> { joins(:item).merge(Item.oj_tstats) }
|
.order_by_spec ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are order by spec. Active Record Scope
153
|
# File 'app/models/line_item.rb', line 153
scope :order_by_spec, ->(spec, datatype = 'varchar', direction = 'asc') { joins(:item).merge(Item.order_by_spec(spec, datatype, direction)) }
|
.power_modules ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are power modules. Active Record Scope
166
|
# File 'app/models/line_item.rb', line 166
scope :power_modules, -> { joins(:item).merge(Item.power_modules) }
|
.powers ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are powers. Active Record Scope
158
|
# File 'app/models/line_item.rb', line 158
scope :powers, -> { joins(:item).merge(Item.powers) }
|
.product_category_sorted ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are product category sorted. Active Record Scope
149
|
# File 'app/models/line_item.rb', line 149
scope :product_category_sorted, -> { includes(item: :product_category).joins(item: :product_category).order(ProductCategory[:priority]) }
|
.relay_panels ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are relay panels. Active Record Scope
172
|
# File 'app/models/line_item.rb', line 172
scope :relay_panels, -> { joins(:item).merge(Item.relay_panels) }
|
.reservable ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are reservable. Active Record Scope
182
|
# File 'app/models/line_item.rb', line 182
scope :reservable, -> { joins(:item).merge(Item.reservable) }
|
.rough_in_kits ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are rough in kits. Active Record Scope
183
|
# File 'app/models/line_item.rb', line 183
scope :rough_in_kits, -> { joins(:item).merge(Item.rough_in_kits) }
|
.sensors ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are sensors. Active Record Scope
168
|
# File 'app/models/line_item.rb', line 168
scope :sensors, -> { joins(:item).merge(Item.sensors) }
|
.services ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are services. Active Record Scope
179
|
# File 'app/models/line_item.rb', line 179
scope :services, -> { where(tax_class: 'svc') }
|
.shipping_only ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are shipping only. Active Record Scope
177
|
# File 'app/models/line_item.rb', line 177
scope :shipping_only, -> { where(tax_class: 'shp') }
|
.sku_and_aliases_search ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are sku and aliases search. Active Record Scope
211
|
# File 'app/models/line_item.rb', line 211
scope :sku_and_aliases_search, ->(sku) { joins(:item).merge(Item.sku_and_aliases_search(sku)) }
|
.smartfit_items ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are smartfit items. Active Record Scope
.smartfix_items ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are smartfix items. Active Record Scope
.smartguide_items ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are smartguide items. Active Record Scope
.smartinstall_items ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are smartinstall items. Active Record Scope
.smartpresets ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are smartpresets. Active Record Scope
174
|
# File 'app/models/line_item.rb', line 174
scope :smartpresets, -> { joins(:item).merge(Item.smartpresets) }
|
.smartservice_items ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are smartservice items. Active Record Scope
203
|
# File 'app/models/line_item.rb', line 203
scope :smartservice_items, -> { joins(:item).merge(Item.smart_services) }
|
.smartstats ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are smartstats. Active Record Scope
164
|
# File 'app/models/line_item.rb', line 164
scope :smartstats, -> { joins(:item).merge(Item.smartstats) }
|
.snow_melting_elements ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are snow melting elements. Active Record Scope
155
|
# File 'app/models/line_item.rb', line 155
scope :snow_melting_elements, -> { joins(:item).merge(Item.snow_melting_elements) }
|
.sort_for_plan ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are sort for plan. Active Record Scope
160
|
# File 'app/models/line_item.rb', line 160
scope :sort_for_plan, -> { order_by_spec('amps', 'decimal', 'asc') }
|
.tempzone_only ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are tempzone only. Active Record Scope
161
|
# File 'app/models/line_item.rb', line 161
scope :tempzone_only, -> { joins(:item).merge(Item.tempzones) }
|
.tempzone_or_environ_heating_elements ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are tempzone or environ heating elements. Active Record Scope
.thermostats ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are thermostats. Active Record Scope
171
|
# File 'app/models/line_item.rb', line 171
scope :thermostats, -> { joins(:item).merge(Item.thermostats) }
|
.total_of_collection(line_items) ⇒ Object
264
265
266
|
# File 'app/models/line_item.rb', line 264
def self.total_of_collection(line_items)
line_items.to_a.sum(&:total).round(2)
end
|
.underlayments ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are underlayments. Active Record Scope
173
|
# File 'app/models/line_item.rb', line 173
scope :underlayments, -> { joins(:item).merge(Item.underlayments) }
|
.with_associations ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are with associations. Active Record Scope
150
|
# File 'app/models/line_item.rb', line 150
scope :with_associations, -> { includes(:item, catalog_item: { store_item: :item }).references(:item, catalog_item: { store_item: :item }) }
|
.with_positive_qty ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are with positive qty. Active Record Scope
209
|
# File 'app/models/line_item.rb', line 209
scope :with_positive_qty, -> { where('quantity > 0') }
|
.with_product_specification ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are with product specification. Active Record Scope
152
|
# File 'app/models/line_item.rb', line 152
scope :with_product_specification, ->(token, value, grouping = nil) { joins(:item).merge(Item.with_product_specification(token, value, grouping)) }
|
.with_reserved_serial_numbers_count ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are with reserved serial numbers count. Active Record Scope
208
|
# File 'app/models/line_item.rb', line 208
scope :with_reserved_serial_numbers_count, -> { all.select_append('(select count(rsn.id) from reserved_serial_numbers rsn where rsn.line_item_id = line_items.id) as reserved_serial_numbers_count') }
|
.with_serial_numbers_count ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are with serial numbers count. Active Record Scope
207
|
# File 'app/models/line_item.rb', line 207
scope :with_serial_numbers_count, -> { all.select_append('(select count(sn.id) from serial_numbers sn where sn.line_item_id = line_items.id) as serial_numbers_count') }
|
.without_children ⇒ ActiveRecord::Relation<LineItem>
A relation of LineItems that are without children. Active Record Scope
205
|
# File 'app/models/line_item.rb', line 205
scope :without_children, -> { where(children_count: [nil, 0]) }
|
Instance Method Details
#all_quantities_allocated_to_shipments? ⇒ Boolean
429
430
431
|
# File 'app/models/line_item.rb', line 429
def all_quantities_allocated_to_shipments?
remaining_quantity_to_allocate_to_shipments == 0
end
|
#as_json ⇒ Object
859
860
861
|
# File 'app/models/line_item.rb', line 859
def as_json
super(methods: %i[name sku get_item_id])
end
|
115
|
# File 'app/models/line_item.rb', line 115
belongs_to :business_unit, optional: true
|
#calculated_tax_class ⇒ Object
469
470
471
472
473
|
# File 'app/models/line_item.rb', line 469
def calculated_tax_class
return tax_class if tax_class
item.nil? ? tax_class : item.tax_class
end
|
98
|
# File 'app/models/line_item.rb', line 98
belongs_to :catalog_item, inverse_of: :line_items, optional: true
|
#category_name ⇒ Object
Alias for Item#category_name
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
|
# File 'app/models/line_item.rb', line 226
delegate :is_oj_programmable_tstat?,
:is_smartstat?,
:is_cork?,
:is_relay_panel?,
:is_legacy_relay?,
:is_publication?,
:maximum_current,
:num_poles,
:category_name,
:image_path,
:image_url,
:thumbnail_url,
:is_floor_heating_product?,
:oversize?,
:ships_via_freight?,
:product_tax_code,
:is_snow_melting_product?,
:is_reviewable?,
:product_line_for_review,
to: :item,
allow_nil: true
|
#children_description(short = false, with_brackets = false) ⇒ Object
628
629
630
631
632
633
634
635
636
637
638
|
# File 'app/models/line_item.rb', line 628
def children_description(short = false, with_brackets = false)
contents = nil
if children.any?
contents = ''
contents += "The #{sku} is " unless short
contents += 'composed of '
contents += children.map { |child| "#{child.quantity} x #{child.item.sku}" }.to_sentence(last_word_connector: ' and ')
contents = "(#{contents})" if with_brackets
end
contents
end
|
#cogs_markup ⇒ Object
746
747
748
|
# File 'app/models/line_item.rb', line 746
def cogs_markup
1.1 end
|
#company_account_ref ⇒ Object
465
466
467
|
# File 'app/models/line_item.rb', line 465
def company_account_ref
ledger_company_account&.identifier
end
|
#copy_discounted_price ⇒ Object
928
929
930
|
# File 'app/models/line_item.rb', line 928
def copy_discounted_price
self.price = discounted_price
end
|
#coupon_amount ⇒ Object
425
426
427
|
# File 'app/models/line_item.rb', line 425
def coupon_amount
line_discounts.sum(:amount)
end
|
104
|
# File 'app/models/line_item.rb', line 104
belongs_to :credit_memo, -> { joins(:line_items).where(line_items: { resource_type: 'CreditMemo' }) }, foreign_key: :resource_id, optional: true
|
#credit_order_line_item ⇒ LineItem
112
|
# File 'app/models/line_item.rb', line 112
belongs_to :credit_order_line_item, class_name: 'LineItem', optional: true
|
#credit_percentage ⇒ Object
479
480
481
482
483
484
485
486
487
|
# File 'app/models/line_item.rb', line 479
def credit_percentage
return nil if credit_rma_item.nil? && credit_order_line_item.nil?
if credit_rma_item
credit_rma_item.credit_percentage
elsif credit_order_line_item.try(:credit_rma_item)
credit_order_line_item.credit_rma_item.credit_percentage
end
end
|
#credit_rma_item ⇒ RmaItem
110
|
# File 'app/models/line_item.rb', line 110
belongs_to :credit_rma_item, class_name: 'RmaItem', optional: true
|
#currency ⇒ Object
421
422
423
|
# File 'app/models/line_item.rb', line 421
def currency
resource.try(:currency)
end
|
#currency_symbol ⇒ Object
640
641
642
|
# File 'app/models/line_item.rb', line 640
def currency_symbol
(resource || delivery).currency_symbol
end
|
#current_line_cogs ⇒ Object
731
732
733
734
735
736
737
738
739
740
741
742
743
744
|
# File 'app/models/line_item.rb', line 731
def current_line_cogs
uc = unit_cogs if unit_cogs && unit_cogs > 0
uc ||= catalog_item.try(:unit_cogs)
uc ||= begin
SupplierItem.order(:id).reverse_order.find_by(item_id:).current_price.unit_cost * cogs_markup
rescue StandardError
nil
end
return if uc.nil?
uc * quantity
end
|
#current_line_profit ⇒ Object
758
759
760
761
762
763
764
|
# File 'app/models/line_item.rb', line 758
def current_line_profit
if estimated_line_cost && (dt = discounted_total)
dt - estimated_line_cost
else
BigDecimal('0.00')
end
end
|
#current_line_profit_margin ⇒ Object
To find the margin, divide gross profit by the revenue.
776
777
778
779
780
781
782
783
|
# File 'app/models/line_item.rb', line 776
def current_line_profit_margin
gross_profit = current_line_profit
revenue = discounted_total
return 0.0 if gross_profit == 0
return -1.0 if revenue == 0
gross_profit / revenue
end
|
#current_line_profit_markup ⇒ Object
To write the markup as a percentage, divide the gross profit by the COGS.
767
768
769
770
771
772
773
|
# File 'app/models/line_item.rb', line 767
def current_line_profit_markup
cogs = estimated_line_cost
gross_profit = current_line_profit
return 0.0 if cogs == 0
gross_profit / cogs
end
|
#deep_dup ⇒ Object
87
88
89
|
# File 'app/models/line_item.rb', line 87
def deep_dup
deep_clone(include: %i[serial_numbers line_discounts])
end
|
107
|
# File 'app/models/line_item.rb', line 107
belongs_to :delivery, inverse_of: :line_items, optional: true
|
#detail_url ⇒ Object
918
919
920
921
922
923
924
|
# File 'app/models/line_item.rb', line 918
def detail_url
i = item
return unless i&.canonical_path
locale = resource.try(:store_id) == 2 ? 'en-CA' : 'en-US'
"https://#{WEB_HOSTNAME}#{i.canonical_url(locale: locale)}"
end
|
#direct_store_item ⇒ StoreItem
106
|
# File 'app/models/line_item.rb', line 106
belongs_to :direct_store_item, class_name: 'StoreItem', foreign_key: :store_item_id, optional: true
|
#discounted_total ⇒ Object
644
645
646
647
648
649
650
651
652
653
|
# File 'app/models/line_item.rb', line 644
def discounted_total
price_total + line_discounts.sum(&:amount)
end
|
#discounts ⇒ ActiveRecord::Relation<Discount>
126
|
# File 'app/models/line_item.rb', line 126
has_many :discounts, through: :line_discounts
|
#discounts_total ⇒ Object
661
662
663
|
# File 'app/models/line_item.rb', line 661
def discounts_total
price_total - discounted_total
end
|
#dropship? ⇒ Boolean
533
534
535
|
# File 'app/models/line_item.rb', line 533
def dropship?
item.present? && item.dropship?
end
|
#effective_discount ⇒ Object
687
688
689
690
|
# File 'app/models/line_item.rb', line 687
def effective_discount
d = price_total - discounted_total
price_total.positive? && d.positive? ? ((d * 100) / price_total).to_i : 0
end
|
#estimated_line_cost ⇒ Object
750
751
752
753
754
755
756
|
# File 'app/models/line_item.rb', line 750
def estimated_line_cost
if is_shipping?
price
else
current_line_cogs
end
end
|
#fulfillment_origin_address ⇒ Object
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
|
# File 'app/models/line_item.rb', line 821
def fulfillment_origin_address
if is_service?
if is_remote_service?
res = resource.store.warehouse_service_address
else
res = delivery&.destination_address
res ||= resource&.shipping_address
end
elsif is_shipping?
res = delivery.origin_address if delivery
res ||= resource.store.warehouse_address
else
res = store_item&.store&.warehouse_address
end
if item.dropship
res = item.supplier_item.supplier.shipping_address
end
res
end
|
#fulfillment_origin_address_id ⇒ Object
817
818
819
|
# File 'app/models/line_item.rb', line 817
def fulfillment_origin_address_id
fulfillment_origin_address&.id
end
|
#get_item_id ⇒ Object
529
530
531
|
# File 'app/models/line_item.rb', line 529
def get_item_id
item&.id
end
|
#handling_charge ⇒ Object
794
795
796
|
# File 'app/models/line_item.rb', line 794
def handling_charge
catalog_item&.store_item&.handling_charge
end
|
#has_children? ⇒ Boolean
624
625
626
|
# File 'app/models/line_item.rb', line 624
def has_children?
children_count.present? && (children_count > 0)
end
|
#has_linked_unvoided_rma_item? ⇒ Boolean
461
462
463
|
# File 'app/models/line_item.rb', line 461
def has_linked_unvoided_rma_item?
credit_rma_item.present? && !credit_rma_item.voided?
end
|
#image_path ⇒ Object
Alias for Item#image_path
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
|
# File 'app/models/line_item.rb', line 226
delegate :is_oj_programmable_tstat?,
:is_smartstat?,
:is_cork?,
:is_relay_panel?,
:is_legacy_relay?,
:is_publication?,
:maximum_current,
:num_poles,
:category_name,
:image_path,
:image_url,
:thumbnail_url,
:is_floor_heating_product?,
:oversize?,
:ships_via_freight?,
:product_tax_code,
:is_snow_melting_product?,
:is_reviewable?,
:product_line_for_review,
to: :item,
allow_nil: true
|
#image_url ⇒ Object
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
|
# File 'app/models/line_item.rb', line 226
delegate :is_oj_programmable_tstat?,
:is_smartstat?,
:is_cork?,
:is_relay_panel?,
:is_legacy_relay?,
:is_publication?,
:maximum_current,
:num_poles,
:category_name,
:image_path,
:image_url,
:thumbnail_url,
:is_floor_heating_product?,
:oversize?,
:ships_via_freight?,
:product_tax_code,
:is_snow_melting_product?,
:is_reviewable?,
:product_line_for_review,
to: :item,
allow_nil: true
|
#in_stock? ⇒ Boolean
567
568
569
570
571
572
573
|
# File 'app/models/line_item.rb', line 567
def in_stock?
if catalog_item catalog_item.qty_available >= quantity
else
true
end
end
|
#inventory_commits ⇒ ActiveRecord::Relation<InventoryCommit>
127
|
# File 'app/models/line_item.rb', line 127
has_many :inventory_commits, dependent: :destroy
|
103
|
# File 'app/models/line_item.rb', line 103
belongs_to :invoice, -> { joins(:line_items).where(line_items: { resource_type: 'Invoice' }) }, foreign_key: :resource_id, optional: true
|
#is_cork? ⇒ Object
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
|
# File 'app/models/line_item.rb', line 226
delegate :is_oj_programmable_tstat?,
:is_smartstat?,
:is_cork?,
:is_relay_panel?,
:is_legacy_relay?,
:is_publication?,
:maximum_current,
:num_poles,
:category_name,
:image_path,
:image_url,
:thumbnail_url,
:is_floor_heating_product?,
:oversize?,
:ships_via_freight?,
:product_tax_code,
:is_snow_melting_product?,
:is_reviewable?,
:product_line_for_review,
to: :item,
allow_nil: true
|
#is_discounted? ⇒ Boolean
692
693
694
|
# File 'app/models/line_item.rb', line 692
def is_discounted?
effective_discount > 0
end
|
#is_floor_heating_product? ⇒ Object
Alias for Item#is_floor_heating_product?
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
|
# File 'app/models/line_item.rb', line 226
delegate :is_oj_programmable_tstat?,
:is_smartstat?,
:is_cork?,
:is_relay_panel?,
:is_legacy_relay?,
:is_publication?,
:maximum_current,
:num_poles,
:category_name,
:image_path,
:image_url,
:thumbnail_url,
:is_floor_heating_product?,
:oversize?,
:ships_via_freight?,
:product_tax_code,
:is_snow_melting_product?,
:is_reviewable?,
:product_line_for_review,
to: :item,
allow_nil: true
|
#is_fulfillable? ⇒ Boolean
616
617
618
|
# File 'app/models/line_item.rb', line 616
def is_fulfillable?
%i[ok low na].include?(stock_status)
end
|
#is_goods? ⇒ Boolean
863
864
865
|
# File 'app/models/line_item.rb', line 863
def is_goods?
tax_class.present? ? tax_class == 'g' : item&.is_goods?&.to_b
end
|
#is_kit? ⇒ Boolean
451
452
453
|
# File 'app/models/line_item.rb', line 451
def is_kit?
item&.is_kit?
end
|
#is_legacy_relay? ⇒ Object
Alias for Item#is_legacy_relay?
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
|
# File 'app/models/line_item.rb', line 226
delegate :is_oj_programmable_tstat?,
:is_smartstat?,
:is_cork?,
:is_relay_panel?,
:is_legacy_relay?,
:is_publication?,
:maximum_current,
:num_poles,
:category_name,
:image_path,
:image_url,
:thumbnail_url,
:is_floor_heating_product?,
:oversize?,
:ships_via_freight?,
:product_tax_code,
:is_snow_melting_product?,
:is_reviewable?,
:product_line_for_review,
to: :item,
allow_nil: true
|
#is_linked_to_same_resource_as_delivery ⇒ Object
445
446
447
448
449
|
# File 'app/models/line_item.rb', line 445
def is_linked_to_same_resource_as_delivery
return unless delivery&.resource && resource&.persisted? && delivery&.resource&.persisted? && resource.id != delivery.resource.id
errors.add(:resource_id, 'is not the same as Delivery resource')
end
|
#is_not_a_kit ⇒ Object
455
456
457
458
459
|
# File 'app/models/line_item.rb', line 455
def is_not_a_kit
return unless is_kit?
errors.add(:catalog_item_id, "#{sku} is a kit. Kits are not permitted on store transfers, please add kit components instead")
end
|
#is_oj_programmable_tstat? ⇒ Object
Alias for Item#is_oj_programmable_tstat?
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
|
# File 'app/models/line_item.rb', line 226
delegate :is_oj_programmable_tstat?,
:is_smartstat?,
:is_cork?,
:is_relay_panel?,
:is_legacy_relay?,
:is_publication?,
:maximum_current,
:num_poles,
:category_name,
:image_path,
:image_url,
:thumbnail_url,
:is_floor_heating_product?,
:oversize?,
:ships_via_freight?,
:product_tax_code,
:is_snow_melting_product?,
:is_reviewable?,
:product_line_for_review,
to: :item,
allow_nil: true
|
#is_onsite_service? ⇒ Boolean
879
880
881
|
# File 'app/models/line_item.rb', line 879
def is_onsite_service?
is_service? && item.sku.include?('ONSITE')
end
|
#is_publication? ⇒ Object
Alias for Item#is_publication?
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
|
# File 'app/models/line_item.rb', line 226
delegate :is_oj_programmable_tstat?,
:is_smartstat?,
:is_cork?,
:is_relay_panel?,
:is_legacy_relay?,
:is_publication?,
:maximum_current,
:num_poles,
:category_name,
:image_path,
:image_url,
:thumbnail_url,
:is_floor_heating_product?,
:oversize?,
:ships_via_freight?,
:product_tax_code,
:is_snow_melting_product?,
:is_reviewable?,
:product_line_for_review,
to: :item,
allow_nil: true
|
899
900
901
902
903
904
905
906
907
908
|
# File 'app/models/line_item.rb', line 899
def is_related_smart_service?(sku)
res = false
if sku.index('_FIXRATE') && is_smartinstall_service? && item.sku.index('_PER_SQFT') && item.sku.split('_PER_SQFT').first == sku.split('_FIXRATE')
res = true
elsif sku.index('_PER_SQFT') && is_smartinstall_service? && item.sku.index('_FIXRATE') && item.sku.split('_FIXRATE').first == sku.split('_PER_SQFT')
res = true
end
res
end
|
#is_relay_panel? ⇒ Object
Alias for Item#is_relay_panel?
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
|
# File 'app/models/line_item.rb', line 226
delegate :is_oj_programmable_tstat?,
:is_smartstat?,
:is_cork?,
:is_relay_panel?,
:is_legacy_relay?,
:is_publication?,
:maximum_current,
:num_poles,
:category_name,
:image_path,
:image_url,
:thumbnail_url,
:is_floor_heating_product?,
:oversize?,
:ships_via_freight?,
:product_tax_code,
:is_snow_melting_product?,
:is_reviewable?,
:product_line_for_review,
to: :item,
allow_nil: true
|
#is_remote_service? ⇒ Boolean
875
876
877
|
# File 'app/models/line_item.rb', line 875
def is_remote_service?
(is_service? && item.sku.include?('REMOTE')) || (is_service? && resource.line_items.any? { |a| a.sku.include?('REMOTE') })
end
|
#is_reviewable? ⇒ Object
Alias for Item#is_reviewable?
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
|
# File 'app/models/line_item.rb', line 226
delegate :is_oj_programmable_tstat?,
:is_smartstat?,
:is_cork?,
:is_relay_panel?,
:is_legacy_relay?,
:is_publication?,
:maximum_current,
:num_poles,
:category_name,
:image_path,
:image_url,
:thumbnail_url,
:is_floor_heating_product?,
:oversize?,
:ships_via_freight?,
:product_tax_code,
:is_snow_melting_product?,
:is_reviewable?,
:product_line_for_review,
to: :item,
allow_nil: true
|
#is_service? ⇒ Boolean
871
872
873
|
# File 'app/models/line_item.rb', line 871
def is_service?
tax_class.present? ? tax_class == 'svc' : item&.is_service?&.to_b
end
|
#is_shipping? ⇒ Boolean
887
888
889
|
# File 'app/models/line_item.rb', line 887
def is_shipping?
tax_class.present? ? tax_class == 'shp' : item&.is_shipping?&.to_b
end
|
#is_smart_service? ⇒ Boolean
895
896
897
|
# File 'app/models/line_item.rb', line 895
def is_smart_service?
item&.pl_descendant_of_path?(LtreePaths::PL_SERVICES)
end
|
#is_smartinstall_service? ⇒ Boolean
#is_smartstat? ⇒ Object
Alias for Item#is_smartstat?
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
|
# File 'app/models/line_item.rb', line 226
delegate :is_oj_programmable_tstat?,
:is_smartstat?,
:is_cork?,
:is_relay_panel?,
:is_legacy_relay?,
:is_publication?,
:maximum_current,
:num_poles,
:category_name,
:image_path,
:image_url,
:thumbnail_url,
:is_floor_heating_product?,
:oversize?,
:ships_via_freight?,
:product_tax_code,
:is_snow_melting_product?,
:is_reviewable?,
:product_line_for_review,
to: :item,
allow_nil: true
|
#is_snow_melting_product? ⇒ Object
Alias for Item#is_snow_melting_product?
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
|
# File 'app/models/line_item.rb', line 226
delegate :is_oj_programmable_tstat?,
:is_smartstat?,
:is_cork?,
:is_relay_panel?,
:is_legacy_relay?,
:is_publication?,
:maximum_current,
:num_poles,
:category_name,
:image_path,
:image_url,
:thumbnail_url,
:is_floor_heating_product?,
:oversize?,
:ships_via_freight?,
:product_tax_code,
:is_snow_melting_product?,
:is_reviewable?,
:product_line_for_review,
to: :item,
allow_nil: true
|
#is_spare_parts? ⇒ Boolean
867
868
869
|
# File 'app/models/line_item.rb', line 867
def is_spare_parts?
item&.is_spare_parts?&.to_b
end
|
#is_tax_unclassed? ⇒ Boolean
883
884
885
|
# File 'app/models/line_item.rb', line 883
def is_tax_unclassed?
tax_class == 'none'
end
|
113
|
# File 'app/models/line_item.rb', line 113
belongs_to :item, optional: true
|
#item_in_stock_in_store ⇒ Object
932
933
934
935
936
937
938
939
940
941
|
# File 'app/models/line_item.rb', line 932
def item_in_stock_in_store
return unless get_item_id && resource&.store_id
store_item = StoreItem.available.where(item_id: get_item_id, store_id: resource.store_id).first
if store_item.nil?
errors.add(:item_id, 'is not available in selected store')
elsif quantity && (store_item.qty_available < quantity)
errors.add(:quantity, 'is more than quantity available in selected store')
end
end
|
114
|
# File 'app/models/line_item.rb', line 114
belongs_to :ledger_company_account, optional: true
|
#ledger_description ⇒ Object
521
522
523
524
525
526
527
|
# File 'app/models/line_item.rb', line 521
def ledger_description
if cm_category.nil? || ((cm_category == 'Item') && sku.present?)
sku
else
"#{cm_category} #{description}"
end
end
|
#line_discounts ⇒ ActiveRecord::Relation<LineDiscount>
125
|
# File 'app/models/line_item.rb', line 125
has_many :line_discounts, dependent: :destroy, inverse_of: :line_item, autosave: true
|
#line_locked? ⇒ Boolean
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
|
# File 'app/models/line_item.rb', line 537
def line_locked?
return true if resource.respond_to?(:editing_locked?) && resource.editing_locked?
return false unless item.plan_sensitive?
return false unless room_configuration
return false if resource.respond_to?(:room_configuration_ids) && resource.room_configuration_ids.exclude?(room_configuration.id)
room_configuration.editing_locked?
end
|
#line_total_with_tax ⇒ Object
655
656
657
658
659
|
# File 'app/models/line_item.rb', line 655
def line_total_with_tax
discounted_total + (tax_total || 0.0)
rescue StandardError
0
end
|
#linear_ft_total ⇒ Object
683
684
685
|
# File 'app/models/line_item.rb', line 683
def linear_ft_total
quantity * (item.length.to_f / 12)
end
|
#linked_to_credit_memo ⇒ Object
475
476
477
|
# File 'app/models/line_item.rb', line 475
def linked_to_credit_memo
resource_type == 'CreditMemo'
end
|
#linked_to_invoice ⇒ Object
489
490
491
|
# File 'app/models/line_item.rb', line 489
def linked_to_invoice
resource_type == 'Invoice'
end
|
#linked_to_st_order ⇒ Object
505
506
507
|
# File 'app/models/line_item.rb', line 505
def linked_to_st_order
(resource_type == 'Order') && (resource.try(:order_type) == 'ST')
end
|
#linked_to_standalone_credit_memo ⇒ Object
493
494
495
|
# File 'app/models/line_item.rb', line 493
def linked_to_standalone_credit_memo
(resource_type == 'CreditMemo') && (resource.try(:category) == 'standalone')
end
|
#linked_to_standalone_credit_memo_or_invoice ⇒ Object
501
502
503
|
# File 'app/models/line_item.rb', line 501
def linked_to_standalone_credit_memo_or_invoice
linked_to_standalone_credit_memo || linked_to_standalone_invoice
end
|
#linked_to_standalone_invoice ⇒ Object
497
498
499
|
# File 'app/models/line_item.rb', line 497
def linked_to_standalone_invoice
(resource_type == 'Invoice') && [Invoice::MI].include?(resource.try(:invoice_type))
end
|
#max_discount ⇒ Object
Determine the max discount in effect for this line item
Only for quote or order
344
345
346
347
348
349
350
351
|
# File 'app/models/line_item.rb', line 344
def max_discount
md = nil
if (discountable_resource = quote || order)
md = discountable_resource.max_discount_override
end
md = catalog_item.max_discount if md.nil? && catalog_item
md
end
|
#maximum_current ⇒ Object
Alias for Item#maximum_current
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
|
# File 'app/models/line_item.rb', line 226
delegate :is_oj_programmable_tstat?,
:is_smartstat?,
:is_cork?,
:is_relay_panel?,
:is_legacy_relay?,
:is_publication?,
:maximum_current,
:num_poles,
:category_name,
:image_path,
:image_url,
:thumbnail_url,
:is_floor_heating_product?,
:oversize?,
:ships_via_freight?,
:product_tax_code,
:is_snow_melting_product?,
:is_reviewable?,
:product_line_for_review,
to: :item,
allow_nil: true
|
#msrp ⇒ Object
Alias for Catalog_item#msrp
248
249
250
251
252
253
254
|
# File 'app/models/line_item.rb', line 248
delegate :price_with_vat,
:sale_price_with_vat,
:msrp,
:msrp_with_vat,
:root_catalog_item,
to: :catalog_item,
allow_nil: true
|
#msrp_total ⇒ Object
671
672
673
674
675
676
677
|
# File 'app/models/line_item.rb', line 671
def msrp_total
return 0.0 if parent_id.present?
(msrp || 0.0) * quantity
rescue StandardError
0.0
end
|
#msrp_with_vat ⇒ Object
Alias for Catalog_item#msrp_with_vat
248
249
250
251
252
253
254
|
# File 'app/models/line_item.rb', line 248
delegate :price_with_vat,
:sale_price_with_vat,
:msrp,
:msrp_with_vat,
:root_catalog_item,
to: :catalog_item,
allow_nil: true
|
#name ⇒ Object
517
518
519
|
# File 'app/models/line_item.rb', line 517
def name
description || item.try(:name) || item_name
end
|
#num_poles ⇒ Object
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
|
# File 'app/models/line_item.rb', line 226
delegate :is_oj_programmable_tstat?,
:is_smartstat?,
:is_cork?,
:is_relay_panel?,
:is_legacy_relay?,
:is_publication?,
:maximum_current,
:num_poles,
:category_name,
:image_path,
:image_url,
:thumbnail_url,
:is_floor_heating_product?,
:oversize?,
:ships_via_freight?,
:product_tax_code,
:is_snow_melting_product?,
:is_reviewable?,
:product_line_for_review,
to: :item,
allow_nil: true
|
The following makes join easier
101
|
# File 'app/models/line_item.rb', line 101
belongs_to :order, -> { joins(:line_items).where(line_items: { resource_type: 'Order' }) }, foreign_key: :resource_id, optional: true
|
#oversize? ⇒ Object
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
|
# File 'app/models/line_item.rb', line 226
delegate :is_oj_programmable_tstat?,
:is_smartstat?,
:is_cork?,
:is_relay_panel?,
:is_legacy_relay?,
:is_publication?,
:maximum_current,
:num_poles,
:category_name,
:image_path,
:image_url,
:thumbnail_url,
:is_floor_heating_product?,
:oversize?,
:ships_via_freight?,
:product_tax_code,
:is_snow_melting_product?,
:is_reviewable?,
:product_line_for_review,
to: :item,
allow_nil: true
|
#parent_quantity_factor ⇒ Object
Determines the parent line quantity
354
355
356
357
358
359
360
361
362
363
364
365
|
# File 'app/models/line_item.rb', line 354
def parent_quantity_factor
return unless parent&.quantity
(quantity / parent.quantity).to_i
end
|
121
|
# File 'app/models/line_item.rb', line 121
has_one :preset_job, dependent: :destroy
|
#price_editable?(account = nil) ⇒ Boolean
803
804
805
806
807
808
809
|
# File 'app/models/line_item.rb', line 803
def price_editable?(account = nil)
account.has_role?('sales_manager') || account.has_role?('admin') || (begin
catalog_item.price_editable
rescue StandardError
false
end)
end
|
#price_total ⇒ Object
665
666
667
668
669
|
# File 'app/models/line_item.rb', line 665
def price_total
(price || 0.0) * quantity
rescue StandardError
0.0
end
|
#price_with_vat ⇒ Object
Alias for Catalog_item#price_with_vat
248
249
250
251
252
253
254
|
# File 'app/models/line_item.rb', line 248
delegate :price_with_vat,
:sale_price_with_vat,
:msrp,
:msrp_with_vat,
:root_catalog_item,
to: :catalog_item,
allow_nil: true
|
#product_line_for_review ⇒ Object
Alias for Item#product_line_for_review
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
|
# File 'app/models/line_item.rb', line 226
delegate :is_oj_programmable_tstat?,
:is_smartstat?,
:is_cork?,
:is_relay_panel?,
:is_legacy_relay?,
:is_publication?,
:maximum_current,
:num_poles,
:category_name,
:image_path,
:image_url,
:thumbnail_url,
:is_floor_heating_product?,
:oversize?,
:ships_via_freight?,
:product_tax_code,
:is_snow_melting_product?,
:is_reviewable?,
:product_line_for_review,
to: :item,
allow_nil: true
|
#product_tax_code ⇒ Object
Alias for Item#product_tax_code
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
|
# File 'app/models/line_item.rb', line 226
delegate :is_oj_programmable_tstat?,
:is_smartstat?,
:is_cork?,
:is_relay_panel?,
:is_legacy_relay?,
:is_publication?,
:maximum_current,
:num_poles,
:category_name,
:image_path,
:image_url,
:thumbnail_url,
:is_floor_heating_product?,
:oversize?,
:ships_via_freight?,
:product_tax_code,
:is_snow_melting_product?,
:is_reviewable?,
:product_line_for_review,
to: :item,
allow_nil: true
|
120
|
# File 'app/models/line_item.rb', line 120
has_one :purchase_order_item, dependent: :restrict_with_error
|
#quantities_indicator_visible? ⇒ Boolean
811
812
813
814
815
|
# File 'app/models/line_item.rb', line 811
def quantities_indicator_visible?
item.quantities_indicator_visible?
rescue StandardError
true
end
|
102
|
# File 'app/models/line_item.rb', line 102
belongs_to :quote, -> { joins(:line_items).where(line_items: { resource_type: 'Quote' }) }, foreign_key: :resource_id, optional: true
|
#remaining_quantity_to_allocate_to_shipments ⇒ Object
433
434
435
|
# File 'app/models/line_item.rb', line 433
def remaining_quantity_to_allocate_to_shipments
quantity - shipment_contents.sum(:quantity)
end
|
#replacement_rma_item ⇒ RmaItem
111
|
# File 'app/models/line_item.rb', line 111
belongs_to :replacement_rma_item, class_name: 'RmaItem', optional: true
|
#reported_category_name ⇒ Object
914
915
916
|
# File 'app/models/line_item.rb', line 914
def reported_category_name
item&.primary_product_line&.lineage_expanded || 'unknown'
end
|
#require_serial_number? ⇒ Boolean
798
799
800
801
|
# File 'app/models/line_item.rb', line 798
def require_serial_number?
false
end
|
#resource ⇒ Resource
99
|
# File 'app/models/line_item.rb', line 99
belongs_to :resource, polymorphic: true, inverse_of: :line_items, optional: true
|
122
|
# File 'app/models/line_item.rb', line 122
has_one :review, dependent: :restrict_with_error
|
#rma_items ⇒ ActiveRecord::Relation<RmaItem>
124
|
# File 'app/models/line_item.rb', line 124
has_many :rma_items, foreign_key: 'returned_line_item_id', dependent: :destroy, inverse_of: :returned_line_item
|
#room_configuration ⇒ RoomConfiguration
109
|
# File 'app/models/line_item.rb', line 109
belongs_to :room_configuration, optional: true
|
#root_catalog_item ⇒ Object
Alias for Catalog_item#root_catalog_item
248
249
250
251
252
253
254
|
# File 'app/models/line_item.rb', line 248
delegate :price_with_vat,
:sale_price_with_vat,
:msrp,
:msrp_with_vat,
:root_catalog_item,
to: :catalog_item,
allow_nil: true
|
#sale_price_with_vat ⇒ Object
Alias for Catalog_item#sale_price_with_vat
248
249
250
251
252
253
254
|
# File 'app/models/line_item.rb', line 248
delegate :price_with_vat,
:sale_price_with_vat,
:msrp,
:msrp_with_vat,
:root_catalog_item,
to: :catalog_item,
allow_nil: true
|
108
|
# File 'app/models/line_item.rb', line 108
belongs_to :serial_number, optional: true
|
#set_cogs ⇒ Object
943
944
945
946
947
948
949
950
951
|
# File 'app/models/line_item.rb', line 943
def set_cogs
return unless !quantity.nil? && unit_cogs.nil? && resource.store_id.present?
store_item = StoreItem.available.where(item_id: get_item_id, store_id: resource.store_id).first
return if store_item.nil?
self.unit_cogs = store_item.unit_cogs
self.total_cogs = store_item.unit_cogs * quantity
end
|
#set_cogs_for_store_transfer ⇒ Object
953
954
955
956
957
958
959
960
961
962
|
# File 'app/models/line_item.rb', line 953
def set_cogs_for_store_transfer
return unless resource.try(:is_store_transfer?)
return if unit_cogs.present? || quantity.nil?
store_item = self.store_item
return if store_item.nil?
self.unit_cogs = store_item.unit_cogs
self.total_cogs = store_item.unit_cogs * quantity if store_item.unit_cogs.present?
end
|
#shipment_contents ⇒ ActiveRecord::Relation<ShipmentContent>
128
|
# File 'app/models/line_item.rb', line 128
has_many :shipment_contents, dependent: :destroy
|
116
|
# File 'app/models/line_item.rb', line 116
belongs_to :shipping_cost, optional: true
|
#shipping_name ⇒ Object
910
911
912
|
# File 'app/models/line_item.rb', line 910
def shipping_name
delivery&.retrieve_shipping_description_for_shipping_cost(shipping_cost) || name
end
|
#shipping_weight ⇒ Object
785
786
787
788
|
# File 'app/models/line_item.rb', line 785
def shipping_weight
item&.base_weight || 0.0
end
|
#ships_via_freight? ⇒ Object
Alias for Item#ships_via_freight?
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
|
# File 'app/models/line_item.rb', line 226
delegate :is_oj_programmable_tstat?,
:is_smartstat?,
:is_cork?,
:is_relay_panel?,
:is_legacy_relay?,
:is_publication?,
:maximum_current,
:num_poles,
:category_name,
:image_path,
:image_url,
:thumbnail_url,
:is_floor_heating_product?,
:oversize?,
:ships_via_freight?,
:product_tax_code,
:is_snow_melting_product?,
:is_reviewable?,
:product_line_for_review,
to: :item,
allow_nil: true
|
#show_out_of_stock?(item_availability = {}) ⇒ Boolean
575
576
577
578
579
580
581
582
583
584
585
|
# File 'app/models/line_item.rb', line 575
def show_out_of_stock?(item_availability = {})
if dropship? && resource.respond_to?(:single_origin?) && resource.single_origin?
!in_stock?
elsif dropship? || item.try(:always_available_online?)
false
elsif !item_availability.empty? && item_availability[catalog_item_id].present?
!item_availability[catalog_item_id]['in_stock']
else
!in_stock?
end
end
|
#single_origin_or_warehouse_pickup? ⇒ Boolean
587
588
589
590
591
|
# File 'app/models/line_item.rb', line 587
def single_origin_or_warehouse_pickup?
return false if resource.is_a?(RoomConfiguration)
resource.single_origin? || resource.is_warehouse_pickup?
end
|
#sku ⇒ Object
509
510
511
|
# File 'app/models/line_item.rb', line 509
def sku
item&.sku || sku_override
end
|
#sort_priority ⇒ Object
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
|
# File 'app/models/line_item.rb', line 376
def sort_priority
i = item || catalog_item&.store_item&.item
return [0, 0, 0, 0] unless i
s1 = i.product_category_priority
if i.is_heating_element?
s2 = -begin
i.width.to_i
rescue StandardError
0
end
s3 = -begin
i.length.to_i
rescue StandardError
0
end
else
s2 = 0
s3 = 0
end
s4 = i.sku
[s1, s2, s3, s4]
end
|
#sq_ft_total ⇒ Object
679
680
681
|
# File 'app/models/line_item.rb', line 679
def sq_ft_total
quantity * item.sqft.to_f
end
|
#stock_status ⇒ Object
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
|
# File 'app/models/line_item.rb', line 593
def stock_status
return :none unless catalog_item
return :na if quantity < 0 return :ok if dropship? && !single_origin_or_warehouse_pickup?
return :ok if unlimited_inventory?
committed_quantity = inventory_commits.sum(&:quantity)
return :ok if committed_quantity >= quantity
si = resource.respond_to?(:from_store_id) && resource.from_store_id ? StoreItem.where(store_id: resource.from_store_id, item_id:, location: 'AVAILABLE').first : store_item
return :oos if si.qty_available < quantity
return :low if item.qty_warn_on_stock && (si.qty_available <= item.qty_warn_on_stock)
:ok
end
|
#store_item ⇒ Object
620
621
622
|
# File 'app/models/line_item.rb', line 620
def store_item
direct_store_item || catalog_item&.store_item
end
|
#supplier_skus ⇒ Object
513
514
515
|
# File 'app/models/line_item.rb', line 513
def supplier_skus
item&.supplier_skus || []
end
|
#taxable_total ⇒ Object
696
697
698
699
700
701
702
|
# File 'app/models/line_item.rb', line 696
def taxable_total
if invoice&.invoice_type == Invoice::CI
discounted_total
else
taxable_amount.present? ? (taxable_amount * quantity) : discounted_total
end
end
|
#taxes_grouped_by_type ⇒ Object
367
368
369
370
371
372
373
374
|
# File 'app/models/line_item.rb', line 367
def taxes_grouped_by_type
tax_grouped = {}
if tax_rate.present? && tax_type.present?
rate_percentage = (tax_rate * 100)
tax_grouped[tax_type] = { tax_amount: tax_total, name: "#{TaxRate.description_for(tax_type)} #{rate_percentage}%", rate: rate_percentage }
end
tax_grouped
end
|
#thumbnail_url ⇒ Object
Alias for Item#thumbnail_url
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
|
# File 'app/models/line_item.rb', line 226
delegate :is_oj_programmable_tstat?,
:is_smartstat?,
:is_cork?,
:is_relay_panel?,
:is_legacy_relay?,
:is_publication?,
:maximum_current,
:num_poles,
:category_name,
:image_path,
:image_url,
:thumbnail_url,
:is_floor_heating_product?,
:oversize?,
:ships_via_freight?,
:product_tax_code,
:is_snow_melting_product?,
:is_reviewable?,
:product_line_for_review,
to: :item,
allow_nil: true
|
#total ⇒ Object
704
705
706
|
# File 'app/models/line_item.rb', line 704
def total
discounted_total
end
|
#total_shipping_weight ⇒ Object
790
791
792
|
# File 'app/models/line_item.rb', line 790
def total_shipping_weight
(shipping_weight * quantity)
end
|
#unit_supplier_purchase_cost ⇒ Object
711
712
713
|
# File 'app/models/line_item.rb', line 711
def unit_supplier_purchase_cost
item.try(:supplier_items)&.last&.current_price&.purchasing_cost
end
|
#unit_value_for_commercial_invoice ⇒ Object
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
|
# File 'app/models/line_item.rb', line 715
def unit_value_for_commercial_invoice
is_intra_company_or_electronic_ci_st = delivery&.order&.is_store_transfer? && (delivery&.order&.shipping_address&.is_warehouse_by_distance? || delivery&.electronic_ship_ci_pdf.present? || delivery&.should_have_electronic_commercial_invoice?) min_unit_value_arr = []
min_unit_value_arr << discounted_price if discounted_price&.positive? min_unit_value_arr << unit_supplier_purchase_cost if unit_supplier_purchase_cost&.positive? min_unit_value_arr << unit_cogs if unit_cogs&.positive? min_unit_value = min_unit_value_arr.min effective_price = discounted_price
effective_price = unit_cogs unless effective_price&.positive? effective_price = unit_supplier_purchase_cost unless effective_price&.positive? effective_price = price unless effective_price&.positive? (is_intra_company_or_electronic_ci_st ? (min_unit_value || effective_price) : effective_price)
end
|
#unlimited_inventory? ⇒ Boolean
612
613
614
|
# File 'app/models/line_item.rb', line 612
def unlimited_inventory?
store_item&.unlimited_inventory?
end
|
#validate_quantity_limit ⇒ Object
437
438
439
440
441
442
443
|
# File 'app/models/line_item.rb', line 437
def validate_quantity_limit
return unless quantity && (ql = store_item&.quantity_limit)
return unless quantity > ql
errors.add(:quantity, "quantity limit #{ql} exceeded for this item")
end
|
#void ⇒ Object
845
846
847
848
849
850
851
852
853
854
855
856
857
|
# File 'app/models/line_item.rb', line 845
def void
puts 'line_item.void'
if resource.line_items.goods.length == 1
resource.rma_cancel
else
order = resource
destroy
order.reload
order.returned
end
end
|