diff --git a/RIGS/forms.py b/RIGS/forms.py index 0b4b14de..c97e937a 100644 --- a/RIGS/forms.py +++ b/RIGS/forms.py @@ -169,3 +169,9 @@ class EventRiskAssessmentForm(forms.ModelForm): model = models.RiskAssessment fields = '__all__' exclude = ['reviewed_at', 'reviewed_by'] + + +class EventChecklistForm(forms.ModelForm): + class Meta: + model = models.EventChecklist + fields = '__all__' diff --git a/RIGS/hs.py b/RIGS/hs.py index 9074e50c..9e9752ee 100644 --- a/RIGS/hs.py +++ b/RIGS/hs.py @@ -83,3 +83,55 @@ class EventRiskAssessmentReview(generic.View): ra.reviewed_at = timezone.now() ra.save() return HttpResponseRedirect(reverse_lazy('ra_list')) + + +class EventChecklistDetail(generic.DetailView): + model = models.EventChecklist + template_name = 'event_checklist_detail.html' + +class EventChecklistEdit(generic.UpdateView): + model = models.EventChecklist + template_name = 'event_checklist_form.html' + form_class = forms.EventChecklistForm + + def get_context_data(self, **kwargs): + context = super(EventChecklistEdit, self).get_context_data(**kwargs) + pk = self.kwargs.get('pk') + ec = models.EventChecklist.objects.get(pk=pk) + context['event'] = ec.event + context['edit'] = True + return context + +class EventChecklistCreate(generic.CreateView): + model = models.EventChecklist + template_name = 'event_checklist_form.html' + form_class = forms.EventChecklistForm + + def get(self, *args, **kwargs): + epk = kwargs.get('pk') + event = models.Event.objects.get(pk=epk) + + # Check if RA exists + ra = models.EventChecklist.objects.filter(event=event).first() + + if ra is not None: + return HttpResponseRedirect(reverse_lazy('ec_edit', kwargs={'pk': ra.pk})) + + return super(EventChecklistCreate, self).get(self) + + def get_form(self, **kwargs): + form = super(EventChecklistCreate, self).get_form(**kwargs) + epk = self.kwargs.get('pk') + event = models.Event.objects.get(pk=epk) + form.instance.event = event + return form + + def get_context_data(self, **kwargs): + context = super(EventChecklistCreate, self).get_context_data(**kwargs) + epk = self.kwargs.get('pk') + event = models.Event.objects.get(pk=epk) + context['event'] = event + return context + + def get_success_url(self): + return reverse_lazy('ec_detail', kwargs={'pk': self.object.pk}) diff --git a/RIGS/migrations/0044_eventchecklist.py b/RIGS/migrations/0044_eventchecklist.py new file mode 100644 index 00000000..f16ed9b3 --- /dev/null +++ b/RIGS/migrations/0044_eventchecklist.py @@ -0,0 +1,38 @@ +# Generated by Django 3.0.7 on 2020-08-14 15:28 + +import RIGS.models +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('RIGS', '0043_auto_20200805_1606'), + ] + + operations = [ + migrations.CreateModel( + name='EventChecklist', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('vehicles', models.TextField(help_text='List vehicles and their drivers')), + ('safe_parking', models.BooleanField(help_text='Vehicles parked safely?(does not obstruct venue access)')), + ('safe_packing', models.BooleanField(help_text='Equipment packed away safely?(including flightcases)')), + ('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?(strobe, smoke, power etc.)')), + ('ear_plugs', models.BooleanField(help_text='Ear plugs issued to crew where needed?')), + ('hs_location', models.TextField(help_text='Location of Safety Bag/Box')), + ('extinguishers_location', models.TextField(help_text='Location of fire extinguishers')), + ('rcds', models.BooleanField(help_text='RCDs installed where needed and tested?')), + ('supply_test', models.BooleanField(help_text='Electrical supplies tested?(using socket tester)')), + ('earthing', models.BooleanField(help_text='Equipment appropriately earthed?(truss, stage, etc)')), + ('pat', models.BooleanField(help_text='All equipment in PAT period?')), + ('event', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='RIGS.Event')), + ('power_mic', models.ForeignKey(blank=True, help_text='Who is the Power MIC?', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='checklist', to=settings.AUTH_USER_MODEL, verbose_name='Power MIC')), + ], + bases=(models.Model, RIGS.models.RevisionMixin), + ), + ] diff --git a/RIGS/models.py b/RIGS/models.py index f0ffe0be..edef1cca 100644 --- a/RIGS/models.py +++ b/RIGS/models.py @@ -639,3 +639,41 @@ class RiskAssessment(models.Model, RevisionMixin): def __str__(self): return "%i - %s" % (self.pk, self.event) + +@reversion.register +class EventChecklist(models.Model, RevisionMixin): + event = models.OneToOneField('Event', on_delete=models.CASCADE) + + # General + power_mic = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='checklist', blank=True, null=True, + verbose_name="Power MIC", on_delete=models.CASCADE, help_text="Who is the Power MIC?") + # TODO Tabular format + vehicles = models.TextField(help_text="List vehicles and their drivers") + + # Safety Checks + safe_parking = models.BooleanField(help_text="Vehicles parked safely?
(does not obstruct venue access)") + safe_packing = models.BooleanField(help_text="Equipment packed away safely?
(including flightcases)") + 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?
(strobe, smoke, power etc.)") + 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") + + # Crew Record TODO + + # Small Electrical Checks + rcds = models.BooleanField(help_text="RCDs installed where needed and tested?") + supply_test = models.BooleanField(help_text="Electrical supplies tested?
(using socket tester)") + earthing = models.BooleanField(help_text="Equipment appropriately earthed?
(truss, stage, etc)") + pat = models.BooleanField(help_text="All equipment in PAT period?") + + @property + def activity_feed_string(self): + return str(self.event) + + def get_absolute_url(self): + return reverse_lazy('ec_detail', kwargs={'pk': self.pk}) + + def __str__(self): + return "%i - %s" % (self.pk, self.event) diff --git a/RIGS/templates/event_checklist_detail.html b/RIGS/templates/event_checklist_detail.html new file mode 100644 index 00000000..9888a68c --- /dev/null +++ b/RIGS/templates/event_checklist_detail.html @@ -0,0 +1,156 @@ +{% extends request.is_ajax|yesno:"base_ajax.html,base_rigs.html" %} +{% block title %}Risk Assessment for Event N{{ object.event.pk|stringformat:"05d" }} {{ object.event.name }}{% endblock %} +{% load help_text from filters %} + +{% block content %} +
+
+

