Skip to content
Merged

Dev #1548

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
a5bdba6
AB#29460 - Hotfix - Remove statement overwriting ApplicantName
plavoie-BC Jul 8, 2025
058b6cb
AB#28707 - Add Non-Registered Organization and Business Columns
plavoie-BC Jul 11, 2025
417ffd5
AB#28585 - Add Tag Assignment Permission Definitions
plavoie-BC Jul 21, 2025
a9261f5
AB#28585 - Add Tag Assignment Permission Data Seeder
plavoie-BC Jul 21, 2025
fa47da7
AB#28585 - Update Tag Assignment Permission Data Seeder
plavoie-BC Jul 22, 2025
9e7f075
Merge remote-tracking branch 'origin/dev' into feature/AB#28585-assig…
plavoie-BC Jul 22, 2025
8f18d4c
Merge remote-tracking branch 'origin/dev' into feature/AB#28707-non-r…
plavoie-BC Jul 29, 2025
90b943d
Merge remote-tracking branch 'origin/dev' into hotfix/AB#29460-recove…
plavoie-BC Jul 29, 2025
1d11f1c
AB#28585 - Tag Permissions - Add Application Tag Modal Permission Con…
plavoie-BC Jul 29, 2025
10b9951
AB#28585 - Tag Permissions - Add Payment Tag Modal Permission Constra…
plavoie-BC Jul 29, 2025
f10c6a4
Merge remote-tracking branch 'origin/dev' into feature/AB#28585-assig…
plavoie-BC Jul 29, 2025
1376a81
AB#28585 - Code Quality Improvements
plavoie-BC Jul 29, 2025
eebb127
AB#28707 - Remove display of unused Non-Registered Business Name Columns
plavoie-BC Jul 29, 2025
93a35bf
AB#28707 - Map IntakeMapping.NonRegisteredBusinessName to Applicant.N…
plavoie-BC Jul 29, 2025
56a0845
Merge pull request #1542 from bcgov/feature/AB#28707-non-reg-org-name…
JamesPasta Jul 29, 2025
38ed4ea
AB#29683: Remove note below the applicant merge screen
aurelio-aot Jul 29, 2025
cd8eedc
Merge remote-tracking branch 'origin/dev' into hotfix/AB#29460-recove…
plavoie-BC Jul 30, 2025
653ceee
bugfix/AB#29438 Fix dropdown alignment for column visibility option
samsaravillo Jul 30, 2025
ae717fb
AB#29460 - Add Recover Applicant Names DataFix Migration Script
plavoie-BC Jul 30, 2025
b58d185
Merge pull request #1546 from bcgov/hotfix/AB#29460-recover-applicant…
JamesPasta Jul 30, 2025
431fd52
Merge pull request #1545 from bcgov/bugfix/AB#29438-Fix-checkmark-on-…
JamesPasta Jul 30, 2025
2a2b4bd
Merge pull request #1543 from bcgov/bugfix/AB#29683-remove-deduplicat…
JamesPasta Jul 30, 2025
1b54b49
Merge pull request #1541 from bcgov/feature/AB#28585-assign-tag-permi…
JamesPasta Jul 30, 2025
fbf2c51
bugfix/AB#29607-FixAmounts
jimmyPasta Jul 30, 2025
9fa60cf
Update applications/Unity.GrantManager/modules/Unity.Payments/src/Uni…
JamesPasta Jul 30, 2025
75d6e6e
Update applications/Unity.GrantManager/modules/Unity.Payments/src/Uni…
JamesPasta Jul 30, 2025
e09d915
Update applications/Unity.GrantManager/modules/Unity.Payments/src/Uni…
JamesPasta Jul 30, 2025
4873a2d
Update applications/Unity.GrantManager/modules/Unity.Payments/src/Uni…
JamesPasta Jul 30, 2025
7cac551
Merge pull request #1547 from bcgov/feature/AB#28691-Payments
JamesPasta Jul 30, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,74 @@ public class QuestionDto : ExtensibleEntityDto<Guid>

public string? GetMin()
{
return JsonSerializer.Deserialize<NumericDefinition>(Definition ?? "{}")?.Min.ToString();
try
{
var def = JsonSerializer.Deserialize<NumericDefinition>(Definition ?? "{}");
if (def?.Min == null)
return null;
// Only allow Int64 values
if (long.TryParse(def.Min.ToString(), out var minValue))
return minValue.ToString();
return null;
}
catch
{
return null;
}
}

