Make venue/date editable on EC

For multi venue, multi day events

Defaults to date and venue set on the event. Also made power MIC default to that set in RA
This commit is contained in:
2020-10-10 13:41:36 +01:00
parent 026e2a0b03
commit 49a2bc83ab
8 changed files with 314 additions and 246 deletions

View File

@@ -187,6 +187,7 @@ class EventRiskAssessmentForm(forms.ModelForm):
class EventChecklistForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(EventChecklistForm, self).__init__(*args, **kwargs)
self.fields['date'].widget.format = '%Y-%m-%d'
for name, field in self.fields.items():
if field.__class__ == forms.NullBooleanField:
# Only display yes/no to user, the 'none' is only ever set in the background
@@ -194,6 +195,11 @@ class EventChecklistForm(forms.ModelForm):
# Parsed from incoming form data by clean, then saved into models when the form is saved
items = {}
related_models = {
'venue': models.Venue,
'power_mic': models.Profile,
}
# Two possible formats
def parsedatetime(self, date_string):
try:

View File

@@ -127,6 +127,12 @@ class EventChecklistEdit(generic.UpdateView):
context['event'] = ec.event
context['edit'] = True
context['page_title'] = 'Edit Event Checklist for Event {}'.format(ec.event.display_id)
form = context['form']
# Get some other objects to include in the form. Used when there are errors but also nice and quick.
for field, model in form.related_models.items():
value = form[field].value()
if value is not None and value != '':
context[field] = model.objects.get(pk=value)
return context

View File

@@ -0,0 +1,27 @@
# Generated by Django 3.1.2 on 2020-10-10 12:20
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('RIGS', '0042_riskassessment_supervisor_consulted'),
]
operations = [
migrations.AddField(
model_name='eventchecklist',
name='date',
field=models.DateField(default=django.utils.timezone.now),
preserve_default=False,
),
migrations.AddField(
model_name='eventchecklist',
name='venue',
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='RIGS.venue'),
preserve_default=False,
),
]

View File

@@ -690,6 +690,7 @@ class RiskAssessment(models.Model, RevisionMixin):
'special_structures': False,
'suspended_structures': False,
}
#inverted_fields = filter(lambda key,value: value, expected_values.items())
class Meta:
ordering = ['event']
@@ -719,6 +720,8 @@ class EventChecklist(models.Model, RevisionMixin):
# General
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?")
venue = models.ForeignKey('Venue', on_delete=models.CASCADE)
date = models.DateField()
# Safety Checks
safe_parking = models.BooleanField(blank=True, null=True, help_text="Vehicles parked safely?<br><small>(does not obstruct venue access)</small>")

View File

