diff --git a/app/Config/Routes.php b/app/Config/Routes.php index e07b1e01..cf5fe44e 100755 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -446,12 +446,14 @@ $routes->group("/util", ["filter" => "authMVC"], function ($routes) { $routes->get('generateDemographyDataTable', 'LeadsController::generateDemographyDataTable'); $routes->post('insufficientCdBalanceHrMailSend', 'EmployeeController::insufficientCdBalanceHrMailSend'); $routes->get('getTpaClaimDumpErrorData/(:any)', 'TicketServiceController::getTpaClaimDumpErrorData/$1'); - + $routes->get('croneDailyActivityReport', 'DashboardController::croneDailyActivityReport'); }); $routes->post("policy_tranction/sendInstallmentRemainderMail","PolicyTransactionController::sendInstallmentRemainderMail"); $routes->cli("cli/sendInstallmentRemainderMail","PolicyTransactionController::sendInstallmentRemainderMail"); $routes->cli("cli/cronDailyBDSReport", "PolicyTransactionController::cronDailyBDSReport"); +$routes->cli('cli/croneDailyActivityReport', 'DashboardController::croneDailyActivityReport'); + $routes->group("policy_tranction", ["filter" => "authMVC"], function ($routes) { diff --git a/app/Controllers/ClientController.php b/app/Controllers/ClientController.php index 6d2064fa..ee3a8098 100755 --- a/app/Controllers/ClientController.php +++ b/app/Controllers/ClientController.php @@ -6975,7 +6975,9 @@ class ClientController extends AdminController // $response = $ticketServiceController->tpaClaimDumpImporter(["file_id" => 53]); //icici // $response = $ticketServiceController->tpaClaimDumpImporter(["file_id" => 54]); //mediassist // $response = $ticketServiceController->tpaClaimDumpImporter(["file_id" => 52]); //reliance - // $response = $ticketServiceController->tpaClaimDumpImporter(["file_id" => 48]); //vidal + // $response = $ticketServiceController->tpaClaimDumpImporter(["file_id" => 48]); //vidal` + // $response = $ticketServiceController->tpaClaimDumpImporter(["file_id" => 57]); //mediassist + // $response = $ticketServiceController->tpaClaimDumpToTicketMasterImporters(["file_id" => 51]); //abhi // $response = $ticketServiceController->tpaClaimDumpToTicketMasterImporters(["file_id" => 50]); //fhpl diff --git a/app/Controllers/DashboardController.php b/app/Controllers/DashboardController.php index 1dab325b..b4d224fe 100755 --- a/app/Controllers/DashboardController.php +++ b/app/Controllers/DashboardController.php @@ -7,6 +7,7 @@ use CodeIgniter\HTTP\RequestInterface; use CodeIgniter\HTTP\ResponseInterface; use Psr\Log\LoggerInterface; use App\Helpers\sendMailNotification; +use App\Helpers\MailHelper; use CodeIgniter\API\ResponseTrait; @@ -24,6 +25,11 @@ use App\Controllers\EmpDataServiceController; use App\Models\TicketMasterModel; use App\Models\LeadsModel; use App\Models\TicketClaimStatusModel; +use App\Models\FileModel; +use App\Models\BatchFileModel; +use App\Models\SalesActivityModel; +use App\Models\SalesActualLeadModel; + class DashboardController extends AdminController @@ -43,6 +49,13 @@ class DashboardController extends AdminController protected $policyStatus; protected $colorShades; protected $claimDashLimit; + protected $filesModel; + protected $batchFilesModel; + protected $leadsModel; + protected $ticketMasterModel; + protected $ticketClaimStatusModel; + protected $salesActivityModel; + protected $salesActualModel; protected $myLogger; @@ -59,6 +72,13 @@ class DashboardController extends AdminController $this->ticketModel = new TicketMasterModel(); $this->leadModel = new LeadsModel(); $this->ticketStatusModel = new TicketClaimStatusModel(); + $this->filesModel = new FileModel(); + $this->batchFilesModel = new BatchFileModel(); + $this->leadsModel = new LeadsModel(); + $this->ticketMasterModel = new TicketMasterModel(); + $this->ticketClaimStatusModel = new TicketClaimStatusModel(); + $this->salesActivityModel = new SalesActivityModel(); + $this->salesActualModel = new SalesActualLeadModel(); $this->myLogger = \Config\Services::mylogger(); @@ -787,4 +807,298 @@ class DashboardController extends AdminController $data['ticket_type_id'] = $ticketTypeId; return $this->respond(['status' => "success", "data" => $data], 200); } + + public function croneDailyActivityReport() + { + + // $today = date('Y-m-d'); + $today = date('Y-m-d', strtotime('-1 day')); + + // Inception & endorsement counts (file uploads) + $total_inception_count = $this->filesModel + ->where('is_active', 1) + ->where('DATE(created_at)', $today) + ->where('action', 'inception') + ->where('status', 'success') + ->countAllResults(); + + $total_endorsement_count = $this->filesModel + ->where('is_active', 1) + ->where('DATE(created_at)', $today) + ->where('action !=', 'inception') + ->where('status', 'success') + ->countAllResults(); + + // TPA & Insurer batch file counts + $total_tpa_incetion_count = $this->batchFilesModel + ->where('is_active', 1) + ->where('DATE(created_at)', $today) + ->where('event_type', 'inception') + ->where('insurer_or_tpa', 'tpa') + ->where('status', 'success') + ->countAllResults(); + + $total_tpa_endorsement_count = $this->batchFilesModel + ->where('is_active', 1) + ->where('DATE(created_at)', $today) + ->where('event_type !=', 'inception') + ->where('insurer_or_tpa', 'tpa') + ->where('status', 'success') + ->countAllResults(); + + $total_insurer_incetion_count = $this->batchFilesModel + ->where('is_active', 1) + ->where('DATE(created_at)', $today) + ->where('event_type', 'inception') + ->where('insurer_or_tpa', 'insurer') + ->where('status', 'success') + ->countAllResults(); + + $total_insurer_endorsement_count = $this->batchFilesModel + ->where('is_active', 1) + ->where('DATE(created_at)', $today) + ->where('event_type !=', 'inception') + ->where('insurer_or_tpa', 'insurer') + ->where('status', 'success') + ->countAllResults(); + + // Claim counts + $total_claim_count = $this->ticketMasterModel + ->where('is_active', 1) + ->where('DATE(created_at)', $today) + ->countAllResults(); + + $total_gmc_status_wise_claim_count = $this->ticketMasterModel + ->select('tcs.claim_status, count(*) as count') + ->join('ticket_claim_status tcs', 'tcs.id = ticket_master.claim_status_id', 'left') + ->where('ticket_master.is_active', 1) + ->where('ticket_master.ticket_type_id', 1) + // ->where('DATE(ticket_master.created_at)', $today) + ->where('tcs.is_active', 1) + ->groupBy('tcs.claim_status') + ->findAll(); + + $total_gpa_status_wise_claim_count = $this->ticketMasterModel + ->select('tcs.claim_status, count(*) as count') + ->join('ticket_claim_status tcs', 'tcs.id = ticket_master.claim_status_id', 'left') + ->where('ticket_master.is_active', 1) + ->where('ticket_master.ticket_type_id', 2) + // ->where('DATE(ticket_master.created_at)', $today) + ->where('tcs.is_active', 1) + ->groupBy('tcs.claim_status') + ->findAll(); + + $total_edli_status_wise_claim_count = $this->ticketMasterModel + ->select('tcs.claim_status, count(*) as count') + ->join('ticket_claim_status tcs', 'tcs.id = ticket_master.claim_status_id', 'left') + ->where('ticket_master.is_active', 1) + ->where('ticket_master.ticket_type_id', 3) + // ->where('DATE(ticket_master.created_at)', $today) + ->where('tcs.is_active', 1) + ->groupBy('tcs.claim_status') + ->findAll(); + + $total_gtli_status_wise_claim_count = $this->ticketMasterModel + ->select('tcs.claim_status, count(*) as count') + ->join('ticket_claim_status tcs', 'tcs.id = ticket_master.claim_status_id', 'left') + ->where('ticket_master.is_active', 1) + ->where('ticket_master.ticket_type_id', 4) + // ->where('DATE(ticket_master.created_at)', $today) + ->where('tcs.is_active', 1) + ->groupBy('tcs.claim_status') + ->findAll(); + + // Sales / lead counts + $total_opportunity_count = $this->leadsModel + ->where('is_active', 1) + ->where('DATE(created_at)', $today) + ->countAllResults(); + + $total_rfq_created_count = $this->leadsModel + ->where('is_active', 1) + ->where('DATE(created_at)', $today) + ->where('status', 'rfq_created') + ->countAllResults(); + + $total_rfq_insurer_send_count = $this->leadsModel + ->where('is_active', 1) + ->where('DATE(created_at)', $today) + ->where('status', 'rfq_sent') + ->countAllResults(); + + $total_qcr_created_count = $this->leadsModel + ->where('is_active', 1) + ->where('DATE(created_at)', $today) + ->where('status', 'qcr_created') + ->countAllResults(); + + $total_qcr_client_send_count = $this->leadsModel + ->where('is_active', 1) + ->where('DATE(created_at)', $today) + ->where('status', 'qcr_sent') + ->countAllResults(); + + $total_placement_count = $this->leadsModel + ->where('is_active', 1) + ->where('DATE(created_at)', $today) + ->where('status', 'won') + ->countAllResults(); + + $total_activity_count = $this->salesActivityModel + ->where('DATE(created_at)', $today) + ->countAllResults(); + + $total_lead_count = $this->salesActualModel + ->where('DATE(created_at)', $today) + ->countAllResults(); + + $total_bds_count = $this->policyTransactionModel + ->select('pt_co_share_details.*') + ->join('pt_co_share_details', 'policy_transaction.id = pt_co_share_details.pt_id') + ->where('DATE(policy_transaction.created_at)', $today) + ->where('pt_co_share_details.is_active', 1) + ->where('policy_transaction.is_active', 1) + ->countAllResults(); + + $total_bds_policy_wise_count = $this->policyTransactionModel + ->select('pt_co_share_details.*') + ->join('pt_co_share_details', 'policy_transaction.id = pt_co_share_details.pt_id') + ->where('DATE(policy_transaction.created_at)', $today) + ->where('pt_co_share_details.is_active', 1) + ->where('policy_transaction.action_type', 'inception') + ->where('policy_transaction.is_active', 1) + ->countAllResults(); + + + $total_bds_endorsement_wise_count = $this->policyTransactionModel + ->select('pt_co_share_details.*') + ->join('pt_co_share_details', 'policy_transaction.id = pt_co_share_details.pt_id') + ->where('DATE(policy_transaction.created_at)', $today) + ->where('pt_co_share_details.is_active', 1) + ->where('policy_transaction.action_type !=', 'inception') + ->where('policy_transaction.is_active', 1) + ->countAllResults(); + + $total_bds_policy_type_wise_count = $this->policyTransactionModel + ->select('policy_type.policy_type, count(*) as count') + ->join('pt_co_share_details', 'policy_transaction.id = pt_co_share_details.pt_id') + ->join('policy_type', 'policy_transaction.policy_type_id = policy_type.id') + ->where('DATE(policy_transaction.created_at)', $today) + ->where('pt_co_share_details.is_active', 1) + ->where('policy_transaction.is_active', 1) + ->groupBy('policy_transaction.policy_type_id') + ->findAll(); + + // Connect Pre DB for Employee Enrollment Count + + $db2 = \Config\Database::connect('preDB'); + + $builder = $db2->table('employees'); + $total_employee_draft_count = $builder->join('employee_polices', 'employees.id = employee_polices.employee_id') + ->select('employee_polices.status, count(*) as count') + ->where('DATE(employee_polices.created_at)', $today) + ->where('employee_polices.is_active', 1) + ->where('employees.is_active', 1) + ->whereIn('employee_polices.status', ['draft']) + ->groupBy('employee_polices.status') + ->countAllResults(); + + + $builder1 = $db2->table('employees'); + $total_employee_enrolled_count = $builder1->join('employee_polices', 'employees.id = employee_polices.employee_id') + ->select('employee_polices.status, count(*) as count') + ->where('DATE(employee_polices.created_at)', $today) + ->where('employee_polices.is_active', 1) + ->where('employees.is_active', 1) + ->whereIn('employee_polices.status', ['enrolled']) + ->groupBy('employee_polices.status') + ->countAllResults(); + + $builder2 = $db2->table('files'); + $total_open_for_enrollemnt_policy_count = $builder2 + ->select('COUNT(*) as count') + ->where('enrollment_open_date <=', $today) + ->where('enrollment_close_date >=', $today) + ->where('is_active', 1) + ->where('status', 'success') + ->countAllResults(); + + $data = [ + 'total_inception_count' => $total_inception_count, + 'total_endorsement_count' => $total_endorsement_count, + 'total_tpa_incetion_count' => $total_tpa_incetion_count, + 'total_tpa_endorsement_count' => $total_tpa_endorsement_count, + 'total_insurer_incetion_count' => $total_insurer_incetion_count, + 'total_insurer_endorsement_count' => $total_insurer_endorsement_count, + 'total_claim_count' => $total_claim_count, + 'total_gmc_status_wise_claim_count' => $total_gmc_status_wise_claim_count, + 'total_gpa_status_wise_claim_count' => $total_gpa_status_wise_claim_count, + 'total_edli_status_wise_claim_count' => $total_edli_status_wise_claim_count, + 'total_gtli_status_wise_claim_count' => $total_gtli_status_wise_claim_count, + 'total_opportunity_count' => $total_opportunity_count, + 'total_rfq_created_count' => $total_rfq_created_count, + 'total_rfq_insurer_send_count' => $total_rfq_insurer_send_count, + 'total_qcr_created_count' => $total_qcr_created_count, + 'total_qcr_client_send_count' => $total_qcr_client_send_count, + 'total_placement_count' => $total_placement_count, + 'total_activity_count' => $total_activity_count, + 'total_lead_count' => $total_lead_count, + 'total_bds_count' => $total_bds_count, + 'total_bds_policy_wise_count' => $total_bds_policy_wise_count, + 'total_bds_endorsement_wise_count' => $total_bds_endorsement_wise_count, + 'total_bds_policy_type_wise_count' => $total_bds_policy_type_wise_count, + 'total_employee_draft_count' => $total_employee_draft_count, + 'total_employee_enrolled_count' => $total_employee_enrolled_count, + 'total_open_for_enrollemnt_policy_count' => $total_open_for_enrollemnt_policy_count, + ]; + + // dd($data); + + $today = date('d-m-Y', strtotime($today)); + $data['today'] = $today; + + // Render the HTML email using the dedicated view + $message = view('daily_report_email_template', $data); + // return $message; + + // Recipients: prefer dedicated env, fallback to BDS report emails if not set + $emailList = getenv('activity.dailyReportEmails') ?: getenv('bds.dailyReportEmails') ?: ''; + $recipientEmails = array_filter(array_map('trim', explode(',', $emailList))); + + if (empty($recipientEmails)) { + $this->myLogger->logme('error', 'croneDailyActivityReport: No recipients configured (set activity.dailyReportEmails in .env).'); + return $this->respond([ + 'status' => 'success', + 'message' => 'Daily activity data prepared but no recipients configured.', + 'data' => $data, + ], 200); + } + + $subject = "Daily Activity Report - {$today}"; + + $res = MailHelper::send_email([ + 'mail' => $recipientEmails, + 'subject' => $subject, + 'message' => $message, + ]); + + $resDecoded = is_string($res) ? json_decode($res, true) : $res; + + if (isset($resDecoded['status']) && $resDecoded['status'] === 'success') { + $this->myLogger->logme('error', 'croneDailyActivityReport: Report email sent to ' . count($recipientEmails) . ' recipients'); + return $this->respond([ + 'status' => true, + 'message' => 'Daily activity report emailed successfully.', + 'recipients' => count($recipientEmails), + ], 200); + } + + $this->myLogger->logme('error', 'croneDailyActivityReport: Email send failed - ' . json_encode($resDecoded)); + return $this->respond([ + 'status' => false, + 'message' => 'Daily activity data prepared but email send failed.', + 'data' => $data, + ], 500); + } + } diff --git a/app/Controllers/EmployeeRestController.php b/app/Controllers/EmployeeRestController.php index 73a1f1bd..df5dcfab 100755 --- a/app/Controllers/EmployeeRestController.php +++ b/app/Controllers/EmployeeRestController.php @@ -2586,61 +2586,90 @@ class EmployeeRestController extends AdminController $required_docs = $this->ticketMaster->select('required_docs')->where('id', $ticket_id)->first(); $data['required_docs'] = json_decode($required_docs['required_docs'] ?? '{}', true) ?? []; - // $ticketData = $data['ticket_data']; - // $ticketHistory = $data['ticket_history']; - // print_r($ticketHistory); die; + // print_rr($data['ticket_history']); die; + + $filteredArray = array_filter($data['ticket_history'], function($item) { + return $item['field_name'] == 'claim_status_id'; + }); + + $filteredArray = array_reverse(array_values($filteredArray)); $currentClaimStatus = $this->claimStatusModel->select("claim_status")->where('id', $data['claims_data']['claim_status_id'])->where('is_active', 1)->first(); $ticketClaimStatus = $this->claimStatusModel->select('claim_status, display_name')->where('display_name is not null')->where('ticket_type', $data['claims_data']['ticket_type_id'])->where('is_active', 1)->findAll(); $status_list = array_column($ticketClaimStatus, 'display_name', 'claim_status'); - // print_r($currentClaimStatus); die; + // dd($filteredArray, $status_list); die; - $data['ticket_data'] = array_fill_keys(array_keys($data['ticket_data']), []); + $filtered_history = []; + $counter = 0; + + foreach ($filteredArray as $key => $value) { + foreach ($status_list as $status => $display_name) { + if ($value['new_value'] == $status) { - // Loop through ticket_data - foreach ($data['ticket_data'] as $status => &$fields) { - // Search ticket_history for matching old_status_value - foreach ($data['ticket_history'] as $history) { + if($display_name == 'Under Process'){ + $unique_key = $display_name . str_repeat("\u{200B}", $counter++); + }else{ + $unique_key = $display_name; + } - if ($history['old_status_value'] === $status) { - // Attach modified_by and created_at - // $fields['modified_by'] = $history['modified_by']; - $fields['modified_by'] = ""; - $fields['modified_at'] = date('d-m-Y h:i A', strtotime($history['created_at'])); - // Break after first match (assuming latest entry is enough) - break; + $filtered_history[$unique_key] = [ + 'modified_by' => "", + 'modified_at' => date('d-m-Y h:i A', strtotime($value['created_at'])), + ]; } } } + // dd($filteredArray, $status_list, $filtered_history); die; - $data['ticket_data'][$currentClaimStatus['claim_status']]['modified_by'] = ""; - $data['ticket_data'][$currentClaimStatus['claim_status']]['modified_at'] = $formatted = date('d-m-Y h:i A', strtotime($data['claims_data']['updated_at'])); - $new_ticket_data = []; - foreach ($data['ticket_data'] as $oldKey => $value) { + // $data['ticket_data'] = array_fill_keys(array_keys($data['ticket_data']), []); - // Only process if key exists in status_list - if (! isset($status_list[$oldKey])) { - continue; // skip and do NOT add to new array - } + // // Loop through ticket_data + // foreach ($data['ticket_data'] as $status => &$fields) { + // // Search ticket_history for matching old_status_value + // foreach ($data['ticket_history'] as $history) { - // Get new key based on mapping - $newKey = $status_list[$oldKey]; + // if ($history['old_status_value'] === $status) { + // // Attach modified_by and created_at + // // $fields['modified_by'] = $history['modified_by']; + // $fields['modified_by'] = ""; + // $fields['modified_at'] = date('d-m-Y h:i A', strtotime($history['created_at'])); + // // Break after first match (assuming latest entry is enough) + // break; + // } + // } + // } - // Avoid duplicates - if (! isset($new_ticket_data[$newKey])) { - $new_ticket_data[$newKey] = $value; - } - } + // $data['ticket_data'][$currentClaimStatus['claim_status']]['modified_by'] = ""; + // $data['ticket_data'][$currentClaimStatus['claim_status']]['modified_at'] = $formatted = date('d-m-Y h:i A', strtotime($data['claims_data']['updated_at'])); - uasort($new_ticket_data, function ($a, $b) { - $timeA = \DateTime::createFromFormat('d-m-Y h:i A', $a['modified_at']); - $timeB = \DateTime::createFromFormat('d-m-Y h:i A', $b['modified_at']); - return $timeA <=> $timeB; // Ascending - }); + // $new_ticket_data = []; - $data['ticket_data'] = $new_ticket_data; + // foreach ($data['ticket_data'] as $oldKey => $value) { + + // // Only process if key exists in status_list + // if (! isset($status_list[$oldKey])) { + // continue; // skip and do NOT add to new array + // } + + // // Get new key based on mapping + // $newKey = $status_list[$oldKey]; + + // // Avoid duplicates + // if (! isset($new_ticket_data[$newKey])) { + // $new_ticket_data[$newKey] = $value; + // } + // } + + // uasort($new_ticket_data, function ($a, $b) { + // $timeA = \DateTime::createFromFormat('d-m-Y h:i A', $a['modified_at']); + // $timeB = \DateTime::createFromFormat('d-m-Y h:i A', $b['modified_at']); + // return $timeA <=> $timeB; // Ascending + // }); + + // $data['ticket_data'] = $new_ticket_data; + $data['ticket_data'] = $filtered_history; $ticketMesssageModel = new TicketMessageModel(); $ticket_message = $ticketMesssageModel @@ -5456,7 +5485,7 @@ class EmployeeRestController extends AdminController 'dashboard' => $database_id, ], 'exp' => time() + (10 * 60), - 'params' => (object) [], + 'params' => (object) ['client_policy' => $policy_id ], // MUST be object for Metabase ]; $token = JWT::encode($payload, $METABASE_SECRET_KEY, 'HS256'); diff --git a/app/Controllers/PolicyTransactionController.php b/app/Controllers/PolicyTransactionController.php index 3dfd21b6..44ed315b 100644 --- a/app/Controllers/PolicyTransactionController.php +++ b/app/Controllers/PolicyTransactionController.php @@ -6121,9 +6121,9 @@ class PolicyTransactionController extends BaseController $filePath = null; try { - $today = date('Y-m-d'); + $today = date('Y-m-d', strtotime('-1 day')); $reportList = $this->policyTransactionModel->getBDSReportList($today, $today,0,0,0,'created_at',0,0,0,0,0,[]); - + if (empty($reportList)) { $this->myLogger->logme('error', "cronDailyBDSReport: No BDS records for {$today}"); return $this->respond(['status' => 'success', 'message' => 'No BDS records for today. No report sent.'], 200); @@ -6219,6 +6219,7 @@ class PolicyTransactionController extends BaseController ]; } + $today = date('d-m-Y', strtotime($today)); $fileName = 'BDS_Daily_Report_' . $today . '.xlsx'; $tmpDir = WRITEPATH . 'tmp' . DIRECTORY_SEPARATOR; if (!is_dir($tmpDir)) { @@ -6244,8 +6245,8 @@ class PolicyTransactionController extends BaseController ], 200); } - $subject = "Daily BDS Report - {$today}"; - $message = "

Please find attached the daily BDS report for {$today}.

"; + $subject = "BDS Report Up to - {$today}"; + $message = "

Please find attached the BDS report up to {$today}.

"; $message .= "

Total records: " . count($reportList) . "

"; $attachments = [ diff --git a/app/Controllers/TestingController.php b/app/Controllers/TestingController.php index daae4293..c83fe172 100644 --- a/app/Controllers/TestingController.php +++ b/app/Controllers/TestingController.php @@ -1097,10 +1097,12 @@ class TestingController extends BaseController 'dashboard' => $database_id ], 'exp' => time() + (10 * 60), // 10 minutes - 'params' => (object)[] + 'params' => (object) ['client_policy' => $policy_id ], // MUST be object for Metabase + ]; $token = JWT::encode($payload, $METABASE_SECRET_KEY, 'HS256'); + // dd($token); if ($this->request->getGet('api') == 1) { return $this->respond([ diff --git a/app/Controllers/TicketController.php b/app/Controllers/TicketController.php index 01109672..7c70ec06 100644 --- a/app/Controllers/TicketController.php +++ b/app/Controllers/TicketController.php @@ -1173,9 +1173,13 @@ class TicketController extends BaseController 'regex_match' => 'Policy Number can only contain letters, numbers, spaces, hyphens(-) underscores(_), and slashes(/).' ] ], - 'tpa_no' => ['label' => 'TPA ID','rules' => 'permit_empty|regex_match[/^[a-zA-Z0-9]+$/]','errors' => [ - 'regex_match' => 'TPA ID can only contain letters and numbers.' - ]], + 'tpa_no' => [ + 'label' => 'TPA ID', + 'rules' => 'permit_empty|regex_match[/^[a-zA-Z0-9\/]+$/]', + 'errors' => [ + 'regex_match' => 'TPA ID can only contain letters, numbers, and /.' + ] + ], 'emp_mobile' => ['label' => 'Employee Mobile No','rules' => 'required|numeric|exact_length[10]', 'errors' => [ 'required' => 'Mobile number is required', @@ -1522,9 +1526,13 @@ class TicketController extends BaseController 'regex_match' => 'Policy Number can only contain letters, numbers, spaces, hyphens(-) underscores(_), and slashes(/).' ] ], - 'tpa_no' => ['label' => 'TPA ID','rules' => 'permit_empty|regex_match[/^[a-zA-Z0-9]+$/]','errors' => [ - 'regex_match' => 'TPA ID can only contain letters and numbers.' - ]], + 'tpa_no' => [ + 'label' => 'TPA ID', + 'rules' => 'permit_empty|regex_match[/^[a-zA-Z0-9\/]+$/]', + 'errors' => [ + 'regex_match' => 'TPA ID can only contain letters, numbers, and /.' + ] + ], 'emp_mobile' => ['label' => 'Employee Mobile No','rules' => 'required|numeric|exact_length[10]', 'errors' => [ 'required' => 'Mobile number is required', diff --git a/app/Libraries/TPAClaimsImportServices/BaseTpaClaimImportService.php b/app/Libraries/TPAClaimsImportServices/BaseTpaClaimImportService.php index 137caf25..3ccbcadd 100644 --- a/app/Libraries/TPAClaimsImportServices/BaseTpaClaimImportService.php +++ b/app/Libraries/TPAClaimsImportServices/BaseTpaClaimImportService.php @@ -9,17 +9,30 @@ use App\Models\TicketMasterModel; use App\Models\EmployeeModel; use App\Models\ClaimDumpFileModel; use App\Models\ClaimsDumpFhplModel; +use App\Models\ClientPolicyModel; + use RuntimeException; abstract class BaseTpaClaimImportService { protected BaseConnection $db; protected $claimDumpFileModel; + protected $clientPolicyModel; + protected $policyNumberMapping; public function __construct() { $this->db = db_connect(); $this->claimDumpFileModel = new ClaimDumpFileModel(); + $this->clientPolicyModel = new ClientPolicyModel(); + $this->policyNumberMapping = [ + (int) env('VIDAL_PRIMARY_KEY_CONSTANT') => 'Insurer Policy Number', + (int) env('ABHI_PRIMARY_KEY_CONSTANT') => 'Policy Number', + (int) env('MEDI_ASSIST_PRIMARY_KEY_CONSTANT') => 'policy_no', + (int) env('FHPL_PRIMARY_KEY_CONSTANT') => 'Policy No', + (int) env('R_CARE_PRIMARY_KEY_CONSTANT') => 'Policy Number', + (int) env('ICICI_PRIMARY_KEY_CONSTANT') => 'POLICY_NO', + ]; } /** @@ -33,6 +46,8 @@ abstract class BaseTpaClaimImportService try { $fileData = $this->claimDumpFileModel->where('id', $fileId)->first(); + $client_policy_data = $this->clientPolicyModel->where('id', $fileData['client_policy_id'])->first(); + // Determine sheet name logic... if (env('FHPL_PRIMARY_KEY_CONSTANT') == $fileData['tpa_id']) { $rows = $this->readExcelBySheetName($filePath, 'Claims&Preauth'); @@ -47,6 +62,18 @@ abstract class BaseTpaClaimImportService return ['status' => false, 'message' => 'Excel file contains no data or wrong file upload']; } + if(isset($this->policyNumberMapping[$fileData['tpa_id']]) && !empty($this->policyNumberMapping[$fileData['tpa_id']])){ + $policy_number_column = $this->policyNumberMapping[$fileData['tpa_id']]; + }else{ + $policy_number_column = 'policy_no'; + } + + + if($client_policy_data['policy_no'] != ($rows[0][$policy_number_column] ?? '')){ + $this->db->transRollback(); + return ['status' => false, 'message' => 'Policy number mismatch in the file and in the system']; + } + $tpaInsertData = $this->mapTPAData($rows, $fileId); if (empty($tpaInsertData)) { diff --git a/app/Models/PolicyTransactionModel.php b/app/Models/PolicyTransactionModel.php index e9656ad6..20da8dec 100644 --- a/app/Models/PolicyTransactionModel.php +++ b/app/Models/PolicyTransactionModel.php @@ -3098,6 +3098,8 @@ if ($date_type === "policy_issue_date") { $conditions .= " AND pcsd.pt_policy_issue_date >= '$startDate' "; $conditions .= " AND pcsd.pt_policy_issue_date <= '$endDate' "; + } else if ($date_type === "created_at") { + $conditions .= " AND pt.created_at <= '$endDate' "; } else { $conditions .= " AND pt.$date_type >= '$startDate' "; $conditions .= " AND pt.$date_type <= '$endDate' "; diff --git a/app/Views/daily_report_email_template.php b/app/Views/daily_report_email_template.php new file mode 100644 index 00000000..0ba7c8ff --- /dev/null +++ b/app/Views/daily_report_email_template.php @@ -0,0 +1,347 @@ + + + + + + + + +
+
+

Daily Activity Report

+
+ Key operations, sales and claim metrics for the day +
+
+ +
+
Date:
+ + +

Inception & Endorsement (File Upload)

+
+
+
Total Inception
+
+
Employee file uploads marked as inception
+
+
+
Total Endorsement
+
+
All non‑inception successful uploads
+
+
+ + +

Employee Enrollment

+
+
+
Draft / Enrolled
+
/
+
Employees in draft / enrolled status for the day
+
+
+
Open for Enrollment Policies
+
+
Policies currently open for enrollment
+
+
+ + +

TPA & Insurer Batch Summary

+
+
+
TPA (Inception / Endorsement)
+
/
+
Successful TPA events
+
+
+
Insurer (Inception / Endorsement)
+
/
+
Successful insurer events
+
+
+ + +

Sales Funnel & Leads

+
+
+
Opportunities & Won
+
/
+
Total opportunities created vs converted
+
+
+
RFQ (Created / Sent to Insurer)
+
/
+
Movement from opportunity to RFQ
+
+
+
QCR (Created / Sent to Client)
+
/
+
Quotes prepared and shared
+
+
+
Total Leads & Activities
+
/
+
Lead entries and logged touchpoints
+
+
+ + +

BDS Policy Transactions

+
+
+
Total BDS Transactions
+
+
All policy transactions processed
+
+
+
BDS (Policy / Endorsement)
+
/
+
Split of inceptions vs endorsements
+
+
+ + +

Claims

+
+
+
Total Claims Registered for the day
+
+
+
+
+ + +

BDS by Policy Type

+
+ + + + + + + + + + + + + + + + + + + + + +
Policy TypeCount
+ +
+ No BDS activity recorded for today. +
+
+ + +

Claim Status Breakdown

+
+ The total claims received so far are listed ticket type-wise. +
+ + $total_gmc_status_wise_claim_count ?? [], + 'GPA Claims' => $total_gpa_status_wise_claim_count ?? [], + 'EDLI Claims' => $total_edli_status_wise_claim_count ?? [], + 'GTLI Claims' => $total_gtli_status_wise_claim_count ?? [], + ]; + $hasAnyClaimData = false; + ?> + + $rows): ?> + + +

+
+ + + + + + + + + + + + + + + +
StatusCount
+ +
+
+ + + +
+ + +
+ + \ No newline at end of file