firstOrFail(); // Create Order $order = Order::create([ 'company_id' => $machine->company_id, 'flow_id' => $data['flow_id'] ?? null, 'order_no' => $data['order_no'] ?? $this->generateOrderNo(), 'machine_id' => $machine->id, 'member_id' => $data['member_id'] ?? null, 'total_amount' => $data['total_amount'], 'discount_amount' => $data['discount_amount'] ?? 0, 'pay_amount' => $data['pay_amount'], 'payment_type' => $data['payment_type'] ?? 0, 'payment_status' => $data['payment_status'] ?? 1, 'payment_at' => now(), 'status' => 'completed', 'metadata' => $data['metadata'] ?? null, ]); // Create Order Items if (!empty($data['items'])) { foreach ($data['items'] as $item) { $order->items()->create([ 'product_id' => $item['product_id'], 'product_name' => $item['product_name'] ?? 'Unknown', 'barcode' => $item['barcode'] ?? null, 'price' => $item['price'], 'quantity' => $item['quantity'], 'subtotal' => $item['price'] * $item['quantity'], ]); } } return $order; }); } /** * Generate a unique order number. */ protected function generateOrderNo(): string { return 'ORD-' . now()->format('YmdHis') . '-' . strtoupper(bin2hex(random_bytes(3))); } /** * Record Invoice (B601). */ public function recordInvoice(array $data): Invoice { return DB::transaction(function () use ($data) { $machine = Machine::where('serial_no', $data['serial_no'])->firstOrFail(); $order = null; if (!empty($data['flow_id'])) { $order = Order::where('flow_id', $data['flow_id'])->first(); } return Invoice::create([ 'company_id' => $machine->company_id, 'order_id' => $order?->id ?? ($data['order_id'] ?? null), 'machine_id' => $machine->id, 'flow_id' => $data['flow_id'] ?? null, 'invoice_no' => $data['invoice_no'] ?? null, 'amount' => $data['amount'] ?? 0, 'carrier_id' => $data['carrier_id'] ?? null, 'invoice_date' => $data['invoice_date'] ?? null, 'random_number' => $data['random_no'] ?? null, 'love_code' => $data['love_code'] ?? null, 'metadata' => $data['metadata'] ?? null, ]); }); } /** * Record dispense result (B602). */ public function recordDispense(array $data): DispenseRecord { return DB::transaction(function () use ($data) { $machine = Machine::where('serial_no', $data['serial_no'])->firstOrFail(); $order = null; if (!empty($data['flow_id'])) { $order = Order::where('flow_id', $data['flow_id'])->first(); } return DispenseRecord::create([ 'company_id' => $machine->company_id, 'order_id' => $order?->id ?? ($data['order_id'] ?? null), 'flow_id' => $data['flow_id'] ?? null, 'machine_id' => $machine->id, 'slot_no' => $data['slot_no'] ?? 'unknown', 'product_id' => $data['product_id'] ?? null, 'amount' => $data['amount'] ?? 0, 'dispense_status' => $data['dispense_status'] ?? 0, 'machine_time' => $data['machine_time'] ?? now(), ]); }); } }