Skip to content

Commit a6590f3

Browse files
authored
Merge pull request #167 from metjuperry/master
2 parents c1005e5 + 5c9ffdb commit a6590f3

2 files changed

Lines changed: 262 additions & 0 deletions

File tree

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
---
2+
title: Liquid
3+
tagline: A series of custom tags and filters for use in Liquid templates, usable throughout our components
4+
author: Matěj Samler
5+
---
6+
7+
## Description
8+
9+
Liquid templating language can be used to map data from source to a different format. Go to [Liquid documentation](https://shopify.github.io/liquid/) for full documentation.
10+
11+
Bellow, we have multiple custom tags and filters we have created for easier work with Dataverse data. You can use these across our various components, such as Record Creation Rules, Power Automate connector, etc.
12+
13+
## General Tags
14+
15+
### JSON
16+
17+
Use this tag to parse a string into json and work with its properties.
18+
19+
**Syntax:**
20+
21+
```liquid
22+
{% json <source> %}
23+
<path>
24+
{% endjson %}
25+
```
26+
27+
**Example:**
28+
29+
Data:
30+
31+
```json
32+
{
33+
"input": "{'name': {'first': 'John', 'last':'Smith'}}"
34+
}
35+
```
36+
37+
Map:
38+
39+
```liquid
40+
My first name is {% json input %} name.first {% endjson %}
41+
```
42+
43+
Output:
44+
45+
```text
46+
My first name is John
47+
```
48+
49+
## CDS Tags
50+
51+
### CDSLookup
52+
53+
Use this tag to lookup a record URL based on a json of filters. The input is a logical name of the entity to search, the output is a record URL of the first found record.
54+
55+
**Syntax:**
56+
57+
```liquid
58+
{% cdslookup <logicalName> %}
59+
<filterJson>
60+
{% endcdslookup %}
61+
```
62+
63+
**Example:**
64+
65+
Data:
66+
67+
```json
68+
{
69+
"Surname" : "Smith"
70+
}
71+
```
72+
73+
Map:
74+
75+
```liquid
76+
URL is {% cdslookup contact %} {'lastname' : '{{ Surname }}'} {% endcdslookup %}
77+
```
78+
79+
Output:
80+
81+
```text
82+
URL is https://placeholder.crm4.dynamics.com/main.aspx?etn=contact&id=5caf3e4f-3737-4a88-8664-7d93d16ab2fc
83+
```
84+
85+
### CDSOptionSetLocalizedLabel
86+
87+
Use this tag to translate a value of option set to human readable string.
88+
89+
**Syntax:**
90+
91+
```liquid
92+
{% cdsoptionsetlocalizedlabel <entityLogicalName>,<fieldName>,<languageCode> %}
93+
<optionSetValue>
94+
{% endcdsoptionsetlocalizedlabel %}
95+
```
96+
97+
**Example:**
98+
99+
Data:
100+
101+
```json
102+
{ "AccountType" : 820001 }
103+
```
104+
105+
Map:
106+
107+
```liquid
108+
Account type is {% cdsoptionsetlocalizedlabel account,type,1033 %}{{ AccountType }}{% endcdsoptionsetlocalizedlabel %}
109+
```
110+
111+
Output:
112+
113+
```text
114+
Account type is Vendor
115+
```
116+
117+
### CDSGetFieldValue
118+
119+
Use this tag to get a value of a field (or multiple) on an record. We are using CDSTypeConverter, so it should return readable input in all cases. We are returning recordUrl if the field is a lookup.
120+
121+
**Syntax:**
122+
123+
```liquid
124+
{% cdsgetfieldvalue <commaSeparatedFieldNames> %}
125+
<recordURL>
126+
{% endcdsgetfieldvalue %}
127+
```
128+
129+
**Example:**
130+
131+
Data:
132+
133+
```json
134+
{ "RecordURL" : "https://placeholder.crm4.dynamics.com/main.aspx?etn=contact&id=5caf3e4f-3737-4a88-8664-7d93d16ab2fc"}
135+
```
136+
137+
Map:
138+
139+
```liquid
140+
Contact surname is {% cdsgetfieldvalue lastname %}{{ RecordURL }}{% endcdsgetfieldvalue %}
141+
```
142+
143+
Output:
144+
145+
```text
146+
Contact surname is Smith
147+
```
148+
149+
**Note:**
150+
This tag returns multiple values, but they are not separated in any way. It should be used to fetch a single value.
151+
152+
### CDSIdToRecordUrl
153+
154+
Transforms logical name and id into a redirectable record url.
155+
156+
**Syntax:**
157+
158+
```liquid
159+
{% cdsidtorecordurl <logicalName> %}
160+
<recordId>
161+
{% endcdsidtorecordurl %}
162+
```
163+
164+
**Example:**
165+
166+
Data:
167+
168+
```json
169+
{ "RecordId" : "5caf3e4f-3737-4a88-8664-7d93d16ab2fc"}
170+
```
171+
172+
Map:
173+
174+
```liquid
175+
URL is {% cdsidtorecordurl contact %}{{ RecordId }}{% endcdsidtorecordurl %}
176+
```
177+
178+
Output:
179+
180+
```text
181+
URL is https://placeholder.crm4.dynamics.com/main.aspx?etn=contact&id=5caf3e4f-3737-4a88-8664-7d93d16ab2fc&pagetype=entityrecord
182+
```
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
---
2+
title: Record Creation Rules
3+
tagline: Define rules for automatic record creation via Dataverse records
4+
author: Matěj Samler
5+
---
6+
7+
# Record Creation Rules
8+
9+
Record Creation rules allow you to define custom rules for listening to CRUD operations on records and automatically creating new records in response to those operations.
10+
These rules are defined via Dataverse records themselves, making them easy to manage and modify without needing to change any code.
11+
12+
## Entities
13+
14+
### Record Creation Rule
15+
16+
Record creation rules is the main entity for defining rules.
17+
18+
Looking at its form, we can see multiple sections:
19+
20+
#### Source entity
21+
22+
- Source Entity Name: Logical name of the entity to listen to
23+
- Trigger Messages: A multiselect optionset for selecting which CRUD operations to listen to. We can select Create, Update, Delete or Assign.
24+
- Filtering Attributes: A comma-separated list of attributes to filter on. This is only applicable when the Trigger Message is set to Update. If this is left empty, the rule will trigger on any update.
25+
- Query: After saving of the record, a query builder will become available. This allows you to define additional filtering criteria for the rule.
26+
27+
#### Target entity
28+
29+
- Entity Name: Logical name of the entity to create records in
30+
- Liquid Map: A liquid template for mapping attributes from the source entity to the target entity. The source entity is used as the data input, so all of its attributes can be accessed directly. There are also some custom Dataverse tags available, see [Liquid](../utilities/liquid.md) for more information.
31+
32+
#### Update Source Record (After Action)
33+
34+
- Success: A liquid template for updating the source record after the target record has been successfully created. Can be used to change status, set a lookup to the created record, etc.
35+
36+
## Record Creation Rule Log
37+
38+
In case of an error during the execution of a record creation rule, a log record will be created. In case of an error, the execution of the message is not halted and the operation will succeed, but the error will be logged for later review.
39+
40+
## How it works
41+
42+
In the background, there are multiple components working together to make this functionality work.
43+
44+
**On create of a new record creation rule, we:**
45+
46+
- Check if a record creation rule listener is already registered for the given source entity and for the selected message. If not, we register a new listener.
47+
48+
**On delete of a record creation rule, we:**
49+
50+
- Check if there are any other record creation rules for the same source entity and message. If not, we unregister the listener.
51+
52+
**When a message is received by the listener, we:**
53+
54+
- Retrieve all record creation rules for the given entity and message
55+
- For each rule, check if the filtering attributes match (if defined)
56+
- For each rule, check if the query matches (if defined)
57+
- For each matching rule, create a new target record based on the liquid map
58+
- For each matching rule, update the source record based on the after action liquid map (if defined)
59+
- In case of an error during processing of a rule, create a log record
60+
61+
The creation itself is done by using an Action
62+
63+
## Implementation details
64+
65+
The main components of the implementation are:
66+
67+
### Workflow activity
68+
69+
- **Plugin Registrator**: Responsible for registering the listeners. Registers a new SDK message on a processing step of the source entity.
70+
- **Plugin Deletor**: Responsible for unregistering the listeners. Unregisters the SDK message if there are no more rules for the given entity and message.
71+
72+
### Plugin
73+
74+
- **ProcessRecordCreationRule**: The main listener plugin. Listens to the messages defined in the record creation rules and processes them.
75+
76+
### Workflows
77+
78+
- **DeleteRuleListener**: A workflow that is called by the plugin deletor to delete the listener.
79+
- **RegisterRuleListener**: A workflow that is called by the plugin registrator to register the listener.
80+
- **talxis_createrecordfromrule**: A workflow that is called by the main listener plugin to create the target record and update the source record. It uses the liquid maps defined in the rule to perform the creation and update.

0 commit comments

Comments
 (0)