Онлайн-калькулятор расчёта пени:
MySQL-функция расчёта пени, в соответствии с учётной ставкой НБУ
CREATE DEFINER = 'username'@'localhost' FUNCTION `calc_fine_nbu`(
price FLOAT UNSIGNED, /* цена договора */
date_pay DATE, /* дата, когда должны оплатить */
date_paid DATE, /* дата фактической оплаты (можно указать сегодняшнюю, или NULL, что одно и то же) */
ratio FLOAT UNSIGNED /* коэффициент относительно учётной ставки НБУ. Например, для расчёта пени по двойной ставке НБУ -- следует установить параметр ratio в "2". */
)
RETURNS float(9,2)
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
DECLARE total_fine FLOAT UNSIGNED DEFAULT 0;
DECLARE prev_daily_fine FLOAT UNSIGNED DEFAULT 0;
DECLARE crate FLOAT UNSIGNED;
DECLARE prev_rate FLOAT UNSIGNED DEFAULT 0;
/* фиксим конечную дату */
DECLARE end_date DATE DEFAULT IF(date_paid IS NULL OR date_paid=0, CURRENT_DATE, date_paid) + INTERVAL 1 DAY;
/* получаем дату действующей учётной ставки в начале периода учёта пени */
DECLARE cdate DATE DEFAULT (SELECT date FROM rate_discount_nbu WHERE date<=date_pay AND date<=end_date ORDER BY date DESC LIMIT 1);
DECLARE l_end INT DEFAULT 0;
DECLARE cur1 CURSOR FOR
SELECT date,rate FROM rate_discount_nbu WHERE date>=cdate AND date<=end_date ORDER BY date;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET l_end = 1;
IF end_date < cdate THEN
RETURN 0; /* nothing to calculate */
END IF;
IF date_paid <= 0 OR date_paid IS NULL THEN
SET date_paid = CURRENT_DATE;
END IF;
IF ratio <= 0 OR ratio IS NULL THEN
SET ratio = 1;
END IF;
OPEN cur1;
REPEAT
FETCH cur1 INTO cdate,crate;
IF NOT l_end THEN
IF prev_rate > 0 THEN
SET total_fine = total_fine + total_fine + ((prev_rate * ratio) / 365 * price * DATEDIFF(cdate, date_pay) / 100);
SET date_pay = cdate;
END IF;
SET prev_rate = crate;
END IF;
UNTIL l_end END REPEAT;
CLOSE cur1;
IF prev_rate > 0 THEN
SET total_fine = total_fine + total_fine + ((prev_rate * ratio) / 365 * price * DATEDIFF(cdate, date_pay) / 100);
END IF;
RETURN total_fine;
END;
Табличка rate_discount_nbu -- список вида "date - rate".
Собственно, ниже приводится дамп таблицы, показывающий учётную ставку НБУ со времени обретения Украиной независимости до даты написания этой заметки.
> SELECT * FROM rate_discount_nbu
+----------+-------+
| date | rate |
+----------+-------+
| 25.06.92 | 30 |
| 16.11.92 | 80 |
| 01.03.93 | 100 |
| 01.05.93 | 240 |
| 01.07.94 | 190 |
| 01.08.94 | 175 |
| 15.08.94 | 140 |
| 25.10.94 | 300 |
| 12.12.94 | 252 |
| 10.03.95 | 204 |
| 29.03.95 | 170 |
| 07.04.95 | 150 |
| 01.05.95 | 96 |
| 07.06.95 | 75 |
| 15.07.95 | 60 |
| 21.08.95 | 70 |
| 10.10.95 | 95 |
| 01.12.95 | 110 |
| 01.01.96 | 105 |
| 04.03.96 | 98 |
| 26.03.96 | 90 |
| 01.04.96 | 85 |
| 08.04.96 | 75 |
| 25.04.96 | 70 |
| 22.05.96 | 63 |
| 07.06.96 | 50 |
| 02.07.96 | 40 |
| 10.01.97 | 35 |
| 08.03.97 | 25 |
| 26.05.97 | 21 |
| 08.07.97 | 18 |
| 05.08.97 | 16 |
| 01.11.97 | 17 |
| 15.11.97 | 25 |
| 24.11.97 | 35 |
| 06.02.98 | 44 |
| 18.03.98 | 41 |
| 21.05.98 | 45 |
| 29.05.98 | 51 |
| 07.07.98 | 82 |
| 21.12.98 | 60 |
| 05.04.99 | 57 |
| 28.04.99 | 50 |
| 24.05.99 | 45 |
| 01.02.00 | 35 |
| 24.03.00 | 32 |
| 10.04.00 | 29 |
| 15.08.00 | 27 |
| 10.03.01 | 25 |
| 07.04.01 | 21 |
| 11.06.01 | 19 |
| 09.08.01 | 17 |
| 10.09.01 | 15 |
| 10.12.01 | 12.5 |
| 11.03.02 | 11.5 |
| 04.04.02 | 10 |
| 05.07.02 | 8 |
| 05.12.02 | 7 |
| 09.06.04 | 7.5 |
| 07.10.04 | 8 |
| 09.11.04 | 9 |
| 10.08.05 | 9.5 |
| 10.06.06 | 8.5 |
| 01.06.07 | 8 |
| 01.01.08 | 10 |
| 30.04.08 | 12 |
| 15.06.09 | 11 |
| 12.08.09 | 10.25 |
| 08.06.10 | 9.5 |
| 08.07.10 | 8.5 |
| 10.08.10 | 7.75 |
| 23.03.12 | 7.5 |
| 10.06.13 | 7 |
| 13.08.13 | 6.5 |
| 15.04.14 | 9.5 |
| 17.07.14 | 12.5 |
+----------+-------+
Query OK.
Все учётные ставки НБУ со времени обретения Украиной независимости -- тут: http://www.bank.gov.ua/control/uk/publish/article?art_id=53647
|