Приём документов → реестр + журнал

Внесение данных из файлов приёма в реестр невостребованных документов
и заполнение журнала. Дата внесения — текущая; журнал заполняется чисто
(без строк-примеров шаблона).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
jze9
2026-06-26 03:11:18 +05:00
commit b5f7060a1f
20 changed files with 1571 additions and 0 deletions

View File

@@ -0,0 +1,97 @@
# -*- coding: utf-8 -*-
"""Оркестратор: связывает чтение источников, запись реестра и журнала."""
from __future__ import annotations
import logging
from dataclasses import dataclass, field
from pathlib import Path
from typing import List
from . import config
from .mapping import discover_sources
from .models import JournalEntry
from .readers import get_reader
from .writers import JournalWriter, RegisterWriter
log = logging.getLogger("priem")
@dataclass
class Result:
entries: List[JournalEntry]
notes: List[str] = field(default_factory=list)
warnings: List[str] = field(default_factory=list)
@property
def total(self) -> int:
return sum(e.count for e in self.entries)
class Pipeline:
def __init__(
self,
register_src: Path = config.REGISTER_SRC,
register_out: Path = config.REGISTER_OUT,
journal_src: Path = config.JOURNAL_SRC,
journal_out: Path = config.JOURNAL_OUT,
priem_dir: Path = config.PRIEM_DIR,
entry_date=config.ENTRY_DATE,
):
self.register_src = Path(register_src)
self.register_out = Path(register_out)
self.journal_src = Path(journal_src)
self.journal_out = Path(journal_out)
self.priem_dir = Path(priem_dir)
self.entry_date = entry_date
if self.register_out == self.register_src:
raise ValueError("register_out совпадает с оригиналом — он был бы перезаписан")
if self.journal_out == self.journal_src:
raise ValueError("journal_out совпадает с оригиналом — он был бы перезаписан")
def run(self) -> Result:
sources = discover_sources(self.priem_dir)
log.info("Найдено файлов приёма: %d", len(sources))
register = RegisterWriter(self.register_src)
entries: List[JournalEntry] = []
notes: List[str] = []
warnings: List[str] = []
for src in sources:
if not register.has_sheet(src.sheet):
raise ValueError(
"В реестре нет листа '%s' (файл %s)" % (src.sheet, src.name))
try:
read = get_reader(src.path).read()
except Exception as exc:
raise RuntimeError(
"Не удалось прочитать файл %s: %s" % (src.path.name, exc)) from exc
count = register.append(src.sheet, read.records)
entries.append(JournalEntry(self.entry_date, src.name, count))
log.info(" %-22s -> %-8s : %3d записей", src.name, src.sheet, count)
for n in read.notes:
notes.append("%s: %s" % (src.name, n))
log.info("%s", n)
for w in read.warnings:
warnings.append("%s: %s" % (src.name, w))
log.warning("%s", w)
register.save(self.register_out)
log.info("Реестр сохранён: %s", self.register_out.name)
journal = JournalWriter(self.journal_src)
journal.write(entries)
journal.save(self.journal_out)
log.info("Журнал сохранён: %s", self.journal_out.name)
result = Result(entries, notes, warnings)
log.info("ИТОГО записей: %d", result.total)
if notes:
log.info("Присоединено заметок: %d (данные не потеряны, см. выше)",
len(notes))
if warnings:
log.warning("ВНИМАНИЕ: %d строк НЕ удалось привязать — проверьте вручную:",
len(warnings))
for w in warnings:
log.warning("%s", w)
return result