From a151e739f41e2f4398f9646093f81af98945f12c Mon Sep 17 00:00:00 2001 From: Abrahamiaan <145220762+Abrahamiaan@users.noreply.github.com> Date: Sun, 17 Dec 2023 00:11:55 +0400 Subject: [PATCH 1/2] Implement the GetUser(userName, showGroupsOnly) Web API --- .../Interfaces/IUserService.cs | 1 + LML.NPOManagement.Bll/Services/UserService.cs | 41 +- .../INPOManagementContext.cs | 3 +- LML.NPOManagement.Dal/Models/User.cs | 5 + LML.NPOManagement.Dal/Models/UsersGroup.cs | 23 + LML.NPOManagement.Dal/NPOManagementContext.cs | 725 +++++++++--------- .../Controllers/UserController.cs | 20 +- .../Properties/launchSettings.json | 62 +- 8 files changed, 494 insertions(+), 386 deletions(-) create mode 100644 LML.NPOManagement.Dal/Models/UsersGroup.cs diff --git a/LML.NPOManagement.Bll/Interfaces/IUserService.cs b/LML.NPOManagement.Bll/Interfaces/IUserService.cs index 09ca42b..8d770f3 100644 --- a/LML.NPOManagement.Bll/Interfaces/IUserService.cs +++ b/LML.NPOManagement.Bll/Interfaces/IUserService.cs @@ -19,5 +19,6 @@ public interface IUserService Task UserInformationRegistration(UserInformationModel userInformationModel, IConfiguration configuration); Task AddUserType(UserInformationModel userInformationModel); Task ActivationUser(string token, IConfiguration configuration); + Task> GetUserByUsername(string userName, bool showGroupsOnly, int userId); } } diff --git a/LML.NPOManagement.Bll/Services/UserService.cs b/LML.NPOManagement.Bll/Services/UserService.cs index d08c5eb..64bfc91 100644 --- a/LML.NPOManagement.Bll/Services/UserService.cs +++ b/LML.NPOManagement.Bll/Services/UserService.cs @@ -263,5 +263,44 @@ public async Task ModifyUserInfo(UserInformationModel userInformationModel await _dbContext.SaveChangesAsync(); return true; } + + public async Task> GetUserByUsername(string userName, bool showGroupsOnly, int userId) + { + List users = new(); + + if (!showGroupsOnly) + { + users = await _dbContext.Users.ToListAsync(); + } + else + { + var groupIds = _dbContext.Users + .Where(u => u.Id == userId) + .SelectMany(u => u.Groups.Select(g => g.Id)) + .ToList(); + + users = _dbContext.Users + .Where(u => u.UsersGroups.Any(g => groupIds.Contains(g.Id))) + .ToList(); + } + + List result = new(); + + foreach (var user in users) + { + var userInfo = await _dbContext.UserInformations.Where(u => u.UserId == user.Id).FirstOrDefaultAsync(); + if (userInfo != null) + { + string fullName = userInfo.FirstName + " " + userInfo.LastName; + if (fullName.StartsWith(userName, StringComparison.OrdinalIgnoreCase)) + { + var userInformationModel = _mapper.Map(userInfo); + result.Add(userInformationModel); + } + } + } + + return result; + } } -} +} \ No newline at end of file diff --git a/LML.NPOManagement.Dal/INPOManagementContext.cs b/LML.NPOManagement.Dal/INPOManagementContext.cs index b4f2a4f..bbfb253 100644 --- a/LML.NPOManagement.Dal/INPOManagementContext.cs +++ b/LML.NPOManagement.Dal/INPOManagementContext.cs @@ -20,7 +20,8 @@ public interface INPOManagementContext DbSet UserIdeas { get; set; } DbSet UserInformations { get; set; } DbSet UserInventories { get; set; } - DbSet UserTypes { get; set; } + DbSet UserTypes { get; set; } + DbSet UsersGroups { get; set; } Task SaveChangesAsync(); void SaveChanges(); } diff --git a/LML.NPOManagement.Dal/Models/User.cs b/LML.NPOManagement.Dal/Models/User.cs index a73f138..1ecec0c 100644 --- a/LML.NPOManagement.Dal/Models/User.cs +++ b/LML.NPOManagement.Dal/Models/User.cs @@ -11,7 +11,9 @@ public User() UserIdeas = new HashSet(); UserInformations = new HashSet(); UserInventories = new HashSet(); + UsersGroups = new HashSet(); Accounts = new HashSet(); + Groups = new HashSet(); Notifications = new HashSet(); Roles = new HashSet(); UserTypes = new HashSet(); @@ -21,13 +23,16 @@ public User() public string Email { get; set; } = null!; public string Password { get; set; } = null!; public string? Status { get; set; } + public int? StatusId { get; set; } public virtual ICollection InvestorInformations { get; set; } public virtual ICollection UserIdeas { get; set; } public virtual ICollection UserInformations { get; set; } public virtual ICollection UserInventories { get; set; } + public virtual ICollection UsersGroups { get; set; } public virtual ICollection Accounts { get; set; } + public virtual ICollection Groups { get; set; } public virtual ICollection Notifications { get; set; } public virtual ICollection Roles { get; set; } public virtual ICollection UserTypes { get; set; } diff --git a/LML.NPOManagement.Dal/Models/UsersGroup.cs b/LML.NPOManagement.Dal/Models/UsersGroup.cs new file mode 100644 index 0000000..6e5e354 --- /dev/null +++ b/LML.NPOManagement.Dal/Models/UsersGroup.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; + +namespace LML.NPOManagement.Dal.Models +{ + public partial class UsersGroup + { + public UsersGroup() + { + Users = new HashSet(); + } + + public int Id { get; set; } + public int CreatedByUserId { get; set; } + public string GroupName { get; set; } = null!; + public DateTime CreatedAt { get; set; } + public string? Description { get; set; } + + public virtual User CreatedByUser { get; set; } = null!; + + public virtual ICollection Users { get; set; } + } +} diff --git a/LML.NPOManagement.Dal/NPOManagementContext.cs b/LML.NPOManagement.Dal/NPOManagementContext.cs index b7dadfc..c16b4a4 100644 --- a/LML.NPOManagement.Dal/NPOManagementContext.cs +++ b/LML.NPOManagement.Dal/NPOManagementContext.cs @@ -1,352 +1,373 @@ -using System; -using System.Collections.Generic; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.Extensions.Configuration; - -namespace LML.NPOManagement.Dal.Models -{ - public partial class NPOManagementContext : DbContext, INPOManagementContext - { - public NPOManagementContext() - { - } - - public NPOManagementContext(DbContextOptions options) - : base(options) - { - } - - public virtual DbSet Accounts { get; set; } = null!; - public virtual DbSet AccountProgresses { get; set; } = null!; - public virtual DbSet Attachments { get; set; } = null!; - public virtual DbSet Donations { get; set; } = null!; - public virtual DbSet InventoryTypes { get; set; } = null!; - public virtual DbSet InvestorInformations { get; set; } = null!; - public virtual DbSet InvestorTierTypes { get; set; } = null!; - public virtual DbSet Notifications { get; set; } = null!; - public virtual DbSet NotificationTransportTypes { get; set; } = null!; - public virtual DbSet NotificationTypes { get; set; } = null!; - public virtual DbSet Roles { get; set; } = null!; - public virtual DbSet Users { get; set; } = null!; - public virtual DbSet UserIdeas { get; set; } = null!; - public virtual DbSet UserInformations { get; set; } = null!; - public virtual DbSet UserInventories { get; set; } = null!; - public virtual DbSet UserTypes { get; set; } = null!; - - protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - { - // if (!optionsBuilder.IsConfigured) - // { - //#warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see http://go.microsoft.com/fwlink/?LinkId=723263. - // optionsBuilder.UseSqlServer("Server=lmldb.cj8tmk4otjem.eu-west-1.rds.amazonaws.com,1433;Database=NPOManagement;User Id=lmladmin;Password=January2021"); - // } - if (!optionsBuilder.IsConfigured) - { - IConfigurationRoot configuration = new ConfigurationBuilder() - .SetBasePath(AppDomain.CurrentDomain.BaseDirectory) - .AddJsonFile("appsettings.json") - .Build(); - optionsBuilder.UseSqlServer(configuration.GetConnectionString("DefaultConnection")); - } - } - - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - modelBuilder.Entity(entity => - { - entity.ToTable("Account"); - - entity.Property(e => e.Description).HasColumnType("ntext"); - - entity.Property(e => e.Name).HasMaxLength(50); - - entity.Property(e => e.Status).HasMaxLength(50); - - entity.HasMany(d => d.Users) - .WithMany(p => p.Accounts) - .UsingEntity>( - "AccountUserInformationConnection", - l => l.HasOne().WithMany().HasForeignKey("UserId").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FK_AccountUserInformationConnection_User"), - r => r.HasOne().WithMany().HasForeignKey("AccountId").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FK_AccountUserInformationConnection_Account"), - j => - { - j.HasKey("AccountId", "UserId").HasName("PK_AccountBeneficiaryConnaction"); - - j.ToTable("AccountUserInformationConnection"); - }); - }); - - modelBuilder.Entity(entity => - { - entity.ToTable("AccountProgress"); - - entity.Property(e => e.Id).HasComment("From Progress in account"); - - entity.Property(e => e.Description).HasColumnType("ntext"); - - entity.HasOne(d => d.Account) - .WithMany(p => p.AccountProgresses) - .HasForeignKey(d => d.AccountId) - .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("FK_AccountProgress_Account"); - }); - - modelBuilder.Entity(entity => - { - entity.ToTable("Attachment"); - }); - - modelBuilder.Entity(entity => - { - entity.ToTable("Donation"); - - entity.Property(e => e.Amount).HasColumnType("numeric(10, 3)"); - - entity.Property(e => e.DateOfCharity).HasColumnType("datetime"); - - entity.HasOne(d => d.Investor) - .WithMany(p => p.Donations) - .HasForeignKey(d => d.InvestorId) - .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("FK_Donation_InvestorInformation"); - }); - - modelBuilder.Entity(entity => - { - entity.ToTable("InventoryType"); - - entity.Property(e => e.Description) - .HasMaxLength(100) - .IsUnicode(false); - }); - - modelBuilder.Entity(entity => - { - entity.ToTable("InvestorInformation"); - - entity.HasOne(d => d.InvestorTier) - .WithMany(p => p.InvestorInformations) - .HasForeignKey(d => d.InvestorTierId) - .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("FK_InvestorInformation_InvestorTierType"); - - entity.HasOne(d => d.User) - .WithMany(p => p.InvestorInformations) - .HasForeignKey(d => d.UserId) - .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("FK_InvestorInformation_User"); - }); - - modelBuilder.Entity(entity => - { - entity.ToTable("InvestorTierType"); - - entity.Property(e => e.InvestorTier).HasMaxLength(50); - }); - - modelBuilder.Entity(entity => - { - entity.ToTable("Notification"); - - entity.Property(e => e.Body).HasColumnType("ntext"); - - entity.Property(e => e.Metadata).HasColumnType("ntext"); - - entity.Property(e => e.Reminder).HasMaxLength(50); - - entity.Property(e => e.Subject) - .HasMaxLength(128) - .IsUnicode(false); - - entity.HasOne(d => d.Attachment) - .WithMany(p => p.Notifications) - .HasForeignKey(d => d.AttachmentId) - .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("FK_Notification_Attachment"); - - entity.HasOne(d => d.NotificationType) - .WithMany(p => p.Notifications) - .HasForeignKey(d => d.NotificationTypeId) - .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("FK_Notification_NotificationType"); - - entity.HasMany(d => d.NotificationTransportTypes) - .WithMany(p => p.Notifications) - .UsingEntity>( - "NotificationBroadcast", - l => l.HasOne().WithMany().HasForeignKey("NotificationTransportTypeId").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FK_NotificationBroadcast_NotificationType"), - r => r.HasOne().WithMany().HasForeignKey("NotificationId").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FK_NotificationBroadcast_Notification"), - j => - { - j.HasKey("NotificationId", "NotificationTransportTypeId"); - - j.ToTable("NotificationBroadcast"); - }); - - entity.HasMany(d => d.Users) - .WithMany(p => p.Notifications) - .UsingEntity>( - "Notification2User", - l => l.HasOne().WithMany().HasForeignKey("UserId").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FK_Notification2User_User"), - r => r.HasOne().WithMany().HasForeignKey("NotificationId").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FK_Notification2User_Notification"), - j => - { - j.HasKey("NotificationId", "UserId").HasName("PK_AccounManagerRoleConnection"); - - j.ToTable("Notification2User"); - }); - }); - - modelBuilder.Entity(entity => - { - entity.ToTable("NotificationTransportType"); - - entity.Property(e => e.Description).HasMaxLength(50); - }); - - modelBuilder.Entity(entity => - { - entity.ToTable("NotificationType"); - - entity.Property(e => e.Description).HasMaxLength(50); - - entity.Property(e => e.Uri) - .HasMaxLength(1024) - .IsUnicode(false) - .HasColumnName("URI"); - }); - - modelBuilder.Entity(entity => - { - entity.ToTable("Role"); - - entity.Property(e => e.UserRole).HasMaxLength(50); - - entity.HasMany(d => d.Users) - .WithMany(p => p.Roles) - .UsingEntity>( - "UserRoleConnection", - l => l.HasOne().WithMany().HasForeignKey("UserId").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FK_UserRoleConnection_User"), - r => r.HasOne().WithMany().HasForeignKey("RoleId").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FK_UserRoleConnection_Role"), - j => - { - j.HasKey("RoleId", "UserId"); - - j.ToTable("UserRoleConnection"); - }); - }); - - modelBuilder.Entity(entity => - { - entity.ToTable("User"); - - entity.Property(e => e.Email) - .HasMaxLength(128) - .IsUnicode(false); - - entity.Property(e => e.Password).HasMaxLength(250); - - entity.Property(e => e.Status).HasMaxLength(50); - }); - - modelBuilder.Entity(entity => - { - entity.ToTable("UserIdea"); - - entity.Property(e => e.IdeaCategory).HasMaxLength(256); - - entity.HasOne(d => d.User) - .WithMany(p => p.UserIdeas) - .HasForeignKey(d => d.UserId) - .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("FK_UserIdea_User"); - }); - - modelBuilder.Entity(entity => - { - entity.ToTable("UserInformation"); - - entity.Property(e => e.CreateDate).HasColumnType("datetime"); - - entity.Property(e => e.DateOfBirth).HasColumnType("datetime"); - - entity.Property(e => e.FirstName).HasMaxLength(50); - - entity.Property(e => e.LastName).HasMaxLength(50); - - entity.Property(e => e.Metadata).HasColumnType("ntext"); - - entity.Property(e => e.MiddleName).HasMaxLength(50); - - entity.Property(e => e.PhoneNumber).HasMaxLength(50); - - entity.Property(e => e.UpdateDate).HasColumnType("datetime"); - - entity.HasOne(d => d.User) - .WithMany(p => p.UserInformations) - .HasForeignKey(d => d.UserId) - .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("FK_UserInformation_User"); - }); - - modelBuilder.Entity(entity => - { - entity.ToTable("UserInventory"); - - entity.Property(e => e.Amount).HasColumnType("numeric(10, 2)"); - - entity.Property(e => e.Date).HasColumnType("datetime"); - - entity.Property(e => e.Description).HasColumnType("ntext"); - - entity.Property(e => e.MeasurmentUnit).HasMaxLength(50); - - entity.HasOne(d => d.InventoryType) - .WithMany(p => p.UserInventories) - .HasForeignKey(d => d.InventoryTypeId) - .OnDelete(DeleteBehavior.ClientSetNull) - .HasConstraintName("FK_AccountManagerInventory_InventoryType"); - - entity.HasOne(d => d.User) - .WithMany(p => p.UserInventories) - .HasForeignKey(d => d.UserId) - .HasConstraintName("FK_UserInventory_User"); - }); - - modelBuilder.Entity(entity => - { - entity.ToTable("UserType"); - - entity.Property(e => e.Description).HasMaxLength(50); - - entity.HasMany(d => d.Users) - .WithMany(p => p.UserTypes) - .UsingEntity>( - "User2UserType", - l => l.HasOne().WithMany().HasForeignKey("UserId").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FK_User2UserType_User1"), - r => r.HasOne().WithMany().HasForeignKey("UserTypeId").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FK_User2UserType_UserType1"), - j => - { - j.HasKey("UserTypeId", "UserId").HasName("PK_User2UserTypeConnection"); - - j.ToTable("User2UserType"); - }); - }); - - OnModelCreatingPartial(modelBuilder); - } - - partial void OnModelCreatingPartial(ModelBuilder modelBuilder); - - void INPOManagementContext.SaveChanges() - { - base.SaveChanges(); - } - public async Task SaveChangesAsync() - { - return await base.SaveChangesAsync(); - } - - } -} +using System; +using System.Collections.Generic; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata; + +namespace LML.NPOManagement.Dal.Models +{ + public partial class NPOManagementContext : DbContext, INPOManagementContext + { + public NPOManagementContext() + { + } + + public NPOManagementContext(DbContextOptions options) + : base(options) + { + } + + public virtual DbSet Accounts { get; set; } = null!; + public virtual DbSet AccountProgresses { get; set; } = null!; + public virtual DbSet Attachments { get; set; } = null!; + public virtual DbSet Donations { get; set; } = null!; + public virtual DbSet InventoryTypes { get; set; } = null!; + public virtual DbSet InvestorInformations { get; set; } = null!; + public virtual DbSet InvestorTierTypes { get; set; } = null!; + public virtual DbSet Notifications { get; set; } = null!; + public virtual DbSet NotificationTransportTypes { get; set; } = null!; + public virtual DbSet NotificationTypes { get; set; } = null!; + public virtual DbSet Roles { get; set; } = null!; + public virtual DbSet Users { get; set; } = null!; + public virtual DbSet UserIdeas { get; set; } = null!; + public virtual DbSet UserInformations { get; set; } = null!; + public virtual DbSet UserInventories { get; set; } = null!; + public virtual DbSet UserTypes { get; set; } = null!; + public virtual DbSet UsersGroups { get; set; } = null!; + + public async Task SaveChangesAsync() + { + return await base.SaveChangesAsync(); + } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + if (!optionsBuilder.IsConfigured) + { + optionsBuilder.UseSqlServer("Data Source=localhost,1433;Initial Catalog=NPOManagement;User ID=sa;Password=098305624v;TrustServerCertificate=true;Encrypt=False;"); + } + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity(entity => + { + entity.ToTable("Account"); + + entity.Property(e => e.Description).HasColumnType("ntext"); + + entity.Property(e => e.Name).HasMaxLength(50); + + entity.Property(e => e.Status).HasMaxLength(50); + + entity.HasMany(d => d.Users) + .WithMany(p => p.Accounts) + .UsingEntity>( + "AccountUserInformationConnection", + l => l.HasOne().WithMany().HasForeignKey("UserId").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FK_AccountUserInformationConnection_User"), + r => r.HasOne().WithMany().HasForeignKey("AccountId").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FK_AccountUserInformationConnection_Account"), + j => + { + j.HasKey("AccountId", "UserId").HasName("PK_AccountBeneficiaryConnaction"); + + j.ToTable("AccountUserInformationConnection"); + }); + }); + + modelBuilder.Entity(entity => + { + entity.ToTable("AccountProgress"); + + entity.Property(e => e.Id).HasComment("From Progress in account"); + + entity.Property(e => e.Description).HasColumnType("ntext"); + + entity.HasOne(d => d.Account) + .WithMany(p => p.AccountProgresses) + .HasForeignKey(d => d.AccountId) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("FK_AccountProgress_Account"); + }); + + modelBuilder.Entity(entity => + { + entity.ToTable("Attachment"); + }); + + modelBuilder.Entity(entity => + { + entity.ToTable("Donation"); + + entity.Property(e => e.Amount).HasColumnType("numeric(10, 3)"); + + entity.Property(e => e.DateOfCharity).HasColumnType("datetime"); + + entity.HasOne(d => d.Investor) + .WithMany(p => p.Donations) + .HasForeignKey(d => d.InvestorId) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("FK_Donation_InvestorInformation"); + }); + + modelBuilder.Entity(entity => + { + entity.ToTable("InventoryType"); + + entity.Property(e => e.Description) + .HasMaxLength(100) + .IsUnicode(false); + }); + + modelBuilder.Entity(entity => + { + entity.ToTable("InvestorInformation"); + + entity.HasOne(d => d.InvestorTier) + .WithMany(p => p.InvestorInformations) + .HasForeignKey(d => d.InvestorTierId) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("FK_InvestorInformation_InvestorTierType"); + + entity.HasOne(d => d.User) + .WithMany(p => p.InvestorInformations) + .HasForeignKey(d => d.UserId) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("FK_InvestorInformation_User"); + }); + + modelBuilder.Entity(entity => + { + entity.ToTable("InvestorTierType"); + + entity.Property(e => e.InvestorTier).HasMaxLength(50); + }); + + modelBuilder.Entity(entity => + { + entity.ToTable("Notification"); + + entity.Property(e => e.Body).HasColumnType("ntext"); + + entity.Property(e => e.Metadata).HasColumnType("ntext"); + + entity.Property(e => e.Reminder).HasMaxLength(50); + + entity.Property(e => e.Subject) + .HasMaxLength(128) + .IsUnicode(false); + + entity.HasOne(d => d.Attachment) + .WithMany(p => p.Notifications) + .HasForeignKey(d => d.AttachmentId) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("FK_Notification_Attachment"); + + entity.HasOne(d => d.NotificationType) + .WithMany(p => p.Notifications) + .HasForeignKey(d => d.NotificationTypeId) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("FK_Notification_NotificationType"); + + entity.HasMany(d => d.NotificationTransportTypes) + .WithMany(p => p.Notifications) + .UsingEntity>( + "NotificationBroadcast", + l => l.HasOne().WithMany().HasForeignKey("NotificationTransportTypeId").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FK_NotificationBroadcast_NotificationType"), + r => r.HasOne().WithMany().HasForeignKey("NotificationId").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FK_NotificationBroadcast_Notification"), + j => + { + j.HasKey("NotificationId", "NotificationTransportTypeId"); + + j.ToTable("NotificationBroadcast"); + }); + + entity.HasMany(d => d.Users) + .WithMany(p => p.Notifications) + .UsingEntity>( + "Notification2User", + l => l.HasOne().WithMany().HasForeignKey("UserId").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FK_Notification2User_User"), + r => r.HasOne().WithMany().HasForeignKey("NotificationId").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FK_Notification2User_Notification"), + j => + { + j.HasKey("NotificationId", "UserId").HasName("PK_AccounManagerRoleConnection"); + + j.ToTable("Notification2User"); + }); + }); + + modelBuilder.Entity(entity => + { + entity.ToTable("NotificationTransportType"); + + entity.Property(e => e.Description).HasMaxLength(50); + }); + + modelBuilder.Entity(entity => + { + entity.ToTable("NotificationType"); + + entity.Property(e => e.Description).HasMaxLength(50); + + entity.Property(e => e.Uri) + .HasMaxLength(1024) + .IsUnicode(false) + .HasColumnName("URI"); + }); + + modelBuilder.Entity(entity => + { + entity.ToTable("Role"); + + entity.Property(e => e.UserRole).HasMaxLength(50); + + entity.HasMany(d => d.Users) + .WithMany(p => p.Roles) + .UsingEntity>( + "UserRoleConnection", + l => l.HasOne().WithMany().HasForeignKey("UserId").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FK_UserRoleConnection_User"), + r => r.HasOne().WithMany().HasForeignKey("RoleId").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FK_UserRoleConnection_Role"), + j => + { + j.HasKey("RoleId", "UserId"); + + j.ToTable("UserRoleConnection"); + }); + }); + + modelBuilder.Entity(entity => + { + entity.ToTable("User"); + + entity.Property(e => e.Email) + .HasMaxLength(128) + .IsUnicode(false); + + entity.Property(e => e.Password).HasMaxLength(250); + + entity.Property(e => e.Status).HasMaxLength(50); + + entity.HasMany(d => d.Groups) + .WithMany(p => p.Users) + .UsingEntity>( + "UserGroupMembership", + l => l.HasOne().WithMany().HasForeignKey("GroupId").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FK__UserGroup__Group__19DFD96B"), + r => r.HasOne().WithMany().HasForeignKey("UserId").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FK__UserGroup__UserI__47A6A41B"), + j => + { + j.HasKey("UserId", "GroupId").HasName("PK__UserGrou__A6C1637AC2561575"); + + j.ToTable("UserGroupMembership"); + }); + }); + + modelBuilder.Entity(entity => + { + entity.ToTable("UserIdea"); + + entity.Property(e => e.IdeaCategory).HasMaxLength(256); + + entity.HasOne(d => d.User) + .WithMany(p => p.UserIdeas) + .HasForeignKey(d => d.UserId) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("FK_UserIdea_User"); + }); + + modelBuilder.Entity(entity => + { + entity.ToTable("UserInformation"); + + entity.Property(e => e.CreateDate).HasColumnType("datetime"); + + entity.Property(e => e.DateOfBirth).HasColumnType("datetime"); + + entity.Property(e => e.FirstName).HasMaxLength(50); + + entity.Property(e => e.LastName).HasMaxLength(50); + + entity.Property(e => e.Metadata).HasColumnType("ntext"); + + entity.Property(e => e.MiddleName).HasMaxLength(50); + + entity.Property(e => e.PhoneNumber).HasMaxLength(50); + + entity.Property(e => e.UpdateDate).HasColumnType("datetime"); + + entity.HasOne(d => d.User) + .WithMany(p => p.UserInformations) + .HasForeignKey(d => d.UserId) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("FK_UserInformation_User"); + }); + + modelBuilder.Entity(entity => + { + entity.ToTable("UserInventory"); + + entity.Property(e => e.Amount).HasColumnType("numeric(10, 2)"); + + entity.Property(e => e.Date).HasColumnType("datetime"); + + entity.Property(e => e.Description).HasColumnType("ntext"); + + entity.Property(e => e.MeasurmentUnit).HasMaxLength(50); + + entity.HasOne(d => d.InventoryType) + .WithMany(p => p.UserInventories) + .HasForeignKey(d => d.InventoryTypeId) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("FK_AccountManagerInventory_InventoryType"); + + entity.HasOne(d => d.User) + .WithMany(p => p.UserInventories) + .HasForeignKey(d => d.UserId) + .HasConstraintName("FK_UserInventory_User"); + }); + + modelBuilder.Entity(entity => + { + entity.ToTable("UserType"); + + entity.Property(e => e.Description).HasMaxLength(50); + + entity.HasMany(d => d.Users) + .WithMany(p => p.UserTypes) + .UsingEntity>( + "User2UserType", + l => l.HasOne().WithMany().HasForeignKey("UserId").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FK_User2UserType_User1"), + r => r.HasOne().WithMany().HasForeignKey("UserTypeId").OnDelete(DeleteBehavior.ClientSetNull).HasConstraintName("FK_User2UserType_UserType1"), + j => + { + j.HasKey("UserTypeId", "UserId").HasName("PK_User2UserTypeConnection"); + + j.ToTable("User2UserType"); + }); + }); + + modelBuilder.Entity(entity => + { + entity.ToTable("UsersGroup"); + + entity.Property(e => e.CreatedAt) + .HasColumnType("datetime") + .HasDefaultValueSql("(getdate())"); + + entity.Property(e => e.GroupName).HasMaxLength(255); + + entity.HasOne(d => d.CreatedByUser) + .WithMany(p => p.UsersGroups) + .HasForeignKey(d => d.CreatedByUserId) + .OnDelete(DeleteBehavior.ClientSetNull) + .HasConstraintName("FK_UsersGroup_User"); + }); + + OnModelCreatingPartial(modelBuilder); + } + + partial void OnModelCreatingPartial(ModelBuilder modelBuilder); + + void INPOManagementContext.SaveChanges() + { + base.SaveChanges(); + } + } +} diff --git a/LML.NPOManagement/Controllers/UserController.cs b/LML.NPOManagement/Controllers/UserController.cs index 5b189f5..ac8d91b 100644 --- a/LML.NPOManagement/Controllers/UserController.cs +++ b/LML.NPOManagement/Controllers/UserController.cs @@ -75,7 +75,25 @@ public async Task Get(int id) var user = await _userService.GetUserById(id); return _mapper.Map(user); } - + + [HttpGet("byFirstChars")] + public async Task>> GetByFirstChars(string firstChars, bool showGroupsOnly) + { + var currentUser = HttpContext.Items["User"] as UserModel; + if (currentUser == null) + { + return BadRequest("Current User Null"); + } + + var users = await _userService.GetUserByUsername(firstChars, showGroupsOnly, currentUser.Id); + if (users == null) + { + return NotFound("Users Not Found"); + } + + return Ok(_mapper.Map, List>(users)); + } + // PUT api//5 [HttpPut("{id}")] public async Task Put(int id, [FromBody] UserRequest userRequest) diff --git a/LML.NPOManagement/Properties/launchSettings.json b/LML.NPOManagement/Properties/launchSettings.json index 9c88b53..fb6cb06 100644 --- a/LML.NPOManagement/Properties/launchSettings.json +++ b/LML.NPOManagement/Properties/launchSettings.json @@ -1,31 +1,31 @@ -{ - "$schema": "https://json.schemastore.org/launchsettings.json", - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:11614", - "sslPort": 44316 - } - }, - "profiles": { - "LML.NPOManagement": { - "commandName": "Project", - "dotnetRunMessages": true, - "launchBrowser": true, - "launchUrl": "swagger", - "applicationUrl": "https://localhost:7049;http://localhost:5049", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "launchUrl": "swagger", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } - } -} +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:11614", + "sslPort": 44316 + } + }, + "profiles": { + "LML.NPOManagement": { + "commandName": "Project", + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "https://localhost:7049;http://localhost:5049", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "dotnetRunMessages": true + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} \ No newline at end of file From c11633ad3307654246ec5b1a70b06c8440000d98 Mon Sep 17 00:00:00 2001 From: vladabrahamian Date: Sat, 6 Jan 2024 23:59:29 +0400 Subject: [PATCH 2/2] Implement the GetByFirstChars(nameFirstChars, includeGroups) Web API --- .../Interfaces/IUserService.cs | 2 +- LML.NPOManagement.Bll/Model/SearchModel.cs | 11 ++++ LML.NPOManagement.Bll/Model/SearchType.cs | 10 ++++ LML.NPOManagement.Bll/Services/UserService.cs | 53 ++++++++++--------- .../Controllers/UserController.cs | 21 ++++---- LML.NPOManagement/Response/SearchResponse.cs | 13 +++++ 6 files changed, 73 insertions(+), 37 deletions(-) create mode 100644 LML.NPOManagement.Bll/Model/SearchModel.cs create mode 100644 LML.NPOManagement.Bll/Model/SearchType.cs create mode 100644 LML.NPOManagement/Response/SearchResponse.cs diff --git a/LML.NPOManagement.Bll/Interfaces/IUserService.cs b/LML.NPOManagement.Bll/Interfaces/IUserService.cs index 8d770f3..b3907a0 100644 --- a/LML.NPOManagement.Bll/Interfaces/IUserService.cs +++ b/LML.NPOManagement.Bll/Interfaces/IUserService.cs @@ -19,6 +19,6 @@ public interface IUserService Task UserInformationRegistration(UserInformationModel userInformationModel, IConfiguration configuration); Task AddUserType(UserInformationModel userInformationModel); Task ActivationUser(string token, IConfiguration configuration); - Task> GetUserByUsername(string userName, bool showGroupsOnly, int userId); + Task> GetSearchResult(string firstChars, bool includeGroups); } } diff --git a/LML.NPOManagement.Bll/Model/SearchModel.cs b/LML.NPOManagement.Bll/Model/SearchModel.cs new file mode 100644 index 0000000..7a10e4e --- /dev/null +++ b/LML.NPOManagement.Bll/Model/SearchModel.cs @@ -0,0 +1,11 @@ +using System; +namespace LML.NPOManagement.Bll.Model +{ + public class SearchModel + { + public int Id { get; set; } + public SearchType Type { get; set; } + public String Name { get; set; } + } +} + diff --git a/LML.NPOManagement.Bll/Model/SearchType.cs b/LML.NPOManagement.Bll/Model/SearchType.cs new file mode 100644 index 0000000..03e72e7 --- /dev/null +++ b/LML.NPOManagement.Bll/Model/SearchType.cs @@ -0,0 +1,10 @@ +using System; +namespace LML.NPOManagement.Bll.Model +{ + public enum SearchType + { + User, + Group + } +} + diff --git a/LML.NPOManagement.Bll/Services/UserService.cs b/LML.NPOManagement.Bll/Services/UserService.cs index 64bfc91..05c07d6 100644 --- a/LML.NPOManagement.Bll/Services/UserService.cs +++ b/LML.NPOManagement.Bll/Services/UserService.cs @@ -264,40 +264,45 @@ public async Task ModifyUserInfo(UserInformationModel userInformationModel return true; } - public async Task> GetUserByUsername(string userName, bool showGroupsOnly, int userId) + public async Task> GetSearchResult(string firstChars, bool includeGroups) { - List users = new(); + var users = await _dbContext.UserInformations + .Where(u => u.FirstName.Contains(firstChars) || u.LastName.Contains(firstChars)) + .ToListAsync(); - if (!showGroupsOnly) + var groups = new List(); + + if (includeGroups) { - users = await _dbContext.Users.ToListAsync(); + groups = await _dbContext.UsersGroups + .Where(g => g.GroupName.Contains(firstChars)) + .ToListAsync(); } - else + + List result = new(); + + foreach (var user in users) { - var groupIds = _dbContext.Users - .Where(u => u.Id == userId) - .SelectMany(u => u.Groups.Select(g => g.Id)) - .ToList(); + var searchModel = new SearchModel() + { + Id = user.Id, + Name = user.FirstName + " " + user.LastName, + Type = SearchType.User + }; - users = _dbContext.Users - .Where(u => u.UsersGroups.Any(g => groupIds.Contains(g.Id))) - .ToList(); + result.Add(searchModel); } - - List result = new(); - foreach (var user in users) + foreach (var group in groups) { - var userInfo = await _dbContext.UserInformations.Where(u => u.UserId == user.Id).FirstOrDefaultAsync(); - if (userInfo != null) + var searchModel = new SearchModel() { - string fullName = userInfo.FirstName + " " + userInfo.LastName; - if (fullName.StartsWith(userName, StringComparison.OrdinalIgnoreCase)) - { - var userInformationModel = _mapper.Map(userInfo); - result.Add(userInformationModel); - } - } + Id = group.Id, + Name = group.GroupName, + Type = SearchType.Group + }; + + result.Add(searchModel); } return result; diff --git a/LML.NPOManagement/Controllers/UserController.cs b/LML.NPOManagement/Controllers/UserController.cs index ac8d91b..a65263b 100644 --- a/LML.NPOManagement/Controllers/UserController.cs +++ b/LML.NPOManagement/Controllers/UserController.cs @@ -44,7 +44,6 @@ public UserController(IUserService userService, IConfiguration configuration, IN cfg.CreateMap(); cfg.CreateMap(); cfg.CreateMap(); - cfg.CreateMap(); cfg.CreateMap(); cfg.CreateMap(); cfg.CreateMap(); @@ -52,6 +51,7 @@ public UserController(IUserService userService, IConfiguration configuration, IN cfg.CreateMap(); cfg.CreateMap(); cfg.CreateMap(); + cfg.CreateMap(); }); _mapper = config.CreateMapper(); _userService = userService; @@ -76,22 +76,19 @@ public async Task Get(int id) return _mapper.Map(user); } + //GET: api// [HttpGet("byFirstChars")] - public async Task>> GetByFirstChars(string firstChars, bool showGroupsOnly) + public async Task>> GetByFirstChars(string nameFirstChars, bool includeGroups) { - var currentUser = HttpContext.Items["User"] as UserModel; - if (currentUser == null) - { - return BadRequest("Current User Null"); - } - - var users = await _userService.GetUserByUsername(firstChars, showGroupsOnly, currentUser.Id); - if (users == null) - { + var searchResults = await _userService.GetSearchResult(nameFirstChars, includeGroups); + if (searchResults == null || !searchResults.Any()) + { return NotFound("Users Not Found"); } - return Ok(_mapper.Map, List>(users)); + var searchResponses = _mapper.Map, List>(searchResults); + + return Ok(searchResponses); } // PUT api//5 diff --git a/LML.NPOManagement/Response/SearchResponse.cs b/LML.NPOManagement/Response/SearchResponse.cs new file mode 100644 index 0000000..f21b870 --- /dev/null +++ b/LML.NPOManagement/Response/SearchResponse.cs @@ -0,0 +1,13 @@ +using System; +using LML.NPOManagement.Bll.Model; + +namespace LML.NPOManagement.Response +{ + public class SearchResponse + { + public int Id { get; set; } + public SearchType Type { get; set; } + public String Name { get; set; } + } +} +