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 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 ($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 } } $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(); // $fileName = $file_data['doc_name']; $url = $file_data['url']; $parts = explode('/', $url); $fileName = end($parts); $filePath = WRITEPATH . '/uploads/claim_files/' . $fileName; try { // Check if the file exists if (file_exists($filePath)) { // Set the appropriate MIME type $mimeType = mime_content_type($filePath); // Send the file to the client for download return $this->response->download($filePath, null, $mimeType); } else { $data['message'] = 'The Physical File Not Found'; echo view('errors/404', $data); } } catch (\Exception $e) { // Handle any exceptions $errorMessage = $e->getMessage(); $this->myLogger->logme('error', $errorMessage); // You can return an error response here echo $errorMessage; } } /** * 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(); } $url = $file_record['url']; $parts = explode('/', $url); $fileName = end($parts); $filePath = WRITEPATH . '/uploads/claim_files/' . $fileName; if (! is_file($filePath)) { throw PageNotFoundException::forPageNotFound(); } $ext = strtolower(pathinfo($fileName, PATHINFO_EXTENSION) ?: ''); if (! in_array($ext, ['pdf', 'png', 'jpg', 'jpeg'], true)) { throw PageNotFoundException::forPageNotFound(); } return $this->response->download($filePath, null, true)->inline()->setFileName($fileName); } 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(); 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); } } 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 = 'Click here to download Claim Form'; } else if ($value == "claim_feedback_form" && $ticket_data['ticket_type_id'] == 1){ $replaceData = 'Click to open Claim Feedback Form'; } else if ($value == "settle_letter"){ $replaceData = ' View Settlement Letter '; }else if ($value == "approved_letter"){ $replaceData = ' View Approved Letter '; }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) => "
{$doc['document']}
", $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; } if (!empty($insurer_data['insurer_claim_form'])) { $storedFileName = basename($insurer_data['insurer_claim_form']); $downloadFileName = !empty($insurer_data['insurer_claim_form_original_name']) ? basename($insurer_data['insurer_claim_form_original_name']) : $storedFileName; $filePath = WRITEPATH . 'insurer_claim_form/' . $storedFileName; if (is_file($filePath)) { return $this->response->download($filePath, null)->setFileName($downloadFileName); } } $fileName = $insurer_data['short_name'] . '.pdf'; $filePath = ROOTPATH . 'public/claim_sample_forms/' . $fileName; try { if (file_exists($filePath)) { return $this->response->download($filePath, null); } else { $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); } $diskFileName = file_Upload_for_lead($file, $uploadPath, ['pdf']); if (empty($diskFileName)) { return ['status' => false, 'message' => 'Failed to upload ' . $documentLabel . ' file.']; } return [ 'status' => true, 'data' => [ 'file_name' => $diskFileName, '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 = 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' ]); } $updated = $this->claimFilesModel ->where('id', $id) ->set(['is_active' => 0]) ->update(); if ($updated) { return $this->response->setJSON([ 'status' => true, 'message' => 'URL successfully marked inactive.' ]); } else { 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' => 'Self', // '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' => 'Self', 'spouse' => 'Spouse', 'childrens' => 'Childrens', 'parents' => 'Parents', 'parents-in-law' => 'Parents-in-law', 'either-parents-pil' => 'Either Parents/PIL', 'elders_count' => 'Total Elders Count' ]; 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[] = "" . ucfirst($person) . " - Min : {$age['min']}, Max : {$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[] = "" . ucfirst($person) . " : " . ($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('/(?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.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(); 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); } $is_moved = $avatar->move(WRITEPATH . 'uploads/claim_dump_excel/'); if ($is_moved) { $filename = $avatar->getName(); $fileSize = $avatar->getSize(); // File size in bytes $fileSize = $fileSize / (1024 * 1024); // Convert to MB $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]); //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]]); // $response = $ticketServiceController->claimDumpExcelFileFormatValidation(["file_id" => $file_id]); }else{ $r = Jobs::addJob(['job_name' => 'claimDumpExcelFileFormatValidation', 'payload' => ['file_id' => $file_id]]); // $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(); $fileName = $file_data['file_name']; $filePath = WRITEPATH . '/uploads/claim_dump_excel/' . $fileName; try { // Check if the file exists if (file_exists($filePath)) { // Set the appropriate MIME type $mimeType = mime_content_type($filePath); // Send the file to the client for download return $this->response->download($filePath, null, $mimeType); } else { $data['message'] = 'The Physical File Not Found'; echo view('errors/404', $data); } } catch (\Exception $e) { // Handle any exceptions $errorMessage = $e->getMessage(); $this->myLogger->logme('error', $errorMessage); // You can return an error response here echo $errorMessage; } } // -------- 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); } $is_moved = $file->move(WRITEPATH . 'uploads/claims_mis/'); if ($is_moved) { $file_path = WRITEPATH.'uploads/claims_mis'; $filename = file_Upload_for_lead($file, $file_path, UPLOAD_EXT_EXCEL); $fileSize = $file->getSize(); // File size in bytes $fileSize = $fileSize / (1024 * 1024); // Convert to MB $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'); } if(!empty($file_name)){ $data['file_name'] = $file; } $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); } $uploadPath = WRITEPATH . 'uploads/claims_mis/'; $filePath = $uploadPath . $record['file_name']; // dd($filePath); if (!file_exists($filePath)) { $data['message'] = 'The Physical File Not Found'; return view('errors/404', $data); } // Force file download return $this->response->download($filePath, null)->setFileName($record['file_name']); } 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); } } }