Skip to content

Commit

Permalink
Skipping IMAD mandatory check (#283)
Browse files Browse the repository at this point in the history
  • Loading branch information
mfdeveloper508 authored Feb 1, 2023
1 parent 18dce4c commit c617d57
Show file tree
Hide file tree
Showing 7 changed files with 185 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{1500}30User ReqT
{1510}1631
{2000}000001234567
{3100}121042882Wells Fargo NA
{3400}231380104Citadel
{3600}DRB
{3320}Sender Reference
{3500}Previous Message Ident
{4000}D123456789 FI Name Address One Address Two Address Three
{4100}D123456789 FI Name Address One Address Two Address Three
{4200}31234 Name Address One Address Two Address Three
{4320}Reference
{4400}D123456789 debitDD Name Address One Address Two Address Three
{5000}11234 Name Address One Address Two Address Three
{5100}D123456789 FI Name Address One Address Two Address Three
{5200}D123456789 FI Name Address One Address Two Address Three
{5400}123456789
{6000}LineOne LineTwo LineThree LineFour
{6100}Line Six
{6200}Line Six
{6210}LTRLine One Line Two Line Three Line Four Line Five Line Six
{6300}Line One Line Two Line Three Line Four Line Five Line Six
{6310}TLXLine One Line Two Line Three Line Four Line Five Line Six
{6400}Line One Line Two Line Three Line Four Line Five Line Six
{6410}LTRLine One Line Two Line Three Line Four Line Five Line Six
{6420}CHECKAdditional Information
{6500}Line One Line Two Line Three Line Four Line Five Line Six
49 changes: 49 additions & 0 deletions examples/bankDrawDownRequest-read-skip-imad/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright 2020 The Moov Authors
// Use of this source code is governed by an Apache License
// license that can be found in the LICENSE file.

package main

import (
"fmt"
"log"
"os"
"path/filepath"

"github.com/moov-io/wire"
)

func main() {
f, err := os.Open(filepath.Join("examples", "bankDrawDownRequest-read-skip-imad", "bankDrawDownRequest.txt"))
if err != nil {
log.Fatalf("Could not open FEDWireMessage: %s\n", err)

}
defer f.Close()
r := wire.NewReader(f)

opts := wire.ValidateOpts{
SkipMandatoryIMAD: true,
}

fwmFile, err := r.ReadWithOpts(&opts)
if err != nil {
log.Fatalf("Could not read FEDWireMessage: %s\n", err)
}
// ensure we have a validated file structure
if err = fwmFile.Validate(); err != nil {
log.Fatalf("Could not validate FEDWireMessage: %s\n", err)
}

if fwmFile.FEDWireMessage.InputMessageAccountabilityData != nil {
log.Fatalf("IMAD doesn't existed in FEDWireMessage")
}

fmt.Printf("Sender Supplied: %v \n", fwmFile.FEDWireMessage.SenderSupplied)
fmt.Printf("Type and Subtype: %v \n", fwmFile.FEDWireMessage.TypeSubType)
fmt.Printf("Input Message Accountability Data: %v \n", fwmFile.FEDWireMessage.InputMessageAccountabilityData)
fmt.Printf("Amount: %v \n", fwmFile.FEDWireMessage.Amount)
fmt.Printf("Sender Depository Institution: %v \n", fwmFile.FEDWireMessage.SenderDepositoryInstitution)
fmt.Printf("Receiver Depository Institution: %v \n", fwmFile.FEDWireMessage.ReceiverDepositoryInstitution)
fmt.Printf("Business Function Code: %v \n", fwmFile.FEDWireMessage.BusinessFunctionCode)
}
15 changes: 13 additions & 2 deletions fedWireMessage.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ package wire

import "strings"

// ValidateOpts contains specific overrides from the default set of validations
type ValidateOpts struct {
// SkipMandatoryIMAD skips checking that InputMessageAccountabilityData is mandatory tag.
SkipMandatoryIMAD bool `json:"skipMandatoryIMAD"`
}

// FEDWireMessage is a FedWire Message
type FEDWireMessage struct {
// ID
Expand Down Expand Up @@ -131,6 +137,8 @@ type FEDWireMessage struct {
RemittanceFreeText *RemittanceFreeText `json:"remittanceFreeText,omitempty"`
// ServiceMessage
ServiceMessage *ServiceMessage `json:"serviceMessage,omitempty"`
// ValidateOpts
ValidateOptions *ValidateOpts `json:"validateOptions,omitempty"`
}

// verify checks basic WIRE rules. Assumes properly parsed records. Each validation func should
Expand Down Expand Up @@ -219,8 +227,11 @@ func (fwm *FEDWireMessage) mandatoryFields(isIncoming bool) error {
if err := fwm.validateTypeSubType(); err != nil {
return err
}
if err := fwm.validateIMAD(); err != nil {
return err

if fwm.ValidateOptions == nil || !fwm.ValidateOptions.SkipMandatoryIMAD {
if err := fwm.validateIMAD(); err != nil {
return err
}
}
if err := fwm.validateAmount(); err != nil {
return err
Expand Down
40 changes: 40 additions & 0 deletions fedWiremessage_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package wire

import (
"encoding/json"
"testing"

"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -1207,3 +1208,42 @@ func TestInvalidAccountCreditedDrawdownForCustomerTransferPlus(t *testing.T) {
expected := fieldError("AccountCreditedDrawdown", ErrInvalidProperty, fwm.AccountCreditedDrawdown).Error()
require.EqualError(t, err, expected)
}

func TestFEDWireMessage_skipIMAD(t *testing.T) {
file := NewFile()
fwm := mockCustomerTransferData()
// Beneficiary
fwm.Beneficiary = mockBeneficiary()
// Originator
fwm.Originator = mockOriginator()
file.AddFEDWireMessage(fwm)
// Create file
if err := file.Create(); err != nil {
t.Fatalf("%T: %s", err, err)
}

err := file.Validate()
require.NoError(t, err)

file.FEDWireMessage.InputMessageAccountabilityData = nil

err = file.Validate()
expected := fieldError("InputMessageAccountabilityData", ErrFieldRequired).Error()
require.EqualError(t, err, expected)

file.SetValidation(&ValidateOpts{SkipMandatoryIMAD: true})
err = file.Validate()
require.NoError(t, err)

bs, err := json.Marshal(file)
require.NoError(t, err)

newFile, err := FileFromJSON(bs)
require.NoError(t, err)
require.NotNil(t, newFile, "Created file shouldn't be nil")
require.Nil(t, newFile.FEDWireMessage.InputMessageAccountabilityData)

err = newFile.Validate()
require.NoError(t, err)
require.Equal(t, true, newFile.GetValidation().SkipMandatoryIMAD)
}
16 changes: 16 additions & 0 deletions file.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,22 @@ func NewFile(opts ...FilePropertyFunc) *File {
return f
}

// SetValidation stores ValidateOpts on the FEDWireMessage's validation rules
func (f *File) SetValidation(opts *ValidateOpts) {
if f == nil || opts == nil {
return
}
f.FEDWireMessage.ValidateOptions = opts
}

// GetValidation returns validation rules of FEDWireMessage
func (f *File) GetValidation() *ValidateOpts {
if f == nil || f.FEDWireMessage.ValidateOptions == nil {
return nil
}
return f.FEDWireMessage.ValidateOptions
}

// AddFEDWireMessage appends a FEDWireMessage to the File
func (f *File) AddFEDWireMessage(fwm FEDWireMessage) FEDWireMessage {
f.FEDWireMessage = fwm
Expand Down
10 changes: 10 additions & 0 deletions reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,14 @@ func NewReader(r io.Reader) *Reader {
// on the first character of each line. It also enforces FED Wire formatting rules and returns
// the appropriate error if issues are found.
func (r *Reader) Read() (File, error) {
return r.read(nil)
}

func (r *Reader) ReadWithOpts(opts *ValidateOpts) (File, error) {
return r.read(opts)
}

func (r *Reader) read(opts *ValidateOpts) (File, error) {
spiltString := func(line string) []string {

// strip new lines
Expand Down Expand Up @@ -112,6 +119,9 @@ func (r *Reader) Read() (File, error) {
r.currentFEDWireMessage = FEDWireMessage{}

if r.errors.Empty() {
if opts != nil {
r.File.SetValidation(opts)
}
err := r.File.Validate()
if err == nil {
return r.File, nil
Expand Down
30 changes: 30 additions & 0 deletions reader_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package wire

import (
"bytes"
"os"
"path"
"path/filepath"
Expand Down Expand Up @@ -82,3 +83,32 @@ func TestRead_missingTag(t *testing.T) {

require.EqualError(t, err, "file validation failed: FIBeneficiaryAdvice is a required field")
}

func TestReadWithValidateOpts(t *testing.T) {
f, err := os.Open("./test/testdata/fedWireMessage-BankTransfer.txt")
if err != nil {
t.Fatalf("%T: %s", err, err)
}
defer f.Close()
r := NewReader(f)

file, err := r.Read()
require.NoError(t, err)
require.NotNil(t, file)

file.FEDWireMessage.InputMessageAccountabilityData = nil

b := &bytes.Buffer{}
w := NewWriter(b)
err = w.Write(&file)
require.Error(t, err)

r1 := NewReader(b)
file, err = r1.ReadWithOpts(&ValidateOpts{
SkipMandatoryIMAD: true,
})

require.Error(t, err)
require.NotNil(t, file)
require.Nil(t, file.FEDWireMessage.InputMessageAccountabilityData)
}

0 comments on commit c617d57

Please sign in to comment.