Templating improvements to RA/EC stuff

This commit is contained in:
2020-08-31 13:03:27 +01:00
parent 8842c2c3d9
commit 689124a891
17 changed files with 146 additions and 61 deletions

View File

@@ -125,3 +125,13 @@ class VenueAdmin(AssociateAdmin):
class OrganisationAdmin(AssociateAdmin):
list_display = ('id', 'name', 'phone', 'email', 'number_of_events')
merge_fields = ['name', 'phone', 'email', 'address', 'notes', 'union_account']
@admin.register(models.RiskAssessment)
class RiskAssessmentAdmin(VersionAdmin):
list_display = ('id', 'event', 'reviewed_at', 'reviewed_by')
@admin.register(models.EventChecklist)
class EventChecklistAdmin(VersionAdmin):
list_display = ('id', 'event', 'reviewed_at', 'reviewed_by')

View File

@@ -95,6 +95,13 @@ class EventChecklistEdit(generic.UpdateView):
template_name = 'event_checklist_form.html'
form_class = forms.EventChecklistForm
def get_success_url(self):
ec = self.get_object()
ec.reviewed_by = None
ec.reviewed_at = None
ec.save()
return reverse_lazy('ec_detail', kwargs={'pk': self.object.pk})
def get_context_data(self, **kwargs):
context = super(EventChecklistEdit, self).get_context_data(**kwargs)
pk = self.kwargs.get('pk')
@@ -145,6 +152,18 @@ class EventChecklistList(generic.ListView):
template_name = 'event_checklist_list.html'
class EventChecklistReview(generic.View):
def get(self, *args, **kwargs):
rpk = kwargs.get('pk')
ec = models.RiskAssessment.objects.get(pk=rpk)
with reversion.create_revision():
reversion.set_user(self.request.user)
ec.reviewed_by = self.request.user
ec.reviewed_at = timezone.now()
ec.save()
return HttpResponseRedirect(reverse_lazy('ec_list'))
class HSList(generic.ListView):
paginate_by = 20
model = models.Event

View File

@@ -20,6 +20,7 @@ class Command(BaseCommand):
keyholder_group = None
finance_group = None
hs_group = None
def handle(self, *args, **options):
from django.conf import settings
@@ -165,6 +166,7 @@ class Command(BaseCommand):
def setupGroups(self):
self.keyholder_group = Group.objects.create(name='Keyholders')
self.finance_group = Group.objects.create(name='Finance')
self.hs_group = Group.objects.create(name='H&S')
keyholderPerms = ["add_event", "change_event", "view_event",
"add_eventitem", "change_eventitem", "delete_eventitem",
@@ -174,9 +176,15 @@ class Command(BaseCommand):
"add_asset", "change_asset", "delete_asset",
"asset_finance", "view_asset", "view_supplier", "asset_finance",
"add_supplier", "view_cabletype", "change_cabletype",
"add_cabletype"]
"add_cabletype", "view_eventchecklist", "change_eventchecklist",
"add_eventchecklist", "view_riskassessment", "change_riskassessment",
"add_riskassessment", "add_eventchecklistcrew", "change_eventchecklistcrew",
"delete_eventchecklistcrew", "view_eventchecklistcrew", "add_eventchecklistvehicle",
"change_eventchecklistvehicle",
"delete_eventchecklistvehicle", "view_eventchecklistvehicle", ]
financePerms = keyholderPerms + ["add_invoice", "change_invoice", "view_invoice",
"add_payment", "change_payment", "delete_payment"]
hsPerms = keyHolderPerms + [ "review_riskassessment", "review_eventchecklist" ]
for permId in keyholderPerms:
self.keyholder_group.permissions.add(Permission.objects.get(codename=permId))
@@ -184,6 +192,9 @@ class Command(BaseCommand):
for permId in financePerms:
self.finance_group.permissions.add(Permission.objects.get(codename=permId))
for permId in hsPerms:
self.hs_group.permissions.add(Permission.objects.get(codename=permId))
def setupGenericProfiles(self):
names = ["Clara Oswin Oswald", "Rory Williams", "Amy Pond", "River Song", "Martha Jones", "Donna Noble",
"Jack Harkness", "Mickey Smith", "Rose Tyler"]
@@ -214,6 +225,14 @@ class Command(BaseCommand):
financeUser.set_password('finance')
financeUser.save()
hsUser = models.Profile.objects.create(username="hs", first_name="HS", last_name="User",
initials="HSU",
email="hsuser@example.com", is_active=True)
hsUser.groups.add(self.hs_group)
hsUser.groups.add(self.keyholder_group)
hsUser.set_password('hs')
hsUser.save()
keyholderUser = models.Profile.objects.create(username="keyholder", first_name="Keyholder", last_name="User",
initials="KU",
email="keyholderuser@example.com", is_active=True)

