Parcourir la source

Move costs math logic to Service.get_prices()

and added unit tests
Jocelyn Delande il y a 9 ans
Parent
commit
c394614343
3 fichiers modifiés avec 107 ajouts et 24 suppressions
  1. 26 0
      costs/models.py
  2. 76 1
      costs/tests/test_models.py
  3. 5 23
      costs/views.py

+ 26 - 0
costs/models.py

@@ -1,4 +1,5 @@
 import datetime
+from itertools import chain
 
 from django.conf import settings
 from django.core.exceptions import ValidationError
@@ -232,3 +233,28 @@ class Service(AbstractItem):
 
     def get_absolute_url(self):
         return reverse('detail-service', kwargs={'pk': self.pk})
+
+    def get_prices(self):
+        costs_uses = CostUse.objects.filter(service=self)
+        goods_uses = GoodUse.objects.filter(service=self)
+
+        total_costs_price = sum(chain(
+            (i.monthly_provision_share() for i in goods_uses),
+            (i.cost_share() for i in costs_uses),
+        ))
+
+        total_goods_value_share = sum(i.value_share() for i in goods_uses)
+
+        if self.subscriptions_count == 0:
+            unit_costs_price = 0
+            unit_goods_value_share = 0
+        else:
+            unit_costs_price = total_costs_price/self.subscriptions_count
+            unit_goods_value_share = \
+                total_goods_value_share/self.subscriptions_count
+        return {
+            'total_costs_price': total_costs_price,
+            'unit_costs_price': unit_costs_price,
+            'total_goods_value_share': total_goods_value_share,
+            'unit_goods_value_share': unit_goods_value_share,
+        }

+ 76 - 1
costs/tests/test_models.py

@@ -1,7 +1,82 @@
+import datetime
+
 from django.test import TestCase
 from django.core.exceptions import ValidationError
 
-from ..models import Service, Cost, CostUse, Document
+from ..models import (
+    Cost, CostUse, Document, Good, GoodUse, Service)
+
+
+class ServiceTests(TestCase):
+    def setUp(self):
+        self.doc = Document.objects.create(name='budget')
+        self.electricity_cost = Cost.objects.create(
+            name='electricity',
+            price=10,
+            document=self.doc,
+        )
+        self.server = Good.objects.create(
+            name="Computer",
+            price=10,
+            document=self.doc,
+            provisioning_duration=datetime.timedelta(days=365*3),
+        )
+
+    def test_get_prices_zero(self):
+        s = Service.objects.create(name='Foo', document=self.doc)
+        self.assertEqual(s.get_prices(), {
+            'total_costs_price': 0,
+            'unit_costs_price': 0,
+            'unit_goods_value_share': 0,
+            'total_goods_value_share': 0,
+        })
+
+    def test_get_prices_w_costs(self):
+        s = Service.objects.create(name='Foo', document=self.doc)
+
+        CostUse.objects.create(
+            service=s, resource=self.electricity_cost, share=0.4)
+
+        self.assertEqual(s.get_prices(), {
+            'total_costs_price': 10,
+            'unit_costs_price': 0,
+            'unit_goods_value_share': 0,
+            'total_goods_value_share': 0,
+        })
+
+        s.subscriptions_count = 2
+        s.save()
+
+        self.assertEqual(s.get_prices(), {
+            'total_costs_price': 10,
+            'unit_costs_price': 5,
+            'unit_goods_value_share': 0,
+            'total_goods_value_share': 0,
+        })
+
+    def test_get_prices_w_goods(self):
+        s = Service.objects.create(
+            name='Foo', document=self.doc, subscriptions_count=0)
+
+        GoodUse.objects.create(
+            service=s, resource=self.server, share=0.4)
+
+        self.assertEqual(s.get_prices(), {
+            'total_costs_price': 10/(365*3)*365.25/12,
+            'unit_costs_price': 0,
+            'unit_goods_value_share': 0,
+            'total_goods_value_share': 10.0,
+        })
+
+        s.subscriptions_count = 2
+        s.save()
+
+        self.assertEqual(s.get_prices(), {
+            'total_costs_price': 10/(365*3)*365.25/12,
+            'unit_costs_price': 10/(365*3)*365.25/12/2,
+            'unit_goods_value_share': 5,
+            'total_goods_value_share': 10,
+        })
 
 
 class AbstractUseTests(TestCase):

+ 5 - 23
costs/views.py

@@ -1,5 +1,3 @@
-from itertools import chain
-
 from django.core.urlresolvers import reverse
 from django.shortcuts import render, get_object_or_404
 
@@ -49,31 +47,15 @@ def detail_service(request, pk):
     costs_uses = CostUse.objects.filter(service=service)
     goods_uses = GoodUse.objects.filter(service=service)
 
-    total_costs_price = sum(chain(
-        (i.monthly_provision_share() for i in goods_uses),
-        (i.cost_share() for i in costs_uses),
-    ))
-
-    total_goods_value_share = sum(i.value_share() for i in goods_uses)
-
-    if service.subscriptions_count == 0:
-        unit_costs_price = 0
-        unit_goods_value_share = 0
-    else:
-        unit_costs_price = total_costs_price/service.subscriptions_count
-        unit_goods_value_share = total_goods_value_share/service.subscriptions_count
-
-    context = {
+    context = {}
+    context.update(service.get_prices())
+    context.update({
         'breadcrumbs': breadcrumbs,
         'document': doc,
         'service': service,
         'costs_uses': costs_uses,
         'goods_uses': goods_uses,
-        'total_costs_price': total_costs_price,
-        'unit_costs_price': unit_costs_price,
+        'monthly_fas': context['unit_goods_value_share']/12,
+    })
 
-        'total_goods_value_share': total_goods_value_share,
-        'unit_goods_value_share': unit_goods_value_share,
-        'monthly_fas': unit_goods_value_share/12,
-    }
     return render(request, 'costs/service_detail.html', context)