diff --git a/app/Controllers/AgentController.php b/app/Controllers/AgentController.php index 834677b..a2c7e37 100644 --- a/app/Controllers/AgentController.php +++ b/app/Controllers/AgentController.php @@ -6,25 +6,27 @@ use App\Controllers\BaseController; use App\Models\AgentModel; use App\Models\AgentIncentiveFileModel; use App\Models\PartnerRetentionRateModel; -use App\Models\PartnerVehicleTypeModel; + class AgentController extends ResourceController { + protected $db; protected $AgentModel; protected $AgentIncentiveFileModel; protected $PartnerRetentionRateModel; - protected $PartnerVehicleTypeModel; + public function __construct() { + $this->db = db_connect(); $this->AgentModel = new AgentModel(); $this->AgentIncentiveFileModel = new AgentIncentiveFileModel(); $this->PartnerRetentionRateModel = new PartnerRetentionRateModel(); - $this->PartnerVehicleTypeModel = new PartnerVehicleTypeModel(); + } /** - * @return list + * @return list */ protected function parseRetentionRatesFromRequest(): array { @@ -49,6 +51,10 @@ class AgentController extends ResourceController if ($vtId === null || $vtId === '') { continue; } + $segmentId = $row['segment_id'] ?? $row['segmentId'] ?? null; + if ($segmentId === null || $segmentId === '') { + continue; + } $rateRaw = $row['retention_rate'] ?? $row['retentionRate'] ?? null; if ($rateRaw === null || $rateRaw === '') { continue; @@ -59,6 +65,7 @@ class AgentController extends ResourceController } $out[] = [ 'vehicle_type_id' => (int) $vtId, + 'segment_id' => (int) $segmentId, 'retention_rate' => round($rate, 2), ]; } @@ -77,6 +84,7 @@ class AgentController extends ResourceController $this->PartnerRetentionRateModel->insert([ 'agent_id' => $agentId, 'vehicle_type_id' => $r['vehicle_type_id'], + 'segment_id' => $r['segment_id'], 'retention_rate' => $r['retention_rate'], 'is_active' => 1, 'created_by' => $userId, @@ -91,10 +99,15 @@ class AgentController extends ResourceController public function partnerVehicleTypeList() { try { - $data = $this->PartnerVehicleTypeModel - ->where('is_active', 1) - ->orderBy('vehicle_type', 'ASC') - ->findAll(); + $data = $this->db->table('partner_segment ps') + ->select('vt.id as vehicle_type_id, vt.vehicle_type, ps.id as segment_id, ps.segment') + ->join('vehicle_type vt', 'vt.id = ps.vehicle_type_id', 'inner') + ->where('ps.is_active', 1) + ->where('vt.is_active', 1) + ->orderBy('vt.vehicle_type', 'ASC') + ->orderBy('ps.segment', 'ASC') + ->get() + ->getResultArray(); return $this->respond(['status' => 'success', 'code' => 200, 'data' => $data], 200); } catch (\Exception $e) { @@ -127,11 +140,12 @@ class AgentController extends ResourceController $data = []; } - if (!isset($data['agent_id'], $data['vehicle_type_id'], $data['retention_rate'])) { - return $this->respond(['status' => 'failed', 'code' => 200, 'data' => 'agent_id, vehicle_type_id and retention_rate are required'], 200); + if (!isset($data['agent_id'], $data['vehicle_type_id'], $data['segment_id'], $data['retention_rate'])) { + return $this->respond(['status' => 'failed', 'code' => 200, 'data' => 'agent_id, vehicle_type_id, segment_id and retention_rate are required'], 200); } $agentId = (int) $data['agent_id']; $vtId = (int) $data['vehicle_type_id']; + $segmentId = (int) $data['segment_id']; $rate = (float) $data['retention_rate']; if ($rate < 0 || $rate > 100) { return $this->respond(['status' => 'failed', 'code' => 200, 'data' => 'retention_rate must be between 0 and 100'], 200); @@ -146,6 +160,7 @@ class AgentController extends ResourceController $existing = $this->PartnerRetentionRateModel ->where('agent_id', $agentId) ->where('vehicle_type_id', $vtId) + ->where('segment_id', $segmentId) ->first(); if ($existing) { @@ -159,6 +174,7 @@ class AgentController extends ResourceController $this->PartnerRetentionRateModel->insert([ 'agent_id' => $agentId, 'vehicle_type_id' => $vtId, + 'segment_id' => $segmentId, 'retention_rate' => round($rate, 2), 'is_active' => 1, 'created_by' => $updatedBy, @@ -234,6 +250,10 @@ class AgentController extends ResourceController if ($vtId === null || $vtId === '') { continue; } + $segmentId = $row['segment_id'] ?? $row['segmentId'] ?? null; + if ($segmentId === null || $segmentId === '') { + continue; + } $rateRaw = $row['retention_rate'] ?? $row['retentionRate'] ?? null; if ($rateRaw === null || $rateRaw === '') { continue; @@ -243,10 +263,12 @@ class AgentController extends ResourceController continue; } $vtId = (int) $vtId; + $segmentId = (int) $segmentId; $existing = $this->PartnerRetentionRateModel ->where('agent_id', $agentId) ->where('vehicle_type_id', $vtId) + ->where('segment_id', $segmentId) ->first(); if ($existing) { @@ -260,6 +282,7 @@ class AgentController extends ResourceController $this->PartnerRetentionRateModel->insert([ 'agent_id' => $agentId, 'vehicle_type_id' => $vtId, + 'segment_id' => $segmentId, 'retention_rate' => round($rate, 2), 'is_active' => 1, 'created_by' => $updatedBy, @@ -356,11 +379,13 @@ class AgentController extends ResourceController } $rates = $this->PartnerRetentionRateModel - ->select('partner_retention_rate.id as retention_row_id, partner_retention_rate.vehicle_type_id, partner_retention_rate.retention_rate, partner_vehicle_type.vehicle_type') - ->join('partner_vehicle_type', 'partner_vehicle_type.id = partner_retention_rate.vehicle_type_id', 'left') + ->select('partner_retention_rate.id as retention_row_id, partner_retention_rate.vehicle_type_id, partner_retention_rate.segment_id, partner_retention_rate.retention_rate, vehicle_type.vehicle_type, partner_segment.segment') + ->join('vehicle_type', 'vehicle_type.id = partner_retention_rate.vehicle_type_id', 'left') + ->join('partner_segment', 'partner_segment.id = partner_retention_rate.segment_id', 'left') ->where('partner_retention_rate.agent_id', (int) $id) ->where('partner_retention_rate.is_active', 1) - ->orderBy('partner_vehicle_type.vehicle_type', 'ASC') + ->orderBy('vehicle_type.vehicle_type', 'ASC') + ->orderBy('partner_segment.segment', 'ASC') ->findAll(); $record['retention_by_vehicle'] = $rates; diff --git a/app/Controllers/DashboardController.php b/app/Controllers/DashboardController.php index 4153445..cf7f787 100644 --- a/app/Controllers/DashboardController.php +++ b/app/Controllers/DashboardController.php @@ -1464,6 +1464,7 @@ public function partnerRenewals($id) pp.policy_number AS policy_no, pp.insured_name AS holder_name, pp.premium_amount AS premium, + pp.vehicle_type AS vehicle_type, DATE_FORMAT(pp.end_date, "%d-%m-%Y") AS end_date, DATEDIFF(pp.end_date, CURDATE()) AS days_left ') diff --git a/app/Controllers/ExcelExportController.php b/app/Controllers/ExcelExportController.php index 6f9b7cc..0e7b6c4 100644 --- a/app/Controllers/ExcelExportController.php +++ b/app/Controllers/ExcelExportController.php @@ -2699,13 +2699,25 @@ class ExcelExportController extends ResourceController public function exportAgentRetentionRateExcel() { try { - $vehicleTypes = $this->db->table('partner_vehicle_type') + $vehicleTypes = $this->db->table('vehicle_type') ->select('id, vehicle_type') ->where('is_active', 1) ->orderBy('vehicle_type', 'ASC') ->get() ->getResultArray(); + $segments = $this->db->table('partner_segment ps') + ->select('ps.id, ps.segment, ps.vehicle_type_id, vt.vehicle_type') + ->join('vehicle_type vt', 'vt.id = ps.vehicle_type_id', 'inner') + ->where('ps.is_active', 1) + ->where('vt.is_active', 1) + ->orderBy('vt.vehicle_type', 'ASC') + ->orderBy('ps.vehicle_type_id', 'ASC') + ->orderBy('ps.id', 'ASC') + ->orderBy('ps.segment', 'ASC') + ->get() + ->getResultArray(); + $agents = $this->db->table('partner_agent') ->select('id, agent_code') ->where('is_active', 1) @@ -2716,7 +2728,7 @@ class ExcelExportController extends ResourceController ->getResultArray(); $rates = $this->db->table('partner_retention_rate') - ->select('agent_id, vehicle_type_id, retention_rate') + ->select('agent_id, vehicle_type_id, segment_id, retention_rate') ->where('is_active', 1) ->get() ->getResultArray(); @@ -2725,48 +2737,69 @@ class ExcelExportController extends ResourceController foreach ($rates as $r) { $aId = (int) ($r['agent_id'] ?? 0); $vId = (int) ($r['vehicle_type_id'] ?? 0); - if ($aId <= 0 || $vId <= 0) { + $sId = (int) ($r['segment_id'] ?? 0); + if ($aId <= 0 || $vId <= 0 || $sId <= 0) { continue; } - $rateMap[$aId . '_' . $vId] = (float) ($r['retention_rate'] ?? 0); + $rateMap[$aId . '_' . $vId . '_' . $sId] = (float) ($r['retention_rate'] ?? 0); + } + + $segmentRows = []; + foreach ($segments as $seg) { + $vId = (int) ($seg['vehicle_type_id'] ?? 0); + $sId = (int) ($seg['id'] ?? 0); + $vehicleTypeName = (string) ($seg['vehicle_type'] ?? ''); + if ($vId <= 0 || $sId <= 0 || $vehicleTypeName === '') { + continue; + } + $segmentRows[] = [ + 'vehicle_type_id' => $vId, + 'vehicle_type' => $vehicleTypeName, + 'segment_id' => $sId, + 'segment' => (string) ($seg['segment'] ?? ''), + ]; } $spreadsheet = new Spreadsheet(); $sheet = $spreadsheet->getActiveSheet(); - $sheet->setCellValue('A1', 'Agent Code / Vehicle Type'); - $colIndex = 2; - foreach ($vehicleTypes as $vt) { + $sheet->setCellValue('A1', 'Vehicle Type'); + $sheet->setCellValue('B1', 'Segment'); + + $colIndex = 3; + foreach ($agents as $agent) { $cell = Coordinate::stringFromColumnIndex($colIndex++) . '1'; - $sheet->setCellValue($cell, (string) ($vt['vehicle_type'] ?? '')); + $sheet->setCellValue($cell, (string) ($agent['agent_code'] ?? '')); } $rowIndex = 2; - foreach ($agents as $agent) { - $agentId = (int) ($agent['id'] ?? 0); - $sheet->setCellValue('A' . $rowIndex, (string) ($agent['agent_code'] ?? '')); + foreach ($segmentRows as $sr) { + $vehicleTypeId = (int) $sr['vehicle_type_id']; + $segmentId = (int) $sr['segment_id']; + $sheet->setCellValue('A' . $rowIndex, (string) $sr['vehicle_type']); + $sheet->setCellValue('B' . $rowIndex, (string) $sr['segment']); - $colIndex = 2; - foreach ($vehicleTypes as $vt) { - $vtId = (int) ($vt['id'] ?? 0); - $key = $agentId . '_' . $vtId; + $colIndex = 3; + foreach ($agents as $agent) { + $agentId = (int) ($agent['id'] ?? 0); + $key = $agentId . '_' . $vehicleTypeId . '_' . $segmentId; $cell = Coordinate::stringFromColumnIndex($colIndex++) . $rowIndex; $sheet->setCellValue($cell, (float) ($rateMap[$key] ?? 0)); } $rowIndex++; } - $lastCol = Coordinate::stringFromColumnIndex(max(1, count($vehicleTypes) + 1)); + $lastCol = Coordinate::stringFromColumnIndex(max(2, count($agents) + 2)); $lastRow = max(1, $rowIndex - 1); $sheet->getStyle("A1:{$lastCol}1")->getFont()->setBold(true); $sheet->getStyle("A1:{$lastCol}{$lastRow}")->getBorders()->getAllBorders()->setBorderStyle(Border::BORDER_THIN); // Input validation for retention cells: - // - Applies to B2:lastCol(lastRow) + // - Applies to C2:lastCol(lastRow) // - Allows decimal value between 0 and 100 only // - Blocks negatives, values > 100, and text/special characters - if (count($vehicleTypes) > 0 && $lastRow >= 2) { - $validation = $sheet->getCell('B2')->getDataValidation(); + if (count($agents) > 0 && $lastRow >= 2) { + $validation = $sheet->getCell('C2')->getDataValidation(); $validation->setType(DataValidation::TYPE_DECIMAL); $validation->setErrorStyle(DataValidation::STYLE_STOP); $validation->setAllowBlank(true); @@ -2780,14 +2813,14 @@ class ExcelExportController extends ResourceController $validation->setErrorTitle('Invalid value'); $validation->setError('Only numeric values from 0 to 100 are allowed.'); for ($row = 2; $row <= $lastRow; $row++) { - for ($col = 2; $col <= (count($vehicleTypes) + 1); $col++) { + for ($col = 3; $col <= (count($agents) + 2); $col++) { $cell = Coordinate::stringFromColumnIndex($col) . $row; $sheet->getCell($cell)->setDataValidation(clone $validation); } } } - for ($i = 1; $i <= count($vehicleTypes) + 1; $i++) { + for ($i = 1; $i <= count($agents) + 2; $i++) { $col = Coordinate::stringFromColumnIndex($i); $sheet->getColumnDimension($col)->setAutoSize(true); } @@ -2815,11 +2848,14 @@ class ExcelExportController extends ResourceController { try { $file = $this->request->getFile('retention_excel'); + if (!$file || !$file->isValid()) { + $file = $this->request->getFile('retention_rate_excel'); + } if (!$file || !$file->isValid()) { return $this->respond([ 'status' => 'failed', 'code' => 200, - 'data' => 'Valid Excel file is required in retention_excel', + 'data' => 'Valid Excel file is required in retention_excel / retention_rate_excel', ], 200); } @@ -2836,24 +2872,24 @@ class ExcelExportController extends ResourceController } $headerRow = $rows[0]; - $headerVehicleTypes = []; - for ($col = 1; $col < count($headerRow); $col++) { + $headerAgents = []; + for ($col = 2; $col < count($headerRow); $col++) { $name = trim((string) ($headerRow[$col] ?? '')); if ($name === '') { continue; } - $headerVehicleTypes[$col] = strtolower($name); + $headerAgents[$col] = strtolower($name); } - if (empty($headerVehicleTypes)) { + if (empty($headerAgents)) { return $this->respond([ 'status' => 'failed', 'code' => 200, - 'data' => 'Vehicle type headers are missing in row 1', + 'data' => 'Agent code headers are missing in row 1', ], 200); } - $vehicleTypeRows = $this->db->table('partner_vehicle_type') + $vehicleTypeRows = $this->db->table('vehicle_type') ->select('id, vehicle_type') ->where('is_active', 1) ->get() @@ -2866,6 +2902,20 @@ class ExcelExportController extends ResourceController } } + $segmentRows = $this->db->table('partner_segment') + ->select('id, segment, vehicle_type_id') + ->where('is_active', 1) + ->get() + ->getResultArray(); + $segmentMap = []; + foreach ($segmentRows as $seg) { + $vId = (int) ($seg['vehicle_type_id'] ?? 0); + $segName = strtolower(trim((string) ($seg['segment'] ?? ''))); + if ($vId > 0 && $segName !== '') { + $segmentMap[$vId . '_' . $segName] = (int) $seg['id']; + } + } + $agentRows = $this->db->table('partner_agent') ->select('id, agent_code') ->where('is_active', 1) @@ -2881,35 +2931,35 @@ class ExcelExportController extends ResourceController } } - $unknownVehicleTypes = []; - $validHeaderVehicleTypes = []; - foreach ($headerVehicleTypes as $colIndex => $vehicleTypeName) { - if (isset($vehicleTypeMap[$vehicleTypeName])) { - $validHeaderVehicleTypes[$colIndex] = $vehicleTypeMap[$vehicleTypeName]; + $unknownAgentCodes = []; + $validHeaderAgents = []; + foreach ($headerAgents as $colIndex => $agentCode) { + if (isset($agentMap[$agentCode])) { + $validHeaderAgents[$colIndex] = $agentMap[$agentCode]; } else { - $unknownVehicleTypes[] = trim((string) ($headerRow[$colIndex] ?? '')); + $unknownAgentCodes[] = trim((string) ($headerRow[$colIndex] ?? '')); } } - if (empty($validHeaderVehicleTypes)) { + if (empty($validHeaderAgents)) { return $this->respond([ 'status' => 'failed', 'code' => 200, - 'data' => 'No valid vehicle type headers found in DB', + 'data' => 'No valid agent code headers found in DB', 'report' => [ - 'unknown_vehicle_types' => array_values(array_unique($unknownVehicleTypes)), + 'unknown_agent_codes' => array_values(array_unique($unknownAgentCodes)), ], ], 200); } $existingRows = $this->db->table('partner_retention_rate') - ->select('id, agent_id, vehicle_type_id, retention_rate') + ->select('id, agent_id, vehicle_type_id, segment_id, retention_rate') ->get() ->getResultArray(); $existingMap = []; foreach ($existingRows as $er) { - $key = ((int) $er['agent_id']) . '_' . ((int) $er['vehicle_type_id']); + $key = ((int) $er['agent_id']) . '_' . ((int) $er['vehicle_type_id']) . '_' . ((int) ($er['segment_id'] ?? 0)); $existingMap[$key] = [ 'id' => (int) $er['id'], 'rate' => (float) ($er['retention_rate'] ?? 0), @@ -2923,49 +2973,68 @@ class ExcelExportController extends ResourceController $skippedSame = 0; $skippedEmptyRow = 0; $skippedEmptyCell = 0; - $skippedUnknownAgentRow = 0; + $skippedUnknownVehicleType = 0; + $skippedUnknownSegment = 0; $invalidRange = 0; $invalidNumber = 0; - $unknownAgentCodes = []; + $unknownVehicleTypes = []; + $unknownSegments = []; $invalidCells = []; - $agentWiseSkippedCounts = []; + $agentWiseSkippedCounts = []; // keyed by row reference "vehicle_type | segment" $this->db->transStart(); for ($r = 1; $r < count($rows); $r++) { $row = $rows[$r]; - $agentCode = strtolower(trim((string) ($row[0] ?? ''))); - if ($agentCode === '') { + $vehicleTypeNameRaw = trim((string) ($row[0] ?? '')); + $segmentNameRaw = trim((string) ($row[1] ?? '')); + if ($vehicleTypeNameRaw === '' && $segmentNameRaw === '') { $skippedEmptyRow++; continue; } - if (!isset($agentMap[$agentCode])) { - $skippedUnknownAgentRow++; - $unknownAgentCodes[] = (string) ($row[0] ?? ''); + + $vehicleTypeKey = strtolower($vehicleTypeNameRaw); + if (!isset($vehicleTypeMap[$vehicleTypeKey])) { + $skippedUnknownVehicleType++; + if ($vehicleTypeNameRaw !== '') { + $unknownVehicleTypes[] = $vehicleTypeNameRaw; + } continue; } - $agentId = $agentMap[$agentCode]; - $agentCodeOriginal = trim((string) ($row[0] ?? '')); - if ($agentCodeOriginal !== '' && !isset($agentWiseSkippedCounts[$agentCodeOriginal])) { - $agentWiseSkippedCounts[$agentCodeOriginal] = 0; + + $vehicleTypeId = (int) $vehicleTypeMap[$vehicleTypeKey]; + $segmentKey = strtolower($segmentNameRaw); + $segmentMapKey = $vehicleTypeId . '_' . $segmentKey; + if ($segmentNameRaw === '' || !isset($segmentMap[$segmentMapKey])) { + $skippedUnknownSegment++; + if ($segmentNameRaw !== '') { + $unknownSegments[] = $segmentNameRaw; + } + continue; + } + $segmentId = (int) $segmentMap[$segmentMapKey]; + + $rowRef = trim($vehicleTypeNameRaw . ' | ' . $segmentNameRaw); + if ($rowRef !== '' && !isset($agentWiseSkippedCounts[$rowRef])) { + $agentWiseSkippedCounts[$rowRef] = 0; } - foreach ($validHeaderVehicleTypes as $colIndex => $vehicleTypeId) { + foreach ($validHeaderAgents as $colIndex => $agentId) { $rawRate = $row[$colIndex] ?? null; $rawText = trim((string) $rawRate); if ($rawText === '') { $skippedEmptyCell++; - if ($agentCodeOriginal !== '') { - $agentWiseSkippedCounts[$agentCodeOriginal]++; + if ($rowRef !== '') { + $agentWiseSkippedCounts[$rowRef]++; } continue; } if (!is_numeric($rawText)) { $invalidNumber++; - if ($agentCodeOriginal !== '') { - $agentWiseSkippedCounts[$agentCodeOriginal]++; + if ($rowRef !== '') { + $agentWiseSkippedCounts[$rowRef]++; } if (count($invalidCells) < 20) { $invalidCells[] = "R" . ($r + 1) . "C" . ($colIndex + 1) . " invalid number"; @@ -2976,8 +3045,8 @@ class ExcelExportController extends ResourceController $rate = (float) $rawText; if (!is_finite($rate)) { $invalidNumber++; - if ($agentCodeOriginal !== '') { - $agentWiseSkippedCounts[$agentCodeOriginal]++; + if ($rowRef !== '') { + $agentWiseSkippedCounts[$rowRef]++; } if (count($invalidCells) < 20) { $invalidCells[] = "R" . ($r + 1) . "C" . ($colIndex + 1) . " invalid number"; @@ -2987,8 +3056,8 @@ class ExcelExportController extends ResourceController if ($rate < 0 || $rate > 100) { $invalidRange++; - if ($agentCodeOriginal !== '') { - $agentWiseSkippedCounts[$agentCodeOriginal]++; + if ($rowRef !== '') { + $agentWiseSkippedCounts[$rowRef]++; } if (count($invalidCells) < 20) { $invalidCells[] = "R" . ($r + 1) . "C" . ($colIndex + 1) . " out of range (0-100)"; @@ -2996,22 +3065,24 @@ class ExcelExportController extends ResourceController continue; } - if ((float) $rate == 0.0) { + // Performance optimization: + // Skip zero values to avoid unnecessary DB lookup/write. + if (round($rate, 2) == 0.00) { $skippedZero++; - if ($agentCodeOriginal !== '') { - $agentWiseSkippedCounts[$agentCodeOriginal]++; + if ($rowRef !== '') { + $agentWiseSkippedCounts[$rowRef]++; } continue; } - $key = $agentId . '_' . $vehicleTypeId; + $key = $agentId . '_' . $vehicleTypeId . '_' . $segmentId; $existing = $existingMap[$key] ?? null; if ($existing) { if (round((float) $existing['rate'], 2) === round((float) $rate, 2)) { $skippedSame++; - if ($agentCodeOriginal !== '') { - $agentWiseSkippedCounts[$agentCodeOriginal]++; + if ($rowRef !== '') { + $agentWiseSkippedCounts[$rowRef]++; } continue; } @@ -3029,6 +3100,7 @@ class ExcelExportController extends ResourceController ->insert([ 'agent_id' => $agentId, 'vehicle_type_id' => $vehicleTypeId, + 'segment_id' => $segmentId, 'retention_rate' => round($rate, 2), 'is_active' => 1, 'created_on' => $now, @@ -3051,19 +3123,23 @@ class ExcelExportController extends ResourceController 'status' => 'success', 'code' => 200, 'data' => [ + 'inserted_rows' => $inserted, + 'updated_rows' => $updated, 'inserted_cells' => $inserted, 'updated_cells' => $updated, 'skipped_zero' => $skippedZero, 'skipped_same' => $skippedSame, 'skipped_empty_row' => $skippedEmptyRow, 'skipped_empty_cell' => $skippedEmptyCell, - 'skipped_unknown_agent' => $skippedUnknownAgentRow, + 'skipped_unknown_vehicle_type' => $skippedUnknownVehicleType, + 'skipped_unknown_segment' => $skippedUnknownSegment, 'invalid_range' => $invalidRange, 'invalid_number' => $invalidNumber, ], 'report' => [ 'unknown_agent_codes' => array_values(array_unique($unknownAgentCodes)), 'unknown_vehicle_types'=> array_values(array_unique($unknownVehicleTypes)), + 'unknown_segments' => array_values(array_unique($unknownSegments)), 'invalid_cells' => $invalidCells, 'agent_wise_skipped_counts' => $agentWiseSkippedCounts, ], diff --git a/app/Controllers/InvoiceController.php b/app/Controllers/InvoiceController.php index 22474f9..81526f0 100644 --- a/app/Controllers/InvoiceController.php +++ b/app/Controllers/InvoiceController.php @@ -84,6 +84,13 @@ class InvoiceController extends ResourceController WHERE piu.invoice_id = partner_invoice.id AND piu.is_active = 1 ) AS utr_numbers, + ( + SELECT GROUP_CONCAT(DISTINCT pp.vehicle_type ORDER BY pp.vehicle_type SEPARATOR ", ") + FROM partner_invoice_items pii + LEFT JOIN partner_policy pp ON pp.id = pii.policy_id + WHERE pii.invoice_id = partner_invoice.id + AND pii.is_active = 1 + ) AS vehicle_types, partner_invoice.invoice_amount AS invoiced_amount, ( COALESCE(( @@ -260,7 +267,7 @@ class InvoiceController extends ResourceController $items = $this->InvoiceItemModel ->select( - 'partner_invoice_items.*, pp.issued_date, pe.name AS customer_name, pp.premium_amount, ' + 'partner_invoice_items.*, pp.vehicle_type, pp.issued_date, pe.name AS customer_name, pp.premium_amount, ' . 'pa.agent_code, pa.name AS agent_name, CONCAT_WS(" - ", pa.agent_code, pa.name) AS agent_code_name', false ) diff --git a/app/Libraries/PartnerPayoutGridRetention.php b/app/Libraries/PartnerPayoutGridRetention.php index e5655a9..07ecb40 100644 --- a/app/Libraries/PartnerPayoutGridRetention.php +++ b/app/Libraries/PartnerPayoutGridRetention.php @@ -8,7 +8,7 @@ use CodeIgniter\Database\BaseConnection; * Partner (agent) grid: same data as * SELECT prr.retention_rate AS partner_RR, prr.vehicle_type_id, pvt.vehicle_type AS partner_VT * FROM partner_retention_rate prr - * LEFT JOIN partner_vehicle_type pvt ON pvt.id = prr.vehicle_type_id + * LEFT JOIN vehicle_type vt ON vt.id = prr.vehicle_type_id * WHERE prr.agent_id = ? AND prr.is_active = 1 * Matched grid row (vehicle type aligns with that PRR row): partner_VT, partner_RR set from DB; * comp/tp/od = partner_RR − original (null/empty base → 0); result ≤ 0 → '-'. @@ -19,7 +19,7 @@ use CodeIgniter\Database\BaseConnection; class PartnerPayoutGridRetention { /** - * Active partner_retention_rate rows with joined partner_vehicle_type (one query for maps + agent grid meta). + * Active partner_retention_rate rows with joined vehicle_type (one query for maps + agent grid meta). * * @return array> */ @@ -30,8 +30,8 @@ class PartnerPayoutGridRetention } return $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') + ->select('prr.vehicle_type_id, prr.retention_rate, vt.vehicle_type') + ->join('vehicle_type vt', 'vt.id = prr.vehicle_type_id', 'left') ->where('prr.agent_id', $agentId) ->where('prr.is_active', 1) ->get() @@ -79,7 +79,7 @@ class PartnerPayoutGridRetention } /** - * partner_vehicle_type.vehicle_type as partner_VT, partner_retention_rate.retention_rate as partner_RR. + * vehicle_type.vehicle_type as partner_VT, partner_retention_rate.retention_rate as partner_RR. * Keys: normalized vehicle name, and id:{vehicle_type_id}. Rows without retention_rate are omitted. * * @return array @@ -90,14 +90,14 @@ class PartnerPayoutGridRetention } /** - * Normalized master label → partner_vehicle_type.id (active rows only). + * Normalized master label → vehicle_type.id (active rows only). * Used when grid row text must be resolved to an id for partner_retention_rate lookup. * * @return array */ public static function buildMasterNormLabelToVehicleTypeIdMap(BaseConnection $db): array { - $rows = $db->table('partner_vehicle_type') + $rows = $db->table('vehicle_type') ->select('id, vehicle_type') ->where('is_active', 1) ->get() @@ -131,7 +131,7 @@ class PartnerPayoutGridRetention if ($vid > 0 && isset($metaMap['id:' . $vid])) { return $metaMap['id:' . $vid]; } - // Grid text matches master partner_vehicle_type but meta was only keyed by id (e.g. weak pvt join on prr) + // Grid text matches master vehicle_type but meta was only keyed by id (e.g. weak pvt join on prr) if ($masterNormLabelToVtId !== null && $key !== '') { $mid = $masterNormLabelToVtId[$key] ?? 0; if ($mid > 0 && isset($metaMap['id:' . $mid])) { diff --git a/app/Models/PartnerRetentionRateModel.php b/app/Models/PartnerRetentionRateModel.php index 28568a3..fc90bfb 100644 --- a/app/Models/PartnerRetentionRateModel.php +++ b/app/Models/PartnerRetentionRateModel.php @@ -11,6 +11,7 @@ class PartnerRetentionRateModel extends Model protected $allowedFields = [ 'agent_id', 'vehicle_type_id', + 'segment_id', 'retention_rate', 'is_active', 'created_by', diff --git a/app/Models/PartnerVehicleTypeModel.php b/app/Models/PartnerVehicleTypeModel.php deleted file mode 100644 index 45a44cb..0000000 --- a/app/Models/PartnerVehicleTypeModel.php +++ /dev/null @@ -1,18 +0,0 @@ -