from datetime import date from decimal import Decimal from pathlib import Path import pytest from openpyxl import load_workbook from finreport_agent.generic import discover_fragments from finreport_agent.extraction import extract_document from finreport_agent.models import GenericDocumentReport from finreport_agent.pipeline import _is_fund_portfolio, convert_report KAP_PDF = Path("/home/ahmet/Downloads/KAP - 1636723.pdf") AFT_PDF = Path("/home/ahmet/Downloads/AFT_2026.06.pdf") DGF_PDF = Path("/home/ahmet/Downloads/DGF_2026.06.pdf") @pytest.mark.skipif(not KAP_PDF.exists(), reason="Local KAP golden PDF is unavailable") def test_rotated_kap_tables_are_discovered_and_stitched(): fragments = discover_fragments(extract_document(KAP_PDF)) financial = [item for item in fragments if item.table_id.startswith("table_")] assert len(financial) == 6 assert financial[0].source_pages == [5, 6, 7] assert financial[1].source_pages == [8, 9, 10] assert financial[2].source_pages == [11, 12] assets_total = next( row for row in financial[0].rows if row.label == "VARLIKLAR TOPLAMI" ) assert assets_total.values == [ Decimal("82737"), Decimal("133729"), Decimal("216466"), Decimal("76130"), Decimal("128393"), Decimal("204523"), ] @pytest.mark.skipif(not KAP_PDF.exists(), reason="Local KAP golden PDF is unavailable") def test_kap_uses_generic_route_and_dynamic_workbook(tmp_path, monkeypatch): monkeypatch.setenv("DISABLE_AGENT_PLANNER", "1") output = tmp_path / "kap.xlsx" result = convert_report(KAP_PDF, output) assert isinstance(result.report, GenericDocumentReport) assert result.report.document_type == "Banka Finansal Raporu" assert [table.sheet_name for table in result.report.tables] == [ "Belge Bilgileri", "Bilanço", "Nazım Hesaplar", "Kâr veya Zarar", "Kapsamlı Gelir", "Nakit Akış", "Özkaynak Değişim", ] workbook = load_workbook(output, data_only=True, read_only=True) assert workbook.sheetnames == [ "Özet", "Belge Bilgileri", "Bilanço", "Nazım Hesaplar", "Kâr veya Zarar", "Kapsamlı Gelir", "Nakit Akış", "Özkaynak Değişim", "Kontroller", "Kaynak İzleri", ] assert "Hisse Senetleri" not in workbook.sheetnames @pytest.mark.skipif(not AFT_PDF.exists(), reason="Local AFT golden PDF is unavailable") def test_different_fund_layout_falls_back_to_generic_route(tmp_path, monkeypatch): monkeypatch.setenv("DISABLE_AGENT_PLANNER", "1") document = extract_document(AFT_PDF) assert not _is_fund_portfolio(document) output = tmp_path / "aft.xlsx" result = convert_report(AFT_PDF, output) assert isinstance(result.report, GenericDocumentReport) assert result.report.planner_mode == "deterministic_fund_schema" assert len(result.report.tables) >= 10 portfolio = next( table for table in result.report.tables if table.sheet_name == "Portföy Değeri" ) apple = next(row for row in portfolio.rows if row.label.startswith("AAPL US")) assert Decimal("885016484.17") in apple.values workbook = load_workbook(output, data_only=True, read_only=True) assert "Tanıtıcı Bilgiler" in workbook.sheetnames assert "Performans" in workbook.sheetnames assert "Portföy Değeri" in workbook.sheetnames assert "Fon Toplam Değeri" in workbook.sheetnames assert "Giderler" in workbook.sheetnames assert "Dönem İşlemleri" in workbook.sheetnames assert "Kontroller" in workbook.sheetnames assert "Kaynak İzleri" in workbook.sheetnames @pytest.mark.skipif(not DGF_PDF.exists(), reason="Local DGF golden PDF is unavailable") def test_standard_fund_sections_do_not_mix_performance_and_portfolio( tmp_path, monkeypatch, ): monkeypatch.setenv("DISABLE_AGENT_PLANNER", "1") output = tmp_path / "dgf.xlsx" result = convert_report(DGF_PDF, output) assert isinstance(result.report, GenericDocumentReport) assert result.report.planner_mode == "deterministic_fund_schema" by_sheet = {table.sheet_name: table for table in result.report.tables} assert { "Tanıtıcı Bilgiler", "Performans", "Portföy Değeri", "Portföy Değeri 2", "Fon Toplam Değeri", "Giderler", "Dönem İşlemleri", }.issubset(by_sheet) performance = by_sheet["Performans"] assert all("TREGVYO" not in row.label for row in performance.rows) assert any(row.label.startswith("A-)Ay Sonu Pay Fiyatı") for row in performance.rows) portfolio = by_sheet["Portföy Değeri 2"] glcvy = next(row for row in portfolio.rows if "GLCVY" in row.label) assert Decimal("532993.50") in glcvy.values assert "TREGVYO00011" in glcvy.values assert date(2026, 6, 26) in glcvy.values expenses = by_sheet["Giderler"] management_fee = next( row for row in expenses.rows if row.label == "Fon Yönetim Ücreti" ) assert management_fee.values[0] == Decimal("27476.04")