Skip to content

Commit 920310f

Browse files
Payments changes for fiscal year column on payment (#268)
* Payments changes for fiscal year column on payment * latest changes for payment FA year & last month
1 parent 282f3f3 commit 920310f

File tree

3 files changed

+62
-28
lines changed

3 files changed

+62
-28
lines changed

OFM.Infrastructure.WebAPI/Extensions/TimeExtensions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,9 +200,9 @@ public static DateTime GetLastBusinessDayOfPaymentMonth(this DateTime PaymentDat
200200

201201
return lastDayOfPaymentMonth;
202202
}
203-
public static DateTime GetFirstDayOfFollowingMonth(this DateTime PaymentDate, List<DateTime> holidays)
203+
public static DateTime GetFirstDayOfFollowingNextMonth(this DateTime PaymentDate, List<DateTime> holidays)
204204
{
205-
DateTime firstDayOfNextMonth = new DateTime(PaymentDate.Year, PaymentDate.Month, 1).AddMonths(1);
205+
DateTime firstDayOfNextMonth = new DateTime(PaymentDate.Year, PaymentDate.Month, 1).AddMonths(2);
206206
// Iterate backward to find the last business day of that payment month.
207207
while (firstDayOfNextMonth.DayOfWeek == DayOfWeek.Saturday ||
208208
firstDayOfNextMonth.DayOfWeek == DayOfWeek.Sunday ||

OFM.Infrastructure.WebAPI/Services/Processes/Payments/P505GeneratePaymentLinesProvider.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,9 @@ private async Task<JsonObject> CreatePaymentsInBatch(Funding funding, decimal fu
503503
}
504504
Guid fiscalYearId = invoiceDate.MatchFiscalYear(fiscalYears);
505505

506+
var FAYear = (invoiceReceivedDate < startDate.AddYears(1)) ? 1 :
507+
(invoiceReceivedDate < startDate.AddYears(2)) ? 2 :
508+
(invoiceReceivedDate < startDate.AddYears(3)) ? 3 : 0;
506509
var paymentToCreate = new JsonObject()
507510
{
508511
{ "ofm_invoice_line_number", lineNumber++ },
@@ -515,7 +518,9 @@ private async Task<JsonObject> CreatePaymentsInBatch(Funding funding, decimal fu
515518
{ "ofm_invoice_date", invoiceDate.ToString("yyyy-MM-dd") },
516519
{ "ofm_invoice_received_date", invoiceReceivedDate.ToString("yyyy-MM-dd")},
517520
{ "ofm_effective_date", effectiveDate.ToString("yyyy-MM-dd")},
518-
{ "ofm_payment_manual_review", manualReview }
521+
{ "ofm_payment_manual_review", manualReview },
522+
{ "ofm_fayear", FAYear.ToString() }
523+
519524
};
520525
if (regardingid is not null && !string.IsNullOrEmpty(regardingTableSet))
521526
{

OFM.Infrastructure.WebAPI/Services/Processes/Payments/P520GenerateAllowancePaymentProvider.cs

Lines changed: 54 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using OFM.Infrastructure.WebAPI.Services.Processes.Fundings;
1111
using OFM.Infrastructure.WebAPI.Messages;
1212
using Microsoft.Extensions.Options;
13+
using Microsoft.Xrm.Sdk;
1314

1415
namespace OFM.Infrastructure.WebAPI.Services.Processes.Payments
1516
{
@@ -345,27 +346,25 @@ public async Task<JsonObject> RunProcessAsync(ID365AppUserService appUserService
345346
DateTime intermediateDate;
346347
DateTime firstAnniversary;
347348
DateTime secondAnniversary;
348-
if (fundingEndDate is null)
349-
{
350-
_logger.LogError(CustomLogEvent.Process, "Unable to retrieve Funding record with Id {ofm_end_date}", fundingEndDate);
351-
return ProcessResult.Completed(ProcessId).SimpleProcessResult;
352-
}
353-
354-
//Two year contract or three year contract
355-
if (fundingEndDate.Value.Year - fundingStartDate.Value.Year == 2)
349+
350+
var threeYear = new DateTime();
351+
threeYear = fundingStartDate.Value.AddYears(3).AddDays(-1);
352+
if (fundingEndDate < threeYear)
356353
{
357354
intermediateDate = fundingEndDate.Value.AddYears(-1);
358355
firstAnniversary = intermediateDate;
359356
secondAnniversary = fundingEndDate.Value;
357+
360358
}
361359
else
362360
{
363361
intermediateDate = fundingEndDate.Value.AddYears(-2);
364362
firstAnniversary = intermediateDate;
365363
intermediateDate = fundingEndDate.Value.AddYears(-1);
366364
secondAnniversary = intermediateDate;
365+
367366
}
368-
367+
369368
ProcessData allPaymentsData = await GetAllPaymentsByApplicationIdDataAsync();
370369
_allPayments = JsonSerializer.Deserialize<List<D365PaymentLine>>(allPaymentsData.Data.ToString());
371370
if (_allPayments is not null && _allPayments.Count > 0)
@@ -389,20 +388,20 @@ public async Task<JsonObject> RunProcessAsync(ID365AppUserService appUserService
389388

390389
#endregion
391390

392-
await ProcessSupportNeedsOrIndigenousPayments(deserializedApplicationData.First(), approvedSA, processParams, fiscalYears, holidaysList);
391+
await ProcessSupportNeedsOrIndigenousPayments(deserializedApplicationData.First(), approvedSA, processParams, fiscalYears, holidaysList, firstAnniversary, secondAnniversary, fundingEndDate);
393392
await ProcessTransportationPayments(deserializedApplicationData.First(), approvedSA, processParams, fiscalYears, holidaysList,firstAnniversary, secondAnniversary, fundingEndDate);
394393

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

397396
return ProcessResult.Completed(ProcessId).SimpleProcessResult;
398397
}
399398

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

407406
_logger.LogInformation(CustomLogEvent.Process, "Finished payments generation for the {allowancetype} application with Id {allowanceId}", approvedSA.ofm_allowance_type, processParams.SupplementaryApplication!.allowanceId);
408407
}
@@ -419,17 +418,17 @@ private async Task<JsonObject> ProcessTransportationPayments(Application baseApp
419418
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;
420419
decimal retroActiveAmount = retroActiveMonthsCount > 0 ? approvedSA.ofm_monthly_amount!.Value * retroActiveMonthsCount : 0;
421420
var endTermLumpSumPayment = approvedSA.ofm_monthly_amount!.Value + retroActiveAmount;
422-
await CreateSinglePayment(approvedSA, approvedSA.ofm_start_date!.Value, endTermLumpSumPayment, false, ecc_payment_type.Transportation, baseApplication!, processParams, fiscalYears, holidaysList);
421+
await CreateSinglePayment(approvedSA, approvedSA.ofm_start_date!.Value, endTermLumpSumPayment, false, ecc_payment_type.Transportation, baseApplication!, processParams, fiscalYears, holidaysList, firstAnniversaryDate, secondAnniversaryDate, fundingEndDate);
423422

424423
_logger.LogInformation(CustomLogEvent.Process, "Finished payments generation for the {allowancetype} application with Id {allowanceId}", approvedSA.ofm_allowance_type, processParams.SupplementaryApplication!.allowanceId);
425424
}
426425
else
427426
{
428427
// Process future payments
429-
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);
428+
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);
430429
// Process retroactive payment
431430
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;
432-
await ProcessRetroActivePayment(baseApplication!, approvedSA, processParams, fiscalYears, holidaysList, approvedSA.ofm_monthly_amount!.Value, retroActiveMonthsCount);
431+
await ProcessRetroActivePayment(baseApplication!, approvedSA, processParams, fiscalYears, holidaysList, approvedSA.ofm_monthly_amount!.Value, retroActiveMonthsCount, firstAnniversaryDate, secondAnniversaryDate, fundingEndDate);
433432
_logger.LogInformation(CustomLogEvent.Process, "Finished payments generation for the {allowancetype} application with Id {allowanceId}", approvedSA.ofm_allowance_type, processParams.SupplementaryApplication!.allowanceId);
434433
}
435434

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

441-
private async Task ProcessRetroActivePayment(Application baseApplication, SupplementaryApplication approvedSA, ProcessParameter processParams, List<D365FiscalYear> fiscalYears, List<DateTime> holidaysList, decimal monthlyPaymentAmount, int retroActiveMonthsCount)
440+
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)
442441
{
443442
decimal retroActiveAmount = retroActiveMonthsCount > 0 ? monthlyPaymentAmount * retroActiveMonthsCount : 0;
444443
if (retroActiveAmount > 0)
445444
{
446-
await CreateSinglePayment(approvedSA, approvedSA.ofm_start_date!.Value, retroActiveAmount, false, ecc_payment_type.Transportation, baseApplication, processParams, fiscalYears, holidaysList);
445+
await CreateSinglePayment(approvedSA, approvedSA.ofm_start_date!.Value, retroActiveAmount, false, ecc_payment_type.Transportation, baseApplication, processParams, fiscalYears, holidaysList, firstAnniversaryDate, secondAnniversaryDate, fundingEndDate);
447446
}
448447

449448
await SaveRetroactiveAmount(approvedSA, retroActiveAmount);
@@ -480,13 +479,27 @@ private async Task<JsonObject> CreateSinglePayment(SupplementaryApplication appr
480479
Application baseApplication,
481480
ProcessParameter processParams,
482481
List<D365FiscalYear> fiscalYears,
483-
List<DateTime> holidaysList)
482+
List<DateTime> holidaysList,
483+
DateTime firstAnniversaryDate,
484+
DateTime secondAnniversaryDate,
485+
DateTime? fundingEndDate)
484486
{
485-
DateTime invoiceDate = paymentDate.GetFirstDayOfFollowingMonth(holidaysList);
487+
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);
486488
DateTime invoiceReceivedDate = invoiceDate.AddBusinessDays(_BCCASApi.PayableInDays, holidaysList);
487489
DateTime effectiveDate = invoiceDate;
488490

489-
Guid fiscalYear = invoiceDate.MatchFiscalYear(fiscalYears);
491+
492+
493+
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))
494+
{
495+
// Date calculation logic is different for mid-year supp application. Overriding regular date logic above
496+
// 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.
497+
invoiceReceivedDate = paymentDate.GetLastBusinessDayOfThePreviousMonth(holidaysList);
498+
invoiceDate = invoiceReceivedDate.GetCFSInvoiceDate(holidaysList, _BCCASApi.PayableInDays);
499+
effectiveDate = invoiceDate;
500+
}
501+
502+
Guid fiscalYear = invoiceDate.AddMonths(-1).MatchFiscalYear(fiscalYears);
490503

491504
var payload = new JsonObject()
492505
{
@@ -502,7 +515,8 @@ private async Task<JsonObject> CreateSinglePayment(SupplementaryApplication appr
502515
{ "ofm_effective_date", effectiveDate.ToString("yyyy-MM-dd")},
503516
{ "ofm_fiscal_year@odata.bind",$"/ofm_fiscal_years({fiscalYear})" },
504517
{ "ofm_payment_manual_review", manualReview },
505-
{ "ofm_regardingid_ofm_allowance@odata.bind",$"/ofm_allowances({approvedSA.Id})" }
518+
{ "ofm_regardingid_ofm_allowance@odata.bind",$"/ofm_allowances({approvedSA.Id})" },
519+
{ "ofm_fayear", approvedSA.ofm_renewal_term.ToString() }
506520
};
507521

508522
var requestBody = JsonSerializer.Serialize(payload);
@@ -526,19 +540,33 @@ private async Task<JsonObject> CreatePaymentsInBatch(Application baseApplication
526540
ecc_payment_type paymentType,
527541
ProcessParameter processParams,
528542
List<D365FiscalYear> fiscalYears,
529-
List<DateTime> holidaysList)
543+
List<DateTime> holidaysList,
544+
DateTime firstAnniversaryDate,
545+
DateTime secondAnniversaryDate,
546+
DateTime? fundingEndDate)
530547
{
531548
List<HttpRequestMessage> createPaymentRequests = [];
532549
int nextLineNumber = await GetNextInvoiceLineNumber();
533550

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

537-
DateTime invoiceDate = paymentDate.GetFirstDayOfFollowingMonth(holidaysList);
554+
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);
538555
DateTime invoiceReceivedDate = invoiceDate.AddBusinessDays(_BCCASApi.PayableInDays, holidaysList);
539556
DateTime effectiveDate = invoiceDate;
540557

541-
Guid? fiscalYear = invoiceDate.MatchFiscalYear(fiscalYears);
558+
559+
560+
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))
561+
{
562+
// Date calculation logic is different for mid-year supp application. Overriding regular date logic above
563+
// 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.
564+
invoiceReceivedDate = paymentDate.GetLastBusinessDayOfThePreviousMonth(holidaysList);
565+
invoiceDate = invoiceReceivedDate.GetCFSInvoiceDate(holidaysList, _BCCASApi.PayableInDays);
566+
effectiveDate = invoiceDate;
567+
}
568+
569+
Guid? fiscalYear = invoiceDate.AddMonths(-1).MatchFiscalYear(fiscalYears);
542570
var paymentToCreate = new JsonObject()
543571
{
544572
{ "ofm_invoice_line_number", nextLineNumber++ },
@@ -553,7 +581,8 @@ private async Task<JsonObject> CreatePaymentsInBatch(Application baseApplication
553581
{ "ofm_effective_date", effectiveDate.ToString("yyyy-MM-dd")},
554582
{ "ofm_fiscal_year@odata.bind",$"/ofm_fiscal_years({fiscalYear})" },
555583
{ "ofm_payment_manual_review", manualReview },
556-
{ "ofm_regardingid_ofm_allowance@odata.bind",$"/ofm_allowances({approvedSA.Id})" }
584+
{ "ofm_regardingid_ofm_allowance@odata.bind",$"/ofm_allowances({approvedSA.Id})" },
585+
{ "ofm_fayear", approvedSA.ofm_renewal_term.ToString() }
557586
};
558587

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

0 commit comments

Comments
 (0)