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 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 = DCAS::Client.new(:username => 'angola', :password => '4ng014', :cache_location => './EFT')
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
1
+ 0.2.0
data/dcas-ruby.gemspec CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{dcas-ruby}
8
- s.version = "0.1.0"
8
+ s.version = "0.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["BehindLogic"]
data/lib/dcas/payment.rb CHANGED
@@ -25,6 +25,10 @@ module DCAS
25
25
  payments.first.class.name.gsub(/.*::/,'').downcase
26
26
  end
27
27
 
28
+ def filename
29
+ "#{@client.company_user}_#{type}.csv"
30
+ end
31
+
28
32
  # Generates a payment batch file and returns its contents.
29
33
  def to_csv
30
34
  FasterCSV.generate do |csv|
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, :company_password, and :cache_location" if [:username, :password, :company_alias, :company_username, :company_password, :cache_location].any? {|k| !options.has_key?(k)}
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, :cache_location
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
- def submit_payments_file!(filename)
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
- with_ftp do |ftp|
45
- # 1) Create the STAGING folder if it's not already there.
46
- ftp.mkdir(DCAS::STAGING_BUCKET) unless ftp.nlst.include?(DCAS::STAGING_BUCKET)
47
- ftp.chdir(DCAS::STAGING_BUCKET)
48
- # 2) Delete the same filename from the STAGING folder if one exists.
49
- ftp.delete(shortname) if ftp.nlst.include?(shortname)
50
- # 3) Upload the file into the STAGING folder.
51
- ftp.put(filename, shortname)
52
- # 4) If we're still connected, check the file size of the file, then move it out of STAGING and mark file as completed.
53
- if ftp.nlst.include?(shortname) && ftp.size(shortname) == File.size(filename)
54
- ftp.rename(shortname, "../#{DCAS::OUTGOING_BUCKET}/#{shortname}") unless DCAS::TESTING
55
- else
56
- raise RuntimeError, "FAILED uploading `#{filename}' - incomplete or unsuccessful upload. Please try again."
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
- def submit_batches!
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
- filename = cache_location + "/#{company_user}_#{batch.type}_#{Time.now.strftime("%Y%m%d")}.csv"
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(1)
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(1)
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(1)
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(1)
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
- - '00111428'
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
- - '00111200'
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
- - '00111829'
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
- - '00111282'
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
- - '00111795'
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
- - '00111537'
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
- - '00111892'
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
- - '00111172'
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
- - '00111284'
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
- - '00111756'
75
+ - '11756'
76
76
  - 'Polly Clark'
77
77
  - '18.88'
78
78
  - 'Checking'
@@ -1,69 +1,69 @@
1
1
  ---
2
2
  -
3
- - '00111532'
3
+ - '11532'
4
4
  - 'Kipp Owen'
5
5
  - '18.88'
6
6
  - 'VISA'
7
7
  - '4508288028044788'
8
8
  - '12/2010'
9
9
  -
10
- - '00111382'
10
+ - '11382'
11
11
  - 'Brooke Racquet'
12
12
  - '18.88'
13
13
  - 'VISA'
14
14
  - '4979170284809229'
15
15
  - '12/2011'
16
16
  -
17
- - '00111018'
17
+ - '11018'
18
18
  - 'Pat Sylvester'
19
19
  - '18.88'
20
20
  - 'MCRD'
21
21
  - '5280827180294022'
22
22
  - '12/2012'
23
23
  -
24
- - '00111992'
24
+ - '11992'
25
25
  - 'Vicki Tolliki'
26
26
  - '18.88'
27
27
  - 'MCRD'
28
28
  - '5173179138280429'
29
29
  - '12/2011'
30
30
  -
31
- - '00111247'
31
+ - '11247'
32
32
  - 'Cheryl Barger'
33
33
  - '18.88'
34
34
  - 'VISA'
35
35
  - '4247972792081828'
36
36
  - '12/2010'
37
37
  -
38
- - '00111028'
38
+ - '11028'
39
39
  - 'Melissa Fletcher'
40
40
  - '18.88'
41
41
  - 'MCRD'
42
42
  - '5428208180420824'
43
43
  - '12/2011'
44
44
  -
45
- - '00111384'
45
+ - '11384'
46
46
  - 'Mack Payne'
47
47
  - '18.88'
48
48
  - 'MCRD'
49
49
  - '5425682492949922'
50
50
  - '12/2012'
51
51
  -
52
- - '00111742'
52
+ - '11742'
53
53
  - 'Melissa Latcher'
54
54
  - '18.88'
55
55
  - 'MCRD'
56
56
  - '5208372629781292'
57
57
  - '12/2011'
58
58
  -
59
- - '00111402'
59
+ - '11402'
60
60
  - 'Caroline Sieben'
61
61
  - '18.88'
62
62
  - 'MCRD'
63
63
  - '5181381081538389'
64
64
  - '12/2012'
65
65
  -
66
- - '00111208'
66
+ - '11208'
67
67
  - 'Charlotte Sue Hiran'
68
68
  - '18.88'
69
69
  - 'MCRD'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dcas-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - BehindLogic