Add TVA balance display to Telegram dashboard with exclusive calculation logic

Implements VAT (TVA) balance tracking for both previous and current month with
mutually exclusive calculations (either payable OR recoverable per period).

Backend Changes:
- Add 4 TVA fields to DashboardSummary model
- Implement TVA query from vbal table (accounts 4423, 4424, 4426, 4427)
- Add exclusive calculation logic:
  * Previous month: difference between account 4423 (payable) OR 4424 (recoverable)
  * Current month: difference 4427-4426 (payable if >0, recoverable if <0)

Telegram Bot Changes:
- Add compact TVA section to dashboard formatter
- Display only when values > 0
- Format: "TVA de plată/recuperat precedent/curent"

Example output:
  **Solduri TVA:**
  - TVA de plată precedent: 7,284 RON
  - TVA de recuperat curent: 3,200 RON

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-18 10:39:04 +02:00
parent 87859e5510
commit 09984cbe1e
3 changed files with 95 additions and 3 deletions

View File

@@ -120,4 +120,10 @@ class DashboardSummary(BaseModel):
clienti_facturat_an_curent: Optional[Decimal] = Decimal('0')
clienti_facturat_an_anterior: Optional[Decimal] = Decimal('0')
furnizori_facturat_an_curent: Optional[Decimal] = Decimal('0')
furnizori_facturat_an_anterior: Optional[Decimal] = Decimal('0')
furnizori_facturat_an_anterior: Optional[Decimal] = Decimal('0')
# SOLDURI TVA
tva_plata_precedent: Decimal = Decimal('0')
tva_recuperat_precedent: Decimal = Decimal('0')
tva_plata_curent: Decimal = Decimal('0')
tva_recuperat_curent: Decimal = Decimal('0')

View File

@@ -385,7 +385,69 @@ class DashboardService:
cursor.execute(treasury_query)
treasury_rows = cursor.fetchall()
# Query 3: Solduri TVA din tabelul vbal
tva_query = f"""
WITH luna_curenta AS (
SELECT anul, luna FROM {schema}.calendar
WHERE anul*12+luna = (SELECT MAX(anul*12+luna) FROM {schema}.calendar)
)
SELECT
cont,
precdeb,
preccred,
ruldeb,
rulcred
FROM {schema}.vbal
WHERE an = (SELECT anul FROM luna_curenta)
AND luna = (SELECT luna FROM luna_curenta)
AND cont IN ('4423', '4424', '4426', '4427')
ORDER BY cont
"""
cursor.execute(tva_query)
tva_rows = cursor.fetchall()
# Procesare solduri TVA
tva_data = {
'4423': {'precdeb': Decimal('0'), 'preccred': Decimal('0'), 'ruldeb': Decimal('0'), 'rulcred': Decimal('0')},
'4424': {'precdeb': Decimal('0'), 'preccred': Decimal('0'), 'ruldeb': Decimal('0'), 'rulcred': Decimal('0')},
'4426': {'precdeb': Decimal('0'), 'preccred': Decimal('0'), 'ruldeb': Decimal('0'), 'rulcred': Decimal('0')},
'4427': {'precdeb': Decimal('0'), 'preccred': Decimal('0'), 'ruldeb': Decimal('0'), 'rulcred': Decimal('0')}
}
for row in tva_rows:
cont = row[0]
if cont in tva_data:
tva_data[cont]['precdeb'] = Decimal(str(row[1] or 0))
tva_data[cont]['preccred'] = Decimal(str(row[2] or 0))
tva_data[cont]['ruldeb'] = Decimal(str(row[3] or 0))
tva_data[cont]['rulcred'] = Decimal(str(row[4] or 0))
# Calcul TVA Luna Precedentă - FIE de plată (4423) FIE de recuperat (4424)
sold_4423 = tva_data['4423']['preccred'] - tva_data['4423']['precdeb']
sold_4424 = tva_data['4424']['precdeb'] - tva_data['4424']['preccred']
if sold_4423 > 0:
tva_plata_precedent = sold_4423
tva_recuperat_precedent = Decimal('0')
elif sold_4424 > 0:
tva_recuperat_precedent = sold_4424
tva_plata_precedent = Decimal('0')
else:
tva_plata_precedent = Decimal('0')
tva_recuperat_precedent = Decimal('0')
# Calcul TVA Luna Curentă - FIE de plată FIE de recuperat
diferenta_curent = tva_data['4427']['rulcred'] - tva_data['4426']['ruldeb']
if diferenta_curent > 0:
tva_plata_curent = diferenta_curent
tva_recuperat_curent = Decimal('0')
else:
tva_recuperat_curent = -diferenta_curent
tva_plata_curent = Decimal('0')
# Procesare trezorerie
treasury_accounts = []
treasury_totals = {}
@@ -465,7 +527,13 @@ class DashboardService:
clienti_facturat_an_curent=Decimal(str(facturi_row[38] or 0)),
clienti_facturat_an_anterior=Decimal(str(facturi_row[39] or 0)),
furnizori_facturat_an_curent=Decimal(str(facturi_row[40] or 0)),
furnizori_facturat_an_anterior=Decimal(str(facturi_row[41] or 0))
furnizori_facturat_an_anterior=Decimal(str(facturi_row[41] or 0)),
# Solduri TVA
tva_plata_precedent=tva_plata_precedent,
tva_recuperat_precedent=tva_recuperat_precedent,
tva_plata_curent=tva_plata_curent,
tva_recuperat_curent=tva_recuperat_curent
)
@staticmethod

View File

@@ -45,6 +45,24 @@ def format_dashboard_response(data: Dict[str, Any], company_name: str = None) ->
else:
text += f" - Net: {furnizori_sold_net:,} RON"
# Solduri TVA - rotunjit la leu
tva_plata_prec = round(float(data.get('tva_plata_precedent', 0)))
tva_recup_prec = round(float(data.get('tva_recuperat_precedent', 0)))
tva_plata_cur = round(float(data.get('tva_plata_curent', 0)))
tva_recup_cur = round(float(data.get('tva_recuperat_curent', 0)))
# Afișează secțiunea doar dacă există cel puțin o valoare > 0
if tva_plata_prec > 0 or tva_recup_prec > 0 or tva_plata_cur > 0 or tva_recup_cur > 0:
text += "\n\n**Solduri TVA:**\n"
if tva_plata_prec > 0:
text += f" - TVA de plată precedent: {tva_plata_prec:,} RON\n"
if tva_recup_prec > 0:
text += f" - TVA de recuperat precedent: {tva_recup_prec:,} RON\n"
if tva_plata_cur > 0:
text += f" - TVA de plată curent: {tva_plata_cur:,} RON\n"
if tva_recup_cur > 0:
text += f" - TVA de recuperat curent: {tva_recup_cur:,} RON\n"
return text