Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ATM_challenge_nov_2021 #33

Open
wants to merge 39 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
d010d7e
basic project structure.
Mljungho Nov 8, 2021
cb96aea
Adding unit test for atm class instantiation
giacoletti Nov 8, 2021
c3cc588
Adding unit test for witdrawal.
Mljungho Nov 8, 2021
921c398
added unit test for withdrawal with enough balance.
Mljungho Nov 8, 2021
957c4ac
Added implementation for withraw account
Mljungho Nov 9, 2021
8e3ef61
Adding unit test for withdrawal bigger amount than available funds
giacoletti Nov 9, 2021
0f6ed0c
Adding unit test for withdrawal bigger amount than ATM available funds
giacoletti Nov 9, 2021
33d72bc
Adding implementation for insufficient funds in atm condition
giacoletti Nov 9, 2021
a5fc1bf
added pin_code argument for withdraw definition and added 'incorrect_…
Mljungho Nov 9, 2021
8c3313b
WIP unit test failing
Mljungho Nov 9, 2021
fcac599
Fixing card expire unit test
giacoletti Nov 9, 2021
f0966a6
Added unit test with account status disabled and implementation
Mljungho Nov 9, 2021
c4272f3
Added unit test with account status disabled and implementation
Mljungho Nov 9, 2021
0901555
Merge branch 'master' of https://github.com/giacoletti/atm_challenge_…
Mljungho Nov 10, 2021
07ed442
Added bills to withdrawal unit test and implementation. Added demonin…
Mljungho Nov 10, 2021
c4a679b
Creating account Class and adding unit test for the account class.
Mljungho Nov 10, 2021
ac0ce73
Added instance doubble Person, added unit test - Ownership of account…
Mljungho Nov 10, 2021
f9c3d40
Adding unit tests for Person class
giacoletti Nov 10, 2021
f63993b
Adding implementation to raise error if trying to do a deposit when w…
giacoletti Nov 10, 2021
d560c03
added unit test to add funds to the account balance and deduct cash i…
Mljungho Nov 11, 2021
7e392ce
added unit test for withdraw funds method. Unit test failing
Mljungho Nov 11, 2021
6e35aec
Adding unit tests for withdrawal method of Person class
giacoletti Nov 11, 2021
c415f5d
Adding unit test to raise error if trying to withdraw with insufficie…
giacoletti Nov 11, 2021
19079e7
Added unit test checking if withdrawal amount is divisible by currenc…
Mljungho Nov 11, 2021
f9299ce
Code refactoring of Person class (WIP)
giacoletti Nov 11, 2021
d7adb94
removed duplicated unit test in atm_spec
Mljungho Nov 12, 2021
0ba51b3
Wrote documentation README.md WIP
Mljungho Nov 12, 2021
03f5d82
Adjusted the syntax block and added ruby code format
Mljungho Nov 12, 2021
a6df40a
Adjusted Ruby code blocks for the README.md WIP
Mljungho Nov 12, 2021
0ef0e66
adjusted ruby codeformat to include the syntax response
Mljungho Nov 12, 2021
957a728
Adjusting the blocks of code and Ruby code formater
Mljungho Nov 12, 2021
6e23ce3
testing .md functions
Mljungho Nov 12, 2021
c3dfb86
Code refactoring for unit tests of Person class for withdrawal operat…
giacoletti Nov 12, 2021
0910374
Code refactoring - Person class, using Atm withdraw method instead of…
giacoletti Nov 12, 2021
675560d
Fixing tip of current branch - not aligned
giacoletti Nov 12, 2021
3fb1fa5
Formatting all ruby files using Rufo
giacoletti Nov 12, 2021
9d0b575
Creating LICENSE.txt
giacoletti Nov 12, 2021
606f7a2
Adding license to README.md
giacoletti Nov 12, 2021
9b4259a
Fixing MIT License link in README.md
giacoletti Nov 12, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.DS_Store

3 changes: 3 additions & 0 deletions .rspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
--format documentation
--require spec_helper
--color
4 changes: 4 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
source 'https://rubygems.org'

