Start RA 'mark review' feature

This commit is contained in:
2020-08-05 20:51:31 +01:00
parent b88554a57f
commit 92377227e0
9 changed files with 45 additions and 85 deletions

View File

@@ -168,4 +168,4 @@ class EventRiskAssessmentForm(forms.ModelForm):
class Meta:
model = models.RiskAssessment
fields = '__all__'
exclude = []
exclude = ['reviewed_at', 'reviewed_by']

View File

@@ -102,7 +102,7 @@ class CalendarICS(ICalFeed):
return item.earliest_time
def item_end_datetime(self, item):
if type(item.latest_time) == datetime.date: # Ical end_datetime is non-inclusive, so add a day
if isinstance(item.latest_time, datetime.date): # Ical end_datetime is non-inclusive, so add a day
return item.latest_time + datetime.timedelta(days=1)
return item.latest_time

View File

@@ -67,6 +67,8 @@ class Profile(AbstractUser):
return self.name
# TODO move to versioning - currently get import errors with that
class RevisionMixin(object):
@property
def is_first_version(self):
@@ -100,7 +102,6 @@ class RevisionMixin(object):
return "V{0} | R{1}".format(version.pk, version.revision.pk)
class Person(models.Model, RevisionMixin):
name = models.CharField(max_length=50)
phone = models.CharField(max_length=15, blank=True, null=True)
@@ -616,9 +617,9 @@ class RiskAssessment(models.Model, RevisionMixin):
# Blimey that was a lot of options
# reviewed_at = models.DateTimeField()
# reviewed_by = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True,
# verbose_name="Reviewer", on_delete=models.CASCADE)
reviewed_at = models.DateTimeField(null=True)
reviewed_by = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True,
verbose_name="Reviewer", on_delete=models.CASCADE)
def clean(self):
errdict = {}

View File

