DROP VIEW IF EXISTS future_transactions;
DROP VIEW IF EXISTS denorm_scheduled_transactions;
DROP VIEW IF EXISTS denorm_transactions;
DROP TABLE IF EXISTS ints;
DROP TABLE IF EXISTS scheduled_subtransactions;
DROP TABLE IF EXISTS scheduled_transactions;
DROP TABLE IF EXISTS subtransactions;
DROP TABLE IF EXISTS transactions;
DROP TABLE IF EXISTS payees;
DROP TABLE IF EXISTS categories_by_month;
DROP TABLE IF EXISTS months;
DROP TABLE IF EXISTS categories;
DROP TABLE IF EXISTS category_groups;
DROP TABLE IF EXISTS accounts;
DROP TYPE IF EXISTS cleared_t;
DROP TYPE IF EXISTS flag_color_t;
DROP TYPE IF EXISTS frequency_t;
CREATE TABLE accounts (
id text PRIMARY KEY,
name text NOT NULL,
on_budget boolean NOT NULL,
closed boolean NOT NULL,
balance bigint NOT NULL,
cleared_balance bigint NOT NULL,
uncleared_balance bigint NOT NULL
);
CREATE TABLE category_groups (
id text PRIMARY KEY,
name text NOT NULL,
hidden boolean NOT NULL
);
CREATE TABLE categories (
id text PRIMARY KEY,
category_group_id text REFERENCES category_groups(id) NOT NULL,
name text NOT NULL,
hidden boolean NOT NULL,
budgeted bigint NOT NULL,
activity bigint NOT NULL,
balance bigint NOT NULL
);
CREATE TABLE months (
month date PRIMARY KEY
);
CREATE TABLE categories_by_month (
month date REFERENCES months(month),
id text REFERENCES categories(id),
category_group_id text REFERENCES category_groups(id) NOT NULL,
name text NOT NULL,
hidden boolean NOT NULL,
budgeted bigint NOT NULL,
activity bigint NOT NULL,
balance bigint NOT NULL,
PRIMARY KEY (month, id)
);
CREATE TABLE payees (
id text PRIMARY KEY,
name text NOT NULL,
transfer_account_id text REFERENCES accounts(id)
);
CREATE TYPE cleared_t AS ENUM ('reconciled', 'cleared', 'uncleared');
CREATE TYPE flag_color_t AS ENUM('red', 'orange', 'yellow', 'green', 'blue', 'purple');
CREATE TABLE transactions (
id text PRIMARY KEY,
date date NOT NULL,
amount bigint NOT NULL,
memo text,
cleared cleared_t NOT NULL,
approved boolean NOT NULL,
flag_color flag_color_t,
account_id text REFERENCES accounts(id) NOT NULL,
payee_id text REFERENCES payees(id),
category_id text REFERENCES categories(id),
transfer_account_id text REFERENCES accounts(id)
);
CREATE TABLE subtransactions (
id text PRIMARY KEY,
transaction_id text REFERENCES transactions(id) NOT NULL,
amount bigint NOT NULL,
memo text,
payee_id text REFERENCES payees(id),
category_id text REFERENCES categories(id),
transfer_account_id text REFERENCES accounts(id)
);
CREATE TYPE frequency_t AS ENUM (
'never',
'daily',
'weekly',
'everyOtherWeek',
'twiceAMonth',
'every4Weeks',
'monthly',
'everyOtherMonth',
'every3Months',
'every4Months',
'twiceAYear',
'yearly',
'everyOtherYear'
);
CREATE TABLE scheduled_transactions (
id text PRIMARY KEY,
date date NOT NULL,
frequency frequency_t NOT NULL,
amount bigint NOT NULL,
memo text,
flag_color flag_color_t,
account_id text REFERENCES accounts(id) NOT NULL,
payee_id text REFERENCES payees(id),
category_id text REFERENCES categories(id),
transfer_account_id text REFERENCES accounts(id)
);
CREATE TABLE scheduled_subtransactions (
id text PRIMARY KEY,
scheduled_transaction_id text REFERENCES scheduled_transactions(id) NOT NULL,
amount bigint NOT NULL,
memo text,
payee_id text REFERENCES payees(id),
category_id text REFERENCES categories(id),
transfer_account_id text REFERENCES accounts(id)
);
CREATE TABLE ints (
i integer PRIMARY KEY
);
CREATE VIEW denorm_transactions AS (
WITH
transactions_with_subtransactions AS (
SELECT
transactions.id,
subtransactions.id AS subtransaction_id,
transactions.date,
coalesce(subtransactions.amount, transactions.amount) AS amount,
coalesce(subtransactions.memo, transactions.memo) AS memo,
transactions.cleared,
transactions.approved,
transactions.flag_color,
transactions.account_id,
coalesce(subtransactions.payee_id, transactions.payee_id) AS payee_id,
coalesce(subtransactions.category_id, transactions.category_id) AS category_id,
coalesce(subtransactions.transfer_account_id, transactions.transfer_account_id) AS transfer_account_id
FROM
transactions LEFT JOIN subtransactions ON (
transactions.id = subtransactions.transaction_id
)
)
SELECT
transactions_with_subtransactions.id,
subtransaction_id,
date,
amount / 1000.0 as amount,
memo,
cleared,
approved,
flag_color,
account_id,
accounts.name AS account,
payee_id,
payees.name AS payee,
category_group_id,
category_groups.name AS category_group,
category_id,
categories.name AS category,
transactions_with_subtransactions.transfer_account_id,
transfer_accounts.name AS transfer_account
FROM
transactions_with_subtransactions LEFT JOIN accounts ON (
transactions_with_subtransactions.account_id = accounts.id
) LEFT JOIN payees ON (
transactions_with_subtransactions.payee_id = payees.id
) LEFT JOIN categories ON (
transactions_with_subtransactions.category_id = categories.id
) LEFT JOIN category_groups ON (
categories.category_group_id = category_groups.id
) LEFT JOIN accounts transfer_accounts ON (
transactions_with_subtransactions.transfer_account_id = transfer_accounts.id
)
);
CREATE VIEW denorm_scheduled_transactions AS (
WITH
scheduled_transactions_with_subtransactions AS (
SELECT
scheduled_transactions.id,
scheduled_subtransactions.id AS scheduled_subtransaction_id,
scheduled_transactions.date,
scheduled_transactions.frequency,
coalesce(scheduled_subtransactions.amount, scheduled_transactions.amount) AS amount,
coalesce(scheduled_subtransactions.memo, scheduled_transactions.memo) AS memo,
scheduled_transactions.flag_color,
scheduled_transactions.account_id,
coalesce(scheduled_subtransactions.payee_id, scheduled_transactions.payee_id) AS payee_id,
coalesce(scheduled_subtransactions.category_id, scheduled_transactions.category_id) AS category_id,
coalesce(scheduled_subtransactions.transfer_account_id, scheduled_transactions.transfer_account_id) AS transfer_account_id
FROM
scheduled_transactions LEFT JOIN scheduled_subtransactions ON (
scheduled_transactions.id = scheduled_subtransactions.scheduled_transaction_id
)
)
SELECT
scheduled_transactions_with_subtransactions.id,
scheduled_subtransaction_id,
date,
frequency,
amount / 1000.0 as amount,
memo,
flag_color,
account_id,
accounts.name AS account,
payee_id,
payees.name AS payee,
category_group_id,
category_groups.name AS category_group,
category_id,
categories.name AS category,
scheduled_transactions_with_subtransactions.transfer_account_id,
transfer_accounts.name AS transfer_account
FROM
scheduled_transactions_with_subtransactions LEFT JOIN accounts ON (
scheduled_transactions_with_subtransactions.account_id = accounts.id
) LEFT JOIN payees ON (
scheduled_transactions_with_subtransactions.payee_id = payees.id
) LEFT JOIN categories ON (
scheduled_transactions_with_subtransactions.category_id = categories.id
) LEFT JOIN category_groups ON (
categories.category_group_id = category_groups.id
) LEFT JOIN accounts transfer_accounts ON (
scheduled_transactions_with_subtransactions.transfer_account_id = transfer_accounts.id
)
);
CREATE VIEW future_transactions AS (
WITH
daily AS (
SELECT
'daily'::frequency_t AS frequency,
(ints.i - 1) * interval '1 day' AS span
FROM
ints
WHERE
ints.i <= 750
),
weekly AS (
SELECT
'weekly'::frequency_t AS frequency,
(ints.i - 1) * interval '1 week' AS span
FROM
ints
WHERE
ints.i <= 120
),
every_other_week AS (
SELECT
'everyOtherWeek'::frequency_t AS frequency,
(ints.i - 1) * interval '2 weeks' AS span
FROM
ints
WHERE
ints.i <= 60
),
twice_a_month AS (
SELECT
'twiceAMonth'::frequency_t AS frequency,
make_interval(months => a.i, days => b.i) AS span
FROM
ints a CROSS JOIN ints b
WHERE
a.i <= 30 and (b.i = 0 or b.i = 15)
),
every_four_weeks AS (
SELECT
'every4Weeks'::frequency_t AS frequency,
(ints.i - 1) * interval '4 weeks' AS span
FROM
ints
WHERE
ints.i <= 30
),
monthly AS (
SELECT
'monthly'::frequency_t AS frequency,
(ints.i - 1) * interval '1 month' AS span
FROM
ints
WHERE
ints.i <= 30
),
every_other_month AS (
SELECT
'everyOtherMonth'::frequency_t AS frequency,
(ints.i - 1) * interval '2 months' AS span
FROM
ints
WHERE
ints.i <= 15
),
every_three_months AS (
SELECT
'every3Months'::frequency_t AS frequency,
(ints.i - 1) * interval '3 months' AS span
FROM
ints
WHERE
ints.i <= 10
),
every_four_months AS (
SELECT
'every4Months'::frequency_t AS frequency,
(ints.i - 1) * interval '4 months' AS span
FROM
ints
WHERE
ints.i <= 10
),
twice_a_year AS (
SELECT
'twiceAYear'::frequency_t AS frequency,
(ints.i - 1) * interval '6 months' AS span
FROM
ints
WHERE
ints.i <= 5
),
yearly AS (
SELECT
'yearly'::frequency_t AS frequency,
(ints.i - 1) * interval '1 year' AS span
FROM
ints
WHERE
ints.i <= 5
),
every_other_year AS (
SELECT
'everyOtherYear'::frequency_t AS frequency,
(ints.i - 1) * interval '2 years' AS span
FROM
ints
WHERE
ints.i <= 5
),
repeated_transactions AS (
SELECT
id,
scheduled_subtransaction_id,
CASE
WHEN frequency = 'never' THEN
date
WHEN frequency = 'daily' THEN
date + daily.span
WHEN frequency = 'weekly' THEN
date + weekly.span
WHEN frequency = 'everyOtherWeek' THEN
date + every_other_week.span
WHEN frequency = 'twiceAMonth' THEN
date + twice_a_month.span
WHEN frequency = 'every4Weeks' THEN
date + every_four_weeks.span
WHEN frequency = 'monthly' THEN
date + monthly.span
WHEN frequency = 'everyOtherMonth' THEN
date + every_other_month.span
WHEN frequency = 'every3Months' THEN
date + every_three_months.span
WHEN frequency = 'every4Months' THEN
date + every_four_months.span
WHEN frequency = 'twiceAYear' THEN
date + twice_a_year.span
WHEN frequency = 'yearly' THEN
date + yearly.span
WHEN frequency = 'everyOtherYear' THEN
date + every_other_year.span
ELSE
NULL
END AS date,
frequency,
amount,
memo,
flag_color,
account_id,
account,
payee_id,
payee,
category_group_id,
category_group,
category_id,
category,
transfer_account_id,
transfer_account
FROM
denorm_scheduled_transactions
LEFT JOIN daily USING (frequency)
LEFT JOIN weekly USING (frequency)
LEFT JOIN every_other_week USING (frequency)
LEFT JOIN twice_a_month USING (frequency)
LEFT JOIN every_four_weeks USING (frequency)
LEFT JOIN monthly USING (frequency)
LEFT JOIN every_other_month USING (frequency)
LEFT JOIN every_three_months USING (frequency)
LEFT JOIN every_four_months USING (frequency)
LEFT JOIN twice_a_year USING (frequency)
LEFT JOIN yearly USING (frequency)
LEFT JOIN every_other_year USING (frequency)
)
SELECT
id,
scheduled_subtransaction_id,
date,
frequency,
amount,
memo,
flag_color,
account_id,
account,
payee_id,
payee,
category_group_id,
category_group,
category_id,
category,
transfer_account_id,
transfer_account
FROM
repeated_transactions
WHERE
date <= CURRENT_DATE + interval '2 years'
);