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:
parent
7dcbd6305b
commit
0646bf7b9b
3 changed files with 111 additions and 11 deletions
34
enums.py
34
enums.py
|
@ -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'),
|
||||
)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
80
record.py
80
record.py
|
@ -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'
|
||||
|
@ -158,6 +221,8 @@ class OptionalEmployeeWageRecord(model.Model):
|
|||
blank4 = BlankField(max_length=128)
|
||||
|
||||
|
||||
|
||||
|
||||
class StateWageRecord(model.Model):
|
||||
record_identifier = 'RS'
|
||||
required = False
|
||||
|
@ -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):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue