744 lines
29 KiB
HTML
744 lines
29 KiB
HTML
{% extends 'base.html' %}
|
|
{% load static %}
|
|
|
|
{% block title %}{% if form.instance.pk %}Edit{% else %}Add{% endif %} Equipment{% endblock %}
|
|
|
|
{% block extra_css %}
|
|
<style>
|
|
.form-header {
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
color: white;
|
|
border-radius: 0.5rem;
|
|
padding: 2rem;
|
|
margin-bottom: 2rem;
|
|
}
|
|
|
|
.form-section {
|
|
background: white;
|
|
border: 1px solid #dee2e6;
|
|
border-radius: 0.375rem;
|
|
margin-bottom: 1.5rem;
|
|
}
|
|
|
|
.section-header {
|
|
background: #f8f9fa;
|
|
border-bottom: 1px solid #dee2e6;
|
|
padding: 1rem 1.5rem;
|
|
font-weight: 600;
|
|
color: #495057;
|
|
}
|
|
|
|
.section-content {
|
|
padding: 1.5rem;
|
|
}
|
|
|
|
.image-upload-area {
|
|
border: 2px dashed #dee2e6;
|
|
border-radius: 0.375rem;
|
|
padding: 2rem;
|
|
text-align: center;
|
|
background: #f8f9fa;
|
|
transition: all 0.3s ease;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.image-upload-area:hover {
|
|
border-color: #007bff;
|
|
background: #e7f3ff;
|
|
}
|
|
|
|
.image-upload-area.dragover {
|
|
border-color: #007bff;
|
|
background: #e7f3ff;
|
|
}
|
|
|
|
.image-preview {
|
|
max-width: 200px;
|
|
max-height: 200px;
|
|
border-radius: 0.375rem;
|
|
border: 2px solid #dee2e6;
|
|
margin: 1rem auto;
|
|
}
|
|
|
|
.specifications-builder {
|
|
border: 1px solid #dee2e6;
|
|
border-radius: 0.375rem;
|
|
padding: 1rem;
|
|
background: #f8f9fa;
|
|
}
|
|
|
|
.spec-item {
|
|
display: flex;
|
|
gap: 0.5rem;
|
|
margin-bottom: 0.5rem;
|
|
align-items: center;
|
|
}
|
|
|
|
.spec-item input {
|
|
flex: 1;
|
|
}
|
|
|
|
.maintenance-schedule {
|
|
background: #fff3cd;
|
|
border: 1px solid #ffeaa7;
|
|
border-radius: 0.375rem;
|
|
padding: 1rem;
|
|
margin-top: 1rem;
|
|
}
|
|
|
|
.cost-calculator {
|
|
background: #e7f3ff;
|
|
border: 1px solid #b3d9ff;
|
|
border-radius: 0.375rem;
|
|
padding: 1rem;
|
|
margin-top: 1rem;
|
|
}
|
|
|
|
.validation-feedback {
|
|
display: block;
|
|
width: 100%;
|
|
margin-top: 0.25rem;
|
|
font-size: 0.875rem;
|
|
}
|
|
|
|
.validation-feedback.valid {
|
|
color: #28a745;
|
|
}
|
|
|
|
.validation-feedback.invalid {
|
|
color: #dc3545;
|
|
}
|
|
|
|
.auto-generate-btn {
|
|
position: absolute;
|
|
right: 0.5rem;
|
|
top: 50%;
|
|
transform: translateY(-50%);
|
|
border: none;
|
|
background: #007bff;
|
|
color: white;
|
|
border-radius: 0.25rem;
|
|
padding: 0.25rem 0.5rem;
|
|
font-size: 0.75rem;
|
|
}
|
|
|
|
.input-group-auto {
|
|
position: relative;
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.form-header {
|
|
padding: 1.5rem;
|
|
}
|
|
|
|
.section-content {
|
|
padding: 1rem;
|
|
}
|
|
|
|
.spec-item {
|
|
flex-direction: column;
|
|
}
|
|
|
|
.spec-item input {
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
}
|
|
</style>
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<div id="content" class="app-content">
|
|
<!-- Page Header -->
|
|
<div class="d-flex align-items-center mb-3">
|
|
<div>
|
|
<ol class="breadcrumb">
|
|
<li class="breadcrumb-item"><a href="{% url 'core:dashboard' %}">Dashboard</a></li>
|
|
<li class="breadcrumb-item"><a href="{% url 'operating_theatre:dashboard' %}">Operating Theatre</a></li>
|
|
<li class="breadcrumb-item"><a href="{% url 'operating_theatre:equipment_list' %}">Equipment</a></li>
|
|
<li class="breadcrumb-item active">{% if form.instance.pk %}Edit{% else %}Add{% endif %} Equipment</li>
|
|
</ol>
|
|
<h1 class="page-header mb-0">
|
|
<i class="fas fa-tools me-2"></i>{% if form.instance.pk %}Edit{% else %}Add{% endif %} Equipment
|
|
</h1>
|
|
</div>
|
|
<div class="ms-auto">
|
|
<a href="{% url 'operating_theatre:equipment_list' %}" class="btn btn-outline-secondary">
|
|
<i class="fas fa-arrow-left me-1"></i>Back to List
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Form Header -->
|
|
<div class="form-header">
|
|
<div class="row">
|
|
<div class="col-md-8">
|
|
<h2 class="mb-3">{% if form.instance.pk %}Edit Equipment{% else %}Add New Equipment{% endif %}</h2>
|
|
<p class="mb-0">
|
|
{% if form.instance.pk %}
|
|
Update the equipment information. Changes will be logged for audit purposes.
|
|
{% else %}
|
|
Add new equipment to the operating theatre inventory. All fields marked with * are required.
|
|
{% endif %}
|
|
</p>
|
|
</div>
|
|
<div class="col-md-4 text-end">
|
|
<div class="mb-2">
|
|
<i class="fas fa-info-circle me-2"></i>
|
|
<span>Equipment tracking helps optimize OR efficiency</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<form method="post" enctype="multipart/form-data" id="equipmentForm">
|
|
{% csrf_token %}
|
|
|
|
<!-- Basic Information -->
|
|
<div class="form-section">
|
|
<div class="section-header">
|
|
<i class="fas fa-info-circle me-2"></i>Basic Information
|
|
</div>
|
|
<div class="section-content">
|
|
<div class="row">
|
|
<div class="col-md-8">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-group mb-3">
|
|
<label class="form-label required">Equipment Name</label>
|
|
{{ form.name }}
|
|
{% if form.name.errors %}
|
|
<div class="validation-feedback invalid">{{ form.name.errors.0 }}</div>
|
|
{% endif %}
|
|
<div class="form-text">Descriptive name for the equipment</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-group mb-3">
|
|
<label class="form-label required">Category</label>
|
|
{{ form.category }}
|
|
{% if form.category.errors %}
|
|
<div class="validation-feedback invalid">{{ form.category.errors.0 }}</div>
|
|
{% endif %}
|
|
<div class="form-text">Equipment category for organization</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group mb-3">
|
|
<label class="form-label">Description</label>
|
|
{{ form.description }}
|
|
{% if form.description.errors %}
|
|
<div class="validation-feedback invalid">{{ form.description.errors.0 }}</div>
|
|
{% endif %}
|
|
<div class="form-text">Detailed description of the equipment</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-group mb-3">
|
|
<label class="form-label">Equipment ID</label>
|
|
<div class="input-group-auto">
|
|
{{ form.equipment_id }}
|
|
<button type="button" class="auto-generate-btn" onclick="generateEquipmentId()">
|
|
<i class="fas fa-magic"></i>
|
|
</button>
|
|
</div>
|
|
{% if form.equipment_id.errors %}
|
|
<div class="validation-feedback invalid">{{ form.equipment_id.errors.0 }}</div>
|
|
{% endif %}
|
|
<div class="form-text">Unique identifier for the equipment</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-group mb-3">
|
|
<label class="form-label required">Serial Number</label>
|
|
{{ form.serial_number }}
|
|
{% if form.serial_number.errors %}
|
|
<div class="validation-feedback invalid">{{ form.serial_number.errors.0 }}</div>
|
|
{% endif %}
|
|
<div class="form-text">Manufacturer's serial number</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-4">
|
|
<div class="form-group mb-3">
|
|
<label class="form-label">Equipment Image</label>
|
|
<div class="image-upload-area" onclick="$('#id_image').click()">
|
|
{% if form.instance.image %}
|
|
<img src="{{ form.instance.image.url }}" alt="Equipment Image" class="image-preview" id="imagePreview">
|
|
{% else %}
|
|
<div id="uploadPlaceholder">
|
|
<i class="fas fa-camera fa-3x text-muted mb-2"></i>
|
|
<div class="text-muted">Click to upload image</div>
|
|
<small class="text-muted">JPG, PNG up to 5MB</small>
|
|
</div>
|
|
<img id="imagePreview" class="image-preview" style="display: none;">
|
|
{% endif %}
|
|
</div>
|
|
{{ form.image }}
|
|
{% if form.image.errors %}
|
|
<div class="validation-feedback invalid">{{ form.image.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Manufacturer Information -->
|
|
<div class="form-section">
|
|
<div class="section-header">
|
|
<i class="fas fa-industry me-2"></i>Manufacturer Information
|
|
</div>
|
|
<div class="section-content">
|
|
<div class="row">
|
|
<div class="col-md-4">
|
|
<div class="form-group mb-3">
|
|
<label class="form-label required">Manufacturer</label>
|
|
{{ form.manufacturer }}
|
|
{% if form.manufacturer.errors %}
|
|
<div class="validation-feedback invalid">{{ form.manufacturer.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="form-group mb-3">
|
|
<label class="form-label required">Model</label>
|
|
{{ form.model }}
|
|
{% if form.model.errors %}
|
|
<div class="validation-feedback invalid">{{ form.model.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="form-group mb-3">
|
|
<label class="form-label">Model Year</label>
|
|
{{ form.model_year }}
|
|
{% if form.model_year.errors %}
|
|
<div class="validation-feedback invalid">{{ form.model_year.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Location and Status -->
|
|
<div class="form-section">
|
|
<div class="section-header">
|
|
<i class="fas fa-map-marker-alt me-2"></i>Location and Status
|
|
</div>
|
|
<div class="section-content">
|
|
<div class="row">
|
|
<div class="col-md-4">
|
|
<div class="form-group mb-3">
|
|
<label class="form-label">Current Location</label>
|
|
{{ form.current_location }}
|
|
{% if form.current_location.errors %}
|
|
<div class="validation-feedback invalid">{{ form.current_location.errors.0 }}</div>
|
|
{% endif %}
|
|
<div class="form-text">Operating room or storage location</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="form-group mb-3">
|
|
<label class="form-label required">Status</label>
|
|
{{ form.status }}
|
|
{% if form.status.errors %}
|
|
<div class="validation-feedback invalid">{{ form.status.errors.0 }}</div>
|
|
{% endif %}
|
|
<div class="form-text">Current operational status</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="form-group mb-3">
|
|
<label class="form-label">Asset Tag</label>
|
|
<div class="input-group-auto">
|
|
{{ form.asset_tag }}
|
|
<button type="button" class="auto-generate-btn" onclick="generateAssetTag()">
|
|
<i class="fas fa-magic"></i>
|
|
</button>
|
|
</div>
|
|
{% if form.asset_tag.errors %}
|
|
<div class="validation-feedback invalid">{{ form.asset_tag.errors.0 }}</div>
|
|
{% endif %}
|
|
<div class="form-text">Hospital asset tracking number</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Financial Information -->
|
|
<div class="form-section">
|
|
<div class="section-header">
|
|
<i class="fas fa-dollar-sign me-2"></i>Financial Information
|
|
</div>
|
|
<div class="section-content">
|
|
<div class="row">
|
|
<div class="col-md-3">
|
|
<div class="form-group mb-3">
|
|
<label class="form-label">Purchase Date</label>
|
|
{{ form.purchase_date }}
|
|
{% if form.purchase_date.errors %}
|
|
<div class="validation-feedback invalid">{{ form.purchase_date.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="form-group mb-3">
|
|
<label class="form-label">Purchase Cost</label>
|
|
{{ form.purchase_cost }}
|
|
{% if form.purchase_cost.errors %}
|
|
<div class="validation-feedback invalid">{{ form.purchase_cost.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="form-group mb-3">
|
|
<label class="form-label">Warranty Expiry</label>
|
|
{{ form.warranty_expiry }}
|
|
{% if form.warranty_expiry.errors %}
|
|
<div class="validation-feedback invalid">{{ form.warranty_expiry.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<div class="form-group mb-3">
|
|
<label class="form-label">Depreciation Rate (%)</label>
|
|
{{ form.depreciation_rate }}
|
|
{% if form.depreciation_rate.errors %}
|
|
<div class="validation-feedback invalid">{{ form.depreciation_rate.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="cost-calculator">
|
|
<h6 class="mb-2">
|
|
<i class="fas fa-calculator me-2"></i>Cost Analysis
|
|
</h6>
|
|
<div class="row">
|
|
<div class="col-md-4">
|
|
<div class="text-center">
|
|
<div class="h5 text-primary" id="currentValue">$0.00</div>
|
|
<small class="text-muted">Current Value</small>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="text-center">
|
|
<div class="h5 text-warning" id="annualDepreciation">$0.00</div>
|
|
<small class="text-muted">Annual Depreciation</small>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="text-center">
|
|
<div class="h5 text-info" id="equipmentAge">0 years</div>
|
|
<small class="text-muted">Equipment Age</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Technical Specifications -->
|
|
<div class="form-section">
|
|
<div class="section-header">
|
|
<i class="fas fa-cogs me-2"></i>Technical Specifications
|
|
</div>
|
|
<div class="section-content">
|
|
<div class="specifications-builder">
|
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
|
<h6 class="mb-0">Equipment Specifications</h6>
|
|
<button type="button" class="btn btn-outline-primary btn-sm" onclick="addSpecification()">
|
|
<i class="fas fa-plus me-1"></i>Add Specification
|
|
</button>
|
|
</div>
|
|
|
|
<div id="specificationsContainer">
|
|
{% if form.instance.specifications %}
|
|
{% for spec, value in form.instance.specifications.items %}
|
|
<div class="spec-item">
|
|
<input type="text" class="form-control" placeholder="Specification name" value="{{ spec }}" name="spec_name[]">
|
|
<input type="text" class="form-control" placeholder="Value" value="{{ value }}" name="spec_value[]">
|
|
<button type="button" class="btn btn-outline-danger btn-sm" onclick="removeSpecification(this)">
|
|
<i class="fas fa-trash"></i>
|
|
</button>
|
|
</div>
|
|
{% endfor %}
|
|
{% endif %}
|
|
</div>
|
|
|
|
<div class="form-text mt-2">
|
|
Add technical specifications like power requirements, dimensions, weight, etc.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Maintenance Information -->
|
|
<div class="form-section">
|
|
<div class="section-header">
|
|
<i class="fas fa-wrench me-2"></i>Maintenance Information
|
|
</div>
|
|
<div class="section-content">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-group mb-3">
|
|
<label class="form-label">Last Maintenance Date</label>
|
|
{{ form.last_maintenance_date }}
|
|
{% if form.last_maintenance_date.errors %}
|
|
<div class="validation-feedback invalid">{{ form.last_maintenance_date.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-group mb-3">
|
|
<label class="form-label">Maintenance Interval (days)</label>
|
|
{{ form.maintenance_interval }}
|
|
{% if form.maintenance_interval.errors %}
|
|
<div class="validation-feedback invalid">{{ form.maintenance_interval.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="maintenance-schedule">
|
|
<h6 class="mb-2">
|
|
<i class="fas fa-calendar-alt me-2"></i>Maintenance Schedule
|
|
</h6>
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="mb-2">
|
|
<strong>Next Maintenance Due:</strong> <span id="nextMaintenanceDate">Not calculated</span>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="mb-2">
|
|
<strong>Days Until Due:</strong> <span id="daysUntilMaintenance">-</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Notes -->
|
|
<div class="form-section">
|
|
<div class="section-header">
|
|
<i class="fas fa-sticky-note me-2"></i>Additional Information
|
|
</div>
|
|
<div class="section-content">
|
|
<div class="form-group mb-3">
|
|
<label class="form-label">Notes</label>
|
|
{{ form.notes }}
|
|
{% if form.notes.errors %}
|
|
<div class="validation-feedback invalid">{{ form.notes.errors.0 }}</div>
|
|
{% endif %}
|
|
<div class="form-text">Additional notes, special instructions, or important information</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Form Actions -->
|
|
<div class="d-flex justify-content-between">
|
|
<div>
|
|
<a href="{% url 'operating_theatre:equipment_list' %}" class="btn btn-outline-secondary">
|
|
<i class="fas fa-times me-1"></i>Cancel
|
|
</a>
|
|
</div>
|
|
<div>
|
|
<button type="button" class="btn btn-outline-info me-2" onclick="previewEquipment()">
|
|
<i class="fas fa-eye me-1"></i>Preview
|
|
</button>
|
|
<button type="submit" class="btn btn-primary">
|
|
<i class="fas fa-save me-1"></i>
|
|
{% if form.instance.pk %}Update Equipment{% else %}Add Equipment{% endif %}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block extra_js %}
|
|
<script>
|
|
$(document).ready(function() {
|
|
// Initialize calculations
|
|
calculateCosts();
|
|
calculateMaintenanceSchedule();
|
|
|
|
// Form change handlers
|
|
$('#id_purchase_cost, #id_purchase_date, #id_depreciation_rate').on('change', calculateCosts);
|
|
$('#id_last_maintenance_date, #id_maintenance_interval').on('change', calculateMaintenanceSchedule);
|
|
|
|
// Image upload handler
|
|
$('#id_image').on('change', function(e) {
|
|
const file = e.target.files[0];
|
|
if (file) {
|
|
const reader = new FileReader();
|
|
reader.onload = function(e) {
|
|
$('#imagePreview').attr('src', e.target.result).show();
|
|
$('#uploadPlaceholder').hide();
|
|
};
|
|
reader.readAsDataURL(file);
|
|
}
|
|
});
|
|
|
|
// Drag and drop for image upload
|
|
$('.image-upload-area').on('dragover', function(e) {
|
|
e.preventDefault();
|
|
$(this).addClass('dragover');
|
|
});
|
|
|
|
$('.image-upload-area').on('dragleave', function(e) {
|
|
e.preventDefault();
|
|
$(this).removeClass('dragover');
|
|
});
|
|
|
|
$('.image-upload-area').on('drop', function(e) {
|
|
e.preventDefault();
|
|
$(this).removeClass('dragover');
|
|
|
|
const files = e.originalEvent.dataTransfer.files;
|
|
if (files.length > 0) {
|
|
$('#id_image')[0].files = files;
|
|
$('#id_image').trigger('change');
|
|
}
|
|
});
|
|
});
|
|
|
|
function generateEquipmentId() {
|
|
const category = $('#id_category').val();
|
|
const timestamp = Date.now().toString().slice(-6);
|
|
const equipmentId = `EQ-${category}-${timestamp}`;
|
|
$('#id_equipment_id').val(equipmentId);
|
|
}
|
|
|
|
function generateAssetTag() {
|
|
const timestamp = Date.now().toString().slice(-8);
|
|
const assetTag = `AT-${timestamp}`;
|
|
$('#id_asset_tag').val(assetTag);
|
|
}
|
|
|
|
function addSpecification() {
|
|
const container = $('#specificationsContainer');
|
|
const specItem = $(`
|
|
<div class="spec-item">
|
|
<input type="text" class="form-control" placeholder="Specification name" name="spec_name[]">
|
|
<input type="text" class="form-control" placeholder="Value" name="spec_value[]">
|
|
<button type="button" class="btn btn-outline-danger btn-sm" onclick="removeSpecification(this)">
|
|
<i class="fas fa-trash"></i>
|
|
</button>
|
|
</div>
|
|
`);
|
|
container.append(specItem);
|
|
}
|
|
|
|
function removeSpecification(button) {
|
|
$(button).closest('.spec-item').remove();
|
|
}
|
|
|
|
function calculateCosts() {
|
|
const purchaseCost = parseFloat($('#id_purchase_cost').val()) || 0;
|
|
const purchaseDate = $('#id_purchase_date').val();
|
|
const depreciationRate = parseFloat($('#id_depreciation_rate').val()) || 0;
|
|
|
|
if (purchaseCost > 0 && purchaseDate && depreciationRate > 0) {
|
|
const purchaseDateObj = new Date(purchaseDate);
|
|
const currentDate = new Date();
|
|
const yearsOld = (currentDate - purchaseDateObj) / (1000 * 60 * 60 * 24 * 365.25);
|
|
|
|
const annualDepreciation = purchaseCost * (depreciationRate / 100);
|
|
const totalDepreciation = annualDepreciation * yearsOld;
|
|
const currentValue = Math.max(0, purchaseCost - totalDepreciation);
|
|
|
|
$('#currentValue').text('$' + currentValue.toFixed(2));
|
|
$('#annualDepreciation').text('$' + annualDepreciation.toFixed(2));
|
|
$('#equipmentAge').text(yearsOld.toFixed(1) + ' years');
|
|
} else {
|
|
$('#currentValue').text('$0.00');
|
|
$('#annualDepreciation').text('$0.00');
|
|
$('#equipmentAge').text('0 years');
|
|
}
|
|
}
|
|
|
|
function calculateMaintenanceSchedule() {
|
|
const lastMaintenanceDate = $('#id_last_maintenance_date').val();
|
|
const maintenanceInterval = parseInt($('#id_maintenance_interval').val()) || 0;
|
|
|
|
if (lastMaintenanceDate && maintenanceInterval > 0) {
|
|
const lastDate = new Date(lastMaintenanceDate);
|
|
const nextDate = new Date(lastDate.getTime() + (maintenanceInterval * 24 * 60 * 60 * 1000));
|
|
const currentDate = new Date();
|
|
const daysUntil = Math.ceil((nextDate - currentDate) / (1000 * 60 * 60 * 24));
|
|
|
|
$('#nextMaintenanceDate').text(nextDate.toLocaleDateString());
|
|
$('#daysUntilMaintenance').text(daysUntil + ' days');
|
|
|
|
if (daysUntil < 0) {
|
|
$('#daysUntilMaintenance').addClass('text-danger').text(Math.abs(daysUntil) + ' days overdue');
|
|
} else if (daysUntil < 30) {
|
|
$('#daysUntilMaintenance').addClass('text-warning');
|
|
} else {
|
|
$('#daysUntilMaintenance').addClass('text-success');
|
|
}
|
|
} else {
|
|
$('#nextMaintenanceDate').text('Not calculated');
|
|
$('#daysUntilMaintenance').text('-');
|
|
}
|
|
}
|
|
|
|
function previewEquipment() {
|
|
// Collect form data for preview
|
|
const formData = new FormData($('#equipmentForm')[0]);
|
|
|
|
// Open preview in new window/modal
|
|
alert('Preview functionality would show equipment details preview');
|
|
}
|
|
|
|
// Form validation
|
|
$('#equipmentForm').on('submit', function(e) {
|
|
let isValid = true;
|
|
|
|
// Check required fields
|
|
$(this).find('input[required], select[required]').each(function() {
|
|
if (!$(this).val()) {
|
|
isValid = false;
|
|
$(this).addClass('is-invalid');
|
|
} else {
|
|
$(this).removeClass('is-invalid');
|
|
}
|
|
});
|
|
|
|
if (!isValid) {
|
|
e.preventDefault();
|
|
alert('Please fill in all required fields.');
|
|
return false;
|
|
}
|
|
|
|
// Collect specifications
|
|
const specNames = $('input[name="spec_name[]"]').map(function() { return $(this).val(); }).get();
|
|
const specValues = $('input[name="spec_value[]"]').map(function() { return $(this).val(); }).get();
|
|
|
|
const specifications = {};
|
|
for (let i = 0; i < specNames.length; i++) {
|
|
if (specNames[i] && specValues[i]) {
|
|
specifications[specNames[i]] = specValues[i];
|
|
}
|
|
}
|
|
|
|
// Add specifications as hidden field
|
|
$('<input>').attr({
|
|
type: 'hidden',
|
|
name: 'specifications',
|
|
value: JSON.stringify(specifications)
|
|
}).appendTo(this);
|
|
});
|
|
</script>
|
|
{% endblock %}
|
|
|