Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

response: offer companyID and companyEntryDescription as matcher fields #269

Merged
merged 1 commit into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading