Category Archives: Dynamics CRM

A Custom Solution for Bulk Creating Subgrid Records Using HTML, JavaScript, and Plugins in Dynamics 365

One of the small but frustrating limitations in Microsoft Dynamics 365 is how subgrids handle record creation. If you’ve worked with Opportunities, Quotes, Orders, or any parent–child setup, you’ve probably experienced this: You need to add multiple related records. The system allows you to add them one at a time. Click New. Save. Repeat. It works, but it’s slow, repetitive, and not how users naturally think. Over time, that friction adds up. The Real Problem In our case, an Australia-based linen and garments company, was using Dynamics 365 to manage sales opportunities for hospitality and healthcare clients. Their sales team regularly needed to add multiple products — such as linen packages, garment services, and rental items, to a single Opportunity. These products were organized by categories like: A typical deal didn’t include just one item. It often included five, ten, or more products across different categories. However, the out-of-the-box sub grid experience required them to: There was nothing technically broken. But from a usability perspective, it wasn’t efficient — especially for a fast-moving sales team handling multiple client proposals daily. What they really wanted was simple: Select products by category → Choose multiple items → Add them in one go → Move on. That capability simply wasn’t available within the standard sub grid behavior. Approach Instead of forcing users to follow the repetitive process, we extended the form with a custom solution. We built a lightweight HTML-based interface embedded inside the form. This interface: Once the user confirms their selection, the chosen records are sent to a custom server-side process. From the user’s perspective, the experience becomes: Open selector → Choose multiple items → Click once → All records created. Simple. Fast. Intuitive. What Happens Behind the Scenes While the interface feels straightforward, the actual processing is handled securely on the server. When users submit their selection: This ensures the solution is: The business logic remains centralized and controlled, not exposed on the client side.file. Why This Matters The improvement may seem small at first. But consider users who perform this task daily. Reducing repetitive actions saves time, lowers frustration, and improves overall efficiency. More importantly, it makes the system feel aligned with how users actually work. Instead of adapting their workflow to system limitations, the system adapts to their workflow. That’s where meaningful customization adds value. The Outcome By combining: We created a smooth bulk record creation experience within Dynamics 365. The platform remains intact. The business logic remains secure, and the user experience becomes significantly better. And sometimes, that’s exactly what good system design is about, not rebuilding everything but removing friction where it matters most. We hope you found this article useful. If you would like to explore how AI-powered customer service can improve your support operations, please contact the CloudFronts team at transform@cloudfronts.com.

Share Story :

Building a Smart Document Viewer in Dynamics 365 Case Management

Posted On March 10, 2026 by Tanu Prajapati Posted in Tagged in

