From 4f6919980e09ef48949abc8c0645b8d91628268a Mon Sep 17 00:00:00 2001 From: "venkatesh.r" Date: Sat, 20 Dec 2025 11:03:55 +0530 Subject: [PATCH] FIX_BDS_REPORT_AND_CHANGE_STATEMENT_UPLOAD_ERROR_HANDLING --- app/Controllers/ClientController.php | 2 +- .../PolicyTransactionController.php | 183 +++++++++++------- app/Models/PolicyTransactionModel.php | 13 +- app/Views/insurer_statement_list.php | 80 +++++++- app/Views/layout/header.php | 2 +- app/Views/report_bds.php | 16 +- 6 files changed, 209 insertions(+), 87 deletions(-) diff --git a/app/Controllers/ClientController.php b/app/Controllers/ClientController.php index dea5763b..d90b46cd 100755 --- a/app/Controllers/ClientController.php +++ b/app/Controllers/ClientController.php @@ -5998,7 +5998,7 @@ class ClientController extends AdminController // ---------- POLICY TRANSACTION CONTROLLER -------------------------------------------------------------------------------- $policyTransactionController = new PolicyTransactionController(); - // $res = $policyTransactionController->validateInsurerStatement(['file_id' => '62']); + // $res = $policyTransactionController->validateInsurerStatement(['file_id' => '271']); // $res = $policyTransactionController->updateInsurerStatement(['file_id' => '62']); // dd('-----', $res); diff --git a/app/Controllers/PolicyTransactionController.php b/app/Controllers/PolicyTransactionController.php index 4f2fcb49..fdfb3d42 100644 --- a/app/Controllers/PolicyTransactionController.php +++ b/app/Controllers/PolicyTransactionController.php @@ -3628,7 +3628,7 @@ } } - public function validateInsurerStatement($params) + public function validateInsurerStatementOld($params) { helper('excel_util_helper'); //get file info @@ -3742,101 +3742,142 @@ return array('status' => $ret_status, 'error_code' => $error_data['error_code'], 'error_data' => $error_data['error_data']); } - public function validateInsurerStatementNew($params) + public function validateInsurerStatement($params) { helper('excel_util_helper'); - //get file info $file_id = $params['file_id']; - $file = $this->insurerStatements->find($file_id); - // dd($file); - $date = new \DateTime($file['month']); + try { - $month = $date->format('m'); - $year = $date->format('Y'); + //get file info + $file = $this->insurerStatements->find($file_id); + // dd($file); - $error_data = ['error_code' => '', 'error_data' => []]; - $status = 'success'; - $ret_status = true; - - $return = []; - if (!isset($file)) { - //file not found in DB - return array('status' => false, 'msg' => 'statement file not found in DB'); - } - $file_name_with_path = WRITEPATH . "/uploads/statements/" . $file['file_name']; + $date = new \DateTime($file['month']); - //check physical file - if (!file_exists($file_name_with_path)) { - //file not found update status and reason - $message = "Physcial file not found"; - // echo $message; - $this->myLogger->logme('error', ($message . ' for statement file id ' . $file_id)); - $this->insurerStatements->where('id', $file_id)->set(['file_status' => 'failed', 'reason' => json_encode(['error_code' => 0, 'error_data' => $message])])->update(); - return array('status' => false, 'error_code' => 0); //0 - Physcial file not found - } + $month = $date->format('m'); + $year = $date->format('Y'); - //get excel data to php array - $spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($file_name_with_path); - $sheet = $spreadsheet->getActiveSheet(); + $error_data = ['error_code' => '', 'error_data' => []]; + $status = 'success'; + $ret_status = true; - $highestRow = $sheet->getHighestRow(); - $highestColumn = $sheet->getHighestColumn(); + $return = []; + if (!isset($file)) { + //file not found in DB + $this->insurerStatements->where('id', $file_id)->set(['file_status' => 'failed', 'reason' => json_encode(['error_code' => 0, 'error_data' => 'statement file not found in DB'])])->update(); + return array('status' => false, 'msg' => 'statement file not found in DB'); + } + $file_name_with_path = WRITEPATH . "/uploads/statements/" . $file['file_name']; - $excel_data = $sheet->rangeToArray('A1:' . $highestColumn . $highestRow, null, true, true, true); - unset($excel_data[0]); - $excel_data = ExcelSanitizeHelper::sanitizeArrayData($excel_data); + //check physical file + if (!file_exists($file_name_with_path)) { + //file not found update status and reason + $message = "Physcial file not found"; + // echo $message; + $this->myLogger->logme('error', ($message . ' for statement file id ' . $file_id)); + $this->insurerStatements->where('id', $file_id)->set(['file_status' => 'failed', 'reason' => json_encode(['error_code' => 0, 'error_data' => $message])])->update(); + return array('status' => false, 'error_code' => 0, 'error_data' => $message); //0 - Physcial file not found + } - //get no of line items and update in DB - $line_items = 0; + //get excel data to php array + $spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($file_name_with_path); + $sheet = $spreadsheet->getActiveSheet(); - // get uploaded month transactions data - $source_data = $this->PTCOShareDetailsModel->getNonReconcileredPolicyTransactions(insurer_id: $file['insurer_id'], insurer_branch_id: $file['branch_id']); + $highestRow = $sheet->getHighestRow(); + $highestColumn = $sheet->getHighestColumn(); - // check policy no,insurer and etc in DB for this month - // if all good return true, otherwise return false with messssage - foreach ($excel_data as $excel_key => $excel_row) { + $excel_data = $sheet->rangeToArray('A1:' . $highestColumn . $highestRow); + unset($excel_data[0]); + $excel_data = ExcelSanitizeHelper::sanitizeArrayData($excel_data); + // dd($excel_data); - $is_row_empty = check_row_is_empty_or_null($excel_row); + //get no of line items and update in DB + $line_items = 0; - if (!$is_row_empty) { + // get uploaded month transactions data + $source_data = $this->PTCOShareDetailsModel->getNonReconcileredPolicyTransactions(insurer_id: $file['insurer_id'], insurer_branch_id: $file['branch_id']); - $is_source_found = 0; + // check policy no,insurer and etc in DB for this month + // if all good return true, otherwise return false with messssage + $matched_entry = []; + $error_messages = []; // row-wise error storage - $policy_no = preg_replace('/^\p{Z}+|\p{Z}+$/u', '', $excel_row[1]); //policy_number from excel - $policy_no = preg_replace( '/[\x{200B}\x{200C}\x{200D}\x{FEFF}\x{00A0}\x{200E}\x{200F}\x{202A}-\x{202E}]/u', '', $excel_row[1]); //policy_number from excel - - $endorsement_no = preg_replace('/^\p{Z}+|\p{Z}+$/u', '', $excel_row[2]??''); //endorsement number from excel - $endorsement_no = preg_replace( '/[\x{200B}\x{200C}\x{200D}\x{FEFF}\x{00A0}\x{200E}\x{200F}\x{202A}-\x{202E}]/u', '', $excel_row[2]??''); //endorsement number from excel + foreach ($excel_data as $excel_key => $excel_row) { - foreach ($source_data as $source_key => $source_row) { + $row_number = $excel_key; + $is_row_empty = check_row_is_empty_or_null($excel_row); - $source_endorsement_no = $source_row['endorsement_no'] !== null ? $source_row['endorsement_no'] : null; - - if (($policy_no == $source_row['policy_no']) && $endorsement_no == $source_endorsement_no) { - $is_source_found = 1; - $line_items = $line_items + 1; - unset($source_data[$source_key]); - continue 2; + if (!$is_row_empty) { + + $policy_no = preg_replace('/^\p{Z}+|\p{Z}+$/u', '', $excel_row[1]); //policy_number from excel + $policy_no = preg_replace('/[\x{200B}\x{200C}\x{200D}\x{FEFF}\x{00A0}\x{200E}\x{200F}\x{202A}-\x{202E}]/u', '', $excel_row[1]); //policy_number from excel + + $endorsement_no = preg_replace('/^\p{Z}+|\p{Z}+$/u', '', $excel_row[2] ?? ''); //endorsement number from excel + $endorsement_no = preg_replace('/[\x{200B}\x{200C}\x{200D}\x{FEFF}\x{00A0}\x{200E}\x{200F}\x{202A}-\x{202E}]/u', '', $excel_row[2] ?? ''); //endorsement number from excel + + foreach ($source_data as $source_key => $source_row) { + + $source_endorsement_no = $source_row['endorsement_no'] !== null ? $source_row['endorsement_no'] : null; + + + // Policy number mismatch + if ($policy_no != $source_row['policy_no']) { + $error_messages[$row_number]['policy_no_mismatch'] = + "Policy number ({$policy_no}) not in NHance."; + } + + // Endorsement number mismatch + if (!empty($endorsement_no) && $endorsement_no != $source_endorsement_no) { + $error_messages[$row_number]['endorsement_no_mismatch'] = + "Endorsement number ({$endorsement_no}) not not in NHance."; + } + + // Duplicate check + if (isset($matched_entry[$policy_no . '|' . $endorsement_no])) { + $error_messages[$row_number]['duplicate'] = + "Duplicate entry found. This policy and endorsement ({$policy_no} '|' {$endorsement_no}) combination has already been matched."; + continue 2; + } + + if (($policy_no == $source_row['policy_no']) && $endorsement_no == $source_endorsement_no) { + $line_items = $line_items + 1; + $matched_entry[] = $policy_no . '|' . $endorsement_no; + continue 2; + } } } - - if ($is_source_found == 0) { - $error_data['error_code'] = 1; //match not found - $error_data['error_data'] = array_merge($error_data['error_data'], [$excel_row[0]]); //match not found - } } - } + // print_rr($error_messages);die; - if ($error_data['error_code']) { - $status = 'failed'; - $ret_status = false; - } + if (!empty($error_messages)) { + $error_data['error_code'] = 2; + $error_data['error_data'] = $error_messages; + $status = 'failed'; + $ret_status = false; + } - //update in DB - $this->insurerStatements->where('id', $file_id)->set(['line_items' => $line_items, 'file_status' => $status, 'reason' => json_encode($error_data)])->update(); - return array('status' => $ret_status, 'error_code' => $error_data['error_code'], 'error_data' => $error_data['error_data']); + //update in DB + $this->insurerStatements->where('id', $file_id)->set(['line_items' => $line_items, 'file_status' => $status, 'reason' => json_encode($error_data)])->update(); + return array('status' => $ret_status, 'error_code' => $error_data['error_code'], 'error_data' => $error_data['error_data']); + } catch (\Throwable $th) { + + $errorData = [ + 'message' => $th->getMessage(), + 'file' => $th->getFile(), + 'line' => $th->getLine(), + 'code' => $th->getCode(), + 'trace' => $th->getTraceAsString(), + 'trace_array' => $th->getTrace(), // full array version (optional) + 'function' => $th->getTrace()[0]['function'] ?? null, + 'class' => $th->getTrace()[0]['class'] ?? null, + ]; + + $this->myLogger->logme("error", "POLICY-TRANSACTION-CONTROLLER - validateInsurerStatement: Exception: " . json_encode($errorData ?? [])); + $this->insurerStatements->where('id', $file_id)->set(['line_items' => 0, 'file_status' => 'failed', 'reason' => json_encode($errorData)])->update(); + return array('status' => false, 'error_code' => [], 'error_data' => $errorData); + } } diff --git a/app/Models/PolicyTransactionModel.php b/app/Models/PolicyTransactionModel.php index 2dc9af06..05a734c1 100644 --- a/app/Models/PolicyTransactionModel.php +++ b/app/Models/PolicyTransactionModel.php @@ -3649,8 +3649,8 @@ if ($reward > 0 && ($row['billed_amt'] ?? 0) == 0.00) { $row['total_irda_amt'] = '0.00'; - $row['billed_amt'] = - $reward; $rewardFlag = 'R'; // Reward row + $row['billed_amt'] = $reward; + $rewardFlag = 'R'; // Reward row } else { $rewardFlag = 'N'; // Normal row } @@ -3689,15 +3689,20 @@ $key = $row['pt_id'].'-'.$row['insurer_id']; // Sum billed amount - $totalBilled[$key] = ($totalBilled[$key] ?? 0) - + (float) ($row['billed_amt'] ?? 0); + $totalBilled[$key] = ($totalBilled[$key] ?? 0) + (float) ($row['billed_amt'] ?? 0); // Store total_irda_amt once if (!isset($totalIrdaMap[$key]) && ($row['total_irda_amt'] ?? 0) > 0) { $totalIrdaMap[$key] = (float) $row['total_irda_amt']; } + + if(($row['reward'] ?? 0) > 0){ + $totalIrdaMap[$key] = ($totalIrdaMap[$key] ?? 0) + (float) $row['reward']; + } } + // dd($totalIrdaMap); + $ptSeen = []; $final = []; diff --git a/app/Views/insurer_statement_list.php b/app/Views/insurer_statement_list.php index 3728bfff..4e4a9192 100644 --- a/app/Views/insurer_statement_list.php +++ b/app/Views/insurer_statement_list.php @@ -174,6 +174,20 @@ } + + + +
@@ -1325,7 +1339,7 @@ }); - function fetchFileError(file_id) { + function fetchFileErrorOld(file_id) { $('#loader').show(); var apiURL = 'getFileErr/' + file_id; // console.log('fetchFileError'); @@ -1370,6 +1384,69 @@ $('#loader').hide(); } + function fetchFileError(file_id) { + $('#loader').show(); + var apiURL = 'getFileErr/' + file_id; + // console.log('fetchFileError'); + // console.log(apiURL); + $.ajax({ + url: apiURL, + method: 'GET', + headers: { + "X-Requested-With": "XMLHttpRequest" + }, + success: function(response) { + console.log(response); + $(this).find(".modal-body").html(""); + if (response.code === 200 && response.dataStatus === true && response.data !== "") { + try { + var file_error_data = JSON.parse(response.data); + var file_error_html = ""; + + // Handle only error_code = 1 (row-wise errors) + if (file_error_data.error_code == 2) { + + Object.keys(file_error_data.error_data).forEach(function (rowNo) { + + file_error_html += ` + Row ${rowNo} :

`; + + Object.values(file_error_data.error_data[rowNo]).forEach(function (message, index) { + file_error_html += `    ${index + 1}. ${message}
`; + }); + + file_error_html += `

`; + }); + + } else if (file_error_data.error_code == 1) { + + file_error_html += 'The following row no(s) from excel are not found with policy transactions / duplicates.'; + file_error_html += ' : ' + '' + file_error_data.error_data.join(',') + ''; + } + // All other error codes → plain text message + else { + file_error_html = `${file_error_data.error_data}`; + } + + $('#file-err-modal').find(".modal-body").html(file_error_html); + return file_error_html; + + } catch (error) { + console.error('Error parsing API response data:', error); + } + } else if (response.code === 404 && response.dataStatus === false) { + console.error('no data found', response); + } else { + console.error('Something went wrong!'); + } + }, + error: function(xhr, status, error) { + console.error('Error fetching data from API:', error); + } + }); + + $('#loader').hide(); + } function checkInvAmont(event = null) { var total = 0; @@ -1404,7 +1481,6 @@ return true; } - function switchRequired(elementId, isRequired, type = 'id') { // console.log('switchRequired: ' + elementId+' - '+' - '+ type); if (type == 'id') //id attribute diff --git a/app/Views/layout/header.php b/app/Views/layout/header.php index 2ed7e44e..d4f88fbd 100755 --- a/app/Views/layout/header.php +++ b/app/Views/layout/header.php @@ -993,7 +993,7 @@ /* Common modal Title styles */ .modal .modal-title { font-weight: 500; - font-size: 27px; + font-size: 23px; line-height: 100%; letter-spacing: 0; text-align: center; diff --git a/app/Views/report_bds.php b/app/Views/report_bds.php index 15cd5a00..23636b9b 100644 --- a/app/Views/report_bds.php +++ b/app/Views/report_bds.php @@ -109,7 +109,7 @@ table.dataTable tbody td { Total Premium Agreed BP % Agreed TP % - Rewards + Rewards Agreed Amount Invoiced Amount Outstanding Amount @@ -197,7 +197,7 @@ table.dataTable tbody td { % % - + - +