From dff5ac230826a92ae761a6af27ab6711498c2250 Mon Sep 17 00:00:00 2001 From: Arona Jones Date: Mon, 5 Jul 2021 23:24:13 +0100 Subject: [PATCH] Whee broken HEAD --- PyRIGS/views.py | 7 +- RIGS/templates/event_form.html | 6 +- RIGS/templates/eventauthorisation.html | 2 +- RIGS/templates/invoice_detail.html | 2 +- RIGS/templates/{ => partials}/item_modal.html | 0 RIGS/templates/{ => partials}/item_table.html | 0 training/admin.py | 2 +- training/forms.py | 16 +++ training/migrations/0001_initial.py | 90 +++++-------- .../migrations/0002_auto_20210630_1514.py | 118 ------------------ .../migrations/0003_auto_20210630_1624.py | 19 --- .../migrations/0004_auto_20210630_1641.py | 23 ---- training/models.py | 10 +- training/templates/edit_training_record.html | 57 +++++++++ training/templates/session_log_form.html | 22 +++- training/templates/trainee_detail.html | 5 + training/urls.py | 2 + training/views.py | 29 ++++- 18 files changed, 177 insertions(+), 233 deletions(-) rename RIGS/templates/{ => partials}/item_modal.html (100%) rename RIGS/templates/{ => partials}/item_table.html (100%) delete mode 100644 training/migrations/0002_auto_20210630_1514.py delete mode 100644 training/migrations/0003_auto_20210630_1624.py delete mode 100644 training/migrations/0004_auto_20210630_1641.py create mode 100644 training/templates/edit_training_record.html diff --git a/PyRIGS/views.py b/PyRIGS/views.py index 0216b104..2803ea55 100644 --- a/PyRIGS/views.py +++ b/PyRIGS/views.py @@ -16,6 +16,7 @@ from django.views.decorators.clickjacking import xframe_options_exempt from RIGS import models from assets import models as asset_models +from training import models as training_models def is_ajax(request): @@ -38,7 +39,8 @@ class SecureAPIRequest(generic.View): 'organisation': models.Organisation, 'profile': models.Profile, 'event': models.Event, - 'supplier': asset_models.Supplier + 'supplier': asset_models.Supplier, + 'training_item': training_models.TrainingItem, } perms = { @@ -47,7 +49,8 @@ class SecureAPIRequest(generic.View): 'organisation': 'RIGS.view_organisation', 'profile': 'RIGS.view_profile', 'event': None, - 'supplier': None + 'supplier': None, + 'training_item': None, # TODO } ''' diff --git a/RIGS/templates/event_form.html b/RIGS/templates/event_form.html index 87163ea5..2e29de3e 100644 --- a/RIGS/templates/event_form.html +++ b/RIGS/templates/event_form.html @@ -72,7 +72,7 @@ {% endblock %} {% block content %} -{% include 'item_modal.html' %} +{% include 'partials/item_modal.html' %}
{% csrf_token %}
@@ -326,7 +326,7 @@
+ class="col-sm-4 col-fitem_tableorm-label">{{ form.purchase_order.label }}
{% render_field form.purchase_order class+="form-control" %} @@ -348,7 +348,7 @@ {% render_field form.notes class+="form-control" %}
- {% include 'item_table.html' %} + {% include 'partials/item_table.html' %}
diff --git a/RIGS/templates/eventauthorisation.html b/RIGS/templates/eventauthorisation.html index 896968ff..f464f72d 100644 --- a/RIGS/templates/eventauthorisation.html +++ b/RIGS/templates/eventauthorisation.html @@ -26,7 +26,7 @@
{% with object=event auth=True %} - {% include 'item_table.html' %} + {% include 'partials/item_table.html' %} {% endwith %}
diff --git a/RIGS/templates/invoice_detail.html b/RIGS/templates/invoice_detail.html index d59e8d83..37c3a68d 100644 --- a/RIGS/templates/invoice_detail.html +++ b/RIGS/templates/invoice_detail.html @@ -78,7 +78,7 @@
{% with object.event as object %} - {% include 'item_table.html' %} + {% include 'partials/item_table.html' %} {% endwith %}
diff --git a/RIGS/templates/item_modal.html b/RIGS/templates/partials/item_modal.html similarity index 100% rename from RIGS/templates/item_modal.html rename to RIGS/templates/partials/item_modal.html diff --git a/RIGS/templates/item_table.html b/RIGS/templates/partials/item_table.html similarity index 100% rename from RIGS/templates/item_table.html rename to RIGS/templates/partials/item_table.html diff --git a/training/admin.py b/training/admin.py index 2e8e05bf..9d6906ed 100644 --- a/training/admin.py +++ b/training/admin.py @@ -2,7 +2,7 @@ from django.contrib import admin from training import models from reversion.admin import VersionAdmin -admin.site.register(models.Trainee, VersionAdmin) +#admin.site.register(models.Trainee, VersionAdmin) admin.site.register(models.TrainingLevel, VersionAdmin) admin.site.register(models.TrainingCategory, VersionAdmin) admin.site.register(models.TrainingItem, VersionAdmin) diff --git a/training/forms.py b/training/forms.py index 32336771..b45a1b8c 100644 --- a/training/forms.py +++ b/training/forms.py @@ -1,4 +1,20 @@ from django import forms +from training import models +from RIGS.models import Profile + class SessionLogForm(forms.Form): pass + + +class QualificationForm(forms.ModelForm): + class Meta: + model = models.TrainingItemQualification + fields = '__all__' + # exclude = ['trainee'] + + def __init__(self, *args, **kwargs): + pk = kwargs.pop('pk', None) + super(QualificationForm, self).__init__(*args, **kwargs) + self.fields['trainee'].initial = Profile.objects.get(pk=pk) + diff --git a/training/migrations/0001_initial.py b/training/migrations/0001_initial.py index efcf3119..3298076e 100644 --- a/training/migrations/0001_initial.py +++ b/training/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 3.1.5 on 2021-06-29 16:10 +# Generated by Django 3.1.5 on 2021-07-05 22:01 import RIGS.models import django.contrib.auth.models @@ -15,33 +15,11 @@ class Migration(migrations.Migration): ] operations = [ - migrations.CreateModel( - name='Department', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=50)), - ], - ), - migrations.CreateModel( - name='Trainee', - fields=[ - ('profile_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='RIGS.profile')), - ], - options={ - 'verbose_name': 'user', - 'verbose_name_plural': 'users', - 'abstract': False, - }, - bases=('RIGS.profile',), - managers=[ - ('objects', django.contrib.auth.models.UserManager()), - ], - ), migrations.CreateModel( name='TrainingCategory', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('number', models.CharField(max_length=3)), + ('reference_number', models.CharField(max_length=3)), ('name', models.CharField(max_length=50)), ], ), @@ -49,58 +27,54 @@ class Migration(migrations.Migration): name='TrainingItem', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('number', models.CharField(max_length=3)), + ('reference_number', models.CharField(max_length=3)), ('name', models.CharField(max_length=50)), - ('category', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='training.trainingcategory')), + ('category', models.ForeignKey(on_delete=django.db.models.deletion.RESTRICT, related_name='items', to='training.trainingcategory')), ], ), migrations.CreateModel( - name='TrainingItemInstance', + name='TrainingLevel', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('training_started_on', models.DateField()), - ('training_complete_on', models.DateField()), - ('passed_out_on', models.DateField()), - ('item', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='training.trainingitem')), - ('passed_out_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='passed_out', to='training.trainee')), - ('trainee', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='items', to='training.trainee')), - ('training_complete_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='training_complete', to='training.trainee')), - ('training_started_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='training_started', to='training.trainee')), + ('department', models.CharField(max_length=50, null=True)), + ('level', models.IntegerField(choices=[(0, 'Technical Assistant'), (1, 'Technician'), (2, 'Supervisor')])), ], - ), - migrations.CreateModel( - name='Technician', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('department', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='training.department')), - ('requirements', models.ManyToManyField(to='training.TrainingItem')), - ], - options={ - 'abstract': False, - }, bases=(models.Model, RIGS.models.RevisionMixin), ), migrations.CreateModel( - name='TechnicalAssistant', + name='Trainee', fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('requirements', models.ManyToManyField(to='training.TrainingItem')), ], options={ - 'abstract': False, + 'proxy': True, + 'indexes': [], + 'constraints': [], }, - bases=(models.Model, RIGS.models.RevisionMixin), + bases=('RIGS.profile',), + managers=[ + ('objects', django.contrib.auth.models.UserManager()), + ], ), migrations.CreateModel( - name='Supervisor', + name='TrainingLevelQualification', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('department', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='training.department')), - ('requirements', models.ManyToManyField(to='training.TrainingItem')), + ('confirmed_on', models.DateTimeField()), + ('confirmed_by', models.ForeignKey(on_delete=django.db.models.deletion.RESTRICT, related_name='confirmer', to='training.trainee')), + ('level', models.ForeignKey(on_delete=django.db.models.deletion.RESTRICT, to='training.traininglevel')), + ('trainee', models.ForeignKey(on_delete=django.db.models.deletion.RESTRICT, related_name='levels', to='training.trainee')), + ], + ), + migrations.CreateModel( + name='TrainingItemQualification', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('depth', models.IntegerField(choices=[(0, 'Training Started'), (1, 'Training Complete'), (2, 'Passed Out')])), + ('date', models.DateField()), + ('notes', models.TextField(blank=True)), + ('item', models.ForeignKey(on_delete=django.db.models.deletion.RESTRICT, to='training.trainingitem')), + ('supervisor', models.ForeignKey(on_delete=django.db.models.deletion.RESTRICT, related_name='qualifications_granted', to='training.trainee')), + ('trainee', models.ForeignKey(on_delete=django.db.models.deletion.RESTRICT, related_name='qualifications_obtained', to='training.trainee')), ], - options={ - 'abstract': False, - }, - bases=(models.Model, RIGS.models.RevisionMixin), ), ] diff --git a/training/migrations/0002_auto_20210630_1514.py b/training/migrations/0002_auto_20210630_1514.py deleted file mode 100644 index cede19b4..00000000 --- a/training/migrations/0002_auto_20210630_1514.py +++ /dev/null @@ -1,118 +0,0 @@ -# Generated by Django 3.1.5 on 2021-06-30 14:14 - -import RIGS.models -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('training', '0001_initial'), - ] - - operations = [ - migrations.CreateModel( - name='TrainingItemQualification', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('depth', models.IntegerField(choices=[(0, 'Training Started'), (1, 'Training Complete'), (2, 'Passed Out')])), - ('date', models.DateTimeField()), - ('notes', models.TextField()), - ], - ), - migrations.CreateModel( - name='TrainingLevel', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('department', models.CharField(max_length=50, null=True)), - ('level', models.IntegerField(choices=[(0, 'Technical Assistant'), (1, 'Technician'), (2, 'Supervisor')])), - ], - bases=(models.Model, RIGS.models.RevisionMixin), - ), - migrations.CreateModel( - name='TrainingLevelQualification', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('confirmed_on', models.DateTimeField()), - ('confirmed_by', models.ForeignKey(on_delete=django.db.models.deletion.RESTRICT, related_name='confirmer', to='training.trainee')), - ('level', models.ForeignKey(on_delete=django.db.models.deletion.RESTRICT, to='training.traininglevel')), - ('trainee', models.ForeignKey(on_delete=django.db.models.deletion.RESTRICT, related_name='levels', to='training.trainee')), - ], - ), - migrations.RemoveField( - model_name='supervisor', - name='department', - ), - migrations.RemoveField( - model_name='supervisor', - name='requirements', - ), - migrations.RemoveField( - model_name='technicalassistant', - name='requirements', - ), - migrations.RemoveField( - model_name='technician', - name='department', - ), - migrations.RemoveField( - model_name='technician', - name='requirements', - ), - migrations.RemoveField( - model_name='trainingiteminstance', - name='item', - ), - migrations.RemoveField( - model_name='trainingiteminstance', - name='passed_out_by', - ), - migrations.RemoveField( - model_name='trainingiteminstance', - name='trainee', - ), - migrations.RemoveField( - model_name='trainingiteminstance', - name='training_complete_by', - ), - migrations.RemoveField( - model_name='trainingiteminstance', - name='training_started_by', - ), - migrations.AlterField( - model_name='trainingitem', - name='category', - field=models.ForeignKey(on_delete=django.db.models.deletion.RESTRICT, to='training.trainingcategory'), - ), - migrations.DeleteModel( - name='Department', - ), - migrations.DeleteModel( - name='Supervisor', - ), - migrations.DeleteModel( - name='TechnicalAssistant', - ), - migrations.DeleteModel( - name='Technician', - ), - migrations.DeleteModel( - name='TrainingItemInstance', - ), - migrations.AddField( - model_name='trainingitemqualification', - name='item', - field=models.ForeignKey(on_delete=django.db.models.deletion.RESTRICT, to='training.trainingitem'), - ), - migrations.AddField( - model_name='trainingitemqualification', - name='supervisor', - field=models.ForeignKey(on_delete=django.db.models.deletion.RESTRICT, related_name='training_started', to='training.trainee'), - ), - migrations.AddField( - model_name='trainingitemqualification', - name='trainee', - field=models.ForeignKey(on_delete=django.db.models.deletion.RESTRICT, related_name='items', to='training.trainee'), - ), - ] diff --git a/training/migrations/0003_auto_20210630_1624.py b/training/migrations/0003_auto_20210630_1624.py deleted file mode 100644 index d835e908..00000000 --- a/training/migrations/0003_auto_20210630_1624.py +++ /dev/null @@ -1,19 +0,0 @@ -# Generated by Django 3.1.5 on 2021-06-30 15:24 - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('training', '0002_auto_20210630_1514'), - ] - - operations = [ - migrations.AlterField( - model_name='trainingitem', - name='category', - field=models.ForeignKey(on_delete=django.db.models.deletion.RESTRICT, related_name='items', to='training.trainingcategory'), - ), - ] diff --git a/training/migrations/0004_auto_20210630_1641.py b/training/migrations/0004_auto_20210630_1641.py deleted file mode 100644 index 339f6b18..00000000 --- a/training/migrations/0004_auto_20210630_1641.py +++ /dev/null @@ -1,23 +0,0 @@ -# Generated by Django 3.1.5 on 2021-06-30 15:41 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('training', '0003_auto_20210630_1624'), - ] - - operations = [ - migrations.RenameField( - model_name='trainingcategory', - old_name='number', - new_name='reference_number', - ), - migrations.RenameField( - model_name='trainingitem', - old_name='number', - new_name='reference_number', - ), - ] diff --git a/training/models.py b/training/models.py index baf4b621..0fd5b201 100644 --- a/training/models.py +++ b/training/models.py @@ -9,7 +9,7 @@ class Trainee(Profile): proxy = True def get_records_of_depth(self, depth): - return self.training_items.filter(depth=depth) + return self.qualifications_obtained.filter(depth=depth) # Items class TrainingCategory(models.Model): @@ -37,12 +37,12 @@ class TrainingItemQualification(models.Model): (PASSED_OUT, 'Passed Out'), ) item = models.ForeignKey('TrainingItem', on_delete=models.RESTRICT) - trainee = models.ForeignKey('Trainee', related_name='training_items', on_delete=models.RESTRICT) + trainee = models.ForeignKey('Trainee', related_name='qualifications_obtained', on_delete=models.RESTRICT) depth = models.IntegerField(choices=CHOICES) - date = models.DateTimeField() + date = models.DateField() # TODO Remember that some training is external. Support for making an organisation the trainer? - supervisor = models.ForeignKey('Trainee', related_name='training_started', on_delete=models.RESTRICT) - notes = models.TextField() + supervisor = models.ForeignKey('Trainee', related_name='qualifications_granted', on_delete=models.RESTRICT) + notes = models.TextField(blank=True) # Levels diff --git a/training/templates/edit_training_record.html b/training/templates/edit_training_record.html new file mode 100644 index 00000000..389334c1 --- /dev/null +++ b/training/templates/edit_training_record.html @@ -0,0 +1,57 @@ +{% extends 'base_rigs.html' %} + +{% load static %} +{% load widget_tweaks %} + +{% block css %} + {{ block.super }} + +{% endblock %} + +{% block preload_js %} + {{ block.super }} + +{% endblock %} + +{% block js %} + {{ block.super }} + + +{% endblock %} + +{% block content %} +{% if form.errors %} + {% include 'form_errors.html' %} +{% endif %} +{% csrf_token %} + {% render_field form.trainee|attr:'hidden' value=form.trainee.initial %} +
+ + +
+
+ + {% render_field form.depth|add_class:'form-control custom-select selectpicker col-sm' %} +
+
+ + +
+
+ +
+ {% render_field form.date|add_class:'form-control'|attr:'type="date"' %} +
+
+
+ +
+ +
+
+ +
+{% endblock %} diff --git a/training/templates/session_log_form.html b/training/templates/session_log_form.html index ab6638f2..739ecf03 100644 --- a/training/templates/session_log_form.html +++ b/training/templates/session_log_form.html @@ -1,6 +1,7 @@ {% extends 'base_rigs.html' %} {% load static %} +{% load button from filters %} {% block css %} {{ block.super }} @@ -23,11 +24,30 @@
+

People

+
+ + +
-
+

Training Items

+
+ {% for depth in depths %} +
+

{{ depth.1 }}

+ +
+ {% endfor %} +
+
+ {% button 'submit' %} +
diff --git a/training/templates/trainee_detail.html b/training/templates/trainee_detail.html index 7c3639c2..f4aca630 100644 --- a/training/templates/trainee_detail.html +++ b/training/templates/trainee_detail.html @@ -1,6 +1,11 @@ {% extends 'base_rigs.html' %} {% block content %} +

Training Levels

{{ user.name }} is a...

diff --git a/training/urls.py b/training/urls.py index 46c03358..88d3bbbd 100644 --- a/training/urls.py +++ b/training/urls.py @@ -12,5 +12,7 @@ urlpatterns = [ path('trainee//', permission_required_with_403('RIGS.view_profile')(views.TraineeDetail.as_view()), name='trainee_detail'), + path('trainee//edit/', views.AddQualification.as_view(), + name='edit_record'), path('session/', views.SessionLog.as_view(), name='session_log'), ] diff --git a/training/views.py b/training/views.py index 0aab5e14..585b6c88 100644 --- a/training/views.py +++ b/training/views.py @@ -1,6 +1,8 @@ from django.shortcuts import render +from django.urls import reverse_lazy from django.views import generic +from PyRIGS.views import OEmbedView, is_ajax from training import models, forms from users import views @@ -38,4 +40,29 @@ class SessionLog(generic.FormView): def get_context_data(self, **kwargs): context = super(SessionLog, self).get_context_data(**kwargs) context["page_title"] = "Log New Training Session" - + context["depths"] = models.TrainingItemQualification.CHOICES + return context + + +class AddQualification(generic.CreateView): + template_name = "edit_training_record.html" + model = models.TrainingItemQualification + form_class = forms.QualificationForm + + def get_context_data(self, **kwargs): + context = super(AddQualification, self).get_context_data(**kwargs) + # context["page_title"] = "Edit {}'s Training Record".format(self.object) + context["depths"] = models.TrainingItemQualification.CHOICES + if is_ajax(self.request): + context['override'] = "base_ajax.html" + else: + context['override'] = 'base_rigs.html' # TODO + return context + + def get_success_url(self): + return reverse_lazy('trainee_detail') + + def get_form_kwargs(self): + kwargs = super(AddQualification, self).get_form_kwargs() + kwargs['pk'] = self.kwargs['pk'] + return kwargs