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