Skip to content

Commit

Permalink
Payments changes for fiscal year column on payment (#268)
Browse files Browse the repository at this point in the history
* Payments changes for fiscal year column on payment

* latest changes for payment FA year & last month
  • Loading branch information
Prashanthi-Sivanarayana authored Nov 7, 2024
1 parent 282f3f3 commit 920310f
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 28 deletions.
4 changes: 2 additions & 2 deletions OFM.Infrastructure.WebAPI/Extensions/TimeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -200,9 +200,9 @@ public static DateTime GetLastBusinessDayOfPaymentMonth(this DateTime PaymentDat

return lastDayOfPaymentMonth;
}
public static DateTime GetFirstDayOfFollowingMonth(this DateTime PaymentDate, List<DateTime> holidays)
public static DateTime GetFirstDayOfFollowingNextMonth(this DateTime PaymentDate, List<DateTime> holidays)
{
DateTime firstDayOfNextMonth = new DateTime(PaymentDate.Year, PaymentDate.Month, 1).AddMonths(1);
DateTime firstDayOfNextMonth = new DateTime(PaymentDate.Year, PaymentDate.Month, 1).AddMonths(2);
// Iterate backward to find the last business day of that payment month.
while (firstDayOfNextMonth.DayOfWeek == DayOfWeek.Saturday ||
firstDayOfNextMonth.DayOfWeek == DayOfWeek.Sunday ||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,9 @@ private async Task<JsonObject> CreatePaymentsInBatch(Funding funding, decimal fu
}
Guid fiscalYearId = invoiceDate.MatchFiscalYear(fiscalYears);

var FAYear = (invoiceReceivedDate < startDate.AddYears(1)) ? 1 :
(invoiceReceivedDate < startDate.AddYears(2)) ? 2 :
(invoiceReceivedDate < startDate.AddYears(3)) ? 3 : 0;
var paymentToCreate = new JsonObject()
{
{ "ofm_invoice_line_number", lineNumber++ },
Expand All @@ -515,7 +518,9 @@ private async Task<JsonObject> CreatePaymentsInBatch(Funding funding, decimal fu
{ "ofm_invoice_date", invoiceDate.ToString("yyyy-MM-dd") },
{ "ofm_invoice_received_date", invoiceReceivedDate.ToString("yyyy-MM-dd")},
{ "ofm_effective_date", effectiveDate.ToString("yyyy-MM-dd")},
{ "ofm_payment_manual_review", manualReview }
{ "ofm_payment_manual_review", manualReview },
{ "ofm_fayear", FAYear.ToString() }

};
if (regardingid is not null && !string.IsNullOrEmpty(regardingTableSet))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using OFM.Infrastructure.WebAPI.Services.Processes.Fundings;
using OFM.Infrastructure.WebAPI.Messages;
using Microsoft.Extensions.Options;
using Microsoft.Xrm.Sdk;

namespace OFM.Infrastructure.WebAPI.Services.Processes.Payments
{
Expand Down Expand Up @@ -345,27 +346,25 @@ public async Task<JsonObject> RunProcessAsync(ID365AppUserService appUserService
DateTime intermediateDate;
DateTime firstAnniversary;
DateTime secondAnniversary;
if (fundingEndDate is null)
{
_logger.LogError(CustomLogEvent.Process, "Unable to retrieve Funding record with Id {ofm_end_date}", fundingEndDate);
return ProcessResult.Completed(ProcessId).SimpleProcessResult;
}

//Two year contract or three year contract
if (fundingEndDate.Value.Year - fundingStartDate.Value.Year == 2)

var threeYear = new DateTime();
threeYear = fundingStartDate.Value.AddYears(3).AddDays(-1);
if (fundingEndDate < threeYear)
{
intermediateDate = fundingEndDate.Value.AddYears(-1);
firstAnniversary = intermediateDate;
secondAnniversary = fundingEndDate.Value;

}
else
{
intermediateDate = fundingEndDate.Value.AddYears(-2);
firstAnniversary = intermediateDate;
intermediateDate = fundingEndDate.Value.AddYears(-1);
secondAnniversary = intermediateDate;

}

ProcessData allPaymentsData = await GetAllPaymentsByApplicationIdDataAsync();
_allPayments = JsonSerializer.Deserialize<List<D365PaymentLine>>(allPaymentsData.Data.ToString());
if (_allPayments is not null && _allPayments.Count > 0)
Expand All @@ -389,20 +388,20 @@ public async Task<JsonObject> RunProcessAsync(ID365AppUserService appUserService

#endregion

await ProcessSupportNeedsOrIndigenousPayments(deserializedApplicationData.First(), approvedSA, processParams, fiscalYears, holidaysList);
await ProcessSupportNeedsOrIndigenousPayments(deserializedApplicationData.First(), approvedSA, processParams, fiscalYears, holidaysList, firstAnniversary, secondAnniversary, fundingEndDate);
await ProcessTransportationPayments(deserializedApplicationData.First(), approvedSA, processParams, fiscalYears, holidaysList,firstAnniversary, secondAnniversary, fundingEndDate);

_logger.LogInformation(CustomLogEvent.Process, "Finished payments generation for the supplementary application {allowanceId}", processParams.SupplementaryApplication!.allowanceId);

return ProcessResult.Completed(ProcessId).SimpleProcessResult;
}

private async Task<JsonObject> ProcessSupportNeedsOrIndigenousPayments(Application baseApplication, SupplementaryApplication approvedSA, ProcessParameter processParams, List<D365FiscalYear> fiscalYears, List<DateTime> holidaysList)
private async Task<JsonObject> ProcessSupportNeedsOrIndigenousPayments(Application baseApplication, SupplementaryApplication approvedSA, ProcessParameter processParams, List<D365FiscalYear> fiscalYears, List<DateTime> holidaysList, DateTime firstAnniversaryDate, DateTime secondAnniversaryDate, DateTime? fundingEndDate)
{
if (approvedSA.ofm_allowance_type == ecc_allowance_type.SupportNeedsProgramming || approvedSA.ofm_allowance_type == ecc_allowance_type.IndigenousProgramming)
{
ecc_payment_type paymentType = (approvedSA.ofm_allowance_type.Value == ecc_allowance_type.SupportNeedsProgramming) ? ecc_payment_type.SupportNeedsFunding : ecc_payment_type.IndigenousProgramming;
await CreateSinglePayment(approvedSA, approvedSA.ofm_start_date!.Value, approvedSA.ofm_funding_amount, false, paymentType, baseApplication!, processParams, fiscalYears, holidaysList);
await CreateSinglePayment(approvedSA, approvedSA.ofm_start_date!.Value, approvedSA.ofm_funding_amount, false, paymentType, baseApplication!, processParams, fiscalYears, holidaysList, firstAnniversaryDate, secondAnniversaryDate, fundingEndDate);

_logger.LogInformation(CustomLogEvent.Process, "Finished payments generation for the {allowancetype} application with Id {allowanceId}", approvedSA.ofm_allowance_type, processParams.SupplementaryApplication!.allowanceId);
}
Expand All @@ -419,17 +418,17 @@ private async Task<JsonObject> ProcessTransportationPayments(Application baseApp
int retroActiveMonthsCount = approvedSA.ofm_retroactive_date!.HasValue ? (approvedSA.ofm_start_date.Value.Year - approvedSA.ofm_retroactive_date!.Value.Year) * 12 + approvedSA.ofm_start_date.Value.Month - approvedSA.ofm_retroactive_date.Value.Month : 0;
decimal retroActiveAmount = retroActiveMonthsCount > 0 ? approvedSA.ofm_monthly_amount!.Value * retroActiveMonthsCount : 0;
var endTermLumpSumPayment = approvedSA.ofm_monthly_amount!.Value + retroActiveAmount;
await CreateSinglePayment(approvedSA, approvedSA.ofm_start_date!.Value, endTermLumpSumPayment, false, ecc_payment_type.Transportation, baseApplication!, processParams, fiscalYears, holidaysList);
await CreateSinglePayment(approvedSA, approvedSA.ofm_start_date!.Value, endTermLumpSumPayment, false, ecc_payment_type.Transportation, baseApplication!, processParams, fiscalYears, holidaysList, firstAnniversaryDate, secondAnniversaryDate, fundingEndDate);

_logger.LogInformation(CustomLogEvent.Process, "Finished payments generation for the {allowancetype} application with Id {allowanceId}", approvedSA.ofm_allowance_type, processParams.SupplementaryApplication!.allowanceId);
}
else
{
// Process future payments
await CreatePaymentsInBatch(baseApplication!, approvedSA!, approvedSA.ofm_start_date.Value, approvedSA.ofm_end_date.Value, approvedSA.ofm_monthly_amount!.Value, false, ecc_payment_type.Transportation, processParams, fiscalYears, holidaysList);
await CreatePaymentsInBatch(baseApplication!, approvedSA!, approvedSA.ofm_start_date.Value, approvedSA.ofm_end_date.Value, approvedSA.ofm_monthly_amount!.Value, false, ecc_payment_type.Transportation, processParams, fiscalYears, holidaysList, firstAnniversaryDate, secondAnniversaryDate, fundingEndDate);
// Process retroactive payment
int retroActiveMonthsCount = approvedSA.ofm_retroactive_date!.HasValue ? (approvedSA.ofm_start_date.Value.Year - approvedSA.ofm_retroactive_date!.Value.Year) * 12 + approvedSA.ofm_start_date.Value.Month - approvedSA.ofm_retroactive_date.Value.Month : 0;
await ProcessRetroActivePayment(baseApplication!, approvedSA, processParams, fiscalYears, holidaysList, approvedSA.ofm_monthly_amount!.Value, retroActiveMonthsCount);
await ProcessRetroActivePayment(baseApplication!, approvedSA, processParams, fiscalYears, holidaysList, approvedSA.ofm_monthly_amount!.Value, retroActiveMonthsCount, firstAnniversaryDate, secondAnniversaryDate, fundingEndDate);
_logger.LogInformation(CustomLogEvent.Process, "Finished payments generation for the {allowancetype} application with Id {allowanceId}", approvedSA.ofm_allowance_type, processParams.SupplementaryApplication!.allowanceId);
}

Expand All @@ -438,12 +437,12 @@ private async Task<JsonObject> ProcessTransportationPayments(Application baseApp
return ProcessResult.Completed(ProcessId).SimpleProcessResult;
}

private async Task ProcessRetroActivePayment(Application baseApplication, SupplementaryApplication approvedSA, ProcessParameter processParams, List<D365FiscalYear> fiscalYears, List<DateTime> holidaysList, decimal monthlyPaymentAmount, int retroActiveMonthsCount)
private async Task ProcessRetroActivePayment(Application baseApplication, SupplementaryApplication approvedSA, ProcessParameter processParams, List<D365FiscalYear> fiscalYears, List<DateTime> holidaysList, decimal monthlyPaymentAmount, int retroActiveMonthsCount, DateTime firstAnniversaryDate, DateTime secondAnniversaryDate, DateTime? fundingEndDate)
{
decimal retroActiveAmount = retroActiveMonthsCount > 0 ? monthlyPaymentAmount * retroActiveMonthsCount : 0;
if (retroActiveAmount > 0)
{
await CreateSinglePayment(approvedSA, approvedSA.ofm_start_date!.Value, retroActiveAmount, false, ecc_payment_type.Transportation, baseApplication, processParams, fiscalYears, holidaysList);
await CreateSinglePayment(approvedSA, approvedSA.ofm_start_date!.Value, retroActiveAmount, false, ecc_payment_type.Transportation, baseApplication, processParams, fiscalYears, holidaysList, firstAnniversaryDate, secondAnniversaryDate, fundingEndDate);
}

await SaveRetroactiveAmount(approvedSA, retroActiveAmount);
Expand Down Expand Up @@ -480,13 +479,27 @@ private async Task<JsonObject> CreateSinglePayment(SupplementaryApplication appr
Application baseApplication,
ProcessParameter processParams,
List<D365FiscalYear> fiscalYears,
List<DateTime> holidaysList)
List<DateTime> holidaysList,
DateTime firstAnniversaryDate,
DateTime secondAnniversaryDate,
DateTime? fundingEndDate)
{
DateTime invoiceDate = paymentDate.GetFirstDayOfFollowingMonth(holidaysList);
DateTime invoiceDate = ((approvedSA.ofm_start_date.Value.Month == firstAnniversaryDate.Month && approvedSA.ofm_start_date.Value.Year == firstAnniversaryDate.Year) || (approvedSA.ofm_start_date.Value.Month == secondAnniversaryDate.Month && approvedSA.ofm_start_date.Value.Year == secondAnniversaryDate.Year) || (approvedSA.ofm_start_date.Value.Month == fundingEndDate?.Month && approvedSA.ofm_start_date.Value.Year == fundingEndDate?.Year)) ? paymentDate.GetFirstDayOfFollowingNextMonth(holidaysList) : (paymentDate == approvedSA.ofm_start_date!.Value) ? paymentDate.GetLastBusinessDayOfThePreviousMonth(holidaysList) : paymentDate.GetCFSInvoiceDate(holidaysList, _BCCASApi.PayableInDays);
DateTime invoiceReceivedDate = invoiceDate.AddBusinessDays(_BCCASApi.PayableInDays, holidaysList);
DateTime effectiveDate = invoiceDate;

Guid fiscalYear = invoiceDate.MatchFiscalYear(fiscalYears);


if (approvedSA.ofm_retroactive_date is not null && !(approvedSA.ofm_start_date.Value.Month == firstAnniversaryDate.Month && approvedSA.ofm_start_date.Value.Year == firstAnniversaryDate.Year) || (approvedSA.ofm_start_date.Value.Month == secondAnniversaryDate.Month && approvedSA.ofm_start_date.Value.Year == secondAnniversaryDate.Year) || (approvedSA.ofm_start_date.Value.Month == fundingEndDate?.Month && approvedSA.ofm_start_date.Value.Year == fundingEndDate?.Year))
{
// Date calculation logic is different for mid-year supp application. Overriding regular date logic above
// Invoice received date is always the last business date of previous month except for first payment of the First funding year, it is 5 business day after the last business day of the last month.
invoiceReceivedDate = paymentDate.GetLastBusinessDayOfThePreviousMonth(holidaysList);
invoiceDate = invoiceReceivedDate.GetCFSInvoiceDate(holidaysList, _BCCASApi.PayableInDays);
effectiveDate = invoiceDate;
}

Guid fiscalYear = invoiceDate.AddMonths(-1).MatchFiscalYear(fiscalYears);

var payload = new JsonObject()
{
Expand All @@ -502,7 +515,8 @@ private async Task<JsonObject> CreateSinglePayment(SupplementaryApplication appr
{ "ofm_effective_date", effectiveDate.ToString("yyyy-MM-dd")},
{ "[email protected]",$"/ofm_fiscal_years({fiscalYear})" },
{ "ofm_payment_manual_review", manualReview },
{ "[email protected]",$"/ofm_allowances({approvedSA.Id})" }
{ "[email protected]",$"/ofm_allowances({approvedSA.Id})" },
{ "ofm_fayear", approvedSA.ofm_renewal_term.ToString() }
};

var requestBody = JsonSerializer.Serialize(payload);
Expand All @@ -526,19 +540,33 @@ private async Task<JsonObject> CreatePaymentsInBatch(Application baseApplication
ecc_payment_type paymentType,
ProcessParameter processParams,
List<D365FiscalYear> fiscalYears,
List<DateTime> holidaysList)
List<DateTime> holidaysList,
DateTime firstAnniversaryDate,
DateTime secondAnniversaryDate,
DateTime? fundingEndDate)
{
List<HttpRequestMessage> createPaymentRequests = [];
int nextLineNumber = await GetNextInvoiceLineNumber();

for (DateTime paymentDate = startDate; paymentDate <= endDate; paymentDate = paymentDate.AddMonths(1))
{

DateTime invoiceDate = paymentDate.GetFirstDayOfFollowingMonth(holidaysList);
DateTime invoiceDate = ((approvedSA.ofm_start_date.Value.Month == firstAnniversaryDate.Month && approvedSA.ofm_start_date.Value.Year == firstAnniversaryDate.Year) || (approvedSA.ofm_start_date.Value.Month == secondAnniversaryDate.Month && approvedSA.ofm_start_date.Value.Year == secondAnniversaryDate.Year) || (approvedSA.ofm_start_date.Value.Month == fundingEndDate?.Month && approvedSA.ofm_start_date.Value.Year == fundingEndDate?.Year)) ? paymentDate.GetFirstDayOfFollowingNextMonth(holidaysList) : (paymentDate == startDate) ? startDate.GetLastBusinessDayOfThePreviousMonth(holidaysList) : paymentDate.GetCFSInvoiceDate(holidaysList, _BCCASApi.PayableInDays);
DateTime invoiceReceivedDate = invoiceDate.AddBusinessDays(_BCCASApi.PayableInDays, holidaysList);
DateTime effectiveDate = invoiceDate;

Guid? fiscalYear = invoiceDate.MatchFiscalYear(fiscalYears);


if (approvedSA.ofm_retroactive_date is not null && !(approvedSA.ofm_start_date.Value.Month == firstAnniversaryDate.Month && approvedSA.ofm_start_date.Value.Year == firstAnniversaryDate.Year) || (approvedSA.ofm_start_date.Value.Month == secondAnniversaryDate.Month && approvedSA.ofm_start_date.Value.Year == secondAnniversaryDate.Year) || (approvedSA.ofm_start_date.Value.Month == fundingEndDate?.Month && approvedSA.ofm_start_date.Value.Year == fundingEndDate?.Year))
{
// Date calculation logic is different for mid-year supp application. Overriding regular date logic above
// Invoice received date is always the last business date of previous month except for first payment of the First funding year, it is 5 business day after the last business day of the last month.
invoiceReceivedDate = paymentDate.GetLastBusinessDayOfThePreviousMonth(holidaysList);
invoiceDate = invoiceReceivedDate.GetCFSInvoiceDate(holidaysList, _BCCASApi.PayableInDays);
effectiveDate = invoiceDate;
}

Guid? fiscalYear = invoiceDate.AddMonths(-1).MatchFiscalYear(fiscalYears);
var paymentToCreate = new JsonObject()
{
{ "ofm_invoice_line_number", nextLineNumber++ },
Expand All @@ -553,7 +581,8 @@ private async Task<JsonObject> CreatePaymentsInBatch(Application baseApplication
{ "ofm_effective_date", effectiveDate.ToString("yyyy-MM-dd")},
{ "[email protected]",$"/ofm_fiscal_years({fiscalYear})" },
{ "ofm_payment_manual_review", manualReview },
{ "[email protected]",$"/ofm_allowances({approvedSA.Id})" }
{ "[email protected]",$"/ofm_allowances({approvedSA.Id})" },
{ "ofm_fayear", approvedSA.ofm_renewal_term.ToString() }
};

createPaymentRequests.Add(new CreateRequest(ofm_payment.EntitySetName, paymentToCreate));
Expand Down

0 comments on commit 920310f

Please sign in to comment.