require 'product_in_checkout.rb' class Checkout class InvalidItem < StandardError; end def initialize(shop:) @shop = shop @items = [] end def add(product_id:, quantity: 1) product = @shop.product_by_id(product_id) raise InvalidItem unless product new_or_existing_product_in_checkout(product).add_quantity(quantity) end def remove(product_id:, quantity: 1) product = @shop.product_by_id(product_id) raise InvalidItem unless product product_in_checkout = existing_product_in_checkout(product) return false unless product_in_checkout product_in_checkout.remove_quantity(quantity) trim_empty_items end def items @items end def item_quantities @items.map { |item| [item.product_id, item.quantity] }.to_h end def clear @items = [] end def total @items.reduce(0.00) { |running_total, item| running_total + item.total } end private def existing_product_in_checkout(product) @items.find { |item| item.product_id == product.id } end def new_or_existing_product_in_checkout(product) product_in_checkout = existing_product_in_checkout(product) unless product_in_checkout product_in_checkout = ProductInCheckout.new(product: product) @items.push(product_in_checkout) end product_in_checkout end def trim_empty_items @items = @items.filter { |item| item.quantity > 0 } end end