mirror of
https://github.com/nottinghamtec/PyRIGS.git
synced 2026-01-22 07:52:15 +00:00
Event checklist crew works
Mostly - its not happy with timezones
This commit is contained in:
@@ -10,6 +10,7 @@ from django.contrib.auth.forms import AuthenticationForm
|
|||||||
from captcha.fields import ReCaptchaField
|
from captcha.fields import ReCaptchaField
|
||||||
from reversion import revisions as reversion
|
from reversion import revisions as reversion
|
||||||
import simplejson
|
import simplejson
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
from RIGS import models
|
from RIGS import models
|
||||||
|
|
||||||
@@ -172,17 +173,17 @@ class EventRiskAssessmentForm(forms.ModelForm):
|
|||||||
|
|
||||||
|
|
||||||
class EventChecklistForm(forms.ModelForm):
|
class EventChecklistForm(forms.ModelForm):
|
||||||
|
# Parsed from incoming form data by clean, then saved into models when the form is saved
|
||||||
items = {}
|
items = {}
|
||||||
|
|
||||||
|
# There's probably a thousand better ways to do this, but this one is mine
|
||||||
def clean(self):
|
def clean(self):
|
||||||
vehicles = {key: val for key, val in self.data.items()
|
vehicles = {key: val for key, val in self.data.items()
|
||||||
if key.startswith('vehicle')}
|
if key.startswith('vehicle')}
|
||||||
drivers = {key: val for key, val in self.data.items()
|
|
||||||
if key.startswith('driver')}
|
|
||||||
for key in vehicles:
|
for key in vehicles:
|
||||||
pk = int(key.split('_')[1])
|
pk = int(key.split('_')[1])
|
||||||
driver_key = 'driver_' + str(pk)
|
driver_key = 'driver_' + str(pk)
|
||||||
if(drivers[driver_key] == ''):
|
if(self.data[driver_key] == ''):
|
||||||
raise forms.ValidationError('Add a driver to vehicle ' + str(pk), code='vehicle_mismatch')
|
raise forms.ValidationError('Add a driver to vehicle ' + str(pk), code='vehicle_mismatch')
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
@@ -191,10 +192,36 @@ class EventChecklistForm(forms.ModelForm):
|
|||||||
item = models.EventChecklistVehicle()
|
item = models.EventChecklistVehicle()
|
||||||
|
|
||||||
item.vehicle = vehicles['vehicle_' + str(pk)]
|
item.vehicle = vehicles['vehicle_' + str(pk)]
|
||||||
item.driver = models.Profile.objects.get(pk=drivers['driver_' + str(pk)])
|
item.driver = models.Profile.objects.get(pk=self.data[driver_key])
|
||||||
|
item.full_clean('checklist')
|
||||||
|
|
||||||
# item does not have a database pk yet as it isn't saved
|
# item does not have a database pk yet as it isn't saved
|
||||||
self.items[pk] = item
|
self.items['v' + str(pk)] = item
|
||||||
|
|
||||||
|
crewmembers = {key: val for key, val in self.data.items()
|
||||||
|
if key.startswith('crewmember')}
|
||||||
|
other_fields = ['start','role','end']
|
||||||
|
for key in crewmembers:
|
||||||
|
pk = int(key.split('_')[1])
|
||||||
|
|
||||||
|
for field in other_fields:
|
||||||
|
value = self.data['{}_{}'.format(field,pk)]
|
||||||
|
if value == '':
|
||||||
|
raise forms.ValidationError('Add a {} to crewmember {}'.format(field, pk), code='{}_mismatch'.format(field))
|
||||||
|
|
||||||
|
try:
|
||||||
|
item = models.EventChecklistCrew.objects.get(pk=pk)
|
||||||
|
except models.EventChecklistCrew.DoesNotExist:
|
||||||
|
item = models.EventChecklistCrew()
|
||||||
|
|
||||||
|
item.crewmember = models.Profile.objects.get(pk=self.data['crewmember_' + str(pk)])
|
||||||
|
item.start = self.data['start_' + str(pk)]
|
||||||
|
item.role = self.data['role_' + str(pk)]
|
||||||
|
item.end = self.data['end_' + str(pk)]
|
||||||
|
item.full_clean('checklist')
|
||||||
|
|
||||||
|
# item does not have a database pk yet as it isn't saved
|
||||||
|
self.items['c' + str(pk)] = item
|
||||||
|
|
||||||
return super(EventChecklistForm, self).clean()
|
return super(EventChecklistForm, self).clean()
|
||||||
|
|
||||||
@@ -203,15 +230,18 @@ class EventChecklistForm(forms.ModelForm):
|
|||||||
if (commit):
|
if (commit):
|
||||||
# Remove all existing, to be recreated from the form
|
# Remove all existing, to be recreated from the form
|
||||||
checklist.vehicles.all().delete()
|
checklist.vehicles.all().delete()
|
||||||
checklist.save()
|
checklist.crew.all().delete()
|
||||||
|
|
||||||
for key in self.items:
|
for key in self.items:
|
||||||
item = self.items[key]
|
item = self.items[key]
|
||||||
reversion.add_to_revision(item)
|
reversion.add_to_revision(item)
|
||||||
# finish and save new database items
|
# finish and save new database items
|
||||||
item.checklist = checklist
|
item.checklist = checklist
|
||||||
|
item.full_clean()
|
||||||
item.save()
|
item.save()
|
||||||
|
|
||||||
|
checklist.save()
|
||||||
|
|
||||||
self.items.clear()
|
self.items.clear()
|
||||||
|
|
||||||
return checklist
|
return checklist
|
||||||
|
|||||||
31
RIGS/migrations/0047_auto_20200829_2105.py
Normal file
31
RIGS/migrations/0047_auto_20200829_2105.py
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# Generated by Django 3.1 on 2020-08-29 20:05
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('RIGS', '0046_auto_20200828_1246'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='eventchecklistvehicle',
|
||||||
|
name='driver',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='vehicles', to=settings.AUTH_USER_MODEL),
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='EventChecklistCrew',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('role', models.CharField(max_length=255, null=True)),
|
||||||
|
('start', models.DateTimeField(blank=True, null=True)),
|
||||||
|
('end', models.DateTimeField(blank=True, null=True)),
|
||||||
|
('checklist', models.ForeignKey(blank=True, on_delete=django.db.models.deletion.CASCADE, related_name='crew', to='RIGS.eventchecklist')),
|
||||||
|
('crewmember', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='crewed', to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -635,7 +635,7 @@ class RiskAssessment(models.Model, RevisionMixin):
|
|||||||
return "%i - %s" % (self.pk, self.event)
|
return "%i - %s" % (self.pk, self.event)
|
||||||
|
|
||||||
|
|
||||||
@reversion.register(follow=['vehicles', ])
|
@reversion.register(follow=['vehicles', 'crew'])
|
||||||
class EventChecklist(models.Model, RevisionMixin):
|
class EventChecklist(models.Model, RevisionMixin):
|
||||||
event = models.OneToOneField('Event', on_delete=models.CASCADE)
|
event = models.OneToOneField('Event', on_delete=models.CASCADE)
|
||||||
|
|
||||||
@@ -680,9 +680,23 @@ class EventChecklist(models.Model, RevisionMixin):
|
|||||||
class EventChecklistVehicle(models.Model):
|
class EventChecklistVehicle(models.Model):
|
||||||
checklist = models.ForeignKey('EventChecklist', related_name='vehicles', blank=True, on_delete=models.CASCADE)
|
checklist = models.ForeignKey('EventChecklist', related_name='vehicles', blank=True, on_delete=models.CASCADE)
|
||||||
vehicle = models.CharField(max_length=255)
|
vehicle = models.CharField(max_length=255)
|
||||||
driver = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='drivers', on_delete=models.CASCADE)
|
driver = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='vehicles', on_delete=models.CASCADE)
|
||||||
|
|
||||||
reversion_hide = True
|
reversion_hide = True
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "{} driven by {}".format(self.vehicle, str(self.driver))
|
return "{} driven by {}".format(self.vehicle, str(self.driver))
|
||||||
|
|
||||||
|
|
||||||
|
@reversion.register
|
||||||
|
class EventChecklistCrew(models.Model):
|
||||||
|
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)
|
||||||
|
start = models.DateTimeField()
|
||||||
|
end = models.DateTimeField()
|
||||||
|
|
||||||
|
reversion_hide = True
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return "{} ({})".format(str(self.crewmember), self.role)
|
||||||
|
|||||||
@@ -61,6 +61,16 @@
|
|||||||
</dl>
|
</dl>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="card card-default mb-3">
|
||||||
|
<div class="card-header">Crew Record</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<ul>
|
||||||
|
{% for i in object.crew.all %}
|
||||||
|
<li>{{i}}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="card card-default mb-3">
|
<div class="card card-default mb-3">
|
||||||
<div class="card-header">Power</div>
|
<div class="card-header">Power</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
|
|||||||
@@ -35,9 +35,11 @@
|
|||||||
{% if object.medium_event %}
|
{% if object.medium_event %}
|
||||||
$('#small-event').slideUp();
|
$('#small-event').slideUp();
|
||||||
$('#medium-event').slideDown();
|
$('#medium-event').slideDown();
|
||||||
|
$('#size-selector button[data-event-size=1]').addClass('active');
|
||||||
{% else %}
|
{% else %}
|
||||||
$('#small-event').slideDown();
|
$('#small-event').slideDown();
|
||||||
$('#medium-event').slideUp();
|
$('#medium-event').slideUp();
|
||||||
|
$('#size-selector button[data-event-size=0]').addClass('active');
|
||||||
{% endif%}
|
{% endif%}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
$('#size-selector button').on('click', function () {
|
$('#size-selector button').on('click', function () {
|
||||||
@@ -53,24 +55,29 @@
|
|||||||
$('#medium-event').slideUp();
|
$('#medium-event').slideUp();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$('#vehicle-add').on('click', function (event) {
|
$('button[data-action=add]').on('click', function (event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
var newID = Number($('#vehiclest').attr('data-pk'));
|
var target = $($(this).attr('data-target'));
|
||||||
$('#vehicles_new').clone().attr('style', "").attr('id', 'vehicles_' + newID).appendTo('#vehiclest');
|
var newID = Number(target.attr('data-pk'));
|
||||||
$('#vehicles_' + newID).find('select,input').attr('name', function(){
|
var newRow = $($(this).attr('data-clone'))
|
||||||
return this.name.split('_')[0] + '_' + newID;
|
.clone().attr('style', "")
|
||||||
//Disabled prevents the hidden row being sent to the form
|
.attr('id', function(i, val){
|
||||||
}).removeAttr('disabled');
|
return val.split("_")[0] + '_' + newID;
|
||||||
$('#vehicles_' + newID).find('button[data-action=delete]').attr('data-id', newID);
|
})
|
||||||
$('#vehicles_' + newID).find('select').addClass('selectpicker');
|
.appendTo(target);
|
||||||
$('#vehicles_' + newID).find('.selectpicker').selectpicker('refresh');
|
newRow.find('select,input').attr('name', function(i, val){
|
||||||
|
return val.split("_")[0] + '_' + newID;
|
||||||
|
})//Disabled is to prevent the hidden row being sent to the form
|
||||||
|
.removeAttr('disabled');
|
||||||
|
newRow.find('button[data-action=delete]').attr('data-id', newID);
|
||||||
|
newRow.find('select').addClass('selectpicker');
|
||||||
|
newRow.find('.selectpicker').selectpicker('refresh');
|
||||||
$(".selectpicker").each(function(){initPicker($(this))});
|
$(".selectpicker").each(function(){initPicker($(this))});
|
||||||
$('#vehiclest').attr('data-pk', newID - 1);
|
$(target).attr('data-pk', newID - 1);
|
||||||
});
|
});
|
||||||
$('button[data-action=delete]').on('click', function(event) {
|
$('button[data-action=delete]').on('click', function(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
console.log($(this).attr('data-id'));
|
$($(this).attr('data-target') + '_' + $(this).attr('data-id')).remove();
|
||||||
$('#vehicles_' + $(this).attr('data-id')).remove();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@@ -124,11 +131,8 @@
|
|||||||
<tbody id="vehiclest" data-pk="-1">
|
<tbody id="vehiclest" data-pk="-1">
|
||||||
<tr id="vehicles_new" style="display: none;">
|
<tr id="vehicles_new" style="display: none;">
|
||||||
<td><input type="text" class="form-control" name="vehicle_new" disabled="true"/></td>
|
<td><input type="text" class="form-control" name="vehicle_new" disabled="true"/></td>
|
||||||
<td>
|
<td><select class="form-control" data-live-search="true" data-sourceurl="{% url 'api_secure' model='profile' %}?fields=first_name,last_name,initials" name="driver_new" disabled="true"></select></td>
|
||||||
<select class="form-control" data-live-search="true" data-sourceurl="{% url 'api_secure' model='profile' %}?fields=first_name,last_name,initials" name="driver_new" disabled="true">
|
<td><button class="btn btn-danger" data-action='delete' data-target='#vehicle'><span class="fas fa-times"></span></button</td>
|
||||||
</select>
|
|
||||||
</td>
|
|
||||||
<td><button class="btn btn-danger" data-action='delete'><span class="fas fa-times"></span></button</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
{# TODO Add required to all fields on row when one is edited #}
|
{# TODO Add required to all fields on row when one is edited #}
|
||||||
{% for i in object.vehicles.all %}
|
{% for i in object.vehicles.all %}
|
||||||
@@ -141,13 +145,13 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
<td><button class="btn btn-danger" data-id='{{i.pk}}' data-action='delete'><span class="fas fa-times"></span></button</td>
|
<td><button class="btn btn-danger" data-id='{{i.pk}}' data-action='delete' data-target='#vehicle'><span class="fas fa-times"></span></button</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<div class="text-right">
|
<div class="text-right">
|
||||||
<button class="btn btn-secondary" id="vehicle-add"><span class="fas fa-plus"></span> Add Vehicle</button>
|
<button class="btn btn-secondary" id="vehicle-add" data-action='add' data-target='#vehiclest' data-clone='#vehicles_new'><span class="fas fa-plus"></span> Add Vehicle</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -184,23 +188,38 @@
|
|||||||
<th scope="col">Start Time</th>
|
<th scope="col">Start Time</th>
|
||||||
<th scope="col">Role</th>
|
<th scope="col">Role</th>
|
||||||
<th scope="col">End Time</th>
|
<th scope="col">End Time</th>
|
||||||
|
<th scope="col"></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody id="crewmemberst" data-pk="-1">
|
||||||
{% for i in '012'|make_list %}
|
<tr id="crew_new" style="display: none;">
|
||||||
<tr>
|
<td>
|
||||||
|
<select name="crewmember_new" class="form-control" data-live-search="true" data-sourceurl="{% url 'api_secure' model='profile' %}?fields=first_name,last_name,initials" disabled="true"></select>
|
||||||
<th scope="row">
|
</td>
|
||||||
</th>
|
<td><input name="start_new" type="datetime-local" class="form-control" value="{{ i.start }}" disabled="true"/></td>
|
||||||
<td><input type="time" class="form-control"/></td>
|
<td><input name="role_new" type="text" class="form-control" value="{{ i.role }}" disabled="true"/></td>
|
||||||
<td><input type="text" class="form-control"/></td>
|
<td><input name="end_new" type="datetime-local" class="form-control" value="{{ i.end }}" disabled="true" /></td>
|
||||||
<td><input type="time" class="form-control"/></td>
|
<td><button class="btn btn-danger" data-id='{{crew.pk}}' data-action='delete' data-target='#crewmember'><span class="fas fa-times"></span></button</td>
|
||||||
|
</tr>
|
||||||
|
{% for crew in object.crew.all %}
|
||||||
|
<tr id="crew_{{crew.pk}}">
|
||||||
|
<td>
|
||||||
|
<select name="crewmember_{{crew.pk}}" class="form-control selectpicker" data-live-search="true" data-sourceurl="{% url 'api_secure' model='profile' %}?fields=first_name,last_name,initials">
|
||||||
|
{% if crew.crewmember != '' %}
|
||||||
|
<option value="{{crew.crewmember.pk}}" selected="selected">{{ crew.crewmember.name }}</option>
|
||||||
|
{% endif %}
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
<td><input name="start_{{crew.pk}}" type="datetime-local" class="form-control" value="{{ crew.start|date:'Y-m-d' }}T{{ crew.start|date:'H:i:s' }}"/></td>
|
||||||
|
<td><input name="role_{{crew.pk}}" type="text" class="form-control" value="{{ crew.role }}"/></td>
|
||||||
|
<td><input name="end_{{crew.pk}}" type="datetime-local" class="form-control" value="{{ crew.end|date:'Y-m-d' }}T{{ crew.end|date:'H:i:s' }}"/></td>
|
||||||
|
<td><button class="btn btn-danger" data-id='{{crew.pk}}' data-action='delete' data-target='#crewmember'><span class="fas fa-times"></span></button</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<div class="text-right">
|
<div class="text-right">
|
||||||
<button class="btn btn-secondary"><span class="fas fa-plus"></span> Add Crewmember</button>
|
<button class="btn btn-secondary" data-action='add' data-target='#crewmemberst' data-clone='#crew_new'><span class="fas fa-plus"></span> Add Crewmember</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -9,9 +9,7 @@
|
|||||||
<h4 class="col-sm-12 pb-3">Welcome back {{ user.get_full_name }}, there {%if rig_count == 1 %}is one rig coming up{%else%}are {{ rig_count|apnumber }} rigs coming up.{%endif%}</h4>
|
<h4 class="col-sm-12 pb-3">Welcome back {{ user.get_full_name }}, there {%if rig_count == 1 %}is one rig coming up{%else%}are {{ rig_count|apnumber }} rigs coming up.{%endif%}</h4>
|
||||||
<div class="col-sm">
|
<div class="col-sm">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header">
|
<h4 class="card-header">Rigboard</h4>
|
||||||
<h4 class="list-group-item-heading">Rigboard</h4>
|
|
||||||
</div>
|
|
||||||
<div class="list-group list-group-flush">
|
<div class="list-group list-group-flush">
|
||||||
<a class="list-group-item list-group-item-action" href="{% url 'rigboard' %}"><i class="fas fa-list"></i> Rigboard</a>
|
<a class="list-group-item list-group-item-action" href="{% url 'rigboard' %}"><i class="fas fa-list"></i> Rigboard</a>
|
||||||
<a class="list-group-item list-group-item-action" href="{% url 'web_calendar' %}"><i class="fas fa-calendar"></i> Calendar</a>
|
<a class="list-group-item list-group-item-action" href="{% url 'web_calendar' %}"><i class="fas fa-calendar"></i> Calendar</a>
|
||||||
@@ -19,9 +17,7 @@
|
|||||||
<a class="list-group-item list-group-item-action" href="{% url 'event_create' %}"><i class="fas fa-plus"></i> New Event</a>
|
<a class="list-group-item list-group-item-action" href="{% url 'event_create' %}"><i class="fas fa-plus"></i> New Event</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div class="card-header">
|
<h4 class="card-header">Asset Database</h4>
|
||||||
<h4 class="list-group-item-heading">Asset Database</h4>
|
|
||||||
</div>
|
|
||||||
<div class="list-group list-group-flush">
|
<div class="list-group list-group-flush">
|
||||||
<a class="list-group-item list-group-item-action" href="{% url 'asset_index' %}"><i class="fas fa-tag"></i> Asset List </a>
|
<a class="list-group-item list-group-item-action" href="{% url 'asset_index' %}"><i class="fas fa-tag"></i> Asset List </a>
|
||||||
{% if perms.assets.add_asset %}
|
{% if perms.assets.add_asset %}
|
||||||
@@ -32,9 +28,7 @@
|
|||||||
<a class="list-group-item list-group-item-action" href="{% url 'supplier_create' %}"><i class="fas fa-plus"></i> New Supplier</a>
|
<a class="list-group-item list-group-item-action" href="{% url 'supplier_create' %}"><i class="fas fa-plus"></i> New Supplier</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div class="card-header">
|
<h4 class="card-header">Quick Links</h4>
|
||||||
<h4 class="list-group-item-heading">Quick Links</h4>
|
|
||||||
</div>
|
|
||||||
<div class="list-group list-group-flush">
|
<div class="list-group list-group-flush">
|
||||||
<a class="list-group-item list-group-item-action" href="https://forum.nottinghamtec.co.uk" target="_blank" rel="noopener noreferrer"><i class="fas fa-comment-alt"></i> TEC Forum</a>
|
<a class="list-group-item list-group-item-action" href="https://forum.nottinghamtec.co.uk" target="_blank" rel="noopener noreferrer"><i class="fas fa-comment-alt"></i> TEC Forum</a>
|
||||||
<a class="list-group-item list-group-item-action" href="//members.nottinghamtec.co.uk/wiki" target="_blank" rel="noopener noreferrer"><i class="fas fa-pen-square"></i> TEC Wiki</a>
|
<a class="list-group-item list-group-item-action" href="//members.nottinghamtec.co.uk/wiki" target="_blank" rel="noopener noreferrer"><i class="fas fa-pen-square"></i> TEC Wiki</a>
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
{% if version.changes.anything_changed or version.changes.old == None %}
|
{% if version.changes.anything_changed or version.changes.old == None %}
|
||||||
{% for change in version.changes.field_changes %}
|
{% for change in version.changes.field_changes %}
|
||||||
<span title="Changes to {{ change.field.verbose_name }}" class="badge badge-info p-2" data-container="body" data-html="true" data-trigger='hover' data-toggle="popover" data-content='{% spaceless %}{% include "version_changes_change.html" %}{% endspaceless %}'>{{ change.field.verbose_name }}</span>
|
<span title="Changes to {{ change.field.verbose_name }}" class="badge badge-info p-2" data-container="body" data-html="true" data-trigger='hover' data-toggle="popover" data-content='{% spaceless %}{% include "partials/version_changes_change.html" %}{% endspaceless %}'>{{ change.field.verbose_name }}</span>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% for itemChange in version.changes.item_changes %}
|
{% for itemchange in version.changes.item_changes %}
|
||||||
<span title="Changes to item '{% if itemChange.new %}{{ itemChange.new.name }}{% else %}{{ itemChange.old.name }}{% endif %}'" class="badge badge-info p-1" data-container="body" data-html="true" data-trigger='hover' data-toggle="popover" data-content='{% spaceless %}
|
<span title="Changes to {{ itemchange.name }}" class="badge badge-info p-2" data-container="body" data-html="true" data-trigger='hover' data-toggle="popover" data-content='{% spaceless %}
|
||||||
<ul class="list-group">
|
<ul class="list-group list-group-flush">
|
||||||
{% for change in itemChange.field_changes %}
|
{% for change in itemchange.field_changes %}
|
||||||
<li class="list-group-item">
|
<li class="list-group-item">
|
||||||
<h4 class="list-group-item-heading">{{ change.field.verbose_name }}</h4>
|
<p>{{ change.field.verbose_name|title }}:</p>
|
||||||
<div class="dont-break-out">{% include 'version_changes_change.html' with change=itemChange %}</div>
|
<div class="dont-break-out">{% include 'partials/version_changes_change.html' with change=itemchange %}</div>
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
{% endspaceless %}'>item '{% if itemChange.new %}{{ itemChange.new.name }}{% else %}{{ itemChange.old.name }}{% endif %}'</span>
|
{% endspaceless %}'>{{ itemchange.name }}</span>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% else %}
|
{% else %}
|
||||||
nothing useful
|
nothing useful
|
||||||
|
|||||||
@@ -118,30 +118,34 @@ class ModelComparison(object):
|
|||||||
@cached_property
|
@cached_property
|
||||||
def item_changes(self):
|
def item_changes(self):
|
||||||
# Recieves two event version objects and compares their items, returns an array of ItemCompare objects
|
# Recieves two event version objects and compares their items, returns an array of ItemCompare objects
|
||||||
item_type = ContentType.objects.get_for_model(models.EventItem)
|
item_type = ContentType.objects.get_for_model(self.version.object)
|
||||||
item_dict = {}
|
old_item_versions = self.version.parent.revision.version_set.exclude(content_type=item_type)
|
||||||
if hasattr(self.version, 'parent'):
|
new_item_versions = self.version.revision.version_set.exclude(content_type=item_type)
|
||||||
old_item_versions = self.version.parent.revision.version_set.filter(content_type=item_type)
|
|
||||||
new_item_versions = self.version.revision.version_set.filter(content_type=item_type)
|
|
||||||
|
|
||||||
comparisonParams = {'excluded_keys': ['id', 'event', 'order']}
|
comparisonParams = {'excluded_keys': ['id', 'event', 'order']}
|
||||||
|
|
||||||
# Build some dicts of what we have
|
# Build some dicts of what we have
|
||||||
# build a list of items, key is the item_pk
|
item_dict = {} # build a list of items, key is the item_pk
|
||||||
for version in old_item_versions: # put all the old versions in a list
|
# FIXME Removing the if checks makes things REALLY slow...
|
||||||
if version.field_dict["event_id"] == int(self.new.pk):
|
for version in old_item_versions: # put all the old versions in a list
|
||||||
compare = ModelComparison(old=version._object_version.object, **comparisonParams)
|
#if version.field_dict["event_id"] == int(self.new.pk):
|
||||||
item_dict[version.object_id] = compare
|
compare = ModelComparison(old=version._object_version.object, **comparisonParams)
|
||||||
|
item_dict[version.object_id] = compare
|
||||||
|
|
||||||
for version in new_item_versions: # go through the new versions
|
for version in new_item_versions: # go through the new versions
|
||||||
if version.field_dict["event_id"] == int(self.new.pk):
|
#if version.field_dict["event_id"] == int(self.new.pk):
|
||||||
try:
|
try:
|
||||||
compare = item_dict[version.object_id] # see if there's a matching old version
|
compare = item_dict[version.object_id] # see if there's a matching old version
|
||||||
compare.new = version._object_version.object # then add the new version to the dictionary
|
compare.new = version._object_version.object # then add the new version to the dictionary
|
||||||
except KeyError: # there's no matching old version, so add this item to the dictionary by itself
|
except KeyError: # there's no matching old version, so add this item to the dictionary by itself
|
||||||
compare = ModelComparison(new=version._object_version.object, **comparisonParams)
|
compare = ModelComparison(new=version._object_version.object, **comparisonParams)
|
||||||
|
|
||||||
item_dict[version.object_id] = compare # update the dictionary with the changes
|
if compare.new:
|
||||||
|
compare.name = str(compare.new)
|
||||||
|
else:
|
||||||
|
compare.name = str(compare.old)
|
||||||
|
|
||||||
|
item_dict[version.object_id] = compare # update the dictionary with the changes
|
||||||
|
|
||||||
changes = []
|
changes = []
|
||||||
for (_, compare) in list(item_dict.items()):
|
for (_, compare) in list(item_dict.items()):
|
||||||
@@ -160,7 +164,6 @@ class ModelComparison(object):
|
|||||||
|
|
||||||
|
|
||||||
class RIGSVersionManager(VersionQuerySet):
|
class RIGSVersionManager(VersionQuerySet):
|
||||||
# TODO Rework this so its possible to define from the other apps
|
|
||||||
def get_for_multiple_models(self, model_array):
|
def get_for_multiple_models(self, model_array):
|
||||||
content_types = []
|
content_types = []
|
||||||
for model in model_array:
|
for model in model_array:
|
||||||
|
|||||||
Reference in New Issue
Block a user