fix(form-add): вид объекта берём из структуры документа, а не поиском по имени

Вид искался как первое совпадение //md:<Вид> по всему файлу и потому зависел
от порядка перебора видов. У бизнес-процесса есть свойство <Task>, и объект
определялся как задача, после чего имя не находилось вовсе: «Не удалось
определить имя объекта из Properties/Name». Прежний упорядоченный список видов
это маскировал — в нём BusinessProcess стоял раньше Task.

Теперь вид — первый элемент-потомок MetaDataObject, и неподдерживаемый вид
отвергается по имени, а не проваливается в поиск имени объекта.

Нашлось платформенной проверкой всех видов разом: собрана конфигурация с
формой каждого поддержанного вида (15 видов, 43 формы) и загружена в 1С.

Заодно покрытие назначений доведено до полного (добавились FolderChoice, Load,
Record), а мелкие кейсы на один объект объединены: несколько назначений в одном
кейсе, эталон показывает все слоты сразу.

Гард дополнен инвариантом «ровно одна основная форма на вид» и его паритетом
между портами — именно им пользуется умолчание -Purpose.

Инструкция: в таблице параметров умолчание Purpose исправлено с Object на
основную форму вида.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-08-21 12:55:30 +03:00
co-authored by Claude Opus 5
parent 0f7745af4b
commit 53fc16d2f1
49 changed files with 294 additions and 472 deletions
+1 -1
View File
@@ -25,7 +25,7 @@ allowed-tools:
|-------------|:------------:|--------------|----------------------------------------------|
| ObjectPath | да | — | Путь к XML-файлу объекта (Documents/Док.xml) |
| FormName | да | — | Имя формы (ФормаДокумента) |
| Purpose | нет | Object | Назначение формы — см. таблицу ниже |
| Purpose | нет | основная форма вида | Назначение формы — см. таблицу ниже: у справочника это форма объекта, у регистра сведений — форма записи, у журнала — форма списка |
| Synonym | нет | = FormName | Синоним формы |
| --set-default | нет | авто | Сделать основной. Без флага основной становится первая форма каждого назначения |
+12 -5
View File
@@ -379,17 +379,24 @@ $supportedTypes = @($formKinds.Keys) + @($noOwnForms.Keys)
# формы есть <ExtendedPresentation>.
$processorLikeTypes = @("DataProcessor", "Report", "ExternalDataProcessor", "ExternalReport")
# Вид объекта — первый элемент-потомок MetaDataObject, а не первое совпавшее по всему документу
# имя. Поиск по документу зависел от порядка перебора видов: у бизнес-процесса есть свойство
# <Task>, и он определялся как задача, после чего имя объекта не находилось вовсе.
$objectType = $null
$objectNode = $null
foreach ($t in $supportedTypes) {
$node = $xmlDoc.SelectSingleNode("//md:$t", $nsMgr)
if ($node) {
$objectType = $t
$objectNode = $node
foreach ($child in $metaDataObject.ChildNodes) {
if ($child.NodeType -eq [System.Xml.XmlNodeType]::Element) {
$objectType = $child.LocalName
$objectNode = $child
break
}
}
if ($objectType -and -not ($formKinds.ContainsKey($objectType) -or $noOwnForms.ContainsKey($objectType))) {
Write-Error "Тип объекта '$objectType' не поддерживается. Поддерживаемые типы: $(($formKinds.Keys | Sort-Object) -join ', ')"
exit 1
}
if (-not $objectType) {
Write-Error "Не удалось определить тип объекта. Поддерживаемые типы: $(($formKinds.Keys | Sort-Object) -join ', ')"
exit 1
+12 -5
View File
@@ -569,15 +569,22 @@ def main():
# метаданных формы есть <ExtendedPresentation>.
processor_like_types = ["DataProcessor", "Report", "ExternalDataProcessor", "ExternalReport"]
# Вид объекта — первый элемент-потомок MetaDataObject, а не первое совпавшее по всему
# документу имя. Поиск по документу зависел от порядка перебора видов: у бизнес-процесса
# есть свойство <Task>, и он определялся как задача, после чего имя объекта не находилось.
object_type = None
object_node = None
for t in supported_types:
node = root.find(f".//md:{t}", NSMAP)
if node is not None:
object_type = t
object_node = node
for child in root:
if isinstance(child.tag, str):
object_type = etree.QName(child).localname
object_node = child
break
if object_type is not None and object_type not in form_kinds and object_type not in no_own_forms:
print(f"Тип объекта '{object_type}' не поддерживается. "
f"Поддерживаемые типы: {', '.join(sorted(form_kinds))}", file=sys.stderr)
sys.exit(1)
if object_type is None:
print(f"Не удалось определить тип объекта. Поддерживаемые типы: {', '.join(sorted(form_kinds))}",
file=sys.stderr)