From f6c40db6b5cb257c1cf64c243ae288df9bf0062c Mon Sep 17 00:00:00 2001 From: "venkatesh.r" Date: Thu, 13 Nov 2025 16:24:48 +0530 Subject: [PATCH 01/17] FIX_HR_ACCESS_POLICY_LIST --- app/Views/hr_access_controll.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Views/hr_access_controll.php b/app/Views/hr_access_controll.php index f845b288..f2d69989 100644 --- a/app/Views/hr_access_controll.php +++ b/app/Views/hr_access_controll.php @@ -144,7 +144,7 @@ // $listed_pre[] = $policies['branch_id'].'-'.$policies['policy_no']; // } - if($value['pre_branch_id'] !== $policies['branch_id']){ + if(empty($value['pre_hr_id']) || $value['pre_branch_id'] !== $policies['branch_id']){ continue; } ?> @@ -212,7 +212,7 @@ // $listed_post[] = $policies['branch_id'].'-'.$policies['policy_no']; // } - if($value['post_branch_id'] !== $policies['branch_id']){ + if(empty($value['post_hr_id']) || $value['post_branch_id'] !== $policies['branch_id']){ continue; } From b24dd840267f824414994b328df74c4bccc2840d Mon Sep 17 00:00:00 2001 From: "venkatesh.r" Date: Thu, 13 Nov 2025 16:27:27 +0530 Subject: [PATCH 02/17] FIX_ALL_EVENT_EROR_ISSUE --- app/Controllers/EmployeeServiceController.php | 4 ++-- app/Views/employee_upload.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/Controllers/EmployeeServiceController.php b/app/Controllers/EmployeeServiceController.php index 4b71694c..690e9c08 100755 --- a/app/Controllers/EmployeeServiceController.php +++ b/app/Controllers/EmployeeServiceController.php @@ -2471,7 +2471,7 @@ class EmployeeServiceController extends AdminController $member_data_count = count($member_data); if ($inception_data_count !== $member_data_count) { - $result['error_summary'][] = 15; + $result['error_summary'][] = 101; $result['error_message'] = " Inception Data Count: {$inception_data_count}   @@ -2504,7 +2504,7 @@ class EmployeeServiceController extends AdminController } if (!$match_found) { - array_push($result['error_summary'], 14); + array_push($result['error_summary'], 100); $result['error_data'][$inception_key]['sno']['error'][] = "This inception row was not found in the member data list."; } } diff --git a/app/Views/employee_upload.php b/app/Views/employee_upload.php index 8a4e1c13..94e6b240 100755 --- a/app/Views/employee_upload.php +++ b/app/Views/employee_upload.php @@ -548,14 +548,14 @@ function fetchFileError(file_id) { "Rule conflict: Twofold relationship found within family " + err_count + ""; break; - case 14: + case 100: hasError14 = true; error_code = 14; file_error_html += "This inception row was not found in the member data list. " + err_count + ""; break; - case 15: + case 101: hasError15 = true; error_code = 15; file_error_html += From 15256892ba18258a4588de43f5c81a08cb051ae3 Mon Sep 17 00:00:00 2001 From: "venkatesh.r" Date: Fri, 14 Nov 2025 09:47:46 +0530 Subject: [PATCH 03/17] FIX_CLAIM_EMP_FILTER --- app/Views/ticket_form_gmc.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/Views/ticket_form_gmc.php b/app/Views/ticket_form_gmc.php index 095e8de7..02f9dfb6 100644 --- a/app/Views/ticket_form_gmc.php +++ b/app/Views/ticket_form_gmc.php @@ -948,16 +948,21 @@ }) function getClientPolicy() { + console.log("get policy function called"); hiddenData = $("#empIDHidden").val(); hiddenData = JSON.parse(hiddenData); console.log('employee id ', hiddenData['emp_id']); let ticket_type_id = $('#ticket_type_id').val(); - console.log("ticket_type_id", ticket_type_id); + let client_id = $('#mobile_emp_client_data_list').val(); + console.log({ticket_type_id, client_id}); + data = { emp_id: hiddenData['emp_id'], ticket_type_id: ticket_type_id, + client_id: client_id, } + $.ajax({ url: '', type: "POST", From dd9a3f1dca4f77233056aac8173c24b90dd25541 Mon Sep 17 00:00:00 2001 From: "venkatesh.r" Date: Fri, 14 Nov 2025 09:48:24 +0530 Subject: [PATCH 04/17] FIX_CLAIM_EMP_FILTER --- app/Controllers/TicketController.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/Controllers/TicketController.php b/app/Controllers/TicketController.php index c8adbcbb..6219326a 100644 --- a/app/Controllers/TicketController.php +++ b/app/Controllers/TicketController.php @@ -2011,6 +2011,7 @@ class TicketController extends BaseController { $received_data = $this->request->getPost(); $ticket_type_id = $this->request->getPost('ticket_type_id') ?? null; + $client_id = $this->request->getPost('client_id') ?? null; $emp_id = $received_data['emp_id']; // Get all client policy IDs for the given employee @@ -2027,6 +2028,9 @@ class TicketController extends BaseController $builder->where('e.is_active', 1); $builder->where('ep.is_active', 1); $builder->where('e.emp_code', $self_data['emp_code']); + if(!empty($client_id)){ + $builder->where('e.client_id', $client_id); + } $builder->groupBy('client_policy_id'); $query = $builder->get(); From 1096511b1ab78e63fa11ed75999cc59734616fb7 Mon Sep 17 00:00:00 2001 From: "venkatesh.r" Date: Fri, 14 Nov 2025 12:13:58 +0530 Subject: [PATCH 05/17] CHANGE_EMP_CLAIM_STATUS_AND_HISTORY --- app/Controllers/EmployeeRestController.php | 62 +++++++++++++++++++--- 1 file changed, 54 insertions(+), 8 deletions(-) diff --git a/app/Controllers/EmployeeRestController.php b/app/Controllers/EmployeeRestController.php index a77a10cb..0daa1d6b 100755 --- a/app/Controllers/EmployeeRestController.php +++ b/app/Controllers/EmployeeRestController.php @@ -2626,19 +2626,34 @@ class EmployeeRestController extends AdminController $data['ticket_history'] = $ticketController->ticketHistory($ticket_id); $data['claims_data'] = $this->ticketMaster->getTicketDataByTicketID($ticket_id); $data['ticket_data'] = $ticketController->getMoreInfo($requestFrom = 'rest', $ticket_id); + $status_list = [ + "DENIAL REVIEW AWAITED" => 'Denial Review Awaited', + "UNDER PROCESS - TPA" => 'Under Process', + "SETTLED" => 'Settled', + "PAYMENT INITIATED" => 'Under Process', + "APPROVED" => 'Approved', + "REJECTED" => 'Rejected', + "UNDER PROCESS - QUERY DOCUMENT RECEIVED" => 'Under Process', + "UNDER PROCESS - CLAIM NO. UPDATION" => 'Under Process' , + "INFORMATION REQUIRED" => 'Information Required', + "CDA" => 'Claim Received', + "ID NOT GENERATED" => 'Claim Received', + "NON ID" => 'Claim Received' + ]; - // $data = $response['data']; // Assuming your full array is stored in $response // $ticketData = $data['ticket_data']; // $ticketHistory = $data['ticket_history']; + $data['ticket_data'] = array_fill_keys(array_keys($data['ticket_data']), []); // Loop through ticket_data foreach ($data['ticket_data'] as $status => &$fields) { // Search ticket_history for matching old_status_value foreach ($data['ticket_history'] as $history) { + if ($history['old_status_value'] === $status) { // Attach modified_by and created_at - $fields['modified_by'] = $history['modified_by']; + // $fields['modified_by'] = $history['modified_by']; $fields['modified_at'] = date('d-m-Y h:i A', strtotime($history['created_at'])); // Break after first match (assuming latest entry is enough) break; @@ -2646,6 +2661,25 @@ class EmployeeRestController extends AdminController } } + $new_ticket_data = []; + + foreach ($data['ticket_data'] as $oldKey => $value) { + + // Only process if key exists in status_list + if (!isset($status_list[$oldKey])) { + continue; // skip and do NOT add to new array + } + + // Get new key based on mapping + $newKey = $status_list[$oldKey]; + + // Avoid duplicates + if (!isset($new_ticket_data[$newKey])) { + $new_ticket_data[$newKey] = $value; + } + } + + $data['ticket_data'] = $new_ticket_data; $ticketMesssageModel = new TicketMessageModel(); $ticket_message = $ticketMesssageModel @@ -3818,16 +3852,27 @@ class EmployeeRestController extends AdminController if (!empty($ticket_data)) { + // $client_claim_status = [ + // 'Received' => [1, 2, 3, 4, 15, 16, 17, 18, 25, 26, 27, 28, 35, 36, 37, 38], + // 'Rejected' => [8, 49, 55, 60], + // 'Cancelled' => [13, 47, 53, 58], + // 'Returned' => [14, 48, 54, 59], + // 'Closed' => [12, 22, 32, 42], + // 'Approved' => [9, 20, 30, 40], + // 'Settled' => [11, 24, 34], + // 'Under Process' => [5, 6, 7, 10, 19, 23, 45, 50, 29, 33, 51, 39, 43, 56], + // ]; + $client_claim_status = [ - 'Received' => [1, 2, 3, 4, 15, 16, 17, 18, 25, 26, 27, 28, 35, 36, 37, 38], - 'Rejected' => [8, 49, 55, 60], - 'Cancelled' => [13, 47, 53, 58], - 'Returned' => [14, 48, 54, 59], - 'Closed' => [12, 22, 32, 42], + 'Claim Received' => [1, 2, 3, 15, 16, 17, 18, 25, 26, 27, 28, 35, 36, 37, 38], + 'Under Process' => [5, 6, 7, 10, 19, 23, 45, 50, 29, 33, 51, 39, 43, 56], + 'Information Required' => [ 4 ], 'Approved' => [9, 20, 30, 40], 'Settled' => [11, 24, 34], - 'Under Process' => [5, 6, 7, 10, 19, 23, 45, 50, 29, 33, 51, 39, 43, 56], + 'Denial Review Awaited' => [66], + 'Rejected' => [8, 49, 55, 60], ]; + foreach ($data['ticket_data'] as $status => &$fields) { foreach ($ticket_data as $key => $value) { @@ -3836,6 +3881,7 @@ class EmployeeRestController extends AdminController $ticket_data[$key]['claim_status'] = $claim_key ?? null; // Assign back to the main array } } + $ticket_data[$key]['priority_type'] = $priorityType[$value['priority']] ?? null; $ticket_data[$key]['mode_of_intimate_type'] = $modeOFIntimate[$value['mode_of_intimation']] ?? null; $ticket_data[$key]['relationship_type'] = ucfirst($value['relationship']) ?? null; From 20e6cabf3a467225c61050e9be2973b76ea727b4 Mon Sep 17 00:00:00 2001 From: "venkatesh.r" Date: Fri, 14 Nov 2025 12:22:58 +0530 Subject: [PATCH 06/17] FIX_ISSUE --- app/Controllers/EmployeeRestController.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/Controllers/EmployeeRestController.php b/app/Controllers/EmployeeRestController.php index 0daa1d6b..0013f928 100755 --- a/app/Controllers/EmployeeRestController.php +++ b/app/Controllers/EmployeeRestController.php @@ -3872,7 +3872,6 @@ class EmployeeRestController extends AdminController 'Denial Review Awaited' => [66], 'Rejected' => [8, 49, 55, 60], ]; - foreach ($data['ticket_data'] as $status => &$fields) { foreach ($ticket_data as $key => $value) { From 3fcb6bdee523843ee886b71ecfbdc7a70eba0012 Mon Sep 17 00:00:00 2001 From: venba-Inspriron-3558 Date: Fri, 14 Nov 2025 12:43:13 +0530 Subject: [PATCH 07/17] TEST_new menu payouts --- app/Config/Routes.php | 1 + app/Controllers/PolicyTransactionController.php | 14 ++++++++++++++ app/Views/layout/header.php | 6 ++++++ app/Views/policy_transaction_payouts.php | 0 4 files changed, 21 insertions(+) create mode 100644 app/Views/policy_transaction_payouts.php diff --git a/app/Config/Routes.php b/app/Config/Routes.php index efec8a5d..7c7ba864 100755 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -478,6 +478,7 @@ $routes->group("rfq", ["filter" => "authMVC"], function ($routes) { $routes->get("driveListFiles", "GoogleDriveController::listFiles"); $routes->post('dmsSearch', 'PolicyTransactionController::dmsSearch', ['filter' => 'authMVC']); $routes->get('dmsSearch', 'PolicyTransactionController::dmsSearch', ['filter' => 'authMVC']); +$routes->get('payouts', 'PolicyTransactionController::payouts', ['filter' => 'authMVC']); $routes->get('downloadGdriveFile', 'GoogleDriveController::downloadGdriveFile', ['filter' => 'authMVC']); $routes->get('cli/sendZeptoMail', 'MasterController::testZeptoSMTP'); diff --git a/app/Controllers/PolicyTransactionController.php b/app/Controllers/PolicyTransactionController.php index a2f88d5f..8d24f27b 100644 --- a/app/Controllers/PolicyTransactionController.php +++ b/app/Controllers/PolicyTransactionController.php @@ -2811,6 +2811,20 @@ $this->loadLayout('dms_search', $data); } + public function payouts() + { + + $data['tab_name'] = 'Payouts'; + $data['page_name'] = 'Payouts'; + $data['payouts'] = []; + $data['agents'] = [ 1 => "Agent 1", 2 => "Agent 2", 3 => "Agent 3", 4 => "Agent 4", 5 => "Agent 5", 6 => "Agent 6", 7 => "Agent 7", 8 => "Agent 8"]; + $data['brokers'] = []; + + if ($this->request->is('post')) {} + if ($this->request->is('get')) {} + + $this->loadLayout('policy_transaction_payouts', $data); + } //--------------------------------------------------------------------------------------------------- public function getCoShareStatementDetails($pt_id) diff --git a/app/Views/layout/header.php b/app/Views/layout/header.php index d81c7f68..8fd011b7 100755 --- a/app/Views/layout/header.php +++ b/app/Views/layout/header.php @@ -2017,6 +2017,12 @@ +
  • + + + Payouts + +
  • diff --git a/app/Views/policy_transaction_payouts.php b/app/Views/policy_transaction_payouts.php new file mode 100644 index 00000000..e69de29b From fbd532258d61b516e467f2c0bd5e8a19813197f5 Mon Sep 17 00:00:00 2001 From: velz Date: Fri, 14 Nov 2025 15:30:23 +0530 Subject: [PATCH 08/17] FEAT_COMMISSION_CALC --- app/Config/Filters.php | 4 +- app/Config/Routes.php | 1 + .../InsuranceCommissionController.php | 274 ++++++++++++++++++ app/Controllers/MasterController.php | 3 + app/Filters/CommissionApiFilter.php | 55 ++++ 5 files changed, 336 insertions(+), 1 deletion(-) create mode 100644 app/Controllers/InsuranceCommissionController.php create mode 100644 app/Filters/CommissionApiFilter.php diff --git a/app/Config/Filters.php b/app/Config/Filters.php index 2cf9a260..00faa273 100755 --- a/app/Config/Filters.php +++ b/app/Config/Filters.php @@ -13,6 +13,7 @@ use App\Filters\AuthMVC; use App\Filters\HttpRequestLog; use App\Filters\CloseDbConnection; use App\Filters\AuthClientApi; +use App\Filters\CommissionApiFilter; use App\Filters\AuthJWT; @@ -36,7 +37,8 @@ class Filters extends BaseConfig 'HttpRequestLog' => HttpRequestLog::class, 'authJWT' => AuthJWT::class, 'AuthClientApi' => AuthClientApi::class, - 'CloseDbConnection' => CloseDbConnection::class + 'CloseDbConnection' => CloseDbConnection::class, + 'CommissionApiFilter' => CommissionApiFilter::class ]; /** diff --git a/app/Config/Routes.php b/app/Config/Routes.php index ad1d3874..7b5a1fca 100755 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -34,6 +34,7 @@ $routes->get("updateRenewalData", "ClientController::updateRenewalData"); $routes->get("updateRenewalDataNotExistingClient", "ClientController::updateRenewalDataNotExistingClient"); $routes->get("updateRenewalInsurerData", "ClientController::updateRenewalInsurerData"); $routes->get("sendMutipleToEmails", "MasterController::sendMutipleToEmails"); +$routes->post("getCommission", "InsuranceCommissionController::initiateCommissionCalc",['filter' => 'CommissionApiFilter']); // $routes->post("iAgreeForAddOn", "EmployeeRestController::iAgreeForAddOn"); // $routes->get("sendCroneRemainderMail", "DashboardController::sendCroneRemainderMail"); // $routes->post("employeeUpload", "EmployeeRestController::employeeUpload"); diff --git a/app/Controllers/InsuranceCommissionController.php b/app/Controllers/InsuranceCommissionController.php new file mode 100644 index 00000000..11f61daa --- /dev/null +++ b/app/Controllers/InsuranceCommissionController.php @@ -0,0 +1,274 @@ +myLogger = \Config\Services::mylogger(); + // Load rules file if present in writable config path + // $rulesPath = WRITEPATH . 'config/insurance_rules.json'; + // if (file_exists($rulesPath)) { + // $this->loadRulesFromFile($rulesPath); + // } + } + + /** + * POST /insurance/calculate + * Accepts JSON body with policy data and returns commission calculation + */ + public function initiateCommissionCalc() + { + // Accept POST params (JSON, form-data, x-www-form-urlencoded) + $input = $this->request->getPost(); + + if (empty($input)) { + $json = $this->request->getJSON(true); + if ($json) { + $input = $json; + } + } + + if (empty($input)) { + return $this->failValidationError('No input data received'); + } + // -------- Required Params Check -------- + if (empty($input['policy_issue_date'])) { + return $this->failValidationError('policy_issue_date is required'); + } + + if (empty($input['department'])) { + return $this->failValidationError('department is required'); + } + + if (empty($input['insurer_id'])) { + return $this->failValidationError('insurer_id is required'); + } + + + // -------- Build Dynamic Rules Path -------- + $policyDate = strtotime($input['policy_issue_date']); + if (!$policyDate) { + return $this->failValidationError('Invalid policy_issue_date'); + } + + $month = strtoupper(date('M', $policyDate)); // SEP + $year = date('Y', $policyDate); // 2025 + $folderName = $month . $year; // SEP2025 + + $insurerId = $input['insurer_id']; // 5 + $department = ucfirst(strtolower($input['department'])); // Motor, Health, Fire + + // Final Path: WRITEPATH/rules/SEP2025/5_Motor.json + $rulesPath = WRITEPATH . "uploads/commission/rules/{$folderName}/{$insurerId}_{$department}.json"; + // echo $rulesPath;die(); + + if (!file_exists($rulesPath)) { + return $this->fail("Rules file not found at: {$rulesPath}"); + } + + // Load the dynamic rule set + $this->loadRulesFromFile($rulesPath); + + // -------- Execute Rule Matching & Commission Calculation -------- + try { + $result = $this->calculateCommission($input); + + $comment = isset($result['rule']['name']) + ? "Matched rule: " . $result['rule']['name'] + : "Matched rule: (unnamed rule)"; + + return $this->respond([ + 'success' => true, + 'data' => [ + 'payout' => $result['payout'], + 'rule' => $result['rule'], + 'comment' => $comment, + // 'rules_path_used' => $rulesPath + ] + ]); + + } catch (\Exception $e) { + return $this->fail($e->getMessage()); + } + } + + + /** + * Load rules JSON and normalise department keys to lowercase for lookups + */ + private function loadRulesFromFile(string $filePath) + { + if (!file_exists($filePath)) { + throw new \Exception("Rules file not found: {$filePath}"); + } + + $json = file_get_contents($filePath); + $parsed = json_decode($json, true); + + if (json_last_error() !== JSON_ERROR_NONE) { + throw new \Exception('Invalid JSON in rules file: ' . json_last_error_msg()); + } + + // Normalise department keys to lowercase for consistent lookups + $this->rules = []; + foreach ($parsed as $dept => $rules) { + $this->rules[strtolower($dept)] = $rules; + } + } + + public function calculateCommission(array $policyData) + { + $department = $policyData['department'] ?? ''; + $deptKey = strtolower($department); + + if (!isset($this->rules[$deptKey])) { + throw new \Exception("No rules found for department: {$department}"); + } + + $matchingRules = []; + + foreach ($this->rules[$deptKey] as $rule) { + if ($this->evaluateConditions($rule['conditions'] ?? [], $policyData)) { + $matchingRules[] = $rule; + } + } + + if (empty($matchingRules)) { + throw new \Exception('No matching rules found for the policy data'); + } + + // Use the first matching rule. In future you can implement priority/weighting + $applicableRule = $matchingRules[0]; + + $payout = $this->applyCalculation($applicableRule['calculation'], $policyData); + + return ['rule' => $applicableRule, 'payout' => $payout]; + } + + private function evaluateConditions(array $conditions, array $data): bool + { + foreach ($conditions as $condition) { + $field = $condition['field']; + $operator = $condition['operator']; + $expectedValue = $condition['value']; + + if (!array_key_exists($field, $data)) { + return false; + } + + $actualValue = $data[$field]; + + if (!$this->compareValues($actualValue, $operator, $expectedValue)) { + return false; + } + } + + return true; + } + + private function compareValues($actual, string $operator, $expected): bool + { + switch ($operator) { + case '==': + return $actual == $expected; + case '!=': + return $actual != $expected; + case '>': + return $actual > $expected; + case '>=': + return $actual >= $expected; + case '<': + return $actual < $expected; + case '<=': + return $actual <= $expected; + case 'between': + return is_array($expected) && $actual >= $expected[0] && $actual <= $expected[1]; + case 'in': + return is_array($expected) && in_array($actual, $expected); + default: + throw new \Exception("Unsupported operator: {$operator}"); + } + } + + private function applyCalculation(array $calculation, array $policyData) + { + $type = $calculation['type'] ?? null; + + switch ($type) { + case 'percentage': + $percentage = $calculation['value'] ?? 0; + $base = $calculation['on'] ?? null; + + if ($base === null || !isset($policyData[$base])) { + throw new \Exception("Base value for calculation not found: {$base}"); + } + + return ($percentage / 100) * $policyData[$base]; + + case 'composite': + $total = 0; + + foreach ($calculation['components'] as $component) { + $percentage = $component['percentage'] ?? 0; + $base = $component['on'] ?? null; + + if ($base === null || !isset($policyData[$base])) { + throw new \Exception("Base value for calculation not found: {$base}"); + } + + if (!empty($component['only_first_year'])) { + if (!empty($policyData['is_renewal'])) { + continue; // Skip this component for renewals + } + } + + $total += ($percentage / 100) * $policyData[$base]; + } + + return $total; + + case 'fixed': + $fixedAmount = $calculation['value'] ?? 0; + + // If 'on' specified but not needed, return fixed amount as-is + return $fixedAmount; + + default: + throw new \Exception('Unsupported calculation type: ' . $type); + } + } + + public function getVolumeReward(array $premiumData) + { + $annualPremium = $premiumData['annual_premium'] ?? 0; + $department = $premiumData['department'] ?? ''; + + if ($department === 'Fire' || $department === 'Marine' || $department === 'Engineering') { + if ($annualPremium > 20000000) { + return 0.01 * $annualPremium; + } elseif ($annualPremium > 10000000) { + return 0.005 * $annualPremium; + } elseif ($annualPremium > 5000000) { + return 0.0025 * $annualPremium; + } + } elseif ($department === 'Motor') { + if ($annualPremium > 15000000) { + return 0.02 * $annualPremium; + } elseif ($annualPremium > 7500000) { + return 0.01 * $annualPremium; + } + } + + return 0; + } +} diff --git a/app/Controllers/MasterController.php b/app/Controllers/MasterController.php index 76bd1a5a..d2ce1329 100755 --- a/app/Controllers/MasterController.php +++ b/app/Controllers/MasterController.php @@ -1976,6 +1976,9 @@ class MasterController extends AdminController 'lead_files' => WRITEPATH . 'uploads/lead_files/', 'claim_files' => WRITEPATH . 'uploads/claim_files/', 'claim_dump_excel' => WRITEPATH . 'uploads/claim_dump_excel/', + 'commission' => WRITEPATH . 'uploads/commission/', + 'files' => WRITEPATH . 'uploads/commission/files', + 'rules' => WRITEPATH . 'uploads/commission/rules', 'claim_sample_forms' => ROOTPATH . 'public/claim_sample_forms/', ]; diff --git a/app/Filters/CommissionApiFilter.php b/app/Filters/CommissionApiFilter.php new file mode 100644 index 00000000..d7ae956e --- /dev/null +++ b/app/Filters/CommissionApiFilter.php @@ -0,0 +1,55 @@ +getHeaderLine('X'); + $authHeader = $_SERVER['REDIRECT_HTTP_AUTHORIZATION']; + // echo $authHeader;die(); + if (empty($authHeader)) { + return service('response')->setJSON([ + 'success' => false, + 'error' => 'Authorization header missing' + ])->setStatusCode(403); + } + + // Expected format: Bearer YOUR_API_KEY + if (stripos($authHeader, 'Bearer ') !== 0) { + return service('response')->setJSON([ + 'success' => false, + 'error' => 'Invalid Authorization format. Expected: Bearer ' + ])->setStatusCode(403); + } + + $apiKey = trim(substr($authHeader, 7)); // extract token after 'Bearer ' + + $envKeys = getenv('ALLOWED_COMMISSION_API_KEYS'); + // Convert CSV -> Array + $allowedKeys = array_map('trim', explode(',', $envKeys)); + // print_r($allowedKeys);die(); + // Validate + if (!in_array($apiKey, $allowedKeys, true)) { + return service('response')->setJSON([ + 'success' => false, + 'error' => 'Invalid API Key' + ])->setStatusCode(403); + } + + // Allow request to proceed + return null; + } + + public function after(RequestInterface $request, ResponseInterface $response, $arguments = null) + { + // Not needed + } +} From d27a892ce815fa146267c7b6d86a6edd5220240b Mon Sep 17 00:00:00 2001 From: "venkatesh.r" Date: Sat, 15 Nov 2025 09:34:35 +0530 Subject: [PATCH 09/17] FEAT_PAYOUT --- app/Controllers/PayoutController.php | 113 ++++++++++++++++++++++++++ app/Models/InvoiceItemModel.php | 41 ++++++++++ app/Models/InvoiceModel.php | 117 +++++++++++++++++++++++++++ app/Models/InvoiceUtrModel.php | 39 +++++++++ 4 files changed, 310 insertions(+) create mode 100644 app/Controllers/PayoutController.php create mode 100644 app/Models/InvoiceItemModel.php create mode 100644 app/Models/InvoiceModel.php create mode 100644 app/Models/InvoiceUtrModel.php diff --git a/app/Controllers/PayoutController.php b/app/Controllers/PayoutController.php new file mode 100644 index 00000000..7b798537 --- /dev/null +++ b/app/Controllers/PayoutController.php @@ -0,0 +1,113 @@ +myLogger = \Config\Services::mylogger(); + + $this->payout_status = [ + 1 => "Draft", + 2 => "Pending", + 3 => "Complete", + ]; + + $this->invoiceItemModel = new InvoiceItemModel(); + $this->invoiceModel = new InvoiceModel(); + $this->invoiceUtrModel = new InvoiceUtrModel(); + $this->policyTransactionModel = new PolicyTransactionModel(); + } + + public function payoutList() + { + // for filtering list + if($this->request->is('post')){ + try{ + $data = $this->request->getPost(); + // print_r($data); die; + + $agent_id = $data['agent_id'] ?? null; + $status_id = $data['status_id'] ?? null; + $start_date = $data['start_date'] ?? null; + $end_date = $data['end_date'] ?? null; + + $payout_data = $this->invoiceModel->invoiceList($this->payout_status, $agent_id, $status_id, $start_date, $end_date); + + $payout_data['payout_list_data'] = $payout_data; + $payout_data = view('payout_list', $payout_data); + + if(!empty($payout_data)){ + return $this->respond(['status' => true, 'code' => 200, 'data' => $payout_data], 200); + }else{ + return $this->respond(['status' => false, 'code' => 400, 'data' => $payout_data, "message" => "No data found"], 200); + } + }catch (\Throwable $th) { + + $this->myLogger->logme("error", "PayoutController - payoutList: Exception: " . $th->getMessage() . " --- Line: " . $th->getLine() . " --- Trace: " . $th->getTraceAsString()); + $errorData = [ + 'message' => $th->getMessage(), + 'file' => $th->getFile(), + 'line' => $th->getLine(), + 'code' => $th->getCode(), + 'trace' => $th->getTraceAsString(), + 'trace_array' => $th->getTrace(), // full array version (optional) + 'function' => $th->getTrace()[0]['function'] ?? null, + 'class' => $th->getTrace()[0]['class'] ?? null, + ]; + $payout_data = view('payout_list'); + return $this->respond(['status' => false, 'code' => 500, 'data' => $payout_data, "message" => "No data found", 'error_data' => $errorData], 500); + } + } + + // for list + $data['payout_status'] = $this->payout_status; + $data['agent_list'] = $this->invoiceModel->agentList(); + $payout_data['payout_list_data'] = $this->invoiceModel->invoiceList($this->payout_status); + $data['payout_list'] = view('payout_list', $payout_data); + + // dd($data); + return $this->loadLayout('payout_list_handler', $data); + } + + public function fetchUtrDetails() + { + $invoice_id = $this->request->getPost('invoice_id') ?? null; + + $payout_data = $this->invoiceModel->invoiceList(); + + $data['utr_data'] = $payout_data; + $payout_data = view('partner_utr_details', $data); + + if(!empty($payout_data)){ + return $this->respond(['status' => true, 'code' => 200, 'data' => $payout_data], 200); + }else{ + return $this->respond(['status' => false, 'code' => 400, 'data' => $payout_data, "message" => "No data found"], 200); + } + } + + public function saveUtrDetails() + { + $data = $this->request->getPost(); + } + + +} diff --git a/app/Models/InvoiceItemModel.php b/app/Models/InvoiceItemModel.php new file mode 100644 index 00000000..328be1d9 --- /dev/null +++ b/app/Models/InvoiceItemModel.php @@ -0,0 +1,41 @@ + 'required|integer', + 'policy_id' => 'required|integer', + 'policy_no' => 'required|max_length[100]', + 'commission_amount' => 'decimal' + ]; + + protected $validationMessages = []; + protected $skipValidation = false; +} diff --git a/app/Models/InvoiceModel.php b/app/Models/InvoiceModel.php new file mode 100644 index 00000000..2a3b71e0 --- /dev/null +++ b/app/Models/InvoiceModel.php @@ -0,0 +1,117 @@ + 'required|max_length[100]', + 'invoice_amount' => 'decimal', + 'agent_id' => 'required|integer', + 'invoice_date' => 'required|valid_date', + ]; + + protected $validationMessages = []; + protected $skipValidation = false; + + + public function invoiceList($status = [], $agent_id = null, $status_id = null, $start_date = null, $end_date = null) + { + $data = $this->select(" + partner_invoice.*, + + -- Total UTR Amount + (SELECT SUM(piu.amount) + FROM partner_invoice_utr piu + WHERE piu.invoice_id = partner_invoice.id + AND piu.is_active = 1 + ) AS total_utr_amount, + + -- Balance Amount + (partner_invoice.invoice_amount - + IFNULL( + (SELECT SUM(piu2.amount) + FROM partner_invoice_utr piu2 + WHERE piu2.invoice_id = partner_invoice.id + AND piu2.is_active = 1 + ), + 0) + ) AS balance_amount, + + -- Payout status + CASE + WHEN payout_status = 1 THEN 'Draft' + WHEN payout_status = 2 THEN 'Pending' + WHEN payout_status = 3 THEN 'Complete' + END AS status_text, + + partner_agent.name as agent_name + ") + ->join('partner_agent', 'partner_invoice.agent_id = partner_agent.id') + ->where('partner_invoice.is_active', 1); + + if(!empty($agent_id)){ + $data->where('partner_invoice.agent_id', $agent_id); + } + + if(!empty($status_id)){ + $data->where('partner_invoice.payout_status', $status_id); + } + + if (!empty($start_date) && !empty($end_date)) { + + $startDate = date('Y-m-d 00:00:00', strtotime($start_date)); + $endDate = date('Y-m-d 23:59:59', strtotime($end_date)); + + $data->where('partner_invoice.invoice_date >=', $startDate) + ->where('partner_invoice.invoice_date <=', $endDate); + } + + if(!empty($agent_id) && !empty($status_id) && !empty($start_date) && !empty($end_date)){ + + $fromDate = date('Y-m-d', strtotime('-60 days')); + $toDate = date('Y-m-d 23:59:59'); + + $data->where('partner_invoice.created_at >=', $fromDate) + ->where('partner_invoice.created_at <=', $toDate); + + } + + $return_data = $data->orderBy('partner_invoice.id','desc')->findAll(); + + // print_r($this->db->getLastQuery()); die; + + return $return_data; + } + + public function agentList(){ + return $this->db->table('partner_agent')->where('is_active', 1)->get()->getResultArray(); + } +} diff --git a/app/Models/InvoiceUtrModel.php b/app/Models/InvoiceUtrModel.php new file mode 100644 index 00000000..9f0c44c4 --- /dev/null +++ b/app/Models/InvoiceUtrModel.php @@ -0,0 +1,39 @@ + 'required|integer', + 'utr_no' => 'required|max_length[100]', + 'amount' => 'decimal' + ]; + + protected $validationMessages = []; + protected $skipValidation = false; +} From 2bf53a61da1c72b84ea4abb4214ae2d22f12b988 Mon Sep 17 00:00:00 2001 From: "venkatesh.r" Date: Sat, 15 Nov 2025 09:35:17 +0530 Subject: [PATCH 10/17] CHANGE_ROUTE --- app/Config/Routes.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/Config/Routes.php b/app/Config/Routes.php index 7c7ba864..c089cd4e 100755 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -737,7 +737,6 @@ $routes->get('testTracelog','TestBusinessController::a'); $routes->get("claimView", "EmployeeRestController::claimView"); // General Tickets - $routes->post("ticketSave", "ThzController::ticketSave"); $routes->get("ticketList", "ThzController::ticketList"); $routes->post("ticketConversationSave", "ThzController::ticketConversationSave"); @@ -767,3 +766,10 @@ $routes->group('test', function($routes) { }); $routes->cli('cli/testcli', 'TestingController::testcli'); +//PARTNER PAYOUT +$routes->group('payout', function($routes) { + $routes->match (['get','post'],'list',"PayoutController::payoutList"); + $routes->post('fetchUtrDetails',"PayoutController::fetchUtrDetails"); + $routes->post('saveUtrDetails',"PayoutController::saveUtrDetails"); +}); + From 16135992fa8d8d628aa6fc6673de43edefe03274 Mon Sep 17 00:00:00 2001 From: "venkatesh.r" Date: Sat, 15 Nov 2025 10:49:27 +0530 Subject: [PATCH 11/17] FEAT_PAYOUT_VIEWS --- app/Views/payout_list.php | 318 ++++++++++++++++++++++++++++++ app/Views/payout_list_handler.php | 308 +++++++++++++++++++++++++++++ 2 files changed, 626 insertions(+) create mode 100644 app/Views/payout_list.php create mode 100644 app/Views/payout_list_handler.php diff --git a/app/Views/payout_list.php b/app/Views/payout_list.php new file mode 100644 index 00000000..4b4eb477 --- /dev/null +++ b/app/Views/payout_list.php @@ -0,0 +1,318 @@ + + +
    +
    +
    +
    +
    +

    Payout List

    +
    +
    +
    + + + + + + + + + + + + + + + + + $row){ ?> + + + + + + + + + + + + + + +
    S.No.Inovice NoInvoice DateInvoice AmountUTR Total AmountBalanceStatusAgentAction
    + +
    +
    +
    +
    +
    + + + + + + \ No newline at end of file diff --git a/app/Views/payout_list_handler.php b/app/Views/payout_list_handler.php new file mode 100644 index 00000000..1857baea --- /dev/null +++ b/app/Views/payout_list_handler.php @@ -0,0 +1,308 @@ +
    +
    +
    +
    +
    +

    + Filter + + + +

    +
    +
    +
    +
    +
    + + +
    + +
    + + +
    + +
    + +
    + + +
    + + +
    + +
    + Clear + Submit +
    + +
    + +
    +
    +
    +
    +
    +
    +
    + +
    + +
    +
    + + \ No newline at end of file From ab1f3d6a9fee375ae1dc5cc8f40f1070bfc67931 Mon Sep 17 00:00:00 2001 From: "venkatesh.r" Date: Sat, 15 Nov 2025 18:48:20 +0530 Subject: [PATCH 12/17] FEAT_PAYOUT_CHANGES --- app/Config/Routes.php | 1 + app/Controllers/ClientController.php | 4 + app/Controllers/PayoutController.php | 100 ++++++++-- app/Models/InvoiceModel.php | 83 +++++++- app/Models/InvoiceUtrModel.php | 34 ++++ app/Views/payout_list.php | 247 +++++++++++++---------- app/Views/payout_list_handler.php | 126 +----------- app/Views/payout_utr_details.php | 280 +++++++++++++++++++++++++++ 8 files changed, 630 insertions(+), 245 deletions(-) create mode 100644 app/Views/payout_utr_details.php diff --git a/app/Config/Routes.php b/app/Config/Routes.php index 3efa4981..9b083b0f 100755 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -772,5 +772,6 @@ $routes->group('payout', function($routes) { $routes->match (['get','post'],'list',"PayoutController::payoutList"); $routes->post('fetchUtrDetails',"PayoutController::fetchUtrDetails"); $routes->post('saveUtrDetails',"PayoutController::saveUtrDetails"); + $routes->post('removeUtrDetails',"PayoutController::removeUtrDetails"); }); diff --git a/app/Controllers/ClientController.php b/app/Controllers/ClientController.php index 0bed75f5..87ec5222 100755 --- a/app/Controllers/ClientController.php +++ b/app/Controllers/ClientController.php @@ -5673,6 +5673,10 @@ class ClientController extends AdminController // $response = $ticketServiceController->extractExcelData("claims_dump_form_client.xlsx"); // dd($response); + // $TicketController = new TicketController(); + // $response = $TicketController->getMoreInfo($requestFrom = 'rest', $ticket_id = 70); + // dd($response); + // ---------- EMP SERVICE CONTROLLER -------------------------------------------------------------------------------- $empServiceController = new EmployeeServiceController(); diff --git a/app/Controllers/PayoutController.php b/app/Controllers/PayoutController.php index 7b798537..06762fd8 100644 --- a/app/Controllers/PayoutController.php +++ b/app/Controllers/PayoutController.php @@ -50,7 +50,7 @@ class PayoutController extends BaseController $start_date = $data['start_date'] ?? null; $end_date = $data['end_date'] ?? null; - $payout_data = $this->invoiceModel->invoiceList($this->payout_status, $agent_id, $status_id, $start_date, $end_date); + $payout_data = $this->invoiceModel->invoiceList($agent_id, $status_id, $start_date, $end_date); $payout_data['payout_list_data'] = $payout_data; $payout_data = view('payout_list', $payout_data); @@ -81,7 +81,7 @@ class PayoutController extends BaseController // for list $data['payout_status'] = $this->payout_status; $data['agent_list'] = $this->invoiceModel->agentList(); - $payout_data['payout_list_data'] = $this->invoiceModel->invoiceList($this->payout_status); + $payout_data['payout_list_data'] = $this->invoiceModel->invoiceList(); $data['payout_list'] = view('payout_list', $payout_data); // dd($data); @@ -90,23 +90,101 @@ class PayoutController extends BaseController public function fetchUtrDetails() { - $invoice_id = $this->request->getPost('invoice_id') ?? null; + $invoice_id = $this->request->getPost('invoice_id') ?? null; + $payout_data = $this->constructUtrDetails($invoice_id); - $payout_data = $this->invoiceModel->invoiceList(); + if(!empty($payout_data)){ + return $this->respond(['status' => true, 'code' => 200, 'data' => $payout_data], 200); + }else{ + return $this->respond(['status' => false, 'code' => 400, 'data' => $payout_data, "message" => "No data found"], 200); + } + } - $data['utr_data'] = $payout_data; - $payout_data = view('partner_utr_details', $data); + public function constructUtrDetails($invoice_id) + { + $utr_data = $this->invoiceUtrModel->where('is_active', 1)->where('invoice_id', $invoice_id)->findAll(); + $summary_data = $this->invoiceModel->utrSummary($invoice_id); - if(!empty($payout_data)){ - return $this->respond(['status' => true, 'code' => 200, 'data' => $payout_data], 200); - }else{ - return $this->respond(['status' => false, 'code' => 400, 'data' => $payout_data, "message" => "No data found"], 200); - } + if($summary_data['invoice_amount'] == $summary_data['total_utr_amount']) { + $data['invoice_completed'] = true; + } + + $data['utr_list_data'] = $utr_data; + $data['summary'] = $summary_data; + $data = view('payout_utr_details', $data); + + return $data; } public function saveUtrDetails() { $data = $this->request->getPost(); + $invoice_id = $this->request->getPost('invoice_id') ?? null; + $utr_id = $this->request->getPost('utr_pk') ?? null; + + if(isset($data['utr_date'])){ + $data['utr_date'] = change_date_format($data['utr_date']); + } + + + if(!empty($utr_id)){ + + $update = $this->invoiceUtrModel->where('id', $utr_id)->set($data)->update(); + $payout_edit_data = $this->constructUtrDetails($invoice_id); + + if($update){ + + $summary_data = $this->invoiceModel->utrSummary($invoice_id); + if($summary_data['invoice_amount'] == $summary_data['total_utr_amount']){ + $sql = "UPDATE partner_invoice SET payout_status = 2 WHERE id = ?"; + db_connect()->query($sql, [$invoice_id]); + } + + return $this->respond(['status' => true, 'code' => 200, 'data' => $payout_edit_data, "message" => "UTR successfully updated"], 200); + }else{ + return $this->respond(['status' => false, 'code' => 400, 'data' => $payout_edit_data, "message" => "Failed to update UTR"], 200); + } + + }else{ + + unset($data['utr_pk']); + $insert_id = $this->invoiceUtrModel->insert($data); + $payout_data = $this->constructUtrDetails($invoice_id); + + if($insert_id){ + + $summary_data = $this->invoiceModel->utrSummary($invoice_id); + if($summary_data['invoice_amount'] == $summary_data['total_utr_amount']){ + $sql = "UPDATE partner_invoice SET payout_status = 2 WHERE id = ?"; + db_connect()->query($sql, [$invoice_id]); + } + + return $this->respond(['status' => true, 'code' => 200, 'data' => $payout_data, "message" => "UTR added successfully"], 200); + }else{ + return $this->respond(['status' => false, 'code' => 400, 'data' => $payout_data, "message" => "Failed to add UTR"], 200); + } + } + } + + public function removeUtrDetails() + { + $data = $this->request->getPost(); + + if(isset($data['utr_id'])){ + + $sql = "UPDATE partner_invoice_utr SET is_active = 0 WHERE id = ?"; + $update = db_connect()->query($sql, [$data['utr_id']]); + + $payout_data = $this->constructUtrDetails($data['invoice_id'] ?? ""); + + if($update){ + return $this->respond(['status' => true, 'code' => 200, 'data' => $payout_data, "message" => "UTR removed successfully"], 200); + }else{ + return $this->respond(['status' => false, 'code' => 400, 'data' => $payout_data, "message" => "Failed to remove UTR"], 200); + } + }else { + return $this->respond(['status' => false, 'code' => 500, 'data' => "", "message" => "Failed to remove UTR"], 200); + } } diff --git a/app/Models/InvoiceModel.php b/app/Models/InvoiceModel.php index 2a3b71e0..49d91ced 100644 --- a/app/Models/InvoiceModel.php +++ b/app/Models/InvoiceModel.php @@ -41,8 +41,41 @@ class InvoiceModel extends Model protected $validationMessages = []; protected $skipValidation = false; + // Callbacks + protected $allowCallbacks = true; + protected $beforeInsert = ["checkAndADDCreatedByValue"]; + protected $afterInsert = []; + protected $beforeUpdate = ["checkAndUpdateUpdatedByValue"]; + protected $afterUpdate = []; + protected $beforeFind = []; + protected $afterFind = []; + protected $beforeDelete = []; + protected $afterDelete = []; - public function invoiceList($status = [], $agent_id = null, $status_id = null, $start_date = null, $end_date = null) + protected function checkAndADDCreatedByValue(array $data) + { + // Check if 'updated_by' value is null or empty + if (empty($data['data']['created_by'])) { + // Set 'updated_by' value to the current session user ID + $data['data']['created_by'] = get_session_userid(); + } + + return $data; + } + + protected function checkAndUpdateUpdatedByValue(array $data) + { + // Check if 'updated_by' value is null or empty + if (empty($data['data']['updated_by'])) { + // Set 'updated_by' value to the current session user ID + $data['data']['updated_by'] = get_session_userid(); + } + + return $data; + } + + + public function invoiceList($agent_id = null, $status_id = null, $start_date = null, $end_date = null) { $data = $this->select(" partner_invoice.*, @@ -67,9 +100,8 @@ class InvoiceModel extends Model -- Payout status CASE - WHEN payout_status = 1 THEN 'Draft' - WHEN payout_status = 2 THEN 'Pending' - WHEN payout_status = 3 THEN 'Complete' + WHEN payout_status = 1 THEN 'Pending' + WHEN payout_status = 2 THEN 'Complete' END AS status_text, partner_agent.name as agent_name @@ -111,7 +143,48 @@ class InvoiceModel extends Model return $return_data; } - public function agentList(){ + public function agentList() + { return $this->db->table('partner_agent')->where('is_active', 1)->get()->getResultArray(); } + + public function utrSummary($invoice_id) + { + $data = $this->select(" + + partner_invoice.*, + + -- Total UTR Amount + (SELECT SUM(piu.amount) + FROM partner_invoice_utr piu + WHERE piu.invoice_id = partner_invoice.id + AND piu.is_active = 1 + ) AS total_utr_amount, + + -- Balance Amount + (partner_invoice.invoice_amount - + IFNULL( + (SELECT SUM(piu2.amount) + FROM partner_invoice_utr piu2 + WHERE piu2.invoice_id = partner_invoice.id + AND piu2.is_active = 1 + ), + 0) + ) AS balance_amount, + + -- Payout status + CASE + WHEN payout_status = 1 THEN 'Pending' + WHEN payout_status = 2 THEN 'Complete' + END AS status_text, + + partner_agent.name as agent_name + ") + ->join('partner_agent', 'partner_invoice.agent_id = partner_agent.id') + ->where('partner_invoice.is_active', 1) + ->where('partner_invoice.id', $invoice_id) + ->first(); + + return $data; + } } diff --git a/app/Models/InvoiceUtrModel.php b/app/Models/InvoiceUtrModel.php index 9f0c44c4..a9da5960 100644 --- a/app/Models/InvoiceUtrModel.php +++ b/app/Models/InvoiceUtrModel.php @@ -17,6 +17,7 @@ class InvoiceUtrModel extends Model 'invoice_id', 'utr_no', 'amount', + 'utr_date', 'is_active', 'created_at', 'created_by', @@ -36,4 +37,37 @@ class InvoiceUtrModel extends Model protected $validationMessages = []; protected $skipValidation = false; + + // Callbacks + protected $allowCallbacks = true; + protected $beforeInsert = ["checkAndADDCreatedByValue"]; + protected $afterInsert = []; + protected $beforeUpdate = ["checkAndUpdateUpdatedByValue"]; + protected $afterUpdate = []; + protected $beforeFind = []; + protected $afterFind = []; + protected $beforeDelete = []; + protected $afterDelete = []; + + protected function checkAndADDCreatedByValue(array $data) + { + // Check if 'updated_by' value is null or empty + if (empty($data['data']['created_by'])) { + // Set 'updated_by' value to the current session user ID + $data['data']['created_by'] = get_session_userid(); + } + + return $data; + } + + protected function checkAndUpdateUpdatedByValue(array $data) + { + // Check if 'updated_by' value is null or empty + if (empty($data['data']['updated_by'])) { + // Set 'updated_by' value to the current session user ID + $data['data']['updated_by'] = get_session_userid(); + } + + return $data; + } } diff --git a/app/Views/payout_list.php b/app/Views/payout_list.php index 4b4eb477..d911715d 100644 --- a/app/Views/payout_list.php +++ b/app/Views/payout_list.php @@ -38,21 +38,145 @@ border-left: 4px solid #2196F3; } + + + + +
    @@ -94,7 +218,7 @@
    -