This blog explains how to build a lightweight Smart Document Viewer inside a Dynamics 365 any entity form using an HTML web resource. It demonstrates how to retrieve related document URLs using Web API, handle multiple files stored in comma-separated fields, render inline previews, and implement a modal popup viewer all without building a PCF control. Overview In many Dynamics 365 implementations, business processes require users to upload and reference supporting documents such as receipts, contracts, images, warranty proofs, inspection photos, or compliance attachments. These documents are often stored externally (Azure Blob, S3, SharePoint, or another storage service) and referenced inside Dynamics using URL fields. While technically functional, the default experience usually involves: To improve usability, we implemented a Smart Document Viewer using a lightweight HTML web resource that: Although demonstrated here in a Case management scenario, this pattern is fully reusable and can be applied to any entity such as: The entity name and field schema may vary, but the implementation pattern remains the same. Reusable Architecture Pattern This customization follows a generic design: Primary Entity → Lookup to Related Entity (optional) → Related Entity stores document URL fields → Web resource retrieves data via Web API → URLs parsed and rendered in viewer This pattern supports: The entity and field names are configurable. Functional Flow Technical Implementation 1. Retrieving Related Record via Web API Instead of reading Quick View controls, we use: parent.Xrm.WebApi.retrieveRecord(“account”, accountId, “$select=receipturl,issueurl,serialnumberimage” ) Why this approach? Best Practice: Always use $select to reduce payload size. 2. Handling Comma-Separated URL Fields Stored value example: url1.pdf, url2.jpg, url3.png Processing logic: function collectUrls(fieldValue) {     if (!fieldValue) return;       var urls = fieldValue.split(“,”);     urls.forEach(function(url) {         var clean = url.trim();         if (clean !== “”) {             documents.push(clean);         }     }); } Key considerations: Advanced Enhancement: You can add: 3. Inline Viewer Implementation Documents are rendered using a dynamically created iframe: var iframe = document.createElement(“iframe”); iframe.src = documents[currentIndex]; Supported formats: The viewer updates a counter: 1 / 5 This improves clarity for users. 4. Circular Navigation Logic Navigation buttons use modulo arithmetic: currentIndex =     (currentIndex + 1) % documents.length; Why modulo? 5. Popup Modal Using Parent DOM Instead of redirecting the page, we create an overlay in the parent document: var overlay = parent.document.createElement(“div”); overlay.style.position = “fixed”; overlay.style.background = “rgba(0,0,0,0.4)”; Popup includes: Important: Always remove overlay on close to prevent memory leaks. Security Considerations When rendering external URLs inside iframe: Check: If iframe does not render, inspect browser console for embedding restrictions. Why HTML Web Resource Instead of PCF? We chose HTML Web Resource because: When to use PCF instead: Popup Modal Viewer Triggered by ā›¶ button (top-right). Behaviour: No full-page takeover Error Handling Scenarios Handled conditions: Meaningful messages are displayed inside viewer container instead of breaking the form. Outcome This customization: All while keeping client data secure and architecture generic. To encapsulate, this blog demonstrates how to implement a Smart Document Viewer inside Dynamics 365 Case forms using HTML web resources and Web API. It covers related record retrieval, multi-file parsing, inline rendering, modal overlay creation, navigation logic, and performance/security best practices without exposing any client-specific data. If you found this blog useful and would like to discuss how Microsoft Bookings can be implemented for your organization, feel free to reach out to us. šŸ“© transform@cloudFronts.com

Share Story :

How to use Dynamics 365 CRM Field-Level Security to maintain confidentiality of Intra-Organizational Data

Summary In most CRM implementations, data exposure should be encapsulated for both inside & outside the organization. Sales, Finance, Operations, HR, everyone works in the same system. Collaboration increases. Visibility increases. But so does risk. This is based on real-world project experience, for a practical example I had implemented for a technology consulting and cybersecurity services firm based in Houston, Texas, USA, specializing in modern digital transformation and enterprise security solutions. This blog explains: 1] Why Security Roles alone are not enough. 2] How users can still access data through Advanced Find, etc. 3] What Field-Level Security offers beyond entity-level restriction. 4] Step-by-step implementation. 5] Business advantages you gain. Table of Contents The Real Problem: Intra-Organizational Data Exposure Implementation of Field-Level Security Results Why Was a Solution Required? Business Impact The Real Problem: Intra-Organizational Data Exposure Let’s take a practical cross-department scenario. Both X Department and Y Department work in the same CRM system built on Microsoft Dynamics 365. Entities Involved 1] Entity 1 2] Entity 2 Working Model X Department Fully owns and manages Entity 1 Occasionally needs to refer to specific information in Entity 2 Y Department Fully owns and manages Entity 2 Occasionally needs to refer to specific information in Entity 1 This is collaborative work. You cannot isolate departments completely. But here’s the challenge: Each entity contains sensitive fields that should not be editable — or sometimes not even visible — to the other department. Security Roles in Microsoft Dynamics 365 operate at the entity (table) level, not at the field (column) level. Approach Result Remove Write access to Entity 2 for X Dept X Dept cannot update anything in Entity 2 — even non-sensitive fields Remove Read access to sensitive fields in Entity 2 Not possible at field level using Security Roles Restrict Entity 2 entirely from X Dept X Dept loses visibility — collaboration breaks Hide fields from the form only Data still accessible via Advanced Find or exports This is the core limitation. Security Roles answer: ā€œCan the user access this record?ā€ They do NOT answer: ā€œWhich specific data inside this record can the user access?ā€ Implementation of Field-Level Security Step 1: Go to your Solution & Identify Sensitive Fields, usually Personal info, facts & figures, etc. e.g. cf_proficiencyrating. Step 2: Select the field and “Enable” it for Field Level Security (This is not possible for MS Out of the Box fields) Step 3: Go to Settings and then select “Security” Step 4: Go to Settings and then select “Security” -> “Field Security Profiles” Step 5: Either create or use existing Field Security Profile, as required Step 6: Within this one can see all the fields across Dataverse which are enabled for Field Security, Here the user should select their field and set create/read/update privileges (Yes/No). Step 7: Then select the system users, or the Team (having the stakeholder users), and save it. Results: Assume you are a user from X dept. who wants to access Entity 2 Record, and you need to see only the Proficiency Rating & Characteristic Name, but not Effective Date & Expiration Date; now since all fields have Field Level Security they would have a Key Icon on them, but the fields which do not have read/write access for you/your team, would have the Key Icon as well as a “—“. The same thing would happen in Views, subgrids, as well as if the user uses Advanced Find. Why this Solution was Required? The organization needed: 1] Cross-functional collaboration 2] Protection of confidential internal data 3] Clear separation of duties 4] No disruption to operational workflows They required a solution that: 1] Did not block entity access 2] Did not require custom development 3] Enforced true data-level protection Business Impact 1. Confidential Data Protection Sensitive internal data was secured without restricting overall entity access, enabling controlled collaboration. 2. Reduced Internal Data Exposure Risk Unauthorized users could no longer retrieve protected fields via Advanced Find, significantly lowering governance risk. 3. Clear Separation of Duties Departmental ownership of sensitive fields was enforced without disrupting cross-functional visibility. 4. Improved Audit Readiness Every modification to protected fields became traceable, strengthening accountability and compliance posture. 5. Reduced Operational Friction System-enforced field restrictions eliminated the need for entity blocking, duplicate records, and manual approval workarounds. 6. Efficiency Gains The solution was delivered through configuration — no custom code, no complex business rules, and minimal maintenance overhead. I Hope you found this blog useful, and if you would like to discuss anything, you can reach out to us at transform@cloudFronts.com.

Share Story :

Reducing Try-Catch in Dynamics 365 Plugins Using DTO Validation Classes

Dynamics 365 plugins run inside an event-driven execution pipeline where business rules and data validation must be enforced before database operations complete. As systems evolve, plugin code often degrades into heavy defensive programming filled with null checks, type casting, and nested exception handling. Over time, exception handling begins to overshadow the actual business logic. This article introduces a DTO + Validation Layer pattern that restructures plugin design into a clean, testable, and scalable architecture. What Is ā€œTry-Catch Hellā€ in Plugins? Typical Causes Symptoms Issue Impact Deep nested try-catch blocks Hard-to-read code Repeated attribute checks Code duplication Business logic hidden in error handling Difficult debugging Validation spread across plugins Inconsistent rules Result:Plugins behave like procedural error-handling scripts instead of structured business components. Architectural Shift: Entity-Centric → DTO-Centric Traditional plugins manipulate the CRM Entity directly. Problem:The Entity object is: This makes failures more likely. Proposed Flow This separates: DTO: A Strongly-Typed Contract DTOs act as a safe bridge between CRM data and business logic. Without DTO With DTO Dynamic attributes Strong typing Runtime failures Compile-time safety SDK-dependent logic Business-layer independenc Mapping Layer: Controlled Data Extraction All CRM attribute handling is isolated in one place. Benefits Validation Layer: Centralized Rule Logic Traditional DTO Validation Model Validation inside plugin Dedicated validator class Hard to reuse Reusable Hard to test Unit-test friendly The Clean Plugin Pattern Now the plugin: Reduction of Exception Noise Before: Exceptions for missing fields, null references, casting issues, and validation errors. After: Only meaningful business validation exceptions remain. The architecture shifts from reactive error handling to structured validation. Generative Design Advantages Capability Benefit New fields Update DTO + Mapper only New rules Extend validator Shared logic Reuse across plugins Automated testing No CRM dependency Testability Improvement No CRM context required. Performance Considerations To conclude, the DTO + Validation pattern is not just a coding improvement- it changes the way plugins are built. In many Dynamics 365 projects, plugins slowly become difficult to read because developers keep adding null checks, type conversions, and try-catch blocks. Over time, the actual business logic gets lost inside error handling. Using DTOs and a Validation layer fixes this problem in a structured way. Instead of working directly with the CRM Entity object everywhere, we first convert data into a clean, strongly typed DTO. This removes repeated attribute checks and reduces runtime errors. The code becomes clearer because we work with proper properties instead of dictionary-style field access. Then, all business rules are moved into a Validator class. This means: Now the plugin only performs four simple steps: Get data → Convert to DTO → Validate → Run business logic Because of this: Developers can understand the purpose of the plugin faster, instead of trying to follow complex nested try-catch blocks. If your Dynamics 365 environment is evolving in complexity, reach out to CloudFronts, transform@cloudfronts.com, specialists regularly design and implement structured plugin architectures that improve performance, maintainability, and long-term scalability.

