mirror of
https://github.com/nottinghamtec/PyRIGS.git
synced 2026-01-16 21:12:13 +00:00
System for allowing certain TrainingCategories to be trained by certain levels, regardless of supervisor status
I.e. the haulage department, ref #482. As generic as I can make it I think.
This commit is contained in:
@@ -23,9 +23,13 @@ class QualificationForm(forms.ModelForm):
|
||||
|
||||
def clean_supervisor(self):
|
||||
supervisor = self.cleaned_data['supervisor']
|
||||
item = self.cleaned_data['item']
|
||||
if supervisor.pk == self.cleaned_data['trainee'].pk:
|
||||
raise forms.ValidationError('One may not supervise oneself...')
|
||||
if not supervisor.is_supervisor:
|
||||
if item.category.training_level:
|
||||
if not supervisor.level_qualifications.filter(level=item.category.training_level):
|
||||
raise forms.ValidationError('Selected supervising person is missing requisite training level to train in this department')
|
||||
elif not supervisor.is_supervisor:
|
||||
raise forms.ValidationError('Selected supervisor must actually *be* a supervisor...')
|
||||
return supervisor
|
||||
|
||||
|
||||
19
training/migrations/0003_trainingcategory_training_level.py
Normal file
19
training/migrations/0003_trainingcategory_training_level.py
Normal file
@@ -0,0 +1,19 @@
|
||||
# Generated by Django 3.2.11 on 2022-01-25 12:58
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('training', '0002_alter_traininglevel_options'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='trainingcategory',
|
||||
name='training_level',
|
||||
field=models.ForeignKey(help_text='If this is set, any user with the selected level may pass out users within this category, regardless of other status', null=True, on_delete=django.db.models.deletion.CASCADE, to='training.traininglevel'),
|
||||
),
|
||||
]
|
||||
@@ -15,22 +15,26 @@ class Trainee(Profile, RevisionMixin):
|
||||
def started_levels(self):
|
||||
return [level for level in TrainingLevel.objects.all() if level.percentage_complete(self) > 0 and level.pk not in self.level_qualifications.values_list('level', flat=True)]
|
||||
|
||||
@property
|
||||
def confirmed_levels(self):
|
||||
return self.level_qualifications.exclude(confirmed_on=None).select_related('level')
|
||||
|
||||
@property
|
||||
def is_technician(self):
|
||||
return self.level_qualifications.exclude(confirmed_on=None).select_related('level') \
|
||||
return self.confirmed_levels \
|
||||
.filter(level__level=TrainingLevel.TECHNICIAN) \
|
||||
.exclude(level__department=TrainingLevel.HAULAGE) \
|
||||
.exclude(level__department__isnull=True).exists()
|
||||
|
||||
@property
|
||||
def is_driver(self):
|
||||
return self.level_qualifications.all().exclude(confirmed_on=None).select_related('level').filter(level__department=TrainingLevel.HAULAGE).exists()
|
||||
return self.confirmed_levels.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')
|
||||
|
||||
def is_user_qualified_in(self, item, required_depth):
|
||||
return self.qualifications_obtained.values('item', 'depth').filter(item=item).filter(depth__gte=required_depth).first() is not None # this is a somewhat ghetto version of get_or_none
|
||||
return self.qualifications_obtained.values('item', 'depth').filter(item=item).filter(depth__gte=required_depth).exists()
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse('trainee_detail', kwargs={'pk': self.pk})
|
||||
@@ -47,6 +51,7 @@ class Trainee(Profile, RevisionMixin):
|
||||
class TrainingCategory(models.Model):
|
||||
reference_number = models.IntegerField(unique=True)
|
||||
name = models.CharField(max_length=50)
|
||||
training_level = models.ForeignKey('TrainingLevel', on_delete=models.CASCADE, null=True, help_text="If this is set, any user with the selected level may pass out users within this category, regardless of other status")
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.reference_number}. {self.name}"
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
</div>
|
||||
<div class="form-group form-row">
|
||||
<label for="supervisor" class="col-sm-2 col-form-label">Supervisor</label>
|
||||
<select name="supervisor" id="supervisor_id" class="form-control selectpicker custom-select col-sm-10" data-live-search="true" data-sourceurl="{% url 'api_secure' model='profile' %}?fields=first_name,last_name,initials&filters=is_supervisor" required>
|
||||
<select name="supervisor" id="supervisor_id" class="form-control selectpicker custom-select col-sm-10" data-live-search="true" data-sourceurl="{% url 'api_secure' model='profile' %}?fields=first_name,last_name,initials" required>
|
||||
{% if object.supervisor %}
|
||||
<option value="{{object.supervisor.pk}}" selected>{{object.supervisor}}</option>
|
||||
{% endif %}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
class="form-control" id="id_search_text"/>
|
||||
<span class="input-group-append">{% button 'search' id="id_search" %}</span>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary mt-2 {% if request.GET.is_supervisor %}active{%endif%}" data-toggle="button" aria-pressed="false" name="is_supervisor" value="{% if request.GET.is_supervisor %}{% else %}True{% endif %}">
|
||||
<button type="submit" class="btn btn-primary mt-2 {% if request.GET.is_supervisor %}active{%endif%}" data-toggle="button" aria-pressed="{% if request.GET.is_supervisor %}true{%endif%}" name="is_supervisor" value="{% if request.GET.is_supervisor %}{% else %}True{% endif %}">
|
||||
Only Supervisors
|
||||
</button>
|
||||
</form>
|
||||
|
||||
Reference in New Issue
Block a user