MERGE_BRANCH_CHATBOT_SRI

This commit is contained in:
Srinivas-Saravanan 2025-02-03 10:27:26 +05:30
commit c7945f8fc2
12 changed files with 133 additions and 27 deletions

View File

@ -421,6 +421,10 @@ $routes->cli('cli/check_bounce_mail_cli', 'MasterController::testCheckBounceMail
$routes->cli('cli/app_check_list', 'MasterController::appCheckList'); $routes->cli('cli/app_check_list', 'MasterController::appCheckList');
$routes->cli('cli/new_gdrive_token', 'GoogleDriveController::generateNewGoogleDriveAccessToken'); $routes->cli('cli/new_gdrive_token', 'GoogleDriveController::generateNewGoogleDriveAccessToken');
//crone job
$routes->cli('cli/enrollOpendAndClose', 'DashboardController::updatePolicyEnrollmentStatus');
$routes->cli("cli/sendCroneRemainderMail", "DashboardController::sendCroneRemainderMail");
//Employee login api's //Employee login api's
$routes->post("/employeeRest/verifyEmployeeNumber", "RestAuthenticationController::verifyEmployeeWithMobileNumber"); $routes->post("/employeeRest/verifyEmployeeNumber", "RestAuthenticationController::verifyEmployeeWithMobileNumber");
$routes->post("/employeeRest/getVerifiedUserData", "RestAuthenticationController::getVerifiedUserData"); $routes->post("/employeeRest/getVerifiedUserData", "RestAuthenticationController::getVerifiedUserData");

View File

@ -56,7 +56,7 @@ class MainMenuConversation extends Conversation
break; break;
default: default:
$this->say("Invalid selection. Please choose an option."); $this->say("Invalid selection. Please choose an option.");
$this->showMainMenu(); $this->bot->startConversation(new MainMenuConversation());
break; break;
} }
}); });

View File

