Skip to main content

Web Templates

Contact Documents - Connection

Source
{% extends 'Layout - Contact Documents' %}
{% block header %}

{% assign CRMPortalContact = false %}

{% fetchxml CRMPortalContacts %}
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="true">
<entity name="contact">
<attribute name="fullname" />
<attribute name="emailaddress1" />
<attribute name="tt_clientcode" />
<attribute name="tt_managername" />
<attribute name="ownerid" />
<attribute name="contactid" />
<order attribute="fullname" descending="false" />
<filter type="and">
<condition attribute="contactid" operator="eq" uitype="contact" value="{{ params.id }}" />
</filter>
<link-entity name="sharepointdocumentlocation" from="regardingobjectid" to="contactid" link-type="inner" alias="ag">
<link-entity name="sharepointdocumentlocation" from="sharepointdocumentlocationid" to="parentsiteorlocation" link-type="inner" alias="ah">
<link-entity name="sharepointsite" from="sharepointsiteid" to="parentsiteorlocation" link-type="inner" alias="ai">
<filter type="and">
<condition attribute="isdefault" operator="eq" value="1" />
</filter>
</link-entity>
</link-entity>
</link-entity>
</entity>
</fetch>
{% endfetchxml %}

{% if CRMPortalContacts.results.entities.size >= 1 %}
{% assign CRMPortalContact = true %}
{% endif %}

{% if CRMPortalContact == true %}
{% include 'Contact Documents - Connection - Old - Header' %}
{% else %}
{% include 'Breadcrumbs' %}

{% assign showUKTax = false %}
{% assign showUSTax = false %}
{% assign showIrelandTax = false %}

{% assign contact = params.id %}

{% fetchxml contactConnections %}
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
<entity name="connection">
<attribute name="record2id" />
<attribute name="record2roleid" />
<attribute name="connectionid" />
<attribute name="record1id" />
<order attribute="record2id" descending="false" />
<filter type="and">
<condition attribute="record1id" operator="eq" uitype="contact" value="{{ user.id }}" />
<condition attribute="record2id" operator="eq" uitype="contact" value="{{ contact }}" />
</filter>
<filter type="or">
<condition attribute="record2roleidname" operator="like" value="%Data Approver%" />
<condition attribute="record2roleidname" operator="like" value="%Data Provider%" />
<condition attribute="record2roleidname" operator="like" value="%Documents Only%" />
<condition attribute="record2roleidname" operator="like" value="%Read Only%" />
</filter>
</entity>
</fetch>
{% endfetchxml %}

{% if contactConnections.results.entities.size >= 1 %}
{% assign connections = contactConnections.results.entities.size | minus: 1 %}
{% for i in (0...connections) %}

{% assign roleName = contactConnections.results.entities[i].record2roleid.name | split: ' - ' %}
{% unless contactConnectionRoles contains contactConnections.results.entities[i].record2roleid.name %}
{% assign contactConnectionRoles = contactConnectionRoles | append:',' | append: contactConnections.results.entities[i].record2roleid.name %}
{% endunless %}
{% case roleName[0] %}
{% when "Data Provider", "Data Approver" %}
{% assign showUKTax = true %}
{% when "US Tax" %}
{% assign showUSTax = true %}
{% when "Ireland Tax" %}
{% assign showIrelandTax = true %}
{% endcase %}
{% endfor %}
{% endif %}

{% include 'Custom Integration - Header' %}
{% endif %}
{% endblock %}

{% block main %}
{% if CRMPortalContact == true %}
{% include 'Contact Documents - Connection - Old - Main' %}
{% else %}
{% include 'WrapperAJAX' %}

<style>
#sharedDocumentsRow {
display: none;
}
</style>

<style>
a:hover {
cursor: pointer;
}
td {
padding: 5px 0px 5px 10px !important;
}
</style>

{% include 'WrapperAJAX Script' %}
{% endif %}
{% endblock %}

{% block title %}

{% if CRMPortalContact == true %}
{% include 'Contact Documents - Connection - Old - Title' %}
{% else %}
{% fetchxml documentContact %}
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
<entity name="contact">
<attribute name="fullname" />
<attribute name="contactid" />
<filter type="and">
<condition attribute="contactid" operator="eq" uitype="contact" value="{{ contact }}" />
</filter>
</entity>
</fetch>
{% endfetchxml %}

{% if documentContact.results.entities.size == 1 %}
{% assign contactFullName = documentContact.results.entities[0].fullname %}
{% else %}
{% assign contactFullName = "Contact Not Found" %}
{% endif %}

{% assign connectionRoles = "General Documents" %}
{% assign contactConnectionRoles = "" %}
{% if contactConnections.results.entities.size >= 1 %}
{% assign connections = contactConnections.results.entities.size | minus: 1 %}
{% for i in (0...connections) %}

{% assign roleName = contactConnections.results.entities[i].record2roleid.name | split: ' - ' %}
{% unless contactConnectionRoles contains contactConnections.results.entities[i].record2roleid.name %}
{% assign contactConnectionRoles = contactConnectionRoles | append:',' | append: contactConnections.results.entities[i].record2roleid.name %}
{% endunless %}

{% case roleName[0] %}
{% when "Audit" %}
{% assign folderpermission = "Audit" %}
{% unless connectionRoles contains folderpermission %}
{% assign connectionRoles = connectionRoles | append:',' | append: folderpermission %}
{% endunless %}
{% when "Accounts" %}
{% assign folderpermission = "Accounts" %}
{% unless connectionRoles contains folderpermission %}
{% assign connectionRoles = connectionRoles | append:',' | append: folderpermission %}
{% endunless %}
{% when "Business Advisory" %}
{% assign folderpermission = "Business Advisory" %}
{% unless connectionRoles contains folderpermission %}
{% assign connectionRoles = connectionRoles | append:',' | append: folderpermission %}
{% endunless %}
{% when "Corporate Finance" %}
{% assign folderpermission = "Corporate Finance" %}
{% unless connectionRoles contains folderpermission %}
{% assign connectionRoles = connectionRoles | append:',' | append: folderpermission %}
{% endunless %}
{% when "Business Tax" %}
{% assign folderpermission = "Corporation Tax" %}
{% unless connectionRoles contains folderpermission %}
{% assign connectionRoles = connectionRoles | append:',' | append: folderpermission %}
{% endunless %}
{% when "Digital" %}
{% assign folderpermission = "Digital" %}
{% unless connectionRoles contains folderpermission %}
{% assign connectionRoles = connectionRoles | append:',' | append: folderpermission %}
{% endunless %}
{% when "Employment Tax" %}
{% assign folderpermission = "Employment Tax" %}
{% unless connectionRoles contains folderpermission %}
{% assign connectionRoles = connectionRoles | append:',' | append: folderpermission %}
{% endunless %}
{% when "Ireland Business Tax" %}
{% assign folderpermission = "Ireland Business Tax" %}
{% unless connectionRoles contains folderpermission %}
{% assign connectionRoles = connectionRoles | append:',' | append: folderpermission %}
{% endunless %}
{% when "Data Provider", "Data Approver", "US Tax", "Ireland Tax" %}
{% assign folderpermission = "Personal Tax" %}
{% unless connectionRoles contains folderpermission %}
{% assign connectionRoles = connectionRoles | append:',' | append: folderpermission %}
{% endunless %}
{% when "Partnership" %}
{% assign folderpermission = "Partnerships" %}
{% unless connectionRoles contains folderpermission %}
{% assign connectionRoles = connectionRoles | append:',' | append: folderpermission %}
{% endunless %}
{% when "Payroll" %}
{% assign folderpermission = "Payroll" %}
{% unless connectionRoles contains folderpermission %}
{% assign connectionRoles = connectionRoles | append:',' | append: folderpermission %}
{% endunless %}
{% when "RandD" %}
{% assign folderpermission = "Research And Development" %}
{% unless connectionRoles contains folderpermission %}
{% assign connectionRoles = connectionRoles | append:',' | append: folderpermission %}
{% endunless %}
{% when "Risk And Assurance" %}
{% assign folderpermission = "Risk And Assurance" %}
{% unless connectionRoles contains folderpermission %}
{% assign connectionRoles = connectionRoles | append:',' | append: folderpermission %}
{% endunless %}
{% when "Trust" %}
{% assign folderpermission = "Trusts" %}
{% unless connectionRoles contains folderpermission %}
{% assign connectionRoles = connectionRoles | append:',' | append: folderpermission %}
{% endunless %}
{% when "Virtual Finance Office" %}
{% assign folderpermission = "Virtual Finance Office" %}
{% unless connectionRoles contains folderpermission %}
{% assign connectionRoles = connectionRoles | append:',' | append: folderpermission %}
{% endunless %}
{% else %}
{% assign folderpermission = 'General Documents' %}
{% unless connectionRoles contains folderpermission %}
{% assign connectionRoles = connectionRoles | append:',' | append: folderpermission %}
{% endunless %}
{% endcase %}
{% endfor %}
{% endif %}

{% assign serviceLines = connectionRoles | split: "," %}

{% assign conditions = '' %}

<h1 style="font-weight:bold;">Documents for {{ contactFullName }}</h1>

{% capture fetchquery %}
<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='true'>
<entity name='tt_contactdocuments'>
<attribute name='tt_contactdocumentsid' />
<attribute name='tt_name' />
<attribute name='createdon' />
<attribute name='tt_serviceline' />
<order attribute='tt_name' descending='false' />
<filter type='and'>
<condition attribute='tt_contact' operator='eq' uitype='contact' value='{{ contact }}' />
<condition attribute='tt_name' operator='ne' value='Private (Hidden From Client)' />
<condition attribute='tt_name' operator='ne' value='Onboarding' />
<filter type='or'>
{% for permission in serviceLines %}
{% capture condition %} <condition attribute='tt_name' operator='eq' value='{{ permission }}'/>{% endcapture %}
{{ condition }}
{% endfor %}
</filter>

</filter>
<link-entity name='sharepointdocumentlocation' from='regardingobjectid' to='tt_contactdocumentsid' link-type='inner' alias='ai'>
<link-entity name='sharepointdocumentlocation' from='sharepointdocumentlocationid' to='parentsiteorlocation' link-type='inner' alias='aj'>
<filter type='and'>
<condition attribute='name' operator='eq' value='Practice Gateway' />
</filter>
</link-entity>
</link-entity>
</entity>
</fetch>
{% endcapture %}

{% fetchxml contactDocuments %}
{{ fetchquery }}
{% endfetchxml %}
{% endif %}
{% endblock %}

{% block sidebar %}
{% if CRMPortalContact == true %}
{% include 'Contact Documents - Connection - Old - Sidebar' %}
{% else %}
{% assign defaultFolder = "" %}
<h3 style="font-size: 20px;">Please select a Folder to view documents. </h3>

{% if contactDocuments.results.entities.size >= 1 %}
<div style="overflow:hidden;height:90%">
<div id="DocumentsList" style="overflow-y: auto;height:100%;text-align: -webkit-center;">
{% assign records = contactDocuments.results.entities.size | minus: 1 %}
{% for i in (0...records) %}
{% assign contactDocumentName = contactDocuments.results.entities[i].tt_name %}
{% assign sectionName = contactDocumentName %}

<ul class="nav nav-pills nav-stacked" style="width:90%;">
<li role="presentation"id="contactDocumentNav{{ i }}">
<a onclick="ShowDocuments('contactDocumentNav{{ i }}','{{sectionName}}')"><i class="fa fa-folder-open-o" aria-hidden="true" style="float:left;"></i>{{contactDocumentName}}</a>
</li>
<p></p>
</ul>
{% endfor %}
</div>
</div>
{% endif %}
<p></p>
{% endif %}
{% endblock %}

{% block content %}
{% if CRMPortalContact == true %}
{% include 'Contact Documents - Connection - Old - Content' %}
{% else %}
{% if contactDocuments.results.entities.size >= 1 %}
{% assign records = contactDocuments.results.entities.size | minus: 1 %}
{% for i in (0...records) %}
{% assign contactDocumentName = contactDocuments.results.entities[i].tt_name %}
{% assign contactDocumentRecord = contactDocuments.results.entities[i].tt_contactdocumentsid %}
{% assign contactDocumentServiceLine = contactDocuments.results.entities[i].tt_serviceline.label %}

{% assign RecordToGetSharePointDetails = contactDocumentRecord %}
{% assign EntityLogicalName = "tt_contactdocuments" %}

{% assign serviceLineRoleRO = contactDocumentName | append: " - Read Only" %}
{% assign serviceLineRoleDO = contactDocumentName | append: " - Documents Only" %}

