models.py 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. from django.conf import settings
  2. from django.core.exceptions import ValidationError
  3. from django.db import models
  4. from .validators import less_than_one
  5. class AbstractItem(models.Model):
  6. name = models.CharField(max_length=130)
  7. description = models.TextField(blank=True)
  8. def __str__(self):
  9. return self.name
  10. class Meta:
  11. abstract = True
  12. class Cost(AbstractItem):
  13. """ A monthtly cost we have to pay
  14. """
  15. price = models.PositiveIntegerField(help_text="Coût mensuel")
  16. class Meta:
  17. verbose_name = 'Coût'
  18. def used(self):
  19. sharing_costs = CostUse.objects.filter(resource=self)
  20. existing_uses_sum = sum(
  21. sharing_costs.values_list('share', flat=True))
  22. return existing_uses_sum
  23. class Good(AbstractItem):
  24. """ A good, which replacement is provisioned
  25. """
  26. price = models.PositiveIntegerField()
  27. provisioning_duration = models.DurationField(
  28. choices=settings.PROVISIONING_DURATIONS)
  29. def get_use_class(self):
  30. return GoodUse
  31. def monthly_provision(self):
  32. return self.price/self.provisioning_duration.days*(365.25/12)
  33. class Meta:
  34. verbose_name = 'Bien'
  35. class AbstractUse(models.Model):
  36. share = models.FloatField(validators=[less_than_one])
  37. service = models.ForeignKey('Service')
  38. class Meta:
  39. abstract = True
  40. def clean(self):
  41. if hasattr(self, 'resource'):
  42. if (self.resource.used() + self.share) > 1:
  43. raise ValidationError(
  44. "Cannot use more than 100% of {})".format(self.resource))
  45. class CostUse(AbstractUse):
  46. resource = models.ForeignKey(Cost)
  47. def cost_share(self):
  48. return self.share*self.resource.price
  49. class GoodUse(AbstractUse):
  50. resource = models.ForeignKey(Good)
  51. def monthly_provision_share(self):
  52. return self.real_share()*self.resource.monthly_provision()
  53. class Service(AbstractItem):
  54. """ A service we sell
  55. (considered monthly)
  56. """
  57. costs = models.ManyToManyField(
  58. Cost,
  59. through=CostUse,
  60. related_name='using_services')
  61. goods = models.ManyToManyField(
  62. Good,
  63. through=GoodUse,
  64. related_name='using_services')
  65. # services = models.ManyToMany('Service') #TODO