Share Story :

Implementing Custom Auto Numbering in Dynamics 365 CRM

In Microsoft Dynamics 365 CRM, every Case (Incident) record comes with a default Ticket Number. Microsoft generates it automatically, and while that’s fine for basic tracking, it usually doesn’t survive first contact with real business requirements. Users want meaningful Case IDs—something that actually tells them what kind of case this is, what service it belongs to, and where it came from. Unfortunately, since Ticket Number (ticketnumber) is a Microsoft-managed field, you can’t just slap a custom format on it using configuration alone. That’s exactly where a Pre-Operation plugin comes in. This blog walks through a real production use case where we customize the default Case ID format without breaking Microsoft’s auto-numbering, and without creating race conditions or duplicate numbers. Use Case Table: Case (Incident) Field: Ticket Number (ticketnumber) Requirement: Execution: Why Pre-Operation Microsoft generates the Ticket Number before the Create operation completes. In Pre-Operation, we can: This gives us: The Custom Ticket Number Format The final Case ID looks like this: Example: Plugin Logic Overview Here’s what the plugin does, step by step: The Plugin Code Plugin Registration Details Message: Create Primary Entity: Case (incident) Stage: Pre-Operation Mode: Synchronous Filtering Attributes: Not required. To conclude, customizing a Microsoft-managed field like Ticket Number often sounds risky, but as you’ve seen, it doesn’t have to be. By letting Dynamics 365 generate the number first and then reshaping it in a pre-Operation plugin, you get the best of both worlds. We hope you found this blog useful, and if you would like to discuss anything, you can reach out to us at transform@cloudfronts.com

Share Story :

Opening an HTML Web Resource from a Subgrid Button in Dynamics 365 CRM

Posted On February 12, 2026 by Admin Posted in

