Release 0.3.0: movements — регистратор ↔ регистры движений

Таблица register_records, мягкая миграция схемы 2→3 и команда query_1c.py movements в обе стороны.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
7 changed files with 463 additions and 10 deletions
+80
View File
@@ -13,6 +13,8 @@
python tools/index/query_1c.py show Document.ЗаказКлиента -b crm3-26
python tools/index/query_1c.py modules \"РВС_Transfer\" -b ws-rhana
python tools/index/query_1c.py refs Catalog.Партнеры -b source
python tools/index/query_1c.py movements ЗаказКлиента -b target
python tools/index/query_1c.py movements AccumulationRegister.ТоварыНаСкладах -b target
python tools/index/query_1c.py object ЗаказКлиента -b target
python tools/index/query_1c.py object Партнер -b crm3-26 --clear
python tools/index/query_1c.py module CommonModules/РВС_TransferAPIДокументы
@@ -43,6 +45,7 @@ from index1c.cli import ( # noqa: E402
from index1c.config import resolve_object_type # noqa: E402
from index1c import read_version_file # noqa: E402
from index1c.search import ( # noqa: E402
find_movements,
find_refs_to,
get_module,
get_object,
@@ -182,6 +185,62 @@ def cmd_refs(args: argparse.Namespace) -> int:
conn.close()
def cmd_movements(args: argparse.Namespace) -> int:
root = resolve_project_root(args)
conn = _open_or_exit(root)
try:
try:
baseconfs = get_baseconfs_for_query(args, conn, root)
except BaseconfError as e:
return handle_baseconf_error(e)
otype = resolve_object_type(args.type) if args.type else None
resolved, rows = find_movements(
conn,
args.target,
configs=baseconfs,
object_type=otype,
limit=args.limit,
)
if not resolved:
print(
format_not_found_object(args.target, baseconfs=baseconfs, conn=conn),
file=sys.stderr,
)
return 2
if not rows:
names = ", ".join(f"`{r['full_name']}`" for r in resolved)
print(f"Связей регистратор↔регистр для {names} не найдено.")
return 2
# группировка: config → from_full_name → links
current_cfg = None
current_from = None
for r in rows:
if r["config"] != current_cfg:
current_cfg = r["config"]
current_from = None
print(f"## [{current_cfg}]")
if r["from_full_name"] != current_from:
current_from = r["from_full_name"]
syn = f"{r['from_synonym']}" if r.get("from_synonym") else ""
if r["direction"] == "document_to_registers":
print(f"### Документ `{current_from}`{syn} → регистры движений")
else:
print(f"### Регистр `{current_from}`{syn} → регистраторы")
to_syn = f"{r['to_synonym']}" if r.get("to_synonym") else ""
print(f"- `{r['to_full_name']}`{to_syn}")
if len(resolved) > 1:
print()
print(
f"Найдено объектов: {len(resolved)}. "
"Уточните полное имя (Document.… / AccumulationRegister.…) или --type."
)
return 0
finally:
conn.close()
def cmd_show(args: argparse.Namespace) -> int:
root = resolve_project_root(args)
conn = _open_or_exit(root)
@@ -336,6 +395,27 @@ def build_parser() -> argparse.ArgumentParser:
)
ref.set_defaults(func=cmd_refs)
mov = sub.add_parser(
"movements",
help="Регистратор ↔ регистры движений (RegisterRecords)",
)
mov.add_argument(
"target",
help="Document.ЗаказКлиента | AccumulationRegister.ТоварыНаСкладах | имя",
)
add_baseconf_args(mov)
mov.add_argument(
"--type",
help="Уточнить тип: Document, AccumulationRegister, InformationRegister, …",
)
mov.add_argument(
"--limit",
type=int,
default=200,
help="Макс. связей на каждый найденный объект (по умолчанию 200)",
)
mov.set_defaults(func=cmd_movements)
sh = sub.add_parser("show", help="Карточка объекта (JSON: поля, типы, ссылки)")
sh.add_argument("name", help="ЗаказКлиента | Document.ЗаказКлиента")
add_baseconf_args(sh)