| 1 |
|
|---|
| 2 | --======================================================================================================================
|
|---|
| 3 | -- PROCEDURES
|
|---|
| 4 | --======================================================================================================================
|
|---|
| 5 |
|
|---|
| 6 | --1.Трансфер во иста валута
|
|---|
| 7 | --Процедурата овозможува трансфер на средства помеѓу две сметки кои користат иста валута.
|
|---|
| 8 | -- Се проверува дали сметките се активни и дали има доволно средства за трансакцијата.
|
|---|
| 9 | -- По успешниот трансфер, автоматски се евидентира нова трансакција во системот.
|
|---|
| 10 | CREATE 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 | $$
|
|---|
| 18 | DECLARE
|
|---|
| 19 | v_ref VARCHAR(30);
|
|---|
| 20 | v_type_id INT;
|
|---|
| 21 | v_curr INT;
|
|---|
| 22 | BEGIN
|
|---|
| 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);
|
|---|
| 68 | END;
|
|---|
| 69 | $$;
|
|---|
| 70 |
|
|---|
| 71 | CALL sp_transfer_same_currency(
|
|---|
| 72 | 100,
|
|---|
| 73 | 10360,
|
|---|
| 74 | 25132,
|
|---|
| 75 | 61735
|
|---|
| 76 | );
|
|---|
| 77 |
|
|---|
| 78 | SELECT account_id, balance
|
|---|
| 79 | FROM Account
|
|---|
| 80 | WHERE account_id IN (10360, 25132);
|
|---|
| 81 |
|
|---|
| 82 |
|
|---|
| 83 |
|
|---|
| 84 |
|
|---|
| 85 | --2.Трансфер со различни валути
|
|---|
| 86 | --Оваа процедура врши трансфер помеѓу сметки со различни валути. Пред префрлување на средствата,
|
|---|
| 87 | -- износот автоматски се конвертира преку функцијата fn_convert_currency.
|
|---|
| 88 | -- На крај се ажурираат салдата на двете сметки и се снима трансакцијата со соодветните валути.
|
|---|
| 89 | CREATE 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 | $$
|
|---|
| 97 | DECLARE
|
|---|
| 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);
|
|---|
| 103 | BEGIN
|
|---|
| 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 | );
|
|---|
| 162 | END;
|
|---|
| 163 | $$;
|
|---|
| 164 |
|
|---|
| 165 | CALL sp_transfer_foreign_currency(
|
|---|
| 166 | 100,
|
|---|
| 167 | 66,
|
|---|
| 168 | 63,
|
|---|
| 169 | 61735
|
|---|
| 170 | );
|
|---|
| 171 |
|
|---|
| 172 | SELECT account_id, balance
|
|---|
| 173 | FROM Account
|
|---|
| 174 | WHERE account_id IN (66, 63);
|
|---|
| 175 |
|
|---|
| 176 |
|
|---|
| 177 | -- 3. Уплата на средства на сметка
|
|---|
| 178 | --Процедурата служи за уплата на средства на банкарска сметка. Покрај проверката дали сметката е активна,
|
|---|
| 179 | -- се креира запис за трансакцијата и се ажурира салдото на сметката.
|
|---|
| 180 | -- Дополнително, преку тригер автоматски се генерира и receipt за уплатата.
|
|---|
| 181 | CREATE 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 | $$
|
|---|
| 191 | DECLARE
|
|---|
| 192 | v_deposit_type_id INT;
|
|---|
| 193 | v_ref_number VARCHAR(30);
|
|---|
| 194 | v_transaction_id INT;
|
|---|
| 195 | BEGIN
|
|---|
| 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;
|
|---|
| 222 | END;
|
|---|
| 223 | $$;
|
|---|
| 224 |
|
|---|
| 225 | CALL sp_deposit(18, 5000.00, 91, 1, 61735);
|
|---|
| 226 |
|
|---|
| 227 | SELECT *
|
|---|
| 228 | FROM Transaction
|
|---|
| 229 | WHERE account_id = 18
|
|---|
| 230 | ORDER BY transaction_id DESC
|
|---|
| 231 | LIMIT 1;
|
|---|
| 232 |
|
|---|
| 233 |
|
|---|
| 234 |
|
|---|
| 235 | -- 4. Исплата на средства од сметка
|
|---|
| 236 | --Оваа процедура овозможува исплата на средства од сметка.
|
|---|
| 237 | -- Системот најпрво проверува дали сметката е активна и дали има доволен баланс за исплата.
|
|---|
| 238 | -- По успешната трансакција, балансот се намалува и се евидентира нов запис во табелата Transaction.
|
|---|
| 239 | CREATE 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 | $$
|
|---|
| 249 | DECLARE
|
|---|
| 250 | v_withdrawal_type_id INT;
|
|---|
| 251 | v_ref_number VARCHAR(30);
|
|---|
| 252 | v_current_balance DECIMAL(20, 2);
|
|---|
| 253 | v_transaction_id INT;
|
|---|
| 254 | BEGIN
|
|---|
| 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;
|
|---|
| 290 | END;
|
|---|
| 291 | $$;
|
|---|
| 292 |
|
|---|
| 293 | CALL sp_withdraw(18, 200.00, 91, 1, 61735);
|
|---|
| 294 |
|
|---|
| 295 | SELECT *
|
|---|
| 296 | FROM Transaction
|
|---|
| 297 | WHERE account_id = 18
|
|---|
| 298 | ORDER BY transaction_id DESC
|
|---|
| 299 | LIMIT 1;
|
|---|