models.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. from django.db import models
  2. from django.contrib.contenttypes.models import ContentType
  3. from django.contrib.contenttypes.fields import GenericForeignKey
  4. from dateutil.relativedelta import relativedelta
  5. class AuthoringDatesModel(models.Model):
  6. created_at = models.DateTimeField(auto_now_add=True, null=True)
  7. modified_at = models.DateTimeField(auto_now=True)
  8. class Meta:
  9. abstract = True
  10. class Source(AuthoringDatesModel):
  11. name = models.CharField(max_length=150)
  12. def __str__(self):
  13. return self.name
  14. class OnlineSource(Source):
  15. url = models.URLField(max_length=200)
  16. class PhysicalSource(Source):
  17. # TODO auto add coordinates by searching shop address
  18. latitude = models.FloatField()
  19. longitude = models.FloatField()
  20. class Category(AuthoringDatesModel):
  21. name = models.CharField(max_length=150)
  22. type = models.CharField(
  23. max_length=20,
  24. choices=[
  25. ("Fixed", "Fixed expense"),
  26. ("Variable", "Variable expense"),
  27. ],
  28. default="Variable",
  29. )
  30. # Surcharge de la manière d'afficher un objet sensor
  31. def __str__(self):
  32. return self.name
  33. class Meta:
  34. # db_table = 'book' # Permet de personnaliser le nom de la table en BDD
  35. verbose_name = "Category" # Le nom lisbile du modèle
  36. verbose_name_plural = "Categories" # Le nom au pluriel du modèle
  37. ordering = ("name", "type") # Le tri par défaut dans les listes
  38. class MetaExpense(AuthoringDatesModel):
  39. category = models.ForeignKey(
  40. Category,
  41. related_name="%(app_label)s_%(class)s_related",
  42. on_delete=models.PROTECT,
  43. )
  44. source = models.ForeignKey(
  45. Source, related_name="%(app_label)s_%(class)s_related", on_delete=models.PROTECT
  46. )
  47. class Meta:
  48. abstract = True
  49. class RawExpense(models.Model):
  50. name = models.CharField(max_length=150)
  51. date = models.DateField()
  52. amount = models.DecimalField(max_digits=10, decimal_places=2)
  53. class LoneExpense(RawExpense, MetaExpense):
  54. def __str__(self):
  55. return self.name
  56. class Meta:
  57. # db_table = 'book' # Permet de personnaliser le nom de la table en BDD
  58. verbose_name = "LoneExpense" # Le nom lisbile du modèle
  59. verbose_name_plural = "LoneExpenses" # Le nom au pluriel du modèle
  60. ordering = ("name", "date", "amount") # Le tri par défaut dans les listes
  61. class Expense(models.Model):
  62. object_id = models.PositiveIntegerField()
  63. content_type = models.ForeignKey(
  64. ContentType,
  65. related_name="%(app_label)s_%(class)s_related",
  66. on_delete=models.CASCADE,
  67. )
  68. content_object = GenericForeignKey("content_type", "object_id")
  69. # Surcharge de la manière d'afficher un objet sensor
  70. def __str__(self):
  71. return self.content_object.name
  72. class Meta:
  73. # db_table = 'book' # Permet de personnaliser le nom de la table en BDD
  74. verbose_name = "Expense" # Le nom lisbile du modèle
  75. verbose_name_plural = "Expenses" # Le nom au pluriel du modèle
  76. """ ordering = ("name", "date", "amount") # Le tri par défaut dans les listes """
  77. class MultiplePaymentExepense(LoneExpense):
  78. payments = models.ManyToManyField(
  79. RawExpense, related_name="multiple_payment_expense"
  80. )
  81. number_of_payment = models.PositiveIntegerField()
  82. def set_payments(self, payment):
  83. payment.date = self.date
  84. payment.name = self.name + " 1st payment"
  85. payment.save()
  86. self.payments.add(payment)
  87. rest_to_pay = (self.amount - payment.amount) / (self.number_of_payment - 1)
  88. for i in range(1, self.number_of_payment):
  89. date = self.date + relativedelta(months=i)
  90. payment = RawExpense(
  91. name=f"{self.name} {i} payment", date=date, amount=rest_to_pay
  92. )
  93. payment.save()
  94. self.payments.add(payment)
  95. self.save()
  96. print(self.payments.count())
  97. def __str__(self):
  98. return self.name
  99. class Meta:
  100. # db_table = 'book' # Permet de personnaliser le nom de la table en BDD
  101. verbose_name = "MultiplePaymentExpense" # Le nom lisbile du modèle
  102. verbose_name_plural = "MultiplePaymentExpenses" # Le nom au pluriel du modèle
  103. ordering = ("name", "date", "amount")