-- replace the {start} with the start date of the selected academic year ('YYYY-MM-DD')
-- replace the {stop} with the end date of the selected academic year ('YYYY-MM-DD')
-- replace the {acad_year} with the selected academic year ('YYYY-YYYY')

DROP TABLE IF EXISTS debit_projects;
DROP TABLE IF EXISTS debit_hourly;
DROP TABLE IF EXISTS debit_monthly;
DROP TABLE IF EXISTS debit_summer;
DROP TABLE IF EXISTS credit;

-- Project fees
SELECT customer_id, price AS debit 
	INTO TEMP debit_projects
FROM projects 
	WHERE submission_date IS NOT NULL 
		AND submission_date >= {start}
		AND submission_date <= {stop};

-- Course fees charged hourly
SELECT cust.customer_id, SUM(ROUND(r.duration*(1-s.discount)*lp.price,2)) AS debit
	INTO TEMP debit_hourly
FROM records AS r
LEFT JOIN students AS s ON s.student_id = r.student_id
LEFT JOIN learning_plans AS lp ON lp.plan_id = s.plan_id
LEFT JOIN customers AS cust ON cust.customer_id = s.parent_id
WHERE lp.charge_type='hourly'
	AND r.record_date >= {start}
	AND r.record_date <= {stop}
	AND lp.acad_year = {acad_year}
	AND s.acad_year = {acad_year}
GROUP BY cust.customer_id;

-- Course fees charged monthly
SELECT n_tab.customer_id, SUM(n_tab.months*n_tab.debit) AS debit
	INTO TEMP debit_monthly
FROM
(SELECT cst.customer_id,
CASE
	WHEN s.del_date ISNULL AND s.signup_date <= timestamp {start} + interval '11 weeks' AND CURRENT_DATE <= timestamp {stop}
		THEN EXTRACT(MONTH FROM age(timestamp {start} + interval '9 weeks'))
	WHEN s.del_date ISNULL AND s.signup_date <= timestamp {start} + interval '11 weeks'AND CURRENT_DATE > timestamp {stop}
		THEN EXTRACT(MONTH FROM age(timestamp {stop},timestamp {start} + interval '9 weeks'))
	WHEN s.del_date ISNULL AND s.signup_date > timestamp {start} + interval '11 weeks' AND CURRENT_DATE <= timestamp {stop}
		THEN EXTRACT(MONTH FROM age(date_trunc('month',CURRENT_DATE)+interval '2 weeks',s.signup_date))
	WHEN s.del_date ISNULL AND s.signup_date > timestamp {start} + interval '11 weeks' AND CURRENT_DATE > timestamp {stop}
		THEN EXTRACT(MONTH FROM age(timestamp {stop} - interval '2 weeks',s.signup_date))
	WHEN s.del_date IS NOT NULL 
		THEN EXTRACT(MONTH FROM age(s.del_date, timestamp {start} + interval '9 weeks'))
END AS months,
ROUND(lp.price*(1-s.discount),2) AS debit
FROM students AS s
LEFT JOIN learning_plans AS lp ON lp.plan_id = s.plan_id
LEFT JOIN customers AS cst ON cst.customer_id = s.parent_id
WHERE lp.charge_type = 'monthly'
	AND lp.acad_year = {acad_year}
	AND s.acad_year = {acad_year})
AS n_tab
GROUP BY n_tab.customer_id;

-- Fees from summer courses
SELECT cst.customer_id, ROUND(lp.price*(1-s.discount)*1.5,2) AS debit
	INTO TEMP debit_summer
FROM records AS r
LEFT JOIN students AS s ON s.student_id = r.student_id
LEFT JOIN learning_plans AS lp ON lp.plan_id = s.plan_id
LEFT JOIN customers AS cst ON cst.customer_id = s.parent_id
WHERE lp.charge_type = 'monthly' 
	AND r.record_date >= {start} 
	AND r.record_date <= timestamp {start} + interval '9 weeks'
	AND lp.acad_year = {acad_year}
	AND s.acad_year = {acad_year}
GROUP BY cst.customer_id, debit;

-- Credits
SELECT customer_id, SUM(amount) AS credit
	INTO TEMP credit
FROM income
WHERE paydate >={start} 
	AND paydate <= date_trunc('month',CURRENT_DATE)+interval '1 month'
GROUP BY customer_id;

-- The final table
SELECT customers.customer_name,customers.surname,
 round(raw_balance.debit,1) AS debit, 
 round(raw_balance.credit,1) AS credit, 
 round(raw_balance.debit-raw_balance.credit,1) AS res
 FROM
(SELECT debit.customer_id,
	CASE WHEN debit.debit ISNULL THEN 0.0 ELSE debit.debit END, 
	CASE WHEN credit.credit ISNULL THEN 0.0 ELSE credit.credit END
FROM
(SELECT customer_id, SUM(debit) AS debit FROM(
	SELECT * FROM debit_projects
	UNION SELECT * FROM debit_hourly
	UNION SELECT * FROM debit_monthly
	UNION SELECT * FROM debit_summer) AS union_debit
GROUP BY customer_id) AS debit
LEFT JOIN credit ON credit.customer_id = debit.customer_id)
AS raw_balance
LEFT JOIN customers ON customers.customer_id=raw_balance.customer_id
WHERE raw_balance.debit-raw_balance.credit >= 0
ORDER BY res DESC;
