1944 lines
90 KiB
PHP
1944 lines
90 KiB
PHP
<?php
|
|
|
|
namespace App\Controllers;
|
|
|
|
use CodeIgniter\RESTful\ResourceController;
|
|
|
|
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
|
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
|
use PhpOffice\PhpSpreadsheet\Style\Border;
|
|
use PhpOffice\PhpSpreadsheet\Cell\Coordinate; // <--- THIS MUST BE HERE
|
|
use PhpOffice\PhpSpreadsheet\Style\Alignment;
|
|
|
|
class ExcelExportController extends ResourceController
|
|
{
|
|
protected $db;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->db = \Config\Database::connect();
|
|
}
|
|
|
|
|
|
/**
|
|
* Centralized function to create the spreadsheet, apply styling,
|
|
* set headers, and stream the file output.
|
|
*
|
|
* @param array $header Column headers (1D array)
|
|
* @param array $data Policy data including the total row (2D array)
|
|
* @param string $title Spreadsheet title
|
|
* @param string $fileName Output file name
|
|
* @param string $totalLabelCol Column letter for the 'TOTAL:' label (e.g., 'C' or 'E')
|
|
* @param string $totalValueCol Column letter for the total value (e.g., 'D' or 'F')
|
|
* @return void
|
|
*/
|
|
private function streamExcelFile(array $header, array $data, string $title, string $fileName, bool $showTotal = true): 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);
|
|
$rowCount = count($data);
|
|
|
|
// 1. Title
|
|
$sheet->mergeCells("A1:{$lastCol}1");
|
|
$sheet->setCellValue('A1', $title);
|
|
$sheet->getStyle('A1')->getFont()->setBold(true)->setSize(14);
|
|
$sheet->getStyle('A1')->getAlignment()->setHorizontal('center');
|
|
|
|
// 2. Headers
|
|
$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');
|
|
|
|
// 3. Data
|
|
$sheet->fromArray($data, NULL, 'A3');
|
|
|
|
// 4. Dynamic Total Row Styling
|
|
if ($rowCount > 0 && $showTotal === true) {
|
|
$totalRowNumber = $rowCount + 2;
|
|
|
|
// Bold the entire last row
|
|
$sheet->getStyle("A{$totalRowNumber}:{$lastCol}{$totalRowNumber}")->getFont()->setBold(true);
|
|
|
|
// Find the second to last column letter for "Total:" alignment
|
|
$labelColLetter = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($columnCount - 1);
|
|
|
|
// Right-align the "Total:" label (usually second to last column)
|
|
$sheet->getStyle($labelColLetter . $totalRowNumber)->getAlignment()->setHorizontal('right');
|
|
|
|
// Format the last column (the sum) as a number
|
|
$sheet->getStyle($lastCol . $totalRowNumber)->getNumberFormat()->setFormatCode('#,##0.00');
|
|
}
|
|
|
|
|
|
// 5. Auto-size
|
|
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();
|
|
}
|
|
|
|
// 1) Broker generate the Excel file
|
|
public function downloadBrokerPoliciesExcel()
|
|
{
|
|
try{
|
|
$managerId = $this->request->getGet('manager_id');
|
|
$brokerId = $this->request->getGet('broker_id');
|
|
$month = $this->request->getGet('month');
|
|
|
|
if (empty($managerId) || empty($brokerId) || empty($month)) {
|
|
|
|
$msg = "Missing: ";
|
|
$msg .= empty($managerId) ? "manager_id " : "";
|
|
$msg .= empty($brokerId) ? "broker_id " : "";
|
|
$msg .= empty($month) ? "month " : "";
|
|
$ref = ['debug_msg' => $msg];
|
|
// $ref = ['debug_msg' => 'Missing required parameters: manager_id, broker_id, and month must be provided.'];
|
|
return $this->response->setJSON(['status' => 'error','code' => 400,'data' => [],'message' => 'Missing required parameters','ref' => $ref])->setStatusCode(200);
|
|
}
|
|
|
|
$data = $this->getBrokerPoliciesData($managerId, $brokerId, $month);
|
|
if (empty($data)) {
|
|
throw new \RuntimeException('No policies found...', 404);
|
|
}
|
|
$lastIndex = count(reset($data)) - 1;
|
|
// usort($data, function($a, $b) use ($lastIndex) {
|
|
// return (float)$a[$lastIndex] <=> (float)$b[$lastIndex];
|
|
// });
|
|
usort($data, function($a, $b) use ($lastIndex) {
|
|
return (float)$b[$lastIndex] <=> (float)$a[$lastIndex];
|
|
});
|
|
$finalData = [];
|
|
$serialNo = 1;
|
|
foreach ($data as $row) {
|
|
$finalData[] = array_merge([$serialNo++], $row);
|
|
}
|
|
|
|
$header = ['S.No',
|
|
'Received Date', 'Assigned To',
|
|
'Partner Name' , 'Partner Code',
|
|
'Insurer Name' ,'Insurer Short Name',
|
|
'Insured Name', 'Vehicle Number',
|
|
'Payment Mode', 'Plan Type',
|
|
'Broker Name', 'Issue Date', 'Policy Number', 'Premium Amount'];
|
|
|
|
|
|
|
|
// Calculate and append total
|
|
$lastColIndex = count($header) - 1; // Get index of the last column (Premium)
|
|
$grandTotal = array_sum(array_column($finalData, $lastColIndex));
|
|
|
|
$totalRow = array_fill(0, count($header), ''); // Create empty row of same width
|
|
$totalRow[$lastColIndex - 1] = 'Total:'; // Put label in 2nd to last
|
|
$totalRow[$lastColIndex] = $grandTotal; // Put sum in last
|
|
$finalData[] = $totalRow;
|
|
|
|
$monthName = ($month === 'current') ? date('M_Y') : date('M_Y', strtotime('-1 month'));
|
|
$brokerName = $finalData[0][11] ?? 'Broker';
|
|
$cleanbrokerName = str_replace(' ', '_', strtolower($brokerName));
|
|
$fileName = $cleanbrokerName . '_Policies_Details_' . $monthName . '.xlsx';
|
|
|
|
// --- CALL CENTRALIZED FUNCTION ---
|
|
$this->streamExcelFile(
|
|
$header,
|
|
$finalData,
|
|
"Broker Policies Details for {$monthName}",
|
|
$fileName,
|
|
true // Pass 'true' to show/bold the total row
|
|
);
|
|
|
|
|
|
return;
|
|
|
|
} catch (\Throwable $e) {
|
|
|
|
// ... (Your error handling remains the same) ...
|
|
$ref = [];
|
|
// Case 1: No Data Found (Soft Success JSON)
|
|
if ($e instanceof \RuntimeException && $e->getCode() === 404) {
|
|
$ref['debug_msg'] = 'No Data Found';
|
|
return $this->respond([
|
|
'status' => 'success',
|
|
'code' => 200,
|
|
'data' => [],
|
|
'message' => 'No Data Found',
|
|
'ref' => $ref
|
|
], 200);
|
|
}
|
|
|
|
// Case 2: Database or Other Error (Error JSON)
|
|
$isDbError = $e instanceof \CodeIgniter\Database\Exceptions\DatabaseException
|
|
|| $e instanceof \mysqli_sql_exception
|
|
|| $e instanceof \PDOException;
|
|
|
|
if ($isDbError) {
|
|
$ref['debug_info'] = $e->getFile() . " / LN : " . $e->getLine();
|
|
$ref['debug_msg'] = 'Database Error Occurred: ' . $e->getMessage();
|
|
$message = 'Database Error Occurred.';
|
|
} else {
|
|
$ref['debug_msg'] = 'An unexpected error occurred: ' . $e->getMessage();
|
|
$message = 'Something went wrong. Please try again later.';
|
|
}
|
|
|
|
return $this->respond([
|
|
'status' => 'error',
|
|
'code' => 500,
|
|
'data' => [],
|
|
'message'=> $message,
|
|
'ref' => $ref
|
|
], 200);
|
|
}
|
|
}
|
|
|
|
|
|
// 2) Product generate the Excel file
|
|
public function downloadProductPoliciesExcel()
|
|
{
|
|
try{
|
|
$managerId = $this->request->getGet('manager_id');
|
|
$vehicleType = $this->request->getGet('vehicle_type');
|
|
$month = $this->request->getGet('month');
|
|
|
|
if (empty($managerId) || empty($vehicleType) || empty($month)) {
|
|
|
|
|
|
$msg = "Missing: ";
|
|
$msg .= empty($managerId) ? "manager_id " : "";
|
|
$msg .= empty($brokerId) ? "broker_id " : "";
|
|
$msg .= empty($month) ? "month " : "";
|
|
$ref = ['debug_msg' => $msg];
|
|
// $ref = ['debug_msg' => 'Missing required parameters: manager_id, broker_id, and month must be provided.'];
|
|
return $this->response->setJSON(['status' => 'error','code' => 400,'data' => [],'message' => 'Missing required parameters','ref' => $ref])->setStatusCode(200);
|
|
|
|
}
|
|
|
|
$data = $this->getProductPoliciesData($managerId, $vehicleType, $month);
|
|
if (empty($data)) {
|
|
throw new \RuntimeException('No policies found for this vehicle type...', 404);
|
|
}
|
|
$lastIndex = count(reset($data)) - 1;
|
|
// usort($data, function($a, $b) use ($lastIndex) {
|
|
// return (float)$a[$lastIndex] <=> (float)$b[$lastIndex];
|
|
// });
|
|
usort($data, function($a, $b) use ($lastIndex) {
|
|
return (float)$b[$lastIndex] <=> (float)$a[$lastIndex];
|
|
});
|
|
$finalData = [];
|
|
$serialNo = 1;
|
|
foreach ($data as $row) {
|
|
$finalData[] = array_merge([$serialNo++], $row);
|
|
}
|
|
// $header = ['Vehicle Type', 'Issue Date', 'Policy Number', 'Premium Amount'];
|
|
$header = ['S.No',
|
|
'Received Date', 'Assigned To',
|
|
'Partner Name' , 'Partner Code',
|
|
'Insurer Name' ,'Insurer Short Name',
|
|
'Insured Name', 'Vehicle Number',
|
|
'Payment Mode', 'Plan Type',
|
|
'Vehicle Type', 'Issue Date', 'Policy Number', 'Premium Amount'];
|
|
|
|
|
|
|
|
// Calculate and append total
|
|
$lastColIndex = count($header) - 1; // Get index of the last column (Premium)
|
|
$grandTotal = array_sum(array_column($finalData, $lastColIndex));
|
|
|
|
$totalRow = array_fill(0, count($header), ''); // Create empty row of same width
|
|
$totalRow[$lastColIndex - 1] = 'Total:'; // Put label in 2nd to last
|
|
$totalRow[$lastColIndex] = $grandTotal; // Put sum in last
|
|
$finalData[] = $totalRow;
|
|
|
|
$monthName = ($month === 'current') ? date('M_Y') : date('M_Y', strtotime('-1 month'));
|
|
$vehicleType = $finalData[0][11] ?? 'Vehicle';
|
|
$cleanVehicleType = str_replace(' ', '_', strtolower($vehicleType));
|
|
$fileName = $cleanVehicleType . '_Policies_Details_' . $monthName . '.xlsx';
|
|
|
|
// --- CALL CENTRALIZED FUNCTION ---
|
|
$this->streamExcelFile(
|
|
$header,
|
|
$finalData,
|
|
"Vehicle Type Policies Details for {$monthName}",
|
|
$fileName,
|
|
true // This will ignore the bold/alignment logic for the last row
|
|
);
|
|
return;
|
|
} catch (\Throwable $e) {
|
|
|
|
// ... (Your error handling remains the same) ...
|
|
$ref = [];
|
|
// Case 1: No Data Found (Soft Success JSON)
|
|
if ($e instanceof \RuntimeException && $e->getCode() === 404) {
|
|
$ref['debug_msg'] = 'No Data Found';
|
|
return $this->respond([
|
|
'status' => 'success',
|
|
'code' => 200,
|
|
'data' => [],
|
|
'message' => 'No Data Found',
|
|
'ref' => $ref
|
|
], 200);
|
|
}
|
|
|
|
// Case 2: Database or Other Error (Error JSON)
|
|
$isDbError = $e instanceof \CodeIgniter\Database\Exceptions\DatabaseException
|
|
|| $e instanceof \mysqli_sql_exception
|
|
|| $e instanceof \PDOException;
|
|
|
|
if ($isDbError) {
|
|
$ref['debug_info'] = $e->getFile() . " / LN : " . $e->getLine();
|
|
$ref['debug_msg'] = 'Database Error Occurred: ' . $e->getMessage();
|
|
$message = 'Database Error Occurred.';
|
|
} else {
|
|
$ref['debug_msg'] = 'An unexpected error occurred: ' . $e->getMessage();
|
|
$message = 'Something went wrong. Please try again later.';
|
|
}
|
|
|
|
return $this->respond([
|
|
'status' => 'error',
|
|
'code' => 500,
|
|
'data' => [],
|
|
'message'=> $message,
|
|
'ref' => $ref
|
|
], 200);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 3) Insurer generate the Excel file
|
|
public function downloadInsurerPoliciesExcel()
|
|
{
|
|
try{
|
|
$managerId = $this->request->getGet('manager_id');
|
|
$insurerId = $this->request->getGet('insurer_id');
|
|
$month = $this->request->getGet('month');
|
|
|
|
// --- ADDED VALIDATION (Simplified logic for clarity) ---
|
|
if (empty($managerId) || empty($insurerId) || empty($month)) {
|
|
$msg = "Missing: ";
|
|
$msg .= empty($managerId) ? "manager_id " : "";
|
|
$msg .= empty($insurerId) ? "insurer_id " : "";
|
|
$msg .= empty($month) ? "month " : "";
|
|
$ref = ['debug_msg' => $msg];
|
|
// Status code remains 200, but JSON code is 400 as per your preference
|
|
return $this->response->setJSON([
|
|
'status' => 'error',
|
|
'code' => 400,
|
|
'data' => [],
|
|
'message' => 'Missing required parameters',
|
|
'ref' => $ref
|
|
])->setStatusCode(200);
|
|
}
|
|
|
|
$data = $this->getInsurerPoliciesData($managerId, $insurerId, $month);
|
|
|
|
// --- 1. MODIFIED LOGIC: Throw RuntimeException if no data ---
|
|
if (empty($data)) {
|
|
throw new \RuntimeException('No policies found for this insurer for the specified month.', 404);
|
|
}
|
|
$lastIndex = count(reset($data)) - 1;
|
|
// usort($data, function($a, $b) use ($lastIndex) {
|
|
// return (float)$a[$lastIndex] <=> (float)$b[$lastIndex];
|
|
// });
|
|
usort($data, function($a, $b) use ($lastIndex) {
|
|
return (float)$b[$lastIndex] <=> (float)$a[$lastIndex];
|
|
});
|
|
$finalData = [];
|
|
$serialNo = 1;
|
|
foreach ($data as $row) {
|
|
$finalData[] = array_merge([$serialNo++], $row);
|
|
}
|
|
|
|
|
|
// Define column headers
|
|
$header = ['S.No',
|
|
'Received Date', 'Assigned To',
|
|
'Partner Name' , 'Partner Code',
|
|
'Vehicle Number',
|
|
'Payment Mode', 'Plan Type',
|
|
'Insurer Name', 'Insurer Short Name','Insured Name', 'Policy Issued Date','Policy Number', 'Premium Amount'];
|
|
|
|
|
|
// Calculate and append total
|
|
$lastColIndex = count($header) - 1; // Get index of the last column (Premium)
|
|
$grandTotal = array_sum(array_column($finalData, $lastColIndex));
|
|
|
|
$totalRow = array_fill(0, count($header), ''); // Create empty row of same width
|
|
$totalRow[$lastColIndex - 1] = 'Total:'; // Put label in 2nd to last
|
|
$totalRow[$lastColIndex] = $grandTotal; // Put sum in last
|
|
$finalData[] = $totalRow;
|
|
|
|
$monthName = ($month === 'current') ? date('M_Y') : date('M_Y', strtotime('-1 month'));
|
|
$InsurerName = $finalData[0][8] ?? 'Insurer' ;
|
|
$cleanInsurerName = str_replace(' ', '_', strtolower($InsurerName));
|
|
$fileName = $cleanInsurerName . '_Policies_Details_' . $monthName . '.xlsx';
|
|
|
|
// --- CALL CENTRALIZED FUNCTION ---
|
|
$this->streamExcelFile(
|
|
$header,
|
|
$finalData,
|
|
"Insurer Policies Details for {$monthName}",
|
|
$fileName,
|
|
true // This will ignore the bold/alignment logic for the last row
|
|
);
|
|
|
|
return; // STOP CI4 rendering anything else
|
|
|
|
} catch (\Throwable $e) {
|
|
|
|
// ... (Your error handling remains the same) ...
|
|
$ref = [];
|
|
// Case 1: No Data Found (Soft Success JSON)
|
|
if ($e instanceof \RuntimeException && $e->getCode() === 404) {
|
|
$ref['debug_msg'] = 'No Data Found';
|
|
return $this->respond([
|
|
'status' => 'success',
|
|
'code' => 200,
|
|
'data' => [],
|
|
'message' => 'No Data Found',
|
|
'ref' => $ref
|
|
], 200);
|
|
}
|
|
|
|
// Case 2: Database or Other Error (Error JSON)
|
|
$isDbError = $e instanceof \CodeIgniter\Database\Exceptions\DatabaseException
|
|
|| $e instanceof \mysqli_sql_exception
|
|
|| $e instanceof \PDOException;
|
|
|
|
if ($isDbError) {
|
|
$ref['debug_info'] = $e->getFile() . " / LN : " . $e->getLine();
|
|
$ref['debug_msg'] = 'Database Error Occurred: ' . $e->getMessage();
|
|
$message = 'Database Error Occurred.';
|
|
} else {
|
|
$ref['debug_msg'] = 'An unexpected error occurred: ' . $e->getMessage();
|
|
$message = 'Something went wrong. Please try again later.';
|
|
}
|
|
|
|
return $this->respond([
|
|
'status' => 'error',
|
|
'code' => 500,
|
|
'data' => [],
|
|
'message'=> $message,
|
|
'ref' => $ref
|
|
], 200);
|
|
}
|
|
}
|
|
|
|
|
|
// 4) LowPremium generate the Excel file (Below 5OK)
|
|
public function downloadLowPremiumAgentExcel()
|
|
{
|
|
try{
|
|
$managerId = $this->request->getGet('manager_id');
|
|
|
|
if (empty($managerId)) {
|
|
$msg = "Missing: ";
|
|
$msg .= empty($managerId) ? "manager_id " : "";
|
|
$ref = ['debug_msg' => $msg];
|
|
// $ref = ['debug_msg' => 'Missing required parameters: manager_id, broker_id, and month must be provided.'];
|
|
return $this->response->setJSON(['status' => 'error','code' => 400,'data' => [],'message' => 'Missing required parameters','ref' => $ref])->setStatusCode(200);
|
|
}
|
|
|
|
$data = $this->getLowPremiumAgentData($managerId);
|
|
if (empty($data)) {
|
|
throw new \RuntimeException('No low premium agents found...', 404);
|
|
}
|
|
|
|
$finalData = [];
|
|
$serialNo = 1;
|
|
|
|
foreach ($data as $row) {
|
|
$finalData[] = array_merge([$serialNo++], $row);
|
|
}
|
|
|
|
$header = ['S.No',
|
|
'Received Date', 'Assigned To',
|
|
'Insurer Name' ,'Insurer Short Name',
|
|
'Insured Name', 'Vehicle Number',
|
|
'Payment Mode', 'Plan Type',
|
|
'Partner Name', 'Partner Code','Partner Status' ,'Policy Number','Issued Date', 'Premium Amount'];
|
|
|
|
|
|
|
|
// Calculate and append total
|
|
$lastColIndex = count($header) - 1; // Get index of the last column (Premium)
|
|
$grandTotal = array_sum(array_column($finalData, $lastColIndex));
|
|
|
|
$totalRow = array_fill(0, count($header), ''); // Create empty row of same width
|
|
$totalRow[$lastColIndex - 1] = 'Total:'; // Put label in 2nd to last
|
|
$totalRow[$lastColIndex] = $grandTotal; // Put sum in last
|
|
$finalData[] = $totalRow;
|
|
|
|
// Note: $month variable is undefined, assuming you want current month for filename
|
|
$monthName = date('M_Y');
|
|
$PartnerName = $finalData[0][9] ?? 'Partner';
|
|
$fileName = 'Partners_Low_Premium_Policy_Details.xlsx';
|
|
|
|
// --- CALL CENTRALIZED FUNCTION ---
|
|
$this->streamExcelFile(
|
|
$header,
|
|
$finalData,
|
|
"Partners Low Premium Policy Details",
|
|
$fileName,
|
|
true // This will ignore the bold/alignment logic for the last row
|
|
);
|
|
|
|
return;
|
|
} catch (\Throwable $e) {
|
|
|
|
// ... (Your error handling remains the same) ...
|
|
$ref = [];
|
|
// Case 1: No Data Found (Soft Success JSON)
|
|
if ($e instanceof \RuntimeException && $e->getCode() === 404) {
|
|
$ref['debug_msg'] = 'No Data Found';
|
|
return $this->respond([
|
|
'status' => 'success',
|
|
'code' => 200,
|
|
'data' => [],
|
|
'message' => 'No Data Found',
|
|
'ref' => $ref
|
|
], 200);
|
|
}
|
|
|
|
// Case 2: Database or Other Error (Error JSON)
|
|
$isDbError = $e instanceof \CodeIgniter\Database\Exceptions\DatabaseException
|
|
|| $e instanceof \mysqli_sql_exception
|
|
|| $e instanceof \PDOException;
|
|
|
|
if ($isDbError) {
|
|
$ref['debug_info'] = $e->getFile() . " / LN : " . $e->getLine();
|
|
$ref['debug_msg'] = 'Database Error Occurred: ' . $e->getMessage();
|
|
$message = 'Database Error Occurred.';
|
|
} else {
|
|
$ref['debug_msg'] = 'An unexpected error occurred: ' . $e->getMessage();
|
|
$message = 'Something went wrong. Please try again later.';
|
|
}
|
|
|
|
return $this->respond([
|
|
'status' => 'error',
|
|
'code' => 500,
|
|
'data' => [],
|
|
'message'=> $message,
|
|
'ref' => $ref
|
|
], 200);
|
|
}
|
|
}
|
|
|
|
// 5.1) AgentMonthly generate the Excel file
|
|
public function downloadAgentMonthlyPoliciesExcel()
|
|
{
|
|
try{
|
|
$managerId = $this->request->getGet('manager_id');
|
|
$agentId = $this->request->getGet('agent_id');
|
|
// $month = $this->request->getGet('month');
|
|
|
|
if (empty($managerId) || empty($agentId)) {
|
|
|
|
$msg = "Missing: ";
|
|
$msg .= empty($managerId) ? "manager_id " : "";
|
|
$msg .= empty($agentId) ? "agent_id " : "";
|
|
// $msg .= empty($month) ? "month " : "";
|
|
$ref = ['debug_msg' => $msg];
|
|
return $this->response->setJSON(['status' => 'error','code' => 400,'data' => [],'message' => 'Missing required parameters','ref' => $ref])->setStatusCode(200);
|
|
}
|
|
|
|
// Renamed helper function for consistency: getAgentMonthlyPoliciesData
|
|
$data = $this->getMonthlyPoliciesData($managerId, $agentId); // , $month);
|
|
|
|
if (empty($data)) {
|
|
throw new \RuntimeException('No policies found for this agent for the specified month.', 404);
|
|
}
|
|
$lastIndex = count(reset($data)) - 1;
|
|
// usort($data, function($a, $b) use ($lastIndex) {
|
|
// return (float)$a[$lastIndex] <=> (float)$b[$lastIndex];
|
|
// });
|
|
usort($data, function($a, $b) use ($lastIndex) {
|
|
return (float)$b[$lastIndex] <=> (float)$a[$lastIndex];
|
|
});
|
|
$finalData = [];
|
|
$serialNo = 1;
|
|
foreach ($data as $row) {
|
|
$finalData[] = array_merge([$serialNo++], $row);
|
|
}
|
|
|
|
|
|
|
|
$header = ['S.No',
|
|
'Received Date', 'Assigned To',
|
|
'Insurer Name', 'Insurer Short Name',
|
|
'Insured Name', 'Vehicle Number',
|
|
'Payment Mode', 'Plan Type', 'Issue Date',
|
|
'Partner Code', 'Partner Name',
|
|
'Policy Number', 'Premium Amount'];
|
|
|
|
|
|
$finalData = [];
|
|
$serialNo = 1;
|
|
|
|
foreach ($data as $row) {
|
|
$finalData[] = array_merge([$serialNo++], $row);
|
|
}
|
|
|
|
// Calculate and append total
|
|
$lastColIndex = count($header) - 1; // Get index of the last column (Premium)
|
|
$grandTotal = array_sum(array_column($finalData, $lastColIndex));
|
|
|
|
$totalRow = array_fill(0, count($header), ''); // Create empty row of same width
|
|
$totalRow[$lastColIndex - 1] = 'Total:'; // Put label in 2nd to last
|
|
$totalRow[$lastColIndex] = $grandTotal; // Put sum in last
|
|
$finalData[] = $totalRow;
|
|
|
|
// $monthName = ($month === 'current') ? date('M_Y') : date('M_Y', strtotime('-1 month'));
|
|
$monthName = date('M Y') ;
|
|
$PartnerName = $finalData[0][11] ?? 'Partner';
|
|
$cleanPartnerName = str_replace(' ', '_', strtolower($PartnerName));
|
|
$fileName = $cleanPartnerName . '_Policies_Details_' . $monthName . '.xlsx';
|
|
|
|
// --- CALL CENTRALIZED FUNCTION ---
|
|
$this->streamExcelFile(
|
|
$header,
|
|
$finalData,
|
|
"Partner Policies Details for {$monthName}",
|
|
$fileName,
|
|
true // This will ignore the bold/alignment logic for the last row
|
|
);
|
|
|
|
|
|
return;
|
|
} catch (\Throwable $e) {
|
|
|
|
// ... (Your error handling remains the same) ...
|
|
$ref = [];
|
|
// Case 1: No Data Found (Soft Success JSON)
|
|
if ($e instanceof \RuntimeException && $e->getCode() === 404) {
|
|
$ref['message'] = 'No Data Found';
|
|
return $this->respond([
|
|
'status' => 'success',
|
|
'code' => 200,
|
|
'data' => [],
|
|
'message' => 'No Data Found',
|
|
'ref' => $ref
|
|
], 200);
|
|
}
|
|
|
|
// Case 2: Database or Other Error (Error JSON)
|
|
$isDbError = $e instanceof \CodeIgniter\Database\Exceptions\DatabaseException
|
|
|| $e instanceof \mysqli_sql_exception
|
|
|| $e instanceof \PDOException;
|
|
|
|
if ($isDbError) {
|
|
$ref['debug_info'] = $e->getFile() . " / LN : " . $e->getLine();
|
|
$ref['message'] = 'Database Error Occurred.';
|
|
$message = 'Database Error Occurred.';
|
|
} else {
|
|
$ref['message'] = 'An unexpected error occurred: ' . $e->getMessage();
|
|
$message = 'An unexpected error occurred: ' . $e->getMessage();
|
|
}
|
|
|
|
return $this->respond([
|
|
'status' => 'error',
|
|
'code' => 500,
|
|
'data' => [],
|
|
'message'=> $message,
|
|
'ref' => $ref
|
|
], 200);
|
|
}
|
|
}
|
|
|
|
// 5.2) Top 50 Agent the Excel file
|
|
public function downloadT50AgentPoliciesExcel()
|
|
{
|
|
|
|
try{
|
|
$managerId = $this->request->getGet('manager_id');
|
|
|
|
if (empty($managerId)) {
|
|
$msg = "Missing: manager_id";
|
|
$ref = ['debug_msg' => $msg];
|
|
return $this->response->setJSON(['status' => 'error', 'code' => 400, 'data' => [], 'message' => 'Missing required parameters', 'ref' => $ref])->setStatusCode(200);
|
|
}
|
|
|
|
// Renamed helper function for consistency: getAgentMonthlyPoliciesData
|
|
$data = $this->getMonthlyPolicyCountandPremiumAmount($managerId);
|
|
$header = ['S.No', 'Partner Code', 'Partner Name', 'Policy Count', 'Premium Amount'];
|
|
|
|
if (empty($data)) {
|
|
throw new \RuntimeException('No policies found.', 404);
|
|
}
|
|
|
|
$lastIndex = count(reset($data)) - 1;
|
|
// usort($data, function($a, $b) use ($lastIndex) {
|
|
// return (float)$a[$lastIndex] <=> (float)$b[$lastIndex];
|
|
// });
|
|
usort($data, function($a, $b) use ($lastIndex) {
|
|
return (float)$b[$lastIndex] <=> (float)$a[$lastIndex];
|
|
});
|
|
$finalData = [];
|
|
$serialNo = 1;
|
|
|
|
foreach ($data as $row) {
|
|
$finalData[] = array_merge([$serialNo++], $row);
|
|
}
|
|
|
|
|
|
// Calculate and append total
|
|
$lastColIndex = count($header) - 1; // Get index of the last column (Premium)
|
|
$grandTotal = array_sum(array_column($finalData, $lastColIndex));
|
|
|
|
$totalRow = array_fill(0, count($header), ''); // Create empty row of same width
|
|
$totalRow[$lastColIndex - 1] = 'Total:'; // Put label in 2nd to last
|
|
$totalRow[$lastColIndex] = $grandTotal; // Put sum in last
|
|
$finalData[] = $totalRow; // Add the total row to the final set
|
|
|
|
$monthName = date('M Y') ;
|
|
$fileName = 'Top_50_Partner_Policies_Details_' . $monthName . '.xlsx';
|
|
|
|
// --- CALL CENTRALIZED FUNCTION ---
|
|
$this->streamExcelFile(
|
|
$header,
|
|
$finalData,
|
|
"Top 50 Partner Policies Details - Monthly Report ".$monthName,
|
|
$fileName,
|
|
true // This will ignore the bold/alignment logic for the last row
|
|
);
|
|
|
|
return;
|
|
} catch (\Throwable $e) {
|
|
|
|
// ... (Your error handling remains the same) ...
|
|
$ref = [];
|
|
// Case 1: No Data Found (Soft Success JSON)
|
|
if ($e instanceof \RuntimeException && $e->getCode() === 404) {
|
|
$ref['message'] = 'No Data Found';
|
|
return $this->respond([
|
|
'status' => 'success',
|
|
'code' => 200,
|
|
'data' => [],
|
|
'message' => 'No Data Found',
|
|
'ref' => $ref
|
|
], 200);
|
|
}
|
|
|
|
// Case 2: Database or Other Error (Error JSON)
|
|
$isDbError = $e instanceof \CodeIgniter\Database\Exceptions\DatabaseException
|
|
|| $e instanceof \mysqli_sql_exception
|
|
|| $e instanceof \PDOException;
|
|
|
|
if ($isDbError) {
|
|
$ref['debug_info'] = $e->getFile() . " / LN : " . $e->getLine();
|
|
$ref['message'] = 'Database Error Occurred.';
|
|
$message = 'Database Error Occurred.';
|
|
} else {
|
|
$ref['message'] = 'An unexpected error occurred: ' . $e->getMessage();
|
|
$message = 'An unexpected error occurred: ' . $e->getMessage();
|
|
}
|
|
|
|
return $this->respond([
|
|
'status' => 'error',
|
|
'code' => 500,
|
|
'data' => [],
|
|
'message'=> $message,
|
|
'ref' => $ref
|
|
], 200);
|
|
}
|
|
}
|
|
|
|
// 6) Agents who all are Without Policies generate the Excel file (last 10 days no Policies created by the agents)
|
|
public function downloadAgentsWithoutPoliciesExcel()
|
|
{
|
|
try{
|
|
$managerId = $this->request->getGet('manager_id');
|
|
|
|
if (empty($managerId)) {
|
|
$msg = "Missing: ";
|
|
$msg .= empty($managerId) ? "manager_id " : "";
|
|
$ref = ['debug_msg' => $msg];
|
|
// $ref = ['debug_msg' => 'Missing required parameters: manager_id, broker_id, and month must be provided.'];
|
|
return $this->response->setJSON(['status' => 'error','code' => 400,'data' => [],'message' => 'Missing required parameters','ref' => $ref])->setStatusCode(200);
|
|
}
|
|
|
|
$data = $this->getAgentsWithoutPoliciesData($managerId);
|
|
|
|
if (empty($data)) {
|
|
throw new \RuntimeException('No Partners without policies found.', 404);
|
|
}
|
|
|
|
$header = ['S.No','Partner Code','Partner Name', 'Email', 'Mobile'];
|
|
|
|
$finalData = [];
|
|
$serialNo = 1; // Start counter at 1
|
|
|
|
// 2. Loop through and prepend the serial number
|
|
foreach ($data as $row) {
|
|
// We create a new array for each row
|
|
$finalData[] = [
|
|
$serialNo++,
|
|
$row['agent_code'],
|
|
$row['agent_name'],
|
|
$row['email'],
|
|
$row['mobile']
|
|
];
|
|
}
|
|
|
|
|
|
|
|
// End Date: Today
|
|
$endDate = date('Ymd');
|
|
// Start Date: 9 days ago (10th day is today)
|
|
$startDate = date('Ymd', strtotime('-9 days'));
|
|
|
|
// --- Filename Generation ---
|
|
|
|
$fileName = 'Partners_Without_Policies_' . $startDate . '_to_' . $endDate . '.xlsx';
|
|
|
|
// Example output: Agents_Without_Policies_20251206_to_20251215.xlsx
|
|
|
|
// --- CENTRALIZED CALL ---
|
|
$this->streamExcelFile(
|
|
$header,
|
|
$finalData,
|
|
"Partners Without Policies (Last 10 Days)",
|
|
$fileName,
|
|
false // This will ignore the bold/alignment logic for the last row
|
|
);
|
|
|
|
return;
|
|
} catch (\Throwable $e) {
|
|
|
|
// ... (Your error handling remains the same) ...
|
|
$ref = [];
|
|
// Case 1: No Data Found (Soft Success JSON)
|
|
if ($e instanceof \RuntimeException && $e->getCode() === 404) {
|
|
$ref['message'] = 'No Data Found';
|
|
return $this->respond([
|
|
'status' => 'success',
|
|
'code' => 200,
|
|
'data' => [],
|
|
'ref' => $ref
|
|
], 200);
|
|
}
|
|
|
|
// Case 2: Database or Other Error (Error JSON)
|
|
$isDbError = $e instanceof \CodeIgniter\Database\Exceptions\DatabaseException
|
|
|| $e instanceof \mysqli_sql_exception
|
|
|| $e instanceof \PDOException;
|
|
|
|
if ($isDbError) {
|
|
$ref['debug_info'] = $e->getFile() . " / LN : " . $e->getLine();
|
|
$ref['message'] = 'Database Error Occurred.';
|
|
} else {
|
|
$ref['message'] = 'An unexpected error occurred: ' . $e->getMessage();
|
|
}
|
|
|
|
return $this->respond([
|
|
'status' => 'error',
|
|
'code' => $e->getCode() ?: 500,
|
|
'data' => [],
|
|
'ref' => $ref
|
|
], 200);
|
|
}
|
|
}
|
|
|
|
// 7 Function to generate the Excel file
|
|
public function downloadStaffAndProductPoliciesExcel()
|
|
{
|
|
try{
|
|
$managerId = $this->request->getGet('manager_id');
|
|
$executiveId = $this->request->getGet('sales_executive_id');
|
|
$vehicleType = $this->request->getGet('vehicle_type');
|
|
$month = $this->request->getGet('month');
|
|
|
|
// --- ADDED VALIDATION (Simplified logic for clarity) ---
|
|
if (empty($managerId) || empty($executiveId) || empty($vehicleType) || empty($month)) {
|
|
$msg = "Missing: ";
|
|
$msg .= empty($managerId) ? "manager_id " : "";
|
|
$msg .= empty($executiveId) ? "sales_executive_id " : "";
|
|
$msg .= empty($vehicleType) ? "vehicle_type " : "";
|
|
$msg .= empty($month) ? "month " : "";
|
|
$ref = ['debug_msg' => $msg];
|
|
// $ref = ['debug_msg' => 'Missing required parameters: manager_id, broker_id, and month must be provided.'];
|
|
return $this->response->setJSON(['status' => 'error','code' => 400,'data' => [],'message' => 'Missing required parameters','ref' => $ref])->setStatusCode(200);
|
|
|
|
}
|
|
|
|
$data = $this->getStaffAndProductPoliciesExcel($managerId, $executiveId,$vehicleType, $month);
|
|
if (empty($data)) {
|
|
throw new \RuntimeException('No policies found for the specified month.', 404);
|
|
}
|
|
$lastIndex = count(reset($data)) - 1;
|
|
// usort($data, function($a, $b) use ($lastIndex) {
|
|
// return (float)$a[$lastIndex] <=> (float)$b[$lastIndex];
|
|
// });
|
|
usort($data, function($a, $b) use ($lastIndex) {
|
|
return (float)$b[$lastIndex] <=> (float)$a[$lastIndex];
|
|
});
|
|
$finalData = [];
|
|
$serialNo = 1;
|
|
foreach ($data as $row) {
|
|
$finalData[] = array_merge([$serialNo++], $row);
|
|
}
|
|
$executiveName = $finalData[0][12] ?? 'Sales Executive';
|
|
$vehicleType = $finalData[0][13] ?? 'Vehicle Type';
|
|
// Define column headers
|
|
|
|
$header = ['S.No',
|
|
'Received Date', 'Assigned To',
|
|
'Partner Name' , 'Partner Code',
|
|
'Insurer Name' ,'Insurer Short Name',
|
|
'Insured Name', 'Vehicle Number',
|
|
'Payment Mode', 'Plan Type',
|
|
'Sales Executive Name', 'Vehicle Type', 'Policy Number','Issued Date', 'Premium Amount'];
|
|
|
|
// --- 1. MODIFIED LOGIC: Throw RuntimeException if no data ---
|
|
|
|
|
|
// Calculate and append total
|
|
$lastColIndex = count($header) - 1; // Get index of the last column (Premium)
|
|
$grandTotal = array_sum(array_column($finalData, $lastColIndex));
|
|
|
|
$totalRow = array_fill(0, count($header), ''); // Create empty row of same width
|
|
$totalRow[$lastColIndex - 1] = 'Total:'; // Put label in 2nd to last
|
|
$totalRow[$lastColIndex] = $grandTotal; // Put sum in last
|
|
$finalData[] = $totalRow;
|
|
|
|
|
|
$monthName = ($month === 'current') ? date('M_Y') : date('M_Y', strtotime('-1 month'));
|
|
|
|
$cleanExecutiveName = str_replace(' ', '_', strtolower($executiveName));
|
|
$cleanVehicleType = str_replace(' ', '_', strtolower($vehicleType));
|
|
$fileName = $cleanExecutiveName . '_' . $cleanVehicleType . '_Policies_Details_' . $monthName . '.xlsx';
|
|
|
|
// --- CALL CENTRALIZED FUNCTION ---
|
|
$this->streamExcelFile(
|
|
$header,
|
|
$finalData,
|
|
"Staff And Product Policies Details for {$monthName}",
|
|
$fileName,
|
|
true // This will ignore the bold/alignment logic for the last row
|
|
);
|
|
|
|
return; // STOP CI4 rendering anything else
|
|
|
|
} catch (\Throwable $e) {
|
|
|
|
// ... (Your error handling remains the same) ...
|
|
$ref = [];
|
|
// Case 1: No Data Found (Soft Success JSON)
|
|
if ($e instanceof \RuntimeException && $e->getCode() === 404) {
|
|
$ref['message'] = 'No Data Found';
|
|
return $this->respond([
|
|
'status' => 'success',
|
|
'code' => 200,
|
|
'data' => [],
|
|
'message' => 'No Data Found',
|
|
'ref' => $ref
|
|
], 200);
|
|
}
|
|
|
|
// Case 2: Database or Other Error (Error JSON)
|
|
$isDbError = $e instanceof \CodeIgniter\Database\Exceptions\DatabaseException
|
|
|| $e instanceof \mysqli_sql_exception
|
|
|| $e instanceof \PDOException;
|
|
|
|
if ($isDbError) {
|
|
$ref['debug_info'] = $e->getFile() . " / LN : " . $e->getLine();
|
|
$ref['message'] = 'Database Error Occurred.';
|
|
$message = 'Database Error Occurred.';
|
|
} else {
|
|
$ref['message'] = 'An unexpected error occurred: ' . $e->getMessage();
|
|
$message = 'An unexpected error occurred: ' . $e->getMessage();
|
|
}
|
|
|
|
return $this->respond([
|
|
'status' => 'error',
|
|
'code' => 500,
|
|
'data' => [],
|
|
'message'=> $message,
|
|
'ref' => $ref
|
|
], 200);
|
|
}
|
|
}
|
|
|
|
// 8 ZIP inside 3 Excel
|
|
public function downloadExcelAsZIP($managerId = null)
|
|
{
|
|
// Ensure managerId is retrieved correctly if not passed as argument
|
|
$managerId = $managerId ?? $this->request->getGet('manager_id');
|
|
|
|
if (empty($managerId)) {
|
|
return $this->response->setJSON([
|
|
'status' => 'error',
|
|
'code' => 400,
|
|
'message' => 'Missing required parameter: manager_id'
|
|
]);
|
|
}
|
|
|
|
// 1. Fetch Data First
|
|
$monthlyData = $this->getMonthlyPoliciesData($managerId, null);
|
|
$lowPremiumData = $this->getLowPremiumAgentData($managerId);
|
|
$inactiveData = $this->getAgentsWithoutPoliciesData($managerId);
|
|
|
|
// 2. Add Total Rows where needed (Premium is usually the last index)
|
|
if (!empty($monthlyData)) {
|
|
$totalMonthly = array_sum(array_column($monthlyData, 12)); // Index 12 is 'premium_amount'
|
|
$monthlyData[] = ['', '', '', '', '', '', '', '', '', '', '', 'Total:', $totalMonthly];
|
|
}
|
|
|
|
if (!empty($lowPremiumData)) {
|
|
$totalLow = array_sum(array_column($lowPremiumData, 13)); // Index 13 is 'premium_amount'
|
|
$lowPremiumData[] = ['', '', '', '', '', '', '', '', '', '', '', '', 'Total:', $totalLow];
|
|
}
|
|
|
|
// 3. Prepare Report Configuration
|
|
$reports = [
|
|
'Monthly_Policies_Details.xlsx' => ['data' => $monthlyData, 'header' => ['Received Date', 'Assigned To', 'Insurer', 'Short Name', 'Insured', 'Reg No', 'Mode', 'Plan', 'Agent', 'Code', 'Policy #', 'Issued Date', 'Premium'], 'title' => "Monthly Report",'showTotal' => true],
|
|
'Low_Premium_Policies_Details.xlsx' => ['data' => $lowPremiumData, 'header' => ['Received Date', 'Assigned To', 'Insurer', 'Short Name', 'Insured', 'Reg No', 'Mode', 'Plan', 'Agent', 'Code', 'Status', 'Policy #', 'Issued Date', 'Premium'], 'title' => "Low Premium Report",'showTotal' => true],
|
|
'Partners_Without_Policies_Details.xlsx' => ['data' => $inactiveData, 'header' => ['Partner Name', 'Partner Code', 'Email', 'Mobile'], 'title' => "Inactive Agents",'showTotal' => false]
|
|
];
|
|
|
|
// 4. Initialize Zip
|
|
$zipFileName = 'Agent_Reports_' . date('Y-m-d_H-i') . '.zip';
|
|
$zipFilePath = tempnam(sys_get_temp_dir(), 'zip');
|
|
|
|
$zip = new \ZipArchive();
|
|
if ($zip->open($zipFilePath, \ZipArchive::CREATE | \ZipArchive::OVERWRITE) === TRUE) {
|
|
foreach ($reports as $name => $config) {
|
|
$excelContent = $this->generateExcelBinary($config['header'], $config['data'], $config['title'],$config['showTotal']);
|
|
$zip->addFromString($name, $excelContent);
|
|
}
|
|
$zip->close();
|
|
}
|
|
|
|
// 5. Direct Download
|
|
// Instead of creating a file on disk, we can send the ZIP data directly.
|
|
// This avoids the "deleteFileAfterSend" error entirely.
|
|
|
|
$zipData = file_get_contents($zipFilePath); // Read the zip file into a variable
|
|
unlink($zipFilePath); // Delete the temp file immediately
|
|
|
|
return $this->response->download($zipFileName, $zipData);
|
|
}
|
|
|
|
|
|
// GENERATE ZIP
|
|
private function generateExcelBinary(array $header, array $data, string $title, bool $showTotal = true): string
|
|
{
|
|
$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
|
|
$sheet = $spreadsheet->getActiveSheet();
|
|
|
|
// 1. Calculate dimensions
|
|
$columnCount = count($header);
|
|
$lastCol = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($columnCount);
|
|
$rowCount = count($data);
|
|
|
|
// 2. Title Styling
|
|
$sheet->mergeCells("A1:{$lastCol}1");
|
|
$sheet->setCellValue('A1', $title);
|
|
$sheet->getStyle('A1')->getFont()->setBold(true)->setSize(14);
|
|
$sheet->getStyle('A1')->getAlignment()->setHorizontal('center');
|
|
|
|
// 3. Headers (Row 2)
|
|
$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'); // Light gray background
|
|
|
|
// 4. Data (Starting Row 3)
|
|
$sheet->fromArray($data, NULL, 'A3');
|
|
|
|
// 5. Bold the Total Row (The last row of data)
|
|
if ($rowCount > 0 && $showTotal === true) {
|
|
$totalRowNumber = $rowCount + 2; // Row 1 (Title) + Row 2 (Header) + Data Rows
|
|
$sheet->getStyle("A{$totalRowNumber}:{$lastCol}{$totalRowNumber}")->getFont()->setBold(true);
|
|
|
|
// Optional: Add a top border to the total row to make it look professional
|
|
// $sheet->getStyle("A{$totalRowNumber}:{$lastCol}{$totalRowNumber}")->getBorders()->getTop()->setBorderStyle(\PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN);
|
|
}
|
|
|
|
// 6. Auto-size Columns
|
|
// Using column index to avoid issues with double-letter columns (e.g., AA, AB)
|
|
for ($i = 1; $i <= $columnCount; $i++) {
|
|
$colLetter = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($i);
|
|
$sheet->getColumnDimension($colLetter)->setAutoSize(true);
|
|
}
|
|
|
|
// 7. Capture Binary Output
|
|
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
|
|
|
|
// Use Output Buffering to grab the file content as a string
|
|
ob_start();
|
|
$writer->save('php://output');
|
|
$excelBinary = ob_get_clean();
|
|
|
|
return $excelBinary;
|
|
}
|
|
|
|
public function downloadStaffPendingSummaryExcel()
|
|
{
|
|
try{
|
|
$managerId = $this->request->getGet('manager_id');
|
|
|
|
|
|
// --- ADDED VALIDATION (Simplified logic for clarity) ---
|
|
if (empty($managerId)) {
|
|
$msg = "Missing: manager_id";
|
|
$ref = ['debug_msg' => $msg];
|
|
return $this->response->setJSON(['status' => 'error', 'code' => 400, 'data' => [], 'message' => 'Missing required parameters', 'ref' => $ref])->setStatusCode(200);
|
|
}
|
|
|
|
$data = $this->getStaffPendingSummaryExcel($managerId);
|
|
|
|
if (empty($data)) {
|
|
throw new \RuntimeException('No summary found.', 404);
|
|
}
|
|
|
|
// Define column headers
|
|
$header = ['S.No', 'Staff Name', 'Today Assigned', 'Pending', 'In Progress', 'Completed', 'Previous Pending'];
|
|
|
|
// Initialize totals
|
|
$sums = array_fill(2, 5, 0); // Start from index 2, cover 5 columns
|
|
$finalData = [];
|
|
$serialNo = 1;
|
|
|
|
// Process data and calculate sums
|
|
foreach ($data as $row) {
|
|
// Convert row to indexed array values to ensure merge works correctly
|
|
$rowData = array_values($row);
|
|
|
|
// Add Serial Number
|
|
$finalData[] = array_merge([$serialNo++], $rowData);
|
|
|
|
// Summing columns index 2 to 6
|
|
for ($i = 2; $i <= 6; $i++) {
|
|
// Use index $i-1 because $row doesn't have S.No yet, but $rowData does
|
|
$sums[$i] += (int)($rowData[$i - 1] ?? 0);
|
|
}
|
|
}
|
|
|
|
// Create the Total Row
|
|
$totalRow = array_fill(0, count($header), ''); // Create empty row
|
|
$totalRow[1] = 'Total:'; // Label under "Staff Name"
|
|
|
|
foreach ($sums as $index => $sumValue) {
|
|
// This ensures that even if the sum is 0, it puts the digit '0' in the cell
|
|
$totalRow[$index] = $sumValue;
|
|
}
|
|
|
|
// Fill sums into the total row
|
|
foreach ($sums as $index => $sumValue) {
|
|
$totalRow[$index] = $sumValue;
|
|
}
|
|
|
|
// Add to final data
|
|
$finalData[] = $totalRow;
|
|
|
|
$fileName = 'Staff_Level_Pending_Summary.xlsx';
|
|
|
|
|
|
// --- CALL CENTRALIZED FUNCTION ---
|
|
$this->streamExcelFile(
|
|
$header,
|
|
$finalData,
|
|
"Staff Level Pending Summary",
|
|
$fileName,
|
|
true
|
|
);
|
|
|
|
return; // STOP CI4 rendering anything else
|
|
|
|
} catch (\Throwable $e) {
|
|
|
|
// ... (Your error handling remains the same) ...
|
|
$ref = [];
|
|
// Case 1: No Data Found (Soft Success JSON)
|
|
if ($e instanceof \RuntimeException && $e->getCode() === 404) {
|
|
$ref['message'] = 'No Data Found';
|
|
return $this->respond([
|
|
'status' => 'success',
|
|
'code' => 200,
|
|
'data' => [],
|
|
'message' => 'No Data Found',
|
|
'ref' => $ref
|
|
], 200);
|
|
}
|
|
|
|
// Case 2: Database or Other Error (Error JSON)
|
|
$isDbError = $e instanceof \CodeIgniter\Database\Exceptions\DatabaseException
|
|
|| $e instanceof \mysqli_sql_exception
|
|
|| $e instanceof \PDOException;
|
|
|
|
if ($isDbError) {
|
|
$ref['debug_info'] = $e->getFile() . " / LN : " . $e->getLine();
|
|
$ref['message'] = 'Database Error Occurred.';
|
|
$message = 'Database Error Occurred.';
|
|
} else {
|
|
$ref['message'] = 'An unexpected error occurred: ' . $e->getMessage();
|
|
$message = 'An unexpected error occurred: ' . $e->getMessage();
|
|
}
|
|
|
|
return $this->respond([
|
|
'status' => 'error',
|
|
'code' => 500,
|
|
'data' => [],
|
|
'message'=> $message,
|
|
'ref' => $ref
|
|
], 200);
|
|
}
|
|
}
|
|
|
|
|
|
public function downloadStaffPendingSummaryExcelByID()
|
|
{
|
|
// try{
|
|
$managerId = $this->request->getGet('manager_id');
|
|
$staffId = $this->request->getGet('staff_id');
|
|
$status = $this->request->getGet('status');
|
|
|
|
|
|
// --- ADDED VALIDATION (Simplified logic for clarity) ---
|
|
if (empty($managerId) || empty($staffId) || empty($status)) {
|
|
$msg = "Missing: ";
|
|
$msg .= empty($managerId) ? "manager_id " : "";
|
|
$msg .= empty($staffId) ? "staff_id " : "";
|
|
$msg .= empty($status) ? "status " : "";
|
|
$ref = ['debug_msg' => $msg];
|
|
// $ref = ['debug_msg' => 'Missing required parameters: manager_id, broker_id, and month must be provided.'];
|
|
return $this->response->setJSON(['status' => 'error','code' => 400,'data' => [],'message' => 'Missing required parameters','ref' => $ref])->setStatusCode(200);
|
|
|
|
}
|
|
|
|
$data = $this->getStaffPendingSummaryExcelByID($managerId,$staffId,$status);
|
|
|
|
if (empty($data)) {
|
|
throw new \RuntimeException('No summary found.', 404);
|
|
}
|
|
|
|
// Define column headers
|
|
|
|
$header = ['S.No', 'Staff Name', 'REG Number','Received Date'];
|
|
|
|
// Initialize totals
|
|
// Initialize totals
|
|
$lastIndex = count(reset($data)) - 1;
|
|
// usort($data, function($a, $b) use ($lastIndex) {
|
|
// return (float)$a[$lastIndex] <=> (float)$b[$lastIndex];
|
|
// });
|
|
usort($data, function($a, $b) use ($lastIndex) {
|
|
return (float)$b[$lastIndex] <=> (float)$a[$lastIndex];
|
|
});
|
|
$finalData = [];
|
|
$serialNo = 1;
|
|
|
|
foreach ($data as $row) {
|
|
$finalData[] = array_merge([$serialNo++], $row);
|
|
}
|
|
|
|
$staffName = $finalData[0][1] ?? 'Staff';
|
|
|
|
$fileName = $staffName.'_'.$status.'_Summary.xlsx';
|
|
// Calculate and append total
|
|
|
|
$cleanStaffName = str_replace(' ', '_', strtolower($staffName));
|
|
$cleanStatus = ucwords(str_replace('_', ' ', strtolower($status)));
|
|
$fileName = $cleanStaffName . '_' . $cleanStatus . '_Summary.xlsx';
|
|
|
|
|
|
// --- CALL CENTRALIZED FUNCTION ---
|
|
$this->streamExcelFile(
|
|
$header,
|
|
$finalData,
|
|
$cleanStaffName ." ". $cleanStatus." Summary",
|
|
$fileName,
|
|
false
|
|
);
|
|
|
|
return; // STOP CI4 rendering anything else
|
|
|
|
// } catch (\Throwable $e) {
|
|
|
|
// // ... (Your error handling remains the same) ...
|
|
// $ref = [];
|
|
// // Case 1: No Data Found (Soft Success JSON)
|
|
// if ($e instanceof \RuntimeException && $e->getCode() === 404) {
|
|
// $ref['message'] = 'No Data Found';
|
|
// return $this->respond([
|
|
// 'status' => 'success',
|
|
// 'code' => 200,
|
|
// 'data' => [],
|
|
// 'message' => 'No Data Found',
|
|
// 'ref' => $ref
|
|
// ], 200);
|
|
// }
|
|
|
|
// // Case 2: Database or Other Error (Error JSON)
|
|
// $isDbError = $e instanceof \CodeIgniter\Database\Exceptions\DatabaseException
|
|
// || $e instanceof \mysqli_sql_exception
|
|
// || $e instanceof \PDOException;
|
|
|
|
// if ($isDbError) {
|
|
// $ref['debug_info'] = $e->getFile() . " / LN : " . $e->getLine();
|
|
// $ref['message'] = 'Database Error Occurred.';
|
|
// $message = 'Database Error Occurred.';
|
|
// } else {
|
|
// $ref['message'] = 'An unexpected error occurred: ' . $e->getMessage();
|
|
// $message = 'An unexpected error occurred: ' . $e->getMessage();
|
|
// }
|
|
|
|
// return $this->respond([
|
|
// 'status' => 'error',
|
|
// 'code' => 500,
|
|
// 'data' => [],
|
|
// 'message'=> $message,
|
|
// 'ref' => $ref
|
|
// ], 200);
|
|
// }
|
|
}
|
|
|
|
|
|
/**
|
|
* Executes the detailed policy query and extracts the data for the spreadsheet.
|
|
* @param string $managerId
|
|
* @param int $brokerId
|
|
* @param string $month ('current' or 'previous')
|
|
* @return array
|
|
*/
|
|
private function getBrokerPoliciesData($managerId, $brokerId, $month): array
|
|
{
|
|
// --- Correction 1: Initialize Database Connection ---
|
|
|
|
$data = [];
|
|
|
|
try {
|
|
$builder = $this->db->table('partner_policy pp');
|
|
// Note: I removed 'broker_id' from SELECT as it's redundant in the Excel sheet details
|
|
|
|
|
|
$builder->select('
|
|
DATE_FORMAT(pe.created_on, "%d-%m-%Y %h:%i %p") AS received_date,
|
|
S.name as assigned_to_name,
|
|
A.name as agent_name, A.agent_code,
|
|
I.name as insurer_name,I.short_name as insurer_short_name,
|
|
pe.name as insured_name,
|
|
pe.reg_no,
|
|
pm.value as payment_mode_value,
|
|
ipti.insurance_plan_type,
|
|
pb.name AS broker_name, DATE_FORMAT(pp.issued_date, "%d-%m-%Y") AS issued_date,CONCAT("\t", pp.policy_number) AS policy_number,
|
|
pp.premium_amount');
|
|
$builder->join('partner_enquiry pe', 'pe.id = pp.enquiry_id', 'left');
|
|
$builder->join('partner_brokers pb', 'pb.id = pe.broker_id', 'left');
|
|
$builder->join('partner_quotation Q', 'Q.enquiry_id = pe.id', 'left');
|
|
$builder->join('partner_payment_mode_master pm', 'pm.id = Q.payment_mode_id', 'left');
|
|
$builder->join('partner_agent A', 'A.id = pe.agent_id', 'left');
|
|
$builder->join('partner_insurance_plan_type_master ipti', 'ipti.id = Q.insurance_plan_type_id', 'left');
|
|
$builder->join('insurers I', 'I.id = Q.insurer_id', 'left');
|
|
$builder->join('partner_staff S', 'S.id = pe.assigned_to', 'left');
|
|
|
|
// --- Correction 2: Use Robust Date Range Filtering ---
|
|
if ($month === "current") {
|
|
// WHERE issued_date >= start_of_current_month AND issued_date < start_of_next_month
|
|
$builder->where("pp.issued_date >= DATE_FORMAT(CURRENT_DATE(), '%Y-%m-01')", NULL, FALSE);
|
|
$builder->where("pp.issued_date < DATE_FORMAT(DATE_ADD(CURRENT_DATE(), INTERVAL 1 MONTH), '%Y-%m-01')", NULL, FALSE);
|
|
}
|
|
else if ($month === "previous") {
|
|
// WHERE issued_date >= start_of_previous_month AND issued_date < start_of_current_month
|
|
$builder->where("pp.issued_date >= DATE_FORMAT(DATE_SUB(CURRENT_DATE(), INTERVAL 1 MONTH), '%Y-%m-01')", NULL, FALSE);
|
|
$builder->where("pp.issued_date < DATE_FORMAT(CURRENT_DATE(), '%Y-%m-01')", NULL, FALSE);
|
|
}
|
|
|
|
// Broker and Manager Filter
|
|
$builder->where('pp.manager_id', $managerId);
|
|
$builder->where('pb.id', $brokerId);
|
|
$builder->orderBy('pp.issued_date', 'DESC');
|
|
|
|
$results = $builder->get()->getResultArray();
|
|
|
|
// Restructure data for PhpSpreadsheet (2D array of values)
|
|
foreach ($results as $row) {
|
|
$data[] = array_values($row);
|
|
}
|
|
|
|
} catch (DatabaseException $e) {
|
|
log_message('error', 'Database Error during Excel fetch: ' . $e->getMessage());
|
|
// Re-throw the exception so it is caught by the main function's catch block
|
|
throw $e;
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* Executes the detailed policy query and extracts the data for the spreadsheet.
|
|
* @param string $managerId
|
|
* @param string $vehicleType
|
|
* @param string $month ('current' or 'previous')
|
|
* @return array
|
|
*/
|
|
private function getProductPoliciesData($managerId, $vehicleType, $month): array
|
|
{
|
|
// --- Correction 1: Initialize Database Connection ---
|
|
|
|
$data = [];
|
|
|
|
try {
|
|
$builder = $this->db->table('partner_policy pp');
|
|
// Note: I removed 'broker_id' from SELECT as it's redundant in the Excel sheet details
|
|
$builder->select('
|
|
DATE_FORMAT(pe.created_on, "%d-%m-%Y %h:%i %p") AS received_date,
|
|
S.name as assigned_to_name,
|
|
A.name as agent_name, A.agent_code,
|
|
I.name as insurer_name,I.short_name as insurer_short_name,
|
|
pe.name as insured_name,
|
|
pe.reg_no,
|
|
pm.value as payment_mode_value,
|
|
ipti.insurance_plan_type,
|
|
pp.vehicle_type, DATE_FORMAT(pp.issued_date, "%d-%m-%Y") AS issued_date,CONCAT("\t", pp.policy_number) AS policy_number,
|
|
pp.premium_amount');
|
|
|
|
$builder->join('partner_enquiry pe', 'pe.id = pp.enquiry_id', 'left');
|
|
$builder->join('partner_quotation Q', 'Q.enquiry_id = pe.id', 'left');
|
|
$builder->join('partner_payment_mode_master pm', 'pm.id = Q.payment_mode_id', 'left');
|
|
$builder->join('partner_agent A', 'A.id = pe.agent_id', 'left');
|
|
$builder->join('partner_insurance_plan_type_master ipti', 'ipti.id = Q.insurance_plan_type_id', 'left');
|
|
$builder->join('insurers I', 'I.id = Q.insurer_id', 'left');
|
|
$builder->join('partner_staff S', 'S.id = pe.assigned_to', 'left');
|
|
|
|
|
|
// --- Correction 2: Use Robust Date Range Filtering ---
|
|
if ($month === "current") {
|
|
// WHERE issued_date >= start_of_current_month AND issued_date < start_of_next_month
|
|
$builder->where("pp.issued_date >= DATE_FORMAT(CURRENT_DATE(), '%Y-%m-01')", NULL, FALSE);
|
|
$builder->where("pp.issued_date < DATE_FORMAT(DATE_ADD(CURRENT_DATE(), INTERVAL 1 MONTH), '%Y-%m-01')", NULL, FALSE);
|
|
}
|
|
else if ($month === "previous") {
|
|
// WHERE issued_date >= start_of_previous_month AND issued_date < start_of_current_month
|
|
$builder->where("pp.issued_date >= DATE_FORMAT(DATE_SUB(CURRENT_DATE(), INTERVAL 1 MONTH), '%Y-%m-01')", NULL, FALSE);
|
|
$builder->where("pp.issued_date < DATE_FORMAT(CURRENT_DATE(), '%Y-%m-01')", NULL, FALSE);
|
|
}
|
|
|
|
// Broker and Manager Filter
|
|
$builder->where('pp.manager_id', $managerId);
|
|
$builder->where('pp.vehicle_type', $vehicleType);
|
|
|
|
|
|
$results = $builder->get()->getResultArray();
|
|
|
|
// Restructure data for PhpSpreadsheet (2D array of values)
|
|
foreach ($results as $row) {
|
|
$data[] = array_values($row);
|
|
}
|
|
|
|
} catch (DatabaseException $e) {
|
|
log_message('error', 'Database Error during Excel fetch: ' . $e->getMessage());
|
|
// Re-throw the exception so it is caught by the main function's catch block
|
|
throw $e;
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* Executes the detailed policy query and extracts the data for the spreadsheet.
|
|
* @param string $managerId
|
|
* @param int $insurerId
|
|
* @param string $month ('current' or 'previous')
|
|
* @return array
|
|
*/
|
|
private function getInsurerPoliciesData($managerId, $insurerId, $month): array
|
|
{
|
|
// --- Correction 1: Initialize Database Connection ---
|
|
|
|
$data = [];
|
|
|
|
try {
|
|
$builder = $this->db->table('partner_policy pp');
|
|
// Note: I removed 'broker_id' from SELECT as it's redundant in the Excel sheet details
|
|
$builder->select('
|
|
DATE_FORMAT(pe.created_on, "%d-%m-%Y %h:%i %p") AS received_date,
|
|
S.name as assigned_to_name,
|
|
A.name as agent_name, A.agent_code,
|
|
pe.reg_no,
|
|
pm.value as payment_mode_value,
|
|
ipti.insurance_plan_type,
|
|
i.name AS insurer_name,i.short_name,pp.insured_name, DATE_FORMAT(pp.issued_date, "%d-%m-%Y") AS issued_date,CONCAT("\t", pp.policy_number) AS policy_number, pp.premium_amount');
|
|
|
|
$builder->join('partner_quotation pq', 'pq.id = pp.quotation_id', 'left');
|
|
$builder->join('insurers i', 'i.id = pq.insurer_id', 'left');
|
|
|
|
$builder->join('partner_enquiry pe', 'pe.id = pp.enquiry_id', 'left');
|
|
$builder->join('partner_payment_mode_master pm', 'pm.id = pq.payment_mode_id', 'left');
|
|
$builder->join('partner_agent A', 'A.id = pe.agent_id', 'left');
|
|
$builder->join('partner_insurance_plan_type_master ipti', 'ipti.id = pq.insurance_plan_type_id', 'left');
|
|
$builder->join('partner_staff S', 'S.id = pe.assigned_to', 'left');
|
|
|
|
// --- Correction 2: Use Robust Date Range Filtering ---
|
|
if ($month === "current") {
|
|
// WHERE issued_date >= start_of_current_month AND issued_date < start_of_next_month
|
|
$builder->where("pp.issued_date >= DATE_FORMAT(CURRENT_DATE(), '%Y-%m-01')", NULL, FALSE);
|
|
$builder->where("pp.issued_date < DATE_FORMAT(DATE_ADD(CURRENT_DATE(), INTERVAL 1 MONTH), '%Y-%m-01')", NULL, FALSE);
|
|
}
|
|
else if ($month === "previous") {
|
|
// WHERE issued_date >= start_of_previous_month AND issued_date < start_of_current_month
|
|
$builder->where("pp.issued_date >= DATE_FORMAT(DATE_SUB(CURRENT_DATE(), INTERVAL 1 MONTH), '%Y-%m-01')", NULL, FALSE);
|
|
$builder->where("pp.issued_date < DATE_FORMAT(CURRENT_DATE(), '%Y-%m-01')", NULL, FALSE);
|
|
}
|
|
|
|
// Broker and Manager Filter
|
|
$builder->where('pp.manager_id', $managerId);
|
|
$builder->where('i.id', $insurerId);
|
|
$builder->where('i.is_active',1);
|
|
$builder->orderBy('pp.issued_date', 'DESC');
|
|
// print_r($builder->getCompiledSelect());die;
|
|
$results = $builder->get()->getResultArray();
|
|
|
|
// Restructure data for PhpSpreadsheet (2D array of values)
|
|
foreach ($results as $row) {
|
|
$data[] = array_values($row);
|
|
}
|
|
|
|
} catch (DatabaseException $e) {
|
|
log_message('error', 'Database Error during Excel fetch: ' . $e->getMessage());
|
|
// Re-throw the exception so it is caught by the main function's catch block
|
|
throw $e;
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* Executes the detailed policy query and extracts the data for the spreadsheet.
|
|
* @param string $managerId
|
|
* @param int $executiveId
|
|
* @param string $vehicleType
|
|
* @param string $month ('current' or 'previous')
|
|
* @return array
|
|
*/
|
|
private function getStaffAndProductPoliciesExcel($managerId, $executiveId,$vehicleType, $month): array
|
|
{
|
|
// --- Correction 1: Initialize Database Connection ---
|
|
|
|
$data = [];
|
|
|
|
try {
|
|
$builder = $this->db->table('partner_policy pp');
|
|
|
|
$builder->select('
|
|
DATE_FORMAT(pe.created_on, "%d-%m-%Y %h:%i %p") AS received_date,
|
|
S.name as assigned_to_name,
|
|
pa.name as agent_name, pa.agent_code,
|
|
I.name as insurer_name,I.short_name as insurer_short_name,
|
|
pe.name as insured_name,
|
|
pe.reg_no,
|
|
pm.value as payment_mode_value,
|
|
ipti.insurance_plan_type,
|
|
pse.name as sales_executive_name, pp.vehicle_type AS vechile_type,CONCAT("\t", pp.policy_number) AS policy_number,DATE_FORMAT(pp.issued_date, "%d-%m-%Y") AS issued_date,pp.premium_amount');
|
|
$builder->join('partner_agent pa', 'pa.id = pp.agent_id', 'left');
|
|
$builder->join('partner_sales_executive pse', 'pse.id = pa.sales_executive_id', 'left');
|
|
|
|
$builder->join('partner_enquiry pe', 'pe.id = pp.enquiry_id', 'left');
|
|
$builder->join('partner_brokers pb', 'pb.id = pe.broker_id', 'left');
|
|
$builder->join('partner_quotation Q', 'Q.enquiry_id = pe.id', 'left');
|
|
$builder->join('partner_payment_mode_master pm', 'pm.id = Q.payment_mode_id', 'left');
|
|
|
|
$builder->join('partner_insurance_plan_type_master ipti', 'ipti.id = Q.insurance_plan_type_id', 'left');
|
|
$builder->join('insurers I', 'I.id = Q.insurer_id', 'left');
|
|
$builder->join('partner_staff S', 'S.id = pe.assigned_to', 'left');
|
|
|
|
|
|
// --- Correction 2: Use Robust Date Range Filtering ---
|
|
if ($month === "current") {
|
|
// WHERE issued_date >= start_of_current_month AND issued_date < start_of_next_month
|
|
$builder->where("pp.issued_date >= DATE_FORMAT(CURRENT_DATE(), '%Y-%m-01')", NULL, FALSE);
|
|
$builder->where("pp.issued_date < DATE_FORMAT(DATE_ADD(CURRENT_DATE(), INTERVAL 1 MONTH), '%Y-%m-01')", NULL, FALSE);
|
|
}
|
|
else if ($month === "previous") {
|
|
// WHERE issued_date >= start_of_previous_month AND issued_date < start_of_current_month
|
|
$builder->where("pp.issued_date >= DATE_FORMAT(DATE_SUB(CURRENT_DATE(), INTERVAL 1 MONTH), '%Y-%m-01')", NULL, FALSE);
|
|
$builder->where("pp.issued_date < DATE_FORMAT(CURRENT_DATE(), '%Y-%m-01')", NULL, FALSE);
|
|
}
|
|
|
|
// Broker and Manager Filter
|
|
$builder->where('pp.manager_id', $managerId);
|
|
$builder->where('pa.sales_executive_id', $executiveId);
|
|
$builder->where('pa.sales_executive_id IS NOT NULL');
|
|
$builder->where('pse.is_active', 1);
|
|
$builder->where('pp.vehicle_type', $vehicleType);
|
|
$builder->orderBy('pp.issued_date', 'DESC');
|
|
$results = $builder->get()->getResultArray();
|
|
|
|
// Restructure data for PhpSpreadsheet (2D array of values)
|
|
foreach ($results as $row) {
|
|
$data[] = array_values($row);
|
|
}
|
|
|
|
} catch (DatabaseException $e) {
|
|
log_message('error', 'Database Error during Excel fetch: ' . $e->getMessage());
|
|
// Re-throw the exception so it is caught by the main function's catch block
|
|
throw $e;
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Executes the detailed policy query and extracts the data for the spreadsheet.
|
|
* @param string $managerId
|
|
* @param int $AgentId
|
|
* @param string $month ('current' or 'previous')
|
|
* @return array
|
|
*/
|
|
private function getMonthlyPoliciesData($managerId, $AgentId): array
|
|
{
|
|
$data = [];
|
|
|
|
try {
|
|
$builder = $this->db->table('partner_policy pp');
|
|
|
|
// 1. Properly aligned Select Statement
|
|
$builder->select('
|
|
DATE_FORMAT(pe.created_on, "%d-%m-%Y %h:%i %p") AS received_date,
|
|
S.name AS assigned_to_name,
|
|
I.name AS insurer_name,
|
|
I.short_name AS insurer_short_name,
|
|
pe.name AS insured_name,
|
|
pe.reg_no,
|
|
pm.value AS payment_mode_value,
|
|
ipti.insurance_plan_type,
|
|
DATE_FORMAT(pp.issued_date, "%d-%m-%Y") AS issued_date,
|
|
pa.agent_code AS agent_code,
|
|
pa.name AS agent_name,
|
|
CONCAT("\t", pp.policy_number) AS policy_number,
|
|
pp.premium_amount
|
|
');
|
|
|
|
// 2. Joins
|
|
$builder->join('partner_agent pa', 'pp.agent_id = pa.id', 'inner');
|
|
$builder->join('partner_enquiry pe', 'pe.id = pp.enquiry_id', 'left');
|
|
$builder->join('partner_brokers pb', 'pb.id = pe.broker_id', 'left');
|
|
$builder->join('partner_quotation Q', 'Q.enquiry_id = pe.id', 'left');
|
|
$builder->join('partner_payment_mode_master pm', 'pm.id = Q.payment_mode_id', 'left');
|
|
$builder->join('partner_insurance_plan_type_master ipti', 'ipti.id = Q.insurance_plan_type_id', 'left');
|
|
$builder->join('insurers I', 'I.id = Q.insurer_id', 'left');
|
|
$builder->join('partner_staff S', 'S.id = pe.assigned_to', 'left');
|
|
|
|
// 3. Where Conditions
|
|
$builder->where('pp.manager_id', $managerId);
|
|
$builder->where('pp.policy_number IS NOT NULL');
|
|
$builder->where('pa.id', $AgentId);
|
|
|
|
|
|
// Current Month Date Range Filter
|
|
// if ($month === "current") {
|
|
// // WHERE issued_date >= start_of_current_month AND issued_date < start_of_next_month
|
|
$builder->where("pp.issued_date >= DATE_FORMAT(CURRENT_DATE(), '%Y-%m-01')", NULL, FALSE);
|
|
$builder->where("pp.issued_date < DATE_FORMAT(DATE_ADD(CURRENT_DATE(), INTERVAL 1 MONTH), '%Y-%m-01')", NULL, FALSE);
|
|
// }
|
|
// else if ($month === "previous") {
|
|
// // WHERE issued_date >= start_of_previous_month AND issued_date < start_of_current_month
|
|
// $builder->where("pp.issued_date >= DATE_FORMAT(DATE_SUB(CURRENT_DATE(), INTERVAL 1 MONTH), '%Y-%m-01')", NULL, FALSE);
|
|
// $builder->where("pp.issued_date < DATE_FORMAT(CURRENT_DATE(), '%Y-%m-01')", NULL, FALSE);
|
|
// }
|
|
|
|
// 4. Order and Limit
|
|
$builder->orderBy('pp.issued_date', 'DESC');
|
|
|
|
// 5. Fetch and Restructure
|
|
$results = $builder->get()->getResultArray();
|
|
|
|
foreach ($results as $row) {
|
|
// Using array_values ensures we return a indexed 2D array for PhpSpreadsheet
|
|
$data[] = array_values($row);
|
|
}
|
|
|
|
} catch (\CodeIgniter\Database\Exceptions\DatabaseException $e) {
|
|
log_message('error', 'Database Error during Excel fetch: ' . $e->getMessage());
|
|
throw $e;
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
|
|
public function getMonthlyPolicyCountandPremiumAmount($manager_id){
|
|
|
|
$data = [];
|
|
|
|
try {
|
|
$customDate = date('Y-m-d');
|
|
|
|
$builder = $this->db->table('partner_policy pp');
|
|
|
|
$builder->select("
|
|
pa.agent_code,
|
|
pa.name AS agent_name,
|
|
COUNT(pp.policy_number) AS policy_count,
|
|
SUM(pp.premium_amount) AS total_premium_amount
|
|
");
|
|
|
|
$builder->join('partner_agent pa', 'pp.agent_id = pa.id', 'inner');
|
|
$builder->join('partner_enquiry pe', 'pe.id = pp.enquiry_id', 'left');
|
|
|
|
$builder->where("MONTH(pp.issued_date) = MONTH('$customDate')", null, false);
|
|
$builder->where("YEAR(pp.issued_date) = YEAR('$customDate')", null, false);
|
|
|
|
$builder->where('pp.manager_id',$manager_id);
|
|
|
|
$builder->groupBy(['pa.id']);
|
|
$builder->orderBy('policy_count', 'DESC');
|
|
$builder->limit(50);
|
|
|
|
$results = $builder->get()->getResultArray();
|
|
|
|
// Restructure data for PhpSpreadsheet (2D array of values)
|
|
foreach ($results as $row) {
|
|
$data[] = array_values($row);
|
|
}
|
|
|
|
} catch (DatabaseException $e) {
|
|
log_message('error', 'Database Error during Excel fetch: ' . $e->getMessage());
|
|
// Re-throw the exception so it is caught by the main function's catch block
|
|
throw $e;
|
|
}
|
|
|
|
return $data;
|
|
|
|
}
|
|
|
|
/**
|
|
* Executes the detailed policy query and extracts the data for the spreadsheet.
|
|
* @param string $managerId
|
|
* @return array
|
|
*/
|
|
private function getAgentsWithoutPoliciesData($managerId): array
|
|
{
|
|
$data = [];
|
|
|
|
try {
|
|
$builder = $this->db->table('partner_agent pa');
|
|
$builder->select('pa.agent_code,pa.name AS agent_name, pa.email, pa.mobile');
|
|
|
|
$builder->join(
|
|
'partner_policy pp',
|
|
'pa.id = pp.agent_id AND pp.issued_date >= DATE_SUB(CURRENT_TIMESTAMP(), INTERVAL 10 DAY)',
|
|
'left'
|
|
);
|
|
$builder->where('pa.manager_id', $managerId);
|
|
$builder->where('pp.id IS NULL', null, false);
|
|
|
|
$builder->orderBy('pa.name', 'ASC');
|
|
|
|
$results = $builder->get()->getResultArray();
|
|
|
|
foreach ($results as $row) {
|
|
$data[] = array_values($row);
|
|
}
|
|
|
|
} catch (\CodeIgniter\Database\Exceptions\DatabaseException $e) {
|
|
log_message('error', 'Database Error during Excel fetch: ' . $e->getMessage());
|
|
throw $e;
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Executes the detailed policy query and extracts the data for the spreadsheet.
|
|
* @param string $managerId
|
|
* @return array
|
|
*/
|
|
private function getLowPremiumAgentData($managerId): array
|
|
{
|
|
// --- Correction 1: Initialize Database Connection ---
|
|
|
|
$data = [];
|
|
|
|
try {
|
|
$builder = $this->db->table('partner_policy pp');
|
|
|
|
$builder->select("
|
|
DATE_FORMAT(pe.created_on, '%d-%m-%Y %h:%i %p') AS received_date,
|
|
S.name as assigned_to_name,
|
|
I.name as insurer_name,I.short_name as insurer_short_name,
|
|
pe.name as insured_name,
|
|
pe.reg_no,
|
|
pm.value as payment_mode_value,
|
|
ipti.insurance_plan_type,
|
|
pa.name AS agent_name,
|
|
pa.agent_code,
|
|
CASE
|
|
WHEN pa.is_active = 1 THEN 'Active Partner'
|
|
ELSE 'Inactive Partner'
|
|
END AS agent_status,
|
|
CONCAT('\t', pp.policy_number) AS policy_number,
|
|
DATE_FORMAT(pp.issued_date, '%d-%m-%Y') AS issued_date,
|
|
pp.premium_amount
|
|
");
|
|
|
|
$builder->join('partner_agent pa', 'pa.id = pp.agent_id', 'inner');
|
|
|
|
$builder->join('partner_enquiry pe', 'pe.id = pp.enquiry_id', 'left');
|
|
$builder->join('partner_quotation Q', 'Q.enquiry_id = pe.id', 'left');
|
|
$builder->join('partner_payment_mode_master pm', 'pm.id = Q.payment_mode_id', 'left');
|
|
|
|
$builder->join('partner_insurance_plan_type_master ipti', 'ipti.id = Q.insurance_plan_type_id', 'left');
|
|
$builder->join('insurers I', 'I.id = Q.insurer_id', 'left');
|
|
$builder->join('partner_staff S', 'S.id = pe.assigned_to', 'left');
|
|
|
|
// WHERE conditions
|
|
$builder->where('pp.manager_id', $managerId);
|
|
// $builder->where('pa.id', $agentId);
|
|
$builder->where('pp.premium_amount <', 50000);
|
|
$builder->orderBy('pp.issued_date', 'DESC');
|
|
|
|
$results = $builder->get()->getResultArray();
|
|
|
|
// Restructure data for PhpSpreadsheet (2D array of values)
|
|
foreach ($results as $row) {
|
|
$data[] = array_values($row);
|
|
}
|
|
|
|
} catch (DatabaseException $e) {
|
|
log_message('error', 'Database Error during Excel fetch: ' . $e->getMessage());
|
|
// Re-throw the exception so it is caught by the main function's catch block
|
|
throw $e;
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
private function getStaffPendingSummaryExcel($managerId): array
|
|
{
|
|
|
|
$data = [];
|
|
|
|
try {
|
|
|
|
$results = $this->db->table('partner_enquiry pe')
|
|
->select("
|
|
ps.name AS staff_name,
|
|
COUNT(pe.id) AS total_assigned,
|
|
SUM(CASE WHEN DATE(pe.created_on) = CURDATE() THEN 1 ELSE 0 END) AS today_assigned,
|
|
SUM(CASE WHEN pe.enquiry_status = 'Assigned' AND DATE(pe.created_on) = CURDATE() THEN 1 ELSE 0 END) AS today_pending,
|
|
SUM(CASE WHEN pe.enquiry_status = 'In progress' AND DATE(pe.created_on) = CURDATE() THEN 1 ELSE 0 END) AS today_in_progress,
|
|
SUM(CASE WHEN pe.enquiry_status = 'Completed' AND DATE(pe.created_on) = CURDATE() THEN 1 ELSE 0 END) AS today_completed,
|
|
SUM(CASE WHEN pe.enquiry_status != 'Completed' THEN 1 ELSE 0 END) AS previous_total_pending,
|
|
")
|
|
->join('partner_staff ps', 'ps.id = pe.assigned_to', 'left')
|
|
->where('pe.manager_id', $managerId)
|
|
->where('pe.is_active', 1)
|
|
->where('pe.assigned_to IS NOT NULL')
|
|
->where('pe.assigned_to !=', 0)
|
|
->groupBy('pe.assigned_to')
|
|
->orderBy('ps.name', 'ASC')
|
|
->get()
|
|
->getResultArray();
|
|
|
|
|
|
// Restructure data for PhpSpreadsheet (2D array of values)
|
|
foreach ($results as $row) {
|
|
unset($row['total_assigned']);
|
|
$data[] = array_values($row);
|
|
}
|
|
|
|
} catch (DatabaseException $e) {
|
|
log_message('error', 'Database Error during Excel fetch: ' . $e->getMessage());
|
|
// Re-throw the exception so it is caught by the main function's catch block
|
|
throw $e;
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
private function getStaffPendingSummaryExcelByID($managerId, $staffId, $status): array
|
|
{
|
|
try {
|
|
$builder = $this->db->table('partner_enquiry pe');
|
|
|
|
// Note: Change 'received_date' back to 'created_on' or update the loop below
|
|
$builder->select("
|
|
ps.name AS staff_name,
|
|
CONCAT('\t', pe.reg_no) AS reg_no,
|
|
DATE_FORMAT(pe.created_on, '%d-%m-%Y %h:%i %p') AS created_on
|
|
", false);
|
|
|
|
$builder->join('partner_staff ps', 'ps.id = pe.assigned_to', 'left');
|
|
|
|
$builder->where('pe.manager_id', $managerId);
|
|
$builder->where('pe.assigned_to', $staffId);
|
|
$builder->where('pe.is_active', 1);
|
|
|
|
// Date boundaries
|
|
$todayStart = date('Y-m-d 00:00:00');
|
|
$todayEnd = date('Y-m-d 23:59:59');
|
|
|
|
switch ($status) {
|
|
case 'today_assigned':
|
|
$builder->where('pe.created_on >=', $todayStart);
|
|
$builder->where('pe.created_on <=', $todayEnd);
|
|
break;
|
|
|
|
case 'today_pending':
|
|
$builder->where('pe.enquiry_status', 'Assigned');
|
|
$builder->where('pe.created_on >=', $todayStart);
|
|
$builder->where('pe.created_on <=', $todayEnd);
|
|
break;
|
|
|
|
case 'today_in_progress':
|
|
$builder->where('pe.enquiry_status', 'In progress');
|
|
$builder->where('pe.created_on >=', $todayStart);
|
|
$builder->where('pe.created_on <=', $todayEnd);
|
|
break;
|
|
|
|
case 'today_completed':
|
|
$builder->where('pe.enquiry_status', 'Completed');
|
|
$builder->where('pe.created_on >=', $todayStart);
|
|
$builder->where('pe.created_on <=', $todayEnd);
|
|
break;
|
|
|
|
case 'previous_total_pending':
|
|
// "Previous Pending" usually means anything NOT completed from BEFORE today
|
|
$builder->where('pe.enquiry_status !=', 'Completed');
|
|
$builder->where('pe.created_on <', $todayStart);
|
|
break;
|
|
}
|
|
|
|
$results = $builder->get()->getResultArray();
|
|
|
|
$data = [];
|
|
foreach ($results as $row) {
|
|
$data[] = [
|
|
$row['staff_name'] ?? 'N/A',
|
|
$row['reg_no'] ?? '-',
|
|
$row['created_on'] ?? '-' // Matches the alias in select
|
|
];
|
|
}
|
|
|
|
return $data;
|
|
|
|
} catch (\Exception $e) {
|
|
log_message('error', 'Excel Fetch Error: ' . $e->getMessage());
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
}
|