0
votes

I am looking for some assistance in calculating the due dates for a new scheduling system.

At present a schedule is based on Monthly or Weekly payment, starting from a defined date.

In the new schedule we want this to be based on the customers pay frequency, starting from a defined date.

We have 13 options for pay frequency:

  1. Montly - Last Working Day
  2. Monthly - Same Date e.g. 20th, 25th
  3. Monthly - 1st Mon/Tue/Wed/Thurs/Fri
  4. Monthly - 2nd Mon/Tue/Wed/Thurs/Fri
  5. Monthly - 3rd Mon/Tue/Wed/Thurs/Fri
  6. Monthly - Last Mon/Tue/Wed/Thurs/Fri
  7. Weekly – Monday
  8. Weekly – Tuesday
  9. Weekly – Wednesday
  10. Weekly – Thursday
  11. Weekly – Friday
  12. 4 Weekly
  13. Fortnightly

Depending on the pay frequency passed in and the number of payments and balance due, I need to produce a new schedule.

The first payment is straight forward as it is on the passed in date, the other dates in the schedule need to be calculated (depending on pay frequency) from that date.

I also need to ensure that the scheduled dates are on a weekday (Mon-Fri) and do not land on a public/bank holiday - in this instance, I will revert to the next valid week day.

The method I have so far is as follows - with the area I need assistance commented:

// Calculate next payment date

public IList<ScheduledInstalment> GenerateSchedule(int agreementID, int paymentCount, 
    PayFrequency frequency, double balance, DateTime firstPaymentDate)
{
    IList<ScheduledInstalment> schedule = new List<ScheduledInstalment>();

    PaymentCalculation calc = GetPaymentCalculation(frequency, firstPaymentDate);

    double regularInstalment = Math.Round(balance / paymentCount, 1);
    double finalInstalment = Math.Round(((regularInstalment * (paymentCount - 1)) - balance), 2);

    for (int i = 0; i <= paymentCount; i++)
    {
        ScheduledInstalment s = new ScheduledInstalment();

        s.AgreementID = agreementID;

        if (i == 0)
        {
            // First Payment
            s.DueDate = firstPaymentDate;
            s.AmountDue = regularInstalment;
        }
        else 

            // Calculate next payment date

            if (i < paymentCount)
            {
                // Regular Payment
                s.AmountDue = regularInstalment;
            }
            else
            {
                // Final Payment
                s.AmountDue = finalInstalment;
            }

        schedule.Add(s);
    }

    return schedule;
}
1
What's your question?...or, what's the problem?David Hoerster
I think he needs help with the logic between else and if(i < paymentCount)...Mike G
That is right Mike, I need help in working out what the due date is in each loop.Richard.Gale
Questions which lack in detail are usually the problem, however in this case the questions has to much detail. Try to simplify your code to just the method you need. Consider you need a method which uses various parameters to calculate the next due date, we only need to know of that method and what parameters we have. What you have tried in that method. Not what you have to do to get into the method itself :)LukeHennerley
Hi Luke, I have included the location where I need help with the code. I have also included 2 other methods to aid the question.Richard.Gale

1 Answers

1
votes

OK, I have managed to get something which seems to work, here is my method below:

public DateTime GetNextRepaymentDate(DateTime BaseDate, int instalmentCount, PaymentCalculation calc)
            {
                DateTime dueDate = new DateTime();

                switch (calc.Interval)
                {
                    case DateInterval.Month:

                        dueDate = BaseDate.AddMonths((instalmentCount) * calc.Number);

                        if (!string.IsNullOrEmpty(calc.OtherCriteria))
                        {
                            if (calc.OtherCriteria == "Last")
                            {
                                int lastDay = DateTime.DaysInMonth(dueDate.Year, dueDate.Month);
                                dueDate = Convert.ToDateTime(string.Format("{0}/{1}/{2}", lastDay, dueDate.Month, dueDate.Year));
                            }
                            else
                            {
                                int fixedDate = Convert.ToInt32(calc.OtherCriteria);

                                if (dueDate.Day != fixedDate)
                                {
                                    if (dueDate.Day > fixedDate)
                                    {
                                        while (dueDate.Day != fixedDate)
                                        {
                                            dueDate = dueDate.AddDays(-1);
                                        }
                                    }
                                    else
                                    {
                                        while (dueDate.Day != fixedDate)
                                        {
                                            dueDate = dueDate.AddDays(1);
                                        }
                                    }
                                }
                            }
                        }

                        break;

                    case DateInterval.WeekOfYear:

                        dueDate = BaseDate.AddDays((instalmentCount) * (calc.Number * 7));

                        if (calc.FixedDay != null)
                        {
                            while (dueDate.DayOfWeek != calc.FixedDay)
                            {
                                dueDate = dueDate.AddDays(-1);
                            }
                        }

                        break;
                }

                while (!PaymentIsAllowedOnDate(dueDate) == true)
                {
                    dueDate = dueDate.AddDays(-1);
                }

                return dueDate;
            }