diff --git a/RIGS/forms.py b/RIGS/forms.py index 934ef76c..54604d5d 100644 --- a/RIGS/forms.py +++ b/RIGS/forms.py @@ -153,3 +153,15 @@ class InternalClientEventAuthorisationForm(BaseClientEventAuthorisationForm): class EventAuthorisationRequestForm(forms.Form): email = forms.EmailField(required=True, label='Authoriser Email') + + +class EventRiskAssessmentForm(forms.ModelForm): + forms.BooleanField.widget = forms.RadioSelect(choices=[ + (True, 'Yes'), + (False, 'No') + ], attrs={'class':'custom-control-input'}) + + class Meta: + model = models.RiskAssessment + fields = '__all__' + exclude = ['event', 'completed_by'] diff --git a/RIGS/migrations/0041_auto_20200528_1751.py b/RIGS/migrations/0041_auto_20200528_1751.py new file mode 100644 index 00000000..7b60d9f7 --- /dev/null +++ b/RIGS/migrations/0041_auto_20200528_1751.py @@ -0,0 +1,57 @@ +# Generated by Django 3.0.3 on 2020-05-28 16:51 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('RIGS', '0040_delete_rigsversion'), + ] + + operations = [ + migrations.RemoveField( + model_name='event', + name='risk_assessment_edit_url', + ), + migrations.CreateModel( + name='RiskAssessment', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created', models.DateTimeField(blank=True, null=True)), + ('last_edited', models.DateTimeField(blank=True, null=True)), + ('nonstandard_equipment', models.BooleanField(default=False)), + ('nonstandard_use', models.BooleanField(default=False)), + ('contractors', models.BooleanField(default=False)), + ('other_companies', models.BooleanField(default=False)), + ('crew_fatigue', models.BooleanField(default=False)), + ('general_notes', models.TextField(blank=True, null=True)), + ('big_power', models.BooleanField(default=False)), + ('generators', models.BooleanField(default=False)), + ('other_companies_power', models.BooleanField(default=False)), + ('nonstandard_equipment_power', models.BooleanField(default=False)), + ('multiple_electrical_environments', models.BooleanField(default=False)), + ('power_notes', models.TextField(blank=True, null=True)), + ('noise_monitoring', models.BooleanField(default=False)), + ('sound_notes', models.TextField(blank=True, null=True)), + ('known_venue', models.BooleanField(default=False)), + ('safe_loading', models.BooleanField(default=False)), + ('safe_storage', models.BooleanField(default=False)), + ('area_outside_of_control', models.BooleanField(default=False)), + ('barrier_required', models.BooleanField(default=False)), + ('nonstandard_emergency_procedure', models.BooleanField(default=False)), + ('special_structures', models.BooleanField(default=False)), + ('persons_responsible_structures', models.TextField(blank=True, null=True)), + ('suspended_structures', models.BooleanField(default=False)), + ('completed_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='completer', to=settings.AUTH_USER_MODEL, verbose_name='Completed By')), + ('power_mic', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='power_mic', to=settings.AUTH_USER_MODEL, verbose_name='Power MIC')), + ], + ), + migrations.AddField( + model_name='event', + name='risk_assessment', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='RIGS.RiskAssessment'), + ), + ] diff --git a/RIGS/models.py b/RIGS/models.py index 7cb34123..61d31fef 100644 --- a/RIGS/models.py +++ b/RIGS/models.py @@ -327,7 +327,7 @@ class Event(models.Model, RevisionMixin): auth_request_to = models.EmailField(null=True, blank=True) # Risk assessment info - risk_assessment_edit_url = models.CharField(verbose_name="risk assessment", max_length=255, blank=True, null=True) + risk_assessment = models.ForeignKey('RiskAssessment', null=True, blank=True, on_delete=models.CASCADE) # Calculated values """ @@ -570,3 +570,48 @@ class Payment(models.Model): def __str__(self): return "%s: %d" % (self.get_method_display(), self.amount) + + +@reversion.register +class RiskAssessment(models.Model): + completed_by = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='completer', blank=True, null=True, + verbose_name="Completed By", on_delete=models.CASCADE) + created = models.DateTimeField(blank=True, null=True) + last_edited = models.DateTimeField(blank=True, null=True) + + # General + nonstandard_equipment = models.BooleanField(default=False) + nonstandard_use = models.BooleanField(default=False) + contractors = models.BooleanField(default=False) + other_companies = models.BooleanField(default=False) + crew_fatigue = models.BooleanField(default=False) + general_notes = models.TextField(blank=True, null=True) + + # Power + big_power = models.BooleanField(default=False) + power_mic = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='power_mic', blank=True, null=True, + verbose_name="Power MIC", on_delete=models.CASCADE) + generators = models.BooleanField(default=False) + other_companies_power = models.BooleanField(default=False) + nonstandard_equipment_power = models.BooleanField(default=False) + multiple_electrical_environments = models.BooleanField(default=False) + power_notes = models.TextField(blank=True, null=True) + + # Sound + noise_monitoring = models.BooleanField(default=False) + sound_notes = models.TextField(blank=True, null=True) + + # Site + known_venue = models.BooleanField(default=False) + safe_loading = models.BooleanField(default=False) + safe_storage = models.BooleanField(default=False) + area_outside_of_control = models.BooleanField(default=False) + barrier_required = models.BooleanField(default=False) + nonstandard_emergency_procedure = models.BooleanField(default=False) + + # Structures + special_structures = models.BooleanField(default=False) + persons_responsible_structures = models.TextField(blank=True, null=True) + suspended_structures = models.BooleanField(default=False) + + # Blimey that was a lot of options diff --git a/RIGS/rigboard.py b/RIGS/rigboard.py index d4474e55..17162fc5 100644 --- a/RIGS/rigboard.py +++ b/RIGS/rigboard.py @@ -8,6 +8,7 @@ from django.core.mail import EmailMessage, EmailMultiAlternatives from django.views import generic from django.urls import reverse_lazy from django.shortcuts import get_object_or_404 +from django.http import HttpResponseRedirect from django.template import RequestContext from django.template.loader import get_template from django.conf import settings @@ -17,6 +18,7 @@ from django.http import HttpResponse from django.core.exceptions import SuspiciousOperation from django.db.models import Q from django.contrib import messages +from django.utils import timezone from django.utils.decorators import method_decorator from django.views.decorators.csrf import csrf_exempt from z3c.rml import rml2pdf @@ -82,25 +84,33 @@ class EventEmbed(EventDetail): template_name = 'event_embed.html' -class EventRA(generic.base.RedirectView): - permanent = False +class EventRADetail(generic.DetailView): + model = models.RiskAssessment + template_name = 'risk_assessment_detail.html' - def get_redirect_url(self, *args, **kwargs): - event = get_object_or_404(models.Event, pk=kwargs['pk']) - - if event.risk_assessment_edit_url: - return event.risk_assessment_edit_url - - params = { - 'entry.708610078': f'N{event.pk:05}', - 'entry.905899507': event.name, - 'entry.139491562': event.venue.name if event.venue else '', - 'entry.1689826056': event.start_date.strftime('%Y-%m-%d') + ( - (' - ' + event.end_date.strftime('%Y-%m-%d')) if event.end_date else ''), - 'entry.902421165': event.mic.name if event.mic else '' - } - return settings.RISK_ASSESSMENT_URL + "?" + urllib.parse.urlencode(params) + def get_object(self, queryset=None): + epk = self.kwargs.get(self.pk_url_kwarg) + event = models.Event.objects.get(pk=epk) + ra, created = models.RiskAssessment.objects.get_or_create(event=event) + ra.event = event + + if created: + ra.created = timezone.now() + + return ra + +class EventRAEdit(generic.UpdateView): + model = models.RiskAssessment + template_name = 'risk_assessment_form.html' + form_class = forms.EventRiskAssessmentForm + + def get_success_url(self): + ra = self.get_object() + ra.completed_by = self.request.user + ra.last_edited = timezone.now() + ra.save() + return super().get_success_url() class EventCreate(generic.CreateView): model = models.Event @@ -437,27 +447,3 @@ class EventAuthoriseRequestEmailPreview(generic.DetailView): }) context['to_name'] = self.request.GET.get('to_name', None) return context - - -@method_decorator(csrf_exempt, name='dispatch') -class LogRiskAssessment(generic.View): - http_method_names = ["post"] - - def post(self, request, **kwargs): - data = request.POST - shared_secret = data.get("secret") - edit_url = data.get("editUrl") - rig_number = data.get("rigNum") - if shared_secret is None or edit_url is None or rig_number is None: - return HttpResponse(status=422) - - if shared_secret != settings.RISK_ASSESSMENT_SECRET: - return HttpResponse(status=403) - - rig_number = int(re.sub("[^0-9]", "", rig_number)) - - event = get_object_or_404(models.Event, pk=rig_number) - event.risk_assessment_edit_url = edit_url - event.save() - - return HttpResponse(status=200) diff --git a/RIGS/templates/partials/yes_no_radio.html b/RIGS/templates/partials/yes_no_radio.html new file mode 100644 index 00000000..a4dacf70 --- /dev/null +++ b/RIGS/templates/partials/yes_no_radio.html @@ -0,0 +1,10 @@ + +