2 Define special types used in BlueChips
7 import sqlalchemy as sa
8 from bluechips.lib.subclass import SmartSubclass
10 from weakref import WeakValueDictionary
13 "Manually install en_US for systems that don't have it."
14 d = {'currency_symbol': '$',
17 'grouping': [3, 3, 0],
18 'int_curr_symbol': 'USD ',
20 'mon_decimal_point': '.',
21 'mon_grouping': [3, 3, 0],
22 'mon_thousands_sep': ',',
33 locale.localeconv = localeconv
35 class Currency(object):
37 Store currency values as an integral number of cents
39 __metaclass__ = SmartSubclass(int)
40 __old_values__ = WeakValueDictionary()
41 def __new__(cls, value):
44 elif isinstance(value, str):
45 value = int(float(value) * 100)
49 if value not in cls.__old_values__:
50 new_object = super(cls, cls).__new__(cls)
51 new_object.value = value
52 cls.__old_values__[value] = new_object
55 return cls.__old_values__[value]
59 If I don't define this, SmartSubclass will return
60 Currency(int(self.value))
65 If I don't define this, SmartSubclass will return
66 Currency(float(self.value))
68 return float(self.value)
71 If I don't define this, SmartSubclass will return
72 Currency(long(self.value))
74 return long(self.value)
76 def __cmp__(self, other):
78 This is overridden for when validators compare a Currency to
84 return self.value.__cmp__(int(other))
86 def __mul__(self, other):
88 If I don't define this, SmartSubclass will convert the other
91 return Currency(self.value * other)
92 def __rmul__(self, other):
94 If I don't define this, SmartSubclass will convert the other
97 return self.__mul__(other)
99 def __str_no_dollar__(self):
101 Get to the formatted string without the dollar sign
103 return str(self).replace('$', '')
106 return '%s("%s")' % (self.__class__.__name__, str(self))
108 return locale.currency(self.value / 100., grouping=True)
110 class DBCurrency(sa.types.TypeDecorator):
112 A type which represents monetary amounts internally as integers.
114 This avoids binary/decimal float conversion issues
117 impl = sa.types.Integer
119 def process_bind_param(self, value, engine):
122 def convert_result_value(self, value, engine):
123 return Currency(value)
124 process_result_value = convert_result_value