Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@
app.register_blueprint(connect_views.cneg001)

app.register_blueprint(webforms_views.weg001)
app.register_blueprint(webforms_views.weg002)

app.register_blueprint(notary_views.neg004)

Expand Down
10 changes: 5 additions & 5 deletions app/ds_config_sample.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# ds_config.py
#
# DocuSign configuration settings
# Docusign configuration settings

DS_CONFIG = {
"ds_client_id": "{INTEGRATION_KEY_AUTH_CODE}", # The app's DocuSign integration key
"ds_client_secret": "{SECRET_KEY}", # The app's DocuSign integration key's secret
"ds_client_id": "{INTEGRATION_KEY_AUTH_CODE}", # The app's Docusign integration key
"ds_client_secret": "{SECRET_KEY}", # The app's Docusign integration key's secret
"organization_id": "{ORGANIZATION_ID}", # A GUID value that identifies the organization
"signer_email": "{SIGNER_EMAIL}",
"signer_name": "{SIGNER_NAME}",
Expand All @@ -16,10 +16,10 @@
"rooms_api_client_host": "https://demo.rooms.docusign.com/restapi",
"monitor_api_client_host": "https://lens-d.docusign.net",
"admin_api_client_host": "https://api-d.docusign.net/management",
"webforms_api_client_host": "https://apps-d.docusign.com/api/webforms/v1.1",
"webforms_api_client_host": "https://apps-d.docusign.com/api/webforms",
"allow_silent_authentication": True, # a user can be silently authenticated if they have an
# active login session on another tab of the same browser
"target_account_id": None, # Set if you want a specific DocuSign AccountId,
"target_account_id": None, # Set if you want a specific Docusign AccountId,
# If None, the user's default account will be used.
"demo_doc_path": "demo_documents",
"doc_salary_docx": "World_Wide_Corp_salary.docx",
Expand Down
2 changes: 1 addition & 1 deletion app/quick_acg/quick_acg_app/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

<body>
<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
<a class="navbar-brand" href="/">DocuSign Examples</a>
<a class="navbar-brand" href="/">Docusign Examples</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
Expand Down
2 changes: 1 addition & 1 deletion app/static/demo_documents/web-form-config.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion app/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

<body>
<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
<a class="navbar-brand" href="/">DocuSign Examples</a>
<a class="navbar-brand" href="/">Docusign Examples</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
Expand Down
10 changes: 10 additions & 0 deletions app/templates/webforms/eg002_create_remote_instance.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!-- extend base layout --> {% extends "base.html" %} {% block content %}

{% include 'example_info.html' %}

<form class="eg" action="" method="post" data-busy="form">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
{% include 'continue_button.html' %}
</form>

{% endblock %}
11 changes: 11 additions & 0 deletions app/templates/webforms/eg002_web_form_create.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!-- extend base layout --> {% extends "base.html" %} {% block content %}

<h4>{{ title }}</h4>
<p>{{ description | safe }}</p>

<form class="eg" action="" method="post" data-busy="form">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
{% include 'continue_button.html' %}
</form>

{% endblock %}
1 change: 1 addition & 0 deletions app/webforms/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
from .views import weg001
from .views import weg002
173 changes: 173 additions & 0 deletions app/webforms/examples/eg002_create_remote_instance.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
import base64

from docusign_webforms import ApiClient, FormInstanceManagementApi, FormManagementApi, CreateInstanceRequestBody
from docusign_esign import Document, Signer, SignHere, Tabs, Recipients, TemplatesApi, Checkbox, DateSigned, \
Text, EnvelopeTemplate

from ...docusign import create_api_client


class Eg002CreateRemoteInstance:
@classmethod
def create_web_form_template(cls, args):
api_client = create_api_client(base_path=args["base_path"], access_token=args["access_token"])
templates_api = TemplatesApi(api_client)

web_forms_templates = templates_api.list_templates(
account_id=args["account_id"],
search_text=args["template_name"]
)

if int(web_forms_templates.result_set_size) > 0:
template_id = web_forms_templates.envelope_templates[0].template_id
else:
template_req_object = cls.make_web_forms_template(args)
template = templates_api.create_template(
account_id=args["account_id"],
envelope_template=template_req_object
)
template_id = template.template_id

return template_id

@classmethod
def create_web_form_instance(cls, form_id, args):
#ds-snippet-start:WebForms2Step2
api_client = ApiClient()
api_client.host = args["base_path"]
api_client.set_default_header(header_name="Authorization", header_value=f"Bearer {args['access_token']}")
#ds-snippet-end:WebForms2Step2

#ds-snippet-start:WebForms2Step4
web_form_values = {
"PhoneNumber": "555-555-5555",
"Yes": ["Yes"],
"Company": "Tally",
"JobTitle": "Programmer Writer"
}
recipient = {
"roleName": "signer",
"name": args["signer_name"],
"email": args["signer_email"]
}
web_form_req_object = {
"formValues": web_form_values,
"recipients": [recipient],
"sendOption": "now"
}
#ds-snippet-end:WebForms2Step4

#ds-snippet-start:WebForms2Step5
webforms_api = FormInstanceManagementApi(api_client)
web_form = webforms_api.create_instance(args["account_id"], form_id, web_form_req_object)
#ds-snippet-end:WebForms2Step5

return web_form

@classmethod
def list_web_forms(cls, args):
api_client = ApiClient()
api_client.host = args["base_path"]
api_client.set_default_header(header_name="Authorization", header_value=f"Bearer {args['access_token']}")

#ds-snippet-start:WebForms2Step3
webforms_api = FormManagementApi(api_client)
web_forms = webforms_api.list_forms(args["account_id"], search=args["form_name"])
#ds-snippet-end:WebForms2Step3

return web_forms

@classmethod
def make_web_forms_template(cls, args):
with open(args["pdf_file"], "rb") as file:
content_bytes = file.read()
base64_file_content = base64.b64encode(content_bytes).decode("ascii")

# Create the document model
document = Document( # create the DocuSign document object
document_base64=base64_file_content,
name="World_Wide_Web_Form", # can be different from actual file name
file_extension="pdf", # many different document types are accepted
document_id=1 # a label used to reference the doc
)

# Create the signer recipient model
signer = Signer(role_name="signer", recipient_id="1", routing_order="1")
# Create fields using absolute positioning
# Create a sign_here tab (field on the document)
sign_here = SignHere(
document_id="1",
tab_label="Signature",
anchor_string="/SignHere/",
anchor_units="pixels",
anchor_x_offset="0",
anchor_y_offset="0"
)
check = Checkbox(
document_id="1",
tab_label="Yes",
anchor_string="/SMS/",
anchor_units="pixels",
anchor_x_offset="0",
anchor_y_offset="0"
)
text1 = Text(
document_id="1",
tab_label="FullName",
anchor_string="/FullName/",
anchor_units="pixels",
anchor_x_offset="0",
anchor_y_offset="0"
)
text2 = Text(
document_id="1",
tab_label="PhoneNumber",
anchor_string="/PhoneNumber/",
anchor_units="pixels",
anchor_x_offset="0",
anchor_y_offset="0"
)
text3 = Text(
document_id="1",
tab_label="Company",
anchor_string="/Company/",
anchor_units="pixels",
anchor_x_offset="0",
anchor_y_offset="0"
)
text4 = Text(
document_id="1",
tab_label="JobTitle",
anchor_string="/JobTitle/",
anchor_units="pixels",
anchor_x_offset="0",
anchor_y_offset="0"
)
date_signed = DateSigned(
document_id="1",
tab_label="DateSigned",
anchor_string="/Date/",
anchor_units="pixels",
anchor_x_offset="0",
anchor_y_offset="0"
)
# Add the tabs model to the signer
# The Tabs object wants arrays of the different field/tab types
signer.tabs = Tabs(
sign_here_tabs=[sign_here],
checkbox_tabs=[check],
text_tabs=[text1, text2, text3, text4],
date_signed=[date_signed]
)

# Top object:
template_request = EnvelopeTemplate(
documents=[document], email_subject="Please sign this document",
recipients=Recipients(signers=[signer]),
description="Example template created via the API",
name=args["template_name"],
shared="false",
status="created"
)

return template_request
1 change: 1 addition & 0 deletions app/webforms/views/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
from .eg001_create_instance import weg001
from .eg002_create_remote_instance import weg002
109 changes: 109 additions & 0 deletions app/webforms/views/eg002_create_remote_instance.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
from os import path

from docusign_esign.client.api_exception import ApiException
from flask import render_template, session, Blueprint, redirect, url_for

from ..examples.eg002_create_remote_instance import Eg002CreateRemoteInstance
from ...docusign import authenticate, ensure_manifest, get_example_by_number
from ...docusign.utils import replace_template_id
from ...ds_config import DS_CONFIG
from ...error_handlers import process_error
from ...consts import API_TYPE, demo_docs_path, web_form_config_file, web_form_template_file

example_number = 2
api = API_TYPE["WEBFORMS"]
eg = f"weg00{example_number}"
weg002 = Blueprint(eg, __name__)


@weg002.route(f"/{eg}", methods=["POST"])
@authenticate(eg=eg, api=api)
@ensure_manifest(manifest_url=DS_CONFIG["example_manifest_url"])
def create_web_form_template():
args = {
"account_id": session["ds_account_id"],
"base_path": session["ds_base_path"],
"access_token": session["ds_access_token"],
"template_name": "Web Form Example Template",
"pdf_file": path.join(demo_docs_path, web_form_template_file)
}
try:
web_form_template_id = Eg002CreateRemoteInstance.create_web_form_template(args)
replace_template_id(path.join(demo_docs_path, web_form_config_file), web_form_template_id)
except ApiException as error:
return process_error(error)

session["web_form_template_id"] = web_form_template_id
return redirect(url_for(f"{eg}.get_web_form_create_view"))


@weg002.route(f"/{eg}/web_form", methods=["POST"])
@authenticate(eg=eg, api=api)
@ensure_manifest(manifest_url=DS_CONFIG["example_manifest_url"])
def create_web_form_instance():
args = {
"account_id": session["ds_account_id"],
"base_path": DS_CONFIG["webforms_api_client_host"],
"signer_name": DS_CONFIG["signer_name"],
"signer_email": DS_CONFIG["signer_email"],
"access_token": session["ds_access_token"],
"form_name": "Web Form Example Template"
}

example = get_example_by_number(session["manifest"], example_number, api)
try:
forms = Eg002CreateRemoteInstance.list_web_forms(args)
if forms.items is None or len(forms.items) == 0:
error_code = "404"
error_message = example["CustomErrorTexts"][0]["ErrorMessage"]
return render_template(
"error.html",
error_code=error_code,
error_message=error_message
)

results = Eg002CreateRemoteInstance.create_web_form_instance(forms.items[0].id, args)
except Exception as error:
return process_error(error)

return render_template(
"example_done.html",
title=example["ExampleName"],
message=example["ResultsPageText"].format(results.envelopes[0].id, results.id)
)


@weg002.route(f"/{eg}", methods=["GET"])
@ensure_manifest(manifest_url=DS_CONFIG["example_manifest_url"])
@authenticate(eg=eg, api=api)
def get_view():
"""responds with the form for the example"""
example = get_example_by_number(session["manifest"], example_number, api)

return render_template(
"webforms/eg002_create_remote_instance.html",
title=example["ExampleName"],
example=example,
source_file="eg002_create_remote_instance.py",
source_url=DS_CONFIG["github_example_url"] + "eg002_create_remote_instance.py",
documentation=DS_CONFIG["documentation"] + eg,
show_doc=DS_CONFIG["documentation"]
)


@weg002.route(f"/{eg}/web_form", methods=["GET"])
@ensure_manifest(manifest_url=DS_CONFIG["example_manifest_url"])
@authenticate(eg=eg, api=api)
def get_web_form_create_view():
if "web_form_template_id" not in session:
return redirect(url_for(f"{eg}.get_view"))

example = get_example_by_number(session["manifest"], example_number, api)
additional_page_data = next((p for p in example["AdditionalPage"] if p["Name"] == "create_web_form"),
None)
return render_template(
"webforms/eg002_web_form_create.html",
title=example["ExampleName"],
example=example,
description=additional_page_data["ResultsPageText"].format("app/static/demo_documents")
)
Loading
Loading