#!/usr/bin/env python3 """Разложить ОСВ из fixtures/osv/_inbox по организациям и периодам, читая ШАПКУ (имена файлов хаотичны). python scripts/sort_osv_fixtures.py fixtures/osv/_inbox fixtures/osv Зависимости: openpyxl, xlrd. """ import re, shutil, sys from pathlib import Path import openpyxl, xlrd ORG = {"русский бисквит": "rb", "счастливочная": "schastl"} # дополнять по мере появления организаций def head(p: Path): if p.suffix.lower() == ".xlsx": ws = openpyxl.load_workbook(p, read_only=True).worksheets[0] rows = [[c for c in r if c] for r in ws.iter_rows(min_row=1, max_row=6, values_only=True)] else: ws = xlrd.open_workbook(p).sheets()[0] rows = [[c.value for c in ws.row(i) if c.value] for i in range(min(6, ws.nrows))] cells = [str(c) for r in rows for c in r] org = next((c for c in cells if c.strip()), "").lower() title = next((c for c in cells if "по счету" in c.lower()), "") return org, title def main(inbox: Path, out: Path) -> int: for p in sorted(inbox.glob("*.xls*")): org, title = head(p) slug = next((v for k, v in ORG.items() if k in org), "other") m = re.search(r"по счету ([\d.]+)\s+за\s+(?:(\d)\s*квартал\s+)?(\d{4})", title, re.I) if not m: print("SKIP (не разобрана шапка):", p.name, "|", title); continue acc, q, y = m.groups() period = f"{y}-Q{q}" if q else f"{y}-FY" dst = out / slug / period dst.mkdir(parents=True, exist_ok=True) shutil.move(str(p), dst / p.name) print(f"{slug}/{period}/{p.name} (сч. {acc})") return 0 if __name__ == "__main__": sys.exit(main(Path(sys.argv[1]), Path(sys.argv[2])))