diff --git a/domains/account.go b/domains/account.go index b5cd3ed..fcd9a15 100644 --- a/domains/account.go +++ b/domains/account.go @@ -8,8 +8,9 @@ const ( // BankAccount represents for a bank customer type BankAccount struct { - Name string - balance int // in cent + Name string + balance int // in cent + operationRecords []*OperationRecord } // Balance get balance and return with ($)dollar instead of the unit which is cent @@ -30,3 +31,7 @@ func (account *BankAccount) Withdraw(moneyInCents int) error { account.balance -= moneyInCents return nil } + +func (account *BankAccount) OperationRecords() []*OperationRecord { + return account.operationRecords +} diff --git a/domains/bank.go b/domains/bank.go index 581a713..fcb4223 100644 --- a/domains/bank.go +++ b/domains/bank.go @@ -6,8 +6,12 @@ import ( "github.com/sirupsen/logrus" ) +type OperationRecordType string + var ( ErrActionMoneyAmountInvalid = fmt.Errorf("money can't be negative or 0") + depositType = OperationRecordType("deposit") + withdrawType = OperationRecordType("withdraw") ) const roundFloat = 0.5 @@ -19,6 +23,11 @@ type Bank struct { totalBalance int } +type OperationRecord struct { + Money int + OperationType OperationRecordType +} + // InitBank inits the bank func InitBank() *Bank { return &Bank{} @@ -26,13 +35,28 @@ func InitBank() *Bank { // OpenAccount opens a account for customer func (bank *Bank) OpenAccount(customerName string) { - bank.accounts = append(bank.accounts, &BankAccount{Name: customerName}) + bank.accounts = append(bank.accounts, &BankAccount{ + Name: customerName, + operationRecords: make([]*OperationRecord, 0), + }) logrus.Infof("opened bank account for: %s", customerName) } +func (bank *Bank) NewOperationRecord(bankAccount *BankAccount, money int, operation OperationRecordType) { + bankAccount.operationRecords = append(bankAccount.operationRecords, &OperationRecord{ + Money: money, + OperationType: operation, + }) +} + +func (bank *Bank) OperationRecordsFor(bankAccount *BankAccount) []*OperationRecord { + return bankAccount.OperationRecords() +} + // DepositFor deposit for a user func (bank *Bank) DepositFor(account *BankAccount, money float64) error { + if money <= 0 { return ErrActionMoneyAmountInvalid } @@ -41,6 +65,8 @@ func (bank *Bank) DepositFor(account *BankAccount, money float64) error { account.Deposit(moneyInCents) bank.totalBalance += moneyInCents + bank.NewOperationRecord(account, moneyInCents, depositType) + logrus.Infof("deposited $%.2f for %s", money, account.Name) return nil @@ -58,6 +84,8 @@ func (bank *Bank) WithdrawFor(account *BankAccount, money float64) error { } bank.totalBalance -= moneyInCents + bank.NewOperationRecord(account, moneyInCents, withdrawType) + logrus.Infof("withdrawn $%.2f for %s", money, account.Name) return nil diff --git a/domains/bank_test.go b/domains/bank_test.go index 7652533..4620774 100644 --- a/domains/bank_test.go +++ b/domains/bank_test.go @@ -28,6 +28,45 @@ func TestInitBank(t *testing.T) { } } +func TestNewOperationRecord(t *testing.T) { + bank := InitBank() + bank.OpenAccount("Dan") + dan, err := bank.AccountFromName("Dan") + + if err != nil { + t.Error("can't find user") + } + + t.Run("can save a deposit operation record for user", func(t *testing.T) { + assert.Equal(t, 0, len(dan.operationRecords)) + bank.NewOperationRecord(dan, 10000, "deposit") + assert.Equal(t, 1, len(dan.operationRecords)) + }) + + t.Run("can save a withdraw operation record for user", func(t *testing.T) { + assert.Equal(t, 1, len(dan.operationRecords)) + bank.NewOperationRecord(dan, 10000, "withdraw") + assert.Equal(t, 2, len(dan.operationRecords)) + }) +} + +func TestOperationRecordsForBankAccount(t *testing.T) { + + t.Run("can get all the operation records for the user", func(t *testing.T) { + bank := InitBank() + bank.OpenAccount("Dan") + dan, _ := bank.AccountFromName("Dan") + bank.DepositFor(dan, 20000) + + records := bank.OperationRecordsFor(dan) + assert.Equal(t, 1, len(records)) + bank.WithdrawFor(dan, 10000) + + records2 := bank.OperationRecordsFor(dan) + assert.Equal(t, 2, len(records2)) + }) +} + func TestBank_OpenAccount(t *testing.T) { bank := InitBank() t.Run("should open a account for customer", func(t *testing.T) {