Compare commits
No commits in common. "master" and "v0.2" have entirely different histories.
2 changed files with 9 additions and 323 deletions
19
0PLAN.org
19
0PLAN.org
|
@ -2,6 +2,15 @@
|
||||||
|
|
||||||
* Plan
|
* Plan
|
||||||
|
|
||||||
|
** 0.2
|
||||||
|
|
||||||
|
- [X] use localStorage to store user
|
||||||
|
- [X] add barcode scanner to get the user
|
||||||
|
- [X] allow editing
|
||||||
|
- [X] add UserSelect component
|
||||||
|
- [X] integrate script for starting build qemu system
|
||||||
|
- [X] add org file to the repository after cleanup
|
||||||
|
|
||||||
** 0.3
|
** 0.3
|
||||||
|
|
||||||
- [ ] versioned schema support
|
- [ ] versioned schema support
|
||||||
|
@ -9,7 +18,6 @@
|
||||||
- [ ] function to check
|
- [ ] function to check
|
||||||
- [ ] function to set
|
- [ ] function to set
|
||||||
- [ ] initial creation of tables at version 1 assuming OK if tables exist
|
- [ ] initial creation of tables at version 1 assuming OK if tables exist
|
||||||
- [ ] users import from hackerbase
|
|
||||||
|
|
||||||
** 0.4
|
** 0.4
|
||||||
|
|
||||||
|
@ -49,15 +57,6 @@
|
||||||
- [X] separate module brmbar-data for queries
|
- [X] separate module brmbar-data for queries
|
||||||
- [X] separate module api-servlets
|
- [X] separate module api-servlets
|
||||||
|
|
||||||
** 0.2
|
|
||||||
|
|
||||||
- [X] use localStorage to store user
|
|
||||||
- [X] add barcode scanner to get the user
|
|
||||||
- [X] allow editing
|
|
||||||
- [X] add UserSelect component
|
|
||||||
- [X] integrate script for starting build qemu system
|
|
||||||
- [X] add org file to the repository after cleanup
|
|
||||||
|
|
||||||
* Qemu
|
* Qemu
|
||||||
|
|
||||||
#+BEGIN_SRC
|
#+BEGIN_SRC
|
||||||
|
|
|
@ -1,313 +0,0 @@
|
||||||
--
|
|
||||||
-- 0000-init.sql
|
|
||||||
--
|
|
||||||
-- Initial SQL schema construction as of 2025-04-20 (or so)
|
|
||||||
--
|
|
||||||
-- ISC License
|
|
||||||
--
|
|
||||||
-- Copyright 2023-2025 Brmlab, z.s.
|
|
||||||
-- Dominik Pantůček <dominik.pantucek@trustica.cz>
|
|
||||||
--
|
|
||||||
-- Permission to use, copy, modify, and/or distribute this software
|
|
||||||
-- for any purpose with or without fee is hereby granted, provided
|
|
||||||
-- that the above copyright notice and this permission notice appear
|
|
||||||
-- in all copies.
|
|
||||||
--
|
|
||||||
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
|
||||||
-- WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
|
||||||
-- WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
|
||||||
-- AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
|
|
||||||
-- CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
|
||||||
-- OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
-- NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
|
||||||
-- CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
--
|
|
||||||
|
|
||||||
-- To require fully-qualified names
|
|
||||||
SELECT pg_catalog.set_config('search_path', '', false);
|
|
||||||
|
|
||||||
-- Privileged schema with protected data
|
|
||||||
CREATE SCHEMA IF NOT EXISTS brmbar_privileged;
|
|
||||||
|
|
||||||
-- Initial versioning
|
|
||||||
CREATE TABLE IF NOT EXISTS brmbar_privileged.brmbar_schema(
|
|
||||||
ver INTEGER NOT NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
-- ----------------------------------------------------------------
|
|
||||||
-- Legacy Schema Initialization
|
|
||||||
-- ----------------------------------------------------------------
|
|
||||||
|
|
||||||
DO $$
|
|
||||||
DECLARE v INTEGER;
|
|
||||||
BEGIN
|
|
||||||
SELECT ver FROM brmbar_privileged.brmbar_schema INTO v;
|
|
||||||
IF v IS NULL THEN
|
|
||||||
-- --------------------------------
|
|
||||||
-- Legacy Types
|
|
||||||
|
|
||||||
SELECT COUNT(*) INTO v
|
|
||||||
FROM pg_catalog.pg_type typ
|
|
||||||
INNER JOIN pg_catalog.pg_namespace nsp
|
|
||||||
ON nsp.oid = typ.typnamespace
|
|
||||||
WHERE nsp.nspname = 'public'
|
|
||||||
AND typ.typname='exchange_rate_direction';
|
|
||||||
IF v=0 THEN
|
|
||||||
RAISE NOTICE 'Creating type exchange_rate_direction';
|
|
||||||
CREATE TYPE public.exchange_rate_direction
|
|
||||||
AS ENUM ('source_to_target', 'target_to_source');
|
|
||||||
ELSE
|
|
||||||
RAISE NOTICE 'Type exchange_rate_direction already exists';
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
SELECT COUNT(*) INTO v
|
|
||||||
FROM pg_catalog.pg_type typ
|
|
||||||
INNER JOIN pg_catalog.pg_namespace nsp
|
|
||||||
ON nsp.oid = typ.typnamespace
|
|
||||||
WHERE nsp.nspname = 'public'
|
|
||||||
AND typ.typname='account_type';
|
|
||||||
IF v=0 THEN
|
|
||||||
RAISE NOTICE 'Creating type account_type';
|
|
||||||
CREATE TYPE public.account_type
|
|
||||||
AS ENUM ('cash', 'debt', 'inventory', 'income', 'expense',
|
|
||||||
'starting_balance', 'ending_balance');
|
|
||||||
ELSE
|
|
||||||
RAISE NOTICE 'Type account_type already exists';
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
SELECT COUNT(*) INTO v
|
|
||||||
FROM pg_catalog.pg_type typ
|
|
||||||
INNER JOIN pg_catalog.pg_namespace nsp
|
|
||||||
ON nsp.oid = typ.typnamespace
|
|
||||||
WHERE nsp.nspname = 'public'
|
|
||||||
AND typ.typname='transaction_split_side';
|
|
||||||
IF v=0 THEN
|
|
||||||
RAISE NOTICE 'Creating type transaction_split_side';
|
|
||||||
CREATE TYPE public.transaction_split_side
|
|
||||||
AS ENUM ('credit', 'debit');
|
|
||||||
ELSE
|
|
||||||
RAISE NOTICE 'Type transaction_split_side already exists';
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
-- --------------------------------
|
|
||||||
-- Currencies sequence, table and potential initial data
|
|
||||||
|
|
||||||
CREATE SEQUENCE IF NOT EXISTS public.currencies_id_seq
|
|
||||||
START WITH 2 INCREMENT BY 1;
|
|
||||||
CREATE TABLE IF NOT EXISTS public.currencies (
|
|
||||||
id INTEGER PRIMARY KEY NOT NULL DEFAULT NEXTVAL('public.currencies_id_seq'::regclass),
|
|
||||||
name VARCHAR(128) NOT NULL,
|
|
||||||
UNIQUE(name)
|
|
||||||
);
|
|
||||||
INSERT INTO public.currencies (id, name) VALUES (1, 'Kč')
|
|
||||||
ON CONFLICT DO NOTHING;
|
|
||||||
|
|
||||||
-- --------------------------------
|
|
||||||
-- Exchange rates table - no initial data required
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS public.exchange_rates (
|
|
||||||
valid_since TIMESTAMP WITHOUT TIME ZONE DEFAULT NOW() NOT NULL,
|
|
||||||
|
|
||||||
target INTEGER NOT NULL,
|
|
||||||
FOREIGN KEY (target) REFERENCES public.currencies (id),
|
|
||||||
|
|
||||||
source INTEGER NOT NULL,
|
|
||||||
FOREIGN KEY (source) REFERENCES public.currencies (id),
|
|
||||||
|
|
||||||
rate DECIMAL(12,2) NOT NULL,
|
|
||||||
rate_dir public.exchange_rate_direction NOT NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
-- --------------------------------
|
|
||||||
-- Accounts sequence and table and 4 initial accounts
|
|
||||||
|
|
||||||
CREATE SEQUENCE IF NOT EXISTS public.accounts_id_seq
|
|
||||||
START WITH 2 INCREMENT BY 1;
|
|
||||||
CREATE TABLE IF NOT EXISTS public.accounts (
|
|
||||||
id INTEGER PRIMARY KEY NOT NULL DEFAULT NEXTVAL('public.accounts_id_seq'::regclass),
|
|
||||||
|
|
||||||
name VARCHAR(128) NOT NULL,
|
|
||||||
UNIQUE (name),
|
|
||||||
|
|
||||||
currency INTEGER NOT NULL,
|
|
||||||
FOREIGN KEY (currency) REFERENCES public.currencies (id),
|
|
||||||
|
|
||||||
acctype public.account_type NOT NULL,
|
|
||||||
|
|
||||||
active BOOLEAN NOT NULL DEFAULT TRUE
|
|
||||||
);
|
|
||||||
INSERT INTO public.accounts (id, name, currency, acctype)
|
|
||||||
VALUES (1, 'BrmBar Cash', (SELECT id FROM public.currencies WHERE name='Kč'), 'cash')
|
|
||||||
ON CONFLICT DO NOTHING;
|
|
||||||
INSERT INTO public.accounts (name, currency, acctype)
|
|
||||||
VALUES ('BrmBar Profits', (SELECT id FROM public.currencies WHERE name='Kč'), 'income')
|
|
||||||
ON CONFLICT DO NOTHING;
|
|
||||||
INSERT INTO public.accounts (name, currency, acctype)
|
|
||||||
VALUES ('BrmBar Excess', (SELECT id FROM public.currencies WHERE name='Kč'), 'income')
|
|
||||||
ON CONFLICT DO NOTHING;
|
|
||||||
INSERT INTO public.accounts (name, currency, acctype)
|
|
||||||
VALUES ('BrmBar Deficit', (SELECT id FROM public.currencies WHERE name='Kč'), 'expense')
|
|
||||||
ON CONFLICT DO NOTHING;
|
|
||||||
|
|
||||||
-- --------------------------------
|
|
||||||
-- Barcodes
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS public.barcodes (
|
|
||||||
barcode VARCHAR(128) PRIMARY KEY NOT NULL,
|
|
||||||
|
|
||||||
account INTEGER NOT NULL,
|
|
||||||
FOREIGN KEY (account) REFERENCES public.accounts (id)
|
|
||||||
);
|
|
||||||
INSERT INTO public.barcodes (barcode, account)
|
|
||||||
VALUES ('_cash_', (SELECT id FROM public.accounts WHERE acctype = 'cash'))
|
|
||||||
ON CONFLICT DO NOTHING;
|
|
||||||
|
|
||||||
-- --------------------------------
|
|
||||||
-- Transactions
|
|
||||||
|
|
||||||
CREATE SEQUENCE IF NOT EXISTS public.transactions_id_seq
|
|
||||||
START WITH 1 INCREMENT BY 1;
|
|
||||||
CREATE TABLE IF NOT EXISTS public.transactions (
|
|
||||||
id INTEGER PRIMARY KEY NOT NULL DEFAULT NEXTVAL('public.transactions_id_seq'::regclass),
|
|
||||||
time TIMESTAMP DEFAULT NOW() NOT NULL,
|
|
||||||
|
|
||||||
responsible INTEGER,
|
|
||||||
FOREIGN KEY (responsible) REFERENCES public.accounts (id),
|
|
||||||
|
|
||||||
description TEXT
|
|
||||||
);
|
|
||||||
|
|
||||||
-- --------------------------------
|
|
||||||
-- Transaction splits
|
|
||||||
|
|
||||||
CREATE SEQUENCE IF NOT EXISTS public.transaction_splits_id_seq
|
|
||||||
START WITH 1 INCREMENT BY 1;
|
|
||||||
CREATE TABLE IF NOT EXISTS public.transaction_splits (
|
|
||||||
id INTEGER PRIMARY KEY NOT NULL DEFAULT NEXTVAL('public.transaction_splits_id_seq'::regclass),
|
|
||||||
|
|
||||||
transaction INTEGER NOT NULL,
|
|
||||||
FOREIGN KEY (transaction) REFERENCES public.transactions (id),
|
|
||||||
|
|
||||||
side public.transaction_split_side NOT NULL,
|
|
||||||
|
|
||||||
account INTEGER NOT NULL,
|
|
||||||
FOREIGN KEY (account) REFERENCES public.accounts (id),
|
|
||||||
amount DECIMAL(12,2) NOT NULL,
|
|
||||||
|
|
||||||
memo TEXT
|
|
||||||
);
|
|
||||||
|
|
||||||
-- --------------------------------
|
|
||||||
-- Account balances view
|
|
||||||
|
|
||||||
CREATE OR REPLACE VIEW public.account_balances AS
|
|
||||||
SELECT ts.account AS id,
|
|
||||||
accounts.name,
|
|
||||||
accounts.acctype,
|
|
||||||
- sum(
|
|
||||||
CASE
|
|
||||||
WHEN ts.side = 'credit'::public.transaction_split_side THEN - ts.amount
|
|
||||||
ELSE ts.amount
|
|
||||||
END) AS crbalance
|
|
||||||
FROM public.transaction_splits ts
|
|
||||||
LEFT JOIN public.accounts ON accounts.id = ts.account
|
|
||||||
GROUP BY ts.account, accounts.name, accounts.acctype
|
|
||||||
ORDER BY (- sum(
|
|
||||||
CASE
|
|
||||||
WHEN ts.side = 'credit'::public.transaction_split_side THEN - ts.amount
|
|
||||||
ELSE ts.amount
|
|
||||||
END));
|
|
||||||
|
|
||||||
-- --------------------------------
|
|
||||||
-- Transaction nice splits view
|
|
||||||
|
|
||||||
CREATE OR REPLACE VIEW public.transaction_nicesplits AS
|
|
||||||
SELECT ts.id,
|
|
||||||
ts.transaction,
|
|
||||||
ts.account,
|
|
||||||
CASE
|
|
||||||
WHEN ts.side = 'credit'::public.transaction_split_side THEN - ts.amount
|
|
||||||
ELSE ts.amount
|
|
||||||
END AS amount,
|
|
||||||
a.currency,
|
|
||||||
ts.memo
|
|
||||||
FROM public.transaction_splits ts
|
|
||||||
LEFT JOIN public.accounts a ON a.id = ts.account
|
|
||||||
ORDER BY ts.id;
|
|
||||||
|
|
||||||
-- --------------------------------
|
|
||||||
-- Transaction cash sums view
|
|
||||||
|
|
||||||
CREATE OR REPLACE VIEW public.transaction_cashsums AS
|
|
||||||
SELECT t.id,
|
|
||||||
t."time",
|
|
||||||
sum(credit.credit_cash) AS cash_credit,
|
|
||||||
sum(debit.debit_cash) AS cash_debit,
|
|
||||||
a.name AS responsible,
|
|
||||||
t.description
|
|
||||||
FROM public.transactions t
|
|
||||||
LEFT JOIN ( SELECT cts.amount AS credit_cash,
|
|
||||||
cts.transaction AS cts_t
|
|
||||||
FROM public.transaction_nicesplits cts
|
|
||||||
LEFT JOIN public.accounts a_1 ON a_1.id = cts.account OR a_1.id = cts.account
|
|
||||||
WHERE a_1.currency = (( SELECT accounts.currency
|
|
||||||
FROM public.accounts
|
|
||||||
WHERE accounts.name::text = 'BrmBar Cash'::text))
|
|
||||||
AND (a_1.acctype = ANY (ARRAY['cash'::public.account_type, 'debt'::public.account_type]))
|
|
||||||
AND cts.amount < 0::numeric) credit ON credit.cts_t = t.id
|
|
||||||
LEFT JOIN ( SELECT dts.amount AS debit_cash,
|
|
||||||
dts.transaction AS dts_t
|
|
||||||
FROM public.transaction_nicesplits dts
|
|
||||||
LEFT JOIN public.accounts a_1 ON a_1.id = dts.account OR a_1.id = dts.account
|
|
||||||
WHERE a_1.currency = (( SELECT accounts.currency
|
|
||||||
FROM public.accounts
|
|
||||||
WHERE accounts.name::text = 'BrmBar Cash'::text))
|
|
||||||
AND (a_1.acctype = ANY (ARRAY['cash'::public.account_type, 'debt'::public.account_type]))
|
|
||||||
AND dts.amount > 0::numeric) debit ON debit.dts_t = t.id
|
|
||||||
LEFT JOIN public.accounts a ON a.id = t.responsible
|
|
||||||
GROUP BY t.id, a.name
|
|
||||||
ORDER BY t.id DESC;
|
|
||||||
|
|
||||||
-- --------------------------------
|
|
||||||
-- Function to check schema version (used in migrations)
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION brmbar_privileged.has_exact_schema_version(
|
|
||||||
IN i_ver INTEGER
|
|
||||||
) RETURNS INTEGER
|
|
||||||
VOLATILE NOT LEAKPROOF LANGUAGE plpgsql AS $x$
|
|
||||||
DECLARE
|
|
||||||
v_ver INTEGER;
|
|
||||||
BEGIN
|
|
||||||
SELECT ver INTO v_ver FROM brmbar_privileged.brmbar_schema;
|
|
||||||
IF v_ver is NULL THEN
|
|
||||||
RETURN false;
|
|
||||||
ELSE
|
|
||||||
RETURN v_ver = i_ver;
|
|
||||||
END IF;
|
|
||||||
END;
|
|
||||||
$x$;
|
|
||||||
|
|
||||||
-- --------------------------------
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION brmbar_privileged.upgrade_schema_version_to(
|
|
||||||
IN i_ver INTEGER
|
|
||||||
) RETURNS INTEGER
|
|
||||||
VOLATILE NOT LEAKPROOF LANGUAGE plpgsql AS $x$
|
|
||||||
DECLARE
|
|
||||||
v_ver INTEGER;
|
|
||||||
BEGIN
|
|
||||||
SELECT ver FROM brmbar_privileged.brmbar_schema INTO v_ver;
|
|
||||||
IF v_ver=(i_ver-1) THEN
|
|
||||||
UPDATE brmbar_privileged.brmbar_schema SET ver = i_ver;
|
|
||||||
ELSE
|
|
||||||
RAISE EXCEPTION 'Invalid brmbar schema version transition (% -> %)', v_ver, i_ver;
|
|
||||||
END IF;
|
|
||||||
END;
|
|
||||||
$x$;
|
|
||||||
|
|
||||||
-- Initialize version 1
|
|
||||||
INSERT INTO brmbar_privileged.brmbar_schema(ver) VALUES(1);
|
|
||||||
END IF;
|
|
||||||
END;
|
|
||||||
$$;
|
|
Loading…
Add table
Add a link
Reference in a new issue