671 lines
30 KiB
HTML
671 lines
30 KiB
HTML
{% extends 'base.html' %}
|
|
{% load static %}
|
|
|
|
{% block title %}Bed Maintenance Management{% endblock %}
|
|
|
|
{% block extra_css %}
|
|
<link href="{% static 'plugins/datatables.net-bs5/css/dataTables.bootstrap5.min.css' %}" rel="stylesheet" />
|
|
<link href="{% static 'plugins/datatables.net-responsive-bs5/css/responsive.bootstrap5.min.css' %}" rel="stylesheet" />
|
|
<style>
|
|
.maintenance-status-scheduled { color: #ffc107; }
|
|
.maintenance-status-in-progress { color: #17a2b8; }
|
|
.maintenance-status-completed { color: #28a745; }
|
|
.maintenance-status-cancelled { color: #6c757d; }
|
|
.maintenance-status-overdue { color: #dc3545; }
|
|
|
|
.priority-low { color: #28a745; }
|
|
.priority-medium { color: #ffc107; }
|
|
.priority-high { color: #fd7e14; }
|
|
.priority-critical { color: #dc3545; }
|
|
|
|
.bed-status-available { background-color: #d4edda; color: #155724; }
|
|
.bed-status-occupied { background-color: #f8d7da; color: #721c24; }
|
|
.bed-status-maintenance { background-color: #fff3cd; color: #856404; }
|
|
.bed-status-out-of-order { background-color: #f5c6cb; color: #721c24; }
|
|
|
|
.maintenance-card {
|
|
transition: all 0.3s ease;
|
|
border-left: 4px solid #dee2e6;
|
|
}
|
|
|
|
.maintenance-card.scheduled { border-left-color: #ffc107; }
|
|
.maintenance-card.in-progress { border-left-color: #17a2b8; }
|
|
.maintenance-card.completed { border-left-color: #28a745; }
|
|
.maintenance-card.overdue { border-left-color: #dc3545; }
|
|
|
|
.maintenance-card:hover {
|
|
transform: translateY(-2px);
|
|
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
|
|
}
|
|
|
|
.stats-card {
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
color: white;
|
|
border-radius: 10px;
|
|
}
|
|
|
|
.stats-card.warning {
|
|
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
|
|
}
|
|
|
|
.stats-card.success {
|
|
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
|
|
}
|
|
|
|
.stats-card.info {
|
|
background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.maintenance-card {
|
|
margin-bottom: 15px;
|
|
}
|
|
|
|
.table-responsive {
|
|
font-size: 0.875rem;
|
|
}
|
|
}
|
|
</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 'inpatients:dashboard' %}">Inpatients</a></li>
|
|
<li class="breadcrumb-item active">Bed Maintenance</li>
|
|
</ol>
|
|
<h1 class="page-header mb-0">
|
|
<i class="fas fa-tools me-2"></i>Bed Maintenance Management
|
|
</h1>
|
|
</div>
|
|
<div class="ms-auto">
|
|
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#scheduleMaintenanceModal">
|
|
<i class="fas fa-plus me-1"></i>Schedule Maintenance
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Statistics Cards -->
|
|
<div class="row mb-4">
|
|
<div class="col-xl-3 col-md-6">
|
|
<div class="card stats-card">
|
|
<div class="card-body">
|
|
<div class="d-flex align-items-center">
|
|
<div class="flex-grow-1">
|
|
<div class="text-white-75 mb-1">Total Beds</div>
|
|
<div class="h3 mb-0 text-white">{{ stats.total_beds|default:0 }}</div>
|
|
</div>
|
|
<div class="ms-3">
|
|
<i class="fas fa-bed fa-2x text-white-50"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-xl-3 col-md-6">
|
|
<div class="card stats-card warning">
|
|
<div class="card-body">
|
|
<div class="d-flex align-items-center">
|
|
<div class="flex-grow-1">
|
|
<div class="text-white-75 mb-1">Under Maintenance</div>
|
|
<div class="h3 mb-0 text-white">{{ stats.under_maintenance|default:0 }}</div>
|
|
</div>
|
|
<div class="ms-3">
|
|
<i class="fas fa-wrench fa-2x text-white-50"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-xl-3 col-md-6">
|
|
<div class="card stats-card success">
|
|
<div class="card-body">
|
|
<div class="d-flex align-items-center">
|
|
<div class="flex-grow-1">
|
|
<div class="text-white-75 mb-1">Scheduled Today</div>
|
|
<div class="h3 mb-0 text-white">{{ stats.scheduled_today|default:0 }}</div>
|
|
</div>
|
|
<div class="ms-3">
|
|
<i class="fas fa-calendar-check fa-2x text-white-50"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-xl-3 col-md-6">
|
|
<div class="card stats-card info">
|
|
<div class="card-body">
|
|
<div class="d-flex align-items-center">
|
|
<div class="flex-grow-1">
|
|
<div class="text-white-75 mb-1">Overdue</div>
|
|
<div class="h3 mb-0 text-white">{{ stats.overdue|default:0 }}</div>
|
|
</div>
|
|
<div class="ms-3">
|
|
<i class="fas fa-exclamation-triangle fa-2x text-white-50"></i>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Filters and Search -->
|
|
<div class="card mb-4">
|
|
<div class="card-body">
|
|
<div class="row g-3">
|
|
<div class="col-md-3">
|
|
<label class="form-label">Ward/Unit</label>
|
|
<select class="form-select" id="ward-filter">
|
|
<option value="">All Wards</option>
|
|
{% for ward in wards %}
|
|
<option value="{{ ward.id }}">{{ ward.name }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<label class="form-label">Maintenance Status</label>
|
|
<select class="form-select" id="status-filter">
|
|
<option value="">All Statuses</option>
|
|
<option value="scheduled">Scheduled</option>
|
|
<option value="in_progress">In Progress</option>
|
|
<option value="completed">Completed</option>
|
|
<option value="cancelled">Cancelled</option>
|
|
<option value="overdue">Overdue</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<label class="form-label">Priority</label>
|
|
<select class="form-select" id="priority-filter">
|
|
<option value="">All Priorities</option>
|
|
<option value="low">Low</option>
|
|
<option value="medium">Medium</option>
|
|
<option value="high">High</option>
|
|
<option value="critical">Critical</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-3">
|
|
<label class="form-label">Date Range</label>
|
|
<select class="form-select" id="date-filter">
|
|
<option value="">All Dates</option>
|
|
<option value="today">Today</option>
|
|
<option value="week">This Week</option>
|
|
<option value="month">This Month</option>
|
|
<option value="overdue">Overdue</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="row mt-3">
|
|
<div class="col-md-6">
|
|
<div class="input-group">
|
|
<span class="input-group-text"><i class="fas fa-search"></i></span>
|
|
<input type="text" class="form-control" id="search-input" placeholder="Search beds, rooms, or maintenance notes...">
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6 text-end">
|
|
<button type="button" class="btn btn-outline-secondary me-2" onclick="clearFilters()">
|
|
<i class="fas fa-times me-1"></i>Clear Filters
|
|
</button>
|
|
<button type="button" class="btn btn-success" onclick="exportMaintenanceReport()">
|
|
<i class="fas fa-file-excel me-1"></i>Export Report
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Maintenance Schedule Table -->
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="card-title mb-0">
|
|
<i class="fas fa-list me-2"></i>Maintenance Schedule
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="table-responsive">
|
|
<table id="maintenanceTable" class="table table-striped table-hover">
|
|
<thead>
|
|
<tr>
|
|
<th>Bed</th>
|
|
<th>Ward/Room</th>
|
|
<th>Maintenance Type</th>
|
|
<th>Priority</th>
|
|
<th>Scheduled Date</th>
|
|
<th>Status</th>
|
|
<th>Assigned To</th>
|
|
<th>Progress</th>
|
|
<th>Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for maintenance in maintenance_schedules %}
|
|
<tr>
|
|
<td>
|
|
<div class="d-flex align-items-center">
|
|
<i class="fas fa-bed me-2 text-muted"></i>
|
|
<div>
|
|
<div class="fw-bold">{{ maintenance.bed.bed_number }}</div>
|
|
<small class="text-muted">{{ maintenance.bed.bed_type }}</small>
|
|
</div>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<div>
|
|
<div class="fw-bold">{{ maintenance.bed.ward.name }}</div>
|
|
<small class="text-muted">Room {{ maintenance.bed.room_number }}</small>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<span class="badge bg-info">{{ maintenance.get_maintenance_type_display }}</span>
|
|
</td>
|
|
<td>
|
|
<span class="badge priority-{{ maintenance.priority }}">
|
|
{{ maintenance.get_priority_display }}
|
|
</span>
|
|
</td>
|
|
<td>
|
|
<div>
|
|
<div>{{ maintenance.scheduled_date|date:"M d, Y" }}</div>
|
|
<small class="text-muted">{{ maintenance.scheduled_time|time:"H:i" }}</small>
|
|
</div>
|
|
</td>
|
|
<td>
|
|
<span class="badge maintenance-status-{{ maintenance.status }}">
|
|
{{ maintenance.get_status_display }}
|
|
</span>
|
|
</td>
|
|
<td>
|
|
{% if maintenance.assigned_to %}
|
|
<div>
|
|
<div class="fw-bold">{{ maintenance.assigned_to.get_full_name }}</div>
|
|
<small class="text-muted">{{ maintenance.assigned_to.department }}</small>
|
|
</div>
|
|
{% else %}
|
|
<span class="text-muted">Not assigned</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
<div class="progress" style="height: 6px;">
|
|
<div class="progress-bar" role="progressbar"
|
|
style="width: {{ maintenance.progress_percentage }}%"
|
|
aria-valuenow="{{ maintenance.progress_percentage }}"
|
|
aria-valuemin="0" aria-valuemax="100"></div>
|
|
</div>
|
|
<small class="text-muted">{{ maintenance.progress_percentage }}%</small>
|
|
</td>
|
|
<td>
|
|
<div class="btn-group" role="group">
|
|
<button type="button" class="btn btn-sm btn-outline-primary"
|
|
onclick="viewMaintenance('{{ maintenance.id }}')">
|
|
<i class="fas fa-eye"></i>
|
|
</button>
|
|
{% if maintenance.status == 'scheduled' %}
|
|
<button type="button" class="btn btn-sm btn-outline-success"
|
|
onclick="startMaintenance('{{ maintenance.id }}')">
|
|
<i class="fas fa-play"></i>
|
|
</button>
|
|
{% endif %}
|
|
{% if maintenance.status == 'in_progress' %}
|
|
<button type="button" class="btn btn-sm btn-outline-warning"
|
|
onclick="updateProgress('{{ maintenance.id }}')">
|
|
<i class="fas fa-edit"></i>
|
|
</button>
|
|
{% endif %}
|
|
<button type="button" class="btn btn-sm btn-outline-secondary"
|
|
onclick="editMaintenance('{{ maintenance.id }}')">
|
|
<i class="fas fa-edit"></i>
|
|
</button>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
{% empty %}
|
|
<tr>
|
|
<td colspan="9" class="text-center py-4">
|
|
<div class="text-muted">
|
|
<i class="fas fa-tools fa-3x mb-3"></i>
|
|
<p>No maintenance schedules found.</p>
|
|
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#scheduleMaintenanceModal">
|
|
<i class="fas fa-plus me-1"></i>Schedule First Maintenance
|
|
</button>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Schedule Maintenance Modal -->
|
|
<div class="modal fade" id="scheduleMaintenanceModal" tabindex="-1" aria-labelledby="scheduleMaintenanceModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-lg">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="scheduleMaintenanceModalLabel">
|
|
<i class="fas fa-calendar-plus me-2"></i>Schedule Bed Maintenance
|
|
</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<form id="scheduleMaintenanceForm" method="post">
|
|
{% csrf_token %}
|
|
<div class="modal-body">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-group mb-3">
|
|
<label class="form-label">Ward <span class="text-danger">*</span></label>
|
|
<select class="form-select" name="ward" id="ward-select" required>
|
|
<option value="">Select ward...</option>
|
|
{% for ward in wards %}
|
|
<option value="{{ ward.id }}">{{ ward.name }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-group mb-3">
|
|
<label class="form-label">Bed <span class="text-danger">*</span></label>
|
|
<select class="form-select" name="bed" id="bed-select" required>
|
|
<option value="">Select bed...</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-group mb-3">
|
|
<label class="form-label">Maintenance Type <span class="text-danger">*</span></label>
|
|
<select class="form-select" name="maintenance_type" required>
|
|
<option value="">Select type...</option>
|
|
<option value="routine">Routine Inspection</option>
|
|
<option value="cleaning">Deep Cleaning</option>
|
|
<option value="repair">Repair</option>
|
|
<option value="replacement">Part Replacement</option>
|
|
<option value="calibration">Equipment Calibration</option>
|
|
<option value="safety_check">Safety Check</option>
|
|
<option value="preventive">Preventive Maintenance</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-group mb-3">
|
|
<label class="form-label">Priority <span class="text-danger">*</span></label>
|
|
<select class="form-select" name="priority" required>
|
|
<option value="low">Low</option>
|
|
<option value="medium" selected>Medium</option>
|
|
<option value="high">High</option>
|
|
<option value="critical">Critical</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-group mb-3">
|
|
<label class="form-label">Scheduled Date <span class="text-danger">*</span></label>
|
|
<input type="date" class="form-control" name="scheduled_date" required>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-group mb-3">
|
|
<label class="form-label">Scheduled Time <span class="text-danger">*</span></label>
|
|
<input type="time" class="form-control" name="scheduled_time" required>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-group mb-3">
|
|
<label class="form-label">Assign To</label>
|
|
<select class="form-select" name="assigned_to">
|
|
<option value="">Select technician...</option>
|
|
{% for technician in maintenance_staff %}
|
|
<option value="{{ technician.id }}">{{ technician.get_full_name }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-group mb-3">
|
|
<label class="form-label">Estimated Duration (hours)</label>
|
|
<input type="number" class="form-control" name="estimated_duration"
|
|
min="0.5" step="0.5" placeholder="2.0">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group mb-3">
|
|
<label class="form-label">Description/Notes</label>
|
|
<textarea class="form-control" name="description" rows="3"
|
|
placeholder="Describe the maintenance work to be performed..."></textarea>
|
|
</div>
|
|
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" name="notify_staff" id="notify-staff" checked>
|
|
<label class="form-check-label" for="notify-staff">
|
|
Notify assigned staff member
|
|
</label>
|
|
</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">
|
|
<i class="fas fa-save me-1"></i>Schedule Maintenance
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- View Maintenance Modal -->
|
|
<div class="modal fade" id="viewMaintenanceModal" tabindex="-1" aria-labelledby="viewMaintenanceModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-lg">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="viewMaintenanceModalLabel">
|
|
<i class="fas fa-eye me-2"></i>Maintenance Details
|
|
</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body" id="maintenance-details">
|
|
<!-- Content loaded via AJAX -->
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
|
|
<i class="fas fa-times me-1"></i>Close
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block extra_js %}
|
|
<script src="{% static 'plugins/datatables.net/js/dataTables.min.js' %}"></script>
|
|
<script src="{% static 'plugins/datatables.net-bs5/js/dataTables.bootstrap5.min.js' %}"></script>
|
|
<script src="{% static 'plugins/datatables.net-responsive/js/dataTables.responsive.min.js' %}"></script>
|
|
<script src="{% static 'plugins/datatables.net-responsive-bs5/js/responsive.bootstrap5.min.js' %}"></script>
|
|
|
|
<script>
|
|
$(document).ready(function() {
|
|
// Initialize DataTable
|
|
const table = $('#maintenanceTable').DataTable({
|
|
responsive: true,
|
|
pageLength: 25,
|
|
order: [[4, 'asc']], // Sort by scheduled date
|
|
columnDefs: [
|
|
{ orderable: false, targets: [8] } // Actions column
|
|
]
|
|
});
|
|
|
|
// Filter functionality
|
|
$('#ward-filter, #status-filter, #priority-filter, #date-filter').on('change', function() {
|
|
applyFilters();
|
|
});
|
|
|
|
$('#search-input').on('keyup', function() {
|
|
table.search(this.value).draw();
|
|
});
|
|
|
|
// Ward selection for bed loading
|
|
$('#ward-select').on('change', function() {
|
|
const wardId = $(this).val();
|
|
const bedSelect = $('#bed-select');
|
|
|
|
bedSelect.empty().append('<option value="">Loading beds...</option>');
|
|
|
|
if (wardId) {
|
|
$.ajax({
|
|
url: '{% url "inpatients:get_ward_beds" %}',
|
|
data: { ward_id: wardId },
|
|
success: function(data) {
|
|
bedSelect.empty().append('<option value="">Select bed...</option>');
|
|
data.beds.forEach(function(bed) {
|
|
bedSelect.append(`<option value="${bed.id}">${bed.bed_number} - ${bed.bed_type}</option>`);
|
|
});
|
|
},
|
|
error: function() {
|
|
bedSelect.empty().append('<option value="">Error loading beds</option>');
|
|
}
|
|
});
|
|
} else {
|
|
bedSelect.empty().append('<option value="">Select bed...</option>');
|
|
}
|
|
});
|
|
|
|
// Form submission
|
|
$('#scheduleMaintenanceForm').on('submit', function(e) {
|
|
e.preventDefault();
|
|
|
|
const formData = new FormData(this);
|
|
|
|
$.ajax({
|
|
url: '{% url "inpatients:schedule_maintenance" %}',
|
|
method: 'POST',
|
|
data: formData,
|
|
processData: false,
|
|
contentType: false,
|
|
success: function(response) {
|
|
if (response.success) {
|
|
$('#scheduleMaintenanceModal').modal('hide');
|
|
location.reload(); // Refresh page to show new maintenance
|
|
} else {
|
|
alert('Error scheduling maintenance: ' + response.message);
|
|
}
|
|
},
|
|
error: function() {
|
|
alert('Error scheduling maintenance. Please try again.');
|
|
}
|
|
});
|
|
});
|
|
});
|
|
|
|
function applyFilters() {
|
|
const ward = $('#ward-filter').val();
|
|
const status = $('#status-filter').val();
|
|
const priority = $('#priority-filter').val();
|
|
const dateRange = $('#date-filter').val();
|
|
|
|
// Apply filters to DataTable
|
|
const table = $('#maintenanceTable').DataTable();
|
|
|
|
// Custom filtering logic would go here
|
|
// For now, we'll just trigger a page refresh with query parameters
|
|
const params = new URLSearchParams();
|
|
if (ward) params.append('ward', ward);
|
|
if (status) params.append('status', status);
|
|
if (priority) params.append('priority', priority);
|
|
if (dateRange) params.append('date_range', dateRange);
|
|
|
|
const url = window.location.pathname + (params.toString() ? '?' + params.toString() : '');
|
|
window.location.href = url;
|
|
}
|
|
|
|
function clearFilters() {
|
|
$('#ward-filter, #status-filter, #priority-filter, #date-filter').val('');
|
|
$('#search-input').val('');
|
|
window.location.href = window.location.pathname;
|
|
}
|
|
|
|
function viewMaintenance(maintenanceId) {
|
|
$.ajax({
|
|
url: '{% url "inpatients:maintenance_detail" pk="0" %}'.replace('0', maintenanceId),
|
|
success: function(data) {
|
|
$('#maintenance-details').html(data);
|
|
$('#viewMaintenanceModal').modal('show');
|
|
},
|
|
error: function() {
|
|
alert('Error loading maintenance details.');
|
|
}
|
|
});
|
|
}
|
|
|
|
function startMaintenance(maintenanceId) {
|
|
if (confirm('Start this maintenance task?')) {
|
|
$.ajax({
|
|
url: '{% url "inpatients:start_maintenance" pk="0" %}'.replace('0', maintenanceId),
|
|
method: 'POST',
|
|
data: {
|
|
'csrfmiddlewaretoken': '{{ csrf_token }}'
|
|
},
|
|
success: function(response) {
|
|
if (response.success) {
|
|
location.reload();
|
|
} else {
|
|
alert('Error starting maintenance: ' + response.message);
|
|
}
|
|
},
|
|
error: function() {
|
|
alert('Error starting maintenance.');
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
function updateProgress(maintenanceId) {
|
|
const progress = prompt('Enter progress percentage (0-100):');
|
|
if (progress !== null && progress >= 0 && progress <= 100) {
|
|
$.ajax({
|
|
url: '{% url "inpatients:update_maintenance_progress" pk="0" %}'.replace('0', maintenanceId),
|
|
method: 'POST',
|
|
data: {
|
|
'progress': progress,
|
|
'csrfmiddlewaretoken': '{{ csrf_token }}'
|
|
},
|
|
success: function(response) {
|
|
if (response.success) {
|
|
location.reload();
|
|
} else {
|
|
alert('Error updating progress: ' + response.message);
|
|
}
|
|
},
|
|
error: function() {
|
|
alert('Error updating progress.');
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
function editMaintenance(maintenanceId) {
|
|
window.location.href = '{% url "inpatients:edit_maintenance" pk="0" %}'.replace('0', maintenanceId);
|
|
}
|
|
|
|
function exportMaintenanceReport() {
|
|
const params = new URLSearchParams(window.location.search);
|
|
params.append('export', 'excel');
|
|
window.location.href = '{% url "inpatients:maintenance_report" %}?' + params.toString();
|
|
}
|
|
</script>
|
|
{% endblock %}
|
|
|