Category Archives: Dynamics 365
Assign your D365 records but keep access as well
Introduction: At times, you are asked to assign certain CRM records to other users and you just have to do it as a part of the process. But let’s face it, you still wonder what might have happened to the record after you assigned it to them but your security roles won’t let you access those. There’s a general D365 setting for this too! You can share your D365 records with other but still retain rights to yourself so keep track of what happened with those later on System Settings: Navigate to Settings > Administration > System Settings In General tab, look for the Setting where it reads as ‘Set whether reassigned records are shared with the original owner’ (quite self-explanatory) Assign Record and check Share Rights: Now, assigning a records from Priyesh to John as shown below – Priyesh would still have rights to the record. Check the Share status of the same. The record will be owner by John but will be shared with Priyesh too. Hope this is helpful!
Share Story :
Delegated Resource error for making time entries in D365 PSA 2.x version
Have you been added as a Delegate for a fellow colleague but not able to Read, Create or Submit Time Entries on their behalf? Let us see what you are missing. Scenario: William Contoso wants to make Veronica Quek as his Delegate and let her enter time on his behalf. Let’s say William added Resource Veronica Quek as the Delegate above. Error for the Delegate Resource: Now, Veronica is attempting to do time entries for William by going to Time Entry Calendar view and switching the user to William. And when Veronica wants to enter time as William, she’d switch to the User on the Time Entries Calendar View like this – But, see this error and she don’t know what the issue might be. Even though she’s the Delegate! Missing Security Role: Yes, this is the first thing you should check. Veronica Quek is missing a Delegate Security Role in PSA to be able to make time entries on behalf of other users. Assign Delegate security role to the user to make them enter time on behalf of others. And thus, your Delegated User should be good to make time entries.
Share Story :
Create Item Requirement from Item Forecast using X++ in D365 Operations
Introduction: In this blog article, we will see how we can create Item Requirement on insertion of Item Forecast using code. Steps: Create Extension Class for ForecastSales Table that is Item Forecast and using CoC for post insert() method we will initialize Item Requirement. We will call a new class which is created in Step 2. public void insert() { next insert(); SalesType salesType = SalesType::ItemReq; CFSCreateItemReqFrmItemForecast createItemReq = new CFSCreateItemReqFrmItemForecast(); createItemReq.initParameters(this); createItemReq.copyToSalesLine(SalesType); } Create a new class that will initialize values and insert record in Item Requirement form. class CFSCreateItemReqFrmItemForecast { ForecastSales forecastSales; } In the new class create a method initParameter. This method will initialize ForecastSales object. void initParameters(ForecastSales _forecastSales) { forecastSales = _forecastSales; } Create another method ‘copytoSalesLine’. It will validate the record and call other methods to copy values to SalesLine Table. public void copyToSalesLine(SalesType _salesType) { ProjTable projTable = ProjTable::find(forecastSales.ProjId); if (_salesType == SalesType::ItemReq) { if (!ProjStatusType::construct(projTable).validateWriteItemRequirement()) { throw error(“@SYS18447”); } } else { if (!ProjStatusType::construct(projTable).validateWriteSalesLine()) { throw error(“@SYS18447”); } } SalesLine salesLine = this.initializeSalesLine(_salesType, forecastSales, projTable); salesLine.createLine(false, // Validation false, // Init from SalesTable true, // Init from InventTable true, // Calc invent Qty false, // Search markup – copied from salesQuotationline false, // Search price – copied from salesQuotationline false, // Check reservation true); // Skip creditlimit check this.updateSalesLine(salesLine, forecastSales); salesLine.update(); } Create a new method ‘initializeSalesLine’. It is called from copyToSalesLine(). protected SalesLine initializeSalesLine(SalesType _salesType, ForecastSales _forecastSales, ProjTable _projTable) { SalesLine salesLine; salesLine.SalesType = _salesType; salesLine.initValue(); salesLine.setInventDimId(_forecastSales.InventDimId); salesLine.ItemId = _forecastSales.ItemId; salesLine.SalesQty = _forecastSales.SalesQty; salesLine.SalesUnit = _forecastSales.SalesUnitId; salesLine.ProjId = _forecastSales.ProjId; salesLine.ActivityNumber = _forecastSales.ActivityNumber; salesLine.CurrencyCode = _forecastSales.Currency; salesLine.initFromProjTable(_projTable, false); return salesLine; } Create a new method updateSalesLine(). It is called from copyToSalesLine() method. protected void updateSalesLine(SalesLine _salesLine, ForecastSales _forecastSales) { _salesLine.DefaultDimension = _salesLine.copyDimension(_forecastSales.DefaultDimension); _salesLine.ProjLinePropertyId = _forecastSales.ProjLinePropertyId; _salesLine.TaxGroup = _forecastSales.TaxGroupId; _salesLine.TaxItemGroup = _forecastSales.TaxItemGroupId; _salesLine.ProjCategoryId = _forecastSales.ProjCategoryId; _salesLine.CostPrice = _forecastSales.CostPrice; _salesLine.SalesPrice = _forecastSales.SalesPrice; _salesLine.LinePercent = _forecastSales.DiscPercent; _salesLine.LineDisc = _forecastSales.DiscAmount; _salesLine.LineAmount = 0; _salesLine.LineAmount = _salesLine.calcLineAmount(); SalesLineType_ItemReq::setSalesLineReceiptDate(_salesLine); }
Share Story :
Post Ledger Journal using X++ in D365 Operations
Introduction: In this blog article, we will see how we can post the journal by using code. How to do? Create a new method and write below code. In this code you declare object of Class ‘LedgerJournalCheckPost’. This class will use journal buffer and post it. public void postJournal(LedgerJournalTable ledgerJournalTable) { LedgerJournalCheckPost jourPost; jourPost = LedgerJournalCheckPost::newLedgerJournalTable(ledgerJournalTable, NoYes::Yes); jourPost.runOperation(); }
Share Story :
Send Custom Emails using SendGrids API
Introduction: In this blog we will demonstrate how to send custom emails using SendGrids API. Scenario: If we want to send custom emails to customers stored in Dynamics 365 with different email body for every customer based on their data stored in CRM, it is not possible to do so by using the normal Email Editor as it has some limitations while displaying dynamic content. One way of doing this is by creating a console app which will use SendGrids API to send out custom emails for every customer. Pre-Requisites: Visual Studio SendGrid Account Implementation: Step 1: For this demonstration we will see how to send out a mail to a single email. First we create a Console App in Visual Studio Step 2: Once the Project is created Right Click on the Project and select Manage Nuget Packages Browse to the latest Nuget packages and install SendGrid package Step 3: Next we have to create an API Key in SendGrid. Just give a name for a key and Click on Create Key which will generate a unique key. Store this key which will be used in the Code Step 4: Below is the Code to send email: using SendGrid; using SendGrid.Helpers.Mail; using System.Threading.Tasks; namespace SendGridConsoleApp { class Program { static void Main(string[] args) { string sendGridAPIKey = “EnterKeyHere”; Execute(sendGridAPIKey).Wait(); } static async Task Execute(string _apiKey) { var client = new SendGridClient(_apiKey); var from = new EmailAddress(“test@gmail.com”, “From UserName”); var subject = “MAIL Send Through SendGrid”; var to = new EmailAddress(“test@gmail.com”, “To UserName”); var plainTextContent = “Example PlainText”; var htmlContent = @”<!DOCTYPE html><html><head><style> table { border-collapse: collapse; width: 100%; } th, td { text-align: left; padding: 8px; } tr:nth-child(even){background-color: #f2f2f2 } th { background-color: #4CAF50; color: white; } </style></head><body><h2>Important Details</h2> <table><tr> <th>Firstname</th> <th>Lastname</th> <th>Email Address</th></tr> <tr><td>Peter</td><td>Griffin</td><td>pgriffin@gmail.com</td></tr> <tr><td>Lois</td><td>Griffin</td><td>Lois@gmail.com</td></tr><tr> <td>Joe</td><td>Swanson</td><td>joe@gmail.com</td> </tr><tr><td>Cleveland</td><td>Brown</td> <td>clev@gmail.com</td></tr></table></body></html>”; var msg = MailHelper.CreateSingleEmail(from, to, subject, plainTextContent, htmlContent); var response = await client.SendEmailAsync(msg); }}} Step 5: Once the Console App is run the email is send below shown is the sample of the Email sent While running this for multiple customers we can create different HTML body content for each customer and pass it to the CreateSingleEmail function.This approach can also be used to send bulk emails to customers.
Share Story :
Keep access to Assigned records in D365
Introduction: At times, you are asked to assign certain CRM records to other users and you just have to do it as a part of the process. But let’s face it, you still wonder what might have happened to the record after you assigned it to them but your security roles won’t let you access those. There’s a general D365 setting for this too! You can share your D365 records with other but still retain rights to yourself so keep track of what happened with those later on Setting: Navigate to Settings > Administration > System Settings In General tab, look for the Setting where it reads as ‘Set whether reassigned records are shared with the original owner’ (quite self-explanatory) Assign Record and check Share Rights: Now, assigning a records from Priyesh to John as shown below – Priyesh would still have rights to the record. Check the Share status of the same. The record will be owner by John but will be shared with Priyesh too.
Share Story :
Using MS Flow and D365 App For Outlook To Track Proposals and Win Opportunities Without Leaving Outlook
For every sales person, getting a signed contract from the client is a euphoric moment. You finally closed the deal, and everything seems right. But the process after winning the deal is cumbersome for many of us. This article documents how we made this process a lot less painful through MS Flow and the D365 App for Outlook. Hopefully you find it very useful as well. I will first walk you through my old process – Once I got the signed contract as a Word or PDF attachment in my email, I would download it and save it to my OneDrive under the respective client folder. I would then open D365, go to the opportunity, then browse to the Documents folder and create a new SharePoint document folder. Then I would click the upload button and browse to the document location the OneDrive folder on my computer and attach the proposal. I would then finally mark the opportunity as Won, which would send out internal emails to our Delivery Team (for Project creation), Accounts Team (for billing details) and our HR team (so they can keep an eye on recruitment needs). Here is what we achieved through the implementation of the new process using MS Flow and D365 App for Outlook – Once I got the signed contract in my email, I would track this email using the D365 App in Outlook. I would also set the regarding field as the Opportunity that this proposal is for. The above action would trigger an MS Flow that would do the following in near real time – It would check if the Opportunity already had a folder created and if not, it would first create the SharePoint document folder on the Opportunity. It would then upload the proposal to the above folder. It would remove the attachment from the tracked email (saving valuable space!) I would then open the Opportunity right from my D365 App for Outlook and mark it as Won. The step by step directions for setting up the MS Flow are documented in this blog article from Krishna Bhanushali from our D365 team – https://www.cloudfronts.in/move-attachments-from-tracked-email-to-sharepoint-using-microsoft-flow/. In conclusion, the above implementation has benefited us through – Significantly reduced number of steps post winning a deal. Time saved by not having to leave Outlook which is where most of us are spending our time. A better process that makes pipeline management easier for sales people, thus driving adoption. If you want to discuss your sales processes further or provide any feedback for improvement, I can be reached at ashah@cloudfronts.com.
Share Story :
How to set a default chart in a view’s Chart Pane
Introduction: This blog explains how to set a default chart in a view’s Chart Pane Scenario: We have created custom chart on order named as Order by printing status. We want this chart should get open when user click on charts pane Steps: Go to Customization –> Order –> Charts. Click on More Actions –> Export Chart. .xml file will get download. Open that file with notepad. Search isdefault and set its value to true. Save Click on More Actions –> Import Chart Import the customized chart. Replace and Import Chart. Publish Customization. Now you can see that chart as default chart.
Share Story :
Error handing in MS Flows
Introduction: In this blog we will be going through the steps of Error Handling in Microsoft Flows. Implementation: Step 1: We have created a basic flow that is triggered when a HTTP POST Request has be made to the generated URL. The body will contain a JSON array with some data The flow will then take the data passed in the POST request body and for each object in the JSON array, it create a record in Dynamics 365 Customer Engagement as shown below. In the above scenario we pass the correct data, but in case the data that is passed to the URL is not correctly formatted or the data is missing we will encounter an error and the flow will fail. To handle such situations we will define an action that will take place when an error is encountered. Step 2: To Log the error, we will create another action to create a log error log in Dynamics 365 Customer Engagement. To make sure that this is created only when an error is encountered we click on the Configure Run After option as shown There are four options shown, here we select only the “has failed” option which states that the log will be created when there is a failure. Once this is done we can see the the flow shows a dotted red line for the last step, this is because the “Log Error in CRM” action will run only in one scenario i.e. when the above action has failed. The benefits of using this approach in our flows is that we can log all the errors at one place and also store the error response of the previous stage by simply selecting the Dynamic Content in the “Log Error in CRM” action.
Share Story :
Update field value based on the current stage of Business Process Flow and trigger workflow when Business Process Flow is finished.
Introduction: This blog explains How to Update field value based on the current stage of Business Process Flow. How to Trigger workflow when Business Process Flow is finished. PART A: Scenario: We have a custom Business Process Flow with 4 stages on Order entity. Whenever user changes the stage of Business Process Flow status field is updated. (we have created custom status field named as printing status). Steps to be followed: 1. Create Real time Workflow on Business Process Flow Entity. 2. Trigger workflow on Process Changes: 3. Add Step –> Update Record. Update the field value with active BPF stage. 4. Create another real time workflow on Order entity. 5. Trigger on Record Field Change and select the field where you are updating the stage value. 6. Add Step –> Check Condition and Update the field value. (check the stage field value and update the status accordingly ) For example first stage in BPF is waiting for jersey then we will check if Current stage is equal to waiting for jersey then update the printing status to waiting for jersey. Complete Workflow: PART B: How to Trigger workflow when Business Process Flow is finished. Scenario: Update the Order Status to fulfilled when Business Process Flow is finished. Steps to be followed: 1. Create a Real time and on demand workflow on Order entity. 2. Add Step -> Change Status to complete 3. Activate the workflow. 4. Go to Business Process flow which you are using and perform the below steps: a. Drag and Drop the workflow in Global Workflow. b. Trigger the workflow on when process is completed and select the workflow which you have created. (you will only see on demand workflows)
