Class: Dscf::Marketplace::OrderValidationService

Inherits:
Object
  • Object
show all
Defined in:
app/services/dscf/marketplace/order_validation_service.rb

Class Method Summary collapse

Class Method Details

.validate(order) ⇒ Object

Validates all items in an order against current listings / availability. Sets validation_status on each OrderItem per the requirements doc: validated, no_longer_listed, price_changed, low_quantity Also populates resolved_* fields where applicable.



8
9
10
11
12
13
14
15
16
17
# File 'app/services/dscf/marketplace/order_validation_service.rb', line 8

def self.validate(order)
  order.order_items.each do |item|
    validate_item(item)
  end
  # Transition order to splitting ready if all validated
  if order.order_items.all? { |i| i.validation_status == "validated" }
    order.update!(status: :splitting) if order.validating?
  end
  order.reload
end

.validate_item(item) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'app/services/dscf/marketplace/order_validation_service.rb', line 20

def self.validate_item(item)
  # Don't re-flag an item the aggregator has already resolved. Re-running
  # validation would otherwise compare the live listing price against the
  # untouched order unit_price and reopen the same issue forever.
  # A resolved item is "validated" but RETAINS its validation_note; an item
  # that was never flagged is "validated" with a nil note (set in the else
  # branch below), so the retained note cleanly distinguishes the two.
  return item if item.validation_status == "validated" && item.validation_note.present?

  current_listing = find_current_active_listing(item)
  return mark_no_longer_listed(item) unless current_listing

  current_price = current_listing.price
  current_qty   = current_listing.quantity

  if current_price != item.unit_price
    item.validation_status = :price_changed
    item.validation_note = "Price changed (listed: #{current_price})"
    item.resolved_unit_price = item.unit_price # keep original order price by default (user can choose listed later)
  elsif item.quantity > current_qty
    item.validation_status = :low_quantity
    item.validation_note = "Low quantity available (listed: #{current_qty})"
    item.resolved_quantity = [ item.quantity, current_qty ].min
  else
    item.validation_status = :validated
    item.validation_note = nil
    item.resolved_unit_price = nil
    item.resolved_quantity = nil
  end

  item.save! if item.changed?
  item
end