DatabaseCreation: dml.2.sql

File dml.2.sql, 27.4 KB (added by 233088, 12 days ago)
Line 
1-- ==========================================================
2-- 1. STATIC BANK DATA
3-- ==========================================================
4
5INSERT INTO banka (banka_id, ime_na_banka, edb, datum_na_osnovanje)
6SELECT gs,
7 (ARRAY[
8 'Komercijalna Banka', 'Stopanska Banka', 'NLB Banka', 'Halkbank',
9 'Silk Road Bank', 'Sparkasse Bank', 'TTK Banka', 'Unibanka',
10 'Centralna Kooperativna Banka', 'ProCredit Bank'
11 ])[((gs - 1) % 10) + 1],
12 RIGHT('5' || LPAD(gs::text, 12, '0'), 13),
13 CURRENT_DATE - ((2000 + floor(random() * 13000))::int)
14FROM generate_series(1, 10) gs;
15
16INSERT INTO valuta (valuta_id, kod, ime, simbol)
17VALUES
18 (1, 'MKD', 'Makedonski denar', 'ден'),
19 (2, 'EUR', 'Euro', '€'),
20 (3, 'USD', 'US Dollar', '$'),
21 (4, 'CHF', 'Swiss Franc', 'CHF'),
22 (5, 'GBP', 'British Pound', '£');
23
24INSERT INTO kursna_lista (kurs_id, datum, kupoven_kurs, sreden_kurs, prodazen_kurs, valuta_od_id, valuta_do_id)
25WITH dates AS (
26 SELECT generate_series(CURRENT_DATE - INTERVAL '29 days', CURRENT_DATE, INTERVAL '1 day')::date AS datum
27), rates AS (
28 SELECT * FROM (VALUES
29 (2, 61.50::numeric),
30 (3, 56.70::numeric),
31 (4, 64.20::numeric),
32 (5, 72.10::numeric)
33 ) AS r(valuta_id, base_rate)
34), generated AS (
35 SELECT row_number() OVER (ORDER BY d.datum, r.valuta_id) AS kurs_id,
36 d.datum,
37 r.valuta_id,
38 r.base_rate + ((random() - 0.5) * 2)::numeric AS mid
39 FROM dates d
40 CROSS JOIN rates r
41)
42SELECT kurs_id,
43 datum,
44 round(mid - 0.25, 4),
45 round(mid, 4),
46 round(mid + 0.25, 4),
47 valuta_id,
48 1
49FROM generated;
50
51-- ==========================================================
52-- 2. USERS, ROLES AND PRIVILEGES
53-- ==========================================================
54
55INSERT INTO bank_user (user_id, username, password_hash, status)
56SELECT gs,
57 'user_' || gs,
58 md5('password_' || gs),
59 CASE WHEN gs % 20 = 0 THEN 'NEAKTIVEN' ELSE 'AKTIVEN' END
60FROM generate_series(1, 110000) gs;
61
62INSERT INTO role (role_id, ime)
63VALUES
64 (1, 'CLIENT'),
65 (2, 'EMPLOYEE'),
66 (3, 'ADMIN');
67
68INSERT INTO privilegii (privilegija_id, privilegija)
69VALUES
70 (1, 'VIEW_ACCOUNT'),
71 (2, 'CREATE_PAYMENT'),
72 (3, 'VIEW_TRANSACTIONS'),
73 (4, 'MANAGE_CLIENTS'),
74 (5, 'APPROVE_LOAN'),
75 (6, 'ADMIN_PANEL');
76
77INSERT INTO role_privilegii (role_id, privilegija_id)
78VALUES
79 (1, 1), (1, 2), (1, 3),
80 (2, 1), (2, 3), (2, 4), (2, 5),
81 (3, 1), (3, 2), (3, 3), (3, 4), (3, 5), (3, 6);
82
83INSERT INTO role_user (role_id, user_id)
84SELECT CASE
85 WHEN gs <= 100000 THEN 1
86 WHEN gs <= 110000 THEN 2
87 ELSE 3
88 END AS role_id,
89 gs AS user_id
90FROM generate_series(1, 110000) gs;
91
92-- ==========================================================
93-- 3. BRANCHES
94-- ==========================================================
95
96INSERT INTO filijala (filijala_id, ime, banka_id)
97SELECT gs,
98 'Filijala_' || gs || '_' ||
99 (ARRAY['Skopje','Bitola','Ohrid','Prilep','Tetovo','Kumanovo','Veles','Stip','Strumica','Gostivar'])[(gs % 10) + 1],
100 ((gs - 1) % 10) + 1
101FROM generate_series(1, 100) gs;
102
103-- ==========================================================
104-- 4. CLIENTS AND EMPLOYEES
105-- ==========================================================
106
107-- FIX: replace the old INSERT INTO klient block with this one.
108-- Reason: embg is UNIQUE, so the 3-digit final index must be unique inside each
109-- birth_date + city_code + gender group.
110
111INSERT INTO klient (klient_id, user_id, ime, prezime, datum_ragjanje, tatkovo_ime, embg)
112WITH person_raw AS (
113 SELECT gs,
114 CASE WHEN gs % 2 = 0 THEN 'M' ELSE 'F' END AS gender,
115 CASE WHEN gs % 2 = 0 THEN
116 (ARRAY['Aleksandar','Bojan','Stefan','Marko','Petar','Martin','David','Filip','Nikola','Krumislav','Vladimir','Andrej','Darko','Igor','Goran','Dejan','Mile','Tome','Antonio','Kristijan','Mihail','Damjan','Dimitar','Luka','Matej','Viktor','Daniel','Jovan'])[((gs * 7) % 28) + 1]
117 ELSE
118 (ARRAY['Sara','Ana','Marija','Elena','Ivana','Jovana','Kristina','Simona','Teodora','Angela','Mila','Tamara','Monika','Viktorija','Bojana','Katerina','Martina','Stefanija','Maja','Biljana','Aleksandra','Anastasija','Mia','Lara','Eva','Irena','Natalija'])[((gs * 7) % 27) + 1]
119 END AS ime,
120 CASE WHEN gs % 2 = 0 THEN
121 (ARRAY['Petrovski','Trajkovski','Stojanovski','Ristovski','Jovanovski','Nikolovski','Tasevski','Bojinovski','Mitrevski','Georgievski','Atanasovski','Kostovski','Dimitrovski','Popovski','Ilievski','Mladenovski','Kolevski','Naumovski','Kuzmanovski','Krstevski'])[((gs * 11) % 20) + 1]
122 ELSE
123 (ARRAY['Petrovska','Trajkovska','Stojanovska','Ristovska','Jovanovska','Nikolovska','Tasevska','Bojinovska','Mitrevska','Georgievska','Atanasovska','Kostovska','Dimitrovska','Popovska','Ilievska','Mladenovska','Kolevska','Naumovska','Kuzmanovska','Krstevska'])[((gs * 11) % 20) + 1]
124 END AS prezime,
125 (ARRAY['Aleksandar','Bojan','Stefan','Marko','Petar','Martin','David','Filip','Nikola','Vladimir','Andrej','Darko','Igor','Goran','Dejan'])[((gs * 13) % 15) + 1] AS tatkovo_ime,
126
127 -- deterministic birthdate instead of random, so distribution is stable
128 make_date(
129 (1946 + ((gs * 37) % 62))::int,
130 (1 + ((gs * 17) % 12))::int,
131 (1 + ((gs * 19) % 28))::int
132 ) AS birth_date,
133
134 (ARRAY['45','46','47','48','49','50','51','52','53','54'])[((gs * 23) % 10) + 1] AS city_code
135 FROM generate_series(1, 100000) gs
136), person AS (
137 SELECT *,
138 ROW_NUMBER() OVER (
139 PARTITION BY birth_date, city_code, gender
140 ORDER BY gs
141 ) AS embg_seq
142 FROM person_raw
143)
144SELECT gs,
145 gs,
146 ime,
147 prezime,
148 birth_date,
149 tatkovo_ime,
150 LPAD(EXTRACT(DAY FROM birth_date)::int::text, 2, '0') ||
151 LPAD(EXTRACT(MONTH FROM birth_date)::int::text, 2, '0') ||
152 LPAD((EXTRACT(YEAR FROM birth_date)::int % 1000)::text, 3, '0') ||
153 city_code ||
154 CASE WHEN gender = 'M' THEN '0' ELSE '5' END ||
155 LPAD(embg_seq::text, 3, '0') AS embg
156FROM person;
157
158-- Optional same fix for vraboten, because vraboten.embg is also UNIQUE.
159
160INSERT INTO vraboten (vraboten_id, user_id, ime, prezime, tatkovo_ime, datum_ragjanje, embg)
161WITH person_raw AS (
162 SELECT gs,
163 100000 + gs AS user_id,
164 CASE WHEN gs % 2 = 0 THEN 'M' ELSE 'F' END AS gender,
165 CASE WHEN gs % 2 = 0 THEN
166 (ARRAY['Aleksandar','Bojan','Stefan','Marko','Petar','Martin','David','Filip','Nikola','Krumislav','Vladimir','Andrej','Darko','Igor','Goran','Dejan','Mile','Tome','Antonio','Kristijan','Mihail','Damjan','Dimitar','Luka','Matej','Viktor','Daniel','Jovan'])[((gs * 7) % 28) + 1]
167 ELSE
168 (ARRAY['Sara','Ana','Marija','Elena','Ivana','Jovana','Kristina','Simona','Teodora','Angela','Mila','Tamara','Monika','Viktorija','Bojana','Katerina','Martina','Stefanija','Maja','Biljana','Aleksandra','Anastasija','Mia','Lara','Eva','Irena','Natalija'])[((gs * 7) % 27) + 1]
169 END AS ime,
170 CASE WHEN gs % 2 = 0 THEN
171 (ARRAY['Petrovski','Trajkovski','Stojanovski','Ristovski','Jovanovski','Nikolovski','Tasevski','Bojinovski','Mitrevski','Georgievski','Atanasovski','Kostovski','Dimitrovski','Popovski','Ilievski','Mladenovski','Kolevski','Naumovski','Kuzmanovski','Krstevski'])[((gs * 11) % 20) + 1]
172 ELSE
173 (ARRAY['Petrovska','Trajkovska','Stojanovska','Ristovska','Jovanovska','Nikolovska','Tasevska','Bojinovska','Mitrevska','Georgievska','Atanasovska','Kostovska','Dimitrovska','Popovska','Ilievska','Mladenovska','Kolevska','Naumovska','Kuzmanovska','Krstevska'])[((gs * 11) % 20) + 1]
174 END AS prezime,
175 (ARRAY['Aleksandar','Bojan','Stefan','Marko','Petar','Martin','David','Filip','Nikola','Vladimir','Andrej','Darko','Igor','Goran','Dejan'])[((gs * 13) % 15) + 1] AS tatkovo_ime,
176 make_date(
177 (1961 + ((gs * 37) % 44))::int,
178 (1 + ((gs * 17) % 12))::int,
179 (1 + ((gs * 19) % 28))::int
180 ) AS birth_date,
181 (ARRAY['45','46','47','48','49','50','51','52','53','54'])[((gs * 23) % 10) + 1] AS city_code
182 FROM generate_series(1, 10000) gs
183), person AS (
184 SELECT *,
185 ROW_NUMBER() OVER (
186 PARTITION BY birth_date, city_code, gender
187 ORDER BY gs
188 ) AS embg_seq
189 FROM person_raw
190)
191SELECT gs,
192 user_id,
193 ime,
194 prezime,
195 tatkovo_ime,
196 birth_date,
197 LPAD(EXTRACT(DAY FROM birth_date)::int::text, 2, '0') ||
198 LPAD(EXTRACT(MONTH FROM birth_date)::int::text, 2, '0') ||
199 LPAD((EXTRACT(YEAR FROM birth_date)::int % 1000)::text, 3, '0') ||
200 city_code ||
201 CASE WHEN gender = 'M' THEN '0' ELSE '5' END ||
202 LPAD(embg_seq::text, 3, '0') AS embg
203FROM person;
204
205INSERT INTO raboti_vo (vraboten_id, filijala_id, raboti_od, raboti_do)
206SELECT gs,
207 ((gs - 1) % 100) + 1,
208 CURRENT_DATE - ((30 + floor(random() * 2970))::int),
209 NULL
210FROM generate_series(1, 10000) gs;
211
212-- ==========================================================
213-- 5. CONTACT DATA
214-- FIXED V3: no UNION ALL is used in contact data.
215-- This avoids PostgreSQL UNION type resolution errors completely.
216-- ==========================================================
217
218-- TELEFON: clients
219INSERT INTO telefon (telefon_id, telefonski_broj, tip_telefon, klient_id, vraboten_id, banka_id, filijala_id)
220SELECT gs::int,
221 ('+3897' || ((gs % 8) + 1)::text || LPAD(gs::text, 6, '0'))::varchar(20),
222 'MOBILEN'::varchar(50),
223 gs::int,
224 NULL::int,
225 NULL::int,
226 NULL::int
227FROM generate_series(1, 100000) AS gs;
228
229-- TELEFON: employees
230INSERT INTO telefon (telefon_id, telefonski_broj, tip_telefon, klient_id, vraboten_id, banka_id, filijala_id)
231SELECT (100000 + gs)::int,
232 ('+3892' || (200000 + gs)::text)::varchar(20),
233 'SLUZBEN'::varchar(50),
234 NULL::int,
235 gs::int,
236 NULL::int,
237 NULL::int
238FROM generate_series(1, 10000) AS gs;
239
240-- TELEFON: banks
241INSERT INTO telefon (telefon_id, telefonski_broj, tip_telefon, klient_id, vraboten_id, banka_id, filijala_id)
242SELECT (110000 + gs)::int,
243 ('+3892' || (300000 + gs)::text)::varchar(20),
244 'CENTRALA'::varchar(50),
245 NULL::int,
246 NULL::int,
247 gs::int,
248 NULL::int
249FROM generate_series(1, 10) AS gs;
250
251-- TELEFON: branches
252INSERT INTO telefon (telefon_id, telefonski_broj, tip_telefon, klient_id, vraboten_id, banka_id, filijala_id)
253SELECT (110010 + gs)::int,
254 ('+3892' || (400000 + gs)::text)::varchar(20),
255 'FILIJALA'::varchar(50),
256 NULL::int,
257 NULL::int,
258 NULL::int,
259 gs::int
260FROM generate_series(1, 100) AS gs;
261
262-- EMAIL: clients
263INSERT INTO email (email_id, email, tip_email, klient_id, vraboten_id, banka_id, filijala_id)
264SELECT k.klient_id::int,
265 lower(k.ime || '.' || k.prezime || k.klient_id || CASE WHEN k.klient_id % 2 = 0 THEN '@gmail.com' ELSE '@yahoo.com' END)::varchar(100),
266 'LICEN'::varchar(50),
267 k.klient_id::int,
268 NULL::int,
269 NULL::int,
270 NULL::int
271FROM klient k;
272
273-- EMAIL: employees
274INSERT INTO email (email_id, email, tip_email, klient_id, vraboten_id, banka_id, filijala_id)
275SELECT (100000 + v.vraboten_id)::int,
276 lower(v.ime || '.' || v.prezime || v.vraboten_id || '@bank.mk')::varchar(100),
277 'SLUZBEN'::varchar(50),
278 NULL::int,
279 v.vraboten_id::int,
280 NULL::int,
281 NULL::int
282FROM vraboten v;
283
284-- EMAIL: banks
285INSERT INTO email (email_id, email, tip_email, klient_id, vraboten_id, banka_id, filijala_id)
286SELECT (110000 + gs)::int,
287 ('contact' || gs || '@bank.mk')::varchar(100),
288 'KONTAKT'::varchar(50),
289 NULL::int,
290 NULL::int,
291 gs::int,
292 NULL::int
293FROM generate_series(1, 10) AS gs;
294
295-- EMAIL: branches
296INSERT INTO email (email_id, email, tip_email, klient_id, vraboten_id, banka_id, filijala_id)
297SELECT (110010 + gs)::int,
298 ('branch' || gs || '@bank.mk')::varchar(100),
299 'FILIJALA'::varchar(50),
300 NULL::int,
301 NULL::int,
302 NULL::int,
303 gs::int
304FROM generate_series(1, 100) AS gs;
305
306-- ADRESA: clients
307INSERT INTO adresa (adresa_id, drzava, grad, opstina, naselba, ulica, broj, stanben_broj, tip_adresa, klient_id, vraboten_id, banka_id, filijala_id)
308SELECT gs::int,
309 'Makedonija'::varchar(100),
310 (ARRAY['Skopje','Bitola','Ohrid','Prilep','Tetovo','Kumanovo','Veles','Stip','Strumica','Gostivar'])[(gs % 10) + 1]::varchar(100),
311 (ARRAY['Centar','Karposh','Aerodrom','Gazi Baba','Kisela Voda','Chair','Bitola','Ohrid','Prilep','Tetovo'])[(gs % 10) + 1]::varchar(100),
312 (ARRAY['Debar Maalo','Kapistec','Karposh 1','Novo Lisiche','Avtokomanda','Bair','Varosh','Dva Bresta','Senjak','Bansko'])[(gs % 10) + 1]::varchar(100),
313 (ARRAY['Partizanska','Ilindenska','Makedonija','Vodnjanska','Dame Gruev','Jane Sandanski','ASNOM','Goce Delcev','11 Oktomvri','Orce Nikolov','Boris Trajkovski','Krste Misirkov','Kuzman Josifovski Pitu'])[(gs % 13) + 1]::varchar(150),
314 ((gs % 200) + 1)::text::varchar(20),
315 ((gs % 40) + 1)::text::varchar(20),
316 'KLIENT'::varchar(50),
317 gs::int,
318 NULL::int,
319 NULL::int,
320 NULL::int
321FROM generate_series(1, 100000) AS gs;
322
323-- ADRESA: employees
324INSERT INTO adresa (adresa_id, drzava, grad, opstina, naselba, ulica, broj, stanben_broj, tip_adresa, klient_id, vraboten_id, banka_id, filijala_id)
325SELECT (100000 + gs)::int,
326 'Makedonija'::varchar(100),
327 (ARRAY['Skopje','Bitola','Ohrid','Prilep','Tetovo','Kumanovo','Veles','Stip','Strumica','Gostivar'])[(gs % 10) + 1]::varchar(100),
328 (ARRAY['Centar','Karposh','Aerodrom','Gazi Baba','Kisela Voda','Chair','Bitola','Ohrid','Prilep','Tetovo'])[(gs % 10) + 1]::varchar(100),
329 (ARRAY['Debar Maalo','Kapistec','Karposh 1','Novo Lisiche','Avtokomanda','Bair','Varosh','Dva Bresta','Senjak','Bansko'])[(gs % 10) + 1]::varchar(100),
330 (ARRAY['Partizanska','Ilindenska','Makedonija','Vodnjanska','Dame Gruev','Jane Sandanski','ASNOM','Goce Delcev','11 Oktomvri','Orce Nikolov','Boris Trajkovski','Krste Misirkov','Kuzman Josifovski Pitu'])[(gs % 13) + 1]::varchar(150),
331 ((gs % 200) + 1)::text::varchar(20),
332 ((gs % 40) + 1)::text::varchar(20),
333 'VRABOTEN'::varchar(50),
334 NULL::int,
335 gs::int,
336 NULL::int,
337 NULL::int
338FROM generate_series(1, 10000) AS gs;
339
340-- ADRESA: banks
341INSERT INTO adresa (adresa_id, drzava, grad, opstina, naselba, ulica, broj, stanben_broj, tip_adresa, klient_id, vraboten_id, banka_id, filijala_id)
342SELECT (110000 + gs)::int,
343 'Makedonija'::varchar(100),
344 (ARRAY['Skopje','Bitola','Ohrid','Prilep','Tetovo','Kumanovo','Veles','Stip','Strumica','Gostivar'])[(gs % 10) + 1]::varchar(100),
345 (ARRAY['Centar','Karposh','Aerodrom','Gazi Baba','Kisela Voda','Chair','Bitola','Ohrid','Prilep','Tetovo'])[(gs % 10) + 1]::varchar(100),
346 (ARRAY['Debar Maalo','Kapistec','Karposh 1','Novo Lisiche','Avtokomanda','Bair','Varosh','Dva Bresta','Senjak','Bansko'])[(gs % 10) + 1]::varchar(100),
347 (ARRAY['Partizanska','Ilindenska','Makedonija','Vodnjanska','Dame Gruev','Jane Sandanski','ASNOM','Goce Delcev','11 Oktomvri','Orce Nikolov','Boris Trajkovski','Krste Misirkov','Kuzman Josifovski Pitu'])[(gs % 13) + 1]::varchar(150),
348 ((gs % 200) + 1)::text::varchar(20),
349 ((gs % 40) + 1)::text::varchar(20),
350 'BANKA'::varchar(50),
351 NULL::int,
352 NULL::int,
353 gs::int,
354 NULL::int
355FROM generate_series(1, 10) AS gs;
356
357-- ADRESA: branches
358INSERT INTO adresa (adresa_id, drzava, grad, opstina, naselba, ulica, broj, stanben_broj, tip_adresa, klient_id, vraboten_id, banka_id, filijala_id)
359SELECT (110010 + gs)::int,
360 'Makedonija'::varchar(100),
361 (ARRAY['Skopje','Bitola','Ohrid','Prilep','Tetovo','Kumanovo','Veles','Stip','Strumica','Gostivar'])[(gs % 10) + 1]::varchar(100),
362 (ARRAY['Centar','Karposh','Aerodrom','Gazi Baba','Kisela Voda','Chair','Bitola','Ohrid','Prilep','Tetovo'])[(gs % 10) + 1]::varchar(100),
363 (ARRAY['Debar Maalo','Kapistec','Karposh 1','Novo Lisiche','Avtokomanda','Bair','Varosh','Dva Bresta','Senjak','Bansko'])[(gs % 10) + 1]::varchar(100),
364 (ARRAY['Partizanska','Ilindenska','Makedonija','Vodnjanska','Dame Gruev','Jane Sandanski','ASNOM','Goce Delcev','11 Oktomvri','Orce Nikolov','Boris Trajkovski','Krste Misirkov','Kuzman Josifovski Pitu'])[(gs % 13) + 1]::varchar(150),
365 ((gs % 200) + 1)::text::varchar(20),
366 ((gs % 40) + 1)::text::varchar(20),
367 'FILIJALA'::varchar(50),
368 NULL::int,
369 NULL::int,
370 NULL::int,
371 gs::int
372FROM generate_series(1, 100) AS gs;
373
374-- ==========================================================
375-- 6. SERVICES, CREDITS, CONTRACTS
376-- ==========================================================
377
378INSERT INTO usluga (usluga_id, ime, opis, datum_od, datum_do, tip_usluga, status, banka_id, filijala_id)
379SELECT gs,
380 'Usluga_' || gs,
381 'Opis za usluga ' || gs,
382 CURRENT_DATE - ((100 + floor(random() * 1900))::int),
383 NULL,
384 (ARRAY['SMETKA','KREDIT','DEPOZIT','KARTICKA','ONLINE_BANKING'])[(gs % 5) + 1],
385 'AKTIVNA',
386 ((((gs - 1) % 100)) % 10) + 1,
387 ((gs - 1) % 100) + 1
388FROM generate_series(1, 500) gs;
389
390INSERT INTO tip_kredit (tip_kredit_id, tip, opis)
391VALUES
392 (1, 'Stanben kredit', 'Kredit za stan'),
393 (2, 'Potrosuvacki kredit', 'Gotovinski kredit'),
394 (3, 'Avto kredit', 'Kredit za vozilo'),
395 (4, 'Studentski kredit', 'Kredit za studenti');
396
397INSERT INTO kredit (kredit_id, kamatna_stapka, rok_otplata, iznos_kredit, mesecna_rata, tip_kredit_id, usluga_id, valuta_id)
398WITH base AS (
399 SELECT gs,
400 round((500 + random() * 99500)::numeric, 2) AS principal,
401 (ARRAY[12,24,36,48,60,84,120,240,360])[(floor(random()*9)::int)+1] AS months,
402 round((2.5 + random() * 7)::numeric, 2) AS rate
403 FROM generate_series(1, 50000) gs
404)
405SELECT gs,
406 rate,
407 months,
408 principal,
409 round((principal / months) * (1 + rate / 100), 2),
410 ((gs - 1) % 4) + 1,
411 ((gs - 1) % 500) + 1,
412 ((gs - 1) % 5) + 1
413FROM base;
414
415INSERT INTO dogovor (dogovor_id, naslov, datum_kreiranje, datum_posledna_promena, datum_potpisuvanje, status, klient_id, banka_id, usluga_id, filijala_id)
416WITH base AS (
417 SELECT gs,
418 CURRENT_DATE - (floor(random() * 2500)::int) AS created,
419 (ARRAY['KREIRAN','POTPISAN','POTPISAN','POTPISAN','OTKAZAN','ISTECEN'])[(floor(random()*6)::int)+1] AS status,
420 ((gs - 1) % 500) + 1 AS usluga_id,
421 ((gs - 1) % 100) + 1 AS filijala_id
422 FROM generate_series(1, 120000) gs
423)
424SELECT gs,
425 'Dogovor za bankarska usluga - ' || EXTRACT(YEAR FROM created)::int || '/' || LPAD(gs::text, 6, '0'),
426 created,
427 created + (floor(random() * 30)::int),
428 CASE WHEN status = 'KREIRAN' THEN NULL ELSE created + (floor(random() * 20)::int) END,
429 status,
430 ((gs - 1) % 100000) + 1,
431 ((filijala_id - 1) % 10) + 1,
432 usluga_id,
433 filijala_id
434FROM base;
435
436INSERT INTO potpisnik (potpisnik_id, datum_potpisuvanje, klient_id, dogovor_id)
437SELECT gs,
438 CURRENT_DATE - (floor(random() * 2000)::int),
439 ((gs - 1) % 100000) + 1,
440 gs
441FROM generate_series(1, 120000) gs;
442
443-- ==========================================================
444-- 7. ACCOUNTS, DEPOSITS AND CARDS
445-- ==========================================================
446
447INSERT INTO smetka (smetka_id, broj_smetka, datum_otvaranje, status, tip_smetka, usluga_id, klient_id, kredit_id, banka_id, valuta_id, saldo)
448WITH base AS (
449 SELECT gs,
450 CASE
451 WHEN random() < 0.62 THEN 'TEKOVNA'
452 WHEN random() < 0.85 THEN 'DEVIZNA'
453 ELSE 'STEDNA'
454 END AS tip_smetka,
455 CASE
456 WHEN random() < 0.88 THEN 'AKTIVNA'
457 WHEN random() < 0.96 THEN 'BLOKIRANA'
458 ELSE 'ZATVORENA'
459 END AS status
460 FROM generate_series(1, 250000) gs
461), enriched AS (
462 SELECT gs,
463 tip_smetka,
464 status,
465 CASE
466 WHEN tip_smetka = 'TEKOVNA' THEN CASE WHEN random() < 0.92 THEN 1 ELSE 2 + floor(random()*4)::int END
467 WHEN tip_smetka = 'DEVIZNA' THEN 2 + floor(random()*4)::int
468 ELSE CASE WHEN random() < 0.65 THEN 1 ELSE 2 + floor(random()*4)::int END
469 END AS valuta_id
470 FROM base
471)
472SELECT gs,
473 RIGHT('300000000000' || LPAD(gs::text, 8, '0'), 20),
474 CURRENT_DATE - (floor(random() * 3000)::int),
475 status,
476 tip_smetka,
477 ((gs - 1) % 500) + 1,
478 ((gs - 1) % 100000) + 1,
479 CASE WHEN gs % 5 = 0 THEN ((gs - 1) % 50000) + 1 ELSE NULL END,
480 ((gs - 1) % 10) + 1,
481 valuta_id,
482 CASE
483 WHEN status = 'ZATVORENA' THEN round((random() * 100)::numeric, 2)
484 WHEN status = 'BLOKIRANA' AND random() < 0.25 THEN round((-100 - random() * 24900)::numeric, 2)
485 WHEN tip_smetka = 'TEKOVNA' AND valuta_id = 1 THEN round((500 + random() * 349500)::numeric, 2)
486 WHEN tip_smetka = 'TEKOVNA' THEN round((20 + random() * 7980)::numeric, 2)
487 WHEN tip_smetka = 'DEVIZNA' THEN round((50 + random() * 29950)::numeric, 2)
488 WHEN tip_smetka = 'STEDNA' AND valuta_id = 1 THEN round((10000 + random() * 1490000)::numeric, 2)
489 ELSE round((200 + random() * 79800)::numeric, 2)
490 END AS saldo
491FROM enriched;
492
493INSERT INTO depozit (depozit_id, iznos_depozit, rok_depozit, kamatna_stapka, datum_odobruvanje, datum_aktiviranje, momentalna_sostojba, tip_depozit, usluga_id, smetka_id, valuta_id)
494WITH base AS (
495 SELECT gs,
496 round((100 + random() * 99900)::numeric, 2) AS dep,
497 CURRENT_DATE - ((1 + floor(random() * 2000))::int) AS approved
498 FROM generate_series(1, 70000) gs
499)
500SELECT gs,
501 dep,
502 (ARRAY[3,6,12,24,36,60])[(floor(random()*6)::int)+1],
503 round((0.5 + random() * 5)::numeric, 2),
504 approved,
505 approved + (floor(random() * 10)::int),
506 round((dep * (1.0 + random() * 0.2))::numeric, 2),
507 (ARRAY['OROCEN','VIDEN','STEDEN'])[(gs % 3) + 1],
508 ((gs - 1) % 500) + 1,
509 ((gs - 1) % 250000) + 1,
510 ((gs - 1) % 5) + 1
511FROM base;
512
513INSERT INTO tip_karticka (tip_karticka_id, ime, opis)
514VALUES
515 (1, 'Debitna', 'Debitna karticka'),
516 (2, 'Kreditna', 'Kreditna karticka'),
517 (3, 'Prepaid', 'Prepaid karticka');
518
519INSERT INTO karticka (karticka_id, broj_karticka, datum_izdavanje, datum_istekuvanje, cvc_kod, status, smetka_id, tip_karticka_id)
520WITH base AS (
521 SELECT gs,
522 CURRENT_DATE - (floor(random() * 1500)::int) AS issued
523 FROM generate_series(1, 180000) gs
524)
525SELECT gs,
526 RIGHT('4' || LPAD(gs::text, 15, '0'), 16),
527 issued,
528 issued + (365 * (ARRAY[3,4,5])[(floor(random()*3)::int)+1]),
529 LPAD((gs % 1000)::text, 3, '0'),
530 CASE WHEN gs % 100 = 0 THEN 'BLOKIRANA' ELSE 'AKTIVNA' END,
531 ((gs - 1) % 250000) + 1,
532 ((gs - 1) % 3) + 1
533FROM base;
534
535-- ==========================================================
536-- 8. NOTIFICATIONS
537-- ==========================================================
538
539INSERT INTO izvestuvanje (izvestuvanje_id, naslov, poraka, datum_isprakjanje, klient_id, banka_id)
540SELECT gs,
541 (ARRAY[
542 'Uspesna transakcija', 'Priliv na smetka', 'Potsetnik za rata', 'Nisko saldo',
543 'Promena na kursna lista', 'Nova bankarska ponuda', 'Bezbednosno izvestuvanje',
544 'Karticka pred istek', 'Blokirana karticka', 'Potpisuvanje dogovor',
545 'Promena na status', 'Izvod dostapen'
546 ])[(floor(random()*12)::int)+1],
547 'Avtomatsko bankarsko izvestuvanje za klientot. Iznos: ' || round((100 + random()*150000)::numeric, 2)::text || ' MKD.',
548 CURRENT_DATE - (floor(random() * 1000)::int),
549 ((gs - 1) % 100000) + 1,
550 ((gs - 1) % 10) + 1
551FROM generate_series(1, 500000) gs;
552
553-- ==========================================================
554-- 9. PAYMENT ORDERS AND TRANSACTIONS
555-- ==========================================================
556
557INSERT INTO nalog (
558 nalog_id, datum_na_valuta, povikuvanje_na_broj_odobruvanje, iznos,
559 danocen_broj_embg, svrha_na_plakjanje, smetka_primalac_id, cel_na_doznaka,
560 hitno, uplateno_mesto, smetka_na_budetski_korisnik_edinka_korisnik,
561 prihodna_sifra, programa, nacin_plakjanje, nalogodavac_id,
562 danocen_broj_primalac, smetka_nalogodavac_id, smetka_nalogoprimac_id,
563 smetka_nalogoprimac, valuta_id, potpisnik_id
564)
565WITH base AS (
566 SELECT gs,
567 ((gs - 1) % 250000) + 1 AS from_acc_id,
568 -- Користиме модуло со поместување за да не биде истата сметка
569 ((gs + 12345) % 250000) + 1 AS to_acc_id,
570 (10 + (random() * 20000))::numeric AS amount,
571 CURRENT_DATE - (floor(random() * 730))::int AS val_date
572 FROM generate_series(1, 1000000) gs -- Оптимално 1 милион за тест во Фаза 4
573)
574SELECT gs,
575 val_date,
576 'REF-' || gs || '-' || EXTRACT(YEAR FROM val_date),
577 round(amount, 2),
578 'EMBG' || LPAD(((gs % 100000) + 1)::text, 9, '0'),
579 'Plakjanje na usluga/faktura br.' || gs,
580 to_acc_id,
581 'Transfer na sredstva',
582 (gs % 10 = 0), -- на секој 10-ти налог е итен
583 'Skopje, Filijala ' || ((gs % 100) + 1),
584 NULL, NULL, NULL, -- Буџетски полиња
585 'PP30',
586 ((gs - 1) % 100000) + 1,
587 'EDB' || LPAD(((gs % 50000) + 1)::text, 10, '0'),
588 from_acc_id,
589 to_acc_id,
590 'MK30000' || LPAD(to_acc_id::text, 10, '0'),
591 ((gs - 1) % 5) + 1,
592 ((gs - 1) % 120000) + 1
593FROM base;
594
595-- Генерирање на трансакции директно од налозите
596INSERT INTO transakcija (transakcija_id, datum_transakcija, vreme_izvrsena, iznos, status, smetka_isprakjac_id, smetka_primac_id, nalog_id, valuta_id)
597SELECT nalog_id,
598 datum_na_valuta,
599 (CURRENT_TIME - (random() * interval '20 hours')),
600 iznos,
601 'ZAVRSENA',
602 smetka_nalogodavac_id,
603 smetka_nalogoprimac_id,
604 nalog_id,
605 valuta_id
606FROM nalog;
607
608-- ==========================================================
609-- LOAN REPAYMENTS (RATA_KREDIT)
610-- ==========================================================
611
612INSERT INTO rata_kredit (rata_kredit_id, iznos_rata, datum_dospevanje, datum_plakjanje, status_rata, kredit_id, transakcija_id)
613SELECT gs,
614 k.mesecna_rata,
615 k.created_at + (interval '1 month' * ((gs - 1) % 12 + 1)),
616 CASE WHEN random() < 0.9 THEN k.created_at + (interval '1 month' * ((gs - 1) % 12 + 1)) ELSE NULL END,
617 CASE WHEN random() < 0.9 THEN 'PLATENA' ELSE 'NEDOSPENA' END,
618 k.kredit_id,
619 CASE WHEN random() < 0.9 THEN ((gs - 1) % 1000000) + 1 ELSE NULL END
620FROM (
621 SELECT kr.kredit_id, kr.mesecna_rata, u.datum_od as created_at
622 FROM kredit kr
623 JOIN usluga u ON kr.usluga_id = u.usluga_id
624 LIMIT 50000
625) k
626CROSS JOIN generate_series(1, 12) gs; -- Генерираме 12 рати за секој кредит