@ -4176,7 +4176,21 @@ class ClientController extends AdminController
->where('client_policy.id', $param) ->where('client_policy.id', $param)
->findAll(); ->findAll();
$dataForClientAndInsurer = []; $dataForClientAndInsurer = $this->clientPolicyModel
->select("
clients.id AS client_id,
clients.client_name,
insurers.id AS insurer_id,
insurers.name AS insurer_name,
tpa.id AS tpa_id,
tpa.name AS tpa_name,
")
->join('clients', 'client_policy.client_id = clients.id', 'left')
->join('insurers', 'client_policy.insurer_id = insurers.id', 'left')
->join('tpa', 'client_policy.tpa_id = tpa.id', 'left')
->where('client_policy.id', $param)
->first();
$memberData = []; $memberData = [];
// Respond based on the query result // Respond based on the query result

View File

@ -286,9 +286,11 @@ class DashboardController extends AdminController
} }
$myLogger->logme('error', 'enrollment_status function completed'); $myLogger->logme('error', 'enrollment_status function completed');
$myLogger->logme('error', 'updated Open Enrollment Policy count : "'.count($openEnrollment).'" and Close Enrollment Policy count : "'.count($closeEnrollment).'"');
return $this->respond([ return $this->respond([
'status' => true, 'status' => true,
'message' => 'updated Policy Enrollment Status', 'message' => 'updated Open and Close Enrollment successfully',
'open_policy_count' => count($openEnrollment), 'open_policy_count' => count($openEnrollment),
'close_policy_count' => count($closeEnrollment), 'close_policy_count' => count($closeEnrollment),
'open_policy_ids' => $openEnrollment, 'open_policy_ids' => $openEnrollment,

View File

@ -98,7 +98,6 @@ class TicketController extends BaseController
6 => "Trigger 6", 6 => "Trigger 6",
7 => "Trigger 7" 7 => "Trigger 7"
]; ];
$this->placeHolders = [ $this->placeHolders = [
'((ACM))' => 'acm', '((ACM))' => 'acm',
@ -109,6 +108,7 @@ class TicketController extends BaseController
'((INSURED_NAME))' => 'insured_name', '((INSURED_NAME))' => 'insured_name',
'((CLAIM_NO))' => 'claim_number', '((CLAIM_NO))' => 'claim_number',
'((RELATIONSHIP))' => 'relationship', '((RELATIONSHIP))' => 'relationship',
'((POLICY_TYPE))' => 'policy_type',
]; ];
$this->ticketMasterModel = new TicketMasterModel(); $this->ticketMasterModel = new TicketMasterModel();
@ -332,7 +332,7 @@ class TicketController extends BaseController
if ($return_value) { if ($return_value) {
//mail trigger part //mail trigger part
$mail_responce = $this->sendAutoMailTrigger($return_value); $mail_responce = $this->sendAutoMailTrigger($return_value);
return $this->respond(['status' => true, 'code' => 200, 'data' => $ticket_data, "message" => "Claim created successfully", 'mail_responce' => $mail_responce], 200); return $this->respond(['status' => true, 'ticket_id' => $return_value, 'code' => 200, 'data' => $ticket_data, "message" => "Claim created successfully", 'mail_responce' => $mail_responce], 200);
} else { } else {
return $this->respond(['status' => false, 'code' => 404, 'message' => 'Failed to create claim'], 200); return $this->respond(['status' => false, 'code' => 404, 'message' => 'Failed to create claim'], 200);
} }
@ -502,6 +502,7 @@ class TicketController extends BaseController
try { try {
// Fetch Ticket Data // Fetch Ticket Data
$ticket_data = $this->ticketMasterModel->getTicketDataByTicketID($ticket_id); $ticket_data = $this->ticketMasterModel->getTicketDataByTicketID($ticket_id);
// print_r($ticket_data); die;
if (!$ticket_data) { if (!$ticket_data) {
$this->myLogger->logme('error', "No ticket data found for Ticket ID: $ticket_id"); $this->myLogger->logme('error', "No ticket data found for Ticket ID: $ticket_id");
@ -512,6 +513,7 @@ class TicketController extends BaseController
// Fetch Email Template Data // Fetch Email Template Data
$template_data = $this->ticketMasterModel->getTemplateDataByTicketID($ticket_id); $template_data = $this->ticketMasterModel->getTemplateDataByTicketID($ticket_id);
// print_r($template_data); die;
if (!$template_data) { if (!$template_data) {
$this->myLogger->logme('error', "No email template found for Claim Status ID: " . $ticket_data['claim_status_id']); $this->myLogger->logme('error', "No email template found for Claim Status ID: " . $ticket_data['claim_status_id']);
@ -524,14 +526,18 @@ class TicketController extends BaseController
$subject = $this->replacePlaceholders($template_data['subject'], $ticket_data); $subject = $this->replacePlaceholders($template_data['subject'], $ticket_data);
$message = $this->replacePlaceholders($template_data['mail_content'], $ticket_data); $message = $this->replacePlaceholders($template_data['mail_content'], $ticket_data);
// print_r($subject);
// print_r($message);
// die;
// Validate Essential Fields // Validate Essential Fields
if (empty($ticket_data['emp_mail'])) { if (empty($ticket_data['emp_mail'])) {
$this->myLogger->logme('error', "Employee email is missing for Ticket ID: $ticket_id"); $this->myLogger->logme('error', "Employee email is missing for Ticket ID : '".$ticket_id ."'");
return null; return null;
} }
if (empty($subject) || empty($message)) { if (empty($subject) || empty($message)) {
$this->myLogger->logme('error', "Generated email content is empty for Ticket ID: $ticket_id"); $this->myLogger->logme('error', "Generated email content is empty for Ticket ID: '".$ticket_id ."'");
return null; return null;
} }
@ -544,6 +550,8 @@ class TicketController extends BaseController
'attachments' => [] 'attachments' => []
]; ];
// print_r($mailData); die;
$this->myLogger->logme('error', "Final Email Data"); $this->myLogger->logme('error', "Final Email Data");
return $mailData; return $mailData;
@ -559,10 +567,15 @@ class TicketController extends BaseController
if (!empty($ticket_data) && !empty($content)) { if (!empty($ticket_data) && !empty($content)) {
foreach ($this->placeHolders as $key => $value) { foreach ($this->placeHolders as $key => $value) {
$replaceData = strtoupper($ticket_data[$value]) ?? '';
if ($value == "emp_code") { if ($value == "emp_code") {
$replaceData = $ticket_data[$value] ?? ''; $replaceData = $ticket_data[$value] ?? '';
}else if($value == "policy_type"){
$replaceData = str_replace("Claim-", "", $this->ticketType[$ticket_data['ticket_type_id']] ?? "");
}else{
$replaceData = strtoupper($ticket_data[$value]) ?? '';
} }
$content = str_replace($key, $replaceData, $content); $content = str_replace($key, $replaceData, $content);
} }
} }
@ -576,8 +589,12 @@ class TicketController extends BaseController
public function sendTrigger($mail_content) public function sendTrigger($mail_content)
{ {
$this->myLogger->logme('error', "Sending email with content"); $this->myLogger->logme('error', "Sending email with content");
if(!empty($mail_content)){
$response = MailHelper::send_email($mail_content); $response = MailHelper::send_email($mail_content);
}else{
$response = ['status' => false, 'code' => 404, 'message' => "Mail not sent, mail data empty"];
$this->myLogger->logme('error', "Mail not sent, mail data empty");
}
$this->myLogger->logme('error', "Email sent response: " . json_encode($response)); $this->myLogger->logme('error', "Email sent response: " . json_encode($response));
@ -634,6 +651,7 @@ class TicketController extends BaseController
$mail_responce = []; $mail_responce = [];
if (!empty($auto_mail_enable) && $auto_mail_enable['is_auto_mail'] == 1) { if (!empty($auto_mail_enable) && $auto_mail_enable['is_auto_mail'] == 1) {
$mail_content = $this->constructMailContent($ticket_id); $mail_content = $this->constructMailContent($ticket_id);
// print_r($mail_content); die;
$mail_responce = $this->sendTrigger($mail_content); $mail_responce = $this->sendTrigger($mail_content);
}elseif (!empty($auto_mail_enable) && $auto_mail_enable['is_auto_mail'] == 0 ){ }elseif (!empty($auto_mail_enable) && $auto_mail_enable['is_auto_mail'] == 0 ){
$this->myLogger->logme('error','Auto Mail Not Sent, Reason: Automail Not Enabled'); $this->myLogger->logme('error','Auto Mail Not Sent, Reason: Automail Not Enabled');

View File

@ -106,7 +106,7 @@ class EmployeeModel extends Model
public function getEmpFamilybyEmpCode(string $client_policy_id = null,string $emp_code = null,string $client_id = null,array $emp_status = [],array $policy_status = [],array $relationship = [],array $client_branch_id = []) public function getEmpFamilybyEmpCode(string $client_policy_id = null,string $emp_code = null,string $client_id = null,array $emp_status = [],array $policy_status = [],array $relationship = [],array $client_branch_id = [])
{ {
$result = $this->select(['employees.id as emp_id', 'employees.client_id','employees.client_branch_id', 'employees.relationship', 'employees.relationship_code', 'employees.change_event', 'employees.emp_code', 'employees.name', 'employees.email_personal', 'employees.email_corporate', 'employees.mobile', 'employees.gender', 'employees.dob', 'employees.doj', 'employees.basic_pay', 'employees.band', 'employees.designation', 'employees.emp_status','employees.unit','employees.file_id','employee_polices.id as emp_policy_id', 'employee_polices.employee_id', 'employee_polices.client_policy_id', 'employee_polices.tpa_id', 'employee_polices.uhid', 'employee_polices.batch_code', 'employee_polices.status', 'employee_polices.pre_existing_alignments', 'employee_polices.basic_cover_si', 'employee_polices.date_coverage', 'employee_polices.policy_end_date', 'employee_polices.days', 'employee_polices.premium', 'employee_polices.rata_premimum', 'employee_polices.gst', 'employee_polices.date_of_exit', 'employee_polices.reason_for_exit','policy_type.long_name as policy_name','client_policy.is_addon', 'employee_polices.payable_employee','employee_polices.rand_string']) $result = $this->select(['employees.id as emp_id', 'employees.client_id','employees.client_branch_id', 'employees.relationship', 'employees.relationship_code', 'employees.change_event', 'employees.emp_code', 'employees.name', 'employees.email_personal', 'employees.email_corporate', 'employees.mobile', 'employees.gender', 'employees.dob', 'employees.doj', 'employees.basic_pay', 'employees.band', 'employees.designation', 'employees.emp_status','employees.unit','employees.file_id','employee_polices.id as emp_policy_id', 'employee_polices.employee_id', 'employee_polices.client_policy_id', 'employee_polices.tpa_id', 'employee_polices.uhid', 'employee_polices.batch_code', 'employee_polices.status', 'employee_polices.pre_existing_alignments', 'employee_polices.basic_cover_si', 'employee_polices.date_coverage', 'employee_polices.policy_end_date', 'employee_polices.days', 'employee_polices.premium', 'employee_polices.rata_premimum', 'employee_polices.gst', 'employee_polices.date_of_exit', 'employee_polices.reason_for_exit','policy_type.long_name as policy_name','client_policy.is_addon', 'employee_polices.payable_employee','employee_polices.rand_string','employee_polices.claim_status'])
->join('employee_polices', 'employee_polices.employee_id = employees.id') ->join('employee_polices', 'employee_polices.employee_id = employees.id')
->join('client_policy', 'client_policy.id = employee_polices.client_policy_id') ->join('client_policy', 'client_policy.id = employee_polices.client_policy_id')
->join('policy_type', 'policy_type.id = client_policy.policy_type_id','left') ->join('policy_type', 'policy_type.id = client_policy.policy_type_id','left')

View File

@ -826,6 +826,7 @@ class EmployeePolicyModel extends Model
employee_polices.rata_premimum as premium, employee_polices.rata_premimum as premium,
employee_polices.claim_status, employee_polices.claim_status,
employee_polices.age_band, employee_polices.age_band,
employee_polices.tpa_id,
batch_data.emp_policy_id AS emp_policy_id, batch_data.emp_policy_id AS emp_policy_id,
@ -1731,7 +1732,7 @@ class EmployeePolicyModel extends Model
employee_polices ep employee_polices ep
WHERE WHERE
ep.file_id = $file_id ep.file_id = $file_id
AND ep.uhid IS NOT NULL' AND ep.uhid IS NOT NULL
AND ep.status != 'truncated' AND ep.status != 'truncated'
AND ep.status != 'truncated' AND ep.status != 'truncated'
AND ep.is_active = 1; AND ep.is_active = 1;

View File

@ -10,7 +10,7 @@
<!-- Header Section --> <!-- Header Section -->
<div class="row mb-3"> <div class="row mb-3">
<div class="col-6 d-flex align-items-center"> <div class="col-6 d-flex align-items-center">
<h4 class="mb-0">Ticket</h4> <h4 class="mb-0">Claims</h4>
</div> </div>
<div class="col-6 text-right"> <div class="col-6 text-right">
<a href="<?= base_url('ticket/list'); ?>" aria-label="Back to ticket list"> <a href="<?= base_url('ticket/list'); ?>" aria-label="Back to ticket list">

View File

@ -63,20 +63,20 @@
<div class="form-group col-md-3"> <div class="form-group col-md-3">
<label for="client_name">Corporate Name<span class="text-danger"></span></label> <label for="client_name">Corporate Name<span class="text-danger"></span></label>
<input type="hidden" id="client_id" name="client_id" value="<?= isset($ticket_data['client_id']) ? $ticket_data['client_id'] : '' ?>"> <input type="hidden" id="client_id" name="client_id" value="<?= isset($ticket_data['client_id']) ? $ticket_data['client_id'] : '' ?>">
<input type="text" class="form-control" id="client_name" placeholder="Client" value="<?= isset($ticket_data['client_name']) ? $ticket_data['client_name'] : '' ?>"> <input type="text" class="form-control" id="client_name" placeholder="Client" value="<?= isset($ticket_data['client_name']) ? $ticket_data['client_name'] : '' ?>" readonly>
</div> </div>
<div class="form-group col-md-3"> <div class="form-group col-md-3">
<label for="insurer_id">Insurer<span class="text-danger"></span></label> <label for="insurer_id">Insurer<span class="text-danger"></span></label>
<input type=hidden id="insurer_id" name="insurer_id" value="<?= isset($ticket_data['insurer_id']) ? $ticket_data['insurer_id'] : '' ?>"> <input type=hidden id="insurer_id" name="insurer_id" value="<?= isset($ticket_data['insurer_id']) ? $ticket_data['insurer_id'] : '' ?>">
<input type=text class="form-control" id="insurer_name" placeholder="Insurer" value="<?= isset($ticket_data['insurer_name']) ? $ticket_data['insurer_name'] : '' ?>"> <input type=text class="form-control" id="insurer_name" placeholder="Insurer" value="<?= isset($ticket_data['insurer_name']) ? $ticket_data['insurer_name'] : '' ?>" readonly>
</div> </div>
<div class="form-group col-md-3"> <div class="form-group col-md-3">
<label for="policy_no">Policy No<span class="text-danger"></span></label> <label for="policy_no">Policy No<span class="text-danger"></span></label>
<input type="text" class="form-control" id="policy_no" <input type="text" class="form-control" id="policy_no"
value="<?= isset($ticket_data['policy_no']) ? $ticket_data['policy_no'] : '' ?>" value="<?= isset($ticket_data['policy_no']) ? $ticket_data['policy_no'] : '' ?>"
name="policy_no" readonly> name="policy_no">
</div> </div>
<div class="form-group col-md-3"> <div class="form-group col-md-3">
@ -127,6 +127,20 @@
name="emp_name"> name="emp_name">
</div> </div>
<div class="form-group col-md-3">
<label for="emp_mobile">Employee Mobile No<span class="text-danger"></span></label>
<input type="text" class="form-control" id="emp_mobile" placeholder="Enter EMP Mobile"
value="<?= isset($ticket_data['emp_mobile']) ? $ticket_data['emp_mobile'] : '' ?>"
name="emp_mobile">
</div>
<div class="form-group col-md-3">
<label for="emp_mail">Employee Mail ID<span class="text-danger"></span></label>
<input type="text" class="form-control" id="emp_mail" placeholder="Enter EMP Mail"
value="<?= isset($ticket_data['emp_mail']) ? $ticket_data['emp_mail'] : '' ?>"
name="emp_mail">
</div>
<div class="form-group col-md-3"> <div class="form-group col-md-3">
<label for="date_of_join">Date of joining<span class="text-danger"></span></label> <label for="date_of_join">Date of joining<span class="text-danger"></span></label>

View File

@ -257,7 +257,16 @@ function toggleAccordion(id) {
const content = document.getElementById(id); const content = document.getElementById(id);
const arrow = document.querySelector(`#${id === 'mobileAccordion' ? 'mobileArrow' : 'clientBranchArrow'}`); const arrow = document.querySelector(`#${id === 'mobileAccordion' ? 'mobileArrow' : 'clientBranchArrow'}`);
// Toggle the display of the accordion content // Define the other accordion to close
const otherId = id === 'mobileAccordion' ? 'clientBranchAccordion' : 'mobileAccordion';
const otherContent = document.getElementById(otherId);
const otherArrow = document.querySelector(`#${id === 'mobileAccordion' ? 'clientBranchArrow' : 'mobileArrow'}`);
// Close the other accordion
otherContent.classList.remove('show');
otherArrow.classList.remove('rotate');
// Toggle the current accordion
if (content.classList.contains('show')) { if (content.classList.contains('show')) {
content.classList.remove('show'); content.classList.remove('show');
arrow.classList.remove('rotate'); arrow.classList.remove('rotate');
@ -267,6 +276,7 @@ function toggleAccordion(id) {
} }
} }
function openFetchEmpDataodal() { function openFetchEmpDataodal() {
var myModal = new bootstrap.Modal(document.getElementById('empDetailsModal')); var myModal = new bootstrap.Modal(document.getElementById('empDetailsModal'));
myModal.show(); myModal.show();
@ -343,6 +353,7 @@ function appendBranch(data) {
//append the clients policy data to the modal //append the clients policy data to the modal
function appendPolicy(data) { function appendPolicy(data) {
let ticket_type = $('#ticket_type_id').val();
$('#emp_client_policy_data_list').empty(); $('#emp_client_policy_data_list').empty();
$('#emp_client_policy_data_list').append($('<option>', { $('#emp_client_policy_data_list').append($('<option>', {
@ -351,12 +362,53 @@ function appendPolicy(data) {
})); }));
$.each(data, function(index, item) { $.each(data, function(index, item) {
if(ticket_type == 1){
if(item.policy_type_id == 2 || item.policy_type_id == 3 || item.policy_type_id == 4 ||item.policy_type_id == 5) {
var option = $('<option>', { var option = $('<option>', {
value: item.id, value: item.id,
text: item.policy_type + '-' + item.policy_no, text: item.policy_type + '-' + item.policy_no,
}); });
$('#emp_client_policy_data_list').append(option).select2(); $('#emp_client_policy_data_list').append(option).select2();
}
}else if(ticket_type == 2){
if(item.policy_type_id == 1) {
var option = $('<option>', {
value: item.id,
text: item.policy_type + '-' + item.policy_no,
});
$('#emp_client_policy_data_list').append(option).select2();
}
}else if(ticket_type == 3){
if(item.policy_type_id == 6) {
var option = $('<option>', {
value: item.id,
text: item.policy_type + '-' + item.policy_no,
});
$('#emp_client_policy_data_list').append(option).select2();
}
}else if(ticket_type == 4){
if(item.policy_type == 7) {
var option = $('<option>', {
value: item.id,
text: item.policy_type + '-' + item.policy_no,
});
$('#emp_client_policy_data_list').append(option).select2();
}
}
}); });
} }
@ -428,6 +480,7 @@ function getEmpData(input) {
if (response.status) { if (response.status) {
console.log(response.message, 'SUCCESS'); console.log(response.message, 'SUCCESS');
appendEmployee(response.data, 'search_by_client_employee'); appendEmployee(response.data, 'search_by_client_employee');
setClientAndInsurerData(response.dataForClientAndInsurer);
} else { } else {
toastr.warning(response.message, 'WARNING'); toastr.warning(response.message, 'WARNING');
} }

View File

@ -130,7 +130,7 @@ table.dataTable tbody td {
placeholder="Template Name" required> placeholder="Template Name" required>
</div> </div>
<div class="form-group col-md-4"> <div class="form-group col-md-3">
<label for="emp_code">Policy Type</label> <label for="emp_code">Policy Type</label>
<select class="form-control" id="policy_type" name="ticket_type" required> <select class="form-control" id="policy_type" name="ticket_type" required>
<option value="">Select Policy Type</option> <option value="">Select Policy Type</option>
@ -144,7 +144,7 @@ table.dataTable tbody td {
</select> </select>
</div> </div>
<div class="form-group col-md-2"> <div class="form-group col-md-3">
<label for="trigger_type">Trigger Type</label> <label for="trigger_type">Trigger Type</label>
<select class="form-control" id="trigger_type" name="trigger_type" required> <select class="form-control" id="trigger_type" name="trigger_type" required>
<option value="">Select status</option> <option value="">Select status</option>
@ -158,7 +158,7 @@ table.dataTable tbody td {
</select> <input id="primaryKey" type="hidden"> </select> <input id="primaryKey" type="hidden">
</div> </div>
<div class="form-group col-md-4"> <div class="form-group col-md-2">
<div> <div>
<div id="statusSwitchWrapper" class="dt-switch-wrapper" <div id="statusSwitchWrapper" class="dt-switch-wrapper"
style="padding-top: 40px;padding-left: 10px;"> style="padding-top: 40px;padding-left: 10px;">
@ -480,7 +480,7 @@ function getMailTemplateData(id) {
$('#template_name').val(res.data.template_name); $('#template_name').val(res.data.template_name);
$('#primaryKey').val(res.data.id); $('#primaryKey').val(res.data.id);
$('#policy_type').val(res.data.ticket_type).change(); $('#policy_type').val(res.data.ticket_type).change();
$('#trigger_type').val(res.data.ticket_type).change(); $('#trigger_type').val(res.data.trigger_type).change();
$('.jodit-wysiwyg').html(res.data.mail_content); $('.jodit-wysiwyg').html(res.data.mail_content);
// Set the auto mail switch // Set the auto mail switch

View File

@ -7,7 +7,7 @@
<!-- Email To Field --> <!-- Email To Field -->
<div class="form-group col-md-4"> <div class="form-group col-md-4">
<label for="emp_mail_for_to">To</label> <label for="emp_mail_for_to">To</label>
<input type="text" value="<?= isset($reply_data['emp_mail'])?$reply_data['emp_mail']:'' ?>" class="form-control" id="emp_mail_for_to" name="emp_mail" placeholder="Recipient email" readonly> <input type="text" value="<?= isset($ticket_data['emp_mail'])?$ticket_data['emp_mail']:'' ?>" class="form-control" id="emp_mail_for_to" name="emp_mail" placeholder="Recipient email" readonly>
</div> </div>
<!-- Subject Field --> <!-- Subject Field -->