diff --git a/app/Controllers/Ipd_discharge.php b/app/Controllers/Ipd_discharge.php index bde0819..dec874d 100644 --- a/app/Controllers/Ipd_discharge.php +++ b/app/Controllers/Ipd_discharge.php @@ -6541,24 +6541,36 @@ class Ipd_discharge extends BaseController $remark = trim((string) ($this->request->getPost('new_surgery_remark') ?? '')); $masterId = max(0, (int) ($this->request->getPost('new_surgery_master_id') ?? 0)); if ($name !== '' && $this->tableHasColumns('ipd_discharge_surgery', ['ipd_id', 'surgery_name'])) { - $insert = [ - 'ipd_id' => $ipdId, - 'surgery_name' => $name, - 'surgery_remark' => $remark, - 'update_by' => $userLabel, - ]; - if ($this->db->fieldExists('surgery_date', 'ipd_discharge_surgery')) { - $insert['surgery_date'] = $date; + $dupQuery = $this->db->table('ipd_discharge_surgery') + ->where('ipd_id', $ipdId) + ->where('surgery_name', $name); + if ($date !== null && $this->db->fieldExists('surgery_date', 'ipd_discharge_surgery')) { + $dupQuery->where('surgery_date', $date); } - if ($this->db->fieldExists('surgery_id', 'ipd_discharge_surgery')) { - $insert['surgery_id'] = $masterId; + if ($dupQuery->countAllResults() > 0) { + $savedAny = false; + $notice = 'This surgery is already added.'; + $noticeType = 'warning'; + } else { + $insert = [ + 'ipd_id' => $ipdId, + 'surgery_name' => $name, + 'surgery_remark' => $remark, + 'update_by' => $userLabel, + ]; + if ($this->db->fieldExists('surgery_date', 'ipd_discharge_surgery')) { + $insert['surgery_date'] = $date; + } + if ($this->db->fieldExists('surgery_id', 'ipd_discharge_surgery')) { + $insert['surgery_id'] = $masterId; + } + if ($this->db->fieldExists('surgery_by_doc_id', 'ipd_discharge_surgery')) { + $insert['surgery_by_doc_id'] = 0; + } + $savedAny = (bool) $this->db->table('ipd_discharge_surgery')->insert($insert); + $notice = $savedAny ? 'Surgery row added.' : 'Unable to add surgery row.'; + $noticeType = $savedAny ? 'success' : 'warning'; } - if ($this->db->fieldExists('surgery_by_doc_id', 'ipd_discharge_surgery')) { - $insert['surgery_by_doc_id'] = 0; - } - $savedAny = (bool) $this->db->table('ipd_discharge_surgery')->insert($insert); - $notice = $savedAny ? 'Surgery row added.' : 'Unable to add surgery row.'; - $noticeType = $savedAny ? 'success' : 'warning'; } else { $notice = $name === '' ? 'Enter surgery name before adding.' @@ -6583,30 +6595,43 @@ class Ipd_discharge extends BaseController $date = $this->parseInputDateToDb((string) ($this->request->getPost('new_procedure_date') ?? '')); $remark = trim((string) ($this->request->getPost('new_procedure_remark') ?? '')); $masterId = max(0, (int) ($this->request->getPost('new_procedure_master_id') ?? 0)); - if ($name !== '' && $date !== null && $this->tableHasColumns('ipd_discharge_procedure', ['ipd_id', 'procedure_name'])) { - $insert = [ - 'ipd_id' => $ipdId, - 'procedure_name' => $name, - 'procedure_remark' => $remark, - 'update_by' => $userLabel, - ]; - if ($this->db->fieldExists('procedure_date', 'ipd_discharge_procedure')) { - $insert['procedure_date'] = $date; + if ($date === null) { + $date = date('Y-m-d'); + } + if ($name !== '' && $this->tableHasColumns('ipd_discharge_procedure', ['ipd_id', 'procedure_name'])) { + $dupQuery = $this->db->table('ipd_discharge_procedure') + ->where('ipd_id', $ipdId) + ->where('procedure_name', $name); + if ($date !== null && $this->db->fieldExists('procedure_date', 'ipd_discharge_procedure')) { + $dupQuery->where('procedure_date', $date); } - if ($this->db->fieldExists('procedure_id', 'ipd_discharge_procedure')) { - $insert['procedure_id'] = $masterId; + if ($dupQuery->countAllResults() > 0) { + $savedAny = false; + $notice = 'This procedure is already added.'; + $noticeType = 'warning'; + } else { + $insert = [ + 'ipd_id' => $ipdId, + 'procedure_name' => $name, + 'procedure_remark' => $remark, + 'update_by' => $userLabel, + ]; + if ($this->db->fieldExists('procedure_date', 'ipd_discharge_procedure')) { + $insert['procedure_date'] = $date; + } + if ($this->db->fieldExists('procedure_id', 'ipd_discharge_procedure')) { + $insert['procedure_id'] = $masterId; + } + if ($this->db->fieldExists('procedure_by_doc_id', 'ipd_discharge_procedure')) { + $insert['procedure_by_doc_id'] = 0; + } + $savedAny = (bool) $this->db->table('ipd_discharge_procedure')->insert($insert); + $notice = $savedAny ? 'Procedure row added.' : 'Unable to add procedure row.'; + $noticeType = $savedAny ? 'success' : 'warning'; } - if ($this->db->fieldExists('procedure_by_doc_id', 'ipd_discharge_procedure')) { - $insert['procedure_by_doc_id'] = 0; - } - $savedAny = (bool) $this->db->table('ipd_discharge_procedure')->insert($insert); - $notice = $savedAny ? 'Procedure row added.' : 'Unable to add procedure row.'; - $noticeType = $savedAny ? 'success' : 'warning'; } else { if ($name === '') { $notice = 'Enter procedure name before adding.'; - } elseif ($date === null) { - $notice = 'Select a valid procedure date before adding.'; } else { $notice = 'Procedure table/columns are missing in database.'; } diff --git a/app/Views/billing/ipd/discharge_create.php b/app/Views/billing/ipd/discharge_create.php index b3ab847..a89b918 100644 --- a/app/Views/billing/ipd/discharge_create.php +++ b/app/Views/billing/ipd/discharge_create.php @@ -1104,7 +1104,7 @@ $historyFields = [ - + @@ -1122,9 +1122,9 @@ $historyFields = [ -
-
-
+
+
+
@@ -3423,10 +3423,17 @@ $historyFields = [ e.preventDefault(); highlightedIndex = Math.max(highlightedIndex - 1, 0); updateHighlight(items); - } else if (e.key === 'Enter' && isVisible) { + } else if (e.key === 'Enter') { e.preventDefault(); - if (highlightedIndex >= 0 && items[highlightedIndex]) { + if (isVisible && highlightedIndex >= 0 && items[highlightedIndex]) { items[highlightedIndex].click(); + } else { + dropdown.style.display = 'none'; + if (inputId === 'new_surgery_name') { + $('#btn_add_surgery_row').click(); + } else if (inputId === 'new_procedure_name') { + $('#btn_add_procedure_row').click(); + } } } else if (e.key === 'Escape') { dropdown.style.display = 'none'; @@ -4242,7 +4249,11 @@ $historyFields = [ $tbody.html(html); } + var isSurgerySubmitting = false; + var isProcedureSubmitting = false; + $(document).on('click', '#btn_add_surgery_row', function() { + if (isSurgerySubmitting) return; var form = getDischargeForm(); var name = ($('#new_surgery_name').val() || '').toString().trim(); if (!name) { @@ -4252,6 +4263,26 @@ $historyFields = [ var date = ($('#new_surgery_date').val() || '').toString().trim(); var remark = ($('#new_surgery_remark').val() || '').toString().trim(); var masterId = parseInt($('#new_surgery_master_id').val() || '0', 10); + + // Prevent client-side duplicate insertion + var isDuplicate = false; + $('#discharge_surgery_tbody tr').each(function() { + var rowName = $(this).find('td:first').text().trim(); + var rowDate = $(this).find('td:nth-child(2)').text().trim(); + if (rowName.toUpperCase() === name.toUpperCase() && (!date || !rowDate || rowDate === date)) { + isDuplicate = true; + return false; + } + }); + if (isDuplicate) { + setSectionStatus('discharge_surgery_status', 'This surgery is already added in the table.', 'error'); + return; + } + + isSurgerySubmitting = true; + var $btn = $('#btn_add_surgery_row'); + $btn.prop('disabled', true).text('Adding...'); + var csrf = getCsrfPair(form); var payload = { action: 'add_surgery', @@ -4271,9 +4302,13 @@ $historyFields = [ $('#new_surgery_date').val(''); $('#new_surgery_remark').val(''); $('#new_surgery_master_id').val('0'); - setSectionStatus('discharge_surgery_status', (data && data.notice) ? data.notice : 'Surgery row added.', 'success'); + var level = (data && data.noticeType === 'warning') ? 'error' : 'success'; + setSectionStatus('discharge_surgery_status', (data && data.notice) ? data.notice : 'Surgery row added.', level); }, 'json').fail(function() { setSectionStatus('discharge_surgery_status', 'Unable to add surgery row.', 'error'); + }).always(function() { + isSurgerySubmitting = false; + $btn.prop('disabled', false).text('+ADD Row'); }); }); @@ -4281,6 +4316,8 @@ $historyFields = [ var form = getDischargeForm(); var id = parseInt($(this).data('id') || '0', 10); if (id <= 0) return; + var $btn = $(this); + $btn.prop('disabled', true); var csrf = getCsrfPair(form); var payload = { action: 'remove_surgery', @@ -4294,10 +4331,13 @@ $historyFields = [ renderSurgeryRows(data.surgeryRows); } setSectionStatus('discharge_surgery_status', (data && data.notice) ? data.notice : 'Surgery row removed.', 'success'); - }, 'json'); + }, 'json').always(function() { + $btn.prop('disabled', false); + }); }); $(document).on('click', '#btn_add_procedure_row', function() { + if (isProcedureSubmitting) return; var form = getDischargeForm(); var name = ($('#new_procedure_name').val() || '').toString().trim(); if (!name) { @@ -4305,8 +4345,33 @@ $historyFields = [ return; } var date = ($('#new_procedure_date').val() || '').toString().trim(); + if (!date) { + var today = new Date().toISOString().split('T')[0]; + date = today; + $('#new_procedure_date').val(today); + } var remark = ($('#new_procedure_remark').val() || '').toString().trim(); var masterId = parseInt($('#new_procedure_master_id').val() || '0', 10); + + // Prevent client-side duplicate insertion + var isDuplicate = false; + $('#discharge_procedure_tbody tr').each(function() { + var rowName = $(this).find('td:first').text().trim(); + var rowDate = $(this).find('td:nth-child(2)').text().trim(); + if (rowName.toUpperCase() === name.toUpperCase() && (!date || !rowDate || rowDate === date)) { + isDuplicate = true; + return false; + } + }); + if (isDuplicate) { + setSectionStatus('discharge_surgery_status', 'This procedure is already added in the table.', 'error'); + return; + } + + isProcedureSubmitting = true; + var $btn = $('#btn_add_procedure_row'); + $btn.prop('disabled', true).text('Adding...'); + var csrf = getCsrfPair(form); var payload = { action: 'add_procedure', @@ -4326,9 +4391,13 @@ $historyFields = [ $('#new_procedure_date').val(''); $('#new_procedure_remark').val(''); $('#new_procedure_master_id').val('0'); - setSectionStatus('discharge_surgery_status', (data && data.notice) ? data.notice : 'Procedure row added.', 'success'); + var level = (data && data.noticeType === 'warning') ? 'error' : 'success'; + setSectionStatus('discharge_surgery_status', (data && data.notice) ? data.notice : 'Procedure row added.', level); }, 'json').fail(function() { setSectionStatus('discharge_surgery_status', 'Unable to add procedure row.', 'error'); + }).always(function() { + isProcedureSubmitting = false; + $btn.prop('disabled', false).text('+ADD Row'); }); }); @@ -4336,6 +4405,8 @@ $historyFields = [ var form = getDischargeForm(); var id = parseInt($(this).data('id') || '0', 10); if (id <= 0) return; + var $btn = $(this); + $btn.prop('disabled', true); var csrf = getCsrfPair(form); var payload = { action: 'remove_procedure', @@ -4349,7 +4420,9 @@ $historyFields = [ renderProcedureRows(data.procedureRows); } setSectionStatus('discharge_surgery_status', (data && data.notice) ? data.notice : 'Procedure row removed.', 'success'); - }, 'json'); + }, 'json').always(function() { + $btn.prop('disabled', false); + }); }); function bindSurgeryTermLookup(form, type, lookupId, ddId, targetMasterId, statusId) { @@ -8832,12 +8905,16 @@ $historyFields = [ if (actionValue === 'add_procedure') { var procedureDateInput = form.querySelector('[name="new_procedure_date"]'); - if (!procedureDateInput || String(procedureDateInput.value || '').trim() === '') { - setSectionStatus('discharge_surgery_status', 'Select procedure date before adding.', 'error'); - if (procedureDateInput) { - procedureDateInput.focus(); + if (procedureDateInput && String(procedureDateInput.value || '').trim() === '') { + var todayDateStr = new Date().toISOString().split('T')[0]; + procedureDateInput.value = todayDateStr; + var pDateItem = payloadArray.find(function(it) { return it.name === 'new_procedure_date'; }); + if (pDateItem) { + pDateItem.value = todayDateStr; + } else { + payloadArray.push({ name: 'new_procedure_date', value: todayDateStr }); } - return; + payload = window.jQuery.param(payloadArray); } } @@ -8872,12 +8949,32 @@ $historyFields = [ noticeLevel = noticeLevel === 'success' ? 'error' : noticeLevel; } if (noticeText !== '') { - var statusIdToUse = statusTargetId !== '' ? statusTargetId : ((targetSectionId === 'section-complaints' || isComplaintAction) ? 'discharge_complaint_status' : 'discharge_medicine_status'); + var statusIdToUse = statusTargetId !== '' ? statusTargetId : ( + (targetSectionId === 'section-complaints' || isComplaintAction) ? 'discharge_complaint_status' : + (targetSectionId === 'section-surgery' || actionValue.indexOf('surgery') !== -1 || actionValue.indexOf('procedure') !== -1) ? 'discharge_surgery_status' : + 'discharge_medicine_status' + ); setSectionStatus(statusIdToUse, noticeText, noticeLevel === 'success' ? 'success' : 'error'); if (typeof window.notify === 'function') { window.notify(noticeLevel === 'success' ? 'success' : 'error', 'Discharge Update', noticeText); } } + // Re-render surgery table rows from returned surgeryRows array + if (Array.isArray(parsedJson.surgeryRows) && typeof renderSurgeryRows === 'function') { + renderSurgeryRows(parsedJson.surgeryRows); + $('#new_surgery_name').val(''); + $('#new_surgery_date').val(''); + $('#new_surgery_remark').val(''); + $('#new_surgery_master_id').val('0'); + } + // Re-render procedure table rows from returned procedureRows array + if (Array.isArray(parsedJson.procedureRows) && typeof renderProcedureRows === 'function') { + renderProcedureRows(parsedJson.procedureRows); + $('#new_procedure_name').val(''); + $('#new_procedure_date').val(''); + $('#new_procedure_remark').val(''); + $('#new_procedure_master_id').val('0'); + } // Re-render complaint table rows from returned complaintRows array if ((isComplaintAction || targetSectionId === 'section-complaints') && Array.isArray(parsedJson.complaintRows)) { if (typeof selectedDischargeComplaints !== 'undefined') {