So my web app takes money. Filthy grubby money. But only in small
quantities, amounts which could easily be represented by "decimal(5.2)".
Trying that in my table, however, leads to unexpected results -- I get
FOUR places after the decimal in my forms instead of two. But only if
there are pennies involved -- if it's only a dollar amount, I get two
places as expected. Hmmm...
OK. I realize that Decimal is kinda kludgy because it was not implemented
across all databases and its support is kind of "add on". So I thought I'd
represent my amounts in cents as an integer quantity. That should suffice
since it can handle the range of numbers I need, and has perfect "rounding"
behavior unlike floating point numbers. To make life easier I even made a
validator to take the input and display an output that is consistent with
money:
class IS_MONEY(object):
def __init__(self,error_message='Should be a number with two places
after the decimal'):
self.error_message=error_message
def __call__(self,value):
try:
rtn = int(float(value)*100)
return (rtn,None)
except:
return (value,self.error_message)
def fomatter(self,value):
rtn = '%d.%02d'%divmod(int(value),100)
return rtn
Unfortunately, my validator doesn't work. I suspect its because the
underlying field is an INTEGER. That opens it up to the default integer
handling provided automatically by web2py in the web2py.js:
function web2py_event_handlers() {
var doc = jQuery(document)
doc.on('click', '.flash', function(e){var t=jQuery(this); if(t.css(
'top')=='0px') t.slideUp('slow'); else t.fadeOut(); e.preventDefault();});
//doc.on('keyup', 'input.integer',
function(){this.value=this.value.reverse().replace(/[^0-9\-]|\-(?=.)/g,'').reverse();});
...and so forth...
Which I nuked. At least for test purposes. It helps a little -- now I can
enter the '.' character!
It STILL doesn't work. My Validator seems to perform the multiplication
part on the input side, but fails to render the value as "nn.nn" on the
output side. Instead it becomes the integer "nnnn" in my forms. I've
tried using a field type of "integer" (for postgres and sqlite) and
"string" (for sqlite, which is not particular about datatypes) but neither
worked differently.
Maybe someone can see where I'm going wrong?
-- Joe B.
--