models.py 2.4 KB

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