10
10
using OFM . Infrastructure . WebAPI . Services . Processes . Fundings ;
11
11
using OFM . Infrastructure . WebAPI . Messages ;
12
12
using Microsoft . Extensions . Options ;
13
+ using Microsoft . Xrm . Sdk ;
13
14
14
15
namespace OFM . Infrastructure . WebAPI . Services . Processes . Payments
15
16
{
@@ -345,27 +346,25 @@ public async Task<JsonObject> RunProcessAsync(ID365AppUserService appUserService
345
346
DateTime intermediateDate ;
346
347
DateTime firstAnniversary ;
347
348
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 )
356
353
{
357
354
intermediateDate = fundingEndDate . Value . AddYears ( - 1 ) ;
358
355
firstAnniversary = intermediateDate ;
359
356
secondAnniversary = fundingEndDate . Value ;
357
+
360
358
}
361
359
else
362
360
{
363
361
intermediateDate = fundingEndDate . Value . AddYears ( - 2 ) ;
364
362
firstAnniversary = intermediateDate ;
365
363
intermediateDate = fundingEndDate . Value . AddYears ( - 1 ) ;
366
364
secondAnniversary = intermediateDate ;
365
+
367
366
}
368
-
367
+
369
368
ProcessData allPaymentsData = await GetAllPaymentsByApplicationIdDataAsync ( ) ;
370
369
_allPayments = JsonSerializer . Deserialize < List < D365PaymentLine > > ( allPaymentsData . Data . ToString ( ) ) ;
371
370
if ( _allPayments is not null && _allPayments . Count > 0 )
@@ -389,20 +388,20 @@ public async Task<JsonObject> RunProcessAsync(ID365AppUserService appUserService
389
388
390
389
#endregion
391
390
392
- await ProcessSupportNeedsOrIndigenousPayments ( deserializedApplicationData . First ( ) , approvedSA , processParams , fiscalYears , holidaysList ) ;
391
+ await ProcessSupportNeedsOrIndigenousPayments ( deserializedApplicationData . First ( ) , approvedSA , processParams , fiscalYears , holidaysList , firstAnniversary , secondAnniversary , fundingEndDate ) ;
393
392
await ProcessTransportationPayments ( deserializedApplicationData . First ( ) , approvedSA , processParams , fiscalYears , holidaysList , firstAnniversary , secondAnniversary , fundingEndDate ) ;
394
393
395
394
_logger . LogInformation ( CustomLogEvent . Process , "Finished payments generation for the supplementary application {allowanceId}" , processParams . SupplementaryApplication ! . allowanceId ) ;
396
395
397
396
return ProcessResult . Completed ( ProcessId ) . SimpleProcessResult ;
398
397
}
399
398
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 )
401
400
{
402
401
if ( approvedSA . ofm_allowance_type == ecc_allowance_type . SupportNeedsProgramming || approvedSA . ofm_allowance_type == ecc_allowance_type . IndigenousProgramming )
403
402
{
404
403
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 ) ;
406
405
407
406
_logger . LogInformation ( CustomLogEvent . Process , "Finished payments generation for the {allowancetype} application with Id {allowanceId}" , approvedSA . ofm_allowance_type , processParams . SupplementaryApplication ! . allowanceId ) ;
408
407
}
@@ -419,17 +418,17 @@ private async Task<JsonObject> ProcessTransportationPayments(Application baseApp
419
418
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 ;
420
419
decimal retroActiveAmount = retroActiveMonthsCount > 0 ? approvedSA . ofm_monthly_amount ! . Value * retroActiveMonthsCount : 0 ;
421
420
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 ) ;
423
422
424
423
_logger . LogInformation ( CustomLogEvent . Process , "Finished payments generation for the {allowancetype} application with Id {allowanceId}" , approvedSA . ofm_allowance_type , processParams . SupplementaryApplication ! . allowanceId ) ;
425
424
}
426
425
else
427
426
{
428
427
// 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 ) ;
430
429
// Process retroactive payment
431
430
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 ) ;
433
432
_logger . LogInformation ( CustomLogEvent . Process , "Finished payments generation for the {allowancetype} application with Id {allowanceId}" , approvedSA . ofm_allowance_type , processParams . SupplementaryApplication ! . allowanceId ) ;
434
433
}
435
434
@@ -438,12 +437,12 @@ private async Task<JsonObject> ProcessTransportationPayments(Application baseApp
438
437
return ProcessResult . Completed ( ProcessId ) . SimpleProcessResult ;
439
438
}
440
439
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 )
442
441
{
443
442
decimal retroActiveAmount = retroActiveMonthsCount > 0 ? monthlyPaymentAmount * retroActiveMonthsCount : 0 ;
444
443
if ( retroActiveAmount > 0 )
445
444
{
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 ) ;
447
446
}
448
447
449
448
await SaveRetroactiveAmount ( approvedSA , retroActiveAmount ) ;
@@ -480,13 +479,27 @@ private async Task<JsonObject> CreateSinglePayment(SupplementaryApplication appr
480
479
Application baseApplication ,
481
480
ProcessParameter processParams ,
482
481
List < D365FiscalYear > fiscalYears ,
483
- List < DateTime > holidaysList )
482
+ List < DateTime > holidaysList ,
483
+ DateTime firstAnniversaryDate ,
484
+ DateTime secondAnniversaryDate ,
485
+ DateTime ? fundingEndDate )
484
486
{
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 ) ;
486
488
DateTime invoiceReceivedDate = invoiceDate . AddBusinessDays ( _BCCASApi . PayableInDays , holidaysList ) ;
487
489
DateTime effectiveDate = invoiceDate ;
488
490
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 ) ;
490
503
491
504
var payload = new JsonObject ( )
492
505
{
@@ -502,7 +515,8 @@ private async Task<JsonObject> CreateSinglePayment(SupplementaryApplication appr
502
515
{ "ofm_effective_date" , effectiveDate . ToString ( "yyyy-MM-dd" ) } ,
503
516
{ "ofm_fiscal_year@odata.bind" , $ "/ofm_fiscal_years({ fiscalYear } )" } ,
504
517
{ "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 ( ) }
506
520
} ;
507
521
508
522
var requestBody = JsonSerializer . Serialize ( payload ) ;
@@ -526,19 +540,33 @@ private async Task<JsonObject> CreatePaymentsInBatch(Application baseApplication
526
540
ecc_payment_type paymentType ,
527
541
ProcessParameter processParams ,
528
542
List < D365FiscalYear > fiscalYears ,
529
- List < DateTime > holidaysList )
543
+ List < DateTime > holidaysList ,
544
+ DateTime firstAnniversaryDate ,
545
+ DateTime secondAnniversaryDate ,
546
+ DateTime ? fundingEndDate )
530
547
{
531
548
List < HttpRequestMessage > createPaymentRequests = [ ] ;
532
549
int nextLineNumber = await GetNextInvoiceLineNumber ( ) ;
533
550
534
551
for ( DateTime paymentDate = startDate ; paymentDate <= endDate ; paymentDate = paymentDate . AddMonths ( 1 ) )
535
552
{
536
553
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 ) ;
538
555
DateTime invoiceReceivedDate = invoiceDate . AddBusinessDays ( _BCCASApi . PayableInDays , holidaysList ) ;
539
556
DateTime effectiveDate = invoiceDate ;
540
557
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 ) ;
542
570
var paymentToCreate = new JsonObject ( )
543
571
{
544
572
{ "ofm_invoice_line_number" , nextLineNumber ++ } ,
@@ -553,7 +581,8 @@ private async Task<JsonObject> CreatePaymentsInBatch(Application baseApplication
553
581
{ "ofm_effective_date" , effectiveDate . ToString ( "yyyy-MM-dd" ) } ,
554
582
{ "ofm_fiscal_year@odata.bind" , $ "/ofm_fiscal_years({ fiscalYear } )" } ,
555
583
{ "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 ( ) }
557
586
} ;
558
587
559
588
createPaymentRequests . Add ( new CreateRequest ( ofm_payment . EntitySetName , paymentToCreate ) ) ;
0 commit comments