docu_sign 0.0.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.
Files changed (91) hide show
  1. data/.document +5 -0
  2. data/.gitignore +7 -0
  3. data/.rspec +1 -0
  4. data/Gemfile +6 -0
  5. data/LICENSE.txt +20 -0
  6. data/README.rdoc +20 -0
  7. data/Rakefile +1 -0
  8. data/docu_sign.example.yml +4 -0
  9. data/docu_sign.gemspec +36 -0
  10. data/lib/docu_sign/anchor_tab.rb +29 -0
  11. data/lib/docu_sign/authentication_status.rb +16 -0
  12. data/lib/docu_sign/builder/anchor_builder.rb +17 -0
  13. data/lib/docu_sign/builder/base.rb +27 -0
  14. data/lib/docu_sign/builder/document_builder.rb +16 -0
  15. data/lib/docu_sign/builder/notification_builder.rb +16 -0
  16. data/lib/docu_sign/builder/recipient_builder.rb +17 -0
  17. data/lib/docu_sign/builder/tab_builder.rb +30 -0
  18. data/lib/docu_sign/cacert.pem +3390 -0
  19. data/lib/docu_sign/client.rb +98 -0
  20. data/lib/docu_sign/docu_sign_model.rb +23 -0
  21. data/lib/docu_sign/docu_sign_response.rb +33 -0
  22. data/lib/docu_sign/document.rb +57 -0
  23. data/lib/docu_sign/document_pdf.rb +14 -0
  24. data/lib/docu_sign/document_status.rb +15 -0
  25. data/lib/docu_sign/envelope.rb +136 -0
  26. data/lib/docu_sign/envelope_status.rb +33 -0
  27. data/lib/docu_sign/error.rb +7 -0
  28. data/lib/docu_sign/extensions.rb +81 -0
  29. data/lib/docu_sign/notification.rb +21 -0
  30. data/lib/docu_sign/railtie.rb +7 -0
  31. data/lib/docu_sign/recipient.rb +61 -0
  32. data/lib/docu_sign/recipient_status.rb +25 -0
  33. data/lib/docu_sign/tab.rb +96 -0
  34. data/lib/docu_sign/tab_status.rb +17 -0
  35. data/lib/docu_sign/version.rb +3 -0
  36. data/lib/docu_sign/void_envelope_status.rb +14 -0
  37. data/lib/docu_sign.rb +37 -0
  38. data/spec/docu_sign/client_spec.rb +8 -0
  39. data/spec/docu_sign/document_spec.rb +51 -0
  40. data/spec/docu_sign/envelope_spec.rb +132 -0
  41. data/spec/docu_sign/post_processing_spec.rb +85 -0
  42. data/spec/docu_sign/sending_spec.rb +96 -0
  43. data/spec/docu_sign/status_spec.rb +146 -0
  44. data/spec/docu_sign/tab_spec.rb +32 -0
  45. data/spec/docu_sign.yml.example +4 -0
  46. data/spec/docu_sign_spec.rb +28 -0
  47. data/spec/dummy/Rakefile +7 -0
  48. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  49. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  50. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  51. data/spec/dummy/config/application.rb +45 -0
  52. data/spec/dummy/config/boot.rb +10 -0
  53. data/spec/dummy/config/database.yml +22 -0
  54. data/spec/dummy/config/environment.rb +5 -0
  55. data/spec/dummy/config/environments/development.rb +26 -0
  56. data/spec/dummy/config/environments/production.rb +49 -0
  57. data/spec/dummy/config/environments/test.rb +35 -0
  58. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  59. data/spec/dummy/config/initializers/inflections.rb +10 -0
  60. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  61. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  62. data/spec/dummy/config/initializers/session_store.rb +8 -0
  63. data/spec/dummy/config/locales/en.yml +2 -0
  64. data/spec/dummy/config/routes.rb +58 -0
  65. data/spec/dummy/config.ru +4 -0
  66. data/spec/dummy/db/test.sqlite3 +0 -0
  67. data/spec/dummy/log/development.log +0 -0
  68. data/spec/dummy/log/production.log +0 -0
  69. data/spec/dummy/log/server.log +0 -0
  70. data/spec/dummy/log/test.log +331 -0
  71. data/spec/dummy/public/404.html +26 -0
  72. data/spec/dummy/public/422.html +26 -0
  73. data/spec/dummy/public/500.html +26 -0
  74. data/spec/dummy/public/favicon.ico +0 -0
  75. data/spec/dummy/public/stylesheets/.gitkeep +0 -0
  76. data/spec/dummy/script/rails +6 -0
  77. data/spec/fixtures/document.pdf +0 -0
  78. data/spec/fixtures/vcr_cassettes/create_and_send_envelope.yml +553 -0
  79. data/spec/fixtures/vcr_cassettes/invalid_request.yml +52 -0
  80. data/spec/fixtures/vcr_cassettes/ping.yml +50 -0
  81. data/spec/fixtures/vcr_cassettes/request_document_pdfs_ex.yml +603 -0
  82. data/spec/fixtures/vcr_cassettes/request_envelope.yml +608 -0
  83. data/spec/fixtures/vcr_cassettes/request_status.yml +609 -0
  84. data/spec/fixtures/vcr_cassettes/request_status_ex.yml +614 -0
  85. data/spec/fixtures/vcr_cassettes/request_statuses.yml +1176 -0
  86. data/spec/fixtures/vcr_cassettes/void_envelope.yml +603 -0
  87. data/spec/spec_helper.rb +37 -0
  88. data/spec/support/vcr.rb +6 -0
  89. data/wsdl/dsapi.wsdl +3735 -0
  90. data/wsdl/dsapi.wsdl.old +3131 -0
  91. metadata +347 -0
