From 843d64487c8f62d36794afd17ef0346afcaad5ad Mon Sep 17 00:00:00 2001 From: prtsie Date: Thu, 22 Aug 2024 10:17:24 +0300 Subject: [PATCH 1/7] Fixed missing comment --- .../VisaApplications/Models/VisaApplicationModelForApplicant.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Models/VisaApplicationModelForApplicant.cs b/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Models/VisaApplicationModelForApplicant.cs index 5703882..910b15f 100644 --- a/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Models/VisaApplicationModelForApplicant.cs +++ b/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Models/VisaApplicationModelForApplicant.cs @@ -18,6 +18,7 @@ namespace ApplicationLayer.Services.VisaApplications.Models /// public PermissionToDestCountry? PermissionToDestCountry { get; set; } + /// public List PastVisits { get; set; } = null!; /// From 99625c957eccb25751838b23ea9f3974700607f0 Mon Sep 17 00:00:00 2001 From: prtsie Date: Thu, 22 Aug 2024 11:06:45 +0300 Subject: [PATCH 2/7] Added status to application, response models of application for applicant and authority --- .../Applicants/Models/AddressModel.cs | 13 ---- .../Applicants/Models/ApplicantModel.cs | 50 +++++++++++++++ .../Applicants/Models/PlaceOfWorkModel.cs | 13 ---- .../IVisaApplicationRequestsHandler.cs | 8 ++- .../VisaApplicationRequestsHandler.cs | 64 +++++++++++++++++-- .../VisaApplicationModelForApplicant.cs | 5 ++ .../VisaApplicationModelForAuthority.cs | 47 ++++++++++++++ .../ApplicationStatus.cs | 12 ++++ .../VisaApplicationDomain/VisaApplication.cs | 5 +- .../Controllers/VisaApplicationController.cs | 8 +-- 10 files changed, 185 insertions(+), 40 deletions(-) delete mode 100644 SchengenVisaApi/ApplicationLayer/Services/Applicants/Models/AddressModel.cs create mode 100644 SchengenVisaApi/ApplicationLayer/Services/Applicants/Models/ApplicantModel.cs delete mode 100644 SchengenVisaApi/ApplicationLayer/Services/Applicants/Models/PlaceOfWorkModel.cs create mode 100644 SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Models/VisaApplicationModelForAuthority.cs create mode 100644 SchengenVisaApi/Domains/VisaApplicationDomain/ApplicationStatus.cs diff --git a/SchengenVisaApi/ApplicationLayer/Services/Applicants/Models/AddressModel.cs b/SchengenVisaApi/ApplicationLayer/Services/Applicants/Models/AddressModel.cs deleted file mode 100644 index e5ccb5e..0000000 --- a/SchengenVisaApi/ApplicationLayer/Services/Applicants/Models/AddressModel.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace ApplicationLayer.Services.Applicants.Models; - -public class AddressModel -{ - /// City part of address - public Guid CityId { get; set; } - - /// Street part of address - public string Street { get; set; } = null!; - - /// Building part of address - public string Building { get; set; } = null!; -} diff --git a/SchengenVisaApi/ApplicationLayer/Services/Applicants/Models/ApplicantModel.cs b/SchengenVisaApi/ApplicationLayer/Services/Applicants/Models/ApplicantModel.cs new file mode 100644 index 0000000..1898c3a --- /dev/null +++ b/SchengenVisaApi/ApplicationLayer/Services/Applicants/Models/ApplicantModel.cs @@ -0,0 +1,50 @@ +using Domains.ApplicantDomain; + +namespace ApplicationLayer.Services.Applicants.Models +{ + /// Model of + public class ApplicantModel + { + /// + public Name Name { get; set; } = null!; + + /// + public Passport Passport { get; set; } = null!; + + /// + public DateTime BirthDate { get; set; } + + /// + public string CountryOfBirth { get; set; } = null!; + + /// + public string CityOfBirth { get; set; } = null!; + + /// + public string Citizenship { get; set; } = null!; + + /// + public string CitizenshipByBirth { get; set; } = null!; + + /// + public Gender Gender { get; set; } + + /// + public MaritalStatus MaritalStatus { get; set; } + + /// + public Name FatherName { get; set; } = null!; + + /// + public Name MotherName { get; set; } = null!; + + /// + public string JobTitle { get; set; } = null!; + + /// + public PlaceOfWork PlaceOfWork { get; set; } = null!; + + /// + public bool IsNonResident { get; set; } + } +} diff --git a/SchengenVisaApi/ApplicationLayer/Services/Applicants/Models/PlaceOfWorkModel.cs b/SchengenVisaApi/ApplicationLayer/Services/Applicants/Models/PlaceOfWorkModel.cs deleted file mode 100644 index f08f220..0000000 --- a/SchengenVisaApi/ApplicationLayer/Services/Applicants/Models/PlaceOfWorkModel.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace ApplicationLayer.Services.Applicants.Models; - -public class PlaceOfWorkModel -{ - /// Name of hirer - public string Name { get; set; } = null!; - - /// of hirer - public AddressModel Address { get; set; } = null!; - - /// Phone number of hirer - public string PhoneNum { get; set; } = null!; -} diff --git a/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Handlers/IVisaApplicationRequestsHandler.cs b/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Handlers/IVisaApplicationRequestsHandler.cs index 616591c..e92e7d6 100644 --- a/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Handlers/IVisaApplicationRequestsHandler.cs +++ b/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Handlers/IVisaApplicationRequestsHandler.cs @@ -6,8 +6,12 @@ namespace ApplicationLayer.Services.VisaApplications.Handlers; public interface IVisaApplicationRequestsHandler { - Task> Get(CancellationToken cancellationToken); - Task> GetForApplicant(Guid userId, CancellationToken cancellationToken); + /// Returns all applications for approving authorities + Task> GetAllAsync(CancellationToken cancellationToken); + /// Returns all applications of one applicant + Task> GetForApplicantAsync(Guid userId, CancellationToken cancellationToken); + + /// Creates application for applicant with specific user identifier Task HandleCreateRequest(Guid userId, VisaApplicationCreateRequest request, CancellationToken cancellationToken); } diff --git a/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Handlers/VisaApplicationRequestsHandler.cs b/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Handlers/VisaApplicationRequestsHandler.cs index 5638207..6997425 100644 --- a/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Handlers/VisaApplicationRequestsHandler.cs +++ b/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Handlers/VisaApplicationRequestsHandler.cs @@ -1,8 +1,10 @@ using ApplicationLayer.InfrastructureServicesInterfaces; +using ApplicationLayer.Services.Applicants.Models; using ApplicationLayer.Services.Applicants.NeededServices; using ApplicationLayer.Services.VisaApplications.Models; using ApplicationLayer.Services.VisaApplications.NeededServices; using ApplicationLayer.Services.VisaApplications.Requests; +using Domains.ApplicantDomain; using Domains.VisaApplicationDomain; namespace ApplicationLayer.Services.VisaApplications.Handlers; @@ -13,9 +15,57 @@ public class VisaApplicationRequestsHandler( IApplicantsRepository applicants, IUnitOfWork unitOfWork) : IVisaApplicationRequestsHandler { - public async Task> Get(CancellationToken cancellationToken) => await applications.GetAllAsync(cancellationToken); + async Task> IVisaApplicationRequestsHandler.GetAllAsync(CancellationToken cancellationToken) + { + var applicationsList = await applications.GetAllAsync(cancellationToken); - public async Task> GetForApplicant(Guid userId, CancellationToken cancellationToken) + //todo mapper + var applicationModels = applicationsList + .Select(a => MapVisaApplicationToModelForAuthorities(a, cancellationToken).Result) + .ToList(); + return applicationModels; + } + + private async Task MapVisaApplicationToModelForAuthorities(VisaApplication visaApplication, + CancellationToken cancellationToken) + { + var applicant = await applicants.GetByIdAsync(visaApplication.ApplicantId, cancellationToken); + var applicantModel = new ApplicantModel + { + Citizenship = applicant.Citizenship, + Gender = applicant.Gender, + Name = applicant.Name, + Passport = applicant.Passport, + BirthDate = applicant.BirthDate, + FatherName = applicant.FatherName, + JobTitle = applicant.JobTitle, + MaritalStatus = applicant.MaritalStatus, + MotherName = applicant.MotherName, + CitizenshipByBirth = applicant.CitizenshipByBirth, + CityOfBirth = applicant.CityOfBirth, + CountryOfBirth = applicant.CountryOfBirth, + IsNonResident = applicant.IsNonResident, + PlaceOfWork = applicant.PlaceOfWork, + }; + return new VisaApplicationModelForAuthority + { + PastVisits = visaApplication.PastVisits, + ReentryPermit = visaApplication.ReentryPermit, + VisaCategory = visaApplication.VisaCategory, + PermissionToDestCountry = visaApplication.PermissionToDestCountry, + DestinationCountry = visaApplication.DestinationCountry, + PastVisas = visaApplication.PastVisas, + RequestDate = visaApplication.RequestDate, + ValidDaysRequested = visaApplication.ValidDaysRequested, + RequestedNumberOfEntries = visaApplication.RequestedNumberOfEntries, + ForGroup = visaApplication.ForGroup, + Applicant = applicantModel, + Id = visaApplication.Id, + Status = visaApplication.Status + }; + } + + public async Task> GetForApplicantAsync(Guid userId, CancellationToken cancellationToken) { //todo mapper var applicantId = await applicants.GetApplicantIdByUserId(userId, cancellationToken); @@ -31,8 +81,11 @@ public class VisaApplicationRequestsHandler( ForGroup = va.ForGroup, PastVisas = va.PastVisas, RequestDate = va.RequestDate, - PastVisits = va.PastVisits - }).ToList(); + PastVisits = va.PastVisits, + Id = va.Id, + Status = va.Status + }) + .ToList(); } public async Task HandleCreateRequest(Guid userId, VisaApplicationCreateRequest request, CancellationToken cancellationToken) @@ -53,7 +106,8 @@ public class VisaApplicationRequestsHandler( PastVisas = request.PastVisas.ToList(), PastVisits = request.PastVisits.ToList(), ForGroup = request.IsForGroup, - RequestDate = DateTime.Today + RequestDate = DateTime.Today, + Status = ApplicationStatus.Pending }; await applications.AddAsync(visaApplication, cancellationToken); diff --git a/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Models/VisaApplicationModelForApplicant.cs b/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Models/VisaApplicationModelForApplicant.cs index 910b15f..c9b53b9 100644 --- a/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Models/VisaApplicationModelForApplicant.cs +++ b/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Models/VisaApplicationModelForApplicant.cs @@ -5,6 +5,11 @@ namespace ApplicationLayer.Services.VisaApplications.Models /// Model of public class VisaApplicationModelForApplicant { + /// + public Guid Id { get; set; } + + /// + public ApplicationStatus Status { get; set; } /// public ReentryPermit? ReentryPermit { get; set; } diff --git a/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Models/VisaApplicationModelForAuthority.cs b/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Models/VisaApplicationModelForAuthority.cs new file mode 100644 index 0000000..6cfed9e --- /dev/null +++ b/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Models/VisaApplicationModelForAuthority.cs @@ -0,0 +1,47 @@ +using ApplicationLayer.Services.Applicants.Models; +using Domains.VisaApplicationDomain; + +namespace ApplicationLayer.Services.VisaApplications.Models +{ + /// Model of with applicant property + public class VisaApplicationModelForAuthority + { + /// + public Guid Id { get; set; } + + /// Applicant of application + public ApplicantModel Applicant { get; set; } = null!; + + /// + public ApplicationStatus Status { get; set; } + + /// + public ReentryPermit? ReentryPermit { get; set; } + + /// + public string DestinationCountry { get; set; } = null!; + + /// + public List PastVisas { get; set; } = null!; + + /// + public PermissionToDestCountry? PermissionToDestCountry { get; set; } + + public List PastVisits { get; set; } = null!; + + /// + public VisaCategory VisaCategory { get; set; } + + /// + public bool ForGroup { get; set; } + + /// + public RequestedNumberOfEntries RequestedNumberOfEntries { get; set; } + + /// + public DateTime RequestDate { get; set; } + + /// + public int ValidDaysRequested { get; set; } + } +} diff --git a/SchengenVisaApi/Domains/VisaApplicationDomain/ApplicationStatus.cs b/SchengenVisaApi/Domains/VisaApplicationDomain/ApplicationStatus.cs new file mode 100644 index 0000000..a3978a2 --- /dev/null +++ b/SchengenVisaApi/Domains/VisaApplicationDomain/ApplicationStatus.cs @@ -0,0 +1,12 @@ +namespace Domains.VisaApplicationDomain +{ + public enum ApplicationStatus + { + /// Waits for approve + Pending, + Approved, + Rejected, + /// Closed by applicant + Closed + } +} diff --git a/SchengenVisaApi/Domains/VisaApplicationDomain/VisaApplication.cs b/SchengenVisaApi/Domains/VisaApplicationDomain/VisaApplication.cs index 3fbde18..4759c09 100644 --- a/SchengenVisaApi/Domains/VisaApplicationDomain/VisaApplication.cs +++ b/SchengenVisaApi/Domains/VisaApplicationDomain/VisaApplication.cs @@ -11,6 +11,9 @@ public class VisaApplication : IEntity /// Identifier of the public Guid ApplicantId { get; set; } + /// Status of application + public ApplicationStatus Status { get; set; } + /// /// always null if is not a non-resident public ReentryPermit? ReentryPermit { get; set; } @@ -18,9 +21,7 @@ public class VisaApplication : IEntity /// Country that wants to visit public string DestinationCountry { get; set; } = null!; - /// /// List of that applicant had before - /// public List PastVisas { get; set; } = null!; /// Permission to enter the destination country of diff --git a/SchengenVisaApi/SchengenVisaApi/Controllers/VisaApplicationController.cs b/SchengenVisaApi/SchengenVisaApi/Controllers/VisaApplicationController.cs index 9aa3837..03f2a0e 100644 --- a/SchengenVisaApi/SchengenVisaApi/Controllers/VisaApplicationController.cs +++ b/SchengenVisaApi/SchengenVisaApi/Controllers/VisaApplicationController.cs @@ -1,4 +1,3 @@ -using System.Security.Claims; using ApplicationLayer.Services.VisaApplications.Handlers; using ApplicationLayer.Services.VisaApplications.Models; using ApplicationLayer.Services.VisaApplications.Requests; @@ -14,18 +13,17 @@ namespace SchengenVisaApi.Controllers; [Route("visaApplication")] public class VisaApplicationController(IVisaApplicationRequestsHandler visaApplicationRequestsHandler) : VisaApiControllerBase { - //todo should return only pending applications //todo should return model /// Returns all applications from DB /// Accessible only for approving authorities [HttpGet] - [ProducesResponseType>(StatusCodes.Status200OK)] + [ProducesResponseType>(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [Authorize(policy: PolicyConstants.ApprovingAuthorityPolicy)] public async Task Get(CancellationToken cancellationToken) { - var result = await visaApplicationRequestsHandler.Get(cancellationToken); + var result = await visaApplicationRequestsHandler.GetAllAsync(cancellationToken); return Ok(result); } @@ -41,7 +39,7 @@ public class VisaApplicationController(IVisaApplicationRequestsHandler visaAppli public async Task GetForApplicant(CancellationToken cancellationToken) { var userId = GetUserId(); - var result = await visaApplicationRequestsHandler.GetForApplicant(userId, cancellationToken); + var result = await visaApplicationRequestsHandler.GetForApplicantAsync(userId, cancellationToken); return Ok(result); } From 7b7ca6ae36cb91af0c9e0cd92f326214fb79ac46 Mon Sep 17 00:00:00 2001 From: prtsie Date: Thu, 22 Aug 2024 11:43:55 +0300 Subject: [PATCH 3/7] Changed exceptions, added action for closing applications by applicant --- .../ApplicationLayer/ApplicationLayer.csproj | 4 ++++ .../EntityNotFoundByIdException.cs | 2 +- .../GeneralExceptions/EntityNotFoundException.cs | 5 +---- .../Handlers/IVisaApplicationRequestsHandler.cs | 3 +++ .../Handlers/VisaApplicationRequestsHandler.cs | 11 +++++++++++ .../IVisaApplicationsRepository.cs | 3 +++ .../Repositories/ApplicantsRepository.cs | 4 ++-- .../ApplicantNotFoundByUserIdException.cs | 5 +---- ...tFoundByApplicantAndApplicationIdException.cs | 7 +++++++ .../Repositories/VisaApplicationsRepository.cs | 11 +++++++++++ .../Controllers/VisaApplicationController.cs | 16 ++++++++++++++++ .../ExceptionFilters/GlobalExceptionsFilter.cs | 2 +- 12 files changed, 61 insertions(+), 12 deletions(-) create mode 100644 SchengenVisaApi/Infrastructure/Database/VisaApplications/Repositories/Exceptions/ApplicationNotFoundByApplicantAndApplicationIdException.cs diff --git a/SchengenVisaApi/ApplicationLayer/ApplicationLayer.csproj b/SchengenVisaApi/ApplicationLayer/ApplicationLayer.csproj index bc6298d..001de30 100644 --- a/SchengenVisaApi/ApplicationLayer/ApplicationLayer.csproj +++ b/SchengenVisaApi/ApplicationLayer/ApplicationLayer.csproj @@ -14,4 +14,8 @@ + + + + diff --git a/SchengenVisaApi/ApplicationLayer/Services/GeneralExceptions/EntityNotFoundByIdException.cs b/SchengenVisaApi/ApplicationLayer/Services/GeneralExceptions/EntityNotFoundByIdException.cs index d3155fe..d7d3e03 100644 --- a/SchengenVisaApi/ApplicationLayer/Services/GeneralExceptions/EntityNotFoundByIdException.cs +++ b/SchengenVisaApi/ApplicationLayer/Services/GeneralExceptions/EntityNotFoundByIdException.cs @@ -5,5 +5,5 @@ namespace ApplicationLayer.Services.GeneralExceptions; /// Exception to throw when entity not found /// Identifier of entity /// Type of entity -public class EntityNotFoundByIdException(Guid id) : EntityNotFoundException($"{typeof(T).Name} with id {id} not found.") +public class EntityNotFoundByIdException(Guid id) : EntityNotFoundException($"{typeof(T).Name} with id {id} not found.") where T : class, IEntity; diff --git a/SchengenVisaApi/ApplicationLayer/Services/GeneralExceptions/EntityNotFoundException.cs b/SchengenVisaApi/ApplicationLayer/Services/GeneralExceptions/EntityNotFoundException.cs index 4f4acca..c0f4867 100644 --- a/SchengenVisaApi/ApplicationLayer/Services/GeneralExceptions/EntityNotFoundException.cs +++ b/SchengenVisaApi/ApplicationLayer/Services/GeneralExceptions/EntityNotFoundException.cs @@ -1,9 +1,6 @@ using ApplicationLayer.GeneralExceptions; -using Domains; namespace ApplicationLayer.Services.GeneralExceptions; /// Exception to throw when entity not found -/// Not found entity type -public class EntityNotFoundException(string message) : ApiException(message) - where T : class, IEntity; +public class EntityNotFoundException(string message) : ApiException(message); diff --git a/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Handlers/IVisaApplicationRequestsHandler.cs b/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Handlers/IVisaApplicationRequestsHandler.cs index e92e7d6..fcd2b53 100644 --- a/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Handlers/IVisaApplicationRequestsHandler.cs +++ b/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Handlers/IVisaApplicationRequestsHandler.cs @@ -14,4 +14,7 @@ public interface IVisaApplicationRequestsHandler /// Creates application for applicant with specific user identifier Task HandleCreateRequest(Guid userId, VisaApplicationCreateRequest request, CancellationToken cancellationToken); + + /// Sets application status to closed + Task HandleCloseRequest(Guid userId, Guid applicationId, CancellationToken cancellationToken); } diff --git a/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Handlers/VisaApplicationRequestsHandler.cs b/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Handlers/VisaApplicationRequestsHandler.cs index 6997425..ab30d22 100644 --- a/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Handlers/VisaApplicationRequestsHandler.cs +++ b/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Handlers/VisaApplicationRequestsHandler.cs @@ -114,4 +114,15 @@ public class VisaApplicationRequestsHandler( await unitOfWork.SaveAsync(cancellationToken); } + + async Task IVisaApplicationRequestsHandler.HandleCloseRequest(Guid userId, Guid applicationId, CancellationToken cancellationToken) + { + var applicantId = await applicants.GetApplicantIdByUserId(userId, cancellationToken); + var application = await applications.GetByApplicantAndApplicationIdAsync(applicantId, applicationId, cancellationToken); + + application.Status = ApplicationStatus.Closed; + await applications.UpdateAsync(application, cancellationToken); + + await unitOfWork.SaveAsync(cancellationToken); + } } diff --git a/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/NeededServices/IVisaApplicationsRepository.cs b/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/NeededServices/IVisaApplicationsRepository.cs index 8904a67..5e132a8 100644 --- a/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/NeededServices/IVisaApplicationsRepository.cs +++ b/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/NeededServices/IVisaApplicationsRepository.cs @@ -7,4 +7,7 @@ public interface IVisaApplicationsRepository : IGenericRepository> GetOfApplicantAsync(Guid applicantId, CancellationToken cancellationToken); + + /// Get specific application of specific user + Task GetByApplicantAndApplicationIdAsync(Guid applicantId, Guid applicationId, CancellationToken cancellationToken); } diff --git a/SchengenVisaApi/Infrastructure/Database/Applicants/Repositories/ApplicantsRepository.cs b/SchengenVisaApi/Infrastructure/Database/Applicants/Repositories/ApplicantsRepository.cs index a5a9ef5..64f4e7f 100644 --- a/SchengenVisaApi/Infrastructure/Database/Applicants/Repositories/ApplicantsRepository.cs +++ b/SchengenVisaApi/Infrastructure/Database/Applicants/Repositories/ApplicantsRepository.cs @@ -21,12 +21,12 @@ public sealed class ApplicantsRepository(IGenericReader reader, IGenericWriter w async Task IApplicantsRepository.FindByUserIdAsync(Guid userId, CancellationToken cancellationToken) { var result = await LoadDomain().SingleOrDefaultAsync(a => a.UserId == userId, cancellationToken); - return result ?? throw new ApplicantNotFoundByUserIdException(userId); + return result ?? throw new ApplicantNotFoundByUserIdException(); } async Task IApplicantsRepository.GetApplicantIdByUserId(Guid userId, CancellationToken cancellationToken) { var result = await base.LoadDomain().SingleOrDefaultAsync(a => a.UserId == userId, cancellationToken); - return result?.Id ?? throw new ApplicantNotFoundByUserIdException(userId); + return result?.Id ?? throw new ApplicantNotFoundByUserIdException(); } } diff --git a/SchengenVisaApi/Infrastructure/Database/Applicants/Repositories/Exceptions/ApplicantNotFoundByUserIdException.cs b/SchengenVisaApi/Infrastructure/Database/Applicants/Repositories/Exceptions/ApplicantNotFoundByUserIdException.cs index 52e7046..a45f9e8 100644 --- a/SchengenVisaApi/Infrastructure/Database/Applicants/Repositories/Exceptions/ApplicantNotFoundByUserIdException.cs +++ b/SchengenVisaApi/Infrastructure/Database/Applicants/Repositories/Exceptions/ApplicantNotFoundByUserIdException.cs @@ -3,8 +3,5 @@ using Domains.ApplicantDomain; namespace Infrastructure.Database.Applicants.Repositories.Exceptions { - public class ApplicantNotFoundByUserIdException(Guid id) : EntityNotFoundException("Applicant not found.") - { - public Guid UserId { get; private set; } = id; - } + public class ApplicantNotFoundByUserIdException() : EntityNotFoundException("Applicant not found."); } diff --git a/SchengenVisaApi/Infrastructure/Database/VisaApplications/Repositories/Exceptions/ApplicationNotFoundByApplicantAndApplicationIdException.cs b/SchengenVisaApi/Infrastructure/Database/VisaApplications/Repositories/Exceptions/ApplicationNotFoundByApplicantAndApplicationIdException.cs new file mode 100644 index 0000000..b8d1241 --- /dev/null +++ b/SchengenVisaApi/Infrastructure/Database/VisaApplications/Repositories/Exceptions/ApplicationNotFoundByApplicantAndApplicationIdException.cs @@ -0,0 +1,7 @@ +using ApplicationLayer.Services.GeneralExceptions; + +namespace Infrastructure.Database.VisaApplications.Repositories.Exceptions +{ + public class ApplicationNotFoundByApplicantAndApplicationIdException(Guid applicationId) + : EntityNotFoundException($"Application with id {applicationId} not found for authenticated user"); +} diff --git a/SchengenVisaApi/Infrastructure/Database/VisaApplications/Repositories/VisaApplicationsRepository.cs b/SchengenVisaApi/Infrastructure/Database/VisaApplications/Repositories/VisaApplicationsRepository.cs index cd20971..2a40dd7 100644 --- a/SchengenVisaApi/Infrastructure/Database/VisaApplications/Repositories/VisaApplicationsRepository.cs +++ b/SchengenVisaApi/Infrastructure/Database/VisaApplications/Repositories/VisaApplicationsRepository.cs @@ -1,6 +1,7 @@ using ApplicationLayer.Services.VisaApplications.NeededServices; using Domains.VisaApplicationDomain; using Infrastructure.Database.Generic; +using Infrastructure.Database.VisaApplications.Repositories.Exceptions; using Microsoft.EntityFrameworkCore; namespace Infrastructure.Database.VisaApplications.Repositories; @@ -16,4 +17,14 @@ public sealed class VisaApplicationsRepository(IGenericReader reader, IGenericWr async Task> IVisaApplicationsRepository.GetOfApplicantAsync(Guid applicantId, CancellationToken cancellationToken) => await LoadDomain().Where(va => va.ApplicantId == applicantId).ToListAsync(cancellationToken); + + async Task IVisaApplicationsRepository.GetByApplicantAndApplicationIdAsync( + Guid applicantId, + Guid applicationId, + CancellationToken cancellationToken) + { + var result = await LoadDomain() + .SingleOrDefaultAsync(va => va.Id == applicationId && va.ApplicantId == applicantId, cancellationToken); + return result ?? throw new ApplicationNotFoundByApplicantAndApplicationIdException(applicationId); + } } diff --git a/SchengenVisaApi/SchengenVisaApi/Controllers/VisaApplicationController.cs b/SchengenVisaApi/SchengenVisaApi/Controllers/VisaApplicationController.cs index 03f2a0e..50125fb 100644 --- a/SchengenVisaApi/SchengenVisaApi/Controllers/VisaApplicationController.cs +++ b/SchengenVisaApi/SchengenVisaApi/Controllers/VisaApplicationController.cs @@ -57,4 +57,20 @@ public class VisaApplicationController(IVisaApplicationRequestsHandler visaAppli await visaApplicationRequestsHandler.HandleCreateRequest(userId, request, cancellationToken); return Ok(); } + + /// Sets application status to closed + /// Accessible only for applicant + [HttpPatch] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + [Authorize(policy: PolicyConstants.ApplicantPolicy)] + [Route("{applicationId:guid}")] + public async Task CloseApplication(Guid applicationId, CancellationToken cancellationToken) + { + var userId = GetUserId(); + await visaApplicationRequestsHandler.HandleCloseRequest(userId, applicationId, cancellationToken); + return Ok(); + } } diff --git a/SchengenVisaApi/SchengenVisaApi/ExceptionFilters/GlobalExceptionsFilter.cs b/SchengenVisaApi/SchengenVisaApi/ExceptionFilters/GlobalExceptionsFilter.cs index 3bd38a6..d8e7c94 100644 --- a/SchengenVisaApi/SchengenVisaApi/ExceptionFilters/GlobalExceptionsFilter.cs +++ b/SchengenVisaApi/SchengenVisaApi/ExceptionFilters/GlobalExceptionsFilter.cs @@ -21,7 +21,7 @@ namespace SchengenVisaApi.ExceptionFilters problemDetails.Detail = exception.Message; switch (exception) { - case EntityNotFoundException: + case EntityNotFoundException: problemDetails.Status = StatusCodes.Status404NotFound; problemDetails.Title = "Requested entity not found"; problemDetails.Type = "https://datatracker.ietf.org/doc/html/rfc7231#section-6.5.4"; From e3060c663fae86bb6d4afe53e47fd285d3c07547 Mon Sep 17 00:00:00 2001 From: prtsie Date: Thu, 22 Aug 2024 16:56:14 +0300 Subject: [PATCH 4/7] fixed warnings --- .../VisaApplications/Handlers/IVisaApplicationRequestsHandler.cs | 1 - .../VisaApplications/Handlers/VisaApplicationRequestsHandler.cs | 1 - .../Exceptions/ApplicantNotFoundByUserIdException.cs | 1 - .../SchengenVisaApi/Controllers/VisaApplicationController.cs | 1 - .../SchengenVisaApi/ExceptionFilters/GlobalExceptionsFilter.cs | 1 - 5 files changed, 5 deletions(-) diff --git a/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Handlers/IVisaApplicationRequestsHandler.cs b/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Handlers/IVisaApplicationRequestsHandler.cs index fcd2b53..03eefe0 100644 --- a/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Handlers/IVisaApplicationRequestsHandler.cs +++ b/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Handlers/IVisaApplicationRequestsHandler.cs @@ -1,6 +1,5 @@ using ApplicationLayer.Services.VisaApplications.Models; using ApplicationLayer.Services.VisaApplications.Requests; -using Domains.VisaApplicationDomain; namespace ApplicationLayer.Services.VisaApplications.Handlers; diff --git a/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Handlers/VisaApplicationRequestsHandler.cs b/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Handlers/VisaApplicationRequestsHandler.cs index ab30d22..428f045 100644 --- a/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Handlers/VisaApplicationRequestsHandler.cs +++ b/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Handlers/VisaApplicationRequestsHandler.cs @@ -4,7 +4,6 @@ using ApplicationLayer.Services.Applicants.NeededServices; using ApplicationLayer.Services.VisaApplications.Models; using ApplicationLayer.Services.VisaApplications.NeededServices; using ApplicationLayer.Services.VisaApplications.Requests; -using Domains.ApplicantDomain; using Domains.VisaApplicationDomain; namespace ApplicationLayer.Services.VisaApplications.Handlers; diff --git a/SchengenVisaApi/Infrastructure/Database/Applicants/Repositories/Exceptions/ApplicantNotFoundByUserIdException.cs b/SchengenVisaApi/Infrastructure/Database/Applicants/Repositories/Exceptions/ApplicantNotFoundByUserIdException.cs index a45f9e8..79fc6d3 100644 --- a/SchengenVisaApi/Infrastructure/Database/Applicants/Repositories/Exceptions/ApplicantNotFoundByUserIdException.cs +++ b/SchengenVisaApi/Infrastructure/Database/Applicants/Repositories/Exceptions/ApplicantNotFoundByUserIdException.cs @@ -1,5 +1,4 @@ using ApplicationLayer.Services.GeneralExceptions; -using Domains.ApplicantDomain; namespace Infrastructure.Database.Applicants.Repositories.Exceptions { diff --git a/SchengenVisaApi/SchengenVisaApi/Controllers/VisaApplicationController.cs b/SchengenVisaApi/SchengenVisaApi/Controllers/VisaApplicationController.cs index 50125fb..61dcd76 100644 --- a/SchengenVisaApi/SchengenVisaApi/Controllers/VisaApplicationController.cs +++ b/SchengenVisaApi/SchengenVisaApi/Controllers/VisaApplicationController.cs @@ -1,7 +1,6 @@ using ApplicationLayer.Services.VisaApplications.Handlers; using ApplicationLayer.Services.VisaApplications.Models; using ApplicationLayer.Services.VisaApplications.Requests; -using Domains.VisaApplicationDomain; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using SchengenVisaApi.Common; diff --git a/SchengenVisaApi/SchengenVisaApi/ExceptionFilters/GlobalExceptionsFilter.cs b/SchengenVisaApi/SchengenVisaApi/ExceptionFilters/GlobalExceptionsFilter.cs index d8e7c94..ae7311c 100644 --- a/SchengenVisaApi/SchengenVisaApi/ExceptionFilters/GlobalExceptionsFilter.cs +++ b/SchengenVisaApi/SchengenVisaApi/ExceptionFilters/GlobalExceptionsFilter.cs @@ -1,7 +1,6 @@ using ApplicationLayer.GeneralExceptions; using ApplicationLayer.Services.AuthServices.LoginService.Exceptions; using ApplicationLayer.Services.GeneralExceptions; -using Domains; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; From 300d8afd936f8f31bd0a9700e0971b556423d124 Mon Sep 17 00:00:00 2001 From: prtsie Date: Thu, 22 Aug 2024 21:14:10 +0300 Subject: [PATCH 5/7] added todo, deleted empty folder --- SchengenVisaApi/ApplicationLayer/ApplicationLayer.csproj | 4 ---- .../SchengenVisaApi/Controllers/UsersController.cs | 1 + 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/SchengenVisaApi/ApplicationLayer/ApplicationLayer.csproj b/SchengenVisaApi/ApplicationLayer/ApplicationLayer.csproj index 001de30..bc6298d 100644 --- a/SchengenVisaApi/ApplicationLayer/ApplicationLayer.csproj +++ b/SchengenVisaApi/ApplicationLayer/ApplicationLayer.csproj @@ -14,8 +14,4 @@ - - - - diff --git a/SchengenVisaApi/SchengenVisaApi/Controllers/UsersController.cs b/SchengenVisaApi/SchengenVisaApi/Controllers/UsersController.cs index 454c67d..0236f1b 100644 --- a/SchengenVisaApi/SchengenVisaApi/Controllers/UsersController.cs +++ b/SchengenVisaApi/SchengenVisaApi/Controllers/UsersController.cs @@ -77,6 +77,7 @@ namespace SchengenVisaApi.Controllers [ProducesResponseType(StatusCodes.Status401Unauthorized)] [Route("authority/{authorityAccountId:guid}")] [Authorize(policy: PolicyConstants.AdminPolicy)] + //todo replace args with ChangeAuthorityAuthDataRequest or something public async Task ChangeAuthorityAuthData(Guid authorityAccountId, RegisterRequest authData, CancellationToken cancellationToken) { await authorityService.ChangeAccountAuthDataAsync(authorityAccountId, authData, cancellationToken); From 78b4ca4f8454143d6cca1363ec9b91352089b6ab Mon Sep 17 00:00:00 2001 From: prtsie Date: Thu, 22 Aug 2024 21:48:01 +0300 Subject: [PATCH 6/7] action for process applications for authorities --- .../ApplicationAlreadyProcessedException.cs | 6 ++++ .../IVisaApplicationRequestsHandler.cs | 6 ++-- .../VisaApplicationRequestsHandler.cs | 31 +++++++++++++++++-- .../Models/AuthorityRequestStatuses.cs | 8 +++++ .../Controllers/UsersController.cs | 8 ++--- .../Controllers/VisaApplicationController.cs | 21 +++++++++++-- .../GlobalExceptionsFilter.cs | 6 ++++ 7 files changed, 75 insertions(+), 11 deletions(-) create mode 100644 SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Exceptions/ApplicationAlreadyProcessedException.cs create mode 100644 SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Models/AuthorityRequestStatuses.cs diff --git a/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Exceptions/ApplicationAlreadyProcessedException.cs b/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Exceptions/ApplicationAlreadyProcessedException.cs new file mode 100644 index 0000000..47da53e --- /dev/null +++ b/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Exceptions/ApplicationAlreadyProcessedException.cs @@ -0,0 +1,6 @@ +using ApplicationLayer.GeneralExceptions; + +namespace ApplicationLayer.Services.VisaApplications.Exceptions +{ + public class ApplicationAlreadyProcessedException() : ApiException("This application already processed or closed by applicant."); +} diff --git a/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Handlers/IVisaApplicationRequestsHandler.cs b/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Handlers/IVisaApplicationRequestsHandler.cs index 03eefe0..1f5ed5e 100644 --- a/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Handlers/IVisaApplicationRequestsHandler.cs +++ b/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Handlers/IVisaApplicationRequestsHandler.cs @@ -12,8 +12,10 @@ public interface IVisaApplicationRequestsHandler Task> GetForApplicantAsync(Guid userId, CancellationToken cancellationToken); /// Creates application for applicant with specific user identifier - Task HandleCreateRequest(Guid userId, VisaApplicationCreateRequest request, CancellationToken cancellationToken); + Task HandleCreateRequestAsync(Guid userId, VisaApplicationCreateRequest request, CancellationToken cancellationToken); /// Sets application status to closed - Task HandleCloseRequest(Guid userId, Guid applicationId, CancellationToken cancellationToken); + Task HandleCloseRequestAsync(Guid userId, Guid applicationId, CancellationToken cancellationToken); + + Task SetApplicationStatusFromAuthorityAsync(Guid applicationId, AuthorityRequestStatuses status, CancellationToken cancellationToken); } diff --git a/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Handlers/VisaApplicationRequestsHandler.cs b/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Handlers/VisaApplicationRequestsHandler.cs index 428f045..88a6b27 100644 --- a/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Handlers/VisaApplicationRequestsHandler.cs +++ b/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Handlers/VisaApplicationRequestsHandler.cs @@ -1,6 +1,7 @@ using ApplicationLayer.InfrastructureServicesInterfaces; using ApplicationLayer.Services.Applicants.Models; using ApplicationLayer.Services.Applicants.NeededServices; +using ApplicationLayer.Services.VisaApplications.Exceptions; using ApplicationLayer.Services.VisaApplications.Models; using ApplicationLayer.Services.VisaApplications.NeededServices; using ApplicationLayer.Services.VisaApplications.Requests; @@ -87,7 +88,7 @@ public class VisaApplicationRequestsHandler( .ToList(); } - public async Task HandleCreateRequest(Guid userId, VisaApplicationCreateRequest request, CancellationToken cancellationToken) + public async Task HandleCreateRequestAsync(Guid userId, VisaApplicationCreateRequest request, CancellationToken cancellationToken) { //TODO mapper @@ -114,7 +115,7 @@ public class VisaApplicationRequestsHandler( await unitOfWork.SaveAsync(cancellationToken); } - async Task IVisaApplicationRequestsHandler.HandleCloseRequest(Guid userId, Guid applicationId, CancellationToken cancellationToken) + async Task IVisaApplicationRequestsHandler.HandleCloseRequestAsync(Guid userId, Guid applicationId, CancellationToken cancellationToken) { var applicantId = await applicants.GetApplicantIdByUserId(userId, cancellationToken); var application = await applications.GetByApplicantAndApplicationIdAsync(applicantId, applicationId, cancellationToken); @@ -124,4 +125,30 @@ public class VisaApplicationRequestsHandler( await unitOfWork.SaveAsync(cancellationToken); } + + async Task IVisaApplicationRequestsHandler.SetApplicationStatusFromAuthorityAsync( + Guid applicationId, + AuthorityRequestStatuses status, + CancellationToken cancellationToken) + { + var application = await applications.GetByIdAsync(applicationId, cancellationToken); + if (application.Status != ApplicationStatus.Pending) + { + //todo refactor exceptions + throw new ApplicationAlreadyProcessedException(); + } + + //todo mapper + ApplicationStatus statusToSet = status switch + { + AuthorityRequestStatuses.Approved => ApplicationStatus.Approved, + AuthorityRequestStatuses.Rejected => ApplicationStatus.Rejected, + _ => throw new ArgumentOutOfRangeException(nameof(status), status, null) + }; + + application.Status = statusToSet; + await applications.UpdateAsync(application, cancellationToken); + + await unitOfWork.SaveAsync(cancellationToken); + } } diff --git a/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Models/AuthorityRequestStatuses.cs b/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Models/AuthorityRequestStatuses.cs new file mode 100644 index 0000000..93f2a93 --- /dev/null +++ b/SchengenVisaApi/ApplicationLayer/Services/VisaApplications/Models/AuthorityRequestStatuses.cs @@ -0,0 +1,8 @@ +namespace ApplicationLayer.Services.VisaApplications.Models +{ + public enum AuthorityRequestStatuses + { + Approved, + Rejected + } +} diff --git a/SchengenVisaApi/SchengenVisaApi/Controllers/UsersController.cs b/SchengenVisaApi/SchengenVisaApi/Controllers/UsersController.cs index 0236f1b..ac0201b 100644 --- a/SchengenVisaApi/SchengenVisaApi/Controllers/UsersController.cs +++ b/SchengenVisaApi/SchengenVisaApi/Controllers/UsersController.cs @@ -35,7 +35,7 @@ namespace SchengenVisaApi.Controllers [ProducesResponseType(StatusCodes.Status409Conflict)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [Route("authority")] + [Route("authorities")] [Authorize(policy: PolicyConstants.AdminPolicy)] public async Task RegisterAuthority(RegisterRequest request, CancellationToken cancellationToken) { @@ -60,7 +60,7 @@ namespace SchengenVisaApi.Controllers [ProducesResponseType>(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [Route("authority")] + [Route("authorities")] [Authorize(policy: PolicyConstants.AdminPolicy)] public async Task GetAuthorityAccounts(CancellationToken cancellationToken) { @@ -75,7 +75,7 @@ namespace SchengenVisaApi.Controllers [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [Route("authority/{authorityAccountId:guid}")] + [Route("authorities/{authorityAccountId:guid}")] [Authorize(policy: PolicyConstants.AdminPolicy)] //todo replace args with ChangeAuthorityAuthDataRequest or something public async Task ChangeAuthorityAuthData(Guid authorityAccountId, RegisterRequest authData, CancellationToken cancellationToken) @@ -91,7 +91,7 @@ namespace SchengenVisaApi.Controllers [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [Route("authority/{authorityAccountId:guid}")] + [Route("authorities/{authorityAccountId:guid}")] [Authorize(policy: PolicyConstants.AdminPolicy)] public async Task RemoveAuthorityAccount(Guid authorityAccountId, CancellationToken cancellationToken) { diff --git a/SchengenVisaApi/SchengenVisaApi/Controllers/VisaApplicationController.cs b/SchengenVisaApi/SchengenVisaApi/Controllers/VisaApplicationController.cs index 61dcd76..d47271d 100644 --- a/SchengenVisaApi/SchengenVisaApi/Controllers/VisaApplicationController.cs +++ b/SchengenVisaApi/SchengenVisaApi/Controllers/VisaApplicationController.cs @@ -9,7 +9,7 @@ namespace SchengenVisaApi.Controllers; /// Controller for [ApiController] -[Route("visaApplication")] +[Route("visaApplications")] public class VisaApplicationController(IVisaApplicationRequestsHandler visaApplicationRequestsHandler) : VisaApiControllerBase { //todo should return model @@ -53,7 +53,7 @@ public class VisaApplicationController(IVisaApplicationRequestsHandler visaAppli public async Task Create(VisaApplicationCreateRequest request, CancellationToken cancellationToken) { var userId = GetUserId(); - await visaApplicationRequestsHandler.HandleCreateRequest(userId, request, cancellationToken); + await visaApplicationRequestsHandler.HandleCreateRequestAsync(userId, request, cancellationToken); return Ok(); } @@ -69,7 +69,22 @@ public class VisaApplicationController(IVisaApplicationRequestsHandler visaAppli public async Task CloseApplication(Guid applicationId, CancellationToken cancellationToken) { var userId = GetUserId(); - await visaApplicationRequestsHandler.HandleCloseRequest(userId, applicationId, cancellationToken); + await visaApplicationRequestsHandler.HandleCloseRequestAsync(userId, applicationId, cancellationToken); + return Ok(); + } + + /// Allows approving authorities approve or reject applications + /// Accessible only for authorities + [HttpPatch] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + [Authorize(policy: PolicyConstants.ApprovingAuthorityPolicy)] + [Route("approving/{applicationId:guid}")] + public async Task SetStatusFromAuthority(Guid applicationId, AuthorityRequestStatuses status, CancellationToken cancellationToken) + { + await visaApplicationRequestsHandler.SetApplicationStatusFromAuthorityAsync(applicationId, status, cancellationToken); return Ok(); } } diff --git a/SchengenVisaApi/SchengenVisaApi/ExceptionFilters/GlobalExceptionsFilter.cs b/SchengenVisaApi/SchengenVisaApi/ExceptionFilters/GlobalExceptionsFilter.cs index ae7311c..4778f64 100644 --- a/SchengenVisaApi/SchengenVisaApi/ExceptionFilters/GlobalExceptionsFilter.cs +++ b/SchengenVisaApi/SchengenVisaApi/ExceptionFilters/GlobalExceptionsFilter.cs @@ -1,6 +1,7 @@ using ApplicationLayer.GeneralExceptions; using ApplicationLayer.Services.AuthServices.LoginService.Exceptions; using ApplicationLayer.Services.GeneralExceptions; +using ApplicationLayer.Services.VisaApplications.Exceptions; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; @@ -35,6 +36,11 @@ namespace SchengenVisaApi.ExceptionFilters problemDetails.Title = "Already exists"; problemDetails.Type = "https://datatracker.ietf.org/doc/html/rfc7231#section-6.5.8"; break; + case ApplicationAlreadyProcessedException: + problemDetails.Status = StatusCodes.Status409Conflict; + problemDetails.Title = "Already processed"; + problemDetails.Type = "https://datatracker.ietf.org/doc/html/rfc7231#section-6.5.8"; + break; default: problemDetails.Status = StatusCodes.Status400BadRequest; problemDetails.Title = "Bad request"; From e70f383903f9468fd0482084199bd24d8663379d Mon Sep 17 00:00:00 2001 From: prtsie Date: Fri, 23 Aug 2024 16:54:30 +0300 Subject: [PATCH 7/7] removes todo --- .../SchengenVisaApi/Controllers/VisaApplicationController.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/SchengenVisaApi/SchengenVisaApi/Controllers/VisaApplicationController.cs b/SchengenVisaApi/SchengenVisaApi/Controllers/VisaApplicationController.cs index d47271d..391972e 100644 --- a/SchengenVisaApi/SchengenVisaApi/Controllers/VisaApplicationController.cs +++ b/SchengenVisaApi/SchengenVisaApi/Controllers/VisaApplicationController.cs @@ -12,7 +12,6 @@ namespace SchengenVisaApi.Controllers; [Route("visaApplications")] public class VisaApplicationController(IVisaApplicationRequestsHandler visaApplicationRequestsHandler) : VisaApiControllerBase { - //todo should return model /// Returns all applications from DB /// Accessible only for approving authorities [HttpGet]