# frozen_string_literal: true module Spree class OrderContents attr_accessor :order def initialize(order) @order = order end # Get current line item for variant if exists # Add variant qty to line_item def add(variant, quantity = 1, shipment = nil) line_item = add_to_line_item(variant, quantity, shipment) update_shipment(shipment) update_order line_item end # Get current line item for variant # Remove variant qty from line_item def remove(variant, quantity = nil, shipment = nil, restock_item = true) line_item = remove_from_line_item(variant, quantity, shipment, restock_item) update_shipment(shipment) order.update_order_fees! if order.completed? update_order line_item end def update_or_create(variant, attributes) line_item = find_line_item_by_variant(variant) if line_item line_item.update(attributes) else line_item = Spree::LineItem.new(attributes) line_item.variant = variant line_item.price = variant.price order.line_items << line_item end update_shipment order.reload line_item end def update_cart(params) if order.update(params) discard_empty_line_items update_shipment update_order true else false end end def update_item(line_item, params) if line_item.update(params) discard_empty_line_items order.update_line_item_fees! line_item order.update_order_fees! if order.completed? update_shipment update_order true else false end end private def discard_empty_line_items order.line_items = order.line_items.select { |li| li.quantity.positive? } end def update_shipment(target_shipment = nil) if order.completed? || target_shipment.present? order.update_shipping_fees! else order.ensure_updated_shipments end end def add_to_line_item(variant, quantity, shipment = nil) line_item = find_line_item_by_variant(variant) if line_item line_item.target_shipment = shipment line_item.quantity += quantity.to_i else line_item = order.line_items.new(quantity:, variant:) line_item.target_shipment = shipment line_item.price = variant.price end line_item.save line_item end def remove_from_line_item(variant, quantity, shipment = nil, restock_item = true) line_item = find_line_item_by_variant(variant, true) line_item.restock_item = restock_item quantity.present? ? line_item.quantity += -quantity : line_item.quantity = 0 line_item.target_shipment = shipment if line_item.quantity == 0 line_item.destroy else line_item.save! end line_item end def find_line_item_by_variant(variant, raise_error = false) line_item = order.find_line_item_by_variant(variant) if line_item.blank? && raise_error raise ActiveRecord::RecordNotFound, "Line item not found for variant #{variant.sku}" end line_item end def update_order order.update_order! order.reload end end end