Category Archives: Dynamics 365
How a Leading North American Commercial Vehicle Manufacturer Triggers MRP On Demand Using a Custom X++ Service in Dynamics 365 Finance & Operations
MRP Batch Trigger Service Summary Planning Optimization (what most F&O teams still call MRP out of habit) normally runs on a fixed recurrence: nightly, or every few hours. That’s fine until an upstream event lands between runs and the plan needs to reflect it before the next window opens. Rather than reconstructing the entire Planning Optimization call from scratch, this post covers a smaller, safer pattern: a custom X++ service that finds the existing, already-configured batch job and flips its status to Waiting, so the batch framework picks it up on its next poll. Same job, same configuration, just triggered early. The example is drawn from an engagement with a North American truck manufacturer, where an upstream integration needed to nudge Master Planning immediately after a data load rather than wait out the scheduled recurrence. On this page 01The business trigger 02Why reuse the batch job, not rebuild the call 03Where the batch job’s RecId comes from 04The service class 05Exposing it as a callable service 06Gotchas worth knowing 07FAQs 08Conclusion The business trigger Planning Optimization is normally left alone once it’s configured: coverage groups, item coverage, and a batch recurrence tell it when to run, and most days that schedule is all anyone needs. The gap shows up when a trigger for a fresh plan doesn’t come from the calendar; it comes from another system. A large sales order import lands late, an engineering change lands mid-afternoon, or an upstream integration finishes a nightly sync on its own schedule, and the planning team needs the recalculated plan before the next window opens, not after. Manually opening Master Planning parameters and clicking “Run now” doesn’t scale when the trigger has to come from outside the ERP entirely. Why reuse the batch job, not rebuild the call Planning Optimization isn’t a simple in-process function call. The batch task hands off to an Azure-hosted optimization engine, carrying policy and configuration that already lives in Master Planning setup: coverage groups, item coverage codes, the plan itself. Reconstructing that entire call from a custom service would mean duplicating configuration the system already tracks, and keeping two copies of it in sync forever. The simpler move: find the batch job the system already runs on its recurrence, and change its status so the batch framework picks it up on the next poll instead of waiting for the scheduled time. Same job, same configuration, just triggered early. Where the batch job’s RecId comes from The service doesn’t look the batch job up by caption at runtime; captions get renamed, retranslated, or duplicated, which makes name-matching fragile. Instead, the correct job’s RecId is captured once, during setup, and stored on a custom parameters table (here, a field on ReqParameters). The trigger call then becomes a single indexed select instead of a caption search. Ops note: because the pointer is a raw RecId, it breaks silently if the batch job is ever deleted and recreated. An LCS environment refresh or a redeploy of the batch setup is enough to do it. Re-capture and re-save the RecId as part of any environment refresh checklist. The service class The method is deliberately thin: find the configured batch job, flip its status inside a transaction, and report back what happened. CFMRPOptimizationBatchTriggerService.xpp internal final class CFMRPOptimizationBatchTriggerService { public CFMRPOptBatchTriggerServiceResponseContract triggerMRPOptBatchJob() { CFMRPOptBatchTriggerServiceResponseContract response = new CFMRPOptBatchTriggerServiceResponseContract(); try { BatchJob batchJob; select firstOnly forUpdate batchJob where batchJob.RecId == ReqParameters::find().MRPOptBatchJobRefRecId; if (!batchJob.RecId) { response.parmMessage(“Planning Optimization batch job was not found.”); } else if (batchJob) { ttsbegin; batchJob.selectForUpdate(true); batchJob.Status = BatchStatus::Waiting; batchJob.update(); ttscommit; response.parmMessage(strFmt( “Planning optimization batch job found and triggered. ID: %1, Description: %2, Status: %3”, batchJob.RecId, batchJob.Caption, enum2Str(batchJob.Status))); } } catch (Exception::Error) { response.parmMessage(“Trigger failed”); } return response; } } Three things worth calling out in that order of execution: The initial select firstOnly forUpdate locates the job and prepares it for a later update, but it sits outside any transaction at that point. The real lock happens with the selectForUpdate(true) call just before ttsbegin, which is what actually matters for correctness under concurrent triggers. Flipping Status to Waiting is the entire “trigger.” Nothing here talks to the Planning Optimization engine directly; that’s the batch framework’s job once it sees a waiting task. The response contract carries a single human-readable message, which is enough for a calling system to log success or failure without needing to parse the batch job’s internal state itself. Exposing it as a callable service The class itself is just X++. Making it callable from outside the ERP is a standard AOT step: 1Add an AOT Service node referencing this class and the triggerMRPOptBatchJob method. 2Add the service to a Service Group and deploy. F&O exposes it over the standard integration endpoint once deployed, callable from an integration platform or middleware without any custom endpoint code. 3Have the calling system read parmMessage to confirm the job was actually found and flipped, rather than treating a successful call as proof that MRP ran. The trigger is fire-and-forget from the batch engine’s side. Gotchas worth knowing “Waiting” is not “running now.” The status change queues the job for the batch server’s next poll, typically seconds to a couple of minutes later depending on batch server load, not a synchronous MRP run. Don’t build a caller that blocks waiting for a result. The catch block swallows the real error. catch (Exception::Error) returns a flat “Trigger failed” with no diagnostic detail retained. That’s fine for a demo; in production it means the caller, and whoever gets paged, has no idea why it failed. Worth extending to log the actual exception before returning the generic message. Retriggering a running job is harmless, but a symptom. Flipping an already-Executing job back to Waiting doesn’t start a second concurrent run. If a caller is doing that repeatedly in a tight retry loop, though, it’s usually a sign the caller isn’t checking the response message before retrying. “A trigger service doesn’t need to reimplement what Master Planning already knows how to run. It only needs to … Continue reading How a Leading North American Commercial Vehicle Manufacturer Triggers MRP On Demand Using a Custom X++ Service in Dynamics 365 Finance & Operations
Share Story :
How a U.S. Industrial Cybersecurity Company Built a Custom Sales Portal with Power Apps Code Apps
Summary A Houston based cybersecurity company came to us with a familiar complaint. Their sales leaders had everything they needed sitting in Dynamics 365, yet every Monday review still started in Excel. They asked for two things: their reports laid out the way they actually think about the business, and an assistant they could simply ask questions. We delivered both in one app, built with Power Apps Code Apps on top of the CRM data they already had. In This Blog What was slowing the sales team down What we built for them, screen by screen The AI agent we added so leaders can just ask What changed for the business How to tell if this approach fits your team Table of Contents Summary→ Business Challenges→ What We Built→ The AI Agent→ How It Works→ Impact→ Is This Right for You?→ Conclusion→ FAQ→ Get in Touch→ Business Challenges Nothing was broken. The data was good and the team was using the CRM. The trouble was getting answers out of it quickly. A standard view shows you a list of records, which is great when you are working a lead. It is far less helpful when the sales director wants to know how many leads turned into real opportunities this quarter, and who brought them in. So the weekly routine looked like this: Open one view, then another, then a third, to piece the funnel together. Export everything to Excel and rebuild the same pivot table as last week. Walk into the meeting with numbers that were already a few days old. What the team really wanted was simple: better looking reports they could read at a glance, and an AI agent alongside them to answer the questions the reports did not cover. Before Several views to see one picture Weekly exports and pivot tables Numbers out of date by meeting time After Key numbers on the first screen One set of filters for everything Answers by simply asking What We Built Power Apps Code Apps let us design the screens completely from scratch while still reading the same Dynamics 365 data, live. Think of it as a new front door to the CRM, arranged around the questions the leadership team asks every week. Nothing was copied or moved anywhere else. The app has four pages, and they all work the same way, so people only learn it once: LeadsWhere new interest comes from and how much of it qualifies. OpportunitiesThe live pipeline, in the order leadership reviews it. SalesWhat has closed and how the team is tracking. ProjectsWhat happens after the deal is won, from Project Operations. Each page opens with the headline numbers, such as total leads, open leads, qualified leads and the qualification rate. Below that sits a single filter bar for owner, status, account, dates and search. Change one filter and every number, chart and list on the page updates with it. The summary page: headline numbers, a trend over time, and breakdowns by customer, source and owner. Shown with demo data. When a chart raises a question, the detail page shows the actual records behind it, already filtered the same way. The detail page, using the same filters as the charts. Shown with demo data. The AI Agent The second half of the request was an assistant. Code Apps do not include one, so we built our own AI agent and placed it in a side panel inside the app. Leaders type a question the way they would ask a colleague, and the agent answers from the live CRM data. Questions like which lead came in most recently, which owner has the best qualification rate this quarter, or which accounts have open deals but no new leads. Things that used to need an export now take a few seconds. In practice this is the feature people mention first when they talk about the app. Want to see how the agent itself was built? We covered that in our earlier post on how we connected an Azure AI Foundry agent to Dynamics 365 for the same client. The AI agent answering a question about the most recent active lead. Shown with demo data. How It Works You do not need to be technical to follow this. There are really only four moving parts. Step oneSign in as usualSame Microsoft account, nothing new to remember Step twoPower Apps opens the appInside the platform you already use Step threeYour custom screensNumbers, charts and lists in your layout Step fourLive CRM dataAlways current, never copied How the pieces fit together, including the AI agent. A few things matter here for the business. People only see the records they were already allowed to see in Dynamics 365. There is no separate portal to pay for or look after. And because the app sits inside a normal Dynamics 365 solution, moving it from testing to live was as routine as any other release. Worth knowing before you start Users cannot save their own personal views in this kind of app, so the filters need to be planned with the team up front. Very heavy reporting may still be better in Power BI. And it is built by a developer rather than configured, so plan for someone to own small changes after go live. Impact One place for the whole story. Leads, pipeline, sales and delivery sit side by side instead of in four corners of the CRM. Questions get answered on the spot. The AI agent handles the ones nobody built a chart for. No new licences or logins. It runs on what the client already owned, under the security they already manage. Is This Right for You? Code Apps are not a replacement for everything in Dynamics 365. This is how we usually explain the choice to clients. This projectCode App Standard Dynamics 365 app Power Pages Who it is for Your own team, when they need a view built around their role Your own team, for everyday record work … Continue reading How a U.S. Industrial Cybersecurity Company Built a Custom Sales Portal with Power Apps Code Apps
Share Story :
Automating Attribute creation in D365 Project Operations, Using Dataverse OData Metadata APIs for an Internal Project Operations–Finance & Operations Integration
Please find this CloudFronts Product at – Integration Module between Dynamics 365 Project Operations and Finance & Operations | Microsoft Marketplace Summary Manually creating custom fields in Dynamics 365 Project Operations across multiple environments is time-consuming, error-prone, and blocks automation. This challenge can be addressed by using Dataverse Metadata OData APIs to programmatically create, update, and publish custom attributes during deployment. The process involves authenticating with Azure AD, calling Metadata API endpoints to create attributes, and publishing the changes with the PublishXml action, all through a fully automated approach. As a result, organizations achieve zero manual intervention, environment consistency, integrations, reduced human error, and a reusable framework that can be applied across all field types. Please find this CloudFronts Product at – CloudFronts – PO-FO Connector Table of Contents Introduction Business Challenge Why OData Metadata APIs? Implementation Procedure End-to-End Working Why This Approach Works Real-World Use Cases Conclusion Introduction When integrating external business applications with Microsoft Dynamics 365 Project Operations, it is common to discover that every customer requires additional fields to store information originating from ERP systems, manufacturing platforms, pricing engines, or product lifecycle management systems. For one of our internal projects & Prospect PoC implementing product-centric integrations, we needed a way to provision these custom fields automatically during deployment. Traditionally, creating new columns involves opening the Power Apps Maker Portal, adding fields manually, publishing the table, exporting a solution, and repeating the same process across multiple environments. While this approach works for occasional changes, it quickly becomes a bottleneck for automated deployments and CI/CD pipelines. The Solution: CloudFronts implemented a fully automated approach using the Dataverse Metadata OData APIs, enabling integration deployments to create and publish new Project Operations attributes programmatically. Business Challenge The customer’s integration platform exchanged large volumes of product and financial information with Dynamics 365 Project Operations. Each deployment required several custom attributes such as: Product identifiers ERP reference numbers Financial synchronization IDs External integration keys Processing status fields Creating these fields manually across Development, Test, UAT, and Production introduced several challenges: Manual configuration effort (time-intensive) Human errors (typos, misconfigurations) Environment inconsistencies (field variations across environments) Longer deployment windows Difficult CI/CD automation The Objective: Allow the deployment process itself to provision any missing attributes before importing data, eliminating manual touchpoints entirely. Why OData Metadata APIs? Most developers use the Dataverse Web API for CRUD operations on business records. However, Dataverse also exposes Metadata APIs, allowing developers to programmatically manage the schema itself—including tables, columns, relationships, and option sets. Microsoft documents creating attribute metadata by posting to the Attributes navigation property of an entity definition. This means integrations can: Create new columns dynamically Update existing metadata Publish customizations instantly Eliminate manual portal work Scale across multiple environments consistently Unlike traditional manual solutions, the Metadata API approach is fully programmable, auditable, and repeatable. Implementation Procedure Step 1 – Authenticate with Dataverse The integration first authenticates against Azure Active Directory using an application registration and retrieves an OAuth Bearer Token. That token is then supplied with every Metadata API request. Authentication Flow: Register application in Azure AD Configure permissions for Dataverse access Obtain OAuth 2.0 Bearer Token Include token in Authorization header for all API calls Step 2 – Creating a Custom Attribute The Dataverse Metadata API exposes the following endpoint for creating new attributes: POST /api/data/v9.2/EntityDefinitions(LogicalName=’msdyn_contractlineinvoiceschedule’)/Attributes Instead of creating business records, this endpoint creates metadata at the schema level. For this implementation, we created a new string attribute with the following properties: Schema Name: int_fnoid Display Name: FNO ID Data Type: String Maximum Length: 100 The request body uses the Microsoft.Dynamics.CRM.StringAttributeMetadata type together with standard metadata properties such as SchemaName, DisplayName, RequiredLevel, and MaxLength. Supported Metadata Types: Microsoft supports multiple metadata types through the same endpoint including String, Decimal, Boolean, Picklist, DateTime, Lookup, Currency, and more. Step 3 – Publishing the Metadata Creating an attribute does not immediately make it available. Like changes made through the Power Apps Maker Portal, metadata created through the Web API must also be published. This is accomplished using the PublishXml action. POST /api/data/v9.2/PublishXml The request specifies the entity to publish. After publishing completes successfully, the new attribute immediately becomes available throughout Dynamics 365. End-to-End Working The complete deployment process follows these steps: Integration authenticates with Azure AD. Dataverse access token is generated. Metadata API checks whether the required attribute exists. Missing attributes are created automatically. PublishXml is executed. New attributes become available. Product synchronization begins. External systems start populating the new fields immediately. Integration Points: This Attribute creation setup can be utilized across Logic Apps, Plugins, Azure Functions, and other Custom Workflows. Why This Approach Works ✓ Fully Automated Deployments No manual intervention is required when new integration fields are introduced. ✓ Environment Consistency Development, Test, UAT, and Production remain synchronized because every environment provisions the same metadata through code. ✓ CI/CD Friendly Metadata creation can be incorporated directly into Azure DevOps or GitHub deployment pipelines. ✓ Reusable Framework The same framework can create String, Decimal, Currency, Lookup, Date, Option Sets, and Boolean fields. ✓ Reduced Human Error Eliminates mistakes caused by manual customization and inconsistent naming conventions. ✓ Prevented Duplication Eliminates duplication of records, preventing system garbage in the database. Real-World Use Cases Use Case 1: PO-FO Integration (Project Operations to Finance Operations) For enterprises running integrated Project Operations and Finance Operations modules, this approach ensures that: ERP reference numbers sync automatically across all linked tables Financial synchronization IDs are created before data import External integration keys propagate consistently Processing status tracking fields exist in all dependent entities No manual re-entry of attribute definitions across environments Impact: Reduces deployment time from hours to minutes, eliminates sync mismatches between PO and FO modules, and enables real-time data reconciliation. Conclusion For an internal project and prospect PoC implementing product-centric integrations, automating metadata creation transforms what was previously a manual administrative task into a repeatable deployment process. Rather than relying on solution imports or manual customization through the Power Apps Maker Portal, integrations can now provision required Project Operations attributes on demand … Continue reading Automating Attribute creation in D365 Project Operations, Using Dataverse OData Metadata APIs for an Internal Project Operations–Finance & Operations Integration
Share Story :
How a U.S. Castings Manufacturer Saved Time by Updating Dynamics 365 Without Logging Into CRM
Summary SIP Industries is a Houston-based manufacturer of engineered components. Every new part it makes goes through a six-stage New Product Development (NPD) Business Process Flow in Dynamics 365. Most of the people who approve those stages never open the CRM. They include plant engineers and QA inspectors in India, the U.S. engineering team and customer reviewers. They replied by email, and the CRM team typed each reply into the NPD record and then clicked Next Stage by hand. We replaced that manual relay with three Power Automate flows, plus a small daily reminder flow. Each approver gets an email with one button, which opens a pre-filled HTML form that needs no login. The flows save the answers to Dataverse and move the stage forward once its conditions are met. Nobody keys in approvals or moves stages by hand any more. SI SIP IndustriesEngineered components manufacturer, Houston, Texas Industry Manufacturing Region United States StackDynamics 365 SalesPower AutomateMicrosoft DataverseSharePoint Table of Contents Summary→ Business Challenges→ Solution Overview→ Technical Approach→ Business Impact→ Conclusion→ Connect With Us→ Business Challenges SIP already had a working NPD Business Process Flow on a custom New Product Development table. The stage design was sound. The time went into one recurring loop that the CRM team ran by hand for every stage of every part. New Product Development View A CRM user emailed the approver for that stage and attached or linked the latest drawing The approver replied in the thread, often with a one-line "go ahead" and an estimate buried in the text The CRM user read the reply and typed the decision, notes and dates into the NPD record The CRM user opened the Business Process Flow and clicked Next Stage The CRM user emailed the next team to tell them it was their turn That loop broke down in four specific places. Licensing the approvers was never realistic. A customer reviewer who signs off a sample twice a year does not need a Dynamics 365 seat, training and a password to remember Some stages close on more than one decision. Feasibility needs feasibility approval, engineering approval and a created engineering drawing. First Article Inspection needs both the India QA team and the U.S. engineering team. These approvals arrived in any order and someone had to keep track of which were still missing Drawing approvals stalled for weeks. Nothing reminded the reviewer, so follow-up depended on a CRM user remembering to chase The audit trail lived in personal mailboxes. Opening the NPD record told you the current stage, not who approved it or when Solution Overview We put an email-driven approval layer on top of the existing NPD process. When an NPD record reaches a stage, Dynamics 365 emails the approver for that stage. The email is written for that stage, so a Pattern request shows pattern details and an inspection request shows inspection details. It ends with one button. Engineering Approval Request Received in Outlook The button opens a web form in the approver’s browser, already filled in with whatever the NPD record holds. The form lists the product’s SharePoint documents and accepts new uploads. The approver picks a decision, adds notes and submits. Feasibility Approval Form Dynamics 365 then saves the answers into the right NPD fields. It moves the process to the next stage if that stage’s conditions are now complete, and the next approver gets their email. A rejection or a "Requires Changes" answer keeps the record in its current stage and notifies the NPD team instead. ⓘWho still uses the CRM The NPD team still works in Dynamics 365 and can set any field directly. The automation responds to changes made in the CRM in the same way as changes made through a form. Technical Approach Architecture at a Glance TriggerNPD record savedStatus or an approval field changes Flow 1Send Approval EmailTracked email with a stage-specific button Flow 2Show Approval FormReturns pre-filled HTML for the stage Flow 3Save Approval ResponseWrites answers and uploads to Dataverse and SharePoint DataverseBPF advancesNext stage starts and Flow 1 fires again These three flows run the entire approval loop, and the loop closes itself. When Flow 3 saves an answer, the NPD record changes, and that change triggers Flow 1 again. Flow 1 then either moves a stage whose conditions are now all met or sends the next approver their email. Alongside the loop, a separate reminder flow runs once a day and chases open drawing approvals. Six Stages, Eight Forms New Product Development Form Stage Approver Form Captures Stage Closes When Feasibility Feasibility team, Engineering team Feasibility approval, engineering approval, notes, estimated development timeline, estimated tooling cost Both approvals recorded and engineering drawing created Drawing Approval Drawing reviewer Drawing received, sample required, feedback, approval Reviewer approves on the form Pattern Plant and tooling team Pattern status, foundry, notes Pattern Status set to Ready For Inspection First Article Inspection India QA, U.S. engineering FAI approval and date, sample sent to U.S., shipment date, U.S. approval and comments Both India and U.S. approvals recorded Customer Approval Customer Yes, No or Requires Changes, with the approval date set automatically Customer answers Yes Production Production team Release notification Final stage NPD stages, approvers and the condition that closes each one Six stages produce eight forms because two stages have two separate approvers. Feasibility has one form for the feasibility team and one for engineering. First Article Inspection has one for India QA and one for U.S. engineering. Each form is identified by a stage key: feasibility, engineering, drawing, pattern, fai, fai_us, customer and production. Each form shows only the fields that apply to the record. The India FAI form asks whether a sample was sent to the U.S. only when the drawing reviewer marked a sample as required. It asks for the shipment date only after the sample has gone. Why the Form Lives Inside Power Automate Criteria Power Pages Canvas App Our choiceHTML form from Power Automate Approver opens it without signing in ✗ ✗ ✓ No … Continue reading How a U.S. Castings Manufacturer Saved Time by Updating Dynamics 365 Without Logging Into CRM
Share Story :
How a Sustainability Certification Nonprofit Automated Certificate Generation in Dynamics 365
Summary This post started with a real request. A Netherlands-based sustainability certification company that runs its certification programme on Dynamics 365 wanted the certificates it issues to come straight out of the CRM, instead of being rebuilt by hand in a document every time. The problem itself is common. Certification bodies, testing labs and manufacturers issue certificates every day, and in most organisations that still means a Word template, a lot of copy and paste, and a PDF sent by email. The data that belongs on the certificate already lives in Dynamics 365, so why can’t the certificate come straight from the record? In this blog we build exactly that. A Generate Certificate button on a Dataverse form calls a Custom API, a small plugin hands the data to an Azure Function, and a branded, print-ready PDF comes back in about four seconds. Today the PDF is stored on the record as a base64 string, previewed and downloaded right on the form. Because the renderer only returns bytes, sending the same file to SharePoint, Azure Blob Storage or an email is a change to one step, not a rebuild. In This Blog This blog walks through a complete, working certificate generator for Dynamics 365, from the data model to the button, using a product certification scenario. The Scenario: A certification body issues product certificates and needs every one to be accurate, branded and traceable. The Approach: Keep the data in Dataverse, render the PDF in an Azure Function, and connect them with a Custom API. The Action: One click on the form produces the certificate, stores it on the record and shows a live preview. The Outcome: No manual formatting, no retyping, no per-document licence fees, and a design that can later publish to SharePoint or Blob storage. Table of Contents Summary→ In This Blog→ Business Challenges→ Solution Overview→ Technical Approach→ Impact→ Conclusion→ FAQ→ Get in Touch→ Business Challenges A certificate is a legal statement: this product, made by this company, meets this standard, from this date to that date. When it is produced by hand, the risks are small individually and expensive together. Copy and paste errors. Product names, model numbers and expiry dates are retyped from the CRM into a document. One wrong digit on an issued certificate means a reissue and an awkward conversation. Template drift. Every coordinator keeps a slightly different copy of the Word template, so logos, wording and signatories quietly diverge. No trail. Once the PDF leaves someone’s desktop there is no record of which version was produced, when, or from which data. Platform limits. Dataverse plugins run in a sandbox that cannot lay out and paginate a PDF, and a JavaScript-only solution would expose service keys to every user’s browser. Before Word template and email Values retyped from the record Layout depends on who made it File lives in someone’s Downloads folder No link back to the CRM record After One click on the record Values read directly from Dataverse One design, driven by configuration PDF stored on the record with its hash Preview and download on the same form Solution Overview The demo uses a fictional certification body, Contoso Product Assurance, which certifies products made by manufacturer accounts against its own published standards. The whole flow runs from a single button: FormGenerate CertificateCommand bar button on the Product Certificate form DataverseCustom APIBound action cf_GenerateCertificate PluginCollect the dataCertificate, product, holder and standard AzureRender the PDFFunction returns the file as base64 RecordStore and previewBase64 saved, previewed and downloadable Architecture One click on the form, one PDF back on the record. The dashed box is where SharePoint, Blob storage or email plug in later. Data modelThree custom tables (Standard, Product, Certificate) plus the standard Account table for manufacturers. Custom API and pluginOne server-side entry point. The function key never reaches the browser. Azure FunctionA .NET 10 renderer on the Consumption plan. Vector PDF, embedded fonts, QR code. Form experienceGenerate and Download buttons plus an inline PDF preview panel. A certificate generated from Dataverse data. Every value on it comes from the record; nothing is typed. Technical Approach 1. The data model Everything lives in one solution, CFCertificateGeneration, so it moves between environments as a unit. Table Purpose Key columns Certification Standard What products are assessed against Code, Version, Default Scope, Validity (Months) Certified Product What is being certified Product Number, Manufacturer (Account), Category Product Certificate The issued certificate Auto-numbered Certificate Number, Status, Issue and Expiry Date, Product, Standard, Holder, Signatory, PDF (Base64), File Name, SHA-256, Generated On The Product Certification app: every certificate with its status, validity and when it was last generated. The certificate number is a Dataverse auto-number column with the format CPA-{DATETIMEUTC:yyyy}-{SEQNUM:5}, so numbering is guaranteed unique by the platform rather than by a person. The certificate holder defaults to the product’s manufacturer and can be overridden when a brand owner holds the certificate for a product someone else makes. 2. The renderer The PDF is drawn with SkiaSharp and the QR code with QRCoder, both open source. The same drawing code targets either a PDF page or a PNG bitmap, which means the image you check during development is exactly what the customer receives. Text is real, selectable text in embedded fonts, every graphic is a vector shape rather than an image, and long product names shrink to fit instead of overflowing the frame. CertificateRenderer.csC# public RenderedCertificate RenderPdf(CertificateRequest request) { Validate(request); using var output = new MemoryStream(); using (var document = SKDocument.CreatePdf(output, metadata)) { var canvas = document.BeginPage(842f, 595f); // A4 landscape, in points Draw(canvas, request); // same code paints the PNG preview document.EndPage(); document.Close(); } return new RenderedCertificate(output.ToArray(), FileNameFor(request.CertificateNumber)); } Vector from edge to edge, so quality never breaks There is not a single raster image in the certificate. Every line of text is real text in an embedded font, and the frame, the seal, the dividers and even the QR code are drawn as vector shapes. Zoom to 800%, print it on A3 or project it on a … Continue reading How a Sustainability Certification Nonprofit Automated Certificate Generation in Dynamics 365
Share Story :
How We Built Legal Reports in Word on Business Central for a Home Loan Bank in the Maldives
Summary A home loan bank in the Maldives came to us needing legal, customer-facing reports for loan statements and overdue notices that had to reflect exact facility figures while matching the bank’s letterhead and legal wording. Traditional RDLC-based report development would have created significant IT dependency and delay for a document like this. Instead, our team used Word-based report layouts in Microsoft Dynamics 365 Business Central, which let us design the legal notice in a familiar document tool while Business Central handled populating it with live facility and customer data. We mapped the bank’s Business Central fields into a Word template, tested it against real facility scenarios, and delivered a working legal report in approximately two days, which is a turnaround that would traditionally take weeks with RDLC. This article walks through how we approached the build, using a sanitized sample report in place of the client’s confidential documents, and explains when we’d recommend Word over RDLC for a bank’s reporting needs. Table of Contents Introduction The Problem: IT Bottlenecks and Delayed Customer Documents The Word-Based Reporting Solution 3.1 How the Word-Based Approach Works 3.2 Creating the Word Template 3.3 Mapping Business Central Fields 3.4 Testing and Delivering the Report Sample Walkthrough: The Legal Report We Built Word Report vs. RDLC Report Time and Effort Comparison Why Banking Teams Benefit from Word Reports What Types of Banking Documents Work Best? Business Benefits When RDLC Is Still the Better Choice FAQs Conclusion About the Author Introduction Legal, customer-facing documents are one of the most sensitive parts of any lending business. A home loan bank in the Maldives came to us needing exactly this kind of document: a legal report covering a loan statement and overdue notice, which had to reflect exact facility figures, carry the correct legal clauses, and match the bank’s letterhead, all while pulling live data straight out of Business Central. Producing a document like this inside Microsoft Dynamics 365 Business Central can easily turn into a multi-week project if it’s built the traditional way. RDLC-based reporting usually means a developer has to build and maintain the report layout, write or modify code, configure data sources, and run several rounds of testing before the document is ready to go out to a customer. For a fairly standard legal document, like a loan statement or overdue notice, that kind of timeline is hard to justify. So instead of taking the client down the RDLC route, we proposed another option: Word-based report layouts. Word templates let us design the layout of the legal report in a tool the bank’s own team could later maintain, while Business Central handled populating it with the correct facility and customer data. The key idea: We designed the legal report’s layout and wording in Word, and let Business Central handle pulling in the correct facility data, so the client wasn’t locked into a developer for every future change. This article walks through how we built it, using a sanitized sample report in place of the client’s confidential documents, and explains how a report that would traditionally take weeks of RDLC development was designed, mapped, and delivered in approximately two days using a Word-based approach. The Problem: IT Bottlenecks and Delayed Customer Documents When the client first came to us, their existing experience with reporting was the same one many banks run into: a dependency between operations teams and technical teams that turns a simple document request into a long wait. The kind of request that used to happen internally looked something like this: “Hey, can we get a loan statement that shows the customer’s outstanding EMI, fines, and facility balance in one clean document?” “Sure, I’ll put in a ticket with IT.” [Two weeks later…] “The statement is almost done. It should be ready in another couple of weeks.” [Four weeks later…] “It’s finally here. Wait… the layout doesn’t match our branch letterhead format.” This kind of situation can happen when a relatively standard customer document becomes dependent on development resources. Why Do These Delays Happen? RDLC report layouts can require specialized development knowledge. Developers need time to configure data sources and implement the required reporting logic. Testing and troubleshooting can add additional development cycles. Small formatting changes such as a different overdue clause or a revised disclaimer may require technical assistance. Future modifications can place the document back into the development queue. Branch or collections staff may resort to manual, Word- or Excel-based workarounds while waiting for the official document. The result is a disconnect between the people who understand exactly what a legal notice or statement needs to say and the people responsible for implementing it in the system. The question we asked the client: What if your own operations or collections team could design and maintain these legal documents, using a tool they already know instead of relying on a developer for every change? The Word-Based Reporting Solution Microsoft Word was already familiar to the bank’s operations staff, so we proposed taking advantage of that. Business Central supports using Word templates directly as report layouts, which meant we didn’t need to build the legal report’s presentation through RDLC at all. Instead of developing the entire document presentation through RDLC, we designed the layout directly in Word and mapped Business Central’s available facility and customer data to the appropriate fields within that template. The solution: We used Word for the legal report’s presentation and Business Central for the facility data behind it. This separated document design from complex layout development and gave the client’s operations team greater control over formatting, tone, and compliance wording going forward. How We Approached the Build Our overall process was straightforward: Design the legal report layout using Microsoft Word. Add the required data fields to the Word template. Map those fields to the appropriate Business Central data. Run the report and let Business Central populate the template. Review the generated document with the client and adjust the layout where needed. The important distinction is that the document’s visual … Continue reading How We Built Legal Reports in Word on Business Central for a Home Loan Bank in the Maldives
Share Story :
How a Leading North American Commercial Vehicle Manufacturer Scoped Master Planning to a Single Site or Warehouse in Dynamics 365 Finance & Supply Chain Management
Site-Level Master Planning Summary Multi-plant manufacturers often run Planning Optimization as one global master plan that nets supply and demand across every site and warehouse together. That’s fine right up until each plant has its own planners, its own coverage rules, and its own idea of when on-hand stock should get consumed first. Microsoft’s “Plan for a single site or warehouse in Planning Optimization” feature (Feature Management, available from version 10.0.44) fixes this at the source: a master plan can now filter on stock dimensions (site, warehouse, batch), not just items, so the plan’s entire universe of supply, demand, and coverage data can be scoped to one location. We rolled this out for a North American truck manufacturer running several plants under a single legacy global plan. Splitting planning by site let each plant’s team run and own a plan tuned to what’s actually stocked and consumed there, without touching anyone else’s numbers. On this page 01The problem with one global plan 02What the feature actually changes 03Turning it on 04Building a plan filter on stock dimensions 05Two plants, two different plans 06Running the site-specific plan 07The catch: full filter only 08FAQs 09Conclusion The problem with one global plan A single master plan covering every plant is simple to set up and easy to explain: one run, one set of planned orders, one schedule. It’s also where the friction starts once a business runs more than one plant with different products, different suppliers, and different teams responsible for each. Planners at one plant end up looking at planned orders shaped in part by another plant’s on-hand corrections and forecast edits. A coverage code change made for one site’s parts can shift output for a site that has nothing to do with it. And because it’s one run, a data issue at any single plant (a bad forecast import, a stuck transaction) can delay the plan for every other plant waiting on the same run to finish. What the feature actually changes Master plans have always supported an item filter. What’s new is a Stock Dimensions table sitting alongside the Items table inside the plan filter, meaning a plan can now be scoped by Site, Warehouse, Batch number, or any other inventory dimension, not just by which items it considers. That distinction matters: this isn’t a coverage-code setting that changes how the plan computes numbers for items it already sees. It changes what the plan sees in the first place. The filter cascades to every planning input, including inventory transactions, forecasts, and item coverage settings like safety stock. Two plans with the same items can end up looking at entirely different supply and demand once their stock-dimension filters diverge. Turning it on The feature ships behind Feature Management, disabled by default: 1Open the Feature Management workspace and find Plan for a single site or warehouse in Planning Optimization. 2Enable it. No separate deployment step is needed; the new filter option appears immediately under Master Planning > Setup > Plans > Master Plans. Building a plan filter on stock dimensions With the feature enabled, scoping a plan to one plant is a setup task, not a code change: 1Open or create a master plan under Master Planning > Setup > Plans > Master Plans. 2Open Plan Filter. The Stock Dimensions table now appears alongside the Items table, and any inventory dimension is selectable as a filter field. 3Add the dimension that defines this plant’s scope (typically Site and Warehouse) and set the values that belong to it. Two plants, two different plans The client’s plants didn’t just need separate scopes; they needed separate policies. One plant runs standard assembly parts with no lot tracking; another runs batch-tracked, shelf-life-sensitive components that need on-hand stock consumed before anything else. The stock-dimension filter made both plans possible from the same master plan setup, configured independently: Plant A: Chassis Assembly Filter: Site = 1, Warehouse = WH-CHASSIS Includes on-hand stock and stock transactions No batch dimension; parts aren’t lot-tracked here Standard pegging behavior Plant B: Engine Components Filter: Site = 2, Warehouse = WH-ENGINE, plus Batch number Override Pegging Sequence enabled: on-hand consumed before other supply Shelf dates respected for batch-tracked, perishable-sensitive components Completely independent run schedule from Plant A Neither configuration affects the other. Plant B’s shelf-life logic never touches Plant A’s parts, and Plant A’s simpler setup isn’t forced to carry batch-level complexity it doesn’t need. “A single global plan optimizes for the business on paper. Separate site-level plans optimize for the planners who actually have to run them.” Running the site-specific plan From Master Planning > Run > Master Planning (or the Master Planning workspace), select the plan for the plant you want to run. The system generates planned orders only within that plan’s stock-dimension scope, and nothing from other sites enters the calculation. The standard item filter is still available at run time to narrow further, or it can be left blank to run every item within the plan’s scope. The catch: full filter only This is the detail that caught our planning team off guard the first time: stock-dimension scoping only works through the master plan’s own Plan Filter, not through the ad hoc runtime dialog filter. Open that runtime dialog and only the Items table is available; Site, Warehouse, and Batch simply aren’t selectable there. Practical implication: planners can’t improvise a one-off site-scoped run from the run dialog. Every site or warehouse that needs its own independent plan needs its own master plan record, configured ahead of time, not a flexible plan filtered differently run to run. FAQs 1Does this replace coverage groups or item coverage settings? No. Coverage codes still govern how the plan calculates replenishment for the items it sees. This feature governs what the plan sees in the first place: the stock-dimension filter applies before coverage logic runs. 2Can supply and demand for one item get double-counted across two site plans? Not if the filters are built to be mutually exclusive: different Site/Warehouse combinations with no … Continue reading How a Leading North American Commercial Vehicle Manufacturer Scoped Master Planning to a Single Site or Warehouse in Dynamics 365 Finance & Supply Chain Management
Share Story :
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. Related Case Studies: Emirates Consortium – Customer Success HDFC PLC – D365 Business Central Integrated with Loan Management 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. 1. 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. 2. 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. 1. 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. 2. 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. 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. 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 … 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
