nhance/app/Helpers/utility_helper.php
2026-07-15 15:49:13 +05:30

2153 lines
71 KiB
PHP
Executable File

<?php
use App\Controllers\ApiServiceController;
use App\Controllers\GoogleDriveController;
use App\Models\BatchFileModel;
use App\Models\FileModel;
use App\Models\TicketMasterModel;
use App\Models\UserTeamsModel;
// File: app/Helpers/Uuid_helper.php
if (! function_exists('generate_uuid')) {
function generate_uuid($version = 4, $format = 'hex')
{
$data = random_bytes(16);
// echo $data.'<br>';
// Set version to 0100
$data[6] = chr(ord($data[6]) & 0x0f | 0x40);
// Set bits 6-7 to 10
$data[8] = chr(ord($data[8]) & 0x3f | 0x80);
// Output the 36 character UUID.
$uuid = vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
return $uuid;
}
}
if (! function_exists('change_date_format2')) {
function change_date_format2($data, $source_format, $output_format)
{
$data = trim($data);
// echo $data, $source_format, $output_format;return true;
try {
// Create DateTime object with the source format
$dateTime = DateTime::createFromFormat($source_format, $data);
// Check if the DateTime object is created successfully
if ($dateTime === false) {
$errors = DateTime::getLastErrors();
throw new Exception('Invalid date or format' . implode(', ', $errors['errors']));
}
// Format the DateTime object with the output format
$formattedDate = $dateTime->format($output_format);
return $formattedDate;
} catch (Exception $e) {
// Handle the exception (e.g., log it, show a user-friendly message)
return "Error: " . $e->getMessage();
return $data;
}
}
}
if (! function_exists('sanitize_upload_filename')) {
function sanitize_upload_filename(string $fileName): string
{
$fileName = preg_replace('/[\x00-\x1F\x7F]/u', '', $fileName);
$fileName = preg_replace('/[\x{00A0}\x{200B}-\x{200D}\x{FEFF}\x{00AD}\x{2060}\x{180E}\x{2028}\x{2029}]/u', '', $fileName);
$fileName = preg_replace('/[\/\\\\:*?"<>|;`${}()\'&!#]/', '', $fileName);
$fileName = preg_replace('/\.{2,}/', '.', $fileName);
$fileName = trim($fileName, ". \t\n\r");
if ($fileName === '' || strlen($fileName) > 200) {
$fileName = time() . '_' . bin2hex(random_bytes(8));
}
return $fileName;
}
}
if (! function_exists('validate_upload_extension')) {
function validate_upload_extension($file, array $allowedExtensions = UPLOAD_ALLOWED_EXTENSIONS): bool
{
$ext = strtolower($file->getClientExtension());
if (! in_array($ext, $allowedExtensions, true)) {
log_message('critical', '[UPLOAD_HELPER] Blocked extension: {ext} | File: {name}', [
'ext' => $ext,
'name' => $file->getClientName(),
]);
return false;
}
return true;
}
}
if (! function_exists('file_Upload')) {
function file_Upload($fileToUpload, $filepath, array $allowedExtensions = UPLOAD_ALLOWED_EXTENSIONS)
{
if ($fileToUpload !== null && $fileToUpload->isValid() && ! $fileToUpload->hasMoved()) {
if (! validate_upload_extension($fileToUpload, $allowedExtensions)) {
return "";
}
$fileName = sanitize_upload_filename($fileToUpload->getName());
$fileToUpload->move($filepath, $fileName);
return $fileName;
} else {
return "";
}
}
}
/**
* Extract original/display filename from a unique storage key.
* Unique keys are stored as: {timestamp}_{hex}_{sanitizedOriginalName}
* Legacy plain filenames are returned unchanged.
*/
if (! function_exists('storage_upload_display_name')) {
function storage_upload_display_name(?string $storedName): string
{
$storedName = (string) $storedName;
if ($storedName === '') {
return '';
}
if (preg_match('/^\d+_[a-f0-9]+_(.+)$/i', $storedName, $matches)) {
return $matches[1];
}
return $storedName;
}
}
/**
* Build a collision-safe storage filename while preserving the original name for display/download.
*/
if (! function_exists('storage_unique_upload_name')) {
function storage_unique_upload_name(string $originalName): string
{
$displayName = sanitize_upload_filename($originalName);
return time() . '_' . bin2hex(random_bytes(8)) . '_' . $displayName;
}
}
/**
* Upload via FileStorageService (S3 wrapper).
* Uses folder path last segment as the S3 folder/bucket prefix.
* Stores a unique disk/S3 key so same original names never overwrite each other.
*
* Env RETAIN_LOCAL (default false):
* - false / missing: S3-only → temp stage → upload → delete local
* - true: dual-write → keep permanent local copy under $filepath after S3 upload
*
* Processors should still use storage_ensure_local_file() when local may be missing.
*
* @param bool $retainLocal Unused; behaviour is controlled by env RETAIN_LOCAL only.
*/
if (! function_exists('storage_file_Upload')) {
function storage_file_Upload($fileToUpload, $filepath, array $allowedExtensions = UPLOAD_ALLOWED_EXTENSIONS, bool $retainLocal = false)
{
if ($fileToUpload === null || ! $fileToUpload->isValid() || $fileToUpload->hasMoved()) {
log_message('error', 'storage_file_Upload validation failed | ' . json_encode([
'filepath' => $filepath,
'reason' => $fileToUpload === null ? 'file_null' : (!$fileToUpload->isValid() ? 'invalid_file' : 'already_moved'),
'error' => (is_object($fileToUpload) && method_exists($fileToUpload, 'getErrorString')) ? $fileToUpload->getErrorString() : null,
], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
return "";
}
if (! validate_upload_extension($fileToUpload, $allowedExtensions)) {
log_message('error', 'storage_file_Upload extension rejected | ' . json_encode([
'filepath' => $filepath,
'client_name' => method_exists($fileToUpload, 'getClientName') ? $fileToUpload->getClientName() : null,
'extension' => method_exists($fileToUpload, 'getExtension') ? $fileToUpload->getExtension() : null,
'allowed_extensions' => $allowedExtensions,
], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
return "";
}
$originalName = method_exists($fileToUpload, 'getClientName') && $fileToUpload->getClientName()
? $fileToUpload->getClientName()
: $fileToUpload->getName();
$fileName = storage_unique_upload_name($originalName);
$storage = \Config\Services::getFileStorageService();
$filepath = rtrim($filepath, '/\\');
// Env controls retention; missing / empty / false => do not keep local when on S3.
$retainLocal = storage_env_retain_local();
if ($storage->usesS3()) {
if ($retainLocal) {
if (! is_dir($filepath)) {
mkdir($filepath, 0755, true);
}
$fileToUpload->move($filepath . DIRECTORY_SEPARATOR, $fileName);
$localPath = $filepath . DIRECTORY_SEPARATOR . $fileName;
$result = $storage->upload($localPath, $filepath, $fileName);
if (! ($result['success'] ?? false)) {
@unlink($localPath);
log_message('error', 'storage_file_Upload retain_local failed | ' . json_encode([
'filepath' => $filepath,
'file_name' => $fileName,
'message' => $result['message'] ?? null,
], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
return '';
}
log_message('info', 'storage_file_Upload retain_local completed | ' . json_encode([
'filepath' => $filepath,
'file_name' => $fileName,
'display_name' => storage_upload_display_name($fileName),
'retain_local' => true,
'bucket' => $storage->getBucket(),
], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
return $fileName;
}
// S3-only: stage briefly, upload, always delete local.
$tmpDir = storage_runtime_temp_dir();
if (! is_dir($tmpDir)) {
@mkdir($tmpDir, 0755, true);
}
$fileToUpload->move($tmpDir . DIRECTORY_SEPARATOR, $fileName);
$localPath = $tmpDir . DIRECTORY_SEPARATOR . $fileName;
$result = $storage->upload($localPath, $filepath, $fileName);
@unlink($localPath);
log_message(
($result['success'] ?? false) ? 'info' : 'error',
'storage_file_Upload s3_only completed | ' . json_encode([
'filepath' => $filepath,
'file_name' => $fileName,
'display_name' => storage_upload_display_name($fileName),
'success' => $result['success'] ?? false,
'key' => $result['key'] ?? null,
'message' => $result['message'] ?? null,
'bucket' => $storage->getBucket(),
'retain_local' => false,
], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)
);
return ($result['success'] ?? false) ? $fileName : '';
}
// Local-driver mode: keep file under the upload folder.
$result = $storage->upload($fileToUpload, $filepath, $fileName);
log_message(
($result['success'] ?? false) ? 'info' : 'error',
'storage_file_Upload completed | ' . json_encode([
'filepath' => $filepath,
'file_name' => $fileName,
'display_name' => storage_upload_display_name($fileName),
'success' => $result['success'] ?? false,
'key' => $result['key'] ?? null,
'url' => $result['url'] ?? null,
'message' => $result['message'] ?? null,
'bucket' => $storage->getBucket(),
'uses_s3' => $storage->usesS3(),
'retain_local' => $retainLocal,
], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)
);
return ($result['success'] ?? false) ? $fileName : "";
}
}
/**
* Read RETAIN_LOCAL from env. Default / missing / empty => false.
*/
if (! function_exists('storage_env_retain_local')) {
function storage_env_retain_local(): bool
{
$raw = env('RETAIN_LOCAL', null);
if ($raw === null || $raw === '') {
return false;
}
if (is_bool($raw)) {
return $raw;
}
return filter_var((string) $raw, FILTER_VALIDATE_BOOLEAN);
}
}
if (! function_exists('file_Upload_random_name')) {
function file_Upload_random_name($fileToUpload, $filepath, array $allowedExtensions = UPLOAD_ALLOWED_EXTENSIONS, string $namePrefix = ''): array
{
$empty = ['stored_name' => '', 'original_name' => ''];
if ($fileToUpload === null || ! $fileToUpload->isValid() || $fileToUpload->hasMoved()) {
return $empty;
}
if (! validate_upload_extension($fileToUpload, $allowedExtensions)) {
return $empty;
}
$originalName = sanitize_upload_filename($fileToUpload->getClientName() ?: $fileToUpload->getName());
$ext = strtolower($fileToUpload->getClientExtension() ?: pathinfo($originalName, PATHINFO_EXTENSION));
$namePrefix = preg_replace('/[^a-zA-Z0-9\-_]/', '', $namePrefix);
$prefix = $namePrefix !== '' ? $namePrefix . '_' : '';
$storedName = $prefix . time() . '_' . bin2hex(random_bytes(8)) . ($ext !== '' ? '.' . $ext : '');
$fileToUpload->move($filepath, $storedName);
return ['stored_name' => $storedName, 'original_name' => $originalName];
}
}
if (! function_exists('resolve_insurer_claim_form_file')) {
function resolve_insurer_claim_form_file(array $insurer): array
{
$checkedPaths = [];
$claimFormDir = WRITEPATH . 'insurer_claim_form/';
if (!empty($insurer['insurer_claim_form'])) {
$storedFileName = basename($insurer['insurer_claim_form']);
$uploadedPath = $claimFormDir . $storedFileName;
$checkedPaths[] = $uploadedPath;
if (is_file($uploadedPath)) {
return [
'available' => true,
'file_path' => $uploadedPath,
'file_name' => !empty($insurer['insurer_claim_form_original_name'])
? basename($insurer['insurer_claim_form_original_name'])
: $storedFileName,
'source' => 'uploaded',
'checked_paths' => $checkedPaths,
];
}
}
$defaultPath = $claimFormDir . INSURER_DEFAULT_CLAIM_FORM_FILE;
$checkedPaths[] = $defaultPath;
if (is_file($defaultPath)) {
return [
'available' => true,
'file_path' => $defaultPath,
'file_name' => INSURER_DEFAULT_CLAIM_FORM_FILE,
'source' => 'irdai_default',
'checked_paths' => $checkedPaths,
];
}
if (!empty($insurer['short_name'])) {
$legacyPath = ROOTPATH . 'public/claim_sample_forms/' . $insurer['short_name'] . '.pdf';
$checkedPaths[] = $legacyPath;
if (is_file($legacyPath)) {
return [
'available' => true,
'file_path' => $legacyPath,
'file_name' => $insurer['short_name'] . '.pdf',
'source' => 'legacy',
'checked_paths' => $checkedPaths,
];
}
}
return [
'available' => false,
'file_path' => null,
'file_name' => null,
'source' => null,
'checked_paths' => $checkedPaths,
];
}
}
if (! function_exists('file_Upload_for_lead')) {
function file_Upload_for_lead($fileToUpload, $filepath, array $allowedExtensions = UPLOAD_ALLOWED_EXTENSIONS)
{
if ($fileToUpload !== null && $fileToUpload->isValid() && ! $fileToUpload->hasMoved()) {
if (! validate_upload_extension($fileToUpload, $allowedExtensions)) {
return "";
}
$fileName = sanitize_upload_filename($fileToUpload->getName());
$fileToUpload->move($filepath, $fileName);
$fileName = $fileToUpload->getName();
return $fileName;
} else {
return "";
}
}
}
// if (!function_exists('multi_file_Upload')) {
// function multi_file_Upload($fileToUpload, $filepath)
// {
// $uploadedFiles = [];
// // Handle multiple files
// if (is_array($fileToUpload)) {
// foreach ($fileToUpload as $file) {
// if ($file !== null && $file->isValid() && !$file->hasMoved()) {
// $file->move($filepath);
// $fileName = $file->getName(); // safer unique name
// $uploadedFiles[] = [
// 'file_name' => $fileName,
// 'file_path' => $filepath . $fileName
// ];
// }
// }
// }
// // Handle single file
// else {
// if ($fileToUpload !== null && $fileToUpload->isValid() && !$fileToUpload->hasMoved()) {
// $fileToUpload->move($filepath);
// $fileName = $fileToUpload->getName();
// $uploadedFiles[] = [
// 'file_name' => $fileName,
// 'file_path' => $filepath . $fileName
// ];
// }
// }
// return $uploadedFiles; // always return array of files
// }
// }
// function for only using in the Flutter Claim File Upload
if (! function_exists('multi_file_Upload')) {
function multi_file_Upload($fileToUpload, $filepath, $docs_name = [], array $allowedExtensions = UPLOAD_ALLOWED_EXTENSIONS)
{
$uploadedFiles = [];
// Normalize: always work with an array of UploadedFile objects
$files = is_array($fileToUpload) ? $fileToUpload : [$fileToUpload];
foreach ($files as $file) {
// If file is itself an array (multiple under same input name)
if (is_array($file)) {
foreach ($file as $index => $f) {
if ($f !== null && $f->isValid() && ! $f->hasMoved()) {
if (! validate_upload_extension($f, $allowedExtensions)) {
continue;
}
$fileRandomName = $f->getRandomName();
$fileName = sanitize_upload_filename($f->getName());
$f->move($filepath, $fileRandomName);
$uploadedFiles[] = [
'file_name' => $fileName,
'doc_name' => $docs_name[$index] ?? $fileName,
'file_path' => $fileRandomName,
];
}
}
} else {
// Single file
if ($file !== null && $file->isValid() && ! $file->hasMoved()) {
if (! validate_upload_extension($file, $allowedExtensions)) {
continue;
}
$fileName = sanitize_upload_filename($file->getName());
$diskName = $file->getRandomName();
$file->move($filepath, $diskName);
$uploadedFiles[] = [
'file_name' => $fileName,
'file_path' => $filepath . $diskName,
];
}
}
}
return $uploadedFiles; // always return array
}
}
/**
* Claim file upload via FileStorageService (S3) with local disk copy retained
* for merge/TPA integrations during phased migration.
*/
if (! function_exists('storage_multi_file_Upload')) {
function storage_multi_file_Upload($fileToUpload, $filepath, $docs_name = [], array $allowedExtensions = UPLOAD_EXT_CLAIM_DOCS)
{
$uploadedFiles = [];
$filepath = rtrim($filepath, '/\\') . DIRECTORY_SEPARATOR;
$storage = \Config\Services::getFileStorageService();
if (! is_dir(rtrim($filepath, '/\\'))) {
mkdir(rtrim($filepath, '/\\'), 0755, true);
}
$files = is_array($fileToUpload) ? $fileToUpload : [$fileToUpload];
foreach ($files as $file) {
if (is_array($file)) {
foreach ($file as $index => $f) {
$uploaded = storage_claim_file_Upload($f, $filepath, $allowedExtensions);
if ($uploaded === '') {
continue;
}
$uploadedFiles[] = [
'file_name' => $uploaded['display_name'],
'doc_name' => $docs_name[$index] ?? $uploaded['display_name'],
'file_path' => $uploaded['disk_name'],
];
}
} else {
$uploaded = storage_claim_file_Upload($file, $filepath, $allowedExtensions);
if ($uploaded === '') {
continue;
}
$uploadedFiles[] = [
'file_name' => $uploaded['display_name'],
'doc_name' => $docs_name[0] ?? $uploaded['display_name'],
'file_path' => $uploaded['disk_name'],
];
}
}
log_message('info', 'storage_multi_file_Upload completed | ' . json_encode([
'filepath' => $filepath,
'uploaded_count' => count($uploadedFiles),
'uses_s3' => $storage->usesS3(),
'bucket' => $storage->getBucket(),
], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
return $uploadedFiles;
}
}
/**
* Single claim file upload: save locally, then mirror to S3 when enabled.
*
* @return array{display_name:string,disk_name:string}|string
*/
if (! function_exists('storage_claim_file_Upload')) {
function storage_claim_file_Upload($fileToUpload, $filepath, array $allowedExtensions = UPLOAD_EXT_CLAIM_DOCS)
{
if ($fileToUpload === null || ! $fileToUpload->isValid() || $fileToUpload->hasMoved()) {
return '';
}
if (! validate_upload_extension($fileToUpload, $allowedExtensions)) {
return '';
}
$filepath = rtrim($filepath, '/\\') . DIRECTORY_SEPARATOR;
$displayName = sanitize_upload_filename($fileToUpload->getName());
$diskName = $fileToUpload->getRandomName();
$storage = \Config\Services::getFileStorageService();
if ($storage->usesS3()) {
$tmpDir = storage_runtime_temp_dir();
if (! is_dir($tmpDir)) {
@mkdir($tmpDir, 0755, true);
}
$fileToUpload->move($tmpDir . DIRECTORY_SEPARATOR, $diskName);
$localPath = $tmpDir . DIRECTORY_SEPARATOR . $diskName;
$result = $storage->upload($localPath, rtrim($filepath, '/\\'), $diskName);
@unlink($localPath);
log_message(
($result['success'] ?? false) ? 'info' : 'error',
'storage_claim_file_Upload s3_only | ' . json_encode([
'filepath' => $filepath,
'disk_name' => $diskName,
'display_name' => $displayName,
'success' => $result['success'] ?? false,
'key' => $result['key'] ?? null,
'message' => $result['message'] ?? null,
'bucket' => $storage->getBucket(),
], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)
);
if (! ($result['success'] ?? false)) {
return '';
}
} else {
if (! is_dir($filepath)) {
@mkdir($filepath, 0755, true);
}
$fileToUpload->move($filepath, $diskName);
}
return [
'display_name' => $displayName,
'disk_name' => $diskName,
];
}
}
/**
* Build a TPA-facing download URL for a claim file.
* Prefers an S3 presigned URL; falls back to app downloadClaimFile/{id} for local mode.
*/
if (! function_exists('storage_claim_file_download_url')) {
function storage_claim_file_download_url(string $diskName, $fileId = null, int $expirationMinutes = 360): string
{
$diskName = basename(trim($diskName));
if ($diskName === '') {
return '';
}
$uploadPath = WRITEPATH . 'uploads/claim_files';
$storage = \Config\Services::getFileStorageService();
if ($storage->usesS3()) {
if (! $storage->exists($uploadPath, $diskName)) {
log_message('error', 'storage_claim_file_download_url | missing on S3 | ' . $diskName);
return '';
}
$result = $storage->getPresignedUrl($uploadPath, $diskName, max(1, $expirationMinutes));
if (($result['success'] ?? false) && ! empty($result['url'])) {
return (string) $result['url'];
}
log_message('error', 'storage_claim_file_download_url | presign failed | ' . json_encode([
'disk_name' => $diskName,
'message' => $result['message'] ?? null,
], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
return '';
}
$localPath = $storage->resolveLocalPath($uploadPath, $diskName);
if (! is_file($localPath)) {
return '';
}
if ($fileId !== null && $fileId !== '') {
return base_url('downloadClaimFile/' . $fileId);
}
return '';
}
}
/**
* Soft-delete claim_files row and remove unused local/S3 object.
*
* @return bool
*/
if (! function_exists('storage_soft_delete_claim_file')) {
function storage_soft_delete_claim_file(int $claimFileId): bool
{
if ($claimFileId <= 0) {
return false;
}
$claimFiles = new \App\Models\ClaimFilesModel();
$record = $claimFiles->find($claimFileId);
if (empty($record)) {
return false;
}
$updated = $claimFiles->update($claimFileId, ['is_active' => 0]);
if (! $updated) {
return false;
}
$diskName = basename((string) (! empty($record['url']) ? $record['url'] : ($record['file_name'] ?? '')));
if ($diskName === '') {
return true;
}
$stillUsed = $claimFiles
->where('is_active', 1)
->where('id !=', $claimFileId)
->groupStart()
->where('url', $diskName)
->orWhere('url', WRITEPATH . 'uploads/claim_files/' . $diskName)
->orWhere('file_name', $diskName)
->groupEnd()
->countAllResults();
if ($stillUsed === 0) {
$storage = \Config\Services::getFileStorageService();
$storage->delete(WRITEPATH . 'uploads/claim_files', $diskName);
}
return true;
}
}
/**
* Resolve a claim file from local/S3 into a readable local path.
*
* @return array{success:bool,path:?string,is_temp:bool,message:string}
*/
if (! function_exists('storage_resolve_claim_file_path')) {
function storage_resolve_claim_file_path(string $uploadPath, string $fileName): array
{
$empty = [
'success' => false,
'path' => null,
'is_temp' => false,
'message' => 'File not found',
];
$fileName = basename(trim($fileName));
if ($fileName === '') {
$empty['message'] = 'Invalid file name';
return $empty;
}
$storage = \Config\Services::getFileStorageService();
$uploadPath = rtrim($uploadPath, '/\\');
$localPath = $storage->resolveLocalPath($uploadPath, $fileName);
if (is_file($localPath) && is_readable($localPath)) {
return [
'success' => true,
'path' => $localPath,
'is_temp' => false,
'message' => 'Local file found',
];
}
if (! $storage->usesS3()) {
return $empty;
}
$download = $storage->download($uploadPath, $fileName);
if (! ($download['success'] ?? false)) {
$empty['message'] = (string) ($download['message'] ?? 'S3 download failed');
return $empty;
}
if (! empty($download['path']) && is_file((string) $download['path'])) {
return [
'success' => true,
'path' => (string) $download['path'],
'is_temp' => false,
'message' => 'Resolved from storage path',
];
}
$content = $download['content'] ?? null;
if (! is_string($content) || $content === '') {
$empty['message'] = 'S3 returned empty content';
return $empty;
}
$tmpDir = rtrim(WRITEPATH, '/\\') . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR . 'claim_files_runtime';
if (! is_dir($tmpDir)) {
@mkdir($tmpDir, 0755, true);
}
$tmpPath = $tmpDir . DIRECTORY_SEPARATOR . uniqid('claim_', true) . '_' . $fileName;
$written = @file_put_contents($tmpPath, $content);
if ($written === false || ! is_file($tmpPath)) {
$empty['message'] = 'Failed to write temp file';
return $empty;
}
storage_register_temp_file($tmpPath);
return [
'success' => true,
'path' => $tmpPath,
'is_temp' => true,
'message' => 'Resolved from S3 content',
];
}
}
if (! function_exists('storage_cleanup_temp_claim_file')) {
function storage_cleanup_temp_claim_file(array $resolved): void
{
if (($resolved['success'] ?? false) && ($resolved['is_temp'] ?? false) && ! empty($resolved['path'])) {
storage_cleanup_temp_file((string) $resolved['path']);
}
}
}
/**
* Runtime temp directory for S3→local staging (never a permanent upload folder).
*/
if (! function_exists('storage_runtime_temp_dir')) {
function storage_runtime_temp_dir(): string
{
return rtrim(WRITEPATH, '/\\') . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR . 'storage_runtime';
}
}
/**
* Register a temp path for automatic cleanup at request/CLI shutdown.
*
* @var list<string>|null
*/
if (! function_exists('storage_register_temp_file')) {
function storage_register_temp_file(string $path): void
{
static $registered = [];
static $shutdownRegistered = false;
$path = (string) $path;
if ($path === '' || in_array($path, $registered, true)) {
return;
}
$registered[] = $path;
if (! $shutdownRegistered) {
$shutdownRegistered = true;
register_shutdown_function(static function () use (&$registered): void {
foreach ($registered as $tmp) {
storage_cleanup_temp_file($tmp);
}
$registered = [];
});
}
}
}
/**
* Delete a temp runtime file (storage_runtime / claim_files_runtime only).
*/
if (! function_exists('storage_cleanup_temp_file')) {
function storage_cleanup_temp_file(?string $path): void
{
if ($path === null || $path === '' || ! is_file($path)) {
return;
}
$real = realpath($path);
if ($real === false) {
@unlink($path);
return;
}
$allowed = [];
foreach ([storage_runtime_temp_dir(), rtrim(WRITEPATH, '/\\') . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR . 'claim_files_runtime'] as $dir) {
if (! is_dir($dir)) {
@mkdir($dir, 0755, true);
}
$resolvedDir = realpath($dir);
if ($resolvedDir !== false) {
$allowed[] = $resolvedDir;
}
}
foreach ($allowed as $root) {
if (strpos($real, rtrim($root, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR) === 0) {
@unlink($real);
return;
}
}
}
}
/**
* Resolve a mail-template attachment to a readable local path (local first, else S3→temp).
*/
if (! function_exists('storage_resolve_mail_attachment_path')) {
function storage_resolve_mail_attachment_path(?string $relativePath, ?string $fileName = null): array
{
$name = basename((string) ($fileName ?: $relativePath));
if ($name === '') {
return ['success' => false, 'path' => null, 'is_temp' => false, 'display_name' => ''];
}
$uploadDir = WRITEPATH . 'uploads/attachments';
$legacyPath = $relativePath ? (WRITEPATH . ltrim(str_replace('\\', '/', $relativePath), '/')) : null;
if ($legacyPath && is_file($legacyPath)) {
return [
'success' => true,
'path' => $legacyPath,
'is_temp' => false,
'display_name' => storage_upload_display_name($name),
];
}
$resolved = storage_resolve_claim_file_path($uploadDir, $name);
$resolved['display_name'] = storage_upload_display_name($name);
if (($resolved['success'] ?? false) && ($resolved['is_temp'] ?? false) && ! empty($resolved['path'])) {
storage_register_temp_file((string) $resolved['path']);
}
return $resolved;
}
}
/**
* Ensure a file exists on local disk for job processors.
* Local first (legacy leftovers); if missing and S3 has it, download into
* writable/cache/storage_runtime/ (temp) and auto-clean at request shutdown.
*/
if (! function_exists('storage_ensure_local_file')) {
function storage_ensure_local_file(string $uploadPath, string $fileName): ?string
{
$fileName = basename(trim($fileName));
if ($fileName === '') {
return null;
}
$storage = \Config\Services::getFileStorageService();
$localPath = $storage->resolveLocalPath($uploadPath, $fileName);
if (is_file($localPath) && is_readable($localPath)) {
return $localPath;
}
if (! $storage->usesS3()) {
return null;
}
$result = $storage->download($uploadPath, $fileName);
if (! ($result['success'] ?? false)) {
return null;
}
$content = $result['content'] ?? null;
if (! is_string($content) || $content === '') {
// download() may have returned a local path already
if (! empty($result['path']) && is_file((string) $result['path'])) {
$existing = (string) $result['path'];
// If path is already under runtime, register cleanup; else leave as-is.
storage_register_temp_file($existing);
return $existing;
}
return null;
}
$tmpDir = storage_runtime_temp_dir();
if (! is_dir($tmpDir)) {
@mkdir($tmpDir, 0755, true);
}
$tmpPath = $tmpDir . DIRECTORY_SEPARATOR . uniqid('stor_', true) . '_' . $fileName;
if (@file_put_contents($tmpPath, $content) === false || ! is_file($tmpPath)) {
return null;
}
storage_register_temp_file($tmpPath);
return $tmpPath;
}
}
/**
* After generating a local workbook, mirror to S3 (when enabled) and remove local permanent copy.
*/
if (! function_exists('storage_mirror_generated_file')) {
function storage_mirror_generated_file(string $localPath, string $uploadPath, string $fileName): bool
{
if (! is_file($localPath)) {
return false;
}
$storage = \Config\Services::getFileStorageService();
if (! $storage->usesS3()) {
return true;
}
$result = $storage->upload($localPath, rtrim($uploadPath, '/\\'), $fileName);
@unlink($localPath);
return (bool) ($result['success'] ?? false);
}
}
if (! function_exists('file_unlink')) {
function file_unlink($filepath)
{
if (is_file($filepath) && file_exists($filepath)) {
unlink($filepath);
}
}
}
if (! function_exists('compressImage')) {
function compressImage($file, $destinationPath, $newWidth = 100, $newHeight = 100)
{
// Load the image manipulation library
$image = \Config\Services::image();
// Resize and compress the image
$image->withFile($file)
->fit($newWidth, $newHeight, 'center')
->save($destinationPath);
return true;
}
}
if (! function_exists('fancy_date_time_format')) {
function fancy_date_time_format($datetime, $return_type = 'fancy')
{
date_default_timezone_set('Asia/Kolkata');
$currentDateTime = new DateTime();
$passedDateTime = new DateTime($datetime);
// Calculate the interval between the current time and the passed datetime
$interval = $currentDateTime->diff($passedDateTime);
// If the interval is more than 1 month or the year is different, return the original datetime
if ($interval->m > 1 || $interval->y != 0) {
if ($return_type == 'fancy') {
return change_date_format($datetime, 'Y-m-d H:i:s', 'd M Y h:i a');
}
return $datetime;
} elseif ($interval->m == 1 && $interval->y == 0) {
return "1 month ago";
} elseif ($interval->d >= 7) {
$weeks = floor($interval->d / 7);
return $weeks == 1 ? "1 week ago" : "$weeks weeks ago";
} elseif ($interval->d >= 1) {
return $interval->d == 1 ? "1 day ago" : $interval->d . " days ago";
} elseif ($interval->h >= 1) {
return $interval->h == 1 ? "1 hour ago" : $interval->h . " hours ago";
} elseif ($interval->i >= 1) {
return $interval->i == 1 ? "1 minute ago" : $interval->i . " minutes ago";
} else {
return "Just now";
}
}
}
if (! function_exists('check_string_date')) {
function check_string_date($str)
{
if (DateTime::createFromFormat('Y-m-d H:i:s', $str) !== false) {
return true;
}
return false;
}
}
if (! function_exists('generate_download_link')) {
function generate_download_link($rand_string)
{
// Generate the link using provided emp_code and client_policy_id
$link = htmlspecialchars(base_url('download-e-card/' . $rand_string));
// Return the link wrapped in anchor tag
// return '<a href="' . $link . '" target="_blank">Click To </a>';
return $link;
}
}
if (! function_exists('generate_random_alphanumeric')) {
function generate_random_alphanumeric($length = 12)
{
$random_string = '';
for ($i = 0; $i < $length; $i++) {
$random_ascii = rand(0, 61);
if ($random_ascii < 10) {
$random_character = chr($random_ascii + 48);
} elseif ($random_ascii < 36) {
$random_character = chr($random_ascii + 55);
} else {
$random_character = chr($random_ascii + 61);
}
$random_string .= $random_character;
}
return $random_string;
}
}
if (! function_exists('get_base64_image')) {
function get_base64_image($path)
{
// Get file extension
$type = pathinfo($path, PATHINFO_EXTENSION);
// Read file content
$dataContent = file_get_contents($path);
// Encode as base64
$base64Image = 'data:image/' . $type . ';base64,' . base64_encode($dataContent);
return $base64Image;
}
}
if (! function_exists('format_indian_number')) {
function format_indian_number($number)
{
// Round the number to two decimal places
$number = isset($number) ? $number : 0;
$number = round($number, 2);
// Split the number into integer and decimal parts
$numberParts = explode('.', number_format($number, 2, '.', ''));
$integerPart = $numberParts[0];
$decimalPart = isset($numberParts[1]) ? $numberParts[1] : '00';
// Format the integer part with commas
$length = strlen($integerPart);
$formattedStr = '';
$counter = 0;
for ($i = $length - 1; $i >= 0; $i--) {
$formattedStr = $integerPart[$i] . $formattedStr;
$counter++;
if ($counter == 3 && $i != 0) {
$formattedStr = ',' . $formattedStr;
$counter = 0;
} elseif ($counter == 2 && $i != 0 && $length - $i > 3) {
$formattedStr = ',' . $formattedStr;
$counter = 0;
}
}
// Combine the integer and decimal parts
return $formattedStr . '.' . $decimalPart;
}
}
if (! function_exists('get_username')) {
function get_username($user_id)
{
// Connect to the database
$db = \Config\Database::connect();
// Query the database
$query = $db->table('user_profiles')
->select('first_name')
->where('id', $user_id)
->get();
// Get the result
$result = $query->getRow();
// Return the username if found, otherwise return null
return $result ? $result->first_name : null;
}
}
if (! function_exists('get_role_id')) {
function get_role_id()
{
$role_id = isset(get_session_userdata()->role) ? get_session_userdata()->role : null;
return $role_id;
}
}
if (! function_exists('teams')) {
function teams()
{
// Load the UserTeamsModel
$teamModel = new \App\Models\UserTeamsModel();
// Get the user ID from the session
$user_id = get_session_userid();
// Fetch the team IDs associated with the user
$user_teams = $teamModel->select('team_id')->where('user_id', $user_id)->findAll();
// Debugging: Log or print the query result to check its structure
// var_dump($user_teams); // You can use this temporarily for testing
// log_message('info', 'User Teams: ' . json_encode($user_teams)); // Optionally log it
// Check if the result is not empty
if (! empty($user_teams)) {
// Extract only the 'team_id' values
$team_ids = array_column($user_teams, 'team_id');
return $team_ids; // Return array of team IDs
} else {
return []; // Return empty array if no teams found
}
}
}
if (! function_exists('generate_client_code')) {
function generate_client_code($string = 'GC')
{
$clientModel = new \App\Models\ClientModel();
$latestClient = $clientModel->select('id')->orderBy('id', 'DESC')->first();
$id = $latestClient ? $latestClient['id'] : 0;
$year = date('y');
$newId = $id + 1;
$client_code = $year . $string . $newId;
return $client_code;
}
}
if (! function_exists('generate_tsi_code')) {
function generate_tsi_code($type)
{
$PolicyTransactionModel = new \App\Models\PolicyTransactionModel();
$latestClient = $PolicyTransactionModel->select('id')->orderBy('id', 'DESC')->first();
$id = $latestClient ? $latestClient['id'] : 0;
$year = date('y');
$month = date('m');
$string = 'P';
if ($type == 2) {
$string2 = 'R';
} else {
$string2 = 'F';
}
$newId = $id + 1;
$tsi_code = $string2 . $month . $year . $string . $newId;
return $tsi_code;
}
}
if (! function_exists('generateRandomCode')) {
function generateRandomCode($prefix = 'RTL-', $length = 6)
{
// Generate a random number with the specified length
$randomNumber = str_pad(mt_rand(0, pow(10, $length) - 1), $length, '0', STR_PAD_LEFT);
// Return the code with the prefix
return $prefix . $randomNumber;
}
}
if (! function_exists('excelFileGDriveUpload')) {
function excelFileGDriveUpload($file_id, $table_name)
{
$doc_type = "UPLOADS";
$uploadFilePath = WRITEPATH . 'uploads/' . ($table_name == 'batch_file' ? 'import_excel' : 'excel');
$models = [
'batch_file' => [
'model' => new BatchFileModel(),
'select' => "client_id, client_policy_id, file_name",
],
'files' => [
'model' => new FileModel(),
'select' => "client_id, policy_id as client_policy_id, file_name",
],
];
if (! array_key_exists($table_name, $models)) {
return;
}
// Retrieve data
$data = $models[$table_name]['model']
->select($models[$table_name]['select'])
->where('id', $file_id)
->where('is_active', 1)
->first();
if ($data) {
$resolved = storage_ensure_local_file($uploadFilePath, $data['file_name']);
if (empty($resolved) || ! is_file($resolved)) {
return;
}
$uploadFilePath = $resolved;
$GoogleDriveController = new GoogleDriveController();
$result = $GoogleDriveController->uploadFiletoGdrive(
// client_id : $data['client_id'],
client_policy_id: $data['client_policy_id'],
doc_type: $doc_type,
file_path: $uploadFilePath,
file_name: $data['file_name']
);
// dd($result);
return true;
} else {
return false;
}
}
}
if (! function_exists('checkFamilyFloaters')) {
function checkFamilyFloaters($policy_premium_data, $client_policy_data, $emp_data)
{
if ($policy_premium_data['premium_type'] == 1) {
//only family floater
if ($emp_data['relationship'] == 'Self') {
return true;
}
if ($client_policy_data['policy_type_id'] == 3 && $client_policy_data['is_addon'] == 3) {
if ($emp_data['rata_premimum'] > 0) {
return true;
} else {
return false;
}
}
return false;
} else {
//individual
return true;
}
}
}
if (! function_exists('numberToWords')) {
function numberToWords($number)
{
$words = [
'0' => 'Zero',
'1' => 'One',
'2' => 'Two',
'3' => 'Three',
'4' => 'Four',
'5' => 'Five',
'6' => 'Six',
'7' => 'Seven',
'8' => 'Eight',
'9' => 'Nine',
'10' => 'Ten',
'11' => 'Eleven',
'12' => 'Twelve',
'13' => 'Thirteen',
'14' => 'Fourteen',
'15' => 'Fifteen',
'16' => 'Sixteen',
'17' => 'Seventeen',
'18' => 'Eighteen',
'19' => 'Nineteen',
'20' => 'Twenty',
'30' => 'Thirty',
'40' => 'Forty',
'50' => 'Fifty',
'60' => 'Sixty',
'70' => 'Seventy',
'80' => 'Eighty',
'90' => 'Ninety',
];
if ($number < 21) {
return $words[$number];
}
if ($number < 100) {
$tens = (int) ($number / 10) * 10;
$units = $number % 10;
return $words[$tens] . ($units ? ' ' . $words[$units] : '');
}
if ($number < 1000) {
$hundreds = (int) ($number / 100);
$remainder = $number % 100;
return $words[$hundreds] . ' Hundred' . ($remainder ? ' and ' . numberToWords($remainder) : '');
}
$levels = ['', ' Thousand', ' Million', ' Billion', ' Trillion', ' Quadrillion', ' Quintillion'];
for ($i = 0, $unit = 1; $i < count($levels); $i++, $unit *= 1000) {
if ($number < $unit * 1000) {
$current = (int) ($number / $unit);
$remainder = $number % $unit;
return numberToWords($current) . $levels[$i] . ($remainder ? ' ' . numberToWords($remainder) : '');
}
}
return $number; // Fallback for numbers beyond the supported range
}
}
if (! function_exists('print_rr')) {
function print_rr($data)
{
echo "<pre>";
print_r($data);
echo "</pre>";
}
}
if (! function_exists('get_server_details')) {
/**
* Get the hostname and server name.
*
* @return array
*/
function get_server_details(): array
{
$hostname = gethostname(); // Get the hostname of the server
$serverName = $_SERVER['SERVER_NAME'] ?? 'Unknown'; // Get the server name
return [
'hostname' => $hostname,
'server_name' => $serverName,
];
}
}
if (! function_exists('isJsonString')) {
function isJsonString($input)
{
json_decode($input); // Decode the string
return (json_last_error() === JSON_ERROR_NONE); // Check if the last JSON error is "no error"
}
}
if (! function_exists('isValidDate')) {
function isValidDate($date, $format)
{
$parsed_date = DateTime::createFromFormat($format, $date);
return $parsed_date && $parsed_date->format($format) === $date;
}
}
if (! function_exists('change_date_format')) {
function change_date_format($date_str, $source_format = null, $output_format = 'Y-m-d')
{
$date_str = trim($date_str);
// Allowed date formats
$allowed_formats = [
// ISO 8601 datetime (must come before plain Y-m-d to avoid partial match issues)
'Y-m-d\TH:i:sP', // 2025-07-26T00:00:00+05:30
'Y-m-d\TH:i:s\Z', // 2025-07-26T00:00:00Z
'Y-m-d\TH:i:s', // 2025-07-26T00:00:00
// Day Month Year (clear unambiguous formats)
'd M Y', // 01 Dec 2024
'd-M-Y', // 01-Dec-2024
'd/M/Y', // 01/Dec/2024
'd.M.Y', // 01.Dec.2024
'd,M,Y', // 01,Dec,2024
// Month Day Year (clear unambiguous formats)
'M d Y', // Dec 01 2024
'M-d-Y', // Dec-01-2024
'M/d/Y', // Dec/01/2024
'M.d.Y', // Dec.01.2024
'M,d,Y', // Dec,01,2024
// Year Month Day (clear unambiguous formats)
'Y M d', // 2024 Dec 01
'Y-M-d', // 2024-Dec-01
'Y/M/d', // 2024/Dec/01
'Y.M.d', // 2024.Dec.01
'Y,M,d', // 2024,Dec,01
// Year Numeric Month Numeric Day
'Y-m-d', // 2024-12-01
'Y/m/d', // 2024/12/01
'Y.m.d', // 2024.12.01
'Y,m,d', // 2024,12,01
'd/m/Y', // 01/01/2025
'd-m-Y', // 01-01-2025
'm/d/Y h:i:s A', // 01-01-2025
'm/d/Y', // 25-05-2025
];
try {
// Case 1: Source and Output formats are provided
if ($source_format !== null && $output_format !== null) {
$date = DateTime::createFromFormat($source_format, $date_str);
if (! $date) {
// throw new Exception("Invalid date string for source format: $source_format");
// log_message('error', "❌ Date format error : Invalid date string | Params => date_str: {$date_str}, source_format: {$source_format}, output_format: {$output_format}");
return null;
}
return $date->format($output_format);
}
// Case 2: Source format is provided, Output format is null
if ($source_format !== null && $output_format === null) {
$date = DateTime::createFromFormat($source_format, $date_str);
if (! $date) {
// throw new Exception("Invalid date string for source format: $source_format");
// log_message('error', "❌ Date format error : Invalid date string | Params => date_str: {$date_str}, source_format: {$source_format}, output_format: {$output_format}");
return null;
}
return $date->format('Y-m-d'); // MySQL default format
}
// Case 3: Source format is null, auto-detect format
if ($source_format === null) {
foreach ($allowed_formats as $format) {
if (isValidDate($date_str, $format)) {
$date = DateTime::createFromFormat($format, $date_str);
return $date->format($output_format); // Default is MySQL format
}
}
// If no format matches, throw an exception
$allowed_placeholders = implode(', ', $allowed_formats);
// throw new Exception("Invalid date string format. Allowed formats: $allowed_placeholders");
// log_message(
// 'error',
// "❌ Date format error: Invalid date string. Allowed formats: {$allowed_placeholders} | Params => date_str: {$date_str}, source_format: {$source_format}, output_format: {$output_format}"
// );
return null;
}
} catch (Exception $e) {
// return "Error: " . $e->getMessage();
// log_message('error', "❌ Date format error: {$e->getMessage()} | Params => date_str: {$date_str}, source_format: {$source_format}, output_format: {$output_format}");
return null;
}
return null;
}
}
// if (!function_exists('check_pay_by_employee_or_company'))
// {
// function check_pay_by_employee_or_company($is_payable_employee = null, $relationship = null) {
// $relationship = strtolower(str_replace(" ", "_", $relationship));
// $result = 0;
// if($relationship == 'self'){
// $result = $is_payable_employee['self'] == 1 ? 1 : 0;
// }else if($relationship == 'spouse'){
// $result = $is_payable_employee['spouse'] == 1 ? 1 : 0;
// }else if(in_array($relationship, ['son', 'daughter'])){
// $result = $is_payable_employee['childern'] == 1 ? 1 : 0;
// }else if(in_array($relationship, ['father', 'mother', 'father_in_law', 'mother_in_law'])){
// $result = $is_payable_employee['elders'] == 1 ? 1 : 0;
// }
// return $result;
// }
// }
if (! function_exists('check_pay_by_employee_or_company')) {
function check_pay_by_employee_or_company($policy_terms = null, $relationship = null)
{
// dd($policy_terms, $relationship);
if (! $policy_terms || ! ($policy_terms = json_decode($policy_terms, true))) {
return 0;
}
// dd($policy_terms, $relationship);
if (! isset($policy_terms['is_payable_employee'])) {
return 0;
}
$is_payable_employee = $policy_terms['is_payable_employee'];
$relationship = strtolower(str_replace(" ", "_", $relationship));
// dd($is_payable_employee, $relationship);
$relationshipMap = [
'self' => 'self',
'spouse' => 'spouse',
'son' => 'childern',
'daughter' => 'childern',
'father' => 'elders',
'mother' => 'elders',
'father_in_law' => 'elders',
'mother_in_law' => 'elders',
];
if (array_key_exists($relationship, $relationshipMap)) {
$key = $relationshipMap[$relationship];
return isset($is_payable_employee[$key]) && $is_payable_employee[$key] == 1 ? 1 : 0;
}
return 0;
}
}
if (! function_exists('is_json_string')) {
function is_json_string($string)
{
if (! is_string($string)) {
return false;
}
$decoded = json_decode($string, true);
return (json_last_error() === JSON_ERROR_NONE && is_array($decoded));
}
}
if (! function_exists('check_cd_entry_exist')) {
function check_cd_entry_exist($params)
{
$db = db_connect();
$client_id = $params['client_id'];
$client_policy_id = $params['client_policy_id'];
$insurer_id = $params['insurer_id'];
$cd_ac_pk = $params['cd_ac_pk'];
$event_name = $params['event_name'];
// Check if truncated entry (sub_type = 8) exists
$has_truncated = $db->table('cash_deposit')
->where('client_id', $client_id)
->where('insurer_id', $insurer_id)
->where('cd_ac_pk', $cd_ac_pk)
->where('client_policy_id', $client_policy_id)
->where('event_name', $event_name)
->where('sub_type', 8)
->where('is_active', 1)
->countAllResults();
if ($has_truncated) {
echo "has_truncated";
// Get all entries with same details (including truncated)
$entries = $db->table('cash_deposit')
->where('client_id', $client_id)
->where('insurer_id', $insurer_id)
->where('cd_ac_pk', $cd_ac_pk)
->where('client_policy_id', $client_policy_id)
->where('event_name', $event_name)
->where('is_active', 1)
->where('sub_type !=', 8)
->get()
->getResultArray();
if (count($entries) > 1) {
// Only one entry found (truncated)
return true;
} else {
return false;
}
} else {
// Check if any other entry exists
$entry = $db->table('cash_deposit')
->where('client_id', $client_id)
->where('insurer_id', $insurer_id)
->where('cd_ac_pk', $cd_ac_pk)
->where('client_policy_id', $client_policy_id)
->where('event_name', $event_name)
->where('is_active', 1)
->get()
->getRowArray();
if (! empty($entry)) {
return true;
}
}
return false;
}
}
if (! function_exists('expected_amount_calc')) {
function expected_amount_calc($data, $index)
{
$agreed_amount = (float) ($data['agreed_amount'][$index] ?? 0);
$agreed_bp_per = (float) ($data['agreed_bp'][$index] ?? 0);
$agreed_tp_per = (float) ($data['agreed_tp'][$index] ?? 0);
$agreed_tep_per = (float) ($data['agreed_ter'][$index] ?? 0);
$standard_bp_per = (float) ($data['standard_bp'][$index] ?? 0);
$standard_tp_per = (float) ($data['standard_tp'][$index] ?? 0);
$standard_tep_per = (float) ($data['standard_ter'][$index] ?? 0);
if ($data['bro_payable_by'] == 0) {
$base_premium = (float) ($data['co_premium'][$index] ?? 0);
$third_part_premium = (float) ($data['co_tp_premium'][$index] ?? 0);
$terrisom_premium = (float) ($data['co_ter_premium'][$index] ?? 0);
} else {
$base_premium = (float) ($data['base_premium'][$index] ?? 0);
$third_part_premium = (float) ($data['tp_premium'][$index] ?? 0);
$terrisom_premium = (float) ($data['ter_premium'][$index] ?? 0);
}
$sum_of_agreed_premium = $agreed_bp_per + $agreed_tp_per + $agreed_tep_per;
$expectedAmount = 0;
if ($agreed_amount > 0) {
$expectedAmount = $agreed_amount;
} elseif ($sum_of_agreed_premium > 0) {
$expectedAmount =
($base_premium * $agreed_bp_per / 100) +
($third_part_premium * $agreed_tp_per / 100) +
($terrisom_premium * $agreed_tep_per / 100);
} else {
$expectedAmount =
($base_premium * $standard_bp_per / 100) +
($third_part_premium * $standard_tp_per / 100) +
($terrisom_premium * $standard_tep_per / 100);
}
return round($expectedAmount, 2); // Optional: round to 2 decimal places
}
}
if (! function_exists('getFileIfExists')) {
function getFileIfExists($path)
{
return file_exists(FCPATH . $path) ? base_url($path) : '';
}
}
if (! function_exists('removeNumberFormatting')) {
function removeNumberFormatting($number)
{
return (float) str_replace(',', '', trim($number));
}
}
if (! function_exists('formatKey')) {
function formatKey($key, $len = 3)
{
$words = explode('_', $key);
$formatted = array_map(function ($word) use ($len) {
return strlen($word) < $len ? strtoupper($word) : ucfirst(strtolower($word));
}, $words);
return implode(' ', $formatted);
}
}
if (! function_exists('getMimeTypeByFileName')) {
function getMimeTypeByFileName($file_name)
{
$ext = strtolower(pathinfo($file_name, PATHINFO_EXTENSION));
$mime_types = [
'pdf' => 'application/pdf',
'jpg' => 'image/jpeg',
'jpeg' => 'image/jpeg',
'png' => 'image/png',
'gif' => 'image/gif',
'doc' => 'application/msword',
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'xls' => 'application/vnd.ms-excel',
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'csv' => 'text/csv',
'txt' => 'text/plain',
'zip' => 'application/zip',
'rar' => 'application/x-rar-compressed',
'json' => 'application/json',
];
return $mime_types[$ext] ?? 'application/octet-stream'; // default fallback
}
}
if (! function_exists('validateExcelFile')) {
function validateExcelFile($file)
{
// 1. Check if the file was uploaded without errors
if (! $file->isValid() || $file->hasMoved()) {
return false;
}
// 2. Size check (16MB)
if ($file->getSizeByUnit('mb') > 16) {
return false;
}
// 3. Define allowed types
$allowedMimes = [
'application/vnd.ms-excel',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'application/vnd.oasis.opendocument.spreadsheet',
'application/zip',
'application/octet-stream',
];
$allowedExtensions = ['xls', 'xlsx', 'ods', 'xlsm'];
// Get the actual values using CI4 methods
$mime = $file->getClientMimeType();
$extension = $file->getExtension(); // This is the CI4 method
// 4. Validate
if (in_array($mime, $allowedMimes) || in_array($extension, $allowedExtensions)) {
return true;
}
return false;
}
}
if (! function_exists('generate_ecard_download_link_based_on_tpa')) {
function generate_ecard_download_link_based_on_tpa($params)
{
$apiServiceController = new ApiServiceController();
$data = $apiServiceController->ecardRequest($params, $return_type = 'internal');
log_message('error', 'E-card request call from the helper for mail send');
if (isset($data['eCardDownload']) && ! empty($data['eCardDownload'])) {
return $data['eCardDownload'];
} else {
return $data['message'];
}
}
}
if (! function_exists('canSendOtp')) {
function canSendOtp(array $row, int $limitSeconds = 60): array
{
// If OTP does not exist → allow
if (empty($row['otp']) || empty($row['updated_at'])) {
return ['allowed' => true];
}
$lastUpdated = strtotime($row['updated_at']);
$currentTime = time();
// Calculate expiry time
$allowedAfter = $lastUpdated + $limitSeconds;
// If still within limit → block
if ($currentTime < $allowedAfter) {
return [
'allowed' => false,
'retry_after' => $allowedAfter - $currentTime,
];
}
return ['allowed' => true];
}
}
if (! function_exists('checkDuplicateClaim')) {
function checkDuplicateClaim(array $params): bool
{
$ticketMaster = new TicketMasterModel();
$query = $ticketMaster->where('is_active', 1);
if (empty($params['doa']) && empty($params['claim_amount'])) {
return false;
}
$hasValidCondition = false;
foreach ($params as $key => $value) {
if ($value !== null && $value !== '') {
$query->where($key, $value);
$hasValidCondition = true;
}
}
if (! $hasValidCondition) {
return false;
}
$result = $query->countAllResults();
// print_r($ticketMaster->getLastQuery()->getQuery()); die;
if ($result > 0) {return true;} else {return false;}
}
}
function getRealClientIP()
{
$request = service('request');
if (! empty($_SERVER['HTTP_CF_CONNECTING_IP'])) {
return $_SERVER['HTTP_CF_CONNECTING_IP'];
}
if (! empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
return explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'])[0];
}
return $request->getIPAddress();
}
function generateFingerprint(bool $exclude_ua = false): string
{
$request = service('request');
$ua = $request->getUserAgent()->getAgentString();
$ip = getRealClientIP();
// Normalize localhost
if ($ip === '127.0.0.1' || $ip === '::1') {
$ipGroup = 'localhost';
}
// IPv4 handling
elseif (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
$parts = explode('.', $ip);
// Use /24 subnet (first 3 octets)
$ipGroup = $parts[0] . '.' . $parts[1] . '.' . $parts[2];
}
// IPv6 handling
elseif (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
// Use first 4 blocks of IPv6 (rough /64 grouping)
$blocks = explode(':', $ip);
$ipGroup = implode(':', array_slice($blocks, 0, 4));
}
// Fallback
else {
$ipGroup = 'unknown';
}
if ($exclude_ua) {
return hash('sha256', $ipGroup);
}
return hash('sha256', $ua . '|' . $ipGroup);
}
if (! function_exists('convertGoogleDriveToDownloadLink')) {
function convertGoogleDriveToDownloadLink(?string $url): ?string
{
if (empty($url)) {
return null;
}
// Trim spaces
$url = trim($url);
// Pattern to extract Google Drive file ID
$patterns = [
'#https?://drive\.google\.com/file/d/([^/]+)/?#',
'#https?://drive\.google\.com/open\?id=([^&]+)#',
'#https?://drive\.google\.com/uc\?id=([^&]+)#',
];
foreach ($patterns as $pattern) {
if (preg_match($pattern, $url, $matches)) {
$fileId = $matches[1];
// Return direct download link
return 'https://drive.google.com/uc?export=download&id=' . $fileId;
}
}
// Not a Google Drive link → return original
return $url;
}
}
if (! function_exists('get_cd_balance')) {
function get_cd_balance(): array
{
$session = session();
return [
'has_cd_balance' => $session->has('cd_balance'),
'cd_balance' => $session->get('cd_balance') ?? null,
'hr_data' => $session->get('hr_data') ?? [],
'cd_balance_info' => $session->get('cd_balance_info') ?? [],
];
}
}
if (! function_exists('clear_cd_balance_session')) {
function clear_cd_balance_session(): void
{
$session = session();
$session->remove('cd_balance');
$session->remove('hr_data');
$session->remove('cd_balance_info');
log_message('error', 'clear_cd_balance_session clered');
}
}
if (! function_exists('format_gender_v2')) {
function format_gender_v2($gender)
{
if (empty($gender)) {
return null;
}
$g = strtoupper(trim($gender));
// Direct-ah check pannuvom
if (str_starts_with($g, 'M')) {
return 'M';
}
// Male, M
if (str_starts_with($g, 'F')) {
return 'F';
}
// Female, F
// Others, Transgender, O - ivatrai 'O' ena return seiyum
if (str_starts_with($g, 'O') || str_starts_with($g, 'T')) {
return 'O';
}
return $g; // Vera ethuvum illaiyengil original-aiye return pannum
}
}
if (! function_exists('map_relationship')) {
/**
* Employee -> self, WIFE -> spouse ena maatri return seiyum.
*/
function map_relationship($relation)
{
if (empty($relation)) {
return '';
}
// Case prechanai varaamal irukka lowercase-kku maatri check seivom
$r = strtolower(trim($relation));
if ($r == 'employee') {
return 'self';
} else if ($r == 'wife') {
return 'spouse';
}
// Matra anaithu relationship-um iruppathu polave (Original-aga) return aagum
return $relation;
}
}
/**
* Extract identity from POST body or GET params.
* Looks for 'email' or 'mobile_number'.
*/
function resolveIdentity($request): ?string
{
// Try POST body first
$email = $request->getPost('email');
// print_r($email);die;
$mobile = $request->getPost('mobile_number');
// Fallback to GET params
if (! $email && ! $mobile) {
$email = $request->getGet('email');
$mobile = $request->getGet('mobile_number');
}
// Fallback to JSON params
if (! $email && ! $mobile) {
$req_data = $request->getJSON();
// print_r( $req_data);
$mobile = $req_data->mobile_number ?? null;
// return trim($mobile_number);
$email = $req_data->email ?? null;
if (! $email) {
$email = $req_data->email_id ?? null;
}
// return trim($email);
}
if ($email) {
return strtolower(trim($email));
}
if ($mobile) {
return trim($mobile);
}
return null;
}
function recordRateLimitFailure(string $context = 'authApi'): void
{
/** @var IncomingRequest $request */
$request = \Config\Services::request();
$limiter = \Config\Services::limiter(); // or your custom limiter service
$fingerprint = $request->getVar('rateLimitFingerprint') ?? generateFingerprint(exclude_ua: true);
$identity = $request->getVar('rateLimitIdentity') ?? resolveIdentity($request);
// Record IP-level failure
$limiter->recordIpFailure($fingerprint);
// Record user-level failure
if (! empty($identity)) {
$limiter->recordUserFailure($identity, $context);
}
}
if (! function_exists('getCurrentFinancialYear')) {
function getCurrentFinancialYear()
{
// Get current year and month
$date = new DateTime();
$currentYear = (int) $date->format('Y');
$currentMonth = (int) $date->format('m');
// If month is Jan, Feb, or March, we are still in the previous year's FY
if ($currentMonth < 4) {
$startYear = $currentYear - 1;
$endYear = $currentYear;
} else {
$startYear = $currentYear;
$endYear = $currentYear + 1;
}
return $startYear . '-' . $endYear;
}
}
if (! function_exists('format_financial_year')) {
function format_financial_year(string $financialYear): string
{
if (empty($financialYear) || ! str_contains($financialYear, '-')) {
return $financialYear;
}
$years = explode('-', $financialYear);
// Ensure we have both parts
$startYear = $years[0] ?? '';
$endYear = $years[1] ?? '';
return "APR " . $startYear . " - MAR " . $endYear;
}
}
if (! function_exists('add_google_calender_event')) {
function add_google_calender_event($data)
{
$calendar = new \App\Libraries\GoogleCalendarService();
// Check if user is authenticated without passing tokens manually
if (! $calendar->isReady()) {
return ['status' => 'failed', 'code' => '404', 'message' => 'Google Access Token Expired'];
}
try {
$response = $calendar->createEvent($data);
return ['status' => 'success', 'code' => '200', 'message' => 'Follow-up Saved', 'response' => $response];
} catch (\Exception $e) {
return ['status' => 'failed', 'code' => '500', 'message' => 'Error: ' . $e->getMessage()];
}
}
}
if (! function_exists('cleanNumber')) {
function cleanNumber($value){
if (empty($value)) {
return 0;
}
$value = str_replace(',', '', trim($value));
return is_numeric($value) ? (float)$value : 0;
}
}