mirror of
https://gitlab.crans.org/bde/nk20
synced 2025-06-21 01:48:21 +02:00
happy new year (contain annually WEI change and update to follow Django Style Guide)
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
# Copyright (C) 2018-2023 by BDE ENS Paris-Saclay
|
||||
# Copyright (C) 2018-2024 by BDE ENS Paris-Saclay
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
from datetime import date
|
||||
|
||||
@ -20,7 +20,6 @@ class Invoice(models.Model):
|
||||
"""
|
||||
An invoice model that can generates a true invoice.
|
||||
"""
|
||||
|
||||
id = models.PositiveIntegerField(
|
||||
primary_key=True,
|
||||
verbose_name=_("Invoice identifier"),
|
||||
@ -81,6 +80,13 @@ class Invoice(models.Model):
|
||||
verbose_name=_("tex source"),
|
||||
)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("invoice")
|
||||
verbose_name_plural = _("invoices")
|
||||
|
||||
def __str__(self):
|
||||
return _("Invoice #{id}").format(id=self.id)
|
||||
|
||||
@transaction.atomic
|
||||
def save(self, *args, **kwargs):
|
||||
"""
|
||||
@ -111,19 +117,11 @@ class Invoice(models.Model):
|
||||
|
||||
return super().save(*args, **kwargs)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("invoice")
|
||||
verbose_name_plural = _("invoices")
|
||||
|
||||
def __str__(self):
|
||||
return _("Invoice #{id}").format(id=self.id)
|
||||
|
||||
|
||||
class Product(models.Model):
|
||||
"""
|
||||
Product that appears on an invoice.
|
||||
"""
|
||||
|
||||
invoice = models.ForeignKey(
|
||||
Invoice,
|
||||
on_delete=models.CASCADE,
|
||||
@ -147,6 +145,13 @@ class Product(models.Model):
|
||||
verbose_name=_("Unit price"),
|
||||
)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("product")
|
||||
verbose_name_plural = _("products")
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.designation} ({self.invoice})"
|
||||
|
||||
@property
|
||||
def amount_euros(self):
|
||||
return "{:.2f}".format(self.amount / 100)
|
||||
@ -159,37 +164,28 @@ class Product(models.Model):
|
||||
def total_euros(self):
|
||||
return "{:.2f}".format(self.total / 100)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("product")
|
||||
verbose_name_plural = _("products")
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.designation} ({self.invoice})"
|
||||
|
||||
|
||||
class RemittanceType(models.Model):
|
||||
"""
|
||||
Store what kind of remittances can be stored.
|
||||
"""
|
||||
|
||||
note = models.OneToOneField(
|
||||
NoteSpecial,
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return str(self.note)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("remittance type")
|
||||
verbose_name_plural = _("remittance types")
|
||||
|
||||
def __str__(self):
|
||||
return str(self.note)
|
||||
|
||||
|
||||
class Remittance(models.Model):
|
||||
"""
|
||||
Treasurers want to regroup checks or bank transfers in bank remittances.
|
||||
"""
|
||||
|
||||
date = models.DateTimeField(
|
||||
default=timezone.now,
|
||||
verbose_name=_("Date"),
|
||||
@ -215,6 +211,17 @@ class Remittance(models.Model):
|
||||
verbose_name = _("remittance")
|
||||
verbose_name_plural = _("remittances")
|
||||
|
||||
def __str__(self):
|
||||
return _("Remittance #{:d}: {}").format(self.id, self.comment, )
|
||||
|
||||
@transaction.atomic
|
||||
def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
|
||||
# Check if all transactions have the right type.
|
||||
if self.transactions.exists() and self.transactions.filter(~Q(source=self.remittance_type.note)).exists():
|
||||
raise ValidationError("All transactions in a remittance must have the same type")
|
||||
|
||||
return super().save(force_insert, force_update, using, update_fields)
|
||||
|
||||
@property
|
||||
def transactions(self):
|
||||
"""
|
||||
@ -237,17 +244,6 @@ class Remittance(models.Model):
|
||||
"""
|
||||
return sum(transaction.total for transaction in self.transactions.all())
|
||||
|
||||
@transaction.atomic
|
||||
def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
|
||||
# Check if all transactions have the right type.
|
||||
if self.transactions.exists() and self.transactions.filter(~Q(source=self.remittance_type.note)).exists():
|
||||
raise ValidationError("All transactions in a remittance must have the same type")
|
||||
|
||||
return super().save(force_insert, force_update, using, update_fields)
|
||||
|
||||
def __str__(self):
|
||||
return _("Remittance #{:d}: {}").format(self.id, self.comment, )
|
||||
|
||||
|
||||
class SpecialTransactionProxy(models.Model):
|
||||
"""
|
||||
@ -255,7 +251,6 @@ class SpecialTransactionProxy(models.Model):
|
||||
That's why we create a proxy in this app, to link special transactions and remittances.
|
||||
If it isn't very clean, it does what we want.
|
||||
"""
|
||||
|
||||
transaction = models.OneToOneField(
|
||||
SpecialTransaction,
|
||||
on_delete=models.CASCADE,
|
||||
@ -301,6 +296,43 @@ class SogeCredit(models.Model):
|
||||
null=True,
|
||||
)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("Credit from the Société générale")
|
||||
verbose_name_plural = _("Credits from the Société générale")
|
||||
|
||||
def __str__(self):
|
||||
return _("Soge credit for {user}").format(user=str(self.user))
|
||||
|
||||
@transaction.atomic
|
||||
def save(self, *args, **kwargs):
|
||||
# This is a pre-registered user that declared that a SoGé account was opened.
|
||||
# No note exists yet.
|
||||
if not NoteUser.objects.filter(user=self.user).exists():
|
||||
return super().save(*args, **kwargs)
|
||||
|
||||
if not self.credit_transaction:
|
||||
credit_transaction = SpecialTransaction(
|
||||
source=NoteSpecial.objects.get(special_type="Virement bancaire"),
|
||||
destination=self.user.note,
|
||||
quantity=1,
|
||||
amount=0,
|
||||
reason="Crédit société générale",
|
||||
last_name=self.user.last_name,
|
||||
first_name=self.user.first_name,
|
||||
bank="Société générale",
|
||||
valid=False,
|
||||
)
|
||||
credit_transaction._force_save = True
|
||||
credit_transaction.save()
|
||||
credit_transaction.refresh_from_db()
|
||||
self.credit_transaction = credit_transaction
|
||||
elif not self.valid:
|
||||
self.credit_transaction.amount = self.amount
|
||||
self.credit_transaction._force_save = True
|
||||
self.credit_transaction.save()
|
||||
|
||||
return super().save(*args, **kwargs)
|
||||
|
||||
@property
|
||||
def valid(self):
|
||||
return self.credit_transaction and self.credit_transaction.valid
|
||||
@ -390,36 +422,6 @@ class SogeCredit(models.Model):
|
||||
tr._force_save = True
|
||||
tr.save()
|
||||
|
||||
@transaction.atomic
|
||||
def save(self, *args, **kwargs):
|
||||
# This is a pre-registered user that declared that a SoGé account was opened.
|
||||
# No note exists yet.
|
||||
if not NoteUser.objects.filter(user=self.user).exists():
|
||||
return super().save(*args, **kwargs)
|
||||
|
||||
if not self.credit_transaction:
|
||||
credit_transaction = SpecialTransaction(
|
||||
source=NoteSpecial.objects.get(special_type="Virement bancaire"),
|
||||
destination=self.user.note,
|
||||
quantity=1,
|
||||
amount=0,
|
||||
reason="Crédit société générale",
|
||||
last_name=self.user.last_name,
|
||||
first_name=self.user.first_name,
|
||||
bank="Société générale",
|
||||
valid=False,
|
||||
)
|
||||
credit_transaction._force_save = True
|
||||
credit_transaction.save()
|
||||
credit_transaction.refresh_from_db()
|
||||
self.credit_transaction = credit_transaction
|
||||
elif not self.valid:
|
||||
self.credit_transaction.amount = self.amount
|
||||
self.credit_transaction._force_save = True
|
||||
self.credit_transaction.save()
|
||||
|
||||
return super().save(*args, **kwargs)
|
||||
|
||||
def delete(self, **kwargs):
|
||||
"""
|
||||
Deleting a SogeCredit is equivalent to say that the Société générale didn't pay.
|
||||
@ -447,10 +449,3 @@ class SogeCredit(models.Model):
|
||||
self.credit_transaction._force_save = True
|
||||
self.credit_transaction.save()
|
||||
super().delete(**kwargs)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("Credit from the Société générale")
|
||||
verbose_name_plural = _("Credits from the Société générale")
|
||||
|
||||
def __str__(self):
|
||||
return _("Soge credit for {user}").format(user=str(self.user))
|
||||
|
Reference in New Issue
Block a user