Craig
Craig

Reputation: 18694

Table driven payment schedule

My Payment Schedule holds a row for a payment schedule that gets run on a specific day, based on an 'effective date'.

CREATE TABLE [dbo].[PaymentSchedule] (
    [PaymentScheduleId] INT  IDENTITY (1, 1) NOT NULL,
    [EffectiveDate]     DATE NOT NULL,
    [EffectiveDays]     INT  NOT NULL,
    CONSTRAINT [pk_PaymentSchedule] PRIMARY KEY CLUSTERED ([PaymentScheduleId] ASC)
);

So, if the effectivedate is '01-JAN-2013', and the 'EffectiveDays' is 7, then payment get made on the 1st of January, and then every 7 days after that. So, on the 8th of January, a payment must be made. On the 15th, a payment must be made.. etc etc.

If the effectivedate was '01-JAN-2013', and the EffectiveDays was 20, then the first payment is the 1st of Jan, the next payment day is the 21th of Jan, and the next after that would be 9th Feb, 2013.. etc etc.

What I am trying to do, is make a function that uses the above table, or a stored proc for that matter, that returns 'Next Payment Date', and takes in a DATE type. So, based on the date passed in, what is the next payment date? And also, 'Is today a payment date'.

Can this be done efficiently? In 7 years time, would I be able to tell if a date is a payment day, for example?

Upvotes: 3

Views: 243

Answers (3)

Danny D
Danny D

Reputation: 52

I may be answering the wrong question, but I think the following code returns payment schedules that hit the selected payment date, if that's what you're looking for?

IF OBJECT_ID('tempdb..#PaymentSchedules') IS NOT NULL
    DROP TABLE #PaymentSchedules;

CREATE TABLE #PaymentSchedules
( PaymentScheduleID INT NOT NULL IDENTITY(1,1)
  CONSTRAINT PK_PaymentSchedules_PaymentScheduleID PRIMARY KEY
, EffectiveDate DATE NOT NULL
, EffectiveDays INT NOT NULL )
;

INSERT #PaymentSchedules (EffectiveDate, EffectiveDays)
VALUES
  ('20120401', 3)
, ('20120401', 2)
, ('20120401', 1)
, ('20120401', 7)
, ('20120401', 14)
;

DECLARE @PaymentDate DATE = '20140310';

WITH myCTE AS
(
  SELECT PaymentScheduleID, PaymentDate = EffectiveDate, EffectiveDays
  FROM #PaymentSchedules
  UNION ALL
  SELECT PaymentScheduleID, PaymentDate = DATEADD(DAY, EffectiveDays, PaymentDate), EffectiveDays
  FROM myCTE
  WHERE DATEADD(DAY, EffectiveDays, PaymentDate) <= @PaymentDate
)

SELECT * FROM myCTE
WHERE PaymentDate = @PaymentDate
OPTION (MAXRECURSION 10000)
;

Upvotes: 0

Gordon Linoff
Gordon Linoff

Reputation: 1269753

Your description of the problem is wrong. If the first payment is on Jan 1, the subsequent payments would be on the Jan 8, Jan 15 and so on.

The answer to your question about the current date is datediff() along with the modulus operator. To see if today is a payment date, take the difference and see if it is an exact multiple of the period you are looking at:

select getdate()
from PaymentSchedule ps
where datediff(day, ps.EffectiveDate, getdate()) % ps.EffectiveDays = 0;

The % is the modulus operator that takes the remainder between two values. So, 3%2 is 1 and 10%5 is 0.

For the next date, the answer is similar:

select dateadd(day,
               ps.EffectiveDays - datediff(day, ps.EffectiveDate, today) % ps.EffectiveDays,
               today) as NextDate
from PaymentSchedule ps cross join
     (select cast(getdate() as date) as today) const

I've structured this as a subquery that defines the current date as today. This makes it easier to substitute in any other date that you might want.

Upvotes: 1

Sergio Lema
Sergio Lema

Reputation: 1629

You can use the method DATEDIFF(datepart, startdate, enddate) setting as datepart "dayofyear" to the result of this method will give you the number of days between the two dates, and divide as Modulo (%) this result by the EffectiveDays and if the result is 0 there is payment day; and if not you will have the days passed from the last payment day (if you sustract it from the EffectivedDays you must have the restant days to the next payment day).

Here is some doc for the DATEDIFF method: http://msdn.microsoft.com/en-us/library/ms189794.aspx

Upvotes: 1

Related Questions