mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-06-15 10:24:57 +03:00
feat(skd-compile): dataParameters auto — копирование value всех типов (ЕРП-паттерн)
Раньше "auto" копировал только variant для StandardPeriod, остальные типы теряли значение по умолчанию. Теперь: - value задан (не-Custom для StandardPeriod) → value + use=true (implicit), правильный xsi:type: boolean/decimal/dateTime/string, DesignTimeValue для ссылочных типов. - value отсутствует или StandardPeriod=Custom → <use>false</use> + <value xsi:nil="true"/>. Соответствует тому, как 1С Designer и ЕРП-отчёты персистят SettingsParameterValue. Тест auto-data-parameters расширен покрытием decimal/string/ref/nil. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -142,7 +142,7 @@ Shorthand: `"Имя [Заголовок]: тип = значение @флаги"
|
||||
}
|
||||
```
|
||||
|
||||
В варианте настроек `"dataParameters": "auto"` автоматически генерирует записи для всех не-hidden параметров с `userSettingID`. Для `StandardPeriod` вариант периода наследуется из дефолта параметра (`Custom`, если не задан).
|
||||
В варианте настроек `"dataParameters": "auto"` автоматически генерирует записи для всех не-hidden параметров с `userSettingID`. Значения по умолчанию копируются из параметра с правильным xsi:type (boolean/decimal/date/string/DesignTimeValue для ссылочных, StandardPeriod — с наследованием variant). Параметры без дефолта или с `StandardPeriod=Custom` помечаются `<use>false</use>` и `<value xsi:nil="true"/>` (активируются пользователем).
|
||||
|
||||
### Фильтры — shorthand
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# skd-compile v1.16 — Compile 1C DCS from JSON
|
||||
# skd-compile v1.17 — Compile 1C DCS from JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[string]$DefinitionFile,
|
||||
@@ -1847,7 +1847,10 @@ function Emit-DataParameters {
|
||||
X "$indent`t`t<dcscor:parameter>$(Esc-Xml "$($dp.parameter)")</dcscor:parameter>"
|
||||
|
||||
# Value
|
||||
if ($null -ne $dp.value) {
|
||||
if ($dp.nilValue -eq $true) {
|
||||
X "$indent`t`t<dcscor:value xsi:nil=`"true`"/>"
|
||||
} elseif ($null -ne $dp.value) {
|
||||
$vtype = "$($dp.valueType)"
|
||||
if ($dp.value -is [PSCustomObject] -and $dp.value.variant) {
|
||||
# StandardPeriod (object form from JSON)
|
||||
X "$indent`t`t<dcscor:value xsi:type=`"v8:StandardPeriod`">"
|
||||
@@ -1862,11 +1865,17 @@ function Emit-DataParameters {
|
||||
X "$indent`t`t`t<v8:startDate>0001-01-01T00:00:00</v8:startDate>"
|
||||
X "$indent`t`t`t<v8:endDate>0001-01-01T00:00:00</v8:endDate>"
|
||||
X "$indent`t`t</dcscor:value>"
|
||||
} elseif ($dp.value -is [bool]) {
|
||||
} elseif ($vtype -eq 'boolean' -or $dp.value -is [bool]) {
|
||||
$bv = "$($dp.value)".ToLower()
|
||||
X "$indent`t`t<dcscor:value xsi:type=`"xs:boolean`">$(Esc-Xml $bv)</dcscor:value>"
|
||||
} elseif ("$($dp.value)" -match '^\d{4}-\d{2}-\d{2}T') {
|
||||
} elseif ($vtype -match '^date' -or "$($dp.value)" -match '^\d{4}-\d{2}-\d{2}T') {
|
||||
X "$indent`t`t<dcscor:value xsi:type=`"xs:dateTime`">$(Esc-Xml "$($dp.value)")</dcscor:value>"
|
||||
} elseif ($vtype -match '^decimal') {
|
||||
X "$indent`t`t<dcscor:value xsi:type=`"xs:decimal`">$(Esc-Xml "$($dp.value)")</dcscor:value>"
|
||||
} elseif ($vtype -match '^string') {
|
||||
X "$indent`t`t<dcscor:value xsi:type=`"xs:string`">$(Esc-Xml "$($dp.value)")</dcscor:value>"
|
||||
} elseif ("$($dp.value)" -match '^(ПланСчетов|Справочник|Перечисление|Документ|ПланВидовХарактеристик|ПланВидовРасчета|БизнесПроцесс|Задача|РегистрСведений|ПланОбмена)\.' -or "$($dp.value)" -match '^(ChartOfAccounts|Catalog|Enum|Document|ChartOfCharacteristicTypes|ChartOfCalculationTypes|BusinessProcess|Task|InformationRegister|ExchangePlan)\.') {
|
||||
X "$indent`t`t<dcscor:value xsi:type=`"dcscor:DesignTimeValue`">$(Esc-Xml "$($dp.value)")</dcscor:value>"
|
||||
} else {
|
||||
X "$indent`t`t<dcscor:value xsi:type=`"xs:string`">$(Esc-Xml "$($dp.value)")</dcscor:value>"
|
||||
}
|
||||
@@ -2162,31 +2171,45 @@ function Emit-SettingsVariants {
|
||||
|
||||
# DataParameters
|
||||
if ($s.dataParameters -eq 'auto') {
|
||||
# Auto-generate dataParameters for all non-hidden params
|
||||
# Auto-generate dataParameters for all non-hidden params.
|
||||
# Pattern follows 1C Designer / ERP persistence:
|
||||
# - value set (non-default) → emit value, use=true (implicit)
|
||||
# - value missing / Custom period → <use>false</use> + <value xsi:nil="true"/>
|
||||
$autoDP = @()
|
||||
foreach ($ap in $script:allParams) {
|
||||
if (-not $ap.hidden) {
|
||||
$dpItem = New-Object PSObject
|
||||
$dpItem | Add-Member -NotePropertyName "parameter" -NotePropertyValue $ap.name
|
||||
$dpItem | Add-Member -NotePropertyName "use" -NotePropertyValue $false
|
||||
$dpItem | Add-Member -NotePropertyName "userSettingID" -NotePropertyValue "auto"
|
||||
# For StandardPeriod emit <dcscor:value> with variant inherited from
|
||||
# the parameter default (Custom if none) — matches how 1C Designer
|
||||
# persists SettingsParameterValue for period parameters.
|
||||
if ($ap.type -eq 'StandardPeriod') {
|
||||
$variant = 'Custom'
|
||||
$av = $ap.value
|
||||
if ($null -ne $av) {
|
||||
if (($av -is [PSCustomObject] -or $av -is [hashtable]) -and $av.variant) {
|
||||
$variant = "$($av.variant)"
|
||||
} elseif ("$av") {
|
||||
$variant = "$av"
|
||||
}
|
||||
if ($ap.hidden) { continue }
|
||||
$dpItem = New-Object PSObject
|
||||
$dpItem | Add-Member -NotePropertyName "parameter" -NotePropertyValue $ap.name
|
||||
$dpItem | Add-Member -NotePropertyName "userSettingID" -NotePropertyValue "auto"
|
||||
|
||||
$hasMeaningfulValue = $false
|
||||
|
||||
if ($ap.type -eq 'StandardPeriod') {
|
||||
# Inherit variant; Custom is treated as "empty"
|
||||
$variant = 'Custom'
|
||||
$av = $ap.value
|
||||
if ($null -ne $av) {
|
||||
if (($av -is [PSCustomObject] -or $av -is [hashtable]) -and $av.variant) {
|
||||
$variant = "$($av.variant)"
|
||||
} elseif ("$av") {
|
||||
$variant = "$av"
|
||||
}
|
||||
$dpItem | Add-Member -NotePropertyName "value" -NotePropertyValue @{ variant = $variant }
|
||||
}
|
||||
$autoDP += $dpItem
|
||||
$dpItem | Add-Member -NotePropertyName "value" -NotePropertyValue @{ variant = $variant }
|
||||
if ($variant -ne 'Custom') { $hasMeaningfulValue = $true }
|
||||
} elseif ($null -ne $ap.value -and "$($ap.value)" -ne '') {
|
||||
$dpItem | Add-Member -NotePropertyName "value" -NotePropertyValue $ap.value
|
||||
$dpItem | Add-Member -NotePropertyName "valueType" -NotePropertyValue "$($ap.type)"
|
||||
$hasMeaningfulValue = $true
|
||||
} else {
|
||||
$dpItem | Add-Member -NotePropertyName "nilValue" -NotePropertyValue $true
|
||||
}
|
||||
|
||||
if (-not $hasMeaningfulValue) {
|
||||
$dpItem | Add-Member -NotePropertyName "use" -NotePropertyValue $false
|
||||
}
|
||||
|
||||
$autoDP += $dpItem
|
||||
}
|
||||
if ($autoDP.Count -gt 0) {
|
||||
Emit-DataParameters -items $autoDP -indent "`t`t`t"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# skd-compile v1.16 — Compile 1C DCS from JSON
|
||||
# skd-compile v1.17 — Compile 1C DCS from JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
import argparse
|
||||
import json
|
||||
@@ -1569,8 +1569,11 @@ def emit_data_parameters(lines, items, indent):
|
||||
lines.append(f'{indent}\t\t<dcscor:parameter>{esc_xml(str(dp["parameter"]))}</dcscor:parameter>')
|
||||
|
||||
# Value
|
||||
if dp.get('value') is not None:
|
||||
if dp.get('nilValue') is True:
|
||||
lines.append(f'{indent}\t\t<dcscor:value xsi:nil="true"/>')
|
||||
elif dp.get('value') is not None:
|
||||
val = dp['value']
|
||||
vtype = str(dp.get('valueType') or '')
|
||||
if isinstance(val, dict) and val.get('variant'):
|
||||
# StandardPeriod
|
||||
lines.append(f'{indent}\t\t<dcscor:value xsi:type="v8:StandardPeriod">')
|
||||
@@ -1578,11 +1581,17 @@ def emit_data_parameters(lines, items, indent):
|
||||
lines.append(f'{indent}\t\t\t<v8:startDate>0001-01-01T00:00:00</v8:startDate>')
|
||||
lines.append(f'{indent}\t\t\t<v8:endDate>0001-01-01T00:00:00</v8:endDate>')
|
||||
lines.append(f'{indent}\t\t</dcscor:value>')
|
||||
elif isinstance(val, bool):
|
||||
elif vtype == 'boolean' or isinstance(val, bool):
|
||||
bv = str(val).lower()
|
||||
lines.append(f'{indent}\t\t<dcscor:value xsi:type="xs:boolean">{esc_xml(bv)}</dcscor:value>')
|
||||
elif re.match(r'^\d{4}-\d{2}-\d{2}T', str(val)):
|
||||
elif re.match(r'^date', vtype) or re.match(r'^\d{4}-\d{2}-\d{2}T', str(val)):
|
||||
lines.append(f'{indent}\t\t<dcscor:value xsi:type="xs:dateTime">{esc_xml(str(val))}</dcscor:value>')
|
||||
elif re.match(r'^decimal', vtype):
|
||||
lines.append(f'{indent}\t\t<dcscor:value xsi:type="xs:decimal">{esc_xml(str(val))}</dcscor:value>')
|
||||
elif re.match(r'^string', vtype):
|
||||
lines.append(f'{indent}\t\t<dcscor:value xsi:type="xs:string">{esc_xml(str(val))}</dcscor:value>')
|
||||
elif re.match(r'^(\u041f\u043b\u0430\u043d\u0421\u0447\u0435\u0442\u043e\u0432|\u0421\u043f\u0440\u0430\u0432\u043e\u0447\u043d\u0438\u043a|\u041f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435|\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442|\u041f\u043b\u0430\u043d\u0412\u0438\u0434\u043e\u0432\u0425\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u0438\u0441\u0442\u0438\u043a|\u041f\u043b\u0430\u043d\u0412\u0438\u0434\u043e\u0432\u0420\u0430\u0441\u0447\u0435\u0442\u0430|\u0411\u0438\u0437\u043d\u0435\u0441\u041f\u0440\u043e\u0446\u0435\u0441\u0441|\u0417\u0430\u0434\u0430\u0447\u0430|\u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0421\u0432\u0435\u0434\u0435\u043d\u0438\u0439|\u041f\u043b\u0430\u043d\u041e\u0431\u043c\u0435\u043d\u0430)\.', str(val)) or re.match(r'^(ChartOfAccounts|Catalog|Enum|Document|ChartOfCharacteristicTypes|ChartOfCalculationTypes|BusinessProcess|Task|InformationRegister|ExchangePlan)\.', str(val)):
|
||||
lines.append(f'{indent}\t\t<dcscor:value xsi:type="dcscor:DesignTimeValue">{esc_xml(str(val))}</dcscor:value>')
|
||||
else:
|
||||
lines.append(f'{indent}\t\t<dcscor:value xsi:type="xs:string">{esc_xml(str(val))}</dcscor:value>')
|
||||
|
||||
@@ -1815,28 +1824,42 @@ def emit_settings_variants(lines, defn):
|
||||
|
||||
# DataParameters
|
||||
if s.get('dataParameters') == 'auto':
|
||||
# Auto-generate dataParameters for all non-hidden params
|
||||
# Auto-generate dataParameters for all non-hidden params.
|
||||
# Pattern follows 1C Designer / ERP persistence:
|
||||
# value set (non-default) → emit value, use=true (implicit)
|
||||
# value missing / Custom period → <use>false</use> + <value xsi:nil="true"/>
|
||||
auto_dp = []
|
||||
for ap in _all_params:
|
||||
if not ap['hidden']:
|
||||
item = {
|
||||
'parameter': ap['name'],
|
||||
'use': False,
|
||||
'userSettingID': 'auto',
|
||||
}
|
||||
# For StandardPeriod emit <dcscor:value> with variant inherited
|
||||
# from the parameter default (Custom if none) — matches how
|
||||
# 1C Designer persists SettingsParameterValue for period params.
|
||||
if ap.get('type') == 'StandardPeriod':
|
||||
variant = 'Custom'
|
||||
av = ap.get('value')
|
||||
if av is not None:
|
||||
if isinstance(av, dict) and av.get('variant'):
|
||||
variant = str(av['variant'])
|
||||
elif str(av):
|
||||
variant = str(av)
|
||||
item['value'] = {'variant': variant}
|
||||
auto_dp.append(item)
|
||||
if ap['hidden']:
|
||||
continue
|
||||
item = {
|
||||
'parameter': ap['name'],
|
||||
'userSettingID': 'auto',
|
||||
}
|
||||
has_meaningful_value = False
|
||||
|
||||
if ap.get('type') == 'StandardPeriod':
|
||||
variant = 'Custom'
|
||||
av = ap.get('value')
|
||||
if av is not None:
|
||||
if isinstance(av, dict) and av.get('variant'):
|
||||
variant = str(av['variant'])
|
||||
elif str(av):
|
||||
variant = str(av)
|
||||
item['value'] = {'variant': variant}
|
||||
if variant != 'Custom':
|
||||
has_meaningful_value = True
|
||||
elif ap.get('value') is not None and str(ap.get('value')) != '':
|
||||
item['value'] = ap['value']
|
||||
item['valueType'] = str(ap.get('type') or '')
|
||||
has_meaningful_value = True
|
||||
else:
|
||||
item['nilValue'] = True
|
||||
|
||||
if not has_meaningful_value:
|
||||
item['use'] = False
|
||||
|
||||
auto_dp.append(item)
|
||||
if auto_dp:
|
||||
emit_data_parameters(lines, auto_dp, '\t\t\t')
|
||||
elif s.get('dataParameters'):
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "dataParameters: auto — наследование variant для StandardPeriod",
|
||||
"name": "dataParameters: auto — наследование значений по всем типам",
|
||||
"params": { "outputPath": "Template.xml" },
|
||||
"input": {
|
||||
"dataSets": [{
|
||||
@@ -9,7 +9,12 @@
|
||||
"parameters": [
|
||||
"Период: СтандартныйПериод = LastMonth @autoDates",
|
||||
"ПериодБезДефолта: СтандартныйПериод",
|
||||
"Флаг: boolean = true"
|
||||
"Флаг: boolean = true",
|
||||
"Сумма: decimal(15,2) = 0",
|
||||
"Ставка: decimal(5,2) = 13.5",
|
||||
"Метка: string(50) = ТестовоеЗначение",
|
||||
"ПустаяСтрока: string(50)",
|
||||
"Валюта: СправочникСсылка.Валюты = Справочник.Валюты.EmptyRef"
|
||||
],
|
||||
"settingsVariants": [{
|
||||
"name": "Основной",
|
||||
|
||||
@@ -83,6 +83,58 @@
|
||||
</valueType>
|
||||
<value xsi:type="xs:boolean">true</value>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>Сумма</name>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>15</v8:Digits>
|
||||
<v8:FractionDigits>2</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
<value xsi:type="xs:decimal">0</value>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>Ставка</name>
|
||||
<valueType>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>5</v8:Digits>
|
||||
<v8:FractionDigits>2</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</valueType>
|
||||
<value xsi:type="xs:decimal">13.5</value>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>Метка</name>
|
||||
<valueType>
|
||||
<v8:Type>xs:string</v8:Type>
|
||||
<v8:StringQualifiers>
|
||||
<v8:Length>50</v8:Length>
|
||||
<v8:AllowedLength>Variable</v8:AllowedLength>
|
||||
</v8:StringQualifiers>
|
||||
</valueType>
|
||||
<value xsi:type="xs:string">ТестовоеЗначение</value>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>ПустаяСтрока</name>
|
||||
<valueType>
|
||||
<v8:Type>xs:string</v8:Type>
|
||||
<v8:StringQualifiers>
|
||||
<v8:Length>50</v8:Length>
|
||||
<v8:AllowedLength>Variable</v8:AllowedLength>
|
||||
</v8:StringQualifiers>
|
||||
</valueType>
|
||||
</parameter>
|
||||
<parameter>
|
||||
<name>Валюта</name>
|
||||
<valueType>
|
||||
<v8:Type xmlns:d5p1="http://v8.1c.ru/8.1/data/enterprise/current-config">d5p1:CatalogRef.Валюты</v8:Type>
|
||||
</valueType>
|
||||
<value xsi:type="dcscor:DesignTimeValue">Справочник.Валюты.EmptyRef</value>
|
||||
</parameter>
|
||||
<settingsVariant>
|
||||
<dcsset:name>Основной</dcsset:name>
|
||||
<dcsset:presentation xsi:type="v8:LocalStringType">
|
||||
@@ -94,7 +146,6 @@
|
||||
<dcsset:settings xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows">
|
||||
<dcsset:dataParameters>
|
||||
<dcscor:item xsi:type="dcsset:SettingsParameterValue">
|
||||
<dcscor:use>false</dcscor:use>
|
||||
<dcscor:parameter>Период</dcscor:parameter>
|
||||
<dcscor:value xsi:type="v8:StandardPeriod">
|
||||
<v8:variant xsi:type="v8:StandardPeriodVariant">LastMonth</v8:variant>
|
||||
@@ -114,10 +165,36 @@
|
||||
<dcsset:userSettingID>UUID-002</dcsset:userSettingID>
|
||||
</dcscor:item>
|
||||
<dcscor:item xsi:type="dcsset:SettingsParameterValue">
|
||||
<dcscor:use>false</dcscor:use>
|
||||
<dcscor:parameter>Флаг</dcscor:parameter>
|
||||
<dcscor:value xsi:type="xs:boolean">true</dcscor:value>
|
||||
<dcsset:userSettingID>UUID-003</dcsset:userSettingID>
|
||||
</dcscor:item>
|
||||
<dcscor:item xsi:type="dcsset:SettingsParameterValue">
|
||||
<dcscor:parameter>Сумма</dcscor:parameter>
|
||||
<dcscor:value xsi:type="xs:decimal">0</dcscor:value>
|
||||
<dcsset:userSettingID>UUID-004</dcsset:userSettingID>
|
||||
</dcscor:item>
|
||||
<dcscor:item xsi:type="dcsset:SettingsParameterValue">
|
||||
<dcscor:parameter>Ставка</dcscor:parameter>
|
||||
<dcscor:value xsi:type="xs:decimal">13.5</dcscor:value>
|
||||
<dcsset:userSettingID>UUID-005</dcsset:userSettingID>
|
||||
</dcscor:item>
|
||||
<dcscor:item xsi:type="dcsset:SettingsParameterValue">
|
||||
<dcscor:parameter>Метка</dcscor:parameter>
|
||||
<dcscor:value xsi:type="xs:string">ТестовоеЗначение</dcscor:value>
|
||||
<dcsset:userSettingID>UUID-006</dcsset:userSettingID>
|
||||
</dcscor:item>
|
||||
<dcscor:item xsi:type="dcsset:SettingsParameterValue">
|
||||
<dcscor:use>false</dcscor:use>
|
||||
<dcscor:parameter>ПустаяСтрока</dcscor:parameter>
|
||||
<dcscor:value xsi:nil="true"/>
|
||||
<dcsset:userSettingID>UUID-007</dcsset:userSettingID>
|
||||
</dcscor:item>
|
||||
<dcscor:item xsi:type="dcsset:SettingsParameterValue">
|
||||
<dcscor:parameter>Валюта</dcscor:parameter>
|
||||
<dcscor:value xsi:type="dcscor:DesignTimeValue">Справочник.Валюты.EmptyRef</dcscor:value>
|
||||
<dcsset:userSettingID>UUID-008</dcsset:userSettingID>
|
||||
</dcscor:item>
|
||||
</dcsset:dataParameters>
|
||||
<dcsset:item xsi:type="dcsset:StructureItemGroup">
|
||||
<dcsset:order>
|
||||
|
||||
Reference in New Issue
Block a user