748 lines
34 KiB
HTML
748 lines
34 KiB
HTML
{% extends "base.html" %}
|
|
{% load static %}
|
|
|
|
{% block title %}{% if object %}Edit{% else %}New{% endif %} Risk Assessment{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="d-flex align-items-center mb-3">
|
|
<div>
|
|
<ol class="breadcrumb">
|
|
<li class="breadcrumb-item"><a href="{% url 'quality:dashboard' %}">Quality</a></li>
|
|
<li class="breadcrumb-item"><a href="{% url 'quality:risk_assessment_list' %}">Risk Assessments</a></li>
|
|
<li class="breadcrumb-item active">{% if object %}Edit{% else %}New{% endif %}</li>
|
|
</ol>
|
|
<h1 class="page-header mb-0">{% if object %}Edit{% else %}New{% endif %} Risk Assessment</h1>
|
|
</div>
|
|
<div class="ms-auto">
|
|
<a href="{% url 'quality:risk_assessment_list' %}" class="btn btn-secondary">
|
|
<i class="fas fa-arrow-left me-2"></i>Back to List
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<form method="post" id="riskAssessmentForm">
|
|
{% csrf_token %}
|
|
|
|
<div class="row">
|
|
<div class="col-xl-8">
|
|
<!-- Basic Information -->
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<h4 class="card-title">
|
|
<i class="fas fa-info-circle me-2"></i>
|
|
Basic Information
|
|
</h4>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row">
|
|
<div class="col-md-8">
|
|
<div class="mb-3">
|
|
<label for="title" class="form-label">
|
|
<strong>Assessment Title *</strong>
|
|
</label>
|
|
<input type="text"
|
|
class="form-control"
|
|
id="title"
|
|
name="title"
|
|
value="{{ object.title|default:"" }}"
|
|
required
|
|
placeholder="Enter a descriptive title for this risk assessment">
|
|
<div class="form-text">
|
|
Provide a clear, descriptive title that identifies the risk being assessed.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="mb-3">
|
|
<label for="assessment_id" class="form-label">
|
|
<strong>Assessment ID</strong>
|
|
</label>
|
|
<input type="text"
|
|
class="form-control"
|
|
id="assessment_id"
|
|
name="assessment_id"
|
|
value="{{ object.assessment_id|default:"" }}"
|
|
placeholder="Auto-generated">
|
|
<div class="form-text">
|
|
Leave blank for auto-generation.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-4">
|
|
<div class="mb-3">
|
|
<label for="risk_category" class="form-label">
|
|
<strong>Risk Category *</strong>
|
|
</label>
|
|
<select class="form-select" id="risk_category" name="risk_category" required>
|
|
<option value="">Select category</option>
|
|
<option value="clinical" {% if object and object.risk_category == 'clinical' %}selected{% endif %}>Clinical</option>
|
|
<option value="operational" {% if object and object.risk_category == 'operational' %}selected{% endif %}>Operational</option>
|
|
<option value="financial" {% if object and object.risk_category == 'financial' %}selected{% endif %}>Financial</option>
|
|
<option value="regulatory" {% if object and object.risk_category == 'regulatory' %}selected{% endif %}>Regulatory</option>
|
|
<option value="technology" {% if object and object.risk_category == 'technology' %}selected{% endif %}>Technology</option>
|
|
<option value="environmental" {% if object and object.risk_category == 'environmental' %}selected{% endif %}>Environmental</option>
|
|
<option value="security" {% if object and object.risk_category == 'security' %}selected{% endif %}>Security</option>
|
|
<option value="reputation" {% if object and object.risk_category == 'reputation' %}selected{% endif %}>Reputation</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="mb-3">
|
|
<label for="department" class="form-label">
|
|
<strong>Department</strong>
|
|
</label>
|
|
<select class="form-select" id="department" name="department">
|
|
<option value="">All Departments</option>
|
|
{% for dept in departments %}
|
|
<option value="{{ dept.pk }}" {% if object and object.department.pk == dept.pk %}selected{% endif %}>
|
|
{{ dept.name }}
|
|
</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<div class="mb-3">
|
|
<label for="priority" class="form-label">
|
|
<strong>Priority *</strong>
|
|
</label>
|
|
<select class="form-select" id="priority" name="priority" required>
|
|
<option value="">Select priority</option>
|
|
<option value="low" {% if object and object.priority == 'low' %}selected{% endif %}>Low</option>
|
|
<option value="medium" {% if object and object.priority == 'medium' %}selected{% endif %}>Medium</option>
|
|
<option value="high" {% if object and object.priority == 'high' %}selected{% endif %}>High</option>
|
|
<option value="critical" {% if object and object.priority == 'critical' %}selected{% endif %}>Critical</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label for="assessment_date" class="form-label">
|
|
<strong>Assessment Date *</strong>
|
|
</label>
|
|
<input type="date"
|
|
class="form-control"
|
|
id="assessment_date"
|
|
name="assessment_date"
|
|
value="{{ object.assessment_date|date:"Y-m-d"|default:"" }}"
|
|
required>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label for="review_date" class="form-label">
|
|
<strong>Next Review Date</strong>
|
|
</label>
|
|
<input type="date"
|
|
class="form-control"
|
|
id="review_date"
|
|
name="review_date"
|
|
value="{{ object.review_date|date:"Y-m-d"|default:"" }}">
|
|
<div class="form-text">
|
|
When should this assessment be reviewed again?
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label for="description" class="form-label">
|
|
<strong>Risk Description *</strong>
|
|
</label>
|
|
<textarea class="form-control"
|
|
id="description"
|
|
name="description"
|
|
rows="4"
|
|
required
|
|
placeholder="Describe the risk in detail, including potential causes and consequences...">{{ object.description|default:"" }}</textarea>
|
|
<div class="form-text">
|
|
Provide a comprehensive description of the risk, including what could go wrong and why.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Risk Factors -->
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<h4 class="card-title mb-0">
|
|
<i class="fas fa-exclamation-triangle me-2"></i>
|
|
Risk Factors
|
|
</h4>
|
|
<button type="button" class="btn btn-sm btn-primary" onclick="addRiskFactor()">
|
|
<i class="fas fa-plus me-1"></i>Add Factor
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="card-body">
|
|
<div id="riskFactors">
|
|
<!-- Risk factors will be dynamically added here -->
|
|
</div>
|
|
<div class="text-center text-muted py-3" id="noFactorsMessage">
|
|
<i class="fas fa-exclamation-triangle fa-2x mb-2"></i>
|
|
<p>No risk factors added yet. Click "Add Factor" to begin.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Mitigation Strategies -->
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<h4 class="card-title">
|
|
<i class="fas fa-shield-alt me-2"></i>
|
|
Mitigation Strategies
|
|
</h4>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="mb-3">
|
|
<label for="mitigation_strategies" class="form-label">
|
|
<strong>Current Mitigation Strategies</strong>
|
|
</label>
|
|
<textarea class="form-control"
|
|
id="mitigation_strategies"
|
|
name="mitigation_strategies"
|
|
rows="4"
|
|
placeholder="Describe existing controls and mitigation measures...">{{ object.mitigation_strategies|default:"" }}</textarea>
|
|
<div class="form-text">
|
|
List current controls, procedures, and measures in place to mitigate this risk.
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label for="implementation_plan" class="form-label">
|
|
<strong>Implementation Plan</strong>
|
|
</label>
|
|
<textarea class="form-control"
|
|
id="implementation_plan"
|
|
name="implementation_plan"
|
|
rows="4"
|
|
placeholder="Describe the plan for implementing additional mitigation measures...">{{ object.implementation_plan|default:"" }}</textarea>
|
|
<div class="form-text">
|
|
Outline steps to implement new or improved risk mitigation measures.
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label for="monitoring_plan" class="form-label">
|
|
<strong>Monitoring Plan</strong>
|
|
</label>
|
|
<textarea class="form-control"
|
|
id="monitoring_plan"
|
|
name="monitoring_plan"
|
|
rows="3"
|
|
placeholder="Describe how this risk will be monitored and measured...">{{ object.monitoring_plan|default:"" }}</textarea>
|
|
<div class="form-text">
|
|
How will you monitor the effectiveness of mitigation strategies?
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Additional Information -->
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<h4 class="card-title">
|
|
<i class="fas fa-cogs me-2"></i>
|
|
Additional Information
|
|
</h4>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label for="regulatory_requirements" class="form-label">
|
|
<strong>Regulatory Requirements</strong>
|
|
</label>
|
|
<textarea class="form-control"
|
|
id="regulatory_requirements"
|
|
name="regulatory_requirements"
|
|
rows="3"
|
|
placeholder="List relevant regulatory requirements...">{{ object.regulatory_requirements|default:"" }}</textarea>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label for="stakeholders" class="form-label">
|
|
<strong>Key Stakeholders</strong>
|
|
</label>
|
|
<textarea class="form-control"
|
|
id="stakeholders"
|
|
name="stakeholders"
|
|
rows="3"
|
|
placeholder="List key stakeholders and their roles...">{{ object.stakeholders|default:"" }}</textarea>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label for="resources_required" class="form-label">
|
|
<strong>Resources Required</strong>
|
|
</label>
|
|
<textarea class="form-control"
|
|
id="resources_required"
|
|
name="resources_required"
|
|
rows="3"
|
|
placeholder="List resources needed for mitigation...">{{ object.resources_required|default:"" }}</textarea>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="mb-3">
|
|
<label for="success_criteria" class="form-label">
|
|
<strong>Success Criteria</strong>
|
|
</label>
|
|
<textarea class="form-control"
|
|
id="success_criteria"
|
|
name="success_criteria"
|
|
rows="3"
|
|
placeholder="Define success criteria for risk mitigation...">{{ object.success_criteria|default:"" }}</textarea>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-xl-4">
|
|
<!-- Risk Matrix -->
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<h5 class="card-title">
|
|
<i class="fas fa-th me-2"></i>
|
|
Risk Matrix
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="risk-matrix">
|
|
<table class="table table-bordered text-center">
|
|
<thead>
|
|
<tr>
|
|
<th></th>
|
|
<th colspan="5">Likelihood</th>
|
|
</tr>
|
|
<tr>
|
|
<th>Impact</th>
|
|
<th>1</th>
|
|
<th>2</th>
|
|
<th>3</th>
|
|
<th>4</th>
|
|
<th>5</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for i in "54321" %}
|
|
<tr>
|
|
<th>{{ i }}</th>
|
|
{% for j in "12345" %}
|
|
<td class="risk-cell risk-{{ i|add:j|floatformat:0 }}"
|
|
data-risk="{{ i|mul:j }}"
|
|
onclick="selectRiskLevel({{ i }}, {{ j }})">
|
|
{{ i|mul:j }}
|
|
</td>
|
|
{% endfor %}
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
<div class="mt-2">
|
|
<small class="text-muted">
|
|
Click on a cell to set the overall risk level.
|
|
</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Risk Score Summary -->
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<h5 class="card-title">
|
|
<i class="fas fa-calculator me-2"></i>
|
|
Risk Score Summary
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="mb-3">
|
|
<label for="overall_risk_score" class="form-label">
|
|
<strong>Overall Risk Score</strong>
|
|
</label>
|
|
<input type="number"
|
|
class="form-control"
|
|
id="overall_risk_score"
|
|
name="overall_risk_score"
|
|
value="{{ object.overall_risk_score|default:"" }}"
|
|
min="1"
|
|
max="25"
|
|
readonly>
|
|
<div class="form-text">
|
|
Calculated from risk factors or matrix selection.
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label for="risk_level" class="form-label">
|
|
<strong>Risk Level</strong>
|
|
</label>
|
|
<select class="form-select" id="risk_level" name="risk_level">
|
|
<option value="">Select level</option>
|
|
<option value="very_low" {% if object and object.risk_level == 'very_low' %}selected{% endif %}>Very Low</option>
|
|
<option value="low" {% if object and object.risk_level == 'low' %}selected{% endif %}>Low</option>
|
|
<option value="medium" {% if object and object.risk_level == 'medium' %}selected{% endif %}>Medium</option>
|
|
<option value="high" {% if object and object.risk_level == 'high' %}selected{% endif %}>High</option>
|
|
<option value="very_high" {% if object and object.risk_level == 'very_high' %}selected{% endif %}>Very High</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="alert alert-info">
|
|
<h6 class="alert-heading">Risk Level Guidelines</h6>
|
|
<ul class="mb-0 small">
|
|
<li><strong>1-4:</strong> Very Low - Minimal impact</li>
|
|
<li><strong>5-9:</strong> Low - Minor impact</li>
|
|
<li><strong>10-14:</strong> Medium - Moderate impact</li>
|
|
<li><strong>15-19:</strong> High - Significant impact</li>
|
|
<li><strong>20-25:</strong> Very High - Severe impact</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Assessment Status -->
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<h5 class="card-title">
|
|
<i class="fas fa-flag me-2"></i>
|
|
Assessment Status
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="mb-3">
|
|
<label for="status" class="form-label">
|
|
<strong>Status</strong>
|
|
</label>
|
|
<select class="form-select" id="status" name="status">
|
|
<option value="draft" {% if not object or object.status == 'draft' %}selected{% endif %}>Draft</option>
|
|
<option value="in_review" {% if object and object.status == 'in_review' %}selected{% endif %}>In Review</option>
|
|
<option value="approved" {% if object and object.status == 'approved' %}selected{% endif %}>Approved</option>
|
|
<option value="implemented" {% if object and object.status == 'implemented' %}selected{% endif %}>Implemented</option>
|
|
<option value="archived" {% if object and object.status == 'archived' %}selected{% endif %}>Archived</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-check mb-3">
|
|
<input class="form-check-input"
|
|
type="checkbox"
|
|
id="requires_approval"
|
|
name="requires_approval"
|
|
{% if not object or object.requires_approval %}checked{% endif %}>
|
|
<label class="form-check-label" for="requires_approval">
|
|
Requires management approval
|
|
</label>
|
|
</div>
|
|
|
|
<div class="form-check mb-3">
|
|
<input class="form-check-input"
|
|
type="checkbox"
|
|
id="is_confidential"
|
|
name="is_confidential"
|
|
{% if object and object.is_confidential %}checked{% endif %}>
|
|
<label class="form-check-label" for="is_confidential">
|
|
Confidential assessment
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Quick Actions -->
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="card-title">
|
|
<i class="fas fa-bolt me-2"></i>
|
|
Quick Actions
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="d-grid gap-2">
|
|
<button type="button" class="btn btn-outline-primary" onclick="calculateRiskScore()">
|
|
<i class="fas fa-calculator me-2"></i>Calculate Risk Score
|
|
</button>
|
|
<button type="button" class="btn btn-outline-secondary" onclick="previewAssessment()">
|
|
<i class="fas fa-eye me-2"></i>Preview Assessment
|
|
</button>
|
|
<button type="button" class="btn btn-outline-info" onclick="saveAsDraft()">
|
|
<i class="fas fa-save me-2"></i>Save as Draft
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="d-flex justify-content-between mt-4">
|
|
<a href="{% url 'quality:risk_assessment_list' %}" class="btn btn-secondary">
|
|
<i class="fas fa-times me-2"></i>Cancel
|
|
</a>
|
|
<div>
|
|
<button type="button" class="btn btn-outline-primary me-2" onclick="saveAsDraft()">
|
|
<i class="fas fa-save me-2"></i>Save as Draft
|
|
</button>
|
|
<button type="submit" class="btn btn-primary">
|
|
<i class="fas fa-check me-2"></i>{% if object %}Update{% else %}Create{% endif %} Assessment
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
|
|
<!-- Risk Factor Template -->
|
|
<template id="riskFactorTemplate">
|
|
<div class="card mb-3 risk-factor-item">
|
|
<div class="card-header">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<h6 class="mb-0">Risk Factor</h6>
|
|
<button type="button" class="btn btn-sm btn-outline-danger" onclick="removeRiskFactor(this)">
|
|
<i class="fas fa-trash"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="mb-3">
|
|
<label class="form-label">Factor Name</label>
|
|
<input type="text" class="form-control factor-name" placeholder="Enter factor name">
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label">Description</label>
|
|
<textarea class="form-control factor-description" rows="2" placeholder="Describe this risk factor"></textarea>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-md-4">
|
|
<label class="form-label">Likelihood (1-5)</label>
|
|
<select class="form-select factor-likelihood" onchange="updateFactorScore(this)">
|
|
<option value="">Select</option>
|
|
<option value="1">1 - Very Unlikely</option>
|
|
<option value="2">2 - Unlikely</option>
|
|
<option value="3">3 - Possible</option>
|
|
<option value="4">4 - Likely</option>
|
|
<option value="5">5 - Very Likely</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<label class="form-label">Impact (1-5)</label>
|
|
<select class="form-select factor-impact" onchange="updateFactorScore(this)">
|
|
<option value="">Select</option>
|
|
<option value="1">1 - Minimal</option>
|
|
<option value="2">2 - Minor</option>
|
|
<option value="3">3 - Moderate</option>
|
|
<option value="4">4 - Major</option>
|
|
<option value="5">5 - Severe</option>
|
|
</select>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<label class="form-label">Risk Score</label>
|
|
<input type="text" class="form-control factor-score" readonly placeholder="Auto-calculated">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
let riskFactorCount = 0;
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// Initialize form
|
|
updateNoFactorsMessage();
|
|
|
|
// Set default assessment date to today
|
|
if (!document.getElementById('assessment_date').value) {
|
|
document.getElementById('assessment_date').value = new Date().toISOString().split('T')[0];
|
|
}
|
|
});
|
|
|
|
function addRiskFactor() {
|
|
const template = document.getElementById('riskFactorTemplate');
|
|
const clone = template.content.cloneNode(true);
|
|
|
|
riskFactorCount++;
|
|
|
|
document.getElementById('riskFactors').appendChild(clone);
|
|
updateNoFactorsMessage();
|
|
}
|
|
|
|
function removeRiskFactor(button) {
|
|
button.closest('.risk-factor-item').remove();
|
|
updateNoFactorsMessage();
|
|
calculateRiskScore();
|
|
}
|
|
|
|
function updateNoFactorsMessage() {
|
|
const factors = document.querySelectorAll('.risk-factor-item');
|
|
const message = document.getElementById('noFactorsMessage');
|
|
|
|
if (factors.length === 0) {
|
|
message.style.display = 'block';
|
|
} else {
|
|
message.style.display = 'none';
|
|
}
|
|
}
|
|
|
|
function updateFactorScore(element) {
|
|
const factorItem = element.closest('.risk-factor-item');
|
|
const likelihood = factorItem.querySelector('.factor-likelihood').value;
|
|
const impact = factorItem.querySelector('.factor-impact').value;
|
|
const scoreField = factorItem.querySelector('.factor-score');
|
|
|
|
if (likelihood && impact) {
|
|
const score = parseInt(likelihood) * parseInt(impact);
|
|
scoreField.value = score;
|
|
|
|
// Update score styling
|
|
scoreField.className = 'form-control factor-score';
|
|
if (score >= 15) {
|
|
scoreField.classList.add('bg-danger', 'text-white');
|
|
} else if (score >= 10) {
|
|
scoreField.classList.add('bg-warning');
|
|
} else if (score >= 5) {
|
|
scoreField.classList.add('bg-info', 'text-white');
|
|
} else {
|
|
scoreField.classList.add('bg-success', 'text-white');
|
|
}
|
|
} else {
|
|
scoreField.value = '';
|
|
scoreField.className = 'form-control factor-score';
|
|
}
|
|
|
|
calculateRiskScore();
|
|
}
|
|
|
|
function calculateRiskScore() {
|
|
const factorScores = document.querySelectorAll('.factor-score');
|
|
let totalScore = 0;
|
|
let factorCount = 0;
|
|
|
|
factorScores.forEach(score => {
|
|
if (score.value) {
|
|
totalScore += parseInt(score.value);
|
|
factorCount++;
|
|
}
|
|
});
|
|
|
|
if (factorCount > 0) {
|
|
const averageScore = Math.round(totalScore / factorCount);
|
|
document.getElementById('overall_risk_score').value = averageScore;
|
|
updateRiskLevel(averageScore);
|
|
}
|
|
}
|
|
|
|
function updateRiskLevel(score) {
|
|
const riskLevelSelect = document.getElementById('risk_level');
|
|
|
|
if (score >= 20) {
|
|
riskLevelSelect.value = 'very_high';
|
|
} else if (score >= 15) {
|
|
riskLevelSelect.value = 'high';
|
|
} else if (score >= 10) {
|
|
riskLevelSelect.value = 'medium';
|
|
} else if (score >= 5) {
|
|
riskLevelSelect.value = 'low';
|
|
} else {
|
|
riskLevelSelect.value = 'very_low';
|
|
}
|
|
}
|
|
|
|
function selectRiskLevel(impact, likelihood) {
|
|
const score = impact * likelihood;
|
|
document.getElementById('overall_risk_score').value = score;
|
|
updateRiskLevel(score);
|
|
|
|
// Highlight selected cell
|
|
document.querySelectorAll('.risk-cell').forEach(cell => {
|
|
cell.classList.remove('selected');
|
|
});
|
|
|
|
event.target.classList.add('selected');
|
|
}
|
|
|
|
function previewAssessment() {
|
|
const title = document.getElementById('title').value;
|
|
const category = document.getElementById('risk_category').value;
|
|
const priority = document.getElementById('priority').value;
|
|
const score = document.getElementById('overall_risk_score').value;
|
|
|
|
if (!title) {
|
|
alert('Please enter an assessment title first.');
|
|
return;
|
|
}
|
|
|
|
const preview = `
|
|
Risk Assessment Preview:
|
|
|
|
Title: ${title}
|
|
Category: ${category || 'Not specified'}
|
|
Priority: ${priority || 'Not specified'}
|
|
Risk Score: ${score || 'Not calculated'}
|
|
|
|
This is a preview of how the assessment will appear.
|
|
`;
|
|
|
|
alert(preview);
|
|
}
|
|
|
|
function saveAsDraft() {
|
|
document.getElementById('status').value = 'draft';
|
|
document.getElementById('riskAssessmentForm').submit();
|
|
}
|
|
|
|
// Form validation
|
|
document.getElementById('riskAssessmentForm').addEventListener('submit', function(e) {
|
|
const title = document.getElementById('title').value;
|
|
const category = document.getElementById('risk_category').value;
|
|
const description = document.getElementById('description').value;
|
|
|
|
if (!title || !category || !description) {
|
|
e.preventDefault();
|
|
alert('Please fill in all required fields (Title, Category, Description).');
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
});
|
|
</script>
|
|
|
|
<style>
|
|
.risk-matrix .risk-cell {
|
|
width: 40px;
|
|
height: 40px;
|
|
font-weight: bold;
|
|
cursor: pointer;
|
|
transition: all 0.2s;
|
|
}
|
|
|
|
.risk-matrix .risk-cell:hover {
|
|
transform: scale(1.1);
|
|
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
|
|
}
|
|
|
|
.risk-matrix .risk-cell.selected {
|
|
border: 3px solid #007bff;
|
|
box-shadow: 0 0 10px rgba(0,123,255,0.5);
|
|
}
|
|
|
|
.risk-cell.risk-1, .risk-cell.risk-2 { background-color: #d4edda; color: #155724; }
|
|
.risk-cell.risk-3, .risk-cell.risk-4, .risk-cell.risk-6 { background-color: #fff3cd; color: #856404; }
|
|
.risk-cell.risk-5, .risk-cell.risk-8, .risk-cell.risk-9, .risk-cell.risk-10 { background-color: #f8d7da; color: #721c24; }
|
|
.risk-cell.risk-12, .risk-cell.risk-15, .risk-cell.risk-16, .risk-cell.risk-20, .risk-cell.risk-25 { background-color: #721c24; color: white; }
|
|
|
|
.risk-factor-item {
|
|
border-left: 4px solid #007bff;
|
|
}
|
|
</style>
|
|
{% endblock %}
|
|
|