mirror of
https://github.com/nottinghamtec/PyRIGS.git
synced 2026-02-12 01:29:42 +00:00
Initial pass at soop-consult confirmation screen for RAs
This commit is contained in:
@@ -161,12 +161,23 @@ class EventRiskAssessmentForm(forms.ModelForm):
|
|||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(EventRiskAssessmentForm, self).__init__(*args, **kwargs)
|
super(EventRiskAssessmentForm, self).__init__(*args, **kwargs)
|
||||||
for name, field in self.fields.items():
|
for name, field in self.fields.items():
|
||||||
if field.__class__ == forms.BooleanField:
|
if str(name) == 'supervisor_consulted':
|
||||||
|
field.widget = forms.CheckboxInput()
|
||||||
|
elif field.__class__ == forms.BooleanField:
|
||||||
field.widget = forms.RadioSelect(choices=[
|
field.widget = forms.RadioSelect(choices=[
|
||||||
(True, 'Yes'),
|
(True, 'Yes'),
|
||||||
(False, 'No')
|
(False, 'No')
|
||||||
], attrs={'class': 'custom-control-input', 'required': 'true'})
|
], attrs={'class': 'custom-control-input', 'required': 'true'})
|
||||||
|
|
||||||
|
def clean(self):
|
||||||
|
unexpected_values = []
|
||||||
|
for field, value in models.RiskAssessment.expected_values.items():
|
||||||
|
if self.cleaned_data.get(field) != value:
|
||||||
|
unexpected_values.append("<li>{}</li>".format(self._meta.model._meta.get_field(field).help_text))
|
||||||
|
if len(unexpected_values) > 0 and not self.cleaned_data.get('supervisor_consulted'):
|
||||||
|
raise forms.ValidationError("Your answers to these questions: <ul>{}</ul> require consulting with a supervisor.".format(''.join([str(elem) for elem in unexpected_values])), code='unusual_answers')
|
||||||
|
return super(EventRiskAssessmentForm, self).clean()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = models.RiskAssessment
|
model = models.RiskAssessment
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ class EventRiskAssessmentCreate(generic.CreateView):
|
|||||||
epk = self.kwargs.get('pk')
|
epk = self.kwargs.get('pk')
|
||||||
event = models.Event.objects.get(pk=epk)
|
event = models.Event.objects.get(pk=epk)
|
||||||
context['event'] = event
|
context['event'] = event
|
||||||
|
context['page_title'] = 'Create Risk Assessment for Event {}'.format(event.display_id)
|
||||||
return context
|
return context
|
||||||
|
|
||||||
def get_success_url(self):
|
def get_success_url(self):
|
||||||
@@ -60,6 +61,7 @@ class EventRiskAssessmentEdit(generic.UpdateView):
|
|||||||
ra = models.RiskAssessment.objects.get(pk=rpk)
|
ra = models.RiskAssessment.objects.get(pk=rpk)
|
||||||
context['event'] = ra.event
|
context['event'] = ra.event
|
||||||
context['edit'] = True
|
context['edit'] = True
|
||||||
|
context['page_title'] = 'Edit Risk Assessment for Event {}'.format(ra.event.display_id)
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
18
RIGS/migrations/0042_riskassessment_supervisor_consulted.py
Normal file
18
RIGS/migrations/0042_riskassessment_supervisor_consulted.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 3.1.2 on 2020-10-10 10:54
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('RIGS', '0041_auto_20200929_1749'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='riskassessment',
|
||||||
|
name='supervisor_consulted',
|
||||||
|
field=models.BooleanField(blank=True, null=True),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -667,9 +667,29 @@ class RiskAssessment(models.Model, RevisionMixin):
|
|||||||
reviewed_by = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True,
|
reviewed_by = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True,
|
||||||
verbose_name="Reviewer", on_delete=models.CASCADE)
|
verbose_name="Reviewer", on_delete=models.CASCADE)
|
||||||
|
|
||||||
inverted_fields = ['nonstandard_equipment', 'nonstandard_use', 'contractors', 'other_companies', 'crew_fatigue', 'big_power',
|
supervisor_consulted = models.BooleanField(null=True)
|
||||||
'generators', 'other_companies_power', 'nonstandard_equipment_power', 'multiple_electrical_environments', 'noise_monitoring'
|
|
||||||
'special_structures', 'suspended_structures']
|
expected_values = {
|
||||||
|
'nonstandard_equipment': False,
|
||||||
|
'nonstandard_use': False,
|
||||||
|
'contractors': False,
|
||||||
|
'other_companies': False,
|
||||||
|
'crew_fatigue': False,
|
||||||
|
'big_power': False,
|
||||||
|
'generators': False,
|
||||||
|
'other_companies_power': False,
|
||||||
|
'nonstandard_equipment_power': False,
|
||||||
|
'multiple_electrical_environments': False,
|
||||||
|
'noise_monitoring': False,
|
||||||
|
'known_venue': True,
|
||||||
|
'safe_loading': True,
|
||||||
|
'safe_storage': True,
|
||||||
|
'area_outside_of_control': False,
|
||||||
|
'barrier_required': False,
|
||||||
|
'nonstandard_emergency_procedure': False,
|
||||||
|
'special_structures': False,
|
||||||
|
'suspended_structures': False,
|
||||||
|
}
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ['event']
|
ordering = ['event']
|
||||||
|
|||||||
@@ -2,8 +2,7 @@
|
|||||||
{% load widget_tweaks %}
|
{% load widget_tweaks %}
|
||||||
{% load static %}
|
{% load static %}
|
||||||
{% load help_text from filters %}
|
{% load help_text from filters %}
|
||||||
|
{% load nice_errors from filters %}
|
||||||
{% block title %}{% if edit %}Edit{% else %}Create{% endif %} Risk Assessment for Event N{{ event.pk|stringformat:"05d" }}{% endblock %}
|
|
||||||
|
|
||||||
{% block css %}
|
{% block css %}
|
||||||
{{ block.super }}
|
{{ block.super }}
|
||||||
@@ -28,13 +27,34 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="col-sm-offset-1 col-sm-10">
|
<div class="col">
|
||||||
<h3>{% if edit %}Edit{% else %}Create{% endif %} Risk Assessment for Event N{{ event.pk|stringformat:"05d" }}</h3>
|
{% if form.errors %}
|
||||||
{% include 'form_errors.html' %}
|
<div class="alert alert-danger alert-dismissable">
|
||||||
{% if edit %}
|
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
|
||||||
<form role="form" method="POST" action="{% url 'ra_edit' pk=object.pk %}">
|
<dl>
|
||||||
|
{% with form|nice_errors as qq %}
|
||||||
|
{% for error_name,desc in qq.items %}
|
||||||
|
{% if error_name == 'General form errors' %}
|
||||||
|
{{ form.non_field_errors.0|safe }}
|
||||||
|
<div class="text-right">
|
||||||
|
{% render_field form.supervisor_consulted class+="form-check-input" form="form" %}<label class="form-check-label" for="{{ form.supervisor_consulted.id_for_label}}">Please confirm you've done so.</label><br>
|
||||||
|
<button class="btn btn-primary mt-2" type="submit" form="form"><span class="fas fa-thumbs-up"></span> Confirm</button>
|
||||||
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<form role="form" method="POST" action="{% url 'event_ra' pk=event.pk %}">
|
<span class="row">
|
||||||
|
<dt class="col-4">{{error_name}}</dt>
|
||||||
|
<dd class="col-8">{{desc}}</dd>
|
||||||
|
</span>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endwith %}
|
||||||
|
</dl>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% if edit %}
|
||||||
|
<form role="form" method="POST" action="{% url 'ra_edit' pk=object.pk %}" id="form">
|
||||||
|
{% else %}
|
||||||
|
<form role="form" method="POST" action="{% url 'event_ra' pk=event.pk %}" id="form">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<input type="hidden" name="{{ form.event.name }}" id="{{ form.event.id_for_label }}"
|
<input type="hidden" name="{{ form.event.name }}" id="{{ form.event.id_for_label }}"
|
||||||
value="{{event.pk}}"/>
|
value="{{event.pk}}"/>
|
||||||
|
|||||||
@@ -34,8 +34,8 @@ def to_class_name(value):
|
|||||||
return value.__class__.__name__
|
return value.__class__.__name__
|
||||||
|
|
||||||
|
|
||||||
@register.filter
|
@register.filter(needs_autoescape=True)
|
||||||
def nice_errors(form, non_field_msg='General form errors'):
|
def nice_errors(form, non_field_msg='General form errors', autoescape=True):
|
||||||
nice_errors = ErrorDict()
|
nice_errors = ErrorDict()
|
||||||
if isinstance(form, forms.BaseForm):
|
if isinstance(form, forms.BaseForm):
|
||||||
for field, errors in list(form.errors.items()):
|
for field, errors in list(form.errors.items()):
|
||||||
@@ -123,7 +123,7 @@ def orderby(request, field, attr):
|
|||||||
def get_field(obj, field, autoescape=True):
|
def get_field(obj, field, autoescape=True):
|
||||||
value = getattr(obj, field)
|
value = getattr(obj, field)
|
||||||
if(isinstance(value, bool)):
|
if(isinstance(value, bool)):
|
||||||
value = yesnoi(value, field in obj.inverted_fields)
|
value = yesnoi(value)
|
||||||
elif(isinstance(value, str)):
|
elif(isinstance(value, str)):
|
||||||
value = truncatewords(value, 20)
|
value = truncatewords(value, 20)
|
||||||
return mark_safe(value)
|
return mark_safe(value)
|
||||||
|
|||||||
@@ -206,6 +206,7 @@ class CreateRiskAssessment(FormPage):
|
|||||||
'special_structures': (regions.RadioSelect, (By.ID, 'id_special_structures')),
|
'special_structures': (regions.RadioSelect, (By.ID, 'id_special_structures')),
|
||||||
'persons_responsible_structures': (regions.TextBox, (By.ID, 'id_persons_responsible_structures')),
|
'persons_responsible_structures': (regions.TextBox, (By.ID, 'id_persons_responsible_structures')),
|
||||||
'suspended_structures': (regions.RadioSelect, (By.ID, 'id_suspended_structures')),
|
'suspended_structures': (regions.RadioSelect, (By.ID, 'id_suspended_structures')),
|
||||||
|
'supervisor_consulted': (regions.CheckBox, (By.ID, 'id_supervisor_consulted')),
|
||||||
}
|
}
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|||||||
@@ -662,6 +662,30 @@ class TestHealthAndSafety(BaseRigboardTest):
|
|||||||
description="start future no end",
|
description="start future no end",
|
||||||
purchase_order='TESTPO',
|
purchase_order='TESTPO',
|
||||||
person=self.client)
|
person=self.client)
|
||||||
|
self.testEvent2 = models.Event.objects.create(name="TE E2", status=models.Event.PROVISIONAL,
|
||||||
|
start_date=date.today() + timedelta(days=6),
|
||||||
|
description="start future no end",
|
||||||
|
purchase_order='TESTPO',
|
||||||
|
person=self.client)
|
||||||
|
self.testRA = models.RiskAssessment.objects.create(event=self.testEvent2, supervisor_consulted=False, nonstandard_equipment=False,
|
||||||
|
nonstandard_use=False,
|
||||||
|
contractors=False,
|
||||||
|
other_companies=False,
|
||||||
|
crew_fatigue=False,
|
||||||
|
big_power=False,
|
||||||
|
generators=False,
|
||||||
|
other_companies_power=False,
|
||||||
|
nonstandard_equipment_power=False,
|
||||||
|
multiple_electrical_environments=False,
|
||||||
|
noise_monitoring=False,
|
||||||
|
known_venue=True,
|
||||||
|
safe_loading=True,
|
||||||
|
safe_storage=True,
|
||||||
|
area_outside_of_control=False,
|
||||||
|
barrier_required=False,
|
||||||
|
nonstandard_emergency_procedure=False,
|
||||||
|
special_structures=False,
|
||||||
|
suspended_structures=False)
|
||||||
self.page = pages.EventDetail(self.driver, self.live_server_url, event_id=self.testEvent.pk).open()
|
self.page = pages.EventDetail(self.driver, self.live_server_url, event_id=self.testEvent.pk).open()
|
||||||
|
|
||||||
# TODO Can I loop through all the boolean fields and test them at once?
|
# TODO Can I loop through all the boolean fields and test them at once?
|
||||||
@@ -700,8 +724,12 @@ class TestHealthAndSafety(BaseRigboardTest):
|
|||||||
self.page.nonstandard_emergency_procedure = False
|
self.page.nonstandard_emergency_procedure = False
|
||||||
self.page.special_structures = False
|
self.page.special_structures = False
|
||||||
self.page.persons_responsible_structures = "Nobody and her cat, She"
|
self.page.persons_responsible_structures = "Nobody and her cat, She"
|
||||||
self.page.suspended_structures = False
|
|
||||||
|
|
||||||
|
self.page.suspended_structures = True
|
||||||
|
self.page.submit()
|
||||||
|
self.assertFalse(self.page.success)
|
||||||
|
|
||||||
|
self.page.suspended_structures = False
|
||||||
self.page.submit()
|
self.page.submit()
|
||||||
self.assertTrue(self.page.success)
|
self.assertTrue(self.page.success)
|
||||||
|
|
||||||
@@ -710,27 +738,16 @@ class TestHealthAndSafety(BaseRigboardTest):
|
|||||||
self.assertIn('edit', self.driver.current_url)
|
self.assertIn('edit', self.driver.current_url)
|
||||||
|
|
||||||
def test_ra_edit(self):
|
def test_ra_edit(self):
|
||||||
# Create assessment to edit
|
self.page = pages.EditRiskAssessment(self.driver, self.live_server_url, pk=self.testRA.pk).open()
|
||||||
self.page = pages.CreateRiskAssessment(self.driver, self.live_server_url, event_id=self.testEvent.pk).open()
|
|
||||||
self.page.nonstandard_equipment = False
|
|
||||||
self.page.nonstandard_use = False
|
|
||||||
self.page.contractors = False
|
|
||||||
self.page.other_companies = False
|
|
||||||
self.page.crew_fatigue = False
|
|
||||||
self.page.general_notes = "There are no notes."
|
|
||||||
self.page.big_power = False
|
|
||||||
self.page.power_mic.search(self.profile.name)
|
|
||||||
self.page.power_mic.toggle()
|
|
||||||
self.assertFalse(self.page.power_mic.is_open)
|
|
||||||
self.page.remove_all_required()
|
|
||||||
self.page.submit()
|
|
||||||
self.page = pages.EditRiskAssessment(self.driver, self.live_server_url, pk=models.RiskAssessment.objects.get(event=self.testEvent.pk).pk).open()
|
|
||||||
self.page.nonstandard_equipment = nse = True
|
self.page.nonstandard_equipment = nse = True
|
||||||
self.page.general_notes = gn = "There are some notes, but I've not written them here as that would be helpful"
|
self.page.general_notes = gn = "There are some notes, but I've not written them here as that would be helpful"
|
||||||
self.page.submit()
|
self.page.submit()
|
||||||
|
self.assertFalse(self.page.success)
|
||||||
|
self.page.supervisor_consulted = True
|
||||||
|
self.page.submit()
|
||||||
self.assertTrue(self.page.success)
|
self.assertTrue(self.page.success)
|
||||||
# Check that data is right
|
# Check that data is right
|
||||||
ra = models.RiskAssessment.objects.get(event=self.testEvent.pk)
|
ra = models.RiskAssessment.objects.get(pk=self.testRA.pk)
|
||||||
self.assertEqual(ra.general_notes, gn)
|
self.assertEqual(ra.general_notes, gn)
|
||||||
self.assertEqual(ra.nonstandard_equipment, nse)
|
self.assertEqual(ra.nonstandard_equipment, nse)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user