from django.conf import settings from django.core.exceptions import ValidationError from django.db import models from .validators import less_than_one class AbstractItem(models.Model): name = models.CharField(max_length=130) description = models.TextField(blank=True) class Meta: abstract = True class Cost(AbstractItem): """ A monthtly cost we have to pay """ price = models.PositiveIntegerField() def used(self): sharing_costs = CostUse.objects.filter(resource=self) existing_uses_sum = sum( sharing_costs.values_list('share', flat=True)) return existing_uses_sum class Good(AbstractItem): """ A good, which replacement is provisioned """ price = models.PositiveIntegerField() provisioning_duration = models.DurationField( choices=settings.PROVISIONING_DURATIONS) class AbstractUse(models.Model): share = models.FloatField(validators=[less_than_one]) service = models.ForeignKey('Service') class Meta: abstract = True def clean(self): if (self.resource.used() + self.share) > 1: raise ValidationError( "Cannot use more than 100% of {})".format(self.resource)) class CostUse(AbstractUse): resource = models.ForeignKey(Cost) class GoodUse(AbstractUse): resource = models.ForeignKey(Good) class Service(AbstractItem): """ A service we sell (considered monthly) """ costs = models.ManyToManyField( Cost, through=CostUse, related_name='using_services') goods = models.ManyToManyField( Good, through=GoodUse, related_name='using_services') # services = models.ManyToMany('Service') #TODO