Skip to content

Commit

Permalink
Merge pull request #374 from moov-io/Support-XCK---Destroyed-Check-En…
Browse files Browse the repository at this point in the history
…try-#347

Support xck   destroyed check entry #347
  • Loading branch information
bkmoovio authored Nov 15, 2018
2 parents ba6b60d + fee86f4 commit 686e281
Show file tree
Hide file tree
Showing 10 changed files with 703 additions and 0 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
## v0.4.1 (Unreleased)

ADDITIONS

- Support ADV, TRC, TRX, XCK StandardEntryClassCode (SEC types)

## v0.4.0 (Released 2018-11-06)

BREAKING CHANGES
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ ACH is under active development but already in production for multiple companies
| TEL | Telephone-Initiated Entry | [Link](test/ach-tel-read/main.go) | [Link](test/ach-tel-write/main.go) |
| TRC | Truncated Check Entry | [Link](test/ach-trc-read/main.go) | [Link](test/ach-trc-write/main.go) |
| WEB | Internet-initiated Entries | [Link](test/ach-web-read/main.go) | [Link](test/ach-web-write/main.go) |
| XCK | Destroyed Check Entry | [Link](test/ach-xck-read/main.go) | [Link](test/ach-xck-write/main.go) |

</details>

Expand Down
2 changes: 2 additions & 0 deletions batch.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ func NewBatch(bh *BatchHeader) (Batcher, error) {
return NewBatchTRC(bh), nil
case "WEB":
return NewBatchWEB(bh), nil
case "XCK":
return NewBatchXCK(bh), nil
default:
}
msg := fmt.Sprintf(msgFileNoneSEC, bh.StandardEntryClassCode)
Expand Down
81 changes: 81 additions & 0 deletions batchXCK.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Copyright 2018 The Moov Authors
// Use of this source code is governed by an Apache License
// license that can be found in the LICENSE file.

package ach

import "fmt"

// BatchXCK holds the BatchHeader and BatchControl and all EntryDetail for XCK Entries.
//
// Destroyed Check Entry identifies a debit entry initiated for a XCk eligible items.
type BatchXCK struct {
Batch
}

// NewBatchXCK returns a *BatchXCK
func NewBatchXCK(bh *BatchHeader) *BatchXCK {
batch := new(BatchXCK)
batch.SetControl(NewBatchControl())
batch.SetHeader(bh)
return batch
}

// Validate checks valid NACHA batch rules. Assumes properly parsed records.
func (batch *BatchXCK) Validate() error {
// basic verification of the batch before we validate specific rules.
if err := batch.verify(); err != nil {
return err
}
// Add configuration and type specific validation for this type.

if batch.Header.StandardEntryClassCode != "XCK" {
msg := fmt.Sprintf(msgBatchSECType, batch.Header.StandardEntryClassCode, "XCK")
return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "StandardEntryClassCode", Msg: msg}
}

// XCK detail entries can only be a debit, ServiceClassCode must allow debits
switch batch.Header.ServiceClassCode {
case 200, 220, 280:
msg := fmt.Sprintf(msgBatchServiceClassCode, batch.Header.ServiceClassCode, "XCK")
return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "ServiceClassCode", Msg: msg}
}

for _, entry := range batch.Entries {
// XCK detail entries must be a debit
if entry.CreditOrDebit() != "D" {
msg := fmt.Sprintf(msgBatchTransactionCodeCredit, entry.TransactionCode)
return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "TransactionCode", Msg: msg}
}
// Amount must be 2,500 or less
if entry.Amount > 250000 {
msg := fmt.Sprintf(msgBatchAmount, "2,500", "XCK")
return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "Amount", Msg: msg}
}
// ProcessControlField underlying IdentificationNumber, must be defined
if entry.ProcessControlField() == "" {
return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "ProcessControlField", Msg: msgFieldRequired}
}
// ItemResearchNumber underlying IdentificationNumber, must be defined
if entry.ItemResearchNumber() == "" {
return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "ItemResearchNumber", Msg: msgFieldRequired}
}
// Verify Addenda* FieldInclusion based on entry.Category and batchHeader.StandardEntryClassCode
if err := batch.addendaFieldInclusion(entry); err != nil {
return err
}
}
return nil
}

// Create takes Batch Header and Entries and builds a valid batch
func (batch *BatchXCK) Create() error {
// generates sequence numbers and batch control
if err := batch.build(); err != nil {
return err
}
// Additional steps specific to batch type
// ...

return batch.Validate()
}
Loading

0 comments on commit 686e281

Please sign in to comment.