Files
tripz-llc/backend/food/cron_order_timeouts.php
2026-08-09 16:56:13 +03:00

66 lines
3.2 KiB
PHP

<?php
// food/cron_order_timeouts.php — يُشغَّل كل دقيقة من crontab المضيف (مثل cron_* في transit)
// 1) عروض توصيل معروضة أكثر من 20 ثانية بلا رد → timed_out + إعادة العرض لمرشح آخر
// 2) طلبات pending أكثر من 5 دقائق بلا رد المطعم → إلغاء نظامي + استرجاع فوري
require_once __DIR__ . '/../core/bootstrap.php';
require_once __DIR__ . '/functions.php';
try { $food_con = Database::get('food'); }
catch (Exception $e) { error_log('[FOOD][CRON] DB unavailable: ' . $e->getMessage()); exit(1); }
// ── 1) عروض منتهية المهلة ──
$expiredSt = $food_con->query(
"SELECT id, order_id, courier_id FROM food_courier_assignments
WHERE status='offered' AND offered_at < (NOW() - INTERVAL 20 SECOND)"
);
foreach ($expiredSt->fetchAll() as $assignment) {
$food_con->prepare("UPDATE food_courier_assignments SET status='timed_out', responded_at=NOW() WHERE id=?")
->execute([$assignment['id']]);
$orderSt = $food_con->prepare("SELECT merchant_id FROM food_orders WHERE id=? AND status='ready'");
$orderSt->execute([$assignment['order_id']]);
$order = $orderSt->fetch();
if (!$order) continue;
$merchantSt = $food_con->prepare("SELECT latitude, longitude FROM food_merchants WHERE id=?");
$merchantSt->execute([$order['merchant_id']]);
$merchant = $merchantSt->fetch();
if (!$merchant) continue;
$candidates = foodFindNearbyCouriers((float)$merchant['latitude'], (float)$merchant['longitude']);
$priorSt = $food_con->prepare("SELECT courier_id FROM food_courier_assignments WHERE order_id=?");
$priorSt->execute([$assignment['order_id']]);
$prior = array_column($priorSt->fetchAll(), 'courier_id');
foreach ($candidates as $candidateId) {
if (in_array($candidateId, $prior, true)) continue;
foodOfferOrderToCourier((int)$assignment['order_id'], $candidateId);
error_log("[FOOD][CRON] Re-offered order {$assignment['order_id']} to courier {$candidateId} after timeout");
break;
}
}
// ── 2) طلبات pending تجاوزت مهلة رد المطعم ──
$stalePendingSt = $food_con->query(
"SELECT id, passenger_id, payment_method, grand_total FROM food_orders
WHERE status='pending' AND created_at < (NOW() - INTERVAL 5 MINUTE)"
);
foreach ($stalePendingSt->fetchAll() as $order) {
food_transition_status((int)$order['id'], 'cancelled_system', 'system', 'cron', 'Merchant did not respond within timeout');
if ($order['payment_method'] === 'wallet') {
$refunded = foodWalletMove(
(string)$order['passenger_id'], (int)$order['grand_total'], 'add',
"food-refund-{$order['id']}", "Food order #{$order['id']} auto-cancelled (merchant timeout)"
);
$food_con->prepare(
"INSERT INTO food_order_payments (order_id, type, amount, status) VALUES (?,'release',?,?)"
)->execute([$order['id'], (int)$order['grand_total'], $refunded ? 'success' : 'failed']);
if (!$refunded) error_log("[FOOD][CRON] refund FAILED for auto-cancelled order {$order['id']} — needs manual reconciliation");
}
}
echo "food cron_order_timeouts done\n";