38086-vm/accounting/templates/accounting/journal_entry_form.html
2026-02-03 03:44:40 +00:00

203 lines
11 KiB
HTML

{% extends 'base.html' %}
{% load i18n %}
{% block content %}
<div class="container-fluid py-4">
<div class="row justify-content-center">
<div class="col-lg-10">
<div class="d-flex justify-content-between align-items-center mb-4">
<div>
<nav aria-label="breadcrumb">
<ol class="breadcrumb mb-1">
<li class="breadcrumb-item"><a href="{% url 'accounting_dashboard' %}">{% trans "Accounting" %}</a></li>
<li class="breadcrumb-item"><a href="{% url 'journal_entries' %}">{% trans "Journal Entries" %}</a></li>
<li class="breadcrumb-item active">{% trans "New Manual Entry" %}</li>
</ol>
</nav>
<h2 class="mb-0">{% trans "New Manual Journal Entry" %}</h2>
</div>
</div>
<form method="post" id="journal-form">
{% csrf_token %}
<div class="card border-0 shadow-sm mb-4">
<div class="card-body p-4">
<div class="row g-3">
<div class="col-md-3">
<label class="form-label">{% trans "Date" %}</label>
{{ form.date }}
</div>
<div class="col-md-3">
<label class="form-label">{% trans "Reference" %}</label>
{{ form.reference }}
</div>
<div class="col-md-6">
<label class="form-label">{% trans "Description" %}</label>
{{ form.description }}
</div>
</div>
</div>
</div>
<div class="card border-0 shadow-sm">
<div class="table-responsive">
<table class="table table-hover align-middle mb-0" id="items-table">
<thead class="bg-light">
<tr>
<th style="width: 40%;">{% trans "Account" %}</th>
<th style="width: 20%;">{% trans "Type" %}</th>
<th style="width: 30%;">{% trans "Amount" %}</th>
<th style="width: 10%;"></th>
</tr>
</thead>
<tbody>
<tr class="item-row">
<td>
<select name="account[]" class="form-select select2-account" required>
<option value="">{% trans "Select Account" %}</option>
{% for acc in accounts %}
<option value="{{ acc.id }}">{{ acc.code }} - {% if LANGUAGE_CODE == 'ar' %}{{ acc.name_ar }}{% else %}{{ acc.name_en }}{% endif %}</option>
{% endfor %}
</select>
</td>
<td>
<select name="type[]" class="form-select item-type" required>
<option value="debit">{% trans "Debit" %}</option>
<option value="credit">{% trans "Credit" %}</option>
</select>
</td>
<td>
<div class="input-group">
<input type="number" name="amount[]" class="form-control item-amount" step="0.001" min="0" required>
<span class="input-group-text">{{ global_settings.currency_symbol }}</span>
</div>
</td>
<td class="text-center">
<button type="button" class="btn btn-outline-danger btn-sm remove-row"><i class="bi bi-trash"></i></button>
</td>
</tr>
<tr class="item-row">
<td>
<select name="account[]" class="form-select select2-account" required>
<option value="">{% trans "Select Account" %}</option>
{% for acc in accounts %}
<option value="{{ acc.id }}">{{ acc.code }} - {% if LANGUAGE_CODE == 'ar' %}{{ acc.name_ar }}{% else %}{{ acc.name_en }}{% endif %}</option>
{% endfor %}
</select>
</td>
<td>
<select name="type[]" class="form-select item-type" required>
<option value="debit">{% trans "Debit" %}</option>
<option value="credit" selected>{% trans "Credit" %}</option>
</select>
</td>
<td>
<div class="input-group">
<input type="number" name="amount[]" class="form-control item-amount" step="0.001" min="0" required>
<span class="input-group-text">{{ global_settings.currency_symbol }}</span>
</div>
</td>
<td class="text-center">
<button type="button" class="btn btn-outline-danger btn-sm remove-row"><i class="bi bi-trash"></i></button>
</td>
</tr>
</tbody>
<tfoot class="bg-light">
<tr>
<td colspan="4">
<button type="button" class="btn btn-outline-primary btn-sm" id="add-row">
<i class="bi bi-plus-lg"></i> {% trans "Add Line" %}
</button>
</td>
</tr>
<tr class="fw-bold">
<td class="text-end">{% trans "Totals" %}:</td>
<td class="text-end">{% trans "Debit" %}: <span id="total-debit">0.000</span></td>
<td class="text-end">{% trans "Credit" %}: <span id="total-credit">0.000</span></td>
<td></td>
</tr>
<tr>
<td colspan="4" class="text-center py-2" id="balance-message">
<span class="badge bg-danger">{% trans "Out of Balance" %}</span>
</td>
</tr>
</tfoot>
</table>
</div>
<div class="card-footer bg-white p-4 border-top d-flex justify-content-end gap-2">
<a href="{% url 'journal_entries' %}" class="btn btn-light">{% trans "Cancel" %}</a>
<button type="submit" class="btn btn-primary px-4" id="submit-btn" disabled>{% trans "Create Entry" %}</button>
</div>
</div>
</form>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const table = document.getElementById('items-table').getElementsByTagName('tbody')[0];
const addBtn = document.getElementById('add-row');
const totalDebitSpan = document.getElementById('total-debit');
const totalCreditSpan = document.getElementById('total-credit');
const balanceMessage = document.getElementById('balance-message');
const submitBtn = document.getElementById('submit-btn');
function updateTotals() {
let totalDebit = 0;
let totalCredit = 0;
document.querySelectorAll('.item-row').forEach(row => {
const type = row.querySelector('.item-type').value;
const amount = parseFloat(row.querySelector('.item-amount').value) || 0;
if (type === 'debit') totalDebit += amount;
else totalCredit += amount;
});
totalDebitSpan.textContent = totalDebit.toFixed(3);
totalCreditSpan.textContent = totalCredit.toFixed(3);
const balanced = totalDebit > 0 && Math.abs(totalDebit - totalCredit) < 0.001;
if (balanced) {
balanceMessage.innerHTML = '<span class="badge bg-success">{% trans "Balanced" %}</span>';
submitBtn.disabled = false;
} else {
balanceMessage.innerHTML = '<span class="badge bg-danger">{% trans "Out of Balance" %}</span>';
submitBtn.disabled = true;
}
}
addBtn.addEventListener('click', function() {
const firstRow = document.querySelector('.item-row');
const newRow = firstRow.cloneNode(true);
newRow.querySelector('.item-amount').value = '';
table.appendChild(newRow);
newRow.querySelector('.remove-row').addEventListener('click', function() {
if (document.querySelectorAll('.item-row').length > 2) {
newRow.remove();
updateTotals();
}
});
newRow.querySelector('.item-type').addEventListener('change', updateTotals);
newRow.querySelector('.item-amount').addEventListener('input', updateTotals);
});
document.querySelectorAll('.remove-row').forEach(btn => {
btn.addEventListener('click', function() {
if (document.querySelectorAll('.item-row').length > 2) {
btn.closest('.item-row').remove();
updateTotals();
}
});
});
document.querySelectorAll('.item-type').forEach(el => el.addEventListener('change', updateTotals));
document.querySelectorAll('.item-amount').forEach(el => el.addEventListener('input', updateTotals));
});
</script>
{% endblock %}