MERGE_TEST_BUG_FIXES

This commit is contained in:
Ubuntu 2026-07-21 12:21:52 +05:30
commit a8a6a6943c
2 changed files with 1766 additions and 9 deletions

View File

@ -0,0 +1,487 @@
<?php
namespace App\Commands;
use App\Helpers\MailHelper;
use App\Helpers\sendMailNotification;
use App\Models\ClientModel;
use App\Models\ClientPolicyModel;
use App\Models\NotificationModel;
use App\Models\PolicyPremium1Model;
use App\Models\PolicyPremium2Model;
use CodeIgniter\CLI\BaseCommand;
use CodeIgniter\CLI\CLI;
/**
* Test member_review_and_summary_mail with generated sample data.
*
* Examples:
* php spark test:member-review-mail --mail=you@example.com --premium-summary=2
* php spark test:member-review-mail --mail=you@example.com --premium-summary=1 --type=topup
* php spark test:member-review-mail --mail=you@example.com --premium-summary=1 --type=simple
* php spark test:member-review-mail --mail=you@example.com --premium-summary=0 --type=full --dry-run
* php spark test:member-review-mail --mail=you@example.com --client-id=12 --premium-summary=2
*/
class TestMemberReviewSummaryMail extends BaseCommand
{
protected $group = 'Testing';
protected $name = 'test:member-review-mail';
protected $description = 'Send/test member_review_and_summary_mail with sample data and is_premium_summery mode';
protected $usage = 'test:member-review-mail --mail=email@example.com [--premium-summary=0|1|2] [--type=full|topup|parents|base|payable|simple] [--client-id=ID] [--dry-run]';
protected $options = [
'--mail' => 'Recipient email address (required)',
'--premium-summary' => 'is_premium_summery value: 0=hide, 1=full columns, 2=Policy Name/Total only (default: 2)',
'--type' => 'Sample data type: full|topup|parents|base|payable|simple (default: full)',
'--client-id' => 'Client ID (optional; auto-picks a client with enabled template)',
'--dry-run' => 'Build mail and save HTML under writable/tmp; do not send',
];
public function run(array $params)
{
$mail = $this->optionValue('mail', $params[0] ?? null);
if (empty($mail) || ! filter_var($mail, FILTER_VALIDATE_EMAIL)) {
CLI::error('Provide a valid --mail you@example.com');
CLI::write($this->usage, 'yellow');
return;
}
$premiumSummary = (int) ($this->optionValue('premium-summary', 2));
if (! in_array($premiumSummary, [0, 1, 2], true)) {
CLI::error('--premium-summary must be 0, 1, or 2');
return;
}
$type = strtolower((string) ($this->optionValue('type', 'full')));
if (! in_array($type, ['full', 'topup', 'parents', 'base', 'payable', 'simple'], true)) {
CLI::error('--type must be one of: full, topup, parents, base, payable, simple');
return;
}
$clientId = $this->optionValue('client-id');
$dryRun = CLI::getOption('dry-run') !== null || $this->hasFlag('dry-run');
$clientModel = new ClientModel();
$clientPolicyModel = new ClientPolicyModel();
$notificationModel = new NotificationModel();
$client = $this->resolveClient($clientModel, $notificationModel, $clientId);
if ($client === null) {
return;
}
$notification = $notificationModel
->where('client_id', $client['id'])
->where('template_name', 'member_review_and_summary_mail')
->first();
if (empty($notification)) {
CLI::error("No member_review_and_summary_mail template for client #{$client['id']}");
return;
}
$wasEnabled = (int) ($notification['enabled'] ?? 0);
if ($wasEnabled !== 1) {
CLI::write('Template is disabled; temporarily enabling for this test...', 'yellow');
$notificationModel->update($notification['id'], ['enabled' => 1]);
$notification['enabled'] = 1;
}
$policies = $this->resolvePolicies($clientPolicyModel, (int) $client['id'], $type);
if ($policies === null) {
if ($wasEnabled !== 1) {
$notificationModel->update($notification['id'], ['enabled' => $wasEnabled]);
}
return;
}
$originalPremiumSummary = [];
foreach ($policies as $key => $policy) {
$originalPremiumSummary[$policy['id']] = $policy['is_premium_summery'] ?? 0;
$clientPolicyModel->update($policy['id'], ['is_premium_summery' => $premiumSummary]);
$policies[$key]['is_premium_summery'] = $premiumSummary;
}
try {
$arrayList = $this->buildSampleArrayList($type, $policies, $mail);
CLI::write('Test config:', 'yellow');
CLI::write(" client_id : {$client['id']} ({$client['client_name']})");
CLI::write(" recipient : {$mail}");
CLI::write(" premium-summary : {$premiumSummary} " . $this->premiumSummaryLabel($premiumSummary));
CLI::write(" sample type : {$type}");
CLI::write(' policy group(s) : ' . count($arrayList));
foreach ($policies as $label => $policy) {
CLI::write(" [{$label}] id={$policy['id']} type={$policy['policy_type_id']} is_addon={$policy['is_addon']}");
}
$paramsMail = [
'array_list' => $arrayList,
'client_policy_id' => array_column($policies, 'id'),
'emp_code' => 'TEST001',
'client_id' => $client['id'],
'notification' => $notification,
'common' => [
'client_id' => $client['id'],
'client_branch_id' => null,
'client_policy_id' => null,
'employee_policy_id' => null,
'employee_id' => null,
'mail_type' => 'member_review_and_summary_mail',
],
];
$wholeData = sendMailNotification::sendMailNotification('member_review_and_summary_mail', $paramsMail);
if (empty($wholeData[0]['message'] ?? null)) {
CLI::error('Mail payload was empty. Check that the notification template is enabled and sample data is valid.');
return;
}
// Force recipient to the provided test mail
$wholeData[0]['mail'] = $mail;
$wholeData[0]['bcc'] = '';
$htmlPath = WRITEPATH . 'tmp/member_review_summary_' . $premiumSummary . '_' . $type . '_' . date('Ymd_His') . '.html';
if (! is_dir(WRITEPATH . 'tmp')) {
mkdir(WRITEPATH . 'tmp', 0775, true);
}
file_put_contents($htmlPath, $wholeData[0]['message']);
CLI::write("Saved preview HTML: {$htmlPath}", 'green');
if ($dryRun) {
CLI::write('Dry-run only — email was not sent.', 'yellow');
CLI::write('Subject: ' . ($wholeData[0]['subject'] ?? ''), 'white');
return;
}
$result = MailHelper::send_email($wholeData[0]);
CLI::write('Send result:', 'yellow');
CLI::write(is_string($result) ? $result : json_encode($result));
CLI::write("Mail sent to {$mail}", 'green');
} finally {
foreach ($originalPremiumSummary as $policyId => $originalValue) {
$clientPolicyModel->update($policyId, ['is_premium_summery' => $originalValue]);
}
if ($wasEnabled !== 1) {
$notificationModel->update($notification['id'], ['enabled' => $wasEnabled]);
}
CLI::write('Restored original is_premium_summery / notification enabled flags.', 'white');
}
}
private function premiumSummaryLabel(int $value): string
{
return match ($value) {
0 => '(hide premium summary)',
1 => '(full Premium/GST columns + summary)',
2 => '(hide columns; summary Policy Name/Total only)',
default => '',
};
}
private function resolveClient(ClientModel $clientModel, NotificationModel $notificationModel, $clientId): ?array
{
if (! empty($clientId)) {
$client = $clientModel->where('id', (int) $clientId)->where('is_active', 1)->first();
if (empty($client)) {
CLI::error("Client #{$clientId} not found or inactive");
return null;
}
return $client;
}
$notification = $notificationModel
->where('template_name', 'member_review_and_summary_mail')
->where('enabled', 1)
->where('client_id >', 0)
->orderBy('id', 'DESC')
->first();
if (empty($notification['client_id'])) {
// Fallback: any template row with client_id
$notification = $notificationModel
->where('template_name', 'member_review_and_summary_mail')
->where('client_id >', 0)
->orderBy('id', 'DESC')
->first();
}
if (empty($notification['client_id'])) {
CLI::error('No client found with member_review_and_summary_mail template. Pass --client-id=ID');
return null;
}
$client = $clientModel->where('id', $notification['client_id'])->where('is_active', 1)->first();
if (empty($client)) {
CLI::error('Resolved client is missing/inactive. Pass --client-id=ID');
return null;
}
return $client;
}
/**
* @return array<string, array>|null
*/
private function resolvePolicies(ClientPolicyModel $clientPolicyModel, int $clientId, string $type): ?array
{
$policies = $clientPolicyModel
->where('client_id', $clientId)
->where('is_active', 1)
->findAll() ?? [];
if (empty($policies)) {
CLI::error("No active client_policy rows for client #{$clientId}");
return null;
}
$withPremium = [];
foreach ($policies as $policy) {
if ($this->hasPremiumConfig($policy)) {
$withPremium[] = $policy;
}
}
if (empty($withPremium)) {
CLI::error("No client_policy with active premium config for client #{$clientId}");
return null;
}
$pick = static function (array $list, ?callable $pref = null) {
if ($pref !== null) {
foreach ($list as $row) {
if ($pref($row)) {
return $row;
}
}
}
return $list[0];
};
$result = [];
if (in_array($type, ['full', 'base', 'topup', 'parents', 'simple'], true)) {
$result['main'] = $pick($withPremium, static function ($p) {
return in_array((int) ($p['is_addon'] ?? 0), [2, 3], true)
|| in_array((int) ($p['policy_type_id'] ?? 0), [1, 2, 3, 6, 7], true);
});
}
if (in_array($type, ['full', 'payable'], true)) {
$payable = $pick($withPremium, static function ($p) {
return (int) ($p['policy_type_id'] ?? 0) === 2;
});
if ((int) ($payable['policy_type_id'] ?? 0) !== 2) {
CLI::write('Warning: no policy_type_id=2 found; payable sample will use main policy and may skip payable table.', 'yellow');
}
$result['payable'] = $payable;
}
if ($type === 'payable' && empty($result['payable'])) {
CLI::error('Could not resolve a policy for payable sample type');
return null;
}
if ($type !== 'payable' && empty($result['main'])) {
CLI::error('Could not resolve a policy for sample type');
return null;
}
// Deduplicate by id while keeping labels
$unique = [];
foreach ($result as $label => $policy) {
$unique[$label] = $policy;
}
return $unique;
}
private function hasPremiumConfig(array $policy): bool
{
$policyId = (int) $policy['id'];
$typeId = (int) ($policy['policy_type_id'] ?? 0);
if (in_array($typeId, [1, 6, 7], true)) {
$row = (new PolicyPremium1Model())
->where('client_policy_id', $policyId)
->where('is_active', '1')
->first();
} else {
$row = (new PolicyPremium2Model())
->where('client_policy_id', $policyId)
->where('is_active', '1')
->first();
}
return ! empty($row);
}
/**
* Build array_list shaped like getEmpFamilybyEmpCode() groups.
*
* @param array<string, array> $policies
*/
private function buildSampleArrayList(string $type, array $policies, string $mail): array
{
$list = [];
if (isset($policies['main']) && in_array($type, ['full', 'base'], true)) {
$p = $policies['main'];
$list[] = [
$this->memberRow($p, 'Self', 'Ravi Kumar', $mail, 500000, 0, 0, 1, 0),
$this->memberRow($p, 'Spouse', 'Anita Kumar', '', 0, 0, 0, 1, 0),
$this->memberRow($p, 'Child', 'Arjun Kumar', '', 0, 0, 0, 1, 0),
];
}
// Single-policy layout matching UI mock: Health Insurance Plan + Premium/GST + summary
if (isset($policies['main']) && $type === 'simple') {
$p = $policies['main'];
$list[] = [
$this->memberRow(
$p,
'Self',
'John Doe',
$mail,
500000,
12000,
2160,
2,
0,
'Health Insurance Plan',
'E12345'
),
];
}
if (isset($policies['main']) && in_array($type, ['full', 'topup'], true)) {
$p = $policies['main'];
$list[] = [
$this->memberRow($p, 'Self', 'Ravi Kumar', $mail, 300000, 4500, 810, 2, 0, 'SI Top-up Cover'),
$this->memberRow($p, 'Spouse', 'Anita Kumar', '', 300000, 3200, 576, 2, 0, 'SI Top-up Cover'),
];
}
if (isset($policies['main']) && in_array($type, ['full', 'parents'], true)) {
$p = $policies['main'];
$list[] = [
$this->memberRow($p, 'Self', 'Ravi Kumar', $mail, 200000, 0, 0, 3, 0, 'Parent Medical Cover'),
$this->memberRow($p, 'Father', 'Suresh Kumar', '', 200000, 6000, 1080, 3, 0, 'Parent Medical Cover'),
$this->memberRow($p, 'Mother', 'Lakshmi Kumar', '', 200000, 5500, 990, 3, 0, 'Parent Medical Cover'),
];
}
if (isset($policies['payable']) && in_array($type, ['full', 'payable'], true)) {
$p = $policies['payable'];
$list[] = [
$this->memberRow($p, 'Self', 'Ravi Kumar', $mail, 400000, 2800, 504, 1, 1, 'Voluntary Top-up'),
$this->memberRow($p, 'Spouse', 'Anita Kumar', '', 400000, 2100, 378, 1, 1, 'Voluntary Top-up'),
];
}
return $list;
}
private function memberRow(
array $policy,
string $relationship,
string $name,
string $email,
float $si,
float $premium,
float $gst,
int $isAddon,
int $payableEmployee,
?string $policyName = null,
string $empCode = 'TEST001'
): array {
$dobOffsets = [
'Self' => '-38 years',
'Spouse' => '-35 years',
'Child' => '-10 years',
'Father' => '-65 years',
'Mother' => '-62 years',
];
// Match mock DOB for simple Health Insurance Plan sample
$dob = ($name === 'John Doe' && $empCode === 'E12345')
? '1985-05-15'
: date('Y-m-d', strtotime($dobOffsets[$relationship] ?? '-30 years'));
return [
'emp_id' => 90001,
'client_id' => $policy['client_id'],
'client_branch_id' => null,
'relationship' => $relationship,
'emp_code' => $empCode,
'name' => $name,
'email_corporate' => $email,
'mobile' => '9876543210',
'dob' => $dob,
'client_policy_id' => $policy['id'],
'basic_cover_si' => $si,
'premium' => $premium,
'rata_premimum' => $premium,
'gst' => $gst,
'policy_name' => $policyName ?? ('Sample Policy #' . $policy['id']),
'is_addon' => $isAddon,
'payable_employee' => $payableEmployee,
];
}
/**
* Read CLI option from CI helper or raw argv (--key=value / --key value).
*/
private function optionValue(string $name, $default = null)
{
$fromCli = CLI::getOption($name);
if ($fromCli !== null && $fromCli !== false && $fromCli !== '') {
return $fromCli;
}
$argv = $_SERVER['argv'] ?? [];
foreach ($argv as $i => $arg) {
if ($arg === '--' . $name && isset($argv[$i + 1]) && strpos((string) $argv[$i + 1], '-') !== 0) {
return $argv[$i + 1];
}
if (strpos((string) $arg, '--' . $name . '=') === 0) {
return substr((string) $arg, strlen($name) + 3);
}
}
return $default;
}
private function hasFlag(string $name): bool
{
if (CLI::getOption($name) !== null) {
return true;
}
$argv = $_SERVER['argv'] ?? [];
foreach ($argv as $arg) {
if ($arg === '--' . $name || strpos((string) $arg, '--' . $name . '=') === 0) {
return true;
}
}
return false;
}
}

File diff suppressed because it is too large Load Diff