https://knowledgefrommanish.com/powerapps/power-apps-mobile-app-mobile-offline-capability-for-model-driven-apps/
Create A Portal Inbox & Messaging Process (Dynamics 365 Power Platform Portal)
https://meganvwalker.com/create-a-portal-inbox-messaging-process/
Developer citizen
Citizen Dev. Journey - Setting up your Microsoft Power Apps Test Environment
https://www.linkedin.com/pulse/citizen-dev-journey-setting-up-your-microsoft-power-joe-camp/
Install SQL Server Integration Services in Visual Studio 2019
https://www.mssqltips.com/sqlservertip/6481/install-sql-server-integration-services-in-visual-studio-2019/
Repeater section content control in Word Template
Using Power Automate word templates with Model-Driven apps
https://www.itaintboring.com/dynamics-crm/using-power-automate-word-templates-with-model-driven-apps/
Workflow activity Samples
https://rajeevpentyala.com/2019/03/23/code-snippet-custom-workflow-activity-with-input-and-output-params/
https://docs.microsoft.com/en-us/power-apps/developer/data-platform/workflow/tutorial-create-workflow-extension
https://github.com/microsoft/PowerApps-Samples/blob/master/cds/orgsvc/C%23/WorkflowActivities/WorkflowActivities/RetrieveCreditScore.cs
Use two-option type of field in Business Process Flow to force user choose specified value to advance to next stage
Requirement:
Force users to choose the specified value of a field in certain stage of Business Process Flow to be able to advance to next stage.
Solution:
1. Set the filed type to "Two Options", and don't set the value which you hope users to choose as the default value.
2. Click the “required” box of the filed on the process flow step, rather than set the requirement on the field definition in customization.
[ISSUE] Dynamics 365 - Advanced Find: One column doesn't show value, but shows in exported excel report
Issue:
Dynamics 365 - Advanced Find: One column doesn't show value, but shows in exported excel report.
For example, below is an Invoice list, the red circled column below "Acutual Revenue(Base) (Opportunity)" is supposed to show values instead of vacant.
In exported excel report, this column shows values normally.
Reason:
Unfortunately, I have no idea.
Solution:
After adding one more column "Acutual Revenue (Opportunity)", the column "Acutual Revenue(Base) (Opportunity)" shows normally.
Free!!! Microsoft Dynamics 365 Fundamentals (CRM) certification
|
Dynamics 365 CRM Show/Retrieve Data of Grandparent Record
Requirement:
We have a construct like entity1 - 1:n - entity2 - 1:n - entity3, and want to display data from entity1 in entity3 (form or list).
Example:
Opportunity 1:n Account
Account 1:n Contact (Primarry Contact)
Opportunity no relationship with Contact (Primary Contact)
So using Dynamics 365 CRM Advanced Find cannot retrieve fields of Contact to Opportunity list.
Solution:
XrmtoolBox + FetchXML
1. XML: Download
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
<entity name="opportunity">
<attribute name="name" />
<attribute name="parentaccountid" />
<filter type="or">
<condition attribute="statecode" operator="eq" value="1" />
<condition attribute="statecode" operator="eq" value="2" />
</filter>
<filter type="and">
<filter>
<condition attribute="actualclosedate" operator="last-x-months" value="8" />
</filter>
</filter>
<order attribute="name" descending="false" />
<link-entity name="account" from="accountid" to="customerid">
<attribute name="primarycontactid" />
<link-entity name="contact" from="contactid" to="primarycontactid">
<attribute name="emailaddress1" />
</link-entity>
</link-entity>
</entity>
</fetch>
Result:
2. XrmToolBox:
- FetchXML Builder: Create XML
- Export To Excel: Export retrieve report to excel spreadsheet, work with FetchXML Builder
Switch Form Type Conditionally Using JavaScript(JS) in Dynamics 365
In Dynamics 365, sometimes it could be a little overwhelming for some users to switch to the correct form when there are many types of forms for a specific entity(table).
For example, if the form type could be switched automatically when CUSTOMER filed value is changed, below JS could be your reference.
Applied Version:
- Microsoft Dynamics 365 (on-premises) v9.0 or later
- Microsoft Dynamics 365 Online
Trigger scenerio:
1. Form - Load
2. Filed: CUSTOMER - Changed
Sample Code:
Date/Time Columns(Fields) Error when Import Data File into Dynamics 365 from EXCEL(CSV)
When I tried to import an Invoice data into Dynamics 365, I got a failure " The date/time format is not valid, or the value is outside the supported range."
So I compared the date/time column of the import spreadsheet with the date/time type field on Dynamics 365 and found they are in different format.
One is "DD/MM/YY" in Canadian format, and the other is "MM/DD/YY" in US format.
So I changed the date format of the import spreadsheet from US format to Canada format to be consistent with Dynamics 365 system.
Try to import again, succeeded finally.
Duplicate Lookup Reference Failure When Import Data File in Dynamics 365
Sometimes, when we tried to import excel data into Dynamics 365, we may get errors like "A duplicate lookup reference was found.".
For example, I tried to import the invoice list into Dynamics 365 CRM but got two duplicate errors for the Order and Opportunity fields(columns).
Customize Lookup Field Search Columns in Dynamics 365
For lookup fields in Dynamics 365 forms, sometimes we hope to search the record by some other columns other than its name column, so we may need to customize Quick Find View.
Customize Lookup Field View in Dynamics 365
1. Change the Lookup fied view.
Below is the view of lookup field - Order.
We can see there are two columns showing: Order name and customer.
If we wanna change the columns it shows, we can customize Order entity's lookup View.
This kind of view always named by " Entity Name + Lookup View".
Then, Add columns we are required to show.
Customize the queries for subgrids of Dynamics 365 form
Subgrids are great but the limitation of needing a direct relationship between the sub entity and the main entity makes it very restrictive. There are many different use cases, if instead of using a pre-configured view that only allows linking to the active Record via a predefined relationship, we could instead bind a custom FetchXML do a subgrid and this custom FetchXML would allow for one token called #RecordID# to reference the currently open record on the form by returning the GUID.
In Classic UI people used the subgrid.control.SetParameter("fetchxml") function but this is now broken in Unified Interface. In Unified Interface it appears a Retrieve Multiple Plugin is the only way to achieve this which is extremely complicated for something as simple as binding a query to a subgrid.
Here is the only way to currently do this:
Reference:
- https://powerusers.microsoft.com/t5/Power-Apps-Ideas/Binding-FetchXML-to-Subgrid-with-reference-to-RecordID-to-filter/idi-p/675538
- https://cloudblogs.microsoft.com/dynamics365/no-audience/2012/04/16/deep-queries-for-subgrids/?source=crm
How to Retrieve the value of an optionset field within a plugin
In Dynamics 365 C# Plugin, if retrieve optionset type fields value, you may need to convert the object to optionsetvalue type before quote its value. See below bold red code.
namespace UpdateTasksByOpportunity.Plugin
{
public class ChangeAllKidEntityRecordsStatusByParentEnty : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
// Obtain the tracing service
ITracingService tracingService =
(ITracingService)serviceProvider.GetService(typeof(ITracingService));
// Obtain the execution context from the service provider.
IPluginExecutionContext context = (IPluginExecutionContext)
serviceProvider.GetService(typeof(IPluginExecutionContext));
// The InputParameters collection contains all the data passed in the message request.
if (context.InputParameters.Contains("Target") &&
(context.InputParameters["Target"] is Entity ||
context.InputParameters["Target"] is EntityReference))
{
Guid regardingobjectid = Guid.NewGuid();
if (context.InputParameters["Target"] is Entity)
{
// Obtain the Parent entity from the input parameters.
Entity entity = (Entity)context.InputParameters["Target"];
// Refer to the opportunity in the task activity.
// Get the current opportunity ID / Parent Entity GUID
regardingobjectid = new Guid(entity.Id.ToString());
}
else if (context.InputParameters["Target"] is EntityReference)
{
// Obtain the Parent entity reference from the input parameters.
EntityReference entityReference = (EntityReference)context.InputParameters["Target"];
// Refer to the opportunity in the task activity.
// Get the current opportunity ID / Parent Entity GUID
regardingobjectid = new Guid(entityReference.Id.ToString());
}
// Obtain the organization service reference which you will need for
// web service calls.
IOrganizationServiceFactory serviceFactory =
(IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
//Check if Opportunity status is changed to "OPEN". If not, return.
//0 - "OPEN"; 1 - "WON"; 2 - "LOST"
Entity entityOpportunity = service.Retrieve("opportunity", regardingobjectid, new ColumnSet("statecode"));
if(((OptionSetValue)entityOpportunity["statecode"]).Value != 0)
{
tracingService.Trace("Opportunity new status: {0} is not OPEN", ((OptionSetValue)entityOpportunity["statecode"]).Value);
return;
}
//0 Open; 1 Completed; 2 Canceled
int stateCode = 2;
string kidEntity = "task";
try
{
// Retrieve all tasks with regarding opportunity is current opportunity
var queryExpression = new QueryExpression(kidEntity);
var qeFilter = new FilterExpression(LogicalOperator.And);
qeFilter.AddCondition(new ConditionExpression("statecode", ConditionOperator.Equal, "Open"));
qeFilter.AddCondition(new ConditionExpression("subject", ConditionOperator.Like, "%F/U%"));
qeFilter.AddCondition(new ConditionExpression("description", ConditionOperator.Like, "%Automated Task%"));
qeFilter.AddCondition(new ConditionExpression("regardingobjectid", ConditionOperator.Like, regardingobjectid));
queryExpression.Criteria = qeFilter;
queryExpression.ColumnSet = new ColumnSet("regardingobjectid");
//Get results:
var result = service.RetrieveMultiple(queryExpression);
foreach (var relatedTask in result.Entities)
{
// Create the Request Object
var state = new SetStateRequest();
state.State = new OptionSetValue(stateCode);
// Point the Request to the case whose state is being changed
state.EntityMoniker = new EntityReference(kidEntity, relatedTask.Id);
// Execute the Request
var stateSet = (SetStateResponse)service.Execute(state);
}
}
catch (FaultException<OrganizationServiceFault> ex)
{
throw new InvalidPluginExecutionException("An error occurred in FollowUpPlugin.", ex);
}
catch (Exception ex)
{
tracingService.Trace("FollowUpPlugin: {0}", ex.ToString());
throw;
}
}
}
}
[Serializable]
internal class FaultException<T> : Exception
{
public FaultException()
{
}
public FaultException(string message) : base(message)
{
}
public FaultException(string message, Exception innerException) : base(message, innerException)
{
}
protected FaultException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
}
}
Query Expression Add Criteria for look up field (Dynamics 365
Microsoft Dynamics 365 Plugin C# code.
If you wanna retrieve multiple records, you may use RetrieveMultiple function.
You can set filters and select the columns(fields) in the retrieve response.
When I set a filter for a lookup field (GUID), I tried two ways.
Both options work normally, the second way is better, greatly reduced the Amount of retrieved records, better for system performance. But the first way is still a good try for reading and comparing GUID value from retrieve response.
Option 1: Add filter in retrieve result procession. (Bad performance.)
// Retrieve all tasks with regarding opportunity is current opportunity
var queryExpression = new QueryExpression(kidEntity);
var qeFilter = new FilterExpression(LogicalOperator.And);
qeFilter.AddCondition(new ConditionExpression("statecode", ConditionOperator.Equal, "Open"));
qeFilter.AddCondition(new ConditionExpression("subject", ConditionOperator.Like, "%F/U%"));
qeFilter.AddCondition(new ConditionExpression("description", ConditionOperator.Like, "%Automated Task%"));
queryExpression.Criteria = qeFilter;
queryExpression.ColumnSet = new ColumnSet("regardingobjectid");
//Get results:
var result = service.RetrieveMultiple(queryExpression);
foreach (var relatedTask in result.Entities)
{
if(((EntityReference)relatedTask.Attributes["regardingobjectid"]).Id.ToString() == (regardingobjectid).ToString())
{
// Create the Request Object
var state = new SetStateRequest();
state.State = new OptionSetValue(stateCode);
// Point the Request to the case whose state is being changed
state.EntityMoniker = new EntityReference(kidEntity, relatedTask.Id);
// Execute the Request
var stateSet = (SetStateResponse)service.Execute(state);
}
}
Option 2: Add the filter into the query expression criteria. (Good performance.)
// Retrieve all tasks with regarding opportunity is current opportunity
var queryExpression = new QueryExpression(kidEntity);
var qeFilter = new FilterExpression(LogicalOperator.And);
qeFilter.AddCondition(new ConditionExpression("statecode", ConditionOperator.Equal, "Open"));
qeFilter.AddCondition(new ConditionExpression("subject", ConditionOperator.Like, "%F/U%"));
qeFilter.AddCondition(new ConditionExpression("description", ConditionOperator.Like, "%Automated Task%"));
qeFilter.AddCondition(new ConditionExpression("regardingobjectid", ConditionOperator.Like, regardingobjectid));
queryExpression.Criteria = qeFilter;
queryExpression.ColumnSet = new ColumnSet("regardingobjectid");
//Get results:
var result = service.RetrieveMultiple(queryExpression);
foreach (var relatedTask in result.Entities)
{
// Create the Request Object
var state = new SetStateRequest();
state.State = new OptionSetValue(stateCode);
// Point the Request to the case whose state is being changed
state.EntityMoniker = new EntityReference(kidEntity, relatedTask.Id);
// Execute the Request
var stateSet = (SetStateResponse)service.Execute(state);
}