Vermietungs-Tool
A local web app for a small room-rental business in Austria: guest register, room ledger, occupancy plan, invoices, the monthly tourist-tax report and the quarterly VAT list. Application code only; it ships no data. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
commit
45424e6fd6
47 files changed
+6701
No files matched your search
@@ -0,0 +1,180 @@
|
||||
-- 001 schema.
|
||||
-- * text is COLLATE "C" (byte order), dates are ISO text, money is double precision
|
||||
-- * every foreign key is DEFERRABLE (INITIALLY IMMEDIATE): company and client point at each other
|
||||
|
||||
CREATE TABLE unit (
|
||||
id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
code text COLLATE "C" NOT NULL UNIQUE, -- short code shown in the lists
|
||||
name text COLLATE "C" NOT NULL,
|
||||
subtitle text COLLATE "C",
|
||||
address text COLLATE "C", -- multi-line issuer address block
|
||||
place text COLLATE "C", -- where invoices are issued ('<place>, am <date>')
|
||||
contact text COLLATE "C", -- multi-line contact block of the invoice footer
|
||||
bank text COLLATE "C",
|
||||
iban text COLLATE "C",
|
||||
uid text COLLATE "C",
|
||||
tvb_number text COLLATE "C", -- Betriebsnummer for the tourist-tax report
|
||||
invoice_prefix text COLLATE "C", -- '2026-' | '26-': the year is kept current
|
||||
logo text COLLATE "C", -- file in app/static/invoice/, nullable
|
||||
photo text COLLATE "C",
|
||||
theme text COLLATE "C", -- 'green' | 'blue'
|
||||
is_current integer NOT NULL DEFAULT 1,
|
||||
succeeded_by_id bigint REFERENCES unit(id) DEFERRABLE -- a former operator reports under its successor
|
||||
);
|
||||
|
||||
CREATE TABLE room (
|
||||
id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
number text COLLATE "C" NOT NULL UNIQUE, -- floor-coded, e.g. '21'
|
||||
category text COLLATE "C", -- EZ | DZ | 3BZ | 4BZ | Garconniere
|
||||
capacity integer,
|
||||
unit_id bigint REFERENCES unit(id) DEFERRABLE, -- current owner
|
||||
long_term integer NOT NULL DEFAULT 0, -- let long-term, left out of the free-bed count
|
||||
floor text COLLATE "C"
|
||||
);
|
||||
|
||||
CREATE TABLE company (
|
||||
id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
name text COLLATE "C" NOT NULL, -- canonical display name
|
||||
kind text COLLATE "C" NOT NULL DEFAULT 'company', -- company | private
|
||||
uid text COLLATE "C",
|
||||
email text COLLATE "C",
|
||||
phone text COLLATE "C",
|
||||
notes text COLLATE "C",
|
||||
current_client_id bigint -- the address version used for NEW invoices
|
||||
);
|
||||
|
||||
CREATE TABLE client (
|
||||
id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
kind text COLLATE "C" NOT NULL DEFAULT 'company', -- company | private
|
||||
name text COLLATE "C" NOT NULL,
|
||||
address text COLLATE "C",
|
||||
postcode text COLLATE "C",
|
||||
city text COLLATE "C",
|
||||
country text COLLATE "C",
|
||||
company_id bigint REFERENCES company(id) DEFERRABLE
|
||||
);
|
||||
ALTER TABLE company ADD FOREIGN KEY (current_client_id) REFERENCES client(id) DEFERRABLE;
|
||||
|
||||
CREATE TABLE company_key (
|
||||
key text COLLATE "C" PRIMARY KEY, -- normalize.company_key(spelling)
|
||||
company_id bigint NOT NULL REFERENCES company(id) DEFERRABLE
|
||||
);
|
||||
|
||||
CREATE TABLE dismissed_finding (
|
||||
kind text COLLATE "C" NOT NULL,
|
||||
key text COLLATE "C" NOT NULL,
|
||||
note text COLLATE "C",
|
||||
PRIMARY KEY (kind, key)
|
||||
);
|
||||
|
||||
CREATE TABLE guest (
|
||||
id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
last_name text COLLATE "C",
|
||||
first_name text COLLATE "C",
|
||||
birth_date text COLLATE "C", -- ISO yyyy-mm-dd
|
||||
nationality text COLLATE "C",
|
||||
doc_type text COLLATE "C",
|
||||
doc_number text COLLATE "C",
|
||||
profession text COLLATE "C",
|
||||
home_street text COLLATE "C",
|
||||
home_postcode text COLLATE "C",
|
||||
home_city text COLLATE "C",
|
||||
home_country text COLLATE "C",
|
||||
phone text COLLATE "C"
|
||||
);
|
||||
|
||||
CREATE TABLE invoice (
|
||||
id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
unit_id bigint REFERENCES unit(id) DEFERRABLE,
|
||||
client_id bigint REFERENCES client(id) DEFERRABLE,
|
||||
number text COLLATE "C", -- '2026-01'
|
||||
date text COLLATE "C",
|
||||
paid_date text COLLATE "C",
|
||||
payment_method text COLLATE "C",
|
||||
notes text COLLATE "C",
|
||||
lines_stale integer NOT NULL DEFAULT 0
|
||||
);
|
||||
|
||||
-- One table for three kinds of rows, told apart by source_sheet: 'guestsheet' (a Gästeblatt in the guest
|
||||
-- register), 'ledger' (a Zimmerbelegung row; its dates live on the charge) and 'invoice' (an invoice line).
|
||||
CREATE TABLE stay (
|
||||
id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
guest_id bigint REFERENCES guest(id) DEFERRABLE, -- null for ledger and invoice rows
|
||||
room_id bigint REFERENCES room(id) DEFERRABLE,
|
||||
unit_id bigint REFERENCES unit(id) DEFERRABLE, -- the operator at the time
|
||||
employer_client_id bigint REFERENCES client(id) DEFERRABLE,
|
||||
arrival text COLLATE "C",
|
||||
departure text COLLATE "C",
|
||||
sheet_number text COLLATE "C",
|
||||
label text COLLATE "C", -- occupant text when guest_id is null
|
||||
notes text COLLATE "C",
|
||||
source_sheet text COLLATE "C", -- guestsheet | ledger | invoice
|
||||
hauptwohnsitz integer,
|
||||
tourism_liable integer
|
||||
);
|
||||
|
||||
CREATE TABLE charge (
|
||||
id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
stay_id bigint REFERENCES stay(id) DEFERRABLE,
|
||||
invoice_id bigint REFERENCES invoice(id) DEFERRABLE,
|
||||
period_from text COLLATE "C",
|
||||
period_to text COLLATE "C",
|
||||
quantity double precision,
|
||||
unit_type text COLLATE "C", -- week | day | night | month
|
||||
gross_per_unit double precision,
|
||||
line_net_override double precision, -- null => computed
|
||||
source_sheet text COLLATE "C",
|
||||
persons numeric,
|
||||
paid_date text COLLATE "C",
|
||||
paid_status text COLLATE "C",
|
||||
tourism_tax double precision,
|
||||
art text COLLATE "C",
|
||||
gb_ref text COLLATE "C",
|
||||
vat_rate double precision NOT NULL DEFAULT 0.10,
|
||||
kind text COLLATE "C" NOT NULL DEFAULT 'stay',
|
||||
description text COLLATE "C",
|
||||
rnr text COLLATE "C",
|
||||
payer text COLLATE "C",
|
||||
notes text COLLATE "C"
|
||||
);
|
||||
|
||||
CREATE TABLE payment (
|
||||
id bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
charge_id bigint NOT NULL REFERENCES charge(id) ON DELETE CASCADE DEFERRABLE,
|
||||
paid_date text COLLATE "C" NOT NULL,
|
||||
amount double precision NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX idx_charge_invoice ON charge(invoice_id);
|
||||
CREATE INDEX idx_charge_stay ON charge(stay_id);
|
||||
CREATE INDEX idx_client_company ON client(company_id);
|
||||
CREATE INDEX idx_stay_guest ON stay(guest_id);
|
||||
CREATE INDEX idx_stay_room ON stay(room_id);
|
||||
-- the company pages count stays and invoices per company in correlated subqueries
|
||||
CREATE INDEX idx_stay_employer ON stay(employer_client_id);
|
||||
CREATE INDEX idx_invoice_client ON invoice(client_id);
|
||||
CREATE INDEX payment_charge ON payment(charge_id);
|
||||
|
||||
-- "Has anything changed?" for the page cache and the browser's frozen column widths: every statement that
|
||||
-- writes a data table counts it up.
|
||||
CREATE TABLE data_version (
|
||||
id integer PRIMARY KEY DEFAULT 1 CHECK (id = 1),
|
||||
version bigint NOT NULL DEFAULT 0
|
||||
);
|
||||
INSERT INTO data_version (id, version) VALUES (1, 0);
|
||||
|
||||
CREATE FUNCTION bump_data_version() RETURNS trigger LANGUAGE plpgsql AS $$
|
||||
BEGIN
|
||||
EXECUTE format('UPDATE %I.data_version SET version = version + 1', TG_TABLE_SCHEMA);
|
||||
RETURN NULL;
|
||||
END $$;
|
||||
|
||||
DO $$
|
||||
DECLARE t text;
|
||||
BEGIN
|
||||
FOREACH t IN ARRAY ARRAY['unit', 'room', 'company', 'client', 'company_key', 'dismissed_finding', 'guest',
|
||||
'invoice', 'stay', 'charge', 'payment'] LOOP
|
||||
EXECUTE format('CREATE TRIGGER %I AFTER INSERT OR UPDATE OR DELETE OR TRUNCATE ON %I '
|
||||
'FOR EACH STATEMENT EXECUTE FUNCTION bump_data_version()', t || '_data_version', t);
|
||||
END LOOP;
|
||||
END $$;
|
||||
Reference in new issue
Block a user