Skip to content

Commit

Permalink
response: offer companyID and companyEntryDescription as matcher fields
Browse files Browse the repository at this point in the history
  • Loading branch information
adamdecaf committed Dec 11, 2024
1 parent 2d041b9 commit eac80f8
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 130 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,11 @@ match:
routingNumber: <string> # Exact match of ABA routing number (RDFIIdentification and CheckDigit)
traceNumber: <string> # Exact match of TraceNumber
entryType: <string> # Checks TransactionCode. Accepted values: credit, debit or prenote. Also can be Nacha value (e.g. 27, 32)

# Match on BatchHeader fields
companyIdentification: <string>
companyEntryDescription: <string>

# Matching will find at most two Actions in the config file order. One Copy Action and one Return/Correction Action.
# Both actions will be executed if the Return/Correction Action has a delay.
# Valid combinations include:
Expand Down
66 changes: 0 additions & 66 deletions docs/CONFIGURATION.md

This file was deleted.

29 changes: 0 additions & 29 deletions docs/RUNNING.md

This file was deleted.

26 changes: 1 addition & 25 deletions docs/README.md → docs/entry-search.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,7 @@
<!-- generated-from:d6ef15f91b0edc74c8eeb3ea0138b6bad74e43fe69d00204b961f761948aa5b9 DO NOT REMOVE, DO UPDATE -->
# ACH Test Harness
**Purpose** | **[Configuration](CONFIGURATION.md)** | **[Running](RUNNING.md)** | **[Client](../pkg/client/README.md)**

---

## Purpose

A configurable FTP/SFTP server and Go library to interactively test ACH scenarios to replicate real world originations, returns, changes, prenotes, and transfers.

## Search
## Entry Search

ach-test-harness offers search over the files, batches, and entries on the underlying filesystem. This is useful for automated testing as well as dashboards when used as a sandbox environment.

### Entries

```
GET /entries?traceNumber=YYYYY
```
Expand Down Expand Up @@ -72,15 +60,3 @@ This endpoint will return the following response:
}
]
```

## Getting help

channel | info
------- | -------
[Project Documentation](https://github.com/moov-io/ach-test-harness/tree/master/docs/) | Our project documentation available online.
Twitter [@moov](https://twitter.com/moov) | You can follow Moov.io's Twitter feed to get updates on our project(s). You can also tweet us questions or just share blogs or stories.
[GitHub Issue](https://github.com/moov-io/ach-test-harness/issues) | If you are able to reproduce a problem please open a GitHub Issue under the specific project that caused the error.
[moov slack](https://slack.moov.io/) | Join our slack channel (`#ach-test-harness`) to have an interactive discussion about the development of the project.