Event Checklist for Event N{{ object.event.pk|stringformat:"05d" }} {{ object.event.name }}

+
+
+ +
+
+
+
General
+
+
+
{{ object|help_text:'nonstandard_equipment' }}
+
+ {{ object.nonstandard_equipment|yesno|title }} +
+
{{ object|help_text:'nonstandard_use'|safe }}
+
+ {{ object.nonstandard_use|yesno|title }} +
+
{{ object|help_text:'contractors' }}
+
+ {{ object.contractors|yesno|title }} +
+
{{ object|help_text:'other_companies' }}
+
+ {{ object.othercompanies|yesno|title }} +
+
{{ object|help_text:'crew_fatigue' }}
+
+ {{ object.crewfatigue|yesno|title }} +
+
{{ object|help_text:'general_notes' }}
+
+ {{ object.general_notes|default:'N/A'|linebreaks }} +
+
+
+
+
+
Power
+
+
+
{{ object|help_text:'big_power' }}
+
+ {{ object.big_power|yesno|title }} +
+
{{ object|help_text:'power_mic' }}
+
+ {{ object.power_mic.name|default:'None' }} +
+
{{ object|help_text:'generators' }}
+
+ {{ object.generators|yesno|title }} +
+
{{ object|help_text:'other_companies_power' }}
+
+ {{ object.other_companies_power|yesno|title }} +
+
{{ object|help_text:'nonstandard_equipment_power' }}
+
+ {{ object.nonstandard_equipment_power|yesno|title }} +
+
{{ object|help_text:'multiple_electrical_environments' }}
+
+ {{ object.multiple_electrical_environments|yesno|title }} +
+
{{ object|help_text:'power_notes' }}
+
+ {{ object.power_notes|default:'N/A'|linebreaks }} +
+
+
+
+
+
Sound
+
+
+
{{ object|help_text:'noise_monitoring' }}
+
+ {{ object.noise_monitoring|yesno|title }} +
+
{{ object|help_text:'sound_notes' }}
+
+ {{ object.sound_notes|default:'N/A'|linebreaks }} +
+
+
+
+
+
Site Details
+
+
+
{{ object|help_text:'known_venue' }}
+
+ {{ object.known_venue|yesno|title }} +
+
{{ object|help_text:'safe_loading'|safe }}
+
+ {{ object.safe_loading.name|yesno|title }} +
+
{{ object|help_text:'safe_storage' }}
+
+ {{ object.safe_storage|yesno|title }} +
+
{{ object|help_text:'area_outside_of_control' }}
+
+ {{ object.area_outside_of_control|yesno|title }} +
+
{{ object|help_text:'barrier_required' }}
+
+ {{ object.barrier_required|yesno|title }} +
+
{{ object|help_text:'nonstandard_emergency_procedure' }}
+
+ {{ object.nonstandard_emergency_procedure|yesno|title }} +
+
+
+
+
+
Structures
+
+
+
{{ object|help_text:'special_structures' }}
+
+ {{ object.special_structures|yesno|title }} +
+
{{ object|help_text:'persons_responsible_structures' }}
+
+ {{ object.persons_responsible_structures.name|default:'N/A'|linebreaks }} +
+
{{ object|help_text:'suspended_structures' }}
+
+ {{ object.suspended_structures|yesno|title }} +
+
+
+
+
+
+
+ +
+
+ {% include 'partials/last_edited.html' with target="ec_history" %} +
+ +{% endblock %} diff --git a/RIGS/templates/event_checklist_form.html b/RIGS/templates/event_checklist_form.html new file mode 100644 index 00000000..0215b42a --- /dev/null +++ b/RIGS/templates/event_checklist_form.html @@ -0,0 +1,187 @@ +{% extends request.is_ajax|yesno:'base_ajax.html,base_rigs.html' %} +{% load widget_tweaks %} +{% load static %} +{% load help_text from filters %} + +{% block title %}{% if edit %}Edit{% else %}Create{% endif %} Event Checklist for Event N{{ event.pk|stringformat:"05d" }}{% endblock %} + +{% block css %} + {{ block.super }} + + +{% endblock %} + +{% block preload_js %} + {{ block.super }} + + +{% endblock %} + +{% block js %} + {{ block.super }} + + + + + + +{% endblock %} + +{% block content %} +
+

