models.py 3.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. # -*- coding: utf-8 -*-
  2. from __future__ import unicode_literals
  3. import datetime
  4. from django.db import models
  5. from django.db.models import Q
  6. class Offer(models.Model):
  7. """Description of an offer available to subscribers.
  8. Implementation notes:
  9. configuration_type store the model name of the configuration backend
  10. (ex VPNConfiguration).
  11. The choices list is dynamically generated at start in the __init__
  12. """
  13. name = models.CharField(max_length=255, blank=False, null=False,
  14. verbose_name="nom de l'offre")
  15. configuration_type = models.CharField(max_length=50,
  16. blank=True,
  17. verbose_name='type de configuration',
  18. help_text="Type de configuration à utiliser avec cette offre")
  19. billing_period = models.IntegerField(blank=False, null=False, default=1,
  20. verbose_name='période de facturation',
  21. help_text='en mois')
  22. period_fees = models.DecimalField(max_digits=5, decimal_places=2,
  23. blank=False, null=False,
  24. verbose_name='montant par période de '
  25. 'facturation',
  26. help_text='en €')
  27. initial_fees = models.DecimalField(max_digits=5, decimal_places=2,
  28. blank=False, null=False,
  29. verbose_name='frais de mise en service',
  30. help_text='en €')
  31. def get_configuration_type_display(self):
  32. """
  33. Renvoi le nom affichable du type de configuration
  34. """
  35. from coin.configuration.models import Configuration
  36. for item in Configuration.get_configurations_choices_list():
  37. if item and self.configuration_type in item:
  38. return item[1]
  39. return self.configuration_type
  40. get_configuration_type_display.short_description = 'type de configuration'
  41. def __unicode__(self):
  42. return '{name} - {period_fee}€ / {billing_period}m'.format(
  43. name=self.name,
  44. period_fee=self.period_fees,
  45. billing_period=self.billing_period)
  46. class Meta:
  47. verbose_name = 'offre'
  48. class OfferSubscription(models.Model):
  49. """Only contains administrative details about a subscription, not
  50. technical. Nothing here should end up into the LDAP backend.
  51. Implementation notes: the Configuration model (which actually implementing the backend
  52. (technical configuration for the technology)) relate to this class
  53. with a OneToOneField
  54. """
  55. subscription_date = models.DateField(
  56. null=False,
  57. blank=False,
  58. default=datetime.date.today,
  59. verbose_name="date de souscription à l'offre")
  60. # TODO: for data retention, prevent deletion of a subscription object
  61. # while the resign date is recent enough (e.g. one year in France).
  62. resign_date = models.DateField(
  63. null=True,
  64. blank=True,
  65. verbose_name='date de résiliation')
  66. # TODO: move this to offers?
  67. commitment = models.IntegerField(blank=False, null=False,
  68. verbose_name="période d'engagement",
  69. help_text = 'en mois',
  70. default=0)
  71. member = models.ForeignKey('members.Member', verbose_name='membre')
  72. offer = models.ForeignKey('Offer', verbose_name='offre')
  73. def __unicode__(self):
  74. return '%s - %s - %s' % (self.member, self.offer.name,
  75. self.subscription_date)
  76. class Meta:
  77. verbose_name = 'abonnement'
  78. def count_active_subscriptions():
  79. today = datetime.date.today()
  80. query = Q(subscription_date__lte=today) & (Q(resign_date__isnull=True) | Q(resign_date__gte=today))
  81. return OfferSubscription.objects.filter(query).count()