Merge branch 'dev' of bitbucket.org:jubilian/nhance into dev
This commit is contained in:
commit
4bbc80fb0b
@ -14,6 +14,7 @@ use App\Filters\HttpRequestLog;
|
|||||||
use App\Filters\CloseDbConnection;
|
use App\Filters\CloseDbConnection;
|
||||||
use App\Filters\AuthClientApi;
|
use App\Filters\AuthClientApi;
|
||||||
use App\Filters\CommissionApiFilter;
|
use App\Filters\CommissionApiFilter;
|
||||||
|
use App\Filters\Cors;
|
||||||
|
|
||||||
use App\Filters\AuthJWT;
|
use App\Filters\AuthJWT;
|
||||||
|
|
||||||
@ -38,7 +39,8 @@ class Filters extends BaseConfig
|
|||||||
'authJWT' => AuthJWT::class,
|
'authJWT' => AuthJWT::class,
|
||||||
'AuthClientApi' => AuthClientApi::class,
|
'AuthClientApi' => AuthClientApi::class,
|
||||||
'CloseDbConnection' => CloseDbConnection::class,
|
'CloseDbConnection' => CloseDbConnection::class,
|
||||||
'CommissionApiFilter' => CommissionApiFilter::class
|
'CommissionApiFilter' => CommissionApiFilter::class,
|
||||||
|
'Cors' => Cors::class
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -51,11 +53,13 @@ class Filters extends BaseConfig
|
|||||||
public array $globals = [
|
public array $globals = [
|
||||||
'before' => [
|
'before' => [
|
||||||
'HttpRequestLog' => ['except' => 'cli/*'],
|
'HttpRequestLog' => ['except' => 'cli/*'],
|
||||||
|
'Cors',
|
||||||
// 'csrf',
|
// 'csrf',
|
||||||
// 'invalidchars',
|
// 'invalidchars',
|
||||||
],
|
],
|
||||||
'after' => [
|
'after' => [
|
||||||
'CloseDbConnection'
|
'CloseDbConnection',
|
||||||
|
'Cors',
|
||||||
// 'secureheaders',
|
// 'secureheaders',
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|||||||
@ -12,6 +12,8 @@ $routes->get('/chatbottest', 'ChatbotControllerNew::chatbotest');
|
|||||||
$routes->get('/chatbot', 'ChatbotControllerNew::chatbot');
|
$routes->get('/chatbot', 'ChatbotControllerNew::chatbot');
|
||||||
|
|
||||||
$routes->get('/swagger', 'SwaggerController::index', ['filter' => 'authMVC']);
|
$routes->get('/swagger', 'SwaggerController::index', ['filter' => 'authMVC']);
|
||||||
|
$routes->get('/fedeploy', 'DeployController::fedeploy_view', ['filter' => 'authMVC']);
|
||||||
|
$routes->post('/fedeploy', 'DeployController::fedeploy', ['filter' => 'authMVC']);
|
||||||
|
|
||||||
// Reminder Mail Notification
|
// Reminder Mail Notification
|
||||||
|
|
||||||
|
|||||||
286
app/Controllers/DeployController.php
Normal file
286
app/Controllers/DeployController.php
Normal file
@ -0,0 +1,286 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controllers;
|
||||||
|
|
||||||
|
use CodeIgniter\Controller;
|
||||||
|
use CodeIgniter\API\ResponseTrait;
|
||||||
|
|
||||||
|
class DeployController extends AdminController
|
||||||
|
{
|
||||||
|
use ResponseTrait;
|
||||||
|
|
||||||
|
protected $myLogger;
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->myLogger = \Config\Services::mylogger();
|
||||||
|
}
|
||||||
|
// public function fedeploy()
|
||||||
|
// {
|
||||||
|
// $request = $this->request;
|
||||||
|
|
||||||
|
// // Multiple zip files: <input type="file" name="zip_files[]" multiple>
|
||||||
|
// // $zipFiles = $this->request->getFileMultiple('zip_files');
|
||||||
|
// $zipFiles = $this->request->getFile('zip_files');//('zip_files');
|
||||||
|
// // print_r($zipFiles);die();
|
||||||
|
|
||||||
|
// // Matching dropdown/text values (arrays, indexed same as zip_files[])
|
||||||
|
// $zipFolders = (array) $request->getPost('zip_folder'); // e.g. ["web/", "dist/"]
|
||||||
|
// $s3Buckets = (array) $request->getPost('s3_bucket'); // e.g. ["benefits-app-bucket", ...]
|
||||||
|
// $s3Prefixes = (array) $request->getPost('s3_prefix'); // e.g. ["hr/", "payroll/"]
|
||||||
|
// $cfDistributions = (array) $request->getPost('cf_distribution_id'); // e.g. ["DIST1", "DIST1", "DIST2"]
|
||||||
|
// $cfPathsList = (array) $request->getPost('cf_paths'); // e.g. ["/hr/*", "/hr/special/*", "/payroll/*"]
|
||||||
|
|
||||||
|
// // Path to Python interpreter and deploy_assets.py script
|
||||||
|
// $pythonBin = getenv('PY_PATH'); // adjust if needed
|
||||||
|
// $scriptPath = getenv('PY_SCRIPT_PATH'); // full path to your script
|
||||||
|
|
||||||
|
// $results = [];
|
||||||
|
|
||||||
|
// if (empty($zipFiles)) {
|
||||||
|
// return $this->response->setJSON([
|
||||||
|
// 'status' => 'error',
|
||||||
|
// 'message' => 'No zip files uploaded',
|
||||||
|
// ]);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // --------------------------------------------------------
|
||||||
|
// // 1) Pre-process distribution IDs → group by distribution
|
||||||
|
// // - So we can run ONE invalidation per distribution
|
||||||
|
// // - And merge all paths into a single JSON array
|
||||||
|
// // --------------------------------------------------------
|
||||||
|
// $distGroups = []; // [distId => ['indexes' => [...], 'paths' => [...], 'firstIndex' => int]]
|
||||||
|
|
||||||
|
// foreach ($cfDistributions as $i => $distId) {
|
||||||
|
// $distId = trim((string) $distId);
|
||||||
|
// $path = trim((string) ($cfPathsList[$i] ?? ''));
|
||||||
|
|
||||||
|
// // Only consider entries where both distribution ID and path are set
|
||||||
|
// if ($distId === '' || $path === '') {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (!isset($distGroups[$distId])) {
|
||||||
|
// $distGroups[$distId] = [
|
||||||
|
// 'indexes' => [],
|
||||||
|
// 'paths' => [],
|
||||||
|
// ];
|
||||||
|
// }
|
||||||
|
|
||||||
|
// $distGroups[$distId]['indexes'][] = $i;
|
||||||
|
// $distGroups[$distId]['paths'][] = $path;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Set firstIndex and unique paths per distribution
|
||||||
|
// foreach ($distGroups as $distId => $info) {
|
||||||
|
// $distGroups[$distId]['firstIndex'] = $info['indexes'][0]; // first file index for this dist
|
||||||
|
// $distGroups[$distId]['paths'] = array_values(array_unique($info['paths'])); // unique paths
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // --------------------------------------------------------
|
||||||
|
// // 2) Process each uploaded file
|
||||||
|
// // --------------------------------------------------------
|
||||||
|
// foreach ($zipFiles as $index => $file) {
|
||||||
|
// if (!$file->isValid() || $file->hasMoved()) {
|
||||||
|
// $results[] = [
|
||||||
|
// 'file' => $file->getName(),
|
||||||
|
// 'status' => 'error',
|
||||||
|
// 'message' => 'Invalid file or already moved.',
|
||||||
|
// ];
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Read matching form values (or fallback)
|
||||||
|
// $zipFolder = $zipFolders[$index] ?? 'web/'; // default example
|
||||||
|
// $s3Bucket = $s3Buckets[$index] ?? '';
|
||||||
|
// $s3Prefix = $s3Prefixes[$index] ?? '';
|
||||||
|
// $cfDistribution = $cfDistributions[$index] ?? '';
|
||||||
|
// $cfDistribution = trim((string) $cfDistribution);
|
||||||
|
|
||||||
|
// // Move file into a known directory (keep original name)
|
||||||
|
// // $uploadDir = WRITEPATH . 'uploads/deploy';
|
||||||
|
// $uploadDir = '/home/ubuntu/py';
|
||||||
|
// if (!is_dir($uploadDir)) {
|
||||||
|
// mkdir($uploadDir, 0775, true);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// $originalName = $file->getName();
|
||||||
|
// $file->move($uploadDir, $originalName);
|
||||||
|
// $zipPath = $uploadDir . DIRECTORY_SEPARATOR . $originalName;
|
||||||
|
|
||||||
|
// // --------------------------------------------------------
|
||||||
|
// // Decide whether THIS file should trigger invalidation
|
||||||
|
// // - Only firstIndex of each distribution will do it
|
||||||
|
// // - cf-paths-json = JSON array of all unique paths for that dist
|
||||||
|
// // --------------------------------------------------------
|
||||||
|
// $doInvalidation = false;
|
||||||
|
// $cfPathsJson = '';
|
||||||
|
|
||||||
|
// if ($cfDistribution !== '' && isset($distGroups[$cfDistribution])) {
|
||||||
|
// $group = $distGroups[$cfDistribution];
|
||||||
|
|
||||||
|
// if ($group['firstIndex'] === $index) {
|
||||||
|
// // This is the first file for this distribution ID → do invalidation ONCE
|
||||||
|
// $doInvalidation = true;
|
||||||
|
|
||||||
|
// // Build CloudFront paths JSON array (AWS syntax: ["path1", "path2", ...])
|
||||||
|
// $cfPathsJson = json_encode($group['paths']); // e.g. ["\/hr\/*","\/hr\/special\/*"]
|
||||||
|
// }
|
||||||
|
// // Else: same distribution ID but NOT first index → no invalidation
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // --------------------------------------------------------
|
||||||
|
// // Build the python command safely using escapeshellarg
|
||||||
|
// // --------------------------------------------------------
|
||||||
|
// $cmdParts = [
|
||||||
|
// escapeshellarg($pythonBin),
|
||||||
|
// escapeshellarg($scriptPath),
|
||||||
|
// '--zip-path', escapeshellarg($zipPath),
|
||||||
|
// '--zip-folder', escapeshellarg($zipFolder),
|
||||||
|
// '--s3-bucket', escapeshellarg($s3Bucket),
|
||||||
|
// '--s3-prefix', escapeshellarg($s3Prefix),
|
||||||
|
// '--do-webhook', // always send webhook after success
|
||||||
|
// ];
|
||||||
|
|
||||||
|
// if ($doInvalidation) {
|
||||||
|
// $cmdParts[] = '--do-invalidation';
|
||||||
|
// $cmdParts[] = '--cf-distribution-id';
|
||||||
|
// $cmdParts[] = escapeshellarg($cfDistribution);
|
||||||
|
// $cmdParts[] = '--cf-paths-json';
|
||||||
|
// $cmdParts[] = escapeshellarg($cfPathsJson); // e.g. '["/hr/*","/hr/special/*"]'
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Final command string (2>&1 to capture stderr too)
|
||||||
|
// $cmd = implode(' ', $cmdParts) . ' 2>&1';
|
||||||
|
// print_r($cmd);die();
|
||||||
|
// $output = [];
|
||||||
|
// $returnVar = 0;
|
||||||
|
|
||||||
|
// exec($cmd, $output, $returnVar);
|
||||||
|
|
||||||
|
// $results[] = [
|
||||||
|
// 'file' => $originalName,
|
||||||
|
// 'zip_path' => $zipPath,
|
||||||
|
// 'command' => $cmd,
|
||||||
|
// 'output' => $output,
|
||||||
|
// 'exit_code' => $returnVar,
|
||||||
|
// 'status' => $returnVar === 0 ? 'success' : 'error',
|
||||||
|
// ];
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return $this->response->setJSON([
|
||||||
|
// 'status' => 'completed',
|
||||||
|
// 'results' => $results,
|
||||||
|
// ]);
|
||||||
|
// }
|
||||||
|
|
||||||
|
public function fedeploy()
|
||||||
|
{
|
||||||
|
$request = $this->request;
|
||||||
|
|
||||||
|
// Single zip file: <input type="file" name="zip_file">
|
||||||
|
$file = $request->getFile('zip_file');
|
||||||
|
|
||||||
|
if (!$file || !$file->isValid()) {
|
||||||
|
return $this->response->setJSON([
|
||||||
|
'status' => 'error',
|
||||||
|
'message' => 'No valid zip file uploaded',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read scalar form values
|
||||||
|
$zipFolder = (string) $request->getPost('zip_folder') ?: 'web/';
|
||||||
|
$s3Bucket = (string) $request->getPost('s3_bucket') ?: '';
|
||||||
|
$s3Prefix = (string) $request->getPost('s3_prefix') ?: '';
|
||||||
|
$cfDistribution = trim((string) $request->getPost('cf_distribution_id'));
|
||||||
|
$cfPathsRaw = (string) $request->getPost('cf_paths');
|
||||||
|
|
||||||
|
// Python interpreter and script path from env
|
||||||
|
$pythonBin = getenv('PY_PATH'); // e.g. /usr/bin/python3
|
||||||
|
$scriptPath = getenv('PY_SCRIPT_PATH'); // e.g. /home/ubuntu/deploy_assets.py
|
||||||
|
|
||||||
|
if (empty($pythonBin) || empty($scriptPath)) {
|
||||||
|
return $this->response->setJSON([
|
||||||
|
'status' => 'error',
|
||||||
|
'message' => 'Python path or script path not configured in environment.',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move file into known directory (keep original name)
|
||||||
|
$uploadDir = '~/py';
|
||||||
|
if (!is_dir($uploadDir)) {
|
||||||
|
mkdir($uploadDir, 0775, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$originalName = $file->getName();
|
||||||
|
$file->move($uploadDir, $originalName);
|
||||||
|
$zipPath = $uploadDir . DIRECTORY_SEPARATOR . $originalName;
|
||||||
|
|
||||||
|
// -----------------------------
|
||||||
|
// CloudFront invalidation data
|
||||||
|
// -----------------------------
|
||||||
|
$doInvalidation = false;
|
||||||
|
$cfPathsJson = '';
|
||||||
|
|
||||||
|
// Allow comma or newline separated paths: "/hr/*,/hr/special/*" or
|
||||||
|
// "/hr/*\n/hr/special/*"
|
||||||
|
$paths = array_filter(
|
||||||
|
array_map('trim', preg_split('/[\r\n,]+/', $cfPathsRaw)),
|
||||||
|
'strlen'
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($cfDistribution !== '' && !empty($paths)) {
|
||||||
|
$doInvalidation = true;
|
||||||
|
$cfPathsJson = json_encode($paths); // e.g. ["\/hr\/*","\/hr\/special\/*"]
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------
|
||||||
|
// Build python command
|
||||||
|
// -----------------------------
|
||||||
|
$cmdParts = [
|
||||||
|
escapeshellarg($pythonBin),
|
||||||
|
escapeshellarg($scriptPath),
|
||||||
|
'--zip-path', escapeshellarg($zipPath),
|
||||||
|
'--zip-folder', escapeshellarg($zipFolder),
|
||||||
|
'--s3-bucket', escapeshellarg($s3Bucket),
|
||||||
|
'--s3-prefix', escapeshellarg($s3Prefix),
|
||||||
|
'--do-webhook', // always send webhook after success
|
||||||
|
];
|
||||||
|
|
||||||
|
if ($doInvalidation) {
|
||||||
|
$cmdParts[] = '--do-invalidation';
|
||||||
|
$cmdParts[] = '--cf-distribution-id';
|
||||||
|
$cmdParts[] = escapeshellarg($cfDistribution);
|
||||||
|
$cmdParts[] = '--cf-paths-json';
|
||||||
|
$cmdParts[] = escapeshellarg($cfPathsJson);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Final command string (2>&1 to capture stderr too)
|
||||||
|
$cmd = implode(' ', $cmdParts) . ' 2>&1';
|
||||||
|
$output = [];
|
||||||
|
$returnVar = 0;
|
||||||
|
print_r($cmd);die();
|
||||||
|
exec($cmd, $output, $returnVar);
|
||||||
|
|
||||||
|
$result = [
|
||||||
|
'file' => $originalName,
|
||||||
|
'zip_path' => $zipPath,
|
||||||
|
'command' => $cmd,
|
||||||
|
'output' => $output,
|
||||||
|
'exit_code' => $returnVar,
|
||||||
|
'status' => $returnVar === 0 ? 'success' : 'error',
|
||||||
|
];
|
||||||
|
|
||||||
|
return $this->response->setJSON([
|
||||||
|
'status' => 'completed',
|
||||||
|
'result' => $result,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function fedeploy_view()
|
||||||
|
{
|
||||||
|
// $this->load->view('fedeploy');
|
||||||
|
$this->loadLayout('fedeploy');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -212,8 +212,14 @@ class PayoutController extends BaseController
|
|||||||
|
|
||||||
$id = $this->request->getGet('id');
|
$id = $this->request->getGet('id');
|
||||||
|
|
||||||
|
if($type == 'add')
|
||||||
|
{
|
||||||
|
$data['agents'] = $this->invoiceModel->agentList(['is_active' => 1]); // common both add and edit
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
$data['agents'] = $this->invoiceModel->agentList(); // common both add and edit
|
$data['agents'] = $this->invoiceModel->agentList(); // common both add and edit
|
||||||
|
}
|
||||||
// $data['checked_policy_numbers'] = [];
|
// $data['checked_policy_numbers'] = [];
|
||||||
// $data['invoice'] = [];
|
// $data['invoice'] = [];
|
||||||
// $data['extra_payouts'] = [];
|
// $data['extra_payouts'] = [];
|
||||||
@ -224,6 +230,8 @@ class PayoutController extends BaseController
|
|||||||
if ($type === 'add') {
|
if ($type === 'add') {
|
||||||
// $invoiceNo = $this->generateInvoiceNumber();
|
// $invoiceNo = $this->generateInvoiceNumber();
|
||||||
$data['payouts'] = $this->invoiceModel->payoutList(1);
|
$data['payouts'] = $this->invoiceModel->payoutList(1);
|
||||||
|
// print_rr($data['payouts']);die();
|
||||||
|
// print_rr($this->invoiceModel->getLastQuery());die();
|
||||||
// $data['invoice_number'] = $invoiceNo;
|
// $data['invoice_number'] = $invoiceNo;
|
||||||
return $this->loadLayout('invoice_policy_mapping_add', $data);
|
return $this->loadLayout('invoice_policy_mapping_add', $data);
|
||||||
}
|
}
|
||||||
@ -251,7 +259,7 @@ class PayoutController extends BaseController
|
|||||||
$data['invoice_number']= $invoice['invoice_no'];
|
$data['invoice_number']= $invoice['invoice_no'];
|
||||||
$data['type'] = $type;
|
$data['type'] = $type;
|
||||||
$data['payout_status'] = $invoice['payout_status'] ;
|
$data['payout_status'] = $invoice['payout_status'] ;
|
||||||
|
// dd($data);
|
||||||
return $this->loadLayout('invoice_policy_mapping', $data);
|
return $this->loadLayout('invoice_policy_mapping', $data);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -263,6 +271,7 @@ class PayoutController extends BaseController
|
|||||||
public function saveInvoice()
|
public function saveInvoice()
|
||||||
{
|
{
|
||||||
$json = $this->request->getJSON(true);
|
$json = $this->request->getJSON(true);
|
||||||
|
// print_rr($json);die();
|
||||||
|
|
||||||
if (!$json) {
|
if (!$json) {
|
||||||
return $this->response->setJSON(['error' => 'Invalid JSON','message' => 'Invalid JSON received.'])->setStatusCode(400);
|
return $this->response->setJSON(['error' => 'Invalid JSON','message' => 'Invalid JSON received.'])->setStatusCode(400);
|
||||||
@ -296,7 +305,7 @@ class PayoutController extends BaseController
|
|||||||
foreach ($json['policies'] as $p) {
|
foreach ($json['policies'] as $p) {
|
||||||
$this->invoiceItemModel->insert([
|
$this->invoiceItemModel->insert([
|
||||||
'invoice_id' => $invoiceId,
|
'invoice_id' => $invoiceId,
|
||||||
'policy_id' => $p['policy_id'],
|
'policy_id' => $p['partner_policy_id'],
|
||||||
'policy_no' => $p['policy_no'],
|
'policy_no' => $p['policy_no'],
|
||||||
'commission_amount' => $p['commission_amount'],
|
'commission_amount' => $p['commission_amount'],
|
||||||
'is_active' => 1
|
'is_active' => 1
|
||||||
|
|||||||
@ -42,6 +42,19 @@ class RuleImportController extends AdminController
|
|||||||
'is_new_vehicle',
|
'is_new_vehicle',
|
||||||
'cubic_capacity',
|
'cubic_capacity',
|
||||||
'policy_business_type',
|
'policy_business_type',
|
||||||
|
'fuel_type',
|
||||||
|
'produt',
|
||||||
|
'geo_rto_state',
|
||||||
|
'geo_rto_city',
|
||||||
|
'model',
|
||||||
|
'make',
|
||||||
|
'weight',
|
||||||
|
'renewal_type',
|
||||||
|
'renewal_sub_type',
|
||||||
|
'premium',
|
||||||
|
'od_premium',
|
||||||
|
'tp_premium',
|
||||||
|
'product'
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
422
app/Filters/Cors.php
Normal file
422
app/Filters/Cors.php
Normal file
@ -0,0 +1,422 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filters;
|
||||||
|
|
||||||
|
use CodeIgniter\Filters\FilterInterface;
|
||||||
|
use CodeIgniter\HTTP\RequestInterface;
|
||||||
|
use CodeIgniter\HTTP\ResponseInterface;
|
||||||
|
use Config\Services;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CORS (Cross-Origin Resource Sharing) Filter
|
||||||
|
*
|
||||||
|
* Handles CORS preflight requests and adds appropriate CORS headers to responses.
|
||||||
|
* Configurable via environment variables for flexibility across different environments.
|
||||||
|
*
|
||||||
|
* @package App\Filters
|
||||||
|
*/
|
||||||
|
class Cors implements FilterInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* List of allowed origins (domains that can access this API)
|
||||||
|
* Can include wildcards like *.example.com
|
||||||
|
*
|
||||||
|
* @var array<string>
|
||||||
|
*/
|
||||||
|
protected array $allowedOrigins = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to allow credentials (cookies, authorization headers) in CORS requests
|
||||||
|
* WARNING: Cannot be true if using wildcard (*) origin
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
protected bool $allowCredentials = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HTTP methods allowed for CORS requests
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected string $allowedMethods = 'GET,POST,PUT,PATCH,DELETE,OPTIONS';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HTTP headers allowed in CORS requests
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected string $allowedHeaders = 'Content-Type,Authorization,X-Requested-With,Accept,Origin';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Headers exposed to the client (accessible via JavaScript)
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected string $exposeHeaders = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* How long (in seconds) the preflight response can be cached
|
||||||
|
* Default: 24 hours (86400 seconds)
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
protected int $maxAge = 86400;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to enable debug logging for CORS requests
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
protected bool $debug = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize CORS configuration from environment variables
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException If configuration is invalid
|
||||||
|
*/
|
||||||
|
|
||||||
|
protected $myLogger;
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
|
||||||
|
$this->myLogger = \Config\Services::mylogger();
|
||||||
|
// Parse allowed origins from environment variable
|
||||||
|
// Format: comma or semicolon separated list
|
||||||
|
// Examples: "https://example.com,https://app.example.com" or "*.example.com"
|
||||||
|
$raw = env('CORS_ALLOWED_ORIGINS', '*');
|
||||||
|
$parts = preg_split('/\s*[,;]\s*/', trim($raw));
|
||||||
|
$this->allowedOrigins = array_filter(array_map('trim', $parts));
|
||||||
|
|
||||||
|
// Load other configuration from environment
|
||||||
|
$this->allowCredentials = filter_var(
|
||||||
|
env('CORS_ALLOW_CREDENTIALS', false),
|
||||||
|
FILTER_VALIDATE_BOOLEAN
|
||||||
|
);
|
||||||
|
$this->allowedMethods = env('CORS_ALLOWED_METHODS', $this->allowedMethods);
|
||||||
|
$this->allowedHeaders = env('CORS_ALLOWED_HEADERS', $this->allowedHeaders);
|
||||||
|
$this->exposeHeaders = env('CORS_EXPOSE_HEADERS', $this->exposeHeaders);
|
||||||
|
$this->maxAge = (int) env('CORS_MAX_AGE', $this->maxAge);
|
||||||
|
$this->debug = filter_var(env('CORS_DEBUG', false), FILTER_VALIDATE_BOOLEAN);
|
||||||
|
|
||||||
|
// Security validation: wildcard origin cannot be used with credentials
|
||||||
|
// This is a browser security requirement, not just a best practice
|
||||||
|
if ($this->allowCredentials && in_array('*', $this->allowedOrigins, true)) {
|
||||||
|
throw new \RuntimeException(
|
||||||
|
'CORS configuration error: Cannot use wildcard (*) origin with credentials enabled. ' .
|
||||||
|
'This violates browser security policies. Either disable credentials or specify explicit origins.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->log('CORS filter initialized', [
|
||||||
|
'allowed_origins' => $this->allowedOrigins,
|
||||||
|
'allow_credentials' => $this->allowCredentials,
|
||||||
|
'allowed_methods' => $this->allowedMethods,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a given origin is allowed to access this API
|
||||||
|
*
|
||||||
|
* Supports:
|
||||||
|
* - Exact matches: https://example.com
|
||||||
|
* - Wildcard origins: *.example.com
|
||||||
|
* - Scheme-less matching: example.com (matches http and https)
|
||||||
|
* - Universal wildcard: *
|
||||||
|
*
|
||||||
|
* @param string|null $origin The Origin header from the request
|
||||||
|
* @return bool True if origin is allowed, false otherwise
|
||||||
|
*/
|
||||||
|
protected function isOriginAllowed(?string $origin): bool
|
||||||
|
{
|
||||||
|
// Reject empty origins
|
||||||
|
if (empty($origin)) {
|
||||||
|
$this->log('Origin rejected: empty origin header');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate origin format - must include scheme (http:// or https://)
|
||||||
|
// This prevents malformed origins from being accepted
|
||||||
|
if (!preg_match('#^https?://#i', $origin)) {
|
||||||
|
$this->log('Origin rejected: invalid format (missing scheme)', ['origin' => $origin]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If wildcard present in configuration, allow any origin
|
||||||
|
if (in_array('*', $this->allowedOrigins, true)) {
|
||||||
|
$this->log('Origin allowed: wildcard match', ['origin' => $origin]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the host from the origin for wildcard matching
|
||||||
|
// Example: https://app.example.com:8080 → app.example.com
|
||||||
|
$originHost = parse_url($origin, PHP_URL_HOST) ?: $origin;
|
||||||
|
|
||||||
|
foreach ($this->allowedOrigins as $allowed) {
|
||||||
|
if ($allowed === '') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. Exact match (including scheme and port)
|
||||||
|
// Example: https://example.com matches https://example.com
|
||||||
|
if (strcasecmp($allowed, $origin) === 0) {
|
||||||
|
$this->log('Origin allowed: exact match', [
|
||||||
|
'origin' => $origin,
|
||||||
|
'matched_rule' => $allowed
|
||||||
|
]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Handle scheme-less and wildcard patterns
|
||||||
|
// If the allowed entry doesn't contain ://, it's either a host-only or wildcard pattern
|
||||||
|
if (strpos($allowed, '://') === false) {
|
||||||
|
|
||||||
|
// 2a. Wildcard subdomain pattern: *.example.com
|
||||||
|
// Matches: app.example.com, api.example.com, dev.app.example.com
|
||||||
|
// Does NOT match: example.com (use explicit entry for root domain)
|
||||||
|
if (strpos($allowed, '*.') === 0) {
|
||||||
|
$allowedRoot = substr($allowed, 2); // Remove *. prefix
|
||||||
|
|
||||||
|
// Check if origin host ends with the allowed root domain
|
||||||
|
if ($originHost === $allowedRoot || str_ends_with($originHost, '.' . $allowedRoot)) {
|
||||||
|
$this->log('Origin allowed: wildcard subdomain match', [
|
||||||
|
'origin' => $origin,
|
||||||
|
'matched_rule' => $allowed,
|
||||||
|
'origin_host' => $originHost
|
||||||
|
]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 2b. Direct host match (scheme-less)
|
||||||
|
// Allows both http and https for the same host
|
||||||
|
// Example: example.com matches both http://example.com and https://example.com
|
||||||
|
else {
|
||||||
|
if (strcasecmp($allowed, $originHost) === 0) {
|
||||||
|
$this->log('Origin allowed: host match (scheme-less)', [
|
||||||
|
'origin' => $origin,
|
||||||
|
'matched_rule' => $allowed,
|
||||||
|
'origin_host' => $originHost
|
||||||
|
]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// No match found - reject this origin
|
||||||
|
$this->log('Origin rejected: no matching rule', [
|
||||||
|
'origin' => $origin,
|
||||||
|
'checked_rules' => $this->allowedOrigins
|
||||||
|
]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build the Access-Control-Allow-Origin header value
|
||||||
|
*
|
||||||
|
* Returns either:
|
||||||
|
* - '*' if wildcard is configured and credentials are disabled
|
||||||
|
* - The actual origin value if credentials are enabled or specific origins configured
|
||||||
|
*
|
||||||
|
* Note: When credentials are enabled, you MUST echo back the specific origin,
|
||||||
|
* browsers reject wildcard with credentials.
|
||||||
|
*
|
||||||
|
* @param string $origin The validated origin
|
||||||
|
* @return string The value for Access-Control-Allow-Origin header
|
||||||
|
*/
|
||||||
|
protected function buildAllowOriginHeader(string $origin): string
|
||||||
|
{
|
||||||
|
// If wildcard configured and credentials NOT required, can safely return '*'
|
||||||
|
// This allows any origin to access the resource
|
||||||
|
if (in_array('*', $this->allowedOrigins, true) && !$this->allowCredentials) {
|
||||||
|
return '*';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, must return the specific origin
|
||||||
|
// This is required when allow-credentials is true
|
||||||
|
return $origin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add all CORS headers to the response
|
||||||
|
*
|
||||||
|
* This method is called for both preflight and actual requests
|
||||||
|
* to ensure consistent CORS headers across all responses.
|
||||||
|
*
|
||||||
|
* @param ResponseInterface $response The response object to add headers to
|
||||||
|
* @param RequestInterface $request The original request
|
||||||
|
* @param string $origin The validated origin
|
||||||
|
* @param bool $isPreflight Whether this is a preflight OPTIONS request
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function addCorsHeaders(
|
||||||
|
ResponseInterface $response,
|
||||||
|
RequestInterface $request,
|
||||||
|
string $origin,
|
||||||
|
bool $isPreflight = false
|
||||||
|
): void {
|
||||||
|
// CRITICAL: Vary header prevents caching issues
|
||||||
|
// Without this, a cached response for origin A might be served to origin B,
|
||||||
|
// causing CORS errors because the Access-Control-Allow-Origin won't match
|
||||||
|
$response->setHeader('Vary', 'Origin');
|
||||||
|
|
||||||
|
// Set the allowed origin
|
||||||
|
$allowOrigin = $this->buildAllowOriginHeader($origin);
|
||||||
|
$response->setHeader('Access-Control-Allow-Origin', $allowOrigin);
|
||||||
|
|
||||||
|
// If credentials are allowed, set the header
|
||||||
|
// This allows cookies, authorization headers, and TLS client certificates
|
||||||
|
if ($this->allowCredentials) {
|
||||||
|
$response->setHeader('Access-Control-Allow-Credentials', 'true');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allowed HTTP methods
|
||||||
|
$response->setHeader('Access-Control-Allow-Methods', $this->allowedMethods);
|
||||||
|
|
||||||
|
// Handle allowed headers
|
||||||
|
if ($isPreflight) {
|
||||||
|
// For preflight: respect what the browser is asking for
|
||||||
|
// The browser sends Access-Control-Request-Headers to ask permission
|
||||||
|
$requestedHeaders = $request->getHeaderLine('Access-Control-Request-Headers');
|
||||||
|
$response->setHeader(
|
||||||
|
'Access-Control-Allow-Headers',
|
||||||
|
$requestedHeaders ?: $this->allowedHeaders
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// For actual requests: use configured headers
|
||||||
|
// Access-Control-Request-Headers is only for preflight
|
||||||
|
$response->setHeader('Access-Control-Allow-Headers', $this->allowedHeaders);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expose additional headers to the client (accessible via JavaScript)
|
||||||
|
// Without this, only simple headers are accessible: Cache-Control, Content-Language,
|
||||||
|
// Content-Type, Expires, Last-Modified, Pragma
|
||||||
|
if (!empty($this->exposeHeaders)) {
|
||||||
|
$response->setHeader('Access-Control-Expose-Headers', $this->exposeHeaders);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cache duration for preflight responses
|
||||||
|
// Reduces preflight requests by allowing browser to cache the permissions
|
||||||
|
if ($this->maxAge > 0) {
|
||||||
|
$response->setHeader('Access-Control-Max-Age', (string) $this->maxAge);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute before the controller
|
||||||
|
*
|
||||||
|
* Handles preflight OPTIONS requests by returning early with appropriate headers.
|
||||||
|
* For other requests, allows them to proceed to the controller.
|
||||||
|
*
|
||||||
|
* @param RequestInterface $request The request object
|
||||||
|
* @param mixed $arguments Optional arguments
|
||||||
|
* @return ResponseInterface|null Response for preflight, null for other requests
|
||||||
|
*/
|
||||||
|
public function before(RequestInterface $request, $arguments = null)
|
||||||
|
{
|
||||||
|
$origin = $request->getHeaderLine('Origin') ?: '';
|
||||||
|
$method = strtoupper($request->getMethod());
|
||||||
|
|
||||||
|
// Handle preflight OPTIONS requests
|
||||||
|
// Preflight is sent by browsers before actual cross-origin requests
|
||||||
|
// to check if the actual request is safe to send
|
||||||
|
if ($method === 'OPTIONS') {
|
||||||
|
$this->log('Preflight request received', [
|
||||||
|
'origin' => $origin,
|
||||||
|
'method' => $method,
|
||||||
|
'uri' => (string) $request->getUri()
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Validate origin - reject if not allowed
|
||||||
|
if (empty($origin) || !$this->isOriginAllowed($origin)) {
|
||||||
|
$this->log('Preflight rejected: origin not allowed', ['origin' => $origin]);
|
||||||
|
|
||||||
|
// Return 403 Forbidden for rejected origins
|
||||||
|
// Some prefer 200 with no CORS headers, but 403 is more explicit
|
||||||
|
return Services::response()
|
||||||
|
->setStatusCode(403)
|
||||||
|
->setJSON(['error' => 'Origin not allowed']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Origin is valid - build preflight response
|
||||||
|
$response = Services::response();
|
||||||
|
$this->addCorsHeaders($response, $request, $origin, true);
|
||||||
|
|
||||||
|
// 204 No Content is the standard response for successful preflight
|
||||||
|
// It indicates "permission granted, but no data to return"
|
||||||
|
$response->setStatusCode(204);
|
||||||
|
$response->setBody('');
|
||||||
|
|
||||||
|
$this->log('Preflight approved', [
|
||||||
|
'origin' => $origin,
|
||||||
|
'allowed_methods' => $this->allowedMethods
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For non-OPTIONS requests, don't return a response
|
||||||
|
// Let the request proceed to the controller
|
||||||
|
// CORS headers will be added in after() method
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute after the controller
|
||||||
|
*
|
||||||
|
* Adds CORS headers to the response for actual (non-preflight) requests.
|
||||||
|
* This ensures all API responses include proper CORS headers.
|
||||||
|
*
|
||||||
|
* @param RequestInterface $request The request object
|
||||||
|
* @param ResponseInterface $response The response object
|
||||||
|
* @param mixed $arguments Optional arguments
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
|
||||||
|
{
|
||||||
|
$origin = $request->getHeaderLine('Origin') ?: '';
|
||||||
|
|
||||||
|
// Only add CORS headers if origin is present and allowed
|
||||||
|
// No origin header means it's a same-origin request (no CORS needed)
|
||||||
|
if (empty($origin)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->isOriginAllowed($origin)) {
|
||||||
|
$this->log('Response blocked: origin not allowed', [
|
||||||
|
'origin' => $origin,
|
||||||
|
'uri' => (string) $request->getUri()
|
||||||
|
]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add CORS headers to the response
|
||||||
|
$this->addCorsHeaders($response, $request, $origin, false);
|
||||||
|
|
||||||
|
$this->log('CORS headers added to response', [
|
||||||
|
'origin' => $origin,
|
||||||
|
'status' => $response->getStatusCode()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log debug information if debug mode is enabled
|
||||||
|
*
|
||||||
|
* Logs to CodeIgniter's log system at 'info' level.
|
||||||
|
* Enable with CORS_DEBUG=true in .env file.
|
||||||
|
*
|
||||||
|
* @param string $message The log message
|
||||||
|
* @param array $context Additional context data
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function log(string $message, array $context = []): void
|
||||||
|
{
|
||||||
|
if (!$this->debug) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// $logger = Services::logger();
|
||||||
|
$contextString = !empty($context) ? json_encode($context, JSON_UNESCAPED_SLASHES) : '';
|
||||||
|
$this->myLogger->logme('error','[CORS] ' . $message . ($contextString ? ' | ' . $contextString : ''));
|
||||||
|
// $logger->info('[CORS] ' . $message . ($contextString ? ' | ' . $contextString : ''));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -143,9 +143,12 @@ class InvoiceModel extends Model
|
|||||||
return $return_data;
|
return $return_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function agentList()
|
public function agentList($params = [])
|
||||||
{
|
{
|
||||||
return $this->db->table('partner_agent')->where('is_active', 1)->get()->getResultArray();
|
if(isset($params['is_active'])){
|
||||||
|
return $this->db->table('partner_agent')->where('is_active', $params['is_active'])->get()->getResultArray();
|
||||||
|
}
|
||||||
|
return $this->db->table('partner_agent')->get()->getResultArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function utrSummary($invoice_id)
|
public function utrSummary($invoice_id)
|
||||||
@ -203,17 +206,19 @@ class InvoiceModel extends Model
|
|||||||
DATE_FORMAT(pp.issued_date, "%d/%m/%Y") AS date,
|
DATE_FORMAT(pp.issued_date, "%d/%m/%Y") AS date,
|
||||||
pii.id AS invoiceItemId,
|
pii.id AS invoiceItemId,
|
||||||
pii.commission_amount as paid_amount,
|
pii.commission_amount as paid_amount,
|
||||||
pi.payout_status
|
pi.payout_status,
|
||||||
|
pp.id as partner_policy_id,
|
||||||
|
pp.policy_transaction_id
|
||||||
')
|
')
|
||||||
->join('partner_invoice_items pii','pii.policy_no = pt.policy_no','left')
|
->join('partner_invoice_items pii','pii.policy_no = pt.policy_no','left')
|
||||||
->join('partner_invoice pi','pi.id = pii.invoice_id','left')
|
->join('partner_invoice pi','pi.id = pii.invoice_id','left')
|
||||||
->join('partner_policy pp','pt.policy_no = pp.policy_number AND pt.agent_id = pp.agent_id','left')
|
->join('partner_policy pp','pt.policy_no = pp.policy_number AND pt.agent_id = pp.agent_id AND pt.id = pp.policy_transaction_id')
|
||||||
->where('pt.is_active',1)
|
->where('pt.is_active',1)
|
||||||
->where('pt.agent_id IS NOT NULL', null, false);
|
->where('pt.agent_id IS NOT NULL');
|
||||||
|
|
||||||
if ($flag == 1) { // Add mode
|
if ($flag == 1) { // Add mode
|
||||||
// EXCLUDE all policies that exist in partner_invoice_items
|
// EXCLUDE all policies that exist in partner_invoice_items
|
||||||
$builder->where("pt.policy_no NOT IN (SELECT policy_no FROM partner_invoice_items)", null, false);
|
$builder->where("pt.id NOT IN (SELECT policy_id FROM partner_invoice_items)", null, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($flag == 2) { // Edit mode
|
if ($flag == 2) { // Edit mode
|
||||||
|
|||||||
43
app/Views/fedeploy.php
Normal file
43
app/Views/fedeploy.php
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<form action="<?= base_url('fedeploy'); ?>" method="post" enctype="multipart/form-data">
|
||||||
|
<!-- Single zip upload -->
|
||||||
|
<div>
|
||||||
|
<label for="zip_file">Zip File</label>
|
||||||
|
<input type="file" name="zip_file" id="zip_file" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label for="zip_folder">Zip Folder (inside zip to deploy)</label>
|
||||||
|
<select name="zip_folder" id="zip_folder">
|
||||||
|
<option value="web/">web/</option>
|
||||||
|
<option value="dist/">dist/</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label for="s3_bucket">S3 Bucket</label>
|
||||||
|
<select name="s3_bucket" id="s3_bucket">
|
||||||
|
<option value="benefits-app-bucket">benefits-app-bucket</option>
|
||||||
|
<option value="other-bucket">other-bucket</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label for="s3_prefix">S3 Prefix</label>
|
||||||
|
<input type="text" name="s3_prefix" id="s3_prefix" value="hr/">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label for="cf_distribution_id">CloudFront Distribution ID (optional)</label>
|
||||||
|
<input type="text" name="cf_distribution_id" id="cf_distribution_id" value="E1MKRK4U5MZ3BD">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label for="cf_paths">
|
||||||
|
CloudFront Invalidation Paths (comma or newline separated, e.g. <code>/hr/*,/hr/special/*</code>)
|
||||||
|
</label>
|
||||||
|
<input type="text" name="cf_paths" id="cf_paths" value="/hr/*">
|
||||||
|
<!-- If you prefer multi-line, use <textarea> instead of <input> -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit">Deploy</button>
|
||||||
|
</form>
|
||||||
@ -720,7 +720,8 @@ table.dataTable tbody td { padding: 4px 4px !important; }
|
|||||||
return {
|
return {
|
||||||
policy_id: p.id,
|
policy_id: p.id,
|
||||||
policy_no: p.policyNo,
|
policy_no: p.policyNo,
|
||||||
commission_amount: finalAmount
|
commission_amount: finalAmount,
|
||||||
|
partner_policy_id : p.partner_policy_id
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -276,7 +276,7 @@ table.dataTable tbody td { padding: 4px 4px !important; }
|
|||||||
|
|
||||||
let agentId = agentEl ? agentEl.value : '';
|
let agentId = agentEl ? agentEl.value : '';
|
||||||
let policyTillDate = policyTillDateEl ? policyTillDateEl.value : '';
|
let policyTillDate = policyTillDateEl ? policyTillDateEl.value : '';
|
||||||
|
console.log('policyTillDate', policyTillDate);
|
||||||
selectedPolicies.clear();
|
selectedPolicies.clear();
|
||||||
|
|
||||||
if (!agentId || agentId === '' || agentId === '0') {
|
if (!agentId || agentId === '' || agentId === '0') {
|
||||||
@ -503,6 +503,8 @@ table.dataTable tbody td { padding: 4px 4px !important; }
|
|||||||
|
|
||||||
|
|
||||||
const selectedPolicyData = filteredPolicies.filter(p => selectedPolicies.has(String(p.id)));
|
const selectedPolicyData = filteredPolicies.filter(p => selectedPolicies.has(String(p.id)));
|
||||||
|
console.log('selectedPolicyData');
|
||||||
|
console.log(selectedPolicyData);
|
||||||
|
|
||||||
let totalAmount = 0;
|
let totalAmount = 0;
|
||||||
const policies = selectedPolicyData.map(p => {
|
const policies = selectedPolicyData.map(p => {
|
||||||
@ -511,7 +513,8 @@ table.dataTable tbody td { padding: 4px 4px !important; }
|
|||||||
return {
|
return {
|
||||||
policy_id: p.id,
|
policy_id: p.id,
|
||||||
policy_no: p.policyNo,
|
policy_no: p.policyNo,
|
||||||
commission_amount: finalAmount
|
commission_amount: finalAmount,
|
||||||
|
partner_policy_id : p.partner_policy_id
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user