Repository: moov-io/ach
Pull request #175 (2018-05-07 21:39:13)

Static check analysis
Clean up of dead code and other static code analysis updates from megacheck 


Patch:
diff --git a/README.md b/README.md
index 14c6aadf..0c61fa2a 100644
--- a/README.md
+++ b/README.md
@@ -68,8 +68,8 @@ The following is based on [simple file creation](https://github.com/moov-io/ach/
  
  ```go
 	fh := ach.NewFileHeader()
-	fh.ImmediateDestination = "9876543210" // A blank space followed by your ODFI's transit/routing number
-	fh.ImmediateOrigin = "1234567890"      // Organization or Company FED ID usually 1 and FEIN/SSN. Assigned by your ODFI
+	fh.ImmediateDestination = 9876543210 // A blank space followed by your ODFI's transit/routing number
+	fh.ImmediateOrigin = 1234567890      // Organization or Company FED ID usually 1 and FEIN/SSN. Assigned by your ODFI
 	fh.FileCreationDate = time.Now()     // Todays Date
 	fh.ImmediateDestinationName = "Federal Reserve Bank"
 	fh.ImmediateOriginName = "My Bank Name")
@@ -91,7 +91,7 @@ func mockBatchPPDHeader() *BatchHeader {
 	bh.CompanyIdentification = "123456789"
 	bh.CompanyEntryDescription = "PAYROLL"
 	bh.EffectiveEntryDate = time.Now()
-	bh.ODFIIdentification = "6200001"
+	bh.ODFIIdentification = 6200001
 	return bh
 }
 
@@ -109,7 +109,7 @@ func mockBatchPPDHeader() *BatchHeader {
 	bh.CompanyIdentification = "123456789"
 	bh.CompanyEntryDescription = "PAYROLL"
 	bh.EffectiveEntryDate = time.Now()
-	bh.ODFIIdentification = "6200001"
+	bh.ODFIIdentification = 6200001
 	return bh
 }
 
@@ -122,7 +122,7 @@ To create an entry
  ```go
 entry := ach.NewEntryDetail()
 entry.TransactionCode = 22
-entry.SetRDFI("009101298")
+entry.SetRDFI(9101298)
 entry.DFIAccountNumber = "123456789"
 entry.Amount = 100000000
 entry.IndividualName = "Wade Arnold"
@@ -173,7 +173,7 @@ func mockBatchWEBHeader() *BatchHeader {
 	bh.CompanyName = "Your Company, inc"
 	bh.CompanyIdentification = "123456789"
 	bh.CompanyEntryDescription = "Online Order"
-	bh.ODFIIdentification = "6200001"
+	bh.ODFIIdentification = 6200001
 	return bh
 }
 
diff --git a/addenda98.go b/addenda98.go
index 815e41f4..b7d1c0ab 100644
--- a/addenda98.go
+++ b/addenda98.go
@@ -20,7 +20,7 @@ type Addenda98 struct {
 	// in the Addenda Record of an 98, within an Acknowledgment Entry, or with an RDFI request for a copy of an authorization.
 	OriginalTrace int
 	// OriginalDFI field contains the Receiving DFI Identification (addenda.RDFIIdentification) as originally included on the forward Entry or Prenotification that the RDFI is returning or correcting.
-	OriginalDFI string
+	OriginalDFI int
 	// CorrectedData
 	CorrectedData string
 	// TraceNumber matches the Entry Detail Trace Number of the entry being returned.
@@ -37,7 +37,6 @@ var (
 
 	// Error messages specific to Addenda98
 	msgAddenda98ChangeCode    = "found is not a valid addenda Change Code"
-	msgAddenda98TypeCode      = "is not Addenda98 type code of 98"
 	msgAddenda98CorrectedData = "must contain the corrected information corresponding to the Change Code"
 )
 
@@ -72,7 +71,7 @@ func (addenda98 *Addenda98) Parse(record string) {
 	// 7-21
 	addenda98.OriginalTrace = addenda98.parseNumField(record[6:21])
 	// 28-35
-	addenda98.OriginalDFI = addenda98.parseStringField(record[27:35])
+	addenda98.OriginalDFI = addenda98.parseNumField(record[27:35])
 	// 36-64
 	addenda98.CorrectedData = strings.TrimSpace(record[35:64])
 	// 80-94
@@ -131,7 +130,7 @@ func (addenda98 *Addenda98) OriginalTraceField() string {
 
 // OriginalDFIField returns a zero padded OriginalDFI string
 func (addenda98 *Addenda98) OriginalDFIField() string {
-	return addenda98.stringRTNField(addenda98.OriginalDFI, 8)
+	return addenda98.numericField(addenda98.OriginalDFI, 8)
 }
 
 //CorrectedDataField returns a space padded CorrectedData string
diff --git a/addenda99.go b/addenda99.go
index 25023874..5e825dc4 100644
--- a/addenda99.go
+++ b/addenda99.go
@@ -42,7 +42,7 @@ type Addenda99 struct {
 	// DateOfDeath The field date of death is to be supplied on Entries being returned for reason of death (return reason codes R14 and R15).
 	DateOfDeath time.Time
 	// OriginalDFI field contains the Receiving DFI Identification (addenda.RDFIIdentification) as originally included on the forward Entry or Prenotification that the RDFI is returning or correcting.
-	OriginalDFI string
+	OriginalDFI int
 	// AddendaInformation
 	AddendaInformation string
 	// TraceNumber matches the Entry Detail Trace Number of the entry being returned.
@@ -83,7 +83,7 @@ func (Addenda99 *Addenda99) Parse(record string) {
 	// 22-27, might be a date or blank
 	Addenda99.DateOfDeath = Addenda99.parseSimpleDate(record[21:27])
 	// 28-35
-	Addenda99.OriginalDFI = Addenda99.parseStringField(record[27:35])
+	Addenda99.OriginalDFI = Addenda99.parseNumField(record[27:35])
 	// 36-79
 	Addenda99.AddendaInformation = strings.TrimSpace(record[35:79])
 	// 80-94
@@ -143,7 +143,7 @@ func (Addenda99 *Addenda99) DateOfDeathField() string {
 
 // OriginalDFIField returns a zero padded OriginalDFI string
 func (Addenda99 *Addenda99) OriginalDFIField() string {
-	return Addenda99.stringRTNField(Addenda99.OriginalDFI, 8)
+	return Addenda99.numericField(Addenda99.OriginalDFI, 8)
 }
 
 //AddendaInformationField returns a space padded AddendaInformation string
diff --git a/batch.go b/batch.go
index 34d17870..251d25bd 100644
--- a/batch.go
+++ b/batch.go
@@ -122,14 +122,8 @@ func (batch *batch) build() error {
 		if err != nil {
 			return err
 		}
-
-		batchHeaderODFI, err := strconv.Atoi(batch.header.ODFIIdentificationField()[:8])
-		if err != nil {
-			return err
-		}
-
 		// Add a sequenced TraceNumber if one is not already set. Have to keep original trance number Return and NOC entries
-		if currentTraceNumberODFI != batchHeaderODFI {
+		if currentTraceNumberODFI != batch.header.ODFIIdentification {
 			batch.entries[i].SetTraceNumber(batch.header.ODFIIdentification, seq)
 		}
 		seq++
@@ -288,10 +282,7 @@ func (batch *batch) isEntryHash() error {
 func (batch *batch) calculateEntryHash() string {
 	hash := 0
 	for _, entry := range batch.entries {
-
-		entryRDFI, _ := strconv.Atoi(entry.RDFIIdentification)
-
-		hash = hash + entryRDFI
+		hash = hash + entry.RDFIIdentification
 	}
 	return batch.numericField(hash, 10)
 }
diff --git a/batchControl.go b/batchControl.go
index a5003e23..74a016f7 100644
--- a/batchControl.go
+++ b/batchControl.go
@@ -56,7 +56,7 @@ type BatchControl struct {
 	// Reserved for the future - Blank, 6 characters long
 	reserved string
 	// OdfiIdentification the routing number is used to identify the DFI originating entries within a given branch.
-	ODFIIdentification string
+	ODFIIdentification int
 	// BatchNumber this number is assigned in ascending sequence to each batch by the ODFI
 	// or its Sending Point in a given file of entries. Since the batch number
 	// in the Batch Header Record and the Batch Control Record is the same,
@@ -90,7 +90,7 @@ func (bc *BatchControl) Parse(record string) {
 	// 74-79 Always blank (just fill with spaces)
 	bc.reserved = "      "
 	// 80-87 This is the same as the "ODFI identification" field in previous Batch Header Record
-	bc.ODFIIdentification = bc.parseStringField(record[79:87])
+	bc.ODFIIdentification = bc.parseNumField(record[79:87])
 	// 88-94 This is the same as the "Batch number" field in previous Batch Header Record
 	bc.BatchNumber = bc.parseNumField(record[87:94])
 }
@@ -156,7 +156,7 @@ func (bc *BatchControl) fieldInclusion() error {
 	if bc.ServiceClassCode == 0 {
 		return &FieldError{FieldName: "ServiceClassCode", Value: strconv.Itoa(bc.ServiceClassCode), Msg: msgFieldInclusion}
 	}
-	if bc.ODFIIdentification == "000000000" {
+	if bc.ODFIIdentification == 0 {
 		return &FieldError{FieldName: "ODFIIdentification", Value: bc.ODFIIdentificationField(), Msg: msgFieldInclusion}
 	}
 	return nil
@@ -194,7 +194,7 @@ func (bc *BatchControl) MessageAuthenticationCodeField() string {
 
 // ODFIIdentificationField get the odfi number zero padded
 func (bc *BatchControl) ODFIIdentificationField() string {
-	return bc.stringRTNField(bc.ODFIIdentification, 8)
+	return bc.numericField(bc.ODFIIdentification, 8)
 }
 
 // BatchNumberField gets a string of the batch number zero padded
diff --git a/batchHeader.go b/batchHeader.go
index 9c475c8f..65d0580e 100644
--- a/batchHeader.go
+++ b/batchHeader.go
@@ -88,7 +88,7 @@ type BatchHeader struct {
 	OriginatorStatusCode int
 
 	//ODFIIdentification First 8 digits of the originating DFI transit routing number
-	ODFIIdentification string
+	ODFIIdentification int
 
 	// BatchNumber is assigned in ascending sequence to each batch by the ODFI
 	// or its Sending Point in a given file of entries. Since the batch number
@@ -146,7 +146,7 @@ func (bh *BatchHeader) Parse(record string) {
 	bh.OriginatorStatusCode = bh.parseNumField(record[78:79])
 	// 80-87 Your ODFI's routing number without the last digit. The last digit is simply a
 	// checksum digit, which is why it is not necessary
-	bh.ODFIIdentification = bh.parseStringField(record[79:87])
+	bh.ODFIIdentification = bh.parseNumField(record[79:87])
 	// 88-94 Sequential number of this Batch Header Record
 	// For example, put "1" if this is the first Batch Header Record in the file
 	bh.BatchNumber = bh.parseNumField(record[87:94])
@@ -226,7 +226,7 @@ func (bh *BatchHeader) fieldInclusion() error {
 	if bh.CompanyEntryDescription == "" {
 		return &FieldError{FieldName: "CompanyEntryDescription", Value: bh.CompanyEntryDescription, Msg: msgFieldInclusion}
 	}
-	if bh.ODFIIdentification == "" {
+	if bh.ODFIIdentification == 0 {
 		return &FieldError{FieldName: "ODFIIdentification", Value: bh.ODFIIdentificationField(), Msg: msgFieldInclusion}
 	}
 	return nil
@@ -264,7 +264,7 @@ func (bh *BatchHeader) EffectiveEntryDateField() string {
 
 // ODFIIdentificationField get the odfi number zero padded
 func (bh *BatchHeader) ODFIIdentificationField() string {
-	return bh.stringRTNField(bh.ODFIIdentification, 8)
+	return bh.numericField(bh.ODFIIdentification, 8)
 }
 
 // BatchNumberField get the batch number zero padded
diff --git a/batcher.go b/batcher.go
index 1ab88eff..e68799d8 100644
--- a/batcher.go
+++ b/batcher.go
@@ -42,7 +42,6 @@ var (
 	msgBatchHeaderControlEquality     = "header %v is not equal to control %v"
 	msgBatchCalculatedControlEquality = "calculated %v is out-of-balance with control %v"
 	msgBatchAscending                 = "%v is less than last %v. Must be in ascending order"
-	msgBatchFieldInclusion            = "%v is a required field "
 	// specific messages for error
 	msgBatchOriginatorDNE         = "%v is not “2” for DNE with entry transaction code of 23 or 33"
 	msgBatchTraceNumberNotODFI    = "%v in header does not match entry trace number %v"
diff --git a/converters.go b/converters.go
index a80962d8..0f74b225 100644
--- a/converters.go
+++ b/converters.go
@@ -18,11 +18,6 @@ func (c *converters) parseNumField(r string) (s int) {
 	return s
 }
 
-func (c *converters) parseStringField(r string) (s string) {
-	s = strings.TrimSpace(r)
-	return s
-}
-
 // formatSimpleDate takes a time.Time and returns a string of YYMMDD
 func (c *converters) formatSimpleDate(t time.Time) string {
 	return t.Format("060102")
@@ -45,6 +40,8 @@ func (c *converters) parseSimpleTime(s string) time.Time {
 	return t
 }
 
+//func (v *Converters) numericField()
+
 // alphaField Alphanumeric and Alphabetic fields are left-justified and space filled.
 func (c *converters) alphaField(s string, max uint) string {
 	ln := uint(len(s))
@@ -65,13 +62,3 @@ func (c *converters) numericField(n int, max uint) string {
 	s = strings.Repeat("0", int(max-ln)) + s
 	return s
 }
-
-// stringField right-justified and zero filled
-func (c *converters) stringRTNField(s string, max uint) string {
-	ln := uint(len(s))
-	if ln > max {
-		return s[:max]
-	}
-	s = strings.Repeat("0", int(max-ln)) + s
-	return s
-}
diff --git a/entryDetail.go b/entryDetail.go
index fcb3ca7e..77a354b1 100644
--- a/entryDetail.go
+++ b/entryDetail.go
@@ -30,10 +30,10 @@ type EntryDetail struct {
 
 	// RDFIIdentification is the RDFI's routing number without the last digit.
 	// Receiving Depository Financial Institution
-	RDFIIdentification string
+	RDFIIdentification int
 
 	// CheckDigit the last digit of the RDFI's routing number
-	CheckDigit string
+	CheckDigit int
 
 	// DFIAccountNumber is the receiver's bank account number you are crediting/debiting.
 	// It important to note that this is an alphanumeric field, so its space padded, no zero padded
@@ -106,9 +106,9 @@ func (ed *EntryDetail) Parse(record string) {
 	// 2-3 is checking credit 22 debit 27 savings credit 32 debit 37
 	ed.TransactionCode = ed.parseNumField(record[1:3])
 	// 4-11 the RDFI's routing number without the last digit.
-	ed.RDFIIdentification = ed.parseStringField(record[3:11])
+	ed.RDFIIdentification = ed.parseNumField(record[3:11])
 	// 12-12 The last digit of the RDFI's routing number
-	ed.CheckDigit = ed.parseStringField(record[11:12])
+	ed.CheckDigit = ed.parseNumField(record[11:12])
 	// 13-29 The receiver's bank account number you are crediting/debiting
 	ed.DFIAccountNumber = record[12:29]
 	// 30-39 Number of cents you are debiting/crediting this account
@@ -169,17 +169,10 @@ func (ed *EntryDetail) Validate() error {
 	if err := ed.isAlphanumeric(ed.DiscretionaryData); err != nil {
 		return &FieldError{FieldName: "DiscretionaryData", Value: ed.DiscretionaryData, Msg: err.Error()}
 	}
-
 	calculated := ed.CalculateCheckDigit(ed.RDFIIdentificationField())
-
-	edCheckDigit, err := strconv.Atoi(ed.CheckDigit)
-	if err != nil {
-		return err
-	}
-
-	if calculated != edCheckDigit {
+	if calculated != ed.CheckDigit {
 		msg := fmt.Sprintf(msgValidCheckDigit, calculated)
-		return &FieldError{FieldName: "RDFIIdentification", Value: ed.CheckDigit, Msg: msg}
+		return &FieldError{FieldName: "RDFIIdentification", Value: strconv.Itoa(ed.CheckDigit), Msg: msg}
 	}
 	return nil
 }
@@ -193,7 +186,7 @@ func (ed *EntryDetail) fieldInclusion() error {
 	if ed.TransactionCode == 0 {
 		return &FieldError{FieldName: "TransactionCode", Value: strconv.Itoa(ed.TransactionCode), Msg: msgFieldInclusion}
 	}
-	if ed.RDFIIdentification == "" {
+	if ed.RDFIIdentification == 0 {
 		return &FieldError{FieldName: "RDFIIdentification", Value: ed.RDFIIdentificationField(), Msg: msgFieldInclusion}
 	}
 	if ed.DFIAccountNumber == "" {
@@ -232,22 +225,22 @@ func (ed *EntryDetail) AddAddenda(addenda Addendumer) []Addendumer {
 }
 
 // SetRDFI takes the 9 digit RDFI account number and separates it for RDFIIdentification and CheckDigit
-func (ed *EntryDetail) SetRDFI(rdfi string) *EntryDetail {
-	s := ed.stringRTNField(rdfi, 9)
-	ed.RDFIIdentification = ed.parseStringField(s[:8])
-	ed.CheckDigit = ed.parseStringField(s[8:9])
+func (ed *EntryDetail) SetRDFI(rdfi int) *EntryDetail {
+	s := ed.numericField(rdfi, 9)
+	ed.RDFIIdentification = ed.parseNumField(s[:8])
+	ed.CheckDigit = ed.parseNumField(s[8:9])
 	return ed
 }
 
 // SetTraceNumber takes first 8 digits of ODFI and concatenates a sequence number onto the TraceNumber
-func (ed *EntryDetail) SetTraceNumber(ODFIIdentification string, seq int) {
-	trace := ed.stringRTNField(ODFIIdentification, 8) + ed.numericField(seq, 7)
+func (ed *EntryDetail) SetTraceNumber(ODFIIdentification int, seq int) {
+	trace := ed.numericField(ODFIIdentification, 8) + ed.numericField(seq, 7)
 	ed.TraceNumber = ed.parseNumField(trace)
 }
 
 // RDFIIdentificationField get the rdfiIdentification with zero padding
 func (ed *EntryDetail) RDFIIdentificationField() string {
-	return ed.stringRTNField(ed.RDFIIdentification, 8)
+	return ed.numericField(ed.RDFIIdentification, 8)
 }
 
 // DFIAccountNumberField gets the DFIAccountNumber with space padding
diff --git a/example/ach-ppd-write/main.go b/example/ach-ppd-write/main.go
index 96b7d805..5c0a838c 100644
--- a/example/ach-ppd-write/main.go
+++ b/example/ach-ppd-write/main.go
@@ -3,6 +3,7 @@ package main
 import (
 	"log"
 	"os"
+	"strconv"
 	"time"
 
 	"github.com/moov-io/ach"
@@ -15,9 +16,9 @@ func main() {
 	// Set originator bank ODFI and destination Operator for the financial institution
 	// this is the funding/receiving source of the transfer
 	fh := ach.NewFileHeader()
-	fh.ImmediateDestination = "231380104" // Routing Number of the ACH Operator or receiving point to which the file is being sent
-	fh.ImmediateOrigin = "121042882"      // Routing Number of the ACH Operator or sending point that is sending the file
-	fh.FileCreationDate = time.Now()      // Todays Date
+	fh.ImmediateDestination = 9876543210 // A blank space followed by your ODFI's transit/routing number
+	fh.ImmediateOrigin = 1234567890      // Organization or Company FED ID usually 1 and FEIN/SSN. Assigned by your ODFI
+	fh.FileCreationDate = time.Now()     // Todays Date
 	fh.ImmediateDestinationName = "Federal Reserve Bank"
 	fh.ImmediateOriginName = "My Bank Name"
 
@@ -25,18 +26,18 @@ func main() {
 	bh := ach.NewBatchHeader()
 	bh.ServiceClassCode = 220          // ACH credit pushes money out, 225 debits/pulls money in.
 	bh.CompanyName = "Name on Account" // The name of the company/person that has relationship with receiver
-	bh.CompanyIdentification = fh.ImmediateOrigin
+	bh.CompanyIdentification = strconv.Itoa(fh.ImmediateOrigin)
 	bh.StandardEntryClassCode = "PPD"         // Consumer destination vs Company CCD
 	bh.CompanyEntryDescription = "REG.SALARY" // will be on receiving accounts statement
 	bh.EffectiveEntryDate = time.Now().AddDate(0, 0, 1)
-	bh.ODFIIdentification = "121042882" // Originating Routing Number
+	bh.ODFIIdentification = 12345678 // first 8 digits of your bank account
 
 	// Identifies the receivers account information
 	// can be multiple entry's per batch
 	entry := ach.NewEntryDetail()
 	// Identifies the entry as a debit and credit entry AND to what type of account (Savings, DDA, Loan, GL)
 	entry.TransactionCode = 22          // Code 22: Credit (deposit) to checking account
-	entry.SetRDFI("231380104")          // Receivers bank transit routing number
+	entry.SetRDFI(9101298)              // Receivers bank transit routing number
 	entry.DFIAccountNumber = "12345678" // Receivers bank account number
 	entry.Amount = 100000000            // Amount of transaction with no decimal. One dollar and eleven cents = 111
 	entry.SetTraceNumber(bh.ODFIIdentification, 1)
diff --git a/example/simple-file-creation/main.go b/example/simple-file-creation/main.go
index 9a744193..2417c851 100644
--- a/example/simple-file-creation/main.go
+++ b/example/simple-file-creation/main.go
@@ -5,14 +5,15 @@ import (
 	"os"
 
 	"github.com/moov-io/ach"
+	"strconv"
 	"time"
 )
 
 func main() {
 	// To create a file
 	fh := ach.NewFileHeader()
-	fh.ImmediateDestination = "231380104"
-	fh.ImmediateOrigin = "121042882"
+	fh.ImmediateDestination = 9876543210
+	fh.ImmediateOrigin = 1234567890
 	fh.FileCreationDate = time.Now()
 	fh.ImmediateDestinationName = "Federal Reserve Bank"
 	fh.ImmediateOriginName = "My Bank Name"
@@ -24,29 +25,28 @@ func main() {
 	bh := ach.NewBatchHeader()
 	bh.ServiceClassCode = 200
 	bh.CompanyName = "Your Company"
-	bh.CompanyIdentification = file.Header.ImmediateOrigin
+	bh.CompanyIdentification = strconv.Itoa(file.Header.ImmediateOrigin)
 	bh.StandardEntryClassCode = "PPD"
 	bh.CompanyEntryDescription = "Trans. Description"
 	bh.EffectiveEntryDate = time.Now().AddDate(0, 0, 1)
-	bh.ODFIIdentification = "121042882"
+	bh.ODFIIdentification = 123456789
 
 	batch, _ := ach.NewBatch(bh)
 
 	// To create an entry
 	entry := ach.NewEntryDetail()
 	entry.TransactionCode = 22
-	entry.SetRDFI("231380104")
-	entry.DFIAccountNumber = "81967038518"
-	entry.Amount = 1000000
+	entry.SetRDFI(9101298)
+	entry.DFIAccountNumber = "123456789"
+	entry.Amount = 100000000
 	entry.IndividualName = "Wade Arnold"
 	entry.SetTraceNumber(bh.ODFIIdentification, 1)
 	entry.IdentificationNumber = "ABC##jvkdjfuiwn"
 	entry.Category = ach.CategoryForward
 
 	// To add one or more optional addenda records for an entry
-
-	addenda := ach.NewAddenda05()
-	addenda.PaymentRelatedInformation = "bonus pay for amazing work on #OSS"
+	addenda, _ := ach.NewAddenda(ach.AddendaParam{
+		PaymentRelatedInfo: "bonus pay for amazing work on #OSS"})
 	entry.AddAddenda(addenda)
 
 	// Entries are added to batches like so:
@@ -68,11 +68,11 @@ func main() {
 	bh2 := ach.NewBatchHeader()
 	bh2.ServiceClassCode = 220
 	bh2.CompanyName = "Your Company"
-	bh2.CompanyIdentification = file.Header.ImmediateOrigin
+	bh2.CompanyIdentification = strconv.Itoa(file.Header.ImmediateOrigin)
 	bh2.StandardEntryClassCode = "WEB"
 	bh2.CompanyEntryDescription = "Subscr"
 	bh2.EffectiveEntryDate = time.Now().AddDate(0, 0, 1)
-	bh2.ODFIIdentification = "121042882"
+	bh2.ODFIIdentification = 123456789
 
 	batch2, _ := ach.NewBatch(bh2)
 
@@ -81,8 +81,8 @@ func main() {
 
 	entry2 := ach.NewEntryDetail()
 	entry2.TransactionCode = 22
-	entry2.SetRDFI("231380104")
-	entry2.DFIAccountNumber = "81967038518"
+	entry2.SetRDFI(102001017)
+	entry2.DFIAccountNumber = "5343121"
 	entry2.Amount = 799
 	entry2.IndividualName = "Wade Arnold"
 	entry2.SetTraceNumber(bh2.ODFIIdentification, 2)
@@ -90,15 +90,15 @@ func main() {
 	entry2.DiscretionaryData = "R"
 	entry2.Category = ach.CategoryForward
 
-	// To add one or more optional addenda records for an entry
-	addenda2 := ach.NewAddenda05()
-	addenda2.PaymentRelatedInformation = "Monthly Membership Subscription"
-	entry2.AddAddenda(addenda2)
+	addenda2, _ := ach.NewAddenda(ach.AddendaParam{
+		PaymentRelatedInfo: "Monthly Membership Subscription"})
 
 	// add the entry to the batch
-	batch2.AddEntry(entry2)
+	entry2.AddAddenda(addenda2)
 
 	// Create and add the second batch
+
+	batch2.AddEntry(entry2)
 	if err := batch2.Create(); err != nil {
 		fmt.Printf("%T: %s", err, err)
 	}
diff --git a/file.go b/file.go
index 5021e7a0..75fdfea4 100644
--- a/file.go
+++ b/file.go
@@ -27,18 +27,8 @@ const (
 	RecordLength = 94
 )
 
-// currently supported SEC codes
-const (
-	ppd = "PPD"
-	web = "WEB"
-	ccd = "CCD"
-	cor = "COR"
-	tel = "TEL"
-)
-
 // Errors strings specific to parsing a Batch container
 var (
-	msgFileControlEquality           = "header %v is not equal to control %v"
 	msgFileCalculatedControlEquality = "calculated %v is out-of-balance with control %v"
 	// specific messages
 	msgRecordLength      = "must be 94 characters and found %d"
diff --git a/fileHeader.go b/fileHeader.go
index 0b24c9f9..a32ec496 100644
--- a/fileHeader.go
+++ b/fileHeader.go
@@ -12,11 +12,10 @@ import (
 
 // Errors specific to a File Header Record
 var (
-	msgRecordType       = "received expecting %d"
-	msgRecordSize       = "is not 094"
-	msgBlockingFactor   = "is not 10"
-	msgFormatCode       = "is not 1"
-	msgFileCreationDate = "was created before " + time.Now().String()
+	msgRecordType     = "received expecting %d"
+	msgRecordSize     = "is not 094"
+	msgBlockingFactor = "is not 10"
+	msgFormatCode     = "is not 1"
 )
 
 // FileHeader is a Record designating physical file characteristics and identify
@@ -31,20 +30,18 @@ type FileHeader struct {
 	priorityCode string
 
 	// ImmediateDestination contains the Routing Number of the ACH Operator or receiving
-	// point to which the file is being sent.  The ach file format specifies a 10 character
-	// field  begins with a blank space in the first position, followed by the four digit
-	// Federal Reserve Routing Symbol, the four digit ABA Institution Identifier, and the Check
-	// Digit (bTTTTAAAAC).  ImmediateDestinationField() will append the blank space to the
-	// routing number.
-	ImmediateDestination string
+	// point to which the file is being sent. The 10 character field begins with
+	// a blank in the first position, followed by the four digit Federal Reserve
+	// Routing Symbol, the four digit ABA Institution Identifier, and the Check
+	// Digit (bTTTTAAAAC).
+	ImmediateDestination int
 
 	// ImmediateOrigin contains the Routing Number of the ACH Operator or sending
-	// point that is sending the file. The ach file format specifies a 10 character field
-	// which begins with a blank space in the first position, followed by the four digit
-	// Federal Reserve Routing Symbol, the four digit ABA Institution Identifier, and the Check
-	// Digit (bTTTTAAAAC).  ImmediateOriginField() will append the blank space to the routing
-	// number.
-	ImmediateOrigin string
+	// point that is sending the file. The 10 character field begins with
+	// a blank in the first position, followed by the four digit Federal Reserve
+	// Routing Symbol, the four digit ABA Institution Identifier, and the Check
+	// Digit (bTTTTAAAAC).
+	ImmediateOrigin int
 
 	// FileCreationDate is expressed in a "YYMMDD" format. The File Creation
 	// Date is the date on which the file is prepared by an ODFI (ACH input files)
@@ -113,9 +110,9 @@ func (fh *FileHeader) Parse(record string) {
 	// (2-3) Always "01"
 	fh.priorityCode = "01"
 	// (4-13) A blank space followed by your ODFI's routing number. For example: " 121140399"
-	fh.ImmediateDestination = fh.parseStringField(record[3:13])
+	fh.ImmediateDestination = fh.parseNumField(record[3:13])
 	// (14-23) A 10-digit number assigned to you by the ODFI once they approve you to originate ACH files through them
-	fh.ImmediateOrigin = fh.parseStringField(record[13:23])
+	fh.ImmediateOrigin = fh.parseNumField(record[13:23])
 	// 24-29 Today's date in YYMMDD format
 	// must be after todays date.
 	fh.FileCreationDate = fh.parseSimpleDate(record[23:29])
@@ -187,12 +184,6 @@ func (fh *FileHeader) Validate() error {
 	if err := fh.isAlphanumeric(fh.ImmediateDestinationName); err != nil {
 		return &FieldError{FieldName: "ImmediateDestinationName", Value: fh.ImmediateDestinationName, Msg: err.Error()}
 	}
-	if fh.ImmediateOrigin == "000000000" {
-		return &FieldError{FieldName: "ImmediateOrigin", Value: fh.ImmediateOrigin, Msg: msgFieldInclusion}
-	}
-	if fh.ImmediateDestination == "000000000" {
-		return &FieldError{FieldName: "ImmediateDestination", Value: fh.ImmediateDestination, Msg: msgFieldInclusion}
-	}
 	if err := fh.isAlphanumeric(fh.ImmediateOriginName); err != nil {
 		return &FieldError{FieldName: "ImmediateOriginName", Value: fh.ImmediateOriginName, Msg: err.Error()}
 	}
@@ -215,10 +206,10 @@ func (fh *FileHeader) fieldInclusion() error {
 	if fh.recordType == "" {
 		return &FieldError{FieldName: "recordType", Value: fh.recordType, Msg: msgFieldInclusion}
 	}
-	if fh.ImmediateDestination == "" {
+	if fh.ImmediateDestination == 0 {
 		return &FieldError{FieldName: "ImmediateDestination", Value: fh.ImmediateDestinationField(), Msg: msgFieldInclusion}
 	}
-	if fh.ImmediateOrigin == "" {
+	if fh.ImmediateOrigin == 0 {
 		return &FieldError{FieldName: "ImmediateOrigin", Value: fh.ImmediateOriginField(), Msg: msgFieldInclusion}
 	}
 	if fh.FileCreationDate.IsZero() {
@@ -241,12 +232,12 @@ func (fh *FileHeader) fieldInclusion() error {
 
 // ImmediateDestinationField gets the immediate destination number with zero padding
 func (fh *FileHeader) ImmediateDestinationField() string {
-	return " " + fh.stringRTNField(fh.ImmediateDestination, 9)
+	return " " + fh.numericField(fh.ImmediateDestination, 9)
 }
 
 // ImmediateOriginField gets the immediate origin number with 0 padding
 func (fh *FileHeader) ImmediateOriginField() string {
-	return " " + fh.stringRTNField(fh.ImmediateOrigin, 9)
+	return " " + fh.numericField(fh.ImmediateOrigin, 9)
 }
 
 // FileCreationDateField gets the file creation date in YYMMDD format
diff --git a/reader.go b/reader.go
index eda7129e..73ed0f47 100644
--- a/reader.go
+++ b/reader.go
@@ -224,7 +224,7 @@ func (r *Reader) parseAddenda() error {
 	r.recordName = "Addenda"
 
 	if r.currentBatch == nil {
-		msg := fmt.Sprintf(msgFileBatchOutside)
+		msg := fmt.Sprint(msgFileBatchOutside)
 		return r.error(&FileError{FieldName: "Addenda", Msg: msg})
 	}
 	if len(r.currentBatch.GetEntries()) == 0 {
@@ -258,7 +258,7 @@ func (r *Reader) parseAddenda() error {
 			r.currentBatch.GetEntries()[entryIndex].AddAddenda(addenda99)
 		}
 	} else {
-		msg := fmt.Sprintf(msgBatchAddendaIndicator)
+		msg := fmt.Sprint(msgBatchAddendaIndicator)
 		return r.error(&FileError{FieldName: "AddendaRecordIndicator", Msg: msg})
 	}
 
diff --git a/writer.go b/writer.go
index e359b3cd..02349976 100644
--- a/writer.go
+++ b/writer.go
@@ -89,7 +89,7 @@ func (w *Writer) Error() error {
 	return err
 }
 
-// WriteAll writes multiple ach.files to w using Write and then calls Flush.
+// WriteAll writes multiple ach.fieles to w using Write and then calls Flush.
 func (w *Writer) WriteAll(files []*File) error {
 	for _, file := range files {
 		err := w.Write(file)


Test patch:
diff --git a/addenda98_test.go b/addenda98_test.go
index c09576cc..cfa346aa 100644
--- a/addenda98_test.go
+++ b/addenda98_test.go
@@ -8,7 +8,7 @@ func mockAddenda98() *Addenda98 {
 	addenda98 := NewAddenda98()
 	addenda98.ChangeCode = "C01"
 	addenda98.OriginalTrace = 12345
-	addenda98.OriginalDFI = "9101298"
+	addenda98.OriginalDFI = 9101298
 	addenda98.CorrectedData = "1918171614"
 	addenda98.TraceNumber = 91012980000088
 
@@ -32,8 +32,8 @@ func TestAddenda98Parse(t *testing.T) {
 	if addenda98.OriginalTrace != 99912340000015 {
 		t.Errorf("expected %v got %v", 99912340000015, addenda98.OriginalTrace)
 	}
-	if addenda98.OriginalDFI != "09101298" {
-		t.Errorf("expected %s got %s", "09101298", addenda98.OriginalDFI)
+	if addenda98.OriginalDFI != 9101298 {
+		t.Errorf("expected %v got %v", 9101298, addenda98.OriginalDFI)
 	}
 	if addenda98.CorrectedData != "1918171614" {
 		t.Errorf("expected %v got %v", "1918171614", addenda98.CorrectedData)
diff --git a/addenda99_test.go b/addenda99_test.go
index 51356e55..7e50c6c8 100644
--- a/addenda99_test.go
+++ b/addenda99_test.go
@@ -14,7 +14,7 @@ func mockAddenda99() *Addenda99 {
 	addenda99.ReturnCode = "R07"
 	addenda99.OriginalTrace = 99912340000015
 	addenda99.AddendaInformation = "Authorization Revoked"
-	addenda99.OriginalDFI = "9101298"
+	addenda99.OriginalDFI = 9101298
 
 	return addenda99
 }
@@ -36,11 +36,11 @@ func TestAddenda99Parse(t *testing.T) {
 	if addenda99.OriginalTrace != 99912340000015 {
 		t.Errorf("expected: %v got: %v", 99912340000015, addenda99.OriginalTrace)
 	}
-	if addenda99.DateOfDeath.IsZero() != true {
+	if !addenda99.DateOfDeath.IsZero() {
 		t.Errorf("expected: %v got: %v", time.Time{}, addenda99.DateOfDeath)
 	}
-	if addenda99.OriginalDFI != "09101298" {
-		t.Errorf("expected: %s got: %s", "09101298", addenda99.OriginalDFI)
+	if addenda99.OriginalDFI != 9101298 {
+		t.Errorf("expected: %v got: %v", 9101298, addenda99.OriginalDFI)
 	}
 	if addenda99.AddendaInformation != "Authorization revoked" {
 		t.Errorf("expected: %v got: %v", "Authorization revoked", addenda99.AddendaInformation)
diff --git a/batchCCD_test.go b/batchCCD_test.go
index d4c96e24..b4806a26 100644
--- a/batchCCD_test.go
+++ b/batchCCD_test.go
@@ -9,16 +9,16 @@ func mockBatchCCDHeader() *BatchHeader {
 	bh.ServiceClassCode = 220
 	bh.StandardEntryClassCode = "CCD"
 	bh.CompanyName = "Your Company, inc"
-	bh.CompanyIdentification = "121042882"
+	bh.CompanyIdentification = "123456789"
 	bh.CompanyEntryDescription = "Vndr Pay"
-	bh.ODFIIdentification = "121042882"
+	bh.ODFIIdentification = 6200001
 	return bh
 }
 
 func mockCCDEntryDetail() *EntryDetail {
 	entry := NewEntryDetail()
 	entry.TransactionCode = 27
-	entry.SetRDFI("231380104")
+	entry.SetRDFI(9101298)
 	entry.DFIAccountNumber = "744-5678-99"
 	entry.Amount = 5000000
 	entry.IdentificationNumber = "location #23"
diff --git a/batchCOR_test.go b/batchCOR_test.go
index 98e478eb..8db3c563 100644
--- a/batchCOR_test.go
+++ b/batchCOR_test.go
@@ -11,16 +11,16 @@ func mockBatchCORHeader() *BatchHeader {
 	bh.ServiceClassCode = 220
 	bh.StandardEntryClassCode = "COR"
 	bh.CompanyName = "Your Company, inc"
-	bh.CompanyIdentification = "121042882"
+	bh.CompanyIdentification = "123456789"
 	bh.CompanyEntryDescription = "Vndr Pay"
-	bh.ODFIIdentification = "121042882"
+	bh.ODFIIdentification = 6200001
 	return bh
 }
 
 func mockCOREntryDetail() *EntryDetail {
 	entry := NewEntryDetail()
 	entry.TransactionCode = 27
-	entry.SetRDFI("231380104")
+	entry.SetRDFI(9101298)
 	entry.DFIAccountNumber = "744-5678-99"
 	entry.Amount = 0
 	entry.IdentificationNumber = "location #23"
diff --git a/batchControl_internal_test.go b/batchControl_internal_test.go
index 2b85409b..e6fa7cbf 100644
--- a/batchControl_internal_test.go
+++ b/batchControl_internal_test.go
@@ -12,8 +12,8 @@ import (
 func mockBatchControl() *BatchControl {
 	bc := NewBatchControl()
 	bc.ServiceClassCode = 220
-	bc.CompanyIdentification = "121042882"
-	bc.ODFIIdentification = "12104288"
+	bc.CompanyIdentification = "123456789"
+	bc.ODFIIdentification = 6200001
 	return bc
 }
 
@@ -25,10 +25,10 @@ func TestMockBatchControl(t *testing.T) {
 	if bc.ServiceClassCode != 220 {
 		t.Error("ServiceClassCode depedendent default value has changed")
 	}
-	if bc.CompanyIdentification != "121042882" {
+	if bc.CompanyIdentification != "123456789" {
 		t.Error("CompanyIdentification depedendent default value has changed")
 	}
-	if bc.ODFIIdentification != "12104288" {
+	if bc.ODFIIdentification != 6200001 {
 		t.Error("ODFIIdentification depedendent default value has changed")
 	}
 }
@@ -41,10 +41,10 @@ func TestParseBatchControl(t *testing.T) {
 	bh := BatchHeader{BatchNumber: 1,
 		ServiceClassCode:      225,
 		CompanyIdentification: "origid",
-		ODFIIdentification:    "7640125"}
+		ODFIIdentification:    7640125}
 	r.addCurrentBatch(NewBatchPPD(&bh))
 
-	r.currentBatch.AddEntry(&EntryDetail{TransactionCode: 27, Amount: 10500, RDFIIdentification: "5320001", TraceNumber: 76401255655291})
+	r.currentBatch.AddEntry(&EntryDetail{TransactionCode: 27, Amount: 10500, RDFIIdentification: 5320001, TraceNumber: 76401255655291})
 	if err := r.parseBatchControl(); err != nil {
 		t.Errorf("%T: %s", err, err)
 	}
@@ -93,10 +93,10 @@ func TestBCString(t *testing.T) {
 	bh := BatchHeader{BatchNumber: 1,
 		ServiceClassCode:      225,
 		CompanyIdentification: "origid",
-		ODFIIdentification:    "7640125"}
+		ODFIIdentification:    7640125}
 	r.addCurrentBatch(NewBatchPPD(&bh))
 
-	r.currentBatch.AddEntry(&EntryDetail{TransactionCode: 27, Amount: 10500, RDFIIdentification: "5320001", TraceNumber: 76401255655291})
+	r.currentBatch.AddEntry(&EntryDetail{TransactionCode: 27, Amount: 10500, RDFIIdentification: 5320001, TraceNumber: 76401255655291})
 	if err := r.parseBatchControl(); err != nil {
 		t.Errorf("%T: %s", err, err)
 	}
@@ -194,7 +194,7 @@ func TestBCFieldInclusionServiceClassCode(t *testing.T) {
 
 func TestBCFieldInclusionODFIIdentification(t *testing.T) {
 	bc := mockBatchControl()
-	bc.ODFIIdentification = "000000000"
+	bc.ODFIIdentification = 0
 	if err := bc.Validate(); err != nil {
 		if e, ok := err.(*FieldError); ok {
 			if e.Msg != msgFieldInclusion {
diff --git a/batchHeader_internal_test.go b/batchHeader_internal_test.go
index 33b2317d..cab77c8a 100644
--- a/batchHeader_internal_test.go
+++ b/batchHeader_internal_test.go
@@ -14,9 +14,9 @@ func mockBatchHeader() *BatchHeader {
 	bh.ServiceClassCode = 220
 	bh.StandardEntryClassCode = "PPD"
 	bh.CompanyName = "ACME Corporation"
-	bh.CompanyIdentification = "121042882"
+	bh.CompanyIdentification = "123456789"
 	bh.CompanyEntryDescription = "PAYROLL"
-	bh.ODFIIdentification = "12104288"
+	bh.ODFIIdentification = 6200001
 	return bh
 }
 
@@ -34,13 +34,13 @@ func TestMockBatchHeader(t *testing.T) {
 	if bh.CompanyName != "ACME Corporation" {
 		t.Error("CompanyName dependent default value has changed")
 	}
-	if bh.CompanyIdentification != "121042882" {
+	if bh.CompanyIdentification != "123456789" {
 		t.Error("CompanyIdentification dependent default value has changed")
 	}
 	if bh.CompanyEntryDescription != "PAYROLL" {
 		t.Error("CompanyEntryDescription dependent default value has changed")
 	}
-	if bh.ODFIIdentification != "12104288" {
+	if bh.ODFIIdentification != 6200001 {
 		t.Error("ODFIIdentification dependent default value has changed")
 	}
 }
@@ -294,15 +294,3 @@ func TestBHFieldInclusionOriginatorStatusCode(t *testing.T) {
 		}
 	}
 }
-
-func TestBHFieldInclusionODFIIdentification(t *testing.T) {
-	bh := mockBatchHeader()
-	bh.ODFIIdentification = ""
-	if err := bh.Validate(); err != nil {
-		if e, ok := err.(*FieldError); ok {
-			if e.FieldName != "ODFIIdentification" {
-				t.Errorf("%T: %s", err, err)
-			}
-		}
-	}
-}
\ No newline at end of file
diff --git a/batchPPD_test.go b/batchPPD_test.go
index 2ace3b12..1e140bc2 100644
--- a/batchPPD_test.go
+++ b/batchPPD_test.go
@@ -14,17 +14,17 @@ func mockBatchPPDHeader() *BatchHeader {
 	bh.ServiceClassCode = 220
 	bh.StandardEntryClassCode = "PPD"
 	bh.CompanyName = "ACME Corporation"
-	bh.CompanyIdentification = "121042882"
+	bh.CompanyIdentification = "123456789"
 	bh.CompanyEntryDescription = "PAYROLL"
 	bh.EffectiveEntryDate = time.Now()
-	bh.ODFIIdentification = "12104288"
+	bh.ODFIIdentification = 6200001
 	return bh
 }
 
 func mockPPDEntryDetail() *EntryDetail {
 	entry := NewEntryDetail()
 	entry.TransactionCode = 22
-	entry.SetRDFI("231380104")
+	entry.SetRDFI(9101298)
 	entry.DFIAccountNumber = "123456789"
 	entry.Amount = 100000000
 	entry.IndividualName = "Wade Arnold"
@@ -38,20 +38,20 @@ func mockBatchPPDHeader2() *BatchHeader {
 	bh.ServiceClassCode = 200
 	bh.CompanyName = "MY BEST COMP."
 	bh.CompanyDiscretionaryData = "INCLUDES OVERTIME"
-	bh.CompanyIdentification = "121042882"
+	bh.CompanyIdentification = "1419871234"
 	bh.StandardEntryClassCode = "PPD"
 	bh.CompanyEntryDescription = "PAYROLL"
 	bh.EffectiveEntryDate = time.Now()
-	bh.ODFIIdentification = "12104288"
+	bh.ODFIIdentification = 109991234
 	return bh
 }
 
 func mockPPDEntry2() *EntryDetail {
 	entry := NewEntryDetail()
-	entry.TransactionCode = 22 // ACH Credit
-	entry.SetRDFI("231380104")
-	entry.DFIAccountNumber = "62292250"         // account number
-	entry.Amount = 100000                       // 1k dollars
+	entry.TransactionCode = 22                  // ACH Credit
+	entry.SetRDFI(81086674)                     // scottrade bank routing number
+	entry.DFIAccountNumber = "62292250"         // scottrade account number
+	entry.Amount = 1000000                      // 1k dollars
 	entry.IdentificationNumber = "658-888-2468" // Unique ID for payment
 	entry.IndividualName = "Wade Arnold"
 	entry.SetTraceNumber(mockBatchPPDHeader2().ODFIIdentification, 1)
@@ -139,7 +139,7 @@ func TestBatchCompanyIdentification(t *testing.T) {
 
 func TestBatchODFIIDMismatch(t *testing.T) {
 	mockBatch := mockBatchPPD()
-	mockBatch.GetControl().ODFIIdentification = "987654321"
+	mockBatch.GetControl().ODFIIdentification = 987654321
 	if err := mockBatch.Validate(); err != nil {
 		if e, ok := err.(*BatchError); ok {
 			if e.FieldName != "ODFIIdentification" {
diff --git a/batchTEL_test.go b/batchTEL_test.go
index 16967ceb..a1dbc2e3 100644
--- a/batchTEL_test.go
+++ b/batchTEL_test.go
@@ -9,16 +9,16 @@ func mockBatchTELHeader() *BatchHeader {
 	bh.ServiceClassCode = 225
 	bh.StandardEntryClassCode = "TEL"
 	bh.CompanyName = "Your Company, inc"
-	bh.CompanyIdentification = "121042882"
+	bh.CompanyIdentification = "123456789"
 	bh.CompanyEntryDescription = "Vndr Pay"
-	bh.ODFIIdentification = "12104288"
+	bh.ODFIIdentification = 6200001
 	return bh
 }
 
 func mockTELEntryDetail() *EntryDetail {
 	entry := NewEntryDetail()
 	entry.TransactionCode = 27
-	entry.SetRDFI("231380104")
+	entry.SetRDFI(9101298)
 	entry.DFIAccountNumber = "744-5678-99"
 	entry.Amount = 5000000
 	entry.IdentificationNumber = "Phone 333-2222"
diff --git a/batchWEB_test.go b/batchWEB_test.go
index e1814e09..6a704c30 100644
--- a/batchWEB_test.go
+++ b/batchWEB_test.go
@@ -7,16 +7,16 @@ func mockBatchWEBHeader() *BatchHeader {
 	bh.ServiceClassCode = 220
 	bh.StandardEntryClassCode = "WEB"
 	bh.CompanyName = "Your Company, inc"
-	bh.CompanyIdentification = "121042882"
+	bh.CompanyIdentification = "123456789"
 	bh.CompanyEntryDescription = "Online Order"
-	bh.ODFIIdentification = "12104288"
+	bh.ODFIIdentification = 6200001
 	return bh
 }
 
 func mockWEBEntryDetail() *EntryDetail {
 	entry := NewEntryDetail()
 	entry.TransactionCode = 22
-	entry.SetRDFI("231380104")
+	entry.SetRDFI(9101298)
 	entry.DFIAccountNumber = "123456789"
 	entry.Amount = 100000000
 	entry.IndividualName = "Wade Arnold"
diff --git a/batch_test.go b/batch_test.go
index 79afbc87..2837a28e 100644
--- a/batch_test.go
+++ b/batch_test.go
@@ -16,36 +16,6 @@ func mockBatch() *batch {
 	return mockBatch
 }
 
-// Batch with mismatched Trace Number ODFI
-func mockBatchInvalidTraceNumberODFI() *batch {
-	mockBatch := &batch{}
-	mockBatch.SetHeader(mockBatchHeader())
-	mockBatch.AddEntry(mockEntryDetailInvalidTraceNumberODFI())
-	return mockBatch
-}
-
-// Entry Detail with mismatched Trace Number ODFI
-func mockEntryDetailInvalidTraceNumberODFI() *EntryDetail {
-	entry := NewEntryDetail()
-	entry.TransactionCode = 22
-	entry.SetRDFI("121042882")
-	entry.DFIAccountNumber = "123456789"
-	entry.Amount = 100000000
-	entry.IndividualName = "Wade Arnold"
-	entry.SetTraceNumber("9928272", 1)
-	entry.IdentificationNumber = "ABC##jvkdjfuiwn"
-	entry.Category = CategoryForward
-	return entry
-}
-
-
-// Batch with no entries
-func mockBatchNoEntry() *batch {
-	mockBatch := &batch{}
-	mockBatch.SetHeader(mockBatchHeader())
-	return mockBatch
-}
-
 // Invalid SEC CODE Batch Header
 func mockBatchInvalidSECHeader() *BatchHeader {
 	bh := NewBatchHeader()
@@ -55,7 +25,7 @@ func mockBatchInvalidSECHeader() *BatchHeader {
 	bh.CompanyIdentification = "123456789"
 	bh.CompanyEntryDescription = "PAYROLL"
 	bh.EffectiveEntryDate = time.Now()
-	bh.ODFIIdentification = "123456789"
+	bh.ODFIIdentification = 6200001
 	return bh
 }
 
@@ -167,7 +137,7 @@ func TestBatchDNEMismatch(t *testing.T) {
 
 func TestBatchTraceNumberNotODFI(t *testing.T) {
 	mockBatch := mockBatch()
-	mockBatch.GetEntries()[0].SetTraceNumber("12345678", 1)
+	mockBatch.GetEntries()[0].SetTraceNumber(12345678, 1)
 	if err := mockBatch.verify(); err != nil {
 		if e, ok := err.(*BatchError); ok {
 			if e.FieldName != "ODFIIdentificationField" {
@@ -336,52 +306,3 @@ func TestBatchTraceNumberExists(t *testing.T) {
 		t.Errorf("Trace number was set to %v before batch.build and is now %v\n", traceBefore, traceAfter)
 	}
 }
-
-func TestBatchFieldInclusion(t *testing.T) {
-	mockBatch := mockBatch()
-	mockBatch.header.ODFIIdentification = ""
-	if err := mockBatch.verify(); err != nil {
-		if e, ok := err.(*BatchError); ok {
-			if e.FieldName != "ODFIIdentification" {
-				t.Errorf("%T: %s", err, err)
-			}
-		} else {
-			t.Errorf("%T: %s", err, err)
-		}
-	}
-}
-
-
-func TestBatchInvalidTraceNumberODFI(t *testing.T) {
-	mockBatch := mockBatchInvalidTraceNumberODFI()
-	if err := mockBatch.build(); err != nil {
-		t.Errorf("%T: %s", err, err)
-	}
-}
-
-func TestBatchNoEntry(t *testing.T) {
-	mockBatch := mockBatchNoEntry()
-	if err := mockBatch.build(); err != nil {
-		if e, ok := err.(*BatchError); ok {
-			if e.FieldName != "entries" {
-				t.Errorf("%T: %s", err, err)
-			}
-		} else {
-			t.Errorf("%T: %s", err, err)
-		}
-	}
-}
-
-func TestBatchControl(t *testing.T) {
-	mockBatch := mockBatch()
-	mockBatch.control.ODFIIdentification = ""
-	if err := mockBatch.verify(); err != nil {
-		if e, ok := err.(*BatchError); ok {
-			if e.FieldName != "ODFIIdentification" {
-				t.Errorf("%T: %s", err, err)
-			}
-		} else {
-			t.Errorf("%T: %s", err, err)
-		}
-	}
-}
\ No newline at end of file
diff --git a/converters_test.go b/converters_test.go
index 53ab199f..cf57646b 100644
--- a/converters_test.go
+++ b/converters_test.go
@@ -50,38 +50,3 @@ func TestParseNumField(t *testing.T) {
 		t.Errorf("Right justified zero got: '%v'", result)
 	}
 }
-
-//TestParseNumField handle zero and spaces in number conversion
-func TestParseStringField(t *testing.T) {
-	c := converters{}
-	result := c.parseStringField(" 012345")
-	if result != "012345" {
-		t.Errorf("Trim spaces: '%v'", result)
-	}
-}
-
-// TestNumericFieldShort ensures zero padding and right justified
-func TestRTNFieldShort(t *testing.T) {
-	c := converters{}
-	result := c.stringRTNField("123456", 8)
-	if result != "00123456" {
-		t.Errorf("Zero padding 8 character string : '%v'", result)
-	}
-}
-
-// TestNumericFieldLong right justified and sliced to max length
-func TestRTNFieldLong(t *testing.T) {
-	c := converters{}
-	result := c.stringRTNField("1234567899", 8)
-	if result != "12345678" {
-		t.Errorf("first 8 character string: '%v'", result)
-	}
-}
-
-func TestRTNFieldExact(t *testing.T) {
-	c := converters{}
-	result := c.stringRTNField("12345678", 8)
-	if result != "12345678" {
-		t.Errorf("first 8 character string: '%v'", result)
-	}
-}
diff --git a/entryDetail_internal_test.go b/entryDetail_internal_test.go
index b8c22b2c..46194a55 100644
--- a/entryDetail_internal_test.go
+++ b/entryDetail_internal_test.go
@@ -12,7 +12,7 @@ import (
 func mockEntryDetail() *EntryDetail {
 	entry := NewEntryDetail()
 	entry.TransactionCode = 22
-	entry.SetRDFI("121042882")
+	entry.SetRDFI(9101298)
 	entry.DFIAccountNumber = "123456789"
 	entry.Amount = 100000000
 	entry.IndividualName = "Wade Arnold"
@@ -39,7 +39,7 @@ func TestMockEntryDetail(t *testing.T) {
 	if entry.IndividualName != "Wade Arnold" {
 		t.Error("IndividualName dependent default value has changed")
 	}
-	if entry.TraceNumber != 121042880000001 {
+	if entry.TraceNumber != 62000010000001 {
 		t.Errorf("TraceNumber dependent default value has changed %v", entry.TraceNumber)
 	}
 }
@@ -65,7 +65,7 @@ func TestParseEntryDetail(t *testing.T) {
 	if record.RDFIIdentificationField() != "05320001" {
 		t.Errorf("RDFIIdentification Expected '05320001' got: '%v'", record.RDFIIdentificationField())
 	}
-	if record.CheckDigit != "9" {
+	if record.CheckDigit != 9 {
 		t.Errorf("CheckDigit Expected '9' got: %v", record.CheckDigit)
 	}
 	if record.DFIAccountNumberField() != "12345            " {
@@ -197,7 +197,7 @@ func TestEDDiscretionaryDataAlphaNumeric(t *testing.T) {
 
 func TestEDisCheckDigit(t *testing.T) {
 	ed := mockEntryDetail()
-	ed.CheckDigit = "1"
+	ed.CheckDigit = 1
 	if err := ed.Validate(); err != nil {
 		if e, ok := err.(*FieldError); ok {
 			if e.FieldName != "RDFIIdentification" {
@@ -209,11 +209,11 @@ func TestEDisCheckDigit(t *testing.T) {
 
 func TestEDSetRDFI(t *testing.T) {
 	ed := NewEntryDetail()
-	ed.SetRDFI("810866774")
-	if ed.RDFIIdentification != "81086677" {
+	ed.SetRDFI(81086674)
+	if ed.RDFIIdentification != 8108667 {
 		t.Error("RDFI identification")
 	}
-	if ed.CheckDigit != "4" {
+	if ed.CheckDigit != 4 {
 		t.Error("Unexpected check digit")
 	}
 }
@@ -244,7 +244,7 @@ func TestEDFieldInclusionTransactionCode(t *testing.T) {
 
 func TestEDFieldInclusionRDFIIdentification(t *testing.T) {
 	entry := mockEntryDetail()
-	entry.RDFIIdentification = ""
+	entry.RDFIIdentification = 0
 	if err := entry.Validate(); err != nil {
 		if e, ok := err.(*FieldError); ok {
 			if e.Msg != msgFieldInclusion {
diff --git a/fileHeader_internal_test.go b/fileHeader_internal_test.go
index f567c42c..5cfe9a45 100644
--- a/fileHeader_internal_test.go
+++ b/fileHeader_internal_test.go
@@ -13,8 +13,8 @@ import (
 // mockFileHeader build a validate File Header for tests
 func mockFileHeader() FileHeader {
 	fh := NewFileHeader()
-	fh.ImmediateDestination = "9876543210"
-	fh.ImmediateOrigin = "1234567890"
+	fh.ImmediateDestination = 9876543210
+	fh.ImmediateOrigin = 1234567890
 	fh.FileCreationDate = time.Now()
 	fh.ImmediateDestinationName = "Federal Reserve Bank"
 	fh.ImmediateOriginName = "My Bank Name"
@@ -26,10 +26,10 @@ func TestMockFileHeader(t *testing.T) {
 	if err := fh.Validate(); err != nil {
 		t.Error("mockFileHeader does not validate and will break other tests")
 	}
-	if fh.ImmediateDestination != "9876543210" {
+	if fh.ImmediateDestination != 9876543210 {
 		t.Error("ImmediateDestination depedendent default value has changed")
 	}
-	if fh.ImmediateOrigin != "1234567890" {
+	if fh.ImmediateOrigin != 1234567890 {
 		t.Error("ImmediateOrigin depedendent default value has changed")
 	}
 	if fh.ImmediateDestinationName != "Federal Reserve Bank" {
@@ -173,9 +173,9 @@ func TestFormatCode(t *testing.T) {
 	}
 }
 
-func TestFHFieldInclusion(t *testing.T) {
+func TestFHFieldInculsion(t *testing.T) {
 	fh := mockFileHeader()
-	fh.ImmediateOrigin = ""
+	fh.ImmediateOrigin = 0
 	if err := fh.Validate(); err != nil {
 		if e, ok := err.(*FieldError); ok {
 			if e.Msg != msgFieldInclusion {
@@ -259,7 +259,7 @@ func TestFHFieldInclusionRecordType(t *testing.T) {
 
 func TestFHFieldInclusionImmediatDestination(t *testing.T) {
 	fh := mockFileHeader()
-	fh.ImmediateDestination = ""
+	fh.ImmediateDestination = 0
 	if err := fh.Validate(); err != nil {
 		if e, ok := err.(*FieldError); ok {
 			if e.Msg != msgFieldInclusion {
@@ -316,15 +316,3 @@ func TestFHFieldInclusionFormatCode(t *testing.T) {
 		}
 	}
 }
-
-func TestFHFieldInclusionCreationDate(t *testing.T) {
-	fh := mockFileHeader()
-	fh.FileCreationDate = time.Time{}
-	if err := fh.Validate(); err != nil {
-		if e, ok := err.(*FieldError); ok {
-			if e.Msg != msgFieldInclusion {
-				t.Errorf("%T: %s", err, err)
-			}
-		}
-	}
-}
\ No newline at end of file
diff --git a/reader_test.go b/reader_test.go
index 127742fb..8355a5c0 100644
--- a/reader_test.go
+++ b/reader_test.go
@@ -8,6 +8,8 @@ import (
 	"os"
 	"strings"
 	"testing"
+	"bytes"
+	"fmt"
 )
 
 func TestParseError(t *testing.T) {
@@ -157,8 +159,7 @@ func TestFileLineLong(t *testing.T) {
 // TestFileFileHeaderErr ensure a parse validation error flows back from the parser.
 func TestFileFileHeaderErr(t *testing.T) {
 	fh := mockFileHeader()
-	//fh.ImmediateOrigin = "0"
-	fh.ImmediateOrigin = ""
+	fh.ImmediateOrigin = 0
 	r := NewReader(strings.NewReader(fh.String()))
 	// necessary to have a file control not nil
 	r.File.Control = mockFileControl()
@@ -177,8 +178,7 @@ func TestFileFileHeaderErr(t *testing.T) {
 // TestFileBatchHeaderErr ensure a parse validation error flows back from the parser.
 func TestFileBatchHeaderErr(t *testing.T) {
 	bh := mockBatchHeader()
-	//bh.ODFIIdentification = 0
-	bh.ODFIIdentification = ""
+	bh.ODFIIdentification = 0
 	r := NewReader(strings.NewReader(bh.String()))
 	_, err := r.Read()
 	if p, ok := err.(*ParseError); ok {
@@ -438,6 +438,30 @@ func TestFileAddBatchValidation(t *testing.T) {
 	}
 }
 
+func TestFileHeaderExists(t *testing.T) {
+	file := mockFilePPD()
+	buf := new(bytes.Buffer)
+	w := NewWriter(buf)
+	w.Write(file)
+	w.Flush()
+	r := NewReader(strings.NewReader(buf.String()))
+	f, err := r.Read()
+	if err != nil {
+		if p, ok := err.(*ParseError); ok {
+			if e, ok := p.Err.(*FileError); ok {
+				if e.Msg != msgFileHeader {
+					t.Errorf("%T: %s", e, e)
+				}
+			}
+		} else {
+			// error is nil if the file was parsed properly.
+			t.Errorf("%T: %s", err, err)
+		}
+	} else {
+		fmt.Println(f.Header.String())
+	}
+}
+
 // TestFileLongErr Batch Header Service Class is 000 which does not validate
 func TestFileLongErr(t *testing.T) {
 	line := "101 076401251 0764012510807291511A094101achdestname            companyname                    5000companyname                         origid    PPDCHECKPAYMT000002080730   1076401250000001"
@@ -468,22 +492,3 @@ func TestFileAddendaOutsideEntry(t *testing.T) {
 		t.Errorf("%T: %s", err, err)
 	}
 }
-
-
-func TestFileFHImmediateOrigin(t *testing.T) {
-	fh := mockFileHeader()
-	fh.ImmediateDestination = ""
-	r := NewReader(strings.NewReader(fh.String()))
-	// necessary to have a file control not nil
-	r.File.Control = mockFileControl()
-	_, err := r.Read()
-	if p, ok := err.(*ParseError); ok {
-		if e, ok := p.Err.(*FieldError); ok {
-			if e.Msg != msgFieldInclusion {
-				t.Errorf("%T: %s", e, e)
-			}
-		}
-	} else {
-		t.Errorf("%T: %s", err, err)
-	}
-}
\ No newline at end of file