public string? GetMax()
{
return JsonSerializer.Deserialize<NumericDefinition>(Definition ?? "{}")?.Max.ToString();
try
{
var def = JsonSerializer.Deserialize<NumericDefinition>(Definition ?? "{}");
if (def?.Max == null)
return null;
// Only allow Int64 values
if (long.TryParse(def.Max.ToString(), out var maxValue))
return maxValue.ToString();
return null;
}
catch
{
return null;
}
}

public string? GetMinLength()
{
return JsonSerializer.Deserialize<TextDefinition>(Definition ?? "{}")?.MinLength.ToString();
try
{
var def = JsonSerializer.Deserialize<TextDefinition>(Definition ?? "{}");
if (def?.MinLength == null)
return null;
// Only allow Int64 values
if (long.TryParse(def.MinLength.ToString(), out var minLength))
return minLength.ToString();
return null;
}
catch
{
return null;
}
}

public string? GetMaxLength()
{
return JsonSerializer.Deserialize<TextDefinition>(Definition ?? "{}")?.MaxLength.ToString();
try
{
var def = JsonSerializer.Deserialize<TextDefinition>(Definition ?? "{}");
if (def?.MaxLength == null)
return null;
// Only allow Int64 values
if (long.TryParse(def.MaxLength.ToString(), out var maxLength))
return maxLength.ToString();
return null;
}
catch
{
return null;
}
}

public string? GetYesValue()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ public enum PaymentRequestStatus
L1Pending = 1,
L1Declined = 2,
L2Pending = 3,
L2Declined = 4,
L3Pending = 5,
L2Declined = 4,
L3Pending = 5,
L3Declined = 6,
Submitted = 7,
Validated = 8,
NotValidated = 9,
Paid = 10,
Failed = 11,
Failed = 11,
FSB = 12, // Financial Services Branch - Prevent CAS Payment
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;
using Volo.Abp.Application.Dtos;

