Update: 2026-08-08 12:58:16

This commit is contained in:
Hamza-Ayed
2026-08-08 12:58:17 +03:00
parent 611b5e616d
commit fae0e4a38a
55 changed files with 5771 additions and 1820 deletions
+16 -12
View File
@@ -9,6 +9,7 @@
require_once __DIR__ . '/../connect.php';
require_once __DIR__ . '/eligibility.php';
require_once __DIR__ . '/../obligations/functions.php';
$driverId = $user_id ?? '';
if (empty($driverId) || ($role ?? '') !== 'driver') {
@@ -22,7 +23,12 @@ if (!$policy) {
$reason = filterRequest('reason') ?: 'بطلب السائق';
// ‏الوثيقة والالتزام يُغلقان معاً. التزام يبقى نشطاً بعد إلغاء وثيقته
// ‏يعني قسطاً يُقيَّد كل ليلة على سائقٍ بلا تغطية — عكس الثغرة السابقة
// ‏تماماً، وأسوأ منها: هناك مال يضيع على الشركة، وهنا مال يُؤخذ ظلماً.
try {
$con->beginTransaction();
// ‏الشرط على driver_id إلى جانب المعرّف: الوثيقة أتت من استعلام
// ‏مقيَّد بالسائق أصلاً، لكن الشرط هنا يجعل الاستعلام آمناً بذاته
// ‏لو أعيد استعماله يوماً في سياق آخر.
@@ -34,24 +40,22 @@ try {
$st->execute([mb_substr($reason, 0, 255), $policy['id'], $driverId]);
if ($st->rowCount() === 0) {
$con->rollBack();
jsonError('تعذّر إلغاء الوثيقة');
}
} catch (PDOException $e) {
obligationClose($con, $driverId, $policy['code'], $reason);
$con->commit();
} catch (Throwable $e) {
if ($con->inTransaction()) $con->rollBack();
error_log('[assurance/cancel] ' . $e->getMessage());
jsonError('Server error');
}
$pending = 0.0;
try {
$st = $con->prepare("
SELECT COALESCE(SUM(amount), 0) FROM insurance_premium_ledger
WHERE policy_id = ? AND status = 'pending'
");
$st->execute([$policy['id']]);
$pending = (float) $st->fetchColumn();
} catch (PDOException $e) {
error_log('[assurance/cancel] تعذّرت قراءة المستحق: ' . $e->getMessage());
}
// ‏المستحق يُقرأ من الدفتر الموحّد لا من دفتر التأمين القديم: القديم
// ‏مجمَّد بعد الترحيل، وقراءته تعني رقماً لا يتغيّر مهما سدّد السائق.
$pending = obligationPendingTotal($con, $driverId, $policy['code']);
error_log("[assurance] أُلغيت وثيقة #{$policy['id']} للسائق $driverId");