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.
- data/.document +5 -0
- data/.gitignore +7 -0
- data/.rspec +1 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +20 -0
- data/Rakefile +1 -0
- data/docu_sign.example.yml +4 -0
- data/docu_sign.gemspec +36 -0
- data/lib/docu_sign/anchor_tab.rb +29 -0
- data/lib/docu_sign/authentication_status.rb +16 -0
- data/lib/docu_sign/builder/anchor_builder.rb +17 -0
- data/lib/docu_sign/builder/base.rb +27 -0
- data/lib/docu_sign/builder/document_builder.rb +16 -0
- data/lib/docu_sign/builder/notification_builder.rb +16 -0
- data/lib/docu_sign/builder/recipient_builder.rb +17 -0
- data/lib/docu_sign/builder/tab_builder.rb +30 -0
- data/lib/docu_sign/cacert.pem +3390 -0
- data/lib/docu_sign/client.rb +98 -0
- data/lib/docu_sign/docu_sign_model.rb +23 -0
- data/lib/docu_sign/docu_sign_response.rb +33 -0
- data/lib/docu_sign/document.rb +57 -0
- data/lib/docu_sign/document_pdf.rb +14 -0
- data/lib/docu_sign/document_status.rb +15 -0
- data/lib/docu_sign/envelope.rb +136 -0
- data/lib/docu_sign/envelope_status.rb +33 -0
- data/lib/docu_sign/error.rb +7 -0
- data/lib/docu_sign/extensions.rb +81 -0
- data/lib/docu_sign/notification.rb +21 -0
- data/lib/docu_sign/railtie.rb +7 -0
- data/lib/docu_sign/recipient.rb +61 -0
- data/lib/docu_sign/recipient_status.rb +25 -0
- data/lib/docu_sign/tab.rb +96 -0
- data/lib/docu_sign/tab_status.rb +17 -0
- data/lib/docu_sign/version.rb +3 -0
- data/lib/docu_sign/void_envelope_status.rb +14 -0
- data/lib/docu_sign.rb +37 -0
- data/spec/docu_sign/client_spec.rb +8 -0
- data/spec/docu_sign/document_spec.rb +51 -0
- data/spec/docu_sign/envelope_spec.rb +132 -0
- data/spec/docu_sign/post_processing_spec.rb +85 -0
- data/spec/docu_sign/sending_spec.rb +96 -0
- data/spec/docu_sign/status_spec.rb +146 -0
- data/spec/docu_sign/tab_spec.rb +32 -0
- data/spec/docu_sign.yml.example +4 -0
- data/spec/docu_sign_spec.rb +28 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config/application.rb +45 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +22 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +26 -0
- data/spec/dummy/config/environments/production.rb +49 -0
- data/spec/dummy/config/environments/test.rb +35 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +10 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/locales/en.yml +2 -0
- data/spec/dummy/config/routes.rb +58 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +0 -0
- data/spec/dummy/log/production.log +0 -0
- data/spec/dummy/log/server.log +0 -0
- data/spec/dummy/log/test.log +331 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +26 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/public/stylesheets/.gitkeep +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/fixtures/document.pdf +0 -0
- data/spec/fixtures/vcr_cassettes/create_and_send_envelope.yml +553 -0
- data/spec/fixtures/vcr_cassettes/invalid_request.yml +52 -0
- data/spec/fixtures/vcr_cassettes/ping.yml +50 -0
- data/spec/fixtures/vcr_cassettes/request_document_pdfs_ex.yml +603 -0
- data/spec/fixtures/vcr_cassettes/request_envelope.yml +608 -0
- data/spec/fixtures/vcr_cassettes/request_status.yml +609 -0
- data/spec/fixtures/vcr_cassettes/request_status_ex.yml +614 -0
- data/spec/fixtures/vcr_cassettes/request_statuses.yml +1176 -0
- data/spec/fixtures/vcr_cassettes/void_envelope.yml +603 -0
- data/spec/spec_helper.rb +37 -0
- data/spec/support/vcr.rb +6 -0
- data/wsdl/dsapi.wsdl +3735 -0
- data/wsdl/dsapi.wsdl.old +3131 -0
- 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,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,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
|