Class: RmaItem
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- RmaItem
- Includes:
- Models::Auditable, Models::LiquidMethods
- Defined in:
- app/models/rma_item.rb
Overview
== Schema Information
Table name: rma_items
Database name: primary
id :integer not null, primary key
arrival_datetime :datetime
inspection_notes :text
liable :string
received_date :date
replacement_required :boolean default(FALSE), not null
restocking_reason :string(255)
returned_item_location :string(255)
returned_item_quantity :integer
returned_reason :string(255)
state :string(255)
tech_examination_needed :boolean default(FALSE), not null
under_warranty :boolean
will_not_be_returned :boolean default(FALSE), not null
created_at :datetime
updated_at :datetime
creator_id :integer
credit_order_id :integer
replacement_order_id :integer
returned_item_id :integer
returned_line_item_id :integer
rma_id :integer
updater_id :integer
Indexes
idx_on_rma_id_returned_reason (rma_id,returned_reason)
idx_rma_id_tech_examination_needed (rma_id,tech_examination_needed)
idx_rma_id_wnb_returned (rma_id,will_not_be_returned)
index_rma_items_on_restocking_reason (restocking_reason)
index_rma_items_on_returned_line_item_id (returned_line_item_id)
index_rma_items_on_returned_reason (returned_reason)
ret_item_id_ret_line_item_id (returned_item_id,returned_line_item_id)
rma_id_replacement_required (rma_id,replacement_required)
rma_id_state (rma_id,state)
Foreign Keys
fk_rails_... (restocking_reason => rma_reason_codes.code) ON UPDATE => cascade
fk_rails_... (returned_reason => rma_reason_codes.code) ON UPDATE => cascade
Constant Summary collapse
- LIABLE_OPTIONS =
%w[WARMLYYOURS CUSTOMER].freeze
Constants included from Models::Auditable
Models::Auditable::ALWAYS_IGNORED
Instance Attribute Summary collapse
-
#new_record ⇒ Object
Returns the value of attribute new_record.
-
#original_qty ⇒ Object
Returns the value of attribute original_qty.
-
#print_label ⇒ Object
Returns the value of attribute print_label.
-
#qty_to_receive ⇒ Object
Returns the value of attribute qty_to_receive.
-
#replacement_item_sku ⇒ Object
Returns the value of attribute replacement_item_sku.
-
#return_item_action ⇒ Object
Returns the value of attribute return_item_action.
-
#returned_item_description ⇒ Object
Returns the value of attribute returned_item_description.
- #returned_item_id ⇒ Object readonly
- #returned_item_quantity ⇒ Object readonly
-
#returned_item_sku ⇒ Object
Returns the value of attribute returned_item_sku.
- #returned_line_item_id ⇒ Object readonly
- #returned_reason ⇒ Object readonly
Belongs to collapse
- #replacement_order ⇒ Order
- #returned_item ⇒ Item
- #returned_line_item ⇒ LineItem
- #rma ⇒ Rma
- #rma_reason_code ⇒ RmaReasonCode
- #rma_restocking_reason_code ⇒ RmaReasonCode
Methods included from Models::Auditable
Has one collapse
Has many collapse
Has and belongs to many collapse
Class Method Summary collapse
-
.active ⇒ ActiveRecord::Relation<RmaItem>
A relation of RmaItems that are active.
-
.awaiting_inspection ⇒ ActiveRecord::Relation<RmaItem>
A relation of RmaItems that are awaiting inspection.
- .calculate_credit_percentage(location, liable) ⇒ Object
- .liable_select_options ⇒ Object
-
.replacement_required ⇒ ActiveRecord::Relation<RmaItem>
A relation of RmaItems that are replacement required.
-
.requested ⇒ ActiveRecord::Relation<RmaItem>
A relation of RmaItems that are requested.
-
.returnable ⇒ ActiveRecord::Relation<RmaItem>
A relation of RmaItems that are returnable.
-
.returned ⇒ ActiveRecord::Relation<RmaItem>
A relation of RmaItems that are returned.
-
.shipping_error ⇒ ActiveRecord::Relation<RmaItem>
A relation of RmaItems that are shipping error.
-
.tech_examination_needed ⇒ ActiveRecord::Relation<RmaItem>
A relation of RmaItems that are tech examination needed.
-
.will_be_returned ⇒ ActiveRecord::Relation<RmaItem>
A relation of RmaItems that are will be returned.
-
.will_not_be_returned ⇒ ActiveRecord::Relation<RmaItem>
A relation of RmaItems that are will not be returned.
Instance Method Summary collapse
- #auto_return ⇒ Object
- #can_be_unreturned? ⇒ Boolean
- #can_be_voided? ⇒ Boolean
- #credit_percentage ⇒ Object
- #delete_linked_credit_order_line_item ⇒ Object
- #editable? ⇒ Boolean
- #events_for_select ⇒ Object
- #is_customer_fault? ⇒ Boolean
- #possible_events ⇒ Object
- #possible_events_for_select ⇒ Object
- #possible_serial_numbers ⇒ Object
- #reactivate_serial_numbers ⇒ Object
- #reason_codes_for_select(include_advanced: true) ⇒ Object
- #replacement_item_description ⇒ Object
-
#returned_line_is_kit_component? ⇒ Boolean
True when this return row is tied to an invoice line that is a child line (e.g. kit part).
- #set_default_return_location ⇒ Object
- #store_item ⇒ Object
- #update_item_ledger ⇒ 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
Instance Attribute Details
#new_record ⇒ Object
Returns the value of attribute new_record.
113 114 115 |
# File 'app/models/rma_item.rb', line 113 def new_record @new_record end |
#original_qty ⇒ Object
Returns the value of attribute original_qty.
113 114 115 |
# File 'app/models/rma_item.rb', line 113 def original_qty @original_qty end |
#print_label ⇒ Object
Returns the value of attribute print_label.
113 114 115 |
# File 'app/models/rma_item.rb', line 113 def print_label @print_label end |
#qty_to_receive ⇒ Object
Returns the value of attribute qty_to_receive.
113 114 115 |
# File 'app/models/rma_item.rb', line 113 def qty_to_receive @qty_to_receive end |
#replacement_item_sku ⇒ Object
Returns the value of attribute replacement_item_sku.
113 114 115 |
# File 'app/models/rma_item.rb', line 113 def replacement_item_sku @replacement_item_sku end |
#return_item_action ⇒ Object
Returns the value of attribute return_item_action.
113 114 115 |
# File 'app/models/rma_item.rb', line 113 def return_item_action @return_item_action end |
#returned_item_description ⇒ Object
Returns the value of attribute returned_item_description.
113 114 115 |
# File 'app/models/rma_item.rb', line 113 def returned_item_description @returned_item_description end |
#returned_item_id ⇒ Object (readonly)
94 |
# File 'app/models/rma_item.rb', line 94 validates :returned_item_id, :returned_item_quantity, :returned_reason, presence: true |
#returned_item_quantity ⇒ Object (readonly)
94 |
# File 'app/models/rma_item.rb', line 94 validates :returned_item_id, :returned_item_quantity, :returned_reason, presence: true |
#returned_item_sku ⇒ Object
Returns the value of attribute returned_item_sku.
113 114 115 |
# File 'app/models/rma_item.rb', line 113 def returned_item_sku @returned_item_sku end |
#returned_line_item_id ⇒ Object (readonly)
99 100 |
# File 'app/models/rma_item.rb', line 99 validates :returned_line_item_id, presence: { if: ->(i) { i.rma&.original_invoice.present? }, message: 'must be present on original invoice. Remove link to original invoice if you still want to include it.' } |
#returned_reason ⇒ Object (readonly)
94 |
# File 'app/models/rma_item.rb', line 94 validates :returned_item_id, :returned_item_quantity, :returned_reason, presence: true |
Class Method Details
.active ⇒ ActiveRecord::Relation<RmaItem>
A relation of RmaItems that are active. Active Record Scope
71 |
# File 'app/models/rma_item.rb', line 71 scope :active, -> { where.not(state: 'voided') } |
.awaiting_inspection ⇒ ActiveRecord::Relation<RmaItem>
A relation of RmaItems that are awaiting inspection. Active Record Scope
73 |
# File 'app/models/rma_item.rb', line 73 scope :awaiting_inspection, -> { where(state: 'awaiting_inspection') } |
.calculate_credit_percentage(location, liable) ⇒ Object
186 187 188 189 190 191 192 193 194 195 196 197 |
# File 'app/models/rma_item.rb', line 186 def self.calculate_credit_percentage(location, liable) return nil if location.nil? || liable.nil? # under_warranty is not taken into account at this point. a product could # still be under warranty but if the customer broke it they're still liable # it's not a fault of the product manufacturing if liable == 'WARMLYYOURS' || location == 'AVAILABLE' 100 else # customer is liable, but it's not resellable 50 end end |
.liable_select_options ⇒ Object
199 200 201 |
# File 'app/models/rma_item.rb', line 199 def self. [%w[WarmlyYours WARMLYYOURS], %w[Customer CUSTOMER]] end |
.replacement_required ⇒ ActiveRecord::Relation<RmaItem>
A relation of RmaItems that are replacement required. Active Record Scope
Validations:
- Inclusion ({ in: [true, false] })
75 |
# File 'app/models/rma_item.rb', line 75 scope :replacement_required, -> { where(replacement_required: true) } |
.requested ⇒ ActiveRecord::Relation<RmaItem>
A relation of RmaItems that are requested. Active Record Scope
72 |
# File 'app/models/rma_item.rb', line 72 scope :requested, -> { where(state: 'requested') } |
.returnable ⇒ ActiveRecord::Relation<RmaItem>
A relation of RmaItems that are returnable. Active Record Scope
79 |
# File 'app/models/rma_item.rb', line 79 scope :returnable, -> { where(state: %w[requested awaiting_inspection]) } |
.returned ⇒ ActiveRecord::Relation<RmaItem>
A relation of RmaItems that are returned. Active Record Scope
74 |
# File 'app/models/rma_item.rb', line 74 scope :returned, -> { where(state: 'returned') } |
.shipping_error ⇒ ActiveRecord::Relation<RmaItem>
A relation of RmaItems that are shipping error. Active Record Scope
78 |
# File 'app/models/rma_item.rb', line 78 scope :shipping_error, -> { where(returned_reason: %w[LIT PMI]) } |
.tech_examination_needed ⇒ ActiveRecord::Relation<RmaItem>
A relation of RmaItems that are tech examination needed. Active Record Scope
80 |
# File 'app/models/rma_item.rb', line 80 scope :tech_examination_needed, -> { where(tech_examination_needed: true) } |
.will_be_returned ⇒ ActiveRecord::Relation<RmaItem>
A relation of RmaItems that are will be returned. Active Record Scope
76 |
# File 'app/models/rma_item.rb', line 76 scope :will_be_returned, -> { where(will_not_be_returned: [false, nil]) } |
.will_not_be_returned ⇒ ActiveRecord::Relation<RmaItem>
A relation of RmaItems that are will not be returned. Active Record Scope
77 |
# File 'app/models/rma_item.rb', line 77 scope :will_not_be_returned, -> { where(will_not_be_returned: true) } |
Instance Method Details
#auto_return ⇒ Object
350 351 352 353 354 355 |
# File 'app/models/rma_item.rb', line 350 def auto_return self.restocking_reason = returned_reason self.qty_to_receive = returned_item_quantity self.returned_item_location ||= 'SCRAP' returned! end |
#can_be_unreturned? ⇒ Boolean
226 227 228 |
# File 'app/models/rma_item.rb', line 226 def can_be_unreturned? returned? && !rma.credit_in_process? && !rma.credited_partially_refunded? && !rma.credited_fully_refunded? && !rma.voided? && !credit_order_line_item&.resource&.printed? end |
#can_be_voided? ⇒ Boolean
222 223 224 |
# File 'app/models/rma_item.rb', line 222 def can_be_voided? awaiting_inspection? || requested? end |
#credit_order_line_item ⇒ LineItem
64 |
# File 'app/models/rma_item.rb', line 64 has_one :credit_order_line_item, class_name: 'LineItem', foreign_key: 'credit_rma_item_id' |
#credit_percentage ⇒ Object
218 219 220 |
# File 'app/models/rma_item.rb', line 218 def credit_percentage RmaItem.calculate_credit_percentage(returned_item_location, liable) end |
#delete_linked_credit_order_line_item ⇒ Object
207 208 209 210 211 212 213 214 215 216 |
# File 'app/models/rma_item.rb', line 207 def delete_linked_credit_order_line_item return true if credit_order_line_item.nil? co = credit_order_line_item.resource credit_order_line_item.destroy co.reload co.returned co.destroy if co.line_items.non_shipping.count.zero? true end |
#editable? ⇒ Boolean
203 204 205 |
# File 'app/models/rma_item.rb', line 203 def editable? awaiting_inspection? || requested? # Todo add a new state for received but not returned end |
#events_for_select ⇒ Object
373 374 375 |
# File 'app/models/rma_item.rb', line 373 def events_for_select [["#{human_state_name.titleize} (Current)", '']] + possible_events_for_select end |
#is_customer_fault? ⇒ Boolean
275 276 277 |
# File 'app/models/rma_item.rb', line 275 def is_customer_fault? rma_reason_code.customer_fault? end |
#item_ledger_entries ⇒ ActiveRecord::Relation<ItemLedgerEntry>
67 |
# File 'app/models/rma_item.rb', line 67 has_many :item_ledger_entries |
#possible_events ⇒ Object
365 366 367 |
# File 'app/models/rma_item.rb', line 365 def possible_events state_transitions.map(&:event).sort end |
#possible_events_for_select ⇒ Object
369 370 371 |
# File 'app/models/rma_item.rb', line 369 def possible_events_for_select possible_events.map { |evt| [evt.to_s.titleize, evt] } end |
#possible_serial_numbers ⇒ Object
230 231 232 233 234 235 236 237 238 239 240 |
# File 'app/models/rma_item.rb', line 230 def possible_serial_numbers return [] unless returned_line_item sns = [] if returned_line_item.require_reservation? && returned_line_item.serial_numbers.present? sns = returned_line_item.serial_numbers elsif (li_children = returned_line_item.children.to_a.select(&:require_reservation?)).present? sns = li_children.map(&:serial_numbers) end sns.to_a.flatten end |
#reactivate_serial_numbers ⇒ Object
242 243 244 245 246 247 248 249 250 251 |
# File 'app/models/rma_item.rb', line 242 def reactivate_serial_numbers serial_numbers.each do |sn| if sn.store_item_id != store_item.id && !store_item.is_kit? sn.update_attribute('store_item_id', store_item.id) end sn.trigger_available sn.reprint end end |
#reason_codes_for_select(include_advanced: true) ⇒ Object
357 358 359 360 361 362 363 |
# File 'app/models/rma_item.rb', line 357 def reason_codes_for_select(include_advanced: true) return [] unless returned_item returned_item.rma_reason_codes(include_advanced: include_advanced).order(:code).map do |e| [e.code_and_description, e.code, { 'data-default-location' => e.default_location }] end end |
#replacement_item_description ⇒ Object
283 284 285 |
# File 'app/models/rma_item.rb', line 283 def replacement_item_description replacement_item.try(:name) end |
#replacement_order ⇒ Order
63 |
# File 'app/models/rma_item.rb', line 63 belongs_to :replacement_order, class_name: 'Order', inverse_of: :rma_items, optional: true |
#replacement_order_line_item ⇒ LineItem
65 66 |
# File 'app/models/rma_item.rb', line 65 has_one :replacement_order_line_item, class_name: 'LineItem', foreign_key: 'replacement_rma_item_id' |
#returned_item ⇒ Item
61 |
# File 'app/models/rma_item.rb', line 61 belongs_to :returned_item, class_name: 'Item', optional: true |
#returned_line_is_kit_component? ⇒ Boolean
True when this return row is tied to an invoice line that is a child line (e.g. kit part).
378 379 380 |
# File 'app/models/rma_item.rb', line 378 def returned_line_is_kit_component? returned_line_item_id.present? && returned_line_item&.parent_id.present? end |
#returned_line_item ⇒ LineItem
62 |
# File 'app/models/rma_item.rb', line 62 belongs_to :returned_line_item, class_name: 'LineItem', optional: true |
#rma ⇒ Rma
56 |
# File 'app/models/rma_item.rb', line 56 belongs_to :rma, inverse_of: :rma_items, optional: true |
#rma_reason_code ⇒ RmaReasonCode
57 58 |
# File 'app/models/rma_item.rb', line 57 belongs_to :rma_reason_code, foreign_key: 'returned_reason', primary_key: 'code', optional: true |
#rma_restocking_reason_code ⇒ RmaReasonCode
59 60 |
# File 'app/models/rma_item.rb', line 59 belongs_to :rma_restocking_reason_code, foreign_key: 'restocking_reason', class_name: 'RmaReasonCode', primary_key: 'code', optional: true |
#serial_numbers ⇒ ActiveRecord::Relation<SerialNumber>
69 |
# File 'app/models/rma_item.rb', line 69 has_and_belongs_to_many :serial_numbers |
#set_default_return_location ⇒ Object
382 383 384 385 |
# File 'app/models/rma_item.rb', line 382 def set_default_return_location self.returned_item_location = rma_reason_code&.default_location if returned_reason_changed? || returned_item_location.blank? self.liable ||= 'WARMLYYOURS' # a default TODO leverage reason codes end |
#store_item ⇒ Object
287 288 289 290 |
# File 'app/models/rma_item.rb', line 287 def store_item store = rma.return_shipping_address.warehouse_store returned_item.store_item_for(store.id, returned_item_location) end |
#update_item_ledger ⇒ Object
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 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 |
# File 'app/models/rma_item.rb', line 292 def update_item_ledger store = rma.return_shipping_address.warehouse_store if returned_item.is_kit? kit_serial_number_ids = serial_number_ids.dup # Use returned line item children to get the actual ordered kit line item quantities if returned_line_item.present? returned_line_item.children.each do |kit_li| ki_store_item = kit_li.item.store_item_for(store.id, 'AVAILABLE') ki_serial_number_ids = serial_numbers.select do |sn| sn.store_item_id == ki_store_item.id end.map(&:id) kit_li_quantity = kit_li.quantity * returned_item_quantity / returned_line_item.quantity ItemLedgerEntry.create!(category: 'RMA_RECEIPT', store: store, item: kit_li.item, gl_date: Date.current, item_kit: returned_item, quantity: kit_li_quantity, currency: store.currency, unit_cost: ki_store_item.unit_cogs, total_cost: ki_store_item.unit_cogs * kit_li_quantity, rma_item: self, location: returned_item_location, description: "RMA ##{rma.rma_number} #{returned_item.sku} (#{kit_li.sku})", serial_number_ids: ki_serial_number_ids) kit_serial_number_ids -= ki_serial_number_ids end else kit_contents = ItemRelation.where(source_item_id: returned_item) kit_contents.each do |kit_content| kc_store_item = kit_content.target_item.store_item_for(store.id, 'AVAILABLE') kc_serial_number_ids = serial_numbers.select do |sn| sn.store_item_id == kc_store_item.id end.map(&:id) kc_quantity = kit_content.quantity * returned_item_quantity ItemLedgerEntry.create!(category: 'RMA_RECEIPT', store: store, item: kit_content.target_item, gl_date: Date.current, item_kit: returned_item, quantity: kc_quantity, currency: store.currency, unit_cost: kc_store_item.unit_cogs, total_cost: kc_store_item.unit_cogs * kc_quantity, rma_item: self, location: returned_item_location, description: "RMA ##{rma.rma_number} #{returned_item.sku} (#{kit_content.target_item.sku})", serial_number_ids: kc_serial_number_ids) kit_serial_number_ids -= kc_serial_number_ids end end ItemLedgerEntry.create!(store: store, item: returned_item, category: 'RMA_RECEIPT_KIT', gl_date: Date.current, quantity: 0, quantity_eval: -returned_item_quantity, currency: store.currency, unit_cost: 0, total_cost: 0, location: returned_item_location, rma_item: self, serial_number_ids: kit_serial_number_ids) else si = returned_item.store_item_for(store.id, 'AVAILABLE') ItemLedgerEntry.create!(category: 'RMA_RECEIPT', store: store, item: returned_item, gl_date: Date.current, quantity: returned_item_quantity, currency: store.currency, unit_cost: si.unit_cogs, total_cost: si.unit_cogs * returned_item_quantity, rma_item: self, location: returned_item_location, description: "RMA ##{rma.rma_number} #{returned_item.sku}", serial_number_ids: serial_number_ids) end end |