diff --git a/OutOfSchool/OutOfSchool.DataAccess/Models/Configurations/WorkshopConfiguration.cs b/OutOfSchool/OutOfSchool.DataAccess/Models/Configurations/WorkshopConfiguration.cs index 1402e551b6..18f6ba4ea1 100644 --- a/OutOfSchool/OutOfSchool.DataAccess/Models/Configurations/WorkshopConfiguration.cs +++ b/OutOfSchool/OutOfSchool.DataAccess/Models/Configurations/WorkshopConfiguration.cs @@ -28,6 +28,9 @@ public void Configure(EntityTypeBuilder builder) builder.HasMany(x => x.Teachers) .WithOne(x => x.Workshop) .HasForeignKey(x => x.WorkshopId); + builder.HasMany(x => x.WorkshopDescriptionItems) + .WithOne(x => x.Workshop) + .HasForeignKey(x => x.WorkshopId); } } } diff --git a/OutOfSchool/OutOfSchool.DataAccess/Models/Workshop.cs b/OutOfSchool/OutOfSchool.DataAccess/Models/Workshop.cs index 3867cfb589..24c805d4bd 100644 --- a/OutOfSchool/OutOfSchool.DataAccess/Models/Workshop.cs +++ b/OutOfSchool/OutOfSchool.DataAccess/Models/Workshop.cs @@ -60,9 +60,7 @@ public class Workshop : IKeyedEntity, IImageDependentEntity [Range(0, 10000, ErrorMessage = "Field value should be in a range from 1 to 10 000")] public decimal Price { get; set; } = default; - [Required(ErrorMessage = "Description is required")] - [MaxLength(500)] - public string Description { get; set; } = string.Empty; + public virtual ICollection WorkshopDescriptionItems { get; set; } public bool WithDisabilityOptions { get; set; } = default; diff --git a/OutOfSchool/OutOfSchool.DataAccess/Models/WorkshopDescriptionItem.cs b/OutOfSchool/OutOfSchool.DataAccess/Models/WorkshopDescriptionItem.cs new file mode 100644 index 0000000000..b19df22d10 --- /dev/null +++ b/OutOfSchool/OutOfSchool.DataAccess/Models/WorkshopDescriptionItem.cs @@ -0,0 +1,22 @@ +using System; +using System.ComponentModel.DataAnnotations; + +namespace OutOfSchool.Services.Models +{ + public class WorkshopDescriptionItem : IKeyedEntity + { + public Guid Id { get; set; } + + [Required(ErrorMessage = "Description heading is required")] + [MaxLength(200)] + public string SectionName { get; set; } + + [Required(ErrorMessage = "Description text is required")] + [MaxLength(2000)] + public string Description { get; set; } + + public Guid WorkshopId { get; set; } + + public virtual Workshop Workshop { get; set; } + } +} \ No newline at end of file diff --git a/OutOfSchool/OutOfSchool.DataAccess/OutOfSchoolDbContext.cs b/OutOfSchool/OutOfSchool.DataAccess/OutOfSchoolDbContext.cs index c535748c18..a1bbb03c26 100644 --- a/OutOfSchool/OutOfSchool.DataAccess/OutOfSchoolDbContext.cs +++ b/OutOfSchool/OutOfSchool.DataAccess/OutOfSchoolDbContext.cs @@ -86,6 +86,8 @@ public OutOfSchoolDbContext(DbContextOptions options) public DbSet ProviderSectionItems { get; set; } + public DbSet WorkshopDescriptionItems { get; set; } + public DbSet ChangesLog { get; set; } public DbSet ProviderAdminChangesLog { get; set; } diff --git a/OutOfSchool/OutOfSchool.ElasticsearchData/Models/WorkshopES.cs b/OutOfSchool/OutOfSchool.ElasticsearchData/Models/WorkshopES.cs index b08d737f7d..c32055bc16 100644 --- a/OutOfSchool/OutOfSchool.ElasticsearchData/Models/WorkshopES.cs +++ b/OutOfSchool/OutOfSchool.ElasticsearchData/Models/WorkshopES.cs @@ -26,7 +26,7 @@ public class WorkshopES public OwnershipType ProviderOwnership { get; set; } - public string Description { get; set; } + public string Description { get; set; } // Sum of all WorkshopDescriptionItems (SectionName + Description) public int MinAge { get; set; } diff --git a/OutOfSchool/OutOfSchool.IdentityServer/Data/Migrations/OutOfSchoolMigrations/20220620185326_AddressH3Add.Designer.cs b/OutOfSchool/OutOfSchool.IdentityServer/Data/Migrations/OutOfSchoolMigrations/20220620185326_AddressH3Add.Designer.cs new file mode 100644 index 0000000000..49dac8222b --- /dev/null +++ b/OutOfSchool/OutOfSchool.IdentityServer/Data/Migrations/OutOfSchoolMigrations/20220620185326_AddressH3Add.Designer.cs @@ -0,0 +1,2078 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using OutOfSchool.Services; + +namespace OutOfSchool.IdentityServer.Data.Migrations.OutOfSchoolMigrations +{ + [DbContext(typeof(OutOfSchoolDbContext))] + [Migration("20220620185326_AddressH3Add")] + partial class AddressH3Add + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Relational:MaxIdentifierLength", 64) + .HasAnnotation("ProductVersion", "5.0.11"); + + modelBuilder.Entity("DirectionInstitutionHierarchy", b => + { + b.Property("DirectionsId") + .HasColumnType("bigint"); + + b.Property("InstitutionHierarchiesId") + .HasColumnType("binary(16)"); + + b.HasKey("DirectionsId", "InstitutionHierarchiesId"); + + b.HasIndex("InstitutionHierarchiesId"); + + b.ToTable("DirectionInstitutionHierarchy"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.DataProtectionKey", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("FriendlyName") + .HasColumnType("longtext"); + + b.Property("Xml") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("DataProtectionKeys"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("varchar(255)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("longtext"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClaimType") + .HasColumnType("longtext"); + + b.Property("ClaimValue") + .HasColumnType("longtext"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClaimType") + .HasColumnType("longtext"); + + b.Property("ClaimValue") + .HasColumnType("longtext"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("varchar(255)"); + + b.Property("ProviderKey") + .HasColumnType("varchar(255)"); + + b.Property("ProviderDisplayName") + .HasColumnType("longtext"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.Property("RoleId") + .HasColumnType("varchar(255)"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.Property("LoginProvider") + .HasColumnType("varchar(255)"); + + b.Property("Name") + .HasColumnType("varchar(255)"); + + b.Property("Value") + .HasColumnType("longtext"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Address", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("BuildingNumber") + .IsRequired() + .HasMaxLength(15) + .HasColumnType("varchar(15)"); + + b.Property("City") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("varchar(30)"); + + b.Property("District") + .HasMaxLength(30) + .HasColumnType("varchar(30)"); + + b.Property("Latitude") + .HasColumnType("double"); + + b.Property("Longitude") + .HasColumnType("double"); + + b.Property("Region") + .HasMaxLength(30) + .HasColumnType("varchar(30)"); + + b.Property("Street") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("varchar(30)"); + + b.HasKey("Id"); + + b.ToTable("Addresses"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Application", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("binary(16)"); + + b.Property("ApprovedTime") + .HasColumnType("datetime(6)"); + + b.Property("ChildId") + .HasColumnType("binary(16)"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("IsBlocked") + .HasColumnType("tinyint(1)"); + + b.Property("ParentId") + .HasColumnType("binary(16)"); + + b.Property("RejectionMessage") + .HasMaxLength(500) + .HasColumnType("varchar(500)"); + + b.Property("Status") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasDefaultValue(1); + + b.Property("WorkshopId") + .HasColumnType("binary(16)"); + + b.HasKey("Id"); + + b.HasIndex("ChildId"); + + b.HasIndex("ParentId"); + + b.HasIndex("WorkshopId"); + + b.ToTable("Applications"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.BlockedProviderParent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("binary(16)"); + + b.Property("DateTimeFrom") + .HasColumnType("datetime(6)"); + + b.Property("DateTimeTo") + .HasColumnType("datetime(6)"); + + b.Property("ParentId") + .HasColumnType("binary(16)"); + + b.Property("ProviderId") + .HasColumnType("binary(16)"); + + b.Property("Reason") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("varchar(500)"); + + b.Property("UserIdBlock") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("UserIdUnblock") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.HasIndex("ProviderId"); + + b.ToTable("BlockedProviderParents"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.ChangesLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("EntityIdGuid") + .HasColumnType("binary(16)"); + + b.Property("EntityIdLong") + .HasColumnType("bigint"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("varchar(128)"); + + b.Property("NewValue") + .HasMaxLength(500) + .HasColumnType("varchar(500)"); + + b.Property("OldValue") + .HasMaxLength(500) + .HasColumnType("varchar(500)"); + + b.Property("PropertyName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("varchar(128)"); + + b.Property("UpdatedDate") + .HasColumnType("datetime(6)"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("ChangesLog"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.ChatWorkshop.ChatMessageWorkshop", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("binary(16)"); + + b.Property("ChatRoomId") + .HasColumnType("binary(16)"); + + b.Property("CreatedDateTime") + .HasColumnType("datetime(6)"); + + b.Property("ReadDateTime") + .HasColumnType("datetime(6)"); + + b.Property("SenderRoleIsProvider") + .HasColumnType("tinyint(1)"); + + b.Property("Text") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.HasKey("Id"); + + b.HasIndex("ChatRoomId"); + + b.ToTable("ChatMessageWorkshops"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.ChatWorkshop.ChatRoomWorkshop", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("binary(16)"); + + b.Property("IsBlocked") + .HasColumnType("tinyint(1)"); + + b.Property("ParentId") + .HasColumnType("binary(16)"); + + b.Property("WorkshopId") + .HasColumnType("binary(16)"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.HasIndex("WorkshopId"); + + b.ToTable("ChatRoomWorkshops"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Child", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("binary(16)"); + + b.Property("DateOfBirth") + .HasColumnType("date"); + + b.Property("FirstName") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("varchar(30)"); + + b.Property("Gender") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasDefaultValue(0); + + b.Property("LastName") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("varchar(30)"); + + b.Property("MiddleName") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("varchar(30)"); + + b.Property("ParentId") + .HasColumnType("binary(16)"); + + b.Property("PlaceOfStudy") + .HasMaxLength(500) + .HasColumnType("varchar(500)"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("Children"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.ChildSocialGroup", b => + { + b.Property("ChildId") + .HasColumnType("binary(16)"); + + b.Property("SocialGroupId") + .HasColumnType("bigint"); + + b.HasKey("ChildId", "SocialGroupId"); + + b.HasIndex("SocialGroupId"); + + b.ToTable("ChildrenSocialGroups"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.City", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("District") + .HasMaxLength(30) + .HasColumnType("varchar(30)"); + + b.Property("GeoHash") + .HasColumnType("bigint unsigned"); + + b.Property("Latitude") + .HasColumnType("double"); + + b.Property("Longitude") + .HasColumnType("double"); + + b.Property("Name") + .HasMaxLength(30) + .HasColumnType("varchar(30)"); + + b.Property("Region") + .HasMaxLength(30) + .HasColumnType("varchar(30)"); + + b.HasKey("Id"); + + b.ToTable("Cities"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Class", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("DepartmentId") + .HasColumnType("bigint"); + + b.Property("Description") + .HasMaxLength(500) + .HasColumnType("varchar(500)"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(150) + .HasColumnType("varchar(150)"); + + b.HasKey("Id"); + + b.HasIndex("DepartmentId"); + + b.ToTable("Classes"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Codeficator", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("Category") + .HasMaxLength(3) + .HasColumnType("varchar(3)"); + + b.Property("Code") + .HasMaxLength(20) + .HasColumnType("varchar(20)"); + + b.Property("GeoHash") + .HasColumnType("bigint unsigned"); + + b.Property("Latitude") + .HasColumnType("double"); + + b.Property("Longitude") + .HasColumnType("double"); + + b.Property("Name") + .HasMaxLength(30) + .HasColumnType("varchar(30)"); + + b.Property("NeedCheck") + .HasColumnType("tinyint(1)"); + + b.Property("ParentId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("Codeficators"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.CompanyInformation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("binary(16)"); + + b.Property("Title") + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.Property("Type") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("CompanyInformation"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.CompanyInformationItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("binary(16)"); + + b.Property("CompanyInformationId") + .HasColumnType("binary(16)"); + + b.Property("Description") + .HasMaxLength(2000) + .HasColumnType("varchar(2000)"); + + b.Property("SectionName") + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.HasKey("Id"); + + b.HasIndex("CompanyInformationId"); + + b.ToTable("CompanyInformationItems"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.DateTimeRange", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("EndTime") + .HasColumnType("time(6)"); + + b.Property("StartTime") + .HasColumnType("time(6)"); + + b.Property("Workdays") + .HasColumnType("tinyint unsigned"); + + b.Property("WorkshopId") + .HasColumnType("binary(16)"); + + b.HasKey("Id"); + + b.HasIndex("WorkshopId"); + + b.ToTable("DateTimeRanges"); + + b.HasCheckConstraint("CK_DateTimeRanges_EndTimeIsAfterStartTime", "EndTime >= StartTime"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Department", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("Description") + .HasMaxLength(500) + .HasColumnType("varchar(500)"); + + b.Property("DirectionId") + .HasColumnType("bigint"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(150) + .HasColumnType("varchar(150)"); + + b.HasKey("Id"); + + b.HasIndex("DirectionId"); + + b.ToTable("Departments"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Direction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("Description") + .HasMaxLength(500) + .HasColumnType("varchar(500)"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("varchar(100)"); + + b.HasKey("Id"); + + b.ToTable("Directions"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.ElasticsearchSyncRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("binary(16)"); + + b.Property("Entity") + .HasColumnType("int"); + + b.Property("Operation") + .HasColumnType("int"); + + b.Property("OperationDate") + .HasColumnType("datetime(6)"); + + b.Property("RecordId") + .HasColumnType("binary(16)"); + + b.HasKey("Id"); + + b.ToTable("ElasticsearchSyncRecords"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Favorite", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.Property("WorkshopId") + .HasColumnType("binary(16)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.HasIndex("WorkshopId"); + + b.ToTable("Favorites"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Images.Image", b => + { + b.Property("EntityId") + .HasColumnType("binary(16)"); + + b.Property("ExternalStorageId") + .HasColumnType("varchar(255)"); + + b.HasKey("EntityId", "ExternalStorageId"); + + b.ToTable("ProviderImages"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Images.Image", b => + { + b.Property("EntityId") + .HasColumnType("binary(16)"); + + b.Property("ExternalStorageId") + .HasColumnType("varchar(255)"); + + b.HasKey("EntityId", "ExternalStorageId"); + + b.ToTable("WorkshopImages"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.InstitutionStatus", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("Name") + .HasMaxLength(100) + .HasColumnType("varchar(100)"); + + b.HasKey("Id"); + + b.ToTable("InstitutionStatuses"); + + b.HasData( + new + { + Id = 1L, + Name = "Працює" + }, + new + { + Id = 2L, + Name = "Перебуває в стані реорганізації" + }, + new + { + Id = 3L, + Name = "Має намір на реорганізацію" + }); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Notification", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("binary(16)"); + + b.Property("Action") + .HasColumnType("int"); + + b.Property("CreatedDateTime") + .HasColumnType("datetime(6)"); + + b.Property("Data") + .HasColumnType("longtext"); + + b.Property("GroupedData") + .HasColumnType("longtext"); + + b.Property("ObjectId") + .HasColumnType("binary(16)"); + + b.Property("ReadDateTime") + .HasColumnType("datetime(6)"); + + b.Property("Type") + .HasColumnType("int"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("Notifications"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Parent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("binary(16)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Parents"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.PermissionsForRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("Description") + .HasMaxLength(100) + .HasColumnType("varchar(100)"); + + b.Property("PackedPermissions") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("RoleName") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("varchar(20)"); + + b.HasKey("Id"); + + b.ToTable("PermissionsForRoles"); + + b.HasData( + new + { + Id = 1L, + Description = "admin permissions", + PackedPermissions = "de\n \r  !()+4325>== + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("binary(16)"); + + b.Property("ActualAddressId") + .HasColumnType("bigint"); + + b.Property("CoverImageId") + .HasColumnType("longtext"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(500) + .IsUnicode(true) + .HasColumnType("varchar(500)"); + + b.Property("Director") + .HasMaxLength(50) + .IsUnicode(true) + .HasColumnType("varchar(50)"); + + b.Property("DirectorDateOfBirth") + .HasColumnType("Date"); + + b.Property("EdrpouIpn") + .HasMaxLength(12) + .HasColumnType("bigint"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("Facebook") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("Founder") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("varchar(30)"); + + b.Property("FullTitle") + .IsRequired() + .HasMaxLength(60) + .IsUnicode(true) + .HasColumnType("varchar(60)"); + + b.Property("Instagram") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("InstitutionId") + .HasColumnType("binary(16)"); + + b.Property("InstitutionStatusId") + .HasColumnType("bigint"); + + b.Property("InstitutionType") + .HasColumnType("int"); + + b.Property("LegalAddressId") + .HasColumnType("bigint"); + + b.Property("Ownership") + .HasColumnType("int"); + + b.Property("PhoneNumber") + .HasMaxLength(15) + .HasColumnType("varchar(15)"); + + b.Property("ShortTitle") + .IsRequired() + .HasMaxLength(60) + .IsUnicode(true) + .HasColumnType("varchar(60)"); + + b.Property("Status") + .HasColumnType("tinyint(1)"); + + b.Property("Type") + .HasColumnType("int"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.Property("Website") + .HasMaxLength(256) + .IsUnicode(true) + .HasColumnType("varchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("ActualAddressId"); + + b.HasIndex("InstitutionId"); + + b.HasIndex("InstitutionStatusId"); + + b.HasIndex("LegalAddressId"); + + b.HasIndex("UserId"); + + b.ToTable("Providers"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.ProviderAdmin", b => + { + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.Property("IsDeputy") + .HasColumnType("tinyint(1)"); + + b.Property("ProviderId") + .HasColumnType("binary(16)"); + + b.HasKey("UserId"); + + b.HasIndex("ProviderId"); + + b.ToTable("ProviderAdmins"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.ProviderAdminChangesLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("ManagedWorkshopId") + .HasColumnType("binary(16)"); + + b.Property("OperationDate") + .HasColumnType("datetime(6)"); + + b.Property("OperationType") + .HasColumnType("int"); + + b.Property("ProviderAdminUserId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.Property("ProviderId") + .HasColumnType("binary(16)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("ManagedWorkshopId"); + + b.HasIndex("ProviderAdminUserId"); + + b.HasIndex("ProviderId"); + + b.HasIndex("UserId"); + + b.ToTable("ProviderAdminChangesLog"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.ProviderSectionItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("binary(16)"); + + b.Property("Description") + .HasMaxLength(2000) + .HasColumnType("varchar(2000)"); + + b.Property("Name") + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.Property("ProviderId") + .HasColumnType("binary(16)"); + + b.HasKey("Id"); + + b.HasIndex("ProviderId"); + + b.ToTable("ProviderSectionItems"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Rating", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("CreationTime") + .HasColumnType("datetime(6)"); + + b.Property("EntityId") + .HasColumnType("binary(16)"); + + b.Property("ParentId") + .HasColumnType("binary(16)"); + + b.Property("Rate") + .HasColumnType("int"); + + b.Property("Type") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("Ratings"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.SocialGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("Name") + .HasMaxLength(100) + .HasColumnType("varchar(100)"); + + b.HasKey("Id"); + + b.ToTable("SocialGroups"); + + b.HasData( + new + { + Id = 1L, + Name = "Діти із багатодітних сімей" + }, + new + { + Id = 2L, + Name = "Діти із малозабезпечених сімей" + }, + new + { + Id = 3L, + Name = "Діти з інвалідністю" + }, + new + { + Id = 4L, + Name = "Діти-сироти" + }, + new + { + Id = 5L, + Name = "Діти, позбавлені батьківського піклування" + }); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.SubordinationStructure.Institution", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("binary(16)"); + + b.Property("NumberOfHierarchyLevels") + .HasColumnType("int"); + + b.Property("Title") + .HasMaxLength(100) + .HasColumnType("varchar(100)"); + + b.HasKey("Id"); + + b.ToTable("Institutions"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.SubordinationStructure.InstitutionFieldDescription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("binary(16)"); + + b.Property("HierarchyLevel") + .HasColumnType("int"); + + b.Property("InstitutionId") + .HasColumnType("binary(16)"); + + b.Property("Title") + .HasMaxLength(100) + .HasColumnType("varchar(100)"); + + b.HasKey("Id"); + + b.HasIndex("InstitutionId"); + + b.ToTable("InstitutionFieldDescriptions"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.SubordinationStructure.InstitutionHierarchy", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("binary(16)"); + + b.Property("HierarchyLevel") + .HasColumnType("int"); + + b.Property("InstitutionId") + .HasColumnType("binary(16)"); + + b.Property("ParentId") + .HasColumnType("binary(16)"); + + b.Property("Title") + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.HasKey("Id"); + + b.HasIndex("InstitutionId"); + + b.HasIndex("ParentId"); + + b.ToTable("InstitutionHierarchies"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Teacher", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("binary(16)"); + + b.Property("CoverImageId") + .HasColumnType("longtext"); + + b.Property("DateOfBirth") + .HasColumnType("date"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(300) + .HasColumnType("varchar(300)"); + + b.Property("FirstName") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("varchar(30)"); + + b.Property("Gender") + .HasColumnType("int"); + + b.Property("LastName") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("varchar(30)"); + + b.Property("MiddleName") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("varchar(30)"); + + b.Property("WorkshopId") + .HasColumnType("binary(16)"); + + b.HasKey("Id"); + + b.HasIndex("WorkshopId"); + + b.ToTable("Teachers"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.User", b => + { + b.Property("Id") + .HasColumnType("varchar(255)"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("longtext"); + + b.Property("CreatingTime") + .HasColumnType("datetime(6)"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("tinyint(1)"); + + b.Property("FirstName") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("varchar(30)"); + + b.Property("Gender") + .HasColumnType("int"); + + b.Property("IsBlocked") + .HasColumnType("tinyint(1)"); + + b.Property("IsDerived") + .HasColumnType("tinyint(1)"); + + b.Property("IsRegistered") + .HasColumnType("tinyint(1)"); + + b.Property("LastLogin") + .HasColumnType("datetime(6)"); + + b.Property("LastName") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("varchar(30)"); + + b.Property("LockoutEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("LockoutEnd") + .HasColumnType("datetime(6)"); + + b.Property("MiddleName") + .HasMaxLength(30) + .HasColumnType("varchar(30)"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("PasswordHash") + .HasMaxLength(84) + .IsUnicode(false) + .HasColumnType("char(84)") + .IsFixedLength(true); + + b.Property("PhoneNumber") + .HasMaxLength(15) + .IsUnicode(false) + .HasColumnType("varchar(15)") + .IsFixedLength(false); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("tinyint(1)"); + + b.Property("Role") + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.Property("SecurityStamp") + .IsRequired() + .HasMaxLength(36) + .IsUnicode(false) + .HasColumnType("varchar(36)") + .IsFixedLength(false); + + b.Property("TwoFactorEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Workshop", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("binary(16)"); + + b.Property("AddressId") + .HasColumnType("bigint"); + + b.Property("ClassId") + .HasColumnType("bigint"); + + b.Property("CoverImageId") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("DepartmentId") + .HasColumnType("bigint"); + + b.Property("DirectionId") + .HasColumnType("bigint"); + + b.Property("DisabilityOptionsDesc") + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("Facebook") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("Instagram") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("InstitutionHierarchyId") + .HasColumnType("binary(16)"); + + b.Property("IsPerMonth") + .HasColumnType("tinyint(1)"); + + b.Property("Keywords") + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.Property("MaxAge") + .HasColumnType("int"); + + b.Property("MinAge") + .HasColumnType("int"); + + b.Property("Phone") + .IsRequired() + .HasMaxLength(15) + .HasColumnType("varchar(15)"); + + b.Property("Price") + .HasColumnType("decimal(18,2)"); + + b.Property("ProviderId") + .HasColumnType("binary(16)"); + + b.Property("ProviderOwnership") + .HasColumnType("int"); + + b.Property("ProviderTitle") + .IsRequired() + .HasMaxLength(60) + .HasColumnType("varchar(60)"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(60) + .HasColumnType("varchar(60)"); + + b.Property("Website") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("WithDisabilityOptions") + .HasColumnType("tinyint(1)"); + + b.HasKey("Id"); + + b.HasIndex("AddressId"); + + b.HasIndex("ClassId"); + + b.HasIndex("DirectionId"); + + b.HasIndex("InstitutionHierarchyId"); + + b.HasIndex("ProviderId"); + + b.ToTable("Workshops"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.WorkshopDescriptionItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("binary(16)"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(2000) + .HasColumnType("varchar(2000)"); + + b.Property("SectionName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.Property("WorkshopId") + .HasColumnType("binary(16)"); + + b.HasKey("Id"); + + b.HasIndex("WorkshopId"); + + b.ToTable("WorkshopDescriptionItems"); + }); + + modelBuilder.Entity("ProviderAdminWorkshop", b => + { + b.Property("ManagedWorkshopsId") + .HasColumnType("binary(16)"); + + b.Property("ProviderAdminsUserId") + .HasColumnType("varchar(255)"); + + b.HasKey("ManagedWorkshopsId", "ProviderAdminsUserId"); + + b.HasIndex("ProviderAdminsUserId"); + + b.ToTable("ProviderAdminWorkshop"); + }); + + modelBuilder.Entity("DirectionInstitutionHierarchy", b => + { + b.HasOne("OutOfSchool.Services.Models.Direction", null) + .WithMany() + .HasForeignKey("DirectionsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("OutOfSchool.Services.Models.SubordinationStructure.InstitutionHierarchy", null) + .WithMany() + .HasForeignKey("InstitutionHierarchiesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("OutOfSchool.Services.Models.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("OutOfSchool.Services.Models.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("OutOfSchool.Services.Models.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("OutOfSchool.Services.Models.User", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Application", b => + { + b.HasOne("OutOfSchool.Services.Models.Child", "Child") + .WithMany() + .HasForeignKey("ChildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("OutOfSchool.Services.Models.Parent", "Parent") + .WithMany() + .HasForeignKey("ParentId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("OutOfSchool.Services.Models.Workshop", "Workshop") + .WithMany("Applications") + .HasForeignKey("WorkshopId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Child"); + + b.Navigation("Parent"); + + b.Navigation("Workshop"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.BlockedProviderParent", b => + { + b.HasOne("OutOfSchool.Services.Models.Parent", "Parent") + .WithMany() + .HasForeignKey("ParentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("OutOfSchool.Services.Models.Provider", "Provider") + .WithMany() + .HasForeignKey("ProviderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Parent"); + + b.Navigation("Provider"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.ChangesLog", b => + { + b.HasOne("OutOfSchool.Services.Models.User", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.ChatWorkshop.ChatMessageWorkshop", b => + { + b.HasOne("OutOfSchool.Services.Models.ChatWorkshop.ChatRoomWorkshop", "ChatRoom") + .WithMany("ChatMessages") + .HasForeignKey("ChatRoomId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ChatRoom"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.ChatWorkshop.ChatRoomWorkshop", b => + { + b.HasOne("OutOfSchool.Services.Models.Parent", "Parent") + .WithMany("ChatRooms") + .HasForeignKey("ParentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("OutOfSchool.Services.Models.Workshop", "Workshop") + .WithMany("ChatRooms") + .HasForeignKey("WorkshopId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Parent"); + + b.Navigation("Workshop"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Child", b => + { + b.HasOne("OutOfSchool.Services.Models.Parent", "Parent") + .WithMany("Children") + .HasForeignKey("ParentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Parent"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.ChildSocialGroup", b => + { + b.HasOne("OutOfSchool.Services.Models.Child", "Child") + .WithMany("ChildSocialGroups") + .HasForeignKey("ChildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("OutOfSchool.Services.Models.SocialGroup", "SocialGroup") + .WithMany("ChildSocialGroups") + .HasForeignKey("SocialGroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Child"); + + b.Navigation("SocialGroup"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Class", b => + { + b.HasOne("OutOfSchool.Services.Models.Department", "Department") + .WithMany("Classes") + .HasForeignKey("DepartmentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Department"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Codeficator", b => + { + b.HasOne("OutOfSchool.Services.Models.Codeficator", "Parent") + .WithMany("Childs") + .HasForeignKey("ParentId"); + + b.Navigation("Parent"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.CompanyInformationItem", b => + { + b.HasOne("OutOfSchool.Services.Models.CompanyInformation", "CompanyInformation") + .WithMany("CompanyInformationItems") + .HasForeignKey("CompanyInformationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CompanyInformation"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.DateTimeRange", b => + { + b.HasOne("OutOfSchool.Services.Models.Workshop", null) + .WithMany("DateTimeRanges") + .HasForeignKey("WorkshopId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Department", b => + { + b.HasOne("OutOfSchool.Services.Models.Direction", "Direction") + .WithMany("Departments") + .HasForeignKey("DirectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Direction"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Favorite", b => + { + b.HasOne("OutOfSchool.Services.Models.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("OutOfSchool.Services.Models.Workshop", "Workshop") + .WithMany() + .HasForeignKey("WorkshopId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + + b.Navigation("Workshop"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Images.Image", b => + { + b.HasOne("OutOfSchool.Services.Models.Provider", "Entity") + .WithMany("Images") + .HasForeignKey("EntityId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Entity"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Images.Image", b => + { + b.HasOne("OutOfSchool.Services.Models.Workshop", "Entity") + .WithMany("Images") + .HasForeignKey("EntityId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Entity"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Parent", b => + { + b.HasOne("OutOfSchool.Services.Models.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Provider", b => + { + b.HasOne("OutOfSchool.Services.Models.Address", "ActualAddress") + .WithMany() + .HasForeignKey("ActualAddressId"); + + b.HasOne("OutOfSchool.Services.Models.SubordinationStructure.Institution", "Institution") + .WithMany() + .HasForeignKey("InstitutionId"); + + b.HasOne("OutOfSchool.Services.Models.InstitutionStatus", "InstitutionStatus") + .WithMany("Providers") + .HasForeignKey("InstitutionStatusId"); + + b.HasOne("OutOfSchool.Services.Models.Address", "LegalAddress") + .WithMany() + .HasForeignKey("LegalAddressId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("OutOfSchool.Services.Models.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ActualAddress"); + + b.Navigation("Institution"); + + b.Navigation("InstitutionStatus"); + + b.Navigation("LegalAddress"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.ProviderAdmin", b => + { + b.HasOne("OutOfSchool.Services.Models.Provider", "Provider") + .WithMany("ProviderAdmins") + .HasForeignKey("ProviderId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.Navigation("Provider"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.ProviderAdminChangesLog", b => + { + b.HasOne("OutOfSchool.Services.Models.Workshop", "ManagedWorkshop") + .WithMany() + .HasForeignKey("ManagedWorkshopId"); + + b.HasOne("OutOfSchool.Services.Models.User", "ProviderAdminUser") + .WithMany() + .HasForeignKey("ProviderAdminUserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("OutOfSchool.Services.Models.Provider", "Provider") + .WithMany() + .HasForeignKey("ProviderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("OutOfSchool.Services.Models.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ManagedWorkshop"); + + b.Navigation("Provider"); + + b.Navigation("ProviderAdminUser"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.ProviderSectionItem", b => + { + b.HasOne("OutOfSchool.Services.Models.Provider", "Provider") + .WithMany("ProviderSectionItems") + .HasForeignKey("ProviderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Provider"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Rating", b => + { + b.HasOne("OutOfSchool.Services.Models.Parent", "Parent") + .WithMany() + .HasForeignKey("ParentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Parent"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.SubordinationStructure.InstitutionFieldDescription", b => + { + b.HasOne("OutOfSchool.Services.Models.SubordinationStructure.Institution", "Institution") + .WithMany() + .HasForeignKey("InstitutionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Institution"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.SubordinationStructure.InstitutionHierarchy", b => + { + b.HasOne("OutOfSchool.Services.Models.SubordinationStructure.Institution", "Institution") + .WithMany() + .HasForeignKey("InstitutionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("OutOfSchool.Services.Models.SubordinationStructure.InstitutionHierarchy", "Parent") + .WithMany() + .HasForeignKey("ParentId"); + + b.Navigation("Institution"); + + b.Navigation("Parent"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Teacher", b => + { + b.HasOne("OutOfSchool.Services.Models.Workshop", "Workshop") + .WithMany("Teachers") + .HasForeignKey("WorkshopId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Workshop"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Workshop", b => + { + b.HasOne("OutOfSchool.Services.Models.Address", "Address") + .WithMany() + .HasForeignKey("AddressId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("OutOfSchool.Services.Models.Class", "Class") + .WithMany() + .HasForeignKey("ClassId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("OutOfSchool.Services.Models.Direction", "Direction") + .WithMany() + .HasForeignKey("DirectionId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("OutOfSchool.Services.Models.SubordinationStructure.InstitutionHierarchy", "InstitutionHierarchy") + .WithMany() + .HasForeignKey("InstitutionHierarchyId"); + + b.HasOne("OutOfSchool.Services.Models.Provider", "Provider") + .WithMany("Workshops") + .HasForeignKey("ProviderId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.Navigation("Address"); + + b.Navigation("Class"); + + b.Navigation("Direction"); + + b.Navigation("InstitutionHierarchy"); + + b.Navigation("Provider"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.WorkshopDescriptionItem", b => + { + b.HasOne("OutOfSchool.Services.Models.Workshop", "Workshop") + .WithMany("WorkshopDescriptionItems") + .HasForeignKey("WorkshopId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Workshop"); + }); + + modelBuilder.Entity("ProviderAdminWorkshop", b => + { + b.HasOne("OutOfSchool.Services.Models.Workshop", null) + .WithMany() + .HasForeignKey("ManagedWorkshopsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("OutOfSchool.Services.Models.ProviderAdmin", null) + .WithMany() + .HasForeignKey("ProviderAdminsUserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.ChatWorkshop.ChatRoomWorkshop", b => + { + b.Navigation("ChatMessages"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Child", b => + { + b.Navigation("ChildSocialGroups"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Codeficator", b => + { + b.Navigation("Childs"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.CompanyInformation", b => + { + b.Navigation("CompanyInformationItems"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Department", b => + { + b.Navigation("Classes"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Direction", b => + { + b.Navigation("Departments"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.InstitutionStatus", b => + { + b.Navigation("Providers"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Parent", b => + { + b.Navigation("ChatRooms"); + + b.Navigation("Children"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Provider", b => + { + b.Navigation("Images"); + + b.Navigation("ProviderAdmins"); + + b.Navigation("ProviderSectionItems"); + + b.Navigation("Workshops"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.SocialGroup", b => + { + b.Navigation("ChildSocialGroups"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Workshop", b => + { + b.Navigation("Applications"); + + b.Navigation("ChatRooms"); + + b.Navigation("DateTimeRanges"); + + b.Navigation("Images"); + + b.Navigation("Teachers"); + + b.Navigation("WorkshopDescriptionItems"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/OutOfSchool/OutOfSchool.IdentityServer/Data/Migrations/OutOfSchoolMigrations/20220620185326_AddressH3Add.cs b/OutOfSchool/OutOfSchool.IdentityServer/Data/Migrations/OutOfSchoolMigrations/20220620185326_AddressH3Add.cs new file mode 100644 index 0000000000..599add6e53 --- /dev/null +++ b/OutOfSchool/OutOfSchool.IdentityServer/Data/Migrations/OutOfSchoolMigrations/20220620185326_AddressH3Add.cs @@ -0,0 +1,58 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace OutOfSchool.IdentityServer.Data.Migrations.OutOfSchoolMigrations +{ + public partial class AddressH3Add : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Description", + table: "Workshops"); + + migrationBuilder.CreateTable( + name: "WorkshopDescriptionItems", + columns: table => new + { + Id = table.Column(type: "binary(16)", nullable: false), + SectionName = table.Column(type: "varchar(200)", maxLength: 200, nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + Description = table.Column(type: "varchar(2000)", maxLength: 2000, nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + WorkshopId = table.Column(type: "binary(16)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_WorkshopDescriptionItems", x => x.Id); + table.ForeignKey( + name: "FK_WorkshopDescriptionItems_Workshops_WorkshopId", + column: x => x.WorkshopId, + principalTable: "Workshops", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateIndex( + name: "IX_WorkshopDescriptionItems_WorkshopId", + table: "WorkshopDescriptionItems", + column: "WorkshopId"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "WorkshopDescriptionItems"); + + migrationBuilder.AddColumn( + name: "Description", + table: "Workshops", + type: "varchar(500)", + maxLength: 500, + nullable: false, + defaultValue: "") + .Annotation("MySql:CharSet", "utf8mb4"); + } + } +} diff --git a/OutOfSchool/OutOfSchool.IdentityServer/Data/Migrations/OutOfSchoolMigrations/OutOfSchoolDbContextModelSnapshot.cs b/OutOfSchool/OutOfSchool.IdentityServer/Data/Migrations/OutOfSchoolMigrations/OutOfSchoolDbContextModelSnapshot.cs index 68dd739cdf..4867561f82 100644 --- a/OutOfSchool/OutOfSchool.IdentityServer/Data/Migrations/OutOfSchoolMigrations/OutOfSchoolDbContextModelSnapshot.cs +++ b/OutOfSchool/OutOfSchool.IdentityServer/Data/Migrations/OutOfSchoolMigrations/OutOfSchoolDbContextModelSnapshot.cs @@ -1379,11 +1379,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("DepartmentId") .HasColumnType("bigint"); - b.Property("Description") - .IsRequired() - .HasMaxLength(500) - .HasColumnType("varchar(500)"); - b.Property("DirectionId") .HasColumnType("bigint"); @@ -1469,6 +1464,32 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("Workshops"); }); + modelBuilder.Entity("OutOfSchool.Services.Models.WorkshopDescriptionItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("binary(16)"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(2000) + .HasColumnType("varchar(2000)"); + + b.Property("SectionName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.Property("WorkshopId") + .HasColumnType("binary(16)"); + + b.HasKey("Id"); + + b.HasIndex("WorkshopId"); + + b.ToTable("WorkshopDescriptionItems"); + }); + modelBuilder.Entity("ProviderAdminWorkshop", b => { b.Property("ManagedWorkshopsId") @@ -1951,6 +1972,17 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Navigation("Provider"); }); + modelBuilder.Entity("OutOfSchool.Services.Models.WorkshopDescriptionItem", b => + { + b.HasOne("OutOfSchool.Services.Models.Workshop", "Workshop") + .WithMany("WorkshopDescriptionItems") + .HasForeignKey("WorkshopId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Workshop"); + }); + modelBuilder.Entity("ProviderAdminWorkshop", b => { b.HasOne("OutOfSchool.Services.Models.Workshop", null) @@ -2035,6 +2067,8 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Navigation("Images"); b.Navigation("Teachers"); + + b.Navigation("WorkshopDescriptionItems"); }); #pragma warning restore 612, 618 } diff --git a/OutOfSchool/OutOfSchool.WebApi.Tests/Controllers/ApplicationControllerTests.cs b/OutOfSchool/OutOfSchool.WebApi.Tests/Controllers/ApplicationControllerTests.cs index 26632b7959..5cbfdfb4a5 100644 --- a/OutOfSchool/OutOfSchool.WebApi.Tests/Controllers/ApplicationControllerTests.cs +++ b/OutOfSchool/OutOfSchool.WebApi.Tests/Controllers/ApplicationControllerTests.cs @@ -14,6 +14,7 @@ using OutOfSchool.WebApi.Controllers.V1; using OutOfSchool.WebApi.Extensions; using OutOfSchool.WebApi.Models; +using OutOfSchool.WebApi.Models.Workshop; using OutOfSchool.WebApi.Services; @@ -536,7 +537,12 @@ private WorkshopDTO FakeWorkshop() Id = Guid.NewGuid(), Title = "Title6", Phone = "1111111111", - Description = "Desc6", + WorkshopDescriptionItems = new[] + { + FakeWorkshopDescriptionItem(), + FakeWorkshopDescriptionItem(), + FakeWorkshopDescriptionItem(), + }, Price = 6000, WithDisabilityOptions = true, ProviderTitle = "ProviderTitle", @@ -601,7 +607,11 @@ private List FakeWorkshops() Id = Guid.NewGuid(), Title = "Title1", Phone = "1111111111", - Description = "Desc1", + WorkshopDescriptionItems = new[] + { + FakeWorkshopDescriptionItem(), + FakeWorkshopDescriptionItem(), + }, Price = 1000, WithDisabilityOptions = true, ProviderId = Guid.NewGuid(), @@ -627,7 +637,10 @@ private List FakeWorkshops() Id = Guid.NewGuid(), Title = "Title2", Phone = "1111111111", - Description = "Desc2", + WorkshopDescriptionItems = new[] + { + FakeWorkshopDescriptionItem(), + }, Price = 2000, WithDisabilityOptions = true, ProviderId = Guid.NewGuid(), @@ -653,7 +666,12 @@ private List FakeWorkshops() Id = Guid.NewGuid(), Title = "Title3", Phone = "1111111111", - Description = "Desc3", + WorkshopDescriptionItems = new[] + { + FakeWorkshopDescriptionItem(), + FakeWorkshopDescriptionItem(), + FakeWorkshopDescriptionItem(), + }, Price = 3000, WithDisabilityOptions = true, ProviderId = Guid.NewGuid(), @@ -675,7 +693,11 @@ private List FakeWorkshops() Id = Guid.NewGuid(), Title = "Title4", Phone = "1111111111", - Description = "Desc4", + WorkshopDescriptionItems = new[] + { + FakeWorkshopDescriptionItem(), + FakeWorkshopDescriptionItem(), + }, Price = 4000, WithDisabilityOptions = true, ProviderId = Guid.NewGuid(), @@ -697,7 +719,10 @@ private List FakeWorkshops() Id = Guid.NewGuid(), Title = "Title5", Phone = "1111111111", - Description = "Desc5", + WorkshopDescriptionItems = new[] + { + FakeWorkshopDescriptionItem(), + }, Price = 5000, WithDisabilityOptions = true, ProviderId = Guid.NewGuid(), @@ -732,5 +757,16 @@ private List FakeWorkshopCards() return eSlist; } + + private WorkshopDescriptionItemDto FakeWorkshopDescriptionItem() + { + var id = Guid.NewGuid(); + return new WorkshopDescriptionItemDto + { + Id = id, + SectionName = "test heading", + Description = $"test description text sentence for id: {id.ToString()}", + }; + } } } diff --git a/OutOfSchool/OutOfSchool.WebApi.Tests/Controllers/WorkshopControllerTests.cs b/OutOfSchool/OutOfSchool.WebApi.Tests/Controllers/WorkshopControllerTests.cs index 7398a3db7e..d8ebe37df6 100644 --- a/OutOfSchool/OutOfSchool.WebApi.Tests/Controllers/WorkshopControllerTests.cs +++ b/OutOfSchool/OutOfSchool.WebApi.Tests/Controllers/WorkshopControllerTests.cs @@ -406,7 +406,11 @@ private WorkshopDTO FakeWorkshop() Id = Guid.NewGuid(), Title = "Title6", Phone = "1111111111", - Description = "Desc6", + WorkshopDescriptionItems = new[] + { + FakeWorkshopDescriptionItem(), + FakeWorkshopDescriptionItem(), + }, Price = 6000, WithDisabilityOptions = true, ProviderTitle = "ProviderTitle", @@ -471,7 +475,10 @@ private List FakeWorkshops() Id = Guid.NewGuid(), Title = "Title1", Phone = "1111111111", - Description = "Desc1", + WorkshopDescriptionItems = new[] + { + FakeWorkshopDescriptionItem(), + }, Price = 1000, WithDisabilityOptions = true, ProviderId = Guid.NewGuid(), @@ -497,7 +504,12 @@ private List FakeWorkshops() Id = Guid.NewGuid(), Title = "Title2", Phone = "1111111111", - Description = "Desc2", + WorkshopDescriptionItems = new[] + { + FakeWorkshopDescriptionItem(), + FakeWorkshopDescriptionItem(), + FakeWorkshopDescriptionItem(), + }, Price = 2000, WithDisabilityOptions = true, ProviderId = Guid.NewGuid(), @@ -523,7 +535,12 @@ private List FakeWorkshops() Id = Guid.NewGuid(), Title = "Title3", Phone = "1111111111", - Description = "Desc3", + WorkshopDescriptionItems = new[] + { + FakeWorkshopDescriptionItem(), + FakeWorkshopDescriptionItem(), + FakeWorkshopDescriptionItem(), + }, Price = 3000, WithDisabilityOptions = true, ProviderId = Guid.NewGuid(), @@ -545,7 +562,11 @@ private List FakeWorkshops() Id = Guid.NewGuid(), Title = "Title4", Phone = "1111111111", - Description = "Desc4", + WorkshopDescriptionItems = new[] + { + FakeWorkshopDescriptionItem(), + FakeWorkshopDescriptionItem(), + }, Price = 4000, WithDisabilityOptions = true, ProviderId = Guid.NewGuid(), @@ -567,7 +588,10 @@ private List FakeWorkshops() Id = Guid.NewGuid(), Title = "Title5", Phone = "1111111111", - Description = "Desc5", + WorkshopDescriptionItems = new[] + { + FakeWorkshopDescriptionItem(), + }, Price = 5000, WithDisabilityOptions = true, ProviderId = Guid.NewGuid(), @@ -611,5 +635,16 @@ private List FakeWorkshopCards() return eSlist; } + + private WorkshopDescriptionItemDto FakeWorkshopDescriptionItem() + { + var id = Guid.NewGuid(); + return new WorkshopDescriptionItemDto + { + Id = id, + SectionName = "test heading", + Description = $"test description text sentence for id: {id.ToString()}", + }; + } } } \ No newline at end of file diff --git a/OutOfSchool/OutOfSchool.WebApi.Tests/Extensions/MappingExtensionsTests.cs b/OutOfSchool/OutOfSchool.WebApi.Tests/Extensions/MappingExtensionsTests.cs index 8dd3e5716e..b1fc3422b8 100644 --- a/OutOfSchool/OutOfSchool.WebApi.Tests/Extensions/MappingExtensionsTests.cs +++ b/OutOfSchool/OutOfSchool.WebApi.Tests/Extensions/MappingExtensionsTests.cs @@ -14,6 +14,7 @@ using OutOfSchool.WebApi.Extensions; using OutOfSchool.WebApi.Models; using OutOfSchool.WebApi.Models.ChatWorkshop; +using OutOfSchool.WebApi.Models.Workshop; using OutOfSchool.WebApi.Util; namespace OutOfSchool.WebApi.Tests.Extensions @@ -244,7 +245,15 @@ public void Mapping_WorkshopDTO_ToCardDto_IsCorrect() Id = Guid.NewGuid(), Title = "Title5", Phone = "1111111111", - Description = "Desc5", + WorkshopDescriptionItems = new[] + { + new WorkshopDescriptionItemDto + { + Id = Guid.NewGuid(), + SectionName = "test heading1", + Description = "test sentence of description1", + }, + }, Price = 5000, IsPerMonth = true, WithDisabilityOptions = true, diff --git a/OutOfSchool/OutOfSchool.WebApi.Tests/Services/Database/WorkshopServiceTests.cs b/OutOfSchool/OutOfSchool.WebApi.Tests/Services/Database/WorkshopServiceTests.cs index ec74baec13..d5ed487f02 100644 --- a/OutOfSchool/OutOfSchool.WebApi.Tests/Services/Database/WorkshopServiceTests.cs +++ b/OutOfSchool/OutOfSchool.WebApi.Tests/Services/Database/WorkshopServiceTests.cs @@ -460,7 +460,6 @@ private Workshop WithWorkshop(Guid id) Id = id, Title = "ChangedTitle", Phone = "1111111111", - Description = "Desc1", Price = 1000, WithDisabilityOptions = true, ProviderTitle = "ProviderTitle", @@ -488,6 +487,15 @@ private Workshop WithWorkshop(Guid id) Latitude = 10, Longitude = 10, }, + WorkshopDescriptionItems = new[] + { + new WorkshopDescriptionItem() + { + Id = Guid.NewGuid(), + SectionName = "Workshop description heading 1", + Description = "Workshop description text 1", + }, + }, }; } diff --git a/OutOfSchool/OutOfSchool.WebApi/Extensions/ElasticsearchMappingExtensions.cs b/OutOfSchool/OutOfSchool.WebApi/Extensions/ElasticsearchMappingExtensions.cs index 350294bad6..114d6b9c9c 100644 --- a/OutOfSchool/OutOfSchool.WebApi/Extensions/ElasticsearchMappingExtensions.cs +++ b/OutOfSchool/OutOfSchool.WebApi/Extensions/ElasticsearchMappingExtensions.cs @@ -11,6 +11,8 @@ namespace OutOfSchool.WebApi.Extensions // TODO: create a mapping profile instead of extensions public static class ElasticsearchMappingExtensions { + private const char SEPARATOR = '¤'; + // From DTO to ES models public static WorkshopES ToESModel(this WorkshopDTO workshopDto) { @@ -21,8 +23,15 @@ public static WorkshopES ToESModel(this WorkshopDTO workshopDto) dest => dest.Keywords, opt => opt.MapFrom(src => - string.Join('¤', src.Keywords.Distinct()))) - .ForMember(dest => dest.Directions, opt => opt.MapFrom(src => src.Directions)); + string.Join(SEPARATOR, src.Keywords.Distinct()))) + .ForMember(dest => dest.Directions, opt => opt.MapFrom(src => src.Directions)) + .ForMember( + dest => dest.Description, + opt => + opt.MapFrom(src => + src.WorkshopDescriptionItems + .Aggregate(string.Empty, (accumulator, wdi) => + $"{accumulator}{wdi.SectionName}{SEPARATOR}{wdi.Description}{SEPARATOR}"))); cfg.CreateMap() .ForMember( diff --git a/OutOfSchool/OutOfSchool.WebApi/Extensions/MappingExtensions.cs b/OutOfSchool/OutOfSchool.WebApi/Extensions/MappingExtensions.cs index 4a159311e7..a86f55f80b 100644 --- a/OutOfSchool/OutOfSchool.WebApi/Extensions/MappingExtensions.cs +++ b/OutOfSchool/OutOfSchool.WebApi/Extensions/MappingExtensions.cs @@ -7,6 +7,7 @@ using OutOfSchool.Services.Models.ChatWorkshop; using OutOfSchool.WebApi.Models; using OutOfSchool.WebApi.Models.ChatWorkshop; +using OutOfSchool.WebApi.Models.Workshop; namespace OutOfSchool.WebApi.Extensions { @@ -152,6 +153,7 @@ public static WorkshopDTO ToModel(this Workshop workshop) cfg.CreateMap(); cfg.CreateMap(); cfg.CreateMap(); + cfg.CreateMap(); }); } diff --git a/OutOfSchool/OutOfSchool.WebApi/Models/ProviderSectionItemDto.cs b/OutOfSchool/OutOfSchool.WebApi/Models/ProviderSectionItemDto.cs index 2a2c233316..edeed17080 100644 --- a/OutOfSchool/OutOfSchool.WebApi/Models/ProviderSectionItemDto.cs +++ b/OutOfSchool/OutOfSchool.WebApi/Models/ProviderSectionItemDto.cs @@ -8,7 +8,7 @@ public class ProviderSectionItemDto public Guid Id { get; set; } [MaxLength(200)] - public string Name { get; set; } + public string SectionName { get; set; } [MaxLength(2000)] public string Description { get; set; } diff --git a/OutOfSchool/OutOfSchool.WebApi/Models/Workshop/WorkshopDTO.cs b/OutOfSchool/OutOfSchool.WebApi/Models/Workshop/WorkshopDTO.cs index e44bfb8b4c..e96e48ea52 100644 --- a/OutOfSchool/OutOfSchool.WebApi/Models/Workshop/WorkshopDTO.cs +++ b/OutOfSchool/OutOfSchool.WebApi/Models/Workshop/WorkshopDTO.cs @@ -13,6 +13,7 @@ using OutOfSchool.Services.Enums; using OutOfSchool.Services.Models; using OutOfSchool.WebApi.Models.Workshop; +using OutOfSchool.WebApi.Util.CustomValidation; using OutOfSchool.WebApi.Util.JsonTools; namespace OutOfSchool.WebApi.Models @@ -64,9 +65,9 @@ public class WorkshopDTO : IValidatableObject [Range(0, 10000, ErrorMessage = "Field value should be in a range from 1 to 10 000")] public decimal Price { get; set; } = default; - [Required(ErrorMessage = "Description is required")] - [MaxLength(500)] - public string Description { get; set; } = string.Empty; + [ModelBinder(BinderType = typeof(JsonModelBinder))] + [CollectionNotEmpty(ErrorMessage = "At least one description is required")] + public IEnumerable WorkshopDescriptionItems { get; set; } public bool WithDisabilityOptions { get; set; } = default; diff --git a/OutOfSchool/OutOfSchool.WebApi/Models/Workshop/WorkshopDescriptionItemDto.cs b/OutOfSchool/OutOfSchool.WebApi/Models/Workshop/WorkshopDescriptionItemDto.cs new file mode 100644 index 0000000000..13fa679250 --- /dev/null +++ b/OutOfSchool/OutOfSchool.WebApi/Models/Workshop/WorkshopDescriptionItemDto.cs @@ -0,0 +1,20 @@ +using System; +using System.ComponentModel.DataAnnotations; + +namespace OutOfSchool.WebApi.Models.Workshop +{ + public class WorkshopDescriptionItemDto + { + public Guid Id { get; set; } + + [Required] + [MaxLength(200)] + public string SectionName { get; set; } + + [Required] + [MaxLength(2000)] + public string Description { get; set; } + + public Guid WorkshopId { get; set; } + } +} \ No newline at end of file diff --git a/OutOfSchool/OutOfSchool.WebApi/Util/CustomValidation/CollectionNotEmptyAttribute.cs b/OutOfSchool/OutOfSchool.WebApi/Util/CustomValidation/CollectionNotEmptyAttribute.cs new file mode 100644 index 0000000000..b982112709 --- /dev/null +++ b/OutOfSchool/OutOfSchool.WebApi/Util/CustomValidation/CollectionNotEmptyAttribute.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections; + +namespace OutOfSchool.WebApi.Util.CustomValidation +{ + [AttributeUsage(AttributeTargets.Property)] + public class CollectionNotEmptyAttribute : System.ComponentModel.DataAnnotations.ValidationAttribute + { + public override bool IsValid(object value) + { + return value switch + { + ICollection collection => collection.Count > 0, + IEnumerable enumerable => enumerable.GetEnumerator().MoveNext(), + _ => false + }; + } + } +} \ No newline at end of file diff --git a/OutOfSchool/OutOfSchool.WebApi/Util/MappingProfile.cs b/OutOfSchool/OutOfSchool.WebApi/Util/MappingProfile.cs index 1738c74a61..d3c703442e 100644 --- a/OutOfSchool/OutOfSchool.WebApi/Util/MappingProfile.cs +++ b/OutOfSchool/OutOfSchool.WebApi/Util/MappingProfile.cs @@ -59,12 +59,18 @@ public MappingProfile() .ForMember(dest => dest.InstitutionHierarchy, opt => opt.MapFrom(src => src.InstitutionHierarchy.Title)) .ForMember(dest => dest.Directions, opt => opt.MapFrom(src => src.InstitutionHierarchy.Directions)); + CreateMap().ReverseMap(); + CreateMap().ReverseMap(); CreateMap(); CreateMap().ReverseMap(); - CreateMap().ReverseMap(); + CreateMap().ReverseMap() + .ForMember( + dest => + dest.Name, opt => + opt.MapFrom(psi => psi.SectionName)); CreateMap() .ForMember(dest => dest.ActualAddress, opt => opt.MapFrom(src => src.ActualAddress)) @@ -142,7 +148,14 @@ public MappingProfile() .ForMember(dest => dest.Rating, opt => opt.Ignore()) .ForMember(dest => dest.Direction, opt => opt.Ignore()) .ForMember(dest => dest.InstitutionHierarchy, opt => opt.MapFrom(src => src.InstitutionHierarchy.Title)) - .ForMember(dest => dest.Directions, opt => opt.MapFrom(src => src.InstitutionHierarchy.Directions)); + .ForMember(dest => dest.Directions, opt => opt.MapFrom(src => src.InstitutionHierarchy.Directions)) + .ForMember( + dest => dest.Description, + opt => + opt.MapFrom(src => + src.WorkshopDescriptionItems + .Aggregate(string.Empty, (accumulator, wdi) => + $"{accumulator}{wdi.SectionName}{SEPARATOR}{wdi.Description}{SEPARATOR}"))); #warning The next mapping is here to test UI Admin features. Will be removed or refactored CreateMap(); diff --git a/OutOfSchool/Tests/OutOfSchool.Tests.Common/TestDataGenerators/WorkshopGenerator.cs b/OutOfSchool/Tests/OutOfSchool.Tests.Common/TestDataGenerators/WorkshopGenerator.cs index 016c96dcc3..e0e35559e0 100644 --- a/OutOfSchool/Tests/OutOfSchool.Tests.Common/TestDataGenerators/WorkshopGenerator.cs +++ b/OutOfSchool/Tests/OutOfSchool.Tests.Common/TestDataGenerators/WorkshopGenerator.cs @@ -21,7 +21,13 @@ public static class WorkshopGenerator .RuleFor(x => x.MinAge, f => f.Random.Number(1, 18)) // .RuleFor(x => x.MaxAge, f => f.) .RuleFor(x => x.Price, f => f.Random.Decimal()) - .RuleFor(x => x.Description, f => f.Lorem.Paragraph()) + .RuleFor(x => x.WorkshopDescriptionItems, f => f.Make(new Random().Next(1, 4), () => + new WorkshopDescriptionItem() + { + Id = Guid.NewGuid(), + SectionName = f.Lorem.Sentence(), + Description = f.Lorem.Paragraph(), + })) .RuleFor(x => x.WithDisabilityOptions, f => f.Random.Bool()) .RuleFor(x => x.DisabilityOptionsDesc, f => f.Lorem.Sentence()) .RuleFor(x => x.CoverImageId, f => f.Image.LoremFlickrUrl())