From 15496b1dd215c74dbf9e177b3dc211980a5dd715 Mon Sep 17 00:00:00 2001 From: Alexander Romanchuk Date: Fri, 15 Apr 2022 00:24:31 +0300 Subject: [PATCH] Add field GroupedData to Notifications. (#588) Add field GroupedData to Notifications. --- .../Models/Notification.cs | 2 + ...28_NotificationsAddGroupedData.Designer.cs | 1578 +++++++++++++++++ ...20413183628_NotificationsAddGroupedData.cs | 24 + .../OutOfSchoolDbContextModelSnapshot.cs | 3 + .../Notifications/NotificationGrouped.cs | 4 + .../NotificationGroupedAndSingle.cs | 5 +- .../Services/ApplicationService.cs | 5 +- .../Services/INotificationService.cs | 11 +- .../Services/NotificationService.cs | 19 +- 9 files changed, 1641 insertions(+), 10 deletions(-) create mode 100644 OutOfSchool/OutOfSchool.IdentityServer/Data/Migrations/OutOfSchoolMigrations/20220413183628_NotificationsAddGroupedData.Designer.cs create mode 100644 OutOfSchool/OutOfSchool.IdentityServer/Data/Migrations/OutOfSchoolMigrations/20220413183628_NotificationsAddGroupedData.cs diff --git a/OutOfSchool/OutOfSchool.DataAccess/Models/Notification.cs b/OutOfSchool/OutOfSchool.DataAccess/Models/Notification.cs index 7bb480fd6b..e0446967ee 100644 --- a/OutOfSchool/OutOfSchool.DataAccess/Models/Notification.cs +++ b/OutOfSchool/OutOfSchool.DataAccess/Models/Notification.cs @@ -14,6 +14,8 @@ public class Notification : IKeyedEntity public Dictionary Data { get; set; } + public string GroupedData { get; set; } + [Required] public NotificationType Type { get; set; } diff --git a/OutOfSchool/OutOfSchool.IdentityServer/Data/Migrations/OutOfSchoolMigrations/20220413183628_NotificationsAddGroupedData.Designer.cs b/OutOfSchool/OutOfSchool.IdentityServer/Data/Migrations/OutOfSchoolMigrations/20220413183628_NotificationsAddGroupedData.Designer.cs new file mode 100644 index 0000000000..71c7d50eb4 --- /dev/null +++ b/OutOfSchool/OutOfSchool.IdentityServer/Data/Migrations/OutOfSchoolMigrations/20220413183628_NotificationsAddGroupedData.Designer.cs @@ -0,0 +1,1578 @@ +// +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("20220413183628_NotificationsAddGroupedData")] + partial class NotificationsAddGroupedData + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Relational:MaxIdentifierLength", 64) + .HasAnnotation("ProductVersion", "5.0.11"); + + 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.AboutPortal", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("binary(16)"); + + b.Property("Title") + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.HasKey("Id"); + + b.ToTable("AboutPortal"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.AboutPortalItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("binary(16)"); + + b.Property("AboutPortalId") + .HasColumnType("binary(16)"); + + b.Property("Description") + .HasMaxLength(2000) + .HasColumnType("varchar(2000)"); + + b.Property("SectionName") + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.HasKey("Id"); + + b.HasIndex("AboutPortalId"); + + b.ToTable("AboutPortalItems"); + }); + + 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("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.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("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.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"); + + 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.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("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("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("InstitutionStatusId") + .HasColumnType("bigint"); + + 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("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.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.SupportInformation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("binary(16)"); + + b.Property("Description") + .HasMaxLength(3000) + .HasColumnType("varchar(3000)"); + + b.Property("SectionName") + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.Property("Title") + .HasMaxLength(200) + .HasColumnType("varchar(200)"); + + b.HasKey("Id"); + + b.ToTable("SupportInformation"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Teacher", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("binary(16)"); + + b.Property("AvatarImageId") + .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("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("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("Description") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("varchar(500)"); + + 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("Head") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.Property("HeadDateOfBirth") + .HasColumnType("date"); + + b.Property("Instagram") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + 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("ProviderId"); + + b.ToTable("Workshops"); + }); + + 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("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.AboutPortalItem", b => + { + b.HasOne("OutOfSchool.Services.Models.AboutPortal", "AboutPortal") + .WithMany("AboutPortalItems") + .HasForeignKey("AboutPortalId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("AboutPortal"); + }); + + 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.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.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.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.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.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("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.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.NoAction) + .IsRequired(); + + 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("Provider"); + }); + + 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.AboutPortal", b => + { + b.Navigation("AboutPortalItems"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.ChatWorkshop.ChatRoomWorkshop", b => + { + b.Navigation("ChatMessages"); + }); + + 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("ProviderAdmins"); + + b.Navigation("Workshops"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.SocialGroup", b => + { + b.Navigation("Children"); + }); + + modelBuilder.Entity("OutOfSchool.Services.Models.Workshop", b => + { + b.Navigation("Applications"); + + b.Navigation("ChatRooms"); + + b.Navigation("DateTimeRanges"); + + b.Navigation("Images"); + + b.Navigation("Teachers"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/OutOfSchool/OutOfSchool.IdentityServer/Data/Migrations/OutOfSchoolMigrations/20220413183628_NotificationsAddGroupedData.cs b/OutOfSchool/OutOfSchool.IdentityServer/Data/Migrations/OutOfSchoolMigrations/20220413183628_NotificationsAddGroupedData.cs new file mode 100644 index 0000000000..a0d32958d7 --- /dev/null +++ b/OutOfSchool/OutOfSchool.IdentityServer/Data/Migrations/OutOfSchoolMigrations/20220413183628_NotificationsAddGroupedData.cs @@ -0,0 +1,24 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace OutOfSchool.IdentityServer.Data.Migrations.OutOfSchoolMigrations +{ + public partial class NotificationsAddGroupedData : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "GroupedData", + table: "Notifications", + type: "longtext", + nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "GroupedData", + table: "Notifications"); + } + } +} diff --git a/OutOfSchool/OutOfSchool.IdentityServer/Data/Migrations/OutOfSchoolMigrations/OutOfSchoolDbContextModelSnapshot.cs b/OutOfSchool/OutOfSchool.IdentityServer/Data/Migrations/OutOfSchoolMigrations/OutOfSchoolDbContextModelSnapshot.cs index 30d8750f35..c03d6e373c 100644 --- a/OutOfSchool/OutOfSchool.IdentityServer/Data/Migrations/OutOfSchoolMigrations/OutOfSchoolDbContextModelSnapshot.cs +++ b/OutOfSchool/OutOfSchool.IdentityServer/Data/Migrations/OutOfSchoolMigrations/OutOfSchoolDbContextModelSnapshot.cs @@ -615,6 +615,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("Data") .HasColumnType("longtext"); + b.Property("GroupedData") + .HasColumnType("longtext"); + b.Property("ObjectId") .HasColumnType("binary(16)"); diff --git a/OutOfSchool/OutOfSchool.WebApi/Models/Notifications/NotificationGrouped.cs b/OutOfSchool/OutOfSchool.WebApi/Models/Notifications/NotificationGrouped.cs index 2779ed7f8e..8d94b76d82 100644 --- a/OutOfSchool/OutOfSchool.WebApi/Models/Notifications/NotificationGrouped.cs +++ b/OutOfSchool/OutOfSchool.WebApi/Models/Notifications/NotificationGrouped.cs @@ -8,6 +8,10 @@ public class NotificationGrouped [Required] public NotificationType Type { get; set; } + public NotificationAction Action { get; set; } + + public string GroupedData { get; set; } + public int Amount { get; set; } } } diff --git a/OutOfSchool/OutOfSchool.WebApi/Models/Notifications/NotificationGroupedAndSingle.cs b/OutOfSchool/OutOfSchool.WebApi/Models/Notifications/NotificationGroupedAndSingle.cs index dc0ffdad63..348779e67f 100644 --- a/OutOfSchool/OutOfSchool.WebApi/Models/Notifications/NotificationGroupedAndSingle.cs +++ b/OutOfSchool/OutOfSchool.WebApi/Models/Notifications/NotificationGroupedAndSingle.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; +using System.Collections.Generic; namespace OutOfSchool.WebApi.Models.Notifications { diff --git a/OutOfSchool/OutOfSchool.WebApi/Services/ApplicationService.cs b/OutOfSchool/OutOfSchool.WebApi/Services/ApplicationService.cs index 34b11d151f..56de5c7406 100644 --- a/OutOfSchool/OutOfSchool.WebApi/Services/ApplicationService.cs +++ b/OutOfSchool/OutOfSchool.WebApi/Services/ApplicationService.cs @@ -314,12 +314,15 @@ public async Task Update(ApplicationDto applicationDto) { "Status", updatedApplication.Status.ToString() }, }; + string groupedData = updatedApplication.Status.ToString(); + await notificationService.Create( NotificationType.Application, NotificationAction.Update, updatedApplication.Id, this, - additionalData).ConfigureAwait(false); + additionalData, + groupedData).ConfigureAwait(false); return mapper.Map(updatedApplication); } diff --git a/OutOfSchool/OutOfSchool.WebApi/Services/INotificationService.cs b/OutOfSchool/OutOfSchool.WebApi/Services/INotificationService.cs index cc756011a0..c3d8dd2216 100644 --- a/OutOfSchool/OutOfSchool.WebApi/Services/INotificationService.cs +++ b/OutOfSchool/OutOfSchool.WebApi/Services/INotificationService.cs @@ -25,9 +25,16 @@ public interface INotificationService /// Notificaton action to add. /// ObjectId. /// Service which implements interface INotificationReciever. - /// Data which need to save with notification + /// Data need to save with notification. + /// Field is used in grouping notifications for response type NotificationGrouped. /// A representing the result of the asynchronous operation. - Task Create(NotificationType type, NotificationAction action, Guid objectId, INotificationReciever service, Dictionary additionalData = null); + Task Create( + NotificationType type, + NotificationAction action, + Guid objectId, + INotificationReciever service, + Dictionary additionalData = null, + string groupedData = null); /// /// Delete the object from DB. diff --git a/OutOfSchool/OutOfSchool.WebApi/Services/NotificationService.cs b/OutOfSchool/OutOfSchool.WebApi/Services/NotificationService.cs index 84ca04df61..f60e9e7a13 100644 --- a/OutOfSchool/OutOfSchool.WebApi/Services/NotificationService.cs +++ b/OutOfSchool/OutOfSchool.WebApi/Services/NotificationService.cs @@ -70,7 +70,13 @@ public async Task Create(NotificationDto notificationDto) return notificationDtoReturn; } - public async Task Create(NotificationType type, NotificationAction action, Guid objectId, INotificationReciever service, Dictionary additionalData = null) + public async Task Create( + NotificationType type, + NotificationAction action, + Guid objectId, + INotificationReciever service, + Dictionary additionalData = null, + string groupedData = null) { if (!notificationsConfig.Value.Enabled || service is null) { @@ -86,6 +92,7 @@ public async Task Create(NotificationType type, NotificationAction action, Guid CreatedDateTime = DateTimeOffset.UtcNow, ObjectId = objectId, Data = additionalData, + GroupedData = groupedData, }; var recipientsIds = await service.GetNotificationsRecipientIds(action, additionalData, objectId).ConfigureAwait(false); @@ -213,8 +220,14 @@ public async Task GetAllUsersNotificationsGroupedA result.NotificationsGrouped = allNotifications .Where(n => grouped.Contains(n.Type)) - .GroupBy(n => n.Type) - .Select(n => new NotificationGrouped { Type = n.Key, Amount = n.Count() }) + .GroupBy(n => new { n.Type, n.Action, n.GroupedData }) + .Select(n => new NotificationGrouped + { + Type = n.Key.Type, + Action = n.Key.Action, + GroupedData = n.Key.GroupedData, + Amount = n.Count(), + }) .ToList(); result.Notifications = allNotifications