diff --git a/src/Application/Payments/LiqPay/TicketGroups/Commands/GetPaymentLink/GetPaymentLinkCommandAuthorizer.cs b/src/Application/Payments/LiqPay/TicketGroups/Commands/GetPaymentLink/GetPaymentLinkCommandAuthorizer.cs index 15e36c4..b1c8fb0 100644 --- a/src/Application/Payments/LiqPay/TicketGroups/Commands/GetPaymentLink/GetPaymentLinkCommandAuthorizer.cs +++ b/src/Application/Payments/LiqPay/TicketGroups/Commands/GetPaymentLink/GetPaymentLinkCommandAuthorizer.cs @@ -1,6 +1,4 @@ using cuqmbr.TravelGuide.Application.Common.Authorization; -using cuqmbr.TravelGuide.Application.Common.Services; -using cuqmbr.TravelGuide.Domain.Enums; using MediatR.Behaviors.Authorization; namespace cuqmbr.TravelGuide.Application.Payments.LiqPay @@ -9,24 +7,8 @@ namespace cuqmbr.TravelGuide.Application.Payments.LiqPay public class GetPaymentLinkCommandAuthorizer : AbstractRequestAuthorizer { - private readonly SessionUserService _sessionUserService; - - public GetPaymentLinkCommandAuthorizer(SessionUserService sessionUserService) - { - _sessionUserService = sessionUserService; - } - public override void BuildPolicy(GetPaymentLinkCommand request) { - UseRequirement(new MustBeAuthenticatedRequirement - { - IsAuthenticated= _sessionUserService.IsAuthenticated - }); - - UseRequirement(new MustBeInRolesRequirement - { - RequiredRoles = [IdentityRole.Administrator], - UserRoles = _sessionUserService.Roles - }); + UseRequirement(new AllowAllRequirement()); } } diff --git a/src/Application/Payments/LiqPay/TicketGroups/Commands/GetPaymentLink/GetPaymentLinkCommandHandler.cs b/src/Application/Payments/LiqPay/TicketGroups/Commands/GetPaymentLink/GetPaymentLinkCommandHandler.cs index dcdd08f..123c931 100644 --- a/src/Application/Payments/LiqPay/TicketGroups/Commands/GetPaymentLink/GetPaymentLinkCommandHandler.cs +++ b/src/Application/Payments/LiqPay/TicketGroups/Commands/GetPaymentLink/GetPaymentLinkCommandHandler.cs @@ -25,6 +25,7 @@ public class GetPaymentLinkCommandHandler : private readonly SessionTimeZoneService _sessionTimeZoneService; private readonly SessionCultureService _sessionCultureService; + private readonly SessionUserService _sessionUserService; public GetPaymentLinkCommandHandler( UnitOfWork unitOfWork, @@ -33,7 +34,8 @@ public class GetPaymentLinkCommandHandler : IStringLocalizer localizer, EmailSenderService emailSender, SessionTimeZoneService SessionTimeZoneService, - SessionCultureService sessionCultureService) + SessionCultureService sessionCultureService, + SessionUserService sessionUserService) { _unitOfWork = unitOfWork; _currencyConverterService = currencyConverterService; @@ -42,6 +44,7 @@ public class GetPaymentLinkCommandHandler : _emailSender = emailSender; _sessionTimeZoneService = SessionTimeZoneService; _sessionCultureService = sessionCultureService; + _sessionUserService = sessionUserService; } public async Task Handle( @@ -409,6 +412,10 @@ public class GetPaymentLinkCommandHandler : .Items; + var account = await _unitOfWork.AccountRepository.GetOneAsync( + e => e.Guid == _sessionUserService.Guid, cancellationToken); + + var travelTime = ticketsDetails.OrderBy(td => td.order).Last().arrivalTime - ticketsDetails.OrderBy(td => td.order).First().departureTime; @@ -451,8 +458,8 @@ public class GetPaymentLinkCommandHandler : Currency = detail.currency, VehicleEnrollmentId = ve.Id }; - }) - .ToArray() + }).ToArray(), + AccountId = account?.Id }; entity = await _unitOfWork.TicketGroupRepository.AddOneAsync( diff --git a/src/Application/TicketGroups/Commands/AddTicketGroup/AddTicketGroupCommandHandler.cs b/src/Application/TicketGroups/Commands/AddTicketGroup/AddTicketGroupCommandHandler.cs index e6f0c3a..9854582 100644 --- a/src/Application/TicketGroups/Commands/AddTicketGroup/AddTicketGroupCommandHandler.cs +++ b/src/Application/TicketGroups/Commands/AddTicketGroup/AddTicketGroupCommandHandler.cs @@ -148,7 +148,7 @@ public class AddTicketGroupCommandHandler : var vehicleEnrollments = (await _unitOfWork.VehicleEnrollmentRepository .GetPageAsync( e => vehicleEnrollmentGuids.Contains(e.Guid), - e => e.Vehicle, + e => e.Vehicle.Company, 1, vehicleEnrollmentGuids.Count(), cancellationToken)) .Items; @@ -416,7 +416,6 @@ public class AddTicketGroupCommandHandler : 1, vehicleEnrollmentGuids.Count(), cancellationToken)) .Items; - var routeAddressGuids = request.Tickets.Select(t => t.DepartureRouteAddressGuid).Concat( request.Tickets.Select(t => t.ArrivalRouteAddressGuid)); diff --git a/src/Application/TicketGroups/Queries/GetTicketGroup/GetTicketGroupQueryHandler.cs b/src/Application/TicketGroups/Queries/GetTicketGroup/GetTicketGroupQueryHandler.cs index f3c270c..e8e50e0 100644 --- a/src/Application/TicketGroups/Queries/GetTicketGroup/GetTicketGroupQueryHandler.cs +++ b/src/Application/TicketGroups/Queries/GetTicketGroup/GetTicketGroupQueryHandler.cs @@ -85,6 +85,14 @@ public class GetTicketGroupQueryHandler : 1, vehicleIds.Count(), cancellationToken)) .Items; + var account = await _unitOfWork.AccountRepository.GetOneAsync( + a => a.Id == ticketGroup.AccountId, cancellationToken); + + if (ticketGroup.AccountId != null) + { + ticketGroup.Account = account; + } + foreach (var ve in vehicleEnrollments) { ve.Vehicle = vehicles.Single(v => v.Id == ve.VehicleId); diff --git a/src/Application/TicketGroups/Queries/GetTicketGroupsPage/GetTicketGroupsPageQuery.cs b/src/Application/TicketGroups/Queries/GetTicketGroupsPage/GetTicketGroupsPageQuery.cs index 2d0a9f9..4f85a19 100644 --- a/src/Application/TicketGroups/Queries/GetTicketGroupsPage/GetTicketGroupsPageQuery.cs +++ b/src/Application/TicketGroups/Queries/GetTicketGroupsPage/GetTicketGroupsPageQuery.cs @@ -32,6 +32,8 @@ public record GetTicketGroupsPageQuery : IRequest> public TimeSpan? TravelTimeLessThanOrEqualTo { get; set; } + public Guid? AccountGuid { get; set; } + // TODO: Add filtering parametetrs listed below. It is hard to // be done because of pagination. diff --git a/src/Application/TicketGroups/Queries/GetTicketGroupsPage/GetTicketGroupsPageQueryHandler.cs b/src/Application/TicketGroups/Queries/GetTicketGroupsPage/GetTicketGroupsPageQueryHandler.cs index a7c0e2b..e350e7d 100644 --- a/src/Application/TicketGroups/Queries/GetTicketGroupsPage/GetTicketGroupsPageQueryHandler.cs +++ b/src/Application/TicketGroups/Queries/GetTicketGroupsPage/GetTicketGroupsPageQueryHandler.cs @@ -76,6 +76,9 @@ public class GetTicketGroupsPageQueryHandler : : true) && (request.TravelTimeLessThanOrEqualTo != null ? e.TravelTime <= request.TravelTimeLessThanOrEqualTo + : true) && + (request.AccountGuid != null + ? e.Account.Guid == request.AccountGuid : true), e => e.Tickets, request.PageNumber, request.PageSize, cancellationToken); @@ -123,6 +126,22 @@ public class GetTicketGroupsPageQueryHandler : 1, vehicleIds.Count(), cancellationToken)) .Items; + var accountIds = + ticketGroups.Select(tg => tg.AccountId); + var accounts = (await _unitOfWork.AccountRepository + .GetPageAsync( + a => accountIds.Contains(a.Id), + 1, accountIds.Count(), cancellationToken)) + .Items; + + foreach (var tg in ticketGroups) + { + if (tg.AccountId != null) + { + tg.Account = accounts.Single(a => a.Id == tg.AccountId); + } + } + foreach (var ve in vehicleEnrollments) { ve.Vehicle = vehicles.Single(v => v.Id == ve.VehicleId); @@ -137,8 +156,8 @@ public class GetTicketGroupsPageQueryHandler : } - // TODO: Replace with AutoMapper resolvers - // Convert currency and apply session time zone + // TODO: Replace with AutoMapper resolvers. + // Convert currency and apply session time zone. var convertTasks = new List(); var processedRouteAddressDetailIds = new HashSet(); diff --git a/src/Application/TicketGroups/TicketGroupAccountDto.cs b/src/Application/TicketGroups/TicketGroupAccountDto.cs new file mode 100644 index 0000000..c439d72 --- /dev/null +++ b/src/Application/TicketGroups/TicketGroupAccountDto.cs @@ -0,0 +1,21 @@ +using cuqmbr.TravelGuide.Application.Common.Mappings; +using cuqmbr.TravelGuide.Domain.Entities; + +namespace cuqmbr.TravelGuide.Application.TicketGroups; + +public sealed class TicketGroupAccountDto : IMapFrom +{ + public Guid Uuid { get; set; } + + public string Username { get; set; } + + public string Email { get; set; } + + public void Mapping(MappingProfile profile) + { + profile.CreateMap() + .ForMember( + d => d.Uuid, + opt => opt.MapFrom(s => s.Guid)); + } +} diff --git a/src/Application/TicketGroups/TicketGroupDto.cs b/src/Application/TicketGroups/TicketGroupDto.cs index 6c5b3c3..bdbbae0 100644 --- a/src/Application/TicketGroups/TicketGroupDto.cs +++ b/src/Application/TicketGroups/TicketGroupDto.cs @@ -39,6 +39,7 @@ public sealed class TicketGroupDto : IMapFrom public decimal Cost { get; set; } + public TicketGroupAccountDto? Account { get; set; } public ICollection Enrollments { get; set; } diff --git a/src/Application/TicketGroups/ViewModels/GetTicketGroupsPageFilterViewModel.cs b/src/Application/TicketGroups/ViewModels/GetTicketGroupsPageFilterViewModel.cs index cee2f12..f60135d 100644 --- a/src/Application/TicketGroups/ViewModels/GetTicketGroupsPageFilterViewModel.cs +++ b/src/Application/TicketGroups/ViewModels/GetTicketGroupsPageFilterViewModel.cs @@ -19,4 +19,6 @@ public sealed class GetTicketGroupsPageFilterViewModel public TimeSpan? TravelTimeGreaterThanOrEqualTo { get; set; } public TimeSpan? TravelTimeLessThanOrEqualTo { get; set; } + + public Guid? AccountUuid { get; set; } } diff --git a/src/Domain/Entities/Account.cs b/src/Domain/Entities/Account.cs index b3b0464..983203d 100644 --- a/src/Domain/Entities/Account.cs +++ b/src/Domain/Entities/Account.cs @@ -18,4 +18,6 @@ public sealed class Account : EntityBase public Employee? Employee { get; set; } public Company? Company { get; set; } + + public ICollection TicketGroups { get; set; } } diff --git a/src/Domain/Entities/TicketGroup.cs b/src/Domain/Entities/TicketGroup.cs index b532b78..66ac0ba 100644 --- a/src/Domain/Entities/TicketGroup.cs +++ b/src/Domain/Entities/TicketGroup.cs @@ -24,4 +24,9 @@ public sealed class TicketGroup : EntityBase public ICollection Tickets { get; set; } + + + public long? AccountId { get; set; } + + public Account? Account { get; set; } } diff --git a/src/HttpApi/Controllers/TicketGroupsController.cs b/src/HttpApi/Controllers/TicketGroupsController.cs index fff0d39..a1291d7 100644 --- a/src/HttpApi/Controllers/TicketGroupsController.cs +++ b/src/HttpApi/Controllers/TicketGroupsController.cs @@ -119,7 +119,8 @@ public class TicketGroupsController : ControllerBase TravelTimeGreaterThanOrEqualTo = filterQuery.TravelTimeGreaterThanOrEqualTo, TravelTimeLessThanOrEqualTo = - filterQuery.TravelTimeLessThanOrEqualTo + filterQuery.TravelTimeLessThanOrEqualTo, + AccountGuid = filterQuery.AccountUuid }, cancellationToken); } diff --git a/src/Persistence/PostgreSql/Configurations/CompanyConfiguration.cs b/src/Persistence/PostgreSql/Configurations/CompanyConfiguration.cs index bc1b29b..0f0a923 100644 --- a/src/Persistence/PostgreSql/Configurations/CompanyConfiguration.cs +++ b/src/Persistence/PostgreSql/Configurations/CompanyConfiguration.cs @@ -54,7 +54,7 @@ public class CompanyConfiguration : BaseConfiguration "fk_" + $"{builder.Metadata.GetTableName()}_" + $"{builder.Property(c => c.AccountId).Metadata.GetColumnName()}") - .OnDelete(DeleteBehavior.Cascade); + .OnDelete(DeleteBehavior.ClientNoAction); builder .HasIndex(c => c.AccountId) diff --git a/src/Persistence/PostgreSql/Configurations/EmployeeConfiguration.cs b/src/Persistence/PostgreSql/Configurations/EmployeeConfiguration.cs index 3aae0e9..345af64 100644 --- a/src/Persistence/PostgreSql/Configurations/EmployeeConfiguration.cs +++ b/src/Persistence/PostgreSql/Configurations/EmployeeConfiguration.cs @@ -69,7 +69,7 @@ public class EmployeeConfiguration : BaseConfiguration "fk_" + $"{builder.Metadata.GetTableName()}_" + $"{builder.Property(e => e.CompanyId).Metadata.GetColumnName()}") - .OnDelete(DeleteBehavior.Cascade); + .OnDelete(DeleteBehavior.ClientNoAction); builder .HasIndex(e => e.CompanyId) diff --git a/src/Persistence/PostgreSql/Configurations/TicketGroupConfiguration.cs b/src/Persistence/PostgreSql/Configurations/TicketGroupConfiguration.cs index 017bbd4..3c29245 100644 --- a/src/Persistence/PostgreSql/Configurations/TicketGroupConfiguration.cs +++ b/src/Persistence/PostgreSql/Configurations/TicketGroupConfiguration.cs @@ -89,5 +89,29 @@ public class TicketGroupConfiguration : BaseConfiguration .HasColumnName("travel_time") .HasColumnType("interval") .IsRequired(true); + + + builder + .Property(tg => tg.AccountId) + .HasColumnName("account_id") + .HasColumnType("bigint") + .IsRequired(false); + + builder + .HasOne(tg => tg.Account) + .WithMany(a => a.TicketGroups) + .HasForeignKey(tg => tg.AccountId) + .HasConstraintName( + "fk_" + + $"{builder.Metadata.GetTableName()}_" + + $"{builder.Property(c => c.AccountId).Metadata.GetColumnName()}") + .OnDelete(DeleteBehavior.SetNull); + + builder + .HasIndex(c => c.AccountId) + .HasDatabaseName( + "ix_" + + $"{builder.Metadata.GetTableName()}_" + + $"{builder.Property(c => c.AccountId).Metadata.GetColumnName()}"); } } diff --git a/src/Persistence/PostgreSql/Migrations/20250530101737_Add_navigation_from_Ticket_Group_to_Account.Designer.cs b/src/Persistence/PostgreSql/Migrations/20250530101737_Add_navigation_from_Ticket_Group_to_Account.Designer.cs new file mode 100644 index 0000000..b5ee921 --- /dev/null +++ b/src/Persistence/PostgreSql/Migrations/20250530101737_Add_navigation_from_Ticket_Group_to_Account.Designer.cs @@ -0,0 +1,1359 @@ +// +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("20250530101737_Add_navigation_from_Ticket_Group_to_Account")] + partial class Add_navigation_from_Ticket_Group_to_Account + { + /// + 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("account_roles_id_sequence"); + + modelBuilder.HasSequence("accounts_id_sequence"); + + modelBuilder.HasSequence("addresses_id_sequence"); + + modelBuilder.HasSequence("cities_id_sequence"); + + modelBuilder.HasSequence("companies_id_sequence"); + + modelBuilder.HasSequence("countries_id_sequence"); + + modelBuilder.HasSequence("employee_documents_id_sequence"); + + modelBuilder.HasSequence("employees_id_sequence"); + + modelBuilder.HasSequence("refresh_tokens_id_sequence"); + + modelBuilder.HasSequence("regions_id_sequence"); + + modelBuilder.HasSequence("roles_id_sequence"); + + modelBuilder.HasSequence("route_address_details_id_sequence"); + + modelBuilder.HasSequence("route_addresses_id_sequence"); + + modelBuilder.HasSequence("routes_id_sequence"); + + modelBuilder.HasSequence("ticket_groups_id_sequence"); + + modelBuilder.HasSequence("tickets_id_sequence"); + + modelBuilder.HasSequence("vehicle_enrollment_employees_id_sequence"); + + modelBuilder.HasSequence("vehicle_enrollments_id_sequence"); + + modelBuilder.HasSequence("vehicles_id_sequence"); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Account", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.accounts_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "accounts_id_sequence"); + + b.Property("Email") + .IsRequired() + .HasColumnType("varchar(256)") + .HasColumnName("email"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("PasswordHash") + .IsRequired() + .HasColumnType("varchar(88)") + .HasColumnName("password_hash"); + + b.Property("PasswordSalt") + .IsRequired() + .HasColumnType("varchar(24)") + .HasColumnName("password_salt"); + + b.Property("Username") + .IsRequired() + .HasColumnType("varchar(32)") + .HasColumnName("username"); + + b.HasKey("Id") + .HasName("pk_accounts"); + + b.HasAlternateKey("Guid") + .HasName("altk_accounts_uuid"); + + b.ToTable("accounts", "application"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.AccountRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.account_roles_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "account_roles_id_sequence"); + + b.Property("AccountId") + .HasColumnType("bigint") + .HasColumnName("account_id"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("RoleId") + .HasColumnType("bigint") + .HasColumnName("role_id"); + + b.HasKey("Id") + .HasName("pk_account_roles"); + + b.HasAlternateKey("Guid") + .HasName("altk_account_roles_uuid"); + + b.HasIndex("AccountId") + .HasDatabaseName("ix_account_roles_account_id"); + + b.HasIndex("RoleId") + .HasDatabaseName("ix_account_roles_role_id"); + + b.ToTable("account_roles", "application"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Address", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.addresses_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "addresses_id_sequence"); + + b.Property("CityId") + .HasColumnType("bigint") + .HasColumnName("city_id"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("Latitude") + .HasColumnType("double precision"); + + b.Property("Longitude") + .HasColumnType("double precision"); + + b.Property("Name") + .IsRequired() + .HasColumnType("varchar(128)") + .HasColumnName("name"); + + b.Property("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("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.cities_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "cities_id_sequence"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("Name") + .IsRequired() + .HasColumnType("varchar(64)") + .HasColumnName("name"); + + b.Property("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("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.companies_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "companies_id_sequence"); + + b.Property("AccountId") + .HasColumnType("bigint") + .HasColumnName("account_id"); + + b.Property("ContactEmail") + .IsRequired() + .HasColumnType("varchar(256)") + .HasColumnName("contact_email"); + + b.Property("ContactPhoneNumber") + .IsRequired() + .HasColumnType("varchar(64)") + .HasColumnName("contact_phone_number"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("LegalAddress") + .IsRequired() + .HasColumnType("varchar(256)") + .HasColumnName("legal_address"); + + b.Property("Name") + .IsRequired() + .HasColumnType("varchar(64)") + .HasColumnName("name"); + + b.HasKey("Id") + .HasName("pk_companies"); + + b.HasAlternateKey("Guid") + .HasName("altk_companies_uuid"); + + b.HasIndex("AccountId") + .IsUnique() + .HasDatabaseName("ix_companies_account_id"); + + b.ToTable("companies", "application"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Country", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.countries_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "countries_id_sequence"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("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.Employee", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.employees_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "employees_id_sequence"); + + b.Property("AccountId") + .HasColumnType("bigint") + .HasColumnName("account_id"); + + b.Property("BirthDate") + .HasColumnType("date") + .HasColumnName("birth_date"); + + b.Property("CompanyId") + .HasColumnType("bigint") + .HasColumnName("company_id"); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("varchar(32)") + .HasColumnName("first_name"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("LastName") + .IsRequired() + .HasColumnType("varchar(32)") + .HasColumnName("last_name"); + + b.Property("Patronymic") + .IsRequired() + .HasColumnType("varchar(32)") + .HasColumnName("patronymic"); + + b.Property("Sex") + .IsRequired() + .HasColumnType("varchar(32)") + .HasColumnName("sex"); + + b.HasKey("Id") + .HasName("pk_employees"); + + b.HasAlternateKey("Guid") + .HasName("altk_employees_uuid"); + + b.HasIndex("AccountId") + .IsUnique() + .HasDatabaseName("ix_employees_account_id"); + + b.HasIndex("CompanyId") + .HasDatabaseName("ix_employees_company_id"); + + b.ToTable("employees", "application", t => + { + t.HasCheckConstraint("ck_employees_sex", "sex IN ('male', 'female')"); + }); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.EmployeeDocument", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.employee_documents_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "employee_documents_id_sequence"); + + b.Property("DocumentType") + .IsRequired() + .HasColumnType("varchar(64)") + .HasColumnName("document_type"); + + b.Property("EmployeeId") + .HasColumnType("bigint") + .HasColumnName("employee_id"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("Information") + .IsRequired() + .HasColumnType("varchar(256)") + .HasColumnName("information"); + + b.HasKey("Id") + .HasName("pk_employee_documents"); + + b.HasAlternateKey("Guid") + .HasName("altk_employee_documents_uuid"); + + b.HasIndex("EmployeeId") + .HasDatabaseName("ix_employee_documents_employee_id"); + + b.ToTable("employee_documents", "application", t => + { + t.HasCheckConstraint("ck_employee_documents_document_type", "document_type IN ('passport')"); + }); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.RefreshToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.refresh_tokens_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "refresh_tokens_id_sequence"); + + b.Property("AccountId") + .HasColumnType("bigint") + .HasColumnName("account_id"); + + b.Property("CreationTime") + .HasColumnType("timestamptz") + .HasColumnName("creation_time"); + + b.Property("ExpirationTime") + .HasColumnType("timestamptz") + .HasColumnName("expiration_time"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("RevocationTime") + .HasColumnType("timestamptz") + .HasColumnName("revocation_time"); + + b.Property("Value") + .IsRequired() + .HasColumnType("varchar(24)") + .HasColumnName("value"); + + b.HasKey("Id") + .HasName("pk_refresh_tokens"); + + b.HasAlternateKey("Guid") + .HasName("altk_refresh_tokens_uuid"); + + b.HasIndex("AccountId") + .HasDatabaseName("ix_refresh_tokens_account_id"); + + b.ToTable("refresh_tokens", "application"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Region", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.regions_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "regions_id_sequence"); + + b.Property("CountryId") + .HasColumnType("bigint") + .HasColumnName("country_id"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("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.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.roles_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "roles_id_sequence"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("Value") + .IsRequired() + .HasColumnType("varchar(64)") + .HasColumnName("name"); + + b.HasKey("Id") + .HasName("pk_roles"); + + b.HasAlternateKey("Guid") + .HasName("altk_roles_uuid"); + + b.ToTable("roles", "application", t => + { + t.HasCheckConstraint("ck_roles_name", "name IN ('administrator', 'user', 'company_owner', 'company_employee')"); + }); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Route", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.routes_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "routes_id_sequence"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("Name") + .IsRequired() + .HasColumnType("varchar(64)") + .HasColumnName("name"); + + b.Property("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("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.route_addresses_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "route_addresses_id_sequence"); + + b.Property("AddressId") + .HasColumnType("bigint") + .HasColumnName("address_id"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("Order") + .HasColumnType("smallint") + .HasColumnName("order"); + + b.Property("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("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.route_address_details_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "route_address_details_id_sequence"); + + b.Property("CostToNextAddress") + .HasColumnType("numeric(24,12)") + .HasColumnName("cost_to_next_address"); + + b.Property("CurrentAddressStopTime") + .HasColumnType("interval") + .HasColumnName("current_address_stop_time"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("RouteAddressId") + .HasColumnType("bigint") + .HasColumnName("route_address_id"); + + b.Property("TimeToNextAddress") + .HasColumnType("interval") + .HasColumnName("time_to_next_address"); + + b.Property("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.Ticket", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.tickets_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "tickets_id_sequence"); + + b.Property("ArrivalRouteAddressId") + .HasColumnType("bigint") + .HasColumnName("arrival_route_address_id"); + + b.Property("Cost") + .HasColumnType("numeric(24,12)") + .HasColumnName("cost"); + + b.Property("Currency") + .IsRequired() + .HasColumnType("varchar(8)") + .HasColumnName("currency"); + + b.Property("DepartureRouteAddressId") + .HasColumnType("bigint") + .HasColumnName("departure_route_address_id"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("Order") + .HasColumnType("smallint") + .HasColumnName("order"); + + b.Property("TicketGroupId") + .HasColumnType("bigint") + .HasColumnName("ticket_group_id"); + + b.Property("VehicleEnrollmentId") + .HasColumnType("bigint") + .HasColumnName("vehicle_enrollment_id"); + + b.HasKey("Id") + .HasName("pk_tickets"); + + b.HasAlternateKey("Guid") + .HasName("altk_tickets_uuid"); + + b.HasIndex("ArrivalRouteAddressId"); + + b.HasIndex("DepartureRouteAddressId"); + + b.HasIndex("TicketGroupId") + .HasDatabaseName("ix_tickets_ticket_group_id"); + + b.HasIndex("VehicleEnrollmentId") + .HasDatabaseName("ix_tickets_vehicle_enrollment_id"); + + b.ToTable("tickets", "application", t => + { + t.HasCheckConstraint("ck_tickets_currency", "currency IN ('DEFAULT', 'USD', 'EUR', 'UAH')"); + }); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.TicketGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.ticket_groups_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "ticket_groups_id_sequence"); + + b.Property("AccountId") + .HasColumnType("bigint") + .HasColumnName("account_id"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("PassangerBirthDate") + .HasColumnType("date") + .HasColumnName("passanger_birth_date"); + + b.Property("PassangerEmail") + .HasColumnType("varchar(256)") + .HasColumnName("passanger_email"); + + b.Property("PassangerFirstName") + .IsRequired() + .HasColumnType("varchar(32)") + .HasColumnName("passanger_first_name"); + + b.Property("PassangerLastName") + .IsRequired() + .HasColumnType("varchar(32)") + .HasColumnName("passanger_last_name"); + + b.Property("PassangerPatronymic") + .IsRequired() + .HasColumnType("varchar(32)") + .HasColumnName("passanger_patronymic"); + + b.Property("PassangerSex") + .IsRequired() + .HasColumnType("varchar(32)") + .HasColumnName("passanger_sex"); + + b.Property("PurchaseTime") + .HasColumnType("timestamptz") + .HasColumnName("purchase_time"); + + b.Property("Status") + .IsRequired() + .HasColumnType("varchar(32)") + .HasColumnName("status"); + + b.Property("TravelTime") + .HasColumnType("interval") + .HasColumnName("travel_time"); + + b.HasKey("Id") + .HasName("pk_ticket_groups"); + + b.HasAlternateKey("Guid") + .HasName("altk_ticket_groups_uuid"); + + b.HasIndex("AccountId") + .HasDatabaseName("ix_ticket_groups_account_id"); + + b.ToTable("ticket_groups", "application", t => + { + t.HasCheckConstraint("ck_ticket_groups_passanger_sex", "passanger_sex IN ('male', 'female')"); + + t.HasCheckConstraint("ck_ticket_groups_status", "status IN ('reserved', 'returned', 'purchased')"); + }); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Vehicle", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.vehicles_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "vehicles_id_sequence"); + + b.Property("CompanyId") + .HasColumnType("bigint") + .HasColumnName("company_id"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("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("VehicleType"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.VehicleEnrollment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.vehicle_enrollments_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "vehicle_enrollments_id_sequence"); + + b.Property("Currency") + .IsRequired() + .HasColumnType("varchar(8)") + .HasColumnName("currency"); + + b.Property("DepartureTime") + .HasColumnType("timestamptz") + .HasColumnName("departure_time"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("RouteId") + .HasColumnType("bigint") + .HasColumnName("route_id"); + + b.Property("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.VehicleEnrollmentEmployee", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasColumnName("id") + .HasDefaultValueSql("nextval('application.vehicle_enrollment_employees_id_sequence')"); + + NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "vehicle_enrollment_employees_id_sequence"); + + b.Property("EmployeeId") + .HasColumnType("bigint") + .HasColumnName("employee_id"); + + b.Property("Guid") + .HasColumnType("uuid") + .HasColumnName("uuid"); + + b.Property("VehicleEnrollmentId") + .HasColumnType("bigint") + .HasColumnName("vehicle_enrollment_id"); + + b.HasKey("Id") + .HasName("pk_vehicle_enrollment_employees"); + + b.HasAlternateKey("Guid") + .HasName("altk_vehicle_enrollment_employees_uuid"); + + b.HasIndex("EmployeeId") + .HasDatabaseName("ix_vehicle_enrollment_employees_employee_id"); + + b.HasIndex("VehicleEnrollmentId") + .HasDatabaseName("ix_vehicle_enrollment_employees_vehicle_enrollment_id"); + + b.ToTable("vehicle_enrollment_employees", "application"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Aircraft", b => + { + b.HasBaseType("cuqmbr.TravelGuide.Domain.Entities.Vehicle"); + + b.Property("Capacity") + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("smallint") + .HasColumnName("capacity"); + + b.Property("Model") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("varchar(64)") + .HasColumnName("model"); + + b.Property("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("Capacity") + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("smallint") + .HasColumnName("capacity"); + + b.Property("Model") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("varchar(64)") + .HasColumnName("model"); + + b.Property("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("Capacity") + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("smallint") + .HasColumnName("capacity"); + + b.Property("Model") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("varchar(64)") + .HasColumnName("model"); + + b.Property("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.AccountRole", b => + { + b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Account", "Account") + .WithMany("AccountRoles") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_account_roles_account_id"); + + b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Role", "Role") + .WithMany("AccountRoles") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_account_roles_role_id"); + + b.Navigation("Account"); + + b.Navigation("Role"); + }); + + 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.Company", b => + { + b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Account", "Account") + .WithOne("Company") + .HasForeignKey("cuqmbr.TravelGuide.Domain.Entities.Company", "AccountId") + .OnDelete(DeleteBehavior.ClientNoAction) + .IsRequired() + .HasConstraintName("fk_companies_account_id"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Employee", b => + { + b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Account", "Account") + .WithOne("Employee") + .HasForeignKey("cuqmbr.TravelGuide.Domain.Entities.Employee", "AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_employees_account_id"); + + b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Company", "Company") + .WithMany("Employees") + .HasForeignKey("CompanyId") + .OnDelete(DeleteBehavior.ClientNoAction) + .IsRequired() + .HasConstraintName("fk_employees_company_id"); + + b.Navigation("Account"); + + b.Navigation("Company"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.EmployeeDocument", b => + { + b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Employee", "Employee") + .WithMany("Documents") + .HasForeignKey("EmployeeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_employee_documents_employee_id"); + + b.Navigation("Employee"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.RefreshToken", b => + { + b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Account", "Account") + .WithMany("RefreshTokens") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_refresh_tokens_account_id"); + + b.Navigation("Account"); + }); + + 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.Ticket", b => + { + b.HasOne("cuqmbr.TravelGuide.Domain.Entities.RouteAddress", "ArrivalRouteAddress") + .WithMany() + .HasForeignKey("ArrivalRouteAddressId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("cuqmbr.TravelGuide.Domain.Entities.RouteAddress", "DepartureRouteAddress") + .WithMany() + .HasForeignKey("DepartureRouteAddressId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("cuqmbr.TravelGuide.Domain.Entities.TicketGroup", "TicketGroup") + .WithMany("Tickets") + .HasForeignKey("TicketGroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_tickets_ticket_group_id"); + + b.HasOne("cuqmbr.TravelGuide.Domain.Entities.VehicleEnrollment", "VehicleEnrollment") + .WithMany("Tickets") + .HasForeignKey("VehicleEnrollmentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_tickets_vehicle_enrollment_id"); + + b.Navigation("ArrivalRouteAddress"); + + b.Navigation("DepartureRouteAddress"); + + b.Navigation("TicketGroup"); + + b.Navigation("VehicleEnrollment"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.TicketGroup", b => + { + b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Account", "Account") + .WithMany("TicketGroups") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("fk_ticket_groups_account_id"); + + b.Navigation("Account"); + }); + + 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.VehicleEnrollmentEmployee", b => + { + b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Employee", "Employee") + .WithMany("VehicleEnrollmentEmployees") + .HasForeignKey("EmployeeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_vehicle_enrollment_employees_employee_id"); + + b.HasOne("cuqmbr.TravelGuide.Domain.Entities.VehicleEnrollment", "VehicleEnrollment") + .WithMany("VehicleEnrollmentEmployees") + .HasForeignKey("VehicleEnrollmentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired() + .HasConstraintName("fk_vehicle_enrollment_employees_vehicle_enrollment_id"); + + b.Navigation("Employee"); + + b.Navigation("VehicleEnrollment"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Account", b => + { + b.Navigation("AccountRoles"); + + b.Navigation("Company"); + + b.Navigation("Employee"); + + b.Navigation("RefreshTokens"); + + b.Navigation("TicketGroups"); + }); + + 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("Employees"); + + b.Navigation("Vehicles"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Country", b => + { + b.Navigation("Regions"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Employee", b => + { + b.Navigation("Documents"); + + b.Navigation("VehicleEnrollmentEmployees"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Region", b => + { + b.Navigation("Cities"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Role", b => + { + b.Navigation("AccountRoles"); + }); + + 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.TicketGroup", b => + { + b.Navigation("Tickets"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Vehicle", b => + { + b.Navigation("Enrollments"); + }); + + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.VehicleEnrollment", b => + { + b.Navigation("RouteAddressDetails"); + + b.Navigation("Tickets"); + + b.Navigation("VehicleEnrollmentEmployees"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Persistence/PostgreSql/Migrations/20250530101737_Add_navigation_from_Ticket_Group_to_Account.cs b/src/Persistence/PostgreSql/Migrations/20250530101737_Add_navigation_from_Ticket_Group_to_Account.cs new file mode 100644 index 0000000..8959a4b --- /dev/null +++ b/src/Persistence/PostgreSql/Migrations/20250530101737_Add_navigation_from_Ticket_Group_to_Account.cs @@ -0,0 +1,114 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Persistence.PostgreSql.Migrations +{ + /// + public partial class Add_navigation_from_Ticket_Group_to_Account : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "fk_companies_account_id", + schema: "application", + table: "companies"); + + migrationBuilder.DropForeignKey( + name: "fk_employees_company_id", + schema: "application", + table: "employees"); + + migrationBuilder.AddColumn( + name: "account_id", + schema: "application", + table: "ticket_groups", + type: "bigint", + nullable: true); + + migrationBuilder.CreateIndex( + name: "ix_ticket_groups_account_id", + schema: "application", + table: "ticket_groups", + column: "account_id"); + + migrationBuilder.AddForeignKey( + name: "fk_companies_account_id", + schema: "application", + table: "companies", + column: "account_id", + principalSchema: "application", + principalTable: "accounts", + principalColumn: "id"); + + migrationBuilder.AddForeignKey( + name: "fk_employees_company_id", + schema: "application", + table: "employees", + column: "company_id", + principalSchema: "application", + principalTable: "companies", + principalColumn: "id"); + + migrationBuilder.AddForeignKey( + name: "fk_ticket_groups_account_id", + schema: "application", + table: "ticket_groups", + column: "account_id", + principalSchema: "application", + principalTable: "accounts", + principalColumn: "id", + onDelete: ReferentialAction.SetNull); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "fk_companies_account_id", + schema: "application", + table: "companies"); + + migrationBuilder.DropForeignKey( + name: "fk_employees_company_id", + schema: "application", + table: "employees"); + + migrationBuilder.DropForeignKey( + name: "fk_ticket_groups_account_id", + schema: "application", + table: "ticket_groups"); + + migrationBuilder.DropIndex( + name: "ix_ticket_groups_account_id", + schema: "application", + table: "ticket_groups"); + + migrationBuilder.DropColumn( + name: "account_id", + schema: "application", + table: "ticket_groups"); + + migrationBuilder.AddForeignKey( + name: "fk_companies_account_id", + schema: "application", + table: "companies", + column: "account_id", + principalSchema: "application", + principalTable: "accounts", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "fk_employees_company_id", + schema: "application", + table: "employees", + column: "company_id", + principalSchema: "application", + principalTable: "companies", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + } + } +} diff --git a/src/Persistence/PostgreSql/Migrations/PostgreSqlDbContextModelSnapshot.cs b/src/Persistence/PostgreSql/Migrations/PostgreSqlDbContextModelSnapshot.cs index 99901fb..9587b06 100644 --- a/src/Persistence/PostgreSql/Migrations/PostgreSqlDbContextModelSnapshot.cs +++ b/src/Persistence/PostgreSql/Migrations/PostgreSqlDbContextModelSnapshot.cs @@ -729,6 +729,10 @@ namespace Persistence.PostgreSql.Migrations NpgsqlPropertyBuilderExtensions.UseSequence(b.Property("Id"), "ticket_groups_id_sequence"); + b.Property("AccountId") + .HasColumnType("bigint") + .HasColumnName("account_id"); + b.Property("Guid") .HasColumnType("uuid") .HasColumnName("uuid"); @@ -780,6 +784,9 @@ namespace Persistence.PostgreSql.Migrations b.HasAlternateKey("Guid") .HasName("altk_ticket_groups_uuid"); + b.HasIndex("AccountId") + .HasDatabaseName("ix_ticket_groups_account_id"); + b.ToTable("ticket_groups", "application", t => { t.HasCheckConstraint("ck_ticket_groups_passanger_sex", "passanger_sex IN ('male', 'female')"); @@ -1053,7 +1060,7 @@ namespace Persistence.PostgreSql.Migrations b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Account", "Account") .WithOne("Company") .HasForeignKey("cuqmbr.TravelGuide.Domain.Entities.Company", "AccountId") - .OnDelete(DeleteBehavior.Cascade) + .OnDelete(DeleteBehavior.ClientNoAction) .IsRequired() .HasConstraintName("fk_companies_account_id"); @@ -1072,7 +1079,7 @@ namespace Persistence.PostgreSql.Migrations b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Company", "Company") .WithMany("Employees") .HasForeignKey("CompanyId") - .OnDelete(DeleteBehavior.Cascade) + .OnDelete(DeleteBehavior.ClientNoAction) .IsRequired() .HasConstraintName("fk_employees_company_id"); @@ -1196,6 +1203,17 @@ namespace Persistence.PostgreSql.Migrations b.Navigation("VehicleEnrollment"); }); + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.TicketGroup", b => + { + b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Account", "Account") + .WithMany("TicketGroups") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.SetNull) + .HasConstraintName("fk_ticket_groups_account_id"); + + b.Navigation("Account"); + }); + modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Vehicle", b => { b.HasOne("cuqmbr.TravelGuide.Domain.Entities.Company", "Company") @@ -1259,6 +1277,8 @@ namespace Persistence.PostgreSql.Migrations b.Navigation("Employee"); b.Navigation("RefreshTokens"); + + b.Navigation("TicketGroups"); }); modelBuilder.Entity("cuqmbr.TravelGuide.Domain.Entities.Address", b =>