Skip to content

Commit 8e19836

Browse files
Merge updates (#71)
Multiple delivery updates
1 parent c87acf3 commit 8e19836

File tree

5 files changed

+341
-0
lines changed

5 files changed

+341
-0
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# frozen_string_literal: true
2+
3+
class ESign::Eeg046MultipleDeliveryController < EgController
4+
before_action -> { check_auth('eSignature') }
5+
before_action -> { @example = Utils::ManifestUtils.new.get_example(@manifest, 46, 'eSignature') }
6+
7+
def create
8+
envelope_args = {
9+
delivery_method: param_gsub(params['delivery_method']),
10+
signer_name: param_gsub(params['signer_name']),
11+
signer_email: param_gsub(params['signer_email']),
12+
cc_name: param_gsub(params['cc_name']),
13+
cc_email: param_gsub(params['cc_email']),
14+
cc_phone_number: param_gsub(params['cc_phone_number']),
15+
cc_country_code: param_gsub(params['cc_country_code']),
16+
phone_number: param_gsub(params['phone_number']),
17+
country_code: param_gsub(params['country_code']),
18+
status: 'sent'
19+
}
20+
args = {
21+
account_id: session['ds_account_id'],
22+
base_path: session['ds_base_path'],
23+
access_token: session['ds_access_token'],
24+
envelope_args: envelope_args
25+
}
26+
27+
results = ESign::Eg046MultipleDeliveryService.new(args).worker
28+
session[:envelope_id] = results['envelope_id']
29+
@title = @example['ExampleName']
30+
@message = format_string(@example['ResultsPageText'], results['envelope_id'])
31+
render 'ds_common/example_done'
32+
rescue DocuSign_eSign::ApiError => e
33+
error = JSON.parse e.response_body
34+
error_message = error['error_description'] || error['message'] || error['error']
35+
36+
if error_message.include?('ACCOUNT_LACKS_PERMISSIONS')
37+
@error_code = 'ACCOUNT_LACKS_PERMISSIONS'
38+
@error_message = @example['CustomErrorTexts'][0]['ErrorMessage']
39+
return render 'ds_common/error'
40+
end
41+
42+
handle_error(e)
43+
end
44+
45+
def get
46+
enableCFR = ESign::GetDataService.new(session[:ds_access_token], session[:ds_base_path]).cfr?(session[:ds_account_id])
47+
if enableCFR == 'enabled'
48+
session[:status_cfr] = 'enabled'
49+
@title = 'Not CFR Part 11 compatible'
50+
@error_information = @manifest['SupportingTexts']['CFRError']
51+
render 'ds_common/error'
52+
end
53+
super
54+
end
55+
end
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
# frozen_string_literal: true
2+
3+
class ESign::Eg046MultipleDeliveryService
4+
attr_reader :args
5+
6+
include ApiCreator
7+
8+
def initialize(args)
9+
@args = args
10+
end
11+
12+
def worker
13+
# Create the envelope request object
14+
envelope_definition = make_envelope(args[:envelope_args])
15+
16+
# Create and send the envelope
17+
# Call Envelopes::create API method
18+
# Exceptions will be caught by the calling function
19+
envelope_api = create_envelope_api(args)
20+
#ds-snippet-start:eSign46Step3
21+
results, _status, headers = envelope_api.create_envelope_with_http_info args[:account_id], envelope_definition
22+
23+
remaining = headers['X-RateLimit-Remaining']
24+
reset = headers['X-RateLimit-Reset']
25+
26+
if remaining && reset
27+
reset_date = Time.at(reset.to_i).utc
28+
puts "API calls remaining: #{remaining}"
29+
puts "Next Reset: #{reset_date}"
30+
end
31+
envelope_id = results.envelope_id
32+
#ds-snippet-end:eSign46Step3
33+
{ 'envelope_id' => envelope_id }
34+
end
35+
36+
private
37+
38+
#ds-snippet-start:eSign46Step2
39+
def make_envelope(envelope_args)
40+
# document 1 (HTML) has tag **signature_1**
41+
# document 2 (DOCX) has tag /sn1/
42+
# document 3 (PDF) has tag /sn1/
43+
#
44+
# The envelope has two recipients:
45+
# recipient 1 - signer
46+
# recipient 2 - cc
47+
# The envelope will be sent first to the signer via SMS
48+
# After it is signed, a copy is sent to the cc person via SMS
49+
50+
# Create the envelope definition
51+
envelope_definition = DocuSign_eSign::EnvelopeDefinition.new
52+
53+
envelope_definition.email_subject = 'Please sign this document set'
54+
55+
# Add the documents
56+
doc1_b64 = Base64.encode64(create_document1(envelope_args))
57+
# Read files 2 and 3 from a local directory
58+
# The reads could raise an exception if the file is not available!
59+
doc_docx = Rails.application.config.doc_docx
60+
doc2_b64 = Base64.encode64(File.binread(File.join('data', doc_docx)))
61+
doc_pdf = Rails.application.config.doc_pdf
62+
doc3_b64 = Base64.encode64(File.binread(File.join('data', doc_pdf)))
63+
64+
# Create the document models
65+
document1 = DocuSign_eSign::Document.new(
66+
# Create the Docusign document object
67+
documentBase64: doc1_b64,
68+
name: 'Order acknowledgement', # Can be different from actual file name
69+
fileExtension: 'html', # Many different document types are accepted
70+
documentId: '1' # A label used to reference the doc
71+
)
72+
document2 = DocuSign_eSign::Document.new(
73+
# Create the Docusign document object
74+
documentBase64: doc2_b64,
75+
name: 'Battle Plan', # Can be different from actual file name
76+
fileExtension: 'docx', # Many different document types are accepted
77+
documentId: '2' # A label used to reference the do
78+
)
79+
document3 = DocuSign_eSign::Document.new(
80+
# Create the Docusign document object
81+
documentBase64: doc3_b64,
82+
name: 'Lorem Ipsum', # Can be different from actual file name
83+
fileExtension: 'pdf', # Many different document types are accepted
84+
documentId: '3' # A label used to reference the doc
85+
)
86+
87+
# The order in the docs array determines the order in the envelope
88+
envelope_definition.documents = [document1, document2, document3]
89+
90+
signer_phone_number = DocuSign_eSign::RecipientPhoneNumber.new
91+
signer_phone_number.country_code = envelope_args[:country_code]
92+
signer_phone_number.number = envelope_args[:phone_number]
93+
94+
signer_additional_notification = DocuSign_eSign::RecipientAdditionalNotification.new
95+
signer_additional_notification.phone_number = signer_phone_number
96+
signer_additional_notification.secondary_delivery_method = envelope_args[:delivery_method]
97+
98+
# Create the signer recipient model
99+
signer1 = DocuSign_eSign::Signer.new
100+
signer1.name = envelope_args[:signer_name]
101+
signer1.email = envelope_args[:signer_email]
102+
signer1.recipient_id = '1'
103+
signer1.routing_order = '1'
104+
signer1.delivery_method = 'Email'
105+
signer1.additional_notifications = [signer_additional_notification]
106+
107+
## routingOrder (lower means earlier) determines the order of deliveries
108+
# to the recipients. Parallel routing order is supported by using the
109+
# same integer as the order for two or more recipients
110+
111+
cc_phone_number = DocuSign_eSign::RecipientPhoneNumber.new
112+
cc_phone_number.country_code = envelope_args[:cc_country_code]
113+
cc_phone_number.number = envelope_args[:cc_phone_number]
114+
115+
cc_additional_notification = DocuSign_eSign::RecipientAdditionalNotification.new
116+
cc_additional_notification.phone_number = cc_phone_number
117+
cc_additional_notification.secondary_delivery_method = envelope_args[:delivery_method]
118+
119+
# Create a cc recipient to receive a copy of the documents
120+
cc1 = DocuSign_eSign::CarbonCopy.new
121+
cc1.name = envelope_args[:cc_name]
122+
cc1.email = envelope_args[:cc_email]
123+
cc1.routing_order = '2'
124+
cc1.recipient_id = '2'
125+
cc1.delivery_method = 'Email'
126+
cc1.additional_notifications = [cc_additional_notification]
127+
128+
# Create signHere fields (also known as tabs) on the documents
129+
# We're using anchor (autoPlace) positioning
130+
#
131+
# The Docusign platform searches throughout your envelope's documents for matching
132+
# anchor strings. So the sign_here_2 tab will be used in both document 2 and 3
133+
# since they use the same anchor string for their "signer 1" tabs.
134+
sign_here1 = DocuSign_eSign::SignHere.new(
135+
anchorString: '**signature_1**',
136+
anchorYOffset: '10',
137+
anchorUnits: 'pixels',
138+
anchorXOffset: '20'
139+
)
140+
141+
sign_here2 = DocuSign_eSign::SignHere.new(
142+
anchorString: '/sn1/',
143+
anchorYOffset: '10',
144+
anchorUnits: 'pixels',
145+
anchorXOffset: '20'
146+
)
147+
# Add the tabs model (including the sign_here tabs) to the signer
148+
# The Tabs object takes arrays of the different field/tab types
149+
signer1_tabs = DocuSign_eSign::Tabs.new({
150+
signHereTabs: [sign_here1, sign_here2]
151+
})
152+
153+
signer1.tabs = signer1_tabs
154+
155+
# Add the recipients to the envelope object
156+
recipients = DocuSign_eSign::Recipients.new(
157+
signers: [signer1],
158+
carbonCopies: [cc1]
159+
)
160+
# Request that the envelope be sent by setting status to "sent".
161+
# To request that the envelope be created as a draft, set status to "created"
162+
envelope_definition.recipients = recipients
163+
envelope_definition.status = envelope_args[:status]
164+
envelope_definition
165+
end
166+
167+
def create_document1(args)
168+
"
169+
<!DOCTYPE html>
170+
<html>
171+
<head>
172+
<meta charset=\"UTF-8\">
173+
</head>
174+
<body style=\"font-family:sans-serif;margin-left:2em;\">
175+
<h1 style=\"font-family: 'Trebuchet MS', Helvetica, sans-serif;
176+
color: darkblue;margin-bottom: 0;\">World Wide Corp</h1>
177+
<h2 style=\"font-family: 'Trebuchet MS', Helvetica, sans-serif;
178+
margin-top: 0px;margin-bottom: 3.5em;font-size: 1em;
179+
color: darkblue;\">Order Processing Division</h2>
180+
<h4>Ordered by #{args[:signer_name]}</h4>
181+
<p style=\"margin-top:0em; margin-bottom:0em;\">Phone number: #{args[:phone_number]}</p>
182+
<p style=\"margin-top:0em; margin-bottom:0em;\">Copy to: #{args[:cc_name]}, #{args[:cc_phone_number]}</p>
183+
<p style=\"margin-top:3em;\">
184+
Candy bonbon pastry jujubes lollipop wafer biscuit biscuit. Topping brownie sesame snaps sweet roll pie. Croissant danish biscuit soufflé caramels jujubes jelly. Dragée danish caramels lemon drops dragée. Gummi bears cupcake biscuit tiramisu sugar plum pastry. Dragée gummies applicake pudding liquorice. Donut jujubes oat cake jelly-o. Dessert bear claw chocolate cake gummies lollipop sugar plum ice cream gummies cheesecake.
185+
</p>
186+
<!-- Note the anchor tag for the signature field is in white. -->
187+
<h3 style=\"margin-top:3em;\">Agreed: <span style=\"color:white;\">**signature_1**/</span></h3>
188+
</body>
189+
</html>"
190+
end
191+
#ds-snippet-end:eSign46Step2
192+
end
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<%= render('partials/example_info') %>
2+
3+
<% form_index = 0 %>
4+
<% delivery_method_index = 0 %>
5+
<% sms_delivery_method_index = 1 %>
6+
<% whatsapp_delivery_method_index = 2 %>
7+
<% signer_name_index = 3 %>
8+
<% signer_email_index = 4 %>
9+
<% signer_code_index = 5 %>
10+
<% signer_phone_index = 6 %>
11+
<% cc_name_index = 7 %>
12+
<% cc_email_index = 8 %>
13+
<% cc_code_index = 9 %>
14+
<% cc_phone_index = 10 %>
15+
16+
<form class="eg" id="data_form" action="" method="post" data-busy="form">
17+
<% if @example["Forms"][form_index]["FormName"] %>
18+
<%= sanitize @example["Forms"][form_index]["FormName"] %>
19+
<% end %>
20+
21+
<div class="form-group">
22+
<label for="delivery_method"><%= @example["Forms"][form_index]["Inputs"][delivery_method_index]["InputName"] %></label><br>
23+
24+
<label for="sms_delivery"><%= @example["Forms"][form_index]["Inputs"][sms_delivery_method_index]["InputName"] %></label>
25+
<input type="radio" name="delivery_method" value="SMS" checked/>
26+
27+
<label for="whatsapp_delivery"><%= @example["Forms"][form_index]["Inputs"][whatsapp_delivery_method_index]["InputName"] %></label>
28+
<input type="radio" name="delivery_method" value="WhatsApp"/>
29+
</div>
30+
31+
<div class="form-group">
32+
<label for="signer_name"><%= @example["Forms"][form_index]["Inputs"][signer_name_index]["InputName"] %></label>
33+
<input type="text" class="form-control" id="signer_name"
34+
placeholder="<%= @example["Forms"][form_index]["Inputs"][signer_name_index]["InputPlaceholder"] %>" name="signer_name"
35+
value="<%= @config.signer_name %>" required />
36+
</div>
37+
<div class="form-group">
38+
<label for="signer_email"><%= @example["Forms"][form_index]["Inputs"][signer_email_index]["InputName"] %></label>
39+
<input type="email" class="form-control" id="signer_email"
40+
placeholder="<%= @example["Forms"][form_index]["Inputs"][signer_email_index]["InputPlaceholder"] %>" name="signer_email"
41+
value="<%= @config.signer_email %>" required />
42+
<%= render('partials/email_will_not_be_shared') %>
43+
</div>
44+
45+
<div class="form-group">
46+
<label for="country_code"><%= @example["Forms"][form_index]["Inputs"][signer_code_index]["InputName"] %></label>
47+
<input type="tel" class="form-control" id="country_code" name="country_code"
48+
aria-describedby="accessHelp"
49+
placeholder="<%= @example["Forms"][form_index]["Inputs"][signer_code_index]["InputPlaceholder"] %>" required />
50+
<%= render('partials/country_code_text') %>
51+
</div>
52+
<div class="form-group">
53+
<label for="phone_number"><%= @example["Forms"][form_index]["Inputs"][signer_phone_index]["InputName"] %></label>
54+
<input type="tel" class="form-control" id="phone_number" name="phone_number"
55+
aria-describedby="accessHelp"
56+
placeholder="<%= @example["Forms"][form_index]["Inputs"][signer_phone_index]["InputPlaceholder"] %>" required />
57+
<%= render('partials/phone_will_not_be_shared') %>
58+
</div>
59+
60+
<div class="form-group">
61+
<label for="cc_name"><%= @example["Forms"][form_index]["Inputs"][cc_name_index]["InputName"] %></label>
62+
<input type="text" class="form-control" id="cc_name"
63+
placeholder="<%= @example["Forms"][form_index]["Inputs"][cc_name_index]["InputPlaceholder"] %>" name="cc_name"
64+
required />
65+
</div>
66+
<div class="form-group">
67+
<label for="cc_email"><%= @example["Forms"][form_index]["Inputs"][cc_email_index]["InputName"] %></label>
68+
<input type="email" class="form-control" id="cc_email"
69+
placeholder="<%= @example["Forms"][form_index]["Inputs"][signer_email_index]["InputPlaceholder"] %>" name="cc_email"
70+
required />
71+
<%= render('partials/email_will_not_be_shared') %>
72+
</div>
73+
74+
<div class="form-group">
75+
<label for="cc_country_code"><%= @example["Forms"][form_index]["Inputs"][cc_code_index]["InputName"] %></label>
76+
<input type="tel" class="form-control" id="cc_country_code" name="cc_country_code"
77+
aria-describedby="accessHelp"
78+
placeholder="<%= @example["Forms"][form_index]["Inputs"][cc_code_index]["InputPlaceholder"] %>" required />
79+
<%= render('partials/country_code_text') %>
80+
</div>
81+
<div class="form-group">
82+
<label for="cc_phone_number"><%= @example["Forms"][form_index]["Inputs"][cc_phone_index]["InputName"] %></label>
83+
<input type="tel" class="form-control" id="cc_phone_number" name="cc_phone_number"
84+
aria-describedby="accessHelp"
85+
placeholder="<%= @example["Forms"][form_index]["Inputs"][cc_phone_index]["InputPlaceholder"] %>" required />
86+
<%= render('partials/phone_will_not_be_shared') %>
87+
</div>
88+
89+
<%= render('partials/submit_button') %>
90+
</form>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<small id="accessHelp" class="form-text text-muted"><%= @manifest["SupportingTexts"]["HelpingTexts"]["CountryCodeText"] %></small>

config/routes.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,9 @@
236236
post 'eeg045' => 'eeg045_delete_restore_envelope#delete_envelope'
237237
get 'eeg045restore' => 'eeg045_delete_restore_envelope#get_restore_envelope'
238238
post 'eeg045restore' => 'eeg045_delete_restore_envelope#restore_envelope'
239+
240+
get 'eeg046' => 'eeg046_multiple_delivery#get'
241+
post 'eeg046' => 'eeg046_multiple_delivery#create'
239242
end
240243

241244
scope module: 'connect' do

0 commit comments

Comments
 (0)