GWM : commission amount update api

This commit is contained in:
Gowtham M 2026-04-03 10:25:09 +05:30
parent bfc0a54d57
commit 114f697fb9
2 changed files with 323 additions and 2 deletions

View File

@ -130,7 +130,9 @@ $routes->group('api', ['filter' => 'appSignature'], function ($routes) {
$routes->get("policy/vehicleTypeMaster", "PolicyController::vehicleTypeMaster");
$routes->get("policy/fuelTypeMaster", "PolicyController::fuelTypeMaster");
$routes->get("policy/softdelete", "PolicyController::softdelete");
$routes->get('policy/downloadPendingCommissionExcel', 'PolicyController::downloadPendingCommissionExcel');
$routes->post('policy/uploadCommissionExcel', 'PolicyController::uploadCommissionExcel');
$routes->post('policy/payoutInilneEditUpdate', 'PolicyController::payoutInilneEditUpdate');
//claims
$routes->get('claim/ClaimList', 'ClaimController::ClaimList');

View File

@ -5,6 +5,8 @@ use CodeIgniter\RESTful\ResourceController;
use App\Models\PolicyModel;
use App\Models\EnquiryModel;
use App\Models\QuotationModel;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\IOFactory;
class PolicyController extends ResourceController
{
@ -1411,14 +1413,331 @@ class PolicyController extends ResourceController
}
}
/**
* Stream a simple XLSX (title row, header row, data rows) without totals row.
*/
private function streamPendingCommissionExcel(array $header, array $data, string $title, string $fileName): void
{
while (ob_get_level() > 0) {
ob_end_clean();
}
$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$columnCount = count($header);
$lastCol = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($columnCount);
$sheet->mergeCells("A1:{$lastCol}1");
$sheet->setCellValue('A1', $title);
$sheet->getStyle('A1')->getFont()->setBold(true)->setSize(14);
$sheet->getStyle('A1')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
$sheet->fromArray($header, null, 'A2');
$sheet->getStyle("A2:{$lastCol}2")->getFont()->setBold(true);
$sheet->getStyle("A2:{$lastCol}2")->getFill()
->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)
->getStartColor()->setARGB('F2F2F2');
if ($data !== []) {
$sheet->fromArray($data, null, 'A3');
}
for ($i = 1; $i <= $columnCount; $i++) {
$col = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($i);
$sheet->getColumnDimension($col)->setAutoSize(true);
}
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header("Content-Disposition: attachment; filename=\"{$fileName}\"");
header('Cache-Control: max-age=0');
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
$writer->save('php://output');
exit();
}
/**
* GET: from_date, to_date (optional), agent_code (optional) at least one filter required.
* Exports policies where commission_amount is NULL or 0 (active policies only).
*/
public function downloadPendingCommissionExcel()
{
try {
$fromDate = $this->request->getGet('from_date');
$toDate = $this->request->getGet('to_date');
$agentCode = $this->request->getGet('agent_code');
$agentCode = $agentCode !== null && $agentCode !== '' ? trim((string) $agentCode) : null;
if ($fromDate === null || $fromDate === '') {
$fromDate = null;
}
if ($toDate === null || $toDate === '') {
$toDate = null;
}
if ($fromDate === null && $toDate === null && $agentCode === null) {
return $this->respond([
'status' => 'failed',
'code' => 400,
'data' => 'Provide at least one of: from_date, to_date, or agent_code',
], 400);
}
$db = \Config\Database::connect();
$builder = $db->table('partner_policy pp');
$builder->select('pa.agent_code, pp.policy_number');
$builder->join('partner_agent pa', 'pa.id = pp.agent_id', 'left');
$builder->where('pp.is_active', 1);
$builder->groupStart()
->where('pp.commission_amount', null)
->orWhere('pp.commission_amount', 0)
->groupEnd();
if ($fromDate !== null) {
$builder->where('pp.issued_date >=', date('Y-m-d', strtotime((string) $fromDate)));
}
if ($toDate !== null) {
$builder->where('pp.issued_date <=', date('Y-m-d', strtotime((string) $toDate)));
}
if ($agentCode !== null) {
$builder->where('pa.agent_code', $agentCode);
}
$builder->orderBy('pa.agent_code', 'ASC');
$builder->orderBy('pp.policy_number', 'ASC');
$rows = $builder->get()->getResultArray();
$dataRows = [];
foreach ($rows as $row) {
$dataRows[] = [
$row['agent_code'] ?? '',
$row['policy_number'] ?? '',
'',
];
}
$header = ['Agent Code', 'Policy Number', 'Payout Amount'];
$fromPart = $fromDate !== null ? date('Y-m-d', strtotime((string) $fromDate)) : 'na';
$toPart = $toDate !== null ? date('Y-m-d', strtotime((string) $toDate)) : 'na';
$agentPart = $agentCode !== null
? preg_replace('/[^A-Za-z0-9_-]+/', '_', $agentCode)
: 'all_agents';
$fileName = "commission_pending_{$fromPart}_{$toPart}_{$agentPart}.xlsx";
$title = 'Pending commission payout (fill Payout Amount and re-upload)';
$this->streamPendingCommissionExcel($header, $dataRows, $title, $fileName);
} catch (\Throwable $e) {
return $this->respond([
'status' => 'failed',
'code' => 500,
'message' => $e->getMessage(),
], 500);
}
}
/**
* POST multipart field: commission_excel (xlsx). Updates partner_policy.commission_amount by policy number.
*/
public function uploadCommissionExcel()
{
try {
$file = $this->request->getFile('commission_excel');
if ($file === null || ! $file->isValid()) {
return $this->respond([
'status' => 'failed',
'code' => 400,
'data' => 'commission_excel file is required (xlsx)',
], 400);
}
$ext = strtolower((string) $file->getClientExtension());
if ($ext !== 'xlsx') {
return $this->respond([
'status' => 'failed',
'code' => 400,
'data' => 'Only .xlsx files are supported',
], 400);
}
$spreadsheet = IOFactory::load($file->getTempName());
$sheet = $spreadsheet->getActiveSheet();
$highestRow = (int) $sheet->getHighestDataRow();
$headerRowNum = null;
for ($r = 1; $r <= min(5, $highestRow); $r++) {
$a = strtolower(trim((string) $sheet->getCell(Coordinate::stringFromColumnIndex(1) . $r)->getValue()));
$b = strtolower(trim((string) $sheet->getCell(Coordinate::stringFromColumnIndex(2) . $r)->getValue()));
if ($a === 'agent code' && str_contains($b, 'policy')) {
$headerRowNum = $r;
break;
}
}
if ($headerRowNum === null) {
return $this->respond([
'status' => 'failed',
'code' => 400,
'data' => 'Could not find header row (Agent Code, Policy Number)',
], 400);
}
$db = \Config\Database::connect();
$db->transStart();
$updated = 0;
$skipped = 0;
$errors = [];
for ($r = $headerRowNum + 1; $r <= $highestRow; $r++) {
$policyNumber = trim((string) $sheet->getCell('B' . $r)->getFormattedValue());
$payoutRaw = $sheet->getCell('C' . $r)->getCalculatedValue();
if ($policyNumber === '') {
continue;
}
if ($payoutRaw === null || $payoutRaw === '') {
$skipped++;
continue;
}
if (is_numeric($payoutRaw)) {
$amount = (float) $payoutRaw;
} else {
$amount = (float) str_replace([',', ' '], '', (string) $payoutRaw);
}
if ($amount < 0 || is_nan($amount)) {
$errors[] = "Row {$r}: invalid payout for policy {$policyNumber}";
continue;
}
$policy = $this->PolicyModel->where('policy_number', $policyNumber)->where('is_active', 1)->first();
if (! $policy) {
$errors[] = "Row {$r}: policy not found: {$policyNumber}";
continue;
}
$this->PolicyModel->update((int) $policy['id'], ['commission_amount' => $amount]);
$updated++;
}
$db->transComplete();
if ($db->transStatus() === false) {
return $this->respond([
'status' => 'failed',
'code' => 500,
'data' => 'Transaction failed',
], 500);
}
return $this->respond([
'status' => 'success',
'code' => 200,
'data' => [
'updated_rows' => $updated,
'skipped_empty_payout' => $skipped,
'errors' => $errors,
],
], 200);
} catch (\Throwable $e) {
return $this->respond([
'status' => 'failed',
'code' => 500,
'message' => $e->getMessage(),
], 500);
}
}
/**
* POST JSON: id (partner_policy.id), commission_amount (number or null).
*/
public function payoutInilneEditUpdate()
{
try {
$data = $this->request->getJSON(true);
if (! is_array($data)) {
return $this->respond([
'status' => 'failed',
'code' => 400,
'data' => 'Invalid JSON body',
], 400);
}
if (! isset($data['id']) || $data['id'] === '' || $data['id'] === null) {
return $this->respond([
'status' => 'failed',
'code' => 400,
'data' => 'id is required',
], 400);
}
if (! array_key_exists('commission_amount', $data)) {
return $this->respond([
'status' => 'failed',
'code' => 400,
'data' => 'commission_amount is required',
], 400);
}
$id = (int) $data['id'];
$policy = $this->PolicyModel->find($id);
if (! $policy) {
return $this->respond([
'status' => 'failed',
'code' => 404,
'data' => 'Data Not Found',
], 404);
}
$raw = $data['commission_amount'];
if ($raw === null || $raw === '') {
$commission = null;
} elseif (is_numeric($raw)) {
$commission = (float) $raw;
} else {
$clean = str_replace([',', ' '], '', (string) $raw);
if ($clean === '' || ! is_numeric($clean)) {
return $this->respond([
'status' => 'failed',
'code' => 400,
'data' => 'commission_amount must be numeric or null',
], 400);
}
$commission = (float) $clean;
}
if ($commission !== null && ($commission < 0 || is_nan($commission))) {
return $this->respond([
'status' => 'failed',
'code' => 400,
'data' => 'commission_amount cannot be negative',
], 400);
}
$this->PolicyModel->update($id, ['commission_amount' => $commission]);
return $this->respond([
'status' => 'success',
'code' => 200,
'data' => [
'id' => $id,
'commission_amount' => $commission,
],
], 200);
} catch (\Throwable $e) {
return $this->respond([
'status' => 'failed',
'code' => 500,
'message' => $e->getMessage(),
], 500);
}
}