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

File procedures.sql, 9.4 KB (added by 231124, 12 hours ago)
Line 
1
2--======================================================================================================================
3-- PROCEDURES
4--======================================================================================================================
5
6--1.Трансфер во иста валута
7--Процедурата овозможува трансфер на средства помеѓу две сметки кои користат иста валута.
8-- Се проверува дали сметките се активни и дали има доволно средства за трансакцијата.
9-- По успешниот трансфер, автоматски се евидентира нова трансакција во системот.
10CREATE OR REPLACE PROCEDURE sp_transfer_same_currency(
11 p_amount DECIMAL(20, 2),
12 p_from_acc INT,
13 p_to_acc INT,
14 p_emp_counter INT
15)
16 LANGUAGE plpgsql AS
17$$
18DECLARE
19 v_ref VARCHAR(30);
20 v_type_id INT;
21 v_curr INT;
22BEGIN
23 IF NOT fn_is_account_eligible(p_from_acc)
24 OR NOT fn_is_account_eligible(p_to_acc) THEN
25 RAISE EXCEPTION 'Nevalidni smetki';
26 END IF;
27
28 IF (SELECT balance FROM Account WHERE account_id = p_from_acc) < p_amount THEN
29 RAISE EXCEPTION 'Nema dovolno sredstva';
30 END IF;
31
32 SELECT currency_id
33 INTO v_curr
34 FROM Account
35 WHERE account_id = p_from_acc;
36
37 IF v_curr != (SELECT currency_id
38 FROM Account
39 WHERE account_id = p_to_acc) THEN
40 RAISE EXCEPTION 'Valutite ne se isti';
41 END IF;
42
43 v_ref := 'TRX-' || TO_CHAR(NOW(), 'YYYYMMDDHH');
44
45 SELECT transaction_type_id
46 INTO v_type_id
47 FROM Transaction_type
48 WHERE type_name = 'TRANSFER';
49
50 UPDATE Account
51 SET balance = balance - p_amount
52 WHERE account_id = p_from_acc;
53
54 UPDATE Account
55 SET balance = balance + p_amount
56 WHERE account_id = p_to_acc;
57
58 INSERT INTO Transaction(amount, status, reference_number,
59 account_id, account_id2,
60 transaction_type_id,
61 currency_id, currency_id2,
62 emp_counter_id)
63 VALUES (p_amount, 'COMPLETED', v_ref,
64 p_from_acc, p_to_acc,
65 v_type_id,
66 v_curr, v_curr,
67 p_emp_counter);
68END;
69$$;
70
71CALL sp_transfer_same_currency(
72 100,
73 10360,
74 25132,
75 61735
76);
77
78SELECT account_id, balance
79FROM Account
80WHERE account_id IN (10360, 25132);
81
82
83
84
85--2.Трансфер со различни валути
86--Оваа процедура врши трансфер помеѓу сметки со различни валути. Пред префрлување на средствата,
87-- износот автоматски се конвертира преку функцијата fn_convert_currency.
88-- На крај се ажурираат салдата на двете сметки и се снима трансакцијата со соодветните валути.
89CREATE OR REPLACE PROCEDURE sp_transfer_foreign_currency(
90 p_amount DECIMAL(20, 2),
91 p_from_acc INT,
92 p_to_acc INT,
93 p_emp_counter INT
94)
95 LANGUAGE plpgsql AS
96$$
97DECLARE
98 v_from_curr INT;
99 v_to_curr INT;
100 v_ref VARCHAR(30);
101 v_type_id INT;
102 v_converted_amount DECIMAL(20,2);
103BEGIN
104 IF NOT fn_is_account_eligible(p_from_acc)
105 OR NOT fn_is_account_eligible(p_to_acc) THEN
106 RAISE EXCEPTION 'Nevalidni smetki';
107 END IF;
108
109 IF (SELECT balance FROM Account WHERE account_id = p_from_acc) < p_amount THEN
110 RAISE EXCEPTION 'Nema dovolno sredstva';
111 END IF;
112
113 SELECT currency_id
114 INTO v_from_curr
115 FROM Account
116 WHERE account_id = p_from_acc;
117
118 SELECT currency_id
119 INTO v_to_curr
120 FROM Account
121 WHERE account_id = p_to_acc;
122
123 v_converted_amount := fn_convert_currency(v_from_curr, v_to_curr, p_amount,'2026-04-12');
124
125 v_ref := 'TRX-' || TO_CHAR(NOW(), 'YYYYMMDDHH');
126
127 SELECT transaction_type_id
128 INTO v_type_id
129 FROM Transaction_type
130 WHERE type_name = 'TRANSFER';
131
132 UPDATE Account
133 SET balance = balance - p_amount
134 WHERE account_id = p_from_acc;
135
136 UPDATE Account
137 SET balance = balance + v_converted_amount
138 WHERE account_id = p_to_acc;
139
140 INSERT INTO Transaction(
141 amount,
142 status,
143 reference_number,
144 account_id,
145 account_id2,
146 transaction_type_id,
147 currency_id,
148 currency_id2,
149 emp_counter_id
150 )
151 VALUES (
152 v_converted_amount,
153 'COMPLETED',
154 v_ref,
155 p_from_acc,
156 p_to_acc,
157 v_type_id,
158 v_from_curr,
159 v_to_curr,
160 p_emp_counter
161 );
162END;
163$$;
164
165CALL sp_transfer_foreign_currency(
166 100,
167 66,
168 63,
169 61735
170);
171
172SELECT account_id, balance
173FROM Account
174WHERE account_id IN (66, 63);
175
176
177-- 3. Уплата на средства на сметка
178--Процедурата служи за уплата на средства на банкарска сметка. Покрај проверката дали сметката е активна,
179-- се креира запис за трансакцијата и се ажурира салдото на сметката.
180-- Дополнително, преку тригер автоматски се генерира и receipt за уплатата.
181CREATE OR REPLACE PROCEDURE sp_deposit(
182 p_account_id INT,
183 p_amount DECIMAL(20, 2),
184 p_currency_id INT,
185 p_payment_method INT,
186 p_emp_counter_id INT,
187 p_description VARCHAR DEFAULT 'Уплата на средства'
188)
189 LANGUAGE plpgsql AS
190$$
191DECLARE
192 v_deposit_type_id INT;
193 v_ref_number VARCHAR(30);
194 v_transaction_id INT;
195BEGIN
196
197 IF NOT fn_is_account_eligible(p_account_id) THEN
198 RAISE EXCEPTION 'Smetkata ne e aktivna';
199 END IF;
200
201 SELECT transaction_type_id
202 INTO v_deposit_type_id
203 FROM Transaction_type
204 WHERE type_name = 'DEPOSIT';
205
206 v_ref_number := 'TRX-' || LPAD(v_transaction_id::TEXT, 10, '0');
207
208 INSERT INTO Transaction (amount, transaction_date, status, description,
209 reference_number, account_id, transaction_type_id,
210 payment_method_id, currency_id, emp_counter_id)
211 VALUES (p_amount, CURRENT_TIMESTAMP, 'COMPLETED', p_description,
212 v_ref_number, p_account_id, v_deposit_type_id,
213 p_payment_method, p_currency_id, p_emp_counter_id)
214 RETURNING transaction_id INTO v_transaction_id;
215
216
217 UPDATE Account
218 SET balance = balance + p_amount
219 WHERE account_id = p_account_id;
220
221 RAISE NOTICE 'Уплатата е успешна. Transaction ID: %, Receipt автоматски генериран.', v_transaction_id;
222END;
223$$;
224
225CALL sp_deposit(18, 5000.00, 91, 1, 61735);
226
227SELECT *
228FROM Transaction
229WHERE account_id = 18
230ORDER BY transaction_id DESC
231LIMIT 1;
232
233
234
235-- 4. Исплата на средства од сметка
236--Оваа процедура овозможува исплата на средства од сметка.
237-- Системот најпрво проверува дали сметката е активна и дали има доволен баланс за исплата.
238-- По успешната трансакција, балансот се намалува и се евидентира нов запис во табелата Transaction.
239CREATE OR REPLACE PROCEDURE sp_withdraw(
240 p_account_id INT,
241 p_amount DECIMAL(20, 2),
242 p_currency_id INT,
243 p_payment_method INT,
244 p_emp_counter_id INT,
245 p_description VARCHAR DEFAULT 'Исплата на средства'
246)
247 LANGUAGE plpgsql AS
248$$
249DECLARE
250 v_withdrawal_type_id INT;
251 v_ref_number VARCHAR(30);
252 v_current_balance DECIMAL(20, 2);
253 v_transaction_id INT;
254BEGIN
255 IF NOT fn_is_account_eligible(p_account_id) THEN
256 RAISE EXCEPTION 'Сметката не е активна';
257 END IF;
258
259
260 SELECT balance
261 INTO v_current_balance
262 FROM Account
263 WHERE account_id = p_account_id;
264
265 IF v_current_balance < p_amount THEN
266 RAISE EXCEPTION 'Недоволен баланс: тековен=%, побаран=%.',
267 v_current_balance, p_amount;
268 END IF;
269
270 SELECT transaction_type_id
271 INTO v_withdrawal_type_id
272 FROM Transaction_type
273 WHERE type_name = 'WITHDRAWAL';
274
275 v_ref_number := 'TRX-' || TO_CHAR(CURRENT_TIMESTAMP, 'YYYYMMDDHH');
276
277 INSERT INTO Transaction (amount, transaction_date, status, description,
278 reference_number, account_id, transaction_type_id,
279 payment_method_id, currency_id, emp_counter_id)
280 VALUES (p_amount, CURRENT_TIMESTAMP, 'COMPLETED', p_description,
281 v_ref_number, p_account_id, v_withdrawal_type_id,
282 p_payment_method, p_currency_id, p_emp_counter_id)
283 RETURNING transaction_id INTO v_transaction_id;
284
285 UPDATE Account
286 SET balance = balance - p_amount
287 WHERE account_id = p_account_id;
288
289 RAISE NOTICE 'Исплатата е успешна. Transaction ID: %', v_transaction_id;
290END;
291$$;
292
293CALL sp_withdraw(18, 200.00, 91, 1, 61735);
294
295SELECT *
296FROM Transaction
297WHERE account_id = 18
298ORDER BY transaction_id DESC
299LIMIT 1;