Added record validation functions for everything (that we saw in the PDF),

we should go over them once more to make sure we didn't miss anything, but
testing validation should probably be done after that. Verify that the
record ordering enforcement code is correct, then start thinking of how
to get data from external sources into the record generator.
This commit is contained in:
Binh 2011-06-11 14:45:12 -05:00
parent 7dcbd6305b
commit 0646bf7b9b
3 changed files with 111 additions and 11 deletions

View file

@ -301,3 +301,37 @@ COUNTRIES = (
('ZM', 'Zambia'),
('ZW', 'Zimbabwe'))
employer_types = (
('F','Federal Government'),
('S','State and Local Governmental Employer'),
('T','Tax Exempt Employer'),
('Y','State and Local Tax Exempt Employer'),
('N','None Apply'),
)
employment_codes = (
('A', 'Agriculture'),
('H', 'Household'),
('M', 'Military'),
('Q', 'Medicare Qualified Government Employee'),
('X', 'Railroad'),
('F', 'Regular'),
('R', 'Regular (all others)'),
)
tax_jurisdiction_codes = (
('V', 'Virgin Islands'),
('G', 'Guam'),
('S', 'American Samoa'),
('N', 'Northern Mariana Islands'),
('P', 'Puerto Rico'),
)
tax_type_codes = (
('C', 'City Income Tax'),
('D', 'Country Income Tax'),
('E', 'School District Income Tax'),
('F', 'Other Income Tax'),
)

View file

@ -1,6 +1,6 @@
import decimal, datetime
import inspect
from enums import STATE_POSTAL_NUMERIC
import enums
class ValidationError(Exception):
def __init__(self, msg, field=None):
@ -71,18 +71,18 @@ class StateField(TextField):
def get_data(self):
value = self.value or ""
if value.strip() and self.use_numeric:
return str(STATE_POSTAL_NUMERIC[value.upper()]).zfill(self.max_length)
return str(enums.state_postal_numeric[value.upper()]).zfill(self.max_length)
else:
return value.ljust(self.max_length).encode('ascii')
def validate(self):
super(StateField, self).validate()
if self.value and self.value.upper() not in STATE_POSTAL_NUMERIC.keys():
if self.value and self.value.upper() not in enums.state_postal_numeric.keys():
raise ValidationError("%s is not a valid state abbreviation" % self.value, field=self)
def parse(self, s):
if s.strip() and self.use_numeric:
states = dict( [(v,k) for (k,v) in STATE_POSTAL_NUMERIC.items()] )
states = dict( [(v,k) for (k,v) in enums.state_postal_numeric.items()] )
self.value = states[int(s)]
else:
self.value = s

View file

