123 lines
3.7 KiB
PHP
123 lines
3.7 KiB
PHP
<?php
|
||
/**
|
||
* auto_adapt.php
|
||
* Auto-Adaptive Pricing — تعديل أسعار kazan الأساسية تلقائياً
|
||
*
|
||
* المعادلة: سعر_الكيلو_الجديد = أقل_متوسط_سعر_منافس × 0.92
|
||
* الحماية: ما ينزل عن 85% من السعر الحالي ولا يزيد عن 115%
|
||
*
|
||
* التشغيل: cron job كل 30-60 دقيقة
|
||
* CLI: php backend/ride/pricing/auto_adapt.php
|
||
* HTTP: curl -X POST https://.../backend/ride/pricing/auto_adapt.php -H "X-Internal-Key: ..."
|
||
*/
|
||
|
||
require_once __DIR__ . '/../../core/bootstrap.php';
|
||
|
||
try {
|
||
$con = Database::get('main');
|
||
} catch (Exception $e) {
|
||
error_log("[AutoAdapt] DB connection failed: " . $e->getMessage());
|
||
exit(1);
|
||
}
|
||
|
||
$countries = [
|
||
'Syria' => 'SY',
|
||
'Jordan' => 'JO',
|
||
'Egypt' => 'EG',
|
||
'Iraq' => 'IQ'
|
||
];
|
||
|
||
$undercutFactor = 0.92;
|
||
$minFloorRatio = 0.85;
|
||
$maxCeilRatio = 1.15;
|
||
|
||
$kmColumns = [
|
||
'speedPrice', 'comfortPrice', 'ladyPrice', 'electricPrice',
|
||
'vanPrice', 'deliveryPrice', 'mishwarVipPrice', 'fixedPrice', 'awfarPrice'
|
||
];
|
||
|
||
$logEntries = [];
|
||
|
||
foreach ($countries as $country => $cc) {
|
||
// 1. متوسط سعر الكيلو لكل منافس (آخر 24 ساعة)
|
||
$sql = "SELECT competitor_name, AVG(price_per_km) AS avg_ppm
|
||
FROM competitor_prices
|
||
WHERE country_code = :cc
|
||
AND created_at >= DATE_SUB(NOW(), INTERVAL 24 HOUR)
|
||
AND price_per_km > 0
|
||
GROUP BY competitor_name
|
||
ORDER BY avg_ppm ASC";
|
||
$stmt = $con->prepare($sql);
|
||
$stmt->execute([':cc' => $cc]);
|
||
$competitorAvgs = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||
|
||
if (empty($competitorAvgs)) {
|
||
error_log("[AutoAdapt] $country — لا توجد بيانات منافسين");
|
||
continue;
|
||
}
|
||
|
||
$lowestAvg = (float)$competitorAvgs[0]['avg_ppm'];
|
||
|
||
// 2. الأسعار الحالية من kazan
|
||
$kazanSql = "SELECT * FROM kazan WHERE country = :country LIMIT 1";
|
||
$stmtK = $con->prepare($kazanSql);
|
||
$stmtK->execute([':country' => $country]);
|
||
$kazanRow = $stmtK->fetch(PDO::FETCH_ASSOC);
|
||
|
||
if (!$kazanRow) {
|
||
error_log("[AutoAdapt] $country — لا يوجد صف في kazan");
|
||
continue;
|
||
}
|
||
|
||
$currentSpeed = (float)$kazanRow['speedPrice'];
|
||
$targetSpeed = $lowestAvg * $undercutFactor;
|
||
|
||
$minAllowed = $currentSpeed * $minFloorRatio;
|
||
$maxAllowed = $currentSpeed * $maxCeilRatio;
|
||
|
||
if ($targetSpeed < $minAllowed) {
|
||
$targetSpeed = $minAllowed;
|
||
} elseif ($targetSpeed > $maxAllowed) {
|
||
$targetSpeed = $maxAllowed;
|
||
}
|
||
|
||
$ratio = $targetSpeed / $currentSpeed;
|
||
|
||
$updates = [];
|
||
$params = [':country' => $country];
|
||
|
||
foreach ($kmColumns as $col) {
|
||
$oldVal = (float)($kazanRow[$col] ?? 0);
|
||
if ($oldVal > 0) {
|
||
$newVal = round($oldVal * $ratio, 2);
|
||
$updates[] = "`$col` = :$col";
|
||
$params[":$col"] = (string)$newVal;
|
||
}
|
||
}
|
||
|
||
if (empty($updates)) {
|
||
continue;
|
||
}
|
||
|
||
$updateSql = "UPDATE kazan SET " . implode(', ', $updates) . " WHERE country = :country";
|
||
$stmtU = $con->prepare($updateSql);
|
||
$stmtU->execute($params);
|
||
|
||
$logEntries[] = [
|
||
'country' => $country,
|
||
'code' => $cc,
|
||
'old_speed' => $currentSpeed,
|
||
'new_speed' => $targetSpeed,
|
||
'lowest_competitor' => $lowestAvg,
|
||
'ratio' => round($ratio, 4),
|
||
];
|
||
|
||
error_log("[AutoAdapt] ✅ $country ($cc): speedPrice $currentSpeed → $targetSpeed (ratio: $ratio)");
|
||
}
|
||
|
||
if (php_sapi_name() === 'cli') {
|
||
echo json_encode(['status' => 'success', 'updates' => $logEntries], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
|
||
} else {
|
||
echo json_encode(['status' => 'success', 'updates' => $logEntries]);
|
||
}
|