An Australia-based linen manufacturing and distribution company was using Microsoft Dynamics 365 to manage their sales lifecycle. Their sales process included: The issue arose when sales representatives needed to add multiple existing products to an Opportunity. The Real Problem Out-of-the-box behavior in Dynamics 365 allows users to: While this works functionally, it becomes inefficient for organizations managing: This resulted in: The business requirement was clear: Users should be able to select multiple existing products and create Opportunity Product records in bulk, from a single interface. Architectural Decision Instead of: To address this, we introduced a custom button on the Opportunity Products subgrid. When clicked, it opens an HTML web resource that allows users to select multiple existing products in a single interface. The selected products are then processed through a Custom Action, which handles the bulk creation of Opportunity Product records server-side. Why Use an HTML Web Resource? In Microsoft Dataverse, not every customization belongs directly inside the main form. Sometimes we need: HTML Web Resources allow us to build: Without disturbing the standard CRM experience. The Web Resource We created an HTML web resource named: The HTML web resource renders a searchable grid of existing Product records, allowing users to perform multi-selection. The selected product IDs are then passed to a Custom Action, which handles the creation of related Opportunity Product records against the active Opportunity. Opening the HTML Web Resource from the Subgrid Button The key technical step was opening the HTML page when the custom ribbon button is clicked. We used modern navigation APIs. JavaScript Used on the Ribbon Button How This Works When the custom button is clicked, the script first retrieves the current Opportunity record ID. This ID is then passed as a parameter to the HTML web resource so that the selected products can be associated with the correct Opportunity. The web resource is opened as a modal dialog using the target: 2 navigation option, ensuring that users can complete the bulk selection process without leaving the form. Inside the HTML Web Resource Within the HTML web resource: This design ensures: All without navigating away from the form. How This Approach Saved Time Faster User Workflow Users select multiple products in one screen. Clean Architecture Concern Where It Lives Business Data Dataverse UI Interaction HTML Web Resource Batch Logic Custom Action (C# Plugin) To encapsulate, with this design the Client was able to: Opening an HTML Web Resource from a button in Microsoft Dynamics 365 is a powerful extension technique. It allows organizations to: We hope you found this blog useful, and if you would like to discuss anything, you can reach out to us at transform@cloudfronts.com

Share Story :

Implementing Plugin for Automated Lead Creation in Dynamics 365

Dynamics 365 CRM plugins are a powerful way to enforce business logic on the server but choosing when and how to use them is just as important as writing the code itself. In one implementation for a Netherlands-based sustainability certification organization, the client needed their certification journey to begin with a custom application entity while still ensuring that applicant and company details were captured as leads for downstream sales and engagement processes. This blog explores how a server-side plugin was used to bridge that gap, reliably creating and associating lead records at runtime while keeping the solution independent of UI behavior and future integrations. In this scenario, the certification application was the starting point of the business process, but sales and engagement still needed to operate on leads. Simply storing the same information in one place wasn’t enough, the system needed a reliable way to translate an application into a lead at the right moment, every time. That transformation logic is neither data storage nor UI behavior; its core business process logic, which is why it was implemented using a Dynamics 365 plugin. Scenario: Certification Application Not Flowing into Sales Users reported the following challenge: a. A user submits or creates a Certification Applicationb. Applicant and company details are captured on a custom entityc. Sales teams expect a Lead to be created for follow-upd. No Lead exists unless created manually or through inconsistent automatione. Application and sales data become disconnected This breaks the intended business flow, as certification teams and sales teams end up working in parallel systems without a reliable link between applications and leads. Possible Solution: Handling Lead Creation Through Manual Processes (Original Approach) Before implementing the plugin, the organization attempted to manage lead creation manually or through disconnected automation. How It Worked (Initially) a. A Certification Application was submittedb. Users reviewed the applicationc. Sales team manually created a Lead with applicant/company detailsd. They tried to match accounts/contacts manuallye. Both records remained loosely connected. Why This Might Look Reasonable a. Simple to explain operationallyb. No development effortc. Works as long as users follow the steps perfectly The Hidden Problems 1] Inconsistent Data Entry a. Users forgot to create leadsb. Leads were created with missing fieldsc. Duplicate accounts/contacts were createdd. Sales lost visibility into new certification inquiries 2] Broken Cross-Department Workflow a. Certification team worked in the custom entityb. Sales team worked in Leadsc. No structural linkage existed between the twod. Downstream reporting (pipeline, conversion, source tracking) became unreliable. Workaround to This Approach: Use Server-Side Logic Instead of Manual Steps Practically, the transformation of an application into a lead is business logic, not user behavior. Once that boundary is respected, the solution becomes stable, predictable, and automation-friendly. Practical Solution: A Server-Side Plugin (Improved Approach) Instead of depending on people or scattered automation, the lead is created centrally and automatically through a plugin registered on the Certification Application entity. Why a Plugin? a. Executes consistently regardless of data sourceb. Not tied to form events or UI interactionsc. Can safely check for existing accounts/contactsd. Ensures one source of truth for lead and application linkagee. Works for portal submissions, integrations, and bulk imports This is essential for a client, where applications may originate from multiple channels and must feed accurately into the sales funnel. How the Plugin-Based Solution Works The solution was implemented using a server-side plugin registered on the Certification Application entity. The plugin executes when a new application is created, retrieves the necessary applicant and organization details, performs basic checks for existing accounts and contacts, creates a Lead using the extracted data, and finally links the Lead back to the originating application record. This ensures that every certification application automatically enters the sales pipeline in a consistent and reliable manner. Implementation Steps (For Developers New to Plugins) If you’re new to Dynamics 365 plugins, the implementation followed these core steps: Build and Register the Plugin. Once the plugin logic is implemented, build the project to generate the signed assembly. After a successful build: After registration, every new Certification Application will automatically trigger the plugin, ensuring that a Lead is created and linked without any manual intervention. a. Open the Plugin Registration Toolb. Connect to the target Dynamics 365 environmentc. Register the compiled assemblyd. Register the plugin step on the Create message of the Certification Application entitye. Configure the execution stage (typically post-operation) and execution mode (Synchronous or Asynchronous, depending on business needs) To encapsulate, this solution shows why server-side plugins are the right place for core business logic in Dynamics 365. By automatically creating and linking a Lead when a Certification Application is created, the organization removed manual steps, prevented data inconsistencies, and ensured that every application reliably flowed into the sales pipeline. We hope you found this blog useful, and if you would like to discuss anything, you can reach out to us at transform@cloudfronts.com

