Skip to content

Commit

Permalink
CON-3124
Browse files Browse the repository at this point in the history
A spike to see if the performance can be increase of getting the monthly payments.
  • Loading branch information
hkf-tech committed Jun 25, 2021
1 parent 958dd5a commit 0b1d103
Show file tree
Hide file tree
Showing 8 changed files with 117 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@
<Build Include="Tables\TransactionLine_EOF.sql" />
<Build Include="StoredProcedures\CreateDraftExpiredFunds.sql" />
<Build Include="StoredProcedures\GetDraftExpiredFunds.sql" />
<Build Include="StoredProcedures\CreateAccountTransfersV1.sql" />
</ItemGroup>
<ItemGroup>
<None Include="Database.publish.xml" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
CREATE PROCEDURE [employer_financial].[CreateAccountTransfersV1]
@transfers [employer_financial].[AccountTransferTable] READONLY
AS
INSERT INTO [employer_financial].[AccountTransfers]
(
SenderAccountId,
SenderAccountName,
ReceiverAccountId,
ReceiverAccountName,
ApprenticeshipId,
CourseName,
CourseLevel,
PeriodEnd,
Amount,
Type,
CreatedDate,
RequiredPaymentId
)
Select
tr.SenderAccountId,
actSender.Name,
tr.ReceiverAccountId,
actReceiver.Name,
tr.ApprenticeshipId,
IsNull(Ir.CourseName, 'Unknown Course'),
Ir.CourseLevel,
tr.PeriodEnd,
tr.Amount,
tr.Type, GetDate(),
tr.RequiredPaymentId
FROM
(SELECT
p.AccountId,
p.PeriodEnd,
p.ApprenticeshipId,
meta.ApprenticeshipCourseName as CourseName
,meta.ApprenticeshipCourseLevel as CourseLevel
,COUNT(DISTINCT Uln) as ApprenticeCount -- This can be commented out not used any where.
,SUM(p.Amount) as PaymentTotal -- This can also be commented out not used any where.
FROM [employer_financial].[Payment] p
INNER JOIN [employer_financial].[PaymentMetaData] meta ON p.PaymentMetaDataId = meta.Id
Inner join @transfers tr on p.AccountId = tr.ReceiverAccountId and p.PeriodEnd = tr.PeriodEnd and p.ApprenticeshipId = tr.ApprenticeshipId
GROUP BY meta.ApprenticeshipCourseName, meta.ApprenticeshipCourseLevel, p.AccountId, p.PeriodEnd, p.ApprenticeshipId) Ir
-- assumption combination of ReceiverAccountId,PeriodEnd & ApprenticeshipId gives a unique row for the information received from payments.
Inner join @transfers tr on Ir.AccountId = tr.ReceiverAccountId and Ir.PeriodEnd = tr.PeriodEnd and Ir.ApprenticeshipId = tr.ApprenticeshipId
Inner join [employer_financial].[Account] actSender on actSender.Id = tr.SenderAccountId
Inner join [employer_financial].[Account] actReceiver on actReceiver.Id = tr.ReceiverAccountId
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,10 @@ CREATE NONCLUSTERED INDEX [IX_Payment_AccountIdUkprnPeriodEndUln] ON [employer_f
GO

CREATE NONCLUSTERED INDEX [IX_Payment_AccountIdCollectionPeriodMonthCollectionPeriodYear] ON [employer_financial].[Payment] ([AccountId], [CollectionPeriodMonth], [CollectionPeriodYear]) INCLUDE ([Amount], [ApprenticeshipId], [CollectionPeriodId], [DeliveryPeriodMonth], [DeliveryPeriodYear], [FundingSource], [PaymentMetaDataId], [PeriodEnd], [Ukprn], [Uln]) WITH (ONLINE = ON)
GO

CREATE NONCLUSTERED INDEX [IX_Payment_Ukprn] ON [employer_financial].[Payment] ([Ukprn]) WITH (ONLINE = ON)
GO

CREATE NONCLUSTERED INDEX [IX_Payment_UkprnAccountId] ON [employer_financial].[Payment] ([AccountId], [Ukprn]) WITH (ONLINE = ON)
GO
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,6 @@ GO

CREATE UNIQUE NONCLUSTERED INDEX [UK_TransactionLine_AccountId_TransactionType_TransactionDate] ON [employer_financial].[TransactionLine] ([AccountId] ASC, [TransactionType] ASC, [TransactionDate] ASC) WHERE [TransactionType] = /*ExpiredFund*/ 5
GO

CREATE INDEX [IX_TransactionLine_Account_DateCreated] ON [employer_financial].[TransactionLine] (AccountId, DateCreated) WITH (ONLINE = ON)
GO
Original file line number Diff line number Diff line change
Expand Up @@ -62,37 +62,48 @@ protected override async Task HandleCore(RefreshAccountTransfersCommand message)
Amount = g.Sum(x => x.Amount),
ApprenticeshipId = firstGroupItem.ApprenticeshipId,
ReceiverAccountId = firstGroupItem.ReceiverAccountId,
// assumption we are not getting this information back from payment, that is why we are getting it again from the local db
ReceiverAccountName = firstGroupItem.ReceiverAccountName,
SenderAccountId = firstGroupItem.SenderAccountId,
// assumption we are not getting this information back from payment, that is why we are getting it again from the local db
SenderAccountName = firstGroupItem.SenderAccountName,
Type = firstGroupItem.Type
// Not mapping the RequiredPaymentId - I assume this is not required, but we are trying to insert it into the transfers table.
};
}).ToArray();

var transferSenderIds = transfers.Select(t => t.SenderAccountId).Distinct();

