module Comee module Core class CustomerOrderService def submit(id) order = CustomerOrder.find_by(id: id) raise(StandardError, "Customer order with id `#{id}` not found.") unless order unless CustomerOrder.statuses[order.status] == CustomerOrder.statuses[:draft] raise(StandardError, "Customer order should be in draft state.") end raise(StandardError, "Customer order should have at least one item.") unless order.customer_order_items.count.positive? order.update!(status: CustomerOrder.statuses[:submitted]) order end def submit_for_confirmation(id) order = CustomerOrder.find_by(id: id) raise(StandardError, "Customer order with id `#{id}` not found.") unless order unless CustomerOrder.statuses[order.status] == CustomerOrder.statuses[:submitted] raise(StandardError, "Customer order should be in submitted state.") end raise(StandardError, "Customer order does not have any items.") if order.customer_order_items.count.zero? order.update!(status: CustomerOrder.statuses[:awaiting_confirmation]) order end def accept(id) order = CustomerOrder.find_by(id: id) raise(StandardError, "Customer order with id `#{id}` not found.") unless order if CustomerOrder.statuses[order.status] == CustomerOrder.statuses[:accepted] raise(StandardError, "Customer order is already in accepted state.") end allowed_statuses = [CustomerOrder.statuses[:submitted], CustomerOrder.statuses[:awaiting_confirmation]] unless allowed_statuses.include?(CustomerOrder.statuses[order.status]) raise(StandardError, "Customer order should be in submitted or awaiting confirmation state.") end raise(StandardError, "Customer order does not have any items.") if order.customer_order_items.count.zero? sales_order = nil CustomerOrder.transaction do sales_order = SalesOrder.create!( order_number: order.order_number, customer_order: order, status: SalesOrder.statuses[:draft] ) items = order.customer_order_items.each_with_object([]) do |item, res| next if item.canceled? res << { sales_order_id: sales_order.id, customer_order_item_id: item.id, product_id: item.product_id, unit_id: item.unit_id, quantity: item.quantity, price: item.price, delivery_date: item.delivery_date } end SalesOrderItem.insert_all!(items) order.update!(status: CustomerOrder.statuses[:accepted]) end sales_order end def cancel(id) order = CustomerOrder.find_by(id: id) raise(StandardError, "Customer order with id `#{id}` not found.") unless order if CustomerOrder.statuses[order.status] == CustomerOrder.statuses[:canceled] raise(StandardError, "Customer order is already canceled.") end order.update!(status: CustomerOrder.statuses[:canceled]) order end end end end