Finance agents (previously known as Copilot for Finance) are Microsoft’s AI-powered assistants designed to help with financial operations directly within Excel and Outlook to:
- Excel: Reconcile and match financial data.
- Outlook: Draft clear, personalized emails and seamlessly attach outstanding invoices or account statements.
In this article, we explore how Outlook functionality integrates with Dynamics 365 Finance and Operations (D365FO) to manage customer communications. You’ll learn how Docentric can help you to retrieve and attach outstanding invoices and customer account statements faster and make your documents look more professional.
What is the Finance agent for Outlook
The Finance agents streamline the collections process directly within Outlook. Key features include:
- Attach documents: Quickly find and attach outstanding invoices and account statements from D365FO.
- Summarize email correspondence: Automatically generate concise summaries from the complete email correspondence to clarify payment details.
- Draft emails: Create tailored and professional collection emails with automatic attachments.
- Single source of truth: Update critical details like transactions, contacts, action items, and customer interactions.
How does the Finance agent work in Outlook
With the Finance agents in Outlook, you can retrieve four different types of documents for a customer: sales invoice, free text invoice, project invoice, and account statement.
Linking the sender's email to the customer
The process starts when you receive a customer’s email. Open the Finance agent’s pane, and you should see something like this:
The agent can’t automatically find the right customer in your D365FO because the sender’s email needs to be linked first. This is why you need to learn it by following these steps:
- Click the Finance agents icon on the email.
- Click Add next to the email address you want to link to the customer.
- In the customer field, select a customer.
- Enter the customer's first and last name.
- Click Save.
Once this is done, each time we receive an email from that sender, the Finance agent knows which customer it’s linked to.
Attaching documents to the email
After saving the record, the add-in pane will look a bit different. The Suggest a reply button has now changed to a dropdown:
Now, we can select Reply with overdue invoices to get a preview of which invoices will be included:
Here, we can remove the invoices that we don’t want to attach to the email. We can also ask it to draft a message using a prompt. After clicking the Add to draft button, the invoices are attached as a ZIP file to the email:
This is the moment when the reports are generated in D365FO. Let’s learn how that works!
Generating the reports
The standard solution uses a data entity called SrsFinanceCopilotEntity, which is called by the agent using the runCopilotReport OData action.
If you check the action’s code, you can see that it takes five parameters:
- _legalEntityName: the legal entity where the customer is.
- _controllerName: the name of the report’s controller class (e.g., SalesInvoiceController, FreeTextInvoiceController, etc.).
- _controllerArgsJson: a JSON string containing details required by the controller class, specifying the record from which information should be retrieved.
- _contractName: the report’s data contract class name.
- _reportParameterJson: a JSON string with parameters used by the contract class.
To generate the reports, the method does the following steps:
- Creates a GUID that’s used as the RunId of the report and adds it to the contract.
- Initializes an Args object with the controllerArgsJson values.
- Initializes a contract class SrsCopilotReportContract with the information from the _reportParameterJson parameter.
- Runs the main method from the controller class using contracts and args from the earlier steps.
- Uses the SRSFileUploadTempStorageStrategy class to return a List object with the URLs of the generated reports.
- Finally, it loops through the URL list, gets the files from each, and returns each as a base64-encoded string.
The method runs once for each pending invoice or account statement.
Adding Docentric to it!
The purpose of the proof of concept project was to see if we could generate the reports using Docentric instead of the standard SSRS ones, and it was possible!
The extension we’ve created does not just use Docentric templates, it also improves the print process.
Using Docentric improved print archive
First, we search for the documents in the Print archive improved by Docentric, and if they’re there (they are already generated), we return them, and the process ends.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
public static str getReportForPrintArchive_DC(Common _jourTable) { DocJournalType jourType = DocJournalType::NA; if (_jourTable is CustInvoiceJour) { jourType = DocJournalType::CustInvoiceJour; } else if (_jourTable is ProjInvoiceJour) { jourType = DocJournalType::ProjInvoiceJour; } if (jourType != DocJournalType::NA) { DocPrintJobHeader docPrintJobHeader; select firstOnly docPrintJobHeader order by RecId desc where docPrintJobHeader.JournalType == jourType && docPrintJobHeader.JournalRecId == _jourTable.RecId; if (docPrintJobHeader) { container reportContent = docPrintJobHeader.getReportInPdfFormat().parmContent(); return DocGlobalHelper::convertToBase64String(DocGlobalHelper::convertContainerToBytes(reportContent)); } } return null; } |
Checking if Docentric is used
If it’s not in the print archive, we will reprint the report.
First, we retrieve the print management settings if there are any. This happens in the getPrintMgmtPrintSettingDetail_DC() method.
Once we have this, we initialize the controller based on the report that will be printed. We support sales order invoices, free text invoices, project invoices and the customer account statement.
Finally, we check if the print medium type contains the suffix “_DC” which means it’s a Docentric print destination, and we get the TemplateId.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
PrintMgmtPrintSettingDetail printSettingDetail; printSettingDetail = SrsFinanceCopilotEntity::getPrintMgmtPrintSettingDetail_DC( _controllerName, args.record()); DocReportTemplateId templateId; boolean isDocentric = false; SysDictClass controllerDict = new SysDictClass(className2Id(_controllerName)); SrsReportRunController controller = controllerDict.makeObject(); switch (_controllerName) { case 'SalesInvoiceController': controller.parmReportName(PrintMgmtDocType::construct(PrintMgmtDocumentType::SalesOrderInvoice).getDefaultReportFormat()); break; case 'FreeTextInvoiceController': controller.parmReportName(PrintMgmtDocType::construct(PrintMgmtDocumentType::SalesFreeTextInvoice).getDefaultReportFormat()); break; case 'PSAProjAndContractInvoiceController': controller.parmReportName(PrintMgmtDocType::construct(PrintMgmtDocumentType::SIProjInvoice).getDefaultReportFormat()); break; case 'CustAccountStatementExtController': controller.parmReportName(PrintMgmtDocType::construct(PrintMgmtDocumentType::CustAccountStatement).getDefaultReportFormat()); break; default: return null; } controller.parmArgs(args); if (printSettingDetail) { SRSPrintDestinationSettings printDestinationSettings = printSettingDetail.parmPrintJobSettings(); isDocentric = (enum2Symbol(enumNum(SRSPrintMediumType), printDestinationSettings.printMediumType()) like '*_DC'); templateId = printDestinationSettings.parmSrsPrintReportSettings_DC().parmTemplateId(); controller.parmReportName(printSettingDetail.parmReportFormatName()); } if (!isDocentric) { DocReportTable report = DocReportTable::findReportSRSReportName(controller.parmReportName()); isDocentric = report && report.IsActiveSRS && report.UseDocentricPreviewForSrs; } if (!isDocentric) return null; |
Generate the report
If it’s a Docentric destination, it uses the Docentric template. Otherwise, we return null to continue with the standard SSRS process.
Finally, we print the reports and convert them to a base64 string like the one the standard uses.
1 2 3 4 |
// Start the report execution and wait until report content is not generated as container. container generatedDocument = reportGenerator.generateReport(); return DocGlobalHelper::convertToBase64String(DocGlobalHelper::convertContainerToBytes(generatedDocument)); |
These changes take advantage of things like Docentric’s enhanced print archive or print destinations.
Conclusion
By using Finance agents and Docentric-generated documents within Outlook, Account Receivables (AR) teams can streamline collections, boost productivity, and reduce operational overhead.
Docentric’s advanced printing capabilities significantly enhance the standard functionality, creating a seamless, efficient user experience while making your documents look more professional - in D365FO and also in the Finance agent.
Download Docentric AX FULL Edition to take full advantage of Finance agents integration today!