FEAT_INS_STATEMENT_UPLOAD_INV_PAYMENTS

This commit is contained in:
velz 2024-09-19 09:25:22 +05:30
parent d6a7a7c485
commit 9f933095b0
10 changed files with 1264 additions and 3 deletions

View File

@ -317,6 +317,13 @@ $routes->group("policy_tranction", ["filter" => "authMVC"], function ($routes) {
$routes->get("list", "PolicyTransactionController::reportBDS");
});
$routes->group("statement", ["filter" => "authMVC"], function ($routes) {
$routes->get("list", "PolicyTransactionController::statementList");
$routes->post("upload", "PolicyTransactionController::uploadInsurerStatement");
$routes->get("getPaymentDetails/(:any)", "PolicyTransactionController::getInvoicePaymentDetails/$1");
$routes->post("saveInvoicePaymentDetails", "PolicyTransactionController::saveInvoicePaymentDetails");
});
});
$routes->cli('cli/processjob', 'JobWorker::processJob');

View File

@ -25,7 +25,9 @@ use App\Models\EmployeeModel;
use App\Models\UserTeamsModel;
use App\Models\UserModel;
use App\Models\EmployeePolicyModel;
use App\Models\InsurerStatements;
use App\Models\InvPaymentDetailsModel;
use Kint;
class PolicyTransactionController extends BaseController
{
@ -51,6 +53,9 @@ class PolicyTransactionController extends BaseController
protected $userTeamsModel;
protected $userModel;
protected $employeePolicyModel;
protected $insurerStatements;
protected $invoiceStatus;
protected $invPaymentDetailsModel;
public function __construct()
{
@ -76,6 +81,15 @@ class PolicyTransactionController extends BaseController
$this->userTeamsModel = new UserTeamsModel();
$this->userModel = new UserModel();
$this->employeePolicyModel = new EmployeePolicyModel();
$this->insurerStatements = new InsurerStatements();
$this->invPaymentDetailsModel = new InvPaymentDetailsModel();
$this->invoiceStatus = [
'pending' => 'Pending',
'generated' => 'Generated',
'sent' => 'Sent',
'payment_received' => 'Payment Received',
];
}
// Policy Transaction Inception
@ -965,6 +979,438 @@ class PolicyTransactionController extends BaseController
$this->loadLayout('report_bds_filter', $data);
}
//insurer statement list page
public function statementList()
{
// dd($this->updateInsurerStatement(['file_id' => 13]));
// $data['insurers'] = $this->insurerModel->where('is_active',1)->findAll();
$data['invoice_status_array'] = $this->invoiceStatus;
$data['insurers'] = $this->insurerBranchModel ->getInsurerBranchesWithInsurerNames();
// dd( $data['insurers']);
$data['insurer_statement_list'] = $this->insurerStatements
->select('insurer_statements.*,
insurers.name AS insurer_name,insurers.short_name,user_profiles.first_name,insurer_branch.branch_code
')
->join('insurers', 'insurer_statements.insurer_id = insurers.id')
->join('insurer_branch', 'insurer_statements.branch_id = insurer_branch.id')
->join('user_profiles', 'insurer_statements.created_by = user_profiles.id')
->orderBy('insurer_statements.id', 'desc')
->findAll();
// dd( $data['insurer_statement_list']);
$this->loadLayout('insurer_statement_list', $data);
}
public function uploadInsurerStatement()
{
//validate uploaded file
$filename = '';
$validated = $this->validate([
'statement' => [
'uploaded[statement]',
'mime_in[statement,application/vnd.ms-excel,application/vnd,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.oasis.opendocument.spreadsheet]',
'max_size[statement,16384]',
],
]);
$this->createStatementFolder();
if ($validated)
{
$avatar = $this->request->getFile('statement');
if (!$avatar) {
$this->myLogger->logme("error", 'Statement File not found');
return $this->respond(['dataStatus' => false, 'code' => 400, 'message' => 'File not found'], 400);
}
$is_moved = $avatar->move(WRITEPATH . 'uploads/statements/');
if ($is_moved) {
$filename = $avatar->getName();
// Handle successful upload, e.g., log success or further processing
$this->myLogger->logme("error", 'Statement File moved successful');
} else {
$this->myLogger->logme("error", 'Statement File move failed');
return $this->respond(['dataStatus' => false, 'code' => 500, 'message' => 'File move failed'], 500);
}
} else {
$this->myLogger->logme("error", 'Statement Upload failed Invalid file');
return $this->respond(['dataStatus' => false, 'code' => 404, 'message' => 'Invalid file'], 404);
}
//process post variable entry in file table
$loggedInUserID = get_session_userid();
// dd($loggedInUserID);
// $loggedInUserID = 8;
$insurer = $this->request->getPost('insurer');
$insurer_id = explode('-', $insurer)[0];
$branch_id = explode('-', $insurer)[1];
// print_r($insurer_id);
// print_r($branch_id);
// die();
$month = $this->request->getPost('statement_month');
$month = change_date_format($month,'Y-M-d','Y-m-d');
// print_r($month);die;
$file_id = $this->insurerStatements->insert(['insurer_id' => $insurer_id, 'branch_id' => $branch_id, 'file_name' => $filename,'month' => $month, 'created_by' => $loggedInUserID]); //here field policy_id have client_policy_id and not policy id from policy master
$this->myLogger->logme("error", '{file_id} statement uploaded success', ['file_id' => $file_id]);
//validate file
$validation_result = $this->validateInsurerStatement(['file_id' => $file_id]);
//update file content to DB
if($validation_result['status'] )
{
$this->updateInsurerStatement(['file_id' => $file_id]);
}
if (!isset($file_id) || !$validation_result['status']) {
return $this->respond(['dataStatus' => false, 'code' => 404, 'message' => 'file not uploaded', 'error_data' => $validation_result['error_data'],'error_code' => $validation_result['error_code']], 200);
}
return $this->respond(['dataStatus' => true, 'code' => 200, 'data' => 'file upload success'], 200);
}
public function createStatementFolder()
{
$folderPath = WRITEPATH . 'uploads/statements/';
// Check if the folder doesn't exist
if (!file_exists($folderPath))
{
// Create the folder
if (mkdir($folderPath, 0777, true)) {
$this->myLogger->logme('error','statement upload folder created successfully');
// Set permissions to a+rwx (read, write, execute for all)
chmod($folderPath, 0777);
$this->myLogger->logme('error','Permissions set to a+rwx.');
} else {
// echo "Failed to create folder.";
$this->myLogger->logme('error','Failed to create statement upload folder.');
}
}
else
{
$this->myLogger->logme('error','upload folder exists.');
}
}
public function validateInsurerStatement($params)
{
//get file info
$file_id = $params['file_id'];
$file = $this->insurerStatements->find($file_id);
// dd($file);
$date = new \DateTime($file['month']);
$month = $date->format('m');
$year = $date->format('Y');
$error_data = ['error_code' => '','error_data' => []];
$status = 'success';
$ret_status = true;
// dd($month.'-'.$year);
$return = [];
if(!isset($file))
{
//file not found in DB
return array('status' => false, 'msg' => 'statement file not found in DB');
}
$file_name_with_path = WRITEPATH."/uploads/statements/".$file['file_name'];
//check physical file
if(!file_exists($file_name_with_path))
{
//file not found update status and reason
$message = "Physcial file not found";
// echo $message;
$this->myLogger->logme('error',($message . ' for statement file id ' . $file_id));
$this->insurerStatements->where('id', $file_id)->set(['file_status' => 'failed','reason' => json_encode(['error_code' => 0,'error_data' => $message])])->update();
return array('status' => false, 'error_code' => 0); //0 - Physcial file not found
}
//get excel data to php array
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($file_name_with_path);
$sheet = $spreadsheet->getActiveSheet();
$highestRowAndColumn = $sheet->getHighestRowAndColumn();
// dd($highestRowAndColumn);
$excel_data = $sheet->rangeToArray('A1:' . $highestRowAndColumn['column'] . $highestRowAndColumn['row']);
unset($excel_data[0]);
// dd($excel_data);
//get no of line items and update in DB
$line_items = count($excel_data);
// get uploaded month transactions data
$source_data = $this->PTCOShareDetailsModel->getNonReconcileredPolicyTransactions(month:$month,year:$year,insurer_id:$file['insurer_id'],insurer_branch_id:$file['branch_id']);
// Kint::dump($source_data);
// Kint::dump($excel_data);
// check policy no,insurer and etc in DB for this month
// if all good return true, otherwise return false with messssage
foreach ($excel_data as $excel_key => $excel_row)
{
$is_source_found = 0;
$excel_row[4] = trim($excel_row[4]);
$excel_row[5] = trim($excel_row[5]);
// Kint::dump(change_date_format($excel_row[4],'d-m-Y','Y-m-d'));
// echo $excel_row[1].'#'.$excel_row[2] .'#'.$excel_row[3].'#'.change_date_format($excel_row[4],'d-m-Y','Y-m-d').'#'.change_date_format($excel_row[5],'d-m-Y','Y-m-d').'<br>';
foreach ($source_data as $source_key => $source_row)
{
// Kint::dump(change_date_format($excel_row[3],'d-m-Y','Y-m-d'));
if( (trim($excel_row[1]) == $source_row['policy_no']) && trim($excel_row[2]) == $source_row['endorsement_no'] && trim($excel_row[3]) == $source_row['client_name'] && change_date_format($excel_row[4],'d-m-Y','Y-m-d') == $source_row['policy_start_date'] && change_date_format($excel_row[5],'d-m-Y','Y-m-d') == $source_row['policy_end_date'])
{
$is_source_found = 1;
unset($source_data[$source_key]);
continue 2;
}
}
if($is_source_found == 0)
{
// echo $excel_key.'-'.$excel_row[1] . '- not found<br>';
$error_data['error_code'] = 1;//match not found
// $error_data['error_data'] = ($error_data['error_data'] ?? []);
$error_data['error_data'] = array_merge($error_data['error_data'],[$excel_row[0]]);//match not found
}
}
if($error_data['error_code'])
{
$status = 'failed';
$ret_status = false;
}
//update in DB
$this->insurerStatements->where('id', $file_id)->set(['line_items' => $line_items,'file_status' => $status,'reason' => json_encode($error_data)])->update();
return array('status' => $ret_status, 'error_code' => $error_data['error_code'],'error_data' => $error_data['error_data']);
}
public function updateInsurerStatement($params)
{
//get file info
$file_id = $params['file_id'];
$file = $this->insurerStatements->find($file_id);
// dd($file);
$date = new \DateTime($file['month']);
$month = $date->format('m');
$year = $date->format('Y');
$error_data = ['error_code' => '','error_data' => []];
$status = 'success';
$ret_status = true;
// dd($month.'-'.$year);
$return = [];
if(!isset($file))
{
//file not found in DB
return array('status' => false, 'msg' => 'statement file not found in DB');
}
$file_name_with_path = WRITEPATH."/uploads/statements/".$file['file_name'];
//check physical file
if(!file_exists($file_name_with_path))
{
//file not found update status and reason
$message = "Physcial file not found";
// echo $message;
$this->myLogger->logme('error',($message . ' for statement file id ' . $file_id));
$this->insurerStatements->where('id', $file_id)->set(['file_status' => 'failed','reason' => json_encode(['error_code' => 0,'error_data' => $message])])->update();
return array('status' => false, 'error_code' => 0); //0 - Physcial file not found
}
//get excel data to php array
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($file_name_with_path);
$sheet = $spreadsheet->getActiveSheet();
$highestRowAndColumn = $sheet->getHighestRowAndColumn();
// dd($highestRowAndColumn);
$excel_data = $sheet->rangeToArray('A1:' . $highestRowAndColumn['column'] . $highestRowAndColumn['row']);
unset($excel_data[0]);
// dd($excel_data);
//get no of line items and update in DB
$line_items = count($excel_data);
// get uploaded month transactions data
$source_data = $this->PTCOShareDetailsModel->getNonReconcileredPolicyTransactions(month:$month,year:$year,insurer_id:$file['insurer_id'],insurer_branch_id:$file['branch_id']);
// Kint::dump($source_data);die;
// Kint::dump($excel_data);
// check policy no,insurer and etc in DB for this month
// if all good return true, otherwise return false with messssage
$data_to_update = [];
foreach ($excel_data as $excel_key => $excel_row)
{
$is_source_found = 0;
$excel_row[4] = trim($excel_row[4]);
$excel_row[5] = trim($excel_row[5]);
foreach ($source_data as $source_key => $source_row)
{
// Kint::dump(change_date_format($excel_row[3],'d-m-Y','Y-m-d'));
if( (trim($excel_row[1]) == $source_row['policy_no']) && trim($excel_row[2]) == $source_row['endorsement_no'] && trim($excel_row[3]) == $source_row['client_name'] && change_date_format($excel_row[4],'d-m-Y','Y-m-d') == $source_row['policy_start_date'] && change_date_format($excel_row[5],'d-m-Y','Y-m-d') == $source_row['policy_end_date'])
{
$is_source_found = 1;
//calculate percentage first
$total_amt = 0;
$actual_bp_per = trim($excel_row[9]);
$actual_bp_brokerage = trim($excel_row[12]);
$actual_bp_amt = trim($excel_row[6]);
if(($actual_bp_brokerage && $actual_bp_brokerage != 0 && $actual_bp_brokerage != ""))
{
$total_amt += $actual_bp_brokerage;
//percentage reverse calculation
if($actual_bp_per == 0 || $actual_bp_per == "")
{
$actual_bp_per = round(($actual_bp_brokerage / $actual_bp_amt) * 100,2);
}
}
else
{
$actual_bp_brokerage = $actual_bp_amt * ($actual_bp_per / 100);
$total_amt += $actual_bp_brokerage;
}
$actual_tp_per = trim($excel_row[10]);
$actual_tp_brokerage = trim($excel_row[13]);
$actual_tp_amt = trim($excel_row[7]);
if($actual_tp_brokerage && $actual_tp_brokerage != 0 && $actual_tp_brokerage != "")
{
$total_amt += $actual_tp_brokerage;
//percentage reverse calculation
if($actual_tp_per == 0 || $actual_tp_per == "")
{
$actual_tp_per = ($actual_tp_brokerage / $actual_tp_amt) * 100;
}
}
else
{
$actual_tp_brokerage = $actual_tp_amt * ($actual_tp_per / 100);
$total_amt += $actual_tp_brokerage;
}
$actual_tep_per = trim($excel_row[11]);
$actual_tep_brokerage = trim($excel_row[14]);
$actual_tep_amt = trim($excel_row[8]);
if($actual_tep_brokerage && $actual_tep_brokerage != 0 && $actual_tep_brokerage != "")
{
$total_amt += $actual_tep_brokerage;
//percentage reverse calculation
if($actual_tep_per == 0 || $actual_tep_per == "")
{
$actual_tep_per = ($actual_tep_brokerage / $actual_tep_amt) * 100;
}
}
else
{
$actual_tep_brokerage = $actual_tep_amt * ($actual_tep_per / 100);
$total_amt += $actual_tep_brokerage;
}
//find variance
$variance_amt = $source_row['exp_amt'] - $total_amt;
$data_to_update[] = ['id' => $source_row['id'],'actual_bp_amt' => $actual_bp_amt,'actual_tp_amt' => $actual_tp_amt,'actual_tep_amt' => $actual_tep_amt,'actual_bp_per' => $actual_bp_per,'actual_tp_per' => $actual_tp_per,'actual_tep_per' => $actual_tep_per,'variance' => $variance_amt,'actual_tep_brokerage_amt' => $actual_tep_brokerage,'actual_tp_brokerage_amt' => $actual_tp_brokerage,'actual_bp_brokerage_amt' => $actual_bp_brokerage,'reward' => trim($excel_row[15]),'statement_id' => $file_id];
unset($source_data[$source_key]);
continue 2;
}
}
}
$this->PTCOShareDetailsModel->updateBatch($data_to_update, 'id');
// dd($data_to_update);
// if($error_data['error_code'])
// {
// $status = 'failed';
// $ret_status = false;
// }
//update in DB
//$this->insurerStatements->where('id', $file_id)->set(['file_status' => $status,'reason' => json_encode($error_data)])->update();
return array('status' => $ret_status, 'error_code' => $error_data['error_code'],'error_data' => $error_data['error_data']);
}
public function getInvoicePaymentDetails()
{
$statement_id = $this->request->getUri()->getSegment(4);
$inv_details = $this->insurerStatements->find($statement_id);
$inv_payment_details = $this->invPaymentDetailsModel
->where('statement_id',$statement_id)
->where('is_active',1)
->get()
->getResultArray();
// print_r($inv_details);
$data = [ 'invoice_status' => $inv_details['invoice_status'],
'invoice_no' => $inv_details['invoice_no'],
'invoice_date' => $inv_details['invoice_date'] ];
$data['payments'] = $inv_payment_details;
return $this->respond(['dataStatus' => true, 'code' => 200, 'data' => $data], 200);
}
public function saveInvoicePaymentDetails()
{
$jsonData = $this->request->getJSON();
$jsonData = (array)$jsonData;
// echo 'Hi';
// print_r($jsonData);die();
$invoiceStatus = $jsonData['invoice_status'];
$hiddenStatementId = $jsonData['hidden_statement_id'];
$invoiceNo = $jsonData['invoice_no'];
$invoiceDate = $jsonData['invoice_date'];
//Update statement table
$parentData = [
'invoice_status' => $invoiceStatus,
'invoice_no' => $invoiceNo,
'invoice_date' => $invoiceDate,
'updated_by' => get_session_userid()
];
// $this->insurerStatements->update($hiddenStatementId, $parentData);
// Process child data
$invoiceAmounts = $jsonData['invoice_amount'];
$utrNos = $jsonData['utr_no'];
$paymentDates = $jsonData['payment_date'];
$pks = $jsonData['pk'];
foreach ($invoiceAmounts as $index => $invoiceAmount) {
$pk = $pks[$index]; // Get the pk for the current record
$utrNo = $utrNos[$index];
$paymentDate = $paymentDates[$index];
// Prepare data for insert/update
$childData = [
'inv_amt' => $invoiceAmount,
'utr_no' => $utrNo,
'received_date' => $paymentDate,
'statement_id' => $hiddenStatementId,
'id' => is_numeric($pk) ? (int)$pk : '',
];
if($pk){ $childData['updated_by'] = get_session_userid(); }
else { $childData['created_by'] = get_session_userid(); }
// print_r($childData);
// Insert or update
$this->invPaymentDetailsModel->save($childData);
print_r($this->invPaymentDetailsModel->errors());
}
return $this->respond(['dataStatus' => true, 'code' => 200], 200);
//return $this->response->setJSON(['dataStatus' => 'true']);
}
}

