Changes between Initial Version and Version 1 of Triggers


Ignore:
Timestamp:
08/31/25 21:51:40 (2 days ago)
Author:
222004
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Triggers

    v1 v1  
     1== Тригери ==
     2
     3// Приказ на дефинирани тригери, со нивната улога, кога се активираат и зошто се корисни. //
     4
     5== **1) Тригер за залиха (inventory_brandedmedicine) – сетирање датум и забрана за негативни количини**\\
     6\\
     7**Што прави:** Автоматски поставува last_changed на денешен датум и спречува quantity < 0.\\
     8**Кога се активира:** Пред INSERT и пред UPDATE.\\
     9**Зошто е корисен:** Осигурува конзистентност на залихата и забрана за нелогични вредности.\\
     10
     11{{{
     12
     13CREATE OR REPLACE FUNCTION synergymed.fn_inventory_bm_before()
     14RETURNS TRIGGER
     15LANGUAGE plpgsql AS $$
     16BEGIN
     17  IF NEW.quantity IS NULL OR NEW.quantity < 0 THEN
     18    RAISE EXCEPTION 'quantity must be non-negative';
     19  END IF;
     20  NEW.last_changed := CURRENT_DATE;
     21  RETURN NEW;
     22END;
     23$$;
     24
     25DROP TRIGGER IF EXISTS trg_inventory_bm_before_ins ON synergymed.inventory_brandedmedicine;
     26CREATE TRIGGER trg_inventory_bm_before_ins
     27BEFORE INSERT ON synergymed.inventory_brandedmedicine
     28FOR EACH ROW EXECUTE FUNCTION synergymed.fn_inventory_bm_before();
     29
     30DROP TRIGGER IF EXISTS trg_inventory_bm_before_upd ON synergymed.inventory_brandedmedicine;
     31CREATE TRIGGER trg_inventory_bm_before_upd
     32BEFORE UPDATE ON synergymed.inventory_brandedmedicine
     33FOR EACH ROW EXECUTE FUNCTION synergymed.fn_inventory_bm_before();
     34
     35}}}
     36
     37----
     38
     39== **2) Тригер за лојалност (payment) – поени на клуб-картичка при успешно плаќање**  \\
     40\\
     41**Што прави:** Додава поени на clubcard ако payment.status = 'завршено'.  \\
     42**Кога се активира:** По INSERT или UPDATE.  \\
     43**Зошто е корисен:** Автоматска интеграција на лојалност со финансиски трансакции.  \\
     44
     45{{{
     46
     47CREATE OR REPLACE FUNCTION synergymed.fn_payment_loyalty_after()
     48RETURNS TRIGGER
     49LANGUAGE plpgsql AS $$
     50DECLARE v_inc INT;
     51BEGIN
     52  IF NEW.status = 'завршено' THEN
     53    IF EXISTS (SELECT 1 FROM synergymed.clubcard WHERE id = NEW.client_id) THEN
     54      v_inc := GREATEST(0, FLOOR(COALESCE(NEW.amount,0) / 10));
     55      UPDATE synergymed.clubcard
     56      SET points = points + v_inc
     57      WHERE id = NEW.client_id;
     58    END IF;
     59  END IF;
     60  RETURN NEW;
     61END;
     62$$;
     63
     64DROP TRIGGER IF EXISTS trg_payment_loyalty ON synergymed.payment;
     65CREATE TRIGGER trg_payment_loyalty
     66AFTER INSERT OR UPDATE OF status, amount ON synergymed.payment
     67FOR EACH ROW EXECUTE FUNCTION synergymed.fn_payment_loyalty_after();
     68
     69}}}
     70
     71----
     72
     73== **3) Тригер за верификација на клиент (sensitiveclientdata) – автоматско одразување во client.is_verified**  \\
     74\\
     75**Што прави:** Ако verification_status = 'верифицирано', тогаш client.is_verified = TRUE; ако е 'одбиено' → FALSE.  \\
     76**Кога се активира:** По INSERT или UPDATE.  \\
     77**Зошто е корисен:** Автоматски ја усогласува регулаторната состојба на клиентот со flag-от во Client. \\
     78
     79{{{
     80
     81CREATE OR REPLACE FUNCTION synergymed.fn_sensitiveclientdata_affect_client_after()
     82RETURNS TRIGGER
     83LANGUAGE plpgsql AS $$
     84BEGIN
     85  IF NEW.verification_status = 'верифицирано' THEN
     86    UPDATE synergymed.client SET is_verified = TRUE WHERE id = NEW.client_id;
     87  ELSIF NEW.verification_status = 'одбиено' THEN
     88    UPDATE synergymed.client SET is_verified = FALSE WHERE id = NEW.client_id;
     89  END IF;
     90  RETURN NEW;
     91END;
     92$$;
     93
     94DROP TRIGGER IF EXISTS trg_sensitiveclientdata_affect_client ON synergymed.sensitiveclientdata;
     95CREATE TRIGGER trg_sensitiveclientdata_affect_client
     96AFTER INSERT OR UPDATE OF verification_status ON synergymed.sensitiveclientdata
     97FOR EACH ROW EXECUTE FUNCTION synergymed.fn_sensitiveclientdata_affect_client_after();
     98
     99}}}
     100
     101----
     102
     103== **4) Тригер за интеракции на лекови (medicineinteraction) – симетрија и анти-рефлексивност**  \\
     104\\
     105**Што прави:** Спречува интеракција лек-со-себе, и редоследува пар (id1, id2) така што id1 < id2.  \\
     106**Кога се активира:** Пред INSERT и UPDATE.  \\
     107**Зошто е корисен:** Гарантира уникатни и чисти парови лекови.  \\
     108
     109{{{
     110
     111CREATE OR REPLACE FUNCTION synergymed.fn_medicineinteraction_order_before()
     112RETURNS TRIGGER
     113LANGUAGE plpgsql AS $$
     114DECLARE a INT; b INT;
     115BEGIN
     116  IF NEW.medicine_id_1 = NEW.medicine_id_2 THEN
     117    RAISE EXCEPTION 'medicine cannot interact with itself';
     118  END IF;
     119
     120  a := LEAST(NEW.medicine_id_1, NEW.medicine_id_2);
     121  b := GREATEST(NEW.medicine_id_1, NEW.medicine_id_2);
     122  NEW.medicine_id_1 := a;
     123  NEW.medicine_id_2 := b;
     124  RETURN NEW;
     125END;
     126$$;
     127
     128DROP TRIGGER IF EXISTS trg_mi_order_before_ins ON synergymed.medicineinteraction;
     129CREATE TRIGGER trg_mi_order_before_ins
     130BEFORE INSERT ON synergymed.medicineinteraction
     131FOR EACH ROW EXECUTE FUNCTION synergymed.fn_medicineinteraction_order_before();
     132
     133DROP TRIGGER IF EXISTS trg_mi_order_before_upd ON synergymed.medicineinteraction;
     134CREATE TRIGGER trg_mi_order_before_upd
     135BEFORE UPDATE ON synergymed.medicineinteraction
     136FOR EACH ROW EXECUTE FUNCTION synergymed.fn_medicineinteraction_order_before();
     137
     138CREATE UNIQUE INDEX IF NOT EXISTS ux_mi_pair
     139ON synergymed.medicineinteraction (medicine_id_1, medicine_id_2);
     140
     141}}}
     142
     143----
     144
     145== **5) Тригер за авто-ажурирање на каталогот на аптеки**  \\
     146\\
     147**Што прави:** Кога се менува inventory_brandedmedicine, автоматски додава записи во pharmacy_catalog за да гарантира дека секој производ што е во залиха е и во каталогот на аптеката.  \\
     148**Кога се активира:** По INSERT или UPDATE на quantity.  \\
     149**Зошто е корисен:** Ја одржува усогласеноста меѓу залихи и каталог, без рачна интервенција.  \\
     150
     151{{{
     152
     153CREATE OR REPLACE FUNCTION synergymed.fn_inventory_autocatalog_after()
     154RETURNS TRIGGER
     155LANGUAGE plpgsql AS $$
     156DECLARE
     157  v_pharmacy_id INT;
     158BEGIN
     159  SELECT ph.company_id INTO v_pharmacy_id
     160  FROM synergymed.inventory i
     161  JOIN synergymed.facility f ON f.id = i.facility_id
     162  JOIN synergymed.pharmacy ph ON ph.company_id = f.company_id
     163  WHERE i.id = COALESCE(NEW.inventory_id, OLD.inventory_id)
     164  LIMIT 1;
     165
     166  IF v_pharmacy_id IS NOT NULL THEN
     167    INSERT INTO synergymed.pharmacy_catalog(pharmacy_id, branded_medicine_id)
     168    VALUES (v_pharmacy_id, COALESCE(NEW.branded_medicine_id, OLD.branded_medicine_id))
     169    ON CONFLICT DO NOTHING;
     170  END IF;
     171
     172  RETURN COALESCE(NEW, OLD);
     173END;
     174$$;
     175
     176DROP TRIGGER IF EXISTS trg_inventory_autocatalog_ins ON synergymed.inventory_brandedmedicine;
     177CREATE TRIGGER trg_inventory_autocatalog_ins
     178AFTER INSERT ON synergymed.inventory_brandedmedicine
     179FOR EACH ROW EXECUTE FUNCTION synergymed.fn_inventory_autocatalog_after();
     180
     181DROP TRIGGER IF EXISTS trg_inventory_autocatalog_upd ON synergymed.inventory_brandedmedicine;
     182CREATE TRIGGER trg_inventory_autocatalog_upd
     183AFTER UPDATE OF quantity ON synergymed.inventory_brandedmedicine
     184FOR EACH ROW EXECUTE FUNCTION synergymed.fn_inventory_autocatalog_after();
     185
     186}}}