@@ -0,0 +1,98 @@
1
+ module DocuSign
2
+ class Client
3
+ attr_accessor :client
4
+
5
+ # A CA file used to verify certificates when connecting to Adyen.
6
+ #
7
+ # @see http://curl.haxx.se/ca/cacert.pem
8
+ CACERT = File.expand_path('../cacert.pem', __FILE__)
9
+
10
+ class << self
11
+ def login(options={})
12
+
13
+ client = Savon::Client.new do |wsdl, http|
14
+ wsdl.document = File.expand_path("../../../wsdl/dsapi.wsdl", __FILE__)
15
+ wsdl.endpoint = options[:endpoint_url] if options[:endpoint_url]
16
+ #http.auth.ssl.ca_cert_file = CACERT
17
+ http.auth.ssl.verify_mode = :none
18
+ http.open_timeout = 1200
19
+ http.read_timeout = 1200
20
+ end
21
+
22
+
23
+
24
+ if options[:integrator_key]
25
+ client.wsse.credentials "[#{options[:integrator_key]}]#{options[:username]}", options[:password]
26
+ client.http.headers["X-DocuSign-Authentication"] = "<DocuSignCredentials><Username>#{options[:username]}</Username><Password>#{options[:password]}</Password><IntegratorKey>#{options[:integrator_key]}</IntegratorKey></DocuSignCredentials>"
27
+ end
28
+
29
+ # if options[:integrators_key]
30
+ # header = IntegratorsKeyAuthHeaderHandler.new(
31
+ # :email => options.delete(:email),
32
+ # :integrators_key => options.delete(:integrators_key),
33
+ # :password => options.delete(:password)
34
+ # )
35
+ # else
36
+ # header = AuthHeaderHandler.new(
37
+ # :user_name => options.delete(:user_name),
38
+ # :password => options.delete(:password)
39
+ # )
40
+ # end
41
+ #
42
+ # connection.headerhandler << header
43
+ #
44
+ # options.each do |key, value|
45
+ # connection.send("#{key}=", value)
46
+ # end
47
+
48
+ client
49
+ end
50
+
51
+ def credentials(email, password, endpoint_url=nil)
52
+
53
+ connection = DocuSign::Credential::CredentialSoap.new
54
+ connection.endpoint_url = endpoint_url if endpoint_url
55
+
56
+ connection.login(:email => email, :password => password).login_result
57
+ end
58
+ end
59
+
60
+ def initialize(options={})
61
+ self.client = self.class.login(options)
62
+ end
63
+
64
+ def method_missing(api_method, *args, &block) # :nodoc:
65
+ if self.client.wsdl.soap_actions.include?(api_method)
66
+ begin
67
+ response = self.client.request(api_method) do
68
+ soap.body = (args.first.respond_to?(:to_savon) ? args.first.to_savon : convert_hash_keys(args.first)) if args.first
69
+ end
70
+ return DocuSignResponse.new(response)
71
+ rescue Savon::SOAP::Fault => e
72
+ raise DocuSign::Error.new(e)
73
+ end
74
+ else
75
+ super
76
+ end
77
+ end
78
+
79
+ private
80
+
81
+ def camelize_key(k)
82
+ k.to_s.gsub(/(^|_)(id)($|_)/){ $2.upcase }.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
83
+ end
84
+
85
+ def convert_hash_keys(value)
86
+ case value
87
+ when Array
88
+ value.map { |v| convert_hash_keys(v) }
89
+ # or `value.map(&method(:convert_hash_keys))`
90
+ when Hash
91
+ Hash[value.map { |k, v| [camelize_key(k), convert_hash_keys(v)] }]
92
+ else
93
+ value
94
+ end
95
+ end
96
+
97
+ end
98
+ end
@@ -0,0 +1,23 @@
1
+ module DocuSign
2
+ class DocuSignModel
3
+ ATTRIBUTES = []
4
+
5
+ def initialize(attributes = {})
6
+ ATTRIBUTES.each do |attr|
7
+ self.send("#{attr}=", attributes[attr])
8
+ end
9
+ end
10
+
11
+ def to_savon
12
+ {}
13
+ end
14
+
15
+ def method_missing(method, *args, &block)
16
+ if method =~ /(.+)\?$/
17
+ self.send($1).nil? ? nil : (self.send($1) == true ? "true" : "false")
18
+ else
19
+ super
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,33 @@
1
+ module DocuSign
2
+
3
+ class DocuSignResponse
4
+
5
+ def self.new(*args)
6
+ response = args.first
7
+ case response.to_hash.keys.first.to_sym
8
+ when :create_and_send_envelope_response
9
+ return EnvelopeStatus.new(response.to_hash[:create_and_send_envelope_response][:create_and_send_envelope_result])
10
+ when :request_status_response
11
+ return EnvelopeStatus.new(response.to_hash[:request_status_response][:request_status_result])
12
+ when :request_status_ex_response
13
+ return EnvelopeStatus.new(response.to_hash[:request_status_ex_response][:request_status_ex_result])
14
+ when :request_statuses_response
15
+ #puts response.to_hash.inspect
16
+ return response.to_hash[:request_statuses_response][:request_statuses_result][:envelope_statuses][:envelope_status].map {|envelope_status_attributes|
17
+ EnvelopeStatus.new(envelope_status_attributes)}
18
+ when :request_envelope_response
19
+ return Envelope.new(response.to_hash[:request_envelope_response][:request_envelope_result])
20
+ when :void_envelope_response
21
+ return VoidEnvelopeStatus.new(response.to_hash[:void_envelope_response][:void_envelope_result])
22
+ when :correct_and_resend_envelope_response
23
+ return nil
24
+ when :request_document_pd_fs_ex_response
25
+ return response.to_hash[:request_document_pd_fs_ex_response][:request_document_pd_fs_ex_result][:document_pdf].map {|document_pdf_attributes| DocumentPDF.new(document_pdf_attributes)}
26
+ else
27
+ puts response.to_hash.inspect
28
+ return response
29
+ end
30
+ end
31
+ end
32
+
33
+ end
@@ -0,0 +1,57 @@
1
+ module DocuSign
2
+ class Document < DocuSignModel
3
+ ATTRIBUTES = [:tabs, :id, :name, :pdf_bytes, :password, :transform_pdf_fields, :file_extension, :match_boxes,
4
+ :attachment_description]
5
+ ATTRIBUTES.each do |attr|
6
+ self.send(:attr_accessor, attr)
7
+ end
8
+ attr_writer :tab_builder
9
+
10
+ def initialize(attributes = {})
11
+ ATTRIBUTES.each do |attr|
12
+ self.send("#{attr}=", attributes[attr])
13
+ end
14
+ end
15
+
16
+ def tabs(recipient = nil, &block)
17
+ @tabs ||= DocuSign::ArrayOfTab.new
18
+
19
+ return @tabs unless block_given?
20
+
21
+ self.tab_builder = DocuSign::Builder::TabBuilder.new(self, recipient)
22
+
23
+ @tabs.tap do |a|
24
+ yield self if block_given?
25
+ end
26
+ end
27
+
28
+ def tab(options = {}, &block)
29
+ tab_builder.build(options, &block).tap do |t|
30
+ tabs << t
31
+ end
32
+ end
33
+
34
+ def tab_builder
35
+ @tab_builder ||= DocuSign::Builder::TabBuilder.new(self)
36
+ end
37
+
38
+ def to_savon
39
+ {
40
+ "ID" => self.id,
41
+ "Name" => self.name,
42
+ "PDFBytes" => self.pdf_bytes,
43
+ "Password" => self.password,
44
+ "TransformPdfFields" => self.transform_pdf_fields,
45
+ "FileExtension" => self.file_extension,
46
+ "MatchBoxes" => self.match_boxes,
47
+ "AttachmentDescription" => self.attachment_description
48
+ }.delete_if{|key, value| value.nil?}
49
+ end
50
+ end
51
+ end
52
+
53
+ # {http://www.docusign.net/API/3.0}ArrayOfDocument
54
+ module DocuSign
55
+ class ArrayOfDocument < ::Array
56
+ end
57
+ end
@@ -0,0 +1,14 @@
1
+ module DocuSign
2
+ class DocumentPDF < DocuSignModel
3
+ ATTRIBUTES = [:name, :pdf_bytes, :document_id, :document_type]
4
+ ATTRIBUTES.each do |attr|
5
+ self.send(:attr_accessor, attr)
6
+ end
7
+
8
+ def initialize(attributes = {})
9
+ ATTRIBUTES.each do |attr|
10
+ self.send("#{attr}=", attributes[attr])
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,15 @@
1
+ module DocuSign
2
+
3
+ class DocumentStatus < DocuSignModel
4
+ ATTRIBUTES = [:id, :name, :template_name, :sequence]
5
+ ATTRIBUTES.each do |attr|
6
+ self.send(:attr_accessor, attr)
7
+ end
8
+
9
+ def initialize(attributes = {})
10
+ ATTRIBUTES.each do |attr|
11
+ self.send("#{attr}=", attributes[attr])
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,136 @@
1
+ module DocuSign
2
+ class Envelope < DocuSignModel
3
+ ATTRIBUTES = [:transaction_id, :asynchronous, :account_id, :documents, :recipients, :tabs, :subject, :email_blurb,
4
+ :signing_location, :custom_fields, :vaulting_options, :auto_navigation, :envelope_id_stamping,
5
+ :authoritative_copy, :notification, :envelope_attachment, :enforce_signer_visibility, :enable_wet_sign,
6
+ :allow_markup, :event_notification, :allow_reassign]
7
+ ATTRIBUTES.each do |attr|
8
+ self.send(:attr_accessor, attr)
9
+ end
10
+
11
+ attr_writer :document_builder
12
+ attr_writer :recipient_builder
13
+ attr_writer :tab_builder
14
+ attr_writer :notification_builder
15
+
16
+ def initialize(attributes = {})
17
+ ATTRIBUTES.each do |attr|
18
+ self.send("#{attr}=", attributes[attr])
19
+ end
20
+ end
21
+
22
+ ##
23
+ # Documents
24
+ def documents(&block)
25
+ @documents ||= DocuSign::ArrayOfDocument.new
26
+
27
+ return @documents unless block_given?
28
+
29
+ self.document_builder = DocuSign::Builder::DocumentBuilder.new()
30
+
31
+ @documents.tap do |a|
32
+ yield self if block_given?
33
+ end
34
+ end
35
+
36
+ def document(options = {}, &block)
37
+ document_builder.build(options, &block).tap do |d|
38
+ documents << d
39
+ end
40
+ end
41
+
42
+ def document_builder
43
+ @document_builder ||= DocuSign::Builder::DocumentBuilder.new()
44
+ end
45
+
46
+ ##
47
+ # Recipients
48
+ def recipients(&block)
49
+ @recipients ||= DocuSign::ArrayOfRecipient.new
50
+
51
+ return @recipients unless block_given?
52
+
53
+ self.recipient_builder = DocuSign::Builder::RecipientBuilder.new()
54
+
55
+ @recipients.tap do |r|
56
+ yield self if block_given?
57
+ end
58
+ end
59
+
60
+ def recipient(options = {}, &block)
61
+ recipient_builder.build(options, &block).tap do |r|
62
+ recipients << r
63
+ end
64
+ end
65
+
66
+ def recipient_builder
67
+ @recipient_builder ||= DocuSign::Builder::RecipientBuilder.new()
68
+ end
69
+
70
+ ##
71
+ # Tabs
72
+ def tabs(recipient = nil, &block)
73
+ @tabs ||= DocuSign::ArrayOfTab.new
74
+
75
+ return @tabs unless block_given?
76
+
77
+ self.tab_builder = DocuSign::Builder::TabBuilder.new(nil, recipient)
78
+
79
+ @tabs.tap do |a|
80
+ yield self if block_given?
81
+ end
82
+ end
83
+
84
+ def tab(options = {}, &block)
85
+ tab_builder.build(options, &block).tap do |t|
86
+ tabs << t
87
+ end
88
+ end
89
+
90
+ def tab_builder
91
+ @tab_builder ||= DocuSign::Builder::TabBuilder.new(nil)
92
+ end
93
+
94
+ def notification(options = {}, &block)
95
+ @notification ||= notification_builder.build(options, &block)
96
+ end
97
+
98
+ def notification_builder
99
+ @notification_builder ||= DocuSign::Builder::NotificationBuilder.new
100
+ end
101
+
102
+ def to_savon
103
+ {"Envelope" => {
104
+ "TransactionID" => self.transaction_id,
105
+ "Asynchronous" => self.asynchronous?,
106
+ "AccountId" => self.account_id,
107
+ "Documents" => {
108
+ "Document" => self.documents.collect(&:to_savon)
109
+ },
110
+ "Recipients" => {
111
+ "Recipient" => self.recipients.collect(&:to_savon)
112
+ },
113
+ "Tabs" => {
114
+ "Tab" => self.tabs.collect(&:to_savon)
115
+ },
116
+ "Subject" => self.subject,
117
+ "EmailBlurb" => self.email_blurb,
118
+ "SigningLocation" => self.signing_location,
119
+ # TODO: CustomFields
120
+ # TODO: VaultingOptions
121
+ "AutoNavigation" => self.auto_navigation?,
122
+ "EnvelopeIDStamping" => self.envelope_id_stamping?,
123
+ "AuthoritativeCopy" => self.authoritative_copy?,
124
+ # TODO: EnvelopeAttachment
125
+ "Notification" => self.notification.try(:to_savon),
126
+ "EnforceSignerVisibility" => self.enforce_signer_visibility?,
127
+ "EnableWetSign" => self.enable_wet_sign?,
128
+ "AllowMarkup" => self.allow_markup?,
129
+ # TODO: EventNotification
130
+ "AllowReassign" => self.allow_reassign?
131
+ }.delete_if{|key, value| value.nil?}}
132
+ end
133
+
134
+ end
135
+
136
+ end
@@ -0,0 +1,33 @@
1
+ module DocuSign
2
+ class EnvelopeStatus < DocuSignModel
3
+ ATTRIBUTES = [:recipient_statuses, :time_generated, :envelope_id, :subject, :user_name, :email, :status, :created, :deleted, :sent, :delivered, :signed, :completed, :declined, :timed_out,
4
+ :ac_status, :ac_status_date, :ac_holder, :ac_holder_email, :ac_holder_location, :signing_location, :sender_ip_address, :envelope_pdf_hash, :custom_field, :vaulting_details, :envelope_stamping,
5
+ :authoritative_copy, :envelope_attachment, :document_statuses, :form_data]
6
+ ATTRIBUTES.each do |attr|
7
+ self.send(:attr_accessor, attr)
8
+ end
9
+
10
+ def initialize(attributes = {})
11
+ ATTRIBUTES.each do |attr|
12
+ self.send("#{attr}=", attributes[attr])
13
+ end
14
+ end
15
+
16
+ def recipient_statuses=(status_attributes)
17
+ if status_attributes && status_attributes[:recipient_status].is_a?(Hash)
18
+ @recipient_statuses = [RecipientStatus.new(status_attributes[:recipient_status])]
19
+ elsif status_attributes && status_attributes[:recipient_status].is_a?(Array)
20
+ @recipient_statuses = status_attributes[:recipient_status].map{|attributes| DocuSign::RecipientStatus.new(attributes)}
21
+ end
22
+ end
23
+
24
+ def document_statuses=(status_attributes)
25
+ if status_attributes && status_attributes[:document_status].is_a?(Hash)
26
+ @document_statuses = [DocumentStatus.new(status_attributes[:document_status])]
27
+ elsif status_attributes && status_attributes[:document_status].is_a?(Array)
28
+ @document_statuses = status_attributes[:document_status].map{|attributes| DocuSign::DocumentStatus.new(attributes)}
29
+ end
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,7 @@
1
+ module DocuSign
2
+
3
+ class Error < RuntimeError
4
+
5
+ end
6
+
7
+ end
@@ -0,0 +1,81 @@
1
+ class Module
2
+ def alias_attribute(new_name, old_name)
3
+ module_eval <<-STR, __FILE__, __LINE__ + 1
4
+ def #{new_name}; self.#{old_name}; end # def subject; self.title; end
5
+ def #{new_name}?; self.#{old_name}?; end # def subject?; self.title?; end
6
+ def #{new_name}=(v); self.#{old_name} = v; end # def subject=(v); self.title = v; end
7
+ STR
8
+ end
9
+ end
10
+
11
+ # AutoCamelize
12
+ #
13
+ # This module enables a class to automatically map
14
+ # Ruby-esque snake_case method calls to the equivalent
15
+ # camelCase calls. If a method with a camelCase equivalent
16
+ # is found, we alias the snake_case method on the
17
+ # class, to avoid tripping method_missing for the same
18
+ # method in the future.
19
+ module ConstEnhancements
20
+ def const_descendants
21
+ constants.reject { |c| c == 'Enumerator' }.inject([]) do |collection, constant|
22
+ c = const_get(constant)
23
+ collection << c
24
+
25
+ if [Module, Class].include?(c.class)
26
+ collection + c.const_descendants
27
+ else
28
+ collection
29
+ end
30
+ end
31
+ end
32
+ end
33
+
34
+ [Module, Class].each do |i|
35
+ i.send :include, ConstEnhancements
36
+ end
37
+
38
+ module AutoCamelize
39
+ def method_missing(method_name, *args, &block)
40
+ ds_name = ds_equivalent(method_name)
41
+
42
+ if ds_name && respond_to?(ds_name)
43
+ self.class.class_eval %Q{
44
+ def #{method_name}(*args, &block)
45
+ send "#{ds_name}", *args, &block
46
+ end
47
+ }
48
+
49
+ send method_name, *args, &block
50
+ else
51
+ super
52
+ end
53
+ end
54
+
55
+ # Find the equivalent built-in method name, if there is one.
56
+ # Example:
57
+ # ds_equivalent('pdf_bytes') => 'pDFBytes'
58
+
59
+ def ds_equivalent(string)
60
+ string = string.to_s.camelize(:lower)
61
+ methods.find { |m| m.downcase == string.downcase }
62
+ end
63
+ end
64
+
65
+ module AutoQuery
66
+ def method_missing(method_name, *args, &block)
67
+ string_name = method_name.to_s
68
+
69
+ if (string_name =~ /\?$/) && respond_to?(string_name.gsub(/\?/, ''))
70
+ self.class.class_eval %Q{
71
+ def #{string_name}(*args, &block)
72
+ !! (send "#{string_name.gsub(/\?/, '')}", *args, &block)
73
+ end
74
+ }
75
+
76
+ send method_name, *args, &block
77
+ else
78
+ super
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,21 @@
1
+ module DocuSign
2
+ class Notification < DocuSignModel
3
+ ATTRIBUTES = [:use_account_defaults, :reminders, :expirations]
4
+ ATTRIBUTES.each do |attr|
5
+ self.send(:attr_accessor, attr)
6
+ end
7
+
8
+ def initialize(attributes = {})
9
+ ATTRIBUTES.each do |attr|
10
+ self.send("#{attr}=", attributes[attr])
11
+ end
12
+ end
13
+
14
+ def to_savon
15
+ { "UseAccountDefaults" => self.use_account_defaults?,
16
+ "Reminders" => (self.reminders.is_a?(Hash) ? {"ReminderEnabled" => self.reminders[:reminder_enabled], "ReminderDelay" => self.reminders[:reminder_delay], "ReminderFrequency" => self.reminders[:reminder_frequency]} : nil),
17
+ "Expirations" => (self.expirations.is_a?(Hash) ? {"ExpireEnabled" => self.expirations[:expire_enabled], "ExpireAfter" => self.expirations[:expire_after], "ExpireWarn" => self.expirations[:expire_warn]} : nil)
18
+ }.delete_if{|key, value| value.nil?}
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,7 @@
1
+ require 'docu_sign'
2
+ require 'rails'
3
+ module DocuSign
4
+ class Railtie < Rails::Railtie
5
+
6
+ end
7
+ end
@@ -0,0 +1,61 @@
1
+ module DocuSign
2
+ class Recipient < DocuSignModel
3
+ ATTRIBUTES = [:id, :user_name, :signer_name, :email, :type, :access_code, :add_access_code_to_email,
4
+ :require_id_lookup, :id_check_configuration_name, :live_id_recipient_authentication,
5
+ :facebook_recipient_authentication, :linkedin_recipient_authentication, :google_recipient_authentication,
6
+ :salesforce_recipient_authentication, :twitter_recipient_authentication, :yahoo_recipient_authentication,
7
+ :open_id_recipient_authentication, :phone_authentication, :signature_info, :captive_info, :custom_fields,
8
+ :routing_order, :id_check_information_input, :auto_navigation, :recipient_attachment, :note, :role_name,
9
+ :template_locked, :template_required, :template_access_code_required, :default_recipient]
10
+ ATTRIBUTES.each do |attr|
11
+ self.send(:attr_accessor, attr)
12
+ end
13
+
14
+ def initialize(attributes = {})
15
+ ATTRIBUTES.each do |attr|
16
+ self.send("#{attr}=", attributes[attr])
17
+ end
18
+ end
19
+
20
+ def to_savon
21
+ {
22
+ "ID" => self.id,
23
+ "UserName" => self.user_name,
24
+ "SignerName" => self.signer_name,
25
+ "Email" => self.email,
26
+ "Type" => self.type,
27
+ "AccessCode" => self.access_code,
28
+ "AddAccessCodeToEmail" => self.add_access_code_to_email,
29
+ "RequireIDLookup" => self.require_id_lookup,
30
+ "IDCheckConfigurationName" => self.id_check_configuration_name,
31
+ "LiveIDRecipientAuthentication" => self.live_id_recipient_authentication,
32
+ "FacebookRecipientAuthentication" => self.facebook_recipient_authentication,
33
+ "LinkedinRecipientAuthentication" => self.linkedin_recipient_authentication,
34
+ "GoogleRecipientAuthentication" => self.google_recipient_authentication,
35
+ "SalesforceRecipientAuthentication" => self.salesforce_recipient_authentication,
36
+ "TwitterRecipientAuthentication" => self.twitter_recipient_authentication,
37
+ "YahooRecipientAuthentication" => self.yahoo_recipient_authentication,
38
+ "OpenIDRecipientAuthentication" => self.open_id_recipient_authentication,
39
+ "PhoneAuthentication" => self.phone_authentication,
40
+ "SignatureInfo" => self.signature_info,
41
+ "CaptiveInfo" => self.captive_info,
42
+ # TODO: CustomFields
43
+ "RoutingOrder" => self.routing_order,
44
+ "IDCheckInformationInput" => self.id_check_information_input,
45
+ "AutoNavigation" => self.auto_navigation,
46
+ # TODO: RecipientAttachment
47
+ "Note" => self.note,
48
+ "RoleName" => self.role_name,
49
+ "TemplateLocked" => self.template_locked,
50
+ "TemplateRequired" => self.template_required,
51
+ "TemplateAccessCodeRequired" => self.template_access_code_required,
52
+ "DefaultRecipient" => self.default_recipient
53
+ # TODO: EmailNotification
54
+ }.delete_if{|key, value| value.nil?}
55
+ end
56
+ end
57
+
58
+ # {http://www.docusign.net/API/3.0}ArrayOfRecipient
59
+ class ArrayOfRecipient < ::Array
60
+ end
61
+ end
@@ -0,0 +1,25 @@
1
+ module DocuSign
2
+ class RecipientStatus < DocuSignModel
3
+ ATTRIBUTES = [:type, :email, :user_name, :routing_order, :sent, :delivered, :signed, :declined, :decline_reason,
4
+ :status, :recipient_ip_address, :client_user_id, :custom_field, :auto_navigation, :id_check_information,
5
+ :recipient_authentication_status, :tab_statuses, :recipient_attachment, :account_status,
6
+ :esign_agreement_information, :form_data, :recipient_id]
7
+ ATTRIBUTES.each do |attr|
8
+ self.send(:attr_accessor, attr)
9
+ end
10
+
11
+ def initialize(attributes = {})
12
+ ATTRIBUTES.each do |attr|
13
+ self.send("#{attr}=", attributes[attr])
14
+ end
15
+ end
16
+
17
+ def tab_statuses=(status_attributes)
18
+ if status_attributes && status_attributes[:tab_status].is_a?(Hash)
19
+ @tab_statuses = [DocuSign::TabStatus.new(status_attributes[:tab_status])]
20
+ elsif status_attributes && status_attributes[:tab_status].is_a?(Array)
21
+ @tab_statuses = status_attributes[:tab_status].map{|attributes| DocuSign::TabStatus.new(attributes)}
22
+ end
23
+ end
24
+ end
25
+ end