4866 lines
198 KiB
PHP
4866 lines
198 KiB
PHP
<style>
|
||
#allTableContainer {
|
||
max-width: 100%;
|
||
overflow-x: auto;
|
||
display: block;
|
||
}
|
||
|
||
|
||
|
||
.btn-custom {
|
||
background-color: #007bff;
|
||
color: #fff;
|
||
margin-right: 10px;
|
||
}
|
||
.readonly-select {
|
||
pointer-events: none;
|
||
background-color: #f0f0f0;
|
||
color: #666;
|
||
}
|
||
|
||
table {
|
||
/* border-collapse: collapse; */
|
||
margin-bottom: 20px;
|
||
/* max-width: 800px; */
|
||
/* table-layout: fixed; */
|
||
width: 1400px;
|
||
min-width: 1200px;
|
||
table-layout: fixed;
|
||
border-collapse: collapse;
|
||
word-wrap: break-word;
|
||
|
||
}
|
||
|
||
table thead tr:nth-child(1) th {
|
||
background-color: #bfe0e2;
|
||
border: 1px solid #007bff;
|
||
}
|
||
table thead tr:nth-child(2) th {
|
||
background-color: #bfe0e2;
|
||
border: 1px solid #007bff;
|
||
}
|
||
|
||
|
||
/* Apply styles to the first column, accounting for rowspan */
|
||
table th:nth-child(1),
|
||
table td:nth-child(1) {
|
||
width: 110px;
|
||
background-color: #bfe0e2;
|
||
}
|
||
|
||
|
||
|
||
/* Ensure rowspan cells in the first column inherit the same styles */
|
||
table td[rowspan]:nth-child(1) {
|
||
width: 110px;
|
||
/* background-color: #bfe0e2; */
|
||
}
|
||
|
||
.table {
|
||
border: 1px solid #007bff; /* Border around the table */
|
||
border-collapse: collapse; /* Ensures borders don’t double up */
|
||
width: 100%;
|
||
}
|
||
|
||
.table th,
|
||
.table td {
|
||
border: 1px solid #007bff; /* Border for all table cells */
|
||
padding: 8px; /* Optional: Adds spacing inside cells */
|
||
text-align: left; /* Optional: Aligns text inside cells */
|
||
}
|
||
|
||
|
||
|
||
th:nth-child(2),
|
||
td:nth-child(2) {
|
||
width: 720px;
|
||
background-color: #bfe0e2;
|
||
/* Adjust first column width */
|
||
}
|
||
.bold {
|
||
font-weight: bold;
|
||
color: red;
|
||
}
|
||
|
||
th:nth-last-child(1),
|
||
td:nth-last-child(1) {
|
||
width: 230px;
|
||
/* Adjust last column width */
|
||
}
|
||
|
||
th,
|
||
td {
|
||
border: 1px solid #000;
|
||
padding: 8px;
|
||
}
|
||
|
||
th {
|
||
/* background-color: #f2f2f2 !important; */
|
||
position: relative !important;
|
||
}
|
||
|
||
.three-dot-menu {
|
||
cursor: pointer;
|
||
}
|
||
|
||
.dropdown-content {
|
||
display: none;
|
||
position: absolute;
|
||
background-color: #f9f9f9;
|
||
box-shadow: 0px 8px 16px rgba(0, 0, 0, 0.2);
|
||
z-index: 1;
|
||
}
|
||
/* Selects the last cell in each row */
|
||
table tr td:last-child,
|
||
table tr th:last-child {
|
||
background-color: white !important;
|
||
}
|
||
|
||
|
||
.dropdown-content button {
|
||
display: block;
|
||
width: 100%;
|
||
padding: 8px;
|
||
text-align: left;
|
||
border: none;
|
||
background: none;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.dropdown-content button:hover {
|
||
background-color: #ddd;
|
||
}
|
||
|
||
/* Dropdown container */
|
||
.simple-dropdown {
|
||
position: absolute;
|
||
background: white;
|
||
border: 1px solid #ccc;
|
||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||
z-index: 1000;
|
||
}
|
||
|
||
/* Individual dropdown options */
|
||
.dropdown-option {
|
||
padding: 8px 16px;
|
||
cursor: pointer;
|
||
min-width: 80px;
|
||
user-select: none;
|
||
background-color: #ff9999;
|
||
}
|
||
|
||
/* Hover effect for options */
|
||
.dropdown-option:hover {
|
||
background-color: #333;
|
||
color : white;
|
||
}
|
||
|
||
/* Optional: Add transition for smoother hover effect */
|
||
.dropdown-option {
|
||
transition: background-color 0.2s ease;
|
||
}
|
||
|
||
/* Optional: Style the TD when it's clickable */
|
||
td[onclick] {
|
||
cursor: pointer;
|
||
}
|
||
|
||
/* Optional: Style for selected state */
|
||
.selected-option {
|
||
background-color: #f8f9fa;
|
||
}
|
||
|
||
.modal {
|
||
display: block !important;
|
||
/* Ensures visibility */
|
||
opacity: 0;
|
||
/* Initial state */
|
||
visibility: hidden;
|
||
/* Prevents flickering */
|
||
}
|
||
|
||
.modal.show {
|
||
opacity: 1;
|
||
visibility: visible;
|
||
z-index: 1050;
|
||
/* Correct z-index for Bootstrap 5 modals */
|
||
}
|
||
|
||
.modal-backdrop {
|
||
z-index: 1040 !important;
|
||
/* Ensures backdrop is below the modal */
|
||
}
|
||
|
||
.swal2-html-container {
|
||
overflow: hidden !important;
|
||
}
|
||
|
||
.select2-selection__choice {
|
||
background-color: #0a8794 !important;
|
||
color: white !important;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.select2-selection__choice__remove {
|
||
color: white !important;
|
||
margin-right: 5px;
|
||
}
|
||
|
||
.table-collapsible-bar {
|
||
min-width: 1300px;
|
||
background-color: #f1f1f1;
|
||
padding: 10px;
|
||
cursor: pointer;
|
||
border: 1px solid #ddd;
|
||
border-radius: 4px 4px 0 0;
|
||
font-weight: bold;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.table-collapsible-bar .collapse-icon {
|
||
transition: transform 0.3s ease;
|
||
}
|
||
|
||
.table-collapsible-bar.collapsed .collapse-icon {
|
||
transform: rotate(-90deg);
|
||
}
|
||
|
||
.table-content {
|
||
overflow-x: auto;
|
||
width: 100%;
|
||
}
|
||
|
||
/* Ensure these styles are present */
|
||
.table-content {
|
||
transition: all 0.3s ease;
|
||
/* overflow: hidden; */
|
||
}
|
||
|
||
.table-content.collapse:not(.show) {
|
||
display: none;
|
||
}
|
||
|
||
.table-content.collapse.show {
|
||
display: block;
|
||
}
|
||
|
||
.collapse-icon {
|
||
transition: transform 0.3s ease;
|
||
}
|
||
|
||
.table-collapsible-bar {
|
||
cursor: pointer;
|
||
user-select: none;
|
||
}
|
||
|
||
</style>
|
||
|
||
|
||
<div class="col-12">
|
||
<div class="card">
|
||
<div class="card-body">
|
||
|
||
<div class="row" style="margin-bottom: 1rem;">
|
||
<div class="col-6" style="align-self: center;">
|
||
<h4 id="rfq_qcr_page_title">
|
||
<?= isset($page_name) ? htmlspecialchars($page_name, ENT_QUOTES, 'UTF-8') : 'RFQ Non-EB' ?>
|
||
</h4>
|
||
</div>
|
||
|
||
<div class="col-2" id="status_change" style="text-align: right; position: relative; top: 56px; left: 386px;">
|
||
<a onclick="checkTheTableDataChanged(1)" class="btn btn-primary">Back</a>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="row" style="margin-bottom: 1rem;margin-left: 0px;">
|
||
<button class="btn btn-custom rfqbtn" id="addProposal" style="margin-right: 10px;">Add New Proposal</button>
|
||
<button id="saveRFQ" onclick="saveRFQ()" class="btn btn-primary" style="margin-right: 10px;">Save RFQ</button>
|
||
<?php if (in_array(get_role_id(), [1,2,3,5]) || in_array(BUSINESS_SUPPORT_TEAM_ID, user_team())) { ?>
|
||
<button id="openQCR" onclick="openQCR()" class="btn btn-primary rfqbtn actionBtns" style="margin-right: 20px;">Proceed to QCR</button>
|
||
<?php } ?>
|
||
<a id="submitExcel" onclick="checkTheTableDataChanged(2)" class="btn btn-primary actionBtns" style="margin-right: 10px;">Export Excel</a>
|
||
<button id="submitInternalMail" class="btn btn-primary actionBtns" style="margin-right: 10px;" onclick="checkTheTableDataChanged(4)">Send Internal Mail</button>
|
||
<button id="submitMail" class="btn btn-primary actionBtns" style="margin-right: 10px;" onclick="checkTheTableDataChanged(3)">Send Insurer Mail</button>
|
||
<button id="submitPlacement" class="btn btn-primary qcrbtn actionBtns" onclick="checkTheTableDataChanged(6)">Placement</button>
|
||
</div>
|
||
|
||
|
||
<input type="hidden" id="lead_id" value="<?= htmlspecialchars($lead_data['id'] ?? "", ENT_QUOTES, 'UTF-8') ?>" />
|
||
|
||
<div id="allTableContainer">
|
||
<div id="tablesContainer"></div>
|
||
<?php include('policyRegisterModel.php'); ?>
|
||
<!-- <div id="excessContainer"></div> -->
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Modal content for Send Insurer and Client Mail -->
|
||
<div class="modal fade" id="list_model" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel"
|
||
aria-hidden="false">
|
||
<div class="modal-dialog modal-full-width">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h4 class="modal-title" id="myCenterModalLabel"></h4>
|
||
<button type="button" id="close_btn" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
|
||
<div class="form-group">
|
||
<div class="form-row" id="input_for_row">
|
||
</div>
|
||
</div>
|
||
|
||
<br>
|
||
<h4>Attachments Files</h4>
|
||
<hr>
|
||
|
||
<div class="form-group" id="insurer_or_clinet_mail_attachment">
|
||
<div class="form-row" >
|
||
<?php echo isset($attachment_html) && !empty($attachment_html) ? $attachment_html : ''; ?>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-group text-right m-b-0" id="hide_smbt_btn">
|
||
<button type="submit" class="btn btn-primary" onclick="constructURL(1)">Send Mail</button>
|
||
</div>
|
||
</div>
|
||
</div><!-- /.modal-content -->
|
||
</div>
|
||
</div><!-- /.modal -->
|
||
|
||
<!-- Modal content for Send Internal Mail -->
|
||
<div class="modal fade" id="internal_mail_modal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel"
|
||
aria-hidden="false">
|
||
<div class="modal-dialog modal-full-width">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h4 class="modal-title" id="internal_mail_modal_label">Send Internal Mail</h4>
|
||
<button type="button" id="close_btn" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
|
||
<div class="form-group">
|
||
|
||
<div class="form-row">
|
||
<div class="form-group col-md-4">
|
||
<label for="to">To </label>
|
||
<select class="form-control" id="to" name="to" required>
|
||
<?php if (isset($userList)) { ?>
|
||
<?php foreach ($userList as $user) { ?>
|
||
<option value="<?= $user['email']; ?>">
|
||
<?= $user['first_name'] . ' - ' . $user['email']; ?>
|
||
</option>
|
||
<?php } ?>
|
||
<?php } ?>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="form-group col-md-4">
|
||
<label for="cc">CC </label>
|
||
<select class="form-control" id="cc" name="cc" required multiple>
|
||
<?php if (isset($userList)) { ?>
|
||
<?php foreach ($userList as $user) { ?>
|
||
<option value="<?= $user['id']; ?>">
|
||
<?= $user['first_name'] . ' - ' . $user['email']; ?>
|
||
</option>
|
||
<?php } ?>
|
||
<?php } ?>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="form-group col-md-12">
|
||
<label for="subject">Subject</label>
|
||
<input id="subject" type="text" class="form-control" name="subject" value="<?= isset($subject) ? $subject : " " ?>">
|
||
</div>
|
||
|
||
<div class="form-group col-md-12">
|
||
<label for="internal_mail_content">Mail Content</label>
|
||
<textarea id="internal_mail_content" class="form-control" name="internal_mail_content" rows="3"><?= isset($mail_content) ? $mail_content : " " ?></textarea>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<br>
|
||
<h4>Attachments Files</h4>
|
||
<hr>
|
||
|
||
<div class="form-group" id="internal_mail_attachment">
|
||
<div class="form-row" >
|
||
<?php echo isset($attachment_html) && !empty($attachment_html) ? $attachment_html : ''; ?>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-group text-right m-b-0" id="hide_smbt_btn">
|
||
<button type="submit" class="btn btn-primary" onclick="constructURL(2)">Send Mail</button>
|
||
</div>
|
||
</div>
|
||
</div><!-- /.modal-content -->
|
||
</div>
|
||
</div><!-- /.modal -->
|
||
|
||
<!-- Modal content for Send Placement Mail -->
|
||
<div class="modal fade" id="placement_mail_modal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel"
|
||
aria-hidden="false">
|
||
<div class="modal-dialog modal-full-width">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h4 class="modal-title" id="myCenterModalLabel">Placement</h4>
|
||
<button type="button" id="close_btn" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
|
||
<div class="form-group">
|
||
|
||
<!-- For display perpose placement alredy submited text display -->
|
||
<div class="form-group col-md-12">
|
||
<label><span id="alert_msg" class="text-danger"></span></label>
|
||
</div>
|
||
|
||
<div class="form-row">
|
||
|
||
<div class="form-group col-md-3">
|
||
<label for="utr_no">UTR No.</label>
|
||
<input type="text" class="form-control" id="utr_no" name="utr_no" placeholder="Enter UTR No.">
|
||
</div>
|
||
|
||
<div class="form-group col-md-3">
|
||
<label for="placement_date">Placement Date</label>
|
||
<input type="text" class="form-control" id="placement_date" name="placement_date" placeholder="DD/MM/YYY">
|
||
</div>
|
||
|
||
<div class="form-group col-md-3">
|
||
<label for="premium_amount">Premium Amount</label>
|
||
<input type="text" class="form-control" id="premium_amount" name="premium_amount" placeholder="Enter Premium Amount">
|
||
</div>
|
||
|
||
<div class="form-group col-md-3">
|
||
<label for="total_amount">Total Amount</label>
|
||
<input type="text" class="form-control" id="total_amount" name="total_amount" placeholder="Enter Total Amount">
|
||
</div>
|
||
|
||
<div class="form-group col-md-3">
|
||
<label for="cd_amount">CD Amount</label>
|
||
<input type="text" class="form-control" id="cd_amount" name="cd_amount" placeholder="Enter CD Amount">
|
||
</div>
|
||
|
||
</div>
|
||
<hr>
|
||
<div class="form-row">
|
||
|
||
<div class="form-group col-md-6">
|
||
<label for="proposals"> Proposals/Insurer <span id="base_danger" class="text-danger">*</span></label>
|
||
<select class="form-control" id="proposals" name="proposals" onchange="getInsurerBranchContacts(this)" required>
|
||
<option value="">Select Proposals</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="form-group col-md-6">
|
||
<label for="placement_to"> To <span id="base_danger" class="text-danger">*</span></label>
|
||
<select class="form-control" id="placement_to" name="placement_to" required>
|
||
<option value="">Select To Mail</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="form-group col-md-6">
|
||
<label for="placement_cc">CC </label>
|
||
<select class="form-control" id="placement_cc" name="placement_cc" required multiple>
|
||
<?php if (isset($userList)) { ?>
|
||
<?php foreach ($userList as $user) { ?>
|
||
<option value="<?= $user['id']; ?>">
|
||
<?= $user['first_name'] . ' - ' . $user['email']; ?>
|
||
</option>
|
||
<?php } ?>
|
||
<?php } ?>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="form-group col-md-12">
|
||
<label for="subject">Subject</label>
|
||
<input type="text" class="form-control" id="placement_subject" name="placement_subject" value="<?= isset($subject) ? $subject : " " ?>" placeholder="Enter Subject">
|
||
</div>
|
||
|
||
</div>
|
||
<hr>
|
||
<div class="form-row">
|
||
<div class="form-group col-md-12">
|
||
<label for="mail_content">Mail Content</label>
|
||
<textarea id="placement_mail_content" class="form-control" name="placement_mail_content" rows="3"><?= isset($mail_content) ? $mail_content : " " ?></textarea>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<br>
|
||
<h4>Attachments Files</h4>
|
||
<hr>
|
||
|
||
<div class="form-group" id="placement_mail_attachment">
|
||
<div class="form-row" >
|
||
<?php echo isset($attachment_html) && !empty($attachment_html) ? $attachment_html : ''; ?>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-group text-right m-b-0" id="hide_smbt_btn">
|
||
<button type="submit" class="btn btn-primary" onclick="constructURL(3)">Send Mail</button>
|
||
</div>
|
||
|
||
</div>
|
||
</div><!-- /.modal-content -->
|
||
</div>
|
||
</div><!-- /.modal -->
|
||
|
||
<script>
|
||
// var randomColor = 'hsl(' + Math.random() * 360 + ', 100%, 93%)';
|
||
var rfq_data = <?= isset($rfq_data['json']) ? json_encode($rfq_data['json'], JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT) : '""' ?>;
|
||
rfq_data = rfq_data ? JSON.parse(rfq_data) : {}; // Convert to object if not already
|
||
|
||
var rfq_or_qcr = 1;
|
||
var proposalDataForDropDown = {};
|
||
var lead_type = "<?= $lead_data['lead_type'] ?>";
|
||
// alert(lead_type);
|
||
var rollover_or_renewal = "";
|
||
|
||
var rfq_count = "<?= $rfq_count ?? null?>";
|
||
// alert(rfq_count);
|
||
|
||
if (lead_type != 1){
|
||
|
||
rollover_or_renewal = lead_type == 2 ? "Existing Renewal" : "Existing Roll Over";
|
||
}
|
||
// alert(rollover_or_renewal);
|
||
|
||
var policyConfig = {
|
||
1: ['Quote asked']
|
||
};
|
||
|
||
let myModal;
|
||
var over_all_column_data = {
|
||
"Proposal 1": {
|
||
"qcr": 0,
|
||
"stc": 0,
|
||
'insurers': []
|
||
}
|
||
};
|
||
var suggestions = {};
|
||
var policyInformationData = <?= isset($rfq_data['registration_json']) ? json_encode($rfq_data['registration_json'], JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT) : '""' ?>;
|
||
var storedData = {};
|
||
// // console.log("stored data : ", typeof(policyInformationData))
|
||
|
||
localStorage.removeItem('policyData');
|
||
if (policyInformationData.length) {
|
||
|
||
localStorage.setItem('policyData', (policyInformationData));
|
||
storedData = policyInformationData;
|
||
}
|
||
|
||
var policySummary = [];
|
||
|
||
// // console.log("policy summary is set :", !$.isEmptyObject(policySummary) ? "no" : "yes")
|
||
$(document).ready(function() {
|
||
myModal = new bootstrap.Modal(document.getElementById('policyRegisterModel'));
|
||
});
|
||
var tableCount = 0;
|
||
const policies = <?= json_encode($policies) ?>;
|
||
// // console.log('policies', policies);
|
||
|
||
const child_table_data = <?= json_encode($child_table_data) ?>;
|
||
// // console.log('child_table_data', child_table_data);
|
||
|
||
const policyOrder = [{
|
||
'fire': {
|
||
"priority": 1
|
||
}
|
||
},
|
||
{
|
||
'burglary': {
|
||
"priority": 2
|
||
}
|
||
},
|
||
{
|
||
'flop': {
|
||
"priority": 3
|
||
}
|
||
},
|
||
{
|
||
'all_risk': {
|
||
"priority": 4
|
||
}
|
||
},
|
||
{
|
||
'mbd': {
|
||
"priority": 5
|
||
}
|
||
},
|
||
{
|
||
'eei': {
|
||
"priority": 6
|
||
}
|
||
},
|
||
{
|
||
'fidelity': {
|
||
"priority": 7
|
||
}
|
||
},
|
||
{
|
||
'money': {
|
||
"priority": 8
|
||
}
|
||
},
|
||
{
|
||
'plate_glass': {
|
||
"priority": 9
|
||
},
|
||
},
|
||
{
|
||
'neon_sign': {
|
||
"priority": 10
|
||
}
|
||
},
|
||
{
|
||
'public_liability': {
|
||
"priority": 11
|
||
}
|
||
}
|
||
];
|
||
|
||
let selectedPolicies = new Set();
|
||
|
||
let proposalCount = 1;
|
||
// // console.log("Proposal count changed", proposalCount);
|
||
let quotesConfig = {
|
||
1: ['Quote asked']
|
||
}; // Stores quote columns for each proposal
|
||
|
||
|
||
|
||
// Update all tables with the new quote column
|
||
function updateAllTables_old(proposalNumber, newQuote) {
|
||
const tables = document.querySelectorAll('table');
|
||
tables.forEach(table => {
|
||
const headerRow1 = table.querySelector('thead tr:first-child');
|
||
const headerRow2 = table.querySelector('thead tr:last-child');
|
||
|
||
// Update proposal header colspan
|
||
const proposalHeader = headerRow1.querySelector(`th[data-proposal="${proposalNumber}"]`);
|
||
if (proposalHeader) {
|
||
proposalHeader.colSpan = quotesConfig[proposalNumber].length;
|
||
}
|
||
|
||
// Calculate the position to insert the new quote column
|
||
let insertPosition = 2; // Start after Particulars column
|
||
for (let i = 1; i < proposalNumber; i++) {
|
||
insertPosition += quotesConfig[i]?.length || 0;
|
||
}
|
||
insertPosition += quotesConfig[proposalNumber].length - 1;
|
||
let table_id = table.id ? table.id : 'parent';
|
||
// // console.log('insert position of ' + table.id + ' - ' + insertPosition);
|
||
// Add new quote sub-header
|
||
const newQuoteHeader = document.createElement('th');
|
||
newQuoteHeader.textContent = newQuote;
|
||
headerRow2.insertBefore(newQuoteHeader, headerRow2.children[insertPosition]);
|
||
|
||
// Add new editable cells to all rows
|
||
table.querySelectorAll('tbody tr').forEach(row => {
|
||
const newCell = document.createElement('td');
|
||
newCell.contentEditable = true; // Make cell editable
|
||
row.insertBefore(newCell, row.children[insertPosition]);
|
||
});
|
||
});
|
||
}
|
||
|
||
// Generate the table (parent or child)
|
||
|
||
// Show dropdown menu
|
||
function showDropdown(event) {
|
||
// // console.log("dropdown function triggered");
|
||
const dropdown = event.target.nextElementSibling;
|
||
// // console.log(dropdown);
|
||
dropdown.style.display = dropdown.style.display === 'block' ? 'none' : 'block';
|
||
event.stopPropagation();
|
||
}
|
||
|
||
// Remove a proposal column
|
||
function removeProposal(proposalNumber) {
|
||
|
||
// alert(proposalNumber);
|
||
var rowIdCount = {};
|
||
|
||
let startIndex = 0;
|
||
// console.log("Remove Proposal startIndex : ",startIndex);
|
||
// console.log("Remove Proposal proposalNumber : ",proposalNumber);
|
||
|
||
|
||
// // console.log('removeProposal');
|
||
// console.log("quotesConfig",quotesConfig);
|
||
|
||
if (!quotesConfig[proposalNumber]) return; // If proposal doesn't exist, exit
|
||
if(Object.keys(quotesConfig).length == 1){
|
||
toastr.warning("You cannot Delete All the Proposals","Warning");
|
||
return;
|
||
}
|
||
// Remove all child columns for the proposal
|
||
const tables = document.querySelectorAll('table');
|
||
tables.forEach(table => {
|
||
|
||
const headerRow1 = table.querySelector('thead tr:first-child');
|
||
const headerRow2 = table.querySelector('thead tr:last-child');
|
||
|
||
// Find the proposal header and calculate its colspan
|
||
const proposalHeader = headerRow1.querySelector(`th[data-proposal="${proposalNumber}"]`);
|
||
if (proposalHeader) {
|
||
// console.log("Remove Proposal : quotesConfig ",quotesConfig[proposalNumber]);
|
||
// console.log("Remove Proposal : proposalHeader ",proposalHeader);
|
||
|
||
if (rfq_or_qcr == 1){
|
||
var colspan = parseInt(quotesConfig[proposalNumber].length);
|
||
}else{
|
||
var colspan = parseInt(proposalHeader.getAttribute('colspan'), 10);
|
||
}
|
||
// console.log("Remove Proposal : colspan ",colspan);
|
||
// Remove the proposal header
|
||
proposalHeader.remove();
|
||
|
||
// Remove corresponding sub-headers in the second header row
|
||
const subHeaders = headerRow2.querySelectorAll(`th`);
|
||
startIndex = 2; // Start after the first two columns (checkbox and Particulars)
|
||
// console.log("Remove Proposal : startIndex 2",startIndex);
|
||
// if (lead_type != 1){
|
||
// proposalNumber = proposalNumber + 1;
|
||
// }else{
|
||
|
||
// }
|
||
if (lead_type != 1){
|
||
for (let i = 0; i < proposalNumber; i++) {
|
||
// // console.log("quotesConfig[i] be", quotesConfig[i])
|
||
// // console.log("quotesConfig[i] length", quotesConfig[i]?.length)
|
||
|
||
|
||
startIndex += quotesConfig[i]?.length || 0;
|
||
|
||
|
||
// console.log("quotesConfig[i] after", quotesConfig[i]);
|
||
// console.log("Remove Proposal : startIndex 3",startIndex);
|
||
}
|
||
}else{
|
||
for (let i = 1; i < proposalNumber; i++) {
|
||
// // console.log("quotesConfig[i] be", quotesConfig[i])
|
||
// // console.log("quotesConfig[i] length", quotesConfig[i]?.length)
|
||
|
||
|
||
startIndex += quotesConfig[i]?.length || 0;
|
||
|
||
|
||
// console.log("quotesConfig[i] after", quotesConfig[i]);
|
||
// console.log("Remove Proposal : startIndex 3",startIndex);
|
||
}
|
||
}
|
||
|
||
for (let i = 0; i < colspan; i++) {
|
||
// console.log("Remove Proposal : colspan ",colspan);
|
||
// console.log("Remove Proposal : startIndex 4",startIndex)
|
||
headerRow2.removeChild(headerRow2.children[startIndex]);
|
||
}
|
||
|
||
// Remove corresponding cells in all rows
|
||
table.querySelectorAll('tbody tr').forEach(row => {
|
||
for (let i = 0; i < colspan; i++) {
|
||
var rowId = row.id;
|
||
if (rowIdCount[rowId] === undefined) {
|
||
rowIdCount[rowId] = 0;
|
||
} else {
|
||
rowIdCount[rowId]++;
|
||
}
|
||
// console.log("rowIdCount[rowId]", rowIdCount[rowId]);
|
||
newStartIndex = rowIdCount[rowId] > 0 ? startIndex-1 : startIndex;
|
||
// console.log("newStartIndex", newStartIndex)
|
||
row.removeChild(row.children[newStartIndex]);
|
||
|
||
}
|
||
});
|
||
}
|
||
});
|
||
|
||
// Remove the proposal from quotesConfig
|
||
delete quotesConfig[proposalNumber];
|
||
|
||
delete policyConfig[proposalNumber];
|
||
// // console.log("DELETE INSURE : policyConfig",policyConfig);
|
||
// // console.log("DELETE INSURE : quotesConfig",quotesConfig);
|
||
// alert(quotesConfig);
|
||
// alert(policyConfig)
|
||
// console.log('End of the functions')
|
||
}
|
||
|
||
// Add a new row
|
||
function addRow(event, element) {
|
||
|
||
// // console.log(' event ', element);
|
||
const button = event.target;
|
||
const row = button.closest('tr');
|
||
const table = row.closest('table');
|
||
const newRow = row.cloneNode(true);
|
||
// // console.log("old Row ", row);
|
||
// return false;
|
||
var tableID = table.id;
|
||
|
||
let nextSNO = getSNO(tableID);
|
||
// Clear input values and generate new IDs
|
||
newRow.querySelectorAll('td').forEach((td, index) => {
|
||
if (index === 0) {
|
||
// // console.log("Trying to set sno");
|
||
td.innerHTML = "";
|
||
td.innerHTML = `${nextSNO}`;
|
||
}
|
||
if (index !== 0 && index !== row.cells.length - 1) td.textContent = '-';
|
||
});
|
||
|
||
table.querySelector('tbody').appendChild(newRow);
|
||
updateSNO(table.id);
|
||
}
|
||
|
||
// Remove a row
|
||
function removeRow(event) {
|
||
const button = event.target;
|
||
const row = button.closest('tr');
|
||
const table = row.closest('table');
|
||
if (row && row.parentElement.children.length > 1) {
|
||
// // console.log("Row Removed");
|
||
row.remove();
|
||
updateSNO(table.id);
|
||
}
|
||
}
|
||
|
||
//function to hide all the 3 dot actions for the child table
|
||
function hideProposalOptionsForChild() {
|
||
// // // console.log('function called');
|
||
const parentTable = document.querySelector("table");
|
||
const tables = document.querySelectorAll('table');
|
||
|
||
// // // console.log('parentTable : ',parentTable);
|
||
tables.forEach(table => {
|
||
if (table !== parentTable) {
|
||
// Hide .three-dot-menu in all other tables
|
||
$(table).find(".three-dot-menu").hide();
|
||
// // // console.log("hided 3 dot menu in the table",table);
|
||
}
|
||
});
|
||
}
|
||
document.addEventListener("change", function(event) {
|
||
const checkbox = event.target;
|
||
if (checkbox.classList.contains("qcr-checkbox")) {
|
||
// // // console.log("QCR checkbox change detected");
|
||
|
||
// Get the row containing the checkbox
|
||
const row = checkbox.closest('tr');
|
||
|
||
// Find the corresponding client-checkbox in the same row
|
||
const clientCheckbox = row.querySelector('.client-checkbox');
|
||
|
||
if (clientCheckbox) {
|
||
// Sync the client-checkbox state with the qcr-checkbox state
|
||
clientCheckbox.checked = checkbox.checked;
|
||
|
||
// Optionally, you can trigger any additional logic here
|
||
if (checkbox.checked) {
|
||
// // // console.log("QCR checkbox is checked, client-checkbox is also checked");
|
||
} else {
|
||
// // // console.log("QCR checkbox is unchecked, client-checkbox is also unchecked");
|
||
}
|
||
} else {
|
||
// // console.warn("No client-checkbox found in the same row");
|
||
}
|
||
} else if (checkbox.classList.contains("client-checkbox")) {
|
||
// // console.log("trying to change");
|
||
const row = checkbox.closest('tr');
|
||
const qcrCheckbox = row.querySelector('.qcr-checkbox');
|
||
|
||
if (!qcrCheckbox.checked) {
|
||
toastr.warning("QCR checkbox is not checked, preventing client-checkbox selection", "Warning");
|
||
checkbox.checked = false; // Prevent selection
|
||
}
|
||
}
|
||
})
|
||
|
||
// Add this once during initial page setup
|
||
document.getElementById('tablesContainer').addEventListener('change', function(event) {
|
||
checkCellValueAndHighlight();
|
||
const container = document.getElementById('tablesContainer');
|
||
const checkbox = event.target;
|
||
if (checkbox.classList.contains('sno-checkbox')) {
|
||
const rowId = checkbox.closest('tr').id;
|
||
const table = checkbox.closest('table');
|
||
if (checkbox.checked) {
|
||
const childContainer = document.createElement('div');
|
||
selectedPolicies.add(rowId);
|
||
child_table_data[rowId]?.forEach(childTable => {
|
||
if (childTable.table_type == "append") {
|
||
var tableName = childTable.table_id;
|
||
// // console.log("table name ", tableName);
|
||
// Handle excess table
|
||
const excessContainer = document.createElement('div');
|
||
excessContainer.setAttribute('data-parent-row', tableName);
|
||
excessContainer.setAttribute(`data-${tableName}-container`, 'true');
|
||
|
||
var result = generateExcessTable(childTable, rowId, tableName);
|
||
if (result) {
|
||
generateTable(excessContainer, true, rowId, childTable);
|
||
container.appendChild(excessContainer);
|
||
// // // console.log('Row id for excess table',rowId);
|
||
$("#excess .three-dot-menu").hide();
|
||
moveExcessTableLast();
|
||
}
|
||
} else {
|
||
// Handle regular table
|
||
childContainer.setAttribute('data-parent-row', rowId);
|
||
generateTable(childContainer, true, rowId, childTable);
|
||
// // // console.log('Row id for excess table', rowId);
|
||
$(childContainer).find(".three-dot-menu").hide();
|
||
|
||
// alert(`${rowId.toUpperCase()}_register`);
|
||
$(`#${rowId.toUpperCase()}_register`).prop("disabled", false);
|
||
moveExcessTableLast();
|
||
|
||
}
|
||
});
|
||
|
||
// Only append regular container if it has content
|
||
if (childContainer.hasChildNodes()) {
|
||
container.appendChild(childContainer);
|
||
}
|
||
styleTableColumns();
|
||
arrangeTables();
|
||
alignTableColumn();
|
||
} else {
|
||
// // console.log('UNCHECKED:', rowId);
|
||
selectedPolicies.delete(rowId);
|
||
// Remove regular child tables
|
||
const regularContainers = container.querySelectorAll(`div[data-parent-row="${rowId}"]:not([data-excess-container])`);
|
||
regularContainers.forEach(container => {
|
||
// // console.log(" contaitner ", container);
|
||
|
||
$(`#${rowId.toUpperCase()}_register`).prop("disabled", true);
|
||
container.remove();
|
||
});
|
||
// // console.log("row id ", rowId);
|
||
// Handle excess table rows
|
||
const excessTable = document.getElementById('excess');
|
||
if (excessTable) {
|
||
// Remove rows associated with this checkbox
|
||
const excessRows = excessTable.querySelectorAll(`tbody tr[data-excess-row-parent="${rowId}"]`);
|
||
excessRows.forEach(row => row.remove());
|
||
|
||
// Check if excess table is empty
|
||
const remainingRows = excessTable.querySelector('tbody').children;
|
||
// // // console.log(remainingRows);
|
||
if (remainingRows.length === 0) {
|
||
// Remove the entire excess table container
|
||
// const excessContainer = excessTable.closest('div[data-excess-container]');
|
||
const excessContainer = $('#excess');
|
||
const excessCollapseBar = document.querySelector('.table-collapsible-bar.Excess');
|
||
if (excessContainer) {
|
||
excessContainer.remove();
|
||
excessCollapseBar.remove();
|
||
}
|
||
} else {
|
||
updateSNO('excess')
|
||
}
|
||
}
|
||
}
|
||
} else if (checkbox.classList.contains("qcr-checkbox")) {
|
||
// // console.log("QCR checkbox change detected");
|
||
|
||
// Get the row containing the checkbox
|
||
const row = checkbox.closest('tr');
|
||
|
||
// Find the corresponding client-checkbox in the same row
|
||
const clientCheckbox = row.querySelector('.client-checkbox');
|
||
|
||
if (clientCheckbox) {
|
||
// Sync the client-checkbox state with the qcr-checkbox state
|
||
clientCheckbox.checked = checkbox.checked;
|
||
|
||
// Optionally, you can trigger any additional logic here
|
||
if (checkbox.checked) {
|
||
// // console.log("QCR checkbox is checked, client-checkbox is also checked");
|
||
} else {
|
||
// // console.log("QCR checkbox is unchecked, client-checkbox is also unchecked");
|
||
}
|
||
} else {
|
||
// console.warn("No client-checkbox found in the same row");
|
||
}
|
||
}
|
||
});
|
||
// Add a new proposal
|
||
document.getElementById('addProposal').addEventListener('click', () => {
|
||
// // console.log("proposal count before ", proposalCount);
|
||
proposalCount++;
|
||
// // console.log("proposal count after ", proposalCount);
|
||
|
||
quotesConfig[proposalCount] = ['Quote asked'];
|
||
policyConfig[proposalCount] = ['Quote asked'];
|
||
const tables = document.querySelectorAll('table');
|
||
let increaseBy = 150;
|
||
increaseTableWidth(increaseBy);
|
||
var randomColor = `hsl(${Math.random() * 360}, 100%, 93%)`;
|
||
|
||
tables.forEach(table => {
|
||
const headerRow1 = table.querySelector('thead tr:first-child');
|
||
const headerRow2 = table.querySelector('thead tr:last-child');
|
||
|
||
// Add new proposal header
|
||
const newProposalHeader = document.createElement('th');
|
||
newProposalHeader.setAttribute('data-proposal', proposalCount);
|
||
newProposalHeader.colSpan = 1;
|
||
newProposalHeader.style.backgroundColor = randomColor;
|
||
newProposalHeader.innerHTML = `
|
||
Proposal ${proposalCount}
|
||
<span class="three-dot-menu" onclick="showDropdown(event)">⋮</span>
|
||
<div class="dropdown-content">
|
||
<button id="isQCR" onclick="addOrRemoveIcon(this,event)" class="qcrProposal" style="background-color: rgb(221, 221, 221);">QCR <i
|
||
class="fa fa-check-square"
|
||
style="color: green; margin-left: 8px;"></i></button>
|
||
<button id="isSTC" class="sendClientProposal" onclick="addOrRemoveIcon(this,event)"
|
||
style="background-color: rgb(221, 221, 221);">Send to Client <i
|
||
class="fa fa-check-square"
|
||
style="color: green; margin-left: 8px;"></i></button>
|
||
<button class = "removeProposal" onclick="removeProposal(${proposalCount})">Remove Proposal</button>
|
||
<button class="newInsurer" onclick="addNewQuote(${proposalCount})">Add New Insurer</button>
|
||
</div>
|
||
`;
|
||
headerRow1.insertBefore(newProposalHeader, headerRow1.lastElementChild);
|
||
|
||
// Add new quote sub-header
|
||
const newQuoteHeader = document.createElement('th');
|
||
newQuoteHeader.textContent = 'Quote asked';
|
||
newQuoteHeader.style.backgroundColor = randomColor;
|
||
headerRow2.insertBefore(newQuoteHeader, headerRow2.querySelector('th:last-child'));
|
||
|
||
// Add new cells to all rows
|
||
table.querySelectorAll('tbody tr').forEach(row => {
|
||
const cells = Array.from(row.getElementsByTagName('td'));
|
||
let targetCell = null;
|
||
let columnCount = 0;
|
||
let spannedColumns = 0;
|
||
|
||
// Account for cells spanned from previous rows
|
||
const rowIndex = Array.from(table.querySelectorAll('tbody tr')).indexOf(row);
|
||
table.querySelectorAll('tbody tr').forEach((prevRow, prevIndex) => {
|
||
if (prevIndex >= rowIndex) return;
|
||
Array.from(prevRow.getElementsByTagName('td')).forEach(cell => {
|
||
const rowspan = parseInt(cell.getAttribute('rowspan') || 1);
|
||
if (rowspan > 1 && prevIndex + rowspan > rowIndex) {
|
||
spannedColumns++;
|
||
}
|
||
});
|
||
});
|
||
|
||
// Find the actual third column cell
|
||
for (let i = 0; i < cells.length && columnCount < 3; i++) {
|
||
columnCount++;
|
||
if (columnCount + spannedColumns === 3) {
|
||
targetCell = cells[i];
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (!targetCell) {
|
||
// Fallback: use the last available cell if third column not found
|
||
targetCell = cells[cells.length - 1];
|
||
}
|
||
|
||
// // console.log("ADD PROPOSAL : targetCell", targetCell);
|
||
const newCell = targetCell.cloneNode(true);
|
||
// // console.log("ADD PROPOSAL : newCell", newCell);
|
||
|
||
newCell.contentEditable = true;
|
||
newCell.onclick = () => getAnswer(table.id, row.id);
|
||
newCell.style.backgroundColor = randomColor;
|
||
row.insertBefore(newCell, row.querySelector('td:last-child'));
|
||
});
|
||
});
|
||
|
||
// console.log(quotesConfig);
|
||
// console.log(policyConfig);
|
||
|
||
hideProposalOptionsForChild();
|
||
showOrHideFieldsBasedOnRFQorQCR();
|
||
// styleTableColumns();
|
||
});
|
||
|
||
// #################################################################################
|
||
|
||
function addNewQuote(proposalNumber) {
|
||
// // console.log("add new Quote start : ", quotesConfig);
|
||
const insurers = <?= json_encode($insurer); ?>;
|
||
selectInsurer(insurers).then(result => {
|
||
insurer = result.selectedInsurer;
|
||
version = result.insurerDetails;
|
||
dataId = result.dataId;
|
||
|
||
insurerName = `${insurer}${version != "" ? " v"+ version : ""}`;
|
||
|
||
let increaseBy = 100;
|
||
increaseTableWidth(increaseBy);
|
||
// // // console.log("Selected Insurer:", insurerName);
|
||
// // // console.log("Entered Version:", version);
|
||
// // // console.log("Entered data id:", dataId);
|
||
// // console.log("add new Quote : ", proposalNumber);
|
||
// // console.log("add new Quote : ", quotesConfig);
|
||
// // console.log("Add new quote insurer name : ", insurerName);
|
||
if (!quotesConfig[proposalNumber]) return;
|
||
// // console.log("add new quote ", quotesConfig[proposalNumber]);
|
||
if (quotesConfig[proposalNumber].includes(insurerName)) {
|
||
// // console.log("add new quote is duplicate");
|
||
Swal.fire({
|
||
title: "Insurer Dublicate Found?",
|
||
text: "Do you want version control!",
|
||
icon: "warning",
|
||
showCancelButton: true,
|
||
confirmButtonColor: "#3085d6",
|
||
cancelButtonColor: "#d33",
|
||
confirmButtonText: "Yes, Procced!"
|
||
}).then((result) => {
|
||
|
||
if (result.isConfirmed) {
|
||
// Handle versioning logic here for duplicate insurer
|
||
let baseInsurerName = insurer;
|
||
let count = 0;
|
||
|
||
// Count how many times this insurer appears in the current proposal
|
||
for (let i = 0; i < quotesConfig[proposalNumber].length; i++) {
|
||
if (quotesConfig[proposalNumber][i].startsWith(baseInsurerName)) {
|
||
count++;
|
||
// // console.log("add count ", count);
|
||
}
|
||
}
|
||
|
||
// Auto-increment version
|
||
if (version === "") {
|
||
insurerName = `${baseInsurerName} v${count + 1}`;
|
||
version = count + 1;
|
||
// // console.log("add inurer name ", insurerName);
|
||
} else {
|
||
// If user already specified version, append count to make it unique
|
||
insurerName = `${baseInsurerName} v${version}_${count + 1}`;
|
||
version = `${version}_${count + 1}`;
|
||
// // console.log("add inurer name else", insurerName);
|
||
|
||
}
|
||
var insurerDetails = {
|
||
id: dataId,
|
||
version: version,
|
||
insurerName: insurerName
|
||
}
|
||
policyConfig[proposalNumber].push(insurerDetails);
|
||
const newQuote = insurerName;
|
||
quotesConfig[proposalNumber].push(newQuote);
|
||
// // console.log("add Quotes config", quotesConfig);
|
||
updateAllTables(proposalNumber, insurerName);
|
||
|
||
var proposalName = `Proposal ${proposalNumber}`;
|
||
const proposalHeader = document.querySelector(`th[data-proposal="${proposalNumber}"]`);
|
||
if (proposalHeader) {
|
||
proposalHeader.colSpan = quotesConfig[proposalNumber].length;
|
||
}
|
||
|
||
}
|
||
});
|
||
} else {
|
||
var insurerDetails = {
|
||
id: dataId,
|
||
version: version,
|
||
insurerName: insurerName
|
||
}
|
||
policyConfig[proposalNumber].push(insurerDetails);
|
||
const newQuote = insurerName;
|
||
quotesConfig[proposalNumber].push(newQuote);
|
||
// // console.log("add Quotes config", quotesConfig);
|
||
updateAllTables(proposalNumber, insurerName);
|
||
|
||
var proposalName = `Proposal ${proposalNumber}`;
|
||
const proposalHeader = document.querySelector(`th[data-proposal="${proposalNumber}"]`);
|
||
if (proposalHeader) {
|
||
// // console.log("Proposal heade length : ", quotesConfig[proposalNumber].length)
|
||
proposalHeader.colSpan = quotesConfig[proposalNumber].length;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
showOrHideFieldsBasedOnRFQorQCR();
|
||
// styleTableColumns();
|
||
hideProposalOptionsForChild();
|
||
});
|
||
|
||
}
|
||
|
||
function changeInsurer(event, proposalNumber, currentInsurer) {
|
||
// Stop event propagation
|
||
event.stopPropagation();
|
||
// // console.log("insurer change function called ", quotesConfig[proposalNumber]);
|
||
if (!quotesConfig[proposalNumber]) return;
|
||
const insurers = <?= json_encode($insurer); ?>;
|
||
|
||
selectInsurer(insurers).then(result => {
|
||
let newInsurerName = result.selectedInsurer;
|
||
let newversion = result.insurerDetails;
|
||
let newdataId = result.dataId;
|
||
var insurerDetailsChange = {
|
||
id: newdataId,
|
||
version: newversion,
|
||
insurerName: newInsurerName
|
||
}
|
||
if (newversion.trim() !== '') {
|
||
newInsurerName = `${newInsurerName}-${newversion.trim()}`.replace(/\s+/g, '');
|
||
}
|
||
|
||
// // console.log('insurer newInsurerName', newInsurerName);
|
||
// // console.log('insurer newversion', newversion);
|
||
|
||
if (newInsurerName) {
|
||
// // // console.log("insurer inside new insurer name : ",headerRow2);
|
||
// Update all tables with the new insurer
|
||
document.querySelectorAll('table').forEach(table => {
|
||
const headerRow2 = table.querySelector('thead tr:last-child');
|
||
// // console.log("insurer inside ", headerRow2);
|
||
// Find the header cells that match our criteria
|
||
Array.from(headerRow2.children).forEach(th => {
|
||
// Check if this cell contains our insurer and proposal
|
||
// // console.log("insurer proposal number : ", proposalNumber);
|
||
// // console.log("insurer header proposal number : ", th);
|
||
if (th.getAttribute('data-proposal') === proposalNumber.toString()) {
|
||
// Get the first text node (the insurer name part)
|
||
let content = th.innerHTML;
|
||
// // console.log("insurer inside ", content);
|
||
// Only replace the exact insurer name, not any menu text
|
||
if (content.includes(currentInsurer)) {
|
||
// Create a regex to match just the insurer name
|
||
const regex = new RegExp(currentInsurer, 'g');
|
||
th.innerHTML = content.replace(regex, newInsurerName);
|
||
|
||
// Update attributes
|
||
if (th.hasAttribute('data-insurer')) {
|
||
th.setAttribute('data-insurer', newInsurerName);
|
||
}
|
||
|
||
if (newdataId && th.hasAttribute('data-id')) {
|
||
th.setAttribute('data-id', dataId);
|
||
}
|
||
|
||
// Update quote code in quotesConfig
|
||
const oldQuoteCode = th.getAttribute('data-quote');
|
||
if (oldQuoteCode) {
|
||
const quoteIndex = quotesConfig[proposalNumber].indexOf(oldQuoteCode);
|
||
if (quoteIndex !== -1) {
|
||
// Generate new quote code based on new insurer
|
||
const newQuoteCode = oldQuoteCode.replace(currentInsurer, newInsurerName);
|
||
quotesConfig[proposalNumber][quoteIndex] = newQuoteCode;
|
||
// // console.log("Existing policy data ", policyConfig[proposalNumber][quoteIndex]);
|
||
policyConfig[proposalNumber][quoteIndex] = insurerDetailsChange;
|
||
// // console.log("quote index ", quoteIndex);
|
||
// // console.log("changed like this ", insurerDetailsChange);
|
||
// Update data-quote attribute
|
||
th.setAttribute('data-quote', newQuoteCode);
|
||
}
|
||
}
|
||
|
||
// Find and update corresponding data cells
|
||
const colIndex = Array.from(th.parentNode.children).indexOf(th);
|
||
table.querySelectorAll(`tbody tr`).forEach(row => {
|
||
const cell = row.children[colIndex];
|
||
if (cell) {
|
||
if (cell.hasAttribute('data-insurer')) {
|
||
cell.setAttribute('data-insurer', newInsurerName);
|
||
}
|
||
if (cell.hasAttribute('data-quote')) {
|
||
const oldQuote = cell.getAttribute('data-quote');
|
||
const newQuote = oldQuote.replace(currentInsurer, newInsurerName);
|
||
cell.setAttribute('data-quote', newQuote);
|
||
}
|
||
}
|
||
});
|
||
}
|
||
}
|
||
});
|
||
});
|
||
|
||
// Show success message
|
||
toastr.success("Insurer Changed", "Success");
|
||
}
|
||
});
|
||
}
|
||
|
||
function removeQuote(event, proposalNumber, quoteCode) {
|
||
event.stopPropagation();
|
||
var rowIdCount = {};
|
||
|
||
if (!quotesConfig[proposalNumber]) return;
|
||
|
||
// Remove quote from config
|
||
const quoteIndex = quotesConfig[proposalNumber].indexOf(quoteCode);
|
||
// // console.log("quote index ", quoteIndex);
|
||
if (quoteIndex !== -1) {
|
||
quotesConfig[proposalNumber].splice(quoteIndex, 1);
|
||
policyConfig[proposalNumber].splice(quoteIndex, 1);
|
||
if (quotesConfig[proposalNumber].length === 0) {
|
||
delete quotesConfig[proposalNumber];
|
||
delete policyConfig[proposalNumber];
|
||
}
|
||
}
|
||
|
||
// Remove from all tables
|
||
document.querySelectorAll('table').forEach(table => {
|
||
const headerRow1 = table.querySelector('thead tr:first-child');
|
||
const headerRow2 = table.querySelector('thead tr:last-child');
|
||
|
||
// Find and remove quote header
|
||
const targetIndex = Array.from(headerRow2.children).findIndex(th =>
|
||
th.textContent.includes(quoteCode) &&
|
||
th.getAttribute('data-proposal') === proposalNumber.toString()
|
||
);
|
||
// // console.log("quote target index ", targetIndex);
|
||
if (targetIndex !== -1) {
|
||
// // console.log("quote target index inside if", targetIndex);
|
||
// Remove from header row 2
|
||
headerRow2.removeChild(headerRow2.children[targetIndex]);
|
||
|
||
// Update proposal header colspan
|
||
const proposalHeader = headerRow1.querySelector(`th[data-proposal="${proposalNumber}"]`);
|
||
// // console.log("quote target index inside if proposal header", proposalHeader);
|
||
|
||
if (proposalHeader) {
|
||
const newColspan = parseInt(proposalHeader.colSpan) - 1;
|
||
// // console.log("Quote new colspan : ", newColspan);
|
||
if (newColspan > 0) {
|
||
proposalHeader.colSpan = newColspan;
|
||
} else {
|
||
proposalHeader.remove();
|
||
}
|
||
}
|
||
|
||
// Remove from data rows
|
||
table.querySelectorAll('tbody tr').forEach(row => {
|
||
const cellIndex = targetIndex; // No need to add 2 since we're using children array
|
||
// console.log("quote target index", cellIndex);
|
||
|
||
var rowId = row.id;
|
||
if (rowIdCount[rowId] === undefined) {
|
||
rowIdCount[rowId] = 0;
|
||
} else {
|
||
rowIdCount[rowId]++;
|
||
}
|
||
// console.log("rowIdCount[rowId]", rowIdCount[rowId]);
|
||
newStartIndex = rowIdCount[rowId] > 0 ? cellIndex-1 : cellIndex;
|
||
// console.log("quote target index inside if proposal header", newStartIndex);
|
||
|
||
if (row.children[cellIndex]) {
|
||
row.removeChild(row.children[newStartIndex]);
|
||
// // console.log("quote target index inside if proposal header", row);
|
||
|
||
}
|
||
});
|
||
}
|
||
});
|
||
}
|
||
|
||
function updateAllTables(proposalNumber, newQuote) {
|
||
// alert(proposalNumber);
|
||
document.querySelectorAll('table').forEach(table => {
|
||
|
||
const headerRow1 = table.querySelector('thead tr:first-child');
|
||
const headerRow2 = table.querySelector('thead tr:last-child');
|
||
// // console.log('headerRow2 data', headerRow2);
|
||
// // console.log('headerRow2 headerRow2.children', headerRow2.children);
|
||
|
||
|
||
const proposalHeader = headerRow1.querySelector(`th[data-proposal="${proposalNumber}"]`);
|
||
console.log("Proposal proposalNumber : ", proposalNumber);
|
||
// Create new quote header
|
||
const newQuoteHeader = document.createElement('th');
|
||
newQuoteHeader.innerHTML = `
|
||
${newQuote}
|
||
<span class="three-dot-menu" onclick="showDropdown(event)">⋮</span>
|
||
<div class="dropdown-content">
|
||
<button id="isInsurerSTC" class="sendInsurerClientProposal" onclick="addOrRemoveIconInsurer(this,event)"
|
||
style="background-color: rgb(221, 221, 221;">
|
||
Send to Client <i class="fa fa-check-square" style="color: green; margin-left: 8px;"></i>
|
||
</button>
|
||
<button onclick="changeInsurer(event, ${proposalNumber}, '${newQuote}')">Change Insurer</button>
|
||
<button onclick="removeQuote(event, ${proposalNumber}, '${newQuote}')">Remove Quote</button>
|
||
</div>
|
||
`;
|
||
newQuoteHeader.dataset.proposal = proposalNumber;
|
||
newQuoteHeader.dataset.quote = newQuote;
|
||
|
||
// Calculate header insert position
|
||
let insertPosition = 2;
|
||
if (lead_type == 1){
|
||
for (let i = 1; i < proposalNumber; i++) {
|
||
insertPosition += quotesConfig[i]?.length || 0;
|
||
}
|
||
}else{
|
||
for (let i = 0; i < proposalNumber; i++) {
|
||
insertPosition += quotesConfig[i]?.length || 0;
|
||
}
|
||
}
|
||
|
||
insertPosition += quotesConfig[proposalNumber].length - 1;
|
||
// // console.log("Header insert position : ", insertPosition);
|
||
|
||
if (headerRow2.children[insertPosition - 1]) {
|
||
|
||
let referenceChild = headerRow2.children[insertPosition - 1]; // Get the target child
|
||
// // console.log("referenceChild", referenceChild);
|
||
let computedStyle = window.getComputedStyle(referenceChild);
|
||
// // console.log("computedStyle", computedStyle);
|
||
|
||
|
||
// Copy all computed styles
|
||
let backgroundColor = computedStyle.getPropertyValue("background-color");
|
||
newQuoteHeader.style.backgroundColor = backgroundColor;
|
||
|
||
}
|
||
|
||
headerRow2.insertBefore(newQuoteHeader, headerRow2.children[insertPosition]);
|
||
if (proposalHeader) proposalHeader.colSpan = quotesConfig[proposalNumber].length;
|
||
|
||
// Add new cells to body rows
|
||
table.querySelectorAll('tbody tr').forEach((row, rowIndex) => {
|
||
const cells = Array.from(row.children);
|
||
let hasRowspanGreaterThan1 = false;
|
||
|
||
// Check if any cell in this row or previous rows affecting this row has rowspan > 1
|
||
for (let r = 0; r <= rowIndex; r++) {
|
||
const checkRow = table.querySelectorAll('tbody tr')[r];
|
||
Array.from(checkRow.children).forEach(cell => {
|
||
const rowspan = parseInt(cell.getAttribute('rowspan') || 1);
|
||
if (rowspan > 1 && r + rowspan > rowIndex) {
|
||
hasRowspanGreaterThan1 = true;
|
||
}
|
||
});
|
||
}
|
||
|
||
if (!hasRowspanGreaterThan1) {
|
||
// Original method for rowspan = 1 or no rowspan
|
||
const lastCell = row.querySelector(`td:nth-child(${insertPosition})`);
|
||
const newCell = lastCell.cloneNode(true);
|
||
if (lastCell.classList.contains("readonly-select")) {
|
||
newCell.classList.remove("readonly-select");
|
||
}
|
||
newCell.contentEditable = true;
|
||
newCell.onclick = () => getAnswer(table.id, row.id);
|
||
row.insertBefore(newCell, row.children[insertPosition]);
|
||
} else {
|
||
// Handle rowspan > 1
|
||
let visualColumn = 0;
|
||
let referenceCell = null;
|
||
let insertBeforeCell = null;
|
||
|
||
// Map visual columns considering spans from this and previous rows
|
||
const columnOccupancy = new Array(headerRow2.children.length).fill(false);
|
||
|
||
// Mark columns occupied by rowspans from previous rows
|
||
for (let prevRowIndex = 0; prevRowIndex < rowIndex; prevRowIndex++) {
|
||
const prevRow = table.querySelectorAll('tbody tr')[prevRowIndex];
|
||
let prevVisualColumn = 0;
|
||
Array.from(prevRow.children).forEach(cell => {
|
||
const colspan = parseInt(cell.getAttribute('colspan') || 1);
|
||
const rowspan = parseInt(cell.getAttribute('rowspan') || 1);
|
||
if (prevRowIndex + rowspan > rowIndex) {
|
||
for (let i = 0; i < colspan; i++) {
|
||
columnOccupancy[prevVisualColumn + i] = true;
|
||
}
|
||
}
|
||
prevVisualColumn += colspan;
|
||
});
|
||
}
|
||
|
||
// Process current row
|
||
for (let i = 0; i < cells.length; i++) {
|
||
const cell = cells[i];
|
||
const colspan = parseInt(cell.getAttribute('colspan') || 1);
|
||
|
||
// Skip columns occupied by previous rowspans
|
||
while (columnOccupancy[visualColumn]) {
|
||
visualColumn++;
|
||
}
|
||
|
||
if (visualColumn === insertPosition - 1) {
|
||
referenceCell = cell;
|
||
insertBeforeCell = cells[i + 1] || null;
|
||
} else if (visualColumn < insertPosition && visualColumn + colspan > insertPosition) {
|
||
referenceCell = cell;
|
||
insertBeforeCell = cells[i + 1] || null;
|
||
}
|
||
|
||
visualColumn += colspan;
|
||
}
|
||
|
||
// If no reference found, use last cell before insertPosition
|
||
if (!referenceCell) {
|
||
for (let i = cells.length - 1; i >= 0; i--) {
|
||
const cell = cells[i];
|
||
let cellStartColumn = 0;
|
||
for (let j = 0; j < i; j++) {
|
||
cellStartColumn += parseInt(cells[j].getAttribute('colspan') || 1);
|
||
}
|
||
if (cellStartColumn <= insertPosition - 1) {
|
||
referenceCell = cell;
|
||
insertBeforeCell = cells[i + 1] || null;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Fallback to first cell if still no reference
|
||
if (!referenceCell && cells.length > 0) {
|
||
referenceCell = cells[0];
|
||
insertBeforeCell = cells[1] || null;
|
||
}
|
||
|
||
const newCell = referenceCell.cloneNode(true);
|
||
newCell.contentEditable = true;
|
||
newCell.onclick = () => getAnswer(table.id, row.id);
|
||
newCell.removeAttribute('rowspan');
|
||
newCell.removeAttribute('colspan');
|
||
|
||
if (insertBeforeCell) {
|
||
row.insertBefore(newCell, insertBeforeCell);
|
||
} else {
|
||
row.appendChild(newCell);
|
||
}
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
function generateTable(container, isChildTable = false, parentRowId = null, tableData = null) {
|
||
const tableContainer = document.createElement('div');
|
||
tableContainer.className = 'table-container';
|
||
|
||
// Create collapsible bar with Bootstrap 4 attributes
|
||
const collapsibleBar = document.createElement('div');
|
||
collapsibleBar.className = `table-collapsible-bar ${tableData ? tableData.table_name : 'Particulars'} collapsed`;
|
||
collapsibleBar.setAttribute('data-toggle', 'collapse'); // Bootstrap 4 collapse trigger
|
||
const collapseId = `collapse-${tableData ? tableData.table_id : 'parent'}`; // Unique ID
|
||
collapsibleBar.setAttribute('data-target', `#${collapseId}`);
|
||
collapsibleBar.innerHTML = `
|
||
${tableData ? tableData.table_name : "Particulars"}
|
||
<span class="collapse-icon">▼</span>
|
||
`;
|
||
|
||
// Create table content wrapper with Bootstrap 4 collapse class
|
||
const tableContent = document.createElement('div');
|
||
tableContent.className = 'table-content collapse'; // Bootstrap 4 collapse class
|
||
tableContent.id = collapseId; // Matches data-target
|
||
|
||
const table = document.createElement('table');
|
||
if (tableData) {
|
||
table.id = tableData.table_id;
|
||
}
|
||
|
||
tableName = tableData ? tableData.table_name : "Particulars";
|
||
// // // console.log("table Name ",tableName);
|
||
// Header setup
|
||
const thead = document.createElement('thead');
|
||
const headerRow1 = document.createElement('tr');
|
||
headerRow1.innerHTML = `
|
||
${isChildTable ? '<th>S.NO</th>' : '<th>Policy</th>'}
|
||
<th>${tableData ? tableData.table_name : "Particulars"}</th>
|
||
${Object.keys(quotesConfig).map(proposal => `
|
||
<th data-proposal="${proposal}" colspan="${quotesConfig[proposal].length}">
|
||
Proposal ${proposal}
|
||
<span class="three-dot-menu" onclick="showDropdown(event)">⋮</span>
|
||
<div class="dropdown-content">
|
||
<button id="isQCR" onclick="addOrRemoveIcon(this,event)" class="qcrProposal" style="background-color: rgb(221, 221, 221);">QCR <i class="fa fa-check-square" style="color: green; margin-left: 8px;"></i></button>
|
||
<button id="isSTC" class="sendClientProposal" onclick="addOrRemoveIcon(this,event)" style="background-color: rgb(221, 221, 221);">Send to Client <i class="fa fa-check-square" style="color: green; margin-left: 8px;"></i></button>
|
||
<button class = "removeProposal" onclick="removeProposal(${proposal})">Remove Proposal</button>
|
||
<button class="newInsurer" onclick="addNewQuote(${proposal})">Add New Insurer</button>
|
||
</div>
|
||
</th>
|
||
`).join('')}
|
||
<th>Action</th>`;
|
||
|
||
const headerRow2 = document.createElement('tr');
|
||
headerRow2.innerHTML = `
|
||
<th>-</th>
|
||
<th>-</th>
|
||
${Object.entries(quotesConfig).flatMap(([proposal, codes]) =>
|
||
codes.map(code => `
|
||
<th data-proposal="${proposal}" data-quote="${code}" class="${code !== 'Quote asked' ? 'insurer_proposal' : ''}">
|
||
${code}
|
||
<span class="three-dot-menu" onclick="showDropdown(event)">⋮</span>
|
||
<div class="dropdown-content">
|
||
<button onclick="removeQuote(event, ${proposal}, '${code}')">Remove Quote</button>
|
||
</div>
|
||
</th>
|
||
`)
|
||
).join('')}
|
||
<th>-</th>`;
|
||
|
||
thead.append(headerRow1, headerRow2);
|
||
table.appendChild(thead);
|
||
let latestWidth = $("table").last().width();
|
||
// // // console.log('Latest width', latestWidth);
|
||
if (tableData) {
|
||
// // // console.log("table ",$(table));
|
||
$(table).width(latestWidth); // Convert to jQuery object using $(table)
|
||
// // // console.log('table data',tableData);
|
||
|
||
}
|
||
|
||
// Body setup
|
||
// Inside generateTable function, when creating tbody for parent table
|
||
const tbody = document.createElement('tbody');
|
||
if (!isChildTable) {
|
||
policies.forEach((policy) => {
|
||
const descriptions = policy.description;
|
||
const quoteAsked = policy.quote_asked;
|
||
const allQuotes = Object.values(quotesConfig).flat();
|
||
|
||
descriptions.forEach((desc, descIndex) => {
|
||
const row = document.createElement('tr');
|
||
row.id = policy.name.replace(/\s+/g, '_').toLowerCase();
|
||
|
||
const quoteCells = allQuotes.map((_, index) => {
|
||
const value = quoteAsked[index] || '-';
|
||
return `<td contenteditable="true">${value}</td>`;
|
||
}).join('');
|
||
|
||
if (descIndex === 0) {
|
||
row.innerHTML = `
|
||
<td rowspan="${descriptions.length}">
|
||
<input type="checkbox" class="sno-checkbox">
|
||
${policy.name}
|
||
${policy.name === 'Fire' || policy.name === 'Burglary' ?
|
||
`<br><button id="${policy.name.toUpperCase()}_register" class="btn btn-primary btn-sm" onclick="getPolicyInfo('${policy.name}')" class="policy-link" data-policy-name="${policy.name}" disabled>Register</button>` :
|
||
''}
|
||
</td>
|
||
<td contenteditable="true">${desc}</td>
|
||
${quoteCells}
|
||
<td></td>`;
|
||
} else {
|
||
row.innerHTML = `
|
||
<td contenteditable="true">${desc}</td>
|
||
${quoteCells}
|
||
<td></td>`;
|
||
}
|
||
|
||
tbody.appendChild(row);
|
||
});
|
||
});
|
||
} else {
|
||
const rowsData = tableData ? tableData.table_row_contents : policies;
|
||
rowsData.forEach((policy, index) => {
|
||
var row_fields = rowsData[index];
|
||
let rowID = Object.keys(row_fields)[0];
|
||
const row = document.createElement('tr');
|
||
row.id = isChildTable ? `${parentRowId}_child_${index}` : policy.name.replace(/\s+/g, '_').toLowerCase();
|
||
row.id = isChildTable ? `${rowID}` : policy.name.replace(/\s+/g, '_').toLowerCase();
|
||
|
||
if (tableData && tableData.table_id === 'excess') {
|
||
row.setAttribute('data-excess-row-parent', parentRowId);
|
||
}
|
||
var policy_question = row_fields[rowID].display_value;
|
||
var answer_type = row_fields[rowID].answer_type;
|
||
var tableID = tableData?.table_id ?? null;
|
||
var SNO = getSNO(tableID);
|
||
if (tableData) {
|
||
suggestions[rowID] = row_fields[rowID].answer_type;
|
||
if (answer_type == 'dropdown') {
|
||
default_answers_array = row_fields[rowID].default_answer;
|
||
default_value = default_answers_array[0].key;
|
||
default_answer = default_answers_array[0].display_value;
|
||
} else {
|
||
default_answers_array = row_fields[rowID].default_answer ? row_fields[rowID].default_answer : "-";
|
||
default_value = default_answers_array;
|
||
default_answer = default_answers_array;
|
||
}
|
||
}
|
||
|
||
row.innerHTML = `
|
||
|
||
${isChildTable
|
||
? `<td>${SNO}</td>`
|
||
: `<td rowspan = "${policy.description.length}"><input type="checkbox" class="sno-checkbox">${policy.name}${policy.name == 'Fire' || policy.name == 'Burglary'
|
||
? `<br><button id = '${policy.name.toUpperCase()}_register' class = "btn btn-primary btn-sm" onclick = "getPolicyInfo('${policy.name}')" class="policy-link" data-policy-name="${policy.name}" disabled>Register</a>`
|
||
: ""}</td>`
|
||
}
|
||
|
||
<td contenteditable="true">${tableData ? policy_question : policy.description}</td>
|
||
|
||
${Object.values(quotesConfig).flatMap(codes =>
|
||
codes.map((codeValue, colIndex) => {
|
||
// // console.log("Subheader th: colinded : ",colIndex);
|
||
// Get the subheader (assuming it's the second <tr> inside <thead>)
|
||
let subHeaderThList = [...document.querySelectorAll("thead tr:nth-child(2) th")];
|
||
// // console.log("subHeaderThList", subHeaderThList);
|
||
|
||
// Filter <th> elements that have a valid 'data-proposal' attribute
|
||
let validSubHeaders = subHeaderThList.filter(th => {
|
||
let dataProposal = th.getAttribute("data-proposal");
|
||
// // console.log("Subheader th: dataProposal : ",dataProposal);
|
||
return dataProposal !== null && dataProposal !== undefined && dataProposal.trim() !== "";
|
||
});
|
||
|
||
|
||
// // console.log("Subheader th: validSubHeaders",validSubHeaders);
|
||
// let validSubHeaders = subHeaderThList.filter(th => th.hasAttribute("data-proposal"));
|
||
// // console.log("Subheader th: validSubHeaders",validSubHeaders);
|
||
|
||
|
||
let subHeaderTh = validSubHeaders.find(th => th.textContent.trim());
|
||
// // console.log("Subheader th: codeValue",codeValue);
|
||
// // console.log("Subheader th: subHeaderTh",subHeaderTh);
|
||
// if (subHeaderTh.classList.contains("insurer_proposal")) {
|
||
// alert(subHeaderTh);
|
||
// }
|
||
let subHeaderText = subHeaderTh ? subHeaderTh.textContent.trim() : '';
|
||
// // console.log("Subheader th: below code",subHeaderText);
|
||
// Check if subheader is NOT "Quote asked"
|
||
let className = !subHeaderText.startsWith("Quote asked") && subHeaderText != "-" ?
|
||
"insurer_proposal" : "";
|
||
// console.log("className", className);
|
||
// alert(subHeaderText);
|
||
let defaultJsonString = typeof default_answers_array == "object" ? JSON.stringify(default_answers_array[0]) : String(default_answers_array);
|
||
|
||
// // // console.log("defaultJsonString", defaultJsonString);
|
||
// // // console.log("defaultJsonString type", typeof defaultJsonString);
|
||
// // // console.log("defaultJsonString string", String(defaultJsonString));
|
||
|
||
|
||
|
||
return `<td class="${className}" onblur="setValueForHiddenField(this,'${answer_type}')"
|
||
onclick="getAnswer('${tableID}','${rowID}')"
|
||
contenteditable="true">
|
||
|
||
${tableData ?
|
||
(default_value === '-' ?
|
||
`${default_value} <input type="hidden" value="${default_value}" />`
|
||
: `${default_answer} <input type="hidden" value='${defaultJsonString}' />`
|
||
)
|
||
: policy.quote_asked
|
||
}
|
||
|
||
</td>`;
|
||
})
|
||
).join('')}
|
||
|
||
<td>
|
||
${isChildTable ? `
|
||
<input id = "qcrCheckbox" name = "qcr" checked type="checkbox" class="qcr-checkbox"> <label for = "qcrCheckbox">QCR</label>
|
||
<input id = "stcCheckbox" name = "stc" checked type="checkbox" class="client-checkbox">Client
|
||
<button class="btn btn-primary btn-sm" onclick="addRow(event,this)">+</button>
|
||
<button class="btn btn-danger btn-sm" onclick="removeRow(event)">-</button>
|
||
` : ''}
|
||
</td>`;
|
||
tbody.appendChild(row);
|
||
});
|
||
}
|
||
table.appendChild(tbody);
|
||
|
||
// Apply jQuery classes and width (unchanged)
|
||
// let latestWidth = $("table").last().width();
|
||
$(table).width(latestWidth);
|
||
$(collapsibleBar).width(latestWidth);
|
||
$(table).addClass("table table-bordered mt-3");
|
||
|
||
// Append to DOM
|
||
tableContent.appendChild(table);
|
||
tableContainer.appendChild(collapsibleBar);
|
||
tableContainer.appendChild(tableContent);
|
||
container.appendChild(tableContainer);
|
||
}
|
||
|
||
|
||
|
||
function generateExcessTable(tableData, parentRowId, tableName) {
|
||
var excessTable = document.getElementById(tableName);
|
||
|
||
if (excessTable) {
|
||
// If table exists, append new rows to it
|
||
const tbody = excessTable.querySelector('tbody');
|
||
// // // console.log("table data ",tableData);
|
||
// Add new rows from tableData
|
||
tableData.table_row_contents.forEach((rowData, index) => {
|
||
let rowID = Object.keys(rowData)[0];
|
||
var question = rowData[rowID].display_value;
|
||
|
||
const row = document.createElement('tr');
|
||
// Add data attribute to track which parent checkbox created this row
|
||
row.setAttribute('data-excess-row-parent', parentRowId);
|
||
let SNO = getSNO(tableName);
|
||
row.innerHTML = `
|
||
<td>${SNO}</td>
|
||
<td contenteditable="true">${question}</td>
|
||
${Object.values(quotesConfig).flatMap(codes =>
|
||
codes.map((codeValue, colIndex) => {
|
||
// // console.log("Subheader th: colinded : ",colIndex);
|
||
// Get the subheader (assuming it's the second <tr> inside <thead>)
|
||
let subHeaderThList = [...document.querySelectorAll("thead tr:nth-child(2) th")];
|
||
|
||
// Filter <th> elements that have a valid 'data-proposal' attribute
|
||
let validSubHeaders = subHeaderThList.filter(th => {
|
||
let dataProposal = th.getAttribute("data-proposal");
|
||
// // console.log("Subheader th: dataProposal : ",dataProposal);
|
||
return dataProposal !== null && dataProposal !== undefined && dataProposal.trim() !== "";
|
||
});
|
||
|
||
|
||
// // console.log("Subheader th: subHeaderThList",subHeaderThList);
|
||
// let validSubHeaders = subHeaderThList.filter(th => th.hasAttribute("data-proposal"));
|
||
// // console.log("Subheader th: validSubHeaders",validSubHeaders);
|
||
|
||
// // console.log("Subheader th: subHeaderTh",subHeaderTh);
|
||
// if (subHeaderTh.classList.contains("insurer_proposal")) {
|
||
// alert(subHeaderTh);
|
||
// }
|
||
// console.log("Subheader th: ",subHeaderTh);
|
||
|
||
let subHeaderTh = validSubHeaders.find(th => th.textContent.trim());
|
||
|
||
let subHeaderText = subHeaderTh ? subHeaderTh.textContent.trim() : '';
|
||
// Check if subheader is NOT "Quote asked"
|
||
let className = !subHeaderText.startsWith("Quote asked") && subHeaderText != "-" ?
|
||
"insurer_proposal" : ""; // alert(subHeaderText);
|
||
let defaultJsonString = typeof default_answers_array == "object" ? JSON.stringify(default_answers_array[0]) : String(default_answers_array);
|
||
|
||
// // // console.log("defaultJsonString", defaultJsonString);
|
||
// // // console.log("defaultJsonString type", typeof defaultJsonString);
|
||
// // // console.log("defaultJsonString string", String(defaultJsonString));
|
||
|
||
|
||
|
||
return `<td class="${className}" onblur="setValueForHiddenField(this,'${rowID.answer_type}')"
|
||
onclick="getAnswer('${'excess'}','${rowID}')"
|
||
contenteditable="true">
|
||
|
||
${tableData ?
|
||
(default_value === '-' ?
|
||
`${default_value} <input type="hidden" value="${default_value}" />`
|
||
: `${default_answer} <input type="hidden" value='${defaultJsonString}' />`
|
||
)
|
||
: policy.quote_asked
|
||
}
|
||
|
||
</td>`;
|
||
})
|
||
).join('')}
|
||
|
||
<td>
|
||
<input id = "qcrCheckbox" name = "qcr" checked value = "1" type="checkbox" class="qcr-checkbox"> <label for = "qcrCheckbox">QCR</label>
|
||
<input name = "stc" checked value = "1" type="checkbox" class="client-checkbox">Client
|
||
<button class="btn btn-primary btn-sm" onclick="addRow(event,this)">+</button>
|
||
<button class="btn btn-danger btn-sm" onclick="removeRow(event)">-</button>
|
||
</td>`;
|
||
tbody.appendChild(row);
|
||
});
|
||
moveExcessTableLast();
|
||
styleTableColumns();
|
||
return false;
|
||
} else {
|
||
return true;
|
||
}
|
||
}
|
||
// Initialize the parent table
|
||
document.addEventListener('DOMContentLoaded', () => {
|
||
// // // console.log("bjnglfkrg ", rfq_data.length);
|
||
const url = window.location.pathname; // Get the path (e.g., "/nhance/rfq/list/75/1")
|
||
const segments = url.split("/"); // Split by "/"
|
||
segments[segments.length - 1] = "1"; // Change the last segment
|
||
const newUrl = segments.join("/"); // Rebuild the URL
|
||
rfq_or_qcr = 1;
|
||
history.pushState(null, "", newUrl); // Change the URL without reloading
|
||
|
||
if (rfq_data.length) {
|
||
// // console.log("inside if conditoon");
|
||
localStorage.setItem('allTablesJsonData', JSON.stringify(rfq_data));
|
||
jsonToTables();
|
||
styleTableColumns();
|
||
proposalDataForDropDown = rfq_data[rfq_data.length - 1].proposal_data;
|
||
// // console.log("proposalDataForDropDown", proposalDataForDropDown);
|
||
if (!$.isEmptyObject(storedData)) {
|
||
// // console.log("DATA FROM DB : ", JSON.parse(storedData));
|
||
let data = JSON.parse(storedData);
|
||
Object.keys(data).forEach(key => {
|
||
|
||
policySummary[key] = addPolicySummaryTable(data[key], key);
|
||
|
||
// prependTable(policySummary[key],key);
|
||
|
||
|
||
});
|
||
|
||
// // // console.log("policy summary : ",child_table_data[key])
|
||
|
||
// // console.log("generate policy summary : ", policySummary);
|
||
styleTableColumns();
|
||
|
||
}
|
||
// generateTable(document.getElementById('tablesContainer'));
|
||
// // // console.log("polices Length ", policies.length);
|
||
|
||
} else {
|
||
generateTable(document.getElementById('tablesContainer'));
|
||
styleTableColumns();
|
||
// // console.log("polices Length ", policies.length);
|
||
if (policies.length == 1) {
|
||
setTimeout(() => {
|
||
$(".sno-checkbox").each(function() {
|
||
// // console.log("time completed function called");
|
||
$(".sno-checkbox").prop("checked", true);
|
||
this.dispatchEvent(new Event("change", {
|
||
bubbles: true
|
||
}));
|
||
});
|
||
}, 100);
|
||
|
||
}
|
||
}
|
||
// styleTableColumns();
|
||
showOrHideFieldsBasedOnRFQorQCR();
|
||
});
|
||
|
||
// Close dropdown when clicking outside
|
||
window.addEventListener('click', () => {
|
||
document.querySelectorAll('.dropdown-content').forEach(dropdown => {
|
||
dropdown.style.display = 'none';
|
||
});
|
||
});
|
||
|
||
function getAnswer(table_id, rowID) {
|
||
event.stopPropagation();
|
||
// alert();
|
||
// // console.log("Function called");
|
||
|
||
// // console.log("Function called", table_id);
|
||
var policy = table_id.split('_').slice(0, -1).join('_');
|
||
// var policy = 'policy_' + table;
|
||
// // console.log('policy ', rowID);
|
||
|
||
Object.entries(child_table_data).forEach(([key, value]) => {
|
||
if (key == policy) {
|
||
var table_data = value;
|
||
// // // console.log("table data ",table_data);
|
||
// Loop through all available table data (removing hardcoded [0])
|
||
table_data.forEach(table => {
|
||
var table_row = table['table_row_contents'];
|
||
// // // console.log("table Row ",table_row);
|
||
Object.entries(table_row).forEach(([key, value]) => {
|
||
var question_id = Object.keys(value)[0];
|
||
// // // console.log("Question ID : ",question_id," row ID : ",rowID);
|
||
if (question_id == rowID) {
|
||
let questionData = value[question_id];
|
||
// // console.log("question data", questionData);
|
||
if (questionData.answer_type == 'dropdown') {
|
||
|
||
var answerAndValues = questionData.answers;
|
||
createDropdown(answerAndValues);
|
||
} else {
|
||
return true;
|
||
}
|
||
}
|
||
});
|
||
});
|
||
}
|
||
});
|
||
}
|
||
|
||
|
||
function createDropdown(answerAndValues) {
|
||
// // // console.log(answerAndValues);
|
||
const originalTd = event.target;
|
||
const dropdown = document.createElement("div");
|
||
dropdown.classList.add("simple-dropdown");
|
||
|
||
answerAndValues.forEach(answer => {
|
||
const option = document.createElement("div");
|
||
option.classList.add("dropdown-option");
|
||
option.textContent = answer.display_value;
|
||
option.dataset.key = answer.key;
|
||
|
||
option.addEventListener("click", function(e) {
|
||
e.stopPropagation();
|
||
originalTd.innerHTML = `${this.textContent}
|
||
<input type="hidden" value='${JSON.stringify({ key: answer.key, display_value: answer.display_value })}' />`;
|
||
checkCellValueAndHighlight();
|
||
// originalTd.dataset.selectedKey = this.dataset.key;
|
||
dropdown.remove();
|
||
});
|
||
|
||
dropdown.appendChild(option);
|
||
});
|
||
|
||
const rect = originalTd.getBoundingClientRect();
|
||
dropdown.style.top = rect.bottom + window.scrollY + 'px';
|
||
dropdown.style.left = rect.left + window.scrollX + 'px';
|
||
|
||
const existingDropdown = document.querySelector('.simple-dropdown');
|
||
if (existingDropdown) {
|
||
existingDropdown.remove();
|
||
}
|
||
|
||
document.body.appendChild(dropdown);
|
||
|
||
document.addEventListener("click", function(e) {
|
||
if (!dropdown.contains(e.target) && e.target !== originalTd) {
|
||
dropdown.remove();
|
||
}
|
||
});
|
||
|
||
originalTd.addEventListener('click', function(e) {
|
||
e.preventDefault();
|
||
if (this.getAttribute('contenteditable') === 'true') {
|
||
// this.setAttribute('contenteditable', 'false');
|
||
}
|
||
});
|
||
}
|
||
|
||
function moveExcessTableLast() {
|
||
const excessTable = document.getElementById("excess");
|
||
const overallContainer = document.getElementById('allTableContainer');
|
||
|
||
if (!excessTable) {
|
||
// // console.log("Excess table not found.");
|
||
return;
|
||
}
|
||
|
||
// Find or create the collapsible bar
|
||
let excessCollapseBar = document.querySelector('.table-collapsible-bar.Excess');
|
||
|
||
if (!excessCollapseBar) {
|
||
excessCollapseBar = document.createElement('div');
|
||
excessCollapseBar.className = 'table-collapsible-bar Excess collapsed';
|
||
excessCollapseBar.innerHTML = `
|
||
Excess
|
||
<span class="collapse-icon">▼</span>
|
||
`;
|
||
|
||
// Add click handler for collapse/expand
|
||
excessCollapseBar.addEventListener('click', function() {
|
||
this.classList.toggle('collapsed');
|
||
const content = this.nextElementSibling;
|
||
content.classList.toggle('collapsed');
|
||
});
|
||
}
|
||
|
||
// Create container if needed
|
||
let tableContainer = excessTable.closest('.table-container');
|
||
if (!tableContainer) {
|
||
tableContainer = document.createElement('div');
|
||
tableContainer.className = 'table-container';
|
||
|
||
// Build proper structure
|
||
tableContainer.appendChild(excessCollapseBar);
|
||
tableContainer.appendChild(excessTable);
|
||
}
|
||
|
||
// Move to end of container
|
||
overallContainer.appendChild(tableContainer);
|
||
}
|
||
// Global object to track SNO for each table
|
||
let tableSNOTracker = {};
|
||
|
||
function getSNO(tableID) {
|
||
if (!tableID) {
|
||
return 1;
|
||
}
|
||
|
||
// Initialize counter if not present
|
||
if (!tableSNOTracker[tableID]) {
|
||
tableSNOTracker[tableID] = 1;
|
||
} else {
|
||
tableSNOTracker[tableID]++;
|
||
}
|
||
|
||
return tableSNOTracker[tableID];
|
||
}
|
||
|
||
function updateSNO(tableID) {
|
||
// // console.log("Function Called Update Sno");
|
||
const table = document.getElementById(tableID);
|
||
// // console.log("table : ", table);
|
||
if (!table) return;
|
||
|
||
const rows = table.querySelectorAll("tbody tr");
|
||
let sno = 1; // Start numbering from 1
|
||
|
||
rows.forEach(row => {
|
||
const firstCell = row.querySelector("td:first-child"); // Get SNO cell
|
||
if (firstCell) {
|
||
firstCell.innerHTML = `<td "class="sno-checkbox"> ${sno}</td>`;
|
||
sno++; // Increment SNO for the next row
|
||
}
|
||
});
|
||
|
||
// ✅ Reset the tracker based on remaining rows
|
||
tableSNOTracker[tableID] = sno;
|
||
}
|
||
|
||
|
||
|
||
function increaseTableWidth(increaseBy) {
|
||
|
||
$('.table-collapsible-bar').each(function() {
|
||
let currentWidth = ($(this).width());
|
||
let increaseTableWidth = (currentWidth + increaseBy);
|
||
if (increaseTableWidth < 1200){
|
||
increaseTableWidth = 1200+increaseBy
|
||
}
|
||
$(this).width(currentWidth + increaseBy);
|
||
});
|
||
// // // console.log("function called tablewidth increase");
|
||
$("table").each(function() {
|
||
let currentWidth = ($(this).width());
|
||
// alert(currentWidth);
|
||
let increaseTableWidth = (currentWidth + increaseBy);
|
||
console.log("Table Width increased to ",increaseTableWidth);
|
||
if (increaseTableWidth < 1200){
|
||
increaseTableWidth = 1200+increaseBy
|
||
}
|
||
$(this).width(increaseTableWidth);
|
||
});
|
||
}
|
||
|
||
function arrangeTables() {
|
||
// Target the container
|
||
const container = document.getElementById('tablesContainer');
|
||
if (!container) {
|
||
// console.error('Error: tablesContainer not found');
|
||
return;
|
||
}
|
||
|
||
// Select divs with data-parent-row (your containers)
|
||
const divContainers = container.querySelectorAll('div[data-parent-row]');
|
||
|
||
const containerArray = Array.from(divContainers).map(div => {
|
||
const policyName = div.getAttribute('data-parent-row').toLowerCase();
|
||
const policyDetails = policyOrder.find(policy =>
|
||
Object.keys(policy)[0] === policyName
|
||
);
|
||
return {
|
||
element: div, // Work with the div, not the table
|
||
policyName: policyName,
|
||
priority: policyDetails ? policyDetails[policyName].priority : Infinity
|
||
};
|
||
});
|
||
|
||
// Filter to only selected policies
|
||
const selectedContainers = containerArray.filter(container =>
|
||
selectedPolicies.has(container.policyName)
|
||
);
|
||
// // // console.log('container selected ',selectedContainers);
|
||
// Sort by priority
|
||
selectedContainers.sort((a, b) => a.priority - b.priority);
|
||
|
||
// Reorder the divs in the container
|
||
selectedContainers.forEach(containerData => {
|
||
container.appendChild(containerData.element);
|
||
});
|
||
}
|
||
|
||
function setValueForHiddenField(element, answer_type) {
|
||
// alert("hi");
|
||
if (answer_type != 'dropdown') {
|
||
// // // console.log(element);
|
||
const hiddenInput = element.querySelector("input[type='hidden']");
|
||
const updatedText = element.textContent.trim();
|
||
var updated_Text = element.textContent.trim();
|
||
// // // console.log('updated text ',updated);
|
||
if (hiddenInput) {
|
||
|
||
hiddenValue = updated_Text;
|
||
|
||
// alert(hiddenValue);
|
||
// Convert it back to a JSON string and set the value
|
||
hiddenInput.value = hiddenValue;
|
||
|
||
// // console.log("Updated Hidden Input Value:", hiddenInput.value);
|
||
} else {
|
||
// console.warn("No hidden input found inside the element.");
|
||
}
|
||
}
|
||
checkCellValueAndHighlight();
|
||
}
|
||
|
||
function addOrRemoveIcon(element, event) {
|
||
event.stopPropagation();
|
||
|
||
// Get the parent dropdown to access both buttons reliably
|
||
const dropdown = element.closest('.dropdown-content');
|
||
const qcrButton = dropdown.querySelector('.qcrProposal');
|
||
const stcButton = dropdown.querySelector('.sendClientProposal');
|
||
|
||
// Get current icons
|
||
let qcrIcon = qcrButton.querySelector('.fa-check-square');
|
||
let stcIcon = stcButton.querySelector('.fa-check-square');
|
||
|
||
// If clicked on QCR button
|
||
if (element.classList.contains('qcrProposal')) {
|
||
if (!qcrIcon) {
|
||
// QCR being checked: add icon to both
|
||
createIcon(qcrButton);
|
||
if (!stcIcon) {
|
||
createIcon(stcButton);
|
||
}
|
||
} else {
|
||
// QCR being unchecked: remove icon from both
|
||
qcrButton.removeChild(qcrIcon);
|
||
if (stcIcon) {
|
||
stcButton.removeChild(stcIcon);
|
||
}
|
||
}
|
||
}
|
||
// If clicked on Send to Client button
|
||
else if (element.classList.contains('sendClientProposal')) {
|
||
if (!stcIcon) {
|
||
// STC being checked: must ensure QCR is checked first
|
||
if (!qcrIcon) {
|
||
createIcon(qcrButton); // Ensure QCR is checked
|
||
}
|
||
createIcon(stcButton);
|
||
} else {
|
||
// STC being unchecked: only remove STC icon
|
||
stcButton.removeChild(stcIcon);
|
||
// QCR remains unchanged
|
||
}
|
||
}
|
||
|
||
// Update your data model or save state if needed
|
||
// updateHeaderCheckBoxProperties();
|
||
}
|
||
|
||
function createIcon(element) {
|
||
let icon = document.createElement('i');
|
||
icon.classList.add('fa', 'fa-check-square');
|
||
icon.style.color = 'green';
|
||
icon.style.marginLeft = '8px';
|
||
element.appendChild(icon);
|
||
}
|
||
|
||
document.addEventListener('click', function(e) {
|
||
if (e.target.classList.contains('policy-link')) {
|
||
const policyName = e.target.getAttribute('data-policy-name');
|
||
getPolicyInfo(policyName);
|
||
e.preventDefault();
|
||
}
|
||
checkCellValueAndHighlight();
|
||
});
|
||
|
||
function getPolicyInfo(policyName) {
|
||
// // console.log("anchor link clicked ", policyName);
|
||
|
||
|
||
myModal = new bootstrap.Modal(document.getElementById('policyRegisterModel'));
|
||
// // console.log("inside if condition");
|
||
|
||
var leadID = $("#lead_id").val();
|
||
let policy = policies.find(p => p.name === policyName);
|
||
// alert(policy.quote_asked[0]);
|
||
// var policySI = policies[]
|
||
|
||
$("#policyName").val(policyName);
|
||
$("#policySI").val(policy.quote_asked[0]);
|
||
$("#leadID").val(leadID);
|
||
$("#multilocation_type_div").hide();
|
||
$('.loader').fadeIn();
|
||
$('.loader-mask').fadeIn();
|
||
|
||
// Add 'show active' to the 'product-selection' tab
|
||
$("#policy_register_forms .tab-pane.show.active").removeClass("active show");
|
||
|
||
// Add 'show active' to the 'product-selection' tab
|
||
$("#product-selection").addClass("active show");
|
||
hideAndShowBurglary();
|
||
|
||
storedPolicyData = JSON.parse(localStorage.getItem('policyData'));
|
||
if (!$.isEmptyObject(storedPolicyData)) {
|
||
// alert("not empty");
|
||
prepareDataForEdit(storedPolicyData);
|
||
}
|
||
myModal.show();
|
||
$('.loader').fadeOut();
|
||
$('.loader-mask').delay(350).fadeOut('slow');
|
||
}
|
||
|
||
function addPolicySummaryTable(storedData, policyName) {
|
||
// alert(policyName);
|
||
var locationCount = storedData.locations.length;
|
||
var tableRowContent = [];
|
||
|
||
// Loop through each location and generate the summary rows dynamically
|
||
for (let i = 0; i < locationCount; i++) {
|
||
let locationIndex = i + 1; // To make it 1-based instead of 0-based
|
||
|
||
tableRowContent.push({
|
||
table_type: "new",
|
||
table_id: `${policyName}_summary_` + locationIndex,
|
||
table_editable: true,
|
||
table_name: "Risk Location " + locationIndex + "- " +
|
||
storedData.locations[i].policyRisk['occupancy'] + "- " +
|
||
storedData.locations[i].policyRisk['address1'] + " " +
|
||
storedData.locations[i].policyRisk['address2'],
|
||
table_row_contents: [{
|
||
[`fire_plantMachineries_${locationIndex}`]: {
|
||
"display_value": "Plant & Machineries and Accessories",
|
||
"answer_type": "free-text",
|
||
"default_answer": storedData.locations[i].policyRiskSplitUp?.plantAndMachinery || ""
|
||
}
|
||
},
|
||
{
|
||
[`fire_electricalFittings_${locationIndex}`]: {
|
||
"display_value": "Electronic Equipments and Accessories",
|
||
"answer_type": "free-text",
|
||
"default_answer": storedData.locations[i].policyRiskSplitUp?.electricalFittings || ""
|
||
}
|
||
},
|
||
{
|
||
[`fire_furnitureFittings_${locationIndex}`]: {
|
||
"display_value": "FFF (Furniture, Fixtures & Fittings)",
|
||
"answer_type": "free-text",
|
||
"default_answer": storedData.locations[i].policyRiskSplitUp?.furniture || ""
|
||
}
|
||
},
|
||
{
|
||
[`fire_content_${locationIndex}`]: {
|
||
"display_value": "Other Contents Related to Insured",
|
||
"answer_type": "free-text",
|
||
"default_answer": storedData.locations[i].policyRiskSplitUp?.content || ""
|
||
}
|
||
}
|
||
]
|
||
});
|
||
}
|
||
|
||
var policySummary = tableRowContent;
|
||
// // console.log("policy summary ", policySummary);
|
||
return policySummary;
|
||
}
|
||
|
||
async function selectInsurer(insurers) {
|
||
|
||
// // console.log("Async function called");
|
||
// Build the HTML for the Select2 dropdown and the input text field
|
||
const selectHTML = `
|
||
<div class="form-row">
|
||
|
||
<div class="form-group col-md-8">
|
||
<select id="insurerSelect">
|
||
<option></option> <!-- Placeholder for Select2 -->
|
||
${insurers.map(insurer => `<option data-id="${insurer.id}-${insurer.insurer_id}" value="${insurer.insurer_name}-${insurer.branch_code}">${insurer.insurer_name}-${insurer.branch_code}</option>`).join('')}
|
||
</select>
|
||
</div>
|
||
|
||
<div class="form-group col-md-4">
|
||
<input type="text" class="form-control" id="insurerDetails" placeholder="Enter Version">
|
||
</div>
|
||
|
||
</div>
|
||
`;
|
||
|
||
// Display SweetAlert with the Select2 dropdown and text input as HTML content
|
||
const result = await Swal.fire({
|
||
title: 'Select an insurer',
|
||
html: selectHTML,
|
||
showCancelButton: true,
|
||
preConfirm: () => {
|
||
|
||
const selectedInsurer = document.getElementById('insurerSelect').value;
|
||
const insurerDetails = document.getElementById('insurerDetails').value;
|
||
|
||
const insurerSelect = document.getElementById('insurerSelect');
|
||
const selectedOption = insurerSelect.options[insurerSelect.selectedIndex];
|
||
const dataId = selectedOption.getAttribute('data-id');
|
||
|
||
if (!selectedInsurer) {
|
||
Swal.showValidationMessage("You need to select an insurer :)");
|
||
}
|
||
|
||
return {
|
||
selectedInsurer,
|
||
insurerDetails,
|
||
dataId
|
||
};
|
||
},
|
||
didOpen: () => {
|
||
// Initialize Select2 on the dropdown
|
||
$('#insurerSelect').select2({
|
||
placeholder: 'Select an insurer',
|
||
dropdownParent: $(
|
||
'.swal2-popup') // Ensure Select2 is rendered inside SweetAlert
|
||
});
|
||
}
|
||
});
|
||
|
||
// Return the selected insurer and input details if confirmed
|
||
if (result.isConfirmed) {
|
||
return result.value;
|
||
}
|
||
return null; // If canceled, return null
|
||
}
|
||
|
||
function saveRFQ() {
|
||
// // console.log("save button clicked");
|
||
leadJson = tablesToJson();
|
||
// // console.log("json from function ", leadJson);
|
||
var policyJson = localStorage.getItem("policyData") ?? null;
|
||
saveRFQTODB(leadJson, policyJson);
|
||
}
|
||
|
||
function saveRFQTODB(tableJSON, policyJson) {
|
||
|
||
let submit_type = "RFQ"
|
||
if(rfq_or_qcr == 2){submit_type = 'QCR'}
|
||
|
||
var formData = {
|
||
lead_id: $("#lead_id").val(),
|
||
json: JSON.stringify(tableJSON),
|
||
submit_type: submit_type,
|
||
registration_json: policyJson
|
||
}
|
||
|
||
var url = '<?= base_url('rfq/create') ?>';
|
||
$('.loader').fadeIn();
|
||
$('.loader-mask').fadeIn();
|
||
|
||
$.ajax({
|
||
url: url,
|
||
data: formData,
|
||
method: "POST",
|
||
success: function(response) {
|
||
if (response.status == true) {
|
||
localStorage.removeItem('policyData');
|
||
|
||
toastr.success(response.message, "Success");
|
||
// // console.log(rfq_data.length);
|
||
|
||
$('.actionBtns').show();
|
||
if (rfq_or_qcr == 2) {
|
||
$("#openQCR").hide();
|
||
}
|
||
|
||
// window.location.reload();
|
||
} else {
|
||
toastr.error(response.message, "Error");
|
||
$('.actionBtns').hide();
|
||
}
|
||
$('.loader').fadeOut();
|
||
$('.loader-mask').delay(350).fadeOut('slow');
|
||
window.location.reload();
|
||
},
|
||
error: function(xhr, status, error) {
|
||
$('.loader').fadeOut();
|
||
$('.loader-mask').delay(350).fadeOut('slow');
|
||
// console.error(xhr.responseText);
|
||
// console.error(status, error);
|
||
}
|
||
})
|
||
}
|
||
|
||
function prepareOverallData() {
|
||
var proposalKey = "";
|
||
const overAllData = {};
|
||
Object.entries(policyConfig).forEach(([proposalNumber, insurers]) => {
|
||
if (lead_type == 1){
|
||
proposalKey = `Proposal ${proposalNumber}`;
|
||
}else{
|
||
if (proposalNumber == 0){
|
||
proposalKey = `${rollover_or_renewal} ${proposalNumber}`;
|
||
}else{
|
||
proposalKey = `Proposal ${proposalNumber}`;
|
||
}
|
||
}
|
||
overAllData[proposalKey] = {
|
||
qcr: 0,
|
||
stc: 0,
|
||
insurers: []
|
||
};
|
||
|
||
const proposalHeader = document.querySelector(`th[data-proposal="${proposalNumber}"]`);
|
||
if (proposalHeader) {
|
||
const qcrSelected = proposalHeader.querySelector('.qcrProposal .fa-check-square') !== null;
|
||
const stcSelected = proposalHeader.querySelector('.sendClientProposal .fa-check-square') !== null;
|
||
overAllData[proposalKey].qcr = qcrSelected ? 1 : 0;
|
||
overAllData[proposalKey].stc = stcSelected ? 1 : 0;
|
||
}
|
||
// // console.log("Insurers Found", insurers);
|
||
|
||
const uniqueInsurers = [];
|
||
insurers.forEach(insurer => {
|
||
if (typeof insurer === 'object' && insurer.id) {
|
||
let stcInsurerSelected = false;
|
||
const insurerHeaders = document.querySelectorAll(`th[data-quote="${insurer.insurerName}"]`);
|
||
insurerHeaders.forEach(header => {
|
||
const headerProposalCount = header.getAttribute("data-proposal");
|
||
if (headerProposalCount == proposalNumber) {
|
||
// // console.log("Found the subheader we are searching");
|
||
if (header.querySelector('.sendInsurerClientProposal .fa-check-square') !== null) {
|
||
stcInsurerSelected = true;
|
||
}
|
||
// // console.log("STC selected for insurer:", stcInsurerSelected);
|
||
}
|
||
});
|
||
uniqueInsurers.push({
|
||
ins_name: insurer.insurerName,
|
||
qcr: 1,
|
||
stc: rfq_or_qcr == 1 ? 1 : stcInsurerSelected ? 1 : 0,
|
||
display_name: insurer.insurerName,
|
||
id: insurer.id
|
||
});
|
||
}
|
||
});
|
||
// // console.log("Unique Insurers Found", uniqueInsurers);
|
||
overAllData[proposalKey].insurers = Array.from(uniqueInsurers.values());
|
||
});
|
||
// // console.log("overalll data created is ", overAllData);
|
||
return overAllData;
|
||
}
|
||
|
||
|
||
function getTextExcludingButton(cell) {
|
||
return Array.from(cell.childNodes)
|
||
.filter(node => node.nodeType === Node.TEXT_NODE) // Get only text nodes
|
||
.map(node => node.textContent.trim()) // Trim unnecessary spaces
|
||
.join(' ').trim();
|
||
}
|
||
|
||
function tablesToJson() {
|
||
const allTablesData = [];
|
||
// Select all tables - adjust the selector if needed (e.g., '.json-table' for specific tables)
|
||
const tables = document.querySelectorAll('table');
|
||
|
||
tables.forEach(table => {
|
||
var headers = [];
|
||
const data = [];
|
||
const tableId = table.id; // Ensure each table has a unique ID
|
||
// // // console.log('Processing table:', tableId);
|
||
|
||
// Get parent headers and subheaders for the current table
|
||
const parentHeaders = table.querySelectorAll('thead tr:nth-child(1) th');
|
||
const subHeaders = table.querySelectorAll('thead tr:nth-child(2) th');
|
||
|
||
let headerIndex = 0;
|
||
parentHeaders.forEach(header => {
|
||
// // console.log("Found header ", header);
|
||
if (header.innerText.trim().startsWith("Proposal") || header.innerText.trim().startsWith("Existing")) {
|
||
var policyNumber = header.getAttribute("data-proposal");
|
||
var colspan = parseInt(quotesConfig[policyNumber].length);
|
||
// // console.log("Found header true colspan : ", colspan);
|
||
} else {
|
||
var colspan = parseInt(header.getAttribute('colspan')) || 1;
|
||
}
|
||
const subHeaderArray = [];
|
||
// console.log("processing save function header : ", header);
|
||
// // // console.log("processing save colspn : ",colspan);
|
||
for (let i = 0; i < colspan; i++) {
|
||
const subheaderHTML = subHeaders[headerIndex].innerHTML;
|
||
const subheaderText = subheaderHTML.replace(/<span class="three-dot-menu"[\s\S]*?<\/div>/g, '').trim();
|
||
subHeaderArray.push(subheaderText);
|
||
headerIndex++;
|
||
}
|
||
// // console.log("inside save colspn : ", colspan);
|
||
const headerHTML = header.innerHTML;
|
||
const headerText = headerHTML.replace(/<span class="three-dot-menu"[\s\S]*?<\/div>/g, '').trim();
|
||
// console.log("processing sub header array : ", subHeaderArray);
|
||
// // console.log("HEader : ", header.innerText == " " ? header.innerText.trim() : headerText);
|
||
headers.push({
|
||
// parentHeader: header.innerText.replace('⋮', '').split('\n')[0].replace(/:.*/, '').trim(),
|
||
parentHeader: headerText,
|
||
subHeaders: subHeaderArray
|
||
});
|
||
// // console.log("processing sub header array : ", headers);
|
||
});
|
||
|
||
// Process each row in the current table
|
||
const rows = table.querySelectorAll('tbody tr');
|
||
const rowIdCount = {};
|
||
|
||
let rowIdForRemoveFirstIndex = "";
|
||
rows.forEach(row => {
|
||
const rowId = row.id;
|
||
// // console.log("row id : ", rowId);
|
||
// // console.log("Suggestions :", suggestions);
|
||
const inputType = suggestions[rowId]?.answer_type || 'text'; // Default to 'text' if undefined
|
||
const cells = row.querySelectorAll('td');
|
||
// // // console.log("row id going to submit us ", );
|
||
const rowData = {
|
||
SNO: cells[0] ? getTextExcludingButton(cells[0]) : '',
|
||
items: cells[1]?.innerText || '',
|
||
row_id: rowId,
|
||
data: []
|
||
};
|
||
if (tableId == "excess") {
|
||
// // console.log("row Trying to set : ", row);
|
||
// // console.log("row Trying to set : ", row.outerHTML);
|
||
rowData['parentPolicy'] = row.getAttribute("data-excess-row-parent")
|
||
}
|
||
// // console.log("Row data foint to submit ", rowData);
|
||
let dataIndex = 0;
|
||
if (rowIdCount[rowId] === undefined) {
|
||
rowIdCount[rowId] = 0;
|
||
} else {
|
||
rowIdCount[rowId]++;
|
||
}
|
||
const occurrence = rowIdCount[rowId];
|
||
// // console.log("NEw Method : rowIdCount",rowIdCount)
|
||
// // console.log("NEw Method : occurrence",occurrence)
|
||
|
||
let rowspan_row_id = '';
|
||
|
||
if (occurrence > 0) {
|
||
var headers2 = headers;
|
||
headers2 = headers2.filter((header, index) => !(index === 0 && header.parentHeader === "Policy"));
|
||
// // console.log("Header 2 ",headers2);
|
||
headers2.forEach((header2, TableDataHeaderIndex) => {
|
||
header2.subHeaders.forEach(subHeader => {
|
||
|
||
if (dataIndex >= cells.length) return; // Prevent out-of-bound errors
|
||
const cell = cells[dataIndex];
|
||
let content;
|
||
// Handle different input types and action cells
|
||
if (inputType === "text" && header2.parentHeader === 'Action') {
|
||
const qcrInput = cell.querySelector('input[name="qcr"]');
|
||
const clientInput = cell.querySelector('input[name="stc"]');
|
||
// // console.log("QCR INPUT : ", qcrInput);
|
||
|
||
content = {
|
||
qcr: qcrInput?.checked ? 1 : 0,
|
||
stc: clientInput?.checked ? 1 : 0
|
||
};
|
||
} else {
|
||
const input = cell.querySelector('input, select, textarea');
|
||
if (input) {
|
||
// // console.log("Input type:", input.type);
|
||
|
||
if (input.type === "checkbox") {
|
||
content = input.checked ? "Checked" : "Not Checked"; // Handling checkboxes
|
||
display_content = input.checked ? "Checked" : "Not Checked";
|
||
} else {
|
||
content = input.value; // Handling other input types like text, select, textarea
|
||
display_content = cell.innerText.trim();
|
||
// // console.log("processing sub header array : ", content);
|
||
}
|
||
} else {
|
||
content = cell.innerText.trim(); // If no input is found, use the cell's text
|
||
display_content = cell.innerText.trim();
|
||
|
||
}
|
||
}
|
||
|
||
|
||
rowData.data.push({
|
||
parentth: header2.parentHeader,
|
||
subth: subHeader,
|
||
// value: cell.innerText,
|
||
input_value: content,
|
||
display_content: display_content,
|
||
rowspan: cell.rowSpan
|
||
});
|
||
|
||
dataIndex++;
|
||
});
|
||
});
|
||
}
|
||
headers.forEach((header, TableDataHeaderIndex) => {
|
||
|
||
// let headerIndexOffset = occurrence;
|
||
// let parentThDataText;
|
||
// if (headers[TableDataHeaderIndex + headerIndexOffset]) {
|
||
// parentThDataText = headers[TableDataHeaderIndex + headerIndexOffset].parentHeader;
|
||
// // // console.log("NEw Method : parentThDataText",parentThDataText)
|
||
// } else {
|
||
// parentThDataText = header.parentHeader; // Fallback if there are no more headers
|
||
// }
|
||
// // // console.log(`Row ${rowId} occurrence ${occurrence} using header: `, parentThDataText);
|
||
|
||
header.subHeaders.forEach(subHeader => {
|
||
|
||
if (dataIndex >= cells.length) return; // Prevent out-of-bound errors
|
||
const cell = cells[dataIndex];
|
||
let content;
|
||
// Handle different input types and action cells
|
||
if (inputType === "text" && header.parentHeader === 'Action') {
|
||
const qcrInput = cell.querySelector('input[name="qcr"]');
|
||
const clientInput = cell.querySelector('input[name="stc"]');
|
||
// // console.log("QCR INPUT : ", qcrInput);
|
||
|
||
content = {
|
||
qcr: qcrInput?.checked ? 1 : 0,
|
||
stc: clientInput?.checked ? 1 : 0
|
||
};
|
||
} else {
|
||
const input = cell.querySelector('input, select, textarea');
|
||
if (input) {
|
||
// // console.log("Input type:", input.type);
|
||
|
||
if (input.type === "checkbox") {
|
||
content = input.checked ? "Checked" : "Not Checked"; // Handling checkboxes
|
||
display_content = input.checked ? "Checked" : "Not Checked";
|
||
} else {
|
||
content = input.value; // Handling other input types like text, select, textarea
|
||
display_content = cell.innerText.trim();
|
||
// // console.log("processing sub header array : ", content);
|
||
}
|
||
} else {
|
||
content = cell.innerText.trim(); // If no input is found, use the cell's text
|
||
display_content = cell.innerText.trim();
|
||
|
||
}
|
||
}
|
||
|
||
// let parentThDataText = header.parentHeader;
|
||
// if(rowId == rowspan_row_id){
|
||
// parentThDataText = rowspan_row_id == rowId ? headers[TableDataHeaderIndex + 1].parentHeader : header.parentHeader;
|
||
|
||
// // // console.log('rowspan_row_id parentThDataText', parentThDataText);
|
||
// // // console.log('rowspan_row_id', rowspan_row_id);
|
||
|
||
// rowspan_row_id = rowspan_row_id - 1;
|
||
// // // console.log('rowspan_row_id after decrement', rowspan_row_id);
|
||
|
||
// }
|
||
// // // console.log("trying to find what this is ",cell);
|
||
rowData.data.push({
|
||
parentth: header.parentHeader,
|
||
subth: subHeader,
|
||
// value: cell.innerText,
|
||
input_value: content,
|
||
display_content: display_content,
|
||
rowspan: cell.rowSpan
|
||
});
|
||
|
||
dataIndex++;
|
||
});
|
||
});
|
||
|
||
data.push(rowData);
|
||
// // // console.log("processing sub header array : ",content);
|
||
});
|
||
tablePolicyName = [...selectedPolicies].find(policy => tableId.startsWith(policy)) || null;
|
||
// // console.log(selectedPolicies);
|
||
// // console.log(tablePolicyName);
|
||
// Get table-specific over_all_column_data (adjust based on your data structure)
|
||
|
||
|
||
allTablesData.push({
|
||
tableId: tableId,
|
||
tablePolicy: tablePolicyName,
|
||
table_data: {
|
||
headers: headers,
|
||
data: data
|
||
},
|
||
// proposal_data: {
|
||
// over_all_column_data: tableOverAllData
|
||
// }
|
||
});
|
||
});
|
||
const tableOverAllData = prepareOverallData() || {};
|
||
allTablesData.push({
|
||
proposal_data: {
|
||
over_all_column_data: tableOverAllData
|
||
}
|
||
});
|
||
// Save all tables' data to localStorage
|
||
localStorage.setItem('allTablesJsonData', JSON.stringify(allTablesData));
|
||
// // console.log('All tables data saved:', allTablesData);
|
||
// toastr.success("RFQ Saved Successfully", "SUCCESS");
|
||
// If needed, reconstruct tables from JSON (implement jsonToTable accordingly)
|
||
|
||
return allTablesData;
|
||
}
|
||
|
||
function openQCR() {
|
||
|
||
const url = window.location.pathname; // Get the path (e.g., "/nhance/rfq/list/75/1")
|
||
const segments = url.split("/"); // Split by "/"
|
||
segments[segments.length - 1] = "2"; // Change the last segment
|
||
const newUrl = segments.join("/"); // Rebuild the URL
|
||
|
||
// // console.log('newUrl', newUrl)
|
||
|
||
history.pushState(null, "", newUrl); // Change the URL without reloading
|
||
|
||
rfq_or_qcr = 2;
|
||
$('.loader').fadeIn();
|
||
$('.loader-mask').fadeIn();
|
||
jsonToTables();
|
||
checkCellValueAndHighlight();
|
||
$('.loader').fadeOut();
|
||
$('.loader-mask').delay(350).fadeOut('slow');
|
||
// $('#rfq_qcr_page_title').text('QCR');
|
||
hideProposalOptionsForChild();
|
||
showOrHideFieldsBasedOnRFQorQCR();
|
||
styleTableColumns();
|
||
}
|
||
|
||
function setPolicyConfiguration(overAllColumnData) {
|
||
let result = {};
|
||
|
||
// Iterate over each proposal
|
||
Object.entries(overAllColumnData).forEach(([proposalKey, proposalData]) => {
|
||
// Extract proposal number from the key (ensuring it's properly extracted)
|
||
let match = proposalKey.match(/\d+/); // Extracts the number from "Proposal X"
|
||
let proposalNumber = "";
|
||
if (lead_type == 1){
|
||
proposalNumber = match ? match[0] : undefined;
|
||
}else{
|
||
if (rfq_count == 0){
|
||
proposalNumber = 0;
|
||
}else{
|
||
// alert(proposalData);
|
||
proposalNumber = match ? match[0] : undefined;
|
||
}
|
||
}
|
||
|
||
// if (!proposalNumber) return; // Skip if extraction fails
|
||
|
||
// Initialize with "Quote asked"
|
||
result[proposalNumber] = ["Quote asked"];
|
||
|
||
// Check if insurers exist and filter those with qcr = 1
|
||
if (Array.isArray(proposalData.insurers)) {
|
||
proposalData.insurers.forEach(insurer => {
|
||
|
||
result[proposalNumber].push({
|
||
id: insurer.id,
|
||
version: "",
|
||
insurerName: insurer.display_name
|
||
});
|
||
|
||
});
|
||
}
|
||
});
|
||
|
||
return result;
|
||
}
|
||
|
||
function setQuotesConfig(overallColumnData) {
|
||
let quotesConfiguration = {}; // Stores the transformed output
|
||
let index = 1; // Keeps track of proposal index
|
||
// // console.log(overallColumnData);
|
||
Object.keys(overallColumnData).forEach((proposalKey) => {
|
||
|
||
let parts = proposalKey.split(" ");
|
||
let lastNumber = parseInt(parts[parts.length - 1], 10);
|
||
|
||
if (lead_type == 1){
|
||
index = lastNumber;
|
||
}else{
|
||
if (rfq_count == 0){
|
||
index = 0;
|
||
}else{
|
||
index = lastNumber;
|
||
}
|
||
}
|
||
|
||
let proposal = overallColumnData[proposalKey];
|
||
let insurersList = proposal.insurers.map(ins => ins.ins_name); // Extract insurer names
|
||
|
||
// Create output format: index { "Quote asked", ...insurers }
|
||
quotesConfiguration[index] = ["Quote asked", ...insurersList];
|
||
|
||
});
|
||
|
||
return quotesConfiguration;
|
||
}
|
||
|
||
function addSuggestion(rowData) {
|
||
// // console.log("child table data rowData", rowData);
|
||
// // console.log("child table data rowData.id", rowData.row_id);
|
||
// // console.log("child table data child_table_data", child_table_data[rowData.row_id]);
|
||
|
||
var table_data = child_table_data[rowData.row_id];
|
||
|
||
table_data.forEach(table => {
|
||
table.table_row_contents.forEach(row => {
|
||
const key = Object.keys(row)[0]; // Get the first key in the row object
|
||
const answerType = row[key].answer_type; // Get the answer_type
|
||
suggestions[key] = answerType; // Store in suggestions object
|
||
});
|
||
});
|
||
|
||
// // console.log("child table data ", suggestions);
|
||
// child_table_data[rowData.rowID]
|
||
}
|
||
|
||
function getTotalCount(proposalDataArray) {
|
||
let proposals = proposalDataArray.proposal_data.over_all_column_data;
|
||
|
||
// Object.k(proposals)
|
||
// console.log("Proposal insurer keuys : ",proposals)
|
||
var proposalCount = 0;
|
||
var insurerCount = 0;
|
||
for (const key in proposals) {
|
||
if (proposals[key].qcr !== 0) {
|
||
proposalCount++; // Count proposals where qcr !== 0
|
||
|
||
// Only count insurers if the proposal's qcr !== 0
|
||
insurerCount += proposals[key].insurers
|
||
? proposals[key].insurers.filter(insurer => insurer.qcr !== 0).length
|
||
: 0;
|
||
}
|
||
}
|
||
return proposalCount + insurerCount;
|
||
}
|
||
|
||
|
||
|
||
function jsonToTables() {
|
||
|
||
const container = document.getElementById('tablesContainer');
|
||
container.innerHTML = '';
|
||
const savedData = JSON.parse(localStorage.getItem('allTablesJsonData'));
|
||
let lastIndex = savedData.length - 1;
|
||
var proposalDataArray = savedData[lastIndex];
|
||
|
||
// Initialize configurations
|
||
policyConfig = setPolicyConfiguration(proposalDataArray.proposal_data.over_all_column_data);
|
||
quotesConfig = setQuotesConfig(proposalDataArray.proposal_data.over_all_column_data);
|
||
let keys = Object.keys(quotesConfig);
|
||
let lastKey = keys[keys.length - 1];
|
||
if (lead_type == 1){
|
||
proposalCount = lastKey;
|
||
}else{
|
||
if (rfq_count == 0){
|
||
proposalCount = 0;
|
||
}else{
|
||
proposalCount = keys.length-1;
|
||
}
|
||
}
|
||
|
||
|
||
proposalCountForTableINcrease = keys.length;
|
||
// console.log(proposalCount);
|
||
// Calculate width increase
|
||
let increaseBy = rfq_or_qcr == 2 ?
|
||
getTotalCount(proposalDataArray) * 150 :
|
||
proposalCountForTableINcrease * 150;
|
||
|
||
|
||
console.log("Quotes COnfig : ",quotesConfig);
|
||
console.log("policy COnfig :", policyConfig);
|
||
// // // console.log("trying to find checkbox data : : : ", increaseBy);
|
||
|
||
|
||
suggestions = {};
|
||
|
||
const policyTables = {};
|
||
let excessTableContainer = null;
|
||
|
||
// Process each table entry
|
||
savedData.forEach((tableEntry, index) => {
|
||
if (!tableEntry.table_data) return;
|
||
|
||
// 1. Create container structure
|
||
const tableContainer = document.createElement('div');
|
||
tableContainer.className = 'table-container';
|
||
|
||
// 2. Create collapsible bar
|
||
const collapsibleBar = document.createElement('div');
|
||
collapsibleBar.className = 'table-collapsible-bar collapsed';
|
||
collapsibleBar.innerHTML = `
|
||
${tableEntry.table_data.headers[1].parentHeader || 'Table'}
|
||
<span class="collapse-icon">▼</span>
|
||
`;
|
||
|
||
// 3. Create collapsible content area
|
||
const tableContent = document.createElement('div');
|
||
tableContent.className = 'table-content collapse';
|
||
tableContent.style.display = 'none'; // Start collapsed
|
||
|
||
// 4. Create the table
|
||
const table = document.createElement('table');
|
||
$(table).addClass("table table-bordered mt-3");
|
||
if (tableEntry.tableId) table.id = tableEntry.tableId;
|
||
|
||
// Create header structure
|
||
const thead = document.createElement('thead');
|
||
const [headerRow1, headerRow2] = createHeaderRows(tableEntry.table_data.headers, proposalDataArray);
|
||
thead.append(headerRow1, headerRow2);
|
||
table.appendChild(thead);
|
||
|
||
// Create body
|
||
const tbody = document.createElement('tbody');
|
||
tableEntry.table_data.data.forEach((rowData, rowDataIndex) => {
|
||
const tr = document.createElement('tr');
|
||
tr.id = rowData.row_id;
|
||
if (tableEntry.tableId === "excess" && rowData.parentPolicy) {
|
||
tr.setAttribute('data-excess-row-parent', rowData.parentPolicy);
|
||
}
|
||
|
||
// Process each cell
|
||
rowData.data.forEach((cellData, cellIndex) => {
|
||
const td = document.createElement(cellIndex === 0 ? 'td' : 'td');
|
||
|
||
// Handle RowSpan Attribute
|
||
if (cellData.rowspan && cellData.rowspan > 1) {
|
||
td.rowSpan = cellData.rowspan;
|
||
}
|
||
|
||
// Handle SNO column
|
||
if (cellIndex === 0 && tableEntry.tableId) {
|
||
td.textContent = rowData.SNO;
|
||
}
|
||
// Handle Action column
|
||
else if (cellData.parentth === 'Action') {
|
||
if (table.id != "") {
|
||
td.innerHTML = `
|
||
<input class="qcr-checkbox" id="qcrCheckbox" name="qcr" type="checkbox" ${cellData.input_value.qcr ? 'checked' : ''}>
|
||
<label for="qcrCheckbox">QCR</label>
|
||
<input class="client-checkbox" name="stc" type="checkbox" ${cellData.input_value.stc ? 'checked' : ''}>
|
||
Client
|
||
<button class="btn btn-primary btn-sm" onclick="addRow(event, this)">+</button>
|
||
<button class="btn btn-danger btn-sm" onclick="removeRowQCR(event)">-</button>`;
|
||
}else {
|
||
td.innerHTML = "";
|
||
}
|
||
// td.contentEditable = true;
|
||
// td.classList.add("readonly-select");
|
||
}
|
||
// Handle regular cells
|
||
else {
|
||
// td.onclick = () => getAnswer(table.id, tr.id);
|
||
td.innerHTML = processCellContent(cellData.input_value, rowData, cellData.display_content);
|
||
// // console.log("DEBUG ISSUE : ",cellData.parentth)
|
||
if (cellData.parentth.startsWith("Proposal") || cellData.parentth.startsWith("Existing")) {
|
||
|
||
if (lead_type == 1){
|
||
td.onclick = () => getAnswer(table.id, tr.id);
|
||
if (cellData.subth != "Quote asked") {
|
||
td.onclick = () => getAnswer(table.id, tr.id);
|
||
td.classList.add("insurer_proposal");
|
||
}
|
||
}else{
|
||
td.onclick = () => getAnswer(table.id, tr.id);
|
||
if (cellData.subth != "Quote asked") {
|
||
td.onclick = () => getAnswer(table.id, tr.id);
|
||
td.classList.add("insurer_proposal");
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
td.contentEditable = true;
|
||
|
||
|
||
if (cellIndex === 0) {
|
||
td.contentEditable = false;
|
||
}
|
||
}
|
||
tr.appendChild(td);
|
||
});
|
||
tbody.appendChild(tr);
|
||
});
|
||
table.appendChild(tbody);
|
||
selectedPolicies.add(tableEntry.tablePolicy);
|
||
|
||
// Set table width
|
||
const firstTable = document.querySelector('table');
|
||
const tableWidth = firstTable ? $(firstTable).width() : 1200;
|
||
$(table).width(tableWidth);
|
||
$(collapsibleBar).width(tableWidth);
|
||
|
||
// Add click handler for collapsible functionality
|
||
collapsibleBar.addEventListener('click', function() {
|
||
const isCollapsed = tableContent.style.display === 'none';
|
||
tableContent.style.display = isCollapsed ? 'block' : 'none';
|
||
const icon = this.querySelector('.collapse-icon');
|
||
icon.style.transform = isCollapsed ? 'rotate(0deg)' : 'rotate(-90deg)';
|
||
|
||
// Trigger resize if needed
|
||
setTimeout(() => {
|
||
$(window).trigger('resize');
|
||
}, 10);
|
||
});
|
||
|
||
// Build the structure
|
||
tableContent.appendChild(table);
|
||
tableContainer.appendChild(collapsibleBar);
|
||
tableContainer.appendChild(tableContent);
|
||
|
||
// Special handling for excess table
|
||
if (tableEntry.tableId === "excess") {
|
||
excessTableContainer = tableContainer;
|
||
} else {
|
||
const policyName = tableEntry.tablePolicy;
|
||
if (!policyTables[policyName]) {
|
||
policyTables[policyName] = [];
|
||
}
|
||
policyTables[policyName].push(tableContainer);
|
||
}
|
||
});
|
||
|
||
// Append tables in policy groups
|
||
Object.entries(policyTables).forEach(([policyName, tables]) => {
|
||
const policyContainer = document.createElement('div');
|
||
policyContainer.setAttribute('data-parent-row', policyName);
|
||
|
||
tables.forEach(table => {
|
||
policyContainer.appendChild(table);
|
||
});
|
||
|
||
container.appendChild(policyContainer);
|
||
});
|
||
|
||
// Append excess table last if exists
|
||
if (excessTableContainer) {
|
||
container.appendChild(excessTableContainer);
|
||
}
|
||
|
||
// Final initialization
|
||
restoreProposalHeaders(savedData[savedData.length - 1].proposal_data.over_all_column_data);
|
||
reattachEventListeners();
|
||
hideProposalOptionsForChild();
|
||
increaseTableWidth(increaseBy);
|
||
contentNonEditableInsurerAdded(proposalDataArray.proposal_data.over_all_column_data);
|
||
// styleTableColumns();
|
||
showOrHideFieldsBasedOnRFQorQCR();
|
||
}
|
||
|
||
// Helper function to create header rows
|
||
function createHeaderRows(headers, proposal_data) {
|
||
|
||
const headerRow1 = document.createElement('tr');
|
||
const headerRow2 = document.createElement('tr');
|
||
var overallColumnDataProposal = proposal_data.proposal_data.over_all_column_data;
|
||
var matchedKey = "";
|
||
var headerName = '';
|
||
headers.forEach(header => {
|
||
// Parent header
|
||
const th1 = document.createElement('th');
|
||
th1.textContent = header.parentHeader;
|
||
// console.log("parent header : ",header.parentHeader);
|
||
if (header.parentHeader.startsWith('Proposal') || header.parentHeader.startsWith("Existing")) {
|
||
if (lead_type == 1){
|
||
headerName = header.parentHeader;
|
||
}else{
|
||
if (rfq_count == 0){
|
||
headerName = rollover_or_renewal;
|
||
}else{
|
||
headerName = header.parentHeader;
|
||
}
|
||
|
||
}
|
||
var proposalHTMLNumber = "";
|
||
// console.log("Header Name : ",header.parentHeader);
|
||
// alert(headerName);
|
||
if (lead_type == 1){
|
||
// console.log("Header Name lead type 1 : ",header.parentHeader);
|
||
matchedKey = Object.keys(overallColumnDataProposal).find(key => headerName == key);
|
||
|
||
if (!matchedKey){
|
||
console.log("inside else");
|
||
matchedKey = Object.keys(overallColumnDataProposal).find(key => headerName.startsWith(key));
|
||
}
|
||
// matchedKey = Object.keys(overallColumnDataProposal).find(key => headerName.startsWith(key));
|
||
proposalHTMLNumber = header.parentHeader.split(' ')[1];
|
||
// console.log('proposalHTMLNumber',proposalHTMLNumber)
|
||
|
||
}else{
|
||
// console.log("Header Name lead type not 1 : ",header.parentHeader);
|
||
|
||
if (rfq_count == 0 && header.parentHeader.startsWith("Proposal")){
|
||
// console.log("Header Name lead type not 1 proposal: ",header.parentHeader);
|
||
|
||
var tempHeader = header.parentHeader;
|
||
matchedKey = Object.keys(overallColumnDataProposal).find(key => tempHeader == key);
|
||
|
||
if (!matchedKey){
|
||
console.log("inside else");
|
||
matchedKey = Object.keys(overallColumnDataProposal).find(key => tempHeader.startsWith(key));
|
||
}
|
||
// matchedKey = Object.keys(overallColumnDataProposal).find(key => tempHeader.startsWith(key));
|
||
proposalHTMLNumber = 0;
|
||
|
||
}else{
|
||
|
||
// console.log("Header Name lead type not 1 noy proposal: ",header.parentHeader);
|
||
|
||
if (header.parentHeader.startsWith("Existing")){
|
||
var tempHeader2 = lead_type == 2 ?"Existing Renewal 0":"Existing Roll Over 0";
|
||
matchedKey = Object.keys(overallColumnDataProposal).find(key => tempHeader2.startsWith(key));
|
||
proposalHTMLNumber = 0;
|
||
|
||
}else if (header.parentHeader.startsWith("Proposal")){
|
||
|
||
matchedKey = Object.keys(overallColumnDataProposal).find(key => headerName == key);
|
||
|
||
if (!matchedKey){
|
||
console.log("inside else");
|
||
matchedKey = Object.keys(overallColumnDataProposal).find(key => headerName.startsWith(key));
|
||
}
|
||
proposalHTMLNumber = header.parentHeader.split(' ')[1];
|
||
}
|
||
|
||
// alert(matchedKey);
|
||
}
|
||
|
||
}
|
||
|
||
|
||
if (matchedKey) {
|
||
console.log(matchedKey);
|
||
// // console.log("something wrong : ", overallColumnDataProposal[matchedKey]);
|
||
var headerCheckBoxProperties = overallColumnDataProposal[matchedKey];
|
||
// // console.log("something wrong :headerCheckBoxProperties ", headerCheckBoxProperties);
|
||
}
|
||
|
||
// console.log("Header checkbox Properties : ",headerCheckBoxProperties);
|
||
th1.innerHTML = `
|
||
${headerName}
|
||
<span class="three-dot-menu" >⋮</span>
|
||
<div class="dropdown-content">
|
||
<button id = "isQCR" onclick = "addOrRemoveIcon(this,event)" class="qcrProposal" style="background-color: rgb(221, 221, 221);">QCR ${headerCheckBoxProperties['qcr'] == 1 ? `<i
|
||
class="fa fa-check-square"
|
||
style="color: green; margin-left: 8px; "></i> `:"" }</button>
|
||
<button id = "isSTC" class="sendClientProposal" onclick = "addOrRemoveIcon(this,event)"
|
||
style="background-color: rgb(221, 221, 221);">Send to Client ${headerCheckBoxProperties['stc'] == 1 ? `<i
|
||
class="fa fa-check-square"
|
||
style="color: green; margin-left: 8px; "></i> `:"" }</button>
|
||
<button class = "removeProposal" onclick="removeProposal(${proposalHTMLNumber})">Remove Proposal</button>
|
||
<button class = "newInsurer" onclick="addNewQuote(${proposalHTMLNumber})">Add New Insurer</button>
|
||
|
||
</div>
|
||
`;
|
||
th1.colSpan = header.subHeaders.length;
|
||
|
||
// // // console.log("insurer data proposal set : ",th1); // See the element's attributes in the // console
|
||
|
||
}
|
||
headerRow1.appendChild(th1);
|
||
// // // console.log("this is the header : ", header);
|
||
// Sub headers
|
||
header.subHeaders.forEach(subHeader => {
|
||
const th2 = document.createElement('th');
|
||
if (header.parentHeader.startsWith("Proposal") || header.parentHeader.startsWith("Existing")) {
|
||
var insurers = overallColumnDataProposal[matchedKey].insurers;
|
||
// console.log("trying to find something :header.parentHeader ", header.parentHeader);
|
||
// console.log("trying to find something :insurers ", insurers);
|
||
// console.log("trying to find : subHeader",subHeader)
|
||
const matchedInsurer = insurers.find(ins => ins.ins_name == subHeader);
|
||
|
||
|
||
if (subHeader != "Quote asked") {
|
||
// // console.log("trying to find something : matchedInsurer", matchedInsurer);
|
||
// // console.log("trying to find something :matchedInsurer stc ", matchedInsurer.stc);
|
||
// // console.log("trying to find something : ", matchedInsurer.stc);
|
||
|
||
// // console.log("this is the subheader : ", subHeader);
|
||
// // console.log("debug 2: ", subHeader, "parent header : ", header.parentHeader);
|
||
th2.classList.add("insurer_proposal");
|
||
th2.innerHTML = `
|
||
${subHeader}
|
||
<span class="three-dot-menu">⋮</span>
|
||
<div class="dropdown-content">
|
||
<button id = "isInsurerSTC" class="sendInsurerClientProposal" onclick = "addOrRemoveIconInsurer(this,event)"
|
||
style="background-color: rgb(221, 221, 221);">Send to Client ${matchedInsurer.stc == 1 ? `<i
|
||
class="fa fa-check-square"
|
||
style="color: green; margin-left: 8px; "></i>`: ""} </button>
|
||
<button onclick="changeInsurer(event, ${proposalHTMLNumber}, '${subHeader}')">Change Insurer</button>
|
||
<button onclick="removeQuote(event, ${proposalHTMLNumber}, '${subHeader}')">Remove Quote</button>
|
||
</div>
|
||
`;
|
||
} else {
|
||
th2.textContent = subHeader;
|
||
}
|
||
|
||
if (lead_type == 1){
|
||
|
||
th1.setAttribute('data-proposal', header.parentHeader.split(' ')[1]);
|
||
th2.setAttribute('data-proposal', header.parentHeader.split(' ')[1]);
|
||
|
||
}else{
|
||
if (headerName.startsWith("Existing")){
|
||
th1.setAttribute('data-proposal',0);
|
||
th2.setAttribute('data-proposal',0);
|
||
|
||
}else{
|
||
th1.setAttribute('data-proposal', header.parentHeader.split(' ')[1]);
|
||
th2.setAttribute('data-proposal', header.parentHeader.split(' ')[1]);
|
||
|
||
}
|
||
|
||
}
|
||
th2.setAttribute("data-quote", subHeader);
|
||
|
||
// // // console.log("header insert position ",th1.getAttribute())
|
||
|
||
} else {
|
||
th2.textContent = subHeader;
|
||
th2.setAttribute('data-proposal', header.parentHeader.split(' ')[1]);
|
||
th1.setAttribute('data-proposal', header.parentHeader.split(' ')[1]);
|
||
}
|
||
|
||
|
||
headerRow2.appendChild(th2);
|
||
});
|
||
});
|
||
|
||
return [headerRow1, headerRow2];
|
||
}
|
||
|
||
// Helper to process cell content
|
||
function processCellContent(value, cellData = null, displayValue) {
|
||
|
||
if (value.startsWith('Check') || value.startsWith('Not')) {
|
||
|
||
if (value == "Checked") {
|
||
addSuggestion(cellData);
|
||
}
|
||
// // // console.log("insude the function value ", value);
|
||
return `<input type="checkbox" ${value == "Checked" ? "checked" :""} class = "sno-checkbox" /> ${cellData.SNO} ${cellData.SNO == 'Fire' || cellData.SNO == 'Burglary'
|
||
? `<br><button id = '${cellData.SNO.toUpperCase()}_register' class = "btn btn-primary btn-sm" onclick = "getPolicyInfo('${cellData.SNO}')" class="policy-link" data-policy-name="${cellData.SNO}" ${value == "Checked" ? "" :"disabled"} >Register</a>`
|
||
: ""}`;
|
||
}
|
||
if (typeof value === 'string' && value.startsWith('{')) {
|
||
try {
|
||
const parsed = JSON.parse(value);
|
||
return `${displayValue} <input type="hidden" value='${JSON.stringify(parsed)}' />`;
|
||
} catch {
|
||
return value;
|
||
}
|
||
}
|
||
return value;
|
||
}
|
||
|
||
// Restore proposal header icons
|
||
function restoreProposalHeaders(proposalData) {
|
||
Object.entries(proposalData).forEach(([proposal, data]) => {
|
||
const proposalNumber = proposal.split(' ')[1];
|
||
const header = document.querySelector(`th[data-proposal="${proposalNumber}"]`);
|
||
// // // console.log("header attribute set");
|
||
|
||
if (header) {
|
||
// if (data.qcr) header.querySelector('.qcrProposal').appendChild(createCheckIcon());
|
||
// if (data.stc) header.querySelector('.sendClientProposal').appendChild(createCheckIcon());
|
||
}
|
||
});
|
||
}
|
||
|
||
// Reattach event listeners
|
||
function reattachEventListeners() {
|
||
const container = document.getElementById('tablesContainer');
|
||
|
||
|
||
// Three-dot menu handlers
|
||
document.querySelectorAll('.three-dot-menu').forEach(menu => {
|
||
menu.addEventListener('click', showDropdown);
|
||
// // // console.log("event listener called ");
|
||
});
|
||
|
||
// Policy link handlers
|
||
document.querySelectorAll('.policy-link').forEach(link => {
|
||
link.addEventListener('click', function(e) {
|
||
getPolicyInfo(e.target.dataset.policyName);
|
||
e.preventDefault();
|
||
});
|
||
});
|
||
}
|
||
|
||
function createCheckIcon() {
|
||
const icon = document.createElement('i');
|
||
icon.className = 'fa fa-check-square';
|
||
icon.style.color = 'green';
|
||
icon.style.marginLeft = '8px';
|
||
return icon;
|
||
}
|
||
|
||
function showOrHideFieldsBasedOnRFQorQCR() {
|
||
// // console.log("function called rfq or qcr ", rfq_or_qcr);
|
||
|
||
if (rfq_or_qcr == 1) {
|
||
$(".insurer_proposal").attr("contenteditable",false);
|
||
$(".newInsurer").hide();
|
||
$("#isQCR").show();
|
||
$(".qcr-checkbox").show();
|
||
$("label[for='qcrCheckbox']").show();
|
||
$("#openQCR").show();
|
||
$("input#qcrCheckbox").show();
|
||
$("#addProposal").show();
|
||
alignTableColumn();
|
||
$(".qcrProposal").show();
|
||
$("#saveRFQ").text("Save RFQ");
|
||
$("#submitMail").text("Send Insurer Mail");
|
||
$(".rfqbtn").show();
|
||
$(".qcrbtn").hide();
|
||
$("#saveRFQ").css("margin-right", "10px");
|
||
$('#rfq_qcr_page_title').text('RFQ');
|
||
$(".removeProposal").show();
|
||
|
||
|
||
} else if (rfq_or_qcr == 2) {
|
||
$(".insurer_proposal").attr("contenteditable",true);
|
||
$(".newInsurer").show();
|
||
$("#isQCR").hide();
|
||
$(".qcr-checkbox").hide();
|
||
$("label[for='qcrCheckbox']").hide();
|
||
$("input#qcrCheckbox").hide();
|
||
$("#addProposal").hide();
|
||
$(".insurer_proposal").show();
|
||
$(".qcrProposal").hide();
|
||
$("#saveRFQ").text("Save QCR");
|
||
$("#submitMail").text("Send Client Mail");
|
||
// $(".sno-checkboxes").prop("disabled", true);
|
||
$("#openQCR").hide();
|
||
$(".removeProposal").hide();
|
||
hideNonQCRRows();
|
||
hideNonQCRColumns();
|
||
disableCheckbox();
|
||
restoreOnClickToColumnCells();
|
||
|
||
$(".rfqbtn").hide();
|
||
$(".qcrbtn").show();
|
||
$("#saveRFQ").css("margin-right", "20px");
|
||
$('#rfq_qcr_page_title').text('QCR');
|
||
|
||
}
|
||
|
||
if (rfq_count != 0) {
|
||
$('.actionBtns').show();
|
||
if (rfq_or_qcr == 2) {
|
||
$("#openQCR").hide();
|
||
$("#submitPlacement").show();
|
||
} else {
|
||
$("#submitPlacement").hide();
|
||
}
|
||
} else {
|
||
$('.actionBtns').hide();
|
||
}
|
||
makeQuoteAskedColumnNonEditableorEditable();
|
||
}
|
||
|
||
function disableCheckbox() {
|
||
|
||
// Select all checkboxes with the class "sno-checkboxes"
|
||
const checkboxes = document.querySelectorAll('.sno-checkbox');
|
||
// // // console.log("inside disable ",checkboxes);
|
||
// Disable all selected checkboxes
|
||
checkboxes.forEach(checkbox => {
|
||
checkbox.disabled = true;
|
||
// // // console.log("inside disable loop",checkbox);
|
||
});
|
||
}
|
||
|
||
function hideNonQCRColumns() {
|
||
|
||
const savedData = JSON.parse(localStorage.getItem('allTablesJsonData'));
|
||
let lastIndex = savedData.length - 1;
|
||
var proposalDataArray = savedData[lastIndex];
|
||
var overallData = proposalDataArray.proposal_data.over_all_column_data;
|
||
const getProposalsWithQCRZero = (data) => {
|
||
return Object.keys(data).filter(proposal => data[proposal].qcr === 0);
|
||
};
|
||
|
||
var proposal = getProposalsWithQCRZero(overallData);
|
||
// // console.log("column to hide : ", proposal);
|
||
proposal.forEach(function(prop) {
|
||
// console.log("column prop : ", prop);
|
||
hideColumn(prop);
|
||
})
|
||
|
||
}
|
||
|
||
function hideColumn(columnName) {
|
||
// // console.log(`Hiding column: ${columnName}`);
|
||
|
||
document.querySelectorAll("table").forEach(table => {
|
||
// 1. Find the main proposal header in the first header row
|
||
const mainHeaderRow = table.querySelector('thead tr:first-child');
|
||
let proposalHeader = null;
|
||
let proposalColspan = 1;
|
||
let startColumnIndex = 2;
|
||
|
||
// Find the header matching the columnName and its position
|
||
Array.from(mainHeaderRow.children).forEach((th, index) => {
|
||
if (th.textContent.trim().startsWith(columnName)) {
|
||
proposalHeader = th;
|
||
proposalColspan = parseInt(th.getAttribute('colspan')) || 1;
|
||
// startColumnIndex = index; // Starting index of the proposal header
|
||
proposalNumber = parseInt(th.textContent.trim().replace(/\D/g, ""), 10);
|
||
return;
|
||
}
|
||
});
|
||
|
||
if (!proposalHeader) {
|
||
// // console.log(`Column "${columnName}" not found.`);
|
||
return;
|
||
}
|
||
|
||
// 2. Hide the main proposal header
|
||
proposalHeader.style.display = "none";
|
||
if (lead_type == 1){
|
||
for (let i = 1; i < proposalNumber; i++) {
|
||
startColumnIndex += quotesConfig[i]?.length || 0;
|
||
}
|
||
}else{
|
||
for (let i = 0; i < proposalNumber; i++) {
|
||
startColumnIndex += quotesConfig[i]?.length || 0;
|
||
}
|
||
}
|
||
|
||
// 3. Find and hide all subheaders under this proposal
|
||
const subHeaderRow = table.querySelector('thead tr:last-child');
|
||
const subHeaders = Array.from(subHeaderRow.children);
|
||
|
||
// Calculate range of subheaders to hide (same colspan as proposal header)
|
||
const endColumnIndex = startColumnIndex + proposalColspan - 1;
|
||
// console.log("end col index : ",endColumnIndex);
|
||
|
||
for (let i = startColumnIndex; i <= endColumnIndex; i++) {
|
||
if (subHeaders[i]) subHeaders[i].style.display = "none";
|
||
}
|
||
|
||
// 4. Hide corresponding cells in all data rows
|
||
table.querySelectorAll('tbody tr').forEach(row => {
|
||
const cells = Array.from(row.children);
|
||
for (let i = startColumnIndex; i <= endColumnIndex; i++) {
|
||
if (cells[i]) cells[i].style.display = "none";
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
function hideNonQCRRows() {
|
||
// // console.log("hideNonQCRRows function called");
|
||
// Select all tables
|
||
document.querySelectorAll("table").forEach(table => {
|
||
|
||
// // console.log("Processing table:", table);
|
||
// Loop through each row in the table
|
||
table.querySelectorAll("tr").forEach(row => {
|
||
// // // console.log("Processing row:", row);
|
||
// Find the qcr-checkbox in the current row
|
||
const qcrCheckbox = row.querySelector(".qcr-checkbox");
|
||
// // console.log("QCR Checkbox:", qcrCheckbox);
|
||
|
||
if (qcrCheckbox && !qcrCheckbox.checked) {
|
||
// If qcr-checkbox exists and is NOT checked, hide the row
|
||
// // console.log("Hiding row:", row);
|
||
row.style.display = "none"; // Uncomment this line to hide the row
|
||
updateVisisbleSNO(table.id);
|
||
} else {
|
||
// Otherwise, ensure the row is visible
|
||
// // // console.log("Showing row:", row);
|
||
row.style.display = "";
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
function removeRowQCR(event) {
|
||
const button = event.target;
|
||
const row = button.closest('tr');
|
||
const table = row.closest('table');
|
||
if (row && row.parentElement.children.length > 1) {
|
||
// // console.log("Row Removed");
|
||
row.remove();
|
||
updateVisisbleSNO(table.id);
|
||
}
|
||
}
|
||
|
||
function updateVisisbleSNO(tableId) {
|
||
// // console.log(`Updating SNO for table: ${tableId}`);
|
||
|
||
const table = document.getElementById(tableId);
|
||
if (!table) {
|
||
// // console.log("Table not found!");
|
||
return;
|
||
}
|
||
|
||
let sno = 1; // Start from 1
|
||
table.querySelectorAll("tr").forEach(row => {
|
||
if (row.style.display !== "none") { // Only update visible rows
|
||
const firstCell = row.querySelector("td:first-child"); // Get SNO cell
|
||
if (firstCell) {
|
||
firstCell.innerHTML = `<td "class="sno-checkbox"> ${sno}</td>`;
|
||
sno++; // Increment SNO for the next row
|
||
}
|
||
// const snoCell = row.querySelector(".sno"); // Assuming SNO cell has class "sno"
|
||
// if (snoCell) {
|
||
// snoCell.textContent = sno++; // Assign and increment SNO
|
||
// // // console.log(`Updated SNO: ${snoCell.textContent}`);
|
||
// }
|
||
}
|
||
});
|
||
}
|
||
|
||
function alignTableColumn() {
|
||
$(".insurer_proposal").each(function() {
|
||
let columnIndex = $(this).index(); // Get index of the hidden column
|
||
let parentHeader = $(this).closest("table").find("tr:first-child th").filter(function() {
|
||
return $(this).attr("colspan") > 1; // Find headers with colspan > 1
|
||
});
|
||
|
||
// Reduce colspan if the hidden column belongs to this header
|
||
parentHeader.each(function() {
|
||
let colspan = parseInt($(this).attr("colspan"), 10);
|
||
if (colspan > 1) {
|
||
$(this).attr("colspan", colspan - 1);
|
||
}
|
||
});
|
||
|
||
// Hide the column
|
||
$(this).hide();
|
||
});
|
||
|
||
}
|
||
function restoreOnClickToColumnCells() {
|
||
|
||
$("table").each(function() {
|
||
const table = $(this);
|
||
const tableId = table.attr("id") || "parent"; // Default to "parent" if no ID
|
||
|
||
// Find all cells marked with data-onclick-removed
|
||
table.find("td.insurer_proposal[data-onclick-removed='true']").each(function() {
|
||
const cell = $(this);
|
||
const row = cell.closest("tr");
|
||
const rowId = row.attr("id");
|
||
|
||
// Reattach the onclick event
|
||
cell[0].onclick = () => getAnswer(tableId, rowId);
|
||
|
||
// Remove the marker attribute since the event is restored
|
||
cell.removeAttr("data-onclick-removed");
|
||
|
||
// Ensure the cell is editable in QCR mode
|
||
cell.attr("contenteditable", "true");
|
||
});
|
||
});
|
||
}
|
||
|
||
function removeOnClickFromColumnCells(cell) {
|
||
cell.removeAttr("onclick");
|
||
cell.off("click");
|
||
cell[0].onclick = null; // Remove any remaining native listeners
|
||
cell.attr("data-onclick-removed", "true"); //mark the cell
|
||
}
|
||
|
||
function makeQuoteAskedColumnNonEditableorEditable() {
|
||
// alert("Quote asked");
|
||
$("table").each(function() {
|
||
var table = $(this);
|
||
var subHeaderRow = table.find("tr:nth-child(2)"); // Assuming second row is the sub-header
|
||
|
||
var targetColumnIndexes = [];
|
||
// var targetColumnIndex = -1; // Stores the correct column index
|
||
var colIndexTracker = []; // Maps visual column index to actual index
|
||
var visualIndex = 0; // Tracks the visual column position considering rowspan/colspan
|
||
|
||
// Step 1: Find the "Quote asked" column index
|
||
subHeaderRow.children("th, td").each(function(actualIndex) {
|
||
colIndexTracker[visualIndex] = actualIndex;
|
||
|
||
if ($(this).text().trim() === "Quote asked") {
|
||
targetColumnIndexes.push(visualIndex);
|
||
}
|
||
|
||
visualIndex += parseInt($(this).attr("colspan") || 1, 10);
|
||
});
|
||
|
||
if (targetColumnIndexes === 0) return; // If "Quote asked" column is not found, exit
|
||
|
||
// Step 2: Make all cells in the found column non-editable, considering rowspan
|
||
var rowSpans = {}; // Keeps track of rowspans per column
|
||
table.find("tr").each(function() {
|
||
var row = $(this);
|
||
var currentVisualIndex = 0;
|
||
|
||
row.children("td, th").each(function(actualIndex) {
|
||
while (rowSpans[currentVisualIndex]) {
|
||
currentVisualIndex++; // Skip previous row-spanned columns
|
||
}
|
||
|
||
var cell = $(this);
|
||
var actualColIndex = colIndexTracker[currentVisualIndex];
|
||
|
||
if (targetColumnIndexes.includes(colIndexTracker[currentVisualIndex])) {
|
||
|
||
if (rfq_or_qcr == 2) {
|
||
cell.attr("contenteditable", "false");
|
||
removeOnClickFromColumnCells(cell);
|
||
|
||
if (!cell.text().trim().startsWith("Proposal") && !cell.text().trim().startsWith("Existing")){
|
||
cell.addClass("readonly-select");
|
||
}
|
||
} else if (rfq_or_qcr == 1) {
|
||
// cell.attr("contenteditable", "true");
|
||
}
|
||
|
||
}
|
||
|
||
var rowspan = parseInt(cell.attr("rowspan") || 1, 10);
|
||
if (rowspan > 1) {
|
||
for (var i = 0; i < rowspan; i++) {
|
||
rowSpans[currentVisualIndex] = (rowSpans[currentVisualIndex] || 0) + 1;
|
||
}
|
||
}
|
||
|
||
currentVisualIndex++;
|
||
});
|
||
|
||
// Step 3: Reduce rowspan count for next row processing
|
||
Object.keys(rowSpans).forEach(function(key) {
|
||
if (rowSpans[key] > 0) {
|
||
rowSpans[key]--;
|
||
}
|
||
});
|
||
});
|
||
});
|
||
}
|
||
|
||
function contentNonEditableInsurerAdded(overallcolumnData) {
|
||
// alert("insurer")
|
||
let insNames = [];
|
||
Object.entries(overallcolumnData).forEach(([proposalKey, proposalValue]) => {
|
||
if (proposalValue.insurers.length > 0) {
|
||
insNames.push(proposalKey); // Push proposal key if insurers are present
|
||
}
|
||
});
|
||
|
||
// console.log("Insurer names to make non-editable:", insNames);
|
||
|
||
$("table").each(function() {
|
||
var table = $(this);
|
||
var mainHeaderRow = table.find("tr:first-child"); // First row as main header
|
||
var targetColumnIndexes = new Set();
|
||
|
||
// Step 1: Create a mapping of visual index to column header text
|
||
var headerMapping = [];
|
||
var visualIndex = 0;
|
||
|
||
mainHeaderRow.children("th, td").each(function() {
|
||
var cellText = $(this).text().trim();
|
||
if (cellText.startsWith("Existing")){
|
||
cellText = lead_type == 2 ?"Existing Renewal 0":"Existing Roll Over 0";
|
||
}
|
||
var colspan = parseInt($(this).attr("colspan") || 1, 10);
|
||
// console.log("cellText",cellText);
|
||
// Store the header text at this visual index
|
||
for (var i = 0; i < colspan; i++) {
|
||
headerMapping[visualIndex + i] = cellText;
|
||
}
|
||
|
||
// Check if this column matches any insurer name
|
||
if (insNames.some(ins => cellText.startsWith(ins))) {
|
||
for (var i = 0; i < colspan; i++) {
|
||
targetColumnIndexes.add(visualIndex + i);
|
||
}
|
||
}
|
||
|
||
visualIndex += colspan;
|
||
});
|
||
|
||
// // console.log("Target column indexes:", Array.from(targetColumnIndexes));
|
||
|
||
if (targetColumnIndexes.size === 0) return; // If no matching column is found, exit
|
||
|
||
var rowSpans = {};
|
||
|
||
// Step 2: Iterate through rows and set cells as non-editable
|
||
table.find("tr").each(function(rowIndex) {
|
||
var row = $(this);
|
||
var currentVisualIndex = 0;
|
||
|
||
row.children("td, th").each(function() {
|
||
// Skip cells that are covered by rowspans from previous rows
|
||
while (rowSpans[currentVisualIndex] > 0) {
|
||
rowSpans[currentVisualIndex]--;
|
||
currentVisualIndex++;
|
||
}
|
||
|
||
var cell = $(this);
|
||
var cellColspan = parseInt(cell.attr("colspan") || 1, 10);
|
||
var cellRowspan = parseInt(cell.attr("rowspan") || 1, 10);
|
||
|
||
// Check if any of the columns this cell spans are in our target set
|
||
let makeNonEditable = false;
|
||
for (let i = 0; i < cellColspan; i++) {
|
||
if (targetColumnIndexes.has(currentVisualIndex + i)) {
|
||
makeNonEditable = true;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (makeNonEditable) {
|
||
// // console.log('Found Cell : ',cell.text());
|
||
cell.attr("contenteditable", "false");
|
||
removeOnClickFromColumnCells(cell);
|
||
}
|
||
|
||
// Track rowspan for future rows
|
||
if (cellRowspan > 1) {
|
||
for (var i = 0; i < cellColspan; i++) {
|
||
rowSpans[currentVisualIndex + i] = (rowSpans[currentVisualIndex + i] || 0) + (cellRowspan - 1);
|
||
}
|
||
}
|
||
|
||
// Move to the next visual position
|
||
currentVisualIndex += cellColspan;
|
||
});
|
||
});
|
||
});
|
||
}
|
||
|
||
function prependTable(policyJson, policyName) {
|
||
|
||
// alert("hi");
|
||
// // console.log("table to prepened : ", policyJson);
|
||
let parentDiv = document.querySelector(`div[data-parent-row=${policyName}]`);
|
||
// let newTable = document.createElement("table");
|
||
|
||
if (parentDiv) {
|
||
|
||
let tables = Array.from(parentDiv.querySelectorAll("table"));
|
||
|
||
tables.forEach(table => {
|
||
if (table.id.includes("summary")) {
|
||
table.remove(); // reMove summary table from the top
|
||
}
|
||
});
|
||
|
||
policyJson.slice().reverse().forEach(childTable => {
|
||
generateTable(parentDiv, true, policyName, childTable);
|
||
|
||
});
|
||
|
||
|
||
moveSummaryTableToTop(policyName);
|
||
hideProposalOptionsForChild();
|
||
showOrHideFieldsBasedOnRFQorQCR();
|
||
styleTableColumns();
|
||
|
||
}
|
||
|
||
|
||
}
|
||
|
||
function moveSummaryTableToTop(policyName) {
|
||
let parentDiv = document.querySelector(`div[data-parent-row="${policyName}"]`);
|
||
if (!parentDiv) return; // Exit if no such div exists
|
||
|
||
// Find all table containers instead of just tables
|
||
let tableContainers = Array.from(parentDiv.querySelectorAll(".table-container"));
|
||
|
||
tableContainers.forEach(container => {
|
||
// Check if this container holds a table with "summary" in its ID
|
||
const table = container.querySelector("table");
|
||
if (table && table.id.includes("summary")) {
|
||
parentDiv.prepend(container); // Move the entire table-container to the top
|
||
updateSNO(table.id); // Update SNO for the moved table
|
||
}
|
||
});
|
||
}
|
||
|
||
|
||
// Calculate the total number of visual columns in the table
|
||
function calculateTotalColumns(table) {
|
||
const rows = table.querySelectorAll('tr');
|
||
let maxColumns = 0;
|
||
rows.forEach((row) => {
|
||
const cells = row.querySelectorAll('th, td');
|
||
let currentColumn = 0;
|
||
cells.forEach((cell) => {
|
||
const colspan = parseInt(cell.getAttribute('colspan')) || 1;
|
||
currentColumn += colspan;
|
||
});
|
||
if (currentColumn > maxColumns) {
|
||
maxColumns = currentColumn;
|
||
}
|
||
});
|
||
return maxColumns;
|
||
}
|
||
|
||
function buildTableGrid(table) {
|
||
const rows = table.querySelectorAll('tr');
|
||
const totalColumns = calculateTotalColumns(table);
|
||
const grid = Array.from({ length: rows.length }, () => Array(totalColumns).fill(null));
|
||
let activeRowSpans = [];
|
||
|
||
rows.forEach((row, rowIndex) => {
|
||
const cells = row.querySelectorAll('th, td');
|
||
let currentColumnIndex = 0;
|
||
let newSpans = []; // Collect new spans for the current row
|
||
|
||
// Handle active rowspans from previous rows
|
||
activeRowSpans.forEach((span) => {
|
||
for (let c = span.startCol; c < span.startCol + span.colspan; c++) {
|
||
if (rowIndex < grid.length && c < totalColumns) {
|
||
grid[rowIndex][c] = 'span';
|
||
}
|
||
}
|
||
});
|
||
|
||
cells.forEach((cell) => {
|
||
// Skip hidden columns
|
||
if (window.getComputedStyle(cell).display === 'none') return;
|
||
|
||
// Find the next available column index
|
||
while (currentColumnIndex < totalColumns && grid[rowIndex][currentColumnIndex] !== null) {
|
||
currentColumnIndex++;
|
||
}
|
||
if (currentColumnIndex >= totalColumns) return; // Skip if beyond grid
|
||
|
||
const colspan = parseInt(cell.getAttribute('colspan')) || 1;
|
||
const rowspan = parseInt(cell.getAttribute('rowspan')) || 1;
|
||
|
||
// Place the cell and mark spanned cells
|
||
for (let r = rowIndex; r < rowIndex + rowspan; r++) {
|
||
for (let c = currentColumnIndex; c < currentColumnIndex + colspan; c++) {
|
||
if (r < grid.length && c < totalColumns) {
|
||
grid[r][c] = (r === rowIndex && c === currentColumnIndex) ? cell : 'span';
|
||
}
|
||
}
|
||
}
|
||
|
||
if (rowspan > 1) {
|
||
newSpans.push({
|
||
startCol: currentColumnIndex,
|
||
colspan: colspan,
|
||
remainingRows: rowspan - 1
|
||
});
|
||
}
|
||
currentColumnIndex += colspan;
|
||
});
|
||
|
||
// Decrement remainingRows and filter out expired spans
|
||
activeRowSpans = activeRowSpans.filter((span) => {
|
||
span.remainingRows--;
|
||
return span.remainingRows > 0;
|
||
});
|
||
|
||
// Add new spans after processing current row
|
||
activeRowSpans.push(...newSpans);
|
||
});
|
||
|
||
return grid;
|
||
}
|
||
|
||
|
||
function styleTableColumns() {
|
||
// alert();
|
||
const tables = document.querySelectorAll('table');
|
||
const columnColors = {};
|
||
|
||
tables.forEach((table) => {
|
||
const grid = buildTableGrid(table);
|
||
const totalColumns = grid[0] ? grid[0].length : 0;
|
||
// // console.log("Table grid:", grid);
|
||
|
||
const cellStartingCols = new Map();
|
||
grid.forEach((row) => {
|
||
row.forEach((cell, colIndex) => {
|
||
if (cell && cell !== 'span' && !cellStartingCols.has(cell)) {
|
||
cellStartingCols.set(cell, colIndex);
|
||
}
|
||
});
|
||
});
|
||
|
||
// // console.log("Setting color:", columnColors);
|
||
cellStartingCols.forEach((startingCol, cell) => {
|
||
const colspan = parseInt(cell.getAttribute('colspan')) || 1;
|
||
|
||
// Assign the same color for the whole column span
|
||
if (!columnColors[startingCol] && startingCol !== 0 && startingCol !== 1 && startingCol !== 2 && startingCol !== totalColumns - 1) {
|
||
columnColors[startingCol] = `hsl(${Math.random() * 360}, 100%, 93%)`;
|
||
}
|
||
|
||
if (startingCol === 0 || startingCol === 1) {
|
||
cell.style.backgroundColor = '#bfe0e2'; // First & second columns
|
||
} else if (startingCol === totalColumns - 1) {
|
||
cell.style.backgroundColor = 'white'; // Third & last column
|
||
} else {
|
||
// Assign the same color to the full colspan range
|
||
const color = columnColors[startingCol] || '#f0f0f0';
|
||
|
||
for (let c = startingCol; c < startingCol + colspan; c++) {
|
||
columnColors[c] = color; // Ensure all spanned columns match
|
||
}
|
||
}
|
||
});
|
||
|
||
// Apply colors to all cells in their respective columns
|
||
grid.forEach((row) => {
|
||
row.forEach((cell, colIndex) => {
|
||
if (cell && cell !== 'span' && columnColors[colIndex]) {
|
||
cell.style.backgroundColor = columnColors[colIndex];
|
||
}
|
||
});
|
||
});
|
||
});
|
||
}
|
||
|
||
|
||
|
||
document.querySelectorAll('.table-collapsible-bar').forEach(bar => {
|
||
bar.addEventListener('click', function() {
|
||
// alert("Hekllo");
|
||
const content = this.nextElementSibling; // The table-content div
|
||
const isCollapsed = this.classList.contains('collapsed');
|
||
|
||
if (isCollapsed) {
|
||
this.classList.remove('collapsed');
|
||
content.style.display = 'block';
|
||
} else {
|
||
this.classList.add('collapsed');
|
||
content.style.display = 'none';
|
||
}
|
||
});
|
||
});
|
||
|
||
$(document).on('input change', 'table', function (e) {
|
||
checkCellValueAndHighlight(e);
|
||
});
|
||
|
||
// Also trigger when new rows or tables are added
|
||
const observer = new MutationObserver(() => {
|
||
checkCellValueAndHighlight();
|
||
});
|
||
|
||
observer.observe(document.body, { childList: true, subtree: true });
|
||
|
||
function checkCellValueAndHighlight(e) {
|
||
|
||
// // // console.log("highlight:", e.target);
|
||
// // // console.log("highlight:", e.target);
|
||
|
||
var rowIdCount = {};
|
||
|
||
const tables = document.querySelectorAll('table'); // Select all tables
|
||
|
||
tables.forEach(table => {
|
||
|
||
if (table.id != ""){
|
||
const headerRows = table.querySelectorAll('thead tr');
|
||
if (headerRows.length < 2) return; // Ensure there are at least 2 header rows
|
||
|
||
const headerRow1 = headerRows[0]; // First header row (main headers)
|
||
const rows = table.querySelectorAll('tbody tr'); // All body rows
|
||
|
||
let startCol = 2; // Start after skipping SNO and items columns
|
||
|
||
headerRow1.querySelectorAll('th').forEach((th, index) => {
|
||
if (index < 2) return; // Skip SNO and items
|
||
|
||
const colspan = th.getAttribute('colspan') ? parseInt(th.getAttribute('colspan')) : 1;
|
||
const rowspan = th.getAttribute('rowspan') ? parseInt(th.getAttribute('rowspan')) : 1;
|
||
const compareIndices = [...Array(colspan).keys()].map(i => i + startCol); // Get column indices to compare
|
||
|
||
rows.forEach(row => {
|
||
const cells = row.querySelectorAll('td');
|
||
compareRange(cells, compareIndices);
|
||
});
|
||
|
||
startCol += colspan; // Move to the next set of columns
|
||
});
|
||
}else{
|
||
|
||
const headerRows = table.querySelectorAll('thead tr');
|
||
// // console.log("Header rows in highlight:", headerRows);
|
||
if (headerRows.length < 2) return; // Ensure there are at least 2 header rows
|
||
|
||
const headerRow1 = headerRows[0]; // First header row (main headers)
|
||
const rows = table.querySelectorAll('tbody tr'); // All body rows
|
||
|
||
let startCol = 2; // Start after skipping SNO and items columns
|
||
let rowSpanStartCol = 1;
|
||
|
||
headerRow1.querySelectorAll('th').forEach((th, index) => {
|
||
if (index < 2) return; // Skip SNO and items
|
||
|
||
let colspan = th.getAttribute('colspan') ? parseInt(th.getAttribute('colspan')) : 1;
|
||
// // console.log('colspan:', colspan);
|
||
|
||
const compareIndices = [...Array(colspan).keys()].map(i => i + startCol); // Get column indices to compare
|
||
// // console.log("Compare indices:", compareIndices);
|
||
|
||
let rowIdCount = {}; // Reset rowIdCount for each column group
|
||
|
||
rows.forEach(row => {
|
||
const rowId = row.id;
|
||
// // console.log("Row ID:", rowId);
|
||
|
||
if (rowIdCount[rowId] === undefined) {
|
||
rowIdCount[rowId] = 0;
|
||
} else {
|
||
rowIdCount[rowId]++;
|
||
}
|
||
// // console.log("Row ID Count:", rowIdCount[rowId]);
|
||
|
||
let dynamicStartCol = rowIdCount[rowId] > 0 ? rowSpanStartCol : startCol;
|
||
// // console.log("Dynamic Start Col:", dynamicStartCol);
|
||
|
||
const dynamicCompareIndices = [...Array(colspan).keys()].map(i => i + dynamicStartCol);
|
||
// // console.log("Dynamic Compare Indices:", dynamicCompareIndices);
|
||
|
||
const cells = row.querySelectorAll('td');
|
||
compareRange(cells, dynamicCompareIndices);
|
||
});
|
||
|
||
startCol += colspan; // Move to the next set of columns
|
||
rowSpanStartCol += colspan; // Move to the next set of columns
|
||
|
||
|
||
});
|
||
|
||
}
|
||
|
||
});
|
||
|
||
|
||
}
|
||
|
||
function compareRange(cells, indices) {
|
||
if (cells.length === 0) return; // Ensure cells exist
|
||
|
||
const baseValue = cells[indices[0]]?.textContent.trim(); // Get base value safely
|
||
// // // console.log("cell index : baseValue",baseValue);
|
||
indices.forEach(index => {
|
||
|
||
// // // console.log("cell index : ",cells[index].textContent.trim());
|
||
if (!cells[index]) return; // Skip if index is out of bounds
|
||
|
||
if (cells[index].textContent.trim() !== baseValue) {
|
||
cells[index].classList.add('bold'); // Highlight mismatched cells
|
||
} else {
|
||
cells[index].classList.remove('bold');
|
||
}
|
||
});
|
||
}
|
||
|
||
</script>
|
||
|
||
<!-- Export Excel and Mail Script -->
|
||
<script>
|
||
var proposalDataForDropDown = {};
|
||
var user_role_id = <?= get_role_id(); ?>;
|
||
|
||
const editorConfig = {
|
||
buttons: [
|
||
"bold",
|
||
"italic",
|
||
"strikethrough",
|
||
"|",
|
||
"superscript",
|
||
"subscript",
|
||
"|",
|
||
"align",
|
||
"fontsize",
|
||
"|",
|
||
"source" // Add the "source" button for editing HTML
|
||
],
|
||
fontsize: ["8px", "10px", "12px", "14px", "16px", "18px", "20px", "22px", "24px"], // Font sizes in pixels
|
||
showPlaceholder: false,
|
||
toolbarButtonSize: "small",
|
||
toolbarAdaptive: false,
|
||
saveHeightInStorage: true,
|
||
minHeight: 400,
|
||
height: 400, // Optional fixed height
|
||
defaultMode: "1", // Start in WYSIWYG mode
|
||
enableDragAndDropFileToEditor: true, // Allow file uploads via drag and drop
|
||
placeholder: "Start typing here...", // Optional placeholder text
|
||
};
|
||
|
||
$(document).ready(function() {
|
||
|
||
const path = window.location.pathname; // Get the current URL path
|
||
const segments = path.split('/'); // Split the path into segments
|
||
const lead_id = segments[segments.length - 2]; // Get the second last segment (15)
|
||
const rfq_type = segments[segments.length - 1]; // Get the last segment (2)
|
||
|
||
// // console.log('Lead ID:', lead_id);
|
||
// // console.log('Type:', rfq_type);
|
||
|
||
let excel_url = '<?= base_url('leads/exportQCRandRFQ/') ?>' + lead_id + '/' + rfq_type + '/' + 2
|
||
// // console.log(excel_url, excel_url);
|
||
|
||
$('#submitExcel').attr('data-url', excel_url);
|
||
|
||
$('#cc').select2({
|
||
placeholder: 'Select CC Mail',
|
||
});
|
||
|
||
$('#placement_cc').select2({
|
||
placeholder: 'Select CC Mail',
|
||
});
|
||
|
||
$('#proposals').select2({
|
||
placeholder: 'Select To proposal',
|
||
});
|
||
|
||
$('#placement_to').select2({
|
||
placeholder: 'Select To Mail',
|
||
});
|
||
|
||
$('#to').select2({
|
||
placeholder: 'Select To Mail',
|
||
});
|
||
|
||
$("textarea.select2-search__field").attr('rows', '1');
|
||
$("textarea.select2-search__field").css('resize', 'none');
|
||
|
||
let placementLeadData = <?= isset($lead_data) && isset($lead_data['proposel_data']) ? json_encode($lead_data['proposel_data']) : 'null'; ?>;
|
||
// // // console.log('placementLeadData', placementLeadData);
|
||
|
||
if (placementLeadData) {
|
||
placementLeadData = JSON.parse(placementLeadData);
|
||
let txt = 'The data has already been sent to the insurer ' +
|
||
placementLeadData.insurer_name +
|
||
' and the proposal is ' +
|
||
placementLeadData.proposel_name + '.';
|
||
$('#alert_msg').text(txt);
|
||
} else {
|
||
$('#alert_msg').text('');
|
||
// // console.log('placementLeadData is null or undefined.');
|
||
}
|
||
|
||
|
||
// Initialize the Jodit editor
|
||
const editor = Jodit.make("#placement_mail_content", editorConfig);
|
||
|
||
const editor2 = Jodit.make("#internal_mail_content", editorConfig);
|
||
|
||
var placement_date_datePicker = flatpickr("#placement_date", {
|
||
dateFormat: "d/m/Y",
|
||
allowInput: false,
|
||
});
|
||
|
||
|
||
})
|
||
|
||
function checkTheTableDataChanged(redirect_type) {
|
||
|
||
|
||
if (redirect_type == 1) {
|
||
//BACK BUTTON
|
||
window.location.href = "<?= base_url("leads/list") ?>"
|
||
|
||
} else if (redirect_type == 2) {
|
||
//EXCEL EXPORT
|
||
// let url = $('#submitExcel').data('url');
|
||
|
||
let lead_id = $('#lead_id').val();
|
||
let url = '<?= base_url('leads/exportQCRandRFQ/') ?>' + lead_id + '/' + rfq_or_qcr + '/' + 2
|
||
|
||
window.location.href = url;
|
||
|
||
} else if (redirect_type == 3) {
|
||
//INSURER OR CLIENT MAIL SEND
|
||
showModal(1);
|
||
|
||
} else if (redirect_type == 4) {
|
||
//INTERNAL MAIL SEND
|
||
showModal(2);
|
||
|
||
} else if (redirect_type == 5) {
|
||
//PROCCED TO QCR
|
||
// submitQCRData();
|
||
let lead_id = $('#lead_id').val();
|
||
let url = '<?= base_url('rfq/list/') ?>' + lead_id + '/' + 2;
|
||
window.location.href = url;
|
||
|
||
} else if (redirect_type == 6) {
|
||
//INTERNAL MAIL SEND
|
||
showModal(3);
|
||
|
||
}
|
||
}
|
||
|
||
function showModal(mail_type) {
|
||
|
||
if (mail_type == 1) {
|
||
|
||
insurerAndClientMailPopUp()
|
||
|
||
} else if (mail_type == 2) {
|
||
|
||
var myModal = new bootstrap.Modal(document.getElementById('internal_mail_modal'));
|
||
myModal.show();
|
||
|
||
// getMailContent('internal_mail_content');
|
||
|
||
} else if (mail_type == 3) {
|
||
|
||
placementMailPopUp()
|
||
// getMailContent('placement_mail_content');
|
||
|
||
}
|
||
|
||
}
|
||
|
||
function insurerAndClientMailPopUp() {
|
||
|
||
var url = '';
|
||
var lead_id = $('#lead_id').val();
|
||
|
||
if (rfq_or_qcr == 2) {
|
||
$('#myCenterModalLabel').text('Client contact to send mail')
|
||
url = '<?= base_url('leads/list/') ?>' + lead_id;
|
||
} else {
|
||
$('#myCenterModalLabel').text('Choose insurer to send mail')
|
||
url = '<?= base_url('util/getLevelContects') ?>'
|
||
}
|
||
|
||
ajaxRequestForGetMailData(url);
|
||
|
||
var myModal = new bootstrap.Modal(document.getElementById('list_model'));
|
||
myModal.show();
|
||
}
|
||
|
||
function placementMailPopUp() {
|
||
|
||
// // console.log(proposalDataForDropDown);
|
||
|
||
const selectElement = document.getElementById('proposals');
|
||
|
||
// Clear existing options
|
||
selectElement.innerHTML = '<option value="">Select Proposals</option>';
|
||
|
||
// Loop through the proposal data and append options
|
||
for (const [proposalKey, proposalValue] of Object.entries(proposalDataForDropDown.over_all_column_data)) {
|
||
proposalValue.insurers.forEach(insurer => {
|
||
const option = document.createElement('option');
|
||
option.value = insurer.id;
|
||
option.setAttribute("data-id", `${proposalKey}-${insurer.display_name}`);
|
||
option.textContent = `${proposalKey} - ${insurer.display_name}`;
|
||
selectElement.appendChild(option);
|
||
});
|
||
}
|
||
|
||
// Show the modal
|
||
const myModal = new bootstrap.Modal(document.getElementById('placement_mail_modal'));
|
||
myModal.show();
|
||
}
|
||
|
||
function ajaxRequestForGetMailData(url) {
|
||
|
||
// // console.log(url);
|
||
|
||
$('.loader').fadeIn();
|
||
$('.loader-mask').fadeIn();
|
||
|
||
$.ajax({
|
||
url: url,
|
||
type: "GET",
|
||
dataType: 'json',
|
||
success: function(res) {
|
||
$('.loader').fadeOut();
|
||
$('.loader-mask').delay(350).fadeOut('slow');
|
||
appendInput(res.data)
|
||
},
|
||
error: function(xhr, status, error) {
|
||
$('.loader').fadeOut();
|
||
$('.loader-mask').delay(350).fadeOut('slow');
|
||
// console.error(xhr.responseText);
|
||
// console.error(status, error);
|
||
}
|
||
});
|
||
}
|
||
|
||
function appendInput(data) {
|
||
|
||
// // console.log(data);
|
||
var lead_id = $('#lead_id').val();
|
||
$('#input_for_row').empty();
|
||
let html = '';
|
||
|
||
if (rfq_or_qcr == 2) {
|
||
|
||
const url = '<?= base_url('leads/list') ?>?lead_id=' + lead_id;
|
||
|
||
html += `
|
||
<div class="form-group col-md-4">
|
||
<label for="contact_mail">Client Contact Mail</label>
|
||
<input value="${data.contact_person_email || ''}" type="text" id="contact_mail" class="form-control" placeholder="Contact Mail" readonly>
|
||
</div>
|
||
`;
|
||
|
||
if (!data.contact_person_email) {
|
||
html += `
|
||
<div class="form-group col-md-4">
|
||
<a href="${url}">Click here to update mail ID</a>
|
||
</div>
|
||
`;
|
||
}
|
||
|
||
if (user_role_id == 1 || user_role_id == 5) {
|
||
|
||
html += `
|
||
|
||
<div class="form-group col-md-4">
|
||
<label for="client_cc">CC </label>
|
||
<select class="form-control" id="client_cc" name="client_cc" required multiple>
|
||
<?php if (isset($userList)) { ?>
|
||
<?php foreach ($userList as $user) { ?>
|
||
<option value="<?= $user['id']; ?>">
|
||
<?= $user['first_name'] . ' - ' . $user['email']; ?>
|
||
</option>
|
||
<?php } ?>
|
||
<?php } ?>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="form-group col-md-4">
|
||
<label for="client_bcc">BCC </label>
|
||
<select class="form-control" id="client_bcc" name="client_bcc" required multiple>
|
||
<?php if (isset($userList)) { ?>
|
||
<?php foreach ($userList as $user) { ?>
|
||
<option value="<?= $user['id']; ?>">
|
||
<?= $user['first_name'] . ' - ' . $user['email']; ?>
|
||
</option>
|
||
<?php } ?>
|
||
<?php } ?>
|
||
</select>
|
||
</div>
|
||
`;
|
||
|
||
}
|
||
|
||
html += `
|
||
<div class="form-group col-md-12">
|
||
<label for="mail_subject">Subject</label>
|
||
<input type="text" id="mail_subject" class="form-control" value="'<?= isset($subject) ? $subject : " " ?>'" placeholder="Subject">
|
||
</div>
|
||
`;
|
||
|
||
} else {
|
||
// Assuming `data.contacts` is an array of contact objects within the main data object
|
||
const contacts = data || {};
|
||
|
||
html = `
|
||
<div class="form-group col-md-4">
|
||
<label for="insurerContact">Insurers</label>
|
||
<select id="insurerContact" class="form-control" name="insurerContact[]" multiple>
|
||
<option></option>
|
||
`;
|
||
|
||
// Loop through each contact property within the `contacts` object
|
||
for (const id in contacts) {
|
||
const contact = contacts[id];
|
||
html += `
|
||
<option value="${contact.id}">${contact.insurer_name} - ${contact.branch_code} - ${contact.contact_person_name} - ${contact.contact_person_email}</option>
|
||
`;
|
||
}
|
||
|
||
html += `
|
||
</select>
|
||
</div>
|
||
`;
|
||
|
||
html += `
|
||
|
||
<div class="form-group col-md-4">
|
||
<label for="client_cc">CC </label>
|
||
<select class="form-control" id="client_cc" name="client_cc" required multiple>
|
||
<?php if (isset($userList)) { ?>
|
||
<?php foreach ($userList as $user) { ?>
|
||
<option value="<?= $user['id']; ?>">
|
||
<?= $user['first_name'] . ' - ' . $user['email']; ?>
|
||
</option>
|
||
<?php } ?>
|
||
<?php } ?>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="form-group col-md-4">
|
||
<label for="client_bcc">BCC </label>
|
||
<select class="form-control" id="client_bcc" name="client_bcc" required multiple>
|
||
<?php if (isset($userList)) { ?>
|
||
<?php foreach ($userList as $user) { ?>
|
||
<option value="<?= $user['id']; ?>">
|
||
<?= $user['first_name'] . ' - ' . $user['email']; ?>
|
||
</option>
|
||
<?php } ?>
|
||
<?php } ?>
|
||
</select>
|
||
</div>
|
||
`;
|
||
|
||
html += `
|
||
<div class="form-group col-md-12">
|
||
<label for="mail_subject">Subject</label>
|
||
<input value="<?= isset($subject) ? $subject : " " ?>" type="text" id="mail_subject" class="form-control" placeholder="Subject">
|
||
</div>
|
||
`;
|
||
|
||
}
|
||
|
||
html += `
|
||
<div class="form-group col-md-12">
|
||
<label for="insurer_and_client_mail_content">Mail Content</label>
|
||
<textarea id="insurer_and_client_mail_content" class="form-control" name="insurer_and_client_mail_content" rows="3"><?= isset($mail_content) ? $mail_content : " " ?></textarea>
|
||
</div>
|
||
`;
|
||
|
||
$('#input_for_row').append(html);
|
||
|
||
// Initialize select2 for the dropdown if insurerContact is present
|
||
if ($('#insurerContact').length) {
|
||
|
||
$('#insurerContact').select2({
|
||
placeholder: 'Select an Insurer',
|
||
});
|
||
|
||
$("textarea.select2-search__field").attr('rows', '1');
|
||
$("textarea.select2-search__field").css('resize', 'none');
|
||
}
|
||
|
||
// Initialize select2 for the dropdown if Client is present
|
||
if ($('#client_cc').length) {
|
||
|
||
$('#client_cc').select2({
|
||
placeholder: 'Select an CC',
|
||
});
|
||
|
||
$('#client_bcc').select2({
|
||
placeholder: 'Select an BCC',
|
||
});
|
||
|
||
$("textarea.select2-search__field").attr('rows', '1');
|
||
$("textarea.select2-search__field").css('resize', 'none');
|
||
}
|
||
|
||
// Initialize the Jodit editor
|
||
const editor = Jodit.make("#insurer_and_client_mail_content", editorConfig);
|
||
|
||
// getMailContent('insurer_and_client_mail_content');
|
||
|
||
}
|
||
|
||
function constructURL(url_type) {
|
||
|
||
if (url_type == 1) {
|
||
constructURL_ForInsurerAndClientMailSend()
|
||
} else if (url_type == 2) {
|
||
constructURL_ForInternalMailSend()
|
||
} else if (url_type == 3) {
|
||
|
||
Swal.fire({
|
||
title: "Do you want to place the proposal data?",
|
||
// text: "Do you want Save this!",
|
||
icon: "warning",
|
||
showCancelButton: true,
|
||
confirmButtonColor: "#3085d6",
|
||
cancelButtonColor: "#d33",
|
||
confirmButtonText: "Yes, Procced!"
|
||
}).then((result) => {
|
||
if (result.isConfirmed) {
|
||
constructURL_ForPlacementMailSend()
|
||
} else {
|
||
return false;
|
||
}
|
||
});
|
||
}
|
||
}
|
||
|
||
// Insurer and Client Mail
|
||
function constructURL_ForInsurerAndClientMailSend() {
|
||
|
||
var lead_id = $('#lead_id').val();
|
||
var mail_content = $('#insurer_and_client_mail_content').val();
|
||
var subject = $('#mail_subject').val();
|
||
var bcc = $('#client_bcc').val();
|
||
var cc = $('#client_cc').val();
|
||
|
||
// // console.log('lead_id', lead_id)
|
||
// // console.log('subject', subject)
|
||
// // console.log('mail_content', mail_content)
|
||
// // console.log('bcc', bcc)
|
||
// // console.log('cc', cc)
|
||
|
||
// Convert cc to JSON string
|
||
cc = cc.map(Number);
|
||
cc = JSON.stringify(cc);
|
||
|
||
// Convert bcc to JSON string
|
||
bcc = bcc.map(Number);
|
||
bcc = JSON.stringify(bcc);
|
||
|
||
var selectedFiles = [];
|
||
$('#insurer_or_clinet_mail_attachment .multi_file_attachment:checked').each(function () {
|
||
selectedFiles.push($(this).val());
|
||
});
|
||
|
||
// Prepare FormData object
|
||
var formData = new FormData();
|
||
formData.append('lead_id', lead_id);
|
||
formData.append('mail_content', mail_content);
|
||
formData.append('subject', subject);
|
||
formData.append('cc', cc);
|
||
formData.append('bcc', bcc);
|
||
formData.append('selected_attachment_files', JSON.stringify(selectedFiles));
|
||
|
||
|
||
if (rfq_or_qcr == 2) {
|
||
formData.append('file_type', 'qcr');
|
||
formData.append('recipient_type', 'client');
|
||
formData.append('recipient_mail', '');
|
||
} else {
|
||
var insurerContact = $('#insurerContact').val();
|
||
insurerContact = insurerContact.map(Number);
|
||
formData.append('file_type', 'rfq');
|
||
formData.append('recipient_type', 'insurer');
|
||
formData.append('recipient_mail', JSON.stringify(insurerContact));
|
||
}
|
||
|
||
ajaxRequest(formData)
|
||
// // console.log('formData', formData)
|
||
|
||
}
|
||
|
||
//Internal Mail
|
||
function constructURL_ForInternalMailSend() {
|
||
|
||
var lead_id = $('#lead_id').val();
|
||
let to = $('#to').val();
|
||
let mail_content = $('#internal_mail_content').val();
|
||
let subject = $('#subject').val();
|
||
let cc = $('#cc').val();
|
||
|
||
// Convert cc to JSON string
|
||
cc = cc.map(Number);
|
||
cc = JSON.stringify(cc);
|
||
|
||
// Determine file type
|
||
var file_type = rfq_or_qcr == 2 ? 'qcr' : 'rfq';
|
||
|
||
var selectedFiles = [];
|
||
$('#internal_mail_attachment .multi_file_attachment:checked').each(function () {
|
||
selectedFiles.push($(this).val());
|
||
});
|
||
|
||
|
||
// Create FormData
|
||
var formData = new FormData();
|
||
formData.append('lead_id', lead_id);
|
||
formData.append('file_type', file_type);
|
||
formData.append('recipient_type', 'internal');
|
||
formData.append('to', to);
|
||
formData.append('cc', cc);
|
||
formData.append('subject', subject);
|
||
formData.append('mail_content', mail_content);
|
||
formData.append('recipient_mail', ''); // Empty value as per logic
|
||
formData.append('selected_attachment_files', JSON.stringify(selectedFiles));
|
||
|
||
|
||
ajaxRequest(formData)
|
||
|
||
}
|
||
|
||
//placement mail
|
||
function constructURL_ForPlacementMailSend() {
|
||
|
||
var lead_id = $('#lead_id').val();
|
||
let to = $('#placement_to').val();
|
||
let placement_date = $('#placement_date').val();
|
||
let utr_no = $('#utr_no').val();
|
||
let premium_amount = $('#premium_amount').val();
|
||
let total_amount = $('#total_amount').val();
|
||
let cd_amount = $('#cd_amount').val();
|
||
let subject = $('#placement_subject').val();
|
||
let mail_content = $('#placement_mail_content').val();
|
||
let proposal_insurer = $('#proposals option:selected').data('id');
|
||
let insurer_and_branch = $('#proposals').val();
|
||
let cc = $('#placement_cc').val();
|
||
|
||
// Process `to` field
|
||
to = to.split(',').map(email => email.trim());
|
||
cc = cc.map(Number); // or split if it's a string: `cc.split(',').map(email => email.trim())`
|
||
|
||
|
||
var selectedFiles = [];
|
||
$('#placement_mail_attachment .multi_file_attachment:checked').each(function () {
|
||
selectedFiles.push($(this).val());
|
||
});
|
||
|
||
|
||
// Prepare FormData
|
||
var formData = new FormData();
|
||
formData.append('lead_id', lead_id);
|
||
formData.append('file_type', rfq_or_qcr == 2 ? 'qcr' : 'rfq');
|
||
formData.append('recipient_type', 'placement');
|
||
formData.append('recipient_mail', JSON.stringify(to));
|
||
formData.append('cc', JSON.stringify(cc));
|
||
formData.append('subject', subject);
|
||
formData.append('proposal_insurer', proposal_insurer);
|
||
formData.append('insurer_and_branch', insurer_and_branch);
|
||
formData.append('placement_date', placement_date);
|
||
formData.append('utr_no', utr_no);
|
||
formData.append('premium_amount', premium_amount);
|
||
formData.append('total_amount', total_amount);
|
||
formData.append('cd_amount', cd_amount);
|
||
formData.append('mail_content', mail_content);
|
||
formData.append('selected_attachment_files', JSON.stringify(selectedFiles));
|
||
|
||
|
||
ajaxRequest(formData);
|
||
|
||
}
|
||
|
||
|
||
function ajaxRequest(formData) {
|
||
|
||
var apiURL = '<?= base_url('leads/sendMail') ?>';
|
||
// // console.log(apiURL);
|
||
|
||
$('.loader').fadeIn();
|
||
$('.loader-mask').fadeIn();
|
||
|
||
$.ajax({
|
||
url: apiURL,
|
||
type: "POST",
|
||
data: formData,
|
||
processData: false, // Required for FormData
|
||
contentType: false, // Required for FormData
|
||
dataType: 'json',
|
||
success: function(res) {
|
||
|
||
$('.loader').fadeOut();
|
||
$('.loader-mask').delay(350).fadeOut('slow');
|
||
|
||
// // console.log(res);
|
||
if (res.status == 'success' && res.code == 200) {
|
||
toastr.success('Mail send Successfully', 'SUCCESS')
|
||
} else {
|
||
if (res.messgae) {
|
||
toastr.error(res.messgae, 'ERROR')
|
||
} else {
|
||
toastr.error('Mail send failed', 'ERROR')
|
||
}
|
||
}
|
||
|
||
$('.close').click()
|
||
},
|
||
error: function(xhr, status, error) {
|
||
|
||
$('.loader').fadeOut();
|
||
$('.loader-mask').delay(350).fadeOut('slow');
|
||
|
||
// console.error(xhr.responseText);
|
||
// console.error(status, error);
|
||
}
|
||
});
|
||
|
||
$('#to').select2({
|
||
placeholder: 'Select To Mail',
|
||
});
|
||
$('#cc').val('').select2({
|
||
placeholder: 'select CC Mail'
|
||
});
|
||
// $('#subject').val('');
|
||
$('#proposals').val('');
|
||
$('#placement_to').val('').select2({
|
||
placeholder: 'select To Mail'
|
||
});
|
||
$('#placement_cc').val('').select2({
|
||
placeholder: 'select CC Mail'
|
||
});
|
||
$('#placement_subject').val('');
|
||
|
||
$("textarea.select2-search__field").attr('rows', '1');
|
||
$("textarea.select2-search__field").css('resize', 'none');
|
||
}
|
||
|
||
function objectToQueryString(obj) {
|
||
return Object.keys(obj).map(key => `${encodeURIComponent(key)}=${encodeURIComponent(obj[key])}`).join('&');
|
||
}
|
||
|
||
function getInsurerBranchContacts(input) {
|
||
|
||
let insurer_and_branch = $(input).val();
|
||
// // console.log('insurer_and_branch', insurer_and_branch);
|
||
|
||
$('.loader').fadeIn();
|
||
$('.loader-mask').fadeIn();
|
||
|
||
$.ajax({
|
||
url: '<?= base_url('util/getInsurerBranchContacts/') ?>' + insurer_and_branch,
|
||
type: "GET",
|
||
dataType: 'json',
|
||
success: function(res) {
|
||
// // console.log(res)
|
||
$('.loader').fadeOut();
|
||
$('.loader-mask').delay(350).fadeOut('slow');
|
||
if (res.status == false) {
|
||
toastr.warning(res.message, 'WARNING')
|
||
} else {
|
||
appendInsurerContact(res.data)
|
||
}
|
||
},
|
||
error: function(xhr, status, error) {
|
||
$('.loader').fadeOut();
|
||
$('.loader-mask').delay(350).fadeOut('slow');
|
||
// console.error(xhr.responseText);
|
||
// console.error(status, error);
|
||
}
|
||
});
|
||
}
|
||
|
||
function appendInsurerContact(data) {
|
||
|
||
// // console.log(data)
|
||
|
||
$('#placement_to').empty();
|
||
$('#placement_to').append($('<option>', {
|
||
value: '',
|
||
text: 'Select'
|
||
}));
|
||
|
||
$.each(data, function(index, item) {
|
||
var option = $('<option>', {
|
||
value: item.id,
|
||
text: item.contact_person_email
|
||
});
|
||
$('#placement_to').append(option);
|
||
});
|
||
}
|
||
|
||
$('.close').click(function() {
|
||
|
||
$('#to').select2({
|
||
placeholder: 'Select To Mail',
|
||
});
|
||
|
||
$('#cc').val('').select2({
|
||
placeholder: 'select CC Mail'
|
||
});
|
||
// $('#subject').val('');
|
||
$('#proposals').val('');
|
||
$('#placement_to').val('').select2({
|
||
placeholder: 'select To Mail'
|
||
});
|
||
$('#placement_cc').val('').select2({
|
||
placeholder: 'select CC Mail'
|
||
});
|
||
$('#placement_subject').val('');
|
||
|
||
$("textarea.select2-search__field").attr('rows', '1');
|
||
$("textarea.select2-search__field").css('resize', 'none');
|
||
})
|
||
|
||
|
||
function addOrRemoveIconInsurer(element, event) {
|
||
event.stopPropagation(); // Prevent event bubbling
|
||
|
||
// Find the button inside the dropdown (or use `element` directly)
|
||
const stcButton = element.closest('.dropdown-content') ?
|
||
element.closest('.dropdown-content').querySelector('.sendInsurerClientProposal') :
|
||
element;
|
||
|
||
// Check if the icon already exists
|
||
let icon = stcButton.querySelector("i.fa-check-square");
|
||
|
||
if (icon) {
|
||
// Remove the icon if it already exists
|
||
icon.remove();
|
||
} else {
|
||
// Create and append the check icon
|
||
createIcon(stcButton);
|
||
}
|
||
}
|
||
</script>
|