Add Asset Management app
Assets from purchase invoice lines, straight-line depreciation/amortization with salvage value, disposals, and [Asset Mgmt] sources in Batch GL Entries. Green third workspace with an app access guard.
This commit is contained in:
@@ -0,0 +1,174 @@
|
||||
<?php
|
||||
session_start();
|
||||
require '../config.php';
|
||||
require '../include_header.php';
|
||||
?>
|
||||
|
||||
<body>
|
||||
<?php require '../include_topbar.php'; ?>
|
||||
<?php require '../include_sidebar_asset.php'; ?>
|
||||
|
||||
<main id="content" class="content py-15">
|
||||
<div class="container-fluid">
|
||||
|
||||
<!-- Page header -->
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="d-flex flex-column flex-md-row justify-content-between align-items-md-center mb-5 gap-3">
|
||||
<div>
|
||||
<h1 class="fs-3 mb-1">Asset Register</h1>
|
||||
<p class="mb-0">Every asset with its cost, accumulated depreciation and book value</p>
|
||||
</div>
|
||||
<div class="d-flex gap-2">
|
||||
<a href="<?php echo $server_url?>asset/purchase_invoices.php" class="btn btn-outline-primary">
|
||||
<i class="ti ti-file-invoice me-1"></i>From Purchase Invoice
|
||||
</a>
|
||||
<a href="<?php echo $server_url?>asset/manage_asset.php" class="btn btn-primary">
|
||||
<i class="ti ti-plus me-1"></i>New Asset
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card overflow-hidden">
|
||||
<div class="card-body p-6">
|
||||
|
||||
<div class="mb-5 d-flex flex-column flex-md-row justify-content-between align-items-md-center gap-3">
|
||||
<ul class="nav nav-pills small" id="status_filter">
|
||||
<li class="nav-item"><a class="nav-link active" href="javascript:;" data-status="">All <span class="count"></span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="javascript:;" data-status="0">Draft <span class="count"></span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="javascript:;" data-status="1">Active <span class="count"></span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="javascript:;" data-status="2">Fully depreciated <span class="count"></span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="javascript:;" data-status="3">Disposed <span class="count"></span></a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="javascript:;" data-status="4">Void <span class="count"></span></a></li>
|
||||
</ul>
|
||||
<div class="position-relative" style="min-width:240px;">
|
||||
<input type="search" id="search_asset" class="form-control ps-9" placeholder="Search number, name, category…">
|
||||
<span class="position-absolute top-25 ms-4">
|
||||
<i class="ti ti-search text-muted"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table mb-0 text-nowrap table-hover table-centered" id="asset_table">
|
||||
<thead class="table-primary border-light">
|
||||
<tr>
|
||||
<th>Asset No.</th>
|
||||
<th>Name</th>
|
||||
<th>Category</th>
|
||||
<th>In Service</th>
|
||||
<th class="text-end">Cost</th>
|
||||
<th class="text-end">Accumulated</th>
|
||||
<th class="text-end">Book Value</th>
|
||||
<th>Status</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
<tfoot></tfoot>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<?php require '../include_ending.php'; ?>
|
||||
<script src="<?php echo $server_url?>assets/js/asset.js"></script>
|
||||
|
||||
<script>
|
||||
var all_assets = [];
|
||||
var search_term = '';
|
||||
var status_filter = new URLSearchParams(window.location.search).get('status') || '';
|
||||
|
||||
function retrieve_assets() {
|
||||
return ajax_request({
|
||||
url: server_url + 'asset/api/engine/asset.php',
|
||||
autoPrepare: true,
|
||||
checkRequired: 0,
|
||||
action: 'read',
|
||||
onSuccess: function(res) {
|
||||
all_assets = res.output || [];
|
||||
update_counts();
|
||||
change_page(1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function update_counts() {
|
||||
$('#status_filter a').each(function() {
|
||||
var s = String($(this).data('status'));
|
||||
var n = s === '' ? all_assets.length : all_assets.filter(function(a) { return String(a.status) === s; }).length;
|
||||
$(this).find('.count').text('(' + n + ')');
|
||||
$(this).toggleClass('active', s === status_filter);
|
||||
});
|
||||
}
|
||||
|
||||
function filtered_assets() {
|
||||
var kw = search_term.toLowerCase();
|
||||
return all_assets.filter(function(a) {
|
||||
if (status_filter !== '' && String(a.status) !== status_filter) return false;
|
||||
if (!kw) return true;
|
||||
return [a.asset_number, a.asset_name, a.category_code, a.category_name, a.invoice_number]
|
||||
.some(function(v) { return String(v || '').toLowerCase().indexOf(kw) !== -1; });
|
||||
});
|
||||
}
|
||||
|
||||
function change_page(page_num) {
|
||||
var rows = filtered_assets();
|
||||
var limit = parseInt(prop_limit, 10);
|
||||
var offset = (page_num - 1) * limit;
|
||||
|
||||
$('table#asset_table tfoot').html(generate_pagination('asset_table', rows.length));
|
||||
|
||||
if (!rows.length) {
|
||||
$('table#asset_table tbody').html('<tr><td colspan="9" class="text-center py-5 text-muted">No assets found.</td></tr>');
|
||||
return;
|
||||
}
|
||||
|
||||
var body = '';
|
||||
rows.slice(offset, offset + limit).forEach(function(a) {
|
||||
var source = a.invoice_number
|
||||
? '<div class="small text-muted"><i class="ti ti-file-invoice me-1"></i>' + escape_html(a.invoice_number) + '</div>'
|
||||
: '';
|
||||
body += `<tr>
|
||||
<td class="py-3 fw-semibold">${escape_html(a.asset_number)}</td>
|
||||
<td class="py-3">${escape_html(a.asset_name)}${source}</td>
|
||||
<td class="py-3">${escape_html(a.category_code)} <span class="text-muted">${escape_html(a.category_name)}</span></td>
|
||||
<td class="py-3">${format_date(a.in_service_date)}</td>
|
||||
<td class="py-3 text-end">${format_number(a.cost, 2)}</td>
|
||||
<td class="py-3 text-end">${format_number(a.accumulated, 2)}</td>
|
||||
<td class="py-3 text-end">${format_number(a.book_value, 2)}</td>
|
||||
<td class="py-3">${asset_status_badge(a.status, a.asset_class)}</td>
|
||||
<td class="py-3"><a href="${server_url}asset/manage_asset.php?id=${a.id}"><i class="ti ti-eye fs-5"></i></a></td>
|
||||
</tr>`;
|
||||
});
|
||||
$('table#asset_table tbody').html(body);
|
||||
}
|
||||
|
||||
$('#status_filter').on('click', 'a', function() {
|
||||
status_filter = String($(this).data('status'));
|
||||
update_counts();
|
||||
change_page(1);
|
||||
});
|
||||
|
||||
$('#search_asset').on('input', debounce(function() {
|
||||
search_term = $(this).val().trim();
|
||||
change_page(1);
|
||||
}, 200));
|
||||
|
||||
$(async function() {
|
||||
try { await retrieve_assets(); } catch (e) { console.log(e); }
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user