fix: Update Trial Balance to use real VBAL VIEW structure

After database verification, VBAL is a VIEW (not a table) that exists
in each company schema with a different structure than initially assumed.

Backend Changes:
- Updated models (trial_balance.py):
  - Changed column names to match real VBAL VIEW
  - CONT (account number)
  - DENUMIRE (account description, not DCONT)
  - PRECDEB/PRECCRED (previous balance, not SD_PREC/SC_PREC)
  - RULDEB/RULCRED (monthly movement, not RD_LUNA/RC_LUNA)
  - SOLDDEB/SOLDCRED (final balance, not SD_FINAL/SC_FINAL)
  - Made DENUMIRE optional (can be NULL in VIEW)

- Updated router (trial_balance.py):
  - Removed COD_FIRMA filter (not in VIEW)
  - Query now uses: {schema}.VBAL WHERE AN = :an AND LUNA = :luna
  - Fixed column names in SELECT (DENUMIRE instead of DCONT)
  - Updated sort columns validation
  - Fixed result processing to match new column order

Frontend Changes:
- Updated TrialBalanceView.vue:
  - Changed field from 'dcont' to 'denumire' in DataTable column

Database Verification:
- VBAL VIEW confirmed in ROMFAST schema (24,217 records)
- Current data available up to November 2025
- Structure verified with 22 columns
- VIEW exists in all company schemas

Testing Notes:
- Backend endpoint ready for testing
- Frontend field names now match API response
- Ready for manual testing with real company data

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-20 00:57:14 +02:00
parent 0b00b66ed5
commit 6c373c609e
5 changed files with 728 additions and 26 deletions

View File

@@ -1,6 +1,6 @@
"""
Pydantic models for Trial Balance (Balanță de Verificare)
Maps to Oracle VBAL table
Maps to Oracle VBAL VIEW (exists in each company schema)
"""
from pydantic import BaseModel, Field
from typing import Optional, List
@@ -8,16 +8,22 @@ from decimal import Decimal
class TrialBalanceItem(BaseModel):
"""
Individual trial balance record from VBAL table
Individual trial balance record from VBAL VIEW
Real structure from Oracle:
- CONT: account number
- DENUMIRE: account description
- PRECDEB/PRECCRED: previous balance debit/credit
- RULDEB/RULCRED: monthly movement debit/credit
- SOLDDEB/SOLDCRED: final balance debit/credit
"""
cont: str = Field(description="Număr cont contabil")
dcont: str = Field(description="Denumire cont")
sold_precedent_debit: Decimal = Field(description="Sold precedent debit", decimal_places=2)
sold_precedent_credit: Decimal = Field(description="Sold precedent credit", decimal_places=2)
rulaj_lunar_debit: Decimal = Field(description="Rulaj lunar debit", decimal_places=2)
rulaj_lunar_credit: Decimal = Field(description="Rulaj lunar credit", decimal_places=2)
sold_final_debit: Decimal = Field(description="Sold final debit", decimal_places=2)
sold_final_credit: Decimal = Field(description="Sold final credit", decimal_places=2)
cont: str = Field(description="Număr cont contabil (CONT)")
denumire: Optional[str] = Field(default="", description="Denumire cont (DENUMIRE)")
sold_precedent_debit: Decimal = Field(description="Sold precedent debit (PRECDEB)", decimal_places=2)
sold_precedent_credit: Decimal = Field(description="Sold precedent credit (PRECCRED)", decimal_places=2)
rulaj_lunar_debit: Decimal = Field(description="Rulaj lunar debit (RULDEB)", decimal_places=2)
rulaj_lunar_credit: Decimal = Field(description="Rulaj lunar credit (RULCRED)", decimal_places=2)
sold_final_debit: Decimal = Field(description="Sold final debit (SOLDDEB)", decimal_places=2)
sold_final_credit: Decimal = Field(description="Sold final credit (SOLDCRED)", decimal_places=2)
class Config:
from_attributes = True

View File

@@ -64,8 +64,9 @@ async def get_trial_balance(
sort_order = 'asc'
# Validează sort_by (previne SQL injection)
valid_sort_columns = ['CONT', 'DCONT', 'SD_PREC', 'SC_PREC', 'RD_LUNA',
'RC_LUNA', 'SD_FINAL', 'SC_FINAL']
# Real column names from VBAL VIEW
valid_sort_columns = ['CONT', 'DENUMIRE', 'PRECDEB', 'PRECCRED',
'RULDEB', 'RULCRED', 'SOLDDEB', 'SOLDCRED']
if sort_by.upper() not in valid_sort_columns:
sort_by = 'CONT'
@@ -90,25 +91,25 @@ async def get_trial_balance(
schema = schema_result[0]
# Construiește query-ul de bază pentru VBAL
# Construiește query-ul de bază pentru VBAL VIEW
# VBAL este un VIEW în fiecare schemă de companie
# Structura reală: CONT, DENUMIRE, AN, LUNA, PRECDEB, PRECCRED, RULDEB, RULCRED, SOLDDEB, SOLDCRED
base_query = f"""
SELECT
CONT,
DCONT,
NVL(SD_PREC, 0) as SD_PREC,
NVL(SC_PREC, 0) as SC_PREC,
NVL(RD_LUNA, 0) as RD_LUNA,
NVL(RC_LUNA, 0) as RC_LUNA,
NVL(SD_FINAL, 0) as SD_FINAL,
NVL(SC_FINAL, 0) as SC_FINAL
NVL(DENUMIRE, '') as DENUMIRE,
NVL(PRECDEB, 0) as PRECDEB,
NVL(PRECCRED, 0) as PRECCRED,
NVL(RULDEB, 0) as RULDEB,
NVL(RULCRED, 0) as RULCRED,
NVL(SOLDDEB, 0) as SOLDDEB,
NVL(SOLDCRED, 0) as SOLDCRED
FROM {schema}.VBAL
WHERE COD_FIRMA = :cod_firma
AND AN = :an
WHERE AN = :an
AND LUNA = :luna
"""
params = {
'cod_firma': company,
'an': an,
'luna': luna
}
@@ -119,7 +120,7 @@ async def get_trial_balance(
params['cont_filter'] = f"{cont_filter}%"
if denumire_filter:
base_query += " AND UPPER(DCONT) LIKE UPPER(:denumire_filter)"
base_query += " AND UPPER(DENUMIRE) LIKE UPPER(:denumire_filter)"
params['denumire_filter'] = f"%{denumire_filter}%"
# Count total pentru paginare
@@ -148,11 +149,13 @@ async def get_trial_balance(
rows = cursor.fetchall()
# Procesează rezultatele
# Index columns: CONT(0), DENUMIRE(1), PRECDEB(2), PRECCRED(3),
# RULDEB(4), RULCRED(5), SOLDDEB(6), SOLDCRED(7), rnum(8)
items = []
for row in rows:
item = TrialBalanceItem(
cont=row[0] or '',
dcont=row[1] or '',
denumire=row[1] or '',
sold_precedent_debit=Decimal(str(row[2] or 0)),
sold_precedent_credit=Decimal(str(row[3] or 0)),
rulaj_lunar_debit=Decimal(str(row[4] or 0)),

View File

@@ -119,7 +119,7 @@
</template>
</Column>
<Column field="dcont" header="Denumire Cont" sortable :style="{ width: '25%' }" />
<Column field="denumire" header="Denumire Cont" sortable :style="{ width: '25%' }" />
<Column header="Sold Precedent" :style="{ width: '15%' }">
<template #body="slotProps">