/*
//The following two can be parallelized
var transferSenderAccountNames = await _accountRepository.GetAccountNames(transferSenderIds);
var transferReceiverAccountName = await _accountRepository.GetAccountName(message.ReceiverAccountId);
foreach (var transfer in transfers)
{
// Can this be different? why assign again?
transfer.PeriodEnd = message.PeriodEnd;

// can CreateAccountTransfers & the following procedure merged into one and just pass in the Id of transfer
// so we don't event get the Names of Transfer Sender & Receiver.
var paymentDetails = await _transferRepository.GetTransferPaymentDetails(transfer);
transfer.CourseName = paymentDetails.CourseName ?? "Unknown Course";
transfer.CourseLevel = paymentDetails.CourseLevel;
// Don't see this getting used any where
transfer.ApprenticeCount = paymentDetails.ApprenticeCount;
transfer.SenderAccountName = transferSenderAccountNames[transfer.SenderAccountId];
transfer.ReceiverAccountName = transferReceiverAccountName;
// If it all goes into stored procedure we will lose this check.
if (transfer.Amount != paymentDetails.PaymentTotal)
_logger.Warn("Transfer total does not match transfer payments total");
}
*/

await _transferRepository.CreateAccountTransfers(transfers);
await _transferRepository.CreateAccountTransfersV1(transfers);
}
catch (Exception ex)
{
Expand Down
1 change: 1 addition & 0 deletions src/SFA.DAS.EmployerFinance/Data/ITransferRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ namespace SFA.DAS.EmployerFinance.Data
{
public interface ITransferRepository
{
Task CreateAccountTransfersV1(IEnumerable<AccountTransfer> transfers);
Task CreateAccountTransfers(IEnumerable<AccountTransfer> transfers);
Task<IEnumerable<AccountTransfer>> GetReceiverAccountTransfersByPeriodEnd(long receiverAccountId, string periodEnd);
Task<AccountTransferDetails> GetTransferPaymentDetails(AccountTransfer transfer);
Expand Down
15 changes: 15 additions & 0 deletions src/SFA.DAS.EmployerFinance/Data/TransferRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,21 @@ public Task CreateAccountTransfers(IEnumerable<AccountTransfer> transfers)
commandType: CommandType.StoredProcedure);
}

public Task CreateAccountTransfersV1(IEnumerable<AccountTransfer> transfers)
{
var accountTransfers = transfers as AccountTransfer[] ?? transfers.ToArray();
var transferDataTable = CreateTransferDataTable(accountTransfers);
var parameters = new DynamicParameters();

parameters.Add("@transfers", transferDataTable.AsTableValuedParameter("[employer_financial].[AccountTransferTable]"));

return _db.Value.Database.Connection.ExecuteAsync(
sql: "[employer_financial].[CreateAccountTransfersV1]",
param: parameters,
transaction: _db.Value.Database.CurrentTransaction.UnderlyingTransaction,
commandType: CommandType.StoredProcedure);
}

public Task<IEnumerable<AccountTransfer>> GetReceiverAccountTransfersByPeriodEnd(long receiverAccountId, string periodEnd)
{
var parameters = new DynamicParameters();
Expand Down
33 changes: 31 additions & 2 deletions src/SFA.DAS.EmployerFinance/Services/PaymentService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@

namespace SFA.DAS.EmployerFinance.Services
{
public class ApprenticeshipCache
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string NINumber { get; set; }
public DateTime? StartDate { get; set; }
public long ApprenticeshipId { get; set; }
}
public class PaymentService : IPaymentService
{
private readonly IPaymentsEventsApiClient _paymentsEventsApiClient;
Expand All @@ -26,6 +34,7 @@ public class PaymentService : IPaymentService
private readonly ILog _logger;
private readonly IInProcessCache _inProcessCache;
private readonly IProviderService _providerService;
private readonly List<ApprenticeshipCache> _apprenticeships;

public PaymentService(IPaymentsEventsApiClient paymentsEventsApiClient,
IEmployerCommitmentApi commitmentsApiClient, IApprenticeshipInfoServiceWrapper apprenticeshipInfoService,
Expand All @@ -38,6 +47,7 @@ public PaymentService(IPaymentsEventsApiClient paymentsEventsApiClient,
_logger = logger;
_inProcessCache = inProcessCache;
_providerService = providerService;
_apprenticeships = new List<ApprenticeshipCache>();
}

public async Task<ICollection<PaymentDetails>> GetAccountPayments(string periodEnd, long employerAccountId)
Expand Down Expand Up @@ -150,11 +160,30 @@ private async Task GetApprenticeshipDetails(long employerAccountId, PaymentDetai
}
}

private async Task<Apprenticeship> GetApprenticeship(long employerAccountId, long apprenticeshipId)
private async Task<ApprenticeshipCache> GetApprenticeship(long employerAccountId, long apprenticeshipId)
{
try
{
return await _commitmentsApiClient.GetEmployerApprenticeship(employerAccountId, apprenticeshipId);
var apprenticeshipFromCache =_apprenticeships.FirstOrDefault(x => x.ApprenticeshipId == apprenticeshipId);

if (apprenticeshipFromCache == null)
{
var apprenticeship = await _commitmentsApiClient.GetEmployerApprenticeship(employerAccountId, apprenticeshipId);
_apprenticeships.Add(new ApprenticeshipCache
{
FirstName = apprenticeship.FirstName,
LastName = apprenticeship.LastName,
NINumber = apprenticeship.NINumber,
StartDate = apprenticeship.StartDate
});
}
else
{
_logger.Info("Found apprenticeship from cache :" + apprenticeshipFromCache.ApprenticeshipId);
}

_logger.Info("Cache apprenticeship size :" + _apprenticeships.Count());
return apprenticeshipFromCache;
}
catch (Exception e)
{
Expand Down

0 comments on commit 0b1d103

Please sign in to comment.