nhance/app/Views/view_deposit.php
2026-07-28 15:52:47 +05:30

1409 lines
61 KiB
PHP
Executable File

<?php
helper('datatable_view');
$vd_header_labels = [
'Date', 'Record Date', 'Unit', 'Policy', 'Endorsement No', 'Sub Type',
'Credit', 'Debit', 'Balance', 'Description', 'User',
];
$vd_col_count = count($vd_header_labels);
$vd_col_max_len = array_fill(0, $vd_col_count, 0);
for ($i = 0; $i < $vd_col_count; $i++) {
$vd_col_max_len[$i] = mb_strlen($vd_header_labels[$i]);
}
$depositdata = $depositdata ?? [];
$subTypeOptions = $subTypeOptions ?? [];
foreach ($depositdata as $row) {
$vd_col_max_len[0] = max($vd_col_max_len[0], mb_strlen(date('d-M-Y h:i A', strtotime((string) $row->created_at))));
$rec = ! empty($row->record_date) ? date('d-M-Y', strtotime((string) $row->record_date)) : '-';
$vd_col_max_len[1] = max($vd_col_max_len[1], mb_strlen($rec));
$vd_col_max_len[2] = max($vd_col_max_len[2], mb_strlen(trim((string) ($row->unit ?? ' - '))));
$policyType = $row->policy_type ?? '';
$policyNo = $row->policy_no ?? '';
$policyCell = ($policyType || $policyNo) ? trim($policyType . ' - ' . $policyNo, ' -') : '-';
$vd_col_max_len[3] = max($vd_col_max_len[3], mb_strlen($policyCell));
$vd_col_max_len[4] = max($vd_col_max_len[4], mb_strlen(strip_tags((string) ($row->endorsement_no ?? '-'))));
$subLabel = isset($subTypeOptions[$row->sub_type]) ? (string) $subTypeOptions[$row->sub_type] : '';
$vd_col_max_len[5] = max($vd_col_max_len[5], mb_strlen($subLabel));
$credit = ($row->transaction_type ?? '') === 'Credit' ? (string) ($row->amount ?? '-') : '-';
$debit = ($row->transaction_type ?? '') === 'Debit' ? (string) ($row->amount ?? '-') : '-';
$vd_col_max_len[6] = max($vd_col_max_len[6], mb_strlen($credit));
$vd_col_max_len[7] = max($vd_col_max_len[7], mb_strlen($debit));
$vd_col_max_len[8] = max($vd_col_max_len[8], mb_strlen((string) ($row->balance ?? '')));
$vd_col_max_len[9] = max($vd_col_max_len[9], mb_strlen((string) ($row->description ?? '')));
$vd_col_max_len[10] = max($vd_col_max_len[10], mb_strlen((string) ($row->username ?? '')));
}
$vd_col_min_px = [120, 100, 72, 160, 110, 88, 150, 150, 170, 140, 100];
$vd_col_max_px = [200, 120, 120, 360, 160, 140, 180, 180, 220, 400, 200];
$vd_col_width_px = nhance_dt_column_widths_px($vd_header_labels, $vd_col_max_len, $vd_col_min_px, $vd_col_max_px);
?>
<style>
<?php for ($i = 0; $i < $vd_col_count; $i++) : ?>
#scroll-horizontal-datatable_wrapper .dataTables_scrollHead table thead th:nth-child(<?= $i + 1 ?>),
#scroll-horizontal-datatable thead th:nth-child(<?= $i + 1 ?>) {
min-width: <?= (int) $vd_col_width_px[$i] ?>px;
width: <?= (int) $vd_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
overflow: visible !important;
}
#scroll-horizontal-datatable tbody td:nth-child(<?= $i + 1 ?>) {
width: <?= (int) $vd_col_width_px[$i] ?>px;
max-width: <?= (int) $vd_col_width_px[$i] ?>px;
min-width: <?= (int) $vd_col_width_px[$i] ?>px;
box-sizing: border-box;
vertical-align: middle;
}
<?php endfor; ?>
#scroll-horizontal-datatable tbody td {
padding: 5px 11px !important;
font-size: 13px;
line-height: 1.25;
overflow: hidden;
text-overflow: ellipsis;
}
#scroll-horizontal-datatable tbody td.deposit-description-cell {
overflow: visible;
text-overflow: clip;
white-space: normal;
}
#scroll-horizontal-datatable_wrapper .dataTables_scrollHead table thead th,
#scroll-horizontal-datatable thead th {
padding: 5px 11px !important;
font-size: 13px;
line-height: 1.25;
}
#scroll-horizontal-datatable_wrapper .dataTables_scrollHead table,
#scroll-horizontal-datatable_wrapper .dataTables_scrollBody table {
table-layout: fixed;
width: 100% !important;
}
#List-page .card-body > .table-responsive {
overflow-x: auto;
}
.deposit-header {
display: flex;
align-items: center;
gap: 10px;
flex-wrap: wrap;
}
.deposit-summary-row {
display: flex;
justify-content: space-between;
align-items: center;
gap: 12px;
flex-wrap: wrap;
}
.metrics{
border:1px solid lightgrey;
border-radius:10px;
box-shadow: 0px 4px 4px 0px #00000040;
width: 100%;
max-width: 100%;
padding: 12px;
min-height: 64px;
}
.dataTables_length label {height: 21px !important;}
#scroll-horizontal-datatable tbody tr:hover { background-color: #e0e0e0; }
.deposit-inline-cell {
display: flex;
align-items: center;
gap: 6px;
}
.deposit-inline-input {
width: 150px;
max-width: 100%;
}
.deposit-inline-input-disabled {
background-color: #f4f5f7 !important;
cursor: not-allowed;
}
.deposit-description-cell .deposit-inline-cell {
width: 100%;
}
.deposit-description-input {
width: 100%;
max-width: 100%;
min-height: 30px;
resize: vertical;
font-size: 13px;
line-height: 1.25;
}
.deposit-balance-wrap {
display: inline-flex;
align-items: center;
gap: 6px;
}
.deposit-history-icon {
color: #0ea5b7;
cursor: pointer;
font-size: 16px;
line-height: 1;
}
#moreInfoModal .modal-dialog {
max-width: 520px;
}
#moreInfoModal .modal-content {
background: #ffffff;
border: 1px solid #e5e7eb;
border-radius: 14px;
color: #111827;
box-shadow: 0 18px 40px rgba(15, 23, 42, 0.12);
}
#moreInfoModal .modal-header,
#moreInfoModal .modal-footer {
border-color: #e5e7eb;
padding: 14px 18px;
background: #ffffff;
}
#moreInfoModal .modal-body {
padding: 0 18px 16px;
background: #ffffff;
}
#moreInfoModal .deposit-history-title-wrap {
display: flex;
align-items: center;
gap: 10px;
}
#moreInfoModal .deposit-history-title-icon {
width: 34px;
height: 34px;
border-radius: 8px;
background: #0ea5b7;
color: #fff;
display: inline-flex;
align-items: center;
justify-content: center;
font-size: 18px;
}
#moreInfoModal .modal-title {
font-size: 18px;
font-weight: 600;
color: #111827;
margin: 0;
}
#moreInfoModal .deposit-history-close-btn {
width: 34px;
height: 34px;
border: 1px solid #d1d5db;
border-radius: 8px;
background: #ffffff;
color: #6b7280;
display: inline-flex;
align-items: center;
justify-content: center;
padding: 0;
}
#moreInfoModal .deposit-history-close-btn:hover {
background: #f3f4f6;
color: #111827;
}
#moreInfoModal .deposit-history-amount-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
margin-bottom: 14px;
}
#moreInfoModal .deposit-history-amount-card {
background: #f9fafb;
border: 1px solid #e5e7eb;
border-radius: 10px;
padding: 12px 14px;
}
#moreInfoModal .deposit-history-amount-label {
font-size: 11px;
letter-spacing: 0.04em;
text-transform: uppercase;
color: #6b7280;
margin-bottom: 6px;
font-weight: 600;
}
#moreInfoModal .deposit-history-amount-value {
font-size: 24px;
line-height: 1.2;
font-weight: 700;
color: #111827;
word-break: break-word;
}
#moreInfoModal .deposit-history-meta-box {
border: 1px solid #e5e7eb;
border-radius: 10px;
overflow: hidden;
background: #f9fafb;
}
#moreInfoModal .deposit-history-meta-row {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
padding: 12px 14px;
background: #ffffff;
}
#moreInfoModal .deposit-history-meta-row + .deposit-history-meta-row {
border-top: 1px solid #e5e7eb;
}
#moreInfoModal .deposit-history-meta-label {
display: inline-flex;
align-items: center;
gap: 8px;
color: #6b7280;
font-size: 14px;
}
#moreInfoModal .deposit-history-meta-value {
color: #111827;
font-size: 14px;
font-weight: 500;
text-align: right;
}
#moreInfoModal .deposit-history-footer-btn {
border: 1px solid #d1d5db;
border-radius: 8px;
background: #ffffff;
color: #374151;
padding: 6px 16px;
font-size: 14px;
}
#moreInfoModal .deposit-history-footer-btn:hover {
background: #f3f4f6;
color: #111827;
}
.deposit-inline-actions {
display: inline-flex;
gap: 4px;
}
.deposit-inline-actions .btn {
padding: 2px 6px;
line-height: 1.2;
}
@media (max-width: 767.98px) {
.deposit-title {
font-size: 22px;
}
.deposit-account-title,
.deposit-summary-title {
font-size: 18px;
margin-bottom: 0;
}
}
</style>
<?php
$depositNavTitle = 'Transaction Details - ' . (isset($insurerName->name) ? $insurerName->name : '');
$depositBackUrl = base_url('client/deposit/' . (isset($clientData->id) ? $clientData->id : ''));
?>
<script>
var pageHideMainNavTitle = true;
var pageTitle = <?= json_encode($depositNavTitle, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_UNESCAPED_UNICODE) ?>;
var pageBackButton = '<a href="<?= esc($depositBackUrl, 'attr') ?>" class="topbar-icon-btn" data-toggle="tooltip" data-placement="top" title="Back" aria-label="Back"><i class="ri-arrow-left-s-line"></i></a>';
</script>
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-body">
<div class="deposit-summary-row">
<div><h4 class="deposit-account-title">CD Account No : <?php echo isset($insurerName->cd_master_account_no) && !empty($insurerName->cd_master_account_no) ? $insurerName->cd_master_account_no : 'N/A' ?></h4></div>
<div><h4 class="deposit-summary-title">Deposit Summary Of <?php echo $clientData->short_name?></h4></div>
</div>
<div>
<div class="row text-center">
<div class="col-12 col-sm-6 col-lg-3 mt-2">
<div class="d-flex justify-content-between align-items-center metrics">
<span class="text-muted font-15 mb-1 text-truncate">Deposits</span>
<h4 style="font-size: 18px;display:inline;"><i
class="fe-arrow-up text-success mr-1" ></i>₹<?php echo $deposiamount->total_credit?>
</h4>
</div>
</div>
<div class="col-12 col-sm-6 col-lg-3 mt-2">
<div class="d-flex justify-content-between align-items-center metrics">
<span class="text-muted font-15 mb-1 text-truncate">Consumed</span>
<h4 style="font-size: 20px;display:inline;"><i
class="fe-arrow-down text-danger mr-1"></i>₹<?php echo $deposiamount->total_withdraw?>
</h4>
</div>
</div>
<div class="col-12 col-sm-6 col-lg-3 mt-2">
<div class="d-flex justify-content-between align-items-center metrics">
<span class="text-muted font-15 mb-1 text-truncate">Refund</span>
<h4 style="font-size: 20px;display:inline;"><i
class="fe-arrow-up text-success mr-1"></i>₹<?php echo $deposiamount->total_refund?>
</h4>
</div>
</div>
<div class="col-12 col-sm-6 col-lg-3 mt-2">
<div class="d-flex justify-content-between align-items-center metrics">
<span class="text-muted font-15 mb-1 text-truncate">Current Balance</span>
<h4 style="font-size: 20px;display:inline;"><i
class="fe-credit-card text-success mr-1"></i>₹<?php echo $deposiamount->balance?>
</h4>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row" id="List-page">
<div class="col-12">
<div class="card">
<div class="card-body">
<!-- <div class="row" style="margin-bottom:1rem;">
<div class="col-6" style="text-align: right; position: relative;top: 56px; z-index:999">
<button type="button" id="btnAdd" class="btn btn-primary waves-effect waves-light" data-toggle="modal" data-target="#addTransactionModal"> + Add</button>
</div>
</div> -->
<div class="table-responsive">
<table data-custom-table-css="table" class="table mb-0 nowrap w-100" cellspacing="0" id="scroll-horizontal-datatable">
<thead class="bg-light">
<tr>
<th class="font-weight-medium">Date</th>
<th class="font-weight-medium">Record Date</th>
<th class="font-weight-medium">Unit</th>
<th class="font-weight-medium">Policy</th>
<th class="font-weight-medium">Endorsement No</th>
<th class="font-weight-medium">Sub Type</th>
<th class="font-weight-medium">Credit</th>
<th class="font-weight-medium">Debit</th>
<th class="font-weight-medium">Balance</th>
<th class="font-weight-medium">Description</th>
<th class="font-weight-medium">User</th>
</tr>
</thead>
<tbody>
<?php foreach($depositdata as $row) { ?>
<?php
$isCreditRow = ($row->transaction_type == 'Credit');
$isDebitRow = ($row->transaction_type == 'Debit');
$creditAmount = $isCreditRow ? (float) $row->amount : 0;
$debitAmount = $isDebitRow ? (float) $row->amount : 0;
$hasAmtHistory = isset($row->new_amt) && trim((string) $row->new_amt) !== '';
$historyOldAmt = trim((string) ($row->old_amt ?? '-')) !== '' ? (string) $row->old_amt : '-';
$historyNewAmt = trim((string) ($row->new_amt ?? '-')) !== '' ? (string) $row->new_amt : '-';
$historyUpdatedBy = trim((string) ($row->amt_updated_by_name ?? '')) !== ''
? (string) $row->amt_updated_by_name
: (!empty($row->amt_updated_by) ? ('User #' . $row->amt_updated_by) : '-');
$historyUpdatedAt = !empty($row->amt_updated_at)
? date('d/m/Y h:i A', strtotime((string) $row->amt_updated_at))
: '-';
?>
<tr id="<?php echo $row->id;?>"
data-row-id="<?= (int) $row->id ?>"
data-transaction-type="<?= esc((string) $row->transaction_type, 'attr') ?>"
data-credit="<?= esc((string) $creditAmount, 'attr') ?>"
data-debit="<?= esc((string) $debitAmount, 'attr') ?>"
data-description="<?= esc((string) ($row->description ?? ''), 'attr') ?>">
<td><?php echo date('d/m/Y h:i A', strtotime($row->created_at)); ?></td>
<td><?php echo isset($row->record_date)? date('d-M-Y', strtotime($row->record_date)):'-' ?></td>
<td><?php echo $row->unit ?? ' - '; ?></td>
<!-- <td><?php echo $row->policy_name ?? '<center> - </center>'; ?></td> -->
<td>
<?php
$policyType = $row->policy_type ?? '';
$policyNo = $row->policy_no ?? '';
if ($policyType || $policyNo) {
echo trim($policyType . ' - ' . $policyNo, ' -');
} else {
echo '-';
}
?>
</td>
<td><?php echo $row->endorsement_no ?? '-'; ?></td>
<td><?php echo isset($subTypeOptions[$row->sub_type]) ? $subTypeOptions[$row->sub_type] : ''; ?>
</td>
<td class="deposit-inline-edit-cell" data-type="credit">
<div class="deposit-inline-cell">
<input type="text" class="form-control form-control-sm deposit-inline-input <?= $isCreditRow ? '' : 'deposit-inline-input-disabled' ?>" placeholder="-" value="<?= $isCreditRow ? esc((string) $row->amount, 'attr') : '' ?>" <?= $isCreditRow ? '' : 'disabled' ?>>
</div>
</td>
<td class="deposit-inline-edit-cell" data-type="debit">
<div class="deposit-inline-cell">
<input type="text" class="form-control form-control-sm deposit-inline-input <?= $isDebitRow ? '' : 'deposit-inline-input-disabled' ?>" placeholder="-" value="<?= $isDebitRow ? esc((string) $row->amount, 'attr') : '' ?>" <?= $isDebitRow ? '' : 'disabled' ?>>
</div>
</td>
<td class="deposit-balance-cell">
<span class="deposit-balance-wrap">
<span><?php echo $row->balance; ?></span>
<?php if ($hasAmtHistory) : ?>
<i class="mdi mdi-information-outline deposit-history-icon js-deposit-history-trigger"
data-old-amt="<?= esc($historyOldAmt, 'attr') ?>"
data-new-amt="<?= esc($historyNewAmt, 'attr') ?>"
data-updated-by="<?= esc($historyUpdatedBy, 'attr') ?>"
data-updated-at="<?= esc($historyUpdatedAt, 'attr') ?>"
onclick="openDepositHistoryModal(this); return false;"
aria-label="Amount change history"
tabindex="0"></i>
<?php endif; ?>
</span>
</td>
<td class="deposit-description-cell">
<div class="deposit-inline-cell">
<textarea class="form-control form-control-sm deposit-description-input"
rows="2"
title="<?= esc((string) ($row->description ?? ''), 'attr') ?>"
aria-label="Description"><?= esc((string) ($row->description ?? '')) ?></textarea>
</div>
</td>
<td><?php echo $row->username; ?></td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- end col -->
</div>
</div>
<div class="modal fade" id="moreInfoModal" tabindex="-1" aria-labelledby="depositHistoryModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<div class="deposit-history-title-wrap">
<span class="deposit-history-title-icon" aria-hidden="true">
<i class="mdi mdi-history"></i>
</span>
<h5 class="modal-title" id="depositHistoryModalLabel">Amount change history</h5>
</div>
<button type="button" class="deposit-history-close-btn" data-dismiss="modal" data-bs-dismiss="modal" aria-label="Close">
<i class="mdi mdi-close"></i>
</button>
</div>
<div class="modal-body">
<div class="deposit-history-amount-grid">
<div class="deposit-history-amount-card">
<div class="deposit-history-amount-label">Old amount</div>
<div class="deposit-history-amount-value" id="history_old_amt">-</div>
</div>
<div class="deposit-history-amount-card">
<div class="deposit-history-amount-label">New amount</div>
<div class="deposit-history-amount-value" id="history_new_amt">-</div>
</div>
</div>
<div class="deposit-history-meta-box">
<div class="deposit-history-meta-row">
<div class="deposit-history-meta-label">
<i class="mdi mdi-account-outline"></i>
<span>Modified by</span>
</div>
<div class="deposit-history-meta-value" id="history_updated_by">-</div>
</div>
<div class="deposit-history-meta-row">
<div class="deposit-history-meta-label">
<i class="mdi mdi-calendar-month-outline"></i>
<span>Modified at</span>
</div>
<div class="deposit-history-meta-value" id="history_updated_at">-</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="deposit-history-footer-btn" data-dismiss="modal" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<script>
function formatDepositHistoryAmount(value) {
if (value === null || value === undefined) {
return '-';
}
var raw = String(value).trim();
if (raw === '' || raw === '-') {
return '-';
}
var num = parseFloat(raw.replace(/,/g, ''));
if (isNaN(num)) {
return raw;
}
return '₹' + num.toLocaleString('en-IN', {
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
}
function openDepositHistoryModal(iconEl) {
var $icon = $(iconEl);
$('#history_old_amt').text(formatDepositHistoryAmount($icon.data('old-amt')));
$('#history_new_amt').text(formatDepositHistoryAmount($icon.data('new-amt')));
$('#history_updated_by').text($icon.data('updated-by') || '-');
$('#history_updated_at').text($icon.data('updated-at') || '-');
var modalElement = document.getElementById('moreInfoModal');
if (typeof bootstrap !== 'undefined' && typeof bootstrap.Modal !== 'undefined' && modalElement) {
var myModal = new bootstrap.Modal(document.getElementById('moreInfoModal'));
myModal.show();
return;
}
if (typeof $('#moreInfoModal').modal === 'function') {
$('#moreInfoModal').modal('show');
return;
}
toastr.warning('History view is not available right now.');
}
</script>
<!-- Add this modal markup at the end of your HTML body -->
<!-- Button to trigger modal -->
<!-- Add this modal markup at the end of your HTML body -->
<div class="modal fade" id="addTransactionModal" tabindex="-1" role="dialog" aria-labelledby="addTransactionModalLabel"
aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="addTransactionModalLabel">Add Transaction</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<h3>Transaction Mode</h3>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<div class="form-check mt-2">
<input class="form-check-input" type="radio" name="transactionMode" id="addMode"value="1" checked>
<label class="form-check-label" for="addMode">Replenishment by Client</label>
</div>
<div class="form-check mt-2">
<input class="form-check-input" type="radio" name="transactionMode" id="refund_by_insurer"value="6">
<label class="form-check-label" for="addMode">Refund by Insurer</label>
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<div class="form-check mt-2">
<input class="form-check-input" type="radio" name="transactionMode" id="assetpolicyadd"value="4">
<label class="form-check-label" for="adjustmentMode">Non EB Credit</label>
</div>
<div class="form-check mt-2">
<input class="form-check-input" type="radio" name="transactionMode" id="assetpolicyreduce"value="5">
<label class="form-check-label" for="adjustmentMode">No EB Debit</label>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label for="field-1" class="control-label">Amount<span class="text-danger">*</span></label>
<input type="text" class="form-control" id="amount" placeholder="Amount" required
inputmode="decimal" maxlength="12"
data-parsley-pattern="^[0-9]+(\\.[0-9]{1,2})?$"
data-parsley-pattern-message="Amount must be a valid number."
data-parsley-required-message="Amount field is required.">
<div id="amount_error" class="text-danger small mt-1" style="display:none;"></div>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="record_date">Record Date <span class="text-danger"></span></label>
<input type="text" class="form-control policy_start_date" id="record_date" name="record_date" placeholder="Record Date">
</div>
</div>
</div>
<!-- <div class="row" id="transactionTypeRow" style="display:none;">
<div class="col-md-6">
<div class="form-group">
<label for="transactionType" class="control-label">Transaction Type</label>
<select class="form-control" id="transactionType">
<option value="Credit">Add</option>
<option value="Debit">Reduce</option>
</select>
</div>
</div>
</div> -->
<div class="row">
<div class="col-md-12">
<div class="form-group no-margin">
<label for="description" class="control-label">Description<span class="text-danger">*</span></label>
<textarea class="form-control" id="description"
placeholder="Write something about the transaction" required></textarea>
<input type="hidden" id="cd_ac_pk" value="<?php echo $depositdata[0]->cd_ac_pk?>">
<input type="hidden" id="cd_ac_no" value="<?php echo $depositdata[0]->cd_ac_no?>">
</div>
</div>
</div>
<!-- <div class="form-group">
<label for="subType" class="control-label" style="display: none;">Transaction Sub Type</label>
<select class="form-control" id="subType" name="sub_type" style="display: none;">
<option value="Deposit" hidden>Replenishment</option>
<option value="Adjustment" hidden>Adjustment</option>
</select>
</div> -->
<div class="modal-footer">
<button type="button" class="btn cancel-btn" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary submit-btn" id="saveTransactionBtn">Submit</button>
</div>
</div>
</div>
</div>
</div>
<script>
$(document).ready(function() {
$('input[name="transactionMode"]').change(function() {
if ($(this).val() === 'adjustment') {
$('#transactionTypeRow').show();
} else {
$('#transactionTypeRow').hide();
}
});
});
</script>
<script>
$(document).ready(function() {
var record_date = flatpickr("#record_date", {
dateFormat: "d/m/Y",
allowInput: false,
});
nhanceListDataTableBeforeInit();
function depositExportFormatBody(data, row, column, node) {
if (column === 6 || column === 7) {
var $input = $(node).find('.deposit-inline-input');
if ($input.length) {
var val = ($input.val() || '').trim();
return val !== '' ? val : '-';
}
var $tr = $(node).closest('tr');
var credit = parseFloat($tr.attr('data-credit')) || 0;
var debit = parseFloat($tr.attr('data-debit')) || 0;
if (column === 6) {
return credit > 0 ? String(credit) : '-';
}
return debit > 0 ? String(debit) : '-';
}
if (column === 8) {
var $balanceSpan = $(node).find('.deposit-balance-wrap > span').first();
if ($balanceSpan.length) {
return ($balanceSpan.text() || '').trim();
}
return ($(node).text() || '').trim();
}
if (column === 9) {
var $descInput = $(node).find('.deposit-description-input');
if ($descInput.length) {
return ($descInput.val() || '').trim();
}
}
if (typeof data === 'string' && data.indexOf('<') !== -1) {
return $('<div>').html(data).text().trim();
}
return data;
}
var depositExportOptions = {
format: {
body: depositExportFormatBody
}
};
var depositPageStorageKey = 'view_deposit_datatable_page_' + window.location.pathname + window.location.search;
function getStoredDepositPage() {
var page = parseInt(sessionStorage.getItem(depositPageStorageKey), 10);
return isNaN(page) || page < 0 ? 0 : page;
}
function storeDepositPage(pageNumber) {
sessionStorage.setItem(depositPageStorageKey, String(pageNumber));
}
window.storeCurrentDepositTablePage = function () {
try {
var table = $('#scroll-horizontal-datatable').DataTable();
storeDepositPage(table.page());
} catch (e) {
// No-op when table is not available.
}
};
function initDepositDescriptionTooltips() {
var selector = '#scroll-horizontal-datatable [data-bs-toggle="tooltip"]';
if (typeof bootstrap !== 'undefined' && typeof bootstrap.Tooltip !== 'undefined') {
document.querySelectorAll(selector).forEach(function (el) {
var existing = bootstrap.Tooltip.getInstance(el);
if (existing) {
existing.dispose();
}
new bootstrap.Tooltip(el, { container: 'body' });
});
return;
}
if (typeof $.fn.tooltip === 'function') {
var $targets = $('#scroll-horizontal-datatable [data-toggle="tooltip"]');
$targets.tooltip('dispose');
$targets.tooltip({ container: 'body' });
}
}
var vdDepositTable = $('#scroll-horizontal-datatable').DataTable(nhanceMergeListDataTableOptions({
// dom: "<'row'<'col-sm-2'f><'col-sm-10 text-right'B>>" +
// "<'row'<'col-sm-12'tr>>" +
// "<'row'<'col-sm-5'i><'col-sm-7'p>>",
// buttons: [
// {
// text: '+ add',
// className: 'btn btn-primary buttons-html5',
// action: function () {
// var myModal = new bootstrap.Modal(document.getElementById('addTransactionModal'));
// myModal.show();
// }
// }
// ,
// {
// extend: 'csv',
// text: 'CSV',
// title: 'CD TransactionDetails',
// exportOptions: {
// columns: ''
// }
// },
// {
// extend: 'pdf',
// text: 'PDF',
// title: 'TransactionDetails',
// exportOptions: {
// columns: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
// format: {
// body: function (data, row, column, node) {
// return data.replace(/<.*?>/g, '');
// }
// }
// },
// customize: function (doc) {
// doc.pageOrientation = 'landscape';
// doc.styles.tableHeader.alignment = 'left';
// doc.defaultStyle.alignment = 'left';
// doc.content[1].table.widths = [
// '9%', '9%', '8%', '9%', '10%',
// '9%', '9%', '9%', '9%', '11%', '8%'
// ];
// }
// }
// ],
dom: "<'row'<'col-sm-6'f><'col-sm-6 text-right'B>>" +
"<'row'<'col-sm-12'tr>>" +
"<'row align-items-center'<'col-5 text-start'i><'col-7 d-flex justify-content-end align-items-center'<'me-2'l>p>>",
lengthMenu: [[10, 20, 50, 100], [10, 20, 50, 100]],
buttons: [
{
text: '<i class="mdi mdi-plus" ></i><span class=" btn-custom"> Add </span>',
className: 'btn app-btn-primary mr-2',
action: function () {
var myModal = new bootstrap.Modal(document.getElementById('addTransactionModal'));
myModal.show();
}
},
{
text: '<i class="mdi mdi-content-save"></i><span class=" btn-custom"> Save </span>',
className: 'btn app-btn-primary mr-2 deposit-top-save-btn d-none',
action: function () {
if (typeof window.saveDepositInlineChanges === 'function') {
window.saveDepositInlineChanges();
} else {
toastr.warning('Save handler is not ready yet.');
}
}
},
{
extend: 'collection',
text: '<span class=" btn-custom"> Export </span><i class="mdi mdi-menu-down"></i>',
className: 'btn app-btn-secondary ',
buttons: [
{
extend: 'csv',
text: '<i class="mdi mdi-file-delimited " ></i><span class=" btn-custom"> CSV </span>',
title: 'CD TransactionDetails',
exportOptions: $.extend(true, { columns: '' }, depositExportOptions),
className: 'app-btn-primary ',
},
{
extend: 'excel',
text: '<i class="mdi mdi-file-excel " ></i><span class=" btn-custom"> EXCEL </span>',
title: 'CD TransactionDetails',
sheetName: 'CD TransactionDetails',
exportOptions: $.extend(true, { orthogonal: 'sort' }, depositExportOptions)
}
]
}
],
language: {
search: `
<div class="datatable-search-wrapper" style="position:relative; display:inline-block;">
_INPUT_
<i class="mdi mdi-magnify datatable-search-icon"
style="position:absolute; right:10px; top:50%; transform:translateY(-50%); color:#666;"></i>
<i class="mdi mdi-close-circle datatable-clear-icon"
style="position:absolute; right:10px; top:50%; transform:translateY(-50%); color:#666; display:none;"></i>
</div>`,
searchPlaceholder: "Search",
emptyTable: '<div class="text-center text-muted">No Data found</div>'
},
ordering: false,
paging: true,
autoWidth: false,
columnDefs: [
<?php for ($i = 0; $i < $vd_col_count; $i++) : ?>
{ targets: <?= $i ?>, width: '<?= (int) $vd_col_width_px[$i] ?>px' },
<?php endfor; ?>
],
}));
vdDepositTable.on('page.dt', function () {
storeDepositPage(vdDepositTable.page());
});
initDepositDescriptionTooltips();
vdDepositTable.on('draw', function () {
initDepositDescriptionTooltips();
});
var selectedPage = getStoredDepositPage();
if (selectedPage > 0 && selectedPage < vdDepositTable.page.info().pages) {
vdDepositTable.page(selectedPage).draw('page');
}
nhanceListDataTableAfterInit();
nhanceListDataTableBindAdjust(vdDepositTable);
$(document).on('click keydown', '.js-deposit-history-trigger', function (e) {
if (e.type === 'keydown' && e.key !== 'Enter' && e.key !== ' ') {
return;
}
e.preventDefault();
openDepositHistoryModal(this);
});
});
</script>
<script>
$(document).ready(function() {
// // Event listener for radio buttons
// $('input[name="transactionMode"]').change(function() {
// if ($(this).val() === 'add') {
// // Set the hidden input value to 'Deposit' when 'Deposit' radio button is selected
// $('#subType').val('Deposit');
// } else if ($(this).val() === 'adjustment') {
// // Set the hidden input value to 'Adjustment' when 'Adjustment' radio button is selected
// $('#subType').val('Adjustment');
// }
// });
$('#saveTransactionBtn').on('click', function() {
var amount = $('#amount').val();
var description = $('#description').val();
var clientId = '<?php echo $clientData->id; ?>';
var insurerId = '<?php echo $insurerName->id; ?>';
var transactionTypeValue = $('input[name="transactionMode"]:checked').val();
var subType = "";
var record_date = $('#record_date').val();
var cd_ac_no = $('#cd_ac_no').val();
var cd_ac_pk = $('#cd_ac_pk').val();
amount = (amount || '').trim();
var amountRegex = /^[0-9]+(\.[0-9]{1,2})?$/;
if (amount === "") {
$('#amount_error').text('Amount field is required.').show();
$('#amount').addClass('is-invalid');
toastr.warning('Amount field is required');
return;
}
if (!amountRegex.test(amount)) {
$('#amount_error').text('Amount must be a valid number.').show();
$('#amount').addClass('is-invalid');
toastr.warning('Amount must be a valid number.');
return;
}
$('#amount_error').hide().text('');
$('#amount').removeClass('is-invalid');
if (description == "") {
toastr.warning('Description field is required')
return;
}
//tranction type
if (transactionTypeValue == 1) {
transactionType = 'Credit';
subType = '1'; // Replenishment or Deposite
} else if (transactionTypeValue == 2) {
transactionType = 'Credit'
subType = '2'; // Adjustment add
} else if (transactionTypeValue == 3) {
transactionType = 'Debit'
subType = '2'; // Adjustment reduce
} else if (transactionTypeValue == 4) {
transactionType = 'Credit'
subType = '5'; // Asset Policy add
} else if (transactionTypeValue == 5) {
transactionType = 'Debit'
subType = '5'; // Asset Policy reduce
} else if (transactionTypeValue == 6) {
transactionType = 'Debit'
subType = '6'; // Refund by indurer
}
console.log('transactionTypeValue', transactionTypeValue)
console.log('transactionType', transactionType)
console.log('description ', description)
console.log('amount ', amount)
console.log('clientId ', clientId)
console.log('insurerId ', insurerId)
console.log('subType ', subType)
console.log('cd_ac_pk ', cd_ac_pk)
console.log('cd_ac_no ', cd_ac_no)
// Send data to the server using Ajax
$.ajax({
type: 'POST',
url: '<?= base_url() . "client/save_deposit" ?>',
data: {
amount: amount,
description: description,
transaction_type: transactionType,
sub_type_id: subType, // Include sub_type_id
client_id: clientId,
insurer_id: insurerId,
record_date: record_date,
cd_ac_pk: cd_ac_pk,
cd_ac_no: cd_ac_no
},
success: function(response) {
// Handle success response
toastr.success("Transaction saved successfully", "Success");
// Reload the page or perform other actions as needed
if (typeof window.storeCurrentDepositTablePage === 'function') {
window.storeCurrentDepositTablePage();
}
location.reload();
},
error: function(xhr, status, error) {
console.error(xhr.responseText);
console.error(status, error);
if (xhr.status === 400) {
let response = JSON.parse(xhr.responseText);
let errorMessages = "";
let seenMessages = []; // Array to store unique messages
if (response.errors) {
$.each(response.errors, function (field, message) {
if (!seenMessages.includes(message)) {
errorMessages += `• ${message}<br>`;
seenMessages.push(message); // Mark this message as "seen"
}
});
toastr.error(errorMessages, 'Validation Error', { "allowHtml": true });
} else {
toastr.warning(response.message || 'Validation failed', 'Warning');
}
} else if (xhr.status === 403) {
let response = JSON.parse(xhr.responseText);
toastr.error(response.message, 'Security Policy');
} else if (xhr.status === 500) {
toastr.error('Something went wrong . Please try again later.', 'Server Error');
} else {
toastr.error('An unexpected error occurred. Please try again later.', 'Error');
}
if (typeof window.storeCurrentDepositTablePage === 'function') {
window.storeCurrentDepositTablePage();
}
location.reload(); // Uncomment if you need to reload the page on error
}
});
});
});
</script>
<script>
$(document).on('input', '#amount', function () {
var value = $(this).val();
value = value.replace(/[^0-9.]/g, '');
var parts = value.split('.');
if (parts.length > 2) {
value = parts[0] + '.' + parts.slice(1).join('');
parts = value.split('.');
}
if (parts[1] && parts[1].length > 2) {
value = parts[0] + '.' + parts[1].slice(0, 2);
}
$(this).val(value);
if (value.length) {
$('#amount_error').hide().text('');
$(this).removeClass('is-invalid');
}
});
</script>
<script>
$(document).ready(function () {
var numericRegex = /^[0-9]+(\.[0-9]{1,2})?$/;
function formatAmount(value) {
var num = parseFloat(value);
if (isNaN(num)) {
return '0.00';
}
return num.toFixed(2);
}
function normalizeInput($input) {
var value = ($input.val() || '').replace(/[^0-9.]/g, '');
var parts = value.split('.');
if (parts.length > 2) {
value = parts[0] + '.' + parts.slice(1).join('');
parts = value.split('.');
}
if (parts[1] && parts[1].length > 2) {
value = parts[0] + '.' + parts[1].slice(0, 2);
}
$input.val(value);
}
function setRowDisplay($row, creditAmount, debitAmount) {
var $creditCell = $row.find('td[data-type="credit"]');
var $debitCell = $row.find('td[data-type="debit"]');
var creditNum = parseFloat(creditAmount) || 0;
var debitNum = parseFloat(debitAmount) || 0;
$row.attr('data-credit', creditNum);
$row.attr('data-debit', debitNum);
$creditCell.find('.deposit-inline-input').val(creditNum > 0 ? formatAmount(creditNum) : '');
$debitCell.find('.deposit-inline-input').val(debitNum > 0 ? formatAmount(debitNum) : '');
}
function recalculateVisibleBalances() {
var running = 0;
var rows = $('#scroll-horizontal-datatable tbody tr').get().reverse();
$(rows).each(function () {
var $row = $(this);
var credit = parseFloat($row.attr('data-credit')) || 0;
var debit = parseFloat($row.attr('data-debit')) || 0;
running += credit;
running -= debit;
$row.find('.deposit-balance-cell').text(formatAmount(running));
});
}
function getTopSaveButton() {
return $('.deposit-top-save-btn');
}
function hasPendingChanges() {
var pending = false;
$('#scroll-horizontal-datatable tbody tr').each(function () {
var $row = $(this);
var creditInputVal = ($row.find('td[data-type="credit"] .deposit-inline-input').val() || '').trim();
var debitInputVal = ($row.find('td[data-type="debit"] .deposit-inline-input').val() || '').trim();
var originalCredit = parseFloat($row.attr('data-credit')) || 0;
var originalDebit = parseFloat($row.attr('data-debit')) || 0;
var inputCredit = creditInputVal === '' ? 0 : parseFloat(creditInputVal);
var inputDebit = debitInputVal === '' ? 0 : parseFloat(debitInputVal);
var descriptionVal = ($row.find('.deposit-description-input').val() || '').trim();
var originalDescription = ($row.attr('data-description') || '').trim();
if (descriptionVal !== originalDescription) {
pending = true;
return false;
}
if (isNaN(inputCredit) || isNaN(inputDebit)) {
return;
}
if (Math.abs(inputCredit - originalCredit) > 0.0001 || Math.abs(inputDebit - originalDebit) > 0.0001) {
pending = true;
return false;
}
});
return pending;
}
function updateTopSaveButtonVisibility() {
var $saveBtn = getTopSaveButton();
if (!$saveBtn.length) {
return;
}
$saveBtn.toggleClass('d-none', !hasPendingChanges());
}
$(document).on('input', '.deposit-inline-input', function () {
var $input = $(this);
normalizeInput($input);
updateTopSaveButtonVisibility();
});
$(document).on('input change', '.deposit-description-input', function () {
var $input = $(this);
$input.attr('title', ($input.val() || '').trim());
updateTopSaveButtonVisibility();
});
function collectChanges() {
var changes = [];
var hasValidationError = false;
$('#scroll-horizontal-datatable tbody tr').each(function () {
var $row = $(this);
var creditInputVal = ($row.find('td[data-type="credit"] .deposit-inline-input').val() || '').trim();
var debitInputVal = ($row.find('td[data-type="debit"] .deposit-inline-input').val() || '').trim();
var originalCredit = parseFloat($row.attr('data-credit')) || 0;
var originalDebit = parseFloat($row.attr('data-debit')) || 0;
var hasCredit = creditInputVal !== '';
var hasDebit = debitInputVal !== '';
if (!hasCredit && !hasDebit) {
return;
}
if (hasCredit && hasDebit) {
toastr.warning('Please fill only one of Credit or Debit per row.');
hasValidationError = true;
return false;
}
var type = hasCredit ? 'credit' : 'debit';
var value = hasCredit ? creditInputVal : debitInputVal;
var amount = parseFloat(value);
var isChanged = (type === 'credit')
? (Math.abs(amount - originalCredit) > 0.0001)
: (Math.abs(amount - originalDebit) > 0.0001);
// Skip untouched rows (important for legacy 0/-ve values)
if (!isChanged) {
return;
}
if (!numericRegex.test(value)) {
toastr.warning('Enter a valid amount (up to 2 decimals).');
hasValidationError = true;
return false;
}
if (amount <= 0) {
toastr.warning('Amount must be greater than 0.');
hasValidationError = true;
return false;
}
changes.push({
rowId: $row.data('row-id'),
type: type,
amount: amount,
$row: $row
});
});
if (hasValidationError) {
return false;
}
return changes;
}
function collectDescriptionChanges() {
var changes = [];
var hasValidationError = false;
$('#scroll-horizontal-datatable tbody tr').each(function () {
var $row = $(this);
var $input = $row.find('.deposit-description-input');
if (!$input.length) {
return;
}
var current = ($input.val() || '').trim();
var original = ($row.attr('data-description') || '').trim();
if (current === original) {
return;
}
if (current === '') {
toastr.warning('Description cannot be empty.');
hasValidationError = true;
return false;
}
if (current.length > 1000) {
toastr.warning('Description must not exceed 1000 characters.');
hasValidationError = true;
return false;
}
changes.push({
rowId: $row.data('row-id'),
description: current,
$row: $row
});
});
if (hasValidationError) {
return false;
}
return changes;
}
window.saveDepositInlineChanges = function () {
var changes = collectChanges();
var descriptionChanges = collectDescriptionChanges();
if (changes === false || descriptionChanges === false) {
return;
}
if ((!Array.isArray(changes) || changes.length === 0) &&
(!Array.isArray(descriptionChanges) || descriptionChanges.length === 0)) {
toastr.info('No changes to save.');
return;
}
var clientId = '<?= esc((string) $clientData->id, 'js') ?>';
var insurerId = '<?= esc((string) $insurerName->id, 'js') ?>';
var cdAcPk = $('#cd_ac_pk').val();
var completed = 0;
var totalChanges = changes.length + descriptionChanges.length;
function finishSave() {
toastr.success('Saved ' + completed + ' change(s) successfully.');
setTimeout(function () {
if (typeof window.storeCurrentDepositTablePage === 'function') {
window.storeCurrentDepositTablePage();
}
location.reload();
}, 250);
}
function saveDescriptionNext(index) {
if (index >= descriptionChanges.length) {
finishSave();
return;
}
var change = descriptionChanges[index];
$.ajax({
type: 'POST',
url: '<?= base_url() . "client/update_deposit_description" ?>',
data: {
deposit_id: change.rowId,
description: change.description,
client_id: clientId,
insurer_id: insurerId,
cd_ac_pk: cdAcPk
},
success: function () {
change.$row.attr('data-description', change.description);
change.$row.find('.deposit-description-input').attr('title', change.description);
completed++;
saveDescriptionNext(index + 1);
},
error: function (xhr) {
if (xhr.status === 400 && xhr.responseText) {
try {
var response = JSON.parse(xhr.responseText);
toastr.error(response.message || 'Validation failed.');
} catch (e) {
toastr.error('Validation failed.');
}
} else if (xhr.status === 404) {
toastr.error('Transaction not found for this account.');
} else {
toastr.error('Unable to update description right now.');
}
}
});
}
function saveAmountNext(index) {
if (index >= changes.length) {
saveDescriptionNext(0);
return;
}
var change = changes[index];
var transactionType = (change.type === 'credit') ? 'Credit' : 'Debit';
$.ajax({
type: 'POST',
url: '<?= base_url() . "client/update_deposit_amount" ?>',
data: {
deposit_id: change.rowId,
amount: change.amount,
transaction_type: transactionType,
client_id: clientId,
insurer_id: insurerId,
cd_ac_pk: cdAcPk
},
success: function () {
if (transactionType === 'Credit') {
setRowDisplay(change.$row, change.amount, 0);
} else {
setRowDisplay(change.$row, 0, change.amount);
}
completed++;
saveAmountNext(index + 1);
},
error: function (xhr) {
if (xhr.status === 400 && xhr.responseText) {
try {
var response = JSON.parse(xhr.responseText);
toastr.error(response.message || 'Validation failed.');
} catch (e) {
toastr.error('Validation failed.');
}
} else if (xhr.status === 404) {
toastr.error('Transaction not found for this account.');
} else {
toastr.error('Unable to update transaction right now.');
}
}
});
}
if (totalChanges === 0) {
toastr.info('No changes to save.');
return;
}
saveAmountNext(0);
};
$(document).on('keydown', '.deposit-inline-input', function (e) {
if (e.key === 'Enter') {
e.preventDefault();
if (typeof window.saveDepositInlineChanges === 'function') {
window.saveDepositInlineChanges();
}
}
});
$(document).on('keydown', '.deposit-description-input', function (e) {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
if (typeof window.saveDepositInlineChanges === 'function') {
window.saveDepositInlineChanges();
}
}
});
updateTopSaveButtonVisibility();
});
</script>