Skip to main content

Document Approval - Letter of Engagement is Signed

Flow Overview

  • Name: Document Approval - Letter of Engagement is Signed
  • Purpose: Updates the Contact record and sends templated emails when an Engagement Letter is signed as part of the Document Approval process.
  • Date Created / Last Modified: [Insert date here]

Dependencies

  • Dataverse
    • Document Approvals
    • Contacts
    • Email Messages
    • Email Contents
  • PowerApps
    • Manual trigger
  • TTS Consulting Utility
    • ReplaceWildcardsInText

Trigger

  • Type: Manual
  • Source: PowerApps

Flow Details

Get Records from Input Parameters

  • Get Document Approval by ID

    Table name: Document Approvals
    Row ID: PowerApps input (Document Approval ID)
  • Get Contact by ID

    Table name: Contacts
    Row ID: PowerApps input (Contact ID)

Set Client Status

  • Child Flow – Get Setting Value: Contact.SetClientOnKYCComplete

  • Condition:

    equals(variables('Contact_SetClientOnKYCComplete'), true)
  • Update Contact (if true): Fields updated include: Address, Client Type, Email, Job Title, etc.

  • Update LLP Status to Client

    Table: Contacts
    Row ID: Contact ID

Initialize Variables

Name: DocumentApprovalURL
Type: String
Value:
concat(baseurl, '/main.aspx?etn=tt_documentapproval&id=', DocumentApprovalID, '&pagetype=entityrecord')
Name: EmailRecipientsArray
Type: Array
Value: []
Name: EmailRegardingContact
Type: String
Value: (empty)

Add Recipients

If Manager is Populated

Manager (Value) is not equal to null
  • Append to EmailRecipientsArray:
{
"participationtypemask": 3,
"partyid@odata.bind": "/systemusers({Manager ID})"
}

If Tax Senior is Populated

Tax Senior (Value) is not equal to null
  • Append to EmailRecipientsArray:
{
"participationtypemask": 3,
"partyid@odata.bind": "/systemusers({Tax Senior ID})"
}

List Reception Contact

FetchXML Query:

<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
<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="{Service Contact}" />
</filter>
</entity>
</fetch>

Condition:

length(body('List_Reception_Contact')?['value']) is equal to int(1)
  • Append to EmailRecipientsArray:
{
"participationtypemask": 3,
"partyid@odata.bind": "/contacts({Service Contact ID})"
}

Append Sender & BCC to EmailRecipientsArray

  • FlowEmailSender:
{
"participationtypemask": 1,
"partyid@odata.bind": "/systemusers({FlowEmailSender ID})"
}
  • FlowEmailBCC:
{
"participationtypemask": 4,
"partyid@odata.bind": "/contacts({FlowEmailBCC Contact ID})"
}

Email Template and Dynamic Replacement

Get Email Content Template

Filter Inputs:

{
"FlowName": "Document Approval - Letter of Engagement is Signed",
"FlowEmailID": "1"
}

FetchXML for Email Contents:

<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
<entity name="tt_emailcontent">
<attribute name="tt_emailcontentid" />
<order attribute="tt_emailsubject" descending="false" />
<filter type="and">
<condition attribute="tt_flowname" operator="eq" value="{FlowName}" />
<condition attribute="tt_flowemailid" operator="eq" value="{FlowEmailID}" />
</filter>
</entity>
</fetch>

Update EmailTemplate

ReplacementMapping JSON:

[
{
"Wildcard": "{{contact.tt_clientcode}}",
"Replacement": "@{outputs('Get_Contact_by_ID')?['body/tt_clientcode']}"
},
{
"Wildcard": "{{contact.fullname}}",
"Replacement": "@{outputs('Get_Contact_by_ID')?['body/fullname']}"
},
{
"Wildcard": "{{var.documentapprovalurl}}",
"Replacement": "@{variables('DocumentApprovalURL')}"
}
]

Replace Wildcards

  • EmailSubject Replacement:
{
"text": "@{outputs('Get_EmailContents_by_ID')?['body/tt_emailsubject']}",
"ReplacementMapping": "@{outputs('Update_EmailTemplate')}"
}
  • EmailBody Replacement:
{
"text": "@{outputs('Get_EmailContents_by_ID')?['body/tt_emailbody']}",
"ReplacementMapping": "@{outputs('Update_EmailTemplate')}"
}

Compose Email

Compose EmailSubject: Output from subject wildcard replacement
Compose EmailBody: Output from body wildcard replacement

Send Email

  • Add a new Email Messages row
Table: Email Messages
Activity Parties: EmailRecipientsArray
  • Perform SendEmail bound action
Table: Email Messages
Action Name: SendEmail
Row ID: Email Message ID
IssueSend: Yes

Final Response

  • Respond to PowerApp or Flow
{
"Success": "Success"
}

Summary

This flow automates post-signature actions for Engagement Letters:

  • It retrieves and updates Contact and Document Approval records.
  • Email templates are dynamically built with placeholders replaced using the ReplaceWildcardsInText utility.
  • Relevant recipients (Manager, Tax Senior, Reception, BCC, Sender) are compiled into a dynamic recipient list.
  • The flow completes by sending a customized email and returning a success response to PowerApps.