Skip to content

Commit

Permalink
Merge pull request #219 from bkmoovio/209
Browse files Browse the repository at this point in the history
closes #209 Add support for CIE
  • Loading branch information
wadearnold authored Jun 20, 2018
2 parents b7622ba + 47dee39 commit 9a19e94
Show file tree
Hide file tree
Showing 11 changed files with 549 additions and 10 deletions.
4 changes: 2 additions & 2 deletions BatchARC_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func mockARCEntryDetail() *EntryDetail {
entry.Amount = 25000
entry.SetCheckSerialNumber("123456789")
entry.SetReceivingCompany("ABC Company")
entry.SetTraceNumber(mockBatchARCHeader().ODFIIdentification, 123)
entry.SetTraceNumber(mockBatchARCHeader().ODFIIdentification, 1)
entry.Category = CategoryForward
return entry
}
Expand Down Expand Up @@ -63,7 +63,7 @@ func mockARCEntryDetailCredit() *EntryDetail {
entry.Amount = 25000
entry.SetCheckSerialNumber("123456789")
entry.SetReceivingCompany("ABC Company")
entry.SetTraceNumber(mockBatchARCHeader().ODFIIdentification, 123)
entry.SetTraceNumber(mockBatchARCHeader().ODFIIdentification, 1)
entry.Category = CategoryForward
return entry
}
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ ACH is under active development but already in production for multiple companies
* ARC (Accounts Receivable Entry)
* BOC (Back Office Conversion)
* CCD (Corporate credit or debit)
* CIE (Customer-Initiated Entry)
* COR (Automated Notification of Change(NOC))
* POP (Point of Purchase)
* POS (Point of Sale)
Expand Down
2 changes: 2 additions & 0 deletions batch.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ func NewBatch(bh *BatchHeader) (Batcher, error) {
return NewBatchBOC(bh), nil
case "CCD":
return NewBatchCCD(bh), nil
case "CIE":
return NewBatchCIE(bh), nil
case "COR":
return NewBatchCOR(bh), nil
case "POP":
Expand Down
4 changes: 2 additions & 2 deletions batchBOC_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func mockBOCEntryDetail() *EntryDetail {
entry.Amount = 25000
entry.SetCheckSerialNumber("123456789")
entry.SetReceivingCompany("ABC Company")
entry.SetTraceNumber(mockBatchBOCHeader().ODFIIdentification, 123)
entry.SetTraceNumber(mockBatchBOCHeader().ODFIIdentification, 1)
entry.Category = CategoryForward
return entry
}
Expand Down Expand Up @@ -63,7 +63,7 @@ func mockBOCEntryDetailCredit() *EntryDetail {
entry.Amount = 25000
entry.SetCheckSerialNumber("123456789")
entry.SetReceivingCompany("ABC Company")
entry.SetTraceNumber(mockBatchBOCHeader().ODFIIdentification, 123)
entry.SetTraceNumber(mockBatchBOCHeader().ODFIIdentification, 1)
entry.Category = CategoryForward
return entry
}
Expand Down
100 changes: 100 additions & 0 deletions batchCIE.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// Copyright 2018 The ACH 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"
)

// BatchCIE holds the BatchHeader and BatchControl and all EntryDetail for CIE Entries.
//
// Customer-Initiated Entry (or CIE entry) is a credit entry initiated on behalf of,
// and upon the instruction of, a consumer to transfer funds to a non-consumer Receiver.
// CIE entries are usually transmitted to a company for payment of funds that the consumer
// owes to that company and are initiated by the consumer through some type of online
// banking product or bill payment service provider. With CIEs, funds owed by the consumer
// are “pushed” to the biller in the form of an ACH credit, as opposed to the biller’s use of
// a debit application (e.g., PPD, WEB) to “pull” the funds from a customer’s account.
type BatchCIE struct {
batch
}

var msgBatchCIEAddenda = "found and 1 Addenda05 is the maximum for SEC code CIE"
var msgBatchCIEAddendaType = "%T found where Addenda05 is required for SEC code CIE"

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

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

// Add type specific validation.

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

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

for _, entry := range batch.Entries {
// CIE detail entries must be a debit
if entry.CreditOrDebit() != "C" {
msg := fmt.Sprintf(msgBatchTransactionCodeCredit, entry.TransactionCode)
return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "TransactionCode", Msg: msg}
}

// Addenda validations - CIE Addenda must be Addenda05

// Addendum must be equal to 1
if len(entry.Addendum) > 1 {
return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "Addendum", Msg: msgBatchCIEAddenda}
}

if len(entry.Addendum) > 0 {
// Addenda type assertion must be Addenda05
addenda05, ok := entry.Addendum[0].(*Addenda05)
if !ok {
msg := fmt.Sprintf(msgBatchCIEAddendaType, entry.Addendum[0])
return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: "Addendum", Msg: msg}
}

// Addenda05 must be Validated
if err := addenda05.Validate(); err != nil {
// convert the field error in to a batch error for a consistent api
if e, ok := err.(*FieldError); ok {
return &BatchError{BatchNumber: batch.Header.BatchNumber, FieldName: e.FieldName, Msg: e.Msg}
}
}
}
}
return nil
}

// Create takes Batch Header and Entries and builds a valid batch
func (batch *BatchCIE) 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 9a19e94

Please sign in to comment.