From 5fc33f9b44b2b708f42e5b2ef3bbcacaeb5096a1 Mon Sep 17 00:00:00 2001 From: alazo Date: Thu, 26 Apr 2018 07:54:29 +0200 Subject: [PATCH] Added supervision bill for student EDE --- stages/admin.py | 15 ++++++++++- .../0014_added_supervisionbill_model.py | 26 +++++++++++++++++++ stages/models.py | 14 ++++++++++ stages/tests.py | 22 +++++++++++++++- 4 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 stages/migrations/0014_added_supervisionbill_model.py diff --git a/stages/admin.py b/stages/admin.py index 8d3dd56..03bf70f 100644 --- a/stages/admin.py +++ b/stages/admin.py @@ -13,7 +13,7 @@ from django.utils.html import format_html from .models import ( Teacher, Option, Student, Section, Level, Klass, Corporation, CorpContact, Domain, Period, Availability, Training, Course, - LogBookReason, LogBook, ExamEDESession + LogBookReason, LogBook, ExamEDESession, SupervisionBill ) from .pdf import ChargeSheetPDF @@ -106,6 +106,11 @@ class TeacherAdmin(admin.ModelAdmin): inlines = [LogBookInline] +class SupervisionBillInline(admin.TabularInline): + model = SupervisionBill + extra = 0 + + class StudentAdmin(admin.ModelAdmin): list_display = ('__str__', 'pcode', 'city', 'klass', 'archived') ordering = ('last_name', 'first_name') @@ -139,6 +144,14 @@ class StudentAdmin(admin.ModelAdmin): }), ) actions = ['archive'] + inlines = [SupervisionBillInline] + + def get_inline_instances(self, request, obj=None): + # SupervisionBillInline is only adequate for EDE students + if obj is None or obj.klass.section.name != 'EDE': + return [] + return super().get_inline_instances(request, obj=obj) + def archive(self, request, queryset): for student in queryset: # Save each item individually to allow for custom save() logic. diff --git a/stages/migrations/0014_added_supervisionbill_model.py b/stages/migrations/0014_added_supervisionbill_model.py new file mode 100644 index 0000000..d891733 --- /dev/null +++ b/stages/migrations/0014_added_supervisionbill_model.py @@ -0,0 +1,26 @@ +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('stages', '0013_renamed_title_to_civility'), + ] + + operations = [ + migrations.CreateModel( + name='SupervisionBill', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('period', models.SmallIntegerField(default=0, verbose_name='période')), + ('date', models.DateField()), + ('student', models.ForeignKey(on_delete=models.deletion.CASCADE, to='stages.Student', verbose_name='étudiant')), + ('supervisor', models.ForeignKey(on_delete=models.deletion.CASCADE, to='stages.CorpContact', verbose_name='superviseur')), + ], + options={ + 'ordering': ['date'], + 'verbose_name': 'Facture de supervision', + 'verbose_name_plural': 'Factures de supervision', + }, + ), + ] diff --git a/stages/models.py b/stages/models.py index 2a3ca1e..2cdd861 100644 --- a/stages/models.py +++ b/stages/models.py @@ -566,3 +566,17 @@ class Course(models.Model): return '{0} - {1} - {2} - {3}'.format( self.teacher, self.public, self.subject, self.period ) + +class SupervisionBill(models.Model): + student = models.ForeignKey(Student, verbose_name='étudiant', on_delete=models.CASCADE) + supervisor = models.ForeignKey(CorpContact, verbose_name='superviseur', on_delete=models.CASCADE) + period = models.SmallIntegerField('période', default=0) + date = models.DateField() + + class Meta: + verbose_name = 'Facture de supervision' + verbose_name_plural = 'Factures de supervision' + ordering = ['date'] + + def __str__(self): + return '{0} : {1}'.format(self.student.full_name, self.supervisor.full_name) diff --git a/stages/tests.py b/stages/tests.py index b57a83a..8669721 100644 --- a/stages/tests.py +++ b/stages/tests.py @@ -81,7 +81,7 @@ class StagesTest(TestCase): Training.objects.create( availability=av3, student=Student.objects.get(first_name="André"), referent=ref1, ) - cls.admin = User.objects.create_user( + cls.admin = User.objects.create_superuser( 'me', 'me@example.org', 'mepassword', first_name='Jean', last_name='Valjean', ) @@ -103,6 +103,26 @@ class StagesTest(TestCase): response = self.client.get(reverse('general-export')) self.assertEqual(response.status_code, 200) + def test_student_change_view(self): + klass_ede = Klass.objects.create( + name="2EDEps", + section=Section.objects.get(name='EDE'), + level=Level.objects.get(name='2') + ) + student_ede = Student.objects.create( + first_name="Claire", last_name="Fontaine", birth_date="2000-01-02", + pcode="2000", city="Neuchâtel", klass=klass_ede + ) + response = self.client.get( + reverse("admin:stages_student_change", args=(student_ede.pk,)) + ) + self.assertContains(response, "Factures de supervision") + student_non_ede = Student.objects.exclude(klass__section__name='EDE').first() + response = self.client.get( + reverse("admin:stages_student_change", args=(student_non_ede.pk,)) + ) + self.assertNotContains(response, "Factures de supervision") + def test_attribution_view(self): response = self.client.get(reverse('attribution')) # Section select