gem 'rspec'
gem 'pry'
32 changes: 32 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
GEM
remote: https://rubygems.org/
specs:
coderay (1.1.3)
diff-lcs (1.4.4)
method_source (1.0.0)
pry (0.14.1)
coderay (~> 1.1)
method_source (~> 1.0)
rspec (3.10.0)
rspec-core (~> 3.10.0)
rspec-expectations (~> 3.10.0)
rspec-mocks (~> 3.10.0)
rspec-core (3.10.1)
rspec-support (~> 3.10.0)
rspec-expectations (3.10.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.10.0)
rspec-mocks (3.10.2)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.10.0)
rspec-support (3.10.3)

PLATFORMS
x86_64-linux

DEPENDENCIES
pry
rspec

BUNDLED WITH
2.2.30
21 changes: 21 additions & 0 deletions LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2021 giacoletti & Mljungho

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
68 changes: 68 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,70 @@
# atm_challenge_2021
#### project by Giovanni Lacoletti & Mathias Ljungholm

## The Code
The ATM_challenge code is a test where we create the logical respons and actions that an ATM machine would preform. We create test cases for various conditions that could happen in reality and design the ATM responce accordingly. We are only operating on the "Logical Tier" for this project, meaning that we will not produce a UI or store the data, we will soley be working with the logic using ruby.

## Dependencies
Gems framework we used are 'rspec' for unit test

## Setup
The repo contains the Gemfile, so you only need to install the bundle.

In CLI type the command: bundle install

This will install the dependencies that is required to run the test.

Inside ".rspec" file make sure you have the flaggs:
--format documentation
--require spec_helper
--color

## Instructions

The code does not have a user interface, so the way you need to run the code and test
open the console and enter irb
" require'./lib/person.rb' " and " require'./lib/atm.rb' " and " require'./lib/account.rb' " in order to access the code in IRB.

now you can create a person following the syntax:

```ruby
person = Person.new ({name: "Mathias"})
=> #<Person:0x0000563980776e28 @name="Mathias", @cash=0>


person.create_account
=> #<Account:0x000056398076a768 @pin_code=8948, @exp_date="11/26", @account_status=:active, @balance=0, @owner="Mathias">


person.deposit(5000)
=> -5000


person.account
=> #<Account:0x000056398076a768 @pin_code=8948, @exp_date="11/26", @account_status=:active, @balance=5000, @owner="Mathias">
```



This is a simple example of us instantiating a person "Mathias", and that person creating an account, and depositing 5000.
those 5000 will show up in the list of attributes once you type person.account.


## Acknowledgments

## Updates/Improvement plans

The code, at this stage, does not take into account the fact that either the balance of the account or the person using the ATM can end up with negative money. witch is obviously nonsence.
In later updates we will need to make sure that this is not the case.

Currently you, as a person, can deposit 200 and the account will display that you have increased your account with 200, while as a person you have -200. This does not reflect real life at all, and will have to be fixed.

the same goes for the account. it will display a negative amount (witch I supose could happen if it is a credit account) but it makes more sence to add a restriction, that the account can not reach <0 unless otherwiese stated.

Furthermore you have the ability to deactivate your account, but this doesn't, at the moment, stop you from depositing funds.

This will have to be implemented at a later stage.

## License

The software is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
37 changes: 37 additions & 0 deletions lib/account.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
require "date"

class Account
STANDARD_VALIDITY_YRS = 5

attr_accessor :pin_code, :account_status, :exp_date, :account_owner, :balance, :owner

def initialize(attrs = {})
@pin_code = generate_pin()
@exp_date = set_expire_date()
@account_status = :active
@balance = 0
set_owner(attrs[:owner])
end

def deactivate
@account_status = :deactivated
end

private

def generate_pin
rand(1000..9999)
end

def set_expire_date
Date.today.next_year(Account::STANDARD_VALIDITY_YRS).strftime("%m/%y")
end

def set_owner(obj)
obj == nil ? missing_owner : @owner = obj
end

