mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-24 20:36:49 +00:00
`Spree::OrderContents#update_or_create` is used to update the cart when on the /shop page. If you start an order and proceed to the "Order summary" step, and then decide to update your order by using the shop link next to the cart, such update wouldn't update the shipment. This result in the order page in the backoffice displaying the wrong data, and more importantly, in the stock not being updated. So now we ensure shipment will be updated, which result in the checkout flow being restarted, thus making sure the shipment is updated.
132 lines
3.2 KiB
Ruby
132 lines
3.2 KiB
Ruby
# 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
|