Marwan Alwali fd2f7259c0 update
2025-08-14 18:05:05 +03:00

419 lines
18 KiB
HTML

<!-- Adjust Stock Modal -->
<div class="modal fade" id="adjustStockModal" tabindex="-1" aria-labelledby="adjustStockModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="adjustStockModalLabel">
<i class="fas fa-balance-scale me-2"></i>Adjust Stock
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<form id="adjustStockForm" method="post">
{% csrf_token %}
<div class="modal-body">
<!-- Item Information -->
<div class="row mb-4">
<div class="col-12">
<div class="card bg-light">
<div class="card-body">
<div class="row">
<div class="col-md-8">
<h6 class="card-title mb-1" id="adjust-item-name">Item Name</h6>
<p class="card-text small text-muted mb-1">
<span class="me-3">
<i class="fas fa-barcode me-1"></i>
<span id="adjust-item-code">Item Code</span>
</span>
<span class="me-3">
<i class="fas fa-layer-group me-1"></i>
<span id="adjust-item-category">Category</span>
</span>
</p>
<p class="card-text small text-muted mb-0">
<i class="fas fa-map-marker-alt me-1"></i>
<span id="adjust-item-location">Location</span>
</p>
</div>
<div class="col-md-4 text-end">
<div class="current-stock">
<small class="text-muted">Current Stock</small>
<h4 class="mb-0" id="adjust-current-stock">0</h4>
<small class="text-muted" id="adjust-stock-unit">units</small>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Adjustment Details -->
<div class="row">
<div class="col-md-6">
<div class="form-group mb-3">
<label class="form-label" for="adjustment_type">
Adjustment Type <span class="text-danger">*</span>
</label>
<select class="form-select" id="adjustment_type" name="adjustment_type" required>
<option value="">Select adjustment type...</option>
<option value="increase">Increase Stock</option>
<option value="decrease">Decrease Stock</option>
<option value="set">Set Exact Amount</option>
</select>
</div>
</div>
<div class="col-md-6">
<div class="form-group mb-3">
<label class="form-label" for="adjustment_quantity">
<span id="quantity-label">Quantity</span> <span class="text-danger">*</span>
</label>
<div class="input-group">
<input type="number" class="form-control" id="adjustment_quantity"
name="adjustment_quantity" min="0" step="0.01" required>
<span class="input-group-text" id="adjust-quantity-unit">units</span>
</div>
<small class="form-text text-muted" id="quantity-help">
Enter the amount to adjust
</small>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group mb-3">
<label class="form-label" for="adjustment_reason">
Reason <span class="text-danger">*</span>
</label>
<select class="form-select" id="adjustment_reason" name="adjustment_reason" required>
<option value="">Select reason...</option>
<option value="damaged">Damaged/Expired</option>
<option value="lost">Lost/Stolen</option>
<option value="found">Found/Recovered</option>
<option value="recount">Physical Recount</option>
<option value="return">Return to Supplier</option>
<option value="donation">Donation</option>
<option value="correction">Data Correction</option>
<option value="other">Other</option>
</select>
</div>
</div>
<div class="col-md-6">
<div class="form-group mb-3">
<label class="form-label" for="adjustment_reference">
Reference Number
</label>
<input type="text" class="form-control" id="adjustment_reference"
name="adjustment_reference" placeholder="Optional reference number">
<small class="form-text text-muted">
PO number, incident report, etc.
</small>
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="form-group mb-3">
<label class="form-label" for="adjustment_notes">
Notes
</label>
<textarea class="form-control" id="adjustment_notes" name="adjustment_notes"
rows="3" placeholder="Additional notes about this adjustment..."></textarea>
</div>
</div>
</div>
<!-- Calculation Preview -->
<div class="row">
<div class="col-12">
<div class="card border-info" id="calculation-preview" style="display: none;">
<div class="card-header bg-info text-white">
<h6 class="card-title mb-0">
<i class="fas fa-calculator me-2"></i>Adjustment Preview
</h6>
</div>
<div class="card-body">
<div class="row text-center">
<div class="col-md-4">
<div class="preview-item">
<small class="text-muted">Current Stock</small>
<h5 class="mb-0" id="preview-current">0</h5>
</div>
</div>
<div class="col-md-4">
<div class="preview-item">
<small class="text-muted">Adjustment</small>
<h5 class="mb-0" id="preview-adjustment">0</h5>
</div>
</div>
<div class="col-md-4">
<div class="preview-item">
<small class="text-muted">New Stock</small>
<h5 class="mb-0 text-primary" id="preview-new">0</h5>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Warnings -->
<div id="adjustment-warnings" style="display: none;">
<div class="alert alert-warning">
<i class="fas fa-exclamation-triangle me-2"></i>
<span id="warning-message">Warning message</span>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
<i class="fas fa-times me-1"></i>Cancel
</button>
<button type="submit" class="btn btn-primary" id="adjust-submit-btn" disabled>
<i class="fas fa-save me-1"></i>Apply Adjustment
</button>
</div>
</form>
</div>
</div>
</div>
<script>
$(document).ready(function() {
// Initialize adjust stock modal
$('#adjustStockModal').on('show.bs.modal', function(event) {
const button = $(event.relatedTarget);
const itemId = button.data('item-id');
const itemName = button.data('item-name');
const itemCode = button.data('item-code');
const itemCategory = button.data('item-category');
const itemLocation = button.data('item-location');
const currentStock = button.data('current-stock');
const stockUnit = button.data('stock-unit');
// Update modal content
$('#adjust-item-name').text(itemName);
$('#adjust-item-code').text(itemCode);
$('#adjust-item-category').text(itemCategory);
$('#adjust-item-location').text(itemLocation);
$('#adjust-current-stock').text(currentStock);
$('#adjust-stock-unit').text(stockUnit);
$('#adjust-quantity-unit').text(stockUnit);
// Store item data
$('#adjustStockForm').data('item-id', itemId);
$('#adjustStockForm').data('current-stock', currentStock);
$('#adjustStockForm').data('stock-unit', stockUnit);
// Reset form
$('#adjustStockForm')[0].reset();
$('#calculation-preview').hide();
$('#adjustment-warnings').hide();
$('#adjust-submit-btn').prop('disabled', true);
});
// Handle adjustment type change
$('#adjustment_type').on('change', function() {
const type = $(this).val();
const quantityLabel = $('#quantity-label');
const quantityHelp = $('#quantity-help');
switch(type) {
case 'increase':
quantityLabel.text('Increase By');
quantityHelp.text('Enter amount to add to current stock');
break;
case 'decrease':
quantityLabel.text('Decrease By');
quantityHelp.text('Enter amount to subtract from current stock');
break;
case 'set':
quantityLabel.text('Set To');
quantityHelp.text('Enter the exact stock amount');
break;
default:
quantityLabel.text('Quantity');
quantityHelp.text('Enter the amount to adjust');
}
updateCalculationPreview();
});
// Handle quantity change
$('#adjustment_quantity, #adjustment_reason').on('input change', function() {
updateCalculationPreview();
});
// Form submission
$('#adjustStockForm').on('submit', function(e) {
e.preventDefault();
const formData = new FormData(this);
const itemId = $(this).data('item-id');
// Add item ID to form data
formData.append('item_id', itemId);
// Show loading state
const submitBtn = $('#adjust-submit-btn');
const originalText = submitBtn.html();
submitBtn.html('<i class="fas fa-spinner fa-spin me-1"></i>Processing...').prop('disabled', true);
$.ajax({
url: '{% url "pharmacy:adjust_inventory" 0 %}'.replace('0', itemId);
method: 'POST',
data: formData,
processData: false,
contentType: false,
success: function(response) {
if (response.success) {
// Show success message
showToast('success', 'Stock adjusted successfully');
// Close modal
$('#adjustStockModal').modal('hide');
// Refresh page or update stock display
if (typeof refreshStockData === 'function') {
refreshStockData();
} else {
location.reload();
}
} else {
showToast('error', response.message || 'Error adjusting stock');
}
},
error: function(xhr) {
let errorMessage = 'Error adjusting stock';
if (xhr.responseJSON && xhr.responseJSON.message) {
errorMessage = xhr.responseJSON.message;
}
showToast('error', errorMessage);
},
complete: function() {
// Restore button state
submitBtn.html(originalText).prop('disabled', false);
}
});
});
});
function updateCalculationPreview() {
const type = $('#adjustment_type').val();
const quantity = parseFloat($('#adjustment_quantity').val()) || 0;
const reason = $('#adjustment_reason').val();
const currentStock = parseFloat($('#adjustStockForm').data('current-stock')) || 0;
if (!type || !quantity || !reason) {
$('#calculation-preview').hide();
$('#adjustment-warnings').hide();
$('#adjust-submit-btn').prop('disabled', true);
return;
}
let newStock = currentStock;
let adjustmentDisplay = '';
switch(type) {
case 'increase':
newStock = currentStock + quantity;
adjustmentDisplay = '+' + quantity;
break;
case 'decrease':
newStock = currentStock - quantity;
adjustmentDisplay = '-' + quantity;
break;
case 'set':
newStock = quantity;
adjustmentDisplay = quantity + ' (set)';
break;
}
// Update preview
$('#preview-current').text(currentStock);
$('#preview-adjustment').text(adjustmentDisplay);
$('#preview-new').text(newStock);
// Show/hide warnings
let hasWarning = false;
if (newStock < 0) {
$('#warning-message').text('This adjustment will result in negative stock!');
$('#adjustment-warnings').show();
hasWarning = true;
} else if (newStock === 0 && type === 'decrease') {
$('#warning-message').text('This adjustment will deplete all stock.');
$('#adjustment-warnings').show();
hasWarning = true;
} else {
$('#adjustment-warnings').hide();
}
// Show preview
$('#calculation-preview').show();
// Enable/disable submit button
$('#adjust-submit-btn').prop('disabled', false);
}
function showToast(type, message) {
// Simple toast notification
const toastClass = type === 'success' ? 'alert-success' : 'alert-danger';
const toastHtml = `
<div class="alert ${toastClass} alert-dismissible fade show position-fixed"
style="top: 20px; right: 20px; z-index: 9999;">
${message}
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
`;
$('body').append(toastHtml);
// Auto-remove after 5 seconds
setTimeout(function() {
$('.alert').fadeOut();
}, 5000);
}
</script>
<style>
.preview-item {
padding: 10px;
border-right: 1px solid #dee2e6;
}
.preview-item:last-child {
border-right: none;
}
.current-stock {
text-align: center;
padding: 10px;
background: #f8f9fa;
border-radius: 5px;
}
#calculation-preview .card-body {
padding: 15px;
}
.modal-lg {
max-width: 800px;
}
/* Mobile responsive */
@media (max-width: 768px) {
.preview-item {
border-right: none;
border-bottom: 1px solid #dee2e6;
margin-bottom: 10px;
}
.preview-item:last-child {
border-bottom: none;
margin-bottom: 0;
}
}
</style>