accounting workflows
This commit is contained in:
@@ -0,0 +1,189 @@
|
||||
<?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 flex-column flex-md-row justify-content-between align-items-md-center mb-6 gap-3">
|
||||
<div>
|
||||
<h1 class="fs-3 mb-1">Posting Window</h1>
|
||||
<p class="mb-0">Define the date range within which GL postings and approved inventory entries can be created, edited, voided, or reversed</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-5">
|
||||
|
||||
<!-- Window card -->
|
||||
<div class="col-lg-6">
|
||||
<div class="card">
|
||||
<div class="card-body p-6">
|
||||
|
||||
<div class="d-flex align-items-center gap-3 mb-5">
|
||||
<div class="icon-shape icon-lg bg-primary bg-opacity-10 text-primary rounded-2">
|
||||
<i class="ti ti-calendar-event fs-4"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h5 class="mb-0 fw-semibold">Open Posting Window</h5>
|
||||
<p class="mb-0 text-muted small">Dates outside this range are locked for GL and inventory movement</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Current status -->
|
||||
<div id="window_display" class="alert alert-secondary mb-5">Loading...</div>
|
||||
|
||||
<div class="alert alert-info d-flex gap-2 mb-5">
|
||||
<i class="ti ti-info-circle mt-1"></i>
|
||||
<div>
|
||||
This window applies to both accounting GL postings and approved inventory entries.
|
||||
Draft inventory rows can still be edited or cancelled before they affect stock balance.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Form -->
|
||||
<div class="row g-3 mb-4">
|
||||
<div class="col-sm-6">
|
||||
<label class="form-label">Open From <span class="text-danger">*</span></label>
|
||||
<input type="text" id="open_from" class="form-control">
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<label class="form-label">Open To <span class="text-danger">*</span></label>
|
||||
<input type="text" id="open_to" class="form-control">
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="form-text">Example: <code>01/01/2026</code> to <code>31/12/2026</code> opens all of 2026.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex gap-2">
|
||||
<button class="btn btn-primary" onclick="save_window()">
|
||||
<i class="ti ti-device-floppy me-1"></i>Save Window
|
||||
</button>
|
||||
<button class="btn btn-outline-secondary" onclick="clear_window()">
|
||||
<i class="ti ti-lock-open me-1"></i>Remove Restrictions
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Guide card -->
|
||||
<div class="col-lg-6">
|
||||
<div class="card border-0 bg-light h-100">
|
||||
<div class="card-body p-5">
|
||||
<h6 class="fw-semibold mb-3"><i class="ti ti-info-circle me-1"></i>How it works</h6>
|
||||
<ul class="small mb-0 ps-3">
|
||||
<li class="mb-2">Journal entries, GL postings, and approved inventory movements are only allowed if their date falls <strong>within</strong> the open window.</li>
|
||||
<li class="mb-2">Dates <strong>before Open From</strong> or <strong>after Open To</strong> are rejected.</li>
|
||||
<li class="mb-2">Inventory entries that already affected stock balance use the same window when they are voided, cancelled, or reversed.</li>
|
||||
<li class="mb-2">To open a full year: set <strong>01/01/YYYY</strong> → <strong>31/12/YYYY</strong>.</li>
|
||||
<li class="mb-2">To roll the window forward (e.g. close January): change Open From to <strong>01/02/YYYY</strong>.</li>
|
||||
<li class="mb-2"><strong>Remove Restrictions</strong> clears both dates — all dates become postable.</li>
|
||||
<li>Existing posted GL and approved inventory entries are not changed automatically — the window is checked when a user creates, edits, voids, cancels, or reverses them.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<?php require '../include_ending.php'; ?>
|
||||
|
||||
<script>
|
||||
var open_from_picker = null;
|
||||
var open_to_picker = null;
|
||||
|
||||
function init_window_pickers() {
|
||||
var config = {
|
||||
dateFormat: 'Y-m-d',
|
||||
altInput: true,
|
||||
altFormat: 'd/m/Y',
|
||||
allowInput: true,
|
||||
onReady: function(_, __, fp) {
|
||||
fp.altInput.classList.add('form-control');
|
||||
}
|
||||
};
|
||||
|
||||
open_from_picker = flatpickr('#open_from', config);
|
||||
open_to_picker = flatpickr('#open_to', config);
|
||||
}
|
||||
|
||||
function load_window() {
|
||||
ajax_request({
|
||||
url: server_url + 'accounting/api/engine/posting_window.php',
|
||||
autoPrepare: true,
|
||||
checkRequired: 0,
|
||||
action: 'read',
|
||||
onSuccess: function(res) {
|
||||
var d = res.output;
|
||||
if (open_from_picker) open_from_picker.setDate(d.open_from || '', false, 'Y-m-d');
|
||||
if (open_to_picker) open_to_picker.setDate(d.open_to || '', false, 'Y-m-d');
|
||||
render_display(d.open_from, d.open_to);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function render_display(from, to) {
|
||||
var el = document.getElementById('window_display');
|
||||
if (!from && !to) {
|
||||
el.className = 'alert alert-success mb-5';
|
||||
el.innerHTML = '<i class="ti ti-lock-open me-2"></i><strong>No restrictions</strong> — all dates are open for posting.';
|
||||
} else {
|
||||
el.className = 'alert alert-primary mb-5';
|
||||
var f = from ? '<strong>' + escape_html(from) + '</strong>' : '<span class="text-muted">no lower limit</span>';
|
||||
var t = to ? '<strong>' + escape_html(to) + '</strong>' : '<span class="text-muted">no upper limit</span>';
|
||||
el.innerHTML = '<i class="ti ti-calendar-event me-2"></i>Posting open from ' + f + ' to ' + t;
|
||||
}
|
||||
}
|
||||
|
||||
function save_window() {
|
||||
var from = document.getElementById('open_from').value;
|
||||
var to = document.getElementById('open_to').value;
|
||||
ajax_request({
|
||||
url: server_url + 'accounting/api/engine/posting_window.php',
|
||||
autoPrepare: true,
|
||||
checkRequired: 0,
|
||||
action: 'save',
|
||||
open_from: from,
|
||||
open_to: to,
|
||||
onSuccess: function() {
|
||||
render_display(from, to);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function clear_window() {
|
||||
if (open_from_picker) open_from_picker.clear();
|
||||
if (open_to_picker) open_to_picker.clear();
|
||||
ajax_request({
|
||||
url: server_url + 'accounting/api/engine/posting_window.php',
|
||||
autoPrepare: true,
|
||||
checkRequired: 0,
|
||||
action: 'save',
|
||||
open_from: '',
|
||||
open_to: '',
|
||||
onSuccess: function() {
|
||||
render_display('', '');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
init_window_pickers();
|
||||
load_window();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user