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:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user