684 lines
37 KiB
HTML
684 lines
37 KiB
HTML
{% extends 'base.html' %}
|
|
{% load static %}
|
|
|
|
{% block title %}Inventory Management - Pharmacy{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="content">
|
|
<div class="container-fluid">
|
|
<!-- Page Header -->
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<div class="page-header">
|
|
<div class="page-title">
|
|
<h4>Pharmacy Inventory Management</h4>
|
|
<h6>Comprehensive medication inventory tracking and management system</h6>
|
|
</div>
|
|
<div class="page-btn">
|
|
<div class="btn-group">
|
|
<a href="{% url 'pharmacy:add_inventory_item' %}" class="btn btn-primary">
|
|
<i class="fa fa-plus"></i> Add Item
|
|
</a>
|
|
<button type="button" class="btn btn-success" data-bs-toggle="modal" data-bs-target="#receiveShipmentModal">
|
|
<i class="fa fa-truck"></i> Receive Shipment
|
|
</button>
|
|
<button type="button" class="btn btn-warning" onclick="generatePurchaseOrders()">
|
|
<i class="fa fa-shopping-cart"></i> Generate POs
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Inventory Summary Cards -->
|
|
<div class="row">
|
|
<div class="col-xl-3 col-sm-6 col-12">
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<div class="dash-widget-header">
|
|
<span class="dash-widget-icon text-primary border-primary">
|
|
<i class="fa fa-boxes"></i>
|
|
</span>
|
|
<div class="dash-count">
|
|
<h3>{{ inventory_stats.total_items|default:1247 }}</h3>
|
|
</div>
|
|
</div>
|
|
<div class="dash-widget-info">
|
|
<h6 class="text-muted">Total Items</h6>
|
|
<div class="progress progress-sm">
|
|
<div class="progress-bar bg-primary" style="width: 85%"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-xl-3 col-sm-6 col-12">
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<div class="dash-widget-header">
|
|
<span class="dash-widget-icon text-warning border-warning">
|
|
<i class="fa fa-exclamation-triangle"></i>
|
|
</span>
|
|
<div class="dash-count">
|
|
<h3>{{ inventory_stats.low_stock|default:23 }}</h3>
|
|
</div>
|
|
</div>
|
|
<div class="dash-widget-info">
|
|
<h6 class="text-muted">Low Stock Items</h6>
|
|
<div class="progress progress-sm">
|
|
<div class="progress-bar bg-warning" style="width: {{ inventory_stats.low_stock_percentage|default:15 }}%"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-xl-3 col-sm-6 col-12">
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<div class="dash-widget-header">
|
|
<span class="dash-widget-icon text-danger border-danger">
|
|
<i class="fa fa-calendar-times"></i>
|
|
</span>
|
|
<div class="dash-count">
|
|
<h3>{{ inventory_stats.expiring_soon|default:8 }}</h3>
|
|
</div>
|
|
</div>
|
|
<div class="dash-widget-info">
|
|
<h6 class="text-muted">Expiring Soon</h6>
|
|
<div class="progress progress-sm">
|
|
<div class="progress-bar bg-danger" style="width: {{ inventory_stats.expiring_percentage|default:5 }}%"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-xl-3 col-sm-6 col-12">
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<div class="dash-widget-header">
|
|
<span class="dash-widget-icon text-success border-success">
|
|
<i class="fa fa-dollar-sign"></i>
|
|
</span>
|
|
<div class="dash-count">
|
|
<h3>${{ inventory_stats.total_value|default:245000|floatformat:0 }}</h3>
|
|
</div>
|
|
</div>
|
|
<div class="dash-widget-info">
|
|
<h6 class="text-muted">Inventory Value</h6>
|
|
<div class="progress progress-sm">
|
|
<div class="progress-bar bg-success" style="width: 92%"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Filters and Search -->
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="card-title">Inventory Filters</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<form method="get" class="row g-3">
|
|
<div class="col-md-3">
|
|
<label class="form-label">Search</label>
|
|
<input type="text" name="search" class="form-control"
|
|
placeholder="Drug name, NDC, or lot number" value="{{ request.GET.search }}">
|
|
</div>
|
|
<div class="col-md-2">
|
|
<label class="form-label">Category</label>
|
|
<select name="category" class="form-select">
|
|
<option value="">All Categories</option>
|
|
<option value="antibiotics" {% if request.GET.category == 'antibiotics' %}selected{% endif %}>Antibiotics</option>
|
|
<option value="cardiovascular" {% if request.GET.category == 'cardiovascular' %}selected{% endif %}>Cardiovascular</option>
|
|
<option value="diabetes" {% if request.GET.category == 'diabetes' %}selected{% endif %}>Diabetes</option>
|
|
<option value="pain_management" {% if request.GET.category == 'pain_management' %}selected{% endif %}>Pain Management</option>
|
|
<option value="controlled" {% if request.GET.category == 'controlled' %}selected{% endif %}>Controlled Substances</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<label class="form-label">Stock Status</label>
|
|
<select name="stock_status" class="form-select">
|
|
<option value="">All Status</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="expiring" {% if request.GET.stock_status == 'expiring' %}selected{% endif %}>Expiring Soon</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<label class="form-label">Location</label>
|
|
<select name="location" class="form-select">
|
|
<option value="">All Locations</option>
|
|
<option value="main_pharmacy" {% if request.GET.location == 'main_pharmacy' %}selected{% endif %}>Main Pharmacy</option>
|
|
<option value="satellite_1" {% if request.GET.location == 'satellite_1' %}selected{% endif %}>Satellite 1</option>
|
|
<option value="emergency" {% if request.GET.location == 'emergency' %}selected{% endif %}>Emergency</option>
|
|
<option value="refrigerated" {% if request.GET.location == 'refrigerated' %}selected{% endif %}>Refrigerated</option>
|
|
<option value="controlled_vault" {% if request.GET.location == 'controlled_vault' %}selected{% endif %}>Controlled Vault</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<label class="form-label">Supplier</label>
|
|
<select name="supplier" class="form-select">
|
|
<option value="">All Suppliers</option>
|
|
{% for supplier in suppliers %}
|
|
<option value="{{ supplier.id }}"
|
|
{% if request.GET.supplier == supplier.id|stringformat:"s" %}selected{% endif %}>
|
|
{{ supplier.name }}
|
|
</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
<div class="col-md-1">
|
|
<label class="form-label"> </label>
|
|
<button type="submit" class="btn btn-primary d-block">
|
|
<i class="fa fa-search"></i>
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Inventory Table -->
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="card-title">
|
|
Inventory Items
|
|
<span class="badge bg-primary">{{ inventory_items.count|default:0 }} items</span>
|
|
</h5>
|
|
<div class="card-tools">
|
|
<div class="btn-group">
|
|
<button type="button" class="btn btn-sm btn-outline-primary dropdown-toggle" data-bs-toggle="dropdown">
|
|
<i class="fa fa-download"></i> Export
|
|
</button>
|
|
<ul class="dropdown-menu">
|
|
<li><a class="dropdown-item" href="#"><i class="fa fa-file-excel"></i> Excel Report</a></li>
|
|
<li><a class="dropdown-item" href="#"><i class="fa fa-file-csv"></i> CSV Data</a></li>
|
|
<li><a class="dropdown-item" href="#"><i class="fa fa-file-pdf"></i> Inventory Report</a></li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="table-responsive">
|
|
<table class="table table-striped">
|
|
<thead>
|
|
<tr>
|
|
<th>
|
|
<input type="checkbox" id="selectAll" class="form-check-input">
|
|
</th>
|
|
<th>Medication</th>
|
|
<th>NDC</th>
|
|
<th>Lot Number</th>
|
|
<th>Quantity</th>
|
|
<th>Unit Cost</th>
|
|
<th>Total Value</th>
|
|
<th>Expiration</th>
|
|
<th>Location</th>
|
|
<th>Status</th>
|
|
<th>Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for item in inventory_items %}
|
|
<tr class="{% if item.is_expired %}table-danger{% elif item.is_expiring_soon %}table-warning{% elif item.is_low_stock %}table-info{% endif %}">
|
|
<td>
|
|
<input type="checkbox" name="selected_items"
|
|
value="{{ item.id }}" class="form-check-input">
|
|
</td>
|
|
<td>
|
|
<div>
|
|
<strong>{{ item.medication.name }}</strong><br>
|
|
<small class="text-muted">{{ item.medication.generic_name }}</small>
|
|
{% if item.medication.controlled_substance %}
|
|
<br><span class="badge bg-warning">Controlled</span>
|
|
{% endif %}
|
|
</div>
|
|
</td>
|
|
<td>{{ item.ndc_number }}</td>
|
|
<td>{{ item.lot_number }}</td>
|
|
<td>
|
|
<div>
|
|
<strong>{{ item.quantity_on_hand }}</strong> {{ item.unit_of_measure }}<br>
|
|
<small class="text-muted">Min: {{ item.minimum_quantity }}</small>
|
|
</div>
|
|
</td>
|
|
<td>${{ item.unit_cost|floatformat:2 }}</td>
|
|
<td>${{ item.total_value|floatformat:2 }}</td>
|
|
<td>
|
|
{{ item.expiration_date|date:"M d, Y" }}
|
|
{% if item.days_until_expiration <= 30 %}
|
|
<br><small class="text-danger">{{ item.days_until_expiration }} days</small>
|
|
{% endif %}
|
|
</td>
|
|
<td>{{ item.storage_location|title }}</td>
|
|
<td>
|
|
{% if item.is_expired %}
|
|
<span class="badge bg-danger">Expired</span>
|
|
{% elif item.is_expiring_soon %}
|
|
<span class="badge bg-warning">Expiring Soon</span>
|
|
{% elif item.is_low_stock %}
|
|
<span class="badge bg-info">Low Stock</span>
|
|
{% elif item.is_out_of_stock %}
|
|
<span class="badge bg-danger">Out of Stock</span>
|
|
{% else %}
|
|
<span class="badge bg-success">In Stock</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
<div class="btn-group">
|
|
<button type="button" class="btn btn-sm btn-outline-primary"
|
|
onclick="adjustQuantity({{ item.id }})" title="Adjust Quantity">
|
|
<i class="fa fa-edit"></i>
|
|
</button>
|
|
<button type="button" class="btn btn-sm btn-outline-success"
|
|
onclick="transferItem({{ item.id }})" title="Transfer">
|
|
<i class="fa fa-exchange-alt"></i>
|
|
</button>
|
|
<div class="btn-group">
|
|
<button type="button" class="btn btn-sm btn-outline-secondary dropdown-toggle"
|
|
data-bs-toggle="dropdown" title="More Actions">
|
|
<i class="fa fa-ellipsis-v"></i>
|
|
</button>
|
|
<ul class="dropdown-menu">
|
|
<li><a class="dropdown-item" href="#"><i class="fa fa-eye"></i> View Details</a></li>
|
|
<li><a class="dropdown-item" href="#"><i class="fa fa-history"></i> Transaction History</a></li>
|
|
<li><a class="dropdown-item" href="#"><i class="fa fa-print"></i> Print Label</a></li>
|
|
<li><hr class="dropdown-divider"></li>
|
|
<li><a class="dropdown-item text-danger" href="#"><i class="fa fa-trash"></i> Remove</a></li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
{% empty %}
|
|
<tr>
|
|
<td colspan="11" class="text-center text-muted">
|
|
<i class="fa fa-boxes fa-3x mb-3"></i>
|
|
<p>No inventory items found</p>
|
|
<a href="{% url 'pharmacy:add_inventory_item' %}" class="btn btn-primary">
|
|
<i class="fa fa-plus"></i> Add First Item
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<!-- Pagination -->
|
|
{% if inventory_items.has_other_pages %}
|
|
<nav aria-label="Inventory pagination">
|
|
<ul class="pagination justify-content-center">
|
|
{% if inventory_items.has_previous %}
|
|
<li class="page-item">
|
|
<a class="page-link" href="?page={{ inventory_items.previous_page_number }}{% for key, value in request.GET.items %}{% if key != 'page' %}&{{ key }}={{ value }}{% endif %}{% endfor %}">Previous</a>
|
|
</li>
|
|
{% endif %}
|
|
|
|
{% for num in inventory_items.paginator.page_range %}
|
|
{% if inventory_items.number == num %}
|
|
<li class="page-item active">
|
|
<span class="page-link">{{ num }}</span>
|
|
</li>
|
|
{% elif num > inventory_items.number|add:'-3' and num < inventory_items.number|add:'3' %}
|
|
<li class="page-item">
|
|
<a class="page-link" href="?page={{ num }}{% for key, value in request.GET.items %}{% if key != 'page' %}&{{ key }}={{ value }}{% endif %}{% endfor %}">{{ num }}</a>
|
|
</li>
|
|
{% endif %}
|
|
{% endfor %}
|
|
|
|
{% if inventory_items.has_next %}
|
|
<li class="page-item">
|
|
<a class="page-link" href="?page={{ inventory_items.next_page_number }}{% for key, value in request.GET.items %}{% if key != 'page' %}&{{ key }}={{ value }}{% endif %}{% endfor %}">Next</a>
|
|
</li>
|
|
{% endif %}
|
|
</ul>
|
|
</nav>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Bulk Actions -->
|
|
{% if inventory_items %}
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="card-title">Bulk Actions</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row">
|
|
<div class="col-md-8">
|
|
<div class="btn-group">
|
|
<button type="button" class="btn btn-outline-primary" id="bulkAdjustBtn">
|
|
<i class="fa fa-edit"></i> Bulk Adjust
|
|
</button>
|
|
<button type="button" class="btn btn-outline-success" id="bulkTransferBtn">
|
|
<i class="fa fa-exchange-alt"></i> Bulk Transfer
|
|
</button>
|
|
<button type="button" class="btn btn-outline-warning" id="bulkOrderBtn">
|
|
<i class="fa fa-shopping-cart"></i> Create Purchase Order
|
|
</button>
|
|
<button type="button" class="btn btn-outline-info" id="bulkPrintBtn">
|
|
<i class="fa fa-print"></i> Print Labels
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4 text-end">
|
|
<span id="selectedCount" class="text-muted">0 items selected</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Recent Transactions -->
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="card-title">Recent Inventory Transactions</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="table-responsive">
|
|
<table class="table table-sm">
|
|
<thead>
|
|
<tr>
|
|
<th>Time</th>
|
|
<th>Type</th>
|
|
<th>Medication</th>
|
|
<th>Quantity</th>
|
|
<th>User</th>
|
|
<th>Reference</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for transaction in recent_transactions %}
|
|
<tr>
|
|
<td>{{ transaction.timestamp|date:"H:i" }}</td>
|
|
<td>
|
|
<span class="badge bg-{{ transaction.type_color }}">
|
|
{{ transaction.transaction_type|title }}
|
|
</span>
|
|
</td>
|
|
<td>{{ transaction.medication.name }}</td>
|
|
<td>
|
|
{% if transaction.transaction_type == 'dispensed' or transaction.transaction_type == 'adjustment_out' %}
|
|
-{{ transaction.quantity }}
|
|
{% else %}
|
|
+{{ transaction.quantity }}
|
|
{% endif %}
|
|
{{ transaction.unit_of_measure }}
|
|
</td>
|
|
<td>{{ transaction.user.get_full_name }}</td>
|
|
<td>{{ transaction.reference_number|default:"-" }}</td>
|
|
</tr>
|
|
{% empty %}
|
|
<tr>
|
|
<td colspan="6" class="text-center text-muted">No recent transactions</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Receive Shipment Modal -->
|
|
<div class="modal fade" id="receiveShipmentModal" tabindex="-1">
|
|
<div class="modal-dialog modal-lg">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">Receive Shipment</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
</div>
|
|
<form id="receiveShipmentForm">
|
|
<div class="modal-body">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label class="form-label">Purchase Order Number</label>
|
|
<input type="text" name="po_number" class="form-control" required>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label class="form-label">Supplier</label>
|
|
<select name="supplier" class="form-select" required>
|
|
<option value="">Select Supplier</option>
|
|
{% for supplier in suppliers %}
|
|
<option value="{{ supplier.id }}">{{ supplier.name }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label class="form-label">Invoice Number</label>
|
|
<input type="text" name="invoice_number" class="form-control">
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label class="form-label">Received Date</label>
|
|
<input type="date" name="received_date" class="form-control" required>
|
|
</div>
|
|
</div>
|
|
<div class="col-12">
|
|
<div class="mb-3">
|
|
<label class="form-label">Notes</label>
|
|
<textarea name="notes" class="form-control" rows="3"
|
|
placeholder="Any notes about the shipment..."></textarea>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<h6>Shipment Items</h6>
|
|
<div id="shipmentItems">
|
|
<div class="shipment-item border rounded p-3 mb-3">
|
|
<div class="row">
|
|
<div class="col-md-4">
|
|
<label class="form-label">Medication</label>
|
|
<select name="medication[]" class="form-select" required>
|
|
<option value="">Select Medication</option>
|
|
{% for medication in medications %}
|
|
<option value="{{ medication.id }}">{{ medication.name }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<label class="form-label">Quantity</label>
|
|
<input type="number" name="quantity[]" class="form-control" required>
|
|
</div>
|
|
<div class="col-md-2">
|
|
<label class="form-label">Lot Number</label>
|
|
<input type="text" name="lot_number[]" class="form-control" required>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<label class="form-label">Expiration Date</label>
|
|
<input type="date" name="expiration_date[]" class="form-control" required>
|
|
</div>
|
|
<div class="col-md-1">
|
|
<label class="form-label"> </label>
|
|
<button type="button" class="btn btn-outline-danger d-block" onclick="removeShipmentItem(this)">
|
|
<i class="fa fa-times"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<button type="button" class="btn btn-outline-primary" onclick="addShipmentItem()">
|
|
<i class="fa fa-plus"></i> Add Item
|
|
</button>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
|
|
<button type="submit" class="btn btn-success">Receive Shipment</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// Set today's date as default for received date
|
|
document.querySelector('input[name="received_date"]').value = new Date().toISOString().split('T')[0];
|
|
|
|
// Select all functionality
|
|
const selectAllCheckbox = document.getElementById('selectAll');
|
|
const itemCheckboxes = document.querySelectorAll('input[name="selected_items"]');
|
|
const selectedCountElement = document.getElementById('selectedCount');
|
|
|
|
function updateSelectedCount() {
|
|
const selectedCount = document.querySelectorAll('input[name="selected_items"]:checked').length;
|
|
selectedCountElement.textContent = `${selectedCount} item${selectedCount !== 1 ? 's' : ''} selected`;
|
|
|
|
// Enable/disable bulk action buttons
|
|
const bulkButtons = document.querySelectorAll('[id^="bulk"]');
|
|
bulkButtons.forEach(button => {
|
|
button.disabled = selectedCount === 0;
|
|
});
|
|
}
|
|
|
|
selectAllCheckbox.addEventListener('change', function() {
|
|
itemCheckboxes.forEach(checkbox => {
|
|
checkbox.checked = this.checked;
|
|
});
|
|
updateSelectedCount();
|
|
});
|
|
|
|
itemCheckboxes.forEach(checkbox => {
|
|
checkbox.addEventListener('change', function() {
|
|
const allChecked = Array.from(itemCheckboxes).every(cb => cb.checked);
|
|
const noneChecked = Array.from(itemCheckboxes).every(cb => !cb.checked);
|
|
|
|
selectAllCheckbox.checked = allChecked;
|
|
selectAllCheckbox.indeterminate = !allChecked && !noneChecked;
|
|
|
|
updateSelectedCount();
|
|
});
|
|
});
|
|
|
|
// Initialize count
|
|
updateSelectedCount();
|
|
|
|
// Receive shipment form handler
|
|
document.getElementById('receiveShipmentForm').addEventListener('submit', function(e) {
|
|
e.preventDefault();
|
|
|
|
if (confirm('Confirm receipt of this shipment? This will update inventory quantities.')) {
|
|
// Handle shipment receipt
|
|
console.log('Processing shipment receipt...');
|
|
|
|
// Close modal
|
|
bootstrap.Modal.getInstance(document.getElementById('receiveShipmentModal')).hide();
|
|
|
|
// Show success message
|
|
alert('Shipment received successfully!');
|
|
}
|
|
});
|
|
});
|
|
|
|
function addShipmentItem() {
|
|
const container = document.getElementById('shipmentItems');
|
|
const template = container.querySelector('.shipment-item').cloneNode(true);
|
|
|
|
// Clear values
|
|
template.querySelectorAll('input, select').forEach(input => {
|
|
input.value = '';
|
|
});
|
|
|
|
container.appendChild(template);
|
|
}
|
|
|
|
function removeShipmentItem(button) {
|
|
const container = document.getElementById('shipmentItems');
|
|
if (container.children.length > 1) {
|
|
button.closest('.shipment-item').remove();
|
|
} else {
|
|
alert('At least one item is required');
|
|
}
|
|
}
|
|
|
|
function adjustQuantity(itemId) {
|
|
const newQuantity = prompt('Enter new quantity:');
|
|
if (newQuantity !== null && !isNaN(newQuantity) && newQuantity >= 0) {
|
|
// Handle quantity adjustment
|
|
console.log(`Adjusting item ${itemId} to quantity ${newQuantity}`);
|
|
|
|
// In real implementation, make AJAX call to update quantity
|
|
alert('Quantity updated successfully!');
|
|
location.reload();
|
|
}
|
|
}
|
|
|
|
function transferItem(itemId) {
|
|
const newLocation = prompt('Enter destination location:');
|
|
if (newLocation !== null && newLocation.trim() !== '') {
|
|
// Handle item transfer
|
|
console.log(`Transferring item ${itemId} to ${newLocation}`);
|
|
|
|
// In real implementation, make AJAX call to transfer item
|
|
alert('Item transferred successfully!');
|
|
location.reload();
|
|
}
|
|
}
|
|
|
|
function generatePurchaseOrders() {
|
|
if (confirm('Generate purchase orders for all low stock items?')) {
|
|
// Handle PO generation
|
|
console.log('Generating purchase orders...');
|
|
alert('Purchase orders generated successfully!');
|
|
}
|
|
}
|
|
|
|
// Bulk action handlers
|
|
document.getElementById('bulkAdjustBtn').addEventListener('click', function() {
|
|
const selected = getSelectedItems();
|
|
if (selected.length > 0) {
|
|
const adjustment = prompt('Enter quantity adjustment (use + or - prefix):');
|
|
if (adjustment !== null) {
|
|
console.log('Bulk adjusting items:', selected, 'by', adjustment);
|
|
alert('Bulk adjustment completed!');
|
|
}
|
|
}
|
|
});
|
|
|
|
document.getElementById('bulkTransferBtn').addEventListener('click', function() {
|
|
const selected = getSelectedItems();
|
|
if (selected.length > 0) {
|
|
const location = prompt('Enter destination location:');
|
|
if (location !== null && location.trim() !== '') {
|
|
console.log('Bulk transferring items:', selected, 'to', location);
|
|
alert('Bulk transfer completed!');
|
|
}
|
|
}
|
|
});
|
|
|
|
function getSelectedItems() {
|
|
return Array.from(document.querySelectorAll('input[name="selected_items"]:checked'))
|
|
.map(checkbox => checkbox.value);
|
|
}
|
|
</script>
|
|
{% endblock %}
|
|
|