# -*- coding: utf-8 -*- """Доменные модели.""" from __future__ import annotations import datetime from dataclasses import dataclass, field from pathlib import Path from typing import List, Optional, Union # Значение ячейки: число, дата, строка либо пусто. CellValue = Optional[Union[str, int, float, datetime.date]] @dataclass class Record: """Одна принятая запись — значения колонок B..M (без № п/п).""" values: List[CellValue] = field(default_factory=list) def value(self, register_col: int) -> CellValue: """Значение для колонки реестра по её индексу (1=B .. 12=M).""" idx = register_col - 1 if 0 <= idx < len(self.values): return self.values[idx] return None @dataclass class ReadResult: """Результат чтения источника. records — записи для внесения в реестр; notes — что было присоединено к записям (информационно, не ошибки); warnings — данные, которые присоединить не к чему (требуют внимания). """ records: List["Record"] = field(default_factory=list) notes: List[str] = field(default_factory=list) warnings: List[str] = field(default_factory=list) @dataclass class SourceFile: """Файл приёма и его привязка к листу реестра.""" path: Path date: datetime.date sheet: str # имя листа в реестре, напр. "ТО1_25" name: str # имя файла без расширения, напр. "09.04.2026_74_25" @dataclass class JournalEntry: """Строка журнала внесения.""" date: datetime.date file_name: str count: int