FIX_OPPOERUTIES_ISSUES
This commit is contained in:
parent
998b949c04
commit
30e2377f1a
@ -463,19 +463,31 @@ class LeadsController extends BaseController
|
||||
// If an existing client is selected from the dropdown, `client_id` will be present.
|
||||
if (empty($postData['client_id'])) {
|
||||
$ignoreClientId = null;
|
||||
$lead = null;
|
||||
if ($id) { // This is an update of a lead
|
||||
$lead = $this->leadsModel->find($id);
|
||||
if ($lead && !empty($lead['is_client_created'])) {
|
||||
$ignoreClientId = $lead['is_client_created'];
|
||||
if ($lead && ! empty($lead['is_client_created'])) {
|
||||
$ignoreClientId = (int) $lead['is_client_created'];
|
||||
}
|
||||
}
|
||||
|
||||
$submittedName = trim((string) ($postData['client_name'] ?? ''));
|
||||
$submittedShort = trim((string) ($postData['client_short_name'] ?? ''));
|
||||
$nameUnchanged = $lead && strcasecmp(trim((string) ($lead['client_name'] ?? '')), $submittedName) === 0;
|
||||
$shortUnchanged = $lead && strcasecmp(trim((string) ($lead['client_short_name'] ?? '')), $submittedShort) === 0;
|
||||
|
||||
if ($ignoreClientId) {
|
||||
$clientNameRules .= '|is_unique[clients.client_name,id,' . $ignoreClientId . ']';
|
||||
$clientShortNameRules .= '|is_unique[clients.short_name,id,' . $ignoreClientId . ']';
|
||||
} else {
|
||||
$clientNameRules .= '|is_unique[clients.client_name]';
|
||||
$clientShortNameRules .= '|is_unique[clients.short_name]';
|
||||
// On edit, unchanged names belong to this opportunity — do not treat as duplicates.
|
||||
// (Client row may already exist even when is_client_created is unset.)
|
||||
if (! $nameUnchanged) {
|
||||
$clientNameRules .= '|is_unique[clients.client_name]';
|
||||
}
|
||||
if (! $shortUnchanged) {
|
||||
$clientShortNameRules .= '|is_unique[clients.short_name]';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -768,6 +780,15 @@ class LeadsController extends BaseController
|
||||
$data['client_id'] = 0;
|
||||
$data['client_branch_id'] = 0;
|
||||
$data['source_policy_id'] = 0;
|
||||
|
||||
// Keep existing client link on update when "Existing Client" is off.
|
||||
// Otherwise is_client_created is wiped to null and later edits fail uniqueness checks.
|
||||
if (! empty($data['id'])) {
|
||||
$existingLead = $this->leadsModel->find($data['id']);
|
||||
if ($existingLead && ! empty($existingLead['is_client_created'])) {
|
||||
$data['is_client_created'] = $existingLead['is_client_created'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4168,7 +4189,7 @@ class LeadsController extends BaseController
|
||||
$data = $this->leadsModel->where('leads.id', $lead_id)->where('leads.is_active', 1)->first();
|
||||
|
||||
if (! $data) {
|
||||
$this->myLogger->logme('featchLeadDataAndInsertClient', "Lead not found or inactive", ['lead_id' => $lead_id]);
|
||||
$this->myLogger->logme('error', 'featchLeadDataAndInsertClient: Lead not found or inactive', ['lead_id' => $lead_id]);
|
||||
return $this->respond(['status' => false, 'message' => 'Failed to create Client', 'data' => null], 200);
|
||||
}
|
||||
|
||||
@ -4186,10 +4207,10 @@ class LeadsController extends BaseController
|
||||
], 200);
|
||||
}
|
||||
|
||||
$this->myLogger->logme('featchLeadDataAndInsertClient', "Client creation failed after processing", ['lead_id' => $lead_id]);
|
||||
$this->myLogger->logme('error', 'featchLeadDataAndInsertClient: Client creation failed after processing', ['lead_id' => $lead_id]);
|
||||
return $this->respond(['status' => false, 'message' => 'Failed to create client', 'data' => $data], 200);
|
||||
} catch (\Throwable $e) {
|
||||
$this->myLogger->logme('error', 'featchLeadDataAndInsertClient failed');
|
||||
$this->myLogger->logme('error', 'featchLeadDataAndInsertClient failed: ' . $e->getMessage());
|
||||
return $this->respond(['status' => false, 'message' => 'Internal server error', 'error' => $e->getMessage()], 500);
|
||||
}
|
||||
}
|
||||
@ -4210,17 +4231,40 @@ class LeadsController extends BaseController
|
||||
return false;
|
||||
}
|
||||
|
||||
$client_id = $this->clientModel->insert($this->prepareClientData($data));
|
||||
if (! $client_id) {
|
||||
return false;
|
||||
}
|
||||
// Reuse client/branch from a previous partial attempt (client created, policy failed).
|
||||
$existingClientId = (int) ($data['is_client_created'] ?? 0);
|
||||
if ($existingClientId > 0) {
|
||||
$client_id = $existingClientId;
|
||||
|
||||
$branch_id = $this->clientBranchModel->insert($this->prepareClientBranchData($data, $client_id));
|
||||
if (! $branch_id) {
|
||||
return false;
|
||||
}
|
||||
$existingBranch = $this->clientBranchModel
|
||||
->where('client_id', $client_id)
|
||||
->where('branch_name', $data['branch_name'] ?? null)
|
||||
->where('branch_code', $data['branch_code'] ?? null)
|
||||
->where('is_active', 1)
|
||||
->first();
|
||||
|
||||
$this->levelContactModel->insert($this->prepareContactData($data, $branch_id));
|
||||
if ($existingBranch) {
|
||||
$branch_id = (int) $existingBranch['id'];
|
||||
} else {
|
||||
$branch_id = $this->clientBranchModel->insert($this->prepareClientBranchData($data, $client_id));
|
||||
if (! $branch_id) {
|
||||
return false;
|
||||
}
|
||||
$this->levelContactModel->insert($this->prepareContactData($data, $branch_id));
|
||||
}
|
||||
} else {
|
||||
$client_id = $this->clientModel->insert($this->prepareClientData($data));
|
||||
if (! $client_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$branch_id = $this->clientBranchModel->insert($this->prepareClientBranchData($data, $client_id));
|
||||
if (! $branch_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->levelContactModel->insert($this->prepareContactData($data, $branch_id));
|
||||
}
|
||||
|
||||
$policy_ids = [];
|
||||
$lead_ids = [];
|
||||
@ -4258,7 +4302,7 @@ class LeadsController extends BaseController
|
||||
'lead_ids' => $lead_ids,
|
||||
];
|
||||
} catch (\Throwable $e) {
|
||||
$this->myLogger->logme('error', 'createClientWithMatchingLeadsPolicies failed');
|
||||
$this->myLogger->logme('error', 'createClientWithMatchingLeadsPolicies failed: ' . $e->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -4349,7 +4393,7 @@ class LeadsController extends BaseController
|
||||
|
||||
return $client_policy_id;
|
||||
} catch (\Throwable $e) {
|
||||
$this->myLogger->logme('error', 'createClientPolicyWithLeadData failed');
|
||||
$this->myLogger->logme('error', 'createClientPolicyWithLeadData failed: ' . $e->getMessage() . ' at ' . $e->getFile() . ':' . $e->getLine());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -4607,9 +4651,20 @@ class LeadsController extends BaseController
|
||||
//Function for convert the RFQ and QCR Json to Policy Terms Json
|
||||
public function convertQCRJsonToPolicyTerms($data, $policy_type, $proposel_name, $insurer_name)
|
||||
{
|
||||
// Extract special conditions from original QCR data first.
|
||||
// transformProposelData drops the Quote Asked column, which is the label source.
|
||||
$specialConditionTerms = $this->extractSpecialConditionsFromQCR(
|
||||
$data,
|
||||
$policy_type,
|
||||
$proposel_name,
|
||||
$insurer_name
|
||||
);
|
||||
|
||||
//transform the data into the currernt proposel and insurere ( get single proposel )
|
||||
$data = $this->transformProposelData($data, $proposel_name, $insurer_name);
|
||||
|
||||
$terms_array = $specialConditionTerms;
|
||||
|
||||
// Initialize age_ratio based on policy type
|
||||
$age_ratio = $policy_type == 2 ? [
|
||||
'self' => ['min' => '18', 'max' => '60'],
|
||||
@ -4641,21 +4696,14 @@ class LeadsController extends BaseController
|
||||
continue;
|
||||
}
|
||||
|
||||
// Special conditions already extracted above.
|
||||
if (str_starts_with((string) $item, 'special_condition')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (true) {
|
||||
|
||||
// CASE 1: Handle special conditions
|
||||
case str_starts_with($item, 'special_condition') && $parentth === $proposel_name && $subth === $insurer_name:
|
||||
// log_message("error","INPUT".json_encode($input_value));
|
||||
$parts = explode('-', $input_value);
|
||||
|
||||
$labelKey = $policy_type == 1 ? 'gpa_special_condition_label' : 'special_condition_label';
|
||||
$inputKey = $policy_type == 1 ? 'gpa_special_condition_input' : 'special_condition_input';
|
||||
|
||||
$terms_array[$labelKey][] = $parts[0] ?? '';
|
||||
$terms_array[$inputKey][] = $parts[1] ?? '';
|
||||
break;
|
||||
|
||||
// CASE 2: Handle sum insured
|
||||
// CASE 1: Handle sum insured
|
||||
case in_array($item, ['sum_insured', 'sumInsured2']):
|
||||
$si_amt = explode(',', $value);
|
||||
$terms_array[$item] = $si_amt[0] ?? '';
|
||||
@ -4668,7 +4716,7 @@ class LeadsController extends BaseController
|
||||
|
||||
break;
|
||||
|
||||
// CASE 3: Handle family floaters
|
||||
// CASE 2: Handle family floaters
|
||||
case $item === 'family_composition':
|
||||
$terms_array['family_floaters'] = isJsonString($input_value) ? json_decode($input_value, true) : $input_value;
|
||||
|
||||
@ -4691,6 +4739,138 @@ class LeadsController extends BaseController
|
||||
return json_encode($terms_array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build special_condition_label/input arrays from QCR rows.
|
||||
*
|
||||
* Mapping:
|
||||
* - Canonical RFQ hidden format "label--value" (or display "label - value") on insurer cell
|
||||
* - Otherwise Quote Asked = label, insurer cell = value
|
||||
*
|
||||
* @return array<string, list<string>>
|
||||
*/
|
||||
private function extractSpecialConditionsFromQCR($data, $policy_type, $proposel_name, $insurer_name): array
|
||||
{
|
||||
$labelKey = $policy_type == 1 ? 'gpa_special_condition_label' : 'special_condition_label';
|
||||
$inputKey = $policy_type == 1 ? 'gpa_special_condition_input' : 'special_condition_input';
|
||||
$result = [
|
||||
$labelKey => [],
|
||||
$inputKey => [],
|
||||
];
|
||||
|
||||
if (empty($data['table_data']['data']) || ! is_array($data['table_data']['data'])) {
|
||||
return [];
|
||||
}
|
||||
|
||||
foreach ($data['table_data']['data'] as $dataRow) {
|
||||
$item = $dataRow['items'] ?? '';
|
||||
if (! str_starts_with((string) $item, 'special_condition')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$quoteAsked = '';
|
||||
$insurerDisplay = '';
|
||||
$insurerInput = '';
|
||||
|
||||
foreach ($dataRow['data'] ?? [] as $cellData) {
|
||||
$parentth = $cellData['parentth'] ?? '';
|
||||
$subth = $cellData['subth'] ?? '';
|
||||
|
||||
if ($parentth !== $proposel_name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$cellInput = isset($cellData['input_value']) && $cellData['input_value'] !== ''
|
||||
? $cellData['input_value']
|
||||
: ($cellData['value'] ?? '');
|
||||
$cellValue = $cellData['value'] ?? '';
|
||||
|
||||
if ($subth === 'Quote Asked') {
|
||||
$quoteAsked = $this->normalizeSpecialConditionCellText($cellValue, $cellInput);
|
||||
}
|
||||
|
||||
if ($subth === $insurer_name) {
|
||||
$insurerDisplay = is_string($cellValue) ? trim($cellValue) : '';
|
||||
$insurerInput = is_string($cellInput) ? trim((string) $cellInput) : '';
|
||||
}
|
||||
}
|
||||
|
||||
[$label, $input] = $this->parseSpecialConditionParts($insurerInput, $insurerDisplay, $quoteAsked);
|
||||
|
||||
if ($label === '' && $input === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$result[$labelKey][] = $label;
|
||||
$result[$inputKey][] = $input;
|
||||
}
|
||||
|
||||
if ($result[$labelKey] === [] && $result[$inputKey] === []) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefer visible cell text; fall back to hidden input_value.
|
||||
*/
|
||||
private function normalizeSpecialConditionCellText($display_value, $input_value): string
|
||||
{
|
||||
$display = is_string($display_value) ? trim($display_value) : '';
|
||||
if ($display !== '') {
|
||||
return $display;
|
||||
}
|
||||
|
||||
return is_string($input_value) ? trim($input_value) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse RFQ/QCR special-condition cells into [label, value].
|
||||
*
|
||||
* @return array{0: string, 1: string}
|
||||
*/
|
||||
private function parseSpecialConditionParts($input_value, $display_value = '', $quote_asked = ''): array
|
||||
{
|
||||
// Prefer canonical hidden "label--value"; otherwise prefer visible insurer text
|
||||
// (QCR edits often update the cell text but leave the hidden input stale/empty).
|
||||
$raw = '';
|
||||
if (is_string($input_value) && str_contains($input_value, '--')) {
|
||||
$raw = trim($input_value);
|
||||
} elseif (is_string($display_value) && trim($display_value) !== '') {
|
||||
$raw = trim($display_value);
|
||||
} elseif (is_string($input_value)) {
|
||||
$raw = trim($input_value);
|
||||
}
|
||||
|
||||
$quoteAsked = is_string($quote_asked) ? trim($quote_asked) : '';
|
||||
|
||||
if ($raw === '' && $quoteAsked === '') {
|
||||
return ['', ''];
|
||||
}
|
||||
|
||||
if ($raw !== '' && str_contains($raw, '--')) {
|
||||
$parts = explode('--', $raw, 2);
|
||||
return [trim($parts[0] ?? ''), trim($parts[1] ?? '')];
|
||||
}
|
||||
|
||||
if ($raw !== '' && str_contains($raw, ' - ')) {
|
||||
$parts = explode(' - ', $raw, 2);
|
||||
return [trim($parts[0] ?? ''), trim($parts[1] ?? '')];
|
||||
}
|
||||
|
||||
// QCR columns: Quote Asked = label, insurer response = value
|
||||
if ($quoteAsked !== '' && $raw !== '') {
|
||||
return [$quoteAsked, $raw];
|
||||
}
|
||||
|
||||
if ($quoteAsked !== '') {
|
||||
return [$quoteAsked, $quoteAsked];
|
||||
}
|
||||
|
||||
// Single insurer cell with no Quote Asked / separator: use as label and value
|
||||
return [$raw, $raw];
|
||||
}
|
||||
|
||||
public function convertNonEbQCRJsonToPolicyTerms($allTableData)
|
||||
{
|
||||
|
||||
@ -4747,6 +4927,14 @@ class LeadsController extends BaseController
|
||||
public function getPlacementJson(array $data): ?string
|
||||
{
|
||||
$proposel_data = json_decode($data['proposel_data'] ?? '', true) ?? [];
|
||||
$proposelName = $proposel_data['proposel_name'] ?? '';
|
||||
$insurerName = $proposel_data['insurer_name'] ?? '';
|
||||
|
||||
// Non-EB placement JSON is filtered by the won proposal/insurer selection.
|
||||
// Without that selection, skip placement terms rather than throwing.
|
||||
if ($proposelName === '' || $insurerName === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
$QCRData = $this->RFQModel
|
||||
->where('is_active', 1)
|
||||
@ -4764,26 +4952,26 @@ class LeadsController extends BaseController
|
||||
return null;
|
||||
}
|
||||
|
||||
$placement_json_data = array_map(function ($jsonData) use ($proposel_data) {
|
||||
$placement_json_data = array_map(function ($jsonData) use ($proposelName, $insurerName) {
|
||||
return $this->transformNonEbProposelData(
|
||||
$jsonData,
|
||||
$proposel_data['proposel_name'] ?? '',
|
||||
$proposel_data['insurer_name'] ?? '',
|
||||
$proposelName,
|
||||
$insurerName,
|
||||
null,
|
||||
1
|
||||
);
|
||||
}, $jsonArray);
|
||||
|
||||
if (! empty($proposalData)) {
|
||||
if (! empty($proposalData['proposal_data']['over_all_column_data']) && is_array($proposalData['proposal_data']['over_all_column_data'])) {
|
||||
foreach ($proposalData['proposal_data']['over_all_column_data'] as $key => &$proposal) {
|
||||
// Keep only the required proposal
|
||||
if ($key !== $proposel_data['proposel_name']) {
|
||||
if ($key !== $proposelName) {
|
||||
unset($proposalData['proposal_data']['over_all_column_data'][$key]);
|
||||
} else {
|
||||
// Within the matched proposal, filter insurers
|
||||
if (! empty($proposal['insurers'])) {
|
||||
$proposal['insurers'] = array_values(array_filter($proposal['insurers'], function ($insurer) use ($proposel_data) {
|
||||
return $insurer['display_name'] === $proposel_data['insurer_name'];
|
||||
$proposal['insurers'] = array_values(array_filter($proposal['insurers'], function ($insurer) use ($insurerName) {
|
||||
return ($insurer['display_name'] ?? null) === $insurerName;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -484,6 +484,12 @@
|
||||
max-width: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Keep Bootstrap modals visible above body backdrop (theme uses overflow:hidden on #wrapper) */
|
||||
body.modal-open #wrapper,
|
||||
body.modal-open .content-page {
|
||||
overflow: visible !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
@ -1150,7 +1156,79 @@
|
||||
placeholder: "Start typing here...", // Optional placeholder text
|
||||
};
|
||||
|
||||
var RFQ_MODAL_IDS = [
|
||||
'list_model',
|
||||
'internal_mail_modal',
|
||||
'placement_mail_modal',
|
||||
'view_demography_modal',
|
||||
'other_docs_upload_modal'
|
||||
];
|
||||
|
||||
function relocateRfqModalsToBody() {
|
||||
RFQ_MODAL_IDS.forEach(function (modalId) {
|
||||
var modalEl = document.getElementById(modalId);
|
||||
if (modalEl && modalEl.parentElement !== document.body) {
|
||||
document.body.appendChild(modalEl);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function clearOrphanedModalBackdrops() {
|
||||
document.querySelectorAll('.modal-backdrop').forEach(function (el) {
|
||||
el.remove();
|
||||
});
|
||||
document.body.classList.remove('modal-open');
|
||||
document.body.style.removeProperty('padding-right');
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a Bootstrap modal reliably on this page:
|
||||
* - moves it under <body> (escapes #wrapper overflow:hidden)
|
||||
* - prefers Bootstrap 4 window.bootstrap.Modal from vendor.min.js
|
||||
* - reuses one instance per element
|
||||
*/
|
||||
function openBootstrapModal(modalId) {
|
||||
var modalEl = document.getElementById(modalId);
|
||||
if (!modalEl) {
|
||||
console.error('Modal not found:', modalId);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (modalEl.parentElement !== document.body) {
|
||||
document.body.appendChild(modalEl);
|
||||
}
|
||||
|
||||
clearOrphanedModalBackdrops();
|
||||
|
||||
if (typeof bootstrap !== 'undefined' && bootstrap.Modal) {
|
||||
var existing = (typeof jQuery !== 'undefined') ? jQuery(modalEl).data('bs.modal') : null;
|
||||
if (existing && typeof existing.show === 'function') {
|
||||
existing.show();
|
||||
return existing;
|
||||
}
|
||||
var modal = new bootstrap.Modal(modalEl);
|
||||
if (typeof jQuery !== 'undefined') {
|
||||
jQuery(modalEl).data('bs.modal', modal);
|
||||
}
|
||||
modal.show();
|
||||
return modal;
|
||||
}
|
||||
|
||||
if (typeof jQuery !== 'undefined' && jQuery.fn && typeof jQuery.fn.modal === 'function') {
|
||||
jQuery(modalEl).modal('show');
|
||||
// BS3 uses .in while theme CSS expects .show
|
||||
modalEl.classList.add('show');
|
||||
modalEl.style.display = 'block';
|
||||
modalEl.removeAttribute('aria-hidden');
|
||||
return null;
|
||||
}
|
||||
|
||||
console.error('No compatible Bootstrap modal API found for', modalId);
|
||||
return null;
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
relocateRfqModalsToBody();
|
||||
|
||||
const path = window.location.pathname; // Get the current URL path
|
||||
const segments = path.split('/'); // Split the path into segments
|
||||
@ -4027,8 +4105,7 @@ function showModal(mail_type) {
|
||||
|
||||
}else if(mail_type == 2){
|
||||
|
||||
var myModal = new bootstrap.Modal(document.getElementById('internal_mail_modal'));
|
||||
myModal.show();
|
||||
openBootstrapModal('internal_mail_modal');
|
||||
|
||||
// getMailContent('internal_mail_content');
|
||||
|
||||
@ -4057,8 +4134,7 @@ function insurerAndClientMailPopUp(){
|
||||
|
||||
ajaxRequestForGetMailData(url);
|
||||
|
||||
var myModal = new bootstrap.Modal(document.getElementById('list_model'));
|
||||
myModal.show();
|
||||
openBootstrapModal('list_model');
|
||||
}
|
||||
|
||||
function placementMailPopUp() {
|
||||
@ -4093,8 +4169,7 @@ function placementMailPopUp() {
|
||||
}
|
||||
|
||||
// Show the modal
|
||||
const myModal = new bootstrap.Modal(document.getElementById('placement_mail_modal'));
|
||||
myModal.show();
|
||||
openBootstrapModal('placement_mail_modal');
|
||||
}
|
||||
|
||||
function ajaxRequestForGetMailData(url) {
|
||||
@ -7354,10 +7429,9 @@ function appendMultiFileData(data) {
|
||||
// }
|
||||
|
||||
function viewDocs(){
|
||||
// Show the modal
|
||||
const myModal = new bootstrap.Modal(document.getElementById('other_docs_upload_modal'));
|
||||
myModal.show();
|
||||
openBootstrapModal('other_docs_upload_modal');
|
||||
}
|
||||
window.viewDocs = viewDocs;
|
||||
|
||||
|
||||
</script>
|
||||
@ -7846,8 +7920,7 @@ function appendMultiFileData(data) {
|
||||
}
|
||||
|
||||
// Show the modal
|
||||
const myModal = new bootstrap.Modal(document.getElementById('view_demography_modal'));
|
||||
myModal.show();
|
||||
openBootstrapModal('view_demography_modal');
|
||||
|
||||
// Hide loader
|
||||
$('.loader').fadeOut();
|
||||
@ -7857,8 +7930,7 @@ function appendMultiFileData(data) {
|
||||
$('#demography_modal_body').append("<p style='text-align: center; color: #6c757d; font-style: italic;'>No Demography Data Found or Wrong File</p>")
|
||||
|
||||
// Show the modal
|
||||
const myModal = new bootstrap.Modal(document.getElementById('view_demography_modal'));
|
||||
myModal.show();
|
||||
openBootstrapModal('view_demography_modal');
|
||||
|
||||
console.error('Error fetching data:', error);
|
||||
console.error(xhr.responseText);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user