{% if contactDocumentName == 'Corporation Tax' %}
{% if contactConnectionRoles contains 'Business Tax' %}
{% assign serviceLineRoleRO = "Business Tax - Read Only" %}
{% assign serviceLineRoleDO = "Business Tax - Documents Only" %}
{% endif %}
{% endif %}
{% if contactDocumentName == 'Trusts' %}
{% if contactConnectionRoles contains 'Trust' %}
{% assign serviceLineRoleRO = "Trust - Read Only" %}
{% assign serviceLineRoleDO = "Trust - Documents Only" %}
{% endif %}
{% endif %}
{% if contactDocumentName == 'Partnerships' %}
{% if contactConnectionRoles contains 'Partnership' %}
{% assign serviceLineRoleRO = "Partnership - Read Only" %}
{% assign serviceLineRoleDO = "Partnership - Documents Only" %}
{% endif %}
{% endif %}
{% if contactDocumentName == 'Research And Development' %}
{% if contactConnectionRoles contains 'RandD' %}
{% assign serviceLineRoleRO = "RandD - Read Only" %}
{% assign serviceLineRoleDO = "RandD - Documents Only" %}
{% endif %}
{% endif %}
{% if contactDocumentName == 'Personal Tax' %}
{% if contactConnectionRoles contains 'Ireland Tax' %}
{% assign serviceLineRoleRO = "Ireland Tax - Read Only" %}
{% assign serviceLineRoleDO = "Ireland Tax - Documents Only" %}
{% endif %}
{% if contactConnectionRoles contains 'UK Tax' %}
{% assign serviceLineRoleRO = "UK Tax - Read Only" %}
{% assign serviceLineRoleDO = "UK Tax - Documents Only" %}
{% endif %}
{% if contactConnectionRoles contains 'US Tax' %}
{% assign serviceLineRoleRO = "US Tax - Read Only" %}
{% assign serviceLineRoleDO = "US Tax - Documents Only" %}
{% endif %}
{% endif %}

{% assign EnableUpload = true %}
{% assign EnableNewFolder = true %}
{% assign EnableDeletion = true %}
{% assign EnableCollaboration = true %}
{% assign showTable = true %}

{% assign sectionName = contactDocumentName %}
{% if contactConnectionRoles contains serviceLineRoleRO %}
{% assign EnableCollaboration = false %}
{% assign EnableUpload = false %}
{% assign EnableNewFolder = false %}
{% assign EnableDeletion = false %}
{% endif %}
{% if contactConnectionRoles contains serviceLineRoleDO %}
{% assign EnableCollaboration = false %}
{% assign EnableDeletion = false %}
{% endif %}

{% if contactDocumentName == "General Documents" %}
{% assign serviceLine = "General" %}
{% elsif contactDocumentName == "Corporation Tax" %}
{% assign serviceLine = "Business Tax" %}
{% else %}
{% assign serviceLine = contactDocumentName %}
{% endif %}

{% include 'Utility/GetSharePointDetails' %}
{% include 'Custom Integration - Main' %}
{% endfor %}
{% endif %}

<script language="javascript">
$( document ).ready(function() {
var sharedContact = "{{ contact }}";
if(sharedContact != null){
localStorage.setItem("sharedContact", sharedContact);
}
});
function ShowDocuments(navid, sectionName)
{
$('.contactDocumentLocation').hide();
$(`.contactDocumentLocation[id="${sectionName}"]`).show();
$('li[role="presentation"]').removeClass('active');
$('#' + navid).addClass('active');
}
$('#DocumentsList').find('li').eq(0).children('a').click();
</script>
{% endif %}
{% endblock %}

Contact Documents - Contact

Source
{% extends 'Layout - Contact Documents' %}
{% block header %}

{% assign CRMPortalContact = false %}

{% fetchxml CRMPortalContacts %}
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="true">
<entity name="contact">
<attribute name="fullname" />
<attribute name="emailaddress1" />
<attribute name="tt_clientcode" />
<attribute name="tt_managername" />
<attribute name="ownerid" />
<attribute name="contactid" />
<order attribute="fullname" descending="false" />
<filter type="and">
<condition attribute="contactid" operator="eq" uitype="contact" value="{{ user.id }}" />
</filter>
<link-entity name="sharepointdocumentlocation" from="regardingobjectid" to="contactid" link-type="inner" alias="ag">
<link-entity name="sharepointdocumentlocation" from="sharepointdocumentlocationid" to="parentsiteorlocation" link-type="inner" alias="ah">
<link-entity name="sharepointsite" from="sharepointsiteid" to="parentsiteorlocation" link-type="inner" alias="ai">
<filter type="and">
<condition attribute="isdefault" operator="eq" value="1" />
</filter>
</link-entity>
</link-entity>
</link-entity>
</entity>
</fetch>
{% endfetchxml %}

{% if CRMPortalContacts.results.entities.size >= 1 %}
{% assign CRMPortalContact = true %}
{% endif %}

{% if CRMPortalContact == true %}
{% include 'Contact Documents - Contact - Old - Header' %}
{% else %}
{% include 'Breadcrumbs' %}

{% assign CRMPortal = false %}


{% assign showUKTax = false %}
{% assign showUSTax = false %}
{% assign showIrelandTax = false %}

{% assign showUKTax = user | has_role: 'Personal Tax User' %}
{% assign showUSTax = user | has_role: 'US Tax User' %}
{% assign showIrelandTax = user | has_role: 'Ireland Tax User' %}

{% assign contact = user.id %}

{% include 'Custom Integration - Header' %}
{% endif %}

{% endblock %}
{% block main %}

{% if CRMPortalContact == true %}
{% include 'Contact Documents - Contact - Old - Main' %}
{% else %}
{% include 'WrapperAJAX' %}

<style>
a:hover {
cursor: pointer;
}
td {
padding: 5px 0px 5px 10px !important;
}
</style>

{% fetchxml connections %}
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="true">
<entity name="contact">
<attribute name="fullname" />
<attribute name="emailaddress1" />
<attribute name="tt_clientcode" />
<attribute name="tt_managername" />
<attribute name="ownerid" />
<attribute name="contactid" />
<order attribute="fullname" descending="false" />
<link-entity name="connection" from="record2id" to="contactid" link-type="inner" alias="av">
<filter type="and">
<filter type="or">
<condition attribute="record2roleidname" operator="like" value="%Data Approver%" />
<condition attribute="record2roleidname" operator="like" value="%Data Provider%" />
<condition attribute="record2roleidname" operator="like" value="%Documents Only%" />
<condition attribute="record2roleidname" operator="like" value="%Read Only%" />
</filter>
</filter>
<link-entity name="contact" from="contactid" to="record1id" link-type="inner" alias="aw">
<filter type="and">
<condition attribute="contactid" operator="eq" uitype="contact" value="{{ contact }}" />
</filter>
</link-entity>
</link-entity>
</entity>
</fetch>
{% endfetchxml %}
{% if connections.results.entities.size > 0 %}
<div>
<h1 style="font-weight:bold;">Shared Document Access</h1>
Contacts that you have shared documents access with are listed below. Select a contact to be able to view their documents.
</div>
<div id="contactList">
<ul class="nav nav-pills nav-justified">
{% assign connectedContacts = connections.results.entities.size | minus: 1 %}
{% assign maxPerRow = 5 %}
{% assign halfConnectedContacts = connectedContacts | divided_by: 2 | ceil %}
{% if halfConnectedContacts < 5 %}
{% assign maxPerRow = halfConnectedContacts %}
{% endif %}
{% assign rowitem = 0 %}
{% for i in (0...connectedContacts) %}
{% assign rowitem = rowitem | plus: 1 %}
{% assign contactName = connections.results.entities[i].fullname %}
{% assign contactID = connections.results.entities[i].contactid %}

<li role="presentation">
<a data-attribute="{{ i }}" href="Shared/?id={{contactID}}">{{contactName}}</a>
</li>
{% if rowitem == maxPerRow %}
</ul>
<ul class="nav nav-pills nav-justified">
{% assign rowitem = 0 %}
{% endif %}
{% endfor %}
</ul>
</div>
<br>
{% endif %}

{% if connections.results.entities.size == 0 %}
<style>
#sharedDocumentsRow {
display: none;
}
</style>
{% endif %}

{% include 'WrapperAJAX Script' %}
{% endif %}
{% endblock %}

{% block title %}

{% if CRMPortalContact == true %}
{% include 'Contact Documents - Contact - Old - Title' %}
{% else %}
{% assign showMyDocuments = true %}
{% assign MyDocumentSiteSetting = settings['Feature/HideMyDocuments'] %}

{% if MyDocumentSiteSetting == "enabled" %}
{% assign serviceLines = "Audit,Business Advisory,Corporate Finance,Business Tax,Digital,Ireland Business Tax,Organisation,Payroll,RandD,Risk And Assurance,Accounts,Employment Tax,Virtual Finance Office" | split: "," %}
{% for role in user.roles %}
{% assign roleType = role | split: " - " | first %}
{% if serviceLines contains roleType %}
{% assign showMyDocuments = false %}
{% break %}
{% endif %}
{% endfor %}
{% endif %}

{% if showMyDocuments %}
<h1 style="font-weight:bold;">My Documents</h1>
{% fetchxml contactDocuments %}
<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='true'>
<entity name='tt_contactdocuments'>
<attribute name='tt_contactdocumentsid' />
<attribute name='tt_name' />
<attribute name='createdon' />
<attribute name='tt_serviceline' />
<order attribute='tt_name' descending='false' />
<filter type='and'>
<condition attribute='tt_contact' operator='eq' uitype='contact' value='{{ contact }}' />
<condition attribute='tt_name' operator='ne' value='Private (Hidden From Client)' />
<condition attribute='tt_name' operator='ne' value='Onboarding' />
</filter>
<link-entity name='sharepointdocumentlocation' from='regardingobjectid' to='tt_contactdocumentsid' link-type='inner' alias='ai'>
<link-entity name='sharepointdocumentlocation' from='sharepointdocumentlocationid' to='parentsiteorlocation' link-type='inner' alias='aj'>
<filter type='and'>
<condition attribute='name' operator='eq' value='Practice Gateway' />
</filter>
</link-entity>
</link-entity>
</entity>
</fetch>
{% endfetchxml %}
{% endif %}
{% endif %}
{% endblock %}

{% block sidebar %}

{% if CRMPortalContact == true %}
{% include 'Contact Documents - Contact - Old - Sidebar' %}
{% else %}
{% if showMyDocuments %}
<h3 style="font-size: 20px;">Select a Folder to view your documents. </h3>

{% if contactDocuments.results.entities.size >= 1 %}
<div style="overflow:hidden;height:90%">
<div id="DocumentsList" style="overflow-y: auto;height:100%;text-align: -webkit-center;">
{% assign records = contactDocuments.results.entities.size | minus: 1 %}
{% for i in (0...records) %}
{% assign contactDocumentName = contactDocuments.results.entities[i].tt_name %}
{% assign sectionName = contactDocumentName %}

<ul class="nav nav-pills nav-stacked" style="width:90%;">
<li role="presentation"id="contactDocumentNav{{ i }}">
<a onclick="ShowDocuments('contactDocumentNav{{ i }}','{{sectionName}}')"><i class="fa fa-folder-open-o" aria-hidden="true" style="float:left;"></i>{{contactDocumentName}}</a>
</li>
<p>
</ul>
{% endfor %}
</div>
</div>
{% endif %}
</p>
{% endif %}
{% endif %}
{% endblock %}

{% block content %}

{% if CRMPortalContact == true %}
{% include 'Contact Documents - Contact - Old - Content' %}
{% else %}
{% if showMyDocuments %}
{% if contactDocuments.results.entities.size >= 1 %}
{% assign records = contactDocuments.results.entities.size | minus: 1 %}
{% for i in (0...records) %}
{% assign contactDocumentName = contactDocuments.results.entities[i].tt_name %}
{% assign contactDocumentRecord = contactDocuments.results.entities[i].tt_contactdocumentsid %}
{% assign contactDocumentServiceLine = contactDocuments.results.entities[i].tt_serviceline.label %}

{% assign RecordToGetSharePointDetails = contactDocumentRecord %}
{% assign EntityLogicalName = "tt_contactdocuments" %}
{% assign EnableUpload = true %}
{% assign EnableNewFolder = true %}
{% assign EnableDeletion = true %}
{% assign EnableCollaboration = true %}
{% assign sectionName = contactDocumentName %}
{% assign showTable = true %}

{% if contactDocumentName == "General Documents" %}
{% assign serviceLine = "General" %}
{% else %}
{% assign serviceLine = contactDocumentName %}
{% endif %}

{% include 'Utility/GetSharePointDetails' %}
{% include 'Custom Integration - Main' %}
{% endfor %}
{% endif %}

<script language="javascript">
function ShowDocuments(navid, sectionName)
{
$('.contactDocumentLocation').hide();
$(`.contactDocumentLocation[id="${sectionName}"]`).show();
$('li[role="presentation"]').removeClass('active');
$('#' + navid).addClass('active');
}
$('#DocumentsList').find('li').eq(0).children('a').click();
</script>
{% endif %}
{% endif %}
{% endblock %}

Contact Documents - Details

Source
{% extends 'Layout - Contact Documents Details' %}

{% block main %}

{% include 'WrapperAJAX' %}
{% include 'Page Copy' %}

{% fetchxml documentdetails %}
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
<entity name="tt_contactdocuments">
<attribute name="tt_contactdocumentsid" />
<attribute name="tt_name" />
<attribute name="tt_contact" />
<filter type="and">
<condition attribute="tt_contactdocumentsid" operator="eq" value="{{ params.id }}" />
</filter>
</entity>
</fetch>
{% endfetchxml %}

{% if documentdetails.results.entities.size >= 1 %}
{% assign DocumentName = documentdetails.results.entities[0].tt_name %}
{% assign contactID = documentdetails.results.entities[0].tt_contact.id %}
{% else %}
{% assign DocumentName = "Document Not Found" %}
{% endif %}

{% assign showUKTax = false %}
{% assign showUSTax = false %}
{% assign showIrelandTax = false %}

{% assign showUKTax = user | has_role: 'Personal Tax User' %}
{% assign showUSTax = user | has_role: 'US Tax User' %}
{% assign showIrelandTax = user | has_role: 'Ireland Tax User' %}

<h2>{{DocumentName}}</h2>
{% if user.id != contactID %}
{% assign connectionType = "" %}
{% case DocumentName %}
{% when "Audit" %}
{% assign connectionType = "Audit" %}
{% when "Business Advisory" %}
{% assign connectionType = "Business Advisory" %}
{% when "Corporation Tax" %}
{% assign connectionType = "Business Tax" %}
{% when "Corporate Finance" %}
{% assign connectionType = "Corporate Finance" %}
{% when "Digital" %}
{% assign connectionType = "Digital" %}
{% when "Personal Tax" %}
{% assign connectionType = "Data" %}
{% when "Partnerships" %}
{% assign connectionType = "Partnership" %}
{% when "Payroll" %}
{% assign connectionType = "Payroll" %}
{% when "Research And Development" %}
{% assign connectionType = "RandD" %}
{% when "Risk And Assurance" %}
{% assign connectionType = "Risk And Assurance" %}
{% when "Trusts" %}
{% assign connectionType = "Trust" %}
{% endcase %}

{% fetchxml contactConnections %}
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
<entity name="connection">
<attribute name="record2id" />
<attribute name="record2roleid" />
<attribute name="connectionid" />
<order attribute="record2id" descending="false" />
<filter type="and">
<condition attribute="record1id" operator="eq" uitype="contact" value="{{user.id}}" />
<condition attribute="record2id" operator="eq" uitype="contact" value="{{contactID}}" />
<condition attribute="record2roleidname" operator="like" value="%{{connectionType}}%" />
</filter>
</entity>
</fetch>
{% endfetchxml %}


{% fetchxml UKTaxConnections %}
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
<entity name="connection">
<attribute name="record2id" />
<attribute name="record2roleid" />
<attribute name="connectionid" />
<order attribute="record2id" descending="false" />
<filter type="and">
<condition attribute="record1id" operator="eq" uitype="contact" value="{{user.id}}" />
<condition attribute="record2id" operator="eq" uitype="contact" value="{{contactID}}" />
<filter type="or">
<condition attribute="record2roleidname" operator="eq" value="Data Approver" />
<condition attribute="record2roleidname" operator="eq" value="Data Provider" />
</filter>
</filter>
</entity>
</fetch>
{% endfetchxml %}

{% if UKTaxConnections.results.entities.size > 0 %}
{% assign showUKTax = true %}
{% else %}
{% assign showUKTax = false %}
{% endif %}

{% fetchxml USTaxConnections %}
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
<entity name="connection">
<attribute name="record2id" />
<attribute name="record2roleid" />
<attribute name="connectionid" />
<order attribute="record2id" descending="false" />
<filter type="and">
<condition attribute="record1id" operator="eq" uitype="contact" value="{{user.id}}" />
<condition attribute="record2id" operator="eq" uitype="contact" value="{{contactID}}" />
<condition attribute="record2roleidname" operator="like" value="%US Tax%" />
</filter>
</entity>
</fetch>
{% endfetchxml %}

{% if USTaxConnections.results.entities.size > 0 %}
{% assign showUSTax = true %}
{% else %}
{% assign showUSTax = false %}
{% endif %}

{% fetchxml IrelandTaxConnections %}
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
<entity name="connection">
<attribute name="record2id" />
<attribute name="record2roleid" />
<attribute name="connectionid" />
<order attribute="record2id" descending="false" />
<filter type="and">
<condition attribute="record1id" operator="eq" uitype="contact" value="{{user.id}}" />
<condition attribute="record2id" operator="eq" uitype="contact" value="{{contactID}}" />
<condition attribute="record2roleidname" operator="like" value="%Ireland Tax%" />
</filter>
</entity>
</fetch>
{% endfetchxml %}

{% if IrelandTaxConnections.results.entities.size > 0 %}
{% assign showIrelandTax = true %}
{% else %}
{% assign showIrelandTax = false %}
{% endif %}

{% assign roleType = "" %}
{% if contactConnections.results.entities.size == 1 %}
{% assign connections = contactConnections.results.entities.size %}
{% assign role = contactConnections.results.entities[0].record2roleid.name %}

{% if role == "Data Approver" OR %}
{% assign roleType = role %}
{% elsif role == "Data Provider" %}
{% assign roleType = role %}
{% else %}
{% assign roleName = contactConnections.results.entities[0].record2roleid.name | split: ' - ' %}
{% assign roleType = roleName[1] %}
{% endif %}

{% endif %}

{% if roleType == "Documents Only" %}
<script language="javascript">
$(document).ready(function ()
{
//Set SharePoint grid read-only
var hideActionMenu = setInterval(function()
{
if ($("td[aria-label='action menu']").length)
{
$("td[aria-label='action menu']").hide();
clearInterval(hideActionMenu);
}
}, 100); // check every 100ms

var AddClickListener = setInterval(function()
{
if ($("button[aria-label='Add files']"))
{
$("button[aria-label='Add files']").on("click", function()
{
location.reload();
}
);
clearInterval(AddClickListener);
}
}, 100); // check every 100ms
});
</script>
{% endif %}

{% if roleType == "Read Only" %}
<script language="javascript">
//Set SharePoint grid read-only
$(document).ready(function ()
{
$(".grid-actions").hide();
var hideActionMenu = setInterval(function()
{
if ($("td[aria-label='action menu']").length)
{
$("td[aria-label='action menu']").hide();
clearInterval(hideActionMenu);
}
}, 100); // check every 100ms
});
</script>
{% endif %}
{% endif %}

<script language="javascript">
var showUSTaxFolder = "{{showUSTax}}";
var showUKTaxFolder = "{{showUKTax}}";
var showIrelandTaxFolder = "{{showIrelandTax}}";
</script>

{% if DocumentName == "Research And Development" %}
<h5>Once a Document has been uploaded, it can take a couple of minutes until collaboration is enabled. Please refresh the page to reload the collaboration links.</h5>
{% editable snippets 'PracticeGateway/JS/DocumentsGridMutationObserver/DocumentCollaboration' %}
{%comment%}Hide Add Folder button temporarily for R&D{%endcomment%}
{% else %}
{% editable snippets 'PracticeGateway/JS/SharedDocumentsGridMutationObserver' %}
{% endif %}


{% entityform id: page.adx_entityform.id %}

{% include 'Utilities' %}

{% endblock %}

Custom Integration

Source
{% extends 'Layout 1 Column' %}

{% block header %}

{% include 'Breadcrumbs' %}

{% endblock %}

{% block main %}
{% include 'WrapperAJAX' %}

{% assign contact = user.id %}

{% include 'Custom Integration - Header' %}


{% assign TaxInformationRequestID = "c53a10e3-82fd-ee11-9f89-6045bdd158eb" %}

{% fetchxml contactDocuments %}
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
<entity name="tt_contactdocuments">
<attribute name="tt_contactdocumentsid" />
<attribute name="tt_name" />
<attribute name="createdon" />
<order attribute="tt_name" descending="false" />
<filter type="and">
<condition attribute="tt_taxinformationrequest" operator="eq" uitype="tt_taxinformationrequest" value="{{ TaxInformationRequestID }}" />
</filter>
</entity>
</fetch>
{% endfetchxml %}

{% if contactDocuments.results.entities.size >= 1 %}
{% assign records = contactDocuments.results.entities.size | minus: 1 %}
{% for i in (0...records) %}
{% assign contactDocumentName = contactDocuments.results.entities[i].tt_name %}
{% assign contactDocumentRecord = contactDocuments.results.entities[i].tt_contactdocumentsid %}
{% assign contactDocumentServiceLine = contactDocuments.results.entities[i].tt_serviceline.label %}

{% assign RecordToGetSharePointDetails = contactDocumentRecord %}
{% assign EntityLogicalName = "tt_contactdocuments" %}
{% assign EnableUpload = true %}
{% assign EnableNewFolder = true %}
{% assign EnableDeletion = true %}
{% assign EnableCollaboration = false %}
{% assign sectionName = contactDocumentName %}
{% assign showTable = true %}

{% assign serviceLine = "Personal Tax" %}

{% include 'Utility/GetSharePointDetails' %}
{% include 'Custom Integration - Main' %}

<script>
var sectionName = "{{ sectionName }}";
// Get the div with the id matching sectionName
var documentSectionDiv = $(`.contactDocumentLocation[id="${sectionName}"]`);
// Select the h2 element with the specified section name
var sectionH2 = $('.section-title').filter(function() {
return $(this).text().trim() === sectionName;
});

// Get the next sibling element (the div)
var sectionDiv = sectionH2.next();
// Find the table within sectionDiv
var sectiontables = sectionDiv.find('table');

// Check if there are at least two tables
if (sectiontables.length >= 2) {
// Get the penultimate table
var penultimateTable = sectiontables.eq(sectiontables.length - 2);

// Insert the documentSectionDiv after the penultimate table
documentSectionDiv.insertAfter(penultimateTable);
} else {
// If there are fewer than two tables, just append documentSectionDiv at the end of sectionDiv
sectionDiv.append(documentSectionDiv);
}
$(`.contactDocumentLocation[id="${sectionName}"]`).find('h1').text(`Documents`)
</script>

{% endfor %}
{% endif %}


{% include 'WrapperAJAX Script' %}

{% endblock %}

Custom Integration - Header

Source
{% assign GetSharePointFilesUrl = snippets["PracticeGateway/Config/SharePoint/GetFilesAPI"] %}
{% assign GetSharePointFilesEditorUrl = snippets["PracticeGateway/Config/SharePoint/GetFileEditorAPI"] %}
{% assign UploadSharePointFileUrl = snippets["PracticeGateway/Config/SharePoint/UploadFileAPI"] %}
{% assign DeleteSharePointFileUrl = snippets["PracticeGateway/Config/SharePoint/DeleteFileAPI"] %}
{% assign DownloadSharePointFileUrl = snippets["PracticeGateway/Config/SharePoint/DownloadFileAPI"] %}
{% assign CreateSharePointFolderUrl = snippets["PracticeGateway/Config/SharePoint/CreateFolderAPI"] %}
{% assign GrantCollaborationUrl = snippets["PracticeGateway/Config/SharePoint/GrantCollaborationAPI"] %}
{% assign emailTeamsUrl = snippets["PracticeGateway/Config/SharePoint/EmailTeamsAPI"] %}

{% comment %} HTTP Requests for AI Extraction {% endcomment %}
{% assign AI_UK_TR_Employments = snippets["PracticeGateway/Config/SharePoint/AI/UKTaxReturn/Employments"] %}
{% assign AI_Funds_TIR_PriorYearK1 = snippets["PracticeGateway/Config/SharePoint/AI/FundsTIR/PriorYearK1"] %}

{% comment %} Setting to enable AI Extraction across all Entities {% endcomment %}
{% assign AIExtractionEnabled = settings['PracticeGateway/Config/AIExtraction'] %}
{% assign AIFundsTIRTesting = settings['PracticeGateway/Config/AIExtraction/FundsTIR/Testing'] %}
<script>
{% include 'Custom Integration - SharePoint Functions' %}
{% include 'Custom Integration - JavaScript' %}
let ascendingOrder = true;
</script>

{% include 'Custom Integration - Modals' %}

{% include 'Custom Integration - Team Notifications' %}

<style>
a:hover {
cursor: pointer;
}
td {
padding: 5px 0px 5px 10px !important;
}
</style>

Custom Integration - JavaScript

Source
// Asynchronous function to populate a table with data
async function PopulateTable(data, sectionName)
{
const sectionSharePointSite = $(`span[id='${sectionName} details']`).data('sharepointsite');
var sectionCurrentFolder = $(`span[id='${sectionName} details']`).data('currentfolder');
const sectionRootFolder = $(`span[id='${sectionName} details']`).data('rootfolder');
const enableDeletion = $(`span[id='${sectionName} details']`).data('enabledeletion');
const enableCollaboration = $(`span[id='${sectionName} details']`).data('enablecollaboration');

// Convert the string to a boolean
const isDeletionEnabled = enableDeletion.toLowerCase() === 'true';
const isCollaborationEnabled = enableCollaboration.toLowerCase() === 'true';

$(`div[id="${sectionName}"]`).find(`ul#pagination-list[data-attribute="${sectionName}"]`).remove()
// Extract unique editorIds from the provided data
//const editorIds = [...new Set(data.map(item => item.EditorId))];

// Fetch editor results for the editorIds from SharePoint using an asynchronous function
//const editorResults = await GetSharePointFileEditors({ "SharePoint Site": sectionSharePointSite, "EditorId": editorIds });

// Initialize an empty string to store table rows
let tableRows = '';

// Initialize default page Number
let pageNumber = 1;

// Iterate through each item in the provided data, pass in the items index
data.forEach((item, index) => {
// Find the corresponding editor for the current item
//const editor = editorResults.find(editor => editor.EditorID === item.EditorId);

// If an editor is found, update the item's EditorName
// if (editor)
// {
// item.EditorName = editor.EditorName;
// }

// Allocate 10 items per page
pageNumber = Math.floor(index / 15) + 1;

item.EditorName = "SharePoint App";

// Determine the item type (Folder or File) based on FileSystemObjectType
const itemType = item.FileSystemObjectType === 1 ? "Folder" : "File";

const itemModified = new Date(item.Modified);

// Extract day, month, and year components from the Date object
const day = itemModified.getDate();
const month = itemModified.getMonth() + 1; // Months are zero-based, so we add 1
const year = itemModified.getFullYear();

// Create a formatted string representing the modification date
const modifiedOn = `${day}-${month}-${year}`;

// Determine the icon based on the item type
const icon = itemType === "Folder" ? '<i class="fa fa-folder-open-o fa-lg" aria-hidden="true"></i> ' : '<i class="fa fa-file-o fa-lg" aria-hidden="true"></i> ';

const fontSize = "16px"; // Set your desired font size here

// Create a table row HTML string for the current item
const tableRow = `<tr data-id="${itemType}" data-entity="fullName" page-number="${pageNumber}" data-name="${item.FileLeafRef}" style="text-align: center;">
<td data-type="System.String" data-attribute="tt_name" aria-readonly="true" data-th="Name" aria-label="${item.FileLeafRef}">
<div style="display: flex; align-items: center; justify-content: center;">
<div style="flex: 1; text-align: left;">
<a id="${itemType}" title="${itemType === 'File' ? `Download File` : `Open Folder`}" onclick="${itemType === 'File' ? `downloadFile('${item.FileLeafRef}','${item.Id}','${sectionName}')` : `OpenFolder('/${item.FileLeafRef}', 0, '${sectionName}')`}" style="font-size: ${fontSize};padding-right: 10px;">
${icon}
</a>
</div>
<div style="flex: 11; font-size: ${fontSize}; text-align: left;">
<a id="${itemType}" title="${itemType === 'File' ? `Download File` : `Open Folder`}" onclick="${itemType === 'File' ? `downloadFile('${item.FileLeafRef}','${item.Id}','${sectionName}')` : `OpenFolder('/${item.FileLeafRef}', 0, '${sectionName}')`}">
${item.FileLeafRef}
</a>
</div>
</div>
</td>
<!-- <td data-type="System.String" data-attribute="tt_id" data-value="${item.Id}" aria-readonly="true" data-th="ID" aria-label="${item.Id}" style="font-size: ${fontSize};">${item.Id}</td> -->
<td data-type="System.String" data-attribute="tt_modifiedOn" data-value="${modifiedOn}" aria-readonly="true" data-th="Modified On" aria-label="${modifiedOn}" style="font-size: ${fontSize};">${modifiedOn}</td>
<!-- <td data-type="System.String" data-attribute="tt_modifiedBy" data-value="${item.EditorName}" aria-readonly="true" data-th="Modified By" aria-label="${item.EditorName}" style="font-size: ${fontSize};">${item.EditorName}</td> -->
<td data-type="System.String" data-attribute="tt_Actions" data-value="${item.Collaboration_x0020_Url}" aria-readonly="true" data-th="Actions" aria-label="${item.Collaboration_x0020_Url}" style="font-size: ${fontSize}; text-align: center;">
${isCollaborationEnabled ? `<a title="Collaborate on File" id="collaborationLink${itemType}" href="${item.Collaboration_x0020_Url}" target="_blank"><i class="fa fa-pencil-square-o fa-lg" aria-hidden="true"></i></a>` : ''}
<a id="downloadLink${itemType}" title="Download File" onclick="downloadFile('${item.FileLeafRef}','${item.Id}','${sectionName}')"><i class="fa fa-download fa-lg" aria-hidden="true"></i></a>
${isDeletionEnabled ? `<a title="Delete File" id="deletionLink${itemType}" onclick="openDeleteModal('${item.FileLeafRef.replace(/'/g, "\\'")}', '${item.Id}', '${sectionName}')"><i class="fa fa-trash fa-lg" aria-hidden="true"></i></a>` : ''}
</td>
</tr>`;

// Concatenate the current table row to the overall tableRows string
tableRows += tableRow;
});

//Create the navigation buttons for the pages
const sectionPages = `<nav aria-label="Page navigation" style="text-align: center;">
<ul class="pagination" id="pagination-list" data-attribute="${sectionName}">
</ul>
</nav>`

// Set the innerHTML of the table body for the section to the constructed tableRows
$(`div[id="${sectionName}"]`).find(`tbody[id="${sectionName}"]`)[0].innerHTML = tableRows;

// Set the innerHTML of the table body for the section to the constructed tableRows
$(`div[id="${sectionName}"]`).find(`tbody[id="${sectionName}"]`)[0].innerHTML = tableRows;

// If there is more than one page, show the navigation
if(pageNumber > 1)
{
$(`div[id="${sectionName}"]`).append(sectionPages);
}

const paginationList = $(`div[id="${sectionName}"]`).find(`ul#pagination-list[data-attribute="${sectionName}"]`);

// Append the Page buttons to the navigation
for (var i = 1; i <= pageNumber; i++) {
var listItem = $(`<li id="${sectionName}${i}"></li>`);
var link = `<a onclick="ChangeDocumentsPage('${sectionName}', ${i})">${i}</a>`;
listItem.append(link);
paginationList.append(listItem); // Append the listItem at the end of paginationList
}

//Display the rows in the table
$(`div[id="${sectionName}"]`).find(`tbody[id="${sectionName}"]`).show();

if (data.length === 0) {
$(`div[id="${sectionName}"]`).find(`div[id="${sectionName} NoDocuments"]`).show();
}

// Remove specific elements by their IDs and href attribute value
$('a#collaborationLinkFile[href="null"], a#collaborationLinkFolder, a#downloadLinkFolder, a#deletionLinkFolder').remove();

// Hide the element with the ID loadingMessage
$(`div[id="${sectionName}"]`).find(`div[id="${sectionName} Loading"]`).hide();


// Create a breadcrumb for folders using template literals
var folderBreadcrumb = `<li><a href="#" data-folderpath="" onclick="OpenFolder(null,1,'${sectionName}')" title="${sectionRootFolder}">${sectionRootFolder}</a></li>`;

// Split the path of the current folder into an array of parts using "/" as the delimiter
var pathParts = sectionCurrentFolder.split("/");

// Find the index of the sectionRootFolder in the path array
var rootFolderIndex = pathParts.indexOf(sectionRootFolder);

// Ensure that sectionRootFolder is found in the path and it's not the last element
if (rootFolderIndex !== -1 && rootFolderIndex < pathParts.length - 1) {
// Slice the array starting from the index after sectionRootFolder, then join the remaining parts back into a string
var subFolders = pathParts.slice(rootFolderIndex + 1).join("/");

// If there are subFolders, add them to the breadcrumb
if (subFolders.length > 0) {
// Split the subFolders string into an array using "/" as the delimiter
var breadcrumbFolders = subFolders.split("/");

// Generate breadcrumb HTML by mapping each folder to a list item with a link
folderBreadcrumb += breadcrumbFolders.map(folder => `<li><a href="#" data-folderpath="/${folder}" onclick="OpenFolder('/${folder}', 1, '${sectionName}')" title="${folder}">${folder}</a></li>`).join('');
}
}

//Always load the first page by default
ChangeDocumentsPage(sectionName, 1);

// Set the innerHTML of the breadcrumb container (#documentsBreadcrumb)
$(`div[id="${sectionName}"]`).find('ol#documentsBreadcrumb')[0].innerHTML = folderBreadcrumb;

removeGuidsFromFolders()
}

function removeGuidsFromFolders()
{
const guidRegex = /_[A-Fa-f0-9]{32}/;

// Select all tr elements with data-id="Folder"
const rows = document.querySelectorAll('tr[data-id="Folder"]');
//Resolve Folder Guids in Table
rows.forEach(row => {
// Get the data-name attribute value
const dataName = row.getAttribute('data-name');

// Check if data-name contains a GUID
const match = dataName.match(guidRegex);
if (match) {
// Get the GUID from the match
const guid = match[0];

// Find the <a> elements within the row
const aElements = row.querySelectorAll('a#Folder');

// Iterate through each <a> element and update its text
aElements.forEach(a => {
// Iterate over child nodes of the <a> element
a.childNodes.forEach(child => {
if (child.nodeType === Node.TEXT_NODE) {
// Update the text content of the text node
const newText = child.textContent.replace(guid, '');
child.textContent = newText;
}
});
});
}
});

const links = document.querySelectorAll('#documentsBreadcrumb a');
//Resolve Folder Guids in Breadcrumbs
links.forEach(link => {
// Get the data-folderpath attribute value
const folderPath = link.getAttribute('data-folderpath');

// Check if data-folderpath contains a GUID
const match = folderPath.match(guidRegex);
if (match) {
// Get the GUID from the match
const guid = match[0];

// Update the text content of the <a> element
const newText = link.textContent.replace(guid, '');
link.textContent = newText;
}
});
}

function ChangeDocumentsPage(sectionName, pageNumber)
{
$(`div[id="${sectionName}"]`).find(`ul#pagination-list[data-attribute="${sectionName}"]`).find(`li`).removeClass('active');
$(`div[id="${sectionName}"]`).find(`ul#pagination-list[data-attribute="${sectionName}"]`).find(`li[id="${sectionName}${pageNumber}"]`).addClass('active');
$(`div[id="${sectionName}"]`).find(`tbody[id="${sectionName}"]`).find(`tr`).hide()
$(`div[id="${sectionName}"]`).find(`tbody[id="${sectionName}"]`).find(`tr[page-number="${pageNumber}"]`).show()

if(sectionName == "Personal Tax")
{
var showUKTax = '{{ showUKTax }}';
var showUSTax = '{{ showUSTax }}';
var showIrelandTax = '{{ showIrelandTax }}';

if(showIrelandTax != "true")
{
$('tr[data-name="Ireland Tax Returns"]').hide();
}
if(showUKTax != "true")
{
$('tr[data-name="UK Tax Returns"]').hide();

}
if(showUSTax != "true")
{
$('tr[data-name="US Tax Returns"]').hide();
}
}
}

// Async function to open a folder
async function OpenFolder(folderName, location, sectionName)
{
const sectionSharePointSite = $(`span[id='${sectionName} details']`).data('sharepointsite');
const sectionDocumentLibrary = $(`span[id='${sectionName} details']`).data('documentlibrary');
const sectionRelativePath = $(`span[id='${sectionName} details']`).data('relativepath');
const sectionSite = $(`span[id='${sectionName} details']`).data('site');
var sectionCurrentFolder = $(`span[id='${sectionName} details']`).data('currentfolder');
const sectionDocumentEntity = $(`span[id='${sectionName} details']`).data('documententity');
const sectionFolderPath = $(`span[id='${sectionName} details']`).data('folderpath');

//Hide sections while loading folder
$(`div[id="${sectionName}"]`).find(`div[id="${sectionName} NoDocuments"]`).hide();
$(`div[id="${sectionName}"]`).find(`tbody[id="${sectionName}"]`).hide();
$(`div[id="${sectionName}"]`).find(`div[id="${sectionName} Loading"]`).show();

$(`div[id="${sectionName}"]`).find(`ul#pagination-list[data-attribute="${sectionName}"]`).remove()

// Variable to store the new breadcrumb
var newBreadcrumb = "";

// Check if folderName is null
if (folderName == null) {

$(`span[id='${sectionName} details']`).data('currentfolder', sectionFolderPath);
sectionCurrentFolder = $(`span[id='${sectionName} details']`).data('currentfolder');
}
// Check if location is 1 (indicating a specific location)
else if (location == 1) {
var breadcrumb = "";
// Iterate over each list item anchor element with data-folderpath attribute
$(`div[id="${sectionName}"]`).find('#documentsBreadcrumb li a[data-folderpath]').each(function () {
breadcrumb += $(this).attr('data-folderpath');
// Check if the data-folderpath attribute matches the provided folderName
if ($(this).attr('data-folderpath') == folderName) {
newBreadcrumb = breadcrumb;
}
});
var newPath = sectionFolderPath + newBreadcrumb
$(`span[id='${sectionName} details']`).data('currentfolder', newPath);

sectionCurrentFolder = $(`span[id='${sectionName} details']`).data('currentfolder');
}
// Check if location is 0 (indicating a general location)
else if (location == 0) {
sectionCurrentFolder += folderName;
$(`span[id='${sectionName} details']`).data('currentfolder', sectionCurrentFolder);

sectionCurrentFolder = $(`span[id='${sectionName} details']`).data('currentfolder');
}

// Create a body object with SharePoint site, document library, folder path, and document entity
const body = {
"SharePoint Site": sectionSharePointSite,
"Document Library": sectionDocumentLibrary,
"Folder Path": `sites/${sectionSite}${sectionCurrentFolder}`,
"Document Entity": sectionDocumentEntity
};

// Show loading message
$(`div[id="${sectionName}"]`).find(`div[id="${sectionName} Loading"]`).show();

// Call GetSharePointFiles function with the body object
const getResults = await GetSharePointFiles(body);

// Check if getResults is truthy
if (getResults) {
// Call PopulateTable function with the results and hide loading message
await PopulateTable(getResults, sectionName);
$(`div[id="${sectionName}"]`).find(`div[id="${sectionName} Loading"]`).hide();

}
}

// Function to open a delete confirmation modal
function openDeleteModal(fileName, fileID, sectionName) {
// Set the file name in the modal
document.querySelector('#DeleteModal .sp-item-name span span').innerText = fileName;

// Attach a click event handler to the "Delete" button in the modal
$('div#DeleteModal button[aria-label="Delete"]').click(() => deleteFile(fileID, sectionName));

// Open the delete confirmation modal
$("#DeleteModal").modal();
}

// Function to open a modal by ID
function openModal(modalid, sectionName) {
// Use jQuery to open the modal with the specified ID
$("#" + modalid).modal();

// Add the onclick function for the "Add Files" button
$("#" + modalid).find("#addFilesButton").on("click", function () {
UploadFile(sectionName);
});
$("#" + modalid).find("#createFolderButton").on("click", function () {
CreateFolder(sectionName);
});
}

async function NotifyTeam(sectionName, serviceLine, sectionCurrentFolder)
{
console.log("Notifying Team")
var teamToNotify = serviceLine;
var lastEmailSent = $(`span[id='LastEmailSentdetails']`).data(`${serviceLine}`);

if(serviceLine == "Personal Tax")
{
console.log(`sectionCurrentFolder: ${sectionCurrentFolder}`);
if (sectionCurrentFolder.includes("UK Tax Returns")) {
var lastEmailSent = $(`span[id='LastEmailSentdetails']`).data(`UK Tax`);
var teamToNotify = "UK Tax";
serviceLine = "UK Tax";
}
if (sectionCurrentFolder.includes("US Tax Returns")) {
var lastEmailSent = $(`span[id='LastEmailSentdetails']`).data(`US Tax`);
var teamToNotify = "US Tax";
serviceLine = "US Tax";
}
if (sectionCurrentFolder.includes("Ireland Tax Returns")) {
var lastEmailSent = $(`span[id='LastEmailSentdetails']`).data(`Ireland Tax`);
var teamToNotify = "Ireland Tax";
serviceLine = "Ireland Tax";
}
}

console.log(`teamToNotify: ${teamToNotify}`);
console.log(`lastEmailSent: ${lastEmailSent}`);

var lastEmailSentDate = lastEmailSent ? new Date(lastEmailSent) : null;
var currentDate = new Date();

// If lastEmailSent is not set, or the difference is greater than 10 minutes
if (!lastEmailSentDate || (currentDate - lastEmailSentDate) / (1000 * 60) > 10) {

$(`span[id='LastEmailSentdetails']`).data(`${serviceLine}`, currentDate);
console.log("Last email was sent over 10 minutes ago, or it has not yet been set.");

const sectionContact = $(`span[id='${sectionName} details']`).data('contact');
// Create body for upload request
const notificationbody = {
"Contact" : sectionContact,
"ServiceLine" : teamToNotify
};

var notificationResponse = NotifyTeamOfFileUpload(notificationbody);
console.log(`notificationResponse: ${notificationResponse}`);

var fieldsToUpdate = await getLastEmailedFields(teamToNotify)
console.log("fieldsToUpdate");
console.log(fieldsToUpdate);
if(fieldsToUpdate)
{
var updateresponse = await UpdateEntityFields("contacts", sectionContact, fieldsToUpdate);

if(updateresponse)
{
console.log("Record Updated")
}
}


} else {
console.log("Last email was sent within the last 10 minutes.");
}
}

async function UpdateEntityFields(entityLogicalName, recordID, payload)
{
return new Promise((resolve) => {
webapi.safeAjax({
type: "PATCH",
url: "/_api/" + entityLogicalName + "(" + recordID + ")",
contentType: "application/json",
data: JSON.stringify(payload),
success: function (res) {
setTimeout(() => {
resolve("Record Has Been Submitted");
}, 10);
}
});
});
};

async function getLastEmailedFields(teamToNotify)
{
const notificationFields = [
{
"ServiceLines": [ "Personal Tax", "Ireland Tax" ],
"LastEmailedField": "tt_lastemailsentirelandtax"
},
{
"ServiceLines": [ "Personal Tax", "UK Tax" ],
"LastEmailedField": "tt_lastemailsentuktax"
},
{
"ServiceLines": [ "Personal Tax", "US Tax" ],
"LastEmailedField": "tt_lastemailsentustax"
},
{
"ServiceLines": [ "Audit" ],
"LastEmailedField": "tt_lastemailsentaudit"
},
{
"ServiceLines": [ "Accounts" ],
"LastEmailedField": "tt_lastemailsentaccounts"
},
{
"ServiceLines": [ "Business Advisory" ],
"LastEmailedField": "tt_lastemailsentbusinessadvisory"
},
{
"ServiceLines": [ "Corporate Finance" ],
"LastEmailedField": "tt_lastemailsentcorporatefinance"
},
{
"ServiceLines": [ "Corporation Tax" ],
"LastEmailedField": "tt_lastemailsentbusinesstax"
},
{
"ServiceLines": [ "Digital" ],
"LastEmailedField": "tt_lastemailsentdigital"
},
{
"ServiceLines": [ "Employment Tax" ],
"LastEmailedField": "tt_lastemailsentemploymenttax"
},
{
"ServiceLines": [ "Funds Tax" ],
"LastEmailedField": "tt_lastemailsentfundstax"
},
{
"ServiceLines": [ "General Documents" ],
"LastEmailedField": "tt_lastemailsentgeneral"
},
{
"ServiceLines": [ "Ireland Business Tax" ],
"LastEmailedField": "tt_lastemailsentirelandbts"
},
{
"ServiceLines": [ "Partnerships" ],
"LastEmailedField": "tt_lastemailsentpartnerships"
},
{
"ServiceLines": [ "Payroll" ],
"LastEmailedField": "tt_lastemailsentpayroll"
},
{
"ServiceLines": [ "Research And Development" ],
"LastEmailedField": "tt_lastemailsentrandd"
},
{
"ServiceLines": [ "Risk And Assurance" ],
"LastEmailedField": "tt_lastemailsentriskandassurance"
},
{
"ServiceLines": [ "Trusts" ],
"LastEmailedField": "tt_lastemailsenttrusts"
},
{
"ServiceLines": [ "Virtual Finance Office" ],
"LastEmailedField": "tt_lastemailsentvirtualfinanceoffice"
},
];

const newNotificationDate = new Date();
var formatted_date = (newNotificationDate.getMonth() + 1) + "/" + newNotificationDate.getDate() + "/" + newNotificationDate.getFullYear() + " " + newNotificationDate.getHours() + ":" + newNotificationDate.getMinutes() + ":" + newNotificationDate.getSeconds();

const filteredFields = notificationFields.filter(field => field.ServiceLines.includes(teamToNotify));
var fieldsToUpdate = filteredFields.map(field => field.LastEmailedField);

var notificationObject = {};
fieldsToUpdate.forEach(field => {
notificationObject[field] = formatted_date;
});

return notificationObject;
}

async function GrantCollaborationAccessToFile(sectionName, fileID)
{
const sectionSharePointSite = $(`span[id='${sectionName} details']`).data('sharepointsite');
const sectionDocumentLibrary = $(`span[id='${sectionName} details']`).data('documentlibrary');
const sectionServiceLine = $(`span[id='${sectionName} details']`).data('serviceline');
const sectionContact = $(`span[id='${sectionName} details']`).data('contact');
// Create body for upload request
const uploadbody = {
"Contact" : sectionContact,
"SharePointSite" : sectionSharePointSite,
"DocumentLibrary" : sectionDocumentLibrary,
"ServiceLine" : sectionServiceLine,
"FileID" : fileID
};

$(`div[id="${sectionName}"]`).find(`div[id="${sectionName} Loading"]`).show();
$(`div[id="${sectionName}"]`).find(`div[id="${sectionName} NoDocuments"]`).hide();

var collabResponse = GrantSharePointCollaborationAccess(uploadbody);
console.log(`collabResponse: ${collabResponse}`);
}

async function ExtractDetailsFromFile(sectionName)
{
const AIFundsTIRTesting = '{{ AIFundsTIRTesting }}';

var testingboolean = false;
if(AIFundsTIRTesting == "enabled"){
testingboolean = true;
}

var extractionBody = {
"ContactID" : "{{ contact }}",
"RecordID" : "{{ params.id }}",
"SectionName" : sectionName,
"Testing" : testingboolean
}

// Perform the file download and await the result
var extractionResponse = ExtractDataFromSharePointFile(sectionName, extractionBody);
console.log(`extractionResponse: ${extractionResponse}`);
}

const sectionSharePointSite = $(`span[id='${sectionName} details']`).data('sharepointsite');
const sectionCurrentFolder = $(`span[id='${sectionName} details']`).data('currentfolder');

// Extract the server-relative path from the current folder
const serverRelativePath = sectionCurrentFolder.slice(1);

// Async function to download a file from SharePoint
async function downloadFile(fileName, fileID, sectionName)
{
const sectionSharePointSite = $(`span[id='${sectionName} details']`).data('sharepointsite');
const sectionCurrentFolder = $(`span[id='${sectionName} details']`).data('currentfolder');

// Extract the server-relative path from the current folder
const serverRelativePath = sectionCurrentFolder.slice(1);

// Prepare body for the file download request
const downloadBody = {
"SharePoint Site": sectionSharePointSite,
"Server Relative Path": serverRelativePath,
"File Name": fileName
};

// Perform the file download and await the result
const downloadResult = await DownloadFileFromSharePoint(downloadBody);

// Check if the file download was successful
if (downloadResult)
{
// Call the downloadSharePointFile function with the download result and file name
downloadSharePointFile(downloadResult, fileName);
}
}

// Function to download a SharePoint file
function downloadSharePointFile(data, name = "myData.txt")
{
// Convert base64 data to ArrayBuffer
const arrBuffer = base64ToArrayBuffer(data.Content);

// Create a Blob from the ArrayBuffer with the specified content type
const blob = new Blob([arrBuffer], { type: data.ContentType });

// Create an 'a' element with properties for downloading the file
const a = Object.assign(document.createElement('a'), {
href: window.URL.createObjectURL(blob),
style: "display:none",
download: name
});

// Append the 'a' element to the document body
document.body.appendChild(a);

// Simulate a click on the 'a' element to trigger the download
a.click();

// Revoke the Object URL to free up resources
window.URL.revokeObjectURL(a.href);

// Remove the 'a' element from the document body
a.remove();
}

// This function converts a base64 encoded string to an ArrayBuffer
function base64ToArrayBuffer(data) {
// Decode the base64 string using window.atob
var binaryString = window.atob(data);
// Get the length of the decoded binary string
var binaryLen = binaryString.length;
// Create a new Uint8Array to hold the bytes
var bytes = new Uint8Array(binaryLen);
// Iterate through each character in the binary string
for (var i = 0; i < binaryLen; i++) {
// Get the ASCII value of the character
var ascii = binaryString.charCodeAt(i);
// Store the ASCII value in the Uint8Array
bytes[i] = ascii;
}
// Return the Uint8Array representing the ArrayBuffer
return bytes;
};

// Async function to delete a file
async function deleteFile(fileID, sectionName)
{
const sectionSharePointSite = $(`span[id='${sectionName} details']`).data('sharepointsite');
const sectionDocumentLibrary = $(`span[id='${sectionName} details']`).data('documentlibrary');
const sectionSite = $(`span[id='${sectionName} details']`).data('site');
const sectionCurrentFolder = $(`span[id='${sectionName} details']`).data('currentfolder');
const sectionDocumentEntity = $(`span[id='${sectionName} details']`).data('documententity');

// Select the delete button
const deleteButton = $('button#deleteFileButton');

// Set the delete button to a loading state with a spinning cog and "Processing" text
deleteButton.empty().append('<span class="fa fa-cog fa-spin" style="display: inline-block !important" aria-hidden="true"></span>');
deleteButton.append(" Processing ");

// Disable the delete button during processing
deleteButton.prop("disabled", true);

// Prepare the body for file deletion
var deletionBody = {
"SharePoint Site": sectionSharePointSite,
"Document Library": sectionDocumentLibrary,
"FileID": fileID
};

// Perform the file deletion operation and await the result
const deletionResult = await DeleteFileFromSharePoint(deletionBody);

// Check if file deletion was successful
if (deletionResult) {
// Prepare body for retrieving updated SharePoint files
var body = {
"SharePoint Site": sectionSharePointSite,
"Document Library": sectionDocumentLibrary,
"Folder Path": `sites/${sectionSite}${sectionCurrentFolder}`,
"Document Entity": sectionDocumentEntity
};

// Retrieve updated SharePoint files
const getResults = await GetSharePointFiles(body);

// Check if file retrieval was successful
if (getResults) {
// Populate the table with the updated files
PopulateTable(getResults, sectionName);

// Remove the click event handler for the delete button in the modal
$('div#DeleteModal').find('button[aria-label="Delete"]').off('click');

// Click the close button in the modal
$('div#DeleteModal').find('button[aria-label="Close"]').click();

// Enable the delete button and update its text
deleteButton.prop("disabled", false).text("Delete");
}
}
}

async function resyncDocuments(sectionName)
{

$(`div[id="${sectionName}"]`).find(`div[id="${sectionName} Loading"]`).show();
$(`div[id="${sectionName}"]`).find(`div[id="${sectionName} NoDocuments"]`).hide();

const sectionSharePointSite = $(`span[id='${sectionName} details']`).data('sharepointsite');
const sectionDocumentLibrary = $(`span[id='${sectionName} details']`).data('documentlibrary');
const sectionSite = $(`span[id='${sectionName} details']`).data('site');
const sectionCurrentFolder = $(`span[id='${sectionName} details']`).data('currentfolder');
const sectionDocumentEntity = $(`span[id='${sectionName} details']`).data('documententity');

var body = {
"SharePoint Site": sectionSharePointSite,
"Document Library": sectionDocumentLibrary,
"Folder Path": `sites/${sectionSite}${sectionCurrentFolder}`,
"Document Entity": sectionDocumentEntity
};

// Retrieve updated SharePoint files
const getResults = await GetSharePointFiles(body);

// Check if file retrieval was successful
if (getResults) {
// Populate the table with the updated files
PopulateTable(getResults, sectionName);
}
}

async function UploadFile(sectionName)
{
const sectionSharePointSite = $(`span[id='${sectionName} details']`).data('sharepointsite');
const sectionDocumentLibrary = $(`span[id='${sectionName} details']`).data('documentlibrary');
const sectionSite = $(`span[id='${sectionName} details']`).data('site');
const sectionCurrentFolder = $(`span[id='${sectionName} details']`).data('currentfolder');
const sectionDocumentEntity = $(`span[id='${sectionName} details']`).data('documententity');

// Select the delete button
const uploadButton = $('button#addFilesButton');

// Set the delete button to a loading state with a spinning cog and "Processing" text
uploadButton.empty().append('<span class="fa fa-cog fa-spin" style="display: inline-block !important" aria-hidden="true"></span>');
uploadButton.append(" Processing ");

// Disable the delete button during processing
uploadButton.prop("disabled", true);

var filesToUpload = $('#fileInput')[0].files

// Loop through each file for upload
if(filesToUpload.length >= 1)
{
for (let i = 0; i < filesToUpload.length; i++) {
const file = filesToUpload[i];

// Create FormData and append file information
const formData = new FormData();
formData.append('file', file);

// Create body for upload request
const uploadbody = {
"SharePoint Site": sectionSharePointSite,
"Document Library": sectionDocumentLibrary,
"Folder Path": sectionCurrentFolder,
"FileName": file.name
};

// Append key-value pairs from uploadbody to FormData
for (const [key, value] of Object.entries(uploadbody)) {
formData.append(key, value);
}

// Perform the file upload and await the result
const uploadResult = await UploadFileToSharePoint(formData);

var uploadFileID = parseInt(uploadResult.FileID);
if(uploadFileID)
{
GrantCollaborationAccessToFile(sectionName, uploadFileID);
};

// Check if upload was successful and if it's the last file in the list
if (uploadResult && i === filesToUpload.length - 1) {
// Prepare body for retrieving updated SharePoint files
const body = {
"SharePoint Site": sectionSharePointSite,
"Document Library": sectionDocumentLibrary,
"Folder Path": `sites/${sectionSite}${sectionCurrentFolder}`,
"Document Entity": sectionDocumentEntity
};

var serviceLinetoAlert = $(`span[id='${sectionName} details']`).data('serviceline')
const notificationSentToTeam = await NotifyTeam(sectionName, serviceLinetoAlert, sectionCurrentFolder)

// Retrieve updated SharePoint files
const getResults = await GetSharePointFiles(body);

// Check if file retrieval was successful
if (getResults) {
// Populate the table with the updated files
PopulateTable(getResults, sectionName);
// Close the upload modal, clear file input, enable the upload button, and update its text
$('div#UploadModal').find('button[aria-label="Close"]').click();
$('input#fileInput')[0].value = "";
uploadButton.prop("disabled", false).text("Add Files");
}
}
}

var AIExtractionEnabled = '{{ AIExtractionEnabled }}';

console.log(`AIExtractionEnabled: ${AIExtractionEnabled}`);
const AIEnabledSections = ["Employments", "Prior Year Form 1065 and Schedule K-1s"]
if(AIEnabledSections.includes(sectionName) && AIExtractionEnabled == "enabled")
{
ExtractDetailsFromFile(sectionName);
}
}
else
{
uploadButton.prop("disabled", false).text("Add Files");
}
};

// Function to clear input fields in modals
function clearModals()
{
// Clear the value of the file input field in the modal
$('input#fileInput')[0].value = "";

// Clear the value of the folder name input field in the modal
$(`div#NewFolderModal`).find('input#FolderName').val('');

// Remove the onclick function from the "Add Files" button
$("#addFilesButton").off("click");
$("#createFolderButton").off("click");
}


// Async function to create a new folder in SharePoint
async function CreateFolder(sectionName)
{
const sectionSharePointSite = $(`span[id='${sectionName} details']`).data('sharepointsite');
const sectionDocumentLibrary = $(`span[id='${sectionName} details']`).data('documentlibrary');
const sectionSite = $(`span[id='${sectionName} details']`).data('site');
const sectionCurrentFolder = $(`span[id='${sectionName} details']`).data('currentfolder');
const sectionDocumentEntity = $(`span[id='${sectionName} details']`).data('documententity');
// Select the create folder button
const createFolderButton = $('button#createFolderButton');

// Set the create folder button to a loading state with a spinning cog and "Processing" text
createFolderButton.empty().append('<span class="fa fa-cog fa-spin" style="display: inline-block !important" aria-hidden="true"></span>');
createFolderButton.append(" Processing ");

// Disable the create folder button during processing
createFolderButton.prop("disabled", true);

// Get the new folder name from the input field
var newFoldername = $(`div#NewFolderModal`).find('input#FolderName')[0].value;

// Create the new folder path
var newFolderpath = `${sectionCurrentFolder.split(sectionDocumentLibrary)[1]}/${newFoldername}`;
// Prepare body for creating a new folder
const createFolderBody = {
"SharePoint Site": sectionSharePointSite,
"Document Library": sectionDocumentLibrary,
"New Folder Path": newFolderpath
};

// Perform the folder creation and await the result
const createResult = await CreateFolderInSharePoint(createFolderBody);

// Check if folder creation was successful
if (createResult) {
// Prepare body for retrieving updated SharePoint files
const body = {
"SharePoint Site": sectionSharePointSite,
"Document Library": sectionDocumentLibrary,
"Folder Path": `sites/${sectionSite}${sectionCurrentFolder}`,
"Document Entity": sectionDocumentEntity
};

// Retrieve updated SharePoint files
const getResults = await GetSharePointFiles(body);

// Check if file retrieval was successful
if (getResults) {
// Populate the table with the updated files
PopulateTable(getResults, sectionName);

// Close the new folder modal, enable the create folder button, clear input field
$('div#NewFolderModal').find('button[aria-label="Close"]').click();
createFolderButton.prop("disabled", false).text("Create Folder");
$('input#FolderName').val('');
}
}
}

function initializeDropZones() {
console.log("Initializing drop zones...");

$('.drop-zone').each(function (index) {
const dropZone = $(this);
console.log(`Drop zone ${index + 1} initialized.`);

dropZone.on('dragover', function (e) {
e.preventDefault();
$(this).addClass('dragover');
console.log(`Dragover detected on drop zone ${index + 1}`);
});

dropZone.on('dragleave', function () {
$(this).removeClass('dragover');
console.log(`Dragleave detected on drop zone ${index + 1}`);
});

dropZone.on('drop', async function (e) {
e.preventDefault();
$(this).removeClass('dragover');
console.log(`Drop event triggered on drop zone ${index + 1}`);

const files = e.originalEvent.dataTransfer.files;
console.log(`Files dropped: ${files.length}`);

const sectionDiv = $(this).find('.contactDocumentLocation').first();
const sectionName = sectionDiv.attr('id');
console.log(`Detected section: ${sectionName}`);

const sectionDetails = $(`span[id='${sectionName} details']`);
const sectionSharePointSite = sectionDetails.data('sharepointsite');
const sectionDocumentLibrary = sectionDetails.data('documentlibrary');
const sectionSite = sectionDetails.data('site');
const sectionCurrentFolder = sectionDetails.data('currentfolder');
const sectionDocumentEntity = sectionDetails.data('documententity');
const serviceLine = sectionDetails.data('serviceline');

console.log("Section metadata:", {
sectionSharePointSite,
sectionDocumentLibrary,
sectionSite,
sectionCurrentFolder,
sectionDocumentEntity,
serviceLine
});

// Initialize upload progress tracking
const uploadMessageId = `dropzoneUploadMessage${sectionName}`;
const $uploadMessage = $(`[id='${uploadMessageId}']`);

// Clear and hide message before starting new upload batch
if ($uploadMessage.length) {
$uploadMessage.text('').hide();
}

let uploadedCount = 0;
const totalFiles = files.length;

// Show initial progress if message element exists
if ($uploadMessage.length && totalFiles > 0) {
$uploadMessage.text(`${uploadedCount} out of ${totalFiles} files uploaded.`).show();
}

for (let i = 0; i < files.length; i++) {
const file = files[i];
console.log(`Uploading file ${i + 1}/${files.length}: ${file.name}`);

const formData = new FormData();
formData.append('file', file);

const uploadBody = {
"SharePoint Site": sectionSharePointSite,
"Document Library": sectionDocumentLibrary,
"Folder Path": sectionCurrentFolder,
"FileName": file.name
};

for (const [key, value] of Object.entries(uploadBody)) {
formData.append(key, value);
}

const uploadResult = await UploadFileToSharePoint(formData);
console.log("Upload result:", uploadResult);

// Update progress after each file
uploadedCount++;
if ($uploadMessage.length) {
$uploadMessage.text(`${uploadedCount} out of ${totalFiles} files uploaded.`).show();
}

const uploadFileID = parseInt(uploadResult.FileID);
if (uploadFileID) {
console.log(`Granting collaboration access for file ID: ${uploadFileID}`);
GrantCollaborationAccessToFile(sectionName, uploadFileID);
}

if (uploadResult && i === files.length - 1) {
const body = {
"SharePoint Site": sectionSharePointSite,
"Document Library": sectionDocumentLibrary,
"Folder Path": `sites/${sectionSite}${sectionCurrentFolder}`,
"Document Entity": sectionDocumentEntity
};

console.log("Notifying team...");
await NotifyTeam(sectionName, serviceLine, sectionCurrentFolder);

console.log("Fetching updated SharePoint files...");
const getResults = await GetSharePointFiles(body);
if (getResults) {
console.log("Populating table with updated files...");
PopulateTable(getResults, sectionName);
}

// Show completion message
if ($uploadMessage.length) {
const documentsUrl = `${window.location.origin}/MyDocuments`;
$uploadMessage.html(`All files uploaded to <a href="${documentsUrl}">General Documents</a>`).show();
}
}
}

const AIExtractionEnabled = '{{ AIExtractionEnabled }}';
const AIEnabledSections = ["Employments", "Prior Year Form 1065 and Schedule K-1s"];
if (AIEnabledSections.includes(sectionName) && AIExtractionEnabled === "enabled") {
console.log(`Triggering AI extraction for section: ${sectionName}`);
ExtractDetailsFromFile(sectionName);
}
});
});
}

Custom Integration - Main

Source
<script>
ConfigureDocuments();

// Async function to configure documents
async function ConfigureDocuments() {
var section = "{{ sectionName }}";
try {
// Prepare body for fetching SharePoint files
const body = {
"SharePoint Site": SharePointSite,
"Document Library": DocumentLibrary,
"Folder Path": `sites/${site}${FolderPath}`,
"Document Entity": documentEntity
};

// Fetch SharePoint files based on the provided body
const getResults = await GetSharePointFiles(body);

// Check if file retrieval was successful
if (getResults) {
// Populate the table with the fetched results
PopulateTable(getResults, section);
}
initializeDropZones();
} catch (error) {
// Log the error during document configuration
console.error('Error during document configuration:', error);
// Handle or log the error as needed
}
}
</script>
<div id="drop-zone" class="drop-zone"{% if showTable == false %}style="height:150px;align-content:center;text-align:center;"{% endif %}>
<div id="{{ sectionName }}" style="" class="contactDocumentLocation" style="display: none;">
{% if showTable %}
<div>
<h1 style="font-weight:bold;">{{ sectionName }}</h1>
</div>
{% endif %}
<span id="{{ sectionName }} details"></span>

<script>
// Assuming you have a variable called sectionName
var sectionName = '{{ sectionName }}';
var enableDeletion = '{{ EnableDeletion }}';
var enableCollaboration = '{{ EnableCollaboration }}';
var serviceLine = '{{ serviceLine }}';
var contact = '{{ contact }}';
var showTable = '{{ showTable }}';

// Add attributes to the <span> element
$(`span[id='${sectionName} details']`).data('sharepointsite', SharePointSite);
$(`span[id='${sectionName} details']`).data('documentlibrary', DocumentLibrary);
$(`span[id='${sectionName} details']`).data('relativepath', RelativePath);
$(`span[id='${sectionName} details']`).data('site', site);
$(`span[id='${sectionName} details']`).data('currentfolder', currentFolder);
$(`span[id='${sectionName} details']`).data('rootfolder', rootFolder);
$(`span[id='${sectionName} details']`).data('documententity', documentEntity);
$(`span[id='${sectionName} details']`).data('folderpath', FolderPath);
$(`span[id='${sectionName} details']`).data('enabledeletion', enableDeletion);
$(`span[id='${sectionName} details']`).data('enablecollaboration', enableCollaboration);
$(`span[id='${sectionName} details']`).data('serviceline', serviceLine);
$(`span[id='${sectionName} details']`).data('contact', contact);

</script>
{% if showTable %}
<h4>Drag and drop your files into the area below or click Add Files to upload directly from your device. Your documents will be securely uploaded to your account.</h4>
<div class="view-toolbar grid-actions clearfix">
<div class="pull-left">
<ol id="documentsBreadcrumb" class="breadcrumb sharepoint-breadcrumbs" style="">
</ol>
</div>
{% if EnableUpload %}
<div class="pull-right">
<a class="add-file btn btn-primary action" href="#" role="button" onclick="openModal('UploadModal', '{{ sectionName }}')">
<span class="fa fa-plus-circle" aria-hidden="true"></span>
Add Files
</a>
{% if EnableNewFolder %}
<a class="add-folder btn btn-info action" href="#" role="button" onclick="openModal('NewFolderModal', '{{ sectionName }}')">
<span class="fa fa-folder" aria-hidden="true"></span>
New Folder
</a>
{% endif %}
<a class="add-folder btn btn-info action" href="#" role="button" onclick="resyncDocuments('{{ sectionName }}')">
<span class="fa fa-refresh" aria-hidden="true"></span>
Refresh
</a>
</div>
{% endif %}
</div>
<div class="view-grid">
<table id="{{ sectionName }}" aria-relevant="additions" role="grid" class="table table-fluid">
<thead>
<tr>
<th scope="col" onclick='sortTable(0, "{{ sectionName }}")' aria-readonly="true" style="width:40%;text-align: left;" class="sort-enabled"><a role="button" aria-label="Name" tabindex="0">Name</a></th>
<!-- <th scope="col" aria-readonly="true" style="width:10%;text-align: center;" class="sort-enabled"><a role="button" aria-label="ID" tabindex="1">ID</a></th> -->
<th scope="col" onclick='sortTable(1, "{{ sectionName }}")' aria-readonly="true" style="width:40%;text-align: center;" class="sort-enabled"><a role="button" aria-label="Modified On" tabindex="2">Modified On</a></th>
<!-- <th scope="col" onclick='sortTable(3, "{{ sectionName }}")' aria-readonly="true" style="width:20%;text-align: center;" class="sort-enabled"><a role="button" aria-label="Modified By" tabindex="3">Modified By</a></th> -->
<th scope="col" aria-readonly="true" style="width:20%;text-align: center;" class="sort-enabled"><a role="button" aria-label="Actions" tabindex="4">Actions</a></th>
</tr>
</thead>
<tbody id="{{ sectionName }}" style="">
</tbody>
</table>
<div id="{{ sectionName }} NoDocuments" style="display:none">
<div class="sharepoint-empty message" role="presentation" style="" tabindex="0">
<div class="alert alert-block alert-warning">There are no folders or files to display.</div>
</div>
</div>
<div id="{{ sectionName }} Loading" style="text-align: center;">
<h4>Loading Documents <span class="fa fa-cog fa-spin" style="display: inline-block !important" aria-hidden="true"></span></h3>
</div>
</div>
{% else %}
<span id = 'uploadicon' class='glyphicon glyphicon-cloud-upload' style='font-size:xxx-large;' title='Complete'></span>
<h5><strong>Drop Files Here.</strong></h5>
<h5 id="dropzoneUploadMessage{{ sectionName }}" style="text-align: right;display:none">Test</h5>
{% endif %}
</div>
</div>

<script>
function sortTable(columnIndex, tableName) {
const table = $('table[id="' + tableName + '"]');
const heading = table.find('th').eq(columnIndex);
const arrowUp = '<i class="fa fa-arrow-up fa-md"></i>';
const arrowDown = '<i class="fa fa-arrow-down fa-md"></i>';

// Remove existing arrow indicators from all headings
table.find('th').each(function () {
$(this).find('.arrow-indicator').remove();
});

// Append arrow indicator to the selected heading
heading.append(`<span class="arrow-indicator">${ascendingOrder ? arrowUp : arrowDown}</span>`);

const rows = Array.from(table[0].rows).slice(1); // Exclude header row

rows.sort((a, b) => {
const cellA = a.cells[columnIndex].textContent.trim().toLowerCase();
const cellB = b.cells[columnIndex].textContent.trim().toLowerCase();

if (cellA < cellB) return ascendingOrder ? -1 : 1;
if (cellA > cellB) return ascendingOrder ? 1 : -1;
return 0;
});

// Remove existing rows
rows.forEach(row => table.find('tbody').append(row));

// Toggle sorting order for the next click
ascendingOrder = !ascendingOrder;
}
</script>

Custom Integration - Modals

Source
<!-- File Deletion Modal -->
<div class="modal fade" id="DeleteModal" role="dialog">
<div class="modal-dialog modal-md" id="myModal">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title" title="Delete file">Delete File</h1>
<button aria-label="Close" class="form-close" data-dismiss="modal" style="position: absolute; top: 3%;" tabindex="0" title="Close" type="button" onclick="clearModals()">
<span aria-hidden="true">×</span>
<span class="sr-only">Close</span>
</button>
</div>
<div class="modal-body">
<p>Are you sure you want to permanently delete this file?</p>
<p class="sp-item-name">
<span class="fa fa-file-o" aria-hidden="true"></span>
<span class="sharepoint-custom-underline" title="FILENAME">
<span>FILENAME HERE</span>
</span>
</p>
</div>
<div class="modal-footer">
<button aria-label="Delete" id="deleteFileButton" class="primary btn btn-primary" tabindex="0" title="Delete" type="button" onclick="">Delete</button>
<button aria-label="Cancel" class="cancel btn btn-default" data-dismiss="modal" tabindex="0" title="Cancel" type="button" onclick="clearModals()">Cancel</button>
</div>
</div>
</div>
</div>
<!-- File Deletion Modal -->

<!-- File Upload Modal -->
<div class="modal fade" id="UploadModal" role="dialog">
<div class="modal-dialog modal-md" id="myModal">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title" title="Add files">Add File(s)</h1>
<button aria-label="Close" class="form-close" data-dismiss="modal" style="position: absolute; top: 3%;" tabindex="0" title="Close" type="button" onclick="clearModals()">
<span aria-hidden="true">×</span>
<span class="sr-only">Close</span>
</button>
</div>
<div class="modal-body">
<div class="form-horizontal add-file" data-target="{&quot;LogicalName&quot;: &quot;tt_contactdocuments&quot;,&quot;Id&quot;: &quot;8f9e6335-a053-ee11-be6f-6045bdf1e87b&quot;}" data-url="/_services/sharepoint-addfiles/d78574f9-20c3-4dcc-8d8d-85cf5b7ac141">
<div class="margin-addfile form-group text-center">
<label class="control-label-addfile col-sm-3">Choose files</label>
<div class="col-sm-9">
<input id="fileInput" aria-label="Choose files" multiple="multiple" name="file" type="file" tabindex="0">
</div>
</div>
<div class="padding-destinationfile destination-group form-group" style="display: none;">
<label class="control-label-addfile col-sm-3">Destination</label>
<div class="col-sm-9">
<p class="form-control-static-addfile destination-folder"></p>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button aria-label="Add Files" id="addFilesButton" class="primary btn btn-primary" tabindex="0" title="Add Files" type="button">Add Files</button>
<button aria-label="Cancel" class="cancel btn btn-default" data-dismiss="modal" tabindex="0" title="Cancel" type="button" onclick="clearModals()">Cancel</button>
</div>
</div>
</div>
</div>
<!-- File Upload Modal -->

<!-- New Folder Modal -->
<div class="modal fade" id="NewFolderModal" role="dialog">
<div class="modal-dialog modal-md" id="myModal">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title" title="New folder">Create Folder</h1>
<button aria-label="Close" class="form-close" data-dismiss="modal" style="position: absolute; top: 3%;" tabindex="0" title="Close" type="button" onclick="clearModals()">
<span aria-hidden="true">×</span>
<span class="sr-only">Close</span>
</button>
</div>
<div class="modal-body">
<div class="form-horizontal add-folder" data-target="" data-url="">
<div class="form-group">
<div class="col-sm-3 text-center info required">
<label class="control-label" for="FolderName">Name</label>
</div>
<div class="col-sm-9">
<input aria-label="Name" aria-required="true" autocomplete="nope" class="form-control" id="FolderName" placeholder="Name" type="text">
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button aria-label="Create Folder" id="createFolderButton" class="primary btn btn-primary" tabindex="0" title="Create Folder" type="button">Create Folder</button>
<button aria-label="Cancel" class="cancel btn btn-default" data-dismiss="modal" tabindex="0" title="Cancel" type="button" onclick="clearModals()">Cancel</button>
</div>
</div>
</div>
</div>
<!-- New Folder Modal -->

Custom Integration - SharePoint Functions

Source
// Async function to retrieve and sort files from SharePoint
async function GetSharePointFiles(payload) {
try {
// SharePoint API endpoint for fetching files
const queryurl = "{{ GetSharePointFilesUrl }}";

// Perform a POST request to the SharePoint API
const response = await fetch(queryurl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
});

// Ensure the response is successful before proceeding
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}

// Wait for a short period before resolving the promise (if necessary)
await new Promise(resolve => setTimeout(resolve, 10));

// Parse and sort the response data
const data = await response.json();
data.sort((a, b) => {
// Compare FileSystemObjectType in descending order
if (a.FileSystemObjectType > b.FileSystemObjectType) return -1;
if (a.FileSystemObjectType < b.FileSystemObjectType) return 1;

// If FileSystemObjectType is equal, compare FileLeafRef in ascending order
return a.FileLeafRef.localeCompare(b.FileLeafRef);
});

// Return the sorted data
return data;
} catch (error) {
// Log and re-throw the error for handling elsewhere if needed
console.error('Error during fetching files:', error);
throw error;
}
}

async function GrantSharePointCollaborationAccess(payload) {
try {
// SharePoint API endpoint for file upload
const grantCollabUrl = "{{ GrantCollaborationUrl }}";

// Perform a POST request to the SharePoint API with FormData
const response = await fetch(grantCollabUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
});

// Ensure the response is successful before proceeding
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}

// Wait for a short period before resolving the promise (if necessary)
await new Promise(resolve => setTimeout(resolve, 10));

// Parse and return the response data as JSON
return await response.json();
} catch (error) {
// Log and re-throw the error for handling elsewhere if needed
console.error('Error during granting collaboration:', error);
throw error;
}
}

async function NotifyTeamOfFileUpload(payload) {
try {
// SharePoint API endpoint for file upload
const queryUrl = "{{ emailTeamsUrl }}";

// Perform a POST request to the SharePoint API with FormData
const response = await fetch(queryUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
});

// Ensure the response is successful before proceeding
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}

// Wait for a short period before resolving the promise (if necessary)
await new Promise(resolve => setTimeout(resolve, 10));

// Parse and return the response data as JSON
return await response.json();
} catch (error) {
// Log and re-throw the error for handling elsewhere if needed
console.error('Error sending notification to teams:', error);
throw error;
}
}

// Async function to retrieve file editors information from SharePoint
async function GetSharePointFileEditors(payload) {
try {
// SharePoint API endpoint for fetching file editors information
const queryurl = "{{ GetSharePointFilesEditorUrl }}";

// Perform a POST request to the SharePoint API
const response = await fetch(queryurl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
});

// Ensure the response is successful before proceeding
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}

