mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-08-28 14:09:41 +03:00
feat(form-decompile,form-compile): dataParameters динсписка + nil-значение схема-параметра (valueListAllowed)
Раундтрип терял две вещи в настройках динамического списка реквизита (форма ВыборПодписантовПечатныхФорм):
1. <dcsset:dataParameters> — значения параметров запроса в ListSettings (список SettingsParameterValue
{use, parameter, value?}). Не захватывались/не эмитились вовсе.
2. <dcssch:value xsi:nil/> у схема-параметра при valueListAllowed=true: компилятор по умолчанию его
пропускал (if valueListAllowed → return), но платформа пишет не всегда (корпус 27 с / 47 без).
dataParameters: грамматика портирована из skd-compile (Emit-DataParameters + Parse-DataParamShorthand +
Test/Emit-EmptyValue) — консистентно с СКД (shorthand "Имя @off" / объект). Form-нюанс: значение
опционально (use=false плейсхолдер без value-узла, в отличие от skd-settings). compile эмитит после
filter (XSD-порядок). decompile: Build-FormDataParameters (объект с полным valueType / shorthand).
nil-значение: декомпилятор ставит явный маркер value:null при valueListAllowed+nil-тег; компилятор
эмитит nil при valueListAllowed + явный value (различает absent от null через Has-DLProp/value_explicit).
Корпус: dataParameters в 9 формах (17 items, все use=false, 4 со значениями DesignTimeValue/ent:/decimal).
Верификация: таргет-раундтрип формы → match (22→0); 9 dataParameters-форм — категория закрыта (остаток —
др. категории filter userSettingPresentation/MultipleValue*). Регресс form-compile 43/43 (ps1+py,
PY-паритет снэпшота); 1С-cert dynamic-list-form (vla-nil + dataParameters грузятся). spec.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
b794560492
commit
819b7fa126
@@ -1,4 +1,4 @@
|
|||||||
# form-compile v1.133 — Compile 1C managed form from JSON or object metadata
|
# form-compile v1.134 — Compile 1C managed form from JSON or object metadata
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
param(
|
param(
|
||||||
[string]$JsonPath,
|
[string]$JsonPath,
|
||||||
@@ -5047,6 +5047,134 @@ function Emit-DLInputParameters {
|
|||||||
X "$indent</dcssch:inputParameters>"
|
X "$indent</dcssch:inputParameters>"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ── dataParameters (значения параметров запроса в настройках компоновки) — порт из skd-compile ──
|
||||||
|
# Грамматика идентична СКД: shorthand "Имя = Значение @off @user" или объект
|
||||||
|
# {parameter, value?, valueType?, use?, nilValue?, viewMode?, userSettingID?, userSettingPresentation?}.
|
||||||
|
function Test-EmptyValue {
|
||||||
|
param($v)
|
||||||
|
if ($null -eq $v) { return $true }
|
||||||
|
$s = "$v".Trim()
|
||||||
|
if ($s -eq "") { return $true }
|
||||||
|
if ($s -eq "_") { return $true }
|
||||||
|
if ($s.ToLowerInvariant() -eq "null") { return $true }
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
function Emit-EmptyValue {
|
||||||
|
param([string]$type, [string]$indent, [string]$tagPrefix = "", [bool]$valueListAllowed = $false)
|
||||||
|
if ($valueListAllowed) { return }
|
||||||
|
$t = if ($null -eq $type) { "" } else { "$type" }
|
||||||
|
$tBare = if ($t -match '^xs:(.+)$') { $matches[1] } else { $t }
|
||||||
|
$pf = $tagPrefix
|
||||||
|
if ($t -eq "") { X "$indent<${pf}value xsi:nil=`"true`"/>" }
|
||||||
|
elseif ($t -eq "StandardPeriod") {
|
||||||
|
X "$indent<${pf}value xsi:type=`"v8:StandardPeriod`">"
|
||||||
|
X "$indent`t<v8:variant xsi:type=`"v8:StandardPeriodVariant`">Custom</v8:variant>"
|
||||||
|
X "$indent`t<v8:startDate>0001-01-01T00:00:00</v8:startDate>"
|
||||||
|
X "$indent`t<v8:endDate>0001-01-01T00:00:00</v8:endDate>"
|
||||||
|
X "$indent</${pf}value>"
|
||||||
|
}
|
||||||
|
elseif ($tBare -match '^string') { X "$indent<${pf}value xsi:type=`"xs:string`"/>" }
|
||||||
|
elseif ($tBare -match '^(date|time)') { X "$indent<${pf}value xsi:type=`"xs:dateTime`">0001-01-01T00:00:00</${pf}value>" }
|
||||||
|
elseif ($tBare -match '^decimal') { X "$indent<${pf}value xsi:type=`"xs:decimal`">0</${pf}value>" }
|
||||||
|
elseif ($tBare -eq "boolean") { X "$indent<${pf}value xsi:type=`"xs:boolean`">false</${pf}value>" }
|
||||||
|
else { X "$indent<${pf}value xsi:nil=`"true`"/>" }
|
||||||
|
}
|
||||||
|
function Parse-DataParamShorthand {
|
||||||
|
param([string]$s)
|
||||||
|
$result = @{ parameter = ""; value = $null; use = $true; userSettingID = $null; viewMode = $null }
|
||||||
|
if ($s -match '@user') { $result.userSettingID = "auto"; $s = $s -replace '\s*@user', '' }
|
||||||
|
if ($s -match '@off') { $result.use = $false; $s = $s -replace '\s*@off', '' }
|
||||||
|
if ($s -match '@quickAccess') { $result.viewMode = "QuickAccess"; $s = $s -replace '\s*@quickAccess', '' }
|
||||||
|
if ($s -match '@normal') { $result.viewMode = "Normal"; $s = $s -replace '\s*@normal', '' }
|
||||||
|
$s = $s.Trim()
|
||||||
|
if ($s -match '^([^=]+)=\s*(.+)$') {
|
||||||
|
$result.parameter = $Matches[1].Trim()
|
||||||
|
$valStr = $Matches[2].Trim()
|
||||||
|
$periodVariants = @("Custom","Today","ThisWeek","ThisTenDays","ThisMonth","ThisQuarter","ThisHalfYear","ThisYear","FromBeginningOfThisWeek","FromBeginningOfThisTenDays","FromBeginningOfThisMonth","FromBeginningOfThisQuarter","FromBeginningOfThisHalfYear","FromBeginningOfThisYear","LastWeek","LastTenDays","LastMonth","LastQuarter","LastHalfYear","LastYear","NextDay","NextWeek","NextTenDays","NextMonth","NextQuarter","NextHalfYear","NextYear","TillEndOfThisWeek","TillEndOfThisTenDays","TillEndOfThisMonth","TillEndOfThisQuarter","TillEndOfThisHalfYear","TillEndOfThisYear")
|
||||||
|
if ($periodVariants -contains $valStr) { $result.value = @{ variant = $valStr } }
|
||||||
|
elseif ($valStr -match '^\d{4}-\d{2}-\d{2}T') { $result.value = $valStr }
|
||||||
|
elseif ($valStr -eq "true" -or $valStr -eq "false") { $result.value = [bool]($valStr -eq "true") }
|
||||||
|
else { $result.value = $valStr }
|
||||||
|
} else { $result.parameter = $s }
|
||||||
|
return $result
|
||||||
|
}
|
||||||
|
function Emit-DataParameters {
|
||||||
|
param($items, [string]$indent, $blockViewMode = $null)
|
||||||
|
if (-not $items -or @($items).Count -eq 0) { return }
|
||||||
|
X "$indent<dcsset:dataParameters>"
|
||||||
|
foreach ($dp in @($items)) {
|
||||||
|
if ($dp -is [string]) {
|
||||||
|
$parsed = Parse-DataParamShorthand $dp
|
||||||
|
$dpObj = New-Object PSObject
|
||||||
|
$dpObj | Add-Member -NotePropertyName "parameter" -NotePropertyValue $parsed.parameter
|
||||||
|
if ($null -ne $parsed.value) { $dpObj | Add-Member -NotePropertyName "value" -NotePropertyValue $parsed.value }
|
||||||
|
if ($parsed.use -eq $false) { $dpObj | Add-Member -NotePropertyName "use" -NotePropertyValue $false }
|
||||||
|
if ($parsed.userSettingID) { $dpObj | Add-Member -NotePropertyName "userSettingID" -NotePropertyValue $parsed.userSettingID }
|
||||||
|
if ($parsed.viewMode) { $dpObj | Add-Member -NotePropertyName "viewMode" -NotePropertyValue $parsed.viewMode }
|
||||||
|
$dp = $dpObj
|
||||||
|
}
|
||||||
|
X "$indent`t<dcscor:item xsi:type=`"dcsset:SettingsParameterValue`">"
|
||||||
|
if ($dp.use -eq $false) { X "$indent`t`t<dcscor:use>false</dcscor:use>" }
|
||||||
|
X "$indent`t`t<dcscor:parameter>$(Esc-Xml "$($dp.parameter)")</dcscor:parameter>"
|
||||||
|
if ($dp.nilValue -eq $true) {
|
||||||
|
X "$indent`t`t<dcscor:value xsi:nil=`"true`"/>"
|
||||||
|
} elseif ((Test-EmptyValue $dp.value) -and $dp.valueType) {
|
||||||
|
# Явный типизированный пустой (xs:string-плейсхолдер и т.п.)
|
||||||
|
Emit-EmptyValue -type "$($dp.valueType)" -indent "$indent`t`t" -tagPrefix "dcscor:" -valueListAllowed $false
|
||||||
|
} elseif (Test-EmptyValue $dp.value) {
|
||||||
|
# Нет значения и нет valueType → НЕ эмитим value-узел (form дин-список: use=false плейсхолдер).
|
||||||
|
# (В отличие от skd-settings, где значение всегда присутствует.)
|
||||||
|
} elseif ($null -ne $dp.value) {
|
||||||
|
$vtype = "$($dp.valueType)"
|
||||||
|
if (($dp.value -is [PSCustomObject] -or $dp.value -is [hashtable] -or $dp.value -is [System.Collections.IDictionary]) -and ($dp.value.variant)) {
|
||||||
|
$_hasDate = $false; $_hasSD = $false
|
||||||
|
if ($dp.value -is [PSCustomObject]) { $_hasDate = [bool]$dp.value.PSObject.Properties['date']; $_hasSD = [bool]$dp.value.PSObject.Properties['startDate'] }
|
||||||
|
else { $_hasDate = $dp.value.Contains('date'); $_hasSD = $dp.value.Contains('startDate') }
|
||||||
|
$_variantStr = "$($dp.value.variant)"
|
||||||
|
$_isSBD = $_hasDate -or (-not $_hasSD -and $_variantStr -like 'BeginningOf*')
|
||||||
|
if ($_isSBD) {
|
||||||
|
$_d = $null
|
||||||
|
if ($dp.value -is [PSCustomObject] -and $dp.value.PSObject.Properties['date']) { $_d = "$($dp.value.date)" }
|
||||||
|
elseif (($dp.value -is [System.Collections.IDictionary]) -and $dp.value.Contains('date')) { $_d = "$($dp.value['date'])" }
|
||||||
|
X "$indent`t`t<dcscor:value xsi:type=`"v8:StandardBeginningDate`">"
|
||||||
|
X "$indent`t`t`t<v8:variant xsi:type=`"v8:StandardBeginningDateVariant`">$(Esc-Xml $_variantStr)</v8:variant>"
|
||||||
|
if ($_variantStr -eq 'Custom') { if (-not $_d) { $_d = '0001-01-01T00:00:00' }; X "$indent`t`t`t<v8:date>$(Esc-Xml $_d)</v8:date>" }
|
||||||
|
X "$indent`t`t</dcscor:value>"
|
||||||
|
} else {
|
||||||
|
$_sd = $null; $_ed = $null
|
||||||
|
if ($dp.value -is [PSCustomObject]) { if ($dp.value.PSObject.Properties['startDate']) { $_sd = "$($dp.value.startDate)" }; if ($dp.value.PSObject.Properties['endDate']) { $_ed = "$($dp.value.endDate)" } }
|
||||||
|
else { if ($dp.value.Contains('startDate')) { $_sd = "$($dp.value['startDate'])" }; if ($dp.value.Contains('endDate')) { $_ed = "$($dp.value['endDate'])" } }
|
||||||
|
X "$indent`t`t<dcscor:value xsi:type=`"v8:StandardPeriod`">"
|
||||||
|
X "$indent`t`t`t<v8:variant xsi:type=`"v8:StandardPeriodVariant`">$(Esc-Xml $_variantStr)</v8:variant>"
|
||||||
|
if ($_variantStr -eq 'Custom') { if (-not $_sd) { $_sd = '0001-01-01T00:00:00' }; if (-not $_ed) { $_ed = '0001-01-01T00:00:00' }; X "$indent`t`t`t<v8:startDate>$(Esc-Xml $_sd)</v8:startDate>"; X "$indent`t`t`t<v8:endDate>$(Esc-Xml $_ed)</v8:endDate>" }
|
||||||
|
X "$indent`t`t</dcscor:value>"
|
||||||
|
}
|
||||||
|
} elseif ($vtype -match '^[a-zA-Z]+:') {
|
||||||
|
$vStr = if ($dp.value -is [bool]) { "$($dp.value)".ToLower() } else { "$($dp.value)" }
|
||||||
|
X "$indent`t`t<dcscor:value xsi:type=`"$vtype`">$(Esc-Xml $vStr)</dcscor:value>"
|
||||||
|
} elseif ($vtype -eq 'boolean' -or $dp.value -is [bool]) {
|
||||||
|
X "$indent`t`t<dcscor:value xsi:type=`"xs:boolean`">$(Esc-Xml ("$($dp.value)".ToLower()))</dcscor:value>"
|
||||||
|
} 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>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($dp.viewMode) { X "$indent`t`t<dcsset:viewMode>$(Esc-Xml "$($dp.viewMode)")</dcsset:viewMode>" }
|
||||||
|
if ($dp.userSettingID) { $uid = if ("$($dp.userSettingID)" -eq "auto") { New-Guid-String } else { "$($dp.userSettingID)" }; X "$indent`t`t<dcsset:userSettingID>$(Esc-Xml $uid)</dcsset:userSettingID>" }
|
||||||
|
if ($dp.userSettingPresentation) { Emit-MLText -tag "dcsset:userSettingPresentation" -text $dp.userSettingPresentation -indent "$indent`t`t" }
|
||||||
|
X "$indent`t</dcscor:item>"
|
||||||
|
}
|
||||||
|
if ($null -ne $blockViewMode) { X "$indent`t<dcsset:viewMode>$(Esc-Xml "$blockViewMode")</dcsset:viewMode>" }
|
||||||
|
X "$indent</dcsset:dataParameters>"
|
||||||
|
}
|
||||||
|
|
||||||
function Emit-DLParameter {
|
function Emit-DLParameter {
|
||||||
param($p, $parsed, [string]$indent)
|
param($p, $parsed, [string]$indent)
|
||||||
X "$indent<Parameter>"
|
X "$indent<Parameter>"
|
||||||
@@ -5066,6 +5194,9 @@ function Emit-DLParameter {
|
|||||||
$valIsArray = ($parsed.value -is [array]) -or ($parsed.value -is [System.Collections.IList] -and $parsed.value -isnot [string])
|
$valIsArray = ($parsed.value -is [array]) -or ($parsed.value -is [System.Collections.IList] -and $parsed.value -isnot [string])
|
||||||
if ($valIsArray) {
|
if ($valIsArray) {
|
||||||
foreach ($v in @($parsed.value)) { Emit-DLValue -type $parsed.type -val $v -indent $ci -valueListAllowed $false }
|
foreach ($v in @($parsed.value)) { Emit-DLValue -type $parsed.type -val $v -indent $ci -valueListAllowed $false }
|
||||||
|
} elseif ($vla -and (Test-DLEmptyValue $parsed.value) -and $parsed.valueExplicit) {
|
||||||
|
# valueListAllowed + явный пустой (value:null от декомпилятора) → платформа здесь пишет nil
|
||||||
|
X "$ci<dcssch:value xsi:nil=`"true`"/>"
|
||||||
} else {
|
} else {
|
||||||
Emit-DLValue -type $parsed.type -val $parsed.value -indent $ci -valueListAllowed $vla
|
Emit-DLValue -type $parsed.type -val $parsed.value -indent $ci -valueListAllowed $vla
|
||||||
}
|
}
|
||||||
@@ -5114,7 +5245,7 @@ function Emit-DLParameters {
|
|||||||
} elseif ((Has-DLProp $p 'valueType') -and $p.valueType) {
|
} elseif ((Has-DLProp $p 'valueType') -and $p.valueType) {
|
||||||
$resolvedType = Resolve-TypeStr "$($p.valueType)"
|
$resolvedType = Resolve-TypeStr "$($p.valueType)"
|
||||||
}
|
}
|
||||||
$parsed = @{ name = "$($p.name)"; type = $resolvedType; value = $(if (Has-DLProp $p 'value') { $p.value } else { $null }); title = $null }
|
$parsed = @{ name = "$($p.name)"; type = $resolvedType; value = $(if (Has-DLProp $p 'value') { $p.value } else { $null }); valueExplicit = (Has-DLProp $p 'value'); title = $null }
|
||||||
if ((Has-DLProp $p 'valueListAllowed') -and $p.valueListAllowed -eq $true) { $parsed.valueListAllowed = $true }
|
if ((Has-DLProp $p 'valueListAllowed') -and $p.valueListAllowed -eq $true) { $parsed.valueListAllowed = $true }
|
||||||
if ((Has-DLProp $p 'hidden') -and $p.hidden -eq $true) { $parsed.hidden = $true }
|
if ((Has-DLProp $p 'hidden') -and $p.hidden -eq $true) { $parsed.hidden = $true }
|
||||||
}
|
}
|
||||||
@@ -5355,6 +5486,8 @@ function Emit-Attributes {
|
|||||||
} else {
|
} else {
|
||||||
# Полный каноничный скелет (умолчание, ~93% форм) — без изменений.
|
# Полный каноничный скелет (умолчание, ~93% форм) — без изменений.
|
||||||
Emit-Filter -items $st.filter -indent $lsi -blockViewMode 'Normal' -blockUserSettingID $script:CANON_FILTER_ID
|
Emit-Filter -items $st.filter -indent $lsi -blockViewMode 'Normal' -blockUserSettingID $script:CANON_FILTER_ID
|
||||||
|
# dataParameters — после filter, до order (XSD-порядок ListSettings)
|
||||||
|
if ($st.PSObject.Properties['dataParameters']) { Emit-DataParameters -items $st.dataParameters -indent $lsi }
|
||||||
Emit-Order -items $st.order -indent $lsi -blockViewMode 'Normal' -blockUserSettingID $script:CANON_ORDER_ID
|
Emit-Order -items $st.order -indent $lsi -blockViewMode 'Normal' -blockUserSettingID $script:CANON_ORDER_ID
|
||||||
Emit-ConditionalAppearance -items $st.conditionalAppearance -indent $lsi -blockViewMode 'Normal' -blockUserSettingID $script:CANON_CA_ID
|
Emit-ConditionalAppearance -items $st.conditionalAppearance -indent $lsi -blockViewMode 'Normal' -blockUserSettingID $script:CANON_CA_ID
|
||||||
X "$lsi<dcsset:itemsViewMode>Normal</dcsset:itemsViewMode>"
|
X "$lsi<dcsset:itemsViewMode>Normal</dcsset:itemsViewMode>"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# form-compile v1.133 — Compile 1C managed form from JSON or object metadata
|
# form-compile v1.134 — Compile 1C managed form from JSON or object metadata
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
import argparse
|
import argparse
|
||||||
import copy
|
import copy
|
||||||
@@ -4786,6 +4786,149 @@ def emit_dl_input_parameters(lines, ip, indent):
|
|||||||
lines.append(f'{indent}</dcssch:inputParameters>')
|
lines.append(f'{indent}</dcssch:inputParameters>')
|
||||||
|
|
||||||
|
|
||||||
|
# ── dataParameters (значения параметров запроса в настройках компоновки) — порт из skd ──
|
||||||
|
def _test_empty_value(v):
|
||||||
|
if v is None:
|
||||||
|
return True
|
||||||
|
s = str(v).strip()
|
||||||
|
return s == '' or s == '_' or s.lower() == 'null'
|
||||||
|
|
||||||
|
|
||||||
|
def emit_empty_value(lines, type_str, indent, tag_prefix='', value_list_allowed=False):
|
||||||
|
if value_list_allowed:
|
||||||
|
return
|
||||||
|
t = type_str or ''
|
||||||
|
t_bare = t[3:] if t.startswith('xs:') else t
|
||||||
|
pf = tag_prefix
|
||||||
|
if t == '':
|
||||||
|
lines.append(f'{indent}<{pf}value xsi:nil="true"/>')
|
||||||
|
elif t == 'StandardPeriod':
|
||||||
|
lines.append(f'{indent}<{pf}value xsi:type="v8:StandardPeriod">')
|
||||||
|
lines.append(f'{indent}\t<v8:variant xsi:type="v8:StandardPeriodVariant">Custom</v8:variant>')
|
||||||
|
lines.append(f'{indent}\t<v8:startDate>0001-01-01T00:00:00</v8:startDate>')
|
||||||
|
lines.append(f'{indent}\t<v8:endDate>0001-01-01T00:00:00</v8:endDate>')
|
||||||
|
lines.append(f'{indent}</{pf}value>')
|
||||||
|
elif re.match(r'^string', t_bare):
|
||||||
|
lines.append(f'{indent}<{pf}value xsi:type="xs:string"/>')
|
||||||
|
elif re.match(r'^(date|time)', t_bare):
|
||||||
|
lines.append(f'{indent}<{pf}value xsi:type="xs:dateTime">0001-01-01T00:00:00</{pf}value>')
|
||||||
|
elif re.match(r'^decimal', t_bare):
|
||||||
|
lines.append(f'{indent}<{pf}value xsi:type="xs:decimal">0</{pf}value>')
|
||||||
|
elif t_bare == 'boolean':
|
||||||
|
lines.append(f'{indent}<{pf}value xsi:type="xs:boolean">false</{pf}value>')
|
||||||
|
else:
|
||||||
|
lines.append(f'{indent}<{pf}value xsi:nil="true"/>')
|
||||||
|
|
||||||
|
|
||||||
|
_DP_PERIOD_VARIANTS = {"Custom","Today","ThisWeek","ThisTenDays","ThisMonth","ThisQuarter","ThisHalfYear","ThisYear","FromBeginningOfThisWeek","FromBeginningOfThisTenDays","FromBeginningOfThisMonth","FromBeginningOfThisQuarter","FromBeginningOfThisHalfYear","FromBeginningOfThisYear","LastWeek","LastTenDays","LastMonth","LastQuarter","LastHalfYear","LastYear","NextDay","NextWeek","NextTenDays","NextMonth","NextQuarter","NextHalfYear","NextYear","TillEndOfThisWeek","TillEndOfThisTenDays","TillEndOfThisMonth","TillEndOfThisQuarter","TillEndOfThisHalfYear","TillEndOfThisYear"}
|
||||||
|
|
||||||
|
|
||||||
|
def parse_data_param_shorthand(s):
|
||||||
|
result = {'parameter': '', 'value': None, 'use': True, 'userSettingID': None, 'viewMode': None}
|
||||||
|
if '@user' in s:
|
||||||
|
result['userSettingID'] = 'auto'; s = re.sub(r'\s*@user', '', s)
|
||||||
|
if '@off' in s:
|
||||||
|
result['use'] = False; s = re.sub(r'\s*@off', '', s)
|
||||||
|
if '@quickAccess' in s:
|
||||||
|
result['viewMode'] = 'QuickAccess'; s = re.sub(r'\s*@quickAccess', '', s)
|
||||||
|
if '@normal' in s:
|
||||||
|
result['viewMode'] = 'Normal'; s = re.sub(r'\s*@normal', '', s)
|
||||||
|
s = s.strip()
|
||||||
|
m = re.match(r'^([^=]+)=\s*(.+)$', s)
|
||||||
|
if m:
|
||||||
|
result['parameter'] = m.group(1).strip()
|
||||||
|
val_str = m.group(2).strip()
|
||||||
|
if val_str in _DP_PERIOD_VARIANTS:
|
||||||
|
result['value'] = {'variant': val_str}
|
||||||
|
elif re.match(r'^\d{4}-\d{2}-\d{2}T', val_str):
|
||||||
|
result['value'] = val_str
|
||||||
|
elif val_str in ('true', 'false'):
|
||||||
|
result['value'] = (val_str == 'true')
|
||||||
|
else:
|
||||||
|
result['value'] = val_str
|
||||||
|
else:
|
||||||
|
result['parameter'] = s
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def emit_data_parameters(lines, items, indent, block_view_mode=None):
|
||||||
|
if not items or len(items) == 0:
|
||||||
|
return
|
||||||
|
lines.append(f'{indent}<dcsset:dataParameters>')
|
||||||
|
for dp in items:
|
||||||
|
if isinstance(dp, str):
|
||||||
|
parsed = parse_data_param_shorthand(dp)
|
||||||
|
dp = {'parameter': parsed['parameter']}
|
||||||
|
if parsed['value'] is not None:
|
||||||
|
dp['value'] = parsed['value']
|
||||||
|
if parsed['use'] is False:
|
||||||
|
dp['use'] = False
|
||||||
|
if parsed['userSettingID']:
|
||||||
|
dp['userSettingID'] = parsed['userSettingID']
|
||||||
|
if parsed['viewMode']:
|
||||||
|
dp['viewMode'] = parsed['viewMode']
|
||||||
|
lines.append(f'{indent}\t<dcscor:item xsi:type="dcsset:SettingsParameterValue">')
|
||||||
|
if dp.get('use') is False:
|
||||||
|
lines.append(f'{indent}\t\t<dcscor:use>false</dcscor:use>')
|
||||||
|
lines.append(f'{indent}\t\t<dcscor:parameter>{esc_xml(str(dp.get("parameter", "")))}</dcscor:parameter>')
|
||||||
|
vtype = str(dp.get('valueType') or '')
|
||||||
|
val = dp.get('value')
|
||||||
|
if dp.get('nilValue') is True:
|
||||||
|
lines.append(f'{indent}\t\t<dcscor:value xsi:nil="true"/>')
|
||||||
|
elif _test_empty_value(val) and vtype:
|
||||||
|
emit_empty_value(lines, vtype, f'{indent}\t\t', tag_prefix='dcscor:', value_list_allowed=False)
|
||||||
|
elif _test_empty_value(val):
|
||||||
|
pass # нет значения → не эмитим value-узел (form дин-список: use=false плейсхолдер)
|
||||||
|
elif val is not None:
|
||||||
|
if isinstance(val, dict) and val.get('variant'):
|
||||||
|
variant = str(val.get('variant'))
|
||||||
|
has_date = 'date' in val
|
||||||
|
has_sd = 'startDate' in val
|
||||||
|
is_sbd = has_date or (not has_sd and variant.startswith('BeginningOf'))
|
||||||
|
if is_sbd:
|
||||||
|
lines.append(f'{indent}\t\t<dcscor:value xsi:type="v8:StandardBeginningDate">')
|
||||||
|
lines.append(f'{indent}\t\t\t<v8:variant xsi:type="v8:StandardBeginningDateVariant">{esc_xml(variant)}</v8:variant>')
|
||||||
|
if variant == 'Custom':
|
||||||
|
d = str(val.get('date') or '0001-01-01T00:00:00')
|
||||||
|
lines.append(f'{indent}\t\t\t<v8:date>{esc_xml(d)}</v8:date>')
|
||||||
|
lines.append(f'{indent}\t\t</dcscor:value>')
|
||||||
|
else:
|
||||||
|
lines.append(f'{indent}\t\t<dcscor:value xsi:type="v8:StandardPeriod">')
|
||||||
|
lines.append(f'{indent}\t\t\t<v8:variant xsi:type="v8:StandardPeriodVariant">{esc_xml(variant)}</v8:variant>')
|
||||||
|
if variant == 'Custom':
|
||||||
|
sd = str(val.get('startDate') or '0001-01-01T00:00:00')
|
||||||
|
ed = str(val.get('endDate') or '0001-01-01T00:00:00')
|
||||||
|
lines.append(f'{indent}\t\t\t<v8:startDate>{esc_xml(sd)}</v8:startDate>')
|
||||||
|
lines.append(f'{indent}\t\t\t<v8:endDate>{esc_xml(ed)}</v8:endDate>')
|
||||||
|
lines.append(f'{indent}\t\t</dcscor:value>')
|
||||||
|
elif re.match(r'^[a-zA-Z]+:', vtype):
|
||||||
|
v_str = str(val).lower() if isinstance(val, bool) else str(val)
|
||||||
|
lines.append(f'{indent}\t\t<dcscor:value xsi:type="{vtype}">{esc_xml(v_str)}</dcscor:value>')
|
||||||
|
elif vtype == 'boolean' or isinstance(val, bool):
|
||||||
|
lines.append(f'{indent}\t\t<dcscor:value xsi:type="xs:boolean">{esc_xml(str(val).lower())}</dcscor:value>')
|
||||||
|
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'^(ПланСчетов|Справочник|Перечисление|Документ|ПланВидовХарактеристик|ПланВидовРасчета|БизнесПроцесс|Задача|РегистрСведений|ПланОбмена)\.', 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>')
|
||||||
|
if dp.get('viewMode'):
|
||||||
|
lines.append(f'{indent}\t\t<dcsset:viewMode>{esc_xml(str(dp["viewMode"]))}</dcsset:viewMode>')
|
||||||
|
if dp.get('userSettingID'):
|
||||||
|
uid = new_uuid() if str(dp['userSettingID']) == 'auto' else str(dp['userSettingID'])
|
||||||
|
lines.append(f'{indent}\t\t<dcsset:userSettingID>{esc_xml(uid)}</dcsset:userSettingID>')
|
||||||
|
if dp.get('userSettingPresentation'):
|
||||||
|
emit_mltext(lines, f'{indent}\t\t', 'dcsset:userSettingPresentation', dp['userSettingPresentation'])
|
||||||
|
lines.append(f'{indent}\t</dcscor:item>')
|
||||||
|
if block_view_mode is not None:
|
||||||
|
lines.append(f'{indent}\t<dcsset:viewMode>{esc_xml(str(block_view_mode))}</dcsset:viewMode>')
|
||||||
|
lines.append(f'{indent}</dcsset:dataParameters>')
|
||||||
|
|
||||||
|
|
||||||
def emit_dl_parameter(lines, p, parsed, indent):
|
def emit_dl_parameter(lines, p, parsed, indent):
|
||||||
is_obj = not isinstance(p, str)
|
is_obj = not isinstance(p, str)
|
||||||
lines.append(f'{indent}<Parameter>')
|
lines.append(f'{indent}<Parameter>')
|
||||||
@@ -4811,6 +4954,9 @@ def emit_dl_parameter(lines, p, parsed, indent):
|
|||||||
if isinstance(pv, list):
|
if isinstance(pv, list):
|
||||||
for v in pv:
|
for v in pv:
|
||||||
emit_dl_value(lines, parsed.get('type', ''), v, ci, False)
|
emit_dl_value(lines, parsed.get('type', ''), v, ci, False)
|
||||||
|
elif vla and is_dl_empty_value(pv) and parsed.get('value_explicit'):
|
||||||
|
# valueListAllowed + явный пустой (value:null от декомпилятора) → платформа пишет nil
|
||||||
|
lines.append(f'{ci}<dcssch:value xsi:nil="true"/>')
|
||||||
else:
|
else:
|
||||||
emit_dl_value(lines, parsed.get('type', ''), pv, ci, vla)
|
emit_dl_value(lines, parsed.get('type', ''), pv, ci, vla)
|
||||||
# useRestriction — ВСЕГДА; дефолт true; false только при явном useRestriction:false.
|
# useRestriction — ВСЕГДА; дефолт true; false только при явном useRestriction:false.
|
||||||
@@ -4865,7 +5011,8 @@ def emit_dl_parameters(lines, params, indent):
|
|||||||
elif p.get('valueType'):
|
elif p.get('valueType'):
|
||||||
resolved_type = resolve_type_str(str(p['valueType']))
|
resolved_type = resolve_type_str(str(p['valueType']))
|
||||||
parsed = {'name': str(p.get('name', '')), 'type': resolved_type,
|
parsed = {'name': str(p.get('name', '')), 'type': resolved_type,
|
||||||
'value': p.get('value') if 'value' in p else None, 'title': None}
|
'value': p.get('value') if 'value' in p else None,
|
||||||
|
'value_explicit': ('value' in p), 'title': None}
|
||||||
if p.get('valueListAllowed') is True:
|
if p.get('valueListAllowed') is True:
|
||||||
parsed['valueListAllowed'] = True
|
parsed['valueListAllowed'] = True
|
||||||
if p.get('hidden') is True:
|
if p.get('hidden') is True:
|
||||||
@@ -5094,6 +5241,9 @@ def emit_attributes(lines, attrs, indent, conditional_appearance=None):
|
|||||||
else:
|
else:
|
||||||
# Полный каноничный скелет (умолчание, ~93% форм) — без изменений.
|
# Полный каноничный скелет (умолчание, ~93% форм) — без изменений.
|
||||||
emit_filter(lines, s.get('filter'), lsi, block_view_mode='Normal', block_user_setting_id=CANON_FILTER_ID)
|
emit_filter(lines, s.get('filter'), lsi, block_view_mode='Normal', block_user_setting_id=CANON_FILTER_ID)
|
||||||
|
# dataParameters — после filter, до order (XSD-порядок ListSettings)
|
||||||
|
if 'dataParameters' in s:
|
||||||
|
emit_data_parameters(lines, s.get('dataParameters'), lsi)
|
||||||
emit_order(lines, s.get('order'), lsi, block_view_mode='Normal', block_user_setting_id=CANON_ORDER_ID)
|
emit_order(lines, s.get('order'), lsi, block_view_mode='Normal', block_user_setting_id=CANON_ORDER_ID)
|
||||||
emit_conditional_appearance(lines, s.get('conditionalAppearance'), lsi, block_view_mode='Normal', block_user_setting_id=CANON_CA_ID)
|
emit_conditional_appearance(lines, s.get('conditionalAppearance'), lsi, block_view_mode='Normal', block_user_setting_id=CANON_CA_ID)
|
||||||
lines.append(f'{lsi}<dcsset:itemsViewMode>Normal</dcsset:itemsViewMode>')
|
lines.append(f'{lsi}<dcsset:itemsViewMode>Normal</dcsset:itemsViewMode>')
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# form-decompile v0.107 — Decompile 1C managed Form.xml to JSON DSL (draft)
|
# form-decompile v0.108 — Decompile 1C managed Form.xml to JSON DSL (draft)
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
# ВНИМАНИЕ: раундтрип не гарантируется. Навык исключён из авто-использования моделью.
|
# ВНИМАНИЕ: раундтрип не гарантируется. Навык исключён из авто-использования моделью.
|
||||||
param(
|
param(
|
||||||
@@ -1231,6 +1231,44 @@ function Build-DLInputParameters {
|
|||||||
return @($items)
|
return @($items)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# dcsset:dataParameters → массив (shorthand "Имя @off" для value-less / объект для типизированного
|
||||||
|
# значения). Грамматика зеркалит skd-compile Emit-DataParameters (form-контекст: значение опционально,
|
||||||
|
# в отличие от skd-settings). Без «auto»-компактизации (нужна машинерия сравнения с top-level).
|
||||||
|
function Build-FormDataParameters {
|
||||||
|
param($dpNode)
|
||||||
|
$entries = @()
|
||||||
|
foreach ($it in @($dpNode.SelectNodes("dcscor:item", $ns))) {
|
||||||
|
$pn = Get-Text $it "dcscor:parameter"
|
||||||
|
$use = Get-Text $it "dcscor:use"
|
||||||
|
$valNode = $it.SelectSingleNode("dcscor:value", $ns)
|
||||||
|
$usidN = $it.SelectSingleNode("dcsset:userSettingID", $ns)
|
||||||
|
$vmN = $it.SelectSingleNode("dcsset:viewMode", $ns)
|
||||||
|
$uspN = $it.SelectSingleNode("dcsset:userSettingPresentation", $ns)
|
||||||
|
if ($valNode -or $usidN -or $vmN -or $uspN) {
|
||||||
|
$obj = [ordered]@{ parameter = $pn }
|
||||||
|
if ($valNode) {
|
||||||
|
if ($valNode.GetAttribute("nil", $NS_XSI) -eq 'true') { $obj['nilValue'] = $true }
|
||||||
|
else {
|
||||||
|
$vType = $valNode.GetAttribute("type", $NS_XSI); $vVal = $valNode.InnerText
|
||||||
|
if ($vType -match 'decimal$' -and $vVal -match '^-?\d+$') { $obj['value'] = [int]$vVal }
|
||||||
|
elseif ($vType -match 'boolean$') { $obj['value'] = ($vVal -eq 'true') }
|
||||||
|
else { $obj['value'] = $vVal }
|
||||||
|
if ($vType) { $obj['valueType'] = $vType }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($use -eq 'false') { $obj['use'] = $false }
|
||||||
|
if ($usidN) { $obj['userSettingID'] = 'auto' }
|
||||||
|
if ($vmN) { $obj['viewMode'] = $vmN.InnerText }
|
||||||
|
if ($uspN) { $usp = Get-MLText $uspN; if ($null -ne $usp) { $obj['userSettingPresentation'] = $usp } }
|
||||||
|
$entries += $obj
|
||||||
|
} else {
|
||||||
|
$s = $pn; if ($use -eq 'false') { $s += ' @off' }
|
||||||
|
$entries += $s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ,$entries
|
||||||
|
}
|
||||||
|
|
||||||
function Build-DLParameter {
|
function Build-DLParameter {
|
||||||
param($pNode)
|
param($pNode)
|
||||||
$name = Get-Child $pNode 'name'
|
$name = Get-Child $pNode 'name'
|
||||||
@@ -1249,10 +1287,14 @@ function Build-DLParameter {
|
|||||||
$vtNode = $pNode.SelectSingleNode("dcssch:valueType", $ns)
|
$vtNode = $pNode.SelectSingleNode("dcssch:valueType", $ns)
|
||||||
$typeVal = $null
|
$typeVal = $null
|
||||||
if ($vtNode) { $typeVal = Decompile-Type $vtNode; if ($typeVal) { $o['type'] = $typeVal } }
|
if ($vtNode) { $typeVal = Decompile-Type $vtNode; if ($typeVal) { $o['type'] = $typeVal } }
|
||||||
# value — опускаем nil (дефолт)
|
# value — опускаем nil (дефолт), КРОМЕ valueListAllowed+nil: платформа пишет <value xsi:nil/>
|
||||||
|
# не всегда (корпус 27 с / 47 без), а компилятор при valueListAllowed по умолчанию его НЕ эмитит →
|
||||||
|
# явный маркер value:null, чтобы реэмитить nil. (Различается через Has-DLProp в компиляторе.)
|
||||||
$vNode = $pNode.SelectSingleNode("dcssch:value", $ns)
|
$vNode = $pNode.SelectSingleNode("dcssch:value", $ns)
|
||||||
if ($vNode -and ($vNode.GetAttribute("nil", $NS_XSI) -ne 'true')) {
|
if ($vNode -and ($vNode.GetAttribute("nil", $NS_XSI) -ne 'true')) {
|
||||||
$o['value'] = Convert-TypedValue -raw $vNode.InnerText -xsiType ($vNode.GetAttribute("type", $NS_XSI))
|
$o['value'] = Convert-TypedValue -raw $vNode.InnerText -xsiType ($vNode.GetAttribute("type", $NS_XSI))
|
||||||
|
} elseif ($vNode -and ((Get-Child $pNode 'valueListAllowed') -eq 'true')) {
|
||||||
|
$o['value'] = $null
|
||||||
}
|
}
|
||||||
# useRestriction — опускаем true (дефолт), фиксируем false
|
# useRestriction — опускаем true (дефолт), фиксируем false
|
||||||
if ((Get-Child $pNode 'useRestriction') -eq 'false') { $o['useRestriction'] = $false }
|
if ((Get-Child $pNode 'useRestriction') -eq 'false') { $o['useRestriction'] = $false }
|
||||||
@@ -2499,6 +2541,13 @@ if ($attrsNode) {
|
|||||||
$ca = Build-ConditionalAppearance -caNode $caNode -loc "settings/conditionalAppearance"
|
$ca = Build-ConditionalAppearance -caNode $caNode -loc "settings/conditionalAppearance"
|
||||||
if (@($ca).Count -gt 0) { $so['conditionalAppearance'] = @($ca) }
|
if (@($ca).Count -gt 0) { $so['conditionalAppearance'] = @($ca) }
|
||||||
}
|
}
|
||||||
|
# Параметры данных компоновки (dcsset:dataParameters) — значения параметров запроса в
|
||||||
|
# настройках. Грамматика как у СКД (shorthand "Имя @off" / объект). См. Build-FormDataParameters.
|
||||||
|
$dpNode = $lsNode.SelectSingleNode("dcsset:dataParameters", $ns)
|
||||||
|
if ($dpNode -and $dpNode.SelectSingleNode("dcscor:item", $ns)) {
|
||||||
|
$dp = Build-FormDataParameters $dpNode
|
||||||
|
if (@($dp).Count -gt 0) { $so['dataParameters'] = @($dp) }
|
||||||
|
}
|
||||||
# Форма скелета ListSettings: дескриптор только для НЕ-каноничных форм (частичные/минимальные).
|
# Форма скелета ListSettings: дескриптор только для НЕ-каноничных форм (частичные/минимальные).
|
||||||
# Канон → $null (компилятор регенерит полный скелет, как раньше).
|
# Канон → $null (компилятор регенерит полный скелет, как раньше).
|
||||||
$lsShape = Get-ListSettingsShape $lsNode
|
$lsShape = Get-ListSettingsShape $lsNode
|
||||||
|
|||||||
@@ -939,6 +939,7 @@ Forgiving-синонимы типа: XML-имя (`SpreadSheetDocumentField`) и
|
|||||||
| `parameters` | array | Параметры схемы запроса (`DataCompositionSchemaParameter`) — см. ниже |
|
| `parameters` | array | Параметры схемы запроса (`DataCompositionSchemaParameter`) — см. ниже |
|
||||||
| `order` | array | Сортировка списка (см. ниже) |
|
| `order` | array | Сортировка списка (см. ниже) |
|
||||||
| `filter` | array | Отбор списка (грамматика как в СКД) |
|
| `filter` | array | Отбор списка (грамматика как в СКД) |
|
||||||
|
| `dataParameters` | array | Значения параметров запроса в настройках (`<dcsset:dataParameters>`). **Грамматика как в СКД**: shorthand `"Имя = Значение @off @user"` или объект `{ parameter, value?, valueType?, use?, nilValue?, viewMode?, userSettingID?, userSettingPresentation? }`. В дин-списке частый паттерн — плейсхолдер отключённого параметра без значения: `"ИмяПараметра @off"` |
|
||||||
| `conditionalAppearance` | array | Условное оформление списка (грамматика как в СКД) |
|
| `conditionalAppearance` | array | Условное оформление списка (грамматика как в СКД) |
|
||||||
|
|
||||||
`ManualQuery` выводится из наличия `query` — отдельным ключом не задаётся.
|
`ManualQuery` выводится из наличия `query` — отдельным ключом не задаётся.
|
||||||
@@ -973,6 +974,8 @@ Forgiving-синонимы типа: XML-имя (`SpreadSheetDocumentField`) и
|
|||||||
|
|
||||||
Объектные ключи (как в СКД): `name`, `title`, `type`/`valueType`, `value`, `valueListAllowed`, `useRestriction`, `availableAsField`, `expression`, `availableValues` (`[{ value, presentation }]`), `inputParameters`, `denyIncompleteValues`, `use`.
|
Объектные ключи (как в СКД): `name`, `title`, `type`/`valueType`, `value`, `valueListAllowed`, `useRestriction`, `availableAsField`, `expression`, `availableValues` (`[{ value, presentation }]`), `inputParameters`, `denyIncompleteValues`, `use`.
|
||||||
|
|
||||||
|
> **`value: null` при `valueListAllowed: true`** — явный маркер «эмитить `<dcssch:value xsi:nil/>`». Платформа пишет nil-значение для valueListAllowed-параметра не всегда (корпус 27 с / 47 без); по умолчанию (ключ `value` отсутствует) компилятор его НЕ эмитит. Декомпилятор ставит `value: null`, когда оригинал содержит nil-тег.
|
||||||
|
|
||||||
#### order / filter / conditionalAppearance
|
#### order / filter / conditionalAppearance
|
||||||
|
|
||||||
Грамматика этих ключей идентична настройкам СКД — см. [skd-dsl-spec.md](skd-dsl-spec.md) (разделы filter / order / conditionalAppearance). Кратко:
|
Грамматика этих ключей идентична настройкам СКД — см. [skd-dsl-spec.md](skd-dsl-spec.md) (разделы filter / order / conditionalAppearance). Кратко:
|
||||||
|
|||||||
@@ -19,8 +19,10 @@
|
|||||||
"attributes": [
|
"attributes": [
|
||||||
{ "name": "Список", "type": "DynamicList", "useAlways": ["~Артикул", "Список.Code", "Description"], "settings": {
|
{ "name": "Список", "type": "DynamicList", "useAlways": ["~Артикул", "Список.Code", "Description"], "settings": {
|
||||||
"mainTable": "Catalog.Товары", "dynamicDataRead": true, "autoSaveUserSettings": false,
|
"mainTable": "Catalog.Товары", "dynamicDataRead": true, "autoSaveUserSettings": false,
|
||||||
|
"parameters": [ { "name": "ВыборТовара", "type": "CatalogRef.Товары", "valueListAllowed": true, "value": null } ],
|
||||||
"order": [ "Description", "Code desc" ],
|
"order": [ "Description", "Code desc" ],
|
||||||
"filter": [ "Артикул = _ @off @user", "Артикул like %тест%", "Description подобно %abc%" ],
|
"filter": [ "Артикул = _ @off @user", "Артикул like %тест%", "Description подобно %abc%" ],
|
||||||
|
"dataParameters": [ "ВыборТовара @off" ],
|
||||||
"conditionalAppearance": [ { "filter": ["Артикул = _"], "appearance": { "ЦветТекста": "web:Red" } } ]
|
"conditionalAppearance": [ { "filter": ["Артикул = _"], "appearance": { "ЦветТекста": "web:Red" } } ]
|
||||||
} }
|
} }
|
||||||
],
|
],
|
||||||
|
|||||||
+21
@@ -100,6 +100,21 @@
|
|||||||
<Settings xsi:type="DynamicList">
|
<Settings xsi:type="DynamicList">
|
||||||
<ManualQuery>false</ManualQuery>
|
<ManualQuery>false</ManualQuery>
|
||||||
<DynamicDataRead>true</DynamicDataRead>
|
<DynamicDataRead>true</DynamicDataRead>
|
||||||
|
<Parameter>
|
||||||
|
<dcssch:name>ВыборТовара</dcssch:name>
|
||||||
|
<dcssch:title xsi:type="v8:LocalStringType">
|
||||||
|
<v8:item>
|
||||||
|
<v8:lang>ru</v8:lang>
|
||||||
|
<v8:content>Выбор товара</v8:content>
|
||||||
|
</v8:item>
|
||||||
|
</dcssch:title>
|
||||||
|
<dcssch:valueType>
|
||||||
|
<v8:Type>cfg:CatalogRef.Товары</v8:Type>
|
||||||
|
</dcssch:valueType>
|
||||||
|
<dcssch:value xsi:nil="true"/>
|
||||||
|
<dcssch:useRestriction>true</dcssch:useRestriction>
|
||||||
|
<dcssch:valueListAllowed>true</dcssch:valueListAllowed>
|
||||||
|
</Parameter>
|
||||||
<MainTable>Catalog.Товары</MainTable>
|
<MainTable>Catalog.Товары</MainTable>
|
||||||
<AutoSaveUserSettings>false</AutoSaveUserSettings>
|
<AutoSaveUserSettings>false</AutoSaveUserSettings>
|
||||||
<ListSettings>
|
<ListSettings>
|
||||||
@@ -123,6 +138,12 @@
|
|||||||
<dcsset:viewMode>Normal</dcsset:viewMode>
|
<dcsset:viewMode>Normal</dcsset:viewMode>
|
||||||
<dcsset:userSettingID>UUID-003</dcsset:userSettingID>
|
<dcsset:userSettingID>UUID-003</dcsset:userSettingID>
|
||||||
</dcsset:filter>
|
</dcsset:filter>
|
||||||
|
<dcsset:dataParameters>
|
||||||
|
<dcscor:item xsi:type="dcsset:SettingsParameterValue">
|
||||||
|
<dcscor:use>false</dcscor:use>
|
||||||
|
<dcscor:parameter>ВыборТовара</dcscor:parameter>
|
||||||
|
</dcscor:item>
|
||||||
|
</dcsset:dataParameters>
|
||||||
<dcsset:order>
|
<dcsset:order>
|
||||||
<dcsset:item xsi:type="dcsset:OrderItemField">
|
<dcsset:item xsi:type="dcsset:OrderItemField">
|
||||||
<dcsset:field>Description</dcsset:field>
|
<dcsset:field>Description</dcsset:field>
|
||||||
|
|||||||
Reference in New Issue
Block a user