Skip to content
Merged

Dev #1735

Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -49,7 +49,8 @@ public async Task SeedAsync(DataSeedContext context)
{
foreach (var template in emailTemplateVariableDtos)
{
var existingVariable = await templateVariablesRepository.FindAsync(tv => tv.Token == template.Token);
var allVariables = await templateVariablesRepository.GetListAsync();
var existingVariable = allVariables.FirstOrDefault(tv => tv.Token == template.Token);
if (existingVariable == null)
{
await templateVariablesRepository.InsertAsync(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ public interface IPaymentRequestAppService : IApplicationService
Task<string> GetNextBatchInfoAsync();
Task<Guid?> GetDefaultAccountCodingId();
Task<decimal?> GetUserPaymentThresholdAsync();
Task ManuallyAddPaymentRequestsToReconciliationQueue(List<Guid> paymentRequestIds);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ private async Task<Dictionary<string, Site>> UpsertSitesFromEventDtoAsync(
{
foreach (var siteEto in upsertSupplierEto.SiteEtos)
{
var siteDto = GetSiteDtoFromSiteEto(siteEto, supplierId);
var siteDto = supplierAppService.GetSiteDtoFromSiteEto(siteEto, supplierId);

if (existingSitesDictionary.TryGetValue(siteDto.Number, out var existingSite))
{
Expand Down Expand Up @@ -81,29 +81,6 @@ private async Task<SupplierDto> GetSupplierFromEvent(UpsertSupplierEto eventData
return supplierDto;
}

private static SiteDto GetSiteDtoFromSiteEto(SiteEto siteEto, Guid supplierId)
{
return new()
{
Number = siteEto.SupplierSiteCode,
PaymentGroup = Enums.PaymentGroup.EFT, // Defaulting to EFT based on conversations with CGG/CAS
AddressLine1 = siteEto.AddressLine1,
AddressLine2 = siteEto.AddressLine2,
AddressLine3 = siteEto.AddressLine3,
City = siteEto.City,
Province = siteEto.Province,
PostalCode = siteEto.PostalCode,
SupplierId = supplierId,
Country = siteEto.Country,
EmailAddress = siteEto.EmailAddress,
EFTAdvicePref = siteEto.EFTAdvicePref,
BankAccount = siteEto.BankAccount,
ProviderId = siteEto.ProviderId,
Status = siteEto.Status,
SiteProtected = siteEto.SiteProtected,
LastUpdatedInCas = siteEto.LastUpdated
};
}

private static UpdateSupplierDto GetUpdateSupplierDtoFromEvent(UpsertSupplierEto eventData)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ public interface ISupplierService : IApplicationService
Task<dynamic> GetCasSupplierInformationAsync(string? supplierNumber);
Task UpdateApplicantSupplierInfo(string? supplierNumber, Guid applicantId);
Task<dynamic> UpdateApplicantSupplierInfoByBn9(string? bn9, Guid applicantId);
Task UpdateSupplierInfo(dynamic casSupplierResponse, Guid applicantId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using System.Threading.Tasks;
using System.Text.Json;
using Volo.Abp.Application.Services;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
using System.Net.Http;
using Unity.Modules.Shared.Http;
Expand Down Expand Up @@ -93,7 +92,7 @@ public async Task<dynamic> UpdateApplicantSupplierInfoByBn9(string? bn9, Guid ap
return casSupplierResponse;
}

private async Task UpdateSupplierInfo(dynamic casSupplierResponse, Guid applicantId)
public async Task UpdateSupplierInfo(dynamic casSupplierResponse, Guid applicantId)
{
try
{
Expand Down Expand Up @@ -159,7 +158,7 @@ string GetProp(string name) =>
}


protected static SiteEto GetSiteEto(JsonElement site)
public static SiteEto GetSiteEto(JsonElement site)
{
string accountNumber = GetJsonProperty("accountnumber", site);
string maskedAccountNumber = accountNumber.Length > 4
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public class CasPaymentRequestCoordinator : ApplicationService
private readonly ITenantRepository _tenantRepository;
private readonly ICurrentTenant _currentTenant;
private readonly PaymentQueueService _paymentQueueService;
private static int FiveMinutes = 5;
private static int TenMinutes = 10;

public CasPaymentRequestCoordinator(
PaymentQueueService paymentQueueService,
Expand Down Expand Up @@ -63,7 +63,7 @@ public async Task AddPaymentRequestsToInvoiceQueue(PaymentRequest paymentRequest
{
InvoiceMessages message = new InvoiceMessages
{
TimeToLive = TimeSpan.FromMinutes(FiveMinutes),
TimeToLive = TimeSpan.FromMinutes(TenMinutes),
PaymentRequestId = paymentRequest.Id,
InvoiceNumber = paymentRequest.InvoiceNumber,
SupplierNumber = paymentRequest.SupplierNumber,
Expand All @@ -81,6 +81,24 @@ public async Task AddPaymentRequestsToInvoiceQueue(PaymentRequest paymentRequest
}
}

public async Task ManuallyAddPaymentRequestsToReconciliationQueue(List<PaymentRequestDto>paymentRequests)
{
foreach (PaymentRequestDto paymentRequest in paymentRequests)
{
ReconcilePaymentMessages reconcilePaymentMessage = new ReconcilePaymentMessages
{
TimeToLive = TimeSpan.FromMinutes(TenMinutes),
PaymentRequestId = paymentRequest.Id,
InvoiceNumber = paymentRequest.InvoiceNumber,
SupplierNumber = paymentRequest.SupplierNumber,
SiteNumber = paymentRequest.Site?.Number ?? string.Empty,
TenantId = _currentTenant.Id!.Value
};

await _paymentQueueService.SendPaymentToReconciliationQueueAsync(reconcilePaymentMessage);
}
}

public async Task AddPaymentRequestsToReconciliationQueue()
{
var tenants = await _tenantRepository.GetListAsync();
Expand All @@ -93,7 +111,7 @@ public async Task AddPaymentRequestsToReconciliationQueue()
{
ReconcilePaymentMessages reconcilePaymentMessage = new ReconcilePaymentMessages
{
TimeToLive = TimeSpan.FromMinutes(FiveMinutes),
TimeToLive = TimeSpan.FromMinutes(TenMinutes),
PaymentRequestId = paymentRequest.Id,
InvoiceNumber = paymentRequest.InvoiceNumber,
SupplierNumber = paymentRequest.SupplierNumber,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
using Unity.Payments.Domain.PaymentThresholds;
using Volo.Abp.Domain.Repositories;
using Unity.GrantManager.Applications;
using Unity.Payments.Domain.Suppliers;
using Unity.Payments.Suppliers;

namespace Unity.Payments.PaymentRequests
{
Expand All @@ -37,7 +39,9 @@ public class PaymentRequestAppService(
IPaymentsManager paymentsManager,
IPaymentRequestRepository paymentRequestsRepository,
IPaymentThresholdRepository paymentThresholdRepository,
IPermissionChecker permissionChecker) : PaymentsAppService, IPaymentRequestAppService
IPermissionChecker permissionChecker,
ISiteRepository siteRepository,
CasPaymentRequestCoordinator casPaymentRequestCoordinator) : PaymentsAppService, IPaymentRequestAppService
#pragma warning restore S107

{
Expand Down Expand Up @@ -427,12 +431,15 @@ protected internal async Task<List<PaymentRequestDto>> MapToDtoAndLoadDetailsAsy
paymentRequestDto.AccountCodingDisplay = await GetAccountDistributionCode(paymentRequestDto.AccountCoding);
}

foreach (var expenseApproval in paymentRequestDto.ExpenseApprovals)
if (paymentRequestDto != null && paymentRequestDto.ExpenseApprovals != null)
{
if (expenseApproval.DecisionUserId.HasValue
&& userDictionary.TryGetValue(expenseApproval.DecisionUserId.Value, out var expenseApprovalUserDto))
foreach (var expenseApproval in paymentRequestDto.ExpenseApprovals)
{
expenseApproval.DecisionUser = expenseApprovalUserDto;
if (expenseApproval.DecisionUserId.HasValue
&& userDictionary.TryGetValue(expenseApproval.DecisionUserId.Value, out var expenseApprovalUserDto))
{
expenseApproval.DecisionUser = expenseApprovalUserDto;
}
}
}
}
Expand Down Expand Up @@ -524,6 +531,23 @@ protected virtual string GetCurrentRequesterName()
return null;
}

public async Task ManuallyAddPaymentRequestsToReconciliationQueue(List<Guid> paymentRequestIds)
{
List<PaymentRequestDto> paymentRequestDtos = [];
foreach (var paymentRequestId in paymentRequestIds)
{
var paymentRequest = await paymentRequestsRepository.GetAsync(paymentRequestId);
if (paymentRequest != null)
{
var paymentRequestDto = ObjectMapper.Map<PaymentRequest, PaymentRequestDto>(paymentRequest);
Site site = await siteRepository.GetAsync(paymentRequest.SiteId);
paymentRequestDto.Site = ObjectMapper.Map<Site, SiteDto>(site);
paymentRequestDtos.Add(paymentRequestDto);
}
}
await casPaymentRequestCoordinator.ManuallyAddPaymentRequestsToReconciliationQueue(paymentRequestDtos);
}

private async Task<int> GetNextSequenceNumberAsync(int currentYear)
{
// Retrieve all payment requests
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ public interface ISupplierAppService : IApplicationService
Task<SupplierDto> UpdateAsync(Guid id, UpdateSupplierDto updateSupplierDto);
Task<SiteDto> CreateSiteAsync(Guid id, CreateSiteDto createSiteDto);
Task<SiteDto> UpdateSiteAsync(Guid id, Guid siteId, UpdateSiteDto updateSiteDto);
Task<List<SiteDto>> GetSitesBySupplierNumberAsync(string? supplierNumber);
Task DeleteAsync(Guid id);
Task<dynamic> GetSitesBySupplierNumberAsync(string? supplierNumber, Guid applicantId);
Task DeleteAsync(Guid id);
SiteDto GetSiteDtoFromSiteEto(SiteEto siteEto, Guid supplierId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using Unity.Payments.Domain.Suppliers;
using Unity.Payments.Domain.Suppliers.ValueObjects;
using Unity.Payments.Integrations.Cas;
using Volo.Abp.Features;

namespace Unity.Payments.Suppliers
{
[RequiresFeature("Unity.Payments")]
public class SupplierAppService(ISupplierRepository supplierRepository,
ISupplierService supplierService,
ISiteAppService siteAppService) : PaymentsAppService, ISupplierAppService
{
protected ILogger logger => LazyServiceProvider.LazyGetService<ILogger>(provider => LoggerFactory?.CreateLogger(GetType().FullName!) ?? NullLogger.Instance);
Expand Down Expand Up @@ -99,12 +102,81 @@ public virtual async Task<SupplierDto> UpdateAsync(Guid id, UpdateSupplierDto up
return ObjectMapper.Map<Supplier, SupplierDto?>(result);
}

public async Task<List<SiteDto>> GetSitesBySupplierNumberAsync(string? supplierNumber)
public async Task<dynamic> GetSitesBySupplierNumberAsync(string? supplierNumber, Guid applicantId)
{
// Change this code to get the supplier list of sites - from the datatabase which it is currently doing
// Then go to CAS and get the list of sites again
// Compare and update the database if there are any new sites
dynamic casSupplierResponse = await supplierService.GetCasSupplierInformationAsync(supplierNumber);
var casSiteDtos = new List<SiteDto>();
if (casSupplierResponse.TryGetProperty("supplieraddress", out JsonElement sitesJson) &&
sitesJson.ValueKind == JsonValueKind.Array)
{
foreach (var site in sitesJson.EnumerateArray())
{
SiteEto siteEto = SupplierService.GetSiteEto(site);
SiteDto siteDto = GetSiteDtoFromSiteEto(siteEto, Guid.Empty);
casSiteDtos.Add(siteDto);
}
}

var supplier = await GetBySupplierNumberAsync(supplierNumber);
if (supplier == null) return new List<SiteDto>();
List<Site> sites = await siteAppService.GetSitesBySupplierIdAsync(supplier.Id);
return sites.Select(ObjectMapper.Map<Site, SiteDto>).ToList();
List<SiteDto> existingSiteDtos = sites.Select(ObjectMapper.Map<Site, SiteDto>).ToList();

bool hasChanges = false;
// If the list of CAS sites is different from the existing sites
if (existingSiteDtos.Count != casSiteDtos.Count)
{
// Update the supplier and sites
hasChanges = true;
}
else if (existingSiteDtos.Count == casSiteDtos.Count)
{
// Go through each site and compare
hasChanges = false;

// based on the matching number, check if any other fields are different
foreach (var casSite in casSiteDtos)
{
var existingSite = existingSiteDtos.FirstOrDefault(s => s.Number == casSite.Number);
if (existingSite != null)
{
// Compare fields and update if necessary
if (existingSite.Country != casSite.Country ||
existingSite.EFTAdvicePref != casSite.EFTAdvicePref ||
existingSite.EmailAddress != casSite.EmailAddress ||
existingSite.PostalCode != casSite.PostalCode ||
existingSite.ProviderId != casSite.ProviderId ||
existingSite.Province != casSite.Province ||
existingSite.SiteProtected != casSite.SiteProtected ||
existingSite.City != casSite.City ||
existingSite.AddressLine1 != casSite.AddressLine1 ||
existingSite.AddressLine2 != casSite.AddressLine2 ||
existingSite.BankAccount != casSite.BankAccount ||
existingSite.Status != casSite.Status)
{
hasChanges = true;
break;
}
}
else
{
hasChanges = true;
break;
}
}
}

if (hasChanges)
{
await supplierService.UpdateSupplierInfo(casSupplierResponse, applicantId);
existingSiteDtos = casSiteDtos;
}


return new { sites = existingSiteDtos, hasChanges };
}

public virtual async Task<SiteDto> CreateSiteAsync(Guid id, CreateSiteDto createSiteDto)
Expand Down Expand Up @@ -149,5 +221,29 @@ public virtual async Task DeleteAsync(Guid id)
{
await supplierRepository.DeleteAsync(id);
}

public SiteDto GetSiteDtoFromSiteEto(SiteEto siteEto, Guid supplierId)
{
return new()
{
Number = siteEto.SupplierSiteCode,
PaymentGroup = Enums.PaymentGroup.EFT, // Defaulting to EFT based on conversations with CGG/CAS
AddressLine1 = siteEto.AddressLine1,
AddressLine2 = siteEto.AddressLine2,
AddressLine3 = siteEto.AddressLine3,
City = siteEto.City,
Province = siteEto.Province,
PostalCode = siteEto.PostalCode,
SupplierId = supplierId,
Country = siteEto.Country,
EmailAddress = siteEto.EmailAddress,
EFTAdvicePref = siteEto.EFTAdvicePref,
BankAccount = siteEto.BankAccount,
ProviderId = siteEto.ProviderId,
Status = siteEto.Status,
SiteProtected = siteEto.SiteProtected,
LastUpdatedInCas = siteEto.LastUpdated
};
}
}
}
Loading