{"id":4752,"date":"2025-11-30T14:13:58","date_gmt":"2025-11-30T14:13:58","guid":{"rendered":"https:\/\/himbap.com\/blog\/?p=4752"},"modified":"2025-11-30T14:13:58","modified_gmt":"2025-11-30T14:13:58","slug":"closing-an-opportunity-automatically-from-bpf","status":"publish","type":"post","link":"https:\/\/himbap.com\/blog\/?p=4752","title":{"rendered":"Closing an Opportunity Automatically from BPF"},"content":{"rendered":"\n<p><strong>Requirement<\/strong><\/p>\n\n\n\n<p>Recently, We worked on an interesting requirement in <strong>Dynamics 365 CE Sales app<\/strong> where the customer wanted to <strong>close an Opportunity as WON directly when the user clicks the final stage in the Business Process Flow (BPF)<\/strong>.<\/p>\n\n\n\n<p>However, the requirement was not as simple as just closing the Opportunity.<br>There were a few important <strong>business validations<\/strong> that we had to enforce before allowing the Opportunity to close.<\/p>\n\n\n\n<p>In this blog, I\u2019ll walk you through the requirement, the challenges, and the full solution I implemented.<\/p>\n\n\n\n<p><strong>Details<\/strong><\/p>\n\n\n\n<p>When the user reaches the <strong>final stage<\/strong> of the Opportunity BPF and clicks <strong>Finish<\/strong>, the system should:<\/p>\n\n\n\n<ol>\n<li><strong>Check several combination of conditions<\/strong> before closing the Opportunity:\n<ul>\n<li>No <strong>Draft Quotes<\/strong> should exist.<\/li>\n\n\n\n<li>No <strong>Active Quotes<\/strong> should exist.<\/li>\n\n\n\n<li>At least one <strong>Quote must be Won<\/strong>.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>If any validation fails \u2192 <strong>show an error message<\/strong> and do NOT close the Opportunity.<\/li>\n\n\n\n<li>If all validations pass \u2192 <strong>automatically close the Opportunity as WON<\/strong>.<\/li>\n\n\n\n<li>After the Opportunity is closed \u2192 show a friendly message on the form:<br><strong>\u201cCongratulations! Your opportunity is won.\u201d<\/strong><\/li>\n<\/ol>\n\n\n\n<p>To meet this end-to-end behavior, we implemented <strong>two components<\/strong>:<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Part 1 \u2013 Plugin on BPF Stage Change<\/strong><\/h2>\n\n\n\n<p>The first part was handled through a plugin because it needed <strong>server-side validation<\/strong> and <strong>automatic Opportunity closing<\/strong>, which cannot be trusted to the client side.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Trigger Point<\/strong><\/h3>\n\n\n\n<ul>\n<li>Message: <code>Update<\/code><\/li>\n\n\n\n<li>Primary Entity: <code>Opportunity Sales Process (BPF entity)<\/code><\/li>\n<\/ul>\n\n\n\n<p>In the plugin, we added multiple validation checks. If any check failed, the plugin threw an execution exception. When all conditions were met, the plugin automatically closed the opportunity as WON.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Part 2 \u2013 JavaScript<\/strong><\/h2>\n\n\n\n<p>Once the plugin automatically closes the Opportunity, we wanted to show a <strong>\u201cCongratulations\u201d<\/strong> message to the user on the form.<\/p>\n\n\n\n<p>However, showing a message after the Opportunity is closed is a bit tricky because:<\/p>\n\n\n\n<ul>\n<li>The BPF updates before the form refreshes.<\/li>\n\n\n\n<li>We need to ensure the Opportunity is <strong>already closed as WON<\/strong>.<\/li>\n\n\n\n<li>The stage change event fires earlier than the record update.<\/li>\n<\/ul>\n\n\n\n<p>To solve this, we implemented a simple <strong>form script<\/strong>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>JavaScript Logic<\/strong><\/h3>\n\n\n\n<ol>\n<li>Bind the script to the <strong>BPF Stage Change<\/strong> event.<\/li>\n\n\n\n<li>Used <strong>timer<\/strong>, because the stage change event occurs before the Opportunity status updates.<\/li>\n\n\n\n<li>After a short delay, check the Opportunity:\n<ul>\n<li>If <strong>status is \u201cWon\u201d<\/strong><\/li>\n\n\n\n<li>And the BPF was just finished<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Then show a message<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Summary<\/strong><\/h2>\n\n\n\n<p>This is how we handled this requirement and used two solutions which involved combining <strong>Plugin<\/strong> and <strong>JavaScript<\/strong>. <\/p>\n\n\n\n<p>Hope it will help someone!!<br><strong>Keep learning and Keep Sharing!!<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Requirement Recently, We worked on an interesting requirement in Dynamics 365 CE Sales app where the customer wanted to close an Opportunity as WON directly when the user clicks the final stage in the Business Process Flow (BPF). However, the requirement was not as simple as just closing the Opportunity.There were a few important business validations that we had to&#8230; <a href=\"https:\/\/himbap.com\/blog\/?p=4752\">Read more &raquo;<\/a><\/p>\n","protected":false},"author":1,"featured_media":4754,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[21,402,522,25],"tags":[1148,1146,1149,421,1147],"_links":{"self":[{"href":"https:\/\/himbap.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4752"}],"collection":[{"href":"https:\/\/himbap.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/himbap.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/himbap.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/himbap.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4752"}],"version-history":[{"count":2,"href":"https:\/\/himbap.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4752\/revisions"}],"predecessor-version":[{"id":4755,"href":"https:\/\/himbap.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4752\/revisions\/4755"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/himbap.com\/blog\/index.php?rest_route=\/wp\/v2\/media\/4754"}],"wp:attachment":[{"href":"https:\/\/himbap.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4752"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/himbap.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4752"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/himbap.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4752"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}