@@ -6,19 +6,18 @@ import urllib.parse
from django.contrib.staticfiles.storage import staticfiles_storage
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
from django.urls import reverse
from django.urls import reverse_lazy
from django.core import signing
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 django.utils import timezone
@@ -426,63 +425,3 @@ class EventAuthoriseRequestEmailPreview(generic.DetailView):
})
context['to_name'] = self.request.GET.get('to_name', None)
return context
class EventRiskAssessmentCreate(generic.CreateView):
model = models.RiskAssessment
template_name = 'risk_assessment_form.html'
form_class = forms.EventRiskAssessmentForm
def get(self, *args, **kwargs):
epk = kwargs.get('pk')
event = models.Event.objects.get(pk=epk)
# Check if RA exists
ra = models.RiskAssessment.objects.filter(event=event).first()
if ra is not None:
return HttpResponseRedirect(reverse_lazy('ra_edit', kwargs={'pk': ra.pk}))
return super(EventRiskAssessmentCreate, self).get(self)
def get_form(self, **kwargs):
form = super(EventRiskAssessmentCreate, 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(EventRiskAssessmentCreate, 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('ra_detail', kwargs={'pk': self.object.pk})
class EventRiskAssessmentEdit(generic.UpdateView):
model = models.RiskAssessment
template_name = 'risk_assessment_form.html'
form_class = forms.EventRiskAssessmentForm
def get_success_url(self):
return reverse_lazy('ra_detail', kwargs={'pk': self.object.pk})
def get_context_data(self, **kwargs):
context = super(EventRiskAssessmentEdit, self).get_context_data(**kwargs)
context['edit'] = True
return context
class EventRiskAssessmentDetail(generic.DetailView):
model = models.RiskAssessment
template_name = 'risk_assessment_detail.html'
class EventRiskAssessmentList(generic.ListView):
paginate_by = 20
model = models.RiskAssessment
template_name = 'risk_assessment_table.html'

View File

@@ -53,6 +53,16 @@
{% if perms.RIGS.view_venue %}
<li class="nav-item"><a class="nav-link" href="{% url 'venue_list' %}">Venues</a></li>
{% endif %}
{% if perms.RIGS.view_riskassessment %}
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownHS" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
H&S
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdownHS">
<a class="dropdown-item" href="{% url 'ra_list' %}">Risk Assessment List</a>
</div>
</li>
{% endif %}
{% endif %}
{% endblock %}

View File

@@ -154,14 +154,14 @@
<div class="card-body" id="is_rig-selector">
<span data-toggle="tooltip"
title="Anything that involves TEC kit, crew, or otherwise us providing a service to anyone.">
<button type="button" class="btn btn-primary" data-is_rig="1">Rig</button>
<button type="button" class="btn btn-primary" data-is_rig="1" style="width: 10rem;">Rig</button>
</span>
<span data-toggle="tooltip"
title="Things that aren't service-based, like training, meetings and site visits.">
<button type="button" class="btn btn-info" data-is_rig="0">Non-Rig</button>
<button type="button" class="btn btn-info" data-is_rig="0" style="width: 10rem;">Non-Rig</button>
</span>
<span data-toggle="tooltip" title="Coming soon...">
<button type="button" class="btn btn-warning" data-is_rig="-1">Subhire</button>
<button type="button" class="btn btn-warning" data-is_rig="-1" style="width: 10rem;">Subhire</button>
</span>
</div>
</div>

View File

@@ -32,8 +32,8 @@
<dd class="col-2">
{{ object.crewfatigue|yesno|title }}
</dd>
<dt class="col-10">{{ object|help_text:'general_notes' }}</dt>
<dd class="col-2">
<dt class="col-12">{{ object|help_text:'general_notes' }}</dt>
<dd class="col-12">
{{ object.general_notes|default:'N/A'|linebreaks }}
</dd>
</dl>
@@ -67,8 +67,8 @@
<dd class="col-sm-6">
{{ object.multiple_electrical_environments|yesno|title }}
</dd>
<dt class="col-sm-6">{{ object|help_text:'power_notes' }}</dt>
<dd class="col-sm-6">
<dt class="col-12">{{ object|help_text:'power_notes' }}</dt>
<dd class="col-12">
{{ object.power_notes|default:'N/A'|linebreaks }}
</dd>
</dl>
@@ -82,8 +82,8 @@
<dd class="col-sm-6">
{{ object.noise_monitoring|yesno|title }}
</dd>
<dt class="col-sm-6">{{ object|help_text:'sound_notes' }}</dt>
<dd class="col-sm-6">
<dt class="col-12">{{ object|help_text:'sound_notes' }}</dt>
<dd class="col-12">
{{ object.sound_notes|default:'N/A'|linebreaks }}
</dd>
</dl>

View File

@@ -7,12 +7,12 @@
{% block content %}
<div class="row">
<div class="col-sm-12">
<div class="col-12">
<h2>Risk Assessment List</h2>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="col-12">
<div class="table-responsive">
<table class="table mb-0">
<thead>
@@ -44,6 +44,7 @@
<th scope="col">{{ object_list.0|verbose_name:'special_structures'|title }}</th>
<th scope="col">{{ object_list.0|verbose_name:'persons_responsible_structures'|title }}</th>
<th scope="col">{{ object_list.0|verbose_name:'suspended_structures'|title }}</th>
<th scope="col">Review</th>
{% endif %}
</tr>
</thead>
@@ -79,10 +80,17 @@
<td class="{% if object.special_structures%}bg-danger text-white{%endif%}">{{object.special_structures|yesno|title}}</td>
<td>{{ object.persons_responsible_structures|default:'N/A'|linebreaks }}</td>
<td class="{% if object.suspended_structures%}bg-danger text-white{%endif%}">{{object.suspended_structures|yesno|title}}</td>
<td>
{% if object.reviewed_by %}
Reviewed by <a href="{% url 'profile_detail' object.reviewed_by.pk %}">{{ object.reviewed_by }}</a> at {{ object.reviewed_at }}
{% else %}
<a class="btn btn-success" href="{% url 'ra_review' object.pk %}">Mark Reviewed</a>
{% endif %}
</td>
</tr>
{% empty %}
<tr class="bg-warning">
<td colspan="6">Not Found</td>
<td colspan="6">No risk assessments found</td>
</tr>
{% endfor %}
</tbody>

View File

@@ -5,7 +5,7 @@ from django.views.decorators.clickjacking import xframe_options_exempt
from django.views.generic import RedirectView
from PyRIGS.decorators import (api_key_required, has_oembed,
permission_required_with_403)
from RIGS import finance, ical, models, rigboard, views
from RIGS import finance, ical, models, rigboard, views, hs
from versioning import versioning
from django.views.decorators.cache import cache_page
@@ -89,17 +89,19 @@ urlpatterns = [
path('event/<int:pk>/history/',
permission_required_with_403('RIGS.view_event')(versioning.VersionHistory.as_view()),
name='event_history', kwargs={'model': models.Event}),
# Event H&S
path('event/<int:pk>/ra/', permission_required_with_403('RIGS.change_event')(rigboard.EventRiskAssessmentCreate.as_view()),
path('event/<int:pk>/ra/', permission_required_with_403('RIGS.change_event')(hs.EventRiskAssessmentCreate.as_view()),
name='event_ra'),
path('event/ra/<int:pk>/', permission_required_with_403('RIGS.change_event')(rigboard.EventRiskAssessmentDetail.as_view()),
path('event/ra/<int:pk>/', permission_required_with_403('RIGS.change_event')(hs.EventRiskAssessmentDetail.as_view()),
name='ra_detail'),
path('event/ra/<int:pk>/edit/', permission_required_with_403('RIGS.change_event')(rigboard.EventRiskAssessmentEdit.as_view()),
path('event/ra/<int:pk>/edit/', permission_required_with_403('RIGS.change_event')(hs.EventRiskAssessmentEdit.as_view()),
name='ra_edit'),
path('event/ra/<int:pk>/history/', permission_required_with_403('RIGS.change_event')(versioning.VersionHistory.as_view()),
name='ra_history', kwargs={'model': models.RiskAssessment}),
path('event/ra/list', permission_required_with_403('RIGS.change_event')(rigboard.EventRiskAssessmentList.as_view()),
path('event/ra/list', permission_required_with_403('RIGS.change_event')(hs.EventRiskAssessmentList.as_view()),
name='ra_list'),
path('event/ra/<int:pk>/review/', permission_required_with_403('RIGS.change_event')(hs.EventRiskAssessmentReview.as_view()), name='ra_review'),
# Finance
path('invoice/', permission_required_with_403('RIGS.view_invoice')(finance.InvoiceIndex.as_view()),