Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(registration) : update dateLastChange companyApplication #307

Merged
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 @@ -54,6 +54,19 @@ public void AttachAndModifyCompanyApplication(Guid companyApplicationId, Action<
setOptionalParameters.Invoke(companyApplication);
}

public void AttachAndModifyCompanyApplications(IEnumerable<(Guid companyApplicationId, Action<CompanyApplication>? Initialize, Action<CompanyApplication> Modify)> applicationData)
{
var initial = applicationData.Select(x =>
{
var companyApplication = new CompanyApplication(x.companyApplicationId, Guid.Empty, default, default, default);
x.Initialize?.Invoke(companyApplication);
return (CompanyApplication: companyApplication, x.Modify);
}
).ToList();
_dbContext.AttachRange(initial.Select(x => x.CompanyApplication));
initial.ForEach(x => x.Modify(x.CompanyApplication));
}

public Invitation CreateInvitation(Guid applicationId, Guid companyUserId) =>
_dbContext.Invitations.Add(
new Invitation(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Entities;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities.Enums;
using System.Security.Cryptography.X509Certificates;

namespace Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Repositories;

Expand Down Expand Up @@ -129,7 +130,7 @@ public void RemoveDocument(Guid documentId) =>
this._dbContext.Documents.SingleOrDefaultAsync(x => x.Id == documentId);

/// <inheritdoc />
public Task<(Guid DocumentId, DocumentStatusId DocumentStatusId, bool IsSameApplicationUser, DocumentTypeId documentTypeId, bool IsQueriedApplicationStatus)> GetDocumentDetailsForApplicationUntrackedAsync(Guid documentId, Guid userCompanyId, IEnumerable<CompanyApplicationStatusId> applicationStatusIds) =>
public Task<(Guid DocumentId, DocumentStatusId DocumentStatusId, bool IsSameApplicationUser, DocumentTypeId documentTypeId, bool IsQueriedApplicationStatus, IEnumerable<Guid> applicationId)> GetDocumentDetailsForApplicationUntrackedAsync(Guid documentId, Guid userCompanyId, IEnumerable<CompanyApplicationStatusId> applicationStatusIds) =>
_dbContext.Documents
.AsNoTracking()
.Where(x => x.Id == documentId)
Expand All @@ -138,12 +139,13 @@ public void RemoveDocument(Guid documentId) =>
Document = document,
Applications = document.CompanyUser!.Identity!.Company!.CompanyApplications
})
.Select(x => new ValueTuple<Guid, DocumentStatusId, bool, DocumentTypeId, bool>(
.Select(x => new ValueTuple<Guid, DocumentStatusId, bool, DocumentTypeId, bool, IEnumerable<Guid>>(
x.Document.Id,
x.Document.DocumentStatusId,
x.Applications.Any(companyApplication => companyApplication.CompanyId == userCompanyId),
x.Document.DocumentTypeId,
x.Applications.Any(companyApplication => applicationStatusIds.Contains(companyApplication.ApplicationStatusId))))
x.Applications.Any(companyApplication => applicationStatusIds.Contains(companyApplication.ApplicationStatusId)),
x.Applications.Select(x => x.Id)))
.SingleOrDefaultAsync();

