diff --git a/src/Dataverse/templates/pp-entity-attribute/.template.config/template.json b/src/Dataverse/templates/pp-entity-attribute/.template.config/template.json
index 3d0fd83e..228e0ecf 100644
--- a/src/Dataverse/templates/pp-entity-attribute/.template.config/template.json
+++ b/src/Dataverse/templates/pp-entity-attribute/.template.config/template.json
@@ -18,7 +18,10 @@
{
"condition": "(!CreateGlobalOptionSet)",
"exclude": ["__solution-root-path__/OptionSets/*"]
- }
+ },
+ {
+ "exclude": ["__solution-root-path__/Entities/__entity-schema-name__/Formulas/__entity-schema-name__-FormulaDefinitions.yaml"]
+ }
]
}
],
@@ -149,6 +152,13 @@
{ "choice": "3", "description": "Time zone independent (stores actual value)" }
]
},
+ "IsFormulaField": {
+ "type": "parameter",
+ "description": "[Text/Decimal/WholeNumber/Float/Boolean/Choice/DateTime] Set true to mark this column as a formula field. This sets SourceType to 3, sets ValidForCreate/UpdateApi to 0 (read-only), adds FormulaDefinitionFileName metadata pointing to Entities/{EntitySchemaName}/Formulas/{EntitySchemaName}-FormulaDefinitions.yaml, and creates or appends to that consolidated YAML file with a placeholder entry. After scaffolding, fill in the Power Fx expression after the colon (e.g., 'ntg_totalamount: =ThisRecord.ntg_price * ThisRecord.ntg_quantity'). For multi-line formulas use '|-'. Reference same-record columns via ThisRecord.column_logical_name. The formula's return type must match the chosen AttributeType. Supported operators: +, -, *, /, %, in, exactin, &. Use Power Fx functions such as If, Switch, Concatenate, Text, DateAdd, UTCNow, etc.",
+ "datatype": "bool",
+ "defaultValue": "false",
+ "isEnabled": "(AttributeType == \"Text\" || AttributeType == \"Decimal\" || AttributeType == \"WholeNumber\" || AttributeType == \"Float\" || AttributeType == \"Boolean\" || AttributeType == \"OptionSet(Local)\" || AttributeType == \"OptionSet(Global)\" || AttributeType == \"DateTime\")"
+ },
"BooleanTrueLabel": {
"type": "parameter",
"description": "[Boolean] Label for the true/yes option.",
@@ -459,6 +469,20 @@
"description": "Adding lookup relationship xml"
},
+ {
+ "actionId": "3A7C4B45-1F5D-4A30-959A-51B88E82B5D2",
+ "condition": "(IsFormulaField)",
+ "args": {
+ "executable": "pwsh",
+ "args": "-noprofile -executionpolicy bypass -File \"./.template.scripts/InitFormulaDefinition.ps1\"",
+ "redirectStandardOutput": "false"
+ },
+ "manualInstructions": [
+ { "text": "Initializing formula definition YAML" }
+ ],
+ "continueOnError": false,
+ "description": "Initializing formula definition YAML"
+ },
{
"actionId": "3A7C4B45-1F5D-4A30-959A-51B88E82B5D2",
"args": {
diff --git a/src/Dataverse/templates/pp-entity-attribute/.template.scripts/InitFormulaDefinition.ps1 b/src/Dataverse/templates/pp-entity-attribute/.template.scripts/InitFormulaDefinition.ps1
new file mode 100644
index 00000000..d2a7c2f8
--- /dev/null
+++ b/src/Dataverse/templates/pp-entity-attribute/.template.scripts/InitFormulaDefinition.ps1
@@ -0,0 +1,27 @@
+$ErrorActionPreference = 'Stop'
+
+$formulasDir = (Resolve-Path '__solution-root-path__/Entities/__entity-schema-name__/Formulas' -ErrorAction SilentlyContinue)?.Path
+$yamlPath = Join-Path ($formulasDir ?? (Join-Path '__solution-root-path__' 'Entities' '__entity-schema-name__' 'Formulas')) '__entity-schema-name__-FormulaDefinitions.yaml'
+$entryKey = '__attribute-schema-name__:'
+
+# Create directory if it doesn't exist
+if (-not (Test-Path (Split-Path $yamlPath))) {
+ New-Item -ItemType Directory -Path (Split-Path $yamlPath) -Force | Out-Null
+}
+
+if (Test-Path $yamlPath) {
+ # File exists — check if this attribute's entry is already present
+ $content = Get-Content $yamlPath -Raw
+ $escapedKey = [regex]::Escape($entryKey)
+ if ($content -notmatch "(^|`n)$escapedKey") {
+ # Append new placeholder entry for the user to fill in
+ Add-Content -Path $yamlPath -Value "${entryKey} "
+ Write-Host "Appended formula placeholder for '$entryKey' in '$yamlPath'. Fill in the Power Fx expression after the colon."
+ } else {
+ Write-Host "Formula entry for '$entryKey' already exists in '$yamlPath'. Skipping."
+ }
+} else {
+ # File doesn't exist — create it with the first placeholder entry
+ Set-Content -Path $yamlPath -Value "${entryKey} "
+ Write-Host "Created '$yamlPath' with formula placeholder for '$entryKey'. Fill in the Power Fx expression after the colon."
+}
diff --git a/src/Dataverse/templates/pp-entity-attribute/.template.temp/attribute.xml b/src/Dataverse/templates/pp-entity-attribute/.template.temp/attribute.xml
index b059ff77..8fa5e1d0 100644
--- a/src/Dataverse/templates/pp-entity-attribute/.template.temp/attribute.xml
+++ b/src/Dataverse/templates/pp-entity-attribute/.template.temp/attribute.xml
@@ -53,13 +53,13 @@
auto
-
+
0
1
1
-
+
0
1
@@ -81,7 +81,11 @@
1
1
+
+ 3
+
0
+
1
@@ -215,4 +219,7 @@
+
+ /Formulas/__entity-schema-name__-FormulaDefinitions.yaml
+
diff --git a/src/Dataverse/templates/pp-entity-attribute/__solution-root-path__/Entities/__entity-schema-name__/Formulas/__entity-schema-name__-FormulaDefinitions.yaml b/src/Dataverse/templates/pp-entity-attribute/__solution-root-path__/Entities/__entity-schema-name__/Formulas/__entity-schema-name__-FormulaDefinitions.yaml
new file mode 100644
index 00000000..4487e0e7
--- /dev/null
+++ b/src/Dataverse/templates/pp-entity-attribute/__solution-root-path__/Entities/__entity-schema-name__/Formulas/__entity-schema-name__-FormulaDefinitions.yaml
@@ -0,0 +1 @@
+__attribute-schema-name__: