[POS-commit] r3953 - in stoqlib/trunk: tests

Henrique Romano henrique at async.com.br
Fri Jul 21 17:13:06 BRT 2006


Author: henrique
Date: Fri Jul 21 17:13:05 2006
New Revision: 3953

Modified:
   stoqlib/trunk/stoqlib/domain/sellable.py
   stoqlib/trunk/tests/test_sellable.py

Log:
- Removing markup column, using properties instead.
- Using properties for BaseSellableInfo's price, so we can avoid using 
  "sellable.base_sellable_info.price" in the callsite.
- When creating an AbstractSellable, set the default price based on 
  category's markup and the cost specified.
- Tests added.


Modified: stoqlib/trunk/stoqlib/domain/sellable.py
==============================================================================
--- stoqlib/trunk/stoqlib/domain/sellable.py	(original)
+++ stoqlib/trunk/stoqlib/domain/sellable.py	Fri Jul 21 17:13:05 2006
@@ -65,10 +65,17 @@
     index = IntCol()
 
 class AbstractSellableCategory(InheritableModel):
+    """ Abstract class for sellable's category. This class can represents a
+    sellable's category as well its base category.
+
+    - I{description}: The category description
+    - I{suggested_markup}: Define the suggested markup when calculating the
+                           sellable's price.
+    - I{salesperson_comission}: A percentage comission suggested for all the
+                                sales which products belongs to this category.
+    """
     description = UnicodeCol()
     suggested_markup = DecimalCol(default=0)
-    # A percentage commission suggested for all the sales which products
-    # belongs to this category or base category
     salesperson_commission = DecimalCol(default=0)
 
     implements(IDescribable)
@@ -87,6 +94,9 @@
 
     implements(IDescribable)
 
+    def get_commission(self):
+        return self.salesperson_commission or self.base_category.get_commission()
+
     def get_markup(self):
         return self.suggested_markup or self.base_category.suggested_markup
 
@@ -180,7 +190,6 @@
     # This default status is used when a new sellable is created,
     # so it must be *always* SOLD (that means no stock for it).
     status = IntCol(default=STATUS_SOLD)
-    markup = DecimalCol(default=0)
     cost = PriceCol(default=0)
     notes = UnicodeCol(default='')
     unit = ForeignKey("SellableUnit", default=None)
@@ -193,7 +202,17 @@
             conn = self.get_connection()
             if not 'on_sale_info' in kw:
                 kw['on_sale_info'] = OnSaleInfo(connection=conn)
+            # markup specification must to reflect in the sellable price, since
+            # there is no such column -- but we can only change the price right
+            # after InheritableModelAdapter._create() get executed.
+            markup = kw.pop('markup', None)
         InheritableModelAdapter._create(self, id, **kw)
+        if not 'price' in kw and ('cost' in kw and 'category' in kw):
+            markup = markup or kw['category'].get_markup()
+            cost = kw.get('cost', currency(0))
+            self.price = cost * (markup / currency(100) + 1)
+        if not self.commission and self.category:
+            self.commission = self.category.get_commission()
 
     #
     # SQLObject setters
@@ -205,6 +224,41 @@
         self._SO_set_barcode(barcode)
 
     #
+    # Helper methods
+    #
+
+    def get_price_by_markup(self, markup):
+        return self.cost + (self.cost * (markup / 100))
+
+    #
+    # Properties
+    #
+
+    def get_markup(self):
+        return ((self.price / self.cost) - 1) * 100
+
+    def set_markup(self, markup):
+        self.price = self.get_price_by_markup(markup)
+
+    markup = property(get_markup, set_markup)
+
+    def get_price(self):
+        return self.base_sellable_info.price
+
+    def set_price(self, price):
+        self.base_sellable_info.price = price
+
+    price = property(get_price, set_price)
+
+    def get_commission(self):
+        return self.base_sellable_info.get_commission()
+
+    def set_commission(self, commission):
+        self.base_sellable_info.commission = commission
+
+    commission = property(get_commission, set_commission)
+
+    #
     # IContainer methods
     #
 
@@ -414,18 +468,6 @@
         return cls._get_sellables_by_barcode(conn, barcode, extra_query,
                                              notify_callback)
 
