488 lines
18 KiB
PHP
488 lines
18 KiB
PHP
<?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;
|
|
}
|
|
}
|