From 16199deb927f1ac311e7b1d936cdbbdf127bab3f Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Sun, 9 Aug 2026 18:06:34 +0300 Subject: [PATCH] =?UTF-8?q?fix(meta-compile,meta-validate):=20=D0=BA=D0=B0?= =?UTF-8?q?=D0=BD=D0=BE=D0=BD=20=D1=81=D1=82=D0=B0=D0=BD=D0=B4=D0=B0=D1=80?= =?UTF-8?q?=D1=82=D0=BD=D1=8B=D1=85=20=D1=80=D0=B5=D0=BA=D0=B2=D0=B8=D0=B7?= =?UTF-8?q?=D0=B8=D1=82=D0=BE=D0=B2=20=D1=80=D0=B5=D0=B3=D0=B8=D1=81=D1=82?= =?UTF-8?q?=D1=80=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Справочник порядка StandardAttributes был неполон у трёх видов регистров, а неизвестные имена эмитятся перед фикс-списком — платформа их вкрапляет, и роундтрип переставал быть побайтовым. Порядок снят с выгрузки платформы, присутствие условных реквизитов теперь выводится из свойств объекта (periodAdjustmentLength, correspondence, registerType), а не из наличия ключа в DSL: иначе регистр, создаваемый с нуля, терял реквизит, который платформа обязана материализовать. Наличие ключа осталось дополняющим условием, чтобы роундтрип не зависел от точности вывода. - регистр расчёта: 11 реквизитов, состав безусловен (проверено матрицей actionPeriod × basePeriod × периодичность на 8.3.27) - регистр бухгалтерии: PeriodAdjustment при длине периода корректировки > 0, RecordType при correspondence=false - регистр накопления: RecordType только у регистра остатков meta-validate: снято ложное предупреждение об «unexpected» RecordType у бухрегистра, условные реквизиты исключены из проверки missing. Проверка: 739 регистров по шести конфигурациям — 0 расхождений; снэпшоты пересняты и верифицированы загрузкой в 1С. Co-Authored-By: Claude Opus 5 (1M context) --- .../meta-compile/scripts/meta-compile.ps1 | 44 ++- .../meta-compile/scripts/meta-compile.py | 47 ++- .../meta-validate/scripts/meta-validate.ps1 | 23 +- .../meta-validate/scripts/meta-validate.py | 26 +- docs/meta-dsl-spec.md | 16 +- .../ДенежныеСредства.xml | 26 ++ ...accounting-register-no-correspondence.json | 16 + .../accumulation-register-turnovers.json | 14 + .../AccountingRegisters/Международный.xml | 326 +++++++++++++++++ .../Международный/Ext/RecordSetModule.bsl | 0 .../Configuration.xml | 252 +++++++++++++ .../Ext/ClientApplicationInterface.xml | 18 + .../Languages/Русский.xml | 16 + .../AccumulationRegisters/ПродажиОбороты.xml | 278 ++++++++++++++ .../ПродажиОбороты/Ext/RecordSetModule.bsl | 0 .../Configuration.xml | 252 +++++++++++++ .../Ext/ClientApplicationInterface.xml | 18 + .../Languages/Русский.xml | 16 + .../AccumulationRegisters/ОстаткиТоваров.xml | 26 ++ .../CalculationRegisters/Начисления.xml | 138 ++++++- .../CalculationRegisters/Начисления.xml | 338 ++++++++++++------ 21 files changed, 1730 insertions(+), 160 deletions(-) create mode 100644 tests/skills/cases/meta-compile/accounting-register-no-correspondence.json create mode 100644 tests/skills/cases/meta-compile/accumulation-register-turnovers.json create mode 100644 tests/skills/cases/meta-compile/snapshots/accounting-register-no-correspondence/AccountingRegisters/Международный.xml create mode 100644 tests/skills/cases/meta-compile/snapshots/accounting-register-no-correspondence/AccountingRegisters/Международный/Ext/RecordSetModule.bsl create mode 100644 tests/skills/cases/meta-compile/snapshots/accounting-register-no-correspondence/Configuration.xml create mode 100644 tests/skills/cases/meta-compile/snapshots/accounting-register-no-correspondence/Ext/ClientApplicationInterface.xml create mode 100644 tests/skills/cases/meta-compile/snapshots/accounting-register-no-correspondence/Languages/Русский.xml create mode 100644 tests/skills/cases/meta-compile/snapshots/accumulation-register-turnovers/AccumulationRegisters/ПродажиОбороты.xml create mode 100644 tests/skills/cases/meta-compile/snapshots/accumulation-register-turnovers/AccumulationRegisters/ПродажиОбороты/Ext/RecordSetModule.bsl create mode 100644 tests/skills/cases/meta-compile/snapshots/accumulation-register-turnovers/Configuration.xml create mode 100644 tests/skills/cases/meta-compile/snapshots/accumulation-register-turnovers/Ext/ClientApplicationInterface.xml create mode 100644 tests/skills/cases/meta-compile/snapshots/accumulation-register-turnovers/Languages/Русский.xml diff --git a/.claude/skills/meta-compile/scripts/meta-compile.ps1 b/.claude/skills/meta-compile/scripts/meta-compile.ps1 index 582fe5b2..ba21e34d 100644 --- a/.claude/skills/meta-compile/scripts/meta-compile.ps1 +++ b/.claude/skills/meta-compile/scripts/meta-compile.ps1 @@ -1,4 +1,4 @@ -# meta-compile v1.92 — Compile 1C metadata object from JSON (+write_xml_file/write_utf8_bom: общий эталон записи) +# meta-compile v1.93 — Compile 1C metadata object from JSON # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory)] @@ -1311,20 +1311,20 @@ $script:standardAttributesByType = @{ "Document" = @("Posted","Ref","DeletionMark","Date","Number") "Enum" = @("Order","Ref") "InformationRegister" = @("Active","LineNumber","Recorder","Period") - "AccumulationRegister" = @("Active","LineNumber","Recorder","Period") - "AccountingRegister" = @("PeriodAdjustment","Account","Active","LineNumber","Recorder","Period") - "CalculationRegister" = @("Active","Recorder","LineNumber","RegistrationPeriod","CalculationType","ReversingEntry") + "AccumulationRegister" = @("RecordType","Active","LineNumber","Recorder","Period") + "AccountingRegister" = @("PeriodAdjustment","Account","RecordType","Active","LineNumber","Recorder","Period") + "CalculationRegister" = @("RegistrationPeriod","ReversingEntry","Active","EndOfBasePeriod","BegOfBasePeriod","EndOfActionPeriod","BegOfActionPeriod","ActionPeriod","CalculationType","LineNumber","Recorder") "ChartOfAccounts" = @("PredefinedDataName","Order","OffBalance","Type","Description","Code","Parent","Predefined","DeletionMark","Ref") "ChartOfCharacteristicTypes" = @("PredefinedDataName","ValueType","Description","Code","IsFolder","Parent","Predefined","DeletionMark","Ref") "ChartOfCalculationTypes" = @("PredefinedDataName","Predefined","Ref","DeletionMark","ActionPeriodIsBasic","Description","Code") "BusinessProcess" = @("Started","HeadTask","Completed","Ref","DeletionMark","Date","Number") "Task" = @("Executed","Description","RoutePoint","BusinessProcess","Ref","DeletionMark","Date","Number") # Порядок в каждом списке — канон выгрузки, снят с корпуса acc+erp (внутри типа разброса нет). - # Условные члены перечислены в $script:stdAttrOptional — они эмитятся только при наличии - # ключа в DSL, но позицию берут отсюда. + # Условные члены перечислены в $script:stdAttrConditions — позицию они берут отсюда, а + # присутствие определяется свойствами объекта. # У ПВХ IsFolder входит в фикс-список: он есть у всех 23 объектов корпуса с этим блоком. - # У бухрегистра PeriodAdjustment, наоборот, условен (1 из 3) — он приходит как «лишний» - # ключ и эмитится ПЕРЕД фикс-списком, что совпадает с платформой. + # У регистра расчёта список безусловен: реквизиты периода действия и базового периода + # платформа пишет при любых ActionPeriod/BasePeriod/Periodicity (синтетика, все 4 комбинации). "ExchangePlan" = @("ThisNode","ReceivedNo","SentNo","Ref","DeletionMark","Description","Code") "DocumentJournal" = @("Type","Ref","Date","Posted","DeletionMark","Number") } @@ -1445,10 +1445,17 @@ function Emit-StandardAttribute { # Миграция типа = добавить его в stdAttrConditionalTypes + stdAttrProfile и переснять снэпшоты; КОД НЕ ТРОГАЕМ. $script:stdAttrConditionalTypes = @('Catalog', 'ExchangePlan', 'ChartOfCharacteristicTypes', 'ChartOfAccounts', 'ChartOfCalculationTypes', 'Document') -# Условные члены списка типа: позиция берётся из $script:standardAttributesByType, а сам -# реквизит эмитится только при наличии ключа в DSL (у бухрегистра PeriodAdjustment — 2 из 5). -$script:stdAttrOptional = @{ - "AccountingRegister" = @("PeriodAdjustment") +# Условные члены списка типа: позиция берётся из $script:standardAttributesByType, а присутствие — +# из свойств самого объекта, как у платформы. Предикат ОБЯЗАН принимать определение параметром: +# scriptblock не видит $def вызывающей функции, и отказ был бы молчаливым. +$script:stdAttrConditions = @{ + "AccountingRegister" = @{ + "PeriodAdjustment" = { param($d) $v = 0; if ($null -ne $d.periodAdjustmentLength) { $v = [int]"$($d.periodAdjustmentLength)" }; $v -gt 0 } + "RecordType" = { param($d) -not ($d.correspondence -eq $true) } + } + "AccumulationRegister" = @{ + "RecordType" = { param($d) $raw = if ($d.registerType) { "$($d.registerType)" } else { "Balance" }; (Normalize-EnumValue "RegisterType" $raw) -eq "Balance" } + } } # Хвостовая группа: реквизиты, которых нет в списке типа и которые идут ПОСЛЕ него. @@ -1469,9 +1476,9 @@ function Emit-StandardAttributes { $profile = $script:stdAttrProfile[$objectType]; if (-not $profile) { $profile = @{} } # Список типа задаёт ПОРЯДОК всех известных стандартных реквизитов, включая условные: # их позиция бывает и до, и после обязательных (у бухрегистра PeriodAdjustment идёт - # перед Account, а ExtDimension1..3/ExtDimensionType1..3 — после Period), поэтому - # «условные скопом вперёд» не выражает канон. Условный эмитим по факту наличия в DSL. - $optional = $script:stdAttrOptional[$objectType]; if (-not $optional) { $optional = @() } + # перед Account, RecordType — после, а ExtDimension1..3/ExtDimensionType1..3 — после Period), + # поэтому «условные скопом вперёд» не выражает канон. + $cond = $script:stdAttrConditions[$objectType] # Ключи, которых нет в списке типа ВООБЩЕ. По умолчанию их позиция — ПЕРЕД списком # (легаси вроде ExchangeDate у части планов обмена). Подходящие под хвостовой шаблон # типа идут ПОСЛЕ, в порядке номера, а внутри номера — сначала ExtDimensionN, затем @@ -1487,7 +1494,12 @@ function Emit-StandardAttributes { $tail = @($tail | Sort-Object @{e={[int]([regex]::Match($_, '\d+').Value)}}, @{e={ if ($_ -match 'Type\d+$') { 1 } else { 0 } }}) X "$indent" foreach ($a in ($extra + $attrs + $tail)) { - if (($optional -contains $a) -and (-not ($sa -and $sa.PSObject.Properties[$a]))) { continue } + # Условный реквизит: эмитим, если так велят свойства объекта ЛИБО если ключ есть в DSL. + # Дизъюнкция страхует роундтрип — декомпилятор перечисляет все имена блока. + if ($cond -and $cond.ContainsKey($a)) { + $present = ($sa -and $sa.PSObject.Properties[$a]) -or (& $cond[$a] $def) + if (-not $present) { continue } + } $ov = @{} if ($profile.ContainsKey($a)) { foreach ($k in $profile[$a].Keys) { $ov[$k] = $profile[$a][$k] } } if ($sa) { # DSL-override применяем всегда при наличии ключа (для не-условных типов тоже, напр. ExchangePlan) diff --git a/.claude/skills/meta-compile/scripts/meta-compile.py b/.claude/skills/meta-compile/scripts/meta-compile.py index e9da38a1..8ce65dff 100644 --- a/.claude/skills/meta-compile/scripts/meta-compile.py +++ b/.claude/skills/meta-compile/scripts/meta-compile.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# meta-compile v1.92 — Compile 1C metadata object from JSON (+write_xml_file/write_utf8_bom: общий эталон записи) +# meta-compile v1.93 — Compile 1C metadata object from JSON # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse @@ -1350,16 +1350,18 @@ standard_attributes_by_type = { 'Document': ['Posted', 'Ref', 'DeletionMark', 'Date', 'Number'], 'Enum': ['Order', 'Ref'], 'InformationRegister': ['Active', 'LineNumber', 'Recorder', 'Period'], - 'AccumulationRegister': ['Active', 'LineNumber', 'Recorder', 'Period'], - 'AccountingRegister': ['PeriodAdjustment', 'Account', 'Active', 'LineNumber', 'Recorder', 'Period'], - 'CalculationRegister': ['Active', 'Recorder', 'LineNumber', 'RegistrationPeriod', 'CalculationType', 'ReversingEntry'], + 'AccumulationRegister': ['RecordType', 'Active', 'LineNumber', 'Recorder', 'Period'], + 'AccountingRegister': ['PeriodAdjustment', 'Account', 'RecordType', 'Active', 'LineNumber', 'Recorder', 'Period'], + 'CalculationRegister': ['RegistrationPeriod', 'ReversingEntry', 'Active', 'EndOfBasePeriod', 'BegOfBasePeriod', 'EndOfActionPeriod', 'BegOfActionPeriod', 'ActionPeriod', 'CalculationType', 'LineNumber', 'Recorder'], 'ChartOfAccounts': ['PredefinedDataName', 'Order', 'OffBalance', 'Type', 'Description', 'Code', 'Parent', 'Predefined', 'DeletionMark', 'Ref'], 'ChartOfCharacteristicTypes': ['PredefinedDataName', 'ValueType', 'Description', 'Code', 'IsFolder', 'Parent', 'Predefined', 'DeletionMark', 'Ref'], 'ChartOfCalculationTypes': ['PredefinedDataName', 'Predefined', 'Ref', 'DeletionMark', 'ActionPeriodIsBasic', 'Description', 'Code'], # Порядок в каждом списке — канон выгрузки, снят с корпуса acc+erp (внутри типа разброса нет). + # Условные члены перечислены в std_attr_conditions — позицию они берут отсюда, а + # присутствие определяется свойствами объекта. # У ПВХ IsFolder входит в фикс-список: он есть у всех 23 объектов корпуса с этим блоком. - # У бухрегистра PeriodAdjustment, наоборот, условен (1 из 3) — он приходит как «лишний» - # ключ и эмитится ПЕРЕД фикс-списком, что совпадает с платформой. + # У регистра расчёта список безусловен: реквизиты периода действия и базового периода + # платформа пишет при любых ActionPeriod/BasePeriod/Periodicity (синтетика, все 4 комбинации). 'BusinessProcess': ['Started', 'HeadTask', 'Completed', 'Ref', 'DeletionMark', 'Date', 'Number'], 'Task': ['Executed', 'Description', 'RoutePoint', 'BusinessProcess', 'Ref', 'DeletionMark', 'Date', 'Number'], # Порядок снят с выгрузки: у плана обмена блок начинается с ThisNode, а не с Ref @@ -1486,10 +1488,21 @@ def emit_standard_attribute(indent, attr_name, ov=None): # Прочие типы → блок всегда (текущее поведение). Миграция типа = +строчка в оба справочника + снэпшоты. std_attr_conditional_types = {'Catalog', 'ExchangePlan', 'ChartOfCharacteristicTypes', 'ChartOfAccounts', 'ChartOfCalculationTypes', 'Document'} -# Условные члены списка типа: позиция берётся из standard_attributes_by_type, а сам -# реквизит эмитится только при наличии ключа в DSL (у бухрегистра PeriodAdjustment — 2 из 5). -std_attr_optional = { - 'AccountingRegister': ('PeriodAdjustment',), +# Условные члены списка типа: позиция берётся из standard_attributes_by_type, а присутствие — +# из свойств самого объекта, как у платформы. Предикат принимает определение параметром +# (зеркало .ps1, где scriptblock не видит $def вызывающей функции). +def _period_adjustment_used(d): + v = d.get('periodAdjustmentLength') + return v is not None and int(str(v)) > 0 + +std_attr_conditions = { + 'AccountingRegister': { + 'PeriodAdjustment': _period_adjustment_used, + 'RecordType': lambda d: d.get('correspondence') is not True, + }, + 'AccumulationRegister': { + 'RecordType': lambda d: normalize_enum_value('RegisterType', str(d.get('registerType') or 'Balance')) == 'Balance', + }, } # Хвостовая группа: реквизиты, которых нет в списке типа и которые идут ПОСЛЕ него. @@ -1512,9 +1525,9 @@ def emit_standard_attributes(indent, object_type): profile = std_attr_profile.get(object_type, {}) # Список типа задаёт ПОРЯДОК всех известных стандартных реквизитов, включая условные: # их позиция бывает и до, и после обязательных (у бухрегистра PeriodAdjustment идёт - # перед Account, а ExtDimension1..3/ExtDimensionType1..3 — после Period), поэтому - # «условные скопом вперёд» не выражает канон. Условный эмитим по факту наличия в DSL. - optional = std_attr_optional.get(object_type, ()) + # перед Account, RecordType — после, а ExtDimension1..3/ExtDimensionType1..3 — после Period), + # поэтому «условные скопом вперёд» не выражает канон. + cond = std_attr_conditions.get(object_type) # Ключи, которых нет в списке типа ВООБЩЕ. По умолчанию их позиция — ПЕРЕД списком # (легаси вроде ExchangeDate у части планов обмена). Подходящие под хвостовой шаблон # типа идут ПОСЛЕ, в порядке номера, а внутри номера — сначала ExtDimensionN, затем @@ -1532,8 +1545,12 @@ def emit_standard_attributes(indent, object_type): tail.sort(key=lambda k: (int(re.search(r'\d+', k).group()), 1 if re.search(r'Type\d+$', k) else 0)) X(f'{indent}') for a in extra + list(attrs) + tail: - if a in optional and not (isinstance(sa, dict) and a in sa): - continue + # Условный реквизит: эмитим, если так велят свойства объекта ЛИБО если ключ есть в DSL. + # Дизъюнкция страхует роундтрип — декомпилятор перечисляет все имена блока. + if cond and a in cond: + present = (isinstance(sa, dict) and a in sa) or cond[a](defn) + if not present: + continue ov = dict(profile.get(a, {})) if isinstance(sa, dict): d = sa.get(a) diff --git a/.claude/skills/meta-validate/scripts/meta-validate.ps1 b/.claude/skills/meta-validate/scripts/meta-validate.ps1 index faa4afad..f5ea46bc 100644 --- a/.claude/skills/meta-validate/scripts/meta-validate.ps1 +++ b/.claude/skills/meta-validate/scripts/meta-validate.ps1 @@ -1,4 +1,4 @@ -# meta-validate v1.16 — Validate 1C metadata object structure (+format_rank: свести к общему эталону) +# meta-validate v1.17 — Validate 1C metadata object structure # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory)] @@ -209,7 +209,7 @@ $standardAttributesByType = @{ "Enum" = @("Order","Ref") "InformationRegister" = @("Active","LineNumber","Recorder","Period") "AccumulationRegister" = @("Active","LineNumber","Recorder","Period","RecordType") - "AccountingRegister" = @("Active","Period","Recorder","LineNumber","Account") + "AccountingRegister" = @("Active","Period","Recorder","LineNumber","Account","PeriodAdjustment","RecordType") "CalculationRegister" = @("Active","Recorder","LineNumber","RegistrationPeriod","CalculationType","ReversingEntry","ActionPeriod","BegOfActionPeriod","EndOfActionPeriod","BegOfBasePeriod","EndOfBasePeriod") "ChartOfAccounts" = @("PredefinedDataName","Predefined","Ref","DeletionMark","Description","Code","Parent","Order","Type","OffBalance") "ChartOfCharacteristicTypes" = @("PredefinedDataName","Predefined","Ref","DeletionMark","Description","Code","Parent","IsFolder","ValueType") @@ -220,6 +220,14 @@ $standardAttributesByType = @{ "DocumentJournal" = @("Type","Ref","Date","Posted","DeletionMark","Number") } +# Стандартные реквизиты, присутствие которых зависит от свойств объекта: у бухрегистра +# PeriodAdjustment — от длины периода корректировки, RecordType — от корреспонденции; у регистра +# накопления RecordType — от вида регистра. Их отсутствие законно, в «Missing» не попадают. +$stdAttrConditionalNames = @{ + "AccountingRegister" = @("PeriodAdjustment","RecordType") + "AccumulationRegister" = @("RecordType") +} + # Types that have StandardAttributes block $typesWithStdAttrs = @( "Catalog","Document","Enum", @@ -607,11 +615,9 @@ if ($typesWithStdAttrs -contains $mdType) { if ($saName) { $foundNames += $saName if ($expectedStdAttrs -notcontains $saName) { - # AccountingRegister has dynamic ExtDimension{N}/ExtDimensionType{N} and optional PeriodAdjustment - $isDynamic = ($mdType -eq "AccountingRegister" -and ($saName -match '^ExtDimension\d+$' -or $saName -match '^ExtDimensionType\d+$' -or $saName -eq "PeriodAdjustment")) - # CalculationRegister has conditional period attrs - $isCalcDynamic = ($mdType -eq "CalculationRegister" -and $saName -in @("ActionPeriod","BegOfActionPeriod","EndOfActionPeriod","BegOfBasePeriod","EndOfBasePeriod")) - if (-not $isDynamic -and -not $isCalcDynamic) { + # AccountingRegister: пары субконто, число которых задаётся планом счетов + $isDynamic = ($mdType -eq "AccountingRegister" -and ($saName -match '^ExtDimension\d+$' -or $saName -match '^ExtDimensionType\d+$')) + if (-not $isDynamic) { Report-Warn "5. Unexpected StandardAttribute '$saName' for $mdType" } } @@ -622,7 +628,8 @@ if ($typesWithStdAttrs -contains $mdType) { } if ($expectedStdAttrs) { - $missingAttrs = @($expectedStdAttrs | Where-Object { $foundNames -notcontains $_ }) + $condNames = $stdAttrConditionalNames[$mdType]; if (-not $condNames) { $condNames = @() } + $missingAttrs = @($expectedStdAttrs | Where-Object { $foundNames -notcontains $_ -and $condNames -notcontains $_ }) if ($missingAttrs.Count -gt 0) { Report-Warn "5. Missing StandardAttributes: $($missingAttrs -join ', ')" } diff --git a/.claude/skills/meta-validate/scripts/meta-validate.py b/.claude/skills/meta-validate/scripts/meta-validate.py index 3803cf99..be177063 100644 --- a/.claude/skills/meta-validate/scripts/meta-validate.py +++ b/.claude/skills/meta-validate/scripts/meta-validate.py @@ -1,4 +1,4 @@ -# meta-validate v1.16 — Validate 1C metadata object structure (Python port) (+format_rank: свести к общему эталону) +# meta-validate v1.17 — Validate 1C metadata object structure (Python port) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import os @@ -209,7 +209,7 @@ standard_attributes_by_type = { "Enum": ["Order", "Ref"], "InformationRegister": ["Active", "LineNumber", "Recorder", "Period"], "AccumulationRegister": ["Active", "LineNumber", "Recorder", "Period", "RecordType"], - "AccountingRegister": ["Active", "Period", "Recorder", "LineNumber", "Account"], + "AccountingRegister": ["Active", "Period", "Recorder", "LineNumber", "Account", "PeriodAdjustment", "RecordType"], "CalculationRegister": ["Active", "Recorder", "LineNumber", "RegistrationPeriod", "CalculationType", "ReversingEntry", "ActionPeriod", "BegOfActionPeriod", "EndOfActionPeriod", "BegOfBasePeriod", "EndOfBasePeriod"], "ChartOfAccounts": ["PredefinedDataName", "Predefined", "Ref", "DeletionMark", "Description", "Code", "Parent", "Order", "Type", "OffBalance"], "ChartOfCharacteristicTypes": ["PredefinedDataName", "Predefined", "Ref", "DeletionMark", "Description", "Code", "Parent", "IsFolder", "ValueType"], @@ -220,6 +220,14 @@ standard_attributes_by_type = { "DocumentJournal": ["Type", "Ref", "Date", "Posted", "DeletionMark", "Number"], } +# Стандартные реквизиты, присутствие которых зависит от свойств объекта: у бухрегистра +# PeriodAdjustment — от длины периода корректировки, RecordType — от корреспонденции; у регистра +# накопления RecordType — от вида регистра. Их отсутствие законно, в «Missing» не попадают. +std_attr_conditional_names = { + "AccountingRegister": ("PeriodAdjustment", "RecordType"), + "AccumulationRegister": ("RecordType",), +} + # Types that have StandardAttributes block types_with_std_attrs = ( "Catalog", "Document", "Enum", @@ -595,23 +603,19 @@ if md_type in types_with_std_attrs: if sa_name: found_names.append(sa_name) if sa_name not in expected_std_attrs: - # AccountingRegister has dynamic attrs + # AccountingRegister: пары субконто, число которых задаётся планом счетов is_dynamic = (md_type == "AccountingRegister" and (re.match(r'^ExtDimension\d+$', sa_name) or - re.match(r'^ExtDimensionType\d+$', sa_name) or - sa_name == "PeriodAdjustment")) - # CalculationRegister has conditional period attrs - is_calc_dynamic = (md_type == "CalculationRegister" and - sa_name in ("ActionPeriod", "BegOfActionPeriod", "EndOfActionPeriod", - "BegOfBasePeriod", "EndOfBasePeriod")) - if not is_dynamic and not is_calc_dynamic: + re.match(r'^ExtDimensionType\d+$', sa_name))) + if not is_dynamic: report_warn(f"5. Unexpected StandardAttribute '{sa_name}' for {md_type}") else: report_error("5. StandardAttribute without 'name' attribute") check5_ok = False if expected_std_attrs: - missing_attrs = [a for a in expected_std_attrs if a not in found_names] + cond_names = std_attr_conditional_names.get(md_type, ()) + missing_attrs = [a for a in expected_std_attrs if a not in found_names and a not in cond_names] if missing_attrs: report_warn(f"5. Missing StandardAttributes: {', '.join(missing_attrs)}") diff --git a/docs/meta-dsl-spec.md b/docs/meta-dsl-spec.md index 3ad852fd..bc77c342 100644 --- a/docs/meta-dsl-spec.md +++ b/docs/meta-dsl-spec.md @@ -944,6 +944,9 @@ choiceParameters/indexing/fullTextSearch/dataHistory/…, см. §3–4). При Признаки измерения — флаги shorthand (`denyIncomplete`, `nouseintotals`) ЛИБО object-ключи (`denyIncompleteValues`, `useInTotals`: bool, дефолт true). Ресурс РН НЕ имеет `` (только ``). +Стандартные реквизиты РН: RecordType, Active, LineNumber, Recorder, Period — в этом порядке. +`RecordType` есть только у регистра остатков (`registerType=Balance`); у оборотного его нет. + ### 7.6a AccountingRegister (Регистр бухгалтерии) | Поле JSON | Умолчание | XML элемент | @@ -957,8 +960,13 @@ choiceParameters/indexing/fullTextSearch/dataHistory/…, см. §3–4). При | `dimensions` / `resources` / `attributes` / `commands` | `[]` | → ChildObjects | Измерения/ресурсы РБ несут `balance` (bool), `accountingFlag` (ссылка `ChartOfAccounts.X.AccountingFlag.Y`); -ресурсы дополнительно `extDimensionAccountingFlag`, измерения — `denyIncompleteValues`. Стандартные реквизиты -ExtDimension1..N связаны с Account через `linkByType` (в блоке `standardAttributes`, §7.1.1; DataPath полный). +ресурсы дополнительно `extDimensionAccountingFlag`, измерения — `denyIncompleteValues`. + +Стандартные реквизиты РБ: PeriodAdjustment, Account, RecordType, Active, LineNumber, Recorder, Period, +далее пары субконто ExtDimensionN/ExtDimensionTypeN (их число задаётся `maxExtDimensionCount` плана счетов). +Два реквизита условны: `PeriodAdjustment` — при `periodAdjustmentLength > 0`, `RecordType` — при +`correspondence=false`. ExtDimension1..N связаны с Account через `linkByType` (в блоке `standardAttributes`, +§7.1.1; DataPath полный). ### 7.6b CalculationRegister (Регистр расчёта) @@ -975,6 +983,10 @@ ExtDimension1..N связаны с Account через `linkByType` (в блок Измерения РР несут `denyIncompleteValues`, `baseDimension` (bool), `scheduleLink` (ссылка на измерение графика); реквизиты — `scheduleLink`; ресурсы — только `` (без Indexing). +Стандартные реквизиты РР: RegistrationPeriod, ReversingEntry, Active, EndOfBasePeriod, BegOfBasePeriod, +EndOfActionPeriod, BegOfActionPeriod, ActionPeriod, CalculationType, LineNumber, Recorder — в этом порядке +и все сразу, независимо от `actionPeriod` / `basePeriod` / `periodicity`. + ### 7.6c BusinessProcess (Бизнес-процесс) Ссылочный тип с нумерацией (Document-стиль). Поля: `numberType`/`numberLength`/`numberAllowedLength`/`checkUnique`/ diff --git a/tests/skills/cases/form-compile-from-object/snapshots/accumreg-list-simple/AccumulationRegisters/ДенежныеСредства.xml b/tests/skills/cases/form-compile-from-object/snapshots/accumreg-list-simple/AccumulationRegisters/ДенежныеСредства.xml index 2514dc1c..3772e3ae 100644 --- a/tests/skills/cases/form-compile-from-object/snapshots/accumreg-list-simple/AccumulationRegisters/ДенежныеСредства.xml +++ b/tests/skills/cases/form-compile-from-object/snapshots/accumreg-list-simple/AccumulationRegisters/ДенежныеСредства.xml @@ -42,6 +42,32 @@ Balance false + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + DontCheck diff --git a/tests/skills/cases/meta-compile/accounting-register-no-correspondence.json b/tests/skills/cases/meta-compile/accounting-register-no-correspondence.json new file mode 100644 index 00000000..90c0037b --- /dev/null +++ b/tests/skills/cases/meta-compile/accounting-register-no-correspondence.json @@ -0,0 +1,16 @@ +{ + "name": "Регистр бухгалтерии без корреспонденции и с периодом корректировки", + "input": { + "type": "AccountingRegister", + "name": "Международный", + "chartOfAccounts": "ChartOfAccounts.Международный", + "correspondence": false, + "periodAdjustmentLength": 1, + "dimensions": ["Организация: CatalogRef.Организации"], + "resources": ["Сумма: Number(15,2)"] + }, + "validatePath": "AccountingRegisters/Международный", + "expect": { + "files": ["AccountingRegisters/Международный.xml", "AccountingRegisters/Международный/Ext/RecordSetModule.bsl"] + } +} diff --git a/tests/skills/cases/meta-compile/accumulation-register-turnovers.json b/tests/skills/cases/meta-compile/accumulation-register-turnovers.json new file mode 100644 index 00000000..554b16e4 --- /dev/null +++ b/tests/skills/cases/meta-compile/accumulation-register-turnovers.json @@ -0,0 +1,14 @@ +{ + "name": "Оборотный регистр накопления (без ВидДвижения)", + "input": { + "type": "AccumulationRegister", + "name": "ПродажиОбороты", + "registerType": "Turnovers", + "dimensions": ["Номенклатура: CatalogRef.Номенклатура"], + "resources": ["Количество: Number(15,3)", "Сумма: Number(15,2)"] + }, + "validatePath": "AccumulationRegisters/ПродажиОбороты", + "expect": { + "files": ["AccumulationRegisters/ПродажиОбороты.xml", "AccumulationRegisters/ПродажиОбороты/Ext/RecordSetModule.bsl"] + } +} diff --git a/tests/skills/cases/meta-compile/snapshots/accounting-register-no-correspondence/AccountingRegisters/Международный.xml b/tests/skills/cases/meta-compile/snapshots/accounting-register-no-correspondence/AccountingRegisters/Международный.xml new file mode 100644 index 00000000..75f67f34 --- /dev/null +++ b/tests/skills/cases/meta-compile/snapshots/accounting-register-no-correspondence/AccountingRegisters/Международный.xml @@ -0,0 +1,326 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + UUID-006 + UUID-007 + + + UUID-008 + UUID-009 + + + UUID-010 + UUID-011 + + + UUID-012 + UUID-013 + + + UUID-014 + UUID-015 + + + + Международный + + + ru + Международный + + + + true + false + ChartOfAccounts.Международный + false + 1 + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + Managed + true + Use + + + + + + + + Организация + + + ru + Организация + + + + + cfg:CatalogRef.Организации + + false + + + + false + + false + false + + + DontCheck + Items + + + Auto + Auto + + + Auto + false + + false + DontIndex + Use + + + + + Сумма + + + ru + Сумма + + + + + xs:decimal + + 15 + 2 + Any + + + false + + + + false + + false + false + + + DontCheck + Items + + + Auto + Auto + + + Auto + false + + + Use + + + + + \ No newline at end of file diff --git a/tests/skills/cases/meta-compile/snapshots/accounting-register-no-correspondence/AccountingRegisters/Международный/Ext/RecordSetModule.bsl b/tests/skills/cases/meta-compile/snapshots/accounting-register-no-correspondence/AccountingRegisters/Международный/Ext/RecordSetModule.bsl new file mode 100644 index 00000000..e69de29b diff --git a/tests/skills/cases/meta-compile/snapshots/accounting-register-no-correspondence/Configuration.xml b/tests/skills/cases/meta-compile/snapshots/accounting-register-no-correspondence/Configuration.xml new file mode 100644 index 00000000..25118f5b --- /dev/null +++ b/tests/skills/cases/meta-compile/snapshots/accounting-register-no-correspondence/Configuration.xml @@ -0,0 +1,252 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + UUID-006 + UUID-007 + + + UUID-008 + UUID-009 + + + UUID-010 + UUID-011 + + + UUID-012 + UUID-013 + + + UUID-014 + UUID-015 + + + + TestConfig + + + ru + TestConfig + + + + + Version8_3_24 + ManagedApplication + + PlatformApplication + + Russian + + + + + false + false + false + + + + + + + + + + + + + + + + + + + + + + Biometrics + true + + + Location + false + + + BackgroundLocation + false + + + BluetoothPrinters + false + + + WiFiPrinters + false + + + Contacts + false + + + Calendars + false + + + PushNotifications + false + + + LocalNotifications + false + + + InAppPurchases + false + + + PersonalComputerFileExchange + false + + + Ads + false + + + NumberDialing + false + + + CallProcessing + false + + + CallLog + false + + + AutoSendSMS + false + + + ReceiveSMS + false + + + SMSLog + false + + + Camera + false + + + Microphone + false + + + MusicLibrary + false + + + PictureAndVideoLibraries + false + + + AudioPlaybackAndVibration + false + + + BackgroundAudioPlaybackAndVibration + false + + + InstallPackages + false + + + OSBackup + true + + + ApplicationUsageStatistics + false + + + BarcodeScanning + false + + + BackgroundAudioRecording + false + + + AllFilesAccess + false + + + Videoconferences + false + + + NFC + false + + + DocumentScanning + false + + + SpeechToText + false + + + Geofences + false + + + IncomingShareRequests + false + + + AllIncomingShareRequestsTypesProcessing + false + + + + + + Normal + + + Language.Русский + + + + + + Managed + NotAutoFree + DontUse + DontUse + TaxiEnableVersion8_2 + DontUse + Version8_3_24 + + + + Русский + Международный + + + \ No newline at end of file diff --git a/tests/skills/cases/meta-compile/snapshots/accounting-register-no-correspondence/Ext/ClientApplicationInterface.xml b/tests/skills/cases/meta-compile/snapshots/accounting-register-no-correspondence/Ext/ClientApplicationInterface.xml new file mode 100644 index 00000000..3c1161b2 --- /dev/null +++ b/tests/skills/cases/meta-compile/snapshots/accounting-register-no-correspondence/Ext/ClientApplicationInterface.xml @@ -0,0 +1,18 @@ + + + + + UUID-002 + + + + + UUID-004 + + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/meta-compile/snapshots/accounting-register-no-correspondence/Languages/Русский.xml b/tests/skills/cases/meta-compile/snapshots/accounting-register-no-correspondence/Languages/Русский.xml new file mode 100644 index 00000000..37c60d78 --- /dev/null +++ b/tests/skills/cases/meta-compile/snapshots/accounting-register-no-correspondence/Languages/Русский.xml @@ -0,0 +1,16 @@ + + + + + Русский + + + ru + Русский + + + + ru + + + \ No newline at end of file diff --git a/tests/skills/cases/meta-compile/snapshots/accumulation-register-turnovers/AccumulationRegisters/ПродажиОбороты.xml b/tests/skills/cases/meta-compile/snapshots/accumulation-register-turnovers/AccumulationRegisters/ПродажиОбороты.xml new file mode 100644 index 00000000..e62576b9 --- /dev/null +++ b/tests/skills/cases/meta-compile/snapshots/accumulation-register-turnovers/AccumulationRegisters/ПродажиОбороты.xml @@ -0,0 +1,278 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + UUID-006 + UUID-007 + + + UUID-008 + UUID-009 + + + UUID-010 + UUID-011 + + + UUID-012 + UUID-013 + + + + ПродажиОбороты + + + ru + Продажи обороты + + + + true + + + Turnovers + false + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + Managed + Use + true + + + + + + + + Количество + + + ru + Количество + + + + + xs:decimal + + 15 + 3 + Any + + + false + + + + false + + false + false + + + DontCheck + Items + + + Auto + Auto + + + Auto + Use + + + + + Сумма + + + ru + Сумма + + + + + xs:decimal + + 15 + 2 + Any + + + false + + + + false + + false + false + + + DontCheck + Items + + + Auto + Auto + + + Auto + Use + + + + + Номенклатура + + + ru + Номенклатура + + + + + cfg:CatalogRef.Номенклатура + + false + + + + false + + false + false + + + DontCheck + Items + + + Auto + Auto + + + Auto + false + DontIndex + Use + true + + + + + \ No newline at end of file diff --git a/tests/skills/cases/meta-compile/snapshots/accumulation-register-turnovers/AccumulationRegisters/ПродажиОбороты/Ext/RecordSetModule.bsl b/tests/skills/cases/meta-compile/snapshots/accumulation-register-turnovers/AccumulationRegisters/ПродажиОбороты/Ext/RecordSetModule.bsl new file mode 100644 index 00000000..e69de29b diff --git a/tests/skills/cases/meta-compile/snapshots/accumulation-register-turnovers/Configuration.xml b/tests/skills/cases/meta-compile/snapshots/accumulation-register-turnovers/Configuration.xml new file mode 100644 index 00000000..b311c0a3 --- /dev/null +++ b/tests/skills/cases/meta-compile/snapshots/accumulation-register-turnovers/Configuration.xml @@ -0,0 +1,252 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + UUID-006 + UUID-007 + + + UUID-008 + UUID-009 + + + UUID-010 + UUID-011 + + + UUID-012 + UUID-013 + + + UUID-014 + UUID-015 + + + + TestConfig + + + ru + TestConfig + + + + + Version8_3_24 + ManagedApplication + + PlatformApplication + + Russian + + + + + false + false + false + + + + + + + + + + + + + + + + + + + + + + Biometrics + true + + + Location + false + + + BackgroundLocation + false + + + BluetoothPrinters + false + + + WiFiPrinters + false + + + Contacts + false + + + Calendars + false + + + PushNotifications + false + + + LocalNotifications + false + + + InAppPurchases + false + + + PersonalComputerFileExchange + false + + + Ads + false + + + NumberDialing + false + + + CallProcessing + false + + + CallLog + false + + + AutoSendSMS + false + + + ReceiveSMS + false + + + SMSLog + false + + + Camera + false + + + Microphone + false + + + MusicLibrary + false + + + PictureAndVideoLibraries + false + + + AudioPlaybackAndVibration + false + + + BackgroundAudioPlaybackAndVibration + false + + + InstallPackages + false + + + OSBackup + true + + + ApplicationUsageStatistics + false + + + BarcodeScanning + false + + + BackgroundAudioRecording + false + + + AllFilesAccess + false + + + Videoconferences + false + + + NFC + false + + + DocumentScanning + false + + + SpeechToText + false + + + Geofences + false + + + IncomingShareRequests + false + + + AllIncomingShareRequestsTypesProcessing + false + + + + + + Normal + + + Language.Русский + + + + + + Managed + NotAutoFree + DontUse + DontUse + TaxiEnableVersion8_2 + DontUse + Version8_3_24 + + + + Русский + ПродажиОбороты + + + \ No newline at end of file diff --git a/tests/skills/cases/meta-compile/snapshots/accumulation-register-turnovers/Ext/ClientApplicationInterface.xml b/tests/skills/cases/meta-compile/snapshots/accumulation-register-turnovers/Ext/ClientApplicationInterface.xml new file mode 100644 index 00000000..3c1161b2 --- /dev/null +++ b/tests/skills/cases/meta-compile/snapshots/accumulation-register-turnovers/Ext/ClientApplicationInterface.xml @@ -0,0 +1,18 @@ + + + + + UUID-002 + + + + + UUID-004 + + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/meta-compile/snapshots/accumulation-register-turnovers/Languages/Русский.xml b/tests/skills/cases/meta-compile/snapshots/accumulation-register-turnovers/Languages/Русский.xml new file mode 100644 index 00000000..37c60d78 --- /dev/null +++ b/tests/skills/cases/meta-compile/snapshots/accumulation-register-turnovers/Languages/Русский.xml @@ -0,0 +1,16 @@ + + + + + Русский + + + ru + Русский + + + + ru + + + \ No newline at end of file diff --git a/tests/skills/cases/meta-compile/snapshots/accumulation-register/AccumulationRegisters/ОстаткиТоваров.xml b/tests/skills/cases/meta-compile/snapshots/accumulation-register/AccumulationRegisters/ОстаткиТоваров.xml index 7d9a28d3..d717a1a4 100644 --- a/tests/skills/cases/meta-compile/snapshots/accumulation-register/AccumulationRegisters/ОстаткиТоваров.xml +++ b/tests/skills/cases/meta-compile/snapshots/accumulation-register/AccumulationRegisters/ОстаткиТоваров.xml @@ -42,6 +42,32 @@ Balance false + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + DontCheck diff --git a/tests/skills/cases/meta-compile/snapshots/calculation-register/CalculationRegisters/Начисления.xml b/tests/skills/cases/meta-compile/snapshots/calculation-register/CalculationRegisters/Начисления.xml index 6f1ba5ce..041d1c83 100644 --- a/tests/skills/cases/meta-compile/snapshots/calculation-register/CalculationRegisters/Начисления.xml +++ b/tests/skills/cases/meta-compile/snapshots/calculation-register/CalculationRegisters/Начисления.xml @@ -52,6 +52,58 @@ ChartOfCalculationTypes.ВидыНачислений false + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + DontCheck @@ -78,7 +130,7 @@ - + DontCheck false @@ -104,7 +156,7 @@ - + DontCheck false @@ -130,7 +182,59 @@ - + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + DontCheck false @@ -182,7 +286,33 @@ - + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + DontCheck false diff --git a/tests/skills/cases/role-compile/snapshots/type-aliases-yo/CalculationRegisters/Начисления.xml b/tests/skills/cases/role-compile/snapshots/type-aliases-yo/CalculationRegisters/Начисления.xml index 04a4607c..301a228a 100644 --- a/tests/skills/cases/role-compile/snapshots/type-aliases-yo/CalculationRegisters/Начисления.xml +++ b/tests/skills/cases/role-compile/snapshots/type-aliases-yo/CalculationRegisters/Начисления.xml @@ -52,84 +52,6 @@ ChartOfCalculationTypes.ВидыРасчета false - - - DontCheck - false - false - Auto - - - false - - - Auto - Auto - - false - Use - false - - - - Use - - - - - - - - DontCheck - false - false - Auto - - - false - - - Auto - Auto - - false - Use - false - - - - Use - - - - - - - - DontCheck - false - false - Auto - - - false - - - Auto - Auto - - false - Use - false - - - - Use - - - - - DontCheck @@ -156,32 +78,6 @@ - - - DontCheck - false - false - Auto - - - false - - - Auto - Auto - - false - Use - false - - - - Use - - - - - DontCheck @@ -208,6 +104,240 @@ + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + Managed Use