diff --git a/.claude/skills/skd-compile/scripts/skd-compile.ps1 b/.claude/skills/skd-compile/scripts/skd-compile.ps1
index 62754ccd..ff745829 100644
--- a/.claude/skills/skd-compile/scripts/skd-compile.ps1
+++ b/.claude/skills/skd-compile/scripts/skd-compile.ps1
@@ -1,4 +1,4 @@
-# skd-compile v1.30 — Compile 1C DCS from JSON
+# skd-compile v1.31 — Compile 1C DCS from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[string]$DefinitionFile,
@@ -1787,6 +1787,51 @@ function Emit-GroupTemplates {
# === Settings Variants ===
+function Emit-SelectionItem {
+ param($item, [string]$indent)
+ if ($item -is [string]) {
+ if ($item -eq "Auto") {
+ X "$indent"
+ } else {
+ X "$indent"
+ X "$indent`t$(Esc-Xml $item)"
+ X "$indent"
+ }
+ return
+ }
+ if ($item.folder -or (Has-JsonProp $item 'folder')) {
+ X "$indent"
+ # Optional на folder (редкий случай, для round-trip-целостности)
+ if ($item.field) {
+ X "$indent`t$(Esc-Xml "$($item.field)")"
+ }
+ X "$indent`t"
+ X "$indent`t`t"
+ X "$indent`t`t`tru"
+ X "$indent`t`t`t$(Esc-Xml "$($item.folder)")"
+ X "$indent`t`t"
+ X "$indent`t"
+ foreach ($sub in $item.items) {
+ Emit-SelectionItem -item $sub -indent "$indent`t"
+ }
+ X "$indent`tAuto"
+ X "$indent"
+ return
+ }
+ # field with optional title
+ X "$indent"
+ X "$indent`t$(Esc-Xml "$($item.field)")"
+ if ($item.title) {
+ X "$indent`t"
+ X "$indent`t`t"
+ X "$indent`t`t`tru"
+ X "$indent`t`t`t$(Esc-Xml "$($item.title)")"
+ X "$indent`t`t"
+ X "$indent`t"
+ }
+ X "$indent"
+}
+
function Emit-Selection {
param($items, [string]$indent, [switch]$skipAuto)
@@ -1794,45 +1839,8 @@ function Emit-Selection {
X "$indent"
foreach ($item in $items) {
- if ($item -is [string]) {
- if ($item -eq "Auto") {
- if (-not $skipAuto) {
- X "$indent`t"
- }
- } else {
- X "$indent`t"
- X "$indent`t`t$(Esc-Xml $item)"
- X "$indent`t"
- }
- } elseif ($item.folder) {
- X "$indent`t"
- X "$indent`t`t"
- X "$indent`t`t`t"
- X "$indent`t`t`t`tru"
- X "$indent`t`t`t`t$(Esc-Xml "$($item.folder)")"
- X "$indent`t`t`t"
- X "$indent`t`t"
- foreach ($sub in $item.items) {
- $subName = if ($sub -is [string]) { $sub } else { "$($sub.field)" }
- X "$indent`t`t"
- X "$indent`t`t`t$(Esc-Xml $subName)"
- X "$indent`t`t"
- }
- X "$indent`t`tAuto"
- X "$indent`t"
- } else {
- X "$indent`t"
- X "$indent`t`t$(Esc-Xml "$($item.field)")"
- if ($item.title) {
- X "$indent`t`t"
- X "$indent`t`t`t"
- X "$indent`t`t`t`tru"
- X "$indent`t`t`t`t$(Esc-Xml "$($item.title)")"
- X "$indent`t`t`t"
- X "$indent`t`t"
- }
- X "$indent`t"
- }
+ if ($skipAuto -and ($item -is [string]) -and $item -eq 'Auto') { continue }
+ Emit-SelectionItem -item $item -indent "$indent`t"
}
X "$indent"
}
@@ -2370,6 +2378,21 @@ function Emit-StructureItem {
X "$indent"
}
+ elseif ($type -eq "nestedObject") {
+ X "$indent"
+ if ($item.objectID) { X "$indent`t$(Esc-Xml "$($item.objectID)")" }
+ X "$indent`t"
+ $s = $item.settings
+ if ($s) {
+ if ($s.selection) { Emit-Selection -items $s.selection -indent "$indent`t`t" }
+ if ($s.filter) { Emit-Filter -items $s.filter -indent "$indent`t`t" }
+ if ($s.order) { Emit-Order -items $s.order -indent "$indent`t`t" }
+ if ($s.conditionalAppearance) { Emit-ConditionalAppearance -items $s.conditionalAppearance -indent "$indent`t`t" }
+ if ($s.outputParameters) { Emit-OutputParameters -params $s.outputParameters -indent "$indent`t`t" }
+ }
+ X "$indent`t"
+ X "$indent"
+ }
}
function Emit-SettingsVariants {
diff --git a/.claude/skills/skd-compile/scripts/skd-compile.py b/.claude/skills/skd-compile/scripts/skd-compile.py
index 6bc8d86e..667600be 100644
--- a/.claude/skills/skd-compile/scripts/skd-compile.py
+++ b/.claude/skills/skd-compile/scripts/skd-compile.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
-# skd-compile v1.30 — Compile 1C DCS from JSON
+# skd-compile v1.31 — Compile 1C DCS from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
import json
@@ -1481,46 +1481,51 @@ def emit_group_templates(lines, defn):
# === Settings Variants ===
+def emit_selection_item(lines, item, indent):
+ if isinstance(item, str):
+ if item == 'Auto':
+ lines.append(f'{indent}')
+ else:
+ lines.append(f'{indent}')
+ lines.append(f'{indent}\t{esc_xml(item)}')
+ lines.append(f'{indent}')
+ return
+ if 'folder' in item:
+ lines.append(f'{indent}')
+ if item.get('field'):
+ lines.append(f'{indent}\t{esc_xml(str(item["field"]))}')
+ lines.append(f'{indent}\t')
+ lines.append(f'{indent}\t\t')
+ lines.append(f'{indent}\t\t\tru')
+ lines.append(f'{indent}\t\t\t{esc_xml(str(item["folder"]))}')
+ lines.append(f'{indent}\t\t')
+ lines.append(f'{indent}\t')
+ for sub in (item.get('items') or []):
+ emit_selection_item(lines, sub, f'{indent}\t')
+ lines.append(f'{indent}\tAuto')
+ lines.append(f'{indent}')
+ return
+ # field with optional title
+ lines.append(f'{indent}')
+ lines.append(f'{indent}\t{esc_xml(str(item["field"]))}')
+ if item.get('title'):
+ lines.append(f'{indent}\t')
+ lines.append(f'{indent}\t\t')
+ lines.append(f'{indent}\t\t\tru')
+ lines.append(f'{indent}\t\t\t{esc_xml(str(item["title"]))}')
+ lines.append(f'{indent}\t\t')
+ lines.append(f'{indent}\t')
+ lines.append(f'{indent}')
+
+
def emit_selection(lines, items, indent, skip_auto=False):
if not items or len(items) == 0:
return
-
lines.append(f'{indent}')
for item in items:
- if isinstance(item, str):
- if item == 'Auto':
- if not skip_auto:
- lines.append(f'{indent}\t')
- else:
- lines.append(f'{indent}\t')
- lines.append(f'{indent}\t\t{esc_xml(item)}')
- lines.append(f'{indent}\t')
- elif item.get('folder'):
- lines.append(f'{indent}\t')
- lines.append(f'{indent}\t\t')
- lines.append(f'{indent}\t\t\t')
- lines.append(f'{indent}\t\t\t\tru')
- lines.append(f'{indent}\t\t\t\t{esc_xml(str(item["folder"]))}')
- lines.append(f'{indent}\t\t\t')
- lines.append(f'{indent}\t\t')
- for sub in (item.get('items') or []):
- sub_name = str(sub.get('field', sub)) if isinstance(sub, dict) else str(sub)
- lines.append(f'{indent}\t\t')
- lines.append(f'{indent}\t\t\t{esc_xml(sub_name)}')
- lines.append(f'{indent}\t\t')
- lines.append(f'{indent}\t\tAuto')
- lines.append(f'{indent}\t')
- else:
- lines.append(f'{indent}\t')
- lines.append(f'{indent}\t\t{esc_xml(str(item["field"]))}')
- if item.get('title'):
- lines.append(f'{indent}\t\t')
- lines.append(f'{indent}\t\t\t')
- lines.append(f'{indent}\t\t\t\tru')
- lines.append(f'{indent}\t\t\t\t{esc_xml(str(item["title"]))}')
- lines.append(f'{indent}\t\t\t')
- lines.append(f'{indent}\t\t')
- lines.append(f'{indent}\t')
+ if skip_auto and isinstance(item, str) and item == 'Auto':
+ continue
+ emit_selection_item(lines, item, f'{indent}\t')
lines.append(f'{indent}')
@@ -1962,6 +1967,20 @@ def emit_structure_item(lines, item, indent):
lines.append(f'{indent}')
+ elif item_type == 'nestedObject':
+ lines.append(f'{indent}')
+ if item.get('objectID'):
+ lines.append(f'{indent}\t{esc_xml(str(item["objectID"]))}')
+ lines.append(f'{indent}\t')
+ s = item.get('settings') or {}
+ if s.get('selection'): emit_selection(lines, s['selection'], f'{indent}\t\t')
+ if s.get('filter'): emit_filter(lines, s['filter'], f'{indent}\t\t')
+ if s.get('order'): emit_order(lines, s['order'], f'{indent}\t\t')
+ if s.get('conditionalAppearance'): emit_conditional_appearance(lines, s['conditionalAppearance'], f'{indent}\t\t')
+ if s.get('outputParameters'): emit_output_parameters(lines, s['outputParameters'], f'{indent}\t\t')
+ lines.append(f'{indent}\t')
+ lines.append(f'{indent}')
+
def emit_settings_variants(lines, defn):
variants = defn.get('settingsVariants')
diff --git a/.claude/skills/skd-decompile/scripts/skd-decompile.ps1 b/.claude/skills/skd-decompile/scripts/skd-decompile.ps1
index b2d14d25..099d8610 100644
--- a/.claude/skills/skd-decompile/scripts/skd-decompile.ps1
+++ b/.claude/skills/skd-decompile/scripts/skd-decompile.ps1
@@ -1,4 +1,4 @@
-# skd-decompile v0.12 — Decompile 1C DCS Template.xml to JSON DSL (draft)
+# skd-decompile v0.13 — Decompile 1C DCS Template.xml to JSON DSL (draft)
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[Parameter(Mandatory)]
@@ -1028,42 +1028,51 @@ function Build-FilterItem {
return $s
}
+# Recursive helper для одного элемента selection. Возвращает либо строку (имя поля / "Auto"),
+# либо ordered hashtable ({field, title} / {folder, items: [...]} / sentinel).
+function Build-SelectionItem {
+ param($item, [string]$loc)
+ $xt = Get-LocalXsiType $item
+ # Implicit SelectedItemField: - без xsi:type, но с
+ if (-not $xt) {
+ $fName = Get-Text $item "dcsset:field"
+ if ($fName) { return $fName }
+ }
+ switch ($xt) {
+ 'SelectedItemAuto' { return 'Auto' }
+ 'SelectedItemField' {
+ $fName = Get-Text $item "dcsset:field"
+ $titleNode = $item.SelectSingleNode("dcsset:lwsTitle", $ns)
+ $title = Get-MLText $titleNode
+ if ($title) { return [ordered]@{ field = $fName; title = $title } }
+ return $fName
+ }
+ 'SelectedItemFolder' {
+ $titleNode = $item.SelectSingleNode("dcsset:lwsTitle", $ns)
+ $folderTitle = Get-MLText $titleNode
+ $inner = @()
+ foreach ($sub in $item.SelectNodes("dcsset:item", $ns)) {
+ $inner += (Build-SelectionItem -item $sub -loc "$loc/folder")
+ }
+ $entry = [ordered]@{ folder = $folderTitle; items = $inner }
+ # folder может также иметь свой (редко, но встречается)
+ $folderField = Get-Text $item "dcsset:field"
+ if ($folderField) { $entry['field'] = $folderField }
+ return $entry
+ }
+ default {
+ return (New-Sentinel -kind "SelectionItem:$xt" -loc $loc -detail 'Неизвестный тип элемента selection')
+ }
+ }
+}
+
# Build selection items array
function Build-Selection {
param($selNode, [string]$loc)
if (-not $selNode) { return @() }
$out = @()
foreach ($it in $selNode.SelectNodes("dcsset:item", $ns)) {
- $xt = Get-LocalXsiType $it
- # Implicit SelectedItemField: without xsi:type but with child.
- # Платформа эмитит это в conditionalAppearance/selection.
- if (-not $xt) {
- $fName = Get-Text $it "dcsset:field"
- if ($fName) { $out += $fName; continue }
- }
- switch ($xt) {
- 'SelectedItemAuto' { $out += 'Auto' }
- 'SelectedItemField' { $out += (Get-Text $it "dcsset:field") }
- 'SelectedItemFolder' {
- $titleNode = $it.SelectSingleNode("dcsset:lwsTitle", $ns)
- $folderTitle = Get-MLText $titleNode
- $inner = @()
- foreach ($sub in $it.SelectNodes("dcsset:item", $ns)) {
- $st = Get-LocalXsiType $sub
- if (-not $st) {
- $subF = Get-Text $sub "dcsset:field"
- if ($subF) { $inner += $subF; continue }
- }
- if ($st -eq 'SelectedItemField') { $inner += (Get-Text $sub "dcsset:field") }
- elseif ($st -eq 'SelectedItemAuto') { $inner += 'Auto' }
- else { $inner += (New-Sentinel -kind "SelectionInFolder:$st" -loc "$loc/folder" -detail 'Неизвестный тип элемента папки выбора') }
- }
- $out += [ordered]@{ folder = $folderTitle; items = $inner }
- }
- default {
- $out += (New-Sentinel -kind "SelectionItem:$xt" -loc $loc -detail 'Неизвестный тип элемента selection')
- }
- }
+ $out += (Build-SelectionItem -item $it -loc $loc)
}
return ,$out
}
@@ -1219,7 +1228,8 @@ function Build-DataParameters {
return ,$entries
}
-# Read groupItems -> array of field names (with periodAddition/groupType warnings)
+# Read groupItems → array. Простые поля → string. С нестандартным groupType/periodAdditionType
+# → object form {field, groupType?, periodAdditionType?} (compile принимает оба варианта).
function Get-GroupFields {
param($parentNode, [string]$loc)
$gFields = @()
@@ -1231,10 +1241,15 @@ function Get-GroupFields {
$gf = Get-Text $gItem "dcsset:field"
$pat = Get-Text $gItem "dcsset:periodAdditionType"
$gt = Get-Text $gItem "dcsset:groupType"
- if (($pat -and $pat -ne 'None') -or ($gt -and $gt -ne 'Items')) {
- $null = Add-Warning -kind 'GroupItemDetails' -loc "$loc/groupItems" -detail "Группировка $gf использует groupType=$gt, periodAdditionType=$pat — не воспроизводится в shorthand"
+ $isDefault = (-not $pat -or $pat -eq 'None') -and (-not $gt -or $gt -eq 'Items')
+ if ($isDefault) {
+ $gFields += $gf
+ } else {
+ $obj = [ordered]@{ field = $gf }
+ if ($gt -and $gt -ne 'Items') { $obj['groupType'] = $gt }
+ if ($pat -and $pat -ne 'None') { $obj['periodAdditionType'] = $pat }
+ $gFields += $obj
}
- $gFields += $gf
} else {
$gFields += (New-Sentinel -kind "GroupItem:$gxt" -loc "$loc/groupItems" -detail 'Тип элемента группировки не покрыт')
}
@@ -1293,6 +1308,39 @@ function Build-Structure {
$idx++
continue
}
+ if ($xt -eq 'StructureItemNestedObject') {
+ $entry = [ordered]@{ type = 'nestedObject' }
+ $objID = Get-Text $it "dcsset:objectID"
+ if ($objID) { $entry['objectID'] = $objID }
+ $settingsNode = $it.SelectSingleNode("dcsset:settings", $ns)
+ if ($settingsNode) {
+ $nestedSettings = [ordered]@{}
+ $selNode = $settingsNode.SelectSingleNode("dcsset:selection", $ns)
+ $selI = Build-Selection -selNode $selNode -loc "$loc/$idx/nested/selection"
+ if ($selI.Count -gt 0) { $nestedSettings['selection'] = $selI }
+ $fNode = $settingsNode.SelectSingleNode("dcsset:filter", $ns)
+ if ($fNode -and $fNode.SelectNodes("dcsset:item", $ns).Count -gt 0) {
+ $fa = @()
+ foreach ($fc in $fNode.SelectNodes("dcsset:item", $ns)) { $fa += (Build-FilterItem -itemNode $fc -loc "$loc/$idx/nested/filter") }
+ $nestedSettings['filter'] = $fa
+ }
+ $oNode = $settingsNode.SelectSingleNode("dcsset:order", $ns)
+ $oI = Build-Order -ordNode $oNode -loc "$loc/$idx/nested/order"
+ if ($oI.Count -gt 0) { $nestedSettings['order'] = $oI }
+ $caNode = $settingsNode.SelectSingleNode("dcsset:conditionalAppearance", $ns)
+ if ($caNode) {
+ $ca = Build-ConditionalAppearance -caNode $caNode -loc "$loc/$idx/nested/ca"
+ if ($ca.Count -gt 0) { $nestedSettings['conditionalAppearance'] = $ca }
+ }
+ $opNode = $settingsNode.SelectSingleNode("dcsset:outputParameters", $ns)
+ $op = Build-OutputParameters -opNode $opNode
+ if ($op -and $op.Count -gt 0) { $nestedSettings['outputParameters'] = $op }
+ $entry['settings'] = $nestedSettings
+ }
+ $items += $entry
+ $idx++
+ continue
+ }
if ($xt -eq 'StructureItemChart') {
$entry = [ordered]@{ type = 'chart' }
$nm = Get-Text $it "dcsset:name"
@@ -1322,28 +1370,8 @@ function Build-Structure {
# Optional name
$nm = Get-Text $it "dcsset:name"
if ($nm) { $entry['name'] = $nm }
- # groupItems → groupFields
- $gi = $it.SelectSingleNode("dcsset:groupItems", $ns)
- $gFields = @()
- if ($gi) {
- foreach ($gItem in $gi.SelectNodes("dcsset:item", $ns)) {
- $gxt = Get-LocalXsiType $gItem
- if ($gxt -eq 'GroupItemField') {
- $gf = Get-Text $gItem "dcsset:field"
- # Look at periodAdditionType — non-None or non-default → sentinel
- $pat = Get-Text $gItem "dcsset:periodAdditionType"
- $gt = Get-Text $gItem "dcsset:groupType"
- if (($pat -and $pat -ne 'None') -or ($gt -and $gt -ne 'Items')) {
- # Non-default grouping — record but don't fail
- # We still emit the field; flag in warnings only
- $null = Add-Warning -kind 'GroupItemDetails' -loc "$loc/groupItems" -detail "Группировка $gf использует groupType=$gt, periodAdditionType=$pat — не воспроизводится в shorthand"
- }
- $gFields += $gf
- } else {
- $gFields += (New-Sentinel -kind "GroupItem:$gxt" -loc "$loc/groupItems" -detail 'Тип элемента группировки не покрыт')
- }
- }
- }
+ # groupItems → groupFields (через общий Get-GroupFields с object form поддержкой)
+ $gFields = Get-GroupFields -parentNode $it -loc $loc
if ($gFields.Count -gt 0) { $entry['groupFields'] = $gFields }
# Local selection — only emit if not "[Auto]" default
@@ -1398,6 +1426,8 @@ function Try-StructureShorthand {
break
}
if ($gfs.Count -ne 1) { return $null }
+ # Только простые имена-строки сворачиваем в shorthand
+ if ($gfs[0] -isnot [string]) { return $null }
$parts += $gfs[0]
$children = $cur['children']
if ($null -eq $children -or $children.Count -eq 0) { break }
diff --git a/tests/skills/cases/skd-decompile/snapshots/structure-nested-and-folder/Template.xml b/tests/skills/cases/skd-decompile/snapshots/structure-nested-and-folder/Template.xml
new file mode 100644
index 00000000..b3d71cb1
--- /dev/null
+++ b/tests/skills/cases/skd-decompile/snapshots/structure-nested-and-folder/Template.xml
@@ -0,0 +1,159 @@
+
+
+
+ ИсточникДанных1
+ Local
+
+
+ DSОбъединение
+
+ Период
+ Период
+
+ xs:dateTime
+
+ Date
+
+
+
+
+ ВидРасчета
+ ВидРасчета
+
+ d5p1:CatalogRef.ВидыРасчета
+
+
+
+ Сумма
+ Сумма
+
+ xs:decimal
+
+ 15
+ 2
+ Any
+
+
+
+
+ Подразделение
+ Подразделение
+
+ d5p1:CatalogRef.Подразделения
+
+
+
+ Часть1
+ ИсточникДанных1
+ ДанныеЧасть1
+
+
+ Часть2
+ ИсточникДанных1
+ ДанныеЧасть2
+
+
+
+ Основной
+
+
+ ru
+ Основной
+
+
+
+
+
+ Период
+
+
+ Сумма
+
+
+ ru
+ Итого
+
+
+
+
+
+
+ ru
+ Группа итогов
+
+
+
+ ВидРасчета
+
+
+ Сумма
+
+
+ ru
+ Сумма с расшифровкой
+
+
+
+
+
+
+ ru
+ Подгруппа
+
+
+
+ Подразделение
+
+ Auto
+
+ Auto
+
+
+
+ Группа1
+
+
+ Период
+ Items
+ Day
+ 0001-01-01T00:00:00
+ 0001-01-01T00:00:00
+
+
+ Подразделение
+ Hierarchy
+ None
+ 0001-01-01T00:00:00
+ 0001-01-01T00:00:00
+
+
+
+
+
+
+
+
+
+ ДанныеЧасть1
+
+
+
+ ВидРасчета
+
+
+ Сумма
+
+
+
+
+
+
+
+
diff --git a/tests/skills/cases/skd-decompile/snapshots/structure-nested-and-folder/decompiled.json b/tests/skills/cases/skd-decompile/snapshots/structure-nested-and-folder/decompiled.json
new file mode 100644
index 00000000..c98f2ed9
--- /dev/null
+++ b/tests/skills/cases/skd-decompile/snapshots/structure-nested-and-folder/decompiled.json
@@ -0,0 +1,80 @@
+{
+ "dataSets": [
+ {
+ "name": "DSОбъединение",
+ "items": [
+ {
+ "name": "Часть1",
+ "objectName": "ДанныеЧасть1"
+ },
+ {
+ "name": "Часть2",
+ "objectName": "ДанныеЧасть2"
+ }
+ ],
+ "fields": [
+ "Период: date",
+ "ВидРасчета: CatalogRef.ВидыРасчета",
+ "Сумма: decimal(15,2)",
+ "Подразделение: CatalogRef.Подразделения"
+ ]
+ }
+ ],
+ "settingsVariants": [
+ {
+ "name": "Основной",
+ "settings": {
+ "selection": [
+ "Период",
+ {
+ "field": "Сумма",
+ "title": "Итого"
+ },
+ {
+ "folder": "Группа итогов",
+ "items": [
+ "ВидРасчета",
+ {
+ "field": "Сумма",
+ "title": "Сумма с расшифровкой"
+ },
+ {
+ "folder": "Подгруппа",
+ "items": [
+ "Подразделение"
+ ]
+ }
+ ]
+ }
+ ],
+ "structure": [
+ {
+ "name": "Группа1",
+ "groupFields": [
+ {
+ "field": "Период",
+ "periodAdditionType": "Day"
+ },
+ {
+ "field": "Подразделение",
+ "groupType": "Hierarchy"
+ }
+ ],
+ "children": [
+ {
+ "type": "nestedObject",
+ "objectID": "ДанныеЧасть1",
+ "settings": {
+ "selection": [
+ "ВидРасчета",
+ "Сумма"
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/tests/skills/cases/skd-decompile/structure-nested-and-folder.json b/tests/skills/cases/skd-decompile/structure-nested-and-folder.json
new file mode 100644
index 00000000..a3da1cef
--- /dev/null
+++ b/tests/skills/cases/skd-decompile/structure-nested-and-folder.json
@@ -0,0 +1,65 @@
+{
+ "name": "Структура: nestedObject + selection с вложенными folder и field-with-title + groupItem object form",
+ "preRun": [
+ {
+ "script": "skd-compile/scripts/skd-compile",
+ "input": {
+ "dataSets": [
+ {
+ "name": "DSОбъединение",
+ "items": [
+ { "name": "Часть1", "objectName": "ДанныеЧасть1" },
+ { "name": "Часть2", "objectName": "ДанныеЧасть2" }
+ ],
+ "fields": [
+ "Период: date",
+ "ВидРасчета: CatalogRef.ВидыРасчета",
+ "Сумма: decimal(15,2)",
+ "Подразделение: CatalogRef.Подразделения"
+ ]
+ }
+ ],
+ "settingsVariants": [
+ {
+ "name": "Основной",
+ "settings": {
+ "selection": [
+ "Период",
+ { "field": "Сумма", "title": "Итого" },
+ {
+ "folder": "Группа итогов",
+ "items": [
+ "ВидРасчета",
+ { "field": "Сумма", "title": "Сумма с расшифровкой" },
+ {
+ "folder": "Подгруппа",
+ "items": ["Подразделение"]
+ }
+ ]
+ }
+ ],
+ "structure": [
+ {
+ "name": "Группа1",
+ "groupFields": [
+ { "field": "Период", "periodAdditionType": "Day" },
+ { "field": "Подразделение", "groupType": "Hierarchy" }
+ ],
+ "children": [
+ { "type": "nestedObject", "objectID": "ДанныеЧасть1", "settings": {
+ "selection": ["ВидРасчета", "Сумма"]
+ }}
+ ]
+ }
+ ]
+ }
+ }
+ ]
+ },
+ "args": { "-DefinitionFile": "{inputFile}", "-OutputPath": "Template.xml" },
+ "cwd": "{workDir}"
+ }
+ ],
+ "params": { "templatePath": "Template.xml" },
+ "outputPath": "decompiled.json"
+}