forked from sbms4d/wasb_sql_test
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgenerate_supplier_payment_plans.sql
More file actions
70 lines (67 loc) · 2.61 KB
/
generate_supplier_payment_plans.sql
File metadata and controls
70 lines (67 loc) · 2.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
USE memory.default
------------------------------
/*
This SQL file displays payment plans for each of the suppliers. It consists of three
CTEs.
supplier_invoice finds the latest due date per supplier and calculates the sum of all
invoices for each of them.
monthly_payment_amount calculates number of monthly payments remaining based off the
latest due date. It also calculates monthly payment amount and the last month amount
(monthly payment plus the remainder).
balance generates a sequence (extra rows) for each of the months we have until due
date to cover our expenses. It also displays balance left for each month.
The query was formatted using https://poorsql.com/ formatter.
*/
------------------------------
WITH supplier_invoice
AS (
SELECT s.supplier_id
,s.name AS supplier_name
,SUM(i.invoice_amount) AS total_invoice_amount
,MAX(i.due_date) latest_due_date
FROM INVOICE i
LEFT JOIN SUPPLIER s ON i.supplier_id = s.supplier_id
GROUP BY s.supplier_id
,s.name
),
monthly_payment_amount
AS (
SELECT supplier_id
,supplier_name
,total_invoice_amount
,latest_due_date
,DATE_DIFF('month', CURRENT_DATE, latest_due_date) + 1 AS number_of_payments -- added +1 because we want to start payments at the end of the current month, this creates that extra month for payment
,FLOOR(total_invoice_amount / (DATE_DIFF('month', CURRENT_DATE, latest_due_date) + 1)) AS monthly_amount -- total amount divided by number of months to pay rounded to nearest integer
,total_invoice_amount % (DATE_DIFF('month', CURRENT_DATE, latest_due_date) + 1) AS last_month_remainder -- remainder from the monthly amount, to be added for the last month of payment
FROM supplier_invoice
),
balance
AS (
SELECT supplier_id
,supplier_name
,CASE
WHEN seq < number_of_payments - 1
THEN monthly_amount
ELSE last_month_remainder + monthly_amount
END AS payment_amount -- these are monthly payments which are all the same except last one that includes the remainder
,seq
,total_invoice_amount - sum(CASE
WHEN seq < number_of_payments - 1
THEN monthly_amount
ELSE last_month_remainder + monthly_amount
END) OVER (
PARTITION BY supplier_id ORDER BY seq
) AS balance_outstanding -- calculates the balance remaining
,
LAST_DAY_OF_MONTH(date_add('month', seq, CURRENT_DATE)) AS payment_date
FROM monthly_payment_amount
CROSS JOIN UNNEST(sequence(0, number_of_payments - 1)) AS t(seq) -- generating a sequence of months for each supplier based on the latest due date
)
SELECT supplier_id
,supplier_name
,payment_amount
,balance_outstanding
,payment_date
FROM balance
ORDER BY supplier_id
,payment_date;