From 83ead4782872f029461e1951222598c4b9d26f57 Mon Sep 17 00:00:00 2001 From: Brooke E Kline Jr Date: Tue, 30 Oct 2018 17:51:17 -0400 Subject: [PATCH] Support NOC for IAT Entries Support NOC for IAT Entries --- iatBatch.go | 217 ++++++++++++++++++++++------------------- iatBatchHeader.go | 5 +- iatBatchHeader_test.go | 21 +++- iatBatch_test.go | 100 ++++++++++++++++--- iatEntryDetail.go | 4 +- 5 files changed, 227 insertions(+), 120 deletions(-) diff --git a/iatBatch.go b/iatBatch.go index 37ca9be3c..c94ba474a 100644 --- a/iatBatch.go +++ b/iatBatch.go @@ -16,6 +16,8 @@ var ( msgBatchIATAddendum = "7 Addendum is the maximum for SEC code IAT" msgBatchIATAddendumCount = "%v Addenda %v for SEC Code IAT" msgBatchIATInvalidAddendumer = "invalid Addendumer for SEC Code IAT" + msgBatchIATNOC = "%v invalid for IAT NOC, should be %v" + msgBatchIATInvalidAddenda = "%v is only valid for %v entry" ) // IATBatch holds the Batch Header and Batch Control and all Entry Records for an IAT batch @@ -139,15 +141,16 @@ func (batch *IATBatch) build() error { batch.Entries[i].SetTraceNumber(batch.Header.ODFIIdentification, seq) } - // Set TraceNumber for IATEntryDetail Addenda10-16 Record Properties - entry.Addenda10.EntryDetailSequenceNumber = batch.parseNumField(batch.Entries[i].TraceNumberField()[8:]) - entry.Addenda11.EntryDetailSequenceNumber = batch.parseNumField(batch.Entries[i].TraceNumberField()[8:]) - entry.Addenda12.EntryDetailSequenceNumber = batch.parseNumField(batch.Entries[i].TraceNumberField()[8:]) - entry.Addenda13.EntryDetailSequenceNumber = batch.parseNumField(batch.Entries[i].TraceNumberField()[8:]) - entry.Addenda14.EntryDetailSequenceNumber = batch.parseNumField(batch.Entries[i].TraceNumberField()[8:]) - entry.Addenda15.EntryDetailSequenceNumber = batch.parseNumField(batch.Entries[i].TraceNumberField()[8:]) - entry.Addenda16.EntryDetailSequenceNumber = batch.parseNumField(batch.Entries[i].TraceNumberField()[8:]) - + if entry.Category != CategoryNOC { + // Set TraceNumber for IATEntryDetail Addenda10-16 Record Properties + entry.Addenda10.EntryDetailSequenceNumber = batch.parseNumField(batch.Entries[i].TraceNumberField()[8:]) + entry.Addenda11.EntryDetailSequenceNumber = batch.parseNumField(batch.Entries[i].TraceNumberField()[8:]) + entry.Addenda12.EntryDetailSequenceNumber = batch.parseNumField(batch.Entries[i].TraceNumberField()[8:]) + entry.Addenda13.EntryDetailSequenceNumber = batch.parseNumField(batch.Entries[i].TraceNumberField()[8:]) + entry.Addenda14.EntryDetailSequenceNumber = batch.parseNumField(batch.Entries[i].TraceNumberField()[8:]) + entry.Addenda15.EntryDetailSequenceNumber = batch.parseNumField(batch.Entries[i].TraceNumberField()[8:]) + entry.Addenda16.EntryDetailSequenceNumber = batch.parseNumField(batch.Entries[i].TraceNumberField()[8:]) + } // Set TraceNumber for Addendumer Addenda17 and Addenda18 SequenceNumber and EntryDetailSequenceNumber seq++ addenda17Seq := 1 @@ -229,27 +232,30 @@ func (batch *IATBatch) isFieldInclusion() error { if err := batch.addendaFieldInclusion(entry); err != nil { return err } - // Verifies each Addenda* record is valid - if err := entry.Addenda10.Validate(); err != nil { - return err - } - if err := entry.Addenda11.Validate(); err != nil { - return err - } - if err := entry.Addenda12.Validate(); err != nil { - return err - } - if err := entry.Addenda13.Validate(); err != nil { - return err - } - if err := entry.Addenda14.Validate(); err != nil { - return err - } - if err := entry.Addenda15.Validate(); err != nil { - return err - } - if err := entry.Addenda16.Validate(); err != nil { - return err + + if entry.Category != CategoryNOC { + // Verifies each Addenda* record is valid + if err := entry.Addenda10.Validate(); err != nil { + return err + } + if err := entry.Addenda11.Validate(); err != nil { + return err + } + if err := entry.Addenda12.Validate(); err != nil { + return err + } + if err := entry.Addenda13.Validate(); err != nil { + return err + } + if err := entry.Addenda14.Validate(); err != nil { + return err + } + if err := entry.Addenda15.Validate(); err != nil { + return err + } + if err := entry.Addenda16.Validate(); err != nil { + return err + } } // Verifies addendumer Addenda17 and Addenda18 records are valid for _, IATAddenda := range entry.Addendum { @@ -365,33 +371,35 @@ func (batch *IATBatch) isAddendaSequence() error { // Verify Addenda* entry detail sequence numbers are valid entryTN := entry.TraceNumberField()[8:] - if entry.Addenda10.EntryDetailSequenceNumberField() != entryTN { - msg := fmt.Sprintf(msgBatchAddendaTraceNumber, entry.Addenda10.EntryDetailSequenceNumberField(), entry.TraceNumberField()[8:]) - return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "TraceNumber", Msg: msg} - } - if entry.Addenda11.EntryDetailSequenceNumberField() != entryTN { - msg := fmt.Sprintf(msgBatchAddendaTraceNumber, entry.Addenda11.EntryDetailSequenceNumberField(), entry.TraceNumberField()[8:]) - return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "TraceNumber", Msg: msg} - } - if entry.Addenda12.EntryDetailSequenceNumberField() != entryTN { - msg := fmt.Sprintf(msgBatchAddendaTraceNumber, entry.Addenda12.EntryDetailSequenceNumberField(), entry.TraceNumberField()[8:]) - return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "TraceNumber", Msg: msg} - } - if entry.Addenda13.EntryDetailSequenceNumberField() != entryTN { - msg := fmt.Sprintf(msgBatchAddendaTraceNumber, entry.Addenda13.EntryDetailSequenceNumberField(), entry.TraceNumberField()[8:]) - return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "TraceNumber", Msg: msg} - } - if entry.Addenda14.EntryDetailSequenceNumberField() != entryTN { - msg := fmt.Sprintf(msgBatchAddendaTraceNumber, entry.Addenda14.EntryDetailSequenceNumberField(), entry.TraceNumberField()[8:]) - return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "TraceNumber", Msg: msg} - } - if entry.Addenda15.EntryDetailSequenceNumberField() != entryTN { - msg := fmt.Sprintf(msgBatchAddendaTraceNumber, entry.Addenda15.EntryDetailSequenceNumberField(), entry.TraceNumberField()[8:]) - return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "TraceNumber", Msg: msg} - } - if entry.Addenda16.EntryDetailSequenceNumberField() != entryTN { - msg := fmt.Sprintf(msgBatchAddendaTraceNumber, entry.Addenda16.EntryDetailSequenceNumberField(), entry.TraceNumberField()[8:]) - return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "TraceNumber", Msg: msg} + if entry.Category != CategoryNOC { + if entry.Addenda10.EntryDetailSequenceNumberField() != entryTN { + msg := fmt.Sprintf(msgBatchAddendaTraceNumber, entry.Addenda10.EntryDetailSequenceNumberField(), entry.TraceNumberField()[8:]) + return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "TraceNumber", Msg: msg} + } + if entry.Addenda11.EntryDetailSequenceNumberField() != entryTN { + msg := fmt.Sprintf(msgBatchAddendaTraceNumber, entry.Addenda11.EntryDetailSequenceNumberField(), entry.TraceNumberField()[8:]) + return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "TraceNumber", Msg: msg} + } + if entry.Addenda12.EntryDetailSequenceNumberField() != entryTN { + msg := fmt.Sprintf(msgBatchAddendaTraceNumber, entry.Addenda12.EntryDetailSequenceNumberField(), entry.TraceNumberField()[8:]) + return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "TraceNumber", Msg: msg} + } + if entry.Addenda13.EntryDetailSequenceNumberField() != entryTN { + msg := fmt.Sprintf(msgBatchAddendaTraceNumber, entry.Addenda13.EntryDetailSequenceNumberField(), entry.TraceNumberField()[8:]) + return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "TraceNumber", Msg: msg} + } + if entry.Addenda14.EntryDetailSequenceNumberField() != entryTN { + msg := fmt.Sprintf(msgBatchAddendaTraceNumber, entry.Addenda14.EntryDetailSequenceNumberField(), entry.TraceNumberField()[8:]) + return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "TraceNumber", Msg: msg} + } + if entry.Addenda15.EntryDetailSequenceNumberField() != entryTN { + msg := fmt.Sprintf(msgBatchAddendaTraceNumber, entry.Addenda15.EntryDetailSequenceNumberField(), entry.TraceNumberField()[8:]) + return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "TraceNumber", Msg: msg} + } + if entry.Addenda16.EntryDetailSequenceNumberField() != entryTN { + msg := fmt.Sprintf(msgBatchAddendaTraceNumber, entry.Addenda16.EntryDetailSequenceNumberField(), entry.TraceNumberField()[8:]) + return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "TraceNumber", Msg: msg} + } } // check if sequence is ascending for addendumer - Addenda17 and Addenda18 @@ -447,33 +455,36 @@ func (batch *IATBatch) isCategory() error { } func (batch *IATBatch) addendaFieldInclusion(entry *IATEntryDetail) error { - if entry.Addenda10 == nil { - msg := fmt.Sprint(msgIATBatchAddendaRequired) - return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "Addenda10", Msg: msg} - } - if entry.Addenda11 == nil { - msg := fmt.Sprint(msgIATBatchAddendaRequired) - return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "Addenda11", Msg: msg} - } - if entry.Addenda12 == nil { - msg := fmt.Sprint(msgIATBatchAddendaRequired) - return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "Addenda12", Msg: msg} - } - if entry.Addenda13 == nil { - msg := fmt.Sprint(msgIATBatchAddendaRequired) - return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "Addenda13", Msg: msg} - } - if entry.Addenda14 == nil { - msg := fmt.Sprint(msgIATBatchAddendaRequired) - return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "Addenda14", Msg: msg} - } - if entry.Addenda15 == nil { - msg := fmt.Sprint(msgIATBatchAddendaRequired) - return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "Addenda15", Msg: msg} - } - if entry.Addenda16 == nil { - msg := fmt.Sprint(msgIATBatchAddendaRequired) - return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "Addenda16", Msg: msg} + + if entry.Category != CategoryNOC { + if entry.Addenda10 == nil { + msg := fmt.Sprint(msgIATBatchAddendaRequired) + return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "Addenda10", Msg: msg} + } + if entry.Addenda11 == nil { + msg := fmt.Sprint(msgIATBatchAddendaRequired) + return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "Addenda11", Msg: msg} + } + if entry.Addenda12 == nil { + msg := fmt.Sprint(msgIATBatchAddendaRequired) + return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "Addenda12", Msg: msg} + } + if entry.Addenda13 == nil { + msg := fmt.Sprint(msgIATBatchAddendaRequired) + return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "Addenda13", Msg: msg} + } + if entry.Addenda14 == nil { + msg := fmt.Sprint(msgIATBatchAddendaRequired) + return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "Addenda14", Msg: msg} + } + if entry.Addenda15 == nil { + msg := fmt.Sprint(msgIATBatchAddendaRequired) + return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "Addenda15", Msg: msg} + } + if entry.Addenda16 == nil { + msg := fmt.Sprint(msgIATBatchAddendaRequired) + return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "Addenda16", Msg: msg} + } } return nil } @@ -499,15 +510,17 @@ func (batch *IATBatch) Validate() error { for _, entry := range batch.Entries { - // Addendum cannot be greater than 7, There can be a maximum of 2 Addenda17 and a maximum of 5 Addenda18 - if len(entry.Addendum) > 7 { - return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "Addendum", Msg: msgBatchIATAddendum} + switch entry.Category { + + case CategoryForward: + if len(entry.Addendum) > 7 { + return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "Addendum", Msg: msgBatchIATAddendum} + } + default: } addenda17Count := 0 addenda18Count := 0 - addenda98Count := 0 - addenda99Count := 0 for _, IATAddenda := range entry.Addendum { @@ -525,23 +538,27 @@ func (batch *IATBatch) Validate() error { return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "Addendum", Msg: msg} } case "98": - addenda98Count = addenda98Count + 1 - if addenda98Count > 1 { - msg := fmt.Sprintf(msgBatchIATAddendumCount, addenda99Count, "98") - return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "Addendum", Msg: msg} + if batch.GetHeader().IATIndicator != "IATCOR" { + msg := fmt.Sprintf(msgBatchIATNOC, batch.GetHeader().IATIndicator, "IATCOR") + return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "IATIndicator", Msg: msg} } - case "99": - addenda99Count = addenda99Count + 1 - if addenda99Count > 1 { - msg := fmt.Sprintf(msgBatchIATAddendumCount, addenda99Count, "99") - return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "Addendum", Msg: msg} + if batch.GetHeader().StandardEntryClassCode != "COR" { + msg := fmt.Sprintf(msgBatchIATNOC, batch.GetHeader().StandardEntryClassCode, "COR") + return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "StandardEntryClassCode", Msg: msg} + } + switch entry.TransactionCode { + case 22, 27, 32, 37, 42, 47, 52, 55, + 23, 28, 33, 38, 43, 48, 53, + 24, 29, 34, 39, 44, 49, 54: + msg := fmt.Sprintf(msgBatchTransactionCode, entry.TransactionCode, "IATCOR") + return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "TransactionCode", Msg: msg} } + case "99": + // Only one Addenda99 can be added in EntryDetail.AddIATAddenda default: return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "Addendum", Msg: msgBatchIATInvalidAddendumer} } } } - // Add type specific validation. - // ... return nil } diff --git a/iatBatchHeader.go b/iatBatchHeader.go index 9b43df654..7d19f4a59 100644 --- a/iatBatchHeader.go +++ b/iatBatchHeader.go @@ -73,7 +73,6 @@ type IATBatchHeader struct { // ForeignExchangeReference Contains either the foreign exchange rate used to execute // the foreign exchange conversion of a cross-border entry or another reference to the foreign // exchange transaction. - // ToDo: potentially write a validator ForeignExchangeReference string `json:"foreignExchangeReference"` // ISODestinationCountryCode is the two-character code, as approved by the International @@ -180,8 +179,8 @@ func (iatBh *IATBatchHeader) Parse(record string) { iatBh.recordType = "5" // 2-4 If the entries are credits, always "220". If the entries are debits, always "225" iatBh.ServiceClassCode = iatBh.parseNumField(record[1:4]) - // 05-20 Leave Blank - It is only used for corrected IAT entries - iatBh.IATIndicator = " " + // 05-20 Blank except for corrected IAT entries + iatBh.IATIndicator = iatBh.parseStringField(record[4:20]) // 21-22 A code indicating currency conversion // “FV” Fixed-to-Variable // “VF” Variable-to-Fixed diff --git a/iatBatchHeader_test.go b/iatBatchHeader_test.go index a3db41cd7..cad76eb48 100644 --- a/iatBatchHeader_test.go +++ b/iatBatchHeader_test.go @@ -41,6 +41,23 @@ func mockIATReturnBatchHeaderFF() *IATBatchHeader { return bh } +// mockIATNOCBatchHeaderFF creates a IAT Return BatchHeader that is Fixed-Fixed +func mockIATNOCBatchHeaderFF() *IATBatchHeader { + bh := NewIATBatchHeader() + bh.ServiceClassCode = 220 + bh.IATIndicator = "IATCOR" + bh.ForeignExchangeIndicator = "FF" + bh.ForeignExchangeReferenceIndicator = 3 + bh.ISODestinationCountryCode = "US" + bh.OriginatorIdentification = "123456789" + bh.StandardEntryClassCode = "COR" + bh.CompanyEntryDescription = "TRADEPAYMT" + bh.ISOOriginatingCurrencyCode = "CAD" + bh.ISODestinationCurrencyCode = "USD" + bh.ODFIIdentification = "12104288" + return bh +} + // testMockIATBatchHeaderFF creates a IAT BatchHeader Fixed-Fixed func testMockIATBatchHeaderFF(t testing.TB) { bh := mockIATBatchHeaderFF() @@ -108,8 +125,8 @@ func testParseIATBatchHeader(t testing.TB) { if record.ServiceClassCode != 220 { t.Errorf("ServiceClassCode Expected '225' got: %v", record.ServiceClassCode) } - if record.IATIndicator != " " { - t.Errorf("IATIndicator Expected ' ' got: %v", record.IATIndicator) + if record.IATIndicator != "" { + t.Errorf("IATIndicator Expected '' got: %v", record.IATIndicator) } if record.ForeignExchangeIndicator != "FF" { t.Errorf("ForeignExchangeIndicator Expected ' ' got: %v", diff --git a/iatBatch_test.go b/iatBatch_test.go index efea97794..cbe1f1db3 100644 --- a/iatBatch_test.go +++ b/iatBatch_test.go @@ -97,7 +97,6 @@ func mockInvalidAddenda17() *Addenda17 { addenda17.TypeCode = "02" addenda17.SequenceNumber = 2 addenda17.EntryDetailSequenceNumber = 0000002 - return addenda17 } @@ -1907,6 +1906,7 @@ func testIATBatchAddenda99Count(t testing.TB) { mockBatch := IATBatch{} mockBatch.SetHeader(mockIATReturnBatchHeaderFF()) mockBatch.AddEntry(mockIATEntryDetail()) + mockBatch.GetEntries()[0].Category = CategoryReturn mockBatch.Entries[0].Addenda10 = mockAddenda10() mockBatch.Entries[0].Addenda11 = mockAddenda11() mockBatch.Entries[0].Addenda12 = mockAddenda12() @@ -1914,8 +1914,9 @@ func testIATBatchAddenda99Count(t testing.TB) { mockBatch.Entries[0].Addenda14 = mockAddenda14() mockBatch.Entries[0].Addenda15 = mockAddenda15() mockBatch.Entries[0].Addenda16 = mockAddenda16() + mockBatch.Entries[0].AddIATAddenda(mockAddenda17()) mockBatch.Entries[0].AddIATAddenda(mockIATAddenda99()) - mockBatch.Entries[0].AddIATAddenda(mockIATAddenda99()) + //mockBatch.Entries[0].AddIATAddenda(mockIATAddenda99()) mockBatch.category = CategoryReturn if err := mockBatch.build(); err != nil { @@ -1947,21 +1948,16 @@ func BenchmarkIATBatchAddenda99Count(b *testing.B) { } } -// TestIATBatchAddenda98Count validates IATBatch Addenda98 Count -func TestIATBatchAddenda98Count(t *testing.T) { +// TestIATBatchAddenda98TotalCount validates IATBatch Addenda98 TotalCount +func TestIATBatchAddenda98TotalCount(t *testing.T) { mockBatch := IATBatch{} - mockBatch.SetHeader(mockIATReturnBatchHeaderFF()) + mockBatch.SetHeader(mockIATNOCBatchHeaderFF()) mockBatch.AddEntry(mockIATEntryDetail()) - mockBatch.Entries[0].Addenda10 = mockAddenda10() - mockBatch.Entries[0].Addenda11 = mockAddenda11() - mockBatch.Entries[0].Addenda12 = mockAddenda12() - mockBatch.Entries[0].Addenda13 = mockAddenda13() - mockBatch.Entries[0].Addenda14 = mockAddenda14() - mockBatch.Entries[0].Addenda15 = mockAddenda15() - mockBatch.Entries[0].Addenda16 = mockAddenda16() + mockBatch.GetEntries()[0].TransactionCode = 21 + mockBatch.GetEntries()[0].AddendaRecords = 2 + mockBatch.GetEntries()[0].Category = CategoryNOC mockBatch.Entries[0].AddIATAddenda(mockIATAddenda98()) - mockBatch.Entries[0].AddIATAddenda(mockIATAddenda98()) - mockBatch.category = CategoryReturn + mockBatch.category = CategoryNOC if err := mockBatch.build(); err != nil { t.Errorf("%T: %s", err, err) @@ -1978,6 +1974,82 @@ func TestIATBatchAddenda98Count(t *testing.T) { } } +// TestIATBatchAddenda98TransactionCode validates IATBatch Transaction Code Count +func TestIATBatchAddenda98TransactionCode(t *testing.T) { + mockBatch := IATBatch{} + mockBatch.SetHeader(mockIATNOCBatchHeaderFF()) + mockBatch.AddEntry(mockIATEntryDetail()) + mockBatch.GetEntries()[0].TransactionCode = 22 + mockBatch.GetEntries()[0].Category = CategoryNOC + mockBatch.Entries[0].AddIATAddenda(mockIATAddenda98()) + mockBatch.category = CategoryNOC + + if err := mockBatch.build(); err != nil { + t.Errorf("%T: %s", err, err) + } + + if err := mockBatch.Validate(); err != nil { + if e, ok := err.(*BatchError); ok { + if e.FieldName != "TransactionCode" { + t.Errorf("%T: %s", err, err) + } + } else { + t.Errorf("%T: %s", err, err) + } + } +} + +// TestIATBatchAddenda98IATIndicator validates IATBatch Transaction Code Count +func TestIATBatchAddenda98IATIndicator(t *testing.T) { + mockBatch := IATBatch{} + mockBatch.SetHeader(mockIATNOCBatchHeaderFF()) + mockBatch.GetHeader().IATIndicator = "B" + mockBatch.AddEntry(mockIATEntryDetail()) + mockBatch.GetEntries()[0].TransactionCode = 22 + mockBatch.GetEntries()[0].Category = CategoryNOC + mockBatch.Entries[0].AddIATAddenda(mockIATAddenda98()) + mockBatch.category = CategoryNOC + + if err := mockBatch.build(); err != nil { + t.Errorf("%T: %s", err, err) + } + + if err := mockBatch.Validate(); err != nil { + if e, ok := err.(*BatchError); ok { + if e.FieldName != "IATIndicator" { + t.Errorf("%T: %s", err, err) + } + } else { + t.Errorf("%T: %s", err, err) + } + } +} + +func TestIATBatchAddenda98SECCode(t *testing.T) { + mockBatch := IATBatch{} + mockBatch.SetHeader(mockIATNOCBatchHeaderFF()) + mockBatch.GetHeader().StandardEntryClassCode = "IAT" + mockBatch.AddEntry(mockIATEntryDetail()) + mockBatch.GetEntries()[0].TransactionCode = 22 + mockBatch.GetEntries()[0].Category = CategoryNOC + mockBatch.Entries[0].AddIATAddenda(mockIATAddenda98()) + mockBatch.category = CategoryNOC + + if err := mockBatch.build(); err != nil { + t.Errorf("%T: %s", err, err) + } + + if err := mockBatch.Validate(); err != nil { + if e, ok := err.(*BatchError); ok { + if e.FieldName != "StandardEntryClassCode" { + t.Errorf("%T: %s", err, err) + } + } else { + t.Errorf("%T: %s", err, err) + } + } +} + // TestMockISODestinationCountryCode validates mockIATBatch func TestMockISODestinationCountryCode(t *testing.T) { iatBatch := mockIATBatch(t) diff --git a/iatEntryDetail.go b/iatEntryDetail.go index 40cefb869..22af10fa4 100644 --- a/iatEntryDetail.go +++ b/iatEntryDetail.go @@ -319,16 +319,18 @@ func (ed *IATEntryDetail) TraceNumberField() string { } // AddIATAddenda appends an Addendumer to the IATEntryDetail -// Currently this is used to add Addenda17 and Addenda18 IAT Addenda records +// Currently this is used to add Addenda17, Addenda18, Addenda98 and Addenda99 IAT Addenda records func (ed *IATEntryDetail) AddIATAddenda(addenda Addendumer) []Addendumer { ed.AddendaRecordIndicator = 1 switch addenda.(type) { case *Addenda98: ed.Category = CategoryNOC + ed.Addendum = nil ed.Addendum = append(ed.Addendum, addenda) return ed.Addendum case *Addenda99: ed.Category = CategoryReturn + ed.Addendum = nil ed.Addendum = append(ed.Addendum, addenda) return ed.Addendum default: