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

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