-
Notifications
You must be signed in to change notification settings - Fork 144
/
is_correspondent_account.sql
68 lines (59 loc) · 2.59 KB
/
is_correspondent_account.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
create or replace function public.is_correspondent_account(
ks text, --к/с
bik text default null --если передан, то дополнительно в к/с происходит проверка контрольного числа по БИК
)
returns boolean
immutable
--returns null on null input
parallel safe
language plpgsql
set search_path = ''
cost 7
as
$func$
declare
digits int[];
checksum int not null default 0;
coefficients constant int[] not null default array[7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1];
i int default 1;
begin
--https://ru.wikipedia.org/wiki/Корреспондентский_счёт
--https://cbr.ru/na/385-p/ Положение Банка России «О правилах ведения бухгалтерского учета в кредитных организациях, расположенных на территории Российской Федерации» № 385-П от 16.07.2012
if ks is null then
return null;
elsif octet_length(ks) != 20
or ks !~ '^[034]\d+$'
or ks ~ '^([1-9])\1+$'
then
return false;
elsif bik is null then
return true;
elsif not public.is_bik(bik) then
return false;
end if;
--http://www.consultant.ru/document/cons_doc_LAW_16053/08c1d0eacf880db80ef56f68c3469e2ea24502d7/
digits := string_to_array('0' || substring(bik, 5, 2) || ks, null)::int[];
while coefficients[i] is not null
loop
checksum := checksum + coefficients[i] * (digits[i] % 10);
i := i + 1;
end loop;
return checksum % 10 = 0;
end;
$func$;
comment on function public.is_correspondent_account(ks text, bik text) is 'Проверяет, что переданная строка является корреспондентским счётом';
--TEST
DO $$
BEGIN
--positive
assert public.is_correspondent_account('40817810099910004312');
assert public.is_correspondent_account('30101810200000000827', '044030827');
assert public.is_correspondent_account('30101810400000000225', '044525225');
--negative
assert not public.is_correspondent_account('3010181020000000082');
assert not public.is_correspondent_account('301018102000000008270');
assert not public.is_correspondent_account('3014567890123456789*');
assert not public.is_correspondent_account('12345678901234567890');
assert not public.is_correspondent_account('30101810300000000827', '044030827');
assert not public.is_correspondent_account('30101810500000000225', '044525225');
END $$;