Enhance Telegram bot UI with YTD comparison, 12-month evolution, and improved navigation

- Add YTD year-over-year comparison table for cash flow evolution
- Extend monthly evolution from 6 to 12 months with dynamic year extraction
- Simplify monthly view to show only Net values aligned with YTD table
- Upgrade client/supplier display from Top 5 to Top 10 with alphabetical sorting
- Remove Refresh and Export buttons from dashboard and evolution views
- Add get_trends() API method for 12-month historical data from backend
- Fix default years to 2025/2024 for accurate YTD calculations

Changes:
- client.py: New get_trends() method calls /api/dashboard/trends endpoint
- helpers.py: Rewrite get_cashflow_evolution_data() to use trends and calculate YTD
- formatters.py: Complete redesign with YTD table and simplified 12-month Net view
- menus.py: Alphabetical sorting for clients/suppliers, removed refresh buttons
- handlers.py: Disabled refresh/export buttons on dashboard and evolution views

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-07 02:30:28 +02:00
parent a4ee394091
commit 87bd04e3ff
5 changed files with 244 additions and 78 deletions

View File

@@ -524,61 +524,130 @@ async def get_cashflow_evolution_data(
period: str = "12m"
) -> Optional[Dict[str, Any]]:
"""
Get cash flow evolution data.
Get cash flow evolution data with YTD comparison.
Uses monthly flows endpoint which returns current month data.
Backend returns: {'inflows': float, 'outflows': float, 'period': str, 'currency': str}
Uses trends endpoint which returns 12-month historical data for current and previous year.
Calculates YTD for comparison and extracts last 12 months in reverse chronological order.
Args:
company_id: Company ID
jwt_token: JWT authentication token
period: Period for monthly data (default: "12m")
period: Period for trends data (default: "12m")
Returns:
Dict with:
- 'performance': Dict with incasari_total, plati_total, net
- 'monthly': Dict with months, incasari, plati arrays
- 'performance': Dict with YTD data for current and previous year
- 'monthly': Dict with last 12 months data (reverse chronological) + prev year comparison
None if request fails
Example:
data = await get_cashflow_evolution_data(1, token)
net = data['performance']['net'] # Net cash flow
months = data['monthly']['months'] # List of month names
ytd_2025 = data['performance']['current_year']
ytd_2024 = data['performance']['previous_year']
"""
try:
client = get_backend_client()
async with client:
# Get monthly flows (current month only from backend)
monthly_flows = await client.get_monthly_flows(
# Get trends data (12 months of historical data)
trends_data = await client.get_trends(
company_id=company_id,
jwt_token=jwt_token,
months=12 # Note: backend ignores this and returns only current month
period="12m"
)
if not monthly_flows:
if not trends_data:
return None
# Transform backend response to expected format
inflows = float(monthly_flows.get('inflows', 0))
outflows = float(monthly_flows.get('outflows', 0))
period_name = monthly_flows.get('period', 'Luna curentă')
# Extract current year data
periods = trends_data.get('periods', []) # ["2024-01", "2024-02", ...]
clienti_incasat = trends_data.get('clienti_incasat', [])
furnizori_achitat = trends_data.get('furnizori_achitat', [])
# Calculate net
net = inflows - outflows
# Extract previous year data
previous_periods = trends_data.get('previous_periods', [])
clienti_incasat_prev = trends_data.get('clienti_incasat_prev', [])
furnizori_achitat_prev = trends_data.get('furnizori_achitat_prev', [])
# Build performance summary
performance = {
'incasari_total': inflows,
'plati_total': outflows,
'net': net
if not periods or not clienti_incasat or not furnizori_achitat:
logger.warning("Trends data missing required fields")
return None
# Calculate YTD (Year-To-Date) = sum of all available months
incasari_ytd = sum(clienti_incasat)
plati_ytd = sum(furnizori_achitat)
net_ytd = incasari_ytd - plati_ytd
incasari_ytd_prev = sum(clienti_incasat_prev) if clienti_incasat_prev else 0
plati_ytd_prev = sum(furnizori_achitat_prev) if furnizori_achitat_prev else 0
net_ytd_prev = incasari_ytd_prev - plati_ytd_prev
# Extract years from periods
current_year = periods[-1].split('-')[0] if periods else "2025"
previous_year = previous_periods[-1].split('-')[0] if previous_periods else "2024"
# Take last 12 months (current year)
last_12_periods = periods[-12:]
last_12_incasari = clienti_incasat[-12:]
last_12_plati = furnizori_achitat[-12:]
# Take corresponding previous year months
last_12_periods_prev = previous_periods[-12:] if previous_periods else []
last_12_incasari_prev = clienti_incasat_prev[-12:] if clienti_incasat_prev else [0] * 12
last_12_plati_prev = furnizori_achitat_prev[-12:] if furnizori_achitat_prev else [0] * 12
# Month abbreviations (Romanian)
month_abbr = {
'01': 'Ian', '02': 'Feb', '03': 'Mar', '04': 'Apr',
'05': 'Mai', '06': 'Iun', '07': 'Iul', '08': 'Aug',
'09': 'Sep', '10': 'Oct', '11': 'Noi', '12': 'Dec'
}
# Build monthly breakdown (single month from backend)
# Format months as "Noi'25/'24"
formatted_months = []
for i, period_str in enumerate(last_12_periods):
if '-' in period_str:
year = period_str.split('-')[0][-2:] # Last 2 digits: "25"
month_num = period_str.split('-')[1]
month_name = month_abbr.get(month_num, month_num)
# Get previous year month
prev_year = previous_year[-2:] if previous_year else "24"
formatted_months.append(f"{month_name}'{year}/'{prev_year}")
else:
formatted_months.append(period_str)
# Reverse chronological order (newest first)
formatted_months.reverse()
last_12_incasari.reverse()
last_12_plati.reverse()
last_12_incasari_prev.reverse()
last_12_plati_prev.reverse()
# Build performance summary (YTD)
performance = {
'current_year': {
'year': current_year,
'incasari': incasari_ytd,
'plati': plati_ytd,
'net': net_ytd
},
'previous_year': {
'year': previous_year,
'incasari': incasari_ytd_prev,
'plati': plati_ytd_prev,
'net': net_ytd_prev
}
}
# Build monthly breakdown (reverse chronological with prev year comparison)
monthly = {
'months': [period_name],
'incasari': [inflows],
'plati': [outflows]
'months': formatted_months,
'incasari': last_12_incasari,
'plati': last_12_plati,
'incasari_prev': last_12_incasari_prev,
'plati_prev': last_12_plati_prev
}
return {