FEAT_RULE_LIST
This commit is contained in:
parent
35e83c6d3a
commit
0a341a731a
@ -784,5 +784,8 @@ $routes->group('commission', function($routes) {
|
|||||||
$routes->get('downloadErrorFile',"RuleImportController::downloadErrorFile");
|
$routes->get('downloadErrorFile',"RuleImportController::downloadErrorFile");
|
||||||
$routes->get("deleteCommissionData/(:any)", "RuleImportController::deleteCommissionData/$1");
|
$routes->get("deleteCommissionData/(:any)", "RuleImportController::deleteCommissionData/$1");
|
||||||
$routes->get('checkSameEntry',"RuleImportController::checkSameEntry");
|
$routes->get('checkSameEntry',"RuleImportController::checkSameEntry");
|
||||||
|
$routes->get('rules/list/(:any)',"RuleImportController::ruleList/$1");
|
||||||
|
$routes->post('rules/save/',"RuleImportController::saveRule");
|
||||||
|
$routes->post('rules/remove/',"RuleImportController::removeRule");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -12,6 +12,7 @@ class RuleImportController extends AdminController
|
|||||||
protected $ruleImportService;
|
protected $ruleImportService;
|
||||||
protected $commissionFilesModel;
|
protected $commissionFilesModel;
|
||||||
protected $departments;
|
protected $departments;
|
||||||
|
protected $departmentFields;
|
||||||
protected $insurerModel;
|
protected $insurerModel;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
@ -27,6 +28,19 @@ class RuleImportController extends AdminController
|
|||||||
'motor' => 'Motor',
|
'motor' => 'Motor',
|
||||||
'health' => 'Health',
|
'health' => 'Health',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
$this->departmentFields = [
|
||||||
|
'motor' => [
|
||||||
|
'department',
|
||||||
|
'vehicle_type',
|
||||||
|
'policy_type',
|
||||||
|
'vehicle_age',
|
||||||
|
'is_new_vehicle',
|
||||||
|
'cubic_capacity',
|
||||||
|
'policy_business_type',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function commissionFileUploadList()
|
public function commissionFileUploadList()
|
||||||
@ -487,7 +501,7 @@ class RuleImportController extends AdminController
|
|||||||
public function deleteCommissionData($id)
|
public function deleteCommissionData($id)
|
||||||
{
|
{
|
||||||
|
|
||||||
$return = $this->removeCommissionRules($id);
|
$return = $this->updateCommissionRules($id);
|
||||||
// dd($return);
|
// dd($return);
|
||||||
|
|
||||||
if($return['status'] == true){
|
if($return['status'] == true){
|
||||||
@ -498,7 +512,7 @@ class RuleImportController extends AdminController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function deActiveCommissionRules($id)
|
public function updateCommissionRules($id, $post_data = null)
|
||||||
{
|
{
|
||||||
// 1. Fetch commission record
|
// 1. Fetch commission record
|
||||||
$commission_data = $this->commissionFilesModel
|
$commission_data = $this->commissionFilesModel
|
||||||
@ -528,7 +542,7 @@ class RuleImportController extends AdminController
|
|||||||
// 4. Read JSON
|
// 4. Read JSON
|
||||||
$json = file_get_contents($filePath);
|
$json = file_get_contents($filePath);
|
||||||
$rules = json_decode($json, true);
|
$rules = json_decode($json, true);
|
||||||
// dd($rules);
|
// print_rr($rules); die;
|
||||||
|
|
||||||
if (!is_array($rules)) {
|
if (!is_array($rules)) {
|
||||||
$this->myLogger->logme("error", "Invalid JSON structure in file: $filePath");
|
$this->myLogger->logme("error", "Invalid JSON structure in file: $filePath");
|
||||||
@ -537,9 +551,58 @@ class RuleImportController extends AdminController
|
|||||||
|
|
||||||
// 5. Mark matching rule as deleted
|
// 5. Mark matching rule as deleted
|
||||||
$ruleFound = false;
|
$ruleFound = false;
|
||||||
|
$log_message = "Rule file updated successfully";
|
||||||
|
|
||||||
|
if(empty($post_data)){
|
||||||
foreach ($rules as &$rule) {
|
foreach ($rules as &$rule) {
|
||||||
if (!isset($rule['is_deleted']) && isset($rule['file_id']) && $rule['file_id'] == $id) {
|
if (isset($rule['file_id']) && $rule['file_id'] == $id && isset($rule['is_deleted']) && $rule['is_deleted'] == false) {
|
||||||
$rule['is_deleted'] = true; // <-- NEW FEATURE
|
$rule['is_deleted'] = true;
|
||||||
|
$ruleFound = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$log_message = "Rule marked as deleted and file updated successfully";
|
||||||
|
} else {
|
||||||
|
|
||||||
|
foreach ($rules as &$rule) {
|
||||||
|
// Match rules for the same file and not deleted
|
||||||
|
if (isset($rule['file_id']) && $rule['file_id'] == $id && $rule['is_deleted'] == false)
|
||||||
|
{
|
||||||
|
// 1. DELETE RULE
|
||||||
|
if (!empty($post_data['rule_id']) && $post_data['rule_id'] == $rule['id'] && isset($post_data['is_deleted']))
|
||||||
|
{
|
||||||
|
$rule['is_deleted'] = true;
|
||||||
|
$ruleFound = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. UPDATE RULE
|
||||||
|
if (!empty($post_data['rule_id']) && $post_data['rule_id'] == $rule['id'])
|
||||||
|
{
|
||||||
|
$rule['conditions'] = $post_data['rule_data']['conditions'];
|
||||||
|
$rule['calculation'] = $post_data['rule_data']['calculation'];
|
||||||
|
$rule['name'] = $post_data['rule_data']['name'];
|
||||||
|
$ruleFound = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. CREATE NEW RULE (only if not found)
|
||||||
|
if (empty($post_data['rule_id']) && !$ruleFound) {
|
||||||
|
|
||||||
|
$newRuleId = 'rule_' . substr(md5(time()), 0, 13);
|
||||||
|
$newRule = [
|
||||||
|
'id' => $newRuleId,
|
||||||
|
'name' => $post_data['rule_data']['name'],
|
||||||
|
"department" => $post_data['rule_data']['department'] ?? "motor",
|
||||||
|
'is_deleted' => false,
|
||||||
|
'file_id' => $id,
|
||||||
|
'conditions' => $post_data['rule_data']['conditions'],
|
||||||
|
'calculation' => $post_data['rule_data']['calculation'],
|
||||||
|
];
|
||||||
|
|
||||||
|
$rules[] = $newRule; // correctly push new rule
|
||||||
|
|
||||||
$ruleFound = true;
|
$ruleFound = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -552,11 +615,11 @@ class RuleImportController extends AdminController
|
|||||||
// 6. Always save file back (No unlink)
|
// 6. Always save file back (No unlink)
|
||||||
file_put_contents($filePath, json_encode($rules, JSON_PRETTY_PRINT));
|
file_put_contents($filePath, json_encode($rules, JSON_PRETTY_PRINT));
|
||||||
|
|
||||||
$this->myLogger->logme("error", "Rule marked deleted and file updated: $filePath");
|
$this->myLogger->logme("error", $log_message);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'status' => true,
|
'status' => true,
|
||||||
'message' => 'Rule marked as deleted and file updated successfully'
|
'message' => $log_message
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -641,5 +704,98 @@ class RuleImportController extends AdminController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function ruleList($id)
|
||||||
|
{
|
||||||
|
$data['page_name'] = "Rule Manager";
|
||||||
|
$data['departments'] = $this->departments;
|
||||||
|
$data['commission_file_id'] = $id;
|
||||||
|
$data['departmentFields'] = json_encode($this->departmentFields);
|
||||||
|
$data['rules'] = $this->getRuleJson($id);
|
||||||
|
return $this->loadLayout('commission_rules_list', $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRuleJson($id)
|
||||||
|
{
|
||||||
|
|
||||||
|
// 1. Fetch commission record
|
||||||
|
$commission_data = $this->commissionFilesModel
|
||||||
|
->where('is_active', 1)
|
||||||
|
->where('id', $id)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
if (!$commission_data) {
|
||||||
|
$this->myLogger->logme("error", "Commission record not found for ID: $id");
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Convert commission_month → OCT2025
|
||||||
|
$month = date("M", strtotime($commission_data['commission_month']));
|
||||||
|
$year = date("Y", strtotime($commission_data['commission_month']));
|
||||||
|
$monthFolder = strtoupper($month . $year);
|
||||||
|
|
||||||
|
// 3. Path
|
||||||
|
$fileName = $commission_data['insurer_id'] . '_' . $commission_data['department'] . '.json';
|
||||||
|
$filePath = WRITEPATH . "uploads/commission/rules/" . $monthFolder . "/" . $fileName;
|
||||||
|
|
||||||
|
if (!file_exists($filePath)) {
|
||||||
|
$this->myLogger->logme("error", "Rule file not found: $filePath");
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Read JSON
|
||||||
|
$json = file_get_contents($filePath);
|
||||||
|
$rules = json_decode($json, true);
|
||||||
|
|
||||||
|
if(!empty($rules)){
|
||||||
|
return $rules;
|
||||||
|
}else{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function saveRule()
|
||||||
|
{
|
||||||
|
$post_data = $this->request->getPost();
|
||||||
|
|
||||||
|
$file_id = $post_data['file_id'];
|
||||||
|
$return = $this->updateCommissionRules($file_id, $post_data);
|
||||||
|
// print_r($return); die;
|
||||||
|
|
||||||
|
if(empty($post_data['rule_id'])){
|
||||||
|
$success_message = "New rule created successfully";
|
||||||
|
$error_message = "Failed to created the new rule";
|
||||||
|
}else{
|
||||||
|
$success_message = "Rule updated successfully";
|
||||||
|
$error_message = "Failed to update the rule";
|
||||||
|
}
|
||||||
|
|
||||||
|
if($return['status'] == true){
|
||||||
|
$data = $this->getRuleJson($file_id);
|
||||||
|
return $this->respond(['status' => true, 'code' => 200, 'data' => $data, 'message' => $success_message], 200);
|
||||||
|
}else{
|
||||||
|
return $this->respond(['status' => false, 'code' => 400, 'message' => $error_message], 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removeRule()
|
||||||
|
{
|
||||||
|
$post_data = $this->request->getPost();
|
||||||
|
|
||||||
|
$file_id = $post_data['file_id'];
|
||||||
|
$return = $this->updateCommissionRules($file_id, $post_data);
|
||||||
|
// print_r($return); die;
|
||||||
|
|
||||||
|
$success_message = "Rule deleted successfully";
|
||||||
|
$error_message = "Failed to delete the rule";
|
||||||
|
|
||||||
|
if($return['status'] == true){
|
||||||
|
$data = $this->getRuleJson($file_id);
|
||||||
|
return $this->respond(['status' => true, 'code' => 200, 'data' => $data, 'message' => $success_message], 200);
|
||||||
|
}else{
|
||||||
|
return $this->respond(['status' => false, 'code' => 400, 'message' => $error_message], 200);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
945
app/Views/commission_rules_list.php
Normal file
945
app/Views/commission_rules_list.php
Normal file
@ -0,0 +1,945 @@
|
|||||||
|
<style>
|
||||||
|
.container {
|
||||||
|
max-width: 1400px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-bar {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
background: white;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 5px 15px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.filter-section {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Card Grid */
|
||||||
|
.rules-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
|
||||||
|
gap: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rule-card {
|
||||||
|
background: white;
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 10px;
|
||||||
|
box-shadow: 0 5px 20px rgba(0,0,0,0.1);
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
/* border-top: 3px solid #E26728; */
|
||||||
|
border-top: 3px solid #02a8b5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rule-card:hover {
|
||||||
|
transform: translateY(-5px);
|
||||||
|
box-shadow: 0 10px 30px rgba(0,0,0,0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rule-card-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: start;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rule-name {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #2c3e50;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
line-height: 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rule-details {
|
||||||
|
margin: 10px 0;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 8px;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rule-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
margin-top: 12px;
|
||||||
|
padding-top: 12px;
|
||||||
|
/* border-top: 1px solid #e9ecef; */
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.department-badge {
|
||||||
|
padding: 2px 5px;
|
||||||
|
border-radius: 15px;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: white;
|
||||||
|
background: linear-gradient(45deg, #3498db, #2980b9);
|
||||||
|
}
|
||||||
|
|
||||||
|
.condition-badge {
|
||||||
|
padding: 2px 5px;
|
||||||
|
border-radius: 15px;
|
||||||
|
font-size: 7px;
|
||||||
|
color: white;
|
||||||
|
background: linear-gradient(45deg, #3498db, #2980b9);
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-item {
|
||||||
|
font-size: 10px;
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-label {
|
||||||
|
font-weight: 500;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ruleModal .modal-body {
|
||||||
|
max-height: 450px; /* adjust as needed */
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
padding: 0px 10px !important;
|
||||||
|
border-radius: 18px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close {
|
||||||
|
color: white;
|
||||||
|
font-size: 2rem;
|
||||||
|
font-weight: bold;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: transform 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close:hover {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.conditions-container {
|
||||||
|
border: 2px solid #e9ecef;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 15px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
background: #f8f9fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.condition-row {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr 1fr auto;
|
||||||
|
gap: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
align-items: end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calculation-section {
|
||||||
|
background: #f8f9fa;
|
||||||
|
border: 2px solid #e9ecef;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.component-row {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr 1fr auto;
|
||||||
|
gap: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
align-items: end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert {
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 8px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-success {
|
||||||
|
background: #d4edda;
|
||||||
|
color: #155724;
|
||||||
|
border: 1px solid #c3e6cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-error {
|
||||||
|
background: #f8d7da;
|
||||||
|
color: #721c24;
|
||||||
|
border: 1px solid #f5c6cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-state {
|
||||||
|
text-align: center;
|
||||||
|
padding: 60px 20px;
|
||||||
|
color: #7f8c8d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-state h3 {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.rules-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.condition-row, .component-row {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-bar {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filter-section {
|
||||||
|
width: 100%;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.readonly-select {
|
||||||
|
pointer-events: none;
|
||||||
|
/* background-color: #f0f0f0; */
|
||||||
|
background-color: #e0e0e0;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
|
||||||
|
<!-- Action Bar -->
|
||||||
|
<div class="action-bar">
|
||||||
|
<div class="filter-section">
|
||||||
|
<label for="filterDepartment">Filter:</label>
|
||||||
|
<select class="form-control" id="filterDepartment" onchange="filterRules()">
|
||||||
|
<option value="">All Departments</option>
|
||||||
|
<option value="Health">Health</option>
|
||||||
|
<option value="Motor">Motor</option>
|
||||||
|
<option value="Fire">Fire</option>
|
||||||
|
<option value="Travel">Travel</option>
|
||||||
|
<option value="Marine">Marine</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-primary" onclick="openModal()">Create New Rule</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Rules Grid -->
|
||||||
|
<div id="rulesList" class="rules-grid">
|
||||||
|
<!-- Rules will be displayed here as cards -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Modal -->
|
||||||
|
<div id="ruleModal" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true" aria-modal="true" data-bs-backdrop="static">
|
||||||
|
<div class="modal-dialog modal-lg" style="max-width: 800px;">
|
||||||
|
<div class="modal-content">
|
||||||
|
|
||||||
|
<div class="modal-header" style="background-color: gainsboro;">
|
||||||
|
<h5 class="modal-title" id="modalTitle">Create New Rule <span id="heading"></span></h5>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-hidden="true" onclick="closeModal()">×</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div id="alert-container"></div>
|
||||||
|
<form id="ruleForm">
|
||||||
|
<input type="hidden" id="ruleId" name="rule_id">
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="department">Department: *</label>
|
||||||
|
<select class="form-control readonly-select" id="department" name="department" required>
|
||||||
|
<?php
|
||||||
|
if (isset($departments) && count($departments)) {
|
||||||
|
foreach ($departments as $key => $value) {
|
||||||
|
echo "<option value=" . $key . ">" . $value . "</option>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="ruleName">Rule Name: *</label>
|
||||||
|
<input type="text" class="form-control" id="ruleName" name="rule_name" required placeholder="Enter rule name">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Conditions Section -->
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Conditions:</label>
|
||||||
|
<div class="conditions-container">
|
||||||
|
<div id="conditionsContainer">
|
||||||
|
<!-- Conditions will be added dynamically -->
|
||||||
|
</div>
|
||||||
|
<button type="button" class="btn btn-primary btn-small" onclick="addCondition()">+ Add Condition</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Calculation Section -->
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Calculation:</label>
|
||||||
|
<div class="calculation-section">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="calculationType">Calculation Type:</label>
|
||||||
|
<select class="form-control" id="calculationType" name="calculation_type" onchange="toggleCalculationFields()">
|
||||||
|
<option value="percentage">Percentage</option>
|
||||||
|
<option value="composite">Composite</option>
|
||||||
|
<option value="fixed">Fixed Amount</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="simpleCalculation">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="calculationValue">Value:</label>
|
||||||
|
<input type="number" class="form-control" id="calculationValue" name="calculation_value" step="0.01">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="calculationOn">Applied On:</label>
|
||||||
|
<select class="form-control" id="calculationOn" name="calculation_on">
|
||||||
|
<option value="premium">Premium</option>
|
||||||
|
<option value="net_premium">Net Premium</option>
|
||||||
|
<option value="od_premium">OD Premium</option>
|
||||||
|
<option value="tp_premium">TP Premium</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="compositeCalculation" class="hidden">
|
||||||
|
<div id="componentsContainer">
|
||||||
|
<!-- Composite components will be added here -->
|
||||||
|
</div>
|
||||||
|
<button type="button" class="btn btn-primary btn-small" onclick="addComponent()">+ Add Component</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group" style="display: flex; gap: 10px;">
|
||||||
|
<button type="submit" class="btn btn-success">Save Rule</button>
|
||||||
|
<button type="button" class="btn btn-secondary" onclick="resetForm()">Reset Form</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
let commission_file_id = '<?= $commission_file_id ?>'
|
||||||
|
let rules = '<?= isset($rules) && !empty($rules) ? json_encode($rules) : '' ?>';
|
||||||
|
|
||||||
|
// Field options based on department
|
||||||
|
const departmentFields = JSON.parse('<?= $departmentFields ?>');
|
||||||
|
|
||||||
|
let conditionCount = 0;
|
||||||
|
let componentCount = 0;
|
||||||
|
|
||||||
|
// Initialize the page
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
// loadAllRules();
|
||||||
|
addCondition(); // Add initial condition
|
||||||
|
});
|
||||||
|
|
||||||
|
function addCondition() {
|
||||||
|
conditionCount++;
|
||||||
|
const container = document.getElementById('conditionsContainer');
|
||||||
|
const department = document.getElementById('department').value;
|
||||||
|
|
||||||
|
const conditionDiv = document.createElement('div');
|
||||||
|
conditionDiv.className = 'condition-row';
|
||||||
|
conditionDiv.id = `condition-${conditionCount}`;
|
||||||
|
|
||||||
|
let fieldOptions = '<option value="">Select Field</option>';
|
||||||
|
if (department && departmentFields[department]) {
|
||||||
|
departmentFields[department].forEach(field => {
|
||||||
|
fieldOptions += `<option value="${field}">${field.replace('_', ' ').toUpperCase()}</option>`;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
conditionDiv.innerHTML = `
|
||||||
|
<div>
|
||||||
|
<select class="form-control" name="condition_field[]" required>
|
||||||
|
${fieldOptions}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<select class="form-control" name="condition_operator[]" required>
|
||||||
|
<option value="">Select Operator</option>
|
||||||
|
<option value="==">==(equals)</option>
|
||||||
|
<option value="!=">=!=(not equals)</option>
|
||||||
|
<option value=">">>(greater than)</option>
|
||||||
|
<option value="<"><(less than)</option>
|
||||||
|
<option value=">=">>=(greater than or equal)</option>
|
||||||
|
<option value="<=">>=(less than or equal)</option>
|
||||||
|
<option value="between">between</option>
|
||||||
|
<option value="in">in (array)</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<input type="text" class="form-control" name="condition_value[]" placeholder="Value" required>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button type="button" class="btn btn-danger btn-small" onclick="removeCondition('condition-${conditionCount}')">×</button>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
container.appendChild(conditionDiv);
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeCondition(conditionId) {
|
||||||
|
const element = document.getElementById(conditionId);
|
||||||
|
if (element) {
|
||||||
|
element.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function addComponent() {
|
||||||
|
componentCount++;
|
||||||
|
const container = document.getElementById('componentsContainer');
|
||||||
|
|
||||||
|
const componentDiv = document.createElement('div');
|
||||||
|
componentDiv.className = 'component-row';
|
||||||
|
componentDiv.id = `component-${componentCount}`;
|
||||||
|
|
||||||
|
componentDiv.innerHTML = `
|
||||||
|
<div>
|
||||||
|
<input type="number" class="form-control" name="component_percentage[]" placeholder="Percentage" step="0.01" required>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<select class="form-control" name="component_on[]" required>
|
||||||
|
<option value="premium">Premium</option>
|
||||||
|
<option value="net_premium">Net Premium</option>
|
||||||
|
<option value="od_premium">OD Premium</option>
|
||||||
|
<option value="tp_premium">TP Premium</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label><input type="checkbox" name="only_first_year[]" value="1"> Only First Year</label>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button type="button" class="btn btn-danger btn-small" onclick="removeComponent('component-${componentCount}')">×</button>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
container.appendChild(componentDiv);
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeComponent(componentId) {
|
||||||
|
const element = document.getElementById(componentId);
|
||||||
|
if (element) {
|
||||||
|
element.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleCalculationFields() {
|
||||||
|
const type = document.getElementById('calculationType').value;
|
||||||
|
const simple = document.getElementById('simpleCalculation');
|
||||||
|
const composite = document.getElementById('compositeCalculation');
|
||||||
|
|
||||||
|
if (type === 'composite') {
|
||||||
|
simple.classList.add('hidden');
|
||||||
|
composite.classList.remove('hidden');
|
||||||
|
if (componentCount === 0) {
|
||||||
|
addComponent();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
simple.classList.remove('hidden');
|
||||||
|
composite.classList.add('hidden');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update field options when department changes
|
||||||
|
document.getElementById('department').addEventListener('change', function() {
|
||||||
|
const conditions = document.querySelectorAll('[name="condition_field[]"]');
|
||||||
|
const department = this.value;
|
||||||
|
|
||||||
|
conditions.forEach(select => {
|
||||||
|
const currentValue = select.value;
|
||||||
|
select.innerHTML = '<option value="">Select Field</option>';
|
||||||
|
|
||||||
|
if (department && departmentFields[department]) {
|
||||||
|
departmentFields[department].forEach(field => {
|
||||||
|
const option = document.createElement('option');
|
||||||
|
option.value = field;
|
||||||
|
option.textContent = field.replace('_', ' ').toUpperCase();
|
||||||
|
if (field === currentValue) {
|
||||||
|
option.selected = true;
|
||||||
|
}
|
||||||
|
select.appendChild(option);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Form submission
|
||||||
|
document.getElementById('ruleForm').addEventListener('submit', function(e) {
|
||||||
|
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
const rule_id = document.getElementById('ruleId').value || null;
|
||||||
|
const formData = new FormData(this);
|
||||||
|
const ruleData = {
|
||||||
|
id: document.getElementById('ruleId').value || null,
|
||||||
|
name: formData.get('rule_name'),
|
||||||
|
department: formData.get('department'),
|
||||||
|
conditions: [],
|
||||||
|
calculation: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Process conditions
|
||||||
|
const fields = formData.getAll('condition_field[]');
|
||||||
|
const operators = formData.getAll('condition_operator[]');
|
||||||
|
const values = formData.getAll('condition_value[]');
|
||||||
|
|
||||||
|
for (let i = 0; i < fields.length; i++) {
|
||||||
|
if (fields[i] && operators[i] && values[i]) {
|
||||||
|
let value = values[i];
|
||||||
|
|
||||||
|
// Parse value based on operator
|
||||||
|
if (operators[i] === 'between') {
|
||||||
|
value = value.split(',').map(v => parseFloat(v.trim()));
|
||||||
|
} else if (operators[i] === 'in') {
|
||||||
|
value = value.split(',').map(v => v.trim());
|
||||||
|
} else if (!isNaN(value)) {
|
||||||
|
value = parseFloat(value);
|
||||||
|
} else if (value.toLowerCase() === 'true') {
|
||||||
|
value = true;
|
||||||
|
} else if (value.toLowerCase() === 'false') {
|
||||||
|
value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ruleData.conditions.push({
|
||||||
|
field: fields[i],
|
||||||
|
operator: operators[i],
|
||||||
|
value: value
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process calculation
|
||||||
|
const calculationType = formData.get('calculation_type');
|
||||||
|
if (calculationType === 'composite') {
|
||||||
|
const percentages = formData.getAll('component_percentage[]');
|
||||||
|
const ons = formData.getAll('component_on[]');
|
||||||
|
const firstYears = formData.getAll('only_first_year[]');
|
||||||
|
|
||||||
|
ruleData.calculation = {
|
||||||
|
type: 'composite',
|
||||||
|
components: []
|
||||||
|
};
|
||||||
|
|
||||||
|
for (let i = 0; i < percentages.length; i++) {
|
||||||
|
if (percentages[i] && ons[i]) {
|
||||||
|
const component = {
|
||||||
|
percentage: parseFloat(percentages[i]),
|
||||||
|
on: ons[i]
|
||||||
|
};
|
||||||
|
|
||||||
|
if (firstYears.includes('1')) {
|
||||||
|
component.only_first_year = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ruleData.calculation.components.push(component);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ruleData.calculation = {
|
||||||
|
type: calculationType,
|
||||||
|
value: parseFloat(formData.get('calculation_value')),
|
||||||
|
on: formData.get('calculation_on')
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('', ruleData);
|
||||||
|
console.log(formData.get('calculation_value'));
|
||||||
|
console.log($('#calculation_value').val());
|
||||||
|
console.log(parseFloat(formData.get('calculation_value')));
|
||||||
|
|
||||||
|
let url = '<?= base_url('commission/rules/save') ?>';
|
||||||
|
|
||||||
|
// Data to send in the AJAX request
|
||||||
|
let requestData = {
|
||||||
|
file_id: commission_file_id,
|
||||||
|
rule_id: rule_id,
|
||||||
|
rule_data: ruleData,
|
||||||
|
};
|
||||||
|
|
||||||
|
$('.loader').fadeIn();
|
||||||
|
$('.loader-mask').fadeIn();
|
||||||
|
|
||||||
|
// Send AJAX request
|
||||||
|
sendAjaxRequestForGlobal(url, 'POST', requestData, function(response) {
|
||||||
|
|
||||||
|
console.log('Data fetched successfully:', response);
|
||||||
|
console.log('response.data type', typeof response.data);
|
||||||
|
console.log('rules type', typeof rules);
|
||||||
|
|
||||||
|
if (response.status == true) {
|
||||||
|
toastr.success(response.message, 'SUCCESS');
|
||||||
|
// rules = response.data;
|
||||||
|
displayRules(response.data);
|
||||||
|
}else{
|
||||||
|
toastr.warning(response.message, 'WARNING');
|
||||||
|
}
|
||||||
|
|
||||||
|
$('.loader').fadeOut();
|
||||||
|
$('.loader-mask').delay(350).fadeOut('slow');
|
||||||
|
|
||||||
|
resetForm()
|
||||||
|
$('.close').click();
|
||||||
|
|
||||||
|
}, function(xhr, status, error) {
|
||||||
|
$('.loader').fadeOut();
|
||||||
|
$('.loader-mask').delay(350).fadeOut('slow');
|
||||||
|
console.error('Error fetching data:', error);
|
||||||
|
console.error(xhr.responseText);
|
||||||
|
toastr.error('An error occurred while fetching the data.', 'ERROR');
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
function deleteRule(ruleId, department) {
|
||||||
|
if (confirm('Are you sure you want to delete this rule?')) {
|
||||||
|
fetch('', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded',
|
||||||
|
},
|
||||||
|
body: 'action=delete_rule&rule_id=' + ruleId + '&department=' + department
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
if (data.success) {
|
||||||
|
showAlert('Rule deleted successfully!', 'success');
|
||||||
|
// loadAllRules();
|
||||||
|
} else {
|
||||||
|
showAlert('Error deleting rule: ' + data.message, 'error');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetForm() {
|
||||||
|
document.getElementById('ruleForm').reset();
|
||||||
|
document.getElementById('ruleId').value = '';
|
||||||
|
document.getElementById('conditionsContainer').innerHTML = '';
|
||||||
|
document.getElementById('componentsContainer').innerHTML = '';
|
||||||
|
conditionCount = 0;
|
||||||
|
componentCount = 0;
|
||||||
|
addCondition();
|
||||||
|
toggleCalculationFields();
|
||||||
|
}
|
||||||
|
|
||||||
|
function filterRules() {
|
||||||
|
const department = document.getElementById('filterDepartment').value;
|
||||||
|
|
||||||
|
if (!department) {
|
||||||
|
// loadAllRules();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch('', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded',
|
||||||
|
},
|
||||||
|
body: 'action=get_rules&department=' + department
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(rules => {
|
||||||
|
const rulesWithDept = rules.map(rule => ({...rule, department: department}));
|
||||||
|
displayRules(rulesWithDept);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function showAlert(message, type) {
|
||||||
|
const alertContainer = document.getElementById('alert-container');
|
||||||
|
const alertClass = type === 'success' ? 'alert-success' : 'alert-error';
|
||||||
|
|
||||||
|
alertContainer.innerHTML = `
|
||||||
|
<div class="alert ${alertClass}">
|
||||||
|
${message}
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Remove alert after 5 seconds
|
||||||
|
setTimeout(() => {
|
||||||
|
alertContainer.innerHTML = '';
|
||||||
|
}, 5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
function openModal() {
|
||||||
|
$('#modalTitle').text('Create New Rule');
|
||||||
|
var myModal = new bootstrap.Modal(document.getElementById('ruleModal'));
|
||||||
|
myModal.show();
|
||||||
|
resetForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeModal() {
|
||||||
|
document.getElementById('ruleModal').style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleCalculationFields() {
|
||||||
|
const type = document.getElementById('calculationType').value;
|
||||||
|
const simple = document.getElementById('simpleCalculation');
|
||||||
|
const composite = document.getElementById('compositeCalculation');
|
||||||
|
|
||||||
|
if (type === 'composite') {
|
||||||
|
simple.classList.add('hidden');
|
||||||
|
composite.classList.remove('hidden');
|
||||||
|
} else {
|
||||||
|
simple.classList.remove('hidden');
|
||||||
|
composite.classList.add('hidden');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function editRule(id) {
|
||||||
|
|
||||||
|
// Convert rules JSON to array (ONLY ONCE)
|
||||||
|
if (typeof rules === "string") {
|
||||||
|
rules = JSON.parse(rules);
|
||||||
|
}
|
||||||
|
|
||||||
|
const rule = rules.find(r => r.id == id);
|
||||||
|
if (!rule) return;
|
||||||
|
|
||||||
|
console.log({ rule });
|
||||||
|
|
||||||
|
$('#modalTitle').text('Edit Rule');
|
||||||
|
$('#ruleId').val(rule.id);
|
||||||
|
$('#department').val(rule.department).trigger('change');
|
||||||
|
$('#ruleName').val(rule.name);
|
||||||
|
|
||||||
|
// Clear existing conditions
|
||||||
|
$('#conditionsContainer').html('');
|
||||||
|
conditionCount = 0;
|
||||||
|
|
||||||
|
// Add conditions
|
||||||
|
rule.conditions.forEach(condition => {
|
||||||
|
addCondition();
|
||||||
|
const lastCondition = $('#conditionsContainer .condition-row:last');
|
||||||
|
|
||||||
|
lastCondition.find('[name="condition_field[]"]').val(condition.field);
|
||||||
|
lastCondition.find('[name="condition_operator[]"]').val(condition.operator);
|
||||||
|
lastCondition.find('[name="condition_value[]"]').val(
|
||||||
|
Array.isArray(condition.value) ? condition.value.join(', ') : condition.value
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Set calculation type
|
||||||
|
$('#calculationType').val(rule.calculation.type);
|
||||||
|
toggleCalculationFields();
|
||||||
|
|
||||||
|
// If composite calculation
|
||||||
|
if (rule.calculation.type === 'composite') {
|
||||||
|
|
||||||
|
$('#componentsContainer').html('');
|
||||||
|
componentCount = 0;
|
||||||
|
|
||||||
|
rule.calculation.components.forEach(component => {
|
||||||
|
addComponent();
|
||||||
|
const lastComponent = $('#componentsContainer .component-row:last');
|
||||||
|
|
||||||
|
lastComponent.find('[name="component_percentage[]"]').val(component.percentage);
|
||||||
|
lastComponent.find('[name="component_on[]"]').val(component.on);
|
||||||
|
|
||||||
|
if (component.only_first_year) {
|
||||||
|
lastComponent.find('[name="only_first_year[]"]').prop('checked', true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$('#calculationValue').val(rule.calculation.value);
|
||||||
|
$('#calculationOn').val(rule.calculation.on);
|
||||||
|
}
|
||||||
|
|
||||||
|
var myModal = new bootstrap.Modal(document.getElementById('ruleModal'));
|
||||||
|
myModal.show();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteRule(id) {
|
||||||
|
|
||||||
|
Swal.fire({
|
||||||
|
icon: "warning",
|
||||||
|
title: "Are you sure you want to delete this rule?",
|
||||||
|
showCancelButton: true, // For Cancel
|
||||||
|
confirmButtonText: "Yes",
|
||||||
|
cancelButtonText: "Cancel",
|
||||||
|
confirmButtonColor: "#ff3333"
|
||||||
|
}).then((result) => {
|
||||||
|
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
|
||||||
|
let url = '<?= base_url('commission/rules/remove') ?>';
|
||||||
|
|
||||||
|
// Data to send in the AJAX request
|
||||||
|
let requestData = {
|
||||||
|
file_id: commission_file_id,
|
||||||
|
rule_id: id,
|
||||||
|
is_deleted: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
$('.loader').fadeIn();
|
||||||
|
$('.loader-mask').fadeIn();
|
||||||
|
|
||||||
|
// Send AJAX request
|
||||||
|
sendAjaxRequestForGlobal(url, 'POST', requestData, function(response) {
|
||||||
|
|
||||||
|
console.log('Data fetched successfully:', response);
|
||||||
|
console.log('response.data type', typeof response.data);
|
||||||
|
console.log('rules type', typeof rules);
|
||||||
|
|
||||||
|
if (response.status == true) {
|
||||||
|
toastr.success(response.message, 'SUCCESS');
|
||||||
|
// rules = response.data;
|
||||||
|
displayRules(response.data);
|
||||||
|
}else{
|
||||||
|
toastr.warning(response.message, 'WARNING');
|
||||||
|
}
|
||||||
|
|
||||||
|
$('.loader').fadeOut();
|
||||||
|
$('.loader-mask').delay(350).fadeOut('slow');
|
||||||
|
|
||||||
|
resetForm()
|
||||||
|
$('.close').click();
|
||||||
|
|
||||||
|
}, function(xhr, status, error) {
|
||||||
|
$('.loader').fadeOut();
|
||||||
|
$('.loader-mask').delay(350).fadeOut('slow');
|
||||||
|
console.error('Error fetching data:', error);
|
||||||
|
console.error(xhr.responseText);
|
||||||
|
toastr.error('An error occurred while fetching the data.', 'ERROR');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetForm() {
|
||||||
|
document.getElementById('ruleForm').reset();
|
||||||
|
document.getElementById('ruleId').value = '';
|
||||||
|
document.getElementById('conditionsContainer').innerHTML = '';
|
||||||
|
document.getElementById('componentsContainer').innerHTML = '';
|
||||||
|
document.getElementById('alert-container').innerHTML = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function showAlert(message, type) {
|
||||||
|
const container = document.getElementById('alert-container');
|
||||||
|
container.innerHTML = `<div class="alert alert-${type}">${message}</div>`;
|
||||||
|
setTimeout(() => {
|
||||||
|
container.innerHTML = '';
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function filterRules() {
|
||||||
|
displayRules();
|
||||||
|
}
|
||||||
|
|
||||||
|
function displayRules(sucess_data = null) {
|
||||||
|
|
||||||
|
const filter = document.getElementById('filterDepartment').value;
|
||||||
|
const container = document.getElementById('rulesList');
|
||||||
|
|
||||||
|
let filteredRules = sucess_data ?? rules;
|
||||||
|
console.log('filteredRules', filteredRules);
|
||||||
|
|
||||||
|
if(sucess_data == null){
|
||||||
|
filteredRules = JSON.parse(filteredRules);
|
||||||
|
console.log('filteredRules', filteredRules);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter) {
|
||||||
|
filteredRules = rules.filter(r => r.department === filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filteredRules.length === 0) {
|
||||||
|
container.innerHTML = `
|
||||||
|
<div class="empty-state" style="grid-column: 1/-1;">
|
||||||
|
<h3>📋 No rules found</h3>
|
||||||
|
<p>Create your first rule to get started!</p>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
container.innerHTML = filteredRules.map(rule => {
|
||||||
|
|
||||||
|
// Build condition badges
|
||||||
|
const conditionBadges = rule.conditions
|
||||||
|
.map(c => `<span class="condition-badge">${c.field}</span>`)
|
||||||
|
.join(' ');
|
||||||
|
|
||||||
|
return `
|
||||||
|
<div class="rule-card">
|
||||||
|
<div class="rule-card-header">
|
||||||
|
<div>
|
||||||
|
<div class="rule-name">${rule.name}</div>
|
||||||
|
</div>
|
||||||
|
<span class="department-badge">${rule.department.charAt(0).toUpperCase() + rule.department.slice(1)}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="rule-details">
|
||||||
|
|
||||||
|
<div class="detail-item">
|
||||||
|
<span class="detail-label">Calculation Type:</span> ${rule.calculation.type}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="detail-item">
|
||||||
|
<span class="detail-label">Value:</span> ${rule.calculation.value || "N/A"}${rule.calculation.type === 'percentage' ? '%' : ''}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="detail-item">
|
||||||
|
<span class="detail-label">Applied On:</span> ${rule.calculation.on || 'N/A'}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="detail-item">
|
||||||
|
<span class="detail-label">Conditions:</span> ${rule.conditions.length} condition(s)
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
${conditionBadges}
|
||||||
|
|
||||||
|
${rule.is_deleted
|
||||||
|
? `<div class="rule-actions">
|
||||||
|
<button class="btn btn-danger btn-small" disabled>Deleted</button>
|
||||||
|
</div>`
|
||||||
|
: `<div class="rule-actions">
|
||||||
|
<button class="btn btn-primary btn-small" onclick="editRule('${rule.id}')">
|
||||||
|
<i class="mdi mdi-pencil"></i>
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-danger btn-small" onclick="deleteRule('${rule.id}')">
|
||||||
|
<i class="mdi mdi-delete"></i>
|
||||||
|
</button>
|
||||||
|
</div>`
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
}).join('');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initial display
|
||||||
|
displayRules();
|
||||||
|
</script>
|
||||||
|
|
||||||
Loading…
Reference in New Issue
Block a user