// Wait for a short period before resolving the promise (if necessary)
await new Promise(resolve => setTimeout(resolve, 10));

// Parse and return the response data as JSON
return await response.json();
} catch (error) {
// Log and re-throw the error for handling elsewhere if needed
console.error('Error during fetching file editors:', error);
throw error;
}
}

// Async function to upload a file to SharePoint
async function UploadFileToSharePoint(formData) {
try {
// SharePoint API endpoint for file upload
const uploadUrl = "{{ UploadSharePointFileUrl }}";

// Perform a POST request to the SharePoint API with FormData
const response = await fetch(uploadUrl, {
method: 'POST',
body: formData,
});

// Ensure the response is successful before proceeding
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}

// Wait for a short period before resolving the promise (if necessary)
await new Promise(resolve => setTimeout(resolve, 10));

// Resolve the promise with a success message
return await response.json();
} catch (error) {
// Log and re-throw the error for handling elsewhere if needed
console.error('Error during file upload:', error);
throw error;
}
}

// Async function to create a folder in SharePoint
async function CreateFolderInSharePoint(payload) {
try {
// SharePoint API endpoint for folder creation
const createUrl = "{{ CreateSharePointFolderUrl }}";

// Perform a POST request to the SharePoint API
const response = await fetch(createUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
});

// Ensure the response is successful before proceeding
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}

