Allow multiple event checklists per event

TODO: Status chip now needs rethinking
This commit is contained in:
2020-09-29 17:59:03 +01:00
parent 0117002b01
commit 813b1dac85
8 changed files with 129 additions and 26 deletions

View File

@@ -127,7 +127,7 @@ class EventChecklistCreate(generic.CreateView):
template_name = 'event_checklist_form.html'
form_class = forms.EventChecklistForm
def get(self, *args, **kwargs):
"""def get(self, *args, **kwargs):
epk = kwargs.get('pk')
event = models.Event.objects.get(pk=epk)
@@ -137,7 +137,7 @@ class EventChecklistCreate(generic.CreateView):
if ra is not None:
return HttpResponseRedirect(reverse_lazy('ec_edit', kwargs={'pk': ra.pk}))
return super(EventChecklistCreate, self).get(self)
return super(EventChecklistCreate, self).get(self)"""
def get_form(self, **kwargs):
form = super(EventChecklistCreate, self).get_form(**kwargs)

View File

@@ -0,0 +1,80 @@
# Generated by Django 3.1 on 2020-09-29 16:49
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('RIGS', '0040_auto_20200925_2141'),
]
operations = [
migrations.AlterField(
model_name='eventchecklist',
name='ear_plugs',
field=models.BooleanField(blank=True, help_text='Ear plugs issued to crew where needed?', null=True),
),
migrations.AlterField(
model_name='eventchecklist',
name='earthing',
field=models.BooleanField(blank=True, help_text='Equipment appropriately earthed?<br><small>(truss, stage, generators etc)</small>', null=True),
),
migrations.AlterField(
model_name='eventchecklist',
name='event',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='checklists', to='RIGS.event'),
),
migrations.AlterField(
model_name='eventchecklist',
name='event_size',
field=models.IntegerField(blank=True, choices=[(0, 'Small'), (1, 'Medium'), (2, 'Large')], null=True),
),
migrations.AlterField(
model_name='eventchecklist',
name='exits',
field=models.BooleanField(blank=True, help_text='Emergency exits clear?', null=True),
),
migrations.AlterField(
model_name='eventchecklist',
name='extinguishers_location',
field=models.CharField(blank=True, help_text='Location of fire extinguishers', max_length=255, null=True),
),
migrations.AlterField(
model_name='eventchecklist',
name='hs_location',
field=models.CharField(blank=True, help_text='Location of Safety Bag/Box', max_length=255, null=True),
),
migrations.AlterField(
model_name='eventchecklist',
name='pat',
field=models.BooleanField(blank=True, help_text='All equipment in PAT period?', null=True),
),
migrations.AlterField(
model_name='eventchecklist',
name='power_mic',
field=models.ForeignKey(blank=True, help_text='Who is the Power MIC?', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='checklists', to=settings.AUTH_USER_MODEL, verbose_name='Power MIC'),
),
migrations.AlterField(
model_name='eventchecklist',
name='safe_packing',
field=models.BooleanField(blank=True, help_text='Equipment packed away safely?<br><small>(including flightcases)</small>', null=True),
),
migrations.AlterField(
model_name='eventchecklist',
name='safe_parking',
field=models.BooleanField(blank=True, help_text='Vehicles parked safely?<br><small>(does not obstruct venue access)</small>', null=True),
),
migrations.AlterField(
model_name='eventchecklist',
name='trip_hazard',
field=models.BooleanField(blank=True, help_text='Appropriate barriers around kit and cabling secured?', null=True),
),
migrations.AlterField(
model_name='eventchecklist',
name='warning_signs',
field=models.BooleanField(blank=True, help_text='Warning signs in place?<br><small>(strobe, smoke, power etc.)</small>'),
),
]

View File