def missing_owner
raise "An Account owner is required"
end
end
113 changes: 113 additions & 0 deletions lib/atm.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
require "date"

class Atm
attr_accessor :funds

def initialize
@funds = 1000
end

# note that we will also change 'value' to 'amount'
# it is a better name for our domain
def withdraw(amount, pin_code, account)
# We will be using Ruby's
# `case` - `when` - `then` flow control statement
# and check if there is enough funds in the account
case
when insufficient_funds_in_account?(amount, account)
# we exit the method if the amount we want to withdraw
# is bigger than the balance on the account
{
status: false,
message: "insufficient funds",
date: Date.today,
}
when insufficient_funds_in_atm?(amount)
{
status: false,
message: "insufficient funds in ATM",
date: Date.today,
}
when incorrect_pin?(pin_code, account.pin_code)
{
status: false,
message: "wrong pin",
date: Date.today
}
when card_expired?(account.exp_date)
{
status: false,
message: "card expired",
date: Date.today
}
when account_deactivated?(account.account_status)
{
status: false,
message: "account disabled",
date: Date.today
}
when denominator_missing?(amount)
{
status: false,
message: "Denominator not available",
date: Date.today
}
else
# if it's not, we preform the transaction
perform_transaction(amount, account)
end
end

private

def insufficient_funds_in_account?(amount, account)
amount > account.balance
end

def insufficient_funds_in_atm?(amount)
@funds < amount
end

def perform_transaction(amount, account)
# We DEDUCT the amount from the Atm's funds
@funds -= amount
# We also DEDUCT the amount from the accounts balance
account.balance = account.balance - amount
# and we return a responce for a successfull withdraw.
{
status: true,
message: "success",
date: Date.today,
amount: amount,
bills: add_bills(amount),
}
end

def incorrect_pin?(pin_code, actual_pin)
pin_code != actual_pin
end

def card_expired?(exp_date)
Date.strptime(exp_date, "%m/%y") < Date.today
end

def account_deactivated?(account_status)
account_status == :deactivated
end

def add_bills(amount)
denominations = [20, 10, 5]
bills = []
denominations.each do |bill|
while amount - bill >= 0
amount -= bill
bills << bill
end
end
bills
end

def denominator_missing?(amount)
amount % 5 != 0
end
end
94 changes: 94 additions & 0 deletions lib/person.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
require "./lib/account.rb"

class Person
attr_accessor :name, :cash, :account

def initialize(args = {})
@name = set_name(args[:name])
@cash = 0
end

def create_account
@account = Account.new({ owner: self.name })
end

def deposit(amount)
@account == nil ? missing_account : deposit_amount(amount)
end

def withdraw(args = {}) # amount, pin_code, account, atm
if atm_missing?(args[:atm])
missing_atm
elsif account_missing?(args[:account])
missing_account
elsif pin_code_missing?(args[:pin])
missing_pin_code
elsif insufficient_funds_in_atm?(args[:atm], args[:amount])
insufficient_funds
elsif insufficient_balance?(@account.balance, args[:amount])
insufficient_account_balance
else
response = args[:atm].withdraw(args[:amount], args[:pin], args[:account])
response[:status] == true ? add_cash(args[:amount]) : response
end
end

private

def missing_name
raise "A name is required"
end

def missing_account
raise "No account present"
end

def missing_atm
raise "An ATM is required"
end

def missing_pin_code
raise "Pin code is required"
end

def insufficient_funds
raise "Insufficient funds in ATM"
end

def insufficient_account_balance
raise "Insufficient account balance"
end

def set_name(name)
name == nil ? missing_name : name
end

def deposit_amount(amount)
@account.balance += amount
@cash -= amount
end

def atm_missing?(atm)
atm == nil
end

def account_missing?(account)
account == nil
end

def pin_code_missing?(pin_code)
pin_code == nil
end

def insufficient_funds_in_atm?(atm, amount)
atm.funds < amount
end

def insufficient_balance?(balance, amount)
balance < amount
end

def add_cash(amount)
@cash += amount
end
end
Loading