From 71aac73525fe64f61fab8208c87c9e9fcea1afcc Mon Sep 17 00:00:00 2001 From: Guillaume Pellerin Date: Fri, 1 Jul 2016 12:54:07 +0200 Subject: [PATCH] add accounting info on XLS export, add payment type --- teleforma/models/core.py | 21 +++++------ teleforma/models/crfpa.py | 77 +++++++++++++++++++++------------------ teleforma/views/crfpa.py | 26 +++++++++---- 3 files changed, 70 insertions(+), 54 deletions(-) diff --git a/teleforma/models/core.py b/teleforma/models/core.py index 51f0bf0d..97ef66ab 100644 --- a/teleforma/models/core.py +++ b/teleforma/models/core.py @@ -70,6 +70,7 @@ session_choices = get_n_choices(8) server_choices = [('icecast', 'icecast'), ('stream-m', 'stream-m')] streaming_choices = [('mp3', 'mp3'), ('ogg', 'ogg'), ('webm', 'webm'), ('mp4', 'mp4')] mimetypes.add_type('video/webm','.webm') +payment_choices = [('check', _('check')), ('tranfer', _('transfer')), ('credit card', _('credit card')), ('money', _('money'))] STATUS_CHOICES = ( (0, _('Hidden')), @@ -88,10 +89,10 @@ class MetaCore: app_label = app_label -class Organization(Model): +class Organization(models.Model): - name = models.CharField(_('name'), max_length=255) - description = models.CharField(_('description'), max_length=255, blank=True) + name = models.CharField(_('name'), max_length=255) + description = models.CharField(_('description'), max_length=255, blank=True) def __unicode__(self): return self.name @@ -101,15 +102,13 @@ class Organization(Model): verbose_name = _('organization') -class Department(Model): +class Department(models.Model): - name = models.CharField(_('name'), max_length=255) - description = models.CharField(_('description'), max_length=255, blank=True) - organization = models.ForeignKey('Organization', related_name='department', - verbose_name=_('organization')) - domain = models.CharField(_('Master domain'), max_length=255, blank=True) - default_period = models.ForeignKey('Period', related_name='department', verbose_name=_('period'), - null=True, blank=True, on_delete=models.SET_NULL) + name = models.CharField(_('name'), max_length=255) + description = models.CharField(_('description'), max_length=255, blank=True) + organization = models.ForeignKey('Organization', related_name='department', verbose_name=_('organization')) + domain = models.CharField(_('Master domain'), max_length=255, blank=True) + default_period = models.ForeignKey('Period', related_name='department', verbose_name=_('period'), null=True, blank=True, on_delete=models.SET_NULL) def __unicode__(self): return self.name diff --git a/teleforma/models/crfpa.py b/teleforma/models/crfpa.py index 904f7e19..e1af036c 100644 --- a/teleforma/models/crfpa.py +++ b/teleforma/models/crfpa.py @@ -40,7 +40,6 @@ from telemeta.models.core import * from teleforma.models.core import * - class IEJ(Model): name = models.CharField(_('name'), max_length=255) @@ -58,18 +57,16 @@ class IEJ(Model): class Training(Model): - code = models.CharField(_('code'), max_length=255) - name = models.CharField(_('name'), max_length=255, blank=True) - description = models.CharField(_('description'), max_length=512, blank=True) - period = models.ForeignKey('Period', related_name='training', verbose_name=_('period'), - blank=True, null=True) - synthesis_note = models.ManyToManyField('CourseType', related_name="training_synthesis_note", - verbose_name=_('synthesis note'), + code = models.CharField(_('code'), max_length=255) + name = models.CharField(_('name'), max_length=255, blank=True) + description = models.CharField(_('description'), max_length=512, blank=True) + period = models.ForeignKey('Period', related_name='training', verbose_name=_('period'), blank=True, null=True) + synthesis_note = models.ManyToManyField('CourseType', related_name="training_synthesis_note", verbose_name=_('synthesis note'), blank=True, null=True) - obligation = models.ManyToManyField('CourseType', related_name="training_obligation", + obligation = models.ManyToManyField('CourseType', related_name="training_obligation", verbose_name=_('obligations'), blank=True, null=True) - procedure = models.ManyToManyField('CourseType', related_name="training_procedure", + procedure = models.ManyToManyField('CourseType', related_name="training_procedure", verbose_name=_('procedure'), blank=True, null=True) written_speciality = models.ManyToManyField('CourseType', related_name="training_written_speciality", @@ -78,20 +75,20 @@ class Training(Model): oral_speciality = models.ManyToManyField('CourseType', related_name="training_oral_speciality", verbose_name=_('oral speciality'), blank=True, null=True) - oral_1 = models.ManyToManyField('CourseType', related_name="training_oral_1", + oral_1 = models.ManyToManyField('CourseType', related_name="training_oral_1", verbose_name=_('oral 1'), blank=True, null=True) - oral_2 = models.ManyToManyField('CourseType', related_name="training_oral_2", + oral_2 = models.ManyToManyField('CourseType', related_name="training_oral_2", verbose_name=_('oral 2'), blank=True, null=True) - options = models.ManyToManyField('CourseType', related_name="training_options", + options = models.ManyToManyField('CourseType', related_name="training_options", verbose_name=_('options'), blank=True, null=True) - magistral = models.ManyToManyField('CourseType', related_name="training_magistral", + magistral = models.ManyToManyField('CourseType', related_name="training_magistral", verbose_name=_('magistral'), blank=True, null=True) - cost = models.FloatField(_('cost'), blank=True, null=True) - available = models.BooleanField(_('available')) + cost = models.FloatField(_('cost'), blank=True, null=True) + available = models.BooleanField(_('available')) def __unicode__(self): if self.name: @@ -113,14 +110,14 @@ class Training(Model): class Student(Model): "A student profile" - user = models.ForeignKey(User, related_name='student', verbose_name=_('user'), unique=True) - iej = models.ForeignKey('IEJ', related_name='student', verbose_name=_('iej'), + user = models.ForeignKey(User, related_name='student', verbose_name=_('user'), unique=True) + iej = models.ForeignKey('IEJ', related_name='student', verbose_name=_('iej'), blank=True, null=True, on_delete=models.SET_NULL) - trainings = models.ManyToManyField('Training', related_name='student_trainings', verbose_name=_('trainings'), + trainings = models.ManyToManyField('Training', related_name='student_trainings', verbose_name=_('trainings'), blank=True, null=True) - training = models.ForeignKey('Training', related_name='student_training', verbose_name=_('training'), + training = models.ForeignKey('Training', related_name='student_training', verbose_name=_('training'), blank=True, null=True, limit_choices_to={'available': True}) - procedure = models.ForeignKey('Course', related_name="procedure_students", + procedure = models.ForeignKey('Course', related_name="procedure_students", verbose_name=_('procedure'), help_text="Matière de procédure", blank=True, null=True, limit_choices_to={'procedure': True}) written_speciality = models.ForeignKey('Course', related_name="written_speciality_students", @@ -130,15 +127,15 @@ class Student(Model): verbose_name=_('oral speciality'), help_text="Matière d’oral de spécialité (matière incluse dans la formation approfondie, en option pour toutes les autres formations)", blank=True, null=True, limit_choices_to={'oral_speciality': True}) - oral_1 = models.ForeignKey('Course', related_name="oral_1_students", verbose_name=_('oral 1 (option)'), + oral_1 = models.ForeignKey('Course', related_name="oral_1_students", verbose_name=_('oral 1 (option)'), help_text="Matière d’oral technique 1 (en option)", blank=True, null=True, limit_choices_to={'oral_1': True}) - oral_2 = models.ForeignKey('Course', related_name="oral_2_students", verbose_name=_('oral 2 (option)'), + oral_2 = models.ForeignKey('Course', related_name="oral_2_students", verbose_name=_('oral 2 (option)'), help_text="Matière d’oral technique 2 (en option)", blank=True, null=True, limit_choices_to={'oral_2': True}) - options = models.ForeignKey('Course', related_name="options_students", verbose_name=_('options'), + options = models.ForeignKey('Course', related_name="options_students", verbose_name=_('options'), blank=True, null=True) - period = models.ForeignKey('Period', related_name='student', verbose_name=_('period'), + period = models.ForeignKey('Period', related_name='student', verbose_name=_('period'), blank=True, null=True, on_delete=models.SET_NULL) platform_only = models.BooleanField(_('e-learning platform only')) application_fees = models.BooleanField(_('application fees'), blank=True) @@ -177,6 +174,13 @@ class Student(Model): amount += payment.value return amount + @property + def total_discount(self): + amount = 0 + for discount in self.discounts.all(): + amount -= discount.value + return amount + @property def balance(self): return round(self.total_payments - self.total_fees, 2) @@ -194,18 +198,18 @@ class Student(Model): class Profile(models.Model): "User profile extension" - user = models.ForeignKey(User, related_name='profile', verbose_name=_('user'), unique=True) - address = models.TextField(_('Address'), blank=True) - postal_code = models.CharField(_('Postal code'), max_length=255, blank=True) - city = models.CharField(_('City'), max_length=255, blank=True) - country = models.CharField(_('Country'), max_length=255, blank=True) - language = models.CharField(_('Language'), max_length=255, blank=True) - telephone = models.CharField(_('Telephone'), max_length=255, blank=True) + user = models.ForeignKey(User, related_name='profile', verbose_name=_('user'), unique=True) + address = models.TextField(_('Address'), blank=True) + postal_code = models.CharField(_('Postal code'), max_length=255, blank=True) + city = models.CharField(_('City'), max_length=255, blank=True) + country = models.CharField(_('Country'), max_length=255, blank=True) + language = models.CharField(_('Language'), max_length=255, blank=True) + telephone = models.CharField(_('Telephone'), max_length=255, blank=True) expiration_date = models.DateField(_('Expiration_date'), blank=True, null=True) - init_password = models.BooleanField(_('Password initialized')) - wifi_login = models.CharField(_('WiFi login'), max_length=255, blank=True) - wifi_pass = models.CharField(_('WiFi pass'), max_length=255, blank=True) - birthday = models.DateField(_('birthday'), blank=True, null=True, help_text="jj/mm/aaaa") + init_password = models.BooleanField(_('Password initialized')) + wifi_login = models.CharField(_('WiFi login'), max_length=255, blank=True) + wifi_pass = models.CharField(_('WiFi pass'), max_length=255, blank=True) + birthday = models.DateField(_('birthday'), blank=True, null=True, help_text="jj/mm/aaaa") class Meta(MetaCore): db_table = app_label + '_' + 'profiles' @@ -224,6 +228,7 @@ class Payment(models.Model): value = models.FloatField(_('amount'), help_text='€') month = models.IntegerField(_('month'), choices=months_choices, default=1) collected = models.BooleanField(_('collected')) + type = models.CharField(_('payment type'), choices=payment_choices, max_length=64) date_created = models.DateTimeField(_('date created'), auto_now_add=True) date_modified = models.DateTimeField(_('date modified'), auto_now=True) diff --git a/teleforma/views/crfpa.py b/teleforma/views/crfpa.py index 64e34922..64827bd5 100644 --- a/teleforma/views/crfpa.py +++ b/teleforma/views/crfpa.py @@ -214,7 +214,7 @@ class UserXLSBook(object): def export_user(self, counter, user): student = Student.objects.filter(user=user) - if student: + if student and (student.training or student.trainings.all()): student = Student.objects.get(user=user) row = self.sheet.row(counter + self.first_row) row.write(0, user.last_name) @@ -247,12 +247,21 @@ class UserXLSBook(object): if student.date_subscribed: row.write(14, student.date_subscribed.strftime("%d/%m/%Y")) - row.write(15, student.total_payments) - row.write(16, student.total_fees) - row.write(17, student.balance) + if student.training: + training = student.training + else: + training = student.trainings.all()[0] + + row.write(15, training.cost) + row.write(16, student.total_discount) + row.write(17, ', '.join([discount.description for discount in student.discounts.all()])) + + row.write(18, student.total_payments) + row.write(19, student.total_fees) + row.write(20, student.balance) payments = student.payments.all() - i = 18 + i = 21 for month in months_choices: payment = payments.filter(month=month[0]) if payment: @@ -283,10 +292,14 @@ class UserXLSBook(object): {'name':'VILLE', 'width':5000}, {'name':'TEL', 'width':5000}, {'name':"Date d'inscription", 'width':5000}, + {'name':"Prix formation brut", 'width':4000}, + {'name':"Total réductions", 'width':4000}, + {'name':"Description réduction", 'width':4000}, {'name':"Total paiements", 'width':4000}, - {'name':"Total reductions", 'width':4000}, + {'name':"Prix formation net", 'width':4000}, {'name':"Balance", 'width':4000}, ] + for month in months_choices: cols.append({'name': 'Paiement ' + slugify(month[1]), 'width': 4000}) @@ -301,7 +314,6 @@ class UserXLSBook(object): counter = self.export_user(counter, user) - class UsersExportView(UsersView): @method_decorator(permission_required('is_staff')) -- 2.39.5