ng-bank-parser 0.1.6 → 0.1.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -1
- data/Gemfile.lock +42 -40
- data/README.md +10 -2
- data/lib/ng-bank-parser.rb +11 -10
- data/lib/ng-bank-parser/banks.rb +10 -1
- data/lib/ng-bank-parser/fixtures/ecobank-pdf-invalid.pdf +160 -0
- data/lib/ng-bank-parser/fixtures/ecobank-pdf-valid.pdf +0 -0
- data/lib/ng-bank-parser/parsers/accessbank-pdf-parser/helpers.rb +1 -3
- data/lib/ng-bank-parser/parsers/ecobank-pdf-parser.rb +35 -0
- data/lib/ng-bank-parser/parsers/ecobank-pdf-parser/helpers.rb +164 -0
- data/lib/ng-bank-parser/version.rb +1 -1
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 051a42caac128747e23f1153ab29969b73cbaa38
|
4
|
+
data.tar.gz: 613248ebd4a944520d81c31366c3eebca7c6297e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b97fc6045653913ba4b119c814f53936265d895c72066c303266437411362cde7878d985e6049930ca20996717fa508db3f3b8ee6c6d6f43390210c832a71e63
|
7
|
+
data.tar.gz: 145c45868fb797ec049bbf9e26ba0621256a95ea3926f5c40018826d790237be0a99feb9bac79ed986eee6cea204f4f7452c5161d9c31d8ccaac4319f64fdfbe
|
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
@@ -11,64 +11,66 @@ PATH
|
|
11
11
|
GEM
|
12
12
|
remote: https://rubygems.org/
|
13
13
|
specs:
|
14
|
-
Ascii85 (1.0.
|
15
|
-
activesupport (
|
16
|
-
|
17
|
-
|
14
|
+
Ascii85 (1.0.3)
|
15
|
+
activesupport (5.2.1)
|
16
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
17
|
+
i18n (>= 0.7, < 2)
|
18
18
|
minitest (~> 5.1)
|
19
|
-
thread_safe (~> 0.3, >= 0.3.4)
|
20
19
|
tzinfo (~> 1.1)
|
21
20
|
afm (0.2.2)
|
22
|
-
|
23
|
-
|
21
|
+
concurrent-ruby (1.0.5)
|
22
|
+
diff-lcs (1.3)
|
23
|
+
domain_name (0.5.20180417)
|
24
24
|
unf (>= 0.0.5, < 1.0.0)
|
25
|
-
hashery (2.1.
|
26
|
-
http-cookie (1.0.
|
25
|
+
hashery (2.1.2)
|
26
|
+
http-cookie (1.0.3)
|
27
27
|
domain_name (~> 0.5)
|
28
|
-
i18n (
|
29
|
-
|
30
|
-
mime-types (2.
|
31
|
-
|
32
|
-
|
28
|
+
i18n (1.1.0)
|
29
|
+
concurrent-ruby (~> 1.0)
|
30
|
+
mime-types (3.2.2)
|
31
|
+
mime-types-data (~> 3.2015)
|
32
|
+
mime-types-data (3.2018.0812)
|
33
|
+
mini_portile2 (2.3.0)
|
34
|
+
minitest (5.11.3)
|
33
35
|
netrc (0.11.0)
|
34
|
-
nokogiri (1.
|
35
|
-
mini_portile2 (~> 2.
|
36
|
-
pdf-reader (1.
|
36
|
+
nokogiri (1.8.4)
|
37
|
+
mini_portile2 (~> 2.3.0)
|
38
|
+
pdf-reader (2.1.0)
|
37
39
|
Ascii85 (~> 1.0.0)
|
38
|
-
afm (~> 0.2.
|
40
|
+
afm (~> 0.2.1)
|
39
41
|
hashery (~> 2.0)
|
40
42
|
ruby-rc4
|
41
43
|
ttfunk
|
42
|
-
rake (10.
|
43
|
-
rest-client (
|
44
|
+
rake (10.5.0)
|
45
|
+
rest-client (2.0.2)
|
44
46
|
http-cookie (>= 1.0.2, < 2.0)
|
45
|
-
mime-types (>= 1.16, <
|
46
|
-
netrc (~> 0.
|
47
|
-
roo (2.
|
47
|
+
mime-types (>= 1.16, < 4.0)
|
48
|
+
netrc (~> 0.8)
|
49
|
+
roo (2.7.1)
|
48
50
|
nokogiri (~> 1)
|
49
51
|
rubyzip (~> 1.1, < 2.0.0)
|
50
|
-
rspec (3.
|
51
|
-
rspec-core (~> 3.
|
52
|
-
rspec-expectations (~> 3.
|
53
|
-
rspec-mocks (~> 3.
|
54
|
-
rspec-core (3.
|
55
|
-
rspec-support (~> 3.
|
56
|
-
rspec-expectations (3.
|
52
|
+
rspec (3.8.0)
|
53
|
+
rspec-core (~> 3.8.0)
|
54
|
+
rspec-expectations (~> 3.8.0)
|
55
|
+
rspec-mocks (~> 3.8.0)
|
56
|
+
rspec-core (3.8.0)
|
57
|
+
rspec-support (~> 3.8.0)
|
58
|
+
rspec-expectations (3.8.1)
|
57
59
|
diff-lcs (>= 1.2.0, < 2.0)
|
58
|
-
rspec-support (~> 3.
|
59
|
-
rspec-mocks (3.
|
60
|
+
rspec-support (~> 3.8.0)
|
61
|
+
rspec-mocks (3.8.0)
|
60
62
|
diff-lcs (>= 1.2.0, < 2.0)
|
61
|
-
rspec-support (~> 3.
|
62
|
-
rspec-support (3.
|
63
|
+
rspec-support (~> 3.8.0)
|
64
|
+
rspec-support (3.8.0)
|
63
65
|
ruby-rc4 (0.1.5)
|
64
|
-
rubyzip (1.
|
65
|
-
thread_safe (0.3.
|
66
|
-
ttfunk (1.
|
67
|
-
tzinfo (1.2.
|
66
|
+
rubyzip (1.2.2)
|
67
|
+
thread_safe (0.3.6)
|
68
|
+
ttfunk (1.5.1)
|
69
|
+
tzinfo (1.2.5)
|
68
70
|
thread_safe (~> 0.1)
|
69
71
|
unf (0.1.4)
|
70
72
|
unf_ext
|
71
|
-
unf_ext (0.0.7.
|
73
|
+
unf_ext (0.0.7.5)
|
72
74
|
|
73
75
|
PLATFORMS
|
74
76
|
ruby
|
@@ -80,4 +82,4 @@ DEPENDENCIES
|
|
80
82
|
rspec
|
81
83
|
|
82
84
|
BUNDLED WITH
|
83
|
-
1.
|
85
|
+
1.16.4
|
data/README.md
CHANGED
@@ -2,9 +2,9 @@
|
|
2
2
|
This is a simple gem to parse Nigerian bank statements of all formats. If your bank and/or file format is not supported, consider reading the contribute wiki and submitting a pull request.
|
3
3
|
|
4
4
|
## API
|
5
|
-
Because not everyone develops in rails, we created a public API to use the gem at http://bank-parser.
|
5
|
+
Because not everyone develops in rails, we created a public API to use the gem at http://bank-parser.square-api.com/parse. The parameters are (bank_key, file_path, password). Read the *Usage* section for more information
|
6
6
|
|
7
|
-
http://bank-parser.
|
7
|
+
http://bank-parser.square-api.com/parse(bank_key, file_path, password)
|
8
8
|
|
9
9
|
## Installation
|
10
10
|
|
@@ -92,6 +92,14 @@ Heritage Bank:
|
|
92
92
|
- key: hb
|
93
93
|
- supported formats: pdf
|
94
94
|
|
95
|
+
Access Bank:
|
96
|
+
- key: accessbank
|
97
|
+
- supported formats: pdf
|
98
|
+
|
99
|
+
Ecobank:
|
100
|
+
- key: ecobank
|
101
|
+
- supported formats: pdf
|
102
|
+
|
95
103
|
## Contributing
|
96
104
|
|
97
105
|
Documentation on contribution can be found in the contribution wiki
|
data/lib/ng-bank-parser.rb
CHANGED
@@ -1,13 +1,14 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
1
|
+
require_relative "ng-bank-parser/version"
|
2
|
+
require_relative "ng-bank-parser/banks"
|
3
|
+
require_relative "ng-bank-parser/router"
|
4
|
+
require_relative "ng-bank-parser/pdf-unlocker"
|
5
|
+
require_relative "ng-bank-parser/parsers/gtb-excel-parser"
|
6
|
+
require_relative "ng-bank-parser/parsers/uba-pdf-parser"
|
7
|
+
require_relative "ng-bank-parser/parsers/hb-pdf-parser"
|
8
|
+
require_relative "ng-bank-parser/parsers/firstbank-pdf-parser"
|
9
|
+
require_relative "ng-bank-parser/parsers/accessbank-pdf-parser"
|
10
|
+
require_relative "ng-bank-parser/parsers/ecobank-pdf-parser"
|
10
11
|
|
11
12
|
module NgBankParser
|
12
|
-
# Your code goes here...
|
13
|
+
# Your code goes here...
|
13
14
|
end
|
data/lib/ng-bank-parser/banks.rb
CHANGED
@@ -46,6 +46,15 @@ module NgBankParser
|
|
46
46
|
invalid: "lib/ng-bank-parser/fixtures/accessbank-pdf-invalid.pdf",
|
47
47
|
extensions: ["pdf"]
|
48
48
|
}]
|
49
|
-
}
|
49
|
+
},{
|
50
|
+
key: "ecobank",
|
51
|
+
name: "Ecobank Nigeria",
|
52
|
+
parsers: [{
|
53
|
+
format: "pdf",
|
54
|
+
valid: "lib/ng-bank-parser/fixtures/ecobank-pdf-valid.pdf",
|
55
|
+
invalid: "lib/ng-bank-parser/fixtures/ecobank-pdf-invalid.pdf",
|
56
|
+
extensions: ["pdf"]
|
57
|
+
}]
|
58
|
+
}]
|
50
59
|
end
|
51
60
|
end
|
@@ -0,0 +1,160 @@
|
|
1
|
+
%PDF-1.3
|
2
|
+
3 0 obj
|
3
|
+
<</Type /Page
|
4
|
+
/Parent 1 0 R
|
5
|
+
/Resources 2 0 R
|
6
|
+
/Contents 4 0 R>>
|
7
|
+
endobj
|
8
|
+
4 0 obj
|
9
|
+
<</Length 165>>
|
10
|
+
stream
|
11
|
+
0.57 w
|
12
|
+
0 G
|
13
|
+
BT
|
14
|
+
/F1 16 Tf
|
15
|
+
16 TL
|
16
|
+
0 g
|
17
|
+
56.69 785.20 Td
|
18
|
+
(Hello world!) Tj
|
19
|
+
ET
|
20
|
+
BT
|
21
|
+
/F1 16 Tf
|
22
|
+
16 TL
|
23
|
+
0 g
|
24
|
+
56.69 756.85 Td
|
25
|
+
(This a random PDF file for testing our parsers.) Tj
|
26
|
+
ET
|
27
|
+
endstream
|
28
|
+
endobj
|
29
|
+
1 0 obj
|
30
|
+
<</Type /Pages
|
31
|
+
/Kids [3 0 R ]
|
32
|
+
/Count 1
|
33
|
+
/MediaBox [0 0 595.28 841.89]
|
34
|
+
>>
|
35
|
+
endobj
|
36
|
+
5 0 obj
|
37
|
+
<</BaseFont/Helvetica/Type/Font
|
38
|
+
/Encoding/WinAnsiEncoding
|
39
|
+
/Subtype/Type1>>
|
40
|
+
endobj
|
41
|
+
6 0 obj
|
42
|
+
<</BaseFont/Helvetica-Bold/Type/Font
|
43
|
+
/Encoding/WinAnsiEncoding
|
44
|
+
/Subtype/Type1>>
|
45
|
+
endobj
|
46
|
+
7 0 obj
|
47
|
+
<</BaseFont/Helvetica-Oblique/Type/Font
|
48
|
+
/Encoding/WinAnsiEncoding
|
49
|
+
/Subtype/Type1>>
|
50
|
+
endobj
|
51
|
+
8 0 obj
|
52
|
+
<</BaseFont/Helvetica-BoldOblique/Type/Font
|
53
|
+
/Encoding/WinAnsiEncoding
|
54
|
+
/Subtype/Type1>>
|
55
|
+
endobj
|
56
|
+
9 0 obj
|
57
|
+
<</BaseFont/Courier/Type/Font
|
58
|
+
/Encoding/WinAnsiEncoding
|
59
|
+
/Subtype/Type1>>
|
60
|
+
endobj
|
61
|
+
10 0 obj
|
62
|
+
<</BaseFont/Courier-Bold/Type/Font
|
63
|
+
/Encoding/WinAnsiEncoding
|
64
|
+
/Subtype/Type1>>
|
65
|
+
endobj
|
66
|
+
11 0 obj
|
67
|
+
<</BaseFont/Courier-Oblique/Type/Font
|
68
|
+
/Encoding/WinAnsiEncoding
|
69
|
+
/Subtype/Type1>>
|
70
|
+
endobj
|
71
|
+
12 0 obj
|
72
|
+
<</BaseFont/Courier-BoldOblique/Type/Font
|
73
|
+
/Encoding/WinAnsiEncoding
|
74
|
+
/Subtype/Type1>>
|
75
|
+
endobj
|
76
|
+
13 0 obj
|
77
|
+
<</BaseFont/Times-Roman/Type/Font
|
78
|
+
/Encoding/WinAnsiEncoding
|
79
|
+
/Subtype/Type1>>
|
80
|
+
endobj
|
81
|
+
14 0 obj
|
82
|
+
<</BaseFont/Times-Bold/Type/Font
|
83
|
+
/Encoding/WinAnsiEncoding
|
84
|
+
/Subtype/Type1>>
|
85
|
+
endobj
|
86
|
+
15 0 obj
|
87
|
+
<</BaseFont/Times-Italic/Type/Font
|
88
|
+
/Encoding/WinAnsiEncoding
|
89
|
+
/Subtype/Type1>>
|
90
|
+
endobj
|
91
|
+
16 0 obj
|
92
|
+
<</BaseFont/Times-BoldItalic/Type/Font
|
93
|
+
/Encoding/WinAnsiEncoding
|
94
|
+
/Subtype/Type1>>
|
95
|
+
endobj
|
96
|
+
2 0 obj
|
97
|
+
<<
|
98
|
+
/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]
|
99
|
+
/Font <<
|
100
|
+
/F1 5 0 R
|
101
|
+
/F2 6 0 R
|
102
|
+
/F3 7 0 R
|
103
|
+
/F4 8 0 R
|
104
|
+
/F5 9 0 R
|
105
|
+
/F6 10 0 R
|
106
|
+
/F7 11 0 R
|
107
|
+
/F8 12 0 R
|
108
|
+
/F9 13 0 R
|
109
|
+
/F10 14 0 R
|
110
|
+
/F11 15 0 R
|
111
|
+
/F12 16 0 R
|
112
|
+
>>
|
113
|
+
/XObject <<
|
114
|
+
>>
|
115
|
+
>>
|
116
|
+
endobj
|
117
|
+
17 0 obj
|
118
|
+
<<
|
119
|
+
/Producer (jsPDF 20120619)
|
120
|
+
/CreationDate (D:20150829130726)
|
121
|
+
>>
|
122
|
+
endobj
|
123
|
+
18 0 obj
|
124
|
+
<<
|
125
|
+
/Type /Catalog
|
126
|
+
/Pages 1 0 R
|
127
|
+
/OpenAction [3 0 R /FitH null]
|
128
|
+
/PageLayout /OneColumn
|
129
|
+
>>
|
130
|
+
endobj
|
131
|
+
xref
|
132
|
+
0 19
|
133
|
+
0000000000 65535 f
|
134
|
+
0000000301 00000 n
|
135
|
+
0000001530 00000 n
|
136
|
+
0000000009 00000 n
|
137
|
+
0000000087 00000 n
|
138
|
+
0000000388 00000 n
|
139
|
+
0000000478 00000 n
|
140
|
+
0000000573 00000 n
|
141
|
+
0000000671 00000 n
|
142
|
+
0000000773 00000 n
|
143
|
+
0000000861 00000 n
|
144
|
+
0000000955 00000 n
|
145
|
+
0000001052 00000 n
|
146
|
+
0000001153 00000 n
|
147
|
+
0000001246 00000 n
|
148
|
+
0000001338 00000 n
|
149
|
+
0000001432 00000 n
|
150
|
+
0000001754 00000 n
|
151
|
+
0000001836 00000 n
|
152
|
+
trailer
|
153
|
+
<<
|
154
|
+
/Size 19
|
155
|
+
/Root 18 0 R
|
156
|
+
/Info 17 0 R
|
157
|
+
>>
|
158
|
+
startxref
|
159
|
+
1940
|
160
|
+
%%EOF
|
Binary file
|
@@ -111,8 +111,6 @@ module AccessbankPdfHelpers
|
|
111
111
|
end
|
112
112
|
|
113
113
|
|
114
|
-
|
115
|
-
|
116
114
|
def error(msg)
|
117
115
|
{ status: 400, message: msg }
|
118
116
|
end
|
@@ -122,7 +120,6 @@ module AccessbankPdfHelpers
|
|
122
120
|
end
|
123
121
|
|
124
122
|
|
125
|
-
|
126
123
|
private
|
127
124
|
def remove_line_spacing(str)
|
128
125
|
str.gsub(/^$\n/, '').lines
|
@@ -161,6 +158,7 @@ module AccessbankPdfHelpers
|
|
161
158
|
Date.strptime(date_str, '%d-%b-%y')
|
162
159
|
end
|
163
160
|
|
161
|
+
|
164
162
|
def string_with_slash_to_date(date_str)
|
165
163
|
Date.strptime(date_str, '%d/%m/%Y')
|
166
164
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'pdf-reader'
|
2
|
+
require 'open-uri'
|
3
|
+
require_relative 'ecobank-pdf-parser/helpers'
|
4
|
+
|
5
|
+
module NgBankParser
|
6
|
+
class EcobankPdf
|
7
|
+
extend EcobankPdfHelpers
|
8
|
+
|
9
|
+
FILE_FORMATS = [".pdf"]
|
10
|
+
|
11
|
+
def self.parse(path, password=nil)
|
12
|
+
unless FILE_FORMATS.include? File.extname(path)
|
13
|
+
return error("Invalid file format. Please use one of the following: #{ FILE_FORMATS.each{ |format| format }}")
|
14
|
+
end
|
15
|
+
|
16
|
+
file = open(path)
|
17
|
+
begin
|
18
|
+
@pdf = PDF::Reader.new(file)
|
19
|
+
rescue PDF::Reader::EncryptedPDFError
|
20
|
+
return error("Invalid file. Please use an unencrypted pdf")
|
21
|
+
rescue
|
22
|
+
return error("Couldn't parse this file")
|
23
|
+
end
|
24
|
+
|
25
|
+
pdf_array = pdf_to_a(@pdf)
|
26
|
+
|
27
|
+
unless has_valid_details?(pdf_array)
|
28
|
+
return error("Couldn't fetch account details from pdf")
|
29
|
+
end
|
30
|
+
|
31
|
+
response = get_details(pdf_array)
|
32
|
+
return success(response)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,164 @@
|
|
1
|
+
module NgBankParser
|
2
|
+
module EcobankPdfHelpers
|
3
|
+
|
4
|
+
def pdf_to_a(pdf)
|
5
|
+
lines = []
|
6
|
+
|
7
|
+
pdf.pages.each do |page|
|
8
|
+
remove_line_spacing(page.text).each do |line|
|
9
|
+
lines << line.strip.split(/\s\s+/)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
return lines
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
def get_details(pdf_array)
|
18
|
+
details = Hash.new
|
19
|
+
details[:bank_name] = 'Ecobank'
|
20
|
+
details[:account_number] = get_account_number(pdf_array)
|
21
|
+
details[:account_name] = get_account_name(pdf_array)
|
22
|
+
|
23
|
+
transactions = get_transactions(pdf_array)
|
24
|
+
details[:from_date] = transactions[0][:date]
|
25
|
+
details[:to_date] = transactions[-1][:date]
|
26
|
+
details[:transactions] = transactions
|
27
|
+
|
28
|
+
return details
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
def has_valid_details?(pdf_array)
|
33
|
+
return (get_account_number(pdf_array) and get_account_name(pdf_array))
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
def get_account_name(pdf_array)
|
38
|
+
pdf_array.each do |row|
|
39
|
+
row.each_with_index do |cell, index|
|
40
|
+
if cell == 'Name'
|
41
|
+
return row[index + 1]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
return nil
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
def get_account_number(pdf_array)
|
50
|
+
pdf_array.each do |row|
|
51
|
+
row.each do |cell|
|
52
|
+
if cell =~ /[0-9]{10}/
|
53
|
+
return cell
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
return nil
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
def get_transactions(pdf_array)
|
62
|
+
start_index = get_first_line_of_transactions(pdf_array)
|
63
|
+
transactions = []
|
64
|
+
|
65
|
+
opening_balance = pdf_array[start_index][-1]
|
66
|
+
|
67
|
+
pdf_array[start_index..-1].each do |transaction|
|
68
|
+
if valid_transaction?(transaction)
|
69
|
+
|
70
|
+
transaction_hash = Hash.new
|
71
|
+
transaction_hash[:date] = string_with_dash_to_date(transaction[0])
|
72
|
+
|
73
|
+
if transaction.count == 6
|
74
|
+
transaction_hash[:remarks] = transaction[2]
|
75
|
+
transaction_hash[:ref] = transaction[3]
|
76
|
+
transaction_hash[:amount] = amount_to_f(transaction[4])
|
77
|
+
transaction_hash[:balance] = amount_to_f(transaction[5])
|
78
|
+
elsif transaction.count == 5
|
79
|
+
if transaction[2].chars.first === "'"
|
80
|
+
transaction_hash[:remarks] = ""
|
81
|
+
transaction_hash[:ref] = transaction[2]
|
82
|
+
transaction_hash[:amount] = amount_to_f(transaction[3])
|
83
|
+
transaction_hash[:balance] = amount_to_f(transaction[4])
|
84
|
+
elsif transaction[2].split("'")[1]
|
85
|
+
transaction_hash[:remarks] = transaction[2].split("'")[0]
|
86
|
+
transaction_hash[:ref] = transaction[2].split("'")[1]
|
87
|
+
transaction_hash[:amount] = amount_to_f(transaction[3])
|
88
|
+
transaction_hash[:balance] = amount_to_f(transaction[4])
|
89
|
+
else
|
90
|
+
transaction_hash[:remarks] = transaction[2]
|
91
|
+
transaction_hash[:ref] = transaction[3]
|
92
|
+
amount_and_balance = transaction[4].split(" ")
|
93
|
+
transaction_hash[:amount] = amount_to_f(amount_and_balance[0])
|
94
|
+
transaction_hash[:balance] = amount_to_f(amount_and_balance[1])
|
95
|
+
end
|
96
|
+
else
|
97
|
+
remarks_and_ref = transaction[2].split("'")
|
98
|
+
transaction_hash[:remarks] = remarks_and_ref[0]
|
99
|
+
transaction_hash[:ref] = "'" << remarks_and_ref[1]
|
100
|
+
amount_and_balance = transaction[3].split(" ")
|
101
|
+
transaction_hash[:amount] = amount_to_f(amount_and_balance[0])
|
102
|
+
transaction_hash[:balance] = amount_to_f(amount_and_balance[1])
|
103
|
+
end
|
104
|
+
|
105
|
+
transaction_hash[:type] = transaction_type(transaction_hash[:balance], opening_balance)
|
106
|
+
|
107
|
+
opening_balance = transaction_hash[:balance]
|
108
|
+
transactions << transaction_hash
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
return transactions
|
113
|
+
end
|
114
|
+
|
115
|
+
|
116
|
+
def error(message)
|
117
|
+
{ status: 400, message: message }
|
118
|
+
end
|
119
|
+
|
120
|
+
def success(data)
|
121
|
+
{ status: 200, data: data }
|
122
|
+
end
|
123
|
+
|
124
|
+
|
125
|
+
private
|
126
|
+
def remove_line_spacing(str)
|
127
|
+
str.gsub(/^$\n/, '').lines
|
128
|
+
end
|
129
|
+
|
130
|
+
|
131
|
+
def transaction_type(current_balance, former_balance)
|
132
|
+
former_balance = amount_to_f(former_balance) if former_balance.is_a?(String)
|
133
|
+
|
134
|
+
current_balance - former_balance > 1 ? 'credit' : 'debit'
|
135
|
+
end
|
136
|
+
|
137
|
+
|
138
|
+
def amount_to_f(amount)
|
139
|
+
amount.gsub(/[^\d\.]/, '').to_f
|
140
|
+
end
|
141
|
+
|
142
|
+
|
143
|
+
def get_first_line_of_transactions(pdf_array)
|
144
|
+
start = -1
|
145
|
+
|
146
|
+
pdf_array.each_with_index do |row, index|
|
147
|
+
start = index + 1 if row[0] == 'Transaction Date'
|
148
|
+
end
|
149
|
+
|
150
|
+
return start
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
def valid_transaction?(line)
|
155
|
+
# first column matches ecobank transaction date pattern and it has between 4 and 6 columns
|
156
|
+
line[0] =~ /([0-3][0-9])[\-]([a-zA-Z]+)[\-]([0-9]{4})/ and line.count >= 4 and line.count <= 6
|
157
|
+
end
|
158
|
+
|
159
|
+
|
160
|
+
def string_with_dash_to_date(date_str)
|
161
|
+
Date.strptime(date_str, '%d-%b-%y')
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ng-bank-parser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Opemipo Aikomo
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: exe
|
13
13
|
cert_chain: []
|
14
|
-
date:
|
14
|
+
date: 2018-09-14 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: bundler
|
@@ -150,6 +150,8 @@ files:
|
|
150
150
|
- lib/ng-bank-parser/banks.rb
|
151
151
|
- lib/ng-bank-parser/fixtures/accessbank-pdf-invalid.pdf
|
152
152
|
- lib/ng-bank-parser/fixtures/accessbank-pdf-valid.pdf
|
153
|
+
- lib/ng-bank-parser/fixtures/ecobank-pdf-invalid.pdf
|
154
|
+
- lib/ng-bank-parser/fixtures/ecobank-pdf-valid.pdf
|
153
155
|
- lib/ng-bank-parser/fixtures/firstbank-pdf-invalid.pdf
|
154
156
|
- lib/ng-bank-parser/fixtures/firstbank-pdf-valid.pdf
|
155
157
|
- lib/ng-bank-parser/fixtures/gtb-excel-invalid.pdf
|
@@ -161,6 +163,8 @@ files:
|
|
161
163
|
- lib/ng-bank-parser/fixtures/uba-pdf-valid.pdf
|
162
164
|
- lib/ng-bank-parser/parsers/accessbank-pdf-parser.rb
|
163
165
|
- lib/ng-bank-parser/parsers/accessbank-pdf-parser/helpers.rb
|
166
|
+
- lib/ng-bank-parser/parsers/ecobank-pdf-parser.rb
|
167
|
+
- lib/ng-bank-parser/parsers/ecobank-pdf-parser/helpers.rb
|
164
168
|
- lib/ng-bank-parser/parsers/firstbank-pdf-parser.rb
|
165
169
|
- lib/ng-bank-parser/parsers/firstbank-pdf-parser/helpers.rb
|
166
170
|
- lib/ng-bank-parser/parsers/firstbank-pdf-parser/statement_utils.rb
|
@@ -199,7 +203,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
199
203
|
version: '0'
|
200
204
|
requirements: []
|
201
205
|
rubyforge_project:
|
202
|
-
rubygems_version: 2.
|
206
|
+
rubygems_version: 2.5.2
|
203
207
|
signing_key:
|
204
208
|
specification_version: 4
|
205
209
|
summary: This is a simple gem to parse Nigerian bank statements of all formats created
|