bankserv 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +6 -0
- data/.rvmrc +1 -0
- data/Gemfile +16 -0
- data/Rakefile +8 -0
- data/bankserv.gemspec +31 -0
- data/config.ru +7 -0
- data/lib/bankserv.rb +48 -0
- data/lib/bankserv/account_holder_verification.rb +90 -0
- data/lib/bankserv/bank_account.rb +19 -0
- data/lib/bankserv/configuration.rb +67 -0
- data/lib/bankserv/credit.rb +70 -0
- data/lib/bankserv/debit.rb +94 -0
- data/lib/bankserv/eft.rb +83 -0
- data/lib/bankserv/engine.rb +183 -0
- data/lib/bankserv/engine/engine_configuration.rb +12 -0
- data/lib/bankserv/engine/engine_process.rb +3 -0
- data/lib/bankserv/request.rb +27 -0
- data/lib/bankserv/transaction.rb +22 -0
- data/lib/bankserv/transmission/document.rb +43 -0
- data/lib/bankserv/transmission/input_document.rb +84 -0
- data/lib/bankserv/transmission/output_document.rb +27 -0
- data/lib/bankserv/transmission/record.rb +13 -0
- data/lib/bankserv/transmission/reply_document.rb +27 -0
- data/lib/bankserv/transmission/set.rb +120 -0
- data/lib/bankserv/transmission/set/account_holder_verification.rb +81 -0
- data/lib/bankserv/transmission/set/account_holder_verification_output.rb +17 -0
- data/lib/bankserv/transmission/set/credit.rb +44 -0
- data/lib/bankserv/transmission/set/debit.rb +44 -0
- data/lib/bankserv/transmission/set/document.rb +45 -0
- data/lib/bankserv/transmission/set/eft.rb +228 -0
- data/lib/bankserv/transmission/set/eft_output.rb +12 -0
- data/lib/bankserv/transmission/set/eft_redirect.rb +18 -0
- data/lib/bankserv/transmission/set/eft_unpaid.rb +18 -0
- data/lib/bankserv/transmission/set/reply.rb +47 -0
- data/lib/bankserv/transmission/statement.rb +46 -0
- data/lib/bankserv/version.rb +3 -0
- data/lib/config/ahv.yml +9 -0
- data/lib/core_extensions.rb +37 -0
- data/lib/generators/active_record/bankserv_generator.rb +30 -0
- data/lib/generators/active_record/templates/migration.rb +141 -0
- data/spec/examples/ahv_input_file.txt +7 -0
- data/spec/examples/ahv_output_file.txt +7 -0
- data/spec/examples/credit_eft_input.txt +166 -0
- data/spec/examples/debit_eft_input_file.txt +20 -0
- data/spec/examples/eft_input_with_2_sets.txt +8 -0
- data/spec/examples/eft_output_file.txt +35 -0
- data/spec/examples/host2host/tmp.log +1 -0
- data/spec/examples/reply/rejected_transmission.txt +7 -0
- data/spec/examples/reply/reply_file.txt +5 -0
- data/spec/examples/statement4_unpacked.dat +51 -0
- data/spec/examples/tmp/OUTPUT0412153500.txt +35 -0
- data/spec/examples/tmp/REPLY0412153000.txt +5 -0
- data/spec/factories.rb +90 -0
- data/spec/internal/config/database.yml.sample +3 -0
- data/spec/internal/config/routes.rb +3 -0
- data/spec/internal/db/schema.rb +138 -0
- data/spec/internal/log/.gitignore +1 -0
- data/spec/internal/public/favicon.ico +0 -0
- data/spec/lib/bankserv/account_holder_verification_spec.rb +104 -0
- data/spec/lib/bankserv/configuration_spec.rb +34 -0
- data/spec/lib/bankserv/core_ext_spec.rb +43 -0
- data/spec/lib/bankserv/credit_spec.rb +92 -0
- data/spec/lib/bankserv/debit_spec.rb +187 -0
- data/spec/lib/bankserv/engine/engine_spec.rb +142 -0
- data/spec/lib/bankserv/transaction_spec.rb +32 -0
- data/spec/lib/bankserv/transmission/input_document_spec.rb +207 -0
- data/spec/lib/bankserv/transmission/output_document_spec.rb +210 -0
- data/spec/lib/bankserv/transmission/reply_document_spec.rb +117 -0
- data/spec/lib/bankserv/transmission/set/account_holder_verification_spec.rb +108 -0
- data/spec/lib/bankserv/transmission/set/credit_spec.rb +96 -0
- data/spec/lib/bankserv/transmission/set/debit_spec.rb +103 -0
- data/spec/lib/bankserv/transmission/statement_spec.rb +109 -0
- data/spec/spec_helper.rb +28 -0
- data/spec/support/helpers.rb +207 -0
- metadata +223 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
class Bankserv::OutputDocument < Bankserv::Document
|
2
|
+
|
3
|
+
def self.document_type
|
4
|
+
'output'
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.store(string)
|
8
|
+
options = Absa::H2h::Transmission::Document.hash_from_s(string, 'output')
|
9
|
+
|
10
|
+
raise "Expected a document set" unless options[:type] == "document"
|
11
|
+
|
12
|
+
document = Bankserv::OutputDocument.new(type: 'output')
|
13
|
+
document.set = Bankserv::Set.from_hash(options)
|
14
|
+
document.set.document = document # whaaaaaa?
|
15
|
+
document.save!
|
16
|
+
document
|
17
|
+
end
|
18
|
+
|
19
|
+
def process!
|
20
|
+
raise "Document already processed" if processed?
|
21
|
+
|
22
|
+
self.set.process
|
23
|
+
self.processed = true
|
24
|
+
self.save
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class Bankserv::ReplyDocument < Bankserv::Document
|
2
|
+
|
3
|
+
def self.document_type
|
4
|
+
'reply'
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.store(string)
|
8
|
+
options = Absa::H2h::Transmission::Document.hash_from_s(string, 'output')
|
9
|
+
|
10
|
+
raise "Expected a document set" unless options[:type] == "document"
|
11
|
+
|
12
|
+
document = Bankserv::ReplyDocument.new(type: 'output')
|
13
|
+
document.set = Bankserv::Set.from_hash(options)
|
14
|
+
document.set.document = document # whaaaaaa?
|
15
|
+
document.save!
|
16
|
+
document
|
17
|
+
end
|
18
|
+
|
19
|
+
def process!
|
20
|
+
raise "Document already processed" if processed?
|
21
|
+
|
22
|
+
self.set.process
|
23
|
+
self.processed = true
|
24
|
+
self.save
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
module Bankserv
|
2
|
+
|
3
|
+
class Set < ActiveRecord::Base
|
4
|
+
belongs_to :set
|
5
|
+
has_many :sets
|
6
|
+
|
7
|
+
has_one :document
|
8
|
+
has_many :records
|
9
|
+
|
10
|
+
def build_header(options = {})
|
11
|
+
records.build(record_type: "header", data: options)
|
12
|
+
end
|
13
|
+
|
14
|
+
def build_trailer(options = {})
|
15
|
+
records.build(record_type: "trailer", data: options)
|
16
|
+
end
|
17
|
+
|
18
|
+
def parent
|
19
|
+
set
|
20
|
+
end
|
21
|
+
|
22
|
+
def rec_status # is it test/live data
|
23
|
+
return document.rec_status if document
|
24
|
+
return parent.rec_status if parent
|
25
|
+
"T"
|
26
|
+
end
|
27
|
+
|
28
|
+
def header
|
29
|
+
records.select {|rec| rec.record_type == "header"}.first
|
30
|
+
end
|
31
|
+
|
32
|
+
def trailer
|
33
|
+
records.select {|rec| rec.record_type == "trailer"}.first
|
34
|
+
end
|
35
|
+
|
36
|
+
def transactions
|
37
|
+
records.select {|rec| !(["header", "trailer"].include? rec.record_type) }
|
38
|
+
end
|
39
|
+
|
40
|
+
def decorate_records
|
41
|
+
klass = "Absa::H2h::Transmission::#{set_type.camelize}".constantize
|
42
|
+
|
43
|
+
records.each do |record|
|
44
|
+
defaults = klass.record_type(record.record_type).template_options
|
45
|
+
record.data = defaults.merge(record.data)
|
46
|
+
record.data[:rec_status] = rec_status unless record.data[:rec_status]
|
47
|
+
end
|
48
|
+
|
49
|
+
self.records.each{|rec| rec.save!} # TODO: does this cause records to save before set?
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.partial_class_name
|
53
|
+
self.name.split("::")[-1]
|
54
|
+
end
|
55
|
+
|
56
|
+
def number_of_records
|
57
|
+
records.size + sets.inject(0) { |sum, set| sum + set.number_of_records }
|
58
|
+
end
|
59
|
+
|
60
|
+
def set_type
|
61
|
+
self.class.partial_class_name.underscore
|
62
|
+
end
|
63
|
+
|
64
|
+
def to_hash
|
65
|
+
data = []
|
66
|
+
data << header.to_hash if header
|
67
|
+
data << transactions.collect{|rec| rec.to_hash}
|
68
|
+
data << sets.collect{|s| s.to_hash}
|
69
|
+
data << trailer.to_hash if trailer
|
70
|
+
data.flatten!
|
71
|
+
|
72
|
+
{
|
73
|
+
type: set_type,
|
74
|
+
data: data
|
75
|
+
}
|
76
|
+
end
|
77
|
+
|
78
|
+
def process
|
79
|
+
sets.each{|s| s.process}
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.from_hash(options)
|
83
|
+
header_options = options[:data].select{|h| h[:type] == 'header'}.first
|
84
|
+
trailer_options = options[:data].select{|h| h[:type] == 'trailer'}.first
|
85
|
+
transaction_options = options[:data].select{|h| not ['header','trailer'].include?(h[:type])}
|
86
|
+
|
87
|
+
klass_name = "Bankserv::Transmission::UserSet::#{options[:type].camelize}"
|
88
|
+
|
89
|
+
if klass_name == "Bankserv::Transmission::UserSet::Eft"
|
90
|
+
# hack for debit/credit eft
|
91
|
+
klass_name = "Bankserv::Transmission::UserSet::Debit" if header_options[:data][:rec_id] == "001"
|
92
|
+
klass_name = "Bankserv::Transmission::UserSet::Credit" if header_options[:data][:rec_id] == "020"
|
93
|
+
end
|
94
|
+
|
95
|
+
set = klass_name.constantize.new
|
96
|
+
set.build_header(header_options[:data]) if header_options
|
97
|
+
|
98
|
+
transaction_options.each do |option|
|
99
|
+
if option[:data].is_a? Array
|
100
|
+
set.sets << self.from_hash(option)
|
101
|
+
else
|
102
|
+
set.records << Record.new(record_type: option[:type], data: option[:data], reference: option[:data][:user_ref])
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
set.build_trailer(trailer_options[:data]) if trailer_options
|
107
|
+
set
|
108
|
+
end
|
109
|
+
|
110
|
+
def contained_sets
|
111
|
+
([self] + sets.map(&:contained_sets)).flatten
|
112
|
+
end
|
113
|
+
|
114
|
+
def record_with_sequence_number(sequence_number)
|
115
|
+
transactions.select{|rec| rec.data[:user_sequence_number] == sequence_number}.first
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module Bankserv
|
2
|
+
module Transmission::UserSet
|
3
|
+
|
4
|
+
class AccountHolderVerification < Set
|
5
|
+
|
6
|
+
before_save :set_trailer, :decorate_records
|
7
|
+
after_save :set_header
|
8
|
+
|
9
|
+
def self.generate(options = {})
|
10
|
+
[:internal, :external].collect do |type|
|
11
|
+
ahvs = Bankserv::AccountHolderVerification.unprocessed.send(type)
|
12
|
+
|
13
|
+
if options[:rec_status] == "L"
|
14
|
+
ahvs.select!{|ahv| not ahv.request.test?}
|
15
|
+
else
|
16
|
+
ahvs.select!{|ahv| ahv.request.test?}
|
17
|
+
end
|
18
|
+
|
19
|
+
if ahvs.count > 0
|
20
|
+
set = self.new
|
21
|
+
set.build_header
|
22
|
+
ahvs.each{|ahv| set.build_transaction(ahv)}
|
23
|
+
set.build_trailer
|
24
|
+
set
|
25
|
+
end
|
26
|
+
end.compact
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.has_work?
|
30
|
+
Bankserv::AccountHolderVerification.unprocessed.select{|item| not item.request.test?}.any?
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.has_test_work?
|
34
|
+
Bankserv::AccountHolderVerification.unprocessed.select{|item| item.request.test?}.any?
|
35
|
+
end
|
36
|
+
|
37
|
+
def build_transaction(ahv)
|
38
|
+
record_data = if ahv.external?
|
39
|
+
Absa::H2h::Transmission::AccountHolderVerification.record_type('external_account_detail').template_options
|
40
|
+
else
|
41
|
+
Absa::H2h::Transmission::AccountHolderVerification.record_type('internal_account_detail').template_options
|
42
|
+
end
|
43
|
+
|
44
|
+
record_data.merge!(
|
45
|
+
seq_no: (transactions.count + 1).to_s,
|
46
|
+
account_number: ahv.bank_account.account_number,
|
47
|
+
id_number: ahv.bank_account.id_number,
|
48
|
+
initials: ahv.bank_account.initials,
|
49
|
+
surname: ahv.bank_account.account_name,
|
50
|
+
user_ref: ahv.internal_user_ref
|
51
|
+
)
|
52
|
+
|
53
|
+
record_data.merge!(branch_code: ahv.bank_account.branch_code) if ahv.external?
|
54
|
+
|
55
|
+
record_type = ahv.internal? ? "internal_account_detail" : "external_account_detail"
|
56
|
+
records.build(record_type: record_type, data: record_data)
|
57
|
+
end
|
58
|
+
|
59
|
+
def account_number_total
|
60
|
+
transactions.inject(0) {|res, e| res + e.data[:account_number].to_i}
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def set_header
|
66
|
+
self.generation_number = Bankserv::Configuration.reserve_user_generation_number!.to_s
|
67
|
+
header.data[:gen_no] = generation_number
|
68
|
+
header.data[:dept_code] = Bankserv::Configuration.department_code
|
69
|
+
header.save!
|
70
|
+
end
|
71
|
+
|
72
|
+
def set_trailer
|
73
|
+
trailer.data[:no_det_recs] = self.transactions.count.to_s
|
74
|
+
trailer.data[:acc_total] = self.account_number_total.to_s
|
75
|
+
trailer.save!
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Bankserv
|
2
|
+
|
3
|
+
module Transmission::UserSet
|
4
|
+
|
5
|
+
class AccountHolderVerificationOutput < Set
|
6
|
+
|
7
|
+
def process
|
8
|
+
transactions.each do |transaction|
|
9
|
+
Bankserv::AccountHolderVerification.for_internal_reference(transaction.reference).first.process_response(transaction.data)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Bankserv
|
2
|
+
module Transmission::UserSet
|
3
|
+
|
4
|
+
class Credit < Eft
|
5
|
+
|
6
|
+
before_save :decorate_records, :decorate_header, :decorate_trailer
|
7
|
+
|
8
|
+
attr_accessor :type_of_service, :accepted_report, :account_type_correct
|
9
|
+
|
10
|
+
def self.class_type
|
11
|
+
Bankserv::Credit
|
12
|
+
end
|
13
|
+
|
14
|
+
def class_type
|
15
|
+
Bankserv::Credit
|
16
|
+
end
|
17
|
+
|
18
|
+
def rec_id
|
19
|
+
'020'
|
20
|
+
end
|
21
|
+
|
22
|
+
def standard_bankserv_record_identifier
|
23
|
+
"10"
|
24
|
+
end
|
25
|
+
|
26
|
+
def standard_entry_class
|
27
|
+
"88"
|
28
|
+
end
|
29
|
+
|
30
|
+
def contra_bankserv_record_identifier
|
31
|
+
"12"
|
32
|
+
end
|
33
|
+
|
34
|
+
def debit_records
|
35
|
+
contra_records
|
36
|
+
end
|
37
|
+
|
38
|
+
def credit_records
|
39
|
+
standard_records
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Bankserv
|
2
|
+
module Transmission::UserSet
|
3
|
+
|
4
|
+
class Debit < Eft
|
5
|
+
|
6
|
+
before_save :decorate_records, :decorate_header, :decorate_trailer
|
7
|
+
|
8
|
+
attr_accessor :type_of_service, :account_type_correct, :accepted_report
|
9
|
+
|
10
|
+
def self.class_type
|
11
|
+
Bankserv::Debit
|
12
|
+
end
|
13
|
+
|
14
|
+
def class_type
|
15
|
+
Bankserv::Debit
|
16
|
+
end
|
17
|
+
|
18
|
+
def rec_id
|
19
|
+
'001'
|
20
|
+
end
|
21
|
+
|
22
|
+
def standard_bankserv_record_identifier
|
23
|
+
"50"
|
24
|
+
end
|
25
|
+
|
26
|
+
def standard_entry_class
|
27
|
+
"44"
|
28
|
+
end
|
29
|
+
|
30
|
+
def contra_bankserv_record_identifier
|
31
|
+
"52"
|
32
|
+
end
|
33
|
+
|
34
|
+
def debit_records
|
35
|
+
standard_records
|
36
|
+
end
|
37
|
+
|
38
|
+
def credit_records
|
39
|
+
contra_records
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Bankserv
|
2
|
+
module Transmission
|
3
|
+
module UserSet
|
4
|
+
|
5
|
+
class Document < Set
|
6
|
+
|
7
|
+
before_save :decorate_records
|
8
|
+
|
9
|
+
def self.generate(options)
|
10
|
+
set = self.new
|
11
|
+
set.build_header(options)
|
12
|
+
set.build_trailer(no_of_recs: options[:no_of_recs])
|
13
|
+
set
|
14
|
+
end
|
15
|
+
|
16
|
+
def build_header(options = {})
|
17
|
+
defaults = {
|
18
|
+
client_code: Bankserv::Configuration.active.client_code,
|
19
|
+
client_name: Bankserv::Configuration.active.client_name,
|
20
|
+
date: Date.today.strftime("%Y%m%d"),
|
21
|
+
destination: "0"
|
22
|
+
}
|
23
|
+
|
24
|
+
records.build(record_type: "header", data: defaults.merge(options))
|
25
|
+
end
|
26
|
+
|
27
|
+
def build_trailer(options = {})
|
28
|
+
options[:no_of_recs] = options[:no_of_recs].to_s
|
29
|
+
records.build(record_type: "trailer", data: options)
|
30
|
+
end
|
31
|
+
|
32
|
+
def decorate_records
|
33
|
+
super
|
34
|
+
set_trailer_number_of_records
|
35
|
+
end
|
36
|
+
|
37
|
+
def set_trailer_number_of_records
|
38
|
+
trailer.data.merge!(no_of_recs: number_of_records.to_s)
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,228 @@
|
|
1
|
+
module Bankserv
|
2
|
+
module Transmission::UserSet
|
3
|
+
|
4
|
+
class Eft < Set
|
5
|
+
|
6
|
+
before_save :decorate_records, :decorate_header, :decorate_trailer
|
7
|
+
|
8
|
+
attr_accessor :type_of_service, :account_type_correct, :accepted_report
|
9
|
+
|
10
|
+
def self.has_work?
|
11
|
+
class_type.has_work?
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.has_test_work?
|
15
|
+
class_type.has_test_work?
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.unprocessed_efts(rec_status)
|
19
|
+
if rec_status == "L"
|
20
|
+
self.class_type.unprocessed.select{|item| not item.request.test?}
|
21
|
+
else
|
22
|
+
self.class_type.unprocessed.select{|item| item.request.test?}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.generate(options = {})
|
27
|
+
efts = self.unprocessed_efts(options[:rec_status])
|
28
|
+
|
29
|
+
if efts.count > 0
|
30
|
+
set = self.new
|
31
|
+
set.type_of_service = efts.first.request.data[:type_of_service]
|
32
|
+
set.accepted_report = efts.first.request.data[:accepted_report] || ""
|
33
|
+
set.account_type_correct = efts.first.request.data[:account_type_correct] || ""
|
34
|
+
set.build_header
|
35
|
+
set.build_batches(options[:rec_status])
|
36
|
+
set.build_trailer
|
37
|
+
set
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def set_type
|
42
|
+
"eft"
|
43
|
+
end
|
44
|
+
|
45
|
+
def short_date(date)
|
46
|
+
date = Date.strptime(date, "%Y-%m-%d")
|
47
|
+
date.strftime("%y%m%d")
|
48
|
+
end
|
49
|
+
|
50
|
+
def last_sequence_number_today
|
51
|
+
last = Record.where("date(created_at) = ? AND record_type = 'standard_record'", Date.today).last
|
52
|
+
last.nil? ? 0 : last.data[:user_sequence_number].to_i
|
53
|
+
end
|
54
|
+
|
55
|
+
def user_sequence_number
|
56
|
+
(last_sequence_number_today + transactions.count + 1).to_s
|
57
|
+
end
|
58
|
+
|
59
|
+
def contra_records
|
60
|
+
records.where(record_type: "contra_record")
|
61
|
+
end
|
62
|
+
|
63
|
+
def standard_records
|
64
|
+
records.where(record_type: "standard_record")
|
65
|
+
end
|
66
|
+
|
67
|
+
def get_user_generation_number
|
68
|
+
Bankserv::Configuration.reserve_user_generation_number!.to_s #Equal to the last accepted user gen number + 1
|
69
|
+
end
|
70
|
+
|
71
|
+
def build_header(options = {})
|
72
|
+
self.generation_number = options[:user_generation_number] || get_user_generation_number
|
73
|
+
record_data = Absa::H2h::Transmission::Eft.record_type('header').template_options
|
74
|
+
|
75
|
+
record_data.merge!(
|
76
|
+
rec_id: rec_id,
|
77
|
+
bankserv_creation_date: Time.now.strftime("%y%m%d"),
|
78
|
+
first_sequence_number: (last_sequence_number_today + 1).to_s,
|
79
|
+
user_generation_number: generation_number,
|
80
|
+
type_of_service: @type_of_service,
|
81
|
+
accepted_report: @accepted_report.nil? ? "" : @accepted_report,
|
82
|
+
account_type_correct: @account_type_correct
|
83
|
+
)
|
84
|
+
|
85
|
+
records.build(record_type: "header", data: record_data)
|
86
|
+
end
|
87
|
+
|
88
|
+
def build_trailer(options = {})
|
89
|
+
record_data = Absa::H2h::Transmission::Eft.record_type('trailer').template_options
|
90
|
+
records.build(record_type: "trailer", data: record_data.merge(rec_id: rec_id))
|
91
|
+
end
|
92
|
+
|
93
|
+
def build_batches(rec_status)
|
94
|
+
efts = self.class.unprocessed_efts(rec_status)
|
95
|
+
|
96
|
+
efts.group_by(&:batch_id).each do |batch_id, eft|
|
97
|
+
eft.select(&:standard?).each{|t| build_standard t}
|
98
|
+
eft.select(&:contra?).each{|t| build_contra t}
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def build_standard(transaction)
|
103
|
+
record_data = Absa::H2h::Transmission::Eft.record_type('standard_record').template_options
|
104
|
+
homing_account_number = transaction.bank_account.account_number.to_i.to_s
|
105
|
+
homing_branch_code = transaction.bank_account.branch_code.to_i.to_s
|
106
|
+
|
107
|
+
record_data.merge!(
|
108
|
+
rec_id: rec_id,
|
109
|
+
user_sequence_number: user_sequence_number,
|
110
|
+
user_nominated_account: transaction.contra_bank_details.account_number,
|
111
|
+
user_branch: transaction.contra_bank_details.branch_code,
|
112
|
+
user_code: Bankserv::Configuration.active.user_code,
|
113
|
+
bankserv_record_identifier: standard_bankserv_record_identifier,
|
114
|
+
homing_branch: homing_branch_code,
|
115
|
+
homing_account_number: homing_account_number.length <= 11 ? homing_account_number : "0",
|
116
|
+
type_of_account: transaction.bank_account.account_type_id,
|
117
|
+
amount: transaction.amount_in_cents.to_s,
|
118
|
+
action_date: short_date(transaction.action_date),
|
119
|
+
entry_class: standard_entry_class,
|
120
|
+
tax_code: "0",
|
121
|
+
user_ref: transaction.formatted_user_ref,
|
122
|
+
homing_account_name: transaction.bank_account.account_name,
|
123
|
+
non_standard_homing_account_number: homing_account_number.length > 11 ? homing_account_number : "0"
|
124
|
+
)
|
125
|
+
|
126
|
+
records.build(record_type: transaction.record_type + "_record", data: record_data)
|
127
|
+
end
|
128
|
+
|
129
|
+
def build_contra(transaction)
|
130
|
+
record_data = Absa::H2h::Transmission::Eft.record_type('contra_record').template_options
|
131
|
+
|
132
|
+
record_data.merge!(
|
133
|
+
rec_id: rec_id,
|
134
|
+
user_sequence_number: user_sequence_number,
|
135
|
+
bankserv_record_identifier: contra_bankserv_record_identifier,
|
136
|
+
user_branch: transaction.bank_account.branch_code,
|
137
|
+
user_nominated_account: transaction.bank_account.account_number.to_i.to_s,
|
138
|
+
user_code: Bankserv::Configuration.active.user_code,
|
139
|
+
homing_branch: transaction.bank_account.branch_code,
|
140
|
+
homing_account_number: transaction.bank_account.account_number,
|
141
|
+
type_of_account: "1",
|
142
|
+
amount: transaction.amount_in_cents.to_s,
|
143
|
+
action_date: short_date(transaction.action_date),
|
144
|
+
entry_class: "10",
|
145
|
+
user_ref: transaction.formatted_user_ref
|
146
|
+
)
|
147
|
+
|
148
|
+
records.build(record_type: transaction.record_type + "_record", data: record_data)
|
149
|
+
end
|
150
|
+
|
151
|
+
def first_action_date
|
152
|
+
fad = Date.today
|
153
|
+
transactions.map(&:data).each do |hash|
|
154
|
+
first = Date.strptime(hash[:action_date], "%y%m%d")
|
155
|
+
fad = first if first < fad
|
156
|
+
end
|
157
|
+
fad.strftime("%y%m%d")
|
158
|
+
end
|
159
|
+
|
160
|
+
def last_action_date
|
161
|
+
lad = Date.today
|
162
|
+
transactions.map(&:data).each do |hash|
|
163
|
+
last = Date.strptime(hash[:action_date], "%y%m%d")
|
164
|
+
lad = last if last < lad
|
165
|
+
end
|
166
|
+
lad = lad + 3.days
|
167
|
+
lad.strftime("%y%m%d")
|
168
|
+
end
|
169
|
+
|
170
|
+
def purge_date
|
171
|
+
date = Date.strptime("#{self.last_action_date}", "%y%m%d") + 4.days
|
172
|
+
date.strftime("%y%m%d")
|
173
|
+
end
|
174
|
+
|
175
|
+
def hash_total_of_homing_account_numbers
|
176
|
+
hash_total = 0
|
177
|
+
|
178
|
+
transactions.each do |transaction|
|
179
|
+
hash_total += transaction.data[:homing_account_number].to_i
|
180
|
+
hash_total += transaction.data[:non_standard_homing_account_number].to_i if transaction.record_type == "standard_record"
|
181
|
+
end
|
182
|
+
|
183
|
+
hash_total.to_s.reverse[0,12].reverse.to_i
|
184
|
+
end
|
185
|
+
|
186
|
+
def total_debit_value
|
187
|
+
debit_records.inject(0) { |sum, record| sum + record.data[:amount].to_i }
|
188
|
+
end
|
189
|
+
|
190
|
+
def total_credit_value
|
191
|
+
credit_records.inject(0) { |sum, record| sum + record.data[:amount].to_i }
|
192
|
+
end
|
193
|
+
|
194
|
+
def no_debit_records
|
195
|
+
debit_records.count.to_s
|
196
|
+
end
|
197
|
+
|
198
|
+
def no_credit_records
|
199
|
+
credit_records.count.to_s
|
200
|
+
end
|
201
|
+
|
202
|
+
private
|
203
|
+
|
204
|
+
def decorate_header
|
205
|
+
header.data[:bankserv_user_code] = Bankserv::Configuration.active.user_code
|
206
|
+
header.data[:bankserv_purge_date] = purge_date
|
207
|
+
header.data[:first_action_date] = first_action_date
|
208
|
+
header.data[:last_action_date] = last_action_date
|
209
|
+
header.save!
|
210
|
+
end
|
211
|
+
|
212
|
+
def decorate_trailer
|
213
|
+
trailer.data[:bankserv_user_code] = Bankserv::Configuration.active.user_code
|
214
|
+
trailer.data[:first_sequence_number] = transactions.first.data[:user_sequence_number].to_s
|
215
|
+
trailer.data[:last_sequence_number] = transactions.last.data[:user_sequence_number].to_s
|
216
|
+
trailer.data[:first_action_date] = first_action_date
|
217
|
+
trailer.data[:last_action_date] = last_action_date
|
218
|
+
trailer.data[:no_debit_records] = no_debit_records
|
219
|
+
trailer.data[:no_credit_records] = no_credit_records
|
220
|
+
trailer.data[:no_contra_records] = records.where(record_type: "contra_record").count.to_s
|
221
|
+
trailer.data[:total_debit_value] = total_debit_value.to_s
|
222
|
+
trailer.data[:total_credit_value] = total_debit_value.to_s
|
223
|
+
trailer.data[:hash_total_of_homing_account_numbers] = hash_total_of_homing_account_numbers.to_s
|
224
|
+
trailer.save!
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|