---
**[Next - Configuration](CONFIGURATION.md)**
2 changes: 1 addition & 1 deletion pkg/response/file_transformer.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func (ft *FileTransfomer) Transform(ctx context.Context, file *ach.File) error {
entries := file.Batches[i].GetEntries()
for j := range entries {
// Check if there's a matching Action and perform it. There may also be a future-dated action to execute.
copyAction, processAction := ft.Matcher.FindAction(entries[j])
copyAction, processAction := ft.Matcher.FindAction(bh, entries[j])
if copyAction != nil {
// Save this Entry
mirror.saveEntry(&file.Batches[i], copyAction.Copy, entries[j])
Expand Down
30 changes: 29 additions & 1 deletion pkg/response/match/matcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func New(logger log.Logger, cfg service.Matching, responses []service.Response)
}
}

func (m Matcher) FindAction(ed *ach.EntryDetail) (copyAction *service.Action, processAction *service.Action) {
func (m Matcher) FindAction(bh *ach.BatchHeader, ed *ach.EntryDetail) (copyAction *service.Action, processAction *service.Action) {
/*
* See https://github.com/moov-io/ach-test-harness#config-schema for more details on how to configure.
*/
Expand Down Expand Up @@ -140,6 +140,26 @@ func (m Matcher) FindAction(ed *ach.EntryDetail) (copyAction *service.Action, pr
}
}

// BatchHeader fields
if matcher.CompanyIdentification != "" {
if matchedCompanyIdentification(matcher, bh) {
positiveMatchers = append(positiveMatchers, "CompanyIdentification")
positive++
} else {
negativeMatchers = append(negativeMatchers, "CompanyIdentification")
negative++
}
}
if matcher.CompanyEntryDescription != "" {
if matchedCompanyEntryDescription(matcher, bh) {
positiveMatchers = append(positiveMatchers, "CompanyEntryDescription")
positive++
} else {
negativeMatchers = append(negativeMatchers, "CompanyEntryDescription")
negative++
}
}

// format the list of negative and positive matchers for logging
var b strings.Builder

Expand Down Expand Up @@ -244,3 +264,11 @@ func matchedPrenote(m service.Match, ed *ach.EntryDetail) bool {
func matchedIndividualName(m service.Match, ed *ach.EntryDetail) bool {
return strings.TrimSpace(ed.IndividualName) == m.IndividualName
}

func matchedCompanyIdentification(m service.Match, bh *ach.BatchHeader) bool {
return strings.EqualFold(strings.TrimSpace(m.CompanyIdentification), strings.TrimSpace(bh.CompanyIdentification))
}

func matchedCompanyEntryDescription(m service.Match, bh *ach.BatchHeader) bool {
return strings.EqualFold(strings.TrimSpace(m.CompanyEntryDescription), strings.TrimSpace(bh.CompanyEntryDescription))
}
65 changes: 57 additions & 8 deletions pkg/response/match/matcher_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,10 @@ func TestMultiMatch(t *testing.T) {
var actionDelayCorrection = actionCorrection
actionDelayCorrection.Delay = &delay

bh := ach.NewBatchHeader()
bh.CompanyIdentification = "Classbook"
bh.CompanyEntryDescription = "Payment"

t.Run("No Match", func(t *testing.T) {
var matcher Matcher
matcher.Logger = log.NewTestLogger()
Expand All @@ -238,12 +242,12 @@ func TestMultiMatch(t *testing.T) {
entries := file.Batches[0].GetEntries()

// Find our Action
copyAction, processAction := matcher.FindAction(entries[0])
copyAction, processAction := matcher.FindAction(bh, entries[0])
require.Nil(t, copyAction)
require.Nil(t, processAction)

// Find our Action
copyAction, processAction = matcher.FindAction(entries[1])
copyAction, processAction = matcher.FindAction(bh, entries[1])
require.Nil(t, copyAction)
require.Nil(t, processAction)
})
Expand All @@ -266,12 +270,12 @@ func TestMultiMatch(t *testing.T) {
entries := file.Batches[0].GetEntries()

// Find our Action
copyAction, processAction := matcher.FindAction(entries[0])
copyAction, processAction := matcher.FindAction(bh, entries[0])
require.Nil(t, copyAction)
require.Nil(t, processAction)

// Find our Action
copyAction, processAction = matcher.FindAction(entries[1])
copyAction, processAction = matcher.FindAction(bh, entries[1])
require.NotNil(t, copyAction)
require.Equal(t, actionCopy, *copyAction)
require.Nil(t, processAction)
Expand All @@ -295,12 +299,12 @@ func TestMultiMatch(t *testing.T) {
entries := file.Batches[0].GetEntries()

// Find our Action
copyAction, processAction := matcher.FindAction(entries[0])
copyAction, processAction := matcher.FindAction(bh, entries[0])
require.Nil(t, copyAction)
require.Nil(t, processAction)

// Find our Action
copyAction, processAction = matcher.FindAction(entries[1])
copyAction, processAction = matcher.FindAction(bh, entries[1])
require.Nil(t, copyAction)
require.NotNil(t, processAction)
require.Equal(t, actionReturn, *processAction)
Expand Down Expand Up @@ -332,15 +336,60 @@ func TestMultiMatch(t *testing.T) {
entries := file.Batches[0].GetEntries()

// Find our Action
copyAction, processAction := matcher.FindAction(entries[0])
copyAction, processAction := matcher.FindAction(bh, entries[0])
require.Nil(t, copyAction)
require.Nil(t, processAction)

// Find our Action
copyAction, processAction = matcher.FindAction(entries[1])
copyAction, processAction = matcher.FindAction(bh, entries[1])
require.NotNil(t, copyAction)
require.Equal(t, actionCopy, *copyAction)
require.NotNil(t, processAction)
require.Equal(t, actionDelayCorrection, *processAction)
})

t.Run("Match BatchHeader Fields", func(t *testing.T) {
var matcher Matcher
matcher.Logger = log.NewTestLogger()
matcher.Responses = []service.Response{}

// Read our test file
file, err := ach.ReadFile(filepath.Join("..", "..", "..", "testdata", "20230809-144155-102000021.ach"))
require.NoError(t, err)
require.NotNil(t, file)
require.True(t, len(file.Batches) > 0)

bh := file.Batches[0].GetHeader()
entries := file.Batches[0].GetEntries()

// Match no entries
copyAction, processAction := matcher.FindAction(bh, entries[0])
require.Nil(t, copyAction)
require.Nil(t, processAction)

// Match based on CompanyID
matcher.Responses = append(matcher.Responses, service.Response{
Match: service.Match{
CompanyIdentification: "Classbook",
},
Action: actionReturn,
})
copyAction, processAction = matcher.FindAction(bh, entries[0])
require.Nil(t, copyAction)
require.NotNil(t, processAction)
require.Equal(t, actionReturn, *processAction)

// Match based on CompanyEntryDescription
matcher.Responses = nil
matcher.Responses = append(matcher.Responses, service.Response{
Match: service.Match{
CompanyEntryDescription: "Payment",
},
Action: actionReturn,
})
copyAction, processAction = matcher.FindAction(bh, entries[0])
require.Nil(t, copyAction)
require.NotNil(t, processAction)
require.Equal(t, actionReturn, *processAction)
})
}
3 changes: 3 additions & 0 deletions pkg/service/model_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,9 @@ type Match struct {
IndividualName string
RoutingNumber string
TraceNumber string

CompanyIdentification string
CompanyEntryDescription string
}

func (m Match) Context() map[string]log.Valuer {
Expand Down

0 comments on commit eac80f8

Please sign in to comment.