Files
roa2web-service-auto/reports-app/backend/app/routers/trial_balance.py
Marius Mutu a45dfa826d feat: Enhance Trial Balance PDF export with professional formatting
- Add multi-line header: company name, centered title, centered period
- Implement pagination with page numbers in footer
- Add generation timestamp in footer
- Optimize column width distribution (Cont: 7%, Denumire: 33%, Values: 10% each)
- Align Cont column to left, all numeric columns to right
- Remove debug console.log statements
- Fix company name property (.firma → .name)
- Use full page width for table (281mm on A4 landscape)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-20 03:18:12 +02:00

92 lines
3.4 KiB
Python

"""
API Router for Trial Balance (Balanță de Verificare)
Refactored to use service layer with caching
"""
from fastapi import APIRouter, Depends, HTTPException, Query
from typing import Optional
from datetime import date
import sys
import os
sys.path.append(os.path.join(os.path.dirname(__file__), '../../../../shared'))
from auth.dependencies import get_current_user
from auth.models import CurrentUser
from ..models.trial_balance import TrialBalanceResponse
from ..services.trial_balance_service import TrialBalanceService
import logging
logger = logging.getLogger(__name__)
router = APIRouter()
@router.get("/", response_model=TrialBalanceResponse)
async def get_trial_balance(
company: str = Query(description="Codul firmei (ID)"),
luna: Optional[int] = Query(None, ge=1, le=12, description="Luna (1-12), default: luna curentă"),
an: Optional[int] = Query(None, ge=2000, le=2100, description="An, default: anul curent"),
cont_filter: Optional[str] = Query(None, description="Filtru număr cont (ex: '512', '4111')"),
denumire_filter: Optional[str] = Query(None, description="Filtru denumire cont (partial match, case-insensitive)"),
sort_by: str = Query("CONT", description="Coloană pentru sortare"),
sort_order: str = Query("asc", description="Ordinea sortării (asc | desc)"),
page: int = Query(1, ge=1, description="Pagina"),
page_size: int = Query(50, ge=1, le=1000000, description="Mărimea paginii"),
current_user: CurrentUser = Depends(get_current_user)
):
"""
Obține balanța de verificare sintetică pentru o firmă
- Necesită autentificare JWT
- Utilizatorul trebuie să aibă acces la firma specificată
- Suportă filtrare după cont și denumire
- Suportă paginare și sortare
- **CACHED 10 min** - folosește sistem cache two-tier (L1 Memory + L2 SQLite)
"""
try:
# Verifică dacă utilizatorul are acces la firma specificată
if company not in current_user.companies:
raise HTTPException(
status_code=403,
detail=f"Nu aveți acces la firma {company}"
)
# Setează valorile implicite pentru lună și an (luna și anul curent)
current_date = date.today()
if luna is None:
luna = current_date.month
if an is None:
an = current_date.year
# Convert company to int
company_id = int(company)
# Call service (with caching) - all business logic moved to service
data = await TrialBalanceService.get_trial_balance(
company_id=company_id,
luna=luna,
an=an,
cont_filter=cont_filter,
denumire_filter=denumire_filter,
sort_by=sort_by,
sort_order=sort_order,
page=page,
page_size=page_size,
username=current_user.username
)
return TrialBalanceResponse(
success=True,
data=data
)
except ValueError as e:
# Schema not found or validation error
logger.error(f"Validation error in trial balance: {str(e)}")
raise HTTPException(status_code=400, detail=str(e))
except Exception as e:
# Log unexpected errors
logger.error(f"Error fetching trial balance: {str(e)}", exc_info=True)
raise HTTPException(
status_code=500,
detail=f"Eroare la obținerea balanței de verificare: {str(e)}"
)