nhance/app/Controllers/PolicyTransactionController.php

8715 lines
391 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Controllers;
use App\Controllers\BaseController;
use App\Controllers\GoogleDriveController;
use App\Helpers\DepositHelper;
use CodeIgniter\API\ResponseTrait;
use App\Models\PolicyTransactionModel;
use App\Models\PolicyTransactionStatusModel;
use App\Models\ClientModel;
use App\Models\ClientBranchModel;
use App\Models\ClientDepositModel;
use App\Models\ClientPolicyModel;
use App\Models\PolicyTypeModel;
use App\Models\InsurerBranchModel;
use App\Models\InsurerModel;
use App\Models\KYCEntityTypeModel;
use App\Models\ClientKYCDocsModel;
use App\Models\TPABranchModel;
use App\Models\TPAModel;
use App\Models\PTFileModel;
use App\Models\PTCOShareDetailsModel;
use App\Models\EmployeeModel;
use App\Models\UserTeamsModel;
use App\Models\UserModel;
use App\Models\EmployeePolicyModel;
use App\Models\InsurerStatements;
use App\Models\InvPaymentDetailsModel;
use App\Models\BatchFileModel;
use App\Models\FileModel;
use App\Models\COShareStmtDetailsModel;
use App\Models\BdsPlacementModel;
use Kint\Kint;
use App\Helpers\MailHelper;
use App\Helpers\ExcelSanitizeHelper;
use App\Models\NhanceBranchModel;
use App\Models\BDSDumpModel;
use App\Models\VehicleModel;
use App\Models\NotificationModel;
use CodeIgniter\CLI\CLI;
use Config\BdsConfig;
use Config\PtRenewalReminderConfig;
use Exception;
class PolicyTransactionController extends BaseController
{
use ResponseTrait;
protected $myLogger;
protected $policyTransactionModel;
protected $policyTransactionStatusModel;
protected $clientModel;
protected $clientPolicyModel;
protected $clientBranchModel;
protected $clientDepositModel;
protected $policyTypeModel;
protected $insurerBranchModel;
protected $insurerModel;
protected $kycEntityTypeModel;
protected $clientKYCDocsModel;
protected $tpaBranchModel;
protected $tpaModel;
protected $PTFileModel;
protected $PTCOShareDetailsModel;
protected $employeeModel;
protected $userTeamsModel;
protected $userModel;
protected $employeePolicyModel;
protected $insurerStatements;
protected $invoiceStatus;
protected $invPaymentDetailsModel;
protected $batchFileModel;
protected $filesModel;
protected $coShareStmtDetailsModel;
protected $BdsPlacementModel;
protected $nhanceBranchModel;
protected $bdsDumpModel;
protected $vehicleModel;
protected $notificationModel;
protected $bds_bulk_upload_excel_file_column;
public function __construct()
{
set_session_context('Policy Tranction');
$this->myLogger = \Config\Services::mylogger();
$this->clientModel = new ClientModel();
$this->clientBranchModel = new ClientBranchModel();
$this->policyTypeModel = new PolicyTypeModel();
$this->clientDepositModel = new ClientDepositModel();
$this->clientPolicyModel = new ClientPolicyModel();
$this->insurerBranchModel = new InsurerBranchModel();
$this->insurerModel = new InsurerModel();
$this->policyTransactionModel = new PolicyTransactionModel();
$this->policyTransactionStatusModel = new PolicyTransactionStatusModel();
$this->kycEntityTypeModel = new KYCEntityTypeModel();
$this->clientKYCDocsModel = new ClientKYCDocsModel();
$this->tpaBranchModel = new TPABranchModel();
$this->tpaModel = new TPAModel();
$this->PTFileModel = new PTFileModel();
$this->PTCOShareDetailsModel = new PTCOShareDetailsModel();
$this->employeeModel = new EmployeeModel();
$this->userTeamsModel = new UserTeamsModel();
$this->userModel = new UserModel();
$this->employeePolicyModel = new EmployeePolicyModel();
$this->insurerStatements = new InsurerStatements();
$this->invPaymentDetailsModel = new InvPaymentDetailsModel();
$this->batchFileModel = new BatchFileModel();
$this->filesModel = new FileModel();
$this->coShareStmtDetailsModel = new COShareStmtDetailsModel();
$this->BdsPlacementModel = new BdsPlacementModel();
$this->nhanceBranchModel = new NhanceBranchModel();
$this->bdsDumpModel = new BDSDumpModel();
$this->vehicleModel = new VehicleModel();
$this->notificationModel = new NotificationModel();
$this->invoiceStatus = [
'pending' => 'Pending',
'generated' => 'Generated',
'sent' => 'Sent',
'payment_received' => 'Payment<br> Received',
];
$this->bds_bulk_upload_excel_file_column = [
'sno' => [
'col_idx' => 0,
'col_cell_name' => 'A',
'col_name' => 'S.No.',
'is_mandatory' => false,
'data_type' => '',
'format' => null,
'allowed_values' => null,
'custom' => null,
'params' => null
],
'nhance_branch' => [
'col_idx' => 1,
'col_cell_name' => 'B',
'col_name' => 'Nhance Branch',
'is_mandatory' => true,
'data_type' => '',
'format' => null,
'allowed_values' => null,
'custom' => 'check_nhance_branch',
'params' => ['row', 'nhance_branch_data']
],
'vehicle_no' => [
'col_idx' => 2,
'col_cell_name' => 'C',
'col_name' => 'Vehicle No',
'is_mandatory' => true,
'data_type' => 'vehicle',
'format' => null,
'allowed_values' => null,
'custom' => 'check_rto_data',
'params' => ['row', 'rto_master']
],
'vehicle_type' => [
'col_idx' => 3,
'col_cell_name' => 'D',
'col_name' => 'Vehicle Type',
'is_mandatory' => true,
'data_type' => '',
'format' => null,
'allowed_values' => null,
'custom' => 'check_vehicle_type',
'params' => ['row', 'vehicle_type']
],
'policy_no' => [
'col_idx' => 4,
'col_cell_name' => 'E',
'col_name' => 'Policy No',
'is_mandatory' => true,
'data_type' => '',
'format' => null,
'allowed_values' => null,
'custom' => 'check_policy_no',
'params' => ['row', 'pt_data']
],
'insured_name' => [
'col_idx' => 5,
'col_cell_name' => 'F',
'col_name' => 'Insured Name',
'is_mandatory' => true,
'data_type' => '',
'format' => null,
'allowed_values' => null,
'custom' => null,
'params' => null
],
'insured_email' => [
'col_idx' => 6,
'col_cell_name' => 'G',
'col_name' => 'Insured Email',
'is_mandatory' => true,
'data_type' => 'email',
'format' => null,
'allowed_values' => null,
'custom' => null,
'params' => null
],
'insurer' => [
'col_idx' => 7,
'col_cell_name' => 'H',
'col_name' => 'Insurer',
'is_mandatory' => true,
'data_type' => '',
'format' => null,
'allowed_values' => null,
'custom' => 'check_insurer_exist',
'params' => ['row', 'insurer_data']
],
'insurer_branch' => [
'col_idx' => 8,
'col_cell_name' => 'I',
'col_name' => 'Insurer Branch',
'is_mandatory' => true,
'data_type' => '',
'format' => null,
'allowed_values' => null,
'custom' => 'check_insurer_branch_exist',
'params' => ['row', 'insurer_branch_data', 'insurers']
],
'policy_issue_date' => [
'col_idx' => 9,
'col_cell_name' => 'J',
'col_name' => 'Policy Issue Date',
'is_mandatory' => true,
'data_type' => 'date',
'format' => 'd/M/Y',
'allowed_values' => null,
'custom' => null,
'params' => null
],
'policy_start_date' => [
'col_idx' => 10,
'col_cell_name' => 'K',
'col_name' => 'Policy Start Date',
'is_mandatory' => true,
'data_type' => 'date',
'format' => 'd/M/Y',
'allowed_values' => null,
'custom' => null,
'params' => null
],
'policy_end_date' => [
'col_idx' => 11,
'col_cell_name' => 'L',
'col_name' => 'Policy End Date',
'is_mandatory' => true,
'data_type' => 'date',
'format' => 'd/M/Y',
'allowed_values' => null,
'custom' => null,
'params' => null
],
'revenue_type' => [
'col_idx' => 12,
'col_cell_name' => 'M',
'col_name' => 'Revenue Type',
'is_mandatory' => true,
'data_type' => '',
'format' => null,
'allowed_values' => ['NA', 'EA', 'EANR'],
'custom' => null,
'params' => null
],
'sales_generated_by' => [
'col_idx' => 13,
'col_cell_name' => 'N',
'col_name' => 'Sales Generated By',
'is_mandatory' => true,
'data_type' => '',
'format' => null,
'allowed_values' => null,
'custom' => 'check_user_exist',
'params' => ['row', 'col_key', 'user_data']
],
'serviced_by' => [
'col_idx' => 14,
'col_cell_name' => 'O',
'col_name' => 'Serviced By',
'is_mandatory' => true,
'data_type' => '',
'format' => null,
'allowed_values' => null,
'custom' => 'check_user_exist',
'params' => ['row', 'col_key', 'user_data']
],
'agent_code' => [
'col_idx' => 15,
'col_cell_name' => 'P',
'col_name' => 'Agent Code',
'is_mandatory' => true,
'data_type' => '',
'format' => null,
'allowed_values' => null,
'custom' => 'check_agent_exist',
'params' => ['row', 'pos_data']
],
'base_premium' => [
'col_idx' => 16,
'col_cell_name' => 'Q',
'col_name' => 'Base Premium',
'is_mandatory' => false,
'data_type' => 'positive_number',
'format' => 'positive_number',
'allowed_values' => null,
'custom' => null,
'params' => null
],
'non_commission_premium_amount' => [
'col_idx' => 17,
'col_cell_name' => 'R',
'col_name' => 'Non commission permium Amount',
'is_mandatory' => false,
'data_type' => 'positive_number',
'format' => 'positive_number',
'allowed_values' => null,
'custom' => null,
'params' => null
],
'tp_premium' => [
'col_idx' => 18,
'col_cell_name' => 'S',
'col_name' => 'TP Premium',
'is_mandatory' => false,
'data_type' => 'positive_number',
'format' => 'positive_number',
'allowed_values' => null,
'custom' => null,
'params' => null
],
'igst' => [
'col_idx' => 19,
'col_cell_name' => 'T',
'col_name' => 'IGST',
'is_mandatory' => false,
'data_type' => 'positive_number',
'format' => 'positive_number',
'allowed_values' => null,
'custom' => 'check_gst_percentage',
'params' => ['row']
],
'cgst' => [
'col_idx' => 20,
'col_cell_name' => 'U',
'col_name' => 'CGST',
'is_mandatory' => false,
'data_type' => 'positive_number',
'format' => 'positive_number',
'allowed_values' => null,
'custom' => 'check_gst_percentage',
'params' => ['row']
],
'sgst' => [
'col_idx' => 21,
'col_cell_name' => 'V',
'col_name' => 'SGST',
'is_mandatory' => false,
'data_type' => 'positive_number',
'format' => 'positive_number',
'allowed_values' => null,
'custom' => 'check_gst_percentage',
'params' => ['row']
],
'stamp_duty' => [
'col_idx' => 22,
'col_cell_name' => 'W',
'col_name' => 'Stamp Duty',
'is_mandatory' => false,
'data_type' => 'positive_number',
'format' => 'positive_number',
'allowed_values' => null,
'custom' => null,
'params' => null
],
// 'total' => [
// 'col_idx' => 23,
// 'col_cell_name' => 'X',
// 'col_name' => 'Total',
// 'is_mandatory' => false,
// 'data_type' => '',
// 'format' => null,
// 'allowed_values' => null,
// 'custom' => null,
// 'params' => null
// ],
'agreed_amount' => [
'col_idx' => 23,
'col_cell_name' => 'X',
'col_name' => 'Agreed Amount',
'is_mandatory' => false,
'data_type' => 'positive_number',
'format' => 'positive_number',
'allowed_values' => null,
'custom' => null,
'params' => null
],
'agreed_bp_percentage' => [
'col_idx' => 24,
'col_cell_name' => 'Y',
'col_name' => 'Agreed BP Percentage',
'is_mandatory' => false,
'data_type' => 'positive_number',
'format' => 'positive_number',
'allowed_values' => null,
'custom' => null,
'params' => null
],
'agreed_tp_percentage' => [
'col_idx' => 25,
'col_cell_name' => 'Z',
'col_name' => 'Agreed TP Percentage',
'is_mandatory' => false,
'data_type' => 'positive_number',
'format' => 'positive_number',
'allowed_values' => null,
'custom' => null,
'params' => null
],
// 'actual_bp_amount' => [
// 'col_idx' => 27,
// 'col_cell_name' => 'AB',
// 'col_name' => 'Actual BP Amount',
// 'is_mandatory' => false,
// 'data_type' => '',
// 'format' => null,
// 'allowed_values' => null,
// 'custom' => null,
// 'params' => null
// ],
// 'actual_tp_amount' => [
// 'col_idx' => 28,
// 'col_cell_name' => 'AC',
// 'col_name' => 'Actual TP Amount',
// 'is_mandatory' => false,
// 'data_type' => '',
// 'format' => null,
// 'allowed_values' => null,
// 'custom' => null,
// 'params' => null
// ],
// 'actual_bp_percentage' => [
// 'col_idx' => 29,
// 'col_cell_name' => 'AD',
// 'col_name' => 'Actual BP Percentage',
// 'is_mandatory' => false,
// 'data_type' => '',
// 'format' => null,
// 'allowed_values' => null,
// 'custom' => null,
// 'params' => null
// ],
// 'actual_tp_percentage' => [
// 'col_idx' => 30,
// 'col_cell_name' => 'AE',
// 'col_name' => 'Actual TP Percentage',
// 'is_mandatory' => false,
// 'data_type' => '',
// 'format' => null,
// 'allowed_values' => null,
// 'custom' => null,
// 'params' => null
// ],
// 'actual_bp_brokerage_amount' => [
// 'col_idx' => 31,
// 'col_cell_name' => 'AF',
// 'col_name' => 'Actual BP Brokerage Amount',
// 'is_mandatory' => false,
// 'data_type' => '',
// 'format' => null,
// 'allowed_values' => null,
// 'custom' => null,
// 'params' => null
// ],
// 'actual_tp_brokerage_amount' => [
// 'col_idx' => 32,
// 'col_cell_name' => 'AG',
// 'col_name' => 'Actual TP Brokerage Amount',
// 'is_mandatory' => false,
// 'data_type' => '',
// 'format' => null,
// 'allowed_values' => null,
// 'custom' => null,
// 'params' => null
// ],
// 'expected_amount' => [
// 'col_idx' => 33,
// 'col_cell_name' => 'AH',
// 'col_name' => 'Expected Amount',
// 'is_mandatory' => true,
// 'data_type' => '',
// 'format' => null,
// 'allowed_values' => null,
// 'custom' => null,
// 'params' => null
// ],
// 'rewards' => [
// 'col_idx' => 34,
// 'col_cell_name' => 'AI',
// 'col_name' => 'Rewards',
// 'is_mandatory' => false,
// 'data_type' => '',
// 'format' => null,
// 'allowed_values' => null,
// 'custom' => null,
// 'params' => null
// ],
];
}
// Policy Transaction Inception
public function viewInception()
{
$bds_edit_pt_id = $this->request->getGet('pt_id') ?? null;
$view = $this->request->getGet('view') ?? null;
$data['tab_name'] = 'Policies';
$data['page_name'] = 'Policies';
// Static arrays for dropdowns
$data['issuer'] = [1 => 'JIBS', 2 => 'Nhance'];
$data['issuer_branch'] = $this->nhanceBranchModel->where('is_active', 1)->findAll();
$data['client_type'] = [1 => 'Group', 2 => 'Individual'];
$data['issuing_type'] = [1 => 'Fresh', 2 => 'Renewal', 3 => 'Roll Over'];
$data['policy_status'] = [
'under_process' => 'Under Process',
'client_pending' => 'Client Pending',
'insurer_pending' => 'Insurer Pending',
'co_insurer_pending' => 'Co-Insurer Pending',
'tpa_pending' => 'TPA Pending',
'validated' => 'Validated',
'cancelled' => 'Cancelled',
'instalment_pending' => 'Instalment Pending',
'completed' => 'Completed',
'lost' => 'Lost',
];
$data['invoice_status_array'] = [
'yet_to_generate' => 'Pending',
'generated' => 'Generated',
'send' => 'Sent',
'recived' => 'Payment Received',
];
// $data['vehicle_type'] = [
// 'two_wheeler' => 'Two Wheeler',
// 'four_wheeler' => 'Four Wheeler',
// 'truck' => 'Truck',
// 'bus' => 'Bus',
// 'van' => 'Van',
// 'suv' => 'SUV',
// 'motorcycle' => 'Motorcycle',
// 'bicycle' => 'Bicycle'
// ];
$data['vehicle_type'] = db_connect()->table('vehicle_type')->where('is_active', 1)->get()->getResultArray();
$data['rto_details'] = db_connect()->table('rto_master')->where('is_active', 1)->get()->getResultArray();
$data['vehicle_des'] = [
'commercial' => 'Commercial',
'private' => 'Private',
];
$data['date_type'] = [
'policy_issue_date' => 'Policy Issue Date',
'policy_start_date' => 'Policy Start Date',
'policy_end_date' => 'Policy End Date',
];
// List rows are loaded via server-side DataTables AJAX.
$data['inception_data_list'] = [];
$data['inception_filters'] = $this->buildInceptionFiltersFromRequest();
// Fetch additional data
$data['client'] = $this->clientModel->where('is_active', 1)->findAll();
$data['client_branch'] = $this->clientBranchModel->where('is_active', 1)->findAll();
$data['policy_type'] = $this->policyTypeModel->where('is_active', 1)->findAll();
$data['insurer'] = $this->insurerModel->where('is_active', 1)->findAll();
$data['entity'] = $this->kycEntityTypeModel->where('is_active', 1)->findAll();
$data['policy_types'] = $this->policyTypeModel->where('is_active', 1)->findAll();
$data['insurer_branch'] = $this->insurerBranchModel->getInsurerBranchesWithInsurerNames();
$data['tpa'] = $this->tpaBranchModel->getTpaBranchesWithTpaNames();
// Fetch PP Teams Data
$data['ppTeamsData'] = $this->userModel
->where('is_active', 1)
->findAll();
// // Fetch Sales Team
// $data['salse_team'] = $this->userModel
// ->select('user_profiles.*,nhance_branch.id as nhance_branch_id, nhance_branch.branch_name as nhance_branch_name')
// ->join('user_teams', 'user_profiles.id = user_teams.user_id')
// ->join('nhance_branch', 'user_profiles.nhance_branch_id = nhance_branch.id','left')
// ->where('user_teams.team_id', 5)
// ->where('user_teams.is_active', 1)
// ->where('user_profiles.is_active', 1)
// ->findAll();
// // Fetch Partner Agent
// $data['partner_agent'] = db_connect()->table('partner_agent')
// ->where('is_active', 1)
// ->get()
// ->getResultArray();
// // Fetch ACM
// $data['ACM'] = $this->userModel
// ->where('role', 3) // Assuming `role` is in `user_profiles`
// ->where('is_active', 1)
// ->findAll();
// Fetch Sales Team
$data['salse_team'] = $this->userModel
->select('
user_profiles.*,
nhance_branch.id as nhance_branch_id,
nhance_branch.branch_name as nhance_branch_name,
rm.first_name AS rm_name
')
// ->join('user_teams', 'user_profiles.id = user_teams.user_id')
->join('nhance_branch', 'user_profiles.nhance_branch_id = nhance_branch.id','left')
->join('user_profiles AS rm', 'user_profiles.rm_id = rm.id', 'left')
// ->where('user_teams.team_id', 5)
// ->where('user_teams.is_active', 1)
->where('user_profiles.is_active', 1)
->groupBy('user_profiles.id', 'asc')
->findAll();
// Fetch Partner Agent
$data['partner_agent'] = db_connect()->table('partner_agent')
->where('is_active', 1)
->get()
->getResultArray();
// Fetch ACM
$data['ACM'] = $this->userModel
->select('
user_profiles.*,
nhance_branch.id AS nhance_branch_id,
nhance_branch.branch_name AS nhance_branch_name,
rm.first_name AS rm_name
')
->join('user_teams', 'user_profiles.id = user_teams.user_id')
->join('nhance_branch', 'user_profiles.nhance_branch_id = nhance_branch.id', 'left')
->join('user_profiles AS rm', 'user_profiles.rm_id = rm.id', 'left')
// ->where('user_profiles.role', 3)
->where('user_profiles.is_active', 1)
->groupBy('user_profiles.id', 'asc')
->findAll();
// dd($data);
//Fetch POS
$data['pos_data'] = db_connect()->table('partner_pos')
->where('is_active', 1)
->get()
->getResultArray();
// Load view
$this->loadLayout('policy_transaction_inception_list', $data);
}
public function inceptionListDataTable()
{
if (!$this->request->isAJAX()) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Invalid request.',
]);
}
$draw = (int) ($this->request->getPost('draw') ?? 0);
$start = max(0, (int) ($this->request->getPost('start') ?? 0));
$length = (int) ($this->request->getPost('length') ?? 10);
$search = trim((string) ($this->request->getPost('search')['value'] ?? ''));
$filters = $this->buildInceptionFiltersFromRequest();
$result = $this->policyTransactionModel->getInceptionTranctionListDataTable(
$draw,
$start,
$length,
$search,
$filters
);
$rows = [];
foreach ($result['data'] as $index => $row) {
$rows[] = $this->formatInceptionRowForDataTable($row, $start + $index + 1);
}
return $this->response->setJSON([
'draw' => $result['draw'],
'recordsTotal' => $result['recordsTotal'],
'recordsFiltered' => $result['recordsFiltered'],
'data' => $rows,
'cache_expires_in_ms' => $result['cache_expires_in_ms'] ?? 300000,
]);
}
public function clearInceptionListCache()
{
if (!$this->request->isAJAX()) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Invalid request.',
]);
}
session()->set('inception_list_cache_version', time());
return $this->response->setJSON([
'status' => true,
'message' => 'Inception list cache cleared.',
]);
}
protected function buildInceptionFiltersFromRequest(): array
{
$normalize = static function ($value) {
return (!isset($value) || $value === '' || $value === null) ? 0 : $value;
};
$ids = [];
if ($this->request->is('post')) {
$postIds = $this->request->getPost('ids') ?? '';
$ids = array_filter(explode(',', (string) $postIds));
}
return [
'start_date' => $normalize($this->request->getGet('start_date') ?? $this->request->getPost('start_date')),
'end_date' => $normalize($this->request->getGet('end_date') ?? $this->request->getPost('end_date')),
'client_id' => $normalize($this->request->getGet('client_id') ?? $this->request->getPost('client_id')),
'insurer_id' => $normalize($this->request->getGet('insurer_id') ?? $this->request->getPost('insurer_id')),
'policy_type_id' => $normalize($this->request->getGet('policy_type_id') ?? $this->request->getPost('policy_type_id')),
'date_type' => $normalize($this->request->getGet('date_type') ?? $this->request->getPost('date_type')),
'issuer' => $normalize($this->request->getGet('issuer') ?? $this->request->getPost('issuer')),
'status' => $normalize($this->request->getGet('status') ?? $this->request->getPost('status')),
'ids' => $ids,
'cache_version' => (int) (session()->get('inception_list_cache_version') ?? 1),
];
}
protected function formatInceptionRowForDataTable(array $row, int $serialNo): array
{
$issuerMap = [1 => 'JIBS', 2 => 'Nhance'];
$issuingTypeMap = [1 => 'Fresh', 2 => 'Renewal', 3 => 'Roll Over'];
$clientTypeMap = [1 => 'Group', 2 => 'Individual'];
$policyStatusMap = [
'under_process' => 'Under Process',
'client_pending' => 'Client Pending',
'insurer_pending' => 'Insurer Pending',
'co_insurer_pending' => 'Co-Insurer Pending',
'tpa_pending' => 'TPA Pending',
'validated' => 'Validated',
'cancelled' => 'Cancelled',
'instalment_pending' => 'Instalment Pending',
'completed' => 'Completed',
'lost' => 'Lost',
];
$clientBranch = ((int) ($row['client_type'] ?? 0) === 2)
? (($row['client_name'] ?? 'N/A') . ' - ' . (!empty($row['pan']) ? $row['pan'] : 'N/A'))
: (($row['client_short_name'] ?? 'N/A') . ' - ' . ($row['client_branch_name'] ?? 'N/A'));
$editAction = '<a class="dropdown-item btnEdit" data-id="' . ($row['id'] ?? '') . '" onclick="alertEveryFiveSeconds(\'' . htmlspecialchars((string) ($row['id'] ?? ''), ENT_QUOTES) . '\')"><i class="mdi mdi-pencil mr-2 text-muted font-18 vertical-middle"></i>Edit</a>';
$deleteAction = '';
if ((int) get_role_id() === 5) {
$deleteAction = '<a class="dropdown-item delete" data-id="' . ($row['id'] ?? '') . '" onclick="removePolicyTransaction(this, \'' . htmlspecialchars((string) ($row['id'] ?? ''), ENT_QUOTES) . '\', ' . (int) ($row['policy_type_id'] ?? 0) . ')"><i class="mdi mdi-delete mr-2 text-muted font-18 vertical-middle"></i>Delete</a>';
}
$actionHtml = '<div class="btn-group dropdown"><a href="javascript: void(0);" class="dropdown-toggle arrow-none btn btn-light btn-sm" data-toggle="dropdown" aria-expanded="false"><i class="mdi mdi-dots-horizontal"></i></a><div class="dropdown-menu dropdown-menu-right">' . $editAction . $deleteAction . '</div></div>';
return [
0 => $serialNo,
1 => $issuerMap[$row['issuer'] ?? 2] ?? 'Nhance',
2 => $issuingTypeMap[$row['issue_type'] ?? 0] ?? 'N/A',
3 => $clientTypeMap[$row['client_type'] ?? 0] ?? 'N/A',
4 => $clientBranch,
5 => $row['insurer_short_name'] ?: 'N/A',
6 => $row['policy_type'] ?: 'N/A',
7 => $row['policy_no'] ?: 'N/A',
8 => empty($row['policy_issue_date']) ? 'N/A' : date('d/m/Y', strtotime($row['policy_issue_date'])),
9 => empty($row['policy_start_date']) ? 'N/A' : date('d/m/Y', strtotime($row['policy_start_date'])),
10 => empty($row['policy_end_date']) ? 'N/A' : date('d/m/Y', strtotime($row['policy_end_date'])),
11 => $row['emp_count'] ?: '0',
12 => $row['dependent_count'] ?: '0',
13 => $policyStatusMap[$row['status'] ?? ''] ?? 'N/A',
14 => $row['user_name'] ?: 'N/A',
15 => $actionHtml,
];
}
public function viewInception2()
{
$bds_edit_pt_id = $this->request->getGet('pt_id') ?? null;
$data['tab_name'] = 'Policies';
$data['page_name'] = 'Policies';
// Static arrays for dropdowns
$data['issuer'] = [1 => 'JIBS', 2 => 'Nhance'];
$data['issuer_branch'] = $this->nhanceBranchModel->where('is_active', 1)->findAll();
$data['client_type'] = [1 => 'Group', 2 => 'Individual'];
$data['issuing_type'] = [1 => 'Fresh', 2 => 'Renewal', 3 => 'Roll Over'];
$data['policy_status'] = [
'under_process' => 'Under Process',
'client_pending' => 'Client Pending',
'insurer_pending' => 'Insurer Pending',
'co_insurer_pending' => 'Co-Insurer Pending',
'tpa_pending' => 'TPA Pending',
'validated' => 'Validated',
'cancelled' => 'Cancelled',
'instalment_pending' => 'Instalment Pending',
'completed' => 'Completed',
'lost' => 'Lost',
];
$data['invoice_status_array'] = [
'yet_to_generate' => 'Pending',
'generated' => 'Generated',
'send' => 'Sent',
'recived' => 'Payment Received',
];
// $data['vehicle_type'] = [
// 'two_wheeler' => 'Two Wheeler',
// 'four_wheeler' => 'Four Wheeler',
// 'truck' => 'Truck',
// 'bus' => 'Bus',
// 'van' => 'Van',
// 'suv' => 'SUV',
// 'motorcycle' => 'Motorcycle',
// 'bicycle' => 'Bicycle'
// ];
$data['vehicle_type'] = db_connect()->table('vehicle_type')->where('is_active', 1)->get()->getResultArray();
$data['rto_details'] = db_connect()->table('rto_master')->where('is_active', 1)->get()->getResultArray();
$data['vehicle_des'] = [
'commercial' => 'Commercial',
'private' => 'Private',
];
$data['date_type'] = [
'policy_issue_date' => 'Policy Issue Date',
'policy_start_date' => 'Policy Start Date',
'policy_end_date' => 'Policy End Date',
];
// Filter data
$start_date = $this->request->getGet('start_date');
$end_date = $this->request->getGet('end_date');
$client_id = $this->request->getGet('client_id');
$insurer_id = $this->request->getGet('insurer_id');
$policy_type_id = $this->request->getGet('policy_type_id');
$date_type = $this->request->getGet('date_type');
$issuer = $this->request->getGet('issuer');
$status = $this->request->getGet('status');
// Handle null or empty values
$start_date = empty($start_date) ? 0 : $start_date;
$end_date = empty($end_date) ? 0 : $end_date;
$client_id = empty($client_id) ? 0 : $client_id;
$insurer_id = empty($insurer_id) ? 0 : $insurer_id;
$policy_type_id = empty($policy_type_id) ? 0 : $policy_type_id;
$date_type = empty($date_type) ? 0 : $date_type;
$issuer = empty($issuer) ? 0 : $issuer;
$status = empty($status) ? 0 : $status; // Corrected from `$issuer`
if(empty($bds_edit_pt_id)){
if ($this->request->is('get')) {
// Fetch inception data list
$data['inception_data_list'] = $this->policyTransactionModel->getInceptionTranctionListData(
$start_date,
$end_date,
$client_id,
$insurer_id,
$policy_type_id,
$date_type,
$issuer,
$status
);
} else {
$ids = $this->request->getPost('ids');
$ids = array_filter(explode(',', $ids));
$data['inception_data_list'] = $this->policyTransactionModel->getInceptionTranctionListData(
$start_date = 0,
$end_date = 0,
$client_id = 0,
$insurer_id = 0,
$policy_type_id = 0,
$date_type = 0,
$issuer = 0,
$status = 0,
$ids
);
}
}else{
$data['inception_data_list'] = [];
}
// Fetch additional data
$data['client'] = $this->clientModel->where('is_active', 1)->findAll();
$data['client_branch'] = $this->clientBranchModel->where('is_active', 1)->findAll();
$data['policy_type'] = $this->policyTypeModel->where('is_active', 1)->findAll();
$data['insurer'] = $this->insurerModel->where('is_active', 1)->findAll();
$data['entity'] = $this->kycEntityTypeModel->where('is_active', 1)->findAll();
$data['policy_types'] = $this->policyTypeModel->where('is_active', 1)->findAll();
$data['insurer_branch'] = $this->insurerBranchModel->getInsurerBranchesWithInsurerNames();
$data['tpa'] = $this->tpaBranchModel->getTpaBranchesWithTpaNames();
// Fetch PP Teams Data
$data['ppTeamsData'] = $this->userModel
->where('is_active', 1)
->findAll();
// Fetch Sales Team
$data['salse_team'] = $this->userModel
->select('
user_profiles.*,
nhance_branch.id as nhance_branch_id,
nhance_branch.branch_name as nhance_branch_name,
rm.first_name AS rm_name
')
->join('user_teams', 'user_profiles.id = user_teams.user_id')
->join('nhance_branch', 'user_profiles.nhance_branch_id = nhance_branch.id','left')
->join('user_profiles AS rm', 'user_profiles.rm_id = rm.id', 'left')
->where('user_teams.team_id', 5)
->where('user_teams.is_active', 1)
->where('user_profiles.is_active', 1)
->groupBy('user_profiles.id', 'asc')
->findAll();
// Fetch Partner Agent
$data['partner_agent'] = db_connect()->table('partner_agent')
->where('is_active', 1)
->get()
->getResultArray();
// Fetch ACM
$data['ACM'] = $this->userModel
->select('
user_profiles.*,
nhance_branch.id AS nhance_branch_id,
nhance_branch.branch_name AS nhance_branch_name,
rm.first_name AS rm_name
')
->join('user_teams', 'user_profiles.id = user_teams.user_id')
->join('nhance_branch', 'user_profiles.nhance_branch_id = nhance_branch.id', 'left')
->join('user_profiles AS rm', 'user_profiles.rm_id = rm.id', 'left')
->where('user_profiles.role', 3)
->where('user_profiles.is_active', 1)
->groupBy('user_profiles.id', 'asc')
->findAll();
// echo '<pre>';
// print_r($data['ppTeamsData']); die;
// dd($data);
// Load view
$this->loadLayout('policy_transaction_inception_list_2', $data);
}
// policy Transaction Create function start
public function createInceptionPolicy()
{
session()->set('inception_list_cache_version', time());
$post_data = $this->request->getPost();
$rules = [
// ==========================================
// 1. CLIENT SECTION (5 Fields)
// ==========================================
'client_type' => ['label' => 'Client Type', 'rules' => 'required', 'errors' => ['required' => 'Client Type must be selected.']],
'client_id' => ['label' => 'Client', 'rules' => 'required', 'errors' => ['required' => 'Please select a Client.']],
'issue_type' => ['label' => 'Business Type', 'rules' => 'required', 'errors' => ['required' => 'Please select a Business Type.']],
'ref' => ['label' => 'Reference', 'rules' => 'permit_empty|regex_match[/^[a-zA-Z0-9 _-]+$/]', 'errors' => [
'regex_match' => 'The {field} can only contain letters, numbers, spaces, dashes, and underscores.'
]],
// ==========================================
// 5. SALES SECTION (12 Fields)
// ==========================================
'base_policy' => ['label' => 'Base Policy', 'rules' => 'permit_empty', 'errors' => []],
'policy_no' => [
'label' => 'Policy Number',
'rules' => 'required|regex_match[/^[a-zA-Z0-9\/_-]+$/]',
'errors' => [
'required' => 'Policy Number is Must.',
'regex_match' => 'Policy Number can only contain letters, numbers, and symbols like / - or _'
]
],
'policy_issue_date' => [
'label' => 'Issue Date',
'rules' => 'required|valid_date[Y-m-d]|regex_match[/^\d{4}-\d{2}-\d{2}$/]',
'errors' => [
'required' => 'Policy Issue Date is required.',
'valid_date' => 'Please provide a valid Policy Issue Date.',
'regex_match' => 'The Policy Issue Date format is incorrect. '
]
],
'month' => ['label' => 'Issue Month', 'rules' => 'required', 'errors' => [
'required' => 'Please select or enter the Policy Issue Month.'
]],
'policy_start_date' => [
'label' => 'D.O.C',
'rules' => 'required|valid_date[Y-m-d]|regex_match[/^\d{4}-\d{2}-\d{2}$/]',
'errors' => [
'required' => 'D.O.C (Start Date) is required.',
'valid_date' => 'Please provide a valid D.O.C date.',
'regex_match' => 'The D.O.C date format is incorrect. '
]
],
'policy_end_date' => ['label' => 'D.O.E', 'rules' => 'required|valid_date[Y-m-d]|regex_match[/^\d{4}-\d{2}-\d{2}$/]', 'errors' => [
'required' => 'D.O.E (Expiry Date) is required.',
'valid_date' => 'Please provide a valid D.O.E date.',
'regex_match' => 'The D.O.E date format is incorrect. '
]],
'emp_count' => ['label' => 'No of Employees', 'rules' => 'permit_empty|numeric', 'errors' => [
'numeric' => 'No of Employees must contain only numbers.'
]],
'dependent_count' => ['label' => 'No of Dependents', 'rules' => 'permit_empty|numeric', 'errors' => [
'numeric' => 'No of Dependents must contain only numbers.'
]],
'installment' => ['label' => 'Installment', 'rules' => 'permit_empty|regex_match[/^[a-zA-Z0-9 _-]+$/]', 'errors' => [
'regex_match' => 'The {field} can only contain letters, numbers, spaces, dashes, and underscores.'
]],
'installment_data' => ['label' => 'Installment Data', 'rules' => 'permit_empty|regex_match[/^[a-zA-Z0-9 _-]+$/]', 'errors' => [
'regex_match' => 'The {field} can only contain letters, numbers, spaces, dashes, and underscores.'
]],
'co_share' => ['label' => 'CoP Yes', 'rules' => 'permit_empty', 'errors' => []],
'bro_payable_by' => ['label' => 'Remuneration Pay By', 'rules' => 'permit_empty', 'errors' => []],
'renewal_date' => ['label' => 'Renewal Date', 'rules' => 'required|valid_date[Y-m-d]|regex_match[/^\d{4}-\d{2}-\d{2}$/]', 'errors' => [
'required' => 'Renewal Date is required.',
'valid_date' => 'Please provide a valid Renewal Date.',
'regex_match' => 'The Renewal Date format is incorrect. '
]],
'sales_generated_by' => ['label' => 'Sales Generated By', 'rules' => 'permit_empty', 'errors' => [
// 'required' => 'Please select the person who generated this sale.'
]],
'serviced_by' => ['label' => 'Serviced By', 'rules' => 'permit_empty', 'errors' => [
// 'required' => 'Please select the service person for this policy.'
]],
'pos_id' => ['label' => 'POS', 'rules' => 'permit_empty', 'errors' => []],
'doc_name.*' => [
'label' => 'Policy Document Name',
'rules' => 'permit_empty|regex_match[/^[a-zA-Z0-9 \/_-]+$/]|min_length[2]|max_length[100]',
'errors' => [
'regex_match' => 'The {field} can only contain letters, numbers, spaces, dashes, and underscores.'
]
],
'other_docs_name.*' => [
'label' => 'Vehicle Document Name',
'rules' => 'permit_empty|regex_match[/^[a-zA-Z0-9 \/_-]+$/]|min_length[2]|max_length[100]',
'errors' => [
'regex_match' => 'The {field} can only contain letters, numbers, spaces, dashes, and underscores.'
]
],
// ==========================================
// 6. PREMIUM DETAILS (Array Fields - 25 Fields)
// Use .* because these come from the dynamic table
// ==========================================
'follow_insurer_id.*' => ['label' => 'Insurer', 'rules' => 'required', 'errors' => ['required' => 'Please select an Insurer.']],
'co_share_type.*' => ['label' => 'Is Leader', 'rules' => 'permit_empty', 'errors' => []],
'cd_ac_no_for_child.*' => ['label' => 'CD Acc No', 'rules' => 'permit_empty', 'errors' => []],
'cd_current_balance.*' => ['label' => 'CD Amount', 'rules' => 'permit_empty', 'errors' => []],
'follower_policy_no.*' => ['label' => 'Follower Policy No', 'rules' => 'permit_empty|regex_match[/^[a-zA-Z0-9\/_-]+$/]', 'errors' => [
'regex_match' => 'The {field} can only contain letters, numbers, spaces, dashes, and underscores.'
]],
'co_share_per.*' => ['label' => 'Co-Share %', 'rules' => 'permit_empty|decimal', 'errors' => ['decimal' => 'Co-Share % must be a valid decimal.']],
'non_comm_per_amt.*' => ['label' => 'Non-Comm Premium', 'rules' => 'permit_empty|decimal', 'errors' => ['decimal' => 'Amount must be numeric.']],
'base_premium.*' => ['label' => 'Base Premium','rules' => 'permit_empty|decimal', 'errors' => ['decimal' => 'Base Premium must be numeric.']],
'tp_premium.*' => ['label' => 'TP Premium', 'rules' => 'permit_empty|decimal', 'errors' => ['decimal' => 'TP Premium must be numeric.']],
'ter_premium.*' => ['label' => 'TEP Premium', 'rules' => 'permit_empty|decimal', 'errors' => ['decimal' => 'TEP Premium must be numeric.']],
'co_premium.*' => ['label' => 'Co-Premium', 'rules' => 'permit_empty|decimal', 'errors' => ['decimal' => 'Co-Premium must be numeric.']],
'co_tp_premium.*' => ['label' => 'Co-TP Premium', 'rules' => 'permit_empty|decimal', 'errors' => ['decimal' => 'Co-TP Premium must be numeric.']],
'co_ter_premium.*' => ['label' => 'Co-TEP Premium', 'rules' => 'permit_empty|decimal', 'errors' => ['decimal' => 'Co-TEP Premium must be numeric.']],
'cgst.*' => ['label' => 'CGST', 'rules' => 'permit_empty|decimal', 'errors' => ['decimal' => 'CGST must be numeric.']],
'sgst.*' => ['label' => 'SGST', 'rules' => 'permit_empty|decimal', 'errors' => ['decimal' => 'SGST must be numeric.']],
'igst.*' => ['label' => 'IGST', 'rules' => 'permit_empty|decimal', 'errors' => ['decimal' => 'IGST must be numeric.']],
'gst_amount.*' => ['label' => 'GST Amount', 'rules' => 'permit_empty|decimal', 'errors' => ['decimal' => 'GST Amount must be numeric.']],
'stamp_duty.*' => ['label' => 'Stamp Duty', 'rules' => 'permit_empty|decimal', 'errors' => ['decimal' => 'Stamp Duty must be numeric.']],
'total.*' => ['label' => 'Total', 'rules' => 'permit_empty|decimal', 'errors' => ['decimal' => 'Total must be a numeric value.']],
'agreed_bp.*' => ['label' => 'Agreed BP %', 'rules' => 'permit_empty|decimal', 'errors' => ['decimal' => 'Agreed BP % must be numeric.']],
'agreed_tp.*' => ['label' => 'Agreed TP %', 'rules' => 'permit_empty|decimal', 'errors' => ['decimal' => 'Agreed TP % must be numeric.']],
'agreed_ter.*' => ['label' => 'Agreed TEP %', 'rules' => 'permit_empty|decimal', 'errors' => ['decimal' => 'Agreed TEP % must be numeric.']],
'agreed_amount.*' => ['label' => 'Agreed Amount', 'rules' => 'permit_empty|decimal', 'errors' => ['decimal' => 'Agreed Amount must be numeric.']],
'actual_bp_amt.*' => ['label' => 'Actual BP Amount', 'rules' => 'permit_empty|decimal', 'errors' => ['decimal' => 'Actual BP Amount must be numeric.']],
'actual_tp_amt.*' => ['label' => 'Actual TP Amount', 'rules' => 'permit_empty|decimal', 'errors' => ['decimal' => 'Actual TP Amount must be numeric.']],
'actual_tep_amt.*' => ['label' => 'Actual TEP Amount', 'rules' => 'permit_empty|decimal', 'errors' => ['decimal' => 'Actual TEP Amount must be numeric.']],
'actual_bp_per.*' => ['label' => 'Actual BP %', 'rules' => 'permit_empty|decimal', 'errors' => ['decimal' => 'Actual BP % must be numeric.']],
'actual_tp_per.*' => ['label' => 'Actual TP %', 'rules' => 'permit_empty|decimal', 'errors' => ['decimal' => 'Actual TP % must be numeric.']],
'actual_tep_per.*' => ['label' => 'Actual TEP %', 'rules' => 'permit_empty|decimal', 'errors' => ['decimal' => 'Actual TEP % must be numeric.']],
'actual_bp_brokerage_amt.*' => ['label' => 'BP Remuneration', 'rules' => 'permit_empty|decimal', 'errors' => ['decimal' => 'BP Remuneration must be numeric.']],
'actual_tp_brokerage_amt.*' => ['label' => 'TP Remuneration', 'rules' => 'permit_empty|decimal', 'errors' => ['decimal' => 'TP Remuneration must be numeric.']],
'actual_tep_brokerage_amt.*' => ['label' => 'TEP Remuneration', 'rules' => 'permit_empty|decimal', 'errors' => ['decimal' => 'TEP Remuneration must be numeric.']],
'exp_amt.*' => ['label' => 'Expected Amount', 'rules' => 'permit_empty|decimal', 'errors' => ['decimal' => 'The Expected Amount field must contain a valid number.']]
];
$isCoShare = !empty($post_data['co_share']);
$calcPolicyIssueDateRule = [
'label' => 'Policy Issue Date',
'rules' => 'required',
'errors' => ['required' => 'Policy Issue Date is required'],
];
if ($isCoShare) {
$coShareTypes = $post_data['co_share_type'] ?? [];
if (is_array($coShareTypes)) {
foreach ($coShareTypes as $index => $type) {
if ((int) $type === 1) {
$rules["calc_policy_issue_date.$index"] = $calcPolicyIssueDateRule;
}
}
}
} else {
$rules['calc_policy_issue_date.*'] = $calcPolicyIssueDateRule;
}
if(isset($post_data['client_type']) && $post_data['client_type'] == 1){
$rules['client_branch_id'] = ['label' => 'Client Branch', 'rules' => 'required', 'errors' => ['required' => 'Client branch is required']];
}
$isValid = $this->validate($rules);
// $Date_of_commencement = $this->request->getPost('policy_start_date');
// $Date_of_expiry = $this->request->getPost('policy_end_date');
// if ($Date_of_commencement && $Date_of_expiry && ($Date_of_expiry < $Date_of_commencement)) {
// $this->validator->setError('policy_end_date', '$Date of Commencement and Date of Expiry are mismatched (Date of Expiry cannot be before $Date of Commencement).');
// $isValid = false;
// }
$start_dates = $this->request->getPost('policy_start_date');
$end_dates = $this->request->getPost('policy_end_date');
if ($start_dates && $end_dates) {
// Standardize: If it's a single string (Type 2), wrap it in an array
$starts = is_array($start_dates) ? $start_dates : [$start_dates];
$ends = is_array($end_dates) ? $end_dates : [$end_dates];
foreach ($starts as $index => $s_date) {
$e_date = $ends[$index] ?? null;
if ($s_date && $e_date) {
$f_start = change_date_format($s_date, 'Y-m-d', 'Y-m-d'); // be carefully here we made so many times mistakes on here
$f_end = change_date_format($e_date, 'Y-m-d', 'Y-m-d');// be carefully here we made so many times mistakes on here
if ($f_start && $f_end && ($f_end < $f_start)) {
$isValid = false;
// Determine the error key name
// If it's an array, we use index (e.g., policy_end_date.0)
$errorKey = is_array($start_dates) ? "policy_end_date.$index" : "policy_end_date";
$this->validator->setError($errorKey, 'D.O.E(Date of Expiry) cannot be before D.O.C(Date of Commencement).');
}
}
}
}
if (!$isValid) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Input validation failed',
'code' => 400,
'errors' => $this->validator->getErrors()
]);
}
$post_data = $post_data ? sanitizeInputArrayAdvanced($post_data) : [];
$this->myLogger->logme('error', 'Policy Trancaction form data : ' . json_encode($post_data));
$id = $post_data['id'] ?? null;
$data = $this->preparePolicyData();
$data['cd_ac_pk'] = $post_data['cd_ac_no'];
$data['issuer'] = 2;
$data['status'] = 'completed';
$this->myLogger->logme('error', 'Policy Trancaction modified form data ( insert data ) : ' . json_encode($data));
if (!$id) {
return $this->insertInceptionPolicy($data);
} else {
return $this->updateInceptionPolicy($id, $data);
}
}
private function preparePolicyData()
{
$request_data = $this->request->getPost();
$data = sanitizeInputArrayAdvanced($request_data);
$file_data = $this->request->getFiles() ?? null;
$data['file_data'] = $file_data ?? null;
$vehicle_file_data = $this->request->getFiles() ?? null;
$data['vehicle_file_data'] = $vehicle_file_data ?? null;
// print_r($data); die;
if (empty($data['policy_issue_date'])) {
$data['policy_issue_date'] = null;
}
if (empty($data['policy_start_date'])) {
$data['policy_start_date'] = null;
}
if (empty($data['policy_end_date'])) {
$data['policy_end_date'] = null;
}
if (empty($data['renewal_date'])) {
$data['renewal_date'] = null;
}
if (empty($data['rollover_date'])) {
$data['rollover_date'] = null;
}
if (empty($data['last_action_date'])) {
$data['last_action_date'] = null;
} else {
$data['last_action_date'] = change_date_format($data['last_action_date']);
}
// Separate Insurer and TPA Branch IDs and IDs
if (isset($data['insurer_id']) && !empty($data['insurer_id'])) {
list($data['insurer_branch_id'], $data['insurer_id']) = explode('-', $data['insurer_id']);
if (isset($data['tpa']) && !empty($data['tpa'])) {
list($data['tpa_branch_id'], $data['tpa_id']) = explode('-', $data['tpa']);
}
}
$data['tsi'] = generate_tsi_code($data['issue_type']);
$data['action_type'] = 'inception';
if (!isset($data['co_share'])) {
$data['co_share'] = 0;
} elseif ($data['co_share']) {
$data['co_share'] = 1;
}
if ($data['co_share'] == 1 && !empty($data['follow_insurer_id']) && is_array($data['follow_insurer_id'])) {
foreach ($data['follow_insurer_id'] as $index => $followInsurer) {
if (($data['co_share_type'][$index] ?? 2) == 1 && !empty($followInsurer)) {
list($data['insurer_branch_id'], $data['insurer_id']) = explode('-', $followInsurer);
break;
}
}
}
// if (!isset($data['bro_payable_by'])) {
// $data['bro_payable_by'] = 0;
// } elseif ($data['bro_payable_by']) {
// $data['bro_payable_by'] = 1;
// }
if (!isset($data['same_as_proposer'])) {
$data['same_as_proposer'] = 0;
} elseif ($data['same_as_proposer']) {
$data['same_as_proposer'] = 1;
}
if (!isset($data['policy_with_corr'])) {
$data['policy_with_corr'] = 0;
} elseif ($data['policy_with_corr']) {
$data['policy_with_corr'] = 1;
}
$data['is_cd_reduce_from_bds'] = ($data['policy_type_id'] > 7 && $data['client_type'] == 1) ? 1 : 0;
if ($data['ct_type'] == "") {
$data['ct_type'] = 1;
}
// $month = '01-'.(string)$this->request->getPost('month');
// $data['month'] = empty($data['month']) ? null : date('Y-m-d', strtotime($month));
// Determine $is_addon value
$data['is_addon'] = in_array($data['policy_type_id'], [1, 2, 6, 7]) ? 1 : (in_array($data['policy_type_id'], [4, 5]) ? 2 : ($data['policy_type_id'] == 3 && isset($data['base_policy']) ? 3 : 1));
// print_r($data); die;
return $data;
}
private function insertInceptionPolicy($data)
{
// print_r($data); die;
$insert = $this->policyTransactionModel->insert($data);
if ($insert) {
$this->insertTransactionStatus($insert, $data, 1);
$emp_data = $this->processInsertIndividualMemberInEmpTable($data);
if (isset($data['follow_insurer_id']) && !empty($data['follow_insurer_id'][0])) {
$pt_co_share_details = $this->insertOrUpdateCoShareDetails($data, $insert);
$client_policy_id = null;
if ($data['ct_type'] == 2) {
$client_policy_insert_data = $this->prepareClientPolicyInsertData($data);
$client_policy_id = $this->clientPolicyModel->insert($client_policy_insert_data);
$this->policyTransactionModel->update($insert, ['client_policy_id' => $client_policy_id]);
$emp_policy_insert = $this->InsertIndividualEmpPolicyTable($emp_data, $client_policy_id);
}
if ($data['client_type'] == 1 && $data['status'] == 'completed' && $data['is_cd_reduce_from_bds'] == 1) {
$this->processCompletedStatus($data, $client_policy_id, $data['insurer_id'], $insert);
}
}
// policy file upload
if(isset($data['doc_name']) && isset($data['file_data']) && !empty($data['doc_name']) && !empty($data['file_data'])){
$this->uploadFile($data['doc_name'], $data['file_data'], $insert);
}
// policy file upload
if(
isset($data['other_docs_name']) && isset($data['vehicle_file_data']) && isset($data['client_id']) && isset($data['vehicle_id']) &&
!empty($data['other_docs_name']) && !empty($data['vehicle_file_data']) && !empty($data['client_id']) && !empty($data['vehicle_id'])
)
{
$vdd = [
'other_docs_name' => $data['other_docs_name'],
'file_data' => $data['vehicle_file_data'],
'client_id' => $data['client_id'],
'vehicle_id' => $data['vehicle_id'],
];
$clientController = new ClientController();
$clientController->uploadVehicleFile($vdd);
}
$client_data = $this->clientModel->where('id', $data['client_id'])->first();
$data['client_kyc'] = $this->clientKYCDocsModel->where('client_id', $data['client_id'])->findAll();
$clientController = new ClientController();
$data['client_kyc_primary_table'] = $clientController->generateKycPrimaryTable($data['client_id']);
$data['client_kyc_other_table'] = $clientController->generateKycOthersTable($data['client_id']);
// $data['client_kyc_single_table'] = $clientController->generateKycSingleTable($data['client_id']);
$data['entity_type_id'] = $client_data['entity_type_id'];
return $this->respondSuccess($insert, "Policy transaction created successfully", $data);
}
return $this->respondError("Failed to create policy transaction");
}
private function updateInceptionPolicy($id, $data)
{
// print_r($data); die;
$data['updated_by'] = get_session_userid();
$old_pt_data = $this->policyTransactionModel->where('is_active', 1)->where("id", $id)->first();
$old_pt_co_share_data = $this->PTCOShareDetailsModel->where('is_active', 1)->where("id", $id)->first();
if ($this->policyTransactionModel->update($id, $data)) {
if (!empty($old_pt_data) && isset($data['policy_no'])) {
$this->updateRelatedPolicyTransactionPolicyNo(
(int) $id,
(string) ($old_pt_data['policy_no'] ?? ''),
(string) $data['policy_no']
);
}
$this->insertTransactionStatus($id, $data, 1);
$emp_data = $this->processInsertIndividualMemberInEmpTable($data);
if (isset($data['follow_insurer_id']) && !empty($data['follow_insurer_id'][0])) {
$this->insertOrUpdateCoShareDetails($data, $id);
if ($data['ct_type'] == 1) {
$this->policyTransactionModel->update($id, ['client_policy_id' => $data['client_policy_id']]);
}
if (empty($data['client_policy_id']) || $data['client_policy_id'] == 0) {
if ($data['ct_type'] == 2) {
$client_policy_insert_data = $this->prepareClientPolicyInsertData($data);
$client_policy_id = $this->clientPolicyModel->insert($client_policy_insert_data);
$this->policyTransactionModel->update($id, ['client_policy_id' => $client_policy_id]);
$this->InsertIndividualEmpPolicyTable($emp_data, $client_policy_id);
}
} else {
if (isset($data['emp_policy_id']) && !empty($data['emp_policy_id'][0])) {
$this->InsertIndividualEmpPolicyTable($emp_data, $data['client_policy_id']);
}
}
// if($old_pt_data['status'] != "completed"){
// if ($data['status'] == 'completed' && $data['ct_type'] == 2) {
// if ($data['client_type'] == 1 && $data['is_cd_reduce_from_bds'] == 1) {
// $this->processCompletedStatus($data, $data['client_policy_id'], $data['insurer_id'], $id);
// }
// }
// }
$data['pt_co_share_details'] = $this->PTCOShareDetailsModel->where('pt_id', $id)->where('is_active', 1)->findAll();
}
if(isset($data['cd_amt_changed']) && !empty($data['cd_amt_changed'])){
$policy_data = $this->policyTransactionModel->where('is_active', 1)->where('id', $id)->first();
$this->cdCorrection($policy_data, $data['cd_amt_changed'], $id);
}
$client_data = $this->clientModel->where('id', $data['client_id'])->first();
$data['client_kyc'] = $this->clientKYCDocsModel->where('client_id', $data['client_id'])->findAll();
$clientController = new ClientController();
$data['client_kyc_primary_table'] = $clientController->generateKycPrimaryTable($data['client_id']);
$data['client_kyc_other_table'] = $clientController->generateKycOthersTable($data['client_id']);
// $data['client_kyc_single_table'] = $clientController->generateKycSingleTable($data['client_id']);
$data['entity_type_id'] = $client_data['entity_type_id'];
return $this->respondSuccess($id, "Policy transaction updated successfully", $data);
}
return $this->respondError("Failed to update policy transaction");
}
/**
* Sync policy_no on related policy_transaction rows when inception policy number changes.
*/
private function updateRelatedPolicyTransactionPolicyNo(
int $inceptionPtId,
string $oldPolicyNo,
string $newPolicyNo
): array {
$oldPolicyNo = trim($oldPolicyNo);
$newPolicyNo = trim($newPolicyNo);
if ($oldPolicyNo === '' || $newPolicyNo === '' || $oldPolicyNo === $newPolicyNo) {
return ['status' => false, 'message' => 'No policy number change detected', 'updated_ids' => []];
}
$relatedRecords = $this->policyTransactionModel
->where('is_active', 1)
->where('id !=', $inceptionPtId)
->where('policy_no', $oldPolicyNo)
->findAll();
if (empty($relatedRecords)) {
return ['status' => true, 'message' => 'No related policy transactions found', 'updated_ids' => []];
}
$updatedIds = [];
$updatedBy = get_session_userid();
foreach ($relatedRecords as $record) {
$this->policyTransactionModel
->where('id', $record['id'])
->set(['policy_no' => $newPolicyNo, 'updated_by' => $updatedBy])
->update();
if ($this->policyTransactionModel->affectedRows() > 0) {
$updatedIds[] = $record['id'];
}
}
$this->myLogger->logme('error', 'Updated policy_no on related policy_transaction records: ' . json_encode([
'inception_pt_id' => $inceptionPtId,
'old_policy_no' => $oldPolicyNo,
'new_policy_no' => $newPolicyNo,
'updated_ids' => $updatedIds,
]));
return [
'status' => true,
'message' => 'Related policy transaction policy numbers updated',
'updated_ids' => $updatedIds,
];
}
private function insertOrUpdateCoShareDetails($data, $pt_id)
{
// Prepare data for insertion and updating
$coShareDetails = [];
if (isset($data['co_share_id']) && !empty($data['co_share_id'])) {
$this->removePtCoShareRecords($data['co_share_id'], $pt_id);
}
if (isset($data['follow_insurer_id'])) {
foreach ($data['follow_insurer_id'] as $index => $insurer) {
// Separate the insurer and insurer branch
if (isset($insurer) && !empty($insurer)) {
list($insurer_branch_id, $insurer_id) = explode('-', $insurer);
} else {
$insurer_branch_id = null;
$insurer_id = null;
}
if ($data['bro_payable_by'] == 1) {
$cop_amt = isset($data['co_premium'][$index]) && ($data['co_premium'][$index] != "0.00" && !empty($data['co_premium'][$index])) ? $data['co_premium'][$index] : ($data['base_premium'][$index] ?? 0);
// print_r($cop_amt);die();
} else {
$cop_amt = $data['co_premium'][$index] ?? 0;
}
if(isset($data['calc_policy_issue_date'][$index])){
$data['calc_policy_issue_date'][$index] = change_date_format($data['calc_policy_issue_date'][$index]);
}
$co_share_type_value = (($data['co_share'] ?? 0) == 1) ? ($data['co_share_type'][$index] ?? 1) : 1;
// Prepare each co-share detail entry
$coShareDetails[] = [
'pt_id' => $pt_id,
'insurer_id' => $insurer_id ?? 0,
'insurer_branch_id' => $insurer_branch_id ?? 0,
'co_share_type' => $co_share_type_value,
'co_share_per' => $data['co_share_per'][$index] ?? 0,
'bp_amt' => $data['base_premium'][$index] ?? 0,
'bp_gst_amt' => $data['gst_amount'][$index] ?? 0,
'bp_igst' => $data['igst'][$index] ?? 0,
'bp_sgst' => $data['sgst'][$index] ?? 0,
'bp_cgst' => $data['cgst'][$index] ?? 0,
'tp_amt' => $data['tp_premium'][$index] ?? 0,
'tep_amt' => $data['ter_premium'][$index] ?? 0,
'cotp_amt' => $data['co_tp_premium'][$index] ?? 0,
'cotep_amt' => $data['co_ter_premium'][$index] ?? 0,
'agreed_amt' => $data['agreed_amount'][$index] ?? 0,
'agreed_bp_per' => $data['agreed_bp'][$index] ?? 0,
'agreed_tp_per' => $data['agreed_tp'][$index] ?? 0,
'agreed_tep_per' => $data['agreed_ter'][$index] ?? 0,
'standerd_bp_per' => $data['standard_bp'][$index] ?? 0,
'standerd_tp_per' => $data['standard_tp'][$index] ?? 0,
'standerd_tep_per' => $data['standard_ter'][$index] ?? 0,
'actual_bp_amt' => $data['actual_bp_amt'][$index] ?? 0,
'actual_tp_amt' => $data['actual_tp_amt'][$index] ?? 0,
'actual_tep_amt' => $data['actual_tep_amt'][$index] ?? 0,
'actual_bp_per' => $data['actual_bp_per'][$index] ?? 0,
'actual_tp_per' => $data['actual_tp_per'][$index] ?? 0,
'actual_tep_per' => $data['actual_tep_per'][$index] ?? 0,
'actual_bp_brokerage_amt' => $data['actual_bp_brokerage_amt'][$index] ?? 0,
'actual_tp_brokerage_amt' => $data['actual_tp_brokerage_amt'][$index] ?? 0,
'actual_tep_brokerage_amt' => $data['actual_tep_brokerage_amt'][$index] ?? 0,
'exp_amt' => isset($data['exp_amt'][$index]) && !empty($data['exp_amt'][$index]) ? $data['exp_amt'][$index] : expected_amount_calc($data, $index),
'amount' => $data['total'][$index] ?? 0,
'stamp_duty' => $data['stamp_duty'][$index] ?? 0,
'cop_amt' => $cop_amt,
'variance' => $data['variance'][$index] ?? 0,
'reward' => $data['reward'][$index] ?? null,
'created_by' => get_session_userid() ?? null,
'updated_by' => get_session_userid() ?? null,
'id' => $data['co_share_id'][$index] ?? null, // Assuming this is the ID to identify existing records
'follower_policy_no' => $data['follower_policy_no'][$index] ?? null,
'non_comm_per_amt' => $data['non_comm_per_amt'][$index] ?? null,
'pt_policy_issue_date' => $data['calc_policy_issue_date'][$index] ?? null,
];
}
// print_r($pt_id);
// print_r($coShareDetails);
// die;
// Separate data into insert and update batches
$insertData = array_filter($coShareDetails, function ($detail) {
return empty($detail['id']); // Only insert new records
});
$updateData = array_filter($coShareDetails, function ($detail) {
return !empty($detail['id']); // Only update existing records
});
// Insert new records
if (!empty($insertData)) {
$this->PTCOShareDetailsModel->insertBatch($insertData);
}
// Update existing records
if (!empty($updateData)) {
$this->PTCOShareDetailsModel->updateBatch($updateData, 'id'); // Assuming 'id' is the unique identifier
}
// print_r($this->PTCOShareDetailsModel->getLastQuery()); die;
// print_r($coShareDetails);
// die;
return true;
}
// print_r($data);
// die;
}
private function prepareClientPolicyInsertData($data)
{
return [
'client_id' => $data['client_id'] ?? null,
'insurer_id' => $data['insurer_id'] ?? null,
'insurer_branch_id' => $data['insurer_branch_id'] ?? null,
'tpa_id' => $data['tpa_id'] ?? null,
'tpa_branch_id' => $data['tpa_branch_id'] ?? null,
'policy_type_id' => $data['policy_type_id'] ?? null,
'policy_start_date' => $data['policy_start_date'] ?? null,
'policy_end_date' => $data['policy_end_date'] ?? null,
'policy_status' => 1,
'is_addon' => $data['is_addon'] ?? null,
'base_policy' => $data['base_policy'] ?? 0,
'created_by' => get_session_userid(),
'policy_no' => $data['policy_no'] ?? null,
'client_branch_id' => $data['client_branch_id'] ?? 0,
'cd_ac_pk' => $data['cd_ac_no'] ?? null,
'gst' => 18,
'policy_entry_from' => 2,
];
}
private function insertTransactionStatus($policyTranId, $data, $statusType)
{
$statusData = [
'policy_tran_id' => $policyTranId,
'status' => $data['status'],
'last_action_date' => $data['last_action_date'],
'status_type' => $statusType,
'created_by' => get_session_userid(),
];
$this->policyTransactionStatusModel->insert($statusData);
}
private function processCompletedStatus($data, $client_policy_id, $insurer_id, $policyTranId)
{
$totalAmount = (int)$data['total'][0] ?? 0;
$description = 'The following amount of Rs. ' . $totalAmount . '/- has been debited for the ' . $data['emp_count'] . ' employees at Inception (BDS).';
$cdTransactionData = [
'amount' => $totalAmount,
'sub_type_id' => 4,
'client_id' => $data['client_id'],
'client_policy_id' => $client_policy_id ?? 0,
'endorsement_no' => null,
'cd_ac_no' => $data['cd_ac_no'] ?? null,
'insurer_id' => $insurer_id,
'description' => $description,
'transaction_type' => 'Debit',
'updated_by' => get_session_userid(),
'event_name' => 'inception',
'is_active' => 1,
'cd_ac_pk' => $data['cd_ac_pk'],
'pt_id' => $policyTranId ?? null,
];
$result = DepositHelper::saveDeposit($cdTransactionData, get_session_userid());
if(isset($result) && $result['success'] == true){
$update_data['ct_tran_id'] = $result['insert_id'];
$this->policyTransactionModel->where('id', $policyTranId)->set($update_data)->update();
}
}
private function cdCorrection($data, $amt, $policyTranId)
{
$totalAmount = (int)($amt ?? 0);
$description = 'The following amount of Rs. ' . $totalAmount . '/- has been debited towards the difference arising from the change in the BDS base premium.';
$cdTransactionData = [
'amount' => abs($totalAmount),
'sub_type_id' => 4,
'client_id' => $data['client_id'],
'client_policy_id' => $data['client_policy_id'] ?? 0,
'endorsement_no' => null,
'cd_ac_no' => $data['cd_ac_no'] ?? null,
'insurer_id' => $data['insurer_id'],
'description' => $description,
'transaction_type' => $totalAmount < 0 ? 'Credit' : 'Debit',
'updated_by' => get_session_userid(),
'event_name' => 'inception',
'is_active' => 1,
'cd_ac_pk' => $data['cd_ac_pk'],
'pt_id' => $policyTranId ?? null,
];
DepositHelper::saveDeposit($cdTransactionData, get_session_userid());
}
private function processInsertIndividualMemberInEmpTable($data)
{
// print_r($data);
if (isset($data['family_name']) && !empty($data['family_name'])) {
$emp_data = [];
$emp_ids = [];
$random_code = generateRandomCode(); // Generate random code once
foreach ($data['family_name'] as $index => $val) {
// Determine the gender based on the relationship
$relationship = $data['relationship'][$index] ?? '';
$gender = 'M'; // Default to Male
// Set gender based on relationship
if (in_array($relationship, ['Mother', 'Daughter', 'Mother in law', 'Spouse'])) {
$gender = 'F';
}
$emp_data[] = [
'client_id' => $data['client_id'] ?? 0,
'client_branch_id' => $data['client_branch_id'] ?? 0,
'name' => $val,
'relationship' => $relationship,
'gender' => $gender,
'emp_status' => 'active',
'created_by' => get_session_userid(),
'emp_code' => $random_code, // Use the same random code for all
'id' => $data['emp_id'][$index] ?? null
];
$emp_ids[] = $data['emp_id'][$index] ?? 0;
}
// print_r($emp_data); die;
// Separate data into insert and update batches
$insertData = array_filter($emp_data, function ($detail) {
return empty($detail['id']); // Only insert new records
});
$updateData = array_filter($emp_data, function ($detail) {
return !empty($detail['id']); // Only update existing records
});
// Insert new records
if (!empty($insertData)) {
$this->employeeModel->insertBatch($insertData);
}
// Update existing records
if (!empty($updateData)) {
$this->employeeModel->updateBatch($updateData, 'id'); // Assuming 'id' is the unique identifier
}
return $emp_ids;
}
}
private function InsertIndividualEmpPolicyTable($emp_ids, $client_policy_id)
{
if (!empty($emp_ids)) {
$emp_policy_data = [];
foreach ($emp_ids as $index => $emp_id) {
$emp_policy_data[] = [
'employee_id' => $emp_id ?? 0,
'client_policy_id' => $client_policy_id ?? 0,
'created_by' => get_session_userid(),
'status' => 'active',
];
}
// print_r($emp_policy_data); die;
// Insert new records
if (!empty($emp_policy_data)) {
$this->employeePolicyModel->insertBatch($emp_policy_data);
}
return true;
}
}
private function respondSuccess($id, $message, $data)
{
return $this->respond(['status' => true, 'pt_id' => $id, 'message' => $message, 'data' => $data], 200);
}
private function respondError($message)
{
return $this->respond(['status' => false, 'message' => $message], 200);
}
// policy Transaction Create function End
// Get the Single Inception Tranction data for edit
public function getInceptionDataForEdit($id)
{
$data = $this->policyTransactionModel
->select('
policy_transaction.*,
clients.short_name as client_short_name,
clients.client_type,
clients.entity_type_id,
policy_type.policy_type,
client_policy.tpa_id as master_tpa_id,
client_policy.tpa_branch_id as master_tpa_branch_id,
client_policy.policy_type_id as master_policy_type_id,
client_policy.is_addon,
client_policy.base_policy,
(
select last_action_date
from policy_transaction_status
where policy_tran_id = policy_transaction.id
and status = policy_transaction.status
order by id desc
limit 1
) as last_action_date
')
->join('clients', 'clients.id = policy_transaction.client_id')
->join('client_policy', 'policy_transaction.client_policy_id = client_policy.id', 'left')
->join('policy_type', 'client_policy.policy_type_id = policy_type.id', 'left')
->where('policy_transaction.id', $id)
->where('policy_transaction.is_active', 1)
->first();
$data['created_at'] = (isset($data['created_at']) && $data['created_at'] !== null && $data['created_at'] !== '')
? date('d/m/Y h:i:s A', strtotime($data['created_at']))
: null;
$data['updated_at'] = (isset($data['updated_at']) && $data['updated_at'] !== null && $data['updated_at'] !== '')
? date('d/m/Y h:i:s A', strtotime($data['updated_at']))
: null;
if (!empty($data['policy_issue_date'])) {
$data['policy_issue_date'] = change_date_format($data['policy_issue_date'], 'Y-m-d', 'd/m/Y');
}
if (!empty($data['policy_start_date'])) {
$data['policy_start_date'] = change_date_format($data['policy_start_date'], 'Y-m-d', 'd/m/Y');
}
if (!empty($data['policy_end_date'])) {
$data['policy_end_date'] = change_date_format($data['policy_end_date'], 'Y-m-d', 'd/m/Y');
}
if (!empty($data['renewal_date'])) {
$data['renewal_date'] = change_date_format($data['renewal_date'], 'Y-m-d', 'd/m/Y');
}
if (!empty($data['rollover_date'])) {
$data['rollover_date'] = change_date_format($data['rollover_date'], 'Y-m-d', 'd/m/Y');
}
if (!empty($data['endorse_eff_date'])) {
$data['endorse_eff_date'] = change_date_format($data['endorse_eff_date'], 'Y-m-d', 'd/m/Y');
}
if (!empty($data['last_action_date'])) {
$data['last_action_date'] = change_date_format($data['last_action_date'], 'Y-m-d', 'd/m/Y');
}
if (!empty($data['month'])) {
$data['month'] = change_date_format($data['month'], 'Y-m-d', 'M/Y');
} else {
$data['month'] = null;
}
// print_r($data); die;
$data['renewal_policy'] = $this->clientPolicyModel
->select('client_policy.*, policy_type.policy_type')
->join('policy_type', 'policy_type.id = client_policy.policy_type_id')
->where('client_policy.client_id', $data['client_id'])
->where('client_policy.client_branch_id', $data['client_branch_id'])
->where('client_policy.is_active', 1)
->findAll();
$data['base_policy_data'] = $this->clientPolicyModel
->select('client_policy.*, policy_type.policy_type')
->join('policy_type', 'policy_type.id = client_policy.policy_type_id')
->where('client_policy.client_id', $data['client_id'])
->where('client_policy.client_branch_id', $data['client_branch_id'])
->whereIn('client_policy.policy_type_id', [2, 3])
->where('client_policy.is_active', 1)
->findAll();
$pt_bp_amt = $this->PTCOShareDetailsModel
->select('bp_amt, amount')
->where('pt_id', $id)
->where('co_share_type', 1)
->where('is_active', 1)
->first();
// dd(db_connect()->getLastQuery() ,$pt_bp_amt);
$data['base_cd_amount'] = $pt_bp_amt['amount'] ?? null;
$ptFileQuery = $this->PTFileModel
->select('pt_files.*')
->join('policy_transaction', 'pt_files.pt_id = policy_transaction.id')
->where('pt_files.pt_id', $id)
->where('pt_files.is_active', 1);
if (!in_array(get_role_id(), [1, 5]) && empty(array_intersect(user_team(), [MANAGEMENT_TEAM_ID, FINANCE_TEAM_ID, BUSINESS_TEAM_ID]))) {
if (get_role_id() == 4 && in_array(POS_TEAM_ID, user_team())) {
$ptFileQuery->where('pt_files.created_by', get_session_userid());
}
}
$data['pt_files'] = $ptFileQuery->findAll();
$data['pt_co_share_details'] = $this->PTCOShareDetailsModel
->select("
pt_co_share_details.*,
(
SELECT
COUNT(*)
FROM
co_share_stmt_details
WHERE
co_share_stmt_details.co_share_id = pt_co_share_details.id
AND co_share_stmt_details.is_active = 1
) AS record_count,
(
SELECT
SUM(actual_bp_amt)
FROM
co_share_stmt_details
WHERE
co_share_id = pt_co_share_details.id
AND is_active = 1
) AS actual_bp_amount,
(
SELECT
SUM(actual_tp_amt)
FROM
co_share_stmt_details
WHERE
co_share_id = pt_co_share_details.id
AND is_active = 1
) AS actual_tp_amount,
(
SELECT
SUM(actual_tep_amt)
FROM
co_share_stmt_details
WHERE
co_share_id = pt_co_share_details.id
AND is_active = 1
) AS actual_tep_amount,
(
SELECT
SUM(actual_bp_per)
FROM
co_share_stmt_details
WHERE
co_share_id = pt_co_share_details.id
AND is_active = 1
) AS actual_bp_percentage,
(
SELECT
SUM(actual_tp_per)
FROM
co_share_stmt_details
WHERE
co_share_id = pt_co_share_details.id
AND is_active = 1
) AS actual_tp_percentage,
(
SELECT
SUM(actual_tep_per)
FROM
co_share_stmt_details
WHERE
co_share_id = pt_co_share_details.id
AND is_active = 1
) AS actual_tep_percentage,
(
SELECT
SUM(actual_bp_brokerage_amt)
FROM
co_share_stmt_details
WHERE
co_share_id = pt_co_share_details.id
AND is_active = 1
) AS actual_bp_brokerage_amount,
(
SELECT
SUM(actual_tp_brokerage_amt)
FROM
co_share_stmt_details
WHERE
co_share_id = pt_co_share_details.id
AND is_active = 1
) AS actual_tp_brokerage_amount,
(
SELECT
SUM(actual_tep_brokerage_amt)
FROM
co_share_stmt_details
WHERE
co_share_id = pt_co_share_details.id
AND is_active = 1
) AS actual_tep_brokerage_amount,
DATE_FORMAT(pt_policy_issue_date, '%d/%m/%Y') AS pt_policy_issue_date
")
->where('pt_id', $id)
->where('is_active', 1)
->orderBy('id', 'asc')
->findAll();
$data['emp_data'] = $this->employeeModel
->select('employees.*, employee_polices.id as emp_policy_id')
->join('employee_polices', 'employees.id = employee_polices.employee_id', 'left')
->where('employees.client_id', $data['client_id'])
->where('employees.is_active', 1)->findAll();
// $data['client_kyc'] = $this->clientKYCDocsModel->where('client_id', $data['client_id'])->findAll();
$clientController = new ClientController();
$data['client_kyc_primary_table'] = $clientController->generateKycPrimaryTable($data['client_id']);
$data['client_kyc_other_table'] = $clientController->generateKycOthersTable($data['client_id']);
$data['client_kyc_single_table'] = $clientController->generateKycSingleTable($data['client_id']);
$data['client_kyc_dd_data'] = $clientController->fetch_dropdown($data['client_id']);
$data['vehicle_docs'] = $this->clientKYCDocsModel
->where('client_id', $data['client_id'])
->where('vehicle_id', $data['vehicle_id'])
->findAll();
// print_r( $data['pt_co_share_details']); die;
// return $data;
if ($data) {
return $this->respond(['status' => true, 'data' => $data], 200);
} else {
return $this->respond(['status' => false], 200);
}
}
// Get the Single Inception Tranction data for edit
public function getInceptionDataForEdit2($id)
{
$data = $this->policyTransactionModel
->select('
policy_transaction.*,
clients.short_name as client_short_name,
clients.client_type,
clients.entity_type_id,
policy_type.policy_type,
client_policy.tpa_id as master_tpa_id,
client_policy.tpa_branch_id as master_tpa_branch_id,
client_policy.policy_type_id as master_policy_type_id,
client_policy.is_addon,
client_policy.base_policy,
(
select last_action_date
from policy_transaction_status
where policy_tran_id = policy_transaction.id
and status = policy_transaction.status
order by id desc
limit 1
) as last_action_date
')
->join('clients', 'clients.id = policy_transaction.client_id')
->join('client_policy', 'policy_transaction.client_policy_id = client_policy.id', 'left')
->join('policy_type', 'client_policy.policy_type_id = policy_type.id', 'left')
->where('policy_transaction.id', $id)
->where('policy_transaction.is_active', 1)
->first();
$data['created_at'] = (isset($data['created_at']) && $data['created_at'] !== null && $data['created_at'] !== '')
? date('d/m/Y h:i:s A', strtotime($data['created_at']))
: null;
$data['updated_at'] = (isset($data['updated_at']) && $data['updated_at'] !== null && $data['updated_at'] !== '')
? date('d/m/Y h:i:s A', strtotime($data['updated_at']))
: null;
if (!empty($data['policy_issue_date'])) {
$data['policy_issue_date'] = change_date_format($data['policy_issue_date'], 'Y-m-d', 'd/m/Y');
}
if (!empty($data['policy_start_date'])) {
$data['policy_start_date'] = change_date_format($data['policy_start_date'], 'Y-m-d', 'd/m/Y');
}
if (!empty($data['policy_end_date'])) {
$data['policy_end_date'] = change_date_format($data['policy_end_date'], 'Y-m-d', 'd/m/Y');
}
if (!empty($data['renewal_date'])) {
$data['renewal_date'] = change_date_format($data['renewal_date'], 'Y-m-d', 'd/m/Y');
}
if (!empty($data['rollover_date'])) {
$data['rollover_date'] = change_date_format($data['rollover_date'], 'Y-m-d', 'd/m/Y');
}
if (!empty($data['endorse_eff_date'])) {
$data['endorse_eff_date'] = change_date_format($data['endorse_eff_date'], 'Y-m-d', 'd/m/Y');
}
if (!empty($data['last_action_date'])) {
$data['last_action_date'] = change_date_format($data['last_action_date'], 'Y-m-d', 'd/m/Y');
}
if (!empty($data['month'])) {
$data['month'] = change_date_format($data['month'], 'Y-m-d', 'M/Y');
} else {
$data['month'] = null;
}
// print_r($data); die;
$data['renewal_policy'] = $this->clientPolicyModel
->select('client_policy.*, policy_type.policy_type')
->join('policy_type', 'policy_type.id = client_policy.policy_type_id')
->where('client_policy.client_id', $data['client_id'])
->where('client_policy.client_branch_id', $data['client_branch_id'])
->where('client_policy.is_active', 1)
->findAll();
$data['base_policy_data'] = $this->clientPolicyModel
->select('client_policy.*, policy_type.policy_type')
->join('policy_type', 'policy_type.id = client_policy.policy_type_id')
->where('client_policy.client_id', $data['client_id'])
->where('client_policy.client_branch_id', $data['client_branch_id'])
->whereIn('client_policy.policy_type_id', [2, 3])
->where('client_policy.is_active', 1)
->findAll();
$pt_bp_amt = $this->PTCOShareDetailsModel
->select('bp_amt, amount')
->where('pt_id', $id)
->where('co_share_type', 1)
->where('is_active', 1)
->first();
// dd(db_connect()->getLastQuery() ,$pt_bp_amt);
$data['base_cd_amount'] = $pt_bp_amt['amount'] ?? null;
$ptFileQuery = $this->PTFileModel
->select('pt_files.*')
->join('policy_transaction', 'pt_files.pt_id = policy_transaction.id')
->where('pt_files.pt_id', $id)
->where('pt_files.is_active', 1);
if (!in_array(get_role_id(), [1, 5]) && empty(array_intersect(user_team(), [MANAGEMENT_TEAM_ID, FINANCE_TEAM_ID, BUSINESS_TEAM_ID]))) {
if (get_role_id() == 4 && in_array(POS_TEAM_ID, user_team())) {
$ptFileQuery->where('pt_files.created_by', get_session_userid());
}
}
$data['pt_files'] = $ptFileQuery->findAll();
$data['pt_co_share_details'] = $this->PTCOShareDetailsModel
->select("
pt_co_share_details.*,
(
SELECT
COUNT(*)
FROM
co_share_stmt_details
WHERE
co_share_stmt_details.co_share_id = pt_co_share_details.id
AND co_share_stmt_details.is_active = 1
) AS record_count,
(
SELECT
SUM(actual_bp_amt)
FROM
co_share_stmt_details
WHERE
co_share_id = pt_co_share_details.id
AND is_active = 1
) AS actual_bp_amount,
(
SELECT
SUM(actual_tp_amt)
FROM
co_share_stmt_details
WHERE
co_share_id = pt_co_share_details.id
AND is_active = 1
) AS actual_tp_amount,
(
SELECT
SUM(actual_tep_amt)
FROM
co_share_stmt_details
WHERE
co_share_id = pt_co_share_details.id
AND is_active = 1
) AS actual_tep_amount,
(
SELECT
SUM(actual_bp_per)
FROM
co_share_stmt_details
WHERE
co_share_id = pt_co_share_details.id
AND is_active = 1
) AS actual_bp_percentage,
(
SELECT
SUM(actual_tp_per)
FROM
co_share_stmt_details
WHERE
co_share_id = pt_co_share_details.id
AND is_active = 1
) AS actual_tp_percentage,
(
SELECT
SUM(actual_tep_per)
FROM
co_share_stmt_details
WHERE
co_share_id = pt_co_share_details.id
AND is_active = 1
) AS actual_tep_percentage,
(
SELECT
SUM(actual_bp_brokerage_amt)
FROM
co_share_stmt_details
WHERE
co_share_id = pt_co_share_details.id
AND is_active = 1
) AS actual_bp_brokerage_amount,
(
SELECT
SUM(actual_tp_brokerage_amt)
FROM
co_share_stmt_details
WHERE
co_share_id = pt_co_share_details.id
AND is_active = 1
) AS actual_tp_brokerage_amount,
(
SELECT
SUM(actual_tep_brokerage_amt)
FROM
co_share_stmt_details
WHERE
co_share_id = pt_co_share_details.id
AND is_active = 1
) AS actual_tep_brokerage_amount,
DATE_FORMAT(pt_policy_issue_date, '%d/%m/%Y') AS pt_policy_issue_date
")
->where('pt_id', $id)
->where('is_active', 1)
->orderBy('id', 'asc')
->findAll();
$data['emp_data'] = $this->employeeModel
->select('employees.*, employee_polices.id as emp_policy_id')
->join('employee_polices', 'employees.id = employee_polices.employee_id', 'left')
->where('employees.client_id', $data['client_id'])
->where('employees.is_active', 1)->findAll();
// $data['client_kyc'] = $this->clientKYCDocsModel->where('client_id', $data['client_id'])->findAll();
$clientController = new ClientController();
$data['client_kyc_primary_table'] = $clientController->generateKycPrimaryTable($data['client_id']);
$data['client_kyc_other_table'] = $clientController->generateKycOthersTable($data['client_id']);
$data['client_kyc_single_table'] = $clientController->generateKycSingleTable($data['client_id']);
$data['client_kyc_dd_data'] = $clientController->fetch_dropdown($data['client_id']);
$data['vehicle_docs'] = $this->clientKYCDocsModel
->where('client_id', $data['client_id'])
->where('vehicle_id', $data['vehicle_id'])
->findAll();
// print_r( $data['pt_co_share_details']); die;
// return $data;
if ($data) {
return $this->respond(['status' => true, 'data' => $data], 200);
} else {
return $this->respond(['status' => false], 200);
}
}
public function removePolicyTransaction($id, $type = 0)
{
if ($id) {
$data['is_active'] = 0;
$data['updated_by'] = get_session_userid();
$policy_transaction_data = $this->policyTransactionModel->where('id', $id)->first();
if($policy_transaction_data['policy_type_id'] > 7 && $type == 0){
$this->policyTransactionModel->where('id', $id)->set($data)->update();
$this->PTCOShareDetailsModel->where('pt_id', $id)->set($data)->update();
$this->clientPolicyModel->where('id', $policy_transaction_data['client_policy_id'])->set($data)->update();
$this->policyTransactionModel->where('client_policy_id', $policy_transaction_data['client_policy_id'])->set($data)->update();
$cd_transaction_model = new ClientDepositModel();
$cd_transaction_model->where('policy_transaction_id', $id)->set($data)->update();
}else{
$this->policyTransactionModel->where('id', $id)->set($data)->update();
$this->PTCOShareDetailsModel->where('pt_id', $id)->set($data)->update();
$cd_transaction_model = new ClientDepositModel();
$cd_transaction_model->where('policy_transaction_id', $id)->set($data)->update();
}
return $this->respond(['status' => true, 'code' => 200, 'message' => 'Policy Transaction removed successfully'], 200);
} else {
return $this->respond(['status' => false, 'code' => 404, 'message' => 'Failed to remove policy transaction'], 200);
}
}
//function for soft delete for pt_co_share_details records
public function removePtCoShareRecords($primaryKeys, $pt_id)
{
if (empty($primaryKeys)) {
return false;
}
// Convert array to a comma-separated string of placeholders for query binding
$placeholders = implode(',', array_fill(0, count($primaryKeys), '?'));
// Prepare the query with proper binding
$sql = "UPDATE pt_co_share_details SET is_active = 0 WHERE pt_id = ? AND id NOT IN ($placeholders)";
// Merge pt_id with primary keys for binding
$params = array_merge([$pt_id], $primaryKeys);
// Execute the query with bound parameters
return db_connect()->query($sql, $params);
}
//------------------------------------------------------------------------------------------------
// Policy Transaction Endorsement
public function viewEndorsement()
{
// echo '<pre>';
// !dd($this->getEndorsementDataForEdit(17));
$bds_edit_pt_id = $this->request->getGet('pt_id') ?? null;
$data['tab_name'] = 'Endorsement';
$data['page_name'] = 'Endorsement';
$data['issuer'] = [1 => 'JIBS', 2 => 'Nhance'];
$data['issuer_branch'] = $this->nhanceBranchModel->where('is_active', 1)->findAll();
$data['client_type'] = [1 => 'Group', 2 => 'Individual'];
$data['policy_status'] = [
'under_process' => 'Under Process',
'client_pending' => 'Client Pending',
'insurer_pending' => 'Insurer Pending',
'co_insurer_pending' => 'Co-Insurer Pending',
'tpa_pending' => 'TPA Pending',
'validated' => 'Validated',
'cancelled' => 'Cancelled',
'instalment_pending' => 'Instalment Pending',
'completed' => 'Completed',
];
$data['invoice_status'] = [
'yet_to_generate' => 'Pending',
'generated' => 'Generated',
'send' => 'Sent',
'recived' => 'Payment Received',
];
$data['action_type'] = [
'addition' => 'Addition',
'deletion' => 'Deletion',
'addition_deletion' => 'Addition & Deletion',
'si_enhancement' => 'SI Enhancement',
'combo_a_d_si' => 'Combo A, D & SI',
'correction' => 'Correction',
'baby_addition' => 'Baby Addition',
'policy_instalment' => 'Policy Instalment',
'addition_inception' => 'Addition-Inception',
'bds_correction' => 'BDS Correction',
'policy_correction' => 'Policy Correction',
'policy_cancellation' => 'Policy Cancellation',
];
$data['date_type'] = [
'policy_issue_date' => 'Policy Issue Date',
'policy_start_date' => 'Policy Start Date',
'policy_end_date' => 'Policy End Date',
];
$data['endorsement_data_list'] = [];
$data['endorsement_filters'] = $this->buildEndorsementFiltersFromRequest();
$data['client'] = $this->clientModel->where('is_active', 1)->findAll();
$data['policy_types'] = $this->policyTypeModel->where('is_active', 1)->findAll();
$data['insurer'] = $this->insurerModel->where('is_active', 1)->findAll();
// $data['tpa'] = $this->tpaModel->where('is_active', 1)->findAll();
$data['insurer_branch'] = $this->insurerBranchModel->getInsurerBranchesWithInsurerNames();
$data['tpa'] = $this->tpaBranchModel->getTpaBranchesWithTpaNames();
list($policyList, $policyListByClient) = $this->getPolicyForEndorsment();
$data['endorsementPolicies'] = $policyList;
$data['endorsementPolicyListByClient'] = $policyListByClient;
// dd($data);
// print_r($data['endorsementPolicies']);die();
$this->loadLayout('policy_transaction_endorsement_list', $data);
}
public function endorsementListDataTable()
{
if (!$this->request->isAJAX()) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Invalid request.',
]);
}
$draw = (int) ($this->request->getPost('draw') ?? 0);
$start = max(0, (int) ($this->request->getPost('start') ?? 0));
$length = (int) ($this->request->getPost('length') ?? 10);
$search = trim((string) ($this->request->getPost('search')['value'] ?? ''));
$filters = $this->buildEndorsementFiltersFromRequest();
$result = $this->policyTransactionModel->getEndorsementTranctionListDataTable(
$draw,
$start,
$length,
$search,
$filters
);
$rows = [];
foreach ($result['data'] as $index => $row) {
$rows[] = $this->formatEndorsementRowForDataTable($row, $start + $index + 1);
}
return $this->response->setJSON([
'draw' => $result['draw'],
'recordsTotal' => $result['recordsTotal'],
'recordsFiltered' => $result['recordsFiltered'],
'data' => $rows,
'cache_expires_in_ms' => $result['cache_expires_in_ms'] ?? 300000,
]);
}
public function clearEndorsementListCache()
{
if (!$this->request->isAJAX()) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Invalid request.',
]);
}
session()->set('endorsement_list_cache_version', time());
return $this->response->setJSON([
'status' => true,
'message' => 'Endorsement list cache cleared.',
]);
}
protected function buildEndorsementFiltersFromRequest(): array
{
$normalize = static function ($value) {
return (!isset($value) || $value === '' || $value === null) ? 0 : $value;
};
return [
'start_date' => $normalize($this->request->getGet('start_date') ?? $this->request->getPost('start_date')),
'end_date' => $normalize($this->request->getGet('end_date') ?? $this->request->getPost('end_date')),
'client_id' => $normalize($this->request->getGet('client_id') ?? $this->request->getPost('client_id')),
'insurer_id' => $normalize($this->request->getGet('insurer_id') ?? $this->request->getPost('insurer_id')),
'policy_type_id' => $normalize($this->request->getGet('policy_type_id') ?? $this->request->getPost('policy_type_id')),
'date_type' => $normalize($this->request->getGet('date_type') ?? $this->request->getPost('date_type')),
'issuer' => $normalize($this->request->getGet('issuer') ?? $this->request->getPost('issuer')),
'status' => $normalize($this->request->getGet('status') ?? $this->request->getPost('status')),
'cache_version' => (int) (session()->get('endorsement_list_cache_version') ?? 1),
];
}
protected function formatEndorsementRowForDataTable(array $row, int $serialNo): array
{
$issuerMap = [1 => 'JIBS', 2 => 'Nhance'];
$policyStatusMap = [
'under_process' => 'Under Process',
'client_pending' => 'Client Pending',
'insurer_pending' => 'Insurer Pending',
'co_insurer_pending' => 'Co-Insurer Pending',
'tpa_pending' => 'TPA Pending',
'validated' => 'Validated',
'cancelled' => 'Cancelled',
'instalment_pending' => 'Instalment Pending',
'completed' => 'Completed',
];
$actionTypeMap = [
'addition' => 'Addition',
'deletion' => 'Deletion',
'addition_deletion' => 'Addition & Deletion',
'si_enhancement' => 'SI Enhancement',
'combo_a_d_si' => 'Combo A, D & SI',
'correction' => 'Correction',
'baby_addition' => 'Baby Addition',
'policy_instalment' => 'Policy Instalment',
'addition_inception' => 'Addition-Inception',
'bds_correction' => 'BDS Correction',
'policy_correction' => 'Policy Correction',
'policy_cancellation' => 'Policy Cancellation',
];
$editAction = '<a class="dropdown-item btnEdit" data-id="' . ($row['id'] ?? '') . '" onclick="getPolicyTransactionDataForEndorsementEdit(\'' . htmlspecialchars((string) ($row['id'] ?? ''), ENT_QUOTES) . '\')"><i class="mdi mdi-pencil mr-2 text-muted font-18 vertical-middle"></i>Edit</a>';
$deleteAction = '';
if ((int) get_role_id() === 5) {
$deleteAction = '<a class="dropdown-item delete" data-id="' . ($row['id'] ?? '') . '" onclick="removePolicyTransaction(this, \'' . htmlspecialchars((string) ($row['id'] ?? ''), ENT_QUOTES) . '\', ' . (int) ($row['policy_type_id'] ?? 0) . ')"><i class="mdi mdi-delete mr-2 text-muted font-18 vertical-middle"></i>Delete</a>';
}
$actionHtml = '<div class="btn-group dropdown"><a href="javascript: void(0);" class="dropdown-toggle arrow-none btn btn-light btn-sm" data-toggle="dropdown" aria-expanded="false"><i class="mdi mdi-dots-horizontal"></i></a><div class="dropdown-menu dropdown-menu-right">' . $editAction . $deleteAction . '</div></div>';
return [
0 => $serialNo,
1 => $issuerMap[$row['issuer'] ?? 0] ?? 'N/A',
2 => $row['client_short_name'] ?: 'N/A',
3 => $row['client_branch_name'] ?: 'N/A',
4 => $row['insurer_short_name'] ?: 'N/A',
5 => $row['policy_type'] ?: 'N/A',
6 => $actionTypeMap[$row['action_type'] ?? ''] ?? 'N/A',
7 => $row['endorsement_no'] ?: 'N/A',
8 => empty($row['data_received_date']) ? 'N/A' : date('d/m/Y', strtotime($row['data_received_date'])),
9 => $row['emp_count'] ?: '0',
10 => $row['dependent_count'] ?: '0',
11 => empty($row['policy_issue_date']) ? 'N/A' : date('d/m/Y', strtotime($row['policy_issue_date'])),
12 => $policyStatusMap[$row['status'] ?? ''] ?? 'N/A',
13 => $actionHtml,
];
}
public function viewEndorsement2()
{
// echo '<pre>';
// !dd($this->getEndorsementDataForEdit(17));
$bds_edit_pt_id = $this->request->getGet('pt_id') ?? null;
$data['tab_name'] = 'Endorsements';
$data['page_name'] = 'Endorsements';
$data['issuer'] = [1 => 'JIBS', 2 => 'Nhance'];
$data['issuer_branch'] = $this->nhanceBranchModel->where('is_active', 1)->findAll();
$data['client_type'] = [1 => 'Group', 2 => 'Individual'];
$data['policy_status'] = [
'under_process' => 'Under Process',
'client_pending' => 'Client Pending',
'insurer_pending' => 'Insurer Pending',
'co_insurer_pending' => 'Co-Insurer Pending',
'tpa_pending' => 'TPA Pending',
'validated' => 'Validated',
'cancelled' => 'Cancelled',
'instalment_pending' => 'Instalment Pending',
'completed' => 'Completed',
];
$data['invoice_status'] = [
'yet_to_generate' => 'Pending',
'generated' => 'Generated',
'send' => 'Sent',
'recived' => 'Payment Received',
];
$data['action_type'] = [
'addition' => 'Addition',
'deletion' => 'Deletion',
'addition_deletion' => 'Addition & Deletion',
'si_enhancement' => 'SI Enhancement',
'combo_a_d_si' => 'Combo A, D & SI',
'correction' => 'Correction',
'baby_addition' => 'Baby Addition',
'policy_instalment' => 'Policy Instalment',
'addition_inception' => 'Addition-Inception',
'bds_correction' => 'BDS Correction',
'policy_correction' => 'Policy Correction',
'policy_cancellation' => 'Policy Cancellation',
];
$data['date_type'] = [
'policy_issue_date' => 'Policy Issue Date',
'policy_start_date' => 'Policy Start Date',
'policy_end_date' => 'Policy End Date',
];
//filter datas
$start_date = $this->request->getGet('start_date');
$end_date = $this->request->getGet('end_date');
$client_id = $this->request->getGet('client_id');
$insurer_id = $this->request->getGet('insurer_id');
$policy_type_id = $this->request->getGet('policy_type_id');
$date_type = $this->request->getGet('date_type');
$issuer = $this->request->getGet('issuer');
$status = $this->request->getGet('status');
$start_date = (!isset($start_date) || $start_date === '' || $start_date === null) ? 0 : $start_date;
$end_date = (!isset($end_date) || $end_date === '' || $end_date === null) ? 0 : $end_date;
$client_id = (!isset($client_id) || $client_id === '' || $client_id === null) ? 0 : $client_id;
$insurer_id = (!isset($insurer_id) || $insurer_id === '' || $insurer_id === null) ? 0 : $insurer_id;
$policy_type_id = (!isset($policy_type_id) || $policy_type_id === '' || $policy_type_id === null) ? 0 : $policy_type_id;
$date_type = (!isset($date_type) || $date_type === '' || $date_type === null) ? 0 : $date_type;
$issuer = (!isset($issuer) || $issuer === '' || $issuer === null) ? 0 : $issuer;
$status = (!isset($status) || $status === '' || $status === null) ? 0 : $status;
if($bds_edit_pt_id == null){
$data['endorsement_data_list'] = $this->policyTransactionModel->getEndorsementTranctionListData($start_date, $end_date, $client_id, $insurer_id, $policy_type_id, $date_type, $issuer, $status);
}else{
$data['endorsement_data_list'] = [];
}
$data['client'] = $this->clientModel->where('is_active', 1)->findAll();
$data['policy_types'] = $this->policyTypeModel->where('is_active', 1)->findAll();
$data['insurer'] = $this->insurerModel->where('is_active', 1)->findAll();
// $data['tpa'] = $this->tpaModel->where('is_active', 1)->findAll();
$data['insurer_branch'] = $this->insurerBranchModel->getInsurerBranchesWithInsurerNames();
$data['tpa'] = $this->tpaBranchModel->getTpaBranchesWithTpaNames();
list($policyList, $policyListByClient) = $this->getPolicyForEndorsment();
$data['endorsementPolicies'] = $policyList;
$data['endorsementPolicyListByClient'] = $policyListByClient;
// dd($data);
// print_r($data['endorsementPolicies']);die();
$this->loadLayout('policy_transaction_endorsement_list_2', $data);
}
public function createEndorsementPolicy()
{
session()->set('endorsement_list_cache_version', time());
// $id = $this->request->getPost('id');
$rules = [
// ==========================================
// 1. CLIENT SECTION
// ==========================================
'client_id' => [
'label' => 'Client',
'rules' => 'required',
'errors' => ['required' => 'Client selection is mandatory.']
],
'client_policy_id' => [
'label' => 'Policy',
'rules' => 'required',
'errors' => ['required' => 'Please select the policy to endorse.']
],
'client_type' => ['rules' => 'permit_empty','errors' => []],
'client_branch_id' => ['rules' => 'permit_empty','errors' => []],
// ==========================================
// 2. ENDORSEMENT SECTION
// ==========================================
'action_type' => [
'label' => 'Endorsement Type',
'rules' => 'required',
'errors' => ['required' => 'Select an Endorsement Type.']
],
'endorsement_no' => ['label' => 'Endorsement No','rules' => 'permit_empty|regex_match[/^[a-zA-Z0-9\/_-]+$/]',
'errors' => [ 'regex_match' => 'Endorsement No can only contain letters, numbers, and symbols like / - or _' ]],
'data_received_date' => [
'label' => 'Data Received Date',
'rules' => 'required|valid_date[d/m/Y]',
'errors' => ['required' => 'Data Received Date is required.', 'valid_date' => 'Please provide a valid Data Received Date.']
],
'policy_issue_date' => [
'label' => 'Endorsement Issue Date',
'rules' => 'required|valid_date[d/m/Y]',
'errors' => ['required' => 'Endorsement Issue Date is required.', 'valid_date' => 'Please provide a valid Endorsement Issue Date.']
],
// ==========================================
// ENDORSEMENT SECTION
// ==========================================
'month' => [
'label' => 'Endorsement Issue Month',
'rules' => 'required',
'errors' => ['required' => 'Endorsement Issue Month (MM/YYYY) is required.']
],
'endorse_eff_date' => [
'label' => 'Endorsement Effective Date',
'rules' => 'permit_empty|valid_date[d/m/Y]',
'errors' => ['valid_date' => 'Please provide a valid Endorsement Effective Date.']
],
'emp_count' => [
'label' => 'No of Employees',
'rules' => 'permit_empty|numeric',
'errors' => ['numeric' => 'No of Employees must be a number.']
],
'dependent_count' => [
'label' => 'No of Dependents',
'rules' => 'permit_empty|numeric',
'errors' => ['numeric' => 'No of Dependents must be a number.']
],
'last_action_date' => [
'label' => 'Latest Action Date',
'rules' => 'permit_empty|valid_date[d/m/Y]',
'errors' => ['valid_date' => 'Please provide a valid Latest Action Date.']
],
'install_due_date' => [
'label' => 'Installment Due Date',
'rules' => 'permit_empty|valid_date[d/m/Y]',
'errors' => ['valid_date' => 'Please provide a valid Installment Due Date.']
],
// ==========================================
// PREMIUM DETAILS (ARRAY FIELDS .*)
// ==========================================
'follow_insurer_id.*' => [
'label' => 'Insurer',
'rules' => 'required',
'errors' => ['required' => 'Please select an Insurer.']
],
'calc_policy_issue_date.*' => [
'label' => 'Premium Endorsement Issue Date',
'rules' => 'required',
'errors' => ['required' => 'Endorsement Issue Date is required.']
],
'co_share_per.*' => [
'label' => 'Co-Share %',
'rules' => 'permit_empty|decimal',
'errors' => ['decimal' => 'Co-Share % must be a valid decimal.']
],
'base_premium.*' => [
'label' => 'Base Premium',
'rules' => 'permit_empty|decimal','errors' => ['decimal' => 'Base Premium must be a valid amount.']
],
'total.*' => [
'label' => 'Total Premium',
'rules' => 'permit_empty|decimal',
'errors' => ['decimal' => 'Total Premium must be a valid amount.'],
],
// Decimal validation with Labels
'non_comm_per_amt.*' => [
'label' => 'Non-Comm Premium',
'rules' => 'permit_empty|decimal',
'errors' => ['decimal' => 'Non-Comm Premium must be numeric.']
],
'tp_premium.*' => [
'label' => 'TP Premium',
'rules' => 'permit_empty|decimal',
'errors' => ['decimal' => 'TP Premium must be numeric.']
],
'ter_premium.*' => [
'label' => 'TEP Premium',
'rules' => 'permit_empty|decimal',
'errors' => ['decimal' => 'TEP Premium must be numeric.']
],
'co_premium.*' => [
'label' => 'Co-Premium',
'rules' => 'permit_empty|decimal',
'errors' => ['decimal' => 'Co-Premium must be numeric.']
],
'co_tp_premium.*' => [
'label' => 'Co-TP Premium',
'rules' => 'permit_empty|decimal',
'errors' => ['decimal' => 'Co-TP Premium must be numeric.']
],
'co_ter_premium.*' => [
'label' => 'Co-TEP Premium',
'rules' => 'permit_empty|decimal',
'errors' => ['decimal' => 'Co-TEP Premium must be numeric.']
],
'cgst.*' => [
'label' => 'CGST',
'rules' => 'permit_empty|decimal',
'errors' => ['decimal' => 'CGST must be numeric.']
],
'sgst.*' => [
'label' => 'SGST',
'rules' => 'permit_empty|decimal',
'errors' => ['decimal' => 'SGST must be numeric.']
],
'igst.*' => [
'label' => 'IGST',
'rules' => 'permit_empty|decimal',
'errors' => ['decimal' => 'IGST must be numeric.']
],
'gst_amount.*' => [
'label' => 'GST Amount',
'rules' => 'permit_empty|decimal',
'errors' => ['decimal' => 'GST Amount must be numeric.']
],
'stamp_duty.*' => [
'label' => 'Stamp Duty',
'rules' => 'permit_empty|decimal',
'errors' => ['decimal' => 'Stamp Duty must be numeric.']
],
'agreed_bp.*' => [
'label' => 'Agreed BP %',
'rules' => 'permit_empty|decimal',
'errors' => ['decimal' => 'Agreed BP % must be numeric.']
],
'agreed_tp.*' => [
'label' => 'Agreed TP %',
'rules' => 'permit_empty|decimal',
'errors' => ['decimal' => 'Agreed TP % must be numeric.']
],
'agreed_ter.*' => [
'label' => 'Agreed TEP %',
'rules' => 'permit_empty|decimal',
'errors' => ['decimal' => 'Agreed TEP % must be numeric.']
],
'agreed_amount.*' => [
'label' => 'Agreed Amount',
'rules' => 'permit_empty|decimal',
'errors' => ['decimal' => 'Agreed Amount must be numeric.']
],
// Finance/Management Specific Labels
'actual_bp_amt.*' => [
'label' => 'Actual BP Amount',
'rules' => 'permit_empty|decimal',
'errors' => ['decimal' => 'Actual BP Amount must be numeric.']
],
'actual_tp_amt.*' => [
'label' => 'Actual TP Amount',
'rules' => 'permit_empty|decimal',
'errors' => ['decimal' => 'Actual TP Amount must be numeric.']
],
'actual_tep_amt.*' => [
'label' => 'Actual TEP Amount',
'rules' => 'permit_empty|decimal',
'errors' => ['decimal' => 'Actual TEP Amount must be numeric.']
],
'actual_bp_per.*' => [
'label' => 'Actual BP %',
'rules' => 'permit_empty|decimal',
'errors' => ['decimal' => 'Actual BP % must be numeric.']
],
'actual_tp_per.*' => [
'label' => 'Actual TP %',
'rules' => 'permit_empty|decimal',
'errors' => ['decimal' => 'Actual TP % must be numeric.']
],
'actual_tep_per.*' => [
'label' => 'Actual TEP %',
'rules' => 'permit_empty|decimal',
'errors' => ['decimal' => 'Actual TEP % must be numeric.']
],
'actual_bp_brokerage_amt.*' => [
'label' => 'BP Remuneration',
'rules' => 'permit_empty|decimal',
'errors' => ['decimal' => 'BP Remuneration must be numeric.']
],
'actual_tp_brokerage_amt.*' => [
'label' => 'TP Remuneration',
'rules' => 'permit_empty|decimal',
'errors' => ['decimal' => 'TP Remuneration must be numeric.']
],
'actual_tep_brokerage_amt.*' => [
'label' => 'TEP Remuneration',
'rules' => 'permit_empty|decimal',
'errors' => ['decimal' => 'TEP Remuneration must be numeric.']
],
'exp_amt.*' => [
'label' => 'Expected Amount',
'rules' => 'permit_empty|decimal',
'errors' => ['decimal' => 'Expected Amount must be numeric.']
],
'co_share_type.*' => ['label' => 'Is Leader', 'rules' => 'permit_empty','errors' => []],
'follower_policy_no.*' => ['label' => 'Follower Policy No', 'rules' => 'permit_empty|regex_match[/^[a-zA-Z0-9 _-]+$/]','errors' => ['regex_match' => 'The {field} can only contain letters, numbers, spaces, dashes, and underscores.']],
'co_share_id.*' => ['label' => 'Record ID', 'rules' => 'permit_empty','errors' => []],
'doc_name.*' => [
'label' => 'Policy Document Name',
'rules' => 'permit_empty|regex_match[/^[a-zA-Z0-9 \/_-]+$/]|min_length[2]|max_length[100]',
'errors' => [
'regex_match' => 'The {field} can only contain letters, numbers, spaces, dashes, and underscores.'
]
],
];
if (!$this->validate($rules)) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Input validation failed',
'code' => 400,
'errors' => $this->validator->getErrors()
]);
}
$data = $this->preparePolicyTransactionData();
$id = (isset($data['id']) && !empty($data['id'])) ? $data['id'] : null;
$data['status'] = 'completed';
if (!$id) {
return $this->insertEndorsementTransaction($data);
} else {
return $this->updateEndorsementTransaction($id, $data);
}
}
private function preparePolicyTransactionData()
{
$request_post_data = $this->request->getPost();
$data = sanitizeInputArrayAdvanced($request_post_data);
// echo '<pre>';
// print_r($data);
// die;
$file_data = $this->request->getFiles() ?? null;
$data['file_data'] = $file_data ?? null;
if (!isset($data['policy_with_corr'])) {
$data['policy_with_corr'] = 0;
} elseif ($data['policy_with_corr']) {
$data['policy_with_corr'] = 1;
}
// if (!isset($data['is_cd_reduce_from_bds'])) {
// $data['is_cd_reduce_from_bds'] = 0;
// } elseif ($data['is_cd_reduce_from_bds']) {
// $data['is_cd_reduce_from_bds'] = 1;
// }
if (empty($data['data_received_date'])) {
$data['data_received_date'] = null;
} else {
$data['data_received_date'] = change_date_format($data['data_received_date'], 'd/m/Y', 'Y-m-d');
}
if (empty($data['policy_issue_date'])) {
$data['policy_issue_date'] = null;
} else {
$data['policy_issue_date'] = change_date_format($data['policy_issue_date'], 'd/m/Y', 'Y-m-d');
}
if (empty($data['endorse_eff_date'])) {
$data['endorse_eff_date'] = null;
} else {
$data['endorse_eff_date'] = change_date_format($data['endorse_eff_date'], 'd/m/Y', 'Y-m-d');
}
if (empty($data['install_due_date'])) {
$data['install_due_date'] = null;
} else {
$data['install_due_date'] = change_date_format($data['install_due_date'], 'd/m/Y', 'Y-m-d');
}
if (!empty($data['month'])) {
$month = '01/' . $data['month'];
$data['month'] = change_date_format($month, 'd/M/Y', 'Y-m-d');
}
if (empty($data['last_action_date'])) {
$data['last_action_date'] = null;
} else {
$data['last_action_date'] = change_date_format($data['last_action_date']);
}
// print_r($data); die;
// Separate Insurer and TPA Branch IDs and IDs
if (isset($data['insurer_id']) && !empty($data['insurer_id'])) {
list($data['insurer_branch_id'], $data['insurer_id']) = explode('-', $data['insurer_id']);
if (isset($data['tpa']) && !empty($data['tpa'])) {
list($data['tpa_branch_id'], $data['tpa_id']) = explode('-', $data['tpa']);
}
}
$issue_type = $this->policyTransactionModel
->where('action_type', 'inception')
->where('client_id', $this->request->getPost('client_id'))
// ->where('client_policy_id', $this->request->getPost('client_policy_id'))
->where('id', $this->request->getPost('client_policy_id'))
->where('policy_transaction.is_active', 1)
->first();
$data['tsi'] = generate_tsi_code($issue_type['issue_type'] ?? 1);
if (!isset($data['client_branch_id']) || $data['client_branch_id'] == "") {
$client_branch_id = $issue_type['client_branch_id'];
}else{
$client_branch_id = $data['client_branch_id'];
}
$data['is_cd_reduce_from_bds'] = (isset($issue_type['policy_type_id']) && $issue_type['policy_type_id'] > 7 && $data['client_type'] == 1) ? 1 : 0;
// if($data['bro_payable_by'] == ""){
// $data['bro_payable_by'] = $issue_type['bro_payable_by'];
// }
if (!$data['id']) {
$data += [
'issuer' => 2,
'issuer_branch' => $data['issuer_branch'] ?? 1,
'client_type' => $data['client_type'] ?? $issue_type['client_type'] ?? null,
'policy_type_id' => $issue_type['policy_type_id'] ?? null,
'issue_type' => $issue_type['issue_type'] ?? null,
'source_client_policy_id' => $issue_type['source_client_policy_id'] ?? null,
'cd_ac_no' => isset($data['cd_ac_no']) && !empty($data['cd_ac_no']) ? $data['cd_ac_no'] : $issue_type['cd_ac_no'] ?? null,
'cd_ac_pk' => isset($data['cd_ac_pk']) && !empty($data['cd_ac_pk']) ? $data['cd_ac_pk'] : $issue_type['cd_ac_pk'] ?? null,
// 'policy_issue_date' => $issue_type['policy_issue_date'] ?? null,
'policy_start_date' => $issue_type['policy_start_date'] ?? null,
'policy_end_date' => $issue_type['policy_end_date'] ?? null,
'revenue_type' => $issue_type['revenue_type'] ?? null,
'co_share' => $issue_type['co_share'] ?? 0,
'bro_payable_by' => $data['bro_payable_by'] == "" ? $issue_type['bro_payable_by'] ?? 0 : $data['bro_payable_by'],
'installment' => $issue_type['installment'] ?? null,
'installment_data' => $issue_type['installment_data'] ?? null,
'location' => $issue_type['location'] ?? null,
'links' => $issue_type['links'] ?? null,
'stage' => $issue_type['stage'] ?? null,
'etat' => $issue_type['etat'] ?? null,
'etat_band' => $issue_type['etat_band'] ?? null,
'edate' => $issue_type['edate'] ?? null,
'renewal_date' => $issue_type['renewal_date'] ?? null,
'rollover_date' => $issue_type['rollover_date'] ?? null,
'policy_holder_name' => $issue_type['policy_holder_name'] ?? null,
'same_as_proposer' => $issue_type['same_as_proposer'] ?? 1,
'ref' => $issue_type['ref'] ?? null,
'spl' => $issue_type['spl'] ?? null,
'fund_received' => $issue_type['fund_received'] ?? null,
'listed_insurers' => $issue_type['listed_insurers'] ?? null,
'ppteam' => $issue_type['ppteam'] ?? null,
'sales_generated_by' => $issue_type['sales_generated_by'] ?? null,
'serviced_by' => $issue_type['serviced_by'] ?? null,
'salse_person_manager_id' => $issue_type['salse_person_manager_id'] ?? null,
'service_person_manager_id' => $issue_type['service_person_manager_id'] ?? null,
'service_person_branch_id' => $issue_type['service_person_branch_id'] ?? null,
'agent_id' => $issue_type['agent_id'] ?? null,
'agent_code' => $issue_type['agent_code'] ?? null,
'pos_id' => $issue_type['pos_id'] ?? null,
];
$data['client_branch_id'] = $client_branch_id;
}
// print_r($issue_type);
// print_r($data);
// die;
return $data;
}
private function insertEndorsementTransaction($data)
{
$insert = $this->policyTransactionModel->insert($data);
if ($insert) {
$this->insertTransactionStatus($insert, $data, 1);
$this->handleCompletedStatus($data, $insert);
$this->insertOrUpdateCoShareDetails($data, $insert);
// policy file upload
if(isset($data['doc_name']) && isset($data['file_data']) && !empty($data['doc_name']) && !empty($data['file_data'])){
$this->uploadFile($data['doc_name'], $data['file_data'], $insert);
}
return $this->respond(['status' => true, 'message' => 'Endorsement transaction created successfully'], 200);
}
return $this->respond(['status' => false, 'message' => 'Endorsement transaction creation failed'], 400);
}
private function updateEndorsementTransaction($id, $data)
{
$data['updated_by'] = get_session_userid();
$old_endorse_data = $this->policyTransactionModel->where('id', $id)->where('is_active', 1)->first();
$update = $this->policyTransactionModel->where('id', $id)->set($data)->update();
if ($update) {
$this->insertTransactionStatus($id, $data, 1);
// if($old_endorse_data['status'] != "completed"){
// $this->handleCompletedStatus($data, $id);
// }
$this->insertOrUpdateCoShareDetails($data, $id);
return $this->respond(['status' => true, 'message' => 'Endorsement transaction updated successfully'], 200);
}
return $this->respond(['status' => false, 'message' => 'Endorsement transaction update failed'], 400);
}
private function handleCompletedStatus($data, $policy_tran_id)
{
if ($data['client_type'] == 1 && $data['status'] == 'completed' && $data['is_cd_reduce_from_bds'] == 1) {
$tolamt = (int) $data['total'][0] ?? 0;
if(!empty($tolamt)){
$description = 'The following amount of Rs. ' . round($tolamt, 2) . '/- has been' .
($data['action_type'] == 'deletion' ? ' Credit ' : ' Debit ') . 'from the policy transaction (BDS)';
$cd_tranction_data = [
'amount' => abs($tolamt),
'sub_type_id' => $data['action_type'] == 'deletion' ? 3 : 4,
'client_id' => $data['client_id'],
'client_policy_id' => $data['client_policy_id'],
'endorsement_no' => null,
'cd_ac_no' => $data['cd_ac_no'] ?? null,
'insurer_id' => $data['insurer_id'],
'description' => $description,
'transaction_type' => $data['action_type'] == 'deletion' ? 'Credit' : 'Debit',
'updated_by' => get_session_userid(),
'event_name' => $data['action_type'],
'is_active' => 1,
'cd_ac_pk' => $data['cd_ac_pk'] ?? null,
'pt_id' => $policy_tran_id ?? null,
];
$result = DepositHelper::saveDeposit($cd_tranction_data, get_session_userid());
if(isset($result['success']) && $result['success']){
$update_data['ct_tran_id'] = $result['insert_id'];
$this->policyTransactionModel->where('id', $policy_tran_id)->set($update_data)->update();
}
}
}
}
public function getEndorsementDataForEdit($id)
{
$data = $this->policyTransactionModel
->select('
policy_transaction.*,
clients.short_name as client_short_name,
clients.client_type,
(
select last_action_date
from policy_transaction_status
where policy_tran_id = policy_transaction.id
and status = policy_transaction.status
order by id desc
limit 1
) as last_action_date
')
->join('clients', 'clients.id = policy_transaction.client_id')
->join('client_policy', 'policy_transaction.client_policy_id = client_policy.id', 'left')
->where('policy_transaction.id', $id)
->where('policy_transaction.is_active', 1)
->orderBy('id', 'asc')
->first();
$pt_id = null;
if(!empty($data)){
$inception_data = $this->policyTransactionModel
->where('policy_no', $data['policy_no'])
->where('client_id', $data['client_id'])
->where('action_type', 'inception')
->first();
$pt_id = $inception_data['id'];
}
if (!empty($data['policy_start_date'])) {
$data['policy_start_date'] = change_date_format($data['policy_start_date'], 'Y-m-d', 'd/m/Y');
}
if (!empty($data['policy_end_date'])) {
$data['policy_end_date'] = change_date_format($data['policy_end_date'], 'Y-m-d', 'd/m/Y');
}
if (!empty($data['data_received_date'])) {
$data['data_received_date'] = change_date_format($data['data_received_date'], 'Y-m-d', 'd/m/Y');
}
if (!empty($data['policy_issue_date'])) {
$data['policy_issue_date'] = change_date_format($data['policy_issue_date'], 'Y-m-d', 'd/m/Y');
}
if (!empty($data['endorse_eff_date'])) {
$data['endorse_eff_date'] = change_date_format($data['endorse_eff_date'], 'Y-m-d', 'd/m/Y');
}
if (!empty($data['install_due_date'])) {
$data['install_due_date'] = change_date_format($data['install_due_date'], 'Y-m-d', 'd/m/Y');
}
if (!empty($data['last_action_date'])) {
$data['last_action_date'] = change_date_format($data['last_action_date'], 'Y-m-d', 'd/m/Y');
}
if (!empty($data['month'])) {
$data['month'] = change_date_format($data['month'], 'Y-m-d', 'M/Y');
}
// print_r($data); die;
//get PT Co-Share Details
$data['pt_co_share_details'] = $this->PTCOShareDetailsModel
->select("
pt_co_share_details.*,
(
SELECT
COUNT(*)
FROM
co_share_stmt_details
WHERE
co_share_stmt_details.co_share_id = pt_co_share_details.id
AND co_share_stmt_details.is_active = 1
) AS record_count,
(
SELECT
SUM(actual_bp_amt)
FROM
co_share_stmt_details
WHERE
co_share_id = pt_co_share_details.id
AND is_active = 1
) AS actual_bp_amount,
(
SELECT
SUM(actual_tp_amt)
FROM
co_share_stmt_details
WHERE
co_share_id = pt_co_share_details.id
AND is_active = 1
) AS actual_tp_amount,
(
SELECT
SUM(actual_tep_amt)
FROM
co_share_stmt_details
WHERE
co_share_id = pt_co_share_details.id
AND is_active = 1
) AS actual_tep_amount,
(
SELECT
SUM(actual_bp_per)
FROM
co_share_stmt_details
WHERE
co_share_id = pt_co_share_details.id
AND is_active = 1
) AS actual_bp_percentage,
(
SELECT
SUM(actual_tp_per)
FROM
co_share_stmt_details
WHERE
co_share_id = pt_co_share_details.id
AND is_active = 1
) AS actual_tp_percentage,
(
SELECT
SUM(actual_tep_per)
FROM
co_share_stmt_details
WHERE
co_share_id = pt_co_share_details.id
AND is_active = 1
) AS actual_tep_percentage,
(
SELECT
SUM(actual_bp_brokerage_amt)
FROM
co_share_stmt_details
WHERE
co_share_id = pt_co_share_details.id
AND is_active = 1
) AS actual_bp_brokerage_amount,
(
SELECT
SUM(actual_tp_brokerage_amt)
FROM
co_share_stmt_details
WHERE
co_share_id = pt_co_share_details.id
AND is_active = 1
) AS actual_tp_brokerage_amount,
(
SELECT
SUM(actual_tep_brokerage_amt)
FROM
co_share_stmt_details
WHERE
co_share_id = pt_co_share_details.id
AND is_active = 1
) AS actual_tep_brokerage_amount,
DATE_FORMAT(pt_policy_issue_date, '%d/%m/%Y') AS pt_policy_issue_date
")
->where('pt_id', $id)
->where('is_active', 1)
->orderBy('id', 'asc')
->findAll();
// print_r($data['endorse_eff_date']); die;
$pt_bp_amt = $this->PTCOShareDetailsModel
->select('bp_amt, amount')
->where('pt_id', $id)
->where('co_share_type', 1)
->where('is_active', 1)
->first();
// dd(db_connect()->getLastQuery() ,$pt_bp_amt);
$data['base_cd_amount'] = $pt_bp_amt['amount'] ?? null;
$ptFileQuery = $this->PTFileModel
->select('pt_files.*')
->join('policy_transaction', 'pt_files.pt_id = policy_transaction.id')
->where('pt_files.pt_id', $id)
->where('pt_files.is_active', 1);
if (!in_array(get_role_id(), [1, 5]) && empty(array_intersect(user_team(), [MANAGEMENT_TEAM_ID, FINANCE_TEAM_ID, BUSINESS_TEAM_ID]))) {
if (get_role_id() == 4 && in_array(POS_TEAM_ID, user_team())) {
$ptFileQuery->where('pt_files.created_by', get_session_userid());
}
}
$data['pt_files'] = $ptFileQuery->findAll();
if ($data) {
return $this->respond(['status' => true, 'data' => $data, 'pt_id' => $pt_id], 200);
} else {
return $this->respond(['status' => false], 200);
}
}
public function getEndorsementDataForEdit2($id)
{
$data = $this->policyTransactionModel
->select('
policy_transaction.*,
clients.short_name as client_short_name,
clients.client_type,
(
select last_action_date
from policy_transaction_status
where policy_tran_id = policy_transaction.id
and status = policy_transaction.status
order by id desc
limit 1
) as last_action_date
')
->join('clients', 'clients.id = policy_transaction.client_id')
->join('client_policy', 'policy_transaction.client_policy_id = client_policy.id', 'left')
->where('policy_transaction.id', $id)
->where('policy_transaction.is_active', 1)
->orderBy('id', 'asc')
->first();
$pt_id = null;
if(!empty($data)){
$inception_data = $this->policyTransactionModel
->where('policy_no', $data['policy_no'])
->where('client_id', $data['client_id'])
->where('action_type', 'inception')
->first();
$pt_id = $inception_data['id'];
}
if (!empty($data['policy_start_date'])) {
$data['policy_start_date'] = change_date_format($data['policy_start_date'], 'Y-m-d', 'd/m/Y');
}
if (!empty($data['policy_end_date'])) {
$data['policy_end_date'] = change_date_format($data['policy_end_date'], 'Y-m-d', 'd/m/Y');
}
if (!empty($data['data_received_date'])) {
$data['data_received_date'] = change_date_format($data['data_received_date'], 'Y-m-d', 'd/m/Y');
}
if (!empty($data['policy_issue_date'])) {
$data['policy_issue_date'] = change_date_format($data['policy_issue_date'], 'Y-m-d', 'd/m/Y');
}
if (!empty($data['endorse_eff_date'])) {
$data['endorse_eff_date'] = change_date_format($data['endorse_eff_date'], 'Y-m-d', 'd/m/Y');
}
if (!empty($data['install_due_date'])) {
$data['install_due_date'] = change_date_format($data['install_due_date'], 'Y-m-d', 'd/m/Y');
}
if (!empty($data['last_action_date'])) {
$data['last_action_date'] = change_date_format($data['last_action_date'], 'Y-m-d', 'd/m/Y');
}
if (!empty($data['month'])) {
$data['month'] = change_date_format($data['month'], 'Y-m-d', 'M/Y');
}
// print_r($data); die;
//get PT Co-Share Details
$data['pt_co_share_details'] = $this->PTCOShareDetailsModel
->select("
pt_co_share_details.*,
(
SELECT
COUNT(*)
FROM
co_share_stmt_details
WHERE
co_share_stmt_details.co_share_id = pt_co_share_details.id
AND co_share_stmt_details.is_active = 1
) AS record_count,
(
SELECT
SUM(actual_bp_amt)
FROM
co_share_stmt_details
WHERE
co_share_id = pt_co_share_details.id
AND is_active = 1
) AS actual_bp_amount,
(
SELECT
SUM(actual_tp_amt)
FROM
co_share_stmt_details
WHERE
co_share_id = pt_co_share_details.id
AND is_active = 1
) AS actual_tp_amount,
(
SELECT
SUM(actual_tep_amt)
FROM
co_share_stmt_details
WHERE
co_share_id = pt_co_share_details.id
AND is_active = 1
) AS actual_tep_amount,
(
SELECT
SUM(actual_bp_per)
FROM
co_share_stmt_details
WHERE
co_share_id = pt_co_share_details.id
AND is_active = 1
) AS actual_bp_percentage,
(
SELECT
SUM(actual_tp_per)
FROM
co_share_stmt_details
WHERE
co_share_id = pt_co_share_details.id
AND is_active = 1
) AS actual_tp_percentage,
(
SELECT
SUM(actual_tep_per)
FROM
co_share_stmt_details
WHERE
co_share_id = pt_co_share_details.id
AND is_active = 1
) AS actual_tep_percentage,
(
SELECT
SUM(actual_bp_brokerage_amt)
FROM
co_share_stmt_details
WHERE
co_share_id = pt_co_share_details.id
AND is_active = 1
) AS actual_bp_brokerage_amount,
(
SELECT
SUM(actual_tp_brokerage_amt)
FROM
co_share_stmt_details
WHERE
co_share_id = pt_co_share_details.id
AND is_active = 1
) AS actual_tp_brokerage_amount,
(
SELECT
SUM(actual_tep_brokerage_amt)
FROM
co_share_stmt_details
WHERE
co_share_id = pt_co_share_details.id
AND is_active = 1
) AS actual_tep_brokerage_amount,
DATE_FORMAT(pt_policy_issue_date, '%d/%m/%Y') AS pt_policy_issue_date
")
->where('pt_id', $id)
->where('is_active', 1)
->orderBy('id', 'asc')
->findAll();
// print_r($data['endorse_eff_date']); die;
$pt_bp_amt = $this->PTCOShareDetailsModel
->select('bp_amt, amount')
->where('pt_id', $id)
->where('co_share_type', 1)
->where('is_active', 1)
->first();
// dd(db_connect()->getLastQuery() ,$pt_bp_amt);
$data['base_cd_amount'] = $pt_bp_amt['amount'] ?? null;
if ($data) {
return $this->respond(['status' => true, 'data' => $data, 'pt_id' => $pt_id], 200);
} else {
return $this->respond(['status' => false], 200);
}
}
//------------------------------------------------------------------------------------------------
//file upload function
public function uploadFile($docs_name = null, $files = null, $pt_id = null)
{
$GoogleDriveController = new GoogleDriveController();
if(empty($docs_name) && empty($files) && empty($pt_id) && $this->request){
$files = $this->request->getFiles();
$docs_name = $this->request->getPost('doc_name');
$pt_id = $this->request->getPost('pt_id');
$client_policy_id = $this->request->getPost('client_policy_id');
$rules = [
'doc_name.*' => [
'label' => 'Policy Document Name',
'rules' => 'permit_empty|required|regex_match[/^[a-zA-Z0-9 _-]+$/]|min_length[2]|max_length[100]',
'errors' => [
'required' => "Policy Document Name is required",
'regex_match' => 'The {field} can only contain letters, numbers, spaces, dashes, and underscores.'
]
],
];
if (!$this->validate($rules)) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Input validation failed',
'code' => 400,
'errors' => $this->validator->getErrors()
]);
}
}
$uploadFilePath = WRITEPATH . 'uploads/client_kyc_documents';
$uploadData = [];
foreach ($docs_name as $key => $docName) {
// Get the corresponding file for this document name
$file = $files['file'][$key];
if (!empty($docName) && $file->isValid() && !$file->hasMoved()) {
// Upload via FileStorageService (S3-only when enabled; unique storage key)
$uploadedFileName = storage_file_Upload($file, $uploadFilePath, UPLOAD_EXT_POLICY_DOCS);
if ($uploadedFileName) {
// Prepare data for each document upload
$docData = [
'pt_id' => $pt_id,
'doc_name' => $docName,
'file_name' => $uploadedFileName,
'created_by' => get_session_userid(),
];
// $uploadFilePath = $uploadFilePath . '/' . $uploadedFileName;
// $GoogleDriveController->uploadFiletoGdrive(client_policy_id: $client_policy_id, doc_type: 'POLICY', file_path: $uploadFilePath, file_name: $uploadedFileName);
// Insert into database
$insert = $this->PTFileModel->insert($docData);
if ($insert) {
$uploadData[] = $docData;
}
}
}
}
if(!empty($docs_name) && !empty($files) && !empty($pt_id) && !$this->request){
return true;
}
// print_r($uploadData); die;
// $uploadData = uploadFilesToGoogleDrive($files['file'], $doc_name, $pt_id);
if (!empty($uploadData)) {
$ptFileQuery = $this->PTFileModel
->select('pt_files.*')
->join('policy_transaction', 'pt_files.pt_id = policy_transaction.id')
->where('pt_files.pt_id', $pt_id)
->where('pt_files.is_active', 1);
if (!in_array(get_role_id(), [1, 5]) && empty(array_intersect(user_team(), [MANAGEMENT_TEAM_ID, FINANCE_TEAM_ID, BUSINESS_TEAM_ID]))) {
if (get_role_id() == 4 && in_array(POS_TEAM_ID, user_team())) {
$ptFileQuery->where('pt_files.created_by', get_session_userid());
}
}
$data['pt_files'] = $ptFileQuery->findAll();
return $this->respond(['status' => true, 'message' => 'File uploaded successfully in G-Drive', 'data' => $data]);
} else {
return $this->respond(['status' => false, 'message' => 'Failed to upload file in G-Drive']);
}
}
// update Invoice Status
public function updateInvoiceStatus()
{
$ids = $this->request->getPost('ids');
$ids = json_decode($ids);
// var_dump($ids); die;
$data['invoice_status'] = $this->request->getPost('invoice_status');
if ($this->request->getPost('invoice_status') == 'generated') {
$data['invoice_no'] = $this->request->getPost('invoice_no');
}
$update = $this->policyTransactionModel
->whereIn('id', $ids)
->set($data)
->update();
if ($update) {
return $this->respond(['status' => true, 'data' => $ids, 'message' => 'Invoice status updated successfully'], 200);
} else {
return $this->respond(['status' => true, 'data' => $ids, 'message' => 'Failed to update invoice status'], 200);
}
}
public function removeCoShareData($id)
{
$this->myLogger->logme('error', 'PT Co Share Detailes Remove function called');
$data = [
'updated_by' => get_session_userid(),
'is_active' => 0
];
$update = $this->PTCOShareDetailsModel->where('id', $id)->set($data)->update();
if ($update) {
return $this->respond(['status' => true, 'code' => 200, 'message' => 'Data removed successfully'], 200);
} else {
return $this->respond(['status' => false, 'code' => 404, 'message' => 'Failed to remove data'], 200);
}
}
public function getPTCOShareCount($client_id, $client_policy_id)
{
$totalCount = $this->PTCOShareDetailsModel
->select("
pt_co_share_details.*,
policy_transaction.bro_payable_by,
policy_transaction.cd_ac_pk,
(
select cd_ac_no
from cd_master
where id = policy_transaction.cd_ac_pk
) as cd_account_no,
(
select balance
from cash_deposit
where cd_ac_pk = policy_transaction.cd_ac_pk
and is_active = 1
order by id desc
limit 1
) as cd_amount,
")
->join('policy_transaction', 'policy_transaction.id = pt_co_share_details.pt_id')
->where('policy_transaction.client_id', $client_id)
// ->where('policy_transaction.client_policy_id', $client_policy_id)
->where('policy_transaction.id', $client_policy_id)
->where('policy_transaction.action_type', 'inception')
->where('policy_transaction.is_active', 1)
->findAll();
$is_copay_yes = $this->policyTransactionModel
->where('client_id', $client_id)
// ->where('client_policy_id', $client_policy_id)
->where('id', $client_policy_id)
->where('action_type', 'inception')
->where('is_active', 1)
->first();
$cd_ac_no = db_connect()->table('cd_master')->where('id', $is_copay_yes['cd_ac_pk'] ?? null)->get()->getRowArray();
if ($totalCount) {
return $this->respond(['status' => true, 'code' => 200, 'data' => $totalCount, 'is_copay_yes' => $is_copay_yes, "cd_master_data" => $cd_ac_no], 200);
} else {
$insurer_data = $this->clientPolicyModel->where('id', $client_policy_id)->where('is_active', 1)->first();
return $this->respond(['status' => false, 'code' => 404, 'message' => 'There is no policy inception data.'], 200);
}
}
public function checkInvoiceStatus($pt_id)
{
$data = $this->policyTransactionModel
->join('pt_co_share_details', 'policy_transaction.id = pt_co_share_details.pt_id')
->join('insurer_statements', 'pt_co_share_details.statement_id = insurer_statements.id')
->where('policy_transaction.id', $pt_id)
->where('policy_transaction.is_active', 1)
->where('pt_co_share_details.is_active', 1)
->where('pt_co_share_details.statement_id IS NOT NULL')
->where('insurer_statements.invoice_no IS NOT NULL')
->countAllResults();
if ($data) {
return $this->respond(['status' => true, 'count' => $data, 'code' => 200], 200);
} else {
return $this->respond(['status' => false, 'count' => 0, 'message' => 'No Data Found', 'code' => 404], 200);
}
}
public function getBasePolicy($client_id, $client_branch_id)
{
$data = $this->clientPolicyModel
->select('client_policy.*, policy_type.policy_type')
->join('policy_type', 'policy_type.id = client_policy.policy_type_id')
->where('client_policy.client_id', $client_id)
->where('client_policy.client_branch_id', $client_branch_id)
->whereIn('client_policy.policy_type_id', [2, 3])
->where('client_policy.is_active', 1)
->findAll();
if ($data) {
return $this->respond(['status' => true, 'data' => $data, 'code' => 200], 200);
} else {
return $this->respond(['status' => false, 'count' => 0, 'message' => 'No Data Found', 'code' => 404], 200);
}
}
//---------------------------------------------------------------------------------------------------
//get BDS Reports data old function
public function reportBDSOld()
{
$data['tab_name'] = 'BDS Report';
$data['page_name'] = 'BDS Report';
$data['issuer'] = [1 => 'JIBS', 2 => 'Nhance'];
$data['client_type'] = [1 => 'Group', 2 => 'Individual'];
$data['issuing_type'] = [1 => 'Fresh', 2 => 'Renewal', 3 => 'Roll Over'];
$data['policy_status'] = [
'pending' => 'Pending',
'exported_to_insurer' => 'Exported to Insurer',
'imported_from_insurer' => 'Imported from Insurer',
'exported_to_tpa' => 'Exported to TPA',
'imported_from_tpa' => 'Imported from TPA',
'completed' => 'Completed'
];
$data['invoice_status_array'] = [
'yet_to_generate' => 'Yet to Generate',
'generated' => 'Generated',
'send' => 'Send',
'recived' => 'Recived',
];
$data['date_type'] = [
'policy_issue_date' => 'Policy Issue Date',
'policy_start_date' => 'Policy Start Date',
'policy_end_date' => 'Policy End Date',
'data_received_date' => 'Data Received Date',
'closure_date' => 'Closure Date',
];
$data['insurer'] = $this->insurerModel->where('is_active', 1)->findAll();
$data['policy_types'] = $this->policyTypeModel->where('is_active', 1)->findAll();
$data['clients'] = $this->clientModel->where('is_active', 1)->findAll();
//filter datas
$start_date = $this->request->getGet('start_date');
$end_date = $this->request->getGet('end_date');
$client_id = $this->request->getGet('client_id');
$insurer_id = $this->request->getGet('insurer_id');
$policy_type_id = $this->request->getGet('policy_type_id');
$date_type = $this->request->getGet('date_type');
$issuer = $this->request->getGet('issuer');
$start_date = (!isset($start_date) || $start_date === '' || $start_date === null) ? 0 : $start_date;
$end_date = (!isset($end_date) || $end_date === '' || $end_date === null) ? 0 : $end_date;
$client_id = (!isset($client_id) || $client_id === '' || $client_id === null) ? 0 : $client_id;
$insurer_id = (!isset($insurer_id) || $insurer_id === '' || $insurer_id === null) ? 0 : $insurer_id;
$policy_type_id = (!isset($policy_type_id) || $policy_type_id === '' || $policy_type_id === null) ? 0 : $policy_type_id;
$date_type = (!isset($date_type) || $date_type === '' || $date_type === null) ? 0 : $date_type;
$issuer = (!isset($issuer) || $issuer === '' || $issuer === null) ? 0 : $issuer;
//Actual data for the list
$data['report_list'] = $this->policyTransactionModel->getBDSReportList($start_date, $end_date, $client_id, $insurer_id, $policy_type_id, $date_type, $issuer);
// dd($data);
$this->loadLayout('report_bds_filter', $data);
}
//get BDS Reports data New Function
public function reportBDS()
{
$data['tab_name'] = 'BDS Report';
$data['page_name'] = 'BDS Report';
$data['issuer'] = [1 => 'JIBS', 2 => 'Nhance'];
$data['client_type'] = [1 => 'Group', 2 => 'Individual'];
$data['issuing_type'] = [1 => 'Fresh', 2 => 'Renewal', 3 => 'Roll Over'];
$data['policy_status'] = [
'pending' => 'Pending',
'exported_to_insurer' => 'Exported to Insurer',
'imported_from_insurer' => 'Imported from Insurer',
'exported_to_tpa' => 'Exported to TPA',
'imported_from_tpa' => 'Imported from TPA',
'completed' => 'Completed'
];
$data['invoice_status_array'] = [
'yet_to_generate' => 'Yet to Generate',
'generated' => 'Generated',
'send' => 'Send',
'recived' => 'Recived',
];
$data['date_type'] = [
'policy_issue_date' => 'Policy Issue Date',
'policy_start_date' => 'Policy Start Date',
'policy_end_date' => 'Policy End Date',
'data_received_date' => 'Data Received Date',
'closure_date' => 'Closure Date',
'statement_month' => 'Statement Month',
];
$data['insurer'] = $this->insurerModel->where('is_active', 1)->findAll();
$data['policy_types'] = $this->policyTypeModel->where('is_active', 1)->findAll();
$data['clients'] = $this->clientModel->where('is_active', 1)->findAll();
$data['users'] = $this->userModel->where('is_active', 1)->findAll();
$data['policy_count'] = $this->policyTransactionModel->where('is_active', 1)->countAllResults();
// List data loaded via server-side DataTables AJAX
$data['report_list'] = [];
$data['bds_filters'] = $this->buildBDSReportFiltersFromRequest();
// dd($data);
$this->loadLayout('report_bds_filter', $data);
}
/**
* Server-side DataTables endpoint for BDS report list.
*/
public function reportBDSDataTable()
{
if (!$this->request->isAJAX()) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Invalid request.',
]);
}
$draw = (int) ($this->request->getPost('draw') ?? 0);
$start = max(0, (int) ($this->request->getPost('start') ?? 0));
$length = (int) ($this->request->getPost('length') ?? 10);
$search = trim((string) ($this->request->getPost('search')['value'] ?? ''));
$filters = $this->buildBDSReportFiltersFromRequest();
$result = $this->policyTransactionModel->getBDSReportListDataTable(
$draw,
$start,
$length,
$search,
$filters
);
$serialStart = $start + 1;
$data = [];
foreach ($result['data'] as $index => $row) {
$data[] = $this->formatBdsReportRowForDataTable($row, $serialStart + $index);
}
return $this->response->setJSON([
'draw' => $result['draw'],
'recordsTotal' => $result['recordsTotal'],
'recordsFiltered' => $result['recordsFiltered'],
'data' => $data,
'totals' => $result['totals'],
]);
}
public function clearReportBDSCache()
{
if (!$this->request->isAJAX()) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Invalid request.',
]);
}
session()->set('bds_report_cache_version', time());
return $this->response->setJSON([
'status' => true,
'message' => 'BDS report cache cleared.',
]);
}
/**
* Normalize BDS report filter params from the current request.
*/
protected function buildBDSReportFiltersFromRequest(): array
{
$start_date = $this->request->getGet('start_date') ?? $this->request->getPost('start_date');
$end_date = $this->request->getGet('end_date') ?? $this->request->getPost('end_date');
$client_id = $this->request->getGet('client_id') ?? $this->request->getPost('client_id');
$insurer_id = $this->request->getGet('insurer_id') ?? $this->request->getPost('insurer_id');
$policy_type_id = $this->request->getGet('policy_type_id') ?? $this->request->getPost('policy_type_id');
$date_type = $this->request->getGet('date_type') ?? $this->request->getPost('date_type');
$issuer = $this->request->getGet('issuer') ?? $this->request->getPost('issuer');
$client_branch_id = $this->request->getGet('client_branch_id') ?? $this->request->getPost('client_branch_id');
$insurer_branch_id = $this->request->getGet('insurer_branch_id') ?? $this->request->getPost('insurer_branch_id');
$client_policy_id = $this->request->getGet('client_policy_id') ?? $this->request->getPost('client_policy_id');
$user_id = $this->request->getGet('user_id') ?? $this->request->getPost('user_id');
if ($date_type == 'statement_month' && $start_date && $end_date) {
$start_date = (string) date('Y-m-01', strtotime($start_date));
$end_date = (string) date('Y-m-t', strtotime($end_date));
}
$normalize = static function ($value) {
return (!isset($value) || $value === '' || $value === null) ? 0 : $value;
};
$where = '';
if ($this->request->is('post')) {
$request_post_data = $this->request->getPost();
$sanitized_post_data = sanitizeInputArrayAdvanced($request_post_data);
$isFromDashboard = $sanitized_post_data['is_dashboard'] ?? null;
if (isset($isFromDashboard) && !empty($isFromDashboard) && (int) $isFromDashboard === 1) {
$ids = array_filter(explode(',', $sanitized_post_data['ids'] ?? ''));
if (!empty($ids)) {
$idsStr = implode(',', array_map('intval', $ids));
$where = "policy_transaction.id IN ($idsStr)";
} else {
$where = [];
}
}
}
return [
'start_date' => $normalize($start_date),
'end_date' => $normalize($end_date),
'client_id' => $normalize($client_id),
'insurer_id' => $normalize($insurer_id),
'policy_type_id' => $normalize($policy_type_id),
'date_type' => $normalize($date_type),
'issuer' => $normalize($issuer),
'client_branch_id' => $normalize($client_branch_id),
'insurer_branch_id' => $normalize($insurer_branch_id),
'client_policy_id' => $normalize($client_policy_id),
'user_id' => $normalize($user_id),
'where' => $where,
'cache_version' => (int) (session()->get('bds_report_cache_version') ?? 1),
];
}
/**
* Format a single BDS report row for DataTables output.
*/
protected function formatBdsReportRowForDataTable(array $row, int $serialNo): array
{
$hasIrda = ((float) ($row['total_irda_amt'] ?? 0)) != 0.0;
$actionType = strtolower((string) ($row['action_type'] ?? ''));
$editBaseUrl = $actionType === 'policy'
? base_url('policy_tranction/inception/list')
: base_url('policy_tranction/endorsement/list');
$editLink = $editBaseUrl . '?pt_id=' . ($row['id'] ?? '');
$totalIrdaAmt = $row['total_irda_amt'] ?? '0.00';
$unbilled = isset($row['unbilled_amount']) ? number_format((float) $row['unbilled_amount'], 2, '.', '') : '0.00';
$fmtDate = static function ($value) {
return empty($value) ? 'N/A' : change_date_format($value, 'Y-m-d', 'd/m/Y');
};
$fmtNum = static function ($value, int $decimals = 2) {
return number_format((float) ($value ?? 0), $decimals, '.', '');
};
$na = static function ($value) {
return ($value !== null && $value !== '') ? $value : 'N/A';
};
$cells = [
$serialNo . ' &nbsp; <a href="' . $editLink . '" class="mdi mdi-pencil"></a>',
$na($row['user_name'] ?? null),
$na($row['policy_issue_month'] ?? null),
$na($row['revenue_type'] ?? null),
$na($row['client_type'] ?? null),
$na($row['client_name'] ?? null),
$na($row['action_type'] ?? null),
$na($row['policy_type'] ?? null),
$na($row['bap'] ?? null),
$na($row['vehicle_no'] ?? null),
$na($row['policy_no'] ?? null),
$na($row['endorsement_no'] ?? null),
$na($row['insurer_branch_name'] ?? null),
$fmtDate($row['endorse_eff_date'] ?? null),
$fmtDate($row['policy_start_date'] ?? null),
$fmtDate($row['policy_end_date'] ?? null),
$na($row['ref'] ?? null),
$na($row['remarks'] ?? null),
$hasIrda ? ($row['bp_amt'] ?: '0.00') : '0.00',
$hasIrda ? ($row['tp_or_ter'] ?: '0.00') : '0.00',
$hasIrda ? ($row['premium_wo_gst'] ?: '0.00') : '0.00',
$hasIrda ? ($row['total_premium'] ?: '0.00') : '0.00',
($hasIrda ? ($row['agreed_bp_per'] ?: '0.00') : '0.00') . '%',
($hasIrda ? ($row['agreed_tp_or_ter_per'] ?: '0.00') : '0.00') . '%',
isset($row['reward']) ? $row['reward'] : '0.00',
'<span class="right-align-input" onclick="showCoShareStatementDetails(this)" data-id="' . ($row['pt_id'] ?? '') . '">' . $totalIrdaAmt . '</span>',
'<span class="right-align-input">' . (empty($row['billed_amt']) ? '0.00' : $row['billed_amt']) . '</span>',
'<span class="right-align-input">' . $unbilled . '</span>',
$na($row['salse_person_name'] ?? null),
$na($row['service_person_name'] ?? null),
$na($row['nhance_branch'] ?? null),
$na($row['installment'] ?? null),
$fmtDate($row['data_received_date'] ?? null),
$fmtDate($row['renewal_date'] ?? null),
$row['co_share'] ?? 'No',
$row['bro_payable_by'] ?? 'No',
$na($row['salse_manager_name'] ?? null),
$na($row['service_manager_name'] ?? null),
$na($row['service_branch'] ?? null),
$fmtDate($row['rollover_date'] ?? null),
$na($row['policy_holder_name'] ?? null),
$row['same_as_proposer'] ?? 'No',
$na($row['follower_policy_no'] ?? null),
$fmtNum($row['co_share_per'] ?? 0),
$fmtNum($row['non_comm_per_amt'] ?? 0),
$fmtNum($row['bp_igst'] ?? 0),
$fmtNum($row['bp_sgst'] ?? 0),
$fmtNum($row['bp_cgst'] ?? 0),
$fmtNum($row['stamp_duty'] ?? 0),
$fmtNum($row['standerd_bp_per'] ?? 0),
$fmtNum($row['standerd_tp_per'] ?? 0),
$fmtNum($row['actual_bp_amt'] ?? 0),
$fmtNum($row['actual_tp_amt'] ?? 0),
$fmtNum($row['actual_bp_per'] ?? 0),
$fmtNum($row['actual_tp_per'] ?? 0),
$fmtNum($row['actual_tep_brokerage_amt'] ?? 0),
$fmtNum($row['actual_tp_brokerage_amt'] ?? 0),
$na($row['cd_ac_no'] ?? null),
];
$rowData = ['DT_RowAttr' => ['data-id' => $row['pt_id'] ?? '']];
foreach ($cells as $index => $cell) {
$rowData[$index] = $cell;
}
return $rowData;
}
public function reportVarience()
{
$data['tab_name'] = 'Variance Report';
$data['page_name'] = 'Variance Report';
$data['issuer'] = [1 => 'JIBS', 2 => 'Nhance'];
$data['insurer'] = $this->insurerModel->where('is_active', 1)->findAll();
$data['policy_types'] = $this->policyTypeModel->where('is_active', 1)->findAll();
$data['clients'] = $this->clientModel->where('is_active', 1)->findAll();
$data['date_type'] = [
'policy_issue_date' => 'Policy Issue Date',
'policy_start_date' => 'Policy Start Date',
'policy_end_date' => 'Policy End Date',
'data_received_date' => 'Data Received Date',
'closure_date' => 'Closure Date',
];
//filter datas
$start_date = $this->request->getGet('start_date');
$end_date = $this->request->getGet('end_date');
$client_id = $this->request->getGet('client_id');
$insurer_id = $this->request->getGet('insurer_id');
$policy_type_id = $this->request->getGet('policy_type_id');
$date_type = $this->request->getGet('date_type');
$issuer = $this->request->getGet('issuer');
$client_branch_id = $this->request->getGet('client_branch_id');
$insurer_branch_id = $this->request->getGet('insurer_branch_id');
$client_policy_id = $this->request->getGet('client_policy_id');
$start_date = (!isset($start_date) || $start_date === '' || $start_date === null) ? 0 : $start_date;
$end_date = (!isset($end_date) || $end_date === '' || $end_date === null) ? 0 : $end_date;
$client_id = (!isset($client_id) || $client_id === '' || $client_id === null) ? 0 : $client_id;
$insurer_id = (!isset($insurer_id) || $insurer_id === '' || $insurer_id === null) ? 0 : $insurer_id;
$policy_type_id = (!isset($policy_type_id) || $policy_type_id === '' || $policy_type_id === null) ? 0 : $policy_type_id;
$date_type = (!isset($date_type) || $date_type === '' || $date_type === null) ? 0 : $date_type;
$issuer = (!isset($issuer) || $issuer === '' || $issuer === null) ? 0 : $issuer;
$client_branch_id = (!isset($client_branch_id) || $client_branch_id === '' || $client_branch_id === null) ? 0 : $client_branch_id;
$insurer_branch_id = (!isset($insurer_branch_id) || $insurer_branch_id === '' || $insurer_branch_id === null) ? 0 : $insurer_branch_id;
$client_policy_id = (!isset($client_policy_id) || $client_policy_id === '' || $client_policy_id === null) ? 0 : $client_policy_id;
$data['varience_list'] = $this->policyTransactionModel->getVarienceReportLIst($start_date, $end_date, $client_id, $insurer_id, $policy_type_id, $date_type, $issuer, $client_branch_id, $insurer_branch_id, $client_policy_id);
// !dd($data['varience_list']);
$this->loadLayout('variance_report_list', $data);
}
public function reportBusinessList()
{
$data['tab_name'] = 'Business Report';
$data['page_name'] = 'Business Report';
$data['issuer'] = [1 => 'JIBS', 2 => 'Nhance'];
$data['insurer'] = $this->insurerModel->where('is_active', 1)->findAll();
$data['policy_types'] = $this->policyTypeModel->where('is_active', 1)->findAll();
$data['clients'] = $this->clientModel->where('is_active', 1)->findAll();
$data['date_type'] = [
'policy_issue_date' => 'Policy Issue Date',
'policy_start_date' => 'Policy Start Date',
'policy_end_date' => 'Policy End Date',
'data_received_date' => 'Data Received Date',
'closure_date' => 'Closure Date',
];
//filter datas
$start_date = $this->request->getGet('start_date');
$end_date = $this->request->getGet('end_date');
$client_id = $this->request->getGet('client_id');
$insurer_id = $this->request->getGet('insurer_id');
$policy_type_id = $this->request->getGet('policy_type_id');
$date_type = $this->request->getGet('date_type');
$issuer = $this->request->getGet('issuer');
$start_date = (!isset($start_date) || $start_date === '' || $start_date === null) ? 0 : $start_date;
$end_date = (!isset($end_date) || $end_date === '' || $end_date === null) ? 0 : $end_date;
$client_id = (!isset($client_id) || $client_id === '' || $client_id === null) ? 0 : $client_id;
$insurer_id = (!isset($insurer_id) || $insurer_id === '' || $insurer_id === null) ? 0 : $insurer_id;
$policy_type_id = (!isset($policy_type_id) || $policy_type_id === '' || $policy_type_id === null) ? 0 : $policy_type_id;
$date_type = (!isset($date_type) || $date_type === '' || $date_type === null) ? 0 : $date_type;
$issuer = (!isset($issuer) || $issuer === '' || $issuer === null) ? 0 : $issuer;
$data['business_list'] = $this->policyTransactionModel->getBusinessReportList($start_date, $end_date, $client_id, $insurer_id, $policy_type_id, $date_type, $issuer);
$this->loadLayout('business_team_list', $data);
}
public function reportFinanceList()
{
$data['tab_name'] = 'Finance Report';
$data['page_name'] = 'Finance Report';
$data['issuer'] = [1 => 'JIBS', 2 => 'Nhance'];
$data['insurer'] = $this->insurerModel->where('is_active', 1)->findAll();
$data['policy_types'] = $this->policyTypeModel->where('is_active', 1)->findAll();
$data['clients'] = $this->clientModel->where('is_active', 1)->findAll();
$data['date_type'] = [
'policy_issue_date' => 'Policy Issue Date',
'policy_start_date' => 'Policy Start Date',
'policy_end_date' => 'Policy End Date',
'data_received_date' => 'Data Received Date',
'closure_date' => 'Closure Date',
];
//filter datas
$start_date = $this->request->getGet('start_date');
$end_date = $this->request->getGet('end_date');
$client_id = $this->request->getGet('client_id');
$insurer_id = $this->request->getGet('insurer_id');
$policy_type_id = $this->request->getGet('policy_type_id');
$date_type = $this->request->getGet('date_type');
$issuer = $this->request->getGet('issuer');
$start_date = (!isset($start_date) || $start_date === '' || $start_date === null) ? 0 : $start_date;
$end_date = (!isset($end_date) || $end_date === '' || $end_date === null) ? 0 : $end_date;
$client_id = (!isset($client_id) || $client_id === '' || $client_id === null) ? 0 : $client_id;
$insurer_id = (!isset($insurer_id) || $insurer_id === '' || $insurer_id === null) ? 0 : $insurer_id;
$policy_type_id = (!isset($policy_type_id) || $policy_type_id === '' || $policy_type_id === null) ? 0 : $policy_type_id;
$date_type = (!isset($date_type) || $date_type === '' || $date_type === null) ? 0 : $date_type;
$issuer = (!isset($issuer) || $issuer === '' || $issuer === null) ? 0 : $issuer;
$data['finance_list'] = $this->policyTransactionModel->getFinanceReportList($start_date, $end_date, $client_id, $insurer_id, $policy_type_id, $date_type, $issuer);
$this->loadLayout('finance_team_list', $data);
}
public function reportOutstanding()
{
$data['tab_name'] = 'Outstanding Report';
$data['page_name'] = 'Outstanding Report';
$data['issuer'] = [1 => 'JIBS', 2 => 'Nhance'];
$data['insurer'] = $this->insurerModel->where('is_active', 1)->findAll();
$data['policy_types'] = $this->policyTypeModel->where('is_active', 1)->findAll();
$data['clients'] = $this->clientModel->where('is_active', 1)->findAll();
$data['date_type'] = [
'policy_issue_date' => 'Policy Issue Date',
'policy_start_date' => 'Policy Start Date',
'policy_end_date' => 'Policy End Date',
'data_received_date' => 'Data Received Date',
'closure_date' => 'Closure Date',
];
//filter datas
$start_date = $this->request->getGet('start_date');
$end_date = $this->request->getGet('end_date');
$client_id = $this->request->getGet('client_id');
$insurer_id = $this->request->getGet('insurer_id');
$insurer_branch_id = $this->request->getGet('insurer_branch_id');
$start_date = (!isset($start_date) || $start_date === '' || $start_date === null) ? 0 : change_date_format($start_date, 'd-m-Y', 'Y-m-01');
$end_date = (!isset($end_date) || $end_date === '' || $end_date === null) ? 0 : change_date_format($end_date, 'd-m-Y', 'Y-m-t');
// dd([$start_date,$end_date]);
$insurer_id = (!isset($insurer_id) || $insurer_id === '' || $insurer_id === null) ? 0 : $insurer_id;
$insurer_branch_id = (!isset($insurer_branch_id) || $insurer_branch_id === '' || $insurer_branch_id === null) ? 0 : $insurer_branch_id;
$data['outstanting_list'] = $this->policyTransactionModel->getOutstandingReportLIst($start_date, $end_date, $insurer_id, $insurer_branch_id);
// dd($this->policyTransactionModel->getLastQuery());
// dd($data);
$this->loadLayout('outstanding_report_list', $data);
}
//---------------------------------------------------------------------------------------------------
//insurer statement list page
public function statementList()
{
// dd($this->updateInsurerStatement(['file_id' => 133])); // for check validateInsurerStatementfunction with hard coded file id always un command
$data['insurers'] = $this->insurerModel->where('is_active',1)->findAll();
$today = date('Y-m-d');
$fromday = $from_date = date('Y-m-d', strtotime('-180 days', strtotime($today)));
// echo $fromday;die();
$data['invoice_status_array'] = $this->invoiceStatus;
$data['insurers'] = $this->insurerBranchModel->getInsurerBranchesWithInsurerNames();
// dd( $data['insurers']);
$data['insurer_statement_list'] = $this->insurerStatements
->select(
'insurer_statements.*,
insurers.name AS insurer_name,
insurers.short_name,
user_profiles.first_name,
insurer_branch.branch_code,
(SELECT SUM(pt_co_share_details.exp_amt)
FROM pt_co_share_details
WHERE pt_co_share_details.is_active = 1
AND pt_co_share_details.statement_id = insurer_statements.id
) AS exp_inv_amt,
(SELECT SUM(inv_payment_details.inv_amt) + SUM(inv_payment_details.tds) + SUM(inv_payment_details.gst)
FROM inv_payment_details
WHERE inv_payment_details.is_active = 1
AND inv_payment_details.statement_id = insurer_statements.id
) AS received_inv_amt'
)
->join('insurers', 'insurer_statements.insurer_id = insurers.id')
->join('insurer_branch', 'insurer_statements.branch_id = insurer_branch.id')
->join('user_profiles', 'insurer_statements.created_by = user_profiles.id')
->where('insurer_statements.is_active', 1)
->where('insurers.is_active', 1)
->where('insurer_branch.is_active', 1)
// ->where('insurer_statements.file_status','success')
->where('date(insurer_statements.created_at) >= ', $from_date)
->where('date(insurer_statements.created_at) <= ', $today)
->orderBy('insurer_statements.id', 'DESC')
->findAll();
// dd( $this->insurerStatements->getLastQuery());
$data['tab_name'] = 'Statement Upload';
$data['page_name'] = 'Statement Upload';
$this->loadLayout('insurer_statement_list', $data);
}
// public function failedStatementList(){
// $today = date('Y-m-d');
// $fromday = $from_date = date('Y-m-d', strtotime('-180 days', strtotime($today)));
// // echo $fromday;die();
// $data['invoice_status_array'] = $this->invoiceStatus;
// $data['insurers'] = $this->insurerBranchModel ->getInsurerBranchesWithInsurerNames();
// // dd( $data['insurers']);
// $data['insurer_statement_list'] = $this->insurerStatements
// ->select('insurer_statements.*,
// insurers.name AS insurer_name,
// insurers.short_name,
// user_profiles.first_name,
// insurer_branch.branch_code,
// (SELECT SUM(pt_co_share_details.exp_amt)
// FROM pt_co_share_details
// WHERE pt_co_share_details.is_active = 1
// AND pt_co_share_details.statement_id = insurer_statements.id
// ) AS exp_inv_amt,
// (SELECT SUM(inv_payment_details.inv_amt) + SUM(inv_payment_details.tds) + SUM(inv_payment_details.gst)
// FROM inv_payment_details
// WHERE inv_payment_details.is_active = 1
// AND inv_payment_details.statement_id = insurer_statements.id
// ) AS received_inv_amt'
// )
// ->join('insurers', 'insurer_statements.insurer_id = insurers.id')
// ->join('insurer_branch', 'insurer_statements.branch_id = insurer_branch.id')
// ->join('user_profiles', 'insurer_statements.created_by = user_profiles.id')
// ->where('insurer_statements.is_active', 1)
// ->where('insurer_statements.file_status','failed')
// ->where('date(insurer_statements.created_at) >= ', $from_date)
// ->where('date(insurer_statements.created_at) <= ', $today)
// ->orderBy('insurer_statements.id', 'DESC')
// ->findAll();
// if($data['insurer_statement_list']){
// return $this->respond(['status' => true, 'code' => 200,'data'=>$data ], 200);
// }else{
// return $this->respond(['status'=>false,'message'=>'Data Not Fount'],404);
// }
// }
public function uploadInsurerStatement()
{
//validate uploaded file
$filename = '';
$validated = $this->validate([
'statement' => [
'uploaded[statement]',
'mime_in[statement,application/vnd.ms-excel,application/vnd,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.oasis.opendocument.spreadsheet]',
'max_size[statement,16384]',
],
]);
// $this->createStatementFolder();
if ($validated) {
$avatar = $this->request->getFile('statement');
if (!$avatar) {
$this->myLogger->logme("error", 'Statement File not found');
return $this->respond(['dataStatus' => false, 'code' => 400, 'message' => 'File not found'], 400);
}
$filename = storage_file_Upload($avatar, WRITEPATH . 'uploads/statements/', UPLOAD_EXT_EXCEL);
if ($filename !== '') {
$this->myLogger->logme("error", 'Statement File moved successful');
} else {
$this->myLogger->logme("error", 'Statement File move failed');
return $this->respond(['dataStatus' => false, 'code' => 500, 'message' => 'File move failed'], 500);
}
} else {
$this->myLogger->logme("error", 'Statement Upload failed Invalid file');
return $this->respond(['dataStatus' => false, 'code' => 404, 'message' => 'Invalid file'], 404);
}
//process post variable entry in file table
$loggedInUserID = get_session_userid();
// dd($loggedInUserID);
// $loggedInUserID = 8;
$insurer = $this->request->getPost('insurer');
$insurer_id = explode('-', $insurer)[0];
$branch_id = explode('-', $insurer)[1];
// print_r($insurer_id);
// print_r($branch_id);
// die();
$month = $this->request->getPost('statement_month');
$month = $month . '-01';
// print_r($month);die;
$month = change_date_format($month, 'Y-M-d', 'Y-m-d');
$stmt_sno = $this->request->getPost('statement_no');
// print_r($month);die;
$file_id = $this->insurerStatements->insert(['insurer_id' => $insurer_id, 'branch_id' => $branch_id, 'file_name' => $filename, 'month' => $month, 'created_by' => $loggedInUserID, 'stmt_sno' => $stmt_sno]); //here field policy_id have client_policy_id and not policy id from policy master
$this->myLogger->logme("error", '{file_id} statement uploaded success', ['file_id' => $file_id]);
//validate file
$validation_result = $this->validateInsurerStatement(['file_id' => $file_id]);
//update file content to DB
if ($validation_result['status']) {
$this->updateInsurerStatement(['file_id' => $file_id]);
}
if (!isset($file_id) || !$validation_result['status']) {
return $this->respond(['dataStatus' => false, 'code' => 404, 'message' => 'file not uploaded', 'error_data' => $validation_result['error_data'], 'error_code' => $validation_result['error_code']], 200);
}
if (isset($file_id) || $validation_result['status']) {
$this->insurerStatements->where('id', $file_id)->set(['invoice_status' => 'pending'])->update();
}
return $this->respond(['dataStatus' => true, 'code' => 200, 'data' => 'file upload success'], 200);
}
public function createStatementFolder()
{
$folderPath = WRITEPATH . 'uploads/statements/';
// Check if the folder doesn't exist
if (!file_exists($folderPath)) {
// Create the folder
if (mkdir($folderPath, 0777, true)) {
$this->myLogger->logme('error', 'statement upload folder created successfully');
// Set permissions to a+rwx (read, write, execute for all)
chmod($folderPath, 0777);
$this->myLogger->logme('error', 'Permissions set to a+rwx.');
} else {
// echo "Failed to create folder.";
$this->myLogger->logme('error', 'Failed to create statement upload folder.');
}
} else {
$this->myLogger->logme('error', 'upload folder exists.');
}
}
public function validateInsurerStatementOld($params)
{
helper('excel_util_helper');
//get file info
$file_id = $params['file_id'];
$file = $this->insurerStatements->find((int)$file_id);
// dd($file);
$date = new \DateTime($file['month']);
$month = $date->format('m');
$year = $date->format('Y');
$error_data = ['error_code' => '', 'error_data' => []];
$status = 'success';
$ret_status = true;
// dd($month.'-'.$year);
$return = [];
if (!isset($file)) {
//file not found in DB
return array('status' => false, 'msg' => 'statement file not found in DB');
}
$file_name_with_path = storage_ensure_local_file(WRITEPATH . 'uploads/statements', $file['file_name']);
//check physical file
if (!file_exists($file_name_with_path)) {
//file not found update status and reason
$message = "Physcial file not found";
// echo $message;
$this->myLogger->logme('error', ($message . ' for statement file id ' . $file_id));
$this->insurerStatements->where('id', $file_id)->set(['file_status' => 'failed', 'reason' => json_encode(['error_code' => 0, 'error_data' => $message])])->update();
return array('status' => false, 'error_code' => 0); //0 - Physcial file not found
}
//get excel data to php array
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($file_name_with_path);
$sheet = $spreadsheet->getActiveSheet();
$highestRowAndColumn = $sheet->getHighestRowAndColumn();
// dd($highestRowAndColumn);
$excel_data = $sheet->rangeToArray('A1:' . $highestRowAndColumn['column'] . $highestRowAndColumn['row']);
unset($excel_data[0]);
$excel_data = ExcelSanitizeHelper::sanitizeArrayData($excel_data);
// Kint::dump($excel_data); // die();
//get no of line items and update in DB
$line_items = 0;
// get uploaded month transactions data
$source_data = $this->PTCOShareDetailsModel->getNonReconcileredPolicyTransactions(insurer_id: $file['insurer_id'], insurer_branch_id: $file['branch_id'], month: $file['month']);
// var_dump($source_data);die();
// Kint::dump($source_data);die();
// check policy no,insurer and etc in DB for this month
// if all good return true, otherwise return false with messssage
foreach ($excel_data as $excel_key => $excel_row) {
$is_row_empty = check_row_is_empty_or_null($excel_row);
if (!$is_row_empty) {
// $excel_row = ExcelSanitizeHelper::sanitizeArrayData($excel_row);
$is_source_found = 0;
// Kint::dump($excel_key,$excel_row[1],$excel_row[2]);
// $policy_start_date = preg_replace('/^\p{Z}+|\p{Z}+$/u', '', $excel_row[4]); //policy_start_date from excel
// $policy_end_date = preg_replace('/^\p{Z}+|\p{Z}+$/u', '', $excel_row[5]); //policy_end_date from excel
$policy_no = preg_replace('/^\p{Z}+|\p{Z}+$/u', '', $excel_row[1]); //policy_end_date from excel
$policy_no = preg_replace( '/[\x{200B}\x{200C}\x{200D}\x{FEFF}\x{00A0}\x{200E}\x{200F}\x{202A}-\x{202E}]/u', '', $excel_row[1]); //policy_end_date from excel
// $client_name = preg_replace('/^\p{Z}+|\p{Z}+$/u', '', $excel_row[3]); //clientname from excel
$endorsement_no = preg_replace('/^\p{Z}+|\p{Z}+$/u', '', $excel_row[2]??''); //policy_end_date from excel
$endorsement_no = preg_replace( '/[\x{200B}\x{200C}\x{200D}\x{FEFF}\x{00A0}\x{200E}\x{200F}\x{202A}-\x{202E}]/u', '', $excel_row[2]??''); //policy_end_date from excel
// Kint::dump($excel_key,$policy_no,$endorsement_no,$policy_start_date,$policy_end_date);//die();
foreach ($source_data as $source_key => $source_row) {
$source_endorsement_no = $source_row['endorsement_no'] !== null ? $source_row['endorsement_no'] : null;
// Kint::dump($source_row, $source_endorsement_no, $policy_no, $endorsement_no);
// if (($policy_no == $source_row['policy_no']) && $endorsement_no == $source_endorsement_no && change_date_format($policy_start_date, 'd-m-Y', 'Y-m-d') == $source_row['policy_start_date'] && change_date_format($policy_end_date, 'd-m-Y', 'Y-m-d') == $source_row['policy_end_date'] && $client_name == $source_row['client_name'])
// {
// $is_source_found = 1;
// $line_items = $line_items + 1;
// unset($source_data[$source_key]);
// continue 2;
// }
if (($policy_no == $source_row['policy_no']) && $endorsement_no == $source_endorsement_no)
{
$is_source_found = 1;
$line_items = $line_items + 1;
unset($source_data[$source_key]);
continue 2;
}
}
if ($is_source_found == 0) {
// echo $excel_key.'-'.$excel_row[1] . '- not found<br>';
$error_data['error_code'] = 1; //match not found
// $error_data['error_data'] = ($error_data['error_data'] ?? []);
$error_data['error_data'] = array_merge($error_data['error_data'], [$excel_row[0]]); //match not found
}
}
}
// dd($error_data);
if ($error_data['error_code']) {
$status = 'failed';
$ret_status = false;
}
//update in DB
$this->insurerStatements->where('id', $file_id)->set(['line_items' => $line_items, 'file_status' => $status, 'reason' => json_encode($error_data)])->update();
return array('status' => $ret_status, 'error_code' => $error_data['error_code'], 'error_data' => $error_data['error_data']);
}
public function validateInsurerStatementOLD1($params)
{
helper('excel_util_helper');
$file_id = $params['file_id'];
try {
//get file info
$file = $this->insurerStatements->find((int)$file_id);
// dd($file);
$date = new \DateTime($file['month']);
$month = $date->format('m');
$year = $date->format('Y');
$error_data = ['error_code' => '', 'error_data' => []];
$status = 'success';
$ret_status = true;
$return = [];
if (!isset($file)) {
//file not found in DB
$this->insurerStatements->where('id', $file_id)->set(['file_status' => 'failed', 'reason' => json_encode(['error_code' => 0, 'error_data' => 'statement file not found in DB'])])->update();
return array('status' => false, 'msg' => 'statement file not found in DB');
}
$file_name_with_path = storage_ensure_local_file(WRITEPATH . 'uploads/statements', $file['file_name']);
//check physical file
if (!file_exists($file_name_with_path)) {
//file not found update status and reason
$message = "Physcial file not found";
// echo $message;
$this->myLogger->logme('error', ($message . ' for statement file id ' . $file_id));
$this->insurerStatements->where('id', $file_id)->set(['file_status' => 'failed', 'reason' => json_encode(['error_code' => 0, 'error_data' => $message])])->update();
return array('status' => false, 'error_code' => 0, 'error_data' => $message); //0 - Physcial file not found
}
//get excel data to php array
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($file_name_with_path);
$sheet = $spreadsheet->getActiveSheet();
$highestRow = $sheet->getHighestRow();
$highestColumn = $sheet->getHighestColumn();
$excel_data = $sheet->rangeToArray('A1:' . $highestColumn . $highestRow);
unset($excel_data[0]);
$excel_data = ExcelSanitizeHelper::sanitizeArrayData($excel_data);
// dd($excel_data);
//get no of line items and update in DB
$line_items = 0;
// get uploaded month transactions data
$source_data = $this->PTCOShareDetailsModel->getNonReconcileredPolicyTransactions(insurer_id: $file['insurer_id'], insurer_branch_id: $file['branch_id'], month: $file['month']);
// dd($source_data);
// check policy no,insurer and etc in DB for this month
// if all good return true, otherwise return false with messssage
$matched_entry = [];
$error_messages = []; // row-wise error storage
foreach ($excel_data as $excel_key => $excel_row) {
$row_number = $excel_key;
$is_row_empty = check_row_is_empty_or_null($excel_row);
$policy_source_found = 0;
$endorsement_source_found = 0;
$dublicate_found = 0;
if (!$is_row_empty) {
$policy_no = preg_replace('/^\p{Z}+|\p{Z}+$/u', '', $excel_row[1]); //policy_number from excel
$policy_no = preg_replace('/[\x{200B}\x{200C}\x{200D}\x{FEFF}\x{00A0}\x{200E}\x{200F}\x{202A}-\x{202E}]/u', '', $excel_row[1]); //policy_number from excel
$endorsement_no = preg_replace('/^\p{Z}+|\p{Z}+$/u', '', $excel_row[2] ?? ''); //endorsement number from excel
$endorsement_no = preg_replace('/[\x{200B}\x{200C}\x{200D}\x{FEFF}\x{00A0}\x{200E}\x{200F}\x{202A}-\x{202E}]/u', '', $excel_row[2] ?? ''); //endorsement number from excel
foreach ($source_data as $source_key => $source_row) {
$source_endorsement_no = $source_row['endorsement_no'] !== null ? $source_row['endorsement_no'] : null;
if (($policy_no == $source_row['policy_no']) ){
$policy_source_found = 1;
}
if( $endorsement_no == $source_endorsement_no) {
$endorsement_source_found = 1;
}
// Duplicate check
if (isset($matched_entry[$policy_no . '|' . $endorsement_no])) {
$dublicate_found = 1;
continue 2;
}
if (($policy_no == $source_row['policy_no']) && $endorsement_no == $source_endorsement_no) {
$line_items = $line_items + 1;
$matched_entry[] = $policy_no . '|' . $endorsement_no;
unset($source_data[$source_key]);
continue 2;
}
}
// Policy number mismatch
if ($policy_source_found == 0) {
$error_messages[$row_number]['policy_no_mismatch'] =
"Policy number <strong>({$policy_no}) </strong> not in NHance.";
}
// Endorsement number mismatch
if (!empty($endorsement_no) && $endorsement_source_found == 0) {
$error_messages[$row_number]['endorsement_no_mismatch'] =
"Endorsement number <strong>({$endorsement_no})</strong> not in NHance.";
}
// Duplicate check
if ($dublicate_found == 1) {
$error_messages[$row_number]['duplicate'] =
"Duplicate entry found. This policy and endorsement <strong>({$policy_no} '|' {$endorsement_no})</strong> combination has already been matched.";
}
}
}
// print_rr($error_messages);die;
if (!empty($error_messages)) {
$error_data['error_code'] = 2;
$error_data['error_data'] = $error_messages;
$status = 'failed';
$ret_status = false;
}
//update in DB
$this->insurerStatements->where('id', $file_id)->set(['line_items' => $line_items, 'file_status' => $status, 'reason' => json_encode($error_data)])->update();
return array('status' => $ret_status, 'error_code' => $error_data['error_code'], 'error_data' => $error_data['error_data']);
} catch (\Throwable $th) {
$errorData = [
'message' => $th->getMessage(),
'file' => $th->getFile(),
'line' => $th->getLine(),
'code' => $th->getCode(),
'trace' => $th->getTraceAsString(),
'trace_array' => $th->getTrace(), // full array version (optional)
'function' => $th->getTrace()[0]['function'] ?? null,
'class' => $th->getTrace()[0]['class'] ?? null,
];
$this->myLogger->logme("error", "POLICY-TRANSACTION-CONTROLLER - validateInsurerStatement: Exception: " . json_encode($errorData ?? []));
$this->insurerStatements->where('id', $file_id)->set(['line_items' => 0, 'file_status' => 'failed', 'reason' => json_encode($errorData)])->update();
return array('status' => false, 'error_code' => [], 'error_data' => $errorData);
}
}
public function updateInsurerStatementOLD($params)
{
helper('excel_util_helper');
//get file info
$file_id = $params['file_id'];
$file = $this->insurerStatements->find((int)$file_id);
// dd($file);
$date = new \DateTime($file['month']);
$month = $date->format('m');
$year = $date->format('Y');
$error_data = ['error_code' => '', 'error_data' => []];
$status = 'success';
$ret_status = true;
// dd($month.'-'.$year);
$return = [];
if (!isset($file)) {
//file not found in DB
return array('status' => false, 'msg' => 'statement file not found in DB');
}
$file_name_with_path = storage_ensure_local_file(WRITEPATH . 'uploads/statements', $file['file_name']);
//check physical file
if (!file_exists($file_name_with_path)) {
//file not found update status and reason
$message = "Physcial file not found";
// echo $message;
$this->myLogger->logme('error', ($message . ' for statement file id ' . $file_id));
$this->insurerStatements->where('id', $file_id)->set(['file_status' => 'failed', 'reason' => json_encode(['error_code' => 0, 'error_data' => $message])])->update();
return array('status' => false, 'error_code' => 0); //0 - Physcial file not found
}
//get excel data to php array
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($file_name_with_path);
$sheet = $spreadsheet->getActiveSheet();
$highestRowAndColumn = $sheet->getHighestRowAndColumn();
// dd($highestRowAndColumn);
$excel_data = $sheet->rangeToArray('A1:' . $highestRowAndColumn['column'] . $highestRowAndColumn['row']);
unset($excel_data[0]);
$excel_data = ExcelSanitizeHelper::sanitizeArrayData($excel_data);
// dd($excel_data);
//get no of line items and update in DB
$line_items = count($excel_data);
// get uploaded month transactions data
$source_data = $this->PTCOShareDetailsModel->getNonReconcileredPolicyTransactions(insurer_id: $file['insurer_id'], insurer_branch_id: $file['branch_id'], month: $file['month']);
// Kint::dump($source_data);//die;
// Kint::dump($excel_data);
// die;
// check policy no,insurer and etc in DB for this month
// if all good return true, otherwise return false with messssage
$data_to_update = [];
try{
foreach ($excel_data as $excel_key => $excel_row) {
$is_row_empty = check_row_is_empty_or_null($excel_row);
if (!$is_row_empty) {
$is_source_found = 0;
// $policy_start_date = preg_replace('/^\p{Z}+|\p{Z}+$/u', '', $excel_row[4]); //policy_start_date from excel
// $policy_end_date = preg_replace('/^\p{Z}+|\p{Z}+$/u', '', $excel_row[5]); //policy_end_date from excel
$policy_no = preg_replace('/^\p{Z}+|\p{Z}+$/u', '', $excel_row[1]); //policy_end_date from excel
$policy_no = preg_replace('/[\x{200C}\x{200B}]/u', '', $excel_row[1]); //
// $client_name = preg_replace('/^\p{Z}+|\p{Z}+$/u', '', $excel_row[3]); //clientname from excel
$endorsement_no = preg_replace('/^\p{Z}+|\p{Z}+$/u', '', $excel_row[2]); //policy_end_date from excel
foreach ($source_data as $source_key => $source_row) {
// Kint::dump(change_date_format($excel_row[3],'d-m-Y','Y-m-d'));
$source_endorsement_no = $source_row['endorsement_no'] !== null ? $source_row['endorsement_no'] : null;
// if (($policy_no == $source_row['policy_no']) && $endorsement_no == $source_endorsement_no && change_date_format($policy_start_date, 'd-m-Y', 'Y-m-d') == $source_row['policy_start_date'] && change_date_format($policy_end_date, 'd-m-Y', 'Y-m-d') == $source_row['policy_end_date'] && $client_name == $source_row['client_name']) {
if (($policy_no == $source_row['policy_no']) && $endorsement_no == $source_endorsement_no) {
$is_source_found = 1;
//calculate percentage first
$total_amt = 0;
// $actual_bp_per = trim($excel_row[9]); //commented becoz this filed removed tfrom excel file
$actual_bp_per = 0; //set default value 0 for maintaining existing code flow
$actual_bp_brokerage = (int) trim($excel_row[5]);
$actual_bp_amt = (int) trim($excel_row[3]);
if (($actual_bp_brokerage && $actual_bp_brokerage != 0 && $actual_bp_brokerage != "")) {
$total_amt += $actual_bp_brokerage;
//percentage reverse calculation
if (($actual_bp_per == 0 || $actual_bp_per == 0) && !empty($actual_bp_amt)) {
$actual_bp_per = (int) round(($actual_bp_brokerage / $actual_bp_amt) * 100, 2);
}
} else {
$actual_bp_brokerage = $actual_bp_amt * ($actual_bp_per / 100);
$total_amt += $actual_bp_brokerage;
}
// $actual_tp_per = trim($excel_row[10]);//commented becoz this filed removed tfrom excel file
$actual_tp_per = 0;//set default value 0 for maintaining existing code flow
$actual_tp_brokerage = (int) trim($excel_row[6]);
$actual_tp_amt = (int) trim($excel_row[4]);
if ($actual_tp_brokerage && $actual_tp_brokerage != 0 && $actual_tp_brokerage != "") {
$total_amt += $actual_tp_brokerage;
//percentage reverse calculation
if (($actual_tp_per == 0 || $actual_tp_per == "") && !empty($actual_tp_amt)) {
$actual_tp_per = (int) round(($actual_tp_brokerage / $actual_tp_amt) * 100, 2);
}
} else {
$actual_tp_brokerage = $actual_tp_amt * ($actual_tp_per / 100);
$total_amt += $actual_tp_brokerage;
}
// $actual_tep_per = trim($excel_row[11]);
// $actual_tep_brokerage = trim($excel_row[14]);
// $actual_tep_amt = trim($excel_row[8]);
$actual_tep_per = 0;
$actual_tep_brokerage = 0;
$actual_tep_amt = 0;
if ($actual_tep_brokerage && $actual_tep_brokerage != 0 && $actual_tep_brokerage != "") {
$total_amt += $actual_tep_brokerage;
//percentage reverse calculation
if (($actual_tep_per == 0 || $actual_tep_per == "") && !empty($actual_tep_amt)) {
$actual_tep_per = ($actual_tep_brokerage / $actual_tep_amt) * 100;
}
} else {
$actual_tep_brokerage = $actual_tep_amt * ($actual_tep_per / 100);
$total_amt += $actual_tep_brokerage;
}
//find variance
$variance_amt = $source_row['exp_amt'] - $total_amt;
$data_to_update[] = ['co_share_id' => $source_row['id'], 'actual_bp_amt' => $actual_bp_amt, 'actual_tp_amt' => $actual_tp_amt, 'actual_tep_amt' => $actual_tep_amt, 'actual_bp_per' => $actual_bp_per, 'actual_tp_per' => $actual_tp_per, 'actual_tep_per' => $actual_tep_per, 'variance' => $variance_amt, 'actual_tep_brokerage_amt' => $actual_tep_brokerage, 'actual_tp_brokerage_amt' => $actual_tp_brokerage, 'actual_bp_brokerage_amt' => $actual_bp_brokerage, 'reward' => trim($excel_row[7]), 'statement_id' => $file_id];
unset($source_data[$source_key]);
continue 2;
}
}
}
}
}catch (\Throwable $th) {
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - updateInsurerStatement: Exception: " . $th->getMessage() . " --- Line: " . $th->getLine() . " --- Trace: " . $th->getTraceAsString());
$errorData = [
'message' => $th->getMessage(),
'file' => $th->getFile(),
'line' => $th->getLine(),
'code' => $th->getCode(),
'trace' => $th->getTraceAsString(),
'trace_array' => $th->getTrace(), // full array version (optional)
'function' => $th->getTrace()[0]['function'] ?? null,
'class' => $th->getTrace()[0]['class'] ?? null,
];
return ['status' => 'failed', 'code' => 500, 'message' => $th->getMessage(), 'error_data' => $errorData];
}
// dd($data_to_update);
$this->coShareStmtDetailsModel->insertBatch($data_to_update, 'id');
// dd($data_to_update);
// if($error_data['error_code'])
// {
// $status = 'failed';
// $ret_status = false;
// }
//update in DB
$this->insurerStatements->where('id', $file_id)->set(['file_status' => $status, 'reason' => json_encode($error_data), 'invoice_status' => 'pending'])->update();
return array('status' => $ret_status, 'error_code' => $error_data['error_code'], 'error_data' => $error_data['error_data']);
}
public function validateInsurerStatement($params)
{
/*
* Changes made: 12-06-2024
* - Added safe file_id handling and DB file record validation before using file details.
* - Fixed physical file missing response and error message.
* - Skips empty Excel rows and collects unique policy numbers from the uploaded statement.
* - Fetches NHance source records only for those uploaded policy numbers.
* - Sanitizes policy and endorsement numbers before comparison to avoid hidden-space mismatch.
* - Validates each row by policy number + endorsement number combination.
* - Detects duplicate policy + endorsement rows and returns row-wise validation errors.
*/
helper('excel_util_helper');
$file_id = $params['file_id'] ?? 0;
try {
$error_data = ['error_code' => '', 'error_data' => []];
$status = 'success';
$ret_status = true;
//get file info
$file = $this->insurerStatements->find((int)$file_id);
// dd($file);
if (empty($file)) {
//file not found in DB
$this->insurerStatements->where('id', $file_id)->set(['file_status' => 'failed', 'reason' => json_encode(['error_code' => 0, 'error_data' => 'statement file not found in DB'])])->update();
return array('status' => false, 'error_code' => 0, 'error_data' => 'statement file not found in DB');
}
$file_name_with_path = storage_ensure_local_file(WRITEPATH . 'uploads/statements', $file['file_name']);
//check physical file
if (!file_exists($file_name_with_path)) {
//file not found update status and reason
$message = "Physical file not found";
// echo $message;
$this->myLogger->logme('error', ($message . ' for statement file id ' . $file_id));
$this->insurerStatements->where('id', $file_id)->set(['file_status' => 'failed', 'reason' => json_encode(['error_code' => 0, 'error_data' => $message])])->update();
return array('status' => false, 'error_code' => 0, 'error_data' => $message); //0 - Physcial file not found
}
//get excel data to php array
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($file_name_with_path);
$sheet = $spreadsheet->getActiveSheet();
$highestRow = $sheet->getHighestRow();
$highestColumn = $sheet->getHighestColumn();
$excel_data = $sheet->rangeToArray('A1:' . $highestColumn . $highestRow);
unset($excel_data[0]);
$excel_data = ExcelSanitizeHelper::sanitizeArrayData($excel_data);
// dd($excel_data);
//get no of line items and update in DB
$line_items = 0;
$policyNos = [];
foreach ($excel_data as $row) {
if (check_row_is_empty_or_null($row)) {
continue;
}
// row[1] => second column (B column)
$policyNo = $this->sanitizeStatementLookupValue($row[1] ?? '');
if ($policyNo !== '') {
$policyNos[] = $policyNo;
}
}
$policyNos = array_values(array_unique($policyNos));
// get uploaded month transactions data
// $source_data = $this->PTCOShareDetailsModel->getNonReconcileredPolicyTransactions(insurer_id: $file['insurer_id'], insurer_branch_id: $file['branch_id'], month: $file['month']);
$source_data = !empty($policyNos) ? $this->PTCOShareDetailsModel->getNonReconcileredPolicyTransactionByPolicyAndEndorsement(insurer_id: $file['insurer_id'], insurer_branch_id: $file['branch_id'], policy_no: $policyNos) : [];
// dd($source_data);
$source_lookup = [];
$source_policy_lookup = [];
$source_endorsement_lookup = [];
foreach ($source_data as $source_row) {
$source_policy_no = $this->sanitizeStatementLookupValue($source_row['policy_no'] ?? '');
$source_endorsement_no = $this->sanitizeStatementLookupValue($source_row['endorsement_no'] ?? '');
$source_entry_key = $source_policy_no . '|' . $source_endorsement_no;
$source_lookup[$source_entry_key] = true;
$source_policy_lookup[$source_policy_no] = true;
$source_endorsement_lookup[$source_policy_no][$source_endorsement_no] = true;
}
// check policy no,insurer and etc in DB for this month
// if all good return true, otherwise return false with messssage
$matched_entry = [];
$error_messages = []; // row-wise error storage
foreach ($excel_data as $excel_key => $excel_row) {
$row_number = $excel_key;
$is_row_empty = check_row_is_empty_or_null($excel_row);
$policy_source_found = 0;
$endorsement_source_found = 0;
$duplicate_found = 0;
if (!$is_row_empty) {
$policy_no = $this->sanitizeStatementLookupValue($excel_row[1] ?? ''); //policy_number from excel
$endorsement_no = $this->sanitizeStatementLookupValue($excel_row[2] ?? ''); //endorsement number from excel
$entry_key = $policy_no . '|' . $endorsement_no;
if (isset($matched_entry[$entry_key])) {
$duplicate_found = 1;
} elseif (isset($source_lookup[$entry_key])) {
$line_items = $line_items + 1;
$matched_entry[$entry_key] = true;
continue;
}
$policy_source_found = isset($source_policy_lookup[$policy_no]) ? 1 : 0;
$endorsement_source_found = isset($source_endorsement_lookup[$policy_no][$endorsement_no]) ? 1 : 0;
// Policy number mismatch
if ($policy_source_found == 0) {
$error_messages[$row_number]['policy_no_mismatch'] =
"Policy number <strong>({$policy_no}) </strong> not in NHance.";
}
// Endorsement number mismatch
if ($policy_source_found == 1 && $endorsement_source_found == 0) {
$error_messages[$row_number]['endorsement_no_mismatch'] =
"Endorsement number <strong>({$endorsement_no})</strong> not in NHance for policy <strong>({$policy_no})</strong>.";
}
// Duplicate check
if ($duplicate_found == 1) {
$error_messages[$row_number]['duplicate'] =
"Duplicate entry found. This policy and endorsement <strong>({$policy_no} | {$endorsement_no})</strong> combination has already been matched.";
}
}
}
// print_rr($error_messages);die;
if (!empty($error_messages)) {
$error_data['error_code'] = 2;
$error_data['error_data'] = $error_messages;
$status = 'failed';
$ret_status = false;
}
//update in DB
$this->insurerStatements->where('id', $file_id)->set(['line_items' => $line_items, 'file_status' => $status, 'reason' => json_encode($error_data)])->update();
return array('status' => $ret_status, 'error_code' => $error_data['error_code'], 'error_data' => $error_data['error_data']);
} catch (\Throwable $th) {
$errorData = [
'message' => $th->getMessage(),
'file' => $th->getFile(),
'line' => $th->getLine(),
'code' => $th->getCode(),
'trace' => $th->getTraceAsString(),
'trace_array' => $th->getTrace(), // full array version (optional)
'function' => $th->getTrace()[0]['function'] ?? null,
'class' => $th->getTrace()[0]['class'] ?? null,
];
$this->myLogger->logme("error", "POLICY-TRANSACTION-CONTROLLER - validateInsurerStatement: Exception: " . json_encode($errorData ?? []));
$this->insurerStatements->where('id', $file_id)->set(['line_items' => 0, 'file_status' => 'failed', 'reason' => json_encode($errorData)])->update();
return array('status' => false, 'error_code' => [], 'error_data' => $errorData);
}
}
private function sanitizeStatementLookupValue($value): string
{
$value = trim((string)($value ?? ''));
$value = preg_replace('/^\p{Z}+|\p{Z}+$/u', '', $value);
return preg_replace('/[\x{200B}\x{200C}\x{200D}\x{FEFF}\x{00A0}\x{200E}\x{200F}\x{202A}-\x{202E}]/u', '', $value);
}
public function updateInsurerStatement($params)
{
/*
* Changes made: 12-06-2024
* - Added safe file_id handling and DB file record validation before using file details.
* - Fixed physical file missing response and error message.
* - Skips empty Excel rows and collects unique policy numbers from the uploaded statement.
* - Fetches NHance source records only for those uploaded policy numbers.
* - Uses the same sanitized policy number + endorsement number matching as validation.
* - Inserts statement details only for matched rows and skips empty or unmatched Excel rows.
* - Added safe default handling for amount and reward columns before calculation/insert.
*/
helper('excel_util_helper');
$file_id = $params['file_id'] ?? 0;
$error_data = ['error_code' => '', 'error_data' => []];
$status = 'success';
$ret_status = true;
//get file info
$file = $this->insurerStatements->find((int)$file_id);
// dd($file);
if (empty($file)) {
//file not found in DB
return array('status' => false, 'error_code' => 0, 'error_data' => 'statement file not found in DB');
}
$file_name_with_path = storage_ensure_local_file(WRITEPATH . 'uploads/statements', $file['file_name']);
//check physical file
if (!file_exists($file_name_with_path)) {
//file not found update status and reason
$message = "Physical file not found";
// echo $message;
$this->myLogger->logme('error', ($message . ' for statement file id ' . $file_id));
$this->insurerStatements->where('id', $file_id)->set(['file_status' => 'failed', 'reason' => json_encode(['error_code' => 0, 'error_data' => $message])])->update();
return array('status' => false, 'error_code' => 0, 'error_data' => $message); //0 - Physcial file not found
}
//get excel data to php array
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($file_name_with_path);
$sheet = $spreadsheet->getActiveSheet();
$highestRowAndColumn = $sheet->getHighestRowAndColumn();
// dd($highestRowAndColumn);
$excel_data = $sheet->rangeToArray('A1:' . $highestRowAndColumn['column'] . $highestRowAndColumn['row']);
unset($excel_data[0]);
$excel_data = ExcelSanitizeHelper::sanitizeArrayData($excel_data);
// dd($excel_data);
$policyNos = [];
foreach ($excel_data as $row) {
if (check_row_is_empty_or_null($row)) {
continue;
}
$policyNo = $this->sanitizeStatementLookupValue($row[1] ?? '');
if ($policyNo !== '') {
$policyNos[] = $policyNo;
}
}
$policyNos = array_values(array_unique($policyNos));
// get uploaded month transactions data
// $source_data = $this->PTCOShareDetailsModel->getNonReconcileredPolicyTransactions(insurer_id: $file['insurer_id'], insurer_branch_id: $file['branch_id'], month: $file['month']);
$source_data = !empty($policyNos) ? $this->PTCOShareDetailsModel->getNonReconcileredPolicyTransactionByPolicyAndEndorsement(insurer_id: $file['insurer_id'], insurer_branch_id: $file['branch_id'], policy_no: $policyNos) : [];
// Kint::dump($source_data);//die;
// Kint::dump($excel_data);
// die;
$source_lookup = [];
foreach ($source_data as $source_row) {
$source_policy_no = $this->sanitizeStatementLookupValue($source_row['policy_no'] ?? '');
$source_endorsement_no = $this->sanitizeStatementLookupValue($source_row['endorsement_no'] ?? '');
$source_lookup[$source_policy_no . '|' . $source_endorsement_no][] = $source_row;
}
// check policy no,insurer and etc in DB for this month
// if all good return true, otherwise return false with messssage
$data_to_update = [];
try {
foreach ($excel_data as $excel_row) {
if (check_row_is_empty_or_null($excel_row)) {
continue;
}
// $policy_start_date = preg_replace('/^\p{Z}+|\p{Z}+$/u', '', $excel_row[4]); //policy_start_date from excel
// $policy_end_date = preg_replace('/^\p{Z}+|\p{Z}+$/u', '', $excel_row[5]); //policy_end_date from excel
$policy_no = $this->sanitizeStatementLookupValue($excel_row[1] ?? ''); //policy_number from excel
// $client_name = preg_replace('/^\p{Z}+|\p{Z}+$/u', '', $excel_row[3]); //clientname from excel
$endorsement_no = $this->sanitizeStatementLookupValue($excel_row[2] ?? ''); //endorsement number from excel
$entry_key = $policy_no . '|' . $endorsement_no;
if (empty($source_lookup[$entry_key])) {
continue;
}
$source_row = array_shift($source_lookup[$entry_key]);
//calculate percentage first
$total_amt = 0;
// $actual_bp_per = trim($excel_row[9]); //commented becoz this filed removed tfrom excel file
$actual_bp_per = 0; //set default value 0 for maintaining existing code flow
$actual_bp_brokerage = (int) trim((string)($excel_row[5] ?? 0));
$actual_bp_amt = (int) trim((string)($excel_row[3] ?? 0));
if (($actual_bp_brokerage && $actual_bp_brokerage != 0 && $actual_bp_brokerage != "")) {
$total_amt += $actual_bp_brokerage;
//percentage reverse calculation
if (($actual_bp_per == 0 || $actual_bp_per == 0) && !empty($actual_bp_amt)) {
$actual_bp_per = (int) round(($actual_bp_brokerage / $actual_bp_amt) * 100, 2);
}
} else {
$actual_bp_brokerage = $actual_bp_amt * ($actual_bp_per / 100);
$total_amt += $actual_bp_brokerage;
}
// $actual_tp_per = trim($excel_row[10]);//commented becoz this filed removed tfrom excel file
$actual_tp_per = 0;//set default value 0 for maintaining existing code flow
$actual_tp_brokerage = (int) trim((string)($excel_row[6] ?? 0));
$actual_tp_amt = (int) trim((string)($excel_row[4] ?? 0));
if ($actual_tp_brokerage && $actual_tp_brokerage != 0 && $actual_tp_brokerage != "") {
$total_amt += $actual_tp_brokerage;
//percentage reverse calculation
if (($actual_tp_per == 0 || $actual_tp_per == "") && !empty($actual_tp_amt)) {
$actual_tp_per = (int) round(($actual_tp_brokerage / $actual_tp_amt) * 100, 2);
}
} else {
$actual_tp_brokerage = $actual_tp_amt * ($actual_tp_per / 100);
$total_amt += $actual_tp_brokerage;
}
// $actual_tep_per = trim($excel_row[11]);
// $actual_tep_brokerage = trim($excel_row[14]);
// $actual_tep_amt = trim($excel_row[8]);
$actual_tep_per = 0;
$actual_tep_brokerage = 0;
$actual_tep_amt = 0;
if ($actual_tep_brokerage && $actual_tep_brokerage != 0 && $actual_tep_brokerage != "") {
$total_amt += $actual_tep_brokerage;
//percentage reverse calculation
if (($actual_tep_per == 0 || $actual_tep_per == "") && !empty($actual_tep_amt)) {
$actual_tep_per = ($actual_tep_brokerage / $actual_tep_amt) * 100;
}
} else {
$actual_tep_brokerage = $actual_tep_amt * ($actual_tep_per / 100);
$total_amt += $actual_tep_brokerage;
}
//find variance
$variance_amt = $source_row['exp_amt'] - $total_amt;
$data_to_update[] = ['co_share_id' => $source_row['id'], 'actual_bp_amt' => $actual_bp_amt, 'actual_tp_amt' => $actual_tp_amt, 'actual_tep_amt' => $actual_tep_amt, 'actual_bp_per' => $actual_bp_per, 'actual_tp_per' => $actual_tp_per, 'actual_tep_per' => $actual_tep_per, 'variance' => $variance_amt, 'actual_tep_brokerage_amt' => $actual_tep_brokerage, 'actual_tp_brokerage_amt' => $actual_tp_brokerage, 'actual_bp_brokerage_amt' => $actual_bp_brokerage, 'reward' => trim((string)($excel_row[7] ?? '')), 'statement_id' => $file_id];
}
} catch (\Throwable $th) {
$this->myLogger->logme("error", "REST-AUTH-CONTROLLER - updateInsurerStatement: Exception: " . $th->getMessage() . " --- Line: " . $th->getLine() . " --- Trace: " . $th->getTraceAsString());
$errorData = [
'message' => $th->getMessage(),
'file' => $th->getFile(),
'line' => $th->getLine(),
'code' => $th->getCode(),
'trace' => $th->getTraceAsString(),
'trace_array' => $th->getTrace(), // full array version (optional)
'function' => $th->getTrace()[0]['function'] ?? null,
'class' => $th->getTrace()[0]['class'] ?? null,
];
return ['status' => 'failed', 'code' => 500, 'message' => $th->getMessage(), 'error_data' => $errorData];
}
// dd($data_to_update);
$this->coShareStmtDetailsModel->insertBatch($data_to_update, 'id');
// dd($data_to_update);
// if($error_data['error_code'])
// {
// $status = 'failed';
// $ret_status = false;
// }
//update in DB
$this->insurerStatements->where('id', $file_id)->set(['file_status' => $status, 'reason' => json_encode($error_data), 'invoice_status' => 'pending'])->update();
return array('status' => $ret_status, 'error_code' => $error_data['error_code'], 'error_data' => $error_data['error_data']);
}
public function getInvoicePaymentDetails()
{
$statement_id = $this->request->getUri()->getSegment(4);
$inv_details = $this->insurerStatements->find((int)$statement_id);
$inv_payment_details = $this->invPaymentDetailsModel
->where('statement_id', $statement_id)
->where('is_active', 1)
->get()
->getResultArray();
if (!$inv_details['invoice_value']) {
$stmt_level_value = $this->coShareStmtDetailsModel->select('sum(actual_tep_brokerage_amt) + sum(actual_tp_brokerage_amt) + sum(actual_bp_brokerage_amt) + sum(reward) as invoice_value')
->where('statement_id', $statement_id)
->groupBy('statement_id')
->get()
->getResultArray();
// print_r($stmt_level_value);
if ($stmt_level_value && count($stmt_level_value) && isset($stmt_level_value[0])) {
$inv_details['invoice_value'] = $stmt_level_value[0]['invoice_value'];
}
}
// ~dd($inv_details);
$data = [
'invoice_status' => $inv_details['invoice_status'],
'gst_per' => isset($inv_details['gst_per']) ? $inv_details['gst_per'] : 18,
'invoice_value' => $inv_details['invoice_value'],
'gst_value' => $inv_details['gst_value'],
'invoice_no' => $inv_details['invoice_no'],
'invoice_amount' => $inv_details['invoice_amount'],
'invoice_date' => isset($inv_details['invoice_date']) ? change_date_format($inv_details['invoice_date'], 'Y-m-d', 'd/m/Y') : null
];
$data['payments'] = $inv_payment_details;
return $this->respond(['dataStatus' => true, 'code' => 200, 'data' => $data], 200);
}
public function saveInvoicePaymentDetails()
{
$jsonData = $this->request->getJSON();
$jsonData = (array)$jsonData;
// echo 'Hi';
// print_r($jsonData);die();
$invoiceStatus = $jsonData['invoice_status'];
$hiddenStatementId = $jsonData['hidden_statement_id'];
$invoiceNo = $jsonData['invoice_no'];
$invoiceDate = change_date_format($jsonData['invoice_date'], 'd/m/Y', 'Y-m-d');
$invoice_amount = $jsonData['invoice_amount'];
$invoice_value = $jsonData['invoice_value'];
$gst_per = $jsonData['invoice_gst_per'];
$gst_value = $jsonData['invoice_gst'];
//Update statement table
$parentData = [
'invoice_status' => $invoiceStatus,
'invoice_no' => $invoiceNo,
'invoice_date' => $invoiceDate,
'invoice_amount' => $invoice_amount,
'gst_per' => $gst_per,
'gst_value' => $gst_value,
'invoice_value' => $invoice_value,
'updated_by' => get_session_userid()
];
$this->insurerStatements->update($hiddenStatementId, $parentData);
// Process child data
$receivedAmounts = $jsonData['received_amount'];
$utrNos = $jsonData['utr_no'];
$tdsTotal = $jsonData['tds'];
$gstTotal = $jsonData['gst_amount'];
$paymentDates = $jsonData['payment_date'];
$pks = $jsonData['pk'];
foreach ($receivedAmounts as $index => $receivedAmount) {
$pk = $pks[$index]; // Get the pk for the current record
$utrNo = $utrNos[$index];
$tds = $tdsTotal[$index];
$gst = $gstTotal[$index];
$paymentDate = $paymentDates[$index];
if($utrNo == "" && $tds == "" && $gst == "" && $receivedAmount == "")
{
continue;
}
// Prepare data for insert/update
$childData = [
'inv_amt' => $receivedAmount,
'utr_no' => $utrNo,
'tds' => $tds,
'gst' => $gst,
'received_date' => change_date_format($paymentDate, 'd/m/Y', 'Y-m-d'),
'statement_id' => $hiddenStatementId
];
if ($pk) {
$childData['updated_by'] = get_session_userid();
$childData['id'] = (int)$pk;
} else {
$childData['created_by'] = get_session_userid();
}
// print_r($childData);
// Insert or update
$this->invPaymentDetailsModel->save($childData);
// print_r($this->invPaymentDetailsModel->errors());
}
return $this->respond(['dataStatus' => true, 'code' => 200], 200);
//return $this->response->setJSON(['dataStatus' => 'true']);
}
public function deletePaymentEntry()
{
$payment_id = $this->request->getUri()->getSegment(4);
//echo $payment_id;
$this->invPaymentDetailsModel->update($payment_id, ['is_active' => 0]);
return $this->respond(['dataStatus' => true, 'code' => 200], 200);
}
public function downloadSampleInsurerStatement()
{
$filePath = ROOTPATH . 'public/sample_excel/insurer_stament_sample.xlsx';
// Check if the file exists
if (file_exists($filePath)) {
// Set the appropriate MIME type
$mimeType = mime_content_type($filePath);
// Send the file to the client for download
return $this->response->download($filePath, null, $mimeType);
} else {
// File not found, show an error message or redirect
echo view('errors/html/production');
}
}
public function downloadInsurerStatement($id)
{
$statement = $this->insurerStatements
->where('id', (int) $id)
->where('is_active', 1)
->first();
if (empty($statement) || empty($statement['file_name'])) {
throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound('Statement file not found');
}
$fileName = basename($statement['file_name']);
$storage = \Config\Services::getFileStorageService();
$result = $storage->download(WRITEPATH . 'uploads/statements', $fileName);
if (! ($result['success'] ?? false)) {
throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound('Statement file not found');
}
$downloadAs = storage_upload_display_name($fileName);
if (! empty($result['path']) && is_file($result['path'])) {
return $this->response->download($result['path'], null)->setFileName($downloadAs);
}
if (! empty($result['content'])) {
return $this->response->download($downloadAs, $result['content'])->setFileName($downloadAs);
}
throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound('Statement file not found');
}
public function getFileErr()
{
$file_id = $this->request->getUri()->getSegment(4);
$file = $this->insurerStatements->find((int)$file_id);
return $this->respond(['dataStatus' => true, 'code' => 200, 'data' => $file['reason']], 200);
}
public function dmsSearch()
{
// echo 'scbsc';die();
if ($this->request->is('post')) {
// $jsonData = (array)$this->request->getJSON();
$request_data = $this->request->getPost();
$data = sanitizeInputArrayAdvanced($request_data);
$customer_id = $data['customer_id'];
$policy_id = $data['policy_id'];
$cus_doc_name = $data['cus_doc_name'];
$policy_doc_name = $data['policy_doc_name'];
$pt_files = [];
$kyc_files = [];
$batch_files = [];
$files = [];
// print_r($jsonData);die();
if ($policy_id != "") {
//get policy docs from policy transation related tables
$pt_files = $this->PTFileModel->getPolicyDriveFilesIndex($policy_id, $policy_doc_name);
$batch_files = $this->batchFileModel->getBatchFilesDataForDocumentSearch($policy_id, $policy_doc_name);
$files = $this->filesModel->getFilesDataForDocumentSearch($policy_id, $policy_doc_name);
// dd($files);
// dd($this->PTFileModel->getLastQuery());
// ~dd($pt_files);
}
if ($customer_id != "") {
$kyc_files = $this->clientKYCDocsModel->getClientKYCDriveFilesIndex($customer_id, $cus_doc_name);
// dd($this->clientKYCDocsModel->getLastQuery());
// !dd($kyc_files);
}
$data['files'] = array_merge($pt_files, $kyc_files, $batch_files, $files);
// dd($data['files']);
}
$data['tab_name'] = 'Documents Search';
$data['page_name'] = 'Documents';
$data['customers'] = $this->clientModel->select('id,client_name,short_name as display_value')->where('is_active', 1)->get()->getResultarray();
$data['policies'] = $this->clientPolicyModel->select("client_policy.id,client_policy.policy_no,policy_type.policy_type,concat(policy_type.policy_type,' - ',client_policy.policy_no) as display_value")
->join('policy_type', 'client_policy.policy_type_id = policy_type.id')
->where('client_policy.is_active', 1)->get()->getResultarray();
// dd($data);
$this->loadLayout('dms_search', $data);
}
//---------------------------------------------------------------------------------------------------
public function getCoShareStatementDetails($pt_id)
{
if (!$pt_id) {
return $this->respond([
'status' => false,
'code' => 400,
'message' => 'No data found'
], 200);
}
// Fetch data from the database
$data = db_connect()->table("co_share_stmt_details")
->select("
co_share_stmt_details.*,
insurer_statements.month,
insurer_statements.invoice_status,
insurer_statements.invoice_date,
insurer_statements.invoice_no,
insurer_statements.invoice_amount,
insurer_statements.stmt_sno,
(co_share_stmt_details.actual_bp_amt + co_share_stmt_details.actual_tp_amt + co_share_stmt_details.actual_tep_amt) AS sum_of_actual_amt
")
->join('insurer_statements', 'co_share_stmt_details.statement_id = insurer_statements.id')
->where([
'co_share_stmt_details.is_active' => 1,
'insurer_statements.is_active' => 1,
'co_share_stmt_details.co_share_id' => $pt_id
])
->get()
->getResultArray();
// Check if data exists before formatting
if ($data) {
foreach ($data as &$row) {
// Check if invoice_date is not null before formatting
$row['invoice_date'] = $row['invoice_date'] ? change_date_format($row['invoice_date'], 'Y-m-d', 'd/m/Y') : null;
// Check if month is not null before formatting
$row['month'] = $row['month'] ? change_date_format($row['month'], 'Y-m-d', 'M-Y') : null;
}
return $this->respond([
'status' => true,
'code' => 200,
'data' => $data
], 200);
} else {
return $this->respond([
'status' => false,
'code' => 400,
'message' => 'No data found'
], 200);
}
}
public function getClientPolicyDataBasedOnClientAndInsuer()
{
$client_id = $this->request->getGet('client_id') ?? 0;
$client_branch_id = $this->request->getGet('client_branch_id') ?? 0;
$insurer_id = $this->request->getGet('insurer_id') ?? 0;
$insurer_branch_id = $this->request->getGet('insurer_branch_id') ?? 0;
$policy_type_id = $this->request->getGet('policy_type_id') ?? 0;
$builder = db_connect()->table("client_policy")
->select("
client_policy.*,
policy_type.policy_type,
")
->join('policy_type', 'client_policy.policy_type_id = policy_type.id')
->where([
'client_policy.is_active' => 1,
]);
if (!empty($client_id)) {
$builder->where('client_policy.client_id', $client_id);
}
if (!empty($client_branch_id)) {
$builder->where('client_policy.client_branch_id', $client_branch_id);
}
if (!empty($insurer_id)) {
$builder->where('client_policy.insurer_id', $insurer_id);
}
if (!empty($insurer_branch_id)) {
$builder->where('client_policy.insurer_branch_id', $insurer_branch_id);
}
if (!empty($policy_type_id)) {
$builder->where('client_policy.policy_type_id', $policy_type_id);
}
$result = $builder->get()->getResultArray();
if ($result) {
return $this->respond(['status' => true, 'code' => 200, 'data' => $result, 'getData' => $this->request->getGet()], 200);
} else {
return $this->respond(['status' => false, 'code' => 400, 'message' => 'No data found'], 200);
}
}
public function checkCDAmountForBasePremium()
{
$base_premium = $this->request->getGet('base_premium') ?? 0;
$cd_ac_no = $this->request->getGet('cd_ac_no') ?? 0;
// Validate inputs
if (empty($cd_ac_no)) {
return $this->respond(['status' => false, 'code' => 400, 'message' => 'CD Account Number is required'], 200);
}
// Build query
$db = db_connect();
$builder = $db->table("cash_deposit")
->where('cd_ac_pk', $cd_ac_no)
->where('is_active', 1)
->orderBy('id', 'desc')
->limit(1);
$result = $builder->get()->getRowArray();
if ($result) {
// Check if base premium exceeds balance
$base_premium_greater_than_balance = $base_premium > $result['balance'];
return $this->respond([
'status' => true,
'code' => 200,
'data' => $result,
'base_premium' => $base_premium,
'cd_ac_no' => $cd_ac_no,
'base_premium_greater_than_balance' => $base_premium_greater_than_balance,
], 200);
}
return $this->respond(['status' => false, 'code' => 400, 'message' => 'No data found for this CD'], 200);
}
public function getInsurerStatementMonth()
{
$insurer_id = $this->request->getGet('insurer_id');
$month = $this->request->getGet('month');
// echo $month;
$insurer_branch_id = explode('-', $insurer_id)[1];
$insurer_id = explode('-', $insurer_id)[0];
$month = $month . '-01';
$month = change_date_format($month, 'Y-M-d', 'Y-m-d');
// echo $month;
$res_data = $this->insurerStatements
->where('insurer_id', $insurer_id)
->where('branch_id', $insurer_branch_id)
->where('month', $month)
->where('is_active', 1)
->where('file_status', 'success')
->findAll();
return $this->respond(['dataStatus' => true, 'code' => 200, 'data' => $res_data], 200);
}
public function deleteStatement($id)
{
// echo $id;die();
$this->coShareStmtDetailsModel->where('statement_id', $id)
->set(['is_active' => 0])
->update();
$this->invPaymentDetailsModel->where('statement_id', $id)
->set(['is_active' => 0])
->update();
$this->insurerStatements->where('id', $id)
->set(['is_active' => 0])
->update();
return $this->respond(['dataStatus' => true, 'code' => 200], 200);
}
public function sendInstallmentRemainderMail()
{
$this->myLogger->logme("error", "Cron Job For Send Installment Remainder Mail Started");
try {
/** @var BdsConfig $bdsConfig */
$bdsConfig = config(BdsConfig::class);
if (!$bdsConfig->shouldFetchInstallmentRemindersToday()) {
$this->myLogger->logme(
'error',
'Installment reminder fetch skipped (bds.installmentReminder.enabled / daily / days config)'
);
CLI::write('Installment reminder fetch skipped per .env configuration');
return ['status' => false, 'message' => 'Fetch skipped per configuration', 'response' => []];
}
$bdsInstallmentData = [];
try {
$bdsInstallmentData = $this->BdsPlacementModel->getLeadInstallmentDetails();
} catch (Exception $e) {
$this->myLogger->logme('error', 'Exception: ' . $e->getMessage() . 'Page: ' . $e->getFile() . ' Line: ' . $e->getLine());
}
$this->myLogger->logme("error", "Data for BDS Installment " . json_encode($bdsInstallmentData));
// dd($bdsInstallmentData);die();
if (empty($bdsInstallmentData)) {
$this->myLogger->logme("error", "No Client Installment is Due in the 5th Day");
CLI::write("No Client Installment is Due in the 5th Day");
return ['status' => false, 'message' => 'No data found', 'response' => []];
}
$results = [];
$successCount = 0;
$failedCount = 0;
$skippedCount = 0;
foreach ($bdsInstallmentData as $installmentData) {
$installmentId = $installmentData['id'] ?? 'unknown';
$leadId = $installmentData['lead_id'] ?? 'unknown';
try {
$mailData = $this->PrepareBDSMailData($installmentData);
if (empty($mailData) || empty($mailData['to_mail'])) {
$this->myLogger->logme(
'error',
"Installment {$installmentId} (lead {$leadId}): skipped — no valid recipient emails"
);
$skippedCount++;
$results[] = [
'installment_id' => $installmentId,
'lead_id' => $leadId,
'status' => 'skipped',
'message' => 'No valid recipient emails',
];
continue;
}
$to_mail = $mailData['to_mail'];
$message = $mailData['message'];
$subject = $mailData['subject'];
$this->myLogger->logme("error", "Installment Pending for " . $subject);
$common = ['mail_type' => 'installment_amount_due_remainder_mail'];
$res = MailHelper::send_email(['mail' => $to_mail, 'subject' => $subject, 'message' => $message, 'common' => $common]);
$res = json_decode($res);
$this->myLogger->logme(
'error',
"Installment {$installmentId} (lead {$leadId}) mail result: " . json_encode($res)
);
if ($res->status == 'success') {
$successCount++;
CLI::write("Mail sent successfully for installment {$installmentId} to " . count($to_mail) . " recipients");
$results[] = [
'installment_id' => $installmentId,
'lead_id' => $leadId,
'status' => 'success',
];
} else {
$failedCount++;
CLI::write("Mail failed for installment {$installmentId}");
$results[] = [
'installment_id' => $installmentId,
'lead_id' => $leadId,
'status' => 'failed',
'response' => $res,
];
}
} catch (Exception $e) {
$failedCount++;
$this->myLogger->logme(
'error',
"Installment {$installmentId} (lead {$leadId}) exception: " . $e->getMessage()
);
$results[] = [
'installment_id' => $installmentId,
'lead_id' => $leadId,
'status' => 'failed',
'message' => $e->getMessage(),
];
}
}
$totalProcessed = count($bdsInstallmentData);
$summaryMessage = "Processed {$totalProcessed} installment(s): {$successCount} sent, {$failedCount} failed, {$skippedCount} skipped";
return [
'status' => $successCount > 0,
'message' => $summaryMessage,
'response' => $results,
];
} catch (Exception $e) {
$this->myLogger->logme('error', 'Exception: ' . $e->getMessage() . 'Page: ' . $e->getFile() . ' Line: ' . $e->getLine());
}
}
protected function PrepareBDSMailData($data)
{
try {
helper('excel_util_helper');
$installment_amount = (float) ($data['installment_amount'] ?? 0);
$payment_date = date('d-m-Y', strtotime($data['payment_date']));
$client = $data['client_name'];
$branch = $data['branch_name'];
$sales_person_mail = $data['sales_person'];
$policy_no = trim((string) ($data['policy_no'] ?? ''));
$client_short_name = isset($data['short_name']) && $data['short_name'] != null ? $data['short_name'] : $data['client_name'];
$formatted_amount = '₹ ' . formatIndianCurrency(number_format($installment_amount, 2, '.', ''));
$is_overdue = strtotime($data['payment_date']) < strtotime(date('Y-m-d'));
$policy_label = $policy_no !== '' ? "Policy #{$policy_no}" : 'Policy Pending';
$policy_period = '';
if (!empty($data['policy_start_date']) && !empty($data['policy_end_date'])) {
$policy_period = date('d-m-Y', strtotime($data['policy_start_date']))
. ' to '
. date('d-m-Y', strtotime($data['policy_end_date']));
}
$subject = $is_overdue
? "Overdue Installment Reminder - {$client_short_name} | {$policy_label} | Due {$payment_date}"
: "Installment Payment Reminder - {$client_short_name} | {$policy_label} | Due {$payment_date}";
$message = view('bds_installment_reminder_email_template', [
'client_name' => $client,
'branch_name' => $branch,
'policy_no' => $policy_no !== '' ? $policy_no : 'Not Assigned',
'policy_type' => $data['policy_type'] ?? '',
'insurer_name' => $data['insurer_name'] ?? '',
'policy_period' => $policy_period,
'payment_date' => $payment_date,
'installment_amount' => $formatted_amount,
'is_overdue' => $is_overdue,
'generated_on' => date('d-m-Y H:i'),
]);
$contactPersonEmail = trim((string) ($data['contact_person_email'] ?? ''));
$to_mail = array_merge(
[$data['acm_email']],
[$sales_person_mail],
$contactPersonEmail !== '' ? [$contactPersonEmail] : []
);
$to_mail = array_values(array_unique(array_filter($to_mail, static function ($email) {
return is_string($email) && filter_var(trim($email), FILTER_VALIDATE_EMAIL);
})));
$this->myLogger->logme("error", "Selected To Address : " . json_encode($to_mail));
return [
'to_mail' => $to_mail,
'message' => $message,
'subject' => $subject
];
} catch (Exception $e) {
$this->myLogger->logme('error', 'Exception: ' . $e->getMessage() . 'Page: ' . $e->getFile() . ' Line: ' . $e->getLine());
}
}
public function sendRenewalReminderMail()
{
$logPrefix = '[PT Renewal Reminder]';
$isCli = is_cli();
$dryRun = $this->isRenewalReminderDryRun($isCli);
$this->logRenewalReminderStep(
$logPrefix . ' Cron started' . ($dryRun ? ' (DRY RUN)' : '')
);
try {
/** @var PtRenewalReminderConfig $config */
$config = config(PtRenewalReminderConfig::class);
$configSnapshot = $config->toArray();
$configSnapshot['notificationId'] = $config->notificationId;
$configSnapshot['dry_run'] = $dryRun;
$this->logRenewalReminderStep(
$logPrefix . ' Config loaded: ' . json_encode($configSnapshot)
);
if (! $config->shouldRunToday()) {
$message = 'Fetch skipped per configuration (enabled/daily/days)';
$this->logRenewalReminderStep($logPrefix . ' ' . $message);
if ($isCli) {
CLI::write($message);
}
return $this->renewalReminderResponse([
'status' => false,
'code' => 200,
'message' => $message,
'dry_run' => $dryRun,
'config' => $configSnapshot,
'summary' => [
'total' => 0,
'sent' => 0,
'failed' => 0,
'skipped' => 0,
],
'data' => [],
], $isCli);
}
$this->logRenewalReminderStep(
$logPrefix . ' Fetching candidates for dateField='
. $config->getDateField()
. ', daysBefore=' . $config->getDaysBefore()
. ', includeOverdue=' . ($config->includeOverdue() ? 'true' : 'false')
. ', clientTypes=' . json_encode($config->getClientTypes())
);
$candidates = [];
try {
$candidates = $this->policyTransactionModel->getRenewalReminderCandidates(
$config->getDateField(),
$config->getDaysBefore(),
$config->getClientTypes(),
$config->includeOverdue()
);
} catch (Exception $e) {
$message = 'Candidate fetch failed: ' . $e->getMessage();
$this->logRenewalReminderStep(
$logPrefix . ' ' . $message
. ' | File: ' . $e->getFile() . ' Line: ' . $e->getLine()
);
return $this->renewalReminderResponse([
'status' => false,
'code' => 500,
'message' => $message,
'dry_run' => $dryRun,
'config' => $configSnapshot,
'summary' => [
'total' => 0,
'sent' => 0,
'failed' => 0,
'skipped' => 0,
],
'data' => [],
], $isCli, 500);
}
$candidateCount = count($candidates);
$candidateIds = array_values(array_map(
static fn ($row) => $row['id'] ?? null,
$candidates
));
$this->logRenewalReminderStep(
$logPrefix . ' Candidates fetched: count=' . $candidateCount
. ', pt_ids=' . json_encode($candidateIds)
);
if ($candidateCount === 0) {
$message = 'No policy_transaction renewal reminders due';
$this->logRenewalReminderStep(
$logPrefix . ' ' . $message
. ' | dateField=' . $config->getDateField()
. ' | daysBefore=' . $config->getDaysBefore()
. ' | includeOverdue=' . ($config->includeOverdue() ? 'true' : 'false')
);
if ($isCli) {
CLI::write($message);
}
// Heavy diagnostics only for HTTP dry-run (not CLI / not live send)
$httpDryRun = $dryRun && ! $isCli;
$diagnostics = null;
$detailedSummary = null;
if ($httpDryRun) {
try {
$diagnostics = $this->policyTransactionModel->diagnoseRenewalReminderCandidates(
$config->getDateField(),
$config->getDaysBefore(),
$config->getClientTypes(),
$config->includeOverdue()
);
} catch (Exception $diagEx) {
$diagnostics = [
'error' => $diagEx->getMessage(),
];
}
$detailedSummary = $this->buildRenewalReminderDryRunSummary(
$config,
0,
0,
0,
0,
[]
);
}
$emptyPayload = [
'status' => true,
'code' => 200,
'message' => $message,
'dry_run' => $dryRun,
'summary' => [
'total' => 0,
'sent' => 0,
'would_send' => 0,
'failed' => 0,
'skipped' => 0,
],
'data' => [],
];
if ($httpDryRun) {
$emptyPayload['config'] = $configSnapshot;
$emptyPayload['detailed_summary'] = $detailedSummary;
$emptyPayload['why_empty'] = $diagnostics;
}
return $this->renewalReminderResponse($emptyPayload, $isCli);
}
$results = [];
$successCount = 0;
$failedCount = 0;
$skippedCount = 0;
$httpDryRun = $dryRun && ! $isCli;
foreach ($candidates as $index => $row) {
$ptId = $row['id'] ?? 'unknown';
$stepNo = $index + 1;
$isOverdue = ! empty($row['is_overdue']);
$this->logRenewalReminderStep(
$logPrefix . " Step {$stepNo}/{$candidateCount}: preparing mail for PT {$ptId}"
. ' | client_id=' . ($row['client_id'] ?? '')
. ' | client_type=' . ($row['client_type'] ?? '')
. ' | policy_no=' . ($row['policy_no'] ?? '')
. ' | is_overdue=' . ($isOverdue ? 'true' : 'false')
);
try {
$mailData = $this->prepareRenewalReminderMailData($row, $config, $dryRun);
if (empty($mailData) || empty($mailData['to_mail'])) {
$skippedCount++;
$skipMsg = "PT {$ptId}: skipped — no valid recipient emails";
$this->logRenewalReminderStep($logPrefix . ' ' . $skipMsg);
if ($isCli) {
CLI::write($skipMsg);
}
if ($httpDryRun) {
$results[] = [
'pt_id' => $ptId,
'client_id' => $row['client_id'] ?? null,
'client_name' => $row['client_name'] ?? null,
'client_email'=> $row['client_email'] ?? ($mailData['client_email'] ?? null),
'client_type' => $row['client_type'] ?? null,
'policy_no' => $row['policy_no'] ?? null,
'policy_type' => $row['policy_type'] ?? null,
'insurer_name'=> $row['insurer_name'] ?? null,
'renewal_date'=> $row['renewal_date'] ?? null,
'policy_end_date' => $row['policy_end_date'] ?? null,
'is_overdue' => $isOverdue,
'status' => 'skipped',
'message' => 'No valid recipient emails',
'include_client_email_enabled' => $mailData['include_client_email_enabled'] ?? $config->includeClientEmail(),
'client_email_included' => $mailData['client_email_included'] ?? false,
'recipient_sources' => $mailData['recipient_sources'] ?? [
'client_email' => [],
'branch_hr' => [],
'configured_to' => [],
],
'to' => [],
'to_count' => 0,
'cc' => $mailData['cc'] ?? [],
'bcc' => $mailData['bcc'] ?? [],
];
} elseif (! $dryRun) {
$results[] = [
'pt_id' => $ptId,
'client_id' => $row['client_id'] ?? null,
'client_name' => $row['client_name'] ?? null,
'policy_no' => $row['policy_no'] ?? null,
'is_overdue' => $isOverdue,
'status' => 'skipped',
'message' => 'No valid recipient emails',
'to' => [],
'cc' => $mailData['cc'] ?? [],
'bcc' => $mailData['bcc'] ?? [],
];
}
continue;
}
if ($dryRun) {
$successCount++;
$dryMsg = "PT {$ptId}: dry run — would send mail to "
. count($mailData['to_mail']) . ' recipient(s)'
. ' | client_email_included=' . (! empty($mailData['client_email_included']) ? 'true' : 'false');
$this->logRenewalReminderStep($logPrefix . ' ' . $dryMsg);
if ($isCli) {
CLI::write($dryMsg);
}
if ($httpDryRun) {
$dateField = $config->getDateField();
$reminderRaw = $row[$dateField] ?? ($row['renewal_date'] ?? $row['policy_end_date'] ?? null);
$results[] = [
'pt_id' => $ptId,
'client_id' => $row['client_id'] ?? null,
'client_name' => $row['client_name'] ?? null,
'client_email' => $mailData['client_email'] ?? ($row['client_email'] ?? null),
'client_type' => $row['client_type'] ?? null,
'policy_no' => $row['policy_no'] ?? null,
'policy_type' => $row['policy_type'] ?? null,
'insurer_name' => $row['insurer_name'] ?? null,
'renewal_date' => $row['renewal_date'] ?? null,
'policy_start_date' => $row['policy_start_date'] ?? null,
'policy_end_date' => $row['policy_end_date'] ?? null,
'reminder_date' => ! empty($reminderRaw) ? date('Y-m-d', strtotime((string) $reminderRaw)) : null,
'is_overdue' => $isOverdue,
'status' => 'dry_run',
'message' => 'Dry run — mail not sent, status not updated',
'include_client_email_enabled' => $mailData['include_client_email_enabled'] ?? $config->includeClientEmail(),
'client_email_included' => $mailData['client_email_included'] ?? false,
'recipient_sources' => $mailData['recipient_sources'] ?? [
'client_email' => [],
'branch_hr' => [],
'configured_to' => [],
],
'subject' => $mailData['subject'] ?? null,
'to' => $mailData['to_mail'],
'to_count' => count($mailData['to_mail']),
'cc' => $mailData['cc'] ?? [],
'cc_count' => count($mailData['cc'] ?? []),
'bcc' => $mailData['bcc'] ?? [],
'bcc_count' => count($mailData['bcc'] ?? []),
'from' => $mailData['from_mail'] ?? null,
];
}
continue;
}
$this->logRenewalReminderStep(
$logPrefix . " Step {$stepNo}/{$candidateCount}: sending mail for PT {$ptId}"
. ' | subject=' . ($mailData['subject'] ?? '')
. ' | to=' . json_encode($mailData['to_mail'])
. ' | cc=' . json_encode($mailData['cc'] ?? [])
. ' | bcc=' . json_encode($mailData['bcc'] ?? [])
. ' | from=' . ($mailData['from_mail'] ?? '')
);
$payload = [
'mail' => $mailData['to_mail'],
'subject' => $mailData['subject'],
'message' => $mailData['message'],
'common' => ['mail_type' => 'pt_renewal_reminder_mail'],
];
if (! empty($mailData['cc'])) {
$payload['cc'] = implode(',', $mailData['cc']);
}
if (! empty($mailData['bcc'])) {
$payload['bcc'] = implode(',', $mailData['bcc']);
}
if (! empty($mailData['from_mail'])) {
$payload['from_mail'] = $mailData['from_mail'];
}
$rawRes = MailHelper::send_email($payload);
$res = json_decode($rawRes);
$this->logRenewalReminderStep(
$logPrefix . " Step {$stepNo}/{$candidateCount}: mail API result for PT {$ptId}: "
. (is_string($rawRes) ? $rawRes : json_encode($res))
);
if (isset($res->status) && $res->status === 'success') {
$successCount++;
try {
$this->policyTransactionModel->update((int) $ptId, [
'renewal_status' => 'renewal_mail_send',
]);
$this->logRenewalReminderStep(
$logPrefix . " PT {$ptId}: renewal_status set to renewal_mail_send"
);
} catch (Exception $statusEx) {
$this->logRenewalReminderStep(
$logPrefix . " PT {$ptId}: failed to update renewal_status — "
. $statusEx->getMessage()
);
}
$okMsg = "PT {$ptId}: mail sent successfully to "
. count($mailData['to_mail']) . ' recipient(s)';
$this->logRenewalReminderStep($logPrefix . ' ' . $okMsg);
if ($isCli) {
CLI::write($okMsg);
}
$results[] = [
'pt_id' => $ptId,
'client_id' => $row['client_id'] ?? null,
'client_name' => $row['client_name'] ?? null,
'policy_no' => $row['policy_no'] ?? null,
'is_overdue' => $isOverdue,
'status' => 'success',
'message' => 'Mail sent successfully',
'subject' => $mailData['subject'] ?? null,
'to' => $mailData['to_mail'],
'cc' => $mailData['cc'] ?? [],
'bcc' => $mailData['bcc'] ?? [],
'from' => $mailData['from_mail'] ?? null,
];
} else {
$failedCount++;
$failMsg = "PT {$ptId}: mail send failed";
$this->logRenewalReminderStep(
$logPrefix . ' ' . $failMsg . ' | response=' . json_encode($res)
);
if ($isCli) {
CLI::write($failMsg);
}
$results[] = [
'pt_id' => $ptId,
'client_id' => $row['client_id'] ?? null,
'client_name' => $row['client_name'] ?? null,
'policy_no' => $row['policy_no'] ?? null,
'is_overdue' => $isOverdue,
'status' => 'failed',
'message' => 'Mail send failed',
'subject' => $mailData['subject'] ?? null,
'to' => $mailData['to_mail'],
'cc' => $mailData['cc'] ?? [],
'bcc' => $mailData['bcc'] ?? [],
'from' => $mailData['from_mail'] ?? null,
'mail_response' => $res,
];
}
} catch (Exception $e) {
$failedCount++;
$failMsg = "PT {$ptId}: exception — " . $e->getMessage();
$this->logRenewalReminderStep(
$logPrefix . ' ' . $failMsg
. ' | File: ' . $e->getFile() . ' Line: ' . $e->getLine()
);
if ($isCli) {
CLI::write($failMsg);
}
$results[] = [
'pt_id' => $ptId,
'client_id' => $row['client_id'] ?? null,
'client_name' => $row['client_name'] ?? null,
'policy_no' => $row['policy_no'] ?? null,
'is_overdue' => $isOverdue,
'status' => 'failed',
'message' => $e->getMessage(),
];
}
}
$summaryMessage = ($dryRun ? 'DRY RUN — ' : '')
. "Processed {$candidateCount} renewal reminder(s): "
. ($dryRun
? "{$successCount} would send, {$failedCount} failed, {$skippedCount} skipped"
: "{$successCount} sent, {$failedCount} failed, {$skippedCount} skipped");
$this->logRenewalReminderStep($logPrefix . ' Cron completed — ' . $summaryMessage);
if ($isCli) {
CLI::write($summaryMessage);
}
$responsePayload = [
'status' => $successCount > 0 || ($dryRun && $candidateCount > 0),
'code' => 200,
'message' => $summaryMessage,
'dry_run' => $dryRun,
'summary' => [
'total' => $candidateCount,
'sent' => $dryRun ? 0 : $successCount,
'would_send' => $dryRun ? $successCount : 0,
'failed' => $failedCount,
'skipped' => $skippedCount,
],
'data' => $results,
];
// Detailed dry-run payload only for HTTP dry-run (skip on CLI for speed)
if ($httpDryRun) {
$detailedSummary = $this->buildRenewalReminderDryRunSummary(
$config,
$candidateCount,
$successCount,
$skippedCount,
$failedCount,
$results
);
$responsePayload['config'] = $configSnapshot;
$responsePayload['detailed_summary'] = $detailedSummary;
$responsePayload['message'] = $detailedSummary['headline'] ?? $summaryMessage;
}
return $this->renewalReminderResponse($responsePayload, $isCli);
} catch (Exception $e) {
$message = 'Unhandled exception: ' . $e->getMessage();
$this->logRenewalReminderStep(
$logPrefix . ' ' . $message
. ' | File: ' . $e->getFile() . ' Line: ' . $e->getLine()
);
return $this->renewalReminderResponse([
'status' => false,
'code' => 500,
'message' => $message,
'dry_run' => $dryRun,
'summary' => [
'total' => 0,
'sent' => 0,
'failed' => 0,
'skipped' => 0,
],
'data' => [],
], $isCli, 500);
}
}
/**
* Detect dry-run mode for HTTP (?dry_run=1) or CLI (--dry-run / dry_run).
*/
protected function isRenewalReminderDryRun(bool $isCli): bool
{
if ($isCli) {
$argv = $_SERVER['argv'] ?? [];
foreach ($argv as $arg) {
$normalized = strtolower(ltrim((string) $arg, '-'));
if (in_array($normalized, ['dry-run', 'dry_run', 'dryrun'], true)) {
return true;
}
}
if (class_exists(CLI::class)) {
if (CLI::getOption('dry-run') !== null || CLI::getOption('dry_run') !== null) {
return true;
}
}
return false;
}
$param = $this->request->getGet('dry_run')
?? $this->request->getGet('dryRun')
?? $this->request->getPost('dry_run')
?? $this->request->getPost('dryRun')
?? '0';
return in_array(strtolower(trim((string) $param)), ['1', 'true', 'yes', 'on'], true);
}
/**
* Build a detailed dry-run summary for renewal reminder mails.
*
* @param PtRenewalReminderConfig $config
* @param array<int, array<string, mixed>> $results
* @return array<string, mixed>
*/
protected function buildRenewalReminderDryRunSummary(
$config,
int $candidateCount,
int $wouldSendCount,
int $skippedCount,
int $failedCount,
array $results
): array {
$overdueCount = 0;
$dueCount = 0;
$uniqueTo = [];
$uniqueCc = [];
$uniqueBcc = [];
$totalToHits = 0;
$totalCcHits = 0;
$totalBccHits = 0;
$byPolicyType = [];
$pendingPolicies = [];
$skippedPolicies = [];
$policiesWithoutEmail = 0;
$policiesWithoutPolicyNo = 0;
$policiesWithClientEmailInTo = 0;
$policiesMissingClientEmail = 0;
$clientEmailsInTo = [];
foreach ($results as $item) {
$status = (string) ($item['status'] ?? '');
$isOverdue = ! empty($item['is_overdue']);
if ($isOverdue) {
$overdueCount++;
} else {
$dueCount++;
}
$policyType = trim((string) ($item['policy_type'] ?? ''));
if ($policyType === '') {
$policyType = 'Unknown';
}
if (! isset($byPolicyType[$policyType])) {
$byPolicyType[$policyType] = [
'policy_type' => $policyType,
'total' => 0,
'would_send' => 0,
'skipped' => 0,
];
}
$byPolicyType[$policyType]['total']++;
$policyNo = trim((string) ($item['policy_no'] ?? ''));
if ($policyNo === '') {
$policiesWithoutPolicyNo++;
}
$clientEmailIncluded = ! empty($item['client_email_included']);
if ($clientEmailIncluded) {
$policiesWithClientEmailInTo++;
foreach (($item['recipient_sources']['client_email'] ?? []) as $email) {
$email = strtolower(trim((string) $email));
if ($email !== '') {
$clientEmailsInTo[$email] = true;
}
}
} elseif (! empty($item['include_client_email_enabled'])) {
$policiesMissingClientEmail++;
}
$compact = [
'pt_id' => $item['pt_id'] ?? null,
'policy_no' => $policyNo !== '' ? $policyNo : 'Not Assigned',
'client_name' => $item['client_name'] ?? null,
'client_email' => $item['client_email'] ?? null,
'client_email_included' => $clientEmailIncluded,
'include_client_email_enabled' => ! empty($item['include_client_email_enabled']),
'policy_type' => $item['policy_type'] ?? null,
'reminder_date' => $item['reminder_date'] ?? ($item['renewal_date'] ?? $item['policy_end_date'] ?? null),
'is_overdue' => $isOverdue,
'to' => $item['to'] ?? [],
'to_count' => (int) ($item['to_count'] ?? count($item['to'] ?? [])),
'recipient_sources' => $item['recipient_sources'] ?? null,
'status' => $status,
];
if ($status === 'dry_run') {
$byPolicyType[$policyType]['would_send']++;
$pendingPolicies[] = $compact;
foreach (($item['to'] ?? []) as $email) {
$email = strtolower(trim((string) $email));
if ($email === '') {
continue;
}
$uniqueTo[$email] = true;
$totalToHits++;
}
foreach (($item['cc'] ?? []) as $email) {
$email = strtolower(trim((string) $email));
if ($email === '') {
continue;
}
$uniqueCc[$email] = true;
$totalCcHits++;
}
foreach (($item['bcc'] ?? []) as $email) {
$email = strtolower(trim((string) $email));
if ($email === '') {
continue;
}
$uniqueBcc[$email] = true;
$totalBccHits++;
}
} elseif ($status === 'skipped') {
$byPolicyType[$policyType]['skipped']++;
$policiesWithoutEmail++;
$skippedPolicies[] = $compact;
}
}
$targetDate = date('Y-m-d', strtotime('+' . max(0, (int) $config->getDaysBefore()) . ' days'));
$headline = sprintf(
'DRY RUN — %d policy(ies) pending for renewal reminder: %d ready to mail, %d skipped (no email), %d failed | client email in TO: %d, missing client email: %d',
$candidateCount,
$wouldSendCount,
$skippedCount,
$failedCount,
$policiesWithClientEmailInTo,
$policiesMissingClientEmail
);
$lines = [
'Policies pending for renewal reminder: ' . $candidateCount,
'Policies ready to mail: ' . $wouldSendCount,
'Policies skipped (no valid email): ' . $skippedCount,
'Policies failed during prepare: ' . $failedCount,
'Include client email enabled: ' . ($config->includeClientEmail() ? 'yes' : 'no'),
'Policies with client email in TO: ' . $policiesWithClientEmailInTo,
'Policies missing/invalid client email: ' . $policiesMissingClientEmail,
'Unique client emails in TO: ' . count($clientEmailsInTo),
'Due on target date (' . $targetDate . '): ' . $dueCount,
'Overdue policies included: ' . $overdueCount,
'Unique TO recipients: ' . count($uniqueTo),
'Unique CC recipients: ' . count($uniqueCc),
'Unique BCC recipients: ' . count($uniqueBcc),
'Total TO deliveries (per mail): ' . $totalToHits,
'Policies without policy no: ' . $policiesWithoutPolicyNo,
'Date field: ' . $config->getDateField(),
'Days before: ' . $config->getDaysBefore(),
'Include overdue: ' . ($config->includeOverdue() ? 'yes' : 'no'),
];
return [
'headline' => $headline,
'lines' => $lines,
'counts' => [
'policies_pending_renewal' => $candidateCount,
'policies_ready_to_mail' => $wouldSendCount,
'policies_skipped_no_email' => $skippedCount,
'policies_failed' => $failedCount,
'policies_due' => $dueCount,
'policies_overdue' => $overdueCount,
'policies_without_policy_no' => $policiesWithoutPolicyNo,
'policies_without_email' => $policiesWithoutEmail,
'include_client_email_enabled' => $config->includeClientEmail(),
'policies_with_client_email_in_to' => $policiesWithClientEmailInTo,
'policies_missing_client_email' => $policiesMissingClientEmail,
'unique_client_emails_in_to' => count($clientEmailsInTo),
'unique_to_recipients' => count($uniqueTo),
'unique_cc_recipients' => count($uniqueCc),
'unique_bcc_recipients' => count($uniqueBcc),
'total_to_deliveries' => $totalToHits,
'total_cc_deliveries' => $totalCcHits,
'total_bcc_deliveries' => $totalBccHits,
'mails_that_would_be_sent' => $wouldSendCount,
],
'filters' => [
'date_field' => $config->getDateField(),
'days_before' => $config->getDaysBefore(),
'target_date' => $targetDate,
'include_overdue' => $config->includeOverdue(),
'include_client_email' => $config->includeClientEmail(),
'client_types' => $config->getClientTypes(),
'configured_to_emails' => $config->getToEmails(),
'configured_cc_emails' => $config->getCcEmails(),
'configured_bcc_emails' => $config->getBccEmails(),
],
'by_policy_type' => array_values($byPolicyType),
'unique_to_emails' => array_keys($uniqueTo),
'unique_client_emails' => array_keys($clientEmailsInTo),
'unique_cc_emails' => array_keys($uniqueCc),
'unique_bcc_emails' => array_keys($uniqueBcc),
'policies_ready' => $pendingPolicies,
'policies_skipped' => $skippedPolicies,
];
}
/**
* Structured JSON for HTTP; plain array for CLI.
*
* @param array $payload
* @param bool $isCli
* @param int $httpStatus
* @return array|\CodeIgniter\HTTP\ResponseInterface
*/
protected function renewalReminderResponse(array $payload, bool $isCli, int $httpStatus = 200)
{
if ($isCli) {
return $payload;
}
return $this->respond($payload, $httpStatus);
}
/**
* Write to CI log and app myLogger for every renewal-reminder step.
*/
protected function logRenewalReminderStep(string $message): void
{
log_message('error', $message);
if ($this->myLogger) {
$this->myLogger->logme('error', $message);
}
}
/**
* @param array $data
* @param PtRenewalReminderConfig $config
* @param bool $skipMailBody Skip HTML body build (faster for dry-run)
* @return array|null
*/
protected function prepareRenewalReminderMailData(array $data, PtRenewalReminderConfig $config, bool $skipMailBody = false)
{
$logPrefix = '[PT Renewal Reminder]';
$ptId = $data['id'] ?? 'unknown';
try {
$this->logRenewalReminderStep(
$logPrefix . " Preparing mail payload for PT {$ptId}"
);
$policyNo = trim((string) ($data['policy_no'] ?? ''));
$clientName = (string) ($data['client_name'] ?? '');
$clientShortName = ! empty($data['client_short_name'])
? (string) $data['client_short_name']
: $clientName;
$clientType = (int) ($data['client_type'] ?? 0);
$clientTypeLabel = $clientType === 1 ? 'Group' : ($clientType === 2 ? 'Individual' : '');
$dateField = $config->getDateField();
$reminderRaw = $data[$dateField] ?? ($data['renewal_date'] ?? $data['policy_end_date'] ?? null);
$reminderDate = ! empty($reminderRaw) ? date('d-m-Y', strtotime((string) $reminderRaw)) : '';
$daysBefore = $config->getDaysBefore();
$isOverdue = ! empty($data['is_overdue'])
|| (! empty($reminderRaw) && strtotime((string) $reminderRaw) < strtotime(date('Y-m-d')));
$policyLabel = $policyNo !== '' ? "Policy #{$policyNo}" : 'Policy Pending';
$policyPeriod = '';
if (! empty($data['policy_start_date']) && ! empty($data['policy_end_date'])) {
$policyPeriod = date('d-m-Y', strtotime($data['policy_start_date']))
. ' to '
. date('d-m-Y', strtotime($data['policy_end_date']));
}
$subject = $isOverdue
? "Overdue Policy Renewal Reminder - {$clientShortName} | {$policyLabel} | Due {$reminderDate}"
: "Policy Renewal Reminder - {$clientShortName} | {$policyLabel} | Due {$reminderDate}";
$placeholderVars = [
'client_name' => $clientName,
'client_short_name' => $clientShortName,
'policy_no' => $policyNo !== '' ? $policyNo : 'Not Assigned',
'policy_type' => (string) ($data['policy_type'] ?? ''),
'insurer_name' => (string) ($data['insurer_name'] ?? ''),
'policy_period' => $policyPeriod,
'reminder_date' => $reminderDate,
'days_before' => (string) $daysBefore,
'client_type' => $clientTypeLabel,
];
if ($config->getMailSubject() !== '') {
$subject = $this->replaceRetailReminderPlaceholders($config->getMailSubject(), $placeholderVars);
}
$message = '';
if (! $skipMailBody) {
if (trim($config->getMailContent()) !== '') {
$message = $this->replaceRetailReminderPlaceholders($config->getMailContent(), $placeholderVars);
} else {
$message = view('pt_renewal_reminder_email_template', [
'client_name' => $clientName,
'client_type_label' => $clientTypeLabel,
'policy_no' => $policyNo !== '' ? $policyNo : 'Not Assigned',
'policy_type' => $data['policy_type'] ?? '',
'insurer_name' => $data['insurer_name'] ?? '',
'policy_period' => $policyPeriod,
'reminder_date' => $reminderDate,
'days_before' => $daysBefore,
'is_overdue' => $isOverdue,
'generated_on' => date('d-m-Y H:i'),
]);
}
}
$toMails = [];
$clientEmailRaw = trim((string) ($data['client_email'] ?? ''));
$clientEmailIncluded = false;
$clientEmailSource = [];
$branchHrSource = [];
$configuredToSource = [];
// Retail (individual) and group: when enabled, add clients.email to TO
if ($config->includeClientEmail()) {
if ($clientEmailRaw !== '' && filter_var($clientEmailRaw, FILTER_VALIDATE_EMAIL)) {
$toMails[] = $clientEmailRaw;
$clientEmailIncluded = true;
$clientEmailSource[] = $clientEmailRaw;
$this->logRenewalReminderStep(
$logPrefix . " PT {$ptId}: added client email to TO: {$clientEmailRaw}"
. ' | client_type=' . $clientType
);
} else {
$this->logRenewalReminderStep(
$logPrefix . " PT {$ptId}: includeClientEmail=true but client email missing/invalid"
. ' | client_type=' . $clientType
. ' | client_email=' . json_encode($clientEmailRaw)
);
}
} else {
$this->logRenewalReminderStep(
$logPrefix . " PT {$ptId}: includeClientEmail=false — client email not added to TO"
);
}
if ($clientType === 1) {
$branchId = (int) ($data['client_branch_id'] ?? 0);
if ($branchId > 0) {
$db = \Config\Database::connect();
$branchHrEmails = $db->table('level_contacts')
->select('email')
->where('ref_id', $branchId)
->where('contact_type', 'client')
->where('is_active', 1)
->where('email IS NOT NULL', null, false)
->where("TRIM(email) != ''", null, false)
->get()
->getResultArray();
$hrList = [];
foreach ($branchHrEmails as $branchHrEmailRow) {
$hrEmail = trim((string) ($branchHrEmailRow['email'] ?? ''));
if ($hrEmail !== '' && filter_var($hrEmail, FILTER_VALIDATE_EMAIL)) {
$toMails[] = $hrEmail;
$branchHrSource[] = $hrEmail;
$hrList[] = $hrEmail;
}
}
$this->logRenewalReminderStep(
$logPrefix . " PT {$ptId}: branch HR emails for branch_id={$branchId}: "
. json_encode($hrList)
);
} else {
$this->logRenewalReminderStep(
$logPrefix . " PT {$ptId}: group client has no client_branch_id for HR lookup"
);
}
}
foreach ($config->getToEmails() as $envToEmail) {
$envToEmail = trim((string) $envToEmail);
if ($envToEmail === '') {
continue;
}
$toMails[] = $envToEmail;
$configuredToSource[] = $envToEmail;
}
$uniqueTo = [];
foreach ($toMails as $email) {
$email = trim((string) $email);
if ($email === '' || ! filter_var($email, FILTER_VALIDATE_EMAIL)) {
continue;
}
$emailKey = strtolower($email);
if (! isset($uniqueTo[$emailKey])) {
$uniqueTo[$emailKey] = $email;
}
}
$toMails = array_values($uniqueTo);
$fromMail = $config->getFromMail();
if ($fromMail === '') {
$fromMail = (string) (getenv('email.fromEmail') ?: '');
}
$this->logRenewalReminderStep(
$logPrefix . " PT {$ptId}: final recipients"
. ' | to=' . json_encode($toMails)
. ' | cc=' . json_encode($config->getCcEmails())
. ' | bcc=' . json_encode($config->getBccEmails())
. ' | from=' . $fromMail
. ' | subject=' . $subject
. ' | client_email_included=' . ($clientEmailIncluded ? 'true' : 'false')
);
return [
'to_mail' => $toMails,
'cc' => $config->getCcEmails(),
'bcc' => $config->getBccEmails(),
'from_mail' => $fromMail,
'message' => $message,
'subject' => $subject,
'client_email' => $clientEmailRaw !== '' ? $clientEmailRaw : null,
'client_email_included' => $clientEmailIncluded,
'include_client_email_enabled' => $config->includeClientEmail(),
'recipient_sources' => [
'client_email' => $clientEmailSource,
'branch_hr' => array_values(array_unique($branchHrSource)),
'configured_to' => array_values(array_unique($configuredToSource)),
],
];
} catch (Exception $e) {
$this->logRenewalReminderStep(
$logPrefix . " PT {$ptId}: prepareRenewalReminderMailData exception — "
. $e->getMessage()
. ' | File: ' . $e->getFile() . ' Line: ' . $e->getLine()
);
return null;
}
}
/**
* Replace {{placeholder}} tokens in retail reminder subject/body.
*
* @param array<string, string> $vars
*/
protected function replaceRetailReminderPlaceholders(string $content, array $vars): string
{
foreach ($vars as $key => $value) {
$content = str_replace('{{' . $key . '}}', (string) $value, $content);
}
return $content;
}
public function retailPolicyList()
{
$data = [
'page_name' => 'Retail Policy',
'retail_default_from_mail' => $this->resolveRetailDefaultFromMail(),
];
return $this->loadLayout('retail_policy_list', $data);
}
public function retailPolicyListData()
{
if (! $this->request->isAJAX()) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Invalid request.',
]);
}
$draw = (int) ($this->request->getPost('draw') ?? 0);
$start = max(0, (int) ($this->request->getPost('start') ?? 0));
$length = (int) ($this->request->getPost('length') ?? 10);
$search = trim((string) ($this->request->getPost('search')['value'] ?? ''));
$result = $this->policyTransactionModel->getRetailPolicyList($draw, $start, $length, $search);
$rows = [];
foreach ($result['data'] as $index => $row) {
$status = strtolower(trim((string) ($row['renewal_status'] ?? '')));
if ($status === '') {
$status = 'pending';
}
// Treat legacy "reminded" the same as renewal_mail_send
if ($status === 'reminded') {
$status = 'renewal_mail_send';
}
if ($status === 'renewal_mail_send') {
$statusHtml = '<span class="badge badge-info renewal-status-badge">Mail Sent</span>';
} elseif ($status === 'renewed') {
$statusHtml = '<span class="badge badge-success renewal-status-badge">Renewed</span>';
} else {
$statusHtml = '<span class="badge badge-warning renewal-status-badge">Pending</span>';
}
$actionHtml = '-';
if ($status === 'renewal_mail_send') {
$ptId = (int) ($row['id'] ?? 0);
$actionHtml = '<button type="button" class="btn btn-sm btn-success waves-effect waves-light btn-mark-renewed" data-id="'
. $ptId . '" title="Mark as Renewed">'
. '<i class="mdi mdi-check-circle-outline"></i> Renewed</button>';
}
$rows[] = [
$start + $index + 1,
esc($row['policy_no'] ?? '-'),
esc($row['policy_type'] ?? '-'),
esc($row['client_name'] ?? '-'),
esc($row['client_mobile'] ?? '-'),
esc($row['client_email'] ?? '-'),
! empty($row['renewal_date']) ? $this->formatRetailDisplayDate($row['renewal_date']) : '-',
$this->formatRetailPolicyPeriod($row),
$statusHtml,
$actionHtml,
];
}
return $this->response->setJSON([
'draw' => $result['draw'],
'recordsTotal' => $result['recordsTotal'],
'recordsFiltered' => $result['recordsFiltered'],
'data' => $rows,
]);
}
public function markRetailPolicyRenewed()
{
if (! $this->request->isAJAX()) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Invalid request.',
]);
}
$ptId = (int) ($this->request->getPost('id') ?? 0);
if ($ptId <= 0) {
return $this->respond([
'status' => false,
'message' => 'Invalid policy id.',
], 400);
}
$row = $this->policyTransactionModel->find($ptId);
if (empty($row) || (int) ($row['is_active'] ?? 0) !== 1) {
return $this->respond([
'status' => false,
'message' => 'Policy not found.',
], 404);
}
$currentStatus = strtolower(trim((string) ($row['renewal_status'] ?? '')));
if (! in_array($currentStatus, ['renewal_mail_send', 'reminded'], true)) {
return $this->respond([
'status' => false,
'message' => 'Only policies with mail sent status can be marked as renewed.',
], 400);
}
try {
$this->policyTransactionModel->update($ptId, [
'renewal_status' => 'renewed',
]);
} catch (Exception $e) {
return $this->respond([
'status' => false,
'message' => 'Failed to update status.',
], 500);
}
return $this->respond([
'status' => true,
'message' => 'Policy marked as renewed.',
], 200);
}
public function getRetailReminderConfig()
{
$row = $this->getOrCreateRetailReminderNotification();
$configJson = [];
if (! empty($row['config_json'])) {
$decoded = json_decode($row['config_json'], true);
if (is_array($decoded)) {
$configJson = $decoded;
}
}
/** @var PtRenewalReminderConfig $config */
$config = config(PtRenewalReminderConfig::class);
$merged = array_merge($config->toArray(), $configJson);
$merged['clientTypes'] = [2];
$merged = $this->normalizeRetailReminderConfigForUi($merged);
return $this->respond([
'status' => true,
'message' => 'Config loaded',
'data' => $merged,
'notification_id' => $row['id'] ?? null,
], 200);
}
public function saveRetailReminderConfig()
{
$row = $this->getOrCreateRetailReminderNotification();
$payload = [
'enabled' => $this->request->getPost('enabled'),
'daily' => $this->request->getPost('daily'),
'days' => trim((string) $this->request->getPost('days')),
'clientTypes' => [2],
'dateField' => trim((string) $this->request->getPost('dateField')),
'daysBefore' => (int) $this->request->getPost('daysBefore'),
'includeClientEmail' => $this->request->getPost('includeClientEmail'),
'includeOverdue' => $this->request->getPost('includeOverdue'),
'toEmails' => trim((string) $this->request->getPost('toEmails')),
'ccEmails' => trim((string) $this->request->getPost('ccEmails')),
'bccEmails' => trim((string) $this->request->getPost('bccEmails')),
'fromMail' => trim((string) $this->request->getPost('fromMail')),
];
$payload['enabled'] = in_array(strtolower((string) $payload['enabled']), ['1', 'true', 'on', 'yes'], true);
$payload['daily'] = in_array(strtolower((string) $payload['daily']), ['1', 'true', 'on', 'yes'], true);
$payload['includeClientEmail'] = in_array(strtolower((string) $payload['includeClientEmail']), ['1', 'true', 'on', 'yes'], true);
$payload['includeOverdue'] = in_array(strtolower((string) $payload['includeOverdue']), ['1', 'true', 'on', 'yes'], true);
if (! in_array($payload['dateField'], ['renewal_date', 'policy_end_date'], true)) {
$payload['dateField'] = 'renewal_date';
}
$payload['daysBefore'] = max(0, $payload['daysBefore']);
$updated = $this->notificationModel->update((int) $row['id'], [
'config_json' => json_encode($payload),
'enabled' => $payload['enabled'] ? 1 : 0,
]);
if ($updated === false && ! empty($this->notificationModel->errors())) {
return $this->respond([
'status' => false,
'message' => 'Failed to save mail config',
'errors' => $this->notificationModel->errors(),
], 500);
}
return $this->respond([
'status' => true,
'message' => 'Mail config saved successfully',
'data' => $payload,
], 200);
}
/**
* @param array<string, mixed> $config
* @return array<string, mixed>
*/
protected function normalizeRetailReminderConfigForUi(array $config): array
{
if (is_array($config['days'] ?? null)) {
$config['days'] = implode(',', $config['days']);
}
foreach (['toEmails', 'ccEmails', 'bccEmails'] as $field) {
if (is_array($config[$field] ?? null)) {
$config[$field] = implode(',', $config[$field]);
}
}
if (trim((string) ($config['fromMail'] ?? '')) === '') {
$config['fromMail'] = $this->resolveRetailDefaultFromMail();
}
return $config;
}
protected function resolveRetailDefaultFromMail(): string
{
$from = trim((string) env('pt.renewalReminder.fromMail', ''));
if ($from !== '') {
return $from;
}
$from = trim((string) env('email.fromEmail', ''));
if ($from !== '') {
return $from;
}
return trim((string) (getenv('email.fromEmail') ?: ''));
}
/**
* @param array<string, mixed> $row
*/
protected function formatRetailPolicyPeriod(array $row): string
{
$start = trim((string) ($row['policy_start_date'] ?? ''));
$end = trim((string) ($row['policy_end_date'] ?? ''));
if ($start !== '' && $end !== '') {
return $this->formatRetailDisplayDate($start) . ' to ' . $this->formatRetailDisplayDate($end);
}
if ($end !== '') {
return $this->formatRetailDisplayDate($end);
}
if ($start !== '') {
return $this->formatRetailDisplayDate($start);
}
return '-';
}
protected function formatRetailDisplayDate(?string $date): string
{
$date = trim((string) $date);
if ($date === '') {
return '-';
}
$timestamp = strtotime($date);
if ($timestamp === false) {
return $date;
}
return date('d/m/Y', $timestamp);
}
public function getRetailReminderTemplate()
{
$row = $this->getOrCreateRetailReminderNotification();
return $this->respond([
'status' => true,
'message' => 'Template loaded',
'data' => [
'id' => $row['id'] ?? null,
'template_name' => $row['template_name'] ?? PtRenewalReminderConfig::TEMPLATE_NAME,
'subject' => $row['subject'] ?? '',
'mail_content' => $row['mail_content'] ?? '',
'mail_content_json'=> $row['mail_content_json'] ?? '',
'enabled' => (int) ($row['enabled'] ?? 0),
],
], 200);
}
public function saveRetailReminderTemplate()
{
$row = $this->getOrCreateRetailReminderNotification();
$subject = trim((string) $this->request->getPost('subject'));
$mailContent = (string) (
$this->request->getPost('mailContent') ?? $this->request->getPost('mail_content') ?? ''
);
$mailJson = (string) (
$this->request->getPost('mailJson') ?? $this->request->getPost('mail_content_json') ?? ''
);
$updated = $this->notificationModel->update((int) $row['id'], [
'subject' => $subject,
'mail_content' => $mailContent,
'mail_content_json' => $mailJson !== '' ? $mailJson : null,
'updated_by' => get_session_userid(),
]);
if ($updated === false && ! empty($this->notificationModel->errors())) {
return $this->respond([
'status' => false,
'message' => 'Failed to save email template',
'errors' => $this->notificationModel->errors(),
], 500);
}
return $this->respond([
'status' => true,
'message' => 'Email template saved successfully',
], 200);
}
public function sendRetailReminderTestMail()
{
if (! $this->request->isAJAX()) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Invalid request.',
]);
}
$testEmail = trim((string) (
$this->request->getPost('test_email') ?? $this->request->getPost('testEmail') ?? ''
));
$subject = trim((string) $this->request->getPost('subject'));
$mailContent = (string) (
$this->request->getPost('mailContent') ?? $this->request->getPost('mail_content') ?? ''
);
if ($testEmail === '' || ! filter_var($testEmail, FILTER_VALIDATE_EMAIL)) {
return $this->respond([
'status' => false,
'message' => 'Please enter a valid email address.',
], 400);
}
if ($subject === '') {
return $this->respond([
'status' => false,
'message' => 'Subject is required.',
], 400);
}
if (trim(strip_tags($mailContent)) === '') {
return $this->respond([
'status' => false,
'message' => 'Mail content is empty.',
], 400);
}
$sampleVars = [
'client_name' => 'Ravi Kumar',
'client_short_name' => 'Ravi',
'policy_no' => 'RET-TEST-1001',
'policy_type' => 'Individual Health',
'insurer_name' => 'Sample Insurer',
'policy_period' => '01/04/2026 to 31/03/2027',
'reminder_date' => date('d/m/Y', strtotime('+30 days')),
'days_before' => '30',
'client_type' => 'Individual',
];
$finalSubject = $this->replaceRetailReminderPlaceholders($subject, $sampleVars);
$finalMessage = $this->replaceRetailReminderPlaceholders($mailContent, $sampleVars);
$fromMail = $this->resolveRetailDefaultFromMail();
$payload = [
'mail' => [$testEmail],
'subject' => '[TEST] ' . $finalSubject,
'message' => $finalMessage,
'common' => ['mail_type' => 'pt_renewal_reminder_test_mail'],
];
if ($fromMail !== '') {
$payload['from_mail'] = $fromMail;
}
try {
$rawRes = MailHelper::send_email($payload);
$res = json_decode($rawRes);
if (isset($res->status) && $res->status === 'success') {
return $this->respond([
'status' => true,
'message' => 'Test mail sent to ' . $testEmail,
'to' => $testEmail,
], 200);
}
return $this->respond([
'status' => false,
'message' => 'Failed to send test mail.',
'mail_response' => $res,
], 500);
} catch (Exception $e) {
return $this->respond([
'status' => false,
'message' => 'Failed to send test mail.',
], 500);
}
}
/**
* @return array
*/
protected function getOrCreateRetailReminderNotification(): array
{
$row = $this->notificationModel
->where('template_name', PtRenewalReminderConfig::TEMPLATE_NAME)
->groupStart()
->where('client_id', null)
->orWhere('client_id', 0)
->orWhere('client_id', '')
->groupEnd()
->orderBy('id', 'DESC')
->first();
if (! empty($row)) {
return $row;
}
$defaultConfig = [
'enabled' => true,
'daily' => true,
'days' => 'mon,tue,wed,thu,fri',
'clientTypes' => [2],
'dateField' => 'renewal_date',
'daysBefore' => 30,
'includeClientEmail' => true,
'includeOverdue' => false,
'toEmails' => '',
'ccEmails' => '',
'bccEmails' => '',
'fromMail' => '',
];
$insertId = $this->notificationModel->insert([
'client_id' => null,
'template_name' => PtRenewalReminderConfig::TEMPLATE_NAME,
'subject' => 'Policy Renewal Reminder',
'mail_content' => '',
'enabled' => 1,
'config_json' => json_encode($defaultConfig),
]);
return $this->notificationModel->find($insertId) ?? [
'id' => $insertId,
'template_name' => PtRenewalReminderConfig::TEMPLATE_NAME,
'subject' => 'Policy Renewal Reminder',
'mail_content' => '',
'config_json' => json_encode($defaultConfig),
'enabled' => 1,
];
}
public function getMoreInfo()
{
$pt_id = $this->request->getPost("pt_id");
$data_to_send['bds_data'] = $this->BdsPlacementModel->where("is_active", 1)->where("pt_id", $pt_id)->findAll();
foreach ($data_to_send['bds_data'] as &$data) {
$data['payment_date'] = (new \DateTime($data['payment_date']))->format('d-m-Y');
}
if (!empty($data_to_send)) {
return $this->respond(['status' => true, "data" => $data_to_send], 200);
} else {
return $this->respond(['status' => false, "No Data Found For the Policy Transaction"], 404);
}
}
public function saveInstallment()
{
$installments = $this->request->getPost('installments');
if (!$installments || !is_array($installments)) {
return $this->respond(['status' => false, 'message' => 'No data received'], 400);
}
$this->myLogger->logme("error", json_encode($installments));
// die();
foreach ($installments as &$row) {
// Convert date from d-m-Y to Y-m-d
if (!empty($row['payment_date'])) {
$date = \DateTime::createFromFormat('d-m-Y', $row['payment_date']);
if ($date) {
$row['payment_date'] = $date->format('Y-m-d');
}
}
$this->BdsPlacementModel->save($row);
}
return $this->respond(['status' => true, 'message' => 'Data saved successfully'], 200);
}
protected function getPolicyForEndorsment()
{
$policyList = [];
$policyListByClient = [];
$clients = $this->clientModel
->select("*, DATE_FORMAT(dob, '%d-%m-%Y') as dob")
->where('is_active', 1)
->findAll();
$clientIds = array_column($clients, 'id');
// $policies = $this->clientPolicyModel
// ->select("
// client_policy.*,
// policy_type.policy_type,
// policy_type.ebp,
// policy_type.etp,
// policy_type.iep,
// policy_type.itp,
// policy_type.bap,
// policy_type.allocg,
// DATE_FORMAT(client_policy.policy_start_date, '%d/%m/%Y') as policy_start_date,
// DATE_FORMAT(client_policy.policy_end_date, '%d/%m/%Y') as policy_end_date
// ")
// ->join('policy_type', 'policy_type.id = client_policy.policy_type_id')
// ->join('policy_transaction pt', 'pt.client_policy_id = client_policy.id and pt.action_type = "inception" and pt.is_active = 1 and pt.client_policy_id is not null')
// ->whereIn('client_policy.client_id', $clientIds)
// ->where('client_policy.is_active', 1)
// ->findAll();
// Only columns needed for policy_transaction_endorsement_list appendPolicies() JSON — not policy_transaction.*
// (full rows + json_encode duplicated memory and exceeded PHP memory_limit on large datasets).
$policies = $this->policyTransactionModel
->select("
policy_transaction.id,
policy_transaction.client_id,
policy_transaction.client_branch_id,
policy_transaction.policy_no,
policy_transaction.policy_type_id,
policy_transaction.insurer_id,
policy_transaction.insurer_branch_id,
policy_transaction.tpa_id,
policy_transaction.tpa_branch_id,
policy_transaction.cd_ac_no,
policy_type.policy_type,
policy_type.ebp,
policy_type.etp,
policy_type.iep,
policy_type.itp,
policy_type.bap,
policy_type.allocg,
DATE_FORMAT(policy_transaction.policy_start_date, '%d/%m/%Y') as policy_start_date,
DATE_FORMAT(policy_transaction.policy_end_date, '%d/%m/%Y') as policy_end_date
")
->join('policy_type', 'policy_type.id = policy_transaction.policy_type_id')
->whereIn('policy_transaction.client_id', $clientIds)
->where('policy_transaction.is_active', 1)
->where('policy_transaction.action_type', "inception")
->findAll();
foreach ($policies as $policy) {
$policyList[$policy['client_branch_id']][] = $policy;
$policyListByClient[$policy['client_id']][] = $policy;
}
return [$policyList, $policyListByClient];
}
public function reportBDSNew()
{
// 🧭 Basic Page Info
$data['tab_name'] = 'BDS Report';
$data['page_name'] = 'BDS Report';
// 📋 Dropdown Data
$data['issuer'] = [1 => 'JIBS', 2 => 'Nhance'];
$data['client_type'] = [1 => 'Group', 2 => 'Individual'];
$data['issuing_type'] = [1 => 'Fresh', 2 => 'Renewal', 3 => 'Roll Over'];
$data['policy_status'] = [
'pending' => 'Pending',
'exported_to_insurer' => 'Exported to Insurer',
'imported_from_insurer'=> 'Imported from Insurer',
'exported_to_tpa' => 'Exported to TPA',
'imported_from_tpa' => 'Imported from TPA',
'completed' => 'Completed'
];
$data['invoice_status_array'] = [
'yet_to_generate' => 'Yet to Generate',
'generated' => 'Generated',
'send' => 'Send',
'recived' => 'Recived',
];
$data['date_type'] = [
'policy_issue_date' => 'Policy Issue Date',
'policy_start_date' => 'Policy Start Date',
'policy_end_date' => 'Policy End Date',
'data_received_date' => 'Data Received Date',
'closure_date' => 'Closure Date',
'statement_month' => 'Statement Month',
];
// 🏢 Fetch Active Data
$data['insurer'] = $this->insurerModel->where('is_active', 1)->findAll();
$data['policy_types'] = $this->policyTypeModel->where('is_active', 1)->findAll();
$data['clients'] = $this->clientModel->where('is_active', 1)->findAll();
$data['users'] = $this->userModel->where('is_active', 1)->findAll();
$data['policy_count'] = $this->policyTransactionModel->where('is_active', 1)->countAllResults();
// 🕐 Filters
$start_date = $this->request->getGet('start_date');
$end_date = $this->request->getGet('end_date');
$client_id = $this->request->getGet('client_id');
$insurer_id = $this->request->getGet('insurer_id');
$policy_type_id = $this->request->getGet('policy_type_id');
$date_type = $this->request->getGet('date_type');
$issuer = $this->request->getGet('issuer');
$client_branch_id = $this->request->getGet('client_branch_id');
$insurer_branch_id = $this->request->getGet('insurer_branch_id');
$client_policy_id = $this->request->getGet('client_policy_id');
$user_id = $this->request->getGet('user_id');
// Handle statement month range
if ($date_type == 'statement_month') {
$start_date = (string) date('Y-m-01', strtotime($start_date));
$end_date = (string) date('Y-m-t', strtotime($end_date));
}
// Ensure default values
$start_date = $start_date ?: 0;
$end_date = $end_date ?: 0;
$client_id = $client_id ?: 0;
$insurer_id = $insurer_id ?: 0;
$policy_type_id = $policy_type_id ?: 0;
$date_type = $date_type ?: 0;
$issuer = $issuer ?: 0;
$client_branch_id = $client_branch_id ?: 0;
$insurer_branch_id = $insurer_branch_id ?: 0;
$client_policy_id = $client_policy_id ?: 0;
$user_id = $user_id ?: 0;
// 🧾 Handle POST requests (Dashboard filters)
if ($this->request->is('post')) {
$isFromDashboard = $this->request->getPost('is_dashboard');
if (!empty($isFromDashboard) && $isFromDashboard == 1) {
$ids = array_filter(explode(',', $this->request->getPost('ids')));
if (!empty($ids)) {
$idsStr = implode(',', array_map('intval', $ids)); // sanitize IDs
$where = "policy_transaction.id IN ($idsStr)";
} else {
$where = []; // No valid IDs
}
}
}
// 📊 Fetch report data
$data['report_list'] = $this->policyTransactionModel->reportBDSNew(
$start_date,
$end_date,
$client_id,
$insurer_id,
$policy_type_id,
$date_type,
$issuer,
$client_branch_id,
$insurer_branch_id,
$client_policy_id,
$user_id,
$where ?? ''
);
$data['list_new'] = true;
// 🧩 Load View
$this->loadLayout('report_bds_filter', $data);
}
// ------------ BDS BULK MOTER POLICY UPLOAD -----------------------------------------------------------------------------------------------
public function policyBulkUpload()
{
$data['page_name'] = "BDS Bulk File Upload";
$data['tab_name'] = "BDS File Upload";
// $response = $this->insertBulkBdsData(['file_id' => 17]);
// dd($response);
if ($this->request->is('get')) {
$data['bds_dump_file_data'] = $this->bdsDumpModel
->select('
bds_dump_files.id as file_id,
bds_dump_files.file_name,
bds_dump_files.status,
bds_dump_files.created_at,
bds_dump_files.created_by,
up.first_name as user_name
')
->join('user_profiles as up', 'bds_dump_files.created_by = up.id', 'left')
->where('bds_dump_files.is_active', 1)
->orderBy('bds_dump_files.id', 'desc')
->findAll();
if (in_array(get_role_id(), [2, 3, 4])) {
$data['bds_dump_file_data'] = array_values(array_filter($data['bds_dump_file_data'], function ($file) {
return (int) ($file['created_by'] ?? 0) === (int) get_session_userid();
}));
}
return $this->loadLayout('bds_dump_file_list', $data);
} else {
$filename = '';
$fileSize = '';
//validate uploaded file
$validated = $this->validate([
'bds_dump_list' => [
'uploaded[bds_dump_list]',
'mime_in[bds_dump_list,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.oasis.opendocument.spreadsheet]',
'max_size[bds_dump_list,16384]',
],
]);
if ($validated) {
$avatar = $this->request->getFile('bds_dump_list');
if (!$avatar) {
$this->myLogger->logme("error", 'File not found');
return $this->respond(['status' => false, 'code' => 400, 'message' => 'File not found'], 400);
}
$filename = storage_file_Upload($avatar, WRITEPATH . 'uploads/bds_dump_excel/', UPLOAD_EXT_EXCEL);
if ($filename !== '') {
$fileSize = method_exists($avatar, 'getSize') ? ($avatar->getSize() / (1024 * 1024)) : 0;
$this->myLogger->logme("error", 'File move successful');
} else {
$this->myLogger->logme("error", 'File move failed');
return $this->respond(['status' => false, 'code' => 500, 'message' => 'File move failed'], 500);
}
} else {
$this->myLogger->logme("error", 'Upload failed Invalid file');
return $this->respond(['status' => false, 'code' => 404, 'message' => 'Invalid file'], 404);
}
$status = 'inprogress';
$insert_data = [
'file_name' => $filename,
'status' => $status,
'created_by' => get_session_userid()
];
$file_id = $this->bdsDumpModel->insert($insert_data);
$this->myLogger->logme("error", 'claim_dumb_file_id : {file_id}, uploaded success', ['file_id' => $file_id]);
//after file upload success than call the file formate validation
// $response = $this->bdsDumpExcelFileFormatValidation(["file_id" => $file_id]);
$r = Jobs::addJob(['job_name' => 'bdsDumpExcelFileFormatValidation', 'payload' => ['file_id' => $file_id]]);
return $this->respond(['status' => true, 'code' => 200, 'message' => 'File uploaded successfully. File being validated'], 200);
}
}
public function downloadBDSDumpFile($file_id)
{
$file_data = $this->bdsDumpModel->where('id', $file_id)->first();
if (empty($file_data) || empty($file_data['file_name'])) {
$data['message'] = 'File record not found';
return view('errors/404', $data);
}
$fileName = basename((string) $file_data['file_name']);
$storage = \Config\Services::getFileStorageService();
$result = $storage->download(WRITEPATH . 'uploads/bds_dump_excel', $fileName);
try {
if ($result['success'] ?? false) {
$downloadAs = storage_upload_display_name($fileName);
if (! empty($result['path']) && is_file($result['path'])) {
return $this->response->download($result['path'], null)->setFileName($downloadAs);
}
if (! empty($result['content'])) {
return $this->response->download($downloadAs, $result['content'])->setFileName($downloadAs);
}
}
$data['message'] = 'The Physical File Not Found';
return view('errors/404', $data);
} catch (\Exception $e) {
$this->myLogger->logme('error', $e->getMessage());
$data['message'] = 'The Physical File Not Found';
return view('errors/404', $data);
}
}
public function bdsDumpExcelFileFormatValidation($params)
{
helper('excel_util_helper');
$file_id = $params['file_id'];
$file = $this->bdsDumpModel->where("id", $file_id)->first();
$return = [];
if (empty($file)) {
return array('status' => false, 'message' => 'File not found in Database');
}
$file_name_with_path = storage_ensure_local_file(WRITEPATH . 'uploads/bds_dump_excel', $file['file_name']);
//check physical file exist
if (!file_exists($file_name_with_path)) {
$message = "Physcial file not found";
$this->myLogger->logme('error', ($message . ' for file id : ' . $file_id));
$this->bdsDumpModel->where('id', $file_id)->set(['status' => 'failed', 'reason' => json_encode(['error_summary' => array_count_values([5]), 'error_data' => $message])])->update();
return array('error_summary' => [5], 'error_data' => $message);
}
// get the BDS dump excel colums
$columns_to_check = $this->bds_bulk_upload_excel_file_column;
$keys = array_keys($columns_to_check);
$allowedHighestColumn = end($columns_to_check);
// Read the excel file
$excel_data = $this->extractExcelData($file['file_name'], $allowedHighestColumn['col_cell_name']);
$excel_columns = ($excel_data[0]);
// echo '<pre>'; var_dump($excel_columns);
//check no of columns in excel
$total_defined_columns = count($columns_to_check);
$excel_columns_count = count($excel_columns);
if($total_defined_columns != $excel_columns_count)
{
//columns count mismatch
$message = "File columns count mismatch. Expected - $total_defined_columns and received - $excel_columns_count";
$this->myLogger->logme('error',($message . ' for file id ' . $file_id));
$this->bdsDumpModel->where('id', $file_id)->set(['status' => 'failed','reason' => json_encode(['error_summary' => array_count_values([5]),'error_data' => $message])])->update();
return array('error_summary' => [5], 'error_data' => $message);
}
//check columns order in excel
$column_count_res = check_columns_name($columns_to_check, $excel_columns);
if(isset($column_count_res) && count($column_count_res))
{
//columns count mismatch
$message = implode("\n", $column_count_res);
$this->myLogger->logme('error',($message . ' for file id ' . $file_id));
$this->bdsDumpModel->where('id', $file_id)->set(['status' => 'failed','reason' => json_encode(['error_summary' => array_count_values([6]), 'error_data' => $message])])->update();
return array('error_summary' => [6], 'error_data' => $message);
}
//Store the error data by this structure
$result = ['error_type' => 1, 'error_summary' => [], 'error_data' => []];
$insurer_data = $this->insurerModel->where('is_active', 1)->findAll();
$insurer_branch_data = $this->insurerBranchModel->where('is_active', 1)->findAll();
$pt_data = $this->policyTransactionModel->where('is_active', 1)->findAll();
$user_data = $this->userModel->where('is_active', 1)->findAll();
$agent_data = db_connect()->table('partner_agent')->where('is_active', 1)->get()->getResultArray();
$pos_data = db_connect()->table('partner_pos')->where('is_active', 1)->get()->getResultArray();
$rto_master = db_connect()->table('rto_master')->where('is_active', 1)->get()->getResultArray();
$vehicle_type = db_connect()->table('vehicle_type')->where('is_active', 1)->get()->getResultArray();
$nhance_branch_data = db_connect()->table('nhance_branch')->where('is_active', 1)->get()->getResultArray();
//remove header
unset($excel_data[0]);
try {
foreach ($excel_data as $row_key => $row) {
//avoid empty rows
if (check_row_is_empty_or_null($row)) {
break;
}
$insurers = [];
foreach ($row as $col_key => $col)
{
$is_mandatory = $columns_to_check[$keys[$col_key]]['is_mandatory'];
$format = $columns_to_check[$keys[$col_key]]['format'];
$data_type = $columns_to_check[$keys[$col_key]]['data_type'];
$allowed_values = $columns_to_check[$keys[$col_key]]['allowed_values'];
$custom_function = isset($columns_to_check[$keys[$col_key]]['custom']) ? $columns_to_check[$keys[$col_key]]['custom'] : null;
$binding_params = isset($columns_to_check[$keys[$col_key]]['params']) ? $columns_to_check[$keys[$col_key]]['params'] : null;
$column_dispaly_name = $columns_to_check[$keys[$col_key]]['col_name'];
$column_index = $columns_to_check[$keys[$col_key]]['col_idx'];
$column_cell = $columns_to_check[$keys[$col_key]]['col_cell_name'];
//mandatory check
if(is_bool($is_mandatory) && $is_mandatory === true)
{
if($col == "" || $col == NULL)
{
array_push($result['error_summary'],1); //push error code for summary
$result['error_data'][$row_key][$keys[$col_key]]['col_name'] = $column_dispaly_name; //push column name
$result['error_data'][$row_key][$keys[$col_key]]['col_idx'] = $column_index; //push column index
$result['error_data'][$row_key][$keys[$col_key]]['error'][] = 'Value is mandatory'; //push exact error desc
}
}
//format check
if(isset($format))
{
$validation = validate_excel_value($col, $data_type, $format, $allowed_values);
if (!$validation['status']) {
array_push($result['error_summary'], 2);
$result['error_data'][$row_key][$keys[$col_key]]['col_name'] = $column_dispaly_name;
$result['error_data'][$row_key][$keys[$col_key]]['col_idx'] = $column_index;
$result['error_data'][$row_key][$keys[$col_key]]['error'][] = $validation['error'];
}
}
//allowed values check
if(($is_mandatory === true && isset($allowed_values) && is_array($allowed_values)) || (is_array($is_mandatory) && (isset($allowed_values) && is_array($allowed_values))))
{
if(!in_array((trim($col)),$allowed_values))
{
array_push($result['error_summary'],3);
$result['error_data'][$row_key][$keys[$col_key]]['col_name'] = $column_dispaly_name; //push column name
$result['error_data'][$row_key][$keys[$col_key]]['col_idx'] = $column_index; //push column index
$result['error_data'][$row_key][$keys[$col_key]]['error'][] = "Value not allowed: Expected ".implode(",",$allowed_values)." and received $col";
}
}
//custom function check
if(isset($custom_function))
{
//convert string params into PHP variables
// Create an array of variables to pass custom helper funcitons
$param_values = [];
foreach($binding_params as $bkey => $bparam) { $param_values[] = ($$bparam); }
$res = call_user_func_array($custom_function,$param_values);
if($res['status'] === false) {
array_push($result['error_summary'],4);
$result['error_data'][$row_key][$keys[$col_key]]['col_name'] = $column_dispaly_name; //push column name
$result['error_data'][$row_key][$keys[$col_key]]['col_idx'] = $column_index; //push column index
$result['error_data'][$row_key][$keys[$col_key]]['error'][] = $res['error'];
}
if($res['status'] == true && isset($res['insurer'])){
$insurers = $res['insurer'];
}
}
}//col foreach
}
} catch (\Exception $e) {
$errorDetails = [
'error_message' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'stack_trace' => $e->getTraceAsString(),
];
$message = "Contact system admin";
$this->bdsDumpModel->where('id', $file_id)->set(['status' => 'failed', 'reason' => json_encode(['error_summary' => array_count_values([5]), 'error_data' => $message])])->update();
$this->myLogger->logme("error", 'Claim dump file format validation failed due to : ' . json_encode($errorDetails ?? []));
return $errorDetails;
}
// return $result;
if (isset($result['error_summary']) && count($result['error_summary'])) {
$result['error_summary'] = array_count_values($result['error_summary']);
$status = 'failed';
$failure_reason = ((json_encode($result)));
$this->bdsDumpModel->where('id', $file_id)->set(['status' => $status, 'reason' => $failure_reason])->update();
$this->myLogger->logme("error", '{file_id} uploaded failed', ['file_id' => $file_id]);
} else { //trigger next data validation via job queue server
//proceed next data level validation in JOB queue
$r = Jobs::addJob(['job_name' => 'insertBulkBdsData', 'payload' => ['file_id' => $file_id]]);
// $response = $this->insertBulkBdsData(['file_id' => $file_id]);
}
return $result;
}
public function insertBulkBdsData($params)
{
helper('excel_util_helper');
$file_id = $params['file_id'];
$file = $this->bdsDumpModel->where("id", $file_id)->first();
$return = [];
if (empty($file)) {
return array('status' => false, 'message' => 'File not found in Database');
}
$file_name_with_path = storage_ensure_local_file(WRITEPATH . 'uploads/bds_dump_excel', $file['file_name']);
//check physical file exist
if (!file_exists($file_name_with_path)) {
$message = "Physcial file not found";
$this->myLogger->logme('error', ($message . ' for file id : ' . $file_id));
$this->bdsDumpModel->where('id', $file_id)->set(['status' => 'failed', 'reason' => json_encode(['error_summary' => array_count_values([5]), 'error_data' => $message])])->update();
return array('error_summary' => [5], 'error_data' => $message);
}
// get the BDS dump excel colums
$columns_to_check = $this->bds_bulk_upload_excel_file_column;
$keys = array_keys($columns_to_check);
$allowedHighestColumn = end($columns_to_check);
// Read the excel file
$excel_data = $this->extractExcelData($file['file_name'], $allowedHighestColumn['col_cell_name']);
$excel_columns = ($excel_data[0]);
//remove header
unset($excel_data[0]);
// dd($excel_data);
//Store the error data by this structure
$result = ['error_type' => 1, 'error_summary' => [], 'error_data' => []];
$client_data = $this->clientModel->where('is_active', 1)->where('client_type', 1)->findAll();
$insurer_data = $this->insurerModel->where('is_active', 1)->findAll();
$insurer_branch_data = $this->insurerBranchModel->where('is_active', 1)->findAll();
$vehicle_data = $this->vehicleModel->where('is_active', 1)->findAll();
$user_data = $this->userModel->where('is_active', 1)->findAll();
$agent_data = db_connect()->table('partner_agent')->where('is_active', 1)->get()->getResultArray();
$pos_data = db_connect()->table('partner_pos')->where('is_active', 1)->get()->getResultArray();
$rto_master = db_connect()->table('rto_master')->where('is_active', 1)->get()->getResultArray();
$vehicle_type_data = db_connect()->table('vehicle_type')->where('is_active', 1)->get()->getResultArray();
$nhance_branch_data = db_connect()->table('nhance_branch')->where('is_active', 1)->get()->getResultArray();
try {
$pt_ids = [];
foreach ($excel_data as $row_key => $row) {
//avoid empty rows
if (check_row_is_empty_or_null($row)) {
break;
}
$vehicle_number = trim($row[2]);
$vehicle_type = trim($row[3]);
$client_name = trim($row[5]);
$client_email = trim($row[6]);
$insurer_short_name = trim($row[7]);
$insurer_branch_code = trim($row[8]);
$salse_generated_by = trim($row[13]);
$serviced_by = trim($row[14]);
$agent_code = trim($row[15]);
$nhance_branch = trim($row[1]);
$policy_no = trim($row[4]);
$policy_issue_date = trim($row[9]);
$policy_start_date = trim($row[10]);
$policy_end_date = trim($row[11]);
$revenue_type = trim($row[12]);
$base_premium = cleanNumber($row[16]);
$non_commission_premium_amount = cleanNumber($row[17]);
$tp_premium = cleanNumber($row[18]);
$igst = cleanNumber($row[19]);
$cgst = cleanNumber($row[20]);
$sgst = cleanNumber($row[21]);
$stamp_duty = cleanNumber($row[22]);
$agreed_amount = cleanNumber($row[23]);
$agreed_bp_percentage = cleanNumber($row[24]);
$agreed_tp_percentage = cleanNumber($row[25]);
// $total = trim($row[23]);
// $actual_bp_amount = trim($row[27]);
// $actual_tp_amount = trim($row[28]);
// $actual_bp_percentage = trim($row[29]);
// $actual_tp_percentage = trim($row[30]);
// $actual_bp_brokerage_amount = trim($row[31]);
// $actual_tp_brokerage_amount = trim($row[32]);
// $expected_amount = trim($row[33]);
// $rewards = trim($row[34]);
$actual_bp_amount = 0;
$actual_tp_amount = 0;
$actual_bp_percentage = 0;
$actual_tp_percentage = 0;
$actual_bp_brokerage_amount = 0;
$actual_tp_brokerage_amount = 0;
$expected_amount = 0;
$rewards = 0;
$calculation = calculateMotorPolicyAmounts([
'base_premium' => $base_premium,
'non_commission_premium_amount' => $non_commission_premium_amount,
'tp_premium' => $tp_premium,
'igst' => $igst,
'cgst' => $cgst,
'sgst' => $sgst,
'stamp_duty' => $stamp_duty,
'agreed_amount' => $agreed_amount,
'agreed_bp_percentage' => $agreed_bp_percentage,
'agreed_tp_percentage' => $agreed_tp_percentage,
'standard_bp_percentage' => 15.00,
'standard_tp_percentage' => 2.5
]);
log_message('error', 'Motor Policy Calculation: ' . json_encode($calculation));
$current_insurer_data = check_insurer_exist($row, $insurer_data)['insurer'] ?? null;
$current_insurer_branch_data = check_insurer_branch_exist($row, $insurer_branch_data, $current_insurer_data)['branch'] ?? null;
$current_nhance_branch = check_nhance_branch($row, $nhance_branch_data)['branch'] ?? null;
// $current_agent_data = check_agent_exist($row, $agent_data)['agent'] ?? null;
$current_agent_data = check_agent_exist($row, $pos_data)['agent'] ?? null;
$salse = check_user_exist($row, 13, $user_data)['user'] ?? null;
$service = check_user_exist($row, 14, $user_data)['user'] ?? null;
$gst_amt = calculate_gst_amount($row) ?? null;
// get the client and vehicle id
$vehicle_and_client_ids = $this->getClientAndVehicleId($row, $vehicle_data, $client_data, $rto_master, $vehicle_type_data);
$vehicle_id = $vehicle_and_client_ids['vehicle_id'] ?? null;
$client_id = $vehicle_and_client_ids['client_id'] ?? null;
$policy_transaction_data = [
'issuer' => 2,
'issuer_branch' => $salse['nhance_branch_id'] ?? null,
'client_id' => $client_id,
'policy_type_id' => 8,
'insurer_id' => $current_insurer_branch_data['insurer_id'] ?? null,
'insurer_branch_id' => $current_insurer_branch_data['id'] ?? null,
'policy_no' => $policy_no,
'vehicle_id' => $vehicle_id,
'issue_type' => 1,
'policy_issue_date' => change_date_format($policy_issue_date, 'd/M/Y', 'Y-m-d'),
'policy_start_date' => change_date_format($policy_start_date, 'd/M/Y', 'Y-m-d'),
'policy_end_date' => change_date_format($policy_end_date, 'd/M/Y', 'Y-m-d'),
'action_type' => 'inception',
'revenue_type' => $revenue_type,
'co_share' => 0,
'status' => 'completed',
'renewal_date' => change_date_format($policy_end_date, 'd/M/Y', 'Y-m-d'),
'policy_holder_name' => $client_name,
'month' => change_date_format($policy_issue_date, 'd/M/Y', 'Y-m-d'),
'sales_generated_by' => $salse['id'] ?? null,
'serviced_by' => $service['id'] ?? null,
'salse_person_manager_id' => $salse['rm_id'] ?? null,
'service_person_manager_id' => $service['rm_id'] ?? null,
'service_person_branch_id' => $service['nhance_branch_id'] ?? null,
// 'agent_id' => $current_agent_data['id'] ?? null,
// 'agent_code' => $current_agent_data['agent_code'] ?? null,
'pos_id' => $current_agent_data['id'] ?? null,
'file_id' => $params['file_id'],
'created_by' => $file['created_by'] ?? null,
'endorsement_no' => null,
'client_branch_id' => null,
'client_policy_id' => null,
'ct_type' => null,
'remarks' => null,
];
$co_share_data = [
'pt_id' => null,
'insurer_id' => $current_insurer_branch_data['insurer_id'] ?? null,
'insurer_branch_id' => $current_insurer_branch_data['id'] ?? null,
'co_share_type' => 1,
'co_share_per' => 100,
'bp_amt' => $base_premium,
'bp_gst_amt' => $calculation['gst_amount'] ?? $gst_amt,
'bp_igst' => $igst ,
'bp_sgst' => $sgst,
'bp_cgst' => $cgst,
'tp_amt' => $tp_premium,
'tp_gst_amt' => 0,
'tp_igst' => 0,
'tp_sgst' => 0,
'tp_cgst' => 0,
'tep_amt' => 0,
'tep_gst_amt' => 0,
'tep_igst' => 0,
'tep_sgst' => 0,
'tep_cgst' => 0,
'agreed_amt' => $agreed_amount,
'agreed_bp_per' => $agreed_bp_percentage,
'agreed_tp_per' => $agreed_tp_percentage,
'agreed_tep_per' => 0,
'actual_bp_amt' => $actual_bp_amount,
'actual_tp_amt' => $actual_tp_amount,
'actual_tep_amt' => 0,
'actual_bp_per' => $actual_bp_percentage,
'actual_tp_per' => $actual_tp_percentage,
'actual_tep_per' => 0,
'actual_bp_brokerage_amt' => $actual_bp_brokerage_amount,
'actual_tp_brokerage_amt' => $actual_tp_brokerage_amount,
'actual_tep_brokerage_amt' => 0,
'standerd_bp_per' => 15.00,
'standerd_tp_per' => 2.50,
'agreed_tep_per' => 0,
'reward' => $rewards,
'variance' => 0,
'remark' => null,
'amount' => $calculation['total_amount'] ?? 0,
'stamp_duty' => $stamp_duty,
'cop_amt' => $base_premium,
'cotp_amt' => $tp_premium,
'cotep_amt' => 0.00,
'exp_amt' => $calculation['expected_amount'] ?? $expected_amount,
'statement_id' => null,
'follower_policy_no' => null,
'non_comm_per_amt' => $non_commission_premium_amount,
'pt_policy_issue_date' => change_date_format($policy_issue_date, 'd/M/Y', 'Y-m-d'),
'file_id' => $params['file_id'],
'created_by' => $file['created_by'] ?? null,
];
if(!empty($vehicle_id) && !empty($client_id)){
$pt_id = $this->policyTransactionModel->insert($policy_transaction_data);
if($pt_id){
$co_share_data['pt_id'] = $pt_id;
$pt_co_share_id = $this->PTCOShareDetailsModel->insert($co_share_data);
$client_policy_insert_data = $this->prepareClientPolicyInsertData($policy_transaction_data);
$client_policy_id = $this->clientPolicyModel->insert($client_policy_insert_data);
$this->policyTransactionModel->update($pt_id, ['client_policy_id' => $client_policy_id]);
$pt_ids[] = $pt_id;
$this->myLogger->logme('error', "BDS entry successfully added with pt_id : $pt_id, pt_co_share_id : $pt_co_share_id, client_policy_id :$client_policy_id");
}
}else{
$this->myLogger->logme('error', 'Skipped......... , vehicle id and client id missing');
}
}
} catch (\Exception $e) {
$errorDetails = [
'error_message' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'stack_trace' => $e->getTraceAsString(),
];
$message = "Contact system admin";
$this->bdsDumpModel->where('id', $file_id)->set(['status' => 'failed', 'reason' => json_encode(['error_summary' => array_count_values([5]), 'error_data' => $message])])->update();
$this->myLogger->logme("error", 'Claim dump file format validation failed due to : ' . json_encode($errorDetails ?? []));
return $errorDetails;
}
// return $result;
if (isset($result['error_summary']) && count($result['error_summary'])) {
$result['error_summary'] = array_count_values($result['error_summary']);
$status = 'failed';
$failure_reason = ((json_encode($result)));
$this->bdsDumpModel->where('id', $file_id)->set(['status' => $status, 'reason' => $failure_reason])->update();
$this->myLogger->logme("error", '{file_id} uploaded failed', ['file_id' => $file_id]);
} else{
$result = count($pt_ids);
$status = 'success';
$failure_reason = ((json_encode($result)));
$this->bdsDumpModel->where('id', $file_id)->set(['status' => $status, 'reason' => $failure_reason])->update();
$this->myLogger->logme("error", '{file_id} uploaded success', ['file_id' => $file_id]);
}
return $result;
}
public function extractExcelData($file_name, $highestColumn)
{
// $file_name = "claims_dump_form_client.xlsx";
// Load the Excel file
$file_name_with_path = storage_ensure_local_file(WRITEPATH . 'uploads/bds_dump_excel', $file_name);
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($file_name_with_path);
$worksheet = $spreadsheet->getActiveSheet();
// Get the highest row and column numbers
$highestRow = $worksheet->getHighestDataRow();
// $highestColumn = $worksheet->getHighestDataColumn();
// dd($highestRow, $highestColumn);
// Get header row (assuming headers are in row 1)
// $headerRow = $worksheet->rangeToArray('A1:' . $highestColumn . '1', null, true, false)[0];
$excel_data = $worksheet->rangeToArray('A1:' . $highestColumn . $highestRow);
// print_rr($excel_data); die;
//Sanitize the excel data
$excel_data = ExcelSanitizeHelper::sanitizeArrayData($excel_data);
// dd($excel_data);
// dd($data);
return $excel_data;
}
public function getBdsBulkUploadExcelErrorData($file_id)
{
try {
$file = $this->bdsDumpModel->where('id', $file_id)->first();
$error_data = json_decode($file['reason']);
// dd($error_data);
$file_name_with_path = storage_ensure_local_file(WRITEPATH . 'uploads/bds_dump_excel', $file['file_name']);
// Kint::dump(file_exists($file_name_with_path)); die;
//check the file exist or not
if (!file_exists($file_name_with_path)) {
$error_message = "File not found";
$this->myLogger->logme('error', ($error_message . ' for file id ' . $file_id));
return 0;
}
$columns_to_check = $this->bds_bulk_upload_excel_file_column;
$allowedHighestColumn = end($columns_to_check);
// Kint::dump($columns_to_check); die;
$excel_data = $this->extractExcelData($file['file_name'], $allowedHighestColumn['col_cell_name']);
$excelErrorData['excel_header'] = $excel_data[0];
unset($excel_data[0]);
// Kint::dump($excel_data); die;
if ($error_data->error_type == 1) {
$finalArray = [];
foreach ($error_data->error_data as $key => $value) {
foreach ($value as $key2 => $value2) {
$error_data = $value2->error;
$data = ['value' => $excel_data[$key][$value2->col_idx], 'error' => $error_data,];
$excel_data[$key][$value2->col_idx] = $data;
}
array_push($finalArray, $excel_data[$key]);
}
foreach ($finalArray as $fkey => $value) {
foreach ($value as $vkey => $arrayData) {
if (!is_array($arrayData)) {
$data = ['value' => $arrayData];
$finalArray[$fkey][$vkey] = $data;
}
}
}
$excelErrorData['excel_data'] = $finalArray;
return $excelErrorData;
} else if ($error_data->error_type == 2) {
$allErrors = [];
$typeTowArray = [];
foreach ($error_data->error_data as $index => $item) {
foreach ($item as $field) {
if (!isset($allErrors[$index])) {
$allErrors[$index] = [];
}
$allErrors[$index] = array_merge($allErrors[$index], $field->error);
}
}
// dd(array_keys($allErrors));
foreach ($allErrors as $key => $value) {
// echo $key;
// print_r($value);
foreach ($excel_data as $excel_data_index => $excel_data_value) {
if ($excel_data_value[0] == $key) {
$data = ['value' => $excel_data[$excel_data_index][1], 'error' => $value,];
$excel_data[$excel_data_index][1] = $data;
array_push($typeTowArray, $excel_data[$excel_data_index]);
break;
}
}
}
// dd($data);
foreach ($typeTowArray as $fkey => $value) {
foreach ($value as $vkey => $arrayData) {
if (!is_array($arrayData)) {
$data = ['value' => $arrayData];
$typeTowArray[$fkey][$vkey] = $data;
}
}
}
$excelErrorData['excel_data'] = $typeTowArray;
return $excelErrorData;
}
} catch (\Exception $e) {
// Handle any exceptions
$errorMessage = $e->getMessage(); //die();
$this->myLogger->logme('error', $errorMessage);
return false; // You can return an error response here
}
}
public function getBdsdumpFileErrorData()
{
$file_id = $this->request->getGet('file_id');
$file = $this->bdsDumpModel->where('id', $file_id)->first();
if (!isset($file)) {
return $this->respond(['status' => false, 'code' => 404, 'message' => 'No data found'], 200);
} else {
return $this->respond(['status' => true, 'code' => 200, 'data' => $file['reason']], 200);
}
}
public function getBdsDumpExcelFileErrors($file_id)
{
// Render views and capture output
$result = $this->getBdsBulkUploadExcelErrorData($file_id) ?? [];
// dd($result);
if ($result != 0) {
$result['file_id'] = $file_id;
echo view('excel_errors', $result);
} else if ($result == 0) {
$data['message'] = 'File Not Found Physically';
return view('errors/404', $data);
} else {
echo view('errors/html/production');
}
}
public function getClientAndVehicleId($row, $vehicle_data, $client_data, $rto_master, $vehicle_type_data)
{
$vehicle_number = trim($row[2]);
$client_name = trim($row[5]);
$client_email = trim($row[6]);
$vehicle_id = null;
$client_id = null;
// -------------------------------------------
// 1. First Stage: Check if vehicle already exists
// -------------------------------------------
if(strtolower(trim($vehicle_number)) != 'new'){
foreach ($vehicle_data as $v) {
if (strcasecmp(trim($v['vehicle_no']), $vehicle_number) === 0) {
$vehicle_id = $v['id'];
$client_id = $v['owner'];
break;
}
}
}
// -------------------------------------------
// 2. Second Stage: Vehicle not found -> check client by email
// -------------------------------------------
$second_stage_client_id = null;
if (empty($vehicle_id) && empty($client_id)) {
if(strtolower(trim($vehicle_number)) != 'new'){
foreach ($client_data as $c) {
if (strcasecmp(trim($c['email']), $client_email) === 0) {
$second_stage_client_id = $c['id'];
break;
}
}
}
if (!empty($second_stage_client_id)) {
// Existing client Insert vehicle
$matched_rto_id = check_rto_data($row, $rto_master);
$vehicle_type_id = check_vehicle_type($row, $vehicle_type_data);
$vehicle_insert = [
'vehicle_no' => $vehicle_number,
'vehicle_type' => $vehicle_type_id['vehicle_type']['id'] ?? null,
'owner' => $second_stage_client_id,
'rto_id' => $matched_rto_id['rto_data']['id'] ?? null,
];
$vehicle_id = $this->vehicleModel->insert($vehicle_insert);
$client_id = $second_stage_client_id;
} else {
// -------------------------------------------
// 3. Third Stage: No existing client → Insert new client then insert vehicle
// -------------------------------------------
$client_insert = [
'client_name' => $client_name,
'short_name' => $client_name,
'email' => $client_email,
'entity_type_id' => 7,
'client_type' => 2,
];
$client_id = $this->clientModel->insert($client_insert);
if ($client_id) {
$matched_rto_id = check_rto_data($row, $rto_master);
$vehicle_type_id = check_vehicle_type($row, $vehicle_type_data);
$vehicle_insert = [
'vehicle_no' => $vehicle_number,
'vehicle_type' => $vehicle_type_id['vehicle_type']['id'] ?? null,
'owner' => $client_id,
'rto_id' => $matched_rto_id['rto_data']['id'] ?? null,
];
$vehicle_id = $this->vehicleModel->insert($vehicle_insert);
}
}
}
return [
'client_id' => $client_id,
'vehicle_id' => $vehicle_id,
];
}
public function truncateBdsBulkUploadData()
{
$file_id = $this->request->getGet('file_id') ?? null;
if (empty($file_id)) {
return array('status' => false, 'message' => 'file_id is required');
}
$data['is_active'] = 0;
$this->policyTransactionModel->where('file_id', $file_id)->set($data)->update();
$this->PTCOShareDetailsModel->where('file_id', $file_id)->set($data)->update();
return $this->respond(['status' => true, 'code' => 200, 'message' => 'BDS bulk upload data truncated successfully'], 200);
}
// ------------------------------------------------------------------------------------------------------------------
/**
* Cron job: Daily BDS Report
* Fetches today's BDS entries, generates Excel (matching report_bds.php column order), and emails to recipients from .env.
* Recipients: comma-separated emails in bds.reportEmails
* File stored temporarily in writable/tmp/ and deleted after sending.
*/
public function cronDailyBDSReport()
{
helper('excel_import_export_helper');
$filePath = null;
try {
$today = date('Y-m-d', strtotime('-1 day'));
$reportList = $this->policyTransactionModel->getBDSReportList($today, $today,0,0,0,'created_at',0,0,0,0,0,[]);
if (empty($reportList)) {
$this->myLogger->logme('error', "cronDailyBDSReport: No BDS records for {$today}");
return $this->respond(['status' => 'success', 'message' => 'No BDS records for today. No report sent.'], 200);
}
// Column headers exactly matching report_bds.php order (including display:none columns)
$headers = [
'S. No', 'User', 'Month', 'Business Type', 'Client Type', 'Insured Name', 'Transaction Type',
'Policy Type', 'BAP Group', 'Vehicle Number', 'Policy No', 'Endorsement No', 'Insurer Branch',
'Endorsement Effective Date', 'Policy Effective Date', 'Policy Expiry Date', 'Reference', 'Remarks',
'BP Premium', 'TP Premium', 'Premium (without GST)', 'Total Premium', 'Agreed BP %', 'Agreed TP %',
'Rewards', 'Agreed Amount', 'Invoiced Amount', 'Outstanding Amount',
'Salse Person', 'Service Person', 'Salse Person Branch', 'Installment', 'Data Received Date', 'Renewal Date',
'Co-Premium', 'Remuneration Pay By Leader', 'Salse Person Manager', 'Service Person Manager',
'Service Person Branch', 'Rollover Date', 'Policyholder Name', 'Insured (Same as Proposer)',
'Follower Policy No', 'Co-Share %', 'Non Commissional Premium Amount', 'CGST', 'SGST', 'IGST',
'Stamp Duty', 'Standard BP %', 'Standard TP %', 'Actual BP Amount', 'Actual TP Amount',
'Actual BP %', 'Actual TP %', 'Actual BP Remuneration Amount', 'Actual TP Remuneration Amount',
'CD Account No'
];
$excelData = [];
foreach ($reportList as $idx => $row) {
$totalIrda = (float)($row['total_irda_amt'] ?? 0);
$billedAmt = (float)($row['billed_amt'] ?? 0);
$unbilledAmt = $totalIrda - $billedAmt;
if ($totalIrda == 0) {
$unbilledAmt = abs($unbilledAmt);
}
$unbilledAmt = ($unbilledAmt == 0 && $billedAmt == 0) ? $totalIrda : $unbilledAmt;
$hasIrda = ($totalIrda != 0);
$excelData[] = [
$idx + 1,
$row['user_name'] ?? 'N/A',
$row['policy_issue_month'] ?? 'N/A',
$row['revenue_type'] ?? 'N/A',
$row['client_type'] ?? 'N/A',
$row['client_name'] ?? 'N/A',
$row['action_type'] ?? 'N/A',
$row['policy_type'] ?? 'N/A',
$row['bap'] ?? 'N/A',
$row['vehicle_no'] ?? 'N/A',
$row['policy_no'] ?? 'N/A',
$row['endorsement_no'] ?? 'N/A',
$row['insurer_branch_name'] ?? 'N/A',
!empty($row['endorse_eff_date']) ? change_date_format($row['endorse_eff_date'], 'Y-m-d', 'd/m/Y') : 'N/A',
!empty($row['policy_start_date']) ? change_date_format($row['policy_start_date'], 'Y-m-d', 'd/m/Y') : 'N/A',
!empty($row['policy_end_date']) ? change_date_format($row['policy_end_date'], 'Y-m-d', 'd/m/Y') : 'N/A',
$row['ref'] ?? 'N/A',
$row['remarks'] ?? 'N/A',
$hasIrda ? ($row['bp_amt'] ?? '0.00') : '0.00',
$hasIrda ? ($row['tp_or_ter'] ?? '0.00') : '0.00',
$hasIrda ? ($row['premium_wo_gst'] ?? '0.00') : '0.00',
$hasIrda ? ($row['total_premium'] ?? '0.00') : '0.00',
$hasIrda ? ($row['agreed_bp_per'] ?? '0.00') . '%' : '0.00%',
$hasIrda ? ($row['agreed_tp_or_ter_per'] ?? '0.00') . '%' : '0.00%',
$row['reward'] ?? '0.00',
$row['total_irda_amt'] ?? '0.00',
!empty($row['billed_amt']) ? $row['billed_amt'] : '0.00',
number_format((float)$unbilledAmt, 2, '.', ''),
$row['salse_person_name'] ?? 'N/A',
$row['service_person_name'] ?? 'N/A',
$row['nhance_branch'] ?? 'N/A',
$row['installment'] ?? 'N/A',
!empty($row['data_received_date']) ? change_date_format($row['data_received_date'], 'Y-m-d', 'd/m/Y') : 'N/A',
!empty($row['renewal_date']) ? change_date_format($row['renewal_date'], 'Y-m-d', 'd/m/Y') : 'N/A',
$row['co_share'] ?? 'No',
$row['bro_payable_by'] ?? 'No',
$row['salse_manager_name'] ?? 'N/A',
$row['service_manager_name'] ?? 'N/A',
$row['service_branch'] ?? 'N/A',
!empty($row['rollover_date']) ? change_date_format($row['rollover_date'], 'Y-m-d', 'd/m/Y') : 'N/A',
$row['policy_holder_name'] ?? 'N/A',
$row['same_as_proposer'] ?? 'No',
$row['follower_policy_no'] ?? 'N/A',
number_format((float)($row['co_share_per'] ?? 0), 2),
number_format((float)($row['non_comm_per_amt'] ?? 0), 2),
number_format((float)($row['bp_cgst'] ?? 0), 2),
number_format((float)($row['bp_sgst'] ?? 0), 2),
number_format((float)($row['bp_igst'] ?? 0), 2),
number_format((float)($row['stamp_duty'] ?? 0), 2),
number_format((float)($row['standerd_bp_per'] ?? 0), 2),
number_format((float)($row['standerd_tp_per'] ?? 0), 2),
number_format((float)($row['actual_bp_amt'] ?? 0), 2),
number_format((float)($row['actual_tp_amt'] ?? 0), 2),
number_format((float)($row['actual_bp_per'] ?? 0), 2),
number_format((float)($row['actual_tp_per'] ?? 0), 2),
number_format((float)($row['actual_tep_brokerage_amt'] ?? 0), 2),
number_format((float)($row['actual_tp_brokerage_amt'] ?? 0), 2),
$row['cd_ac_no'] ?? 'N/A'
];
}
$today = date('d-m-Y', strtotime($today));
$fileName = 'BDS_Daily_Report_' . $today . '.xlsx';
$tmpDir = WRITEPATH . 'tmp' . DIRECTORY_SEPARATOR;
if (!is_dir($tmpDir)) {
mkdir($tmpDir, 0755, true);
}
$filePath = $tmpDir . $fileName;
$generated = generate_excel($headers, $excelData, $filePath);
if (!$generated) {
$this->myLogger->logme('error', 'cronDailyBDSReport: Excel generation failed');
return $this->respond(['status' => false, 'message' => 'Excel generation failed'], 500);
}
$emailList = getenv('bds.dailyReportEmails') ?: '';
$recipientEmails = array_filter(array_map('trim', explode(',', $emailList)));
if (empty($recipientEmails)) {
@unlink($filePath);
$this->myLogger->logme('error', 'cronDailyBDSReport: No recipients in bds.dailyReportEmails. Report generated but not sent.');
return $this->respond([
'status' => 'success',
'message' => 'Report generated. No recipients configured (set bds.dailyReportEmails in .env).',
'file' => $fileName
], 200);
}
$subject = "BDS Report Up to - {$today}";
$message = "<p>Please find attached the BDS report up to {$today}.</p>";
$message .= "<p>Total records: " . count($reportList) . "</p>";
$attachments = [
['filePath' => $filePath, 'fileName' => $fileName]
];
$res = MailHelper::send_email([
'mail' => $recipientEmails,
'subject' => $subject,
'message' => $message,
'attachments' => $attachments
]);
@unlink($filePath);
$resDecoded = is_string($res) ? json_decode($res, true) : $res;
if (isset($resDecoded['status']) && $resDecoded['status'] === 'success') {
$this->myLogger->logme('error', "cronDailyBDSReport: Report sent to " . count($recipientEmails) . " recipients");
return $this->respond([
'status' => true,
'message' => 'Report generated and emailed successfully.',
'recipients' => count($recipientEmails)
], 200);
}
$this->myLogger->logme('error', 'cronDailyBDSReport: Email send failed - ' . json_encode($resDecoded));
return $this->respond(['status' => false, 'message' => 'Report generated but email send failed'], 500);
} catch (Exception $e) {
if ($filePath && is_file($filePath)) {
@unlink($filePath);
}
$this->myLogger->logme('error', 'cronDailyBDSReport Exception: ' . $e->getMessage());
return $this->respond(['status' => false, 'message' => $e->getMessage()], 500);
}
}
/**
* Download policy transaction (pt_files) document from local/S3 storage.
*/
public function downloadPtDocument($fileOrId = null)
{
if ($fileOrId === null || $fileOrId === '') {
$data['message'] = 'No file specified.';
return view('errors/404', $data);
}
$uploadFilePath = WRITEPATH . 'uploads/client_kyc_documents';
$storedFileName = null;
$downloadAs = null;
if (ctype_digit((string) $fileOrId)) {
$record = $this->PTFileModel->find((int) $fileOrId);
if (empty($record) || empty($record['file_name'])) {
$data['message'] = 'File record not found';
return view('errors/404', $data);
}
$storedFileName = basename((string) $record['file_name']);
$downloadAs = storage_upload_display_name($storedFileName);
} else {
$storedFileName = basename((string) $fileOrId);
$downloadAs = storage_upload_display_name($storedFileName);
}
$storage = \Config\Services::getFileStorageService();
$result = $storage->download($uploadFilePath, $storedFileName);
if (! ($result['success'] ?? false)) {
$data['message'] = 'The Physical File Not Found';
return view('errors/404', $data);
}
if (! empty($result['path']) && is_file($result['path'])) {
return $this->response->download($result['path'], null)->setFileName($downloadAs);
}
if (! empty($result['content'])) {
return $this->response
->download($downloadAs, $result['content'])
->setFileName($downloadAs);
}
$data['message'] = 'The Physical File Not Found';
return view('errors/404', $data);
}
}