Class: Comee::Core::CustomerOrderService
- Inherits:
-
Object
- Object
- Comee::Core::CustomerOrderService
- Defined in:
- app/services/comee/core/customer_order_service.rb
Instance Method Summary collapse
- #accept(id, accepted_by = nil) ⇒ Object
- #cancel(id) ⇒ Object
-
#convert_price(price, unit_id, new_unit_id) ⇒ Numeric
This method converts a price value per a unit of measure to a price value per another unit of measure.
-
#convert_quantity(quantity, unit_id, new_unit_id) ⇒ Numeric
This method converts a price value per a unit of measure to a price value per another unit of measure.
- #create(params) ⇒ Object
- #submit(id) ⇒ Object
- #submit_for_confirmation(id) ⇒ Object
- #suggest_values(item_id, from_id, to_id, quantity, old_price = nil) ⇒ Object
Instance Method Details
#accept(id, accepted_by = nil) ⇒ Object
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 |
# File 'app/services/comee/core/customer_order_service.rb', line 136 def accept(id, accepted_by = nil) 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 if order.customer_order_items.count.zero? || order.customer_order_items.all?(&:canceled?) raise(StandardError, "Customer order does not have any items.") end sales_order = nil CustomerOrder.transaction do sales_order = SalesOrder.create!( order_date: order.order_date, customer_order: order, status: SalesOrder.statuses[:draft], client: order.client, order_terms: order.order_terms, shipment_address: order.shipment_address, invoice_address: order.invoice_address, delivery_address: order.delivery_address, destination: order.final_destination, handover_date: order.handover_date, shipping_date: order.shipping_date, delivery_date: order.final_delivery_date, consignee: order.consignee, created_by: accepted_by || "", consolidator_date: order.consolidator_date, voyage_no: order.voyage_no, shipping_arrangement: order.shipping_arrangement ) order_items = order.customer_order_items.includes(:product, :unit) client_id = order.client.parent_id || order.client_id product_ids = order_items.map(&:product_id).uniq client_prices = ClientPrice.where( client_id: client_id, product_id: product_ids, status: ClientPrice.statuses[:current] ) master_prices = MasterPrice.includes(:supplier).where(primary: true, status: Price.statuses[:current], product_id: product_ids) items = order_items.each_with_object([]) do |item, res| next if item.canceled? default_unit = item.product.default_unit unit_id = default_unit ? default_unit["id"] : item.unit_id quantity = convert_quantity(item.quantity, item.unit_id, unit_id) client_price = client_prices.find { |price| price.product_id == item.product_id } master_price = master_prices.find { |price| price.product_id == item.product_id } raise(StandardError, "No primary supplier found for product #{item.customer_item_no}") unless master_price product_lookup = master_price.product_lookup order_price = convert_price(item.price, item.unit_id, unit_id) price = if client_price convert_price(client_price.price, client_price.unit_id, unit_id) else convert_price(master_price.selling_price, master_price.unit_id, unit_id) end res << { sales_order_id: sales_order.id, customer_order_item_id: item.id, product_id: item.product_id, unit_id: unit_id, serial_no: item.serial_no, customer_item_no: item.customer_item_no, customer_item_alias: item.customer_item_alias, customer_item_description: item.customer_item_description, quantity: quantity, price: price, price_diff: price - order_price, total_price: quantity * price, delivery_date: item.delivery_date, handover_date: order.handover_date, lead_time: master_price&.lead_time, use_alias: item.use_alias, additional_details: { supplier_id: master_price.supplier_id, supplier_name: master_price.supplier.name, supplier_item_no: product_lookup&.code, supplier_description: product_lookup&.item_description, country_of_origin: master_price&.country_of_origin } } end SalesOrderItem.insert_all!(items) order.update!(status: CustomerOrder.statuses[:accepted]) sales_order.calculate_total_price sales_order.calculate_vat sales_order.save! end sales_order end |
#cancel(id) ⇒ Object
239 240 241 242 243 244 245 246 247 248 249 |
# File 'app/services/comee/core/customer_order_service.rb', line 239 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 |
#convert_price(price, unit_id, new_unit_id) ⇒ Numeric
This method converts a price value per a unit of measure to a price value per another unit of measure.
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'app/services/comee/core/customer_order_service.rb', line 39 def convert_price(price, unit_id, new_unit_id) return price if unit_id == new_unit_id conversions = UnitConversion.where("from_id = ? AND to_id = ?", unit_id, new_unit_id) .or(UnitConversion.where("from_id = ? AND to_id = ?", new_unit_id, unit_id)) unless conversions.count.positive? units = Unit.where(id: [unit_id, new_unit_id]).select(:code) raise(StandardError, "There is no conversion factor between #{units[0].code} and #{units[1].code}.") end conversion = conversions.first return (price / conversion.factor).round(2) if unit_id == conversion.from_id && new_unit_id == conversion.to_id (price * conversion.factor).round(2) end |
#convert_quantity(quantity, unit_id, new_unit_id) ⇒ Numeric
This method converts a price value per a unit of measure to a price value per another unit of measure.
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'app/services/comee/core/customer_order_service.rb', line 65 def convert_quantity(quantity, unit_id, new_unit_id) return quantity if unit_id == new_unit_id conversions = UnitConversion.where("from_id = ? AND to_id = ?", unit_id, new_unit_id) .or(UnitConversion.where("from_id = ? AND to_id = ?", new_unit_id, unit_id)) unless conversions.count.positive? units = Unit.where(id: [unit_id, new_unit_id]) raise(StandardError, "There is no conversion factor between #{units[0].code} and #{units[1].code}.") end conversion = conversions.first return (quantity * conversion.factor).round if unit_id == conversion.from_id && new_unit_id == conversion.to_id (quantity / conversion.factor).round end |
#create(params) ⇒ Object
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'app/services/comee/core/customer_order_service.rb', line 4 def create(params) ActiveRecord::Base.transaction do prev_order = Comee::Core::CustomerOrder.find_by(order_number: params[:order_number]) if prev_order && Comee::Core::CustomerOrderItem.exists?(customer_order_id: prev_order.id) Comee::Core::CustomerOrderItem.where(customer_order_id: prev_order.id).delete_all prev_order.delete end end order = nil params = params.to_h.with_indifferent_access ActiveRecord::Base.transaction do order_params = params.except(:items) order = Comee::Core::CustomerOrder.create(**order_params) items = params.slice(:items)[:items] items.each do |item| item[:customer_order_id] = order.id item[:total_price] = item[:quantity] * item[:price] unless item.key?(:total_price) && !item[:total_price].nil? end Comee::Core::CustomerOrderItem.insert_all!(items) end order end |
#submit(id) ⇒ Object
108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'app/services/comee/core/customer_order_service.rb', line 108 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 |
#submit_for_confirmation(id) ⇒ Object
122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'app/services/comee/core/customer_order_service.rb', line 122 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 |
#suggest_values(item_id, from_id, to_id, quantity, old_price = nil) ⇒ Object
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'app/services/comee/core/customer_order_service.rb', line 82 def suggest_values(item_id, from_id, to_id, quantity, old_price = nil) item = SalesOrderItem.includes(:product, sales_order: :client) .find_by(id: item_id) raise(StandardError, "Order item with id `#{item_id}` not found.") unless item client = item.sales_order.client client_id = client.parent_id || client.id client_price = old_price unless client_price client_price = ClientPrice.find_by(product_id: item.product_id, client_id: client_id) if client_price client_price = convert_price(client_price.price, client_price.unit_id, from_id) else master_price = MasterPrice.find_by(product_id: item.product_id, primary: true) raise(StandardError, "No price entry could be found for product `#{item.product.code}`.") unless master_price client_price = convert_price(master_price.selling_price, master_price.unit_id, from_id) end end price = convert_price(client_price, from_id, to_id) new_quantity = convert_quantity(quantity, from_id, to_id) {quantity: new_quantity, price: price, total_price: (new_quantity * price).round(2)} end |