mirror of
https://github.com/nottinghamtec/PyRIGS.git
synced 2026-01-18 14:02:15 +00:00
Some reversion fiddling
This commit is contained in:
@@ -43,7 +43,7 @@
|
||||
<img class="card-img-top" src="{% static 'imgs/training.jpg' %}" alt="" style="height: 150px; object-fit: cover;">
|
||||
<h4 class="card-header">Training Database</h4>
|
||||
<div class="list-group list-group-flush">
|
||||
<a class="list-group-item list-group-item-action text-info" href="{% url 'trainee_detail' %}"><span class="fas fa-file-signature align-middle"></span><span class="align-middle"> My Training Record</span></a>
|
||||
<a class="list-group-item list-group-item-action text-info" href="{% url 'trainee_detail' request.user.pk %}"><span class="fas fa-file-signature align-middle"></span><span class="align-middle"> My Training Record</span></a>
|
||||
<a class="list-group-item list-group-item-action" href="{% url 'trainee_list' %}"><span class="fas fa-users"></span> Trainee List</a>
|
||||
<a class="list-group-item list-group-item-action" href="{% url 'level_list' %}"><span class="fas fa-layer-group"></span> Level List</a></a>
|
||||
<a class="list-group-item list-group-item-action" href="{% url 'item_list' %}"><span class="fas fa-sitemap"></span> Item List</a></a>
|
||||
|
||||
@@ -128,9 +128,8 @@ class Command(BaseCommand):
|
||||
for depth, depth_index in depths:
|
||||
if child.find('{}_Date'.format(depth)) is not None:
|
||||
if child.find('{}_Assessor_ID'.format(depth)) is None:
|
||||
print("Training Record #{} had no supervisor. Hmm.".format(child.find('ID').text))
|
||||
tally[2] += 1
|
||||
# TODO Assign God/Satan/Unknown here.
|
||||
print("Training Record #{} had no supervisor. Assigning System User.".format(child.find('ID').text))
|
||||
supervisor = Profile.objects.get(first_name="God")
|
||||
continue
|
||||
supervisor = Profile.objects.get(pk=self.id_map[child.find('{}_Assessor_ID'.format(depth)).text])
|
||||
if child.find('Member_ID') is None:
|
||||
@@ -258,23 +257,25 @@ class Command(BaseCommand):
|
||||
root = self.parse_xml(self.xml_path('Training Level Requirements.xml'))
|
||||
|
||||
for child in root:
|
||||
try:
|
||||
item = child.find('Item').text.split(".")
|
||||
obj, created = models.TrainingLevelRequirement.objects.update_or_create(
|
||||
level=models.TrainingLevel.objects.get(
|
||||
pk=int(
|
||||
child.find('Level').text)), item=models.TrainingItem.objects.get(
|
||||
active=True, reference_number=item[1], category=models.TrainingCategory.objects.get(
|
||||
reference_number=item[0])), depth=int(
|
||||
child.find('Depth').text))
|
||||
items = child.find('Items').text.split(",")
|
||||
for item in items:
|
||||
try:
|
||||
item = item.split('.')
|
||||
obj, created = models.TrainingLevelRequirement.objects.update_or_create(
|
||||
level=models.TrainingLevel.objects.get(
|
||||
pk=int(
|
||||
child.find('Level').text)), item=models.TrainingItem.objects.get(
|
||||
active=True, reference_number=item[1], category=models.TrainingCategory.objects.get(
|
||||
reference_number=item[0])), depth=int(
|
||||
child.find('Depth').text))
|
||||
|
||||
if created:
|
||||
tally[1] += 1
|
||||
else:
|
||||
tally[0] += 1
|
||||
except models.TrainingItem.DoesNotExist:
|
||||
print("Item with number {} does not exist".format(item))
|
||||
except models.TrainingItem.MultipleObjectsReturned:
|
||||
print(models.TrainingItem.objects.filter(reference_number=item[1], category=models.TrainingCategory.objects.get(reference_number=item[0])))
|
||||
if created:
|
||||
tally[1] += 1
|
||||
else:
|
||||
tally[0] += 1
|
||||
except models.TrainingItem.DoesNotExist:
|
||||
print("Item with number {} does not exist".format(item))
|
||||
except models.TrainingItem.MultipleObjectsReturned:
|
||||
print(models.TrainingItem.objects.filter(reference_number=item[1], category=models.TrainingCategory.objects.get(reference_number=item[0])))
|
||||
|
||||
print('TrainingLevelRequirements - Updated: {}, Created: {}'.format(tally[0], tally[1]))
|
||||
|
||||
@@ -6,11 +6,9 @@ from django.urls import reverse
|
||||
|
||||
from django.utils.safestring import SafeData, mark_safe
|
||||
|
||||
# 'shim' overtop the profile model to neatly contain all training related fields etc
|
||||
|
||||
|
||||
@reversion.register # profile is already registered, but this triggers my custom versioning logic
|
||||
class Trainee(Profile, RevisionMixin):
|
||||
@reversion.register(follow=['qualifications_obtained']) # profile is already registered, but this triggers my custom versioning logic
|
||||
class Trainee(Profile, RevisionMixin): # 'shim' overtop the profile model to neatly contain all training related fields etc
|
||||
class Meta:
|
||||
proxy = True
|
||||
|
||||
@@ -20,7 +18,10 @@ class Trainee(Profile, RevisionMixin):
|
||||
return [level for level in TrainingLevel.objects.all() if level.percentage_complete(self) > 0]
|
||||
|
||||
def level_qualifications(self, only_confirmed=False):
|
||||
return self.levels.all().filter(confirmed_on__isnull=only_confirmed).select_related('level')
|
||||
levels = self.levels.all()
|
||||
if only_confirmed:
|
||||
levels = levels.exclude(confirmed_on=None)
|
||||
return levels.select_related('level')
|
||||
|
||||
@property
|
||||
def is_supervisor(self):
|
||||
@@ -61,11 +62,11 @@ class TrainingItem(models.Model):
|
||||
active = models.BooleanField(default=True)
|
||||
|
||||
@property
|
||||
def number(self):
|
||||
def display_id(self):
|
||||
return "{}.{}".format(self.category.reference_number, self.reference_number)
|
||||
|
||||
def __str__(self):
|
||||
name = "{} {}".format(self.number, self.name)
|
||||
name = "{} {}".format(self.display_id, self.name)
|
||||
if not self.active:
|
||||
name += " (inactive)"
|
||||
return name
|
||||
@@ -79,6 +80,7 @@ class TrainingItem(models.Model):
|
||||
ordering = ['category__reference_number', 'reference_number']
|
||||
|
||||
|
||||
@reversion.register
|
||||
class TrainingItemQualification(models.Model):
|
||||
STARTED = 0
|
||||
COMPLETE = 1
|
||||
@@ -100,13 +102,9 @@ class TrainingItemQualification(models.Model):
|
||||
def __str__(self):
|
||||
return "{} in {} on {}".format(self.depth, self.item, self.date)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
super().save()
|
||||
for level in TrainingLevel.objects.all(): # Mm yes efficiency FIXME
|
||||
if level.user_has_requirements(self.trainee):
|
||||
with reversion.create_revision():
|
||||
level_qualification = TrainingLevelQualification.objects.get_or_create(trainee=self.trainee, level=level)
|
||||
reversion.add_to_revision(self.trainee)
|
||||
@property
|
||||
def activity_feed_string(self):
|
||||
return str("qualification for {} in {} ({})".format(self.trainee, self.item, self.get_depth_display()))
|
||||
|
||||
@classmethod
|
||||
def get_colour_from_depth(obj, depth):
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
My Record
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="navbarDropdownMy">
|
||||
<a class="dropdown-item" href="{% url 'trainee_detail' %}"><span class="fas fa-eye"></span>
|
||||
<a class="dropdown-item" href="{% url 'trainee_detail' request.user.pk %}"><span class="fas fa-eye"></span>
|
||||
Overview</a>
|
||||
<a class="dropdown-item" href="{% url 'trainee_item_detail' request.user.pk %}"><span class="fas fa-list"></span>
|
||||
Item Detail</a>
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
@@ -43,7 +43,8 @@
|
||||
<div class="row">
|
||||
<div class="col-sm-12 text-right">
|
||||
{% include 'partials/add_qualification.html' %}
|
||||
<a href="{% url 'trainee_item_detail' object.pk %}" class="btn btn-info"><span class="fas fa-info-circle"></span> View Detailed Record</a><br/>
|
||||
<a href="{% url 'trainee_item_detail' object.pk %}" class="btn btn-info"><span class="fas fa-info-circle"></span> View Detailed Record</a>
|
||||
<a href="{% url 'profile_detail' object.pk %}" class="btn btn-primary"><span class="fas fa-eye"></span> View User Profile</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
@@ -51,6 +52,7 @@
|
||||
<ul class="list-group col-12">
|
||||
{% for qual in completed_levels %}
|
||||
<li class="list-group-item">
|
||||
{{ qual.level.get_icon }}
|
||||
<a href="{% url 'level_detail' qual.level.pk %}">{{ qual.level }}</a>
|
||||
{% if qual.confirmed_on is None %}
|
||||
{% if request.user.pk != object.pk and request.user.is_supervisor %}
|
||||
@@ -59,7 +61,7 @@
|
||||
<button class="btn btn-warning" disabled>Awaiting Confirmation</button>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<button class="btn btn-success active">Confirmed <small>by {{ qual.confirmed_by|default:'System' }}</small></button>
|
||||
Confirmed by <a href="{{ qual.confirmed_by.get_absolute_url }}">{{ qual.confirmed_by|default:'System' }}</a> on {{ qual.confirmed_on|date }}
|
||||
{% endif %}
|
||||
</li>
|
||||
{% empty %}
|
||||
|
||||
@@ -36,8 +36,8 @@
|
||||
<tr id="row_item">
|
||||
<th scope="row" class="align-middle" id="cell_name"><a href="{% url 'trainee_detail' object.pk %}">{{ object.name }} {% if request.user.pk == object.pk %}<span class="fas fa-user text-success"></span>{%endif%}</a></th>
|
||||
<td {% if object.is_driver %}class="table-success"{%endif%}>{{ object.is_driver|yesno|title }}</td>
|
||||
<td>{% for level in object|get_levels_of_depth:1 %}{{ level.get_icon }}{%empty%}No{%endfor%}</td>
|
||||
<td {% if object.is_supervisor %}class="table-success"{%endif%}>{{ object.is_supervisor|yesno|title }}</td>
|
||||
<td>{% for level in object|get_levels_of_depth:1 %}{% if forloop.first %}Yes {%endif%}{{ level.get_icon }}{%empty%}No{%endfor%}</td>
|
||||
<td {% if object.is_supervisor %}class="table-success"{%endif%}>{% for level in object|get_levels_of_depth:2 %}{% if forloop.first %}Yes {%endif%}{{ level.get_icon }}{%empty%}No{%endfor%}</td>
|
||||
<td>{{ object.num_qualifications }}</td>
|
||||
<td style="white-space: nowrap">
|
||||
<a class="btn btn-info" href="{% url 'trainee_detail' pk=object.pk %}"><span class="fas fa-eye"></span> View Training Record</a>
|
||||
|
||||
@@ -8,7 +8,6 @@ from training import views
|
||||
urlpatterns = [
|
||||
path('items/', login_required(views.ItemList.as_view()), name='item_list'),
|
||||
path('trainee/list/', login_required(views.TraineeList.as_view()), name='trainee_list'),
|
||||
path('trainee/', login_required(views.TraineeDetail.as_view()), name='trainee_detail'),
|
||||
path('trainee/<int:pk>/',
|
||||
permission_required_with_403('RIGS.view_profile')(views.TraineeDetail.as_view()),
|
||||
name='trainee_detail'),
|
||||
|
||||
Reference in New Issue
Block a user