bmc_hub/migrations/103_fixed_price_reporting_views.sql
Christian e4b9091a1b feat: Implement fixed-price agreements frontend views and related templates
- Added views for listing fixed-price agreements, displaying agreement details, and a reporting dashboard.
- Created HTML templates for listing, detailing, and reporting on fixed-price agreements.
- Introduced API endpoint to fetch active customers for agreement creation.
- Added migration scripts for creating necessary database tables and views for fixed-price agreements, billing periods, and reporting.
- Implemented triggers for auto-generating agreement numbers and updating timestamps.
- Enhanced ticket management with archived ticket views and filtering capabilities.
2026-02-08 01:45:00 +01:00

114 lines
4.4 KiB
SQL

-- Migration 103: Fixed-Price Reporting Views
-- Pre-aggregated views for dashboard and reporting performance
-- Agreement performance aggregation
CREATE OR REPLACE VIEW fixed_price_agreement_performance AS
SELECT
a.id,
a.agreement_number,
a.customer_id,
a.customer_name,
a.status,
a.monthly_hours,
a.hourly_rate,
a.overtime_rate,
a.internal_cost_rate,
-- Period counts
COUNT(DISTINCT bp.id) as total_periods,
COUNT(DISTINCT bp.id) FILTER (WHERE bp.status = 'billed') as billed_periods,
-- Hour aggregations
COALESCE(SUM(bp.included_hours), 0) as total_included_hours,
COALESCE(SUM(bp.used_hours), 0) as total_used_hours,
COALESCE(SUM(bp.overtime_hours) FILTER (WHERE bp.overtime_approved), 0) as total_approved_overtime,
-- Revenue (only billed periods)
COALESCE(SUM(bp.base_amount) FILTER (WHERE bp.status = 'billed'), 0) as total_base_revenue,
COALESCE(SUM(bp.overtime_amount) FILTER (WHERE bp.status = 'billed' AND bp.overtime_approved), 0) as total_overtime_revenue,
COALESCE(
SUM(bp.base_amount) FILTER (WHERE bp.status = 'billed') +
SUM(bp.overtime_amount) FILTER (WHERE bp.status = 'billed' AND bp.overtime_approved),
0
) as total_revenue,
-- Cost calculation
COALESCE(SUM(bp.used_hours) * a.internal_cost_rate, 0) as total_internal_cost,
-- Profit
COALESCE(
SUM(bp.base_amount) FILTER (WHERE bp.status = 'billed') +
SUM(bp.overtime_amount) FILTER (WHERE bp.status = 'billed' AND bp.overtime_approved) -
SUM(bp.used_hours) * a.internal_cost_rate,
0
) as total_profit,
-- Utilization (used hours / included hours)
CASE
WHEN SUM(bp.included_hours) > 0
THEN ROUND((SUM(bp.used_hours) / SUM(bp.included_hours) * 100)::numeric, 1)
ELSE 0
END as utilization_percent,
-- Latest period
MAX(bp.period_end) as latest_period_end
FROM customer_fixed_price_agreements a
LEFT JOIN fixed_price_billing_periods bp ON a.id = bp.agreement_id
GROUP BY a.id;
-- Monthly trend view
CREATE OR REPLACE VIEW fixed_price_monthly_trends AS
SELECT
DATE_TRUNC('month', bp.period_start)::date as month,
COUNT(DISTINCT a.id) as active_agreements,
COUNT(DISTINCT bp.id) as total_periods,
SUM(bp.included_hours) as total_included_hours,
SUM(bp.used_hours) as total_used_hours,
SUM(bp.overtime_hours) FILTER (WHERE bp.overtime_approved) as total_approved_overtime,
SUM(bp.base_amount) FILTER (WHERE bp.status = 'billed') as monthly_base_revenue,
SUM(bp.overtime_amount) FILTER (WHERE bp.status = 'billed' AND bp.overtime_approved) as monthly_overtime_revenue,
SUM(bp.base_amount + COALESCE(bp.overtime_amount, 0)) FILTER (WHERE bp.status = 'billed') as monthly_total_revenue,
AVG(a.internal_cost_rate) as avg_internal_cost_rate,
SUM(bp.used_hours * a.internal_cost_rate) as monthly_internal_cost,
SUM(bp.base_amount + COALESCE(bp.overtime_amount, 0)) FILTER (WHERE bp.status = 'billed') -
SUM(bp.used_hours * a.internal_cost_rate) as monthly_profit
FROM fixed_price_billing_periods bp
JOIN customer_fixed_price_agreements a ON bp.agreement_id = a.id
GROUP BY DATE_TRUNC('month', bp.period_start)
ORDER BY month DESC;
-- Customer aggregation
CREATE OR REPLACE VIEW fixed_price_customer_summary AS
SELECT
a.customer_id,
a.customer_name,
COUNT(DISTINCT a.id) as agreement_count,
COUNT(DISTINCT a.id) FILTER (WHERE a.status = 'active') as active_agreements,
SUM(bp.used_hours) as total_hours_used,
SUM(bp.base_amount + COALESCE(bp.overtime_amount, 0)) FILTER (WHERE bp.status = 'billed') as total_revenue,
SUM(bp.used_hours * a.internal_cost_rate) as total_cost,
SUM(bp.base_amount + COALESCE(bp.overtime_amount, 0)) FILTER (WHERE bp.status = 'billed') -
SUM(bp.used_hours * a.internal_cost_rate) as total_profit,
MAX(bp.period_end) as last_billing_date
FROM customer_fixed_price_agreements a
LEFT JOIN fixed_price_billing_periods bp ON a.id = bp.agreement_id
GROUP BY a.customer_id, a.customer_name;
COMMENT ON VIEW fixed_price_agreement_performance IS
'Aggregated performance metrics per agreement for reporting';
COMMENT ON VIEW fixed_price_monthly_trends IS
'Month-over-month revenue and profitability trends';
COMMENT ON VIEW fixed_price_customer_summary IS
'Customer-level aggregation of all fixed-price agreements';