// Wait for a short period before resolving the promise (if necessary)
await new Promise(resolve => setTimeout(resolve, 10));

// Parse and return the response data as JSON
return await response.json();
} catch (error) {
// Log and re-throw the error for handling elsewhere if needed
console.error('Error during folder creation:', error);
throw error;
}
}

// Async function to delete a file from SharePoint
async function DeleteFileFromSharePoint(payload) {
try {
// SharePoint API endpoint for file deletion
const deletionUrl = "{{ DeleteSharePointFileUrl }}";

// Perform a POST request to the SharePoint API
const response = await fetch(deletionUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
});

// Ensure the response is successful before proceeding
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}

// Wait for a short period before resolving the promise (if necessary)
await new Promise(resolve => setTimeout(resolve, 10));

// Resolve the promise with a success message
return "File Removed From SharePoint";
} catch (error) {
// Log and re-throw the error for handling elsewhere if needed
console.error('Error during file deletion:', error);
throw error;
}
}

// Async function to download a file from SharePoint
async function DownloadFileFromSharePoint(payload) {
try {
// SharePoint API endpoint for file download
const downloadUrl = '{{ DownloadSharePointFileUrl }}';

// Perform a POST request to the SharePoint API
const response = await fetch(downloadUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
});

// Ensure the response is successful before proceeding
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}

