Files
pgz-sport/migrations/crm_full_20260505.sql
T
damir 1d02c0897d Sidebar: +ERP +CRM +Dokumenti, godišnjaci import (18 PDFs), filter helpers
- pgz nav now includes /erp/full, /crm/v2, /admin/users, /dokumenti
- 4 dokumenti endpoints: list, godišnjaci/list, godišnjak/{godina} PDF, detail
- 18 godišnjaka u pgz_sport.dokumenti (2006-2024) with savez_id=333
- PGŽ filter helpers (window._pgz_filter_priority, togglePGZFilter)
- navItemClick handler for nav items with href
2026-05-05 13:08:11 +02:00

131 lines
5.9 KiB
PL/PgSQL

-- crm_full_20260505.sql
-- PGŽ Sport — Salesforce-Lite CRM (Accounts/Contacts/Leads/Opportunities/Activities/Cases)
-- Author: dradulic@outlook.com / damir@rinet.one
-- Date: 2026-05-05
BEGIN;
-- 1) ACCOUNTS ------------------------------------------------------------
CREATE TABLE IF NOT EXISTS pgz_sport.crm_accounts (
id BIGSERIAL PRIMARY KEY,
naziv TEXT NOT NULL,
type TEXT NOT NULL DEFAULT 'klub'
CHECK (type IN ('klub','savez','sponzor','drzava','drugo')),
klub_id BIGINT REFERENCES pgz_sport.klubovi(id) ON DELETE SET NULL,
savez_id BIGINT REFERENCES pgz_sport.savezi(id) ON DELETE SET NULL,
oib TEXT,
email TEXT,
telefon TEXT,
web TEXT,
adresa TEXT,
grad TEXT,
industry TEXT,
napomene TEXT,
owner_user_id BIGINT REFERENCES pgz_sport.users(id) ON DELETE SET NULL,
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now()
);
-- 2) CONTACTS ------------------------------------------------------------
CREATE TABLE IF NOT EXISTS pgz_sport.crm_contacts (
id BIGSERIAL PRIMARY KEY,
account_id BIGINT REFERENCES pgz_sport.crm_accounts(id) ON DELETE SET NULL,
clan_id BIGINT REFERENCES pgz_sport.clanovi(id) ON DELETE SET NULL,
ime TEXT NOT NULL,
prezime TEXT NOT NULL,
funkcija TEXT,
email TEXT,
telefon TEXT,
mobitel TEXT,
napomene TEXT,
owner_user_id BIGINT REFERENCES pgz_sport.users(id) ON DELETE SET NULL,
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now()
);
-- 3) LEADS ---------------------------------------------------------------
CREATE TABLE IF NOT EXISTS pgz_sport.crm_leads (
id BIGSERIAL PRIMARY KEY,
ime TEXT,
prezime TEXT,
organizacija TEXT,
email TEXT,
telefon TEXT,
izvor TEXT,
status TEXT NOT NULL DEFAULT 'new'
CHECK (status IN ('new','contacted','qualified','lost','converted')),
napomene TEXT,
owner_user_id BIGINT REFERENCES pgz_sport.users(id) ON DELETE SET NULL,
converted_account_id BIGINT REFERENCES pgz_sport.crm_accounts(id) ON DELETE SET NULL,
converted_contact_id BIGINT REFERENCES pgz_sport.crm_contacts(id) ON DELETE SET NULL,
converted_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now()
);
-- 4) OPPORTUNITIES -------------------------------------------------------
CREATE TABLE IF NOT EXISTS pgz_sport.crm_opportunities (
id BIGSERIAL PRIMARY KEY,
account_id BIGINT REFERENCES pgz_sport.crm_accounts(id) ON DELETE CASCADE,
contact_id BIGINT REFERENCES pgz_sport.crm_contacts(id) ON DELETE SET NULL,
naziv TEXT NOT NULL,
type TEXT DEFAULT 'financiranje'
CHECK (type IN ('financiranje','sponzorstvo','grant','natjecanje','drugo')),
stage TEXT NOT NULL DEFAULT 'prospecting'
CHECK (stage IN ('prospecting','qualification','proposal','negotiation','closed_won','closed_lost')),
amount_eur NUMERIC(14,2),
probability INT DEFAULT 20 CHECK (probability BETWEEN 0 AND 100),
close_date DATE,
napomene TEXT,
owner_user_id BIGINT REFERENCES pgz_sport.users(id) ON DELETE SET NULL,
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now()
);
-- 5) ACTIVITIES ----------------------------------------------------------
CREATE TABLE IF NOT EXISTS pgz_sport.crm_activities (
id BIGSERIAL PRIMARY KEY,
type TEXT NOT NULL CHECK (type IN ('call','meeting','email','task','note')),
subject TEXT NOT NULL,
body TEXT,
account_id BIGINT REFERENCES pgz_sport.crm_accounts(id) ON DELETE CASCADE,
contact_id BIGINT REFERENCES pgz_sport.crm_contacts(id) ON DELETE SET NULL,
opportunity_id BIGINT REFERENCES pgz_sport.crm_opportunities(id) ON DELETE SET NULL,
lead_id BIGINT REFERENCES pgz_sport.crm_leads(id) ON DELETE SET NULL,
due_at TIMESTAMPTZ,
completed_at TIMESTAMPTZ,
owner_user_id BIGINT REFERENCES pgz_sport.users(id) ON DELETE SET NULL,
created_at TIMESTAMPTZ DEFAULT now()
);
-- 6) CASES ---------------------------------------------------------------
CREATE TABLE IF NOT EXISTS pgz_sport.crm_cases (
id BIGSERIAL PRIMARY KEY,
account_id BIGINT REFERENCES pgz_sport.crm_accounts(id) ON DELETE CASCADE,
contact_id BIGINT REFERENCES pgz_sport.crm_contacts(id) ON DELETE SET NULL,
subject TEXT NOT NULL,
description TEXT,
status TEXT NOT NULL DEFAULT 'open'
CHECK (status IN ('open','in_progress','waiting','resolved','closed')),
priority TEXT NOT NULL DEFAULT 'normal'
CHECK (priority IN ('low','normal','high','urgent')),
owner_user_id BIGINT REFERENCES pgz_sport.users(id) ON DELETE SET NULL,
resolved_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now()
);
-- Indexes
CREATE INDEX IF NOT EXISTS crm_contacts_account ON pgz_sport.crm_contacts(account_id);
CREATE INDEX IF NOT EXISTS crm_opp_stage ON pgz_sport.crm_opportunities(stage);
CREATE INDEX IF NOT EXISTS crm_opp_account ON pgz_sport.crm_opportunities(account_id);
CREATE INDEX IF NOT EXISTS crm_opp_close ON pgz_sport.crm_opportunities(close_date);
CREATE INDEX IF NOT EXISTS crm_act_account ON pgz_sport.crm_activities(account_id);
CREATE INDEX IF NOT EXISTS crm_act_due ON pgz_sport.crm_activities(due_at);
CREATE INDEX IF NOT EXISTS crm_act_open ON pgz_sport.crm_activities(completed_at) WHERE completed_at IS NULL;
CREATE INDEX IF NOT EXISTS crm_cases_status ON pgz_sport.crm_cases(status);
CREATE INDEX IF NOT EXISTS crm_leads_status ON pgz_sport.crm_leads(status);
CREATE INDEX IF NOT EXISTS crm_accounts_type ON pgz_sport.crm_accounts(type);
COMMIT;