How to apply a multi-document template - c#

The general process
Documents are uploaded to DocuSign creating a new Envelope.
Templates are applied to this Envelope.
Recipients are updated to make sure there is no mixup with signers from the template
The Envelope is sent to the signers.
Intended use of templates
The primary use of templates is to allow users to upload documents and use all other information from templates like fields and other setting for the uploaded documents. Signers can also be freely set and overwrite the ones defined in the template.
For applying templates we use https://developers.docusign.com/docs/esign-rest-api/reference/envelopes/envelopetemplates/applytodocument/
The Template
The template consist of 2 documents. The first document has 3 pages and the second document has 2 pages.
There is one signer. A signature box is added to the last page of both documents.
The Problem
Test scenario: The exact same documents as in the template. This results in the signature box on the second document is not set.
Test scenario: Use the 3 page file for both documents. This results in the signature box being put on page 3 of both documents. So it looks like the assignment works only from document 1 to all the other documents
Test scenario: Use different 3 page documents that match the template for both documents. The result is the same as in the 2. test scenario.
What I tried
The described scenarios are based on this (simplyfied) code for applying the templates:
//variables envAPI (class EnvelopesApi), accountId, templateId and envelope (class Envelope) are already set
DocumentTemplateList templateList = new DocumentTemplateList();
templateList.DocumentTemplates = new List<DocumentTemplate>();
templateList.DocumentTemplates.Add(new DocumentTemplate()
{
TemplateId = templateId,
DocumentId = "1"
});
envAPI.ApplyTemplateToDocument(accountId, envelope.EnvelopeId, "1", templateList);
templateList = new DocumentTemplateList();
templateList.DocumentTemplates = new List<DocumentTemplate>();
templateList.DocumentTemplates.Add(new DocumentTemplate()
{
TemplateId = templateId,
DocumentId = "2"
});
envAPI.ApplyTemplateToDocument(accountId, envelope.EnvelopeId, "2", templateList);
//some recipient checking is done here
envAPI.Update(accountId, envelope.EnvelopeId, envelope);
I also tried using more entries in templateList.DocumentTemplates but that only caused INVALID_REQUEST_BODY errors.
I realized the DocumentID property of the documents in the templates are very different after the first file. My test template has 1 for the first document and the ID of the second document is a very large number. Using this large number also causes INVALID_REQUEST_BODY errors.
Is this actually correct and the error is somewhere else? Because it looks like it should work this way. Or is the problem located somewhere else?

The workflow that you are trying is a perfect place to use a composite template. The recommendation is use one composite template per document. In one POST envelopes call you can swap out the documents on the templates with documents at runtime and apply server (saved) templates to the documents. You can add recipients, drop recipients by not including them, and also add tabs or write values to tabs at runtime. See:
https://www.docusign.com/blog/dsdev-from-the-trenches-composite-templates
https://www.docusign.com/blog/dsdev-why-use-composite-templates

To answer my own question: This doesn't work. At least not this way.
Yes, composite templates are one way of dealing with this requirement but then again, why do multi-document templates even exist?
So the answer is quite simple: Do it the other way around.
To use a multi-document template properly, the template needs to be the starting point. Use a template and replace the files to create an evenlope instead of creating an envelope first and then applying templates to the envelope.

Related

itextsharp copy a pdf with empty fields add it to pdf , read fields only of first page

When I press a button, the items of the checkedlistbox should be written in a PDF. The PDF document has 1 page with 20 fields but it should be flexible. So if the checkedlistbox has 52 entries for example, the program creates a PDF with 3 pages (copy the pdf and add it 2 times). This works, but the fields of the following pages have the same name as the first. I hope this isn't a problem.
Then it reads the field names:
PdfReader pdfReader = new PdfReader(path);
AcroFields pdfFormFields = pdfReader.AcroFields;
foreach (KeyValuePair<string, AcroFields.Item> kvp in pdfFormFields.Fields) {
listoffieldnames.Add(kvp.Key.ToString());
}
pdfReader.Close();
My problem is, the reader only reads the fields of the first page.
the program creates a PDF with 3 pages (copy the pdf and add it 2 times). This works, but the fields of the following pages have the same name as the first. I hope this isn't a problem.
Well, this is a problem.
A PDF has only a single abstract form definition in which a field uniquely is identified by its fully qualified name. A field, on the other hand, can have multiple widgets, i.e. multiple visualizations, which may differ in display details (e.g. might use different fonts or font sizes) but which all show the same value.
Code copying multiple copies of the same source PDF into a target PDF may handle this in different ways:
It might ignore the field uniqueness issue and create a PDF with multiple form fields with the same name.
It might recognize duplicate field names and merge those fields with the same name as multiple widgets of a single field.
It might recognize duplicate field names and rename duplicates to eventually have unique names.
(If you used iTextSharp to create these copies: iTextSharp can be used in different ways to merge PDFs, either fast and dumb or not quite so fast and intelligent, implementing either the second or third option.)
How PDFs created in the dumb first way are handled by PDF viewers differs for different viewers and even different versions of the same viewer: The duplicate fields either are interpreted as multiple widgets of the same field or only one of the fields with the same name is handled as a proper field and the others are inactive / defunct.
As in your case the fields of the following pages have the same name as the first, your copying code is one of the first two types, so if multiple copies of the same field are functional at all, they represent the same single form field.

