140 lines
4.8 KiB
PL/PgSQL
140 lines
4.8 KiB
PL/PgSQL
-- M32 — Avviso se una presenza cambia a meno di 6 ore dall'evento (DD-050)
|
|||
|
|
--
|
||
|
|
-- Quando una riga di `risposte_presenze` cambia (nuova, modificata o ritirata) e mancano da 0 a 6 ore
|
||
|
|
-- all'inizio di una partita o di un allenamento, ai destinatari arriva una notifica «Presenza modificata».
|
||
|
|
--
|
||
|
|
-- FASE DI PROVA: i destinatari sono solo gli admin (DD-050, «Fase di prova»). Per aprirla agli allenatori
|
||
|
|
-- basta aggiungere 'allenatore' alla lista dei ruoli qui sotto, con una nuova migration.
|
||
|
|
--
|
||
|
|
-- Dal database in poi il resto è già fatto: il trigger di M22/M26 accoda l'email, quello delle push
|
||
|
|
-- (esteso qui con il tipo nuovo) accoda la push, la riga è il centro notifiche in-app (DD-038).
|
||
|
|
|
||
|
|
-- --- Tipo di notifica --------------------------------------------------------------------------
|
||
|
|
|
||
|
|
ALTER TABLE public.notifiche_utente DROP CONSTRAINT notifiche_utente_tipo_check;
|
||
|
|
ALTER TABLE public.notifiche_utente ADD CONSTRAINT notifiche_utente_tipo_check CHECK (
|
||
|
|
tipo IN (
|
||
|
|
'admin',
|
||
|
|
'evento_promemoria_24h',
|
||
|
|
'evento_promemoria_3h',
|
||
|
|
'turno_palloni',
|
||
|
|
'turno_palloni_12h',
|
||
|
|
'turno_palloni_6h',
|
||
|
|
'turno_palloni_3h',
|
||
|
|
'turno_palloni_revocato',
|
||
|
|
'sollecita_presenze',
|
||
|
|
'sollecita_presenze_24h',
|
||
|
|
'sollecita_presenze_12h',
|
||
|
|
'sollecita_presenze_6h',
|
||
|
|
'sondaggio_cacche',
|
||
|
|
'compleanno',
|
||
|
|
'compleanno_auguri',
|
||
|
|
'presenza_modificata'
|
||
|
|
)
|
||
|
|
);
|
||
|
|
|
||
|
|
-- --- Funzione e trigger ------------------------------------------------------------------------
|
||
|
|
--
|
||
|
|
-- `evento_id` resta NULL (come i messaggi `admin`): la UNIQUE (giocatore_id, evento_id, tipo) non si
|
||
|
|
-- applica e due modifiche dello stesso evento restano due notifiche distinte.
|
||
|
|
--
|
||
|
|
-- Cancellare un evento elimina le risposte con un trigger AFTER DELETE su `eventi_app` (M14): quando
|
||
|
|
-- scatta questo, l'evento non esiste più, quindi non parte nessun avviso.
|
||
|
|
|
||
|
|
CREATE OR REPLACE FUNCTION public.avvisa_presenza_modificata()
|
||
|
|
RETURNS trigger
|
||
|
|
LANGUAGE plpgsql
|
||
|
|
SECURITY DEFINER
|
||
|
|
SET search_path = public
|
||
|
|
AS $$
|
||
|
|
DECLARE
|
||
|
|
evento_id_r text := CASE WHEN TG_OP = 'DELETE' THEN OLD.evento_id ELSE NEW.evento_id END;
|
||
|
|
giocatore_r text := CASE WHEN TG_OP = 'DELETE' THEN OLD.giocatore_id ELSE NEW.giocatore_id END;
|
||
|
|
prima text := CASE WHEN TG_OP = 'INSERT' THEN NULL ELSE OLD.stato END;
|
||
|
|
dopo text := CASE WHEN TG_OP = 'DELETE' THEN NULL ELSE NEW.stato END;
|
||
|
|
ev record;
|
||
|
|
chi record;
|
||
|
|
BEGIN
|
||
|
|
IF prima IS NOT DISTINCT FROM dopo THEN
|
||
|
|
RETURN NULL;
|
||
|
|
END IF;
|
||
|
|
|
||
|
|
SELECT e.titolo, e.data, e.ora, e.tipo, public.inizio_evento(e.data, e.ora) AS inizio
|
||
|
|
INTO ev
|
||
|
|
FROM public.eventi_app e
|
||
|
|
WHERE e.id = evento_id_r;
|
||
|
|
|
||
|
|
IF NOT FOUND
|
||
|
|
OR ev.tipo NOT IN ('partita', 'allenamento')
|
||
|
|
OR ev.inizio IS NULL
|
||
|
|
OR ev.inizio - now() NOT BETWEEN interval '0' AND interval '6 hours' THEN
|
||
|
|
RETURN NULL;
|
||
|
|
END IF;
|
||
|
|
|
||
|
|
SELECT trim(g.nome || ' ' || g.cognome) AS nome_completo
|
||
|
|
INTO chi
|
||
|
|
FROM public.giocatori_squadra g
|
||
|
|
WHERE g.id = giocatore_r;
|
||
|
|
|
||
|
|
IF NOT FOUND THEN
|
||
|
|
RETURN NULL;
|
||
|
|
END IF;
|
||
|
|
|
||
|
|
INSERT INTO public.notifiche_utente (giocatore_id, tipo, titolo, corpo)
|
||
|
|
SELECT d.id,
|
||
|
|
'presenza_modificata',
|
||
|
|
'Presenza modificata: ' || chi.nome_completo,
|
||
|
|
'Evento: ' || ev.titolo
|
||
|
|
|| E'\nData: ' || to_char(ev.data, 'DD/MM/YYYY') || ', ore ' || ev.ora
|
||
|
|
|| E'\nDa: ' || public.nome_stato_presenza(prima)
|
||
|
|
|| E'\nA: ' || public.nome_stato_presenza(dopo)
|
||
|
|
FROM public.giocatori_squadra d
|
||
|
|
WHERE d.attivo = true
|
||
|
|
AND d.id <> giocatore_r
|
||
|
|
AND EXISTS (
|
||
|
|
SELECT 1
|
||
|
|
FROM public.user_roles ur
|
||
|
|
WHERE ur.user_id = d.auth_user_id
|
||
|
|
AND ur.role IN ('admin')
|
||
|
|
);
|
||
|
|
|
||
|
|
RETURN NULL;
|
||
|
|
END;
|
||
|
|
$$;
|
||
|
|
|
||
|
|
REVOKE ALL ON FUNCTION public.avvisa_presenza_modificata() FROM PUBLIC, anon, authenticated;
|
||
|
|
|
||
|
|
CREATE OR REPLACE FUNCTION public.nome_stato_presenza(p_stato text)
|
||
|
|
RETURNS text
|
||
|
|
LANGUAGE sql IMMUTABLE AS $$
|
||
|
|
SELECT CASE WHEN p_stato = 'ritardo' THEN 'in ritardo' ELSE coalesce(p_stato, 'nessuna risposta') END;
|
||
|
|
$$;
|
||
|
|
|
||
|
|
CREATE TRIGGER risposte_presenze_avvisa_modifica
|
||
|
|
AFTER INSERT OR UPDATE OF stato OR DELETE ON public.risposte_presenze
|
||
|
|
FOR EACH ROW
|
||
|
|
EXECUTE FUNCTION public.avvisa_presenza_modificata();
|
||
|
|
|
||
|
|
-- --- Push: anche la presenza modificata --------------------------------------------------------
|
||
|
|
--
|
||
|
|
-- Stesso trigger di M31 con il tipo nuovo. L'email passa già dal trigger di M22/M26.
|
||
|
|
|
||
|
|
DROP TRIGGER notifiche_utente_accoda_push_promemoria ON public.notifiche_utente;
|
||
|
|
CREATE TRIGGER notifiche_utente_accoda_push_promemoria
|
||
|
|
AFTER INSERT ON public.notifiche_utente
|
||
|
|
FOR EACH ROW
|
||
|
|
WHEN (NEW.tipo IN (
|
||
|
|
'evento_promemoria_24h',
|
||
|
|
'evento_promemoria_3h',
|
||
|
|
'turno_palloni_12h',
|
||
|
|
'turno_palloni_6h',
|
||
|
|
'turno_palloni_3h',
|
||
|
|
'turno_palloni_revocato',
|
||
|
|
'sollecita_presenze_24h',
|
||
|
|
'sollecita_presenze_12h',
|
||
|
|
'sollecita_presenze_6h',
|
||
|
|
'compleanno',
|
||
|
|
'compleanno_auguri',
|
||
|
|
'presenza_modificata'
|
||
|
|
))
|
||
|
|
EXECUTE FUNCTION public.accoda_push_promemoria();
|