Category Archives: Blog
Enhancing General Ledger Visibility with Purchase Invoice Details in Dynamics 365 Business Central for a Maldives Financial Institution and an Abu Dhabi-Based Diversified Holding Company
Summary In Business Central, users may need to view relevant purchase invoice details directly from General Ledger Entries for better transaction visibility and traceability. This enhancement was implemented based on requirements identified across multiple Business Central implementations, including projects for a leading UAE-based consortium and a financial institution in the Maldives. The solution enables purchase invoice details to be automatically captured against relevant General Ledger Entries for new transactions, while also providing an option to update previously posted entries. This helps finance users quickly identify the related invoice information without having to navigate through multiple pages or documents. Table of Contents Introduction Understanding the Business Requirement The Challenge with Standard G/L Entry Descriptions Displaying vs. Storing the Description Designing the Solution Updating Historical G/L Entries Maintaining the Description for New Entries Implementation Approach Business Impact Frequently Asked Questions Conclusion Introduction In day-to-day financial operations, users often need to trace General Ledger Entries back to the original purchase transactions for verification, reconciliation, and reporting purposes. However, the standard General Ledger view may not always provide enough contextual information to quickly identify the details of the related purchase invoice. Based on requirements identified across multiple Business Central implementations, including projects for a leading UAE-based consortium and a financial institution operating in the Maldives, an enhancement was introduced to make relevant purchase invoice details available directly within General Ledger Entries. The enhancement improves transaction visibility by capturing the relevant purchase invoice description against the General Ledger Entry. For newly posted transactions, the information can be populated automatically, while previously posted entries can be updated through a dedicated action. This approach reduces the need for users to navigate between General Ledger Entries and posted purchase invoices, making financial review and transaction tracing more convenient and efficient. Understanding the Business Requirement From a Finance user’s perspective, the requirement was straightforward: When a user reviews a G/L Entry, the Description should provide meaningful information about the transaction. The requirement needed to work for both existing historical entries and transactions posted after the customization was introduced. Historical G/L Entries Business Central may already contain a significant number of posted G/L Entries. These historical records also needed to have the enhanced description populated. Updating these entries individually would not be practical. Therefore, the solution needed to provide a controlled way to update existing G/L Entries in bulk. New G/L Entries For future transactions, the description should be populated automatically during the posting process so that users do not have to manually update the G/L Entry after posting. This resulted in two key requirements: Provide a mechanism to populate descriptions for historical G/L Entries. Automatically maintain the description for newly created G/L Entries. The Challenge with Standard G/L Entry Descriptions The first question during the design was whether the required description could simply be calculated when the G/L Entry page was opened. At the page level, a value can be calculated dynamically based on related information. This approach can be useful when the requirement is simply to display additional information to the user. However, there is an important distinction between displaying a calculated value and storing that value in the underlying G/L Entry record. A page-level calculated value does not automatically become part of the underlying G/L Entry data. Therefore, although a user may see the expected description on the page, the value may not be available in the same way for other processes that directly consume the G/L Entry data. Key Design Consideration The requirement was not only to display a meaningful description. The description needed to be persisted against the G/L Entry record. Displaying vs. Storing the Description This distinction became an important part of the solution design. Page-Level Calculation A page-level calculation is useful when the requirement is simply: “Show this information to the user.” The value can be generated when the page is opened without modifying the underlying G/L Entry record. Persisted G/L Entry Description For this requirement, the description needed to become part of the actual G/L Entry data. The solution therefore stores the generated description directly against the G/L Entry. G/L Entry → Determine Transaction Information → Generate Description → Store in G/L Entry This approach ensures that the description remains available after the page is closed and can be consumed by other Business Central processes that use the G/L Entry record. Designing the Solution The solution was designed around two scenarios: historical G/L Entries and newly created G/L Entries. 5.1 Historical G/L Entries A dedicated action is provided to populate the enhanced description for existing G/L Entries. This allows Finance users or authorized administrators to update historical records without having to process each entry individually. 5.2 Newly Created G/L Entries For newly posted transactions, the description is maintained as part of the G/L Entry creation process. This means that the enhancement does not depend on users remembering to manually update the description after every posting. Two-Part Approach Existing Entries: One-time controlled update. New Entries: Automatic description population during the posting process. Updating Historical G/L Entries Since the system may already contain historical G/L Entries, simply implementing the logic for future postings would leave existing records without the enhanced description. To address this, we introduced a one-time action that allows the required description to be generated and stored for historical entries. The process can be represented as: Existing G/L Entries → Run Update Action → Determine Required Information → Generate Description → Update G/L Entry This approach provides a practical way to bring historical records into the same structure used for newly posted transactions. Maintaining the Description for New Entries Updating historical records solves only one part of the requirement. The same description logic also needs to be applied to future G/L Entries. Therefore, the solution ensures that the description is generated and stored when the relevant G/L Entry is created. This avoids a situation where historical records have the enhanced description while newly posted transactions continue using the previous standard behavior. Business Transaction → Posting → G/L Entry Created → Generate … Continue reading Enhancing General Ledger Visibility with Purchase Invoice Details in Dynamics 365 Business Central for a Maldives Financial Institution and an Abu Dhabi-Based Diversified Holding Company
Share Story :
How an Australia-Based Commercial Laundry Company Built a Custom Dynamics 365 Sales Dashboard Beyond Standard Reporting
Summary The sales team at commercial laundry and linen rental organization could open any record in Dynamics 365 and still could not answer how much of the open book sat in healthcare. Sector was never a field on a deal, it was four boolean flags on the product, three joins away from the quote a manager wanted to group. We replaced the standard sales dashboards with Custom Sales Dashboard that reads the Dataverse Web API directly, rolls sector up through the line items, and puts leads, opportunities, quotes and signed contracts under a single set of filters. Every tile, cell and chart segment opens the records behind it and exports to Excel with real numbers and real dates. Table of Contents Summary→ Business Challenges→ Solution Overview→ Technical Approach→ Impact→ Conclusion→ Get in touch→ Business Challenges Commercial laundry and linen rental organization runs multiple laundries, called plants in the CRM, and quotes work by the weight a customer sends each week. A deal is a weekly tonnage and a weekly dollar figure before it is anything else, which is why the standard sales charts had so little to say about it. The reporting asks were ordinary. The data model underneath them was not, and every ask broke on a different part of it. Sector is not stored on the lead, opportunity, quote or order. It is independent flags on the product record: healthcare, motel, garments, etc. A chart grouped on the quote has no column to group by A single product can carry more than one flag, so one quote can legitimately belong to two sectors. Grouping without a rule double counts the same dollars Total Amount reads 0.00 on every quote and every order in the org. All money sits in annualrevenue and weeklyrevenue, which the standard sales charts and rollups do not read Contracts are salesorder records. The out of the box contract table is empty, so anything pointed at it returns nothing at all The plant lookup laundry is populated on roughly six quotes in ten. The rest only know their laundry through the originating opportunity Orders copied from an accepted quote frequently carry no line items of their own, so a product level report built on order lines quietly loses them Managers wanted one choice of sector, sales person or plant to move leads, opportunities, quotes and contracts together. Standard dashboards filter each chart against its own entity Nobody could see the forward book: which signed contracts start in the next twenty weeks, and what weekly tonnage each start week brings ⚠The real blocker Every one of these needs a value computed from grandchild rows, from the quote down to its lines down to the product flags. The chart designer groups on fields that exist on the record being charted, and this one does not exist anywhere. Solution Overview We built one page that lives inside the CRM as a web resource. It opens like any other dashboard, signs the user in with the session they already have, and reads live records rather than a nightly copy. The page carries six tabs. Overview holds a pipeline matrix and the stage, sector, sales person and plant mix. Pipeline Activity plots leads and quotes created per week for the last fifteen weeks. Contracts Won shows the forward book by contract start week. Win and Loss compares closed won against closed lost by value and by count. Approvals and Activities measures how long contract, logistics and freight rate decisions take. Reports lists contracted and quoted stock at product line level. Three filters at the top, sector, sales person and plant, drive every chart, tile and table on every tab at once A fourth filter, customer, appears only on the Reports tab because it only narrows those two tables Clicking any chart segment, matrix cell or tile opens a drawer listing the records behind that exact number Each row in the drawer links to the real CRM form, and the whole selection exports to Excel with numbers as numbers and dates as dates ⓘWhy the drill through mattered more than the charts A sales manager who cannot see the eleven contracts behind a bar will not act on the bar. Registering the source records for every visual was the difference between a picture and a working tool. Technical Approach Where the page runs The dashboard is a single HTML web resource, customDashboard, shipped in the main solution. Running inside the model driven app means it inherits the user’s authentication and their record level security, so a sales person sees their own scope without us writing a line of security code. It resolves the org URL from parent.Xrm.Utility.getGlobalContext() and falls back to window.location.origin when it is opened outside a form, which is what makes local debugging possible. SourceDataverse Web API v9.2Live reads with the signed in user’s context Load14 parallel queriesOne Promise.all on page open IndexLookup maps and sector indexProduct flags resolved once, then cached RenderMatrix, tiles and Chart.jsRedrawn in memory on every filter change ActDrawer and XLSX exportRecords behind the number, typed for Excel Everything loads once. Accounts, factories, depots, leads, opportunities, quotes, orders, the three line item tables, products, freight rates, delivery point risk assessments and activities all come down in a single Promise.all, and every later interaction is a filter over arrays already in memory. Changing a filter costs nothing on the network. Rolling sector up from the product The rollup walks the line items of a quote, order or opportunity, reads the flags off each product, and weights each sector by line weight times quantity. The heaviest sector becomes the primary, which is what the breakdown charts group on so the totals stay additive. The full list is kept separately and is what the sector filter tests against, so a quote that touches healthcare and motel appears under both filters and is counted once in the donut. cf_customDashboard.html, sector rollupjavascript function rollupSectors(lines, productIdField) { const weight = {}; lines.forEach(l => { const sectors = PRODUCT_SECTORS[String(l[productIdField] || ”).toLowerCase()] … Continue reading How an Australia-Based Commercial Laundry Company Built a Custom Dynamics 365 Sales Dashboard Beyond Standard Reporting
Share Story :
How a Leading North American Commercial Vehicle Manufacturer Managed Return Purchase Orders and Warehouse Return Movements in Dynamics 365 Finance & Operations
Summary Return Purchase Orders affect operational health and are often overlooked in implementation planning. This guide covers the return workflow in Dynamics 365 F&O: creating return orders, executing warehouse movements, managing supplier shipments, and reconciling credits to accounts payable. We address configuration practices, warehouse operations, challenges (including trade agreement alignment), reporting frameworks, and integration patterns for multi-system environments. Table of Contents 1. The Problem: Why Return Purchase Orders Matter 2. The Core Flow: Return Purchase Order in D365 F&O 3. Warehouse Return Movement 4. Linking Movements to Returns 5. Configuration Deep Dive 6. Trade Agreement Alignment After Returns 7. Warehouse Practices 8. Configuration Checklist 9. Issues & Resolutions 10. Integration Considerations 11. Reporting & Monitoring 12. FAQs 1. The Problem: Why Return Purchase Orders Matter In any supply chain, orders don’t always go as planned. Quality issues, over-shipments, damage, and spec mismatches happen. When they do, the warehouse receives material that doesn’t meet requirements—and the system needs to reflect that. A Return Purchase Order is not just a procurement transaction. It’s an operation that touches procurement, inventory management, warehouse operations, and finance. Miss a step, and you create: Inventory mismatch — on-hand quantities that don’t match physical stock Supplier master data drift — invoices tied to prices that no longer apply after returns Warehouse disruption — excess stock, blocked pallets, confusion on what’s usable Finance rework — accruals and liabilities out of sync This guide walks through how D365 F&O handles Return Purchase Orders, with focus on the warehouse return movement process that keeps physical and system inventory in sync. Procurement Warehouse Finance Original PO Return Order (linked to PO) Create Return order # referenced Transfer Journal Active Floor → Return Staging Ship Ship to Supplier RMA / credit note Credit Reconciled against Return OrderThe Return Purchase Order flow crosses three systems: a return order in Procurement drives a Transfer Journal in the Warehouse, which drives a credit reconciliation in Finance — connected end to end by the return order number. 2. The Core Flow: Return Purchase Order in D365 F&O Step 1: Create a Purchase Order Return When material needs to be returned to the supplier: Navigate: Accounts Payable → Purchase Orders → All Purchase Orders Select the original PO Action: Click Return Order (in the Ribbon, or Create menu) System creates a return order linked to the original PO, with: Supplier reference intact Quantities that can be adjusted (typically the original received quantity is pre-populated) Line item details copied from the original PO Status = Open Configuration: Return orders inherit the original PO’s delivery address and supplier terms, but warehouses can override the receiving location if the return flows through a different staging area. Accounts payable › Purchase orders › All purchase orders › PO-000482 › Return order PostConfirmCancelPrint Return order numberRO-000091 StatusOpen Vendor accountV-10234 — Acme Components Inc. Original purchase orderPO-000482 WarehouseWH-MAIN Return-to locationRETURN_QA Item number Product name Qty to return Unit price Line amount IT-4021 Steel Bracket 40mm 25 $50.00 $1,250.00 IT-4088 Hex Bolt Set 10 $12.50 $125.00 Illustrative mockup of a Return Order form — not an actual product screenshot. The return order carries the original PO reference, vendor, and return-to location into the warehouse process. Step 2: Warehouse Return Movement Once the return order exists, the warehouse must physically move material out of active inventory. In D365, this happens via Transfer Journal or Movement Journal, depending on your configuration. 3. Warehouse Return Movement Options Active Floor Transfer Journal Return Staging QA Hold Returnable Not returnable Ship to Supplier Scrap / Write-offOnce material reaches Return Staging, the path splits: returnable stock ships back to the supplier under the return order; non-returnable stock is scrapped through an Inventory Adjustment journal. Option A: Transfer Journal (Used in Most Implementations) Used when material physically moves from one warehouse/location to another (e.g., floor → return staging area). Navigate: Inventory Management → Journals → Transfer Journal Create new journal entry Add lines: From warehouse: where the inventory currently sits To warehouse: return staging/quarantine area Item number, quantity, UOM Assign to Return Purchase Order (optional reference field) Post System adjusts on-hand in “From” warehouse, increases in “To” warehouse Inventory management › Journal entries › Transfer journal › RETURN-TRANSFER-0091 PostValidateLinesInquiries Journal nameRETURN-TRANSFER StatusDraft ReferenceRO-000091 Posting date09/16/2026 Item number From warehouse / location To warehouse / location Quantity IT-4021 WH-MAIN / ACTIVE_FLOOR WH-MAIN / RETURN_QA 25 IT-4088 WH-MAIN / ACTIVE_FLOOR WH-MAIN / RETURN_QA 10 Illustrative mockup of a Transfer Journal — not an actual product screenshot. The Reference field carries the return order number so the warehouse movement stays traceable to Finance. Workflow:Active Floor → Return Staging → Ship to Supplier(Transfer Journal 1) → (Transfer Journal 2 or direct shipment) Option B: Inventory Adjustment Journal Used if you’re removing defective/unsaleable inventory entirely (scrap, damage). Navigate: Inventory Management → Journals → Inventory Adjustment Create new journal Add lines: Item, warehouse, quantity Mark as “Loss” or “Damage” Post On-hand reduced; writeoff recorded When to use: Only when the material cannot be returned to supplier (scrap/damage). Do NOT use for supplier returns—you lose the linkage to the Return Purchase Order. 4. The Critical Step: Linking Movements to Returns This is where many implementations stumble. Problem: You create a return order and move inventory, but the two are never connected. Result: Finance doesn’t know which returns have been physically staged Accounts payable credits the invoice without visibility into what’s actually coming back Warehouse can’t track which pallets belong to which return Without a Link With a Link Return Order Warehouse Movement Finance / AP Return Order Warehouse Movement Finance / AP Return Order # Return Order #Without a shared reference, the return order, the warehouse movement, and the finance record never connect. Carrying the return order number through the transfer journal and into the credit memo links all three. Solution: Before posting the movement journal, reference the Return Purchase Order number in a comment or custom field Or: Use a dedicated warehouse location code (e.g., RETURN_TO_[SUPPLIER_CODE]) that signals items are earmarked for return Approach: Set up … Continue reading How a Leading North American Commercial Vehicle Manufacturer Managed Return Purchase Orders and Warehouse Return Movements in Dynamics 365 Finance & Operations
Share Story :
How We Connected an Azure AI Foundry Agent to Dynamics 365 Using the Dataverse MCP Server for a Texas Industrial Cybersecurity Company
Watch first Your browser does not support embedded video. Download the video instead. Twenty seconds: what the agent does, and why per-user CRM security is the part that is actually hard. 01Summary A Houston-based cybersecurity firm wanted their sales team to ask plain-language questions about CRM data, “how many active leads do we have”, “summarise this account’s open opportunities”, without opening Dynamics 365 and building a view for every question. We built it as an Azure AI Foundry agent connected to Microsoft Dataverse over the Model Context Protocol (MCP). No custom data layer, no synchronised copy of CRM, no bespoke API surface. Dataverse itself is the MCP server, and Foundry’s Agent Service calls it as a tool. The agent runs on GPT-4.1 and took an afternoon to wire up. The two things that actually cost time were an OAuth redirect URL that Foundry generates after you click Connect, and an architecture decision we got wrong the first time: the tenant your agent lives in decides whether per-user CRM security is achievable at all. 02In This Blog A practitioner walkthrough of connecting Foundry to Dynamics 365 over MCP, written around the two failures that cost us the most time rather than the happy path alone. The Scenario: A sales team that wanted answers from CRM without building a view for every question. The Approach: Use Dataverse as a first-party MCP server rather than building an API layer and hand-written function schemas. The Action: Environment enablement, an Entra app registration, the MCP tool with OAuth identity passthrough, and the redirect URL nobody warns you about. The Outcome: Per-user security enforced by Dataverse itself, with no parallel permission model to maintain. The connection is an afternoon. The question of whose identity the agent is acting as decides whether any of it survives contact with production. Table of Contents 01Summary→ 02In This Blog→ 03Why MCP Changes the Shape of This Problem→ 04Enable the MCP Server and Allow Your Client→ 05Register the Entra App→ 06Add the MCP Tool to the Agent→ 07Close the Redirect URL Loop→ 08Consent, and the Consent Loop→ 09Calling the Agent From Your Own Application→ 10The Tenancy Trap→ 11Licensing→ 12Impact→ 13Conclusion→ 14FAQ→ 15Get in Touch→ 03Why MCP Changes the Shape of This Problem Before MCP, connecting an LLM to Dynamics 365 meant building glue: an API layer, a set of hand-written function definitions describing each operation, schema documentation maintained by hand, and a deployment to own forever. Every new table meant another function. The Model Context Protocol replaces that with a contract. The server advertises its tools, the model discovers them at runtime, and the plumbing is the same whichever client connects. Microsoft ships Dataverse as a first-party MCP server, so the glue layer is simply gone. Dataverse MCP endpointurl https://{organisation}.crm{n}.dynamics.com/api/mcp A preview endpoint exists at /api/mcp_preview with additional tools, gated behind a separate environment setting. Check your region number Environment URLs are not always .crm. Ours has been .crm4 on other engagements, and pointing at the wrong host produces an authentication failure that looks like a permissions problem. Confirm it in Power Apps under Settings, Session details. The tool surface Tool What it does search Searches table schemas and business skills by keyword search_data Searches structured and unstructured data describe Returns details for tables, records, schemas, skills and apps read_query Runs supported Dataverse SQL SELECT queries create_record Inserts a row, returns the Gcfb-mcp7fd update_record Updates an existing row delete_record Deletes a row, only after explicit user approval create_table, update_table, delete_table Schema operations upsert_skill, delete_skill Manages Dataverse skills and playbooks init_file_upload, commit_file_upload, file_download SAS-based file handling The tool names changed, and older tutorials are wrong describe_table, list_tables and fetch were removed and folded into describe. The tool previously called search, which searched data, is now search_data, and search now searches metadata. If you maintain an allow list or deny list by tool name in your client, this rename silently changes what your agent can do. Review it. 04Step 1: Enable the MCP Server and Allow Your Client This is admin work in the Power Platform admin center, not maker work, and it is where most failed attempts stall. Open the environment settingsPower Platform admin center, then Manage, then Environments. Open the target environment and select Settings on the command bar. Turn on the MCP serverExpand Product, select Features, find Dataverse Model Context Protocol, and enable Allow MCP clients to interact with Dataverse MCP server. Open the allowed client listSelect Advanced Settings. This is where non-Microsoft and custom clients are registered individually. Add your client and enable itCreate an Allowed MCP Client record carrying the Application Id of the app registration you create in Step 2, then set Is Enabled to Yes. Copilot Studio is enabled by default. Nothing else is. Your Foundry agent is not Copilot Studio, so it needs an explicit entry. This is the single most common cause of “the connection succeeded but the agent never calls the tool”. Field Value Name A readable label, for example Foundry Dataverse Agent Unique Name A unique identifier for the record Application Id The client (app) ID of the Entra app registration from Step 2 Is Enabled Yes Figure 1: The Allowed MCP Client record. Is Enabled defaults to No. Is Enabled defaults to No Saving the record is not the same as enabling it. A disabled record behaves identically to no record at all, and produces no error anywhere. Set it to Yes before you save. This is a chicken-and-egg with Step 2: you need the Application Id before you can fill this in. Create the app registration first, then come back. Two constraints worth knowing before you plan the rollout: Managing the MCP server through Advanced connector policies requires the environment to be a Managed Environment. The allow list applies only to the /api/mcp agent entrypoint. MCP-named custom APIs are ordinary Dataverse APIs and are not restricted by this setting. If you want the preview tools, enable Allow MCP clients to interact with Dataverse MCP server (Preview version) as a … Continue reading How We Connected an Azure AI Foundry Agent to Dynamics 365 Using the Dataverse MCP Server for a Texas Industrial Cybersecurity Company
Share Story :
How CloudFronts Built a Project Risk Assessment Engine with Databricks Genie
The Warning Signs Were Always There – Project Risk Engine Summary On most delivery projects, the warning signs appear well before the escalation. They sit in email threads, support case notes, overdue invoice reminders, and resource utilization reports – scattered across systems that nobody has the time to cross-reference every week. By the time a project gets formally marked at risk, it is usually already a difficult conversation. This post shares what we built at CloudFronts to solve that problem from the inside. The Project Risk Engine uses a multi-model AI approach running on Azure Databricks to read unstructured project communication, score project health, and flag projects in RED – all surfaced to project managers inside Microsoft Teams through Databricks Genie, in plain English. We built it for our own PMO first. This article walks through why we built it, how it works, and what it changed. Table of Contents 01 Where This Started 02 Where Project Health Actually Lives 03 What the Risk Engine Does 04 How It Works – Four Layers 05 How a Project Gets Flagged RED 06 Genie in Teams 07 What Changed for the Team 08 Who It Helps 09 How to Implement This 10 Challenges We Faced 11 FAQs 12 Conclusion Where This Started This did not start as a product idea. It started as a recurring frustration inside our own team – the group at CloudFronts responsible for delivery and billing excellence. Three things kept happening. Early warning signs were buried in long email chains, so risks only surfaced after they had grown. Project managers had no quick way to assess project health, which meant the team reviewed each project by hand every week just to work out where things stood. And because we run many projects simultaneously, it was easy for a real problem to slip through unnoticed. Here is a real example. One of our clients had a support agreement coming up for renewal. It is the kind of thing everyone assumes someone else is tracking – but it was not flagged until almost the last day. If that client had decided not to renew, leadership would have had no early warning at all. The information was there. It just was not in front of anyone in time. In another case, a project had two phases and the client had not yet confirmed the scope for the second. That was a clear risk to the final payment. Most of us were aware of it in some abstract way – but the project was not formally flagged until the invoice was already due. A few weeks earlier would have made a real difference. “The warning signs were already there. They were just scattered, and easy to miss until it was too late.” Where Project Health Actually Lives A project’s health is not in one place. It is spread across four areas – and any one of them, left unmonitored, can become a risk that affects cash flow, client relationships, or delivery quality. Booking Contract renewals, new work coming in, and MSA status. A contract quietly approaching expiry is a risk most teams only notice when it is almost too late. Billing & Delivery Project status, open risks, support tickets, internal notes, and the client emails tied to them. This is where the unstructured signals sit. Collection What has been invoiced, what is outstanding, and what is running overdue. Delayed invoicing and unpaid milestones are early indicators of a project in trouble. Resource & Utilization Who is working on what, how busy they are, and where allocation gaps are forming. Low utilization on a contracted engagement is a billing risk waiting to happen. Any one of these on its own does not tell you much. You only see the full picture when you put all four together – and that is exactly what the engine does. What the Project Risk Engine Does 1Unifies the data – Delivery, support, billing, and resourcing data from Dynamics 365 CRM and Outlook is pulled into one governed dataset on Azure Databricks, structured through a Medallion Architecture (Bronze → Silver → Gold). 2Reads the unstructured signals – AI reviews client emails, internal notes, and case history to surface hidden threats: delays, blockers, escalation patterns, and unanswered client requests that never make it into a status field. 3Scores and flags – Every project receives a health score from zero to ten, along with a risk summary, identified threats, and next recommended actions. Projects meeting RED criteria are automatically flagged. 4Makes it conversational – Project managers can ask questions about any project in plain English, directly inside Microsoft Teams through Databricks Genie. No dashboards to open, no reports to pull. How It Works – A Multi-Model, Four-Layer Approach The risk analysis is not a single AI call. It is a deliberate, layered process – lightweight checks first, heavy AI only where it is needed. This keeps it fast and cost-efficient while ensuring accuracy on the things that matter. Layer1 Rule-Based Pre-Filter No AI involved. Simple rules filter out inactive email threads not part of any recent communication, eliminating noise before any model is engaged. Layer2 Lightweight AI Triage A smaller model sorts remaining threads into four categories: active, completed, informational, or waiting. Only active and waiting threads move forward. Layer3 Deep Risk Analysis A larger model – Claude Sonnet 4.5 – runs deep analysis on threads that survived the first two layers. It is used here because this stage requires stronger reasoning: detecting underlying threats, assessing likelihood, and estimating impact. Layer4 Executive Summary Everything is rolled up into a project health score (0–10), top threats, and recommended next actions – a clear, evidence-backed picture of where each project stands. Solution Architecture Here is how the full architecture fits together – from data sources through to the project manager asking a question in Teams. Data flows from Dynamics 365 CRM and Outlook → Azure Logic Apps → ADLS Gen2 Medallion layers → Azure Databricks → Genie AI → Microsoft Teams … Continue reading How CloudFronts Built a Project Risk Assessment Engine with Databricks Genie
Share Story :
Location Movement Scanning in Dynamics 365 Finance & Operations: Turning Warehouse Floor Movements into Traceable, Scanner-Directed Work
Summary This article covers the implementation of barcode-based location movement scanning in Dynamics 365 Finance & Operations (WMS) for a North American manufacturing operation. The physical warehouse was built into D365 using an Aisle–Rack–Shelf–Bin location model created through the Location setup wizard, and Work templates, Location directives and Mobile device menu items were configured so that every material movement becomes directed, scanner-guided work. Multi-stage routing with enforced stop-work breaks ensures that complex movements across stations are captured step by step, replacing paper-based and manual location tracking with real-time scanning on the Warehouse Management mobile app. Finally, inventory adjustment journals close the loop so that work-order completion reconciles on-hand inventory accurately. Table of Contents Introduction The Business Problem The Solution Building the Warehouse Location Model (Aisle–Rack–Shelf–Bin) Creating Locations with the Location Setup Wizard Enabling the Worker on the Warehouse Mobile App Work Templates Location Directives Mobile Device Menu Items The Multiple Scanning Movement Process Inventory Adjustment Journals for Work-Order Closure Implementation Considerations & Limitations Business Impact FAQs Conclusion 1. Introduction In Microsoft Dynamics 365 Finance & Operations, the warehouse is only as accurate as the data captured on the floor. Every receipt, put-away and internal move has to be recorded against a precise physical location, otherwise on-hand inventory, replenishment and downstream planning all drift out of alignment. For high-volume manufacturing and distribution operations, keying that information manually is slow, error-prone and impossible to audit after the fact. Location movement scanning solves this by making the warehouse location itself the anchor of every transaction. Instead of typing where something is, an operator scans it. Dynamics 365 F&O Warehouse Management (WMS) turns those scans into directed work — the mobile device tells the worker exactly where to go, what to pick and where to put it, and the system records each step in real time. This article walks through how location movement scanning was designed and delivered for a North American commercial vehicle manufacturing operation as part of a Warehouse Management, Inventory and Scanning rollout. It covers how the physical warehouse was modelled in D365, how the Aisle–Rack–Shelf–Bin location structure was created, and how Work templates, Location directives and Mobile device menu items work together to convert a floor movement into a traceable, scanner-guided sequence — all closing out cleanly against inventory. Scan on the mobile device Directed work system-guided steps Accurate inventory real-time, to the binFigure 1. Location scanning turns a floor movement into directed, traceable work with real-time inventory. 2. The Business Problem The operation runs a large, multi-zone warehouse footprint where materials move continuously between receiving, pick stations, sub-assembly areas and staging. Before the D365 F&O rollout, location tracking depended heavily on manual entry and local knowledge. Workers knew where things were, but the system frequently did not. As volume and layout complexity grew, several operational problems surfaced: On-hand inventory did not reliably reflect the physical location of stock. Internal movements between aisles, racks and stations were captured inconsistently, or after the fact. There was no directed, enforced sequence for multi-step movements, so steps were skipped or done out of order. Work could not be traced — it was difficult to prove who moved what, from where, to where, and when. Manual keying of long item and location codes introduced errors that rippled into planning and replenishment. Reconciling inventory at the end of a work order required time-consuming manual investigation. The business needed the physical warehouse represented accurately inside D365, and every movement on the floor captured through scanning — directed by the system, enforced in the right order, and reconciled against inventory without manual guesswork. The Objective: Model the warehouse down to the bin, and make every material movement a scanner-directed, traceable transaction so on-hand inventory, work status and location data stay accurate in real time. 3. The Solution Dynamics 365 F&O Warehouse Management provides the full building blocks for scanner-directed movement: a structured location hierarchy, Work templates that define the sequence of steps, Location directives that decide where each step happens, and Mobile device menu items that expose the process on the handheld scanner. The solution was assembled in layers — first the physical location model, then the worker enablement, then the three configuration objects (templates, directives, menu items) that turn a movement into directed work, and finally the inventory reconciliation that closes it out. Work templatesWHAT stepsPick · Custom · Put sequenceLocation directivesWHERE it happensresolves the exact binMobile menu itemsHOW on the scannerstart / resume work Directed, scanner-guided work every floor movement — enforced & traceableFigure 2. Work templates, Location directives and Mobile menu items combine into a single directed-work engine. 3.1 Building the Warehouse Location Model (Aisle–Rack–Shelf–Bin) The foundation of location scanning is a location structure that mirrors the physical warehouse. In this rollout the model followed an Aisle–Rack–Shelf–Bin hierarchy, using a location profile (RSBA) applied consistently across warehouse zones such as floor locations, tugger lanes and rack storage. Each physical position becomes an addressable location in D365 that a barcode can represent. Getting this hierarchy right is what allows a single scan to resolve to an exact bin. Location hierarchy Site └─ Warehouse └─ Aisle └─ Rack └─ Shelf └─ Bin ← scannable location SiteWarehouseAisleRackShelfBin — scannable locationFigure 3. The Aisle–Rack–Shelf–Bin location hierarchy modelled in D365, resolving to a scannable bin. 3.2 Creating Locations with the Location Setup Wizard Locations were generated using the Location setup wizard rather than created one by one, which keeps naming consistent and saves considerable effort across a large footprint. Navigation Warehouse management > Setup > Warehouse > Locations > Location setup wizard Steps 1. Open the Location setup wizard 2. Set up all relevant details (profile = RSBA, aisle/rack ranges) 3. Click Create 4. Repeat per bin identifier: Enter “A” → Create Enter “B” → Create Enter “C” → Create Because the bins were A, B and C, the create step was repeated for each. To verify, open the Location field, filter by “C”, and confirm every location generated for the “C” rack is present. The same wizard-driven … Continue reading Location Movement Scanning in Dynamics 365 Finance & Operations: Turning Warehouse Floor Movements into Traceable, Scanner-Directed Work
Share Story :
From Prospecting to Pipeline Intelligence: How We Embedded LinkedIn Sales Navigator into Dynamics 365 Sales for a Texas-Based, Cybersecurity & Azure Services Company
Summary For technology services companies selling AI, cybersecurity, and Azure solutions, the hardest part of selling is rarely finding a company — it’s finding the right decision-maker, the right relationship path, and the right moment to engage. We recently implemented LinkedIn Sales Navigator inside Microsoft Dynamics 365 Sales for a Texas-based technology services company specializing in AI, cybersecurity, Azure, and cloud services. The goal wasn’t to drop a LinkedIn widget into a form — it was to build a connected prospecting experience where LinkedIn relationship intelligence and Dynamics 365 sales execution work together without forcing sellers to switch between systems. The result: sellers can research prospects, understand account relationships, identify mutual connections, and capture sales activity — all from within the CRM they already use every day. LinkedIn became the intelligence layer; Dynamics 365 remained the operational system of record. This article covers the business requirement, the matching strategy, the CRM synchronization design, and the key lessons learned from turning a LinkedIn integration into an actual sales process change. Table of Contents Introduction The Business Requirement Why LinkedIn Sales Navigator and Dynamics 365? What We Set Out to Achieve Solution Overview Setting Up LinkedIn Sales Navigator Connecting Sales Navigator with Dynamics 365 Sales Embedding Sales Navigator into CRM Forms Designing the Matching Strategy Bringing LinkedIn Intelligence into the Sales Process Icebreakers and Relationship Intelligence Lead Introduction and Related Leads Account Intelligence and Organizational Relationships CRM Synchronization and Activity Writeback Data Validation: Keeping CRM Current Controlling What Gets Written Back to CRM Synchronizing Open Opportunity Information Testing and Validation Business Impact The Strategic Value Beyond Integration Key Implementation Lessons Conclusion Frequently Asked Questions Final Takeaway This Blog Explains Why fragmented prospecting between LinkedIn and Dynamics 365 was costing sellers time and context. What licensing and administrative foundation CRM integration with Sales Navigator requires. Why matching LinkedIn profiles to CRM records is a business problem, not just a technical one. How CRM synchronization and activity writeback were scoped to avoid a noisy, unrestricted sync. How Sales Navigator can surface signals that CRM contact data has gone stale. The measurable improvements to seller workflow, CRM data quality, and account planning. The lessons we’d apply again on the next CRM-to-LinkedIn implementation. Case Study Read more about our Journey with this Customer over here: View Case Study Introduction For technology services organizations, selling is rarely about finding a company and sending an email. The real challenge is identifying the right organization, the right decision-makers, the right relationship path, and the right moment to engage. This becomes particularly important for companies operating across Artificial Intelligence, Cybersecurity, Azure, Cloud, and digital transformation, where sales cycles involve multiple stakeholders, technical influencers, business leaders, and evolving buying committees. We recently implemented LinkedIn Sales Navigator with Microsoft Dynamics 365 Sales for a Texas-based technology services company specializing in AI, cybersecurity, Azure, and related cloud services. The objective was not simply to place a LinkedIn widget inside Dynamics 365 — it was much broader: Create a connected prospecting experience where LinkedIn relationship intelligence and Dynamics 365 sales execution could work together without forcing sellers to continuously switch between systems. The implementation brought LinkedIn Sales Navigator capabilities into the organization’s existing Dynamics 365 Sales environment, enabling sellers to research prospects, identify relevant connections, understand account relationships, create and update CRM records, and capture relevant sales activity within the CRM ecosystem. This Dynamics 365 Sales LinkedIn integration as a way to bring real-time intelligence about prospects and organizations into the sales process, including profile information, mutual connections, key decision-makers, and other sales insights. For this organization, the value came from turning that capability into a business process rather than simply a software integration. The Business Requirement The client already had Dynamics 365 Project Operations & Sales as its CRM platform and LinkedIn as an important channel for professional prospecting and relationship building. However, the sales process naturally crossed between the two platforms. A typical seller workflow could involve: Finding a target company. Searching LinkedIn for decision-makers. Researching their background. Looking for mutual connections. Checking whether the person already existed in Dynamics 365. Reviewing the account’s existing opportunities. Deciding how to approach the prospect. Creating or updating the CRM record. Recording the interaction. Returning to Dynamics 365 to continue managing the opportunity. Each individual step is manageable. The problem emerges when this happens repeatedly across dozens or hundreds of prospects. The organization needed to reduce this fragmentation. The business requirement centered around five objectives: 1. Improve prospect discovery Help sellers identify relevant people and organizations more efficiently. 2. Improve relationship intelligence Allow sellers to understand mutual connections, organizational relationships, and relevant prospect information. 3. Reduce application switching Bring useful LinkedIn intelligence directly into the Dynamics 365 sales experience. 4. Improve CRM data quality Create mechanisms for identifying outdated information and reducing duplicate or disconnected prospect records. 5. Preserve CRM as the operational system of record LinkedIn should enhance the sales process, not create a parallel sales database. That last point became one of the most important principles of the implementation. Why LinkedIn Sales Navigator and Dynamics 365? LinkedIn Sales Navigator is fundamentally a prospecting and relationship intelligence platform. Dynamics 365 Sales, on the other hand, provides the CRM and sales execution layer. The strategic opportunity was to combine the two. LinkedIn provides access to professional and organizational intelligence, while Dynamics 365 provides the business context around: Accounts Contacts Leads Opportunities Activities Sales pipeline Ownership Customer history When these systems are connected correctly, the seller does not need to think in terms of two disconnected applications. Instead, the experience becomes: Discover → Understand → Engage → Capture → Progress LinkedIn’s Sales Navigator highlights CRM Sync capabilities such as auto-save, activity writeback, CRM badges, ROI reporting, and search filtering. CRM integration is available with Sales Navigator Advanced Plus. D365 CRM allows to surface LinkedIn information directly within Dynamics 365 Sales through Sales Navigator controls and embedded experiences. What We Set Out to Achieve Our objective during the implementation was to go beyond the technical connection. … Continue reading From Prospecting to Pipeline Intelligence: How We Embedded LinkedIn Sales Navigator into Dynamics 365 Sales for a Texas-Based, Cybersecurity & Azure Services Company
Share Story :
SAP Business Data Cloud: More Than a Data Platform
Summary Enterprises have spent years solving the data extraction problem — moving SAP data into warehouses, lakes, and reporting platforms. But extraction is largely a solved problem. The real challenge now is making that data understandable, trustworthy, and useful — to both business users and AI systems. That shift requires business context, metadata, and governance, not another connector. This blog shares observations from an enterprise data modernization assessment and offers a perspective on how SAP Business Data Cloud should be evaluated — not as just another extraction tool, but as a capability that can bring SAP data, business semantics, metadata, and governance closer together. It also examines why zero-copy data sharing, while valuable, is only part of the answer, and why metadata strategy should be defined before any platform is selected. The central argument is straightforward: AI without trusted business context produces answers that are technically valid but business-wrong. Before any AI layer is added, the foundation must be right — and that means starting with the right question: not “which tool?” but “what does this organization need its data platform to become?” Table of Contents 01 Introduction 02 Extraction Is No Longer the Challenge 03 BDC Is Not Just a Connector 04 Metadata Is the Foundation 05 Zero-Copy — Important but Incomplete 06 From Technical Data to Business Data 07 The AI Conversation 08 Evaluate the Outcome, Not the Tool 09 So, Why SAP Business Data Cloud? 10 FAQs 11 Conclusion Introduction Most conversations about SAP data integration start in the wrong place. They begin with extraction — which tool moves data fastest, which connector supports CDC, which platform has the best SAP adapter. These are reasonable technical questions, but they are increasingly the wrong ones to be leading with. The organizations genuinely advancing their data capabilities are not asking “how do we get SAP data out?” They are asking “how do we make SAP data understandable, trustworthy, and useful — to both our people and our AI systems?” This blog shares observations from an enterprise data modernization assessment and offers a perspective on how we should be thinking about SAP Business Data Cloud — not as just another extraction option, but as part of a broader conversation about metadata, business context, and what modern enterprise data platforms actually need to deliver. Data Extraction Is No Longer the Biggest Challenge Over the years, organizations have invested heavily in moving data from ERP systems into data warehouses, data lakes, and reporting platforms. The architecture often becomes: SAP → Extraction → Staging → ETL → SQL → Semantic Model → Power BI It works. But over time, every additional layer introduces another copy of data, another technology to maintain, another process to monitor, and another place where business logic can be implemented. In one enterprise modernization assessment, the existing landscape included SAP, DP Agents, SAP Datasphere, SSIS, SQL Server, and Power BI. The challenge was not a shortage of technology. The challenge was multiple movement layers, duplicated logic, and no single place where the data could be understood as a whole. That is where the conversation about SAP BDC needs to start. BDC Is Not Just Another SAP Connector If we compare SAP BDC only on extraction capability, the difference becomes difficult to justify. Most modern tools — BDC, Datasphere, and various DBT-based approaches — can all support data extraction and incremental or CDC scenarios to varying degrees. But when we introduce another dimension — business context — the discussion changes entirely. A modern enterprise data platform needs to answer: 1What does this field actually mean in business terms? 2Is this a customer, vendor, product, or financial measure? 3What is the agreed business definition — and who owns it? 4Which KPIs depend on this data element? 5How does this business object relate to others? 6Can this data be trusted — and can an AI agent understand its context? This is where metadata stops being a nice-to-have and becomes the foundation on which everything else depends. Metadata Is the Foundation Metadata should be one of the first things defined before selecting a data platform. Technology should follow business requirements — not the other way around. A modern metadata strategy needs to cover: Business Metadata Technical Metadata Relationships Business Glossary Semantic Definitions Data Quality Ownership Lineage Classification & Change Why does this matter? Because the direction of enterprise analytics is shifting: From “Where is my data?” To “What does my data mean?” And eventually “Can AI understand my data and give me a trusted answer?” That progression requires context — and context requires metadata. You cannot shortcut this by starting with AI. “The future of analytics is not about finding data faster. It is about understanding data better — and making that understanding available to both people and AI systems.” Zero-Copy Is Important — But It Is Not the Whole Story One of the strongest technical capabilities highlighted in the assessment is BDC’s managed zero-copy data sharing approach. It can reduce unnecessary data movement while allowing SAP data to participate in the broader enterprise data architecture without being physically duplicated across systems. This matters because data movement has a cost — in infrastructure, in latency, in maintenance, and in the accumulation of inconsistent versions of the same data sitting in different places. But zero-copy should not be positioned as the only reason to choose BDC: Zero-copy solves the movement problem — reducing duplication and infrastructure cost Metadata and business semantics solve the understanding problem — making data meaningful and trusted The second problem is becoming increasingly important, and it is the one most extraction-focused evaluations fail to address. From Technical Data to Business Data A traditional data platform is typically designed around tables and pipelines. A modern data platform needs to move closer to business objects and business domains. Instead of asking a business user to understand technical SAP table names like VBAK, VBAP, KNA1, or MARA, the platform should provide business-level concepts: Customer → Sales Order → Product → Revenue → … Continue reading SAP Business Data Cloud: More Than a Data Platform
Share Story :
From Trading Partner cXML to Infor LN Sales Order: How a European Life-Sciences Manufacturer Automated EDI Order Intake with Azure Integration Services
Summary A global life-sciences and laboratory equipment supplier sends purchase orders to our customer (BÜCHI’s customer-centric vision accelerates innovation using Azure Integration Services | Microsoft) as machine-generated cXML OrderRequest.xml documents. The customer runs Infor LN, which expects a SalesOrder BOD delivered through the Infor ION I/O Box. Between the two sat a translation problem that was being solved by hand. Every order arriving from the trading partner had to be read, interpreted and re-keyed into Infor LN by the order desk. That worked at low volume. It did not scale, it delayed order confirmation by hours, and it introduced transcription errors on the fields that matter most — quantities, delivery dates and ship-to addresses. We closed that gap with Azure Integration Services: API Management as the secure front door, Blob Storage as the immutable archive, Service Bus for asynchronous decoupling and retries, Azure Functions in C# for the cXML-to-BOD translation, and a write into the Infor ION I/O Box SQL database from which ION creates the sales order in LN. Key Vault and App Configuration hold secrets and environment-specific values; Application Insights makes every transaction traceable end to end. The result is a straight-through process: Partner posts cXML → Archive → Queue → Transform to BOD → I/O Box → Infor ION → Sales Order in LN. This article covers how the interface was designed, how the mapping and its business rules were kept maintainable, how failures are handled and replayed, and the guardrails that keep an asynchronous EDI interface trustworthy in production. Table of Contents From Manual Order Entry to Automated Order Intake The Business Challenge Solution Overview Receiving the Purchase Order: Azure API Management Decoupling the Interface: Azure Service Bus Translating cXML into the Infor Process.SalesOrder BOD The Business Rules Hidden Inside the Mapping Writing to the Infor ION I/O Box Handling Exceptions, Retries and Replay Technical Architecture Monitoring with Application Insights Designing the Integration Around Business Events Business Impact Design Constraints and Guardrails Final Thoughts This Blog Explains Why manual order entry from EDI purchase orders stops scaling, and what it costs. How a partner cXML OrderRequest is received, archived and queued on Azure. How the cXML document is translated into an Infor Process.SalesOrder BOD. How conditional business rules — partner cross-references, note construction, ship-date fallbacks — are kept out of hard-coded logic. How multi-line orders are looped into SalesOrderPosition blocks. How the BOD is handed to Infor LN through the ION I/O Box. How failures are retried, dead-lettered and replayed without asking the partner to resend. How a single transaction ID makes the whole interface searchable in Application Insights. From Manual Order Entry to Automated Order Intake For manufacturers that sell through large, process-driven customers, the order does not arrive as a phone call or an email attachment. It arrives as a machine-generated EDI document, posted to an endpoint at any hour of the day, in a format defined entirely by the buyer. Our customer — a European division of a global life-sciences and laboratory equipment supplier — runs Infor LN as its ERP. Their key trading partner sends purchase orders as cXML OrderRequest.xml documents. Infor LN, on the other side, expects a Process.SalesOrder BOD delivered through the Infor ION I/O Box. Both systems were working exactly as designed. The problem lived in the space between them, and that space was being crossed by a person with a keyboard. A purchase order that arrives electronically and is then typed in by hand is not an integrated process. It is a manual process with an electronic first step. The objective of the project was therefore narrow and concrete: when the trading partner posts an order, a sales order should appear in Infor LN — correctly mapped, without human intervention, and with enough visibility that the support team can prove it happened. The Business Challenge On the surface this looks like a file conversion. In practice, five things made it anything but. 1. Two Schemas That Share Almost No Vocabulary cXML is a flat, attribute-heavy commerce format. The Infor BOD is a deeply nested OAGIS structure with an ApplicationArea envelope, a DataArea payload and a UserArea carrying LN-specific properties. Almost every field required transformation rather than a straight copy. 2. Business Logic Hidden Inside the Mapping The partner’s identity codes had to be cross-referenced to Infor LN business partner IDs — with different values in Test and Production. Header comments needed a hardcoded Remark: prefix. Goods marks, customer references and order numbers had to be concatenated into a single footer note, skipping the values that did not arrive so no blank lines were left behind. 3. A Ship Date With a Rule of Its Own Requested ship date could not simply be copied. If the line carries a date, use it. If it is missing, or in the past, use the current date. If the order has multiple lines with different dates, take the earliest. A rule that reads as one sentence in a specification becomes a decision tree in code. 4. Line-Level Repetition A single order can contain many ItemOut elements, each of which becomes a SalesOrderPosition block in the BOD, carrying its own item ID, quantity, required delivery date and note. 5. No Second Chances, and No Visibility The exchange is asynchronous and real-time. If a message failed silently, the first sign of trouble would be the customer asking why their order had not shipped. Operations needed to answer “what happened to this order?” without raising a support ticket. Manual re-keying was the fallback, and it carried exactly the costs you would expect: order entry delays measured in hours, transcription errors on quantities and delivery dates, and a team doing work that added no value. Solution Overview We built the interface on Azure Integration Services as a set of small, independently deployable components rather than one monolithic job. The solution uses: Azure API Management Azure Blob Storage Azure Service Bus Azure Functions (C#) Infor ION I/O Box (SQL) Azure Key Vault and App Configuration Application … Continue reading From Trading Partner cXML to Infor LN Sales Order: How a European Life-Sciences Manufacturer Automated EDI Order Intake with Azure Integration Services
Share Story :
How a Maldives-Based Loan Firm Streamlined Multi-Level Payment Approvals with Microsoft Dynamics 365 Business Central
Summary As part of our implementation for HDFC Maldives, we encountered a complex payment approval requirement in Microsoft Dynamics 365 Business Central involving multiple approval stages, any-one-user approval behavior, Checked By validation, actual approver tracking, and Internet Banking approval. Instead of replacing the standard Business Central workflow framework, we extended it only where the required business behavior differed from the standard process. This approach allowed us to retain Workflow User Groups, Approval Entries, workflow progression, and standard approval capabilities while introducing custom controls for Checked By processing, Sequence 2 approval handling, actual approver logging, and final payment voucher traceability. Table of Contents Introduction Understanding the Business Requirement What Worked with Standard Business Central? The Challenge at the Second Approval Sequence Finding the Right Approach The Second Challenge: Who Actually Approved? Introducing the Actual Approver Log Why Checked By Was Kept Separate Automatic Transition to Standard Approval Improving Payment Voucher Traceability Final Solution Architecture Preview Video Business Impact Frequently Asked Questions Conclusion Introduction Approval workflows often look straightforward when they are first discussed: one person submits a transaction, the required approvers review it, and the process continues once approval is completed. In practice, the requirements can become much more complex when different stages need different approval behaviors. During a loan management implementation for a Maldives-based financial services organization, we encountered exactly this situation while designing the approval process for Payment Journals in Microsoft Dynamics 365 Business Central. The business did not want a simple sequential approval process. Some stages required any one authorized user to complete the approval, another stage required a separate pre-check before the standard workflow could begin, and the final payment process required two Internet Banking approvals. The challenge was therefore not simply to configure a workflow. It was to determine how much of the standard Business Central approval framework could be retained, where customization was genuinely required, and how to maintain an accurate audit trail of the users who actually performed each approval action. The Design Principle Rather than replacing Business Central’s standard workflow framework, we decided to keep the standard approval engine wherever possible and customize only the areas where the required business behavior differed from the standard process. Understanding the Business Requirement The Payment Journal required several approval stages, with different rules at each level. Stage Approvers Required Behavior Checked By Multiple Checkers Any one authorized checker Sequence 1 2 Approvers Any one approver Sequence 2 4 Approvers Any one approver Internet Banking 2 Approvers Two-level validation The intended business process was: Payment Journal → Checked By – Any One → Sequence 1 – Any One of 2 → Sequence 2 – Any One of 4 → Posting → Internet Banking Approval At first glance, the standard Workflow User Group functionality appeared capable of handling most of this requirement. However, testing revealed an important difference between the expected business behavior and the approval behavior encountered at the later approval sequence. Fig: Payment approval workflow configured for the multi-stage payment process. What Worked with Standard Business Central? Workflow User Groups were the natural starting point because they already provide a structured way to maintain approvers without hardcoding individual users in custom development. For the first approval sequence, two approvers were configured and the required behavior worked as expected. Sequence 1 Approver A + Approver B → Any one approver completes the stage → Workflow continues This initially suggested that the standard approval configuration would be sufficient for the entire process. The benefit of continuing with standard Business Central was significant because the platform was already managing Workflow User Groups, Approval Entries, statuses, approval requests, cancellations, notifications, and workflow progression. The Challenge at the Second Approval Sequence The main challenge appeared when the transaction progressed to the second approval sequence. Four approvers were configured at this level, but the business requirement remained the same: any one of the four authorized approvers should be able to complete the stage. Expected Behavior Approver C / Approver D / Approver E / Approver F → Any one approves → Approval stage completes However, the workflow behavior encountered at this subsequent sequence did not allow the stage to complete in the required manner after only one user approved. The transaction remained pending because the approval requests associated with the sequence were still active. This created the central mismatch between the standard workflow behavior encountered during testing and the customer’s required approval model. Finding the Right Approach One option would have been to replace the approval process entirely with a custom approval engine. We deliberately avoided that approach. Business Central was already successfully handling several important parts of the process: Workflow User Groups Approval Entries Approval statuses Sending approval requests Cancelling approval requests Workflow progression Rebuilding all of this would have introduced unnecessary complexity and additional maintenance. The Approach Keep the standard Business Central workflow and customize only the approval behavior that did not meet the business requirement. For the second approval sequence, we introduced a custom Approve Approval Request action that allows one authorized approver to complete the required stage while preserving the surrounding standard workflow framework. :contentReference[oaicite:4]{index=4} The Second Challenge: Who Actually Approved? Solving the approval progression created another important requirement. When one user completed the customized approval stage, the related standard Approval Entries could ultimately reflect an Approved status for the eligible approvers. Consider four users: Approver C Approver D ← Actually clicked Approve Approver E Approver F If the final Approval Entries are reviewed only by status, they may not clearly identify that Approver D was the person who physically performed the approval action. This became especially important because the Payment Voucher needed to answer a very simple audit question: Who actually clicked Approve? The standard Approval Entry status alone was therefore not sufficient for the reporting requirement. :contentReference[oaicite:5]{index=5} Introducing the Actual Approver Log To preserve the identity of the person who actually performed the approval, we introduced a separate Actual Approver Log. At the moment the user performs the approval action, the solution captures: User ID … Continue reading How a Maldives-Based Loan Firm Streamlined Multi-Level Payment Approvals with Microsoft Dynamics 365 Business Central
