models.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. # -*- coding: utf-8 -*-
  2. import datetime
  3. import calendar
  4. import random
  5. from decimal import Decimal
  6. from django.db import models
  7. from coin.offers.models import Offer
  8. from coin.members.models import Member
  9. class Invoice(models.Model):
  10. INVOICES_STATUS_CHOICES = (
  11. ('open', u'A payer'),
  12. ('closed', u'Reglée'),
  13. ('trouble', u'Litige')
  14. )
  15. number = models.CharField(max_length=25,
  16. default=lambda:Invoice.next_invoice_number(),
  17. unique=True,
  18. verbose_name='Numéro')
  19. status = models.CharField(max_length=50, choices=INVOICES_STATUS_CHOICES,
  20. default='open',
  21. verbose_name='Statut')
  22. date = models.DateField(default=datetime.date.today, null=True)
  23. date_due = models.DateField(
  24. default=(datetime.date(datetime.date.today().year,
  25. datetime.date.today().month + 1, 1) -
  26. datetime.timedelta(days=1)),
  27. null=True,
  28. verbose_name=u'Date d\'échéance de paiement')
  29. member = models.ForeignKey(Member, null=True, blank=True, default=None,
  30. verbose_name='Membre', on_delete=models.SET_NULL)
  31. def amount(self):
  32. "Calcul le montant de la facture en fonction des éléments de détails"
  33. total = Decimal('0.0')
  34. for detail in self.details.all():
  35. total += detail.total()
  36. return total.quantize(Decimal('0.01'))
  37. def has_owner(self, uid):
  38. "Check if passed uid (ex gmajax) is owner of the invoice"
  39. return self.member.ldap_cn == uid
  40. @staticmethod
  41. def next_invoice_number():
  42. "Détermine un numéro de facture aléatoire"
  43. return u'%s%02i-%i-%i' % (datetime.date.today().year,
  44. datetime.date.today().month,
  45. random.randrange(100, 999),
  46. random.randrange(100, 999))
  47. def __unicode__(self):
  48. return u'#%s %0.2f€ %s' % (self.number, self.amount(), self.date_due)
  49. class Meta:
  50. verbose_name = 'facture'
  51. class InvoiceDetail(models.Model):
  52. label = models.CharField(max_length=100)
  53. amount = models.DecimalField(max_digits=5, decimal_places=2,
  54. verbose_name='Montant')
  55. quantity = models.IntegerField(null=True, verbose_name=u'Quantité',
  56. default=1)
  57. tax = models.DecimalField(null=True, default=0.0, decimal_places=2,
  58. max_digits=4, verbose_name='TVA',
  59. help_text='en %')
  60. invoice = models.ForeignKey(Invoice, verbose_name='Facture',
  61. related_name='details')
  62. offer = models.ForeignKey(Offer, null=True, blank=True, default=None,
  63. verbose_name='Offre')
  64. period_from = models.DateField(
  65. default=datetime.date(datetime.date.today().year,
  66. datetime.date.today().month, 1),
  67. null=True,
  68. blank=True,
  69. verbose_name=u'Début de période',
  70. help_text=u'Date de début de période sur laquelle est facturé cet item')
  71. period_to = models.DateField(
  72. default=(datetime.date(datetime.date.today().year,
  73. datetime.date.today().month + 1, 1) -
  74. datetime.timedelta(days=1)),
  75. null=True,
  76. blank=True,
  77. verbose_name=u'Fin de période',
  78. help_text=u'Date de fin de période sur laquelle est facturé cet item')
  79. def __unicode__(self):
  80. return self.label
  81. def total(self):
  82. "Calcul le total"
  83. return (self.amount * (self.tax / Decimal('100.0') +
  84. Decimal('1.0')) * self.quantity).quantize(Decimal('0.01'))
  85. class Meta:
  86. verbose_name = 'détail de facture'
  87. class Payment(models.Model):
  88. PAYMENT_MEAN_CHOICES = (
  89. ('cash', u'Espèces'),
  90. ('check', u'Chèque'),
  91. ('transfer', u'Virement'),
  92. ('other', u'Autre')
  93. )
  94. payment_mean = models.CharField(max_length=100, null=True,
  95. default='transfer',
  96. choices=PAYMENT_MEAN_CHOICES,
  97. verbose_name='Moyen de paiement')
  98. amount = models.DecimalField(max_digits=7, decimal_places=2, null=True,
  99. verbose_name='Montant')
  100. date = models.DateField(default=datetime.date.today)
  101. invoice = models.ForeignKey(Invoice, verbose_name='Facture')
  102. class Meta:
  103. verbose_name = 'paiement'