feat: Add A-Z filter for clients/suppliers in Telegram bot
- Add A-Z alphabetical filter keyboard for clients and suppliers lists (same pattern as company selection, without emoji) - Increase clients/suppliers list pagination from 10 to 20 items per page - Remove emoji from company A-Z filter button for consistency - Add 6 new callback handlers: clients_alpha_menu, clients_alpha:LETTER, clients_alpha_page:PAGE:LETTER, and supplier equivalents - Dashboard service and models updates - Telegram bot: email handlers, auth, DB operations, internal API improvements - Frontend: dashboard cards updates (CashFlow, Clienti, Furnizori, Treasury) - Frontend: SolduriCompactCard and CollapsibleCard improvements - DashboardView enhancements - start.sh and run-with-restart.sh script updates - IIS web.config and service worker updates Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
import os
|
||||
|
||||
from shared.database.oracle_pool import oracle_pool
|
||||
from ..models.dashboard import DashboardSummary, TreasuryAccount, TrendData
|
||||
from ..models.dashboard import DashboardSummary, TreasuryAccount, TrendData, BudgetDebtGroup, BudgetDebtSubAccount
|
||||
from ..cache.decorators import cached
|
||||
from decimal import Decimal
|
||||
from typing import Dict, Any, List, Optional
|
||||
@@ -12,6 +12,45 @@ import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Grupuri de conturi pentru Datorii la Buget (3 grupe: TVA / BASS / CAM)
|
||||
BUDGET_GROUPS = [
|
||||
{
|
||||
'key': 'TVA',
|
||||
'label': 'TVA',
|
||||
'accounts': ['4423', '4424'],
|
||||
},
|
||||
{
|
||||
'key': 'BASS',
|
||||
'label': 'BASS',
|
||||
'accounts': ['431', '4311', '4313', '4315', '4316', '437', '444', '4411', '4418', '446', '447'],
|
||||
},
|
||||
{
|
||||
'key': 'CAM',
|
||||
'label': 'CAM',
|
||||
'accounts': ['436'],
|
||||
},
|
||||
]
|
||||
|
||||
ACCOUNT_LABELS = {
|
||||
'4311': '4311 - CAS angajat',
|
||||
'4313': '4313 - CAS accidente muncă',
|
||||
'4315': '4315 - CAS suplimentar',
|
||||
'4316': '4316 - CASS angajat',
|
||||
'431': '431 - CAS (cont total)',
|
||||
'437': '437 - CASS (cont total)',
|
||||
'444': '444 - Impozit salarii',
|
||||
'4411': '4411 - Impozit pe profit',
|
||||
'4418': '4418 - Impozit amânat',
|
||||
'446': '446 - Alte impozite și taxe',
|
||||
'447': '447 - Fonduri speciale',
|
||||
'4423': '4423 - TVA de plată',
|
||||
'4424': '4424 - TVA de recuperat',
|
||||
'4426': '4426 - TVA deductibilă',
|
||||
'4427': '4427 - TVA colectată',
|
||||
'436': '436 - CAM',
|
||||
}
|
||||
|
||||
|
||||
class DashboardService:
|
||||
"""Service pentru dashboard - date agregate"""
|
||||
|
||||
@@ -412,13 +451,17 @@ class DashboardService:
|
||||
AND ((cont IN ('5121','5311') AND soldcred - solddeb != 0)
|
||||
OR (cont IN ('5124','5314') AND soldvalcred - soldvaldeb != 0))
|
||||
GROUP BY cont, nume, nume_val
|
||||
ORDER BY cont, nume
|
||||
ORDER BY
|
||||
CASE WHEN cont IN ('5121','5311') THEN 0 ELSE 1 END,
|
||||
cont,
|
||||
UPPER(nume)
|
||||
"""
|
||||
|
||||
cursor.execute(treasury_query, period_params)
|
||||
treasury_rows = cursor.fetchall()
|
||||
|
||||
# Query 3: Solduri TVA din tabelul vbal (folosește același period_cte)
|
||||
# Query 3: Solduri datorii buget din tabelul vbal (43xx + 44xx)
|
||||
# Extins față de TVA-only pentru a include CAS, CASS, impozite, etc.
|
||||
tva_query = f"""
|
||||
{period_cte}
|
||||
SELECT
|
||||
@@ -426,34 +469,42 @@ class DashboardService:
|
||||
precdeb,
|
||||
preccred,
|
||||
ruldeb,
|
||||
rulcred
|
||||
rulcred,
|
||||
solddeb,
|
||||
soldcred
|
||||
FROM {schema}.vbal
|
||||
WHERE an = (SELECT anul FROM luna_curenta)
|
||||
AND luna = (SELECT luna FROM luna_curenta)
|
||||
AND cont IN ('4423', '4424', '4426', '4427')
|
||||
AND (cont LIKE '43%' OR cont LIKE '44%')
|
||||
ORDER BY cont
|
||||
"""
|
||||
|
||||
cursor.execute(tva_query, period_params)
|
||||
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')}
|
||||
}
|
||||
# Procesare solduri: dict generic pentru toate conturile 43xx/44xx
|
||||
_zero = {'precdeb': Decimal('0'), 'preccred': Decimal('0'), 'ruldeb': Decimal('0'), 'rulcred': Decimal('0'), 'solddeb': Decimal('0'), 'soldcred': Decimal('0')}
|
||||
all_budget_data: Dict[str, Any] = {}
|
||||
|
||||
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))
|
||||
all_budget_data[cont] = {
|
||||
'precdeb': Decimal(str(row[1] or 0)),
|
||||
'preccred': Decimal(str(row[2] or 0)),
|
||||
'ruldeb': Decimal(str(row[3] or 0)),
|
||||
'rulcred': Decimal(str(row[4] or 0)),
|
||||
'solddeb': Decimal(str(row[5] or 0)),
|
||||
'soldcred': Decimal(str(row[6] or 0)),
|
||||
}
|
||||
|
||||
# Backward compat: tva_data dict cu doar conturile TVA clasice
|
||||
tva_data = {
|
||||
k: all_budget_data.get(k, dict(_zero))
|
||||
for k in ['4423', '4424', '4426', '4427']
|
||||
}
|
||||
|
||||
# Calcul TVA Luna Precedentă - FIE de plată (4423) FIE de recuperat (4424)
|
||||
# Primary: folosim soldurile conturilor de regularizare TVA (luna anterioară închisă)
|
||||
sold_4423 = tva_data['4423']['preccred'] - tva_data['4423']['precdeb']
|
||||
sold_4424 = tva_data['4424']['precdeb'] - tva_data['4424']['preccred']
|
||||
|
||||
@@ -464,18 +515,97 @@ class DashboardService:
|
||||
tva_recuperat_precedent = sold_4424
|
||||
tva_plata_precedent = Decimal('0')
|
||||
else:
|
||||
tva_plata_precedent = Decimal('0')
|
||||
tva_recuperat_precedent = Decimal('0')
|
||||
# Fallback: când luna anterioară nu e închisă (4423/4424 = 0),
|
||||
# calculăm soldul lunar net al conturilor 4427/4426
|
||||
sold_4427_prec = tva_data['4427']['preccred'] - tva_data['4427']['precdeb']
|
||||
sold_4426_prec = tva_data['4426']['precdeb'] - tva_data['4426']['preccred']
|
||||
diferenta_prec = sold_4427_prec - sold_4426_prec
|
||||
if diferenta_prec > 0:
|
||||
tva_plata_precedent = diferenta_prec
|
||||
tva_recuperat_precedent = Decimal('0')
|
||||
else:
|
||||
tva_recuperat_precedent = -diferenta_prec
|
||||
tva_plata_precedent = Decimal('0')
|
||||
|
||||
# Calcul TVA Luna Curentă - FIE de plată FIE de recuperat
|
||||
diferenta_curent = tva_data['4427']['rulcred'] - tva_data['4426']['ruldeb']
|
||||
# Calcul TVA Luna Curentă - rulaj lunar 4423/4424 (nu sold cumulat)
|
||||
sold_4423_cur = tva_data['4423']['rulcred'] - tva_data['4423']['ruldeb']
|
||||
sold_4424_cur = tva_data['4424']['ruldeb'] - tva_data['4424']['rulcred']
|
||||
|
||||
if diferenta_curent > 0:
|
||||
tva_plata_curent = diferenta_curent
|
||||
if sold_4423_cur > 0:
|
||||
tva_plata_curent = sold_4423_cur
|
||||
tva_recuperat_curent = Decimal('0')
|
||||
else:
|
||||
tva_recuperat_curent = -diferenta_curent
|
||||
elif sold_4424_cur > 0:
|
||||
tva_recuperat_curent = sold_4424_cur
|
||||
tva_plata_curent = Decimal('0')
|
||||
else:
|
||||
# Fallback: rulaj lunar net 4427/4426 (ruldeb/rulcred = doar luna curentă)
|
||||
sold_4427_cur = tva_data['4427']['rulcred'] - tva_data['4427']['ruldeb']
|
||||
sold_4426_cur = tva_data['4426']['ruldeb'] - tva_data['4426']['rulcred']
|
||||
diferenta_curent = sold_4427_cur - sold_4426_cur
|
||||
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')
|
||||
|
||||
# Calcul Datorii la Buget - 3 grupe (TVA / BASS / CAM) cu sub-conturi
|
||||
budget_debt_breakdown = []
|
||||
for group_def in BUDGET_GROUPS:
|
||||
sub_accounts = []
|
||||
group_prec = Decimal('0')
|
||||
group_cur = Decimal('0')
|
||||
|
||||
if group_def['key'] == 'TVA':
|
||||
# TVA special: valorile deja calculate (semn ±)
|
||||
tva_prec = tva_plata_precedent - tva_recuperat_precedent
|
||||
tva_cur = tva_plata_curent - tva_recuperat_curent
|
||||
group_prec = tva_prec
|
||||
group_cur = tva_cur
|
||||
# Sub-conturi TVA (doar cele cu sold non-zero)
|
||||
for cont in ['4423', '4424', '4426', '4427']:
|
||||
if cont in all_budget_data:
|
||||
d = all_budget_data[cont]
|
||||
if cont == '4424': # creanță → semn negativ
|
||||
val_prec = -(d['precdeb'] - d['preccred'])
|
||||
val_cur = -(d['ruldeb'] - d['rulcred'])
|
||||
else: # 4423, 4426, 4427: rulcred - ruldeb (lunar, nu cumulat)
|
||||
val_prec = d['preccred'] - d['precdeb']
|
||||
val_cur = d['rulcred'] - d['ruldeb']
|
||||
if val_prec != 0 or val_cur != 0:
|
||||
sub_accounts.append(BudgetDebtSubAccount(
|
||||
cont=cont,
|
||||
label=ACCOUNT_LABELS[cont],
|
||||
precedent=val_prec,
|
||||
curent=val_cur,
|
||||
))
|
||||
else:
|
||||
# BASS și CAM: matching exact pe codul contului
|
||||
for account_code in group_def['accounts']:
|
||||
if account_code in all_budget_data:
|
||||
d = all_budget_data[account_code]
|
||||
val_prec = d['preccred'] - d['precdeb'] # pozitiv = datorie
|
||||
val_cur = d['rulcred'] - d['ruldeb'] # rulaj luna curentă (consistent cu TVA)
|
||||
if val_prec != 0 or val_cur != 0:
|
||||
sub_accounts.append(BudgetDebtSubAccount(
|
||||
cont=account_code,
|
||||
label=ACCOUNT_LABELS.get(account_code, account_code),
|
||||
precedent=val_prec,
|
||||
curent=val_cur,
|
||||
))
|
||||
group_prec += val_prec
|
||||
group_cur += val_cur
|
||||
|
||||
if group_prec != 0 or group_cur != 0 or sub_accounts:
|
||||
budget_debt_breakdown.append(BudgetDebtGroup(
|
||||
key=group_def['key'],
|
||||
label=group_def['label'],
|
||||
precedent=group_prec,
|
||||
curent=group_cur,
|
||||
sub_accounts=sub_accounts,
|
||||
))
|
||||
|
||||
budget_debt_total_precedent = sum(g.precedent for g in budget_debt_breakdown)
|
||||
|
||||
# Procesare trezorerie
|
||||
treasury_accounts = []
|
||||
@@ -562,7 +692,11 @@ class DashboardService:
|
||||
tva_plata_precedent=tva_plata_precedent,
|
||||
tva_recuperat_precedent=tva_recuperat_precedent,
|
||||
tva_plata_curent=tva_plata_curent,
|
||||
tva_recuperat_curent=tva_recuperat_curent
|
||||
tva_recuperat_curent=tva_recuperat_curent,
|
||||
|
||||
# Datorii la buget pe grupe cu sub-conturi
|
||||
budget_debt_breakdown=budget_debt_breakdown,
|
||||
budget_debt_total_precedent=budget_debt_total_precedent,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
@@ -1691,7 +1825,9 @@ class DashboardService:
|
||||
AND vb.luna = lc.luna
|
||||
AND vb.cont IN ('5311', '5314', '5328', '5121', '5124')
|
||||
AND (vb.solddeb - vb.soldcred) <> 0
|
||||
ORDER BY tip, vb.cont
|
||||
ORDER BY tip,
|
||||
CASE WHEN vb.cont IN ('5121','5311') THEN 0 ELSE 1 END,
|
||||
UPPER(vb.nume)
|
||||
"""
|
||||
|
||||
cursor.execute(treasury_query, period_params)
|
||||
|
||||
Reference in New Issue
Block a user