Files
openfoodnetwork/app/services/line_item_syncer.rb

56 lines
1.7 KiB
Ruby

# Responsible for keeping line items on initialised orders for a subscription in sync with
# the subscription line items on that subscription.
class LineItemSyncer
def initialize(subscription, order_update_issues)
@subscription = subscription
@order_update_issues = order_update_issues
end
def sync!(order)
update_item_quantities(order)
create_new_items(order)
destroy_obsolete_items(order)
end
private
delegate :subscription_line_items, to: :subscription
attr_reader :subscription, :order_update_issues
def update_item_quantities(order)
changed_subscription_line_items.each do |sli|
line_item = order.line_items.find_by_variant_id(sli.variant_id)
next if update_quantity(line_item, sli)
product_name = "#{line_item.product.name} - #{line_item.full_name}"
order_update_issues.add(order, product_name)
end
end
def create_new_items(order)
new_subscription_line_items.each do |sli|
order.line_items.create(variant_id: sli.variant_id, quantity: sli.quantity, skip_stock_check: true)
end
end
def destroy_obsolete_items(order)
order.line_items.where(variant_id: subscription_line_items.select(&:marked_for_destruction?).map(&:variant_id)).destroy_all
end
def changed_subscription_line_items
subscription_line_items.select{ |sli| sli.changed? && sli.persisted? }
end
def new_subscription_line_items
subscription_line_items.select(&:new_record?)
end
def update_quantity(line_item, sli)
if line_item.quantity == sli.quantity_was
return line_item.update_attributes(quantity: sli.quantity, skip_stock_check: true)
end
line_item.quantity == sli.quantity
end
end