Marwan Alwali 6b85b05882 update
2025-08-13 19:31:08 +03:00

548 lines
26 KiB
HTML

{% extends "base.html" %}
{% load static %}
{% block title %}Stock Details - {{ object.item.name }}{% endblock %}
{% block content %}
<div class="d-flex align-items-center mb-3">
<div>
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{% url 'inventory:dashboard' %}">Inventory</a></li>
<li class="breadcrumb-item"><a href="{% url 'inventory:stock_list' %}">Stock</a></li>
<li class="breadcrumb-item active">{{ object.inventory_item.item_name }}</li>
</ol>
<h1 class="page-header mb-0">Stock Details - {{ object.inventory_item.item_name }}</h1>
</div>
<div class="ms-auto">
<div class="btn-group">
<a href="{% url 'inventory:stock_update' object.pk %}" class="btn btn-primary">
<i class="fas fa-edit me-2"></i>Update Stock
</a>
<button type="button" class="btn btn-outline-secondary dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown">
<span class="visually-hidden">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#" onclick="adjustStock('add')">
<i class="fas fa-plus text-success me-2"></i>Add Stock
</a></li>
<li><a class="dropdown-item" href="#" onclick="adjustStock('remove')">
<i class="fas fa-minus text-warning me-2"></i>Remove Stock
</a></li>
<li><a class="dropdown-item" href="#" onclick="transferStock()">
<i class="fas fa-exchange-alt text-info me-2"></i>Transfer Stock
</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="#" onclick="generateReport()">
<i class="fas fa-chart-line me-2"></i>Generate Report
</a></li>
<li><a class="dropdown-item text-danger" href="">
<i class="fas fa-trash me-2"></i>Delete Stock Record
</a></li>
</ul>
</div>
</div>
</div>
<div class="row">
<div class="col-xl-8">
<!-- Stock Information -->
<div class="card mb-4">
<div class="card-header">
<h4 class="card-title">
<i class="fas fa-boxes me-2"></i>
Stock Information
</h4>
<div class="card-toolbar">
<span class="badge bg-{% if object.current_quantity <= object.minimum_quantity %}danger{% elif object.current_quantity <= object.reorder_level %}warning{% else %}success{% endif %} fs-6">
{% if object.current_quantity <= object.minimum_quantity %}
Critical Stock
{% elif object.current_quantity <= object.reorder_level %}
Low Stock
{% else %}
In Stock
{% endif %}
</span>
</div>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<table class="table table-borderless">
<tr>
<td class="fw-bold">Item:</td>
<td>
<a href="{% url 'inventory:item_detail' object.inventory_item.pk %}">
{{ object.inventory_item.item_name }}
</a>
</td>
</tr>
<tr>
<td class="fw-bold">SKU:</td>
<td>{{ object.inventory_item.item_code }}</td>
</tr>
<tr>
<td class="fw-bold">Category:</td>
<td>{{ object.inventory_item.get_category_display }}</td>
</tr>
<tr>
<td class="fw-bold">Location:</td>
<td>{{ object.location.name }}</td>
</tr>
<tr>
<td class="fw-bold">Current Quantity:</td>
<td>
<span class="fs-4 fw-bold {% if object.quantity_available <= object.inventory_item.min_stock_level %}text-danger{% elif object.quantity_available <= object.inventory_item.reorder_point %}text-warning{% else %}text-success{% endif %}">
{{ object.quantity_available }}
</span>
{{ object.inventory_item.unit_of_measure }}
</td>
</tr>
</table>
</div>
<div class="col-md-6">
<table class="table table-borderless">
<tr>
<td class="fw-bold">Minimum Quantity:</td>
<td>{{ object.inventory_item.min_stock_level }} {{ object.inventory_item.unit_of_measure }}</td>
</tr>
<tr>
<td class="fw-bold">Reorder Level:</td>
<td>{{ object.inventory_item.reorder_point }} {{ object.inventory_item.unit_of_measure }}</td>
</tr>
<tr>
<td class="fw-bold">Maximum Quantity:</td>
<td>{{ object.inventory_item.max_stock_level|default:"Not set" }} {{ object.item.unit_of_measure }}</td>
</tr>
<tr>
<td class="fw-bold">Unit Cost:</td>
<td><span class="symbol">&#xea;</span>{{ object.unit_cost|floatformat:'2g' }}</td>
</tr>
<tr>
<td class="fw-bold">Total Value:</td>
<td>
<span class="fs-5 fw-bold text-primary">
<span class="symbol">&#xea;</span>{{ object.total_cost|floatformat:'2g' }}
</span>
</td>
</tr>
</table>
</div>
</div>
<!-- Stock Level Progress Bar -->
<div class="mt-3">
<div class="d-flex justify-content-between mb-1">
<span>Stock Level</span>
<span>{{ object.quantity_available }} / {{ object.inventory_item.min_stock_level }} {{ object.inventory_item.unit_of_measure }}</span>
</div>
<div class="progress">
{% if object.inventory_item.max_stock_level %}
{% widthratio object.quantity_available object.inventory_item.max_stock_level 100 as percentage %}
{% else %}
{% widthratio object.quantity_available object.inventory_item.min_stock_level 100 as percentage %}
{% endif %}
<div class="progress-bar bg-{% if object.quantity_available <= object.inventory_item.min_stock_level %}danger{% elif object.quantity_available <= object.inventory_item.reorder_point %}warning{% else %}success{% endif %}"
style="width: {{ percentage|default:0 }}%"></div>
</div>
<div class="d-flex justify-content-between mt-1">
<small class="text-danger">Min: {{ object.inventory_item.min_stock_level }}</small>
<small class="text-warning">Reorder: {{ object.inventory_item.reorder_point }}</small>
{% if object.maximum_quantity %}
<small class="text-success">Max: {{ object.inventory_item.max_stock_level }}</small>
{% endif %}
</div>
</div>
{% if object.notes %}
<div class="mt-3">
<h6>Notes:</h6>
<div class="alert alert-info">
{{ object.notes }}
</div>
</div>
{% endif %}
</div>
</div>
<!-- Recent Transactions -->
<div class="card mb-4">
<div class="card-header">
<h4 class="card-title">
<i class="fas fa-history me-2"></i>
Recent Transactions
</h4>
<div class="card-toolbar">
<button type="button" class="btn btn-sm btn-outline-primary" onclick="refreshTransactions()">
<i class="fas fa-sync me-2"></i>Refresh
</button>
</div>
</div>
<div class="card-body">
{% if recent_transactions %}
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th>Date</th>
<th>Type</th>
<th>Quantity</th>
<th>Balance</th>
<th>Reference</th>
<th>User</th>
</tr>
</thead>
<tbody>
{% for transaction in recent_transactions %}
<tr>
<td>
<div>{{ transaction.date|date:"M d, Y" }}</div>
<div class="small text-muted">{{ transaction.date|time:"g:i A" }}</div>
</td>
<td>
<span class="badge bg-{% if transaction.transaction_type == 'in' %}success{% elif transaction.transaction_type == 'out' %}warning{% elif transaction.transaction_type == 'adjustment' %}info{% else %}secondary{% endif %}">
{{ transaction.get_transaction_type_display }}
</span>
</td>
<td>
<span class="{% if transaction.transaction_type == 'in' %}text-success{% elif transaction.transaction_type == 'out' %}text-warning{% endif %}">
{% if transaction.transaction_type == 'in' %}+{% elif transaction.transaction_type == 'out' %}-{% endif %}{{ transaction.quantity }}
</span>
</td>
<td>{{ transaction.balance_after }}</td>
<td>
{% if transaction.reference %}
{{ transaction.reference }}
{% else %}
<span class="text-muted">-</span>
{% endif %}
</td>
<td>{{ transaction.user.get_full_name|default:"System" }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="text-center mt-3">
<a href="#" class="btn btn-outline-primary" onclick="viewAllTransactions()">
<i class="fas fa-list me-2"></i>View All Transactions
</a>
</div>
{% else %}
<div class="text-center text-muted py-4">
<i class="fas fa-history fa-3x mb-3"></i>
<h5>No Transactions</h5>
<p>No transaction history available for this stock item.</p>
</div>
{% endif %}
</div>
</div>
<!-- Expiry Information -->
{% if expiring_batches %}
<div class="card">
<div class="card-header">
<h4 class="card-title">
<i class="fas fa-calendar-times me-2"></i>
Expiring Batches
</h4>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th>Batch Number</th>
<th>Quantity</th>
<th>Expiry Date</th>
<th>Days Left</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{% for batch in expiring_batches %}
<tr>
<td>{{ batch.batch_number }}</td>
<td>{{ batch.quantity }} {{ object.item.unit_of_measure }}</td>
<td>{{ batch.expiry_date|date:"M d, Y" }}</td>
<td>
<span class="{% if batch.days_until_expiry <= 7 %}text-danger{% elif batch.days_until_expiry <= 30 %}text-warning{% else %}text-success{% endif %}">
{{ batch.days_until_expiry }} days
</span>
</td>
<td>
<span class="badge bg-{% if batch.days_until_expiry <= 0 %}danger{% elif batch.days_until_expiry <= 7 %}warning{% elif batch.days_until_expiry <= 30 %}info{% else %}success{% endif %}">
{% if batch.days_until_expiry <= 0 %}
Expired
{% elif batch.days_until_expiry <= 7 %}
Critical
{% elif batch.days_until_expiry <= 30 %}
Warning
{% else %}
Good
{% endif %}
</span>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endif %}
</div>
<div class="col-xl-4">
<!-- Quick Actions -->
<div class="card mb-4">
<div class="card-header">
<h5 class="card-title">
<i class="fas fa-bolt me-2"></i>
Quick Actions
</h5>
</div>
<div class="card-body">
<div class="d-grid gap-2">
<button type="button" class="btn btn-success" onclick="adjustStock('add')">
<i class="fas fa-plus me-2"></i>Add Stock
</button>
<button type="button" class="btn btn-warning" onclick="adjustStock('remove')">
<i class="fas fa-minus me-2"></i>Remove Stock
</button>
<button type="button" class="btn btn-info" onclick="transferStock()">
<i class="fas fa-exchange-alt me-2"></i>Transfer Stock
</button>
<button type="button" class="btn btn-outline-primary" onclick="createOrder()">
<i class="fas fa-shopping-cart me-2"></i>Create Order
</button>
<button type="button" class="btn btn-outline-secondary" onclick="printLabel()">
<i class="fas fa-print me-2"></i>Print Label
</button>
</div>
</div>
</div>
<!-- Stock Statistics -->
<div class="card mb-4">
<div class="card-header">
<h5 class="card-title">
<i class="fas fa-chart-bar me-2"></i>
Statistics (30 days)
</h5>
</div>
<div class="card-body">
<div class="row text-center">
<div class="col-6">
<div class="border-end">
<div class="fs-4 fw-bold text-success">{{ stock_stats.total_in|default:0 }}</div>
<div class="small text-muted">Stock In</div>
</div>
</div>
<div class="col-6">
<div class="fs-4 fw-bold text-warning">{{ stock_stats.total_out|default:0 }}</div>
<div class="small text-muted">Stock Out</div>
</div>
</div>
<hr>
<div class="mb-3">
<div class="d-flex justify-content-between mb-1">
<span>Turnover Rate</span>
<span>{{ stock_stats.turnover_rate|default:0 }}%</span>
</div>
<div class="progress">
<div class="progress-bar bg-info" style="width: {{ stock_stats.turnover_rate|default:0 }}%"></div>
</div>
</div>
<div class="mb-2">
<strong>Average Daily Usage:</strong> {{ stock_stats.avg_daily_usage|default:0 }} {{ object.item.unit_of_measure }}
</div>
<div>
<strong>Days of Stock:</strong> {{ stock_stats.days_of_stock|default:0 }} days
</div>
</div>
</div>
<!-- Supplier Information -->
{% if object.item.suppliers.exists %}
<div class="card mb-4">
<div class="card-header">
<h5 class="card-title">
<i class="fas fa-truck me-2"></i>
Suppliers
</h5>
</div>
<div class="card-body">
{% for supplier in object.item.suppliers.all %}
<div class="d-flex align-items-center mb-3">
<div class="flex-grow-1">
<div class="fw-bold">
<a href="{% url 'inventory:supplier_detail' supplier.pk %}">
{{ supplier.name }}
</a>
</div>
<div class="small text-muted">{{ supplier.contact_person }}</div>
<div class="small text-muted">{{ supplier.phone }}</div>
</div>
<div class="flex-shrink-0">
<button type="button" class="btn btn-sm btn-outline-primary" onclick="contactSupplier('{{ supplier.pk }}')">
<i class="fas fa-phone"></i>
</button>
</div>
</div>
{% endfor %}
</div>
</div>
{% endif %}
<!-- Alerts -->
{% if alerts %}
<div class="card mb-4">
<div class="card-header">
<h5 class="card-title">
<i class="fas fa-exclamation-triangle me-2"></i>
Alerts
</h5>
</div>
<div class="card-body">
{% for alert in alerts %}
<div class="alert alert-{% if alert.severity == 'critical' %}danger{% elif alert.severity == 'warning' %}warning{% else %}info{% endif %} alert-dismissible fade show" role="alert">
<strong>{{ alert.get_severity_display }}:</strong> {{ alert.message }}
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
{% endfor %}
</div>
</div>
{% endif %}
<!-- Location Information -->
<div class="card">
<div class="card-header">
<h5 class="card-title">
<i class="fas fa-map-marker-alt me-2"></i>
Location Details
</h5>
</div>
<div class="card-body">
<div class="mb-2">
<strong>Location:</strong> {{ object.location.name }}
</div>
<div class="mb-2">
<strong>Zone:</strong> {{ object.location.zone|default:"Not specified" }}
</div>
<div class="mb-2">
<strong>Aisle:</strong> {{ object.location.aisle|default:"Not specified" }}
</div>
<div class="mb-2">
<strong>Shelf:</strong> {{ object.location.shelf|default:"Not specified" }}
</div>
<div>
<strong>Temperature:</strong> {{ object.location.temperature_range|default:"Room temperature" }}
</div>
</div>
</div>
</div>
</div>
<!-- Stock Adjustment Modal -->
<div class="modal fade" id="stockAdjustmentModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Stock Adjustment</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<form id="stockAdjustmentForm">
{% csrf_token %}
<input type="hidden" id="adjustmentType" name="adjustment_type">
<div class="mb-3">
<label for="adjustmentQuantity" class="form-label">Quantity</label>
<input type="number" class="form-control" id="adjustmentQuantity" name="quantity" min="1" required>
</div>
<div class="mb-3">
<label for="adjustmentReason" class="form-label">Reason</label>
<select class="form-select" id="adjustmentReason" name="reason" required>
<option value="">Select reason</option>
<option value="received">Stock Received</option>
<option value="dispensed">Stock Dispensed</option>
<option value="damaged">Damaged/Expired</option>
<option value="lost">Lost/Stolen</option>
<option value="correction">Inventory Correction</option>
<option value="transfer">Transfer</option>
<option value="other">Other</option>
</select>
</div>
<div class="mb-3">
<label for="adjustmentNotes" class="form-label">Notes</label>
<textarea class="form-control" id="adjustmentNotes" name="notes" rows="3"></textarea>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" onclick="confirmAdjustment()">Confirm Adjustment</button>
</div>
</div>
</div>
</div>
<script>
function adjustStock(type) {
document.getElementById('adjustmentType').value = type;
const modal = new bootstrap.Modal(document.getElementById('stockAdjustmentModal'));
modal.show();
}
function confirmAdjustment() {
const form = document.getElementById('stockAdjustmentForm');
const formData = new FormData(form);
// In a real implementation, this would submit via AJAX
console.log('Stock adjustment:', formData.get('adjustment_type'), formData.get('quantity'));
// Close modal and refresh page
bootstrap.Modal.getInstance(document.getElementById('stockAdjustmentModal')).hide();
location.reload();
}
function transferStock() {
// In a real implementation, this would open a transfer modal
alert('Stock transfer functionality would be implemented here.');
}
function createOrder() {
// In a real implementation, this would create a purchase order
alert('Purchase order creation would be implemented here.');
}
function printLabel() {
// In a real implementation, this would print a stock label
window.print();
}
function contactSupplier(supplierId) {
// In a real implementation, this would open supplier contact modal
alert('Supplier contact functionality would be implemented here.');
}
function refreshTransactions() {
// In a real implementation, this would refresh transactions via AJAX
location.reload();
}
function viewAllTransactions() {
// In a real implementation, this would show all transactions
alert('Full transaction history would be displayed here.');
}
function generateReport() {
// In a real implementation, this would generate a stock report
alert('Stock report generation would be implemented here.');
}
</script>
{% endblock %}