-    #
-    # General methods
-    #
-
-    def set_default_commission(self):
-        if not self.category:
-            self.commission = 0
-        else:
-            commission = self.category.base_category.get_commission()
-            self.commission = (self.category.get_commission()
-                               or commission)
-
 #
 # Views
 #

Modified: stoqlib/trunk/tests/test_sellable.py
==============================================================================
--- stoqlib/trunk/tests/test_sellable.py	(original)
+++ stoqlib/trunk/tests/test_sellable.py	Fri Jul 21 17:13:05 2006
@@ -24,7 +24,12 @@
 
 from kiwi.datatypes import currency
 
-from stoqlib.domain.sellable import SellableCategory, BaseSellableCategory
+from stoqlib.domain.sellable import (SellableCategory,
+                                     BaseSellableCategory,
+                                     AbstractSellable,
+                                     BaseSellableInfo)
+from stoqlib.domain.product import Product
+from stoqlib.domain.interfaces import ISellable
 from tests.base import BaseDomainTest
 
 class TestSellableCategory(BaseDomainTest):
@@ -48,3 +53,76 @@
         self.failUnless(self._category.get_markup() == currency(10))
         self._category.suggested_markup = None
         self.failUnless(self._category.get_markup() == currency(20))
+
+class TestAbstractSellable(BaseDomainTest):
+    _table = AbstractSellable
+
+    def setUp(self):
+        BaseDomainTest.setUp(self)
+        self._base_category = BaseSellableCategory(description="Cigarro",
+                                                   connection=self.conn)
+        self._category = SellableCategory(description="Hollywood",
+                                          base_category=self._base_category,
+                                          suggested_markup=10,
+                                          connection=self.conn)
+
+    def test_price_based_on_category_markup(self):
+        # When the price isn't defined, but the category and the cost. In this
+        # case the sellable must have the price calculated applying the category's
+        # markup in the sellable's cost.
+        product = Product(connection=self.conn)
+        self._category.suggested_markup = 0
+        sellable_info = BaseSellableInfo(description=u"MX123",
+                                         max_discount=0,
+                                         commission=0,
+                                         connection=self.conn)
+        sellable = product.addFacet(ISellable,
+                                    base_sellable_info=sellable_info,
+                                    cost=100,
+                                    category=self._category,
+                                    connection=self.conn)
+        self.failUnless(sellable.markup == self._category.get_markup(),
+                        ("Expected markup: %r, got %r"
+                         % (self._category.get_markup(),
+                            sellable.markup)))
+        price = sellable.cost * (sellable.markup / currency(100) + 1)
+        self.failUnless(sellable.price == price,
+                        ("Expected price: %r, got %r"
+                         % (price, sellable.price)))
+
+    def test_price_based_on_specified_markup(self):
+        # When the price isn't defined, but the category, markup and the cost.
+        # In this case the category's markup must be ignored and the price
+        # calculated applying the markup specified in the sellable's cost.
+        product = Product(connection=self.conn)
+        sellable_info = BaseSellableInfo(description=u"FY123",
+                                         connection=self.conn)
+        markup = 5
+        sellable = product.addFacet(ISellable,
+                                    base_sellable_info=sellable_info,
+                                    category=self._category,
+                                    markup=markup,
+                                    cost=100,
+                                    connection=self.conn)
+        self.failUnless(sellable.markup == markup,
+                        ("Expected markup: %r, got %r"
+                         % (markup, sellable.markup)))
+        price = sellable.cost * (markup / currency(100) + 1)
+        self.failUnless(sellable.price == price,
+                        ("Expected price: %r, got %r"
+                         % (price, sellable.price)))
+
+    def test_commission(self):
+        product = Product(connection=self.conn)
+        sellable_info = BaseSellableInfo(description=u"TX342",
+                                         connection=self.conn)
+        self._category.salesperson_commission = 10
+        sellable = product.addFacet(ISellable,
+                                    base_sellable_info=sellable_info,
+                                    category=self._category,
+                                    connection=self.conn)
+        self.failUnless(sellable.commission
+                        == self._category.salesperson_commission,
+                        ("Expected salesperson commission: %r, got %r"
+                         % (self._category.salesperson_commission,
+                            sellable.commission)))


More information about the POS-commit mailing list