Функции, процедури, тригери : triggers.txt

File triggers.txt, 5.4 KB (added by 231068, 7 days ago)
Line 
1
2--====================================================================================================================
3-- TRIGGERS
4--====================================================================================================================
5-- 1. Затворање на кредит кога сите рати се платени
6CREATE OR REPLACE FUNCTION fn_close_loan_when_paid()
7 RETURNS TRIGGER AS
8$$
9DECLARE
10 v_unpaid_count INT;
11BEGIN
12 IF NEW.loan_id IS NULL THEN
13 RETURN NEW;
14 END IF;
15
16 IF NEW.status = 'PAID' AND OLD.status IS DISTINCT FROM 'PAID' THEN
17
18 SELECT COUNT(*)
19 INTO v_unpaid_count
20 FROM Loan_installment
21 WHERE loan_id = NEW.loan_id
22 AND status != 'PAID'
23 AND installment_id != NEW.installment_id;
24
25 IF v_unpaid_count = 0 THEN
26 UPDATE Loan
27 SET status = 'CLOSED',
28 end_date = CURRENT_DATE
29 WHERE loan_id = NEW.loan_id
30 AND status = 'APPROVED';
31 END IF;
32 END IF;
33
34 RETURN NEW;
35END;
36$$ LANGUAGE plpgsql;
37
38DROP TRIGGER IF EXISTS trg_close_loan_when_paid ON Loan_installment;
39
40CREATE TRIGGER trg_close_loan_when_paid
41 AFTER UPDATE OF status
42 ON Loan_installment
43 FOR EACH ROW
44EXECUTE FUNCTION fn_close_loan_when_paid();
45
46
47-- 2. Превенција на негативен баланс
48CREATE OR REPLACE FUNCTION fn_prevent_negative_balance()
49 RETURNS TRIGGER AS
50$$
51DECLARE
52 v_min_balance DECIMAL(20, 2) := 0;
53BEGIN
54 SELECT COALESCE(minimum_balance, 0)
55 INTO v_min_balance
56 FROM SavingsAccount
57 WHERE account_id = NEW.account_id;
58
59 IF NEW.balance < v_min_balance THEN
60 RAISE EXCEPTION 'Недоволен баланс';
61 END IF;
62
63 RETURN NEW;
64END;
65$$ LANGUAGE plpgsql;
66
67DROP TRIGGER IF EXISTS trg_prevent_negative_balance ON Account;
68
69CREATE TRIGGER trg_prevent_negative_balance
70 BEFORE UPDATE OF balance
71 ON Account
72 FOR EACH ROW
73EXECUTE FUNCTION fn_prevent_negative_balance();
74
75
76-- 3. Логирање на сомнителни трансакции (Audit trail)
77CREATE TABLE IF NOT EXISTS Suspicious_transaction_log
78(
79 log_id SERIAL PRIMARY KEY,
80 transaction_id INT NOT NULL,
81 account_id INT,
82 amount DECIMAL(20, 2),
83 status VARCHAR(20),
84 flagged_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
85 reason VARCHAR(255)
86);
87
88CREATE OR REPLACE FUNCTION fn_log_suspicious_transaction()
89 RETURNS TRIGGER AS
90$$
91BEGIN
92 IF NEW.amount > 9000 AND NEW.status IN ('PENDING', 'FAILED') THEN
93 INSERT INTO Suspicious_transaction_log(transaction_id, account_id, amount, status, reason)
94 VALUES (NEW.transaction_id, NEW.account_id, NEW.amount, NEW.status, 'High risk');
95 END IF;
96 RETURN NEW;
97END;
98$$ LANGUAGE plpgsql;
99
100DROP TRIGGER IF EXISTS trg_log_suspicious_transaction ON Transaction;
101
102CREATE TRIGGER trg_log_suspicious_transaction
103 AFTER INSERT OR UPDATE OF status
104 ON Transaction
105 FOR EACH ROW
106EXECUTE FUNCTION fn_log_suspicious_transaction();
107
108
109-- 4. Ажурирање на Daily Report при комплетирана трансакција
110CREATE OR REPLACE FUNCTION fn_update_daily_report()
111 RETURNS TRIGGER AS
112$$
113DECLARE
114 v_branch_id INT;
115BEGIN
116 IF NEW.status = 'COMPLETED'
117 AND (TG_OP = 'INSERT' OR OLD.status IS DISTINCT FROM 'COMPLETED') THEN
118
119 SELECT branch_id
120 INTO v_branch_id
121 FROM Account
122 WHERE account_id = NEW.account_id;
123
124 IF v_branch_id IS NULL THEN
125 RETURN NEW;
126 END IF;
127
128 INSERT INTO Daily_report(report_date, total_transactions, total_amount, branch_id)
129 VALUES (CURRENT_DATE, 1, NEW.amount, v_branch_id)
130 ON CONFLICT DO NOTHING;
131
132 UPDATE Daily_report
133 SET total_transactions = total_transactions + 1,
134 total_amount = total_amount + NEW.amount
135 WHERE report_date = CURRENT_DATE
136 AND branch_id = v_branch_id;
137 END IF;
138
139 RETURN NEW;
140END;
141$$ LANGUAGE plpgsql;
142
143DROP TRIGGER IF EXISTS trg_update_daily_report ON Transaction;
144
145CREATE TRIGGER trg_update_daily_report
146 AFTER INSERT OR UPDATE OF status
147 ON Transaction
148 FOR EACH ROW
149EXECUTE FUNCTION fn_update_daily_report();
150
151
152-- 5. Автоматско генерирање Receipt при COMPLETED трансакција
153CREATE OR REPLACE FUNCTION fn_auto_generate_receipt()
154 RETURNS TRIGGER AS
155$$
156DECLARE
157 v_receipt_number VARCHAR(30);
158BEGIN
159 IF NEW.status = 'COMPLETED'
160 AND (TG_OP = 'INSERT' OR OLD.status IS DISTINCT FROM 'COMPLETED') THEN
161
162 v_receipt_number := 'RCPT-' ||
163 TO_CHAR(NEW.transaction_date, 'YYYYMMDD') ||
164 '-' ||
165 LPAD(NEW.transaction_id::TEXT, 9, '0');
166
167 IF NOT EXISTS (SELECT 1
168 FROM Receipt
169 WHERE transaction_id = NEW.transaction_id) THEN
170 INSERT INTO Receipt(print_time, receipt_number, transaction_id)
171 VALUES (CURRENT_TIMESTAMP, v_receipt_number, NEW.transaction_id);
172 END IF;
173 END IF;
174
175 RETURN NEW;
176END;
177$$ LANGUAGE plpgsql;
178
179DROP TRIGGER IF EXISTS trg_auto_generate_receipt ON Transaction;
180
181CREATE TRIGGER trg_auto_generate_receipt
182 AFTER INSERT OR UPDATE OF status
183 ON Transaction
184 FOR EACH ROW
185EXECUTE FUNCTION fn_auto_generate_receipt();