create or replace function ems.fn_economics_daily_month( p_site_id int, p_month_start date, p_month_end date ) returns jsonb language sql stable as $fn$ select jsonb_build_object( 'has_green_bonus', exists ( select 1 from ems.asset_pv_array apv where apv.site_id = p_site_id and apv.green_bonus_czk_kwh is not null ), 'days', coalesce( ( select jsonb_agg(sub.day_row order by sub.day_local) from ( select r.day_local, jsonb_build_object( 'day', r.day_local, 'interval_count', r.interval_count, 'import_kwh', r.import_kwh, 'export_kwh', r.export_kwh, 'pv_kwh', r.pv_kwh, 'load_kwh', r.load_kwh, 'pv_self_consumption_kwh', r.pv_self_consumption_kwh, 'ev_kwh', r.ev_kwh, 'hp_kwh', r.hp_kwh, 'import_cost_czk', case when l.site_id is not null then l.import_cost_czk else r.import_cost_czk end, 'export_revenue_czk', case when l.site_id is not null then l.export_revenue_czk else r.export_revenue_czk end, 'grid_import_cashflow_czk', coalesce(l.grid_import_cashflow_czk, r.grid_import_cashflow_czk), 'grid_export_revenue_czk', coalesce(l.grid_export_revenue_czk, r.grid_export_revenue_czk), 'net_cost_czk', case when l.site_id is not null then l.net_cost_czk else r.net_cost_czk end, 'green_bonus_czk', case when l.site_id is not null then l.green_bonus_czk else r.green_bonus_czk end, 'total_balance_czk', case when l.site_id is not null then l.total_balance_czk else r.total_balance_czk end, 'planned_balance_czk', r.planned_balance_czk, 'deviation_cost_czk', r.deviation_cost_czk, 'is_locked', (l.site_id is not null) ) as day_row from ems.vw_economics_daily r left join ems.audit_day_lock l on l.site_id = r.site_id and l.day_local = r.day_local where r.site_id = p_site_id and r.day_local >= p_month_start and r.day_local < p_month_end order by r.day_local ) sub ), '[]'::jsonb ) ); $fn$; comment on function ems.fn_economics_daily_month(int, date, date) is 'Měsíční denní ekonomika + lock merge jako JSON (GET /economics/daily).';