diff --git a/.gitignore b/.gitignore index 1c3fe2ae..45d0f791 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,8 @@ *.a *.so +.DS_Store + # Folders _obj _test diff --git a/pkg/response/file_transformer.go b/pkg/response/file_transformer.go index 9b112709..a09d2d31 100644 --- a/pkg/response/file_transformer.go +++ b/pkg/response/file_transformer.go @@ -1,10 +1,12 @@ package response import ( + "cmp" "context" "fmt" "math/rand" "path/filepath" + "slices" "time" "github.com/moov-io/ach" @@ -99,6 +101,11 @@ func (ft *FileTransfomer) Transform(ctx context.Context, file *ach.File) error { for delay, batchesByCategory := range outBatches { for _, batch := range batchesByCategory { if entries = (*batch).GetEntries(); len(entries) > 0 { + // Sort the entries before the final build + slices.SortFunc(entries, func(e1, e2 *ach.EntryDetail) int { + return cmp.Compare(e1.TraceNumber, e2.TraceNumber) + }) + if err := (*batch).Create(); err != nil { return fmt.Errorf("transform batch[%d] create error: %v", i, err) } diff --git a/pkg/response/file_transformer_test.go b/pkg/response/file_transformer_test.go index 9eca1e89..8324c392 100644 --- a/pkg/response/file_transformer_test.go +++ b/pkg/response/file_transformer_test.go @@ -59,6 +59,9 @@ var ( Value: 62_01, }, } + matchRoutingNumber = service.Match{ + RoutingNumber: "083000137", + } actionReturn = service.Action{ Return: &service.Return{ @@ -1040,3 +1043,23 @@ func TestFileTransformer_CTX(t *testing.T) { require.Equal(t, "C01", entries[0].Addenda98.ChangeCode) }) } + +func TestFileTransform_Sorted(t *testing.T) { + resp := service.Response{ + Match: matchRoutingNumber, + Action: actionReturn, + } + fileTransformer, _ := testFileTransformer(t, resp) + + // read the file + achIn, err := ach.ReadFile(filepath.Join("..", "..", "testdata", "out-of-order.ach")) + require.NoError(t, err) + require.NotNil(t, achIn) + + // transform the file several times making sure we don't error + // The code can sometimes reorder entries which causes the transform to fail + for i := 0; i < 100; i++ { + err := fileTransformer.Transform(context.Background(), achIn) + require.NoError(t, err) + } +} diff --git a/testdata/out-of-order.ach b/testdata/out-of-order.ach new file mode 100644 index 00000000..228d5bf2 --- /dev/null +++ b/testdata/out-of-order.ach @@ -0,0 +1,7 @@ +101 011000015 2214757862412170450A094101FRBBOSTON MOOVODFI +5200BT* Matt's Biz MjZjNDQzY2CCD12275-1 241217 1221475780000004 +622083000137345452324 0000000180 Matt Ryavec Co cc0221475780029324 +622083000137121212 0000000100 Matt Ryavec Co 390221475780109254 +82000000020016600026000000000000000000000280MjZjNDQzY2 221475780000004 +9000014000005000000190371392563000000509793000000509793 +9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999