Class: CloverSandboxSimulator::Services::Clover::OrderService
- Inherits:
-
BaseService
- Object
- BaseService
- CloverSandboxSimulator::Services::Clover::OrderService
- Defined in:
- lib/clover_sandbox_simulator/services/clover/order_service.rb
Overview
Manages Clover orders and line items
Constant Summary collapse
- DINING_OPTIONS =
%w[HERE TO_GO DELIVERY].freeze
Instance Attribute Summary
Attributes inherited from BaseService
Instance Method Summary collapse
-
#add_customer_to_order(order_id, customer_id) ⇒ Object
Add customer to order.
-
#add_line_item(order_id, item_id:, quantity: 1, note: nil) ⇒ Object
Add line item to order.
-
#add_line_items(order_id, items, raise_on_empty: false) ⇒ Array
Batch add line items (adds one by one as Clover doesn’t support bulk).
-
#add_modification(order_id, line_item_id:, modifier_id:) ⇒ Hash
Add a single modification (modifier) to a line item.
-
#add_modifications(order_id, line_item_id:, modifier_ids:) ⇒ Array<Hash>
Add multiple modifications to a line item.
-
#apply_discount(order_id, discount_id:, calculated_amount: nil) ⇒ Object
Apply discount to order IMPORTANT: Always sends calculated amount, not percentage, so that the discount amount is correctly returned when fetching the order.
-
#apply_inline_discount(order_id, name:, percentage: nil, amount: nil, order_total: nil) ⇒ Object
Apply an inline discount without requiring a pre-existing discount ID IMPORTANT: For percentage discounts, caller should provide the order_total so we can calculate the actual amount.
-
#calculate_total(order_id) ⇒ Object
Calculate order total from line items.
-
#create_order(employee_id: nil, customer_id: nil) ⇒ Object
Create an order shell.
-
#delete_order(order_id) ⇒ Object
Delete an order.
-
#get_order(order_id) ⇒ Object
Get a single order with expanded data.
-
#get_orders(limit: 50, offset: 0, filter: nil) ⇒ Object
Fetch all orders.
-
#set_dining_option(order_id, option) ⇒ Object
Set dining option.
-
#update_state(order_id, state) ⇒ Object
Update order state.
-
#update_total(order_id, total) ⇒ Object
Update order total.
Methods inherited from BaseService
Constructor Details
This class inherits a constructor from CloverSandboxSimulator::Services::BaseService
Instance Method Details
#add_customer_to_order(order_id, customer_id) ⇒ Object
Add customer to order
193 194 195 196 197 198 |
# File 'lib/clover_sandbox_simulator/services/clover/order_service.rb', line 193 def add_customer_to_order(order_id, customer_id) logger.debug "Adding customer #{customer_id} to order #{order_id}" request(:post, endpoint("orders/#{order_id}"), payload: { "customers" => { "elements" => [{ "id" => customer_id }] } }) end |
#add_line_item(order_id, item_id:, quantity: 1, note: nil) ⇒ Object
Add line item to order
44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/clover_sandbox_simulator/services/clover/order_service.rb', line 44 def add_line_item(order_id, item_id:, quantity: 1, note: nil) logger.debug "Adding item #{item_id} to order #{order_id}" payload = { "item" => { "id" => item_id }, "quantity" => quantity } payload["note"] = note if note request(:post, endpoint("orders/#{order_id}/line_items"), payload: payload) end |
#add_line_items(order_id, items, raise_on_empty: false) ⇒ Array
Batch add line items (adds one by one as Clover doesn’t support bulk)
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/clover_sandbox_simulator/services/clover/order_service.rb', line 61 def add_line_items(order_id, items, raise_on_empty: false) logger.info "Adding #{items.size} items to order #{order_id}" line_items = [] failed_count = 0 items.each do |item| line_item = add_line_item( order_id, item_id: item[:item_id], quantity: item[:quantity] || 1, note: item[:note] ) if line_item line_items << line_item else failed_count += 1 logger.debug "Failed to add item #{item[:item_id]} to order #{order_id}" end end if line_items.empty? && items.any? = "All #{items.size} line items failed to be added to order #{order_id}" logger.warn raise StandardError, if raise_on_empty elsif failed_count > 0 logger.warn "#{failed_count} of #{items.size} line items failed to be added to order #{order_id}" end line_items end |
#add_modification(order_id, line_item_id:, modifier_id:) ⇒ Hash
Add a single modification (modifier) to a line item
99 100 101 102 103 104 |
# File 'lib/clover_sandbox_simulator/services/clover/order_service.rb', line 99 def add_modification(order_id, line_item_id:, modifier_id:) logger.debug "Adding modifier #{modifier_id} to line item #{line_item_id}" payload = { "modifier" => { "id" => modifier_id } } request(:post, endpoint("orders/#{order_id}/line_items/#{line_item_id}/modifications"), payload: payload) end |
#add_modifications(order_id, line_item_id:, modifier_ids:) ⇒ Array<Hash>
Add multiple modifications to a line item
111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/clover_sandbox_simulator/services/clover/order_service.rb', line 111 def add_modifications(order_id, line_item_id:, modifier_ids:) logger.info "Adding #{modifier_ids.size} modifiers to line item #{line_item_id}" modifications = [] modifier_ids.each do |modifier_id| mod = add_modification(order_id, line_item_id: line_item_id, modifier_id: modifier_id) modifications << mod if mod end modifications end |
#apply_discount(order_id, discount_id:, calculated_amount: nil) ⇒ Object
Apply discount to order IMPORTANT: Always sends calculated amount, not percentage, so that the discount amount is correctly returned when fetching the order.
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/clover_sandbox_simulator/services/clover/order_service.rb', line 126 def apply_discount(order_id, discount_id:, calculated_amount: nil) logger.info "Applying discount #{discount_id} to order #{order_id}" # Fetch discount details discount_service = DiscountService.new(config: config) discount = discount_service.get_discount(discount_id) return nil unless discount payload = { "name" => discount["name"] } if calculated_amount payload["amount"] = -calculated_amount.abs elsif discount["amount"] payload["amount"] = discount["amount"] elsif discount["percentage"] # For percentage discounts, we MUST calculate the amount # because Clover returns amount=0 for percentage discounts when fetched order_total = calculate_total(order_id) calculated = (order_total * discount["percentage"] / 100.0).round logger.info "Calculated discount: #{discount["percentage"]}% of #{order_total} = #{calculated}" payload["amount"] = -calculated.abs end request(:post, endpoint("orders/#{order_id}/discounts"), payload: payload) end |
#apply_inline_discount(order_id, name:, percentage: nil, amount: nil, order_total: nil) ⇒ Object
Apply an inline discount without requiring a pre-existing discount ID IMPORTANT: For percentage discounts, caller should provide the order_total so we can calculate the actual amount. Otherwise Clover returns amount=0.
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 |
# File 'lib/clover_sandbox_simulator/services/clover/order_service.rb', line 156 def apply_inline_discount(order_id, name:, percentage: nil, amount: nil, order_total: nil) logger.info "Applying inline discount '#{name}' to order #{order_id}" payload = { "name" => name } if amount payload["amount"] = -amount.abs elsif percentage # Calculate the actual amount for percentage discounts if order_total calculated = (order_total * percentage / 100.0).round logger.info "Calculated inline discount: #{percentage}% of #{order_total} = #{calculated}" payload["amount"] = -calculated.abs else # Fallback: fetch order total and calculate total = calculate_total(order_id) calculated = (total * percentage / 100.0).round logger.info "Calculated inline discount: #{percentage}% of #{total} = #{calculated}" payload["amount"] = -calculated.abs end else raise ArgumentError, "Must provide either percentage or amount" end request(:post, endpoint("orders/#{order_id}/discounts"), payload: payload) end |
#calculate_total(order_id) ⇒ Object
Calculate order total from line items
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 238 239 240 241 242 243 244 245 246 |
# File 'lib/clover_sandbox_simulator/services/clover/order_service.rb', line 213 def calculate_total(order_id) order = get_order(order_id) return 0 unless order && order["lineItems"]&.dig("elements") total = 0 order["lineItems"]["elements"].each do |line_item| price = line_item["price"] || 0 quantity = line_item["quantity"] || 1 item_total = price * quantity # Add modification prices if line_item["modifications"]&.dig("elements") line_item["modifications"]["elements"].each do |mod| item_total += (mod["price"] || 0) end end total += item_total end # Subtract discounts if order["discounts"]&.dig("elements") order["discounts"]["elements"].each do |discount| if discount["percentage"] total -= (total * discount["percentage"] / 100.0).round else total -= (discount["amount"] || 0).abs end end end total end |
#create_order(employee_id: nil, customer_id: nil) ⇒ Object
Create an order shell
28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/clover_sandbox_simulator/services/clover/order_service.rb', line 28 def create_order(employee_id: nil, customer_id: nil) logger.info "Creating order..." payload = {} payload["employee"] = { "id" => employee_id } if employee_id order = request(:post, endpoint("orders"), payload: payload) if order && customer_id add_customer_to_order(order["id"], customer_id) end order end |
#delete_order(order_id) ⇒ Object
Delete an order
249 250 251 252 |
# File 'lib/clover_sandbox_simulator/services/clover/order_service.rb', line 249 def delete_order(order_id) logger.info "Deleting order: #{order_id}" request(:delete, endpoint("orders/#{order_id}")) end |
#get_order(order_id) ⇒ Object
Get a single order with expanded data
21 22 23 24 25 |
# File 'lib/clover_sandbox_simulator/services/clover/order_service.rb', line 21 def get_order(order_id) request(:get, endpoint("orders/#{order_id}"), params: { expand: "lineItems,discounts,payments,customers" }) end |
#get_orders(limit: 50, offset: 0, filter: nil) ⇒ Object
Fetch all orders
11 12 13 14 15 16 17 18 |
# File 'lib/clover_sandbox_simulator/services/clover/order_service.rb', line 11 def get_orders(limit: 50, offset: 0, filter: nil) logger.info "Fetching orders..." params = { limit: limit, offset: offset } params[:filter] = filter if filter response = request(:get, endpoint("orders"), params: params) response&.dig("elements") || [] end |
#set_dining_option(order_id, option) ⇒ Object
Set dining option
184 185 186 187 188 189 190 |
# File 'lib/clover_sandbox_simulator/services/clover/order_service.rb', line 184 def set_dining_option(order_id, option) unless DINING_OPTIONS.include?(option) raise ArgumentError, "Invalid dining option: #{option}. Must be one of #{DINING_OPTIONS.join(', ')}" end request(:post, endpoint("orders/#{order_id}"), payload: { "diningOption" => option }) end |
#update_state(order_id, state) ⇒ Object
Update order state
207 208 209 210 |
# File 'lib/clover_sandbox_simulator/services/clover/order_service.rb', line 207 def update_state(order_id, state) logger.info "Updating order #{order_id} state to #{state}" request(:post, endpoint("orders/#{order_id}"), payload: { "state" => state }) end |
#update_total(order_id, total) ⇒ Object
Update order total
201 202 203 204 |
# File 'lib/clover_sandbox_simulator/services/clover/order_service.rb', line 201 def update_total(order_id, total) logger.debug "Updating order #{order_id} total to #{total}" request(:post, endpoint("orders/#{order_id}"), payload: { "total" => total }) end |