dcas-ruby 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/API.rdoc +8 -1
- data/VERSION +1 -1
- data/dcas-ruby.gemspec +1 -1
- data/lib/dcas/payment.rb +4 -0
- data/lib/dcas.rb +66 -29
- data/spec/dcas_spec.rb +4 -4
- data/spec/fixtures/ach_payments.yml +10 -10
- data/spec/fixtures/credit_card_payments.yml +10 -10
- metadata +1 -1
data/API.rdoc
CHANGED
@@ -7,7 +7,14 @@
|
|
7
7
|
* Parse response files
|
8
8
|
|
9
9
|
=== First you must set up the login info and a cache location
|
10
|
-
angola =
|
10
|
+
angola = DCAS::Client.new(
|
11
|
+
:username => 'angola',
|
12
|
+
:password => '4ng014',
|
13
|
+
:company_alias => 'angolaHQ',
|
14
|
+
:company_username => 'angolatw',
|
15
|
+
:company_password => 'secret',
|
16
|
+
:cache_location => './PaymentFileStore'
|
17
|
+
)
|
11
18
|
|
12
19
|
=== Create a Payment Batch
|
13
20
|
ach_payments = angola.new_batch(batch_id)
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/dcas-ruby.gemspec
CHANGED
data/lib/dcas/payment.rb
CHANGED
data/lib/dcas.rb
CHANGED
@@ -6,6 +6,7 @@ module DCAS
|
|
6
6
|
OUTGOING_BUCKET = 'outgoing'
|
7
7
|
INCOMING_BUCKET = 'incoming'
|
8
8
|
STAGING_BUCKET = 'staging'
|
9
|
+
DEFAULT_CACHE_LOCATION = 'EFT'
|
9
10
|
|
10
11
|
class << self
|
11
12
|
# Parses the responses from a response file and returns an array of DCAS::Response objects.
|
@@ -16,16 +17,17 @@ module DCAS
|
|
16
17
|
class Client
|
17
18
|
# Instantiate a new Client object which can do authenticated actions in a DCAS FTPS bucket.
|
18
19
|
def initialize(options={})
|
19
|
-
raise ArgumentError, "must include :username, :password, :company_alias, :company_username,
|
20
|
-
@username = options[:username]
|
21
|
-
@password = options[:password]
|
22
|
-
@company_alias = options[:company_alias]
|
23
|
-
@company_username = options[:company_username]
|
24
|
-
@company_password = options[:company_password]
|
25
|
-
@cache_location = options[:cache_location]
|
20
|
+
raise ArgumentError, "must include :username, :password, :company_alias, :company_username, and :company_password" if [:username, :password, :company_alias, :company_username, :company_password].any? {|k| options[k].to_s.length == 0}
|
21
|
+
@username = options[:username].to_s
|
22
|
+
@password = options[:password].to_s
|
23
|
+
@company_alias = options[:company_alias].to_s
|
24
|
+
@company_username = options[:company_username].to_s
|
25
|
+
@company_password = options[:company_password].to_s
|
26
|
+
@cache_location = options[:cache_location].to_s || DEFAULT_CACHE_LOCATION
|
26
27
|
end
|
27
28
|
|
28
|
-
attr_reader :username, :password, :company_alias, :company_username, :company_password
|
29
|
+
attr_reader :username, :password, :company_alias, :company_username, :company_password
|
30
|
+
attr_accessor :cache_location
|
29
31
|
|
30
32
|
# :nodoc:
|
31
33
|
def batches
|
@@ -39,40 +41,75 @@ module DCAS
|
|
39
41
|
end
|
40
42
|
|
41
43
|
# Uploads a single payments file to the DCAS outgoing payments bucket.
|
42
|
-
|
44
|
+
# You can optionally supply a 'lock' object, which must respond to:
|
45
|
+
# #submit_locked?(filename)
|
46
|
+
# #submit_lock!(filename)
|
47
|
+
# #submit_finished!(filename)
|
48
|
+
# #submit_failed!(filename)
|
49
|
+
# If a lock_object is supplied, the method will mark it as failed and return false instead of raising an error, in case of failure.
|
50
|
+
def submit_payments_file!(filename, lock_object=nil)
|
43
51
|
shortname = filename.gsub(/.*[\\\/][^\\\/]+$/,'')
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
52
|
+
if lock_object && lock_object.submit_locked?(shortname)
|
53
|
+
raise RuntimeError, "Submit for #{shortname} is locked!"
|
54
|
+
else
|
55
|
+
lock_object.submit_lock!(shortname) if lock_object
|
56
|
+
with_ftp do |ftp|
|
57
|
+
# 1) Create the STAGING folder if it's not already there.
|
58
|
+
ftp.mkdir(DCAS::STAGING_BUCKET) unless ftp.nlst.include?(DCAS::STAGING_BUCKET)
|
59
|
+
ftp.chdir(DCAS::STAGING_BUCKET)
|
60
|
+
# 2) Delete the same filename from the STAGING folder if one exists.
|
61
|
+
ftp.delete(shortname) if ftp.nlst.include?(shortname)
|
62
|
+
# 3) Upload the file into the STAGING folder.
|
63
|
+
ftp.put(filename, shortname)
|
64
|
+
# 4) If we're still connected, check the file size of the file, then move it out of STAGING and mark file as completed.
|
65
|
+
if ftp.nlst.include?(shortname) && ftp.size(shortname) == File.size(filename)
|
66
|
+
ftp.rename(shortname, "../#{DCAS::OUTGOING_BUCKET}/#{shortname}") unless DCAS::TESTING
|
67
|
+
lock_object.submit_finished!(shortname) if lock_object
|
68
|
+
else
|
69
|
+
if lock_object
|
70
|
+
lock_object.submit_failed!(shortname)
|
71
|
+
return false
|
72
|
+
else
|
73
|
+
raise RuntimeError, "FAILED uploading `#{filename}' - incomplete or unsuccessful upload. Please try again."
|
74
|
+
end
|
75
|
+
end
|
57
76
|
end
|
58
77
|
end
|
59
78
|
true
|
60
79
|
end
|
61
80
|
|
81
|
+
# Writes one batch to file and submits it to the DCAS outgoing payments bucket.
|
82
|
+
# You can optionally supply a 'lock' object, which must respond to:
|
83
|
+
# #submit_locked?
|
84
|
+
# #submit_lock!(filename)
|
85
|
+
# #submit_finished!(filename)
|
86
|
+
# #submit_failed!(filename)
|
87
|
+
# If a lock_object is supplied, the method will mark it as failed and return false instead of raising an error, in case of failure.
|
88
|
+
def submit_batch!(batch, lock_object=nil)
|
89
|
+
File.makedirs(cache_location)
|
90
|
+
filename = cache_location + "/" + batch.filename
|
91
|
+
# 1) Create the file locally.
|
92
|
+
File.open(filename) {|f| f << batch.to_csv }
|
93
|
+
# 2) Upload it to the DCAS outgoing payments bucket.
|
94
|
+
submit_payments_file!(filename, lock_object)
|
95
|
+
end
|
96
|
+
|
62
97
|
# Writes all batches to file and submits them to the DCAS outgoing payments bucket.
|
63
|
-
|
98
|
+
# You can optionally supply a 'lock' object, which must respond to:
|
99
|
+
# #submit_locked?
|
100
|
+
# #submit_lock!(filename)
|
101
|
+
# #submit_finished!(filename)
|
102
|
+
# #submit_failed!(filename)
|
103
|
+
def submit_batches!(lock_object=nil)
|
64
104
|
File.makedirs(cache_location)
|
65
105
|
batches_submitted = 0
|
66
|
-
with_ftp do
|
106
|
+
with_ftp do # causes all batches to be uploaded in a single session
|
67
107
|
# 1) Gather all payments for this client.
|
68
108
|
batches.each do |batch| # 2) For each file type (ach, cc) yet to be uploaded:
|
69
|
-
|
70
|
-
# 1) Create the file locally.
|
71
|
-
File.open(filename) {|f| f << batch.to_csv }
|
72
|
-
# 2) Upload it to the DCAS outgoing payments bucket.
|
73
|
-
batches_submitted += 1 if submit_payments_file!(filename)
|
109
|
+
batches_submitted += 1 if submit_batch!(batch, lock_object)
|
74
110
|
end
|
75
111
|
end
|
112
|
+
batches_submitted
|
76
113
|
end
|
77
114
|
|
78
115
|
# Checks for response files in the DCAS incoming responses bucket.
|
data/spec/dcas_spec.rb
CHANGED
@@ -14,14 +14,14 @@ describe "Dcas - Comprehensive failure frequency test" do
|
|
14
14
|
end
|
15
15
|
|
16
16
|
it "should generate Ach payment files correctly" do
|
17
|
-
ach_batch = @fake_client.new_batch(
|
17
|
+
ach_batch = @fake_client.new_batch('1001')
|
18
18
|
Fixtures[:TestPayments][:Ach].collect {|p| ach_batch << DCAS::AchPayment.new(*p) }
|
19
19
|
ach_payments_file = ach_batch.to_csv
|
20
20
|
ach_payments_file.should eql(File.read('spec/fixtures/ach_payments.csv'))
|
21
21
|
end
|
22
22
|
|
23
23
|
it "should generate CreditCard payment files correctly" do
|
24
|
-
cc_batch = @fake_client.new_batch(
|
24
|
+
cc_batch = @fake_client.new_batch('1001')
|
25
25
|
Fixtures[:TestPayments][:CreditCard].collect {|p| cc_batch << DCAS::CreditCardPayment.new(*p) }
|
26
26
|
cc_payments_file = cc_batch.to_csv
|
27
27
|
cc_payments_file.should eql(File.read('spec/fixtures/credit_card_payments.csv'))
|
@@ -32,10 +32,10 @@ describe "Dcas - Comprehensive failure frequency test" do
|
|
32
32
|
# Depends: Fixture load of a list of DCAS logins to test
|
33
33
|
# Depends: Fixed test files
|
34
34
|
Fixtures[:Clients].each do |client|
|
35
|
-
cc_batch = client.new_batch(
|
35
|
+
cc_batch = client.new_batch('123')
|
36
36
|
Fixtures[:TestPayments][:CreditCard].each {|p| cc_batch << DCAS::CreditCardPayment.new(*p) }
|
37
37
|
|
38
|
-
ach_batch = client.new_batch(
|
38
|
+
ach_batch = client.new_batch('123')
|
39
39
|
Fixtures[:TestPayments][:Ach].each {|p| ach_batch << DCAS::AchPayment.new(*p) }
|
40
40
|
|
41
41
|
client.submit_batches!.should eql(Fixtures[:PaymentFiles].length)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
---
|
2
2
|
-
|
3
|
-
- '
|
3
|
+
- '11428'
|
4
4
|
- 'Dan Hall'
|
5
5
|
- '18.88'
|
6
6
|
- 'Checking'
|
@@ -8,7 +8,7 @@
|
|
8
8
|
- '182045828'
|
9
9
|
- '2010010'
|
10
10
|
-
|
11
|
-
- '
|
11
|
+
- '11200'
|
12
12
|
- 'Karie Moore'
|
13
13
|
- '18.88'
|
14
14
|
- 'Checking'
|
@@ -16,7 +16,7 @@
|
|
16
16
|
- '584218548'
|
17
17
|
- '2010010'
|
18
18
|
-
|
19
|
-
- '
|
19
|
+
- '11829'
|
20
20
|
- 'Therese Boon'
|
21
21
|
- '18.88'
|
22
22
|
- 'Checking'
|
@@ -24,7 +24,7 @@
|
|
24
24
|
- '94217885428'
|
25
25
|
- '2010010'
|
26
26
|
-
|
27
|
-
- '
|
27
|
+
- '11282'
|
28
28
|
- 'Gretchen Gutierrez'
|
29
29
|
- '18.88'
|
30
30
|
- 'Savings'
|
@@ -32,7 +32,7 @@
|
|
32
32
|
- '24254'
|
33
33
|
- '2010010'
|
34
34
|
-
|
35
|
-
- '
|
35
|
+
- '11795'
|
36
36
|
- 'Audrice Pitto'
|
37
37
|
- '18.88'
|
38
38
|
- 'Checking'
|
@@ -40,7 +40,7 @@
|
|
40
40
|
- '280458548254'
|
41
41
|
- '2010010'
|
42
42
|
-
|
43
|
-
- '
|
43
|
+
- '11537'
|
44
44
|
- 'Rachel Ruppert'
|
45
45
|
- '18.88'
|
46
46
|
- 'Checking'
|
@@ -48,7 +48,7 @@
|
|
48
48
|
- '641081508245'
|
49
49
|
- '2010010'
|
50
50
|
-
|
51
|
-
- '
|
51
|
+
- '11892'
|
52
52
|
- 'Judith Witlock'
|
53
53
|
- '18.88'
|
54
54
|
- 'Checking'
|
@@ -56,7 +56,7 @@
|
|
56
56
|
- '52488542858'
|
57
57
|
- '2010010'
|
58
58
|
-
|
59
|
-
- '
|
59
|
+
- '11172'
|
60
60
|
- 'Kris Martell'
|
61
61
|
- '18.88'
|
62
62
|
- 'Savings'
|
@@ -64,7 +64,7 @@
|
|
64
64
|
- '4728458248'
|
65
65
|
- '2010010'
|
66
66
|
-
|
67
|
-
- '
|
67
|
+
- '11284'
|
68
68
|
- 'Michell Penderson'
|
69
69
|
- '18.88'
|
70
70
|
- 'Checking'
|
@@ -72,7 +72,7 @@
|
|
72
72
|
- '38184599459'
|
73
73
|
- '2010010'
|
74
74
|
-
|
75
|
-
- '
|
75
|
+
- '11756'
|
76
76
|
- 'Polly Clark'
|
77
77
|
- '18.88'
|
78
78
|
- 'Checking'
|
@@ -1,69 +1,69 @@
|
|
1
1
|
---
|
2
2
|
-
|
3
|
-
- '
|
3
|
+
- '11532'
|
4
4
|
- 'Kipp Owen'
|
5
5
|
- '18.88'
|
6
6
|
- 'VISA'
|
7
7
|
- '4508288028044788'
|
8
8
|
- '12/2010'
|
9
9
|
-
|
10
|
-
- '
|
10
|
+
- '11382'
|
11
11
|
- 'Brooke Racquet'
|
12
12
|
- '18.88'
|
13
13
|
- 'VISA'
|
14
14
|
- '4979170284809229'
|
15
15
|
- '12/2011'
|
16
16
|
-
|
17
|
-
- '
|
17
|
+
- '11018'
|
18
18
|
- 'Pat Sylvester'
|
19
19
|
- '18.88'
|
20
20
|
- 'MCRD'
|
21
21
|
- '5280827180294022'
|
22
22
|
- '12/2012'
|
23
23
|
-
|
24
|
-
- '
|
24
|
+
- '11992'
|
25
25
|
- 'Vicki Tolliki'
|
26
26
|
- '18.88'
|
27
27
|
- 'MCRD'
|
28
28
|
- '5173179138280429'
|
29
29
|
- '12/2011'
|
30
30
|
-
|
31
|
-
- '
|
31
|
+
- '11247'
|
32
32
|
- 'Cheryl Barger'
|
33
33
|
- '18.88'
|
34
34
|
- 'VISA'
|
35
35
|
- '4247972792081828'
|
36
36
|
- '12/2010'
|
37
37
|
-
|
38
|
-
- '
|
38
|
+
- '11028'
|
39
39
|
- 'Melissa Fletcher'
|
40
40
|
- '18.88'
|
41
41
|
- 'MCRD'
|
42
42
|
- '5428208180420824'
|
43
43
|
- '12/2011'
|
44
44
|
-
|
45
|
-
- '
|
45
|
+
- '11384'
|
46
46
|
- 'Mack Payne'
|
47
47
|
- '18.88'
|
48
48
|
- 'MCRD'
|
49
49
|
- '5425682492949922'
|
50
50
|
- '12/2012'
|
51
51
|
-
|
52
|
-
- '
|
52
|
+
- '11742'
|
53
53
|
- 'Melissa Latcher'
|
54
54
|
- '18.88'
|
55
55
|
- 'MCRD'
|
56
56
|
- '5208372629781292'
|
57
57
|
- '12/2011'
|
58
58
|
-
|
59
|
-
- '
|
59
|
+
- '11402'
|
60
60
|
- 'Caroline Sieben'
|
61
61
|
- '18.88'
|
62
62
|
- 'MCRD'
|
63
63
|
- '5181381081538389'
|
64
64
|
- '12/2012'
|
65
65
|
-
|
66
|
-
- '
|
66
|
+
- '11208'
|
67
67
|
- 'Charlotte Sue Hiran'
|
68
68
|
- '18.88'
|
69
69
|
- 'MCRD'
|