Skip to content
This repository has been archived by the owner on Aug 26, 2022. It is now read-only.

Commit

Permalink
transfers: delete the ACH file when we delete a transfer
Browse files Browse the repository at this point in the history
  • Loading branch information
adamdecaf committed Dec 13, 2018
1 parent 84b79bb commit 2aa28e2
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 15 deletions.
2 changes: 1 addition & 1 deletion database.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ var (
`create table if not exists originators(originator_id primary key, user_id, default_depository, identification, metadata, created_at datetime, last_updated_at datetime, deleted_at datetime);`,

// Transfers
`create table if not exists transfers(transfer_id, user_id, type, amount, originator_id, originator_depository, customer, customer_depository, description, standard_entry_class_code, status, same_day, created_at datetime, last_updated_at datetime, deleted_at datetime);`,
`create table if not exists transfers(transfer_id, user_id, type, amount, originator_id, originator_depository, customer, customer_depository, description, standard_entry_class_code, status, same_day, file_id, created_at datetime, last_updated_at datetime, deleted_at datetime);`,
}

// Metrics
Expand Down
56 changes: 44 additions & 12 deletions transfers.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,14 +270,14 @@ func getUserTransfer(transferRepo transferRepository) http.HandlerFunc {

// readTransferRequests will attempt to parse the incoming body as either a transferRequest or []transferRequest.
// If no requests were read a non-nil error is returned.
func readTransferRequests(r *http.Request) ([]transferRequest, error) {
func readTransferRequests(r *http.Request) ([]*transferRequest, error) {
bs, err := read(r.Body)
if err != nil {
return nil, err
}

var req transferRequest
var requests []transferRequest
var requests []*transferRequest
if err := json.Unmarshal(bs, &req); err != nil {
// failed, but try []transferRequest
if err := json.Unmarshal(bs, &requests); err != nil {
Expand All @@ -287,7 +287,7 @@ func readTransferRequests(r *http.Request) ([]transferRequest, error) {
if err := req.missingFields(); err != nil {
return nil, err
}
requests = append(requests, req)
requests = append(requests, &req)
}
if len(requests) == 0 {
return nil, errors.New("no Transfer request objects found")
Expand All @@ -314,10 +314,11 @@ func createUserTransfers(custRepo customerRepository, depRepo depositoryReposito
return
}

id, userId, requestId := nextID(), moovhttp.GetUserId(r), moovhttp.GetRequestId(r)
userId, requestId := moovhttp.GetUserId(r), moovhttp.GetRequestId(r)
ach := achclient.New(userId, logger)

for i := range requests {
id := nextID()
req := requests[i]

if err := req.missingFields(); err != nil {
Expand Down Expand Up @@ -368,7 +369,7 @@ func createUserTransfers(custRepo customerRepository, depRepo depositoryReposito
return
}

req.fileId = fileId
req.fileId = fileId // add fileId onto our request

err = eventRepo.writeEvent(userId, &Event{
ID: EventID(nextID()),
Expand Down Expand Up @@ -417,6 +418,21 @@ func deleteUserTransfer(transferRepo transferRepository) http.HandlerFunc {
}

id, userId := getTransferId(r), moovhttp.GetUserId(r)

// Delete from our ACH service
fileId, err := transferRepo.getFileIdForTransfer(id, userId)
if err != nil {
internalError(w, err)
return
}

ach := achclient.New(userId, logger)
if err := ach.DeleteFile(fileId); err != nil { // TODO(adam): ignore 404's
internalError(w, err)
return
}

// Delete from our database
if err := transferRepo.deleteUserTransfer(id, userId); err != nil {
internalError(w, err)
return
Expand All @@ -431,7 +447,7 @@ func deleteUserTransfer(transferRepo transferRepository) http.HandlerFunc {
// 400 - errors, check json
func validateUserTransfer(transferRepo transferRepository) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
w, err := wrapResponseWriter(w, r, "deleteUserTransfer")
w, err := wrapResponseWriter(w, r, "validateUserTransfer")
if err != nil {
return
}
Expand All @@ -442,7 +458,7 @@ func validateUserTransfer(transferRepo transferRepository) http.HandlerFunc {

func getUserTransferFiles(transferRepo transferRepository) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
w, err := wrapResponseWriter(w, r, "deleteUserTransfer")
w, err := wrapResponseWriter(w, r, "getUserTransferFiles")
if err != nil {
return
}
Expand Down Expand Up @@ -489,8 +505,9 @@ func getUserTransferEvents(eventRepo eventRepository, transferRepo transferRepos
type transferRepository interface {
getUserTransfers(userId string) ([]*Transfer, error)
getUserTransfer(id TransferID, userId string) (*Transfer, error)
getFileIdForTransfer(id TransferID, userId string) (string, error)

createUserTransfers(userId string, requests []transferRequest) ([]*Transfer, error)
createUserTransfers(userId string, requests []*transferRequest) ([]*Transfer, error)
deleteUserTransfer(id TransferID, userId string) error
}

Expand Down Expand Up @@ -561,8 +578,23 @@ limit 1`
return transfer, nil
}

func (r *sqliteTransferRepo) createUserTransfers(userId string, requests []transferRequest) ([]*Transfer, error) {
query := `insert into transfers (transfer_id, user_id, type, amount, originator_id, originator_depository, customer, customer_depository, description, standard_entry_class_code, status, same_day, created_at) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
func (r *sqliteTransferRepo) getFileIdForTransfer(id TransferID, userId string) (string, error) {
query := `select file_id from transfers where transfer_id = ? and user_id = ? and deleted_at is null limit 1;`
stmt, err := r.db.Prepare(query)
if err != nil {
return "", err
}
row := stmt.QueryRow(id, userId)

var fileId string
if err := row.Scan(&fileId); err != nil {
return "", err
}
return fileId, nil
}

func (r *sqliteTransferRepo) createUserTransfers(userId string, requests []*transferRequest) ([]*Transfer, error) {
query := `insert into transfers (transfer_id, user_id, type, amount, originator_id, originator_depository, customer, customer_depository, description, standard_entry_class_code, status, same_day, file_id, created_at) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
stmt, err := r.db.Prepare(query)
if err != nil {
return nil, err
Expand Down Expand Up @@ -592,7 +624,7 @@ func (r *sqliteTransferRepo) createUserTransfers(userId string, requests []trans
}

// write transfer
_, err := stmt.Exec(transferId, userId, req.Type, req.Amount.String(), req.Originator, req.OriginatorDepository, req.Customer, req.CustomerDepository, req.Description, req.StandardEntryClassCode, status, req.SameDay, now)
_, err := stmt.Exec(transferId, userId, req.Type, req.Amount.String(), req.Originator, req.OriginatorDepository, req.Customer, req.CustomerDepository, req.Description, req.StandardEntryClassCode, status, req.SameDay, req.fileId, now)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -634,7 +666,7 @@ func abaCheckDigit(rtn string) string {
// This method also verifies the status of the Customer, Customer Depository and Originator Repository
//
// All return values are either nil or non-nil and the error will be the opposite.
func getTransferObjects(req transferRequest, userId string, custRepo customerRepository, depRepo depositoryRepository, origRepo originatorRepository) (*Customer, *Depository, *Originator, *Depository, error) {
func getTransferObjects(req *transferRequest, userId string, custRepo customerRepository, depRepo depositoryRepository, origRepo originatorRepository) (*Customer, *Depository, *Originator, *Depository, error) {
// Customer
cust, err := custRepo.getUserCustomer(req.Customer, userId)
if err != nil {
Expand Down
10 changes: 8 additions & 2 deletions transfers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ func TestTransfers__getUserTransfers(t *testing.T) {

amt, _ := NewAmount("USD", "12.42")
userId := nextID()
req := transferRequest{
req := &transferRequest{
Type: PushTransfer,
Amount: *amt,
Originator: OriginatorID("originator"),
Expand All @@ -173,9 +173,10 @@ func TestTransfers__getUserTransfers(t *testing.T) {
CustomerDepository: DepositoryID("customer"),
Description: "money",
StandardEntryClassCode: "PPD",
fileId: "test-file",
}

if _, err := repo.createUserTransfers(userId, []transferRequest{req}); err != nil {
if _, err := repo.createUserTransfers(userId, []*transferRequest{req}); err != nil {
t.Fatal(err)
}

Expand Down Expand Up @@ -203,6 +204,11 @@ func TestTransfers__getUserTransfers(t *testing.T) {
if v := transfers[0].Amount.String(); v != "USD 12.42" {
t.Errorf("got %q", v)
}

fileId, _ := repo.getFileIdForTransfer(transfers[0].ID, userId)
if fileId != "test-file" {
t.Error("no fileId found in transfers table")
}
}

func TestTransfers__ABA(t *testing.T) {
Expand Down

0 comments on commit 2aa28e2

Please sign in to comment.