MERGE_UAT_FIXES

This commit is contained in:
Ubuntu 2026-03-18 10:42:47 +05:30
commit 33730dc1ee
15 changed files with 715 additions and 236 deletions

View File

@ -100,6 +100,7 @@ $routes->group("/user", ["filter" => "authMVC"], function ($routes) {
$routes->get("list", "UserController::list");
$routes->get("getuser/(:hash)", "UserController::getuser/$1");
$routes->get("deactive/(:hash)", "UserController::deactive/$1");
$routes->get("activateUser/(:any)", "UserController::activateUser/$1");
$routes->get("rolesandteams", "UserController::getRolesAndTeams");
$routes->get("getUserActivityHistory", "UserController::getUserActivityHistory");
$routes->match(['get','post','put'], 'partner', 'UserController::partner');

View File

@ -1004,8 +1004,8 @@ class ClientController extends AdminController
]
],
'short_name' => [
'rules' => 'required|regex_match[/^[a-zA-Z0-9_-]+$/]|min_length[2]|max_length[15]',
'errors' => [
'rules' => 'required|regex_match[/^[a-zA-Z0-9_\- ]+$/]|min_length[2]|max_length[15]',
'errors' => [
'required' => 'Client Short Name is required',
'regex_match' => 'Client Short Name can only contain letters, numbers, hyphens and underscores.',
'min_length' => 'Client Short Name must be at least 2 characters.',
@ -1013,9 +1013,8 @@ class ClientController extends AdminController
]
],
'pan' => [
'rules' => 'required|regex_match[/^[A-Z]{5}[0-9]{4}[A-Z]$/]',
'rules' => 'permit_empty|regex_match[/^[A-Z]{5}[0-9]{4}[A-Z]$/]',
'errors' => [
'required' => 'PAN Number is required.',
'regex_match' => 'Invalid PAN format. Example: ABCDE1234F'
]
],
@ -1120,7 +1119,7 @@ class ClientController extends AdminController
]
],
'short_name' => [
'rules' => 'required|regex_match[/^[a-zA-Z0-9_-]+$/]',
'rules' => 'required|regex_match[/^[a-zA-Z0-9_\- ]+$/]|min_length[2]|max_length[15]',
'errors' => [
'required' => 'Client Short Name is required',
'regex_match' => 'Client Short Name can only contain letters, numbers, hyphens and underscores.',
@ -1129,9 +1128,8 @@ class ClientController extends AdminController
]
],
'pan' => [
'rules' => 'required|regex_match[/^[A-Z]{5}[0-9]{4}[A-Z]$/]',
'rules' => 'permit_empty|regex_match[/^[A-Z]{5}[0-9]{4}[A-Z]$/]',
'errors' => [
'required' => 'PAN Number is required.',
'regex_match' => 'Invalid PAN format. Example: ABCDE1234F'
]
],
@ -1876,10 +1874,10 @@ class ClientController extends AdminController
]
],
'designation.*' => [
'rules' => 'required|alpha_space',
'rules' => 'required|regex_match[/^[A-Za-z0-9\-_\/ ]+$/]',
'errors' => [
'required' => 'Designation is required',
'alpha_space' => 'Designation may contain only letters and spaces'
'regex_match' => 'Designation may only contain letters, numbers, /, -, _ and spaces'
]
],
'email.*' => [
@ -2283,10 +2281,10 @@ class ClientController extends AdminController
]
],
'designation.*' => [
'rules' => 'required|alpha_space',
'rules' => 'required|regex_match[/^[A-Za-z0-9\-_\/ ]+$/]',
'errors' => [
'required' => 'Designation is required',
'alpha_space' => 'Designation may contain only letters and spaces'
'regex_match' => 'Designation may only contain letters, numbers, /, -, _ and spaces'
]
],
'email.*' => [
@ -2467,10 +2465,10 @@ class ClientController extends AdminController
]
],
'designation.*' => [
'rules' => 'required|alpha_space',
'rules' => 'required|regex_match[/^[A-Za-z0-9\-_\/ ]+$/]',
'errors' => [
'required' => 'Designation is required',
'alpha_space' => 'Designation may contain only letters and spaces'
'regex_match' => 'Designation may only contain letters, numbers, /, -, _ and spaces'
]
],
'email.*' => [
@ -5803,6 +5801,99 @@ class ClientController extends AdminController
// print_r($postData); die;
$client_type = $postData['client_type'] ?? null;
$from_modal = $postData['from_modal'] ?? null;
$rules = [
'client_name' => [
'label' => 'Client Name',
'rules' => 'required|regex_match[/^[a-zA-Z0-9 ,\/_\-]+$/]',
'errors' => [
'required' => 'Client Name is required.',
'regex_match' => 'Client Name only allows letters, numbers, spaces, and , / _ -'
]
],
'short_name' => [
'label' => 'Client Short Name',
'rules' => 'required|regex_match[/^[a-zA-Z0-9,\/_\-]+$/]|is_unique[clients.short_name]',
'errors' => [
'required' => 'Short Name is required.',
'regex_match' => 'Short Name only allows letters, numbers, and , / _ -',
'is_unique' => 'This Short Name is already in use.'
]
],
'pan' => [
'label' => 'PAN',
'rules' => 'permit_empty|regex_match[/^[A-Z]{5}[0-9]{4}[A-Z]{1}$/]',
'errors' => [
'regex_match' => 'Invalid PAN format (Example: ABCDE1234F).'
]
],
'entity_type_id' => [
'label' => 'Entity Type',
'rules' => 'required',
'errors' => [
'required' => 'Please select an Entity Type.'
]
],
'branch_name' => [
'label' => 'Branch Name',
'rules' => 'required|regex_match[/^[a-zA-Z0-9 ,\/_\-]+$/]',
'errors' => [
'required' => 'Branch Name is required.',
'regex_match' => 'Branch Name only allows letters, numbers, spaces, and , / _ -'
]
],
'branch_code' => [
'label' => 'Branch Code',
'rules' => 'required|regex_match[/^[a-zA-Z0-9,\/_\-]+$/]',
'errors' => [
'required' => 'Branch Code is required.',
'regex_match' => 'Branch Code only allows letters, numbers, and , / _ -'
]
],
'name' => [
'label' => 'Contact Person Name',
'rules' => 'required|regex_match[/^[a-zA-Z0-9 ,\/_\-]+$/]',
'errors' => [
'required' => 'Name is required.',
'regex_match' => 'Name only allows letters, numbers, spaces, and , / _ -'
]
],
'mobile' => [
'label' => 'Mobile',
'rules' => 'required|numeric|exact_length[10]',
'errors' => [
'required' => 'Mobile number is required.',
'numeric' => 'Mobile must contain only digits.',
'exact_length' => 'Mobile number must be exactly 10 digits.'
]
],
'email' => [
'label' => 'Email',
'rules' => 'required|valid_email',
'errors' => [
'required' => 'Email is required.',
'valid_email' => 'Please provide a valid email address.'
]
],
'gst' => [
'label' => 'GST',
'rules' => 'required|regex_match[/^\d{2}[A-Z]{5}\d{4}[A-Z]{1}[A-Z\d]{1}[Z]{1}[A-Z\d]{1}$/]',
'errors' => [
'required' => 'GST Number is required.',
'regex_match' => 'Invalid GST format (Example: 12ABCDE1234F5Z6).'
]
]
];
if (isset($from_modal) && !$this->validate($rules)) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Input validation failed',
'code' => 400,
'errors' => $this->validator->getErrors()
]);
}
$client_insert = null;
if ($client_type == 2) {
@ -5928,7 +6019,8 @@ class ClientController extends AdminController
],
];
if (!$this->validate($rules)) {
if (!$this->validate($rules)) {
return $this->response->setStatusCode(400)->setJSON([
'status' => false,
'message' => 'Input validation failed',
@ -5936,6 +6028,7 @@ class ClientController extends AdminController
'errors' => $this->validator->getErrors()
]);
}
$data = $this->request->getPost();
$sanitized_post_data = sanitizeInputArrayAdvanced($data);
$id = $sanitized_post_data['vehicle_primary_key'] ?? null;

View File

@ -370,7 +370,9 @@ class LeadsController extends BaseController
$actual_lead_id = ! empty($actual_lead_id) ? $actual_lead_id : null;
$postData = $this->request->getPost();
$data = $this->prepareLeadData();
$rules = [
$rules = [
'lead_type' => [
'rules' => 'integer',
@ -380,21 +382,6 @@ class LeadsController extends BaseController
'rules' => 'required',
'errors' => ['required' => 'Issuer is required'],
],
'entity_type_id' => [
'rules' => 'required',
'errors' => ['required' => 'Entity Type is required'],
],
'client_name' => [
'rules' => 'required|regex_match[/^[a-zA-Z0-9_ -]+$/]',
'errors' => [
'required' => 'Client Name is required',
'regex_match' => 'Client Name only letters, numbers, space, hyphens and underscores are allowed',
],
],
'client_short_name' => [
'rules' => 'required|regex_match[/^[a-zA-Z0-9_-]+$/]',
'errors' => ['required' => 'Client Short Name is required', 'regex_match' => 'Client Short Name only letters, numbers, hyphens and underscores are allowed'],
],
'gst' => [
'rules' => 'required|regex_match[/^[0-9]{2}[A-Z]{5}[0-9]{4}[A-Z]{1}[1-9A-Z]{1}Z[0-9A-Z]{1}$/]',
'errors' => [
@ -460,6 +447,30 @@ class LeadsController extends BaseController
],
];
if (isset($postData['lead_type']) && $postData['lead_type'] == 1) {
$rules['entity_type_id'] = [
'rules' => 'required',
'errors' => ['required' => 'Entity Type is required'],
];
$rules['client_name'] = [
'rules' => 'required|regex_match[/^[a-zA-Z0-9_ -]+$/]',
'errors' => [
'required' => 'Client Name is required',
'regex_match' => 'Client Name only letters, numbers, space, hyphens and underscores are allowed',
],
];
$rules['client_short_name'] = [
'rules' => 'required|regex_match[/^[a-zA-Z0-9_-]+$/]',
'errors' => [
'required' => 'Client Short Name is required',
'regex_match' => 'Client Short Name only letters, numbers, hyphens and underscores are allowed'
],
];
}
foreach ($postData as $key => $value) {
// Check if the key starts with 'docs_name_'
if (strpos($key, 'docs_name_') === 0) {

View File

@ -1290,7 +1290,13 @@ class TicketController extends BaseController
]
],
// --- ADDITIONAL / CONDITIONAL FIELDS ---
'claim_number' => ['label' => 'Claim Number','rules' => 'permit_empty|alpha_numeric_punct','errors' => ['alpha_numeric_punct' => 'Invalid Claim Number.']],
'claim_number' => [
'label' => 'Claim Number',
'rules' => 'permit_empty|regex_match[/^[a-zA-Z0-9\/_-]+$/]',
'errors' => [
'regex_match' => 'Claim Number only allows letters, numbers, slashes (/), hyphens (-), and underscores (_).'
]
],
'denial_date' => ['label' => 'Denial Date','rules' => 'permit_empty|regex_match[/^\d{2}\/\d{2}\/\d{4}$/]','errors' => ['regex_match' => 'Denial Date must be dd/mm/yyyy.']],
'approved_amount' => ['label' => 'Approved Amount','rules' => 'permit_empty|numeric',
'errors' => ['numeric' => 'Approved amount must be numeric']
@ -1649,7 +1655,13 @@ class TicketController extends BaseController
],
// --- ADDITIONAL / CONDITIONAL FIELDS ---
'claim_number' => ['label' => 'Claim Number','rules' => 'permit_empty|alpha_numeric_punct','errors' => ['alpha_numeric_punct' => 'Invalid Claim Number.']],
'claim_number' => [
'label' => 'Claim Number',
'rules' => 'permit_empty|regex_match[/^[a-zA-Z0-9\/_-]+$/]',
'errors' => [
'regex_match' => 'Claim Number only allows letters, numbers, slashes (/), hyphens (-), and underscores (_).'
]
],
'denial_date' => ['label' => 'Denial Date','rules' => 'permit_empty|regex_match[/^\d{2}\/\d{2}\/\d{4}$/]','errors' => ['regex_match' => 'Denial Date must be dd/mm/yyyy.']],
'approved_amount' => ['label' => 'Approved Amount','rules' => 'permit_empty|numeric',
'errors' => ['numeric' => 'Approved amount must be numeric']

View File

@ -115,12 +115,13 @@ class UserController extends AdminController
// ======================
'emp_code' => [
'label' => 'Employee Code',
'rules' => 'required|min_length[3]|max_length[15]|regex_match[/^[a-zA-Z0-9_\-\/]+$/]',
'rules' => 'required|min_length[3]|max_length[15]|regex_match[/^[a-zA-Z0-9_\-\/]+$/]|is_unique[user_profiles.emp_code]',
'errors' => [
'required' => 'Employee Code is required',
'min_length' => 'Employee Code must be at least 3 characters',
'max_length' => 'Employee Code cannot exceed 15 characters',
'regex_match' => 'Employee Code can only contain letters, numbers, underscores, hyphens, and forward slashes (/).'
'regex_match' => 'Employee Code can only contain letters, numbers, underscores, hyphens, and forward slashes (/).',
'is_unique' => 'This Employee Code already exists.'
]
],
@ -141,10 +142,11 @@ class UserController extends AdminController
// Email
// ======================
'email' => [
'rules' => 'required|regex_match[/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/]',
'rules' => 'required|regex_match[/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/]|is_unique[user_profiles.email]',
'errors' => [
'required' => 'Email address is required.',
'regex_match' => 'Please enter a valid email format (e.g., name@domain.com).'
'regex_match' => 'Please enter a valid email format (e.g., name@domain.com).',
'is_unique' => 'This Email address already exists.'
]
],
@ -152,10 +154,11 @@ class UserController extends AdminController
// Mobile
// ======================
'mobile' => [
'rules' => 'required|regex_match[/^[6-9][0-9]{9}$/]',
'rules' => 'required|regex_match[/^[6-9][0-9]{9}$/]|is_unique[user_profiles.mobile]',
'errors' => [
'required' => 'Mobile number is required',
'regex_match' => 'Enter a valid 10-digit mobile number starting with 6, 7, 8, or 9',
'is_unique' => 'This Mobile number already exists.'
]
],
@ -268,7 +271,10 @@ class UserController extends AdminController
if (!$this->request->getPost()) {
return redirect()->to(base_url('/user/list'));
} else {
// echo ":/ in 163";
$data = $this->request->getPost();
$userData = sanitizeInputArrayAdvanced($data);
$id = $userData['PrimaryKey'];
$rules = [
// ======================
@ -297,13 +303,13 @@ class UserController extends AdminController
// Employee Code
// ======================
'emp_code' => [
'label' => 'Employee Code',
'rules' => 'required|min_length[3]|max_length[15]|regex_match[/^[a-zA-Z0-9_\-\/]+$/]',
'rules' => "required|min_length[3]|max_length[15]|regex_match[/^[a-zA-Z0-9_\-\/]+$/]|is_unique[user_profiles.emp_code,id,{$id}]",
'errors' => [
'required' => 'Employee Code is required',
'min_length' => 'Employee Code must be at least 3 characters',
'max_length' => 'Employee Code cannot exceed 15 characters',
'regex_match' => 'Employee Code can only contain letters, numbers, underscores, hyphens, and forward slashes (/).'
'regex_match' => 'Employee Code can only contain letters, numbers, underscores, hyphens, and forward slashes (/).',
'is_unique' => 'This Employee Code already exists.'
]
],
@ -324,10 +330,11 @@ class UserController extends AdminController
// Email
// ======================
'email' => [
'rules' => 'required|regex_match[/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/]',
'rules' => "required|regex_match[/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/]|is_unique[user_profiles.email,id,{$id}]",
'errors' => [
'required' => 'Email address is required.',
'regex_match' => 'Please enter a valid email format (e.g., name@domain.com).'
'regex_match' => 'Please enter a valid email format (e.g., name@domain.com).',
'is_unique' => 'This Email address already exists.'
]
],
@ -335,10 +342,11 @@ class UserController extends AdminController
// Mobile
// ======================
'mobile' => [
'rules' => 'required|regex_match[/^[6-9][0-9]{9}$/]',
'rules' => "required|regex_match[/^[6-9][0-9]{9}$/]|is_unique[user_profiles.mobile,id,{$id}]",
'errors' => [
'required' => 'Mobile number is required',
'regex_match' => 'Enter a valid 10-digit mobile number starting with 6, 7, 8, or 9',
'is_unique' => 'This Mobile number already exists.'
]
],
@ -466,7 +474,29 @@ class UserController extends AdminController
$emailToDelete = $model->where('id', $id)->first();
$deactive = $model->where('id', $id)->set(['is_active' => 0])->update();
$this->bookStack->deleteUser($emailToDelete);
// $this->bookStack->deleteUser($emailToDelete);
if($deactive)
{
// $db = \Config\Database::connect();
// $tableName = 'hdz_staff';
// $db->table($tableName)->insert($hdz_staff);
echo json_encode(array("status" => true));
}else{
echo json_encode(array("status" => false));
}
}
public function activateUser($id = null)
{
$model = new UserModel();
$emailToDelete = $model->where('id', $id)->first();
$deactive = $model->where('id', $id)->set(['is_active' => 1])->update();
// $this->bookStack->deleteUser($emailToDelete);
if($deactive)
{
// $db = \Config\Database::connect();

View File

@ -389,7 +389,15 @@ table.dataTable tbody td {
<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" style="cursor: pointer;">
<a data-toggle="modal" data-target="#con-close-modal" class="dropdown-item btnEdit" data-id="<?php echo $row->id; ?>"><i data-id="<?php echo $row->id; ?>" class="mdi mdi-pencil mr-2 text-muted font-18 vertical-middle btnEdit"></i>Edit</a>
<a class="dropdown-item btnDelete" data-id="<?php echo $row->id; ?>"><i data-id="<?php echo $row->id; ?>" class="mdi mdi-delete mr-2 text-muted font-18 vertical-middle btnDelete"></i>Delete</a>
<?php if($row->is_active == 1 && in_array(get_session_userid(), [1, 5])) { ?>
<a class="dropdown-item btnDelete" data-id="<?php echo $row->id; ?>"><i data-id="<?php echo $row->id; ?>" class="mdi mdi-delete mr-2 text-muted font-18 vertical-middle btnDelete"></i>Delete</a>
<?php } ?>
<?php if($row->is_active == 0 && in_array(get_session_userid(), [1, 5])) { ?>
<a class="dropdown-item btnActivate" data-id="<?php echo $row->id; ?>">
<i class="mdi mdi-account-check mr-2 text-muted font-18 vertical-middle btnActivate" data-id="<?php echo $row->id; ?>"></i>
Activate
</a>
<?php } ?>
</div>
</div>
</td>
@ -493,7 +501,7 @@ table.dataTable tbody td {
<select class="form-control" id="nhance_branch_id" name="nhance_branch_id" required>
<option value="">Select Nhance Branch</option>
<?php foreach($NHanceBranchData as $value) { ?>
<option value="<?= $value['id'] ?>"><?= $value['branch_name'] ?></option>
<option value="<?= $value['id'] ?>" <?= old('nhance_branch_id') == $value['id'] ? 'selected' : '' ?>><?= $value['branch_name'] ?></option>
<?php } ?>
</select>
</div>
@ -502,7 +510,7 @@ table.dataTable tbody td {
<select class="form-control" id="rm_id" name="rm_id" required>
<option value="">Select Reporting Manager</option>
<?php foreach($user_data as $value) { ?>
<option value="<?= $value['id'] ?>"><?= $value['first_name'] ?></option>
<option value="<?= $value['id'] ?>" <?= old('rm_id') == $value['id'] ? 'selected' : '' ?>><?= $value['first_name'] ?></option>
<?php } ?>
</select>
</div>
@ -511,11 +519,11 @@ table.dataTable tbody td {
<div class="form-row">
<div class="form-group col-md-6">
<label for="emp_code">Employee Code<span class="text-danger">*</span></label>
<input type="text" class="form-control" id="emp_code" placeholder="Enter Code" name="emp_code" onchange="validateInput(this, 'user_profiles', 'emp_code', 'btnSubmit')" required>
<input type="text" class="form-control" id="emp_code" placeholder="Enter Code" name="emp_code" onchange="validateInput(this, 'user_profiles', 'emp_code', 'btnSubmit')" required value="<?= old('emp_code') ?>">
</div>
<div class="form-group col-md-6">
<label for="first_name">Name<span class="text-danger">*</span></label>
<input type="text" class="form-control" id="first_name" placeholder="Enter Name" name="first_name" required>
<input type="text" class="form-control" id="first_name" placeholder="Enter Name" name="first_name" required value="<?= old('first_name') ?>">
</div>
</div>
@ -523,19 +531,19 @@ table.dataTable tbody td {
<div class="form-row">
<div class="form-group col-md-6">
<label for="email">Email<span class="text-danger">*</span></label>
<input type="text" class="form-control" id="email" placeholder="Enter Email" name="email" data-parsley-trigger="change" data-parsley-type="email" onchange="validateInput(this, 'user_profiles', 'email', 'btnSubmit')" required>
<input type="text" class="form-control" id="email" placeholder="Enter Email" name="email" data-parsley-trigger="change" data-parsley-type="email" onchange="validateInput(this, 'user_profiles', 'email', 'btnSubmit')" required value="<?= old('email') ?>">
</div>
<div class="form-group col-md-6">
<label for="mobile">Mobile Number<span class="text-danger">*</span></label>
<input type="text" class="form-control" id="mobile" placeholder="Enter Mobile Number ( starting with 6, 7, 8, or 9 only. )" name="mobile" onkeypress = "return onlyNumbers(event)" maxlength="10" minlength="10" pattern="^[6-9]\d{9}$" data-parsley-type-message="Please enter a valid 10-digit mobile number starting with 6, 7, 8, or 9." data-parsley-required-message="Please enter a valid 10-digit mobile number starting with 6, 7, 8, or 9." required>
<input type="text" class="form-control" id="mobile" placeholder="Enter Mobile Number ( starting with 6, 7, 8, or 9 only. )" name="mobile" onkeypress="return onlyNumbers(event)" onchange="validateInput(this, 'user_profiles', 'mobile', 'btnSubmit')" maxlength="10" minlength="10" pattern="^[6-9]\d{9}$" data-parsley-type-message="Please enter a valid 10-digit mobile number starting with 6, 7, 8, or 9." data-parsley-required-message="Please enter a valid 10-digit mobile number starting with 6, 7, 8, or 9." required value="<?= old('mobile') ?>">
</div>
</div>
<div class="form-row">
<div class="form-group col-md-6">
<label for="emp_code">User Role<span class="text-danger">*</span>
<label for="role">User Role<span class="text-danger">*</span>
<span class="tooltip-trigger mdi mdi-information-outline" id="roleAccessMatrixTrigger"></span>
</label>
<select class="form-control" id="role" name="role" required>
@ -557,7 +565,7 @@ table.dataTable tbody td {
</div>
<div class="form-group col-md-6">
<label for="profile">User Team<span class="text-danger">*</span>
<label for="team">User Team<span class="text-danger">*</span>
<span class="tooltip-trigger mdi mdi-information-outline" id="accessMatrixTrigger"></span>
</label>
<select hidden class="form-control" id="team" name="team[]" multiple required>
@ -891,6 +899,21 @@ table.dataTable tbody td {
<?php foreach (session()->getFlashdata('errors') as $error): ?>
toastr.error("<?= addslashes($error) ?>", "Validation Error");
<?php endforeach; ?>
var errorModal = new bootstrap.Modal(document.getElementById('con-close-modal'));
errorModal.show();
<?php if(old('PrimaryKey')): ?>
$('#UserForm').attr('action', '<?= base_url('/user/edit') ?>');
$('#UserId').val('<?= old('PrimaryKey') ?>');
$('#btnSubmit').html('Update');
$('.modal-title').text('Update User');
$('#email').attr('data-original', '<?= old('email') ?>');
$('#mobile').attr('data-original', '<?= old('mobile') ?>');
$('#emp_code').attr('data-original', '<?= old('emp_code') ?>');
<?php else: ?>
$('#UserForm').attr('action', '<?= base_url('/user/create') ?>');
<?php endif; ?>
});
</script>
<?php endif; ?>
@ -1086,10 +1109,11 @@ table.dataTable tbody td {
$('.close').click(function(){
$('#UserId').val('');
$('#first_name').val('');
$('#email').val('');
$('#mobile').val('');
$('#emp_code').val('');
$('#email').val('').removeAttr('data-original');
$('#mobile').val('').removeAttr('data-original');
$('#emp_code').val('').removeAttr('data-original');
$('#role').val('')
$('#btnSubmit').prop('disabled', false);
})
// $('body').on('click', '#btnUsers', function () {
@ -1103,83 +1127,74 @@ table.dataTable tbody td {
// $(this).addClass('active');
// loadPartner();
// });
$('body').on('click', '.btnEdit', function () {
$('body').on('click', '.btnEdit', function () {
var user_id = $(this).attr('data-id');
$.ajax({
url: '<?php echo base_url('user/getuser/');?>'+user_id,
type: "GET",
dataType: 'json',
success: function (res) {
console.log(":():",res);
console.log(":():",res.data.nhance_branch_id);
$('#updateModal').modal('show');
$('#role').val('')
$('#UserForm').attr('action', '<?php echo base_url('user/edit');?>');
$('#UserId').val(res.data.id);
$('#first_name').val(res.data.first_name);
$('#last_name').val(res.data.last_name);
$('#email').val(res.data.email);
$('#mobile').val(res.data.mobile);
$('#emp_code').val(res.data.emp_code);
$('#role option[value="' + res.data.role + '"]').prop('selected', true);
$('#rm_id').val(res.data.rm_id).select2(); // ✅ correct trigger
if (res.data.nhance_branch_id !== null &&
res.data.nhance_branch_id !== "" &&
res.data.nhance_branch_id !== 0) {
$('#nhance_branch_id')
.val(res.data.nhance_branch_id)
.trigger('change.select2');
} else {
$('#nhance_branch_id')
.val(null) // ✅ MUST be null
.trigger('change.select2'); // ✅ correct trigger
}
$('#UserForm').parsley().reset();
$('#btnSubmit').html('Update');
var user_id = $(this).attr('data-id');
$.each(res.userTeamData, function(index, item) {
$('#team option[value="' + item.team_id + '"]').prop('selected', true);
$('#team').multiselect('refresh');
});
$.ajax({
url: '<?php echo base_url('user/getuser/');?>' + user_id,
type: "GET",
dataType: 'json',
success: function (res) {
// Set form action to edit
$('#UserForm').attr('action', '<?php echo base_url('user/edit');?>');
$('#UserId').val(res.data.id);
$('#first_name').val(res.data.first_name);
$('#email').val(res.data.email).attr('data-original', res.data.email);
$('#mobile').val(res.data.mobile).attr('data-original', res.data.mobile);
$('#emp_code').val(res.data.emp_code).attr('data-original', res.data.emp_code);
$('#role').val(res.data.role).trigger('change');
$('#rm_id').val(res.data.rm_id).trigger('change.select2');
},
error: function (xhr, status, error) {
console.error("Error Details:");
console.error("Status Code:", xhr.status);
console.error("Status Text:", xhr.statusText);
console.error("Response Text:", xhr.responseText);
console.error("Ready State:", xhr.readyState);
console.error("Response Headers:", xhr.getAllResponseHeaders());
console.error("Error Thrown:", error);
console.error("Status:", status);
if (xhr.status === 400) {
let response = JSON.parse(xhr.responseText);
let errorMessages = "";
let seenMessages = []; // Array to store unique messages
if (response.errors) {
$.each(response.errors, function (field, message) {
if (!seenMessages.includes(message)) {
errorMessages += `• ${message}<br>`;
seenMessages.push(message); // Mark this message as "seen"
}
});
toastr.error(errorMessages, 'Validation Error', { "allowHtml": true });
} else {
toastr.warning(response.message || 'Validation failed', 'Warning');
}
} else if (xhr.status === 403) {
let response = JSON.parse(xhr.responseText);
toastr.error(response.message, 'Security Policy');
} else if (xhr.status === 500) {
toastr.error('Something went wrong . Please try again later.', 'Server Error');
} else {
toastr.error('An unexpected error occurred. Please try again later.', 'Error');
}
if (res.data.nhance_branch_id) {
$('#nhance_branch_id').val(res.data.nhance_branch_id).trigger('change.select2');
} else {
$('#nhance_branch_id').val(null).trigger('change.select2');
}
});
// Reset team first, then set selected
$('#team').multiselect('deselectAll', false);
$.each(res.userTeamData, function(index, item) {
$('#team option[value="' + item.team_id + '"]').prop('selected', true);
});
$('#team').multiselect('refresh');
$('.modal-title').text('Update User');
$('#btnSubmit').html('Update');
// ✅ Open modal AFTER data is loaded
var myModal = new bootstrap.Modal(document.getElementById('con-close-modal'));
myModal.show();
},
error: function (xhr) {
if (xhr.status === 400) {
let response = JSON.parse(xhr.responseText);
let errorMessages = "";
let seenMessages = [];
if (response.errors) {
$.each(response.errors, function (field, message) {
if (!seenMessages.includes(message)) {
errorMessages += `• ${message}<br>`;
seenMessages.push(message);
}
});
toastr.error(errorMessages, 'Validation Error', { "allowHtml": true });
} else {
toastr.warning(response.message || 'Validation failed', 'Warning');
}
} else if (xhr.status === 403) {
let response = JSON.parse(xhr.responseText);
toastr.error(response.message, 'Security Policy');
} else if (xhr.status === 500) {
toastr.error('Something went wrong. Please try again later.', 'Server Error');
} else {
toastr.error('An unexpected error occurred.', 'Error');
}
}
});
});
$('body').on('click', '.btnDelete', function () {
@ -1201,7 +1216,29 @@ table.dataTable tbody td {
})
}
});
});
});
$('body').on('click', '.btnActivate', function () {
Swal.fire({
title: "Are you sure?",
text: "You need to active this user",
icon: "info",
showCancelButton: true,
confirmButtonColor: "#3085d6",
confirmButtonText: "Yes",
}).then((result) => {
if (result.isConfirmed) {
var student_id = $(this).attr('data-id');
$.get('<?php echo base_url('user/activateUser/');?>'+student_id, function (data) {
console.log(data);
toastr.success('User actived successfully', 'Success');
window.location.reload()
})
}
});
});
$('body').on('click', '.btnPartnerEdit', function () {
let user = JSON.parse($(this).attr('data-obj')); // ✅ convert back to object
@ -1296,13 +1333,95 @@ table.dataTable tbody td {
return false;
}
var form = document.getElementById("UserForm");
var form = document.getElementById("UserForm");
// Add submit event listener to the form
form.addEventListener("submit", function(event) {
// Disable the submit button to avoid multiple submissions
// document.getElementById("btnSubmit").disabled = true;
form.addEventListener("submit", function(event) {
event.preventDefault();
var btn = document.getElementById('btnSubmit');
var currentUserId = $('#UserId').val(); // capture BEFORE ajax
btn.disabled = true;
btn.innerText = "Saving...";
var actionUrl = $('#UserForm').attr('action');
var formData = new FormData(form);
$.ajax({
url: actionUrl,
type: "POST",
data: formData,
processData: false,
contentType: false,
success: function(responseText) {
// Parse returned HTML and look for toastr.error calls (validation errors injected by CI flashdata)
var tempDiv = document.createElement('div');
tempDiv.innerHTML = responseText;
var errorMessages = [];
tempDiv.querySelectorAll('script').forEach(function(script) {
var content = script.innerText || script.textContent;
var matches = content.match(/toastr\.error\("([^"]+)"/g);
if (matches) {
matches.forEach(function(m) {
var msg = m.replace(/toastr\.error\("/, '').replace(/"$/, '');
if (!errorMessages.includes(msg)) {
errorMessages.push(msg);
}
});
}
});
if (errorMessages.length > 0) {
// ❌ VALIDATION FAILED — keep modal OPEN, show all errors in one toast
var errorList = '<ul style="margin:4px 0 0 0; padding-left:18px; text-align:left;">';
errorMessages.forEach(function(msg) {
errorList += '<li>' + msg + '</li>';
});
errorList += '</ul>';
toastr.error(errorList, 'Validation Errors', {
"allowHtml": true,
"timeOut": 8000,
"closeButton": true
});
// ✅ Modal stays OPEN — do NOT hide it
} else {
// ✅ SUCCESS
toastr.success('User saved successfully!', 'Success');
// ✅ Bootstrap 4 way to close modal
$('#con-close-modal').modal('hide');
// Full reset
form.reset();
$('#UserForm').parsley().reset();
$('#UserId').val('');
$('#nhance_branch_id').val(null).trigger('change.select2');
$('#rm_id').val(null).trigger('change.select2');
$('#role').val('').trigger('change');
$('#team').multiselect('deselectAll', false);
$('#team').multiselect('refresh');
$('#email').removeAttr('data-original');
$('#mobile').removeAttr('data-original');
$('#emp_code').removeAttr('data-original');
$('.modal-title').text('Add User');
$('#btnSubmit').text('Submit').prop('disabled', false);
loadUser();
}
},
error: function(xhr) {
toastr.error('An unexpected error occurred. Please try again.', 'Error');
},
complete: function() {
btn.disabled = false;
btn.innerText = currentUserId ? 'Update' : 'Submit';
}
});
});
function submitPartner(event) {
event.preventDefault();
@ -1516,7 +1635,7 @@ table.dataTable tbody td {
<i class="mdi mdi-dots-horizontal"></i>
</a>
<div class="dropdown-menu dropdown-menu-right">
<a data-toggle="modal" data-target="#con-close-modal" class="dropdown-item btnEdit" data-id="${row.id}">
<a class="dropdown-item btnEdit" data-id="${row.id}" style="cursor:pointer;">
<i data-id="${row.id}" class="mdi mdi-pencil mr-2 text-muted font-18 vertical-middle btnEdit"></i>Edit
</a>
<a class="dropdown-item btnDelete" data-id="${row.id}">
@ -1962,22 +2081,30 @@ table.dataTable tbody td {
<script>
$(document).on('click', '#btnAdd', function() {
// Reset the form
$('#UserForm')[0].reset();
$('#UserId').val('');
// Specifically reset Select2 if you are using it
$('#nhance_branch_id').val('').trigger('change');
$('#rm_id').val('').trigger('change');
// Update Modal Title and Action
$('.modal-title').text('Add User');
$('#btnSubmit').text('Submit');
$('#UserForm').attr('action', '<?php echo base_url('/user/create');?>');
var myModal = new bootstrap.Modal(document.getElementById('con-close-modal'));
myModal.show();
});
$('#UserForm')[0].reset(); // 1⃣ reset form values first
$('#UserForm').parsley().reset(); // 2⃣ then reset parsley validation
$('#btnSubmit').prop('disabled', false); // 3⃣ re-enable submit button
$('#nhance_branch_id').val(null).trigger('change.select2');
$('#rm_id').val(null).trigger('change.select2');
$('#team').multiselect('deselectAll', false);
$('#team').multiselect('refresh');
// remove data-original attributes
$('#email').removeAttr('data-original');
$('#mobile').removeAttr('data-original');
$('#emp_code').removeAttr('data-original');
$('.modal-title').text('Add User');
$('#btnSubmit').text('Submit');
$('#UserForm').attr('action', '<?php echo base_url('/user/create');?>');
var myModal = new bootstrap.Modal(document.getElementById('con-close-modal'));
myModal.show();
});
// $(document).on('click', '#btnAdd', function(){
// $('#first_name').val('');
@ -2009,6 +2136,13 @@ table.dataTable tbody td {
function validateInput(input, table, field, submitButId){
let value = $(input).val();
let originalValue = $(input).attr('data-original');
if (originalValue && value.trim().toLowerCase() === originalValue.trim().toLowerCase()) {
$('#' + submitButId).prop('disabled', false);
return;
}
let label = $(input).closest('.form-group').find('label').text().replace('*', '').trim();
let message = "Value is duplicate!";
@ -2018,7 +2152,8 @@ table.dataTable tbody td {
checkDuplicateTableFieldValue(table, field, value, function(isDuplicate) {
if (isDuplicate) {
toastr.warning(message, 'Warning');
toastr.warning(message, 'Warning');
$(input).focus();
// $(input).val('')
$('#' + submitButId).prop('disabled', true);
} else{

View File

@ -67,8 +67,7 @@
<div class="form-row">
<div class="form-group col-md-6">
<label for="mobile">CD Account Number<span class="text-danger">*</span></label>
<input type="text" class="form-control" id="cd_ac_no_for_cd_master" name="cd_ac_no" onkeypress="return onlyNumbers(event)" required data-parsley-type="digits">
<small style="margin-left: 10px;font-size: 10px;"><span class="text-danger" id="cd_ac_no_for_cd_master_errorr"></span></small>
<input type="text" class="form-control" id="cd_ac_no_for_cd_master" name="cd_ac_no" pattern="[a-zA-Z0-9\/_-]+" title="Only letters, numbers, /, -, and _ are allowed" required> <small style="margin-left: 10px;font-size: 10px;"><span class="text-danger" id="cd_ac_no_for_cd_master_errorr"></span></small>
</div>
<div class="form-group col-md-6">
@ -366,4 +365,33 @@
}
}
$(document).ready(function() {
// Target the input by its ID
$('#cd_ac_no_for_cd_master').on('keypress', function(e) {
// Get the character code
var keyCode = e.which || e.keyCode;
var char = String.fromCharCode(keyCode);
// Regular Expression: allow a-z, A-Z, 0-9, /, -, _
// If the character doesn't match, prevent it from being typed
var regex = /^[a-zA-Z0-9\/_-]+$/;
if (!regex.test(char)) {
e.preventDefault();
// Optional: Show a quick error message in your span
$('#cd_ac_no_for_cd_master_errorr').text('Character not allowed').fadeOut(2000, function() {
$(this).text('').show();
});
return false;
}
});
// Also handle "Paste" to ensure invalid data isn't pasted in
$('#cd_ac_no_for_cd_master').on('input', function() {
var value = $(this).val();
var sanitized = value.replace(/[^a-zA-Z0-9\/_-]/g, '');
$(this).val(sanitized);
});
});
</script>

View File

@ -124,8 +124,8 @@ input:checked + .slider:before {
<div class="form-row">
<div class="form-group col-md-4">
<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" data-parsley-trigger="change" data-parsley-pattern="^[A-Z]{5}[0-9]{4}[A-Z]$" required>
<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" data-parsley-trigger="change" data-parsley-pattern="^[A-Z]{5}[0-9]{4}[A-Z]$">
</div>
<!-- <div class="form-group col-md-4">
<label for="gst">GST<span class="text-danger">*</span></label>

View File

@ -254,7 +254,10 @@ input:checked + .slider-branch-contact:before {
<div class="form-group col-md-6">
<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>
name="designation[]" id="designation" required
pattern="[A-Za-z0-9\-_/ ]+"
oninput="this.value = this.value.replace(/[^A-Za-z0-9\-_\/ ]/g, '')"
title="Designation may only contain letters, numbers, /, -, _ and spaces only allowed">
</div>
</div>
<div class="form-row">
@ -736,7 +739,10 @@ function appendContactHtml(contact = false, reset = false) {
</div>
<div class="form-group col-md-6">
<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\-_/ ]+"
oninput="this.value = this.value.replace(/[^A-Za-z0-9\-_\/ ]/g, '')"
title="Designation may only contain letters, numbers, /, -, _ and spaces only allowed">
</div>
</div>
<div class="form-row">

View File

@ -149,15 +149,15 @@ table.dataTable thead th {
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="myCenterModalLabel">Lead List</h4>
<h4 class="modal-title" id="myCenterModalLabel">Opportunity List</h4>
<button type="button" id="close_btn" class="close" data-dismiss="modal" aria-hidden="true">×</button>
</div>
<div class="modal-body">
<div class="form-group col-md-12">
<label for="lead_id"> Lead List <span class="text-danger">*</span></label>
<label for="lead_id"> Opportunity List <span class="text-danger">*</span></label>
<select class="form-control" id="lead_id" name="lead_id" required>
<option value="">Select Lead</option>
<option value="">Select Opportunity</option>
<?php if(isset($lead_data)) { ?>
<?php foreach ($lead_data as $value) { ?>
<option value="<?= $value['id']?>"><?= $value['client_name'] ?> - <?= $value['branch_name'] ?> - <?= $value['user_name'] ?></option>

View File

@ -647,57 +647,58 @@
</script>
<script>
function toggleAccordion(header) {
if (event.target.classList.contains('fa-info-circle') ||
event.target.parentElement.classList.contains('fa-info-circle')) {
getHrActivityHistory();
return; // Do nothing if click was on the info icon
}
const card = header.parentElement;
const content = card.querySelector('.card-content');
const icon = header.querySelector('.accordion-icon i');
// function toggleAccordion(header) {
// if (event.target.classList.contains('fa-info-circle') ||
// event.target.parentElement.classList.contains('fa-info-circle')) {
// getHrActivityHistory();
// return; // Do nothing if click was on the info icon
// }
// const card = header.parentElement;
// const content = card.querySelector('.card-content');
// const icon = header.querySelector('.accordion-icon i');
// Close all other accordions
document.querySelectorAll('.user-card').forEach(otherCard => {
if (otherCard !== card) {
const otherContent = otherCard.querySelector('.card-content');
const otherIcon = otherCard.querySelector('.accordion-icon i');
otherIcon.setAttribute('class', 'mdi mdi-chevron-down');
// // Close all other accordions
// document.querySelectorAll('.user-card').forEach(otherCard => {
// if (otherCard !== card) {
// const otherContent = otherCard.querySelector('.card-content');
// const otherIcon = otherCard.querySelector('.accordion-icon i');
// otherIcon.setAttribute('class', 'mdi mdi-chevron-down');
}
});
// }
// });
// Toggle current accordion
content.classList.toggle('active');
if (content.classList.contains('active')) {
icon.classList.setAttribute('class', 'mdi mdi-chevron-up');
} else {
icon.classList.setAttribute('class', 'mdi mdi-chevron-down');
}
}
// // Toggle current accordion
// content.classList.toggle('active');
// if (content.classList.contains('active')) {
// icon.classList.setAttribute('class', 'mdi mdi-chevron-up');
// } else {
// icon.classList.setAttribute('class', 'mdi mdi-chevron-down');
// }
// }
function toggleSection(checkbox, sectionId) {
const section = document.getElementById(sectionId);
const checkboxes = section.querySelectorAll('input[type="checkbox"]');
// function toggleSection(checkbox, sectionId) {
// const section = document.getElementById(sectionId);
// const checkboxes = section.querySelectorAll('input[type="checkbox"]');
if (checkbox.checked) {
section.classList.remove('hidden');
checkboxes.forEach(cb => {
cb.disabled = false;
});
} else {
section.classList.add('hidden');
checkboxes.forEach(cb => {
cb.checked = false;
cb.disabled = true;
});
}
}
// if (checkbox.checked) {
// section.classList.remove('hidden');
// checkboxes.forEach(cb => {
// cb.disabled = false;
// });
// } else {
// section.classList.add('hidden');
// checkboxes.forEach(cb => {
// cb.checked = false;
// cb.disabled = true;
// });
// }
// }
function getCheckedValues(name) {
const checkboxes = document.querySelectorAll(`input[name="${name}"]:checked`);
return Array.from(checkboxes).map(cb => parseInt(cb.value));
}
// function getCheckedValues(name) {
// const checkboxes = document.querySelectorAll(`input[name="${name}"]:checked`);
// return Array.from(checkboxes).map(cb => parseInt(cb.value));
// }
function getHrActivityHistory() {
console.log(event.target.dataset.id); //return;
@ -827,12 +828,6 @@
}
// Helper function to get checked checkbox values (if not already defined)
function getCheckedValues(namePrefix) {
const checkboxes = document.querySelectorAll(`input[name^="${namePrefix}"]:checked`);
return Array.from(checkboxes).map(cb => cb.value);
}
$(document).on('change', '.select-all', function() {
let $this = $(this);
let type = $this.data('type');

View File

@ -339,15 +339,15 @@ input:checked + .slider_blue::before {
<div class="modal-dialog modal-dialog-centered modal-lg">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="myCenterModalLabel">Lead List</h4>
<h4 class="modal-title" id="myCenterModalLabel">Opportunity List</h4>
<button type="button" id="close_btn" class="close" data-dismiss="modal" aria-hidden="true">×</button>
</div>
<div class="modal-body">
<div class="form-group col-md-12">
<label for="lead_id"> Lead List <span class="text-danger">*</span></label>
<label for="lead_id"> Opportunity List <span class="text-danger">*</span></label>
<select class="form-control" id="lead_id" name="lead_id" required>
<option value="">Select Lead</option>
<option value="">Select Opportunity</option>
<?php if(isset($lead_data)) { ?>
<?php foreach ($lead_data as $value) { ?>
<option value="<?= $value['id']?>" data-clientid="<?= $value['client_id']?>", data-branchid="<?= $value['client_branch_id']?>"><?= $value['client_name'] ?> - <?= $value['branch_name'] ?> - <?= $value['user_name'] ?></option>

View File

@ -126,6 +126,27 @@
<?php foreach ($hr_access_data as $key => $value) {
$key = $key + 1;
// Calculate data counts per user for toggling rules
$prePolicyCount = 0;
if (!empty($pre_policy_data)) {
foreach ($pre_policy_data as $p) {
if (!empty($value['pre_hr_id']) && $value['pre_branch_id'] === $p['branch_id']) {
$prePolicyCount++;
}
}
}
$postPolicyCount = 0;
if (!empty($post_policy_data)) {
foreach ($post_policy_data as $p) {
if (!empty($value['post_hr_id']) && $value['post_branch_id'] === $p['branch_id']) {
$postPolicyCount++;
}
}
}
$cdCount = !empty($post_cd_data) ? count($post_cd_data) : 0;
?>
<!-- User 1 Card -->
@ -158,7 +179,7 @@
<div class="section">
<div class="section-title">
<input type="checkbox" class="main-checkbox"
onchange="toggleSection(this, '<?= 'user' . $key ?>-pre')" name="<?= 'user' . $key ?>_modules"
onchange="toggleSection(this, '<?= 'user' . $key ?>-pre', <?= $prePolicyCount ?>)" name="<?= 'user' . $key ?>_modules"
value="1" <?php if (in_array(1, $value['allowed_pre_modules'] ?? [])) {
echo 'checked';
} ?>>
@ -219,7 +240,7 @@
<div class="section">
<div class="section-title">
<input type="checkbox" class="main-checkbox"
onchange="toggleSection(this, '<?= 'user' . $key ?>-active')" name="<?= 'user' . $key ?>_modules"
onchange="toggleSection(this, '<?= 'user' . $key ?>-active', <?= $postPolicyCount ?>)" name="<?= 'user' . $key ?>_modules"
value="2" <?php if (in_array(2, $value['allowed_post_modules'])) {
echo 'checked';
} ?>>
@ -294,7 +315,7 @@
<div class="section">
<div class="section-title">
<input type="checkbox" class="main-checkbox"
onchange="toggleSection(this, '<?= 'user' . $key ?>-cd')" name="<?= 'user' . $key ?>_modules" value="3" <?php if (in_array(3, $value['allowed_post_modules'])) {
onchange="toggleSection(this, '<?= 'user' . $key ?>-cd', <?= $cdCount ?>)" name="<?= 'user' . $key ?>_modules" value="3" <?php if (in_array(3, $value['allowed_post_modules'])) {
echo 'checked';
} ?>>
<i class="mdi mdi-file mr-2"></i>CD statement
@ -367,4 +388,74 @@
<?php } ?>
</div>
</div>
</div>
</div>
<script>
function toggleAccordion(header) {
const card = header.parentElement;
const content = card.querySelector('.card-content');
const icon = header.querySelector('.accordion-icon i');
// Close all other accordions
document.querySelectorAll('.user-card').forEach(otherCard => {
if (otherCard !== card) {
const otherContent = otherCard.querySelector('.card-content');
const otherIcon = otherCard.querySelector('.accordion-icon i');
if (otherContent && otherIcon) {
otherContent.classList.remove('active');
otherIcon.setAttribute('class', 'mdi mdi-chevron-down');
}
}
});
// Toggle current accordion
if (content && icon) {
content.classList.toggle('active');
if (content.classList.contains('active')) {
icon.setAttribute('class', 'mdi mdi-chevron-up');
} else {
icon.setAttribute('class', 'mdi mdi-chevron-down');
}
}
}
function toggleSection(checkbox, sectionId, dataCount) {
const section = document.getElementById(sectionId);
const checkboxes = section.querySelectorAll('input[type="checkbox"]');
// If checkbox is being unchecked, always allow without any restriction
if (!checkbox.checked) {
section.classList.add('hidden');
checkboxes.forEach(cb => {
cb.checked = false;
cb.disabled = true;
});
return;
}
// From here, checkbox is being checked
// If there is no data, show warning and revert the checkbox state
if (!dataCount || dataCount === 0) {
checkbox.checked = false;
if (typeof toastr !== 'undefined' && toastr.warning) {
toastr.warning('No data available for this section.', 'Warning');
} else {
alert('No data available for this section.');
}
return;
}
// Data is available and checkbox is being checked - show section and enable inner checkboxes
section.classList.remove('hidden');
checkboxes.forEach(cb => {
cb.disabled = false;
});
}
function getCheckedValues(name) {
const checkboxes = document.querySelectorAll(`input[name="${name}"]:checked`);
return Array.from(checkboxes).map(cb => cb.value);
}
</script>

View File

@ -314,7 +314,7 @@
</div>
<div class="form-group col-md-4 renewalFields">
<label for="contact_person_summary">Contact Person</label>
<label for="contact_person_summary">Contact Person<span class="text-danger">*</span></label>
<select class="form-control" name="contact_person_summary" id="contact_person_summary">
<option value="">Select a Contact</option>
</select>
@ -1243,7 +1243,7 @@
</div>
<div class="form-group col-md-4">
<label for="">Date of Commencement <span class="text-danger"></span></label>
<label for="">Date of Commencement <span class="text-danger">*</span></label>
<div class="input-icon">
<input type="text" class="form-control policy_start_date" id="policy_start_date_${increment}" name="policy_start_date[]" placeholder="Enter DOC" onchange="calculatePolicyMetrics(this)">
<i class="mdi mdi-calendar-blank-outline additional-icon"></i>
@ -1252,7 +1252,7 @@
</div>
<div class="form-group col-md-4">
<label for="">Date of Expiry <span class="text-danger"></span></label>
<label for="">Date of Expiry <span class="text-danger">*</span></label>
<div class="input-icon">
<input type="text" class="form-control policy_end_date" id="policy_end_date_${increment}" name="policy_end_date[]" placeholder="Enter DOE">
<i class="mdi mdi-calendar-blank-outline additional-icon"></i>

View File

@ -8,16 +8,17 @@
</div>
<div class="modal-body" style="overflow-y: auto;height: 90vh;">
<form class="parsley-examples" method="post" id="client_form" enctype="multipart/form-data">
<input type="hidden" name="from_modal" value="1">
<div class="form-group">
<div class="form-row">
<div class="form-group col-md-12">
<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>
<label for="client_name_for_modal">Client Name<span class="text-danger">*</span></label>
<input type="text" class="form-control" id="client_name_for_modal" name="client_name" required>
</div>
<div class="form-group col-md-12">
<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>
<label for="client_short_name_for_modal">Client Short name<span class="text-danger">*</span></label>
<input type="text" class="form-control" id="client_short_name_for_modal" name="short_name" onkeyup="validateInputForClient(this, 'clients', 'short_name')" required>
</div>
<div class="form-group col-md-12">
@ -31,7 +32,7 @@
<!-- Client Type -->
<div class="form-row clienttypediv" style="display: none;">
<div class="form-group col-md-6">
<!-- <div class="form-group col-md-6">
<label for="dob">Date of Birth<span class="text-danger">*</span></label>
<input type="text" class="form-control" id="dob" placeholder="DD/MM/YYYY" name="dob" >
</div>
@ -40,16 +41,16 @@
<label for="cost_center">Mobile<span class="text-danger"></span></label>
<input type="text" class="form-control" id="phone" placeholder="Enter Mobile Number" maxlength="10" name="phone"
onkeypress="return onlyNumbers(event)" onchange="validateInputForClient(this, 'clients', 'phone')">
</div>
</div> -->
<div class="form-group col-md-12">
<!-- <div class="form-group col-md-12">
<label for="email2">Email<span class="text-danger">*</span></label>
<input type="email" class="form-control" id="email2" placeholder="Enter Email" name="email2">
</div>
<div class="form-group col-md-12">
<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')">
</div>
</div> -->
</div>
@ -57,8 +58,8 @@
<div class="form-row branchdiv">
<div class="form-group col-md-12">
<label for="short_name">Entity Type<span class="text-danger"></span></label>
<select class="form-control" id="entity_type_id_for_client" name="entity_type_id">
<label for="short_name">Entity Type<span class="text-danger">*</span></label>
<select class="form-control" id="entity_type_id_for_client" name="entity_type_id" required>
<option value="" selected>Select Entity</option>
<?php
if (isset($entity) && count($entity)) {
@ -87,7 +88,7 @@
<div class="form-group col-md-6">
<label for="branch_code">Mobile<span class="text-danger">*</span></label>
<input type="text" class="form-control" id="mobile" maxlength="10" name="mobile" onkeypress="return onlyNumbers(event)" required>
<input type="text" class="form-control" id="mobile" maxlength="10" name="mobile" onkeypress="return onlyNumbers(event)" oninput="this.value = this.value.replace(/[^0-9]/g, '');" required>
</div>
<div class="form-group col-md-12">
<label for="email">Email<span class="text-danger">*</span></label>
@ -285,11 +286,87 @@
error: function (xhr, status, error) {
console.error(xhr.responseText);
console.error(status, error);
isClientFormSubmitting = false;
$('.loader').fadeOut();
$('.loader-mask').delay(350).fadeOut('slow');
setTimeout(function() {
$('.loader').fadeOut();
$('.loader-mask').delay(350).fadeOut('slow');
// $('#client_add_modal_submit_btn').prop('disabled', false);
if (xhr.status === 400) {
let response = JSON.parse(xhr.responseText);
let errorMessages = "";
let seenMessages = []; // Array to store unique messages
if (response.errors) {
$.each(response.errors, function (field, message) {
if (!seenMessages.includes(message)) {
errorMessages += `• ${message}<br>`;
seenMessages.push(message); // Mark this message as "seen"
}
});
toastr.error(errorMessages, 'Validation Error', { "allowHtml": true });
} else {
toastr.warning(response.message || 'Validation failed', 'Warning');
}
} else if (xhr.status === 403) {
let response = JSON.parse(xhr.responseText);
toastr.error(response.message, 'Security Policy');
} else if (xhr.status === 404) {
toastr.warning('Resource not found', 'Warning');
} else if (xhr.status === 500) {
toastr.error('Something went wrong . Please try again later.', 'Server Error');
} else {
toastr.error('An unexpected error occurred. Please try again later.', 'Error');
}
}, 1000);
}
});
});
$('#client_name_for_modal').on('input', function() {
clearTimeout(shortNameTimer);
shortNameTimer = setTimeout(generateShortNameModal, 200);
});
function generateShortNameModal() {
let clientInput = $("#client_name_for_modal");
let shortInput = $("#client_short_name_for_modal");
let newClientName = clientInput.val().trim();
console.log(`LN : NEW - ${newClientName}`);
if (newClientName.length == 0) {
shortInput.val('');
return;
}
let shortName = newClientName.substring(0, 10).replace(/\s+/g, '').toUpperCase();
console.log(`LN : NEW - ${shortName}`);
makeUniqueShortNameModal(shortName);
}
function makeUniqueShortNameModal(baseName) {
let input = $("#client_short_name_for_modal")[0];
checkDuplicateTableFieldValue("clients", "short_name", baseName, function(isDuplicate) {
if (isDuplicate) {
let counter = 1;
function tryNext() {
let padded = String(counter).padStart(3, '0'); // 001, 002, 003
let newName = baseName + padded;
checkDuplicateTableFieldValue("clients", "short_name", newName, function(exists) {
if (exists) {
counter++;
tryNext();
} else {
$("#client_short_name_for_modal").val(newName);
validateInput(input, "clients", "short_name");
}
});
}
tryNext();
} else {
$("#client_short_name_for_modal").val(baseName);
validateInput(input, "clients", "short_name");
}
});
}
</script>