From 2ced61fed036a7e5b508e0bf09506cb9b63747bc Mon Sep 17 00:00:00 2001 From: isaacclad Date: Wed, 24 Jun 2026 23:57:30 +0000 Subject: [PATCH] Push paid menu orders to the Ladill POS kitchen MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a menu (food) storefront order is paid, best-effort POST it to the merchant's Ladill POS kitchen ingest (config/kitchen.php → KITCHEN_API_URL/KEY) so it lands on their Kitchen Display alongside dine-in tabs. Failures are logged, never surfaced — order completion is unaffected; POS ignores orders for accounts that don't run a POS kitchen. Co-Authored-By: Claude Opus 4.8 --- app/Services/Merchant/KitchenPusher.php | 59 +++++++++++++++++++ app/Services/Merchant/MerchantSaleService.php | 3 + config/kitchen.php | 8 +++ 3 files changed, 70 insertions(+) create mode 100644 app/Services/Merchant/KitchenPusher.php create mode 100644 config/kitchen.php diff --git a/app/Services/Merchant/KitchenPusher.php b/app/Services/Merchant/KitchenPusher.php new file mode 100644 index 0000000..04fea93 --- /dev/null +++ b/app/Services/Merchant/KitchenPusher.php @@ -0,0 +1,59 @@ +loadMissing('qrCode', 'merchant'); + + // Only food menus feed a kitchen. + if (($order->qrCode?->type) !== QrCode::TYPE_MENU || ! $order->merchant) { + return; + } + + $items = collect((array) $order->items) + ->filter(fn ($i) => strtolower(trim((string) ($i['name'] ?? ''))) !== 'shipping') + ->map(fn ($i) => [ + 'name' => (string) ($i['name'] ?? ''), + 'quantity' => max(1, (int) ($i['qty'] ?? 1)), + 'unit_price_minor' => (int) round(((float) ($i['price_ghs'] ?? 0)) * 100), + ]) + ->filter(fn ($i) => $i['name'] !== '') + ->values() + ->all(); + + if ($items === []) { + return; + } + + try { + Http::withToken($key)->acceptJson()->asJson()->timeout(8) + ->post($url.'/kitchen/orders', [ + 'owner' => (string) $order->merchant->public_id, + 'reference' => (string) ($order->payment_reference ?: ('QO-'.$order->id)), + 'customer_name' => $order->customer_name, + 'items' => $items, + ]); + } catch (\Throwable $e) { + report($e); + } + } +} diff --git a/app/Services/Merchant/MerchantSaleService.php b/app/Services/Merchant/MerchantSaleService.php index 393d8f3..cf1b406 100644 --- a/app/Services/Merchant/MerchantSaleService.php +++ b/app/Services/Merchant/MerchantSaleService.php @@ -20,6 +20,7 @@ class MerchantSaleService private PaystackService $paystack, private BillingClient $billing, private SmsService $sms, + private KitchenPusher $kitchen, ) {} /** @@ -217,6 +218,7 @@ class MerchantSaleService ]); $this->notifyOrderPlaced($order->fresh(['qrCode', 'merchant'])); + $this->kitchen->push($order->fresh(['qrCode', 'merchant'])); return $order; } @@ -257,6 +259,7 @@ class MerchantSaleService ); $this->notifyOrderPlaced($order->fresh(['qrCode', 'merchant'])); + $this->kitchen->push($order->fresh(['qrCode', 'merchant'])); return $order; } diff --git a/config/kitchen.php b/config/kitchen.php new file mode 100644 index 0000000..15ccf30 --- /dev/null +++ b/config/kitchen.php @@ -0,0 +1,8 @@ + rtrim((string) env('KITCHEN_API_URL', ''), '/'), + 'key' => env('KITCHEN_API_KEY'), +];