Add confirmation modal before sending advance payslips

When creating an Advance Payment, a confirmation modal now appears
showing all selected workers, individual amounts, total, and a warning
that payslips will be sent to Spark Receipt. Non-advance adjustments
submit normally without the extra step.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Konrad du Plessis 2026-02-19 23:34:34 +02:00
parent f56c082421
commit 4e490ea2d4

View File

@ -558,6 +558,43 @@
</div>
</div>
<!-- Advance Confirmation Modal -->
<div class="modal fade" id="advanceConfirmModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-info bg-opacity-10">
<h5 class="modal-title fw-bold">Confirm Advance Payment</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="alert alert-info small mb-3">
This will immediately create a payslip for each worker below and send it to Spark Receipt. This cannot be undone.
</div>
<table class="table table-sm mb-0">
<thead>
<tr>
<th>Worker</th>
<th class="text-end">Amount</th>
</tr>
</thead>
<tbody id="advanceConfirmWorkerList"></tbody>
<tfoot>
<tr class="fw-bold">
<td>Total</td>
<td class="text-end" id="advanceConfirmTotal"></td>
</tr>
</tfoot>
</table>
<div class="mt-2 small text-muted" id="advanceConfirmDescription"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-light" data-bs-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-info" id="advanceConfirmSubmit">Yes, Send Advance</button>
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Adjustment modal: Select All / Clear helpers
@ -575,6 +612,62 @@ document.addEventListener('DOMContentLoaded', function() {
});
}
// Advance confirmation: intercept Add Adjustment form submit
const addAdjForm = document.querySelector('#addAdjustmentModal form');
if (addAdjForm) {
const advanceConfirmModalEl = document.getElementById('advanceConfirmModal');
const advanceConfirmModal = new bootstrap.Modal(advanceConfirmModalEl);
const addAdjModal = bootstrap.Modal.getInstance(document.getElementById('addAdjustmentModal')) ||
new bootstrap.Modal(document.getElementById('addAdjustmentModal'));
addAdjForm.addEventListener('submit', function(e) {
const typeSelect = addAdjForm.querySelector('select[name="type"]');
if (typeSelect.value !== 'ADVANCE') return; // let non-ADVANCE submit normally
e.preventDefault();
// Gather selected workers
const workerSelect = document.getElementById('adjWorkerSelect');
const selectedWorkers = [];
for (const opt of workerSelect.selectedOptions) {
selectedWorkers.push(opt.text);
}
if (selectedWorkers.length === 0) return;
const amount = addAdjForm.querySelector('input[name="amount"]').value;
const description = addAdjForm.querySelector('input[name="description"]').value;
// Populate confirmation modal using safe DOM methods
const tbody = document.getElementById('advanceConfirmWorkerList');
while (tbody.firstChild) tbody.removeChild(tbody.firstChild);
selectedWorkers.forEach(function(name) {
const tr = document.createElement('tr');
const tdName = document.createElement('td');
tdName.textContent = name;
const tdAmount = document.createElement('td');
tdAmount.className = 'text-end';
tdAmount.textContent = 'R ' + parseFloat(amount).toFixed(2);
tr.appendChild(tdName);
tr.appendChild(tdAmount);
tbody.appendChild(tr);
});
const total = (selectedWorkers.length * parseFloat(amount)).toFixed(2);
document.getElementById('advanceConfirmTotal').textContent = 'R ' + total + ' (' + selectedWorkers.length + ' worker' + (selectedWorkers.length > 1 ? 's' : '') + ')';
document.getElementById('advanceConfirmDescription').textContent = description ? 'Description: ' + description : '';
// Hide add modal, show confirmation
addAdjModal.hide();
advanceConfirmModal.show();
// Wire confirm button to actually submit
document.getElementById('advanceConfirmSubmit').onclick = function() {
advanceConfirmModal.hide();
addAdjForm.submit();
};
});
}
// Edit/Delete Adjustment Modal Logic
const editModalEl = document.getElementById('editAdjustmentModal');
const deleteModalEl = document.getElementById('deleteAdjustmentModal');