GWM : commission amount update api
This commit is contained in:
parent
bfc0a54d57
commit
114f697fb9
@ -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');
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user