243 lines
8.6 KiB
PHP
243 lines
8.6 KiB
PHP
<?php
|
||
session_start();
|
||
require '../config.php';
|
||
require '../include_header.php';
|
||
?>
|
||
|
||
<body>
|
||
<?php require '../include_topbar.php'; ?>
|
||
<?php require '../include_master_sidebar.php'; ?>
|
||
|
||
<main id="content" class="content py-15">
|
||
<div class="container-fluid">
|
||
|
||
<div class="row">
|
||
<div class="col-12">
|
||
<div class="d-flex align-items-center mb-5 gap-3">
|
||
<a href="<?php echo $server_url?>accounting/chart_of_accounts.php" class="btn btn-light btn-sm">
|
||
<i class="ti ti-arrow-left me-1"></i>Back
|
||
</a>
|
||
<div>
|
||
<h1 class="fs-3 mb-0">Manage Account</h1>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="row" id="accountForm">
|
||
<div class="col-lg-7">
|
||
<div class="card">
|
||
<div class="card-body p-6">
|
||
|
||
<input type="hidden" id="id">
|
||
|
||
<div class="row g-4">
|
||
|
||
<div class="col-md-4">
|
||
<label class="form-label">Account Code <span class="text-danger">*</span></label>
|
||
<input type="text" class="form-control" id="account_code" placeholder="e.g. 1100" required>
|
||
<div class="form-text">1xxx Asset · 2xxx Liability · 3xxx Equity · 4xxx Revenue · 5-9xxx Expense</div>
|
||
</div>
|
||
|
||
<div class="col-md-8">
|
||
<label class="form-label">Account Name <span class="text-danger">*</span></label>
|
||
<input type="text" class="form-control" id="account_name" placeholder="e.g. Cash at Bank" required>
|
||
</div>
|
||
|
||
<div class="col-md-6">
|
||
<label class="form-label">Account Type <span class="text-danger">*</span></label>
|
||
<select class="form-select" id="account_type" required>
|
||
<option value="">— Auto-detected from code —</option>
|
||
<option value="asset">Asset</option>
|
||
<option value="liability">Liability</option>
|
||
<option value="equity">Equity</option>
|
||
<option value="revenue">Revenue</option>
|
||
<option value="expense">Expense</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="col-md-6">
|
||
<label class="form-label">Account Level <span class="text-danger">*</span></label>
|
||
<select class="form-select" id="is_posting" required>
|
||
<option value="1">Item — used in journal entries</option>
|
||
<option value="0">Parent — grouping / reports only</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="col-md-12" id="parent_row">
|
||
<label class="form-label">Parent Account</label>
|
||
<select class="form-select" id="parent_code">
|
||
<option value="">— None (top-level parent) —</option>
|
||
</select>
|
||
<div class="form-text">Only parent-level accounts of the same type are shown.</div>
|
||
</div>
|
||
|
||
<div class="col-md-6">
|
||
<label class="form-label">Status</label>
|
||
<select class="form-select" id="status">
|
||
<option value="1">Active</option>
|
||
<option value="0">Inactive</option>
|
||
</select>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<div class="d-flex gap-2 mt-5">
|
||
<button class="btn btn-primary" onclick="manage_account();" id="btn_submit">Create Account</button>
|
||
<button class="btn btn-secondary" onclick="reset_input('#accountForm');" id="btn_reset">Clear</button>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Guide card -->
|
||
<div class="col-lg-5">
|
||
<div class="card border-0 bg-light">
|
||
<div class="card-body p-5">
|
||
<h6 class="fw-semibold mb-3"><i class="ti ti-info-circle me-1"></i>Account Level Guide</h6>
|
||
<p class="small mb-3">
|
||
<strong>Parent</strong> accounts group items for reporting (e.g. <em>1000 Current Assets</em>).
|
||
They cannot be used in journal entries.
|
||
</p>
|
||
<p class="small mb-3">
|
||
<strong>Item</strong> accounts are the leaf-level codes posted in every journal entry
|
||
(e.g. <em>1110 Cash at Bank</em>).
|
||
</p>
|
||
<hr class="my-3">
|
||
<p class="small mb-1 fw-semibold">Standard ranges:</p>
|
||
<table class="table table-sm small mb-0">
|
||
<tbody>
|
||
<tr><td>1xxx</td><td>Asset</td></tr>
|
||
<tr><td>2xxx</td><td>Liability</td></tr>
|
||
<tr><td>3xxx</td><td>Equity</td></tr>
|
||
<tr><td>4xxx</td><td>Revenue</td></tr>
|
||
<tr><td>5–9xxx</td><td>Expense</td></tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
</div>
|
||
</main>
|
||
|
||
<?php require '../include_ending.php'; ?>
|
||
|
||
<script>
|
||
var all_accounts = [];
|
||
|
||
// ── Auto-detect type from code prefix ────────────────────────────────
|
||
function detect_type(code) {
|
||
var first = parseInt((code || '').charAt(0));
|
||
if (first === 1) return 'asset';
|
||
if (first === 2) return 'liability';
|
||
if (first === 3) return 'equity';
|
||
if (first === 4) return 'revenue';
|
||
if (first >= 5 && first <= 9) return 'expense';
|
||
return '';
|
||
}
|
||
|
||
$('#account_code').on('input', function() {
|
||
var type = detect_type($(this).val().trim());
|
||
if (type) {
|
||
$('#account_type').val(type);
|
||
refresh_parent_dropdown(type, null);
|
||
}
|
||
});
|
||
|
||
$('#account_type').on('change', function() {
|
||
refresh_parent_dropdown($(this).val(), null);
|
||
});
|
||
|
||
// Hide parent row when account level is set to Parent (is_posting=0)
|
||
$('#is_posting').on('change', function() {
|
||
if ($(this).val() == '0') {
|
||
$('#parent_row').hide();
|
||
$('#parent_code').val('');
|
||
} else {
|
||
$('#parent_row').show();
|
||
}
|
||
});
|
||
|
||
// ── Parent dropdown: filter to same type + is_posting=0 ─────────────
|
||
function refresh_parent_dropdown(type, selected_code) {
|
||
var opts = '<option value="">— None (top-level parent) —</option>';
|
||
var parents = all_accounts.filter(function(a) {
|
||
return a.is_posting == 0 && a.status == 1 && (!type || a.account_type === type);
|
||
});
|
||
$.each(parents, function(i, item) {
|
||
var sel = (selected_code && selected_code == item.account_code) ? 'selected' : '';
|
||
opts += `<option value="${escape_html(item.account_code)}" ${sel}>${escape_html(item.account_code)} — ${escape_html(item.account_name)}</option>`;
|
||
});
|
||
$('#parent_code').html(opts);
|
||
}
|
||
|
||
function load_all_accounts(selected_parent, selected_type) {
|
||
return ajax_request({
|
||
url: '<?php echo $server_url?>accounting/api/engine/account.php',
|
||
autoPrepare: true,
|
||
checkRequired: 0,
|
||
action: 'read',
|
||
onSuccess: function(res) {
|
||
all_accounts = res.output || [];
|
||
refresh_parent_dropdown(selected_type, selected_parent);
|
||
}
|
||
});
|
||
}
|
||
|
||
function manage_account() {
|
||
return ajax_request({
|
||
url: '<?php echo $server_url?>accounting/api/engine/manage_account.php',
|
||
autoPrepare: true,
|
||
checkRequired: 1,
|
||
action: 'manage',
|
||
onSuccess: function() {
|
||
window.location.href = '<?php echo $server_url?>accounting/chart_of_accounts.php';
|
||
}
|
||
});
|
||
}
|
||
|
||
function retrieve_for_edit() {
|
||
<?php if (empty($_GET['id'])): ?>
|
||
return false;
|
||
<?php endif; ?>
|
||
|
||
return ajax_request({
|
||
url: '<?php echo $server_url?>accounting/api/engine/retrieve_account.php',
|
||
autoPrepare: true,
|
||
checkRequired: 0,
|
||
action: 'read',
|
||
data: { id: <?php echo (int)$_GET['id']; ?> },
|
||
onSuccess: function(res) {
|
||
var item = res.output;
|
||
$('#id').val(item.id);
|
||
$('#account_code').val(item.account_code);
|
||
$('#account_name').val(item.account_name);
|
||
$('#account_type').val(item.account_type);
|
||
$('#is_posting').val(item.is_posting);
|
||
$('#status').val(item.status);
|
||
if (item.is_posting == 0) $('#parent_row').hide();
|
||
load_all_accounts(item.parent_code, item.account_type);
|
||
$('#btn_submit').text('Update Account');
|
||
$('#btn_reset').hide();
|
||
}
|
||
});
|
||
}
|
||
|
||
$(async function() {
|
||
try {
|
||
<?php if (empty($_GET['id'])): ?>
|
||
await load_all_accounts(null, null);
|
||
<?php else: ?>
|
||
await retrieve_for_edit();
|
||
<?php endif; ?>
|
||
} catch(e) { console.log(e); }
|
||
});
|
||
</script>
|
||
|
||
</body>
|
||
</html>
|