Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 расчет пени  [new]
optimizer
Member

Откуда: НКР
Сообщений: 1029
добрый день. Делал расчет пеней следующим образом (ниже упрощенная вырезка), но изменилась постановка, и не получается придумать бескурсорный вариант.
Первоначальная постановка: для набора долгов и набора платежей получаю набор покрытия платежом долга, и соответственно их просрочка, а после уже и пени на просрочку.
declare @duty_objectless table(
			duty_id int,
			duty_date date,
			duty_amount decimal(18, 2),
			duty_cumul decimal(18, 2))
declare @payments_objectless table(
			pay_id int,
			pay_date date,
			pay_amount decimal(18, 2),
			pay_cumul decimal(18, 2))

insert into @duty_objectless (duty_id,  duty_date, duty_amount, duty_cumul)
select sd.duty_id, sd.duty_date, sd.duty_amount as duty_amount,
		sum(sd.duty_amount) over (order by sd.duty_date, sd.duty_id rows unbounded preceding)
from (select 1 as duty_id, '20130220' as duty_date, 100 as duty_amount
	  union all
	  select 2 as duty_id, '20130320' as duty_date, 50 as duty_amount
	  union all
	  select 3 as duty_id, '20130420' as duty_date, 30 as duty_amount) sd

insert into @payments_objectless (pay_id, pay_date, pay_amount, pay_cumul)
	select sp.pay_id, sp.pay_date, sp.pay_amount,
		sum(sp.pay_amount) over (order by sp.pay_date, sp.pay_id rows unbounded preceding)
from (select 1 as pay_id, '20130101' as pay_date, 90 as pay_amount
	  union all
	  select 2 as pay_id, '20130401' as pay_date, 20 as pay_amount
	  union all
	  select 3 as pay_id, '20130410' as pay_date, 50 as pay_amount) sp

declare @coverage_objectless table(
				duty_id int,
				pay_id int,
				coverage decimal(18, 2),
				pay_delay int)

insert into @coverage_objectless (duty_id, pay_id, coverage, pay_delay)
select duty_id, pay_id,
		case when duty_cumul < pay_cumul then duty_cumul else pay_cumul end -
		case when duty_cumul-duty_amount < pay_cumul-pay_amount then pay_cumul-pay_amount else duty_cumul-duty_amount end as coverage,
		DATEDIFF(day, duty_date, pay_date) as pay_delay
  from @duty_objectless 
  cross join @payments_objectless
 where case when duty_cumul < pay_cumul then duty_cumul else pay_cumul end -
		case when duty_cumul-duty_amount < pay_cumul-pay_amount then pay_cumul-pay_amount else duty_cumul-duty_amount end > 0

declare @rate90 decimal(18, 5)
declare @rate365 decimal(18, 5)
set @rate90 = 0.0075
set @rate365 = 0.01

select tt.*,
				case
					when tt.pay_delay >= 365 then 90 * @rate90 * tt.coverage + 275 * @rate365 * tt.coverage
					when tt.pay_delay > 90 and tt.pay_delay < 365 then 90 * @rate90 * tt.coverage + (tt.pay_delay - 90) * @rate365 * tt.coverage
					when tt.pay_delay > 0 and tt.pay_delay <= 90 then tt.pay_delay * @rate90 * tt.coverage 
					else 0
				end as fine
from (
-- 2.1 по оплаченным
select 2 as kind, cvr.duty_id, cvr.pay_id, cvr.coverage, cvr.pay_delay
from @coverage_objectless as cvr
) tt


Сейчас же надо пени не после считать, а при платеже гасить долги, и в этот момент рассчитать пени, и если остался излишек у текущего платежа, погасить им пени. Но сначала платеж гасит долги на текущий его момент, а потом пени.
14 окт 13, 16:57    [14968404]     Ответить | Цитировать Сообщить модератору
 Re: расчет пени  [new]
Добрый Э - Эх
Guest
чем такие портянки постить, лучше бы привел юзабильный набор репрезентативных тестовых данных и желаемый результат на них...
14 окт 13, 18:10    [14968901]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить