637 lines
29 KiB
HTML
637 lines
29 KiB
HTML
{% extends "base.html" %}
|
|
{% load static %}
|
|
|
|
{% block title %}{{ audit.title }} - Quality Audits{% endblock %}
|
|
|
|
{% block content %}
|
|
<!-- BEGIN breadcrumb -->
|
|
<ol class="breadcrumb float-xl-end">
|
|
<li class="breadcrumb-item"><a href="{% url 'core:dashboard' %}">Dashboard</a></li>
|
|
<li class="breadcrumb-item"><a href="{% url 'quality:dashboard' %}">Quality</a></li>
|
|
<li class="breadcrumb-item"><a href="{% url 'quality:audit_list' %}">Audits</a></li>
|
|
<li class="breadcrumb-item active">{{ audit.title|truncatechars:30 }}</li>
|
|
</ol>
|
|
<!-- END breadcrumb -->
|
|
|
|
<!-- BEGIN page-header -->
|
|
<h1 class="page-header">
|
|
{{ audit.title }}
|
|
<small>Quality audit details and findings</small>
|
|
</h1>
|
|
<!-- END page-header -->
|
|
|
|
<!-- BEGIN row -->
|
|
<div class="row">
|
|
<div class="col-xl-8">
|
|
<!-- Audit Information -->
|
|
<div class="panel panel-inverse">
|
|
<div class="panel-heading">
|
|
<h4 class="panel-title">Audit Information</h4>
|
|
<div class="panel-heading-btn">
|
|
{% if audit.status == 'planned' %}
|
|
<button type="button" class="btn btn-success btn-sm me-2" onclick="startAudit()">
|
|
<i class="fa fa-play me-1"></i>Start Audit
|
|
</button>
|
|
{% elif audit.status == 'in_progress' %}
|
|
<button type="button" class="btn btn-warning btn-sm me-2" onclick="completeAudit()">
|
|
<i class="fa fa-check me-1"></i>Complete Audit
|
|
</button>
|
|
{% endif %}
|
|
<a href="{% url 'quality:audit_edit' audit.pk %}" class="btn btn-primary btn-sm me-2">
|
|
<i class="fa fa-edit me-1"></i>Edit
|
|
</a>
|
|
<button type="button" class="btn btn-secondary btn-sm" onclick="printAudit()">
|
|
<i class="fa fa-print me-1"></i>Print
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="panel-body">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<table class="table table-borderless">
|
|
<tr>
|
|
<td width="120"><strong>Audit ID:</strong></td>
|
|
<td>{{ audit.audit_number|default:audit.id }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>Type:</strong></td>
|
|
<td>
|
|
{% if audit.audit_type == 'internal' %}
|
|
<span class="badge bg-primary">Internal</span>
|
|
{% elif audit.audit_type == 'external' %}
|
|
<span class="badge bg-info">External</span>
|
|
{% elif audit.audit_type == 'regulatory' %}
|
|
<span class="badge bg-warning text-dark">Regulatory</span>
|
|
{% elif audit.audit_type == 'accreditation' %}
|
|
<span class="badge bg-success">Accreditation</span>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>Status:</strong></td>
|
|
<td>
|
|
{% if audit.status == 'planned' %}
|
|
<span class="badge bg-secondary">Planned</span>
|
|
{% elif audit.status == 'in_progress' %}
|
|
<span class="badge bg-info">In Progress</span>
|
|
{% elif audit.status == 'completed' %}
|
|
<span class="badge bg-success">Completed</span>
|
|
{% elif audit.status == 'cancelled' %}
|
|
<span class="badge bg-danger">Cancelled</span>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>Department:</strong></td>
|
|
<td>{{ audit.department.name|default:"All Departments" }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>Lead Auditor:</strong></td>
|
|
<td>
|
|
{% if audit.lead_auditor %}
|
|
{{ audit.lead_auditor.get_full_name }}
|
|
<br><small class="text-muted">{{ audit.lead_auditor.email }}</small>
|
|
{% else %}
|
|
<span class="text-muted">Not assigned</span>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<table class="table table-borderless">
|
|
<tr>
|
|
<td width="120"><strong>Scheduled:</strong></td>
|
|
<td>
|
|
{% if audit.scheduled_date %}
|
|
{{ audit.scheduled_date|date:"F d, Y" }}
|
|
{% if audit.is_overdue %}
|
|
<br><small class="text-danger">Overdue</small>
|
|
{% endif %}
|
|
{% else %}
|
|
<span class="text-muted">Not scheduled</span>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>Started:</strong></td>
|
|
<td>
|
|
{% if audit.start_date %}
|
|
{{ audit.start_date|date:"F d, Y g:i A" }}
|
|
{% else %}
|
|
<span class="text-muted">Not started</span>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>Completed:</strong></td>
|
|
<td>
|
|
{% if audit.completion_date %}
|
|
{{ audit.completion_date|date:"F d, Y g:i A" }}
|
|
{% else %}
|
|
<span class="text-muted">Not completed</span>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>Findings:</strong></td>
|
|
<td>
|
|
{% if audit.findings_count > 0 %}
|
|
<span class="badge bg-orange">{{ audit.findings_count }} finding{{ audit.findings_count|pluralize }}</span>
|
|
{% else %}
|
|
<span class="badge bg-success">No findings</span>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>Created:</strong></td>
|
|
<td>
|
|
{{ audit.created_at|date:"F d, Y g:i A" }}
|
|
<br><small class="text-muted">by {{ audit.created_by.get_full_name|default:audit.created_by.username }}</small>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
{% if audit.description %}
|
|
<div class="mt-3">
|
|
<h6>Description:</h6>
|
|
<p class="text-muted">{{ audit.description }}</p>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if audit.scope %}
|
|
<div class="mt-3">
|
|
<h6>Audit Scope:</h6>
|
|
<p class="text-muted">{{ audit.scope }}</p>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Audit Findings -->
|
|
<div class="panel panel-inverse">
|
|
<div class="panel-heading">
|
|
<h4 class="panel-title">Audit Findings</h4>
|
|
<div class="panel-heading-btn">
|
|
{% if audit.status == 'in_progress' %}
|
|
<button type="button" class="btn btn-primary btn-sm" data-bs-toggle="modal" data-bs-target="#addFindingModal">
|
|
<i class="fa fa-plus me-1"></i>Add Finding
|
|
</button>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="panel-body">
|
|
{% if audit.findings.exists %}
|
|
<div class="table-responsive">
|
|
<table class="table table-striped">
|
|
<thead>
|
|
<tr>
|
|
<th>Finding</th>
|
|
<th>Severity</th>
|
|
<th>Status</th>
|
|
<th>Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for finding in audit.findings.all %}
|
|
<tr>
|
|
<td>
|
|
<strong>{{ finding.title }}</strong>
|
|
<br><small class="text-muted">{{ finding.description|truncatechars:100 }}</small>
|
|
</td>
|
|
<td>
|
|
{% if finding.severity == 'critical' %}
|
|
<span class="badge bg-danger">Critical</span>
|
|
{% elif finding.severity == 'major' %}
|
|
<span class="badge bg-warning text-dark">Major</span>
|
|
{% elif finding.severity == 'minor' %}
|
|
<span class="badge bg-info">Minor</span>
|
|
{% elif finding.severity == 'observation' %}
|
|
<span class="badge bg-secondary">Observation</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
{% if finding.status == 'open' %}
|
|
<span class="badge bg-danger">Open</span>
|
|
{% elif finding.status == 'in_progress' %}
|
|
<span class="badge bg-warning text-dark">In Progress</span>
|
|
{% elif finding.status == 'resolved' %}
|
|
<span class="badge bg-success">Resolved</span>
|
|
{% elif finding.status == 'closed' %}
|
|
<span class="badge bg-secondary">Closed</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
<div class="btn-group">
|
|
<button type="button" class="btn btn-outline-primary btn-sm" onclick="viewFinding('{{ finding.id }}')">
|
|
<i class="fa fa-eye"></i>
|
|
</button>
|
|
{% if audit.status == 'in_progress' %}
|
|
<button type="button" class="btn btn-outline-secondary btn-sm" onclick="editFinding('{{ finding.id }}')">
|
|
<i class="fa fa-edit"></i>
|
|
</button>
|
|
{% endif %}
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{% else %}
|
|
<div class="text-center text-muted py-4">
|
|
<i class="fa fa-search fa-3x mb-3"></i>
|
|
<br>No findings recorded
|
|
{% if audit.status == 'in_progress' %}
|
|
<br><small>Add findings as you conduct the audit</small>
|
|
{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Audit Timeline -->
|
|
<div class="panel panel-inverse">
|
|
<div class="panel-heading">
|
|
<h4 class="panel-title">Audit Timeline</h4>
|
|
</div>
|
|
<div class="panel-body">
|
|
<div class="timeline">
|
|
<div class="timeline-item">
|
|
<div class="timeline-time">{{ audit.created_at|date:"M d, Y g:i A" }}</div>
|
|
<div class="timeline-icon bg-primary"><i class="fa fa-plus"></i></div>
|
|
<div class="timeline-body">
|
|
<div class="timeline-header">Audit Created</div>
|
|
<div class="timeline-content">
|
|
Audit created by {{ audit.created_by.get_full_name|default:audit.created_by.username }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{% if audit.start_date %}
|
|
<div class="timeline-item">
|
|
<div class="timeline-time">{{ audit.start_date|date:"M d, Y g:i A" }}</div>
|
|
<div class="timeline-icon bg-success"><i class="fa fa-play"></i></div>
|
|
<div class="timeline-body">
|
|
<div class="timeline-header">Audit Started</div>
|
|
<div class="timeline-content">
|
|
Audit commenced by {{ audit.lead_auditor.get_full_name|default:"System" }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% for finding in audit.findings.all %}
|
|
<div class="timeline-item">
|
|
<div class="timeline-time">{{ finding.created_at|date:"M d, Y g:i A" }}</div>
|
|
<div class="timeline-icon bg-warning"><i class="fa fa-exclamation-triangle"></i></div>
|
|
<div class="timeline-body">
|
|
<div class="timeline-header">Finding Added: {{ finding.title }}</div>
|
|
<div class="timeline-content">
|
|
{{ finding.description|truncatechars:100 }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
|
|
{% if audit.completion_date %}
|
|
<div class="timeline-item">
|
|
<div class="timeline-time">{{ audit.completion_date|date:"M d, Y g:i A" }}</div>
|
|
<div class="timeline-icon bg-info"><i class="fa fa-check"></i></div>
|
|
<div class="timeline-body">
|
|
<div class="timeline-header">Audit Completed</div>
|
|
<div class="timeline-content">
|
|
Audit completed with {{ audit.findings_count }} finding{{ audit.findings_count|pluralize }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-xl-4">
|
|
<!-- Quick Actions -->
|
|
<div class="panel panel-inverse">
|
|
<div class="panel-heading">
|
|
<h4 class="panel-title">Quick Actions</h4>
|
|
</div>
|
|
<div class="panel-body">
|
|
<div class="d-grid gap-2">
|
|
{% if audit.status == 'planned' %}
|
|
<button type="button" class="btn btn-success" onclick="startAudit()">
|
|
<i class="fa fa-play me-2"></i>Start Audit
|
|
</button>
|
|
{% elif audit.status == 'in_progress' %}
|
|
<button type="button" class="btn btn-warning" onclick="completeAudit()">
|
|
<i class="fa fa-check me-2"></i>Complete Audit
|
|
</button>
|
|
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addFindingModal">
|
|
<i class="fa fa-plus me-2"></i>Add Finding
|
|
</button>
|
|
{% endif %}
|
|
|
|
<a href="{% url 'quality:audit_edit' audit.pk %}" class="btn btn-outline-primary">
|
|
<i class="fa fa-edit me-2"></i>Edit Audit
|
|
</a>
|
|
|
|
{% if audit.status == 'completed' %}
|
|
<button type="button" class="btn btn-outline-success" onclick="generateReport()">
|
|
<i class="fa fa-file-pdf me-2"></i>Generate Report
|
|
</button>
|
|
{% endif %}
|
|
|
|
<button type="button" class="btn btn-outline-secondary" onclick="printAudit()">
|
|
<i class="fa fa-print me-2"></i>Print Audit
|
|
</button>
|
|
|
|
{% if audit.status != 'completed' %}
|
|
<button type="button" class="btn btn-outline-danger" onclick="cancelAudit()">
|
|
<i class="fa fa-times me-2"></i>Cancel Audit
|
|
</button>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Audit Team -->
|
|
<div class="panel panel-inverse">
|
|
<div class="panel-heading">
|
|
<h4 class="panel-title">Audit Team</h4>
|
|
</div>
|
|
<div class="panel-body">
|
|
{% if audit.lead_auditor %}
|
|
<div class="d-flex align-items-center mb-3">
|
|
<div class="flex-fill">
|
|
<div class="fw-bold">{{ audit.lead_auditor.get_full_name }}</div>
|
|
<div class="text-muted small">Lead Auditor</div>
|
|
<div class="text-muted small">{{ audit.lead_auditor.email }}</div>
|
|
</div>
|
|
<div>
|
|
<span class="badge bg-primary">Lead</span>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% for team_member in audit.team_members.all %}
|
|
<div class="d-flex align-items-center mb-3">
|
|
<div class="flex-fill">
|
|
<div class="fw-bold">{{ team_member.get_full_name }}</div>
|
|
<div class="text-muted small">Team Member</div>
|
|
<div class="text-muted small">{{ team_member.email }}</div>
|
|
</div>
|
|
<div>
|
|
<span class="badge bg-secondary">Member</span>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
|
|
{% if not audit.lead_auditor and not audit.team_members.exists %}
|
|
<div class="text-center text-muted">
|
|
<i class="fa fa-users fa-2x mb-2"></i>
|
|
<br>No team members assigned
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Audit Statistics -->
|
|
<div class="panel panel-inverse">
|
|
<div class="panel-heading">
|
|
<h4 class="panel-title">Statistics</h4>
|
|
</div>
|
|
<div class="panel-body">
|
|
<div class="row text-center">
|
|
<div class="col-6">
|
|
<div class="h3 mb-0">{{ audit.findings_count|default:0 }}</div>
|
|
<div class="text-muted small">Total Findings</div>
|
|
</div>
|
|
<div class="col-6">
|
|
<div class="h3 mb-0">{{ audit.critical_findings_count|default:0 }}</div>
|
|
<div class="text-muted small">Critical</div>
|
|
</div>
|
|
</div>
|
|
<hr>
|
|
<div class="row text-center">
|
|
<div class="col-6">
|
|
<div class="h3 mb-0">{{ audit.open_findings_count|default:0 }}</div>
|
|
<div class="text-muted small">Open</div>
|
|
</div>
|
|
<div class="col-6">
|
|
<div class="h3 mb-0">{{ audit.resolved_findings_count|default:0 }}</div>
|
|
<div class="text-muted small">Resolved</div>
|
|
</div>
|
|
</div>
|
|
|
|
{% if audit.duration %}
|
|
<hr>
|
|
<div class="text-center">
|
|
<div class="h3 mb-0">{{ audit.duration }} days</div>
|
|
<div class="text-muted small">Duration</div>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<!-- END row -->
|
|
|
|
<!-- Add Finding Modal -->
|
|
<div class="modal fade" id="addFindingModal" tabindex="-1">
|
|
<div class="modal-dialog modal-lg">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">
|
|
<i class="fa fa-plus me-2"></i>Add Audit Finding
|
|
</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<form id="addFindingForm">
|
|
{% csrf_token %}
|
|
<input type="hidden" id="auditId" value="{{ audit.id }}">
|
|
|
|
<div class="form-floating mb-3">
|
|
<input type="text" class="form-control" id="findingTitle" required>
|
|
<label for="findingTitle">Finding Title *</label>
|
|
</div>
|
|
|
|
<div class="form-floating mb-3">
|
|
<textarea class="form-control" id="findingDescription" style="height: 120px;" required></textarea>
|
|
<label for="findingDescription">Description *</label>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-floating mb-3">
|
|
<select class="form-select" id="findingSeverity" required>
|
|
<option value="">Select Severity</option>
|
|
<option value="critical">Critical</option>
|
|
<option value="major">Major</option>
|
|
<option value="minor">Minor</option>
|
|
<option value="observation">Observation</option>
|
|
</select>
|
|
<label for="findingSeverity">Severity *</label>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-floating mb-3">
|
|
<select class="form-select" id="findingCategory">
|
|
<option value="">Select Category</option>
|
|
<option value="documentation">Documentation</option>
|
|
<option value="process">Process</option>
|
|
<option value="compliance">Compliance</option>
|
|
<option value="safety">Safety</option>
|
|
<option value="quality">Quality</option>
|
|
</select>
|
|
<label for="findingCategory">Category</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-floating mb-3">
|
|
<textarea class="form-control" id="findingRecommendation" style="height: 100px;"></textarea>
|
|
<label for="findingRecommendation">Recommended Action</label>
|
|
</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="addFinding()">
|
|
<i class="fa fa-plus me-2"></i>Add Finding
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block js %}
|
|
<script>
|
|
function startAudit() {
|
|
if (confirm('Start this audit? This will change the status to "In Progress".')) {
|
|
$.ajax({
|
|
url: '{% url "quality:start_audit" %}',
|
|
method: 'POST',
|
|
data: {
|
|
'audit_id': '{{ audit.id }}',
|
|
'csrfmiddlewaretoken': '{{ csrf_token }}'
|
|
},
|
|
success: function(response) {
|
|
if (response.success) {
|
|
toastr.success('Audit started successfully');
|
|
location.reload();
|
|
} else {
|
|
toastr.error(response.message || 'Failed to start audit');
|
|
}
|
|
},
|
|
error: function() {
|
|
toastr.error('Failed to start audit');
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
function completeAudit() {
|
|
if (confirm('Complete this audit? This will finalize the audit and generate the report.')) {
|
|
$.ajax({
|
|
url: '{% url "quality:complete_audit" %}',
|
|
method: 'POST',
|
|
data: {
|
|
'audit_id': '{{ audit.id }}',
|
|
'csrfmiddlewaretoken': '{{ csrf_token }}'
|
|
},
|
|
success: function(response) {
|
|
if (response.success) {
|
|
toastr.success('Audit completed successfully');
|
|
location.reload();
|
|
} else {
|
|
toastr.error(response.message || 'Failed to complete audit');
|
|
}
|
|
},
|
|
error: function() {
|
|
toastr.error('Failed to complete audit');
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
function cancelAudit() {
|
|
if (confirm('Cancel this audit? This action cannot be undone.')) {
|
|
$.ajax({
|
|
url: '{% url "quality:cancel_audit" %}',
|
|
method: 'POST',
|
|
data: {
|
|
'audit_id': '{{ audit.id }}',
|
|
'csrfmiddlewaretoken': '{{ csrf_token }}'
|
|
},
|
|
success: function(response) {
|
|
if (response.success) {
|
|
toastr.success('Audit cancelled successfully');
|
|
location.reload();
|
|
} else {
|
|
toastr.error(response.message || 'Failed to cancel audit');
|
|
}
|
|
},
|
|
error: function() {
|
|
toastr.error('Failed to cancel audit');
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
function addFinding() {
|
|
const formData = {
|
|
'audit_id': $('#auditId').val(),
|
|
'title': $('#findingTitle').val(),
|
|
'description': $('#findingDescription').val(),
|
|
'severity': $('#findingSeverity').val(),
|
|
'category': $('#findingCategory').val(),
|
|
'recommendation': $('#findingRecommendation').val(),
|
|
'csrfmiddlewaretoken': '{{ csrf_token }}'
|
|
};
|
|
|
|
$.ajax({
|
|
url: '{% url "quality:add_audit_finding" %}',
|
|
method: 'POST',
|
|
data: formData,
|
|
success: function(response) {
|
|
if (response.success) {
|
|
toastr.success('Finding added successfully');
|
|
$('#addFindingModal').modal('hide');
|
|
location.reload();
|
|
} else {
|
|
toastr.error(response.message || 'Failed to add finding');
|
|
}
|
|
},
|
|
error: function() {
|
|
toastr.error('Failed to add finding');
|
|
}
|
|
});
|
|
}
|
|
|
|
function viewFinding(findingId) {
|
|
// Open finding detail modal or redirect to finding detail page
|
|
window.open('{% url "quality:audit_finding_detail" 0 %}'.replace('0', findingId), '_blank');
|
|
}
|
|
|
|
function editFinding(findingId) {
|
|
// Open finding edit modal or redirect to finding edit page
|
|
window.location.href = '{% url "quality:audit_finding_edit" 0 %}'.replace('0', findingId);
|
|
}
|
|
|
|
function generateReport() {
|
|
window.open('{% url "quality:audit_report" audit.pk %}', '_blank');
|
|
toastr.info('Generating audit report...');
|
|
}
|
|
|
|
function printAudit() {
|
|
window.print();
|
|
}
|
|
</script>
|
|
{% endblock %}
|
|
|