diff --git a/.claude/skills/meta-compile/SKILL.md b/.claude/skills/meta-compile/SKILL.md index 5d48e2d1..dcc6496f 100644 --- a/.claude/skills/meta-compile/SKILL.md +++ b/.claude/skills/meta-compile/SKILL.md @@ -1,6 +1,6 @@ --- name: meta-compile -description: Компиляция объекта метаданных 1С (Справочник, Документ, Перечисление, Константа, Регистр) из компактного JSON-определения +description: Создать исходники объекта метаданных 1С (справочник, документ, регистр, перечисление, константа, общий модуль, обработка, HTTP-сервис и др.) в выгрузке конфигурации. Используй когда пользователь просит добавить или создать объект конфигурации argument-hint: allowed-tools: - Bash @@ -24,11 +24,21 @@ allowed-tools: powershell.exe -NoProfile -File .claude\skills\meta-compile\scripts\meta-compile.ps1 -JsonPath "" -OutputDir "" ``` -`OutputDir` — директория, содержащая подпапки `Catalogs/`, `Documents/`, `Enums/`, `Constants/`, `InformationRegisters/`, `AccumulationRegisters/`, а также `Configuration.xml`. +`OutputDir` — директория, содержащая подпапки типов (`Catalogs/`, `Documents/`, ...) и `Configuration.xml`. -## Поддерживаемые типы +## Поддерживаемые типы (23) -Catalog (Справочник), Document (Документ), Enum (Перечисление), Constant (Константа), InformationRegister (РегистрСведений), AccumulationRegister (РегистрНакопления). +### Ссылочные +Catalog (Справочник), Document (Документ), Enum (Перечисление), ExchangePlan (ПланОбмена), ChartOfAccounts (ПланСчетов), ChartOfCharacteristicTypes (ПВХ), ChartOfCalculationTypes (ПВР), BusinessProcess (БизнесПроцесс), Task (Задача) + +### Регистры +InformationRegister (РегистрСведений), AccumulationRegister (РегистрНакопления), AccountingRegister (РегистрБухгалтерии), CalculationRegister (РегистрРасчёта) + +### Отчёты/Обработки +Report (Отчёт), DataProcessor (Обработка) + +### Сервисные +Constant (Константа), DefinedType (ОпределяемыйТип), CommonModule (ОбщийМодуль), ScheduledJob (РегламентноеЗадание), EventSubscription (ПодпискаНаСобытие), DocumentJournal (ЖурналДокументов), HTTPService (HTTPСервис), WebService (ВебСервис) ## JSON DSL — краткий справочник @@ -55,34 +65,15 @@ Catalog (Справочник), Document (Документ), Enum (Перечи "ИмяРеквизита: Тип | req, index" — с флагами ``` -Типы: `String(100)`, `Number(15,2)`, `Boolean`, `Date`, `DateTime`, `CatalogRef.Xxx`, `DocumentRef.Xxx`, `EnumRef.Xxx`, `DefinedType.Xxx`. Русские синонимы: `Строка(100)`, `Число(15,2)`, `Булево`, `Дата`, `СправочникСсылка.Xxx`. +Типы: `String(100)`, `Number(15,2)`, `Boolean`, `Date`, `DateTime`, `CatalogRef.Xxx`, `DocumentRef.Xxx`, `EnumRef.Xxx`, `ChartOfAccountsRef.Xxx`, `ChartOfCharacteristicTypesRef.Xxx`, `ChartOfCalculationTypesRef.Xxx`, `ExchangePlanRef.Xxx`, `BusinessProcessRef.Xxx`, `TaskRef.Xxx`, `DefinedType.Xxx`. -Флаги: `req` (обязательное), `index`, `indexAdditional`, `nonneg`, `master`, `mainFilter`, `denyIncomplete`, `useInTotals`. +Русские синонимы типов: `Строка`, `Число`, `Булево`, `Дата`, `СправочникСсылка.Xxx`, `ДокументСсылка.Xxx`, `ПланСчетовСсылка.Xxx`. -### Табличные части (Catalog, Document) - -```json -"tabularSections": { - "Товары": ["Номенклатура: CatalogRef.Xxx | req", "Количество: Number(10,3)"] -} -``` - -### Перечисления - -```json -"values": ["Приход", "Расход", { "name": "НДС20", "synonym": "НДС 20%" }] -``` - -### Измерения и ресурсы (регистры) - -```json -"dimensions": ["Организация: CatalogRef.Xxx | master, mainFilter"], -"resources": ["Количество: Number(15,3)"] -``` +Флаги: `req`, `index`, `indexAdditional`, `nonneg`, `master`, `mainFilter`, `denyIncomplete`, `useInTotals`. ## Примеры -### Минимальный справочник +### Справочник ```json { "type": "Catalog", "name": "Валюты" } @@ -100,23 +91,90 @@ Catalog (Справочник), Document (Документ), Enum (Перечи { "type": "Constant", "name": "ОсновнаяВалюта", "valueType": "CatalogRef.Валюты" } ``` +### Определяемый тип + +```json +{ "type": "DefinedType", "name": "ДенежныеСредства", "valueTypes": ["CatalogRef.БанковскиеСчета", "CatalogRef.Кассы"] } +``` + +### Общий модуль + +```json +{ "type": "CommonModule", "name": "ОбменДаннымиСервер", "context": "server", "returnValuesReuse": "DuringRequest" } +``` + +Шорткаты context: `"server"` → Server+ServerCall, `"client"` → ClientManagedApplication, `"serverClient"` → Server+ClientManagedApplication. + ### Регистр сведений ```json { - "type": "InformationRegister", - "name": "КурсыВалют", - "periodicity": "Day", + "type": "InformationRegister", "name": "КурсыВалют", "periodicity": "Day", "dimensions": ["Валюта: CatalogRef.Валюты | master, mainFilter, denyIncomplete"], "resources": ["Курс: Number(15,4)", "Кратность: Number(10,0)"] } ``` +### План обмена + +```json +{ "type": "ExchangePlan", "name": "ОбменССайтом", "attributes": ["АдресСервера: String(200)"] } +``` + +### Журнал документов + +```json +{ + "type": "DocumentJournal", "name": "Взаимодействия", + "registeredDocuments": ["Document.Встреча", "Document.ТелефонныйЗвонок"], + "columns": [{ "name": "Организация", "indexing": "Index", "references": ["Document.Встреча.Attribute.Организация"] }] +} +``` + +### HTTP-сервис + +```json +{ + "type": "HTTPService", "name": "API", "rootURL": "api", + "urlTemplates": { "Users": { "template": "/v1/users", "methods": { "Get": "GET", "Create": "POST" } } } +} +``` + +### Веб-сервис + +```json +{ + "type": "WebService", "name": "DataExchange", "namespace": "http://www.1c.ru/DataExchange", + "operations": { "TestConnection": { "returnType": "xs:boolean", "handler": "ПроверкаПодключения", "parameters": { "ErrorMessage": { "type": "xs:string", "direction": "Out" } } } } +} +``` + +### План счетов + +```json +{ + "type": "ChartOfAccounts", "name": "Хозрасчетный", + "extDimensionTypes": "ChartOfCharacteristicTypes.ВидыСубконто", "maxExtDimensionCount": 3, + "codeMask": "@@@.@@.@", "codeLength": 8, + "accountingFlags": ["Валютный", "Количественный"], + "extDimensionAccountingFlags": ["Суммовой", "Валютный"] +} +``` + +### Бизнес-процесс + +```json +{ "type": "BusinessProcess", "name": "Задание", "attributes": ["Описание: String(200)"] } +``` + ## Что генерируется - `{OutputDir}/{TypePlural}/{Name}.xml` — метаданные объекта -- `{OutputDir}/{TypePlural}/{Name}/Ext/ObjectModule.bsl` — пустой модуль (Catalog, Document) -- `{OutputDir}/{TypePlural}/{Name}/Ext/RecordSetModule.bsl` — пустой модуль (регистры) +- `{OutputDir}/{TypePlural}/{Name}/Ext/ObjectModule.bsl` — модуль объекта (Catalog, Document, Report, DataProcessor, ExchangePlan, ChartOfAccounts, ChartOfCharacteristicTypes, ChartOfCalculationTypes, BusinessProcess, Task) +- `{OutputDir}/{TypePlural}/{Name}/Ext/RecordSetModule.bsl` — модуль набора записей (4 типа регистров) +- `{OutputDir}/{TypePlural}/{Name}/Ext/Module.bsl` — модуль (CommonModule, HTTPService, WebService) +- `{OutputDir}/{TypePlural}/{Name}/Ext/Content.xml` — состав плана обмена (ExchangePlan) +- `{OutputDir}/{TypePlural}/{Name}/Ext/Flowchart.xml` — карта маршрута (BusinessProcess) - `Configuration.xml` — автоматическая регистрация в `` ## Верификация diff --git a/.claude/skills/meta-compile/scripts/meta-compile.ps1 b/.claude/skills/meta-compile/scripts/meta-compile.ps1 index 7146850d..041d7683 100644 --- a/.claude/skills/meta-compile/scripts/meta-compile.ps1 +++ b/.claude/skills/meta-compile/scripts/meta-compile.ps1 @@ -22,12 +22,32 @@ $def = $json | ConvertFrom-Json # Object type synonyms (Russian → English) $script:objectTypeSynonyms = @{ - "Справочник" = "Catalog" - "Документ" = "Document" - "Перечисление" = "Enum" - "Константа" = "Constant" - "РегистрСведений" = "InformationRegister" - "РегистрНакопления"= "AccumulationRegister" + "Справочник" = "Catalog" + "Документ" = "Document" + "Перечисление" = "Enum" + "Константа" = "Constant" + "РегистрСведений" = "InformationRegister" + "РегистрНакопления" = "AccumulationRegister" + "РегистрБухгалтерии" = "AccountingRegister" + "РегистрРасчёта" = "CalculationRegister" + "РегистрРасчета" = "CalculationRegister" + "ПланСчетов" = "ChartOfAccounts" + "ПланВидовХарактеристик" = "ChartOfCharacteristicTypes" + "ПланВидовРасчёта" = "ChartOfCalculationTypes" + "ПланВидовРасчета" = "ChartOfCalculationTypes" + "БизнесПроцесс" = "BusinessProcess" + "Задача" = "Task" + "ПланОбмена" = "ExchangePlan" + "ЖурналДокументов" = "DocumentJournal" + "Отчёт" = "Report" + "Отчет" = "Report" + "Обработка" = "DataProcessor" + "ОбщийМодуль" = "CommonModule" + "РегламентноеЗадание" = "ScheduledJob" + "ПодпискаНаСобытие" = "EventSubscription" + "HTTPСервис" = "HTTPService" + "ВебСервис" = "WebService" + "ОпределяемыйТип" = "DefinedType" } if (-not $def.type) { @@ -41,7 +61,11 @@ if ($script:objectTypeSynonyms.ContainsKey($objType)) { $objType = $script:objectTypeSynonyms[$objType] } -$validTypes = @("Catalog","Document","Enum","Constant","InformationRegister","AccumulationRegister") +$validTypes = @("Catalog","Document","Enum","Constant","InformationRegister","AccumulationRegister", + "AccountingRegister","CalculationRegister","ChartOfAccounts","ChartOfCharacteristicTypes", + "ChartOfCalculationTypes","BusinessProcess","Task","ExchangePlan","DocumentJournal", + "Report","DataProcessor","CommonModule","ScheduledJob","EventSubscription", + "HTTPService","WebService","DefinedType") if ($objType -notin $validTypes) { Write-Error "Unsupported type: $objType. Valid: $($validTypes -join ', ')" exit 1 @@ -125,6 +149,11 @@ $script:typeSynonyms["документссылка"] = "DocumentRe $script:typeSynonyms["перечислениессылка"] = "EnumRef" $script:typeSynonyms["плансчетовссылка"] = "ChartOfAccountsRef" $script:typeSynonyms["планвидовхарактеристикссылка"] = "ChartOfCharacteristicTypesRef" +$script:typeSynonyms["планвидоврасчётассылка"] = "ChartOfCalculationTypesRef" +$script:typeSynonyms["планвидоврасчетассылка"] = "ChartOfCalculationTypesRef" +$script:typeSynonyms["планобменассылка"] = "ExchangePlanRef" +$script:typeSynonyms["бизнеспроцессссылка"] = "BusinessProcessRef" +$script:typeSynonyms["задачассылка"] = "TaskRef" $script:typeSynonyms["определяемыйтип"] = "DefinedType" $script:typeSynonyms["definedtype"] = "DefinedType" @@ -219,7 +248,7 @@ function Emit-TypeContent { } # Reference types: CatalogRef.XXX, DocumentRef.XXX, etc. - if ($typeStr -match '^(CatalogRef|DocumentRef|EnumRef|ChartOfAccountsRef|ChartOfCharacteristicTypesRef)\.(.+)$') { + if ($typeStr -match '^(CatalogRef|DocumentRef|EnumRef|ChartOfAccountsRef|ChartOfCharacteristicTypesRef|ChartOfCalculationTypesRef|ExchangePlanRef|BusinessProcessRef|TaskRef)\.(.+)$') { X "$indentcfg:$typeStr" return } @@ -375,6 +404,78 @@ $script:generatedTypes = @{ @{ prefix = "AccumulationRegisterRecordSet"; category = "RecordSet" } @{ prefix = "AccumulationRegisterRecordKey"; category = "RecordKey" } ) + "AccountingRegister" = @( + @{ prefix = "AccountingRegisterRecord"; category = "Record" } + @{ prefix = "AccountingRegisterManager"; category = "Manager" } + @{ prefix = "AccountingRegisterSelection"; category = "Selection" } + @{ prefix = "AccountingRegisterList"; category = "List" } + @{ prefix = "AccountingRegisterRecordSet"; category = "RecordSet" } + @{ prefix = "AccountingRegisterRecordKey"; category = "RecordKey" } + ) + "CalculationRegister" = @( + @{ prefix = "CalculationRegisterRecord"; category = "Record" } + @{ prefix = "CalculationRegisterManager"; category = "Manager" } + @{ prefix = "CalculationRegisterSelection"; category = "Selection" } + @{ prefix = "CalculationRegisterList"; category = "List" } + @{ prefix = "CalculationRegisterRecordSet"; category = "RecordSet" } + @{ prefix = "CalculationRegisterRecordKey"; category = "RecordKey" } + ) + "ChartOfAccounts" = @( + @{ prefix = "ChartOfAccountsObject"; category = "Object" } + @{ prefix = "ChartOfAccountsRef"; category = "Ref" } + @{ prefix = "ChartOfAccountsSelection"; category = "Selection" } + @{ prefix = "ChartOfAccountsList"; category = "List" } + @{ prefix = "ChartOfAccountsManager"; category = "Manager" } + ) + "ChartOfCharacteristicTypes" = @( + @{ prefix = "ChartOfCharacteristicTypesObject"; category = "Object" } + @{ prefix = "ChartOfCharacteristicTypesRef"; category = "Ref" } + @{ prefix = "ChartOfCharacteristicTypesSelection"; category = "Selection" } + @{ prefix = "ChartOfCharacteristicTypesList"; category = "List" } + @{ prefix = "ChartOfCharacteristicTypesManager"; category = "Manager" } + ) + "ChartOfCalculationTypes" = @( + @{ prefix = "ChartOfCalculationTypesObject"; category = "Object" } + @{ prefix = "ChartOfCalculationTypesRef"; category = "Ref" } + @{ prefix = "ChartOfCalculationTypesSelection"; category = "Selection" } + @{ prefix = "ChartOfCalculationTypesList"; category = "List" } + @{ prefix = "ChartOfCalculationTypesManager"; category = "Manager" } + @{ prefix = "DisplacingCalculationTypes"; category = "DisplacingCalculationTypes" } + @{ prefix = "BaseCalculationTypes"; category = "BaseCalculationTypes" } + @{ prefix = "LeadingCalculationTypes"; category = "LeadingCalculationTypes" } + ) + "BusinessProcess" = @( + @{ prefix = "BusinessProcessObject"; category = "Object" } + @{ prefix = "BusinessProcessRef"; category = "Ref" } + @{ prefix = "BusinessProcessSelection"; category = "Selection" } + @{ prefix = "BusinessProcessList"; category = "List" } + @{ prefix = "BusinessProcessManager"; category = "Manager" } + ) + "Task" = @( + @{ prefix = "TaskObject"; category = "Object" } + @{ prefix = "TaskRef"; category = "Ref" } + @{ prefix = "TaskSelection"; category = "Selection" } + @{ prefix = "TaskList"; category = "List" } + @{ prefix = "TaskManager"; category = "Manager" } + ) + "ExchangePlan" = @( + @{ prefix = "ExchangePlanObject"; category = "Object" } + @{ prefix = "ExchangePlanRef"; category = "Ref" } + @{ prefix = "ExchangePlanSelection"; category = "Selection" } + @{ prefix = "ExchangePlanList"; category = "List" } + @{ prefix = "ExchangePlanManager"; category = "Manager" } + ) + "DocumentJournal" = @( + @{ prefix = "DocumentJournalSelection"; category = "Selection" } + @{ prefix = "DocumentJournalList"; category = "List" } + @{ prefix = "DocumentJournalManager"; category = "Manager" } + ) + "Report" = @( + @{ prefix = "ReportObject"; category = "Object" } + ) + "DataProcessor" = @( + @{ prefix = "DataProcessorObject"; category = "Object" } + ) } function Emit-InternalInfo { @@ -383,6 +484,10 @@ function Emit-InternalInfo { if (-not $types) { return } X "$indent" + # ExchangePlan: ThisNode UUID before GeneratedTypes + if ($objectType -eq "ExchangePlan") { + X "$indent`t$(New-Guid-String)" + } foreach ($gt in $types) { $fullName = "$($gt.prefix).$objectName" X "$indent`t" @@ -401,6 +506,15 @@ $script:standardAttributesByType = @{ "Enum" = @("Order","Ref") "InformationRegister" = @("Active","LineNumber","Recorder","Period") "AccumulationRegister" = @("Active","LineNumber","Recorder","Period") + "AccountingRegister" = @("Active","Period","Recorder","LineNumber","Account") + "CalculationRegister" = @("Active","Recorder","LineNumber","RegistrationPeriod","CalculationType","ReversingEntry") + "ChartOfAccounts" = @("PredefinedDataName","Predefined","Ref","DeletionMark","Description","Code","Parent","Order","Type","OffBalance") + "ChartOfCharacteristicTypes" = @("PredefinedDataName","Predefined","Ref","DeletionMark","Description","Code","Parent","ValueType") + "ChartOfCalculationTypes" = @("PredefinedDataName","Predefined","Ref","DeletionMark","Description","Code","ActionPeriodIsBasic") + "BusinessProcess" = @("Ref","DeletionMark","Date","Number","Started","Completed","HeadTask") + "Task" = @("Ref","DeletionMark","Date","Number","Executed","Description","RoutePoint","BusinessProcess") + "ExchangePlan" = @("Ref","DeletionMark","Code","Description","ThisNode","SentNo","ReceivedNo") + "DocumentJournal" = @("Type","Ref","Date","Posted","DeletionMark","Number") } function Emit-StandardAttribute { @@ -534,14 +648,8 @@ function Emit-TabularSection { X "$indent" # InternalInfo for TabularSection - $typePrefix = switch ($objectType) { - "Catalog" { "CatalogTabularSection" } - "Document" { "DocumentTabularSection" } - } - $rowPrefix = switch ($objectType) { - "Catalog" { "CatalogTabularSectionRow" } - "Document" { "DocumentTabularSectionRow" } - } + $typePrefix = "${objectType}TabularSection" + $rowPrefix = "${objectType}TabularSectionRow" X "$indent`t" X "$indent`t`t" @@ -563,7 +671,10 @@ function Emit-TabularSection { X "$indent`t`t" X "$indent`t`tDontCheck" Emit-TabularStandardAttributes "$indent`t`t" - X "$indent`t`tForItem" + # Use=ForItem only for Catalog/Document + if ($objectType -in @("Catalog","Document")) { + X "$indent`t`tForItem" + } X "$indent`t" X "$indent`t" @@ -1090,6 +1201,1142 @@ function Emit-AccumulationRegisterProperties { X "$i" } +# --- 13a. Wave 1: DefinedType, CommonModule, ScheduledJob, EventSubscription --- + +function Emit-DefinedTypeProperties { + param([string]$indent) + $i = $indent + + X "$i$(Esc-Xml $objName)" + Emit-MLText $i "Synonym" $synonym + X "$i" + + # Type — composite type with multiple v8:Type entries + $valueTypes = @() + if ($def.valueTypes) { + $valueTypes = @($def.valueTypes) + } + if ($valueTypes.Count -gt 0) { + X "$i" + foreach ($vt in $valueTypes) { + $resolved = Resolve-TypeStr "$vt" + if ($resolved -match '^(CatalogRef|DocumentRef|EnumRef|ChartOfAccountsRef|ChartOfCharacteristicTypesRef|ChartOfCalculationTypesRef|ExchangePlanRef|BusinessProcessRef|TaskRef)\.') { + X "$i`tcfg:$resolved" + } elseif ($resolved -eq "Boolean") { + X "$i`txs:boolean" + } elseif ($resolved -match '^String') { + X "$i`txs:string" + X "$i`t" + X "$i`t`t0" + X "$i`t`tVariable" + X "$i`t" + } else { + X "$i`tcfg:$resolved" + } + } + X "$i" + } else { + X "$i" + } +} + +function Emit-CommonModuleProperties { + param([string]$indent) + $i = $indent + + X "$i$(Esc-Xml $objName)" + Emit-MLText $i "Synonym" $synonym + X "$i" + + # Context shortcuts + $context = if ($def.context) { "$($def.context)" } else { "" } + + $global = if ($def.global -eq $true) { "true" } else { "false" } + $server = "false"; $serverCall = "false"; $clientManaged = "false" + $clientOrdinary = "false"; $externalConnection = "false"; $privileged = "false" + + switch ($context) { + "server" { $server = "true"; $serverCall = "true" } + "serverCall" { $server = "true"; $serverCall = "true" } + "client" { $clientManaged = "true" } + "serverClient" { $server = "true"; $clientManaged = "true" } + default { + if ($def.server -eq $true) { $server = "true" } + if ($def.serverCall -eq $true) { $serverCall = "true" } + if ($def.clientManagedApplication -eq $true) { $clientManaged = "true" } + if ($def.clientOrdinaryApplication -eq $true) { $clientOrdinary = "true" } + if ($def.externalConnection -eq $true) { $externalConnection = "true" } + if ($def.privileged -eq $true) { $privileged = "true" } + } + } + + X "$i$global" + X "$i$clientManaged" + X "$i$server" + X "$i$externalConnection" + X "$i$clientOrdinary" + X "$i$serverCall" + X "$i$privileged" + + $returnValuesReuse = if ($def.returnValuesReuse) { "$($def.returnValuesReuse)" } else { "DontUse" } + X "$i$returnValuesReuse" +} + +function Emit-ScheduledJobProperties { + param([string]$indent) + $i = $indent + + X "$i$(Esc-Xml $objName)" + Emit-MLText $i "Synonym" $synonym + X "$i" + + $methodName = if ($def.methodName) { "$($def.methodName)" } else { "" } + X "$i$(Esc-Xml $methodName)" + + $description = if ($def.description) { "$($def.description)" } else { $synonym } + X "$i$(Esc-Xml $description)" + + $key = if ($def.key) { "$($def.key)" } else { "" } + X "$i$(Esc-Xml $key)" + + $use = if ($def.use -eq $true) { "true" } else { "false" } + X "$i$use" + + $predefined = if ($def.predefined -eq $true) { "true" } else { "false" } + X "$i$predefined" + + $restartCount = if ($null -ne $def.restartCountOnFailure) { "$($def.restartCountOnFailure)" } else { "3" } + $restartInterval = if ($null -ne $def.restartIntervalOnFailure) { "$($def.restartIntervalOnFailure)" } else { "10" } + X "$i$restartCount" + X "$i$restartInterval" +} + +function Emit-EventSubscriptionProperties { + param([string]$indent) + $i = $indent + + X "$i$(Esc-Xml $objName)" + Emit-MLText $i "Synonym" $synonym + X "$i" + + # Source — array of v8:Type + $sources = @() + if ($def.source) { $sources = @($def.source) } + if ($sources.Count -gt 0) { + X "$i" + foreach ($src in $sources) { + $resolved = Resolve-TypeStr "$src" + X "$i`tcfg:$resolved" + } + X "$i" + } else { + X "$i" + } + + $event = if ($def.event) { "$($def.event)" } else { "BeforeWrite" } + X "$i$event" + + $handler = if ($def.handler) { "$($def.handler)" } else { "" } + X "$i$(Esc-Xml $handler)" +} + +# --- 13b. Wave 2: Report, DataProcessor --- + +function Emit-ReportProperties { + param([string]$indent) + $i = $indent + + X "$i$(Esc-Xml $objName)" + Emit-MLText $i "Synonym" $synonym + X "$i" + X "$itrue" + + $defaultForm = if ($def.defaultForm) { "$($def.defaultForm)" } else { "" } + if ($defaultForm) { X "$i$defaultForm" } else { X "$i" } + + $auxForm = if ($def.auxiliaryForm) { "$($def.auxiliaryForm)" } else { "" } + if ($auxForm) { X "$i$auxForm" } else { X "$i" } + + $mainDCS = if ($def.mainDataCompositionSchema) { "$($def.mainDataCompositionSchema)" } else { "" } + if ($mainDCS) { X "$i$mainDCS" } else { X "$i" } + + $defSettings = if ($def.defaultSettingsForm) { "$($def.defaultSettingsForm)" } else { "" } + if ($defSettings) { X "$i$defSettings" } else { X "$i" } + + $auxSettings = if ($def.auxiliarySettingsForm) { "$($def.auxiliarySettingsForm)" } else { "" } + if ($auxSettings) { X "$i$auxSettings" } else { X "$i" } + + $defVariant = if ($def.defaultVariantForm) { "$($def.defaultVariantForm)" } else { "" } + if ($defVariant) { X "$i$defVariant" } else { X "$i" } + + X "$i" + X "$i" + X "$ifalse" + X "$i" + X "$i" +} + +function Emit-DataProcessorProperties { + param([string]$indent) + $i = $indent + + X "$i$(Esc-Xml $objName)" + Emit-MLText $i "Synonym" $synonym + X "$i" + X "$ifalse" + + $defaultForm = if ($def.defaultForm) { "$($def.defaultForm)" } else { "" } + if ($defaultForm) { X "$i$defaultForm" } else { X "$i" } + + $auxForm = if ($def.auxiliaryForm) { "$($def.auxiliaryForm)" } else { "" } + if ($auxForm) { X "$i$auxForm" } else { X "$i" } + + X "$ifalse" + X "$i" + X "$i" +} + +# --- 13c. Wave 3: ExchangePlan, ChartOfCharacteristicTypes, DocumentJournal --- + +function Emit-ExchangePlanProperties { + param([string]$indent) + $i = $indent + + X "$i$(Esc-Xml $objName)" + Emit-MLText $i "Synonym" $synonym + X "$i" + X "$itrue" + + $codeLength = if ($null -ne $def.codeLength) { "$($def.codeLength)" } else { "9" } + $descriptionLength = if ($null -ne $def.descriptionLength) { "$($def.descriptionLength)" } else { "100" } + $codeType = if ($def.codeType) { "$($def.codeType)" } else { "String" } + $codeAllowedLength = if ($def.codeAllowedLength) { "$($def.codeAllowedLength)" } else { "Variable" } + $autonumbering = if ($def.autonumbering -eq $false) { "false" } else { "true" } + $checkUnique = if ($def.checkUnique -eq $true) { "true" } else { "false" } + + X "$i$codeLength" + X "$i$codeType" + X "$i$codeAllowedLength" + X "$i$descriptionLength" + X "$iAsDescription" + X "$iInDialog" + X "$i$checkUnique" + X "$i$autonumbering" + + Emit-StandardAttributes $i "ExchangePlan" + + $distributed = if ($def.distributedInfoBase -eq $true) { "true" } else { "false" } + $includeExt = if ($def.includeConfigurationExtensions -eq $true) { "true" } else { "false" } + X "$i$distributed" + X "$i$includeExt" + + X "$i" + X "$itrue" + X "$iBothWays" + X "$i" + X "$i`tExchangePlan.$objName.StandardAttribute.Description" + X "$i`tExchangePlan.$objName.StandardAttribute.Code" + X "$i" + X "$iBegin" + X "$iDontUse" + X "$iDirectly" + X "$i" + X "$i" + X "$i" + X "$i" + X "$i" + X "$i" + X "$ifalse" + X "$i" + + $dataLockControlMode = if ($def.dataLockControlMode) { "$($def.dataLockControlMode)" } else { "Automatic" } + X "$i$dataLockControlMode" + + $fullTextSearch = if ($def.fullTextSearch) { "$($def.fullTextSearch)" } else { "Use" } + X "$i$fullTextSearch" + + X "$i" + X "$i" + X "$i" + X "$i" + X "$i" + X "$iDontUse" + X "$iAuto" + X "$iDontUse" + X "$ifalse" + X "$ifalse" +} + +function Emit-ChartOfCharacteristicTypesProperties { + param([string]$indent) + $i = $indent + + X "$i$(Esc-Xml $objName)" + Emit-MLText $i "Synonym" $synonym + X "$i" + X "$itrue" + + $codeLength = if ($null -ne $def.codeLength) { "$($def.codeLength)" } else { "9" } + $descriptionLength = if ($null -ne $def.descriptionLength) { "$($def.descriptionLength)" } else { "25" } + $codeType = if ($def.codeType) { "$($def.codeType)" } else { "String" } + $codeAllowedLength = if ($def.codeAllowedLength) { "$($def.codeAllowedLength)" } else { "Variable" } + $autonumbering = if ($def.autonumbering -eq $false) { "false" } else { "true" } + $checkUnique = if ($def.checkUnique -eq $true) { "true" } else { "false" } + + X "$i$codeLength" + X "$i$codeType" + X "$i$codeAllowedLength" + X "$i$descriptionLength" + X "$i$checkUnique" + X "$i$autonumbering" + X "$iAsDescription" + + # CharacteristicExtValues + $charExtValues = if ($def.characteristicExtValues) { "$($def.characteristicExtValues)" } else { "" } + if ($charExtValues) { X "$i$charExtValues" } + else { X "$i" } + + # Type — composite type of allowed characteristic value types + $valueTypes = @() + if ($def.valueTypes) { $valueTypes = @($def.valueTypes) } + if ($valueTypes.Count -gt 0) { + X "$i" + foreach ($vt in $valueTypes) { + Emit-TypeContent "$i`t" "$vt" + } + X "$i" + } else { + X "$i" + X "$i`txs:boolean" + X "$i`txs:string" + X "$i`t" + X "$i`t`t0" + X "$i`t`tVariable" + X "$i`t" + X "$i`txs:decimal" + X "$i`t" + X "$i`t`t15" + X "$i`t`t2" + X "$i`t`tAny" + X "$i`t" + X "$i`txs:dateTime" + X "$i`t" + X "$i`t`tDateTime" + X "$i`t" + X "$i" + } + + $hierarchical = if ($def.hierarchical -eq $true) { "true" } else { "false" } + X "$i$hierarchical" + X "$itrue" + + Emit-StandardAttributes $i "ChartOfCharacteristicTypes" + X "$i" + X "$iAuto" + X "$iInDialog" + X "$itrue" + X "$iBothWays" + X "$i" + X "$i`tChartOfCharacteristicTypes.$objName.StandardAttribute.Description" + X "$i`tChartOfCharacteristicTypes.$objName.StandardAttribute.Code" + X "$i" + X "$iBegin" + X "$iDontUse" + X "$iDirectly" + X "$i" + X "$i" + X "$i" + X "$i" + X "$i" + X "$i" + X "$i" + X "$i" + X "$i" + X "$i" + X "$ifalse" + X "$i" + X "$i" + + $dataLockControlMode = if ($def.dataLockControlMode) { "$($def.dataLockControlMode)" } else { "Automatic" } + X "$i$dataLockControlMode" + + $fullTextSearch = if ($def.fullTextSearch) { "$($def.fullTextSearch)" } else { "Use" } + X "$i$fullTextSearch" + + X "$i" + X "$i" + X "$i" + X "$i" + X "$i" + X "$iDontUse" + X "$iAuto" + X "$iDontUse" + X "$ifalse" + X "$ifalse" +} + +function Emit-DocumentJournalProperties { + param([string]$indent) + $i = $indent + + X "$i$(Esc-Xml $objName)" + Emit-MLText $i "Synonym" $synonym + X "$i" + + $defaultForm = if ($def.defaultForm) { "$($def.defaultForm)" } else { "" } + if ($defaultForm) { X "$i$defaultForm" } else { X "$i" } + + $auxForm = if ($def.auxiliaryForm) { "$($def.auxiliaryForm)" } else { "" } + if ($auxForm) { X "$i$auxForm" } else { X "$i" } + + X "$itrue" + + # RegisteredDocuments + $regDocs = @() + if ($def.registeredDocuments) { $regDocs = @($def.registeredDocuments) } + if ($regDocs.Count -gt 0) { + X "$i" + foreach ($rd in $regDocs) { + $rdStr = "$rd" + # Resolve Russian synonyms: Документ.Xxx → Document.Xxx + if ($rdStr.Contains('.')) { + $dotIdx = $rdStr.IndexOf('.') + $rdPrefix = $rdStr.Substring(0, $dotIdx) + $rdSuffix = $rdStr.Substring($dotIdx + 1) + if ($script:objectTypeSynonyms.ContainsKey($rdPrefix)) { + $rdPrefix = $script:objectTypeSynonyms[$rdPrefix] + } + $rdStr = "$rdPrefix.$rdSuffix" + } + X "$i`t$rdStr" + } + X "$i" + } else { + X "$i" + } + + Emit-StandardAttributes $i "DocumentJournal" + + X "$i" + X "$i" + X "$i" +} + +# --- 13d. Wave 4: ChartOfAccounts, AccountingRegister, ChartOfCalculationTypes, CalculationRegister --- + +function Emit-ChartOfAccountsProperties { + param([string]$indent) + $i = $indent + + X "$i$(Esc-Xml $objName)" + Emit-MLText $i "Synonym" $synonym + X "$i" + X "$itrue" + + # ExtDimensionTypes + $extDimTypes = if ($def.extDimensionTypes) { "$($def.extDimensionTypes)" } else { "" } + if ($extDimTypes) { X "$i$extDimTypes" } + else { X "$i" } + + $maxExtDim = if ($null -ne $def.maxExtDimensionCount) { "$($def.maxExtDimensionCount)" } else { "3" } + X "$i$maxExtDim" + + $codeMask = if ($def.codeMask) { "$($def.codeMask)" } else { "" } + if ($codeMask) { X "$i$codeMask" } else { X "$i" } + + $codeLength = if ($null -ne $def.codeLength) { "$($def.codeLength)" } else { "8" } + $descriptionLength = if ($null -ne $def.descriptionLength) { "$($def.descriptionLength)" } else { "120" } + $codeSeries = if ($def.codeSeries) { "$($def.codeSeries)" } else { "WholeChartOfAccounts" } + $autoOrder = if ($def.autoOrderByCode -eq $false) { "false" } else { "true" } + $orderLength = if ($null -ne $def.orderLength) { "$($def.orderLength)" } else { "5" } + + X "$i$codeLength" + X "$i$descriptionLength" + X "$i$codeSeries" + X "$ifalse" + X "$itrue" + X "$iAsDescription" + X "$i$autoOrder" + X "$i$orderLength" + + $hierarchical = if ($def.hierarchical -eq $true) { "true" } else { "false" } + X "$i$hierarchical" + + X "$iInDialog" + + Emit-StandardAttributes $i "ChartOfAccounts" + + # StandardTabularSections — ExtDimensionTypes + X "$i" + X "$i`t" + X "$i`t`t" + foreach ($stAttr in @("TurnoversOnly","Predefined","ExtDimensionType","LineNumber")) { + Emit-StandardAttribute "$i`t`t`t" $stAttr + } + X "$i`t`t" + X "$i`t" + X "$i" + + X "$i" + X "$iAuto" + X "$itrue" + X "$iBothWays" + X "$i" + X "$i`tChartOfAccounts.$objName.StandardAttribute.Description" + X "$i`tChartOfAccounts.$objName.StandardAttribute.Code" + X "$i" + X "$iBegin" + X "$iDontUse" + X "$iDirectly" + X "$i" + X "$i" + X "$i" + X "$i" + X "$i" + X "$i" + X "$ifalse" + X "$i" + X "$i" + + $dataLockControlMode = if ($def.dataLockControlMode) { "$($def.dataLockControlMode)" } else { "Automatic" } + X "$i$dataLockControlMode" + + $fullTextSearch = if ($def.fullTextSearch) { "$($def.fullTextSearch)" } else { "Use" } + X "$i$fullTextSearch" + + X "$i" + X "$i" + X "$i" + X "$i" + X "$i" + X "$iDontUse" + X "$iAuto" + X "$iDontUse" + X "$ifalse" + X "$ifalse" +} + +function Emit-AccountingRegisterProperties { + param([string]$indent) + $i = $indent + + X "$i$(Esc-Xml $objName)" + Emit-MLText $i "Synonym" $synonym + X "$i" + X "$itrue" + X "$i" + X "$i" + + $chartOfAccounts = if ($def.chartOfAccounts) { "$($def.chartOfAccounts)" } else { "" } + if ($chartOfAccounts) { X "$i$chartOfAccounts" } + else { X "$i" } + + $correspondence = if ($def.correspondence -eq $true) { "true" } else { "false" } + X "$i$correspondence" + + $periodAdjLen = if ($null -ne $def.periodAdjustmentLength) { "$($def.periodAdjustmentLength)" } else { "0" } + X "$i$periodAdjLen" + + X "$ifalse" + + Emit-StandardAttributes $i "AccountingRegister" + + $dataLockControlMode = if ($def.dataLockControlMode) { "$($def.dataLockControlMode)" } else { "Automatic" } + X "$i$dataLockControlMode" + + $fullTextSearch = if ($def.fullTextSearch) { "$($def.fullTextSearch)" } else { "Use" } + X "$i$fullTextSearch" + + X "$i" + X "$i" + X "$i" +} + +function Emit-ChartOfCalculationTypesProperties { + param([string]$indent) + $i = $indent + + X "$i$(Esc-Xml $objName)" + Emit-MLText $i "Synonym" $synonym + X "$i" + X "$itrue" + + $codeLength = if ($null -ne $def.codeLength) { "$($def.codeLength)" } else { "9" } + $descriptionLength = if ($null -ne $def.descriptionLength) { "$($def.descriptionLength)" } else { "25" } + $codeType = if ($def.codeType) { "$($def.codeType)" } else { "String" } + $codeAllowedLength = if ($def.codeAllowedLength) { "$($def.codeAllowedLength)" } else { "Variable" } + $autonumbering = if ($def.autonumbering -eq $false) { "false" } else { "true" } + $checkUnique = if ($def.checkUnique -eq $true) { "true" } else { "false" } + + X "$i$codeLength" + X "$i$codeType" + X "$i$codeAllowedLength" + X "$i$descriptionLength" + X "$iAsDescription" + X "$i$checkUnique" + X "$i$autonumbering" + + $dependence = if ($def.dependenceOnCalculationTypes) { "$($def.dependenceOnCalculationTypes)" } else { "NotUsed" } + X "$i$dependence" + + # BaseCalculationTypes + $baseTypes = @() + if ($def.baseCalculationTypes) { $baseTypes = @($def.baseCalculationTypes) } + if ($baseTypes.Count -gt 0) { + X "$i" + foreach ($bt in $baseTypes) { + X "$i`t$bt" + } + X "$i" + } else { + X "$i" + } + + $actionPeriodUse = if ($def.actionPeriodUse -eq $true) { "true" } else { "false" } + X "$i$actionPeriodUse" + + Emit-StandardAttributes $i "ChartOfCalculationTypes" + X "$i" + X "$iAuto" + X "$iInDialog" + X "$itrue" + X "$iBothWays" + X "$i" + X "$i`tChartOfCalculationTypes.$objName.StandardAttribute.Description" + X "$i`tChartOfCalculationTypes.$objName.StandardAttribute.Code" + X "$i" + X "$iBegin" + X "$iDontUse" + X "$iDirectly" + X "$i" + X "$i" + X "$i" + X "$i" + X "$i" + X "$i" + X "$ifalse" + X "$i" + X "$i" + + $dataLockControlMode = if ($def.dataLockControlMode) { "$($def.dataLockControlMode)" } else { "Automatic" } + X "$i$dataLockControlMode" + + $fullTextSearch = if ($def.fullTextSearch) { "$($def.fullTextSearch)" } else { "Use" } + X "$i$fullTextSearch" + + X "$i" + X "$i" + X "$i" + X "$i" + X "$i" + X "$iDontUse" + X "$iAuto" +} + +function Emit-CalculationRegisterProperties { + param([string]$indent) + $i = $indent + + X "$i$(Esc-Xml $objName)" + Emit-MLText $i "Synonym" $synonym + X "$i" + X "$itrue" + X "$i" + X "$i" + + $chartOfCalcTypes = if ($def.chartOfCalculationTypes) { "$($def.chartOfCalculationTypes)" } else { "" } + if ($chartOfCalcTypes) { X "$i$chartOfCalcTypes" } + else { X "$i" } + + $periodicity = if ($def.periodicity) { "$($def.periodicity)" } else { "Month" } + X "$i$periodicity" + + $actionPeriod = if ($def.actionPeriod -eq $true) { "true" } else { "false" } + X "$i$actionPeriod" + + $basePeriod = if ($def.basePeriod -eq $true) { "true" } else { "false" } + X "$i$basePeriod" + + $schedule = if ($def.schedule) { "$($def.schedule)" } else { "" } + if ($schedule) { X "$i$schedule" } else { X "$i" } + + $scheduleValue = if ($def.scheduleValue) { "$($def.scheduleValue)" } else { "" } + if ($scheduleValue) { X "$i$scheduleValue" } else { X "$i" } + + $scheduleDate = if ($def.scheduleDate) { "$($def.scheduleDate)" } else { "" } + if ($scheduleDate) { X "$i$scheduleDate" } else { X "$i" } + + X "$ifalse" + + Emit-StandardAttributes $i "CalculationRegister" + + $dataLockControlMode = if ($def.dataLockControlMode) { "$($def.dataLockControlMode)" } else { "Automatic" } + X "$i$dataLockControlMode" + + $fullTextSearch = if ($def.fullTextSearch) { "$($def.fullTextSearch)" } else { "Use" } + X "$i$fullTextSearch" + + X "$i" + X "$i" + X "$i" +} + +# --- 13e. Wave 5: BusinessProcess, Task --- + +function Emit-BusinessProcessProperties { + param([string]$indent) + $i = $indent + + X "$i$(Esc-Xml $objName)" + Emit-MLText $i "Synonym" $synonym + X "$i" + X "$itrue" + + $editType = if ($def.editType) { "$($def.editType)" } else { "InDialog" } + X "$i$editType" + + $numberType = if ($def.numberType) { "$($def.numberType)" } else { "String" } + $numberLength = if ($null -ne $def.numberLength) { "$($def.numberLength)" } else { "11" } + $numberAllowedLength = if ($def.numberAllowedLength) { "$($def.numberAllowedLength)" } else { "Variable" } + $checkUnique = if ($def.checkUnique -eq $false) { "false" } else { "true" } + $autonumbering = if ($def.autonumbering -eq $false) { "false" } else { "true" } + + X "$i$numberType" + X "$i$numberLength" + X "$i$numberAllowedLength" + X "$i$checkUnique" + X "$i$autonumbering" + + Emit-StandardAttributes $i "BusinessProcess" + X "$i" + + X "$i" + X "$i" + X "$i`tBusinessProcess.$objName.StandardAttribute.Number" + X "$i" + X "$iDontUse" + X "$iBegin" + X "$iDontUse" + X "$iDirectly" + X "$i" + X "$i" + X "$i" + X "$i" + X "$i" + X "$i" + X "$ifalse" + X "$i" + + $dataLockControlMode = if ($def.dataLockControlMode) { "$($def.dataLockControlMode)" } else { "Automatic" } + X "$i$dataLockControlMode" + + $fullTextSearch = if ($def.fullTextSearch) { "$($def.fullTextSearch)" } else { "Use" } + X "$i$fullTextSearch" + + X "$i" + X "$i" + X "$i" + X "$i" + X "$i" + X "$iAuto" + X "$iDontUse" + X "$ifalse" + X "$ifalse" +} + +function Emit-TaskProperties { + param([string]$indent) + $i = $indent + + X "$i$(Esc-Xml $objName)" + Emit-MLText $i "Synonym" $synonym + X "$i" + X "$itrue" + + $numberType = if ($def.numberType) { "$($def.numberType)" } else { "String" } + $numberLength = if ($null -ne $def.numberLength) { "$($def.numberLength)" } else { "14" } + $numberAllowedLength = if ($def.numberAllowedLength) { "$($def.numberAllowedLength)" } else { "Variable" } + $checkUnique = if ($def.checkUnique -eq $false) { "false" } else { "true" } + $autonumbering = if ($def.autonumbering -eq $false) { "false" } else { "true" } + + $taskNumberAutoPrefix = if ($def.taskNumberAutoPrefix) { "$($def.taskNumberAutoPrefix)" } else { "BusinessProcessNumber" } + $descriptionLength = if ($null -ne $def.descriptionLength) { "$($def.descriptionLength)" } else { "150" } + + X "$i$numberType" + X "$i$numberLength" + X "$i$numberAllowedLength" + X "$i$checkUnique" + X "$i$autonumbering" + X "$i$taskNumberAutoPrefix" + X "$i$descriptionLength" + + # Addressing + $addressing = if ($def.addressing) { "$($def.addressing)" } else { "" } + if ($addressing) { X "$i$addressing" } else { X "$i" } + + $mainAddressing = if ($def.mainAddressingAttribute) { "$($def.mainAddressingAttribute)" } else { "" } + if ($mainAddressing) { X "$i$mainAddressing" } else { X "$i" } + + $currentPerformer = if ($def.currentPerformer) { "$($def.currentPerformer)" } else { "" } + if ($currentPerformer) { X "$i$currentPerformer" } else { X "$i" } + + Emit-StandardAttributes $i "Task" + X "$i" + + X "$i" + X "$i" + X "$i`tTask.$objName.StandardAttribute.Number" + X "$i" + X "$iDontUse" + X "$iBegin" + X "$iDontUse" + X "$iDirectly" + X "$i" + X "$i" + X "$i" + X "$i" + X "$i" + X "$i" + X "$ifalse" + X "$i" + + $dataLockControlMode = if ($def.dataLockControlMode) { "$($def.dataLockControlMode)" } else { "Automatic" } + X "$i$dataLockControlMode" + + $fullTextSearch = if ($def.fullTextSearch) { "$($def.fullTextSearch)" } else { "Use" } + X "$i$fullTextSearch" + + X "$i" + X "$i" + X "$i" + X "$i" + X "$i" + X "$iAuto" + X "$iDontUse" + X "$ifalse" + X "$ifalse" +} + +# --- 13f. Wave 6: HTTPService, WebService --- + +function Emit-HTTPServiceProperties { + param([string]$indent) + $i = $indent + + X "$i$(Esc-Xml $objName)" + Emit-MLText $i "Synonym" $synonym + X "$i" + + $rootURL = if ($def.rootURL) { "$($def.rootURL)" } else { $objName.ToLower() } + X "$i$(Esc-Xml $rootURL)" + + $reuseSessions = if ($def.reuseSessions) { "$($def.reuseSessions)" } else { "DontUse" } + X "$i$reuseSessions" + + $sessionMaxAge = if ($null -ne $def.sessionMaxAge) { "$($def.sessionMaxAge)" } else { "20" } + X "$i$sessionMaxAge" +} + +function Emit-WebServiceProperties { + param([string]$indent) + $i = $indent + + X "$i$(Esc-Xml $objName)" + Emit-MLText $i "Synonym" $synonym + X "$i" + + $namespace = if ($def.namespace) { "$($def.namespace)" } else { "" } + X "$i$(Esc-Xml $namespace)" + + $xdtoPackages = if ($def.xdtoPackages) { "$($def.xdtoPackages)" } else { "" } + if ($xdtoPackages) { X "$i$xdtoPackages" } else { X "$i" } + + $reuseSessions = if ($def.reuseSessions) { "$($def.reuseSessions)" } else { "DontUse" } + X "$i$reuseSessions" + + $sessionMaxAge = if ($null -ne $def.sessionMaxAge) { "$($def.sessionMaxAge)" } else { "20" } + X "$i$sessionMaxAge" +} + +# --- 13g. ChildObjects emitters for new types --- + +function Emit-Column { + param([string]$indent, $colDef) + $uuid = New-Guid-String + + $name = "" + $synonym = "" + $indexing = "DontIndex" + $references = @() + + if ($colDef -is [string]) { + $name = "$colDef" + $synonym = Split-CamelCase $name + } else { + $name = "$($colDef.name)" + $synonym = if ($colDef.synonym) { "$($colDef.synonym)" } else { Split-CamelCase $name } + if ($colDef.indexing) { $indexing = "$($colDef.indexing)" } + if ($colDef.references) { $references = @($colDef.references) } + } + + X "$indent" + X "$indent`t" + X "$indent`t`t$(Esc-Xml $name)" + Emit-MLText "$indent`t`t" "Synonym" $synonym + X "$indent`t`t" + X "$indent`t`t$indexing" + if ($references.Count -gt 0) { + X "$indent`t`t" + foreach ($ref in $references) { + X "$indent`t`t`t$ref" + } + X "$indent`t`t" + } else { + X "$indent`t`t" + } + X "$indent`t" + X "$indent" +} + +function Emit-AccountingFlag { + param([string]$indent, [string]$flagName) + $uuid = New-Guid-String + $flagSynonym = Split-CamelCase $flagName + + X "$indent" + X "$indent`t" + X "$indent`t`t$(Esc-Xml $flagName)" + Emit-MLText "$indent`t`t" "Synonym" $flagSynonym + X "$indent`t`t" + X "$indent`t`t" + X "$indent`t`t`txs:boolean" + X "$indent`t`t" + X "$indent`t`tfalse" + X "$indent`t`t" + X "$indent`t`t" + X "$indent`t`t" + X "$indent`t`tfalse" + X "$indent`t`t" + X "$indent`t`tfalse" + X "$indent`t`tfalse" + X "$indent`t`t" + X "$indent`t`t" + X "$indent`t`tDontCheck" + X "$indent`t`t" + X "$indent`t`t" + X "$indent`t`tAuto" + X "$indent`t`t" + X "$indent`t`t" + X "$indent`t`tAuto" + X "$indent`t" + X "$indent" +} + +function Emit-ExtDimensionAccountingFlag { + param([string]$indent, [string]$flagName) + $uuid = New-Guid-String + $flagSynonym = Split-CamelCase $flagName + + X "$indent" + X "$indent`t" + X "$indent`t`t$(Esc-Xml $flagName)" + Emit-MLText "$indent`t`t" "Synonym" $flagSynonym + X "$indent`t`t" + X "$indent`t`t" + X "$indent`t`t`txs:boolean" + X "$indent`t`t" + X "$indent`t`tfalse" + X "$indent`t`t" + X "$indent`t`t" + X "$indent`t`t" + X "$indent`t`tfalse" + X "$indent`t`t" + X "$indent`t`tfalse" + X "$indent`t`tfalse" + X "$indent`t`t" + X "$indent`t`t" + X "$indent`t`tDontCheck" + X "$indent`t`t" + X "$indent`t`t" + X "$indent`t`tAuto" + X "$indent`t`t" + X "$indent`t`t" + X "$indent`t`tAuto" + X "$indent`t" + X "$indent" +} + +function Emit-URLTemplate { + param([string]$indent, [string]$tmplName, $tmplDef) + $uuid = New-Guid-String + $tmplSynonym = Split-CamelCase $tmplName + + $template = "" + $methods = @{} + + if ($tmplDef -is [string]) { + $template = "$tmplDef" + } else { + $template = if ($tmplDef.template) { "$($tmplDef.template)" } else { "/$($tmplName.ToLower())" } + if ($tmplDef.methods) { + $tmplDef.methods.PSObject.Properties | ForEach-Object { + $methods[$_.Name] = "$($_.Value)" + } + } + } + + X "$indent" + X "$indent`t" + X "$indent`t`t$(Esc-Xml $tmplName)" + Emit-MLText "$indent`t`t" "Synonym" $tmplSynonym + X "$indent`t`t" + X "$indent`t" + + if ($methods.Count -gt 0) { + X "$indent`t" + foreach ($methodName in $methods.Keys) { + $methodUuid = New-Guid-String + $httpMethod = $methods[$methodName] + $methodSynonym = Split-CamelCase $methodName + $handler = "${tmplName}${methodName}" + + X "$indent`t`t" + X "$indent`t`t`t" + X "$indent`t`t`t`t$(Esc-Xml $methodName)" + Emit-MLText "$indent`t`t`t`t" "Synonym" $methodSynonym + X "$indent`t`t`t`t$httpMethod" + X "$indent`t`t`t`t$(Esc-Xml $handler)" + X "$indent`t`t`t" + X "$indent`t`t" + } + X "$indent`t" + } else { + X "$indent`t" + } + + X "$indent" +} + +function Emit-Operation { + param([string]$indent, [string]$opName, $opDef) + $uuid = New-Guid-String + $opSynonym = Split-CamelCase $opName + + $returnType = "xs:string" + $nillable = "false" + $transactioned = "false" + $handler = $opName + $params = @{} + + if ($opDef -is [string]) { + $returnType = "$opDef" + } else { + if ($opDef.returnType) { $returnType = "$($opDef.returnType)" } + if ($opDef.nillable -eq $true) { $nillable = "true" } + if ($opDef.transactioned -eq $true) { $transactioned = "true" } + if ($opDef.handler) { $handler = "$($opDef.handler)" } + if ($opDef.parameters) { + $opDef.parameters.PSObject.Properties | ForEach-Object { + $params[$_.Name] = $_.Value + } + } + } + + X "$indent" + X "$indent`t" + X "$indent`t`t$(Esc-Xml $opName)" + Emit-MLText "$indent`t`t" "Synonym" $opSynonym + X "$indent`t`t" + X "$indent`t`t$returnType" + X "$indent`t`t$nillable" + X "$indent`t`t$transactioned" + X "$indent`t`t$(Esc-Xml $handler)" + X "$indent`t" + + if ($params.Count -gt 0) { + X "$indent`t" + foreach ($paramName in $params.Keys) { + $paramUuid = New-Guid-String + $paramDef = $params[$paramName] + $paramSynonym = Split-CamelCase $paramName + $paramType = "xs:string" + $paramNillable = "true" + $paramDir = "In" + + if ($paramDef -is [string]) { + $paramType = "$paramDef" + } else { + if ($paramDef.type) { $paramType = "$($paramDef.type)" } + if ($paramDef.nillable -eq $false) { $paramNillable = "false" } + if ($paramDef.direction) { $paramDir = "$($paramDef.direction)" } + } + + X "$indent`t`t" + X "$indent`t`t`t" + X "$indent`t`t`t`t$(Esc-Xml $paramName)" + Emit-MLText "$indent`t`t`t`t" "Synonym" $paramSynonym + X "$indent`t`t`t`t$paramType" + X "$indent`t`t`t`t$paramNillable" + X "$indent`t`t`t`t$paramDir" + X "$indent`t`t`t" + X "$indent`t`t" + } + X "$indent`t" + } else { + X "$indent`t" + } + + X "$indent" +} + +function Emit-AddressingAttribute { + param([string]$indent, $addrDef) + $uuid = New-Guid-String + + $name = "" + $attrSynonym = "" + $typeStr = "" + $addressingDimension = "" + $indexing = "Index" + + if ($addrDef -is [string]) { + $name = "$addrDef" + $attrSynonym = Split-CamelCase $name + } else { + $name = "$($addrDef.name)" + $attrSynonym = if ($addrDef.synonym) { "$($addrDef.synonym)" } else { Split-CamelCase $name } + if ($addrDef.type) { $typeStr = "$($addrDef.type)" } + if ($addrDef.addressingDimension) { $addressingDimension = "$($addrDef.addressingDimension)" } + if ($addrDef.indexing) { $indexing = "$($addrDef.indexing)" } + } + + X "$indent" + X "$indent`t" + X "$indent`t`t$(Esc-Xml $name)" + Emit-MLText "$indent`t`t" "Synonym" $attrSynonym + X "$indent`t`t" + + if ($typeStr) { + Emit-ValueType "$indent`t`t" $typeStr + } else { + X "$indent`t`t" + X "$indent`t`t`txs:string" + X "$indent`t`t" + } + + if ($addressingDimension) { + X "$indent`t`t$addressingDimension" + } else { + X "$indent`t`t" + } + + X "$indent`t`t$indexing" + X "$indent`t`tUse" + X "$indent`t`tUse" + X "$indent`t" + X "$indent" +} + # --- 14. Namespaces --- $script:xmlnsDecl = 'xmlns="http://v8.1c.ru/8.3/MDClasses" xmlns:app="http://v8.1c.ru/8.2/managed-application/core" xmlns:cfg="http://v8.1c.ru/8.1/data/enterprise/current-config" xmlns:cmi="http://v8.1c.ru/8.2/managed-application/cmi" xmlns:ent="http://v8.1c.ru/8.1/data/enterprise" xmlns:lf="http://v8.1c.ru/8.2/managed-application/logform" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows" xmlns:xen="http://v8.1c.ru/8.3/xcf/enums" xmlns:xpr="http://v8.1c.ru/8.3/xcf/predef" 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"' @@ -1110,12 +2357,29 @@ Emit-InternalInfo "`t`t" $objType $objName X "`t`t" switch ($objType) { - "Catalog" { Emit-CatalogProperties "`t`t`t" } - "Document" { Emit-DocumentProperties "`t`t`t" } - "Enum" { Emit-EnumProperties "`t`t`t" } - "Constant" { Emit-ConstantProperties "`t`t`t" } - "InformationRegister" { Emit-InformationRegisterProperties "`t`t`t" } - "AccumulationRegister" { Emit-AccumulationRegisterProperties "`t`t`t" } + "Catalog" { Emit-CatalogProperties "`t`t`t" } + "Document" { Emit-DocumentProperties "`t`t`t" } + "Enum" { Emit-EnumProperties "`t`t`t" } + "Constant" { Emit-ConstantProperties "`t`t`t" } + "InformationRegister" { Emit-InformationRegisterProperties "`t`t`t" } + "AccumulationRegister" { Emit-AccumulationRegisterProperties "`t`t`t" } + "DefinedType" { Emit-DefinedTypeProperties "`t`t`t" } + "CommonModule" { Emit-CommonModuleProperties "`t`t`t" } + "ScheduledJob" { Emit-ScheduledJobProperties "`t`t`t" } + "EventSubscription" { Emit-EventSubscriptionProperties "`t`t`t" } + "Report" { Emit-ReportProperties "`t`t`t" } + "DataProcessor" { Emit-DataProcessorProperties "`t`t`t" } + "ExchangePlan" { Emit-ExchangePlanProperties "`t`t`t" } + "ChartOfCharacteristicTypes" { Emit-ChartOfCharacteristicTypesProperties "`t`t`t" } + "DocumentJournal" { Emit-DocumentJournalProperties "`t`t`t" } + "ChartOfAccounts" { Emit-ChartOfAccountsProperties "`t`t`t" } + "AccountingRegister" { Emit-AccountingRegisterProperties "`t`t`t" } + "ChartOfCalculationTypes" { Emit-ChartOfCalculationTypesProperties "`t`t`t" } + "CalculationRegister" { Emit-CalculationRegisterProperties "`t`t`t" } + "BusinessProcess" { Emit-BusinessProcessProperties "`t`t`t" } + "Task" { Emit-TaskProperties "`t`t`t" } + "HTTPService" { Emit-HTTPServiceProperties "`t`t`t" } + "WebService" { Emit-WebServiceProperties "`t`t`t" } } X "`t`t" @@ -1123,8 +2387,12 @@ X "`t`t" # ChildObjects $hasChildren = $false -# Catalog/Document: attributes + tabularSections -if ($objType -in @("Catalog","Document")) { +# --- Types with Attributes + TabularSections --- +$typesWithAttrTS = @("Catalog","Document","Report","DataProcessor","ExchangePlan", + "ChartOfCharacteristicTypes","ChartOfAccounts","ChartOfCalculationTypes", + "BusinessProcess","Task") + +if ($objType -in $typesWithAttrTS) { $attrs = @() if ($def.attributes) { foreach ($a in $def.attributes) { @@ -1138,10 +2406,29 @@ if ($objType -in @("Catalog","Document")) { } } - if ($attrs.Count -gt 0 -or $tsSections.Count -gt 0) { + # ChartOfAccounts: AccountingFlags + ExtDimensionAccountingFlags + $acctFlags = @() + $extDimFlags = @() + if ($objType -eq "ChartOfAccounts") { + if ($def.accountingFlags) { $acctFlags = @($def.accountingFlags) } + if ($def.extDimensionAccountingFlags) { $extDimFlags = @($def.extDimensionAccountingFlags) } + } + + # Task: AddressingAttributes + $addrAttrs = @() + if ($objType -eq "Task" -and $def.addressingAttributes) { + $addrAttrs = @($def.addressingAttributes) + } + + $childCount = $attrs.Count + $tsSections.Count + $acctFlags.Count + $extDimFlags.Count + $addrAttrs.Count + if ($childCount -gt 0) { $hasChildren = $true X "`t`t" - $context = $objType.ToLower() + $context = switch ($objType) { + "Catalog" { "catalog" } + "Document" { "document" } + default { "object" } + } foreach ($a in $attrs) { Emit-Attribute "`t`t`t" $a $context } @@ -1149,13 +2436,22 @@ if ($objType -in @("Catalog","Document")) { $columns = $tsSections[$tsName] Emit-TabularSection "`t`t`t" $tsName $columns $objType $objName } + foreach ($af in $acctFlags) { + Emit-AccountingFlag "`t`t`t" "$af" + } + foreach ($edf in $extDimFlags) { + Emit-ExtDimensionAccountingFlag "`t`t`t" "$edf" + } + foreach ($aa in $addrAttrs) { + Emit-AddressingAttribute "`t`t`t" $aa + } X "`t`t" } else { X "`t`t" } } -# Enum: enum values +# --- Enum: enum values --- if ($objType -eq "Enum") { $values = @() if ($def.values) { @@ -1175,10 +2471,10 @@ if ($objType -eq "Enum") { } } -# Constant: no ChildObjects element at all +# --- Constant, DefinedType, ScheduledJob, EventSubscription: no ChildObjects --- -# Registers: dimensions + resources + attributes -if ($objType -in @("InformationRegister","AccumulationRegister")) { +# --- Registers: dimensions + resources + attributes --- +if ($objType -in @("InformationRegister","AccumulationRegister","AccountingRegister","CalculationRegister")) { $dims = @() $resources = @() $regAttrs = @() @@ -1216,6 +2512,64 @@ if ($objType -in @("InformationRegister","AccumulationRegister")) { } } +# --- DocumentJournal: columns --- +if ($objType -eq "DocumentJournal") { + $columns = @() + if ($def.columns) { $columns = @($def.columns) } + if ($columns.Count -gt 0) { + $hasChildren = $true + X "`t`t" + foreach ($col in $columns) { + Emit-Column "`t`t`t" $col + } + X "`t`t" + } else { + X "`t`t" + } +} + +# --- HTTPService: URLTemplates --- +if ($objType -eq "HTTPService") { + $urlTemplates = @{} + if ($def.urlTemplates) { + $def.urlTemplates.PSObject.Properties | ForEach-Object { + $urlTemplates[$_.Name] = $_.Value + } + } + if ($urlTemplates.Count -gt 0) { + $hasChildren = $true + X "`t`t" + foreach ($tmplName in $urlTemplates.Keys) { + Emit-URLTemplate "`t`t`t" $tmplName $urlTemplates[$tmplName] + } + X "`t`t" + } else { + X "`t`t" + } +} + +# --- WebService: Operations --- +if ($objType -eq "WebService") { + $operations = @{} + if ($def.operations) { + $def.operations.PSObject.Properties | ForEach-Object { + $operations[$_.Name] = $_.Value + } + } + if ($operations.Count -gt 0) { + $hasChildren = $true + X "`t`t" + foreach ($opName in $operations.Keys) { + Emit-Operation "`t`t`t" $opName $operations[$opName] + } + X "`t`t" + } else { + X "`t`t" + } +} + +# --- CommonModule: no ChildObjects --- + X "`t" X "" @@ -1225,12 +2579,29 @@ $metadataXml = $script:xml.ToString() # Type → plural directory mapping $script:typePluralMap = @{ - "Catalog" = "Catalogs" - "Document" = "Documents" - "Enum" = "Enums" - "Constant" = "Constants" - "InformationRegister" = "InformationRegisters" - "AccumulationRegister" = "AccumulationRegisters" + "Catalog" = "Catalogs" + "Document" = "Documents" + "Enum" = "Enums" + "Constant" = "Constants" + "InformationRegister" = "InformationRegisters" + "AccumulationRegister" = "AccumulationRegisters" + "AccountingRegister" = "AccountingRegisters" + "CalculationRegister" = "CalculationRegisters" + "ChartOfAccounts" = "ChartsOfAccounts" + "ChartOfCharacteristicTypes"= "ChartsOfCharacteristicTypes" + "ChartOfCalculationTypes" = "ChartsOfCalculationTypes" + "BusinessProcess" = "BusinessProcesses" + "Task" = "Tasks" + "ExchangePlan" = "ExchangePlans" + "DocumentJournal" = "DocumentJournals" + "Report" = "Reports" + "DataProcessor" = "DataProcessors" + "CommonModule" = "CommonModules" + "ScheduledJob" = "ScheduledJobs" + "EventSubscription" = "EventSubscriptions" + "HTTPService" = "HTTPServices" + "WebService" = "WebServices" + "DefinedType" = "DefinedTypes" } $typePlural = $script:typePluralMap[$objType] @@ -1239,6 +2610,9 @@ $typeDir = Join-Path $OutputDir $typePlural # Main XML file: {OutputDir}/{TypePlural}/{Name}.xml $mainXmlPath = Join-Path $typeDir "$objName.xml" +# Types that don't have subdirectory structure (no Ext/, no modules) +$typesNoSubDir = @("DefinedType","ScheduledJob","EventSubscription") + # Object subdirectory: {OutputDir}/{TypePlural}/{Name}/Ext/ $objSubDir = Join-Path $typeDir $objName $extDir = Join-Path $objSubDir "Ext" @@ -1246,43 +2620,64 @@ $extDir = Join-Path $objSubDir "Ext" if (-not (Test-Path $typeDir)) { New-Item -ItemType Directory -Path $typeDir -Force | Out-Null } -if (-not (Test-Path $extDir)) { - New-Item -ItemType Directory -Path $extDir -Force | Out-Null +if ($objType -notin $typesNoSubDir) { + if (-not (Test-Path $extDir)) { + New-Item -ItemType Directory -Path $extDir -Force | Out-Null + } } $enc = New-Object System.Text.UTF8Encoding($true) [System.IO.File]::WriteAllText($mainXmlPath, $metadataXml, $enc) # Module files -$moduleCreated = "" -switch ($objType) { - "Catalog" { - $modulePath = Join-Path $extDir "ObjectModule.bsl" - if (-not (Test-Path $modulePath)) { - [System.IO.File]::WriteAllText($modulePath, "", $enc) - $moduleCreated = $modulePath - } +$modulesCreated = @() + +# Types with ObjectModule.bsl +$typesWithObjectModule = @("Catalog","Document","Report","DataProcessor","ExchangePlan", + "ChartOfAccounts","ChartOfCharacteristicTypes","ChartOfCalculationTypes", + "BusinessProcess","Task") +# Types with RecordSetModule.bsl +$typesWithRecordSetModule = @("InformationRegister","AccumulationRegister","AccountingRegister","CalculationRegister") +# Types with Module.bsl (general) +$typesWithModule = @("CommonModule","HTTPService","WebService") + +if ($objType -in $typesWithObjectModule) { + $modulePath = Join-Path $extDir "ObjectModule.bsl" + if (-not (Test-Path $modulePath)) { + [System.IO.File]::WriteAllText($modulePath, "", $enc) + $modulesCreated += $modulePath } - "Document" { - $modulePath = Join-Path $extDir "ObjectModule.bsl" - if (-not (Test-Path $modulePath)) { - [System.IO.File]::WriteAllText($modulePath, "", $enc) - $moduleCreated = $modulePath - } +} +if ($objType -in $typesWithRecordSetModule) { + $modulePath = Join-Path $extDir "RecordSetModule.bsl" + if (-not (Test-Path $modulePath)) { + [System.IO.File]::WriteAllText($modulePath, "", $enc) + $modulesCreated += $modulePath } - "InformationRegister" { - $modulePath = Join-Path $extDir "RecordSetModule.bsl" - if (-not (Test-Path $modulePath)) { - [System.IO.File]::WriteAllText($modulePath, "", $enc) - $moduleCreated = $modulePath - } +} +if ($objType -in $typesWithModule) { + $modulePath = Join-Path $extDir "Module.bsl" + if (-not (Test-Path $modulePath)) { + [System.IO.File]::WriteAllText($modulePath, "", $enc) + $modulesCreated += $modulePath } - "AccumulationRegister" { - $modulePath = Join-Path $extDir "RecordSetModule.bsl" - if (-not (Test-Path $modulePath)) { - [System.IO.File]::WriteAllText($modulePath, "", $enc) - $moduleCreated = $modulePath - } +} + +# Special files +if ($objType -eq "ExchangePlan") { + $contentPath = Join-Path $extDir "Content.xml" + if (-not (Test-Path $contentPath)) { + $contentXml = "`r`n`r`n" + [System.IO.File]::WriteAllText($contentPath, $contentXml, $enc) + $modulesCreated += $contentPath + } +} +if ($objType -eq "BusinessProcess") { + $flowchartPath = Join-Path $extDir "Flowchart.xml" + if (-not (Test-Path $flowchartPath)) { + $flowchartXml = "`r`n`r`n" + [System.IO.File]::WriteAllText($flowchartPath, $flowchartXml, $enc) + $modulesCreated += $flowchartPath } } @@ -1365,12 +2760,14 @@ $tsCount = 0 $dimCount = 0 $resCount = 0 $valCount = 0 +$colCount = 0 if ($def.attributes) { $attrCount = @($def.attributes).Count } if ($def.tabularSections) { $tsCount = @($def.tabularSections.PSObject.Properties).Count } if ($def.dimensions) { $dimCount = @($def.dimensions).Count } if ($def.resources) { $resCount = @($def.resources).Count } if ($def.values) { $valCount = @($def.values).Count } +if ($def.columns) { $colCount = @($def.columns).Count } Write-Host "[OK] $objType '$objName' compiled" Write-Host " UUID: $uuid" @@ -1382,13 +2779,14 @@ if ($tsCount -gt 0) { $details += "TabularSections: $tsCount" } if ($dimCount -gt 0) { $details += "Dimensions: $dimCount" } if ($resCount -gt 0) { $details += "Resources: $resCount" } if ($valCount -gt 0) { $details += "Values: $valCount" } +if ($colCount -gt 0) { $details += "Columns: $colCount" } if ($details.Count -gt 0) { Write-Host " $($details -join ', ')" } -if ($moduleCreated) { - Write-Host " Module: $moduleCreated" +foreach ($mc in $modulesCreated) { + Write-Host " Module: $mc" } switch ($regResult) { diff --git a/docs/meta-dsl-spec.md b/docs/meta-dsl-spec.md index bae3bb21..9cac2986 100644 --- a/docs/meta-dsl-spec.md +++ b/docs/meta-dsl-spec.md @@ -1,12 +1,12 @@ # Meta DSL — спецификация JSON-формата для объектов метаданных 1С -Версия: 1.0 +Версия: 2.0 ## Обзор JSON DSL для описания объектов метаданных конфигурации 1С. Компактный формат компилируется в полноценный XML, совместимый с выгрузкой конфигурации 1С:Предприятие 8.3. -Поддерживаемые типы (Фаза 1): **Catalog**, **Document**, **Enum**, **Constant**, **InformationRegister**, **AccumulationRegister**. +Поддерживаемые типы (23): **Catalog**, **Document**, **Enum**, **Constant**, **InformationRegister**, **AccumulationRegister**, **AccountingRegister**, **CalculationRegister**, **ChartOfAccounts**, **ChartOfCharacteristicTypes**, **ChartOfCalculationTypes**, **BusinessProcess**, **Task**, **ExchangePlan**, **DocumentJournal**, **Report**, **DataProcessor**, **CommonModule**, **ScheduledJob**, **EventSubscription**, **HTTPService**, **WebService**, **DefinedType**. --- @@ -76,6 +76,11 @@ JSON DSL для описания объектов метаданных конф | `DocumentRef.Xxx` | `cfg:DocumentRef.Xxx` | | `EnumRef.Xxx` | `cfg:EnumRef.Xxx` | | `ChartOfAccountsRef.Xxx` | `cfg:ChartOfAccountsRef.Xxx` | +| `ChartOfCharacteristicTypesRef.Xxx` | `cfg:ChartOfCharacteristicTypesRef.Xxx` | +| `ChartOfCalculationTypesRef.Xxx` | `cfg:ChartOfCalculationTypesRef.Xxx` | +| `ExchangePlanRef.Xxx` | `cfg:ExchangePlanRef.Xxx` | +| `BusinessProcessRef.Xxx` | `cfg:BusinessProcessRef.Xxx` | +| `TaskRef.Xxx` | `cfg:TaskRef.Xxx` | | `DefinedType.Xxx` | `cfg:DefinedType.Xxx` (через `v8:TypeSet`) | ### 3.3 Русские синонимы типов @@ -91,6 +96,11 @@ JSON DSL для описания объектов метаданных конф | `ДокументСсылка.Xxx` | `DocumentRef.Xxx` | | `ПеречислениеСсылка.Xxx` | `EnumRef.Xxx` | | `ПланСчетовСсылка.Xxx` | `ChartOfAccountsRef.Xxx` | +| `ПланВидовХарактеристикСсылка.Xxx` | `ChartOfCharacteristicTypesRef.Xxx` | +| `ПланВидовРасчётаСсылка.Xxx` | `ChartOfCalculationTypesRef.Xxx` | +| `ПланОбменаСсылка.Xxx` | `ExchangePlanRef.Xxx` | +| `БизнесПроцессСсылка.Xxx` | `BusinessProcessRef.Xxx` | +| `ЗадачаСсылка.Xxx` | `TaskRef.Xxx` | | `ОпределяемыйТип.Xxx` | `DefinedType.Xxx` | Регистронезависимые. @@ -139,7 +149,7 @@ JSON DSL для описания объектов метаданных конф ## 5. Табличные части -Только для Catalog и Document. +Для типов с ChildObjects → TabularSection: Catalog, Document, ExchangePlan, ChartOfCharacteristicTypes, ChartOfCalculationTypes, BusinessProcess, Task, Report, DataProcessor, ChartOfAccounts. ```json "tabularSections": { @@ -157,6 +167,8 @@ JSON DSL для описания объектов метаданных конф Ключ — имя табличной части, значение — массив реквизитов (в строковой или объектной форме). +Для Catalog и Document добавляется `ForItem` в Properties табличной части. + --- ## 6. Значения перечислений @@ -260,6 +272,399 @@ JSON DSL для описания объектов метаданных конф | `resources` | `[]` | → Resource в ChildObjects | | `attributes` | `[]` | → Attribute в ChildObjects | +### 7.7 DefinedType + +| Поле JSON | Умолчание | XML элемент | +|-----------|----------|-------------| +| `valueTypes` | `[]` | Type (составной — массив `v8:Type`) | + +Без ChildObjects и модулей. + +```json +{ "type": "DefinedType", "name": "ДенежныеСредства", "valueTypes": ["CatalogRef.БанковскиеСчета", "CatalogRef.Кассы"] } +``` + +### 7.8 CommonModule + +| Поле JSON | Умолчание | XML элемент | +|-----------|----------|-------------| +| `context` | — | Шорткат (см. ниже) | +| `global` | `false` | Global | +| `server` | `false` | Server | +| `serverCall` | `false` | ServerCall | +| `clientManagedApplication` | `false` | ClientManagedApplication | +| `clientOrdinaryApplication` | `false` | ClientOrdinaryApplication | +| `externalConnection` | `false` | ExternalConnection | +| `privileged` | `false` | Privileged | +| `returnValuesReuse` | `DontUse` | ReturnValuesReuse | + +Шорткаты `context`: +- `"server"` → Server=true, ServerCall=true +- `"client"` → ClientManagedApplication=true +- `"serverClient"` → Server=true, ClientManagedApplication=true + +Модуль: `Ext/Module.bsl` (пустой). + +```json +{ "type": "CommonModule", "name": "ОбменДаннымиСервер", "context": "server", "returnValuesReuse": "DuringRequest" } +``` + +### 7.9 ScheduledJob + +| Поле JSON | Умолчание | XML элемент | +|-----------|----------|-------------| +| `methodName` | `""` | MethodName | +| `description` | = synonym | Description | +| `key` | `""` | Key | +| `use` | `false` | Use | +| `predefined` | `false` | Predefined | +| `restartCountOnFailure` | `3` | RestartCountOnFailure | +| `restartIntervalOnFailure` | `10` | RestartIntervalOnFailure | + +Без ChildObjects и модулей. + +```json +{ "type": "ScheduledJob", "name": "ОбменДанными", "methodName": "ОбменДаннымиСервер.Выполнить", "use": true } +``` + +### 7.10 EventSubscription + +| Поле JSON | Умолчание | XML элемент | +|-----------|----------|-------------| +| `source` | `[]` | Source (массив `v8:Type`, формат `cfg:XxxObject.Name`) | +| `event` | `BeforeWrite` | Event | +| `handler` | `""` | Handler | + +Без ChildObjects и модулей. + +Значения `event`: `BeforeWrite`, `OnWrite`, `BeforeDelete`, `OnReadAtServer`, `FillCheckProcessing` и др. + +```json +{ "type": "EventSubscription", "name": "ПередЗаписьюКонтрагента", "source": ["CatalogObject.Контрагенты"], "event": "BeforeWrite", "handler": "ОбщегоНазначенияСервер.ПередЗаписьюКонтрагента" } +``` + +### 7.11 Report + +| Поле JSON | Умолчание | XML элемент | +|-----------|----------|-------------| +| `defaultForm` | `""` | DefaultForm | +| `auxiliaryForm` | `""` | AuxiliaryForm | +| `mainDataCompositionSchema` | `""` | MainDataCompositionSchema | +| `defaultSettingsForm` | `""` | DefaultSettingsForm | +| `auxiliarySettingsForm` | `""` | AuxiliarySettingsForm | +| `defaultVariantForm` | `""` | DefaultVariantForm | +| `attributes` | `[]` | → Attribute в ChildObjects | +| `tabularSections` | `{}` | → TabularSection в ChildObjects | + +Модули: `Ext/ObjectModule.bsl` (пустой). + +```json +{ "type": "Report", "name": "ОстаткиТоваров", "attributes": ["НачалоПериода: Date", "КонецПериода: Date"] } +``` + +### 7.12 DataProcessor + +| Поле JSON | Умолчание | XML элемент | +|-----------|----------|-------------| +| `defaultForm` | `""` | DefaultForm | +| `auxiliaryForm` | `""` | AuxiliaryForm | +| `attributes` | `[]` | → Attribute в ChildObjects | +| `tabularSections` | `{}` | → TabularSection в ChildObjects | + +Модули: `Ext/ObjectModule.bsl` (пустой). + +```json +{ "type": "DataProcessor", "name": "ЗагрузкаДанных", "attributes": ["ПутьКФайлу: String(500)"] } +``` + +### 7.13 ExchangePlan + +| Поле JSON | Умолчание | XML элемент | +|-----------|----------|-------------| +| `codeLength` | `9` | CodeLength | +| `codeType` | `String` | CodeType | +| `codeAllowedLength` | `Variable` | CodeAllowedLength | +| `descriptionLength` | `100` | DescriptionLength | +| `autonumbering` | `true` | Autonumbering | +| `checkUnique` | `false` | CheckUnique | +| `distributedInfoBase` | `false` | DistributedInfoBase | +| `includeConfigurationExtensions` | `false` | IncludeConfigurationExtensions | +| `dataLockControlMode` | `Automatic` | DataLockControlMode | +| `fullTextSearch` | `Use` | FullTextSearch | +| `attributes` | `[]` | → Attribute в ChildObjects | +| `tabularSections` | `{}` | → TabularSection в ChildObjects | + +Модули: `Ext/ObjectModule.bsl` (пустой). +Дополнительно: `Ext/Content.xml` (пустой шаблон). + +```json +{ "type": "ExchangePlan", "name": "ОбменССайтом", "attributes": ["АдресСервера: String(200)"] } +``` + +### 7.14 ChartOfCharacteristicTypes + +| Поле JSON | Умолчание | XML элемент | +|-----------|----------|-------------| +| `codeLength` | `9` | CodeLength | +| `codeType` | `String` | CodeType | +| `codeAllowedLength` | `Variable` | CodeAllowedLength | +| `descriptionLength` | `25` | DescriptionLength | +| `autonumbering` | `true` | Autonumbering | +| `checkUnique` | `false` | CheckUnique | +| `characteristicExtValues` | `""` | CharacteristicExtValues | +| `valueTypes` | авто* | Type (составной тип значений характеристик) | +| `hierarchical` | `false` | Hierarchical | +| `dataLockControlMode` | `Automatic` | DataLockControlMode | +| `fullTextSearch` | `Use` | FullTextSearch | +| `attributes` | `[]` | → Attribute в ChildObjects | +| `tabularSections` | `{}` | → TabularSection в ChildObjects | + +\* Если `valueTypes` не указан, по умолчанию: Boolean, String, Number(15,2), DateTime. + +Модули: `Ext/ObjectModule.bsl` (пустой). + +```json +{ + "type": "ChartOfCharacteristicTypes", "name": "ВидыСубконто", + "valueTypes": ["CatalogRef.Номенклатура", "CatalogRef.Контрагенты", "Boolean", "String", "Number(15,2)"] +} +``` + +### 7.15 DocumentJournal + +| Поле JSON | Умолчание | XML элемент | +|-----------|----------|-------------| +| `defaultForm` | `""` | DefaultForm | +| `auxiliaryForm` | `""` | AuxiliaryForm | +| `registeredDocuments` | `[]` | RegisteredDocuments | +| `columns` | `[]` | → Column в ChildObjects | + +Без модулей. + +DSL для `registeredDocuments` — массив строк `"Document.ИмяДокумента"` (или русский `"Документ.ИмяДокумента"`). + +DSL для `columns` (§12). + +```json +{ + "type": "DocumentJournal", "name": "Взаимодействия", + "registeredDocuments": ["Document.Встреча", "Document.ТелефонныйЗвонок"], + "columns": [{ "name": "Организация", "indexing": "Index", "references": ["Document.Встреча.Attribute.Организация"] }] +} +``` + +### 7.16 ChartOfAccounts + +| Поле JSON | Умолчание | XML элемент | +|-----------|----------|-------------| +| `extDimensionTypes` | `""` | ExtDimensionTypes (ссылка на ПВХ) | +| `maxExtDimensionCount` | `3` | MaxExtDimensionCount | +| `codeMask` | `""` | CodeMask | +| `codeLength` | `8` | CodeLength | +| `descriptionLength` | `120` | DescriptionLength | +| `codeSeries` | `WholeChartOfAccounts` | CodeSeries | +| `autoOrderByCode` | `true` | AutoOrderByCode | +| `orderLength` | `5` | OrderLength | +| `hierarchical` | `false` | Hierarchical | +| `dataLockControlMode` | `Automatic` | DataLockControlMode | +| `fullTextSearch` | `Use` | FullTextSearch | +| `accountingFlags` | `[]` | → AccountingFlag в ChildObjects (§13) | +| `extDimensionAccountingFlags` | `[]` | → ExtDimensionAccountingFlag в ChildObjects (§14) | +| `attributes` | `[]` | → Attribute в ChildObjects | +| `tabularSections` | `{}` | → TabularSection в ChildObjects | + +Модули: `Ext/ObjectModule.bsl` (пустой). + +```json +{ + "type": "ChartOfAccounts", "name": "Хозрасчетный", + "extDimensionTypes": "ChartOfCharacteristicTypes.ВидыСубконто", "maxExtDimensionCount": 3, + "codeMask": "@@@.@@.@", "codeLength": 8, + "accountingFlags": ["Валютный", "Количественный"], + "extDimensionAccountingFlags": ["Суммовой", "Валютный"] +} +``` + +### 7.17 AccountingRegister + +| Поле JSON | Умолчание | XML элемент | +|-----------|----------|-------------| +| `chartOfAccounts` | `""` | ChartOfAccounts (ссылка на план счетов) | +| `correspondence` | `false` | Correspondence | +| `periodAdjustmentLength` | `0` | PeriodAdjustmentLength | +| `dataLockControlMode` | `Automatic` | DataLockControlMode | +| `fullTextSearch` | `Use` | FullTextSearch | +| `dimensions` | `[]` | → Dimension в ChildObjects | +| `resources` | `[]` | → Resource в ChildObjects | +| `attributes` | `[]` | → Attribute в ChildObjects | + +Модули: `Ext/RecordSetModule.bsl` (пустой). + +```json +{ + "type": "AccountingRegister", "name": "Хозрасчетный", + "chartOfAccounts": "ChartOfAccounts.Хозрасчетный", "correspondence": true, + "dimensions": ["Организация: CatalogRef.Организации"], + "resources": ["Сумма: Number(15,2)"] +} +``` + +### 7.18 ChartOfCalculationTypes + +| Поле JSON | Умолчание | XML элемент | +|-----------|----------|-------------| +| `codeLength` | `9` | CodeLength | +| `codeType` | `String` | CodeType | +| `codeAllowedLength` | `Variable` | CodeAllowedLength | +| `descriptionLength` | `25` | DescriptionLength | +| `autonumbering` | `true` | Autonumbering | +| `checkUnique` | `false` | CheckUnique | +| `dependenceOnCalculationTypes` | `NotUsed` | DependenceOnCalculationTypes | +| `baseCalculationTypes` | `[]` | BaseCalculationTypes | +| `actionPeriodUse` | `false` | ActionPeriodUse | +| `dataLockControlMode` | `Automatic` | DataLockControlMode | +| `fullTextSearch` | `Use` | FullTextSearch | +| `attributes` | `[]` | → Attribute в ChildObjects | +| `tabularSections` | `{}` | → TabularSection в ChildObjects | + +Значения `dependenceOnCalculationTypes`: `NotUsed`, `ExclusionAndDependence`, `ExclusionOnly`. + +Модули: `Ext/ObjectModule.bsl` (пустой). + +```json +{ + "type": "ChartOfCalculationTypes", "name": "Начисления", + "dependenceOnCalculationTypes": "ExclusionAndDependence", + "actionPeriodUse": true +} +``` + +### 7.19 CalculationRegister + +| Поле JSON | Умолчание | XML элемент | +|-----------|----------|-------------| +| `chartOfCalculationTypes` | `""` | ChartOfCalculationTypes (ссылка на ПВР) | +| `periodicity` | `Month` | Periodicity | +| `actionPeriod` | `false` | ActionPeriod | +| `basePeriod` | `false` | BasePeriod | +| `schedule` | `""` | Schedule (ссылка на РС графиков) | +| `scheduleValue` | `""` | ScheduleValue | +| `scheduleDate` | `""` | ScheduleDate | +| `dataLockControlMode` | `Automatic` | DataLockControlMode | +| `fullTextSearch` | `Use` | FullTextSearch | +| `dimensions` | `[]` | → Dimension в ChildObjects | +| `resources` | `[]` | → Resource в ChildObjects | +| `attributes` | `[]` | → Attribute в ChildObjects | + +Модули: `Ext/RecordSetModule.bsl` (пустой). + +```json +{ + "type": "CalculationRegister", "name": "Начисления", + "chartOfCalculationTypes": "ChartOfCalculationTypes.Начисления", + "periodicity": "Month", "actionPeriod": true, "basePeriod": true, + "dimensions": ["Сотрудник: CatalogRef.Сотрудники"], + "resources": ["Сумма: Number(15,2)", "Дни: Number(3,0)"] +} +``` + +### 7.20 BusinessProcess + +| Поле JSON | Умолчание | XML элемент | +|-----------|----------|-------------| +| `editType` | `InDialog` | EditType | +| `numberType` | `String` | NumberType | +| `numberLength` | `11` | NumberLength | +| `numberAllowedLength` | `Variable` | NumberAllowedLength | +| `checkUnique` | `true` | CheckUnique | +| `autonumbering` | `true` | Autonumbering | +| `dataLockControlMode` | `Automatic` | DataLockControlMode | +| `fullTextSearch` | `Use` | FullTextSearch | +| `attributes` | `[]` | → Attribute в ChildObjects | +| `tabularSections` | `{}` | → TabularSection в ChildObjects | + +Модули: `Ext/ObjectModule.bsl` (пустой). +Дополнительно: `Ext/Flowchart.xml` (заглушка карты маршрута). + +```json +{ "type": "BusinessProcess", "name": "Задание", "attributes": ["Описание: String(200)"] } +``` + +### 7.21 Task + +| Поле JSON | Умолчание | XML элемент | +|-----------|----------|-------------| +| `numberType` | `String` | NumberType | +| `numberLength` | `14` | NumberLength | +| `numberAllowedLength` | `Variable` | NumberAllowedLength | +| `checkUnique` | `true` | CheckUnique | +| `autonumbering` | `true` | Autonumbering | +| `taskNumberAutoPrefix` | `BusinessProcessNumber` | TaskNumberAutoPrefix | +| `descriptionLength` | `150` | DescriptionLength | +| `addressing` | `""` | Addressing (ссылка на РС адресации) | +| `mainAddressingAttribute` | `""` | MainAddressingAttribute | +| `currentPerformer` | `""` | CurrentPerformer | +| `dataLockControlMode` | `Automatic` | DataLockControlMode | +| `fullTextSearch` | `Use` | FullTextSearch | +| `attributes` | `[]` | → Attribute в ChildObjects | +| `tabularSections` | `{}` | → TabularSection в ChildObjects | +| `addressingAttributes` | `[]` | → AddressingAttribute в ChildObjects (§15) | + +Модули: `Ext/ObjectModule.bsl` (пустой). + +```json +{ + "type": "Task", "name": "ЗадачаИсполнителя", "descriptionLength": 200, + "addressing": "InformationRegister.АдресацияЗадач", + "addressingAttributes": [{ "name": "Исполнитель", "type": "CatalogRef.Пользователи", "addressingDimension": "InformationRegister.АдресацияЗадач.Dimension.Исполнитель" }] +} +``` + +### 7.22 HTTPService + +| Поле JSON | Умолчание | XML элемент | +|-----------|----------|-------------| +| `rootURL` | = имя (lowercase) | RootURL | +| `reuseSessions` | `DontUse` | ReuseSessions | +| `sessionMaxAge` | `20` | SessionMaxAge | +| `urlTemplates` | `{}` | → URLTemplate в ChildObjects (§16) | + +Модули: `Ext/Module.bsl` (пустой). + +```json +{ + "type": "HTTPService", "name": "API", "rootURL": "api", + "urlTemplates": { + "Users": { "template": "/v1/users", "methods": { "Get": "GET", "Create": "POST" } } + } +} +``` + +### 7.23 WebService + +| Поле JSON | Умолчание | XML элемент | +|-----------|----------|-------------| +| `namespace` | `""` | Namespace | +| `xdtoPackages` | `""` | XDTOPackages | +| `reuseSessions` | `DontUse` | ReuseSessions | +| `sessionMaxAge` | `20` | SessionMaxAge | +| `operations` | `{}` | → Operation в ChildObjects (§17) | + +Модули: `Ext/Module.bsl` (пустой). + +```json +{ + "type": "WebService", "name": "DataExchange", "namespace": "http://www.1c.ru/DataExchange", + "operations": { + "TestConnection": { + "returnType": "xs:boolean", + "handler": "ПроверкаПодключения", + "parameters": { "ErrorMessage": { "type": "xs:string", "direction": "Out" } } + } + } +} +``` + --- ## 8. Русские синонимы типов объектов @@ -272,6 +677,23 @@ JSON DSL для описания объектов метаданных конф | `Константа` | `Constant` | | `РегистрСведений` | `InformationRegister` | | `РегистрНакопления` | `AccumulationRegister` | +| `РегистрБухгалтерии` | `AccountingRegister` | +| `РегистрРасчёта` | `CalculationRegister` | +| `ПланСчетов` | `ChartOfAccounts` | +| `ПланВидовХарактеристик` | `ChartOfCharacteristicTypes` | +| `ПланВидовРасчёта` | `ChartOfCalculationTypes` | +| `БизнесПроцесс` | `BusinessProcess` | +| `Задача` | `Task` | +| `ПланОбмена` | `ExchangePlan` | +| `ЖурналДокументов` | `DocumentJournal` | +| `Отчёт` | `Report` | +| `Обработка` | `DataProcessor` | +| `ОбщийМодуль` | `CommonModule` | +| `РегламентноеЗадание` | `ScheduledJob` | +| `ПодпискаНаСобытие` | `EventSubscription` | +| `HTTPСервис` | `HTTPService` | +| `ВебСервис` | `WebService` | +| `ОпределяемыйТип` | `DefinedType` | --- @@ -312,6 +734,8 @@ JSON DSL для описания объектов метаданных конф Флаг `useInTotals` — только для измерений AccumulationRegister (по умолчанию `true`). +Применимо к: InformationRegister, AccumulationRegister, AccountingRegister, CalculationRegister. + --- ## 11. Примеры @@ -410,3 +834,252 @@ JSON DSL для описания объектов метаданных конф ] } ``` + +### Определяемый тип + +```json +{ "type": "DefinedType", "name": "ДенежныеСредства", "valueTypes": ["CatalogRef.БанковскиеСчета", "CatalogRef.Кассы"] } +``` + +### Общий модуль + +```json +{ "type": "CommonModule", "name": "ОбменДаннымиСервер", "context": "server", "returnValuesReuse": "DuringRequest" } +``` + +### План обмена + +```json +{ "type": "ExchangePlan", "name": "ОбменССайтом", "attributes": ["АдресСервера: String(200)"] } +``` + +### Журнал документов + +```json +{ + "type": "DocumentJournal", "name": "Взаимодействия", + "registeredDocuments": ["Document.Встреча", "Document.ТелефонныйЗвонок"], + "columns": [{ "name": "Организация", "indexing": "Index", "references": ["Document.Встреча.Attribute.Организация"] }] +} +``` + +### План счетов + +```json +{ + "type": "ChartOfAccounts", "name": "Хозрасчетный", + "extDimensionTypes": "ChartOfCharacteristicTypes.ВидыСубконто", "maxExtDimensionCount": 3, + "codeMask": "@@@.@@.@", "codeLength": 8, + "accountingFlags": ["Валютный", "Количественный"], + "extDimensionAccountingFlags": ["Суммовой", "Валютный"] +} +``` + +### HTTP-сервис + +```json +{ + "type": "HTTPService", "name": "API", "rootURL": "api", + "urlTemplates": { + "Users": { "template": "/v1/users", "methods": { "Get": "GET", "Create": "POST" } } + } +} +``` + +### Веб-сервис + +```json +{ + "type": "WebService", "name": "DataExchange", "namespace": "http://www.1c.ru/DataExchange", + "operations": { + "TestConnection": { + "returnType": "xs:boolean", + "handler": "ПроверкаПодключения", + "parameters": { "ErrorMessage": { "type": "xs:string", "direction": "Out" } } + } + } +} +``` + +### Бизнес-процесс + +```json +{ "type": "BusinessProcess", "name": "Задание", "attributes": ["Описание: String(200)"] } +``` + +### Задача + +```json +{ + "type": "Task", "name": "ЗадачаИсполнителя", "descriptionLength": 200, + "addressing": "InformationRegister.АдресацияЗадач", + "addressingAttributes": [{ "name": "Исполнитель", "type": "CatalogRef.Пользователи" }] +} +``` + +--- + +## 12. Графы журнала документов (columns) + +Только для DocumentJournal. + +### Строковая форма + +```json +"columns": ["Организация", "Контрагент"] +``` + +Создаёт графу без ссылок, без индексации. + +### Объектная форма + +```json +"columns": [ + { + "name": "Организация", + "synonym": "Организация", + "indexing": "Index", + "references": [ + "Document.Встреча.Attribute.Организация", + "Document.ТелефонныйЗвонок.Attribute.Организация" + ] + } +] +``` + +| Поле | Умолчание | Описание | +|------|----------|----------| +| `name` | — | Имя графы (обязательное) | +| `synonym` | авто | Синоним | +| `indexing` | `DontIndex` | `DontIndex` / `Index` | +| `references` | `[]` | Ссылки на реквизиты регистрируемых документов | + +--- + +## 13. Признаки учёта (accountingFlags) + +Только для ChartOfAccounts. + +```json +"accountingFlags": ["Валютный", "Количественный"] +``` + +Массив имён. Каждый признак — Boolean-тип. Синоним авто из CamelCase. + +--- + +## 14. Признаки учёта субконто (extDimensionAccountingFlags) + +Только для ChartOfAccounts. + +```json +"extDimensionAccountingFlags": ["Суммовой", "Валютный"] +``` + +Аналогично accountingFlags, но применяется к субконто (ExtDimensionTypes). + +--- + +## 15. Реквизиты адресации (addressingAttributes) + +Только для Task. + +### Строковая форма + +```json +"addressingAttributes": ["Исполнитель"] +``` + +### Объектная форма + +```json +"addressingAttributes": [ + { + "name": "Исполнитель", + "type": "CatalogRef.Пользователи", + "addressingDimension": "InformationRegister.АдресацияЗадач.Dimension.Исполнитель" + } +] +``` + +| Поле | Умолчание | Описание | +|------|----------|----------| +| `name` | — | Имя реквизита (обязательное) | +| `type` | `String` | Тип значения | +| `synonym` | авто | Синоним | +| `addressingDimension` | `""` | Ссылка на измерение регистра адресации | + +--- + +## 16. URL-шаблоны HTTP-сервиса (urlTemplates) + +Только для HTTPService. + +```json +"urlTemplates": { + "Users": { + "template": "/v1/users", + "methods": { + "Get": "GET", + "Create": "POST" + } + } +} +``` + +Ключ — имя шаблона. Значение — объект: + +| Поле | Умолчание | Описание | +|------|----------|----------| +| `template` | `/{name}` | URL-шаблон (строка) | +| `methods` | `{}` | Имя метода → HTTP-метод (`GET`, `POST`, `PUT`, `DELETE`, `PATCH`) | + +Обработчик метода авто: `{TemplateName}{MethodName}` (напр. `UsersGet`). + +Если значение — строка, интерпретируется как `template` без методов. + +--- + +## 17. Операции веб-сервиса (operations) + +Только для WebService. + +```json +"operations": { + "TestConnection": { + "returnType": "xs:boolean", + "handler": "ПроверкаПодключения", + "nillable": false, + "transactioned": false, + "parameters": { + "ErrorMessage": { + "type": "xs:string", + "nillable": true, + "direction": "Out" + } + } + } +} +``` + +Ключ — имя операции. Значение — объект: + +| Поле | Умолчание | Описание | +|------|----------|----------| +| `returnType` | `xs:string` | XDTO-тип возвращаемого значения | +| `handler` | = имя операции | Имя процедуры-обработчика | +| `nillable` | `false` | Может ли возвращать null | +| `transactioned` | `false` | Выполняется в транзакции | +| `parameters` | `{}` | Параметры операции | + +Если значение — строка, интерпретируется как `returnType`. + +### Параметры операции + +| Поле | Умолчание | Описание | +|------|----------|----------| +| `type` | `xs:string` | XDTO-тип параметра | +| `nillable` | `true` | Может ли быть null | +| `direction` | `In` | Направление: `In` / `Out` / `InOut` | + +Если значение — строка, интерпретируется как `type`.