Share Story :

Plugin Class Code Recovery using XRMToolBox & C# DotPeek.

In an ideal Dynamics 365 (Dataverse) project, plugin source code lives safely in a version-controlled repository, flows cleanly through Azure DevOps pipelines, and is always recoverable. In reality, many of us inherit environments where that discipline didn’t exist. I recently worked with a customer where: This created a common but uncomfortable challenge in the Dynamics 365 world:How do you maintain, debug, or enhance plugins when the source code is lost? Rewriting everything from scratch was risky and time-consuming. Guessing behavior based on runtime results wasn’t reliable. Fortunately, Dynamics 365 and the .NET ecosystem give us a practical and effective alternative. Using XrmToolBox and JetBrains dotPeek, it is possible to recover readable C# plugin code directly from the deployed assembly. (Though the C# Class code recovered won’t be 100% exact, as the variable names would be different and generic; it is only suitable for close logic, structure & functional recovery) The Practical Solution The approach consists of two main steps: This does not magically restore comments or original formatting, but it does give a working, understandable code that closely reflects the original plugin logic. Tools Used Step 1: Extract the Plugin Assembly from Dataverse 1. Connect to the Environment 2. Load the Assembly Recovery Tool 3. Download the DLL At this point, you have successfully recovered the compiled plugin assembly exactly as it exists in the environment. Step 2: Decompile the DLL Using JetBrains dotPeek 1. Open dotPeek 2. Explore the Decompiled Code dotPeek will: One can now browse through: This is usually more than enough to understand how the plugin works. 3. Export to a Visual Studio Project (Optional but Recommended) One of dotPeek’s most powerful features is Export to Project: This gives you a proper .csproj with class files that you can open, build, and extend. Possibilities with the Recovered Code Once you have the decompiled C# code, several options open up: 1. Rebuild the Plugin Assembly 2. Re-register the Plugin 3. Maintain or Enhance Functionality Important Considerations Key Takeaway Losing plugin source code does not mean losing control of your Dynamics 365 solution. With XrmToolBox’s Assembly Recovery Tool and JetBrains dotPeek, you can: There are chances while working in Dynamics 365 technologies, that a developer might face this situation. Knowing this technique can save days-or weeks-of effort and give your customer confidence that their system remains fully supportable. We hope you found this blog useful, and if you would like to discuss anything, you can reach out to us at transform@cloudfronts.com

