nhance/app/Controllers/TicketServiceController.php
2026-07-15 15:49:13 +05:30

2310 lines
95 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

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

<?php
namespace App\Controllers;
use App\Controllers\BaseController;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\API\ResponseTrait;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use Kint\Kint;
use App\Libraries\TpaClaimsImportFactory;
use App\Libraries\TPAClaimsImportServices\FhplClaimImportService;
use App\Libraries\TPAClaimsImportServices\MediAssistClaimImportService;
use App\Libraries\TPAClaimsImportServices\AbhiClaimImportService;
use App\Libraries\TPAClaimsImportServices\RcareClaimImportService;
use App\Libraries\TPAClaimsImportServices\VidalClaimImportService;
use App\Libraries\TPAClaimsImportServices\IciciClaimImportService;
use App\Libraries\TPAClaimsImportServices\BaseTpaClaimImportService;
use App\Models\ClaimDumpFileModel;
use App\Models\EmployeeModel;
use App\Models\InsurerModel;
use App\Models\TPAModel;
use App\Models\ClientModel;
use App\Models\TicketClaimStatusModel;
use App\Models\ClientPolicyModel;
use App\Models\ClaimsDumpFhplModel;
use App\Helpers\ExcelSanitizeHelper;
use App\Models\TicketMasterModel;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Style\Fill;
class TicketServiceController extends AdminController
{
use ResponseTrait;
protected $myLogger;
protected $claim_dump_excel_columns;
protected $tableHeaders;
protected $actualHeaders;
protected $claimDumpFileModel;
protected $clientModel;
protected $insurerModel;
protected $TPAModel;
protected $ticketClaimStatusModel;
protected $clientPolicyModel;
protected $medi_assist_primary_key;
protected $vidal_primary_key;
protected $icici_primary_key;
public function __construct()
{
helper('excel_util_helper');
helper('claim_dump_helper');
$this->myLogger = \Config\Services::mylogger();
set_session_context('Ticket Service Controller');
$this->claimDumpFileModel = new ClaimDumpFileModel();
$this->clientModel = new ClientModel();
$this->insurerModel = new InsurerModel();
$this->TPAModel = new TPAModel();
$this->ticketClaimStatusModel = new TicketClaimStatusModel();
$this->clientPolicyModel = new ClientPolicyModel();
$this->medi_assist_primary_key = getenv('MEDI_ASSIST_PRIMARY_KEY_CONSTANT');
$this->vidal_primary_key = getenv('VIDAL_PRIMARY_KEY_CONSTANT');
$this->icici_primary_key = getenv('ICICI_PRIMARY_KEY_CONSTANT');
$this->claim_dump_excel_columns = [
// Mandatory Fields
'sno' => [
'col_idx' => 0,
'col_cell_name' => 'A',
'col_name' => 'S.No.',
'is_mandatory' => true,
'data_type' => 'int',
'format' => null,
'allowed_values' => null
],
'policy_type' => [
'col_idx' => 1,
'col_cell_name' => 'B',
'col_name' => 'Policy Type',
'is_mandatory' => true,
'data_type' => 'str',
'format' => null,
'allowed_values' => ['GMC', 'GPA', 'EDLI', 'GTLI']
],
'status' => [
'col_idx' => 2,
'col_cell_name' => 'C',
'col_name' => 'Status',
'is_mandatory' => true,
'data_type' => 'str',
'format' => null,
'allowed_values' => null
],
'client_short_name' => [
'col_idx' => 3,
'col_cell_name' => 'D',
'col_name' => 'Corporate Name',
'is_mandatory' => true,
'data_type' => 'str',
'format' => null,
'allowed_values' => null
],
'insurer' => [
'col_idx' => 4,
'col_cell_name' => 'E',
'col_name' => 'Insurer',
'is_mandatory' => true,
'data_type' => 'str',
'format' => null,
'allowed_values' => null
],
'tpa' => [
'col_idx' => 5,
'col_cell_name' => 'F',
'col_name' => 'TPA',
'is_mandatory' => true,
'data_type' => 'str',
'format' => null,
'allowed_values' => null
],
'policy_no' => [
'col_idx' => 6,
'col_cell_name' => 'G',
'col_name' => 'Policy No',
'is_mandatory' => true,
'data_type' => 'str',
'format' => null,
'allowed_values' => null
],
'employee_code' => [
'col_idx' => 7,
'col_cell_name' => 'H',
'col_name' => 'Employee Code',
'is_mandatory' => true,
'data_type' => 'str',
'format' => null,
'allowed_values' => null
],
'employee_name' => [
'col_idx' => 8,
'col_cell_name' => 'I',
'col_name' => 'Employee Name',
'is_mandatory' => true,
'data_type' => 'str',
'format' => null,
'allowed_values' => null
],
'insured_name' => [
'col_idx' => 9,
'col_cell_name' => 'J',
'col_name' => 'Insured Name',
'is_mandatory' => true,
'data_type' => 'str',
'format' => null,
'allowed_values' => null
],
'relationship' => [
'col_idx' => 10,
'col_cell_name' => 'K',
'col_name' => 'Relationship',
'is_mandatory' => true,
'data_type' => 'str',
'format' => null,
'allowed_values' => ['Self', 'Spouse', 'Child', 'Parent', 'Other']
],
'mode_of_intimation' => [
'col_idx' => 11,
'col_cell_name' => 'L',
'col_name' => 'Mode of Intimation',
'is_mandatory' => true,
'data_type' => 'str',
'format' => null,
'allowed_values' => ['Email', 'Phone', 'Portal', 'Physical']
],
'acm' => [
'col_idx' => 12,
'col_cell_name' => 'M',
'col_name' => 'ACM',
'is_mandatory' => false,
'data_type' => 'str',
'format' => null,
'allowed_values' => null
],
'claim_type' => [
'col_idx' => 13,
'col_cell_name' => 'N',
'col_name' => 'Claim Type',
'is_mandatory' => true,
'data_type' => 'str',
'format' => null,
'allowed_values' => null
],
'priority' => [
'col_idx' => 14,
'col_cell_name' => 'O',
'col_name' => 'Priority',
'is_mandatory' => true,
'data_type' => 'str',
'format' => null,
'allowed_values' => ['Critical', 'Emergency', 'Urgent', 'High', 'Medium', 'Low']
],
// Common Fields
'date_of_birth' => [
'col_idx' => 15,
'col_cell_name' => 'P',
'col_name' => 'Date of Birth',
'is_mandatory' => false,
'data_type' => 'date',
'format' => 'd-m-Y',
'allowed_values' => null
],
'employee_mobile' => [
'col_idx' => 16,
'col_cell_name' => 'Q',
'col_name' => 'Employee Mobile',
'is_mandatory' => false,
'data_type' => 'str',
'format' => '/^[0-9]{10}$/',
'allowed_values' => null
],
'employee_email' => [
'col_idx' => 17,
'col_cell_name' => 'R',
'col_name' => 'Employee Email',
'is_mandatory' => false,
'data_type' => 'str',
'format' => 'email',
'allowed_values' => null
],
'employee_personal_email' => [
'col_idx' => 18,
'col_cell_name' => 'S',
'col_name' => 'Employee Personal Email',
'is_mandatory' => false,
'data_type' => 'str',
'format' => 'email',
'allowed_values' => null
],
// GMC Specific Fields
'hospital_name' => [
'col_idx' => 19,
'col_cell_name' => 'T',
'col_name' => 'Hospital Name',
'is_mandatory' => false,
'data_type' => 'str',
'format' => null,
'allowed_values' => null
],
'doa' => [
'col_idx' => 20,
'col_cell_name' => 'U',
'col_name' => 'DOA (Date of Admission)',
'is_mandatory' => false,
'data_type' => 'date',
'format' => 'd-m-Y',
'allowed_values' => null
],
'dod' => [
'col_idx' => 21,
'col_cell_name' => 'V',
'col_name' => 'DOD (Date of Discharge)',
'is_mandatory' => false,
'data_type' => 'date',
'format' => 'd-m-Y',
'allowed_values' => null
],
'claim_amount' => [
'col_idx' => 22,
'col_cell_name' => 'W',
'col_name' => 'Claim Amount',
'is_mandatory' => false,
'data_type' => 'decimal',
'format' => '2',
'allowed_values' => null
],
'pod_no' => [
'col_idx' => 23,
'col_cell_name' => 'X',
'col_name' => 'POD No.',
'is_mandatory' => false,
'data_type' => 'str',
'format' => null,
'allowed_values' => null
],
'tpa_id' => [
'col_idx' => 24,
'col_cell_name' => 'Y',
'col_name' => 'TPA ID',
'is_mandatory' => false,
'data_type' => 'str',
'format' => null,
'allowed_values' => null
],
'claim_number' => [
'col_idx' => 25,
'col_cell_name' => 'Z',
'col_name' => 'Claim Number',
'is_mandatory' => false,
'data_type' => 'str',
'format' => null,
'allowed_values' => null
],
// GPA Specific Fields
'sum_insured' => [
'col_idx' => 26,
'col_cell_name' => 'AA',
'col_name' => 'Sum Insured',
'is_mandatory' => false,
'data_type' => 'decimal',
'format' => '2',
'allowed_values' => null
],
'date_of_join' => [
'col_idx' => 27,
'col_cell_name' => 'AB',
'col_name' => 'Date of Join',
'is_mandatory' => false,
'data_type' => 'date',
'format' => 'd-m-Y',
'allowed_values' => null
],
'date_of_inception' => [
'col_idx' => 28,
'col_cell_name' => 'AC',
'col_name' => 'Date of Inception',
'is_mandatory' => false,
'data_type' => 'date',
'format' => 'd-m-Y',
'allowed_values' => null
],
'date_of_accident' => [
'col_idx' => 29,
'col_cell_name' => 'AD',
'col_name' => 'Date of Accident',
'is_mandatory' => false,
'data_type' => 'date',
'format' => 'd-m-Y',
'allowed_values' => null
],
'date_of_death' => [
'col_idx' => 30,
'col_cell_name' => 'AE',
'col_name' => 'Date of Death',
'is_mandatory' => false,
'data_type' => 'date',
'format' => 'd-m-Y',
'allowed_values' => null
],
'date_of_intimate' => [
'col_idx' => 31,
'col_cell_name' => 'AF',
'col_name' => 'Date of Intimate',
'is_mandatory' => false,
'data_type' => 'date',
'format' => 'd-m-Y',
'allowed_values' => null
],
// Status Wise Column Mandatory
'raised_date' => [
'col_idx' => 32,
'col_cell_name' => 'AG',
'col_name' => 'Raised Date',
'is_mandatory' => false,
'data_type' => 'date',
'format' => 'd-m-Y',
'allowed_values' => null
],
'registration_date' => [
'col_idx' => 33,
'col_cell_name' => 'AH',
'col_name' => 'Registration Date',
'is_mandatory' => false,
'data_type' => 'date',
'format' => 'd-m-Y',
'allowed_values' => null
],
'query_received_date' => [
'col_idx' => 34,
'col_cell_name' => 'AI',
'col_name' => 'Query Received Date',
'is_mandatory' => false,
'data_type' => 'date',
'format' => 'd-m-Y',
'allowed_values' => null
],
'payment_initiate_date' => [
'col_idx' => 35,
'col_cell_name' => 'AJ',
'col_name' => 'Payment Initiate Date',
'is_mandatory' => false,
'data_type' => 'date',
'format' => 'd-m-Y',
'allowed_values' => null
],
'denial_reason' => [
'col_idx' => 36,
'col_cell_name' => 'AK',
'col_name' => 'Denial Reason',
'is_mandatory' => false,
'data_type' => 'str',
'format' => null,
'allowed_values' => null
],
'denial_date' => [
'col_idx' => 37,
'col_cell_name' => 'AL',
'col_name' => 'Denial Date',
'is_mandatory' => false,
'data_type' => 'date',
'format' => 'd-m-Y',
'allowed_values' => null
],
'approved_date' => [
'col_idx' => 38,
'col_cell_name' => 'AM',
'col_name' => 'Approved Date',
'is_mandatory' => false,
'data_type' => 'date',
'format' => 'd-m-Y',
'allowed_values' => null
],
'approved_letter' => [
'col_idx' => 39,
'col_cell_name' => 'AN',
'col_name' => 'Approved Letter',
'is_mandatory' => false,
'data_type' => 'str',
'format' => null,
'allowed_values' => null
],
'approved_amount' => [
'col_idx' => 40,
'col_cell_name' => 'AO',
'col_name' => 'Approved Amount',
'is_mandatory' => false,
'data_type' => 'decimal',
'format' => '2',
'allowed_values' => null
],
'approved_description' => [
'col_idx' => 41,
'col_cell_name' => 'AP',
'col_name' => 'Approved Description',
'is_mandatory' => false,
'data_type' => 'str',
'format' => null,
'allowed_values' => null
],
'utr_details' => [
'col_idx' => 42,
'col_cell_name' => 'AQ',
'col_name' => 'UTR Details',
'is_mandatory' => false,
'data_type' => 'str',
'format' => null,
'allowed_values' => null
],
'settle_letter' => [
'col_idx' => 43,
'col_cell_name' => 'AR',
'col_name' => 'Settle Letter',
'is_mandatory' => false,
'data_type' => 'str',
'format' => null,
'allowed_values' => null
],
'settled_date' => [
'col_idx' => 44,
'col_cell_name' => 'AS',
'col_name' => 'Settled Date',
'is_mandatory' => false,
'data_type' => 'date',
'format' => 'd-m-Y',
'allowed_values' => null
],
'return_remark' => [
'col_idx' => 45,
'col_cell_name' => 'AT',
'col_name' => 'Return Remark',
'is_mandatory' => false,
'data_type' => 'str',
'format' => null,
'allowed_values' => null
],
'cancel_remark' => [
'col_idx' => 46,
'col_cell_name' => 'AU',
'col_name' => 'Cancel Remark',
'is_mandatory' => false,
'data_type' => 'str',
'format' => null,
'allowed_values' => null
],
'awb_courier' => [
'col_idx' => 47,
'col_cell_name' => 'AV',
'col_name' => 'AWB No. and Courier Name',
'is_mandatory' => false,
'data_type' => 'str',
'format' => null,
'allowed_values' => null
],
'non_id_reason' => [
'col_idx' => 48,
'col_cell_name' => 'AW',
'col_name' => 'Non ID Reason',
'is_mandatory' => false,
'data_type' => 'str',
'format' => null,
'allowed_values' => null
]
];
$this->tableHeaders = [
"S NO",
"POLICY #",
"Status",
"Account manager",
"Insurer",
"TPA",
"Corporate",
"Emp ID",
"TPA ID",
"Claim ID",
"Employee Name",
"Insured Name",
"Relationship",
"Emp. Mobile",
"Emp mail id",
"Claim Collection",
"Source Detail",
"Claim Type",
"Hospital",
"DOA",
"DOD",
"Claim Amount",
"Date of Claim Receipt",
"Date sent to TPA",
"Date of Claim Registration",
"Date - Latest Query Raise",
"Date - Latest Query Resolution",
"Approved Amt",
"Date of Approval",
"UTR - Settlement",
"Date of Settlement",
"Reason",
"Remarks",
"Approval Letter",
"Settlement Letter",
"Denial Letter",
];
$this->actualHeaders = [
"sno" => [
'col_idx' => 0,
'col_cell_name' => 'A',
'col_name' => 'S NO',
'is_mandatory' => true,
'data_type' => 'int',
'format' => null,
'allowed_values' => null
],
"corporate" => [
'col_idx' => 6,
'col_cell_name' => 'G',
'col_name' => 'Corporate',
'is_mandatory' => true,
'data_type' => 'string',
'format' => null,
'allowed_values' => null,
'custom' => 'check_client',
'params' => ['client_excel_name']
],
"policy_no" => [
'col_idx' => 1,
'col_cell_name' => 'B',
'col_name' => 'POLICY #',
'is_mandatory' => true,
'data_type' => 'string',
'format' => null,
'allowed_values' => null,
],
"status" => [
'col_idx' => 2,
'col_cell_name' => 'C',
'col_name' => 'Status',
'is_mandatory' => true,
'data_type' => 'string',
'format' => null,
'allowed_values' => null,
'custom' => 'check_status',
'params' => ['excel_status_data']
],
"acm" => [
'col_idx' => 3,
'col_cell_name' => 'D',
'col_name' => 'Account manager',
'is_mandatory' => false,
'data_type' => 'string',
'format' => null,
'allowed_values' => null
],
"insurer" => [
'col_idx' => 4,
'col_cell_name' => 'E',
'col_name' => 'Insurer',
'is_mandatory' => true,
'data_type' => 'string',
'format' => null,
'allowed_values' => null,
'custom' => 'check_insurer',
'params' => ['insurer_excel_name']
],
"tpa" => [
'col_idx' => 5,
'col_cell_name' => 'F',
'col_name' => 'TPA',
'is_mandatory' => false,
'data_type' => 'string',
'format' => null,
'allowed_values' => null,
'custom' => 'check_tpa',
'params' => ['tpa_excel_name']
],
"emp_id" => [
'col_idx' => 7,
'col_cell_name' => 'H',
'col_name' => 'Emp ID',
'is_mandatory' => true,
'data_type' => 'string',
'format' => null,
'allowed_values' => null
],
"tpa_id" => [
'col_idx' => 8,
'col_cell_name' => 'I',
'col_name' => 'TPA ID',
'is_mandatory' => false,
'data_type' => 'string',
'format' => null,
'allowed_values' => null
],
"claim_id" => [
'col_idx' => 9,
'col_cell_name' => 'J',
'col_name' => 'Claim ID',
'is_mandatory' => false,
'data_type' => 'string',
'format' => null,
'allowed_values' => null
],
"employee_name" => [
'col_idx' => 10,
'col_cell_name' => 'K',
'col_name' => 'Employee Name',
'is_mandatory' => true,
'data_type' => 'string',
'format' => null,
'allowed_values' => null
],
"insured_name" => [
'col_idx' => 11,
'col_cell_name' => 'L',
'col_name' => 'Insured Name',
'is_mandatory' => true,
'data_type' => 'string',
'format' => null,
'allowed_values' => null
],
"relationship" => [
'col_idx' => 12,
'col_cell_name' => 'M',
'col_name' => 'Relationship',
'is_mandatory' => true,
'data_type' => 'string',
'format' => null,
'allowed_values' => ['self', 'spouse', 'son', 'daughter', 'father', 'mother', 'father-in-law', 'mother-in-law']
],
"emp_mobile" => [
'col_idx' => 13,
'col_cell_name' => 'N',
'col_name' => 'Emp. Mobile',
'is_mandatory' => false,
'data_type' => 'string',
'format' => null,
'allowed_values' => null
],
"emp_email" => [
'col_idx' => 14,
'col_cell_name' => 'O',
'col_name' => 'Emp mail id',
'is_mandatory' => true,
'data_type' => 'string',
'format' => null,
'allowed_values' => null
],
"claim_collection" => [
'col_idx' => 15,
'col_cell_name' => 'P',
'col_name' => 'Claim Collection',
'is_mandatory' => true,
'data_type' => 'string',
'format' => null,
'allowed_values' => ["In Person", "Courier", "Online Mode - Email", "Smart Service Desk", "Direct to TPA"]
],
"source_detail" => [
'col_idx' => 16,
'col_cell_name' => 'Q',
'col_name' => 'Source Detail',
'is_mandatory' => false,
'data_type' => 'string',
'format' => null,
'allowed_values' => null
],
"claim_type" => [
'col_idx' => 17,
'col_cell_name' => 'R',
'col_name' => 'Claim Type',
'is_mandatory' => true,
'data_type' => 'string',
'format' => null,
'allowed_values' => ["Claim", "Main Hospitalization", "Pre / Post", "OPD", "ReOpen", "TTD", "PTD", "PPD", "Death"]
],
"hospital" => [
'col_idx' => 18,
'col_cell_name' => 'S',
'col_name' => 'Hospital',
'is_mandatory' => false,
'data_type' => 'string',
'format' => null,
'allowed_values' => null
],
"doa" => [
'col_idx' => 19,
'col_cell_name' => 'T',
'col_name' => 'DOA',
'is_mandatory' => false,
'data_type' => 'date',
'format' => 'd/m/Y',
'allowed_values' => null
],
"dod" => [
'col_idx' => 20,
'col_cell_name' => 'U',
'col_name' => 'DOD',
'is_mandatory' => false,
'data_type' => 'date',
'format' => 'd/m/Y',
'allowed_values' => null
],
"claim_amount" => [
'col_idx' => 21,
'col_cell_name' => 'V',
'col_name' => 'Claim Amount',
'is_mandatory' => false,
'data_type' => 'str',
'format' => null,
'allowed_values' => null
],
"date_claim_receipt" => [
'col_idx' => 22,
'col_cell_name' => 'W',
'col_name' => 'Date of Claim Receipt',
'is_mandatory' => false,
'data_type' => 'date',
'format' => 'd/m/Y',
'allowed_values' => null
],
"date_claim_registration" => [
'col_idx' => 24,
'col_cell_name' => 'Y',
'col_name' => 'Date of Claim Registration',
'is_mandatory' => false,
'data_type' => 'date',
'format' => 'd/m/Y',
'allowed_values' => null
],
"date_latest_query_raise" => [
'col_idx' => 25,
'col_cell_name' => 'Z',
'col_name' => 'Date - Latest Query Raise',
'is_mandatory' => false,
'data_type' => 'date',
'format' => 'd/m/Y',
'allowed_values' => null
],
"date_latest_query_resolution" => [
'col_idx' => 26,
'col_cell_name' => 'AA',
'col_name' => 'Date - Latest Query Resolution',
'is_mandatory' => false,
'data_type' => 'date',
'format' => 'd/m/Y',
'allowed_values' => null
],
"approved_amt" => [
'col_idx' => 27,
'col_cell_name' => 'AB',
'col_name' => 'Approved Amt',
'is_mandatory' => false,
'data_type' => 'str',
'format' => null,
'allowed_values' => null
],
"date_approval" => [
'col_idx' => 28,
'col_cell_name' => 'AC',
'col_name' => 'Date of Approval',
'is_mandatory' => false,
'data_type' => 'date',
'format' => 'd/m/Y',
'allowed_values' => null
],
"utr_settlement" => [
'col_idx' => 29,
'col_cell_name' => 'AD',
'col_name' => 'UTR - Settlement',
'is_mandatory' => false,
'data_type' => 'string',
'format' => null,
'allowed_values' => null
],
"date_settlement" => [
'col_idx' => 30,
'col_cell_name' => 'AE',
'col_name' => 'Date of Settlement',
'is_mandatory' => false,
'data_type' => 'date',
'format' => 'd/m/Y',
'allowed_values' => null
],
"reason" => [
'col_idx' => 31,
'col_cell_name' => 'AF',
'col_name' => 'Reason',
'is_mandatory' => false,
'data_type' => 'text',
'format' => null,
'allowed_values' => null
],
"remarks" => [
'col_idx' => 32,
'col_cell_name' => 'AG',
'col_name' => 'Remarks',
'is_mandatory' => false,
'data_type' => 'text',
'format' => null,
'allowed_values' => null
],
"approval_letter" => [
'col_idx' => 33,
'col_cell_name' => 'AH',
'col_name' => 'Approval Letter',
'is_mandatory' => false,
'data_type' => 'string',
'format' => null,
'allowed_values' => null
],
"settlement_letter" => [
'col_idx' => 34,
'col_cell_name' => 'AI',
'col_name' => 'Settlement Letter',
'is_mandatory' => false,
'data_type' => 'string',
'format' => null,
'allowed_values' => null
],
"denial_letter" => [
'col_idx' => 35,
'col_cell_name' => 'AJ',
'col_name' => 'Denial Letter',
'is_mandatory' => false,
'data_type' => 'string',
'format' => null,
'allowed_values' => null
]
];
}
//create a sample excel for development
public function createSampleClaimDumpExcelFileWithHeaderOnly()
{
// create a sample file
$headers = [];
foreach ($this->claim_dump_excel_columns as $key => $value) {
$headers[] = $value['col_name'];
}
generateExcelWithHeader($headers, 'claim_dump_sample.xlsx');
dd($headers);
}
// ---------------------------------------------------------------------------------------------------------
public function claimDumpExcelFileFormatValidation($params)
{
$file_id = $params['file_id'];
$file = $this->claimDumpFileModel->where("id", $file_id)->first();
$this->myLogger->logme('error', "Start the claim dump file format validataion with the file id : " . $file_id);
// dd($file);
$return = [];
if (empty($file)) {
return array('status' => false, 'message' => 'File not found in Database');
}
$file_name_with_path = storage_ensure_local_file(WRITEPATH . 'uploads/claim_dump_excel', $file['file_name']);
//check physical file exist
if (!file_exists($file_name_with_path)) {
$message = "Physcial file not found";
$this->myLogger->logme('error', ($message . ' for file id : ' . $file_id));
$this->claimDumpFileModel->where('id', $file_id)->set(['status' => 'failed', 'reason' => json_encode(['error_summary' => array_count_values([5]), 'error_data' => $message])])->update();
return array('error_summary' => [5], 'error_data' => $message);
}
//Read the excel file
try {
$excel_data_and_headers = $this->extractExcelData($file['file_name']);
$excel_data = $excel_data_and_headers['excel_data'];
} catch (\Exception $e) {
$errorDetails = [
'error_message' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'stack_trace' => $e->getTraceAsString(),
];
$message = "Contact system admin";
$this->claimDumpFileModel->where('id', $file_id)->set(['status' => 'failed', 'reason' => json_encode(['error_summary' => array_count_values([5]), 'error_data' => $message])])->update();
$this->myLogger->logme("error", 'Excel data extraction failed due to : ' . json_encode($errorDetails ?? []));
return $errorDetails;
}
// dd($excel_data_and_headers);
//Claim dump excel colums
$columns_to_check = $excel_data_and_headers['claim_dump_excel_columns'];
// dd($columns_to_check);
//if upload the unwanted file upload handle
if(count($columns_to_check) == 0){
$message = "Wrong file was uploaded";
$this->claimDumpFileModel->where('id', $file_id)->set(['status' => 'failed', 'reason' => json_encode(['error_summary' => array_count_values([5]), 'error_data' => $message])])->update();
return array('error_summary' => [5], 'error_data' => $message);
}
//Store the error data by this structure
$result = ['error_type' => 1, 'error_summary' => [], 'error_data' => []];
//excel data is empty than through the error
if(count($excel_data ?? []) <= 1){
$message = "Uploaded file is empty";
$this->claimDumpFileModel->where('id', $file_id)->set(['status' => 'failed', 'reason' => json_encode(['error_summary' => array_count_values([5]), 'error_data' => $message])])->update();
return array('error_summary' => [5], 'error_data' => $message);
}
//check no of columns in excel
$excel_columns = ($excel_data[0]);
// $keys = array_keys($columns_to_check);
//check columns order in excel
$column_count_res = check_columns_name($columns_to_check, $excel_columns);
// dd($column_count_res);
if (isset($column_count_res) && count($column_count_res)) {
//columns count mismatch
$message = implode("\n", $column_count_res);
$this->myLogger->logme('error', ($message . ' for file id ' . $file_id));
$this->claimDumpFileModel->where('id', $file_id)->set(['status' => 'failed', 'reason' => json_encode(['error_summary' => array_count_values([6]), 'error_data' => $message])])->update();
return array('error_summary' => [6], 'error_data' => $message);
}
$client_data = $this->clientModel->where('is_active', 1)->where('client_type', 1)->findAll();
$insurer_data = $this->insurerModel->where('is_active', 1)->findAll();
$tpa_data = $this->TPAModel->where('is_active', 1)->findAll();
$claim_status_data = $this->ticketClaimStatusModel->select('id, claim_status')->where('is_active', 1)->orderBy('id', 'asc')->groupBy('claim_status')->findAll();
//remove header
unset($excel_data[0]);
try {
foreach ($excel_data as $row_key => $row) {
//avoid empty rows
if (check_row_is_empty_or_null($row)) {
break;
}
//iterate each row for columns validations
foreach ($row as $col_key => $col) {
if (!isset($columns_to_check[$col_key])) {
continue;
}
$is_mandatory = $columns_to_check[$col_key]['is_mandatory'];
$format = $columns_to_check[$col_key]['format'];
$allowed_values = $columns_to_check[$col_key]['allowed_values'];
$custom_function = isset($columns_to_check[$col_key]['custom']) ? $columns_to_check[$col_key]['custom'] : null;
$binding_params = isset($columns_to_check[$col_key]['params']) ? $columns_to_check[$col_key]['params'] : null;
$column_dispaly_name = $columns_to_check[$col_key]['col_name'];
$column_index = $columns_to_check[$col_key]['col_idx'];
$column_cell = $columns_to_check[$col_key]['col_cell_name'];
if ($column_dispaly_name == "Corporate") {
$client_excel_name = ["client_name" => $col, "client_data" => $client_data];
}
if ($column_dispaly_name == "Insurer") {
$insurer_excel_name = ["insurer_name" => $col, "insurer_data" => $insurer_data];
}
if ($column_dispaly_name == "TPA") {
$tpa_excel_name = ["tpa_name" => $col, "tpa_data" => $tpa_data];
}
if ($column_dispaly_name == "Status") {
$excel_status_data = ["value" => $col, "data" => $claim_status_data];
}
//mandatory check
if (is_bool($is_mandatory) && $is_mandatory === true) {
if ($col == "" || $col == NULL) {
array_push($result['error_summary'], 1); //push error code for summary
$result['error_data'][$row_key][$col_key]['col_name'] = $column_dispaly_name; //push column name
$result['error_data'][$row_key][$col_key]['col_idx'] = $column_index; //push column index
$result['error_data'][$row_key][$col_key]['error'][] = 'Value is mandatory'; //push exact error desc
}
}
//format check
if (isset($format)) {
$format_error = dynamic_check_excel_date_format($col, $format);
if (!$format_error['status']) {
array_push($result['error_summary'], 2);
$result['error_data'][$row_key][$col_key]['col_name'] = $column_dispaly_name; //push column name
$result['error_data'][$row_key][$col_key]['col_idx'] = $column_index; //push column index
$result['error_data'][$row_key][$col_key]['error'][] = $format_error['error'];
}
}
//allowed values check
if (($is_mandatory === true && isset($allowed_values) && is_array($allowed_values)) || (is_array($is_mandatory) && (isset($allowed_values) && is_array($allowed_values)))) {
if (!in_array((trim($col)), $allowed_values)) {
array_push($result['error_summary'], 3);
$result['error_data'][$row_key][$col_key]['col_name'] = $column_dispaly_name; //push column name
$result['error_data'][$row_key][$col_key]['col_idx'] = $column_index; //push column index
$result['error_data'][$row_key][$col_key]['error'][] = "Value not allowed: Expected " . implode(",", $allowed_values) . " and received $col";
}
}
//custom function check
if (isset($custom_function)) {
// convert string params into PHP variables
// Create an array of variables to pass custom helper funcitons
$param_values = [];
foreach ($binding_params as $bkey => $bparam) {
$param_values[] = ($$bparam);
}
$res = call_user_func_array($custom_function, $param_values);
if ($res['status'] === false) {
array_push($result['error_summary'], 4);
$result['error_data'][$row_key][$col_key]['col_name'] = $column_dispaly_name; //push column name
$result['error_data'][$row_key][$col_key]['col_idx'] = $column_index; //push column index
$result['error_data'][$row_key][$col_key]['error'][] = $res['error'];
}
}
}
}
} catch (\Exception $e) {
$errorDetails = [
'error_message' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'stack_trace' => $e->getTraceAsString(),
];
$message = "Contact system admin";
$this->claimDumpFileModel->where('id', $file_id)->set(['status' => 'failed', 'reason' => json_encode(['error_summary' => array_count_values([5]), 'error_data' => $message])])->update();
$this->myLogger->logme("error", 'Claim dump file format validation failed due to : ' . json_encode($errorDetails ?? []));
return $errorDetails;
}
if (isset($result['error_summary']) && count($result['error_summary'])) {
$result['error_summary'] = array_count_values($result['error_summary']);
$status = 'failed';
$failure_reason = ((json_encode($result)));
$this->claimDumpFileModel->where('id', $file_id)->set(['status' => $status, 'reason' => $failure_reason])->update();
$this->myLogger->logme("error", '{file_id} uploaded failed', ['file_id' => $file_id]);
} else { //trigger next data validation via job queue server
//proceed next data level validation in JOB queue
$r = Jobs::addJob(['job_name' => 'claimDumpExcelFileDataValidation', 'payload' => ['file_id' => $file_id]]);
// $response = $this->claimDumpExcelFileDataValidation(['file_id' => $file_id]);
}
return $result;
}
public function claimDumpExcelFileDataValidation($params)
{
//get file name
$file_id = $params['file_id'];
$file = $this->claimDumpFileModel->find((int)$file_id);
$this->myLogger->logme('error', "Start the claim dump File Data Validataion with the file id : " . $file_id);
// dd($file);
if (!isset($file)) {
return array('status' => false, 'message' => 'File not found in Database');
}
$file_name_with_path = storage_ensure_local_file(WRITEPATH . 'uploads/claim_dump_excel', $file['file_name']);
//check physical file
if (!file_exists($file_name_with_path)) {
$message = "Physical file not found";
$this->myLogger->logme('error', ($message . ' for file id ' . $file_id));
$this->claimDumpFileModel->where('id', $file_id)->set(['status' => 'failed', 'reason' => json_encode(['error_summary' => array_count_values([5]), 'error_data' => $message])])->update();
return array('error_summary' => [5], 'error_data' => $message);
}
//Read the excel file
try {
$excel_data_and_headers = $this->extractExcelData($file['file_name'], "modified_column");
$excel_data = $excel_data_and_headers['excel_data'];
} catch (\Exception $e) {
$errorDetails = [
'error_message' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'stack_trace' => $e->getTraceAsString(),
];
$message = "Contact system admin";
$this->claimDumpFileModel->where('id', $file_id)->set(['status' => 'failed', 'reason' => json_encode(['error_summary' => array_count_values([5]), 'error_data' => $message])])->update();
$this->myLogger->logme("error", 'Excel data extraction failed due to : ' . json_encode($errorDetails ?? []));
return $errorDetails;
}
// dd($excel_data_and_headers);
// print_rr($excel_data);
//Claim dump excel colums
$columns_to_check = $excel_data_and_headers['claim_dump_excel_columns'];
// dd($columns_to_check);
$result = ['error_type' => 1, 'error_summary' => [], 'error_data' => []];
//remove header
unset($excel_data[0]);
try {
foreach ($excel_data as $row_key => $row) {
//avoid empty rows
if (check_row_is_empty_or_null($row)) {
break;
}
$client_column_index = $columns_to_check['corporate']['col_idx'];
$policy_no_column_index = $columns_to_check['policy_no']['col_idx'];
$insurer_column_index = $columns_to_check['insurer']['col_idx'];
$tpa_column_index = $columns_to_check['tpa']['col_idx'];
$emp_id_column_index = $columns_to_check['emp_id']['col_idx'];
$emp_name_column_index = $columns_to_check['employee_name']['col_idx'];
$insured_name_column_index = $columns_to_check['insured_name']['col_idx'];
$claim_no_column_index = $columns_to_check['claim_id']['col_idx'];
$tpa_no_column_index = $columns_to_check['tpa_id']['col_idx'];
$relation_column_index = $columns_to_check['relationship']['col_idx'];
$acm_column_index = $columns_to_check['acm']['col_idx'];
//excel file Account Manager Details like Name and Mobile Number
$excel_acm_data = $row[$acm_column_index] ?? null;
// var_dump($excel_acm_data); die;
$acm_name = null;
$acm_mobile = null;
//seperate the Account Manager Name and Mobile No
if (!empty($excel_acm_data)) {
$excel_acm_data = str_replace(['', '—'], '-', $excel_acm_data);
$parts = array_map('trim', explode('-', $excel_acm_data, 2));
$acm_name = $parts[0] ?? null;
$acm_mobile = $parts[1] ?? null;
// ensure mobile number is digits only
if ($acm_mobile !== null) {
$acm_mobile = preg_replace('/\D/', '', $acm_mobile);
}
}
// dd($acm_name, $acm_mobile);
$params = [
'client_name' => $row[$client_column_index] ?? null,
'policy_no' => $row[$policy_no_column_index] ?? null,
'insurer_short_name' => $row[$insurer_column_index] ?? null,
'tpa_short_name' => $row[$tpa_column_index] ?? null,
'emp_code' => $row[$emp_id_column_index] ?? null,
'emp_name' => $row[$emp_name_column_index] ?? null,
'insured_name' => $row[$insured_name_column_index] ?? null,
'claim_no' => $row[$claim_no_column_index] ?? null,
'tpa_no' => $row[$tpa_no_column_index] ?? null,
'relationship' => $row[$relation_column_index] ?? null,
'acm_mobile' => $acm_mobile ?? null,
'acm_name' => $acm_name ?? null,
];
$ticketMasterModal = new TicketMasterModel();
//check the Claim
$claim_data = $ticketMasterModal->getTheClaimDetails($params);
// dd($claim_data);
if (count($claim_data) != 0) {
array_push($result['error_summary'], 7);
$result['error_data'][$row_key][$policy_no_column_index]['col_name'] = $columns_to_check['policy_no']['col_name']; //push column name
$result['error_data'][$row_key][$policy_no_column_index]['col_idx'] = $policy_no_column_index; //push column index
$result['error_data'][$row_key][$policy_no_column_index]['error'][] = "This claim already exist in the system";
} else {
//check the policy
$policy_data = $ticketMasterModal->getPolicyData($params);
// dd($policy_data);
if (count($policy_data) == 0) {
array_push($result['error_summary'], 8);
$result['error_data'][$row_key][$policy_no_column_index]['col_name'] = $columns_to_check['policy_no']['col_name']; //push column name
$result['error_data'][$row_key][$policy_no_column_index]['col_idx'] = $policy_no_column_index; //push column index
$result['error_data'][$row_key][$policy_no_column_index]['error'][] = "The combination of Client, Insurer, TPA and Policy No. does not exist in the system";
} else {
//check the employee and insured
$params['is_from'] = 'claim_dump';
$employee_data = $ticketMasterModal->getEmployeeAndEmployeePolicyDetails($params) ?? [];
// dd($employee_data);
if (count($employee_data) == 0) {
array_push($result['error_summary'], 9);
$result['error_data'][$row_key][$emp_name_column_index]['col_name'] = $columns_to_check['employee_name']['col_name']; //push column name
$result['error_data'][$row_key][$emp_name_column_index]['col_idx'] = $emp_name_column_index; //push column index
$result['error_data'][$row_key][$emp_name_column_index]['error'][] = "This employee not exist in the system";
}
}
//check the Account Manager exist
$acm_data = $ticketMasterModal->getAcmUserDetails($params) ?? [];
// dd($acm_data);
if (count($acm_data) == 0) {
array_push($result['error_summary'], 10);
$result['error_data'][$row_key][$acm_column_index]['col_name'] = $columns_to_check['acm']['col_name']; //push column name
$result['error_data'][$row_key][$acm_column_index]['col_idx'] = $acm_column_index; //push column index
$result['error_data'][$row_key][$acm_column_index]['error'][] = "This Acount Manager not exist in the system";
}
}
}
} catch (\Exception $e) {
$errorDetails = [
'error_message' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'stack_trace' => $e->getTraceAsString(),
];
$message = "Contact system admin";
$this->claimDumpFileModel->where('id', $file_id)->set(['status' => 'failed', 'reason' => json_encode(['error_summary' => array_count_values([5]), 'error_data' => $message])])->update();
$this->myLogger->logme("error", 'Claim dump file data validation failed due to : ' . json_encode($errorDetails ?? []));
return $errorDetails;
}
if (isset($result['error_summary']) && count($result['error_summary'])) {
$result['error_summary'] = array_count_values($result['error_summary']);
$status = 'failed';
$failure_reason = ((json_encode($result)));
$this->claimDumpFileModel->where('id', $file_id)->set(['status' => $status, 'reason' => $failure_reason])->update();
$this->myLogger->logme("error", '{file_id} uploaded failed', ['file_id' => $file_id]);
} else {
$r = Jobs::addJob(['job_name' => 'claimDumpOnBoardProcess', 'payload' => ['file_id' => $file_id]]);
}
return $result;
}
public function claimDumpOnBoardProcess($params)
{
//get file name
$file_id = $params['file_id'];
$file = $this->claimDumpFileModel->find((int)$file_id);
$this->myLogger->logme('error', "Start the claim dump OnBoard Process with the file id : " . $file_id);
// dd($file);
if (!isset($file)) {
return array('status' => false, 'message' => 'File not found in Database');
}
$file_name_with_path = storage_ensure_local_file(WRITEPATH . 'uploads/claim_dump_excel', $file['file_name']);
//check physical file
if (!file_exists($file_name_with_path)) {
$message = "Physical file not found";
$this->myLogger->logme('error', ($message . ' for file id ' . $file_id));
$this->claimDumpFileModel->where('id', $file_id)->set(['status' => 'failed', 'reason' => json_encode(['error_summary' => array_count_values([5]), 'error_data' => $message])])->update();
return array('error_summary' => [5], 'error_data' => $message);
}
//Read the excel file
try {
$excel_data_and_headers = $this->extractExcelData($file['file_name'], "modified_column");
$excel_data = $excel_data_and_headers['excel_data'];
unset($excel_data[0]); //remove header
} catch (\Exception $e) {
$errorDetails = [
'error_message' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'stack_trace' => $e->getTraceAsString(),
];
$message = "Contact system admin";
$this->claimDumpFileModel->where('id', $file_id)->set(['status' => 'failed', 'reason' => json_encode(['error_summary' => array_count_values([5]), 'error_data' => $message])])->update();
$this->myLogger->logme("error", 'Excel data extraction failed due to : ' . json_encode($errorDetails ?? []));
return $errorDetails;
}
// dd($excel_data_and_headers);
//Claim dump excel colums
$columns_to_check = $excel_data_and_headers['claim_dump_excel_columns'];
//create the instance of the ticket master modal
$ticketMasterModal = new TicketMasterModel();
$inserted_claim_list = [];
//loop the excel data to be insert the ticket master modal
try{
foreach ($excel_data as $row_key => $row) {
//avoid empty rows
if (check_row_is_empty_or_null($row)) {
break;
}
$client_column_index = $columns_to_check['corporate']['col_idx'];
$policy_no_column_index = $columns_to_check['policy_no']['col_idx'];
$insurer_column_index = $columns_to_check['insurer']['col_idx'];
$tpa_column_index = $columns_to_check['tpa']['col_idx'];
$emp_id_column_index = $columns_to_check['emp_id']['col_idx'];
$emp_name_column_index = $columns_to_check['employee_name']['col_idx'];
$insured_name_column_index = $columns_to_check['insured_name']['col_idx'];
$claim_no_column_index = $columns_to_check['claim_id']['col_idx'];
$tpa_no_column_index = $columns_to_check['tpa_id']['col_idx'];
$relation_column_index = $columns_to_check['relationship']['col_idx'];
$params = [
'client_name' => $row[$client_column_index] ?? null,
'policy_no' => $row[$policy_no_column_index] ?? null,
'insurer_short_name' => $row[$insurer_column_index] ?? null,
'tpa_short_name' => $row[$tpa_column_index] ?? null,
'emp_code' => $row[$emp_id_column_index] ?? null,
'emp_name' => $row[$emp_name_column_index] ?? null,
'insured_name' => $row[$insured_name_column_index] ?? null,
'claim_no' => $row[$claim_no_column_index] ?? null,
'tpa_no' => $row[$tpa_no_column_index] ?? null,
'relationship' => $row[$relation_column_index] ?? null,
];
// get the policy data
$policy_data = $ticketMasterModal->getEmployeeAndEmployeePolicyDetails($params);
// dd($policy_data);
//construct the claim data to be insert
$data = $this->constructClaimData($row, $policy_data, $columns_to_check);
// dd($data);
if(!empty($data)){
$data['file_id'] = $file_id;
$data['claim_created_by'] = "DUMP";
//insert the claim data to ticket master table
$insert = $ticketMasterModal->insert($data);
$inserted_claim_list[] = $insert;
$str = implode(', ', array_map(fn($k, $v) => "$k=$v", array_keys($params), $params)) ?? "";
$this->myLogger->logme("error",'Claim insert success --- :' . $str);
}else{
$str = implode(', ', array_map(fn($k, $v) => "$k=$v", array_keys($params), $params)) ?? "";
$this->myLogger->logme("error",'This employee claim dose not insert --- :' . $str);
}
}
}catch(\Exception $e){
$errorDetails = [
'error_message' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'stack_trace' => $e->getTraceAsString(),
];
$message = "Contact system admin";
$this->claimDumpFileModel->where('id', $file_id)->set(['status' => 'failed', 'reason' => json_encode(['error_summary' => array_count_values([5]), 'error_data' => $message])])->update();
$this->myLogger->logme("error", 'Claim dump file Onboard Process failed due to : ' . json_encode( $errorDetails ?? []));
return $errorDetails;
}
$this->claimDumpFileModel->where('id', $file_id)->set(['status' => 'success','reason' => ''])->update();
$this->myLogger->logme("error",'{file_id} claim dump uploaded success',['file_id' => $file_id]);
return $inserted_claim_list;
}
public function extractExcelData($file_name, $returnType = null)
{
// $file_name = "claims_dump_form_client.xlsx";
// Load the Excel file
$file_name_with_path = storage_ensure_local_file(WRITEPATH . 'uploads/claim_dump_excel', $file_name);
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($file_name_with_path);
$worksheet = $spreadsheet->getActiveSheet();
// Get the highest row and column numbers
$highestRow = $worksheet->getHighestDataRow();
$highestColumn = $worksheet->getHighestDataColumn();
// dd($highestRow, $highestColumn);
// Get header row (assuming headers are in row 1)
// $headerRow = $worksheet->rangeToArray('A1:' . $highestColumn . '1', null, true, false)[0];
$excel_data = $worksheet->rangeToArray('A1:' . $highestColumn . $highestRow);
// print_rr($excel_data); die;
$header_with_column_index = $this->getTheColumnIndex($excel_data[0], $this->actualHeaders, $returnType);
//Sanitize the excel data
$excel_data = ExcelSanitizeHelper::sanitizeArrayData($excel_data);
// dd($excel_data);
$data = [
'claim_dump_excel_columns' => $header_with_column_index,
'excel_data' => $excel_data,
];
// dd($data);
return $data;
}
private function getTheColumnIndex($headerRow, $definedColumns, $returnType = null)
{
$result = [];
foreach ($definedColumns as $key => $value) {
foreach ($headerRow as $col_index => $col_name) {
if($returnType == null){
if(trim($col_name) == trim($value['col_name'])){
$columnLetter = Coordinate::stringFromColumnIndex(($col_index + 1));
$result[$col_index] = $value;
$result[$col_index]["col_idx"] = $col_index;
$result[$col_index]["col_cell_name"] = $columnLetter;
}
}else{
if(trim($col_name) == trim($value['col_name'])){
$columnLetter = Coordinate::stringFromColumnIndex(($col_index + 1));
$definedColumns[$key]["col_idx"] = $col_index;
$definedColumns[$key]["col_cell_name"] = $columnLetter;
}
}
}
}
// dd($result);
if($returnType == null){
return $result;
}
return $definedColumns;
}
private function constructClaimData($excel_data, $db_data, $columns_to_check)
{
// dd($db_data);
$client_column_index = $columns_to_check['corporate']['col_idx'];
$policy_no_column_index = $columns_to_check['policy_no']['col_idx'];
$insurer_column_index = $columns_to_check['insurer']['col_idx'];
$tpa_column_index = $columns_to_check['tpa']['col_idx'];
$emp_id_column_index = $columns_to_check['emp_id']['col_idx'];
$emp_name_column_index = $columns_to_check['employee_name']['col_idx'];
$insured_name_column_index = $columns_to_check['insured_name']['col_idx'];
$claim_no_column_index = $columns_to_check['claim_id']['col_idx'];
$tpa_no_column_index = $columns_to_check['tpa_id']['col_idx'];
$relation_column_index = $columns_to_check['relationship']['col_idx'];
$status_column_index = $columns_to_check['status']['col_idx'];
$acm_column_index = $columns_to_check['acm']['col_idx'];
$tpa_id_column_index = $columns_to_check['tpa_id']['col_idx'];
$claim_id_column_index = $columns_to_check['claim_id']['col_idx'];
$emp_mobile_column_index = $columns_to_check['emp_mobile']['col_idx'];
$emp_email_column_index = $columns_to_check['emp_email']['col_idx'];
$claim_collection_column_index = $columns_to_check['claim_collection']['col_idx'];
$source_detail_column_index = $columns_to_check['source_detail']['col_idx'];
$claim_type_column_index = $columns_to_check['claim_type']['col_idx'];
$hospital_column_index = $columns_to_check['hospital']['col_idx'];
$doa_column_index = $columns_to_check['doa']['col_idx'];
$dod_column_index = $columns_to_check['dod']['col_idx'];
$claim_amount_column_index = $columns_to_check['claim_amount']['col_idx'];
$date_claim_receipt_column_index = $columns_to_check['date_claim_receipt']['col_idx'];
$date_claim_registration_column_index = $columns_to_check['date_claim_registration']['col_idx'];
$date_latest_query_raise_column_index = $columns_to_check['date_latest_query_raise']['col_idx'];
$date_latest_query_resolution_index = $columns_to_check['date_latest_query_resolution']['col_idx'];
$approved_amt_column_index = $columns_to_check['approved_amt']['col_idx'];
$date_approval_column_index = $columns_to_check['date_approval']['col_idx'];
$utr_settlement_column_index = $columns_to_check['utr_settlement']['col_idx'];
$date_settlement_column_index = $columns_to_check['date_settlement']['col_idx'];
$reason_column_index = $columns_to_check['reason']['col_idx'];
$remarks_column_index = $columns_to_check['remarks']['col_idx'];
$approval_letter_column_index = $columns_to_check['approval_letter']['col_idx'];
$settlement_letter_column_index = $columns_to_check['settlement_letter']['col_idx'];
$denial_letter_column_index = $columns_to_check['denial_letter']['col_idx'];
$excel_status_data = $excel_data[$status_column_index] ?? null;
$excel_relationship_data = $excel_data[$relation_column_index] ?? null;
$excel_acm_data = $excel_data[$acm_column_index] ?? null;
$excel_tpa_id_data = $excel_data[$tpa_id_column_index] ?? null;
$excel_claim_id_data = $excel_data[$claim_id_column_index] ?? null;
$excel_emp_mobile_data = $excel_data[$emp_mobile_column_index] ?? null;
$excel_emp_email_data = $excel_data[$emp_email_column_index] ?? null;
$excel_claim_collection_data = $excel_data[$claim_collection_column_index] ?? null;
$excel_source_detail_data = $excel_data[$source_detail_column_index] ?? null;
$excel_claim_type_data = $excel_data[$claim_type_column_index] ?? null;
$excel_hospital_data = $excel_data[$hospital_column_index] ?? null;
$excel_doa_data = $excel_data[$doa_column_index] ?? null;
$excel_dod_data = $excel_data[$dod_column_index] ?? null;
$excel_claim_amount_data = $excel_data[$claim_amount_column_index] ?? null;
$excel_date_claim_receipt_data = $excel_data[$date_claim_receipt_column_index] ?? null;
$excel_date_claim_registration_data = $excel_data[$date_claim_registration_column_index] ?? null;
$excel_date_latest_query_raise_data = $excel_data[$date_latest_query_raise_column_index] ?? null;
$excel_date_latest_query_resolution_data = $excel_data[$date_latest_query_resolution_index] ?? null;
$excel_approved_amt_data = $excel_data[$approved_amt_column_index] ?? null;
$excel_date_approval_data = $excel_data[$date_approval_column_index] ?? null;
$excel_utr_settlement_data = $excel_data[$utr_settlement_column_index] ?? null;
$excel_date_settlement_data = $excel_data[$date_settlement_column_index] ?? null;
$excel_reason_data = $excel_data[$reason_column_index] ?? null;
$excel_remarks_data = $excel_data[$remarks_column_index] ?? null;
$excel_approval_letter_data = $excel_data[$approval_letter_column_index] ?? null;
$excel_settlement_letter_data = $excel_data[$settlement_letter_column_index] ?? null;
$excel_denial_letter_data = $excel_data[$denial_letter_column_index] ?? null;
//create the instance of the ticket master modal
$ticketMasterModal = new TicketMasterModel();
//excel file Account Manager Details like Name and Mobile Number
$excel_acm_data = $excel_data[$acm_column_index] ?? null;
$acm_name = null;
$acm_mobile = null;
//seperate the Account Manager Name and Mobile No
if (!empty($excel_acm_data)) {
$parts = array_map('trim', explode('-', $excel_acm_data, 2));
$acm_name = $parts[0] ?? null;
$acm_mobile = $parts[1] ?? null;
}
$params = [
"acm_name" => $acm_name,
"acm_mobile" => $acm_mobile,
];
//get the acountmanager data
$acm_data = $ticketMasterModal->getAcmUserDetails($params) ?? [];
// dd($acm_data);
//get the claim status id from the database
$claim_status_data = $this->ticketClaimStatusModel
->select('id, claim_status, ticket_type')
->where('is_active', 1)
->where('ticket_type', $db_data['ticket_type_id'])
->where('LOWER(claim_status)', strtolower($excel_status_data))
->first();
// dd($claim_status_data);
$claim_status_id = $claim_status_data['id'] ?? null;
//initialize Ticket controller for the other data
$ticketController = new TicketController();
$mode_of_intimation = array_flip($ticketController->modeOFIntimate);
//handle the Claim Type data key
$cliam_type_id = 1;
if(isset($db_data['ticket_type_id'])){
if($db_data['ticket_type_id'] == 2){
$claim_type = array_flip($ticketController->claimType[1]);
$cliam_type_id = $claim_type[$excel_claim_type_data] ?? 1;
}else{
$claim_type = array_flip($ticketController->claimType[2]);
$cliam_type_id = $claim_type[$excel_claim_type_data] ?? 1;
}
}
$db_data['insured_name'] = $excel_data[$insured_name_column_index] ?? null;
//get Insured emp name and Insured emp id
$insured_data = $ticketMasterModal->getInsuredDetails($db_data);
// dd($insured_data);
//handle remarks based on the status
$return_remarks = null;
$cancel_remarks = null;
$denial_reason = null;
if(strtolower($excel_status_data) == strtolower('RETURNED')){
$return_remarks = $excel_remarks_data ?? null;
}else if(strtolower($excel_status_data) == strtolower('CANCELLED')){
$cancel_remarks = $excel_remarks_data ?? null;
}else if(strtolower($excel_status_data) == strtolower('REJECTED')){
$denial_reason = $excel_reason_data ?? null;
}
$ticketMaster = [
'ticket_type_id' => $db_data['ticket_type_id'] ?? null,
'claim_status_id' => $claim_status_id ?? null,
'acm_id' => $acm_data['id'] ?? null,
'insurer_id' => $db_data['insurer_id'] ?? null,
'tpa_id' => $db_data['tpa_id'] ?? null,
'client_id' => $db_data['client_id'] ?? null,
'emp_id' => $db_data['emp_id'] ?? null,
'client_policy_id' => $db_data['client_policy_id'] ?? null,
'policy_no' => $db_data['policy_no'] ?? null,
'emp_code' => $db_data['emp_code'] ?? null,
'tpa_no' => $excel_tpa_id_data ?? $db_data['tpa_no'] ?? null,
'emp_name' => $db_data['emp_name'] ?? null,
'relationship' => strtolower($excel_relationship_data) ?? null,
'emp_mobile' => $excel_emp_mobile_data ?? $db_data['emp_mobile'] ?? null,
'emp_mail' => $excel_emp_email_data ?? $db_data['emp_mail'] ?? null,
'mode_of_intimation' => $mode_of_intimation[$excel_claim_collection_data] ?? null,
'claim_type' => $cliam_type_id ?? null,
'insured_emp_id' => $insured_data['emp_id'] ?? null,
'insured_name' => $insured_data['name'] ?? $excel_data[$insured_name_column_index] ?? null,
'hospital_name' => $excel_hospital_data ?? null,
'claim_amount' => $excel_claim_amount_data ?? null,
'claim_number' => $excel_claim_id_data ?? null,
'approved_letter' => $excel_approval_letter_data ?? null,
'approved_amount' => $excel_approved_amt_data ?? null,
'utr_details' => $excel_utr_settlement_data ?? null,
'settle_letter' => $excel_settlement_letter_data ?? null,
'return_remark' => $return_remarks,
'cancel_remark' => $cancel_remarks,
'denial_reason' => $denial_reason ?? null,
'doa' => normalizeDate($excel_doa_data),
'dod' => normalizeDate($excel_dod_data),
'raised_date' => normalizeDate($excel_date_latest_query_raise_data),
'registration_date' => normalizeDate($excel_date_claim_registration_data),
'query_received_date' => normalizeDate($excel_date_latest_query_resolution_data),
'approved_date' => normalizeDate($excel_date_approval_data),
'settled_date' => normalizeDate($excel_date_settlement_data),
'priority' => null,
'emp_personal_mail' => null,
'pod_no' => null,
'dob' => null,
'date_of_join' => null,
'date_of_incep' => null,
'date_of_accident' => null,
'date_of_death' => null,
'date_of_intimat' => null,
'si_amt' => null,
'denial_date' => null,
'awb_no_courier_name' => null,
'non_id_reason' => null,
'pay_initiate_date' => null,
'approved_description' => null
];
// dd($ticketMaster);
return $ticketMaster;
}
public function getClaimExcelErrorData($file_id)
{
try {
$file = $this->claimDumpFileModel->where('id', $file_id)->first();
$error_data = json_decode($file['reason']);
// dd($error_data);
$file_name_with_path = storage_ensure_local_file(WRITEPATH . 'uploads/claim_dump_excel', $file['file_name']);
//check the file exist or not
if (!file_exists($file_name_with_path)) {
$error_message = "File not found";
$this->myLogger->logme('error', ($error_message . ' for file id ' . $file_id));
return 0;
}
$excel_data_and_headers = $this->extractExcelData($file['file_name']);
$excel_data = $excel_data_and_headers['excel_data'];
$excelErrorData['excel_header'] = $excel_data[0];
unset($excel_data[0]);
// Kint::dump($excel_data);
if ($error_data->error_type == 1) {
$finalArray = [];
foreach ($error_data->error_data as $key => $value) {
foreach ($value as $key2 => $value2) {
$error_data = $value2->error;
$data = ['value' => $excel_data[$key][$value2->col_idx], 'error' => $error_data,];
$excel_data[$key][$value2->col_idx] = $data;
}
array_push($finalArray, $excel_data[$key]);
}
foreach ($finalArray as $fkey => $value) {
foreach ($value as $vkey => $arrayData) {
if (!is_array($arrayData)) {
$data = ['value' => $arrayData];
$finalArray[$fkey][$vkey] = $data;
}
}
}
$excelErrorData['excel_data'] = $finalArray;
return $excelErrorData;
} else if ($error_data->error_type == 2) {
$allErrors = [];
$typeTowArray = [];
foreach ($error_data->error_data as $index => $item) {
foreach ($item as $field) {
if (!isset($allErrors[$index])) {
$allErrors[$index] = [];
}
$allErrors[$index] = array_merge($allErrors[$index], $field->error);
}
}
// dd(array_keys($allErrors));
foreach ($allErrors as $key => $value) {
// echo $key;
// print_r($value);
foreach ($excel_data as $excel_data_index => $excel_data_value) {
if ($excel_data_value[0] == $key) {
$data = ['value' => $excel_data[$excel_data_index][1], 'error' => $value,];
$excel_data[$excel_data_index][1] = $data;
array_push($typeTowArray, $excel_data[$excel_data_index]);
break;
}
}
}
// dd($data);
foreach ($typeTowArray as $fkey => $value) {
foreach ($value as $vkey => $arrayData) {
if (!is_array($arrayData)) {
$data = ['value' => $arrayData];
$typeTowArray[$fkey][$vkey] = $data;
}
}
}
$excelErrorData['excel_data'] = $typeTowArray;
return $excelErrorData;
}
} catch (\Exception $e) {
// Handle any exceptions
$errorMessage = $e->getMessage(); //die();
$this->myLogger->logme('error', $errorMessage);
return false; // You can return an error response here
}
}
public function truncateClaimDumpFile($file_id)
{
}
// --------------------------------------------------------------------------------------------------------------------------------
/**
* Resolve Claim Dump file metadata (and optionally the physical Excel) for TPA imports.
*
* @param int|null $fileId
* @param bool $requirePhysicalFile Job 1 needs the Excel; Job 2 only needs DB metadata.
* @return array{status:bool,message?:string,fileData?:array,filePath?:string}
*/
private function resolveTpaClaimDumpFile(?int $fileId, bool $requirePhysicalFile = true): array
{
if (empty($fileId)) {
return [
'status' => false,
'message' => 'File ID is missing',
];
}
$fileData = $this->claimDumpFileModel->find((int) $fileId);
if (!$fileData) {
return [
'status' => false,
'message' => 'Invalid file ID. No file data found',
];
}
$filePath = storage_ensure_local_file(WRITEPATH . 'uploads/claim_dump_excel', $fileData['file_name']);
if ($requirePhysicalFile && !is_file($filePath)) {
return [
'status' => false,
'message' => 'Claim dump file not found',
];
}
return [
'status' => true,
'fileData' => $fileData,
'filePath' => is_file($filePath) ? $filePath : null,
];
}
/**
* First TPA-wise job parse Excel and push data into TPA staging table.
*
* @param array $params
* @return array
*/
public function tpaClaimDumpImporter(array $params)
{
$file_id = isset($params['file_id']) ? (int) $params['file_id'] : null;
log_message('error', '[CLAIM_DUMP][CTRL_JOB1_START] file_id=' . ($file_id ?? 'null'));
try {
$resolved = $this->resolveTpaClaimDumpFile($file_id);
if ($resolved['status'] === false) {
$message = $resolved['message'] ?? 'Unable to resolve claim dump file';
log_message('error', '[CLAIM_DUMP][CTRL_JOB1_RESOLVE_FAILED] file_id=' . ($file_id ?? 'null') . ' message=' . $message);
if (!empty($file_id)) {
$this->markAsFailed($file_id, $message);
}
return [
'status' => false,
'message' => $message,
];
}
$fileData = $resolved['fileData'];
$filePath = $resolved['filePath'];
log_message('error', '[CLAIM_DUMP][CTRL_JOB1_RESOLVED] file_id=' . $file_id . ' tpa_id=' . ($fileData['tpa_id'] ?? 'null') . ' file=' . ($fileData['file_name'] ?? ''));
// Prevent concurrent Job 1 runs for the same file.
$db = \Config\Database::connect();
$db->table('claim_dump_files')
->where('id', $file_id)
->where('status', 'inprogress')
->update([
'status' => 'processing',
'updated_at' => date('Y-m-d H:i:s'),
]);
if ($db->affectedRows() === 0) {
log_message('error', '[CLAIM_DUMP][CTRL_JOB1_LOCK_SKIP] file_id=' . $file_id);
return [
'status' => true,
'message' => 'Claim dump import already in progress or completed for this file.',
];
}
log_message('error', '[CLAIM_DUMP][CTRL_JOB1_LOCK_ACQUIRED] file_id=' . $file_id);
$handler = TpaClaimsImportFactory::make($fileData['tpa_id'] ?? 0);
$result = $handler->runTpaClaimDumpInsert($filePath, $file_id);
if (!empty($result['status']) && $result['status'] === true) {
// Ready for Job 2 (release Job 1 lock back to inprogress).
$this->claimDumpFileModel->update($file_id, [
'status' => 'inprogress',
]);
Jobs::addJob([
'job_name' => 'tpaClaimDumpToTicketMasterImporters',
'payload' => ['file_id' => $file_id],
]);
log_message('error', '[CLAIM_DUMP][CTRL_JOB1_SUCCESS_QUEUED_JOB2] file_id=' . $file_id . ' message=' . ($result['message'] ?? '') . ' record_count=' . ($result['record_count'] ?? 0));
} else {
// FORCE FAIL LOGIC
log_message('error', '[CLAIM_DUMP][CTRL_JOB1_FAILED] file_id=' . $file_id . ' message=' . ($result['message'] ?? 'unknown'));
$this->markAsFailed(
$file_id,
$result['message'] ?? 'System error contact admin',
$fileData['created_by'] ?? null
);
}
return $result;
} catch (\Throwable $th) {
$this->myLogger->logme("error", 'TPA_CLAIM_IMPORTER_JOB : ' . $th->getMessage());
log_message('error', '[CLAIM_DUMP][CTRL_JOB1_EXCEPTION] file_id=' . ($file_id ?? 'null') . ' error=' . $th->getMessage());
if (!empty($file_id)) {
$this->markAsFailed($file_id, 'System error contact admin');
}
return [
'status' => false,
'message' => 'TPA Claim dump import failed',
'error_data' => $th->getMessage(),
];
}
}
private function markAsFailed($file_id, $message, $user_id = null)
{
$reason = json_encode([
'error_summary' => [5 => 1],
'error_data' => $message
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
$data = [
'status' => 'failed',
'reason' => $reason,
'updated_by' => $user_id
];
// Using the direct update(id, data) method is often more reliable inside try/catch
return $this->claimDumpFileModel->update($file_id, $data);
}
/**
* Second TPA-wise job move data from TPA staging into ticket_master.
*
* @param array $params
* @return array
*/
public function tpaClaimDumpToTicketMasterImporters(array $params)
{
$file_id = isset($params['file_id']) ? (int) $params['file_id'] : null;
$fileData = null;
log_message('error', '[CLAIM_DUMP][CTRL_JOB2_START] file_id=' . ($file_id ?? 'null'));
try {
// Job 2 reads staging tables only — physical Excel is not required.
$resolved = $this->resolveTpaClaimDumpFile($file_id, false);
if ($resolved['status'] === false) {
$message = $resolved['message'] ?? 'Unable to resolve claim dump file';
log_message('error', '[CLAIM_DUMP][CTRL_JOB2_RESOLVE_FAILED] file_id=' . ($file_id ?? 'null') . ' message=' . $message);
if (!empty($file_id)) {
$this->markAsFailed($file_id, $message);
}
return [
'status' => false,
'message' => $message,
];
}
$fileData = $resolved['fileData'];
log_message('error', '[CLAIM_DUMP][CTRL_JOB2_RESOLVED] file_id=' . $file_id . ' tpa_id=' . ($fileData['tpa_id'] ?? 'null'));
// Atomic lock: skip if another worker is already processing this file.
$db = \Config\Database::connect();
$db->table('claim_dump_files')
->where('id', $file_id)
->where('status !=', 'processing')
->update([
'status' => 'processing',
'updated_at' => date('Y-m-d H:i:s'),
]);
if ($db->affectedRows() === 0) {
log_message('error', '[CLAIM_DUMP][CTRL_JOB2_LOCK_SKIP] file_id=' . $file_id);
return [
'status' => true,
'message' => 'Ticket master import already in progress for this file.',
];
}
log_message('error', '[CLAIM_DUMP][CTRL_JOB2_LOCK_ACQUIRED] file_id=' . $file_id);
$handler = TpaClaimsImportFactory::make($fileData['tpa_id'] ?? 0);
$result = $handler->runTicketMasterInsert($params);
if (!empty($result['status']) && $result['status'] === true) {
// Success (including rejection-only): dump staging is kept for error export / retry.
$this->claimDumpFileModel->update($file_id, [
'status' => 'success',
'reason' => null,
]);
log_message('error', '[CLAIM_DUMP][CTRL_JOB2_SUCCESS] file_id=' . $file_id . ' message=' . ($result['message'] ?? ''));
} else {
// Job 2 failed but Job 1 dump rows are preserved for retry.
log_message('error', '[CLAIM_DUMP][CTRL_JOB2_FAILED] file_id=' . $file_id . ' message=' . ($result['message'] ?? 'unknown'));
$this->markAsFailed(
$file_id,
$result['message'] ?? 'System error contact admin',
$fileData['created_by'] ?? null
);
}
return $result;
} catch (\Throwable $th) {
// Log the full error
$this->myLogger->logme("error", 'TICKET_MASTER_CLAIM_IMPORTER_JOB :' . $th->getMessage() . ' at line ' . $th->getLine());
log_message('error', '[CLAIM_DUMP][CTRL_JOB2_EXCEPTION] file_id=' . ($file_id ?? 'null') . ' error=' . $th->getMessage() . ' line=' . $th->getLine());
// CRITICAL: Even if the code crashes, try to mark the file as failed
if ($file_id) {
$this->markAsFailed($file_id, 'Fatal Crash: ' . $th->getMessage(), $fileData['created_by'] ?? null);
}
return [
'status' => false,
'message' => $th->getMessage(),
'error_data' => [
'line' => $th->getLine(),
'file' => $th->getFile(),
],
];
}
}
public function readExcelBySheetName(string $filePath, string $sheetName): array
{
if (!file_exists($filePath)) {
return [];
}
$spreadsheet = IOFactory::load($filePath);
// Get sheet by name
$sheet = $spreadsheet->getSheetByName($sheetName);
if ($sheet === null) {
return [];
}
$rows = $sheet->toArray(null, true, true, true);
// Need at least header + one row
if (count($rows) < 2) {
return [];
}
// First row = headers
$headers = array_shift($rows);
$headers = array_map('trim', $headers);
$data = [];
foreach ($rows as $row) {
// Skip completely empty rows
if (!array_filter($row)) {
continue;
}
$item = [];
foreach ($headers as $key => $headerName) {
if ($headerName !== '') {
$item[$headerName] = $row[$key] ?? null;
}
}
$data[] = $item;
}
return $data;
}
public function getTpaClaimDumpErrorData($file_id)
{
$file_id = (int) $file_id;
// Ensure we always have a Response object, even if controller was instantiated manually
$response = $this->response ?? service('response');
if ($file_id <= 0) {
return $response
->setStatusCode(ResponseInterface::HTTP_BAD_REQUEST)
->setJSON(['status' => false, 'message' => 'Invalid file id']);
}
$fileData = $this->claimDumpFileModel->find($file_id);
if (!$fileData) {
return $response
->setStatusCode(ResponseInterface::HTTP_NOT_FOUND)
->setJSON(['status' => false, 'message' => 'File record not found']);
}
$tpaId = (int) ($fileData['tpa_id'] ?? 0);
if ($tpaId <= 0) {
return $response
->setStatusCode(ResponseInterface::HTTP_BAD_REQUEST)
->setJSON(['status' => false, 'message' => 'TPA not linked with this file']);
}
// Resolve TPA staging table based on configured TPA IDs
$tableName = match ($tpaId) {
(int) env('VIDAL_PRIMARY_KEY_CONSTANT') => 'claims_dump_vidal',
(int) env('ABHI_PRIMARY_KEY_CONSTANT') => 'claims_dump_abhi',
(int) env('MEDI_ASSIST_PRIMARY_KEY_CONSTANT') => 'claims_dump_medi_assist',
(int) env('FHPL_PRIMARY_KEY_CONSTANT') => 'claims_dump_fhpl',
(int) env('R_CARE_PRIMARY_KEY_CONSTANT') => 'claims_dump_reliance',
(int) env('ICICI_PRIMARY_KEY_CONSTANT') => 'claims_dump_icici',
default => null,
};
if ($tableName === null) {
return $response
->setStatusCode(ResponseInterface::HTTP_BAD_REQUEST)
->setJSON(['status' => false, 'message' => 'Unsupported TPA for error dump export']);
}
$db = \Config\Database::connect();
$builder = $db->table($tableName);
// Fetch only records belonging to this file and having a rejection reason
$rows = $builder
->where('file_id', $file_id)
->where('is_active', 1)
->where('master_reject_reason IS NOT NULL', null, false)
->get()
->getResultArray();
if (empty($rows)) {
// No error records return a small Excel file with just a message
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->setTitle('Errors');
$sheet->setCellValue('A1', 'Message');
$sheet->setCellValue('A2', 'No rejected records found for this file.');
$writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
ob_start();
$writer->save('php://output');
$excelOutput = ob_get_clean();
$filename = 'tpa_claim_dump_errors_' . $file_id . '.xlsx';
return $response
->setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
->setHeader('Content-Disposition', 'attachment; filename="' . $filename . '"')
->setHeader('Cache-Control', 'max-age=0')
->setBody($excelOutput);
}
// Columns that must NOT be included in the Excel export
$excludedColumns = [
'id',
'client_id',
'client_policy_id',
'ticket_id',
'file_id',
'created_at',
'updated_at',
'created_by',
'updated_by',
'is_active',
];
$firstRow = $rows[0];
// Build header mapping and track the "Rejected Reason" column index
$dbColumnOrder = [];
$displayHeaderLabels = [];
$rejectedReasonColIdx = null; // 1-based index for Excel column
foreach ($firstRow as $columnName => $_) {
if (in_array($columnName, $excludedColumns, true)) {
continue;
}
$dbColumnOrder[] = $columnName;
if ($columnName === 'master_reject_reason' || $columnName === 'master_rejection_reason_key') {
$displayHeaderLabels[] = 'Rejected Reason';
$rejectedReasonColIdx = count($displayHeaderLabels); // current column index (1-based)
} else {
$displayHeaderLabels[] = $columnName;
}
}
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->setTitle('Errors');
// Header row
$rowIndex = 1;
foreach ($displayHeaderLabels as $colIndex => $headerLabel) {
$columnLetter = Coordinate::stringFromColumnIndex($colIndex + 1);
$cellAddress = $columnLetter . $rowIndex;
$sheet->setCellValue($cellAddress, $headerLabel);
}
// Data rows
$rowIndex = 2;
foreach ($rows as $row) {
foreach ($dbColumnOrder as $i => $columnName) {
$colIndex = $i + 1;
$columnLetter = Coordinate::stringFromColumnIndex($colIndex);
$cellAddress = $columnLetter . $rowIndex;
$value = $row[$columnName] ?? null;
$sheet->setCellValue($cellAddress, $value);
// Highlight the "Rejected Reason" values
if ($rejectedReasonColIdx !== null && $colIndex === $rejectedReasonColIdx) {
$sheet->getStyle($cellAddress)
->getFill()
->setFillType(Fill::FILL_SOLID)
->getStartColor()
->setARGB('FFFFF4B2'); // light yellow
}
}
$rowIndex++;
}
// Autosize columns for better readability
$highestColumnIndex = count($displayHeaderLabels);
for ($col = 1; $col <= $highestColumnIndex; $col++) {
$columnLetter = Coordinate::stringFromColumnIndex($col);
$sheet->getColumnDimension($columnLetter)->setAutoSize(true);
}
$writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
ob_start();
$writer->save('php://output');
$excelOutput = ob_get_clean();
$filename = 'tpa_claim_dump_errors_' . $file_id . '.xlsx';
return $response
->setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
->setHeader('Content-Disposition', 'attachment; filename="' . $filename . '"')
->setHeader('Cache-Control', 'max-age=0')
->setBody($excelOutput);
}
}