Parcourir la source

Fix usage completion on *Use saving.

Was failing on edition because a *Use was counting itself two times in the math
to see if usage was above 1.
Jocelyn Delande il y a 9 ans
Parent
commit
9270e47adb
2 fichiers modifiés avec 33 ajouts et 8 suppressions
  1. 22 8
      costs/models.py
  2. 11 0
      costs/tests/test_models.py

+ 22 - 8
costs/models.py

@@ -13,6 +13,25 @@ class AbstractItem(models.Model):
     def __str__(self):
         return self.name
 
+    def get_use_class(self):
+        raise NotImplemented
+
+    def used(self, except_by=None):
+        """ Return the used fraction of an item
+
+        :type: Service
+        :param except_by: exclude this service from the math
+        :rtype: float
+        """
+        sharing_costs = self.get_use_class().objects.filter(resource=self)
+        if except_by:
+            sharing_costs = sharing_costs.exclude(service=except_by)
+
+        existing_uses_sum = sum(
+            sharing_costs.values_list('share', flat=True))
+
+        return existing_uses_sum
+
     class Meta:
         abstract = True
 
@@ -22,17 +41,12 @@ class Cost(AbstractItem):
     """
     price = models.FloatField(help_text="Coût mensuel")
 
+    def get_use_class(self):
+        return CostUse
 
     class Meta:
         verbose_name = 'Coût'
 
-    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
@@ -60,7 +74,7 @@ class AbstractUse(models.Model):
 
     def clean(self):
         if hasattr(self, 'resource'):
-            if (self.resource.used() + self.share) > 1:
+            if (self.resource.used(except_by=self.service) + self.share) > 1:
                 raise ValidationError(
                     "Cannot use more than 100% of {})".format(self.resource))
 

+ 11 - 0
costs/tests/test_models.py

@@ -69,3 +69,14 @@ class AbstractUseTests(TestCase):
         with self.assertRaises(ValidationError):
             u2.full_clean()
             u2.save()
+
+    def test_modify_service_share_no_error(self):
+        u1 = CostUse(
+            service=self.hosting_service,
+            resource=self.datacenter_cost,
+            share=1)
+
+        u1.full_clean()
+        u1.save()
+        u1.full_clean()
+        u1.save()