""" Comprehensive Integration Test Suite for Mirchi Trading Backend Connected to PostgreSQL Database Test Scenarios: 1. 5 Parties: Awaak-only, Jawaak-only, Mixed, Patti Awaak, Patti Jawaak 2. 5 Mirchi Types: Byadgi, Teja, Kashmiri, C5, Dabbi 3. Regular Awaak -> Jawaak flow 4. Patti Awaak -> Jawaak flow 5. Mixed Jawaak scenarios 6. Payment scenarios: Full, Half Due, Cash, Online, Partial, Full Due 7. Due scenarios in Awaak, Jawaak, Mixed 8. Revert scenarios for all bill types """ import pytest import asyncio from httpx import AsyncClient, ASGITransport from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine, async_sessionmaker from sqlalchemy import select from datetime import datetime import sys import os # Add backend to path sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from app.main import app from app.core.database import Base, get_db from app.core.config import settings from app.models import Party, MirchiType, Transaction, PattiTransaction, BillNumberSequence from app.models.transaction import BillType from app.models.patti_transaction import PattiBillType from app.models.party import PartyType # Use PostgreSQL database for integration tests TEST_DATABASE_URL = settings.DATABASE_URL @pytest.fixture(scope="session") def event_loop(): """Create event loop for async tests""" loop = asyncio.get_event_loop_policy().new_event_loop() yield loop loop.close() @pytest.fixture(scope="function") async def db_session(): """Create database session for tests - uses PostgreSQL""" engine = create_async_engine(TEST_DATABASE_URL, echo=False) async_session = async_sessionmaker(engine, expire_on_commit=False) async with async_session() as session: yield session await engine.dispose() @pytest.fixture(scope="function") async def client(db_session): """Create test client""" async def override_get_db(): yield db_session app.dependency_overrides[get_db] = override_get_db async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as ac: yield ac app.dependency_overrides.clear() # ============================================ # TEST DATA SETUP # ============================================ class TestDataSetup: """Setup test data - Parties and Mirchi Types""" @pytest.mark.asyncio async def test_01_create_mirchi_types(self, client: AsyncClient, db_session: AsyncSession): """Create 5 Mirchi Types: Byadgi, Teja, Kashmiri, C5, Dabbi""" mirchi_types = ["Byadgi", "Teja", "Kashmiri", "C5", "Dabbi"] created_types = [] for name in mirchi_types: response = await client.post("/api/mirchi-types", json={"name": name}) if response.status_code == 201: created_types.append(response.json()["data"]) else: # Already exists, fetch it get_resp = await client.get(f"/api/mirchi-types?search={name}") if get_resp.json()["total"] > 0: created_types.append(get_resp.json()["data"][0]) assert len(created_types) >= 5, "All 5 mirchi types should exist" print(f"\n✅ Verified {len(created_types)} Mirchi Types") @pytest.mark.asyncio async def test_02_create_parties(self, client: AsyncClient, db_session: AsyncSession): """Create 5 Parties with different types""" parties = [ {"name": "Ramesh Awaak Party", "phone": "9876543201", "city": "Sangli", "party_type": "awaak"}, {"name": "Suresh Jawaak Party", "phone": "9876543202", "city": "Kolhapur", "party_type": "jawaak"}, {"name": "Mixed Trading Co", "phone": "9876543203", "city": "Pune", "party_type": "both"}, {"name": "Patti Awaak Holder", "phone": "9876543204", "city": "Solapur", "party_type": "awaak"}, {"name": "Patti Jawaak Buyer", "phone": "9876543205", "city": "Satara", "party_type": "jawaak"}, ] created_parties = [] for party in parties: response = await client.post("/api/parties", json=party) if response.status_code == 201: created_parties.append(response.json()["data"]) assert len(created_parties) >= 5, "All 5 parties should be created" print(f"\n✅ Created {len(created_parties)} Parties") # ============================================ # REGULAR AWAAK -> JAWAAK FLOW # ============================================ class TestRegularAwaakJawaakFlow: """Regular trading flow tests""" @pytest.mark.asyncio async def test_awaak_full_payment(self, client: AsyncClient, db_session: AsyncSession): """Awaak transaction with FULL payment (cash)""" parties = await client.get("/api/parties?search=Ramesh Awaak") assert parties.json()["total"] > 0, "Party should exist" party_id = parties.json()["data"][0]["id"] response = await client.post("/api/transactions", json={ "bill_date": datetime.now().strftime("%Y-%m-%d"), "bill_type": "awaak", "party_id": party_id, "subtotal": 50000, "total_amount": 50000, "paid_amount": 50000, "balance_amount": 0, "lot_number": "LOT-AWAAK-FULL-001", "items": [{"mirchi_name": "Byadgi", "poti_count": 50, "net_weight": 2500, "rate_per_kg": 20, "amount": 50000}], "payments": [{"amount": 50000, "mode": "cash"}] }) assert response.status_code == 201 data = response.json() assert data["data"]["balance_amount"] == 0 print(f"\n✅ Awaak Full Payment: Bill {data['data']['bill_number']}") @pytest.mark.asyncio async def test_awaak_half_due(self, client: AsyncClient, db_session: AsyncSession): """Awaak transaction with HALF payment, HALF due""" parties = await client.get("/api/parties?search=Ramesh Awaak") party_id = parties.json()["data"][0]["id"] response = await client.post("/api/transactions", json={ "bill_date": datetime.now().strftime("%Y-%m-%d"), "bill_type": "awaak", "party_id": party_id, "subtotal": 40000, "total_amount": 40000, "paid_amount": 20000, "balance_amount": 20000, "lot_number": "LOT-AWAAK-HALF-001", "items": [{"mirchi_name": "Teja", "poti_count": 40, "net_weight": 2000, "rate_per_kg": 20, "amount": 40000}], "payments": [{"amount": 20000, "mode": "cash"}] }) assert response.status_code == 201 data = response.json() assert data["data"]["balance_amount"] == 20000 print(f"\n✅ Awaak Half Due: Bill {data['data']['bill_number']}, Due=₹{data['data']['balance_amount']}") @pytest.mark.asyncio async def test_awaak_full_due(self, client: AsyncClient, db_session: AsyncSession): """Awaak transaction with FULL DUE (no payment)""" parties = await client.get("/api/parties?search=Ramesh Awaak") party_id = parties.json()["data"][0]["id"] response = await client.post("/api/transactions", json={ "bill_date": datetime.now().strftime("%Y-%m-%d"), "bill_type": "awaak", "party_id": party_id, "subtotal": 30000, "total_amount": 30000, "paid_amount": 0, "balance_amount": 30000, "lot_number": "LOT-AWAAK-DUE-001", "items": [{"mirchi_name": "Kashmiri", "poti_count": 30, "net_weight": 1500, "rate_per_kg": 20, "amount": 30000}], "payments": [] }) assert response.status_code == 201 data = response.json() assert data["data"]["balance_amount"] == 30000 print(f"\n✅ Awaak Full Due: Bill {data['data']['bill_number']}, Due=₹{data['data']['balance_amount']}") @pytest.mark.asyncio async def test_jawaak_full_payment_online(self, client: AsyncClient, db_session: AsyncSession): """Jawaak transaction with FULL payment (UPI/Online)""" parties = await client.get("/api/parties?search=Suresh Jawaak") party_id = parties.json()["data"][0]["id"] response = await client.post("/api/transactions", json={ "bill_date": datetime.now().strftime("%Y-%m-%d"), "bill_type": "jawaak", "party_id": party_id, "subtotal": 60000, "total_amount": 60000, "paid_amount": 60000, "balance_amount": 0, "items": [{"mirchi_name": "Byadgi", "poti_count": 30, "net_weight": 3000, "rate_per_kg": 20, "amount": 60000}], "payments": [{"amount": 60000, "mode": "upi", "reference": "UPI-123456"}] }) assert response.status_code == 201 data = response.json() assert data["data"]["bill_number"].startswith("J") print(f"\n✅ Jawaak Full Online Payment: Bill {data['data']['bill_number']}") @pytest.mark.asyncio async def test_jawaak_partial_payment_cash_online(self, client: AsyncClient, db_session: AsyncSession): """Jawaak with PARTIAL payment - Half Cash, Half Online""" parties = await client.get("/api/parties?search=Suresh Jawaak") party_id = parties.json()["data"][0]["id"] response = await client.post("/api/transactions", json={ "bill_date": datetime.now().strftime("%Y-%m-%d"), "bill_type": "jawaak", "party_id": party_id, "subtotal": 50000, "total_amount": 50000, "paid_amount": 25000, "balance_amount": 25000, "items": [{"mirchi_name": "Teja", "poti_count": 25, "net_weight": 2500, "rate_per_kg": 20, "amount": 50000}], "payments": [{"amount": 15000, "mode": "cash"}, {"amount": 10000, "mode": "upi"}] }) assert response.status_code == 201 data = response.json() assert data["data"]["paid_amount"] == 25000 assert len(data["data"]["payments"]) == 2 print(f"\n✅ Jawaak Partial (Cash+UPI): Bill {data['data']['bill_number']}") # ============================================ # PATTI AWAAK -> JAWAAK FLOW # ============================================ class TestPattiAwaakJawaakFlow: """Patti trading flow tests""" @pytest.mark.asyncio async def test_patti_awaak_no_lot(self, client: AsyncClient, db_session: AsyncSession): """Patti Awaak - No lot required""" parties = await client.get("/api/parties?search=Patti Awaak Holder") party_id = parties.json()["data"][0]["id"] response = await client.post("/api/patti-transactions", json={ "bill_date": datetime.now().strftime("%Y-%m-%d"), "bill_type": "patti_awaak", "party_id": party_id, "subtotal": 35000, "total_amount": 35000, "paid_amount": 0, "balance_amount": 35000, "expenses": {"packing": 200, "godown": 300, "commission": 500}, "items": [{"mirchi_name": "C5", "poti_count": 35, "net_weight": 1750, "rate_per_kg": 20, "amount": 35000}] }) assert response.status_code == 201 data = response.json() assert data["data"]["bill_number"].startswith("PA") print(f"\n✅ Patti Awaak (no lot): Bill {data['data']['bill_number']}") @pytest.mark.asyncio async def test_patti_awaak_with_lot(self, client: AsyncClient, db_session: AsyncSession): """Patti Awaak - With lot (optional)""" parties = await client.get("/api/parties?search=Patti Awaak Holder") party_id = parties.json()["data"][0]["id"] response = await client.post("/api/patti-transactions", json={ "bill_date": datetime.now().strftime("%Y-%m-%d"), "bill_type": "patti_awaak", "party_id": party_id, "subtotal": 25000, "total_amount": 25000, "paid_amount": 10000, "balance_amount": 15000, "lot_number": "LOT-PA-001", "expenses": {"packing": 150, "godown": 200}, "items": [{"mirchi_name": "Dabbi", "poti_count": 25, "net_weight": 1250, "rate_per_kg": 20, "amount": 25000}] }) assert response.status_code == 201 data = response.json() assert data["data"]["lot_number"] == "LOT-PA-001" print(f"\n✅ Patti Awaak (with lot): Bill {data['data']['bill_number']}") @pytest.mark.asyncio async def test_patti_jawaak_with_lot_weightage(self, client: AsyncClient, db_session: AsyncSession): """Patti Jawaak - Lot MANDATORY, weightage required""" parties = await client.get("/api/parties?search=Patti Jawaak Buyer") party_id = parties.json()["data"][0]["id"] response = await client.post("/api/patti-transactions", json={ "bill_date": datetime.now().strftime("%Y-%m-%d"), "bill_type": "patti_jawaak", "party_id": party_id, "subtotal": 40000, "total_amount": 40000, "paid_amount": 40000, "balance_amount": 0, "lot_number": "LOT-PJ-001", "gross_weight": 1850, "verified_net_weight": 1800, "expenses": {"packing": 200, "godown": 300}, "items": [{"mirchi_name": "C5", "poti_count": 36, "net_weight": 1800, "rate_per_kg": 22.22, "amount": 40000}] }) assert response.status_code == 201 data = response.json() assert data["data"]["bill_number"].startswith("PJ") assert data["data"]["lot_number"] == "LOT-PJ-001" assert data["data"]["gross_weight"] == 1850 print(f"\n✅ Patti Jawaak (lot+weightage): Bill {data['data']['bill_number']}") @pytest.mark.asyncio async def test_patti_jawaak_without_lot_fails(self, client: AsyncClient, db_session: AsyncSession): """Patti Jawaak without lot should FAIL""" parties = await client.get("/api/parties?search=Patti Jawaak Buyer") party_id = parties.json()["data"][0]["id"] response = await client.post("/api/patti-transactions", json={ "bill_date": datetime.now().strftime("%Y-%m-%d"), "bill_type": "patti_jawaak", "party_id": party_id, "subtotal": 20000, "total_amount": 20000, "paid_amount": 20000, "balance_amount": 0, "items": [{"mirchi_name": "Dabbi", "poti_count": 20, "net_weight": 1000, "rate_per_kg": 20, "amount": 20000}] }) assert response.status_code == 400 print(f"\n✅ Patti Jawaak without lot correctly FAILS") # ============================================ # MIXED JAWAAK SCENARIOS # ============================================ class TestMixedJawaakScenarios: """Mixed Jawaak tests""" @pytest.mark.asyncio async def test_mixed_jawaak_full_payment(self, client: AsyncClient, db_session: AsyncSession): """Mixed Jawaak with full payment""" parties = await client.get("/api/parties?search=Mixed Trading") party_id = parties.json()["data"][0]["id"] response = await client.post("/api/transactions", json={ "bill_date": datetime.now().strftime("%Y-%m-%d"), "bill_type": "jawaak", "party_id": party_id, "subtotal": 70000, "total_amount": 70000, "paid_amount": 70000, "balance_amount": 0, "items": [ {"mirchi_name": "Byadgi", "poti_count": 20, "net_weight": 1000, "rate_per_kg": 30, "amount": 30000, "source": "normal"}, {"mirchi_name": "Teja", "poti_count": 20, "net_weight": 1000, "rate_per_kg": 40, "amount": 40000, "source": "patti"} ], "payments": [{"amount": 40000, "mode": "bank"}, {"amount": 30000, "mode": "cash"}] }) assert response.status_code == 201 data = response.json() assert data["data"]["is_mixed"] is True print(f"\n✅ Mixed Jawaak: Bill {data['data']['bill_number']}, is_mixed=True") @pytest.mark.asyncio async def test_mixed_jawaak_half_due(self, client: AsyncClient, db_session: AsyncSession): """Mixed Jawaak with half due""" parties = await client.get("/api/parties?search=Mixed Trading") party_id = parties.json()["data"][0]["id"] response = await client.post("/api/transactions", json={ "bill_date": datetime.now().strftime("%Y-%m-%d"), "bill_type": "jawaak", "party_id": party_id, "subtotal": 50000, "total_amount": 50000, "paid_amount": 25000, "balance_amount": 25000, "items": [ {"mirchi_name": "Kashmiri", "poti_count": 15, "net_weight": 750, "rate_per_kg": 30, "amount": 22500, "source": "normal"}, {"mirchi_name": "C5", "poti_count": 14, "net_weight": 700, "rate_per_kg": 39.29, "amount": 27500, "source": "patti"} ], "payments": [{"amount": 15000, "mode": "upi"}, {"amount": 10000, "mode": "cash"}] }) assert response.status_code == 201 data = response.json() assert data["data"]["is_mixed"] is True assert data["data"]["balance_amount"] == 25000 print(f"\n✅ Mixed Jawaak Half Due: Due=₹{data['data']['balance_amount']}") @pytest.mark.asyncio async def test_mixed_jawaak_full_due(self, client: AsyncClient, db_session: AsyncSession): """Mixed Jawaak with FULL DUE""" parties = await client.get("/api/parties?search=Mixed Trading") party_id = parties.json()["data"][0]["id"] response = await client.post("/api/transactions", json={ "bill_date": datetime.now().strftime("%Y-%m-%d"), "bill_type": "jawaak", "party_id": party_id, "subtotal": 30000, "total_amount": 30000, "paid_amount": 0, "balance_amount": 30000, "items": [ {"mirchi_name": "Dabbi", "poti_count": 10, "net_weight": 500, "rate_per_kg": 30, "amount": 15000, "source": "normal"}, {"mirchi_name": "Dabbi", "poti_count": 10, "net_weight": 500, "rate_per_kg": 30, "amount": 15000, "source": "patti"} ], "payments": [] }) assert response.status_code == 201 data = response.json() assert data["data"]["balance_amount"] == 30000 print(f"\n✅ Mixed Jawaak Full Due: Due=₹{data['data']['balance_amount']}") # ============================================ # REVERT SCENARIOS # ============================================ class TestRevertScenarios: """Revert tests for all bill types""" @pytest.mark.asyncio async def test_revert_awaak(self, client: AsyncClient, db_session: AsyncSession): """Revert awaak transaction""" parties = await client.get("/api/parties?search=Ramesh Awaak") party_id = parties.json()["data"][0]["id"] create_response = await client.post("/api/transactions", json={ "bill_date": datetime.now().strftime("%Y-%m-%d"), "bill_type": "awaak", "party_id": party_id, "subtotal": 10000, "total_amount": 10000, "paid_amount": 0, "balance_amount": 10000, "items": [{"mirchi_name": "C5", "poti_count": 10, "net_weight": 500, "rate_per_kg": 20, "amount": 10000}], "payments": [] }) txn_id = create_response.json()["data"]["id"] response = await client.post(f"/api/transactions/{txn_id}/revert") assert response.status_code == 200 print(f"\n✅ Revert Awaak: Success") @pytest.mark.asyncio async def test_revert_jawaak(self, client: AsyncClient, db_session: AsyncSession): """Revert jawaak transaction - should fail with payments""" parties = await client.get("/api/parties?search=Suresh Jawaak") party_id = parties.json()["data"][0]["id"] create_response = await client.post("/api/transactions", json={ "bill_date": datetime.now().strftime("%Y-%m-%d"), "bill_type": "jawaak", "party_id": party_id, "subtotal": 8000, "total_amount": 8000, "paid_amount": 8000, "balance_amount": 0, "items": [{"mirchi_name": "Dabbi", "poti_count": 8, "net_weight": 400, "rate_per_kg": 20, "amount": 8000}], "payments": [{"amount": 8000, "mode": "cash"}] }) txn_id = create_response.json()["data"]["id"] response = await client.post(f"/api/transactions/{txn_id}/revert") # Should fail because there are unreversed payments assert response.status_code == 400 print(f"\n✅ Revert Jawaak with payments: Correctly FAILS (payments must be reversed first)") @pytest.mark.asyncio async def test_revert_patti_awaak(self, client: AsyncClient, db_session: AsyncSession): """Revert patti awaak transaction""" parties = await client.get("/api/parties?search=Patti Awaak Holder") party_id = parties.json()["data"][0]["id"] create_response = await client.post("/api/patti-transactions", json={ "bill_date": datetime.now().strftime("%Y-%m-%d"), "bill_type": "patti_awaak", "party_id": party_id, "subtotal": 6000, "total_amount": 6000, "paid_amount": 0, "balance_amount": 6000, "items": [{"mirchi_name": "Byadgi", "poti_count": 6, "net_weight": 300, "rate_per_kg": 20, "amount": 6000}] }) txn_id = create_response.json()["data"]["id"] response = await client.post(f"/api/patti-transactions/{txn_id}/revert") assert response.status_code == 200 print(f"\n✅ Revert Patti Awaak: Success") @pytest.mark.asyncio async def test_revert_patti_jawaak(self, client: AsyncClient, db_session: AsyncSession): """Revert patti jawaak transaction""" parties = await client.get("/api/parties?search=Patti Jawaak Buyer") party_id = parties.json()["data"][0]["id"] create_response = await client.post("/api/patti-transactions", json={ "bill_date": datetime.now().strftime("%Y-%m-%d"), "bill_type": "patti_jawaak", "party_id": party_id, "subtotal": 5000, "total_amount": 5000, "paid_amount": 5000, "balance_amount": 0, "lot_number": "LOT-REVERT-001", "gross_weight": 550, "verified_net_weight": 500, "items": [{"mirchi_name": "Teja", "poti_count": 5, "net_weight": 250, "rate_per_kg": 20, "amount": 5000}] }) txn_id = create_response.json()["data"]["id"] response = await client.post(f"/api/patti-transactions/{txn_id}/revert") assert response.status_code == 200 print(f"\n✅ Revert Patti Jawaak: Success") @pytest.mark.asyncio async def test_revert_mixed_jawaak(self, client: AsyncClient, db_session: AsyncSession): """Revert mixed jawaak transaction - should fail with payments""" parties = await client.get("/api/parties?search=Mixed Trading") party_id = parties.json()["data"][0]["id"] create_response = await client.post("/api/transactions", json={ "bill_date": datetime.now().strftime("%Y-%m-%d"), "bill_type": "jawaak", "party_id": party_id, "subtotal": 12000, "total_amount": 12000, "paid_amount": 6000, "balance_amount": 6000, "items": [ {"mirchi_name": "Byadgi", "poti_count": 5, "net_weight": 250, "rate_per_kg": 24, "amount": 6000, "source": "normal"}, {"mirchi_name": "Teja", "poti_count": 5, "net_weight": 250, "rate_per_kg": 24, "amount": 6000, "source": "patti"} ], "payments": [{"amount": 6000, "mode": "cash"}] }) txn_id = create_response.json()["data"]["id"] assert create_response.json()["data"]["is_mixed"] is True response = await client.post(f"/api/transactions/{txn_id}/revert") # Should fail because there are unreversed payments assert response.status_code == 400 print(f"\n✅ Revert Mixed Jawaak with payments: Correctly FAILS (payments must be reversed first)") @pytest.mark.asyncio async def test_revert_already_reverted_fails(self, client: AsyncClient, db_session: AsyncSession): """Reverting already reverted transaction should fail""" parties = await client.get("/api/parties?search=Ramesh Awaak") party_id = parties.json()["data"][0]["id"] create_response = await client.post("/api/transactions", json={ "bill_date": datetime.now().strftime("%Y-%m-%d"), "bill_type": "awaak", "party_id": party_id, "subtotal": 5000, "total_amount": 5000, "paid_amount": 0, "balance_amount": 5000, "items": [{"mirchi_name": "Kashmiri", "poti_count": 5, "net_weight": 250, "rate_per_kg": 20, "amount": 5000}], "payments": [] }) txn_id = create_response.json()["data"]["id"] # First revert await client.post(f"/api/transactions/{txn_id}/revert") # Second revert should fail response = await client.post(f"/api/transactions/{txn_id}/revert") assert response.status_code == 400 print(f"\n✅ Revert already reverted: Correctly FAILS") # ============================================ # BILL NUMBER SEQUENCE TESTS # ============================================ class TestBillNumberSequences: """Bill numbering tests""" @pytest.mark.asyncio async def test_bill_number_sequence(self, client: AsyncClient, db_session: AsyncSession): """Verify bill numbers increment correctly""" parties = await client.get("/api/parties?search=Ramesh Awaak") party_id = parties.json()["data"][0]["id"] bill_numbers = [] for i in range(3): response = await client.post("/api/transactions", json={ "bill_date": datetime.now().strftime("%Y-%m-%d"), "bill_type": "awaak", "party_id": party_id, "subtotal": 1000, "total_amount": 1000, "paid_amount": 1000, "balance_amount": 0, "items": [{"mirchi_name": "C5", "poti_count": 1, "net_weight": 50, "rate_per_kg": 20, "amount": 1000}], "payments": [{"amount": 1000, "mode": "cash"}] }) if response.status_code == 201: bill_numbers.append(response.json()["data"]["bill_number"]) year = datetime.now().year for bn in bill_numbers: assert bn.startswith(f"A{year}") print(f"\n✅ Bill Number Sequence: {bill_numbers}") @pytest.mark.asyncio async def test_bill_number_info(self, client: AsyncClient, db_session: AsyncSession): """Get bill number sequence info""" response = await client.get("/api/transactions/bill-number-info?bill_type=awaak") assert response.status_code == 200 print(f"\n✅ Bill Number Info retrieved") # ============================================ # SEARCH AND FILTER TESTS # ============================================ class TestSearchAndFilter: """Search and filtering tests""" @pytest.mark.asyncio async def test_search_by_bill_number(self, client: AsyncClient, db_session: AsyncSession): """Search by bill number""" response = await client.get("/api/transactions?search=A202") assert response.status_code == 200 print(f"\n✅ Search by bill number: Found {response.json()['total']} transactions") @pytest.mark.asyncio async def test_filter_by_bill_type(self, client: AsyncClient, db_session: AsyncSession): """Filter by bill type""" response = await client.get("/api/transactions?bill_type=awaak") assert response.status_code == 200 print(f"\n✅ Filter by awaak: Found {response.json()['total']} transactions") @pytest.mark.asyncio async def test_filter_by_party(self, client: AsyncClient, db_session: AsyncSession): """Filter by party ID""" parties = await client.get("/api/parties?search=Ramesh Awaak") party_id = parties.json()["data"][0]["id"] response = await client.get(f"/api/transactions?party_id={party_id}") assert response.status_code == 200 print(f"\n✅ Filter by party: Found {response.json()['total']} transactions") if __name__ == "__main__": pytest.main([__file__, "-v", "--tb=short", "-s"])