]> asedeno.scripts.mit.edu Git - bluechips.git/blob - bluechips/model/types.py
Switch from using Decimal to using a new Currency class
[bluechips.git] / bluechips / model / types.py
1 """
2 Define special types used in BlueChips
3 """
4
5 import sqlalchemy as sa
6 from bluechips.lib.subclass import SmartSubclass
7
8 class Currency(object):
9     __metaclass__ = SmartSubclass(int)
10     def __init__(self, value):
11         if isinstance(value, str):
12             self.value = int(float(value) * 100)
13         else:
14             self.value = int(value)
15     
16     def __int__(self):
17         return self.value
18     def __float__(self):
19         return float(self.value)
20     def __long__(self):
21         return long(self.value)
22     
23     def __cmp__(self, other):
24         try:
25             return self.value.__cmp__(int(other))
26         except:
27             return self.value.__cmp__(0)
28     
29     def __mul__(self, other):
30         return Currency(self.value * other)
31     def __rmul__(self, other):
32         return self.__mul__(other)
33     
34     def __str_no_dollar__(self):
35         return str(self)[1:]
36     
37     def __repr__(self):
38         return '%s("%s")' % (self.__class__.__name__, str(self))
39     def __str__(self):
40         sign = '-' if self.value < 0 else ''
41         cents = abs(self.value) % 100
42         dollars = (abs(self.value) - cents) / 100
43         return '$%s%s.%.02d' % (sign, dollars, cents)
44
45 class DBCurrency(sa.types.TypeDecorator):
46     """
47     A type which represents monetary amounts internally as integers.
48     
49     This avoids binary/decimal float conversion issues
50     """
51     
52     impl = sa.types.Integer
53     
54     def process_bind_param(self, value, engine):
55         return int(value)
56     
57     def convert_result_value(self, value, engine):
58         return Currency(value)