{% if edit %}Edit{% else %}Create{% endif %} Event Checklist for Event N{{ event.pk|stringformat:"05d" }}

+ {% include 'form_errors.html' %} + {% if edit %} +
+ {% else %} + + {% endif %} + + {% csrf_token %} +
+
+
+
Event Information
+
+
+
Event Date
+
{{form.event.start_date}}
+
Event Name
+
{{form.event.name}}
+
Client
+
{{form.event.person}}
+
Venue
+
{{form.event.Venue}}
+
+ +
+ +
+ + + + + + + + + + {% for i in '012'|make_list %} + + + + + {% endfor %} + +
VehicleDriver
+ +
+
+ +
+
+
+
+
+
+
+
+
Safety Checks
+
+ {% include 'partials/checklist_checkbox.html' with formitem=form.safe_parking %} + {% include 'partials/checklist_checkbox.html' with formitem=form.safe_packing %} + {% include 'partials/checklist_checkbox.html' with formitem=form.exits %} + {% include 'partials/checklist_checkbox.html' with formitem=form.trip_hazard %} + {% include 'partials/checklist_checkbox.html' with formitem=form.warning_signs %} + {% include 'partials/checklist_checkbox.html' with formitem=form.ear_plugs %} + + {% render_field form.hs_location class+="form-control" %} + + {% render_field form.extinguishers_location class+="form-control" %} +
+
+
+
+
+
+
+
Crew Record
+
+ + + + + + + + + + + {% for i in '012'|make_list %} + + + + + + + + {% endfor %} + +
CrewmemberStart TimeRoleEnd Time
+ +
+
+ +
+
+
+
+
+
+
+
+
Electrical Checks for ‘Small’ TEC Events <6kVA (aprox. 26A)
+
+ {% include 'partials/checklist_checkbox.html' with formitem=form.rcds %} + {% include 'partials/checklist_checkbox.html' with formitem=form.supply_test %} + {% include 'partials/checklist_checkbox.html' with formitem=form.earthing %} + {% include 'partials/checklist_checkbox.html' with formitem=form.pat %} +
+
+
+
+
+
+
+
Electrical Checks for ‘Medium’ TEC Events
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+{% endblock %} diff --git a/RIGS/templates/partials/checklist_checkbox.html b/RIGS/templates/partials/checklist_checkbox.html new file mode 100644 index 00000000..ac8dd80e --- /dev/null +++ b/RIGS/templates/partials/checklist_checkbox.html @@ -0,0 +1,6 @@ +{% load widget_tweaks %} +{% load help_text from filters %} +
+ {% render_field formitem|attr:'required=true' class+="form-check-input" %} + +
diff --git a/RIGS/templates/partials/hs_details.html b/RIGS/templates/partials/hs_details.html index 332b2f63..b423f77c 100644 --- a/RIGS/templates/partials/hs_details.html +++ b/RIGS/templates/partials/hs_details.html @@ -16,6 +16,13 @@ {% endif%}
Event Checklist:
- Coming Soon + {% if event.eventchecklist %} + Completed
+ {% else %} + + {% endif%} diff --git a/RIGS/urls.py b/RIGS/urls.py index a85fd2d8..b89cf771 100644 --- a/RIGS/urls.py +++ b/RIGS/urls.py @@ -103,6 +103,15 @@ urlpatterns = [ name='ra_list'), path('event/ra//review/', permission_required_with_403('RIGS.change_event')(hs.EventRiskAssessmentReview.as_view()), name='ra_review'), + path('event//checklist/', permission_required_with_403('RIGS.change_event')(hs.EventChecklistCreate.as_view()), + name='event_ec'), + path('event/checklist//', permission_required_with_403('RIGS.change_event')(hs.EventChecklistDetail.as_view()), + name='ec_detail'), + path('event/checklist//edit/', permission_required_with_403('RIGS.change_event')(hs.EventChecklistEdit.as_view()), + name='ec_edit'), + path('event/checklist//history/', permission_required_with_403('RIGS.change_event')(versioning.VersionHistory.as_view()), + name='ec_history', kwargs={'model': models.EventChecklist}), + # Finance path('invoice/', permission_required_with_403('RIGS.view_invoice')(finance.InvoiceIndex.as_view()), name='invoice_list'),