X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=bluechips%2Fmodel%2Ftypes.py;h=59f3d35bf8d150e0cc368e939db1058f46b0378a;hb=fed6d11d2cbd6d617d18bc01a78196865da4155b;hp=673a366927386ac8025821bd1ed1ce6adebe634e;hpb=d5ca54a2f614baff95c0b6c485352af4dd0fcbc1;p=bluechips.git diff --git a/bluechips/model/types.py b/bluechips/model/types.py index 673a366..59f3d35 100644 --- a/bluechips/model/types.py +++ b/bluechips/model/types.py @@ -3,8 +3,10 @@ Define special types used in BlueChips """ import locale +from decimal import Decimal, InvalidOperation import sqlalchemy as sa +from formencode import validators, Invalid from bluechips.lib.subclass import SmartSubclass from weakref import WeakValueDictionary @@ -32,6 +34,31 @@ def localeconv(): return d locale.localeconv = localeconv + +class CurrencyValidator(validators.FancyValidator): + "A validator to convert to Currency objects." + messages = {'amount': "Please enter a valid currency amount", + 'precision': "Only two digits after the decimal, please", + 'nonzero': "Please enter a non-zero amount"} + + def _to_python(self, value, state): + try: + dec = Decimal(value) + except InvalidOperation: + raise Invalid(self.message('amount', state), + value, state) + else: + ret = dec.quantize(Decimal('1.00')) + if ret == 0: + raise Invalid(self.message('nonzero', state), + value, state) + elif ret != dec: + raise Invalid(self.message('precision', state), + value, state) + else: + return Currency(int(ret * 100)) + + class Currency(object): """ Store currency values as an integral number of cents @@ -95,18 +122,25 @@ class Currency(object): argument to an int """ return self.__mul__(other) - - def __str_no_dollar__(self): + def __div__(self, other): """ - Get to the formatted string without the dollar sign + If I don't define this, SmartSubclass will convert the other + argument to an int + """ + return Currency(self.value / other) + def __truediv__(self, other): + """ + If I don't define this, SmartSubclass will convert the other + argument to an int """ - return str(self).replace('$', '') + return Currency(self.value / other) def __repr__(self): return '%s("%s")' % (self.__class__.__name__, str(self)) def __str__(self): return locale.currency(self.value / 100., grouping=True) + class DBCurrency(sa.types.TypeDecorator): """ A type which represents monetary amounts internally as integers.