/// <inheritdoc />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public interface IApplicationRepository
{
CompanyApplication CreateCompanyApplication(Guid companyId, CompanyApplicationStatusId companyApplicationStatusId, CompanyApplicationTypeId applicationTypeId, Action<CompanyApplication>? setOptionalFields = null);
void AttachAndModifyCompanyApplication(Guid companyApplicationId, Action<CompanyApplication> setOptionalParameters);
void AttachAndModifyCompanyApplications(IEnumerable<(Guid companyApplicationId, Action<CompanyApplication>? Initialize, Action<CompanyApplication> Modify)> applicationData);
Invitation CreateInvitation(Guid applicationId, Guid companyUserId);
void DeleteInvitations(IEnumerable<Guid> invitationIds);
Task<(bool Exists, CompanyApplicationStatusId StatusId)> GetOwnCompanyApplicationUserDataAsync(Guid applicationId, Guid userCompanyId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ public interface IDocumentRepository
/// <param name="documentId"></param>
/// <param name="userCompanyId"></param>
/// <param name="applicationStatusIds"></param>
Task<(Guid DocumentId, DocumentStatusId DocumentStatusId, bool IsSameApplicationUser, DocumentTypeId documentTypeId, bool IsQueriedApplicationStatus)> GetDocumentDetailsForApplicationUntrackedAsync(Guid documentId, Guid userCompanyId, IEnumerable<CompanyApplicationStatusId> applicationStatusIds);
/// <param name="applicationId"></param>
Task<(Guid DocumentId, DocumentStatusId DocumentStatusId, bool IsSameApplicationUser, DocumentTypeId documentTypeId, bool IsQueriedApplicationStatus, IEnumerable<Guid> applicationId)> GetDocumentDetailsForApplicationUntrackedAsync(Guid documentId, Guid userCompanyId, IEnumerable<CompanyApplicationStatusId> applicationStatusIds);

/// <summary>
/// Attaches the document and sets the optional parameters
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
using Microsoft.Extensions.Options;
using Org.Eclipse.TractusX.Portal.Backend.Bpdm.Library;
using Org.Eclipse.TractusX.Portal.Backend.Bpdm.Library.Models;
using Org.Eclipse.TractusX.Portal.Backend.Framework.DateTimeProvider;
using Org.Eclipse.TractusX.Portal.Backend.Framework.ErrorHandling;
using Org.Eclipse.TractusX.Portal.Backend.Framework.Models.Configuration;
using Org.Eclipse.TractusX.Portal.Backend.Framework.Web;
Expand Down Expand Up @@ -52,6 +53,7 @@ public class RegistrationBusinessLogic : IRegistrationBusinessLogic
private readonly ILogger<RegistrationBusinessLogic> _logger;
private readonly IApplicationChecklistCreationService _checklistService;
private readonly IIdentityService _identityService;
private readonly IDateTimeProvider _dateTimeProvider;

private static readonly Regex bpnRegex = new(@"(\w|\d){16}", RegexOptions.None, TimeSpan.FromSeconds(1));

Expand All @@ -64,7 +66,8 @@ public RegistrationBusinessLogic(
ILogger<RegistrationBusinessLogic> logger,
IPortalRepositories portalRepositories,
IApplicationChecklistCreationService checklistService,
IIdentityService identityService)
IIdentityService identityService,
IDateTimeProvider dateTimeProvider)
{
_settings = settings.Value;
_mailingService = mailingService;
Expand All @@ -75,6 +78,7 @@ public RegistrationBusinessLogic(
_portalRepositories = portalRepositories;
_checklistService = checklistService;
_identityService = identityService;
_dateTimeProvider = dateTimeProvider;
}

public IAsyncEnumerable<string> GetClientRolesCompositeAsync() =>
Expand Down Expand Up @@ -166,7 +170,10 @@ public async Task<int> UploadDocumentAsync(Guid applicationId, IFormFile documen
{
throw new ForbiddenException($"The users company is not assigned with application {applicationId}");
}

_portalRepositories.GetInstance<IApplicationRepository>().AttachAndModifyCompanyApplication(applicationId, application =>
{
application.DateLastChanged = _dateTimeProvider.OffsetNow;
});
var mediaTypeId = document.ContentType.ParseMediaTypeId();
var (content, hash) = await document.GetContentAndHash(cancellationToken).ConfigureAwait(false);

Expand Down Expand Up @@ -276,7 +283,7 @@ private async Task SetCompanyDetailDataInternal(Guid applicationId, CompanyDetai

companyRepository.CreateUpdateDeleteIdentifiers(companyDetails.CompanyId, companyApplicationData.UniqueIds, companyDetails.UniqueIds.Select(x => (x.UniqueIdentifierId, x.Value)));

UpdateApplicationStatus(applicationId, companyApplicationData.ApplicationStatusId, UpdateApplicationSteps.CompanyWithAddress, applicationRepository);
UpdateApplicationStatus(applicationId, companyApplicationData.ApplicationStatusId, UpdateApplicationSteps.CompanyWithAddress, applicationRepository, _dateTimeProvider);

await _portalRepositories.SaveAsync().ConfigureAwait(false);
}
Expand Down Expand Up @@ -434,6 +441,10 @@ private async Task<int> InviteNewUserInternalAsync(Guid applicationId, UserCreat
}

_portalRepositories.GetInstance<IApplicationRepository>().CreateInvitation(applicationId, newCompanyUserId);
_portalRepositories.GetInstance<IApplicationRepository>().AttachAndModifyCompanyApplication(applicationId, application =>
{
application.DateLastChanged = _dateTimeProvider.OffsetNow;
});

var modified = await _portalRepositories.SaveAsync().ConfigureAwait(false);

Expand Down Expand Up @@ -474,7 +485,7 @@ public async Task<int> SetOwnCompanyApplicationStatusAsync(Guid applicationId, C
throw new NotFoundException($"CompanyApplication {applicationId} not found");
}

ValidateCompanyApplicationStatus(applicationId, status, applicationUserData, applicationRepository);
ValidateCompanyApplicationStatus(applicationId, status, applicationUserData, applicationRepository, _dateTimeProvider);

return await _portalRepositories.SaveAsync().ConfigureAwait(false);
}
Expand Down Expand Up @@ -545,7 +556,7 @@ public async Task<int> SubmitRoleConsentAsync(Guid applicationId, CompanyRoleAgr

HandleConsent(consents, agreementConsentsToSet, consentRepository, companyId, userId);

UpdateApplicationStatus(applicationId, applicationStatusId, UpdateApplicationSteps.CompanyRoleAgreementConsents, _portalRepositories.GetInstance<IApplicationRepository>());
UpdateApplicationStatus(applicationId, applicationStatusId, UpdateApplicationSteps.CompanyRoleAgreementConsents, _portalRepositories.GetInstance<IApplicationRepository>(), _dateTimeProvider);

return await _portalRepositories.SaveAsync().ConfigureAwait(false);
}
Expand Down Expand Up @@ -598,6 +609,7 @@ public async Task<bool> SubmitRegistrationAsync(Guid applicationId)
{
application.ApplicationStatusId = CompanyApplicationStatusId.SUBMITTED;
application.ChecklistProcessId = process.Id;
application.DateLastChanged = _dateTimeProvider.OffsetNow;
});

await _portalRepositories.SaveAsync().ConfigureAwait(false);
Expand Down Expand Up @@ -717,7 +729,10 @@ public async Task<int> SetInvitationStatusAsync()
{
invitationData.InvitationStatusId = InvitationStatusId.ACCEPTED;
}

_portalRepositories.GetInstance<IApplicationRepository>().AttachAndModifyCompanyApplication(invitationData.CompanyApplicationId, application =>
{
application.DateLastChanged = _dateTimeProvider.OffsetNow;
});
return await _portalRepositories.SaveAsync().ConfigureAwait(false);
}

