add companies management
This commit is contained in:
parent
74dc7ceff3
commit
f4611f029f
@ -13,11 +13,16 @@ public sealed class AircraftDto : IMapFrom<Aircraft>
|
|||||||
|
|
||||||
public short Capacity { get; set; }
|
public short Capacity { get; set; }
|
||||||
|
|
||||||
|
public Guid CompanyUuid { get; set; }
|
||||||
|
|
||||||
public void Mapping(MappingProfile profile)
|
public void Mapping(MappingProfile profile)
|
||||||
{
|
{
|
||||||
profile.CreateMap<Aircraft, AircraftDto>()
|
profile.CreateMap<Aircraft, AircraftDto>()
|
||||||
.ForMember(
|
.ForMember(
|
||||||
d => d.Uuid,
|
d => d.Uuid,
|
||||||
opt => opt.MapFrom(s => s.Guid));
|
opt => opt.MapFrom(s => s.Guid))
|
||||||
|
.ForMember(
|
||||||
|
d => d.CompanyUuid,
|
||||||
|
opt => opt.MapFrom(s => s.Company.Guid));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,4 +9,6 @@ public record AddAircraftCommand : IRequest<AircraftDto>
|
|||||||
public string Model { get; set; }
|
public string Model { get; set; }
|
||||||
|
|
||||||
public short Capacity { get; set; }
|
public short Capacity { get; set; }
|
||||||
|
|
||||||
|
public Guid CompanyGuid { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -33,11 +33,23 @@ public class AddAircraftCommandHandler :
|
|||||||
"Aircraft with given number already exists.");
|
"Aircraft with given number already exists.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var parentEntity = await _unitOfWork.CompanyRepository.GetOneAsync(
|
||||||
|
e => e.Guid == request.CompanyGuid, cancellationToken);
|
||||||
|
|
||||||
|
if (parentEntity == null)
|
||||||
|
{
|
||||||
|
throw new NotFoundException(
|
||||||
|
$"Parent entity with Guid: {request.CompanyGuid} not found.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
entity = new Aircraft()
|
entity = new Aircraft()
|
||||||
{
|
{
|
||||||
Number = request.Number,
|
Number = request.Number,
|
||||||
Model = request.Model,
|
Model = request.Model,
|
||||||
Capacity = request.Capacity
|
Capacity = request.Capacity,
|
||||||
|
CompanyId = parentEntity.Id,
|
||||||
|
Company = parentEntity
|
||||||
};
|
};
|
||||||
|
|
||||||
entity = await _unitOfWork.AircraftRepository.AddOneAsync(
|
entity = await _unitOfWork.AircraftRepository.AddOneAsync(
|
||||||
|
@ -33,5 +33,9 @@ public class AddAircraftCommandValidator : AbstractValidator<AddAircraftCommand>
|
|||||||
RuleFor(v => v.Capacity)
|
RuleFor(v => v.Capacity)
|
||||||
.NotEmpty()
|
.NotEmpty()
|
||||||
.WithMessage(localizer["FluentValidation.NotEmpty"]);
|
.WithMessage(localizer["FluentValidation.NotEmpty"]);
|
||||||
|
|
||||||
|
RuleFor(v => v.CompanyGuid)
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage(localizer["FluentValidation.NotEmpty"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,4 +11,6 @@ public record UpdateAircraftCommand : IRequest<AircraftDto>
|
|||||||
public string Model { get; set; }
|
public string Model { get; set; }
|
||||||
|
|
||||||
public short Capacity { get; set; }
|
public short Capacity { get; set; }
|
||||||
|
|
||||||
|
public Guid CompanyGuid { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ public class UpdateAircraftCommandHandler :
|
|||||||
}
|
}
|
||||||
|
|
||||||
var duplicateEntity = await _unitOfWork.AircraftRepository.GetOneAsync(
|
var duplicateEntity = await _unitOfWork.AircraftRepository.GetOneAsync(
|
||||||
e => e.Number == request.Number,
|
e => e.Number == request.Number && e.Guid != request.Guid,
|
||||||
cancellationToken);
|
cancellationToken);
|
||||||
|
|
||||||
if (duplicateEntity != null)
|
if (duplicateEntity != null)
|
||||||
@ -41,9 +41,20 @@ public class UpdateAircraftCommandHandler :
|
|||||||
"Aircraft with given number already exists.");
|
"Aircraft with given number already exists.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var parentEntity = await _unitOfWork.CompanyRepository.GetOneAsync(
|
||||||
|
e => e.Guid == request.CompanyGuid, cancellationToken);
|
||||||
|
|
||||||
|
if (parentEntity == null)
|
||||||
|
{
|
||||||
|
throw new NotFoundException(
|
||||||
|
$"Parent entity with Guid: {request.CompanyGuid} not found.");
|
||||||
|
}
|
||||||
|
|
||||||
entity.Number = request.Number;
|
entity.Number = request.Number;
|
||||||
entity.Model = request.Model;
|
entity.Model = request.Model;
|
||||||
entity.Capacity = request.Capacity;
|
entity.Capacity = request.Capacity;
|
||||||
|
entity.CompanyId = parentEntity.Id;
|
||||||
|
entity.Company = parentEntity;
|
||||||
|
|
||||||
entity = await _unitOfWork.AircraftRepository.UpdateOneAsync(
|
entity = await _unitOfWork.AircraftRepository.UpdateOneAsync(
|
||||||
entity, cancellationToken);
|
entity, cancellationToken);
|
||||||
|
@ -37,5 +37,9 @@ public class UpdateAircraftCommandValidator : AbstractValidator<UpdateAircraftCo
|
|||||||
RuleFor(v => v.Capacity)
|
RuleFor(v => v.Capacity)
|
||||||
.NotEmpty()
|
.NotEmpty()
|
||||||
.WithMessage(localizer["FluentValidation.NotEmpty"]);
|
.WithMessage(localizer["FluentValidation.NotEmpty"]);
|
||||||
|
|
||||||
|
RuleFor(v => v.CompanyGuid)
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage(localizer["FluentValidation.NotEmpty"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,8 @@ public class GetAircraftQueryHandler :
|
|||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var entity = await _unitOfWork.AircraftRepository.GetOneAsync(
|
var entity = await _unitOfWork.AircraftRepository.GetOneAsync(
|
||||||
e => e.Guid == request.Guid, cancellationToken);
|
e => e.Guid == request.Guid, e => e.Company,
|
||||||
|
cancellationToken);
|
||||||
|
|
||||||
_unitOfWork.Dispose();
|
_unitOfWork.Dispose();
|
||||||
|
|
||||||
|
@ -13,11 +13,9 @@ public record GetAircraftsPageQuery : IRequest<PaginatedList<AircraftDto>>
|
|||||||
|
|
||||||
public string Sort { get; set; } = String.Empty;
|
public string Sort { get; set; } = String.Empty;
|
||||||
|
|
||||||
public string? Number { get; set; }
|
public Guid? CompanyGuid { get; set; }
|
||||||
|
|
||||||
public string? Model { get; set; }
|
public short? CapacityGreaterThanOrEqualTo { get; set; }
|
||||||
|
|
||||||
public short? CapacityGreaterOrEqualThan { get; set; }
|
public short? CapacityLessThanOrEqualTo { get; set; }
|
||||||
|
|
||||||
public short? CapacityLessOrEqualThan { get; set; }
|
|
||||||
}
|
}
|
||||||
|
@ -28,12 +28,16 @@ public class GetAircraftsPageQueryHandler :
|
|||||||
e =>
|
e =>
|
||||||
(e.Number.ToLower().Contains(request.Search.ToLower()) ||
|
(e.Number.ToLower().Contains(request.Search.ToLower()) ||
|
||||||
e.Model.ToLower().Contains(request.Search.ToLower())) &&
|
e.Model.ToLower().Contains(request.Search.ToLower())) &&
|
||||||
(request.CapacityGreaterOrEqualThan != null
|
(request.CompanyGuid != null
|
||||||
? e.Capacity >= request.CapacityGreaterOrEqualThan
|
? e.Company.Guid == request.CompanyGuid
|
||||||
: true) &&
|
: true) &&
|
||||||
(request.CapacityLessOrEqualThan != null
|
(request.CapacityGreaterThanOrEqualTo != null
|
||||||
? e.Capacity <= request.CapacityLessOrEqualThan
|
? e.Capacity >= request.CapacityGreaterThanOrEqualTo
|
||||||
|
: true) &&
|
||||||
|
(request.CapacityLessThanOrEqualTo != null
|
||||||
|
? e.Capacity <= request.CapacityLessThanOrEqualTo
|
||||||
: true),
|
: true),
|
||||||
|
e => e.Company,
|
||||||
request.PageNumber, request.PageSize,
|
request.PageNumber, request.PageSize,
|
||||||
cancellationToken);
|
cancellationToken);
|
||||||
|
|
||||||
|
@ -7,4 +7,6 @@ public sealed class AddAircraftViewModel
|
|||||||
public string Model { get; set; }
|
public string Model { get; set; }
|
||||||
|
|
||||||
public short Capacity { get; set; }
|
public short Capacity { get; set; }
|
||||||
|
|
||||||
|
public Guid CompanyUuid { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -2,14 +2,12 @@ namespace cuqmbr.TravelGuide.Application.Aircrafts.ViewModels;
|
|||||||
|
|
||||||
public sealed class GetAircraftsPageFilterViewModel
|
public sealed class GetAircraftsPageFilterViewModel
|
||||||
{
|
{
|
||||||
public string? Number { get; set; }
|
public Guid? CompanyUuid { get; set; }
|
||||||
|
|
||||||
public string? Model { get; set; }
|
|
||||||
|
|
||||||
// TODO: Consider adding strict equals rule although it is not
|
// TODO: Consider adding strict equals rule although it is not
|
||||||
// necessarily needed to filter with exact capacity
|
// necessarily needed to filter with exact capacity
|
||||||
|
|
||||||
public short? CapacityGreaterOrEqualThan { get; set; }
|
public short? CapacityGreaterThanOrEqualTo { get; set; }
|
||||||
|
|
||||||
public short? CapacityLessOrEqualThan { get; set; }
|
public short? CapacityLessThanOrEqualTo { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -7,4 +7,6 @@ public sealed class UpdateAircraftViewModel
|
|||||||
public string Model { get; set; }
|
public string Model { get; set; }
|
||||||
|
|
||||||
public short Capacity { get; set; }
|
public short Capacity { get; set; }
|
||||||
|
|
||||||
|
public Guid CompanyUuid { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -13,11 +13,16 @@ public sealed class BusDto : IMapFrom<Bus>
|
|||||||
|
|
||||||
public short Capacity { get; set; }
|
public short Capacity { get; set; }
|
||||||
|
|
||||||
|
public Guid CompanyUuid { get; set; }
|
||||||
|
|
||||||
public void Mapping(MappingProfile profile)
|
public void Mapping(MappingProfile profile)
|
||||||
{
|
{
|
||||||
profile.CreateMap<Bus, BusDto>()
|
profile.CreateMap<Bus, BusDto>()
|
||||||
.ForMember(
|
.ForMember(
|
||||||
d => d.Uuid,
|
d => d.Uuid,
|
||||||
opt => opt.MapFrom(s => s.Guid));
|
opt => opt.MapFrom(s => s.Guid))
|
||||||
|
.ForMember(
|
||||||
|
d => d.CompanyUuid,
|
||||||
|
opt => opt.MapFrom(s => s.Company.Guid));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,4 +9,6 @@ public record AddBusCommand : IRequest<BusDto>
|
|||||||
public string Model { get; set; }
|
public string Model { get; set; }
|
||||||
|
|
||||||
public short Capacity { get; set; }
|
public short Capacity { get; set; }
|
||||||
|
|
||||||
|
public Guid CompanyGuid { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -33,11 +33,22 @@ public class AddBusCommandHandler :
|
|||||||
"Bus with given number already exists.");
|
"Bus with given number already exists.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var parentEntity = await _unitOfWork.CompanyRepository.GetOneAsync(
|
||||||
|
e => e.Guid == request.CompanyGuid, cancellationToken);
|
||||||
|
|
||||||
|
if (parentEntity == null)
|
||||||
|
{
|
||||||
|
throw new NotFoundException(
|
||||||
|
$"Parent entity with Guid: {request.CompanyGuid} not found.");
|
||||||
|
}
|
||||||
|
|
||||||
entity = new Bus()
|
entity = new Bus()
|
||||||
{
|
{
|
||||||
Number = request.Number,
|
Number = request.Number,
|
||||||
Model = request.Model,
|
Model = request.Model,
|
||||||
Capacity = request.Capacity
|
Capacity = request.Capacity,
|
||||||
|
CompanyId = parentEntity.Id,
|
||||||
|
Company = parentEntity
|
||||||
};
|
};
|
||||||
|
|
||||||
entity = await _unitOfWork.BusRepository.AddOneAsync(
|
entity = await _unitOfWork.BusRepository.AddOneAsync(
|
||||||
|
@ -33,5 +33,9 @@ public class AddBusCommandValidator : AbstractValidator<AddBusCommand>
|
|||||||
RuleFor(v => v.Capacity)
|
RuleFor(v => v.Capacity)
|
||||||
.NotEmpty()
|
.NotEmpty()
|
||||||
.WithMessage(localizer["FluentValidation.NotEmpty"]);
|
.WithMessage(localizer["FluentValidation.NotEmpty"]);
|
||||||
|
|
||||||
|
RuleFor(v => v.CompanyGuid)
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage(localizer["FluentValidation.NotEmpty"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,4 +11,6 @@ public record UpdateBusCommand : IRequest<BusDto>
|
|||||||
public string Model { get; set; }
|
public string Model { get; set; }
|
||||||
|
|
||||||
public short Capacity { get; set; }
|
public short Capacity { get; set; }
|
||||||
|
|
||||||
|
public Guid CompanyGuid { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ public class UpdateBusCommandHandler :
|
|||||||
}
|
}
|
||||||
|
|
||||||
var duplicateEntity = await _unitOfWork.BusRepository.GetOneAsync(
|
var duplicateEntity = await _unitOfWork.BusRepository.GetOneAsync(
|
||||||
e => e.Number == request.Number,
|
e => e.Number == request.Number && e.Guid != request.Guid,
|
||||||
cancellationToken);
|
cancellationToken);
|
||||||
|
|
||||||
if (duplicateEntity != null)
|
if (duplicateEntity != null)
|
||||||
@ -41,9 +41,20 @@ public class UpdateBusCommandHandler :
|
|||||||
"Bus with given number already exists.");
|
"Bus with given number already exists.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var parentEntity = await _unitOfWork.CompanyRepository.GetOneAsync(
|
||||||
|
e => e.Guid == request.CompanyGuid, cancellationToken);
|
||||||
|
|
||||||
|
if (parentEntity == null)
|
||||||
|
{
|
||||||
|
throw new NotFoundException(
|
||||||
|
$"Parent entity with Guid: {request.CompanyGuid} not found.");
|
||||||
|
}
|
||||||
|
|
||||||
entity.Number = request.Number;
|
entity.Number = request.Number;
|
||||||
entity.Model = request.Model;
|
entity.Model = request.Model;
|
||||||
entity.Capacity = request.Capacity;
|
entity.Capacity = request.Capacity;
|
||||||
|
entity.CompanyId = parentEntity.Id;
|
||||||
|
entity.Company = parentEntity;
|
||||||
|
|
||||||
entity = await _unitOfWork.BusRepository.UpdateOneAsync(
|
entity = await _unitOfWork.BusRepository.UpdateOneAsync(
|
||||||
entity, cancellationToken);
|
entity, cancellationToken);
|
||||||
|
@ -37,5 +37,9 @@ public class UpdateBusCommandValidator : AbstractValidator<UpdateBusCommand>
|
|||||||
RuleFor(v => v.Capacity)
|
RuleFor(v => v.Capacity)
|
||||||
.NotEmpty()
|
.NotEmpty()
|
||||||
.WithMessage(localizer["FluentValidation.NotEmpty"]);
|
.WithMessage(localizer["FluentValidation.NotEmpty"]);
|
||||||
|
|
||||||
|
RuleFor(v => v.CompanyGuid)
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage(localizer["FluentValidation.NotEmpty"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,8 @@ public class GetBusQueryHandler :
|
|||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var entity = await _unitOfWork.BusRepository.GetOneAsync(
|
var entity = await _unitOfWork.BusRepository.GetOneAsync(
|
||||||
e => e.Guid == request.Guid, cancellationToken);
|
e => e.Guid == request.Guid, e => e.Company,
|
||||||
|
cancellationToken);
|
||||||
|
|
||||||
_unitOfWork.Dispose();
|
_unitOfWork.Dispose();
|
||||||
|
|
||||||
|
@ -13,11 +13,9 @@ public record GetBusesPageQuery : IRequest<PaginatedList<BusDto>>
|
|||||||
|
|
||||||
public string Sort { get; set; } = String.Empty;
|
public string Sort { get; set; } = String.Empty;
|
||||||
|
|
||||||
public string? Number { get; set; }
|
public Guid? CompanyGuid { get; set; }
|
||||||
|
|
||||||
public string? Model { get; set; }
|
public short? CapacityGreaterThanOrEqualTo { get; set; }
|
||||||
|
|
||||||
public short? CapacityGreaterOrEqualThan { get; set; }
|
public short? CapacityLessThanOrEqualTo { get; set; }
|
||||||
|
|
||||||
public short? CapacityLessOrEqualThan { get; set; }
|
|
||||||
}
|
}
|
||||||
|
@ -28,12 +28,16 @@ public class GetBusesPageQueryHandler :
|
|||||||
e =>
|
e =>
|
||||||
(e.Number.ToLower().Contains(request.Search.ToLower()) ||
|
(e.Number.ToLower().Contains(request.Search.ToLower()) ||
|
||||||
e.Model.ToLower().Contains(request.Search.ToLower())) &&
|
e.Model.ToLower().Contains(request.Search.ToLower())) &&
|
||||||
(request.CapacityGreaterOrEqualThan != null
|
(request.CompanyGuid != null
|
||||||
? e.Capacity >= request.CapacityGreaterOrEqualThan
|
? e.Company.Guid == request.CompanyGuid
|
||||||
: true) &&
|
: true) &&
|
||||||
(request.CapacityLessOrEqualThan != null
|
(request.CapacityGreaterThanOrEqualTo != null
|
||||||
? e.Capacity <= request.CapacityLessOrEqualThan
|
? e.Capacity >= request.CapacityGreaterThanOrEqualTo
|
||||||
|
: true) &&
|
||||||
|
(request.CapacityLessThanOrEqualTo != null
|
||||||
|
? e.Capacity <= request.CapacityLessThanOrEqualTo
|
||||||
: true),
|
: true),
|
||||||
|
e => e.Company,
|
||||||
request.PageNumber, request.PageSize,
|
request.PageNumber, request.PageSize,
|
||||||
cancellationToken);
|
cancellationToken);
|
||||||
|
|
||||||
|
@ -7,4 +7,6 @@ public sealed class AddBusViewModel
|
|||||||
public string Model { get; set; }
|
public string Model { get; set; }
|
||||||
|
|
||||||
public short Capacity { get; set; }
|
public short Capacity { get; set; }
|
||||||
|
|
||||||
|
public Guid CompanyUuid { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -2,14 +2,9 @@ namespace cuqmbr.TravelGuide.Application.Buses.ViewModels;
|
|||||||
|
|
||||||
public sealed class GetBusesPageFilterViewModel
|
public sealed class GetBusesPageFilterViewModel
|
||||||
{
|
{
|
||||||
public string? Number { get; set; }
|
public Guid? CompanyUuid { get; set; }
|
||||||
|
|
||||||
public string? Model { get; set; }
|
public short? CapacityGreaterThanOrEqualTo { get; set; }
|
||||||
|
|
||||||
// TODO: Consider adding strict equals rule although it is not
|
public short? CapacityLessThanOrEqualTo { get; set; }
|
||||||
// necessarily needed to filter with exact capacity
|
|
||||||
|
|
||||||
public short? CapacityGreaterOrEqualThan { get; set; }
|
|
||||||
|
|
||||||
public short? CapacityLessOrEqualThan { get; set; }
|
|
||||||
}
|
}
|
||||||
|
@ -7,4 +7,6 @@ public sealed class UpdateBusViewModel
|
|||||||
public string Model { get; set; }
|
public string Model { get; set; }
|
||||||
|
|
||||||
public short Capacity { get; set; }
|
public short Capacity { get; set; }
|
||||||
|
|
||||||
|
public Guid CompanyUuid { get; set; }
|
||||||
}
|
}
|
||||||
|
24
src/Application/Common/FluentValidation/CustomValidators.cs
Normal file
24
src/Application/Common/FluentValidation/CustomValidators.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
using FluentValidation;
|
||||||
|
|
||||||
|
namespace cuqmbr.TravelGuide.Application.Common.FluentValidation;
|
||||||
|
|
||||||
|
public static class CustomValidators
|
||||||
|
{
|
||||||
|
// According to RFC 5321.
|
||||||
|
public static IRuleBuilderOptions<T, string> IsEmail<T>(
|
||||||
|
this IRuleBuilder<T, string> ruleBuilder)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
ruleBuilder
|
||||||
|
.Matches(@"^[\w\.-]{1,64}@[\w\.-]{1,251}\.\w{2,4}$");
|
||||||
|
}
|
||||||
|
|
||||||
|
// According to ITU-T E.164, no spaces.
|
||||||
|
public static IRuleBuilderOptions<T, string> IsPhoneNumber<T>(
|
||||||
|
this IRuleBuilder<T, string> ruleBuilder)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
ruleBuilder
|
||||||
|
.Matches(@"^\+[0-9]{7,15}$");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
using cuqmbr.TravelGuide.Domain.Entities;
|
||||||
|
|
||||||
|
namespace cuqmbr.TravelGuide.Application.Common.Interfaces
|
||||||
|
.Persistence.Repositories;
|
||||||
|
|
||||||
|
public interface CompanyRepository : BaseRepository<Company> { }
|
@ -26,6 +26,8 @@ public interface UnitOfWork : IDisposable
|
|||||||
|
|
||||||
RouteAddressRepository RouteAddressRepository { get; }
|
RouteAddressRepository RouteAddressRepository { get; }
|
||||||
|
|
||||||
|
CompanyRepository CompanyRepository { get; }
|
||||||
|
|
||||||
int Save();
|
int Save();
|
||||||
|
|
||||||
Task<int> SaveAsync(CancellationToken cancellationToken);
|
Task<int> SaveAsync(CancellationToken cancellationToken);
|
||||||
|
@ -0,0 +1,14 @@
|
|||||||
|
using MediatR;
|
||||||
|
|
||||||
|
namespace cuqmbr.TravelGuide.Application.Companies.Commands.AddCompany;
|
||||||
|
|
||||||
|
public record AddCompanyCommand : IRequest<CompanyDto>
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public string LegalAddress { get; set; }
|
||||||
|
|
||||||
|
public string ContactEmail { get; set; }
|
||||||
|
|
||||||
|
public string ContactPhoneNumber { get; set; }
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
using cuqmbr.TravelGuide.Application.Common.Authorization;
|
||||||
|
using cuqmbr.TravelGuide.Application.Common.Interfaces.Services;
|
||||||
|
using cuqmbr.TravelGuide.Application.Common.Models;
|
||||||
|
using MediatR.Behaviors.Authorization;
|
||||||
|
|
||||||
|
namespace cuqmbr.TravelGuide.Application.Companies.Commands.AddCompany;
|
||||||
|
|
||||||
|
public class AddCompanyCommandAuthorizer :
|
||||||
|
AbstractRequestAuthorizer<AddCompanyCommand>
|
||||||
|
{
|
||||||
|
private readonly SessionUserService _sessionUserService;
|
||||||
|
|
||||||
|
public AddCompanyCommandAuthorizer(SessionUserService sessionUserService)
|
||||||
|
{
|
||||||
|
_sessionUserService = sessionUserService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void BuildPolicy(AddCompanyCommand request)
|
||||||
|
{
|
||||||
|
UseRequirement(new MustBeAuthenticatedRequirement
|
||||||
|
{
|
||||||
|
IsAuthenticated= _sessionUserService.IsAuthenticated
|
||||||
|
});
|
||||||
|
|
||||||
|
UseRequirement(new MustBeInRolesRequirement
|
||||||
|
{
|
||||||
|
RequiredRoles = [IdentityRole.Administrator],
|
||||||
|
UserRoles = _sessionUserService.Roles
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
using MediatR;
|
||||||
|
using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence;
|
||||||
|
using cuqmbr.TravelGuide.Domain.Entities;
|
||||||
|
using AutoMapper;
|
||||||
|
using cuqmbr.TravelGuide.Application.Common.Exceptions;
|
||||||
|
|
||||||
|
namespace cuqmbr.TravelGuide.Application.Companies.Commands.AddCompany;
|
||||||
|
|
||||||
|
public class AddCompanyCommandHandler :
|
||||||
|
IRequestHandler<AddCompanyCommand, CompanyDto>
|
||||||
|
{
|
||||||
|
private readonly UnitOfWork _unitOfWork;
|
||||||
|
private readonly IMapper _mapper;
|
||||||
|
|
||||||
|
public AddCompanyCommandHandler(
|
||||||
|
UnitOfWork unitOfWork,
|
||||||
|
IMapper mapper)
|
||||||
|
{
|
||||||
|
_unitOfWork = unitOfWork;
|
||||||
|
_mapper = mapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<CompanyDto> Handle(
|
||||||
|
AddCompanyCommand request,
|
||||||
|
CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var entity = await _unitOfWork.CompanyRepository.GetOneAsync(
|
||||||
|
e => e.Name == request.Name, cancellationToken);
|
||||||
|
|
||||||
|
if (entity != null)
|
||||||
|
{
|
||||||
|
throw new DuplicateEntityException(
|
||||||
|
"Company with given name already exists.");
|
||||||
|
}
|
||||||
|
|
||||||
|
entity = new Company()
|
||||||
|
{
|
||||||
|
Name = request.Name,
|
||||||
|
LegalAddress = request.LegalAddress,
|
||||||
|
ContactEmail = request.ContactEmail,
|
||||||
|
ContactPhoneNumber = request.ContactPhoneNumber
|
||||||
|
};
|
||||||
|
|
||||||
|
entity = await _unitOfWork.CompanyRepository.AddOneAsync(
|
||||||
|
entity, cancellationToken);
|
||||||
|
|
||||||
|
await _unitOfWork.SaveAsync(cancellationToken);
|
||||||
|
_unitOfWork.Dispose();
|
||||||
|
|
||||||
|
return _mapper.Map<CompanyDto>(entity);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
using cuqmbr.TravelGuide.Application.Common.FluentValidation;
|
||||||
|
using cuqmbr.TravelGuide.Application.Common.Interfaces.Services;
|
||||||
|
using FluentValidation;
|
||||||
|
using Microsoft.Extensions.Localization;
|
||||||
|
|
||||||
|
namespace cuqmbr.TravelGuide.Application.Companies.Commands.AddCompany;
|
||||||
|
|
||||||
|
public class AddCompanyCommandValidator : AbstractValidator<AddCompanyCommand>
|
||||||
|
{
|
||||||
|
public AddCompanyCommandValidator(
|
||||||
|
IStringLocalizer localizer,
|
||||||
|
SessionCultureService cultureService)
|
||||||
|
{
|
||||||
|
RuleFor(v => v.Name)
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage(localizer["FluentValidation.NotEmpty"])
|
||||||
|
.MaximumLength(64)
|
||||||
|
.WithMessage(
|
||||||
|
String.Format(
|
||||||
|
cultureService.Culture,
|
||||||
|
localizer["FluentValidation.MaximumLength"],
|
||||||
|
64));
|
||||||
|
|
||||||
|
RuleFor(v => v.LegalAddress)
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage(localizer["FluentValidation.NotEmpty"])
|
||||||
|
.MaximumLength(256)
|
||||||
|
.WithMessage(
|
||||||
|
String.Format(
|
||||||
|
cultureService.Culture,
|
||||||
|
localizer["FluentValidation.MaximumLength"],
|
||||||
|
256));
|
||||||
|
|
||||||
|
RuleFor(v => v.ContactEmail)
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage(localizer["FluentValidation.NotEmpty"])
|
||||||
|
.IsEmail()
|
||||||
|
.WithMessage(localizer["FluentValidation.IsEmail"])
|
||||||
|
.MaximumLength(256)
|
||||||
|
.WithMessage(
|
||||||
|
String.Format(
|
||||||
|
cultureService.Culture,
|
||||||
|
localizer["FluentValidation.MaximumLength"],
|
||||||
|
256));
|
||||||
|
|
||||||
|
RuleFor(v => v.ContactPhoneNumber)
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage(localizer["FluentValidation.NotEmpty"])
|
||||||
|
.IsPhoneNumber()
|
||||||
|
.WithMessage(localizer["FluentValidation.IsPhoneNumber"])
|
||||||
|
.MaximumLength(64)
|
||||||
|
.WithMessage(
|
||||||
|
String.Format(
|
||||||
|
cultureService.Culture,
|
||||||
|
localizer["FluentValidation.MaximumLength"],
|
||||||
|
64));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
using MediatR;
|
||||||
|
|
||||||
|
namespace cuqmbr.TravelGuide.Application.Companies.Commands.DeleteCompany;
|
||||||
|
|
||||||
|
public record DeleteCompanyCommand : IRequest
|
||||||
|
{
|
||||||
|
public Guid Guid { get; set; }
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
using cuqmbr.TravelGuide.Application.Common.Authorization;
|
||||||
|
using cuqmbr.TravelGuide.Application.Common.Interfaces.Services;
|
||||||
|
using cuqmbr.TravelGuide.Application.Common.Models;
|
||||||
|
using MediatR.Behaviors.Authorization;
|
||||||
|
|
||||||
|
namespace cuqmbr.TravelGuide.Application.Companies.Commands.DeleteCompany;
|
||||||
|
|
||||||
|
public class DeleteCompanyCommandAuthorizer :
|
||||||
|
AbstractRequestAuthorizer<DeleteCompanyCommand>
|
||||||
|
{
|
||||||
|
private readonly SessionUserService _sessionUserService;
|
||||||
|
|
||||||
|
public DeleteCompanyCommandAuthorizer(SessionUserService sessionUserService)
|
||||||
|
{
|
||||||
|
_sessionUserService = sessionUserService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void BuildPolicy(DeleteCompanyCommand request)
|
||||||
|
{
|
||||||
|
UseRequirement(new MustBeAuthenticatedRequirement
|
||||||
|
{
|
||||||
|
IsAuthenticated= _sessionUserService.IsAuthenticated
|
||||||
|
});
|
||||||
|
|
||||||
|
UseRequirement(new MustBeInRolesRequirement
|
||||||
|
{
|
||||||
|
RequiredRoles = [IdentityRole.Administrator],
|
||||||
|
UserRoles = _sessionUserService.Roles
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
using MediatR;
|
||||||
|
using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence;
|
||||||
|
using cuqmbr.TravelGuide.Application.Common.Exceptions;
|
||||||
|
|
||||||
|
namespace cuqmbr.TravelGuide.Application.Companies.Commands.DeleteCompany;
|
||||||
|
|
||||||
|
public class DeleteCompanyCommandHandler : IRequestHandler<DeleteCompanyCommand>
|
||||||
|
{
|
||||||
|
private readonly UnitOfWork _unitOfWork;
|
||||||
|
|
||||||
|
public DeleteCompanyCommandHandler(UnitOfWork unitOfWork)
|
||||||
|
{
|
||||||
|
_unitOfWork = unitOfWork;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Handle(
|
||||||
|
DeleteCompanyCommand request,
|
||||||
|
CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var entity = await _unitOfWork.CompanyRepository.GetOneAsync(
|
||||||
|
e => e.Guid == request.Guid, cancellationToken);
|
||||||
|
|
||||||
|
if (entity == null)
|
||||||
|
{
|
||||||
|
throw new NotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
|
await _unitOfWork.CompanyRepository.DeleteOneAsync(
|
||||||
|
entity, cancellationToken);
|
||||||
|
|
||||||
|
await _unitOfWork.SaveAsync(cancellationToken);
|
||||||
|
_unitOfWork.Dispose();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
using FluentValidation;
|
||||||
|
using Microsoft.Extensions.Localization;
|
||||||
|
|
||||||
|
namespace cuqmbr.TravelGuide.Application.Companies.Commands.DeleteCompany;
|
||||||
|
|
||||||
|
public class DeleteCompanyCommandValidator : AbstractValidator<DeleteCompanyCommand>
|
||||||
|
{
|
||||||
|
public DeleteCompanyCommandValidator(IStringLocalizer localizer)
|
||||||
|
{
|
||||||
|
RuleFor(v => v.Guid)
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage(localizer["FluentValidation.NotEmpty"]);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
using MediatR;
|
||||||
|
|
||||||
|
namespace cuqmbr.TravelGuide.Application.Companies.Commands.UpdateCompany;
|
||||||
|
|
||||||
|
public record UpdateCompanyCommand : IRequest<CompanyDto>
|
||||||
|
{
|
||||||
|
public Guid Guid { get; set; }
|
||||||
|
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public string LegalAddress { get; set; }
|
||||||
|
|
||||||
|
public string ContactEmail { get; set; }
|
||||||
|
|
||||||
|
public string ContactPhoneNumber { get; set; }
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
using cuqmbr.TravelGuide.Application.Common.Authorization;
|
||||||
|
using cuqmbr.TravelGuide.Application.Common.Interfaces.Services;
|
||||||
|
using cuqmbr.TravelGuide.Application.Common.Models;
|
||||||
|
using MediatR.Behaviors.Authorization;
|
||||||
|
|
||||||
|
namespace cuqmbr.TravelGuide.Application.Companies.Commands.UpdateCompany;
|
||||||
|
|
||||||
|
public class UpdateCompanyCommandAuthorizer :
|
||||||
|
AbstractRequestAuthorizer<UpdateCompanyCommand>
|
||||||
|
{
|
||||||
|
private readonly SessionUserService _sessionUserService;
|
||||||
|
|
||||||
|
public UpdateCompanyCommandAuthorizer(SessionUserService sessionUserService)
|
||||||
|
{
|
||||||
|
_sessionUserService = sessionUserService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void BuildPolicy(UpdateCompanyCommand request)
|
||||||
|
{
|
||||||
|
UseRequirement(new MustBeAuthenticatedRequirement
|
||||||
|
{
|
||||||
|
IsAuthenticated= _sessionUserService.IsAuthenticated
|
||||||
|
});
|
||||||
|
|
||||||
|
UseRequirement(new MustBeInRolesRequirement
|
||||||
|
{
|
||||||
|
RequiredRoles = [IdentityRole.Administrator],
|
||||||
|
UserRoles = _sessionUserService.Roles
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
using MediatR;
|
||||||
|
using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence;
|
||||||
|
using AutoMapper;
|
||||||
|
using cuqmbr.TravelGuide.Application.Common.Exceptions;
|
||||||
|
|
||||||
|
namespace cuqmbr.TravelGuide.Application.Companies.Commands.UpdateCompany;
|
||||||
|
|
||||||
|
public class UpdateCompanyCommandHandler :
|
||||||
|
IRequestHandler<UpdateCompanyCommand, CompanyDto>
|
||||||
|
{
|
||||||
|
private readonly UnitOfWork _unitOfWork;
|
||||||
|
private readonly IMapper _mapper;
|
||||||
|
|
||||||
|
public UpdateCompanyCommandHandler(
|
||||||
|
UnitOfWork unitOfWork,
|
||||||
|
IMapper mapper)
|
||||||
|
{
|
||||||
|
_unitOfWork = unitOfWork;
|
||||||
|
_mapper = mapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<CompanyDto> Handle(
|
||||||
|
UpdateCompanyCommand request,
|
||||||
|
CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var entity = await _unitOfWork.CompanyRepository.GetOneAsync(
|
||||||
|
e => e.Guid == request.Guid, cancellationToken);
|
||||||
|
|
||||||
|
if (entity == null)
|
||||||
|
{
|
||||||
|
throw new NotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
|
entity.Name = request.Name;
|
||||||
|
entity.LegalAddress = request.LegalAddress;
|
||||||
|
entity.ContactEmail = request.ContactEmail;
|
||||||
|
entity.ContactPhoneNumber = request.ContactPhoneNumber;
|
||||||
|
|
||||||
|
entity = await _unitOfWork.CompanyRepository.UpdateOneAsync(
|
||||||
|
entity, cancellationToken);
|
||||||
|
|
||||||
|
await _unitOfWork.SaveAsync(cancellationToken);
|
||||||
|
_unitOfWork.Dispose();
|
||||||
|
|
||||||
|
return _mapper.Map<CompanyDto>(entity);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
using cuqmbr.TravelGuide.Application.Common.FluentValidation;
|
||||||
|
using cuqmbr.TravelGuide.Application.Common.Interfaces.Services;
|
||||||
|
using FluentValidation;
|
||||||
|
using Microsoft.Extensions.Localization;
|
||||||
|
|
||||||
|
namespace cuqmbr.TravelGuide.Application.Companies.Commands.UpdateCompany;
|
||||||
|
|
||||||
|
public class UpdateCompanyCommandValidator : AbstractValidator<UpdateCompanyCommand>
|
||||||
|
{
|
||||||
|
public UpdateCompanyCommandValidator(
|
||||||
|
IStringLocalizer localizer,
|
||||||
|
SessionCultureService cultureService)
|
||||||
|
{
|
||||||
|
RuleFor(v => v.Guid)
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage(localizer["FluentValidation.NotEmpty"]);
|
||||||
|
|
||||||
|
RuleFor(v => v.Name)
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage(localizer["FluentValidation.NotEmpty"])
|
||||||
|
.MaximumLength(64)
|
||||||
|
.WithMessage(
|
||||||
|
String.Format(
|
||||||
|
cultureService.Culture,
|
||||||
|
localizer["FluentValidation.MaximumLength"],
|
||||||
|
64));
|
||||||
|
|
||||||
|
RuleFor(v => v.LegalAddress)
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage(localizer["FluentValidation.NotEmpty"])
|
||||||
|
.MaximumLength(256)
|
||||||
|
.WithMessage(
|
||||||
|
String.Format(
|
||||||
|
cultureService.Culture,
|
||||||
|
localizer["FluentValidation.MaximumLength"],
|
||||||
|
256));
|
||||||
|
|
||||||
|
RuleFor(v => v.ContactEmail)
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage(localizer["FluentValidation.NotEmpty"])
|
||||||
|
.IsEmail()
|
||||||
|
.WithMessage(localizer["FluentValidation.IsEmail"])
|
||||||
|
.MaximumLength(256)
|
||||||
|
.WithMessage(
|
||||||
|
String.Format(
|
||||||
|
cultureService.Culture,
|
||||||
|
localizer["FluentValidation.MaximumLength"],
|
||||||
|
256));
|
||||||
|
|
||||||
|
RuleFor(v => v.ContactPhoneNumber)
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage(localizer["FluentValidation.NotEmpty"])
|
||||||
|
.IsPhoneNumber()
|
||||||
|
.WithMessage(localizer["FluentValidation.IsPhoneNumber"])
|
||||||
|
.MaximumLength(64)
|
||||||
|
.WithMessage(
|
||||||
|
String.Format(
|
||||||
|
cultureService.Culture,
|
||||||
|
localizer["FluentValidation.MaximumLength"],
|
||||||
|
64));
|
||||||
|
}
|
||||||
|
}
|
25
src/Application/Companies/CompanyDto.cs
Normal file
25
src/Application/Companies/CompanyDto.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
using cuqmbr.TravelGuide.Application.Common.Mappings;
|
||||||
|
using cuqmbr.TravelGuide.Domain.Entities;
|
||||||
|
|
||||||
|
namespace cuqmbr.TravelGuide.Application.Companies;
|
||||||
|
|
||||||
|
public sealed class CompanyDto : IMapFrom<Company>
|
||||||
|
{
|
||||||
|
public Guid Uuid { get; set; }
|
||||||
|
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public string LegalAddress { get; set; }
|
||||||
|
|
||||||
|
public string ContactEmail { get; set; }
|
||||||
|
|
||||||
|
public string ContactPhoneNumber { get; set; }
|
||||||
|
|
||||||
|
public void Mapping(MappingProfile profile)
|
||||||
|
{
|
||||||
|
profile.CreateMap<Company, CompanyDto>()
|
||||||
|
.ForMember(
|
||||||
|
d => d.Uuid,
|
||||||
|
opt => opt.MapFrom(s => s.Guid));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
using cuqmbr.TravelGuide.Application.Common.Models;
|
||||||
|
using MediatR;
|
||||||
|
|
||||||
|
namespace cuqmbr.TravelGuide.Application.Companies.Queries.GetCompaniesPage;
|
||||||
|
|
||||||
|
public record GetCompaniesPageQuery : IRequest<PaginatedList<CompanyDto>>
|
||||||
|
{
|
||||||
|
public int PageNumber { get; set; } = 1;
|
||||||
|
|
||||||
|
public int PageSize { get; set; } = 10;
|
||||||
|
|
||||||
|
public string Search { get; set; } = String.Empty;
|
||||||
|
|
||||||
|
public string Sort { get; set; } = String.Empty;
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
using cuqmbr.TravelGuide.Application.Common.Authorization;
|
||||||
|
using cuqmbr.TravelGuide.Application.Common.Interfaces.Services;
|
||||||
|
using cuqmbr.TravelGuide.Application.Common.Models;
|
||||||
|
using MediatR.Behaviors.Authorization;
|
||||||
|
|
||||||
|
namespace cuqmbr.TravelGuide.Application.Companies.Queries.GetCompaniesPage;
|
||||||
|
|
||||||
|
public class GetCompaniesPageQueryAuthorizer :
|
||||||
|
AbstractRequestAuthorizer<GetCompaniesPageQuery>
|
||||||
|
{
|
||||||
|
private readonly SessionUserService _sessionUserService;
|
||||||
|
|
||||||
|
public GetCompaniesPageQueryAuthorizer(SessionUserService sessionUserService)
|
||||||
|
{
|
||||||
|
_sessionUserService = sessionUserService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void BuildPolicy(GetCompaniesPageQuery request)
|
||||||
|
{
|
||||||
|
UseRequirement(new MustBeAuthenticatedRequirement
|
||||||
|
{
|
||||||
|
IsAuthenticated= _sessionUserService.IsAuthenticated
|
||||||
|
});
|
||||||
|
|
||||||
|
UseRequirement(new MustBeInRolesRequirement
|
||||||
|
{
|
||||||
|
RequiredRoles = [IdentityRole.Administrator],
|
||||||
|
UserRoles = _sessionUserService.Roles
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
using MediatR;
|
||||||
|
using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence;
|
||||||
|
using AutoMapper;
|
||||||
|
using cuqmbr.TravelGuide.Application.Common.Models;
|
||||||
|
using cuqmbr.TravelGuide.Application.Common.Extensions;
|
||||||
|
|
||||||
|
namespace cuqmbr.TravelGuide.Application.Companies.Queries.GetCompaniesPage;
|
||||||
|
|
||||||
|
public class GetCompaniesPageQueryHandler :
|
||||||
|
IRequestHandler<GetCompaniesPageQuery, PaginatedList<CompanyDto>>
|
||||||
|
{
|
||||||
|
private readonly UnitOfWork _unitOfWork;
|
||||||
|
private readonly IMapper _mapper;
|
||||||
|
|
||||||
|
public GetCompaniesPageQueryHandler(
|
||||||
|
UnitOfWork unitOfWork,
|
||||||
|
IMapper mapper)
|
||||||
|
{
|
||||||
|
_unitOfWork = unitOfWork;
|
||||||
|
_mapper = mapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<PaginatedList<CompanyDto>> Handle(
|
||||||
|
GetCompaniesPageQuery request,
|
||||||
|
CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var paginatedList = await _unitOfWork.CompanyRepository.GetPageAsync(
|
||||||
|
e =>
|
||||||
|
e.Name.ToLower().Contains(request.Search.ToLower()) ||
|
||||||
|
e.LegalAddress.ToLower().Contains(request.Search.ToLower()) ||
|
||||||
|
e.ContactEmail.ToLower().Contains(request.Search.ToLower()) ||
|
||||||
|
e.ContactPhoneNumber.ToLower().Contains(request.Search.ToLower()),
|
||||||
|
request.PageNumber, request.PageSize,
|
||||||
|
cancellationToken);
|
||||||
|
|
||||||
|
var mappedItems = _mapper
|
||||||
|
.ProjectTo<CompanyDto>(paginatedList.Items.AsQueryable());
|
||||||
|
|
||||||
|
mappedItems = QueryableExtension<CompanyDto>
|
||||||
|
.ApplySort(mappedItems, request.Sort);
|
||||||
|
|
||||||
|
_unitOfWork.Dispose();
|
||||||
|
|
||||||
|
return new PaginatedList<CompanyDto>(
|
||||||
|
mappedItems.ToList(),
|
||||||
|
paginatedList.TotalCount, request.PageNumber,
|
||||||
|
request.PageSize);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
using cuqmbr.TravelGuide.Application.Common.Interfaces.Services;
|
||||||
|
using FluentValidation;
|
||||||
|
using Microsoft.Extensions.Localization;
|
||||||
|
|
||||||
|
namespace cuqmbr.TravelGuide.Application.Companies.Queries.GetCompaniesPage;
|
||||||
|
|
||||||
|
public class GetCompaniesPageQueryValidator : AbstractValidator<GetCompaniesPageQuery>
|
||||||
|
{
|
||||||
|
public GetCompaniesPageQueryValidator(
|
||||||
|
IStringLocalizer localizer,
|
||||||
|
SessionCultureService cultureService)
|
||||||
|
{
|
||||||
|
RuleFor(v => v.PageNumber)
|
||||||
|
.GreaterThanOrEqualTo(1)
|
||||||
|
.WithMessage(
|
||||||
|
String.Format(
|
||||||
|
cultureService.Culture,
|
||||||
|
localizer["FluentValidation.GreaterThanOrEqualTo"],
|
||||||
|
1));
|
||||||
|
|
||||||
|
RuleFor(v => v.PageSize)
|
||||||
|
.GreaterThanOrEqualTo(1)
|
||||||
|
.WithMessage(
|
||||||
|
String.Format(
|
||||||
|
cultureService.Culture,
|
||||||
|
localizer["FluentValidation.GreaterThanOrEqualTo"],
|
||||||
|
1))
|
||||||
|
.LessThanOrEqualTo(50)
|
||||||
|
.WithMessage(
|
||||||
|
String.Format(
|
||||||
|
cultureService.Culture,
|
||||||
|
localizer["FluentValidation.LessThanOrEqualTo"],
|
||||||
|
50));
|
||||||
|
|
||||||
|
RuleFor(v => v.Search)
|
||||||
|
.MaximumLength(64)
|
||||||
|
.WithMessage(
|
||||||
|
String.Format(
|
||||||
|
cultureService.Culture,
|
||||||
|
localizer["FluentValidation.MaximumLength"],
|
||||||
|
64));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
using MediatR;
|
||||||
|
|
||||||
|
namespace cuqmbr.TravelGuide.Application.Companies.Queries.GetCompany;
|
||||||
|
|
||||||
|
public record GetCompanyQuery : IRequest<CompanyDto>
|
||||||
|
{
|
||||||
|
public Guid Guid { get; set; }
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
using cuqmbr.TravelGuide.Application.Common.Authorization;
|
||||||
|
using cuqmbr.TravelGuide.Application.Common.Interfaces.Services;
|
||||||
|
using cuqmbr.TravelGuide.Application.Common.Models;
|
||||||
|
using MediatR.Behaviors.Authorization;
|
||||||
|
|
||||||
|
namespace cuqmbr.TravelGuide.Application.Companies.Queries.GetCompany;
|
||||||
|
|
||||||
|
public class GetCompanyQueryAuthorizer :
|
||||||
|
AbstractRequestAuthorizer<GetCompanyQuery>
|
||||||
|
{
|
||||||
|
private readonly SessionUserService _sessionUserService;
|
||||||
|
|
||||||
|
public GetCompanyQueryAuthorizer(SessionUserService sessionUserService)
|
||||||
|
{
|
||||||
|
_sessionUserService = sessionUserService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void BuildPolicy(GetCompanyQuery request)
|
||||||
|
{
|
||||||
|
UseRequirement(new MustBeAuthenticatedRequirement
|
||||||
|
{
|
||||||
|
IsAuthenticated= _sessionUserService.IsAuthenticated
|
||||||
|
});
|
||||||
|
|
||||||
|
UseRequirement(new MustBeInRolesRequirement
|
||||||
|
{
|
||||||
|
RequiredRoles = [IdentityRole.Administrator],
|
||||||
|
UserRoles = _sessionUserService.Roles
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
using MediatR;
|
||||||
|
using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence;
|
||||||
|
using cuqmbr.TravelGuide.Application.Common.Exceptions;
|
||||||
|
using AutoMapper;
|
||||||
|
|
||||||
|
namespace cuqmbr.TravelGuide.Application.Companies.Queries.GetCompany;
|
||||||
|
|
||||||
|
public class GetCompanyQueryHandler :
|
||||||
|
IRequestHandler<GetCompanyQuery, CompanyDto>
|
||||||
|
{
|
||||||
|
private readonly UnitOfWork _unitOfWork;
|
||||||
|
private readonly IMapper _mapper;
|
||||||
|
|
||||||
|
public GetCompanyQueryHandler(
|
||||||
|
UnitOfWork unitOfWork,
|
||||||
|
IMapper mapper)
|
||||||
|
{
|
||||||
|
_unitOfWork = unitOfWork;
|
||||||
|
_mapper = mapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<CompanyDto> Handle(
|
||||||
|
GetCompanyQuery request,
|
||||||
|
CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var entity = await _unitOfWork.CompanyRepository.GetOneAsync(
|
||||||
|
e => e.Guid == request.Guid, cancellationToken);
|
||||||
|
|
||||||
|
_unitOfWork.Dispose();
|
||||||
|
|
||||||
|
if (entity == null)
|
||||||
|
{
|
||||||
|
throw new NotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return _mapper.Map<CompanyDto>(entity);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
using FluentValidation;
|
||||||
|
using Microsoft.Extensions.Localization;
|
||||||
|
|
||||||
|
namespace cuqmbr.TravelGuide.Application.Companies.Queries.GetCompany;
|
||||||
|
|
||||||
|
public class GetCompanyQueryValidator : AbstractValidator<GetCompanyQuery>
|
||||||
|
{
|
||||||
|
public GetCompanyQueryValidator(IStringLocalizer localizer)
|
||||||
|
{
|
||||||
|
RuleFor(v => v.Guid)
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage(localizer["FluentValidation.NotEmpty"]);
|
||||||
|
}
|
||||||
|
}
|
12
src/Application/Companies/ViewModels/AddCompanyViewModel.cs
Normal file
12
src/Application/Companies/ViewModels/AddCompanyViewModel.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
namespace cuqmbr.TravelGuide.Application.Companies.ViewModels;
|
||||||
|
|
||||||
|
public sealed class AddCompanyViewModel
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public string LegalAddress { get; set; }
|
||||||
|
|
||||||
|
public string ContactEmail { get; set; }
|
||||||
|
|
||||||
|
public string ContactPhoneNumber { get; set; }
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
namespace cuqmbr.TravelGuide.Application.Companies.ViewModels;
|
||||||
|
|
||||||
|
public sealed class UpdateCompanyViewModel
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public string LegalAddress { get; set; }
|
||||||
|
|
||||||
|
public string ContactEmail { get; set; }
|
||||||
|
|
||||||
|
public string ContactPhoneNumber { get; set; }
|
||||||
|
}
|
@ -4,7 +4,9 @@
|
|||||||
"NotEmpty": "Must not be empty.",
|
"NotEmpty": "Must not be empty.",
|
||||||
"GreaterThanOrEqualTo": "Must be greater than or equal to {0:G}.",
|
"GreaterThanOrEqualTo": "Must be greater than or equal to {0:G}.",
|
||||||
"LessThanOrEqualTo": "Must be less than or equal to {0:G}.",
|
"LessThanOrEqualTo": "Must be less than or equal to {0:G}.",
|
||||||
"MustBeInEnum": "Must be one of the following: {0}."
|
"MustBeInEnum": "Must be one of the following: {0}.",
|
||||||
|
"IsEmail": "Must be a valid email address according to RFC 5321.",
|
||||||
|
"IsPhoneNumber": "Must be a valid phone number according to ITU-T E.164 with no separator characters."
|
||||||
},
|
},
|
||||||
"Validation": {
|
"Validation": {
|
||||||
"DistinctOrder": "Must have distinct order values.",
|
"DistinctOrder": "Must have distinct order values.",
|
||||||
|
@ -9,4 +9,6 @@ public record AddTrainCommand : IRequest<TrainDto>
|
|||||||
public string Model { get; set; }
|
public string Model { get; set; }
|
||||||
|
|
||||||
public short Capacity { get; set; }
|
public short Capacity { get; set; }
|
||||||
|
|
||||||
|
public Guid CompanyGuid { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -33,11 +33,22 @@ public class AddTrainCommandHandler :
|
|||||||
"Train with given number already exists.");
|
"Train with given number already exists.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var parentEntity = await _unitOfWork.CompanyRepository.GetOneAsync(
|
||||||
|
e => e.Guid == request.CompanyGuid, cancellationToken);
|
||||||
|
|
||||||
|
if (parentEntity == null)
|
||||||
|
{
|
||||||
|
throw new NotFoundException(
|
||||||
|
$"Parent entity with Guid: {request.CompanyGuid} not found.");
|
||||||
|
}
|
||||||
|
|
||||||
entity = new Train()
|
entity = new Train()
|
||||||
{
|
{
|
||||||
Number = request.Number,
|
Number = request.Number,
|
||||||
Model = request.Model,
|
Model = request.Model,
|
||||||
Capacity = request.Capacity
|
Capacity = request.Capacity,
|
||||||
|
CompanyId = parentEntity.Id,
|
||||||
|
Company = parentEntity
|
||||||
};
|
};
|
||||||
|
|
||||||
entity = await _unitOfWork.TrainRepository.AddOneAsync(
|
entity = await _unitOfWork.TrainRepository.AddOneAsync(
|
||||||
|
@ -33,5 +33,9 @@ public class AddTrainCommandValidator : AbstractValidator<AddTrainCommand>
|
|||||||
RuleFor(v => v.Capacity)
|
RuleFor(v => v.Capacity)
|
||||||
.NotEmpty()
|
.NotEmpty()
|
||||||
.WithMessage(localizer["FluentValidation.NotEmpty"]);
|
.WithMessage(localizer["FluentValidation.NotEmpty"]);
|
||||||
|
|
||||||
|
RuleFor(v => v.CompanyGuid)
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage(localizer["FluentValidation.NotEmpty"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,4 +11,6 @@ public record UpdateTrainCommand : IRequest<TrainDto>
|
|||||||
public string Model { get; set; }
|
public string Model { get; set; }
|
||||||
|
|
||||||
public short Capacity { get; set; }
|
public short Capacity { get; set; }
|
||||||
|
|
||||||
|
public Guid CompanyGuid { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ public class UpdateTrainCommandHandler :
|
|||||||
}
|
}
|
||||||
|
|
||||||
var duplicateEntity = await _unitOfWork.TrainRepository.GetOneAsync(
|
var duplicateEntity = await _unitOfWork.TrainRepository.GetOneAsync(
|
||||||
e => e.Number == request.Number,
|
e => e.Number == request.Number && e.Guid != request.Guid,
|
||||||
cancellationToken);
|
cancellationToken);
|
||||||
|
|
||||||
if (duplicateEntity != null)
|
if (duplicateEntity != null)
|
||||||
@ -41,9 +41,20 @@ public class UpdateTrainCommandHandler :
|
|||||||
"Train with given number already exists.");
|
"Train with given number already exists.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var parentEntity = await _unitOfWork.CompanyRepository.GetOneAsync(
|
||||||
|
e => e.Guid == request.CompanyGuid, cancellationToken);
|
||||||
|
|
||||||
|
if (parentEntity == null)
|
||||||
|
{
|
||||||
|
throw new NotFoundException(
|
||||||
|
$"Parent entity with Guid: {request.CompanyGuid} not found.");
|
||||||
|
}
|
||||||
|
|
||||||
entity.Number = request.Number;
|
entity.Number = request.Number;
|
||||||
entity.Model = request.Model;
|
entity.Model = request.Model;
|
||||||
entity.Capacity = request.Capacity;
|
entity.Capacity = request.Capacity;
|
||||||
|
entity.CompanyId = parentEntity.Id;
|
||||||
|
entity.Company = parentEntity;
|
||||||
|
|
||||||
entity = await _unitOfWork.TrainRepository.UpdateOneAsync(
|
entity = await _unitOfWork.TrainRepository.UpdateOneAsync(
|
||||||
entity, cancellationToken);
|
entity, cancellationToken);
|
||||||
|
@ -37,5 +37,9 @@ public class UpdateTrainCommandValidator : AbstractValidator<UpdateTrainCommand>
|
|||||||
RuleFor(v => v.Capacity)
|
RuleFor(v => v.Capacity)
|
||||||
.NotEmpty()
|
.NotEmpty()
|
||||||
.WithMessage(localizer["FluentValidation.NotEmpty"]);
|
.WithMessage(localizer["FluentValidation.NotEmpty"]);
|
||||||
|
|
||||||
|
RuleFor(v => v.CompanyGuid)
|
||||||
|
.NotEmpty()
|
||||||
|
.WithMessage(localizer["FluentValidation.NotEmpty"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,8 @@ public class GetTrainQueryHandler :
|
|||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var entity = await _unitOfWork.TrainRepository.GetOneAsync(
|
var entity = await _unitOfWork.TrainRepository.GetOneAsync(
|
||||||
e => e.Guid == request.Guid, cancellationToken);
|
e => e.Guid == request.Guid, e => e.Company,
|
||||||
|
cancellationToken);
|
||||||
|
|
||||||
_unitOfWork.Dispose();
|
_unitOfWork.Dispose();
|
||||||
|
|
||||||
|
@ -13,9 +13,7 @@ public record GetTrainsPageQuery : IRequest<PaginatedList<TrainDto>>
|
|||||||
|
|
||||||
public string Sort { get; set; } = String.Empty;
|
public string Sort { get; set; } = String.Empty;
|
||||||
|
|
||||||
public string? Number { get; set; }
|
public Guid? CompanyGuid { get; set; }
|
||||||
|
|
||||||
public string? Model { get; set; }
|
|
||||||
|
|
||||||
public short? CapacityGreaterOrEqualThan { get; set; }
|
public short? CapacityGreaterOrEqualThan { get; set; }
|
||||||
|
|
||||||
|
@ -28,12 +28,16 @@ public class GetTrainsPageQueryHandler :
|
|||||||
e =>
|
e =>
|
||||||
(e.Number.ToLower().Contains(request.Search.ToLower()) ||
|
(e.Number.ToLower().Contains(request.Search.ToLower()) ||
|
||||||
e.Model.ToLower().Contains(request.Search.ToLower())) &&
|
e.Model.ToLower().Contains(request.Search.ToLower())) &&
|
||||||
|
(request.CompanyGuid != null
|
||||||
|
? e.Company.Guid == request.CompanyGuid
|
||||||
|
: true) &&
|
||||||
(request.CapacityGreaterOrEqualThan != null
|
(request.CapacityGreaterOrEqualThan != null
|
||||||
? e.Capacity >= request.CapacityGreaterOrEqualThan
|
? e.Capacity >= request.CapacityGreaterOrEqualThan
|
||||||
: true) &&
|
: true) &&
|
||||||
(request.CapacityLessOrEqualThan != null
|
(request.CapacityLessOrEqualThan != null
|
||||||
? e.Capacity <= request.CapacityLessOrEqualThan
|
? e.Capacity <= request.CapacityLessOrEqualThan
|
||||||
: true),
|
: true),
|
||||||
|
e => e.Company,
|
||||||
request.PageNumber, request.PageSize,
|
request.PageNumber, request.PageSize,
|
||||||
cancellationToken);
|
cancellationToken);
|
||||||
|
|
||||||
|
@ -13,11 +13,16 @@ public sealed class TrainDto : IMapFrom<Train>
|
|||||||
|
|
||||||
public short Capacity { get; set; }
|
public short Capacity { get; set; }
|
||||||
|
|
||||||
|
public Guid CompanyUuid { get; set; }
|
||||||
|
|
||||||
public void Mapping(MappingProfile profile)
|
public void Mapping(MappingProfile profile)
|
||||||
{
|
{
|
||||||
profile.CreateMap<Train, TrainDto>()
|
profile.CreateMap<Train, TrainDto>()
|
||||||
.ForMember(
|
.ForMember(
|
||||||
d => d.Uuid,
|
d => d.Uuid,
|
||||||
opt => opt.MapFrom(s => s.Guid));
|
opt => opt.MapFrom(s => s.Guid))
|
||||||
|
.ForMember(
|
||||||
|
d => d.CompanyUuid,
|
||||||
|
opt => opt.MapFrom(s => s.Company.Guid));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,4 +7,6 @@ public sealed class AddTrainViewModel
|
|||||||
public string Model { get; set; }
|
public string Model { get; set; }
|
||||||
|
|
||||||
public short Capacity { get; set; }
|
public short Capacity { get; set; }
|
||||||
|
|
||||||
|
public Guid CompanyUuid { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -2,14 +2,12 @@ namespace cuqmbr.TravelGuide.Application.Trains.ViewModels;
|
|||||||
|
|
||||||
public sealed class GetTrainsPageFilterViewModel
|
public sealed class GetTrainsPageFilterViewModel
|
||||||
{
|
{
|
||||||
public string? Number { get; set; }
|
|
||||||
|
|
||||||
public string? Model { get; set; }
|
|
||||||
|
|
||||||
// TODO: Consider adding strict equals rule although it is not
|
// TODO: Consider adding strict equals rule although it is not
|
||||||
// necessarily needed to filter with exact capacity
|
// necessarily needed to filter with exact capacity
|
||||||
|
|
||||||
public short? CapacityGreaterOrEqualThan { get; set; }
|
public Guid? CompanyUuid { get; set; }
|
||||||
|
|
||||||
public short? CapacityLessOrEqualThan { get; set; }
|
public short? CapacityGreaterThanOrEqualTo { get; set; }
|
||||||
|
|
||||||
|
public short? CapacityLessThanOrEqualTo { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -7,4 +7,6 @@ public sealed class UpdateTrainViewModel
|
|||||||
public string Model { get; set; }
|
public string Model { get; set; }
|
||||||
|
|
||||||
public short Capacity { get; set; }
|
public short Capacity { get; set; }
|
||||||
|
|
||||||
|
public Guid CompanyUuid { get; set; }
|
||||||
}
|
}
|
||||||
|
15
src/Domain/Entities/Company.cs
Normal file
15
src/Domain/Entities/Company.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
namespace cuqmbr.TravelGuide.Domain.Entities;
|
||||||
|
|
||||||
|
public sealed class Company : EntityBase
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public string LegalAddress { get; set; }
|
||||||
|
|
||||||
|
public string ContactEmail { get; set; }
|
||||||
|
|
||||||
|
public string ContactPhoneNumber { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
public ICollection<Vehicle> Vehicles { get; set; }
|
||||||
|
}
|
@ -7,5 +7,10 @@ public abstract class Vehicle : EntityBase
|
|||||||
public VehicleType VehicleType { get; set; }
|
public VehicleType VehicleType { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
public long CompanyId { get; set; }
|
||||||
|
|
||||||
|
public Company Company { get; set; }
|
||||||
|
|
||||||
|
|
||||||
public ICollection<VehicleEnrollment> Enrollments { get; set; }
|
public ICollection<VehicleEnrollment> Enrollments { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ using Microsoft.AspNetCore.Mvc;
|
|||||||
using Swashbuckle.AspNetCore.Annotations;
|
using Swashbuckle.AspNetCore.Annotations;
|
||||||
using cuqmbr.TravelGuide.Application.Common.Models;
|
using cuqmbr.TravelGuide.Application.Common.Models;
|
||||||
using cuqmbr.TravelGuide.Application.Common.ViewModels;
|
using cuqmbr.TravelGuide.Application.Common.ViewModels;
|
||||||
using cuqmbr.TravelGuide.Domain.Enums;
|
|
||||||
using cuqmbr.TravelGuide.Application.Aircrafts;
|
using cuqmbr.TravelGuide.Application.Aircrafts;
|
||||||
using cuqmbr.TravelGuide.Application.Aircrafts.Commands.AddAircraft;
|
using cuqmbr.TravelGuide.Application.Aircrafts.Commands.AddAircraft;
|
||||||
using cuqmbr.TravelGuide.Application.Aircrafts.Queries.GetAircraftsPage;
|
using cuqmbr.TravelGuide.Application.Aircrafts.Queries.GetAircraftsPage;
|
||||||
@ -51,7 +50,8 @@ public class AircraftsController : ControllerBase
|
|||||||
{
|
{
|
||||||
Number = viewModel.Number,
|
Number = viewModel.Number,
|
||||||
Model = viewModel.Model,
|
Model = viewModel.Model,
|
||||||
Capacity = viewModel.Capacity
|
Capacity = viewModel.Capacity,
|
||||||
|
CompanyGuid = viewModel.CompanyUuid
|
||||||
},
|
},
|
||||||
cancellationToken));
|
cancellationToken));
|
||||||
}
|
}
|
||||||
@ -87,10 +87,11 @@ public class AircraftsController : ControllerBase
|
|||||||
PageSize = pageQuery.PageSize,
|
PageSize = pageQuery.PageSize,
|
||||||
Search = searchQuery.Search,
|
Search = searchQuery.Search,
|
||||||
Sort = sortQuery.Sort,
|
Sort = sortQuery.Sort,
|
||||||
CapacityGreaterOrEqualThan =
|
CompanyGuid = filterQuery.CompanyUuid,
|
||||||
filterQuery.CapacityGreaterOrEqualThan,
|
CapacityGreaterThanOrEqualTo =
|
||||||
CapacityLessOrEqualThan =
|
filterQuery.CapacityGreaterThanOrEqualTo,
|
||||||
filterQuery.CapacityLessOrEqualThan
|
CapacityLessThanOrEqualTo =
|
||||||
|
filterQuery.CapacityLessThanOrEqualTo
|
||||||
},
|
},
|
||||||
cancellationToken);
|
cancellationToken);
|
||||||
}
|
}
|
||||||
@ -158,7 +159,8 @@ public class AircraftsController : ControllerBase
|
|||||||
Guid = uuid,
|
Guid = uuid,
|
||||||
Number = viewModel.Number,
|
Number = viewModel.Number,
|
||||||
Model = viewModel.Model,
|
Model = viewModel.Model,
|
||||||
Capacity = viewModel.Capacity
|
Capacity = viewModel.Capacity,
|
||||||
|
CompanyGuid = viewModel.CompanyUuid
|
||||||
},
|
},
|
||||||
cancellationToken);
|
cancellationToken);
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ using Microsoft.AspNetCore.Mvc;
|
|||||||
using Swashbuckle.AspNetCore.Annotations;
|
using Swashbuckle.AspNetCore.Annotations;
|
||||||
using cuqmbr.TravelGuide.Application.Common.Models;
|
using cuqmbr.TravelGuide.Application.Common.Models;
|
||||||
using cuqmbr.TravelGuide.Application.Common.ViewModels;
|
using cuqmbr.TravelGuide.Application.Common.ViewModels;
|
||||||
using cuqmbr.TravelGuide.Domain.Enums;
|
|
||||||
using cuqmbr.TravelGuide.Application.Buses;
|
using cuqmbr.TravelGuide.Application.Buses;
|
||||||
using cuqmbr.TravelGuide.Application.Buses.Commands.AddBus;
|
using cuqmbr.TravelGuide.Application.Buses.Commands.AddBus;
|
||||||
using cuqmbr.TravelGuide.Application.Buses.Queries.GetBusesPage;
|
using cuqmbr.TravelGuide.Application.Buses.Queries.GetBusesPage;
|
||||||
@ -51,7 +50,8 @@ public class BusesController : ControllerBase
|
|||||||
{
|
{
|
||||||
Number = viewModel.Number,
|
Number = viewModel.Number,
|
||||||
Model = viewModel.Model,
|
Model = viewModel.Model,
|
||||||
Capacity = viewModel.Capacity
|
Capacity = viewModel.Capacity,
|
||||||
|
CompanyGuid = viewModel.CompanyUuid
|
||||||
},
|
},
|
||||||
cancellationToken));
|
cancellationToken));
|
||||||
}
|
}
|
||||||
@ -87,10 +87,11 @@ public class BusesController : ControllerBase
|
|||||||
PageSize = pageQuery.PageSize,
|
PageSize = pageQuery.PageSize,
|
||||||
Search = searchQuery.Search,
|
Search = searchQuery.Search,
|
||||||
Sort = sortQuery.Sort,
|
Sort = sortQuery.Sort,
|
||||||
CapacityGreaterOrEqualThan =
|
CompanyGuid = filterQuery.CompanyUuid,
|
||||||
filterQuery.CapacityGreaterOrEqualThan,
|
CapacityGreaterThanOrEqualTo =
|
||||||
CapacityLessOrEqualThan =
|
filterQuery.CapacityGreaterThanOrEqualTo,
|
||||||
filterQuery.CapacityLessOrEqualThan
|
CapacityLessThanOrEqualTo =
|
||||||
|
filterQuery.CapacityLessThanOrEqualTo
|
||||||
},
|
},
|
||||||
cancellationToken);
|
cancellationToken);
|
||||||
}
|
}
|
||||||
@ -158,7 +159,8 @@ public class BusesController : ControllerBase
|
|||||||
Guid = uuid,
|
Guid = uuid,
|
||||||
Number = viewModel.Number,
|
Number = viewModel.Number,
|
||||||
Model = viewModel.Model,
|
Model = viewModel.Model,
|
||||||
Capacity = viewModel.Capacity
|
Capacity = viewModel.Capacity,
|
||||||
|
CompanyGuid = viewModel.CompanyUuid
|
||||||
},
|
},
|
||||||
cancellationToken);
|
cancellationToken);
|
||||||
}
|
}
|
||||||
|
190
src/HttpApi/Controllers/CompaniesController.cs
Normal file
190
src/HttpApi/Controllers/CompaniesController.cs
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Swashbuckle.AspNetCore.Annotations;
|
||||||
|
using cuqmbr.TravelGuide.Application.Common.Models;
|
||||||
|
using cuqmbr.TravelGuide.Application.Common.ViewModels;
|
||||||
|
using cuqmbr.TravelGuide.Application.Companies;
|
||||||
|
using cuqmbr.TravelGuide.Application.Companies.Commands.AddCompany;
|
||||||
|
using cuqmbr.TravelGuide.Application.Companies.Queries.GetCompaniesPage;
|
||||||
|
using cuqmbr.TravelGuide.Application.Companies.Queries.GetCompany;
|
||||||
|
using cuqmbr.TravelGuide.Application.Companies.Commands.UpdateCompany;
|
||||||
|
using cuqmbr.TravelGuide.Application.Companies.Commands.DeleteCompany;
|
||||||
|
using cuqmbr.TravelGuide.Application.Companies.ViewModels;
|
||||||
|
|
||||||
|
namespace cuqmbr.TravelGuide.HttpApi.Controllers;
|
||||||
|
|
||||||
|
[Route("companies")]
|
||||||
|
public class CompaniesController : ControllerBase
|
||||||
|
{
|
||||||
|
[HttpPost]
|
||||||
|
[SwaggerOperation("Add a company")]
|
||||||
|
[SwaggerResponse(
|
||||||
|
StatusCodes.Status201Created, "Object successfuly created",
|
||||||
|
typeof(CompanyDto))]
|
||||||
|
[SwaggerResponse(
|
||||||
|
StatusCodes.Status400BadRequest, "Object already exists",
|
||||||
|
typeof(ProblemDetails))]
|
||||||
|
[SwaggerResponse(
|
||||||
|
StatusCodes.Status400BadRequest, "Input data validation error",
|
||||||
|
typeof(HttpValidationProblemDetails))]
|
||||||
|
[SwaggerResponse(
|
||||||
|
StatusCodes.Status401Unauthorized, "Unauthorized to perform an action",
|
||||||
|
typeof(ProblemDetails))]
|
||||||
|
[SwaggerResponse(
|
||||||
|
StatusCodes.Status403Forbidden,
|
||||||
|
"Not enough privileges to perform an action",
|
||||||
|
typeof(ProblemDetails))]
|
||||||
|
[SwaggerResponse(
|
||||||
|
StatusCodes.Status404NotFound, "Parent object not found",
|
||||||
|
typeof(ProblemDetails))]
|
||||||
|
[SwaggerResponse(
|
||||||
|
StatusCodes.Status500InternalServerError, "Internal server error",
|
||||||
|
typeof(ProblemDetails))]
|
||||||
|
public async Task<ActionResult<CompanyDto>> Add(
|
||||||
|
[FromBody] AddCompanyViewModel viewModel,
|
||||||
|
CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
return StatusCode(
|
||||||
|
StatusCodes.Status201Created,
|
||||||
|
await Mediator.Send(
|
||||||
|
new AddCompanyCommand()
|
||||||
|
{
|
||||||
|
Name = viewModel.Name,
|
||||||
|
LegalAddress = viewModel.LegalAddress,
|
||||||
|
ContactEmail = viewModel.ContactEmail,
|
||||||
|
ContactPhoneNumber = viewModel.ContactPhoneNumber,
|
||||||
|
},
|
||||||
|
cancellationToken));
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
[SwaggerOperation("Get a list of all companies")]
|
||||||
|
[SwaggerResponse(
|
||||||
|
StatusCodes.Status200OK, "Request successful",
|
||||||
|
typeof(PaginatedList<CompanyDto>))]
|
||||||
|
[SwaggerResponse(
|
||||||
|
StatusCodes.Status400BadRequest, "Input data validation error",
|
||||||
|
typeof(HttpValidationProblemDetails))]
|
||||||
|
[SwaggerResponse(
|
||||||
|
StatusCodes.Status401Unauthorized, "Unauthorized to perform an action",
|
||||||
|
typeof(ProblemDetails))]
|
||||||
|
[SwaggerResponse(
|
||||||
|
StatusCodes.Status403Forbidden,
|
||||||
|
"Not enough privileges to perform an action",
|
||||||
|
typeof(ProblemDetails))]
|
||||||
|
[SwaggerResponse(
|
||||||
|
StatusCodes.Status500InternalServerError, "Internal server error",
|
||||||
|
typeof(ProblemDetails))]
|
||||||
|
public async Task<PaginatedList<CompanyDto>> GetPage(
|
||||||
|
[FromQuery] PageQuery pageQuery, [FromQuery] SearchQuery searchQuery,
|
||||||
|
[FromQuery] SortQuery sortQuery,
|
||||||
|
CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
return await Mediator.Send(
|
||||||
|
new GetCompaniesPageQuery()
|
||||||
|
{
|
||||||
|
PageNumber = pageQuery.PageNumber,
|
||||||
|
PageSize = pageQuery.PageSize,
|
||||||
|
Search = searchQuery.Search,
|
||||||
|
Sort = sortQuery.Sort
|
||||||
|
},
|
||||||
|
cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("{uuid:guid}")]
|
||||||
|
[SwaggerOperation("Get a company by uuid")]
|
||||||
|
[SwaggerResponse(
|
||||||
|
StatusCodes.Status200OK, "Request successful", typeof(CompanyDto))]
|
||||||
|
[SwaggerResponse(
|
||||||
|
StatusCodes.Status400BadRequest, "Input data validation error",
|
||||||
|
typeof(HttpValidationProblemDetails))]
|
||||||
|
[SwaggerResponse(
|
||||||
|
StatusCodes.Status401Unauthorized, "Unauthorized to perform an action",
|
||||||
|
typeof(ProblemDetails))]
|
||||||
|
[SwaggerResponse(
|
||||||
|
StatusCodes.Status403Forbidden,
|
||||||
|
"Not enough privileges to perform an action",
|
||||||
|
typeof(ProblemDetails))]
|
||||||
|
[SwaggerResponse(
|
||||||
|
StatusCodes.Status404NotFound, "Object not found", typeof(CompanyDto))]
|
||||||
|
[SwaggerResponse(
|
||||||
|
StatusCodes.Status500InternalServerError, "Internal server error",
|
||||||
|
typeof(ProblemDetails))]
|
||||||
|
public async Task<CompanyDto> Get(
|
||||||
|
[FromRoute] Guid uuid,
|
||||||
|
CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
return await Mediator.Send(new GetCompanyQuery() { Guid = uuid },
|
||||||
|
cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPut("{uuid:guid}")]
|
||||||
|
[SwaggerOperation("Update a company")]
|
||||||
|
[SwaggerResponse(
|
||||||
|
StatusCodes.Status200OK, "Request successful", typeof(CompanyDto))]
|
||||||
|
[SwaggerResponse(
|
||||||
|
StatusCodes.Status400BadRequest, "Object already exists",
|
||||||
|
typeof(ProblemDetails))]
|
||||||
|
[SwaggerResponse(
|
||||||
|
StatusCodes.Status400BadRequest, "Input data validation error",
|
||||||
|
typeof(HttpValidationProblemDetails))]
|
||||||
|
[SwaggerResponse(
|
||||||
|
StatusCodes.Status401Unauthorized, "Unauthorized to perform an action",
|
||||||
|
typeof(ProblemDetails))]
|
||||||
|
[SwaggerResponse(
|
||||||
|
StatusCodes.Status403Forbidden,
|
||||||
|
"Not enough privileges to perform an action",
|
||||||
|
typeof(ProblemDetails))]
|
||||||
|
[SwaggerResponse(
|
||||||
|
StatusCodes.Status404NotFound, "Object not found", typeof(CompanyDto))]
|
||||||
|
[SwaggerResponse(
|
||||||
|
StatusCodes.Status404NotFound, "Parent object not found",
|
||||||
|
typeof(ProblemDetails))]
|
||||||
|
[SwaggerResponse(
|
||||||
|
StatusCodes.Status500InternalServerError, "Internal server error",
|
||||||
|
typeof(ProblemDetails))]
|
||||||
|
public async Task<CompanyDto> Update(
|
||||||
|
[FromRoute] Guid uuid,
|
||||||
|
[FromBody] UpdateCompanyViewModel viewModel,
|
||||||
|
CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
return await Mediator.Send(
|
||||||
|
new UpdateCompanyCommand()
|
||||||
|
{
|
||||||
|
Guid = uuid,
|
||||||
|
Name = viewModel.Name,
|
||||||
|
LegalAddress = viewModel.LegalAddress,
|
||||||
|
ContactEmail = viewModel.ContactEmail,
|
||||||
|
ContactPhoneNumber = viewModel.ContactPhoneNumber,
|
||||||
|
},
|
||||||
|
cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpDelete("{uuid:guid}")]
|
||||||
|
[SwaggerOperation("Delete a company")]
|
||||||
|
[SwaggerResponse(StatusCodes.Status204NoContent, "Request successful")]
|
||||||
|
[SwaggerResponse(
|
||||||
|
StatusCodes.Status400BadRequest, "Input data validation error",
|
||||||
|
typeof(HttpValidationProblemDetails))]
|
||||||
|
[SwaggerResponse(
|
||||||
|
StatusCodes.Status401Unauthorized, "Unauthorized to perform an action",
|
||||||
|
typeof(ProblemDetails))]
|
||||||
|
[SwaggerResponse(
|
||||||
|
StatusCodes.Status403Forbidden,
|
||||||
|
"Not enough privileges to perform an action",
|
||||||
|
typeof(ProblemDetails))]
|
||||||
|
[SwaggerResponse(
|
||||||
|
StatusCodes.Status404NotFound, "Object not found",
|
||||||
|
typeof(ProblemDetails))]
|
||||||
|
[SwaggerResponse(
|
||||||
|
StatusCodes.Status500InternalServerError, "Internal server error",
|
||||||
|
typeof(ProblemDetails))]
|
||||||
|
public async Task<IActionResult> Delete(
|
||||||
|
[FromRoute] Guid uuid,
|
||||||
|
CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
await Mediator.Send(
|
||||||
|
new DeleteCompanyCommand() { Guid = uuid },
|
||||||
|
cancellationToken);
|
||||||
|
return StatusCode(StatusCodes.Status204NoContent);
|
||||||
|
}
|
||||||
|
}
|
@ -88,9 +88,9 @@ public class TrainsController : ControllerBase
|
|||||||
Search = searchQuery.Search,
|
Search = searchQuery.Search,
|
||||||
Sort = sortQuery.Sort,
|
Sort = sortQuery.Sort,
|
||||||
CapacityGreaterOrEqualThan =
|
CapacityGreaterOrEqualThan =
|
||||||
filterQuery.CapacityGreaterOrEqualThan,
|
filterQuery.CapacityGreaterThanOrEqualTo,
|
||||||
CapacityLessOrEqualThan =
|
CapacityLessOrEqualThan =
|
||||||
filterQuery.CapacityLessOrEqualThan
|
filterQuery.CapacityLessThanOrEqualTo
|
||||||
},
|
},
|
||||||
cancellationToken);
|
cancellationToken);
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ public sealed class InMemoryUnitOfWork : UnitOfWork
|
|||||||
new InMemoryVehicleEnrollmentRepository(_dbContext);
|
new InMemoryVehicleEnrollmentRepository(_dbContext);
|
||||||
RouteAddressRepository =
|
RouteAddressRepository =
|
||||||
new InMemoryRouteAddressRepository(_dbContext);
|
new InMemoryRouteAddressRepository(_dbContext);
|
||||||
|
CompanyRepository = new InMemoryCompanyRepository(_dbContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CountryRepository CountryRepository { get; init; }
|
public CountryRepository CountryRepository { get; init; }
|
||||||
@ -50,6 +51,8 @@ public sealed class InMemoryUnitOfWork : UnitOfWork
|
|||||||
|
|
||||||
public RouteAddressRepository RouteAddressRepository { get; init; }
|
public RouteAddressRepository RouteAddressRepository { get; init; }
|
||||||
|
|
||||||
|
public CompanyRepository CompanyRepository { get; init; }
|
||||||
|
|
||||||
public int Save()
|
public int Save()
|
||||||
{
|
{
|
||||||
return _dbContext.SaveChanges();
|
return _dbContext.SaveChanges();
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories;
|
||||||
|
using cuqmbr.TravelGuide.Domain.Entities;
|
||||||
|
|
||||||
|
namespace cuqmbr.TravelGuide.Persistence.InMemory.Repositories;
|
||||||
|
|
||||||
|
public sealed class InMemoryCompanyRepository :
|
||||||
|
InMemoryBaseRepository<Company>, CompanyRepository
|
||||||
|
{
|
||||||
|
public InMemoryCompanyRepository(InMemoryDbContext dbContext)
|
||||||
|
: base(dbContext) { }
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
using cuqmbr.TravelGuide.Domain.Entities;
|
||||||
|
using cuqmbr.TravelGuide.Domain.Enums;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||||
|
|
||||||
|
namespace cuqmbr.TravelGuide.Persistence.PostgreSql.Configurations;
|
||||||
|
|
||||||
|
public class CompanyConfiguration : BaseConfiguration<Company>
|
||||||
|
{
|
||||||
|
public override void Configure(EntityTypeBuilder<Company> builder)
|
||||||
|
{
|
||||||
|
builder
|
||||||
|
.ToTable("companies");
|
||||||
|
|
||||||
|
base.Configure(builder);
|
||||||
|
|
||||||
|
|
||||||
|
builder
|
||||||
|
.Property(c => c.Name)
|
||||||
|
.HasColumnName("name")
|
||||||
|
.HasColumnType("varchar(64)")
|
||||||
|
.IsRequired(true);
|
||||||
|
|
||||||
|
builder
|
||||||
|
.Property(c => c.LegalAddress)
|
||||||
|
.HasColumnName("legal_address")
|
||||||
|
.HasColumnType("varchar(256)")
|
||||||
|
.IsRequired(true);
|
||||||
|
|
||||||
|
builder
|
||||||
|
.Property(c => c.ContactEmail)
|
||||||
|
.HasColumnName("contact_email")
|
||||||
|
.HasColumnType("varchar(256)")
|
||||||
|
.IsRequired(true);
|
||||||
|
|
||||||
|
builder
|
||||||
|
.Property(c => c.ContactPhoneNumber)
|
||||||
|
.HasColumnName("contact_phone_number")
|
||||||
|
.HasColumnType("varchar(64)")
|
||||||
|
.IsRequired(true);
|
||||||
|
}
|
||||||
|
}
|
@ -37,5 +37,29 @@ public class VehicleConfiguration : BaseConfiguration<Vehicle>
|
|||||||
.HasValue<Train>(VehicleType.Train);
|
.HasValue<Train>(VehicleType.Train);
|
||||||
|
|
||||||
base.Configure(builder);
|
base.Configure(builder);
|
||||||
|
|
||||||
|
|
||||||
|
builder
|
||||||
|
.Property(v => v.CompanyId)
|
||||||
|
.HasColumnName("company_id")
|
||||||
|
.HasColumnType("bigint")
|
||||||
|
.IsRequired(true);
|
||||||
|
|
||||||
|
builder
|
||||||
|
.HasOne(v => v.Company)
|
||||||
|
.WithMany(c => c.Vehicles)
|
||||||
|
.HasForeignKey(v => v.CompanyId)
|
||||||
|
.HasConstraintName(
|
||||||
|
"fk_" +
|
||||||
|
$"{builder.Metadata.GetTableName()}_" +
|
||||||
|
$"{builder.Property(v => v.CompanyId).Metadata.GetColumnName()}")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade);
|
||||||
|
|
||||||
|
builder
|
||||||
|
.HasIndex(v => v.CompanyId)
|
||||||
|
.HasDatabaseName(
|
||||||
|
"ix_" +
|
||||||
|
$"{builder.Metadata.GetTableName()}_" +
|
||||||
|
$"{builder.Property(v => v.CompanyId).Metadata.GetColumnName()}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
706
src/Persistence/PostgreSql/Migrations/20250515101417_Add_Companies.Designer.cs
generated
Normal file
706
src/Persistence/PostgreSql/Migrations/20250515101417_Add_Companies.Designer.cs
generated
Normal file
@ -0,0 +1,706 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||||
|
using cuqmbr.TravelGuide.Persistence.PostgreSql;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Persistence.PostgreSql.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(PostgreSqlDbContext))]
|
||||||
|
[Migration("20250515101417_Add_Companies")]
|
||||||
|
partial class Add_Companies
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasDefaultSchema("application")
|
||||||
|
.HasAnnotation("ProductVersion", "9.0.4")
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||||
|
|
||||||
|
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||||
|
|
||||||
|
modelBuilder.HasSequence("addresses_id_sequence");
|
||||||
|
|
||||||
|
modelBuilder.HasSequence("cities_id_sequence");
|
||||||
|
|
||||||
|
modelBuilder.HasSequence("companies_id_sequence");
|
||||||
|
|
||||||
|
modelBuilder.HasSequence("countries_id_sequence");
|
||||||
|
|
||||||
|
modelBuilder.HasSequence("regions_id_sequence");
|
||||||
|
|
||||||
|
modelBuilder.HasSequence("route_address_details_id_sequence");
|
||||||
|
|
||||||
|
modelBuilder.HasSequence("route_addresses_id_sequence");
|
||||||
|
|
||||||
|
modelBuilder.HasSequence("routes_id_sequence");
|
||||||
|
|
||||||
|
modelBuilder.HasSequence("vehicle_enrollments_id_sequence");
|
||||||
|
|
||||||
|
modelBuilder.HasSequence("vehicles_id_sequence");
|
||||||
|
|
||||||
|
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Address", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bigint")
|
||||||
|
.HasColumnName("id")
|
||||||
|
.HasDefaultValueSql("nextval('application.addresses_id_sequence')");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseSequence(b.Property<long>("Id"), "addresses_id_sequence");
|
||||||
|
|
||||||
|
b.Property<long>("CityId")
|
||||||
|
.HasColumnType("bigint")
|
||||||
|
.HasColumnName("city_id");
|
||||||
|
|
||||||
|
b.Property<Guid>("Guid")
|
||||||
|
.HasColumnType("uuid")
|
||||||
|
.HasColumnName("uuid");
|
||||||
|
|
||||||
|
b.Property<double>("Latitude")
|
||||||
|
.HasColumnType("double precision");
|
||||||
|
|
||||||
|
b.Property<double>("Longitude")
|
||||||
|
.HasColumnType("double precision");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("varchar(128)")
|
||||||
|
.HasColumnName("name");
|
||||||
|
|
||||||
|
b.Property<string>("VehicleType")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("varchar(16)")
|
||||||
|
.HasColumnName("vehicle_type");
|
||||||
|
|
||||||
|
b.HasKey("Id")
|
||||||
|
.HasName("pk_addresses");
|
||||||
|
|
||||||
|
b.HasAlternateKey("Guid")
|
||||||
|
.HasName("altk_addresses_uuid");
|
||||||
|
|
||||||
|
b.HasIndex("CityId")
|
||||||
|
.HasDatabaseName("ix_addresses_city_id");
|
||||||
|
|
||||||
|
b.ToTable("addresses", "application", t =>
|
||||||
|
{
|
||||||
|
t.HasCheckConstraint("ck_addresses_vehicle_type", "vehicle_type IN ('bus', 'train', 'aircraft')");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.City", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bigint")
|
||||||
|
.HasColumnName("id")
|
||||||
|
.HasDefaultValueSql("nextval('application.cities_id_sequence')");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseSequence(b.Property<long>("Id"), "cities_id_sequence");
|
||||||
|
|
||||||
|
b.Property<Guid>("Guid")
|
||||||
|
.HasColumnType("uuid")
|
||||||
|
.HasColumnName("uuid");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("varchar(64)")
|
||||||
|
.HasColumnName("name");
|
||||||
|
|
||||||
|
b.Property<long>("RegionId")
|
||||||
|
.HasColumnType("bigint")
|
||||||
|
.HasColumnName("region_id");
|
||||||
|
|
||||||
|
b.HasKey("Id")
|
||||||
|
.HasName("pk_cities");
|
||||||
|
|
||||||
|
b.HasAlternateKey("Guid")
|
||||||
|
.HasName("altk_cities_uuid");
|
||||||
|
|
||||||
|
b.HasIndex("RegionId")
|
||||||
|
.HasDatabaseName("ix_cities_region_id");
|
||||||
|
|
||||||
|
b.ToTable("cities", "application");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Company", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bigint")
|
||||||
|
.HasColumnName("id")
|
||||||
|
.HasDefaultValueSql("nextval('application.companies_id_sequence')");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseSequence(b.Property<long>("Id"), "companies_id_sequence");
|
||||||
|
|
||||||
|
b.Property<string>("ContactEmail")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("varchar(256)")
|
||||||
|
.HasColumnName("contact_email");
|
||||||
|
|
||||||
|
b.Property<string>("ContactPhoneNumber")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("varchar(64)")
|
||||||
|
.HasColumnName("contact_phone_number");
|
||||||
|
|
||||||
|
b.Property<Guid>("Guid")
|
||||||
|
.HasColumnType("uuid")
|
||||||
|
.HasColumnName("uuid");
|
||||||
|
|
||||||
|
b.Property<string>("LegalAddress")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("varchar(256)")
|
||||||
|
.HasColumnName("legal_address");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("varchar(64)")
|
||||||
|
.HasColumnName("name");
|
||||||
|
|
||||||
|
b.HasKey("Id")
|
||||||
|
.HasName("pk_companies");
|
||||||
|
|
||||||
|
b.HasAlternateKey("Guid")
|
||||||
|
.HasName("altk_companies_uuid");
|
||||||
|
|
||||||
|
b.ToTable("companies", "application");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Country", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bigint")
|
||||||
|
.HasColumnName("id")
|
||||||
|
.HasDefaultValueSql("nextval('application.countries_id_sequence')");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseSequence(b.Property<long>("Id"), "countries_id_sequence");
|
||||||
|
|
||||||
|
b.Property<Guid>("Guid")
|
||||||
|
.HasColumnType("uuid")
|
||||||
|
.HasColumnName("uuid");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("varchar(64)")
|
||||||
|
.HasColumnName("name");
|
||||||
|
|
||||||
|
b.HasKey("Id")
|
||||||
|
.HasName("pk_countries");
|
||||||
|
|
||||||
|
b.HasAlternateKey("Guid")
|
||||||
|
.HasName("altk_countries_uuid");
|
||||||
|
|
||||||
|
b.ToTable("countries", "application");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Region", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bigint")
|
||||||
|
.HasColumnName("id")
|
||||||
|
.HasDefaultValueSql("nextval('application.regions_id_sequence')");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseSequence(b.Property<long>("Id"), "regions_id_sequence");
|
||||||
|
|
||||||
|
b.Property<long>("CountryId")
|
||||||
|
.HasColumnType("bigint")
|
||||||
|
.HasColumnName("country_id");
|
||||||
|
|
||||||
|
b.Property<Guid>("Guid")
|
||||||
|
.HasColumnType("uuid")
|
||||||
|
.HasColumnName("uuid");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("varchar(64)")
|
||||||
|
.HasColumnName("name");
|
||||||
|
|
||||||
|
b.HasKey("Id")
|
||||||
|
.HasName("pk_regions");
|
||||||
|
|
||||||
|
b.HasAlternateKey("Guid")
|
||||||
|
.HasName("altk_regions_uuid");
|
||||||
|
|
||||||
|
b.HasIndex("CountryId")
|
||||||
|
.HasDatabaseName("ix_regions_country_id");
|
||||||
|
|
||||||
|
b.ToTable("regions", "application");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Route", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bigint")
|
||||||
|
.HasColumnName("id")
|
||||||
|
.HasDefaultValueSql("nextval('application.routes_id_sequence')");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseSequence(b.Property<long>("Id"), "routes_id_sequence");
|
||||||
|
|
||||||
|
b.Property<Guid>("Guid")
|
||||||
|
.HasColumnType("uuid")
|
||||||
|
.HasColumnName("uuid");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("varchar(64)")
|
||||||
|
.HasColumnName("name");
|
||||||
|
|
||||||
|
b.Property<string>("VehicleType")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("varchar(16)")
|
||||||
|
.HasColumnName("vehicle_type");
|
||||||
|
|
||||||
|
b.HasKey("Id")
|
||||||
|
.HasName("pk_routes");
|
||||||
|
|
||||||
|
b.HasAlternateKey("Guid")
|
||||||
|
.HasName("altk_routes_uuid");
|
||||||
|
|
||||||
|
b.ToTable("routes", "application", t =>
|
||||||
|
{
|
||||||
|
t.HasCheckConstraint("ck_routes_vehicle_type", "vehicle_type IN ('bus', 'train', 'aircraft')");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.RouteAddress", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bigint")
|
||||||
|
.HasColumnName("id")
|
||||||
|
.HasDefaultValueSql("nextval('application.route_addresses_id_sequence')");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseSequence(b.Property<long>("Id"), "route_addresses_id_sequence");
|
||||||
|
|
||||||
|
b.Property<long>("AddressId")
|
||||||
|
.HasColumnType("bigint")
|
||||||
|
.HasColumnName("address_id");
|
||||||
|
|
||||||
|
b.Property<Guid>("Guid")
|
||||||
|
.HasColumnType("uuid")
|
||||||
|
.HasColumnName("uuid");
|
||||||
|
|
||||||
|
b.Property<short>("Order")
|
||||||
|
.HasColumnType("smallint")
|
||||||
|
.HasColumnName("order");
|
||||||
|
|
||||||
|
b.Property<long>("RouteId")
|
||||||
|
.HasColumnType("bigint")
|
||||||
|
.HasColumnName("route_id");
|
||||||
|
|
||||||
|
b.HasKey("Id")
|
||||||
|
.HasName("pk_route_addresses");
|
||||||
|
|
||||||
|
b.HasAlternateKey("Guid")
|
||||||
|
.HasName("altk_route_addresses_uuid");
|
||||||
|
|
||||||
|
b.HasAlternateKey("AddressId", "RouteId", "Order")
|
||||||
|
.HasName("altk_route_addresses_address_id_route_id_order");
|
||||||
|
|
||||||
|
b.HasIndex("AddressId")
|
||||||
|
.HasDatabaseName("ix_route_addresses_address_id");
|
||||||
|
|
||||||
|
b.HasIndex("RouteId")
|
||||||
|
.HasDatabaseName("ix_route_addresses_route_id");
|
||||||
|
|
||||||
|
b.ToTable("route_addresses", "application");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.RouteAddressDetail", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bigint")
|
||||||
|
.HasColumnName("id")
|
||||||
|
.HasDefaultValueSql("nextval('application.route_address_details_id_sequence')");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseSequence(b.Property<long>("Id"), "route_address_details_id_sequence");
|
||||||
|
|
||||||
|
b.Property<decimal>("CostToNextAddress")
|
||||||
|
.HasColumnType("numeric(24,12)")
|
||||||
|
.HasColumnName("cost_to_next_address");
|
||||||
|
|
||||||
|
b.Property<TimeSpan>("CurrentAddressStopTime")
|
||||||
|
.HasColumnType("interval")
|
||||||
|
.HasColumnName("current_address_stop_time");
|
||||||
|
|
||||||
|
b.Property<Guid>("Guid")
|
||||||
|
.HasColumnType("uuid")
|
||||||
|
.HasColumnName("uuid");
|
||||||
|
|
||||||
|
b.Property<long>("RouteAddressId")
|
||||||
|
.HasColumnType("bigint")
|
||||||
|
.HasColumnName("route_address_id");
|
||||||
|
|
||||||
|
b.Property<TimeSpan>("TimeToNextAddress")
|
||||||
|
.HasColumnType("interval")
|
||||||
|
.HasColumnName("time_to_next_address");
|
||||||
|
|
||||||
|
b.Property<long>("VehicleEnrollmentId")
|
||||||
|
.HasColumnType("bigint")
|
||||||
|
.HasColumnName("vehicle_enrollment_id");
|
||||||
|
|
||||||
|
b.HasKey("Id")
|
||||||
|
.HasName("pk_route_address_details");
|
||||||
|
|
||||||
|
b.HasAlternateKey("Guid")
|
||||||
|
.HasName("altk_route_address_details_uuid");
|
||||||
|
|
||||||
|
b.HasIndex("RouteAddressId")
|
||||||
|
.HasDatabaseName("ix_route_address_details_route_address_id");
|
||||||
|
|
||||||
|
b.HasIndex("VehicleEnrollmentId")
|
||||||
|
.HasDatabaseName("ix_route_address_details_vehicle_enrollment_id");
|
||||||
|
|
||||||
|
b.ToTable("route_address_details", "application");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Vehicle", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bigint")
|
||||||
|
.HasColumnName("id")
|
||||||
|
.HasDefaultValueSql("nextval('application.vehicles_id_sequence')");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseSequence(b.Property<long>("Id"), "vehicles_id_sequence");
|
||||||
|
|
||||||
|
b.Property<long>("CompanyId")
|
||||||
|
.HasColumnType("bigint")
|
||||||
|
.HasColumnName("company_id");
|
||||||
|
|
||||||
|
b.Property<Guid>("Guid")
|
||||||
|
.HasColumnType("uuid")
|
||||||
|
.HasColumnName("uuid");
|
||||||
|
|
||||||
|
b.Property<string>("VehicleType")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("varchar(16)")
|
||||||
|
.HasColumnName("vehicle_type");
|
||||||
|
|
||||||
|
b.HasKey("Id")
|
||||||
|
.HasName("pk_vehicles");
|
||||||
|
|
||||||
|
b.HasAlternateKey("Guid")
|
||||||
|
.HasName("altk_vehicles_uuid");
|
||||||
|
|
||||||
|
b.HasIndex("CompanyId")
|
||||||
|
.HasDatabaseName("ix_vehicles_company_id");
|
||||||
|
|
||||||
|
b.ToTable("vehicles", "application", t =>
|
||||||
|
{
|
||||||
|
t.HasCheckConstraint("ck_vehicles_vehicle_type", "vehicle_type IN ('bus', 'train', 'aircraft')");
|
||||||
|
});
|
||||||
|
|
||||||
|
b.HasDiscriminator<string>("VehicleType");
|
||||||
|
|
||||||
|
b.UseTphMappingStrategy();
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.VehicleEnrollment", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bigint")
|
||||||
|
.HasColumnName("id")
|
||||||
|
.HasDefaultValueSql("nextval('application.vehicle_enrollments_id_sequence')");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseSequence(b.Property<long>("Id"), "vehicle_enrollments_id_sequence");
|
||||||
|
|
||||||
|
b.Property<string>("Currency")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("varchar(8)")
|
||||||
|
.HasColumnName("currency");
|
||||||
|
|
||||||
|
b.Property<DateTimeOffset>("DepartureTime")
|
||||||
|
.HasColumnType("timestamptz")
|
||||||
|
.HasColumnName("departure_time");
|
||||||
|
|
||||||
|
b.Property<Guid>("Guid")
|
||||||
|
.HasColumnType("uuid")
|
||||||
|
.HasColumnName("uuid");
|
||||||
|
|
||||||
|
b.Property<long>("RouteId")
|
||||||
|
.HasColumnType("bigint")
|
||||||
|
.HasColumnName("route_id");
|
||||||
|
|
||||||
|
b.Property<long>("VehicleId")
|
||||||
|
.HasColumnType("bigint")
|
||||||
|
.HasColumnName("vehicle_id");
|
||||||
|
|
||||||
|
b.HasKey("Id")
|
||||||
|
.HasName("pk_vehicle_enrollments");
|
||||||
|
|
||||||
|
b.HasAlternateKey("Guid")
|
||||||
|
.HasName("altk_vehicle_enrollments_uuid");
|
||||||
|
|
||||||
|
b.HasIndex("RouteId")
|
||||||
|
.HasDatabaseName("ix_vehicle_enrollments_route_id");
|
||||||
|
|
||||||
|
b.HasIndex("VehicleId")
|
||||||
|
.HasDatabaseName("ix_vehicle_enrollments_vehicle_id");
|
||||||
|
|
||||||
|
b.ToTable("vehicle_enrollments", "application", t =>
|
||||||
|
{
|
||||||
|
t.HasCheckConstraint("ck_vehicle_enrollments_currency", "currency IN ('DEFAULT', 'USD', 'EUR', 'UAH')");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Aircraft", b =>
|
||||||
|
{
|
||||||
|
b.HasBaseType("cuqmbr.TravelGuide.Domain.Entities.Vehicle");
|
||||||
|
|
||||||
|
b.Property<short>("Capacity")
|
||||||
|
.ValueGeneratedOnUpdateSometimes()
|
||||||
|
.HasColumnType("smallint")
|
||||||
|
.HasColumnName("capacity");
|
||||||
|
|
||||||
|
b.Property<string>("Model")
|
||||||
|
.IsRequired()
|
||||||
|
.ValueGeneratedOnUpdateSometimes()
|
||||||
|
.HasColumnType("varchar(64)")
|
||||||
|
.HasColumnName("model");
|
||||||
|
|
||||||
|
b.Property<string>("Number")
|
||||||
|
.IsRequired()
|
||||||
|
.ValueGeneratedOnUpdateSometimes()
|
||||||
|
.HasColumnType("varchar(32)")
|
||||||
|
.HasColumnName("number");
|
||||||
|
|
||||||
|
b.ToTable(t =>
|
||||||
|
{
|
||||||
|
t.HasCheckConstraint("ck_vehicles_vehicle_type", "vehicle_type IN ('bus', 'train', 'aircraft')");
|
||||||
|
});
|
||||||
|
|
||||||
|
b.HasDiscriminator().HasValue("aircraft");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Bus", b =>
|
||||||
|
{
|
||||||
|
b.HasBaseType("cuqmbr.TravelGuide.Domain.Entities.Vehicle");
|
||||||
|
|
||||||
|
b.Property<short>("Capacity")
|
||||||
|
.ValueGeneratedOnUpdateSometimes()
|
||||||
|
.HasColumnType("smallint")
|
||||||
|
.HasColumnName("capacity");
|
||||||
|
|
||||||
|
b.Property<string>("Model")
|
||||||
|
.IsRequired()
|
||||||
|
.ValueGeneratedOnUpdateSometimes()
|
||||||
|
.HasColumnType("varchar(64)")
|
||||||
|
.HasColumnName("model");
|
||||||
|
|
||||||
|
b.Property<string>("Number")
|
||||||
|
.IsRequired()
|
||||||
|
.ValueGeneratedOnUpdateSometimes()
|
||||||
|
.HasColumnType("varchar(32)")
|
||||||
|
.HasColumnName("number");
|
||||||
|
|
||||||
|
b.ToTable(t =>
|
||||||
|
{
|
||||||
|
t.HasCheckConstraint("ck_vehicles_vehicle_type", "vehicle_type IN ('bus', 'train', 'aircraft')");
|
||||||
|
});
|
||||||
|
|
||||||
|
b.HasDiscriminator().HasValue("bus");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Train", b =>
|
||||||
|
{
|
||||||
|
b.HasBaseType("cuqmbr.TravelGuide.Domain.Entities.Vehicle");
|
||||||
|
|
||||||
|
b.Property<short>("Capacity")
|
||||||
|
.ValueGeneratedOnUpdateSometimes()
|
||||||
|
.HasColumnType("smallint")
|
||||||
|
.HasColumnName("capacity");
|
||||||
|
|
||||||
|
b.Property<string>("Model")
|
||||||
|
.IsRequired()
|
||||||
|
.ValueGeneratedOnUpdateSometimes()
|
||||||
|
.HasColumnType("varchar(64)")
|
||||||
|
.HasColumnName("model");
|
||||||
|
|
||||||
|
b.Property<string>("Number")
|
||||||
|
.IsRequired()
|
||||||
|
.ValueGeneratedOnUpdateSometimes()
|
||||||
|
.HasColumnType("varchar(32)")
|
||||||
|
.HasColumnName("number");
|
||||||
|
|
||||||
|
b.ToTable(t =>
|
||||||
|
{
|
||||||
|
t.HasCheckConstraint("ck_vehicles_vehicle_type", "vehicle_type IN ('bus', 'train', 'aircraft')");
|
||||||
|
});
|
||||||
|
|
||||||
|
b.HasDiscriminator().HasValue("train");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Address", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("cuqmbr.TravelGuide.Domain.Entities.City", "City")
|
||||||
|
.WithMany("Addresses")
|
||||||
|
.HasForeignKey("CityId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_addresses_city_id");
|
||||||
|
|
||||||
|
b.Navigation("City");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.City", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Region", "Region")
|
||||||
|
.WithMany("Cities")
|
||||||
|
.HasForeignKey("RegionId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_cities_region_id");
|
||||||
|
|
||||||
|
b.Navigation("Region");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Region", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Country", "Country")
|
||||||
|
.WithMany("Regions")
|
||||||
|
.HasForeignKey("CountryId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_regions_country_id");
|
||||||
|
|
||||||
|
b.Navigation("Country");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.RouteAddress", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Address", "Address")
|
||||||
|
.WithMany("AddressRoutes")
|
||||||
|
.HasForeignKey("AddressId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_route_addresses_address_id");
|
||||||
|
|
||||||
|
b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Route", "Route")
|
||||||
|
.WithMany("RouteAddresses")
|
||||||
|
.HasForeignKey("RouteId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_route_addresses_route_id");
|
||||||
|
|
||||||
|
b.Navigation("Address");
|
||||||
|
|
||||||
|
b.Navigation("Route");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.RouteAddressDetail", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("cuqmbr.TravelGuide.Domain.Entities.RouteAddress", "RouteAddress")
|
||||||
|
.WithMany("Details")
|
||||||
|
.HasForeignKey("RouteAddressId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_route_address_details_route_address_id");
|
||||||
|
|
||||||
|
b.HasOne("cuqmbr.TravelGuide.Domain.Entities.VehicleEnrollment", "VehicleEnrollment")
|
||||||
|
.WithMany("RouteAddressDetails")
|
||||||
|
.HasForeignKey("VehicleEnrollmentId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_route_address_details_vehicle_enrollment_id");
|
||||||
|
|
||||||
|
b.Navigation("RouteAddress");
|
||||||
|
|
||||||
|
b.Navigation("VehicleEnrollment");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Vehicle", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Company", "Company")
|
||||||
|
.WithMany("Vehicles")
|
||||||
|
.HasForeignKey("CompanyId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_vehicles_company_id");
|
||||||
|
|
||||||
|
b.Navigation("Company");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.VehicleEnrollment", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Route", "Route")
|
||||||
|
.WithMany("VehicleEnrollments")
|
||||||
|
.HasForeignKey("RouteId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_vehicle_enrollments_route_id");
|
||||||
|
|
||||||
|
b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Vehicle", "Vehicle")
|
||||||
|
.WithMany("Enrollments")
|
||||||
|
.HasForeignKey("VehicleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_vehicle_enrollments_vehicle_id");
|
||||||
|
|
||||||
|
b.Navigation("Route");
|
||||||
|
|
||||||
|
b.Navigation("Vehicle");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Address", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("AddressRoutes");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.City", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Addresses");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Company", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Vehicles");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Country", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Regions");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Region", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Cities");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Route", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("RouteAddresses");
|
||||||
|
|
||||||
|
b.Navigation("VehicleEnrollments");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.RouteAddress", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Details");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Vehicle", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Enrollments");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.VehicleEnrollment", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("RouteAddressDetails");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,110 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Persistence.PostgreSql.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class Add_Companies : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropCheckConstraint(
|
||||||
|
name: "ck_vehicle_enrollments_currency",
|
||||||
|
schema: "application",
|
||||||
|
table: "vehicle_enrollments");
|
||||||
|
|
||||||
|
migrationBuilder.CreateSequence(
|
||||||
|
name: "companies_id_sequence",
|
||||||
|
schema: "application");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<long>(
|
||||||
|
name: "company_id",
|
||||||
|
schema: "application",
|
||||||
|
table: "vehicles",
|
||||||
|
type: "bigint",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: 0L);
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "companies",
|
||||||
|
schema: "application",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
id = table.Column<long>(type: "bigint", nullable: false, defaultValueSql: "nextval('application.companies_id_sequence')"),
|
||||||
|
name = table.Column<string>(type: "varchar(64)", nullable: false),
|
||||||
|
legal_address = table.Column<string>(type: "varchar(256)", nullable: false),
|
||||||
|
contact_email = table.Column<string>(type: "varchar(256)", nullable: false),
|
||||||
|
contact_phone_number = table.Column<string>(type: "varchar(64)", nullable: false),
|
||||||
|
uuid = table.Column<Guid>(type: "uuid", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("pk_companies", x => x.id);
|
||||||
|
table.UniqueConstraint("altk_companies_uuid", x => x.uuid);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_vehicles_company_id",
|
||||||
|
schema: "application",
|
||||||
|
table: "vehicles",
|
||||||
|
column: "company_id");
|
||||||
|
|
||||||
|
migrationBuilder.AddCheckConstraint(
|
||||||
|
name: "ck_vehicle_enrollments_currency",
|
||||||
|
schema: "application",
|
||||||
|
table: "vehicle_enrollments",
|
||||||
|
sql: "currency IN ('DEFAULT', 'USD', 'EUR', 'UAH')");
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "fk_vehicles_company_id",
|
||||||
|
schema: "application",
|
||||||
|
table: "vehicles",
|
||||||
|
column: "company_id",
|
||||||
|
principalSchema: "application",
|
||||||
|
principalTable: "companies",
|
||||||
|
principalColumn: "id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "fk_vehicles_company_id",
|
||||||
|
schema: "application",
|
||||||
|
table: "vehicles");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "companies",
|
||||||
|
schema: "application");
|
||||||
|
|
||||||
|
migrationBuilder.DropIndex(
|
||||||
|
name: "ix_vehicles_company_id",
|
||||||
|
schema: "application",
|
||||||
|
table: "vehicles");
|
||||||
|
|
||||||
|
migrationBuilder.DropCheckConstraint(
|
||||||
|
name: "ck_vehicle_enrollments_currency",
|
||||||
|
schema: "application",
|
||||||
|
table: "vehicle_enrollments");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "company_id",
|
||||||
|
schema: "application",
|
||||||
|
table: "vehicles");
|
||||||
|
|
||||||
|
migrationBuilder.DropSequence(
|
||||||
|
name: "companies_id_sequence",
|
||||||
|
schema: "application");
|
||||||
|
|
||||||
|
migrationBuilder.AddCheckConstraint(
|
||||||
|
name: "ck_vehicle_enrollments_currency",
|
||||||
|
schema: "application",
|
||||||
|
table: "vehicle_enrollments",
|
||||||
|
sql: "currency IN ('USD', 'EUR', 'UAH')");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -27,6 +27,8 @@ namespace Persistence.PostgreSql.Migrations
|
|||||||
|
|
||||||
modelBuilder.HasSequence("cities_id_sequence");
|
modelBuilder.HasSequence("cities_id_sequence");
|
||||||
|
|
||||||
|
modelBuilder.HasSequence("companies_id_sequence");
|
||||||
|
|
||||||
modelBuilder.HasSequence("countries_id_sequence");
|
modelBuilder.HasSequence("countries_id_sequence");
|
||||||
|
|
||||||
modelBuilder.HasSequence("regions_id_sequence");
|
modelBuilder.HasSequence("regions_id_sequence");
|
||||||
@ -125,6 +127,49 @@ namespace Persistence.PostgreSql.Migrations
|
|||||||
b.ToTable("cities", "application");
|
b.ToTable("cities", "application");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Company", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bigint")
|
||||||
|
.HasColumnName("id")
|
||||||
|
.HasDefaultValueSql("nextval('application.companies_id_sequence')");
|
||||||
|
|
||||||
|
NpgsqlPropertyBuilderExtensions.UseSequence(b.Property<long>("Id"), "companies_id_sequence");
|
||||||
|
|
||||||
|
b.Property<string>("ContactEmail")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("varchar(256)")
|
||||||
|
.HasColumnName("contact_email");
|
||||||
|
|
||||||
|
b.Property<string>("ContactPhoneNumber")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("varchar(64)")
|
||||||
|
.HasColumnName("contact_phone_number");
|
||||||
|
|
||||||
|
b.Property<Guid>("Guid")
|
||||||
|
.HasColumnType("uuid")
|
||||||
|
.HasColumnName("uuid");
|
||||||
|
|
||||||
|
b.Property<string>("LegalAddress")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("varchar(256)")
|
||||||
|
.HasColumnName("legal_address");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("varchar(64)")
|
||||||
|
.HasColumnName("name");
|
||||||
|
|
||||||
|
b.HasKey("Id")
|
||||||
|
.HasName("pk_companies");
|
||||||
|
|
||||||
|
b.HasAlternateKey("Guid")
|
||||||
|
.HasName("altk_companies_uuid");
|
||||||
|
|
||||||
|
b.ToTable("companies", "application");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Country", b =>
|
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Country", b =>
|
||||||
{
|
{
|
||||||
b.Property<long>("Id")
|
b.Property<long>("Id")
|
||||||
@ -327,6 +372,10 @@ namespace Persistence.PostgreSql.Migrations
|
|||||||
|
|
||||||
NpgsqlPropertyBuilderExtensions.UseSequence(b.Property<long>("Id"), "vehicles_id_sequence");
|
NpgsqlPropertyBuilderExtensions.UseSequence(b.Property<long>("Id"), "vehicles_id_sequence");
|
||||||
|
|
||||||
|
b.Property<long>("CompanyId")
|
||||||
|
.HasColumnType("bigint")
|
||||||
|
.HasColumnName("company_id");
|
||||||
|
|
||||||
b.Property<Guid>("Guid")
|
b.Property<Guid>("Guid")
|
||||||
.HasColumnType("uuid")
|
.HasColumnType("uuid")
|
||||||
.HasColumnName("uuid");
|
.HasColumnName("uuid");
|
||||||
@ -342,6 +391,9 @@ namespace Persistence.PostgreSql.Migrations
|
|||||||
b.HasAlternateKey("Guid")
|
b.HasAlternateKey("Guid")
|
||||||
.HasName("altk_vehicles_uuid");
|
.HasName("altk_vehicles_uuid");
|
||||||
|
|
||||||
|
b.HasIndex("CompanyId")
|
||||||
|
.HasDatabaseName("ix_vehicles_company_id");
|
||||||
|
|
||||||
b.ToTable("vehicles", "application", t =>
|
b.ToTable("vehicles", "application", t =>
|
||||||
{
|
{
|
||||||
t.HasCheckConstraint("ck_vehicles_vehicle_type", "vehicle_type IN ('bus', 'train', 'aircraft')");
|
t.HasCheckConstraint("ck_vehicles_vehicle_type", "vehicle_type IN ('bus', 'train', 'aircraft')");
|
||||||
@ -397,7 +449,7 @@ namespace Persistence.PostgreSql.Migrations
|
|||||||
|
|
||||||
b.ToTable("vehicle_enrollments", "application", t =>
|
b.ToTable("vehicle_enrollments", "application", t =>
|
||||||
{
|
{
|
||||||
t.HasCheckConstraint("ck_vehicle_enrollments_currency", "currency IN ('USD', 'EUR', 'UAH')");
|
t.HasCheckConstraint("ck_vehicle_enrollments_currency", "currency IN ('DEFAULT', 'USD', 'EUR', 'UAH')");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -566,6 +618,18 @@ namespace Persistence.PostgreSql.Migrations
|
|||||||
b.Navigation("VehicleEnrollment");
|
b.Navigation("VehicleEnrollment");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Vehicle", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Company", "Company")
|
||||||
|
.WithMany("Vehicles")
|
||||||
|
.HasForeignKey("CompanyId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired()
|
||||||
|
.HasConstraintName("fk_vehicles_company_id");
|
||||||
|
|
||||||
|
b.Navigation("Company");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.VehicleEnrollment", b =>
|
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.VehicleEnrollment", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Route", "Route")
|
b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Route", "Route")
|
||||||
@ -597,6 +661,11 @@ namespace Persistence.PostgreSql.Migrations
|
|||||||
b.Navigation("Addresses");
|
b.Navigation("Addresses");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Company", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Vehicles");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Country", b =>
|
modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Country", b =>
|
||||||
{
|
{
|
||||||
b.Navigation("Regions");
|
b.Navigation("Regions");
|
||||||
|
@ -26,6 +26,7 @@ public sealed class PostgreSqlUnitOfWork : UnitOfWork
|
|||||||
new PostgreSqlVehicleEnrollmentRepository(_dbContext);
|
new PostgreSqlVehicleEnrollmentRepository(_dbContext);
|
||||||
RouteAddressRepository =
|
RouteAddressRepository =
|
||||||
new PostgreSqlRouteAddressRepository(_dbContext);
|
new PostgreSqlRouteAddressRepository(_dbContext);
|
||||||
|
CompanyRepository = new PostgreSqlCompanyRepository(_dbContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CountryRepository CountryRepository { get; init; }
|
public CountryRepository CountryRepository { get; init; }
|
||||||
@ -50,6 +51,8 @@ public sealed class PostgreSqlUnitOfWork : UnitOfWork
|
|||||||
|
|
||||||
public RouteAddressRepository RouteAddressRepository { get; init; }
|
public RouteAddressRepository RouteAddressRepository { get; init; }
|
||||||
|
|
||||||
|
public CompanyRepository CompanyRepository { get; init; }
|
||||||
|
|
||||||
public int Save()
|
public int Save()
|
||||||
{
|
{
|
||||||
return _dbContext.SaveChanges();
|
return _dbContext.SaveChanges();
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
using cuqmbr.TravelGuide.Application.Common.Interfaces.Persistence.Repositories;
|
||||||
|
using cuqmbr.TravelGuide.Domain.Entities;
|
||||||
|
|
||||||
|
namespace cuqmbr.TravelGuide.Persistence.PostgreSql.Repositories;
|
||||||
|
|
||||||
|
public sealed class PostgreSqlCompanyRepository :
|
||||||
|
PostgreSqlBaseRepository<Company>, CompanyRepository
|
||||||
|
{
|
||||||
|
public PostgreSqlCompanyRepository(PostgreSqlDbContext dbContext)
|
||||||
|
: base(dbContext) { }
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user