1
- from docusign_esign import EnvelopesApi , ReturnUrlRequest
1
+ import base64
2
+ from os import path
3
+
4
+ from docusign_esign import EnvelopesApi , ReturnUrlRequest , EnvelopesApi , EnvelopeDefinition , \
5
+ Document , Signer , CarbonCopy , SignHere , Tabs , Recipients
2
6
from flask import url_for , session , request
3
7
4
- from .eg002_signing_via_email import Eg002SigningViaEmailController
5
8
from ...consts import pattern , demo_docs_path
6
9
from ...docusign import create_api_client
7
10
@@ -24,7 +27,7 @@ def get_args():
24
27
"signer_name" : signer_name ,
25
28
"cc_email" : cc_email ,
26
29
"cc_name" : cc_name ,
27
- "status" : "sent " ,
30
+ "status" : "created " ,
28
31
}
29
32
args = {
30
33
"starting_view" : starting_view ,
@@ -36,36 +39,196 @@ def get_args():
36
39
}
37
40
return args
38
41
39
- @staticmethod
40
- def worker (args ,doc_docx_path ,doc_pdf_path ):
42
+ @classmethod
43
+ def worker (cls , args , doc_docx_path , doc_pdf_path ):
41
44
"""
42
45
This function does the work of creating the envelope in
43
46
draft mode and returning a URL for the sender"s view
44
47
"""
45
48
46
49
# Step 2. Create the envelope with "created" (draft) status
47
- args ["envelope_args" ]["status" ] = "created"
48
- # Using worker from example 002
49
- results = Eg002SigningViaEmailController .worker (args , doc_docx_path , doc_pdf_path )
50
- envelope_id = results ["envelope_id" ]
50
+ envelope = cls .create_envelope (args , doc_docx_path , doc_pdf_path )
51
+ envelope_id = envelope .envelope_id
51
52
52
53
# Step 3. Create the sender view
54
+ sender_view_url = cls .create_sender_view (args , envelope_id )
55
+
56
+ return {"envelope_id" : envelope_id , "redirect_url" : sender_view_url }
57
+
58
+ @classmethod
59
+ #ds-snippet-start:eSign11Step3
60
+ def create_sender_view (cls , args , envelope_id ):
53
61
view_request = ReturnUrlRequest (return_url = args ["ds_return_url" ])
54
62
# Exceptions will be caught by the calling function
55
- #ds-snippet-start:eSign11Step3
56
63
api_client = create_api_client (base_path = args ["base_path" ], access_token = args ["access_token" ])
57
64
58
65
envelope_api = EnvelopesApi (api_client )
59
- results = envelope_api .create_sender_view (
66
+ sender_view = envelope_api .create_sender_view (
60
67
account_id = args ["account_id" ],
61
68
envelope_id = envelope_id ,
62
69
return_url_request = view_request
63
70
)
64
71
65
72
# Switch to Recipient and Documents view if requested by the user
66
- url = results .url
73
+ url = sender_view .url
67
74
if args ["starting_view" ] == "recipient" :
68
75
url = url .replace ("send=1" , "send=0" )
69
- #ds-snippet-end:eSign13Step3
70
76
71
- return {"envelope_id" : envelope_id , "redirect_url" : url }
77
+ return url
78
+ #ds-snippet-end:eSign11Step3
79
+
80
+ @classmethod
81
+ #ds-snippet-start:eSign11Step2
82
+ def create_envelope (cls , args , doc_docx_path , doc_pdf_path ):
83
+ envelope_args = args ["envelope_args" ]
84
+ # Create the envelope request object
85
+ envelope_definition = cls .make_envelope (envelope_args , doc_docx_path , doc_pdf_path )
86
+ api_client = create_api_client (base_path = args ["base_path" ], access_token = args ["access_token" ])
87
+ # Call Envelopes::create API method
88
+ # Exceptions will be caught by the calling function
89
+ envelopes_api = EnvelopesApi (api_client )
90
+ return envelopes_api .create_envelope (account_id = args ["account_id" ], envelope_definition = envelope_definition )
91
+
92
+ @classmethod
93
+ def make_envelope (cls , args , doc_docx_path , doc_pdf_path ):
94
+ """
95
+ Creates envelope
96
+ Document 1: An HTML document.
97
+ Document 2: A Word .docx document.
98
+ Document 3: A PDF document.
99
+ DocuSign will convert all of the documents to the PDF format.
100
+ The recipients" field tags are placed using <b>anchor</b> strings.
101
+ """
102
+
103
+ # document 1 (html) has sign here anchor tag **signature_1**
104
+ # document 2 (docx) has sign here anchor tag /sn1/
105
+ # document 3 (pdf) has sign here anchor tag /sn1/
106
+ #
107
+ # The envelope has two recipients.
108
+ # recipient 1 - signer
109
+ # recipient 2 - cc
110
+ # The envelope will be sent first to the signer.
111
+ # After it is signed, a copy is sent to the cc person.
112
+
113
+ # create the envelope definition
114
+ env = EnvelopeDefinition (
115
+ email_subject = "Please sign this document set"
116
+ )
117
+ doc1_b64 = base64 .b64encode (bytes (cls .create_document1 (args ), "utf-8" )).decode ("ascii" )
118
+ # read files 2 and 3 from a local directory
119
+ # The reads could raise an exception if the file is not available!
120
+ with open (path .join (demo_docs_path , doc_docx_path ), "rb" ) as file :
121
+ doc2_docx_bytes = file .read ()
122
+ doc2_b64 = base64 .b64encode (doc2_docx_bytes ).decode ("ascii" )
123
+ with open (path .join (demo_docs_path , doc_pdf_path ), "rb" ) as file :
124
+ doc3_pdf_bytes = file .read ()
125
+ doc3_b64 = base64 .b64encode (doc3_pdf_bytes ).decode ("ascii" )
126
+
127
+ # Create the document models
128
+ document1 = Document ( # create the DocuSign document object
129
+ document_base64 = doc1_b64 ,
130
+ name = "Order acknowledgement" , # can be different from actual file name
131
+ file_extension = "html" , # many different document types are accepted
132
+ document_id = "1" # a label used to reference the doc
133
+ )
134
+ document2 = Document ( # create the DocuSign document object
135
+ document_base64 = doc2_b64 ,
136
+ name = "Battle Plan" , # can be different from actual file name
137
+ file_extension = "docx" , # many different document types are accepted
138
+ document_id = "2" # a label used to reference the doc
139
+ )
140
+ document3 = Document ( # create the DocuSign document object
141
+ document_base64 = doc3_b64 ,
142
+ name = "Lorem Ipsum" , # can be different from actual file name
143
+ file_extension = "pdf" , # many different document types are accepted
144
+ document_id = "3" # a label used to reference the doc
145
+ )
146
+ # The order in the docs array determines the order in the envelope
147
+ env .documents = [document1 , document2 , document3 ]
148
+
149
+ # Create the signer recipient model
150
+ signer1 = Signer (
151
+ email = args ["signer_email" ],
152
+ name = args ["signer_name" ],
153
+ recipient_id = "1" ,
154
+ routing_order = "1"
155
+ )
156
+ # routingOrder (lower means earlier) determines the order of deliveries
157
+ # to the recipients. Parallel routing order is supported by using the
158
+ # same integer as the order for two or more recipients.
159
+
160
+ # create a cc recipient to receive a copy of the documents
161
+ cc1 = CarbonCopy (
162
+ email = args ["cc_email" ],
163
+ name = args ["cc_name" ],
164
+ recipient_id = "2" ,
165
+ routing_order = "2"
166
+ )
167
+
168
+ # Create signHere fields (also known as tabs) on the documents,
169
+ # We"re using anchor (autoPlace) positioning
170
+ #
171
+ # The DocuSign platform searches throughout your envelope"s
172
+ # documents for matching anchor strings. So the
173
+ # signHere2 tab will be used in both document 2 and 3 since they
174
+ # use the same anchor string for their "signer 1" tabs.
175
+ sign_here1 = SignHere (
176
+ anchor_string = "**signature_1**" ,
177
+ anchor_units = "pixels" ,
178
+ anchor_y_offset = "10" ,
179
+ anchor_x_offset = "20"
180
+ )
181
+
182
+ sign_here2 = SignHere (
183
+ anchor_string = "/sn1/" ,
184
+ anchor_units = "pixels" ,
185
+ anchor_y_offset = "10" ,
186
+ anchor_x_offset = "20"
187
+ )
188
+
189
+ # Add the tabs model (including the sign_here tabs) to the signer
190
+ # The Tabs object wants arrays of the different field/tab types
191
+ signer1 .tabs = Tabs (sign_here_tabs = [sign_here1 , sign_here2 ])
192
+
193
+ # Add the recipients to the envelope object
194
+ recipients = Recipients (signers = [signer1 ], carbon_copies = [cc1 ])
195
+ env .recipients = recipients
196
+
197
+ # Request that the envelope be sent by setting |status| to "sent".
198
+ # To request that the envelope be created as a draft, set to "created"
199
+ env .status = args ["status" ]
200
+
201
+ return env
202
+
203
+ @classmethod
204
+ def create_document1 (cls , args ):
205
+ """ Creates document 1 -- an html document"""
206
+
207
+ return f"""
208
+ <!DOCTYPE html>
209
+ <html>
210
+ <head>
211
+ <meta charset="UTF-8">
212
+ </head>
213
+ <body style="font-family:sans-serif;margin-left:2em;">
214
+ <h1 style="font-family: "Trebuchet MS", Helvetica, sans-serif;
215
+ color: darkblue;margin-bottom: 0;">World Wide Corp</h1>
216
+ <h2 style="font-family: "Trebuchet MS", Helvetica, sans-serif;
217
+ margin-top: 0px;margin-bottom: 3.5em;font-size: 1em;
218
+ color: darkblue;">Order Processing Division</h2>
219
+ <h4>Ordered by { args ["signer_name" ]} </h4>
220
+ <p style="margin-top:0em; margin-bottom:0em;">Email: { args ["signer_email" ]} </p>
221
+ <p style="margin-top:0em; margin-bottom:0em;">Copy to: { args ["cc_name" ]} , { args ["cc_email" ]} </p>
222
+ <p style="margin-top:3em;">
223
+ Candy bonbon pastry jujubes lollipop wafer biscuit biscuit. Topping brownie sesame snaps sweet roll pie.
224
+ Croissant danish biscuit soufflé caramels jujubes jelly. Dragée danish caramels lemon drops dragée.
225
+ Gummi bears cupcake biscuit tiramisu sugar plum pastry. Dragée gummies applicake pudding liquorice.
226
+ Donut jujubes oat cake jelly-o.
227
+ Dessert bear claw chocolate cake gummies lollipop sugar plum ice cream gummies cheesecake.
228
+ </p>
229
+ <!-- Note the anchor tag for the signature field is in white. -->
230
+ <h3 style="margin-top:3em;">Agreed: <span style="color:white;">**signature_1**/</span></h3>
231
+ </body>
232
+ </html>
233
+ """
234
+ #ds-snippet-end:eSign11Step2
0 commit comments