From 01546196480db377661970053c1eb7664848447e Mon Sep 17 00:00:00 2001 From: Adam Shannon Date: Fri, 11 Aug 2023 14:39:14 -0500 Subject: [PATCH] fix: Corrected Data is 29 characters, not 22 --- addenda98.go | 20 ++++++++------- addenda98_test.go | 47 +++++++++++++++++------------------ test/issues/issue1278_test.go | 47 +++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 33 deletions(-) create mode 100644 test/issues/issue1278_test.go diff --git a/addenda98.go b/addenda98.go index e05e85936..3d37dce7a 100644 --- a/addenda98.go +++ b/addenda98.go @@ -318,32 +318,34 @@ func first(size int, data string) string { return strings.TrimSpace(data[:size]) } +const correctedDataCharLength = 29 + // ParseCorrectedData returns the string properlty formatted and justified for an // Addenda98.CorrectedData field. The code must be an official NACHA change code. func WriteCorrectionData(code string, data *CorrectedData) string { pad := &converters{} switch strings.ToUpper(code) { case "C01": - return pad.alphaField(data.AccountNumber, 22) + return pad.alphaField(data.AccountNumber, correctedDataCharLength) case "C02": - return pad.alphaField(data.RoutingNumber, 22) + return pad.alphaField(data.RoutingNumber, correctedDataCharLength) case "C03": - spaces := strings.Repeat(" ", 22-len(data.RoutingNumber)-len(data.AccountNumber)) + spaces := strings.Repeat(" ", correctedDataCharLength-len(data.RoutingNumber)-len(data.AccountNumber)) return fmt.Sprintf("%s%s%s", data.RoutingNumber, spaces, data.AccountNumber) case "C04": - return pad.alphaField(data.Name, 22) + return pad.alphaField(data.Name, correctedDataCharLength) case "C05": - return pad.alphaField(strconv.Itoa(data.TransactionCode), 22) + return pad.alphaField(strconv.Itoa(data.TransactionCode), correctedDataCharLength) case "C06": txcode := strconv.Itoa(data.TransactionCode) - spaces := strings.Repeat(" ", 22-len(data.AccountNumber)-len(txcode)) + spaces := strings.Repeat(" ", correctedDataCharLength-len(data.AccountNumber)-len(txcode)) return fmt.Sprintf("%s%s%s", data.AccountNumber, spaces, txcode) case "C07": txcode := strconv.Itoa(data.TransactionCode) - spaces := strings.Repeat(" ", 22-9-len(data.AccountNumber)-len(txcode)) + spaces := strings.Repeat(" ", correctedDataCharLength-9-len(data.AccountNumber)-len(txcode)) return fmt.Sprintf("%s%s%s%s", data.RoutingNumber, data.AccountNumber, spaces, txcode) case "C09": - return pad.alphaField(data.Identification, 22) + return pad.alphaField(data.Identification, correctedDataCharLength) } - return pad.alphaField("", 22) + return pad.alphaField("", correctedDataCharLength) } diff --git a/addenda98_test.go b/addenda98_test.go index 9055edea9..c9f2c21c3 100644 --- a/addenda98_test.go +++ b/addenda98_test.go @@ -21,6 +21,7 @@ import ( "testing" "github.com/moov-io/base" + "github.com/stretchr/testify/require" ) func mockAddenda98() *Addenda98 { @@ -372,6 +373,9 @@ func TestCorrectedData__ParseCorrectedData(t *testing.T) { if v := run("C03", "987654320 123456"); v.AccountNumber != "123456" || v.RoutingNumber != "987654320" { t.Errorf("%#v", v) } + if v := run("C03", "987654320 123456"); v.AccountNumber != "123456" || v.RoutingNumber != "987654320" { + t.Errorf("%#v", v) + } if v := run("C04", "Jane Doe"); v.Name != "Jane Doe" { t.Errorf("%#v", v) } @@ -387,6 +391,9 @@ func TestCorrectedData__ParseCorrectedData(t *testing.T) { if v := run("C07", "9876543201242415 22"); v.RoutingNumber != "987654320" || v.AccountNumber != "1242415" || v.TransactionCode != 22 { t.Errorf("%#v", v) } + if v := run("C07", "9876543201242415 22"); v.RoutingNumber != "987654320" || v.AccountNumber != "1242415" || v.TransactionCode != 22 { + t.Errorf("%#v", v) + } if v := run("C07", "1234"); v != nil { t.Errorf("expected nil: %v", v) } @@ -403,35 +410,27 @@ func TestCorrectedData__ParseCorrectedData(t *testing.T) { func TestCorrectedData__WriteCorrectionData(t *testing.T) { data := &CorrectedData{AccountNumber: "12345"} - if v := WriteCorrectionData("C01", data); v != "12345 " { - t.Errorf("C01 got %q (length=%d)", v, len(v)) - } + require.Equal(t, "12345 ", WriteCorrectionData("C01", data)) + data = &CorrectedData{RoutingNumber: "987654320"} - if v := WriteCorrectionData("C02", data); v != "987654320 " { - t.Errorf("C02 got %q (length=%d)", v, len(v)) - } + require.Equal(t, "987654320 ", WriteCorrectionData("C02", data)) + data = &CorrectedData{AccountNumber: "123", RoutingNumber: "987654320"} - if v := WriteCorrectionData("C03", data); v != "987654320 123" { - t.Errorf("C03 got %q (length=%d)", v, len(v)) - } + require.Equal(t, "987654320 123", WriteCorrectionData("C03", data)) + data = &CorrectedData{Name: "Jane Doe"} - if v := WriteCorrectionData("C04", data); v != "Jane Doe " { - t.Errorf("C04 got %q (length=%d)", v, len(v)) - } + require.Equal(t, "Jane Doe ", WriteCorrectionData("C04", data)) + data = &CorrectedData{TransactionCode: 22} - if v := WriteCorrectionData("C05", data); v != "22 " { - t.Errorf("C05 got %q (length=%d)", v, len(v)) - } + require.Equal(t, "22 ", WriteCorrectionData("C05", data)) + data = &CorrectedData{AccountNumber: "5421", TransactionCode: 27} - if v := WriteCorrectionData("C06", data); v != "5421 27" { - t.Errorf("C06 got %q (length=%d)", v, len(v)) - } + require.Equal(t, "5421 27", WriteCorrectionData("C06", data)) + data = &CorrectedData{RoutingNumber: "987654320", AccountNumber: "5421", TransactionCode: 32} - if v := WriteCorrectionData("C07", data); v != "9876543205421 32" { - t.Errorf("C07 got %q (length=%d)", v, len(v)) - } + require.Equal(t, "9876543205421 32", WriteCorrectionData("C07", data)) + data = &CorrectedData{Identification: "FooBar"} - if v := WriteCorrectionData("C09", data); v != "FooBar " { - t.Errorf("C09 got %q (length=%d)", v, len(v)) - } + require.Equal(t, "FooBar ", WriteCorrectionData("C09", data)) + } diff --git a/test/issues/issue1278_test.go b/test/issues/issue1278_test.go new file mode 100644 index 000000000..bb7965811 --- /dev/null +++ b/test/issues/issue1278_test.go @@ -0,0 +1,47 @@ +// Licensed to The Moov Authors under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. The Moov Authors licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package issues + +import ( + "testing" + + "github.com/moov-io/ach" + + "github.com/stretchr/testify/require" +) + +func TestIssue1278(t *testing.T) { + data := &ach.CorrectedData{ + AccountNumber: "cDgvNMS41YdAlj0XD", + RoutingNumber: "021000021", + } + output := ach.WriteCorrectionData("C03", data) + + expected := "021000021 cDgvNMS41YdAlj0XD" + require.Equal(t, expected, output) + + // Verify read works + addenda98 := &ach.Addenda98{ + ChangeCode: "C03", + CorrectedData: expected, + } + data = addenda98.ParseCorrectedData() + require.NotNil(t, data) + require.Equal(t, "021000021", data.RoutingNumber) + require.Equal(t, "cDgvNMS41YdAlj0XD", data.AccountNumber) +}