namespace Unity.Payments.PaymentRequests
{
[Serializable]
public class AccountCodingDto : AuditedEntityDto<Guid>
{
public string MinistryClient { get; private set; }
public string Responsibility { get; private set; }
public string ServiceLine { get; private set; }
public string Stob { get; private set; }
public string ProjectNumber { get; private set; }
public AccountCodingDto()
{
MinistryClient = string.Empty;
Responsibility = string.Empty;
ServiceLine = string.Empty;
Stob = string.Empty;
ProjectNumber = string.Empty;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ public class PaymentRequestDto : AuditedEntityDto<Guid>
public string? Note { get; set; }
public string? ErrorSummary { get; set; }
public Guid? AccountCodingId { get; set; }
public AccountCodingDto? AccountCoding { get; set; }
public string AccountCodingDisplay { get; set; } = string.Empty;
public PaymentUserDto? CreatorUser { get; set; }
public Collection<PaymentTagDto> PaymentTags { get; set; }
public Collection<ExpenseApprovalDto> ExpenseApprovals { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Unity.Payments.Domain.Exceptions;
using Unity.Payments.PaymentRequests;
using Unity.Payments.Domain.PaymentTags;
using Unity.Payments.Domain.AccountCodings;

namespace Unity.Payments.Domain.PaymentRequests
{
Expand Down Expand Up @@ -60,7 +61,7 @@ public virtual Site Site
public virtual int? CasHttpStatusCode { get; private set; } = null;
public virtual string? CasResponse { get; private set; } = string.Empty;
public virtual Guid? AccountCodingId { get; private set; }

public virtual AccountCoding? AccountCoding { get; set; } = null;
public virtual string? Note { get; private set; } = null;
protected PaymentRequest()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,7 @@ namespace Unity.Payments.Domain.Services
public interface IPaymentsManager
{
Task UpdatePaymentStatusAsync(Guid paymentRequestId, PaymentApprovalAction triggerAction);
Task<bool> GetFormPreventPaymentStatusByPaymentRequestId(Guid paymentRequestId);
Task<bool> GetFormPreventPaymentStatusByApplicationId(Guid applicationId);
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
using Stateless;
using Microsoft.EntityFrameworkCore;
using Stateless;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Unity.GrantManager.Applications;
using Unity.Payments.Domain.PaymentRequests;
using Unity.Payments.Domain.Shared;
using Unity.Payments.Domain.Workflow;
Expand All @@ -16,28 +18,15 @@

namespace Unity.Payments.Domain.Services
{
public class PaymentsManager : DomainService, IPaymentsManager
{
/* To be implemented */
private readonly IPaymentRequestRepository _paymentRequestRepository;
private readonly IUnitOfWorkManager _unitOfWorkManager;
private readonly IPermissionChecker _permissionChecker;
private readonly CasPaymentRequestCoordinator _casPaymentRequestCoordinator;
private readonly ICurrentUser _currentUser;

public PaymentsManager(
public class PaymentsManager(
IApplicationRepository applicationRepository,
IApplicationFormRepository applicationFormRepository,
CasPaymentRequestCoordinator casPaymentRequestCoordinator,
IPaymentRequestRepository paymentRequestRepository,
IUnitOfWorkManager unitOfWorkManager,
IPermissionChecker permissionChecker,
ICurrentUser currentUser)
{
_casPaymentRequestCoordinator = casPaymentRequestCoordinator;
_paymentRequestRepository = paymentRequestRepository;
_unitOfWorkManager = unitOfWorkManager;
_permissionChecker = permissionChecker;
_currentUser = currentUser;
}
ICurrentUser currentUser) : DomainService, IPaymentsManager
{

private void ConfigureWorkflow(StateMachine<PaymentRequestStatus, PaymentApprovalAction> paymentStateMachine)
{
Expand Down Expand Up @@ -67,13 +56,12 @@ private void ConfigureWorkflow(StateMachine<PaymentRequestStatus, PaymentApprova

private bool HasPermission(string permission)
{
return _permissionChecker.IsGrantedAsync(permission).Result;
return permissionChecker.IsGrantedAsync(permission).Result;
}


public async Task<List<PaymentActionResultItem>> GetActions(Guid paymentRequestsId)
{
var paymentRequest = await _paymentRequestRepository.GetAsync(paymentRequestsId, true);
var paymentRequest = await paymentRequestRepository.GetAsync(paymentRequestsId, true);

var Workflow = new PaymentsWorkflow<PaymentRequestStatus, PaymentApprovalAction>(
() => paymentRequest.Status,
Expand All @@ -98,8 +86,8 @@ public async Task<List<PaymentActionResultItem>> GetActions(Guid paymentRequests

public async Task<PaymentRequest> TriggerAction(Guid paymentRequestsId, PaymentApprovalAction triggerAction)
{
var paymentRequest = await _paymentRequestRepository.GetAsync(paymentRequestsId, true);
var currentUserId = _currentUser.GetId();
var paymentRequest = await paymentRequestRepository.GetAsync(paymentRequestsId, true);
var currentUserId = currentUser.GetId();

var statusChange = paymentRequest.Status;

Expand All @@ -114,33 +102,33 @@ public async Task<PaymentRequest> TriggerAction(Guid paymentRequestsId, PaymentA

if (triggerAction == PaymentApprovalAction.L1Approve)
{
var index = paymentRequest.ExpenseApprovals.FindIndex(i => i.Type == Enums.ExpenseApprovalType.Level1);
var index = paymentRequest.ExpenseApprovals.FindIndex(i => i.Type == ExpenseApprovalType.Level1);
paymentRequest.ExpenseApprovals[index].Approve(currentUserId);
statusChangedTo = PaymentRequestStatus.L2Pending;
}
else if (triggerAction == PaymentApprovalAction.L1Decline)
{
var index = paymentRequest.ExpenseApprovals.FindIndex(i => i.Type == Enums.ExpenseApprovalType.Level1);
var index = paymentRequest.ExpenseApprovals.FindIndex(i => i.Type == ExpenseApprovalType.Level1);
paymentRequest.ExpenseApprovals[index].Decline(currentUserId);
statusChangedTo = PaymentRequestStatus.L1Declined;
}
else if (triggerAction == PaymentApprovalAction.L2Approve)
{
var index = paymentRequest.ExpenseApprovals.FindIndex(i => i.Type == Enums.ExpenseApprovalType.Level2);
var index = paymentRequest.ExpenseApprovals.FindIndex(i => i.Type == ExpenseApprovalType.Level2);
paymentRequest.ExpenseApprovals[index].Approve(currentUserId);
statusChangedTo = PaymentRequestStatus.L3Pending;

}
else if (triggerAction == PaymentApprovalAction.L2Decline)
{
var index = paymentRequest.ExpenseApprovals.FindIndex(i => i.Type == Enums.ExpenseApprovalType.Level2);
var index = paymentRequest.ExpenseApprovals.FindIndex(i => i.Type == ExpenseApprovalType.Level2);
paymentRequest.ExpenseApprovals[index].Decline(currentUserId);
statusChangedTo = PaymentRequestStatus.L2Declined;
}

else if (triggerAction == PaymentApprovalAction.L3Decline)
{
var index = paymentRequest.ExpenseApprovals.FindIndex(i => i.Type == Enums.ExpenseApprovalType.Level3);
var index = paymentRequest.ExpenseApprovals.FindIndex(i => i.Type == ExpenseApprovalType.Level3);
paymentRequest.ExpenseApprovals[index].Decline(currentUserId);
statusChangedTo = PaymentRequestStatus.L3Declined;
}
Expand All @@ -149,26 +137,56 @@ public async Task<PaymentRequest> TriggerAction(Guid paymentRequestsId, PaymentA
{
if (HasPermission(PaymentsPermissions.Payments.L2ApproveOrDecline))
{
var index = paymentRequest.ExpenseApprovals.FindIndex(i => i.Type == Enums.ExpenseApprovalType.Level2);
var index = paymentRequest.ExpenseApprovals.FindIndex(i => i.Type == ExpenseApprovalType.Level2);
paymentRequest.ExpenseApprovals[index].Approve(currentUserId);
}
else if (HasPermission(PaymentsPermissions.Payments.L3ApproveOrDecline))
{
var index = paymentRequest.ExpenseApprovals.FindIndex(i => i.Type == Enums.ExpenseApprovalType.Level3);
var index = paymentRequest.ExpenseApprovals.FindIndex(i => i.Type == ExpenseApprovalType.Level3);
paymentRequest.ExpenseApprovals[index].Approve(currentUserId);
}
bool preventPayment = await GetFormPreventPaymentStatusByApplicationId(paymentRequest.CorrelationId);

statusChangedTo = PaymentRequestStatus.Submitted;
await _casPaymentRequestCoordinator.AddPaymentRequestsToInvoiceQueue(paymentRequest);
if (preventPayment)
{
statusChangedTo = PaymentRequestStatus.FSB;
}
else
{
statusChangedTo = PaymentRequestStatus.Submitted;
await casPaymentRequestCoordinator.AddPaymentRequestsToInvoiceQueue(paymentRequest);
}


}
paymentRequest.SetPaymentRequestStatus(statusChangedTo);

return await _paymentRequestRepository.UpdateAsync(paymentRequest);
return await paymentRequestRepository.UpdateAsync(paymentRequest);
}

public async Task<bool> GetFormPreventPaymentStatusByPaymentRequestId(Guid paymentRequestId)
{
PaymentRequest paymentRequest = await paymentRequestRepository.GetAsync(paymentRequestId);
Guid applicationId = paymentRequest.CorrelationId;
var applicationQueryable = await applicationRepository.GetQueryableAsync();
var applicationWithIncludes = await applicationQueryable.Where(a => a.Id == applicationId)
.Include(a => a.ApplicationForm).ToListAsync();

var appForm = applicationWithIncludes.FirstOrDefault()?.ApplicationForm;
return appForm != null && appForm.PreventPayment;
}

public async Task<bool> GetFormPreventPaymentStatusByApplicationId(Guid applicationId)
{
Application application = await applicationRepository.GetAsync(applicationId);
Guid formId = application.ApplicationForm.Id;
ApplicationForm appForm = await applicationFormRepository.GetAsync(formId);
return appForm.PreventPayment;
}

public async Task UpdatePaymentStatusAsync(Guid paymentRequestId, PaymentApprovalAction triggerAction)
{
using var uow = _unitOfWorkManager.Begin();
using var uow = unitOfWorkManager.Begin();

await TriggerAction(paymentRequestId, triggerAction);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ public static void ConfigurePayments(
.WithMany()
.HasForeignKey(x => x.SiteId)
.OnDelete(DeleteBehavior.NoAction);

b.HasOne(e => e.AccountCoding)
.WithMany()
.HasForeignKey(x => x.AccountCodingId)
.OnDelete(DeleteBehavior.NoAction);

b.HasIndex(e => e.ReferenceNumber).IsUnique();
});
Expand Down
Loading