Push paid menu orders to the Ladill POS kitchen
Deploy Ladill Merchant / deploy (push) Successful in 45s
Deploy Ladill Merchant / deploy (push) Successful in 45s
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 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
20ec89f534
commit
2ced61fed0
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Merchant;
|
||||
|
||||
use App\Models\QrCode;
|
||||
use App\Models\QrSaleOrder;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
|
||||
/**
|
||||
* Pushes a paid menu (food) storefront order to the merchant's Ladill POS
|
||||
* Kitchen Display. Best-effort: failures are logged, never surfaced — they must
|
||||
* not break order completion. POS ignores orders for accounts not running a POS
|
||||
* kitchen, so this is safe to call for every menu order.
|
||||
*/
|
||||
class KitchenPusher
|
||||
{
|
||||
public function push(QrSaleOrder $order): void
|
||||
{
|
||||
$url = (string) config('kitchen.url');
|
||||
$key = (string) config('kitchen.key');
|
||||
if ($url === '' || $key === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
$order->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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
// Ladill POS kitchen ingest — paid food-storefront orders are pushed here so
|
||||
// they appear on the merchant's POS Kitchen Display. Empty = disabled.
|
||||
'url' => rtrim((string) env('KITCHEN_API_URL', ''), '/'),
|
||||
'key' => env('KITCHEN_API_KEY'),
|
||||
];
|
||||
Reference in New Issue
Block a user