nhance_partner_be/app/Libraries/PartnerPayoutGridRetention.php
2026-04-04 15:06:51 +05:30

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;
}
}