A super quick article on how to download an attachment from CRM and upload to a "file upload" field in Creator.
Why?
My use case here is that we are creating a Creator app that will show the attachments on a CRM contact record (and be clickable). The complication here is that the user can use the Creator form to add a new attachment that will eventually be uploaded back to CRM.
How?
At time of print, things have moved on and based on the Zoho official forums, this used to be a daunting task. Not anymore at least from what I've seen.
You could try adding a subform to Creator but have it as a blank form rather than a bidirectional form as in this example, the parent record doesn't yet exist... The cheat here is that we actually want the user to be able to click and download/open the attachments on the CRM record from within the Creator app. As for the add a new attachment, well that's just functionality.
Here's my Creator form (well the part for the attachments):
- An attachments section to hold a notes field.
- A notes field called "Note_Attachments" (this will display a HTML table with click-to-download files)
- A blank subform callled "Attachments" (links to a form called "Documents")

Here's the Creator form to hold the Attachments:
- Parent Record (a single line that will be a unique ref to prevent downloading the same record again and again)
- Document Name (a single line that will be the name of the file including its extension)
- Document (the file upload field)
- Downloaded (a picklist with the options "Downloaded" and "Pending Upload")

Here's the code for the parent form to download the attachments and upload them to the Creator "Document" form:
copyraw
//
// get attachments
v_NoteAttachments = "<table class='jl-table-info jl-table-attachments'>";
m_SortCriteria = Map();
m_SortCriteria.put("sort_by","Created_Time");
m_SortCriteria.put("sort_order","desc");
l_Attachments = zoho.crm.getRelatedRecords("Attachments","Contacts",v_CrmContactID,1,200,m_SortCriteria);
for each r_Attachment in l_Attachments
{
if(r_Attachment.get("id") != null)
{
v_AttachmentEndpoint = "https://www.zohoapis.com/crm/v2/Contacts/" + v_CrmContactID + "/Attachments/" + r_Attachment.get("id");
r_Download = invokeurl
[
url :v_AttachmentEndpoint
type :GET
connection:"ab_crm"
];
r_Download.setParamName("file");
r_CheckIfDocumentAlreadyExists = Document[Parent_Record == v_CrmContactID.toString() && Document_Name == r_Attachment.get("File_Name")];
if(r_CheckIfDocumentAlreadyExists.count() > 0)
{
r_NewDocumentRecord = Document[ID == r_CheckIfDocumentAlreadyExists.ID];
v_DateAdded = r_NewDocumentRecord.Added_Time.toString("E, d MMM yyyy HH:mm");
}
else
{
r_Document = insert into Document
[
Added_User=zoho.loginuser
Document_Name=r_Attachment.get("File_Name")
Document_File=r_Download
Downloaded="Downloaded"
Parent_Record=v_CrmContactID.toString()
];
r_NewDocumentRecord = Document[ID == r_Document];
v_DateAdded = r_NewDocumentRecord.Added_Time.toString("E, d MMM yyyy HH:mm");
}
v_LinkToDownload = "<a href='https://creator.zoho.com/file" + zoho.appuri + "All_Documents/" + r_NewDocumentRecord.ID + "/Document_File/download?filepath=/" + r_NewDocumentRecord.Document_File + "'>" + r_NewDocumentRecord.Document_Name + "</a>";
v_NoteAttachments = v_NoteAttachments + "<tr><td>" + v_DateAdded + "</td><td style='font-weight:700;'>" + v_LinkToDownload + "</td></tr>";
}
}
v_NoteAttachments = v_NoteAttachments + "</table>";
input.Note_Attachments = v_NoteAttachments;
- //
- // get attachments
- v_NoteAttachments = "<table class='jl-table-info jl-table-attachments'>";
- m_SortCriteria = Map();
- m_SortCriteria.put("sort_by","Created_Time");
- m_SortCriteria.put("sort_order","desc");
- l_Attachments = zoho.crm.getRelatedRecords("Attachments","Contacts",v_CrmContactID,1,200,m_SortCriteria);
- for each r_Attachment in l_Attachments
- {
- if(r_Attachment.get("id") != null)
- {
- v_AttachmentEndpoint = "https://www.zohoapis.com/crm/v2/Contacts/" + v_CrmContactID + "/Attachments/" + r_Attachment.get("id");
- r_Download = invokeUrl
- [
- url :v_AttachmentEndpoint
- type :GET
- connection:"ab_crm"
- ];
- r_Download.setParamName("file");
- r_CheckIfDocumentAlreadyExists = Document[Parent_Record == v_CrmContactID.toString() && Document_Name == r_Attachment.get("File_Name")];
- if(r_CheckIfDocumentAlreadyExists.count() > 0)
- {
- r_NewDocumentRecord = Document[ID == r_CheckIfDocumentAlreadyExists.ID];
- v_DateAdded = r_NewDocumentRecord.Added_Time.toString("E, d MMM yyyy HH:mm");
- }
- else
- {
- r_Document = insert into Document
- [
- Added_User=zoho.loginuser
- Document_Name=r_Attachment.get("File_Name")
- Document_File=r_Download
- Downloaded="Downloaded"
- Parent_Record=v_CrmContactID.toString()
- ];
- r_NewDocumentRecord = Document[ID == r_Document];
- v_DateAdded = r_NewDocumentRecord.Added_Time.toString("E, d MMM yyyy HH:mm");
- }
- v_LinkToDownload = "<a href='https://creator.zoho.com/file" + zoho.appuri + "All_Documents/" + r_NewDocumentRecord.ID + "/Document_File/download?filepath=/" + r_NewDocumentRecord.Document_File + "'>" + r_NewDocumentRecord.Document_Name + "</a>";
- v_NoteAttachments = v_NoteAttachments + "<tr><td>" + v_DateAdded + "</td><td style='font-weight:700;'>" + v_LinkToDownload + "</td></tr>";
- }
- }
- v_NoteAttachments = v_NoteAttachments + "</table>";
- input.Note_Attachments = v_NoteAttachments;
Here's the code at the end of the parent form to hide the columns I don't need the user to see (I'll populate these by code):
copyraw
hide Attachments.Parent_Record; hide Attachments.Document_Name; hide Attachments.Downloaded;
- hide Attachments.Parent_Record;
- hide Attachments.Document_Name;
- hide Attachments.Downloaded;
Here's the code I use when a "Addition of a row" workflow is triggered on that subform. This makes sure I don't download it again and create a new Creator record to hold the same file but in a new record, as well as include the marker to check when uploading the files back to CRM:
copyraw
row.Parent_Record=input.CRM_Contact; row.Downloaded="Pending Upload";
- row.Parent_Record=input.CRM_Contact;
- row.Downloaded="Pending Upload";
Here's the code I use when uploading a file to the newly added row in that subform (on user input). This sets the document name for display later:
copyraw
if(!isnull(row.Document_File))
{
v_FileDetected = row.Document_File;
if(v_FileDetected.contains("_"))
{
v_SubstringStart = v_FileDetected.indexOf("_");
v_FilenameDetected = v_FileDetected.subString(v_SubstringStart + 1);
v_FilenameFormatted = v_FilenameDetected.replaceAll("_"," ");
row.Document_Name=v_FilenameFormatted;
}
}
- if(!isnull(row.Document_File))
- {
- v_FileDetected = row.Document_File;
- if(v_FileDetected.contains("_"))
- {
- v_SubstringStart = v_FileDetected.indexOf("_");
- v_FilenameDetected = v_FileDetected.subString(v_SubstringStart + 1);
- v_FilenameFormatted = v_FilenameDetected.replaceAll("_"," ");
- row.Document_Name=v_FilenameFormatted;
- }
- }
And finally, with a bit of CSS, this is what the end product looks like:

Category: Zoho :: Article: 809



Add comment