feat(skd-compile): availableValues на DataSet fields

Раньше availableValues эмитились только для parameters. Реальные
отчёты также задают availableValues на полях dataSet (например
ТипЗаписи=1..5 со ссылочными значениями), что давало отсутствие
важной семантики при roundtrip.

DSL: `field.availableValues: [{value, presentation, valueType?}]` —
типы значений автоопределяются (bool/decimal/dateTime/string),
presentation поддерживает multilang.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-05-22 17:25:08 +03:00
parent 2235b11700
commit b58f9aa6a2
2 changed files with 51 additions and 2 deletions
@@ -1,4 +1,4 @@
# skd-compile v1.40 — Compile 1C DCS from JSON
# skd-compile v1.41 — Compile 1C DCS from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[string]$DefinitionFile,
@@ -853,6 +853,10 @@ function Emit-Field {
if ($fieldDef.attrRestrict) {
$f["attrRestrict"] = @($fieldDef.attrRestrict)
}
# availableValues — array of {value, presentation}
if ($fieldDef.availableValues) {
$f["availableValues"] = $fieldDef.availableValues
}
# orderExpression — {expression, orderType, autoOrder}
if ($fieldDef.orderExpression) {
$f["orderExpression"] = $fieldDef.orderExpression
@@ -956,6 +960,27 @@ function Emit-Field {
X "$indent`t</valueType>"
}
# AvailableValues — list of allowed values with optional multilang presentation
if ($f["availableValues"]) {
foreach ($av in $f["availableValues"]) {
X "$indent`t<availableValue>"
$avVal = $av.value
$avType = if ($av.valueType) { "$($av.valueType)" } else { '' }
if (-not $avType) {
if ($avVal -is [bool]) { $avType = 'xs:boolean' }
elseif ($avVal -is [int] -or $avVal -is [long] -or $avVal -is [double]) { $avType = 'xs:decimal' }
elseif ("$avVal" -match '^\d{4}-\d{2}-\d{2}T') { $avType = 'xs:dateTime' }
else { $avType = 'xs:string' }
}
$avStr = if ($avVal -is [bool]) { "$avVal".ToLower() } else { Esc-Xml "$avVal" }
X "$indent`t`t<value xsi:type=`"$avType`">$avStr</value>"
if ($av.presentation) {
Emit-MLText -tag "presentation" -text $av.presentation -indent "$indent`t`t"
}
X "$indent`t</availableValue>"
}
}
# Appearance
if ($f.appearance -and $f.appearance.Count -gt 0) {
X "$indent`t<appearance>"
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# skd-compile v1.40 — Compile 1C DCS from JSON
# skd-compile v1.41 — Compile 1C DCS from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
import json
@@ -646,6 +646,9 @@ def emit_field(lines, field_def, indent):
# attrRestrict
if field_def.get('attrRestrict'):
f['attrRestrict'] = list(field_def['attrRestrict'])
# availableValues — array of {value, presentation}
if field_def.get('availableValues'):
f['availableValues'] = field_def['availableValues']
# orderExpression — {expression, orderType, autoOrder}
if field_def.get('orderExpression'):
f['orderExpression'] = field_def['orderExpression']
@@ -732,6 +735,27 @@ def emit_field(lines, field_def, indent):
emit_value_type(lines, f['type'], f'{indent}\t\t')
lines.append(f'{indent}\t</valueType>')
# AvailableValues — list of allowed values with optional multilang presentation
if f.get('availableValues'):
for av in f['availableValues']:
lines.append(f'{indent}\t<availableValue>')
av_val = av.get('value')
av_type = str(av.get('valueType', '')) if av.get('valueType') else ''
if not av_type:
if isinstance(av_val, bool):
av_type = 'xs:boolean'
elif isinstance(av_val, (int, float)):
av_type = 'xs:decimal'
elif re.match(r'^\d{4}-\d{2}-\d{2}T', str(av_val)):
av_type = 'xs:dateTime'
else:
av_type = 'xs:string'
av_str = str(av_val).lower() if isinstance(av_val, bool) else esc_xml(str(av_val))
lines.append(f'{indent}\t\t<value xsi:type="{av_type}">{av_str}</value>')
if av.get('presentation'):
emit_mltext(lines, f'{indent}\t\t', 'presentation', av['presentation'])
lines.append(f'{indent}\t</availableValue>')
# Appearance
if f.get('appearance') and len(f['appearance']) > 0:
lines.append(f'{indent}\t<appearance>')