]> asedeno.scripts.mit.edu Git - bluechips.git/blobdiff - bluechips/model/types.py
Add some documentation to the Currency type
[bluechips.git] / bluechips / model / types.py
index 1504d2184e051fcc7fd6030e317c4290f1ff6060..4de0033c3a2b8b86c7256210b8f13ef655382567 100644 (file)
@@ -3,10 +3,76 @@ Define special types used in BlueChips
 """
 
 import sqlalchemy as sa
-from decimal import Decimal
-import locale
+from bluechips.lib.subclass import SmartSubclass
 
-class Currency(sa.types.TypeDecorator):
+class Currency(object):
+    """
+    Store currency values as an integral number of cents
+    """
+    __metaclass__ = SmartSubclass(int)
+    def __init__(self, value):
+        if isinstance(value, str):
+            self.value = int(float(value) * 100)
+        else:
+            self.value = int(value)
+    
+    def __int__(self):
+        """
+        If I don't define this, SmartSubclass will return
+        Currency(int(self.value))
+        """
+        return self.value
+    def __float__(self):
+        """
+        If I don't define this, SmartSubclass will return
+        Currency(float(self.value))
+        """
+        return float(self.value)
+    def __long__(self):
+        """
+        If I don't define this, SmartSubclass will return
+        Currency(long(self.value))
+        """
+        return long(self.value)
+    
+    def __cmp__(self, other):
+        """
+        This is overridden for when validators compare a Currency to
+        ''
+        """
+        if other == '':
+            return 1
+        else:
+            return self.value.__cmp__(int(other))
+    
+    def __mul__(self, other):
+        """
+        If I don't define this, SmartSubclass will convert the other
+        argument to an int
+        """
+        return Currency(self.value * other)
+    def __rmul__(self, other):
+        """
+        If I don't define this, SmartSubclass will convert the other
+        argument to an int
+        """
+        return self.__mul__(other)
+    
+    def __str_no_dollar__(self):
+        """
+        Get to the formatted string without the dollar sign
+        """
+        return str(self)[1:]
+    
+    def __repr__(self):
+        return '%s("%s")' % (self.__class__.__name__, str(self))
+    def __str__(self):
+        sign = '-' if self.value < 0 else ''
+        cents = abs(self.value) % 100
+        dollars = (abs(self.value) - cents) / 100
+        return '$%s%s.%.02d' % (sign, dollars, cents)
+
+class DBCurrency(sa.types.TypeDecorator):
     """
     A type which represents monetary amounts internally as integers.
     
@@ -16,7 +82,7 @@ class Currency(sa.types.TypeDecorator):
     impl = sa.types.Integer
     
     def process_bind_param(self, value, engine):
-        return int(value * 100)
+        return int(value)
     
     def convert_result_value(self, value, engine):
-        return Decimal(Decimal(value) / 100).quantize(Decimal("0.01"))
+        return Currency(value)