@@ -5,238 +5,248 @@
{% load button from filters %}
{% block content %}
<div class="row py-3">
<div class="col-12">
<div class="row">
<div class="col-12 text-right my-3">
{% button 'edit' url='ec_edit' pk=object.pk %}
{% button 'view' url='event_detail' pk=object.pk text="Event" %}
{% include 'partials/review_status.html' with perm=perms.RIGS.review_eventchecklist review='ec_review' %}
</div>
</div>
<div class="row">
<div class="col-md-6 col-sm-12">
<div class="card card-default mb-3">
<div class="card-header">General</div>
<div class="card-body">
<dl class="row">
<dt class="col-6">{{ object|help_text:'power_mic' }}</dt>
<dd class="col-6">
<a href="{% url 'profile_detail' object.power_mic.pk %}">{{ object.power_mic.name }}</a>
</dd>
</dl>
<p>List vehicles and their drivers</p>
<ul>
{% for i in object.vehicles.all %}
<li>{{i}}</li>
{% endfor %}
</ul>
</div>
</div>
</div>
<div class="col-md-6 col-sm-12">
<div class="card card-default mb-3">
<div class="card-header">Safety Checks</div>
<div class="card-body">
<dl class="row">
<dt class="col-10">{{ object|help_text:'safe_parking'|safe }}</dt>
<dd class="col-2">
{{ object.safe_parking|yesnoi }}
</dd>
<dt class="col-10">{{ object|help_text:'safe_packing'|safe }}</dt>
<dd class="col-2">
{{ object.safe_packing|yesnoi }}
</dd>
<dt class="col-10">{{ object|help_text:'exits'|safe }}</dt>
<dd class="col-2">
{{ object.exits|yesnoi }}
</dd>
<dt class="col-10">{{ object|help_text:'trip_hazard'|safe }}</dt>
<dd class="col-2">
{{ object.trip_hazard|yesnoi }}
</dd>
<dt class="col-10">{{ object|help_text:'warning_signs'|safe }}</dt>
<dd class="col-2">
{{ object.warning_signs|yesnoi }}
</dd>
<dt class="col-10">{{ object|help_text:'ear_plugs'|safe }}</dt>
<dd class="col-2">
{{ object.ear_plugs|yesnoi }}
</dd>
</dl>
</div>
</div>
</div>
</div>
<div class="card card-default mb-3">
<div class="card-header">Crew Record</div>
<table class="table">
<thead>
<tr>
<th scope="col">Crewmember</th>
<th scope="col">Start Time</th>
<th scope="col">Role</th>
<th scope="col">End Time</th>
</tr>
</thead>
<tbody id="crewmemberst">
{% for crew in object.crew.all %}
<tr>
<td>{{crew.crewmember}}</td>
<td>{{crew.start}}</td>
<td>{{crew.role}}</td>
<td>{{crew.end}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="card card-default mb-3">
<div class="card-header">Power {% if object.event_size == 2 %}
<span class="badge badge-danger p-2 my-3">Large Event</span>
{% elif object.event_size == 1 %}
<span class="badge badge-warning p-2 my-3">Medium Event</span>
{%else%}<span class="badge badge-success p-2 my-3">Small Event</span>
{%endif%}</div>
{% if object.event_size != 2 %}
<div class="card-body">
{% if object.event_size == 1 %}
<dl class="row">
<dt class="col-10">{{ object|help_text:'source_rcd'|safe }}</dt>
<dd class="col-2">
{{ object.source_rcd|yesnoi }}
</dd>
<dt class="col-10">{{ object|help_text:'labelling'|safe }}</dt>
<dd class="col-2">
{{ object.labelling|yesnoi }}
</dd>
<dt class="col-10">{{ object|help_text:'earthing'|safe }}</dt>
<dd class="col-2">
{{ object.earthing|yesnoi }}
</dd>
<dt class="col-10">{{ object|help_text:'pat'|safe }}</dt>
<dd class="col-2">
{{ object.pat|yesnoi }}
</dd>
</dl>
<hr>
<p>Tests at first distro</p>
<table class="table table-bordered">
<thead>
<tr>
<th scope="col" class="text-center">Test</th>
<th scope="col" colspan="3" class="text-center">Value</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row" rowspan="2">Voltage<br><small>(cube meter)</small></th>
<th>{{ object|help_text:'fd_voltage_l1' }}</th>
<th>{{ object|help_text:'fd_voltage_l2' }}</th>
<th>{{ object|help_text:'fd_voltage_l3' }}</th>
</tr>
<tr>
<td>{{ object.fd_voltage_l1 }}</td>
<td>{{ object.fd_voltage_l2 }}</td>
<td>{{ object.fd_voltage_l3 }}</td>
</tr>
<tr>
<th scope="row">{{ object|help_text:'fd_phase_rotation'|safe }}</th>
<td colspan="3">{{ object.fd_phase_rotation|yesnoi }}</td>
</tr>
<tr>
<th scope="row">{{ object|help_text:'fd_earth_fault'|safe}}</th>
<td colspan="3">{{ object.fd_earth_fault }}</td>
</tr>
<tr>
<th scope="row">{{ object|help_text:'fd_pssc'}}</th>
<td colspan="3">{{ object.fd_pssc }}</td>
</tr>
</tbody>
</table>
<hr>
<p>Tests at 'Worst Case' points (at least 1 point required)</p>
<table class="table table-bordered">
<thead>
<tr>
<th scope="col" class="text-center">Test</th>
<th scope="col" class="text-center">Point 1</th>
<th scope="col" class="text-center">Point 2</th>
<th scope="col" class="text-center">Point 3</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">{{ object|help_text:'w1_description'|safe}}</th>
<td>{{ object.w1_description }}</td>
<td>{{ object.w2_description|default:'' }}</td>
<td>{{ object.w3_description|default:'' }}</td>
</tr>
<tr>
<th scope="row">{{ object|help_text:'w1_polarity'|safe}}</th>
<td>{{ object.w1_polarity|yesnoi }}</td>
<td>{{ object.w2_polarity|default:''|yesnoi }}</td>
<td>{{ object.w3_polarity|default:''|yesnoi }}</td>
</tr>
<tr>
<th scope="row">{{ object|help_text:'w1_voltage'|safe}}</th>
<td>{{ object.w1_voltage }}</td>
<td>{{ object.w2_voltage|default:'' }}</td>
<td>{{ object.w3_voltage|default:'' }}</td>
</tr>
<tr>
<th scope="row">{{ object|help_text:'w1_earth_fault'|safe}}</th>
<td>{{ object.w1_earth_fault }}</td>
<td>{{ object.w2_earth_fault|default:'' }}</td>
<td>{{ object.w3_earth_fault|default:'' }}</td>
</tr>
</tbody>
</table>
<hr>
<dl class="row">
<dt class="col-10">{{ object|help_text:'all_rcds_tested'|safe }}</dt>
<dd class="col-2">
{{ object.all_rcds_tested|yesnoi }}
</dd>
<dt class="col-10">{{ object|help_text:'public_sockets_tested'|safe }}</dt>
<dd class="col-2">
{{ object.public_sockets_tested|yesnoi }}
</dd>
</dl>
<hr>
{% include 'partials/ec_power_info.html' %}
{% else %}
<dl class="row">
<dt class="col-10">{{ object|help_text:'rcds'|safe }}</dt>
<dd class="col-2">
{{ object.rcds|yesnoi }}
</dd>
<dt class="col-10">{{ object|help_text:'supply_test'|safe }}</dt>
<dd class="col-2">
{{ object.supply_test|yesnoi }}
</dd>
<dt class="col-10">{{ object|help_text:'earthing'|safe }}</dt>
<dd class="col-2">
{{ object.earthing|yesnoi }}
</dd>
<dt class="col-10">{{ object|help_text:'pat'|safe }}</dt>
<dd class="col-2">
{{ object.pat|yesnoi }}
</dd>
</dl>
<div class="row">
<div class="col-12 text-right my-3">
{% button 'edit' url='ec_edit' pk=object.pk %}
{% button 'view' url='event_detail' pk=object.pk text="Event" %}
{% include 'partials/review_status.html' with perm=perms.RIGS.review_eventchecklist review='ec_review' %}
</div>
</div>
<div class="row">
<div class="col-md-6 col-sm-12">
<div class="card mb-3">
<div class="card-header">General</div>
<div class="card-body">
<dl class="row">
<dt class="col-6">Date</dt>
<dd class="col-6">
{{ object.date }}
</dd>
<dt class="col-6">Venue</dt>
<dd class="col-6">
{% if object.venue %}
<a href="{% url 'venue_detail' object.venue.pk %}" class="modal-href">
{{ object.venue }}
</a>
{% endif %}
</div>
{% endif %}
</dd>
<dt class="col-6">{{ object|help_text:'power_mic' }}</dt>
<dd class="col-6">
<a href="{% url 'profile_detail' object.power_mic.pk %}">{{ object.power_mic.name }}</a>
</dd>
</dl>
<p>List vehicles and their drivers</p>
<ul>
{% for i in object.vehicles.all %}
<li>{{i}}</li>
{% endfor %}
</ul>
</div>
</div>
</div>
<div class="col-md-6 col-sm-12">
<div class="card mb-3">
<div class="card-header">Safety Checks</div>
<div class="card-body">
<dl class="row">
<dt class="col-10">{{ object|help_text:'safe_parking'|safe }}</dt>
<dd class="col-2">
{{ object.safe_parking|yesnoi }}
</dd>
<dt class="col-10">{{ object|help_text:'safe_packing'|safe }}</dt>
<dd class="col-2">
{{ object.safe_packing|yesnoi }}
</dd>
<dt class="col-10">{{ object|help_text:'exits'|safe }}</dt>
<dd class="col-2">
{{ object.exits|yesnoi }}
</dd>
<dt class="col-10">{{ object|help_text:'trip_hazard'|safe }}</dt>
<dd class="col-2">
{{ object.trip_hazard|yesnoi }}
</dd>
<dt class="col-10">{{ object|help_text:'warning_signs'|safe }}</dt>
<dd class="col-2">
{{ object.warning_signs|yesnoi }}
</dd>
<dt class="col-10">{{ object|help_text:'ear_plugs'|safe }}</dt>
<dd class="col-2">
{{ object.ear_plugs|yesnoi }}
</dd>
</dl>
</div>
</div>
<div class="col-12 text-right">
{% button 'edit' url='ec_edit' pk=object.pk %}
{% button 'view' url='event_detail' pk=object.pk text="Event" %}
{% include 'partials/review_status.html' with perm=perms.RIGS.review_eventchecklist review='ec_review' %}
</div>
<div class="col-12 text-right">
{% include 'partials/last_edited.html' with target="eventchecklist_history" %}
</div>
</div>
</div>
<div class="card mb-3">
<div class="card-header">Crew Record</div>
<div class="table-responsive">
<table class="table table-sm">
<thead>
<tr>
<th scope="col">Crewmember</th>
<th scope="col">Start Time</th>
<th scope="col">Role</th>
<th scope="col">End Time</th>
</tr>
</thead>
<tbody id="crewmemberst">
{% for crew in object.crew.all %}
<tr>
<td>{{crew.crewmember}}</td>
<td>{{crew.start}}</td>
<td>{{crew.role}}</td>
<td>{{crew.end}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<div class="card mb-3">
<div class="card-header">Power {% if object.event_size == 2 %}
<span class="badge badge-danger p-2 my-3">Large Event</span>
{% elif object.event_size == 1 %}
<span class="badge badge-warning p-2 my-3">Medium Event</span>
{%else%}<span class="badge badge-success p-2 my-3">Small Event</span>
{%endif%}</div>
{% if object.event_size != 2 %}
<div class="card-body">
{% if object.event_size == 1 %}
<dl class="row">
<dt class="col-10">{{ object|help_text:'source_rcd'|safe }}</dt>
<dd class="col-2">
{{ object.source_rcd|yesnoi }}
</dd>
<dt class="col-10">{{ object|help_text:'labelling'|safe }}</dt>
<dd class="col-2">
{{ object.labelling|yesnoi }}
</dd>
<dt class="col-10">{{ object|help_text:'earthing'|safe }}</dt>
<dd class="col-2">
{{ object.earthing|yesnoi }}
</dd>
<dt class="col-10">{{ object|help_text:'pat'|safe }}</dt>
<dd class="col-2">
{{ object.pat|yesnoi }}
</dd>
</dl>
<hr>
<p>Tests at first distro</p>
<table class="table table-bordered">
<thead>
<tr>
<th scope="col" class="text-center">Test</th>
<th scope="col" colspan="3" class="text-center">Value</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row" rowspan="2">Voltage<br><small>(cube meter)</small></th>
<th>{{ object|help_text:'fd_voltage_l1' }}</th>
<th>{{ object|help_text:'fd_voltage_l2' }}</th>
<th>{{ object|help_text:'fd_voltage_l3' }}</th>
</tr>
<tr>
<td>{{ object.fd_voltage_l1 }}</td>
<td>{{ object.fd_voltage_l2 }}</td>
<td>{{ object.fd_voltage_l3 }}</td>
</tr>
<tr>
<th scope="row">{{ object|help_text:'fd_phase_rotation'|safe }}</th>
<td colspan="3">{{ object.fd_phase_rotation|yesnoi }}</td>
</tr>
<tr>
<th scope="row">{{ object|help_text:'fd_earth_fault'|safe}}</th>
<td colspan="3">{{ object.fd_earth_fault }}</td>
</tr>
<tr>
<th scope="row">{{ object|help_text:'fd_pssc'}}</th>
<td colspan="3">{{ object.fd_pssc }}</td>
</tr>
</tbody>
</table>
<hr>
<p>Tests at 'Worst Case' points (at least 1 point required)</p>
<table class="table table-bordered">
<thead>
<tr>
<th scope="col" class="text-center">Test</th>
<th scope="col" class="text-center">Point 1</th>
<th scope="col" class="text-center">Point 2</th>
<th scope="col" class="text-center">Point 3</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">{{ object|help_text:'w1_description'|safe}}</th>
<td>{{ object.w1_description }}</td>
<td>{{ object.w2_description|default:'' }}</td>
<td>{{ object.w3_description|default:'' }}</td>
</tr>
<tr>
<th scope="row">{{ object|help_text:'w1_polarity'|safe}}</th>
<td>{{ object.w1_polarity|yesnoi }}</td>
<td>{{ object.w2_polarity|default:''|yesnoi }}</td>
<td>{{ object.w3_polarity|default:''|yesnoi }}</td>
</tr>
<tr>
<th scope="row">{{ object|help_text:'w1_voltage'|safe}}</th>
<td>{{ object.w1_voltage }}</td>
<td>{{ object.w2_voltage|default:'' }}</td>
<td>{{ object.w3_voltage|default:'' }}</td>
</tr>
<tr>
<th scope="row">{{ object|help_text:'w1_earth_fault'|safe}}</th>
<td>{{ object.w1_earth_fault }}</td>
<td>{{ object.w2_earth_fault|default:'' }}</td>
<td>{{ object.w3_earth_fault|default:'' }}</td>
</tr>
</tbody>
</table>
<hr>
<dl class="row">
<dt class="col-10">{{ object|help_text:'all_rcds_tested'|safe }}</dt>
<dd class="col-2">
{{ object.all_rcds_tested|yesnoi }}
</dd>
<dt class="col-10">{{ object|help_text:'public_sockets_tested'|safe }}</dt>
<dd class="col-2">
{{ object.public_sockets_tested|yesnoi }}
</dd>
</dl>
<hr>
{% include 'partials/ec_power_info.html' %}
{% else %}
<dl class="row">
<dt class="col-10">{{ object|help_text:'rcds'|safe }}</dt>
<dd class="col-2">
{{ object.rcds|yesnoi }}
</dd>
<dt class="col-10">{{ object|help_text:'supply_test'|safe }}</dt>
<dd class="col-2">
{{ object.supply_test|yesnoi }}
</dd>
<dt class="col-10">{{ object|help_text:'earthing'|safe }}</dt>
<dd class="col-2">
{{ object.earthing|yesnoi }}
</dd>
<dt class="col-10">{{ object|help_text:'pat'|safe }}</dt>
<dd class="col-2">
{{ object.pat|yesnoi }}
</dd>
</dl>
{% endif %}
</div>
{% endif %}
</div>
</div>
<div class="col-12 text-right">
{% button 'edit' url='ec_edit' pk=object.pk %}
{% button 'view' url='event_detail' pk=object.pk text="Event" %}
{% include 'partials/review_status.html' with perm=perms.RIGS.review_eventchecklist review='ec_review' %}
</div>
<div class="col-12 text-right">
{% include 'partials/last_edited.html' with target="eventchecklist_history" %}
</div>
{% endblock %}

View File

@@ -114,19 +114,37 @@
<dd class="col-8">{{ event.name }}</dd>
<dt class="col-4">Client</dt>
<dd class="col-8">{{ event.person }}</dd>
<dt class="col-4">Venue</dt>
<dd class="col-8">{{ event.venue }}</dd>
</dl>
<div class="row">
<label for="{{ form.power_mic.id_for_label }}"
class="col-4 control-label font-weight-bold">{{ form.power_mic.help_text }}</label>
<div class="col-8 col-md-4">
<select id="{{ form.power_mic.id_for_label }}" name="{{ form.power_mic.name }}" class="form-control selectpicker" data-live-search="true" data-sourceurl="{% url 'api_secure' model='profile' %}?fields=first_name,last_name,initials" required="true">
{% if object.power_mic %}
<option value="{{object.power_mic.pk}}" selected="selected">{{ object.power_mic.name }}</option>
{% endif %}
</select>
</div>
<div class="form-group form-row">
<label for="{{ form.date.id_for_label }}"
class="col-4 control-label">{{ form.date.label }}</label>
{% if not form.date.value %}
{% render_field form.date class+="form-control col-8" value=event.start_date %}
{% else %}
{% render_field form.date class+="form-control col-8" %}
{% endif %}
</div>
<div class="form-group form-row">
<label for="{{ form.venue.id_for_label }}"
class="col-4 control-label">{{ form.venue.label }}</label>
<select id="{{ form.venue.id_for_label }}" name="{{ form.venue.name }}" class="form-control selectpicker col-8" data-live-search="true" data-sourceurl="{% url 'api_secure' model='venue' %}">
{% if venue %}
<option value="{{venue.pk}}" selected="selected">{{ venue.name }}</option>
{% elif event.venue %}
<option value="{{event.venue.pk}}" selected="selected">{{ event.venue.name }}</option>
{% endif %}
</select>
</div>
<div class="form-group form-row">
<label for="{{ form.power_mic.id_for_label }}"
class="col-4 control-label">{{ form.power_mic.help_text }}</label>
<select id="{{ form.power_mic.id_for_label }}" name="{{ form.power_mic.name }}" class="form-control selectpicker col-8" data-live-search="true" data-sourceurl="{% url 'api_secure' model='profile' %}?fields=first_name,last_name,initials" required="true">
{% if power_mic %}
<option value="{{power_mic.pk}}" selected="selected">{{ power_mic.name }}</option>
{% elif event.riskassessment.power_mic %}
<option value="{{event.riskassessment.power_mic.pk}}" selected="selected">{{ event.riskassessment.power_mic.name }}</option>
{% endif %}
</select>
</div>
<p class="pt-3 font-weight-bold">List vehicles and their drivers</p>
<div class="table-responsive">

View File

@@ -30,7 +30,7 @@
{% 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
<a href="{% url 'event_ec' event.pk %}" class="btn btn-info"><span class="fas fa-paperclip"></span> <span
class="hidden-xs">Create</span></a>
</td>
</tr>

View File

@@ -47,6 +47,7 @@ def nice_errors(form, non_field_msg='General form errors', autoescape=True):
return nice_errors
@register.inclusion_tag('pagination.html', takes_context=True)
def paginator(context, adjacent_pages=3):
"""
To be used in conjunction with the object_list generic view.
@@ -90,9 +91,6 @@ def paginator(context, adjacent_pages=3):
return dict
register.inclusion_tag('pagination.html', takes_context=True)(paginator)
@register.simple_tag
def url_replace(request, field, value):
dict_ = request.GET.copy()
@@ -123,7 +121,7 @@ def orderby(request, field, attr):
def get_field(obj, field, autoescape=True):
value = getattr(obj, field)
if(isinstance(value, bool)):
value = yesnoi(value)
value = yesnoi(value, field in obj.inverted_fields)
elif(isinstance(value, str)):
value = truncatewords(value, 20)
return mark_safe(value)