View File

@@ -0,0 +1,33 @@
# Generated by Django 3.1 on 2020-08-31 11:18
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('RIGS', '0053_auto_20200830_1940'),
]
operations = [
migrations.AlterModelOptions(
name='eventchecklist',
options={'ordering': ['event'], 'permissions': [('eventchecklist_review', 'Can review ECs')]},
),
migrations.AlterModelOptions(
name='riskassessment',
options={'ordering': ['event'], 'permissions': [('riskassessment_review', 'Can review RAs')]},
),
migrations.AddField(
model_name='eventchecklist',
name='reviewed_at',
field=models.DateTimeField(null=True),
),
migrations.AddField(
model_name='eventchecklist',
name='reviewed_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Reviewer'),
),
]

View File

@@ -1,6 +1,5 @@
import datetime
import hashlib
import datetime
import pytz
from django import forms
@@ -571,6 +570,14 @@ class Payment(models.Model):
return "%s: %d" % (self.get_method_display(), self.amount)
# Probably shouldn't be doing HTML at the python level but hey...they say not to do logic in templates! :P
def get_review_string(obj, review_link):
if obj.reviewed_by:
return "<span class='badge badge-success py-2'>Reviewed by <a href='{}'>{}</a> at {}</span>".format(reverse_lazy('profile_detail', kwargs={'pk': obj.reviewed_by.pk}), obj.reviewed_by, obj.reviewed_at.strftime("%d/%m/%Y %H:%M"))
else:
return "<a class='btn btn-success my-2' href='{}'>Mark Reviewed</a>".format(reverse_lazy(review_link, kwargs={'pk': obj.pk}))
@reversion.register
class RiskAssessment(models.Model, RevisionMixin):
event = models.OneToOneField('Event', on_delete=models.CASCADE)
@@ -615,6 +622,12 @@ class RiskAssessment(models.Model, RevisionMixin):
reviewed_by = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True,
verbose_name="Reviewer", on_delete=models.CASCADE)
class Meta:
ordering = ['event']
permissions = [
('riskassessment_review', 'Can review RAs')
]
def clean(self):
errdict = {}
for field in RiskAssessment._meta.fields:
@@ -624,6 +637,10 @@ class RiskAssessment(models.Model, RevisionMixin):
if errdict != {}: # If there was an error when validation
raise ValidationError(errdict)
@property
def review_string(self):
return get_review_string(self, 'ra_review')
@property
def activity_feed_string(self):
return str(self.event)
@@ -689,6 +706,16 @@ class EventChecklist(models.Model, RevisionMixin):
all_rcds_tested = models.BooleanField(blank=True,null=True,help_text="All circuit RCDs tested?<br><small>(using test button)</small>")
public_sockets_tested = models.BooleanField(blank=True,null=True,help_text="Public/Performer accessible circuits tested?<br><small>(using socket tester)</small>")
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)
class Meta:
ordering = ['event']
permissions = [
('eventchecklist_review', 'Can review ECs')
]
def clean(self):
errdict = {}
if self.earthing == None or self.pat == None:
@@ -707,6 +734,9 @@ class EventChecklist(models.Model, RevisionMixin):
if errdict != {}: # If there was an error when validation
raise ValidationError(errdict)
@property
def review_string(self):
return get_review_string(self, 'ec_review')
@property
def activity_feed_string(self):
@@ -720,7 +750,7 @@ class EventChecklist(models.Model, RevisionMixin):
@reversion.register
class EventChecklistVehicle(models.Model):
class EventChecklistVehicle(models.Model, RevisionMixin):
checklist = models.ForeignKey('EventChecklist', related_name='vehicles', blank=True, on_delete=models.CASCADE)
vehicle = models.CharField(max_length=255)
driver = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='vehicles', on_delete=models.CASCADE)
@@ -732,7 +762,7 @@ class EventChecklistVehicle(models.Model):
@reversion.register
class EventChecklistCrew(models.Model):
class EventChecklistCrew(models.Model, RevisionMixin):
checklist = models.ForeignKey('EventChecklist', related_name='crew', blank=True, on_delete=models.CASCADE)
crewmember = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='crewed', on_delete=models.CASCADE)
role = models.CharField(max_length=255)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -51,7 +51,7 @@
.input-group-text {
border-color: #121416;
}
.btn-secondary {
.btn-secondary, .btn-info {
color: white;
}
.page-item.disabled {

View File

@@ -225,6 +225,7 @@
<div class="col-12 text-right">
<a href="{% url 'ec_edit' object.pk %}" class="btn btn-warning my-3"><span class="fas fa-edit"></span> <span
class="hidden-xs">Edit</span></a>
{{ object.review_string|safe }}
</div>
<div class="col-12 text-right">
{% include 'partials/last_edited.html' with target="eventchecklist_history" %}

View File

@@ -46,11 +46,7 @@
{# Buttons #}
<td>
<a class="btn btn-primary" href="{% url 'ra_detail' object.pk %}">View</a>
{% 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 my-2" href="{% url 'ra_review' object.pk %}">Mark Reviewed</a>
{% endif %}
{{ object.review_string|safe }}
</td>
</tr>
{% empty %}

View File

@@ -79,7 +79,7 @@
{% endif %}
{% if event.is_rig and event.internal and perms.RIGS.view_event %}
<div class="col-sm-12 py-3">
{ include 'partials/auth_details.html' %}
{% include 'partials/auth_details.html' %}
<div>
{% endif %}
{% if not request.is_ajax and perms.RIGS.view_event %}

View File

@@ -17,35 +17,16 @@
<tbody>
{% for event in object_list %}
<tr id="event_row">
<th scope="row" id="event_number">{{ event.pk }} | {{ event.name }}</th>
<th scope="row" id="event_number"><a href="{% url 'event_detail' event.pk %}">{{ event }}</a></th>
<!--Dates-->
<td id="event_dates">
<div><strong>{{ event.start_date|date:"D d/m/Y" }}</strong></div>
<span><strong>{{ event.start_date|date:"D d/m/Y" }}</strong></span>
{% if event.end_date and event.end_date != event.start_date %}
<div><strong>{{ event.end_date|date:"D d/m/Y" }}</strong></div>
{% endif %}
</td>
<td>
{% if event.riskassessment %}
<a class="btn btn-primary" href="{% url 'ra_detail' event.riskassessment.pk %}">View</a>
{% if event.riskassessment.reviewed_by %}
Reviewed by <a href="{% url 'profile_detail' event.riskassessment.reviewed_by.pk %}">{{ event.riskassessment.reviewed_by }}</a> at {{ event.riskassessment.reviewed_at }}
{% else %}
<a class="btn btn-success my-2" href="{% url 'ra_review' event.riskassessment.pk %}">Mark Reviewed</a>
{% endif %}
{% else %}
<a href="{% url 'event_ra' event.pk %}" class="btn btn-success"><span class="fas fa-paperclip"></span> <span
class="hidden-xs">Create Risk Assessment</span></a>
{% endif %}
</td>
<td>
{% if event.eventchecklist %}
<a class="btn btn-primary" href="{% url 'ec_detail' event.eventchecklist.pk %}">View</a>
{% else %}
<a href="{% url 'event_ec' event.pk %}" class="btn btn-success"><span class="fas fa-paperclip"></span> <span
class="hidden-xs">Create Event Checklist</span></a>
<br><span><strong>{{ event.end_date|date:"D d/m/Y" }}</strong></span>
{% endif %}
</td>
<td>{% include 'partials/hs_status.html' with event=event object=event.riskassessment view='ra_detail' edit='ra_edit' create='event_ra' %}</td>
<td>{% include 'partials/hs_status.html' with event=event object=event.eventchecklist view='ec_detail' edit='ec_edit' create='event_ec' %}</td>
</tr>
{% empty %}
<tr class="bg-warning text-dark">

View File

@@ -6,23 +6,9 @@
<div class="card-header">Health &amp; Safety Details</div>
<div class="card-body">
<h5>Risk Assessment:</h5>
{% if event.riskassessment %}
<span class="fas fa-check text-success"></span> Completed <div class="btn-group"><a href="{% url 'ra_detail' event.riskassessment.pk %}" class="btn btn-primary"><span class="fas fa-eye"></span> <span
class="hidden-xs">View</span><a href="{% url 'ra_edit' event.riskassessment.pk %}" class="btn btn-warning"><span class="fas fa-edit"></span> <span
class="hidden-xs">Edit</span></a></div>
{% else %}
<a href="{% url 'event_ra' event.pk %}" class="btn btn-success"><span class="fas fa-paperclip"></span> <span
class="hidden-xs">Create Risk Assessment</span></a>
{% endif%}
{% 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>
{% if event.eventchecklist %}
<span class="fas fa-check text-success"></span> Completed <div class="btn-group"><a href="{% url 'ec_detail' event.eventchecklist.pk %}" class="btn btn-primary"><span class="fas fa-eye"></span> <span
class="hidden-xs">View</span><a href="{% url 'ec_edit' event.eventchecklist.pk %}" class="btn btn-warning"><span class="fas fa-edit"></span> <span
class="hidden-xs">Edit</span></a></div>
{% else %}
<a href="{% url 'event_ec' event.pk %}" class="btn btn-success"><span class="fas fa-paperclip"></span> <span
class="hidden-xs">Create Event Checklist</span></a>
{% endif%}
{% include 'partials/hs_status.html' with event=event object=event.eventchecklist view='ec_detail' edit='ec_edit' create='event_ec' %}
</div>
</div>

View File

@@ -0,0 +1,12 @@
{% load to_class_name from filters %}
{% if object.pk != None %}
{#<span class="badge badge-success my-3"><span class="fas fa-check"></span> Completed</span><br/>#}
<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>
</div>
{{ object.review_string|safe }}
{% else %}
<a href="{% url create event.pk %}" class="btn btn-info"><span class="fas fa-paperclip"></span> <span
class="hidden-xs">Create</span></a>
{% endif %}

View File

@@ -149,6 +149,7 @@
<div class="col-12 text-right">
<a href="{% url 'ra_edit' object.pk %}" class="btn btn-warning my-3"><span class="fas fa-edit"></span> <span
class="hidden-xs">Edit</span></a>
{{ object.review_string|safe }}
</div>
<div class="col-12 text-right">
{% include 'partials/last_edited.html' with target="riskassessment_history" %}

View File

@@ -84,11 +84,7 @@
{# Buttons #}
<td>
<a class="btn btn-primary" href="{% url 'ra_detail' object.pk %}">View</a>
{% 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 my-2" href="{% url 'ra_review' object.pk %}">Mark Reviewed</a>
{% endif %}
{{ object.review_string|safe }}
</td>
</tr>
{% empty %}

View File

@@ -81,7 +81,7 @@ urlpatterns = [
name='ra_edit'),
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'),
path('event/ra/<int:pk>/review/', permission_required_with_403('RIGS.review_riskassessment')(hs.EventRiskAssessmentReview.as_view()), name='ra_review'),
path('event/<int:pk>/checklist/', permission_required_with_403('RIGS.change_event')(hs.EventChecklistCreate.as_view()),
name='event_ec'),
@@ -91,6 +91,7 @@ urlpatterns = [
name='ec_edit'),
path('event/checklist/list', permission_required_with_403('RIGS.change_event')(hs.EventChecklistList.as_view()),
name='ec_list'),
path('event/checklist/<int:pk>/review/', permission_required_with_403('RIGS.review_eventchecklist')(hs.EventChecklistReview.as_view()), name='ec_review'),
# Finance
path('invoice/', permission_required_with_403('RIGS.view_invoice')(finance.InvoiceIndex.as_view()),