Expand Down Expand Up @@ -796,7 +811,7 @@ private static void HandleConsent(IEnumerable<ConsentData> consents, IEnumerable
private static void ValidateCompanyApplicationStatus(Guid applicationId,
CompanyApplicationStatusId status,
(bool Exists, CompanyApplicationStatusId StatusId) applicationData,
IApplicationRepository applicationRepository)
IApplicationRepository applicationRepository, IDateTimeProvider dateTimeProvider)
{
var allowedCombination = new (CompanyApplicationStatusId applicationStatus, CompanyApplicationStatusId status)[]
{
Expand All @@ -819,17 +834,19 @@ private static void ValidateCompanyApplicationStatus(Guid applicationId,
applicationRepository.AttachAndModifyCompanyApplication(applicationId, a =>
{
a.ApplicationStatusId = status;
a.DateLastChanged = dateTimeProvider.OffsetNow;
});
}

private static void UpdateApplicationStatus(Guid applicationId, CompanyApplicationStatusId applicationStatusId, UpdateApplicationSteps type, IApplicationRepository applicationRepository)
private static void UpdateApplicationStatus(Guid applicationId, CompanyApplicationStatusId applicationStatusId, UpdateApplicationSteps type, IApplicationRepository applicationRepository, IDateTimeProvider dateTimeProvider)
{
var updateStatus = GetAndValidateUpdateApplicationStatus(applicationStatusId, type);
if (updateStatus != default)
{
applicationRepository.AttachAndModifyCompanyApplication(applicationId, ca =>
{
ca.ApplicationStatusId = updateStatus;
ca.DateLastChanged = dateTimeProvider.OffsetNow;
});
}
}
Expand Down Expand Up @@ -897,6 +914,12 @@ public async Task<bool> DeleteRegistrationDocumentAsync(Guid documentId)

documentRepository.RemoveDocument(details.DocumentId);

_portalRepositories.GetInstance<IApplicationRepository>().AttachAndModifyCompanyApplications(
details.applicationId.Select(applicationId => new ValueTuple<Guid, Action<CompanyApplication>?, Action<CompanyApplication>>(
applicationId,
null,
application => application.DateLastChanged = _dateTimeProvider.OffsetNow)));

await this._portalRepositories.SaveAsync().ConfigureAwait(false);
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

using Microsoft.EntityFrameworkCore;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Repositories;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.DBAccess.Tests.Setup;
using Org.Eclipse.TractusX.Portal.Backend.PortalBackend.PortalEntities;
Expand Down Expand Up @@ -501,6 +502,37 @@ public async Task GetCompanyIdNameForSubmittedApplication_WithValidData_Creates(

#endregion

#region AttachAndModifyCompanyApplications

[Fact]
public async Task AttachAndModifyCompanyApplications()
{
// Arrange
var (sut, context) = await CreateSutWithContext().ConfigureAwait(false);
var companyApplicationData = new (Guid applicationId, Action<CompanyApplication>?, Action<CompanyApplication>)[] {
(Guid.NewGuid(), null, application => application.ApplicationStatusId = CompanyApplicationStatusId.CREATED),
(Guid.NewGuid(), application => application.ApplicationStatusId = CompanyApplicationStatusId.CREATED, application => application.ApplicationStatusId = CompanyApplicationStatusId.SUBMITTED),
(Guid.NewGuid(), application => application.ApplicationStatusId = CompanyApplicationStatusId.CONFIRMED, application => application.ApplicationStatusId = CompanyApplicationStatusId.DECLINED),
(Guid.NewGuid(), application => application.ApplicationStatusId = CompanyApplicationStatusId.CONFIRMED, application => application.ApplicationStatusId = CompanyApplicationStatusId.CONFIRMED)
};

// Act
sut.AttachAndModifyCompanyApplications(companyApplicationData);

// Assert
var changeTracker = context.ChangeTracker;
var changedEntries = changeTracker.Entries().ToList();
changeTracker.HasChanges().Should().BeTrue();
changedEntries.Should().HaveCount(4).And.AllSatisfy(x => x.Entity.Should().BeOfType<CompanyApplication>()).And.Satisfy(
x => x.State == EntityState.Modified && ((CompanyApplication)x.Entity).Id == companyApplicationData[0].applicationId && ((CompanyApplication)x.Entity).ApplicationStatusId == CompanyApplicationStatusId.CREATED,
x => x.State == EntityState.Modified && ((CompanyApplication)x.Entity).Id == companyApplicationData[1].applicationId && ((CompanyApplication)x.Entity).ApplicationStatusId == CompanyApplicationStatusId.SUBMITTED,
x => x.State == EntityState.Modified && ((CompanyApplication)x.Entity).Id == companyApplicationData[2].applicationId && ((CompanyApplication)x.Entity).ApplicationStatusId == CompanyApplicationStatusId.DECLINED,
x => x.State == EntityState.Unchanged && ((CompanyApplication)x.Entity).Id == companyApplicationData[3].applicationId && ((CompanyApplication)x.Entity).ApplicationStatusId == CompanyApplicationStatusId.CONFIRMED
);
}

#endregion

private async Task<(IApplicationRepository sut, PortalDbContext context)> CreateSutWithContext()
{
var context = await _dbTestDbFixture.GetPortalDbContext().ConfigureAwait(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,36 @@ public async Task GetRegistrationDocumentAsync__ReturnsExpectedResult()
result.MediaTypeId.Should().Be(MediaTypeId.PDF);
}

[Fact]
public async Task GetDocumentDetailsForApplicationUntrackedAsync_ReturnsExpected()
{
// Arrange
var applicationStatusIds = new[]{
CompanyApplicationStatusId.SUBMITTED,
CompanyApplicationStatusId.CONFIRMED,
CompanyApplicationStatusId.DECLINED
};
var (sut, _) = await CreateSut().ConfigureAwait(false);

// Act
var result = await sut.GetDocumentDetailsForApplicationUntrackedAsync(
new Guid("9685f744-9d90-4102-a949-fcd0bb86f954"),
new Guid("41fd2ab8-71cd-4546-9bef-a388d91b2542"),
applicationStatusIds).ConfigureAwait(false);

// Assert
result.Should().NotBeNull();
result.DocumentId.Should().Be(new Guid("9685f744-9d90-4102-a949-fcd0bb86f954"));
result.documentTypeId.Should().Be(DocumentTypeId.CX_FRAME_CONTRACT);
result.DocumentStatusId.Should().Be(DocumentStatusId.LOCKED);
result.applicationId.Should().HaveCount(1).And.Satisfy(
x => x == new Guid("6b2d1263-c073-4a48-bfaf-704dc154ca9e")
);
result.IsQueriedApplicationStatus.Should().BeTrue();
result.IsSameApplicationUser.Should().BeTrue();

}

#region Setup

private async Task<(DocumentRepository, PortalDbContext)> CreateSut()
Expand Down
Loading
Loading