Share Story :

Browser-Level State Retention in Dynamics 365 CRM: Improving Performance & UX with Session Storage

Dynamics 365 model-driven apps are excellent at storing business data, but not every piece of information belongs in Dataverse. A common design folly is using Dataverse fields to store temporary UI state-things like selected views, filters, or user navigation preferences. While this works technically, it introduces unnecessary performance overhead and can create incorrect behavior in multi-user environments. In this blog, I’ll focus on browser-level retention of CRM UI data using “sessionStorage“, using subgrid view retention as a practical example for a technology consulting and cybersecurity services firm based in Houston, Texas, USA, specializing in modern digital transformation and enterprise security solutions. The Real Problem: UI State vs Business Data Let’s separate concerns clearly: Type Example Where it should live Business data Status, owner, amounts Dataverse UI state Selected view, filter, scroll position Browser Subgrid views fall squarely into the UI state category. Scenario: Subgrid View Resetting on Navigation Users reported the following behavior: This breaks user workflow, especially for records that users revisit frequently. Possible Solution: Persisting UI State in Dataverse (Original Approach) This would attempt to fix it by storing the selected subgrid view GUID in a Dataverse field on the parent record. How It Works Why this might look reasonable The Hidden Problems 1] Slower Form Execution 2] Data Model Pollution 3] Incorrect Multi-User Behavior 4] Scalability Issues In short, Dataverse was doing work it should never have been asked to do. Workaround to this Approach: Keep UI State in the Browser for that session, But practically: The selected subgrid view belongs to the user’s session, not the record. Once that boundary is respected, the solution becomes much cleaner. Practical Solution: Browser Session Storage (Improved Approach) Instead of persisting view selection in Dataverse, we store it locally in the browser using sessionStorage. sessionStorage is part of the Web Storage API, which provides a way to store key-value pairs in a web browser. Unlike localStorage, which persists data even after the browser is closed, sessionStorage is designed to store data only for the duration of a single session. This means that the data is available as long as the tab or window is open, and it is cleared when the tab or window is closed. Why Session Storage? How the Improved Solution Works 1. Store the View Locally on Subgrid Change 2. Restore the View on Form/Grid Load This ensures that when the user revisits the form, the subgrid opens exactly where they left off. Why This Approach Is Superior 1] Faster Execution 2] Correct User Experience 3] Clean Architecture 4] Zero Backend Impact When to Use Browser-Level Retention Use this pattern when: Examples: To conclude, not all data deserves to live in Dataverse. When you store UI state in the browser instead of the database, you gain: Subgrid view retention is just one example-but the principle applies broadly across Dynamics 365 customizations. We hope you found this blog useful, and if you would like to discuss anything, you can reach out to us at transform@cloudfronts.com

Share Story :

Seamlessly Switching Lead-Based BPFs After Qualification in Dynamics 365 CRM