@@ -383,6 +383,10 @@ class Event(models.Model, RevisionMixin):
else:
return bool(self.purchase_order)
@property
def hs_done(self):
return self.riskassessment is not None and len(self.checklists.all()) > 0
@property
def has_start_time(self):
return self.start_time is not None
@@ -684,31 +688,31 @@ class EventChecklist(models.Model, RevisionMixin):
MEDIUM = (1, 'Medium')
LARGE = (2, 'Large')
SIZES = (SMALL, MEDIUM, LARGE)
event = models.OneToOneField('Event', on_delete=models.CASCADE)
event = models.ForeignKey('Event', related_name='checklists', on_delete=models.CASCADE)
# General
power_mic = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='checklists', null=True,
power_mic = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True, related_name='checklists',
verbose_name="Power MIC", on_delete=models.CASCADE, help_text="Who is the Power MIC?")
# Safety Checks
safe_parking = models.BooleanField(help_text="Vehicles parked safely?<br><small>(does not obstruct venue access)</small>")
safe_packing = models.BooleanField(help_text="Equipment packed away safely?<br><small>(including flightcases)</small>")
exits = models.BooleanField(help_text="Emergency exits clear?")
trip_hazard = models.BooleanField(help_text="Appropriate barriers around kit and cabling secured?")
warning_signs = models.BooleanField(help_text="Warning signs in place?<br><small>(strobe, smoke, power etc.)</small>")
ear_plugs = models.BooleanField(help_text="Ear plugs issued to crew where needed?")
hs_location = models.CharField(max_length=255, help_text="Location of Safety Bag/Box")
extinguishers_location = models.CharField(max_length=255, help_text="Location of fire extinguishers")
safe_parking = models.BooleanField(blank=True, null=True, help_text="Vehicles parked safely?<br><small>(does not obstruct venue access)</small>")
safe_packing = models.BooleanField(blank=True, null=True, help_text="Equipment packed away safely?<br><small>(including flightcases)</small>")
exits = models.BooleanField(blank=True, null=True, help_text="Emergency exits clear?")
trip_hazard = models.BooleanField(blank=True, null=True, help_text="Appropriate barriers around kit and cabling secured?")
warning_signs = models.BooleanField(blank=True, help_text="Warning signs in place?<br><small>(strobe, smoke, power etc.)</small>")
ear_plugs = models.BooleanField(blank=True, null=True, help_text="Ear plugs issued to crew where needed?")
hs_location = models.CharField(blank=True, null=True, max_length=255, help_text="Location of Safety Bag/Box")
extinguishers_location = models.CharField(blank=True, null=True, max_length=255, help_text="Location of fire extinguishers")
# Small Electrical Checks
rcds = models.BooleanField(blank=True, null=True, help_text="RCDs installed where needed and tested?")
supply_test = models.BooleanField(blank=True, null=True, help_text="Electrical supplies tested?<br><small>(using socket tester)</small>")
# Shared electrical checks
earthing = models.BooleanField(help_text="Equipment appropriately earthed?<br><small>(truss, stage, generators etc)</small>")
pat = models.BooleanField(help_text="All equipment in PAT period?")
earthing = models.BooleanField(blank=True, null=True, help_text="Equipment appropriately earthed?<br><small>(truss, stage, generators etc)</small>")
pat = models.BooleanField(blank=True, null=True, help_text="All equipment in PAT period?")
event_size = models.IntegerField(choices=SIZES)
event_size = models.IntegerField(blank=True, null=True, choices=SIZES)
# Medium Electrical Checks
source_rcd = models.BooleanField(blank=True, null=True, help_text="Source RCD protected?<br><small>(if cable is more than 3m long) </small>")
labelling = models.BooleanField(blank=True, null=True, help_text="Appropriate and clear labelling on distribution and cabling?")
@@ -748,7 +752,7 @@ class EventChecklist(models.Model, RevisionMixin):
('review_eventchecklist', 'Can review Event Checklists')
]
def clean(self):
"""def clean(self):
errdict = {}
if self.power_mic is None:
@@ -768,7 +772,7 @@ class EventChecklist(models.Model, RevisionMixin):
errdict['w1_description'] = 'Fully complete at least the first worst case point'
if errdict != {}: # If there was an error when validation
raise ValidationError(errdict)
raise ValidationError(errdict)"""
@property
def activity_feed_string(self):

View File

