mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-07-13 22:35:16 +03:00
feat(meta-compile,meta-decompile): поддержка типа ChartOfCharacteristicTypes (ПВХ) (v1.35/v0.24)
Третий тип после Catalog/ExchangePlan. Декомпилятор расширен на ПВХ. Компилятор
Emit-ChartOfCharacteristicTypesProperties переписан на общие хелперы в каноническом
порядке; новое — блок Type (тип значения характеристики, составной) и
CharacteristicExtValues; иерархия папки+элементы. StandardAttributes-профиль ПВХ
(Наименование=ShowError, Родитель=FFV=true), блок условный.
Крупная новая фича — предопределённые виды несут ТИП НА ЭЛЕМЕНТ: ключ `type` в
объектной форме predefined (строка/массив; '' → пустой <Type/>). Root-элемент
PlanOfCharacteristicKindPredefinedItems.
Общие фиксы (не только ПВХ):
• Get-TypeShorthand ищет квалификаторы String/Number/Date по всему typeNode —
составной тип значения группирует квалификаторы в конце, не сразу за типом.
• Expand-DataPath гард [:/]: спец-путь 0:GUID/0:GUID (зависимости ПВХ) не разворачивается.
• Контекст реквизита ПВХ = catalog (у него полные Use/FillFromFillingValue/DataHistory).
• TabularSection Use, GeneratedType Characteristic-префикс, CodeSeries +WholeCharacteristicKind.
Роундтрип 24 ПВХ: match 0→16, TOTAL 4929→52 (−99%). Остаток (8) — принятые хвосты
(FillValue-пробелы, TS-LineNumber-опущение). Catalog/EP не регрессировали
(108/120, 39/42). Регресс 47/47 ps1+py, ps1↔py identical (6/6 ПВХ). spec §7.2b,
кейс chart-of-characteristic-types (+valueType/predefined-with-type/standardAttributes).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# meta-compile v1.34 — Compile 1C metadata object from JSON
|
||||
# meta-compile v1.35 — Compile 1C metadata object from JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -257,7 +257,7 @@ $script:validEnumValues = @{
|
||||
"FillChecking" = @("DontCheck","ShowError","ShowWarning")
|
||||
"Indexing" = @("DontIndex","Index","IndexWithAdditionalOrder")
|
||||
"SubordinationUse" = @("ToItems","ToFolders","ToFoldersAndItems")
|
||||
"CodeSeries" = @("WholeCatalog","WithinSubordination","WithinOwnerSubordination")
|
||||
"CodeSeries" = @("WholeCatalog","WithinSubordination","WithinOwnerSubordination","WholeCharacteristicKind")
|
||||
"ChoiceMode" = @("BothWays","QuickChoice","FromForm")
|
||||
"CreateOnInput" = @("Auto","Use","DontUse")
|
||||
"ChoiceHistoryOnInput" = @("Auto","DontUse")
|
||||
@@ -932,7 +932,7 @@ $script:generatedTypes = @{
|
||||
@{ prefix = "ChartOfCharacteristicTypesRef"; category = "Ref" }
|
||||
@{ prefix = "ChartOfCharacteristicTypesSelection"; category = "Selection" }
|
||||
@{ prefix = "ChartOfCharacteristicTypesList"; category = "List" }
|
||||
@{ prefix = "ChartOfCharacteristicTypesCharacteristic"; category = "Characteristic" }
|
||||
@{ prefix = "Characteristic"; category = "Characteristic" }
|
||||
@{ prefix = "ChartOfCharacteristicTypesManager"; category = "Manager" }
|
||||
)
|
||||
"ChartOfCalculationTypes" = @(
|
||||
@@ -1037,11 +1037,16 @@ $script:stdAttrProfile = @{
|
||||
"Parent" = @{ FillFromFillingValue = "true" }
|
||||
"Description" = @{ FillChecking = "ShowError" }
|
||||
}
|
||||
# ExchangePlan: блок материализуется всегда (не условный), Наименование/Код → FillChecking=ShowError (корпус 40/38 из 41).
|
||||
# ExchangePlan: Наименование/Код → FillChecking=ShowError (корпус 40/38 из 41).
|
||||
"ExchangePlan" = @{
|
||||
"Description" = @{ FillChecking = "ShowError" }
|
||||
"Code" = @{ FillChecking = "ShowError" }
|
||||
}
|
||||
# ChartOfCharacteristicTypes: Наименование → FillChecking=ShowError (21/23), Родитель → FFV=true (23/23).
|
||||
"ChartOfCharacteristicTypes" = @{
|
||||
"Description" = @{ FillChecking = "ShowError" }
|
||||
"Parent" = @{ FillFromFillingValue = "true" }
|
||||
}
|
||||
}
|
||||
|
||||
# $ov — hashtable переопределений (профиль + DSL) для полей: FillChecking, FillFromFillingValue,
|
||||
@@ -1102,7 +1107,7 @@ function Emit-StandardAttribute {
|
||||
# Прочие типы (не в множестве) → блок эмитится всегда (текущее поведение, пока их правило не выведено).
|
||||
# - stdAttrProfile[тип]: профиль материализованного блока (пусто = schema-дефолт), поверх — DSL-override.
|
||||
# Миграция типа = добавить его в stdAttrConditionalTypes + stdAttrProfile и переснять снэпшоты; КОД НЕ ТРОГАЕМ.
|
||||
$script:stdAttrConditionalTypes = @('Catalog', 'ExchangePlan')
|
||||
$script:stdAttrConditionalTypes = @('Catalog', 'ExchangePlan', 'ChartOfCharacteristicTypes')
|
||||
function Emit-StandardAttributes {
|
||||
param([string]$indent, [string]$objectType)
|
||||
$attrs = $script:standardAttributesByType[$objectType]
|
||||
@@ -1204,6 +1209,7 @@ function Expand-DataPath {
|
||||
param([string]$dp)
|
||||
if (-not $dp) { return $dp }
|
||||
$s = "$dp"
|
||||
if ($s -match '[:/]') { return $s } # спец-путь (напр. 0:GUID/0:GUID в зависимостях ПВХ) — не разворачиваем
|
||||
if ($s -match '^(StandardAttribute|Attribute)\.') { return "$objType.$objName.$s" }
|
||||
if (-not $s.Contains('.')) {
|
||||
$en = Resolve-StdAttrEn $s
|
||||
@@ -1710,8 +1716,8 @@ function Emit-TabularSection {
|
||||
Emit-MLText "$indent`t`t" "ToolTip" $tsTooltip
|
||||
X "$indent`t`t<FillChecking>DontCheck</FillChecking>"
|
||||
Emit-TabularStandardAttributes "$indent`t`t" $tsLineNumber
|
||||
# Use=ForItem only for Catalog tabular sections (Document does not have Use)
|
||||
if ($objectType -eq "Catalog") {
|
||||
# Use=ForItem у ТЧ иерархических ссылочных типов (Catalog, ChartOfCharacteristicTypes); Document не имеет Use.
|
||||
if ($objectType -in @("Catalog", "ChartOfCharacteristicTypes")) {
|
||||
X "$indent`t`t<Use>ForItem</Use>"
|
||||
}
|
||||
X "$indent`t</Properties>"
|
||||
@@ -2557,35 +2563,21 @@ function Emit-ChartOfCharacteristicTypesProperties {
|
||||
|
||||
X "$i<Name>$(Esc-Xml $objName)</Name>"
|
||||
Emit-MLText $i "Synonym" $synonym
|
||||
X "$i<Comment/>"
|
||||
X "$i<UseStandardCommands>true</UseStandardCommands>"
|
||||
if ($def.comment) { X "$i<Comment>$(Esc-XmlText "$($def.comment)")</Comment>" } else { X "$i<Comment/>" }
|
||||
$useStdCmd = if (Get-BoolProp "useStandardCommands" $true) { "true" } else { "false" }
|
||||
X "$i<UseStandardCommands>$useStdCmd</UseStandardCommands>"
|
||||
$inclHelp = if (Get-BoolProp "includeHelpInContents" $false) { "true" } else { "false" }
|
||||
X "$i<IncludeHelpInContents>$inclHelp</IncludeHelpInContents>"
|
||||
|
||||
$codeLength = if ($null -ne $def.codeLength) { "$($def.codeLength)" } else { "9" }
|
||||
$descriptionLength = if ($null -ne $def.descriptionLength) { "$($def.descriptionLength)" } else { "25" }
|
||||
$codeAllowedLength = Get-EnumProp "CodeAllowedLength" "codeAllowedLength" "Variable"
|
||||
$autonumbering = if ($def.autonumbering -eq $false) { "false" } else { "true" }
|
||||
$checkUnique = if ($def.checkUnique -eq $true) { "true" } else { "false" }
|
||||
|
||||
X "$i<CodeLength>$codeLength</CodeLength>"
|
||||
X "$i<CodeAllowedLength>$codeAllowedLength</CodeAllowedLength>"
|
||||
X "$i<DescriptionLength>$descriptionLength</DescriptionLength>"
|
||||
X "$i<CheckUnique>$checkUnique</CheckUnique>"
|
||||
X "$i<Autonumbering>$autonumbering</Autonumbering>"
|
||||
X "$i<DefaultPresentation>AsDescription</DefaultPresentation>"
|
||||
|
||||
# CharacteristicExtValues
|
||||
$charExtValues = if ($def.characteristicExtValues) { "$($def.characteristicExtValues)" } else { "" }
|
||||
if ($charExtValues) { X "$i<CharacteristicExtValues>$charExtValues</CharacteristicExtValues>" }
|
||||
# CharacteristicExtValues — ссылка на справочник доп. значений характеристик (обычно пусто).
|
||||
if ($def.characteristicExtValues) { X "$i<CharacteristicExtValues>$(Esc-Xml "$($def.characteristicExtValues)")</CharacteristicExtValues>" }
|
||||
else { X "$i<CharacteristicExtValues/>" }
|
||||
|
||||
# Type — composite type of allowed characteristic value types
|
||||
$valueTypes = @()
|
||||
if ($def.valueTypes) { $valueTypes = @($def.valueTypes) }
|
||||
if ($valueTypes.Count -gt 0) {
|
||||
# Type — тип значения характеристики (составной). DSL `valueType` строка "A + B + C" ИЛИ массив; нет ключа → дефолт.
|
||||
$vt = $def.valueType; if (-not $vt -and $def.valueTypes) { $vt = ($def.valueTypes -join ' + ') }
|
||||
if ($vt) {
|
||||
X "$i<Type>"
|
||||
foreach ($vt in $valueTypes) {
|
||||
Emit-TypeContent "$i`t" "$vt"
|
||||
}
|
||||
Emit-TypeContent "$i`t" "$vt"
|
||||
X "$i</Type>"
|
||||
} else {
|
||||
X "$i<Type>"
|
||||
@@ -2610,52 +2602,68 @@ function Emit-ChartOfCharacteristicTypesProperties {
|
||||
|
||||
$hierarchical = if ($def.hierarchical -eq $true) { "true" } else { "false" }
|
||||
X "$i<Hierarchical>$hierarchical</Hierarchical>"
|
||||
X "$i<FoldersOnTop>true</FoldersOnTop>"
|
||||
$foldersOnTop = if ($def.foldersOnTop -eq $false) { "false" } else { "true" }
|
||||
X "$i<FoldersOnTop>$foldersOnTop</FoldersOnTop>"
|
||||
|
||||
$codeLength = if ($null -ne $def.codeLength) { "$($def.codeLength)" } else { "9" }
|
||||
$descriptionLength = if ($null -ne $def.descriptionLength) { "$($def.descriptionLength)" } else { "100" }
|
||||
X "$i<CodeLength>$codeLength</CodeLength>"
|
||||
X "$i<CodeAllowedLength>$(Get-EnumProp 'CodeAllowedLength' 'codeAllowedLength' 'Variable')</CodeAllowedLength>"
|
||||
X "$i<DescriptionLength>$descriptionLength</DescriptionLength>"
|
||||
X "$i<CodeSeries>$(Get-EnumProp 'CodeSeries' 'codeSeries' 'WholeCharacteristicKind')</CodeSeries>"
|
||||
$checkUnique = if ($def.checkUnique -eq $false) { "false" } else { "true" }
|
||||
X "$i<CheckUnique>$checkUnique</CheckUnique>"
|
||||
$autonumbering = if ($def.autonumbering -eq $false) { "false" } else { "true" }
|
||||
X "$i<Autonumbering>$autonumbering</Autonumbering>"
|
||||
X "$i<DefaultPresentation>$(Get-EnumProp 'DefaultPresentation' 'defaultPresentation' 'AsDescription')</DefaultPresentation>"
|
||||
|
||||
Emit-StandardAttributes $i "ChartOfCharacteristicTypes"
|
||||
X "$i<Characteristics/>"
|
||||
X "$i<PredefinedDataUpdate>Auto</PredefinedDataUpdate>"
|
||||
X "$i<EditType>InDialog</EditType>"
|
||||
Emit-Characteristics $i $def.characteristics
|
||||
X "$i<PredefinedDataUpdate>$(Get-EnumProp 'PredefinedDataUpdate' 'predefinedDataUpdate' 'Auto')</PredefinedDataUpdate>"
|
||||
X "$i<EditType>$(Get-EnumProp 'EditType' 'editType' 'InDialog')</EditType>"
|
||||
$quickChoice = if ($def.quickChoice -eq $true) { "true" } else { "false" }
|
||||
X "$i<QuickChoice>$quickChoice</QuickChoice>"
|
||||
X "$i<ChoiceMode>BothWays</ChoiceMode>"
|
||||
X "$i<InputByString>"
|
||||
X "$i`t<xr:Field>ChartOfCharacteristicTypes.$objName.StandardAttribute.Description</xr:Field>"
|
||||
X "$i`t<xr:Field>ChartOfCharacteristicTypes.$objName.StandardAttribute.Code</xr:Field>"
|
||||
X "$i</InputByString>"
|
||||
X "$i<SearchStringModeOnInputByString>Begin</SearchStringModeOnInputByString>"
|
||||
X "$i<FullTextSearchOnInputByString>DontUse</FullTextSearchOnInputByString>"
|
||||
X "$i<ChoiceMode>$(Get-EnumProp 'ChoiceMode' 'choiceMode' 'BothWays')</ChoiceMode>"
|
||||
|
||||
# InputByString: override ЛИБО дефолт [Descr при D>0]+[Code при C>0] (prefix ChartOfCharacteristicTypes).
|
||||
if (Test-DefKey 'inputByString') {
|
||||
$ibFields = @($def.inputByString | ForEach-Object { Expand-DataPath "$_" })
|
||||
} else {
|
||||
$ibFields = @()
|
||||
if ([int]$descriptionLength -gt 0) { $ibFields += "ChartOfCharacteristicTypes.$objName.StandardAttribute.Description" }
|
||||
if ([int]$codeLength -gt 0) { $ibFields += "ChartOfCharacteristicTypes.$objName.StandardAttribute.Code" }
|
||||
}
|
||||
Emit-FieldBlock $i "InputByString" $ibFields
|
||||
X "$i<CreateOnInput>$(Get-EnumProp 'CreateOnInput' 'createOnInput' 'DontUse')</CreateOnInput>"
|
||||
X "$i<SearchStringModeOnInputByString>$(Get-EnumProp 'SearchStringModeOnInputByString' 'searchStringModeOnInputByString' 'Begin')</SearchStringModeOnInputByString>"
|
||||
X "$i<ChoiceDataGetModeOnInputByString>Directly</ChoiceDataGetModeOnInputByString>"
|
||||
X "$i<DefaultObjectForm/>"
|
||||
X "$i<DefaultFolderForm/>"
|
||||
X "$i<DefaultListForm/>"
|
||||
X "$i<DefaultChoiceForm/>"
|
||||
X "$i<DefaultFolderChoiceForm/>"
|
||||
X "$i<AuxiliaryObjectForm/>"
|
||||
X "$i<AuxiliaryFolderForm/>"
|
||||
X "$i<AuxiliaryListForm/>"
|
||||
X "$i<AuxiliaryChoiceForm/>"
|
||||
X "$i<AuxiliaryFolderChoiceForm/>"
|
||||
X "$i<IncludeHelpInContents>false</IncludeHelpInContents>"
|
||||
X "$i<BasedOn/>"
|
||||
X "$i<DataLockFields/>"
|
||||
|
||||
$dataLockControlMode = Get-EnumProp "DataLockControlMode" "dataLockControlMode" "Automatic"
|
||||
X "$i<DataLockControlMode>$dataLockControlMode</DataLockControlMode>"
|
||||
|
||||
$fullTextSearch = Get-EnumProp "FullTextSearch" "fullTextSearch" "Use"
|
||||
X "$i<FullTextSearch>$fullTextSearch</FullTextSearch>"
|
||||
|
||||
X "$i<FullTextSearchOnInputByString>DontUse</FullTextSearchOnInputByString>"
|
||||
X "$i<ChoiceHistoryOnInput>$(Get-EnumProp 'ChoiceHistoryOnInput' 'choiceHistoryOnInput' 'Auto')</ChoiceHistoryOnInput>"
|
||||
Emit-FormRef $i "DefaultObjectForm" $def.defaultObjectForm
|
||||
Emit-FormRef $i "DefaultFolderForm" $def.defaultFolderForm
|
||||
Emit-FormRef $i "DefaultListForm" $def.defaultListForm
|
||||
Emit-FormRef $i "DefaultChoiceForm" $def.defaultChoiceForm
|
||||
Emit-FormRef $i "DefaultFolderChoiceForm" $def.defaultFolderChoiceForm
|
||||
Emit-FormRef $i "AuxiliaryObjectForm" $def.auxiliaryObjectForm
|
||||
Emit-FormRef $i "AuxiliaryFolderForm" $def.auxiliaryFolderForm
|
||||
Emit-FormRef $i "AuxiliaryListForm" $def.auxiliaryListForm
|
||||
Emit-FormRef $i "AuxiliaryChoiceForm" $def.auxiliaryChoiceForm
|
||||
Emit-FormRef $i "AuxiliaryFolderChoiceForm" $def.auxiliaryFolderChoiceForm
|
||||
Emit-BasedOn $i $def.basedOn
|
||||
$dlFields = if (Test-DefKey 'dataLockFields') { @($def.dataLockFields | ForEach-Object { Expand-DataPath "$_" }) } else { @() }
|
||||
Emit-FieldBlock $i "DataLockFields" $dlFields
|
||||
X "$i<DataLockControlMode>$(Get-EnumProp 'DataLockControlMode' 'dataLockControlMode' 'Managed')</DataLockControlMode>"
|
||||
X "$i<FullTextSearch>$(Get-EnumProp 'FullTextSearch' 'fullTextSearch' 'Use')</FullTextSearch>"
|
||||
Emit-MLText $i "ObjectPresentation" $def.objectPresentation
|
||||
Emit-MLText $i "ExtendedObjectPresentation" $def.extendedObjectPresentation
|
||||
Emit-MLText $i "ListPresentation" $def.listPresentation
|
||||
Emit-MLText $i "ExtendedListPresentation" $def.extendedListPresentation
|
||||
Emit-MLText $i "Explanation" $def.explanation
|
||||
X "$i<CreateOnInput>DontUse</CreateOnInput>"
|
||||
X "$i<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>"
|
||||
X "$i<DataHistory>DontUse</DataHistory>"
|
||||
X "$i<UpdateDataHistoryImmediatelyAfterWrite>false</UpdateDataHistoryImmediatelyAfterWrite>"
|
||||
X "$i<ExecuteAfterWriteDataHistoryVersionProcessing>false</ExecuteAfterWriteDataHistoryVersionProcessing>"
|
||||
X "$i<DataHistory>$(Get-EnumProp 'DataHistory' 'dataHistory' 'DontUse')</DataHistory>"
|
||||
$updDH = if (Get-BoolProp "updateDataHistoryImmediatelyAfterWrite" $false) { "true" } else { "false" }
|
||||
X "$i<UpdateDataHistoryImmediatelyAfterWrite>$updDH</UpdateDataHistoryImmediatelyAfterWrite>"
|
||||
$execDH = if (Get-BoolProp "executeAfterWriteDataHistoryVersionProcessing" $false) { "true" } else { "false" }
|
||||
X "$i<ExecuteAfterWriteDataHistoryVersionProcessing>$execDH</ExecuteAfterWriteDataHistoryVersionProcessing>"
|
||||
}
|
||||
|
||||
function Emit-DocumentJournalProperties {
|
||||
@@ -3549,7 +3557,8 @@ if ($objType -in $typesWithAttrTS) {
|
||||
"Catalog" { "catalog" }
|
||||
"Document" { "document" }
|
||||
{ $_ -in @("DataProcessor","Report") } { "processor" }
|
||||
{ $_ -in @("ChartOfAccounts","ChartOfCharacteristicTypes","ChartOfCalculationTypes") } { "chart" }
|
||||
"ChartOfCharacteristicTypes" { "catalog" } # реквизиты ПВХ структурно как у справочника (Use/FillFromFillingValue/DataHistory)
|
||||
{ $_ -in @("ChartOfAccounts","ChartOfCalculationTypes") } { "chart" }
|
||||
default { "object" }
|
||||
}
|
||||
foreach ($a in $attrs) {
|
||||
@@ -3756,7 +3765,7 @@ function Resolve-PredefItem {
|
||||
$name = $m.Groups[2].Value
|
||||
$code = if ($m.Groups[1].Success) { $m.Groups[1].Value } else { '' }
|
||||
$desc = if ($m.Groups[3].Success) { $m.Groups[3].Value } else { Split-CamelCase $name }
|
||||
return @{ name = $name; code = $code; desc = $desc; isFolder = $false; children = @() }
|
||||
return @{ name = $name; code = $code; desc = $desc; isFolder = $false; children = @(); type = $null }
|
||||
}
|
||||
# Объектная форма + русские синонимы (прощающий ввод).
|
||||
$gv = { param($o, [string[]]$keys) foreach ($k in $keys) { if ($o.PSObject.Properties[$k]) { return $o.$k } } return $null }
|
||||
@@ -3769,7 +3778,9 @@ function Resolve-PredefItem {
|
||||
$folderV = & $gv $val @('isFolder','группа')
|
||||
$isFolder = ($folderV -eq $true)
|
||||
$subs = & $gv $val @('childItems','подчиненные')
|
||||
return @{ name = $name; code = $code; desc = $desc; isFolder = $isFolder; children = @(if ($subs) { $subs } else { @() }) }
|
||||
$typeV = & $gv $val @('type','тип') # тип значения характеристики (ПВХ): строка "A + B" ИЛИ массив
|
||||
if ($typeV -is [System.Array]) { $typeV = ($typeV -join ' + ') }
|
||||
return @{ name = $name; code = $code; desc = $desc; isFolder = $isFolder; children = @(if ($subs) { $subs } else { @() }); type = $typeV }
|
||||
}
|
||||
function Emit-PredefItem {
|
||||
param($sb, $val, [string]$indent, [string]$codeType)
|
||||
@@ -3781,6 +3792,18 @@ function Emit-PredefItem {
|
||||
else { [void]$sb.Append("$indent`t<Code>$(Esc-XmlText $r.code)</Code>`n") }
|
||||
if ($r.desc -eq '') { [void]$sb.Append("$indent`t<Description/>`n") }
|
||||
else { [void]$sb.Append("$indent`t<Description>$(Esc-XmlText $r.desc)</Description>`n") }
|
||||
# Type — тип значения предопределённой характеристики (ПВХ); между Description и IsFolder.
|
||||
# type=$null → блока нет (Catalog); type='' → пустой <Type/>; type='A + B' → наполненный.
|
||||
if ($null -ne $r.type -and "$($r.type)" -eq '') { [void]$sb.Append("$indent`t<Type/>`n") }
|
||||
elseif ($r.type) {
|
||||
[void]$sb.Append("$indent`t<Type>`n")
|
||||
$tmp = New-Object System.Text.StringBuilder
|
||||
$saveXml = $script:xml; $script:xml = $tmp
|
||||
Emit-TypeContent "$indent`t`t" "$($r.type)"
|
||||
$script:xml = $saveXml
|
||||
[void]$sb.Append(($tmp.ToString() -replace "`r`n", "`n"))
|
||||
[void]$sb.Append("$indent`t</Type>`n")
|
||||
}
|
||||
[void]$sb.Append("$indent`t<IsFolder>$(if ($r.isFolder) { 'true' } else { 'false' })</IsFolder>`n")
|
||||
if ($r.children.Count -gt 0) {
|
||||
[void]$sb.Append("$indent`t<ChildItems>`n")
|
||||
@@ -3897,11 +3920,12 @@ if ($objType -eq "BusinessProcess") {
|
||||
}
|
||||
}
|
||||
|
||||
# Предопределённые элементы (Ext/Predefined.xml) — пока Catalog. Пусто/нет ключа → файл не создаём.
|
||||
if ($objType -eq "Catalog" -and $def.predefined -and @($def.predefined).Count -gt 0) {
|
||||
# Предопределённые элементы (Ext/Predefined.xml). Root-элемент — по типу. Пусто/нет ключа → файл не создаём.
|
||||
$predefRootByType = @{ 'Catalog' = 'CatalogPredefinedItems'; 'ChartOfCharacteristicTypes' = 'PlanOfCharacteristicKindPredefinedItems' }
|
||||
if ($predefRootByType.ContainsKey($objType) -and $def.predefined -and @($def.predefined).Count -gt 0) {
|
||||
Ensure-ExtDir
|
||||
$catCodeType = if ($def.codeType) { "$($def.codeType)" } else { 'String' }
|
||||
$predefXml = Build-PredefinedXml @($def.predefined) "CatalogPredefinedItems" $catCodeType
|
||||
$predefXml = Build-PredefinedXml @($def.predefined) $predefRootByType[$objType] $catCodeType
|
||||
$predefPath = Join-Path $extDir "Predefined.xml"
|
||||
[System.IO.File]::WriteAllText($predefPath, $predefXml, $enc)
|
||||
$modulesCreated += $predefPath
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# meta-compile v1.34 — Compile 1C metadata object from JSON
|
||||
# meta-compile v1.35 — Compile 1C metadata object from JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
|
||||
import argparse
|
||||
@@ -374,7 +374,7 @@ valid_enum_values = {
|
||||
'FillChecking': ['DontCheck', 'ShowError', 'ShowWarning'],
|
||||
'Indexing': ['DontIndex', 'Index', 'IndexWithAdditionalOrder'],
|
||||
'SubordinationUse': ['ToItems', 'ToFolders', 'ToFoldersAndItems'],
|
||||
'CodeSeries': ['WholeCatalog', 'WithinSubordination', 'WithinOwnerSubordination'],
|
||||
'CodeSeries': ['WholeCatalog', 'WithinSubordination', 'WithinOwnerSubordination', 'WholeCharacteristicKind'],
|
||||
'ChoiceMode': ['BothWays', 'QuickChoice', 'FromForm'],
|
||||
'CreateOnInput': ['Auto', 'Use', 'DontUse'],
|
||||
'ChoiceHistoryOnInput': ['Auto', 'DontUse'],
|
||||
@@ -952,7 +952,7 @@ generated_types = {
|
||||
{'prefix': 'ChartOfCharacteristicTypesRef', 'category': 'Ref'},
|
||||
{'prefix': 'ChartOfCharacteristicTypesSelection', 'category': 'Selection'},
|
||||
{'prefix': 'ChartOfCharacteristicTypesList', 'category': 'List'},
|
||||
{'prefix': 'ChartOfCharacteristicTypesCharacteristic', 'category': 'Characteristic'},
|
||||
{'prefix': 'Characteristic', 'category': 'Characteristic'},
|
||||
{'prefix': 'ChartOfCharacteristicTypesManager', 'category': 'Manager'},
|
||||
],
|
||||
'ChartOfCalculationTypes': [
|
||||
@@ -1056,6 +1056,11 @@ std_attr_profile = {
|
||||
'Description': {'FillChecking': 'ShowError'},
|
||||
'Code': {'FillChecking': 'ShowError'},
|
||||
},
|
||||
# ChartOfCharacteristicTypes: Наименование → FillChecking=ShowError (21/23), Родитель → FFV=true (23/23).
|
||||
'ChartOfCharacteristicTypes': {
|
||||
'Description': {'FillChecking': 'ShowError'},
|
||||
'Parent': {'FillFromFillingValue': 'true'},
|
||||
},
|
||||
}
|
||||
|
||||
# ov — dict переопределений (профиль + DSL): FillChecking, FillFromFillingValue, Synonym,
|
||||
@@ -1121,7 +1126,7 @@ def emit_standard_attribute(indent, attr_name, ov=None):
|
||||
# Единый эмиттер блока StandardAttributes — поведение правят ДАННЫЕ, не форк кода (см. коммент в .ps1).
|
||||
# std_attr_conditional_types: типы, где блок только при кастомизации (DSL-ключ standardAttributes).
|
||||
# Прочие типы → блок всегда (текущее поведение). Миграция типа = +строчка в оба справочника + снэпшоты.
|
||||
std_attr_conditional_types = {'Catalog', 'ExchangePlan'}
|
||||
std_attr_conditional_types = {'Catalog', 'ExchangePlan', 'ChartOfCharacteristicTypes'}
|
||||
def emit_standard_attributes(indent, object_type):
|
||||
attrs = standard_attributes_by_type.get(object_type)
|
||||
if not attrs:
|
||||
@@ -1273,6 +1278,8 @@ def expand_data_path(dp):
|
||||
if not dp:
|
||||
return dp
|
||||
s = str(dp)
|
||||
if re.search(r'[:/]', s):
|
||||
return s # спец-путь (напр. 0:GUID/0:GUID в зависимостях ПВХ) — не разворачиваем
|
||||
if re.match(r'^(StandardAttribute|Attribute)\.', s):
|
||||
return f'{obj_type}.{obj_name}.{s}'
|
||||
if '.' not in s:
|
||||
@@ -1764,7 +1771,7 @@ def emit_tabular_section(indent, ts_name, columns, object_type, object_name, ts_
|
||||
emit_mltext(f'{indent}\t\t', 'ToolTip', ts_tooltip)
|
||||
X(f'{indent}\t\t<FillChecking>DontCheck</FillChecking>')
|
||||
emit_tabular_standard_attributes(f'{indent}\t\t', ts_line_number)
|
||||
if object_type == 'Catalog':
|
||||
if object_type in ('Catalog', 'ChartOfCharacteristicTypes'):
|
||||
X(f'{indent}\t\t<Use>ForItem</Use>')
|
||||
X(f'{indent}\t</Properties>')
|
||||
ts_context = 'processor-tabular' if object_type in ('DataProcessor', 'Report') else 'tabular'
|
||||
@@ -2476,29 +2483,22 @@ def emit_chart_of_characteristic_types_properties(indent):
|
||||
i = indent
|
||||
X(f'{i}<Name>{esc_xml(obj_name)}</Name>')
|
||||
emit_mltext(i, 'Synonym', synonym)
|
||||
X(f'{i}<Comment/>')
|
||||
X(f'{i}<UseStandardCommands>true</UseStandardCommands>')
|
||||
code_length = str(defn['codeLength']) if defn.get('codeLength') is not None else '9'
|
||||
description_length = str(defn['descriptionLength']) if defn.get('descriptionLength') is not None else '25'
|
||||
code_allowed_length = get_enum_prop('CodeAllowedLength', 'codeAllowedLength', 'Variable')
|
||||
autonumbering = 'false' if defn.get('autonumbering') is False else 'true'
|
||||
check_unique = 'true' if defn.get('checkUnique') is True else 'false'
|
||||
X(f'{i}<CodeLength>{code_length}</CodeLength>')
|
||||
X(f'{i}<CodeAllowedLength>{code_allowed_length}</CodeAllowedLength>')
|
||||
X(f'{i}<DescriptionLength>{description_length}</DescriptionLength>')
|
||||
X(f'{i}<CheckUnique>{check_unique}</CheckUnique>')
|
||||
X(f'{i}<Autonumbering>{autonumbering}</Autonumbering>')
|
||||
X(f'{i}<DefaultPresentation>AsDescription</DefaultPresentation>')
|
||||
char_ext_values = str(defn['characteristicExtValues']) if defn.get('characteristicExtValues') else ''
|
||||
if char_ext_values:
|
||||
X(f'{i}<CharacteristicExtValues>{char_ext_values}</CharacteristicExtValues>')
|
||||
if defn.get('comment'):
|
||||
X(f'{i}<Comment>{esc_xml_text(str(defn["comment"]))}</Comment>')
|
||||
else:
|
||||
X(f'{i}<Comment/>')
|
||||
X(f'{i}<UseStandardCommands>{"true" if get_bool_prop("useStandardCommands", True) else "false"}</UseStandardCommands>')
|
||||
X(f'{i}<IncludeHelpInContents>{"true" if get_bool_prop("includeHelpInContents", False) else "false"}</IncludeHelpInContents>')
|
||||
if defn.get('characteristicExtValues'):
|
||||
X(f'{i}<CharacteristicExtValues>{esc_xml(str(defn["characteristicExtValues"]))}</CharacteristicExtValues>')
|
||||
else:
|
||||
X(f'{i}<CharacteristicExtValues/>')
|
||||
value_types = list(defn.get('valueTypes', []))
|
||||
if value_types:
|
||||
vt = defn.get('valueType')
|
||||
if not vt and defn.get('valueTypes'):
|
||||
vt = ' + '.join(defn['valueTypes'])
|
||||
if vt:
|
||||
X(f'{i}<Type>')
|
||||
for vt in value_types:
|
||||
emit_type_content(f'{i}\t', str(vt))
|
||||
emit_type_content(f'{i}\t', str(vt))
|
||||
X(f'{i}</Type>')
|
||||
else:
|
||||
X(f'{i}<Type>')
|
||||
@@ -2519,50 +2519,60 @@ def emit_chart_of_characteristic_types_properties(indent):
|
||||
X(f'{i}\t\t<v8:DateFractions>DateTime</v8:DateFractions>')
|
||||
X(f'{i}\t</v8:DateQualifiers>')
|
||||
X(f'{i}</Type>')
|
||||
hierarchical = 'true' if defn.get('hierarchical') is True else 'false'
|
||||
X(f'{i}<Hierarchical>{hierarchical}</Hierarchical>')
|
||||
X(f'{i}<FoldersOnTop>true</FoldersOnTop>')
|
||||
X(f'{i}<Hierarchical>{"true" if defn.get("hierarchical") is True else "false"}</Hierarchical>')
|
||||
X(f'{i}<FoldersOnTop>{"false" if defn.get("foldersOnTop") is False else "true"}</FoldersOnTop>')
|
||||
code_length = str(defn['codeLength']) if defn.get('codeLength') is not None else '9'
|
||||
description_length = str(defn['descriptionLength']) if defn.get('descriptionLength') is not None else '100'
|
||||
X(f'{i}<CodeLength>{code_length}</CodeLength>')
|
||||
X(f'{i}<CodeAllowedLength>{get_enum_prop("CodeAllowedLength", "codeAllowedLength", "Variable")}</CodeAllowedLength>')
|
||||
X(f'{i}<DescriptionLength>{description_length}</DescriptionLength>')
|
||||
X(f'{i}<CodeSeries>{get_enum_prop("CodeSeries", "codeSeries", "WholeCharacteristicKind")}</CodeSeries>')
|
||||
X(f'{i}<CheckUnique>{"false" if defn.get("checkUnique") is False else "true"}</CheckUnique>')
|
||||
X(f'{i}<Autonumbering>{"false" if defn.get("autonumbering") is False else "true"}</Autonumbering>')
|
||||
X(f'{i}<DefaultPresentation>{get_enum_prop("DefaultPresentation", "defaultPresentation", "AsDescription")}</DefaultPresentation>')
|
||||
emit_standard_attributes(i, 'ChartOfCharacteristicTypes')
|
||||
X(f'{i}<Characteristics/>')
|
||||
X(f'{i}<PredefinedDataUpdate>Auto</PredefinedDataUpdate>')
|
||||
X(f'{i}<EditType>InDialog</EditType>')
|
||||
quick_choice = 'true' if defn.get('quickChoice') is True else 'false'
|
||||
X(f'{i}<QuickChoice>{quick_choice}</QuickChoice>')
|
||||
X(f'{i}<ChoiceMode>BothWays</ChoiceMode>')
|
||||
X(f'{i}<InputByString>')
|
||||
X(f'{i}\t<xr:Field>ChartOfCharacteristicTypes.{obj_name}.StandardAttribute.Description</xr:Field>')
|
||||
X(f'{i}\t<xr:Field>ChartOfCharacteristicTypes.{obj_name}.StandardAttribute.Code</xr:Field>')
|
||||
X(f'{i}</InputByString>')
|
||||
X(f'{i}<SearchStringModeOnInputByString>Begin</SearchStringModeOnInputByString>')
|
||||
X(f'{i}<FullTextSearchOnInputByString>DontUse</FullTextSearchOnInputByString>')
|
||||
emit_characteristics(i, defn.get('characteristics'))
|
||||
X(f'{i}<PredefinedDataUpdate>{get_enum_prop("PredefinedDataUpdate", "predefinedDataUpdate", "Auto")}</PredefinedDataUpdate>')
|
||||
X(f'{i}<EditType>{get_enum_prop("EditType", "editType", "InDialog")}</EditType>')
|
||||
X(f'{i}<QuickChoice>{"true" if defn.get("quickChoice") is True else "false"}</QuickChoice>')
|
||||
X(f'{i}<ChoiceMode>{get_enum_prop("ChoiceMode", "choiceMode", "BothWays")}</ChoiceMode>')
|
||||
if 'inputByString' in defn:
|
||||
ib_fields = [expand_data_path(str(x)) for x in (defn.get('inputByString') or [])]
|
||||
else:
|
||||
ib_fields = []
|
||||
if int(description_length) > 0:
|
||||
ib_fields.append(f'ChartOfCharacteristicTypes.{obj_name}.StandardAttribute.Description')
|
||||
if int(code_length) > 0:
|
||||
ib_fields.append(f'ChartOfCharacteristicTypes.{obj_name}.StandardAttribute.Code')
|
||||
emit_field_block(i, 'InputByString', ib_fields)
|
||||
X(f'{i}<CreateOnInput>{get_enum_prop("CreateOnInput", "createOnInput", "DontUse")}</CreateOnInput>')
|
||||
X(f'{i}<SearchStringModeOnInputByString>{get_enum_prop("SearchStringModeOnInputByString", "searchStringModeOnInputByString", "Begin")}</SearchStringModeOnInputByString>')
|
||||
X(f'{i}<ChoiceDataGetModeOnInputByString>Directly</ChoiceDataGetModeOnInputByString>')
|
||||
X(f'{i}<DefaultObjectForm/>')
|
||||
X(f'{i}<DefaultFolderForm/>')
|
||||
X(f'{i}<DefaultListForm/>')
|
||||
X(f'{i}<DefaultChoiceForm/>')
|
||||
X(f'{i}<DefaultFolderChoiceForm/>')
|
||||
X(f'{i}<AuxiliaryObjectForm/>')
|
||||
X(f'{i}<AuxiliaryFolderForm/>')
|
||||
X(f'{i}<AuxiliaryListForm/>')
|
||||
X(f'{i}<AuxiliaryChoiceForm/>')
|
||||
X(f'{i}<AuxiliaryFolderChoiceForm/>')
|
||||
X(f'{i}<IncludeHelpInContents>false</IncludeHelpInContents>')
|
||||
X(f'{i}<BasedOn/>')
|
||||
X(f'{i}<DataLockFields/>')
|
||||
data_lock_control_mode = get_enum_prop('DataLockControlMode', 'dataLockControlMode', 'Automatic')
|
||||
X(f'{i}<DataLockControlMode>{data_lock_control_mode}</DataLockControlMode>')
|
||||
full_text_search = get_enum_prop('FullTextSearch', 'fullTextSearch', 'Use')
|
||||
X(f'{i}<FullTextSearch>{full_text_search}</FullTextSearch>')
|
||||
X(f'{i}<FullTextSearchOnInputByString>DontUse</FullTextSearchOnInputByString>')
|
||||
X(f'{i}<ChoiceHistoryOnInput>{get_enum_prop("ChoiceHistoryOnInput", "choiceHistoryOnInput", "Auto")}</ChoiceHistoryOnInput>')
|
||||
emit_form_ref(i, 'DefaultObjectForm', defn.get('defaultObjectForm'))
|
||||
emit_form_ref(i, 'DefaultFolderForm', defn.get('defaultFolderForm'))
|
||||
emit_form_ref(i, 'DefaultListForm', defn.get('defaultListForm'))
|
||||
emit_form_ref(i, 'DefaultChoiceForm', defn.get('defaultChoiceForm'))
|
||||
emit_form_ref(i, 'DefaultFolderChoiceForm', defn.get('defaultFolderChoiceForm'))
|
||||
emit_form_ref(i, 'AuxiliaryObjectForm', defn.get('auxiliaryObjectForm'))
|
||||
emit_form_ref(i, 'AuxiliaryFolderForm', defn.get('auxiliaryFolderForm'))
|
||||
emit_form_ref(i, 'AuxiliaryListForm', defn.get('auxiliaryListForm'))
|
||||
emit_form_ref(i, 'AuxiliaryChoiceForm', defn.get('auxiliaryChoiceForm'))
|
||||
emit_form_ref(i, 'AuxiliaryFolderChoiceForm', defn.get('auxiliaryFolderChoiceForm'))
|
||||
emit_based_on(i, defn.get('basedOn'))
|
||||
dl_fields = [expand_data_path(str(x)) for x in defn.get('dataLockFields', [])] if 'dataLockFields' in defn else []
|
||||
emit_field_block(i, 'DataLockFields', dl_fields)
|
||||
X(f'{i}<DataLockControlMode>{get_enum_prop("DataLockControlMode", "dataLockControlMode", "Managed")}</DataLockControlMode>')
|
||||
X(f'{i}<FullTextSearch>{get_enum_prop("FullTextSearch", "fullTextSearch", "Use")}</FullTextSearch>')
|
||||
emit_mltext(i, 'ObjectPresentation', defn.get('objectPresentation'))
|
||||
emit_mltext(i, 'ExtendedObjectPresentation', defn.get('extendedObjectPresentation'))
|
||||
emit_mltext(i, 'ListPresentation', defn.get('listPresentation'))
|
||||
emit_mltext(i, 'ExtendedListPresentation', defn.get('extendedListPresentation'))
|
||||
emit_mltext(i, 'Explanation', defn.get('explanation'))
|
||||
X(f'{i}<CreateOnInput>DontUse</CreateOnInput>')
|
||||
X(f'{i}<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>')
|
||||
X(f'{i}<DataHistory>DontUse</DataHistory>')
|
||||
X(f'{i}<UpdateDataHistoryImmediatelyAfterWrite>false</UpdateDataHistoryImmediatelyAfterWrite>')
|
||||
X(f'{i}<ExecuteAfterWriteDataHistoryVersionProcessing>false</ExecuteAfterWriteDataHistoryVersionProcessing>')
|
||||
X(f'{i}<DataHistory>{get_enum_prop("DataHistory", "dataHistory", "DontUse")}</DataHistory>')
|
||||
X(f'{i}<UpdateDataHistoryImmediatelyAfterWrite>{"true" if get_bool_prop("updateDataHistoryImmediatelyAfterWrite", False) else "false"}</UpdateDataHistoryImmediatelyAfterWrite>')
|
||||
X(f'{i}<ExecuteAfterWriteDataHistoryVersionProcessing>{"true" if get_bool_prop("executeAfterWriteDataHistoryVersionProcessing", False) else "false"}</ExecuteAfterWriteDataHistoryVersionProcessing>')
|
||||
|
||||
def emit_document_journal_properties(indent):
|
||||
i = indent
|
||||
@@ -3343,7 +3353,9 @@ if obj_type in types_with_attr_ts:
|
||||
context = 'document'
|
||||
elif obj_type in ('DataProcessor', 'Report'):
|
||||
context = 'processor'
|
||||
elif obj_type in ('ChartOfAccounts', 'ChartOfCharacteristicTypes', 'ChartOfCalculationTypes'):
|
||||
elif obj_type == 'ChartOfCharacteristicTypes':
|
||||
context = 'catalog' # реквизиты ПВХ структурно как у справочника (Use/FillFromFillingValue/DataHistory)
|
||||
elif obj_type in ('ChartOfAccounts', 'ChartOfCalculationTypes'):
|
||||
context = 'chart'
|
||||
else:
|
||||
context = 'object'
|
||||
@@ -3575,7 +3587,7 @@ def resolve_predef_item(val):
|
||||
name = m.group(2)
|
||||
code = m.group(1) if m.group(1) is not None else ''
|
||||
desc = m.group(3) if m.group(3) is not None else split_camel_case(name)
|
||||
return {'name': name, 'code': code, 'desc': desc, 'isFolder': False, 'children': []}
|
||||
return {'name': name, 'code': code, 'desc': desc, 'isFolder': False, 'children': [], 'type': None}
|
||||
def gv(keys):
|
||||
for k in keys:
|
||||
if k in val:
|
||||
@@ -3589,7 +3601,10 @@ def resolve_predef_item(val):
|
||||
desc = ('' if desc_v is None else str(desc_v)) if has_desc else split_camel_case(name)
|
||||
is_folder = gv(['isFolder', 'группа']) is True
|
||||
subs = gv(['childItems', 'подчиненные']) or []
|
||||
return {'name': name, 'code': code, 'desc': desc, 'isFolder': is_folder, 'children': list(subs)}
|
||||
type_v = gv(['type', 'тип']) # тип значения характеристики (ПВХ): строка "A + B" ИЛИ массив
|
||||
if isinstance(type_v, list):
|
||||
type_v = ' + '.join(type_v)
|
||||
return {'name': name, 'code': code, 'desc': desc, 'isFolder': is_folder, 'children': list(subs), 'type': type_v}
|
||||
|
||||
def emit_predef_item(out, val, indent, code_type):
|
||||
r = resolve_predef_item(val)
|
||||
@@ -3605,6 +3620,19 @@ def emit_predef_item(out, val, indent, code_type):
|
||||
out.append(f'{indent}\t<Description/>')
|
||||
else:
|
||||
out.append(f'{indent}\t<Description>{esc_xml_text(r["desc"])}</Description>')
|
||||
# Type — тип значения предопределённой характеристики (ПВХ). None→нет блока; ''→<Type/>; 'A + B'→наполненный.
|
||||
rt = r.get('type')
|
||||
if rt is not None and str(rt) == '':
|
||||
out.append(f'{indent}\t<Type/>')
|
||||
elif rt:
|
||||
out.append(f'{indent}\t<Type>')
|
||||
global lines
|
||||
saved = lines
|
||||
lines = []
|
||||
emit_type_content(indent + '\t\t', str(rt))
|
||||
out.extend(lines)
|
||||
lines = saved
|
||||
out.append(f'{indent}\t</Type>')
|
||||
out.append(f'{indent}\t<IsFolder>{"true" if r["isFolder"] else "false"}</IsFolder>')
|
||||
if r['children']:
|
||||
out.append(f'{indent}\t<ChildItems>')
|
||||
@@ -3638,11 +3666,12 @@ if obj_type == 'BusinessProcess':
|
||||
write_utf8_bom(flowchart_path, flowchart_xml)
|
||||
modules_created.append(flowchart_path)
|
||||
|
||||
# Предопределённые элементы (Ext/Predefined.xml) — пока Catalog.
|
||||
if obj_type == 'Catalog' and defn.get('predefined'):
|
||||
# Предопределённые элементы (Ext/Predefined.xml). Root-элемент по типу.
|
||||
predef_root_by_type = {'Catalog': 'CatalogPredefinedItems', 'ChartOfCharacteristicTypes': 'PlanOfCharacteristicKindPredefinedItems'}
|
||||
if obj_type in predef_root_by_type and defn.get('predefined'):
|
||||
ensure_ext_dir()
|
||||
cat_code_type = str(defn['codeType']) if defn.get('codeType') else 'String'
|
||||
predef_xml = build_predefined_xml(defn['predefined'], 'CatalogPredefinedItems', cat_code_type)
|
||||
predef_xml = build_predefined_xml(defn['predefined'], predef_root_by_type[obj_type], cat_code_type)
|
||||
predef_path = os.path.join(ext_dir, 'Predefined.xml')
|
||||
write_utf8_bom(predef_path, predef_xml)
|
||||
modules_created.append(predef_path)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# meta-decompile v0.23 — XML объекта метаданных 1С → JSON-черновик формата meta-compile
|
||||
# meta-decompile v0.24 — XML объекта метаданных 1С → JSON-черновик формата meta-compile
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
#
|
||||
# Поддержаны: Catalog, ExchangePlan. Инверс meta-compile (omit-on-default: ключ эмитим только
|
||||
# Поддержаны: Catalog, ExchangePlan, ChartOfCharacteristicTypes. Инверс meta-compile (omit-on-default: ключ эмитим только
|
||||
# когда значение в XML отличается от умолчания компилятора). Неподдерживаемый тип / не-MetaDataObject
|
||||
# root → exit 3 (ring3, как form-decompile).
|
||||
param(
|
||||
@@ -91,8 +91,8 @@ foreach ($c in $rootEl.ChildNodes) { if ($c.NodeType -eq 'Element') { $objNode =
|
||||
if (-not $objNode) { [Console]::Error.WriteLine("meta-decompile: пустой MetaDataObject"); exit 3 }
|
||||
$objType = $objNode.LocalName
|
||||
|
||||
if ($objType -notin @('Catalog', 'ExchangePlan')) {
|
||||
[Console]::Error.WriteLine("meta-decompile: тип '$objType' пока не поддержан (Catalog, ExchangePlan)"); exit 3
|
||||
if ($objType -notin @('Catalog', 'ExchangePlan', 'ChartOfCharacteristicTypes')) {
|
||||
[Console]::Error.WriteLine("meta-decompile: тип '$objType' пока не поддержан (Catalog, ExchangePlan, ChartOfCharacteristicTypes)"); exit 3
|
||||
}
|
||||
|
||||
$props = $objNode.SelectSingleNode('md:Properties', $nsm)
|
||||
@@ -157,24 +157,27 @@ function Get-TypeShorthand {
|
||||
'(^|:)boolean$' { $parts += 'Boolean'; break }
|
||||
'(^|:)string$' {
|
||||
$len = '10'; $al = ''
|
||||
if ($next -and $next.LocalName -eq 'StringQualifiers') {
|
||||
$l = $next.SelectSingleNode('v8:Length', $nsm); if ($l) { $len = $l.InnerText }
|
||||
$aln = $next.SelectSingleNode('v8:AllowedLength', $nsm); if ($aln -and $aln.InnerText -eq 'Fixed') { $al = ',fixed' }
|
||||
$sq = if ($next -and $next.LocalName -eq 'StringQualifiers') { $next } else { $typeNode.SelectSingleNode('v8:StringQualifiers', $nsm) }
|
||||
if ($sq) {
|
||||
$l = $sq.SelectSingleNode('v8:Length', $nsm); if ($l) { $len = $l.InnerText }
|
||||
$aln = $sq.SelectSingleNode('v8:AllowedLength', $nsm); if ($aln -and $aln.InnerText -eq 'Fixed') { $al = ',fixed' }
|
||||
}
|
||||
$parts += "String($len$al)"; break
|
||||
}
|
||||
'(^|:)decimal$' {
|
||||
$d = '10'; $f = '0'; $sign = ''
|
||||
if ($next -and $next.LocalName -eq 'NumberQualifiers') {
|
||||
$dn = $next.SelectSingleNode('v8:Digits', $nsm); if ($dn) { $d = $dn.InnerText }
|
||||
$fn = $next.SelectSingleNode('v8:FractionDigits', $nsm); if ($fn) { $f = $fn.InnerText }
|
||||
$sn = $next.SelectSingleNode('v8:AllowedSign', $nsm); if ($sn -and $sn.InnerText -eq 'Nonnegative') { $sign = ',nonneg' }
|
||||
$nq = if ($next -and $next.LocalName -eq 'NumberQualifiers') { $next } else { $typeNode.SelectSingleNode('v8:NumberQualifiers', $nsm) }
|
||||
if ($nq) {
|
||||
$dn = $nq.SelectSingleNode('v8:Digits', $nsm); if ($dn) { $d = $dn.InnerText }
|
||||
$fn = $nq.SelectSingleNode('v8:FractionDigits', $nsm); if ($fn) { $f = $fn.InnerText }
|
||||
$sn = $nq.SelectSingleNode('v8:AllowedSign', $nsm); if ($sn -and $sn.InnerText -eq 'Nonnegative') { $sign = ',nonneg' }
|
||||
}
|
||||
$parts += "Number($d,$f$sign)"; break
|
||||
}
|
||||
'(^|:)dateTime$' {
|
||||
$fr = 'DateTime'
|
||||
if ($next -and $next.LocalName -eq 'DateQualifiers') { $dn = $next.SelectSingleNode('v8:DateFractions', $nsm); if ($dn) { $fr = $dn.InnerText } }
|
||||
$dq = if ($next -and $next.LocalName -eq 'DateQualifiers') { $next } else { $typeNode.SelectSingleNode('v8:DateQualifiers', $nsm) }
|
||||
if ($dq) { $dn = $dq.SelectSingleNode('v8:DateFractions', $nsm); if ($dn) { $fr = $dn.InnerText } }
|
||||
$parts += $fr; break # Date | DateTime
|
||||
}
|
||||
'(^|:)base64Binary$' { $parts += 'ValueStorage'; break }
|
||||
@@ -389,16 +392,18 @@ if ($ownersNode) {
|
||||
}
|
||||
Add-EnumProp 'subordinationUse' 'SubordinationUse' 'ToItems'
|
||||
# Тип-зависимые дефолты (компилятор задаёт их по типу — декомпилятор обязан зеркалить, иначе omit ≠ значению).
|
||||
$descrLenDef = if ($objType -eq 'ExchangePlan') { 150 } else { 25 }
|
||||
$createInpDef = if ($objType -eq 'ExchangePlan') { 'DontUse' } else { 'Use' }
|
||||
$dataLockDef = if ($objType -eq 'ExchangePlan') { 'Managed' } else { 'Automatic' }
|
||||
$descrLenDef = switch ($objType) { 'ExchangePlan' { 150 } 'ChartOfCharacteristicTypes' { 100 } default { 25 } }
|
||||
$createInpDef = if ($objType -eq 'Catalog') { 'Use' } else { 'DontUse' }
|
||||
$dataLockDef = if ($objType -eq 'Catalog') { 'Automatic' } else { 'Managed' }
|
||||
$codeSeriesDef = if ($objType -eq 'ChartOfCharacteristicTypes') { 'WholeCharacteristicKind' } else { 'WholeCatalog' }
|
||||
$checkUniqueDef = ($objType -eq 'ChartOfCharacteristicTypes') # ПВХ дефолт true, Catalog false
|
||||
Add-IntProp 'codeLength' 'CodeLength' 9
|
||||
Add-IntProp 'descriptionLength' 'DescriptionLength' $descrLenDef
|
||||
Add-EnumProp 'codeType' 'CodeType' 'String'
|
||||
Add-EnumProp 'codeAllowedLength' 'CodeAllowedLength' 'Variable'
|
||||
Add-BoolProp 'autonumbering' 'Autonumbering' $true
|
||||
Add-BoolProp 'checkUnique' 'CheckUnique' $false
|
||||
Add-EnumProp 'codeSeries' 'CodeSeries' 'WholeCatalog'
|
||||
Add-BoolProp 'checkUnique' 'CheckUnique' $checkUniqueDef
|
||||
Add-EnumProp 'codeSeries' 'CodeSeries' $codeSeriesDef
|
||||
Add-EnumProp 'defaultPresentation' 'DefaultPresentation' 'AsDescription'
|
||||
Add-BoolProp 'quickChoice' 'QuickChoice' $false
|
||||
Add-EnumProp 'choiceMode' 'ChoiceMode' 'BothWays'
|
||||
@@ -419,6 +424,19 @@ if ($objType -eq 'ExchangePlan') {
|
||||
Add-BoolProp 'updateDataHistoryImmediatelyAfterWrite' 'UpdateDataHistoryImmediatelyAfterWrite' $false
|
||||
Add-BoolProp 'executeAfterWriteDataHistoryVersionProcessing' 'ExecuteAfterWriteDataHistoryVersionProcessing' $false
|
||||
}
|
||||
# ChartOfCharacteristicTypes-специфичные свойства.
|
||||
if ($objType -eq 'ChartOfCharacteristicTypes') {
|
||||
Add-EnumProp 'dataHistory' 'DataHistory' 'DontUse'
|
||||
Add-BoolProp 'updateDataHistoryImmediatelyAfterWrite' 'UpdateDataHistoryImmediatelyAfterWrite' $false
|
||||
Add-BoolProp 'executeAfterWriteDataHistoryVersionProcessing' 'ExecuteAfterWriteDataHistoryVersionProcessing' $false
|
||||
$cev = P 'CharacteristicExtValues'; if ($cev) { $dsl['characteristicExtValues'] = $cev }
|
||||
# Type — тип значения характеристики; valueType при отличии от дефолта (Boolean+String(100)+Number(15,2)+DateTime).
|
||||
$vtNode = $props.SelectSingleNode('md:Type', $nsm)
|
||||
if ($vtNode) {
|
||||
$vtStr = Get-TypeShorthand $vtNode
|
||||
if ($vtStr -and $vtStr -ne 'Boolean + String(100) + Number(15,2) + DateTime') { $dsl['valueType'] = $vtStr }
|
||||
}
|
||||
}
|
||||
|
||||
# Короткая форма поля: <Type>.<Name>.StandardAttribute.X / .Attribute.X → StandardAttribute.X / Attribute.X
|
||||
# (Expand-DataPath компилятора разворачивает частичную форму обратно — dogfood резолвера).
|
||||
@@ -535,6 +553,10 @@ $stdProfileByType = @{
|
||||
'Description' = @{ fillChecking = 'ShowError' }
|
||||
'Code' = @{ fillChecking = 'ShowError' }
|
||||
}
|
||||
'ChartOfCharacteristicTypes' = @{
|
||||
'Description' = @{ fillChecking = 'ShowError' }
|
||||
'Parent' = @{ fillFromFillingValue = $true }
|
||||
}
|
||||
}
|
||||
$catStdProfile = if ($stdProfileByType.ContainsKey($objType)) { $stdProfileByType[$objType] } else { @{} }
|
||||
# Фикс-список стандартных реквизитов типа (зеркало standardAttributesByType компилятора) — чтобы отличать
|
||||
@@ -542,11 +564,12 @@ $catStdProfile = if ($stdProfileByType.ContainsKey($objType)) { $stdProfileByTyp
|
||||
$stdFixedByType = @{
|
||||
'Catalog' = @('PredefinedDataName','Predefined','Ref','DeletionMark','IsFolder','Owner','Parent','Description','Code')
|
||||
'ExchangePlan' = @('Ref','DeletionMark','Code','Description','ThisNode','SentNo','ReceivedNo')
|
||||
'ChartOfCharacteristicTypes' = @('PredefinedDataName','Predefined','Ref','DeletionMark','Description','Code','Parent','ValueType')
|
||||
}
|
||||
$stdFixed = if ($stdFixedByType.ContainsKey($objType)) { $stdFixedByType[$objType] } else { @() }
|
||||
# Условные типы: блок эмитим-как-триггер даже пустым (материализуется при отклонении ≥1 реквизита от schema-default;
|
||||
# у ExchangePlan это почти всегда — Description/Code=ShowError; редкий all-default EP блок опускает).
|
||||
$stdConditionalTypes = @('Catalog', 'ExchangePlan')
|
||||
$stdConditionalTypes = @('Catalog', 'ExchangePlan', 'ChartOfCharacteristicTypes')
|
||||
$saNode = $props.SelectSingleNode('md:StandardAttributes', $nsm)
|
||||
if ($saNode) {
|
||||
$saMap = [ordered]@{}
|
||||
@@ -703,20 +726,25 @@ if (Test-Path -LiteralPath $predefPath) {
|
||||
# ВАЖНО: обернуть весь if в @(), иначе PS распаковывает одноэлементный @(...) из if-блока
|
||||
# обратно в узел → $kids.Count = $null → папки с ОДНИМ ребёнком теряют его.
|
||||
$kids = @(if ($childContainer) { $childContainer.SelectNodes("*[local-name()='Item']") } else { @() })
|
||||
# Type — тип значения предопределённой характеристики (ПВХ). Наличие → object-форма (в строку не влезает).
|
||||
# Наличие узла <Type> (даже пустого <Type/>) → object-форма с ключом type ('' для пустого); нет узла (Catalog) → без.
|
||||
$typeEl = $itemEl.SelectSingleNode("*[local-name()='Type']")
|
||||
$typeStr = if ($typeEl) { Get-TypeShorthand $typeEl } else { $null }
|
||||
$auto = Split-CamelWords $name
|
||||
|
||||
if (-not $isFolder -and $kids.Count -eq 0) {
|
||||
# Плоский → компактная строка.
|
||||
if (-not $isFolder -and $kids.Count -eq 0 -and $null -eq $typeEl) {
|
||||
# Плоский без типа → компактная строка.
|
||||
$s = if ($code) { "($code) $name" } else { $name }
|
||||
if ($desc -eq '') { $s = "$s []" }
|
||||
elseif ($desc -ne $auto) { $s = "$s [$desc]" }
|
||||
return $s
|
||||
}
|
||||
# Группа/иерархия → объект.
|
||||
# Группа/иерархия/с типом → объект.
|
||||
$o = [ordered]@{ name = $name }
|
||||
if ($code) { $o['code'] = $code }
|
||||
if ($desc -eq '') { $o['description'] = '' }
|
||||
elseif ($desc -ne $auto) { $o['description'] = $desc }
|
||||
if ($null -ne $typeStr) { $o['type'] = $typeStr }
|
||||
if ($isFolder) { $o['isFolder'] = $true }
|
||||
if ($kids.Count -gt 0) {
|
||||
$sub = [System.Collections.ArrayList]@()
|
||||
|
||||
@@ -619,6 +619,32 @@ omit-on-empty. Поля пишутся частичной формой (`Standar
|
||||
ключ `standardAttributes`. Опциональный легаси-реквизит `ExchangeDate` (часть планов) поддержан как «доп.» член
|
||||
`standardAttributes` (эмитится по факту наличия ключа, вне фикс-списка).
|
||||
|
||||
### 7.2b ChartOfCharacteristicTypes (План видов характеристик)
|
||||
|
||||
Иерархический ссылочный тип (папки+элементы, без уровней/подчинения). Общий с Catalog слой: `synonym`, `comment`,
|
||||
`useStandardCommands`, `includeHelpInContents`, `hierarchical`/`foldersOnTop`, коды (`codeLength`/`codeAllowedLength`/
|
||||
`descriptionLength`/`checkUnique`/`autonumbering`), `defaultPresentation`, `standardAttributes` (§7.1.1),
|
||||
`characteristics` (§7.1.4), `inputByString` (§7.1.5), формы (вкл. `*Folder*`), `basedOn`, `dataLockFields`, презентации,
|
||||
`predefined` (§7.1.2) — предопределённые виды характеристик.
|
||||
|
||||
| Поле JSON | Умолчание | XML элемент |
|
||||
|-----------|----------|-------------|
|
||||
| `valueType` | *(любой примитив)* | Type (тип значения характеристики, составной — строка `"A + B"` или массив `valueTypes`) |
|
||||
| `characteristicExtValues` | пусто | CharacteristicExtValues (ссылка на справочник доп. значений) |
|
||||
| `createOnInput` | `DontUse` | CreateOnInput *(≠ Catalog `Use`)* |
|
||||
| `dataLockControlMode` | `Managed` | DataLockControlMode *(≠ Catalog `Automatic`)* |
|
||||
| `codeSeries` | `WholeCharacteristicKind` | CodeSeries *(≠ Catalog `WholeCatalog`)* |
|
||||
| `checkUnique` | `true` | CheckUnique *(≠ Catalog `false`)* |
|
||||
| `descriptionLength` | `100` | DescriptionLength *(≠ Catalog `25`)* |
|
||||
| `dataHistory` + `updateDataHistoryImmediatelyAfterWrite` + `executeAfterWriteDataHistoryVersionProcessing` | `DontUse`/`false`/`false` | DataHistory-триплет |
|
||||
|
||||
Стандартные реквизиты ПВХ: PredefinedDataName, Predefined, Ref, DeletionMark, Description, Code, Parent, ValueType
|
||||
(профиль: Наименование → FillChecking=ShowError, Родитель → FillFromFillingValue=true). Блок **условный** (`standardAttributes`).
|
||||
|
||||
**Предопределённые виды** несут **тип значения на элемент** — ключ `type` в объектной форме `predefined`-элемента
|
||||
(строка `"A + B"` или массив; `""` → пустой `<Type/>`; отсутствие ключа → без блока). Пример:
|
||||
`{"name": "Цвет", "code": "000001", "type": "CatalogRef.Цвета"}`.
|
||||
|
||||
### 7.3 Enum
|
||||
|
||||
| Поле JSON | Умолчание | XML элемент |
|
||||
|
||||
@@ -4,8 +4,15 @@
|
||||
"type": "ChartOfCharacteristicTypes",
|
||||
"name": "ДополнительныеРеквизитыИСведения",
|
||||
"descriptionLength": 100,
|
||||
"hierarchical": true,
|
||||
"valueTypes": ["String(200)", "Number(15,2)", "Boolean", "Date"],
|
||||
"attributes": ["НаборСвойств: String(100)"]
|
||||
"standardAttributes": { "Description": { "synonym": "Свойство" } },
|
||||
"attributes": ["НаборСвойств: String(100)"],
|
||||
"predefined": [
|
||||
{ "name": "Цвет", "code": "000001", "type": "CatalogRef.ЗначенияСвойств" },
|
||||
{ "name": "Размер", "code": "000002", "type": "String(50) + Number(3,0)" },
|
||||
{ "name": "Группа", "code": "000003", "isFolder": true, "type": "" }
|
||||
]
|
||||
},
|
||||
"validatePath": "ChartsOfCharacteristicTypes/ДополнительныеРеквизитыИСведения",
|
||||
"expect": {
|
||||
|
||||
+26
-16
@@ -18,7 +18,7 @@
|
||||
<xr:TypeId>UUID-008</xr:TypeId>
|
||||
<xr:ValueId>UUID-009</xr:ValueId>
|
||||
</xr:GeneratedType>
|
||||
<xr:GeneratedType name="ChartOfCharacteristicTypesCharacteristic.ДополнительныеРеквизитыИСведения" category="Characteristic">
|
||||
<xr:GeneratedType name="Characteristic.ДополнительныеРеквизитыИСведения" category="Characteristic">
|
||||
<xr:TypeId>UUID-010</xr:TypeId>
|
||||
<xr:ValueId>UUID-011</xr:ValueId>
|
||||
</xr:GeneratedType>
|
||||
@@ -37,12 +37,7 @@
|
||||
</Synonym>
|
||||
<Comment/>
|
||||
<UseStandardCommands>true</UseStandardCommands>
|
||||
<CodeLength>9</CodeLength>
|
||||
<CodeAllowedLength>Variable</CodeAllowedLength>
|
||||
<DescriptionLength>100</DescriptionLength>
|
||||
<CheckUnique>false</CheckUnique>
|
||||
<Autonumbering>true</Autonumbering>
|
||||
<DefaultPresentation>AsDescription</DefaultPresentation>
|
||||
<IncludeHelpInContents>false</IncludeHelpInContents>
|
||||
<CharacteristicExtValues/>
|
||||
<Type>
|
||||
<v8:Type>xs:string</v8:Type>
|
||||
@@ -62,8 +57,15 @@
|
||||
<v8:DateFractions>Date</v8:DateFractions>
|
||||
</v8:DateQualifiers>
|
||||
</Type>
|
||||
<Hierarchical>false</Hierarchical>
|
||||
<Hierarchical>true</Hierarchical>
|
||||
<FoldersOnTop>true</FoldersOnTop>
|
||||
<CodeLength>9</CodeLength>
|
||||
<CodeAllowedLength>Variable</CodeAllowedLength>
|
||||
<DescriptionLength>100</DescriptionLength>
|
||||
<CodeSeries>WholeCharacteristicKind</CodeSeries>
|
||||
<CheckUnique>true</CheckUnique>
|
||||
<Autonumbering>true</Autonumbering>
|
||||
<DefaultPresentation>AsDescription</DefaultPresentation>
|
||||
<StandardAttributes>
|
||||
<xr:StandardAttribute name="PredefinedDataName">
|
||||
<xr:LinkByType/>
|
||||
@@ -171,7 +173,7 @@
|
||||
</xr:StandardAttribute>
|
||||
<xr:StandardAttribute name="Description">
|
||||
<xr:LinkByType/>
|
||||
<xr:FillChecking>DontCheck</xr:FillChecking>
|
||||
<xr:FillChecking>ShowError</xr:FillChecking>
|
||||
<xr:MultiLine>false</xr:MultiLine>
|
||||
<xr:FillFromFillingValue>false</xr:FillFromFillingValue>
|
||||
<xr:CreateOnInput>Auto</xr:CreateOnInput>
|
||||
@@ -187,7 +189,12 @@
|
||||
<xr:DataHistory>Use</xr:DataHistory>
|
||||
<xr:MarkNegatives>false</xr:MarkNegatives>
|
||||
<xr:MinValue xsi:nil="true"/>
|
||||
<xr:Synonym/>
|
||||
<xr:Synonym>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Свойство</v8:content>
|
||||
</v8:item>
|
||||
</xr:Synonym>
|
||||
<xr:Comment/>
|
||||
<xr:FullTextSearch>Use</xr:FullTextSearch>
|
||||
<xr:ChoiceParameterLinks/>
|
||||
@@ -225,7 +232,7 @@
|
||||
<xr:LinkByType/>
|
||||
<xr:FillChecking>DontCheck</xr:FillChecking>
|
||||
<xr:MultiLine>false</xr:MultiLine>
|
||||
<xr:FillFromFillingValue>false</xr:FillFromFillingValue>
|
||||
<xr:FillFromFillingValue>true</xr:FillFromFillingValue>
|
||||
<xr:CreateOnInput>Auto</xr:CreateOnInput>
|
||||
<xr:MaxValue xsi:nil="true"/>
|
||||
<xr:ToolTip/>
|
||||
@@ -283,9 +290,11 @@
|
||||
<xr:Field>ChartOfCharacteristicTypes.ДополнительныеРеквизитыИСведения.StandardAttribute.Description</xr:Field>
|
||||
<xr:Field>ChartOfCharacteristicTypes.ДополнительныеРеквизитыИСведения.StandardAttribute.Code</xr:Field>
|
||||
</InputByString>
|
||||
<CreateOnInput>DontUse</CreateOnInput>
|
||||
<SearchStringModeOnInputByString>Begin</SearchStringModeOnInputByString>
|
||||
<FullTextSearchOnInputByString>DontUse</FullTextSearchOnInputByString>
|
||||
<ChoiceDataGetModeOnInputByString>Directly</ChoiceDataGetModeOnInputByString>
|
||||
<FullTextSearchOnInputByString>DontUse</FullTextSearchOnInputByString>
|
||||
<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>
|
||||
<DefaultObjectForm/>
|
||||
<DefaultFolderForm/>
|
||||
<DefaultListForm/>
|
||||
@@ -296,18 +305,15 @@
|
||||
<AuxiliaryListForm/>
|
||||
<AuxiliaryChoiceForm/>
|
||||
<AuxiliaryFolderChoiceForm/>
|
||||
<IncludeHelpInContents>false</IncludeHelpInContents>
|
||||
<BasedOn/>
|
||||
<DataLockFields/>
|
||||
<DataLockControlMode>Automatic</DataLockControlMode>
|
||||
<DataLockControlMode>Managed</DataLockControlMode>
|
||||
<FullTextSearch>Use</FullTextSearch>
|
||||
<ObjectPresentation/>
|
||||
<ExtendedObjectPresentation/>
|
||||
<ListPresentation/>
|
||||
<ExtendedListPresentation/>
|
||||
<Explanation/>
|
||||
<CreateOnInput>DontUse</CreateOnInput>
|
||||
<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>
|
||||
<DataHistory>DontUse</DataHistory>
|
||||
<UpdateDataHistoryImmediatelyAfterWrite>false</UpdateDataHistoryImmediatelyAfterWrite>
|
||||
<ExecuteAfterWriteDataHistoryVersionProcessing>false</ExecuteAfterWriteDataHistoryVersionProcessing>
|
||||
@@ -340,6 +346,8 @@
|
||||
<ExtendedEdit>false</ExtendedEdit>
|
||||
<MinValue xsi:nil="true"/>
|
||||
<MaxValue xsi:nil="true"/>
|
||||
<FillFromFillingValue>false</FillFromFillingValue>
|
||||
<FillValue xsi:type="xs:string"/>
|
||||
<FillChecking>DontCheck</FillChecking>
|
||||
<ChoiceFoldersAndItems>Items</ChoiceFoldersAndItems>
|
||||
<ChoiceParameterLinks/>
|
||||
@@ -349,8 +357,10 @@
|
||||
<ChoiceForm/>
|
||||
<LinkByType/>
|
||||
<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>
|
||||
<Use>ForItem</Use>
|
||||
<Indexing>DontIndex</Indexing>
|
||||
<FullTextSearch>Use</FullTextSearch>
|
||||
<DataHistory>Use</DataHistory>
|
||||
</Properties>
|
||||
</Attribute>
|
||||
</ChildObjects>
|
||||
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<PredefinedData xmlns="http://v8.1c.ru/8.3/xcf/predef" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:xr="http://v8.1c.ru/8.3/xcf/readable" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="PlanOfCharacteristicKindPredefinedItems" version="2.17">
|
||||
<Item id="UUID-001">
|
||||
<Name>Цвет</Name>
|
||||
<Code>000001</Code>
|
||||
<Description>Цвет</Description>
|
||||
<Type>
|
||||
<v8:Type xmlns:d5p1="http://v8.1c.ru/8.1/data/enterprise/current-config">d5p1:CatalogRef.ЗначенияСвойств</v8:Type>
|
||||
</Type>
|
||||
<IsFolder>false</IsFolder>
|
||||
</Item>
|
||||
<Item id="UUID-002">
|
||||
<Name>Размер</Name>
|
||||
<Code>000002</Code>
|
||||
<Description>Размер</Description>
|
||||
<Type>
|
||||
<v8:Type>xs:string</v8:Type>
|
||||
<v8:StringQualifiers>
|
||||
<v8:Length>50</v8:Length>
|
||||
<v8:AllowedLength>Variable</v8:AllowedLength>
|
||||
</v8:StringQualifiers>
|
||||
<v8:Type>xs:decimal</v8:Type>
|
||||
<v8:NumberQualifiers>
|
||||
<v8:Digits>3</v8:Digits>
|
||||
<v8:FractionDigits>0</v8:FractionDigits>
|
||||
<v8:AllowedSign>Any</v8:AllowedSign>
|
||||
</v8:NumberQualifiers>
|
||||
</Type>
|
||||
<IsFolder>false</IsFolder>
|
||||
</Item>
|
||||
<Item id="UUID-003">
|
||||
<Name>Группа</Name>
|
||||
<Code>000003</Code>
|
||||
<Description>Группа</Description>
|
||||
<Type/>
|
||||
<IsFolder>true</IsFolder>
|
||||
</Item>
|
||||
</PredefinedData>
|
||||
Reference in New Issue
Block a user