In Microsoft Dynamics 365 CRM, Business Process Flows (BPFs) are powerful tools that guide users through defined business stages. However, when working with Lead-based BPFs that persist into Opportunity, certain platform limitations surface-especially when multiple Lead-rooted BPFs are involved. This blog walks through a real-world challenge I encountered while working with a Houston-based technology consulting and cybersecurity services firm. The firm specializes in modern digital transformation and enterprise security solutions. I explore issues with Lead → Opportunity Business Process Flow (BPF) switching, explain why the out-of-the-box behavior falls short, and detail how I designed a robust client-side and server-side solution to safely and reliably switch BPFs-even after a Lead has already been qualified. How BPFs Work (Quick Recap) It ideally won’t allow a switch, either via brute forcing via client side or server side as – The Problem In my scenario: The Challenge Once a Lead is qualified: This is non-intuitive, error-prone, and inefficient, especially considering the manual effort that goes into it. Solution Overview I implemented a guided, safe, and reversible BPF switching mechanism that: High-Level Architecture This solution uses: Step-by-Step Methodology 1. Entry Point: Opportunity Ribbon Button A custom ribbon button on the Opportunity form: These fields act as a controlled handshake between Opportunity and Lead. 2. Lead OnLoad: Controlled Trigger Execution On Lead form load: if (diffSeconds > 20) { return;} Xrm.WebApi.updateRecord(“lead”, formContext.data.entity.getId(), { cf_shouldtrigger: false}); This ensures: 3. Identifying and Aborting the Existing BPF Before switching: var activeProcess = formContext.data.process.getActiveProcess(); Xrm.WebApi.updateRecord(bpfEntityName,result.entities[0].businessprocessflowinstanceid,{statecode: 1, // Inactivestatuscode: 3 // Aborted}); This is a critical step—without aborting the old instance, Dynamics can behave unpredictably. 4. Switching the UI BPF After aborting: 5. Handling BPF Instance Creation (First-Time Switch Logic) The solution explicitly checks: If it exists: If it does NOT exist (first switch): This dual-path logic makes the solution idempotent and reusable. 6. Server-Side Plugin: Persisting the Truth A plugin ensures that: // Identify BPF typebool isNewBpf = (context.PrimaryEntityName == “new_bpf_entity”); // Resolve related LeadGuid leadId = isNewBpf? ((EntityReference)target[“bpf_leadid”]).Id: ((EntityReference)target[“leadid”]).Id; // Retrieve related Opportunity via LeadEntity opportunity = GetOpportunityByLead(service, leadId); // Determine stages and pathstring qualifyStageId = isNewBpf ? NEW_QUALIFY_STAGE : OLD_QUALIFY_STAGE;string finalStageId = isNewBpf ? NEW_FINAL_STAGE : OLD_FINAL_STAGE;string traversedPath =START_STAGE + “,” + qualifyStageId + “,” + finalStageId; // PATCH 1 – Qualify stageservice.Update(new Entity(target.LogicalName, target.Id){[“activestageid”] = new EntityReference(“processstage”, new Guid(qualifyStageId)),[“traversedpath”] = START_STAGE + “,” + qualifyStageId}); // PATCH 2 – Final stage + Opportunity bindservice.Update(new Entity(target.LogicalName, target.Id){[“activestageid”] = new EntityReference(“processstage”, new Guid(finalStageId)),[“traversedpath”] = traversedPath,[isNewBpf ? “bpf_opportunityid” : “opportunityid”] =new EntityReference(“opportunity”, opportunity.Id)}); // Mark Lead as successfully processedservice.Update(new Entity(“lead”, leadId){[“cf_pluginsuccess”] = new OptionSetValue(1) // Yes}); This guarantees data consistency and auditability. 7. Final UI Sync & Redirect After successful completion:   Xrm.Navigation.openForm({ entityName: “opportunity”, entityId: opportunityId }); From the user’s perspective: ā€œI clicked a button, confirmed the switch, and landed back in my Opportunity—done.ā€ Why This Solution Works āœ” Respects Dynamics 365 BPF constraintsāœ” Prevents orphaned or conflicting BPF instancesāœ” Handles first-time and repeat switchesāœ” Ensures server-side persistenceāœ” Minimal user disruptionāœ” Fully reversible Most importantly, it bridges the gap between platform limitations and real business needs. Dynamics 365 BPFs are powerful-but when multiple Lead-rooted processes coexist, manual switching is not enough. This solution demonstrates how: can be combined to deliver a seamless, enterprise-grade experience without unsupported hacks. If you’re facing similar challenges with Lead → Opportunity BPF transitions, this pattern can be adapted and reused with confidence. We hope you found this blog useful, and if you would like to discuss anything, you can reach out to us at transform@cloudfronts.com

Share Story :

SEARCH BLOGS:

FOLLOW CLOUDFRONTS BLOG :


Secured By miniOrange