Umbraco site wide settings node

I am working with Umbraco and was wondering whether there is a easy way to create a site wise settings node.
At the moment I have this tree structure.
Content
Home
Item 1
Item 2
Item 2a
What I would like to create is something like this
SITE WIDE CONTENT
Content
Home
Item 1
Item 2
Item 2a
Site Wide Content will contain something like Google Analytics Url, that the user can change easily.
Is there a way to accomplish this?
EDIT: See bottom for a method for handling page redirects and 404 errors resulting from templateless nodes...
A common node structure may look like this which allows for site specific content - the advantage here is that all the site content resides under the home node and users can't create more content in the root (provided you've set things up properly):
Home [Contains Settings Tab]
Page 1
Page 2
Contact Us
About
Depending on how much site wide settings information, you could create a Settings tab on the Home DocumentType and store it all there (as illustrated above); or create a tree structure using a Settings node (as illustrated below):
Home
Page 1
Page 2
Contact Us
About
Settings [has General Settings tabs/properties]
Email Templates [Store other nodes that represent mail merge template for example]
Alternatively, for Global Settings/Content (where I might have multiple sites) I frequently create a separate node structure at the root to contain global settings, email templates, etc.:
Home
Page 1
Page 2
Contact Us
About
Settings [has GlobalSettings tabs/properties]
Email Templates [Store other nodes that represent mail merge template for example]
Create a Settings DocumentType to act as a folder or container, but don't give it a template and all your global/site-wide settings/data content can be organised under that.
Handling Nodes without Templates
DocumentTypes that are created without assigning/creating a Template for them (as in the case of say the Section node at the base level of the tree and it's children) will throw a 404 error when someone attempts to visit it's URL, and thus should be excluded from any navigation rendered in the website. Any user manually entering the URL that you would expect to find the node at, e.g. /settings will be presented with the default 404 error page as it doesn't exist.
There are a few ways to mitigate this:
Add a property to the DocumentType with the alias umbracoRedirect and using the ContentPicker DataType;
Create a custom 404 Error page and set up the Umbraco configuration to use that instead of the default.
If you use the first option, you can set the page that you want the user to see by default - generally the Home page.
The second option can be good if you have some custom logic (like finding closest matching page based on URL) in your 404 error page, or use something like SEO Checker to handle 404 errors and redirects for you.
A lot of this is mitigated by simply making sure those nodes aren't visible via their URL in the website at all, which can be done by coding your navigation structures (menu's, sitemaps, etc.) to exclude them.
Note: I generally make sure they are also excluded by any sitemap.xml generators so that search engines don't attempt to index them. You can also add them to your robots.txt files as well.

How to populate a docusign template using a C# dictionary?

How can I populate a docusign template using a C# dictionary via the docusign .Net client?
I read somewhere a docusign template with custom html but could not find any examples online.
the Envelope object has a couple of fields you will need:
TemplateId - is like an EnvelopeId a GUID for a unique template
TemplateRoles - is a collection of TemplateRole objects that represents the roles/recipients for this template.
In order to get this information for a given template - you would need to call use the Template class and call the GetTemplate() method/API to get all information for a template. this would include the roles/recipients (As well a more things in the json, which we just pass back as is) here is the important things:
var recipients = json["recipients"];
var subject = (string)json["emailSubject"];
var blurb = (string)json["emailBlurb"];
I can share a bit more code of looping through the recipients and adding them to the TemplateRoles if you want. Let me know if this is the direction you want to go and how else I can help.

ASP.NET MVC / C# - String to valid URL characters?

