581 lines
23 KiB
PHP
581 lines
23 KiB
PHP
<?= $this->extend('layout/management_layout') ?>
|
|
<?= $this->section('content') ?>
|
|
|
|
<div class="container mt-4">
|
|
<h2 class="text-center mt-4 mb-3">Manual Payment</h2>
|
|
|
|
<?php if (session()->getFlashdata('success')): ?>
|
|
<div class="alert alert-success"><?= session()->getFlashdata('success') ?></div>
|
|
<?php endif; ?>
|
|
<?php if (session()->getFlashdata('error')): ?>
|
|
<div class="alert alert-danger"><?= session()->getFlashdata('error') ?></div>
|
|
<?php endif; ?>
|
|
|
|
<!-- Search form -->
|
|
<form method="get" action="<?= base_url('payment/manual_pay') ?>" class="mb-3">
|
|
<div class="input-group">
|
|
<input type="text" name="search_term" class="form-control" placeholder="Enter Parent Email or Phone" required value="<?= esc($searchTermUsedInSearch ?? '') ?>">
|
|
<button class="btn btn-primary" type="submit">Search</button>
|
|
</div>
|
|
</form>
|
|
|
|
<?php if ($parent): ?>
|
|
<!-- Parent + Student info -->
|
|
<div class="row mb-4">
|
|
<div class="col-md-6">
|
|
<div class="card">
|
|
<div class="card-header">Parent Information</div>
|
|
<div class="card-body">
|
|
<p><strong>Name:</strong> <?= esc($parent['firstname']) ?> <?= esc($parent['lastname']) ?></p>
|
|
<p><strong>Phone:</strong> <?= esc($parent['cellphone']) ?></p>
|
|
<p><strong>Email:</strong> <?= esc($parent['email']) ?></p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="card">
|
|
<div class="card-header">Students</div>
|
|
<div class="card-body">
|
|
<?php if (!empty($students)): ?>
|
|
<ul class="list-group">
|
|
<?php foreach ($students as $student): ?>
|
|
<li class="list-group-item"><?= esc($student['firstname']) ?> <?= esc($student['lastname']) ?></li>
|
|
<?php endforeach; ?>
|
|
</ul>
|
|
<?php else: ?>
|
|
<p>No students found.</p>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Payments table -->
|
|
<h5>Payments</h5>
|
|
<table class="table table-bordered">
|
|
<thead>
|
|
<tr>
|
|
<th>Paid Date</th>
|
|
<th>Paid Amount</th>
|
|
<th>Balance</th>
|
|
<th>Payment Method</th>
|
|
<th>Check Number</th>
|
|
<th>Installments</th>
|
|
<th>Status</th>
|
|
<th>Check/Card File</th>
|
|
<th>Action</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach ($payments as $payment): ?>
|
|
<tr>
|
|
<td><?= $payment['payment_date']->format('m-d-Y h:i A') ?></td>
|
|
<td>$<?= number_format((float)$payment['paid_amount'], 2) ?></td>
|
|
<td>$<?= number_format((float)$payment['balance'], 2) ?></td>
|
|
<td>
|
|
<?php
|
|
$method = strtolower((string)$payment['payment_method']);
|
|
if ($method === 'cash') {
|
|
echo '<span class="badge" style="background-color:#28a745;color:#fff;">Cash</span>';
|
|
} elseif ($method === 'check') {
|
|
echo '<span class="badge" style="background-color:#1ba2b9;color:#fff;">Check</span>';
|
|
} elseif ($method === 'card' || $method === 'debit/credit card') {
|
|
echo '<span class="badge" style="background-color:#007bff;color:#fff;">Card</span>';
|
|
} else {
|
|
echo '<span class="badge bg-secondary">' . esc($payment['payment_method']) . '</span>';
|
|
}
|
|
?>
|
|
</td>
|
|
<td><?= !empty($payment['check_number']) ? esc($payment['check_number']) : '-' ?></td>
|
|
<td><?= esc($payment['number_of_installments']) ?></td>
|
|
<td><?= esc($payment['status']) ?></td>
|
|
<td>
|
|
<?php if (!empty($payment['check_file'])): ?>
|
|
<!-- Trigger Modal -->
|
|
<a href="#" data-bs-toggle="modal" data-bs-target="#checkModal<?= (int)$payment['id'] ?>">View</a> /
|
|
<a href="<?= base_url('payment/file/' . (int) $payment['id'] . '/download') ?>">Download</a>
|
|
|
|
<!-- Modal -->
|
|
<div class="modal fade" id="checkModal<?= (int)$payment['id'] ?>" tabindex="-1" aria-hidden="true">
|
|
<div class="modal-dialog modal-dialog-centered modal-lg">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">Check Preview</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body text-center">
|
|
<iframe src="<?= base_url('payment/file/' . (int) $payment['id'] . '/inline') ?>"
|
|
width="100%" height="600px" style="border:none;"></iframe>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<?php else: ?>
|
|
-
|
|
<?php endif; ?>
|
|
</td>
|
|
<td>
|
|
<button class="btn btn-sm btn-secondary" data-bs-toggle="modal" data-bs-target="#editPaymentModal<?= (int)$payment['id'] ?>">Edit</button>
|
|
</td>
|
|
</tr>
|
|
|
|
<!-- Edit Payment Modal -->
|
|
<div class="modal fade" id="editPaymentModal<?= (int)$payment['id'] ?>" tabindex="-1" aria-labelledby="editPaymentModalLabel<?= (int)$payment['id'] ?>" aria-hidden="true">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<form method="post" action="<?= base_url('payment/manual_pay_edit') ?>" enctype="multipart/form-data">
|
|
<?= csrf_field() ?>
|
|
<input type="hidden" name="payment_id" value="<?= (int)$payment['id'] ?>">
|
|
<input type="hidden" name="search_term" value="<?= esc($searchTermUsedInSearch ?? '') ?>">
|
|
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="editPaymentModalLabel<?= (int)$payment['id'] ?>">Edit Payment ID <?= (int)$payment['id'] ?></h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="mb-3">
|
|
<label>Paid Amount</label>
|
|
<input type="number" step="0.01" name="paid_amount" class="form-control" value="<?= esc($payment['paid_amount']) ?>" required>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label>Payment Method</label>
|
|
<select name="payment_method" class="form-select edit-payment-method"
|
|
data-payment-id="<?= (int)$payment['id'] ?>"
|
|
onchange="toggleEditFields(<?= (int)$payment['id'] ?>)" required>
|
|
<option value="Cash" <?= ($payment['payment_method'] === 'Cash') ? 'selected' : '' ?>>Cash</option>
|
|
<option value="Check" <?= ($payment['payment_method'] === 'Check') ? 'selected' : '' ?>>Check</option>
|
|
<option value="Card" <?= ($payment['payment_method'] === 'Card') ? 'selected' : '' ?>>Debit/Credit Card</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="mb-3 check-number-edit" id="check-number-edit-<?= (int)$payment['id'] ?>" style="display:none;">
|
|
<label>Check Number</label>
|
|
<input type="text" name="check_number" class="form-control"
|
|
value="<?= !empty($payment['check_number']) ? esc($payment['check_number']) : '' ?>">
|
|
</div>
|
|
|
|
<div class="mb-3" id="payment-file-edit-<?= (int)$payment['id'] ?>" style="display:none;">
|
|
<label>Replace Payment File (optional)</label>
|
|
<input type="file" name="payment_file" class="form-control" accept=".jpg,.jpeg,.png,.pdf">
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="submit" class="btn btn-success">Save Changes</button>
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
|
|
<?php if (isset($pager)): ?>
|
|
<div class="d-flex justify-content-center">
|
|
<?= $pager->links() ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<!-- Invoices -->
|
|
<?php if (!empty($invoices)): ?>
|
|
<h5>Invoices</h5>
|
|
<table class="table table-bordered">
|
|
<thead>
|
|
<tr>
|
|
<th>Invoice #</th>
|
|
<th>Total</th>
|
|
<th>Paid</th>
|
|
<th>Balance</th>
|
|
<th>Status</th>
|
|
<th>Due Date</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach ($invoices as $invoice): ?>
|
|
<?php
|
|
$dueDisp = '-';
|
|
if (!empty($invoice['due_date'])) {
|
|
$dueDisp = local_date($invoice['due_date'], 'm-d-Y');
|
|
}
|
|
?>
|
|
<tr>
|
|
<td><?= esc($invoice['invoice_number']) ?></td>
|
|
<td>$<?= number_format((float)$invoice['total_amount'], 2) ?></td>
|
|
<td>$<?= number_format((float)$invoice['paid_amount'], 2) ?></td>
|
|
<td>$<?= number_format((float)$invoice['balance'], 2) ?></td>
|
|
<td><?= esc($invoice['status']) ?></td>
|
|
<td><?= esc($dueDisp) ?></td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
<?php endif; ?>
|
|
|
|
<div class="text-end mb-3">
|
|
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addPaymentModal">Add Payment</button>
|
|
</div>
|
|
|
|
<?php elseif (isset($parent)): ?>
|
|
<p class="text-danger">Parent found but no payment records.</p>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<!-- Add Payment Modal -->
|
|
<div class="modal fade" id="addPaymentModal" tabindex="-1" aria-labelledby="addPaymentModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<!-- IMPORTANT: post to existing POST route payment/manual_pay -->
|
|
<form method="post" action="<?= base_url('payment/manual_pay') ?>" id="addPaymentForm" enctype="multipart/form-data">
|
|
<?= csrf_field() ?>
|
|
<input type="hidden" name="search_term" value="<?= esc($searchTermUsedInSearch ?? '') ?>">
|
|
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="addPaymentModalLabel">Add Manual Payment</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
</div>
|
|
|
|
<div class="modal-body">
|
|
<!-- Invoice select with per-invoice data for JS -->
|
|
<div class="mb-3">
|
|
<label for="invoice_id" class="form-label">Select Invoice</label>
|
|
<select
|
|
name="invoice_id"
|
|
id="invoice_id"
|
|
class="form-select"
|
|
required
|
|
onchange="onInvoiceChange(this)"
|
|
data-end-date="<?= esc($installmentEndYmd) ?>">
|
|
<?php if (!empty($invoices)): ?>
|
|
<?php foreach ($invoices as $invoice): ?>
|
|
<option
|
|
value="<?= (int)$invoice['id'] ?>"
|
|
data-balance="<?= esc($invoice['balance']) ?>">
|
|
Invoice <?= esc($invoice['invoice_number']) ?> |
|
|
Balance: $<?= number_format((float)$invoice['balance'], 2) ?> |
|
|
Paid: $<?= number_format((float)$invoice['paid_amount'], 2) ?>
|
|
</option>
|
|
<?php endforeach; ?>
|
|
<?php else: ?>
|
|
<option value="">No invoices available</option>
|
|
<?php endif; ?>
|
|
</select>
|
|
</div>
|
|
|
|
<!-- Method -->
|
|
<div class="mb-3">
|
|
<label for="payment_method" class="form-label">Payment Method</label>
|
|
<select name="payment_method" id="payment_method" class="form-select" required onchange="togglePaymentFieldsAdd()">
|
|
<option value="">Select Method</option>
|
|
<option value="cash">Cash</option>
|
|
<option value="check">Check</option>
|
|
<option value="card">Debit/Credit Card</option>
|
|
</select>
|
|
</div>
|
|
|
|
<!-- Check number (only for checks) -->
|
|
<div class="mb-3" id="check-number-field" style="display:none;">
|
|
<label for="check_number" class="form-label">Check Number</label>
|
|
<input type="text" name="check_number" id="check_number" class="form-control">
|
|
</div>
|
|
|
|
<!-- Receipt upload (check/card) -->
|
|
<div class="mb-3" id="payment-upload" style="display:none;">
|
|
<label for="payment_file" class="form-label">Upload File</label>
|
|
<input type="file" name="payment_file" id="payment_file" class="form-control" accept=".jpg,.jpeg,.png,.pdf">
|
|
</div>
|
|
|
|
<!-- Payment type -->
|
|
<div class="mb-3">
|
|
<label for="payment_type" class="form-label">Payment Type</label>
|
|
<select name="payment_type" id="payment_type" class="form-select" required onchange="toggleInstallmentFields()">
|
|
<option value="full">Full Payment</option>
|
|
<option value="installment">Installment Payment</option>
|
|
</select>
|
|
</div>
|
|
|
|
<!-- Installment section -->
|
|
<div id="installment-section" style="display:none;">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label for="installment_count" class="form-label">Number of Installments</label>
|
|
<select name="installment_count" id="installment_count" class="form-select" onchange="recalcInstallments()"></select>
|
|
<div class="form-text">Maximum installments available: <span id="max-installments">0</span></div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label for="installment_amount" class="form-label">Amount per Installment</label>
|
|
<input type="number" step="0.01" name="installment_amount" id="installment_amount" class="form-control" readonly>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="text-muted small">
|
|
Choose the number of installments (up to the maximum available). The first payment is due today.
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Amount -->
|
|
<div class="mb-3">
|
|
<label for="amount" class="form-label">Amount</label>
|
|
<input type="number" step="0.01" name="amount" id="amount" class="form-control" required>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="modal-footer">
|
|
<button type="submit" class="btn btn-success">Submit Payment</button>
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- End Payment Modal -->
|
|
|
|
<?= $this->endSection() ?>
|
|
|
|
<?= $this->section('scripts') ?>
|
|
<script>
|
|
// =========================
|
|
// Helpers
|
|
// =========================
|
|
function el(id) {
|
|
return document.getElementById(id);
|
|
}
|
|
|
|
function parseYMD(ymd) {
|
|
if (typeof ymd !== 'string') return null;
|
|
const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(ymd.trim());
|
|
if (!m) return null;
|
|
const y = +m[1],
|
|
mo = +m[2],
|
|
d = +m[3];
|
|
const dt = new Date(y, mo - 1, d);
|
|
if (dt.getFullYear() !== y || dt.getMonth() !== mo - 1 || dt.getDate() !== d) return null;
|
|
return dt;
|
|
}
|
|
|
|
function todayYMD() {
|
|
const t = new Date();
|
|
const y = t.getFullYear();
|
|
const m = String(t.getMonth() + 1).padStart(2, '0');
|
|
const d = String(t.getDate()).padStart(2, '0');
|
|
return `${y}-${m}-${d}`;
|
|
}
|
|
|
|
// Months between TODAY and end date. Always >= 1.
|
|
function calculateInstallmentsFromToday(endDateStr) {
|
|
const start = parseYMD(todayYMD());
|
|
const end = parseYMD(endDateStr);
|
|
if (!start || !end) return 1;
|
|
if (end.getTime() < start.getTime()) return 1;
|
|
|
|
let months = (end.getFullYear() - start.getFullYear()) * 12 +
|
|
(end.getMonth() - start.getMonth());
|
|
if (end.getDate() > start.getDate()) months += 1;
|
|
|
|
return Math.max(1, months);
|
|
}
|
|
|
|
// =========================
|
|
// State
|
|
// =========================
|
|
let currentInvoiceBalance = 0;
|
|
let maxInstallmentNumber = 1;
|
|
|
|
// =========================
|
|
// Edit modal helpers
|
|
// =========================
|
|
function toggleEditFields(paymentId) {
|
|
const select = document.querySelector(`select[data-payment-id='${paymentId}']`);
|
|
const checkField = document.getElementById(`check-number-edit-${paymentId}`);
|
|
const fileField = document.getElementById(`payment-file-edit-${paymentId}`);
|
|
const input = checkField ? checkField.querySelector('input') : null;
|
|
if (!select || !checkField || !fileField || !input) return;
|
|
|
|
const v = (select.value || '').toLowerCase();
|
|
if (v === 'check') {
|
|
checkField.style.display = 'block';
|
|
fileField.style.display = 'block';
|
|
input.required = true;
|
|
} else if (v === 'card') {
|
|
checkField.style.display = 'none';
|
|
fileField.style.display = 'block';
|
|
input.required = false;
|
|
} else {
|
|
checkField.style.display = 'none';
|
|
fileField.style.display = 'none';
|
|
input.required = false;
|
|
}
|
|
}
|
|
|
|
// =========================
|
|
// Add Payment modal logic
|
|
// =========================
|
|
function onInvoiceChange(select) {
|
|
const opt = select.options[select.selectedIndex];
|
|
currentInvoiceBalance = parseFloat(opt?.dataset?.balance || '0') || 0;
|
|
|
|
// READ FROM THE SELECT (it has data-end-date)
|
|
const endDate = select?.dataset?.endDate || select.getAttribute('data-end-date') || '';
|
|
|
|
const computed = calculateInstallmentsFromToday(endDate);
|
|
maxInstallmentNumber = computed;
|
|
|
|
const maxSpan = el('max-installments');
|
|
if (maxSpan) maxSpan.textContent = String(maxInstallmentNumber);
|
|
|
|
populateInstallmentOptions();
|
|
toggleInstallmentFields();
|
|
recalcInstallments();
|
|
updateAmountField();
|
|
}
|
|
|
|
function populateInstallmentOptions() {
|
|
const countSelect = el('installment_count');
|
|
if (!countSelect) return;
|
|
|
|
countSelect.innerHTML = '';
|
|
for (let i = 1; i <= maxInstallmentNumber; i++) {
|
|
const option = document.createElement('option');
|
|
option.value = i;
|
|
option.textContent = i + (i === 1 ? ' installment' : ' installments');
|
|
countSelect.appendChild(option);
|
|
}
|
|
countSelect.value = String(maxInstallmentNumber);
|
|
}
|
|
|
|
function togglePaymentFieldsAdd() {
|
|
const method = (el('payment_method').value || '').toLowerCase();
|
|
const checkField = el('check-number-field');
|
|
const fileField = el('payment-upload');
|
|
const checkInput = el('check_number');
|
|
const ptype = el('payment_type');
|
|
const section = el('installment-section');
|
|
|
|
if (method === 'check') {
|
|
if (checkField) checkField.style.display = 'block';
|
|
if (fileField) fileField.style.display = 'block';
|
|
if (checkInput) checkInput.required = true;
|
|
if (ptype) ptype.disabled = false;
|
|
} else if (method === 'card') {
|
|
if (checkField) checkField.style.display = 'none';
|
|
if (fileField) fileField.style.display = 'block';
|
|
if (checkInput) checkInput.required = false;
|
|
if (ptype) {
|
|
ptype.value = 'full';
|
|
ptype.disabled = true;
|
|
}
|
|
if (section) section.style.display = 'none';
|
|
} else {
|
|
if (checkField) checkField.style.display = 'none';
|
|
if (fileField) fileField.style.display = 'none';
|
|
if (checkInput) checkInput.required = false;
|
|
if (ptype) ptype.disabled = false;
|
|
toggleInstallmentFields();
|
|
}
|
|
updateAmountField();
|
|
}
|
|
|
|
function toggleInstallmentFields() {
|
|
const method = (el('payment_method').value || '').toLowerCase();
|
|
const type = el('payment_type') ? el('payment_type').value : 'full';
|
|
const section = el('installment-section');
|
|
|
|
if (method === 'card') {
|
|
if (section) section.style.display = 'none';
|
|
return;
|
|
}
|
|
|
|
if (section) section.style.display = (type === 'installment') ? 'block' : 'none';
|
|
|
|
if (type === 'installment') {
|
|
populateInstallmentOptions();
|
|
}
|
|
}
|
|
|
|
function recalcInstallments() {
|
|
const method = (el('payment_method').value || '').toLowerCase();
|
|
const type = el('payment_type') ? el('payment_type').value : 'full';
|
|
const countSelect = el('installment_count');
|
|
const amtEl = el('installment_amount');
|
|
|
|
if (!countSelect || !amtEl) return;
|
|
|
|
if (type !== 'installment' || method === 'card') {
|
|
amtEl.value = '';
|
|
return;
|
|
}
|
|
|
|
const selected = parseInt(countSelect.value || '1', 10);
|
|
const raw = (currentInvoiceBalance > 0 ? (currentInvoiceBalance / selected) : 0);
|
|
const rounded = (Math.round(raw * 100) / 100).toFixed(2);
|
|
amtEl.value = rounded;
|
|
|
|
updateAmountField();
|
|
}
|
|
|
|
function updateAmountField() {
|
|
const method = (el('payment_method').value || '').toLowerCase();
|
|
const type = el('payment_type') ? el('payment_type').value : 'full';
|
|
const amountInput = el('amount');
|
|
|
|
if (!amountInput) return;
|
|
|
|
if (method === 'card' || type === 'full') {
|
|
amountInput.value = (currentInvoiceBalance || 0).toFixed(2);
|
|
} else {
|
|
const installmentAmount = el('installment_amount') ? (el('installment_amount').value || '0') : '0';
|
|
amountInput.value = installmentAmount;
|
|
}
|
|
}
|
|
|
|
// =========================
|
|
// Init
|
|
// =========================
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// Initialize edit modals
|
|
document.querySelectorAll('.edit-payment-method').forEach(select => {
|
|
const id = select.getAttribute('data-payment-id');
|
|
toggleEditFields(id);
|
|
select.addEventListener('change', () => toggleEditFields(id));
|
|
});
|
|
|
|
// Wire Add Payment modal
|
|
const invoiceSelect = el('invoice_id');
|
|
if (invoiceSelect && invoiceSelect.options.length > 0) {
|
|
invoiceSelect.addEventListener('change', function() {
|
|
onInvoiceChange(this);
|
|
});
|
|
onInvoiceChange(invoiceSelect); // initial compute
|
|
}
|
|
|
|
const paymentTypeSel = el('payment_type');
|
|
if (paymentTypeSel) {
|
|
paymentTypeSel.addEventListener('change', function() {
|
|
toggleInstallmentFields();
|
|
recalcInstallments();
|
|
updateAmountField();
|
|
});
|
|
}
|
|
|
|
const paymentMethodSel = el('payment_method');
|
|
if (paymentMethodSel) {
|
|
paymentMethodSel.addEventListener('change', function() {
|
|
togglePaymentFieldsAdd();
|
|
recalcInstallments();
|
|
updateAmountField();
|
|
});
|
|
}
|
|
|
|
const installmentCountSel = el('installment_count');
|
|
if (installmentCountSel) {
|
|
installmentCountSel.addEventListener('change', function() {
|
|
recalcInstallments();
|
|
});
|
|
}
|
|
});
|
|
</script>
|
|
<?= $this->endSection() ?>
|