197 lines
7.7 KiB
PHP
197 lines
7.7 KiB
PHP
<?php
|
|
/**
|
|
* Smoke test: CD low balance alert on debit (DepositHelper + CdLowBalanceAlertHelper)
|
|
*
|
|
* Run:
|
|
* php tests/smoke_cd_low_balance_alert.php [cd_ac_pk] # dry-run: show state only
|
|
* php tests/smoke_cd_low_balance_alert.php [cd_ac_pk] --debit 1 # live: post 1 INR test debit + alert check
|
|
* php tests/smoke_cd_low_balance_alert.php --cron # run cron scan only
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
ob_start();
|
|
|
|
define('FCPATH', __DIR__ . '/../public/');
|
|
chdir(FCPATH);
|
|
|
|
require FCPATH . '../app/Config/Paths.php';
|
|
$paths = new Config\Paths();
|
|
require rtrim($paths->systemDirectory, '\\/ ') . DIRECTORY_SEPARATOR . 'bootstrap.php';
|
|
require_once SYSTEMPATH . 'Config/DotEnv.php';
|
|
(new CodeIgniter\Config\DotEnv(ROOTPATH))->load();
|
|
|
|
defined('ENVIRONMENT') || define('ENVIRONMENT', env('CI_ENVIRONMENT', 'development'));
|
|
|
|
$boot = APPPATH . 'Config/Boot/' . ENVIRONMENT . '.php';
|
|
if (is_file($boot)) {
|
|
require_once $boot;
|
|
}
|
|
|
|
use App\Helpers\CdLowBalanceAlertHelper;
|
|
use App\Helpers\DepositHelper;
|
|
use App\Models\CDMasterModel;
|
|
use App\Models\ClientDepositModel;
|
|
use App\Models\ClientRMModel;
|
|
|
|
$pass = 0;
|
|
$fail = 0;
|
|
$results = [];
|
|
|
|
function ok(string $label, bool $cond, string $detail = ''): void
|
|
{
|
|
global $pass, $fail, $results;
|
|
if ($cond) {
|
|
$pass++;
|
|
$results[] = '[PASS] ' . $label . ($detail ? " — {$detail}" : '');
|
|
} else {
|
|
$fail++;
|
|
$results[] = '[FAIL] ' . $label . ($detail ? " — {$detail}" : '');
|
|
}
|
|
}
|
|
|
|
function argValue(string $flag): ?string
|
|
{
|
|
global $argv;
|
|
$idx = array_search($flag, $argv, true);
|
|
if ($idx === false || ! isset($argv[$idx + 1])) {
|
|
return null;
|
|
}
|
|
|
|
return (string) $argv[$idx + 1];
|
|
}
|
|
|
|
function resolveCurrentBalance(ClientDepositModel $depositModel, int $cdAcPk, float $openingBalance): float
|
|
{
|
|
$lastDeposit = $depositModel
|
|
->select('balance')
|
|
->where('cd_ac_pk', $cdAcPk)
|
|
->where('is_active', 1)
|
|
->orderBy('id', 'DESC')
|
|
->first();
|
|
|
|
if (! empty($lastDeposit)) {
|
|
return (float) ($lastDeposit['balance'] ?? 0);
|
|
}
|
|
|
|
return $openingBalance;
|
|
}
|
|
|
|
$db = db_connect('default');
|
|
$cdMasterModel = new CDMasterModel();
|
|
$depositModel = new ClientDepositModel();
|
|
$runCron = in_array('--cron', $argv, true);
|
|
$debitAmount = argValue('--debit');
|
|
$cdAcPkArg = null;
|
|
|
|
foreach (array_slice($argv, 1) as $arg) {
|
|
if (str_starts_with($arg, '--')) {
|
|
continue;
|
|
}
|
|
if (ctype_digit($arg)) {
|
|
$cdAcPkArg = (int) $arg;
|
|
break;
|
|
}
|
|
}
|
|
|
|
echo PHP_EOL . '=== smoke_cd_low_balance_alert ===' . PHP_EOL;
|
|
|
|
if ($runCron) {
|
|
$response = CdLowBalanceAlertHelper::runCron();
|
|
ok('cron status', ($response['status'] ?? false) === true, (string) ($response['message'] ?? ''));
|
|
ok('cron response has data key', array_key_exists('data', $response));
|
|
echo 'Cron response: ' . json_encode($response, JSON_PRETTY_PRINT) . PHP_EOL;
|
|
} else {
|
|
$configured = $cdMasterModel->getCdMastersWithLowAlertThreshold();
|
|
ok('at least one CD master has alert threshold', count($configured) > 0, 'count=' . count($configured));
|
|
|
|
if ($cdAcPkArg === null && ! empty($configured)) {
|
|
$cdAcPkArg = (int) ($configured[0]['id'] ?? 0);
|
|
}
|
|
|
|
ok('cd_ac_pk resolved', $cdAcPkArg !== null && $cdAcPkArg > 0, 'cd_ac_pk=' . ($cdAcPkArg ?? 'none'));
|
|
|
|
if ($cdAcPkArg > 0) {
|
|
$cdMaster = $cdMasterModel->getCdMasterWithLowAlertThresholdById($cdAcPkArg);
|
|
ok('CD master found with alert threshold', $cdMaster !== null, 'cd_ac_pk=' . $cdAcPkArg);
|
|
|
|
if ($cdMaster !== null) {
|
|
$threshold = (float) ($cdMaster['cd_balance_low_alert_amount'] ?? 0);
|
|
$currentBalance = resolveCurrentBalance($depositModel, $cdAcPkArg, (float) ($cdMaster['opening_bal'] ?? 0));
|
|
$isLow = $currentBalance < $threshold;
|
|
|
|
echo PHP_EOL . 'Account snapshot:' . PHP_EOL;
|
|
echo ' client_id : ' . ($cdMaster['client_id'] ?? '') . ' (' . ($cdMaster['client_name'] ?? '') . ')' . PHP_EOL;
|
|
echo ' cd_ac_pk : ' . $cdAcPkArg . PHP_EOL;
|
|
echo ' cd_ac_no : ' . ($cdMaster['cd_ac_no'] ?? '') . PHP_EOL;
|
|
echo ' balance : ' . number_format($currentBalance, 2) . PHP_EOL;
|
|
echo ' alert amt : ' . number_format($threshold, 2) . PHP_EOL;
|
|
echo ' below alert : ' . ($isLow ? 'yes' : 'no') . PHP_EOL;
|
|
|
|
$acmRows = (new ClientRMModel())
|
|
->select('user_profiles.first_name, user_profiles.email')
|
|
->join('user_profiles', 'user_profiles.id = client_rm.user_id')
|
|
->where('client_rm.client_id', (int) $cdMaster['client_id'])
|
|
->where('client_rm.level', 3)
|
|
->where('client_rm.is_active', 1)
|
|
->where('user_profiles.is_active', 1)
|
|
->findAll();
|
|
ok('account manager exists for client', count($acmRows) > 0, 'count=' . count($acmRows));
|
|
|
|
foreach ($acmRows as $row) {
|
|
echo ' ACM : ' . ($row['first_name'] ?? '') . ' <' . ($row['email'] ?? '') . '>' . PHP_EOL;
|
|
}
|
|
|
|
if ($debitAmount !== null) {
|
|
$amount = (float) $debitAmount;
|
|
ok('debit amount > 0', $amount > 0, 'amount=' . $amount);
|
|
|
|
$beforeBalance = $currentBalance;
|
|
$afterBalance = $beforeBalance - $amount;
|
|
|
|
echo PHP_EOL . 'Posting test debit of ' . number_format($amount, 2) . ' ...' . PHP_EOL;
|
|
|
|
$saveResult = DepositHelper::saveDeposit([
|
|
'amount' => $amount,
|
|
'sub_type_id' => 4,
|
|
'client_id' => (int) $cdMaster['client_id'],
|
|
'client_policy_id' => 0,
|
|
'endorsement_no' => 'SMOKE-TEST-' . date('YmdHis'),
|
|
'cd_ac_no' => (string) ($cdMaster['cd_ac_no'] ?? ''),
|
|
'insurer_id' => (int) ($cdMaster['insurer_id'] ?? 0),
|
|
'unit' => 'SMOKE',
|
|
'description' => 'Smoke test debit for CD low balance alert',
|
|
'transaction_type' => 'Debit',
|
|
'updated_by' => 1,
|
|
'event_name' => 'smoke_test',
|
|
'is_active' => 1,
|
|
'cd_ac_pk' => $cdAcPkArg,
|
|
], 1);
|
|
|
|
ok('saveDeposit succeeded', ($saveResult['success'] ?? false) === true, json_encode($saveResult));
|
|
|
|
$newBalance = resolveCurrentBalance($depositModel, $cdAcPkArg, (float) ($cdMaster['opening_bal'] ?? 0));
|
|
ok('balance reduced after debit', $newBalance < $beforeBalance, "before={$beforeBalance}, after={$newBalance}");
|
|
|
|
if ($afterBalance < $threshold) {
|
|
ok('balance now below alert threshold', $newBalance < $threshold);
|
|
echo 'Check writable/logs/log-' . date('Y-m-d') . '.log for CdLowBalanceAlertHelper triggerAfterBalanceReduction' . PHP_EOL;
|
|
echo 'ACM mail should be sent if mail is configured.' . PHP_EOL;
|
|
} else {
|
|
echo 'Balance still above alert threshold after debit; no mail expected.' . PHP_EOL;
|
|
echo 'Tip: use a larger --debit amount or lower cd_balance_low_alert_amount for this account.' . PHP_EOL;
|
|
}
|
|
} else {
|
|
echo PHP_EOL . 'Dry run only (no debit posted).' . PHP_EOL;
|
|
echo 'To test live debit + alert: php tests/smoke_cd_low_balance_alert.php ' . $cdAcPkArg . ' --debit 1' . PHP_EOL;
|
|
echo 'To test cron scan: php tests/smoke_cd_low_balance_alert.php --cron' . PHP_EOL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
echo PHP_EOL . implode(PHP_EOL, $results) . PHP_EOL;
|
|
echo PHP_EOL . "Summary: {$pass} passed, {$fail} failed" . PHP_EOL;
|
|
|
|
exit($fail > 0 ? 1 : 0);
|