mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-08-16 16:29:01 +03:00
fix(form-validate,cfe-borrow): остаточные ложные ошибки на формах платформы
Корпусный прогон (УТ/БП/ERP, 21 097 форм) после понижения Command/Action оставлял 8 форм с ошибками. Разобраны все, дефектов оказалось два. 1. Вложенная таблица. Путь Items.<Таблица>.CurrentData.<Поле> разрешался ОДНИМ шагом: если таблица сама привязана через Items.*, корнем оставался литерал «Items», и типовая форма объявлялась битой (НастройкаПравилОбработкиЗаявокСотрудников в БП и ERP). Теперь разрешение идёт цепочкой, со страховкой от кольца ссылок. 2. AutoCommandBar с обычным id вместо -1. Это соглашение, а не требование: 21 094 формы из 21 097 используют -1, но три платформа выгружает с обычным id и грузит их без нареканий. Понижено до предупреждения; ошибка осталась на случай, когда id вообще не число. Оставшиеся три формы — дубли id элементов и команд. Это НЕ ложные срабатывания: измерение по корпусу показало ровно по одному случаю на 21 097 форм, то есть опечатки вендора, а не структурное правило (были бы пулы id раздельными, пересечений были бы тысячи). Плюс кейс duplicate-id прямо требует считать дубль ошибкой. Итого по корпусу: 283 формы с ошибками → 3. Заодно дооформлена фикстура cfe-borrow/container-types (пространство имён веб-сервису, документ журналу и последовательности): verify-snapshots по cfe-borrow теперь 12/12.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# form-validate v1.14 — Validate 1C managed form
|
||||
# form-validate v1.15 — Validate 1C managed form
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
|
||||
import argparse
|
||||
@@ -256,10 +256,15 @@ def main():
|
||||
if acb is not None:
|
||||
acb_name = acb.get("name", "")
|
||||
acb_id = acb.get("id", "")
|
||||
# id=-1 — соглашение, а не требование: в корпусе УТ/БП/ERP так у 21 094 форм из 21 097,
|
||||
# но три формы платформа выгружает с обычным id и грузит их без нареканий. Поэтому
|
||||
# предупреждение; ошибка — только если id вовсе не число.
|
||||
if acb_id == "-1":
|
||||
report_ok(f"AutoCommandBar: name='{acb_name}', id={acb_id}")
|
||||
elif re.match(r'^-?\d+$', acb_id):
|
||||
report_warn(f"AutoCommandBar id='{acb_id}', usually '-1'")
|
||||
else:
|
||||
report_error(f"AutoCommandBar id='{acb_id}', expected '-1'")
|
||||
report_error(f"AutoCommandBar id='{acb_id}' is not a number")
|
||||
else:
|
||||
report_error("AutoCommandBar element missing")
|
||||
|
||||
@@ -511,11 +516,21 @@ def main():
|
||||
segments = clean_path.split(".")
|
||||
root_attr = segments[0]
|
||||
|
||||
# Resolve Items.<TableName>.CurrentData.<Field>... — table element, not attribute
|
||||
if root_attr == 'Items':
|
||||
# Resolve Items.<TableName>.CurrentData.<Field>... — table element, not attribute.
|
||||
# Разрешаем ЦЕПОЧКОЙ: таблица во вложенной таблице сама привязана через Items.*, и один
|
||||
# шаг оставлял корнем литерал «Items» — форма платформы объявлялась битой (типовые
|
||||
# НастройкаПравилОбработкиЗаявокСотрудников в БП и ERP).
|
||||
items_hops = 0
|
||||
items_broken = False
|
||||
while root_attr == 'Items':
|
||||
items_hops += 1
|
||||
if items_hops > 10: # страховка от кольца ссылок
|
||||
items_broken = True
|
||||
break
|
||||
if len(segments) < 3 or segments[2] != 'CurrentData':
|
||||
report_warn(f"[{tag}] '{el_name}': {b_tag}='{data_path}' — unknown Items.* shape, expected Items.<Table>.CurrentData.*")
|
||||
continue
|
||||
items_broken = True
|
||||
break
|
||||
table_name = segments[1]
|
||||
table_el = None
|
||||
for candidate in all_elements:
|
||||
@@ -525,14 +540,19 @@ def main():
|
||||
if table_el is None:
|
||||
report_error(f"[{tag}] '{el_name}': {b_tag}='{data_path}' — table element '{table_name}' not found")
|
||||
path_errors += 1
|
||||
continue
|
||||
items_broken = True
|
||||
break
|
||||
table_dp_node = table_el["Node"].find(f"{{{F_NS}}}DataPath")
|
||||
if table_dp_node is None or not (table_dp_node.text or "").strip():
|
||||
continue
|
||||
items_broken = True
|
||||
break
|
||||
table_dp = re.sub(r'\[\d+\]', '', (table_dp_node.text or "").strip())
|
||||
if table_dp.startswith('~'):
|
||||
table_dp = table_dp[1:]
|
||||
root_attr = table_dp.split(".")[0]
|
||||
segments = table_dp.split(".")
|
||||
root_attr = segments[0]
|
||||
if items_broken:
|
||||
continue
|
||||
|
||||
if root_attr not in attr_map:
|
||||
report_error(f"[{tag}] '{el_name}': {b_tag}='{data_path}' — attribute '{root_attr}' not found")
|
||||
|
||||
Reference in New Issue
Block a user