543 lines
23 KiB
HTML
543 lines
23 KiB
HTML
{% extends 'base.html' %}
|
|
{% load static %}
|
|
|
|
{% block title %}Delete QC Record - {{ qc_record.test_name }}{% endblock %}
|
|
|
|
{% block css %}
|
|
<style>
|
|
.delete-warning {
|
|
background: #f8d7da;
|
|
border: 2px solid #dc3545;
|
|
border-radius: 8px;
|
|
padding: 20px;
|
|
margin-bottom: 20px;
|
|
animation: pulse 2s infinite;
|
|
}
|
|
|
|
@keyframes pulse {
|
|
0% { opacity: 1; }
|
|
50% { opacity: 0.8; }
|
|
100% { opacity: 1; }
|
|
}
|
|
|
|
.qc-info {
|
|
background: #d1ecf1;
|
|
border-left: 4px solid #17a2b8;
|
|
border-radius: 8px;
|
|
padding: 20px;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.impact-assessment {
|
|
background: #fff3cd;
|
|
border-left: 4px solid #ffc107;
|
|
border-radius: 8px;
|
|
padding: 20px;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.compliance-warning {
|
|
background: #f8d7da;
|
|
border: 2px solid #dc3545;
|
|
border-radius: 8px;
|
|
padding: 20px;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.deletion-options {
|
|
background: #d4edda;
|
|
border-left: 4px solid #28a745;
|
|
border-radius: 8px;
|
|
padding: 20px;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.required-field {
|
|
color: #dc3545;
|
|
}
|
|
|
|
.regulatory-alert {
|
|
background: #dc3545;
|
|
color: white;
|
|
padding: 15px;
|
|
border-radius: 8px;
|
|
margin-bottom: 20px;
|
|
text-align: center;
|
|
font-weight: bold;
|
|
}
|
|
</style>
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<!-- BEGIN breadcrumb -->
|
|
<ol class="breadcrumb float-xl-end">
|
|
<li class="breadcrumb-item"><a href="{% url 'core:dashboard' %}">Home</a></li>
|
|
<li class="breadcrumb-item"><a href="{% url 'blood_bank:dashboard' %}">Blood Bank</a></li>
|
|
<li class="breadcrumb-item"><a href="{% url 'blood_bank:quality_control_list' %}">Quality Control</a></li>
|
|
<li class="breadcrumb-item"><a href="{% url 'blood_bank:quality_control_detail' qc_record.id %}">{{ qc_record.test_name }}</a></li>
|
|
<li class="breadcrumb-item active">Delete Record</li>
|
|
</ol>
|
|
<!-- END breadcrumb -->
|
|
|
|
<!-- BEGIN page-header -->
|
|
<h1 class="page-header">
|
|
Delete QC Record
|
|
<small>{{ qc_record.test_name }}</small>
|
|
{% if qc_record.result == 'failed' %}
|
|
<span class="badge bg-danger ms-2">FAILED TEST</span>
|
|
{% endif %}
|
|
</h1>
|
|
<!-- END page-header -->
|
|
|
|
<!-- BEGIN regulatory alert -->
|
|
<div class="regulatory-alert">
|
|
<i class="fa fa-exclamation-triangle fa-2x"></i><br>
|
|
WARNING: Deleting QC records may violate regulatory compliance requirements.<br>
|
|
Consider archiving instead of permanent deletion.
|
|
</div>
|
|
<!-- END regulatory alert -->
|
|
|
|
<!-- BEGIN panel -->
|
|
<div class="panel panel-inverse">
|
|
<div class="panel-heading">
|
|
<h4 class="panel-title">
|
|
<i class="fa fa-trash"></i> Delete Quality Control Record
|
|
</h4>
|
|
<div class="panel-heading-btn">
|
|
<span class="badge bg-danger">CRITICAL ACTION</span>
|
|
</div>
|
|
</div>
|
|
<div class="panel-body">
|
|
<!-- BEGIN delete warning -->
|
|
<div class="delete-warning">
|
|
<h5><i class="fa fa-exclamation-triangle"></i> CRITICAL ACTION REQUIRED</h5>
|
|
<p class="mb-2"><strong>You are about to permanently delete a quality control record.</strong></p>
|
|
<p class="mb-0">This action will:</p>
|
|
<ul class="mb-0">
|
|
<li>Permanently remove the QC test record from the system</li>
|
|
<li>Delete all associated test results and data</li>
|
|
<li>Remove compliance documentation</li>
|
|
<li>Impact regulatory audit trails</li>
|
|
<li>Potentially violate FDA, AABB, and CAP requirements</li>
|
|
{% if qc_record.result == 'failed' %}
|
|
<li><strong>Delete critical failure documentation</strong></li>
|
|
{% endif %}
|
|
{% if qc_record.capa_initiated %}
|
|
<li><strong>Affect active CAPA investigations</strong></li>
|
|
{% endif %}
|
|
</ul>
|
|
</div>
|
|
<!-- END delete warning -->
|
|
|
|
<!-- BEGIN QC record information -->
|
|
<div class="qc-info">
|
|
<h5><i class="fa fa-clipboard-check"></i> QC Record Information</h5>
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<table class="table table-borderless mb-0">
|
|
<tr>
|
|
<td class="fw-bold">Test Name:</td>
|
|
<td>{{ qc_record.test_name }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="fw-bold">Test Type:</td>
|
|
<td>{{ qc_record.get_test_type_display }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="fw-bold">Test Date:</td>
|
|
<td>{{ qc_record.test_date|date:"M d, Y H:i" }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="fw-bold">Tested By:</td>
|
|
<td>{{ qc_record.tested_by.get_full_name }}</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<table class="table table-borderless mb-0">
|
|
<tr>
|
|
<td class="fw-bold">Result:</td>
|
|
<td>
|
|
<span class="badge bg-{% if qc_record.result == 'passed' %}success{% elif qc_record.result == 'failed' %}danger{% else %}warning{% endif %}">
|
|
{{ qc_record.get_result_display }}
|
|
</span>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="fw-bold">Sample ID:</td>
|
|
<td>{{ qc_record.sample_id|default:"Not specified" }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="fw-bold">Equipment:</td>
|
|
<td>{{ qc_record.equipment_used|default:"Not specified" }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="fw-bold">Reviewed:</td>
|
|
<td>
|
|
{% if qc_record.reviewed_by %}
|
|
<span class="text-success">Yes - {{ qc_record.reviewed_by.get_full_name }}</span>
|
|
{% else %}
|
|
<span class="text-warning">Pending Review</span>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
{% if qc_record.test_notes %}
|
|
<div class="mt-3">
|
|
<h6>Test Notes:</h6>
|
|
<div class="alert alert-info">{{ qc_record.test_notes }}</div>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
<!-- END QC record information -->
|
|
|
|
<!-- BEGIN compliance warning -->
|
|
<div class="compliance-warning">
|
|
<h5><i class="fa fa-shield-alt"></i> Regulatory Compliance Impact</h5>
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<h6>Affected Standards</h6>
|
|
<ul>
|
|
<li><strong>FDA 21 CFR Part 606:</strong> QC record retention requirements</li>
|
|
<li><strong>AABB Standards:</strong> Quality documentation requirements</li>
|
|
<li><strong>ISO 15189:</strong> Quality management system records</li>
|
|
<li><strong>CAP Requirements:</strong> Laboratory quality assurance</li>
|
|
</ul>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<h6>Compliance Risks</h6>
|
|
<ul>
|
|
<li>Loss of audit trail integrity</li>
|
|
<li>Regulatory inspection findings</li>
|
|
<li>Accreditation issues</li>
|
|
<li>Legal liability concerns</li>
|
|
{% if qc_record.result == 'failed' %}
|
|
<li><strong>Loss of failure investigation records</strong></li>
|
|
{% endif %}
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
{% if qc_record.result == 'failed' %}
|
|
<div class="alert alert-danger mt-3">
|
|
<strong><i class="fa fa-exclamation-triangle"></i> CRITICAL:</strong>
|
|
This is a failed QC test. Deleting this record may violate regulatory requirements for failure investigation documentation.
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if qc_record.capa_initiated %}
|
|
<div class="alert alert-warning mt-3">
|
|
<strong><i class="fa fa-exclamation-circle"></i> ACTIVE CAPA:</strong>
|
|
This record is associated with an active CAPA ({{ qc_record.capa_number }}). Deletion may impact the investigation.
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
<!-- END compliance warning -->
|
|
|
|
<!-- BEGIN impact assessment -->
|
|
<div class="impact-assessment">
|
|
<h5><i class="fa fa-exclamation-circle"></i> Impact Assessment</h5>
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<h6>Related Records</h6>
|
|
<ul>
|
|
{% if qc_record.blood_unit %}
|
|
<li><strong>Blood Unit:</strong> {{ qc_record.blood_unit.unit_number }}</li>
|
|
{% endif %}
|
|
{% if qc_record.equipment_used %}
|
|
<li><strong>Equipment:</strong> {{ qc_record.equipment_used }}</li>
|
|
{% endif %}
|
|
<li><strong>Test Results:</strong> All parameter data will be lost</li>
|
|
<li><strong>Trend Data:</strong> Historical trending will be affected</li>
|
|
</ul>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<h6>System Impact</h6>
|
|
<ul>
|
|
<li>QC statistics and reports will be affected</li>
|
|
<li>Trend analysis data will be incomplete</li>
|
|
<li>Audit trail will show deletion event</li>
|
|
<li>Compliance reports may be impacted</li>
|
|
{% if qc_record.result == 'failed' %}
|
|
<li><strong>Failure rate calculations will change</strong></li>
|
|
{% endif %}
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- END impact assessment -->
|
|
|
|
<!-- BEGIN deletion form -->
|
|
<form method="post" id="deletionForm">
|
|
{% csrf_token %}
|
|
|
|
<div class="deletion-options">
|
|
<h5><i class="fa fa-clipboard-list"></i> Deletion Authorization</h5>
|
|
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label for="deletionReason" class="form-label">
|
|
Deletion Reason <span class="required-field">*</span>
|
|
</label>
|
|
<select class="form-select" id="deletionReason" name="deletion_reason" required>
|
|
<option value="">Select reason...</option>
|
|
<option value="data_entry_error">Data entry error</option>
|
|
<option value="duplicate_record">Duplicate record</option>
|
|
<option value="test_invalidated">Test invalidated</option>
|
|
<option value="equipment_malfunction">Equipment malfunction</option>
|
|
<option value="sample_contamination">Sample contamination</option>
|
|
<option value="procedural_error">Procedural error</option>
|
|
<option value="regulatory_approval">Regulatory approval obtained</option>
|
|
<option value="other">Other (specify below)</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label for="authorizedBy" class="form-label">
|
|
Authorized By <span class="required-field">*</span>
|
|
</label>
|
|
<select class="form-select" id="authorizedBy" name="authorized_by" required>
|
|
<option value="">Select authorizing person...</option>
|
|
{% for supervisor in supervisors %}
|
|
<option value="{{ supervisor.id }}">{{ supervisor.get_full_name }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label for="authorizationCode" class="form-label">
|
|
Authorization Code <span class="required-field">*</span>
|
|
</label>
|
|
<input type="text" class="form-control" id="authorizationCode" name="authorization_code"
|
|
placeholder="Enter supervisor authorization code" required>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label for="regulatoryApproval" class="form-label">
|
|
Regulatory Approval
|
|
</label>
|
|
<input type="text" class="form-control" id="regulatoryApproval" name="regulatory_approval"
|
|
placeholder="Reference number (if applicable)">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
<div class="form-group">
|
|
<label for="deletionJustification" class="form-label">
|
|
Detailed Justification <span class="required-field">*</span>
|
|
</label>
|
|
<textarea class="form-control" id="deletionJustification" name="deletion_justification"
|
|
rows="4" required placeholder="Provide detailed justification for deletion, including regulatory compliance considerations..."></textarea>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label for="alternativeAction" class="form-label">Alternative Action Considered</label>
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="archiveConsidered" name="archive_considered">
|
|
<label class="form-check-label" for="archiveConsidered">
|
|
Archive record instead of deletion
|
|
</label>
|
|
</div>
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="correctionConsidered" name="correction_considered">
|
|
<label class="form-check-label" for="correctionConsidered">
|
|
Correct data instead of deletion
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label for="mitigationMeasures" class="form-label">Mitigation Measures</label>
|
|
<textarea class="form-control" id="mitigationMeasures" name="mitigation_measures"
|
|
rows="3" placeholder="Describe measures to prevent similar issues..."></textarea>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- BEGIN confirmation checklist -->
|
|
<div class="alert alert-danger">
|
|
<h6><i class="fa fa-check-square"></i> Critical Confirmation Checklist</h6>
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="confirmRegulatory" required>
|
|
<label class="form-check-label" for="confirmRegulatory">
|
|
I confirm that this deletion complies with all regulatory requirements
|
|
</label>
|
|
</div>
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="confirmAuditTrail" required>
|
|
<label class="form-check-label" for="confirmAuditTrail">
|
|
I understand that this action will be permanently recorded in the audit trail
|
|
</label>
|
|
</div>
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="confirmImpact" required>
|
|
<label class="form-check-label" for="confirmImpact">
|
|
I acknowledge the impact on compliance and quality documentation
|
|
</label>
|
|
</div>
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="confirmAuthorization" required>
|
|
<label class="form-check-label" for="confirmAuthorization">
|
|
I have proper authorization to perform this critical action
|
|
</label>
|
|
</div>
|
|
{% if qc_record.result == 'failed' %}
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="confirmFailureRecord" required>
|
|
<label class="form-check-label" for="confirmFailureRecord">
|
|
I understand that deleting a failed QC record may violate regulatory requirements
|
|
</label>
|
|
</div>
|
|
{% endif %}
|
|
{% if qc_record.capa_initiated %}
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="confirmCapa" required>
|
|
<label class="form-check-label" for="confirmCapa">
|
|
I acknowledge that this record is associated with an active CAPA investigation
|
|
</label>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
<!-- END confirmation checklist -->
|
|
|
|
<!-- BEGIN form actions -->
|
|
<div class="d-flex justify-content-between mt-4">
|
|
<a href="{% url 'blood_bank:quality_control_detail' qc_record.id %}" class="btn btn-secondary">
|
|
<i class="fa fa-arrow-left"></i> Cancel Deletion
|
|
</a>
|
|
<div>
|
|
<button type="button" class="btn btn-warning" onclick="suggestArchive()">
|
|
<i class="fa fa-archive"></i> Archive Instead
|
|
</button>
|
|
<button type="button" class="btn btn-info" onclick="validateDeletion()">
|
|
<i class="fa fa-check"></i> Validate Deletion
|
|
</button>
|
|
<button type="submit" class="btn btn-danger" id="submitBtn" disabled>
|
|
<i class="fa fa-trash"></i> Permanently Delete Record
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<!-- END form actions -->
|
|
</form>
|
|
<!-- END deletion form -->
|
|
</div>
|
|
</div>
|
|
<!-- END panel -->
|
|
{% endblock %}
|
|
|
|
{% block js %}
|
|
<script>
|
|
$(document).ready(function() {
|
|
// Form validation
|
|
$('.form-check-input, #deletionReason, #authorizedBy, #authorizationCode, #deletionJustification').on('change input', function() {
|
|
validateDeletion();
|
|
});
|
|
|
|
$('#deletionForm').on('submit', function(e) {
|
|
if (!validateDeletion()) {
|
|
e.preventDefault();
|
|
} else {
|
|
// Final confirmation
|
|
if (!confirm('Are you absolutely certain you want to permanently delete this QC record? This action cannot be undone and may violate regulatory requirements.')) {
|
|
e.preventDefault();
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
function validateDeletion() {
|
|
var errors = [];
|
|
|
|
// Check required fields
|
|
if (!$('#deletionReason').val()) {
|
|
errors.push('Please select a deletion reason');
|
|
}
|
|
|
|
if (!$('#authorizedBy').val()) {
|
|
errors.push('Please select the authorizing person');
|
|
}
|
|
|
|
if (!$('#authorizationCode').val().trim()) {
|
|
errors.push('Please enter the authorization code');
|
|
}
|
|
|
|
if (!$('#deletionJustification').val().trim()) {
|
|
errors.push('Please provide detailed justification');
|
|
}
|
|
|
|
// Check confirmation checkboxes
|
|
var requiredCheckboxes = ['confirmRegulatory', 'confirmAuditTrail', 'confirmImpact', 'confirmAuthorization'];
|
|
{% if qc_record.result == 'failed' %}
|
|
requiredCheckboxes.push('confirmFailureRecord');
|
|
{% endif %}
|
|
{% if qc_record.capa_initiated %}
|
|
requiredCheckboxes.push('confirmCapa');
|
|
{% endif %}
|
|
|
|
var uncheckedBoxes = requiredCheckboxes.filter(function(id) {
|
|
return !document.getElementById(id).checked;
|
|
});
|
|
|
|
if (uncheckedBoxes.length > 0) {
|
|
errors.push('Please confirm all checklist items');
|
|
}
|
|
|
|
// Enable/disable submit button
|
|
$('#submitBtn').prop('disabled', errors.length > 0);
|
|
|
|
if (errors.length > 0 && errors.length < 6) {
|
|
// Only show errors if there are just a few (user is actively trying to submit)
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
function suggestArchive() {
|
|
Swal.fire({
|
|
title: 'Consider Archiving',
|
|
html: `
|
|
<div class="text-start">
|
|
<p><strong>Archiving is often a better alternative to deletion:</strong></p>
|
|
<ul>
|
|
<li>Maintains regulatory compliance</li>
|
|
<li>Preserves audit trail integrity</li>
|
|
<li>Allows future reference if needed</li>
|
|
<li>Meets retention requirements</li>
|
|
</ul>
|
|
<p>Would you like to archive this record instead?</p>
|
|
</div>
|
|
`,
|
|
icon: 'info',
|
|
showCancelButton: true,
|
|
confirmButtonText: 'Yes, Archive Instead',
|
|
cancelButtonText: 'Continue with Deletion'
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
// In real implementation, this would redirect to archive function
|
|
window.location.href = '{% url "blood_bank:quality_control_detail" qc_record.id %}';
|
|
}
|
|
});
|
|
}
|
|
</script>
|
|
{% endblock %}
|
|
|