@@ -1,5 +1,6 @@
{% extends 'base_rigs.html' %}
{% load paginator from filters %}
{% load button from filters %}
{% block title %}H&S Overview{% endblock %}
@@ -11,7 +12,7 @@
<th scope="col">Event</th>
<th scope="col">Dates</th>
<th scope="col">RA</th>
<th scope="col">Checklist</th>
<th scope="col">Checklists</th>
</tr>
</thead>
<tbody>
@@ -26,7 +27,14 @@
{% endif %}
</td>
<td>{% include 'partials/hs_status.html' with event=event object=event.riskassessment view='ra_detail' edit='ra_edit' create='event_ra' review='ra_review' perm=perms.RIGS.review_riskassessment %}</td>
<td>{% include 'partials/hs_status.html' with event=event object=event.eventchecklist view='ec_detail' edit='ec_edit' create='event_ec' review='ec_review' perm=perms.RIGS.review_eventchecklist %}</td>
<td>
{% for checklist in event.checklists.all %}
{% include 'partials/hs_status.html' with event=event object=checklist view='ec_detail' edit='ec_edit' create='event_ec' review='ec_review' perm=perms.RIGS.review_eventchecklist %}
<br>
{% endfor %}
<a href="{% url 'event_ec' event.pk %}" class="btn btn-info mt-2"><span class="fas fa-paperclip"></span> <span
class="hidden-xs">Create</span></a>
</td>
</tr>
{% empty %}
<tr class="bg-warning text-dark">

View File

@@ -19,8 +19,9 @@
{% endif %}
<br>
{% if not event.dry_hire %}
{% if event.eventchecklist %}
<span class="badge badge-success">Checklist: <span class="fas fa-check"></span>{%if event.eventchecklist.reviewed_by%}<span class="fas fa-check"></span>{%endif%}</span>
{% if event.hs_done %}
{# TODO Display status of all checklists #}
<span class="badge badge-success">Checklist: <span class="fas fa-check"></span></span>
{% else %}
<span class="badge badge-danger">Checklist: <span class="fas fa-times"></span></span>
{% endif %}

View File

@@ -1,4 +1,4 @@
<div class="card {% if event.riskassessment and event.eventchecklist %}
<div class="card {% if event.hs_done %}
border-success
{% else %}
border-warning
@@ -8,7 +8,12 @@
<h5>Risk Assessment:</h5>
{% include 'partials/hs_status.html' with event=event object=event.riskassessment view='ra_detail' edit='ra_edit' create='event_ra' %}
<hr>
<h5>Event Checklist:</h5>
{% include 'partials/hs_status.html' with event=event object=event.eventchecklist view='ec_detail' edit='ec_edit' create='event_ec' %}
<h5>Event Checklists:</h5>
{% for checklist in event.checklists.all %}
{% include 'partials/hs_status.html' with event=event object=checklist view='ec_detail' edit='ec_edit' create='event_ec' review='ec_review' perm=perms.RIGS.review_eventchecklist %}
<br/>
{% endfor %}
<a href="{% url 'event_ec' event.pk %}" class="btn btn-info mt-2"><span class="fas fa-paperclip"></span> <span
class="hidden-xs">Create</span></a>
</div>
</div>

View File

@@ -1,7 +1,8 @@
{% load button from filters %}
{% if object.pk != None %}
<div class="btn-group">
<a href="{% url view object.pk %}" class="btn btn-primary"><span class="fas fa-eye"></span> <span class="hidden-xs"> View</span>
<a href="{% url edit object.pk %}" class="btn btn-warning"><span class="fas fa-edit"></span><span class="hidden-xs"> Edit</span></a>
{% button view object.pk 'view' %}
{% button edit object.pk 'edit' %}
</div>
{% if object.reviewed_by %}
<span class='badge badge-success py-2'>Reviewed by <a href='{% url 'profile_detail' object.reviewed_by.pk %}'>{{object.reviewed_by}}</a> at {{object.reviewed_at}}</span>

View File

@@ -202,4 +202,8 @@ def button(url, pk, type, clazz=None, icon=None, text=None):
clazz = "btn-info"
icon = "fa-copy"
text = "Duplicate"
elif type == 'view':
clazz = "btn-primary"
icon = "fa-eye"
text = "View"
return {'target': url, 'id': pk, 'class': clazz, 'icon': icon, 'text': text}