import csv import os from datetime import date from decimal import Decimal from pathlib import Path import pytest from synthgen import chart from synthgen.ledger import An, Ledger, opening D = Decimal def test_double_entry(): lg = Ledger("AGRO") lg.post(date(2025, 1, 10), "62.01", An("AGRO"), "90.01", None, D("1200.00"), "продажа") lg.post(date(2025, 2, 10), "51", None, "62.01", An("AGRO"), D("200.00"), "оплата") opening(lg, date(2025, 1, 1), "51", None, D("500.00")) opening(lg, date(2025, 1, 1), "60.01", An("AGRO"), D("-70.00")) for d in (date(2025, 1, 1), date(2025, 1, 31), date(2025, 12, 31)): assert sum(lg.balance(d).values()) == 0 def test_balance_signs_and_prefix(): lg = Ledger("X") lg.post(date(2025, 1, 10), "62.01", An("AGRO"), "90.01", None, D("1200.00"), "") lg.post(date(2025, 2, 10), "51", None, "62.01", An("AGRO"), D("200.00"), "") assert lg.balance(date(2025, 3, 31), "62") == {("62.01", An("AGRO")): D("1000.00")} assert lg.balance(date(2025, 1, 31), "62") == {("62.01", An("AGRO")): D("1200.00")} def test_turnover_window(): lg = Ledger("X") lg.post(date(2024, 12, 31), "62.01", An("A"), "90.01", None, D("10.00"), "") lg.post(date(2025, 1, 1), "62.01", An("A"), "90.01", None, D("20.00"), "") lg.post(date(2025, 3, 31), "51", None, "62.01", An("A"), D("5.00"), "") lg.post(date(2025, 4, 1), "62.01", An("A"), "90.01", None, D("40.00"), "") t = lg.turnover(date(2025, 1, 1), date(2025, 3, 31), "62") assert t == {("62.01", An("A")): (D("20.00"), D("5.00"))} def test_csv_deterministic(tmp_path): def build(p: Path): lg = Ledger("X") lg.post(date(2025, 1, 10), "62.01", An("A", contract="Д-1"), "90.01", None, D("1.50"), "м") lg.to_csv(p) return p.read_bytes() a = build(tmp_path / "a.csv") assert a == build(tmp_path / "b.csv") rows = list(csv.reader(a.decode("utf-8").splitlines(), delimiter=";")) assert rows[0] == "day;dt;dt_cp;dt_contract;dt_item;ct;ct_cp;ct_contract;ct_item;amount;memo".split(";") assert rows[1][:3] == ["2025-01-10", "62.01", "A"] def test_rejects_bad_amount(): lg = Ledger("X") with pytest.raises(ValueError): lg.post(date(2025, 1, 1), "51", None, "62.01", None, D("0"), "") def test_chart_helpers(): assert chart.parent("76.07.1") == "76.07" assert chart.parent("76.07") == "76" assert chart.parent("58.01") == "58" assert chart.is_off_balance("001") and chart.is_off_balance("011") assert not chart.is_off_balance("01") def test_chart_codes_in_core_seed(): ws = Path(os.environ.get("ARM_KA_WORKSPACE", "/Users/andrey.epifancev/projects/awp-ca")) seed = ws / "arm-core/api/seed/core/chart_of_accounts.csv" if not seed.exists(): pytest.skip("нет seed плана счетов") codes = {r["code"] for r in csv.DictReader(seed.open(encoding="utf-8"))} missing = [c for c in chart.ACCOUNTS if c != "000" and c not in codes] assert not missing