atm_program 1.4.1.pre

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 6e60dda1416ccfeb905bf97486c26c9df458d26a09762cbbb4ddafb77f539044
4
+ data.tar.gz: c11852c94b28ab86b612018c28d9718c929daf79d721fe25b2879dd5488a3233
5
+ SHA512:
6
+ metadata.gz: 9a10f7d97f1bb8f0a55b1b7a4d0af5c8525f231d13b095155e6bed0ac6e5c4c963d20284dfbd6e1ed32d80d298e0b89a580994d2cac9e9b74cd192c893b6c2c3
7
+ data.tar.gz: 51ebcdffce77ab80ba62558cdfcc962277c1bcc55134f6ee05213f076b866ce2aab43da093360e066586a835d95478ffbd220167c5028359aaf593ee30efe605
data/lib/account.csv ADDED
@@ -0,0 +1,3 @@
1
+ name,card_number,pin,balance,card_blocked
2
+ alex,123456789011,MTIzNA==,7500,false
3
+ vincent,123456789012,MTExMQ==,10000,false
data/lib/account.rb ADDED
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'csv'
4
+ # class Account
5
+ class Account
6
+ attr_accessor :name, :card_number, :pin, :balance, :transactions, :card_blocked
7
+
8
+ def initialize(name, card_number, pin, balance, card_blocked)
9
+ @name = name
10
+ @card_number = card_number
11
+ @pin = pin
12
+ @balance = balance
13
+ @card_blocked = card_blocked
14
+ end
15
+
16
+ def self.find_by_card_number(card_number)
17
+ CSV.table('/account.csv').each do |entry|
18
+ if entry[:card_number] == card_number
19
+ return new(entry[:name], entry[:card_number], entry[:pin], entry[:balance], entry[:card_blocked])
20
+ end
21
+ end
22
+ nil
23
+ end
24
+ end
data/lib/atm.rb ADDED
@@ -0,0 +1,158 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'account'
4
+ require_relative 'validation'
5
+ require_relative 'transaction'
6
+ require 'csv'
7
+ require 'base64'
8
+
9
+ # class ATM
10
+ class Atm
11
+ include Validation
12
+ def initialize
13
+ welcome_screen
14
+ end
15
+
16
+ private
17
+
18
+ def thank_you
19
+ puts "\nThank You for using the ATM"
20
+ sleep(2)
21
+ welcome_screen
22
+ end
23
+
24
+ def clear
25
+ sleep(4)
26
+ puts `clear`
27
+ end
28
+
29
+ def welcome_screen(str = nil)
30
+ thank_you if str == :exit
31
+ loop do
32
+ clear
33
+ print "---------------------------- Welcome to the ATM ----------------------------\n\n".colorize(:light_green), 'Enter card number => '
34
+ @card_number = gets.chomp.to_i
35
+ get_current_account(@card_number)
36
+ puts "Hello, #{@current_account.name.capitalize}\n\n"
37
+ display_options(:initial_options) unless card_blocked?
38
+ thank_you
39
+ end
40
+ rescue Interrupt
41
+ abort("\nThank You for using the ATM")
42
+ end
43
+
44
+ def get_current_account(card_number)
45
+ return if @current_account = Account.find_by_card_number(card_number)
46
+
47
+ puts 'Card not valid'
48
+ thank_you
49
+ welcome_screen
50
+ end
51
+
52
+ def display_options(option_type)
53
+ case option_type
54
+ when :initial_options
55
+ puts "\n1. Banking", '2. Mini Statement', '3. Change Pin', '4. Request Chequebook', '5. Exit', "\nSelect option :"
56
+ user_choice = Integer(gets.chomp)
57
+ execute_initial_option(user_choice)
58
+ when :banking_options
59
+ puts "\n1. Withdrawl", '2. Balance', '3. Deposit', '4. Fast Cash', '5. Back', '6. Exit', "\nSelect option :"
60
+ user_choice = Integer(gets.chomp)
61
+ execute_banking_option(user_choice)
62
+ end
63
+ rescue ArgumentError
64
+ puts 'Please enter your option in number.'
65
+ display_options(option_type)
66
+ end
67
+
68
+ def execute_initial_option(option)
69
+ case option
70
+ when 1 then display_options(:banking_options)
71
+ when 2 then mini_statement
72
+ when 3 then Transaction.new(@current_account, :'Change Pin')
73
+ when 4 then Transaction.new(@current_account, :'Request Chequebook')
74
+ when 5 then welcome_screen(:exit)
75
+ else
76
+ puts "#{option} is not a right option", 'Please select the righ option.'
77
+ display_options(:initial_options)
78
+ end
79
+ end
80
+
81
+ def execute_banking_option(option)
82
+ case option
83
+ when 1 then Transaction.new(@current_account, :Withdrawl, take_amount(:Withdrawl))
84
+ when 2 then display_balance
85
+ when 3 then Transaction.new(@current_account, :Deposit, take_amount(:Deposit))
86
+ when 4 then display_fast_cash_options
87
+ when 5 then display_options(:initial_options)
88
+ when 6 then welcome_screen(:exit)
89
+ else
90
+ puts "#{option} is not a right option", "Please select the righ option.\n"
91
+ display_options(:banking_options)
92
+ end
93
+ end
94
+
95
+ def take_amount(transaction_type)
96
+ case transaction_type
97
+ when :Withdrawl
98
+ available_denominations = [100, 200, 500]
99
+ puts "\nAvailable denominations are =>\t#{available_denominations[0]}\t#{available_denominations[1]}\t#{available_denominations[2]}\n\n"
100
+ puts "\nPlease enter amount in multiples of available denominations:"
101
+ Integer(gets.chomp)
102
+ when :Deposit
103
+ puts 'Enter amount:'
104
+ Integer(gets.chomp)
105
+ end
106
+ rescue ArgumentError
107
+ puts 'Please enter amount in numbers.'
108
+ take_amount(transaction_type)
109
+ end
110
+
111
+ def display_balance
112
+ puts "\nBalance => #{@current_account.balance}\n\n" if valid_pin?
113
+ end
114
+
115
+ def mini_statement
116
+ return unless valid_pin?
117
+
118
+ transactions = []
119
+ CSV.table('/transaction.csv').each do |row|
120
+ next unless row[:card_number] == @current_account.card_number && row[:status] == 'Success'
121
+
122
+ transaction_number = row[:transaction_number].to_s.rjust(4, '0')
123
+ transactions.append(row[:amount].nil? ? "#{transaction_number} #{row[:time]} #{row[:type]}" : "#{transaction_number} #{row[:time]} #{row[:type]} of Rs =>#{row[:amount]}")
124
+ next
125
+ end
126
+ puts transactions.empty? ? "You don't have any Transactions" : transactions.last(5)
127
+ sleep(3)
128
+ end
129
+
130
+ def display_fast_cash_options
131
+ puts '1. 1000', '2. 2000', '3. 5000', '4. 10000', '5. Back', '6. Exit', "\nselect option => "
132
+ execute_fast_cash(Integer(gets.chomp))
133
+ rescue ArgumentError
134
+ puts 'Please enter your option in number:'
135
+ display_fast_cash_options
136
+ end
137
+
138
+ def execute_fast_cash(option)
139
+ case option
140
+ when 1 then Transaction.new(@current_account, :Withdrawl, 1_000)
141
+ when 2 then Transaction.new(@current_account, :Withdrawl, 2_000)
142
+ when 3 then Transaction.new(@current_account, :Withdrawl, 5_000)
143
+ when 4 then Transaction.new(@current_account, :Withdrawl, 10_000)
144
+ when 5 then display_options(:banking_options)
145
+ when 6 then welcome_screen
146
+ else
147
+ puts "#{option} is not a right option", 'Please select the righ option.'
148
+ display_fast_cash_options
149
+ end
150
+ end
151
+
152
+ def take_pin
153
+ Integer(ask('Enter your Pin:') { |q| q.echo = '*' })
154
+ rescue ArgumentError
155
+ puts 'Please enter pin in numbers'
156
+ take_pin
157
+ end
158
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+ require 'base64'
3
+ require_relative 'atm'
4
+ require 'highline/import'
5
+ require 'colorize'
6
+
7
+ module ATM
8
+ def self.start
9
+ Atm.new
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ transaction_number,card_number,type,time,amount,status
2
+ 1,123456789012,Withdrawl,23/03/2022 12:05:36:am,102,Fail
3
+ 2,123456789011,Withdrawl,23/03/2022 12:21:12:pm,500,Success
@@ -0,0 +1,137 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'validation'
4
+ # class Transaction
5
+ class Transaction
6
+ include Validation
7
+
8
+ private
9
+
10
+ def initialize(current_account, type, amount = nil)
11
+ @current_account = current_account
12
+ @type = type
13
+ @amount = amount
14
+ @transaction_number = File.readlines('/transaction.csv').length
15
+ @row = "#{@transaction_number},#{@current_account.card_number},#{@type},#{Time.now.strftime('%d/%m/%Y %I:%M:%S:%P')},#{@amount},"
16
+ validate_type if valid_pin?
17
+ end
18
+
19
+ def validate_type
20
+ case @type
21
+ when :Withdrawl then withdrawl
22
+ when :Deposit then deposit
23
+ when :'Change Pin' then change_pin
24
+ when :'Request Chequebook' then request_chequebook
25
+ end
26
+ end
27
+
28
+ def sufficient_balance?
29
+ return true if @current_account.balance >= @amount
30
+
31
+ puts 'Insufficient balance'
32
+ @status = 'Fail'
33
+ update_transaction_file(@row << @status << "\n")
34
+ false
35
+ end
36
+
37
+ def withdrawl
38
+ return unless sufficient_balance?
39
+
40
+ if amount_in_multiples_of_available_denominations?(@amount)
41
+ @status = 'Success'
42
+ puts "Successfully withdrawl of Rs #{@amount}"
43
+ update_transaction_file(@row << @status << "\n")
44
+ update_account_file(:Withdrawl, amount: @amount)
45
+ else
46
+ @status = 'Fail'
47
+ update_transaction_file(@row << @status << "\n")
48
+ end
49
+ rescue Interrupt
50
+ rescue_interrupt
51
+ end
52
+
53
+ def deposit
54
+ @status = 'Success'
55
+ update_account_file(:Deposit, amount: @amount)
56
+ puts "Successfully deposit of Rs #{@amount}"
57
+ update_transaction_file(@row << @status << "\n")
58
+ rescue Interrupt
59
+ rescue_interrupt
60
+ end
61
+
62
+ def change_pin
63
+ pins = take_change_pins
64
+ if pins.first == pins.last
65
+ update_account_file(@type, pin: Base64.strict_encode64(pins.first.to_s))
66
+ @status = 'Success'
67
+ puts 'Successfully pin changed. '
68
+ else
69
+ puts 'New pin and confirm pin did not matched'
70
+ @status = 'Fail'
71
+ end
72
+ update_transaction_file(@row << @status << "\n")
73
+ rescue Interrupt
74
+ rescue_interrupt
75
+ end
76
+
77
+ def take_pin
78
+ Integer(ask('Enter your Pin:') { |q| q.echo = '*' })
79
+ rescue ArgumentError
80
+ puts 'Please enter pin in numbers'
81
+ take_pin
82
+ end
83
+
84
+ def take_change_pins
85
+ new_pin = Integer(ask('Enter new pin:') { |q| q.echo = '*' })
86
+ if valid_pin_length?(new_pin)
87
+ confirm_pin = Integer(ask('Enter confirm pin:') { |q| q.echo = '*' })
88
+ [new_pin, confirm_pin]
89
+ else
90
+ puts 'pin must be 4 digits.'
91
+ take_change_pins
92
+ end
93
+ rescue ArgumentError
94
+ puts 'Please enter pin in numbers'
95
+ take_change_pins
96
+ end
97
+
98
+ def request_chequebook
99
+ @status = 'Success'
100
+ puts "Hey #{@current_account.name.capitalize}, Your request for chequebook is accepted"
101
+ update_transaction_file(@row << @status << "\n")
102
+ rescue Interrupt
103
+ rescue_interrupt
104
+ end
105
+
106
+ def update_account_file(transaction_type, amount: nil, pin: nil)
107
+ data = CSV.table('/account.csv')
108
+ data.each do |entry|
109
+ next unless entry[:card_number] == @current_account.card_number
110
+
111
+ case transaction_type
112
+ when :Withdrawl then entry[:balance] -= amount
113
+ when :Deposit then entry[:balance] += amount
114
+ when :'Change Pin' then entry[:pin] = pin
115
+ end
116
+ File.write('/account.csv', data)
117
+ break
118
+ end
119
+ end
120
+
121
+ def update_transaction_file(data)
122
+ File.open('/transaction.csv', 'a') do |row|
123
+ row << data
124
+ end
125
+ end
126
+
127
+ def rescue_interrupt
128
+ thank_you
129
+ @status = 'Fail'
130
+ update_transaction_file(@row << @status << "\n")
131
+ end
132
+
133
+ def thank_you
134
+ puts "\nThank You for using the ATM"
135
+ sleep(2)
136
+ end
137
+ end
data/lib/validation.rb ADDED
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ # module Validation
4
+ module Validation
5
+
6
+ def card_blocked?
7
+ if @current_account.card_blocked == 'true'
8
+
9
+ puts 'Your card is Blocked, Please contact your branch'
10
+ welcome_screen
11
+ else
12
+ false
13
+ end
14
+ end
15
+
16
+ def valid_pin?
17
+ 3.times do |n|
18
+ pin = Base64.strict_encode64(take_pin.to_s)
19
+ return true if @current_account.pin == pin
20
+
21
+ puts "Incorrect Pin\n\n"
22
+ next unless n == 2
23
+
24
+ @accounts_table = CSV.table('/account.csv').each do |account|
25
+ if account[:card_number] == @current_account.card_number
26
+ account[:card_blocked] = 'true'
27
+ break
28
+ end
29
+ end
30
+ File.write('/account.csv', @accounts_table)
31
+ puts "You have entered wrong pin 3 times\nnow your card is blocked contact your bank for more details.."
32
+ return false
33
+ end
34
+ end
35
+
36
+ def amount_in_multiples_of_available_denominations?(amount)
37
+ available_denominations = [100, 200, 500]
38
+ if (amount % available_denominations[0]).zero? || (amount % available_denominations[1]).zero? || (amount % available_denominations[2]).zero?
39
+ true
40
+ else
41
+ puts "The amount you entered is not multiple of available denominations\n\n"
42
+ false
43
+ end
44
+ end
45
+
46
+ def valid_pin_length?(pin)
47
+ pin.to_s.length == 4
48
+ end
49
+ end
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: atm_program
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.4.1.pre
5
+ platform: ruby
6
+ authors:
7
+ - Zaid Shaikh
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-03-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: colorize
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.8.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.8.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: highline
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 2.0.3
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 2.0.3
41
+ description:
42
+ email: 45shaikhzaid@gmail.com
43
+ executables: []
44
+ extensions: []
45
+ extra_rdoc_files: []
46
+ files:
47
+ - lib/account.csv
48
+ - lib/account.rb
49
+ - lib/atm.rb
50
+ - lib/atm_program.rb
51
+ - lib/transaction.csv
52
+ - lib/transaction.rb
53
+ - lib/validation.rb
54
+ homepage: https://github.com/shaikh21/ATM
55
+ licenses:
56
+ - MIT
57
+ metadata:
58
+ documentation_uri: https://github.com/shaikh21/ATM
59
+ post_install_message:
60
+ rdoc_options: []
61
+ require_paths:
62
+ - lib
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: 2.7.0
68
+ required_rubygems_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">"
71
+ - !ruby/object:Gem::Version
72
+ version: 1.3.1
73
+ requirements: []
74
+ rubygems_version: 3.3.3
75
+ signing_key:
76
+ specification_version: 4
77
+ summary: This GEM contains the simple ATM program.
78
+ test_files: []