View File

@ -24,6 +24,7 @@ if (!function_exists('change_date_format')) {
function change_date_format($data, $source_format, $output_format)
{
$data = trim($data);
// echo $data, $source_format, $output_format;return true;
try {
// Create DateTime object with the source format
@ -31,7 +32,8 @@ if (!function_exists('change_date_format')) {
// Check if the DateTime object is created successfully
if ($dateTime === false) {
throw new Exception('Invalid date or format');
$errors = DateTime::getLastErrors();
throw new Exception('Invalid date or format' . implode(', ', $errors['errors']));
}
// Format the DateTime object with the output format
$formattedDate = $dateTime->format($output_format);

View File

@ -0,0 +1,30 @@
<?php
namespace App\Models;
use CodeIgniter\Model;
class InsurerStatements extends Model
{
protected $table = 'insurer_statements';
protected $primaryKey = 'id';
protected $allowedFields = [
"id",
"insurer_id",
"branch_id",
"line_items",
"file_name",
"month",
"created_by",
"is_active",
"file_status",
"reason",
"invoice_status",
"invoice_no",
"invoice_date",
"updated_by"
];
}

View File

@ -0,0 +1,24 @@
<?php
namespace App\Models;
use CodeIgniter\Model;
class InvPaymentDetailsModel extends Model
{
protected $table = 'inv_payment_details';
protected $primaryKey = 'id';
// Allowed fields for insert/update
protected $allowedFields = [
'id',
'statement_id',
'inv_amt',
'utr_no',
'received_date',
'created_by',
'is_active',
'updated_by'
];
}

View File

@ -47,6 +47,10 @@ class PTCOShareDetailsModel extends Model
'actual_bp_per',
'actual_tp_per',
'actual_tep_per',
'actual_bp_brokerage_amt',
'actual_tp_brokerage_amt',
'actual_tep_brokerage_amt',
'reward',
'exp_amt',
'variance',
'remark',
@ -59,6 +63,43 @@ class PTCOShareDetailsModel extends Model
'amount',
'stamp_duty',
'cop_amt',
'statement_id'
];
public function getNonReconcileredPolicyTransactions(string $month,string $year,string $insurer_id,string $insurer_branch_id)
{
return $this->db->table('pt_co_share_details pt_co')
->select('
pt_co.id,
pt_co.pt_id,
pt_co.exp_amt,
pt.id AS policy_transaction_id,
pt.endorsement_no,
c.client_name,
pt.created_at,
pt_co.insurer_id,
pt_co.insurer_branch_id,
pt.policy_no,
pt.policy_issue_date,
pt.policy_start_date,
pt.policy_end_date,
pt.status,
pt_co.bp_amt,
pt_co.tp_amt,
pt_co.tep_amt,
pt_co.exp_amt
')
->join('policy_transaction pt', 'pt_co.pt_id = pt.id')
->join('clients c', 'pt.client_id = c.id')
->where('pt_co.is_active', 1)
->where('MONTH(pt.created_at)', $month)
->where('YEAR(pt.created_at)', $year)
->where('pt_co.insurer_id', $insurer_id)
->where('pt_co.insurer_branch_id', $insurer_branch_id)
// ->where('pt_co.exp_amt', 0.00)
// ->orWhere('pt_co.exp_amt is null')
->get()
->getResultArray();
}
}

View File

@ -0,0 +1,708 @@
<style>
.table th,
.table td {
padding: 8px;
}
table.dataTable tbody td {
padding: 4px 4px !important;
}
/* table.dataTable thead th {
padding: 4px 4px !important;
} */
.col-12 {
max-width: 98% !important;
}
.dataTables_filter {
position: absolute;
}
.highlight {
border: 2px solid red;
background-color: #ffe6e6;
}
.column-header {
margin-right: 10px; /* Adjust this value as needed */
}
.form-section {
border: 1px solid #ccc;
padding: 15px;
margin-bottom: 20px;
}
.row-box {
border: 1px solid #ccc;
padding: 10px;
margin-bottom: 10px;
}
</style>
<style>
.switch {
position: relative;
display: inline-block;
width: 54px;
height: 34px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
.slider:before {
position: absolute;
content: "";
height: 19px;
width: 19px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
input:checked + .slider {
background-color: #2196F3;
}
input:focus + .slider {
box-shadow: 0 0 1px #2196F3;
}
input:checked + .slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
/* Rounded sliders */
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
</style>
<div class="row" id="inception_list">
<div class="col-12">
<div class="card">
<div class="card-body">
<div class="row" style="margin-bottom:1rem;">
<div class="col-6" style="align-self: center;">
<h4 style="position: relative;">Insurer Statement List</h4>
</div>
<!-- <div class="col-2" id="add_div" style="text-align: right; position: relative;top: 56px; left: 314px;"> -->
<!-- <button type="button" id="change_status" class="btn btn-primary waves-effect waves-light">Invoice Status</button> -->
<!-- </div> -->
<!-- <div class="col-1" id="status_change" style="text-align: right; position: relative;top: 56px; left: 291px;"> -->
<button type="button" id="btnAdd" onclick="showFileUploadModal()" class="btn btn-primary waves-effect waves-light">Upload</button>
<!-- </div> -->
</div>
<div>
<table class="table table-striped mb-0 nowrap" cellspacing="0" id="tickets-table">
<thead class="bg-light">
<tr>
<th></th>
<th><div class="column-header">Insurer</div></th>
<th><div class="column-header">Month</div></th>
<th><div class="column-header">Statement</div></th>
<th><div class="column-header">Line Items</div></th>
<th><div class="column-header">User/Time</div></th>
<th><div class="column-header">Action</div></th>
</tr>
</thead>
<tbody>
<?php foreach($insurer_statement_list as $row){ ?>
<tr>
<td><input type="hidden" class="row-select" data-id="<?= $row['id']; ?>"></td>
<td><?php echo $row['short_name'].'-'.$row['branch_code']; ?></td>
<td><?php echo change_date_format($row['month'],'Y-m-d','M-Y'); ?></td>
<td><?php echo $row['file_name'] ?> </td>
<td><?php echo $row['line_items'] ?></td>
<td><?php echo change_date_format($row['created_at'],'Y-m-d H:i:s','d M Y h:i a').' by <br>'.$row['first_name'] ?></td>
<td>
<div class="btn-group dropdown">
<a href="javascript: void(0);" class="dropdown-toggle arrow-none btn btn-light btn-sm" data-toggle="dropdown" aria-expanded="false"><i class="mdi mdi-dots-horizontal"></i></a>
<div class="dropdown-menu dropdown-menu-right">
<a class="dropdown-item btnEdit" data-id="<?= $row['id'];?>" onclick="showInvoiceStatusModal(event)">
<i class="mdi mdi-pencil mr-2 text-muted font-18 vertical-middle"></i>Invoice status
</a>
</div>
</div>
</td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
</div>
</div>
</div><!-- end col -->
</div>
<!-- end table row -->
<!-- CD No form content modal-->
<div class="modal fade" id="cd_form_modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="title">Add CD Account Number</h4>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
</div>
<div class="modal-body p-4">
<div class="">
<form role="form" class="parsley-examples" method="post" id="CDMasterForm" enctype="multipart/form-data">
<div class="form-group">
<div class="form-row">
<div class="form-group col-md-12">
<label for="email">Opening Date<span class="text-danger">*</span></label>
<input type="text" class="form-control" name="opening_date" id="opening_date" required>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12">
<label for="mobile">CD Account Number<span class="text-danger">*</span></label>
<input type="text" class="form-control" id="cd_ac_no_data" name="cd_ac_no" required>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12">
<label for="mobile">Opening Amount<span class="text-danger">*</span></label>
<input type="text" class="form-control" id="opening_bal" name="opening_bal" onkeypress="return onlyNumbers(event)" required>
</div>
</div>
</div>
<div class="form-group text-right m-b-0">
<button type="submit" class="btn btn-primary waves-effect waves-light mr-1"
id="btnSubmit">Submit</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<div class="modal fade" id="file_upload" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="title">Upload Insurer Statement</h4>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
</div>
<div class="modal-body p-4">
<div class="">
<form role="form" class="parsley-examples" method="post" id="insurer_statement_upload_form" enctype="multipart/form-data" action="upload">
<div class="form-group">
<div class="form-group col-md-12">
<label for="insurer"> Insurer <spanclass="text-danger">*</spanclass=></label>
<select class="form-control" id="insurer" name="insurer" required>
<option value="" selected>Select Insurer</option>
<?php
if (isset($insurers) && count($insurers)) {
foreach ($insurers as $key => $value) {
echo "<option value=" . $value['insurer_id'].'-'.$value['id'] . ">" . $value['insurer_name'] .'-'. $value['branch_code'] . "</option>";
}
}
?>
</select>
</div>
<div class="form-group col-md-12">
<label for="statement_month">Statement month</label>
<input type="date" class="form-control" id="statement_month" name="statement_month" placeholder="Enter Invoice Number" required>
</div>
<div class="form-group col-md-12" >
<label for="statment">Statement </label>
<input type="file" class="form-control" name="statement" required accept=" application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel,application/vnd.oasis.opendocument.spreadsheet">
</div>
</div>
<div class="form-group text-right m-b-0">
<button type="submit" class="btn btn-primary waves-effect waves-light mr-1"
id="btnSubmit">Submit</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<!-- Invoice status content modal-->
<div class="modal fade" id="invoice_modal" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="title">Update Invoice Status</h4>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
</div>
<div class="modal-body p-4">
<div class="">
<form role="form" class="parsley-examples" method="post" id="invoiceForm" enctype="multipart/form-data" action="<?php echo base_url().'policy_tranction/statement/saveInvoicePaymentDetails'?>">
<div class="form-group">
<div class="row">
<div class="form-group col-md-6">
<label for="addon_policy">Invoice Status <span class="text-danger">*</span></label>
<select class="form-control" id="invoice_status" name="invoice_status" required>
<option value="" selected>Select Invoice Status</option>
<?php
if (isset($invoice_status_array) && count($invoice_status_array)) {
foreach ($invoice_status_array as $key => $value) {
echo "<option value='" . $key . "'>" . $value . "</option>";
}
}
?>
</select>
<input type="hidden" id="hidden_statement_id" name="hidden_statement_id">
</div>
</div>
<!-- Invoice Number and Invoice Date in same row -->
<div class="row" id="invoice_no_div_modal" style="display: none;">
<div class="form-group col-md-6">
<label for="invoice_no">Invoice Number<span id="base_danger" class="text-danger"></span></label>
<input type="text" class="form-control" id="invoice_no_modal" name="invoice_no" placeholder="Enter Invoice Number" required>
</div>
<div class="form-group col-md-6">
<label for="invoice_date">Invoice Date</label>
<input type="date" class="form-control" id="invoice_date_modal" name="invoice_date" value="<?php echo date('Y-m-d'); ?>" required>
</div>
</div>
</div>
<!-- Payment Received Table -->
<div class="form-group col-md-12" style="display: none;" id="payment_table_div_modal">
<button type="button" id="add_row_btn" class="btn btn-secondary float-right"><i class="fa fa-plus"></i></button>
<table class="table table-bordered" id="payment_table_modal">
<thead>
<tr>
<th style="display: none;">pk</th>
<th>Invoice Amount</th>
<th>UTR Number</th>
<th>Date</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr>
<td style="display: none;"><input type="hidden" class="form-control" name="pk[]" placeholder="Enter Amount"></td>
<td><input type="number" class="form-control" name="invoice_amount[]" placeholder="Enter Amount" required></td>
<td><input type="text" class="form-control" name="utr_no[]" placeholder="Enter UTR No" required></td>
<td><input type="date" class="form-control" name="payment_date[]" value="<?php echo date('Y-m-d'); ?>" required></td>
<td><i class="fa fa-trash mr-2 font-18 vertical-middle text-danger remove-row" style="text-align: center;"></i></td>
</tr>
</tbody>
</table>
<!-- <button type="button" id="add_row_btn" class="btn btn-secondary float-right mt-2"><i class="fa fa-plus"></i></button> -->
</div>
<div class="form-group text-right m-b-0">
<!-- <button type="button" id="add_row_btn" class="btn btn-primary waves-effect waves-light mr-1">Add payment</button> -->
<button type="submit" class="btn btn-primary waves-effect waves-light mr-1" id="btnSubmit">Submit</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<script>
document.getElementById('invoice_status').addEventListener('change', function () {
const invoiceStatus = this.value;
console.log(invoiceStatus);
const invoiceNoDiv = document.getElementById('invoice_no_div_modal');
// const invoiceDateDiv = document.getElementById('invoice_date_div_modal');
const paymentTableDiv = document.getElementById('payment_table_div_modal');
// Hide everything initially
invoiceNoDiv.style.display = 'none';
// invoiceDateDiv.style.display = 'none';
paymentTableDiv.style.display = 'none';
// Show fields based on selected status
if (invoiceStatus === 'generated' || invoiceStatus === 'sent') {
invoiceNoDiv.style.display = 'flex';
switchRequired('invoice_no_modal',true);
switchRequired('invoice_date_modal',true);
switchRequired('invoice_amount',false,'name');
switchRequired('utr_no',false,'name');
switchRequired('payment_date',false,'name');
switchRequired('pk',false,'name');
// invoiceDateDiv.style.display = 'block';
} else if (invoiceStatus === 'payment_received') {
invoiceNoDiv.style.display = 'flex';
paymentTableDiv.style.display = 'block';
switchRequired('invoice_no_modal',true);
switchRequired('invoice_date_modal',true);
switchRequired('invoice_amount',true,'name');
switchRequired('utr_no',true,'name');
switchRequired('payment_date',true,'name');
switchRequired('pk',true,'name');
}else if(invoiceStatus === 'pending')
{
invoiceNoDiv.style.display = 'none';
paymentTableDiv.style.display = 'none';
switchRequired('invoice_no_modal',false);
switchRequired('invoice_date_modal',false);
switchRequired('invoice_amount',false,'name');
switchRequired('utr_no',false,'name');
switchRequired('payment_date',false,'name');
switchRequired('pk',false,'name');
}
});
$(document).ready(function () {
$('#invoiceForm').on('submit', function (e) {
e.preventDefault(); // Prevent default form submission
var form = document.getElementById('invoiceForm');
if(!form.checkValidity())
{
return false;
}
// Serialize form data to array and then convert to JSON
var formData = new FormData(form);
var formDataJSON = {};
// Iterate over FormData entries
formData.forEach(function(value, key) {
// Check if the key ends with '[]' indicating an array-like input
if (key.endsWith('[]')) {
// Remove '[]' from the key and store it as an array in formDataJSON
var arrayKey = key.slice(0, -2);
if (!formDataJSON[arrayKey]) {
formDataJSON[arrayKey] = [];
}
formDataJSON[arrayKey].push(value); // Push the value into the array
} else {
formDataJSON[key] = value; // Standard single-value field
}
});
// Convert the JSON object to a string
var jsonData = JSON.stringify(formDataJSON);
console.log(jsonData);
$('.loader').fadeIn();
$('.loader-mask').fadeIn();
// Send the JSON data to the backend using AJAX
$.ajax({
url: 'saveInvoicePaymentDetails', // Replace with your backend URL
type: 'POST',
contentType: 'application/json',
data: jsonData,
success: function (response) {
console.log(response);
// Close the modal
// var myModal = new bootstrap.Modal(document.getElementById('invoice_modal'));
// myModal.hide();
// Reset the form data
$('#invoiceForm')[0].reset();
// Optionally display success message or perform further actions
alert('Invoice updated successfully!');
},
error: function (xhr, status, error) {
// Handle any errors
console.error('Form submission failed:', error);
alert('An error occurred while updating the invoice.');
}
});
$('.loader').fadeOut();
$('.loader-mask').delay(10).fadeOut('slow');
});
});
// Add/Delete rows in the payment table
document.getElementById('add_row_btn').addEventListener('click', function () {
const tableBody = document.querySelector('#payment_table_modal tbody');
const newRow = document.createElement('tr');
newRow.innerHTML = `
<td style="display: none;"><input type="hidden" class="form-control" name="pk[]" placeholder="Enter Amount"></td>
<td><input type="number" class="form-control" name="invoice_amount[]" placeholder="Enter Amount" required></td>
<td><input type="text" class="form-control" name="utr_no[]" placeholder="Enter UTR No" required></td>
<td><input type="date" class="form-control" value="<?php echo date('Y-m-d'); ?>" name="payment_date[]" placeholder="Enter UTR No" required></td>
<td><i class="fa fa-trash mr-2 font-18 vertical-middle text-danger remove-row" style="text-align: center;"></i></td>
`;
tableBody.appendChild(newRow);
});
// Remove row
document.getElementById('payment_table_modal').addEventListener('click', function (e) {
if (e.target && e.target.classList.contains('remove-row')) {
if (confirm("Do you want to delete this entry?")) {
var row = e.target.closest('tr');
var pk = row.querySelector('input[name="pk[]"]').value;
if (pk === "") {
// If pk is empty, remove the row
row.remove();
} else {
// If pk is non-empty, send AJAX request to remove it from the backend
$.ajax({
url: '/delete-entry', // Your backend URL here
type: 'POST',
data: { pk: pk }, // Send the pk value to delete on server-side
success: function (response) {
// On success, remove the row
if (response.success) {
row.remove();
} else {
alert('Failed to delete the entry.');
}
},
error: function () {
alert('Error occurred while deleting the entry.');
}
});
}
}
}
});
function switchRequired(elementId, isRequired, type = 'id') {
if(type == 'id')//id attribute
{
let element = document.getElementById(elementId);
if (isRequired) {
element.setAttribute('required', 'required');
} else {
element.removeAttribute('required');
}
}
else //name attribute
{
var name_attribute = elementId+'[]';
// Select all elements with the name 'invoice_amt[]'
var elements = document.getElementsByName(name_attribute);
// Loop through the elements and set or remove the 'required' attribute
elements.forEach(function(element) {
if (isRequired) {
element.setAttribute('required', 'required'); // Make required
} else {
element.removeAttribute('required'); // Remove required
}
});
}
}
</script>
<script>
function showFileUploadModal(input)
{
var myModal = new bootstrap.Modal(document.getElementById('file_upload'));
myModal.show();
// $(input).val('');
}
function showInvoiceStatusModal(event)
{
// console.log(event.target.data)
var dataId = event.target.getAttribute('data-id');
// Set the value to a hidden input field in the modal
document.getElementById('hidden_statement_id').value = dataId;
$('.loader').fadeIn();
$('.loader-mask').fadeIn();
// AJAX call to get the invoice details based on data-id
$.ajax({
url: 'getPaymentDetails/'+ dataId, // Replace with your backend URL
method: 'get',
// data: { id: dataId },
// dataType: 'json',
success: function(response) {
$('.loader').fadeOut();
$('.loader-mask').delay(10).fadeOut('slow');
console.log(response);
// Assuming response contains the necessary data
if (response.dataStatus === true && response.code === 200) {
// Populate modal fields
if(response.data.invoice_status !== null)
{
var inv_status_element = document.getElementById('invoice_status');
inv_status_element.value = response.data.invoice_status;
var event = new Event('change');
inv_status_element.dispatchEvent(event);
}
document.getElementById('invoice_no_modal').value = response.data.invoice_no;
document.getElementById('invoice_date_modal').value = response.data.invoice_date;
// Clear existing rows in the payment table
var paymentTableBody = document.querySelector('#payment_table_modal tbody');
// Populate payment table rows
if(response.data.payments.length)
{
paymentTableBody.innerHTML = '';
response.data.payments.forEach(function(payment) {
var row = paymentTableBody.insertRow();
row.innerHTML = `
<td style="display: none;"><input type="hidden" class="form-control" name="pk[]" value="${payment.id}"></td>
<td><input type="number" class="form-control" name="invoice_amount[]" placeholder="Enter Amount" value="${payment.inv_amt}" required></td>
<td><input type="text" class="form-control" name="utr_no[]" placeholder="Enter UTR No" value="${payment.utr_no}" required></td>
<td><input type="date" class="form-control" name="payment_date[]" value="${payment.received_date}" required></td>
<td><i class="fa fa-trash mr-2 font-18 vertical-middle text-danger remove-row" style="text-align: center;"></i></td>
`;
});
}
// Show the modal
var myModal = new bootstrap.Modal(document.getElementById('invoice_modal'));
myModal.show();
} else {
// Handle error if the response is not successful
console.error('Failed to fetch data:', response);
alert("Something went wrong! Couldn't get data");
}
},
error: function(xhr, status, error) {
// Handle AJAX errors
console.error('AJAX Error:', status, error);
alert("Something went wrong! Couldn't reach app");
}
});
$('.loader').fadeOut();
$('.loader-mask').delay(10).fadeOut('slow');
var myModal = new bootstrap.Modal(document.getElementById('invoice_modal'));
myModal.show();
// $(input).val('');
}
$(document).ready(function(){
var rollover_date = flatpickr("#statement_month", {
dateFormat: "Y-M-d",
allowInput: true
});
});
$('#insurer_statement_upload_form').submit(function(event) {
event.preventDefault();
var isValid = $('#insurer_statement_upload_form').parsley().validate();
if (!isValid) {
console.log('Form is Empty', 'Warning');
alert('choose all fileds');
return;
}
// Create FormData object
var formData = new FormData($(this)[0]);
for (var pair of formData.entries()) {
console.log(pair[0] + ', ' + pair[1]);
}
$('.loader').fadeIn();
$('.loader-mask').fadeIn();
$.ajax({
url: $(this).attr("action"),
type: "POST",
data: formData,
processData: false, // Prevent jQuery from automatically processing the data
contentType: false, // Let jQuery handle the content type
headers: {
// "Content-Type":"multipart/form-data",
"X-Requested-With": "XMLHttpRequest"
},
success: function(response) {
console.log(response);
$('#insurer_statement_upload_form')[0].reset();
if (response.code === 200 && response.dataStatus === true && response
.data !== "") {
toastr.success(
'File upload successs',
'success');
$('.close').click()
window.location.reload(true);
} else if (response.code === 404 && response.dataStatus === false) {
console.error('no data found', response);
// alert(response.message);
toastr.error(response.message, 'Failed');
window.location.reload(true);
} else {
console.error('Something went wrong!');
// alert('Something went wrong! Try later');
toastr.error('Something went wrong! Try later', 'Error');
window.location.reload(true);
}
},
error: function(xhr, status, error) {
// Request failed, handle error
console.error("Request failed:", status, error);
toastr.error('Something went wrong! Try later', 'Error');
$('#uploadForm')[0].reset();
window.location.reload(true);
}
});
$('.loader').fadeOut();
$('.loader-mask').delay(10).fadeOut('slow');
});
</script>

View File

@ -299,7 +299,7 @@
fetchMessages();
setInterval(fetchMessages, 10000); // Fetch messages every ten seconds
setInterval(fetchMessages, 60000); // Fetch messages every sixty seconds
});
$(document).ready(function() {

View File

@ -670,6 +670,9 @@
<li>
<a href="<?= base_url('/policy_tranction/report/list') ?>">BDS</a>
</li>
<li>
<a href="<?= base_url('/policy_tranction/statement/list') ?>">Statement upload</a>
</li>
</ul>
</div>
</li>

Binary file not shown.