Repository: moov-io/ach
Pull request #173 (2018-05-01 14:04:39)

170
# 170 int to string modifications


Patch:
diff --git a/README.md b/README.md
index 0c61fa2a..14c6aadf 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(9101298)
+entry.SetRDFI("009101298")
 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 3e732d74..815e41f4 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 int
+	OriginalDFI string
 	// CorrectedData
 	CorrectedData string
 	// TraceNumber matches the Entry Detail Trace Number of the entry being returned.
@@ -72,7 +72,7 @@ func (addenda98 *Addenda98) Parse(record string) {
 	// 7-21
 	addenda98.OriginalTrace = addenda98.parseNumField(record[6:21])
 	// 28-35
-	addenda98.OriginalDFI = addenda98.parseNumField(record[27:35])
+	addenda98.OriginalDFI = addenda98.parseStringField(record[27:35])
 	// 36-64
 	addenda98.CorrectedData = strings.TrimSpace(record[35:64])
 	// 80-94
@@ -131,7 +131,7 @@ func (addenda98 *Addenda98) OriginalTraceField() string {
 
 // OriginalDFIField returns a zero padded OriginalDFI string
 func (addenda98 *Addenda98) OriginalDFIField() string {
-	return addenda98.numericField(addenda98.OriginalDFI, 8)
+	return addenda98.stringRTNField(addenda98.OriginalDFI, 8)
 }
 
 //CorrectedDataField returns a space padded CorrectedData string
diff --git a/addenda99.go b/addenda99.go
index 5e825dc4..25023874 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 int
+	OriginalDFI string
 	// 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.parseNumField(record[27:35])
+	Addenda99.OriginalDFI = Addenda99.parseStringField(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.numericField(Addenda99.OriginalDFI, 8)
+	return Addenda99.stringRTNField(Addenda99.OriginalDFI, 8)
 }
 
 //AddendaInformationField returns a space padded AddendaInformation string
diff --git a/batch.go b/batch.go
index 251d25bd..34d17870 100644
--- a/batch.go
+++ b/batch.go
@@ -122,8 +122,14 @@ 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 != batch.header.ODFIIdentification {
+		if currentTraceNumberODFI != batchHeaderODFI {
 			batch.entries[i].SetTraceNumber(batch.header.ODFIIdentification, seq)
 		}
 		seq++
@@ -282,7 +288,10 @@ func (batch *batch) isEntryHash() error {
 func (batch *batch) calculateEntryHash() string {
 	hash := 0
 	for _, entry := range batch.entries {
-		hash = hash + entry.RDFIIdentification
+
+		entryRDFI, _ := strconv.Atoi(entry.RDFIIdentification)
+
+		hash = hash + entryRDFI
 	}
 	return batch.numericField(hash, 10)
 }
diff --git a/batchControl.go b/batchControl.go
index 74a016f7..a5003e23 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 int
+	ODFIIdentification string
 	// 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.parseNumField(record[79:87])
+	bc.ODFIIdentification = bc.parseStringField(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 == 0 {
+	if bc.ODFIIdentification == "000000000" {
 		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.numericField(bc.ODFIIdentification, 8)
+	return bc.stringRTNField(bc.ODFIIdentification, 8)
 }
 
 // BatchNumberField gets a string of the batch number zero padded
diff --git a/batchHeader.go b/batchHeader.go
index 65d0580e..9c475c8f 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 int
+	ODFIIdentification string
 
 	// 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.parseNumField(record[79:87])
+	bh.ODFIIdentification = bh.parseStringField(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 == 0 {
+	if bh.ODFIIdentification == "" {
 		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.numericField(bh.ODFIIdentification, 8)
+	return bh.stringRTNField(bh.ODFIIdentification, 8)
 }
 
 // BatchNumberField get the batch number zero padded
diff --git a/converters.go b/converters.go
index 0f74b225..a80962d8 100644
--- a/converters.go
+++ b/converters.go
@@ -18,6 +18,11 @@ 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")
@@ -40,8 +45,6 @@ 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))
@@ -62,3 +65,13 @@ 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 77a354b1..fcb3ca7e 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 int
+	RDFIIdentification string
 
 	// CheckDigit the last digit of the RDFI's routing number
-	CheckDigit int
+	CheckDigit string
 
 	// 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.parseNumField(record[3:11])
+	ed.RDFIIdentification = ed.parseStringField(record[3:11])
 	// 12-12 The last digit of the RDFI's routing number
-	ed.CheckDigit = ed.parseNumField(record[11:12])
+	ed.CheckDigit = ed.parseStringField(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,10 +169,17 @@ 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())
-	if calculated != ed.CheckDigit {
+
+	edCheckDigit, err := strconv.Atoi(ed.CheckDigit)
+	if err != nil {
+		return err
+	}
+
+	if calculated != edCheckDigit {
 		msg := fmt.Sprintf(msgValidCheckDigit, calculated)
-		return &FieldError{FieldName: "RDFIIdentification", Value: strconv.Itoa(ed.CheckDigit), Msg: msg}
+		return &FieldError{FieldName: "RDFIIdentification", Value: ed.CheckDigit, Msg: msg}
 	}
 	return nil
 }
@@ -186,7 +193,7 @@ func (ed *EntryDetail) fieldInclusion() error {
 	if ed.TransactionCode == 0 {
 		return &FieldError{FieldName: "TransactionCode", Value: strconv.Itoa(ed.TransactionCode), Msg: msgFieldInclusion}
 	}
-	if ed.RDFIIdentification == 0 {
+	if ed.RDFIIdentification == "" {
 		return &FieldError{FieldName: "RDFIIdentification", Value: ed.RDFIIdentificationField(), Msg: msgFieldInclusion}
 	}
 	if ed.DFIAccountNumber == "" {
@@ -225,22 +232,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 int) *EntryDetail {
-	s := ed.numericField(rdfi, 9)
-	ed.RDFIIdentification = ed.parseNumField(s[:8])
-	ed.CheckDigit = ed.parseNumField(s[8:9])
+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])
 	return ed
 }
 
 // SetTraceNumber takes first 8 digits of ODFI and concatenates a sequence number onto the TraceNumber
-func (ed *EntryDetail) SetTraceNumber(ODFIIdentification int, seq int) {
-	trace := ed.numericField(ODFIIdentification, 8) + ed.numericField(seq, 7)
+func (ed *EntryDetail) SetTraceNumber(ODFIIdentification string, seq int) {
+	trace := ed.stringRTNField(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.numericField(ed.RDFIIdentification, 8)
+	return ed.stringRTNField(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 5c0a838c..96b7d805 100644
--- a/example/ach-ppd-write/main.go
+++ b/example/ach-ppd-write/main.go
@@ -3,7 +3,6 @@ package main
 import (
 	"log"
 	"os"
-	"strconv"
 	"time"
 
 	"github.com/moov-io/ach"
@@ -16,9 +15,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 = 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.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.ImmediateDestinationName = "Federal Reserve Bank"
 	fh.ImmediateOriginName = "My Bank Name"
 
@@ -26,18 +25,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 = strconv.Itoa(fh.ImmediateOrigin)
+	bh.CompanyIdentification = 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 = 12345678 // first 8 digits of your bank account
+	bh.ODFIIdentification = "121042882" // Originating Routing Number
 
 	// 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(9101298)              // Receivers bank transit routing number
+	entry.SetRDFI("231380104")          // 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 74e7a6ed..9a744193 100644
--- a/example/simple-file-creation/main.go
+++ b/example/simple-file-creation/main.go
@@ -5,15 +5,14 @@ import (
 	"os"
 
 	"github.com/moov-io/ach"
-	"strconv"
 	"time"
 )
 
 func main() {
 	// To create a file
 	fh := ach.NewFileHeader()
-	fh.ImmediateDestination = 9876543210
-	fh.ImmediateOrigin = 1234567890
+	fh.ImmediateDestination = "231380104"
+	fh.ImmediateOrigin = "121042882"
 	fh.FileCreationDate = time.Now()
 	fh.ImmediateDestinationName = "Federal Reserve Bank"
 	fh.ImmediateOriginName = "My Bank Name"
@@ -25,20 +24,20 @@ func main() {
 	bh := ach.NewBatchHeader()
 	bh.ServiceClassCode = 200
 	bh.CompanyName = "Your Company"
-	bh.CompanyIdentification = strconv.Itoa(file.Header.ImmediateOrigin)
+	bh.CompanyIdentification = file.Header.ImmediateOrigin
 	bh.StandardEntryClassCode = "PPD"
 	bh.CompanyEntryDescription = "Trans. Description"
 	bh.EffectiveEntryDate = time.Now().AddDate(0, 0, 1)
-	bh.ODFIIdentification = 123456789
+	bh.ODFIIdentification = "121042882"
 
 	batch, _ := ach.NewBatch(bh)
 
 	// To create an entry
 	entry := ach.NewEntryDetail()
 	entry.TransactionCode = 22
-	entry.SetRDFI(9101298)
-	entry.DFIAccountNumber = "123456789"
-	entry.Amount = 100000000
+	entry.SetRDFI("231380104")
+	entry.DFIAccountNumber = "81967038518"
+	entry.Amount = 1000000
 	entry.IndividualName = "Wade Arnold"
 	entry.SetTraceNumber(bh.ODFIIdentification, 1)
 	entry.IdentificationNumber = "ABC##jvkdjfuiwn"
@@ -69,11 +68,11 @@ func main() {
 	bh2 := ach.NewBatchHeader()
 	bh2.ServiceClassCode = 220
 	bh2.CompanyName = "Your Company"
-	bh2.CompanyIdentification = strconv.Itoa(file.Header.ImmediateOrigin)
+	bh2.CompanyIdentification = file.Header.ImmediateOrigin
 	bh2.StandardEntryClassCode = "WEB"
 	bh2.CompanyEntryDescription = "Subscr"
 	bh2.EffectiveEntryDate = time.Now().AddDate(0, 0, 1)
-	bh2.ODFIIdentification = 123456789
+	bh2.ODFIIdentification = "121042882"
 
 	batch2, _ := ach.NewBatch(bh2)
 
@@ -82,8 +81,8 @@ func main() {
 
 	entry2 := ach.NewEntryDetail()
 	entry2.TransactionCode = 22
-	entry2.SetRDFI(102001017)
-	entry2.DFIAccountNumber = "5343121"
+	entry2.SetRDFI("231380104")
+	entry2.DFIAccountNumber = "81967038518"
 	entry2.Amount = 799
 	entry2.IndividualName = "Wade Arnold"
 	entry2.SetTraceNumber(bh2.ODFIIdentification, 2)
diff --git a/fileHeader.go b/fileHeader.go
index 49d0f4d4..0b24c9f9 100644
--- a/fileHeader.go
+++ b/fileHeader.go
@@ -31,18 +31,20 @@ 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 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
+	// 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
 
 	// ImmediateOrigin contains the Routing Number of the ACH Operator or sending
-	// 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
+	// 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
 
 	// 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)
@@ -111,9 +113,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.parseNumField(record[3:13])
+	fh.ImmediateDestination = fh.parseStringField(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.parseNumField(record[13:23])
+	fh.ImmediateOrigin = fh.parseStringField(record[13:23])
 	// 24-29 Today's date in YYMMDD format
 	// must be after todays date.
 	fh.FileCreationDate = fh.parseSimpleDate(record[23:29])
@@ -185,6 +187,12 @@ 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()}
 	}
@@ -207,10 +215,10 @@ func (fh *FileHeader) fieldInclusion() error {
 	if fh.recordType == "" {
 		return &FieldError{FieldName: "recordType", Value: fh.recordType, Msg: msgFieldInclusion}
 	}
-	if fh.ImmediateDestination == 0 {
+	if fh.ImmediateDestination == "" {
 		return &FieldError{FieldName: "ImmediateDestination", Value: fh.ImmediateDestinationField(), Msg: msgFieldInclusion}
 	}
-	if fh.ImmediateOrigin == 0 {
+	if fh.ImmediateOrigin == "" {
 		return &FieldError{FieldName: "ImmediateOrigin", Value: fh.ImmediateOriginField(), Msg: msgFieldInclusion}
 	}
 	if fh.FileCreationDate.IsZero() {
@@ -233,12 +241,12 @@ func (fh *FileHeader) fieldInclusion() error {
 
 // ImmediateDestinationField gets the immediate destination number with zero padding
 func (fh *FileHeader) ImmediateDestinationField() string {
-	return " " + fh.numericField(fh.ImmediateDestination, 9)
+	return " " + fh.stringRTNField(fh.ImmediateDestination, 9)
 }
 
 // ImmediateOriginField gets the immediate origin number with 0 padding
 func (fh *FileHeader) ImmediateOriginField() string {
-	return " " + fh.numericField(fh.ImmediateOrigin, 9)
+	return " " + fh.stringRTNField(fh.ImmediateOrigin, 9)
 }
 
 // FileCreationDateField gets the file creation date in YYMMDD format
diff --git a/writer.go b/writer.go
index 02349976..e359b3cd 100644
--- a/writer.go
+++ b/writer.go
@@ -89,7 +89,7 @@ func (w *Writer) Error() error {
 	return err
 }
 
-// WriteAll writes multiple ach.fieles to w using Write and then calls Flush.
+// WriteAll writes multiple ach.files 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 cfa346aa..c09576cc 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 != 9101298 {
-		t.Errorf("expected %v got %v", 9101298, addenda98.OriginalDFI)
+	if addenda98.OriginalDFI != "09101298" {
+		t.Errorf("expected %s got %s", "09101298", 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 bf341ca4..51356e55 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
 }
@@ -39,8 +39,8 @@ func TestAddenda99Parse(t *testing.T) {
 	if addenda99.DateOfDeath.IsZero() != true {
 		t.Errorf("expected: %v got: %v", time.Time{}, addenda99.DateOfDeath)
 	}
-	if addenda99.OriginalDFI != 9101298 {
-		t.Errorf("expected: %v got: %v", 9101298, addenda99.OriginalDFI)
+	if addenda99.OriginalDFI != "09101298" {
+		t.Errorf("expected: %s got: %s", "09101298", 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 b4806a26..d4c96e24 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 = "123456789"
+	bh.CompanyIdentification = "121042882"
 	bh.CompanyEntryDescription = "Vndr Pay"
-	bh.ODFIIdentification = 6200001
+	bh.ODFIIdentification = "121042882"
 	return bh
 }
 
 func mockCCDEntryDetail() *EntryDetail {
 	entry := NewEntryDetail()
 	entry.TransactionCode = 27
-	entry.SetRDFI(9101298)
+	entry.SetRDFI("231380104")
 	entry.DFIAccountNumber = "744-5678-99"
 	entry.Amount = 5000000
 	entry.IdentificationNumber = "location #23"
diff --git a/batchCOR_test.go b/batchCOR_test.go
index 8db3c563..98e478eb 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 = "123456789"
+	bh.CompanyIdentification = "121042882"
 	bh.CompanyEntryDescription = "Vndr Pay"
-	bh.ODFIIdentification = 6200001
+	bh.ODFIIdentification = "121042882"
 	return bh
 }
 
 func mockCOREntryDetail() *EntryDetail {
 	entry := NewEntryDetail()
 	entry.TransactionCode = 27
-	entry.SetRDFI(9101298)
+	entry.SetRDFI("231380104")
 	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 e6fa7cbf..2b85409b 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 = "123456789"
-	bc.ODFIIdentification = 6200001
+	bc.CompanyIdentification = "121042882"
+	bc.ODFIIdentification = "12104288"
 	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 != "123456789" {
+	if bc.CompanyIdentification != "121042882" {
 		t.Error("CompanyIdentification depedendent default value has changed")
 	}
-	if bc.ODFIIdentification != 6200001 {
+	if bc.ODFIIdentification != "12104288" {
 		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 = 0
+	bc.ODFIIdentification = "000000000"
 	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 cab77c8a..33b2317d 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 = "123456789"
+	bh.CompanyIdentification = "121042882"
 	bh.CompanyEntryDescription = "PAYROLL"
-	bh.ODFIIdentification = 6200001
+	bh.ODFIIdentification = "12104288"
 	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 != "123456789" {
+	if bh.CompanyIdentification != "121042882" {
 		t.Error("CompanyIdentification dependent default value has changed")
 	}
 	if bh.CompanyEntryDescription != "PAYROLL" {
 		t.Error("CompanyEntryDescription dependent default value has changed")
 	}
-	if bh.ODFIIdentification != 6200001 {
+	if bh.ODFIIdentification != "12104288" {
 		t.Error("ODFIIdentification dependent default value has changed")
 	}
 }
@@ -294,3 +294,15 @@ 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 1e140bc2..2ace3b12 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 = "123456789"
+	bh.CompanyIdentification = "121042882"
 	bh.CompanyEntryDescription = "PAYROLL"
 	bh.EffectiveEntryDate = time.Now()
-	bh.ODFIIdentification = 6200001
+	bh.ODFIIdentification = "12104288"
 	return bh
 }
 
 func mockPPDEntryDetail() *EntryDetail {
 	entry := NewEntryDetail()
 	entry.TransactionCode = 22
-	entry.SetRDFI(9101298)
+	entry.SetRDFI("231380104")
 	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 = "1419871234"
+	bh.CompanyIdentification = "121042882"
 	bh.StandardEntryClassCode = "PPD"
 	bh.CompanyEntryDescription = "PAYROLL"
 	bh.EffectiveEntryDate = time.Now()
-	bh.ODFIIdentification = 109991234
+	bh.ODFIIdentification = "12104288"
 	return bh
 }
 
 func mockPPDEntry2() *EntryDetail {
 	entry := NewEntryDetail()
-	entry.TransactionCode = 22                  // ACH Credit
-	entry.SetRDFI(81086674)                     // scottrade bank routing number
-	entry.DFIAccountNumber = "62292250"         // scottrade account number
-	entry.Amount = 1000000                      // 1k dollars
+	entry.TransactionCode = 22 // ACH Credit
+	entry.SetRDFI("231380104")
+	entry.DFIAccountNumber = "62292250"         // account number
+	entry.Amount = 100000                       // 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 a1dbc2e3..16967ceb 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 = "123456789"
+	bh.CompanyIdentification = "121042882"
 	bh.CompanyEntryDescription = "Vndr Pay"
-	bh.ODFIIdentification = 6200001
+	bh.ODFIIdentification = "12104288"
 	return bh
 }
 
 func mockTELEntryDetail() *EntryDetail {
 	entry := NewEntryDetail()
 	entry.TransactionCode = 27
-	entry.SetRDFI(9101298)
+	entry.SetRDFI("231380104")
 	entry.DFIAccountNumber = "744-5678-99"
 	entry.Amount = 5000000
 	entry.IdentificationNumber = "Phone 333-2222"
diff --git a/batchWEB_test.go b/batchWEB_test.go
index 6a704c30..e1814e09 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 = "123456789"
+	bh.CompanyIdentification = "121042882"
 	bh.CompanyEntryDescription = "Online Order"
-	bh.ODFIIdentification = 6200001
+	bh.ODFIIdentification = "12104288"
 	return bh
 }
 
 func mockWEBEntryDetail() *EntryDetail {
 	entry := NewEntryDetail()
 	entry.TransactionCode = 22
-	entry.SetRDFI(9101298)
+	entry.SetRDFI("231380104")
 	entry.DFIAccountNumber = "123456789"
 	entry.Amount = 100000000
 	entry.IndividualName = "Wade Arnold"
diff --git a/batch_test.go b/batch_test.go
index 2837a28e..79afbc87 100644
--- a/batch_test.go
+++ b/batch_test.go
@@ -16,6 +16,36 @@ 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()
@@ -25,7 +55,7 @@ func mockBatchInvalidSECHeader() *BatchHeader {
 	bh.CompanyIdentification = "123456789"
 	bh.CompanyEntryDescription = "PAYROLL"
 	bh.EffectiveEntryDate = time.Now()
-	bh.ODFIIdentification = 6200001
+	bh.ODFIIdentification = "123456789"
 	return bh
 }
 
@@ -137,7 +167,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" {
@@ -306,3 +336,52 @@ 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 cf57646b..53ab199f 100644
--- a/converters_test.go
+++ b/converters_test.go
@@ -50,3 +50,38 @@ 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 46194a55..b8c22b2c 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(9101298)
+	entry.SetRDFI("121042882")
 	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 != 62000010000001 {
+	if entry.TraceNumber != 121042880000001 {
 		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(81086674)
-	if ed.RDFIIdentification != 8108667 {
+	ed.SetRDFI("810866774")
+	if ed.RDFIIdentification != "81086677" {
 		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 = 0
+	entry.RDFIIdentification = ""
 	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 5cfe9a45..f567c42c 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 TestFHFieldInculsion(t *testing.T) {
+func TestFHFieldInclusion(t *testing.T) {
 	fh := mockFileHeader()
-	fh.ImmediateOrigin = 0
+	fh.ImmediateOrigin = ""
 	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 = 0
+	fh.ImmediateDestination = ""
 	if err := fh.Validate(); err != nil {
 		if e, ok := err.(*FieldError); ok {
 			if e.Msg != msgFieldInclusion {
@@ -316,3 +316,15 @@ 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 8355a5c0..127742fb 100644
--- a/reader_test.go
+++ b/reader_test.go
@@ -8,8 +8,6 @@ import (
 	"os"
 	"strings"
 	"testing"
-	"bytes"
-	"fmt"
 )
 
 func TestParseError(t *testing.T) {
@@ -159,7 +157,8 @@ 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 = "0"
+	fh.ImmediateOrigin = ""
 	r := NewReader(strings.NewReader(fh.String()))
 	// necessary to have a file control not nil
 	r.File.Control = mockFileControl()
@@ -178,7 +177,8 @@ 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 = 0
+	bh.ODFIIdentification = ""
 	r := NewReader(strings.NewReader(bh.String()))
 	_, err := r.Read()
 	if p, ok := err.(*ParseError); ok {
@@ -438,30 +438,6 @@ 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"
@@ -492,3 +468,22 @@ 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