489 lines
23 KiB
HTML
489 lines
23 KiB
HTML
{% extends "base.html" %}
|
|
{% load allauth %}
|
|
{% load static humanize %}
|
|
|
|
{% block title %}Inventory Items - Inventory Management{% endblock %}
|
|
|
|
{% block css %}
|
|
<link href="{% static 'plugins/select2/dist/css/select2.min.css' %}" rel="stylesheet" />
|
|
<link href="{% static 'plugins/bootstrap-datepicker/dist/css/bootstrap-datepicker.min.css' %}" rel="stylesheet" />
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<!-- BEGIN breadcrumb -->
|
|
<ol class="breadcrumb float-xl-end">
|
|
<li class="breadcrumb-item"><a href="{% url 'core:dashboard' %}">Dashboard</a></li>
|
|
<li class="breadcrumb-item"><a href="{% url 'inventory:dashboard' %}">Inventory</a></li>
|
|
<li class="breadcrumb-item active">Items</li>
|
|
</ol>
|
|
<!-- END breadcrumb -->
|
|
|
|
<!-- BEGIN page-header -->
|
|
<h1 class="page-header">
|
|
Inventory Items
|
|
<small>Medical Supplies & Equipment Catalog</small>
|
|
</h1>
|
|
<!-- END page-header -->
|
|
|
|
<!-- BEGIN panel -->
|
|
<div class="panel panel-inverse">
|
|
<div class="panel-heading">
|
|
<h4 class="panel-title">Inventory Items Management</h4>
|
|
<div class="panel-heading-btn">
|
|
<a href="{% url 'inventory:item_create' %}" class="btn btn-xs btn-success me-2">
|
|
<i class="fa fa-plus"></i> Add Item
|
|
</a>
|
|
<a href="javascript:;" class="btn btn-xs btn-icon btn-default" data-toggle="panel-expand"><i class="fa fa-expand"></i></a>
|
|
<a href="javascript:;" class="btn btn-xs btn-icon btn-default" data-toggle="panel-reload"><i class="fa fa-redo"></i></a>
|
|
<a href="javascript:;" class="btn btn-xs btn-icon btn-default" data-toggle="panel-collapse"><i class="fa fa-minus"></i></a>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="panel-body">
|
|
<!-- Filters and Search (GET form) -->
|
|
<form id="filter-form" method="get" class="row g-3 mb-3 align-items-end">
|
|
<div class="col-md-3">
|
|
<label class="form-label">Search Items</label>
|
|
<div class="input-group">
|
|
<input type="text" class="form-control" name="q" id="search-input" value="{{ request.GET.q|default_if_none:'' }}" placeholder="Item name, code, or description...">
|
|
<button class="btn btn-outline-secondary" type="submit" id="search-btn">
|
|
<i class="fa fa-search"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-2">
|
|
<label class="form-label">Category</label>
|
|
<select class="form-select" name="category" id="category-filter">
|
|
<option value="" {% if not request.GET.category %}selected{% endif %}>All Categories</option>
|
|
<option value="MEDICAL_SUPPLIES" {% if request.GET.category == 'MEDICAL_SUPPLIES' %}selected{% endif %}>Medical Supplies</option>
|
|
<option value="PHARMACEUTICALS" {% if request.GET.category == 'PHARMACEUTICALS' %}selected{% endif %}>Pharmaceuticals</option>
|
|
<option value="SURGICAL_INSTRUMENTS" {% if request.GET.category == 'SURGICAL_INSTRUMENTS' %}selected{% endif %}>Surgical Instruments</option>
|
|
<option value="DIAGNOSTIC_EQUIPMENT" {% if request.GET.category == 'DIAGNOSTIC_EQUIPMENT' %}selected{% endif %}>Diagnostic Equipment</option>
|
|
<option value="PATIENT_CARE" {% if request.GET.category == 'PATIENT_CARE' %}selected{% endif %}>Patient Care Equipment</option>
|
|
<option value="LABORATORY_SUPPLIES" {% if request.GET.category == 'LABORATORY_SUPPLIES' %}selected{% endif %}>Laboratory Supplies</option>
|
|
<option value="RADIOLOGY_SUPPLIES" {% if request.GET.category == 'RADIOLOGY_SUPPLIES' %}selected{% endif %}>Radiology Supplies</option>
|
|
<option value="OTHER" {% if request.GET.category == 'OTHER' %}selected{% endif %}>Other</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="col-md-2">
|
|
<label class="form-label">Item Type</label>
|
|
<select class="form-select" name="item_type" id="type-filter">
|
|
<option value="" {% if not request.GET.item_type %}selected{% endif %}>All Types</option>
|
|
<option value="CONSUMABLE" {% if request.GET.item_type == 'CONSUMABLE' %}selected{% endif %}>Consumable</option>
|
|
<option value="REUSABLE" {% if request.GET.item_type == 'REUSABLE' %}selected{% endif %}>Reusable</option>
|
|
<option value="EQUIPMENT" {% if request.GET.item_type == 'EQUIPMENT' %}selected{% endif %}>Equipment</option>
|
|
<option value="MEDICATION" {% if request.GET.item_type == 'MEDICATION' %}selected{% endif %}>Medication</option>
|
|
<option value="DEVICE" {% if request.GET.item_type == 'DEVICE' %}selected{% endif %}>Medical Device</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="col-md-2">
|
|
<label class="form-label">Stock Status</label>
|
|
<select class="form-select" name="stock_status" id="stock-filter">
|
|
<option value="" {% if not request.GET.stock_status %}selected{% endif %}>All Items</option>
|
|
<option value="in_stock" {% if request.GET.stock_status == 'in_stock' %}selected{% endif %}>In Stock</option>
|
|
<option value="low_stock" {% if request.GET.stock_status == 'low_stock' %}selected{% endif %}>Low Stock</option>
|
|
<option value="out_of_stock" {% if request.GET.stock_status == 'out_of_stock' %}selected{% endif %}>Out of Stock</option>
|
|
<option value="needs_reorder" {% if request.GET.stock_status == 'needs_reorder' %}selected{% endif %}>Needs Reorder</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="col-md-3">
|
|
<label class="form-label">Manufacturer</label>
|
|
<select class="form-select select2" name="manufacturer" id="manufacturer-filter" data-current="{{ request.GET.manufacturer|default_if_none:'' }}">
|
|
<option value="">All Manufacturers</option>
|
|
{% if manufacturers %}
|
|
{% for m in manufacturers %}
|
|
<option value="{{ m.id }}" {% if request.GET.manufacturer == m.id|stringformat:'s' %}selected{% endif %}>
|
|
{{ m.name }}
|
|
</option>
|
|
{% endfor %}
|
|
{% endif %}
|
|
</select>
|
|
</div>
|
|
</form>
|
|
|
|
<!-- Quick Stats -->
|
|
<div class="row mb-4">
|
|
<div class="col-lg-3 col-md-6 mb-3">
|
|
<div class="card border-0 bg-primary text-white">
|
|
<div class="card-body d-flex align-items-center">
|
|
<div class="flex-fill">
|
|
<div class="fs-10px text-white-transparent-5 mb-1">TOTAL ITEMS</div>
|
|
<div class="fs-18px fw-900 text-white" id="total-items">{{ stats.total_items|default:"-" }}</div>
|
|
</div>
|
|
<div class="w-50px h-50px bg-white-transparent-2 rounded-circle d-flex align-items-center justify-content-center">
|
|
<i class="fa fa-boxes fa-lg text-white"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-lg-3 col-md-6 mb-3">
|
|
<div class="card border-0 bg-warning text-white">
|
|
<div class="card-body d-flex align-items-center">
|
|
<div class="flex-fill">
|
|
<div class="fs-10px text-white-transparent-5 mb-1">LOW STOCK ITEMS</div>
|
|
<div class="fs-18px fw-900 text-white" id="low-stock-count">{{ stats.low_stock_count|default:"-" }}</div>
|
|
</div>
|
|
<div class="w-50px h-50px bg-white-transparent-2 rounded-circle d-flex align-items-center justify-content-center">
|
|
<i class="fa fa-exclamation-triangle fa-lg text-white"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-lg-3 col-md-6 mb-3">
|
|
<div class="card border-0 bg-danger text-white">
|
|
<div class="card-body d-flex align-items-center">
|
|
<div class="flex-fill">
|
|
<div class="fs-10px text-white-transparent-5 mb-1">OUT OF STOCK</div>
|
|
<div class="fs-18px fw-900 text-white" id="out-of-stock-count">{{ stats.out_of_stock_count|default:"-" }}</div>
|
|
</div>
|
|
<div class="w-50px h-50px bg-white-transparent-2 rounded-circle d-flex align-items-center justify-content-center">
|
|
<i class="fa fa-times-circle fa-lg text-white"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-lg-3 col-md-6 mb-3">
|
|
<div class="card border-0 bg-success text-white">
|
|
<div class="card-body d-flex align-items-center">
|
|
<div class="flex-fill">
|
|
<div class="fs-10px text-white-transparent-5 mb-1">TOTAL VALUE</div>
|
|
<div class="fs-18px fw-900 text-white" id="total-value">
|
|
{% if stats.total_value %}${{ stats.total_value|floatformat:2|intcomma }}{% else %}-{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="w-50px h-50px bg-white-transparent-2 rounded-circle d-flex align-items-center justify-content-center">
|
|
<i class="fa fa-dollar-sign fa-lg text-white"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Action Buttons -->
|
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
|
<div class="btn-group">
|
|
<button type="button" class="btn btn-outline-secondary" id="bulk-actions-btn" disabled>
|
|
<i class="fa fa-tasks me-2"></i>Bulk Actions
|
|
</button>
|
|
<button type="button" class="btn btn-outline-secondary dropdown-toggle dropdown-toggle-split"
|
|
data-bs-toggle="dropdown" id="bulk-dropdown" disabled>
|
|
<span class="visually-hidden">Toggle Dropdown</span>
|
|
</button>
|
|
<ul class="dropdown-menu">
|
|
<li><a class="dropdown-item" href="#" id="bulk-update-category">
|
|
<i class="fa fa-tag me-2"></i>Update Category
|
|
</a></li>
|
|
<li><a class="dropdown-item" href="#" id="bulk-update-supplier">
|
|
<i class="fa fa-truck me-2"></i>Update Supplier
|
|
</a></li>
|
|
<li><hr class="dropdown-divider"></li>
|
|
{# <li><a class="dropdown-item" href="{% url 'inventory:item_export' %}?{{ request.GET.urlencode }}">#}
|
|
{# <i class="fa fa-download me-2"></i>Export Current View#}
|
|
{# </a></li>#}
|
|
<li><a class="dropdown-item text-danger" href="#" id="bulk-deactivate">
|
|
<i class="fa fa-ban me-2"></i>Deactivate Selected
|
|
</a></li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="btn-group">
|
|
<a class="btn btn-outline-secondary" href="?{{ request.GET.urlencode }}">
|
|
<i class="fa fa-refresh me-2"></i>Refresh
|
|
</a>
|
|
<button type="button" class="btn btn-outline-secondary" onclick="showStockAlerts()">
|
|
<i class="fa fa-bell me-2"></i>Stock Alerts
|
|
</button>
|
|
<button type="button" class="btn btn-outline-secondary dropdown-toggle" data-bs-toggle="dropdown">
|
|
<i class="fa fa-download me-2"></i>Export
|
|
</button>
|
|
{# <ul class="dropdown-menu">#}
|
|
{# <li><a class="dropdown-item" href="{% url 'inventory:item_export' %}?format=csv&{{ request.GET.urlencode }}">#}
|
|
{# <i class="fa fa-file-csv me-2"></i>Export as CSV#}
|
|
{# </a></li>#}
|
|
{# <li><a class="dropdown-item" href="{% url 'inventory:item_export' %}?format=excel&{{ request.GET.urlencode }}">#}
|
|
{# <i class="fa fa-file-excel me-2"></i>Export as Excel#}
|
|
{# </a></li>#}
|
|
{# <li><a class="dropdown-item" href="{% url 'inventory:item_export' %}?format=pdf&{{ request.GET.urlencode }}">#}
|
|
{# <i class="fa fa-file-pdf me-2"></i>Export as PDF#}
|
|
{# </a></li>#}
|
|
{# </ul>#}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Items Table (regular table) -->
|
|
<div class="table-responsive">
|
|
<table class="table table-striped table-bordered align-middle">
|
|
<thead>
|
|
<tr>
|
|
<th width="30">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="select-all">
|
|
</div>
|
|
</th>
|
|
<th>Item Code</th>
|
|
<th>Item Name</th>
|
|
<th>Category</th>
|
|
<th>Type</th>
|
|
<th>Manufacturer</th>
|
|
<th>Current Stock</th>
|
|
<th>Unit Cost</th>
|
|
<th>Total Value</th>
|
|
<th>Status</th>
|
|
<th width="140">Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% if items %}
|
|
{% for item in items %}
|
|
<tr>
|
|
<td>
|
|
<div class="form-check">
|
|
<input class="form-check-input row-checkbox" type="checkbox" value="{{ item.id }}">
|
|
</div>
|
|
</td>
|
|
<td><div class="fw-bold">{{ item.item_code }}</div></td>
|
|
<td>
|
|
<div class="fw-bold">{{ item.item_name }}</div>
|
|
{% if item.description %}<div class="text-muted small">{{ item.description|truncatechars:80 }}</div>{% endif %}
|
|
</td>
|
|
<td>
|
|
{% if item.get_category_display %}
|
|
<span class="badge bg-secondary">{{ item.get_category_display }}</span>
|
|
{% else %}-{% endif %}
|
|
</td>
|
|
<td>
|
|
<span class="badge
|
|
bg-{% if item.item_type == 'CONSUMABLE' %}primary
|
|
{% elif item.item_type == 'REUSABLE' %}success
|
|
{% elif item.item_type == 'EQUIPMENT' %}info
|
|
{% elif item.item_type == 'MEDICATION' %}warning
|
|
{% elif item.item_type == 'DEVICE' %}danger
|
|
{% elif item.item_type == 'REUSABLE' %}success
|
|
{% else %}secondary
|
|
{% endif %}">
|
|
{{ item.get_item_type_display }}</span>
|
|
</td>
|
|
<td>{{ item.manufacturer.name|default:item.manufacturer|default:"-" }}</td>
|
|
<td>
|
|
{% with cs=item.current_stock|default:0 rp=item.reorder_point|default:0 %}
|
|
{% if cs|floatformat:0 <= 0 %}
|
|
<span class="text-danger fw-bold">{{ cs }} {{ item.get_unit_of_measure_display }}</span>
|
|
{% elif cs|floatformat:0 <= rp|floatformat:0 %}
|
|
<span class="text-warning fw-bold">{{ cs }} {{ item.get_unit_of_measure_display }}</span>
|
|
{% else %}
|
|
<span>{{ cs }} {{ item.get_unit_of_measure_display }}</span>
|
|
{% endif %}
|
|
{% endwith %}
|
|
</td>
|
|
<td>${{ item.unit_cost|default:0|floatformat:2|intcomma }}</td>
|
|
<td>
|
|
{% with tv=item.total_value|default:item.current_stock|default:0|floatformat:2 %}
|
|
{% if item.total_value %}
|
|
${{ item.total_value|floatformat:2|intcomma }}
|
|
{% else %}
|
|
${{ item.current_stock|default:0|floatformat:0|add:"0"|floatformat:0|intcomma }}
|
|
{% endif %}
|
|
{% endwith %}
|
|
</td>
|
|
<td>
|
|
{# {% if item.get_stock_status_display %}#}
|
|
{# {% with s=item.stock_status %}#}
|
|
{# {% if s == 'in_stock' %}{% setvar 'success' as ss %}{% elif s == 'low_stock' %}{% setvar 'warning' as ss %}#}
|
|
{# {% elif s == 'out_of_stock' %}{% setvar 'danger' as ss %}{% elif s == 'needs_reorder' %}{% setvar 'info' as ss %}#}
|
|
{# {% else %}{% setvar 'secondary' as ss %}{% endif %}#}
|
|
{# <span class="badge bg-{{ ss|default:'secondary' }}">{{ item.get_stock_status_display }}</span>#}
|
|
{# {% endwith %}#}
|
|
{# {% else %}-{% endif %}#}
|
|
</td>
|
|
<td>
|
|
<div class="btn-group btn-group-sm">
|
|
<a class="btn btn-outline-primary" href="{% url 'inventory:item_detail' item.id %}" title="View">
|
|
<i class="fa fa-eye"></i>
|
|
</a>
|
|
<a class="btn btn-outline-secondary" href="{% url 'inventory:item_update' item.id %}" title="Edit">
|
|
<i class="fa fa-edit"></i>
|
|
</a>
|
|
<a class="btn btn-outline-info" href="{% url 'inventory:stock_list' %}?item={{ item.id }}" title="Stock">
|
|
<i class="fa fa-boxes"></i>
|
|
</a>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
{% else %}
|
|
<tr>
|
|
<td colspan="11" class="text-center">No items found.</td>
|
|
</tr>
|
|
{% endif %}
|
|
</tbody>
|
|
</table>
|
|
|
|
{% if is_paginated %}
|
|
{% include 'partial/pagination.html' %}
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- END panel -->
|
|
|
|
<!-- Stock Alerts Modal -->
|
|
<div class="modal fade" id="stockAlertsModal" tabindex="-1">
|
|
<div class="modal-dialog modal-xl">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">Stock Level Alerts</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="row mb-3">
|
|
<div class="col-md-4">
|
|
<select class="form-select" id="alert-type-filter">
|
|
<option value="">All Alerts</option>
|
|
<option value="low_stock">Low Stock</option>
|
|
<option value="out_of_stock">Out of Stock</option>
|
|
<option value="needs_reorder">Needs Reorder</option>
|
|
<option value="expiring_soon">Expiring Soon</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<select class="form-select" id="alert-priority-filter">
|
|
<option value="">All Priorities</option>
|
|
<option value="critical">Critical</option>
|
|
<option value="high">High</option>
|
|
<option value="medium">Medium</option>
|
|
<option value="low">Low</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<button class="btn btn-primary" onclick="generateReorderReport()">
|
|
<i class="fa fa-shopping-cart me-2"></i>Generate Reorder Report
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div id="stock-alerts-content"></div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
|
<button type="button" class="btn btn-primary" onclick="createPurchaseOrders()">Create Purchase Orders</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Quick View Modal -->
|
|
<div class="modal fade" id="itemQuickViewModal" tabindex="-1">
|
|
<div class="modal-dialog modal-lg">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">Item Quick View</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
</div>
|
|
<div class="modal-body" id="item-quick-view-content"></div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
|
<a href="#" class="btn btn-primary" id="view-full-item">View Full Details</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block js %}
|
|
<script src="{% static 'plugins/select2/dist/js/select2.min.js' %}"></script>
|
|
<script src="{% static 'plugins/bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js' %}"></script>
|
|
<script>
|
|
(function() {
|
|
// Select2
|
|
$('.select2').select2({ theme: 'bootstrap-5', width: '100%' });
|
|
|
|
// Auto-submit filters on change (except search which uses the button, but still submit on Enter)
|
|
$('#category-filter, #type-filter, #stock-filter, #manufacturer-filter').on('change', function() {
|
|
document.getElementById('filter-form').submit();
|
|
});
|
|
|
|
// Select all / individual
|
|
const selectAll = document.getElementById('select-all');
|
|
const toggleBulk = () => {
|
|
const checkedCount = document.querySelectorAll('.row-checkbox:checked').length;
|
|
document.getElementById('bulk-actions-btn').disabled = checkedCount === 0;
|
|
document.getElementById('bulk-dropdown').disabled = checkedCount === 0;
|
|
};
|
|
|
|
if (selectAll) {
|
|
selectAll.addEventListener('change', function() {
|
|
document.querySelectorAll('.row-checkbox').forEach(cb => cb.checked = selectAll.checked);
|
|
toggleBulk();
|
|
});
|
|
}
|
|
document.addEventListener('change', function(e) {
|
|
if (e.target.classList && e.target.classList.contains('row-checkbox')) toggleBulk();
|
|
});
|
|
|
|
// Bulk actions (placeholders unless you wire endpoints)
|
|
const getSelectedIds = () => Array.from(document.querySelectorAll('.row-checkbox:checked')).map(x => x.value);
|
|
|
|
document.getElementById('bulk-update-category').addEventListener('click', function(e) {
|
|
e.preventDefault();
|
|
const ids = getSelectedIds();
|
|
if (!ids.length) { toastr && toastr.warning('Please select items to update'); return; }
|
|
toastr && toastr.info('Bulk category update functionality will be implemented');
|
|
});
|
|
|
|
document.getElementById('bulk-update-supplier').addEventListener('click', function(e) {
|
|
e.preventDefault();
|
|
const ids = getSelectedIds();
|
|
if (!ids.length) { toastr && toastr.warning('Please select items to update'); return; }
|
|
toastr && toastr.info('Bulk supplier update functionality will be implemented');
|
|
});
|
|
|
|
{#document.getElementById('bulk-deactivate').addEventListener('click', function(e) {#}
|
|
{# e.preventDefault();#}
|
|
{# const ids = getSelectedIds();#}
|
|
{# if (!ids.length) { toastr && toastr.warning('Please select items to deactivate'); return; }#}
|
|
{# if (!confirm('Are you sure you want to deactivate ' + ids.length + ' item(s)?')) return;#}
|
|
{##}
|
|
{# fetch("{% url 'inventory:item_bulk_deactivate' %}", {#}
|
|
{# method: 'POST',#}
|
|
{# headers: { 'Content-Type': 'application/json', 'X-CSRFToken': '{{ csrf_token }}' },#}
|
|
{# body: JSON.stringify({ item_ids: ids })#}
|
|
{# }).then(r => r.json()).then(data => {#}
|
|
{# if (data.success) {#}
|
|
{# toastr && toastr.success(data.message || 'Items deactivated');#}
|
|
{# window.location.reload();#}
|
|
{# } else {#}
|
|
{# toastr && toastr.error(data.message || 'Failed to deactivate items');#}
|
|
{# }#}
|
|
{# }).catch(() => toastr && toastr.error('An error occurred during bulk deactivation'));#}
|
|
{# });#}
|
|
|
|
// Stats (if you still want to refresh via API; otherwise you can remove this block)
|
|
function loadStats() {
|
|
fetch('{% url "inventory:inventory_stats" %}')
|
|
.then(r => r.json())
|
|
.then(data => {
|
|
document.getElementById('total-items').textContent = data.total_items ?? '-';
|
|
document.getElementById('low-stock-count').textContent = data.low_stock_count ?? '-';
|
|
document.getElementById('out-of-stock-count').textContent = data.out_of_stock_count ?? '-';
|
|
document.getElementById('total-value').textContent = data.total_value ? ('$' + Number(data.total_value).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })) : '-';
|
|
}).catch(() => {});
|
|
}
|
|
// Optional periodic refresh
|
|
// setInterval(loadStats, 300000);
|
|
|
|
{#window.showStockAlerts = function() {#}
|
|
{# const modal = new bootstrap.Modal(document.getElementById('stockAlertsModal'));#}
|
|
{# modal.show();#}
|
|
{# // TODO: fetch and render alerts if you have an API#}
|
|
{# // fetch('{% url "inventory:stock_alerts_api" %}').then(r => r.json()).then(...);#}
|
|
{# };#}
|
|
|
|
window.createPurchaseOrders = function() {
|
|
toastr && toastr.info('Purchase order creation functionality will be implemented');
|
|
};
|
|
})();
|
|
</script>
|
|
{% endblock %} |