// Wait for a short period before resolving the promise (if necessary)
await new Promise(resolve => setTimeout(resolve, 10));

// Parse and return the response data as JSON
return await response.json();
} catch (error) {
// Log and re-throw the error for handling elsewhere if needed
console.error('Error during file download:', error);
throw error;
}
}

async function ExtractDataFromSharePointFile(sectionName, payload) {
try {
console.log("Extracting Data from File");
// SharePoint API endpoint for file download
const EmploymentsURL = '{{ AI_UK_TR_Employments }}';
const PriorYearK1 = '{{ AI_Funds_TIR_PriorYearK1 }}';


switch(sectionName) {
case "Employments":
var extractionUrl = EmploymentsURL;
break;
case "Prior Year Form 1065 and Schedule K-1s":
var extractionUrl = PriorYearK1;

break;
default:
var extractionUrl = '';
break;
}

console.log(`extractionUrl: ${extractionUrl}`);

// Perform a POST request to the SharePoint API
const response = await fetch(extractionUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
});

// Ensure the response is successful before proceeding
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}

// Wait for a short period before resolving the promise (if necessary)
await new Promise(resolve => setTimeout(resolve, 10));

// Parse and return the response data as JSON
return await response.json();
} catch (error) {
// Log and re-throw the error for handling elsewhere if needed
console.error('Error during data extraction from file:', error);
throw error;
}
}

Custom Integration - Team Notifications

Source
{% fetchxml LastEmailSentToTeam %}
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
<entity name="contact">
<attribute name="fullname" />
<attribute name="tt_clientcode" />
<attribute name="contactid" />
<attribute name="tt_lastemailsentustax" />
<attribute name="tt_lastemailsentuktax" />
<attribute name="tt_lastemailsenttrusts" />
<attribute name="tt_lastemailsentriskandassurance" />
<attribute name="tt_lastemailsentrandd" />
<attribute name="tt_lastemailsentpayroll" />
<attribute name="tt_lastemailsentpartnerships" />
<attribute name="tt_lastemailsentirelandtax" />
<attribute name="tt_lastemailsentirelandbts" />
<attribute name="tt_lastemailsentgeneral" />
<attribute name="tt_lastemailsentfundstax" />
<attribute name="tt_lastemailsentdigital" />
<attribute name="tt_lastemailsentcorporatefinance" />
<attribute name="tt_lastemailsentbusinesstax" />
<attribute name="tt_lastemailsentbusinessadvisory" />
<attribute name="tt_lastemailsentaudit" />
<attribute name="tt_lastemailsentaccounts" />
<order attribute="fullname" descending="false" />
<filter type="and">
<condition attribute="contactid" operator="eq" uitype="contact" value="{{ contact }}" />
</filter>
</entity>
</fetch>
{% endfetchxml %}

{% if LastEmailSentToTeam.results.entities.size == 1 %}
{% assign lastEmailUSTax = LastEmailSentToTeam.results.entities[0].tt_lastemailsentustax %}
{% assign lastEmailUKTax = LastEmailSentToTeam.results.entities[0].tt_lastemailsentuktax %}
{% assign lastEmailTrusts = LastEmailSentToTeam.results.entities[0].tt_lastemailsenttrusts %}
{% assign lastEmailRiskAndAssurance = LastEmailSentToTeam.results.entities[0].tt_lastemailsentriskandassurance %}
{% assign lastEmailResearchAndDevelopment = LastEmailSentToTeam.results.entities[0].tt_lastemailsentrandd %}
{% assign lastEmailPayroll = LastEmailSentToTeam.results.entities[0].tt_lastemailsentpayroll %}
{% assign lastEmailPartnerships = LastEmailSentToTeam.results.entities[0].tt_lastemailsentpartnerships %}
{% assign lastEmailIrelandTax = LastEmailSentToTeam.results.entities[0].tt_lastemailsentirelandtax %}
{% assign lastEmailIrelandBTS = LastEmailSentToTeam.results.entities[0].tt_lastemailsentirelandbts %}
{% assign lastEmailGeneral = LastEmailSentToTeam.results.entities[0].tt_lastemailsentgeneral %}
{% assign lastEmailFundsTax = LastEmailSentToTeam.results.entities[0].tt_lastemailsentfundstax %}
{% assign lastEmailDigital = LastEmailSentToTeam.results.entities[0].tt_lastemailsentdigital %}
{% assign lastEmailCorporateFinance = LastEmailSentToTeam.results.entities[0].tt_lastemailsentcorporatefinance %}
{% assign lastEmailBusinessTax = LastEmailSentToTeam.results.entities[0].tt_lastemailsentbusinesstax %}
{% assign lastEmailBusinessAdvisory = LastEmailSentToTeam.results.entities[0].tt_lastemailsentbusinessadvisory %}
{% assign lastEmailAudit = LastEmailSentToTeam.results.entities[0].tt_lastemailsentaudit %}
{% assign lastEmailAccounts = LastEmailSentToTeam.results.entities[0].tt_lastemailsentaccounts %}
{% assign lastEmailEmploymentTax = LastEmailSentToTeam.results.entities[0].tt_lastemailsentemploymenttax %}
{% assign lastEmailVirtualFinanceOffice = LastEmailSentToTeam.results.entities[0].tt_lastemailsentvirtualfinanceoffice %}
{% endif %}

<span id="LastEmailSentdetails"></span>

<script>
var currentDate = new Date();

var lastEmailUSTax = '{{ lastEmailUSTax }}';
var lastEmailUKTax = '{{ lastEmailUKTax }}';
var lastEmailTrusts = '{{ lastEmailTrusts }}';
var lastEmailRiskAndAssurance = '{{ lastEmailRiskAndAssurance }}';
var lastEmailResearchAndDevelopment = '{{ lastEmailResearchAndDevelopment }}';
var lastEmailPayroll = '{{ lastEmailPayroll }}';
var lastEmailPartnerships = '{{ lastEmailPartnerships }}';
var lastEmailIrelandTax = '{{ lastEmailIrelandTax }}';
var lastEmailIrelandBTS = '{{ lastEmailIrelandBTS }}';
var lastEmailGeneral = '{{ lastEmailGeneral }}';
var lastEmailFundsTax = '{{ lastEmailFundsTax }}';
var lastEmailDigital = '{{ lastEmailDigital }}';
var lastEmailCorporateFinance = '{{ lastEmailCorporateFinance }}';
var lastEmailBusinessTax = '{{ lastEmailBusinessTax }}';
var lastEmailBusinessAdvisory = '{{ lastEmailBusinessAdvisory }}';
var lastEmailAudit = '{{ lastEmailAudit }}';
var lastEmailAccounts = '{{ lastEmailAccounts }}';
var lastEmailEmploymentTax = '{{ lastEmailEmploymentTax }}';
var lastEmailVirtualFinanceOffice = '{{ lastEmailVirtualFinanceOffice }}';

// Add attributes to the <span> element
$(`span[id='LastEmailSentdetails']`).data('Audit', lastEmailAudit);
$(`span[id='LastEmailSentdetails']`).data('Accounts', lastEmailAccounts);
$(`span[id='LastEmailSentdetails']`).data('Business Advisory', lastEmailBusinessAdvisory);
$(`span[id='LastEmailSentdetails']`).data('Corporate Finance', lastEmailCorporateFinance);
$(`span[id='LastEmailSentdetails']`).data('Corporation Tax', lastEmailBusinessTax);
$(`span[id='LastEmailSentdetails']`).data('Digital', lastEmailDigital);
$(`span[id='LastEmailSentdetails']`).data('Employment Tax', lastEmailEmploymentTax);
$(`span[id='LastEmailSentdetails']`).data('Funds Tax', lastEmailFundsTax);
$(`span[id='LastEmailSentdetails']`).data('General Documents', lastEmailGeneral);
$(`span[id='LastEmailSentdetails']`).data('Ireland Business Tax', lastEmailIrelandBTS);
$(`span[id='LastEmailSentdetails']`).data('Partnerships', lastEmailPartnerships);
$(`span[id='LastEmailSentdetails']`).data('Payroll', lastEmailPayroll);
$(`span[id='LastEmailSentdetails']`).data('Research And Development', lastEmailResearchAndDevelopment);
$(`span[id='LastEmailSentdetails']`).data('Risk And Assurance', lastEmailRiskAndAssurance);
$(`span[id='LastEmailSentdetails']`).data('Trusts', lastEmailTrusts);

$(`span[id='LastEmailSentdetails']`).data('Ireland Tax', lastEmailIrelandTax);
$(`span[id='LastEmailSentdetails']`).data('UK Tax', lastEmailUKTax);
$(`span[id='LastEmailSentdetails']`).data('US Tax', lastEmailUSTax);
$(`span[id='LastEmailSentdetails']`).data('Virtual Finance Office', lastEmailVirtualFinanceOffice);

</script>

Home - Document Upload

Source
{% assign contact = user.id %}
{% include 'Custom Integration - Header' %}

{% capture documentLocationQuery %}
<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='true'>
<entity name='tt_contactdocuments'>
<attribute name='tt_contactdocumentsid' />
<attribute name='tt_name' />
<attribute name='createdon' />
<attribute name='tt_serviceline' />
<order attribute='tt_name' descending='false' />
<filter type='and'>
<condition attribute='tt_contact' operator='eq' uitype='contact' value='{{ contact }}' />
<condition attribute='tt_name' operator='eq' value='General Documents' />
</filter>
<link-entity name='sharepointdocumentlocation' from='regardingobjectid' to='tt_contactdocumentsid' link-type='inner' alias='ai'>
<link-entity name='sharepointdocumentlocation' from='sharepointdocumentlocationid' to='parentsiteorlocation' link-type='inner' alias='aj'>
<filter type='and'>
<condition attribute='name' operator='eq' value='Practice Gateway' />
</filter>
</link-entity>
</link-entity>
</entity>
</fetch>
{% endcapture %}

{% fetchxml contactDocuments %}
{{ documentLocationQuery }}
{% endfetchxml %}

{% if contactDocuments.results.entities.size >= 1 %}
{% assign records = contactDocuments.results.entities.size | minus: 1 %}
{% for i in (0...records) %}
{% assign contactDocumentName = contactDocuments.results.entities[i].tt_name %}
{% assign contactDocumentRecord = contactDocuments.results.entities[i].tt_contactdocumentsid %}
{% assign contactDocumentServiceLine = contactDocuments.results.entities[i].tt_serviceline.label %}

{% assign RecordToGetSharePointDetails = contactDocumentRecord %}
{% assign EntityLogicalName = "tt_contactdocuments" %}
{% assign EnableUpload = true %}
{% assign EnableNewFolder = true %}
{% assign EnableDeletion = true %}
{% assign EnableCollaboration = true %}
{% assign sectionName = contactDocumentName %}
{% assign showTable = false %}

{% if contactDocumentName == "General Documents" %}
{% assign serviceLine = "General" %}
{% else %}
{% assign serviceLine = contactDocumentName %}
{% endif %}

{% include 'Utility/GetSharePointDetails' %}
{% include 'Custom Integration - Main' %}
{% endfor %}
{% endif %}

<script language="javascript">
function ShowDocuments(navid, sectionName)
{
$('.contactDocumentLocation').hide();
$(`.contactDocumentLocation[id="${sectionName}"]`).show();
$('li[role="presentation"]').removeClass('active');
$('#' + navid).addClass('active');
}
$('#DocumentsList').find('li').eq(0).children('a').click();
</script>

Utility/GetSharePointDetails

Source
{% fetchxml recordSharePointDetails %}
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
<entity name="sharepointdocumentlocation">
<attribute name="name" />
<attribute name="regardingobjectid" />
<attribute name="tt_sharepointdetails" />
<order attribute="name" descending="false" />
<filter type="and">
<condition attribute="locationtype" operator="eq" value="0" />
<condition attribute="servicetype" operator="eq" value="0" />
<condition attribute="regardingobjectid" operator="eq" uitype="{{EntityLogicalName}}" value="{{RecordToGetSharePointDetails}}" />
</filter>
</entity>
</fetch>
{% endfetchxml %}

{% if recordSharePointDetails.results.entities.size == 1 %}
{% assign recordSharePointDetails = recordSharePointDetails.results.entities[0].tt_sharepointdetails %}
{% endif %}

<script>
//Get Object from Liquid
var recordSharePointDetails = `{{recordSharePointDetails}}`;
var SharePointJSON = JSON.parse(recordSharePointDetails);

//Declare values from JSON
var SharePointSite = SharePointJSON["SharePoint Site"];
var DocumentLibrary = SharePointJSON["Document Library"];
var RelativePath = SharePointJSON["Relative Path"];

if (RelativePath.startsWith('/')) {
RelativePath = RelativePath.substring(1);
}

// Split the path into an array based on the '/' delimiter
var pathArray = RelativePath.split('/');
// Get the last item from the array
var rootFolder = pathArray[pathArray.length - 1];

var splitSiteUrl = SharePointSite.split("/sites/");
var site = splitSiteUrl[1];
var FolderPath = "/" + DocumentLibrary + "/" + RelativePath;

var currentFolder = FolderPath;
var documentEntity = "{{EntityLogicalName}}";
</script>