nhance/app/Controllers/TicketController.php
2026-07-21 17:45:17 +05:30

5467 lines
239 KiB
PHP

<?php
namespace App\Controllers;
use App\Controllers\BaseController;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\API\ResponseTrait;
use App\Models\TicketMasterModel;
use App\Models\TicketClaimStatusModel;
use App\Models\ClientModel;
use App\Models\TicketHistoryModel;
use App\Models\TicketMailTemplateModel;
use App\Models\TicketMessageModel;
use App\Models\TicketNoteModel;
use App\Models\UserModel;
use App\Models\ClientPolicyModel;
use App\Models\EmployeePolicyModel;
use App\Models\InsurerModel;
use App\Models\EmployeeModel;
use App\Models\TPAModel;
use App\Models\ClaimFilesModel;
use App\Models\ClaimDumpFileModel;
use App\Models\VehicleModel;
use App\Models\PartnerPolicyModel;
use App\Models\ClaimMisFileModel;
use DOMDocument;
use DOMXPath;
use Psr\Log\LoggerInterface;
use Kint\Kint;
use App\Helpers\MailHelper;
use CodeIgniter\Exceptions\PageNotFoundException;
class TicketController extends BaseController
{
use ResponseTrait;
protected $myLogger;
public $ticketType;
public $priorityType;
public $relationshipType;
public $modeOFIntimate;
public $claimType;
public $claimStatus;
public $placeHolders;
public $extraFields;
public $nonIDReason;
public $removeArrayKey;
protected $clientModel;
protected $ticketMasterModel;
protected $ticketHistoryModel;
protected $ticketMailTemplateModel;
protected $ticketMessageModel;
protected $ticketNoteModel;
protected $triggerType;
protected $userModel;
protected $employeeModel;
protected $clientPolicyModel;
protected $employeePolicyModel;
protected $extraFieldsDisplayForFrontend;
protected $insurerModel;
protected $TPAModel;
protected $claimFilesModel;
protected $claimDumpFileModel;
protected $vehicleModel;
protected $partnerPolicyModel;
protected $claimmisFileModel;
public function __construct()
{
$this->myLogger = \Config\Services::mylogger();
set_session_context('Ticket Master Controller');
$this->ticketMasterModel = new TicketMasterModel();
$this->ticketType = [1 => "Claim-GMC", 2 => "Claim-GPA", 3 => "EDLI", 4 => "GTLI", 8 => "Motor", 72 => "OPD"];
$this->priorityType = [
1 => "Low",
2 => "Medium",
3 => "High",
4 => "Urgent",
5 => "Emergency",
6 => "Critical"
];
$this->relationshipType = [
"self" => "Self",
"spouse" => "Spouse",
"son" => "Son",
"daughter" => "Daughter",
"father" => "Father",
"mother" => "Mother",
"father-in-law" => "Father-in-Law",
"mother-in-law" => "Mother-in-Law"
];
$this->modeOFIntimate = [
1 => "In Person",
2 => "Courier",
3 => "Online Mode - Email",
4 => "Smart Service Desk",
5 => "Direct to TPA"
];
$this->claimType = [
1 => [
1 => "Main Hospitalization",
3 => "Pre / Post",
2 => "OPD",
4 => "ReOpen",
],
2 => [
1 => "TTD",
2 => "PTD",
3 => "PPD",
4 => "Death",
]
];
$this->triggerType = [
1 => "Trigger 1",
2 => "Trigger 2",
3 => "Trigger 3",
4 => "Trigger 4",
5 => "Trigger 5",
6 => "Trigger 6",
7 => "Trigger 7",
8 => "Trigger 8",
9 => "Trigger 9",
];
$this->placeHolders = [
'((ACM))' => 'acm',
'((ACM_CONTACT))' => 'acm_mobile',
'((EMPLOYEE_NAME))' => 'emp_name',
'((EMPLOYEE_ID))' => 'emp_code',
'((CORPORATE_NAME))' => 'client_name',
'((INSURED_NAME))' => 'insured_name',
'((CLAIM_NO))' => 'claim_number',
'((RELATIONSHIP))' => 'relationship',
'((POLICY_TYPE))' => 'policy_type',
'((AUTO_QUERY_CONTENT))' => 'auto_query_content',
'((CLAIM_FORM_LINK))' => 'claim_form_link',
'((CLAIM_FEEDBACK_FORM))' => 'claim_feedback_form',
'((SETTLED_LETTER))' => 'settle_letter',
'((APPROVED_LETTER))' => 'approved_letter',
'((APPROVED_DESCRIBTION))' => 'approved_description',
];
$this->extraFields = [
1 => ['non_id_reason'],
10 => ['pay_initiate_date'],
3 => ['raised_date'],
4 => ['raised_date'],
5 => ['claim_number', 'registration_date'],
7 => ['query_received_date'],
8 => ['denial_reason','denial_date'],
9 => ['approved_amount','approved_date', 'approved_letter', "approved_description"],
11 => ['utr_details', 'settled_date', 'settle_letter'],
40 => ['approved_amount','approved_date', 'approved_letter', "approved_description"],
44 => ['utr_details', 'settled_date', 'settle_letter'],
30 => ['approved_amount','approved_date', 'approved_letter', "approved_description"],
34 => ['utr_details', 'settled_date', 'settle_letter'],
20 => ['approved_amount','approved_date', 'approved_letter', "approved_description"],
24 => ['utr_details', 'settled_date', 'settle_letter'],
14 => ['return_remark', 'awb_no_courier_name'],
48 => ['return_remark', 'awb_no_courier_name'],
59 => ['return_remark', 'awb_no_courier_name'],
54 => ['return_remark', 'awb_no_courier_name'],
13 => ['cancel_remark'],
47 => ['cancel_remark'],
53 => ['cancel_remark'],
58 => ['cancel_remark'],
2 => [],
6 => [],
12 => [],
15 => [],
16 => [],
17 => [],
18 => [],
19 => [],
21 => [],
22 => [],
23 => [],
25 => [],
26 => [],
27 => [],
28 => [],
29 => [],
31 => [],
32 => [],
33 => [],
35 => [],
36 => [],
37 => [],
38 => [],
39 => [],
41 => [],
42 => [],
43 => [],
45 => [],
46 => [],
49 => [],
50 => [],
51 => [],
52 => [],
55 => [],
56 => [],
57 => [],
60 => []
];
$this->extraFieldsDisplayForFrontend = [
1 => ['non_id_reason' => 'Non ID Reason'],
10 => ['pay_initiate_date' => 'Payment Initiated Date'],
3 => ['raised_date' => 'Raised Date'],
4 => ['raised_date' => 'Raised Date'],
5 => [
'claim_number' => 'Claim Number',
'registration_date' => 'Registration Date'
],
7 => ['query_received_date' => 'Query Received Date'],
8 => [
'denial_reason' => 'Denial Reason',
'denial_date' => 'Denial Date'
],
9 => [
'approved_amount' => 'Approved Amount',
'approved_date' => 'Approved Date',
'approved_letter' => 'Approved Letter',
'approved_description' => 'Approved Description'
],
11 => [
'utr_details' => 'UTR Details',
'settled_date' => 'Settled Date',
'settle_letter' => 'Settle Letter'
],
40 => [
'approved_amount' => 'Approved Amount',
'approved_date' => 'Approved Date',
'approved_letter' => 'Approved Letter',
'approved_description' => 'Approved Description'
],
44 => [
'utr_details' => 'UTR Details',
'settled_date' => 'Settled Date',
'settle_letter' => 'Settle Letter'
],
30 => [
'approved_amount' => 'Approved Amount',
'approved_date' => 'Approved Date',
'approved_letter' => 'Approved Letter',
'approved_description' => 'Approved Description'
],
34 => [
'utr_details' => 'UTR Details',
'settled_date' => 'Settled Date',
'settle_letter' => 'Settle Letter'
],
20 => [
'approved_amount' => 'Approved Amount',
'approved_date' => 'Approved Date',
'approved_letter' => 'Approved Letter',
'approved_description' => 'Approved Description'
],
24 => [
'utr_details' => 'UTR Details',
'settled_date' => 'Settled Date',
'settle_letter' => 'Settle Letter'
],
14 => [
'return_remark' => 'Return Remark',
'awb_no_courier_name' => 'AWB No Courier Name'
],
48 => [
'return_remark' => 'Return Remark',
'awb_no_courier_name' => 'AWB No Courier Name'
],
59 => [
'return_remark' => 'Return Remark',
'awb_no_courier_name' => 'AWB No Courier Name'
],
54 => [
'return_remark' => 'Return Remark',
'awb_no_courier_name' => 'AWB No Courier Name'
],
13 => ['cancel_remark' => 'Cancel Remark'],
47 => ['cancel_remark' => 'Cancel Remark'],
53 => ['cancel_remark' => 'Cancel Remark'],
58 => ['cancel_remark' => 'Cancel Remark'],
// OPD claim status
67 => ['non_id_reason' => 'Non ID Reason'],
69 => ['raised_date' => 'Raised Date'],
70 => ['raised_date' => 'Raised Date'],
71 => [
'claim_number' => 'Claim Number',
'registration_date' => 'Registration Date'
],
72 => ['query_received_date' => 'Query Received Date'],
73 => [
'denial_reason' => 'Denial Reason',
'denial_date' => 'Denial Date'
],
74 => [
'approved_amount' => 'Approved Amount',
'approved_date' => 'Approved Date',
'approved_letter' => 'Approved Letter',
'approved_description' => 'Approved Description'
],
75 => ['pay_initiate_date' => 'Payment Initiated Date'],
76 => [
'utr_details' => 'UTR Details',
'settled_date' => 'Settled Date',
'settle_letter' => 'Settle Letter'
],
78 => ['cancel_remark' => 'Cancel Remark'],
79 => [
'return_remark' => 'Return Remark',
'awb_no_courier_name' => 'AWB No Courier Name'
],
];
$this->nonIDReason = [
"Newborn Baby" => "Newborn Baby",
"Newly Wedded Spouse" => "Newly Wedded Spouse",
"Policy Pending" => "Policy Pending",
"New Joinee" => "New Joinee",
"Exceptional Case" => "Exceptional Case"
];
$this->removeArrayKey = [
2 => [],
6 => [],
12 => [],
15 => [],
16 => [],
17 => [],
18 => [],
19 => [],
21 => [],
22 => [],
23 => [],
25 => [],
26 => [],
27 => [],
28 => [],
29 => [],
31 => [],
32 => [],
33 => [],
35 => [],
36 => [],
37 => [],
38 => [],
39 => [],
41 => [],
42 => [],
43 => [],
45 => [],
46 => [],
49 => [],
50 => [],
51 => [],
52 => [],
55 => [],
56 => [],
57 => [],
60 => [],
68 => [],
77 => [],
80 => [],
81 => [],
];
$this->ticketMasterModel = new TicketMasterModel();
$this->claimStatus = new TicketClaimStatusModel();
$this->clientModel = new ClientModel();
$this->ticketHistoryModel = new TicketHistoryModel();
$this->ticketMailTemplateModel = new TicketMailTemplateModel();
$this->ticketNoteModel = new TicketNoteModel();
$this->ticketMessageModel = new TicketMessageModel();
$this->userModel = new UserModel();
$this->employeeModel = new EmployeeModel();
$this->clientPolicyModel = new ClientPolicyModel();
$this->employeePolicyModel = new EmployeePolicyModel();
$this->insurerModel = new InsurerModel();
$this->TPAModel = new TPAModel();
$this->claimFilesModel = new ClaimFilesModel();
$this->claimDumpFileModel = new ClaimDumpFileModel();
$this->vehicleModel = new VehicleModel();
$this->partnerPolicyModel = new PartnerPolicyModel();
$this->claimmisFileModel = new ClaimMisFileModel();
}
public function ticketList()
{
$data['ticket_type'] = $this->ticketType;
$data['modeOFIntimate'] = $this->modeOFIntimate;
$data['priorityType'] = $this->priorityType;
$data['claimType'] = $this->claimType;
$data['tab_name'] = "Claims";
if ($this->request->is('get')) {
$data['page_name'] = "Claims";
$data['claim_status'] = $this->claimStatus->select('id,ticket_type,claim_status')->where('is_active', 1)->findAll();
$data['client_list'] = $this->clientModel->select('id,client_name')->where('is_active', 1)->findAll();
$data['insurer_list'] = $this->insurerModel->where('is_active', 1)->findAll();
$data['tpa_list'] = $this->TPAModel->where('is_active', 1)->findAll();
$data['ticket_data'] = $this->ticketSearch(1);
$data['date_type'] = [
'ticket_created_date' => 'Created Date',
'ticket_updated_date' => 'Updated Date',
];
return $this->loadLayout('ticket_search', $data);
} else {
$isFromDashboard = $this->request->getPost("is_dashboard");
log_message('error', 'Is From Dashboard: ' . $isFromDashboard);
if (isset($isFromDashboard) && !empty($isFromDashboard)){
$data['page_name'] = "Claims";
if ($isFromDashboard == 1) {
$data['ticket_data'] = $this->ticketSearch(3);
}else if ($isFromDashboard == 2){
$data['ticket_data'] = $this->ticketSearch(4);
}else if ($isFromDashboard == 3){
$data['ticket_data'] = $this->ticketSearch(2);
}else if ($isFromDashboard == 4){
$data['ticket_data'] = $this->ticketSearch(5);
}
$data['claim_status'] = $this->claimStatus->select('id,ticket_type,claim_status')->where('is_active', 1)->findAll();
$data['client_list'] = $this->clientModel->select('id,client_name')->where('is_active', 1)->findAll();
return $this->loadLayout('ticket_search', $data);
}
else{
$data['ticket_data'] = $this->ticketSearch();
return $this->respond([
'status' => true,
'rows' => $data['ticket_data'] ?? [],
], 200);
}
}
}
public function exportTickets()
{
$format = $this->request->getPost('export_format') ?? 'csv';
$rows = $this->ticketSearch(); // uses same POST filters as the list
// Restrict to DataTables-visible rows when client sends export_ids
if ($this->request->getPost('export_ids') !== null) {
$exportIds = array_values(array_filter(array_map('intval', explode(',', (string) $this->request->getPost('export_ids')))));
if (empty($exportIds)) {
$rows = [];
} else {
$idOrder = array_flip($exportIds);
$rows = array_values(array_filter($rows, function ($row) use ($idOrder) {
return isset($idOrder[(int) ($row['id'] ?? 0)]);
}));
usort($rows, function ($a, $b) use ($idOrder) {
return ($idOrder[(int) $a['id']] ?? 0) <=> ($idOrder[(int) $b['id']] ?? 0);
});
}
}
$headers = [
'Created At', 'Updated At', 'Status', 'Policy Type', 'Claim Number', 'TPA ID', 'Emp ID', 'Emp Name',
'Insured Name', 'Corporate Name', 'ACM', 'Insurer', 'TPA', 'Policy No',
'Priority', 'Relationship', 'Emp Mobile', 'Emp Email', 'Emp Personal Email',
'Mode of Intimation', 'Claim Type', 'Claim Category', 'Hospital Name', 'DOA', 'DOD',
'Claim Amount', 'POD No.', 'Date of Join', 'Date of Inception', 'DOB',
'Date of Accident', 'Date of Death', 'Date of Intimation', 'Sum Insured',
'Raised Date', 'Registration Date', 'Query Received Date', 'Denial Date',
'Approved Date', 'Settled Date', 'Denial Reason', 'Approved Letter',
'Approved Amount', 'UTR Details', 'Settle Letter', 'Return Remark',
'Cancel Remark', 'AWB No & Courier Name', 'Non ID Reason',
'Payment Initiate Date', 'Approved Description', 'TAT', 'Claim Created By',
];
$claimTypeMap = $this->claimType;
$priorityMap = $this->priorityType;
$modeMap = $this->modeOFIntimate;
$ticketTypeMap = $this->ticketType;
$buildRow = function (array $row) use ($claimTypeMap, $priorityMap, $modeMap, $ticketTypeMap): array {
$typeId = (int) ($row['ticket_type_id'] ?? 0);
$claimKey = $row['claim_type'] ?? '';
$claimTypeLabel = $claimTypeMap[$typeId][$claimKey] ?? '';
$claimCreatedBy = strtoupper((string) ($row['claim_created_by'] ?? ''));
$claimCreatedByLabel = $claimCreatedBy === 'CRM' ? 'STAFF' : $claimCreatedBy;
$claimCategory = trim((string) ($row['tpa_claim_type'] ?? ''));
return [
$row['ticket_created_date'] ?? '',
$row['ticket_updated_date'] ?? '',
$row['status'] ?? '',
str_replace('Claim-', '', $ticketTypeMap[$typeId] ?? ''),
$row['claim_no'] ?? '',
$row['tpa_no'] ?? '',
$row['emp_code'] ?? '',
$row['emp_name'] ?? '',
$row['insured_name'] ?? '',
$row['short_name'] ?? '',
$row['acm_name'] ?? '',
$row['insurer_name'] ?? '',
$row['tpa_name'] ?? '',
$row['policy_no'] ?? '',
$priorityMap[$row['priority'] ?? 0] ?? '',
$row['relationship'] ?? '',
$row['emp_mobile'] ?? '',
$row['emp_mail'] ?? '',
$row['emp_personal_mail'] ?? '',
$modeMap[$row['mode_of_intimation'] ?? ''] ?? '',
$claimTypeLabel,
$claimCategory,
$row['hospital_name'] ?? '',
$row['doa'] ?? '',
$row['dod'] ?? '',
$row['claim_amount'] ?? '',
$row['pod_no'] ?? '',
$row['date_of_join'] ?? '',
$row['date_of_incep'] ?? '',
$row['dob'] ?? '',
$row['date_of_accident'] ?? '',
$row['date_of_death'] ?? '',
$row['date_of_intimat'] ?? '',
$row['si_amt'] ?? '',
$row['raised_date'] ?? '',
$row['registration_date'] ?? '',
$row['query_received_date'] ?? '',
$row['denial_date'] ?? '',
$row['approved_date'] ?? '',
$row['settled_date'] ?? '',
$row['denial_reason'] ?? '',
$row['approved_letter'] ?? '',
$row['approved_amount'] ?? '',
$row['utr_details'] ?? '',
$row['settle_letter'] ?? '',
$row['return_remark'] ?? '',
$row['cancel_remark'] ?? '',
$row['awb_no_courier_name'] ?? '',
$row['non_id_reason'] ?? '',
$row['pay_initiate_date'] ?? '',
$row['approved_description'] ?? '',
$row['tat'] ?? '',
$claimCreatedByLabel,
];
};
$filename = 'Claim-List-' . date('Y-m-d');
if ($format === 'excel') {
$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->setTitle('Claim List');
$sheet->fromArray([$headers], null, 'A1');
$rowIndex = 2;
foreach ($rows as $row) {
$sheet->fromArray([$buildRow($row)], null, 'A' . $rowIndex);
$rowIndex++;
}
// Bold header row
$lastCol = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex(count($headers));
$sheet->getStyle('A1:' . $lastCol . '1')->getFont()->setBold(true);
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment; filename="' . $filename . '.xlsx"');
header('Cache-Control: max-age=0');
ob_end_clean();
$writer->save('php://output');
exit;
}
// Default: CSV
header('Content-Type: text/csv; charset=UTF-8');
header('Content-Disposition: attachment; filename="' . $filename . '.csv"');
header('Cache-Control: max-age=0');
ob_end_clean();
$out = fopen('php://output', 'w');
// UTF-8 BOM for Excel compatibility
fwrite($out, "\xEF\xBB\xBF");
fputcsv($out, $headers);
foreach ($rows as $row) {
fputcsv($out, $buildRow($row));
}
fclose($out);
exit;
}
public function ticketSearch($action = null)
{
$db = db_connect();
$rawWhere = [];
// log_message('error', 'Ticket Search Action: ' . $action);
$subquery = $db->table('ticket_master tm')
->select([
'tm.id AS ticket_id',
"CASE
WHEN DATEDIFF(
CURDATE(),
COALESCE(latest_history.created_at, tm.created_at)
) BETWEEN 0 AND 6 THEN '0-6 Days'
WHEN DATEDIFF(
CURDATE(),
COALESCE(latest_history.created_at, tm.created_at)
) BETWEEN 7 AND 12 THEN '7-12 Days'
WHEN DATEDIFF(
CURDATE(),
COALESCE(latest_history.created_at, tm.created_at)
) BETWEEN 13 AND 20 THEN '13-20 Days'
ELSE 'Above 20 Days'
END AS tat"
])
->join(
'(SELECT th.ticket_id, MAX(th.created_at) AS created_at
FROM ticket_history th
WHERE th.field_name = "claim_status_id"
GROUP BY th.ticket_id) AS latest_history',
'latest_history.ticket_id = tm.id',
'left'
)
->where('tm.is_active', 1)
->groupBy('tm.id, tm.created_at, latest_history.created_at');
//action 1 get last 100 rows, action 2 filter and get all rows related to that, action 3 gets according to dashboard, action 4 gets according to ACM, action 5 tat
if ($action == 1) {
$query = $db->table('ticket_master tm')
->select([
'tm.id',
'tm.ticket_type_id',
'tm.claim_status_id',
'tm.claim_created_by',
'tm.is_head_approved',
'tcs.claim_status AS status',
'tm.claim_number AS claim_no',
'tm.tpa_claim_push_reference_no',
'tm.tpa_id',
'tm.tpa_no',
'tm.emp_name',
'tm.emp_code',
'tm.relationship',
'i.name AS insurer_name',
'c.client_name',
'tm.insured_name',
'c.short_name',
'DATE_FORMAT(tm.created_at, "%d-%m-%Y") AS ticket_created_date',
'DATE_FORMAT(tm.updated_at, "%d-%m-%Y") AS ticket_updated_date',
'COALESCE(tat_category.tat, "0-6 Days") AS tat',
'tm.claim_status_id',
'(SELECT first_name FROM user_profiles WHERE user_profiles.id = tm.acm_id) AS acm_name',
'(SELECT name FROM insurers WHERE insurers.id = tm.insurer_id) AS insurer_name',
'(SELECT name FROM tpa WHERE tpa.id = tm.tpa_id) AS tpa_name',
'tm.acm_id',
'tm.insurer_id',
'tm.tpa_id',
'tm.client_policy_id',
'tm.policy_no',
'tm.priority',
'tm.relationship',
'tm.emp_mobile',
'tm.emp_mail',
'tm.emp_personal_mail',
'tm.mode_of_intimation',
'tm.claim_type',
'tm.tpa_claim_type',
'tm.hospital_name',
'tm.doa',
'tm.dod',
'tm.claim_amount',
'tm.pod_no',
'tm.date_of_join',
'tm.date_of_incep',
'tm.dob',
'tm.date_of_accident',
'tm.date_of_death',
'tm.date_of_intimat',
'tm.si_amt',
'tm.raised_date',
'tm.registration_date',
'tm.query_received_date',
'tm.denial_date',
'tm.approved_date',
'tm.settled_date',
'tm.denial_reason',
'tm.approved_letter',
'tm.approved_amount',
'tm.utr_details',
'tm.settle_letter',
'tm.return_remark',
'tm.cancel_remark',
'tm.awb_no_courier_name',
'tm.non_id_reason',
'tm.pay_initiate_date',
'tm.approved_description'
])
->join('insurers i', 'i.id = tm.insurer_id AND i.is_active = 1', 'left')
->join('clients c', 'c.id = tm.client_id AND c.is_active = 1', 'left')
->join('ticket_claim_status tcs', 'tcs.id = tm.claim_status_id AND tcs.is_active = 1', 'left')
->join("({$subquery->getCompiledSelect()}) tat_category", 'tm.id = tat_category.ticket_id', 'left')
->where('tm.is_active', 1)
->whereNotIn('claim_status_id', [11, 12, 13, 22, 24, 32, 34, 42, 44, 47, 53, 58, 65])
->orderBy('tm.id', 'DESC')
->limit(500);
$data = $query->get()->getResultArray();
// dd(db_connect()->getLastQuery());
return $data;
} else if ($action == 3) {
$ids = $this->request->getPost('ids');
$ids = array_filter(explode(',', $ids));
if (!empty($ids)) {
$idsStr = implode(',', array_map('intval', $ids)); // sanitize IDs to be integers
$where = "tm.id IN ($idsStr)";
} else {
$where = '1 = 0'; // No valid IDs, return empty result
}
// dd($where);
} else if ($action == 4){
$acm_id = $this->request->getPost('ids');
// dd($acm_id);
if (!empty($acm_id)) {
$where = "tm.acm_id = $acm_id";
} else {
$where = '1 = 0'; // No valid IDs, return empty result
}
}else if ($action == 5) {
$search_data = $this->request->getPost();
$where = "tm.created_at >= '" . $search_data['from_date'] . "' AND tm.created_at <= '" . $search_data['to_date'] . "'" ."and ticket_type_id = ".$search_data['ticket_type_id'];
} else {
$search_data = $this->request->getPost();
// print_r($search_data); die()
$where = [];
foreach ($search_data as $search_objects => $key) {
if (stripos((string)$search_objects, 'csrf') !== false) {
continue;
}
if ($search_objects === 'export_format' || $search_objects === 'export_ids') {
continue;
}
if ($key != null && $key != '' && $key != 0 && $search_objects != 'is_dashboard') {
if($search_objects == "date_type" && $search_data[$search_objects] === 'ticket_created_date'){
$startDate = date('Y-m-d 00:00:00', strtotime($search_data['start_date']));
$endDate = date('Y-m-d 23:59:59', strtotime($search_data['end_date']));
$rawWhere[] = "tm.created_at BETWEEN '$startDate' AND '$endDate'";
}
elseif($search_objects == "date_type" && $search_data[$search_objects] === 'ticket_updated_date'){
$startDate = date('Y-m-d 00:00:00', strtotime($search_data['start_date']));
$endDate = date('Y-m-d 23:59:59', strtotime($search_data['end_date']));
$rawWhere[] = "tm.updated_at BETWEEN '$startDate' AND '$endDate'";
} elseif ($search_objects === 'tpa_claim_type') {
$cat = strtolower(trim((string) $key));
if ($cat === 'cashless') {
$rawWhere[] = "LOWER(COALESCE(tm.tpa_claim_type, '')) LIKE '%cash%'";
} elseif ($cat === 'reimbursement') {
$rawWhere[] = "LOWER(COALESCE(tm.tpa_claim_type, '')) LIKE '%reimburse%'";
}
} elseif($search_objects != "date_type" && $search_objects != "start_date" && $search_objects != "end_date"){
$where[$search_objects] = $key;
}
}
}
}
$query = $db->table('ticket_master tm')
->select([
'tm.id',
'tm.ticket_type_id',
'tcs.claim_status AS status',
'tm.claim_number AS claim_no',
'tm.tpa_claim_push_reference_no',
'tm.claim_status_id',
'tm.claim_created_by',
'tm.is_head_approved',
'tm.tpa_id',
'tm.tpa_no',
'tm.emp_name',
'tm.emp_code',
'tm.relationship',
'i.name AS insurer_name',
'c.client_name',
'tm.insured_name',
'c.short_name',
'DATE_FORMAT(tm.created_at, "%d-%m-%Y") AS ticket_created_date',
'DATE_FORMAT(tm.updated_at, "%d-%m-%Y") AS ticket_updated_date',
'COALESCE(tat_category.tat, "0-6 Days") AS tat',
'(SELECT first_name FROM user_profiles WHERE user_profiles.id = tm.acm_id) AS acm_name',
'(SELECT name FROM insurers WHERE insurers.id = tm.insurer_id) AS insurer_name',
'(SELECT name FROM tpa WHERE tpa.id = tm.tpa_id) AS tpa_name',
'tm.claim_status_id',
'tm.acm_id',
'tm.insurer_id',
'tm.tpa_id',
'tm.client_policy_id',
'tm.policy_no',
'tm.priority',
'tm.relationship',
'tm.emp_mobile',
'tm.emp_mail',
'tm.emp_personal_mail',
'tm.mode_of_intimation',
'tm.claim_type',
'tm.tpa_claim_type',
'tm.hospital_name',
'tm.doa',
'tm.dod',
'tm.claim_amount',
'tm.pod_no',
'tm.date_of_join',
'tm.date_of_incep',
'tm.dob',
'tm.date_of_accident',
'tm.date_of_death',
'tm.date_of_intimat',
'tm.si_amt',
'tm.raised_date',
'tm.registration_date',
'tm.query_received_date',
'tm.denial_date',
'tm.approved_date',
'tm.settled_date',
'tm.denial_reason',
'tm.approved_letter',
'tm.approved_amount',
'tm.utr_details',
'tm.settle_letter',
'tm.return_remark',
'tm.cancel_remark',
'tm.awb_no_courier_name',
'tm.non_id_reason',
'tm.pay_initiate_date',
'tm.approved_description'
])
->join('insurers i', 'i.id = tm.insurer_id AND i.is_active = 1', 'left')
->join('clients c', 'c.id = tm.client_id AND c.is_active = 1', 'left')
->join('ticket_claim_status tcs', 'tcs.id = tm.claim_status_id AND tcs.is_active = 1', 'left')
->join("({$subquery->getCompiledSelect()}) tat_category", 'tm.id = tat_category.ticket_id', 'left')
->where('tm.is_active', 1)
->where($where)
->orderBy('tm.id', 'DESC');
if (!empty($rawWhere)) {
foreach ($rawWhere as $condition) {
$query->where($condition, null, false); // raw SQL
}
}
$exportIdsRaw = $this->request->getPost('export_ids');
if ($exportIdsRaw !== null) {
$exportIds = array_values(array_filter(array_map('intval', explode(',', (string) $exportIdsRaw))));
if (empty($exportIds)) {
return [];
}
$query->whereIn('tm.id', $exportIds);
}
$data = $query->get()->getResultArray();
// dd($db->getLastQuery()->getQuery());die;
// dd($data);
if ($action == 5){
$tat = $this->request->getPost("tat_category");
$data = array_values(array_filter($data, function($dat) use ($tat) {
return $dat['tat'] == $tat;
}));
}
// print_rr($data);
// log_message('error',' Claims Master Data '.json_encode($data));die();
// print_rr($data);die();
return $data;
}
public function ticket_form($ticket_type)
{
$data = $this->ticket_form_data($ticket_type);
$data['tab_name'] = "Claims";
$data['page_name'] = "Claims";
// dd($data);
return $this->loadLayout('ticket_form_handler', $data);
}
public function ticket_form_data($ticket_type, $claim_status_id = null)
{
$this->myLogger->logme('error', "Fetching ticket form data for Ticket Type: $ticket_type");
$data = [
'ticket_form' => 1,
'selected_ticket_type' => $ticket_type,
'ticket_type' => $this->ticketType,
'priorityType' => $this->priorityType,
'relationshipType' => $this->relationshipType,
'modeOFIntimate' => $this->modeOFIntimate,
'nonIDReason' => $this->nonIDReason,
'claim_ticket_type_id' => $ticket_type
];
switch ($ticket_type) {
case 2:
$data['ticket_form'] = 'GPA';
break;
case 3:
$data['ticket_form'] = 'EDLI';
break;
case 4:
$data['ticket_form'] = 'GTLI';
break;
case 8:
$data['ticket_form'] = 'Motor';
break;
case 72:
$data['ticket_form'] = 'OPD';
break;
}
// Fetch ACM Users
$db = db_connect();
$data['acms'] = $db->table('user_profiles')
->select('id, first_name')
->where(['is_active' => 1, 'role' => 3])
->get()
->getResultArray();
// Fetch Claim Status
if(empty($claim_status_id)){
if($ticket_type == 2){
$claim_status_id = 15;
}else if($ticket_type == 3){
$claim_status_id = 25;
}else if($ticket_type == 4){
$claim_status_id = 35;
}else if($ticket_type == 8){
$claim_status_id = 62;
}else if($ticket_type == 72){
$claim_status_id = 67;
}else{
$claim_status_id = 1;
}
}
$data['claim_status'] = $this->transFormClaimStatus($claim_status_id, $ticket_type);
$data['extra_fields'] = $this->getExtraFields($data['claim_status']);
$data['extra_fields_array_for_validate'] = $this->getExtraFields($data['claim_status'], 1);
if ($ticket_type == 1 || $ticket_type == 72) {
$data['claim_type'] = $this->claimType[1];
} else {
$data['claim_type'] = $this->claimType[2];
}
if($ticket_type == 8){
$data['client_for_motor'] = $this->clientModel->select('id,client_name,phone')->where('client_type', 2)->where('is_active', 1)->findAll();
}
$this->myLogger->logme('error', "Ticket form data fetched successfully for Ticket Type: $ticket_type");
return $data;
}
public function fetchVehiclePolicy($id)
{
$method = $this->request->getMethod();
try {
if (!$id) {
throw new \Exception('Invalid ID', 400);
}
if ($method === 'get') {
$data['vehicle_list'] = $this->vehicleModel
->where('is_active', 1)
->where('owner', $id)
->findAll();
// $data['partner_policy_list'] = $this->partnerPolicyModel
// ->where('is_active', 1)
// ->findAll();
$data['partner_policy_list'] = $this->partnerPolicyModel->partnerPolicyList();
$client = $this->clientModel
->where('is_active', 1)
->where('id', $id)
->first();
$data['email'] = !empty($client) ? $client['email'] : null;
$data['phone'] = !empty($client) ? $client['phone'] : null;
if (empty($data['vehicle_list']) && empty($data['partner_policy_list'])) {
throw new \Exception('No Records found', 404);
}
return $this->response
->setJSON(['status' => 'success', 'data' => $data])
->setStatusCode(200);
}
throw new \Exception('Invalid request method', 405);
} catch (\Throwable $e) {
$code = ($e->getCode() && $e->getCode() >= 100 && $e->getCode() < 600) ? $e->getCode() : 500;
$isDbError = $e instanceof \CodeIgniter\Database\Exceptions\DatabaseException
|| $e instanceof \mysqli_sql_exception
|| $e instanceof \PDOException;
$context = [
'title' => get_class($e),
'type' => get_class($e),
'code' => $code,
'message' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine()
];
$this->myLogger->logme('error', "Exception: {message} in {file} on line {line}", $context, 0);
return $this->response->setJSON([
'status' => 'error',
'message' => $isDbError ? 'Data Access Error' : $e->getMessage(),
'ref' => ($isDbError ? 'database - ' : 'application - ') . $code . ' - ' . $e->getLine()
])->setStatusCode($code);
}
}
//transform the claim status
public function transFormClaimStatus($claimStatusId, $ticket_type)
{
// Fetch the main claim status by ID
$claimStatusData = $this->claimStatus
->select('*')
->where(['is_active' => 1, 'ticket_type' => $ticket_type])
->where('id', $claimStatusId)
->first();
// dd($claimStatusData);
// Initialize the filtered claim status array
$filteredClaimStatus = [];
if (!empty($claimStatusData)) {
// Add the main claim status to the result
$filteredClaimStatus[] = $claimStatusData;
// Decode the allowed_status JSON field
$filterClaimStatusIds = json_decode($claimStatusData['allowed_status'], true);
// Fetch additional claim statuses if IDs exist
if (!empty($filterClaimStatusIds) && is_array($filterClaimStatusIds)) {
$additionalClaimStatuses = $this->claimStatus
->select('*')
->where(['is_active' => 1, 'ticket_type' => $ticket_type])
->whereIn('id', $filterClaimStatusIds)
->get()
->getResultArray();
// Merge additional claim statuses into the result
$filteredClaimStatus = array_merge($filteredClaimStatus, $additionalClaimStatuses);
}
}
return $filteredClaimStatus;
}
public function getExtraFields(array $claimStatus, $nonFilterArray = 0): array
{
$extra_fields = [];
if($nonFilterArray == 1){
foreach ($claimStatus as $value) {
if (isset($this->extraFields[$value['id']])) {
if (!isset($extra_fields[$value['id']])) {
$extra_fields[$value['id']] = [];
}
$extra_fields[$value['id']] = array_merge($extra_fields[$value['id']], $this->extraFields[$value['id']]);
}
}
}else{
foreach ($claimStatus as $value) {
if (isset($this->extraFields[$value['id']])) {
$extra_fields[] = $this->extraFields[$value['id']];
}
}
$extra_fields = array_values(array_unique(array_merge(...$extra_fields)));
}
return $extra_fields;
}
/**
* Overlay conditional `required` rules onto a base validation rule-set based on the
* submitted `claim_status_id`. For example, when claim_status_id is a "Settled" status
* (11/24/34/44), fields like `utr_details` and `settled_date` are promoted from
* `permit_empty` to `required` so the request is rejected when they are blank.
*
* Letter URL fields (`approved_letter`, `settle_letter`) accept an alternative PDF
* upload, so they are intentionally not promoted here; that pairing is enforced by
* the upload validation flow. `approved_description` stays optional to match the
* existing UI contract.
*/
private function applyClaimStatusConditionalRules(array $rules): array
{
$claimStatusId = (int) $this->request->getPost('claim_status_id');
if ($claimStatusId <= 0) {
return $rules;
}
if (!isset($this->extraFields[$claimStatusId]) || !is_array($this->extraFields[$claimStatusId])) {
return $rules;
}
$requiredFields = $this->extraFields[$claimStatusId];
$skipFields = ['approved_letter', 'settle_letter', 'approved_description'];
foreach ($requiredFields as $field) {
if (in_array($field, $skipFields, true) || !isset($rules[$field])) {
continue;
}
$existingRules = $rules[$field]['rules'] ?? '';
$parts = $existingRules === ''
? []
: array_values(array_filter(array_map('trim', explode('|', $existingRules)), function ($part) {
return $part !== '' && $part !== 'permit_empty';
}));
if (!in_array('required', $parts, true)) {
array_unshift($parts, 'required');
}
$rules[$field]['rules'] = implode('|', array_unique($parts));
if (!isset($rules[$field]['errors']) || !is_array($rules[$field]['errors'])) {
$rules[$field]['errors'] = [];
}
$label = $rules[$field]['label'] ?? ucwords(str_replace('_', ' ', $field));
$rules[$field]['errors']['required'] = $label . ' is required for the selected claim status.';
}
return $rules;
}
public function view_ticket($ticket_id)
{
// $ticket_data = $this->ticketMasterModel->where('id', $ticket_id)->where('is_active', 1)->first();
$ticket_data = $this->ticketMasterModel->getTicketDataByTicketID($ticket_id);
// Security Check: Verify if record exists
if (empty($ticket_data)) {
// Redirect or show a 404 to prevent "Undefined array key" errors
return redirect()->to(base_url('ticket/list'))->with('error', 'Ticket not found');
}
$ticket_data['is_tpa_api_service_enabled'] = $this->ticketMasterModel->isTpaApiServiceEnabled($ticket_id);
$ticket_data = $this->formatDateForClaim($ticket_data, 'd/m/Y');
if (in_array($ticket_data['claim_status_id'], [15, 25, 35])) {
$ticket_data['auto_query_content'] = $this->getCheckListAndConvertArrayToString($ticket_data);
}
// dd($ticket_data);
$template_data = $this->ticketMasterModel->getTemplateDataByTicketID($ticket_id);
if (!empty($template_data)) {
$template_data['mail_content'] = $this->replacePlaceholders($template_data['mail_content'], $ticket_data);
$template_data['subject'] = $this->replacePlaceholders($template_data['subject'], $ticket_data);
}
$data = $this->ticket_form_data($ticket_data['ticket_type_id'], $ticket_data['claim_status_id']);
$data['reply_data'] = $template_data;
$data['placeHolders'] = $this->placeHolders;
$data['message_data'] = $this->getTicketMessage($ticket_id);
$data['view_ticket_page'] = [];
if($ticket_data['ticket_type_id'] == 1){
$data['member_data'] = $this->employeeModel->getEmployeeByEmployeeCode($ticket_data['emp_code']);
}else{
$data['member_data'] = array_filter(
$this->employeeModel->getEmployeeByEmployeeCode($ticket_data['emp_code']),
function ($member) {
return isset($member['emp_relationship']) && $member['emp_relationship'] == 'Self';
}
);
}
$data['ticket_history'] = $this->ticketHistory($ticket_id);
$data['ticket_check_list'] = db_connect()->table('ticket_check_list')->where('is_active', 1)->where('ticket_type_id', $ticket_data['ticket_type_id'])->get()->getResultArray();
if (!empty($ticket_data['client_policy_id'])){
$ticket_data['client_policy_id_text'] = $this->clientPolicyModel->select('concat(policy_type.policy_type,"-",client_policy.policy_no) as client_policy_name')->join('policy_type','policy_type.id = client_policy.policy_type_id and policy_type.is_active = 1')->where('client_policy.id',$ticket_data['client_policy_id'])->first()['client_policy_name'] ?? "N/A";
}
// dd($data);
$data['ticket_data'] = $ticket_data;
$data['acms'] = $this->employeeModel->getAcmUsingClientID($ticket_data['client_id']);
// do not remove this
// $raw_json = $this->ticketMasterModel->getPolicyTermsJson($ticket_id) ;
// $decoded_top = json_decode($raw_json ?? "", true) ?? [];
// $data['policy_terms'] = $this->recursive_json_decode($decoded_top);
$policy_data = $this->ticketMasterModel
->select('client_policy.policy_terms')
->join('client_policy', 'ticket_master.client_policy_id = client_policy.id')
->where('client_policy.is_active', 1)
->where('ticket_master.is_active', 1)
->where('ticket_master.id', $ticket_id)
->first();
if(isset($policy_data['policy_terms']) && !empty($policy_data['policy_terms'])){
$terms = json_decode($policy_data['policy_terms'], true);
$data['policy_terms'] = $this->convertTermsToDisplay($terms);
// print_rr($data); die;
}
// 8TH TYPE is Motor - so do not remove it....
if($ticket_data['ticket_type_id'] == 8){
$claim_status_id = $ticket_data['claim_status_id'];
$ticket_type = $ticket_data['ticket_type_id'];
$data['claim_status'] = $this->transFormClaimStatus($claim_status_id, $ticket_type);
$data['client_for_motor'] = $this->clientModel->select('id,client_name,phone')->where('client_type', 2)->where('is_active', 1)->findAll();
}
$data['tab_name'] = "Claims";
$data['page_name'] = "Claims";
return $this->loadLayout('ticket_edit_onbording', $data);
}
public function formatDateForClaim($ticket_data, $out_put_format = 'Y-m-d')
{
if (empty($ticket_data['doa'])) {
$ticket_data['doa'] = null;
} else {
$ticket_data['doa'] = change_date_format($ticket_data['doa'], null, $out_put_format);
}
if (empty($ticket_data['dod'])) {
$ticket_data['dod'] = null;
} else {
$ticket_data['dod'] = change_date_format($ticket_data['dod'], null, $out_put_format);
}
if (empty($ticket_data['dob'])) {
$ticket_data['dob'] = null;
} else {
$ticket_data['dob'] = change_date_format($ticket_data['dob'], null, $out_put_format);
}
if (empty($ticket_data['date_of_join'])) {
$ticket_data['date_of_join'] = null;
} else {
$ticket_data['date_of_join'] = change_date_format($ticket_data['date_of_join'], null, $out_put_format);
}
if (empty($ticket_data['date_of_incep'])) {
$ticket_data['date_of_incep'] = null;
} else {
$ticket_data['date_of_incep'] = change_date_format($ticket_data['date_of_incep'], null, $out_put_format);
}
if (empty($ticket_data['date_of_accident'])) {
$ticket_data['date_of_accident'] = null;
} else {
$ticket_data['date_of_accident'] = change_date_format($ticket_data['date_of_accident'], null, $out_put_format);
}
if (empty($ticket_data['date_of_death'])) {
$ticket_data['date_of_death'] = null;
} else {
$ticket_data['date_of_death'] = change_date_format($ticket_data['date_of_death'], null, $out_put_format);
}
if (empty($ticket_data['date_of_intimat'])) {
$ticket_data['date_of_intimat'] = null;
} else {
$ticket_data['date_of_intimat'] = change_date_format($ticket_data['date_of_intimat'], null, $out_put_format);
}
if (empty($ticket_data['raised_date'])) {
$ticket_data['raised_date'] = null;
} else {
$ticket_data['raised_date'] = change_date_format($ticket_data['raised_date'], null, $out_put_format);
}
if (empty($ticket_data['registration_date'])) {
$ticket_data['registration_date'] = null;
} else {
$ticket_data['registration_date'] = change_date_format($ticket_data['registration_date'], null, $out_put_format);
}
if (empty($ticket_data['query_received_date'])) {
$ticket_data['query_received_date'] = null;
} else {
$ticket_data['query_received_date'] = change_date_format($ticket_data['query_received_date'], null, $out_put_format);
}
if (empty($ticket_data['denial_date'])) {
$ticket_data['denial_date'] = null;
} else {
$ticket_data['denial_date'] = change_date_format($ticket_data['denial_date'], null, $out_put_format);
}
if (empty($ticket_data['approved_date'])) {
$ticket_data['approved_date'] = null;
} else {
$ticket_data['approved_date'] = change_date_format($ticket_data['approved_date'], null, $out_put_format);
}
if (empty($ticket_data['settled_date'])) {
$ticket_data['settled_date'] = null;
} else {
$ticket_data['settled_date'] = change_date_format($ticket_data['settled_date'], null, $out_put_format);
}
if (empty($ticket_data['pay_initiate_date'])) {
$ticket_data['pay_initiate_date'] = null;
} else {
$ticket_data['pay_initiate_date'] = change_date_format($ticket_data['pay_initiate_date'], null, $out_put_format);
}
return $ticket_data;
}
public function createTicket()
{
$request_data = $this->request->getPost();
$approvedLetterFile = $this->request->getFile('approved_letter_file');
$settleLetterFile = $this->request->getFile('settle_letter_file');
$selected_ticket_type = $this->request->getPost('ticket_type_id');
// 1. Initialize an empty rules array
$rules = [];
if ($selected_ticket_type == 1 || $selected_ticket_type == 72) {
$rules = [
// --- EMPLOYEE DETAILS ---
'emp_code' => [
'label' => 'Employee ID',
'rules' => 'required|min_length[2]|max_length[20]|regex_match[/^[a-zA-Z0-9\s\/_-]+$/]',
'errors' => [
'required' => 'Employee ID is required.',
'regex_match' => 'Employee ID can only contain letters, numbers, spaces, slashes (/), hyphens (-) and underscores (_).'
]
],
'emp_name' => [
'label' => 'Employee Name',
'rules' => 'required|min_length[3]|regex_match[/^[a-zA-Z0-9\s\/_-]+$/]',
'errors' => [
'required' => 'Employee Name is required',
'min_length' => 'Employee Name must be at least 3 characters long',
'regex_match' => 'Employee Name can only contain letters, numbers, spaces, slashes (/), hyphens (-), and underscores (_).'
]
],
'insured_name' => [
'label' => 'Insured Name',
'rules' => 'required|min_length[3]|regex_match[/^[a-zA-Z0-9\s\/_-]+$/]',
'errors' => [
'required' => 'Insured Name is required',
'min_length' => 'Insured Name must be at least 3 characters long',
'regex_match' => 'Insured Name can only contain letters, numbers, spaces, slashes (/), hyphens (-), and underscores (_).'
]
],
'relationship' => ['label' => 'Relationship','rules' => 'required',
'errors' => ['required' => 'Please select a Relationship']
],
'policy_no' => [
'label' => 'Policy Number',
// Allows: A-Z, a-z, 0-9, spaces (\s), hyphens (\-), underscores (_), and slashes (\/)
'rules' => 'permit_empty|min_length[3]|max_length[50]|regex_match[/^[a-zA-Z0-9\s\-\/_]+$/]',
'errors' => [
'min_length' => 'Policy Number appears too short (min 5 characters).',
'regex_match' => 'Policy Number can only contain letters, numbers, spaces, hyphens(-) underscores(_), and slashes(/).'
]
],
'tpa_no' => [
'label' => 'TPA ID',
'rules' => 'permit_empty|regex_match[/^[a-zA-Z0-9\/\-_]+$/]',
'errors' => [
'regex_match' => 'TPA ID can only contain letters, numbers, /, -, and _.'
]
],
'emp_mobile' => ['label' => 'Employee Mobile No','rules' => 'required|numeric|exact_length[10]',
'errors' => [
'required' => 'Mobile number is required',
'numeric' => 'Mobile must contain only numbers',
'exact_length' => 'Mobile must be exactly 10 digits'
]
],
'emp_mail' => ['label' => 'Employee Mail ID',
'rules' => 'required|regex_match[/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/]',
'errors' => [
'required' => 'Employee Email address is required.',
'regex_match' => 'Please enter a valid email format (e.g., name@domain.com).'
]
],
'emp_personal_mail' => ['label' => 'Personal Mail ID',
'rules' => 'permit_empty|regex_match[/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/]',
'errors' => [
'regex_match' => 'Please enter a valid email format (e.g., name@domain.com).'
]
],
'client_policy_id' => ['label' => 'Policy','rules' => 'required',
'errors' => ['required' => 'Please select a Policy']
],
'acm_id' => ['label' => 'Account Manager','rules' => 'required',
'errors' => ['required' => 'Select an Account Manager']
],
// --- CLAIM DETAILS ---
'claim_status_id' => ['label' => 'Status','rules' => 'required',
'errors' => ['required' => 'Claim Status is required']
],
'priority' => ['label' => 'Priority','rules' => 'required',
'errors' => ['required' => 'Priority is required']
],
'mode_of_intimation' => ['label' => 'Mode of Submission','rules' => 'required',
'errors' => ['required' => 'Mode of Submission is required']
],
'claim_type' => ['label' => 'Claim Type','rules' => 'required',
'errors' => ['required' => 'Claim Type is required']
],
'hospital_name' => [
'label' => 'Hospital Name',
'rules' => 'required|regex_match[/^[a-zA-Z0-9\s\-_.\']+$/]',
'errors' => [
'required' => 'Hospital Name is required',
'regex_match' => 'The {field} can only contain letters, numbers, spaces, dashes, underscores, dots, and apostrophes.'
]
],
'hospital_address' => [
'label' => 'Hospital Address',
'rules' => 'permit_empty|regex_match[/^[a-zA-Z0-9\s.,#\/_-]+$/]',
'errors' => [
'regex_match' => 'The {field} contains invalid characters (Allowed: letters, numbers, spaces, -, _, ., ,, # and /).'
],
],
'hospital_state' => [
'label' => 'Hospital State',
'rules' => 'permit_empty|regex_match[/^[a-zA-Z\s\-]+$/]',
'errors' => [
'regex_match' => 'Hospital State name can only contain letters, spaces, and hyphens.'
]
],
'hospital_city' => [
'label' => 'Hospital City', // Added label for consistency
'rules' => 'permit_empty|regex_match[/^[a-zA-Z\s\-]+$/]',
'errors' => [
'regex_match' => 'Hospital City can only contain letters, spaces, and hyphens.'
]
],
'hospital_pin_code' => [
'label' => 'Hospital Pincode',
'rules' => 'permit_empty|numeric|exact_length[6]',
'errors' => [
'numeric' => 'Hospital Pincode must be digits only.',
'exact_length' => 'Hospital Pincode must be exactly 6 digits.'
]
],
'hospital_phone_no' => [
'label' => 'Hospital Phone',
'rules' => 'permit_empty|numeric|min_length[10]|max_length[15]',
'errors' => [
'numeric' => 'Phone number must contain only digits.',
'min_length' => 'Phone number is too short.',
'max_length' => 'Phone number is too long.'
]
],
'doa' => ['label' => 'DOA', 'rules' => 'required',
'errors' => ['required' => 'Date of Admission is required']
],
'dod' => [ 'label' => 'DOD', 'rules' => 'required',
'errors' => ['required' => 'Date of Discharge is required']
],
'claim_amount' => [
'label' => 'Claim Amount',
'rules' => 'permit_empty|numeric',
'errors' => ['numeric' => 'Claim Amount must contain only numbers.']
],
'pod_no' => [
'label' => 'POD No',
'rules' => 'permit_empty|regex_match[/^[a-zA-Z0-9 \/_-]+$/]',
'errors' => [
'regex_match' => 'The {field} may only contain letters, numbers, spaces, slashes, underscores, and hyphens.',
]
],
// --- ADDITIONAL / CONDITIONAL FIELDS ---
'claim_number' => [
'label' => 'Claim Number',
'rules' => 'permit_empty|regex_match[/^[a-zA-Z0-9\/_-]+$/]',
'errors' => [
'regex_match' => 'Claim Number only allows letters, numbers, slashes (/), hyphens (-), and underscores (_).'
]
],
'denial_date' => ['label' => 'Denial Date','rules' => 'permit_empty|regex_match[/^\d{2}\/\d{2}\/\d{4}$/]','errors' => ['regex_match' => 'Denial Date must be dd/mm/yyyy.']],
'approved_amount' => ['label' => 'Approved Amount','rules' => 'permit_empty|numeric',
'errors' => ['numeric' => 'Approved amount must be numeric']
],
'approved_date' => ['label' => 'Approved Date','rules' => 'permit_empty|regex_match[/^\d{2}\/\d{2}\/\d{4}$/]','errors' => ['regex_match' => 'Approved Date must be dd/mm/yyyy.']],
'approved_letter' => ['label' => 'Approved Letter','rules' => 'permit_empty','errors' => []],
'approved_description' => ['label' => 'Approved Description','rules' => 'permit_empty','errors' => []],
'utr_details' => [
'label' => 'UTR Details',
'rules' => 'permit_empty|regex_match[/^[a-zA-Z0-9 \/_-]+$/]',
'errors' => [
'regex_match' => 'UTR Details allows only alphanumeric characters, spaces, and / _ -'
]
],
'settled_date' => ['label' => 'Settled Date','rules' => 'permit_empty|regex_match[/^\d{2}\/\d{2}\/\d{4}$/]','errors' => ['regex_match' => 'Settled Date must be dd/mm/yyyy.']],
'settle_letter' => ['label' => 'Settle Letter','rules' => 'permit_empty','errors' => []],
'pay_initiate_date' => ['label' => 'Payment Initiate Date','rules' => 'permit_empty|regex_match[/^\d{2}\/\d{2}\/\d{4}$/]','errors' => ['regex_match' => 'Payment Initiate Date must be dd/mm/yyyy.']],
'cancel_remark' => ['label' => 'Cancel Remark','rules' => 'permit_empty','errors' => []],
'return_remark' => ['label' => 'Return Remark','rules' => 'permit_empty','errors' => []],
'awb_no_courier_name' => ['label' => 'AWB No','rules' => 'permit_empty','errors' => []],
'non_id_reason' => ['label' => 'Non ID Reason','rules' => 'permit_empty','errors' => []],
'client_id' => ['rules' => 'required','errors' => ['required' => 'Client ID is required']],
'insurer_id' => ['rules' => 'required','errors' => ['required' => 'Insurer is required'],
'si_amt' => [ 'label' => 'Sum Insured', 'rules' => 'permit_empty|numeric', 'errors' => ['numeric' => 'Sum Insured must be a valid number.']],
'registration_date' => ['label' => 'Registration Date','rules' => 'permit_empty|regex_match[/^\d{2}\/\d{2}\/\d{4}$/]','errors' => ['regex_match' => 'Registration Date must be dd/mm/yyyy.']],
'denial_reason' => ['label' => 'Denial Reason', 'rules' => 'permit_empty|string','errors' => ['string' => 'Invalid characters in Denial Reason.']],
],
];
} else if ($selected_ticket_type == 8) {
$rules = [
// --- GENERAL DETAILS ---
'client_name' => ['label' => 'Client Name','rules' => 'required|is_not_list[0]',
'errors' => [
'required' => 'Please select a Client Name.',
'is_not_list' => 'Please select a valid Client from the list.'
]
],
'vehicle_id' => ['label' => 'Vehicle',
'rules' => 'required',
'errors' => [
'required' => 'Vehicle selection is required.'
]
],
'client_policy_id' => ['label' => 'Policy','rules' => 'required',
'errors' => ['required' => 'Please select a Policy.',]
],
'insurer_id' => ['label' => 'Insurer ID','rules' => 'required',
'errors' => ['required' => 'Insurer data is missing. Please re-select the policy.']
],
'emp_mobile' => ['label' => 'Employee Mobile No','rules' => 'required|numeric|exact_length[10]',
'errors' => [
'required' => 'Mobile number is required',
'numeric' => 'Mobile must contain only numbers',
'exact_length' => 'Mobile must be exactly 10 digits'
]
],
'emp_mail' => ['label' => 'Employee Mail ID',
'rules' => 'required|regex_match[/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/]',
'errors' => [
'required' => 'Employee Email address is required.',
'regex_match' => 'Please enter a valid email format (e.g., name@domain.com).'
]
],
// --- CLAIM DETAILS ---
'ticket_type_id' => ['label' => 'Policy Type','rules' => 'required','errors' => ['required' => 'Policy Type is required.']],
'claim_status_id' => ['label' => 'Status','rules' => 'required','errors' => ['required' => 'Status is required.']],
// --- HIDDEN KEYS (Integrity Checks) ---
'ticket_master_id' => ['label' => 'Ticket Master ID','rules' => 'permit_empty','errors' => []],
'client_id' => ['label' => 'Client ID','rules' => 'required','errors' => ['required' => 'System error: Client ID is missing.']]
];
} else {
$rules = [
// --- EMPLOYEE DETAILS ---
'emp_code' => [
'label' => 'Employee ID',
'rules' => 'required|min_length[2]|max_length[20]|regex_match[/^[a-zA-Z0-9\s\/_-]+$/]',
'errors' => [
'required' => 'Employee ID is required.',
'regex_match' => 'Employee ID can only contain letters, numbers, spaces, slashes (/), hyphens (-) and underscores (_).',
]
],
'emp_name' => [
'label' => 'Employee Name',
'rules' => 'required|min_length[3]|regex_match[/^[a-zA-Z0-9\s\/_-]+$/]',
'errors' => [
'required' => 'Employee Name is required',
'min_length' => 'Employee Name must be at least 3 characters long',
'regex_match' => 'Employee Name can only contain letters, numbers, spaces, slashes (/), hyphens (-), and underscores (_).'
]
],
'emp_mobile' => ['label' => 'Employee Mobile No','rules' => 'required|numeric|exact_length[10]',
'errors' => [
'required' => 'Mobile number is required',
'numeric' => 'Mobile must contain only numbers',
'exact_length' => 'Mobile must be exactly 10 digits'
]
],
'emp_mail' => ['label' => 'Employee Mail ID',
'rules' => 'required|regex_match[/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/]',
'errors' => [
'required' => 'Employee Email address is required.',
'regex_match' => 'Please enter a valid email format (e.g., name@domain.com).'
]
],
'emp_personal_mail' => ['label' => 'Personal Mail ID',
'rules' => 'permit_empty|regex_match[/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/]',
'errors' => [
'regex_match' => 'Please enter a valid email format (e.g., name@domain.com).'
]
],
'client_policy_id' => ['label' => 'Policy','rules' => 'required','errors' => ['required' => 'Please select a Policy']],
'acm_id' => ['label' => 'Account Manager','rules' => 'required','errors' => ['required' => 'Account Manager must be selected']],
// --- CLAIM DETAILS ---
'claim_status_id' => ['label' => 'Status','rules' => 'required','errors' => ['required' => 'Claim status is required']],
'claim_type' => ['label' => 'Claim Type','rules' => 'required','errors' => ['required' => 'Claim type is required']],
'dob' => ['label' => 'Date of Birth','rules' => 'required','errors' => ['required' => 'Date of Birth is required']],
'date_of_intimat' => ['label' => 'Date of Intimation','rules' => 'required','errors' => ['required' => 'Intimation date is required']],
'si_amt' => ['label' => 'Sum Insured','rules' => 'required|numeric','errors' => ['numeric' => 'Sum insured must be a number']],
'approved_amount' => ['label' => 'Approved Amount','rules' => 'permit_empty|numeric','errors' => ['numeric' => 'Approved amount must be numeric']],
'approved_date' => ['label' => 'Approved Date','rules' => 'permit_empty|regex_match[/^\d{2}\/\d{2}\/\d{4}$/]','errors' => ['regex_match' => 'Approved Date must be dd/mm/yyyy.']],
'approved_letter' => ['label' => 'Approved Letter','rules' => 'permit_empty','errors' => []],
'approved_description' => ['label' => 'Approved Description','rules' => 'permit_empty','errors' => []],
'utr_details' => [
'label' => 'UTR Details',
'rules' => 'permit_empty|regex_match[/^[a-zA-Z0-9 \/_-]+$/]',
'errors' => [
'regex_match' => 'UTR Details allows only alphanumeric characters, spaces, and / _ -'
]
],
'settled_date' => ['label' => 'Settled Date','rules' => 'permit_empty|regex_match[/^\d{2}\/\d{2}\/\d{4}$/]','errors' => ['regex_match' => 'Settled Date must be dd/mm/yyyy.']],
'settle_letter' => ['label' => 'Settle Letter','rules' => 'permit_empty','errors' => []],
'pay_initiate_date' => ['label' => 'Payment Initiate Date','rules' => 'permit_empty|regex_match[/^\d{2}\/\d{2}\/\d{4}$/]','errors' => ['regex_match' => 'Payment Initiate Date must be dd/mm/yyyy.']],
'cancel_remark' => ['label' => 'Cancel Remark','rules' => 'permit_empty','errors' => []],
'return_remark' => ['label' => 'Return Remark','rules' => 'permit_empty','errors' => []],
];
}
$rules = $this->applyClaimStatusConditionalRules($rules);
if (!$this->validate($rules)) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Input validation failed',
'code' => 400,
'errors' => $this->validator->getErrors()
]);
}
$request_data = $this->request->getPost();
$sanitized_data = sanitizeInputArrayAdvanced($request_data);
$ticket_data = $this->formatDateForClaim($sanitized_data);
$approvedLetterUrl = trim((string) ($ticket_data['approved_letter'] ?? ''));
$settleLetterUrl = trim((string) ($ticket_data['settle_letter'] ?? ''));
$hasApprovedLetterFile = $approvedLetterFile !== null
&& $approvedLetterFile->isValid()
&& $approvedLetterFile->getError() !== UPLOAD_ERR_NO_FILE;
$hasSettleLetterFile = $settleLetterFile !== null
&& $settleLetterFile->isValid()
&& $settleLetterFile->getError() !== UPLOAD_ERR_NO_FILE;
if ($approvedLetterUrl !== '' && $hasApprovedLetterFile) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Input validation failed',
'code' => 400,
'errors' => ['approved_letter' => 'Provide either Approved Letter URL or Approved Letter PDF file, not both.'],
]);
}
if ($approvedLetterUrl !== '' && ! $this->isClaimUploadUrl($approvedLetterUrl)) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Input validation failed',
'code' => 400,
'errors' => ['approved_letter' => 'Approved Letter URL format is invalid.'],
]);
}
if ($settleLetterUrl !== '' && $hasSettleLetterFile) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Input validation failed',
'code' => 400,
'errors' => ['settle_letter' => 'Provide either Settle Letter URL or Settle Letter PDF file, not both.'],
]);
}
if ($settleLetterUrl !== '' && ! $this->isClaimUploadUrl($settleLetterUrl)) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Input validation failed',
'code' => 400,
'errors' => ['settle_letter' => 'Settle Letter URL format is invalid.'],
]);
}
$uploadedApprovedLetter = null;
if ($hasApprovedLetterFile) {
$uploadResult = $this->uploadApprovedLetterPdf($approvedLetterFile, 'Approved Letter');
if (! ($uploadResult['status'] ?? false)) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Input validation failed',
'code' => 400,
'errors' => ['approved_letter_file' => $uploadResult['message'] ?? 'Invalid Approved Letter file.'],
]);
}
$uploadedApprovedLetter = $uploadResult['data'];
$ticket_data['approved_letter'] = '';
} else {
$ticket_data['approved_letter'] = $approvedLetterUrl;
}
$uploadedSettleLetter = null;
if ($hasSettleLetterFile) {
$uploadResult = $this->uploadApprovedLetterPdf($settleLetterFile, 'Settle Letter');
if (! ($uploadResult['status'] ?? false)) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Input validation failed',
'code' => 400,
'errors' => ['settle_letter_file' => $uploadResult['message'] ?? 'Invalid Settle Letter file.'],
]);
}
$uploadedSettleLetter = $uploadResult['data'];
$ticket_data['settle_letter'] = '';
} else {
$ticket_data['settle_letter'] = $settleLetterUrl;
}
// $ticket_data = $this->getLastMatchedStatus($ticket_data, );
// print_rr($ticket_data); die;
$isduplicate = checkDuplicateClaim([
'doa' => change_date_format($ticket_data['doa'] ?? '') ?? null,
'emp_code' => $ticket_data['emp_code'] ?? null,
'claim_amount' => $ticket_data['claim_amount'] ?? null,
'policy_no' => $ticket_data['policy_no'] ?? null
]);
if ($isduplicate) {
$errorDetails = [];
if (!empty($ticket_data['doa'])) {
$errorDetails[] = 'DOA: ' . change_date_format($ticket_data['doa']);
}
if (!empty($ticket_data['claim_amount'])) {
$errorDetails[] = 'Claim Amount: ₹' . number_format($ticket_data['claim_amount'], 2);
}
if (!empty($ticket_data['emp_code'])) {
$errorDetails[] = 'Emp Code: ' . $ticket_data['emp_code'];
}
if (!empty($ticket_data['policy_no'])) {
$errorDetails[] = 'Policy No: ' . $ticket_data['policy_no'];
}
$response = [
'status' => false,
'code' => 409,
'message' => 'Duplicate claim found for ' . implode(', ', $errorDetails)
];
return $this->respond($response, 200);
}
if ($ticket_data) {
$ticket_data['claim_created_by'] = "CRM";
$return_value = $this->ticketMasterModel->insert($ticket_data);
if ($return_value) {
if ($uploadedApprovedLetter !== null) {
$approvedLetterDownloadUrl = $this->createApprovedLetterFileUrl(
(int) $return_value,
(int) ($ticket_data['ticket_type_id'] ?? 1),
$uploadedApprovedLetter,
'APPROVED_LETTER_PDF'
);
$ticket_data['approved_letter'] = $approvedLetterDownloadUrl;
}
if ($uploadedSettleLetter !== null) {
$settleLetterDownloadUrl = $this->createApprovedLetterFileUrl(
(int) $return_value,
(int) ($ticket_data['ticket_type_id'] ?? 1),
$uploadedSettleLetter,
'SETTLE_LETTER_PDF'
);
$ticket_data['settle_letter'] = $settleLetterDownloadUrl;
}
if ($uploadedApprovedLetter !== null || $uploadedSettleLetter !== null) {
$updateUploadedLetterData = [];
if (isset($ticket_data['approved_letter'])) {
$updateUploadedLetterData['approved_letter'] = $ticket_data['approved_letter'];
}
if (isset($ticket_data['settle_letter'])) {
$updateUploadedLetterData['settle_letter'] = $ticket_data['settle_letter'];
}
$this->ticketMasterModel->where('id', $return_value)->set($updateUploadedLetterData)->update();
}
//mail trigger part
$this->putHistoryAfterInsert($ticket_data, $return_value);
$mail_responce = $this->sendAutoMailTrigger($return_value);
$this->autoMessageInsertBasedOnMailResponse($mail_responce, $return_value);
return $this->respond(['status' => true, 'ticket_id' => $return_value, 'code' => 200, 'data' => $ticket_data, "message" => "Claim created successfully", 'mail_responce' => $mail_responce], 200);
} else {
return $this->respond(['status' => false, 'code' => 404, 'message' => 'Failed to create claim'], 200);
}
} else {
return $this->respond(['status' => false, 'code' => 404, 'message' => 'claim data not found'], 200);
}
}
public function updateTicket()
{
$request_data = $this->request->getPost();
$approvedLetterFile = $this->request->getFile('approved_letter_file');
$settleLetterFile = $this->request->getFile('settle_letter_file');
$selected_ticket_type = $this->request->getPost('ticket_type_id');
// 1. Initialize an empty rules array
$rules = [];
if ($selected_ticket_type == 1 || $selected_ticket_type == 72) {
$rules = [
// --- EMPLOYEE DETAILS ---
'emp_code' => [
'label' => 'Employee ID',
'rules' => 'required|min_length[2]|max_length[20]|regex_match[/^[a-zA-Z0-9\s\/_-]+$/]',
'errors' => [
'required' => 'Employee ID is required.',
'regex_match' => 'Employee ID can only contain letters, numbers, spaces, slashes (/), hyphens (-) and underscores (_).',
]
],
'emp_name' => [
'label' => 'Employee Name',
'rules' => 'required|min_length[3]|regex_match[/^[a-zA-Z0-9\s\/_-]+$/]',
'errors' => [
'required' => 'Employee Name is required',
'min_length' => 'Employee Name must be at least 3 characters long',
'regex_match' => 'Employee Name can only contain letters, numbers, spaces, slashes (/), hyphens (-), and underscores (_).'
]
],
'insured_name' => [
'label' => 'Insured Name',
'rules' => 'required|min_length[3]|regex_match[/^[a-zA-Z0-9\s\/_-]+$/]',
'errors' => [
'required' => 'Insured Name is required',
'min_length' => 'Insured Name must be at least 3 characters long',
'regex_match' => 'Insured Name can only contain letters, numbers, spaces, slashes (/), hyphens (-), and underscores (_).'
]
],
'relationship' => ['label' => 'Relationship','rules' => 'required',
'errors' => ['required' => 'Please select a Relationship']
],
'policy_no' => [
'label' => 'Policy Number',
// Allows: A-Z, a-z, 0-9, spaces (\s), hyphens (\-), underscores (_), and slashes (\/)
'rules' => 'permit_empty|min_length[3]|max_length[50]|regex_match[/^[a-zA-Z0-9\s\-\/_]+$/]',
'errors' => [
'min_length' => 'Policy Number appears too short (min 3 characters).',
'regex_match' => 'Policy Number can only contain letters, numbers, spaces, hyphens(-) underscores(_), and slashes(/).'
]
],
'tpa_no' => [
'label' => 'TPA ID',
'rules' => 'permit_empty|regex_match[/^[a-zA-Z0-9\/\-_]+$/]',
'errors' => [
'regex_match' => 'TPA ID can only contain letters, numbers, /, -, and _.'
]
],
'emp_mobile' => ['label' => 'Employee Mobile No','rules' => 'required|numeric|exact_length[10]',
'errors' => [
'required' => 'Mobile number is required',
'numeric' => 'Mobile must contain only numbers',
'exact_length' => 'Mobile must be exactly 10 digits'
]
],
'emp_mail' => ['label' => 'Employee Mail ID',
'rules' => 'required|regex_match[/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/]',
'errors' => [
'required' => 'Employee Email address is required.',
'regex_match' => 'Please enter a valid email format (e.g., name@domain.com).'
]
],
'emp_personal_mail' => ['label' => 'Personal Mail ID',
'rules' => 'permit_empty|regex_match[/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/]',
'errors' => [
'regex_match' => 'Please enter a valid email format (e.g., name@domain.com).'
]
],
'client_policy_id' => ['label' => 'Policy','rules' => 'required',
'errors' => ['required' => 'Please select a Policy']
],
'acm_id' => ['label' => 'Account Manager','rules' => 'required',
'errors' => ['required' => 'Select an Account Manager']
],
// --- CLAIM DETAILS ---
'claim_status_id' => ['label' => 'Status','rules' => 'required',
'errors' => ['required' => 'Claim Status is required']
],
'priority' => ['label' => 'Priority','rules' => 'required',
'errors' => ['required' => 'Priority is required']
],
'mode_of_intimation' => ['label' => 'Mode of Submission','rules' => 'required',
'errors' => ['required' => 'Mode of Submission is required']
],
'claim_type' => ['label' => 'Claim Type','rules' => 'required',
'errors' => ['required' => 'Claim Type is required']
],
'hospital_name' => [
'label' => 'Hospital Name',
'rules' => 'required|regex_match[/^[a-zA-Z0-9\s\-_.\']+$/]',
'errors' => [
'required' => 'Hospital Name is required',
'regex_match' => 'The {field} can only contain letters, numbers, spaces, dashes, underscores, dots, and apostrophes.'
]
],
'hospital_address' => [
'label' => 'Hospital Address',
'rules' => 'permit_empty|regex_match[/^[a-zA-Z0-9\s.,#\/_-]+$/]',
'errors' => [
'regex_match' => 'The {field} contains invalid characters (Allowed: letters, numbers, spaces, -, _, ., ,, # and /).'
],
],
'hospital_state' => [
'label' => 'Hospital State',
'rules' => 'permit_empty|regex_match[/^[a-zA-Z\s\-]+$/]',
'errors' => [
'regex_match' => 'Hospital State name can only contain letters, spaces, and hyphens.'
]
],
'hospital_city' => [
'label' => 'Hospital City', // Added label for consistency
'rules' => 'permit_empty|regex_match[/^[a-zA-Z\s\-]+$/]',
'errors' => [
'regex_match' => 'Hospital City can only contain letters, spaces, and hyphens.'
]
],
'hospital_pin_code' => [
'label' => 'Hospital Pincode',
'rules' => 'permit_empty|numeric|exact_length[6]',
'errors' => [
'numeric' => 'Hospital Pincode must be digits only.',
'exact_length' => 'Hospital Pincode must be exactly 6 digits.'
]
],
'hospital_phone_no' => [
'label' => 'Hospital Phone',
'rules' => 'permit_empty|numeric|min_length[10]|max_length[15]',
'errors' => [
'numeric' => 'Phone number must contain only digits.',
'min_length' => 'Phone number is too short.',
'max_length' => 'Phone number is too long.'
]
],
'doa' => ['label' => 'DOA', 'rules' => 'required',
'errors' => ['required' => 'Date of Admission is required']
],
'dod' => [ 'label' => 'DOD', 'rules' => 'required',
'errors' => ['required' => 'Date of Discharge is required']
],
'claim_amount' => [
'label' => 'Claim Amount',
'rules' => 'permit_empty|numeric',
'errors' => ['numeric' => 'Claim Amount must contain only numbers.']
],
'pod_no' => [
'label' => 'POD No',
'rules' => 'permit_empty|regex_match[/^[a-zA-Z0-9 \/_-]+$/]',
'errors' => [
'regex_match' => 'The {field} may only contain letters, numbers, spaces, slashes, underscores, and hyphens.',
]
],
// --- ADDITIONAL / CONDITIONAL FIELDS ---
'claim_number' => [
'label' => 'Claim Number',
'rules' => 'permit_empty|regex_match[/^[a-zA-Z0-9\/_-]+$/]',
'errors' => [
'regex_match' => 'Claim Number only allows letters, numbers, slashes (/), hyphens (-), and underscores (_).'
]
],
'denial_date' => ['label' => 'Denial Date','rules' => 'permit_empty|regex_match[/^\d{2}\/\d{2}\/\d{4}$/]','errors' => ['regex_match' => 'Denial Date must be dd/mm/yyyy.']],
'approved_amount' => ['label' => 'Approved Amount','rules' => 'permit_empty|numeric',
'errors' => ['numeric' => 'Approved amount must be numeric']
],
'approved_date' => ['label' => 'Approved Date','rules' => 'permit_empty|regex_match[/^\d{2}\/\d{2}\/\d{4}$/]','errors' => ['regex_match' => 'Approved Date must be dd/mm/yyyy.']],
'approved_letter' => ['label' => 'Approved Letter','rules' => 'permit_empty','errors' => []],
'approved_description' => ['label' => 'Approved Description','rules' => 'permit_empty','errors' => []],
'utr_details' => [
'label' => 'UTR Details',
'rules' => 'permit_empty|regex_match[/^[a-zA-Z0-9 \/_-]+$/]',
'errors' => [
'regex_match' => 'UTR Details allows only alphanumeric characters, spaces, and / _ -'
]
],
'settled_date' => ['label' => 'Settled Date','rules' => 'permit_empty|regex_match[/^\d{2}\/\d{2}\/\d{4}$/]','errors' => ['regex_match' => 'Settled Date must be dd/mm/yyyy.']],
'settle_letter' => ['label' => 'Settle Letter','rules' => 'permit_empty','errors' => []],
'pay_initiate_date' => ['label' => 'Payment Initiate Date','rules' => 'permit_empty|regex_match[/^\d{2}\/\d{2}\/\d{4}$/]','errors' => ['regex_match' => 'Payment Initiate Date must be dd/mm/yyyy.']],
'cancel_remark' => ['label' => 'Cancel Remark','rules' => 'permit_empty','errors' => []],
'return_remark' => ['label' => 'Return Remark','rules' => 'permit_empty','errors' => []],
'awb_no_courier_name' => ['label' => 'AWB No','rules' => 'permit_empty','errors' => []],
'non_id_reason' => ['label' => 'Non ID Reason','rules' => 'permit_empty','errors' => []],
'client_id' => ['rules' => 'required','errors' => ['required' => 'Client ID is required']],
'insurer_id' => ['rules' => 'required','errors' => ['required' => 'Insurer is required'],
'si_amt' => [ 'label' => 'Sum Insured', 'rules' => 'permit_empty|numeric', 'errors' => ['numeric' => 'Sum Insured must be a valid number.']],
'registration_date' => ['label' => 'Registration Date','rules' => 'permit_empty|regex_match[/^\d{2}\/\d{2}\/\d{4}$/]','errors' => ['regex_match' => 'Registration Date must be dd/mm/yyyy.']],
'denial_reason' => ['label' => 'Denial Reason', 'rules' => 'permit_empty|string','errors' => ['string' => 'Invalid characters in Denial Reason.']],
],
];
} else if ($selected_ticket_type == 8) {
$rules = [
// --- GENERAL DETAILS ---
'client_name' => ['label' => 'Client Name','rules' => 'required|is_not_list[0]',
'errors' => [
'required' => 'Please select a Client Name.',
'is_not_list' => 'Please select a valid Client from the list.'
]
],
'vehicle_id' => ['label' => 'Vehicle',
'rules' => 'required',
'errors' => [
'required' => 'Vehicle selection is required.'
]
],
'client_policy_id' => ['label' => 'Policy','rules' => 'required',
'errors' => ['required' => 'Please select a Policy.',]
],
'insurer_id' => ['label' => 'Insurer ID','rules' => 'required',
'errors' => ['required' => 'Insurer data is missing. Please re-select the policy.']
],
'emp_mobile' => ['label' => 'Employee Mobile No','rules' => 'required|numeric|exact_length[10]',
'errors' => [
'required' => 'Mobile number is required',
'numeric' => 'Mobile must contain only numbers',
'exact_length' => 'Mobile must be exactly 10 digits'
]
],
'emp_mail' => ['label' => 'Employee Mail ID',
'rules' => 'required|regex_match[/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/]',
'errors' => [
'required' => 'Employee Email address is required.',
'regex_match' => 'Please enter a valid email format (e.g., name@domain.com).'
]
],
// --- CLAIM DETAILS ---
'ticket_type_id' => ['label' => 'Policy Type','rules' => 'required','errors' => ['required' => 'Policy Type is required.']],
'claim_status_id' => ['label' => 'Status','rules' => 'required','errors' => ['required' => 'Status is required.']],
// --- HIDDEN KEYS (Integrity Checks) ---
'ticket_master_id' => ['label' => 'Ticket Master ID','rules' => 'permit_empty','errors' => []],
'client_id' => ['label' => 'Client ID','rules' => 'required','errors' => ['required' => 'System error: Client ID is missing.']]
];
} else {
$rules = [
// --- EMPLOYEE DETAILS ---
'emp_code' => [
'label' => 'Employee ID',
'rules' => 'required|min_length[2]|max_length[20]|regex_match[/^[a-zA-Z0-9\s\/_-]+$/]',
'errors' => [
'required' => 'Employee ID is required.',
'regex_match' => 'Employee ID can only contain letters, numbers, spaces, slashes (/), hyphens (-) and underscores (_).',
]
],
'emp_name' => [
'label' => 'Employee Name',
'rules' => 'required|min_length[3]|regex_match[/^[a-zA-Z0-9\s\/_-]+$/]',
'errors' => [
'required' => 'Employee Name is required',
'min_length' => 'Employee Name must be at least 3 characters long',
'regex_match' => 'Employee Name can only contain letters, numbers, spaces, slashes (/), hyphens (-), and underscores (_).'
]
],
'emp_mobile' => ['label' => 'Employee Mobile No','rules' => 'required|numeric|exact_length[10]',
'errors' => [
'required' => 'Mobile number is required',
'numeric' => 'Mobile must contain only numbers',
'exact_length' => 'Mobile must be exactly 10 digits'
]
],
'emp_mail' => ['label' => 'Employee Mail ID',
'rules' => 'required|regex_match[/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/]',
'errors' => [
'required' => 'Employee Email address is required.',
'regex_match' => 'Please enter a valid email format (e.g., name@domain.com).'
]
],
'emp_personal_mail' => ['label' => 'Personal Mail ID',
'rules' => 'permit_empty|regex_match[/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/]',
'errors' => [
'regex_match' => 'Please enter a valid email format (e.g., name@domain.com).'
]
],
'client_policy_id' => ['label' => 'Policy','rules' => 'required','errors' => ['required' => 'Please select a Policy']],
'acm_id' => ['label' => 'Account Manager','rules' => 'required','errors' => ['required' => 'Account Manager must be selected']],
// --- CLAIM DETAILS ---
'claim_status_id' => ['label' => 'Status','rules' => 'required','errors' => ['required' => 'Claim status is required']],
'claim_type' => ['label' => 'Claim Type','rules' => 'required','errors' => ['required' => 'Claim type is required']],
'dob' => ['label' => 'Date of Birth','rules' => 'required','errors' => ['required' => 'Date of Birth is required']],
'date_of_intimat' => ['label' => 'Date of Intimation','rules' => 'required','errors' => ['required' => 'Intimation date is required']],
'si_amt' => ['label' => 'Sum Insured','rules' => 'required|numeric','errors' => ['numeric' => 'Sum insured must be a number']],
'approved_amount' => ['label' => 'Approved Amount','rules' => 'permit_empty|numeric','errors' => ['numeric' => 'Approved amount must be numeric']],
'approved_date' => ['label' => 'Approved Date','rules' => 'permit_empty|regex_match[/^\d{2}\/\d{2}\/\d{4}$/]','errors' => ['regex_match' => 'Approved Date must be dd/mm/yyyy.']],
'approved_letter' => ['label' => 'Approved Letter','rules' => 'permit_empty','errors' => []],
'approved_description' => ['label' => 'Approved Description','rules' => 'permit_empty','errors' => []],
'utr_details' => [
'label' => 'UTR Details',
'rules' => 'permit_empty|regex_match[/^[a-zA-Z0-9 \/_-]+$/]',
'errors' => [
'regex_match' => 'UTR Details allows only alphanumeric characters, spaces, and / _ -'
]
],
'settled_date' => ['label' => 'Settled Date','rules' => 'permit_empty|regex_match[/^\d{2}\/\d{2}\/\d{4}$/]','errors' => ['regex_match' => 'Settled Date must be dd/mm/yyyy.']],
'settle_letter' => ['label' => 'Settle Letter','rules' => 'permit_empty','errors' => []],
'pay_initiate_date' => ['label' => 'Payment Initiate Date','rules' => 'permit_empty|regex_match[/^\d{2}\/\d{2}\/\d{4}$/]','errors' => ['regex_match' => 'Payment Initiate Date must be dd/mm/yyyy.']],
'cancel_remark' => ['label' => 'Cancel Remark','rules' => 'permit_empty','errors' => []],
'return_remark' => ['label' => 'Return Remark','rules' => 'permit_empty','errors' => []],
];
}
$rules = $this->applyClaimStatusConditionalRules($rules);
if (!$this->validate($rules)) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Input validation failed',
'code' => 400,
'errors' => $this->validator->getErrors()
]);
}
$sanitized_data = sanitizeInputArrayAdvanced($request_data);
$ticket_data = $this->formatDateForClaim($sanitized_data);
$ticket_id = $this->request->getPost('ticket_master_id');
$approvedLetterUrl = trim((string) ($ticket_data['approved_letter'] ?? ''));
$settleLetterUrl = trim((string) ($ticket_data['settle_letter'] ?? ''));
$hasApprovedLetterFile = $approvedLetterFile !== null
&& $approvedLetterFile->isValid()
&& $approvedLetterFile->getError() !== UPLOAD_ERR_NO_FILE;
$hasSettleLetterFile = $settleLetterFile !== null
&& $settleLetterFile->isValid()
&& $settleLetterFile->getError() !== UPLOAD_ERR_NO_FILE;
if ($approvedLetterUrl !== '' && $hasApprovedLetterFile) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Input validation failed',
'code' => 400,
'errors' => ['approved_letter' => 'Provide either Approved Letter URL or Approved Letter PDF file, not both.'],
]);
}
if ($approvedLetterUrl !== '' && ! $this->isClaimUploadUrl($approvedLetterUrl)) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Input validation failed',
'code' => 400,
'errors' => ['approved_letter' => 'Approved Letter URL format is invalid.'],
]);
}
if ($settleLetterUrl !== '' && $hasSettleLetterFile) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Input validation failed',
'code' => 400,
'errors' => ['settle_letter' => 'Provide either Settle Letter URL or Settle Letter PDF file, not both.'],
]);
}
if ($settleLetterUrl !== '' && ! $this->isClaimUploadUrl($settleLetterUrl)) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Input validation failed',
'code' => 400,
'errors' => ['settle_letter' => 'Settle Letter URL format is invalid.'],
]);
}
$uploadedApprovedLetter = null;
if ($hasApprovedLetterFile) {
$uploadResult = $this->uploadApprovedLetterPdf($approvedLetterFile, 'Approved Letter');
if (! ($uploadResult['status'] ?? false)) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Input validation failed',
'code' => 400,
'errors' => ['approved_letter_file' => $uploadResult['message'] ?? 'Invalid Approved Letter file.'],
]);
}
$uploadedApprovedLetter = $uploadResult['data'];
$ticket_data['approved_letter'] = '';
} else {
$ticket_data['approved_letter'] = $approvedLetterUrl;
}
$uploadedSettleLetter = null;
if ($hasSettleLetterFile) {
$uploadResult = $this->uploadApprovedLetterPdf($settleLetterFile, 'Settle Letter');
if (! ($uploadResult['status'] ?? false)) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Input validation failed',
'code' => 400,
'errors' => ['settle_letter_file' => $uploadResult['message'] ?? 'Invalid Settle Letter file.'],
]);
}
$uploadedSettleLetter = $uploadResult['data'];
$ticket_data['settle_letter'] = '';
} else {
$ticket_data['settle_letter'] = $settleLetterUrl;
}
$old_ticket_data = $this->ticketMasterModel->where('id', $ticket_id)->where('is_active', 1)->first();
$ticket_data['claim_status_id'] = $this->getLastMatchedStatus($ticket_data, $old_ticket_data);
$ticket_data['last_updated_by'] = 'USER';
// print_rr($ticket_data); die;
$this->myLogger->logme('error', "[UPDATE_CLAIM] Ticket Master ID: {data}", ['data' => $ticket_id]);
$this->myLogger->logme('error', "[UPDATE_CLAIM] Old Ticket Data: {data}", ['data' => json_encode($old_ticket_data, JSON_PRETTY_PRINT)]);
$this->myLogger->logme('error', "[UPDATE_CLAIM] New Ticket Data: {data}", ['data' => json_encode($ticket_data, JSON_PRETTY_PRINT)]);
if ($ticket_data) {
if ($uploadedApprovedLetter !== null) {
$ticket_data['approved_letter'] = $this->createApprovedLetterFileUrl(
(int) $ticket_id,
(int) ($ticket_data['ticket_type_id'] ?? 1),
$uploadedApprovedLetter,
'APPROVED_LETTER_PDF'
);
}
if ($uploadedSettleLetter !== null) {
$ticket_data['settle_letter'] = $this->createApprovedLetterFileUrl(
(int) $ticket_id,
(int) ($ticket_data['ticket_type_id'] ?? 1),
$uploadedSettleLetter,
'SETTLE_LETTER_PDF'
);
}
$return_value = $this->ticketMasterModel->where('id', $ticket_id)->set($ticket_data)->update();
if ($return_value) {
$mail_responce = null;
if($old_ticket_data['claim_status_id'] != $ticket_data['claim_status_id']){
//mail trigger part
$mail_responce = $this->sendAutoMailTrigger($ticket_id);
$this->autoMessageInsertBasedOnMailResponse($mail_responce, $ticket_id);
}
//send mail to the head for rejected ticket approvel
if($ticket_data['claim_status_id'] == 8 && $ticket_data['is_head_approved'] == 0){
$this->sendMailToTheHead($ticket_id);
}else{
$this->myLogger->logme('error', "Head Mail can't be sent");
$this->myLogger->logme('error', "CLAIM STATUS ID : {data}", ['data' => $ticket_data['claim_status_id']]);
$this->myLogger->logme('error', "IS HEAD APPROVED : {data}", ['data' => $ticket_data['is_head_approved']]);
}
return $this->respond(['status' => true, 'code' => 200, 'data' => $ticket_data, "message" => "Claim updated successfully", 'mail_responce' => $mail_responce], 200);
} else {
return $this->respond(['status' => false, 'code' => 404, 'message' => 'Failed to update claim'], 200);
}
} else {
return $this->respond(['status' => false, 'code' => 404, 'message' => 'claim data not found'], 200);
}
}
public function mailTemplate()
{
$data = [];
$data['trigger_type'] = $this->triggerType;
$data['policy_type'] = $this->ticketType;
$data['placeHolders'] = $this->placeHolders;
$data['ticket_data'] = $this->ticketMailTemplateModel->where('is_active', 1)->findAll();
foreach ($data['ticket_data'] as $key => $ticket_data) {
$tooltip_array = $this->claimStatus->select('claim_status')->where('ticket_type',$data['ticket_data'][$key]['ticket_type'])->where('trigger_type',$data['ticket_data'][$key]['trigger_type'])->where('is_active',1)->first();
if (isset($tooltip_array) && $tooltip_array != null){
$data['ticket_data'][$key]['tool_tip'] = $tooltip_array['claim_status'];
}else{
$data['ticket_data'][$key]['tool_tip'] =$data['ticket_data'][$key]['template_name'];
}
}
// dd($data['ticket_data']);
$data['ticket_type'] = $this->ticketType;
$data['trigger_type'] = $this->triggerType;
$data['page_name'] = "Claims";
return $this->loadLayout('ticket_mail_template', $data);
}
public function crudTemplate($action)
{
//action 1 is create. action 2 is edit and action 3 is delete
if ($action == 1) {
$rules = [
'template_name' => [
'rules' => 'required',
'errors' => [
'required' => 'Template Name is required'
]
],
'ticket_type' => [
'rules' => 'required',
'errors' => [
'required' => 'Policy Type is required'
]
],
'trigger_type' => [
'rules' => 'required',
'errors' => [
'required' => 'Trigger Type is required'
]
],
'subject' => [
'rules' => 'required',
'errors' => [
'required' => 'Subject is required'
]
],
'mail_content' => [
'rules' => 'required',
'errors' => [
'required' => 'Mail Content is required'
]
]
];
if (!$this->validate($rules)) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Input validation failed',
'code' => 400,
'errors' => $this->validator->getErrors()
]);
}
$data = $this->request->getPost();
$received_data = sanitizeInputArrayAdvanced($data, ['mail_content']);
if (isset($received_data['id']) && $received_data['id'] != '') {
$status = $this->ticketMailTemplateModel->save($received_data);
if ($status) {
return $this->respond(['status' => true], 200);
} else {
return $this->respond(['status' => false], 200);
}
} else {
$status = $this->ticketMailTemplateModel->save($received_data);
if ($status) {
return $this->respond(['status' => true], 200);
} else {
return $this->respond(['status' => false], 200);
}
}
} elseif ($action == 2) {
$table_id = (int)$this->request->getPost('id');
$data = $this->ticketMailTemplateModel->where('id', $table_id)->where('is_active', 1)->first();
if ($data && isset($data['ticket_type']) && isset($data['trigger_type'])) {
$tooltip_array = $this->claimStatus->select('claim_status')
->where('ticket_type', $data['ticket_type'])
->where('trigger_type', $data['trigger_type'])
->where('is_active', 1)
->first();
$data['tool_tip'] = (isset($tooltip_array['claim_status']))
? $tooltip_array['claim_status']
: $data['template_name'];
} else {
// Handle case where $data is null or missing required fields
$data = $data ?: []; // Ensure $data is an array if null
$data['tool_tip'] = $data['template_name'];
}
if ($data) {
return $this->respond(['status' => true, 'data' => $data], 200);
} else {
return $this->respond(['status' => false], 404);
}
} elseif ($action == 3) {
$table_id = (int)$this->request->getPost('id');
$sql = "update ticket_mail_template set is_active = 0 where id = :table_id: ";
$binds = ['table_id'=>$table_id];
$status = $this->ticketMailTemplateModel->query($sql,$binds);
if ($status) {
return $this->respond(['status' => true], 200);
} else {
return $this->respond(['status' => false], 404);
}
}
}
public function crudNote($action)
{
// action = 1 is read, action 2 is insert/update
if ($action == 1) {
$ticket_master_id = $this->request->getPost('id');
$is_auto_query = $this->request->getPost('is_auto_query');
// print_rr($is_auto_query);
if (isset($ticket_master_id) && $ticket_master_id != '') {
$data = $this->ticketNoteModel->where('is_active', 1)->where('ticket_id', $ticket_master_id)->where('is_auto_query', $is_auto_query)->first();
if ($data) {
return $this->respond(['status' => true, 'data' => $data], 200);
} else {
return $this->respond(['status' => false], 200);
}
}
} elseif ($action == 2) {
$request_data = $this->request->getPost();
$rules = [
'note' => [
'label' => 'Add Notes',
'rules' => 'required|min_length[3]|max_length[1000]',
'errors' => [
'required' => 'The note field cannot be empty.',
'min_length' => 'The note is too short (minimum 3 characters).',
'max_length' => 'The note cannot exceed 1000 characters.'
]
],
];
if (!$this->validate($rules)) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Input validation failed',
'code' => 400,
'errors' => $this->validator->getErrors()
]);
}
$data = sanitizeInputArrayAdvanced($request_data);
// if (isset($data['id']) && $data['id'] != ''){
// print_rr($data);die();
$status = $this->ticketNoteModel->save($data);
$id = isset($data['id']) ? $data['id'] : $this->ticketNoteModel->insertID();
// }
if ($status) {
return $this->respond(['status' => true, 'id' => $id], 200);
} else {
return $this->respond(['status' => false], 200);
}
}
}
public function saveReply()
{
$received_data = $this->request->getPost();
$rules = [
'emp_mail' => [
'label' => 'To',
'rules' => 'required|regex_match[/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/]',
'errors' => [
'required' => 'Email address is required.',
'regex_match' => 'Please enter a valid email format (e.g., name@domain.com).'
]
],
'mail_subject' => [
'label' => 'Subject',
'rules' => 'required|min_length[5]',
'errors' => [
'required' => 'Please enter a Subject for the mail.',
'min_length' => 'Subject should be at least 5 characters long.'
]
]
];
if (!$this->validate($rules)) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Input validation failed',
'code' => 400,
'errors' => $this->validator->getErrors()
]);
}
// print_r($received_data); die;
$received_data['sender'] = 'staff';
$status = $this->ticketMessageModel->insert($received_data);
if ($status) {
$return = $this->sendReplyMessage($received_data);
return $this->respond(['status' => true, 'code' => 200, 'return' => $return], 200);
} else {
return $this->respond(['status' => false, 'code' => 404], 404);
}
}
public function getTicketMessage($ticket_master_id)
{
// log_message('error','Function called');die();
// $ticket_master_id = $this->request->getPost('id');
$dataToSend = [];
$user_id = get_session_userid();
// $logged_user = $this->userModel->select('first_name,last_name,profile')->where('id', $user_id)->first();
// $dataToSend['user_name'] = $logged_user['first_name'] . ' ' . $logged_user['last_name'];
$dataToSend['messages'] = $this->ticketMessageModel
->select('ticket_messages.*,up.first_name as user_name')
->join('user_profiles up', 'up.id = ticket_messages.created_by', 'left')
->where('ticket_messages.is_active', 1)
->where('ticket_messages.ticket_id', $ticket_master_id)
->orderBy('ticket_messages.created_at', 'DESC')
->findAll();
foreach ($dataToSend['messages'] as &$message) {
// $mail_content_converted = $this->convertHtmlToText($message['mail_content']);
// $message['mail_content'] = $mail_content_converted;
$claimFiles = new ClaimFilesModel();
$message["files_data"] = $claimFiles->where('is_active', 1)
->where('file_type', 2)->where('ticket_id', $ticket_master_id)
->where('ticket_message_id', $message['id'])
->findAll();
}
unset($message);
$dataToSend['emp_name'] = $this->ticketMasterModel->select('emp_name')
->where('id', $ticket_master_id)->where('is_active', 1)
->first()['emp_name'];
// dd($dataToSend);
if ($dataToSend) {
return $dataToSend;
} else {
$data = [];
return $data;
}
}
public function downloadClaimFile($claim_file_id = null)
{
// $actionType = $this->request->getGet();
$claimFiles = new ClaimFilesModel();
$file_data = $claimFiles->where('id', $claim_file_id)->first();
if (empty($file_data)) {
$data['message'] = 'File record not found';
return view('errors/404', $data);
}
$fileName = $this->resolveClaimFileDiskName($file_data);
try {
$download = $this->downloadFileFromStorage(WRITEPATH . 'uploads/claim_files', $fileName);
if ($download !== null) {
return $download;
}
$data['message'] = 'The Physical File Not Found';
return view('errors/404', $data);
} catch (\Exception $e) {
// Handle any exceptions
$errorMessage = $e->getMessage();
$this->myLogger->logme('error', $errorMessage);
$data['message'] = 'The Physical File Not Found';
return view('errors/404', $data);
}
}
/**
* Inline preview in browser for uploaded claim files (PDF / PNG / JPG / JPEG only).
*/
public function viewClaimFile($claim_file_id = null)
{
if ($claim_file_id === null || $claim_file_id === '') {
throw PageNotFoundException::forPageNotFound();
}
$claimFiles = new ClaimFilesModel();
$file_record = $claimFiles->where('id', $claim_file_id)->where('is_active', 1)->first();
if ($file_record === null || ! in_array((int) ($file_record['file_type'] ?? 0), [2, 4], true)) {
throw PageNotFoundException::forPageNotFound();
}
$fileName = $this->resolveClaimFileDiskName($file_record);
$ext = strtolower(pathinfo($fileName, PATHINFO_EXTENSION) ?: '');
if (! in_array($ext, ['pdf', 'png', 'jpg', 'jpeg'], true)) {
throw PageNotFoundException::forPageNotFound();
}
$storage = \Config\Services::getFileStorageService();
$uploadPath = WRITEPATH . 'uploads/claim_files';
$result = $storage->download($uploadPath, $fileName);
if (! ($result['success'] ?? false)) {
throw PageNotFoundException::forPageNotFound();
}
if (! empty($result['path']) && is_file($result['path'])) {
return $this->response->download($result['path'], null, true)->inline()->setFileName($fileName);
}
if (! empty($result['content'])) {
$mimeType = getMimeTypeByFileName($fileName) ?: 'application/octet-stream';
return $this->response
->setHeader('Content-Type', $mimeType)
->setHeader('Content-Disposition', 'inline; filename="' . $fileName . '"')
->setBody($result['content']);
}
throw PageNotFoundException::forPageNotFound();
}
public function convertHtmlToTextOld($html)
{
if(!empty($html)){
$dom = new DOMDocument();
@$dom->loadHTML($html);
return strip_tags($dom->saveHTML());
}else{
return '';
}
}
public function convertHtmlToText($html)
{
if (empty($html)) {
return '';
}
// Remove BOM / strange characters
$html = preg_replace('/[\x00-\x1F\x80-\xFF]/', ' ', $html);
// Load HTML safely
$dom = new DOMDocument();
libxml_use_internal_errors(true);
$dom->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'));
// Remove style and script tags
$xpath = new DOMXPath($dom);
foreach ($xpath->query('//style|//script') as $node) {
$node->parentNode->removeChild($node);
}
// Extract clean text
$text = $dom->textContent;
// Clean extra spaces
$text = preg_replace('/\s+/', ' ', $text);
return trim($text);
}
public function removeTicket()
{
$ticket_id = $this->request->getGet('ticket_id');
if (!empty($ticket_id)) {
$data['is_active'] = 0;
$this->ticketMasterModel->where('id', $ticket_id)->set($data)->update();
$this->clearDumpTicketLinksForTicket((int) $ticket_id);
return $this->respond(['status' => true, 'code' => 200, 'message' => 'Claim removed successfully'], 200);
} else {
return $this->respond(['status' => false, 'code' => 404, 'message' => 'Failed to remove Claim'], 200);
}
}
/**
* Clear TPA dump ticket_id links when a ticket is soft-deleted (avoids orphan dump refs).
*/
private function clearDumpTicketLinksForTicket(int $ticketId): void
{
if ($ticketId <= 0) {
return;
}
$tables = [
'claims_dump_vidal',
'claims_dump_abhi',
'claims_dump_medi_assist',
'claims_dump_fhpl',
'claims_dump_reliance',
'claims_dump_icici',
];
$db = db_connect();
foreach ($tables as $table) {
if (!$db->tableExists($table)) {
continue;
}
$db->table($table)
->where('ticket_id', $ticketId)
->set(['ticket_id' => null])
->update();
}
}
public function getTpaClaimPushLogs()
{
$ticketId = $this->request->getGet('ticket_id');
if (empty($ticketId)) {
return $this->respond([
'status' => false,
'message' => 'ticket_id is required',
], 400);
}
$ticket = $this->ticketMasterModel
->select('id, tpa_claim_push_logs')
->where('id', $ticketId)
->where('is_active', 1)
->first();
if (!$ticket) {
return $this->respond([
'status' => false,
'message' => 'Claim not found',
], 404);
}
$logs = trim((string) ($ticket['tpa_claim_push_logs'] ?? ''));
return $this->respond([
'status' => true,
'message' => 'TPA claim push logs fetched successfully',
'data' => [
'ticket_id' => (int) $ticketId,
'logs' => $logs,
'has_logs' => $logs !== '',
],
], 200);
}
//---- Email Trigger Part----------------------------------------------------------------------------------------------
public function constructMailContent($ticket_id, $status_id = null)
{
$this->myLogger->logme('error', "Constructing mail content for Ticket ID: $ticket_id");
try {
// Fetch Ticket Data
$ticket_data = $this->ticketMasterModel->getTicketDataByTicketID($ticket_id);
// print_r($ticket_data); die;
if (!$ticket_data) {
$this->myLogger->logme('error', "No ticket data found for Ticket ID: $ticket_id");
return null;
}
$this->myLogger->logme('error', "Fetched ticket data: " . json_encode($ticket_data));
if (!empty($status_id)) {
$ticket_data['claim_status_id'] = (int) $status_id;
}
// Fetch Email Template Data
$template_data = !empty($status_id)
? ($this->ticketMasterModel->getTemplateDataByStatusID((int) $status_id, (int) ($ticket_data['ticket_type_id'] ?? 0))[0] ?? null)
: $this->ticketMasterModel->getTemplateDataByTicketID($ticket_id);
if (!$template_data) {
$this->myLogger->logme('error', "No email template found for Claim Status ID: " . $ticket_data['claim_status_id']);
return null;
}
if (in_array($ticket_data['claim_status_id'], [15, 25, 35])) {
$ticket_data['auto_query_content'] = $this->getCheckListAndConvertArrayToString($ticket_data);
}
// print_r($ticket_data); die;
$this->myLogger->logme('error', "Fetched email template: " . json_encode($template_data));
// Generate Email Content
$subject = $this->replacePlaceholders($template_data['subject'], $ticket_data);
$message = $this->replacePlaceholders($template_data['mail_content'], $ticket_data);
// print_r($subject);
// print_r($message);
// die;
// Validate Essential Fields
if (empty($ticket_data['emp_mail'])) {
$this->myLogger->logme('error', "Employee email is missing for Ticket ID : '" . $ticket_id . "'");
return null;
}
if (empty($subject) || empty($message)) {
$this->myLogger->logme('error', "Generated email content is empty for Ticket ID: '" . $ticket_id . "'");
return null;
}
// Construct Mail Data
$mailData = [
'mail' => [$ticket_data['emp_mail'], $ticket_data['emp_personal_mail'] ?? ""],
'subject' => $subject,
'message' => $message,
'cc' => $ticket_data['common_mails'] ?? '',
'attachments' => []
];
// // if the employee personal mail is not empty then send the mail to the employee personal mail
// if(!empty($ticket_data['emp_personal_mail'])){
// $mailData[] = [
// 'mail' => [$ticket_data['emp_mail'], $ticket_data['emp_personal_mail'] ?? ""],
// 'subject' => $subject,
// 'message' => $message,
// 'cc' => $ticket_data['common_mails'] ?? '',
// 'attachments' => []
// ];
// }
// print_r($mailData); die;
$this->myLogger->logme('error', "Final Email Data");
return $mailData;
} catch (\Exception $e) {
$this->myLogger->logme('error', "Exception in constructMailContent: " . $e->getMessage());
return null;
}
}
public function replacePlaceholders($content, $ticket_data)
{
$this->myLogger->logme('error', "Replacing placeholders in content");
if (!empty($ticket_data) && !empty($content)) {
// print_rr($ticket_data);die();
if (!isset($ticket_data['id'])) { $ticket_data['id'] = $ticket_data['ticket_master_id'];}
if (!isset($ticket_data['ticket_master_id'])) {$ticket_data['ticket_master_id'] = $ticket_data['id'];}
foreach ($this->placeHolders as $key => $value) {
if ($value == "emp_code") {
$replaceData = $ticket_data[$value] ?? '';
} else if ($value == "policy_type") {
$replaceData = str_replace("Claim-", "", $this->ticketType[$ticket_data['ticket_type_id']] ?? "");
} else if ($value == "claim_form_link"){
$replaceData = '<a href="' . base_url('claim-form-download/' . md5($ticket_data['insurer_id'])) . '" target="_blank">Click here to download Claim Form</a>';
} else if ($value == "claim_feedback_form" && $ticket_data['ticket_type_id'] == 1){
$replaceData = '<a href="' . base_url('claims-feedback-form/' . md5($ticket_data['id'])) . '" target="_blank">Click to open Claim Feedback Form</a>';
} else if ($value == "settle_letter"){
$replaceData = '<a href="' . $ticket_data['settle_letter'] . '" target="_blank"> View Settlement Letter </a>';
}else if ($value == "approved_letter"){
$replaceData = '<a href="' . $ticket_data['approved_letter'] . '" target="_blank"> View Approved Letter </a>';
}else {
$replaceData = isset($ticket_data[$value]) ? $ticket_data[$value] : '';
}
$content = str_replace($key, $replaceData, $content);
}
}
$this->myLogger->logme('error', "Final content after placeholder replacement");
return $content;
}
//mail send function
public function sendTrigger($mail_content)
{
$this->myLogger->logme('error', "Sending email with content");
if (!empty($mail_content)) {
$mail_content['from_mail'] = "claims@nhanceindia.in";
$response = MailHelper::send_email($mail_content);
} else {
$response = ['status' => false, 'code' => 404, 'message' => "Mail not sent, mail data empty"];
$this->myLogger->logme('error', "Mail not sent, mail data empty");
}
$this->myLogger->logme('error', "Email sent response: " . json_encode($response));
return $response;
}
//reply mail part
public function sendReplyMessage($mail_data)
{
$this->myLogger->logme('error', "Preparing reply email for Ticket ID: " . $mail_data['ticket_id']);
$acm_mails = $this->ticketMasterModel->getTicketDataByTicketID($mail_data['ticket_id']);
if (!$acm_mails) {
$this->myLogger->logme('error', "No ACM mails found for Ticket ID: " . $mail_data['ticket_id']);
$this->myLogger->logme('error', "Reply mail not send");
return false;
}
$ticket_data = $this->ticketMasterModel->getTicketDataByTicketID($mail_data['ticket_id']);
// print_rr($ticket_data);die();
if (!$ticket_data) {
$this->myLogger->logme('error', "No ticket data found for Ticket ID : " . $mail_data['ticket_id']);
$this->myLogger->logme('error', "Reply mail not send");
return null;
}
if (!empty($mail_data)) {
$mail_data['mail_content'] = $this->replacePlaceholders($mail_data['mail_content'], $ticket_data);
$mail_data['mail_subject'] = $this->replacePlaceholders($mail_data['mail_subject'], $ticket_data);
}
$this->myLogger->logme('error', "Fetched ACM emails");
// if(!empty($ticket_data['emp_personal_mail'])){
// $this->myLogger->logme('error', "Send employee personal mail start");
// $emailPersonalData = [
// 'mail' => $ticket_data['emp_personal_mail'],
// 'subject' => $mail_data['mail_subject'],
// 'message' => $mail_data['mail_content'],
// 'common' => [],
// 'cc' => $acm_mails['common_mails'],
// 'attachments' => []
// ];
// $this->sendTrigger($emailPersonalData);
// $this->myLogger->logme('error', "Send employee personal mail successfully");
// }else{
// $this->myLogger->logme('error', "Send employee personal mail is empty");
// }
$emailData = [
'mail' => [$mail_data['emp_mail'], $ticket_data['emp_personal_mail'] ?? ""],
'subject' => $mail_data['mail_subject'],
'message' => $mail_data['mail_content'],
'common' => ['module' => "claim", 'pk' => $mail_data['ticket_id']],
'cc' => $acm_mails['common_mails'],
'attachments' => []
];
$this->myLogger->logme('error', "Final Reply Email Data");
return $this->sendTrigger($emailData);
}
//auto mail part
public function sendAutoMailTrigger($ticket_id)
{
$auto_mail_enable = $this->ticketMasterModel->getTemplateDataByTicketID($ticket_id);
// print_rr($auto_mail_enable);
$mail_responce = [];
if (!empty($auto_mail_enable) && $auto_mail_enable['is_auto_mail'] == 1) {
$mail_content = $this->constructMailContent($ticket_id);
// print_r($mail_content); die;
// foreach ($mail_content as $key => $value) {
$mail_responce = $this->sendTrigger($mail_content);
// $this->myLogger->logme('error', '{data} - Auto Mail Sent, Successfully', ['data' => $key + 1]);
$this->myLogger->logme('error', 'Auto Mail Sent, Successfully');
// }
} elseif (!empty($auto_mail_enable) && $auto_mail_enable['is_auto_mail'] == 0) {
$this->myLogger->logme('error', 'Auto Mail Not Sent, Reason: Automail Not Enabled');
} else {
$this->myLogger->logme('error', 'Auto Mail Not Sent, Reason: Mail Template Not Created');
}
return $mail_responce;
}
//---- End Email Trigger Part----------------------------------------------------------------------------------------------
public function ticketHistory($ticket_id)
{
$sql = "SELECT
th.id,
th.field_name,
th.display_name,
th.old_value,
th.new_value,
th.created_at,
th.updated_by,
CONCAT_WS(' ', creator.first_name, creator.last_name) AS modified_by,
-- Claim Status
old_status.claim_status as old_status_value,
new_status.claim_status as new_status_value,
-- Account Manager
CONCAT(old_account_manager.first_name, ' ', old_account_manager.last_name) as old_account_manager,
CONCAT(new_account_manager.first_name, ' ', new_account_manager.last_name) as new_account_manager,
-- Insured Employee ID Change
old_insured_emp.name as old_insured_id_name,
new_insured_emp.name as new_insured_id_name,
ticket_master.ticket_type_id
FROM
ticket_history th
-- Join for the user who made the change
LEFT JOIN user_profiles creator
ON th.created_by = creator.id
-- Status value lookups
LEFT JOIN ticket_claim_status old_status
ON th.field_name = 'claim_status_id'
AND th.old_value = old_status.id
AND old_status.is_active = 1
LEFT JOIN ticket_claim_status new_status
ON th.field_name = 'claim_status_id'
AND th.new_value = new_status.id
LEFT JOIN user_profiles as old_account_manager
ON th.field_name = 'acm_id'
AND th.old_value = old_account_manager.id
LEFT JOIN user_profiles as new_account_manager
ON th.field_name = 'acm_id'
AND th.new_value = new_account_manager.id
LEFT JOIN employees as old_insured_emp
ON th.field_name = 'insured_emp_id'
AND th.old_value = old_insured_emp.id
LEFT JOIN employees as new_insured_emp
ON th.field_name = 'insured_emp_id'
AND th.new_value = new_insured_emp.id
LEFT JOIN ticket_master as ticket_master
on th.field_name = 'claim_type'
AND th.ticket_id = ticket_master.id
WHERE
th.ticket_id = :ticket_id:
AND th.is_active = 1
ORDER BY
th.created_at DESC";
$binds = ['ticket_id'=>(int)$ticket_id];
$data = $this->ticketHistoryModel->query($sql,$binds)->getResultArray();
// dd(db_connect()->getLastQuery());
$priorityType = $this->priorityType;
$relationshipType = $this->relationshipType;
$modeOFIntimate = $this->modeOFIntimate;
$claim_type = $this->claimType;
foreach ($data as &$row) {
if ($row['field_name'] == 'claim_status_id') {
$new_old_value = isset($row['old_status_value']) ? $row['old_status_value'] : '-';
$new_new_value = $row['new_status_value'];
$row['old_value'] = $new_old_value;
$row['new_value'] = $new_new_value;
} elseif ($row['field_name'] == 'acm_id') {
$new_old_value = isset($row['old_account_manager']) ? $row['old_account_manager'] : '-';
$new_new_value = $row['new_account_manager'];
$row['old_value'] = $new_old_value;
$row['new_value'] = $new_new_value;
} elseif ($row['field_name'] == 'insured_emp_id') {
$new_old_value = isset($row['old_insured_id_name']) ? $row['old_insured_id_name'] : '-';
$new_new_value = $row['new_insured_id_name'];
$row['old_value'] = $new_old_value;
$row['new_value'] = $new_new_value;
} elseif ($row['field_name'] == 'priority') {
$new_old_value = isset($priorityType[$row['old_value']]) ? $priorityType[$row['old_value']] : '-';
$new_new_value = isset($priorityType[$row['new_value']]) ? $priorityType[$row['new_value']] : '-';
$row['old_value'] = $new_old_value;
$row['new_value'] = $new_new_value;
} elseif ($row['field_name'] == 'relationship') {
$new_old_value = isset($relationshipType[$row['old_value']]) ? $relationshipType[$row['old_value']] : '-';
$new_new_value = isset($relationshipType[$row['new_value']]) ? $relationshipType[$row['new_value']] : '-';
$row['old_value'] = $new_old_value;
$row['new_value'] = $new_new_value;
} elseif ($row['field_name'] == 'mode_of_intimation') {
$new_old_value = isset($modeOFIntimate[$row['old_value']]) ? $modeOFIntimate[$row['old_value']] : "-";
$new_new_value = isset($modeOFIntimate[$row['old_value']]) ? $modeOFIntimate[$row['old_value']] : "-";
$row['old_value'] = $new_old_value;
$row['new_value'] = $new_new_value;
} elseif ($row['field_name'] == 'claim_type') {
$new_old_value = isset($claim_type[$row['ticket_type_id']][$row['old_value']]) ? $claim_type[$row['ticket_type_id']][$row['old_value']] : '-';
$new_new_value = isset($claim_type[$row['ticket_type_id']][$row['new_value']]) ? $claim_type[$row['ticket_type_id']][$row['new_value']] : '-';
$row['old_value'] = $new_old_value;
$row['new_value'] = $new_new_value;
} elseif ($row['field_name'] == 'claim_type') {
$new_old_value = isset($claim_type[$row['old_value']]) ? $claim_type[$row['old_value']] : '-';
$new_new_value = isset($claim_type[$row['new_value']]) ? $claim_type[$row['new_value']] : '-';
$row['old_value'] = $new_old_value;
$row['new_value'] = $new_new_value;
} else {
$new_old_value = isset($row['old_value']) ? $row['old_value'] : '-';
$new_new_value = isset($row['new_value']) ? $row['new_value'] : '-';
$row['old_value'] = $new_old_value;
$row['new_value'] = $new_new_value;
}
}
return ($data);
}
public function sendMailWithAutoQuery()
{
$ticket_ids = $this->ticketMessageModel
->select('ticket_master.id')
->join('ticket_master', 'ticket_master.id = ticket_messages.ticket_id AND ticket_master.is_active = 1 and ticket_master.claim_status_id in (4,17,27,37)')
->join('ticket_claim_status AS tcs', 'tcs.id = ticket_messages.claim_status AND (tcs.is_active = 1)')
->join('ticket_notes', 'ticket_notes.ticket_id = ticket_messages.ticket_id AND ticket_notes.is_auto_query = 1 AND ticket_notes.is_active = 1')
->where('ticket_messages.is_active', 1)
->where('ticket_messages.claim_status in (4,17,27,37)')
->groupBy('ticket_master.id')
->having('DATEDIFF(CURDATE(), MAX(ticket_messages.created_at)) =', 7)
->having('count(ticket_messages.id) < ', 6)
->findAll();
// var_dump($ticket_ids);die();
foreach ($ticket_ids as $ticket) {
$ticket_id = $ticket['id'];
$acm_mails = $this->ticketMasterModel->getTicketDataByTicketID($ticket_id);
$ticket_data = $this->ticketMasterModel->getTicketDataByTicketID($ticket_id);
$template_data = $this->ticketMasterModel->getTemplateDataByTicketID($ticket_id);
if (!empty($template_data)) {
$template_data['mail_content'] = $this->replacePlaceholders($template_data['mail_content'], $ticket_data);
$template_data['subject'] = $this->replacePlaceholders($template_data['subject'], $ticket_data);
}
$emailData = [
'mail' => $template_data['emp_mail'],
'subject' => $template_data['subject'],
'message' => $template_data['mail_content'],
'common' => ['module' => "claim", 'pk' => $ticket_id],
'cc' => $acm_mails['common_mails'],
'attachments' => []
];
$this->myLogger->logme('error', "Final Reply Email Data");
// var_dump($emailData);
$this->sendTrigger($emailData);
}
return 'Ticket id\'s : '.json_encode($ticket_ids);
}
public function ticketReports()
{
if ($this->request->is('get')) {
$default_start = new \DateTime();
$data['default_end'] = $default_start->format('d-m-Y');
$data['default_start'] = $default_start->modify('-60 days')->format('d-m-Y');
$data['policy_type'] = $this->ticketType;
$data['account_manager'] = $this->userModel->select('first_name')->where('is_active', 1)->where('role', 3)->findAll();
$data['report_type'] = [
'acc_manager_wise_status' => 'Account Manger Wise Status Report',
'tpa_wise_status' => 'TPA Wise Status Report',
'tat_band_wise' => 'TAT Wise Status Report'
];
//
$data['tab_name'] = "Claim Reports";
$data['page_name'] = "Claims";
$this->loadLayout('ticket_reports', $data);
} else {
$received_data = $this->request->getPost();
$from_Date = $received_data['fromDate'];
$to_Date = $received_data['toDate'];
$fromDate = \DateTime::createFromFormat('d-m-Y', $from_Date)->format('Y-m-d');
$toDate = \DateTime::createFromFormat('d-m-Y', $to_Date)->format('Y-m-d');
$policy_type = $received_data['policy_type'];
// print_rr($received_data);
if ($received_data['report_type'] == "acc_manager_wise_status"){
$viewData['policy_type'] = $received_data['policy_type'];
$viewData['account_manager_wise_data'] = $this->ticketMasterModel->accountManagerWiseReport($policy_type,$fromDate,$toDate);
// print_rr($viewData);die();
if ($policy_type == 1){
$viewData['column_order'] = [
'ACM_NAME', 'ID NOT GENERATED', 'NON ID', 'CDA', 'INFORMATION REQUIRED',
'UNDER PROCESS - CLAIM NO. UPDATION',
'UNDER PROCESS - QUERY DOCUMENT RECEIVED', 'APPROVED', 'PAYMENT INITIATED',
'TOTAL'
];
$ordered_data = [];
foreach ($viewData['account_manager_wise_data'] as $tpa_data) {
$temp = [];
foreach ($viewData['column_order'] as $key) {
$temp[$key] = isset($tpa_data[$key]) ? $tpa_data[$key] : 0; // Default to 0 if key is missing
}
$ordered_data[] = $temp;
}
$viewData['tpa_wise_data'] = $ordered_data;
// print_rr($viewData);die();
$html = view('claims_report_acc_manager_wise', $viewData);
return $this->respond(['status' => true, 'html' => $html], 200);
}else{
$viewData['column_order'] = [
'ACM_NAME', 'CLAIM INTIMATION', 'INTIMATION TO INSURER', 'CLIENT PENDING',
'INSURER PENDING','INVESTIGATION','APPROVED','TOTAL', 'NOT COVERED',
'CLOSED', 'SETTLED', 'CLEARED_TOTAL'
];
$ordered_data = [];
foreach ($viewData['account_manager_wise_data'] as $tpa_data) {
$temp = [];
foreach ($viewData['column_order'] as $key) {
$temp[$key] = isset($tpa_data[$key]) ? $tpa_data[$key] : 0; // Default to 0 if key is missing
}
$ordered_data[] = $temp;
}
$viewData['tpa_wise_data'] = $ordered_data;
// print_rr($viewData);die();
$html = view('claims_report_acc_manager_wise', $viewData);
return $this->respond(['status' => true, 'html' => $html], 200);
}
} elseif ($received_data['report_type'] == 'tpa_wise_status') {
$viewData['tpa_wise_data'] = $this->ticketMasterModel->tpaWiseReport($policy_type, $fromDate, $toDate);
$viewData['column_order'] = [
'TPA_NAME', 'NON ID', 'ID NOT GENERATED', 'CDA', 'INFORMATION REQUIRED',
'UNDER PROCESS - CLAIM NO. UPDATION',
'UNDER PROCESS - QUERY DOCUMENT RECEIVED', 'APPROVED', 'PAYMENT INITIATED',
'TOTAL', 'SETTLED', 'CLOSED', 'CANCELLED', 'RETURNED', 'CLEARED_TOTAL','TPA_ID'
];
// Reorder data based on column order
$ordered_data = [];
foreach ($viewData['tpa_wise_data'] as $tpa_data) {
$temp = [];
foreach ($viewData['column_order'] as $key) {
$temp[$key] = isset($tpa_data[$key]) ? $tpa_data[$key] : 0; // Default to 0 if key is missing
}
$ordered_data[] = $temp;
}
$viewData['tpa_wise_data'] = $ordered_data;
// print_r($ordered_data);die();
// $html = view('claims_report_tpa_wise', $viewData);
$html = view('claims_report_tpa_wise',$viewData);
return $this->respond(['status' => true, 'html' => $html], 200);
} else if ($received_data['report_type'] == 'tat_band_wise') {
$viewData['data'] = $this->ticketMasterModel->getTATReport($policy_type, $fromDate, $toDate);
$viewData['policyType'] = $policy_type;
$viewData['fromDate'] = $fromDate;
$viewData['toDate'] = $toDate;
$html = view('tat_report_band_wise_list', $viewData);
return $this->respond(['status' => true, 'html' => $html], 200);
}
}
}
// -------------------------------------------------------------------------------------------------------------------------
// function for Reject ticket Head Approvel mail sent function
public function sendMailToTheHead($ticket_id)
{
$this->myLogger->logme('error', "sendMailToTheHead Function Called");
$ticket_data = $this->ticketMasterModel->getTicketDataByTicketID($ticket_id);
if(!empty($ticket_data)){
// print_r($ticket_data); die;
$head_mail = $this->employeeModel
->select('user_profiles.email')
->join('clients', 'employees.client_id = clients.id')
->join('client_rm', 'clients.id = client_rm.client_id')
->join('user_profiles', 'client_rm.user_id = user_profiles.id')
->where('employees.is_active', 1)
->where('client_rm.is_active', 1)
->where('client_rm.level', 1)
->where('employees.id', $ticket_data['emp_id'])
->first();
if(!empty($head_mail)){
$template_data = $this->ticketMailTemplateModel
->where('ticket_mail_template.ticket_type', 0)
->where('ticket_mail_template.trigger_type', 0)
->first();
if(!empty($template_data)){
$subject = $this->replacePlaceholders($template_data['subject'], $ticket_data);
$message = $this->replacePlaceholders($template_data['mail_content'], $ticket_data);
$emailData = [
'mail' => $head_mail['email'],
'subject' => $subject,
'message' => $message,
'common' => ['module' => "claim", 'pk' => $ticket_data['id']],
];
$this->sendTrigger($emailData);
}else{
$this->myLogger->logme('error', "Head Mail can't be sent because Template data is empty");
}
}else{
$this->myLogger->logme('error', "Head Mail can't be sent because head mail is empty");
}
}else{
$this->myLogger->logme('error', "Head Mail can't be sent because ticket data is empty");
}
}
public function getLastMatchedStatusOld($incoming_form_values, $old_ticket_data)
{
if (empty($incoming_form_values) || !isset($incoming_form_values['claim_status_id']) || !isset($incoming_form_values['extra_fields_array_for_validate'])) {
return null;
}
$lastMatchedStatus = $incoming_form_values['claim_status_id'];
// Use the provided `extra_fields_array_for_validate` from the incoming data
$statusMapping = json_decode($incoming_form_values['extra_fields_array_for_validate'], true);
// print_r($statusMapping);
// echo "-------------------------------";
//for remove the non used arrays
foreach ($statusMapping as $key1 => $value1) {
foreach ($this->removeArrayKey as $key2 => $value2) {
if($key1 === $key2){
unset($statusMapping[$key1]);
}
}
}
// print_r($statusMapping); die;
// if($incoming_form_values['claim_status_id'] != $old_ticket_data['claim_status_id']){
foreach ($statusMapping as $status => $requiredFields) {
if(!empty($requiredFields) && $status != $old_ticket_data['claim_status_id']){
// Ensure requiredFields is an array
if (!is_array($requiredFields)) {
$requiredFields = [$requiredFields];
}
// Check if all required fields exist and are not empty in the incoming form values
$allFieldsMatched = true;
foreach ($requiredFields as $field) {
if(in_array($field, ['approved_description'])){
continue;
}
if (!isset($incoming_form_values[$field]) || empty($incoming_form_values[$field])) {
$allFieldsMatched = false;
break;
}
}
// Update the last matched status if all fields are validated
if ($allFieldsMatched) {
$lastMatchedStatus = $status;
}
}
}
if($lastMatchedStatus == 1 || $lastMatchedStatus == 67){
if(!empty($incoming_form_values['tpa_no'])){
if($lastMatchedStatus == 1){
$lastMatchedStatus = 2;
}else if($lastMatchedStatus == 67){
$lastMatchedStatus = 68;
}
}
}
// }
return $lastMatchedStatus;
}
public function getLastMatchedStatus($incoming_form_values, $old_ticket_data)
{
// Preserve the incoming claim_status_id (if any) as the safe fallback so callers
// never accidentally nullify the status when validation inputs are missing.
$incomingStatus = $incoming_form_values['claim_status_id'] ?? null;
if (empty($incoming_form_values) || !isset($incoming_form_values['extra_fields_array_for_validate'])) {
return $incomingStatus;
}
$lastMatchedStatus = $incomingStatus;
$statusMapping = json_decode($incoming_form_values['extra_fields_array_for_validate'], true);
if (!is_array($statusMapping) || empty($statusMapping)) {
return $incomingStatus;
}
// Drop transitional / aggregate statuses that should never be auto-selected.
$removeKeys = is_array($this->removeArrayKey) ? $this->removeArrayKey : [];
$statusMapping = array_diff_key($statusMapping, $removeKeys);
$oldStatusId = is_array($old_ticket_data) ? ($old_ticket_data['claim_status_id'] ?? null) : null;
$skipFields = ['approved_description'];
foreach ($statusMapping as $status => $requiredFields) {
if (empty($requiredFields)) {
continue;
}
// Skip the current/old status — we only advance forward to a newer status.
if ($oldStatusId !== null && (int) $status === (int) $oldStatusId) {
continue;
}
if (!is_array($requiredFields)) {
$requiredFields = [$requiredFields];
}
$allFieldsMatched = true;
foreach ($requiredFields as $field) {
if (in_array($field, $skipFields, true)) {
continue;
}
if (!isset($incoming_form_values[$field]) || $incoming_form_values[$field] === '' || $incoming_form_values[$field] === null) {
$allFieldsMatched = false;
break;
}
}
if ($allFieldsMatched) {
$lastMatchedStatus = $status;
}
}
// When a TPA number is present, promote the base "registered" statuses
// (1 -> 2 for standard, 67 -> 68 for the alternate flow).
if (!empty($incoming_form_values['tpa_no']) && in_array((int) $lastMatchedStatus, [1, 67], true)) {
$lastMatchedStatus = ((int) $lastMatchedStatus === 1) ? 2 : 68;
}
return $lastMatchedStatus;
}
public function getPolicyStartDate()
{
$data = $this->request->getPost();
$client_policy_id = $data['policy_id'];
$policy_start_date = $this->clientPolicyModel->select('policy_start_date')->where('id', $client_policy_id)->first()['policy_start_date'];
// dd($data);
if (isset($data['employeeId']) && $data['employeeId'] != "" && $data['employeeId'] != null) {
// dd($data);
$emp_id = $data['employeeId'];
$empData = $this->employeeModel->select('dob,doj')->where('id',$emp_id)->findAll();
if (!empty($empData) && $empData != "" && $empData != null ) {
foreach ($empData as &$emp) { // Loop through the data
$doi = $this->employeePolicyModel->select('date_coverage,basic_cover_si')->where('client_policy_id',$client_policy_id)->first();
$emp['dob'] = date('d/m/Y', strtotime($emp['dob']));
$emp['doj'] = date('d/m/Y', strtotime($emp['doj']));
$emp['date_of_inception'] = date('d/m/Y', strtotime($doi['date_coverage']));
$emp['basic_cover_si'] = $doi['basic_cover_si'];
}
}
if ($empData){
return $this->respond(['status' => true, 'minDate' => $policy_start_date,'empData'=> $empData], 200);
}else{
return $this->respond(['status' => false, 'message' => "Policy Not Found"]);
}
} else {
// dd($policy_start_date);
if ($policy_start_date) {
return $this->respond(['status' => true, 'minDate' => $policy_start_date], 200);
} else {
return $this->respond(['status' => false, 'message' => "Policy Not Found"]);
}
}
}
public function getPoliciesbyEmpID()
{
$emp_id = (int) ($this->request->getPost('emp_id') ?? 0);
$ticket_type_id = (int) ($this->request->getPost('ticket_type_id') ?? 0);
$client_id = (int) ($this->request->getPost('client_id') ?? 0);
if ($emp_id <= 0) {
return $this->respond(['status' => false, 'message' => 'Invalid Employee']);
}
$policyTypeMap = [
1 => [2, 3, 4, 5], // GMC
2 => [1], // GPA
3 => [6], // EDLI
4 => [7], // GTLI
72 => [72], // OPD
];
$db = db_connect();
$builder = $db->table('employee_polices ep');
$builder->select('ep.client_policy_id');
$builder->join('employees e', 'e.id = ep.employee_id');
$builder->join('client_policy cp', 'cp.id = ep.client_policy_id');
$builder->where('ep.employee_id', $emp_id);
$builder->where('ep.is_active', 1);
$builder->whereIn('ep.status', ['active', 'expired']);
$builder->where('e.is_active', 1);
if ($client_id > 0) {
$builder->where('e.client_id', $client_id);
}
if (isset($policyTypeMap[$ticket_type_id])) {
$builder->whereIn('cp.policy_type_id', $policyTypeMap[$ticket_type_id]);
}
$policyRows = $builder->groupBy('ep.client_policy_id')->get()->getResultArray();
$policy_ids = array_values(array_unique(array_column($policyRows, 'client_policy_id')));
if (empty($policy_ids)) {
return $this->respond(['status' => false, 'message' => 'Policy Not Found']);
}
$policyNameandID = $this->clientPolicyModel
->select('
CONCAT(policy_type.policy_type, "-", client_policy.policy_no) as client_policy_name,
client_policy.id as client_policy_value,
client_policy.policy_type_id,
client_policy.policy_no,
insurers.id as insurer_id,
insurers.name as insurer_name,
tpa.name as tpa_name,
tpa.id as tpa_id
')
->join('policy_type', 'policy_type.id = client_policy.policy_type_id AND policy_type.is_active = 1')
->join('insurers', 'insurers.id = client_policy.insurer_id AND insurers.is_active = 1', 'left')
->join('tpa', 'tpa.id = client_policy.tpa_id AND tpa.is_active = 1', 'left')
->whereIn('client_policy.id', $policy_ids)
->findAll();
if (!empty($policyNameandID)) {
return $this->respond(['status' => true, 'policy_data' => $policyNameandID]);
}
return $this->respond(['status' => false, 'message' => 'Policy Not Found']);
}
public function getCheckListAndConvertArrayToString($ticket_data)
{
$data = db_connect()->table('ticket_check_list')
->where('is_active', 1)
->where('ticket_type_id', $ticket_data['ticket_type_id'])
->get()->getResultArray();
$data = !empty($data) ? implode("", array_map(fn($doc) => "<p>{$doc['document']}</p>", $data)) : "";
// $data = !empty($data) ? implode(", ", array_column($data, 'document')) : "";
// print_r($data); die;
return $data;
}
public function downloadClaimForm($insurer_id)
{
$insurerModel = new InsurerModel();
$insurer_data = $insurerModel->where('MD5(id)', $insurer_id)->where('is_active', 1)->first();
if (!$insurer_data) {
$data['message'] = 'The Physical File Not Found';
echo view('errors/404', $data);
return;
}
$claimFormFile = resolve_insurer_claim_form_file($insurer_data);
try {
if (!empty($claimFormFile['available']) && !empty($claimFormFile['file_path'])) {
return $this->response->download($claimFormFile['file_path'], null)
->setFileName($claimFormFile['file_name']);
}
$data['message'] = 'The Physical File Not Found';
echo view('errors/404', $data);
} catch (\Exception $e) {
$this->myLogger->logme('error', $e->getMessage());
return $this->response->setStatusCode(500)->setBody('An error occurred while downloading the file.');
}
}
// -------------------------------------------------------------------------------------------------------------------------
public function autoMessageInsertBasedOnMailResponse($mail_sent_status, $ticket_id)
{
if (gettype($mail_sent_status) == 'array') {
$this->myLogger->logme('error', "auto Message Insert Based On Mail Response Failed because is array :$ticket_id ");
} else {
$mail_sent_status = json_decode($mail_sent_status);
$this->myLogger->logme('error', "mail_sent_status is object :$ticket_id ");
}
if (!empty($mail_sent_status) && isset($mail_sent_status->status) && $mail_sent_status->status == 'success') {
$sent_message_data['ticket_id'] = $ticket_id;
$sent_message_data['sender'] = 'staff';
$sent_message_data['emp_mail'] = isset($mail_sent_status->data->params->mail[0]) ? $mail_sent_status->data->params->mail[0] ?? null : $mail_sent_status->data->params->mail ?? null;
$sent_message_data['mail_subject'] = $mail_sent_status->data->params->subject;
$sent_message_data['mail_content'] = $mail_sent_status->data->params->message;
$message_insert_status = $this->ticketMessageModel->insert($sent_message_data);
if ($message_insert_status) {
$this->myLogger->logme('error', "Claim initiated, Mail sent Successfully, successfully store message:$ticket_id ");
} else {
$this->myLogger->logme('error', "Claim initiated, Mail sent Successfully, Failed to store message:$ticket_id ");
}
return true;
} else {
$this->myLogger->logme('error', "Failed to send Mail :$ticket_id ");
return false;
}
}
public function putHistoryAfterInsert($ticket_data, $ticket_id)
{
$this->myLogger->logme('error', "Put History After Insert function called : $ticket_id");
if(!empty($ticket_data)){
$history_data = [
'ticket_id' => $ticket_id,
'field_name' => 'claim_status_id',
'display_name' => 'Ticket Created',
'old_value' => null,
'new_value' => $ticket_data['claim_status_id'],
'created_by' => get_session_userid(),
'is_active' => 1
];
$this->myLogger->logme('error', "Put History After Insert function called : " . json_encode($history_data));
$history_insert = $this->ticketHistoryModel->insert($history_data);
if($history_insert){
$this->myLogger->logme('error', "Put History After Insert Ticket Data Successfully");
}else{
$this->myLogger->logme('error', "Put History After Insert Ticket Data Failed");
}
}else{
$this->myLogger->logme('error', "Put History After Insert Ticket Data is empty");
}
return true;
}
public function viewClaimFeedbackForm($md5_ticket_id,$empView = null)
{
if ($this->request->is("get")){
$data['ticket_id'] = $md5_ticket_id;
$data['ticket_data'] = $this->ticketMasterModel->select('ticket_master.*,clients.client_name')->join('clients','clients.id = ticket_master.client_id')->where('MD5(ticket_master.id)',$md5_ticket_id)->where('ticket_master.is_active',1)->first();
$data['form_submitted'] = !empty($data['ticket_data']['feedback_json'])? 1 : 0;
$data['viewer'] = !empty($empView) ? $empView : 0;
// dd($data);
return view('ticket_feedback_form', $data);
}else{
$formDataJson = json_encode($this->request->getPost());
// log_message("error","Form data : ".$formDataJson);
$data_to_store = [
'feedback_json' => $formDataJson
];
if (!empty($formDataJson)){
// $this->ticketMasterModel->save($data_to_store);
$this->ticketMasterModel->where('MD5(id)', $md5_ticket_id)->set($data_to_store)->update();
return $this->respond(['status' => true,'id'=> $md5_ticket_id,'received_data' => $formDataJson], 200);
}else{
return $this->respond(['status' => false,'id'=> $md5_ticket_id,'received_data' => $formDataJson], 200);
}
}
}
public function feedbackList()
{
$data['feedback_data'] = $this->ticketMasterModel->select("ticket_master.*,clients.client_name")->join("clients","clients.id = ticket_master.client_id")->where("ticket_master.is_active",1)->where("ticket_master.feedback_json IS NOT NULL", null, false)->where("ticket_master.feedback_json !=", "")->findAll();
$data['page_name'] = "Claims";
// dd($data);
$this->loadLayout("ticket_feedback_list",$data);
}
public function getMoreInfo($requestFrom = null , $ticket_id = null)
{
if($requestFrom == null){
$ticket_id = $this->request->getPost('ticket_id');
}
$this->myLogger->logme("error", "Ticket ID : " . $ticket_id);
$fields = $this->extraFields;
$displayFields = $this->extraFieldsDisplayForFrontend;
$data_to_send = [];
// Get ticket data
$ticket_data = $this->ticketMasterModel->where("id", $ticket_id)->where("is_active", 1)->first();
// Query previous status
$ticket_previous_status = $this->ticketMasterModel
->select("th.old_value, tcs.claim_status")
->join("ticket_history th", "th.ticket_id = ticket_master.id AND th.field_name = 'claim_status_id' AND th.is_active = 1")
->join("ticket_claim_status tcs", "tcs.id = th.old_value AND tcs.is_active = 1")
->where("ticket_master.is_active", 1)
->where("ticket_master.id", $ticket_id)
->groupBy("th.old_value, tcs.claim_status")
->get()
->getResultArray();
// dd($ticket_previous_status);
// Loop through previous status and gather the required data
foreach ($ticket_previous_status as $status) {
// $this->myLogger->logme("error", "Status : " . json_encode($status));
if (isset($fields[$status['old_value']])) {
$field = $fields[$status['old_value']];
// print_r($field);
// Ensure claim_status is a scalar value (string or int)
$claim_status = (string)$status['claim_status']; // Cast to string to avoid issues
// echo $claim_status;
// dd($displayFields[$status['old_value']]);
// Initialize claim_status if it doesn't exist in the array
if (!isset($data_to_send[$claim_status])) {
$data_to_send[$claim_status] = [];
}
// Handle case where $field is an array
if (is_array($field)) {
foreach ($field as $f) {
// dd($displayFields[$status['old_value']]);
// Check if the field exists in the ticket data
$data_to_send[$claim_status][$f] = ['display_name' => $displayFields[$status['old_value']][$f] ,'display_value' => isset($ticket_data[$f]) ? $ticket_data[$f] : null];
// dd($data_to_send);
// Check if the field contains a date and format it
if ($this->isDate($data_to_send[$claim_status][$f]['display_value'])) {
$data_to_send[$claim_status][$f] = ['display_name' => $displayFields[$status['old_value']][$f] ,'display_value' => date('d-m-Y', strtotime($data_to_send[$claim_status][$f]['display_value']))];
// $data_to_send[$claim_status][$f] = date('d-m-Y', strtotime($data_to_send[$claim_status][$f]));
}
// $this->myLogger->logme("error", "Data for field {$f}: " . json_encode($data_to_send[$claim_status][$f]));
}
} else {
// If field is not an array, handle it as a single field
// Check if the field exists in the ticket data
$data_to_send[$claim_status] = ['display_name' => $displayFields[$status['old_value']] ,'display_value' => isset($ticket_data) ? $ticket_data : null];
// Check if the field contains a date and format it
if ($this->isDate($data_to_send[$claim_status][$field])) {
// $data_to_send[$claim_status] = ['display_name' => $displayFields[$status['old_value']] ,'display_value' => date('d-m-Y', strtotime($data_to_send[$claim_status]['display_value']))];
}
// $this->myLogger->logme("error", "Data for field {$field}: " . json_encode($data_to_send[$claim_status][$field]));
}
}
}
// $this->myLogger->logme('error', "Total data: " . json_encode($data_to_send));
if($requestFrom == 'rest'){
return $data_to_send;
}
// Send response based on data availability
if (!empty($data_to_send)) {
return $this->respond(['status' => true, 'data' => $data_to_send], 200);
} else {
return $this->respond(['status' => false], 200);
}
}
private function isDate($value, $format = 'Y-m-d')
{
// Check if the value is a valid date string (basic validation)
$date = \DateTime::createFromFormat($format, $value);
return $date && $date->format($format) === $value;
}
/**
* Claim upload URL row: allow http(s) with path, query, port; bare host with TLD; localhost; IPv4/IPv6.
* Replaces the old strict regex that rejected ?query= and long TLDs.
*/
private function isClaimUploadUrl(string $s): bool
{
$v = trim($s);
if ($v === '' || strlen($v) > 2048) {
return false;
}
if (! preg_match('#^https?://#i', $v)) {
$v = 'https://' . $v;
}
$parts = parse_url($v);
if ($parts === false || empty($parts['host'])) {
return false;
}
$scheme = strtolower($parts['scheme'] ?? '');
if ($scheme !== 'http' && $scheme !== 'https') {
return false;
}
$host = strtolower($parts['host']);
if ($host === 'localhost') {
return true;
}
$hostForIp = $host;
if (strlen($host) > 2 && $host[0] === '[' && substr($host, -1) === ']') {
$hostForIp = substr($host, 1, -1);
}
if (filter_var($hostForIp, FILTER_VALIDATE_IP)) {
return true;
}
return strpos($host, '.') !== false;
}
private function uploadApprovedLetterPdf($file, string $documentLabel = 'Approved Letter'): array
{
if ($file === null || ! $file->isValid() || $file->getError() === UPLOAD_ERR_NO_FILE) {
return ['status' => false, 'message' => $documentLabel . ' file is missing.'];
}
$ext = strtolower((string) $file->getClientExtension());
$mime = strtolower((string) $file->getMimeType());
$allowedMime = ['application/pdf', 'application/x-pdf'];
if ($ext !== 'pdf' || (! empty($mime) && ! in_array($mime, $allowedMime, true))) {
return ['status' => false, 'message' => 'Only PDF files are allowed for ' . $documentLabel . ' upload.'];
}
$uploadPath = WRITEPATH . 'uploads/claim_files/';
if (! is_dir($uploadPath)) {
mkdir($uploadPath, 0755, true);
}
$uploaded = storage_claim_file_Upload($file, $uploadPath, ['pdf']);
if ($uploaded === '') {
return ['status' => false, 'message' => 'Failed to upload ' . $documentLabel . ' file.'];
}
return [
'status' => true,
'data' => [
'file_name' => $uploaded['disk_name'],
'mime_type' => $mime ?: 'application/pdf',
],
];
}
private function createApprovedLetterFileUrl(int $ticketId, int $ticketTypeId, array $uploadedFile, string $docName = 'APPROVED_LETTER_PDF'): string
{
$fileId = $this->claimFilesModel->insert([
'ticket_id' => $ticketId,
// 'ticket_type' => $ticketTypeId,
'file_type' => 3,
'doc_name' => $docName,
'file_name' => $uploadedFile['file_name'],
'url' => $uploadedFile['file_name'],
'mime_type' => $uploadedFile['mime_type'] ?? 'application/pdf',
'is_active' => 1,
]);
return base_url('downloadClaimFile/' . $fileId);
}
public function upload_url()
{
$request_data = $this->request->getPost();
$data = sanitizeInputArrayAdvanced($request_data);
$rules = [
'ticket_id_url' => [
'label' => 'Ticket ID URL',
'rules' => 'required|numeric',
'errors' => [
'required' => 'System could not identify the Number.',
'numeric' => 'Invalid format.'
]
],
'docs_name.*' => [
'label' => 'Required Documents',
'rules' => 'required|regex_match[/^[a-zA-Z0-9_\- ]+$/]',
'errors' => [
'required' => 'Document Name is required',
'regex_match' => 'Document Name can only contain letters, numbers, hyphens, and underscores'
]
],
'url.*' => [
'label' => 'URL',
'rules' => 'if_exist|required',
'errors' => [
'required' => 'URL is required.',
]
],
];
if (!$this->validate($rules)) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Input validation failed',
'code' => 400,
'errors' => $this->validator->getErrors()
]);
}
if (! empty($data['url']) && is_array($data['url'])) {
foreach ($data['url'] as $idx => $singleUrl) {
$singleUrl = (string) $singleUrl;
if (trim($singleUrl) !== '' && ! $this->isClaimUploadUrl($singleUrl)) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Input validation failed',
'code' => 400,
'errors' => [
'url.' . $idx => 'The URL format is invalid. Use https://example.com/path?x=1 or example.com',
],
]);
}
}
}
$get_file_data = $this->request->getFiles('file_upload') ?? [];
$ticket_id = $data['ticket_id_url'];
if(empty($get_file_data)){
$insertArr = [];
foreach ($data['docs_name'] as $key => $eachData) {
if (!empty($eachData)) {
$insertData = [
'doc_name' => $data['docs_name'][$key] ?? '',
'url' => convertGoogleDriveToDownloadLink($data['url'][$key] ?? ''),
'ticket_id' => $data['ticket_id_url'] ?? '',
'created_by' => get_session_userid(),
'is_active' => 1,
'file_type' => 1
];
$insertArr[] = $insertData;
}
}
if (!empty($insertArr)) {
// Insert into database
$insert = $this->claimFilesModel->insertBatch($insertArr);
}
if (isset($insert) && !empty($insert)) {
return $this->respond(['status' => true, 'message' => 'File uploaded successfully ']);
} else {
return $this->respond(['status' => false, 'message' => 'Failed to upload file ']);
}
}else{
$get_docs_name = $data['docs_name'];
$file_data = [];
if(isset($get_file_data) && !empty($get_file_data)){
$file_path = WRITEPATH . 'uploads/claim_files/';
$file_data = storage_multi_file_Upload($get_file_data, $file_path, $get_docs_name, UPLOAD_EXT_CLAIM_DOCS);
}
if(!empty($file_data)){
$employeeRest = new EmployeeRestController();
$result = $employeeRest->handleCliamFiles($file_data, $ticket_id);
if(!empty($result)){
return $this->respond(['status' => true, 'message' => 'File uploaded successfully ']);
}else{
return $this->respond(['status' => false, 'message' => 'Failed to upload file ']);
}
}else{
return $this->respond(['status' => false, 'message' => 'Failed to upload file ']);
}
}
}
//get the claim file list data against the ticket id
public function getUrlDataByTicketId()
{
$ticket_id = $this->request->getPost('ticket_id');
if (!$ticket_id) {
return $this->response->setJSON([
'status' => false,
'message' => 'Ticket ID is required',
'data' => []
]);
}
$urlData = $this->claimFilesModel
->select("
*,
CASE
WHEN file_type IN (2, 4) AND url IS NOT NULL AND url != ''
THEN CONCAT('" . base_url('downloadClaimFile/') . "', id)
ELSE url
END AS url
")
->where('ticket_id', $ticket_id)
->where('file_type !=', 3) // Assuming you want to fetch both URL and file uploads
->where('is_active', 1)
->findAll();
helper('merge_pdf');
$mergeUi = merge_ticket_manual_merge_status((int) $ticket_id);
return $this->response->setJSON([
'status' => true,
'data' => $urlData,
'merge_ui' => $mergeUi,
]);
}
/**
* Manually merge claim PDF/image files for a ticket (Claim Files tab).
*/
public function manualMergeClaimFiles()
{
$ticket_id = (int) $this->request->getPost('ticket_id');
if ($ticket_id <= 0) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Ticket ID is required',
]);
}
helper('merge_pdf');
$mergeUi = merge_ticket_manual_merge_status($ticket_id);
if (! $mergeUi['show_manual_merge'] && $mergeUi['mergeable_count'] < 1) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'No PDF or image files available on disk to merge.',
]);
}
$ticket = $this->ticketMasterModel
->select('id, ticket_type_id')
->where('id', $ticket_id)
->where('is_active', 1)
->first();
if (! $ticket) {
return $this->response->setStatusCode(404)->setJSON([
'status' => false,
'message' => 'Claim not found.',
]);
}
try {
$result = merge_ticket_pdfs($ticket_id, [
'ticket_type' => (int) ($ticket['ticket_type_id'] ?? 1),
'created_by' => function_exists('get_session_userid') ? get_session_userid() : null,
]);
} catch (\Throwable $e) {
log_message('error', 'TicketController::manualMergeClaimFiles | ticket_id=' . $ticket_id . ' | ' . $e->getMessage());
return $this->response->setStatusCode(500)->setJSON([
'status' => false,
'message' => 'Merge failed: ' . $e->getMessage(),
]);
}
if (! ($result['status'] ?? false)) {
return $this->response->setJSON([
'status' => false,
'message' => $result['message'] ?? 'Merge failed. Check logs for details.',
'data' => $result,
]);
}
return $this->response->setJSON([
'status' => true,
'message' => $result['message'] ?? 'Documents merged successfully.',
'data' => $result,
]);
}
public function remove_url()
{
$id = $this->request->getGet('id');
if (empty(trim($id ?? ''))) {
return $this->response->setJSON([
'status' => false,
'message' => 'Invalid ID'
]);
}
if (storage_soft_delete_claim_file((int) $id)) {
return $this->response->setJSON([
'status' => true,
'message' => 'URL successfully marked inactive.'
]);
}
return $this->response->setJSON([
'status' => false,
'message' => 'Failed to update record.'
]);
}
public function recursive_json_decode($input)
{
if (is_string($input)) {
$decoded = json_decode($input, true);
if (json_last_error() === JSON_ERROR_NONE) {
return $this->recursive_json_decode($decoded); // continue decoding recursively
} else {
return $input;
}
}
if (is_array($input)) {
foreach ($input as $key => $value) {
$input[$key] = $this->recursive_json_decode($value);
}
}
return $input;
}
public function convertTermsToDisplay(array $data)
{
$result = [];
$LableKeys = [
"sum_insured" => "Sum Insured",
"family_floater" => "Family Floater",
"family_floaters" => "Family Floater Details",
"age_ratio" => "Age Ratio",
"is_payable_employee" => "Payable by Employee",
"waiverofpreexistingdiseases" => "Waivers of Pre Existing Diseases",
"waiverof1,2,3&4thyearexclusions" => "Waivers of 1, 2, 3 & 4th Year Exclusions",
"waiverof30dayswaitingperiod" => "Waivers of 30 Days Waiting Period",
"waiver_of_90_days_waiting_period" => "Waiver of 90 Days Waiting Period",
"waiver_of_other_waiting_periods" => "Waiver of Other Waiting Periods",
"maternity_benefit" => "Maternity Benefit",
"9monthwaitingperiodwaived" => "9 Month Waiting Period Waived",
"maternitycoverage" => "Maternity Coverage",
"twindelivery" => "Twin Delivery",
"well_baby_well_mother_expenses" => "Well Baby & Well Mother Expenses",
"preandpostnatal" => "Pre and Post Natal",
"infertility_treatment_coverage" => "Infertility Treatment Coverage",
"babyday1cover" => "Baby Day 1 Cover",
"coverfromthedateofjoining" => "Cover from the Date of Joining",
"mid_term_addition_of_new_born_newly_wedded_spouse" => "Mid Term Addition of New Born / Newly Wedded Spouse",
"prehospitalizationcover" => "Pre Hospitalization Cover",
"posthospitalizationcover" => "Post Hospitalization Cover",
"congenitaldiseasesinternal" => "Congenital Diseases - Internal",
"congenitaldiseasesexternal" => "Congenital Diseases - External",
"copayzonewisecopay" => "Co-Pay (Zone Wise)",
"roomrentlimit" => "Room Rent Limit",
"icu_limit" => "ICU Limit",
"proportionatedeductionclause" => "Proportionate Deduction Clause",
"ailmentcapping" => "Ailment Capping",
"ailment_capping_details" => "Ailment Capping Details",
"corporatebuffer" => "Corporate Buffer",
"non_admissible_contingency_corporate_buffer" => "Non-Admissible Contingency Corporate Buffer",
"ambulancecharges" => "Ambulance Charges",
"airambulance" => "Air Ambulance",
"reasonableandcustomarycharges" => "Reasonable and Customary Charges",
"daycaretreatment" => "Day Care Treatment",
"lasiksurgery" => "Lasik Surgery",
"ayudhtreatmentcover" => "Ayudh Treatment Cover",
"moderntreatmentsasperirdai" => "Modern Treatments as per IRDAI",
"opd_treatment" => "OPD Treatment",
"days_of_discharge" => "Days of Discharge",
"days_from_dod" => "Days from Date of Discharge",
"terrorism" => "Terrorism Cover",
"widower_cover" => "Widower Cover",
"breavement_cover" => "Breavement Cover",
"suminsuredenhancement" => "Sum Insured Enhancement",
"special_condition_label" => "Special Condition Label",
"special_condition_input" => "Special Condition Input"
];
// // 1. Family Floaters
// $floatersMap = [
// 'self' => '<b>Self</b>',
// 'spouse' => 'Spouse',
// 'childrens' => 'Childrens',
// 'parents' => 'Parents',
// 'parents-in-law' => 'Parents-in-law',
// 'either-parents-pil' => 'Either Parents/PIL',
// 'elders_count' => 'Elders'
// ];
// 1. Family Floaters
$floatersMap = [
'self' => '<b style="color : #000;">Self</b>',
'spouse' => '<b style="color : #000;">Spouse</b>',
'childrens' => '<b style="color : #000;">Childrens</b>',
'parents' => '<b style="color : #000;">Parents</b>',
'parents-in-law' => '<b style="color : #000;">Parents-in-law</b>',
'either-parents-pil' => '<b style="color : #000;">Either Parents/PIL</b>',
'elders_count' => '<b style="color : #000;">Total Elders Count</b>'
];
if(isset($data['family_floaters'])){
$floatersOutput = [];
foreach ($floatersMap as $key => $label) {
if (isset($data['family_floaters'][$key])) {
$val = $data['family_floaters'][$key];
$floatersOutput[] = "$label : " . ($val > 0 ? $val : 'No');
}
}
$data['family_floaters'] = implode(', ', $floatersOutput);
}
// 2. Age Ratio
if (!empty($data['age_ratio'])) {
$ageOutput = [];
foreach ($data['age_ratio'] as $person => $age) {
if (isset($age['min']) && isset($age['max'])) {
// $ageOutput[] = ucfirst($person) . " - Min : {$age['min']}, Max : {$age['max']}";
$ageOutput[] = "<b style='color : #000;'>" . ucfirst($person) . "</b> - <b> Min </b>: {$age['min']}, <b> Max </b> : {$age['max']}";
}
}
$data['age_ratio'] = implode(', ', $ageOutput);
}
// 3. Is Payable Employee
if (!empty($data['is_payable_employee'])) {
$payableOutput = [];
foreach ($data['is_payable_employee'] as $person => $status) {
// $payableOutput[] = ucfirst($person) . " : " . ($status ? 'Yes' : 'No');
$payableOutput[] = "<b style='color : #000;'>" . ucfirst($person) . "</b> : " . ($status ? 'Yes' : 'No');
}
$data['is_payable_employee'] = implode(', ', $payableOutput);
}
// 4. Remove the Enrollment display key
if(isset($data['enrollment_display_key'])){
unset($data['enrollment_display_key']);
}
// 5. Merge the Sum Insured value if the multiple sum insured exists
if (isset($data['multiple_sum_insured'])) {
$multipleSumInsured = is_array($data['multiple_sum_insured']) ? $data['multiple_sum_insured'] : [$data['multiple_sum_insured']]; // force into array if string
if (isset($data['sumInsured2'])) {
$data['sumInsured2'] .= ", " . implode(", ", $multipleSumInsured);
} else {
$data['sum_insured'] .= ", " . implode(", ", $multipleSumInsured);
}
unset($data['multiple_sum_insured']);
}
// 6. Add the special condition to key value pair
if(!empty($data['special_condition_label'])){
foreach ($data['special_condition_label'] as $key => $value) {
if($value != "" && $value != null) {
$data[$value] = $data['special_condition_input'][$key];
}
}
}//GMC
if(!empty($data['gpa_special_condition_label'])){
foreach ($data['gpa_special_condition_label'] as $key => $value) {
if($value != "" && $value != null) {
$data[$value] = $data['gpa_special_condition_input'][$key];
}
}
}//GPA
// 7. Remove the special condition keys
unset($data['special_condition_label']);
unset($data['special_condition_input']);
unset($data['gpa_special_condition_label']);
unset($data['gpa_special_condition_input']);
if(isset($data['sumInsured2'])){
$firstItem = ["Sum Insured" => $data['sumInsured2']];
unset($data['sumInsured2']);
$data = $firstItem + $data;
}
// 8. Change the key name to lable name
$result = [];
foreach ($data as $key => $value) {
// $label = isset($LableKeys[$key]) ? $LableKeys[$key] : $key;
if (isset($LableKeys[$key])) {
$label = $LableKeys[$key];
// echo "1";
} else {
// Handle camelCase first, then snake_case
$label = preg_replace('/(?<!^)[A-Z]/', ' $0', $key); // camelCase → space
$label = ucwords(str_replace('_', ' ', $label)); // snake_case → space & capitalize
// echo "2";
}
$result[$label] = $value == 1 ? "Yes" : ($value == 0 ? "No" : $value);
}
// return count($result);
// return $data;
return $result;
}
public function getClaimTemplateData()
{
try {
$ticket_id = $this->request->getPost('ticket_id') ?? $this->request->getGet('ticket_id');
$status_id = $this->request->getPost('status_id') ?? $this->request->getGet('status_id');
if (empty($ticket_id) || empty($status_id)) {
return $this->respond(['status' => false, 'message' => 'Ticket ID and Status ID are required'], 400);
}
$mail_content = $this->constructMailContent($ticket_id, $status_id);
if ($mail_content) {
return $this->respond(['status' => true, 'data' => $mail_content], 200);
}
return $this->respond(['status' => false, 'message' => 'Failed to construct mail content'], 200);
} catch (\Exception $e) {
$this->myLogger->logme('error', 'Error in getClaimTemplateData: ' . $e->getMessage() . ' in file ' . $e->getFile() . ' on line ' . $e->getLine() . $e->getTraceAsString());
return $this->respond(['status' => false, 'message' => 'An error occurred while fetching template data'], 500);
}
}
public function uploadApprovedLetterFromReply()
{
try {
$ticket_id = $this->request->getPost('ticket_id');
$status_id = $this->request->getPost('status_id');
$approvedLetterUrl = trim((string) $this->request->getPost('approved_letter'));
$approvedLetterFile = $this->request->getFile('approved_letter_file');
if (empty($ticket_id) || empty($status_id)) {
return $this->respond(['status' => false, 'message' => 'Ticket ID and Status ID are required'], 400);
}
if ((int) $status_id !== 9) {
return $this->respond(['status' => false, 'message' => 'Approved letter upload is allowed only for APPROVED status'], 400);
}
$ticket_data = $this->ticketMasterModel->getTicketDataByTicketID($ticket_id);
if (empty($ticket_data)) {
return $this->respond(['status' => false, 'message' => 'Ticket not found'], 404);
}
$claimStatusId = (int) ($ticket_data['claim_status_id'] ?? 0);
$approvedLetterReplaceStatuses = [10, 11];
if (!empty($ticket_data['approved_letter']) && !in_array($claimStatusId, $approvedLetterReplaceStatuses, true)) {
return $this->respond([
'status' => false,
'message' => 'Approved letter already available',
'data' => ['approved_letter' => $ticket_data['approved_letter']],
], 200);
}
$hasApprovedLetterFile = $approvedLetterFile !== null
&& $approvedLetterFile->isValid()
&& $approvedLetterFile->getError() !== UPLOAD_ERR_NO_FILE;
if ($approvedLetterUrl !== '' && $hasApprovedLetterFile) {
return $this->respond([
'status' => false,
'message' => 'Provide either Approved Letter URL or Approved Letter PDF file, not both.',
], 400);
}
if ($approvedLetterUrl !== '' && !$this->isClaimUploadUrl($approvedLetterUrl)) {
return $this->respond(['status' => false, 'message' => 'Approved Letter URL format is invalid.'], 400);
}
if ($approvedLetterUrl === '' && !$hasApprovedLetterFile) {
return $this->respond(['status' => false, 'message' => 'Provide Approved Letter URL or Approved Letter PDF file.'], 400);
}
$approvedLetterValue = $approvedLetterUrl;
if ($hasApprovedLetterFile) {
$uploadResult = $this->uploadApprovedLetterPdf($approvedLetterFile, 'Approved Letter');
if (!($uploadResult['status'] ?? false)) {
return $this->respond(['status' => false, 'message' => $uploadResult['message'] ?? 'Invalid Approved Letter file.'], 400);
}
$approvedLetterValue = $this->createApprovedLetterFileUrl(
(int) $ticket_id,
(int) ($ticket_data['ticket_type_id'] ?? 1),
$uploadResult['data'],
'APPROVED_LETTER_PDF'
);
}
$this->ticketMasterModel
->where('id', (int) $ticket_id)
->set(['approved_letter' => $approvedLetterValue])
->update();
return $this->respond([
'status' => true,
'message' => 'Approved letter uploaded successfully',
'data' => ['approved_letter' => $approvedLetterValue],
], 200);
} catch (\Exception $e) {
$this->myLogger->logme('error', 'Error in uploadApprovedLetterFromReply: ' . $e->getMessage() . ' in file ' . $e->getFile() . ' on line ' . $e->getLine() . $e->getTraceAsString());
return $this->respond(['status' => false, 'message' => 'An error occurred while uploading approved letter'], 500);
}
}
public function uploadClaimFilesToTPA()
{
try {
$ticket_id = $this->request->getPost('ticket_id');
if (empty($ticket_id)) {
return $this->respond(['status' => false, 'message' => 'Ticket ID and Status ID are required'], 400);
}
$apiServiceController = new ApiServiceController();
$response = $apiServiceController->pushClaimFiles($ticket_id);
if ($response['status'] ?? false) {
return $this->respond(['status' => true, 'message' => 'Claim files uploaded to TPA successfully'], 200);
} else {
return $this->respond(['status' => false, 'message' => $response['message'] ?? 'Failed to upload claim files to TPA'], 200);
}
} catch (\Exception $e) {
$this->myLogger->logme('error', 'Error in uploadClaimFilesToTPA: ' . $e->getMessage() . ' in file ' . $e->getFile() . ' on line ' . $e->getLine() . $e->getTraceAsString());
return $this->respond(['status' => false, 'message' => 'An error occurred while uploading claim files to TPA'], 500);
}
}
// -------- CLAIM DUMP UPLOAD ----------------------------------------------------------------------------------------------
public function claimDumpUpload()
{
$data['tab_name'] = "Claim Dump Upload";
$data['page_name'] = "Claims";
$data['tpa_list'] = $this->TPAModel->where('is_active', 1)->findAll();
if($this->request->is('get')){
$data['claim_dump_file_data'] = $this->claimDumpFileModel
->select('
claim_dump_files.id as file_id,
claim_dump_files.file_name,
claim_dump_files.status,
claim_dump_files.tpa_id,
claim_dump_files.created_at,
up.first_name as user_name,
c.client_name,
cp.policy_no
')
->join('user_profiles as up', 'claim_dump_files.created_by = up.id', 'left')
->join('client_policy as cp', 'claim_dump_files.client_policy_id = cp.id', 'left')
->join('clients as c', 'cp.client_id = c.id', 'left')
->where('claim_dump_files.is_active', 1)
->orderBy('claim_dump_files.id', 'desc')
->findAll();
$data['claim_dump_file_data'] = $this->attachPendingDumpTicketCounts(
$data['claim_dump_file_data'] ?? []
);
return $this->loadLayout('claim_dump_file_list', $data);
}else{
// print_r($this->request->getFile('claim_dump_list')); die;
$filename = '';
$fileSize = '';
//validate uploaded file
$validated = $this->validate([
'claim_dump_list' => [
'uploaded[claim_dump_list]',
'mime_in[claim_dump_list,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.oasis.opendocument.spreadsheet]',
'max_size[claim_dump_list,16384]',
],
]);
if ($validated)
{
$avatar = $this->request->getFile('claim_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/claim_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';
$claim_dump_date = null;
$claim_dump_date_input = trim((string) ($this->request->getPost('claim_dump_date') ?? ''));
if (!empty($claim_dump_date_input)) {
$claim_dump_date = change_date_format($claim_dump_date_input, 'd/m/Y', 'Y-m-d');
}
$insert_data = [
'file_name' => $filename,
'status' => $status,
'client_id' => !empty($this->request->getPost('client_id')) ? $this->request->getPost('client_id') : null,
'client_policy_id' => !empty($this->request->getPost('client_policy_id')) ? $this->request->getPost('client_policy_id') : null,
'tpa_id' => !empty($this->request->getPost('tpa_id')) ? $this->request->getPost('tpa_id') : null,
'claim_dump_date' => $claim_dump_date,
];
$file_id = $this->claimDumpFileModel->insert($insert_data);
$this->myLogger->logme("error", 'claim_dumb_file_id : {file_id}, uploaded success', ['file_id' => $file_id]);
log_message('error', '[CLAIM_DUMP][UPLOAD_SAVED] file_id=' . $file_id
. ' file_name=' . $filename
. ' client_id=' . ($insert_data['client_id'] ?? 'null')
. ' client_policy_id=' . ($insert_data['client_policy_id'] ?? 'null')
. ' tpa_id=' . ($insert_data['tpa_id'] ?? 'null'));
//after file upload success than call the file formate validation in service controller
// $ticketServiceController = new TicketServiceController();
if(!empty($insert_data['tpa_id'])){
$r = Jobs::addJob(['job_name' => 'tpaClaimDumpImporter', 'payload' => ['file_id' => $file_id]]);
log_message('error', '[CLAIM_DUMP][UPLOAD_QUEUED_JOB1] file_id=' . $file_id . ' job=tpaClaimDumpImporter');
// $response = $ticketServiceController->claimDumpExcelFileFormatValidation(["file_id" => $file_id]);
}else{
$r = Jobs::addJob(['job_name' => 'claimDumpExcelFileFormatValidation', 'payload' => ['file_id' => $file_id]]);
log_message('error', '[CLAIM_DUMP][UPLOAD_QUEUED_LEGACY] file_id=' . $file_id . ' job=claimDumpExcelFileFormatValidation');
// $response = $ticketServiceController->claimDumpExcelFileFormatValidation(["file_id" => $file_id]);
}
return $this->respond(['status' => true, 'code' => 200, 'message' => 'File uploaded successfully. File being validated'], 200);
}
}
public function getClaimDumpFileErrorData()
{
$file_id = $this->request->getGet('file_id');
$file = $this->claimDumpFileModel->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 getClaimDumpExcelFileErrors($file_id)
{
// $file_id = $this->request->getGet('file_id');
$ticketServiceController = new TicketServiceController();
// Render views and capture output
$result = $ticketServiceController->getClaimExcelErrorData($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 downloadClaimDumpFile($file_id)
{
// $actionType = $this->request->getGet();
$file_data = $this->claimDumpFileModel->where('id', $file_id)->first();
if (empty($file_data)) {
$data['message'] = 'File record not found';
return view('errors/404', $data);
}
$fileName = $file_data['file_name'];
try {
$download = $this->downloadFileFromStorage(WRITEPATH . 'uploads/claim_dump_excel', $fileName);
if ($download !== null) {
return $download;
}
$data['message'] = 'The Physical File Not Found';
return view('errors/404', $data);
} catch (\Exception $e) {
// Handle any exceptions
$errorMessage = $e->getMessage();
$this->myLogger->logme('error', $errorMessage);
$data['message'] = 'The Physical File Not Found';
return view('errors/404', $data);
}
}
/**
* Soft-delete a TPA claim dump upload: dump rows + tickets created by that file_id.
*/
public function truncateClaimDumpFile()
{
$fileId = (int) ($this->request->getGet('file_id') ?? $this->request->getPost('file_id') ?? 0);
log_message('error', '[CLAIM_DUMP][CTRL_TRUNCATE_START] file_id=' . $fileId);
if ($fileId <= 0) {
log_message('error', '[CLAIM_DUMP][CTRL_TRUNCATE_INVALID] file_id=' . $fileId);
return $this->respond(['status' => false, 'code' => 400, 'message' => 'file_id is required'], 200);
}
$fileData = $this->claimDumpFileModel->where('id', $fileId)->where('is_active', 1)->first();
if (empty($fileData)) {
log_message('error', '[CLAIM_DUMP][CTRL_TRUNCATE_NOT_FOUND] file_id=' . $fileId);
return $this->respond(['status' => false, 'code' => 404, 'message' => 'File not found or already truncated'], 200);
}
$tpaId = (int) ($fileData['tpa_id'] ?? 0);
if ($tpaId <= 0) {
log_message('error', '[CLAIM_DUMP][CTRL_TRUNCATE_NO_TPA] file_id=' . $fileId);
return $this->respond(['status' => false, 'code' => 400, 'message' => 'Truncate is only supported for TPA claim dumps'], 200);
}
try {
$handler = \App\Libraries\TpaClaimsImportFactory::make($tpaId);
$result = $handler->softTruncateClaimDump($fileId);
log_message(
!empty($result['status']) ? 'info' : 'error',
'[CLAIM_DUMP][CTRL_TRUNCATE_DONE] file_id=' . $fileId
. ' status=' . (!empty($result['status']) ? 'true' : 'false')
. ' message=' . ($result['message'] ?? '')
);
return $this->respond([
'status' => !empty($result['status']),
'code' => !empty($result['status']) ? 200 : 400,
'message' => $result['message'] ?? 'Truncate failed',
'data' => $result,
], 200);
} catch (\Throwable $th) {
$this->myLogger->logme('error', 'truncateClaimDumpFile: ' . $th->getMessage());
log_message('error', '[CLAIM_DUMP][CTRL_TRUNCATE_EXCEPTION] file_id=' . $fileId . ' error=' . $th->getMessage());
return $this->respond([
'status' => false,
'code' => 500,
'message' => 'Truncate failed: ' . $th->getMessage(),
], 200);
}
}
/**
* List dump rows for a file where ticket_id is still NULL (not moved to ticket_master).
*/
public function getClaimDumpPendingRows()
{
$fileId = (int) ($this->request->getGet('file_id') ?? $this->request->getPost('file_id') ?? 0);
if ($fileId <= 0) {
return $this->respond(['status' => false, 'code' => 400, 'message' => 'file_id is required'], 200);
}
$fileData = $this->claimDumpFileModel->where('id', $fileId)->where('is_active', 1)->first();
if (empty($fileData)) {
return $this->respond(['status' => false, 'code' => 404, 'message' => 'File not found'], 200);
}
$tpaId = (int) ($fileData['tpa_id'] ?? 0);
$tableMap = $this->getTpaDumpTableMap();
$tpaTable = $tableMap[$tpaId] ?? null;
if ($tpaTable === null) {
return $this->respond([
'status' => false,
'code' => 400,
'message' => 'Pending dump view is only supported for TPA claim dumps',
], 200);
}
$displayMap = $this->getPendingDumpDisplayColumns($tpaId);
$selectCols = array_values(array_unique(array_merge(['id'], array_keys($displayMap))));
$db = db_connect();
if (!$db->tableExists($tpaTable)) {
return $this->respond(['status' => false, 'code' => 400, 'message' => 'Dump table not found'], 200);
}
// Only select columns that exist on the table.
$existingCols = array_column($db->query('SHOW COLUMNS FROM `' . $tpaTable . '`')->getResultArray(), 'Field');
$selectCols = array_values(array_intersect($selectCols, $existingCols));
if ($selectCols === []) {
$selectCols = ['id'];
}
$rows = $db->table($tpaTable)
->select(implode(', ', $selectCols))
->where('file_id', $fileId)
->where('is_active', 1)
->where('ticket_id IS NULL', null, false)
->orderBy('id', 'ASC')
->limit(500)
->get()
->getResultArray();
$headers = [];
foreach ($selectCols as $col) {
$headers[] = [
'key' => $col,
'label' => $displayMap[$col] ?? $col,
];
}
return $this->respond([
'status' => true,
'code' => 200,
'message' => 'Pending dump rows loaded',
'data' => [
'file_id' => $fileId,
'file_name' => $fileData['file_name'] ?? '',
'tpa_id' => $tpaId,
'count' => count($rows),
'headers' => $headers,
'rows' => $rows,
],
], 200);
}
/**
* Display columns for pending dump modal (db_column => label).
*
* @return array<string, string>
*/
private function getPendingDumpDisplayColumns(int $tpaId): array
{
$byTpa = [
(int) env('ICICI_PRIMARY_KEY_CONSTANT') => [
'id' => 'Dump ID',
'employee_member_id' => 'Emp Code',
'main_member_name' => 'Employee Name',
'insured_name' => 'Insured Name',
'uhid' => 'UHID / TPA No',
'claimed_amount' => 'Claim Amount',
'doa' => 'DOA',
'updated_status' => 'Status',
'relation' => 'Relation',
'master_reject_reason' => 'Reject Reason',
],
(int) env('ABHI_PRIMARY_KEY_CONSTANT') => [
'id' => 'Dump ID',
'member_code' => 'Emp Code',
'proposer_name' => 'Employee Name',
'patient_name' => 'Insured Name',
'healthcard_id' => 'UHID / TPA No',
'claimed_amount' => 'Claim Amount',
'doa' => 'DOA',
'claim_status' => 'Status',
'relation' => 'Relation',
'master_reject_reason' => 'Reject Reason',
],
(int) env('MEDI_ASSIST_PRIMARY_KEY_CONSTANT') => [
'id' => 'Dump ID',
'pribenef_employee_code' => 'Emp Code',
'pribenef_name' => 'Employee Name',
'benef_name' => 'Insured Name',
'event_id' => 'UHID / TPA No',
'claim_amount' => 'Claim Amount',
'date_of_admission' => 'DOA',
'claim_status' => 'Status',
'benef_relation' => 'Relation',
'master_reject_reason' => 'Reject Reason',
],
(int) env('FHPL_PRIMARY_KEY_CONSTANT') => [
'id' => 'Dump ID',
'employee_id' => 'Emp Code',
'main_member_name' => 'Employee Name',
'member_name' => 'Insured Name',
'uhid_no' => 'UHID / TPA No',
'claim_amount' => 'Claim Amount',
'admission_date' => 'DOA',
'current_claim_status' => 'Status',
'relationship' => 'Relation',
'master_reject_reason' => 'Reject Reason',
],
(int) env('R_CARE_PRIMARY_KEY_CONSTANT') => [
'id' => 'Dump ID',
'employee_member_id' => 'Emp Code',
'insured_name' => 'Employee Name',
'patient_name' => 'Insured Name',
'uhid' => 'UHID / TPA No',
'claimed_amount' => 'Claim Amount',
'doa_opd_treatment_from' => 'DOA',
'final_status' => 'Status',
'relation' => 'Relation',
'master_reject_reason' => 'Reject Reason',
],
(int) env('VIDAL_PRIMARY_KEY_CONSTANT') => [
'id' => 'Dump ID',
'employee_number' => 'Emp Code',
'primary_policy_holder_name' => 'Employee Name',
'patient_name' => 'Insured Name',
'primary_policy_holder_card_id' => 'UHID / TPA No',
'claim_amount' => 'Claim Amount',
'date_of_admission' => 'DOA',
'claim_status' => 'Status',
'relation' => 'Relation',
'master_reject_reason' => 'Reject Reason',
],
];
return $byTpa[$tpaId] ?? [
'id' => 'Dump ID',
'master_reject_reason' => 'Reject Reason',
];
}
/**
* Re-run Job 2 for dump rows that never got a ticket_master link (ticket_id IS NULL).
*/
public function reprocessClaimDumpPending()
{
$fileId = (int) ($this->request->getGet('file_id') ?? $this->request->getPost('file_id') ?? 0);
log_message('error', '[CLAIM_DUMP][CTRL_REPROCESS_PENDING_START] file_id=' . $fileId);
if ($fileId <= 0) {
return $this->respond(['status' => false, 'code' => 400, 'message' => 'file_id is required'], 200);
}
$fileData = $this->claimDumpFileModel->where('id', $fileId)->where('is_active', 1)->first();
if (empty($fileData)) {
return $this->respond(['status' => false, 'code' => 404, 'message' => 'File not found'], 200);
}
if (($fileData['status'] ?? '') === 'processing') {
return $this->respond([
'status' => false,
'code' => 400,
'message' => 'Cannot reprocess while import is processing',
], 200);
}
$tpaId = (int) ($fileData['tpa_id'] ?? 0);
if ($tpaId <= 0) {
return $this->respond([
'status' => false,
'code' => 400,
'message' => 'Reprocess is only supported for TPA claim dumps',
], 200);
}
$tableMap = $this->getTpaDumpTableMap();
$tpaTable = $tableMap[$tpaId] ?? null;
if ($tpaTable === null) {
return $this->respond(['status' => false, 'code' => 400, 'message' => 'Unsupported TPA'], 200);
}
try {
$db = db_connect();
$pendingBefore = (int) $db->table($tpaTable)
->where('file_id', $fileId)
->where('is_active', 1)
->where('ticket_id IS NULL', null, false)
->countAllResults();
if ($pendingBefore <= 0) {
return $this->respond([
'status' => true,
'code' => 200,
'message' => 'No pending dump rows to process',
'data' => ['pending_before' => 0],
], 200);
}
// Allow previously rejected unlinked rows to be tried again.
$db->table($tpaTable)
->where('file_id', $fileId)
->where('is_active', 1)
->where('ticket_id IS NULL', null, false)
->where('master_reject_reason IS NOT NULL', null, false)
->set(['master_reject_reason' => null])
->update();
$handler = \App\Libraries\TpaClaimsImportFactory::make($tpaId);
$result = $handler->runTicketMasterInsert(['file_id' => $fileId]);
$pendingAfter = (int) $db->table($tpaTable)
->where('file_id', $fileId)
->where('is_active', 1)
->where('ticket_id IS NULL', null, false)
->countAllResults();
if (!empty($result['status'])) {
$this->claimDumpFileModel->update($fileId, [
'status' => 'success',
'reason' => null,
]);
}
log_message(
'error',
'[CLAIM_DUMP][CTRL_REPROCESS_PENDING_DONE] file_id=' . $fileId
. ' pending_before=' . $pendingBefore
. ' pending_after=' . $pendingAfter
. ' status=' . (!empty($result['status']) ? 'true' : 'false')
. ' message=' . ($result['message'] ?? '')
);
$moved = max(0, $pendingBefore - $pendingAfter);
$message = !empty($result['status'])
? "Processed pending dump rows. Moved {$moved} of {$pendingBefore} to ticket master."
: ($result['message'] ?? 'Reprocess failed');
if (!empty($result['status']) && $pendingAfter > 0) {
$message .= " {$pendingAfter} row(s) still pending (e.g. employee not found).";
}
return $this->respond([
'status' => !empty($result['status']),
'code' => !empty($result['status']) ? 200 : 400,
'message' => $message,
'data' => [
'pending_before' => $pendingBefore,
'pending_after' => $pendingAfter,
'moved' => $moved,
'job2' => $result,
],
], 200);
} catch (\Throwable $th) {
$this->myLogger->logme('error', 'reprocessClaimDumpPending: ' . $th->getMessage());
log_message('error', '[CLAIM_DUMP][CTRL_REPROCESS_PENDING_EXCEPTION] file_id=' . $fileId . ' error=' . $th->getMessage());
return $this->respond([
'status' => false,
'code' => 500,
'message' => 'Reprocess failed: ' . $th->getMessage(),
], 200);
}
}
/**
* @return array<int, string>
*/
private function getTpaDumpTableMap(): array
{
return [
(int) env('VIDAL_PRIMARY_KEY_CONSTANT') => 'claims_dump_vidal',
(int) env('ABHI_PRIMARY_KEY_CONSTANT') => 'claims_dump_abhi',
(int) env('MEDI_ASSIST_PRIMARY_KEY_CONSTANT') => 'claims_dump_medi_assist',
(int) env('FHPL_PRIMARY_KEY_CONSTANT') => 'claims_dump_fhpl',
(int) env('R_CARE_PRIMARY_KEY_CONSTANT') => 'claims_dump_reliance',
(int) env('ICICI_PRIMARY_KEY_CONSTANT') => 'claims_dump_icici',
];
}
/**
* Attach pending dump row counts (ticket_id IS NULL) for list UI.
*
* @param list<array<string, mixed>> $files
* @return list<array<string, mixed>>
*/
private function attachPendingDumpTicketCounts(array $files): array
{
if ($files === []) {
return $files;
}
$tableMap = $this->getTpaDumpTableMap();
$byTpa = [];
foreach ($files as $file) {
$tpaId = (int) ($file['tpa_id'] ?? 0);
$fileId = (int) ($file['file_id'] ?? 0);
if ($tpaId > 0 && $fileId > 0 && isset($tableMap[$tpaId])) {
$byTpa[$tpaId][] = $fileId;
}
}
$counts = [];
$db = db_connect();
foreach ($byTpa as $tpaId => $fileIds) {
$fileIds = array_values(array_unique($fileIds));
if ($fileIds === []) {
continue;
}
$table = $tableMap[$tpaId];
if (!$db->tableExists($table)) {
continue;
}
$rows = $db->table($table)
->select('file_id, COUNT(*) AS pending_count', false)
->where('is_active', 1)
->where('ticket_id IS NULL', null, false)
->whereIn('file_id', $fileIds)
->groupBy('file_id')
->get()
->getResultArray();
foreach ($rows as $row) {
$counts[(int) $row['file_id']] = (int) $row['pending_count'];
}
}
foreach ($files as &$file) {
$fileId = (int) ($file['file_id'] ?? 0);
$file['pending_ticket_count'] = $counts[$fileId] ?? 0;
}
unset($file);
return $files;
}
// -------- END CLAIM DUMP UPLOAD ----------------------------------------------------------------------------------------------
public function saveIRDocsJson()
{
// -----------------------------------------------------
// 1) GET INPUT
// -----------------------------------------------------
$request_data = $this->request->getPost();
$data = sanitizeInputArrayAdvanced($request_data);
$ticket_id = $data['ticket_id'] ?? '';
$required_docs = $data['required_docs'] ?? '';
// -----------------------------------------------------
// 2) BASIC VALIDATION (CI4)
// -----------------------------------------------------
$rules = [
'ticket_id' => [
'label' => 'Ticket ID',
'rules' => 'required|numeric',
'errors' => [
'required' => 'System could not identify the Number.',
'numeric' => 'Invalid format.'
]
],
'required_docs' => [
'label' => 'Required Documents',
'rules' => 'required',
'errors' => [
'required' => 'Document data is required'
]
]
];
if (!$this->validate($rules)) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Input validation failed',
'code' => 400,
'errors' => $this->validator->getErrors()
]);
}
// -----------------------------------------------------
// 3) VALIDATE JSON FORMAT
// -----------------------------------------------------
$docsArray = json_decode($required_docs, true);
if (json_last_error() !== JSON_ERROR_NONE) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Input validation failed',
'code' => 400,
'errors' => [
'required_docs' => 'Invalid JSON format'
]
]);
}
// -----------------------------------------------------
// 4) VALIDATE JSON STRUCTURE
// -----------------------------------------------------
if (!isset($docsArray['docs']) || !is_array($docsArray['docs'])) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Input validation failed',
'code' => 400,
'errors' => [
'required_docs' => 'Invalid document structure'
]
]);
}
// -----------------------------------------------------
// 5) VALIDATE EACH DOCUMENT NAME
// -----------------------------------------------------
foreach ($docsArray['docs'] as $index => $doc) {
// Check document_name exists
if (!isset($doc['document_name'])) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'code' => 400,
'message' => 'Input validation failed',
'errors' => [
'required_docs' =>
"Document name missing at row " . ($index + 1)
]
]);
}
// Same charset as claim upload `docs_name.*` / client `ticketdocname`
if (!preg_match('/^[a-zA-Z0-9_\- ]+$/', $doc['document_name'])) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'code' => 400,
'message' => 'Input validation failed',
'errors' => [
'required_docs' =>
"Document Name can only contain letters, numbers, hyphens, and underscores (row " . ($index + 1) . ")"
]
]);
}
// Check document_received exists
if (!array_key_exists('document_received', $doc)) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'code' => 400,
'message' => 'Input validation failed',
'errors' => [
'required_docs' =>
"document_received key missing at row " . ($index + 1)
]
]);
}
}
// -----------------------------------------------------
// 6) EXTRA SAFETY CHECKS
// -----------------------------------------------------
if (empty($ticket_id) || empty($required_docs)) {
return $this->respond([
'status' => false,
'code' => 404,
'message' => 'Failed to save Docs'
], 200);
}
// -----------------------------------------------------
// 7) UPDATE DATABASE
// -----------------------------------------------------
db_connect()->query(
"UPDATE ticket_master SET required_docs = ? WHERE id = ?",
[$required_docs, $ticket_id]
);
// -----------------------------------------------------
// 8) RETURN UPDATED DATA
// -----------------------------------------------------
$saved = $this->ticketMasterModel
->select('required_docs')
->where('id', $ticket_id)
->first();
$savedDocs = json_decode($saved['required_docs'] ?? '{}', true) ?? [];
return $this->respond([
'status' => true,
'code' => 200,
'message' => 'IR docs saved successfully',
'data' => $savedDocs
], 200);
}
public function saveIRDocsJson_old()
{
$request_data = $this->request->getPost();
$data = sanitizeInputArrayAdvanced($request_data);
$ticket_id = $data['ticket_id'];
$required_docs = $data['required_docs'];
$rules = [
'ticket_id' => [
'label' => 'Ticket ID',
'rules' => 'required|numeric',
'errors' => [
'required' => 'System could not identify the Number.',
'numeric' => 'Invalid format.'
]
],
'required_docs' => [
'label' => 'Required Documents',
'rules' => 'required|regex_match[/^[a-zA-Z0-9_\- ]+$/]',
'errors' => [
'required' => 'Document Name is required',
'regex_match' => 'Document Name can only contain letters, numbers, hyphens, and underscores'
]
]
];
if (!$this->validate($rules)) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Input validation failed',
'code' => 400,
'errors' => $this->validator->getErrors()
]);
}
if(empty($ticket_id)){
return $this->respond(['status' => false, 'code' => 404, 'message' => 'Failed to save Docs'], 200);
}
if(empty($required_docs)){
return $this->respond(['status' => false, 'code' => 404, 'message' => 'Failed to save Docs'], 200);
}
db_connect()->query(
"UPDATE ticket_master SET required_docs = ? WHERE id = ?",
[$required_docs, $ticket_id]
);
$required_docs = $this->ticketMasterModel->select('required_docs')->where('id', $ticket_id)->first();
$required_docs = json_decode($required_docs['required_docs'] ?? '{}', true) ?? [];
return $this->respond(['status' => true, 'code' => 200, 'message' => 'IR docs saved successfully', 'data' => $required_docs], 200);
}
// -------- CLAIM MIS UPLOAD ----------------------------------------------------------------------------------------------
public function claimMisFileList()
{
$data['tab_name'] = "Claim MIS Upload";
$data['page_name'] = "Cliam MIS Files";
$data['claim_mis_file_list'] = $this->claimmisFileModel
->select('claims_mis_files.*, user_profiles.first_name as user_name')
->join('user_profiles', 'claims_mis_files.created_by = user_profiles.id')
->where('claims_mis_files.is_active', 1)
->orderBy('claims_mis_files.id', 'desc')
->findAll();
$data['tpa_list'] = $this->TPAModel->where('is_active', 1)->findAll();
return $this->loadLayout('claim_mis_file_list', $data);
}
public function uploadClaimMisFile()
{
$filename = '';
$fileSize = '';
//validate uploaded file
$validated = $this->validate([
'file' => [
'uploaded[file]',
'mime_in[file,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.oasis.opendocument.spreadsheet]',
'max_size[file,16384]',
],
]);
if ($validated)
{
$file = $this->request->getFile('file');
if (!$file) {
$this->myLogger->logme("error", 'File not found');
return $this->respond(['status' => false, 'code' => 400, 'message' => 'File not found'], 400);
}
$filename = storage_file_Upload($file, WRITEPATH . 'uploads/claims_mis/', UPLOAD_EXT_EXCEL);
if ($filename !== '') {
$this->myLogger->logme("error", 'File move successful');
$request_data = $this->request->getPost();
$data = sanitizeInputArrayAdvanced($request_data);
if(isset($data['from_date']) && !empty($data['from_date'])){
$data['from_date'] = change_date_format($data['from_date'], 'd/m/Y', 'Y-m-d');
}
if(isset($data['to_date']) && !empty($data['to_date'])){
$data['to_date'] = change_date_format($data['to_date'], 'd/m/Y', 'Y-m-d');
}
$data['file_name'] = $filename;
$response = $this->claimmisFileModel->insert($data);
if($response){
return $this->respond(['status'=>true, 'code'=>200, 'message'=>'MIS file uploaded successfully'], 200);
}else{
return $this->respond(['status'=>true, 'code'=>500, 'message'=>'Failed to upload'], 200);
}
} 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);
}
/*** OLD CODE KEEP it Safe
$file = $this->request->getFile('file');
$data = $this->request->getPost();
if(isset($data['from_date']) && !empty($data['from_date'])){
$data['from_date'] = change_date_format($data['from_date'], 'd/m/Y', 'Y-m-d');
}
if(isset($data['to_date']) && !empty($data['to_date'])){
$data['to_date'] = change_date_format($data['to_date'], 'd/m/Y', 'Y-m-d');
}
$file_path = WRITEPATH.'uploads/claims_mis';
$file_name = file_Upload_for_lead($file, $file_path, UPLOAD_EXT_EXCEL);
if(!empty($file_name)){
$data['file_name'] = $file_name;
}
$response = $this->claimmisFileModel->insert($data);
if($response){
return $this->respond(['status'=>true, 'code'=>200, 'message'=>'MIS file uploaded successfully'], 200);
}else{
return $this->respond(['status'=>true, 'code'=>500, 'message'=>'Failed to upload'], 200);
}
****/
}
public function downloadClaimMisFile()
{
try {
$file_id = $this->request->getGet('id');
// Find record
$record = $this->claimmisFileModel->where('id', $file_id)->first();
// dd($record);
if (!$record) {
$data['message'] = 'File record not found';
return view('errors/404', $data);
}
$download = $this->downloadFileFromStorage(WRITEPATH . 'uploads/claims_mis', $record['file_name']);
if ($download === null) {
$data['message'] = 'The Physical File Not Found';
return view('errors/404', $data);
}
return $download;
} catch (\Exception $e) {
// return $this->failServerError($e->getMessage());
$this->myLogger->logme('error', 'Error occoured in downloadClaimMisFile : ' . $e->getMessage());
$data['message'] = 'File record not found';
return view('errors/404', $data);
}
}
private function resolveClaimFileDiskName(array $fileRecord): string
{
$url = (string) ($fileRecord['url'] ?? '');
if ($url !== '') {
return basename($url);
}
return basename((string) ($fileRecord['file_name'] ?? ''));
}
/**
* Download helper for phased local->S3 migration.
* Returns null when file is unavailable in both local and S3.
*/
private function downloadFileFromStorage(string $uploadPath, string $fileName)
{
$storage = \Config\Services::getFileStorageService();
$result = $storage->download($uploadPath, $fileName);
if (!($result['success'] ?? false)) {
return null;
}
if (!empty($result['path']) && is_file($result['path'])) {
return $this->response->download($result['path'], null)->setFileName($fileName);
}
if (!empty($result['content'])) {
return $this->response->download($fileName, $result['content'])->setFileName($fileName);
}
return null;
}
}