MERGE_TEST_MINOR_HR_CLAIMS

This commit is contained in:
Ubuntu 2026-04-20 17:44:59 +05:30
commit a64cc2916e
76 changed files with 4173 additions and 495 deletions

View File

@ -560,6 +560,8 @@ $routes->cli('cli/send_mail_cli', 'MasterController::testGmailAPIViaCLI');
$routes->cli('cli/sendZeptoMail', 'MasterController::testZeptoSMTP'); $routes->cli('cli/sendZeptoMail', 'MasterController::testZeptoSMTP');
$routes->cli('cli/check_bounce_mail_cli', 'MasterController::testCheckBounceMails'); $routes->cli('cli/check_bounce_mail_cli', 'MasterController::testCheckBounceMails');
$routes->cli('cli/app_check_list', 'MasterController::appCheckList'); $routes->cli('cli/app_check_list', 'MasterController::appCheckList');
$routes->cli('cli/reset-token-timeout', 'RestAuthenticationController::resetTokenTimeOut');
$routes->cli('cli/reset-token-timeout/(:num)', 'RestAuthenticationController::resetTokenTimeOut/$1');
$routes->cli('cli/new_gdrive_token', 'GoogleDriveController::generateNewGoogleDriveAccessToken'); $routes->cli('cli/new_gdrive_token', 'GoogleDriveController::generateNewGoogleDriveAccessToken');
$routes->cli('cli/list-sheet-folder-files', 'GoogleSheetController::listFolderSheetFilesCli'); $routes->cli('cli/list-sheet-folder-files', 'GoogleSheetController::listFolderSheetFilesCli');
$routes->cli('cli/list-sheet-folder-files/(:any)', 'GoogleSheetController::listFolderSheetFilesCli/$1'); $routes->cli('cli/list-sheet-folder-files/(:any)', 'GoogleSheetController::listFolderSheetFilesCli/$1');

View File

@ -446,6 +446,9 @@ class ApiServiceController extends BaseController
if ($tpaID == $this->medi_assist_primary_key) { // MediAssist if ($tpaID == $this->medi_assist_primary_key) { // MediAssist
$mediAssistController = new MediAssistApiController(); $mediAssistController = new MediAssistApiController();
return $mediAssistController->IRSubmission($claimId); return $mediAssistController->IRSubmission($claimId);
}else if ($tpaID == $this->vidal_primary_key) { // Vidal
$vidalApiController = new VidalApiController();
return $vidalApiController->IRSubmission($claimId);
}else{ }else{
log_message('error', "This ticket id ( {$claimId} ) TPA has no API service enabled. TPA ID : {$tpaID}"); log_message('error', "This ticket id ( {$claimId} ) TPA has no API service enabled. TPA ID : {$tpaID}");
} }

View File

@ -2409,13 +2409,16 @@ class EmployeeRestController extends AdminController
$client_id = $this->request->getGet('client_id') ?? null; $client_id = $this->request->getGet('client_id') ?? null;
$data['claim_status'] = $this->claimStatusModel $data['claim_status'] = $this->claimStatusModel
->select('id,ticket_type, display_name as claim_status') ->select('id, ticket_type, display_name as claim_status')
->where('is_active', 1) ->where('is_active', 1)
->where('display_name IS NOT NULL OR display_name <> ""') ->groupStart()
->whereIn('claim_status_id',[1,2,3,4]) ->where('display_name IS NOT NULL')
->groupBy('display_name') ->orWhere('display_name <>', '')
->findAll(); ->groupEnd()
->whereIn('ticket_type', [1,2,3,4])
->groupBy('display_name')
->findAll();
if (!empty($client_id)) { if (!empty($client_id)) {
@ -3723,6 +3726,7 @@ class EmployeeRestController extends AdminController
if (! empty($emp_ticket_data)) { if (! empty($emp_ticket_data)) {
$received_relationship = $received_data['relationship'] ?? null;
unset($received_data['relationship']); unset($received_data['relationship']);
$fetchData = $emp_ticket_data[0]; $fetchData = $emp_ticket_data[0];
@ -3750,8 +3754,8 @@ class EmployeeRestController extends AdminController
$fetchData = array_merge($fetchData, $received_data); $fetchData = array_merge($fetchData, $received_data);
// $fetchData['relationship'] = strtolower($fetchData['relationship']) ?? $fetchData['relationship']; // $fetchData['relationship'] = isset($fetchData['relationship']) ? strtolower($fetchData['relationship']) : null;
$fetchData['relationship'] = isset($fetchData['relationship']) ? strtolower($fetchData['relationship']) : null; $fetchData['relationship'] = strtolower($received_relationship ?? $fetchData['relationship'] ?? '') ?: null;
$fetchData['created_by'] = $fetchData['emp_id']; $fetchData['created_by'] = $fetchData['emp_id'];
$fetchData['claim_created_by'] = "USER"; $fetchData['claim_created_by'] = "USER";

View File

@ -85,6 +85,8 @@ class FhplApiController extends BaseController
cp.policy_no as policyNo, cp.policy_no as policyNo,
e.emp_code as memberId, e.emp_code as memberId,
tn.note as disease, tn.note as disease,
cf.id as fileId,
cf.url as filePath,
cf.url as filePath cf.url as filePath
') ')
->join('employees e', 'e.id = tm.emp_id', 'left') ->join('employees e', 'e.id = tm.emp_id', 'left')
@ -102,6 +104,7 @@ class FhplApiController extends BaseController
} }
// Build absolute file path // Build absolute file path
$file_id = $data['fileId'] ?? null;
$filename = basename($data['filePath']); $filename = basename($data['filePath']);
$pdfPath = WRITEPATH . 'uploads/claim_files/' . $filename; $pdfPath = WRITEPATH . 'uploads/claim_files/' . $filename;
@ -182,6 +185,18 @@ class FhplApiController extends BaseController
'tpa_claim_push_reference_no' => $fhplClaimNo, 'tpa_claim_push_reference_no' => $fhplClaimNo,
'updated_at' => date('Y-m-d H:i:s') 'updated_at' => date('Y-m-d H:i:s')
]); ]);
// Update claim files table that file is sent to tpa for this claim
if(!empty($file_id)){
$this->db->table('claim_files')
->where('id', $file_id)
->update([ 'is_file_sent_to_tpa' => 1 ]);
log_message('error','HEALTH_INDIA - Claim Push | Updating claim_files table for file_id: '.$file_id);
}else{
log_message('error','HEALTH_INDIA - Claim Push | No file_id found to update claim_files table.');
}
log_message('error', 'FHPL - Claim Push SUCCESS | claimId: '.$claimId.' | claimNO: '.$fhplClaimNo); log_message('error', 'FHPL - Claim Push SUCCESS | claimId: '.$claimId.' | claimNO: '.$fhplClaimNo);
return ['status' => true, 'message' => 'Claim Push SUCCESS', 'response' => $response]; return ['status' => true, 'message' => 'Claim Push SUCCESS', 'response' => $response];

View File

@ -105,6 +105,7 @@ class HealthIndiaApiController extends BaseController
cp.policy_no as policyNumber, cp.policy_no as policyNumber,
e.emp_code as employeeCode, e.emp_code as employeeCode,
tn.note as disease, tn.note as disease,
cf.id as fileId,
cf.url as filePath, cf.url as filePath,
tm.claim_type as claimType, tm.claim_type as claimType,
tm.claim_type as benefitType tm.claim_type as benefitType
@ -130,6 +131,7 @@ class HealthIndiaApiController extends BaseController
} }
// Build absolute file path // Build absolute file path
$file_id = $data['fileId'] ?? null;
$filename = basename($data['filePath']); $filename = basename($data['filePath']);
$pdfPath = WRITEPATH . 'uploads/claim_files/' . $filename; $pdfPath = WRITEPATH . 'uploads/claim_files/' . $filename;
@ -231,6 +233,18 @@ class HealthIndiaApiController extends BaseController
'updated_at' => date('Y-m-d H:i:s') 'updated_at' => date('Y-m-d H:i:s')
]); ]);
// Update claim files table that file is sent to tpa for this claim
if(!empty($file_id)){
$this->db->table('claim_files')
->where('id', $file_id)
->update([ 'is_file_sent_to_tpa' => 1 ]);
log_message('error','HEALTH_INDIA - Claim Push | Updating claim_files table for file_id: '.$file_id);
}else{
log_message('error','HEALTH_INDIA - Claim Push | No file_id found to update claim_files table.');
}
log_message('error', 'HEALTH_INDIA - Claim Push SUCCESS | claimId: ' . $claimId . ' | CCN: ' . $ccn . ' | CCN_EXT: ' . $ccnExt); log_message('error', 'HEALTH_INDIA - Claim Push SUCCESS | claimId: ' . $claimId . ' | CCN: ' . $ccn . ' | CCN_EXT: ' . $ccnExt);
return ['status' => true, 'message' => 'Claim Push SUCCESS', 'response' => $response]; return ['status' => true, 'message' => 'Claim Push SUCCESS', 'response' => $response];
} else { } else {

View File

@ -42,8 +42,9 @@ class MediAssistApiController extends BaseController
'Password:'. getenv('MEDI_ASSIST_API_PASSWORD').'', 'Password:'. getenv('MEDI_ASSIST_API_PASSWORD').'',
]; ];
$file_id = null;
//Prepare body data //Prepare body data
// Fetch the data from DB // Fetch the data from DB
$data = $this->db->table('ticket_master tm') $data = $this->db->table('ticket_master tm')
->select(' ->select('
@ -59,6 +60,7 @@ class MediAssistApiController extends BaseController
tm.tpa_no as memberId, tm.tpa_no as memberId,
tn.note as disease, tn.note as disease,
tn.note as reasonForHospitalization, tn.note as reasonForHospitalization,
cf.id as fileId,
cf.url as fileName, cf.url as fileName,
cf.url as filePath cf.url as filePath
') ')
@ -83,6 +85,7 @@ class MediAssistApiController extends BaseController
if ($fileDir) { if ($fileDir) {
$downloadUrl = base_url('fileDownload?file_path=').$fileDir; $downloadUrl = base_url('fileDownload?file_path=').$fileDir;
$file_id = $data['fileId'] ?? null;
} else { } else {
$downloadUrl = ''; $downloadUrl = '';
} }
@ -152,10 +155,23 @@ class MediAssistApiController extends BaseController
log_message('error','MEDI_ASSIST - Claim Push SUCCESS | claimId: '.$claimId.' | claimReferenceNo: '.$claimRef); log_message('error','MEDI_ASSIST - Claim Push SUCCESS | claimId: '.$claimId.' | claimReferenceNo: '.$claimRef);
// Update claim reference number in ticket_master
$this->db->table('ticket_master') $this->db->table('ticket_master')
->where('id',$claimId) ->where('id',$claimId)
->update([ 'tpa_claim_push_reference_no' => $claimRef ]); ->update([ 'tpa_claim_push_reference_no' => $claimRef ]);
// Update claim files table that file is sent to tpa for this claim
if(!empty($file_id)){
$this->db->table('claim_files')
->where('id', $file_id)
->update([ 'is_file_sent_to_tpa' => 1 ]);
log_message('error','MEDI_ASSIST - Claim Push | Updating claim_files table for file_id: '.$file_id);
}else{
log_message('error','MEDI_ASSIST - Claim Push | No file_id found to update claim_files table.');
}
return ['status' => true, 'message' => 'Claim Push SUCCESS', 'response' => $response]; return ['status' => true, 'message' => 'Claim Push SUCCESS', 'response' => $response];
} else { } else {
@ -695,16 +711,19 @@ class MediAssistApiController extends BaseController
$fileData = $this->db->table('claim_files f') $fileData = $this->db->table('claim_files f')
->where('f.ticket_id', $claimId) ->where('f.ticket_id', $claimId)
->where('f.docs_for_ir', 1) ->where('f.docs_for_ir', 1)
->where('f.file_type', 2)
->where('f.is_file_sent_to_tpa', 0)
->get() ->get()
->getResultArray(); ->getResultArray();
$Attachments = []; $Attachments = [];
$tpaSentFileIds = [];
if (count($fileData)) { if (count($fileData)) {
foreach ($fileData as $file) { foreach ($fileData as $file) {
if (!empty($file['url'])) { if (!empty($file['url']) && $file['file_type'] == 2) {
$filename = basename($file['url']); $filename = basename($file['url']);
$fileDir = WRITEPATH . 'uploads/claim_files/' . $filename; $fileDir = WRITEPATH . 'uploads/claim_files/' . $filename;
@ -721,6 +740,9 @@ class MediAssistApiController extends BaseController
"AttachmentName" => $filename, "AttachmentName" => $filename,
"AttachmentPath" => $downloadUrl "AttachmentPath" => $downloadUrl
]; ];
$tpaSentFileIds[] = $file['id']; // Collect file IDs to update later
} else { } else {
log_message('error',"MEDI_ASSIST - IR Submission Missing File URL → file_id={$file['id']}"); log_message('error',"MEDI_ASSIST - IR Submission Missing File URL → file_id={$file['id']}");
} }
@ -767,6 +789,18 @@ class MediAssistApiController extends BaseController
log_message('error',"MEDI_ASSIST - IR Submission SUCCESS → ClaimID={$ticket['ClaimID']}"); log_message('error',"MEDI_ASSIST - IR Submission SUCCESS → ClaimID={$ticket['ClaimID']}");
// 6. UPDATE FILES AS SENT TO TPA
if(count($tpaSentFileIds) > 0){
$this->db->table('claim_files')
->whereIn('id', $tpaSentFileIds)
->update(['is_file_sent_to_tpa' => 1]);
log_message('error',"MEDI_ASSIST - IR Submission | Updating claim_files for file IDs: " . implode(', ', $tpaSentFileIds));
} else {
log_message('error',"MEDI_ASSIST - IR Submission | No files to update as sent to TPA");
}
return [ return [
'status' => true, 'status' => true,
'message' => 'IR Submitted successfully', 'message' => 'IR Submitted successfully',

View File

@ -2326,6 +2326,10 @@ class RestAuthenticationController extends AdminController
public function logout() public function logout()
{ {
return $this->respond([
'status' => true,
'message' => 'Logged out successfully'
], 200);
$authHeader = $this->request->getHeaderLine('Authorization'); $authHeader = $this->request->getHeaderLine('Authorization');
if (!$authHeader) { if (!$authHeader) {
@ -2373,4 +2377,52 @@ class RestAuthenticationController extends AdminController
], 200); ], 200);
} }
public function resetTokenTimeOut($bufferSeconds = null)
{
if (!is_cli()) {
return $this->respond([
'status' => false,
'message' => 'This endpoint is CLI only.'
], 403);
}
$envBuffer = (int) (getenv('TOKEN_TIMEOUT_RESET_BUFFER_SECONDS') ?: 300);
$buffer = is_numeric($bufferSeconds) ? (int) $bufferSeconds : $envBuffer;
if ($buffer < 0) {
$buffer = 0;
}
$cutoffEpoch = time() - $buffer;
$db = db_connect();
$db->table('level_contacts')
->where('token_time_out IS NOT NULL', null, false)
->where('token_time_out <=', $cutoffEpoch)
->set(['token_time_out' => null])
->update();
$levelContactsUpdated = $db->affectedRows();
$db->table('employees')
->where('token_time_out IS NOT NULL', null, false)
->where('token_time_out <=', $cutoffEpoch)
->set(['token_time_out' => null])
->update();
$employeesUpdated = $db->affectedRows();
$result = [
'status' => true,
'message' => 'Token timeout reset completed.',
'buffer_seconds' => $buffer,
'cutoff_epoch' => $cutoffEpoch,
'updated' => [
'level_contacts' => $levelContactsUpdated,
'employees' => $employeesUpdated,
'total' => $levelContactsUpdated + $employeesUpdated,
],
];
echo json_encode($result, JSON_UNESCAPED_SLASHES) . PHP_EOL;
return;
}
} }

View File

@ -503,6 +503,7 @@ class TicketController extends BaseController
'tm.id', 'tm.id',
'tm.ticket_type_id', 'tm.ticket_type_id',
'tm.claim_status_id', 'tm.claim_status_id',
'tm.claim_created_by',
'tm.is_head_approved', 'tm.is_head_approved',
'tcs.claim_status AS status', 'tcs.claim_status AS status',
'tm.claim_number AS claim_no', 'tm.claim_number AS claim_no',
@ -538,6 +539,7 @@ class TicketController extends BaseController
'tm.emp_personal_mail', 'tm.emp_personal_mail',
'tm.mode_of_intimation', 'tm.mode_of_intimation',
'tm.claim_type', 'tm.claim_type',
'tm.tpa_claim_type',
'tm.hospital_name', 'tm.hospital_name',
'tm.doa', 'tm.doa',
'tm.dod', 'tm.dod',
@ -640,6 +642,7 @@ class TicketController extends BaseController
'tcs.claim_status AS status', 'tcs.claim_status AS status',
'tm.claim_number AS claim_no', 'tm.claim_number AS claim_no',
'tm.claim_status_id', 'tm.claim_status_id',
'tm.claim_created_by',
'tm.is_head_approved', 'tm.is_head_approved',
'tm.tpa_id', 'tm.tpa_id',
'tm.tpa_no', 'tm.tpa_no',
@ -671,6 +674,7 @@ class TicketController extends BaseController
'tm.emp_personal_mail', 'tm.emp_personal_mail',
'tm.mode_of_intimation', 'tm.mode_of_intimation',
'tm.claim_type', 'tm.claim_type',
'tm.tpa_claim_type',
'tm.hospital_name', 'tm.hospital_name',
'tm.doa', 'tm.doa',
'tm.dod', 'tm.dod',
@ -1138,6 +1142,8 @@ class TicketController extends BaseController
public function createTicket() public function createTicket()
{ {
$request_data = $this->request->getPost(); $request_data = $this->request->getPost();
$approvedLetterFile = $this->request->getFile('approved_letter_file');
$settleLetterFile = $this->request->getFile('settle_letter_file');
$selected_ticket_type = $this->request->getPost('ticket_type_id'); $selected_ticket_type = $this->request->getPost('ticket_type_id');
// 1. Initialize an empty rules array // 1. Initialize an empty rules array
@ -1453,6 +1459,84 @@ class TicketController extends BaseController
$request_data = $this->request->getPost(); $request_data = $this->request->getPost();
$sanitized_data = sanitizeInputArrayAdvanced($request_data); $sanitized_data = sanitizeInputArrayAdvanced($request_data);
$ticket_data = $this->formatDateForClaim($sanitized_data); $ticket_data = $this->formatDateForClaim($sanitized_data);
$approvedLetterUrl = trim((string) ($ticket_data['approved_letter'] ?? ''));
$settleLetterUrl = trim((string) ($ticket_data['settle_letter'] ?? ''));
$hasApprovedLetterFile = $approvedLetterFile !== null
&& $approvedLetterFile->isValid()
&& $approvedLetterFile->getError() !== UPLOAD_ERR_NO_FILE;
$hasSettleLetterFile = $settleLetterFile !== null
&& $settleLetterFile->isValid()
&& $settleLetterFile->getError() !== UPLOAD_ERR_NO_FILE;
if ($approvedLetterUrl !== '' && $hasApprovedLetterFile) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Input validation failed',
'code' => 400,
'errors' => ['approved_letter' => 'Provide either Approved Letter URL or Approved Letter PDF file, not both.'],
]);
}
if ($approvedLetterUrl !== '' && ! $this->isClaimUploadUrl($approvedLetterUrl)) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Input validation failed',
'code' => 400,
'errors' => ['approved_letter' => 'Approved Letter URL format is invalid.'],
]);
}
if ($settleLetterUrl !== '' && $hasSettleLetterFile) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Input validation failed',
'code' => 400,
'errors' => ['settle_letter' => 'Provide either Settle Letter URL or Settle Letter PDF file, not both.'],
]);
}
if ($settleLetterUrl !== '' && ! $this->isClaimUploadUrl($settleLetterUrl)) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Input validation failed',
'code' => 400,
'errors' => ['settle_letter' => 'Settle Letter URL format is invalid.'],
]);
}
$uploadedApprovedLetter = null;
if ($hasApprovedLetterFile) {
$uploadResult = $this->uploadApprovedLetterPdf($approvedLetterFile, 'Approved Letter');
if (! ($uploadResult['status'] ?? false)) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Input validation failed',
'code' => 400,
'errors' => ['approved_letter_file' => $uploadResult['message'] ?? 'Invalid Approved Letter file.'],
]);
}
$uploadedApprovedLetter = $uploadResult['data'];
$ticket_data['approved_letter'] = '';
} else {
$ticket_data['approved_letter'] = $approvedLetterUrl;
}
$uploadedSettleLetter = null;
if ($hasSettleLetterFile) {
$uploadResult = $this->uploadApprovedLetterPdf($settleLetterFile, 'Settle Letter');
if (! ($uploadResult['status'] ?? false)) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Input validation failed',
'code' => 400,
'errors' => ['settle_letter_file' => $uploadResult['message'] ?? 'Invalid Settle Letter file.'],
]);
}
$uploadedSettleLetter = $uploadResult['data'];
$ticket_data['settle_letter'] = '';
} else {
$ticket_data['settle_letter'] = $settleLetterUrl;
}
// $ticket_data = $this->getLastMatchedStatus($ticket_data, ); // $ticket_data = $this->getLastMatchedStatus($ticket_data, );
// print_rr($ticket_data); die; // print_rr($ticket_data); die;
@ -1497,6 +1581,37 @@ class TicketController extends BaseController
$ticket_data['claim_created_by'] = "CRM"; $ticket_data['claim_created_by'] = "CRM";
$return_value = $this->ticketMasterModel->insert($ticket_data); $return_value = $this->ticketMasterModel->insert($ticket_data);
if ($return_value) { if ($return_value) {
if ($uploadedApprovedLetter !== null) {
$approvedLetterDownloadUrl = $this->createApprovedLetterFileUrl(
(int) $return_value,
(int) ($ticket_data['ticket_type_id'] ?? 1),
$uploadedApprovedLetter,
'APPROVED_LETTER_PDF'
);
$ticket_data['approved_letter'] = $approvedLetterDownloadUrl;
}
if ($uploadedSettleLetter !== null) {
$settleLetterDownloadUrl = $this->createApprovedLetterFileUrl(
(int) $return_value,
(int) ($ticket_data['ticket_type_id'] ?? 1),
$uploadedSettleLetter,
'SETTLE_LETTER_PDF'
);
$ticket_data['settle_letter'] = $settleLetterDownloadUrl;
}
if ($uploadedApprovedLetter !== null || $uploadedSettleLetter !== null) {
$updateUploadedLetterData = [];
if (isset($ticket_data['approved_letter'])) {
$updateUploadedLetterData['approved_letter'] = $ticket_data['approved_letter'];
}
if (isset($ticket_data['settle_letter'])) {
$updateUploadedLetterData['settle_letter'] = $ticket_data['settle_letter'];
}
$this->ticketMasterModel->where('id', $return_value)->set($updateUploadedLetterData)->update();
}
//mail trigger part //mail trigger part
$this->putHistoryAfterInsert($ticket_data, $return_value); $this->putHistoryAfterInsert($ticket_data, $return_value);
$mail_responce = $this->sendAutoMailTrigger($return_value); $mail_responce = $this->sendAutoMailTrigger($return_value);
@ -1515,6 +1630,8 @@ class TicketController extends BaseController
{ {
$request_data = $this->request->getPost(); $request_data = $this->request->getPost();
$approvedLetterFile = $this->request->getFile('approved_letter_file');
$settleLetterFile = $this->request->getFile('settle_letter_file');
$selected_ticket_type = $this->request->getPost('ticket_type_id'); $selected_ticket_type = $this->request->getPost('ticket_type_id');
// 1. Initialize an empty rules array // 1. Initialize an empty rules array
@ -1830,6 +1947,85 @@ class TicketController extends BaseController
$sanitized_data = sanitizeInputArrayAdvanced($request_data); $sanitized_data = sanitizeInputArrayAdvanced($request_data);
$ticket_data = $this->formatDateForClaim($sanitized_data); $ticket_data = $this->formatDateForClaim($sanitized_data);
$ticket_id = $this->request->getPost('ticket_master_id'); $ticket_id = $this->request->getPost('ticket_master_id');
$approvedLetterUrl = trim((string) ($ticket_data['approved_letter'] ?? ''));
$settleLetterUrl = trim((string) ($ticket_data['settle_letter'] ?? ''));
$hasApprovedLetterFile = $approvedLetterFile !== null
&& $approvedLetterFile->isValid()
&& $approvedLetterFile->getError() !== UPLOAD_ERR_NO_FILE;
$hasSettleLetterFile = $settleLetterFile !== null
&& $settleLetterFile->isValid()
&& $settleLetterFile->getError() !== UPLOAD_ERR_NO_FILE;
if ($approvedLetterUrl !== '' && $hasApprovedLetterFile) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Input validation failed',
'code' => 400,
'errors' => ['approved_letter' => 'Provide either Approved Letter URL or Approved Letter PDF file, not both.'],
]);
}
if ($approvedLetterUrl !== '' && ! $this->isClaimUploadUrl($approvedLetterUrl)) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Input validation failed',
'code' => 400,
'errors' => ['approved_letter' => 'Approved Letter URL format is invalid.'],
]);
}
if ($settleLetterUrl !== '' && $hasSettleLetterFile) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Input validation failed',
'code' => 400,
'errors' => ['settle_letter' => 'Provide either Settle Letter URL or Settle Letter PDF file, not both.'],
]);
}
if ($settleLetterUrl !== '' && ! $this->isClaimUploadUrl($settleLetterUrl)) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Input validation failed',
'code' => 400,
'errors' => ['settle_letter' => 'Settle Letter URL format is invalid.'],
]);
}
$uploadedApprovedLetter = null;
if ($hasApprovedLetterFile) {
$uploadResult = $this->uploadApprovedLetterPdf($approvedLetterFile, 'Approved Letter');
if (! ($uploadResult['status'] ?? false)) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Input validation failed',
'code' => 400,
'errors' => ['approved_letter_file' => $uploadResult['message'] ?? 'Invalid Approved Letter file.'],
]);
}
$uploadedApprovedLetter = $uploadResult['data'];
$ticket_data['approved_letter'] = '';
} else {
$ticket_data['approved_letter'] = $approvedLetterUrl;
}
$uploadedSettleLetter = null;
if ($hasSettleLetterFile) {
$uploadResult = $this->uploadApprovedLetterPdf($settleLetterFile, 'Settle Letter');
if (! ($uploadResult['status'] ?? false)) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Input validation failed',
'code' => 400,
'errors' => ['settle_letter_file' => $uploadResult['message'] ?? 'Invalid Settle Letter file.'],
]);
}
$uploadedSettleLetter = $uploadResult['data'];
$ticket_data['settle_letter'] = '';
} else {
$ticket_data['settle_letter'] = $settleLetterUrl;
}
$old_ticket_data = $this->ticketMasterModel->where('id', $ticket_id)->where('is_active', 1)->first(); $old_ticket_data = $this->ticketMasterModel->where('id', $ticket_id)->where('is_active', 1)->first();
$ticket_data['claim_status_id'] = $this->getLastMatchedStatus($ticket_data, $old_ticket_data); $ticket_data['claim_status_id'] = $this->getLastMatchedStatus($ticket_data, $old_ticket_data);
$ticket_data['last_updated_by'] = 'USER'; $ticket_data['last_updated_by'] = 'USER';
@ -1840,6 +2036,24 @@ class TicketController extends BaseController
$this->myLogger->logme('error', "[UPDATE_CLAIM] New Ticket Data: {data}", ['data' => json_encode($ticket_data, JSON_PRETTY_PRINT)]); $this->myLogger->logme('error', "[UPDATE_CLAIM] New Ticket Data: {data}", ['data' => json_encode($ticket_data, JSON_PRETTY_PRINT)]);
if ($ticket_data) { if ($ticket_data) {
if ($uploadedApprovedLetter !== null) {
$ticket_data['approved_letter'] = $this->createApprovedLetterFileUrl(
(int) $ticket_id,
(int) ($ticket_data['ticket_type_id'] ?? 1),
$uploadedApprovedLetter,
'APPROVED_LETTER_PDF'
);
}
if ($uploadedSettleLetter !== null) {
$ticket_data['settle_letter'] = $this->createApprovedLetterFileUrl(
(int) $ticket_id,
(int) ($ticket_data['ticket_type_id'] ?? 1),
$uploadedSettleLetter,
'SETTLE_LETTER_PDF'
);
}
$return_value = $this->ticketMasterModel->where('id', $ticket_id)->set($ticket_data)->update(); $return_value = $this->ticketMasterModel->where('id', $ticket_id)->set($ticket_data)->update();
if ($return_value) { if ($return_value) {
@ -3262,6 +3476,55 @@ class TicketController extends BaseController
return strpos($host, '.') !== false; return strpos($host, '.') !== false;
} }
private function uploadApprovedLetterPdf($file, string $documentLabel = 'Approved Letter'): array
{
if ($file === null || ! $file->isValid() || $file->getError() === UPLOAD_ERR_NO_FILE) {
return ['status' => false, 'message' => $documentLabel . ' file is missing.'];
}
$ext = strtolower((string) $file->getClientExtension());
$mime = strtolower((string) $file->getMimeType());
$allowedMime = ['application/pdf', 'application/x-pdf'];
if ($ext !== 'pdf' || (! empty($mime) && ! in_array($mime, $allowedMime, true))) {
return ['status' => false, 'message' => 'Only PDF files are allowed for ' . $documentLabel . ' upload.'];
}
$uploadPath = WRITEPATH . 'uploads/claim_files/';
if (! is_dir($uploadPath)) {
mkdir($uploadPath, 0755, true);
}
$diskFileName = file_Upload_for_lead($file, $uploadPath, ['pdf']);
if (empty($diskFileName)) {
return ['status' => false, 'message' => 'Failed to upload ' . $documentLabel . ' file.'];
}
return [
'status' => true,
'data' => [
'file_name' => $diskFileName,
'mime_type' => $mime ?: 'application/pdf',
],
];
}
private function createApprovedLetterFileUrl(int $ticketId, int $ticketTypeId, array $uploadedFile, string $docName = 'APPROVED_LETTER_PDF'): string
{
$fileId = $this->claimFilesModel->insert([
'ticket_id' => $ticketId,
'ticket_type' => $ticketTypeId,
'file_type' => 3,
'doc_name' => $docName,
'file_name' => $uploadedFile['file_name'],
'url' => $uploadedFile['file_name'],
'mime_type' => $uploadedFile['mime_type'] ?? 'application/pdf',
'is_active' => 1,
]);
return base_url('downloadClaimFile/' . $fileId);
}
public function upload_url() public function upload_url()
{ {
@ -3377,6 +3640,7 @@ class TicketController extends BaseController
} }
} }
//get the claim file list data against the ticket id
public function getUrlDataByTicketId() public function getUrlDataByTicketId()
{ {
$ticket_id = $this->request->getPost('ticket_id'); $ticket_id = $this->request->getPost('ticket_id');
@ -3399,6 +3663,7 @@ class TicketController extends BaseController
END AS url END AS url
") ")
->where('ticket_id', $ticket_id) ->where('ticket_id', $ticket_id)
->where('file_type !=', 3) // Assuming you want to fetch both URL and file uploads
->where('is_active', 1) ->where('is_active', 1)
->findAll(); ->findAll();

View File

@ -156,6 +156,7 @@ class VidalApiController extends BaseController
e.emp_code as memberId, e.emp_code as memberId,
tn.note as disease, tn.note as disease,
tn.note as reasonForHospitalization, tn.note as reasonForHospitalization,
cf.id as cfFileId,
cf.url as fileName, cf.url as fileName,
cf.url as filePath, cf.url as filePath,
pt.policy_type as typeOfClaim, pt.policy_type as typeOfClaim,
@ -195,6 +196,7 @@ class VidalApiController extends BaseController
} }
$fileId = $upload['fileId']; $fileId = $upload['fileId'];
$tpa_sent_file_id = $data['cfFileId'] ?? null;
// $url = 'https://devapigw.vidalhealthtpa.com/partner-integration/api/claims/submit'; // $url = 'https://devapigw.vidalhealthtpa.com/partner-integration/api/claims/submit';
$url = getenv('VIDAL_API_BASE_URL').'/claims/submit'; $url = getenv('VIDAL_API_BASE_URL').'/claims/submit';
$method = 'POST'; $method = 'POST';
@ -299,6 +301,18 @@ class VidalApiController extends BaseController
->where('id',$claimId) ->where('id',$claimId)
->update([ 'tpa_claim_push_reference_no' => $claimInwardNO , 'tpa_claim_id' => $claimNO , 'claim_number' => $claimNO ]); ->update([ 'tpa_claim_push_reference_no' => $claimInwardNO , 'tpa_claim_id' => $claimNO , 'claim_number' => $claimNO ]);
// Update claim files table that file is sent to tpa for this claim
if(!empty($tpa_sent_file_id)){
$this->db->table('claim_files')
->where('id', $tpa_sent_file_id)
->update([ 'is_file_sent_to_tpa' => 1 ]);
log_message('error','MEDI_ASSIST - Claim Push | Updating claim_files table for file_id: '.$tpa_sent_file_id);
}else{
log_message('error','MEDI_ASSIST - Claim Push | No file_id found to update claim_files table.');
}
return ['status' => true, 'message' => 'Claim Push SUCCESS']; return ['status' => true, 'message' => 'Claim Push SUCCESS'];
} else { } else {
@ -1664,6 +1678,8 @@ class VidalApiController extends BaseController
$fileData = $this->db->table('claim_files f') $fileData = $this->db->table('claim_files f')
->where('f.ticket_id', $claimId) ->where('f.ticket_id', $claimId)
->where('f.docs_for_ir', 1) ->where('f.docs_for_ir', 1)
->where('f.file_type', 2)
->where('f.is_file_sent_to_tpa', 0)
->get() ->get()
->getResultArray(); ->getResultArray();
@ -1678,6 +1694,7 @@ class VidalApiController extends BaseController
// 3. UPLOAD FILES TO VIDAL // 3. UPLOAD FILES TO VIDAL
$fileIdList = []; $fileIdList = [];
$tpaSentFileIds = [];
foreach ($fileData as $file) { foreach ($fileData as $file) {
@ -1701,6 +1718,7 @@ class VidalApiController extends BaseController
} }
$fileIdList[] = $upload['fileId']; // deeplink URL $fileIdList[] = $upload['fileId']; // deeplink URL
$tpaSentFileIds[] = $file['id']; // local file ID for updating
} }
if (empty($fileIdList)) { if (empty($fileIdList)) {
@ -1756,6 +1774,18 @@ class VidalApiController extends BaseController
log_message('error', "VIDAL - IR Submission SUCCESS → ClaimNO={$ticket['claimNO']}"); log_message('error', "VIDAL - IR Submission SUCCESS → ClaimNO={$ticket['claimNO']}");
// 6. UPDATE FILES AS SENT TO TPA
if(count($tpaSentFileIds) > 0){
$this->db->table('claim_files')
->whereIn('id', $tpaSentFileIds)
->update(['is_file_sent_to_tpa' => 1]);
log_message('error',"VIDAL - IR Submission | Updating claim_files for file IDs: " . implode(', ', $tpaSentFileIds));
} else {
log_message('error',"VIDAL - IR Submission | No files to update as sent to TPA");
}
return [ return [
'status' => true, 'status' => true,
'message' => 'IR Submitted successfully', 'message' => 'IR Submitted successfully',

View File

@ -692,6 +692,7 @@ class VoloApiController extends BaseController
tm.claim_amount as requestedAmount, tm.claim_amount as requestedAmount,
tm.tpa_no as memberId, tm.tpa_no as memberId,
cp.policy_no as policyNo, cp.policy_no as policyNo,
cf.id as fileId,
cf.url as filePath cf.url as filePath
') ')
->join('client_policy cp', 'tm.client_policy_id = cp.id', 'left') ->join('client_policy cp', 'tm.client_policy_id = cp.id', 'left')
@ -710,6 +711,7 @@ class VoloApiController extends BaseController
return ['status' => false, 'message' => 'Claim Push FAILED | File Missing']; return ['status' => false, 'message' => 'Claim Push FAILED | File Missing'];
} }
$file_id = $data['fileId'] ?? null;
$filename = basename($data['filePath']); $filename = basename($data['filePath']);
$pdfPath = WRITEPATH . 'uploads/claim_files/' . $filename; $pdfPath = WRITEPATH . 'uploads/claim_files/' . $filename;
if (!is_readable($pdfPath)) { if (!is_readable($pdfPath)) {
@ -781,6 +783,18 @@ class VoloApiController extends BaseController
]); ]);
log_message('error', 'VOLO - Claim Push SUCCESS | claimId: ' . $claimId . ' | ref: ' . $ref); log_message('error', 'VOLO - Claim Push SUCCESS | claimId: ' . $claimId . ' | ref: ' . $ref);
// Update claim files table that file is sent to tpa for this claim
if(!empty($file_id)){
$this->db->table('claim_files')
->where('id', $file_id)
->update([ 'is_file_sent_to_tpa' => 1 ]);
log_message('error','VOLO - Claim Push | Updating claim_files table for file_id: '.$file_id);
}else{
log_message('error','VOLO - Claim Push | No file_id found to update claim_files table.');
}
return ['status' => true, 'message' => 'Claim Push SUCCESS', 'response' => $response]; return ['status' => true, 'message' => 'Claim Push SUCCESS', 'response' => $response];
} }

View File

@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
/**
* Batch-list style column widths: px from max character count (same formula as batch_list.php).
*
* @param array<int, string> $headerLabels
* @param array<int, int> $maxLenPerCol Same length as $headerLabels
* @param array<int, int> $minPx
* @param array<int, int> $maxPx
* @return array<int, int>
*/
function nhance_dt_column_widths_px(array $headerLabels, array $maxLenPerCol, array $minPx, array $maxPx): array
{
$n = count($headerLabels);
$out = [];
for ($i = 0; $i < $n; $i++) {
$chars = max($maxLenPerCol[$i] ?? 0, mb_strlen($headerLabels[$i]));
$px = (int) round($chars * 7.0 + 26);
$out[] = min(
(int) ($maxPx[$i] ?? 640),
max((int) ($minPx[$i] ?? 48), $px)
);
}
return $out;
}

View File

@ -24,6 +24,7 @@ class ClaimFilesModel extends Model
'file_name', 'file_name',
'mime_type', 'mime_type',
'docs_for_ir', 'docs_for_ir',
'is_file_sent_to_tpa',
]; ];
// Callbacks // Callbacks

View File

@ -341,6 +341,62 @@ table.dataTable tbody td {
</style> </style>
<?php
helper('datatable_view');
$UserList = $UserList ?? [];
$ul_header_labels = ['Name', 'Email', 'Mobile No', 'Role', 'Status', 'Action'];
$ul_col_count = count($ul_header_labels);
$ul_col_max_len = array_fill(0, $ul_col_count, 0);
for ($i = 0; $i < $ul_col_count; $i++) {
$ul_col_max_len[$i] = mb_strlen($ul_header_labels[$i]);
}
if (!empty($UserList)) {
foreach ($UserList as $row) {
$ul_col_max_len[0] = max($ul_col_max_len[0], mb_strlen((string) ($row->first_name ?? '')));
$ul_col_max_len[1] = max($ul_col_max_len[1], mb_strlen((string) ($row->email ?? '')));
$ul_col_max_len[2] = max($ul_col_max_len[2], mb_strlen((string) ($row->mobile ?? '')));
$ul_col_max_len[3] = max($ul_col_max_len[3], mb_strlen((string) ($row->user_role ?? '')));
$statusLabel = (($row->is_active ?? 0) == 1) ? 'Active' : 'In-Active';
$ul_col_max_len[4] = max($ul_col_max_len[4], mb_strlen($statusLabel));
$ul_col_max_len[5] = max($ul_col_max_len[5], 4);
}
}
$ul_col_min_px = array_fill(0, $ul_col_count, 80);
$ul_col_max_px = array_fill(0, $ul_col_count, 360);
$ul_col_min_px[0] = 72;
$ul_col_max_px[0] = 280;
$ul_col_min_px[5] = 72;
$ul_col_max_px[5] = 96;
$ul_col_width_px = nhance_dt_column_widths_px($ul_header_labels, $ul_col_max_len, $ul_col_min_px, $ul_col_max_px);
?>
<style>
<?php for ($i = 0; $i < $ul_col_count; $i++) : ?>
#user-table_wrapper .dataTables_scrollHead table thead th:nth-child(<?= $i + 1 ?>),
#user-table thead th:nth-child(<?= $i + 1 ?>) {
min-width: <?= (int) $ul_col_width_px[$i] ?>px;
width: <?= (int) $ul_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
overflow: visible !important;
}
#user-table tbody td:nth-child(<?= $i + 1 ?>) {
width: <?= (int) $ul_col_width_px[$i] ?>px;
max-width: <?= (int) $ul_col_width_px[$i] ?>px;
min-width: <?= (int) $ul_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
}
<?php endfor; ?>
#user-table tbody td:not(:last-child) {
overflow: hidden;
text-overflow: ellipsis;
}
#user-table tbody td:last-child {
overflow: visible;
text-overflow: clip;
}
</style>
<?php <?php
$session = \Config\Services::session(); $session = \Config\Services::session();
@ -951,8 +1007,8 @@ table.dataTable tbody td {
allowInput: false, allowInput: false,
}); });
table = $('#user-table').DataTable({ nhanceListDataTableBeforeInit();
scrollX: true, table = $('#user-table').DataTable(nhanceMergeListDataTableOptions({
// dom: "<'row'<'col-sm-3'f><'col-sm-9'B>>" + // dom: "<'row'<'col-sm-3'f><'col-sm-9'B>>" +
// "<'row'<'col-sm-12'tr>>" + // "<'row'<'col-sm-12'tr>>" +
// "<'row'<'col-sm-5'i><'col-sm-7'p>>", // "<'row'<'col-sm-5'i><'col-sm-7'p>>",
@ -1083,8 +1139,15 @@ table.dataTable tbody td {
$(this).addClass('active'); $(this).addClass('active');
loadPartner(); loadPartner();
}); });
} },
}); columnDefs: [
<?php for ($i = 0; $i < $ul_col_count; $i++) : ?>
{ targets: <?= $i ?>, width: '<?= (int) $ul_col_width_px[$i] ?>px' },
<?php endfor; ?>
]
}));
nhanceListDataTableAfterInit();
nhanceListDataTableBindAdjust(table);
function applyBottomRowDropup() { function applyBottomRowDropup() {
if (!table) return; if (!table) return;
@ -1109,12 +1172,12 @@ table.dataTable tbody td {
// IMPORTANT — DataTables draw event REF: TTS // IMPORTANT — DataTables draw event REF: TTS
table.on('draw.dt', function () { table.on('draw.dt', function () {
let rowCount = $('#scroll-horizontal-datatable').DataTable().rows({ filter: 'applied' }).count(); let rowCount = table.rows({ filter: 'applied' }).count();
if (rowCount <= 2) { if (rowCount <= 2) {
$('.dataTables_scrollBody').css('overflow', 'inherit'); $('#user-table_wrapper .dataTables_scrollBody').css('overflow', 'inherit');
} else { } else {
$('.dataTables_scrollBody').css('overflow', 'auto'); $('#user-table_wrapper .dataTables_scrollBody').css('overflow', 'auto');
} }
}); });

View File

@ -1,3 +1,27 @@
<?php
helper('datatable_view');
$aim_header_labels = [
'Advertisement Image Name', 'Client Name', 'Client Short Name', 'Status', 'Action',
];
$aim_col_count = count($aim_header_labels);
$aim_col_max_len = array_fill(0, $aim_col_count, 0);
for ($i = 0; $i < $aim_col_count; $i++) {
$aim_col_max_len[$i] = mb_strlen($aim_header_labels[$i]);
}
$addImageList = $addImageList ?? [];
foreach ($addImageList as $row) {
$aim_col_max_len[0] = max($aim_col_max_len[0], mb_strlen((string) ($row['name'] ?? '')));
$c1 = ($row['client_id'] ?? 0) != 0 ? (string) ($row['client_name'] ?? '') : '-';
$aim_col_max_len[1] = max($aim_col_max_len[1], mb_strlen($c1));
$c2 = ($row['client_id'] ?? 0) != 0 ? (string) ($row['short_name'] ?? '') : '-';
$aim_col_max_len[2] = max($aim_col_max_len[2], mb_strlen($c2));
$aim_col_max_len[3] = max($aim_col_max_len[3], mb_strlen((string) ($row['status'] ?? '')));
$aim_col_max_len[4] = max($aim_col_max_len[4], 4);
}
$aim_col_min_px = [120, 140, 120, 88, 72];
$aim_col_max_px = [400, 400, 240, 140, 88];
$aim_col_width_px = nhance_dt_column_widths_px($aim_header_labels, $aim_col_max_len, $aim_col_min_px, $aim_col_max_px);
?>
<style> <style>
.col-12{ .col-12{
@ -6,6 +30,45 @@
.dataTables_length label {height: 21px !important;} .dataTables_length label {height: 21px !important;}
<?php for ($i = 0; $i < $aim_col_count; $i++) : ?>
#add-image-list-table_wrapper .dataTables_scrollHead table thead th:nth-child(<?= $i + 1 ?>),
#add-image-list-table thead th:nth-child(<?= $i + 1 ?>) {
min-width: <?= (int) $aim_col_width_px[$i] ?>px;
width: <?= (int) $aim_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
overflow: visible !important;
}
#add-image-list-table tbody td:nth-child(<?= $i + 1 ?>) {
width: <?= (int) $aim_col_width_px[$i] ?>px;
max-width: <?= (int) $aim_col_width_px[$i] ?>px;
min-width: <?= (int) $aim_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
}
<?php endfor; ?>
#add-image-list-table tbody td:nth-child(1),
#add-image-list-table tbody td:nth-child(2),
#add-image-list-table tbody td:nth-child(3),
#add-image-list-table tbody td:nth-child(4) {
overflow: hidden;
text-overflow: ellipsis;
}
#add-image-list-table tbody td:nth-child(5) {
overflow: visible;
text-overflow: clip;
}
#add-image-list-table tbody td {
padding: 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
#add-image-list-table thead th {
padding: 5px 2.35rem 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
</style> </style>
<div class="row" id="client_list"> <div class="row" id="client_list">
@ -22,7 +85,7 @@
</div> --> </div> -->
<!-- <table data-custom-table-css="table" class="table table-sm table-hover m-0 table-centered dt-responsive nowrap w-100" cellspacing="0" <!-- <table data-custom-table-css="table" class="table table-sm table-hover m-0 table-centered dt-responsive nowrap w-100" cellspacing="0"
id="tickets-table"> --> id="tickets-table"> -->
<table data-custom-table-css="table" class="table mb-0 nowrap" cellspacing="0" id="tickets-table"> <table data-custom-table-css="table" class="table mb-0 nowrap" cellspacing="0" id="add-image-list-table">
<thead class="bg-light"> <thead class="bg-light">
<tr> <tr>
<th class="font-weight-medium">Advertisement Image Name&nbsp;</th> <th class="font-weight-medium">Advertisement Image Name&nbsp;</th>
@ -338,7 +401,8 @@
$('#add_image_id').val(''); $('#add_image_id').val('');
$('#client_id').val(null).trigger('change'); $('#client_id').val(null).trigger('change');
$('#advertise_image').val(''); $('#advertise_image').val('');
table = $('#tickets-table').DataTable({ nhanceListDataTableBeforeInit();
table = $('#add-image-list-table').DataTable(nhanceMergeListDataTableOptions({
// dom: "<'row'<'col-sm-1'f><'col-sm-11 text-right'B>>" + // Filter left, button right // dom: "<'row'<'col-sm-1'f><'col-sm-11 text-right'B>>" + // Filter left, button right
// "<'row'<'col-sm-12'tr>>" + // "<'row'<'col-sm-12'tr>>" +
// "<'row'<'col-sm-5'i><'col-sm-7'p>>", // "<'row'<'col-sm-5'i><'col-sm-7'p>>",
@ -372,15 +436,22 @@
next: '►' next: '►'
} }
}, },
paging: true paging: true,
}); columnDefs: [
<?php for ($i = 0; $i < $aim_col_count; $i++) : ?>
{ targets: <?= $i ?>, width: '<?= (int) $aim_col_width_px[$i] ?>px' },
<?php endfor; ?>
],
}));
nhanceListDataTableAfterInit();
nhanceListDataTableBindAdjust(table);
function applyBottomRowDropup() { function applyBottomRowDropup() {
if (!table) return; if (!table) return;
const currentRows = table.rows({ page: 'current' }).nodes().toArray(); const currentRows = table.rows({ page: 'current' }).nodes().toArray();
$('#tickets-table tbody tr').removeClass('nh-force-dropup'); $('#add-image-list-table tbody tr').removeClass('nh-force-dropup');
$('#tickets-table tbody tr td.table-action-cell .btn-group.dropdown').removeClass('dropup'); $('#add-image-list-table tbody tr td.table-action-cell .btn-group.dropdown').removeClass('dropup');
const targetCount = Math.min(2, currentRows.length); const targetCount = Math.min(2, currentRows.length);
for (let i = 0; i < targetCount; i++) { for (let i = 0; i < targetCount; i++) {
@ -392,7 +463,7 @@
} }
applyBottomRowDropup(); applyBottomRowDropup();
$('#tickets-table').on('draw.dt', applyBottomRowDropup); $('#add-image-list-table').on('draw.dt', applyBottomRowDropup);
}); });
// ✅ Define your modal function separately // ✅ Define your modal function separately

View File

@ -266,7 +266,7 @@ for ($i = 0; $i < $batch_col_count; $i++) {
?> ?>
<tr> <tr>
<td class="text-center"><b><?php echo ($key + 1) ?></b></td> <td><b><?php echo ($key + 1) ?></b></td>
<td><?php echo $file['batch_code'] ?></td> <td><?php echo $file['batch_code'] ?></td>
<td class="reload batch-file-cell" data-toggle="tooltip" data-placement="top" title="<?php echo htmlspecialchars($file['file_name'] ?? '', ENT_QUOTES, 'UTF-8') ?>"> <td class="reload batch-file-cell" data-toggle="tooltip" data-placement="top" title="<?php echo htmlspecialchars($file['file_name'] ?? '', ENT_QUOTES, 'UTF-8') ?>">
<?php echo $file['file_name']?> <?php echo $file['file_name']?>

View File

@ -45,7 +45,7 @@
?> ?>
<tr> <tr>
<td class="text-center"><b><?php echo ($key + 1) ?></b></td> <td><b><?php echo ($key + 1) ?></b></td>
<td style="overflow: hidden;" class="reload truncate" data-toggle="tooltip" data-placement="top" title="<?php echo $file['file_name'] ?>"> <td style="overflow: hidden;" class="reload truncate" data-toggle="tooltip" data-placement="top" title="<?php echo $file['file_name'] ?>">
<?php echo $file['file_name'] ?> <?php echo $file['file_name'] ?>
</td> </td>

View File

@ -1,3 +1,41 @@
<?php
helper('datatable_view');
$bds_header_labels = [
'S.No', 'Renewal Month', 'Issuer', 'Policy No', 'Policy', 'Insurer Name', 'Insurer Branch', 'Insured', 'Client Type', 'Business Type',
'Date of Issue', 'Policy Start Date', 'Policy Expiry Date', 'Vehicle No', 'Lead Status',
];
$bds_col_count = count($bds_header_labels);
$bds_col_max_len = array_fill(0, $bds_col_count, 0);
for ($i = 0; $i < $bds_col_count; $i++) {
$bds_col_max_len[$i] = mb_strlen($bds_header_labels[$i]);
}
$renewal_data = $renewal_data ?? [];
$issuer = $issuer ?? [];
$client_type = $client_type ?? [];
foreach ($renewal_data as $index => $row) {
$bds_col_max_len[0] = max($bds_col_max_len[0], mb_strlen((string) ($index + 1)));
$rm = empty($row['policy_end_date']) ? ' - ' : date('M-Y', strtotime((string) $row['policy_end_date']));
$bds_col_max_len[1] = max($bds_col_max_len[1], mb_strlen($rm));
$bds_col_max_len[2] = max($bds_col_max_len[2], mb_strlen((string) ($issuer[$row['issuer']] ?? ' - ')));
$bds_col_max_len[3] = max($bds_col_max_len[3], mb_strlen((string) ($row['policy_no'] ?? ' - ')));
$bds_col_max_len[4] = max($bds_col_max_len[4], mb_strlen((string) ($row['policy_type'] ?? ' - ')));
$bds_col_max_len[5] = max($bds_col_max_len[5], mb_strlen((string) ($row['insurer_name'] ?? ' - ')));
$bds_col_max_len[6] = max($bds_col_max_len[6], mb_strlen((string) ($row['insurer_branch_name'] ?? ' - ')));
$bds_col_max_len[7] = max($bds_col_max_len[7], mb_strlen((string) ($row['client_name'] ?? ' - ')));
$bds_col_max_len[8] = max($bds_col_max_len[8], mb_strlen((string) ($client_type[$row['client_type'] ?? ''] ?? '-')));
$bds_col_max_len[9] = max($bds_col_max_len[9], mb_strlen((string) ($row['revenue_type'] ?? ' - ')));
$bds_col_max_len[10] = max($bds_col_max_len[10], mb_strlen(empty($row['policy_issue_date']) ? '' : date('d/m/Y', strtotime((string) $row['policy_issue_date']))));
$bds_col_max_len[11] = max($bds_col_max_len[11], mb_strlen(empty($row['policy_start_date']) ? '' : date('d/m/Y', strtotime((string) $row['policy_start_date']))));
$bds_col_max_len[12] = max($bds_col_max_len[12], mb_strlen(empty($row['policy_end_date']) ? '' : date('d/m/Y', strtotime((string) $row['policy_end_date']))));
$bds_col_max_len[13] = max($bds_col_max_len[13], mb_strlen((string) ($row['vehicle_no'] ?? ' - ')));
$bds_col_max_len[14] = max($bds_col_max_len[14], mb_strlen((string) ucfirst((string) ($row['lead_status'] ?? ' - '))));
}
$bds_col_min_px = array_fill(0, $bds_col_count, 80);
$bds_col_min_px[0] = 48;
$bds_col_max_px = array_fill(0, $bds_col_count, 360);
$bds_col_max_px[0] = 64;
$bds_col_width_px = nhance_dt_column_widths_px($bds_header_labels, $bds_col_max_len, $bds_col_min_px, $bds_col_max_px);
?>
<style> <style>
.table th, .table th,
.table td { .table td {
@ -18,6 +56,38 @@ table.dataTable tbody td {
</style> </style>
<style>
<?php for ($i = 0; $i < $bds_col_count; $i++) : ?>
#bds-renewal-report-list-table_wrapper .dataTables_scrollHead table thead th:nth-child(<?= $i + 1 ?>),
#bds-renewal-report-list-table thead th:nth-child(<?= $i + 1 ?>) {
min-width: <?= (int) $bds_col_width_px[$i] ?>px;
width: <?= (int) $bds_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
overflow: visible !important;
}
#bds-renewal-report-list-table tbody td:nth-child(<?= $i + 1 ?>) {
width: <?= (int) $bds_col_width_px[$i] ?>px;
max-width: <?= (int) $bds_col_width_px[$i] ?>px;
min-width: <?= (int) $bds_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
}
<?php endfor; ?>
#bds-renewal-report-list-table tbody td {
overflow: hidden;
text-overflow: ellipsis;
padding: 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
#bds-renewal-report-list-table thead th {
padding: 5px 2.35rem 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
</style>
<div class="col-12" id="inception_list"> <div class="col-12" id="inception_list">
<div class="card"> <div class="card">
<div class="card-body" style="background-color: #F5FFFF !important; border-radius: 10px; box-shadow: 4px 4px 4px 4px #00000040;"> <div class="card-body" style="background-color: #F5FFFF !important; border-radius: 10px; box-shadow: 4px 4px 4px 4px #00000040;">
@ -28,7 +98,7 @@ table.dataTable tbody td {
</div> --> </div> -->
<div> <div>
<div class="table-responsive"> <div class="table-responsive">
<table data-custom-table-css="table" id="scroll-horizontal-datatable" class="table w-100 nowrap"> <table data-custom-table-css="table" data-nhance-list-dt="1" id="bds-renewal-report-list-table" class="table w-100 nowrap">
<thead class="bg-light"> <thead class="bg-light">
<tr> <tr>
<th> <th>
@ -83,7 +153,7 @@ table.dataTable tbody td {
<?php foreach($renewal_data as $index => $row) { ?> <?php foreach($renewal_data as $index => $row) { ?>
<tr> <tr>
<td><?php echo $index+1; ?></td> <td><?php echo $index+1; ?></td>
<td><?php echo empty($row['policy_end_date']) ? ' - ' : date('M-Y', strtotime($row['policy_end_date'])); ?> <td><?php echo empty($row['policy_end_date']) ? ' - ' : date('M-Y', strtotime($row['policy_end_date'])); ?></td>
<td><?php echo $issuer[$row['issuer']] ?? ' - '; ?></td> <td><?php echo $issuer[$row['issuer']] ?? ' - '; ?></td>
<td><?php echo $row['policy_no'] ?? ' - '; ?></td> <td><?php echo $row['policy_no'] ?? ' - '; ?></td>
<td><?php echo $row['policy_type'] ?? ' - '; ?></td> <td><?php echo $row['policy_type'] ?? ' - '; ?></td>
@ -114,11 +184,11 @@ table.dataTable tbody td {
// Datatable document ready // Datatable document ready
$(document).ready(function() { $(document).ready(function() {
var ticketsTable = $('#scroll-horizontal-datatable'); var ticketsTable = $('#bds-renewal-report-list-table');
if (ticketsTable.length) { if (ticketsTable.length) {
ticketsTable.DataTable({ nhanceListDataTableBeforeInit();
scrollX: true, var nhBdsRenewalTable = ticketsTable.DataTable(nhanceMergeListDataTableOptions({
// dom: "<'row'<'col-sm-2'f><'col-sm-10 text-right'B>>" + // Filter left, buttons right // dom: "<'row'<'col-sm-2'f><'col-sm-10 text-right'B>>" + // Filter left, buttons right
// "<'row'<'col-sm-12'tr>>" + // "<'row'<'col-sm-12'tr>>" +
// "<'row'<'col-sm-5'i><'col-sm-7'p>>", // Pagination at the bottom, without page length selector // "<'row'<'col-sm-5'i><'col-sm-7'p>>", // Pagination at the bottom, without page length selector
@ -163,7 +233,14 @@ $(document).ready(function() {
paging: true, // Enable pagination paging: true, // Enable pagination
pageLength: 20, // Set default number of rows per page (optional) pageLength: 20, // Set default number of rows per page (optional)
ordering: true, ordering: true,
}); columnDefs: [
<?php for ($i = 0; $i < $bds_col_count; $i++) : ?>
{ targets: <?= $i ?>, width: '<?= (int) $bds_col_width_px[$i] ?>px' },
<?php endfor; ?>
],
}));
nhanceListDataTableAfterInit();
nhanceListDataTableBindAdjust(nhBdsRenewalTable);
} else { } else {
console.error("Table atet found."); console.error("Table atet found.");
} }

View File

@ -202,7 +202,7 @@
<?php if (isset($business_list)) { ?> <?php if (isset($business_list)) { ?>
<?php foreach($business_list as $index => $row){ ?> <?php foreach($business_list as $index => $row){ ?>
<tr> <tr>
<td class="text-center"><?= $index + 1 ?></td> <td><?= $index + 1 ?></td>
<td><?php echo $row['client_name']; ?></td> <td><?php echo $row['client_name']; ?></td>
<td><?php echo $row['insurer_name']; ?></td> <td><?php echo $row['insurer_name']; ?></td>
<td><?php echo $row['policy_type']; ?></td> <td><?php echo $row['policy_type']; ?></td>

View File

@ -1,3 +1,34 @@
<?php
helper('datatable_view');
$cdm_header_labels = [
'S.No', 'Client Name', 'Insurer Name', 'Insurer Branch Name', 'Opening Date', 'CD Account No', 'Opening Amount', 'Date/User', 'Action',
];
$cdm_col_count = count($cdm_header_labels);
$cdm_col_max_len = array_fill(0, $cdm_col_count, 0);
for ($i = 0; $i < $cdm_col_count; $i++) {
$cdm_col_max_len[$i] = mb_strlen($cdm_header_labels[$i]);
}
$CD_Master_Data = $CD_Master_Data ?? [];
foreach ($CD_Master_Data as $index => $row) {
$cdm_col_max_len[0] = max($cdm_col_max_len[0], mb_strlen((string) ($index + 1)));
$clientCell = ($row['client_name'] ?? '') . '( ' . ($row['short_name'] ?? '') . ' )';
$cdm_col_max_len[1] = max($cdm_col_max_len[1], mb_strlen($clientCell));
$cdm_col_max_len[2] = max($cdm_col_max_len[2], mb_strlen((string) ($row['insurer_name'] ?? '')));
$cdm_col_max_len[3] = max($cdm_col_max_len[3], mb_strlen((string) ($row['insurer_branch_name'] ?? '')));
$od = ! empty($row['opening_date']) ? date('d-m-Y', strtotime((string) $row['opening_date'])) : '';
$cdm_col_max_len[4] = max($cdm_col_max_len[4], mb_strlen($od));
$cdm_col_max_len[5] = max($cdm_col_max_len[5], mb_strlen((string) ($row['cd_ac_no'] ?? '')));
$cdm_col_max_len[6] = max($cdm_col_max_len[6], mb_strlen((string) ($row['opening_bal'] ?? '')));
$du = ! empty($row['created_at'])
? (date('d-M-Y h:i A', strtotime((string) $row['created_at'])) . ' by ' . ($row['user_name'] ?? ''))
: '';
$cdm_col_max_len[7] = max($cdm_col_max_len[7], mb_strlen($du));
$cdm_col_max_len[8] = max($cdm_col_max_len[8], 4);
}
$cdm_col_min_px = [48, 140, 120, 140, 100, 120, 100, 200, 72];
$cdm_col_max_px = [64, 400, 320, 360, 120, 200, 160, 480, 88];
$cdm_col_width_px = nhance_dt_column_widths_px($cdm_header_labels, $cdm_col_max_len, $cdm_col_min_px, $cdm_col_max_px);
?>
<style> <style>
.col-12 { .col-12 {
@ -13,6 +44,44 @@
</style> </style>
<style>
<?php for ($i = 0; $i < $cdm_col_count; $i++) : ?>
#cd-master-list-table_wrapper .dataTables_scrollHead table thead th:nth-child(<?= $i + 1 ?>),
#cd-master-list-table thead th:nth-child(<?= $i + 1 ?>) {
min-width: <?= (int) $cdm_col_width_px[$i] ?>px;
width: <?= (int) $cdm_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
overflow: visible !important;
}
#cd-master-list-table tbody td:nth-child(<?= $i + 1 ?>) {
width: <?= (int) $cdm_col_width_px[$i] ?>px;
max-width: <?= (int) $cdm_col_width_px[$i] ?>px;
min-width: <?= (int) $cdm_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
}
<?php endfor; ?>
#cd-master-list-table tbody td:not(:last-child) {
overflow: hidden;
text-overflow: ellipsis;
}
#cd-master-list-table tbody td:last-child {
overflow: visible;
text-overflow: clip;
}
#cd-master-list-table tbody td {
padding: 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
#cd-master-list-table thead th {
padding: 5px 2.35rem 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
</style>
<div class="row" id="client_list"> <div class="row" id="client_list">
<div class="col-12"> <div class="col-12">
<div class="card"> <div class="card">
@ -28,7 +97,7 @@
</div> </div>
</div> --> </div> -->
<table data-custom-table-css="table" id="scroll-horizontal-datatable" class="table mb-0 nowrap" cellspacing="0"> <table data-custom-table-css="table" data-nhance-list-dt="1" id="cd-master-list-table" class="table mb-0 nowrap" cellspacing="0">
<thead class="bg-light"> <thead class="bg-light">
<tr> <tr>
<th class="font-weight-medium">S.No&nbsp;</th> <th class="font-weight-medium">S.No&nbsp;</th>
@ -45,7 +114,7 @@
<tbody> <tbody>
<?php foreach($CD_Master_Data as $index => $row){ ?> <?php foreach($CD_Master_Data as $index => $row){ ?>
<tr> <tr>
<td class="text-center"><?= $index + 1; ?></td> <td><?= $index + 1; ?></td>
<td><?php echo $row['client_name']; ?>( <?= $row['short_name'] ?> )</td> <td><?php echo $row['client_name']; ?>( <?= $row['short_name'] ?> )</td>
<td><?php echo $row['insurer_name']; ?></td> <td><?php echo $row['insurer_name']; ?></td>
<td><?php echo $row['insurer_branch_name']; ?></td> <td><?php echo $row['insurer_branch_name']; ?></td>
@ -80,8 +149,8 @@
$(document).ready(function() { $(document).ready(function() {
var table = $('#scroll-horizontal-datatable').DataTable({ nhanceListDataTableBeforeInit();
scrollX: true, var table = $('#cd-master-list-table').DataTable(nhanceMergeListDataTableOptions({
// dom: "<'row'<'col-sm-6'f><'col-sm-6 text-right'B>>" + // dom: "<'row'<'col-sm-6'f><'col-sm-6 text-right'B>>" +
// "<'row'<'col-sm-12'tr>>" + // "<'row'<'col-sm-12'tr>>" +
// "<'row'<'col-sm-5'i><'col-sm-7'p>>", // "<'row'<'col-sm-5'i><'col-sm-7'p>>",
@ -141,7 +210,12 @@
}, },
paging: true, paging: true,
pageLength: 10, pageLength: 10,
order: [[0, 'desc']] order: [[0, 'desc']],
columnDefs: [
<?php for ($i = 0; $i < $cdm_col_count; $i++) : ?>
{ targets: <?= $i ?>, width: '<?= (int) $cdm_col_width_px[$i] ?>px' },
<?php endfor; ?>
],
// scrollX: true, // scrollX: true,
// dom: "<'row'<'col-sm-6'f><'col-sm-6 text-right'B>>" + // dom: "<'row'<'col-sm-6'f><'col-sm-6 text-right'B>>" +
// "<'row'<'col-sm-12'tr>>" + // "<'row'<'col-sm-12'tr>>" +
@ -169,13 +243,15 @@
// searchPlaceholder: "Search..." // searchPlaceholder: "Search..."
// }, // },
// paging: true, // paging: true,
}); }));
nhanceListDataTableAfterInit();
nhanceListDataTableBindAdjust(table);
function applyBottomRowDropup() { function applyBottomRowDropup() {
if (!table) return; if (!table) return;
const currentRows = table.rows({ page: 'current' }).nodes().toArray(); const currentRows = table.rows({ page: 'current' }).nodes().toArray();
$('#scroll-horizontal-datatable tbody tr').removeClass('nh-force-dropup'); $('#cd-master-list-table tbody tr').removeClass('nh-force-dropup');
$('#scroll-horizontal-datatable tbody tr td.table-action-cell .btn-group.dropdown').removeClass('dropup'); $('#cd-master-list-table tbody tr td.table-action-cell .btn-group.dropdown').removeClass('dropup');
const targetCount = Math.min(2, currentRows.length); const targetCount = Math.min(2, currentRows.length);
for (let i = 0; i < targetCount; i++) { for (let i = 0; i < targetCount; i++) {
@ -186,7 +262,7 @@
} }
} }
applyBottomRowDropup(); applyBottomRowDropup();
$('#scroll-horizontal-datatable').on('draw.dt', applyBottomRowDropup); $('#cd-master-list-table').on('draw.dt', applyBottomRowDropup);
}) })
$(document).ready(function(){ $(document).ready(function(){

View File

@ -155,7 +155,7 @@
?> ?>
<tr> <tr>
<td class="text-center"><b><?php echo ($key + 1) ?></b></td> <td><b><?php echo ($key + 1) ?></b></td>
<td><?php echo $file['client_name'] ?></td> <td><?php echo $file['client_name'] ?></td>
<td><?php echo $file['policy_no'] ?></td> <td><?php echo $file['policy_no'] ?></td>
<td style="overflow: hidden;" class="reload truncate" data-toggle="tooltip" data-placement="top" title="<?php echo $file['file_name'] ?>"> <td style="overflow: hidden;" class="reload truncate" data-toggle="tooltip" data-placement="top" title="<?php echo $file['file_name'] ?>">

View File

@ -46,7 +46,7 @@
?> ?>
<tr> <tr>
<td class="text-center"><b><?php echo ($key + 1) ?></b></td> <td><b><?php echo ($key + 1) ?></b></td>
<td class="text-center"><?php echo $file['file_name'] ?></td> <td class="text-center"><?php echo $file['file_name'] ?></td>
<td><?php echo change_date_format($file['created_at'],'Y-m-d H:i:s', 'd M Y h:i a') . ' by <strong>' . $file['user_name'] . '</strong>' ?> <td><?php echo change_date_format($file['created_at'],'Y-m-d H:i:s', 'd M Y h:i a') . ' by <strong>' . $file['user_name'] . '</strong>' ?>
<td> <td>

View File

@ -106,6 +106,58 @@ input:checked + .slider:before {
.slider.round:before { .slider.round:before {
border-radius: 50%; border-radius: 50%;
} }
.hr-processed-options {
display: inline-flex;
align-items: center;
justify-content: flex-start;
gap: 1.25rem;
flex-wrap: nowrap;
white-space: nowrap;
width: auto;
max-width: 100%;
}
.hr-processed-option {
display: inline-flex;
align-items: center;
justify-content: flex-start;
flex: 0 0 auto;
width: auto;
margin: 0;
}
.hr-radio-input {
appearance: auto;
-webkit-appearance: radio;
width: 14px;
height: 14px;
margin-top: 0;
margin-right: 0.35rem;
margin-left: 0;
position: static;
float: none;
vertical-align: middle;
}
.hr-radio-label {
display: inline-block;
width: auto;
margin: 0;
white-space: nowrap;
line-height: 1.2;
}
#hr_file_processed_by_error_container {
display: block;
width: 100%;
margin-top: 0.25rem;
clear: both;
}
#hr_file_processed_by_error_container .parsley-errors-list {
margin-bottom: 0;
}
</style> </style>
<div class="tab-pane fade active show" id="general-q-tab"> <div class="tab-pane fade active show" id="general-q-tab">
@ -170,8 +222,10 @@ input:checked + .slider:before {
id="client_logo" name="client_logo" id="client_logo" name="client_logo"
accept="image/jpeg, image/jpg, image/png" accept="image/jpeg, image/jpg, image/png"
onchange="PreviewImage0(event);" onchange="PreviewImage0(event);"
data-parsley-max-file-size="200" data-parsley-client-max-file-size="200"
data-parsley-file-extension="jpg,jpeg,png" data-parsley-client-file-extension="jpg,jpeg,png"
data-parsley-client-max-file-size-message="Maximum file size allowed is 200KB."
data-parsley-client-file-extension-message="Only JPG, JPEG, PNG files are allowed."
data-parsley-errors-container="#client_logo_error_container" data-parsley-errors-container="#client_logo_error_container"
/> />
</div> </div>
@ -198,25 +252,29 @@ input:checked + .slider:before {
<div class="form-group col-md-4"> <div class="form-group col-md-4">
<label for="client_name">Client Name<span <label for="client_name">Client Name<span
class="text-danger">*</span></label> class="text-danger">*</span></label>
<input type="text" class="form-control" id="client_name" data-old-name="<?= isset($client['client_name']) ? $client['client_name'] : '' ?>" <input type="text" class="form-control" id="client_name"
placeholder="Enter Client Name" value="<?= isset($client['client_name']) ? $client['client_name'] : '' ?>" name="client_name" data-old-name="<?= isset($client['client_name']) ? $client['client_name'] : '' ?>"
required maxlength="255" data-parsley-maxlength="255"> placeholder="Enter Client Name"
value="<?= isset($client['client_name']) ? $client['client_name'] : '' ?>" name="client_name"
required maxlength="45" data-parsley-minlength="2" data-parsley-maxlength="45"
data-parsley-pattern="^[a-zA-Z0-9\\s_-]+$"
data-parsley-pattern-message="Only letters, numbers, spaces, underscore (_) and hyphen (-) are allowed.">
</div> </div>
<div class="form-group col-md-4"> <div class="form-group col-md-4">
<label for="short_name">Client Short Name<span <label for="short_name">Client Short Name<span
class="text-danger">*</span></label> class="text-danger">*</span></label>
<input type="text" class="form-control" id="short_name" <input type="text" class="form-control" id="short_name" data-parsley-minlength="2"
maxlength="100" data-parsley-maxlength="100" data-parsley-maxlength="15" data-parsley-pattern="/^[a-zA-Z0-9_\- ]+$/"
data-old-short="<?= isset($client['short_name']) ? $client['short_name'] : '' ?>" data-old-short="<?= isset($client['short_name']) ? $client['short_name'] : '' ?>" placeholder="Enter Short Name"
placeholder="Enter Short Name" value="<?= isset($client['short_name']) ? $client['short_name'] : '' ?>" name="short_name" onkeyup="validateInput(this, 'clients', 'short_name', 'clientBtnSubmit')" required> value="<?= isset($client['short_name']) ? $client['short_name'] : '' ?>" name="short_name" onkeyup="validateInput(this, 'clients', 'short_name', 'clientBtnSubmit')" required>
</div> </div>
</div> </div>
<div class="form-row"> <div class="form-row">
<div class="form-group col-md-4"> <div class="form-group col-md-4">
<label for="pan">PAN<span class="text-danger"></span></label> <label for="pan">PAN<span class="text-danger"></span></label>
<input type="text" class="form-control" id="pan" placeholder="Enter PAN Number" data-parsley-error-message="Invalid PAN Number. Example: ABCDE1234F" value="<?= isset($client['pan']) ? $client['pan'] : '' ?>" name="pan" <input type="text" class="form-control" id="pan" placeholder="Enter PAN Number" data-parsley-error-message="Invalid PAN Number. Example: ABCDE1234F" value="<?= isset($client['pan']) ? $client['pan'] : '' ?>" name="pan"
maxlength="10" data-parsley-maxlength="10" data-parsley-trigger="change" data-parsley-pattern="^[A-Z]{5}[0-9]{4}[A-Z]$"> maxlength="10" data-parsley-maxlength="10" data-parsley-trigger="keyup" data-parsley-pattern="^[A-Z]{5}[0-9]{4}[A-Z]$">
</div> </div>
<!-- <div class="form-group col-md-4"> <!-- <div class="form-group col-md-4">
<label for="gst">GST<span class="text-danger">*</span></label> <label for="gst">GST<span class="text-danger">*</span></label>
@ -236,26 +294,33 @@ input:checked + .slider:before {
<div class="form-group col-md-4"> <div class="form-group col-md-4">
<label>HR File Processed By <span class="text-danger">*</span></label> <label>HR File Processed By <span class="text-danger">*</span></label>
<div class="d-flex align-items-center"> <div class="hr-processed-options">
<div class="form-check form-check-inline mb-0" style="margin-right: -356px;"> <div class="hr-processed-option">
<input class="form-check-input" <input class="hr-radio-input"
type="radio" type="radio"
name="hr_file_processed_by" name="hr_file_processed_by"
id="hr_processed" id="hr_processed"
value="1" required <?php echo(isset($client['hr_file_processed_by']) && $client['hr_file_processed_by'] == 1) ? 'checked' : '' ?>> value="1"
<label class="form-check-label" for="hr_processed">HR</label> required
data-parsley-trigger="change"
data-parsley-errors-container="#hr_file_processed_by_error_container"
<?php echo(isset($client['hr_file_processed_by']) && $client['hr_file_processed_by'] == 1) ? 'checked' : '' ?>>
<label class="hr-radio-label" for="hr_processed">HR</label>
</div> </div>
<div class="form-check form-check-inline mb-0"> <div class="hr-processed-option">
<input class="form-check-input" <input class="hr-radio-input"
type="radio" type="radio"
name="hr_file_processed_by" name="hr_file_processed_by"
id="account_manager_processed" id="account_manager_processed"
value="2" value="2"
<?php echo(isset($client['hr_file_processed_by']) && $client['hr_file_processed_by'] == 2) ? 'checked' : '' ?>> data-parsley-trigger="change"
<label class="form-check-label" for="account_manager_processed">Account Manager</label> data-parsley-errors-container="#hr_file_processed_by_error_container"
<?php echo(isset($client['hr_file_processed_by']) && $client['hr_file_processed_by'] == 2) ? 'checked' : '' ?>>
<label class="hr-radio-label" for="account_manager_processed">Account Manager</label>
</div> </div>
</div> </div>
<div id="hr_file_processed_by_error_container"></div>
</div> </div>
@ -342,6 +407,31 @@ input:checked + .slider:before {
var form_action = ''; var form_action = '';
$(document).ready(function() { $(document).ready(function() {
if (window.Parsley) {
Parsley.addValidator('clientMaxFileSize', {
requirementType: 'integer',
validateString: function(_value, maxSizeKb, parsleyInstance) {
const files = parsleyInstance.element.files;
if (!files || !files.length) return true;
return (files[0].size / 1024) <= maxSizeKb;
}
});
Parsley.addValidator('clientFileExtension', {
requirementType: 'string',
validateString: function(_value, allowedExtensions, parsleyInstance) {
const files = parsleyInstance.element.files;
if (!files || !files.length) return true;
const allowed = allowedExtensions.split(',').map(function(ext) {
return ext.trim().toLowerCase();
});
const fileName = files[0].name || '';
const extension = fileName.split('.').pop().toLowerCase();
return allowed.indexOf(extension) !== -1;
}
});
}
$('#client_logo').change(function() { $('#client_logo').change(function() {
validateFile(this); validateFile(this);
return; return;
@ -365,6 +455,9 @@ input:checked + .slider:before {
}); });
$(document).ready(function () { $(document).ready(function () {
$('#general_form').parsley({
trigger: 'input'
});
$("#general_form").submit(function(event) { $("#general_form").submit(function(event) {
@ -574,7 +667,7 @@ input:checked + .slider:before {
// For example, you can display the image // For example, you can display the image
const reader = new FileReader(); const reader = new FileReader();
reader.onload = function(e) { reader.onload = function(e) {
$("#uploadPreview").attr("src", e.target.result); $("#uploadPreview0").attr("src", e.target.result);
}; };
reader.readAsDataURL(file); reader.readAsDataURL(file);
} }
@ -585,7 +678,9 @@ input:checked + .slider:before {
// Helper function to clear the preview and the file input // Helper function to clear the preview and the file input
function resetImageInput(input) { function resetImageInput(input) {
input.value = ""; // This clears the file so it won't be submitted input.value = ""; // This clears the file so it won't be submitted
$("#uploadPreview").attr("src", "<?= base_url()?>/public/assets/images/avatar_2x.png"); $("#uploadPreview0").attr("src", "<?= base_url()?>/public/assets/images/avatar_2x.png");
$("#fileNameText0").text("( Upload Your Logo )");
$("#client_logo_error_container").empty();
} }
</script> </script>

View File

@ -171,12 +171,16 @@ input:checked + .slider-branch-contact:before {
<div class="form-group col-md-6"> <div class="form-group col-md-6">
<label for="branch_name">Branch Name<span class="text-danger">*</span></label> <label for="branch_name">Branch Name<span class="text-danger">*</span></label>
<input type="text" class="form-control" id="branch_name" placeholder="Enter Branch Name" <input type="text" class="form-control" id="branch_name" placeholder="Enter Branch Name"
name="branch_name" required> name="branch_name" required data-parsley-minlength="3"
data-parsley-pattern="^[a-zA-Z0-9\\s_-]+$"
data-parsley-pattern-message="Branch Name can contain letters, numbers, spaces, underscore (_) and hyphen (-).">
</div> </div>
<div class="form-group col-md-6"> <div class="form-group col-md-6">
<label for="branch_code">Branch Code<span class="text-danger">*</span></label> <label for="branch_code">Branch Code<span class="text-danger">*</span></label>
<input type="text" class="form-control" id="branch_code" placeholder="Enter Branch Code" <input type="text" class="form-control" id="branch_code" placeholder="Enter Branch Code"
name="branch_code" onchange="setDefaultUnitValue(this)" required> name="branch_code" onchange="setDefaultUnitValue(this)" required
data-parsley-pattern="^[a-zA-Z0-9_-]+$"
data-parsley-pattern-message="Branch Code can contain letters, numbers, underscore (_) and hyphen (-).">
</div> </div>
</div> </div>
@ -204,23 +208,29 @@ input:checked + .slider-branch-contact:before {
<div class="form-group col-md-3"> <div class="form-group col-md-3">
<label for="district">District<span class="text-danger">*</span></label> <label for="district">District<span class="text-danger">*</span></label>
<input type="text" class="form-control" id="district" placeholder="Enter District" <input type="text" class="form-control" id="district" placeholder="Enter District"
name="district" required> name="district" required
data-parsley-pattern="^[a-zA-Z0-9\\s-]+$"
data-parsley-pattern-message="District can contain letters, numbers, spaces, and hyphens.">
</div> </div>
<div class="form-group col-md-3"> <div class="form-group col-md-3">
<label for="city">City<span class="text-danger">*</span></label> <label for="city">City<span class="text-danger">*</span></label>
<input type="text" class="form-control" id="branch_city" placeholder="Enter City" <input type="text" class="form-control" id="branch_city" placeholder="Enter City"
name="city" required> name="city" required
data-parsley-pattern="^[a-zA-Z0-9\\s-]+$"
data-parsley-pattern-message="City can contain letters, numbers, spaces, and hyphens.">
</div> </div>
<div class="form-group col-md-3"> <div class="form-group col-md-3">
<label for="gst">Pincode<span class="text-danger">*</span></label> <label for="gst">Pincode<span class="text-danger">*</span></label>
<input type="text" class="form-control" id="pincode" placeholder="Enter Pincode" name="pincode" required> <input type="text" class="form-control" id="pincode" placeholder="Enter Pincode" name="pincode"
maxlength="6" required data-parsley-pattern="^[0-9]{6}$"
data-parsley-pattern-message="Pincode must be exactly 6 digits.">
</div> </div>
</div> </div>
<div class="form-row"> <div class="form-row">
<div class="form-group col-md-4"> <div class="form-group col-md-4">
<label for="gst">GST<span class="text-danger">*</span></label> <label for="gst">GST<span class="text-danger">*</span></label>
<input type="text" name="gst" class="form-control" id="gst" placeholder="Enter GST Number" data-parsley-error-message="Invalid GST Number. Example: 12ABCDE1234F5Z6" data-parsley-trigger="change" data-parsley-pattern="^\d{2}[A-Z]{5}\d{4}[A-Z]{1}[A-Z\d]{1}[Z]{1}[A-Z\d]{1}$" required> <input type="text" name="gst" class="form-control" id="gst" placeholder="Enter GST Number" data-parsley-error-message="Invalid GST Number format." data-parsley-trigger="change" data-parsley-pattern="^\d{2}[A-Z]{5}\d{4}[A-Z]{1}[A-Z\d]{1}Z[A-Z\d]{1}$" required>
</div> </div>
<div class="form-group col-md-4"> <div class="form-group col-md-4">
<label for="state">Units<span class="text-danger"></span></label> <label for="state">Units<span class="text-danger"></span></label>
@ -252,13 +262,17 @@ input:checked + .slider-branch-contact:before {
<div class="form-group col-md-6"> <div class="form-group col-md-6">
<label for="first_name">Name<span class="text-danger">*</span></label> <label for="first_name">Name<span class="text-danger">*</span></label>
<input value="" type="text" class="form-control" placeholder="Enter Contact Name" <input value="" type="text" class="form-control" placeholder="Enter Contact Name"
name="name[]" id="name" required> name="name[]" id="name" required
data-parsley-pattern="^[A-Za-z\\s]+$"
data-parsley-pattern-message="Contact name may contain only letters and spaces.">
</div> </div>
<div class="form-group col-md-6"> <div class="form-group col-md-6">
<label for="designation">Designation<span class="text-danger">*</span></label> <label for="designation">Designation<span class="text-danger">*</span></label>
<input value="" type="text" class="form-control" placeholder="Enter Designation Name" <input value="" type="text" class="form-control" placeholder="Enter Designation Name"
name="designation[]" id="designation" required name="designation[]" id="designation" required
pattern="[A-Za-z0-9\-_/ ]+" pattern="[A-Za-z0-9\-_/ ]+"
data-parsley-pattern="^[A-Za-z0-9\\-_\\/ ]+$"
data-parsley-pattern-message="Designation may only contain letters, numbers, /, -, _ and spaces."
oninput="this.value = this.value.replace(/[^A-Za-z0-9\-_\/ ]/g, '')" oninput="this.value = this.value.replace(/[^A-Za-z0-9\-_\/ ]/g, '')"
title="Designation may only contain letters, numbers, /, -, _ and spaces only allowed"> title="Designation may only contain letters, numbers, /, -, _ and spaces only allowed">
</div> </div>
@ -267,7 +281,10 @@ input:checked + .slider-branch-contact:before {
<div class="form-group col-md-6"> <div class="form-group col-md-6">
<label for="last_name">Email<span class="text-danger">*</span></label> <label for="last_name">Email<span class="text-danger">*</span></label>
<input value="" type="text" class="form-control" placeholder="Enter Contact Email" <input value="" type="text" class="form-control" placeholder="Enter Contact Email"
name="email[]" id="email" data-parsley-trigger="change" data-parsley-type="email" onchange="validateDuplicateByClientBranch(this, 'email','branchBtnSubmit')" required> name="email[]" id="email" data-parsley-trigger="change"
data-parsley-pattern="^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
data-parsley-pattern-message="Please enter a valid email format (e.g., name@domain.com)."
onchange="validateDuplicateByClientBranch(this, 'email','branchBtnSubmit')" required>
</div> </div>
<div class="form-group col-md-6"> <div class="form-group col-md-6">
<label for="mobile">Mobile<span class="text-danger">*</span></label> <label for="mobile">Mobile<span class="text-danger">*</span></label>
@ -275,8 +292,9 @@ input:checked + .slider-branch-contact:before {
name="mobile[]" id="mobile" name="mobile[]" id="mobile"
onchange="validateDuplicateByClientBranch(this, 'mobile','branchBtnSubmit')" onchange="validateDuplicateByClientBranch(this, 'mobile','branchBtnSubmit')"
onkeypress="return onlyNumbers(event)" maxlength="10" minlength="10" onkeypress="return onlyNumbers(event)" maxlength="10" minlength="10"
data-parsley-type-message="Please enter a valid 10-digit mobile number." data-parsley-pattern="^[0-9]{10}$"
data-parsley-required-message="Please enter a valid 10-digit mobile number." data-parsley-pattern-message="Mobile number must be exactly 10 digits."
data-parsley-required-message="Mobile number must be exactly 10 digits."
required> required>
</div> </div>
</div> </div>
@ -752,12 +770,16 @@ function appendContactHtml(contact = false, reset = false) {
<input type="hidden" name="branch_table_pk[]" id="${uniqueId}_branch_table_pk" value="${contact !== undefined && contact !== false ? contact.id : ''}"> <input type="hidden" name="branch_table_pk[]" id="${uniqueId}_branch_table_pk" value="${contact !== undefined && contact !== false ? contact.id : ''}">
<div class="form-group col-md-6"> <div class="form-group col-md-6">
<label for="${uniqueId}_first_name">Name<span class="text-danger">*</span></label> <label for="${uniqueId}_first_name">Name<span class="text-danger">*</span></label>
<input value="${contact !== undefined && contact !== false ? contact.name : ''}" type="text" class="form-control" placeholder="Enter Contact Name" name="name[]" id="${uniqueId}_name" required> <input value="${contact !== undefined && contact !== false ? contact.name : ''}" type="text" class="form-control" placeholder="Enter Contact Name" name="name[]" id="${uniqueId}_name" required
data-parsley-pattern="^[A-Za-z\\s]+$"
data-parsley-pattern-message="Contact name may contain only letters and spaces.">
</div> </div>
<div class="form-group col-md-6"> <div class="form-group col-md-6">
<label for="${uniqueId}_designation">Designation<span class="text-danger">*</span></label> <label for="${uniqueId}_designation">Designation<span class="text-danger">*</span></label>
<input value="${contact !== undefined && contact !== false ? contact.designation : ''}" type="text" class="form-control" placeholder="Enter Designation Name" name="designation[]" id="${uniqueId}_designation" required <input value="${contact !== undefined && contact !== false ? contact.designation : ''}" type="text" class="form-control" placeholder="Enter Designation Name" name="designation[]" id="${uniqueId}_designation" required
pattern="[A-Za-z0-9\-_/ ]+" pattern="[A-Za-z0-9\-_/ ]+"
data-parsley-pattern="^[A-Za-z0-9\\-_\\/ ]+$"
data-parsley-pattern-message="Designation may only contain letters, numbers, /, -, _ and spaces."
oninput="this.value = this.value.replace(/[^A-Za-z0-9\-_\/ ]/g, '')" oninput="this.value = this.value.replace(/[^A-Za-z0-9\-_\/ ]/g, '')"
title="Designation may only contain letters, numbers, /, -, _ and spaces only allowed"> title="Designation may only contain letters, numbers, /, -, _ and spaces only allowed">
</div> </div>
@ -765,11 +787,11 @@ function appendContactHtml(contact = false, reset = false) {
<div class="form-row"> <div class="form-row">
<div class="form-group col-md-6"> <div class="form-group col-md-6">
<label for="${uniqueId}_last_name">Email<span class="text-danger">*</span></label> <label for="${uniqueId}_last_name">Email<span class="text-danger">*</span></label>
<input value="${contact !== undefined && contact !== false ? contact.email : ''}" type="text" class="form-control" placeholder="Enter Contact Email" name="email[]" id="${uniqueId}_email" data-parsley-trigger="change" data-parsley-type="email" onchange="validateDuplicateByClientBranch(this, 'email', 'branchBtnSubmit')" required> <input value="${contact !== undefined && contact !== false ? contact.email : ''}" type="text" class="form-control" placeholder="Enter Contact Email" name="email[]" id="${uniqueId}_email" data-parsley-trigger="change" data-parsley-pattern="^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$" data-parsley-pattern-message="Please enter a valid email format (e.g., name@domain.com)." onchange="validateDuplicateByClientBranch(this, 'email', 'branchBtnSubmit')" required>
</div> </div>
<div class="form-group col-md-6"> <div class="form-group col-md-6">
<label for="${uniqueId}_mobile">Mobile<span class="text-danger">*</span></label> <label for="${uniqueId}_mobile">Mobile<span class="text-danger">*</span></label>
<input value="${contact !== undefined && contact !== false ? contact.mobile : ''}" type="text" class="form-control" placeholder="Enter Contact Mobile" name="mobile[]" id="${uniqueId}_mobile" onchange="validateDuplicateByClientBranch(this, 'mobile', 'branchBtnSubmit')" onkeypress = "return onlyNumbers(event)" maxlength="10" min="10" data-parsley-type-message="Please enter a valid 10-digit mobile number." data-parsley-required-message="Please enter a valid 10-digit mobile number." required> <input value="${contact !== undefined && contact !== false ? contact.mobile : ''}" type="text" class="form-control" placeholder="Enter Contact Mobile" name="mobile[]" id="${uniqueId}_mobile" onchange="validateDuplicateByClientBranch(this, 'mobile', 'branchBtnSubmit')" onkeypress = "return onlyNumbers(event)" maxlength="10" minlength="10" data-parsley-pattern="^[0-9]{10}$" data-parsley-pattern-message="Mobile number must be exactly 10 digits." data-parsley-required-message="Mobile number must be exactly 10 digits." required>
</div> </div>
</div> </div>
<div class="form-group" style="display: flex;"> <div class="form-group" style="display: flex;">

View File

@ -1,3 +1,85 @@
<?php
helper('datatable_view');
$cd_header_labels = ['Insurer Name', 'Insurer Branch Name', 'CD Account Number', 'Current Balance', 'Action'];
$cd_col_count = count($cd_header_labels);
$cd_col_max_len = array_fill(0, $cd_col_count, 0);
for ($i = 0; $i < $cd_col_count; $i++) {
$cd_col_max_len[$i] = mb_strlen($cd_header_labels[$i]);
}
$balances = $balances ?? [];
$clientData = $clientData ?? [];
foreach ($clientData as $value) {
$cd_col_max_len[0] = max($cd_col_max_len[0], mb_strlen((string) ($value->insurer_name ?? '')));
$cd_col_max_len[1] = max($cd_col_max_len[1], mb_strlen((string) ($value->insurer_branch_name ?? '')));
$cd_col_max_len[2] = max($cd_col_max_len[2], mb_strlen((string) ($value->cd_master_account_no ?? '')));
$insurerId = $value->insurer_id;
$cd_ac_pk = $value->cd_ac_pk;
$balStr = 'N/A';
if (isset($balances[$insurerId . '-' . $cd_ac_pk])) {
$balStr = (string) ($balances[$insurerId . '-' . $cd_ac_pk]->balance ?? '');
}
$balDisplay = '₹ ' . $balStr;
$cd_col_max_len[3] = max($cd_col_max_len[3], mb_strlen($balDisplay));
$cd_col_max_len[4] = max($cd_col_max_len[4], mb_strlen('View Deposit'));
}
$cd_col_min_px = [100, 120, 120, 100, 120];
$cd_col_max_px = [240, 280, 280, 200, 160];
$cd_col_width_px = nhance_dt_column_widths_px($cd_header_labels, $cd_col_max_len, $cd_col_min_px, $cd_col_max_px);
?>
<style>
<?php for ($i = 0; $i < $cd_col_count; $i++) : ?>
#client-deposit-list-table_wrapper .dataTables_scrollHead table thead th:nth-child(<?= $i + 1 ?>),
#client-deposit-list-table thead th:nth-child(<?= $i + 1 ?>) {
min-width: <?= (int) $cd_col_width_px[$i] ?>px;
width: <?= (int) $cd_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
overflow: visible !important;
}
#client-deposit-list-table tbody td:nth-child(<?= $i + 1 ?>) {
width: <?= (int) $cd_col_width_px[$i] ?>px;
max-width: <?= (int) $cd_col_width_px[$i] ?>px;
min-width: <?= (int) $cd_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
}
<?php endfor; ?>
#client-deposit-list-table tbody td:nth-child(1),
#client-deposit-list-table tbody td:nth-child(2),
#client-deposit-list-table tbody td:nth-child(3),
#client-deposit-list-table tbody td:nth-child(4) {
overflow: hidden;
text-overflow: ellipsis;
}
#client-deposit-list-table tbody td:nth-child(5) {
overflow: visible;
text-overflow: clip;
white-space: nowrap;
text-align: center;
}
#client-deposit-list-table .view-deposit-link {
display: inline-flex;
align-items: center;
gap: 0.35rem;
padding: 0.25rem 0.5rem;
border-radius: 0.25rem;
text-decoration: none;
}
#client-deposit-list-table .view-deposit-link:hover {
background-color: #f5f7fa;
}
#client-deposit-list-table tbody td {
padding: 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
#client-deposit-list-table_wrapper .dataTables_scrollHead table thead th,
#client-deposit-list-table thead th {
padding: 5px 2.35rem 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
</style>
<script> <script>
var pageHideMainNavTitle = true; var pageHideMainNavTitle = true;
var pageTitle = 'Client Deposit - <?= $clientName[0]["client_name"]; ?>'; var pageTitle = 'Client Deposit - <?= $clientName[0]["client_name"]; ?>';
@ -22,7 +104,7 @@
</div> -> </div> ->
</div> --> </div> -->
<div class="table-responsive"> <div class="table-responsive">
<table data-custom-table-css="table" class="table mb-0 nowrap w-100 table-centered" cellspacing="0" id="tickets-table"> <table data-custom-table-css="table" class="table mb-0 nowrap w-100 table-centered" cellspacing="0" id="client-deposit-list-table">
<thead class="bg-light"> <thead class="bg-light">
<tr> <tr>
<th class="font-weight-medium">Insurer Name&nbsp;</th> <th class="font-weight-medium">Insurer Name&nbsp;</th>
@ -54,9 +136,9 @@
?> ?>
</td> </td>
<td> <td>
<a class="dropdown-item" <a class="view-deposit-link"
href="<?= base_url("client/view_deposit/{$value->insurer_id}?client_id={$value->client_id}&cd_ac_pk={$value->cd_ac_pk}"); ?>"> href="<?= base_url("client/view_deposit/{$value->insurer_id}?client_id={$value->client_id}&cd_ac_pk={$value->cd_ac_pk}"); ?>">
<i class="mdi mdi-eye mr-2 text-muted font-18 vertical-middle"></i>View Deposit <i class="mdi mdi-eye text-muted font-18 vertical-middle"></i><span>View Deposit</span>
</a> </a>
</td> </td>
</tr> </tr>
@ -73,7 +155,8 @@
<script> <script>
$(document).ready(function() { $(document).ready(function() {
$('#tickets-table').DataTable({ nhanceListDataTableBeforeInit();
var nhDepositTable = $('#client-deposit-list-table').DataTable(nhanceMergeListDataTableOptions({
// dom: "<'row'<'col-sm-0'f><'col-sm-9 text-right'B>>", // dom: "<'row'<'col-sm-0'f><'col-sm-9 text-right'B>>",
dom: "<'row'<'col-12 d-flex justify-content-between align-items-center'<'datatable-search dataTables_filter'f><'datatable-buttons dt-buttons'B>>>" + dom: "<'row'<'col-12 d-flex justify-content-between align-items-center'<'datatable-search dataTables_filter'f><'datatable-buttons dt-buttons'B>>>" +
"<'row'<'col-sm-12'tr>>" + "<'row'<'col-sm-12'tr>>" +
@ -118,8 +201,15 @@ $(document).ready(function() {
searchPlaceholder: "Search", searchPlaceholder: "Search",
emptyTable: '<div class="text-center text-muted">No Data found</div>' emptyTable: '<div class="text-center text-muted">No Data found</div>'
}, },
columnDefs: [
<?php for ($i = 0; $i < $cd_col_count; $i++) : ?>
{ targets: <?= $i ?>, width: '<?= (int) $cd_col_width_px[$i] ?>px' },
<?php endfor; ?>
],
}); }));
nhanceListDataTableAfterInit();
nhanceListDataTableBindAdjust(nhDepositTable);
$('.dataTables_length label').css('height', '21px'); $('.dataTables_length label').css('height', '21px');
}) })

View File

@ -43,11 +43,13 @@
<div class="form-row additional-doc-row" data-row-index="0"> <div class="form-row additional-doc-row" data-row-index="0">
<div class="form-group col-md-4"> <div class="form-group col-md-4">
<label>Document Name<span class="text-danger">*</span></label> <label>Document Name<span class="text-danger">*</span></label>
<input type="text" class="form-control other-doc-name-field" placeholder="Document Name" name="other_docs_name[]" data-parsley-inceptioncharset="true" data-parsley-trigger="input change" required> <input type="text" class="form-control other-doc-name-field" placeholder="Document Name" name="other_docs_name[]" data-parsley-inceptioncharset="true" data-parsley-trigger="input change" data-parsley-pattern="^[a-zA-Z0-9\\s_-]+$" data-parsley-pattern-message="Only letters, numbers, spaces, underscore (_) and hyphen (-) are allowed." required>
</div> </div>
<div class="form-group col-md-4"> <div class="form-group col-md-4">
<label>File<span class="text-danger">*</span></label> <label>File<span class="text-danger">*</span></label>
<input class="form-control other-doc-file-field" type="file" name="file_name[]" required accept=".pdf, .jpeg, .jpg, .png"> <input class="form-control other-doc-file-field" type="file" name="file_name[]" required accept=".pdf, .jpeg, .jpg, .png">
<small class="mt-1 text-muted d-block">Allowed: PDF, JPG, JPEG, PNG. Size : 200KB/image 25MB/PDF</small>
<div class="other-doc-file-error text-danger small mt-1"></div>
</div> </div>
<div class="form-group col-md-4" style="<?= isset($client['id']) ? 'margin-top: 41px;' : 'margin-top: 30px;' ?>"> <div class="form-group col-md-4" style="<?= isset($client['id']) ? 'margin-top: 41px;' : 'margin-top: 30px;' ?>">
<button type="button" class="btn btn-outline-danger remove-additional-doc-row" style="display:none;">Remove</button> <button type="button" class="btn btn-outline-danger remove-additional-doc-row" style="display:none;">Remove</button>
@ -96,17 +98,79 @@
<script> <script>
var kycPrimaryKey = $('#client_id_kyc').val(); var kycPrimaryKey = $('#client_id_kyc').val();
var allowedExtensions = ['pdf', 'png', 'jpeg', 'jpg'];
var maxImageSizeInBytes = 200 * 1024;
var maxPdfSizeInBytes = 25 * 1024 * 1024;
function resetOtherDocFileField($field) {
$field.val('');
}
function validateOtherDocFileField($field, showToastr) {
var $row = $field.closest('.additional-doc-row');
var $scope = $row.length ? $row : $field.closest('form');
var $error = $scope.find('.other-doc-file-error, .kyc-primary-file-error').first();
var file = $field[0].files && $field[0].files[0];
if ($error.length) {
$error.text('');
}
$field.removeClass('is-invalid');
if (!file) {
return true;
}
var fileName = file.name || '';
var fileExtension = fileName.split('.').pop().toLowerCase();
var sizeErrorMessage = '';
if (allowedExtensions.indexOf(fileExtension) === -1) {
var typeMessage = 'Only PDF, JPG, JPEG, PNG files are allowed.';
if ($error.length) {
$error.text(typeMessage);
}
$field.addClass('is-invalid');
resetOtherDocFileField($field);
if (showToastr) {
toastr.warning(typeMessage, 'Invalid file type');
}
return false;
}
if (fileExtension === 'pdf' && file.size > maxPdfSizeInBytes) {
sizeErrorMessage = 'PDF size should be up to 25MB.';
} else if (['png', 'jpg', 'jpeg'].indexOf(fileExtension) !== -1 && file.size > maxImageSizeInBytes) {
sizeErrorMessage = 'Image size should be up to 200KB.';
}
if (sizeErrorMessage) {
if ($error.length) {
$error.text(sizeErrorMessage);
}
$field.addClass('is-invalid');
resetOtherDocFileField($field);
if (showToastr) {
toastr.warning(sizeErrorMessage, 'Invalid file size');
}
return false;
}
return true;
}
function getAdditionalDocRowTemplate(index) { function getAdditionalDocRowTemplate(index) {
return ` return `
<div class="form-row additional-doc-row" data-row-index="${index}"> <div class="form-row additional-doc-row" data-row-index="${index}">
<div class="form-group col-md-4"> <div class="form-group col-md-4">
<label>Document Name<span class="text-danger">*</span></label> <label>Document Name<span class="text-danger">*</span></label>
<input type="text" class="form-control other-doc-name-field" placeholder="Document Name" name="other_docs_name[]" data-parsley-inceptioncharset="true" data-parsley-trigger="input change" required> <input type="text" class="form-control other-doc-name-field" placeholder="Document Name" name="other_docs_name[]" data-parsley-inceptioncharset="true" data-parsley-trigger="input change" data-parsley-pattern="^[a-zA-Z0-9\\s_-]+$" data-parsley-pattern-message="Only letters, numbers, spaces, underscore (_) and hyphen (-) are allowed." required>
</div> </div>
<div class="form-group col-md-4"> <div class="form-group col-md-4">
<label>File<span class="text-danger">*</span></label> <label>File<span class="text-danger">*</span></label>
<input class="form-control other-doc-file-field" type="file" name="file_name[]" required accept=".pdf, .jpeg, .jpg, .png"> <input class="form-control other-doc-file-field" type="file" name="file_name[]" required accept=".pdf, .jpeg, .jpg, .png">
<small class="mt-1 text-muted d-block">Allowed: PDF, JPG, JPEG, PNG. Size : 200KB/image 25MB/PDF</small>
<div class="other-doc-file-error text-danger small mt-1"></div>
</div> </div>
<div class="form-group col-md-4" style="<?= isset($client['id']) ? 'margin-top: 41px;' : 'margin-top: 30px;' ?>"> <div class="form-group col-md-4" style="<?= isset($client['id']) ? 'margin-top: 41px;' : 'margin-top: 30px;' ?>">
<button type="button" class="btn btn-outline-danger remove-additional-doc-row">Remove</button> <button type="button" class="btn btn-outline-danger remove-additional-doc-row">Remove</button>
@ -126,7 +190,6 @@
var form = $(this).closest('form'); var form = $(this).closest('form');
var formData = new FormData(form[0]); var formData = new FormData(form[0]);
var fileInputs = form.find('input[type="file"]'); var fileInputs = form.find('input[type="file"]');
var allowedExtensions = ['pdf', 'png', 'jpeg', 'jpg'];
if (kycPrimaryKey === '') { if (kycPrimaryKey === '') {
toastr.error('Client is required', 'Error'); toastr.error('Client is required', 'Error');
@ -135,24 +198,26 @@
} }
var isFormEmpty = true; var isFormEmpty = true;
var hasInvalidFile = false;
fileInputs.each(function() { fileInputs.each(function() {
var files = $(this)[0].files; var $currentFileInput = $(this);
var files = $currentFileInput[0].files;
if (files.length > 0) { if (files.length > 0) {
for (var i = 0; i < files.length; i++) { if (!validateOtherDocFileField($currentFileInput, true)) {
var fileName = files[i].name; hasInvalidFile = true;
var fileExtension = fileName.split('.').pop().toLowerCase(); return false;
if (allowedExtensions.indexOf(fileExtension) === -1) {
form.trigger('reset')
toastr.warning('File type not allowed: ' + fileName, 'Only Allowed pdf, png, jpg and jpeg');
return;
}
} }
isFormEmpty = false; isFormEmpty = false;
return false;
} }
}); });
if (hasInvalidFile) {
return;
}
if (isFormEmpty) { if (isFormEmpty) {
form.find('.kyc-primary-file-error').text('Please select a file.');
fileInputs.addClass('is-invalid');
toastr.warning('Form is Empty', 'Warning'); toastr.warning('Form is Empty', 'Warning');
return; return;
} }
@ -238,31 +303,29 @@
var isValid = $('#kyc_form').parsley().validate(); var isValid = $('#kyc_form').parsley().validate();
var form_action = ''; var form_action = '';
var allowedExtensions = ['pdf', 'png', 'jpeg', 'jpg'];
$('#kyc_form .other-doc-name-field, #kyc_form .other-doc-file-field').removeClass('is-invalid'); $('#kyc_form .other-doc-name-field, #kyc_form .other-doc-file-field').removeClass('is-invalid');
$('#kyc_form .other-doc-file-error').text('');
$('#additional_docs_rows .additional-doc-row').each(function() { $('#additional_docs_rows .additional-doc-row').each(function() {
var docNameField = $(this).find('.other-doc-name-field'); var docNameField = $(this).find('.other-doc-name-field');
var fileField = $(this).find('.other-doc-file-field'); var fileField = $(this).find('.other-doc-file-field');
var docNameValue = (docNameField.val() || '').trim(); var docNameValue = (docNameField.val() || '').trim();
var selectedFile = fileField[0].files[0]; var hasSelectedFile = !!(fileField[0].files[0]);
if (docNameValue === '' || !selectedFile) { if (docNameValue === '' || !hasSelectedFile) {
isValid = false; isValid = false;
if (docNameValue === '') { if (docNameValue === '') {
docNameField.addClass('is-invalid'); docNameField.addClass('is-invalid');
} }
if (!selectedFile) { if (!hasSelectedFile) {
fileField.addClass('is-invalid'); fileField.addClass('is-invalid');
} }
return; return;
} }
var fileExtension = selectedFile.name.split('.').pop().toLowerCase(); if (!validateOtherDocFileField(fileField, true)) {
if (allowedExtensions.indexOf(fileExtension) === -1) {
isValid = false; isValid = false;
fileField.addClass('is-invalid');
} }
}); });
@ -401,6 +464,14 @@
}); });
}); });
$(document).on('change', '.other-doc-file-field', function () {
validateOtherDocFileField($(this), true);
});
$(document).on('change', '.file-input__input', function () {
validateOtherDocFileField($(this), true);
});
function getKYCEntityDocument(entity_type_id, client_id){ function getKYCEntityDocument(entity_type_id, client_id){
$.ajax({ $.ajax({
@ -433,6 +504,8 @@
<input type="hidden" class="form-control" value="${item.id}" name="kyc_doc_type_id"> <input type="hidden" class="form-control" value="${item.id}" name="kyc_doc_type_id">
<input type="hidden" name="client_id" value="${client_id}"> <input type="hidden" name="client_id" value="${client_id}">
<button class="btn btn-sm btn-primary submit" style="position: relative; right:0px;">Submit</button> <button class="btn btn-sm btn-primary submit" style="position: relative; right:0px;">Submit</button>
<small class="mt-1 text-muted d-block">Allowed: PDF, JPG, JPEG, PNG. Size : 200KB/image 25MB/PDF</small>
<div class="kyc-primary-file-error text-danger small mt-1"></div>
</form> </form>
</td> </td>
<td id="name_${item.id}" style="display:none;"></td> <td id="name_${item.id}" style="display:none;"></td>

View File

@ -1,4 +1,23 @@
<?php
helper('datatable_view');
$client_header_labels = ['S.No', 'Client Name', 'Account Manager', 'Action'];
$client_col_count = count($client_header_labels);
$client_col_max_len = array_fill(0, $client_col_count, 0);
for ($i = 0; $i < $client_col_count; $i++) {
$client_col_max_len[$i] = mb_strlen($client_header_labels[$i]);
}
$clientList = $clientList ?? [];
foreach ($clientList as $index => $row) {
$client_col_max_len[0] = max($client_col_max_len[0], mb_strlen((string) ($index + 1)));
$nameCell = trim((string) $row->client_name) . ' ( ' . trim((string) $row->short_name) . ' ) ';
$client_col_max_len[1] = max($client_col_max_len[1], mb_strlen($nameCell));
$client_col_max_len[2] = max($client_col_max_len[2], mb_strlen((string) ($row->account_managers ?? '')));
$client_col_max_len[3] = max($client_col_max_len[3], 4);
}
$client_col_min_px = [48, 120, 100, 52];
$client_col_max_px = [64, 520, 400, 72];
$client_col_width_px = nhance_dt_column_widths_px($client_header_labels, $client_col_max_len, $client_col_min_px, $client_col_max_px);
?>
<style> <style>
/* .table th, /* .table th,
.table td { .table td {
@ -67,12 +86,12 @@ table.dataTable thead th {
.dataTables_length label {height: 21px !important;} .dataTables_length label {height: 21px !important;}
#tickets-table .btn-group.dropdown, #client-list-table .btn-group.dropdown,
#tickets-table .dropdown { #client-list-table .dropdown {
position: relative; position: relative;
} }
#tickets-table .dropdown-menu { #client-list-table .dropdown-menu {
z-index: 30000 !important; z-index: 30000 !important;
max-height: 170px; max-height: 170px;
overflow-y: auto; overflow-y: auto;
@ -80,10 +99,54 @@ table.dataTable thead th {
scroll-behavior: smooth; scroll-behavior: smooth;
} }
#tickets-table .dropdown-menu.show { #client-list-table .dropdown-menu.show {
z-index: 30000 !important; z-index: 30000 !important;
} }
<?php for ($i = 0; $i < $client_col_count; $i++) : ?>
#client-list-table_wrapper .dataTables_scrollHead table thead th:nth-child(<?= $i + 1 ?>),
#client-list-table thead th:nth-child(<?= $i + 1 ?>) {
min-width: <?= (int) $client_col_width_px[$i] ?>px;
width: <?= (int) $client_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
overflow: visible !important;
}
#client-list-table tbody td:nth-child(<?= $i + 1 ?>) {
width: <?= (int) $client_col_width_px[$i] ?>px;
max-width: <?= (int) $client_col_width_px[$i] ?>px;
min-width: <?= (int) $client_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
}
<?php endfor; ?>
#client-list-table tbody td:nth-child(1),
#client-list-table tbody td:nth-child(2),
#client-list-table tbody td:nth-child(3) {
overflow: hidden;
text-overflow: ellipsis;
}
#client-list-table tbody td:nth-child(4) {
overflow: visible;
text-overflow: clip;
}
#client-list-table tbody td {
padding: 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
#client-list-table_wrapper .dataTables_scrollHead table thead th,
#client-list-table thead th {
padding: 5px 2.35rem 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
#client-list-table .dropdown-toggle.btn-sm {
padding: 4px 9px !important;
font-size: 13px;
line-height: 1.2;
}
@ -104,7 +167,7 @@ table.dataTable thead th {
<a href="<?= base_url("client/create"); ?>" type="button" id="btnAdd" class="btn btn-primary waves-effect waves-light" data-toggle="" data-placement="top" title="Add" data-trigger="hover">Add</a> <a href="<?= base_url("client/create"); ?>" type="button" id="btnAdd" class="btn btn-primary waves-effect waves-light" data-toggle="" data-placement="top" title="Add" data-trigger="hover">Add</a>
</div> --> </div> -->
<!-- </div>--> <!-- </div>-->
<table data-custom-table-css="table" class="table mb-0 nowrap" cellspacing="0" id="tickets-table"> <table data-custom-table-css="table" class="table table-hover mb-0 nowrap w-100 m-0 table-centered" cellspacing="0" id="client-list-table">
<thead class="bg-light"> <thead class="bg-light">
<tr> <tr>
<th class="font-weight-medium">S.No&nbsp;</th> <th class="font-weight-medium">S.No&nbsp;</th>
@ -117,7 +180,7 @@ table.dataTable thead th {
<tbody> <tbody>
<?php foreach($clientList as $index => $row){ ?> <?php foreach($clientList as $index => $row){ ?>
<tr > <tr >
<td class="text-center"><?=$index+1?></td> <td><?=$index+1?></td>
<td class="client_info" data-id="<?php echo $row->id; ?>"><?php echo $row->client_name; ?> ( <?php echo $row->short_name; ?> ) </td> <td class="client_info" data-id="<?php echo $row->id; ?>"><?php echo $row->client_name; ?> ( <?php echo $row->short_name; ?> ) </td>
<!-- <td> <!-- <td>
<?php $account_managers = ''; ?> <?php $account_managers = ''; ?>
@ -194,7 +257,7 @@ table.dataTable thead th {
<script> <script>
document.addEventListener("DOMContentLoaded", function () { document.addEventListener("DOMContentLoaded", function () {
const table = document.getElementById("tickets-table"); const table = document.getElementById("client-list-table");
// Create custom dropdown // Create custom dropdown
function createCustomDropdown(row) { function createCustomDropdown(row) {
@ -319,7 +382,8 @@ table.dataTable thead th {
var table; var table;
$(document).ready(function() $(document).ready(function()
{ {
table = $('#tickets-table').DataTable({ nhanceListDataTableBeforeInit();
table = $('#client-list-table').DataTable(nhanceMergeListDataTableOptions({
// dom: "<'row'<'col-12 d-flex justify-content-between align-items-center'<'datatable-search dataTables_filter'f><'datatable-buttons dt-buttons'B>>>" + // dom: "<'row'<'col-12 d-flex justify-content-between align-items-center'<'datatable-search dataTables_filter'f><'datatable-buttons dt-buttons'B>>>" +
// "<'row'<'col-sm-12'tr>>" + // "<'row'<'col-sm-12'tr>>" +
// "<'row'<'col-sm-5'i><'col-sm-7'p>>", // "<'row'<'col-sm-5'i><'col-sm-7'p>>",
@ -378,7 +442,14 @@ $(document).ready(function()
}, },
paging: true , paging: true ,
// pagingType: 'full_numbers' // pagingType: 'full_numbers'
}); columnDefs: [
<?php for ($i = 0; $i < $client_col_count; $i++) : ?>
{ targets: <?= $i ?>, width: '<?= (int) $client_col_width_px[$i] ?>px' },
<?php endfor; ?>
],
}));
nhanceListDataTableAfterInit();
nhanceListDataTableBindAdjust(table);
// $(".datatable-buttons").prepend(` // $(".datatable-buttons").prepend(`
// <label class="switch"> // <label class="switch">
@ -427,7 +498,7 @@ $('#toggleButtons').on('change', function() {
// Client list specific guard: keep action menu above table header // Client list specific guard: keep action menu above table header
// and always show from the top (prevents first item from appearing hidden). // and always show from the top (prevents first item from appearing hidden).
$(document).on('show.bs.dropdown', '#tickets-table tbody .dropdown', function () { $(document).on('show.bs.dropdown', '#client-list-table tbody .dropdown', function () {
var $dd = $(this); var $dd = $(this);
var $menu = $dd.children('.dropdown-menu'); var $menu = $dd.children('.dropdown-menu');
var $row = $dd.closest('tr'); var $row = $dd.closest('tr');
@ -453,7 +524,7 @@ $(document).on('show.bs.dropdown', '#tickets-table tbody .dropdown', function ()
} }
}); });
$(document).on('hidden.bs.dropdown', '#tickets-table tbody .dropdown', function () { $(document).on('hidden.bs.dropdown', '#client-list-table tbody .dropdown', function () {
var $dd = $(this); var $dd = $(this);
$dd.removeClass('dropup'); $dd.removeClass('dropup');
$dd.children('.dropdown-menu').scrollTop(0).css('z-index', ''); $dd.children('.dropdown-menu').scrollTop(0).css('z-index', '');

View File

@ -205,7 +205,9 @@ input:checked + .slider_blue::before {
<div class="form-group col-md-4"> <div class="form-group col-md-4">
<label for="policy_type"> Policy Type<span class="text-danger">*</span></label> <label for="policy_type"> Policy Type<span class="text-danger">*</span></label>
<select class="form-control" id="policy_type" name="policy_type_id" required> <select class="form-control" id="policy_type" name="policy_type_id" required
data-parsley-pattern="^[1-9][0-9]*$"
data-parsley-pattern-message="Please select a valid Policy Type.">
<option value="0">Select Policy Type</option> <option value="0">Select Policy Type</option>
<?php foreach ($policy_types as $value) { ?> <?php foreach ($policy_types as $value) { ?>
<option value="<?= $value['id']?>"><?= $value['policy_type'] ?></option> <option value="<?= $value['id']?>"><?= $value['policy_type'] ?></option>
@ -248,7 +250,9 @@ input:checked + .slider_blue::before {
<div class="form-group col-md-4"> <div class="form-group col-md-4">
<label for="policy_no">Policy No<span class="text-danger">*</span></label> <label for="policy_no">Policy No<span class="text-danger">*</span></label>
<input value="" type="text" class="form-control" oninput="checkPolicyNo(this)" placeholder="Enter Policy Number" name="policy_no" id="policy_no" required> <input value="" type="text" class="form-control" oninput="checkPolicyNo(this)" placeholder="Enter Policy Number" name="policy_no" id="policy_no" required
data-parsley-pattern="^[a-zA-Z0-9\\s_\\-/\\\\]+$"
data-parsley-pattern-message="Invalid characters in Policy No.">
</div> </div>
</div> </div>
@ -280,12 +284,18 @@ input:checked + .slider_blue::before {
<div class="form-group col-md-4"> <div class="form-group col-md-4">
<label for="gst_no">GST ( % )<span class="text-danger">*</span></label> <label for="gst_no">GST ( % )<span class="text-danger">*</span></label>
<input type="text" class="form-control" placeholder="GST (%)" id="gst_no" name="gst" required> <input type="text" class="form-control" placeholder="GST (%)" id="gst_no" name="gst" required
data-parsley-type="number"
data-parsley-range="[0, 100]"
data-parsley-type-message="GST must be a valid number."
data-parsley-range-message="GST percentage must be between 0 and 100.">
</div> </div>
<div class="form-group col-md-4"> <div class="form-group col-md-4">
<label for="wellness_plan_id">Wellness Plan ID<span class="text-danger"></span></label> <label for="wellness_plan_id">Wellness Plan ID<span class="text-danger"></span></label>
<input type="text" class="form-control" id="wellness_plan_id" name="wellness_plan_id"> <input type="text" class="form-control" id="wellness_plan_id" name="wellness_plan_id"
data-parsley-pattern="^[a-zA-Z0-9/_-]+$"
data-parsley-pattern-message="Wellness Plan ID can only contain letters, numbers, hyphens (-), underscores (_), and forward slashes (/).">
</div> </div>
<div class="form-group col-md-4"> <div class="form-group col-md-4">

View File

@ -173,7 +173,7 @@
<?php if (isset($commission_file_list)) : ?> <?php if (isset($commission_file_list)) : ?>
<?php foreach ($commission_file_list as $index => $row) { ?> <?php foreach ($commission_file_list as $index => $row) { ?>
<tr> <tr>
<td class="text-center"><?= $index+1 ?></td> <td><?= $index+1 ?></td>
<td style="overflow: hidden;" class="reload truncate" data-toggle="tooltip" data-placement="top" title="<?php echo $row['file_name'] ?>"> <td style="overflow: hidden;" class="reload truncate" data-toggle="tooltip" data-placement="top" title="<?php echo $row['file_name'] ?>">
<?php echo $row['file_name'] ?> <?php echo $row['file_name'] ?>
</td> </td>

View File

@ -144,7 +144,7 @@
<?php if (isset($files)) { ?> <?php if (isset($files)) { ?>
<?php foreach($files as $index => $row){ ?> <?php foreach($files as $index => $row){ ?>
<tr> <tr>
<td class="text-center"><?= $index + 1 ?></td> <td><?= $index + 1 ?></td>
<td><?php echo $row['doc_name']; ?></td> <td><?php echo $row['doc_name']; ?></td>
<td><?php echo $row['file_name']; ?></td> <td><?php echo $row['file_name']; ?></td>
<td> <td>

View File

@ -30,10 +30,6 @@
white-space: normal; white-space: normal;
} }
.dataTables_filter{
position: absolute;
}
.right-align-input { .right-align-input {
text-align: right; text-align: right;
} }
@ -81,7 +77,131 @@
</style> </style>
<?php $pro_rata_total = 0; $gst_total = 0 ?> <?php
helper('datatable_view');
$getData = $getData ?? null;
$emp_show_client_branch = isset($getData) && $getData['client_id'] == '0' && $getData['policy_id'] == '0' && $getData['branch_id'] == '0' && ($getData['emp_code'] != '' || $getData['emp_name'] != '' || $getData['status'] != '');
$emp_show_branch = isset($getData) && $getData['client_id'] != '0' && $getData['branch_id'] == '0';
$emp_header_labels = ['S.No'];
if ($emp_show_client_branch) {
$emp_header_labels[] = 'Client/Branch';
}
if ($emp_show_branch) {
$emp_header_labels[] = 'Branch';
}
$emp_header_labels = array_merge($emp_header_labels, [
'Name', 'EMP Code', 'Relationship', 'Gender', 'Email', 'Mobile', 'Date of Birth',
'Policy name', 'Insurer name', 'TPA ID', 'Risk ID', 'Policy status',
'(₹)Sum Insured', '(₹)Premium', '(₹)Pro Rata Premium', '(₹)GST', 'Action',
]);
$emp_col_count = count($emp_header_labels);
$emp_col_max_len = array_fill(0, $emp_col_count, 0);
for ($i = 0; $i < $emp_col_count; $i++) {
$emp_col_max_len[$i] = mb_strlen($emp_header_labels[$i]);
}
if (isset($employees)) {
foreach ($employees as $key => $employee) {
$ci = 0;
$emp_col_max_len[$ci] = max($emp_col_max_len[$ci], mb_strlen((string) ($key + 1)));
$ci++;
if ($emp_show_client_branch) {
$cb = ($employee['client_short_name'] ?? '') . ' - ' . ($employee['client_branch_name'] ?? '');
$emp_col_max_len[$ci] = max($emp_col_max_len[$ci], mb_strlen($cb));
$ci++;
}
if ($emp_show_branch) {
$emp_col_max_len[$ci] = max($emp_col_max_len[$ci], mb_strlen((string) ($employee['client_branch_name'] ?? '')));
$ci++;
}
$emp_col_max_len[$ci] = max($emp_col_max_len[$ci], mb_strlen((string) ($employee['name'] ?? '')));
$ci++;
$emp_col_max_len[$ci] = max($emp_col_max_len[$ci], mb_strlen((string) ($employee['emp_code'] ?? '')));
$ci++;
$emp_col_max_len[$ci] = max($emp_col_max_len[$ci], mb_strlen((string) ($employee['relationship'] ?? '')));
$ci++;
$emp_col_max_len[$ci] = max($emp_col_max_len[$ci], mb_strlen((string) ($employee['gender'] ?? '')));
$ci++;
$emp_col_max_len[$ci] = max($emp_col_max_len[$ci], mb_strlen((string) ($employee['email_corporate'] ?? '')));
$ci++;
$emp_col_max_len[$ci] = max($emp_col_max_len[$ci], mb_strlen((string) ($employee['mobile'] ?? '')));
$ci++;
$dobStr = '';
if (! empty($employee['dob'])) {
$dobStr = date('d/m/Y', strtotime((string) $employee['dob']));
}
$emp_col_max_len[$ci] = max($emp_col_max_len[$ci], mb_strlen($dobStr));
$ci++;
$polStr = (isset($employee['policy_type']) ? $employee['policy_type'] : '') . ' - ' . (isset($employee['policy_no']) ? $employee['policy_no'] : '');
$emp_col_max_len[$ci] = max($emp_col_max_len[$ci], mb_strlen($polStr));
$ci++;
$emp_col_max_len[$ci] = max($emp_col_max_len[$ci], mb_strlen((string) ($employee['insurer_short_name'] ?? '')));
$ci++;
$emp_col_max_len[$ci] = max($emp_col_max_len[$ci], mb_strlen((string) ($employee['tpa_id'] ?? '')));
$ci++;
$emp_col_max_len[$ci] = max($emp_col_max_len[$ci], mb_strlen((string) ($employee['uhid'] ?? '')));
$ci++;
$emp_col_max_len[$ci] = max($emp_col_max_len[$ci], mb_strlen((string) ($employee['status'] ?? '')));
$ci++;
$emp_col_max_len[$ci] = max($emp_col_max_len[$ci], mb_strlen((string) format_indian_number($employee['basic_cover_si'] ?? 0)));
$ci++;
$emp_col_max_len[$ci] = max($emp_col_max_len[$ci], mb_strlen((string) format_indian_number($employee['premium'] ?? 0)));
$ci++;
$emp_col_max_len[$ci] = max($emp_col_max_len[$ci], mb_strlen((string) format_indian_number($employee['rata_premimum'] ?? 0)));
$ci++;
$emp_col_max_len[$ci] = max($emp_col_max_len[$ci], mb_strlen((string) format_indian_number($employee['gst'] ?? 0)));
$ci++;
$emp_col_max_len[$ci] = max($emp_col_max_len[$ci], 4);
}
}
$emp_col_max_len[$emp_col_count - 6] = max($emp_col_max_len[$emp_col_count - 6], mb_strlen('Total'));
$emp_col_min_px = array_fill(0, $emp_col_count, 80);
$emp_col_max_px = array_fill(0, $emp_col_count, 360);
$emp_col_min_px[0] = 48;
$emp_col_max_px[0] = 72;
$emp_col_min_px[$emp_col_count - 1] = 72;
$emp_col_max_px[$emp_col_count - 1] = 96;
$emp_col_width_px = nhance_dt_column_widths_px($emp_header_labels, $emp_col_max_len, $emp_col_min_px, $emp_col_max_px);
$pro_rata_total = 0;
$gst_total = 0;
?>
<style>
<?php for ($i = 0; $i < $emp_col_count; $i++) : ?>
#employee-data-list-table_wrapper .dataTables_scrollHead table thead th:nth-child(<?= $i + 1 ?>),
#employee-data-list-table thead th:nth-child(<?= $i + 1 ?>) {
min-width: <?= (int) $emp_col_width_px[$i] ?>px;
width: <?= (int) $emp_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
overflow: visible !important;
}
#employee-data-list-table tbody td:nth-child(<?= $i + 1 ?>) {
width: <?= (int) $emp_col_width_px[$i] ?>px;
max-width: <?= (int) $emp_col_width_px[$i] ?>px;
min-width: <?= (int) $emp_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
}
<?php endfor; ?>
#employee-data-list-table tbody td:not(:last-child) {
overflow: hidden;
text-overflow: ellipsis;
}
#employee-data-list-table tbody td:last-child {
overflow: visible;
text-overflow: clip;
}
#employee-data-list-table tbody td {
padding: 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
#employee-data-list-table thead th {
padding: 5px 2.35rem 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
</style>
<div class="row" id="client_list"> <div class="row" id="client_list">
<div class="col-12"> <div class="col-12">
@ -92,7 +212,8 @@
<h4 style="position: relative;">Employees</h4> <h4 style="position: relative;">Employees</h4>
</div> </div>
</div> </div>
<table data-custom-table-css="table" class="table table-striped mb-0 nowrap" cellspacing="0" id="tickets-table"> <div class="table-responsive">
<table data-custom-table-css="table" class="table table-hover m-0 table-centered nowrap w-100 dt-responsive" cellspacing="0" id="employee-data-list-table">
<thead class="bg-light"> <thead class="bg-light">
<tr> <tr>
<th class="font-weight-medium">S.No&nbsp;</th> <th class="font-weight-medium">S.No&nbsp;</th>
@ -132,7 +253,7 @@
$gst_total = 0; $gst_total = 0;
foreach ($employees as $key => $employee) { ?> foreach ($employees as $key => $employee) { ?>
<tr> <tr>
<td class="text-center"><b><?php echo ($key + 1); ?></b></td> <td><b><?php echo ($key + 1); ?></b></td>
<?php if (isset($getData)) { <?php if (isset($getData)) {
if ($getData['client_id'] == '0' && $getData['policy_id'] == '0' && $getData['branch_id'] == '0' && ($getData['emp_code'] != "" || $getData['emp_name'] != "" || $getData['status'] != "")) { ?> if ($getData['client_id'] == '0' && $getData['policy_id'] == '0' && $getData['branch_id'] == '0' && ($getData['emp_code'] != "" || $getData['emp_name'] != "" || $getData['status'] != "")) { ?>
@ -157,19 +278,19 @@
<?php <?php
switch ($employee['status']) { switch ($employee['status']) {
case 'draft': case 'draft':
echo '<span class="badge badge-secondary">' . $employee['status'] . '</span>'; echo '<span class="badge badge-secondary">' . ucfirst($employee['status']) . '</span>';
break; break;
case 'active': case 'active':
echo '<span class="badge badge-success">' . $employee['status'] . '</span>'; echo '<span class="badge badge-success">' . ucfirst($employee['status']) . '</span>';
break; break;
case 'inactive': case 'inactive':
echo '<span class="badge badge-warning">' . $employee['status'] . '</span>'; echo '<span class="badge badge-warning">' . ucfirst($employee['status']) . '</span>';
break; break;
case 'expired': case 'expired':
echo '<span class="badge badge-danger">' . $employee['status'] . '</span>'; echo '<span class="badge badge-danger">' . ucfirst($employee['status']) . '</span>';
break; break;
case 'enrolled': case 'enrolled':
echo '<span class="badge2 badge2-secondary2">' . $employee['status'] . '</span>'; echo '<span class="badge2 badge2-secondary2">' . ucfirst($employee['status']) . '</span>';
break; break;
default: default:
echo $employee['status']; echo $employee['status'];
@ -249,6 +370,7 @@
</tr> </tr>
</tfoot> </tfoot>
</table> </table>
</div>
</div> </div>
</div> </div>
</div><!-- end col --> </div><!-- end col -->
@ -347,37 +469,56 @@
}) })
$(document).ready(function() { $(document).ready(function() {
var ticketsTable = $('#tickets-table'); var ticketsTable = $('#employee-data-list-table');
if (ticketsTable.length) { if (ticketsTable.length) {
ticketsTable.DataTable({ var _dtDefScroll = {
scrollX: true, scrollX: $.fn.dataTable.defaults.scrollX,
// dom: "<'row'<'col-sm-6'f><'col-sm-6 text-right'B>>" + // Filter left, buttons right scrollY: $.fn.dataTable.defaults.scrollY,
// "<'row'<'col-sm-12'tr>>" + scrollCollapse: $.fn.dataTable.defaults.scrollCollapse
// "<'row'<'col-sm-5'i><'col-sm-7'p>>", // Pagination at the bottom, without page length selector };
dom: "<'row'<'col-sm-6'f><'col-sm-6 text-right'B>>" + // Filter left, buttons right $.extend($.fn.dataTable.defaults, { scrollX: false, scrollY: false, scrollCollapse: false });
"<'row'<'col-sm-12'tr>>" +
"<'row align-items-center'<'col-5 text-start'i><'col-7 d-flex justify-content-end align-items-center'<'me-2'l>p>>", var nhEmpDataTable = ticketsTable.DataTable({
dom: "<'row'<'col-sm-6'f><'col-sm-6 text-right'B>>" +
"<'row'<'col-sm-12'tr>>" +
"<'row align-items-center'<'col-5 text-start'i><'col-7 d-flex justify-content-end align-items-center'<'me-2'l>p>>",
lengthMenu: [[10, 20, 50, 100], [10, 20, 50, 100]], lengthMenu: [[10, 20, 50, 100], [10, 20, 50, 100]],
scrollX: false,
scrollY: false,
scrollCollapse: false,
initComplete: function () {
var $wrap = $(this.api().table().container());
var $body = $wrap.find('.dataTables_scrollBody');
var $head = $wrap.find('.dataTables_scrollHead');
if ($body.length && $head.length) {
$body.off('scroll.nhEmpHScroll').on('scroll.nhEmpHScroll', function () {
$head.scrollLeft($(this).scrollLeft());
});
$head.off('scroll.nhEmpHScroll').on('scroll.nhEmpHScroll', function () {
$body.scrollLeft($(this).scrollLeft());
});
}
},
buttons: [ buttons: [
{ {
extend: 'collection', extend: 'collection',
text: '<span class=" btn-custom"> Export </span><i class="mdi mdi-menu-down"></i>', text: '<span class=" btn-custom"> Export </span><i class="mdi mdi-menu-down"></i>',
className: 'btn app-btn-secondary ', className: 'btn app-btn-secondary ',
buttons: [ buttons: [
{ {
extend: 'csv', extend: 'csv',
text: '<i class="mdi mdi-file-delimited " ></i><span class=" btn-custom"> CSV </span>', text: '<i class="mdi mdi-file-delimited " ></i><span class=" btn-custom"> CSV </span>',
className: 'app-btn-primary ', className: 'app-btn-primary ',
title: 'Members', title: 'Members',
}, },
{ {
extend: 'excel', extend: 'excel',
text: '<i class="mdi mdi-file-excel " ></i><span class=" btn-custom"> EXCEL </span>', text: '<i class="mdi mdi-file-excel " ></i><span class=" btn-custom"> EXCEL </span>',
className: 'app-btn-primary ', className: 'app-btn-primary ',
title: 'Members', title: 'Members',
sheetName: 'Members' sheetName: 'Members'
} }
] ]
} }
], ],
@ -393,9 +534,28 @@
searchPlaceholder: "Search", searchPlaceholder: "Search",
emptyTable: '<div class="text-center text-muted">No Data found</div>' emptyTable: '<div class="text-center text-muted">No Data found</div>'
}, },
paging: true, // Enable pagination paging: true,
pageLength: 25 // Set default number of rows per page (optional) pageLength: 25,
autoWidth: false,
responsive: false,
columnDefs: [
<?php for ($i = 0; $i < $emp_col_count; $i++) : ?>
{ targets: <?= $i ?>, width: '<?= (int) $emp_col_width_px[$i] ?>px' },
<?php endfor; ?>
],
}); });
$.extend($.fn.dataTable.defaults, _dtDefScroll);
nhEmpDataTable.on('draw.dt', function () {
nhEmpDataTable.columns.adjust();
});
$(window).on('resize', function () {
nhEmpDataTable.columns.adjust();
});
setTimeout(function () {
nhEmpDataTable.columns.adjust();
}, 0);
} else { } else {
console.error("Table not found."); console.error("Table not found.");
} }
@ -871,7 +1031,7 @@
} }
$('#tickets-table tbody').on('click', 'td', function () { $('#employee-data-list-table tbody').on('click', 'td', function () {
const colIndex = this.cellIndex; const colIndex = this.cellIndex;
const rowIndex = this.parentElement.rowIndex - 1; // minus header const rowIndex = this.parentElement.rowIndex - 1; // minus header
console.log('Row:', rowIndex, 'Column:', colIndex); console.log('Row:', rowIndex, 'Column:', colIndex);

View File

@ -1,3 +1,30 @@
<?php
helper('datatable_view');
$end_header_labels = ['S.No', 'Name/code', 'Policy name', 'Endorsement ID', 'Insurer name', 'Remarks', 'Endorsement Type', 'Status', 'Action'];
$end_col_count = count($end_header_labels);
$end_col_max_len = array_fill(0, $end_col_count, 0);
for ($i = 0; $i < $end_col_count; $i++) {
$end_col_max_len[$i] = mb_strlen($end_header_labels[$i]);
}
$employees = $employees ?? [];
foreach ($employees as $key => $employee) {
$end_col_max_len[0] = max($end_col_max_len[0], mb_strlen((string) ($key + 1)));
$end_col_max_len[1] = max($end_col_max_len[1], mb_strlen(trim((string) ($employee['name'] ?? '')) . '( ' . trim((string) ($employee['emp_code'] ?? '')) . ' )'));
$policyLine = (isset($employee['policy_type']) ? (string) $employee['policy_type'] : '') . ' - ' . (isset($employee['policy_no']) ? (string) $employee['policy_no'] : '');
$end_col_max_len[2] = max($end_col_max_len[2], mb_strlen($policyLine));
$end_col_max_len[3] = max($end_col_max_len[3], mb_strlen((string) ($employee['endorsement_id'] ?? '')));
$end_col_max_len[4] = max($end_col_max_len[4], mb_strlen((string) ($employee['insurer_short_name'] ?? '')));
$end_col_max_len[5] = max($end_col_max_len[5], mb_strlen((string) ($employee['remarks'] ?? '')));
$act = $employee['actions'] ?? '';
$actionLabel = $act === 'c' ? 'Correction' : ($act === 'si' ? 'SI Enhancement' : ($act === 'd' ? 'Deletion' : (string) $act));
$end_col_max_len[6] = max($end_col_max_len[6], mb_strlen($actionLabel));
$end_col_max_len[7] = max($end_col_max_len[7], mb_strlen((string) ($employee['status'] ?? '')));
$end_col_max_len[8] = max($end_col_max_len[8], 4);
}
$end_col_min_px = [48, 120, 160, 110, 120, 120, 120, 96, 52];
$end_col_max_px = [64, 280, 400, 200, 240, 360, 200, 160, 72];
$end_col_width_px = nhance_dt_column_widths_px($end_header_labels, $end_col_max_len, $end_col_min_px, $end_col_max_px);
?>
<style> <style>
.table th, .table th,
.table td { .table td {
@ -61,6 +88,49 @@
flex-shrink: 0; flex-shrink: 0;
gap: 10px; gap: 10px;
} }
<?php for ($i = 0; $i < $end_col_count; $i++) : ?>
#endorsement-list-table_wrapper .dataTables_scrollHead table thead th:nth-child(<?= $i + 1 ?>),
#endorsement-list-table thead th:nth-child(<?= $i + 1 ?>) {
min-width: <?= (int) $end_col_width_px[$i] ?>px;
width: <?= (int) $end_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
overflow: visible !important;
}
#endorsement-list-table tbody td:nth-child(<?= $i + 1 ?>) {
width: <?= (int) $end_col_width_px[$i] ?>px;
max-width: <?= (int) $end_col_width_px[$i] ?>px;
min-width: <?= (int) $end_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
}
<?php endfor; ?>
#endorsement-list-table tbody td:nth-child(1),
#endorsement-list-table tbody td:nth-child(2),
#endorsement-list-table tbody td:nth-child(3),
#endorsement-list-table tbody td:nth-child(4),
#endorsement-list-table tbody td:nth-child(5),
#endorsement-list-table tbody td:nth-child(6),
#endorsement-list-table tbody td:nth-child(7),
#endorsement-list-table tbody td:nth-child(8) {
overflow: hidden;
text-overflow: ellipsis;
}
#endorsement-list-table tbody td:nth-child(9) {
overflow: visible;
text-overflow: clip;
}
#endorsement-list-table tbody td {
padding: 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
#endorsement-list-table thead th {
padding: 5px 2.35rem 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
</style> </style>
<div class="container-fluid-min"> <div class="container-fluid-min">
@ -124,7 +194,7 @@
</div> </div>
</div> --> </div> -->
<table data-custom-table-css="table" class="table table-hover m-0 table-centered dt-responsive w-100" cellspacing="0" id="tickets-table"> <table data-custom-table-css="table" class="table table-hover m-0 table-centered dt-responsive w-100" cellspacing="0" id="endorsement-list-table">
<thead class="bg-light"> <thead class="bg-light">
<tr> <tr>
<th class="font-weight-medium">S.No&nbsp;</th> <th class="font-weight-medium">S.No&nbsp;</th>
@ -145,7 +215,7 @@
foreach ($employees as $key => $employee) { ?> foreach ($employees as $key => $employee) { ?>
<tr> <tr>
<td class="text-center"><b><?php echo ($key + 1) ?></b></td> <td><b><?php echo ($key + 1) ?></b></td>
<td><?php echo $employee['name'] ?>( <?php echo $employee['emp_code'] ?> )</td> <td><?php echo $employee['name'] ?>( <?php echo $employee['emp_code'] ?> )</td>
<!-- <td><?php echo isset($employee['policy_name']) ? $employee['policy_name'] : '' ?> - <?php echo isset($employee['policy_no']) ? $employee['policy_no'] : '' ?> - <?php echo isset($employee['policy_type']) ? $employee['policy_type'] : '' ?></td> --> <!-- <td><?php echo isset($employee['policy_name']) ? $employee['policy_name'] : '' ?> - <?php echo isset($employee['policy_no']) ? $employee['policy_no'] : '' ?> - <?php echo isset($employee['policy_type']) ? $employee['policy_type'] : '' ?></td> -->
<td><?php echo isset($employee['policy_type']) ? $employee['policy_type'] : '' ?> - <?php echo isset($employee['policy_no']) ? $employee['policy_no'] : '' ?></td> <td><?php echo isset($employee['policy_type']) ? $employee['policy_type'] : '' ?> - <?php echo isset($employee['policy_no']) ? $employee['policy_no'] : '' ?></td>
@ -625,7 +695,8 @@
$(document).ready(function() { $(document).ready(function() {
$('#tickets-table').DataTable({ nhanceListDataTableBeforeInit();
var nhEndorsementTable = $('#endorsement-list-table').DataTable(nhanceMergeListDataTableOptions({
// dom: "<'row'<'col-12 d-flex justify-content-between align-items-center'<'datatable-search dataTables_filter'f><'datatable-buttons dt-buttons'B>>>" + // dom: "<'row'<'col-12 d-flex justify-content-between align-items-center'<'datatable-search dataTables_filter'f><'datatable-buttons dt-buttons'B>>>" +
// "<'row'<'col-sm-12'tr>>" + // "<'row'<'col-sm-12'tr>>" +
// "<'row'<'col-sm-5'i><'col-sm-7'p>>", // "<'row'<'col-sm-5'i><'col-sm-7'p>>",
@ -689,12 +760,18 @@
}, },
paging: true, paging: true,
// pagingType: 'full_numbers' // pagingType: 'full_numbers'
columnDefs: [{ columnDefs: [
type: 'scientific', <?php for ($i = 0; $i < $end_col_count; $i++) : ?>
targets: 0 <?php if ($i === 0) : ?>
} // Apply custom sorting type to the first column { targets: 0, width: '<?= (int) $end_col_width_px[0] ?>px', type: 'scientific' },
<?php else : ?>
{ targets: <?= $i ?>, width: '<?= (int) $end_col_width_px[$i] ?>px' },
<?php endif; ?>
<?php endfor; ?>
], ],
}); }));
nhanceListDataTableAfterInit();
nhanceListDataTableBindAdjust(nhEndorsementTable);

View File

@ -1,3 +1,28 @@
<?php
helper('datatable_view');
$ex_header_labels = ['S.No', 'Client', 'Policy No', 'Description', 'Approved By', 'Amount', 'Expense Date', 'Action'];
$ex_col_count = count($ex_header_labels);
$ex_col_max_len = array_fill(0, $ex_col_count, 0);
for ($i = 0; $i < $ex_col_count; $i++) {
$ex_col_max_len[$i] = mb_strlen($ex_header_labels[$i]);
}
$expenses = $expenses ?? [];
foreach ($expenses as $index => $row) {
$ex_col_max_len[0] = max($ex_col_max_len[0], mb_strlen((string) ($index + 1)));
$cl = ($row['client_name'] ?? '') . (! empty($row['short_name']) ? ' (' . $row['short_name'] . ')' : '');
$ex_col_max_len[1] = max($ex_col_max_len[1], mb_strlen($cl));
$ex_col_max_len[2] = max($ex_col_max_len[2], mb_strlen((string) ($row['policy_no'] ?? '')));
$ex_col_max_len[3] = max($ex_col_max_len[3], mb_strlen((string) ($row['description'] ?? '')));
$ex_col_max_len[4] = max($ex_col_max_len[4], mb_strlen((string) ($row['approved_by_name'] ?? '')));
$ex_col_max_len[5] = max($ex_col_max_len[5], mb_strlen(number_format((float) ($row['amount'] ?? 0), 2)));
$ed = ! empty($row['expense_date']) ? date('d-m-Y', strtotime((string) $row['expense_date'])) : '';
$ex_col_max_len[6] = max($ex_col_max_len[6], mb_strlen($ed));
$ex_col_max_len[7] = max($ex_col_max_len[7], 4);
}
$ex_col_min_px = [48, 140, 120, 160, 120, 96, 110, 72];
$ex_col_max_px = [64, 360, 280, 400, 240, 140, 140, 88];
$ex_col_width_px = nhance_dt_column_widths_px($ex_header_labels, $ex_col_max_len, $ex_col_min_px, $ex_col_max_px);
?>
<style> <style>
.truncate { .truncate {
@ -30,6 +55,50 @@
</style> </style>
<style>
<?php for ($i = 0; $i < $ex_col_count; $i++) : ?>
#expense-table_wrapper .dataTables_scrollHead table thead th:nth-child(<?= $i + 1 ?>),
#expense-table thead th:nth-child(<?= $i + 1 ?>) {
min-width: <?= (int) $ex_col_width_px[$i] ?>px;
width: <?= (int) $ex_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
overflow: visible !important;
}
#expense-table tbody td:nth-child(<?= $i + 1 ?>) {
width: <?= (int) $ex_col_width_px[$i] ?>px;
max-width: <?= (int) $ex_col_width_px[$i] ?>px;
min-width: <?= (int) $ex_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
}
<?php endfor; ?>
#expense-table tbody td:nth-child(1),
#expense-table tbody td:nth-child(2),
#expense-table tbody td:nth-child(3),
#expense-table tbody td:nth-child(4),
#expense-table tbody td:nth-child(5),
#expense-table tbody td:nth-child(6),
#expense-table tbody td:nth-child(7) {
overflow: hidden;
text-overflow: ellipsis;
}
#expense-table tbody td:nth-child(8) {
overflow: visible;
text-overflow: clip;
}
#expense-table tbody td {
padding: 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
#expense-table thead th {
padding: 5px 2.35rem 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
</style>
<div class="row" id="expense_module"> <div class="row" id="expense_module">
<div class="col-12"> <div class="col-12">
<div class="card"> <div class="card">
@ -163,7 +232,7 @@
<?php if (! empty($expenses)) : ?> <?php if (! empty($expenses)) : ?>
<?php foreach ($expenses as $index => $row) : ?> <?php foreach ($expenses as $index => $row) : ?>
<tr> <tr>
<td class="text-center"><?= $index + 1; ?></td> <td><?= $index + 1; ?></td>
<td> <td>
<?= esc($row['client_name'] ?? ''); ?> <?= esc($row['client_name'] ?? ''); ?>
<?= ! empty($row['short_name']) ? ' (' . esc($row['short_name']) . ')' : ''; ?> <?= ! empty($row['short_name']) ? ' (' . esc($row['short_name']) . ')' : ''; ?>
@ -494,8 +563,8 @@
maxDate: new Date(), maxDate: new Date(),
}); });
$('#expense-table').DataTable({ nhanceListDataTableBeforeInit();
scrollX: true, var nhExpenseTable = $('#expense-table').DataTable(nhanceMergeListDataTableOptions({
dom: "<'row'<'col-12 d-flex justify-content-between align-items-center'<'datatable-search dataTables_filter'f><'datatable-buttons dt-buttons'B>>>" + dom: "<'row'<'col-12 d-flex justify-content-between align-items-center'<'datatable-search dataTables_filter'f><'datatable-buttons dt-buttons'B>>>" +
"<'row'<'col-sm-12'tr>>" + "<'row'<'col-sm-12'tr>>" +
"<'row align-items-center'<'col-5 text-start'i><'col-7 d-flex justify-content-end align-items-center'<'me-2'l>p>>", "<'row align-items-center'<'col-5 text-start'i><'col-7 d-flex justify-content-end align-items-center'<'me-2'l>p>>",
@ -569,8 +638,15 @@
</div>`, </div>`,
searchPlaceholder: "Search", searchPlaceholder: "Search",
emptyTable: '<div class="text-center text-muted">No Data found</div>' emptyTable: '<div class="text-center text-muted">No Data found</div>'
} },
}); columnDefs: [
<?php for ($i = 0; $i < $ex_col_count; $i++) : ?>
{ targets: <?= $i ?>, width: '<?= (int) $ex_col_width_px[$i] ?>px' },
<?php endfor; ?>
]
}));
nhanceListDataTableAfterInit();
nhanceListDataTableBindAdjust(nhExpenseTable);
$('.dataTables_length label').css('height', '21px'); $('.dataTables_length label').css('height', '21px');

View File

@ -34,12 +34,80 @@
</style> </style>
<?php
helper('datatable_view');
$faq_header_labels = ['S.No.', 'Category', 'Question', 'Status', 'Action'];
$faq_col_count = count($faq_header_labels);
$faq_col_max_len = array_fill(0, $faq_col_count, 0);
for ($i = 0; $i < $faq_col_count; $i++) {
$faq_col_max_len[$i] = mb_strlen($faq_header_labels[$i]);
}
$faq_list_rows = $faq_list ?? [];
$faq_sl = 0;
foreach ($faq_list_rows as $row) {
++$faq_sl;
$faq_col_max_len[0] = max($faq_col_max_len[0], mb_strlen((string) $faq_sl));
$category = $row['category'] ? $row['category'] : 'N/A';
$catDisp = (strlen($category) > 50) ? substr($category, 0, 50) . '...' : $category;
$faq_col_max_len[1] = max($faq_col_max_len[1], mb_strlen($catDisp));
$question_text = $row['question'] ? strip_tags($row['question']) : 'N/A';
$qDisp = (strlen($question_text) > 50) ? substr($question_text, 0, 50) . '...' : $question_text;
$faq_col_max_len[2] = max($faq_col_max_len[2], mb_strlen($qDisp));
$faq_st = (isset($row['is_active']) && (int) $row['is_active'] === 1) ? 'Active' : 'In-Active';
$faq_col_max_len[3] = max($faq_col_max_len[3], mb_strlen($faq_st));
$faq_col_max_len[4] = max($faq_col_max_len[4], 4);
}
$faq_col_min_px = [48, 100, 200, 88, 72];
$faq_col_max_px = [64, 280, 480, 120, 88];
$faq_col_width_px = nhance_dt_column_widths_px($faq_header_labels, $faq_col_max_len, $faq_col_min_px, $faq_col_max_px);
?>
<style>
<?php for ($i = 0; $i < $faq_col_count; $i++) : ?>
#faq-list-table_wrapper .dataTables_scrollHead table thead th:nth-child(<?= $i + 1 ?>),
#faq-list-table thead th:nth-child(<?= $i + 1 ?>) {
min-width: <?= (int) $faq_col_width_px[$i] ?>px;
width: <?= (int) $faq_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
overflow: visible !important;
}
#faq-list-table tbody td:nth-child(<?= $i + 1 ?>) {
width: <?= (int) $faq_col_width_px[$i] ?>px;
max-width: <?= (int) $faq_col_width_px[$i] ?>px;
min-width: <?= (int) $faq_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
}
<?php endfor; ?>
#faq-list-table tbody td:nth-child(1),
#faq-list-table tbody td:nth-child(2),
#faq-list-table tbody td:nth-child(3),
#faq-list-table tbody td:nth-child(4) {
overflow: hidden;
text-overflow: ellipsis;
}
#faq-list-table tbody td:nth-child(5) {
overflow: visible;
text-overflow: clip;
}
#faq-list-table tbody td {
padding: 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
#faq-list-table thead th {
padding: 5px 2.35rem 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
</style>
<!-- End ADD and EDIT Page HTML --> <!-- End ADD and EDIT Page HTML -->
<div class="row" id="List-page"> <div class="row" id="List-page">
<div class="col-12"> <div class="col-12">
<div class="card"> <div class="card">
<div class="card-body"> <div class="card-body">
<table data-custom-table-css="table" class="table mb-0 nowrap" cellspacing="0" id="user-table"> <table data-custom-table-css="table" class="table mb-0 nowrap" cellspacing="0" id="faq-list-table">
<thead class="bg-light"> <thead class="bg-light">
<tr> <tr>
<th class="font-weight-medium">S.No.&nbsp;</th> <th class="font-weight-medium">S.No.&nbsp;</th>
@ -56,7 +124,7 @@
$slno = 1; ?> $slno = 1; ?>
<?php foreach($faq_list as $index => $row) { ?> <?php foreach($faq_list as $index => $row) { ?>
<tr> <tr>
<td class="text-center"><?= $slno++; ?></td> <td><?= $slno++; ?></td>
<td><?php $category = $row['category'] ? $row['category'] : 'N/A'; <td><?php $category = $row['category'] ? $row['category'] : 'N/A';
echo (strlen($category) > 50) echo (strlen($category) > 50)
? htmlspecialchars(substr($category, 0, 50)) . "..." ? htmlspecialchars(substr($category, 0, 50)) . "..."
@ -223,9 +291,9 @@
$('#answer').parsley().validate(); $('#answer').parsley().validate();
}); });
var ticketsTable = $('#user-table'); var ticketsTable = $('#faq-list-table');
var table = ticketsTable.DataTable({ nhanceListDataTableBeforeInit();
scrollX: true, var table = ticketsTable.DataTable(nhanceMergeListDataTableOptions({
// dom: "<'row'<'col-sm-7'f><'col-sm-5 text-right'B>>" + // Filter left, buttons right // dom: "<'row'<'col-sm-7'f><'col-sm-5 text-right'B>>" + // Filter left, buttons right
// "<'row'<'col-sm-12'tr>>" + // "<'row'<'col-sm-12'tr>>" +
// "<'row'<'col-sm-5'i><'col-sm-7'p>>", // Pagination at the bottom, without page length selector // "<'row'<'col-sm-5'i><'col-sm-7'p>>", // Pagination at the bottom, without page length selector
@ -276,7 +344,14 @@
paging: true, // Enable pagination paging: true, // Enable pagination
pageLength: 10, // Set default number of rows per page (optional) pageLength: 10, // Set default number of rows per page (optional)
// ordering: false, // ordering: false,
}); columnDefs: [
<?php for ($i = 0; $i < $faq_col_count; $i++) : ?>
{ targets: <?= $i ?>, width: '<?= (int) $faq_col_width_px[$i] ?>px' },
<?php endfor; ?>
],
}));
nhanceListDataTableAfterInit();
nhanceListDataTableBindAdjust(table);
function placeActionDropdown($toggle) { function placeActionDropdown($toggle) {
const $group = $toggle.closest('.btn-group.dropdown'); const $group = $toggle.closest('.btn-group.dropdown');
@ -297,7 +372,7 @@
} }
} }
$('#user-table').on('show.bs.dropdown', '.table-action-cell .dropdown-toggle', function () { $('#faq-list-table').on('show.bs.dropdown', '.table-action-cell .dropdown-toggle', function () {
const $toggle = $(this); const $toggle = $(this);
const $scrollBody = $toggle.closest('.dataTables_scrollBody'); const $scrollBody = $toggle.closest('.dataTables_scrollBody');
@ -309,7 +384,7 @@
placeActionDropdown($toggle); placeActionDropdown($toggle);
}); });
$('#user-table').on('hide.bs.dropdown', '.table-action-cell .dropdown-toggle', function () { $('#faq-list-table').on('hide.bs.dropdown', '.table-action-cell .dropdown-toggle', function () {
const $scrollBody = $(this).closest('.dataTables_scrollBody'); const $scrollBody = $(this).closest('.dataTables_scrollBody');
const prevOverflowY = $scrollBody.data('prev-overflow-y'); const prevOverflowY = $scrollBody.data('prev-overflow-y');
if ($scrollBody.length) { if ($scrollBody.length) {
@ -318,7 +393,7 @@
}); });
ticketsTable.on('draw.dt', function () { ticketsTable.on('draw.dt', function () {
$('#user-table tbody tr td.table-action-cell .btn-group.dropdown').removeClass('dropup'); $('#faq-list-table tbody tr td.table-action-cell .btn-group.dropdown').removeClass('dropup');
}); });
}); });

View File

@ -1,3 +1,44 @@
<?php
helper('datatable_view');
$fl_header_labels = [
'S.No', 'File name', 'Client', 'Client Branch', 'Policy',
'Event', 'User/Time', 'Status', 'Action',
];
$fl_col_count = count($fl_header_labels);
$fl_col_max_len = array_fill(0, $fl_col_count, 0);
for ($i = 0; $i < $fl_col_count; $i++) {
$fl_col_max_len[$i] = mb_strlen($fl_header_labels[$i]);
}
$fileList = $fileList ?? [];
if (!empty($fileList) && is_array($fileList)) {
foreach ($fileList as $key => $file) {
$fl_col_max_len[0] = max($fl_col_max_len[0], mb_strlen((string) ($key + 1)));
$fl_col_max_len[1] = max($fl_col_max_len[1], mb_strlen((string) ($file['file_name'] ?? '')));
$fl_col_max_len[2] = max($fl_col_max_len[2], mb_strlen((string) ($file['short_name'] ?? '')));
$fl_col_max_len[3] = max($fl_col_max_len[3], mb_strlen((string) ($file['branch_name'] ?? '')));
$policy_display = trim(
(isset($file['policy_type']) ? $file['policy_type'] : '')
. ' - '
. (isset($file['policy_no']) ? $file['policy_no'] : '')
);
$fl_col_max_len[4] = max($fl_col_max_len[4], mb_strlen($policy_display));
$fl_col_max_len[5] = max($fl_col_max_len[5], mb_strlen((string) ($file['action'] ?? '')));
$userTime = change_date_format($file['created_at'] ?? '', 'Y-m-d H:i:s', 'd M Y h:i a')
. ' by '
. ($file['first_name'] ?? '');
$fl_col_max_len[6] = max($fl_col_max_len[6], mb_strlen($userTime));
$st = (string) ($file['status'] ?? '');
$fl_col_max_len[7] = max($fl_col_max_len[7], mb_strlen($st));
if ($st === 'inprogress' || $st === 'success') {
$fl_col_max_len[7] = max($fl_col_max_len[7], 12);
}
$fl_col_max_len[8] = max($fl_col_max_len[8], 4);
}
}
$fl_col_min_px = [48, 100, 72, 80, 120, 88, 160, 96, 72];
$fl_col_max_px = [64, 320, 180, 180, 360, 160, 320, 200, 88];
$fl_col_width_px = nhance_dt_column_widths_px($fl_header_labels, $fl_col_max_len, $fl_col_min_px, $fl_col_max_px);
?>
<style> <style>
.modal-full-width { .modal-full-width {
width: 95% !important; width: 95% !important;
@ -11,70 +52,114 @@
.column-header { margin-right: 10px; /* Adjust this value as needed */ } .column-header { margin-right: 10px; /* Adjust this value as needed */ }
/* Compact table + buttons (NHance) */ /* Compact table + buttons (NHance) */
#tickets-table thead th, #file-list-table tbody td {
#tickets-table tbody td {
padding: 6px 12px !important; padding: 6px 12px !important;
font-size: 13px; font-size: 13px;
line-height: 1.25; line-height: 1.25;
} }
#file-list-table_wrapper .dataTables_scrollHead table thead th,
#file-list-table thead th {
padding: 6px 2.35rem 6px 12px !important;
font-size: 13px;
line-height: 1.25;
}
#tickets-table .font-12 { #file-list-table .font-12 {
font-size: 12px; font-size: 12px;
} }
/* Action dropdown toggle in rows */ /* Action dropdown toggle in rows */
#tickets-table .dropdown-toggle.btn-sm { #file-list-table .dropdown-toggle.btn-sm {
padding: 4px 9px !important; padding: 4px 9px !important;
font-size: 13px; font-size: 13px;
line-height: 1.2; line-height: 1.2;
} }
/* DataTables toolbar buttons (Export/Filter/Clear Filter) */ /* DataTables toolbar buttons (Export/Filter/Clear Filter) */
#tickets-table_wrapper .dt-buttons .btn { #file-list-table_wrapper .dt-buttons .btn {
padding: 6px 13px !important; padding: 6px 13px !important;
font-size: 13px; font-size: 13px;
} }
#tickets-table_wrapper .dt-buttons .btn .btn-custom { #file-list-table_wrapper .dt-buttons .btn .btn-custom {
font-size: 13px; font-size: 13px;
} }
#tickets-table{ #file-list-table{
width: 100% !important; width: 100% !important;
} }
#tickets-table thead th{ #file-list-table thead th{
white-space: nowrap; white-space: nowrap;
vertical-align: middle; vertical-align: middle;
} }
#tickets-table_wrapper .datatable-search-wrapper{ #file-list-table_wrapper .datatable-search-wrapper{
width: auto !important; width: auto !important;
} }
#tickets-table_wrapper .dataTables_filter input{ #file-list-table_wrapper .dataTables_filter input{
padding-right: 34px !important; padding-right: 34px !important;
width: 220px !important; width: 220px !important;
} }
#tickets-table_wrapper .row.align-items-center{ #file-list-table_wrapper .row.align-items-center{
flex-wrap: nowrap; flex-wrap: nowrap;
} }
#tickets-table_wrapper .dataTables_info, #file-list-table_wrapper .dataTables_info,
#tickets-table_wrapper .dataTables_length, #file-list-table_wrapper .dataTables_length,
#tickets-table_wrapper .dataTables_paginate{ #file-list-table_wrapper .dataTables_paginate{
white-space: nowrap; white-space: nowrap;
} }
#tickets-table_wrapper .datatable-search-icon, #file-list-table_wrapper .datatable-search-icon,
#tickets-table_wrapper .datatable-clear-icon{ #file-list-table_wrapper .datatable-clear-icon{
right: 11px !important; right: 11px !important;
} }
#file-list-page .card-body > .table-responsive {
overflow-x: auto !important;
-webkit-overflow-scrolling: touch;
max-width: 100%;
}
</style>
<style>
<?php for ($i = 0; $i < $fl_col_count; $i++) : ?>
#file-list-table_wrapper .dataTables_scrollHead table thead th:nth-child(<?= $i + 1 ?>),
#file-list-table thead th:nth-child(<?= $i + 1 ?>) {
min-width: <?= (int) $fl_col_width_px[$i] ?>px;
width: <?= (int) $fl_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
overflow: visible !important;
}
#file-list-table tbody td:nth-child(<?= $i + 1 ?>) {
width: <?= (int) $fl_col_width_px[$i] ?>px;
max-width: <?= (int) $fl_col_width_px[$i] ?>px;
min-width: <?= (int) $fl_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
}
<?php endfor; ?>
#file-list-table tbody td:nth-child(1),
#file-list-table tbody td:nth-child(2),
#file-list-table tbody td:nth-child(3),
#file-list-table tbody td:nth-child(4),
#file-list-table tbody td:nth-child(5),
#file-list-table tbody td:nth-child(6),
#file-list-table tbody td:nth-child(7),
#file-list-table tbody td:nth-child(8) {
overflow: hidden;
text-overflow: ellipsis;
}
#file-list-table tbody td:nth-child(9) {
overflow: visible;
text-overflow: clip;
}
</style> </style>
<div class="col-12"> <div class="col-12" id="file-list-page">
<div class="card"> <div class="card">
<div class="card-body"> <div class="card-body">
<div class="row" style="padding-bottom: 10px;"> <div class="row" style="padding-bottom: 10px;">
@ -84,7 +169,7 @@
</div> </div>
<div class="table-responsive"> <div class="table-responsive">
<table data-custom-table-css="table" class="table mb-0 nowrap w-100 table-centered" cellspacing="0" id="tickets-table"> <table data-custom-table-css="table" class="table mb-0 nowrap w-100 table-centered" cellspacing="0" id="file-list-table">
<thead class="bg-light"> <thead class="bg-light">
<tr> <tr>
<th class="font-weight-medium"><div class="column-header">S.No</div></th> <th class="font-weight-medium"><div class="column-header">S.No</div></th>
@ -109,7 +194,7 @@
?> ?>
<tr> <tr>
<td class="text-center"><b><?php echo ($key + 1) ?></b></td> <td><b><?php echo ($key + 1) ?></b></td>
<td style="overflow: hidden;" class="reload truncate" data-toggle="tooltip" data-placement="top" title="<?php echo $file['file_name'] ?>"> <td style="overflow: hidden;" class="reload truncate" data-toggle="tooltip" data-placement="top" title="<?php echo $file['file_name'] ?>">
<?php echo $file['file_name']?> <?php echo $file['file_name']?>
</td> </td>
@ -524,11 +609,13 @@
$(document).ready(function() { $(document).ready(function() {
$('#tickets-table').DataTable({ nhanceListDataTableBeforeInit();
var nhFileListTable = $('#file-list-table').DataTable(nhanceMergeListDataTableOptions({
dom: "<'row'<'col-sm-7'f><'col-sm-5 text-right'B>>" + // Filter left, buttons right dom: "<'row'<'col-sm-7'f><'col-sm-5 text-right'B>>" +
"<'row'<'col-sm-12'tr>>" + "<'row'<'col-sm-12'tr>>" +
"<'row align-items-center'<'col-5 text-start'i><'col-7 d-flex justify-content-end align-items-center'<'me-2'l>p>>", lengthMenu: [[10, 20, 50, 100], [10, 20, 50, 100]], "<'row align-items-center'<'col-5 text-start'i><'col-7 d-flex justify-content-end align-items-center'<'me-2'l>p>>",
lengthMenu: [[10, 20, 50, 100], [10, 20, 50, 100]],
buttons: [ buttons: [
{ {
extend: 'collection', extend: 'collection',
@ -574,19 +661,15 @@
emptyTable: '<div class="text-center text-muted">No Data found</div>' emptyTable: '<div class="text-center text-muted">No Data found</div>'
}, },
paging: true, paging: true,
}); columnDefs: [
<?php for ($i = 0; $i < $fl_col_count; $i++) : ?>
{ targets: <?= $i ?>, width: '<?= (int) $fl_col_width_px[$i] ?>px' },
<?php endfor; ?>
],
}));
nhanceListDataTableAfterInit();
nhanceListDataTableBindAdjust(nhFileListTable);
setTimeout(function () {
const dt = $('#tickets-table').DataTable();
dt.columns.adjust().draw(false);
}, 0);
});
$(window).on('resize', function () {
if ($.fn.DataTable.isDataTable('#tickets-table')) {
$('#tickets-table').DataTable().columns.adjust();
}
}); });
</script> </script>

View File

@ -1,8 +1,72 @@
<?php
helper('datatable_view');
$fec_header_labels = ['S.No.', 'Type', 'Content Section', 'Heading', 'Status', 'Action'];
$fec_col_count = count($fec_header_labels);
$fec_col_max_len = array_fill(0, $fec_col_count, 0);
for ($i = 0; $i < $fec_col_count; $i++) {
$fec_col_max_len[$i] = mb_strlen($fec_header_labels[$i]);
}
$fec_rows = $data['fe_list'] ?? [];
$fec_sl = 0;
foreach ($fec_rows as $row) {
++$fec_sl;
$fec_col_max_len[0] = max($fec_col_max_len[0], mb_strlen((string) $fec_sl));
$fec_col_max_len[1] = max($fec_col_max_len[1], mb_strlen((string) ($row['type'] ?? '')));
$fec_col_max_len[2] = max($fec_col_max_len[2], mb_strlen((string) ($row['content_section'] ?? '')));
$fec_col_max_len[3] = max($fec_col_max_len[3], mb_strlen((string) ($row['heading'] ?? '')));
$fec_st = (isset($row['is_active']) && (int) $row['is_active'] === 1) ? 'Active' : 'In-Active';
$fec_col_max_len[4] = max($fec_col_max_len[4], mb_strlen($fec_st));
$fec_col_max_len[5] = max($fec_col_max_len[5], 4);
}
$fec_col_min_px = [48, 88, 120, 140, 88, 72];
$fec_col_max_px = [64, 200, 360, 480, 120, 88];
$fec_col_width_px = nhance_dt_column_widths_px($fec_header_labels, $fec_col_max_len, $fec_col_min_px, $fec_col_max_px);
?>
<style> <style>
.col-12 { .col-12 {
max-width: 98% !important; max-width: 98% !important;
} }
.dataTables_length label {height: 21px !important;} .dataTables_length label {height: 21px !important;}
<?php for ($i = 0; $i < $fec_col_count; $i++) : ?>
#frontend-content-list-table_wrapper .dataTables_scrollHead table thead th:nth-child(<?= $i + 1 ?>),
#frontend-content-list-table thead th:nth-child(<?= $i + 1 ?>) {
min-width: <?= (int) $fec_col_width_px[$i] ?>px;
width: <?= (int) $fec_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
overflow: visible !important;
}
#frontend-content-list-table tbody td:nth-child(<?= $i + 1 ?>) {
width: <?= (int) $fec_col_width_px[$i] ?>px;
max-width: <?= (int) $fec_col_width_px[$i] ?>px;
min-width: <?= (int) $fec_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
}
<?php endfor; ?>
#frontend-content-list-table tbody td:nth-child(1),
#frontend-content-list-table tbody td:nth-child(2),
#frontend-content-list-table tbody td:nth-child(3),
#frontend-content-list-table tbody td:nth-child(4),
#frontend-content-list-table tbody td:nth-child(5) {
overflow: hidden;
text-overflow: ellipsis;
}
#frontend-content-list-table tbody td:nth-child(6) {
overflow: visible;
text-overflow: clip;
}
#frontend-content-list-table tbody td {
padding: 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
#frontend-content-list-table thead th {
padding: 5px 2.35rem 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
</style> </style>
<!-- End ADD and EDIT Page HTML --> <!-- End ADD and EDIT Page HTML -->
@ -10,7 +74,7 @@
<div class="col-12"> <div class="col-12">
<div class="card"> <div class="card">
<div class="card-body"> <div class="card-body">
<table data-custom-table-css="table" class="table mb-0 nowrap" cellspacing="0" id="user-table"> <table data-custom-table-css="table" class="table mb-0 nowrap" cellspacing="0" id="frontend-content-list-table">
<thead class="bg-light"> <thead class="bg-light">
<tr> <tr>
<!-- `content` `notes` --> <!-- `content` `notes` -->
@ -26,7 +90,7 @@
<?php if(!empty($data['fe_list'])) { $slno = 1; ?> <?php if(!empty($data['fe_list'])) { $slno = 1; ?>
<?php foreach($data['fe_list'] as $index => $row) { ?> <?php foreach($data['fe_list'] as $index => $row) { ?>
<tr> <tr>
<td class="text-center"><?= $slno++; ?></td> <td><?= $slno++; ?></td>
<td><?= $row['type']; ?></td> <td><?= $row['type']; ?></td>
<td><?= $row['content_section']; ?></td> <td><?= $row['content_section']; ?></td>
<td><?= $row['heading']; ?></td> <td><?= $row['heading']; ?></td>
@ -268,9 +332,9 @@
$('#notes').parsley().validate(); $('#notes').parsley().validate();
}); });
var ticketsTable = $('#user-table'); var ticketsTable = $('#frontend-content-list-table');
table = ticketsTable.DataTable({ nhanceListDataTableBeforeInit();
scrollX: true, table = ticketsTable.DataTable(nhanceMergeListDataTableOptions({
// dom: "<'row'<'col-sm-7'f><'col-sm-5 text-right'B>>" + // Filter left, buttons right // dom: "<'row'<'col-sm-7'f><'col-sm-5 text-right'B>>" + // Filter left, buttons right
// "<'row'<'col-sm-12'tr>>" + // "<'row'<'col-sm-12'tr>>" +
// "<'row'<'col-sm-5'i><'col-sm-7'p>>", // Pagination at the bottom, without page length selector // "<'row'<'col-sm-5'i><'col-sm-7'p>>", // Pagination at the bottom, without page length selector
@ -322,14 +386,21 @@
paging: true, // Enable pagination paging: true, // Enable pagination
pageLength: 10, // Set default number of rows per page (optional) pageLength: 10, // Set default number of rows per page (optional)
// ordering: false, // ordering: false,
}); columnDefs: [
<?php for ($i = 0; $i < $fec_col_count; $i++) : ?>
{ targets: <?= $i ?>, width: '<?= (int) $fec_col_width_px[$i] ?>px' },
<?php endfor; ?>
],
}));
nhanceListDataTableAfterInit();
nhanceListDataTableBindAdjust(table);
function applyBottomRowDropup() { function applyBottomRowDropup() {
if (!table) return; if (!table) return;
const currentRows = table.rows({ page: 'current' }).nodes().toArray(); const currentRows = table.rows({ page: 'current' }).nodes().toArray();
$('#user-table tbody tr').removeClass('nh-force-dropup'); $('#frontend-content-list-table tbody tr').removeClass('nh-force-dropup');
$('#user-table tbody tr td.table-action-cell .btn-group.dropdown').removeClass('dropup'); $('#frontend-content-list-table tbody tr td.table-action-cell .btn-group.dropdown').removeClass('dropup');
const targetCount = Math.min(2, currentRows.length); const targetCount = Math.min(2, currentRows.length);
for (let i = 0; i < targetCount; i++) { for (let i = 0; i < targetCount; i++) {
@ -340,7 +411,7 @@
} }
} }
applyBottomRowDropup(); applyBottomRowDropup();
$('#user-table').on('draw.dt', applyBottomRowDropup); $('#frontend-content-list-table').on('draw.dt', applyBottomRowDropup);
}); });
$('.close').click(function(){ resetValues(); }) $('.close').click(function(){ resetValues(); })
@ -691,7 +762,7 @@
</script> </script>
<!-- <script> <!-- <script>
document.addEventListener("DOMContentLoaded", function() { document.addEventListener("DOMContentLoaded", function() {
const table = document.getElementById("user-table"); const table = document.getElementById("frontend-content-list-table");
// Create custom dropdown // Create custom dropdown
function createCustomDropdown(row) { function createCustomDropdown(row) {

View File

@ -1,3 +1,30 @@
<?php
helper('datatable_view');
$hr_header_labels = ['S.No', 'File name', 'Client', 'Client Branch', 'Policy', 'Event', 'User/Time', 'Status', 'Action'];
$hr_col_count = count($hr_header_labels);
$hr_col_max_len = array_fill(0, $hr_col_count, 0);
for ($i = 0; $i < $hr_col_count; $i++) {
$hr_col_max_len[$i] = mb_strlen($hr_header_labels[$i]);
}
$fileList = $fileList ?? [];
foreach ($fileList as $key => $file) {
$hr_col_max_len[0] = max($hr_col_max_len[0], mb_strlen((string) ($key + 1)));
$hr_col_max_len[1] = max($hr_col_max_len[1], mb_strlen((string) ($file['file_name'] ?? '')));
$hr_col_max_len[2] = max($hr_col_max_len[2], mb_strlen((string) ($file['short_name'] ?? '')));
$hr_col_max_len[3] = max($hr_col_max_len[3], mb_strlen((string) ($file['branch_name'] ?? '')));
$hr_col_max_len[4] = max($hr_col_max_len[4], mb_strlen((string) ($file['policy_no'] ?? '')));
$hr_col_max_len[5] = max($hr_col_max_len[5], mb_strlen((string) ($file['file_action'] ?? '')));
$userTimePlain = change_date_format($file['created_at'] ?? '', 'Y-m-d H:i:s', 'd M Y h:i A')
. ' by '
. (string) ($file['first_name'] ?? '');
$hr_col_max_len[6] = max($hr_col_max_len[6], mb_strlen($userTimePlain));
$hr_col_max_len[7] = max($hr_col_max_len[7], mb_strlen((string) ($file['status'] ?? '')));
$hr_col_max_len[8] = max($hr_col_max_len[8], 4);
}
$hr_col_min_px = [48, 120, 88, 96, 120, 88, 200, 96, 52];
$hr_col_max_px = [64, 480, 240, 240, 360, 200, 520, 200, 72];
$hr_col_width_px = nhance_dt_column_widths_px($hr_header_labels, $hr_col_max_len, $hr_col_min_px, $hr_col_max_px);
?>
<style> <style>
.table th, .table th,
.table td { .table td {
@ -53,6 +80,39 @@
background-color: #e0e0e0; background-color: #e0e0e0;
} }
<?php for ($i = 0; $i < $hr_col_count; $i++) : ?>
#hr_tickets_table_wrapper .dataTables_scrollHead table thead th:nth-child(<?= $i + 1 ?>),
#hr_tickets_table thead th:nth-child(<?= $i + 1 ?>) {
min-width: <?= (int) $hr_col_width_px[$i] ?>px;
width: <?= (int) $hr_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
overflow: visible !important;
}
#hr_tickets_table tbody td:nth-child(<?= $i + 1 ?>) {
width: <?= (int) $hr_col_width_px[$i] ?>px;
max-width: <?= (int) $hr_col_width_px[$i] ?>px;
min-width: <?= (int) $hr_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
}
<?php endfor; ?>
#hr_tickets_table tbody td:nth-child(1),
#hr_tickets_table tbody td:nth-child(2),
#hr_tickets_table tbody td:nth-child(3),
#hr_tickets_table tbody td:nth-child(4),
#hr_tickets_table tbody td:nth-child(5),
#hr_tickets_table tbody td:nth-child(6),
#hr_tickets_table tbody td:nth-child(7),
#hr_tickets_table tbody td:nth-child(8) {
overflow: hidden;
text-overflow: ellipsis;
}
#hr_tickets_table tbody td:nth-child(9) {
overflow: visible;
text-overflow: clip;
}
</style> </style>
<div class="tab-pane fade" id="HR-DOC-tab"> <div class="tab-pane fade" id="HR-DOC-tab">
@ -439,9 +499,8 @@
if (window.hrFileTableInstance) { if (window.hrFileTableInstance) {
return; return;
} }
window.hrFileTableInstance = $('#hr_tickets_table').DataTable({ nhanceListDataTableBeforeInit();
scrollX: false, window.hrFileTableInstance = $('#hr_tickets_table').DataTable(nhanceMergeListDataTableOptions({
autoWidth: false,
// dom: "<'row'<'col-12 d-flex justify-content-between align-items-center'<'datatable-search dataTables_filter'f><'datatable-buttons dt-buttons'B>>>" + // dom: "<'row'<'col-12 d-flex justify-content-between align-items-center'<'datatable-search dataTables_filter'f><'datatable-buttons dt-buttons'B>>>" +
// "<'row'<'col-sm-12'tr>>" + // "<'row'<'col-sm-12'tr>>" +
// "<'row'<'col-sm-5'i><'col-sm-7'p>>", // "<'row'<'col-sm-5'i><'col-sm-7'p>>",
@ -480,7 +539,14 @@
}, },
paging: true, paging: true,
ordering: false, ordering: false,
}); columnDefs: [
<?php for ($i = 0; $i < $hr_col_count; $i++) : ?>
{ targets: <?= $i ?>, width: '<?= (int) $hr_col_width_px[$i] ?>px' },
<?php endfor; ?>
],
}));
nhanceListDataTableAfterInit();
nhanceListDataTableBindAdjust(window.hrFileTableInstance);
$('.dataTables_filter input').css({ $('.dataTables_filter input').css({
'background': '#F0F0F0', 'background': '#F0F0F0',
'border': 'none', 'border': 'none',

View File

@ -1,3 +1,4 @@
<?php helper('datatable_view'); ?>
<style> <style>
.table th, .table th,
.table td { .table td {

View File

@ -170,8 +170,10 @@ input:checked + .slider:before {
<div class="input-icon"> <div class="input-icon">
<input type="file" class="form-control" id="insurer_logo" name="insurer_logo" <input type="file" class="form-control" id="insurer_logo" name="insurer_logo"
accept="image/jpeg, image/jpg, image/png" onchange="PreviewImage();" accept="image/jpeg, image/jpg, image/png" onchange="PreviewImage();"
data-parsley-max-file-size="200" data-parsley-insurer-max-file-size="200"
data-parsley-file-extension="jpg,jpeg,png" data-parsley-insurer-file-extension="jpg,jpeg,png"
data-parsley-insurer-max-file-size-message="File size should not exceed 200KB."
data-parsley-insurer-file-extension-message="Only JPG, JPEG, PNG files are allowed."
data-parsley-errors-container="#logo_error_container"> data-parsley-errors-container="#logo_error_container">
<i class="mdi mdi-upload additional-icon"></i> <i class="mdi mdi-upload additional-icon"></i>
</div> </div>
@ -204,8 +206,8 @@ input:checked + .slider:before {
<script> <script>
$(document).ready(function() { $(document).ready(function() {
// Custom Parsley validator for file size // Custom Parsley validator for insurer logo file size
window.Parsley.addValidator('maxFileSize', { window.Parsley.addValidator('insurerMaxFileSize', {
validateString: function(value, maxSize, parsleyInstance) { validateString: function(value, maxSize, parsleyInstance) {
if (!window.FileReader) { if (!window.FileReader) {
alert('Your browser does not support FileReader API, please upgrade.'); alert('Your browser does not support FileReader API, please upgrade.');
@ -223,8 +225,8 @@ input:checked + .slider:before {
} }
}); });
// Custom Parsley validator for file extension // Custom Parsley validator for insurer logo file extension
window.Parsley.addValidator('fileExtension', { window.Parsley.addValidator('insurerFileExtension', {
validateString: function(value, requirement, parsleyInstance) { validateString: function(value, requirement, parsleyInstance) {
var file = parsleyInstance.$element[0].files[0]; var file = parsleyInstance.$element[0].files[0];
if (!file) { return true; } // No file, so validation passes if (!file) { return true; } // No file, so validation passes
@ -239,12 +241,16 @@ input:checked + .slider:before {
}); });
$('#insurer_logo').on('change', function() { $('#insurer_logo').on('change', function() {
PreviewImage(); PreviewImage();
}); });
$("#insurer_general_form").submit(function(events) { $("#insurer_general_form").submit(function(events) {
events.preventDefault(); events.preventDefault();
if (!validateInsurerLogoFile(true)) {
return;
}
// var isValid = $('#insurer_General_PrimaryKey').parsley().validate(); // var isValid = $('#insurer_General_PrimaryKey').parsley().validate();
var isValid = $('#insurer_general_form').parsley().validate(); var isValid = $('#insurer_general_form').parsley().validate();
@ -357,22 +363,22 @@ input:checked + .slider:before {
var file = fileInput.files[0]; var file = fileInput.files[0];
var fileName = file.name.toLowerCase(); var fileName = file.name.toLowerCase();
var parts = fileName.split('.'); var parts = fileName.split('.');
$('#logo_error_container').empty();
// VALIDATION: Extensions and Double Extensions (e.g. .php.jpeg) // VALIDATION: Extensions and Double Extensions (e.g. .php.jpeg)
var allowedExtensions = /(\.jpg|\.jpeg|\.png)$/i; var allowedExtensions = /(\.jpg|\.jpeg|\.png)$/i;
if (!allowedExtensions.exec(fileName) || parts.length > 2) { if (!allowedExtensions.exec(fileName) || parts.length > 2) {
toastr.error("Security violation: Invalid format or double extension.", "Blocked"); toastr.error("Security violation: Invalid format or double extension.", "Blocked");
fileInput.value = ""; // Clear the field resetInsurerLogoInput();
preview.src = defaultAvatar; // RESET PREVIEW
return; return;
} }
// VALIDATION: Size (200KB) // VALIDATION: Size (200KB)
if ((file.size / 1024) > 200) { if ((file.size / 1024) > 200) {
toastr.warning("File size exceeds 200 KB limit.", "Warning"); toastr.warning("File size exceeds 200 KB limit.", "Warning");
fileInput.value = ""; // Clear the field resetInsurerLogoInput();
preview.src = defaultAvatar; // RESET PREVIEW
return; return;
} }
@ -383,6 +389,47 @@ input:checked + .slider:before {
preview.src = oFREvent.target.result; preview.src = oFREvent.target.result;
}; };
} }
function resetInsurerLogoInput() {
var fileInput = document.getElementById("insurer_logo");
var preview = document.getElementById("uploadPreview");
fileInput.value = "";
preview.src = '<?= base_url() . "public/assets/images/avatar_2x.png" ?>';
$('#logo_error_container').empty();
}
function validateInsurerLogoFile(showToastr) {
var fileInput = document.getElementById("insurer_logo");
if (!fileInput.files || !fileInput.files[0]) {
return true;
}
var file = fileInput.files[0];
var fileName = file.name.toLowerCase();
var parts = fileName.split('.');
var allowedExtensions = /(\.jpg|\.jpeg|\.png)$/i;
if (!allowedExtensions.exec(fileName) || parts.length > 2) {
$('#logo_error_container').html('<ul class="parsley-errors-list filled"><li class="parsley-required">Only JPG, JPEG, PNG files are allowed.</li></ul>');
if (showToastr) {
toastr.warning("Only JPG, JPEG, PNG files are allowed.", "Invalid file type");
}
resetInsurerLogoInput();
return false;
}
if ((file.size / 1024) > 200) {
$('#logo_error_container').html('<ul class="parsley-errors-list filled"><li class="parsley-required">File size should not exceed 200KB.</li></ul>');
if (showToastr) {
toastr.warning("File size should not exceed 200KB.", "Invalid file size");
}
resetInsurerLogoInput();
return false;
}
$('#logo_error_container').empty();
return true;
}
//----------------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------------

View File

@ -106,12 +106,17 @@
<div class="form-group col-md-6"> <div class="form-group col-md-6">
<label for="branch_name">Branch Name <span class="text-danger">*</span></label> <label for="branch_name">Branch Name <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="branch_name" <input type="text" class="form-control" id="branch_name"
placeholder="Enter Branch Name" name="branch_name" required> placeholder="Enter Branch Name" name="branch_name" required
data-parsley-minlength="3"
data-parsley-pattern="^[a-zA-Z0-9\\s_-]+$"
data-parsley-pattern-message="Branch Name can contain letters, numbers, spaces, underscore (_) and hyphen (-).">
</div> </div>
<div class="form-group col-md-6"> <div class="form-group col-md-6">
<label for="branch_code">Branch Code <span class="text-danger">*</span></label> <label for="branch_code">Branch Code <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="branch_code" <input type="text" class="form-control" id="branch_code"
placeholder="Enter Branch Code" name="branch_code" required> placeholder="Enter Branch Code" name="branch_code" required
data-parsley-pattern="^[a-zA-Z0-9_-]+$"
data-parsley-pattern-message="Branch Code can contain letters, numbers, underscore (_) and hyphen (-).">
</div> </div>
</div> </div>
@ -141,7 +146,9 @@
<div class="form-group col-md-6"> <div class="form-group col-md-6">
<label for="district">District <span class="text-danger">*</span></label> <label for="district">District <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="district" <input type="text" class="form-control" id="district"
placeholder="Enter District" name="district" required> placeholder="Enter District" name="district" required
data-parsley-pattern="^[a-zA-Z0-9\\s-]+$"
data-parsley-pattern-message="District can contain letters, numbers, spaces, and hyphens.">
</div> </div>
</div> </div>
@ -150,11 +157,15 @@
<div class="form-group col-md-6"> <div class="form-group col-md-6">
<label for="branch_city">City <span class="text-danger">*</span></label> <label for="branch_city">City <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="branch_city" <input type="text" class="form-control" id="branch_city"
placeholder="Enter City" name="city" required> placeholder="Enter City" name="city" required
data-parsley-pattern="^[a-zA-Z0-9\\s-]+$"
data-parsley-pattern-message="City can contain letters, numbers, spaces, and hyphens.">
</div> </div>
<div class="form-group col-md-6"> <div class="form-group col-md-6">
<label for="pincode">Pincode <span class="text-danger">*</span></label> <label for="pincode">Pincode <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="pincode" placeholder="Enter Pincode" name="pincode" required maxlength="6" inputmode="numeric"> <input type="text" class="form-control" id="pincode" placeholder="Enter Pincode" name="pincode" required maxlength="6" inputmode="numeric"
data-parsley-pattern="^[0-9]{6}$"
data-parsley-pattern-message="Pincode must be exactly 6 digits.">
</div> </div>
</div> </div>
@ -185,19 +196,25 @@
<!-- <input type="hidden" name="primarykey[]" id="contact_id_1" value=""/> --> <!-- <input type="hidden" name="primarykey[]" id="contact_id_1" value=""/> -->
<div class="form-group col-md-12"> <div class="form-group col-md-12">
<label for="name">Name <span class="text-danger">*</span></label> <label for="name">Name <span class="text-danger">*</span></label>
<input value="" type="text" class="form-control" placeholder="Enter Contact Name" name="name[]" id="name" required> <input value="" type="text" class="form-control" placeholder="Enter Contact Name" name="name[]" id="name" required
data-parsley-pattern="^[A-Za-z\\s]+$"
data-parsley-pattern-message="Contact name may contain only letters and spaces.">
</div> </div>
</div> </div>
<div class="form-row"> <div class="form-row">
<div class="form-group col-md-12"> <div class="form-group col-md-12">
<label for="designation">Designation <span class="text-danger">*</span></label> <label for="designation">Designation <span class="text-danger">*</span></label>
<input value="" type="text" class="form-control" placeholder="Enter Designation Name" name="designation[]" id="designation" required> <input value="" type="text" class="form-control" placeholder="Enter Designation Name" name="designation[]" id="designation" required
data-parsley-pattern="^[A-Za-z0-9\\-_\\/ ]+$"
data-parsley-pattern-message="Designation may only contain letters, numbers, /, -, _ and spaces.">
</div> </div>
</div> </div>
<div class="form-row"> <div class="form-row">
<div class="form-group col-md-12"> <div class="form-group col-md-12">
<label for="email">Email <span class="text-danger">*</span></label> <label for="email">Email <span class="text-danger">*</span></label>
<input value="" type="email" data-parsley-type="email" data-parsley-trigger="change"class="form-control" placeholder="Enter Contact Email" name="email[]" id="email" required> <input value="" type="email" data-parsley-trigger="change" class="form-control" placeholder="Enter Contact Email" name="email[]" id="email" required
data-parsley-pattern="^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
data-parsley-pattern-message="Please enter a valid email format (e.g., name@domain.com).">
</div> </div>
</div> </div>
<div class="form-row"> <div class="form-row">
@ -435,8 +452,11 @@
switch (key) { switch (key) {
case 'branch_name': case 'branch_name':
if (v.length < 3) return 'Branch Name must be at least 3 characters.';
if (!/^[a-zA-Z0-9\s_-]+$/.test(v)) return 'Branch Name can contain letters, numbers, spaces, underscore (_) and hyphen (-).';
return ''; return '';
case 'branch_code': case 'branch_code':
if (!/^[a-zA-Z0-9_-]+$/.test(v)) return 'Branch Code can contain letters, numbers, underscore (_) and hyphen (-).';
return ''; return '';
case 'address1': case 'address1':
return ''; return '';
@ -458,6 +478,7 @@
if (!contactNamePattern.test(v)) return 'Contact name is invalid Format'; if (!contactNamePattern.test(v)) return 'Contact name is invalid Format';
return ''; return '';
case 'designation': case 'designation':
if (!/^[A-Za-z0-9\-_\/ ]+$/.test(v)) return 'Designation may only contain letters, numbers, /, -, _ and spaces.';
return ''; return '';
case 'email': case 'email':
if (!emailPattern.test(v)) return 'Please enter a valid email format (e.g., name@domain.com).'; if (!emailPattern.test(v)) return 'Please enter a valid email format (e.g., name@domain.com).';
@ -946,19 +967,25 @@
<div class="form-row"> <div class="form-row">
<div class="form-group col-md-12"> <div class="form-group col-md-12">
<label>Name<span class="text-danger">*</span></label> <label>Name<span class="text-danger">*</span></label>
<input value="${contact ? contact.name : ''}" type="text" class="form-control" placeholder="Enter Contact Name" name="name[]" required> <input value="${contact ? contact.name : ''}" type="text" class="form-control" placeholder="Enter Contact Name" name="name[]" required
data-parsley-pattern="^[A-Za-z\\s]+$"
data-parsley-pattern-message="Contact name may contain only letters and spaces.">
</div> </div>
</div> </div>
<div class="form-row"> <div class="form-row">
<div class="form-group col-md-12"> <div class="form-group col-md-12">
<label>Designation<span class="text-danger">*</span></label> <label>Designation<span class="text-danger">*</span></label>
<input value="${contact ? contact.designation : ''}" type="text" class="form-control" placeholder="Enter Designation Name" name="designation[]" required> <input value="${contact ? contact.designation : ''}" type="text" class="form-control" placeholder="Enter Designation Name" name="designation[]" required
data-parsley-pattern="^[A-Za-z0-9\\-_\\/ ]+$"
data-parsley-pattern-message="Designation may only contain letters, numbers, /, -, _ and spaces.">
</div> </div>
</div> </div>
<div class="form-row"> <div class="form-row">
<div class="form-group col-md-12"> <div class="form-group col-md-12">
<label>Email<span class="text-danger">*</span></label> <label>Email<span class="text-danger">*</span></label>
<input value="${contact ? contact.email : ''}" type="email" data-parsley-type="email" data-parsley-trigger="change"class="form-control" placeholder="Enter Contact Email" name="email[]" required> <input value="${contact ? contact.email : ''}" type="email" data-parsley-trigger="change" class="form-control" placeholder="Enter Contact Email" name="email[]" required
data-parsley-pattern="^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
data-parsley-pattern-message="Please enter a valid email format (e.g., name@domain.com).">
</div> </div>
</div> </div>
<div class="form-row"> <div class="form-row">

View File

@ -111,7 +111,7 @@
<?php if(isset($insurer_templete_list)){ ?> <?php if(isset($insurer_templete_list)){ ?>
<?php foreach($insurer_templete_list as $key => $value ){ ?> <?php foreach($insurer_templete_list as $key => $value ){ ?>
<tr> <tr>
<td class="text-center"><?= $key+1; ?></td> <td><?= $key+1; ?></td>
<td><?= $value['policy_type']; ?></td> <td><?= $value['policy_type']; ?></td>
<td><?= $events[$value['event_name']]; ?></td> <td><?= $events[$value['event_name']]; ?></td>
<td><?= $value['type_name'] == 'import' ? 'Upload' : 'Download'; ?></td> <td><?= $value['type_name'] == 'import' ? 'Upload' : 'Download'; ?></td>

View File

@ -1,3 +1,24 @@
<?php
helper('datatable_view');
$insurerList = $insurerList ?? [];
$ins_header_labels = ['Name', 'Type', 'Action'];
$ins_col_count = count($ins_header_labels);
$ins_col_max_len = array_fill(0, $ins_col_count, 0);
for ($i = 0; $i < $ins_col_count; $i++) {
$ins_col_max_len[$i] = mb_strlen($ins_header_labels[$i]);
}
if (is_array($insurerList)) {
foreach ($insurerList as $row) {
$nameCell = trim(($row['name'] ?? '') . ' ( ' . ($row['short_name'] ?? '') . ' )');
$ins_col_max_len[0] = max($ins_col_max_len[0], mb_strlen($nameCell));
$ins_col_max_len[1] = max($ins_col_max_len[1], mb_strlen((string) ($row['type'] ?? '')));
$ins_col_max_len[2] = max($ins_col_max_len[2], 4);
}
}
$ins_col_min_px = [120, 88, 72];
$ins_col_max_px = [560, 240, 96];
$ins_col_width_px = nhance_dt_column_widths_px($ins_header_labels, $ins_col_max_len, $ins_col_min_px, $ins_col_max_px);
?>
<style> <style>
.btn-color { .btn-color {
background-color: rgba(52, 174, 178, 1); background-color: rgba(52, 174, 178, 1);
@ -18,6 +39,44 @@
} }
</style> </style>
<style>
<?php for ($i = 0; $i < $ins_col_count; $i++) : ?>
#insurer-list-table_wrapper .dataTables_scrollHead table thead th:nth-child(<?= $i + 1 ?>),
#insurer-list-table thead th:nth-child(<?= $i + 1 ?>) {
min-width: <?= (int) $ins_col_width_px[$i] ?>px;
width: <?= (int) $ins_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
overflow: visible !important;
}
#insurer-list-table tbody td:nth-child(<?= $i + 1 ?>) {
width: <?= (int) $ins_col_width_px[$i] ?>px;
max-width: <?= (int) $ins_col_width_px[$i] ?>px;
min-width: <?= (int) $ins_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
}
<?php endfor; ?>
#insurer-list-table tbody td:not(:last-child) {
overflow: hidden;
text-overflow: ellipsis;
}
#insurer-list-table tbody td:last-child {
overflow: visible;
text-overflow: clip;
}
#insurer-list-table tbody td {
padding: 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
#insurer-list-table_wrapper .dataTables_scrollHead table thead th,
#insurer-list-table thead th {
padding: 5px 2.35rem 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
</style>
<div class="container-fluid-min"> <div class="container-fluid-min">
<div class="row" id="insurer_list"> <div class="row" id="insurer_list">
@ -30,7 +89,7 @@
</div> </div>
</div> --> </div> -->
<table data-custom-table-css="table" class="table mb-0 nowrap" cellspacing="0" <table data-custom-table-css="table" class="table mb-0 nowrap" cellspacing="0"
id="tickets-table"> id="insurer-list-table">
<thead class="bg-light"> <thead class="bg-light">
<tr> <tr>
<th class="font-weight-medium">Name&nbsp;</th> <th class="font-weight-medium">Name&nbsp;</th>
@ -71,10 +130,8 @@
<script> <script>
$(document).ready(function() { $(document).ready(function() {
var table = $('#tickets-table').DataTable({ nhanceListDataTableBeforeInit();
// dom: "<'row'<'col-12 d-flex justify-content-between align-items-center'<'datatable-search dataTables_filter'f><'datatable-buttons dt-buttons'B>>>" + var table = $('#insurer-list-table').DataTable(nhanceMergeListDataTableOptions({
// "<'row'<'col-sm-12'tr>>" +
// "<'row'<'col-sm-5'i><'col-sm-7'p>>",
dom: "<'row'<'col-12 d-flex justify-content-between align-items-center'<'datatable-search dataTables_filter'f><'datatable-buttons dt-buttons'B>>>" + dom: "<'row'<'col-12 d-flex justify-content-between align-items-center'<'datatable-search dataTables_filter'f><'datatable-buttons dt-buttons'B>>>" +
"<'row'<'col-sm-12'tr>>" + "<'row'<'col-sm-12'tr>>" +
"<'row align-items-center'<'col-5 text-start'i><'col-7 d-flex justify-content-end align-items-center'<'me-2'l>p>>", "<'row align-items-center'<'col-5 text-start'i><'col-7 d-flex justify-content-end align-items-center'<'me-2'l>p>>",
@ -121,14 +178,21 @@
} }
}, },
paging: true, paging: true,
}); columnDefs: [
<?php for ($i = 0; $i < $ins_col_count; $i++) : ?>
{ targets: <?= $i ?>, width: '<?= (int) $ins_col_width_px[$i] ?>px' },
<?php endfor; ?>
],
}));
nhanceListDataTableAfterInit();
nhanceListDataTableBindAdjust(table);
function applyBottomRowDropup() { function applyBottomRowDropup() {
if (!table) return; if (!table) return;
const currentRows = table.rows({ page: 'current' }).nodes().toArray(); const currentRows = table.rows({ page: 'current' }).nodes().toArray();
$('#tickets-table tbody tr').removeClass('nh-force-dropup'); $('#insurer-list-table tbody tr').removeClass('nh-force-dropup');
$('#tickets-table tbody tr td.table-action-cell .btn-group.dropdown').removeClass('dropup'); $('#insurer-list-table tbody tr td.table-action-cell .btn-group.dropdown').removeClass('dropup');
const targetCount = Math.min(2, currentRows.length); const targetCount = Math.min(2, currentRows.length);
for (let i = 0; i < targetCount; i++) { for (let i = 0; i < targetCount; i++) {
@ -139,7 +203,7 @@
} }
} }
applyBottomRowDropup(); applyBottomRowDropup();
$('#tickets-table').on('draw.dt', applyBottomRowDropup); $('#insurer-list-table').on('draw.dt', applyBottomRowDropup);
}) })

View File

@ -1,3 +1,31 @@
<?php
helper('datatable_view');
$isl_header_labels = [' ', 'Insurer', 'Month', 'Statement sno', 'Filename', 'Line items', 'File status', 'Invoice status', 'User/Time', 'Action'];
$isl_col_count = count($isl_header_labels);
$isl_col_max_len = array_fill(0, $isl_col_count, 0);
for ($i = 0; $i < $isl_col_count; $i++) {
$isl_col_max_len[$i] = mb_strlen($isl_header_labels[$i]);
}
$insurer_statement_list = $insurer_statement_list ?? [];
$invoice_status_array = $invoice_status_array ?? [];
foreach ($insurer_statement_list as $row) {
$isl_col_max_len[0] = max($isl_col_max_len[0], 2);
$isl_col_max_len[1] = max($isl_col_max_len[1], mb_strlen((string) (($row['short_name'] ?? '') . '-' . ($row['branch_code'] ?? ''))));
$isl_col_max_len[2] = max($isl_col_max_len[2], mb_strlen((string) change_date_format($row['month'] ?? '', 'Y-m-d', 'M-Y')));
$isl_col_max_len[3] = max($isl_col_max_len[3], mb_strlen((string) ($row['stmt_sno'] ?? '')));
$isl_col_max_len[4] = max($isl_col_max_len[4], mb_strlen((string) ($row['file_name'] ?? '')));
$isl_col_max_len[5] = max($isl_col_max_len[5], mb_strlen((string) ($row['line_items'] ?? '')));
$isl_col_max_len[6] = max($isl_col_max_len[6], mb_strlen((string) ($row['file_status'] ?? '')));
$invLabel = isset($invoice_status_array[$row['invoice_status'] ?? '']) ? (string) $invoice_status_array[$row['invoice_status']] : ' - ';
$isl_col_max_len[7] = max($isl_col_max_len[7], mb_strlen($invLabel));
$ut = change_date_format($row['created_at'] ?? '', 'Y-m-d H:i:s', 'd M Y h:i A') . ' by ' . ($row['first_name'] ?? '');
$isl_col_max_len[8] = max($isl_col_max_len[8], mb_strlen($ut));
$isl_col_max_len[9] = max($isl_col_max_len[9], 4);
}
$isl_col_min_px = [40, 120, 88, 88, 120, 72, 88, 120, 200, 72];
$isl_col_max_px = [56, 320, 120, 140, 480, 120, 160, 200, 560, 88];
$isl_col_width_px = nhance_dt_column_widths_px($isl_header_labels, $isl_col_max_len, $isl_col_min_px, $isl_col_max_px);
?>
<style> <style>
.table th, .table th,
.table td { .table td {
@ -179,6 +207,52 @@
} }
</style> </style>
<style>
<?php for ($i = 0; $i < $isl_col_count; $i++) : ?>
#insurer-statement-list-table_wrapper .dataTables_scrollHead table thead th:nth-child(<?= $i + 1 ?>),
#insurer-statement-list-table thead th:nth-child(<?= $i + 1 ?>) {
min-width: <?= (int) $isl_col_width_px[$i] ?>px;
width: <?= (int) $isl_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
overflow: visible !important;
}
#insurer-statement-list-table tbody td:nth-child(<?= $i + 1 ?>) {
width: <?= (int) $isl_col_width_px[$i] ?>px;
max-width: <?= (int) $isl_col_width_px[$i] ?>px;
min-width: <?= (int) $isl_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
}
<?php endfor; ?>
#insurer-statement-list-table tbody td:nth-child(1),
#insurer-statement-list-table tbody td:nth-child(2),
#insurer-statement-list-table tbody td:nth-child(3),
#insurer-statement-list-table tbody td:nth-child(4),
#insurer-statement-list-table tbody td:nth-child(5),
#insurer-statement-list-table tbody td:nth-child(6),
#insurer-statement-list-table tbody td:nth-child(7),
#insurer-statement-list-table tbody td:nth-child(8),
#insurer-statement-list-table tbody td:nth-child(9) {
overflow: hidden;
text-overflow: ellipsis;
}
#insurer-statement-list-table tbody td:nth-child(10) {
overflow: visible;
text-overflow: clip;
}
#insurer-statement-list-table tbody td {
padding: 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
#insurer-statement-list-table thead th {
padding: 5px 2.35rem 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
</style>
<div class="container-fluid-min"> <div class="container-fluid-min">
<div class="row" id="inception_list"> <div class="row" id="inception_list">
@ -187,7 +261,7 @@
<div class="card-body"> <div class="card-body">
<div class="table-responsive"> <div class="table-responsive">
<table data-custom-table-css="table" class="table table-striped mb-0 nowrap" cellspacing="0" id="tickets-table"> <table data-custom-table-css="table" class="table table-striped mb-0 nowrap" cellspacing="0" id="insurer-statement-list-table">
<thead class="bg-light"> <thead class="bg-light">
<tr> <tr>
<th class="no-sort"></th> <th class="no-sort"></th>
@ -540,7 +614,7 @@
</div> </div>
<script> <script>
document.addEventListener("DOMContentLoaded", function() { document.addEventListener("DOMContentLoaded", function() {
const table = document.getElementById("tickets-table"); const table = document.getElementById("insurer-statement-list-table");
// Create custom dropdown // Create custom dropdown
function createCustomDropdown(row) { function createCustomDropdown(row) {
@ -1773,7 +1847,8 @@
// Initialize DataTable // Initialize DataTable
// Change Comment: Added dom and buttons properties to arrange search, switch, and upload button on a single line, similar to client_list.php. // Change Comment: Added dom and buttons properties to arrange search, switch, and upload button on a single line, similar to client_list.php.
const table = $('#tickets-table').DataTable({ nhanceListDataTableBeforeInit();
const table = $('#insurer-statement-list-table').DataTable(nhanceMergeListDataTableOptions({
dom: "<'row'<'col-12 d-flex justify-content-between align-items-center'<'datatable-search dataTables_filter'f><'datatable-buttons dt-buttons'B>>>" + dom: "<'row'<'col-12 d-flex justify-content-between align-items-center'<'datatable-search dataTables_filter'f><'datatable-buttons dt-buttons'B>>>" +
"<'row'<'col-sm-12'tr>>" + "<'row'<'col-sm-12'tr>>" +
"<'row align-items-center'<'col-5 text-start'i><'col-7 d-flex justify-content-end align-items-center'<'me-2'l>p>>", "<'row align-items-center'<'col-5 text-start'i><'col-7 d-flex justify-content-end align-items-center'<'me-2'l>p>>",
@ -1803,8 +1878,15 @@
`, `,
searchPlaceholder: "Search", searchPlaceholder: "Search",
emptyTable: '<div class="text-center text-muted">No Data found</div>' emptyTable: '<div class="text-center text-muted">No Data found</div>'
} },
}); columnDefs: [
<?php for ($i = 0; $i < $isl_col_count; $i++) : ?>
{ targets: <?= $i ?>, width: '<?= (int) $isl_col_width_px[$i] ?>px' },
<?php endfor; ?>
]
}));
nhanceListDataTableAfterInit();
nhanceListDataTableBindAdjust(table);
// Change Comment: Prepending the 'Failed Status' switch to the DataTable's button container to group it with other controls. // Change Comment: Prepending the 'Failed Status' switch to the DataTable's button container to group it with other controls.
$(".datatable-buttons").prepend(` $(".datatable-buttons").prepend(`

View File

@ -56,12 +56,17 @@ table.dataTable tbody td { padding: 4px 4px !important; }
</style> </style>
<script>
var pageHideMainNavTitle = true;
var pageTitle = 'Invoice Details';
var pageBackButton = '<a href="javascript:void(0);" onclick="history.back();" class="topbar-icon-btn" title="Back"><i class="ri-arrow-left-s-line"></i></a>';
</script>
<!-- ---- HTML structure remains mostly same ---- --> <!-- ---- HTML structure remains mostly same ---- -->
<div class="row" id="invoices_details"> <div class="row mt-3" id="invoices_details" style="margin-top:42px !important;">
<div class="col-12"> <div class="col-12">
<div id="invoices_accordion" class="ml-3"> <div id="invoices_accordion" class="ml-3">
<div class="card mb-1"> <div class="card mb-1">
<h4 class="m-1"> <!-- <h4 class="m-1">
<a href="#" onclick="history.back(); return false;"> <a href="#" onclick="history.back(); return false;">
<i style="font-size: 18px;" class="mdi mdi-chevron-left" title="Back"></i> <i style="font-size: 18px;" class="mdi mdi-chevron-left" title="Back"></i>
</a> </a>
@ -70,7 +75,7 @@ table.dataTable tbody td { padding: 4px 4px !important; }
aria-expanded="true"> aria-expanded="true">
<i id="icon" class="mdi mdi-chevron-down mr-1 text-primary" style="font-size: 28px;"></i> <i id="icon" class="mdi mdi-chevron-down mr-1 text-primary" style="font-size: 28px;"></i>
</a> </a>
</h4> </h4> -->
<div id="collapseOne" class="collapse show" aria-labelledby="headingOne" data-parent="#invoices_accordion"> <div id="collapseOne" class="collapse show" aria-labelledby="headingOne" data-parent="#invoices_accordion">
<div class="card-body" style="padding-bottom: unset;"> <div class="card-body" style="padding-bottom: unset;">

View File

@ -359,7 +359,7 @@ body {
$page_break_class = (($serial % $records_per_page) == 0 && $serial != count($policies)) ? 'page-break' : ''; $page_break_class = (($serial % $records_per_page) == 0 && $serial != count($policies)) ? 'page-break' : '';
?> ?>
<tr class="<?= $page_break_class ?>"> <tr class="<?= $page_break_class ?>">
<td class="text-center"><?= $serial ?></td> <td><?= $serial ?></td>
<td><?= $policy['policy_no'] ?></td> <td><?= $policy['policy_no'] ?></td>
<td><?= $policy['customer_name'] ?></td> <td><?= $policy['customer_name'] ?></td>
<td class="text-right"><?= number_format($policy['premium'], 2) ?></td> <td class="text-right"><?= number_format($policy['premium'], 2) ?></td>

View File

@ -1,3 +1,22 @@
<?php
helper('datatable_view');
$kyc_header_labels = ['Name', 'Action'];
$kyc_col_count = count($kyc_header_labels);
$kyc_col_max_len = array_fill(0, $kyc_col_count, 0);
for ($i = 0; $i < $kyc_col_count; $i++) {
$kyc_col_max_len[$i] = mb_strlen($kyc_header_labels[$i]);
}
$kycList = $kycList ?? [];
if (is_array($kycList)) {
foreach ($kycList as $row) {
$kyc_col_max_len[0] = max($kyc_col_max_len[0], mb_strlen((string) ($row['name'] ?? '')));
$kyc_col_max_len[1] = max($kyc_col_max_len[1], 4);
}
}
$kyc_col_min_px = [160, 72];
$kyc_col_max_px = [480, 88];
$kyc_col_width_px = nhance_dt_column_widths_px($kyc_header_labels, $kyc_col_max_len, $kyc_col_min_px, $kyc_col_max_px);
?>
<style> <style>
.custom-dropdown-menu { .custom-dropdown-menu {
@ -40,6 +59,44 @@
} }
.dataTables_length label {height: 21px !important;} .dataTables_length label {height: 21px !important;}
</style> </style>
<style>
<?php for ($i = 0; $i < $kyc_col_count; $i++) : ?>
#kyc-list-table_wrapper .dataTables_scrollHead table thead th:nth-child(<?= $i + 1 ?>),
#kyc-list-table thead th:nth-child(<?= $i + 1 ?>) {
min-width: <?= (int) $kyc_col_width_px[$i] ?>px;
width: <?= (int) $kyc_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
overflow: visible !important;
}
#kyc-list-table tbody td:nth-child(<?= $i + 1 ?>) {
width: <?= (int) $kyc_col_width_px[$i] ?>px;
max-width: <?= (int) $kyc_col_width_px[$i] ?>px;
min-width: <?= (int) $kyc_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
}
<?php endfor; ?>
#kyc-list-table tbody td:first-child {
overflow: hidden;
text-overflow: ellipsis;
}
#kyc-list-table tbody td:last-child {
overflow: visible;
text-overflow: clip;
}
#kyc-list-table tbody td {
padding: 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
#kyc-list-table thead th {
padding: 5px 2.35rem 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
</style>
<div class="row" id="kyc_list"> <div class="row" id="kyc_list">
<div class="col-12"> <div class="col-12">
<div class="card"> <div class="card">
@ -50,7 +107,7 @@
</div> </div>
</div> --> </div> -->
<table data-custom-table-css="table" class="table table-sm table-hover m-0 table-centered dt-responsive nowrap w-100" cellspacing="0" <table data-custom-table-css="table" class="table table-sm table-hover m-0 table-centered dt-responsive nowrap w-100" cellspacing="0"
id="tickets-table"> id="kyc-list-table">
<thead class="bg-light"> <thead class="bg-light">
<tr> <tr>
<th class="font-weight-medium">Name</th> <th class="font-weight-medium">Name</th>
@ -83,7 +140,7 @@
<!-- end row --> <!-- end row -->
<script> <script>
document.addEventListener("DOMContentLoaded", function () { document.addEventListener("DOMContentLoaded", function () {
const table = document.getElementById("tickets-table"); const table = document.getElementById("kyc-list-table");
// Create custom dropdown // Create custom dropdown
function createCustomDropdown(row) { function createCustomDropdown(row) {
@ -174,7 +231,8 @@
$(document).ready(function(){ $(document).ready(function(){
$('#tickets-table').DataTable({ nhanceListDataTableBeforeInit();
var nhKycTable = $('#kyc-list-table').DataTable(nhanceMergeListDataTableOptions({
// dom: "<'row'<'col-12 d-flex justify-content-between align-items-center'<'datatable-search dataTables_filter'f><'datatable-buttons dt-buttons'B>>>" + // dom: "<'row'<'col-12 d-flex justify-content-between align-items-center'<'datatable-search dataTables_filter'f><'datatable-buttons dt-buttons'B>>>" +
// "<'row'<'col-sm-12'tr>>" + // "<'row'<'col-sm-12'tr>>" +
@ -221,12 +279,19 @@
emptyTable: '<div class="text-center text-muted">No Data found</div>' emptyTable: '<div class="text-center text-muted">No Data found</div>'
}, },
paging: true , paging: true ,
}); columnDefs: [
<?php for ($i = 0; $i < $kyc_col_count; $i++) : ?>
{ targets: <?= $i ?>, width: '<?= (int) $kyc_col_width_px[$i] ?>px' },
<?php endfor; ?>
],
}));
nhanceListDataTableAfterInit();
nhanceListDataTableBindAdjust(nhKycTable);
}) })
const btnExport = document.querySelector("#btnExport"); const btnExport = document.querySelector("#btnExport");
const tableElement = document.querySelector("#tickets-table"); const tableElement = document.querySelector("#kyc-list-table");
btnExport.addEventListener("click", () => { btnExport.addEventListener("click", () => {
const obj = new csvExport(tableElement); const obj = new csvExport(tableElement);

View File

@ -100,11 +100,17 @@
var $ = jQuery; var $ = jQuery;
// Global defaults for all list pages unless overridden in a specific view. // Global defaults for all list pages unless overridden in a specific view.
// Use horizontal scroll (scrollX) instead of Responsive (+/- child rows). // scrollY + scrollCollapse split thead/tbody and misalign columns vs headers (see batch_list).
// Wide tables: rely on .table-responsive; set scrollX: true on a page only if required.
$.extend(true, $.fn.dataTable.defaults, { $.extend(true, $.fn.dataTable.defaults, {
scrollX: true, scrollX: false,
scrollY: '55vh', scrollY: false,
scrollCollapse: true, scrollCollapse: false,
bScrollCollapse: false,
/* Hungarian names — copied into oScroll before the wrapper is built (preInit.dt is too late). */
sScrollX: "",
sScrollY: "",
sScrollXInner: "",
autoWidth: false, autoWidth: false,
pageLength: 10, pageLength: 10,
lengthMenu: [[10, 20, 50, 100], [10, 20, 50, 100]], lengthMenu: [[10, 20, 50, 100], [10, 20, 50, 100]],
@ -116,7 +122,9 @@
} }
}); });
// Per-table init can still pass responsive: true; force off so every list uses scrollX, not +/- rows. // responsive: false for all tables (row-collapse mode off).
// Note: preInit.dt runs *after* pb() in DT 1.10.x, so it cannot disable scroll split; use sScrollX/sScrollY
// in defaults + nhanceMergeListDataTableOptions instead.
$(document).on('preInit.dt', function (e, settings) { $(document).on('preInit.dt', function (e, settings) {
if (settings && settings.oInit) { if (settings && settings.oInit) {
settings.oInit.responsive = false; settings.oInit.responsive = false;
@ -181,6 +189,9 @@
})(); })();
</script> </script>
<!-- Shared list DataTable helpers (batch_list-style: scroll/align/columns.adjust) -->
<script src="<?= base_url() . "public"; ?>/assets/js/pages/nhance-list-datatable.js"></script>
<script src="<?= base_url() . "public"; ?>/assets/libs/bootstrap-datepicker/js/bootstrap-datepicker.min.js"></script> <script src="<?= base_url() . "public"; ?>/assets/libs/bootstrap-datepicker/js/bootstrap-datepicker.min.js"></script>
<script src="<?= base_url() . "public"; ?>/assets/libs/moment/min/moment.min.js"></script> <script src="<?= base_url() . "public"; ?>/assets/libs/moment/min/moment.min.js"></script>
<script src="<?= base_url() . "public"; ?>/assets/libs/bootstrap-daterangepicker/daterangepicker.js"></script> <script src="<?= base_url() . "public"; ?>/assets/libs/bootstrap-daterangepicker/daterangepicker.js"></script>

View File

@ -689,6 +689,17 @@
//------------------------------ GET DATA ( EDIT, BRANCH, POLICY ) --------------------------------------------------------------------------- //------------------------------ GET DATA ( EDIT, BRANCH, POLICY ) ---------------------------------------------------------------------------
//view and edit Lead data function ( NOT IN USE DON'T DELETE ) //view and edit Lead data function ( NOT IN USE DON'T DELETE )
function togglePolicyTypeDivider(dataIncrement) {
var $policyType = $('#policy_type_id_' + dataIncrement);
var selectedPolicyText = ($policyType.find('option:selected').text() || '').toLowerCase();
var isGmcPolicy = selectedPolicyText.indexOf('gmc') !== -1;
var $policyDivider = $('#appendArea_' + dataIncrement).find('hr').first();
if ($policyDivider.length) {
$policyDivider.toggle(!isGmcPolicy);
}
}
function getLeadsDataForEdit(input) { function getLeadsDataForEdit(input) {
$('.loader').fadeIn(); $('.loader').fadeIn();
@ -718,6 +729,7 @@
if (typeof window.refreshLeadsFormValidation === 'function') { if (typeof window.refreshLeadsFormValidation === 'function') {
window.refreshLeadsFormValidation(); window.refreshLeadsFormValidation();
} }
togglePolicyTypeDivider(dataIncrement);
let policy_type_id = res.data.policy_type_id; let policy_type_id = res.data.policy_type_id;
let lead_type = res.data.lead_type; let lead_type = res.data.lead_type;
@ -1105,6 +1117,7 @@
if (typeof window.refreshLeadsFormValidation === 'function') { if (typeof window.refreshLeadsFormValidation === 'function') {
window.refreshLeadsFormValidation(); window.refreshLeadsFormValidation();
} }
togglePolicyTypeDivider(dataIncrement);
console.log("Policy Type ID : ", policy_type_id); console.log("Policy Type ID : ", policy_type_id);
if (policy_type_id == 1 || policy_type_id == 6 || policy_type_id == 7) { if (policy_type_id == 1 || policy_type_id == 6 || policy_type_id == 7) {

View File

@ -1,3 +1,55 @@
<?php
helper('datatable_view');
/* Column widths from max data length (same approach as batch_list.php → stable TH/TD alignment). */
$leads_header_labels = [
'S.No', 'Opportunity Type', 'Issuer', 'Client Type', 'Client / Branch',
'Entity Type', 'Branch Name', 'Branch Code', 'Contact Person Name', 'Contact Person Mobile',
'Policy Type', 'Status', 'Action',
];
$leads_col_count = count($leads_header_labels);
$leads_col_max_len = array_fill(0, $leads_col_count, 0);
for ($i = 0; $i < $leads_col_count; $i++) {
$leads_col_max_len[$i] = mb_strlen($leads_header_labels[$i]);
}
$lead_type = $lead_type ?? [];
$issuer = $issuer ?? [];
$client_type = $client_type ?? [];
$lead_status = $lead_status ?? [];
$lead_data_list = $lead_data_list ?? [];
if (! empty($lead_data_list) && is_array($lead_data_list)) {
foreach ($lead_data_list as $index => $row) {
$leads_col_max_len[0] = max($leads_col_max_len[0], mb_strlen((string) ($index + 1)));
$leads_col_max_len[1] = max($leads_col_max_len[1], mb_strlen((string) ($lead_type[$row['lead_type'] ?? ''] ?? '-')));
$leads_col_max_len[2] = max($leads_col_max_len[2], mb_strlen((string) ($issuer[$row['issuer'] ?? ''] ?? '-')));
$leads_col_max_len[3] = max($leads_col_max_len[3], mb_strlen((string) ($client_type[$row['client_type'] ?? ''] ?? '-')));
$clientBranch = (isset($row['client_type']) && (int) $row['client_type'] === 2)
? (string) ($row['client_name'] ?? '-')
: (string) (($row['client_short_name'] ?? '-') . ' - ' . ($row['branch_name'] ?? '-'));
$leads_col_max_len[4] = max($leads_col_max_len[4], mb_strlen($clientBranch));
$leads_col_max_len[5] = max($leads_col_max_len[5], mb_strlen((string) ($row['entity_type'] ?? '-')));
$leads_col_max_len[6] = max($leads_col_max_len[6], mb_strlen((string) ($row['branch_name'] ?? '-')));
$leads_col_max_len[7] = max($leads_col_max_len[7], mb_strlen((string) ($row['branch_code'] ?? '-')));
$leads_col_max_len[8] = max($leads_col_max_len[8], mb_strlen((string) ($row['contact_person_name'] ?? '-')));
$leads_col_max_len[9] = max($leads_col_max_len[9], mb_strlen((string) ($row['contact_person_mobile'] ?? '-')));
$leads_col_max_len[10] = max($leads_col_max_len[10], mb_strlen((string) ($row['policy_type'] ?? '-')));
$leads_col_max_len[11] = max($leads_col_max_len[11], mb_strlen((string) ($lead_status[$row['status'] ?? ''] ?? '-')));
$leads_col_max_len[12] = max($leads_col_max_len[12], 4);
}
}
$leads_col_min_px = [48, 72, 88, 72, 120, 88, 96, 72, 120, 100, 120, 96, 52];
$leads_col_max_px = [64, 220, 180, 140, 520, 200, 240, 120, 280, 130, 280, 200, 72];
$leads_col_width_px = [];
for ($i = 0; $i < $leads_col_count; $i++) {
$chars = max($leads_col_max_len[$i], mb_strlen($leads_header_labels[$i]));
$px = (int) round($chars * 7.0 + 26);
$leads_col_width_px[$i] = min(
$leads_col_max_px[$i],
max($leads_col_min_px[$i], $px)
);
}
?>
<style> <style>
.col-12 { .col-12 {
max-width: 98% !important; max-width: 98% !important;
@ -116,6 +168,60 @@
.table-responsive { .table-responsive {
overflow-x: auto !important; overflow-x: auto !important;
} }
/* Opportunities table: column widths from PHP (batch_list.php pattern) */
<?php for ($i = 0; $i < $leads_col_count; $i++) : ?>
#leads-list-table_wrapper .dataTables_scrollHead table thead th:nth-child(<?= $i + 1 ?>),
#leads-list-table thead th:nth-child(<?= $i + 1 ?>) {
min-width: <?= (int) $leads_col_width_px[$i] ?>px;
width: <?= (int) $leads_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
overflow: visible !important;
}
#leads-list-table tbody td:nth-child(<?= $i + 1 ?>) {
width: <?= (int) $leads_col_width_px[$i] ?>px;
max-width: <?= (int) $leads_col_width_px[$i] ?>px;
min-width: <?= (int) $leads_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
}
<?php endfor; ?>
#leads-list-table tbody td:nth-child(1),
#leads-list-table tbody td:nth-child(2),
#leads-list-table tbody td:nth-child(3),
#leads-list-table tbody td:nth-child(4),
#leads-list-table tbody td:nth-child(5),
#leads-list-table tbody td:nth-child(6),
#leads-list-table tbody td:nth-child(7),
#leads-list-table tbody td:nth-child(8),
#leads-list-table tbody td:nth-child(9),
#leads-list-table tbody td:nth-child(10),
#leads-list-table tbody td:nth-child(11),
#leads-list-table tbody td:nth-child(12) {
overflow: hidden;
text-overflow: ellipsis;
}
#leads-list-table tbody td:nth-child(13) {
overflow: visible;
text-overflow: clip;
}
#leads-list-table tbody td {
padding: 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
#leads-list-table_wrapper .dataTables_scrollHead table thead th,
#leads-list-table thead th {
padding: 5px 2.35rem 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
#leads-list-table .dropdown-toggle.btn-sm {
padding: 4px 9px !important;
font-size: 13px;
line-height: 1.2;
}
</style> </style>
@ -134,7 +240,7 @@
</div> </div>
<div> <div>
<div class="table-responsive"> <div class="table-responsive">
<table data-custom-table-css="table" class="table mb-0 nowrap" cellspacing="0" id="tickets-table"> <table data-custom-table-css="table" class="table table-hover mb-0 nowrap w-100 table-centered m-0" cellspacing="0" id="leads-list-table">
<thead class="bg-light"> <thead class="bg-light">
<tr> <tr>
@ -158,7 +264,7 @@
<?php if (isset($lead_data_list)) {?> <?php if (isset($lead_data_list)) {?>
<?php foreach ($lead_data_list as $index => $row) {?> <?php foreach ($lead_data_list as $index => $row) {?>
<tr> <tr>
<td class="text-center"> <td>
<?php echo $index + 1; ?> <?php echo $index + 1; ?>
<?php if ($row['demography_file_status'] == "failed") {?> <?php if ($row['demography_file_status'] == "failed") {?>
<a href="<?php echo base_url('util/getMemberDataExcelFileErrors?lead_id=') . $row['id'] ?>" <a href="<?php echo base_url('util/getMemberDataExcelFileErrors?lead_id=') . $row['id'] ?>"
@ -716,10 +822,11 @@
// Datatable document ready // Datatable document ready
$(document).ready(function() { $(document).ready(function() {
var ticketsTable = $('#tickets-table'); var ticketsTable = $('#leads-list-table');
if (ticketsTable.length) { if (ticketsTable.length) {
table = ticketsTable.DataTable({ nhanceListDataTableBeforeInit();
table = ticketsTable.DataTable(nhanceMergeListDataTableOptions({
// dom: "<'row'<'col-sm-7'f><'col-sm-5 text-right'B>>" + // Filter left, buttons right // dom: "<'row'<'col-sm-7'f><'col-sm-5 text-right'B>>" + // Filter left, buttons right
// "<'row'<'col-sm-12'tr>>" + // "<'row'<'col-sm-12'tr>>" +
// "<'row'<'col-sm-5'i><'col-sm-7'p>>", // Pagination at the bottom, without page length selector // "<'row'<'col-sm-5'i><'col-sm-7'p>>", // Pagination at the bottom, without page length selector
@ -778,14 +885,21 @@
paging: true, // Enable pagination paging: true, // Enable pagination
pageLength: 10, // Set default number of rows per page (optional) pageLength: 10, // Set default number of rows per page (optional)
// ordering: false, // ordering: false,
}); columnDefs: [
<?php for ($i = 0; $i < $leads_col_count; $i++) : ?>
{ targets: <?= $i ?>, width: '<?= (int) $leads_col_width_px[$i] ?>px' },
<?php endfor; ?>
],
}));
nhanceListDataTableAfterInit();
nhanceListDataTableBindAdjust(table);
function applyBottomRowDropup() { function applyBottomRowDropup() {
if (!table) return; if (!table) return;
const currentRows = table.rows({ page: 'current' }).nodes().toArray(); const currentRows = table.rows({ page: 'current' }).nodes().toArray();
$('#tickets-table tbody tr').removeClass('nh-force-dropup'); $('#leads-list-table tbody tr').removeClass('nh-force-dropup');
$('#tickets-table tbody tr td.table-action-cell .btn-group.dropdown').removeClass('dropup'); $('#leads-list-table tbody tr td.table-action-cell .btn-group.dropdown').removeClass('dropup');
const targetCount = Math.min(2, currentRows.length); const targetCount = Math.min(2, currentRows.length);
for (let i = 0; i < targetCount; i++) { for (let i = 0; i < targetCount; i++) {

View File

@ -32,7 +32,7 @@ table.dataTable tbody td {
<?php if (!empty($logs)): ?> <?php if (!empty($logs)): ?>
<?php foreach ($logs as $index => $log): ?> <?php foreach ($logs as $index => $log): ?>
<tr> <tr>
<td class="text-center"><?= $index + 1 . '.' ?></td> <td><?= $index + 1 . '.' ?></td>
<td><?= esc($log) ?></td> <td><?= esc($log) ?></td>
<td> <td>
<a href="<?= base_url('util/view_log/' . urlencode($log)) ?>">View</a> | <a href="<?= base_url('util/view_log/' . urlencode($log)) ?>">View</a> |

View File

@ -13,16 +13,16 @@
<div class="form-row"> <div class="form-row">
<div class="form-group col-md-12"> <div class="form-group col-md-12">
<label for="client_name">Client Name<span class="text-danger">*</span></label> <label for="client_name">Client Name<span class="text-danger">*</span></label>
<input type="text" class="form-control" id="client_name" name="client_name" required> <input type="text" class="form-control" id="client_name" name="client_name" onkeypress="return restrictCharacters(event, /[a-zA-Z0-9 ,\\/_-]/)" required>
</div> </div>
<div class="form-group col-md-12"> <div class="form-group col-md-12">
<label for="short_name">Client Short name<span class="text-danger">*</span></label> <label for="short_name">Client Short name<span class="text-danger">*</span></label>
<input type="text" class="form-control" id="short_name" name="short_name" onkeyup="validateInputForClient(this, 'clients', 'short_name')" required> <input type="text" class="form-control" id="short_name" name="short_name" onkeyup="validateInputForClient(this, 'clients', 'short_name')" onkeypress="return restrictCharacters(event, /[a-zA-Z0-9,\\/_-]/)" required>
</div> </div>
<div class="form-group col-md-12"> <div class="form-group col-md-12">
<label for="cost_center">PAN</label> <label for="cost_center">PAN</label>
<input type="text" class="form-control" id="pan" placeholder="Enter PAN No" name="pan" onchange="validateInputForClient(this, 'clients', 'pan')"> <input type="text" class="form-control" id="pan" placeholder="Enter PAN No" name="pan" onchange="validateInputForClient(this, 'clients', 'pan')" onkeypress="return restrictCharacters(event, /[A-Z0-9]/)" oninput="this.value = this.value.toUpperCase()">
</div> </div>
</div> </div>
@ -48,7 +48,7 @@
</div> </div>
<div class="form-group col-md-12"> <div class="form-group col-md-12">
<label for="aadhar">Aadhar</label> <label for="aadhar">Aadhar</label>
<input type="text" class="form-control" id="aadhar" placeholder="Enter Aadher No" name="aadhar" maxlength="12" onchange="validateInputForClient(this, 'clients', 'aadhar')"> <input type="text" class="form-control" id="aadhar" placeholder="Enter Aadher No" name="aadhar" maxlength="12" onchange="validateInputForClient(this, 'clients', 'aadhar')" onkeypress="return onlyNumbers(event)">
</div> </div>
</div> </div>
@ -72,17 +72,17 @@
<div class="form-group col-md-6"> <div class="form-group col-md-6">
<label for="client_name">Branch Name<span class="text-danger">*</span></label> <label for="client_name">Branch Name<span class="text-danger">*</span></label>
<input type="text" class="form-control" id="branch_name" name="branch_name" required> <input type="text" class="form-control" id="branch_name" name="branch_name" onkeypress="return restrictCharacters(event, /[a-zA-Z0-9 ,\\/_-]/)" required>
</div> </div>
<div class="form-group col-md-6"> <div class="form-group col-md-6">
<label for="branch_code">Branch Code<span class="text-danger">*</span></label> <label for="branch_code">Branch Code<span class="text-danger">*</span></label>
<input type="text" class="form-control" id="branch_code" name="branch_code" required> <input type="text" class="form-control" id="branch_code" name="branch_code" onkeypress="return restrictCharacters(event, /[a-zA-Z0-9,\\/_-]/)" required>
</div> </div>
<div class="form-group col-md-6"> <div class="form-group col-md-6">
<label for="branch_code">Name<span class="text-danger">*</span></label> <label for="branch_code">Name<span class="text-danger">*</span></label>
<input type="text" class="form-control" id="name" name="name" required> <input type="text" class="form-control" id="name" name="name" onkeypress="return restrictCharacters(event, /[a-zA-Z\s]/)" required>
</div> </div>
<div class="form-group col-md-6"> <div class="form-group col-md-6">
@ -97,7 +97,7 @@
<div class="form-group col-md-12"> <div class="form-group col-md-12">
<label for="gst">GST<span class="text-danger">*</span></label> <label for="gst">GST<span class="text-danger">*</span></label>
<input type="text" class="form-control" id="gst" placeholder="Enter GST Number" oninput="validateInputForClient(this, 'client_branch', 'gst')" <input type="text" class="form-control" id="gst" placeholder="Enter GST Number" oninput="validateInputForClient(this, 'client_branch', 'gst')"
data-parsley-error-message="Invalid GST Number. Example: 12ABCDE1234F5Z6" name="gst" data-parsley-trigger="change" data-parsley-pattern="^\d{2}[A-Z]{5}\d{4}[A-Z]{1}[A-Z\d]{1}[Z]{1}[A-Z\d]{1}$" required> data-parsley-error-message="Invalid GST Number. Example: 12ABCDE1234F5Z6" name="gst" data-parsley-trigger="change" data-parsley-pattern="^\d{2}[A-Z]{5}\d{4}[A-Z]{1}[A-Z\d]{1}[Z]{1}[A-Z\d]{1}$" onkeypress="return restrictCharacters(event, /[A-Z0-9]/)" oninput="this.value = this.value.toUpperCase()" required>
</div> </div>
</div> </div>
@ -116,6 +116,34 @@
let isGSTValidating = false; let isGSTValidating = false;
let isGSTValid = false; let isGSTValid = false;
function restrictCharacters(event, pattern) {
// Allow control keys (Backspace, Tab, Enter, etc.) which have charCode < 32
// or are navigation keys.
if (event.which < 32 || event.key === "ArrowLeft" || event.key === "ArrowRight" || event.key === "Delete" || event.key === "Backspace" || event.key === "Tab") {
return true;
}
const char = String.fromCharCode(event.which);
if (!pattern.test(char)) {
event.preventDefault();
return false;
}
return true;
}
function onlyNumbers(event) {
const charCode = (event.which) ? event.which : event.keyCode;
// Allow control keys
if (event.which < 32 || event.key === "ArrowLeft" || event.key === "ArrowRight" || event.key === "Delete" || event.key === "Backspace" || event.key === "Tab") {
return true;
}
// Allow numbers 0-9
if (charCode > 31 && (charCode < 48 || charCode > 57)) {
event.preventDefault();
return false;
}
return true;
}
function validateInputForClient(input, table, field) { function validateInputForClient(input, table, field) {
let owner_type = $('#Owner_type').val(); let owner_type = $('#Owner_type').val();

View File

@ -1,8 +1,66 @@
<?php
helper('datatable_view');
$nb_header_labels = ['S.No.', 'Branch Name', 'Action'];
$nb_col_count = count($nb_header_labels);
$nb_col_max_len = array_fill(0, $nb_col_count, 0);
for ($i = 0; $i < $nb_col_count; $i++) {
$nb_col_max_len[$i] = mb_strlen($nb_header_labels[$i]);
}
if (isset($data) && is_array($data)) {
$nb_sl = 0;
foreach ($data as $row) {
++$nb_sl;
$nb_col_max_len[0] = max($nb_col_max_len[0], mb_strlen((string) $nb_sl));
$nb_col_max_len[1] = max($nb_col_max_len[1], mb_strlen((string) ($row['branch_name'] ?? '')));
$nb_col_max_len[2] = max($nb_col_max_len[2], 4);
}
}
$nb_col_min_px = [48, 140, 72];
$nb_col_max_px = [64, 400, 88];
$nb_col_width_px = nhance_dt_column_widths_px($nb_header_labels, $nb_col_max_len, $nb_col_min_px, $nb_col_max_px);
?>
<style> <style>
.dataTables_filter { .dataTables_filter {
position: absolute; position: absolute;
} }
.dataTables_length label {height: 21px !important;} .dataTables_length label {height: 21px !important;}
<?php for ($i = 0; $i < $nb_col_count; $i++) : ?>
#nhance-branch-list-table_wrapper .dataTables_scrollHead table thead th:nth-child(<?= $i + 1 ?>),
#nhance-branch-list-table thead th:nth-child(<?= $i + 1 ?>) {
min-width: <?= (int) $nb_col_width_px[$i] ?>px;
width: <?= (int) $nb_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
overflow: visible !important;
}
#nhance-branch-list-table tbody td:nth-child(<?= $i + 1 ?>) {
width: <?= (int) $nb_col_width_px[$i] ?>px;
max-width: <?= (int) $nb_col_width_px[$i] ?>px;
min-width: <?= (int) $nb_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
}
<?php endfor; ?>
#nhance-branch-list-table tbody td:nth-child(1),
#nhance-branch-list-table tbody td:nth-child(2) {
overflow: hidden;
text-overflow: ellipsis;
}
#nhance-branch-list-table tbody td:nth-child(3) {
overflow: visible;
text-overflow: clip;
}
#nhance-branch-list-table tbody td {
padding: 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
#nhance-branch-list-table thead th {
padding: 5px 2.35rem 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
</style> </style>
<!-- End ADD and EDIT Page HTML --> <!-- End ADD and EDIT Page HTML -->
@ -10,7 +68,7 @@
<div class="col-12"> <div class="col-12">
<div class="card"> <div class="card">
<div class="card-body"> <div class="card-body">
<table data-custom-table-css="table" class="table table-sm m-0 table-centered dt-responsive nowrap w-100" cellspacing="a" id="user-table"> <table data-custom-table-css="table" class="table table-sm m-0 table-centered dt-responsive nowrap w-100" cellspacing="a" id="nhance-branch-list-table">
<thead class="bg-light"> <thead class="bg-light">
<tr> <tr>
<th class="font-weight-medium">S.No.</th> <th class="font-weight-medium">S.No.</th>
@ -23,7 +81,7 @@
<?php if(isset($data)) { $slno = 1; ?> <?php if(isset($data)) { $slno = 1; ?>
<?php foreach($data as $index => $row) { ?> <?php foreach($data as $index => $row) { ?>
<tr> <tr>
<td class="text-center"><?= $slno++; ?></td> <td><?= $slno++; ?></td>
<td><?= $row['branch_name']; ?></td> <td><?= $row['branch_name']; ?></td>
<!-- <td> <!-- <td>
<span class="<?php if($row['is_active'] == 1){ echo 'badge badge-primary'; }else{ echo 'badge badge-danger'; } ?>"> <span class="<?php if($row['is_active'] == 1){ echo 'badge badge-primary'; }else{ echo 'badge badge-danger'; } ?>">
@ -96,9 +154,9 @@
<script> <script>
var table; var table;
$(document).ready(function () { $(document).ready(function () {
var ticketsTable = $('#user-table'); var ticketsTable = $('#nhance-branch-list-table');
ticketsTable.DataTable({ nhanceListDataTableBeforeInit();
scrollX: true, table = ticketsTable.DataTable(nhanceMergeListDataTableOptions({
// dom: "<'row'<'col-sm-7'f><'col-sm-5 text-right'B>>" + // Filter left, buttons right // dom: "<'row'<'col-sm-7'f><'col-sm-5 text-right'B>>" + // Filter left, buttons right
// "<'row'<'col-sm-12'tr>>" + // "<'row'<'col-sm-12'tr>>" +
// "<'row'<'col-sm-5'i><'col-sm-7'p>>", // Pagination at the bottom, without page length selector // "<'row'<'col-sm-5'i><'col-sm-7'p>>", // Pagination at the bottom, without page length selector
@ -146,7 +204,14 @@
paging: true, // Enable pagination paging: true, // Enable pagination
pageLength: 10, // Set default number of rows per page (optional) pageLength: 10, // Set default number of rows per page (optional)
// ordering: false, // ordering: false,
}); columnDefs: [
<?php for ($i = 0; $i < $nb_col_count; $i++) : ?>
{ targets: <?= $i ?>, width: '<?= (int) $nb_col_width_px[$i] ?>px' },
<?php endfor; ?>
],
}));
nhanceListDataTableAfterInit();
nhanceListDataTableBindAdjust(table);
}); });
$('.close').click(function(){ $('.close').click(function(){

View File

@ -1202,7 +1202,7 @@ function nonebCreateFileList(data) {
var html = ''; var html = '';
data.forEach(function(item, index) { data.forEach(function(item, index) {
html += '<tr>' + html += '<tr>' +
'<td class="text-center">' + (index + 1) + '</td>' + '<td>' + (index + 1) + '</td>' +
'<td>' + item.doc_name + '</td>' + '<td>' + item.doc_name + '</td>' +
'<td><a href="' + item.url + '" target="_blank">' + (item.file_type == 1 ? item.url : item.doc_name) + '</a></td>' + '<td><a href="' + item.url + '" target="_blank">' + (item.file_type == 1 ? item.url : item.doc_name) + '</a></td>' +
'<td><a href="javascript:void(0);" class="noneb-delete-url" data-href="' + base_url + 'non-eb-claim/removeFile?id=' + item.id + '"><i class="mdi mdi-delete mr-1"></i></a></td>' + '<td><a href="javascript:void(0);" class="noneb-delete-url" data-href="' + base_url + 'non-eb-claim/removeFile?id=' + item.id + '"><i class="mdi mdi-delete mr-1"></i></a></td>' +

View File

@ -1,3 +1,34 @@
<?php
helper('datatable_view');
$or_header_labels = [
'S.No', 'Insurer', 'Insurer Branch', 'Statement Month', 'Statement No', 'Invoice No', 'Invoice Status',
'Invoice Date', 'Invoice Amount', 'Realization Amount', 'Outstanding Amount',
];
$or_col_count = count($or_header_labels);
$or_col_max_len = array_fill(0, $or_col_count, 0);
for ($i = 0; $i < $or_col_count; $i++) {
$or_col_max_len[$i] = mb_strlen($or_header_labels[$i]);
}
$outstanting_list = $outstanting_list ?? [];
foreach ($outstanting_list as $index => $row) {
$or_col_max_len[0] = max($or_col_max_len[0], mb_strlen((string) ($index + 1)));
$or_col_max_len[1] = max($or_col_max_len[1], mb_strlen((string) ($row['short_name'] ?? '')));
$or_col_max_len[2] = max($or_col_max_len[2], mb_strlen((string) ($row['branch_name'] ?? '')));
$or_col_max_len[3] = max($or_col_max_len[3], mb_strlen((string) change_date_format($row['month'] ?? '', 'Y-m-d', 'Y-m')));
$or_col_max_len[4] = max($or_col_max_len[4], mb_strlen((string) ($row['stmt_sno'] ?? '')));
$or_col_max_len[5] = max($or_col_max_len[5], mb_strlen((string) ($row['invoice_no'] ?? '')));
$or_col_max_len[6] = max($or_col_max_len[6], mb_strlen((string) (isset($row['invoice_status']) ? $row['invoice_status'] : ' - ')));
$or_col_max_len[7] = max($or_col_max_len[7], mb_strlen((string) change_date_format($row['invoice_date'] ?? '', 'Y-m-d', 'd-M-Y')));
$or_col_max_len[8] = max($or_col_max_len[8], mb_strlen((string) (isset($row['invoice_amount']) ? $row['invoice_amount'] : '0.00')));
$or_col_max_len[9] = max($or_col_max_len[9], mb_strlen((string) (isset($row['total_paid']) ? $row['total_paid'] : '0.00')));
$or_col_max_len[10] = max($or_col_max_len[10], mb_strlen((string) (isset($row['outstanding_amount']) ? $row['outstanding_amount'] : '0.00')));
}
$or_col_min_px = array_fill(0, $or_col_count, 88);
$or_col_min_px[0] = 48;
$or_col_max_px = array_fill(0, $or_col_count, 360);
$or_col_max_px[0] = 64;
$or_col_width_px = nhance_dt_column_widths_px($or_header_labels, $or_col_max_len, $or_col_min_px, $or_col_max_px);
?>
<style> <style>
.table th, .table th,
.table td { .table td {
@ -84,6 +115,38 @@
} }
</style> </style>
<style>
<?php for ($i = 0; $i < $or_col_count; $i++) : ?>
#outstanding-report-list-table_wrapper .dataTables_scrollHead table thead th:nth-child(<?= $i + 1 ?>),
#outstanding-report-list-table thead th:nth-child(<?= $i + 1 ?>) {
min-width: <?= (int) $or_col_width_px[$i] ?>px;
width: <?= (int) $or_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
overflow: visible !important;
}
#outstanding-report-list-table tbody td:nth-child(<?= $i + 1 ?>) {
width: <?= (int) $or_col_width_px[$i] ?>px;
max-width: <?= (int) $or_col_width_px[$i] ?>px;
min-width: <?= (int) $or_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
}
<?php endfor; ?>
#outstanding-report-list-table tbody td {
overflow: hidden;
text-overflow: ellipsis;
padding: 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
#outstanding-report-list-table thead th {
padding: 5px 2.35rem 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
</style>
<div class="container-fluid-min"> <div class="container-fluid-min">
<div id="filter-sidebar" class="filter-sidebar"> <div id="filter-sidebar" class="filter-sidebar">
<div class="filter-sidebar-header"> <div class="filter-sidebar-header">
@ -140,15 +203,17 @@
<div class="col-12" id="outstanding_list"> <div class="col-12" id="outstanding_list">
<div class="card"> <div class="card">
<div class="card-body"> <div class="card-body">
<!--
<div class="row" style="padding-bottom: 10px;"> <div class="row" style="padding-bottom: 10px;">
<div class="col-6" style="align-self: center;"> <div class="col-6" style="align-self: center;">
<h4 style="position: relative;">Outstanding Report</h4> <h4 style="position: relative;">Outstanding Report</h4>
</div> </div>
</div> </div>
-->
<div class="table-responsive"> <div class="table-responsive">
<table data-custom-table-css="table" id="scroll-horizontal-datatable" class="table mb-0 nowrap w-100 table-centered" cellspacing="0" > <table data-custom-table-css="table" data-nhance-list-dt="1" id="outstanding-report-list-table" class="table mb-0 nowrap w-100 table-centered" cellspacing="0" >
<thead class="bg-light"> <thead class="bg-light">
<tr> <tr>
<th><div class="column-header">S.No</div></th> <th><div class="column-header">S.No</div></th>
@ -173,7 +238,7 @@
if (isset($outstanting_list)) { ?> if (isset($outstanting_list)) { ?>
<?php foreach ($outstanting_list as $index => $row) { ?> <?php foreach ($outstanting_list as $index => $row) { ?>
<tr> <tr>
<td class="text-center"><?= $index + 1 ?></td> <td><?= $index + 1 ?></td>
<td><?php echo $row['short_name']; ?></td> <td><?php echo $row['short_name']; ?></td>
<td><?php echo $row['branch_name']; ?></td> <td><?php echo $row['branch_name']; ?></td>
<td><?php echo change_date_format($row['month'],'Y-m-d','Y-m') ?></td> <td><?php echo change_date_format($row['month'],'Y-m-d','Y-m') ?></td>
@ -210,11 +275,11 @@
$(document).ready(function() { $(document).ready(function() {
var ticketsTable = $('#scroll-horizontal-datatable'); var ticketsTable = $('#outstanding-report-list-table');
if (ticketsTable.length) { if (ticketsTable.length) {
ticketsTable.DataTable({ nhanceListDataTableBeforeInit();
scrollX: true, var nhOutstandingTable = ticketsTable.DataTable(nhanceMergeListDataTableOptions({
// dom: "<'row'<'col-sm-6'f><'col-sm-6 text-right'B>>" + // Filter left, buttons right // dom: "<'row'<'col-sm-6'f><'col-sm-6 text-right'B>>" + // Filter left, buttons right
// "<'row'<'col-sm-12'tr>>" + // "<'row'<'col-sm-12'tr>>" +
// "<'row'<'col-sm-5'i><'col-sm-7'p>>", // Pagination at the bottom, without page length selector // "<'row'<'col-sm-5'i><'col-sm-7'p>>", // Pagination at the bottom, without page length selector
@ -290,8 +355,15 @@
emptyTable: '<div class="text-center text-muted">No Data found</div>' emptyTable: '<div class="text-center text-muted">No Data found</div>'
}, },
paging: true, // Enable pagination paging: true, // Enable pagination
pageLength: 25 // Set default number of rows per page (optional) pageLength: 25, // Set default number of rows per page (optional)
}); columnDefs: [
<?php for ($i = 0; $i < $or_col_count; $i++) : ?>
{ targets: <?= $i ?>, width: '<?= (int) $or_col_width_px[$i] ?>px' },
<?php endfor; ?>
],
}));
nhanceListDataTableAfterInit();
nhanceListDataTableBindAdjust(nhOutstandingTable);
} else { } else {
console.error("Table not found."); console.error("Table not found.");
} }

View File

@ -296,7 +296,7 @@
<tbody> <tbody>
<?php foreach ($endorsement_data_list as $index => $row) { ?> <?php foreach ($endorsement_data_list as $index => $row) { ?>
<tr> <tr>
<td class="text-center"><?php echo $index + 1; ?></td> <td><?php echo $index + 1; ?></td>
<td><?php echo $issuer[$row['issuer']] ?? 'N/A'; ?></td><!-- Issuer --> <td><?php echo $issuer[$row['issuer']] ?? 'N/A'; ?></td><!-- Issuer -->
<td><?php echo $row['client_short_name'] ?: 'N/A'; ?></td><!-- Client --> <td><?php echo $row['client_short_name'] ?: 'N/A'; ?></td><!-- Client -->
<td><?php echo $row['client_branch_name'] ?: 'N/A'; ?></td><!-- Branch --> <td><?php echo $row['client_branch_name'] ?: 'N/A'; ?></td><!-- Branch -->

View File

@ -325,7 +325,7 @@ table.dataTable thead th {
<tbody> <tbody>
<?php foreach ($endorsement_data_list as $index => $row) { ?> <?php foreach ($endorsement_data_list as $index => $row) { ?>
<tr> <tr>
<td class="text-center"><?php echo $index + 1; ?></td> <td><?php echo $index + 1; ?></td>
<td><?php echo $issuer[$row['issuer']] ?? 'N/A'; ?></td><!-- Issuer --> <td><?php echo $issuer[$row['issuer']] ?? 'N/A'; ?></td><!-- Issuer -->
<td><?php echo $row['client_short_name'] ?: 'N/A'; ?></td><!-- Client --> <td><?php echo $row['client_short_name'] ?: 'N/A'; ?></td><!-- Client -->
<td><?php echo $row['client_branch_name'] ?: 'N/A'; ?></td><!-- Branch --> <td><?php echo $row['client_branch_name'] ?: 'N/A'; ?></td><!-- Branch -->

View File

@ -1,3 +1,26 @@
<?php
helper('datatable_view');
$pt_header_labels = ['Policy Type', 'Policy Long Name', 'BAP', 'Category', 'BAP Category', 'Action'];
$pt_col_count = count($pt_header_labels);
$pt_col_max_len = array_fill(0, $pt_col_count, 0);
for ($i = 0; $i < $pt_col_count; $i++) {
$pt_col_max_len[$i] = mb_strlen($pt_header_labels[$i]);
}
$policyList = $policyList ?? [];
if (is_array($policyList)) {
foreach ($policyList as $row) {
$pt_col_max_len[0] = max($pt_col_max_len[0], mb_strlen((string) ($row['policy_type'] ?: 'N/A')));
$pt_col_max_len[1] = max($pt_col_max_len[1], mb_strlen((string) ($row['long_name'] ?: 'N/A')));
$pt_col_max_len[2] = max($pt_col_max_len[2], mb_strlen((string) ($row['bap'] ?: 'N/A')));
$pt_col_max_len[3] = max($pt_col_max_len[3], mb_strlen((string) ($row['allocg'] ?: 'N/A')));
$pt_col_max_len[4] = max($pt_col_max_len[4], mb_strlen((string) ($row['alloci'] ?: 'N/A')));
$pt_col_max_len[5] = max($pt_col_max_len[5], 4);
}
}
$pt_col_min_px = [100, 140, 72, 100, 100, 72];
$pt_col_max_px = [240, 480, 120, 200, 200, 88];
$pt_col_width_px = nhance_dt_column_widths_px($pt_header_labels, $pt_col_max_len, $pt_col_min_px, $pt_col_max_px);
?>
<style> <style>
.custom-dropdown-menu { .custom-dropdown-menu {
display: none; display: none;
@ -68,6 +91,48 @@
.dataTables_length label {height: 21px !important;} .dataTables_length label {height: 21px !important;}
</style> </style>
<style>
<?php for ($i = 0; $i < $pt_col_count; $i++) : ?>
#policy-type-list-table_wrapper .dataTables_scrollHead table thead th:nth-child(<?= $i + 1 ?>),
#policy-type-list-table thead th:nth-child(<?= $i + 1 ?>) {
min-width: <?= (int) $pt_col_width_px[$i] ?>px;
width: <?= (int) $pt_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
overflow: visible !important;
}
#policy-type-list-table tbody td:nth-child(<?= $i + 1 ?>) {
width: <?= (int) $pt_col_width_px[$i] ?>px;
max-width: <?= (int) $pt_col_width_px[$i] ?>px;
min-width: <?= (int) $pt_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
}
<?php endfor; ?>
#policy-type-list-table tbody td:nth-child(1),
#policy-type-list-table tbody td:nth-child(2),
#policy-type-list-table tbody td:nth-child(3),
#policy-type-list-table tbody td:nth-child(4),
#policy-type-list-table tbody td:nth-child(5) {
overflow: hidden;
text-overflow: ellipsis;
}
#policy-type-list-table tbody td:nth-child(6) {
overflow: visible;
text-overflow: clip;
}
#policy-type-list-table tbody td {
padding: 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
#policy-type-list-table thead th {
padding: 5px 2.35rem 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
</style>
<div class="container-fluid-min"> <div class="container-fluid-min">
<div class="row" id="policy_list"> <div class="row" id="policy_list">
<div class="col-12"> <div class="col-12">
@ -87,7 +152,7 @@
</div> </div>
</div> --> </div> -->
<table data-custom-table-css="table" class="table table-sm table-hover m-0 table-centered dt-responsive nowrap w-100" cellspacing="0" <table data-custom-table-css="table" class="table table-sm table-hover m-0 table-centered dt-responsive nowrap w-100" cellspacing="0"
id="tickets-table"> id="policy-type-list-table">
<thead class="bg-light"> <thead class="bg-light">
<tr> <tr>
<th class="font-weight-medium">Policy Type</th> <th class="font-weight-medium">Policy Type</th>
@ -131,7 +196,7 @@
<script> <script>
document.addEventListener("DOMContentLoaded", function() { document.addEventListener("DOMContentLoaded", function() {
const table = document.getElementById("tickets-table"); const table = document.getElementById("policy-type-list-table");
// Create custom dropdown // Create custom dropdown
function createCustomDropdown(row) { function createCustomDropdown(row) {
@ -217,7 +282,8 @@
<script> <script>
$(document).ready(function(){ $(document).ready(function(){
$('#tickets-table').DataTable({ nhanceListDataTableBeforeInit();
var nhPolicyTypeTable = $('#policy-type-list-table').DataTable(nhanceMergeListDataTableOptions({
// dom: "<'row'<'col-12 d-flex justify-content-between align-items-center'<'datatable-search dataTables_filter'f><'datatable-buttons dt-buttons'B>>>" + // dom: "<'row'<'col-12 d-flex justify-content-between align-items-center'<'datatable-search dataTables_filter'f><'datatable-buttons dt-buttons'B>>>" +
// "<'row'<'col-sm-12'tr>>" + // "<'row'<'col-sm-12'tr>>" +
// "<'row'<'col-sm-5'i><'col-sm-7'p>>", // "<'row'<'col-sm-5'i><'col-sm-7'p>>",
@ -267,13 +333,20 @@
emptyTable: '<div class="text-center text-muted">No Data found</div>' emptyTable: '<div class="text-center text-muted">No Data found</div>'
}, },
paging: true , paging: true ,
columnDefs: [
<?php for ($i = 0; $i < $pt_col_count; $i++) : ?>
{ targets: <?= $i ?>, width: '<?= (int) $pt_col_width_px[$i] ?>px' },
<?php endfor; ?>
],
}); }));
nhanceListDataTableAfterInit();
nhanceListDataTableBindAdjust(nhPolicyTypeTable);
}) })
const btnExport = document.querySelector("#btnExport"); const btnExport = document.querySelector("#btnExport");
const tableElement = document.querySelector("#tickets-table"); const tableElement = document.querySelector("#policy-type-list-table");
btnExport.addEventListener("click", () => { btnExport.addEventListener("click", () => {
const obj = new csvExport(tableElement); const obj = new csvExport(tableElement);

View File

@ -1,3 +1,29 @@
<?php
helper('datatable_view');
$pos_header_labels = ['S.No.', 'Manager', 'POS Name', 'POS Code', 'Email', 'Mobile', 'Status', 'Action'];
$pos_col_count = count($pos_header_labels);
$pos_col_max_len = array_fill(0, $pos_col_count, 0);
for ($i = 0; $i < $pos_col_count; $i++) {
$pos_col_max_len[$i] = mb_strlen($pos_header_labels[$i]);
}
$pos_list_rows = $data['pos_list'] ?? [];
$pos_sl = 0;
foreach ($pos_list_rows as $row) {
++$pos_sl;
$pos_col_max_len[0] = max($pos_col_max_len[0], mb_strlen((string) $pos_sl));
$pos_col_max_len[1] = max($pos_col_max_len[1], mb_strlen((string) ($row['manager_name'] ?? '')));
$pos_col_max_len[2] = max($pos_col_max_len[2], mb_strlen((string) ($row['name'] ?? '')));
$pos_col_max_len[3] = max($pos_col_max_len[3], mb_strlen((string) ($row['pos_code'] ?? '')));
$pos_col_max_len[4] = max($pos_col_max_len[4], mb_strlen((string) ($row['email'] ?? '')));
$pos_col_max_len[5] = max($pos_col_max_len[5], mb_strlen((string) ($row['mobile'] ?? '')));
$pos_status_txt = (isset($row['is_active']) && (int) $row['is_active'] === 1) ? 'Active' : 'In-Active';
$pos_col_max_len[6] = max($pos_col_max_len[6], mb_strlen($pos_status_txt));
$pos_col_max_len[7] = max($pos_col_max_len[7], 4);
}
$pos_col_min_px = [48, 96, 120, 96, 180, 100, 88, 72];
$pos_col_max_px = [64, 240, 280, 160, 360, 140, 120, 88];
$pos_col_width_px = nhance_dt_column_widths_px($pos_header_labels, $pos_col_max_len, $pos_col_min_px, $pos_col_max_px);
?>
<style> <style>
.dataTables_filter { .dataTables_filter {
position: absolute; position: absolute;
@ -29,6 +55,38 @@
color: #16181b !important; color: #16181b !important;
cursor: pointer !important; cursor: pointer !important;
} }
<?php for ($i = 0; $i < $pos_col_count; $i++) : ?>
#pos-list-table_wrapper .dataTables_scrollHead table thead th:nth-child(<?= $i + 1 ?>),
#pos-list-table thead th:nth-child(<?= $i + 1 ?>) {
min-width: <?= (int) $pos_col_width_px[$i] ?>px;
width: <?= (int) $pos_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
overflow: visible !important;
}
#pos-list-table tbody td:nth-child(<?= $i + 1 ?>) {
width: <?= (int) $pos_col_width_px[$i] ?>px;
max-width: <?= (int) $pos_col_width_px[$i] ?>px;
min-width: <?= (int) $pos_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
}
<?php endfor; ?>
#pos-list-table tbody td:nth-child(1),
#pos-list-table tbody td:nth-child(2),
#pos-list-table tbody td:nth-child(3),
#pos-list-table tbody td:nth-child(4),
#pos-list-table tbody td:nth-child(5),
#pos-list-table tbody td:nth-child(6),
#pos-list-table tbody td:nth-child(7) {
overflow: hidden;
text-overflow: ellipsis;
}
#pos-list-table tbody td:nth-child(8) {
overflow: visible;
text-overflow: clip;
}
</style> </style>
<!-- End ADD and EDIT Page HTML --> <!-- End ADD and EDIT Page HTML -->
@ -36,7 +94,7 @@
<div class="col-12"> <div class="col-12">
<div class="card"> <div class="card">
<div class="card-body"> <div class="card-body">
<table data-custom-table-css="table" class="table table-sm m-0 table-centered dt-responsive nowrap w-100" cellspacing="a" id="user-table"> <table data-custom-table-css="table" class="table table-sm m-0 table-centered dt-responsive nowrap w-100" cellspacing="a" id="pos-list-table">
<thead class="bg-light"> <thead class="bg-light">
<tr> <tr>
<th class="font-weight-medium">S.No.</th> <th class="font-weight-medium">S.No.</th>
@ -53,7 +111,7 @@
<?php if(!empty($data['pos_list'])) { $slno = 1; ?> <?php if(!empty($data['pos_list'])) { $slno = 1; ?>
<?php foreach($data['pos_list'] as $index => $row) { ?> <?php foreach($data['pos_list'] as $index => $row) { ?>
<tr> <tr>
<td class="text-center"><?= $slno++; ?></td> <td><?= $slno++; ?></td>
<td><?= $row['manager_name']; ?></td> <td><?= $row['manager_name']; ?></td>
<td><?= $row['name']; ?></td> <td><?= $row['name']; ?></td>
<td><?= $row['pos_code']; ?></td> <td><?= $row['pos_code']; ?></td>
@ -232,9 +290,9 @@
var table; var table;
$(document).ready(function () { $(document).ready(function () {
$('#manager_id').select2(); $('#manager_id').select2();
var ticketsTable = $('#user-table'); var ticketsTable = $('#pos-list-table');
ticketsTable.DataTable({ nhanceListDataTableBeforeInit();
scrollX: true, table = ticketsTable.DataTable(nhanceMergeListDataTableOptions({
// dom: "<'row'<'col-sm-7'f><'col-sm-5 text-right'B>>" + // Filter left, buttons right // dom: "<'row'<'col-sm-7'f><'col-sm-5 text-right'B>>" + // Filter left, buttons right
// "<'row'<'col-sm-12'tr>>" + // "<'row'<'col-sm-12'tr>>" +
// "<'row'<'col-sm-5'i><'col-sm-7'p>>", // Pagination at the bottom, without page length selector // "<'row'<'col-sm-5'i><'col-sm-7'p>>", // Pagination at the bottom, without page length selector
@ -282,7 +340,14 @@
paging: true, // Enable pagination paging: true, // Enable pagination
pageLength: 10, // Set default number of rows per page (optional) pageLength: 10, // Set default number of rows per page (optional)
// ordering: false, // ordering: false,
}); columnDefs: [
<?php for ($i = 0; $i < $pos_col_count; $i++) : ?>
{ targets: <?= $i ?>, width: '<?= (int) $pos_col_width_px[$i] ?>px' },
<?php endfor; ?>
],
}));
nhanceListDataTableAfterInit();
nhanceListDataTableBindAdjust(table);
}); });
$('.close').click(function(){ $('.close').click(function(){
@ -534,7 +599,7 @@
</script> </script>
<script> <script>
document.addEventListener("DOMContentLoaded", function() { document.addEventListener("DOMContentLoaded", function() {
const table = document.getElementById("user-table"); const table = document.getElementById("pos-list-table");
// Create custom dropdown // Create custom dropdown
function createCustomDropdown(row) { function createCustomDropdown(row) {

View File

@ -40,12 +40,14 @@ table.dataTable tbody td {
<div class="col-12" id="second_page"> <div class="col-12" id="second_page">
<div class="card"> <div class="card">
<div class="card-body"> <div class="card-body">
<!--
<div class="row" style="padding-bottom: 10px;"> <div class="row" style="padding-bottom: 10px;">
<div class="col-6" style="align-self: center;"> <div class="col-6" style="align-self: center;">
<h4 style="position: relative;">BDS Report <span id="bds_title"></span></h4> <h4 style="position: relative;">BDS Report <span id="bds_title"></span></h4>
</div> </div>
</div> </div>
-->
<div class="table-responsive"> <div class="table-responsive">
<div id="totals" class="d-flex flex-wrap gap-2 mb-2"> <div id="totals" class="d-flex flex-wrap gap-2 mb-2">

View File

@ -1,3 +1,46 @@
<?php
helper('datatable_view');
$ret_header_labels = [
'S.No', 'Policy number', 'Endorsement Number', 'Description', 'Client', 'Insurer name',
'Agent', 'Mananger', 'Created At', 'Status', 'Action',
];
$ret_col_count = count($ret_header_labels);
$ret_col_max_len = array_fill(0, $ret_col_count, 0);
for ($i = 0; $i < $ret_col_count; $i++) {
$ret_col_max_len[$i] = mb_strlen($ret_header_labels[$i]);
}
$employees = $employees ?? [];
$ret_sl = 0;
foreach ($employees as $employee) {
++$ret_sl;
$ret_col_max_len[0] = max($ret_col_max_len[0], mb_strlen((string) $ret_sl));
$ret_col_max_len[1] = max($ret_col_max_len[1], mb_strlen((string) ($employee['policy_number'] ?? '')));
$ret_col_max_len[2] = max($ret_col_max_len[2], mb_strlen((string) ($employee['endorsement_no'] ?? '')));
$ret_col_max_len[3] = max($ret_col_max_len[3], mb_strlen((string) ($employee['endorsement_description'] ?? '')));
$clientCell = ! empty($employee['client_name'])
? ($employee['client_name'] . ' ( ' . ($employee['client_short_name'] ?? '') . ' ) ')
: 'N/A';
$ret_col_max_len[4] = max($ret_col_max_len[4], mb_strlen($clientCell));
$insCell = ! empty($employee['insurer_name'])
? ($employee['insurer_name'] . ' ( ' . ($employee['insurer_short_name'] ?? '') . ' ) ')
: 'N/A';
$ret_col_max_len[5] = max($ret_col_max_len[5], mb_strlen($insCell));
$ret_col_max_len[6] = max($ret_col_max_len[6], mb_strlen((string) ($employee['agent_name'] ?? 'N/A')));
$ret_col_max_len[7] = max($ret_col_max_len[7], mb_strlen((string) ($employee['manager_name'] ?? 'N/A')));
$createdPlain = '';
if (! empty($employee['created_at'])) {
$createdPlain = date('j F Y', strtotime((string) $employee['created_at']))
. ' '
. date('h:i A', strtotime((string) $employee['created_at']));
}
$ret_col_max_len[8] = max($ret_col_max_len[8], mb_strlen($createdPlain));
$ret_col_max_len[9] = max($ret_col_max_len[9], mb_strlen((string) ($employee['status'] ?? '')));
$ret_col_max_len[10] = max($ret_col_max_len[10], 4);
}
$ret_col_min_px = [48, 100, 120, 120, 140, 140, 96, 96, 140, 96, 72];
$ret_col_max_px = [64, 200, 220, 400, 400, 360, 240, 240, 220, 160, 80];
$ret_col_width_px = nhance_dt_column_widths_px($ret_header_labels, $ret_col_max_len, $ret_col_min_px, $ret_col_max_px);
?>
<style> <style>
.table th, .table th,
.table td { .table td {
@ -77,6 +120,51 @@
flex-shrink: 0; flex-shrink: 0;
gap: 10px; gap: 10px;
} }
<?php for ($i = 0; $i < $ret_col_count; $i++) : ?>
#retail-endorsement-list-table_wrapper .dataTables_scrollHead table thead th:nth-child(<?= $i + 1 ?>),
#retail-endorsement-list-table thead th:nth-child(<?= $i + 1 ?>) {
min-width: <?= (int) $ret_col_width_px[$i] ?>px;
width: <?= (int) $ret_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
overflow: visible !important;
}
#retail-endorsement-list-table tbody td:nth-child(<?= $i + 1 ?>) {
width: <?= (int) $ret_col_width_px[$i] ?>px;
max-width: <?= (int) $ret_col_width_px[$i] ?>px;
min-width: <?= (int) $ret_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
}
<?php endfor; ?>
#retail-endorsement-list-table tbody td:nth-child(1),
#retail-endorsement-list-table tbody td:nth-child(2),
#retail-endorsement-list-table tbody td:nth-child(3),
#retail-endorsement-list-table tbody td:nth-child(4),
#retail-endorsement-list-table tbody td:nth-child(5),
#retail-endorsement-list-table tbody td:nth-child(6),
#retail-endorsement-list-table tbody td:nth-child(7),
#retail-endorsement-list-table tbody td:nth-child(8),
#retail-endorsement-list-table tbody td:nth-child(9),
#retail-endorsement-list-table tbody td:nth-child(10) {
overflow: hidden;
text-overflow: ellipsis;
}
#retail-endorsement-list-table tbody td:nth-child(11) {
overflow: visible;
text-overflow: clip;
}
#retail-endorsement-list-table tbody td {
padding: 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
#retail-endorsement-list-table thead th {
padding: 5px 2.35rem 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
</style> </style>
<div class="container-fluid-min"> <div class="container-fluid-min">
@ -138,7 +226,7 @@
<h4 style="position: relative;">Endorsement</h4> <h4 style="position: relative;">Endorsement</h4>
</div> </div>
</div> --> </div> -->
<table data-custom-table-css="table" class="table table-hover m-0 table-centered w-100" cellspacing="0" id="tickets-table"> <table data-custom-table-css="table" class="table table-hover m-0 table-centered w-100" cellspacing="0" id="retail-endorsement-list-table">
<thead class="bg-light"> <thead class="bg-light">
<tr> <tr>
<th class="font-weight-medium">S.No&nbsp;</th> <th class="font-weight-medium">S.No&nbsp;</th>
@ -160,20 +248,20 @@
if (isset($employees)) { if (isset($employees)) {
foreach ($employees as $key => $employee) { ?> foreach ($employees as $key => $employee) { ?>
<tr> <tr>
<td class="text-center"><b><?php echo ($key + 1) ?></b></td> <td><b><?php echo ($key + 1) ?></b></td>
<td class="text-center"><?php echo $employee['policy_number'] ?></td> <td><?php echo $employee['policy_number'] ?></td>
<td class="text-center"><?php echo $employee['endorsement_no'] ?></td> <td><?php echo $employee['endorsement_no'] ?></td>
<td class="text-center"><?php echo $employee['endorsement_description'] ?></td> <td class="text-center"><?php echo $employee['endorsement_description'] ?></td>
<td class="text-center"><?php echo $employee['client_name'] ? $employee['client_name'] . ' ( ' . $employee['client_short_name'] . ' ) ' : 'N/A' ?></td> <td><?php echo $employee['client_name'] ? $employee['client_name'] . ' ( ' . $employee['client_short_name'] . ' ) ' : 'N/A' ?></td>
<td class="text-center"><?php echo $employee['insurer_name'] ? $employee['insurer_name'] . ' ( ' . $employee['insurer_short_name'] . ' ) ' : 'N/A' ?></td> <td><?php echo $employee['insurer_name'] ? $employee['insurer_name'] . ' ( ' . $employee['insurer_short_name'] . ' ) ' : 'N/A' ?></td>
<td class="text-center"><?php echo $employee['agent_name'] ?? 'N/A' ?></td> <td><?php echo $employee['agent_name'] ?? 'N/A' ?></td>
<td class="text-center"><?php echo $employee['manager_name'] ?? 'N/A' ?></td> <td><?php echo $employee['manager_name'] ?? 'N/A' ?></td>
<td class="text-center"><?php if (!empty($employee['created_at'])): <td><?php if (!empty($employee['created_at'])):
$cd = date("j F Y", strtotime($employee['created_at'])); $cd = date("j F Y", strtotime($employee['created_at']));
$ct = date("h:i A", strtotime($employee['created_at'])); $ct = date("h:i A", strtotime($employee['created_at']));
echo $cd . "<br><span class='time'> " . $ct . "</span>"; echo $cd . "<br><span class='time'> " . $ct . "</span>";
endif; ?></td> endif; ?></td>
<td class="text-center"><?php if ($employee['status'] == 'open') { <td><?php if ($employee['status'] == 'open') {
echo '<span class="badge badge-primary">' . $employee['status'] . '</span>'; echo '<span class="badge badge-primary">' . $employee['status'] . '</span>';
} elseif ($employee['status'] == 'inprogress') { } elseif ($employee['status'] == 'inprogress') {
echo '<span class="badge badge-warning">' . $employee['status'] . '</span>'; echo '<span class="badge badge-warning">' . $employee['status'] . '</span>';
@ -182,7 +270,7 @@
} }
?> ?>
</td> </td>
<td class="text-center table-action-cell"> <td class="table-action-cell">
<div class="btn-group dropdown"> <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> <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"> <div class="dropdown-menu dropdown-menu-right">
@ -405,8 +493,8 @@
$(document).ready(function() { $(document).ready(function() {
var table = $('#tickets-table').DataTable({ nhanceListDataTableBeforeInit();
scrollX: true, var table = $('#retail-endorsement-list-table').DataTable(nhanceMergeListDataTableOptions({
dom: "<'row'<'col-12 d-flex justify-content-between align-items-center'<'datatable-search dataTables_filter'f><'datatable-buttons dt-buttons'B>>>" + dom: "<'row'<'col-12 d-flex justify-content-between align-items-center'<'datatable-search dataTables_filter'f><'datatable-buttons dt-buttons'B>>>" +
"<'row'<'col-sm-12'tr>>" + "<'row'<'col-sm-12'tr>>" +
"<'row align-items-center'<'col-5 text-start'i><'col-7 d-flex justify-content-end align-items-center'<'me-2'l>p>>", "<'row align-items-center'<'col-5 text-start'i><'col-7 d-flex justify-content-end align-items-center'<'me-2'l>p>>",
@ -469,19 +557,25 @@
}, },
paging: true, paging: true,
// pagingType: 'full_numbers' // pagingType: 'full_numbers'
columnDefs: [{ columnDefs: [
type: 'scientific', <?php for ($i = 0; $i < $ret_col_count; $i++) : ?>
targets: 0 <?php if ($i === 0) : ?>
} // Apply custom sorting type to the first column { targets: 0, width: '<?= (int) $ret_col_width_px[0] ?>px', type: 'scientific' },
<?php else : ?>
{ targets: <?= $i ?>, width: '<?= (int) $ret_col_width_px[$i] ?>px' },
<?php endif; ?>
<?php endfor; ?>
], ],
}); }));
nhanceListDataTableAfterInit();
nhanceListDataTableBindAdjust(table);
function applyBottomRowDropup() { function applyBottomRowDropup() {
if (!table) return; if (!table) return;
const currentRows = table.rows({ page: 'current' }).nodes().toArray(); const currentRows = table.rows({ page: 'current' }).nodes().toArray();
$('#tickets-table tbody tr').removeClass('nh-force-dropup'); $('#retail-endorsement-list-table tbody tr').removeClass('nh-force-dropup');
$('#tickets-table tbody tr td.table-action-cell .btn-group.dropdown').removeClass('dropup'); $('#retail-endorsement-list-table tbody tr td.table-action-cell .btn-group.dropdown').removeClass('dropup');
// Mark last two rows on current page to open action menu upward. // Mark last two rows on current page to open action menu upward.
const targetCount = Math.min(2, currentRows.length); const targetCount = Math.min(2, currentRows.length);
@ -494,7 +588,7 @@
} }
applyBottomRowDropup(); applyBottomRowDropup();
$('#tickets-table').on('draw.dt', applyBottomRowDropup); $('#retail-endorsement-list-table').on('draw.dt', applyBottomRowDropup);
}); });

View File

@ -1,6 +1,68 @@
<?php
helper('datatable_view');
$rto_header_labels = ['S.No.', 'RTO Office at', 'RTO Code', 'RTO State', 'Action'];
$rto_col_count = count($rto_header_labels);
$rto_col_max_len = array_fill(0, $rto_col_count, 0);
for ($i = 0; $i < $rto_col_count; $i++) {
$rto_col_max_len[$i] = mb_strlen($rto_header_labels[$i]);
}
if (isset($data) && is_array($data)) {
$rto_sl = 0;
foreach ($data as $row) {
++$rto_sl;
$rto_col_max_len[0] = max($rto_col_max_len[0], mb_strlen((string) $rto_sl));
$rto_col_max_len[1] = max($rto_col_max_len[1], mb_strlen((string) ($row['rto_name'] ?? '')));
$rto_col_max_len[2] = max($rto_col_max_len[2], mb_strlen((string) ($row['rto_code'] ?? '')));
$rto_col_max_len[3] = max($rto_col_max_len[3], mb_strlen((string) ($row['rto_state'] ?? '')));
$rto_col_max_len[4] = max($rto_col_max_len[4], 4);
}
}
$rto_col_min_px = [48, 140, 88, 120, 72];
$rto_col_max_px = [64, 400, 120, 200, 88];
$rto_col_width_px = nhance_dt_column_widths_px($rto_header_labels, $rto_col_max_len, $rto_col_min_px, $rto_col_max_px);
?>
<style> <style>
.dataTables_filter {position: absolute;} .dataTables_filter {position: absolute;}
.dataTables_length label {height: 21px !important;} .dataTables_length label {height: 21px !important;}
<?php for ($i = 0; $i < $rto_col_count; $i++) : ?>
#rto-master-list-table_wrapper .dataTables_scrollHead table thead th:nth-child(<?= $i + 1 ?>),
#rto-master-list-table thead th:nth-child(<?= $i + 1 ?>) {
min-width: <?= (int) $rto_col_width_px[$i] ?>px;
width: <?= (int) $rto_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
overflow: visible !important;
}
#rto-master-list-table tbody td:nth-child(<?= $i + 1 ?>) {
width: <?= (int) $rto_col_width_px[$i] ?>px;
max-width: <?= (int) $rto_col_width_px[$i] ?>px;
min-width: <?= (int) $rto_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
}
<?php endfor; ?>
#rto-master-list-table tbody td:nth-child(1),
#rto-master-list-table tbody td:nth-child(2),
#rto-master-list-table tbody td:nth-child(3),
#rto-master-list-table tbody td:nth-child(4) {
overflow: hidden;
text-overflow: ellipsis;
}
#rto-master-list-table tbody td:nth-child(5) {
overflow: visible;
text-overflow: clip;
}
#rto-master-list-table tbody td {
padding: 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
#rto-master-list-table thead th {
padding: 5px 2.35rem 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
</style> </style>
<!-- End ADD and EDIT Page HTML --> <!-- End ADD and EDIT Page HTML -->
@ -8,7 +70,7 @@
<div class="col-12"> <div class="col-12">
<div class="card"> <div class="card">
<div class="card-body"> <div class="card-body">
<table data-custom-table-css="table" class="table table-sm m-0 table-centered dt-responsive nowrap w-100" cellspacing="a" id="user-table"> <table data-custom-table-css="table" class="table table-sm m-0 table-centered dt-responsive nowrap w-100" cellspacing="a" id="rto-master-list-table">
<thead class="bg-light"> <thead class="bg-light">
<tr> <tr>
<th class="font-weight-medium">S.No.</th> <th class="font-weight-medium">S.No.</th>
@ -23,7 +85,7 @@
<?php if(isset($data)) { $slno = 1; ?> <?php if(isset($data)) { $slno = 1; ?>
<?php foreach($data as $index => $row) { ?> <?php foreach($data as $index => $row) { ?>
<tr> <tr>
<td class="text-center"><?= $slno++; ?></td> <td><?= $slno++; ?></td>
<td><?= $row['rto_name']; ?></td> <td><?= $row['rto_name']; ?></td>
<td><?= $row['rto_code']; ?></td> <td><?= $row['rto_code']; ?></td>
<td><?= $row['rto_state']; ?></td> <td><?= $row['rto_state']; ?></td>
@ -129,9 +191,9 @@
<script> <script>
var table; var table;
$(document).ready(function () { $(document).ready(function () {
var ticketsTable = $('#user-table'); var ticketsTable = $('#rto-master-list-table');
ticketsTable.DataTable({ nhanceListDataTableBeforeInit();
scrollX: true, table = ticketsTable.DataTable(nhanceMergeListDataTableOptions({
// dom: "<'row'<'col-sm-7'f><'col-sm-5 text-right'B>>" + // Filter left, buttons right // dom: "<'row'<'col-sm-7'f><'col-sm-5 text-right'B>>" + // Filter left, buttons right
// "<'row'<'col-sm-12'tr>>" + // "<'row'<'col-sm-12'tr>>" +
// "<'row'<'col-sm-5'i><'col-sm-7'p>>", // Pagination at the bottom, without page length selector // "<'row'<'col-sm-5'i><'col-sm-7'p>>", // Pagination at the bottom, without page length selector
@ -179,7 +241,14 @@
paging: true, // Enable pagination paging: true, // Enable pagination
pageLength: 10, // Set default number of rows per page (optional) pageLength: 10, // Set default number of rows per page (optional)
// ordering: false, // ordering: false,
}); columnDefs: [
<?php for ($i = 0; $i < $rto_col_count; $i++) : ?>
{ targets: <?= $i ?>, width: '<?= (int) $rto_col_width_px[$i] ?>px' },
<?php endfor; ?>
],
}));
nhanceListDataTableAfterInit();
nhanceListDataTableBindAdjust(table);
}); });
$('.close').click(function(){ $('.close').click(function(){

View File

@ -64,9 +64,6 @@
#map_emp_modal .modal-backdrop.show { #map_emp_modal .modal-backdrop.show {
opacity: 0.5; /* Darken backdrop for better focus */ opacity: 0.5; /* Darken backdrop for better focus */
} }
th:first-child, td:first-child {
width: 50px; /* Adjust width as needed */
}
.table-responsive { .table-responsive {
overflow-x: auto; overflow-x: auto;
} }
@ -77,14 +74,14 @@ th:first-child, td:first-child {
} }
/* Keep this long header readable and prevent sort icon overlap. */ /* Keep this long header readable and prevent sort icon overlap. */
#tickets-table th.existing-policy-col, #test-members-list-table th.existing-policy-col,
#tickets-table td.existing-policy-col { #test-members-list-table td.existing-policy-col {
min-width: 170px; min-width: 170px;
white-space: nowrap; white-space: nowrap;
} }
/* Action column aligned center in both head and body. */ /* Action column aligned center in both head and body. */
#tickets-table th.action-col { #test-members-list-table th.action-col {
min-width: 90px; min-width: 90px;
text-align: center !important; text-align: center !important;
} }
@ -110,7 +107,104 @@ th:first-child, td:first-child {
</style> </style>
<?php $pro_rata_total = 0; $gst_total = 0 ?> <?php
helper('datatable_view');
$getData = $getData ?? null;
$tm_show_client_branch = isset($getData) && $getData['client_id'] == '0' && $getData['policy_id'] == '0' && $getData['branch_id'] == '0' && ($getData['emp_code'] != '' || $getData['emp_name'] != '' || $getData['status'] != '');
$tm_show_branch = isset($getData) && $getData['client_id'] != '0' && $getData['branch_id'] == '0';
$tm_header_labels = [' ', 'S.No'];
if ($tm_show_client_branch) {
$tm_header_labels[] = 'Client/Branch';
}
if ($tm_show_branch) {
$tm_header_labels[] = 'Branch';
}
$tm_header_labels = array_merge($tm_header_labels, [
'Name', 'EMP Code', 'Relationship', 'Gender', 'Date of Birth',
'Existing Policy Count', 'Action',
]);
$tm_col_count = count($tm_header_labels);
$tm_col_max_len = array_fill(0, $tm_col_count, 0);
for ($i = 0; $i < $tm_col_count; $i++) {
$tm_col_max_len[$i] = mb_strlen($tm_header_labels[$i]);
}
if (isset($employees) && is_array($employees)) {
foreach ($employees as $key => $employee) {
$ci = 0;
$tm_col_max_len[$ci] = max($tm_col_max_len[$ci], 1);
$ci++;
$tm_col_max_len[$ci] = max($tm_col_max_len[$ci], mb_strlen((string) ($key + 1)));
$ci++;
if ($tm_show_client_branch) {
$cb = ($employee['client_short_name'] ?? '') . ' - ' . ($employee['client_branch_name'] ?? '');
$tm_col_max_len[$ci] = max($tm_col_max_len[$ci], mb_strlen($cb));
$ci++;
}
if ($tm_show_branch) {
$tm_col_max_len[$ci] = max($tm_col_max_len[$ci], mb_strlen((string) ($employee['client_branch_name'] ?? '')));
$ci++;
}
$tm_col_max_len[$ci] = max($tm_col_max_len[$ci], mb_strlen((string) ($employee['name'] ?? '')));
$ci++;
$tm_col_max_len[$ci] = max($tm_col_max_len[$ci], mb_strlen((string) ($employee['emp_code'] ?? '')));
$ci++;
$tm_col_max_len[$ci] = max($tm_col_max_len[$ci], mb_strlen((string) ($employee['relationship'] ?? '')));
$ci++;
$tm_col_max_len[$ci] = max($tm_col_max_len[$ci], mb_strlen((string) ($employee['gender'] ?? '')));
$ci++;
$dobStr = '';
if (!empty($employee['dob'])) {
$dobStr = date('d/M/Y', strtotime((string) $employee['dob']));
}
$tm_col_max_len[$ci] = max($tm_col_max_len[$ci], mb_strlen($dobStr));
$ci++;
$tm_col_max_len[$ci] = max($tm_col_max_len[$ci], mb_strlen((string) ($employee['policy_count'] ?? '')));
$ci++;
$tm_col_max_len[$ci] = max($tm_col_max_len[$ci], 4);
}
}
$tm_col_min_px = array_fill(0, $tm_col_count, 80);
$tm_col_max_px = array_fill(0, $tm_col_count, 360);
$tm_col_min_px[0] = 44;
$tm_col_max_px[0] = 56;
$tm_col_min_px[1] = 48;
$tm_col_max_px[1] = 72;
$tm_col_min_px[$tm_col_count - 2] = 120;
$tm_col_max_px[$tm_col_count - 2] = 400;
$tm_col_min_px[$tm_col_count - 1] = 72;
$tm_col_max_px[$tm_col_count - 1] = 96;
$tm_col_width_px = nhance_dt_column_widths_px($tm_header_labels, $tm_col_max_len, $tm_col_min_px, $tm_col_max_px);
$pro_rata_total = 0;
$gst_total = 0;
?>
<style>
<?php for ($i = 0; $i < $tm_col_count; $i++) : ?>
#test-members-list-table_wrapper .dataTables_scrollHead table thead th:nth-child(<?= $i + 1 ?>),
#test-members-list-table thead th:nth-child(<?= $i + 1 ?>) {
min-width: <?= (int) $tm_col_width_px[$i] ?>px;
width: <?= (int) $tm_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
overflow: visible !important;
}
#test-members-list-table tbody td:nth-child(<?= $i + 1 ?>) {
width: <?= (int) $tm_col_width_px[$i] ?>px;
max-width: <?= (int) $tm_col_width_px[$i] ?>px;
min-width: <?= (int) $tm_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
}
<?php endfor; ?>
#test-members-list-table tbody td:not(:last-child) {
overflow: hidden;
text-overflow: ellipsis;
}
#test-members-list-table tbody td:last-child {
overflow: visible;
text-overflow: clip;
}
</style>
<div class="row" id="client_list"> <div class="row" id="client_list">
<div class="col-12"> <div class="col-12">
@ -121,7 +215,7 @@ th:first-child, td:first-child {
<h3 style="position: relative;">Employees</h3> <h3 style="position: relative;">Employees</h3>
</div> </div>
</div> --> </div> -->
<table data-custom-table-css="table" class="table mb-0 nowrap" cellspacing="0" id="tickets-table"> <table data-custom-table-css="table" class="table mb-0 nowrap" cellspacing="0" id="test-members-list-table">
<thead class="bg-light"> <thead class="bg-light">
<tr> <tr>
<th><input type="checkbox" id="selectAll" onclick="toggleAll(this)">&nbsp;</th> <th><input type="checkbox" id="selectAll" onclick="toggleAll(this)">&nbsp;</th>
@ -444,15 +538,12 @@ th:first-child, td:first-child {
}); });
$(document).ready(function() { $(document).ready(function() {
var ticketsTable = $('#tickets-table'); var ticketsTable = $('#test-members-list-table');
if (ticketsTable.length) { if (ticketsTable.length) {
var table = ticketsTable.DataTable({ nhanceListDataTableBeforeInit();
scrollX: true, var nhTestMembersTable = ticketsTable.DataTable(nhanceMergeListDataTableOptions({
// dom: "<'row'<'col-sm-6'f><'col-sm-6 text-right'B>>" + // Filter left, buttons right dom: "<'row'<'col-sm-6'f><'col-sm-6 text-right'B>>" +
// "<'row'<'col-sm-12'tr>>" +
// "<'row'<'col-sm-5'i><'col-sm-7'p>>", // Pagination at the bottom, without page length selector
dom: "<'row'<'col-sm-6'f><'col-sm-6 text-right'B>>" + // Filter left, buttons right
"<'row'<'col-sm-12'tr>>" + "<'row'<'col-sm-12'tr>>" +
"<'row align-items-center'<'col-5 text-start'i><'col-7 d-flex justify-content-end align-items-center'<'me-2'l>p>>", "<'row align-items-center'<'col-5 text-start'i><'col-7 d-flex justify-content-end align-items-center'<'me-2'l>p>>",
lengthMenu: [[10, 20, 50, 100], [10, 20, 50, 100]], lengthMenu: [[10, 20, 50, 100], [10, 20, 50, 100]],
@ -486,18 +577,24 @@ th:first-child, td:first-child {
next: '►' next: '►'
} }
}, },
paging: true, // Enable pagination paging: true,
pageLength: 10 // Set default number of rows per page (optional) pageLength: 10,
}); columnDefs: [
<?php for ($i = 0; $i < $tm_col_count; $i++) : ?>
{ targets: <?= $i ?>, width: '<?= (int) $tm_col_width_px[$i] ?>px' },
<?php endfor; ?>
],
}));
nhanceListDataTableAfterInit();
nhanceListDataTableBindAdjust(nhTestMembersTable);
function applyBottomRowDropup() { function applyBottomRowDropup() {
if (!table) return; if (!nhTestMembersTable) return;
const currentRows = table.rows({ page: 'current' }).nodes().toArray(); const currentRows = nhTestMembersTable.rows({ page: 'current' }).nodes().toArray();
$('#tickets-table tbody tr').removeClass('nh-force-dropup'); $('#test-members-list-table tbody tr').removeClass('nh-force-dropup');
$('#tickets-table tbody tr td.table-action-cell .btn-group.dropdown').removeClass('dropup'); $('#test-members-list-table tbody tr td.table-action-cell .btn-group.dropdown').removeClass('dropup');
// Mark last two rows on current page to open action menu upward.
const targetCount = Math.min(2, currentRows.length); const targetCount = Math.min(2, currentRows.length);
for (let i = 0; i < targetCount; i++) { for (let i = 0; i < targetCount; i++) {
const row = currentRows[currentRows.length - 1 - i]; const row = currentRows[currentRows.length - 1 - i];
@ -507,7 +604,7 @@ th:first-child, td:first-child {
} }
} }
applyBottomRowDropup(); applyBottomRowDropup();
$('#tickets-table').on('draw.dt', applyBottomRowDropup); $('#test-members-list-table').on('draw.dt', applyBottomRowDropup);
} else { } else {
console.error("Table not found."); console.error("Table not found.");
} }

View File

@ -1,3 +1,50 @@
<?php
helper('datatable_view');
$thz_header_labels = [
'Ticket ID', 'Name', 'Policy Number', 'Ticket Type', 'Subject', 'Status', 'Assign To', 'Created At', 'Updated At',
];
$thz_col_count = count($thz_header_labels);
$thz_col_max_len = array_fill(0, $thz_col_count, 0);
for ($i = 0; $i < $thz_col_count; $i++) {
$thz_col_max_len[$i] = mb_strlen($thz_header_labels[$i]);
}
$ticket_data = $ticket_data ?? [];
foreach ($ticket_data as $row) {
$thz_col_max_len[0] = max($thz_col_max_len[0], mb_strlen((string) ($row['thz_id'] ?? '')));
$namePlain = (string) ($row['name'] ?? '');
if (! empty($row['empcode'])) {
$namePlain .= ' (' . $row['empcode'] . ')';
}
if (! empty($row['mobile'])) {
$namePlain .= ' ' . $row['mobile'];
}
$thz_col_max_len[1] = max($thz_col_max_len[1], mb_strlen($namePlain));
$pol = (! empty($row['policy_no']) && strtolower((string) $row['policy_no']) !== 'null') ? (string) $row['policy_no'] : 'N/A';
$thz_col_max_len[2] = max($thz_col_max_len[2], mb_strlen($pol));
$tt = $row['ticket_type'] ? (string) $row['ticket_type'] : 'N/A';
$thz_col_max_len[3] = max($thz_col_max_len[3], mb_strlen($tt));
$subject = $row['subject'] ? (string) $row['subject'] : 'N/A';
$subDisp = (strlen($subject) > 18) ? substr($subject, 0, 18) . '...' : $subject;
$thz_col_max_len[4] = max($thz_col_max_len[4], mb_strlen($subDisp));
$st = $row['status'] ? (string) $row['status'] : 'N/A';
$thz_col_max_len[5] = max($thz_col_max_len[5], mb_strlen($st));
$as = $row['assignee_name'] ? (string) $row['assignee_name'] : 'N/A';
$thz_col_max_len[6] = max($thz_col_max_len[6], mb_strlen($as));
$cr = '';
if (! empty($row['created_at'])) {
$cr = date('j M Y', strtotime((string) $row['created_at'])) . ' ' . date('h:i A', strtotime((string) $row['created_at']));
}
$thz_col_max_len[7] = max($thz_col_max_len[7], mb_strlen($cr));
$ur = '';
if (! empty($row['updated_at'])) {
$ur = date('j M Y', strtotime((string) $row['updated_at'])) . ' ' . date('h:i A', strtotime((string) $row['updated_at']));
}
$thz_col_max_len[8] = max($thz_col_max_len[8], mb_strlen($ur));
}
$thz_col_min_px = [72, 160, 120, 100, 120, 88, 120, 140, 140];
$thz_col_max_px = [120, 360, 280, 220, 400, 160, 280, 220, 220];
$thz_col_width_px = nhance_dt_column_widths_px($thz_header_labels, $thz_col_max_len, $thz_col_min_px, $thz_col_max_px);
?>
<style> <style>
.table th, .table th,
.table td { .table td {
@ -51,6 +98,48 @@ beccause = dataTables_length and dataTables_paginate need in same line thats why
</style> </style>
<style>
<?php for ($i = 0; $i < $thz_col_count; $i++) : ?>
#thz-table_wrapper .dataTables_scrollHead table thead th:nth-child(<?= $i + 1 ?>),
#thz-table thead th:nth-child(<?= $i + 1 ?>) {
min-width: <?= (int) $thz_col_width_px[$i] ?>px;
width: <?= (int) $thz_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
overflow: visible !important;
}
#thz-table tbody td:nth-child(<?= $i + 1 ?>) {
width: <?= (int) $thz_col_width_px[$i] ?>px;
max-width: <?= (int) $thz_col_width_px[$i] ?>px;
min-width: <?= (int) $thz_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
}
<?php endfor; ?>
#thz-table tbody td:nth-child(1),
#thz-table tbody td:nth-child(2),
#thz-table tbody td:nth-child(3),
#thz-table tbody td:nth-child(4),
#thz-table tbody td:nth-child(5),
#thz-table tbody td:nth-child(6),
#thz-table tbody td:nth-child(7),
#thz-table tbody td:nth-child(8),
#thz-table tbody td:nth-child(9) {
overflow: hidden;
text-overflow: ellipsis;
}
#thz-table tbody td {
padding: 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
#thz-table thead th {
padding: 5px 2.35rem 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
</style>
<div class="row" id="ticket_list"> <div class="row" id="ticket_list">
<div class="col-12"> <div class="col-12">
<div class="card"> <div class="card">
@ -77,7 +166,7 @@ beccause = dataTables_length and dataTables_paginate need in same line thats why
<?php if(isset($ticket_data)) { ?> <?php if(isset($ticket_data)) { ?>
<?php foreach($ticket_data as $index => $row){ ?> <?php foreach($ticket_data as $index => $row){ ?>
<tr data-id="<?= $row['thz_id']; ?>" style="cursor: pointer;"> <tr data-id="<?= $row['thz_id']; ?>" style="cursor: pointer;">
<td class="text-center"><?php echo $row['thz_id']; ?></td> <td><?php echo $row['thz_id']; ?></td>
<td class="text-left"><?php echo $row['name']; ?> <td class="text-left"><?php echo $row['name']; ?>
<span class="text-custom-grey"><?php if (!empty($row['empcode'])): echo '('.$row['empcode'].')'; endif; ?></span><br> <span class="text-custom-grey"><?php if (!empty($row['empcode'])): echo '('.$row['empcode'].')'; endif; ?></span><br>
<span class="text-custom-grey"><?php if (!empty($row['mobile'])): echo $row['mobile']; endif; ?></span> <span class="text-custom-grey"><?php if (!empty($row['mobile'])): echo $row['mobile']; endif; ?></span>
@ -340,8 +429,8 @@ beccause = dataTables_length and dataTables_paginate need in same line thats why
var ticketsTable = $('#thz-table'); var ticketsTable = $('#thz-table');
if (ticketsTable.length) { if (ticketsTable.length) {
ticketsTable.DataTable({ nhanceListDataTableBeforeInit();
scrollX: true, var nhThzTable = ticketsTable.DataTable(nhanceMergeListDataTableOptions({
// dom: "<'row'<'col-sm-7'f><'col-sm-5 text-right'B>>" + // Filter left, buttons right // dom: "<'row'<'col-sm-7'f><'col-sm-5 text-right'B>>" + // Filter left, buttons right
// "<'row'<'col-sm-12'tr>>" + // "<'row'<'col-sm-12'tr>>" +
// "<'row'<'col-sm-5'i><'col-sm-7'p>>", // Pagination at the bottom, without page length selector // "<'row'<'col-sm-5'i><'col-sm-7'p>>", // Pagination at the bottom, without page length selector
@ -395,8 +484,15 @@ beccause = dataTables_length and dataTables_paginate need in same line thats why
}, },
paging: true, paging: true,
pageLength: 10, pageLength: 10,
order: [[0, 'desc']] order: [[0, 'desc']],
}); columnDefs: [
<?php for ($i = 0; $i < $thz_col_count; $i++) : ?>
{ targets: <?= $i ?>, width: '<?= (int) $thz_col_width_px[$i] ?>px' },
<?php endfor; ?>
],
}));
nhanceListDataTableAfterInit();
nhanceListDataTableBindAdjust(nhThzTable);
} else { } else {
console.error("Table not found."); console.error("Table not found.");
} }

View File

@ -465,15 +465,23 @@
let ticket_master_id = $('#ticket_master_id').val(); let ticket_master_id = $('#ticket_master_id').val();
console.log({ticket_master_id}); console.log({ticket_master_id});
if (!ticket_master_id) {
toastr.warning('Claim ID not found. Please ensure the form is loaded.', 'Warning');
return;
}
let requestData = { let requestData = {
claim_id: ticket_master_id, claim_id: ticket_master_id,
}; };
let url = '<?= base_url('ticket/getTpaClaimStatus') ?>'; let url = '<?= base_url('ticket/getTpaClaimStatus') ?>';
$('.loader').fadeIn();
$('.loader-mask').fadeIn();
// Send AJAX request // Send AJAX request
sendAjaxRequestForGlobal(url, 'GET', requestData, function(response) { sendAjaxRequestForGlobal(url, 'GET', requestData, function(response) {
$('.loader').fadeOut();
$('.loader-mask').delay(350).fadeOut('slow');
console.log('Data fetched successfully:', response); console.log('Data fetched successfully:', response);
@ -485,6 +493,8 @@
} }
}, function(xhr, status, error) { }, function(xhr, status, error) {
$('.loader').fadeOut();
$('.loader-mask').delay(350).fadeOut('slow');
console.error('Error fetching data:', error); console.error('Error fetching data:', error);
console.error(xhr.responseText); console.error(xhr.responseText);
toastr.error('An error occurred while saving docs.', 'Error'); toastr.error('An error occurred while saving docs.', 'Error');

View File

@ -1,3 +1,24 @@
<?php
helper('datatable_view');
$tf_header_labels = ['Claim Number', 'Emp Code', 'Emp name', 'Corporate name'];
$tf_col_count = count($tf_header_labels);
$tf_col_max_len = array_fill(0, $tf_col_count, 0);
for ($i = 0; $i < $tf_col_count; $i++) {
$tf_col_max_len[$i] = mb_strlen($tf_header_labels[$i]);
}
$feedback_rows = $feedback_data ?? [];
if (is_array($feedback_rows)) {
foreach ($feedback_rows as $data) {
$tf_col_max_len[0] = max($tf_col_max_len[0], mb_strlen((string) ($data['claim_number'] ?: 'N/A')));
$tf_col_max_len[1] = max($tf_col_max_len[1], mb_strlen((string) ($data['emp_code'] ?: 'N/A')));
$tf_col_max_len[2] = max($tf_col_max_len[2], mb_strlen((string) ($data['emp_name'] ?: 'N/A')));
$tf_col_max_len[3] = max($tf_col_max_len[3], mb_strlen((string) ($data['client_name'] ?: 'N/A')));
}
}
$tf_col_min_px = [120, 88, 120, 140];
$tf_col_max_px = [360, 200, 400, 520];
$tf_col_width_px = nhance_dt_column_widths_px($tf_header_labels, $tf_col_max_len, $tf_col_min_px, $tf_col_max_px);
?>
<style> <style>
.table th, .table th,
.table td { .table td {
@ -26,13 +47,26 @@ table.dataTable tbody td {
} }
</style> </style>
<style> <style>
.table th:nth-child(1), <?php for ($i = 0; $i < $tf_col_count; $i++) : ?>
.table td:nth-child(1) { #ticket-feedback-list-table_wrapper .dataTables_scrollHead table thead th:nth-child(<?= $i + 1 ?>),
max-width: 200px !important; #ticket-feedback-list-table thead th:nth-child(<?= $i + 1 ?>) {
min-width: 100px !important; min-width: <?= (int) $tf_col_width_px[$i] ?>px;
overflow: hidden !important; width: <?= (int) $tf_col_width_px[$i] ?>px;
text-overflow: ellipsis !important; box-sizing: border-box;
white-space: nowrap !important; vertical-align: middle;
overflow: visible !important;
}
#ticket-feedback-list-table tbody td:nth-child(<?= $i + 1 ?>) {
width: <?= (int) $tf_col_width_px[$i] ?>px;
max-width: <?= (int) $tf_col_width_px[$i] ?>px;
min-width: <?= (int) $tf_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
}
<?php endfor; ?>
#ticket-feedback-list-table tbody td {
overflow: hidden;
text-overflow: ellipsis;
} }
.dataTables_length label {height: 21px !important;} .dataTables_length label {height: 21px !important;}
@ -53,7 +87,7 @@ table.dataTable tbody td {
</div> --> </div> -->
<div class="table-responsive"> <div class="table-responsive">
<table data-custom-table-css="table" id="scroll-horizontal-datatable" class="table w-100 nowrap"> <table data-custom-table-css="table" id="ticket-feedback-list-table" class="table w-100 nowrap">
<thead class="bg-light"> <thead class="bg-light">
<tr> <tr>
<th>Claim Number</th> <th>Claim Number</th>
@ -92,30 +126,13 @@ table.dataTable tbody td {
// Datatable document ready // Datatable document ready
$(document).ready(function() { $(document).ready(function() {
var ticketsTable = $('#scroll-horizontal-datatable'); var ticketsTable = $('#ticket-feedback-list-table');
if (ticketsTable.length) { if (ticketsTable.length) {
ticketsTable.DataTable({ nhanceListDataTableBeforeInit();
scrollX: true, var nhTicketFeedbackTable = ticketsTable.DataTable(nhanceMergeListDataTableOptions({
// dom: "<'row'<'col-sm-6'f><'col-sm-6 text-right'B>>" + // Filter left, buttons right dom: "<'row'<'col-sm-6'f><'col-sm-6 text-right'B>>" +
// "<'row'<'col-sm-12'tr>>" +
// "<'row'<'col-sm-5'i><'col-sm-7'p>>", // Pagination at the bottom, without page length selector
// buttons: [{
// extend: 'csv',
// text: 'CSV',
// title: 'Claim-List',
// },
// {
// extend: 'excel',
// text: 'Excel',
// title: 'claim-List',
// exportOptions: {
// orthogonal: 'sort'
// },
// },
// ],
dom: "<'row'<'col-sm-6'f><'col-sm-6 text-right'B>>" + // Filter left, buttons right
"<'row'<'col-sm-12'tr>>" + "<'row'<'col-sm-12'tr>>" +
"<'row align-items-center'<'col-5 text-start'i><'col-7 d-flex justify-content-end align-items-center'<'me-2'l>p>>", "<'row align-items-center'<'col-5 text-start'i><'col-7 d-flex justify-content-end align-items-center'<'me-2'l>p>>",
lengthMenu: [[10, 20, 50, 100], [10, 20, 50, 100]], lengthMenu: [[10, 20, 50, 100], [10, 20, 50, 100]],
@ -156,10 +173,17 @@ $(document).ready(function() {
searchPlaceholder: "Search", searchPlaceholder: "Search",
emptyTable: '<div class="text-center text-muted">No Data found</div>' emptyTable: '<div class="text-center text-muted">No Data found</div>'
}, },
paging: true, // Enable pagination paging: true,
pageLength: 10, // Set default number of rows per page (optional) pageLength: 10,
ordering: false, ordering: false,
}); columnDefs: [
<?php for ($i = 0; $i < $tf_col_count; $i++) : ?>
{ targets: <?= $i ?>, width: '<?= (int) $tf_col_width_px[$i] ?>px' },
<?php endfor; ?>
],
}));
nhanceListDataTableAfterInit();
nhanceListDataTableBindAdjust(nhTicketFeedbackTable);
} else { } else {
console.error("Table atet found."); console.error("Table atet found.");
} }
@ -185,4 +209,4 @@ $(document).ready(function() {
} }
</script> </script>

View File

@ -429,10 +429,26 @@
value="<?= isset($ticket_data['approved_date']) ? $ticket_data['approved_date'] : '' ?>" name="approved_date"> value="<?= isset($ticket_data['approved_date']) ? $ticket_data['approved_date'] : '' ?>" name="approved_date">
</div> </div>
<div class="form-group col-md-6 approved" style="display: none;"> <div class="form-group col-md-3 approved" style="display: none;">
<label class="label-font-size" for="approved_letter">Approved Letter</label> <label class="label-font-size" for="approved_letter">Approved Letter URL</label>
<input type="text" class="form-control" id="approved_letter" placeholder="Enter Approved Letter" <input
value="<?= isset($ticket_data['approved_letter']) ? $ticket_data['approved_letter'] : '' ?>" name="approved_letter"> type="text"
class="form-control"
id="approved_letter"
placeholder="Enter Approved Letter URL"
value="<?= isset($ticket_data['approved_letter']) ? $ticket_data['approved_letter'] : '' ?>"
name="approved_letter">
</div>
<div class="form-group col-md-3 approved" style="display: none;">
<label class="label-font-size" for="approved_letter_file">Approved Letter PDF</label>
<input
type="file"
class="form-control"
id="approved_letter_file"
name="approved_letter_file"
accept=".pdf,application/pdf">
<small class="text-muted">Only PDF allowed.</small>
</div> </div>
<div class="form-group col-md-6 approved" style="display: none;"> <div class="form-group col-md-6 approved" style="display: none;">
@ -453,12 +469,23 @@
value="<?= isset($ticket_data['settled_date']) ? $ticket_data['settled_date'] : '' ?>" name="settled_date"> value="<?= isset($ticket_data['settled_date']) ? $ticket_data['settled_date'] : '' ?>" name="settled_date">
</div> </div>
<div class="form-group col-md-6 settled" style="display: none;"> <div class="form-group col-md-3 settled" style="display: none;">
<label class="label-font-size" for="settle_letter">Settle Letter</label> <label class="label-font-size" for="settle_letter">Settle Letter URL</label>
<input type="text" class="form-control" id="settle_letter" placeholder="Enter Settle Letter" <input type="text" class="form-control" id="settle_letter" placeholder="Enter Settle Letter URL"
value="<?= isset($ticket_data['settle_letter']) ? $ticket_data['settle_letter'] : '' ?>" name="settle_letter"> value="<?= isset($ticket_data['settle_letter']) ? $ticket_data['settle_letter'] : '' ?>" name="settle_letter">
</div> </div>
<div class="form-group col-md-3 settled" style="display: none;">
<label class="label-font-size" for="settle_letter_file">Settle Letter PDF</label>
<input
type="file"
class="form-control"
id="settle_letter_file"
name="settle_letter_file"
accept=".pdf,application/pdf">
<small class="text-muted">Only PDF allowed.</small>
</div>
<div class="form-group col-md-3 payment" style="display: none;"> <div class="form-group col-md-3 payment" style="display: none;">
<label class="label-font-size" for="pay_initiate_date">Payment Initiate Date</label> <label class="label-font-size" for="pay_initiate_date">Payment Initiate Date</label>
<input type="text" class="form-control datepicker" id="pay_initiate_date" placeholder="Select Payment Initiate Date" <input type="text" class="form-control datepicker" id="pay_initiate_date" placeholder="Select Payment Initiate Date"
@ -619,6 +646,8 @@
console.log("extraFields", extraFields); console.log("extraFields", extraFields);
claimStatusFieldChanges(extraFields); claimStatusFieldChanges(extraFields);
handleTPARequired(tpa_id_for_hid_filed); handleTPARequired(tpa_id_for_hid_filed);
// syncApprovedLetterInputs();
// syncSettleLetterInputs();
}) })
// function updateClaimStatusDisplay(value) { // function updateClaimStatusDisplay(value) {
@ -723,6 +752,8 @@
$field.prop('required', false); $field.prop('required', false);
var $parentDiv = $field.closest("div"); var $parentDiv = $field.closest("div");
$parentDiv.find("label[for='approved_description'] .text-danger").remove(); $parentDiv.find("label[for='approved_description'] .text-danger").remove();
syncApprovedLetterInputs();
syncSettleLetterInputs();
} }
$('#claim_status_id').on('change', function() { $('#claim_status_id').on('change', function() {
@ -774,6 +805,95 @@
}); });
function validateApprovedLetterPdf(fileInput) {
const file = fileInput.files && fileInput.files[0] ? fileInput.files[0] : null;
if (!file) {
return true;
}
const fileName = (file.name || '').toLowerCase();
const isPdfByName = fileName.endsWith('.pdf');
const mimeType = (file.type || '').toLowerCase();
const isPdfByType = mimeType === '' || mimeType === 'application/pdf' || mimeType === 'application/x-pdf';
const fieldLabel = fileInput.id === 'settle_letter_file' ? 'Settle Letter' : 'Approved Letter';
if (!isPdfByName || !isPdfByType) {
fileInput.value = '';
toastr.warning('Only PDF files are allowed for ' + fieldLabel + '.', 'Warning');
return false;
}
return true;
}
function syncApprovedLetterInputs() {
const $urlInput = $('#approved_letter');
const $fileInput = $('#approved_letter_file');
if (!$urlInput.length || !$fileInput.length) {
return;
}
const hasUrl = $.trim($urlInput.val()) !== '';
const hasFile = $fileInput[0].files && $fileInput[0].files.length > 0;
const isApprovedSectionVisible = $urlInput.closest('.approved').is(':visible');
$fileInput.prop('disabled', hasUrl);
$urlInput.prop('disabled', hasFile);
// Keep the file optional; URL remains conditionally required for approved state unless file is present.
$fileInput.prop('required', false);
$urlInput.prop('required', isApprovedSectionVisible && !hasFile);
}
function syncSettleLetterInputs() {
const $urlInput = $('#settle_letter');
const $fileInput = $('#settle_letter_file');
if (!$urlInput.length || !$fileInput.length) {
return;
}
const hasUrl = $.trim($urlInput.val()) !== '';
const hasFile = $fileInput[0].files && $fileInput[0].files.length > 0;
const isSettledSectionVisible = $urlInput.closest('.settled').is(':visible');
$fileInput.prop('disabled', hasUrl);
$urlInput.prop('disabled', hasFile);
$fileInput.prop('required', false);
$urlInput.prop('required', isSettledSectionVisible && !hasFile);
}
function enforceLetterPairRules() {
syncApprovedLetterInputs();
syncSettleLetterInputs();
}
$('#approved_letter').on('input blur', function () {
enforceLetterPairRules();
});
$('#approved_letter_file').on('change', function () {
if (validateApprovedLetterPdf(this)) {
enforceLetterPairRules();
} else {
enforceLetterPairRules();
}
});
$('#settle_letter').on('input blur', function () {
enforceLetterPairRules();
});
$('#settle_letter_file').on('change', function () {
if (validateApprovedLetterPdf(this)) {
enforceLetterPairRules();
} else {
enforceLetterPairRules();
}
});
function claimStatusFieldChanges(fields) { function claimStatusFieldChanges(fields) {
fields.forEach(function(fieldId) { fields.forEach(function(fieldId) {
@ -789,6 +909,13 @@
if ($label.length && !$label.find(".text-danger").length) { if ($label.length && !$label.find(".text-danger").length) {
// $label.append(' <span class="text-danger">*</span>'); // $label.append(' <span class="text-danger">*</span>');
} }
// Keep paired PDF upload visibility in sync with URL field visibility.
if (fieldId === 'approved_letter') {
$('#approved_letter_file').closest('div').show();
} else if (fieldId === 'settle_letter') {
$('#settle_letter_file').closest('div').show();
}
} }
}); });
} }
@ -860,6 +987,9 @@
} }
}); });
// Re-apply URL/file pair rules after bulk required toggles.
enforceLetterPairRules();
} }
$(document).on("input", function(event) { $(document).on("input", function(event) {
@ -870,7 +1000,7 @@
console.log('targetId', targetId); console.log('targetId', targetId);
console.log('fields.includes(targetId)', fields.includes(targetId)); console.log('fields.includes(targetId)', fields.includes(targetId));
if (fields.includes(targetId)) { if (fields.includes(targetId) || targetId == "approved_letter_file" || targetId == "settle_letter_file") {
let $field = $("#" + targetId); let $field = $("#" + targetId);
console.log('$field id', $field); console.log('$field id', $field);
@ -904,9 +1034,14 @@
$field.prop('required', false); $field.prop('required', false);
var $parentDiv = $field.closest("div"); var $parentDiv = $field.closest("div");
$parentDiv.find("label[for='approved_description'] .text-danger").remove(); $parentDiv.find("label[for='approved_description'] .text-danger").remove();
enforceLetterPairRules();
}); });
$('#ticket_form_data').on('submit', function() {
enforceLetterPairRules();
});
// function addRequiredFieldSymbol(field_name) { // function addRequiredFieldSymbol(field_name) {
// // Find the field with the given name // // Find the field with the given name
// var $field = $(`[name="${field_name}"]`); // var $field = $(`[name="${field_name}"]`);

View File

@ -281,12 +281,23 @@
value="<?= isset($ticket_data['approved_date']) ? $ticket_data['approved_date'] : '' ?>" name="approved_date"> value="<?= isset($ticket_data['approved_date']) ? $ticket_data['approved_date'] : '' ?>" name="approved_date">
</div> </div>
<div class="form-group col-md-6 approved" style="display: none;"> <div class="form-group col-md-3 approved" style="display: none;">
<label class="label-font-size" for="approved_letter">Approved Letter</label> <label class="label-font-size" for="approved_letter">Approved Letter URL</label>
<input type="text" class="form-control" id="approved_letter" placeholder="Enter Approved Letter" <input type="text" class="form-control" id="approved_letter" placeholder="Enter Approved Letter URL"
value="<?= isset($ticket_data['approved_letter']) ? $ticket_data['approved_letter'] : '' ?>" name="approved_letter"> value="<?= isset($ticket_data['approved_letter']) ? $ticket_data['approved_letter'] : '' ?>" name="approved_letter">
</div> </div>
<div class="form-group col-md-3 approved" style="display: none;">
<label class="label-font-size" for="approved_letter_file">Approved Letter PDF</label>
<input
type="file"
class="form-control"
id="approved_letter_file"
name="approved_letter_file"
accept=".pdf,application/pdf">
<small class="text-muted">Only PDF allowed.</small>
</div>
<div class="form-group col-md-6 approved" style="display: none;"> <div class="form-group col-md-6 approved" style="display: none;">
<label class="label-font-size" for="approved_description">Approved Description</label> <label class="label-font-size" for="approved_description">Approved Description</label>
<input type="text" class="form-control" id="approved_description" placeholder="Enter Approved Description" <input type="text" class="form-control" id="approved_description" placeholder="Enter Approved Description"
@ -305,12 +316,23 @@
value="<?= isset($ticket_data['settled_date']) ? $ticket_data['settled_date'] : '' ?>" name="settled_date"> value="<?= isset($ticket_data['settled_date']) ? $ticket_data['settled_date'] : '' ?>" name="settled_date">
</div> </div>
<div class="form-group col-md-6 settled" style="display: none;"> <div class="form-group col-md-3 settled" style="display: none;">
<label class="label-font-size" for="settle_letter">Settle Letter</label> <label class="label-font-size" for="settle_letter">Settle Letter URL</label>
<input type="text" class="form-control" id="settle_letter" placeholder="Enter Settle Letter" <input type="text" class="form-control" id="settle_letter" placeholder="Enter Settle Letter URL"
value="<?= isset($ticket_data['settle_letter']) ? $ticket_data['settle_letter'] : '' ?>" name="settle_letter"> value="<?= isset($ticket_data['settle_letter']) ? $ticket_data['settle_letter'] : '' ?>" name="settle_letter">
</div> </div>
<div class="form-group col-md-3 settled" style="display: none;">
<label class="label-font-size" for="settle_letter_file">Settle Letter PDF</label>
<input
type="file"
class="form-control"
id="settle_letter_file"
name="settle_letter_file"
accept=".pdf,application/pdf">
<small class="text-muted">Only PDF allowed.</small>
</div>
<div class="form-group col-md-3 canceled" style="display: none;"> <div class="form-group col-md-3 canceled" style="display: none;">
<label class="label-font-size" for="cancel_remark">Cancel Remark</label> <label class="label-font-size" for="cancel_remark">Cancel Remark</label>
<textarea class="form-control" id="cancel_remark" rows="1" placeholder="Enter Cancel Remark" name="cancel_remark"><?= isset($ticket_data['cancel_remark']) ? $ticket_data['cancel_remark'] : '' ?></textarea> <textarea class="form-control" id="cancel_remark" rows="1" placeholder="Enter Cancel Remark" name="cancel_remark"><?= isset($ticket_data['cancel_remark']) ? $ticket_data['cancel_remark'] : '' ?></textarea>
@ -432,6 +454,8 @@
GlobelExtraFields = extraFields; GlobelExtraFields = extraFields;
console.log("extraFields", extraFields); console.log("extraFields", extraFields);
claimStatusFieldChanges(extraFields); claimStatusFieldChanges(extraFields);
// syncApprovedLetterInputs();
// syncSettleLetterInputs();
}) })
@ -458,6 +482,7 @@
$field.prop('required', false); $field.prop('required', false);
var $parentDiv = $field.closest("div"); var $parentDiv = $field.closest("div");
$parentDiv.find("label[for='approved_description'] .text-danger").remove(); $parentDiv.find("label[for='approved_description'] .text-danger").remove();
enforceLetterPairRules();
} }
@ -465,6 +490,72 @@
updateClaimStatusDisplay($(this).val()); updateClaimStatusDisplay($(this).val());
}); });
function validateApprovedLetterPdf(fileInput) {
const file = fileInput.files && fileInput.files[0] ? fileInput.files[0] : null;
if (!file) {
return true;
}
const fileName = (file.name || '').toLowerCase();
const isPdfByName = fileName.endsWith('.pdf');
const mimeType = (file.type || '').toLowerCase();
const isPdfByType = mimeType === '' || mimeType === 'application/pdf' || mimeType === 'application/x-pdf';
const fieldLabel = fileInput.id === 'settle_letter_file' ? 'Settle Letter' : 'Approved Letter';
if (!isPdfByName || !isPdfByType) {
fileInput.value = '';
toastr.warning('Only PDF files are allowed for ' + fieldLabel + '.', 'Warning');
return false;
}
return true;
}
function syncApprovedLetterInputs() {
const $urlInput = $('#approved_letter');
const $fileInput = $('#approved_letter_file');
if (!$urlInput.length || !$fileInput.length) {
return;
}
const hasUrl = $.trim($urlInput.val()) !== '';
const hasFile = $fileInput[0].files && $fileInput[0].files.length > 0;
const isApprovedSectionVisible = $urlInput.closest('.approved').is(':visible');
$fileInput.prop('disabled', hasUrl);
$urlInput.prop('disabled', hasFile);
$fileInput.prop('required', false);
$urlInput.prop('required', isApprovedSectionVisible && !hasFile);
}
function syncSettleLetterInputs() {
const $urlInput = $('#settle_letter');
const $fileInput = $('#settle_letter_file');
if (!$urlInput.length || !$fileInput.length) {
return;
}
const hasUrl = $.trim($urlInput.val()) !== '';
const hasFile = $fileInput[0].files && $fileInput[0].files.length > 0;
$fileInput.prop('disabled', hasUrl);
$urlInput.prop('disabled', hasFile);
// Settled Letter should remain optional by default.
$fileInput.prop('required', false);
$urlInput.prop('required', false);
$("label[for='settle_letter'] .text-danger").remove();
$("label[for='settle_letter_file'] .text-danger").remove();
}
function enforceLetterPairRules() {
syncApprovedLetterInputs();
syncSettleLetterInputs();
}
function claimStatusFieldChanges(fields) { function claimStatusFieldChanges(fields) {
console.log('fields', fields); console.log('fields', fields);
fields.forEach(function(fieldId) { fields.forEach(function(fieldId) {
@ -480,6 +571,13 @@
if ($label.length && !$label.find(".text-danger").length) { if ($label.length && !$label.find(".text-danger").length) {
// $label.append(' <span class="text-danger">*</span>'); // $label.append(' <span class="text-danger">*</span>');
} }
// Keep paired PDF upload visibility in sync with URL field visibility.
if (fieldId === 'approved_letter') {
$('#approved_letter_file').closest('div').show();
} else if (fieldId === 'settle_letter') {
$('#settle_letter_file').closest('div').show();
}
} }
}); });
} }
@ -554,6 +652,9 @@
} }
}); });
// Re-apply URL/file pair rules after bulk required toggles.
enforceLetterPairRules();
} }
@ -565,7 +666,7 @@
console.log('targetId', targetId); console.log('targetId', targetId);
console.log('fields.includes(targetId)', fields.includes(targetId)); console.log('fields.includes(targetId)', fields.includes(targetId));
if (fields.includes(targetId)) { if (fields.includes(targetId) || targetId == "approved_letter_file" || targetId == "settle_letter_file") {
let $field = $("#" + targetId); let $field = $("#" + targetId);
console.log('$field id', $field); console.log('$field id', $field);
@ -593,8 +694,31 @@
$field.prop('required', false); $field.prop('required', false);
var $parentDiv = $field.closest("div"); var $parentDiv = $field.closest("div");
$parentDiv.find("label[for='approved_description'] .text-danger").remove(); $parentDiv.find("label[for='approved_description'] .text-danger").remove();
enforceLetterPairRules();
}); });
$('#approved_letter').on('input blur', function () {
enforceLetterPairRules();
});
$('#approved_letter_file').on('change', function () {
validateApprovedLetterPdf(this);
enforceLetterPairRules();
});
$('#settle_letter').on('input blur', function () {
enforceLetterPairRules();
});
$('#settle_letter_file').on('change', function () {
validateApprovedLetterPdf(this);
enforceLetterPairRules();
});
$('#ticket_form_data').on('submit', function() {
enforceLetterPairRules();
});
// function addRequiredFieldSymbol(field_name) { // function addRequiredFieldSymbol(field_name) {
// // Find the field with the given name // // Find the field with the given name
// var $field = $(`[name="${field_name}"]`); // var $field = $(`[name="${field_name}"]`);

View File

@ -30,6 +30,62 @@ table.dataTable tbody td {
color: #6c757d !important; color: #6c757d !important;
} }
.policy-type-icon {
display: inline-flex;
align-items: center;
margin-right: 6px;
font-size: 0.95rem;
vertical-align: middle;
}
.policy-type-icon--cashless {
color: #0ea5e9;
}
.policy-type-icon--reimbursement {
color: #f59e0b;
}
/* Claim source pill — text only, fixed width (DUMP_TPA); hidden when no value */
.claim-source-badge {
display: inline-flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
padding: 0 4px;
border-radius: 999px;
font-size: 0.52rem;
font-weight: 600;
line-height: 1.3;
white-space: nowrap;
text-align: center;
overflow: hidden;
text-overflow: ellipsis;
width: 8.75em;
min-width: 8.75em;
max-width: 8.75em;
}
.claim-source-badge--tpa {
background: #d1fae5;
color: #047857;
}
.claim-source-badge--user {
background: #dbeafe;
color: #1d4ed8;
}
.claim-source-badge--dump-tpa {
background: #ede9fe;
color: #6d28d9;
}
.claim-source-badge--dump {
background: #ffedd5;
color: #c2410c;
}
.claim-source-badge--crm {
background: #fce7f3;
color: #9d174d;
}
</style> </style>
<style> <style>
.table th:nth-child(1), .table th:nth-child(1),
@ -170,7 +226,34 @@ table.dataTable tbody td {
<?php endif; ?> <?php endif; ?>
</td> </td>
<td><?php echo str_replace("Claim-", "", $ticket_type[$row['ticket_type_id']] ?? 'N/A'); ?></td> <td><?php
$claimSrc = $row['claim_created_by'] ?? '';
$claimSrcClassMap = [
'TPA' => 'claim-source-badge--tpa',
'USER' => 'claim-source-badge--user',
'DUMP_TPA' => 'claim-source-badge--dump-tpa',
'DUMP' => 'claim-source-badge--dump',
'CRM' => 'claim-source-badge--crm',
];
$claimSrcClass = $claimSrcClassMap[$claimSrc] ?? null;
$policyTypeLabel = str_replace('Claim-', '', $ticket_type[$row['ticket_type_id']] ?? 'N/A');
$tpaClaimTypeRaw = trim((string)($row['tpa_claim_type'] ?? ''));
$tpaClaimType = strtolower($tpaClaimTypeRaw);
$policyTypeIconHtml = '';
if ($tpaClaimType !== '') {
if (strpos($tpaClaimType, 'cash') !== false) {
$policyTypeIconHtml = '<span class="policy-type-icon policy-type-icon--cashless" title="Cashless"><i class="mdi mdi-hospital-box-outline" aria-hidden="true"></i></span>';
} elseif (strpos($tpaClaimType, 'reimburse') !== false) {
$policyTypeIconHtml = '<span class="policy-type-icon policy-type-icon--reimbursement" title="Reimbursement"><i class="mdi mdi-cash-refund" aria-hidden="true"></i></span>';
}
}
echo $policyTypeIconHtml . esc($policyTypeLabel);
if ($claimSrcClass !== null) {
echo '<br><span class="claim-source-badge ' . esc($claimSrcClass, 'attr') . '">' . esc($claimSrc) . '</span>';
}
?></td>
<td><?php echo $row['claim_no'] ?: 'N/A' ; ?> <td><?php echo $row['claim_no'] ?: 'N/A' ; ?>
<?php if (!empty($row['ticket_created_date'])): ?> <?php if (!empty($row['ticket_created_date'])): ?>
<span class="text-custom-grey"><br><?= "Created at ".$row['ticket_created_date']; ?></span> <span class="text-custom-grey"><br><?= "Created at ".$row['ticket_created_date']; ?></span>
@ -297,6 +380,34 @@ function getClaimTypeLabel(row) {
return window.claimTypeMap[typeId][claimKey] || ''; return window.claimTypeMap[typeId][claimKey] || '';
} }
function getClaimSourceBadgeHtml(claimCreatedBy) {
var map = {
'TPA': 'claim-source-badge--tpa',
'USER': 'claim-source-badge--user',
'DUMP_TPA': 'claim-source-badge--dump-tpa',
'DUMP': 'claim-source-badge--dump',
'CRM': 'claim-source-badge--crm'
};
var key = claimCreatedBy || '';
var cls = map[key];
if (!cls) {
return '';
}
return '<span class="claim-source-badge ' + cls + '">' + escapeHtml(key) + '</span>';
}
function getPolicyTypeIconHtml(tpaClaimType) {
var type = (tpaClaimType || '').toString().trim().toLowerCase();
if (!type) return '';
if (type.indexOf('cash') !== -1) {
return '<span class="policy-type-icon policy-type-icon--cashless" title="Cashless"><i class="mdi mdi-hospital-box-outline" aria-hidden="true"></i></span>';
}
if (type.indexOf('reimburse') !== -1) {
return '<span class="policy-type-icon policy-type-icon--reimbursement" title="Reimbursement"><i class="mdi mdi-cash-refund" aria-hidden="true"></i></span>';
}
return '';
}
function getStatusDisplay(row) { function getStatusDisplay(row) {
var status = row.status || ''; var status = row.status || '';
var claimStatusId = Number(row.claim_status_id || 0); var claimStatusId = Number(row.claim_status_id || 0);
@ -342,6 +453,8 @@ function buildTicketRowHtml(row) {
var statusUpdated = row.ticket_updated_date ? '<span class="text-custom-grey"><br>Updated at ' + escapeHtml(row.ticket_updated_date) + '</span>' : ''; var statusUpdated = row.ticket_updated_date ? '<span class="text-custom-grey"><br>Updated at ' + escapeHtml(row.ticket_updated_date) + '</span>' : '';
var claimCreated = row.ticket_created_date ? '<span class="text-custom-grey"><br>Created at ' + escapeHtml(row.ticket_created_date) + '</span>' : ''; var claimCreated = row.ticket_created_date ? '<span class="text-custom-grey"><br>Created at ' + escapeHtml(row.ticket_created_date) + '</span>' : '';
var policyType = (window.ticketTypeMap[row.ticket_type_id] || '').replace('Claim-', ''); var policyType = (window.ticketTypeMap[row.ticket_type_id] || '').replace('Claim-', '');
var policyTypeIcon = getPolicyTypeIconHtml(row.tpa_claim_type);
var claimSourceBadge = getClaimSourceBadgeHtml(row.claim_created_by);
var modeOfIntimation = window.modeOfIntimateMap[row.mode_of_intimation] || ''; var modeOfIntimation = window.modeOfIntimateMap[row.mode_of_intimation] || '';
var priority = window.priorityTypeMap[row.priority || 0] || ''; var priority = window.priorityTypeMap[row.priority || 0] || '';
@ -351,7 +464,7 @@ function buildTicketRowHtml(row) {
'<span class="status-tooltip">' + getStatusDisplay(row) + '</span>' + '<span class="status-tooltip">' + getStatusDisplay(row) + '</span>' +
statusUpdated + statusUpdated +
'</td>' + '</td>' +
'<td>' + asText(policyType) + '</td>' + '<td>' + policyTypeIcon + asText(policyType) + (claimSourceBadge ? '<br>' + claimSourceBadge : '') + '</td>' +
'<td>' + asText(row.claim_no) + claimCreated + '</td>' + '<td>' + asText(row.claim_no) + claimCreated + '</td>' +
'<td>' + asText(row.tpa_no) + '</td>' + '<td>' + asText(row.tpa_no) + '</td>' +
'<td>' + asText(row.emp_code) + '</td>' + '<td>' + asText(row.emp_code) + '</td>' +

View File

@ -240,11 +240,16 @@
<div class="form-row"> <div class="form-row">
<div class="form-group col-md-6"> <div class="form-group col-md-6">
<label for="branch_name">Branch Name <span class="text-danger">*</span></label> <label for="branch_name">Branch Name <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="branch_name" placeholder="Enter Branch Name" name="branch_name" required maxlength="255" data-parsley-maxlength="255"> <input type="text" class="form-control" id="branch_name" placeholder="Enter Branch Name" name="branch_name" required maxlength="255" data-parsley-maxlength="255"
data-parsley-minlength="3"
data-parsley-pattern="^[a-zA-Z0-9\\s_-]+$"
data-parsley-pattern-message="Branch Name can contain letters, numbers, spaces, underscore (_) and hyphen (-).">
</div> </div>
<div class="form-group col-md-6"> <div class="form-group col-md-6">
<label for="branch_code">Branch Code <span class="text-danger">*</span></label> <label for="branch_code">Branch Code <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="branch_code" placeholder="Enter Branch Code" name="branch_code" required maxlength="100" data-parsley-maxlength="100"> <input type="text" class="form-control" id="branch_code" placeholder="Enter Branch Code" name="branch_code" required maxlength="100" data-parsley-maxlength="100"
data-parsley-pattern="^[a-zA-Z0-9_-]+$"
data-parsley-pattern-message="Branch Code can contain letters, numbers, underscore (_) and hyphen (-).">
</div> </div>
</div> </div>
@ -274,7 +279,9 @@
</div> </div>
<div class="form-group col-md-6"> <div class="form-group col-md-6">
<label for="district">District <span class="text-danger">*</span></label> <label for="district">District <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="district" placeholder="Enter District" name="district" required maxlength="100" data-parsley-maxlength="100"> <input type="text" class="form-control" id="district" placeholder="Enter District" name="district" required maxlength="100" data-parsley-maxlength="100"
data-parsley-pattern="^[a-zA-Z0-9\\s-]+$"
data-parsley-pattern-message="District can contain letters, numbers, spaces, and hyphens.">
</div> </div>
</div> </div>
@ -282,11 +289,15 @@
<div class="form-row"> <div class="form-row">
<div class="form-group col-md-6"> <div class="form-group col-md-6">
<label for="branch_city">City <span class="text-danger">*</span></label> <label for="branch_city">City <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="branch_city" placeholder="Enter City" name="city" required maxlength="100" data-parsley-maxlength="100"> <input type="text" class="form-control" id="branch_city" placeholder="Enter City" name="city" required maxlength="100" data-parsley-maxlength="100"
data-parsley-pattern="^[a-zA-Z0-9\\s-]+$"
data-parsley-pattern-message="City can contain letters, numbers, spaces, and hyphens.">
</div> </div>
<div class="form-group col-md-6"> <div class="form-group col-md-6">
<label for="pincode">Pincode <span class="text-danger">*</span></label> <label for="pincode">Pincode <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="pincode" placeholder="Enter Pincode" name="pincode" required data-parsley-type="digits" data-parsley-length="[6,6]" maxlength="6"> <input type="text" class="form-control" id="pincode" placeholder="Enter Pincode" name="pincode" required data-parsley-type="digits" data-parsley-length="[6,6]" maxlength="6"
data-parsley-pattern="^[0-9]{6}$"
data-parsley-pattern-message="Pincode must be exactly 6 digits.">
</div> </div>
</div> </div>
@ -313,25 +324,33 @@
<div class="form-row"> <div class="form-row">
<div class="form-group col-md-12"> <div class="form-group col-md-12">
<label for="name">Name <span class="text-danger">*</span></label> <label for="name">Name <span class="text-danger">*</span></label>
<input value="" type="text" class="form-control" placeholder="Enter Contact Name" name="name[]" id="name" required maxlength="100" data-parsley-maxlength="100"> <input value="" type="text" class="form-control" placeholder="Enter Contact Name" name="name[]" id="name" required maxlength="100" data-parsley-maxlength="100"
data-parsley-pattern="^[A-Za-z\\s]+$"
data-parsley-pattern-message="Contact name may contain only letters and spaces.">
</div> </div>
</div> </div>
<div class="form-row"> <div class="form-row">
<div class="form-group col-md-12"> <div class="form-group col-md-12">
<label for="designation">Designation <span class="text-danger">*</span></label> <label for="designation">Designation <span class="text-danger">*</span></label>
<input value="" type="text" class="form-control" placeholder="Enter Designation Name" name="designation[]" id="designation" required maxlength="100" data-parsley-maxlength="100"> <input value="" type="text" class="form-control" placeholder="Enter Designation Name" name="designation[]" id="designation" required maxlength="100" data-parsley-maxlength="100"
data-parsley-pattern="^[A-Za-z0-9\\-_\\/ ]+$"
data-parsley-pattern-message="Designation may only contain letters, numbers, /, -, _ and spaces.">
</div> </div>
</div> </div>
<div class="form-row"> <div class="form-row">
<div class="form-group col-md-12"> <div class="form-group col-md-12">
<label for="email">Email <span class="text-danger">*</span></label> <label for="email">Email <span class="text-danger">*</span></label>
<input value="" data-parsley-type="email" type="email" data-parsley-trigger="change" data-parsley-type="email" class="form-control" placeholder="Enter Contact Email" name="email[]" id="email" required> <input value="" type="email" data-parsley-trigger="change" class="form-control" placeholder="Enter Contact Email" name="email[]" id="email" required
data-parsley-pattern="^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
data-parsley-pattern-message="Please enter a valid email format (e.g., name@domain.com).">
</div> </div>
</div> </div>
<div class="form-row"> <div class="form-row">
<div class="form-group col-md-12"> <div class="form-group col-md-12">
<label for="mobile">Mobile <span class="text-danger">*</span></label> <label for="mobile">Mobile <span class="text-danger">*</span></label>
<input value="" data-parsley-type="digits" data-parsley-length="[10,10]" data-parsley-trigger="change" type="text" class="form-control" placeholder="Enter Contact Mobile" name="mobile[]" id="mobile" required maxlength="10" inputmode="numeric"> <input value="" data-parsley-type="digits" data-parsley-length="[10,10]" data-parsley-trigger="change" type="text" class="form-control" placeholder="Enter Contact Mobile" name="mobile[]" id="mobile" required maxlength="10" inputmode="numeric"
data-parsley-pattern="^[0-9]{10}$"
data-parsley-pattern-message="Mobile number must be exactly 10 digits.">
</div> </div>
</div> </div>
</div> </div>
@ -950,25 +969,33 @@ function renumberContacts() {
<div class="form-group col-md-12"> <div class="form-group col-md-12">
<label>Name<span class="text-danger">*</span></label> <label>Name<span class="text-danger">*</span></label>
<input value="${contact ? contact.name : ''}" type="text" class="form-control" placeholder="Enter Contact Name" name="name[]" required maxlength="100" data-parsley-maxlength="100"> <input value="${contact ? contact.name : ''}" type="text" class="form-control" placeholder="Enter Contact Name" name="name[]" required maxlength="100" data-parsley-maxlength="100"
data-parsley-pattern="^[A-Za-z\\s]+$"
data-parsley-pattern-message="Contact name may contain only letters and spaces.">
</div> </div>
</div> </div>
<div class="form-row"> <div class="form-row">
<div class="form-group col-md-12"> <div class="form-group col-md-12">
<label>Designation<span class="text-danger">*</span></label> <label>Designation<span class="text-danger">*</span></label>
<input value="${contact ? contact.designation : ''}" type="text" class="form-control" placeholder="Enter Designation Name" name="designation[]" required maxlength="100" data-parsley-maxlength="100"> <input value="${contact ? contact.designation : ''}" type="text" class="form-control" placeholder="Enter Designation Name" name="designation[]" required maxlength="100" data-parsley-maxlength="100"
data-parsley-pattern="^[A-Za-z0-9\\-_\\/ ]+$"
data-parsley-pattern-message="Designation may only contain letters, numbers, /, -, _ and spaces.">
</div> </div>
</div> </div>
<div class="form-row"> <div class="form-row">
<div class="form-group col-md-12"> <div class="form-group col-md-12">
<label>Email<span class="text-danger">*</span></label> <label>Email<span class="text-danger">*</span></label>
<input value="${contact ? contact.email : ''}" data-parsley-type="email" type="email" data-parsley-trigger="change" data-parsley-type="email" class="form-control" placeholder="Enter Contact Email" name="email[]" required> <input value="${contact ? contact.email : ''}" type="email" data-parsley-trigger="change" class="form-control" placeholder="Enter Contact Email" name="email[]" required
data-parsley-pattern="^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
data-parsley-pattern-message="Please enter a valid email format (e.g., name@domain.com).">
</div> </div>
</div> </div>
<div class="form-row"> <div class="form-row">
<div class="form-group col-md-12"> <div class="form-group col-md-12">
<label>Mobile<span class="text-danger">*</span></label> <label>Mobile<span class="text-danger">*</span></label>
<input value="${contact ? contact.mobile : ''}" data-parsley-type="digits" data-parsley-length="[10,10]" data-parsley-trigger="change" type="text" class="form-control" placeholder="Enter Contact Mobile" name="mobile[]" required maxlength="10" inputmode="numeric"> <input value="${contact ? contact.mobile : ''}" data-parsley-type="digits" data-parsley-length="[10,10]" data-parsley-trigger="change" type="text" class="form-control" placeholder="Enter Contact Mobile" name="mobile[]" required maxlength="10" inputmode="numeric"
data-parsley-pattern="^[0-9]{10}$"
data-parsley-pattern-message="Mobile number must be exactly 10 digits.">
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,3 +1,23 @@
<?php
helper('datatable_view');
$tpaList = $tpaList ?? [];
$tpa_header_labels = ['Name', 'Action'];
$tpa_col_count = count($tpa_header_labels);
$tpa_col_max_len = array_fill(0, $tpa_col_count, 0);
for ($i = 0; $i < $tpa_col_count; $i++) {
$tpa_col_max_len[$i] = mb_strlen($tpa_header_labels[$i]);
}
if (is_array($tpaList)) {
foreach ($tpaList as $row) {
$nameCell = trim(($row['name'] ?? '') . ' ( ' . ($row['short_name'] ?? '') . ' )');
$tpa_col_max_len[0] = max($tpa_col_max_len[0], mb_strlen($nameCell));
$tpa_col_max_len[1] = max($tpa_col_max_len[1], 4);
}
}
$tpa_col_min_px = [160, 72];
$tpa_col_max_px = [560, 96];
$tpa_col_width_px = nhance_dt_column_widths_px($tpa_header_labels, $tpa_col_max_len, $tpa_col_min_px, $tpa_col_max_px);
?>
<style> <style>
.custom-dropdown-menu { .custom-dropdown-menu {
display: none; display: none;
@ -39,6 +59,44 @@
} }
.dataTables_length label {height: 21px !important;} .dataTables_length label {height: 21px !important;}
</style> </style>
<style>
<?php for ($i = 0; $i < $tpa_col_count; $i++) : ?>
#tpa-list-table_wrapper .dataTables_scrollHead table thead th:nth-child(<?= $i + 1 ?>),
#tpa-list-table thead th:nth-child(<?= $i + 1 ?>) {
min-width: <?= (int) $tpa_col_width_px[$i] ?>px;
width: <?= (int) $tpa_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
overflow: visible !important;
}
#tpa-list-table tbody td:nth-child(<?= $i + 1 ?>) {
width: <?= (int) $tpa_col_width_px[$i] ?>px;
max-width: <?= (int) $tpa_col_width_px[$i] ?>px;
min-width: <?= (int) $tpa_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
}
<?php endfor; ?>
#tpa-list-table tbody td:first-child {
overflow: hidden;
text-overflow: ellipsis;
}
#tpa-list-table tbody td:last-child {
overflow: visible;
text-overflow: clip;
}
#tpa-list-table tbody td {
padding: 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
#tpa-list-table_wrapper .dataTables_scrollHead table thead th,
#tpa-list-table thead th {
padding: 5px 2.35rem 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
</style>
<div class="container-fluid-min"> <div class="container-fluid-min">
<div class="row" id="tpa_list"> <div class="row" id="tpa_list">
<div class="col-12"> <div class="col-12">
@ -50,7 +108,7 @@
</div> </div>
</div> --> </div> -->
<table data-custom-table-css="table" class="table table-sm table-hover m-0 table-centered dt-responsive nowrap w-100" cellspacing="0" <table data-custom-table-css="table" class="table table-sm table-hover m-0 table-centered dt-responsive nowrap w-100" cellspacing="0"
id="tickets-table"> id="tpa-list-table">
<thead class="bg-light"> <thead class="bg-light">
<tr> <tr>
<th class="font-weight-medium">Name</th> <th class="font-weight-medium">Name</th>
@ -87,7 +145,10 @@
<!-- end row --> <!-- end row -->
<script> <script>
document.addEventListener("DOMContentLoaded", function() { document.addEventListener("DOMContentLoaded", function() {
const table = document.getElementById("tickets-table"); const table = document.getElementById("tpa-list-table");
if (!table) {
return;
}
// Create custom dropdown // Create custom dropdown
function createCustomDropdown(row) { function createCustomDropdown(row) {
@ -179,10 +240,8 @@
$(document).ready(function() { $(document).ready(function() {
$('#tickets-table').DataTable({ nhanceListDataTableBeforeInit();
// dom: "<'row'<'col-12 d-flex justify-content-between align-items-center'<'datatable-search dataTables_filter'f><'datatable-buttons dt-buttons'B>>>" + var nhTpaTable = $('#tpa-list-table').DataTable(nhanceMergeListDataTableOptions({
// "<'row'<'col-sm-12'tr>>" +
// "<'row'<'col-sm-5'i><'col-sm-7'p>>",
dom: "<'row'<'col-12 d-flex justify-content-between align-items-center'<'datatable-search dataTables_filter'f><'datatable-buttons dt-buttons'B>>>" + dom: "<'row'<'col-12 d-flex justify-content-between align-items-center'<'datatable-search dataTables_filter'f><'datatable-buttons dt-buttons'B>>>" +
"<'row'<'col-sm-12'tr>>" + "<'row'<'col-sm-12'tr>>" +
"<'row align-items-center'<'col-5 text-start'i><'col-7 d-flex justify-content-end align-items-center'<'me-2'l>p>>", "<'row align-items-center'<'col-5 text-start'i><'col-7 d-flex justify-content-end align-items-center'<'me-2'l>p>>",
@ -225,13 +284,21 @@
emptyTable: '<div class="text-center text-muted">No Data found</div>' emptyTable: '<div class="text-center text-muted">No Data found</div>'
}, },
paging: true, paging: true,
}); columnDefs: [
<?php for ($i = 0; $i < $tpa_col_count; $i++) : ?>
{ targets: <?= $i ?>, width: '<?= (int) $tpa_col_width_px[$i] ?>px' },
<?php endfor; ?>
],
}));
nhanceListDataTableAfterInit();
nhanceListDataTableBindAdjust(nhTpaTable);
}) });
const btnExport = document.querySelector("#btnExport"); const btnExport = document.querySelector("#btnExport");
const tableElement = document.querySelector("#tickets-table"); const tableElement = document.querySelector("#tpa-list-table");
if (btnExport && tableElement) {
btnExport.addEventListener("click", () => { btnExport.addEventListener("click", () => {
const obj = new csvExport(tableElement); const obj = new csvExport(tableElement);
const csvData = obj.exportCsv(); const csvData = obj.exportCsv();
@ -248,6 +315,7 @@
URL.revokeObjectURL(url); URL.revokeObjectURL(url);
}, 500); }, 500);
}); });
}
class csvExport { class csvExport {

View File

@ -1,3 +1,37 @@
<?php
helper('datatable_view');
$vr_header_labels = [
'S.No', 'Client', 'Client Branch', 'Insurer', 'Insurer Branch', 'Policy Type', 'Policy No', 'Endorsement No',
'Premium', 'Statement Premium', 'Premium Variance', 'Expected Amount', 'Statement Amount', 'Variance',
];
$vr_col_count = count($vr_header_labels);
$vr_col_max_len = array_fill(0, $vr_col_count, 0);
for ($i = 0; $i < $vr_col_count; $i++) {
$vr_col_max_len[$i] = mb_strlen($vr_header_labels[$i]);
}
$varience_list = $varience_list ?? [];
foreach ($varience_list as $index => $row) {
$vr_col_max_len[0] = max($vr_col_max_len[0], mb_strlen((string) ($index + 1)));
$vr_col_max_len[1] = max($vr_col_max_len[1], mb_strlen((string) ($row['client_name'] ?? '')));
$vr_col_max_len[2] = max($vr_col_max_len[2], mb_strlen((string) ($row['client_branch_name'] ?? '')));
$vr_col_max_len[3] = max($vr_col_max_len[3], mb_strlen((string) ($row['insurer_name'] ?? '')));
$vr_col_max_len[4] = max($vr_col_max_len[4], mb_strlen((string) ($row['insurer_branch_name'] ?? '')));
$vr_col_max_len[5] = max($vr_col_max_len[5], mb_strlen((string) ($row['policy_type'] ?? '')));
$vr_col_max_len[6] = max($vr_col_max_len[6], mb_strlen((string) ($row['policy_no'] ?? '')));
$vr_col_max_len[7] = max($vr_col_max_len[7], mb_strlen((string) ($row['endorsement_no'] ?? '')));
$vr_col_max_len[8] = max($vr_col_max_len[8], mb_strlen((string) ($row['original_premium'] ?? '')));
$vr_col_max_len[9] = max($vr_col_max_len[9], mb_strlen((string) (isset($row['statement_premium']) ? $row['statement_premium'] : '0.00')));
$vr_col_max_len[10] = max($vr_col_max_len[10], mb_strlen((string) ($row['premium_variance_amt'] ?? '')));
$vr_col_max_len[11] = max($vr_col_max_len[11], mb_strlen((string) ($row['exp_amt'] ?? '')));
$vr_col_max_len[12] = max($vr_col_max_len[12], mb_strlen((string) (isset($row['statement_amount']) ? $row['statement_amount'] : '0.00')));
$vr_col_max_len[13] = max($vr_col_max_len[13], mb_strlen((string) (isset($row['variance_amt']) ? $row['variance_amt'] : '0.00')));
}
$vr_col_min_px = array_fill(0, $vr_col_count, 88);
$vr_col_min_px[0] = 48;
$vr_col_max_px = array_fill(0, $vr_col_count, 360);
$vr_col_max_px[0] = 64;
$vr_col_width_px = nhance_dt_column_widths_px($vr_header_labels, $vr_col_max_len, $vr_col_min_px, $vr_col_max_px);
?>
<style> <style>
.table th, .table th,
.table td { .table td {
@ -168,6 +202,38 @@
.dataTables_length label {height: 21px !important;} .dataTables_length label {height: 21px !important;}
</style> </style>
<style>
<?php for ($i = 0; $i < $vr_col_count; $i++) : ?>
#variance-report-list-table_wrapper .dataTables_scrollHead table thead th:nth-child(<?= $i + 1 ?>),
#variance-report-list-table thead th:nth-child(<?= $i + 1 ?>) {
min-width: <?= (int) $vr_col_width_px[$i] ?>px;
width: <?= (int) $vr_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
overflow: visible !important;
}
#variance-report-list-table tbody td:nth-child(<?= $i + 1 ?>) {
width: <?= (int) $vr_col_width_px[$i] ?>px;
max-width: <?= (int) $vr_col_width_px[$i] ?>px;
min-width: <?= (int) $vr_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
}
<?php endfor; ?>
#variance-report-list-table tbody td {
overflow: hidden;
text-overflow: ellipsis;
padding: 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
#variance-report-list-table thead th {
padding: 5px 2.35rem 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
</style>
<div class="container-fluid-min"> <div class="container-fluid-min">
<div id="filter-sidebar" class="filter-sidebar"> <div id="filter-sidebar" class="filter-sidebar">
<div class="filter-sidebar-header"> <div class="filter-sidebar-header">
@ -278,14 +344,16 @@
<div class="col-12" id="varience_list"> <div class="col-12" id="varience_list">
<div class="card"> <div class="card">
<div class="card-body"> <div class="card-body">
<!--
<div class="row" style="padding-bottom: 10px;"> <div class="row" style="padding-bottom: 10px;">
<div class="col-6" style="align-self: center;"> <div class="col-6" style="align-self: center;">
<h4 style="position: relative;">Variance Report</h4> <h4 style="position: relative;">Variance Report</h4>
</div> </div>
</div> </div>
-->
<div class="table-responsive"> <div class="table-responsive">
<table data-custom-table-css="table" id="scroll-horizontal-datatable" class="table w-100 nowrap"> <table data-custom-table-css="table" data-nhance-list-dt="1" id="variance-report-list-table" class="table w-100 nowrap">
<thead class="bg-light"> <thead class="bg-light">
<tr> <tr>
<th>S.No&nbsp;&nbsp;&nbsp;&nbsp;</th> <th>S.No&nbsp;&nbsp;&nbsp;&nbsp;</th>
@ -308,7 +376,7 @@
<?php if (isset($varience_list)) { ?> <?php if (isset($varience_list)) { ?>
<?php foreach($varience_list as $index => $row){ ?> <?php foreach($varience_list as $index => $row){ ?>
<tr> <tr>
<td class="text-center"><?= $index + 1 ?></td> <td><?= $index + 1 ?></td>
<td><?php echo $row['client_name']; ?></td> <td><?php echo $row['client_name']; ?></td>
<td style="display: none;"><?php echo $row['client_branch_name']; ?></td> <td style="display: none;"><?php echo $row['client_branch_name']; ?></td>
<td style="display: none;"><?php echo $row['insurer_name']; ?></td> <td style="display: none;"><?php echo $row['insurer_name']; ?></td>
@ -357,10 +425,10 @@
// Datatable document ready // Datatable document ready
$(document).ready(function() { $(document).ready(function() {
var ticketsTable = $('#scroll-horizontal-datatable'); var ticketsTable = $('#variance-report-list-table');
if (ticketsTable.length) { if (ticketsTable.length) {
ticketsTable.DataTable({ nhanceListDataTableBeforeInit();
scrollX: true, var nhVarianceTable = ticketsTable.DataTable(nhanceMergeListDataTableOptions({
// dom: "<'row'<'col-sm-6'f><'col-sm-6 text-right'B>>" + // Filter left, buttons right // dom: "<'row'<'col-sm-6'f><'col-sm-6 text-right'B>>" + // Filter left, buttons right
// "<'row'<'col-sm-12'tr>>" + // "<'row'<'col-sm-12'tr>>" +
// "<'row'<'col-sm-5'i><'col-sm-7'p>>", // Pagination at the bottom, without page length selector // "<'row'<'col-sm-5'i><'col-sm-7'p>>", // Pagination at the bottom, without page length selector
@ -432,8 +500,15 @@
emptyTable: '<div class="text-center text-muted">No Data found</div>' emptyTable: '<div class="text-center text-muted">No Data found</div>'
}, },
paging: true, // Enable pagination paging: true, // Enable pagination
pageLength: 25 // Set default number of rows per page (optional) pageLength: 25, // Set default number of rows per page (optional)
}); columnDefs: [
<?php for ($i = 0; $i < $vr_col_count; $i++) : ?>
{ targets: <?= $i ?>, width: '<?= (int) $vr_col_width_px[$i] ?>px' },
<?php endfor; ?>
],
}));
nhanceListDataTableAfterInit();
nhanceListDataTableBindAdjust(nhVarianceTable);
} else { } else {
console.error("Table not found."); console.error("Table not found.");
} }

View File

@ -31,6 +31,71 @@
</style> </style>
<?php
helper('datatable_view');
$vm_header_labels = [
'S.No', 'Owner Type', 'Owner Name', 'RC Book No', 'Vehicle No', 'Vehicle type', 'Description', 'Action',
];
$vm_col_count = count($vm_header_labels);
$vm_col_max_len = array_fill(0, $vm_col_count, 0);
for ($i = 0; $i < $vm_col_count; $i++) {
$vm_col_max_len[$i] = mb_strlen($vm_header_labels[$i]);
}
$vehicle_Master_Data = $vehicle_Master_Data ?? [];
$vehicle_des = $vehicle_des ?? [];
foreach ($vehicle_Master_Data as $index => $row) {
$vm_col_max_len[0] = max($vm_col_max_len[0], mb_strlen((string) ($index + 1)));
$vm_col_max_len[1] = max($vm_col_max_len[1], mb_strlen((string) ($row['owner_type'] ?: 'N/A')));
$vm_col_max_len[2] = max($vm_col_max_len[2], mb_strlen((string) ($row['owner_name'] ?: 'N/A')));
$vm_col_max_len[3] = max($vm_col_max_len[3], mb_strlen((string) ($row['rc'] ?: 'N/A')));
$vm_col_max_len[4] = max($vm_col_max_len[4], mb_strlen((string) ($row['vehicle_no'] ?: 'N/A')));
$vm_col_max_len[5] = max($vm_col_max_len[5], mb_strlen((string) ($row['vehicle_type'] ?: 'N/A')));
$descLabel = $vehicle_des[$row['description']] ?? 'N/A';
$vm_col_max_len[6] = max($vm_col_max_len[6], mb_strlen((string) $descLabel));
$vm_col_max_len[7] = max($vm_col_max_len[7], 4);
}
$vm_col_min_px = [48, 88, 120, 100, 100, 100, 120, 72];
$vm_col_max_px = [64, 160, 280, 180, 180, 200, 320, 88];
$vm_col_width_px = nhance_dt_column_widths_px($vm_header_labels, $vm_col_max_len, $vm_col_min_px, $vm_col_max_px);
?>
<style>
<?php for ($i = 0; $i < $vm_col_count; $i++) : ?>
#vehicle-master-list-table_wrapper .dataTables_scrollHead table thead th:nth-child(<?= $i + 1 ?>),
#vehicle-master-list-table thead th:nth-child(<?= $i + 1 ?>) {
min-width: <?= (int) $vm_col_width_px[$i] ?>px;
width: <?= (int) $vm_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
overflow: visible !important;
}
#vehicle-master-list-table tbody td:nth-child(<?= $i + 1 ?>) {
width: <?= (int) $vm_col_width_px[$i] ?>px;
max-width: <?= (int) $vm_col_width_px[$i] ?>px;
min-width: <?= (int) $vm_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
}
<?php endfor; ?>
#vehicle-master-list-table tbody td:not(:last-child) {
overflow: hidden;
text-overflow: ellipsis;
}
#vehicle-master-list-table tbody td:last-child {
overflow: visible;
text-overflow: clip;
}
#vehicle-master-list-table tbody td {
padding: 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
#vehicle-master-list-table thead th {
padding: 5px 2.35rem 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
</style>
<div class="row" id="client_list"> <div class="row" id="client_list">
<div class="col-12"> <div class="col-12">
<div class="card"> <div class="card">
@ -40,7 +105,7 @@
<h4 style="position: relative;">Vehicle Master</h4> <h4 style="position: relative;">Vehicle Master</h4>
</div> </div>
</div> --> </div> -->
<table data-custom-table-css="table" id="scroll-horizontal-datatable" class="table mb-0 nowrap" cellspacing="0"> <table data-custom-table-css="table" data-nhance-list-dt="1" id="vehicle-master-list-table" class="table mb-0 nowrap" cellspacing="0">
<thead class="bg-light"> <thead class="bg-light">
<tr> <tr>
<th class="font-weight-medium">S.No&nbsp;</th> <th class="font-weight-medium">S.No&nbsp;</th>
@ -57,7 +122,7 @@
<tbody> <tbody>
<?php foreach($vehicle_Master_Data as $index => $row){ ?> <?php foreach($vehicle_Master_Data as $index => $row){ ?>
<tr> <tr>
<td class="text-center"><?php echo $index+1; ?></td> <td><?php echo $index+1; ?></td>
<td><?php echo $row['owner_type'] ?: 'N/A'; ?></td> <td><?php echo $row['owner_type'] ?: 'N/A'; ?></td>
<td><?php echo $row['owner_name'] ?: 'N/A'; ?></td> <td><?php echo $row['owner_name'] ?: 'N/A'; ?></td>
<td><?php echo $row['rc'] ?: 'N/A'; ?></td> <td><?php echo $row['rc'] ?: 'N/A'; ?></td>
@ -336,10 +401,10 @@ $(document).ready(function() {
$(document).ready(function() { $(document).ready(function() {
var table = $('#scroll-horizontal-datatable'); var table = $('#vehicle-master-list-table');
if (table.length) { if (table.length) {
var dataTable = table.DataTable({ nhanceListDataTableBeforeInit();
scrollX: true, var dataTable = table.DataTable(nhanceMergeListDataTableOptions({
// dom: "<'row'<'col-12 d-flex justify-content-between align-items-center'<'datatable-search dataTables_filter'f><'datatable-buttons dt-buttons'B>>>" + // dom: "<'row'<'col-12 d-flex justify-content-between align-items-center'<'datatable-search dataTables_filter'f><'datatable-buttons dt-buttons'B>>>" +
// "<'row'<'col-sm-12'tr>>" + // "<'row'<'col-sm-12'tr>>" +
// "<'row'<'col-sm-5'i><'col-sm-7'p>>", // "<'row'<'col-sm-5'i><'col-sm-7'p>>",
@ -400,15 +465,22 @@ $(document).ready(function() {
}, },
paging: true, paging: true,
pageLength: 10, pageLength: 10,
order: [[0, 'desc']] order: [[0, 'desc']],
}); columnDefs: [
<?php for ($i = 0; $i < $vm_col_count; $i++) : ?>
{ targets: <?= $i ?>, width: '<?= (int) $vm_col_width_px[$i] ?>px' },
<?php endfor; ?>
],
}));
nhanceListDataTableAfterInit();
nhanceListDataTableBindAdjust(dataTable);
function applyBottomRowDropup() { function applyBottomRowDropup() {
if (!dataTable) return; if (!dataTable) return;
const currentRows = dataTable.rows({ page: 'current' }).nodes().toArray(); const currentRows = dataTable.rows({ page: 'current' }).nodes().toArray();
$('#scroll-horizontal-datatable tbody tr').removeClass('nh-force-dropup'); $('#vehicle-master-list-table tbody tr').removeClass('nh-force-dropup');
$('#scroll-horizontal-datatable tbody tr td.table-action-cell .btn-group.dropdown').removeClass('dropup'); $('#vehicle-master-list-table tbody tr td.table-action-cell .btn-group.dropdown').removeClass('dropup');
const targetCount = Math.min(2, currentRows.length); const targetCount = Math.min(2, currentRows.length);
for (let i = 0; i < targetCount; i++) { for (let i = 0; i < targetCount; i++) {
@ -419,7 +491,7 @@ $(document).ready(function() {
} }
} }
applyBottomRowDropup(); applyBottomRowDropup();
$('#scroll-horizontal-datatable').on('draw.dt', applyBottomRowDropup); $('#vehicle-master-list-table').on('draw.dt', applyBottomRowDropup);
} else { } else {
console.error("Table atet found."); console.error("Table atet found.");

View File

@ -1,3 +1,25 @@
<?php
helper('datatable_view');
$vt_header_labels = ['Name', 'Email', 'Mobile No', 'Role', 'Status', 'Action'];
$vt_col_count = count($vt_header_labels);
$vt_col_max_len = array_fill(0, $vt_col_count, 0);
for ($i = 0; $i < $vt_col_count; $i++) {
$vt_col_max_len[$i] = mb_strlen($vt_header_labels[$i]);
}
$UserList = $UserList ?? [];
foreach ($UserList as $row) {
$vt_col_max_len[0] = max($vt_col_max_len[0], mb_strlen((string) ($row->first_name ?? '')));
$vt_col_max_len[1] = max($vt_col_max_len[1], mb_strlen((string) ($row->email ?? '')));
$vt_col_max_len[2] = max($vt_col_max_len[2], mb_strlen((string) ($row->mobile ?? '')));
$vt_col_max_len[3] = max($vt_col_max_len[3], mb_strlen((string) ($row->user_role ?? '')));
$vt_st = (isset($row->is_active) && (int) $row->is_active === 1) ? 'Active' : 'In-Active';
$vt_col_max_len[4] = max($vt_col_max_len[4], mb_strlen($vt_st));
$vt_col_max_len[5] = max($vt_col_max_len[5], 4);
}
$vt_col_min_px = [120, 180, 100, 120, 88, 72];
$vt_col_max_px = [280, 360, 140, 240, 120, 88];
$vt_col_width_px = nhance_dt_column_widths_px($vt_header_labels, $vt_col_max_len, $vt_col_min_px, $vt_col_max_px);
?>
<style> <style>
/* body { /* body {
font-family: Arial, sans-serif; font-family: Arial, sans-serif;
@ -209,7 +231,7 @@
grid-template-columns: 1fr .4fr .5fr .2fr; grid-template-columns: 1fr .4fr .5fr .2fr;
} }
#user-table_filter input{ width:100%; } #vehicle-type-list-table_filter input{ width:100%; }
button.dt-button, button.dt-button,
button.dt-button:focus, button.dt-button:focus,
@ -298,6 +320,46 @@
} }
.dataTables_length label {height: 21px !important;} .dataTables_length label {height: 21px !important;}
<?php for ($i = 0; $i < $vt_col_count; $i++) : ?>
#vehicle-type-list-table_wrapper .dataTables_scrollHead table thead th:nth-child(<?= $i + 1 ?>),
#vehicle-type-list-table thead th:nth-child(<?= $i + 1 ?>) {
min-width: <?= (int) $vt_col_width_px[$i] ?>px;
width: <?= (int) $vt_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
overflow: visible !important;
}
#vehicle-type-list-table tbody td:nth-child(<?= $i + 1 ?>) {
width: <?= (int) $vt_col_width_px[$i] ?>px;
max-width: <?= (int) $vt_col_width_px[$i] ?>px;
min-width: <?= (int) $vt_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
}
<?php endfor; ?>
#vehicle-type-list-table tbody td:nth-child(1),
#vehicle-type-list-table tbody td:nth-child(2),
#vehicle-type-list-table tbody td:nth-child(3),
#vehicle-type-list-table tbody td:nth-child(4),
#vehicle-type-list-table tbody td:nth-child(5) {
overflow: hidden;
text-overflow: ellipsis;
}
#vehicle-type-list-table tbody td:nth-child(6) {
overflow: visible;
text-overflow: clip;
}
#vehicle-type-list-table tbody td {
padding: 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
#vehicle-type-list-table thead th {
padding: 5px 2.35rem 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
</style> </style>
@ -311,7 +373,7 @@
<h4 style="position: relative;">Users</h4> <h4 style="position: relative;">Users</h4>
</div> </div>
</div> --> </div> -->
<table data-custom-table-css="table" class="table mb-0 nowrap" cellspacing="0" id="user-table"> <table data-custom-table-css="table" class="table mb-0 nowrap" cellspacing="0" id="vehicle-type-list-table">
<thead class="bg-light"> <thead class="bg-light">
<tr> <tr>
<th class="font-weight-medium">S.No.&nbsp;</th> <th class="font-weight-medium">S.No.&nbsp;</th>
@ -759,8 +821,8 @@
allowInput: false, allowInput: false,
}); });
table = $('#user-table').DataTable({ nhanceListDataTableBeforeInit();
scrollX: true, table = $('#vehicle-type-list-table').DataTable(nhanceMergeListDataTableOptions({
// dom: "<'row'<'col-sm-3'f><'col-sm-9'B>>" + // dom: "<'row'<'col-sm-3'f><'col-sm-9'B>>" +
// "<'row'<'col-sm-12'tr>>" + // "<'row'<'col-sm-12'tr>>" +
// "<'row'<'col-sm-5'i><'col-sm-7'p>>", // "<'row'<'col-sm-5'i><'col-sm-7'p>>",
@ -854,7 +916,12 @@
} }
], ],
paging: true, paging: true,
pageLength: 10, pageLength: 10,
columnDefs: [
<?php for ($i = 0; $i < $vt_col_count; $i++) : ?>
{ targets: <?= $i ?>, width: '<?= (int) $vt_col_width_px[$i] ?>px' },
<?php endfor; ?>
],
language: { language: {
search: ` search: `
<div class="datatable-search-wrapper" style="position:relative; display:inline-block;"> <div class="datatable-search-wrapper" style="position:relative; display:inline-block;">
@ -892,14 +959,16 @@
loadPartner(); loadPartner();
}); });
} }
}); }));
nhanceListDataTableAfterInit();
nhanceListDataTableBindAdjust(table);
function applyBottomRowDropup() { function applyBottomRowDropup() {
if (!table) return; if (!table) return;
const currentRows = table.rows({ page: 'current' }).nodes().toArray(); const currentRows = table.rows({ page: 'current' }).nodes().toArray();
$('#user-table tbody tr').removeClass('nh-force-dropup'); $('#vehicle-type-list-table tbody tr').removeClass('nh-force-dropup');
$('#user-table tbody tr td.table-action-cell .btn-group.dropdown').removeClass('dropup'); $('#vehicle-type-list-table tbody tr td.table-action-cell .btn-group.dropdown').removeClass('dropup');
// Mark last two rows on current page to open action menu upward. // Mark last two rows on current page to open action menu upward.
const targetCount = Math.min(2, currentRows.length); const targetCount = Math.min(2, currentRows.length);
@ -911,7 +980,7 @@
} }
} }
applyBottomRowDropup(); applyBottomRowDropup();
$('#user-table').on('draw.dt', applyBottomRowDropup); $('#vehicle-type-list-table').on('draw.dt', applyBottomRowDropup);
$('#team').multiselect({ $('#team').multiselect({

View File

@ -22,7 +22,7 @@
<?php if(isset($data)) { $slno = 1; ?> <?php if(isset($data)) { $slno = 1; ?>
<?php foreach($data as $index => $row) { ?> <?php foreach($data as $index => $row) { ?>
<tr> <tr>
<td class="text-center"><?= $slno++; ?></td> <td><?= $slno++; ?></td>
<td><?= $row['vehicle_type']; ?></td> <td><?= $row['vehicle_type']; ?></td>
<!-- <td> <!-- <td>
<span class="<?php if($row['is_active'] == 1){ echo 'badge badge-primary'; }else{ echo 'badge badge-danger'; } ?>"> <span class="<?php if($row['is_active'] == 1){ echo 'badge badge-primary'; }else{ echo 'badge badge-danger'; } ?>">

View File

@ -225,7 +225,12 @@
<div class="col-md-6"> <div class="col-md-6">
<div class="form-group"> <div class="form-group">
<label for="field-1" class="control-label">Amount<span class="text-danger">*</span></label> <label for="field-1" class="control-label">Amount<span class="text-danger">*</span></label>
<input type="number" class="form-control" id="amount" placeholder="Amount" required> <input type="text" class="form-control" id="amount" placeholder="Amount" required
inputmode="decimal" maxlength="12"
data-parsley-pattern="^[0-9]+(\\.[0-9]{1,2})?$"
data-parsley-pattern-message="Amount must be a valid number."
data-parsley-required-message="Amount field is required.">
<div id="amount_error" class="text-danger small mt-1" style="display:none;"></div>
</div> </div>
</div> </div>
@ -428,11 +433,26 @@
var cd_ac_no = $('#cd_ac_no').val(); var cd_ac_no = $('#cd_ac_no').val();
var cd_ac_pk = $('#cd_ac_pk').val(); var cd_ac_pk = $('#cd_ac_pk').val();
if (amount == "") { amount = (amount || '').trim();
toastr.warning('Amount field is required') var amountRegex = /^[0-9]+(\.[0-9]{1,2})?$/;
if (amount === "") {
$('#amount_error').text('Amount field is required.').show();
$('#amount').addClass('is-invalid');
toastr.warning('Amount field is required');
return; return;
} }
if (!amountRegex.test(amount)) {
$('#amount_error').text('Amount must be a valid number.').show();
$('#amount').addClass('is-invalid');
toastr.warning('Amount must be a valid number.');
return;
}
$('#amount_error').hide().text('');
$('#amount').removeClass('is-invalid');
if (description == "") { if (description == "") {
toastr.warning('Description field is required') toastr.warning('Description field is required')
return; return;
@ -526,4 +546,24 @@
}); });
}); });
</script>
<script>
$(document).on('input', '#amount', function () {
var value = $(this).val();
value = value.replace(/[^0-9.]/g, '');
var parts = value.split('.');
if (parts.length > 2) {
value = parts[0] + '.' + parts.slice(1).join('');
parts = value.split('.');
}
if (parts[1] && parts[1].length > 2) {
value = parts[0] + '.' + parts[1].slice(0, 2);
}
$(this).val(value);
if (value.length) {
$('#amount_error').hide().text('');
$(this).removeClass('is-invalid');
}
});
</script> </script>

View File

@ -384,44 +384,46 @@ table.dataTable tbody > tr > td:last-child {
padding-right: 1.35rem !important; padding-right: 1.35rem !important;
} }
table.dataTable thead > tr > th:last-child {
text-align: left;
}
/* /*
* Action cells: only when the last column contains a Bootstrap dropdown (avoids * Action cells: only when the last column contains a Bootstrap dropdown (avoids
* right-aligning numeric/text-only last columns on other listings). * affecting numeric/text-only last columns that are not row actions).
*/ */
table.dataTable tbody > tr > td:last-child:has(.dropdown) { table.dataTable tbody > tr > td:last-child:has(.dropdown) {
position: relative; position: relative;
text-align: right; text-align: left;
} }
table.dataTable tbody > tr > td:last-child:has(.dropdown) .btn-group.dropdown { table.dataTable tbody > tr > td:last-child:has(.dropdown) .btn-group.dropdown {
display: inline-flex; display: inline-flex;
justify-content: flex-end; justify-content: flex-start;
} }
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* Action column centered / dropdown (opt-in per row) * Action column left-aligned / dropdown (footer.js adds .table-action-cell)
* Add class="table-action-cell" on the <td> that wraps .btn-group.dropdown
* (any column position; overrides last-column right-align above).
* ----------------------------------------------------------------------------- */ * ----------------------------------------------------------------------------- */
table.dataTable tbody > tr > td.table-action-cell { table.dataTable tbody > tr > td.table-action-cell {
text-align: center !important; text-align: left !important;
vertical-align: middle !important; vertical-align: middle !important;
} }
table.dataTable tbody > tr > td.table-action-cell .btn-group.dropdown { table.dataTable tbody > tr > td.table-action-cell .btn-group.dropdown {
display: inline-flex !important; display: inline-flex !important;
justify-content: center !important; justify-content: flex-start !important;
float: none !important; float: none !important;
margin-right: 0 !important; /* Prevent global dropdown margin shifting anchor */ margin-right: 0 !important; /* Prevent global dropdown margin shifting anchor */
} }
table.dataTable tbody > tr > td:last-child.table-action-cell:has(.dropdown), table.dataTable tbody > tr > td:last-child.table-action-cell:has(.dropdown),
table.dataTable tbody > tr > td.table-action-cell:has(.dropdown) { table.dataTable tbody > tr > td.table-action-cell:has(.dropdown) {
text-align: center !important; text-align: left !important;
} }
table.dataTable tbody > tr > td:last-child.table-action-cell:has(.dropdown) .btn-group.dropdown { table.dataTable tbody > tr > td:last-child.table-action-cell:has(.dropdown) .btn-group.dropdown {
justify-content: center !important; justify-content: flex-start !important;
} }
/* Dropdown menu stacks above row borders / scroll quirks */ /* Dropdown menu stacks above row borders / scroll quirks */

View File

@ -0,0 +1,111 @@
/**
* Shared list DataTable behavior (aligned with batch_list.php):
* - Temporarily neutralize scroll defaults during init
* - Force scrollX/Y/Collapse off, autoWidth/responsive false
* - Sync horizontal scroll between scrollHead and scrollBody when present
* - columns.adjust on draw, resize, and after first paint
*/
(function (window, $) {
"use strict";
if (typeof $ === "undefined" || !$ || !$.fn || !$.fn.DataTable) {
return;
}
var _savedDefaults = null;
window.nhanceListDataTableBeforeInit = function () {
_savedDefaults = {
scrollX: $.fn.dataTable.defaults.scrollX,
scrollY: $.fn.dataTable.defaults.scrollY,
scrollCollapse: $.fn.dataTable.defaults.scrollCollapse,
bScrollCollapse: $.fn.dataTable.defaults.bScrollCollapse,
sScrollX: $.fn.dataTable.defaults.sScrollX,
sScrollY: $.fn.dataTable.defaults.sScrollY,
sScrollXInner: $.fn.dataTable.defaults.sScrollXInner,
};
$.extend($.fn.dataTable.defaults, {
scrollX: false,
scrollY: false,
scrollCollapse: false,
bScrollCollapse: false,
sScrollX: "",
sScrollY: "",
sScrollXInner: "",
});
};
window.nhanceListDataTableAfterInit = function () {
if (_savedDefaults) {
$.extend($.fn.dataTable.defaults, _savedDefaults);
_savedDefaults = null;
}
};
window.nhanceListDataTableBaseInitComplete = function () {
return function () {
var api = this.api();
var $wrap = $(api.table().container());
var $body = $wrap.find(".dataTables_scrollBody");
var $head = $wrap.find(".dataTables_scrollHead");
if ($body.length && $head.length) {
$body.off("scroll.nhanceListHScroll").on("scroll.nhanceListHScroll", function () {
$head.scrollLeft($(this).scrollLeft());
});
$head.off("scroll.nhanceListHScroll").on("scroll.nhanceListHScroll", function () {
$body.scrollLeft($(this).scrollLeft());
});
}
};
};
/**
* Merge page-specific DataTable options with batch_list-style list defaults.
* User initComplete runs after base scroll sync.
*/
window.nhanceMergeListDataTableOptions = function (userOptions) {
userOptions = userOptions || {};
var userInit = userOptions.initComplete;
var merged = $.extend(true, {}, userOptions);
/* DataTables maps these to oScroll *before* pb()/tb() runs. CamelCase alone is not enough if
sScrollX/sScrollY were set via defaults, Hungarian options, or truthy strings. */
merged.scrollX = false;
merged.scrollY = false;
merged.scrollCollapse = false;
merged.sScrollX = "";
merged.sScrollY = "";
merged.sScrollXInner = "";
merged.bScrollCollapse = false;
merged.autoWidth = false;
merged.responsive = false;
if (merged.paging === undefined) {
merged.paging = true;
}
var baseInit = window.nhanceListDataTableBaseInitComplete();
merged.initComplete = function () {
baseInit.call(this);
if (typeof userInit === "function") {
userInit.call(this);
}
};
return merged;
};
window.nhanceListDataTableBindAdjust = function (dtApi) {
if (!dtApi || !dtApi.on) {
return;
}
var tid = $(dtApi.table().node()).attr("id") || "nhance_dt";
var resizeNs = "resize.nhanceListDt_" + tid;
dtApi.columns.adjust();
dtApi.on("draw.dt", function () {
dtApi.columns.adjust();
});
$(window).off(resizeNs).on(resizeNs, function () {
dtApi.columns.adjust();
});
setTimeout(function () {
dtApi.columns.adjust();
}, 0);
};
})(window, jQuery);