getMessage() . "\n"); exit(1); } $today = date('Y-m-d'); // ‏الشهري يُقيَّد على أول الشهر لا على يوم الاشتراك: دفتر تتوزّع فيه // ‏تواريخ القيد على ثلاثين يوماً يستحيل تسويته مع الشريك. $monthStart = date('Y-m-01'); $charged = 0; $skipped = 0; try { // ‏المصدر الآن الالتزامات لا الوثائق. القيد على `kind = 'recurring'` // ‏لا على المنتج التأميني تحديداً: أي منتج دوري يُضاف لاحقاً يُقيَّد // ‏بالمنطق نفسه بلا سطر جديد هنا. $st = $con->query(" SELECT o.id, o.driver_id, o.last_charged_on, o.cycle_amount, pr.code AS product_code, pr.currency, pr.billing_cycle FROM driver_obligations o JOIN obligation_products pr ON pr.id = o.product_id WHERE o.status = 'active' AND pr.kind = 'recurring' AND pr.billing_cycle <> 'none' ORDER BY o.id ASC "); foreach ($st->fetchAll(PDO::FETCH_ASSOC) as $policy) { $chargeDate = $policy['billing_cycle'] === 'monthly' ? $monthStart : $today; // ‏الفلترة الرخيصة أولاً — تجنّبنا محاولة إدراج لكل التزام كل يوم. if ($policy['last_charged_on'] === $chargeDate) { $skipped++; continue; } try { $con->beginTransaction(); $con->prepare(" INSERT INTO obligation_ledger (obligation_id, driver_id, product_code, charge_date, amount, amount_collected, amount_remaining, currency, status) VALUES (?, ?, ?, ?, ?, 0, ?, ?, 'pending') ")->execute([ $policy['id'], $policy['driver_id'], $policy['product_code'], $chargeDate, $policy['cycle_amount'], $policy['cycle_amount'], $policy['currency'], ]); $con->prepare(" UPDATE driver_obligations SET last_charged_on = ? WHERE id = ? ")->execute([$chargeDate, $policy['id']]); $con->commit(); $charged++; } catch (PDOException $e) { if ($con->inTransaction()) $con->rollBack(); // ‏23000 = خرق المفتاح الفريد: نسخة أخرى سبقتنا للقيد نفسه. // ‏هذه ليست حالة خطأ — هي بالضبط ما صُمّم المفتاح لمنعه. if ($e->getCode() === '23000') { $con->prepare(" UPDATE driver_obligations SET last_charged_on = ? WHERE id = ? ")->execute([$chargeDate, $policy['id']]); $skipped++; } else { error_log("[insurance] تعذّر قيد استحقاق الالتزام #{$policy['id']}: " . $e->getMessage()); } } } } catch (PDOException $e) { fwrite(STDERR, '[insurance] فشل المرور: ' . $e->getMessage() . "\n"); exit(1); } echo "[insurance] قُيِّد {$charged} قسطاً، تُخطّي {$skipped}\n";