88 lines
3.9 KiB
PHP
88 lines
3.9 KiB
PHP
<?php
|
|
/**
|
|
* driver_assurance/plans.php — الخطط المتاحة وأهلية السائق لكلٍّ منها
|
|
*
|
|
* نرد بكل الخطط لا المؤهَّل لها فقط، ومع كل واحدة سبب عدم الأهلية إن
|
|
* وُجد. إخفاء ما لا يستحقه السائق يجعل التأمين مجهولاً عنده؛ إظهاره
|
|
* مع «ينقصك ٤٠ رحلة» يحوّله إلى هدف يسعى إليه — وهذا هو مقصد الشرط
|
|
* أصلاً: ربط السائق بالمنصّة.
|
|
*/
|
|
|
|
require_once __DIR__ . '/../connect.php';
|
|
require_once __DIR__ . '/eligibility.php';
|
|
require_once __DIR__ . '/../obligations/functions.php';
|
|
|
|
// الهوية من الـJWT لا من الطلب — الأهلية معلومة عن السائق نفسه،
|
|
// وقراءتها بمعرّف مُرسَل تكشف أرقام غيره.
|
|
$driverId = $user_id ?? '';
|
|
if (empty($driverId) || ($role ?? '') !== 'driver') {
|
|
jsonError('Unauthorized', 401);
|
|
}
|
|
|
|
$country = getenv('APP_COUNTRY') ?: 'Jordan';
|
|
|
|
try {
|
|
$st = $con->prepare("
|
|
SELECT pl.*, pr.name AS provider_name, pr.name_ar AS provider_name_ar
|
|
FROM insurance_plans pl
|
|
JOIN insurance_providers pr ON pr.id = pl.provider_id
|
|
WHERE pl.is_active = 1 AND pr.is_active = 1 AND pr.country = ?
|
|
ORDER BY pl.premium ASC
|
|
");
|
|
$st->execute([$country]);
|
|
$plans = $st->fetchAll(PDO::FETCH_ASSOC);
|
|
} catch (PDOException $e) {
|
|
error_log('[assurance/plans] ' . $e->getMessage());
|
|
jsonError('Server error');
|
|
}
|
|
|
|
$current = assuranceActivePolicy($con, $driverId);
|
|
|
|
// نداء واحد للمحفظة لكل الشاشة: الملخّص عن السائق لا عن الخطة.
|
|
// بدونه كانت الشاشة تعرض «مؤهَّل» ثم يُرفض الطلب عند الضغط — وهو أسوأ
|
|
// من الرفض المبكر: يعد السائق بشيء ثم يسحبه.
|
|
$incomeSummary = obligationWalletIncomeSummary($driverId);
|
|
|
|
$out = [];
|
|
foreach ($plans as $plan) {
|
|
$check = assuranceCheckEligibility($con, $driverId, $plan);
|
|
|
|
// بوابة الائتمان تُقاس على منتج الالتزام المقابل للخطة. غيابه يعني
|
|
// خطة لم تُرحَّل بعد — لا نحجبها ولا ندّعي أهليةً لها، بل نتركها
|
|
// لحكم شروط الخطة وحدها ونسجّل الحالة.
|
|
$product = obligationProduct($con, $plan['code']);
|
|
if ($product) {
|
|
$gate = obligationCheckWalletIncome($product, $driverId, $incomeSummary);
|
|
if (!$gate['eligible']) {
|
|
$check['eligible'] = false;
|
|
$check['reasons'] = array_merge($check['reasons'], $gate['reasons']);
|
|
}
|
|
} else {
|
|
error_log("[assurance/plans] لا منتج التزام للخطة {$plan['code']}");
|
|
}
|
|
|
|
$out[] = [
|
|
'id' => (int) $plan['id'],
|
|
'code' => $plan['code'],
|
|
'name' => $plan['name_ar'],
|
|
'description' => $plan['description_ar'],
|
|
'provider' => $plan['provider_name_ar'] ?: $plan['provider_name'],
|
|
'billing_cycle' => $plan['billing_cycle'],
|
|
'premium' => (float) $plan['premium'],
|
|
'currency' => $plan['currency'],
|
|
'coverage' => $plan['coverage_summary'],
|
|
'eligible' => $check['eligible'],
|
|
'missing' => $check['reasons'],
|
|
'is_current' => $current && (int) $current['plan_id'] === (int) $plan['id'],
|
|
// تقدّم السائق نحو الشرط — رقم يفهمه بلا شرح.
|
|
'progress_rides' => $check['rides'],
|
|
'required_rides' => (int) $plan['min_completed_rides'],
|
|
];
|
|
}
|
|
|
|
jsonSuccess([
|
|
'plans' => $out,
|
|
'has_policy' => (bool) $current,
|
|
'driver_rating' => $current ? (float) $current['rating_at_signup'] : null,
|
|
], 'success');
|