I don't know how to ask this, and I don't know what it is called either so I'll just describe what I want to achieve.
In the database, some articles' title originaly has spaces:
my title with spaces
But in the url, spaces are replaced by other characters such as plus sign (+) or underscore (_)
http://www.mydomain.com/mycontroller/myaction/my_title_with_spaces
or
http://www.mydomain.com/mycontroller/myaction/my+title+with+spaces
Now, how do you do that in C#? Or is there any helper in ASP.NET MVC that can do something like that?
Let say we achieved the said URL, is there any risk that two unique titles become the same in the URL? Please consider these titles:
Title's
Titles
after parsing, they became the same
Titles
Titles
This will be a problem when retrieving the article from the database since I'll get two results, one for "Title" and one for "Title's".
I would implement that functionality like this:
1. When creating a new article, generate the URL representation based on the title.
Use a function that converts the title for a suitable representation.
For example, the title "This is an example" might generate something like "This_is_an_example".
This is up to you. You can create a function that parses the title with rules you define, or use an existing one if it suits better your problem.
2. Ensure the URL representation is unique
If it's going to be an ID, it must be unique. So, when creating new articles you must query your database for the resulting URL representation. If you get a result from the database, it means the newly created article generated the same representation as one of the already created articles. Add something to it so it remains unique.
This could be something like "This_is_an_example_2". In this case, we added the "_2" to the end of the generated representation so it differs from the already existing one. Once more, with each change you have to ensure this representation remains unique.
3. Save the created ID in the database, along with the article data
In the database be sure to save the "This_is_an_example" ID and relate it to the article. Maybe even as the table primary key?
4. Query the database for the correct article
Now, about showing a site visitor the correct article:
When a visitor asks for the following resource, for example:
http://www.mydomain.com/mycontroller/myaction/this_is_an_example_2
Extract the URL part that identifies the article, in this case "this_is_an_example_2".
When you have that, you have the identifier of the article in the database. So, you can query the database for the article with the "this_is_an_example_2" ID and show the article's content to the user.
This might involve some URL rewriting. Unfortunately I'm unable to help you with that in asp.NET. Some search on the subject will surely help you.

Recurring calendar entries in Lotus Notes

Does somebody know if it is possible to change one of documents in a series of recurring meetings?
I changed one of them with c# api and it changed all documents in the series (e.g. 5 docs in series will be modified during one save() call)
var document = view.GetFirstDocument();
if (document != null)
{
do
{
var item = document.GetFirstItem("Repeats");
var repeat = tmpItem != null ? Convert.ToInt32(tmpItem.Text) : 0;
if(repeats)
{
document.ReplaceItemValue("myVal", "1"); //it change all my 5 docs after first save
document.Save(true, false);
}
document = view.GetNextDocument(document);
}
while (document != null);
}
From "Lotus Notes Calendar and Scheduling explained! Part 1":
the instance document of a repeating meeting can be split into multiple documents if the chair reschedules some instances. Consider a repeating meeting that repeats once a week for five weeks. If the chair advances the first and second instance by an hour, the single response document for all five instances is now split into two response documents: one for the first and the second instance and another for the remaining instances.
And from the "IBM Lotus Notes and Domino Calendaring & Scheduling Schema":
Repeating events are scheduled more than once over time and are represented by at least two notes in a parent-child relationship. The parent note is identified by its ApptUNID item (which is its note universal ID), and the child note is identified by the same ApptUNID as the parent and the original RepeatInstanceDates. The ApptUNID and RepeatInstanceDates items form a key pair of values that uniquely identify a particular repeat instance. More details are covered in the Repeat Model section of this paper.
So what you basically have to do is find the child Document of the event ($CSFlags conatins "i" and $Ref the parents UNID) and create a new (second) child document for the changed date/time, removing this particular date/time entry from the existing child document, IIRC.
In such cases, I always do that manually in the Notes Client and then compare the fields created that way with the ones I created via my code.
In the code you loop through the view and change all documents that are available in the view. You need to pick the document you want to change.
EDIT:
A repeating entry is a document shown multiple times in a view. So it is possible that you are updating the same document multiple times. Compare the UniversalID of all the documents in the series to be sure.
If you change one of the entries using the Lotus Client it will ask if you want to update all, if you select "just this instance" the entry will be saved in a new document. So a repeating entry can be a single document or a combination of documents.
The best advice, and really the only advice, that I can give you is to study the LotusScript code in the mail template, and see exactly what it does when a user changes one entry in a repeating appointment. Lotus has not documented it in any other way, but the template code is all open source and it is the ultimate authority. Your task is to be compatible with what they do in the template -- otherwise it is pretty likely that your code will have side-effects that cause problems for users who try to use the Notes client to take additional actions on the calendar event series after your code has run.

Categories

Resources