Much versioning work

This commit is contained in:
2022-01-01 19:53:03 +00:00
parent 0727a23236
commit 70d4c42676
10 changed files with 32 additions and 28 deletions

View File

@@ -7,8 +7,8 @@ from django.urls import reverse
from django.utils.safestring import SafeData, mark_safe
@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
@reversion.register(for_concrete_model=False)
class Trainee(Profile, RevisionMixin):
class Meta:
proxy = True
@@ -17,22 +17,16 @@ class Trainee(Profile, RevisionMixin): # 'shim' overtop the profile model to ne
def started_levels(self):
return [level for level in TrainingLevel.objects.all() if level.percentage_complete(self) > 0]
def level_qualifications(self, only_confirmed=False):
levels = self.levels.all()
if only_confirmed:
levels = levels.exclude(confirmed_on=None)
return levels.select_related('level')
@property
def is_supervisor(self):
return self.level_qualifications(True) \
return self.level_qualifications.all().exclude(confirmed_on=None).select_related('level') \
.filter(level__gte=TrainingLevel.SUPERVISOR) \
.exclude(level__department=TrainingLevel.HAULAGE) \
.exclude(level__department__isnull=True).exists()
@property
def is_driver(self):
return self.level_qualifications(True).filter(level__department=TrainingLevel.HAULAGE).exists()
return self.level_qualifications.all().exclude(confirmed_on=None).select_related('level').filter(level__department=TrainingLevel.HAULAGE).exists()
def get_records_of_depth(self, depth):
return self.qualifications_obtained.filter(depth=depth).select_related('item', 'trainee', 'supervisor')
@@ -80,7 +74,7 @@ class TrainingItem(models.Model):
ordering = ['category__reference_number', 'reference_number']
@reversion.register
@reversion.register(follow=['trainee'])
class TrainingItemQualification(models.Model):
STARTED = 0
COMPLETE = 1
@@ -104,7 +98,7 @@ class TrainingItemQualification(models.Model):
@property
def activity_feed_string(self):
return str("qualification for {} in {} ({})".format(self.trainee, self.item, self.get_depth_display()))
return str("{} in {}".format(self.get_depth_display(), self.item))
@classmethod
def get_colour_from_depth(obj, depth):
@@ -231,9 +225,9 @@ class TrainingLevelRequirement(models.Model, RevisionMixin):
unique_together = ["level", "item"]
@reversion.register
@reversion.register(follow=['trainee'])
class TrainingLevelQualification(models.Model, RevisionMixin):
trainee = models.ForeignKey('Trainee', related_name='levels', on_delete=models.RESTRICT)
trainee = models.ForeignKey('Trainee', related_name='level_qualifications', on_delete=models.RESTRICT)
level = models.ForeignKey('TrainingLevel', on_delete=models.RESTRICT)
confirmed_on = models.DateTimeField(null=True)
confirmed_by = models.ForeignKey('Trainee', related_name='confirmer', on_delete=models.RESTRICT, null=True)

View File

@@ -39,4 +39,4 @@ def get_supervisor(tech):
@register.filter
def get_levels_of_depth(trainee, level):
return trainee.level_qualifications(True).filter(level__level=level)
return trainee.level_qualifications.all().exclude(confirmed_on=None).select_related('level').filter(level__level=level)

0
training/tests/pages.py Normal file
View File

View File

@@ -0,0 +1,11 @@
import pytest
from pytest_django.asserts import assertFormError, assertRedirects, assertContains, assertNotContains
pytestmark = pytest.mark.django_db
def test_(admin_client):
url = reverse('add_qualification')
response = admin_client.post(url)
assertFormError(response, 'form', 'name', 'This field is required.')

View File

@@ -3,7 +3,8 @@ from django.urls import path
from django.contrib.auth.decorators import login_required
from PyRIGS.decorators import permission_required_with_403
from training import views
from training import views, models
from versioning.views import VersionHistory
urlpatterns = [
path('items/', login_required(views.ItemList.as_view()), name='item_list'),
@@ -11,6 +12,7 @@ urlpatterns = [
path('trainee/<int:pk>/',
permission_required_with_403('RIGS.view_profile')(views.TraineeDetail.as_view()),
name='trainee_detail'),
path('trainee/<int:pk>/history', permission_required_with_403('RIGS.view_profile')(VersionHistory.as_view()), name='trainee_history', kwargs={'model': models.Trainee, 'app': 'training'}), # Not picked up automatically because proxy model (I think)
path('trainee/<int:pk>/add_qualification/', login_required(views.AddQualification.as_view()),
name='add_qualification'),
path('session/', login_required(views.SessionLog.as_view()), name='session_log'),

View File

@@ -37,7 +37,7 @@ class TraineeDetail(views.ProfileDetail):
else:
context["page_title"] = "{}'s Training Record".format(self.object.first_name + " " + self.object.last_name)
context["started_levels"] = self.object.started_levels()
context["completed_levels"] = self.object.level_qualifications().select_related('level')
context["completed_levels"] = self.object.level_qualifications.all()
context["categories"] = models.TrainingCategory.objects.all().prefetch_related('items')
return context
@@ -97,7 +97,7 @@ class TraineeList(generic.ListView):
# not an integer
pass
return self.model.objects.filter(filter).annotate(num_qualifications=Count('qualifications_obtained')).order_by('-num_qualifications').prefetch_related('levels', 'qualifications_obtained', 'qualifications_obtained__item')
return self.model.objects.filter(filter).annotate(num_qualifications=Count('qualifications_obtained')).order_by('-num_qualifications').prefetch_related('level_qualifications', 'qualifications_obtained', 'qualifications_obtained__item')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)