mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-07-13 22:35:16 +03:00
feat(meta-edit): структурное свойство ChoiceParameters + фикс namespace app (Фаза 2 Шаг 3b-2a, v1.16)
modify-attribute/-dimension/-resource: ChoiceParameters ([{name, type?, value?}]) —
порт Emit-ChoiceParameters + полный кластер fill-ref машинерии в meta-edit
(fillRefRoots/fillRefKindRoot/fillEmptyRefWords/accountTypeValues, Normalize-FillRef,
Normalize-ChoiceValue/T, Expand-ChoiceRefValue, ConvertFrom-ChParamShorthand,
ConvertTo-ChScalar, Format-FillNum). Значение → app:value с xsi:type (bool/decimal/
DesignTimeRef); массив → v8:FixedArray/v8:Value; type разворачивает голые ref-имена
(EnumRef.X + "Оптовая" → Enum.X.EnumValue.Оптовая).
КРИТИЧНО: Import-Fragment (ps1+py) теперь объявляет xmlns:app + xmlns:ent — иначе
app:item/app:value падали бы "undeclared prefix". app/ent объявлены в корне 1С-файлов
→ вставка без per-element xmlns.
Cert декомпиляцией: выход meta-edit БАЙТ-В-БАЙТ = meta-compile (ps1 и py; включая
v8:FixedArray и DesignTimeRef-разворот). verify-snapshots --case modify-attribute-structural
(расширен ChoiceParameters bool+EmptyRef) грузится в 1С. meta-edit 14/14 ps1+py.
Остаток Шага 3: fillValue явный (нужна экстракция типа реквизита из XML).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# meta-edit v1.15 — Edit existing 1C metadata object XML (+structural attr props Format/EditFormat/ToolTip/ChoiceForm/MinValue/MaxValue/LinkByType/ChoiceParameterLinks)
|
||||
# meta-edit v1.16 — Edit existing 1C metadata object XML (+structural attr props Format/EditFormat/ToolTip/ChoiceForm/MinValue/MaxValue/LinkByType/ChoiceParameterLinks/ChoiceParameters)
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[string]$DefinitionFile,
|
||||
@@ -607,6 +607,8 @@ function Import-Fragment([string]$xmlString) {
|
||||
xmlns:v8="http://v8.1c.ru/8.1/data/core"
|
||||
xmlns:xr="http://v8.1c.ru/8.3/xcf/readable"
|
||||
xmlns:cfg="http://v8.1c.ru/8.1/data/enterprise/current-config"
|
||||
xmlns:app="http://v8.1c.ru/8.2/managed-application/core"
|
||||
xmlns:ent="http://v8.1c.ru/8.1/data/enterprise"
|
||||
xmlns:xs="http://www.w3.org/2001/XMLSchema">$xmlString</_W>
|
||||
"@
|
||||
$frag = New-Object System.Xml.XmlDocument
|
||||
@@ -2280,6 +2282,11 @@ function Modify-ChildElements($modifyDef, [string]$childType) {
|
||||
Info "Set $xmlTag '$elemName'.ChoiceParameterLinks"; $script:modifyCount++
|
||||
}
|
||||
}
|
||||
"ChoiceParameters" {
|
||||
if (Set-AttrPropertyElement $propsEl "ChoiceParameters" (Build-ChoiceParametersXml (Get-ChildIndent $propsEl) $changeValue)) {
|
||||
Info "Set $xmlTag '$elemName'.ChoiceParameters"; $script:modifyCount++
|
||||
}
|
||||
}
|
||||
default {
|
||||
# Scalar property change (Indexing, FillChecking, Use, etc.)
|
||||
$scalarEl = $null
|
||||
@@ -2544,6 +2551,153 @@ function Build-ChoiceParameterLinksXml([string]$indent, $cpl) {
|
||||
return $sb.ToString()
|
||||
}
|
||||
|
||||
# --- Порт из meta-compile: значения параметров выбора (ChoiceParameters) ---
|
||||
|
||||
$script:fillRefRoots = @{
|
||||
'перечисление'='Enum'; 'справочник'='Catalog'; 'документ'='Document';
|
||||
'плансчетов'='ChartOfAccounts'; 'планвидовхарактеристик'='ChartOfCharacteristicTypes';
|
||||
'планвидоврасчета'='ChartOfCalculationTypes'; 'планвидоврасчёта'='ChartOfCalculationTypes';
|
||||
'планобмена'='ExchangePlan'; 'бизнеспроцесс'='BusinessProcess'; 'задача'='Task';
|
||||
'enum'='Enum'; 'catalog'='Catalog'; 'document'='Document'; 'chartofaccounts'='ChartOfAccounts';
|
||||
'chartofcharacteristictypes'='ChartOfCharacteristicTypes'; 'chartofcalculationtypes'='ChartOfCalculationTypes';
|
||||
'exchangeplan'='ExchangePlan'; 'businessprocess'='BusinessProcess'; 'task'='Task'
|
||||
}
|
||||
$script:fillEmptyRefWords = @('emptyref','пустаяссылка')
|
||||
$script:fillEnumValWords = @('enumvalue','значениеперечисления')
|
||||
$script:accountTypeValues = @('Active','Passive','ActivePassive')
|
||||
$script:fillRefKindRoot = @{
|
||||
'catalogref'='Catalog'; 'documentref'='Document'; 'enumref'='Enum';
|
||||
'chartofaccountsref'='ChartOfAccounts'; 'chartofcharacteristictypesref'='ChartOfCharacteristicTypes';
|
||||
'chartofcalculationtypesref'='ChartOfCalculationTypes'; 'exchangeplanref'='ExchangePlan';
|
||||
'businessprocessref'='BusinessProcess'; 'taskref'='Task'
|
||||
}
|
||||
|
||||
function ConvertTo-ChScalar([string]$s) {
|
||||
$t = "$s".Trim()
|
||||
if ($t -match '^(?i:true|истина)$') { return $true }
|
||||
if ($t -match '^(?i:false|ложь)$') { return $false }
|
||||
if ($t -match '^-?\d+$') { return [int]$t }
|
||||
if ($t -match '^-?\d+\.\d+$') { return [double]::Parse($t, [System.Globalization.CultureInfo]::InvariantCulture) }
|
||||
return $t
|
||||
}
|
||||
|
||||
function Format-FillNum($n) {
|
||||
if ($n -is [double] -or $n -is [decimal]) { return $n.ToString([System.Globalization.CultureInfo]::InvariantCulture) }
|
||||
return "$n"
|
||||
}
|
||||
|
||||
function Normalize-FillRef([string]$s) {
|
||||
if ([string]::IsNullOrEmpty($s)) { return $null }
|
||||
if ($s -match '^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\.[0-9a-fA-F-]+$') { return $s }
|
||||
$parts = $s -split '\.'
|
||||
if ($parts.Count -lt 2) { return $null }
|
||||
$root = $script:fillRefRoots[$parts[0].ToLower()]
|
||||
if (-not $root) { return $null }
|
||||
$typeName = $parts[1]
|
||||
if ($root -eq 'Enum') {
|
||||
if ($parts.Count -eq 2) { return $null }
|
||||
if ($parts.Count -eq 3) {
|
||||
if ($script:fillEmptyRefWords -contains $parts[2].ToLower()) { return "Enum.$typeName.EmptyRef" }
|
||||
return "Enum.$typeName.EnumValue.$($parts[2])"
|
||||
}
|
||||
$member = $parts[2]
|
||||
if ($script:fillEnumValWords -contains $member.ToLower()) { $rest = $parts[3..($parts.Count-1)] -join '.' }
|
||||
else { $rest = $parts[2..($parts.Count-1)] -join '.' }
|
||||
return "Enum.$typeName.EnumValue.$rest"
|
||||
}
|
||||
$tail = @($parts[1..($parts.Count-1)])
|
||||
for ($i = 0; $i -lt $tail.Count; $i++) {
|
||||
if ($script:fillEmptyRefWords -contains $tail[$i].ToLower()) { $tail[$i] = 'EmptyRef' }
|
||||
}
|
||||
return "$root." + ($tail -join '.')
|
||||
}
|
||||
|
||||
function Expand-ChoiceRefValue([string]$value, [string]$typeStr) {
|
||||
if (-not $typeStr) { return $null }
|
||||
$t = Resolve-TypeStr $typeStr
|
||||
$root = $null; $tn = $null
|
||||
if ($t -match '^(\w+Ref)\.(.+)$') { $root = $script:fillRefKindRoot[$Matches[1].ToLower()]; $tn = $Matches[2] }
|
||||
elseif ($t -match '^([^.]+)\.(.+)$') { $root = $script:fillRefRoots[$Matches[1].ToLower()]; $tn = $Matches[2] }
|
||||
if (-not $root) { return $null }
|
||||
if ($script:fillEmptyRefWords -contains "$value".ToLower()) { return "$root.$tn.EmptyRef" }
|
||||
if ($root -eq 'Enum') { return "Enum.$tn.EnumValue.$value" }
|
||||
return "$root.$tn.$value"
|
||||
}
|
||||
|
||||
function Normalize-ChoiceValue($value) {
|
||||
if ($value -is [bool]) { return @{ XsiType='xs:boolean'; Text=$(if ($value) { 'true' } else { 'false' }) } }
|
||||
if ($value -is [int] -or $value -is [long] -or $value -is [double] -or $value -is [decimal]) {
|
||||
return @{ XsiType='xs:decimal'; Text=(Format-FillNum $value) }
|
||||
}
|
||||
$s = "$value"
|
||||
if ($s -eq '') { return @{ XsiType='xs:string'; Text='' } }
|
||||
if ($s -match '^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$') { return @{ XsiType='xs:dateTime'; Text=$s } }
|
||||
$ref = Normalize-FillRef $s
|
||||
if ($ref) { return @{ XsiType='xr:DesignTimeRef'; Text=$ref } }
|
||||
if ($script:accountTypeValues -contains $s) { return @{ XsiType='ent:AccountType'; Text=$s } }
|
||||
return @{ XsiType='xs:string'; Text=$s }
|
||||
}
|
||||
|
||||
function Normalize-ChoiceValueT($value, [string]$typeStr) {
|
||||
if ($typeStr -and ($value -is [string]) -and (-not "$value".Contains('.'))) {
|
||||
$ex = Expand-ChoiceRefValue "$value" $typeStr
|
||||
if ($ex) { return @{ XsiType='xr:DesignTimeRef'; Text=$ex } }
|
||||
}
|
||||
return Normalize-ChoiceValue $value
|
||||
}
|
||||
|
||||
function ConvertFrom-ChParamShorthand([string]$s) {
|
||||
$eq = $s.IndexOf('=')
|
||||
if ($eq -lt 0) { return @{ name = $s.Trim() } }
|
||||
$name = $s.Substring(0, $eq).Trim(); $rest = $s.Substring($eq + 1)
|
||||
if ($rest -match ',') {
|
||||
$vals = @(); foreach ($p in ($rest -split ',')) { $vals += ,(ConvertTo-ChScalar $p) }
|
||||
return @{ name = $name; value = $vals }
|
||||
}
|
||||
return @{ name = $name; value = (ConvertTo-ChScalar $rest) }
|
||||
}
|
||||
|
||||
# ChoiceParameters — [{name, type?, value?}] (порт Emit-ChoiceParameters). Значение на app:value (xsi:type=тип);
|
||||
# массив → v8:FixedArray с v8:Value; без value → nil. Требует xmlns:app в Import-Fragment.
|
||||
function Build-ChoiceParametersXml([string]$indent, $cp) {
|
||||
if (-not $cp -or @($cp).Count -eq 0) { return "$indent<ChoiceParameters/>" }
|
||||
$sb = New-Object System.Text.StringBuilder
|
||||
$sb.Append("$indent<ChoiceParameters>") | Out-Null
|
||||
foreach ($item in @($cp)) {
|
||||
if ($item -is [string]) { $item = ConvertFrom-ChParamShorthand $item }
|
||||
$name = Get-ChElProp $item @('name','имя')
|
||||
$ptype = Get-ChElProp $item @('type','тип')
|
||||
$hasVal = $false; $val = $null
|
||||
if ($item -is [System.Collections.IDictionary]) {
|
||||
if ($item.Contains('value')) { $hasVal = $true; $val = $item['value'] }
|
||||
elseif ($item.Contains('значение')) { $hasVal = $true; $val = $item['значение'] }
|
||||
} elseif ($item.PSObject) {
|
||||
if ($item.PSObject.Properties['value']) { $hasVal = $true; $val = $item.PSObject.Properties['value'].Value }
|
||||
elseif ($item.PSObject.Properties['значение']) { $hasVal = $true; $val = $item.PSObject.Properties['значение'].Value }
|
||||
}
|
||||
$valIsArray = ($val -is [System.Array]) -or ($val -is [System.Collections.IList] -and $val -isnot [string])
|
||||
$sb.Append("`r`n$indent`t<app:item name=`"$(Esc-Xml "$name")`">") | Out-Null
|
||||
if (-not $hasVal) {
|
||||
$sb.Append("`r`n$indent`t`t<app:value xsi:nil=`"true`"/>") | Out-Null
|
||||
} elseif ($valIsArray) {
|
||||
$sb.Append("`r`n$indent`t`t<app:value xsi:type=`"v8:FixedArray`">") | Out-Null
|
||||
foreach ($v in $val) {
|
||||
$norm = Normalize-ChoiceValueT $v $ptype
|
||||
if ([string]::IsNullOrEmpty($norm.Text)) { $sb.Append("`r`n$indent`t`t`t<v8:Value xsi:type=`"$($norm.XsiType)`"/>") | Out-Null }
|
||||
else { $sb.Append("`r`n$indent`t`t`t<v8:Value xsi:type=`"$($norm.XsiType)`">$(Esc-Xml $norm.Text)</v8:Value>") | Out-Null }
|
||||
}
|
||||
$sb.Append("`r`n$indent`t`t</app:value>") | Out-Null
|
||||
} else {
|
||||
$norm = Normalize-ChoiceValueT $val $ptype
|
||||
if ([string]::IsNullOrEmpty($norm.Text)) { $sb.Append("`r`n$indent`t`t<app:value xsi:type=`"$($norm.XsiType)`"/>") | Out-Null }
|
||||
else { $sb.Append("`r`n$indent`t`t<app:value xsi:type=`"$($norm.XsiType)`">$(Esc-Xml $norm.Text)</app:value>") | Out-Null }
|
||||
}
|
||||
$sb.Append("`r`n$indent`t</app:item>") | Out-Null
|
||||
}
|
||||
$sb.Append("`r`n$indent</ChoiceParameters>") | Out-Null
|
||||
return $sb.ToString()
|
||||
}
|
||||
|
||||
function Find-PropertyElement([string]$propName) {
|
||||
foreach ($child in $script:propertiesEl.ChildNodes) {
|
||||
if ($child.NodeType -eq 'Element' -and $child.LocalName -eq $propName) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# meta-edit v1.15 — Edit existing 1C metadata object XML (+structural attr props Format/EditFormat/ToolTip/ChoiceForm/MinValue/MaxValue/LinkByType/ChoiceParameterLinks)
|
||||
# meta-edit v1.16 — Edit existing 1C metadata object XML (+structural attr props Format/EditFormat/ToolTip/ChoiceForm/MinValue/MaxValue/LinkByType/ChoiceParameterLinks/ChoiceParameters)
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
|
||||
import argparse
|
||||
@@ -567,6 +567,8 @@ def import_fragment(xml_string):
|
||||
f' xmlns:v8="{V8_NS}"'
|
||||
f' xmlns:xr="{XR_NS}"'
|
||||
f' xmlns:cfg="{CFG_NS}"'
|
||||
f' xmlns:app="http://v8.1c.ru/8.2/managed-application/core"'
|
||||
f' xmlns:ent="http://v8.1c.ru/8.1/data/enterprise"'
|
||||
f' xmlns:xs="{XS_NS}">'
|
||||
f"{xml_string}</_W>"
|
||||
)
|
||||
@@ -2121,6 +2123,10 @@ def modify_child_elements(modify_def, child_type):
|
||||
if set_attr_property_element(props_el, "ChoiceParameterLinks", build_choice_parameter_links_xml(get_child_indent(props_el), change_value)):
|
||||
info(f"Set {xml_tag} '{elem_name}'.ChoiceParameterLinks")
|
||||
modify_count += 1
|
||||
elif change_prop == "ChoiceParameters":
|
||||
if set_attr_property_element(props_el, "ChoiceParameters", build_choice_parameters_xml(get_child_indent(props_el), change_value)):
|
||||
info(f"Set {xml_tag} '{elem_name}'.ChoiceParameters")
|
||||
modify_count += 1
|
||||
|
||||
else:
|
||||
# Scalar property change (Indexing, FillChecking, Use, etc.)
|
||||
@@ -2396,6 +2402,181 @@ def build_choice_parameter_links_xml(indent, cpl):
|
||||
return "\r\n".join(parts)
|
||||
|
||||
|
||||
# --- Порт из meta-compile: значения параметров выбора (ChoiceParameters) ---
|
||||
|
||||
fill_ref_roots = {
|
||||
'перечисление': 'Enum', 'справочник': 'Catalog', 'документ': 'Document',
|
||||
'плансчетов': 'ChartOfAccounts', 'планвидовхарактеристик': 'ChartOfCharacteristicTypes',
|
||||
'планвидоврасчета': 'ChartOfCalculationTypes', 'планвидоврасчёта': 'ChartOfCalculationTypes',
|
||||
'планобмена': 'ExchangePlan', 'бизнеспроцесс': 'BusinessProcess', 'задача': 'Task',
|
||||
'enum': 'Enum', 'catalog': 'Catalog', 'document': 'Document', 'chartofaccounts': 'ChartOfAccounts',
|
||||
'chartofcharacteristictypes': 'ChartOfCharacteristicTypes', 'chartofcalculationtypes': 'ChartOfCalculationTypes',
|
||||
'exchangeplan': 'ExchangePlan', 'businessprocess': 'BusinessProcess', 'task': 'Task',
|
||||
}
|
||||
fill_empty_ref_words = {'emptyref', 'пустаяссылка'}
|
||||
fill_enum_val_words = {'enumvalue', 'значениеперечисления'}
|
||||
account_type_values = ('Active', 'Passive', 'ActivePassive')
|
||||
fill_ref_kind_root = {
|
||||
'catalogref': 'Catalog', 'documentref': 'Document', 'enumref': 'Enum',
|
||||
'chartofaccountsref': 'ChartOfAccounts', 'chartofcharacteristictypesref': 'ChartOfCharacteristicTypes',
|
||||
'chartofcalculationtypesref': 'ChartOfCalculationTypes', 'exchangeplanref': 'ExchangePlan',
|
||||
'businessprocessref': 'BusinessProcess', 'taskref': 'Task',
|
||||
}
|
||||
|
||||
|
||||
def convert_to_ch_scalar(s):
|
||||
t = str(s).strip()
|
||||
if re.match(r'^(true|истина)$', t, re.IGNORECASE):
|
||||
return True
|
||||
if re.match(r'^(false|ложь)$', t, re.IGNORECASE):
|
||||
return False
|
||||
if re.match(r'^-?\d+$', t):
|
||||
return int(t)
|
||||
if re.match(r'^-?\d+\.\d+$', t):
|
||||
return float(t)
|
||||
return t
|
||||
|
||||
|
||||
def format_fill_num(n):
|
||||
if isinstance(n, float):
|
||||
return str(int(n)) if n == int(n) else repr(n)
|
||||
return str(n)
|
||||
|
||||
|
||||
def normalize_fill_ref(s):
|
||||
if not s:
|
||||
return None
|
||||
if re.match(r'^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\.[0-9a-fA-F-]+$', s):
|
||||
return s
|
||||
parts = s.split('.')
|
||||
if len(parts) < 2:
|
||||
return None
|
||||
root = fill_ref_roots.get(parts[0].lower())
|
||||
if not root:
|
||||
return None
|
||||
type_name = parts[1]
|
||||
if root == 'Enum':
|
||||
if len(parts) == 2:
|
||||
return None
|
||||
if len(parts) == 3:
|
||||
if parts[2].lower() in fill_empty_ref_words:
|
||||
return f"Enum.{type_name}.EmptyRef"
|
||||
return f"Enum.{type_name}.EnumValue.{parts[2]}"
|
||||
member = parts[2]
|
||||
rest = '.'.join(parts[3:]) if member.lower() in fill_enum_val_words else '.'.join(parts[2:])
|
||||
return f"Enum.{type_name}.EnumValue.{rest}"
|
||||
tail = list(parts[1:])
|
||||
for i in range(len(tail)):
|
||||
if tail[i].lower() in fill_empty_ref_words:
|
||||
tail[i] = 'EmptyRef'
|
||||
return f"{root}." + '.'.join(tail)
|
||||
|
||||
|
||||
def expand_choice_ref_value(value, type_str):
|
||||
if not type_str:
|
||||
return None
|
||||
t = resolve_type_str(type_str)
|
||||
root = None
|
||||
tn = None
|
||||
m = re.match(r'^(\w+Ref)\.(.+)$', t)
|
||||
if m:
|
||||
root = fill_ref_kind_root.get(m.group(1).lower())
|
||||
tn = m.group(2)
|
||||
else:
|
||||
m2 = re.match(r'^([^.]+)\.(.+)$', t)
|
||||
if m2:
|
||||
root = fill_ref_roots.get(m2.group(1).lower())
|
||||
tn = m2.group(2)
|
||||
if not root:
|
||||
return None
|
||||
if str(value).lower() in fill_empty_ref_words:
|
||||
return f"{root}.{tn}.EmptyRef"
|
||||
if root == 'Enum':
|
||||
return f"Enum.{tn}.EnumValue.{value}"
|
||||
return f"{root}.{tn}.{value}"
|
||||
|
||||
|
||||
def normalize_choice_value(value):
|
||||
if isinstance(value, bool):
|
||||
return {'XsiType': 'xs:boolean', 'Text': 'true' if value else 'false'}
|
||||
if isinstance(value, (int, float)):
|
||||
return {'XsiType': 'xs:decimal', 'Text': format_fill_num(value)}
|
||||
s = str(value)
|
||||
if s == '':
|
||||
return {'XsiType': 'xs:string', 'Text': ''}
|
||||
if re.match(r'^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$', s):
|
||||
return {'XsiType': 'xs:dateTime', 'Text': s}
|
||||
ref = normalize_fill_ref(s)
|
||||
if ref:
|
||||
return {'XsiType': 'xr:DesignTimeRef', 'Text': ref}
|
||||
if s in account_type_values:
|
||||
return {'XsiType': 'ent:AccountType', 'Text': s}
|
||||
return {'XsiType': 'xs:string', 'Text': s}
|
||||
|
||||
|
||||
def normalize_choice_value_t(value, type_str):
|
||||
if type_str and isinstance(value, str) and '.' not in str(value):
|
||||
ex = expand_choice_ref_value(value, type_str)
|
||||
if ex:
|
||||
return {'XsiType': 'xr:DesignTimeRef', 'Text': ex}
|
||||
return normalize_choice_value(value)
|
||||
|
||||
|
||||
def convert_from_ch_param_shorthand(s):
|
||||
eq = s.find('=')
|
||||
if eq < 0:
|
||||
return {'name': s.strip()}
|
||||
name = s[:eq].strip()
|
||||
rest = s[eq + 1:]
|
||||
if ',' in rest:
|
||||
return {'name': name, 'value': [convert_to_ch_scalar(p) for p in rest.split(',')]}
|
||||
return {'name': name, 'value': convert_to_ch_scalar(rest)}
|
||||
|
||||
|
||||
def build_choice_parameters_xml(indent, cp):
|
||||
"""ChoiceParameters — [{name, type?, value?}] (порт Emit-ChoiceParameters). Требует xmlns:app в import_fragment."""
|
||||
items = cp if isinstance(cp, list) else ([cp] if cp else [])
|
||||
if not items:
|
||||
return f"{indent}<ChoiceParameters/>"
|
||||
parts = [f"{indent}<ChoiceParameters>"]
|
||||
for item in items:
|
||||
if isinstance(item, str):
|
||||
item = convert_from_ch_param_shorthand(item)
|
||||
name = get_ch_el_prop(item, ['name', 'имя'])
|
||||
ptype = get_ch_el_prop(item, ['type', 'тип'])
|
||||
has_val = False
|
||||
val = None
|
||||
if isinstance(item, dict):
|
||||
if 'value' in item:
|
||||
has_val = True
|
||||
val = item['value']
|
||||
elif 'значение' in item:
|
||||
has_val = True
|
||||
val = item['значение']
|
||||
val_is_array = isinstance(val, list)
|
||||
parts.append(f'{indent}\t<app:item name="{esc_xml(str(name) if name is not None else "")}">')
|
||||
if not has_val:
|
||||
parts.append(f'{indent}\t\t<app:value xsi:nil="true"/>')
|
||||
elif val_is_array:
|
||||
parts.append(f'{indent}\t\t<app:value xsi:type="v8:FixedArray">')
|
||||
for v in val:
|
||||
norm = normalize_choice_value_t(v, ptype)
|
||||
if not norm['Text']:
|
||||
parts.append(f'{indent}\t\t\t<v8:Value xsi:type="{norm["XsiType"]}"/>')
|
||||
else:
|
||||
parts.append(f'{indent}\t\t\t<v8:Value xsi:type="{norm["XsiType"]}">{esc_xml(norm["Text"])}</v8:Value>')
|
||||
parts.append(f'{indent}\t\t</app:value>')
|
||||
else:
|
||||
norm = normalize_choice_value_t(val, ptype)
|
||||
if not norm['Text']:
|
||||
parts.append(f'{indent}\t\t<app:value xsi:type="{norm["XsiType"]}"/>')
|
||||
else:
|
||||
parts.append(f'{indent}\t\t<app:value xsi:type="{norm["XsiType"]}">{esc_xml(norm["Text"])}</app:value>')
|
||||
parts.append(f'{indent}\t</app:item>')
|
||||
parts.append(f"{indent}</ChoiceParameters>")
|
||||
return "\r\n".join(parts)
|
||||
|
||||
|
||||
def find_property_element(prop_name):
|
||||
for child in properties_el:
|
||||
if localname(child) == prop_name:
|
||||
|
||||
@@ -20,7 +20,11 @@
|
||||
"Контр": {
|
||||
"ChoiceForm": "Catalog.Спр.Form.ФормаВыбора",
|
||||
"ChoiceParameterLinks": ["Отбор.Владелец=Ссылка"],
|
||||
"LinkByType": { "dataPath": "Ссылка", "linkItem": 0 }
|
||||
"LinkByType": { "dataPath": "Ссылка", "linkItem": 0 },
|
||||
"ChoiceParameters": [
|
||||
{ "name": "Отбор.ПометкаУдаления", "value": false },
|
||||
{ "name": "Отбор.Ссылка", "value": "Catalog.Спр.EmptyRef" }
|
||||
]
|
||||
},
|
||||
"Сумма": { "MinValue": 0, "MaxValue": 1000000 }
|
||||
}
|
||||
|
||||
@@ -179,7 +179,14 @@
|
||||
<xr:ValueChange>Clear</xr:ValueChange>
|
||||
</xr:Link>
|
||||
</ChoiceParameterLinks>
|
||||
<ChoiceParameters />
|
||||
<ChoiceParameters>
|
||||
<app:item name="Отбор.ПометкаУдаления">
|
||||
<app:value xsi:type="xs:boolean">false</app:value>
|
||||
</app:item>
|
||||
<app:item name="Отбор.Ссылка">
|
||||
<app:value xsi:type="xr:DesignTimeRef">Catalog.Спр.EmptyRef</app:value>
|
||||
</app:item>
|
||||
</ChoiceParameters>
|
||||
<QuickChoice>Auto</QuickChoice>
|
||||
<CreateOnInput>Auto</CreateOnInput>
|
||||
<ChoiceForm>Catalog.Спр.Form.ФормаВыбора</ChoiceForm>
|
||||
|
||||
Reference in New Issue
Block a user