Changes between Version 3 and Version 4 of App


Ignore:
Timestamp:
09/30/25 10:53:26 (2 weeks ago)
Author:
211561
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • App

    v3 v4  
    3737= Тригери
    3838
     39== Негативни/нулти количини и цени во {{{ORDER_BATCHES}}}
     40
     41Кога се извршува {{{INSERT}}} или {{{UPDATE}}} на {{{ORDER_BATCHES}}}, осигурај {{{quantity > 0}}} и {{{price_per_unit >= 0}}}; пресметај {{{total_price = quantity * price_per_unit}}} и постави {{{timestamps}}}.
     42
     43{{{
     44CREATE OR REPLACE FUNCTION trg_order_batches_validate() RETURNS trigger AS $
     45BEGIN
     46  IF NEW.quantity IS NULL OR NEW.quantity <= 0 THEN
     47    RAISE EXCEPTION 'quantity must be > 0';
     48  END IF;
     49  IF NEW.price_per_unit IS NULL OR NEW.price_per_unit < 0 THEN
     50    RAISE EXCEPTION 'price_per_unit must be >= 0';
     51  END IF;
     52  NEW.total_price := NEW.quantity * NEW.price_per_unit;
     53  NEW.updated_at := NOW();
     54  IF TG_OP = 'INSERT' THEN
     55    NEW.created_at := NOW();
     56  END IF;
     57  RETURN NEW;
     58END;
     59$ LANGUAGE plpgsql;
     60
     61CREATE TRIGGER order_batches_validate
     62BEFORE INSERT OR UPDATE ON order_batches
     63FOR EACH ROW EXECUTE FUNCTION trg_order_batches_validate();
     64}}}
     65
     66== Нарачки со истечени серии
     67
     68Пред {{{INSERT}}} или {{{UPDATE}}} на {{{ORDER_BATCHES}}}, провери дали повиканата {{{BATCH}}} не е истечена според датумот на нарачката ({{{orders.date}}}). Се фрла {{{exception}}} ако {{{expiration_date < orders.date}}}.
     69
     70{{{
     71CREATE OR REPLACE FUNCTION trg_order_batches_no_expired() RETURNS trigger AS $
     72DECLARE
     73  ord_date DATE;
     74  batch_exp DATE;
     75BEGIN
     76  SELECT date INTO ord_date FROM orders WHERE id = NEW.order_id;
     77  SELECT expiration_date INTO batch_exp FROM batches WHERE id = NEW.batch_id;
     78  IF ord_date IS NULL OR batch_exp IS NULL THEN
     79    RAISE EXCEPTION 'order or batch not found';
     80  END IF;
     81  IF batch_exp < ord_date THEN
     82    RAISE EXCEPTION 'cannot add expired batch to order (batch % expired %)', NEW.batch_id, batch_exp;
     83  END IF;
     84  RETURN NEW;
     85END;
     86$ LANGUAGE plpgsql;
     87
     88CREATE TRIGGER order_batches_no_expired
     89BEFORE INSERT OR UPDATE ON order_batches
     90FOR EACH ROW EXECUTE FUNCTION trg_order_batches_no_expired();
     91}}}
     92
     93== Бришење на {{{PRODUCERS/PRODUCTS/BATCHES}}} кои се реферирани
     94
     95Забрането бришење на:
     96
     97- {{{producer}}} ако постојат {{{products}}}
     98- {{{product}}} ако постојат {{{batches}}}
     99- {{{batch}}} ако е искористен во {{{order_batches}}}.
     100
     101{{{
     102CREATE OR REPLACE FUNCTION trg_prevent_fk_deletes() RETURNS trigger AS $
     103BEGIN
     104  IF TG_TABLE_NAME = 'producers' THEN
     105    IF EXISTS (SELECT 1 FROM products WHERE producer_id = OLD.id) THEN
     106      RAISE EXCEPTION 'cannot delete producer with products';
     107    END IF;
     108  ELSIF TG_TABLE_NAME = 'products' THEN
     109    IF EXISTS (SELECT 1 FROM batches WHERE product_id = OLD.id) THEN
     110      RAISE EXCEPTION 'cannot delete product with batches';
     111    END IF;
     112  ELSIF TG_TABLE_NAME = 'batches' THEN
     113    IF EXISTS (SELECT 1 FROM order_batches WHERE batch_id = OLD.id) THEN
     114      RAISE EXCEPTION 'cannot delete batch referenced in orders';
     115    END IF;
     116  END IF;
     117  RETURN OLD;
     118END;
     119$ LANGUAGE plpgsql;
     120
     121CREATE TRIGGER prevent_delete_producers
     122BEFORE DELETE ON producers
     123FOR EACH ROW EXECUTE FUNCTION trg_prevent_fk_deletes();
     124
     125CREATE TRIGGER prevent_delete_products
     126BEFORE DELETE ON products
     127FOR EACH ROW EXECUTE FUNCTION trg_prevent_fk_deletes();
     128
     129CREATE TRIGGER prevent_delete_batches
     130BEFORE DELETE ON batches
     131FOR EACH ROW EXECUTE FUNCTION trg_prevent_fk_deletes();
     132}}}
     133
     134== Автоматско ажурирање на {{{ORDER.status}}} според плаќања
     135
     136Кога {{{PAYMENT}}} се означува како {{{paid}}} ({{{payment_status = 'paid'}}} и {{{payment_date}}} не е {{{NULL}}}), провери {{{SUM(payments.amount) >= orders.total_amount}}}, а потоа постави {{{orders.status = 'paid'}}}.
     137
     138{{{
     139CREATE OR REPLACE FUNCTION trg_payments_update_order_status() RETURNS trigger AS $
     140DECLARE
     141  paid_sum NUMERIC;
     142  ord_total NUMERIC;
     143BEGIN
     144  IF TG_OP = 'DELETE' THEN
     145    RETURN OLD;
     146  END IF;
     147
     148  SELECT COALESCE(SUM(amount),0) INTO paid_sum FROM payments WHERE order_id = NEW.order_id AND payment_status = 'paid';
     149  SELECT COALESCE(total_amount,0) INTO ord_total FROM orders WHERE id = NEW.order_id;
     150
     151  IF paid_sum >= ord_total AND ord_total > 0 THEN
     152    UPDATE orders SET status = 'paid' WHERE id = NEW.order_id;
     153  END IF;
     154  RETURN NEW;
     155END;
     156$ LANGUAGE plpgsql;
     157
     158CREATE TRIGGER payments_update_order_status
     159AFTER INSERT OR UPDATE ON payments
     160FOR EACH ROW EXECUTE FUNCTION trg_payments_update_order_status();
     161}}}
     162
     163== Известувања за промена на статус на нарачка
     164
     165Известување кога нарачката го променила статусот ({{{ORDER.status}}}) — испраќа {{{RAISE NOTICE}}} со ордедена порака
     166
     167{{{
     168CREATE OR REPLACE FUNCTION trg_order_status_change_fun()
     169RETURNS trigger AS $
     170BEGIN
     171  IF TG_OP = 'UPDATE' AND NEW.status IS DISTINCT FROM OLD.status THEN
     172    RAISE NOTICE 'Order % changed it's status: % → %', NEW.id, OLD.status, NEW.status;
     173    IF NEW.status = 'shipped' OR NEW.status = 'delivered' THEN
     174      RAISE NOTICE 'Good news! Order % is %!', NEW.id, NEW.status;
     175    END IF;
     176  END IF;
     177  RETURN NEW;
     178END;
     179$ LANGUAGE plpgsql;
     180
     181DROP TRIGGER IF EXISTS trg_order_status_change ON orders;
     182CREATE TRIGGER trg_order_status_change
     183AFTER UPDATE ON orders
     184FOR EACH ROW
     185WHEN (OLD.status IS DISTINCT FROM NEW.status)
     186EXECUTE FUNCTION trg_order_status_change_fun();
     187}}}
     188
    39189= Трансакции