pyaccuwage/fields.py
Binh Van Nguyen 068f1bbae4 Added load/dump methods which work similarly to those found in
simplejson. Tests seem to work so far. Still need to figure out
how to get data into the records in some easy way.
2011-04-02 15:28:38 -05:00

126 lines
3.5 KiB
Python

import decimal
class ValidationError(Exception):
pass
class Field(object):
creation_counter = 0
def __init__(self, name=None, max_length=0, required=True, uppercase=True):
self.name = name
self._value = None
self.max_length = max_length
self.required = required
self.uppercase = uppercase
self.creation_counter = Field.creation_counter
Field.creation_counter += 1
def validate(self):
raise NotImplemented
def get_data(self):
raise NotImplemented
def __setvalue(self, value):
self._value = value
def __getvalue(self):
return self._value
value = property(__getvalue, __setvalue)
def read(self, fp):
if fp.tell() + self.max_length <= fp.len:
data = fp.read(self.max_length)
print self, self.max_length, data
return self.parse(data)
return None
def parse(self, s):
self.value = s.strip()
class TextField(Field):
def validate(self):
if self.value == None and self.required:
raise ValidationError("value required")
if len(self.value) > self.max_length:
raise ValidationError("value is too long")
def get_data(self):
value = self.value or ""
if self.uppercase:
value = value.upper()
return value.ljust(self.max_length).encode('ascii')
class StateField(TextField):
def __init__(self, name=None, required=True):
return super(StateField, self).__init__(name=name, max_length=2, required=required)
class EmailField(TextField):
def __init__(self, name=None, required=True, max_length=None):
return super(EmailField, self).__init__(name=name, max_length=max_length,
required=required, uppercase=False)
class NumericField(TextField):
def validate(self):
super(NumericField, self).validate()
try:
int(self.value)
except ValueError:
raise ValidationError("field contains non-numeric characters")
def get_data(self):
value = self.value or ""
return value.zfill(self.max_length)
def parse(self, s):
self.value = int(s)
class StaticField(TextField):
def __init__(self, name=None, required=True, value=None):
super(StaticField, self).__init__(name=name, required=required,
max_length=len(value))
self._value = value
def parse(self, s):
print 'STATIC', self.max_length, s, len(s)
pass
class BlankField(TextField):
def get_data(self):
return " " * self.max_length
def parse(self, s):
pass
class BooleanField(Field):
def __init__(self, name=None, required=True, value=None):
super(BooleanField, self).__init__(name=name, required=required, max_length=1)
self._value = value
def validate(self):
pass
def get_data(self):
return '1' if self._value else '0'
def parse(self, s):
self.value = (s == '1')
class MoneyField(Field):
def validate(self):
if self.value == None and self.required:
raise ValidationError("value required")
if len(str(int((self.value or 0)*100))) > self.max_length:
raise ValidationError("value is too long")
def get_data(self):
return str(int((self.value or 0)*100)).encode('ascii').zfill(self.max_length)
def parse(self, s):
self.value = decimal.Decimal(s) * decimal.Decimal('0.01')