201 lines
6.4 KiB
SQL
201 lines
6.4 KiB
SQL
CREATE TABLE IF NOT EXISTS settings (
|
|
key TEXT PRIMARY KEY,
|
|
value TEXT
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS users (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
name TEXT NOT NULL,
|
|
email TEXT NOT NULL UNIQUE COLLATE NOCASE,
|
|
password_hash TEXT NOT NULL,
|
|
role TEXT NOT NULL DEFAULT 'user',
|
|
active INTEGER NOT NULL DEFAULT 1,
|
|
created_at TEXT NOT NULL
|
|
);
|
|
|
|
-- Relaties (zoals accounts in EspoCRM): klantbundels (huishouden, familie, bedrijf) en partners
|
|
-- (leverancier, aannemer, ...). Contactpersonen hangen eronder met een rol.
|
|
CREATE TABLE IF NOT EXISTS relations (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
kind TEXT NOT NULL DEFAULT 'klant',
|
|
type TEXT DEFAULT '',
|
|
name TEXT NOT NULL,
|
|
email TEXT DEFAULT '',
|
|
phone TEXT DEFAULT '',
|
|
website TEXT DEFAULT '',
|
|
address TEXT DEFAULT '',
|
|
postcode TEXT DEFAULT '',
|
|
city TEXT DEFAULT '',
|
|
kvk TEXT DEFAULT '',
|
|
notes TEXT DEFAULT '',
|
|
created_at TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_relations_name ON relations(kind, name COLLATE NOCASE);
|
|
|
|
CREATE TABLE IF NOT EXISTS contacts (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
name TEXT NOT NULL DEFAULT '',
|
|
email TEXT DEFAULT '',
|
|
phone TEXT DEFAULT '',
|
|
company TEXT DEFAULT '',
|
|
address TEXT DEFAULT '',
|
|
postcode TEXT DEFAULT '',
|
|
city TEXT DEFAULT '',
|
|
type TEXT NOT NULL DEFAULT 'lead',
|
|
status TEXT NOT NULL DEFAULT 'nieuw',
|
|
source TEXT DEFAULT '',
|
|
value REAL NOT NULL DEFAULT 0,
|
|
assigned_user_id INTEGER REFERENCES users(id) ON DELETE SET NULL,
|
|
relation_id INTEGER REFERENCES relations(id) ON DELETE SET NULL,
|
|
relation_role TEXT DEFAULT '',
|
|
portal_token TEXT,
|
|
portal_password_hash TEXT,
|
|
portal_last_login TEXT,
|
|
notes TEXT DEFAULT '',
|
|
extra TEXT DEFAULT '{}',
|
|
created_at TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_contacts_email ON contacts(email COLLATE NOCASE);
|
|
|
|
CREATE TABLE IF NOT EXISTS activities (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
contact_id INTEGER NOT NULL REFERENCES contacts(id) ON DELETE CASCADE,
|
|
type TEXT NOT NULL,
|
|
body TEXT DEFAULT '',
|
|
user_id INTEGER REFERENCES users(id) ON DELETE SET NULL,
|
|
created_at TEXT NOT NULL
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS files (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
contact_id INTEGER REFERENCES contacts(id) ON DELETE CASCADE,
|
|
stored TEXT NOT NULL,
|
|
original TEXT NOT NULL,
|
|
mime TEXT DEFAULT '',
|
|
size INTEGER DEFAULT 0,
|
|
created_at TEXT NOT NULL
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS products (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
name TEXT NOT NULL,
|
|
sku TEXT DEFAULT '',
|
|
description TEXT DEFAULT '',
|
|
unit TEXT DEFAULT 'stuk',
|
|
supplier TEXT DEFAULT '',
|
|
supplier_id INTEGER REFERENCES relations(id) ON DELETE SET NULL,
|
|
price REAL NOT NULL DEFAULT 0,
|
|
vat REAL NOT NULL DEFAULT 21,
|
|
image TEXT DEFAULT '',
|
|
active INTEGER NOT NULL DEFAULT 1,
|
|
created_at TEXT NOT NULL,
|
|
updated_at TEXT
|
|
);
|
|
|
|
-- Elke wijziging aan een product (handmatig, import of API), zodat prijsmutaties terug te zien zijn.
|
|
CREATE TABLE IF NOT EXISTS product_history (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
product_id INTEGER NOT NULL REFERENCES products(id) ON DELETE CASCADE,
|
|
field TEXT NOT NULL,
|
|
old_value TEXT,
|
|
new_value TEXT,
|
|
source TEXT DEFAULT '',
|
|
user_id INTEGER REFERENCES users(id) ON DELETE SET NULL,
|
|
created_at TEXT NOT NULL
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_product_history ON product_history(product_id, created_at);
|
|
|
|
CREATE TABLE IF NOT EXISTS quotes (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
number TEXT UNIQUE NOT NULL,
|
|
contact_id INTEGER REFERENCES contacts(id) ON DELETE SET NULL,
|
|
status TEXT NOT NULL DEFAULT 'concept',
|
|
title TEXT DEFAULT '',
|
|
date TEXT NOT NULL,
|
|
valid_until TEXT,
|
|
intro TEXT DEFAULT '',
|
|
notes TEXT DEFAULT '',
|
|
created_at TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS quote_lines (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
quote_id INTEGER NOT NULL REFERENCES quotes(id) ON DELETE CASCADE,
|
|
position INTEGER NOT NULL DEFAULT 0,
|
|
product_id INTEGER,
|
|
description TEXT NOT NULL DEFAULT '',
|
|
qty REAL NOT NULL DEFAULT 1,
|
|
unit TEXT DEFAULT '',
|
|
price REAL NOT NULL DEFAULT 0,
|
|
vat REAL NOT NULL DEFAULT 21
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS emails (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
uid TEXT UNIQUE,
|
|
message_id TEXT DEFAULT '',
|
|
direction TEXT NOT NULL DEFAULT 'in',
|
|
contact_id INTEGER REFERENCES contacts(id) ON DELETE SET NULL,
|
|
from_name TEXT DEFAULT '',
|
|
from_addr TEXT DEFAULT '',
|
|
to_addr TEXT DEFAULT '',
|
|
subject TEXT DEFAULT '',
|
|
body TEXT DEFAULT '',
|
|
date TEXT NOT NULL,
|
|
is_read INTEGER NOT NULL DEFAULT 0,
|
|
archived INTEGER NOT NULL DEFAULT 0,
|
|
cc TEXT DEFAULT '',
|
|
attachments TEXT DEFAULT ''
|
|
);
|
|
CREATE INDEX IF NOT EXISTS idx_emails_from ON emails(from_addr);
|
|
|
|
-- E-mailtemplates: onderwerp en tekst met velden als {voornaam}, ingevuld bij het opstellen of versturen
|
|
-- (MAIL_FIELDS in app.py).
|
|
CREATE TABLE IF NOT EXISTS email_templates (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
name TEXT NOT NULL,
|
|
subject TEXT DEFAULT '',
|
|
body TEXT DEFAULT '',
|
|
created_at TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS tasks (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
contact_id INTEGER REFERENCES contacts(id) ON DELETE CASCADE,
|
|
user_id INTEGER REFERENCES users(id) ON DELETE SET NULL,
|
|
title TEXT NOT NULL,
|
|
due_date TEXT,
|
|
done INTEGER NOT NULL DEFAULT 0,
|
|
created_at TEXT NOT NULL
|
|
);
|
|
|
|
-- Agenda: één agenda per gebruiker, ook via CalDAV (/dav/). `ics` is het kalenderobject zoals een
|
|
-- agenda-app het stuurde (of zoals de CRM het maakte), de losse kolommen zijn daaruit gehaald voor weergave.
|
|
CREATE TABLE IF NOT EXISTS events (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
contact_id INTEGER REFERENCES contacts(id) ON DELETE SET NULL,
|
|
uid TEXT NOT NULL,
|
|
href TEXT NOT NULL,
|
|
title TEXT NOT NULL DEFAULT '',
|
|
location TEXT DEFAULT '',
|
|
description TEXT DEFAULT '',
|
|
starts_at TEXT NOT NULL,
|
|
ends_at TEXT NOT NULL,
|
|
all_day INTEGER NOT NULL DEFAULT 0,
|
|
rrule TEXT DEFAULT '',
|
|
exdates TEXT DEFAULT '',
|
|
ics TEXT NOT NULL,
|
|
etag TEXT NOT NULL,
|
|
created_at TEXT NOT NULL,
|
|
updated_at TEXT NOT NULL
|
|
);
|
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_events_href ON events(user_id, href);
|
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_events_uid ON events(user_id, uid);
|
|
CREATE INDEX IF NOT EXISTS idx_events_start ON events(starts_at);
|
|
CREATE INDEX IF NOT EXISTS idx_events_contact ON events(contact_id);
|