Recently while trying to invoke the HTTP Request trigger, on passing the token we got the below error from the Postman
{
"error": {
"code": "MisMatchingOAuthClaims",
"message": "One or more claims either missing or does not match with the open authentication access control policy."
}
}
Turned out that we missed the trailing slash for the resource’s value while generating the token.
The Case Handling Time widget (preview) can be added to the Case Form, giving a focused way to track case resolution efficiency. By using this feature, we can identify patterns, make informed decisions, and continuously refine processes.
To enable it to navigate to
Customer Service Admin Center >> Customer Support >> Case Settings >> Case handling time (preview)
Update Interval specifies how frequently the handling time widget is refreshed (it also updates the database). Can be between 10 to 60 minutes. The interesting point here is if 2 agents open the same case at the same time, the widget will display 20 minutes, after 10 minutes.
Next, open the form where we want to add the component, click on Get more components, and search for the Handling Time component to add it.
Configure the properties for the component –
Table – Time Trackers
View – All Time Trackers
Allow users to add time logs – True / False (enables agents to log time)
Show users only their contributed time – True / False (specifies whether an agent can only see their time or time entered by other agents also for that case)
Allow users to edit their automatic time tracked – True / False (specifies if an agent can edit automatic time tracked).
Save and publish the changes.
We can see the Handling Time widget at the bottom right corner in the minimized state on the form.
On maximizing it after some time, we can see the following details there.
Automatic Time Tracking, Manual Time Tracking, History section.
Checking My Time shows the Live time spent by that particular agent.
Clicking on the plus button allows us to add manual Time log records.
If there is a second user who opens the form, the automatic time tracking shows the values applied to that user.
We can use the setIsValid method for validating field values in Model-driven apps. This method helps ensure that the data entered by users meets the required criteria before it’s processed or saved.
The setIsValid method is used to set the validity of a column’s value. It can mark a field as valid or invalid based on custom validation logic.
bool: A Boolean value. Set to false to mark the column value as invalid, and true to mark it as valid.
message: (Optional) A string containing the message to display when the value is invalid.
Below we are using the setIsValid method in the function that ensures that the “End Date” is earlier than or equal to the “Start Date”, else it will mark the “End Date” as invalid.
function validateDates(executionContext) {
var formContext = executionContext.getFormContext();
var startDate = formContext.getAttribute("custom_startdate");
var endDate = formContext.getAttribute("custom_enddate");
if (startDate && endDate && endDate.getValue() <= startDate.getValue()) {
endDate.setIsValid(false, "End Date must be after Start Date.");
} else {
endDate.setIsValid(true);
}
}
We have it registered in the On Change of the ‘Start Date’ and ‘End Date’ fields.
Here if we try saving the record, if the End Date is smaller than the Start Date, we will get the message specified.
In Dataverse, solution dependencies are a vital aspect of managing and deploying applications. Dependencies ensure that required components are present for a solution to work seamlessly across environments. However, with complex solutions, understanding and managing these dependencies can become overwhelming.
The updated dependencies page is designed to simplify dependency management by offering a more intuitive, action-driven experience.
Select a particular component in the solution, right-click>> Advanced >> Show dependencies.
We can see 3 different tabs.
Delete Blocked By (tab): Displays any dependencies preventing deletion of a component. Below we can see that for the Age column, it shows Contact’s System Form as the dependency.
Clicking on the Open option takes us to the component page, where we can see all the forms for the contact table.
Used By (tab): Lists other components dependent on the selected component.
Uses (tab): Shows dependencies that the selected component relies upon.
On clicking Open, it opens the Columns page for that table.
The different actions that we can take are Open and inspect the object, Delete the object, Remove dependency, and open the relevant documentation.
Below we have selected the option Remove dependency. As we saw the dependency here refers to the Contact System form in which we have the age field used.
Select Remove.
We get the success message after the successful removal of the dependency.
i.e. we can see the field removed from the blocking Contact’s System form.
Now if we want we can easily delete that particular field with no object blocking the delete.
Lastly, the Delete option for the solution allows the delete (uninstall) the solution that has dependencies on the solution component.
We had mapped the primary field for deletion and the package was also showing success.
However back in our CRM / Sales Hub app, we saw that none of the records were deleted (total – 48999)
The reason it was showing success is that we had specified the Ignore Error option in our CDS Destination component.
Then we created 2 more records but didn’t specify the partition ID for them.
This time on the successful run of the package we can see those 2 new records getting deleted for which we didn’t specify any partition ID i.e. Test 1 and Test 2 records were deleted successfully.
If we check the Microsoft docs it mentions that we need to include the partition ID using the alternate key to delete those records using the DeleteMultiple request.
Could not find a way to specify an Alternate Key in the CDS Destination component for the Delete message and if we try deleting the records one by one instead of using the DeleteMultiple request we get the below error.
[CDS Destination [2]] Error: An error occurred with the following error message: “System.Exception: Error(s) occurred when processing the batch: [1] KingswaySoft.IntegrationToolkit.DynamicsCrm.WebAPI.WebApiServiceException: The remote server returned an error: (404) Not Found. (Error Type / Reason: NotFound, Detailed Message: {“error”:{“code”:”0x80040217″,”message”:”The HTTP status code of the response was not expected (404).\n\nStatus: 404\nResponse: \n{\”error\”:{\”message\”:\”Could not find item ‘b3a70971-9674-ef11-a671-6045bdfe58ee’.\”,\”details\”:[{\”message\”:\”\\r\\nErrors : [\\r\\n \\\”Resource Not Found. Learn more: https://aka.ms/cosmosdb-tsg-not-found\\\”\\r\\n]\\r\\n\”}]}}”}}) (SSIS Integration Toolkit for Microsoft Dynamics 365, v23.2.2.32701 – DtsDebugHost, v16.0.5270.0)System.Net.WebException
As expected, using CrmServiceClient also if we do not include partitionid we will get the below error for the records that have partition id specified.
The HTTP status code of the response was not expected (404).
Response:
{“error”:{“message”:”Could not find item ‘b3a70971-9674-ef11-a671-6045bdfe58ee’.”,”details”:[{“message”:”\r\nErrors : [\r\n \”Resource Not Found. Learn more: https://aka.ms/cosmosdb-tsg-not-found\”\r\n]\r\n”}]}}
Here we can specify the partitionId parameter to delete those records having the partitionId specified in the DeleteRequest
For DeleteMultiple Request we need to provide the alternate key as shown below.
We will have the alternate key auto-created by the system when we create an elastic table.
Sample Code –
var myServiceClient = new CrmServiceClient(connectionString);
var query = new QueryExpression("custom_myelastictable");
query.ColumnSet.AddColumns("custom_name", "partitionid");
var myElasticTableCollection = myServiceClient.RetrieveMultiple(query);
var lstEntityRefCollection = new EntityReferenceCollection();
// Delete Request
foreach (var elasticTable in myElasticTableCollection.Entities)
{
var deleteRequest = new DeleteRequest();
deleteRequest.Target = new EntityReference("custom_myelastictable", elasticTable.Id);
deleteRequest.Parameters["partitionId"] = elasticTable.Attributes["partitionid"];
var response = myServiceClient.Execute(deleteRequest);
}
// DeleteMultiple Request
foreach (var elasticTable in myElasticTableCollection.Entities)
{
var entityRef = new EntityReference("custom_myelastictable", elasticTable.Id);
entityRef.KeyAttributes.Add("custom_myelastictableid", elasticTable.Id);
entityRef.KeyAttributes.Add("partitionid", elasticTable.Attributes["partitionid"]);
lstEntityRefCollection.Add(entityRef);
}
var deleteMultipleRequest = new OrganizationRequest();
deleteMultipleRequest.RequestName = "DeleteMultiple";
deleteMultipleRequest.Parameters.Add("Targets", lstEntityRefCollection);
myServiceClient.Execute(deleteMultipleRequest);