diff --git a/OutOfSchool/OutOfSchool.DataAccess/Models/Favorite.cs b/OutOfSchool/OutOfSchool.DataAccess/Models/Favorite.cs new file mode 100644 index 0000000000..81b6e542f6 --- /dev/null +++ b/OutOfSchool/OutOfSchool.DataAccess/Models/Favorite.cs @@ -0,0 +1,20 @@ +using System.ComponentModel.DataAnnotations; + +namespace OutOfSchool.Services.Models +{ + public class Favorite + { + public long Id { get; set; } + + [Required] + [Range(1, long.MaxValue, ErrorMessage = "Workshop id should be grater than 0")] + public long WorkshopId { get; set; } + + [Required] + public string UserId { get; set; } + + public virtual Workshop Workshop { get; set; } + + public virtual User User { get; set; } + } +} diff --git a/OutOfSchool/OutOfSchool.DataAccess/OutOfSchoolDbContext.cs b/OutOfSchool/OutOfSchool.DataAccess/OutOfSchoolDbContext.cs index b17d276bf9..3e3210e74b 100644 --- a/OutOfSchool/OutOfSchool.DataAccess/OutOfSchoolDbContext.cs +++ b/OutOfSchool/OutOfSchool.DataAccess/OutOfSchoolDbContext.cs @@ -46,6 +46,8 @@ public OutOfSchoolDbContext(DbContextOptions options) public DbSet Cities { get; set; } + public DbSet Favorites { get; set; } + protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); diff --git a/OutOfSchool/OutOfSchool.IdentityServer/Data/Migrations/OutOfSchoolMigrations/20210723161143_Favorites.Designer.cs b/OutOfSchool/OutOfSchool.IdentityServer/Data/Migrations/OutOfSchoolMigrations/20210723161143_Favorites.Designer.cs new file mode 100644 index 0000000000..d66100332f --- /dev/null +++ b/OutOfSchool/OutOfSchool.IdentityServer/Data/Migrations/OutOfSchoolMigrations/20210723161143_Favorites.Designer.cs @@ -0,0 +1,1288 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using OutOfSchool.Services; + +namespace OutOfSchool.IdentityServer.Data.Migrations.OutOfSchoolMigrations +{ + [DbContext(typeof(OutOfSchoolDbContext))] + [Migration("20210723161143_Favorites")] + partial class Favorites + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .UseIdentityColumns() + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("ProductVersion", "5.0.2"); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("nvarchar(450)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(36) + .IsUnicode(false) + .HasColumnType("char(36)") + .IsFixedLength(true); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex") + .HasFilter("[NormalizedName] IS NOT NULL"); + + b.ToTable("AspNetRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .UseIdentityColumn(); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .UseIdentityColumn(); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderKey") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("nvarchar(450)"); + + b.Property("RoleId") + .HasColumnType("nvarchar(450)"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("nvarchar(450)"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Address", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .UseIdentityColumn(); + + b.Property("BuildingNumber") + .IsRequired() + .HasMaxLength(15) + .HasColumnType("nvarchar(15)"); + + b.Property("City") + .IsRequired() + .HasMaxLength(15) + .HasColumnType("nvarchar(15)"); + + b.Property("District") + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("Latitude") + .HasColumnType("float"); + + b.Property("Longitude") + .HasColumnType("float"); + + b.Property("Region") + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("Street") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.HasKey("Id"); + + b.ToTable("Addresses"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Application", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .UseIdentityColumn(); + + b.Property("ChildId") + .HasColumnType("bigint"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("ParentId") + .HasColumnType("bigint"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("WorkshopId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("ChildId"); + + b.HasIndex("ParentId"); + + b.HasIndex("WorkshopId"); + + b.ToTable("Applications"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.BirthCertificate", b => + { + b.Property("Id") + .HasColumnType("bigint"); + + b.Property("SvidDate") + .HasColumnType("datetime2"); + + b.Property("SvidNum") + .HasColumnType("nvarchar(max)"); + + b.Property("SvidNumMD5") + .HasColumnType("nvarchar(max)"); + + b.Property("SvidSer") + .HasColumnType("nvarchar(max)"); + + b.Property("SvidWho") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("BirthCertificates"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.ChatMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .UseIdentityColumn(); + + b.Property("ChatRoomId") + .HasColumnType("bigint"); + + b.Property("CreatedTime") + .HasColumnType("datetime2"); + + b.Property("IsRead") + .HasColumnType("bit"); + + b.Property("Text") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("UserId") + .IsRequired() + .HasMaxLength(450) + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("ChatRoomId"); + + b.HasIndex("UserId"); + + b.ToTable("ChatMessages"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.ChatRoom", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .UseIdentityColumn(); + + b.Property("WorkshopId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("WorkshopId"); + + b.ToTable("ChatRooms"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.ChatRoomUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .UseIdentityColumn(); + + b.Property("ChatRoomId") + .HasColumnType("bigint"); + + b.Property("UserId") + .IsRequired() + .HasMaxLength(450) + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("ChatRoomId"); + + b.HasIndex("UserId"); + + b.ToTable("ChatRoomUsers"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Child", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .UseIdentityColumn(); + + b.Property("DateOfBirth") + .HasColumnType("datetime2"); + + b.Property("FirstName") + .IsRequired() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)"); + + b.Property("Gender") + .HasColumnType("int"); + + b.Property("LastName") + .IsRequired() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)"); + + b.Property("MiddleName") + .HasMaxLength(40) + .HasColumnType("nvarchar(40)"); + + b.Property("ParentId") + .HasColumnType("bigint"); + + b.Property("SocialGroupId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.HasIndex("SocialGroupId"); + + b.ToTable("Children"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.City", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .UseIdentityColumn(); + + b.Property("District") + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("Latitude") + .HasColumnType("float"); + + b.Property("Longitude") + .HasColumnType("float"); + + b.Property("Name") + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("Region") + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.HasKey("Id"); + + b.ToTable("Cities"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Class", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .UseIdentityColumn(); + + b.Property("DepartmentId") + .HasColumnType("bigint"); + + b.Property("Description") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(60) + .HasColumnType("nvarchar(60)"); + + b.HasKey("Id"); + + b.HasIndex("DepartmentId"); + + b.ToTable("Classes"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Department", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .UseIdentityColumn(); + + b.Property("Description") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("DirectionId") + .HasColumnType("bigint"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(60) + .HasColumnType("nvarchar(60)"); + + b.HasKey("Id"); + + b.HasIndex("DirectionId"); + + b.ToTable("Departments"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Direction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .UseIdentityColumn(); + + b.Property("Description") + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(60) + .HasColumnType("nvarchar(60)"); + + b.HasKey("Id"); + + b.ToTable("Directions"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Favorite", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .UseIdentityColumn(); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.Property("WorkshopId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.HasIndex("WorkshopId"); + + b.ToTable("Favorites"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Parent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .UseIdentityColumn(); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Parents"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Provider", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .UseIdentityColumn(); + + b.Property("ActualAddressId") + .HasColumnType("bigint"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("Director") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("DirectorDateOfBirth") + .HasColumnType("datetime2"); + + b.Property("EdrpouIpn") + .IsRequired() + .HasMaxLength(12) + .HasColumnType("nvarchar(12)"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Facebook") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("Founder") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("FullTitle") + .IsRequired() + .HasMaxLength(60) + .HasColumnType("nvarchar(60)"); + + b.Property("Instagram") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("LegalAddressId") + .HasColumnType("bigint"); + + b.Property("Ownership") + .HasColumnType("int"); + + b.Property("PhoneNumber") + .HasMaxLength(15) + .HasColumnType("nvarchar(15)"); + + b.Property("ShortTitle") + .IsRequired() + .HasMaxLength(60) + .HasColumnType("nvarchar(60)"); + + b.Property("Status") + .HasColumnType("bit"); + + b.Property("Type") + .HasColumnType("int"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.Property("Website") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.HasKey("Id"); + + b.HasIndex("ActualAddressId"); + + b.HasIndex("LegalAddressId"); + + b.HasIndex("UserId"); + + b.ToTable("Providers"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Rating", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .UseIdentityColumn(); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("EntityId") + .HasColumnType("bigint"); + + b.Property("ParentId") + .HasColumnType("bigint"); + + 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") + .UseIdentityColumn(); + + b.Property("Name") + .HasMaxLength(100) + .HasColumnType("nvarchar(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.Teacher", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .UseIdentityColumn(); + + b.Property("DateOfBirth") + .HasColumnType("datetime2"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(300) + .HasColumnType("nvarchar(300)"); + + b.Property("FirstName") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("Image") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("LastName") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("MiddleName") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("WorkshopId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("WorkshopId"); + + b.ToTable("Teachers"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.User", b => + { + b.Property("Id") + .HasColumnType("nvarchar(450)"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(36) + .IsUnicode(false) + .HasColumnType("char(36)") + .IsFixedLength(true); + + b.Property("CreatingTime") + .HasColumnType("datetime2"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("bit"); + + b.Property("FirstName") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("IsRegistered") + .HasColumnType("bit"); + + b.Property("LastLogin") + .HasColumnType("datetime2"); + + b.Property("LastName") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("MiddleName") + .HasMaxLength(30) + .HasColumnType("nvarchar(30)"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(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("bit"); + + b.Property("Role") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("SecurityStamp") + .IsRequired() + .HasMaxLength(36) + .IsUnicode(false) + .HasColumnType("varchar(36)") + .IsFixedLength(false); + + b.Property("TwoFactorEnabled") + .HasColumnType("bit"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex") + .HasFilter("[NormalizedUserName] IS NOT NULL"); + + b.ToTable("AspNetUsers"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Workshop", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .UseIdentityColumn(); + + b.Property("AddressId") + .HasColumnType("bigint"); + + b.Property("ClassId") + .HasColumnType("bigint"); + + b.Property("DaysPerWeek") + .HasColumnType("int"); + + b.Property("DepartmentId") + .HasColumnType("bigint"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("DirectionId") + .HasColumnType("bigint"); + + b.Property("DisabilityOptionsDesc") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Facebook") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Head") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("HeadDateOfBirth") + .HasColumnType("datetime2"); + + b.Property("Instagram") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("IsPerMonth") + .HasColumnType("bit"); + + b.Property("Keywords") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Logo") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("MaxAge") + .HasColumnType("int"); + + b.Property("MinAge") + .HasColumnType("int"); + + b.Property("Phone") + .IsRequired() + .HasMaxLength(15) + .HasColumnType("nvarchar(15)"); + + b.Property("Price") + .HasColumnType("decimal(18,2)"); + + b.Property("ProviderId") + .HasColumnType("bigint"); + + b.Property("ProviderTitle") + .IsRequired() + .HasMaxLength(60) + .HasColumnType("nvarchar(60)"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(60) + .HasColumnType("nvarchar(60)"); + + b.Property("Website") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("WithDisabilityOptions") + .HasColumnType("bit"); + + b.HasKey("Id"); + + b.HasIndex("AddressId"); + + b.HasIndex("ClassId"); + + b.HasIndex("DirectionId"); + + b.HasIndex("ProviderId"); + + b.ToTable("Workshops"); + }); + + 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.Cascade) + .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.BirthCertificate", b => + { + b.HasOne("OutOfSchool.Services.Models.Child", "Child") + .WithOne("BirthCertificate") + .HasForeignKey("OutOfSchool.Services.Models.BirthCertificate", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Child"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.ChatMessage", b => + { + b.HasOne("OutOfSchool.Services.Models.ChatRoom", "ChatRoom") + .WithMany("ChatMessages") + .HasForeignKey("ChatRoomId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("OutOfSchool.Services.Models.User", "User") + .WithMany("ChatMessages") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ChatRoom"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.ChatRoom", b => + { + b.HasOne("OutOfSchool.Services.Models.Workshop", "Workshop") + .WithMany("ChatRooms") + .HasForeignKey("WorkshopId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Workshop"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.ChatRoomUser", b => + { + b.HasOne("OutOfSchool.Services.Models.ChatRoom", "ChatRoom") + .WithMany("ChatRoomUsers") + .HasForeignKey("ChatRoomId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("OutOfSchool.Services.Models.User", "User") + .WithMany("ChatRoomUsers") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ChatRoom"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Child", b => + { + b.HasOne("OutOfSchool.Services.Models.Parent", "Parent") + .WithMany("Children") + .HasForeignKey("ParentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("OutOfSchool.Services.Models.SocialGroup", "SocialGroup") + .WithMany("Children") + .HasForeignKey("SocialGroupId"); + + b.Navigation("Parent"); + + 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.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.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") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + 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("LegalAddress"); + + b.Navigation("User"); + }); + + 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.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.Cascade) + .IsRequired(); + + b.HasOne("OutOfSchool.Services.Models.Provider", "Provider") + .WithMany("Workshops") + .HasForeignKey("ProviderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Address"); + + b.Navigation("Class"); + + b.Navigation("Direction"); + + b.Navigation("Provider"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.ChatRoom", b => + { + b.Navigation("ChatMessages"); + + b.Navigation("ChatRoomUsers"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Child", b => + { + b.Navigation("BirthCertificate"); + }); + + 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.Parent", b => + { + b.Navigation("Children"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Provider", b => + { + b.Navigation("Workshops"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.SocialGroup", b => + { + b.Navigation("Children"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.User", b => + { + b.Navigation("ChatMessages"); + + b.Navigation("ChatRoomUsers"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Workshop", b => + { + b.Navigation("Applications"); + + b.Navigation("ChatRooms"); + + b.Navigation("Teachers"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/OutOfSchool/OutOfSchool.IdentityServer/Data/Migrations/OutOfSchoolMigrations/20210723161143_Favorites.cs b/OutOfSchool/OutOfSchool.IdentityServer/Data/Migrations/OutOfSchoolMigrations/20210723161143_Favorites.cs new file mode 100644 index 0000000000..6d81c54907 --- /dev/null +++ b/OutOfSchool/OutOfSchool.IdentityServer/Data/Migrations/OutOfSchoolMigrations/20210723161143_Favorites.cs @@ -0,0 +1,55 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace OutOfSchool.IdentityServer.Data.Migrations.OutOfSchoolMigrations +{ + /// + /// Add Favorites table. + /// + public partial class Favorites : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Favorites", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + WorkshopId = table.Column(type: "bigint", nullable: false), + UserId = table.Column(type: "nvarchar(450)", nullable: false), + }, + constraints: table => + { + table.PrimaryKey("PK_Favorites", x => x.Id); + table.ForeignKey( + name: "FK_Favorites_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.NoAction); + table.ForeignKey( + name: "FK_Favorites_Workshops_WorkshopId", + column: x => x.WorkshopId, + principalTable: "Workshops", + principalColumn: "Id", + onDelete: ReferentialAction.NoAction); + }); + + migrationBuilder.CreateIndex( + name: "IX_Favorites_UserId", + table: "Favorites", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_Favorites_WorkshopId", + table: "Favorites", + column: "WorkshopId"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Favorites"); + } + } +} diff --git a/OutOfSchool/OutOfSchool.IdentityServer/Data/Migrations/OutOfSchoolMigrations/OutOfSchoolDbContextModelSnapshot.cs b/OutOfSchool/OutOfSchool.IdentityServer/Data/Migrations/OutOfSchoolMigrations/OutOfSchoolDbContextModelSnapshot.cs index 1b3a366f98..2205d02941 100644 --- a/OutOfSchool/OutOfSchool.IdentityServer/Data/Migrations/OutOfSchoolMigrations/OutOfSchoolDbContextModelSnapshot.cs +++ b/OutOfSchool/OutOfSchool.IdentityServer/Data/Migrations/OutOfSchoolMigrations/OutOfSchoolDbContextModelSnapshot.cs @@ -474,6 +474,29 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("Directions"); }); + modelBuilder.Entity("OutOfSchool.Services.Models.Favorite", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .UseIdentityColumn(); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.Property("WorkshopId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.HasIndex("WorkshopId"); + + b.ToTable("Favorites"); + }); + modelBuilder.Entity("OutOfSchool.Services.Models.Parent", b => { b.Property("Id") @@ -1091,6 +1114,25 @@ protected override void BuildModel(ModelBuilder modelBuilder) 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.Parent", b => { b.HasOne("OutOfSchool.Services.Models.User", "User") diff --git a/OutOfSchool/OutOfSchool.WebApi/Controllers/FavoriteController.cs b/OutOfSchool/OutOfSchool.WebApi/Controllers/FavoriteController.cs new file mode 100644 index 0000000000..b97b2c1a7e --- /dev/null +++ b/OutOfSchool/OutOfSchool.WebApi/Controllers/FavoriteController.cs @@ -0,0 +1,149 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Localization; +using OutOfSchool.WebApi.Extensions; +using OutOfSchool.WebApi.Models; +using OutOfSchool.WebApi.Services; + +namespace OutOfSchool.WebApi.Controllers +{ + [ApiController] + [Route("[controller]")] + [Authorize(AuthenticationSchemes = "Bearer")] + public class FavoriteController : ControllerBase + { + private readonly IFavoriteService service; + private readonly IStringLocalizer localizer; + + /// + /// Initializes a new instance of the class. + /// + /// Service for Favorite model. + /// Localizer. + public FavoriteController(IFavoriteService service, IStringLocalizer localizer) + { + this.service = service; + this.localizer = localizer; + } + + /// + /// Get all Favorites from the database. + /// + /// List of all Favorites. + [Authorize(Roles = "admin")] + [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(IEnumerable))] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + [HttpGet("all")] + public async Task Get() + { + var favorites = await service.GetAll().ConfigureAwait(false); + + if (!favorites.Any()) + { + return NoContent(); + } + + return Ok(favorites); + } + + /// + /// Get Favorite by it's id. + /// + /// Favorite id. + /// Favorite. + [Authorize(Roles = "parent,admin")] + [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(FavoriteDto))] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + [HttpGet("{id}")] + public async Task GetById(long id) + { + this.ValidateId(id, localizer); + + return Ok(await service.GetById(id).ConfigureAwait(false)); + } + + /// + /// Get all Favorites from the database by UserId. + /// + /// List of all User Favorites. + [Authorize(Roles = "parent,admin")] + [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(IEnumerable))] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + [HttpGet] + public async Task GetAllByUser() + { + string userId = User.FindFirst("sub")?.Value; + + var favorites = await service.GetAllByUser(userId).ConfigureAwait(false); + + if (!favorites.Any()) + { + return NoContent(); + } + + return Ok(favorites); + } + + /// + /// Add a new Favorite to the database. + /// + /// Favorite entity to add. + /// A representing the result of the asynchronous operation. + [Authorize(Roles = "parent,admin")] + [ProducesResponseType(StatusCodes.Status201Created)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + [HttpPost] + public async Task Create(FavoriteDto dto) + { + var favorite = await service.Create(dto).ConfigureAwait(false); + + return CreatedAtAction( + nameof(GetById), + new { id = favorite.Id, }, + favorite); + } + + /// + /// Update info about a Favorite in the database. + /// + /// Favorite to update. + /// Favorite. + [Authorize(Roles = "parent,admin")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + [HttpPut] + public async Task Update(FavoriteDto dto) + { + return Ok(await service.Update(dto).ConfigureAwait(false)); + } + + /// + /// Delete a specific Favorite from the database. + /// + /// Favorite id. + /// A representing the result of the asynchronous operation. + [Authorize(Roles = "parent,admin")] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + [HttpDelete("{id}")] + public async Task Delete(long id) + { + this.ValidateId(id, localizer); + + await service.Delete(id).ConfigureAwait(false); + + return NoContent(); + } + } +} diff --git a/OutOfSchool/OutOfSchool.WebApi/Extensions/MappingExtensions.cs b/OutOfSchool/OutOfSchool.WebApi/Extensions/MappingExtensions.cs index a331a48ddd..cb8365721b 100644 --- a/OutOfSchool/OutOfSchool.WebApi/Extensions/MappingExtensions.cs +++ b/OutOfSchool/OutOfSchool.WebApi/Extensions/MappingExtensions.cs @@ -107,6 +107,11 @@ public static DirectionDto ToModel(this Direction direction) return Mapper(direction, cfg => { cfg.CreateMap(); }); } + public static FavoriteDto ToModel(this Favorite favorite) + { + return Mapper(favorite, cfg => { cfg.CreateMap(); }); + } + public static ParentDTO ToModel(this Parent parent) { var parentDto = @@ -243,6 +248,11 @@ public static Direction ToDomain(this DirectionDto directionDto) return Mapper(directionDto, cfg => { cfg.CreateMap(); }); } + public static Favorite ToDomain(this FavoriteDto favoriteDto) + { + return Mapper(favoriteDto, cfg => { cfg.CreateMap(); }); + } + public static Parent ToDomain(this ParentDTO parentDto) { var parent = diff --git a/OutOfSchool/OutOfSchool.WebApi/Models/FavoriteDto.cs b/OutOfSchool/OutOfSchool.WebApi/Models/FavoriteDto.cs new file mode 100644 index 0000000000..3c3eda669c --- /dev/null +++ b/OutOfSchool/OutOfSchool.WebApi/Models/FavoriteDto.cs @@ -0,0 +1,16 @@ +using System.ComponentModel.DataAnnotations; + +namespace OutOfSchool.WebApi.Models +{ + public class FavoriteDto + { + public long Id { get; set; } + + [Required] + [Range(1, long.MaxValue, ErrorMessage = "Workshop id should be grater than 0")] + public long WorkshopId { get; set; } + + [Required] + public string UserId { get; set; } + } +} diff --git a/OutOfSchool/OutOfSchool.WebApi/Services/FavoriteService.cs b/OutOfSchool/OutOfSchool.WebApi/Services/FavoriteService.cs new file mode 100644 index 0000000000..a2b8851b92 --- /dev/null +++ b/OutOfSchool/OutOfSchool.WebApi/Services/FavoriteService.cs @@ -0,0 +1,131 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Localization; +using OutOfSchool.Services.Models; +using OutOfSchool.Services.Repository; +using OutOfSchool.WebApi.Extensions; +using OutOfSchool.WebApi.Models; +using Serilog; + +namespace OutOfSchool.WebApi.Services +{ + /// + /// Implements the interface with CRUD functionality for Favorite entity. + /// + public class FavoriteService : IFavoriteService + { + private readonly IEntityRepository repository; + private readonly ILogger logger; + private readonly IStringLocalizer localizer; + + public FavoriteService(IEntityRepository repository, ILogger logger, IStringLocalizer localizer) + { + this.repository = repository; + this.logger = logger; + this.localizer = localizer; + } + + /// + public async Task> GetAll() + { + logger.Information("Getting all Favorites started."); + + var favorites = await repository.GetAll().ConfigureAwait(false); + + logger.Information(!favorites.Any() + ? "Favorites table is empty." + : $"All {favorites.Count()} records were successfully received from the Favorites table"); + + return favorites.Select(favorite => favorite.ToModel()).ToList(); + } + + /// + public async Task GetById(long id) + { + logger.Information($"Getting Favorite by Id started. Looking Id = {id}."); + + var favorite = await repository.GetById(id).ConfigureAwait(false); + + if (favorite == null) + { + throw new ArgumentOutOfRangeException( + nameof(id), + localizer["The id cannot be greater than number of table entities."]); + } + + logger.Information($"Successfully got a Favorite with Id = {id}."); + + return favorite.ToModel(); + } + + /// + public async Task> GetAllByUser(string userId) + { + logger.Information($"Getting Favorites by User started. Looking UserId = {userId}."); + + var favorites = await repository.GetByFilter(x => x.UserId == userId).ConfigureAwait(false); + + logger.Information(!favorites.Any() + ? $"There aren't Favorites for User with Id = {userId}." + : $"All {favorites.Count()} records were successfully received from the Favorites table"); + + return favorites.Select(x => x.ToModel()).ToList(); + } + + /// + public async Task Create(FavoriteDto dto) + { + logger.Information("Favorite creating was started."); + + var favorite = dto.ToDomain(); + + var newFavorite = await repository.Create(favorite).ConfigureAwait(false); + + logger.Information($"Favorite with Id = {newFavorite?.Id} created successfully."); + + return newFavorite.ToModel(); + } + + /// + public async Task Update(FavoriteDto dto) + { + logger.Information($"Updating Favorite with Id = {dto?.Id} started."); + + try + { + var favorite = await repository.Update(dto.ToDomain()).ConfigureAwait(false); + + logger.Information($"Favorite with Id = {favorite?.Id} updated succesfully."); + + return favorite.ToModel(); + } + catch (DbUpdateConcurrencyException) + { + logger.Error($"Updating failed. Favorite with Id = {dto?.Id} doesn't exist in the system."); + throw; + } + } + + /// + public async Task Delete(long id) + { + logger.Information($"Deleting Favorite with Id = {id} started."); + + var favorite = await repository.GetById(id).ConfigureAwait(false); + + if (favorite == null) + { + throw new ArgumentOutOfRangeException( + nameof(id), + localizer[$"Favorite with Id = {id} doesn't exist in the system"]); + } + + await repository.Delete(favorite).ConfigureAwait(false); + + logger.Information($"Favorite with Id = {id} succesfully deleted."); + } + } +} diff --git a/OutOfSchool/OutOfSchool.WebApi/Services/IFavoriteService.cs b/OutOfSchool/OutOfSchool.WebApi/Services/IFavoriteService.cs new file mode 100644 index 0000000000..c043400eaf --- /dev/null +++ b/OutOfSchool/OutOfSchool.WebApi/Services/IFavoriteService.cs @@ -0,0 +1,53 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using OutOfSchool.WebApi.Models; + +namespace OutOfSchool.WebApi.Services +{ + /// + /// Defines interface for CRUD functionality for Favorite entity. + /// + public interface IFavoriteService + { + /// + /// Get all entities. + /// + /// List of all Favorites. + Task> GetAll(); + + /// + /// Get entity by it's key. + /// + /// Key in the table. + /// Favorite. + Task GetById(long id); + + /// + /// Get all entities. + /// + /// User Id. + /// List of all Favorites by User. + Task> GetAllByUser(string userId); + + /// + /// Add entity. + /// + /// Favorite entity to add. + /// A representing the result of the asynchronous operation. + Task Create(FavoriteDto dto); + + /// + /// Update entity. + /// + /// Favorite entity to add. + /// A representing the result of the asynchronous operation. + Task Update(FavoriteDto dto); + + /// + /// Delete entity. + /// + /// Favorite key. + /// A representing the result of the asynchronous operation. + Task Delete(long id); + } +} diff --git a/OutOfSchool/OutOfSchool.WebApi/Startup.cs b/OutOfSchool/OutOfSchool.WebApi/Startup.cs index ebbcfcfb3c..7bc39d0f72 100644 --- a/OutOfSchool/OutOfSchool.WebApi/Startup.cs +++ b/OutOfSchool/OutOfSchool.WebApi/Startup.cs @@ -138,6 +138,7 @@ public void ConfigureServices(IServiceCollection services) services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); @@ -155,6 +156,7 @@ public void ConfigureServices(IServiceCollection services) services.AddTransient, EntityRepository>(); services.AddTransient, EntityRepository>(); services.AddTransient, EntityRepository>(); + services.AddTransient, EntityRepository>(); services.AddTransient, EntityRepository>(); services.AddTransient, EntityRepository>(); services.AddTransient, EntityRepository>();