pratikbackend / tests /test_integration.py
Antaram's picture
Upload 96 files
7647b38 verified
Raw
History Blame Contribute Delete
29.3 kB
"""
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"])