167 lines
5.1 KiB
PHP
167 lines
5.1 KiB
PHP
<?php
|
|
|
|
namespace App\Libraries;
|
|
|
|
use CodeIgniter\Database\BaseConnection;
|
|
|
|
/**
|
|
* Partner (agent) grid: match payout grid vehicle_type to partner_vehicle_type via
|
|
* partner_retention_rate (agent_id + vehicle_type_id), subtract retention from comp/tp/od.
|
|
* Values <= 0 after subtraction are returned as '-'.
|
|
*/
|
|
class PartnerPayoutGridRetention
|
|
{
|
|
public static function normalizeVehicleTypeLabel(?string $s): string
|
|
{
|
|
if ($s === null || $s === '') {
|
|
return '';
|
|
}
|
|
|
|
return strtolower(trim(preg_replace('/\s+/u', ' ', $s)));
|
|
}
|
|
|
|
/**
|
|
* @return array<string, float> normalized name => rate, and id:{vehicle_type_id} => rate
|
|
*/
|
|
public static function buildRetentionMap(BaseConnection $db, int $agentId): array
|
|
{
|
|
if ($agentId <= 0) {
|
|
return [];
|
|
}
|
|
|
|
$rows = $db->table('partner_retention_rate prr')
|
|
->select('prr.vehicle_type_id, prr.retention_rate, pvt.vehicle_type')
|
|
->join('partner_vehicle_type pvt', 'pvt.id = prr.vehicle_type_id', 'left')
|
|
->where('prr.agent_id', $agentId)
|
|
->where('prr.is_active', 1)
|
|
->get()
|
|
->getResultArray();
|
|
|
|
$map = [];
|
|
foreach ($rows as $r) {
|
|
if (! array_key_exists('retention_rate', $r) || $r['retention_rate'] === null || $r['retention_rate'] === '') {
|
|
continue;
|
|
}
|
|
$rate = (float) $r['retention_rate'];
|
|
$name = isset($r['vehicle_type']) ? trim((string) $r['vehicle_type']) : '';
|
|
if ($name !== '') {
|
|
$map[self::normalizeVehicleTypeLabel($name)] = $rate;
|
|
}
|
|
$vid = isset($r['vehicle_type_id']) ? (int) $r['vehicle_type_id'] : 0;
|
|
if ($vid > 0) {
|
|
$map['id:' . $vid] = $rate;
|
|
}
|
|
}
|
|
|
|
return $map;
|
|
}
|
|
|
|
/**
|
|
* @param array<int, array<string, mixed>> $rows
|
|
*
|
|
* @return array<int, array<string, mixed>>
|
|
*/
|
|
public static function applyToRows(array $rows, int $agentId, BaseConnection $db): array
|
|
{
|
|
if ($agentId <= 0 || $rows === []) {
|
|
return $rows;
|
|
}
|
|
|
|
$map = self::buildRetentionMap($db, $agentId);
|
|
if ($map === []) {
|
|
return $rows;
|
|
}
|
|
|
|
foreach ($rows as &$row) {
|
|
$key = self::normalizeVehicleTypeLabel(isset($row['vehicle_type']) ? (string) $row['vehicle_type'] : '');
|
|
$rate = null;
|
|
if ($key !== '' && isset($map[$key])) {
|
|
$rate = $map[$key];
|
|
} else {
|
|
$vid = isset($row['vehicle_type_id']) ? (int) $row['vehicle_type_id'] : 0;
|
|
if ($vid > 0 && isset($map['id:' . $vid])) {
|
|
$rate = $map['id:' . $vid];
|
|
}
|
|
}
|
|
if ($rate === null) {
|
|
continue;
|
|
}
|
|
|
|
foreach (['comp', 'tp', 'od'] as $col) {
|
|
if (! array_key_exists($col, $row)) {
|
|
continue;
|
|
}
|
|
$raw = $row[$col];
|
|
if ($raw === null || $raw === '' || $raw === '-') {
|
|
continue;
|
|
}
|
|
$base = self::toFloat($raw);
|
|
if ($base === null) {
|
|
continue;
|
|
}
|
|
$adj = $base - $rate;
|
|
if ($adj <= 0) {
|
|
$row[$col] = '-';
|
|
} elseif (abs($adj - round($adj)) < 0.00001) {
|
|
$row[$col] = (string) (int) round($adj);
|
|
} else {
|
|
$row[$col] = rtrim(rtrim(number_format($adj, 2, '.', ''), '0'), '.');
|
|
}
|
|
}
|
|
}
|
|
unset($row);
|
|
|
|
return $rows;
|
|
}
|
|
|
|
public static function retentionForRow(array $row, array $map): ?float
|
|
{
|
|
$key = self::normalizeVehicleTypeLabel(isset($row['vehicle_type']) ? (string) $row['vehicle_type'] : '');
|
|
if ($key !== '' && isset($map[$key])) {
|
|
return $map[$key];
|
|
}
|
|
$vid = isset($row['vehicle_type_id']) ? (int) $row['vehicle_type_id'] : 0;
|
|
if ($vid > 0 && isset($map['id:' . $vid])) {
|
|
return $map['id:' . $vid];
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* @return float|int|string|null '-' when adjusted <= 0, else numeric display
|
|
*/
|
|
public static function adjustPayoutValue($raw, float $rate)
|
|
{
|
|
if ($raw === null || $raw === '' || $raw === '-') {
|
|
return $raw;
|
|
}
|
|
$base = self::toFloat($raw);
|
|
if ($base === null) {
|
|
return $raw;
|
|
}
|
|
$adj = $base - $rate;
|
|
if ($adj <= 0) {
|
|
return '-';
|
|
}
|
|
if (abs($adj - round($adj)) < 0.00001) {
|
|
return (int) round($adj);
|
|
}
|
|
|
|
return rtrim(rtrim(number_format($adj, 2, '.', ''), '0'), '.');
|
|
}
|
|
|
|
private static function toFloat($raw): ?float
|
|
{
|
|
if (is_numeric($raw)) {
|
|
return (float) $raw;
|
|
}
|
|
$clean = preg_replace('/[^0-9.\-]/', '', (string) $raw);
|
|
if ($clean === '' || $clean === '-' || $clean === '.') {
|
|
return null;
|
|
}
|
|
|
|
return (float) $clean;
|
|
}
|
|
}
|