From 1ebd5b9997b2a8b0f7649c78d7a8999948d50b15 Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Thu, 15 Oct 2026 18:37:23 +0400 Subject: [PATCH] =?UTF-8?q?=D0=A8=D0=B0=D1=85=D0=BC=D0=B0=D1=82=D0=BA?= =?UTF-8?q?=D0=B0:=20=D0=B7=D0=B5=D0=BB=D1=91=D0=BD=D1=8B=D0=B9=20make=20c?= =?UTF-8?q?heck=20(#114)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Убраны отладочные print() в режиме MANUAL. - mypy: computed_field у is_debit/is_credit — с type: ignore[prop-decorator], как у остальных схем; флаг is_more_5_percent без сравнения Decimal с None (поведение прежнее). - ruff format по трём файлам. - test_openapi_routes: новые маршруты шахматки и правил элиминации в EXPECTED_ROUTES. make check: ruff, ruff format, mypy — чисто; pytest 1303 passed, 44 skipped. Co-Authored-By: Claude Opus 5.5 --- api/src/api/endpoints/directories/accounts.py | 2 +- api/src/schemas/directories.py | 4 +-- api/src/services/intercompany_matrix.py | 4 +-- api/tests/test_api_accounts.py | 27 ++++++++++++++----- api/tests/test_intercompany_matrix_export.py | 3 +-- api/tests/test_openapi_routes.py | 7 +++++ 6 files changed, 33 insertions(+), 14 deletions(-) diff --git a/api/src/api/endpoints/directories/accounts.py b/api/src/api/endpoints/directories/accounts.py index a00f3e6..eb0b912 100644 --- a/api/src/api/endpoints/directories/accounts.py +++ b/api/src/api/endpoints/directories/accounts.py @@ -17,5 +17,5 @@ router = APIRouter() summary="Список счетов плана счетов", ) async def list_accounts(session: SessionDep) -> list[AccountOut]: - """ Все счета одним списком """ + """Все счета одним списком""" return [AccountOut.model_validate(account) for account in await repo.list_accounts(session)] diff --git a/api/src/schemas/directories.py b/api/src/schemas/directories.py index 1bb3059..a376362 100644 --- a/api/src/schemas/directories.py +++ b/api/src/schemas/directories.py @@ -51,13 +51,13 @@ class AccountOut(BaseModel): row_type: AccountRowType is_off_balance: bool - @computed_field + @computed_field # type: ignore[prop-decorator] @property def is_debit(self) -> bool: """Счёт можно выбрать для дебетовой стороны: активный или активно-пассивный.""" return self.kind in (AccountKind.A, AccountKind.AP) - @computed_field + @computed_field # type: ignore[prop-decorator] @property def is_credit(self) -> bool: """Счёт можно выбрать для кредитовой стороны: пассивный или активно-пассивный.""" diff --git a/api/src/services/intercompany_matrix.py b/api/src/services/intercompany_matrix.py index 38b4c28..c35d1cb 100644 --- a/api/src/services/intercompany_matrix.py +++ b/api/src/services/intercompany_matrix.py @@ -129,7 +129,7 @@ def calculate_matrix( variance_amount = abs(amount_a - amount_b) base = min(amount_a, amount_b) variance_percent = None if base == ZERO else variance_amount / base * 100 - is_more_5_percent = False if base == ZERO else variance_percent > VARIANCE_THRESHOLD_PERCENT + is_more_5_percent = variance_percent is not None and variance_percent > VARIANCE_THRESHOLD_PERCENT cells.append( IntercompanyMatrixCellOut( company_a_id=company_a, @@ -303,8 +303,6 @@ class IntercompanyMatrixService: raise DomainValidationError("ACCOUNTS_REQUIRED", "Выберите дебетовые и кредитовые счета") debit = _selected_accounts(debit_account_ids, (), "D", by_id, children) credit = _selected_accounts(credit_account_ids, (), "K", by_id, children) - print(debit) - print(credit) else: raise DomainValidationError("INVALID_MODE", "Неизвестный режим выбора счетов") selection = MatrixSelection(debit, credit, "closing") diff --git a/api/tests/test_api_accounts.py b/api/tests/test_api_accounts.py index 4052303..54c8497 100644 --- a/api/tests/test_api_accounts.py +++ b/api/tests/test_api_accounts.py @@ -13,16 +13,31 @@ async def test_accounts_are_flat_and_naturally_sorted() -> None: root_id, sub_id = uuid.uuid4(), uuid.uuid4() rows = [ SimpleNamespace( - id=sub_id, code="60.10", parent_id=root_id, name="Авансы", kind=AccountKind.A, - row_type=AccountRowType.subaccount, is_off_balance=False, + id=sub_id, + code="60.10", + parent_id=root_id, + name="Авансы", + kind=AccountKind.A, + row_type=AccountRowType.subaccount, + is_off_balance=False, ), SimpleNamespace( - id=root_id, code="60", parent_id=None, name="Расчёты", kind=AccountKind.AP, - row_type=AccountRowType.account, is_off_balance=False, + id=root_id, + code="60", + parent_id=None, + name="Расчёты", + kind=AccountKind.AP, + row_type=AccountRowType.account, + is_off_balance=False, ), SimpleNamespace( - id=uuid.uuid4(), code="60.2", parent_id=root_id, name="Поставщики", kind=AccountKind.P, - row_type=AccountRowType.subaccount, is_off_balance=False, + id=uuid.uuid4(), + code="60.2", + parent_id=root_id, + name="Поставщики", + kind=AccountKind.P, + row_type=AccountRowType.subaccount, + is_off_balance=False, ), ] session = SimpleNamespace(scalars=AsyncMock(return_value=SimpleNamespace(all=lambda: rows))) diff --git a/api/tests/test_intercompany_matrix_export.py b/api/tests/test_intercompany_matrix_export.py index 82fe9a7..70776b4 100644 --- a/api/tests/test_intercompany_matrix_export.py +++ b/api/tests/test_intercompany_matrix_export.py @@ -87,8 +87,7 @@ def test_matrix_export_has_three_rows_per_debit_company_and_highlights_threshold assert middle.border.bottom.style is None assert bottom.border.bottom.style == "thin" assert all( - cell.border.left.style == "thin" and cell.border.right.style == "thin" - for cell in (top, middle, bottom) + cell.border.left.style == "thin" and cell.border.right.style == "thin" for cell in (top, middle, bottom) ) diff --git a/api/tests/test_openapi_routes.py b/api/tests/test_openapi_routes.py index cdcf63a..a5b1566 100644 --- a/api/tests/test_openapi_routes.py +++ b/api/tests/test_openapi_routes.py @@ -73,6 +73,13 @@ EXPECTED_ROUTES: dict[str, set[str]] = { "/api/v1/consolidations/versions/{version_id}/osv/export": {"get"}, "/api/v1/consolidations/versions/{version_id}/counterparty-candidates": {"get"}, "/api/v1/consolidations/versions/{version_id}/osv/entries/{entry_id}/counterparty": {"post"}, + # шахматка ВГО и правила элиминации + "/api/v1/consolidations/versions/{version_id}/elimination-rules": {"get"}, + "/api/v1/consolidations/versions/{version_id}/intercompany-matrix/all": {"get"}, + "/api/v1/consolidations/versions/{version_id}/intercompany-matrix/all/export": {"get"}, + "/api/v1/consolidations/versions/{version_id}/intercompany-matrix/manual": {"post"}, + "/api/v1/consolidations/versions/{version_id}/intercompany-matrix/manual/export": {"post"}, + "/api/v1/consolidations/versions/{version_id}/intercompany-matrix/result-table": {"get"}, } # Префиксы, под которыми маршрутов сверх EXPECTED_ROUTES быть не должно