@ -1,5 +1,6 @@
import model
from fields import *
import enums
__all__ = RECORD_TYPES = ['SubmitterRecord', 'EmployerRecord',
'EmployeeWageRecord', 'OptionalEmployeeWageRecord',
@ -12,9 +13,9 @@ class SubmitterRecord(model.Model):
submitter_ein = NumericField(max_length=9)
user_id = TextField(max_length=8)
software_vendor = TextField(max_length=4)
software_vendor = TextField(max_length=4, required=False)
blank1 = BlankField(max_length=5)
resub_indictator = BooleanField()
resub_indictator = BooleanField(required=False)
resub_identifier = TextField(max_length=6, required=False)
software_code = StaticField(value='98') # In-house program
company_name = TextField(max_length=57)
@ -50,12 +51,39 @@ class SubmitterRecord(model.Model):
preparer_code = TextField(max_length=1)
blank6 = BlankField(max_length=12)
def validate_submitter_ein(self, f):
f.value = f.value.replace('-','')
excluded_values = ('07','08','09','17','18','19','28','29','49','69', '70', '78', '79', '89')
if f.value[0:2] in excluded_values:
raise ValidationError("%s not one of %s" % (f.value, excluded_values), field=f)
try:
int(f.value)
except ValueError:
raise ValidationError("%s must be numeric values only" % f.value, field=f)
def validate_resub_identifier(self, f):
if self.resub_indicator.value == True:
if not f.value:
raise ValidationError("resub_identifier must be set because resub_indicator is True", field=f)
def validate_preferred_notification(self, f):
if self.preferred_notification.value == '1':
if not self.contact_email.value:
raise ValidationError("contact_email must be set if preferred notification method is email (1)", field=f)
def validate_preparer_code(self, f):
valid_options = ('A','L','S','P','O')
if self.preparer_code.value.upper() not in valid_options:
raise ValidationError("preparer_code %s not one of %s" % (self.preparer_code.value, valid_options), field=f)
class EmployerRecord(model.Model):
record_identifier = 'RE'
required = True
tax_year = NumericField(max_length=4)
agent_indicator = NumericField(max_length=1)
agent_indicator = NumericField(max_length=1, required=False)
employer_ein = TextField(max_length=9)
agent_for_ein = TextField(max_length=9, required=False)
terminating_business_indicator = BooleanField()
@ -68,15 +96,45 @@ class EmployerRecord(model.Model):
state = StateField()
zipcode = TextField(max_length=5)
zipcode_ext = TextField(max_length=4, required=False)
blank1 = BlankField(max_length=5)
kind_of_employer = TextField(max_length=1)
blank1 = BlankField(max_length=4)
foreign_state_province = TextField(max_length=23)
foreign_postal_code = TextField(max_length=15)
country_code = TextField(max_length=2, required=False)
employment_code = TextField(max_length=1)
tax_jurisdiction_code = TextField(max_length=1)
tax_jurisdiction_code = TextField(max_length=1, required=False)
third_party_sick_pay = BooleanField()
blank2 = BlankField(max_length=291)
def validate_agent_indicator(self, f):
v = f.value
if v and v not in (1,2,3):
raise ValidationError("%s not in one of (1,2,3)" % v, field=f)
def validate_employer_ein(self, f):
excluded_values = ('00','07','08','09','17','18','19','28','29','49','69','70','78','79','89')
if f.value[0:2] in excluded_values:
raise ValidationError("%s not one of %s" % (f.value, excluded_values), field=f)
def validate_agent_for_ein(self, f):
if self.agent_indicator.value == 1 and not f.value:
raise ValidationError("agent_for_ein must be provided with agent_indicator=1", field=f)
def validate_kind_of_employer(self, f):
choices = [k for k,v in enums.employer_types]
if f.value.upper() not in choices:
raise ValidationError("%s not in one of %s" % (f.value, choices), field=f)
def validate_employment_code(self, f):
choices = [k for k,v in enums.employment_codes]
if f.value.upper() not in choices:
raise ValidationError("%s not in one of %s" % (f.value, choices), field=f)
def validate_tax_jurisdiction_code(self, f):
choices = [k for k,v in enums.tax_jurisdiction_codes]
if f.value and f.value.upper() not in choices:
raise ValidationError("%s not in one of %s" % (f.value, choices), field=f)
class EmployeeWageRecord(model.Model):
record_identifier = 'RW'
@ -129,6 +187,11 @@ class EmployeeWageRecord(model.Model):
third_party_sick_pay = BooleanField()
blank5 = BlankField(max_length=23)
def validate_ssn(self, f):
if str(f.value).startswith('666','9'):
raise ValidationError("ssn cannot start with 666 or 9", field=f)
class OptionalEmployeeWageRecord(model.Model):
record_identifier = 'RO'
@ -157,6 +220,8 @@ class OptionalEmployeeWageRecord(model.Model):
virgin_islands_income_tax_withheld = MoneyField(max_length=11, required=False)
blank4 = BlankField(max_length=128)
class StateWageRecord(model.Model):
record_identifier = 'RS'
@ -202,8 +267,9 @@ class StateWageRecord(model.Model):
blank4 = BlankField(max_length=25)
def validate_tax_type_code(self, field):
if field.value not in ['C','D','E','F']:
raise ValidationError("%s not one of (c,d,e,f)" % field.value, field=f)
choices [x for x,y in enums.tax_type_codes]
if field.value.upper() not in choices
raise ValidationError("%s not one of %s" % (field.value,choices), field=f)
class TotalRecord(model.Model):