diff --git a/Berizco.Api/AppSettings/Production/appsettings.Production.json b/Berizco.Api/AppSettings/Production/appsettings.Production.json index 0c208ae..d386c77 100644 --- a/Berizco.Api/AppSettings/Production/appsettings.Production.json +++ b/Berizco.Api/AppSettings/Production/appsettings.Production.json @@ -1,8 +1,56 @@ { + "ConnectionStrings": { + "Postgres": "User ID=postgres;Password=root;Host=localhost;Port=5432;Database=iGarsonDB;", + "PostgresServer": "Host=pg-0,pg-1;Username=igarsonAgent;Password=xHTpBf4wC+bBeNg2pL6Ga7VEWKFJx7VPEUpqxwPFfOc2YYTVwFQuHfsiqoVeT9+6;Database=BrizcoDB;Load Balance Hosts=true;Target Session Attributes=primary;Application Name=iGLS" + }, "Logging": { "LogLevel": { "Default": "Information", - "Microsoft.AspNetCore": "Warning" + "Microsoft": "None", + "Microsoft.Hosting.Lifetime": "Information", + "Microsoft.AspNetCore.SignalR": "Debug", + "Microsoft.AspNetCore.Http.Connections": "Debug" } - } -} + }, + "SiteSettings": { + "BaseUrl": "http://localhost:32769", + "UserSetting": { + "Username": "Root", + "Email": "info@brizco.io", + "Password": "root1234", + "Phone": "09211111111", + "RoleName": "RootAdmin", + "FirstName": "همه کاره", + "LastName": "سیستم" + }, + "JwtSettings": { + "SecretKey": "pg8mt74/bk5yx2mr23Zvsu/81Z2czAycEo9ewcm34AndD8SFDXGqBiYv_YaHosseinYaAli_ABOOOOOOOOOLFAZL_BIMEH_JAD_NASABE_YA_GHARIBAL_GHORABA_@@@@_06/0CZWyAqy2H6Xpjp0npg8mt74/bk5yx2mr23Zvsu/81Z2czAycEo9ewcm34AndD8SFDXGqBiYvACLB0dED9vjy+h5sK1BnB30=", + "Issuer": "Brizco", + "Audience": "Brizco", + "ExpireAddDay": "15" + } + }, + "IpRateLimiting": { + "EnableEndpointRateLimiting": false, + "StackBlockedRequests": false, + "RealIpHeader": "X-Real-IP", + "ClientIdHeader": "X-ClientId", + "HttpStatusCode": 429, + "IpWhitelist": [ "127.0.0.1", "::1/10", "192.168.0.0/24" ], + "EndpointWhitelist": [ "get:/api/license", "*:/api/status" ], + "ClientWhitelist": [ "dev-id-1", "dev-id-2" ], + "GeneralRules": [ + { + "Endpoint": "*", + "Period": "1m", + "Limit": 60 + }, + { + "Endpoint": "*", + "Period": "15m", + "Limit": 250 + } + ] + }, + "AllowedHosts": "*" +} \ No newline at end of file diff --git a/Berizco.Api/AppSettings/appsettings.Development.json b/Berizco.Api/AppSettings/appsettings.Development.json index d2d2b1a..873928d 100644 --- a/Berizco.Api/AppSettings/appsettings.Development.json +++ b/Berizco.Api/AppSettings/appsettings.Development.json @@ -13,10 +13,11 @@ } }, "SiteSettings": { + "BaseUrl": "http://localhost:32769", "UserSetting": { - "Username": "Root", - "Email": "igarson_admin@vnfco.ir", - "Password": "root1234", + "Username": "root", + "Email": "info@brizco.io", + "Password": "JXZXdG9lYI58qzsYzCnO", "Phone": "09211111111", "RoleName": "RootAdmin", "FirstName": "همه کاره", @@ -24,8 +25,8 @@ }, "JwtSettings": { "SecretKey": "pg8mt74/bk5yx2mr23Zvsu/81Z2czAycEo9ewcm34AndD8SFDXGqBiYv_YaHosseinYaAli_ABOOOOOOOOOLFAZL_BIMEH_JAD_NASABE_YA_GHARIBAL_GHORABA_@@@@_06/0CZWyAqy2H6Xpjp0npg8mt74/bk5yx2mr23Zvsu/81Z2czAycEo9ewcm34AndD8SFDXGqBiYvACLB0dED9vjy+h5sK1BnB30=", - "Issuer": "iGarson", - "Audience": "iGarson", + "Issuer": "Brizco", + "Audience": "Brizco", "ExpireAddDay": "15" } }, diff --git a/Berizco.Api/Brizco.Api.csproj b/Berizco.Api/Brizco.Api.csproj index 656e5ec..cb6fddc 100644 --- a/Berizco.Api/Brizco.Api.csproj +++ b/Berizco.Api/Brizco.Api.csproj @@ -57,6 +57,7 @@ + diff --git a/Berizco.Api/Controllers/AuthController.cs b/Berizco.Api/Controllers/AuthController.cs index cfd2380..da0b5ed 100644 --- a/Berizco.Api/Controllers/AuthController.cs +++ b/Berizco.Api/Controllers/AuthController.cs @@ -1,6 +1,6 @@ using Brizco.Common.Models.Api; using Brizco.Core.BaseServices; -using Brizco.Core.BaseServices.Abstracts; +using Brizco.Core.CoreServices.Abstracts; using Microsoft.AspNetCore.Authorization.Infrastructure; namespace Brizco.Api.Controllers; @@ -16,6 +16,9 @@ public class AuthController : ICarterModule group.MapPost("login/password", LoginWithPassword) .WithDisplayName("LoginWithPassword") .HasApiVersion(1.0); + group.MapPost("login/swagger", LoginSwagger) + .WithDisplayName("LoginSwagger") + .HasApiVersion(1.0); group.MapPost("login/code", LoginWithVerifyCode) .WithDisplayName("LoginWithVerifyCode") @@ -25,7 +28,7 @@ public class AuthController : ICarterModule .WithDisplayName("GetVerifyCodeCode") .HasApiVersion(1.0); - group.MapPut("forgetpassword", ForgetPassword) + group.MapPut("forget/password", ForgetPassword) .WithDisplayName("ForgetPassword") .HasApiVersion(1.0); @@ -54,8 +57,13 @@ public class AuthController : ICarterModule TypedResults.Ok(await accountService.ForgetPasswordAsync(phoneNumber)); - public async Task LoginSwagger([FromForm] TokenRequest tokenRequest, IAccountService accountService, CancellationToken cancellationToken) - => TypedResults.Json(await accountService.LoginWithPasswordAsync(tokenRequest.username, tokenRequest.password,cancellationToken)); + public async Task LoginSwagger(HttpContext ctx, IAccountService accountService, CancellationToken cancellationToken) + { + + var username = ctx.Request.Form["username"]; + var password = ctx.Request.Form["password"]; + return TypedResults.Json(await accountService.LoginWithPasswordAsync(username, password, cancellationToken)); + } } \ No newline at end of file diff --git a/Berizco.Api/Controllers/ComplexController.cs b/Berizco.Api/Controllers/ComplexController.cs index bbf7480..cf7f85d 100644 --- a/Berizco.Api/Controllers/ComplexController.cs +++ b/Berizco.Api/Controllers/ComplexController.cs @@ -5,9 +5,11 @@ public class ComplexController : ICarterModule public virtual void AddRoutes(IEndpointRouteBuilder app) { - var group = app.NewVersionedApi("Complex").MapGroup($"api/complex"); + var group = app.NewVersionedApi("Complex") + .MapGroup($"api/complex") + .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser()); - group.MapGet("{page}", GetAllAsync) + group.MapGet("", GetAllAsync) .WithDisplayName("GetAllComplex") .HasApiVersion(1.0); @@ -26,7 +28,7 @@ public class ComplexController : ICarterModule } // GET:Get All Entity - public async Task GetAllAsync(int page,ISender sender, CancellationToken cancellationToken) + public async Task GetAllAsync([FromQuery] int page,ISender sender, CancellationToken cancellationToken) => TypedResults.Ok(await sender.Send(new GetComplexesQuery(page), cancellationToken)); // GET:Get An Entity By Id diff --git a/Berizco.Api/Controllers/RoleController.cs b/Berizco.Api/Controllers/RoleController.cs new file mode 100644 index 0000000..73d7744 --- /dev/null +++ b/Berizco.Api/Controllers/RoleController.cs @@ -0,0 +1,51 @@ +namespace Brizco.Api.Controllers; + +public class RoleController : ICarterModule +{ + public RoleController() + { + } + public virtual void AddRoutes(IEndpointRouteBuilder app) + { + var group = app.NewVersionedApi("Role") + .MapGroup($"api/role") + .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser()); + + group.MapGet("", GetAllAsync) + .WithDisplayName("GetAllRoles") + .HasApiVersion(1.0); + + group.MapGet("{id}", GetAsync) + .WithDisplayName("GetOneRole") + .HasApiVersion(1.0); + + group.MapPost("", Post) + .HasApiVersion(1.0); + + group.MapPut("", Put) + .HasApiVersion(1.0); + + group.MapDelete("", Delete) + .HasApiVersion(1.0); + } + + // GET:Get All Entity + public async Task GetAllAsync([FromQuery] int page, IUserService userService, CancellationToken cancellationToken) + => TypedResults.Ok(await userService.GetRolesAsync(page, cancellationToken)); + + // GET:Get An Entity By Id + public async Task GetAsync(Guid id, IUserService userService, CancellationToken cancellationToken) + => TypedResults.Ok(await userService.GetRoleAsync(id)); + + // POST:Create Entity + public async Task Post([FromBody] RoleActionRequestDto request, IUserService userService, CancellationToken cancellationToken) + => TypedResults.Ok(await userService.CreateRoleAsync(request)); + + // PUT:Update Entity + public async Task Put([FromBody] RoleActionRequestDto request, IUserService userService, CancellationToken cancellationToken) + => TypedResults.Ok(await userService.EditRoleAsync(request)); + + // DELETE:Delete Entity + public async Task Delete(Guid id, IUserService userService, CancellationToken cancellationToken) + => TypedResults.Ok(await userService.RemoveRoleAsync(id)); +} \ No newline at end of file diff --git a/Berizco.Api/Controllers/ShiftController.cs b/Berizco.Api/Controllers/ShiftController.cs index 92270aa..f416ed1 100644 --- a/Berizco.Api/Controllers/ShiftController.cs +++ b/Berizco.Api/Controllers/ShiftController.cs @@ -6,9 +6,11 @@ public class ShiftController : ICarterModule } public virtual void AddRoutes(IEndpointRouteBuilder app) { - var group = app.NewVersionedApi("Shift").MapGroup($"api/shift"); + var group = app.NewVersionedApi("Shift") + .MapGroup($"api/shift") + .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser()); - group.MapGet("{page}", GetAllAsync) + group.MapGet("", GetAllAsync) .WithDisplayName("GetAllShift") .HasApiVersion(1.0); @@ -32,7 +34,7 @@ public class ShiftController : ICarterModule } // GET:Get All Entity - public async Task GetAllAsync(int page,ISender sender, CancellationToken cancellationToken) + public async Task GetAllAsync([FromQuery] int page,ISender sender, CancellationToken cancellationToken) => TypedResults.Ok(await sender.Send(new GetShiftsQuery(page), cancellationToken)); // GET:Get An Entity By Id diff --git a/Berizco.Api/Controllers/TaskController.cs b/Berizco.Api/Controllers/TaskController.cs index 01c22c1..f379916 100644 --- a/Berizco.Api/Controllers/TaskController.cs +++ b/Berizco.Api/Controllers/TaskController.cs @@ -7,9 +7,11 @@ public class TaskController : ICarterModule } public virtual void AddRoutes(IEndpointRouteBuilder app) { - var group = app.NewVersionedApi("Task").MapGroup($"api/task"); + var group = app.NewVersionedApi("Task") + .MapGroup($"api/task") + .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser()); - group.MapGet("{page}", GetAllAsync) + group.MapGet("", GetAllAsync) .WithDisplayName("GetAllTask") .HasApiVersion(1.0); @@ -28,7 +30,7 @@ public class TaskController : ICarterModule } // GET:Get All Entity - public async Task GetAllAsync(int page,ISender sender, CancellationToken cancellationToken) + public async Task GetAllAsync([FromQuery] int page,ISender sender, CancellationToken cancellationToken) => TypedResults.Ok(await sender.Send(new GetTasksQuery(page), cancellationToken)); // GET:Get An Entity By Id diff --git a/Berizco.Api/Controllers/UserController.cs b/Berizco.Api/Controllers/UserController.cs new file mode 100644 index 0000000..69f77e9 --- /dev/null +++ b/Berizco.Api/Controllers/UserController.cs @@ -0,0 +1,54 @@ +using Brizco.Core.EntityServices; +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace Brizco.Api.Controllers; + +public class UserController : ICarterModule +{ + public UserController() + { + } + public virtual void AddRoutes(IEndpointRouteBuilder app) + { + var group = app.NewVersionedApi("User") + .MapGroup($"api/user") + .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser()); + + group.MapGet("", GetAllAsync) + .WithDisplayName("GetAllUser") + .HasApiVersion(1.0); + + group.MapGet("{id}", GetAsync) + .WithDisplayName("GetOneUser") + .HasApiVersion(1.0); + + group.MapPost("", Post) + .HasApiVersion(1.0); + + group.MapPut("", Put) + .HasApiVersion(1.0); + + group.MapDelete("", Delete) + .HasApiVersion(1.0); + } + + // GET:Get All Entity + public async Task GetAllAsync([FromQuery]int page, IUserService userService, CancellationToken cancellationToken) + => TypedResults.Ok(await userService.GetUsersAsync(page,cancellationToken)); + + // GET:Get An Entity By Id + public async Task GetAsync(Guid id, IUserService userService, CancellationToken cancellationToken) + => TypedResults.Ok(await userService.GetUserAsync(id)); + + // POST:Create Entity + public async Task Post([FromBody] UserActionRequestDto request, IUserService userService, CancellationToken cancellationToken) + => TypedResults.Ok(await userService.CreateUserAsync(request,cancellationToken)); + + // PUT:Update Entity + public async Task Put([FromBody] UserActionRequestDto request, IUserService userService, CancellationToken cancellationToken) + => TypedResults.Ok(await userService.EditUserAsync(request,cancellationToken)); + + // DELETE:Delete Entity + public async Task Delete(Guid id, IUserService userService, CancellationToken cancellationToken) + => TypedResults.Ok(await userService.RemoveUserAsync(id, cancellationToken)); +} \ No newline at end of file diff --git a/Berizco.Api/WebFramework/Swagger/SwaggerConfiguration.cs b/Berizco.Api/WebFramework/Swagger/SwaggerConfiguration.cs index 025e2e0..d8428fc 100644 --- a/Berizco.Api/WebFramework/Swagger/SwaggerConfiguration.cs +++ b/Berizco.Api/WebFramework/Swagger/SwaggerConfiguration.cs @@ -59,7 +59,7 @@ public static class SwaggerConfiguration #region Security - var url = $"{baseUrl}/api/v1/user/LoginSwagger"; + var url = $"{baseUrl}/api/auth/login/swagger"; options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme { Type = SecuritySchemeType.OAuth2, diff --git a/Berizco.Repository/Brizco.Repository.csproj b/Berizco.Repository/Brizco.Repository.csproj index d728e30..1bcddfd 100644 --- a/Berizco.Repository/Brizco.Repository.csproj +++ b/Berizco.Repository/Brizco.Repository.csproj @@ -58,6 +58,7 @@ + diff --git a/Berizco.Repository/Handlers/Complex/CreateComplexUserCommandHandler.cs b/Berizco.Repository/Handlers/Complex/CreateComplexUserCommandHandler.cs index 2612a36..2434856 100644 --- a/Berizco.Repository/Handlers/Complex/CreateComplexUserCommandHandler.cs +++ b/Berizco.Repository/Handlers/Complex/CreateComplexUserCommandHandler.cs @@ -1,4 +1,5 @@ -using Brizco.Domain.Entities.User; +using Brizco.Domain.Entities.Complex; +using Brizco.Domain.Entities.User; using Microsoft.AspNetCore.Identity; namespace Brizco.Repository.Handlers.Complex; @@ -31,13 +32,26 @@ public class CreateComplexUserCommandHandler : IRequestHandler().Update(complex); - var role = await _roleManager.FindByIdAsync(request.RoleId.ToString()); var user = await _userManager.FindByIdAsync(request.UserId.ToString()); - var result = await _userManager.AddToRoleAsync(user, role.Name); - if (!result.Succeeded) - throw new AppException(string.Join('|', result.Errors)); + if (user == null) + throw new AppException("User not found", ApiResultStatusCode.NotFound); + var complexUser = await _repositoryWrapper.SetRepository() + .TableNoTracking + .FirstOrDefaultAsync(f => f.ComplexId == request.ComplexId && f.UserId == request.UserId, cancellationToken); + if (complexUser != null) + throw new AppException("این کاربر در این رستوران وجود دارد"); + + complexUser = complex.AddComplexUser(request.UserId); + foreach (var roleId in request.RoleIds) + { + var role = await _roleManager.FindByIdAsync(roleId.ToString()); + var result = await _userManager.AddToRoleAsync(user, role.Name); + if (!result.Succeeded) + throw new AppException(string.Join('|', result.Errors)); + complexUser.AddRole(role.Id); + } + + _repositoryWrapper.SetRepository().Add(complexUser); await _repositoryWrapper.SaveChangesAsync(cancellationToken); await _repositoryWrapper.CommitAsync(cancellationToken); return complexUser.AdaptToSDto(); diff --git a/Berizco.Repository/Handlers/Complex/DeleteComplexUserCommandHandler.cs b/Berizco.Repository/Handlers/Complex/DeleteComplexUserCommandHandler.cs index 78d0d33..a9bfab2 100644 --- a/Berizco.Repository/Handlers/Complex/DeleteComplexUserCommandHandler.cs +++ b/Berizco.Repository/Handlers/Complex/DeleteComplexUserCommandHandler.cs @@ -18,7 +18,7 @@ public class DeleteComplexUserCommandHandler : IRequestHandler() .TableNoTracking - .FirstOrDefaultAsync(c => c.Id == request.ComplexUserId, cancellationToken); + .FirstOrDefaultAsync(c => c.ComplexId == request.ComplexId && c.UserId == request.UserId, cancellationToken); if (complexUser == null) throw new AppException("ComplexUser not found", ApiResultStatusCode.NotFound); diff --git a/Berizco.Repository/Handlers/Complex/GetComplexUsersQueryHandler.cs b/Berizco.Repository/Handlers/Complex/GetComplexUsersQueryHandler.cs new file mode 100644 index 0000000..8152bc0 --- /dev/null +++ b/Berizco.Repository/Handlers/Complex/GetComplexUsersQueryHandler.cs @@ -0,0 +1,32 @@ +using Brizco.Domain.Entities.Complex; +using Microsoft.IdentityModel.Tokens; + +namespace Brizco.Repository.Handlers.Complex; + +public class GetComplexUsersQueryHandler : IRequestHandler> +{ + private readonly IRepositoryWrapper _repositoryWrapper; + + public GetComplexUsersQueryHandler(IRepositoryWrapper repositoryWrapper) + { + _repositoryWrapper = repositoryWrapper; + } + public async Task> Handle(GetComplexUsersQuery request, CancellationToken cancellationToken) + { + if (!request.ComplexId.IsNullOrEmpty() && Guid.TryParse(request.ComplexId, out Guid complexId)) + return await _repositoryWrapper.SetRepository().TableNoTracking + .Where(c => c.ComplexId == complexId) + .OrderByDescending(s => s.CreatedAt) + .Skip(request.Page * 15).Take(15) + .Select(ComplexUserMapper.ProjectToSDto) + .ToListAsync(cancellationToken); + + + return await _repositoryWrapper.SetRepository().TableNoTracking + .OrderByDescending(s => s.CreatedAt) + .Skip(request.Page * 15).Take(15) + .Select(ComplexUserMapper.ProjectToSDto) + .ToListAsync(cancellationToken); + + } +} \ No newline at end of file diff --git a/Berizco.Repository/Handlers/Complex/UpdateComplexUserCommandHandler.cs b/Berizco.Repository/Handlers/Complex/UpdateComplexUserCommandHandler.cs new file mode 100644 index 0000000..0795b44 --- /dev/null +++ b/Berizco.Repository/Handlers/Complex/UpdateComplexUserCommandHandler.cs @@ -0,0 +1,80 @@ +using Brizco.Domain.Entities.Complex; +using Brizco.Domain.Entities.User; +using StackExchange.Redis; + +namespace Brizco.Repository.Handlers.Complex; + +public class UpdateComplexUserCommandHandler : IRequestHandler +{ + private readonly IRepositoryWrapper _repositoryWrapper; + private readonly UserManager _userManager; + private readonly RoleManager _roleManager; + + public UpdateComplexUserCommandHandler(IRepositoryWrapper repositoryWrapper, + UserManager userManager, + RoleManager roleManager) + { + _repositoryWrapper = repositoryWrapper; + _userManager = userManager; + _roleManager = roleManager; + } + + public async Task Handle(UpdateComplexUserCommand request, CancellationToken cancellationToken) + { + try + { + await _repositoryWrapper.BeginTransaction(cancellationToken); + var complexUser = await _repositoryWrapper.SetRepository().TableNoTracking + .FirstOrDefaultAsync(c => c.UserId == request.UserId && c.ComplexId==request.ComplexId , cancellationToken); + if (complexUser == null) + throw new AppException("ComplexUser not found", ApiResultStatusCode.NotFound); + + var complexUserRoles = await _repositoryWrapper.SetRepository() + .TableNoTracking + .Where(cur => cur.ComplexUserId == complexUser.Id) + .ToListAsync(cancellationToken); + + var user = await _userManager.FindByIdAsync(complexUser.UserId.ToString()); + if (user == null) + throw new AppException("User not found", ApiResultStatusCode.NotFound); + + + foreach (var userRole in complexUserRoles.ToList()) + { + if(request.RoleIds.Contains(userRole.RoleId)) + { + complexUserRoles.Remove(userRole); + request.RoleIds.Remove(userRole.RoleId); + } + } + + foreach (var userRole in complexUserRoles) + { + _repositoryWrapper.SetRepository().Delete(userRole); + var role = await _roleManager.FindByIdAsync(userRole.RoleId.ToString()); + var result = await _userManager.RemoveFromRoleAsync(user, role.Name); + if (!result.Succeeded) + throw new AppException(string.Join('|', result.Errors)); + } + + foreach (var roleId in request.RoleIds) + { + var role = await _roleManager.FindByIdAsync(roleId.ToString()); + var result = await _userManager.AddToRoleAsync(user, role.Name); + if (!result.Succeeded) + throw new AppException(string.Join('|', result.Errors)); + var userRole = complexUser.AddRole(role.Id); + _repositoryWrapper.SetRepository().Add(userRole); + } + + await _repositoryWrapper.SaveChangesAsync(cancellationToken); + await _repositoryWrapper.CommitAsync(cancellationToken); + return true; + } + catch (Exception) + { + await _repositoryWrapper.RollBackAsync(cancellationToken); + throw; + } + } +} \ No newline at end of file diff --git a/Berizco.Repository/Migrations/20230919130824_Init.Designer.cs b/Berizco.Repository/Migrations/20230920133908_Init.Designer.cs similarity index 94% rename from Berizco.Repository/Migrations/20230919130824_Init.Designer.cs rename to Berizco.Repository/Migrations/20230920133908_Init.Designer.cs index 539b19e..52e2e65 100644 --- a/Berizco.Repository/Migrations/20230919130824_Init.Designer.cs +++ b/Berizco.Repository/Migrations/20230920133908_Init.Designer.cs @@ -12,7 +12,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; namespace Brizco.Repository.Migrations { [DbContext(typeof(ApplicationContext))] - [Migration("20230919130824_Init")] + [Migration("20230920133908_Init")] partial class Init { /// @@ -106,9 +106,6 @@ namespace Brizco.Repository.Migrations .IsRequired() .HasColumnType("text"); - b.Property("RoleId") - .HasColumnType("uuid"); - b.Property("UserId") .HasColumnType("uuid"); @@ -116,13 +113,56 @@ namespace Brizco.Repository.Migrations b.HasIndex("ComplexId"); - b.HasIndex("RoleId"); - b.HasIndex("UserId"); b.ToTable("ComplexUsers", "public"); }); + modelBuilder.Entity("Brizco.Domain.Entities.Complex.ComplexUserRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ComplexUserId") + .HasColumnType("uuid"); + + b.Property("CreatedAt") + .HasColumnType("timestamp without time zone"); + + b.Property("CreatedBy") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsRemoved") + .HasColumnType("boolean"); + + b.Property("ModifiedAt") + .HasColumnType("timestamp without time zone"); + + b.Property("ModifiedBy") + .IsRequired() + .HasColumnType("text"); + + b.Property("RemovedAt") + .HasColumnType("timestamp without time zone"); + + b.Property("RemovedBy") + .IsRequired() + .HasColumnType("text"); + + b.Property("RoleId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ComplexUserId"); + + b.HasIndex("RoleId"); + + b.ToTable("ComplexUserRoles", "public"); + }); + modelBuilder.Entity("Brizco.Domain.Entities.Shift.Shift", b => { b.Property("Id") @@ -603,6 +643,10 @@ namespace Brizco.Repository.Migrations b.Property("Gender") .HasColumnType("integer"); + b.Property("InternationalId") + .IsRequired() + .HasColumnType("text"); + b.Property("LastName") .IsRequired() .HasColumnType("text"); @@ -786,12 +830,6 @@ namespace Brizco.Repository.Migrations .OnDelete(DeleteBehavior.Restrict) .IsRequired(); - b.HasOne("Brizco.Domain.Entities.User.ApplicationRole", "Role") - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - b.HasOne("Brizco.Domain.Entities.User.ApplicationUser", "User") .WithMany() .HasForeignKey("UserId") @@ -800,11 +838,28 @@ namespace Brizco.Repository.Migrations b.Navigation("Complex"); - b.Navigation("Role"); - b.Navigation("User"); }); + modelBuilder.Entity("Brizco.Domain.Entities.Complex.ComplexUserRole", b => + { + b.HasOne("Brizco.Domain.Entities.Complex.ComplexUser", "ComplexUser") + .WithMany("Roles") + .HasForeignKey("ComplexUserId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Brizco.Domain.Entities.User.ApplicationRole", "Role") + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("ComplexUser"); + + b.Navigation("Role"); + }); + modelBuilder.Entity("Brizco.Domain.Entities.Shift.Shift", b => { b.HasOne("Brizco.Domain.Entities.Complex.Complex", "Complex") @@ -996,6 +1051,11 @@ namespace Brizco.Repository.Migrations b.Navigation("Users"); }); + modelBuilder.Entity("Brizco.Domain.Entities.Complex.ComplexUser", b => + { + b.Navigation("Roles"); + }); + modelBuilder.Entity("Brizco.Domain.Entities.Shift.Shift", b => { b.Navigation("Days"); diff --git a/Berizco.Repository/Migrations/20230919130824_Init.cs b/Berizco.Repository/Migrations/20230920133908_Init.cs similarity index 94% rename from Berizco.Repository/Migrations/20230919130824_Init.cs rename to Berizco.Repository/Migrations/20230920133908_Init.cs index b4abe47..940b0a1 100644 --- a/Berizco.Repository/Migrations/20230919130824_Init.cs +++ b/Berizco.Repository/Migrations/20230920133908_Init.cs @@ -45,6 +45,7 @@ namespace Brizco.Repository.Migrations Id = table.Column(type: "uuid", nullable: false), FirstName = table.Column(type: "text", nullable: false), LastName = table.Column(type: "text", nullable: false), + InternationalId = table.Column(type: "text", nullable: false), BirthDate = table.Column(type: "timestamp without time zone", nullable: false), Gender = table.Column(type: "integer", nullable: false), SignUpStatus = table.Column(type: "integer", nullable: false), @@ -190,6 +191,41 @@ namespace Brizco.Repository.Migrations onDelete: ReferentialAction.Restrict); }); + migrationBuilder.CreateTable( + name: "ComplexUsers", + schema: "public", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + UserId = table.Column(type: "uuid", nullable: false), + ComplexId = table.Column(type: "uuid", nullable: false), + RemovedAt = table.Column(type: "timestamp without time zone", nullable: false), + CreatedAt = table.Column(type: "timestamp without time zone", nullable: false), + CreatedBy = table.Column(type: "text", nullable: false), + IsRemoved = table.Column(type: "boolean", nullable: false), + RemovedBy = table.Column(type: "text", nullable: false), + ModifiedAt = table.Column(type: "timestamp without time zone", nullable: false), + ModifiedBy = table.Column(type: "text", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ComplexUsers", x => x.Id); + table.ForeignKey( + name: "FK_ComplexUsers_Complexes_ComplexId", + column: x => x.ComplexId, + principalSchema: "public", + principalTable: "Complexes", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_ComplexUsers_Users_UserId", + column: x => x.UserId, + principalSchema: "public", + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + migrationBuilder.CreateTable( name: "Logins", schema: "public", @@ -234,49 +270,6 @@ namespace Brizco.Repository.Migrations onDelete: ReferentialAction.Restrict); }); - migrationBuilder.CreateTable( - name: "ComplexUsers", - schema: "public", - columns: table => new - { - Id = table.Column(type: "uuid", nullable: false), - UserId = table.Column(type: "uuid", nullable: false), - ComplexId = table.Column(type: "uuid", nullable: false), - RoleId = table.Column(type: "uuid", nullable: false), - RemovedAt = table.Column(type: "timestamp without time zone", nullable: false), - CreatedAt = table.Column(type: "timestamp without time zone", nullable: false), - CreatedBy = table.Column(type: "text", nullable: false), - IsRemoved = table.Column(type: "boolean", nullable: false), - RemovedBy = table.Column(type: "text", nullable: false), - ModifiedAt = table.Column(type: "timestamp without time zone", nullable: false), - ModifiedBy = table.Column(type: "text", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_ComplexUsers", x => x.Id); - table.ForeignKey( - name: "FK_ComplexUsers_Complexes_ComplexId", - column: x => x.ComplexId, - principalSchema: "public", - principalTable: "Complexes", - principalColumn: "Id", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_ComplexUsers_Roles_RoleId", - column: x => x.RoleId, - principalSchema: "public", - principalTable: "Roles", - principalColumn: "Id", - onDelete: ReferentialAction.Restrict); - table.ForeignKey( - name: "FK_ComplexUsers_Users_UserId", - column: x => x.UserId, - principalSchema: "public", - principalTable: "Users", - principalColumn: "Id", - onDelete: ReferentialAction.Restrict); - }); - migrationBuilder.CreateTable( name: "RoleClaims", schema: "public", @@ -489,6 +482,41 @@ namespace Brizco.Repository.Migrations onDelete: ReferentialAction.Restrict); }); + migrationBuilder.CreateTable( + name: "ComplexUserRoles", + schema: "public", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + ComplexUserId = table.Column(type: "uuid", nullable: false), + RoleId = table.Column(type: "uuid", nullable: false), + RemovedAt = table.Column(type: "timestamp without time zone", nullable: false), + CreatedAt = table.Column(type: "timestamp without time zone", nullable: false), + CreatedBy = table.Column(type: "text", nullable: false), + IsRemoved = table.Column(type: "boolean", nullable: false), + RemovedBy = table.Column(type: "text", nullable: false), + ModifiedAt = table.Column(type: "timestamp without time zone", nullable: false), + ModifiedBy = table.Column(type: "text", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ComplexUserRoles", x => x.Id); + table.ForeignKey( + name: "FK_ComplexUserRoles_ComplexUsers_ComplexUserId", + column: x => x.ComplexUserId, + principalSchema: "public", + principalTable: "ComplexUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_ComplexUserRoles_Roles_RoleId", + column: x => x.RoleId, + principalSchema: "public", + principalTable: "Roles", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + migrationBuilder.CreateTable( name: "ShiftPlanUsers", schema: "public", @@ -530,18 +558,24 @@ namespace Brizco.Repository.Migrations table: "Claims", column: "UserId"); + migrationBuilder.CreateIndex( + name: "IX_ComplexUserRoles_ComplexUserId", + schema: "public", + table: "ComplexUserRoles", + column: "ComplexUserId"); + + migrationBuilder.CreateIndex( + name: "IX_ComplexUserRoles_RoleId", + schema: "public", + table: "ComplexUserRoles", + column: "RoleId"); + migrationBuilder.CreateIndex( name: "IX_ComplexUsers_ComplexId", schema: "public", table: "ComplexUsers", column: "ComplexId"); - migrationBuilder.CreateIndex( - name: "IX_ComplexUsers_RoleId", - schema: "public", - table: "ComplexUsers", - column: "RoleId"); - migrationBuilder.CreateIndex( name: "IX_ComplexUsers_UserId", schema: "public", @@ -673,7 +707,7 @@ namespace Brizco.Repository.Migrations schema: "public"); migrationBuilder.DropTable( - name: "ComplexUsers", + name: "ComplexUserRoles", schema: "public"); migrationBuilder.DropTable( @@ -712,6 +746,10 @@ namespace Brizco.Repository.Migrations name: "UserRoles", schema: "public"); + migrationBuilder.DropTable( + name: "ComplexUsers", + schema: "public"); + migrationBuilder.DropTable( name: "ShiftPlans", schema: "public"); diff --git a/Berizco.Repository/Migrations/ApplicationContextModelSnapshot.cs b/Berizco.Repository/Migrations/ApplicationContextModelSnapshot.cs index 3482684..060d09c 100644 --- a/Berizco.Repository/Migrations/ApplicationContextModelSnapshot.cs +++ b/Berizco.Repository/Migrations/ApplicationContextModelSnapshot.cs @@ -103,9 +103,6 @@ namespace Brizco.Repository.Migrations .IsRequired() .HasColumnType("text"); - b.Property("RoleId") - .HasColumnType("uuid"); - b.Property("UserId") .HasColumnType("uuid"); @@ -113,13 +110,56 @@ namespace Brizco.Repository.Migrations b.HasIndex("ComplexId"); - b.HasIndex("RoleId"); - b.HasIndex("UserId"); b.ToTable("ComplexUsers", "public"); }); + modelBuilder.Entity("Brizco.Domain.Entities.Complex.ComplexUserRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ComplexUserId") + .HasColumnType("uuid"); + + b.Property("CreatedAt") + .HasColumnType("timestamp without time zone"); + + b.Property("CreatedBy") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsRemoved") + .HasColumnType("boolean"); + + b.Property("ModifiedAt") + .HasColumnType("timestamp without time zone"); + + b.Property("ModifiedBy") + .IsRequired() + .HasColumnType("text"); + + b.Property("RemovedAt") + .HasColumnType("timestamp without time zone"); + + b.Property("RemovedBy") + .IsRequired() + .HasColumnType("text"); + + b.Property("RoleId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ComplexUserId"); + + b.HasIndex("RoleId"); + + b.ToTable("ComplexUserRoles", "public"); + }); + modelBuilder.Entity("Brizco.Domain.Entities.Shift.Shift", b => { b.Property("Id") @@ -600,6 +640,10 @@ namespace Brizco.Repository.Migrations b.Property("Gender") .HasColumnType("integer"); + b.Property("InternationalId") + .IsRequired() + .HasColumnType("text"); + b.Property("LastName") .IsRequired() .HasColumnType("text"); @@ -783,12 +827,6 @@ namespace Brizco.Repository.Migrations .OnDelete(DeleteBehavior.Restrict) .IsRequired(); - b.HasOne("Brizco.Domain.Entities.User.ApplicationRole", "Role") - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - b.HasOne("Brizco.Domain.Entities.User.ApplicationUser", "User") .WithMany() .HasForeignKey("UserId") @@ -797,11 +835,28 @@ namespace Brizco.Repository.Migrations b.Navigation("Complex"); - b.Navigation("Role"); - b.Navigation("User"); }); + modelBuilder.Entity("Brizco.Domain.Entities.Complex.ComplexUserRole", b => + { + b.HasOne("Brizco.Domain.Entities.Complex.ComplexUser", "ComplexUser") + .WithMany("Roles") + .HasForeignKey("ComplexUserId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Brizco.Domain.Entities.User.ApplicationRole", "Role") + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("ComplexUser"); + + b.Navigation("Role"); + }); + modelBuilder.Entity("Brizco.Domain.Entities.Shift.Shift", b => { b.HasOne("Brizco.Domain.Entities.Complex.Complex", "Complex") @@ -993,6 +1048,11 @@ namespace Brizco.Repository.Migrations b.Navigation("Users"); }); + modelBuilder.Entity("Brizco.Domain.Entities.Complex.ComplexUser", b => + { + b.Navigation("Roles"); + }); + modelBuilder.Entity("Brizco.Domain.Entities.Shift.Shift", b => { b.Navigation("Days"); diff --git a/Berizco.Repository/Repositories/Base/RepositoryWrapper.cs b/Berizco.Repository/Repositories/Base/RepositoryWrapper.cs index b61134f..60dd9ba 100644 --- a/Berizco.Repository/Repositories/Base/RepositoryWrapper.cs +++ b/Berizco.Repository/Repositories/Base/RepositoryWrapper.cs @@ -1,6 +1,4 @@ -using Brizco.Repository.Models; -using Brizco.Repository.Repositories.UnitOfWork; -using Microsoft.EntityFrameworkCore.ChangeTracking; +using Microsoft.EntityFrameworkCore.ChangeTracking; using Microsoft.EntityFrameworkCore.Storage; namespace Brizco.Repository.Repositories.Base; @@ -14,6 +12,7 @@ public class RepositoryWrapper : IRepositoryWrapper } public IBaseRepository SetRepository() where T : ApiEntity => new BaseRepository(_context); + public async Task RollBackAsync(CancellationToken cancellationToken) { @@ -27,9 +26,9 @@ public class RepositoryWrapper : IRepositoryWrapper throw new ArgumentNullException(nameof(_currentTransaction)); await _currentTransaction.CommitAsync(cancellationToken); } - public async Task BeginTransaction() + public async Task BeginTransaction(CancellationToken cancellationToken) { - _currentTransaction = await _context.Database.BeginTransactionAsync(); + _currentTransaction = await _context.Database.BeginTransactionAsync(cancellationToken); } public async Task SaveChangesAsync(CancellationToken cancellationToken = default) { diff --git a/Brizco.Core/Brizco.Core.csproj b/Brizco.Core/Brizco.Core.csproj index 81ebdf8..28d732b 100644 --- a/Brizco.Core/Brizco.Core.csproj +++ b/Brizco.Core/Brizco.Core.csproj @@ -16,7 +16,6 @@ - @@ -25,12 +24,14 @@ + + @@ -43,6 +44,7 @@ + diff --git a/Brizco.Core/BaseServices/Abstracts/IAccountService.cs b/Brizco.Core/CoreServices/Abstracts/IAccountService.cs similarity index 93% rename from Brizco.Core/BaseServices/Abstracts/IAccountService.cs rename to Brizco.Core/CoreServices/Abstracts/IAccountService.cs index bf24bc4..e81c9aa 100644 --- a/Brizco.Core/BaseServices/Abstracts/IAccountService.cs +++ b/Brizco.Core/CoreServices/Abstracts/IAccountService.cs @@ -1,4 +1,4 @@ -namespace Brizco.Core.BaseServices.Abstracts; +namespace Brizco.Core.CoreServices.Abstracts; public interface IAccountService : IScopedDependency { diff --git a/Brizco.Core/CoreServices/Abstracts/IPageService.cs b/Brizco.Core/CoreServices/Abstracts/IPageService.cs new file mode 100644 index 0000000..25986b6 --- /dev/null +++ b/Brizco.Core/CoreServices/Abstracts/IPageService.cs @@ -0,0 +1,6 @@ +namespace Brizco.Core.CoreServices.Abstracts; + +public interface IPageService +{ + +} \ No newline at end of file diff --git a/Brizco.Core/BaseServices/AccountService.cs b/Brizco.Core/CoreServices/AccountService.cs similarity index 88% rename from Brizco.Core/BaseServices/AccountService.cs rename to Brizco.Core/CoreServices/AccountService.cs index a0cc9ae..b406152 100644 --- a/Brizco.Core/BaseServices/AccountService.cs +++ b/Brizco.Core/CoreServices/AccountService.cs @@ -1,12 +1,4 @@ -using Brizco.Common.Extensions; -using Brizco.Domain.CommandQueries.Commands; -using Brizco.Domain.Dtos.RequestDtos; -using Brizco.Domain.Enums; -using MediatR; -using Microsoft.IdentityModel.Tokens; -using System.Threading; - -namespace Brizco.Core.BaseServices; +namespace Brizco.Core.CoreServices; public class AccountService : IAccountService { @@ -18,6 +10,7 @@ public class AccountService : IAccountService private readonly IRepositoryWrapper _repositoryWrapper; private readonly ISmsService _smsService; private readonly IComplexService _complexService; + private readonly IUserService _userService; public AccountService( UserManager userManager, @@ -26,7 +19,8 @@ public class AccountService : IAccountService ICurrentUserService currentUserService, IRepositoryWrapper repositoryWrapper, ISmsService smsService, - IComplexService complexService) + IComplexService complexService, + IUserService userService) { _userManager = userManager; _userSignInManager = userSignInManager; @@ -35,6 +29,7 @@ public class AccountService : IAccountService _repositoryWrapper = repositoryWrapper; _smsService = smsService; _complexService = complexService; + _userService = userService; } @@ -76,17 +71,8 @@ public class AccountService : IAccountService throw new AppException("شماره تلفن ارسالی اشتباه است"); var user = await _userManager.FindByNameAsync(newPhoneNumber); if (user == null) - { - user = new ApplicationUser - { - UserName = phoneNumber, - PhoneNumber = phoneNumber, - SignUpStatus = SignUpStatus.StartSignUp - }; - var result = await _userManager.CreateAsync(user); - if (!result.Succeeded) - throw new AppException(string.Join('|', result.Errors)); - } + user = await _userService.CreateUserAsync(phoneNumber); + var token = await _userManager.GenerateTwoFactorTokenAsync(user, "Phone"); await _smsService.SendVerifyCodeAsync(newPhoneNumber, token); return user.SignUpStatus; @@ -121,7 +107,7 @@ public class AccountService : IAccountService user.PhoneNumberConfirmed = true; user.SignUpStatus = SignUpStatus.PhoneNumberVerified; var result = await _userManager.UpdateAsync(user); - if(!result.Succeeded) + if (!result.Succeeded) throw new AppException(string.Join('|', result.Errors)); } return await CompleteLogin(user, cancellationToken); @@ -171,11 +157,18 @@ public class AccountService : IAccountService .TableNoTracking .Where(mcu => mcu.UserId == user.Id) .OrderByDescending(o => o.CreatedAt) - .ToListAsync(cancellationToken); - var lastComplex = complexUsers.FirstOrDefault(); + .FirstOrDefaultAsync(cancellationToken); + if(complexUsers == null) + return await _jwtService.Generate(user); + + var complexUserRoles = await _repositoryWrapper.SetRepository() + .TableNoTracking + .Where(c=>c.ComplexUserId==complexUsers.Id) + .OrderByDescending(o => o.CreatedAt) + .FirstOrDefaultAsync(cancellationToken); AccessToken jwt; - if (lastComplex != null) - jwt = await _jwtService.Generate(user, lastComplex.ComplexId, lastComplex.RoleId); + if (complexUserRoles != null) + jwt = await _jwtService.Generate(user, complexUsers.ComplexId, complexUserRoles.RoleId); else jwt = await _jwtService.Generate(user); diff --git a/Brizco.Core/EntityServices/Abstracts/IUserService.cs b/Brizco.Core/EntityServices/Abstracts/IUserService.cs new file mode 100644 index 0000000..d33dd59 --- /dev/null +++ b/Brizco.Core/EntityServices/Abstracts/IUserService.cs @@ -0,0 +1,19 @@ +namespace Brizco.Core.EntityServices.Abstracts; + +public interface IUserService : IScopedDependency +{ + Task> GetUsersAsync(int page = 0, CancellationToken cancellationToken = default); + Task GetUserAsync(Guid userId); + Task CreateUserAsync(string phoneNumber); + Task CreateUserAsync(UserActionRequestDto request, CancellationToken cancellationToken); + Task EditUserAsync(UserActionRequestDto request, CancellationToken cancellationToken); + Task EditUserProfileAsync(UserActionRequestDto request, CancellationToken cancellationToken); + Task RemoveUserAsync(Guid userId, CancellationToken cancellationToken); + + + Task> GetRolesAsync(int page = 0, CancellationToken cancellationToken = default); + Task GetRoleAsync(Guid roleId); + Task CreateRoleAsync(RoleActionRequestDto request); + Task EditRoleAsync(RoleActionRequestDto request); + Task RemoveRoleAsync(Guid roleId); +} \ No newline at end of file diff --git a/Brizco.Core/EntityServices/ComplexService.cs b/Brizco.Core/EntityServices/ComplexService.cs index 1579870..7a1e1e6 100644 --- a/Brizco.Core/EntityServices/ComplexService.cs +++ b/Brizco.Core/EntityServices/ComplexService.cs @@ -36,7 +36,7 @@ public class ComplexService : IComplexService foreach (var claim in ApplicationClaims.ManagerClaims) await _roleManager.AddClaimAsync(managerRole, claim); - var complexUser = await _sender.Send(new CreateComplexUserCommand(complex.Id, managerUserId, managerRole.Id), cancellationToken); + var complexUser = await _sender.Send(new CreateComplexUserCommand(complex.Id, managerUserId, new List{ managerRole.Id }), cancellationToken); return complex; } diff --git a/Brizco.Core/EntityServices/UserService.cs b/Brizco.Core/EntityServices/UserService.cs new file mode 100644 index 0000000..e86a493 --- /dev/null +++ b/Brizco.Core/EntityServices/UserService.cs @@ -0,0 +1,287 @@ +using System.Security.Claims; +using System.Threading; +using Brizco.Domain.CommandQueries.Queries; +using Brizco.Domain.Mappers; +using Mapster; + +namespace Brizco.Core.EntityServices; + +public class UserService : IUserService +{ + private readonly ICurrentUserService _currentUserService; + private readonly UserManager _userManager; + private readonly RoleManager _roleManager; + private readonly ISender _sender; + + public UserService(ICurrentUserService currentUserService, + UserManager userManager, + RoleManager roleManager, + ISender sender) + { + _currentUserService = currentUserService; + _userManager = userManager; + _roleManager = roleManager; + _sender = sender; + } + + public async Task> GetUsersAsync(int page = 0, CancellationToken cancellationToken = default) + { + if (_currentUserService.ComplexId.IsNullOrEmpty()) + throw new AppException("Wrong authorize token , ComplexId needed"); + if (!Guid.TryParse(_currentUserService.ComplexId, out Guid complexId)) + throw new AppException("Wrong authorize token , ComplexId needed"); + var complexUsers = await _sender.Send(new GetComplexUsersQuery(complexId.ToString(), page),cancellationToken); + + return complexUsers; + } + + public async Task GetUserAsync(Guid userId) + => (await _userManager.FindByIdAsync(userId.ToString())).AdaptToSDto(); + + public async Task CreateUserAsync(string phoneNumber) + { + var user = new ApplicationUser + { + UserName = phoneNumber, + PhoneNumber = phoneNumber, + SignUpStatus = SignUpStatus.StartSignUp + }; + var result = await _userManager.CreateAsync(user); + if (!result.Succeeded) + throw new AppException(string.Join('|', result.Errors)); + return user; + } + + public async Task CreateUserAsync(UserActionRequestDto request, CancellationToken cancellationToken) + { + if (_currentUserService.ComplexId.IsNullOrEmpty()) + throw new AppException("Wrong authorize token , ComplexId needed"); + if (!Guid.TryParse(_currentUserService.ComplexId, out Guid complexId)) + throw new AppException("Wrong authorize token , ComplexId needed"); + + var user = new ApplicationUser + { + UserName = request.PhoneNumber, + PhoneNumber = request.PhoneNumber, + FirstName = request.FirstName, + LastName = request.LastName, + InternationalId = request.InternationalId, + BirthDate = request.BirthDate, + Gender = request.Gender, + SignUpStatus = SignUpStatus.SignUpCompleted + }; + if (!request.Password.IsNullOrEmpty()) + { + var result = await _userManager.CreateAsync(user, request.Password); + if (!result.Succeeded) + throw new AppException(string.Join('|', result.Errors)); + } + else + { + var result = await _userManager.CreateAsync(user); + if (!result.Succeeded) + throw new AppException(string.Join('|', result.Errors)); + } + + await _sender.Send(new CreateComplexUserCommand(complexId, user.Id, request.RoleIds), cancellationToken); + return user; + } + + public async Task EditUserAsync(UserActionRequestDto request, CancellationToken cancellationToken) + { + if (_currentUserService.ComplexId.IsNullOrEmpty()) + throw new AppException("Wrong authorize token , ComplexId needed"); + if (!Guid.TryParse(_currentUserService.ComplexId, out Guid complexId)) + throw new AppException("Wrong authorize token , ComplexId needed"); + if (_currentUserService.UserId == null) + throw new AppException("Wrong authorize token , UserId needed"); + + var user = await _userManager.FindByIdAsync(_currentUserService.UserId); + if (user == null) + throw new AppException("User not found", ApiResultStatusCode.NotFound); + user.LastName = request.LastName; + user.FirstName = request.FirstName; + user.UserName = request.PhoneNumber; + user.PhoneNumber = request.PhoneNumber; + user.FirstName = request.FirstName; + user.LastName = request.LastName; + user.InternationalId = request.InternationalId; + user.BirthDate = request.BirthDate; + user.Gender = request.Gender; + + var result = await _userManager.UpdateAsync(user); + if (!result.Succeeded) + throw new AppException(string.Join('|', result.Errors)); + if (!request.Password.IsNullOrEmpty()) + { + if (await _userManager.HasPasswordAsync(user)) + await _userManager.RemovePasswordAsync(user); + + var addPassResult = await _userManager.AddPasswordAsync(user, request.Password); + if (!addPassResult.Succeeded) + throw new AppException(string.Join('|', addPassResult.Errors)); + } + + await _sender.Send(new UpdateComplexUserCommand(user.Id, complexId, request.RoleIds), cancellationToken); + return true; + } + + public async Task EditUserProfileAsync(UserActionRequestDto request, CancellationToken cancellationToken) + { + if (_currentUserService.UserId == null) + throw new AppException("Wrong authorize token , UserId needed"); + + var user = await _userManager.FindByIdAsync(_currentUserService.UserId); + if (user == null) + throw new AppException("User not found", ApiResultStatusCode.NotFound); + user.LastName = request.LastName; + user.FirstName = request.FirstName; + user.UserName = request.PhoneNumber; + user.PhoneNumber = request.PhoneNumber; + user.FirstName = request.FirstName; + user.LastName = request.LastName; + user.InternationalId = request.InternationalId; + user.BirthDate = request.BirthDate; + user.Gender = request.Gender; + + var result = await _userManager.UpdateAsync(user); + if (!result.Succeeded) + throw new AppException(string.Join('|', result.Errors)); + if (!request.Password.IsNullOrEmpty()) + { + if (await _userManager.HasPasswordAsync(user)) + await _userManager.RemovePasswordAsync(user); + + var addPassResult = await _userManager.AddPasswordAsync(user, request.Password); + if (!addPassResult.Succeeded) + throw new AppException(string.Join('|', addPassResult.Errors)); + } + + return true; + } + + public async Task RemoveUserAsync(Guid userId, CancellationToken cancellationToken) + { + if (_currentUserService.ComplexId.IsNullOrEmpty()) + throw new AppException("Wrong authorize token , ComplexId needed"); + if (!Guid.TryParse(_currentUserService.ComplexId, out Guid complexId)) + throw new AppException("Wrong authorize token , ComplexId needed"); + var user = await _userManager.FindByIdAsync(userId.ToString()); + if (user == null) + throw new AppException("User not found", ApiResultStatusCode.NotFound); + var removeResult = await _userManager.DeleteAsync(user); + if (!removeResult.Succeeded) + throw new AppException(string.Join('|', removeResult.Errors)); + await _sender.Send(new DeleteComplexUserCommand(userId, complexId), cancellationToken); + return true; + } + + + + public async Task> GetRolesAsync(int page = 0,CancellationToken cancellationToken = default) + { + if (_currentUserService.ComplexId.IsNullOrEmpty()) + throw new AppException("Wrong authorize token , ComplexId needed"); + if (!Guid.TryParse(_currentUserService.ComplexId, out Guid complexId)) + throw new AppException("Wrong authorize token , ComplexId needed"); + + var roles = await _roleManager.Roles + .Where(r=>r.ComplexId==complexId) + .Skip(page * 15) + .Take(15) + .ToListAsync(cancellationToken); + return roles; + } + + public async Task GetRoleAsync(Guid roleId) + { + var role = (await _roleManager.FindByIdAsync(roleId.ToString())); + if (role == null) + throw new AppException("نقش پیدا نشد",ApiResultStatusCode.NotFound); + + var roleDto = role.Adapt(); + roleDto.Permissions = (await _roleManager.GetClaimsAsync(role)) + .Where(c => c.Type == CustomClaimType.Permission) + .Select(c => c.Value) + .ToList(); + + return roleDto; + } + + public async Task CreateRoleAsync(RoleActionRequestDto request) + { + if (_currentUserService.ComplexId.IsNullOrEmpty()) + throw new AppException("Wrong authorize token , ComplexId needed"); + if (!Guid.TryParse(_currentUserService.ComplexId, out Guid complexId)) + throw new AppException("Wrong authorize token , ComplexId wrong"); + if (request.EnglishName.IsNullOrEmpty()) + throw new AppException("لطفا نام انگلیسی را وارد کنید"); + var applicationRole = new ApplicationRole + { + ComplexId = complexId, + EnglishName = request.EnglishName, + PersianName = request.PersianName, + Description = request.Description, + Name = $"{request.EnglishName}_{complexId.ToString()}" + }; + var createRoleResult = await _roleManager.CreateAsync(applicationRole); + if (!createRoleResult.Succeeded) + throw new AppException(string.Join('|', createRoleResult.Errors)); + + foreach (var claim in request.Permissions) + await _roleManager.AddClaimAsync(applicationRole, new Claim(CustomClaimType.Permission, claim)); + return applicationRole; + } + + public async Task EditRoleAsync(RoleActionRequestDto request) + { + if (_currentUserService.ComplexId.IsNullOrEmpty()) + throw new AppException("Wrong authorize token , ComplexId needed"); + if (!Guid.TryParse(_currentUserService.ComplexId, out Guid complexId)) + throw new AppException("Wrong authorize token , ComplexId wrong"); + if (request.EnglishName.IsNullOrEmpty()) + throw new AppException("لطفا نام انگلیسی را وارد کنید"); + var applicationRole = await _roleManager.FindByIdAsync(request.RoleId.ToString()); + if (applicationRole == null) + throw new AppException("نقش پیدا نشد"); + + applicationRole.ComplexId = complexId; + applicationRole.EnglishName = request.EnglishName; + applicationRole.PersianName = request.PersianName; + applicationRole.Description = request.Description; + applicationRole.Name = $"{request.EnglishName}_{complexId.ToString()}"; + + var createRoleResult = await _roleManager.UpdateAsync(applicationRole); + if (!createRoleResult.Succeeded) + throw new AppException(string.Join('|', createRoleResult.Errors)); + var roleClaims = (await _roleManager.GetClaimsAsync(applicationRole)).Where(c => c.Type == CustomClaimType.Permission).ToList(); + foreach (var roleClaim in roleClaims.ToList()) + { + if (request.Permissions.Contains(roleClaim.Value)) + { + roleClaims.Remove(roleClaim); + request.Permissions.Remove(roleClaim.Value); + } + } + + foreach (var claim in request.Permissions) + await _roleManager.AddClaimAsync(applicationRole, new Claim(CustomClaimType.Permission, claim)); + + foreach (var claim in roleClaims) + await _roleManager.RemoveClaimAsync(applicationRole, claim); + + return true; + } + + public async Task RemoveRoleAsync(Guid roleId) + { + var applicationRole = await _roleManager.FindByIdAsync(roleId.ToString()); + if (applicationRole == null) + throw new AppException("User not found", ApiResultStatusCode.NotFound); + var removeResult = await _roleManager.DeleteAsync(applicationRole); + if (!removeResult.Succeeded) + throw new AppException(string.Join('|', removeResult.Errors)); + return true; + } + +} \ No newline at end of file diff --git a/Brizco.Domain/Brizco.Domain.csproj b/Brizco.Domain/Brizco.Domain.csproj index e31a5b5..ca32ffc 100644 --- a/Brizco.Domain/Brizco.Domain.csproj +++ b/Brizco.Domain/Brizco.Domain.csproj @@ -66,6 +66,7 @@ + diff --git a/Brizco.Domain/CommandQueries/Commands/ComplexCommands.cs b/Brizco.Domain/CommandQueries/Commands/ComplexCommands.cs index e6e2c1c..db19385 100644 --- a/Brizco.Domain/CommandQueries/Commands/ComplexCommands.cs +++ b/Brizco.Domain/CommandQueries/Commands/ComplexCommands.cs @@ -3,14 +3,19 @@ public sealed record CreateComplexCommand(string Name, string Address, string SupportPhone) : IRequest; -public sealed record CreateComplexUserCommand(Guid ComplexId,Guid UserId,Guid RoleId) - : IRequest; - -public sealed record DeleteComplexUserCommand(Guid ComplexUserId) - : IRequest; - public sealed record UpdateComplexCommand(Guid Id, string Name, string Address, string SupportPhone) : IRequest; public sealed record DeleteComplexCommand(Guid Id) + : IRequest; + + + +public sealed record CreateComplexUserCommand(Guid ComplexId, Guid UserId, List RoleIds) + : IRequest; + +public sealed record UpdateComplexUserCommand(Guid UserId,Guid ComplexId,List RoleIds) + : IRequest; + +public sealed record DeleteComplexUserCommand(Guid UserId, Guid ComplexId) : IRequest; \ No newline at end of file diff --git a/Brizco.Domain/CommandQueries/Commands/TaskCommands.cs b/Brizco.Domain/CommandQueries/Commands/TaskCommands.cs index 0bc5216..b59d790 100644 --- a/Brizco.Domain/CommandQueries/Commands/TaskCommands.cs +++ b/Brizco.Domain/CommandQueries/Commands/TaskCommands.cs @@ -1,6 +1,4 @@ -using Brizco.Domain.Entities.Shift; - -namespace Brizco.Domain.CommandQueries.Commands; +namespace Brizco.Domain.CommandQueries.Commands; public sealed record CreateTaskCommand(TaskType Type, string Title, @@ -15,7 +13,8 @@ int Amount, PurchaseAmountType AmountType, List Users, List Shifts, -List Roles) : IRequest; +List Roles, +List Days) : IRequest; public sealed record UpdateTaskCommand(Guid Id, TaskType Type, @@ -31,7 +30,8 @@ public sealed record UpdateTaskCommand(Guid Id, PurchaseAmountType AmountType, List Users, List Shifts, - List Roles) : IRequest; + List Roles, + List Days) : IRequest; public sealed record DeleteTaskCommand(Guid Id) diff --git a/Brizco.Domain/CommandQueries/Queries/ComplexQueries.cs b/Brizco.Domain/CommandQueries/Queries/ComplexQueries.cs index 1ba24a7..2faead2 100644 --- a/Brizco.Domain/CommandQueries/Queries/ComplexQueries.cs +++ b/Brizco.Domain/CommandQueries/Queries/ComplexQueries.cs @@ -4,4 +4,8 @@ public sealed record GetComplexesQuery(int Page = 0) : IRequest>; public sealed record GetComplexQuery(Guid Id) : - IRequest; \ No newline at end of file + IRequest; + + +public sealed record GetComplexUsersQuery(string ComplexId,int Page = 0) : + IRequest>; \ No newline at end of file diff --git a/Brizco.Domain/Dtos/RequestDtos/RoleActionRequestDto.cs b/Brizco.Domain/Dtos/RequestDtos/RoleActionRequestDto.cs new file mode 100644 index 0000000..19db715 --- /dev/null +++ b/Brizco.Domain/Dtos/RequestDtos/RoleActionRequestDto.cs @@ -0,0 +1,11 @@ +namespace Brizco.Domain.Dtos.RequestDtos; + +public class RoleActionRequestDto +{ + public Guid RoleId { get; set; } + public Guid ComplexId { get; set; } + public string Description { get; set; } = string.Empty; + public string EnglishName { get; set; } = string.Empty; + public string PersianName { get; set; } = string.Empty; + public List Permissions { get; set; } = new(); +} \ No newline at end of file diff --git a/Brizco.Domain/Dtos/RequestDtos/UserActionRequestDto.cs b/Brizco.Domain/Dtos/RequestDtos/UserActionRequestDto.cs new file mode 100644 index 0000000..0be160e --- /dev/null +++ b/Brizco.Domain/Dtos/RequestDtos/UserActionRequestDto.cs @@ -0,0 +1,17 @@ +namespace Brizco.Domain.Dtos.RequestDtos; + +public class UserActionRequestDto +{ + public string PhoneNumber { get; set; } = string.Empty; + public string FirstName { get; set; } = string.Empty; + public string LastName { get; set; } = string.Empty; + public DateTime BirthDate { get; set; } + public Gender Gender { get; set; } + public string InternationalId { get; set; } = string.Empty; + public string Password { get; set; } = string.Empty; + public List RoleIds { get; set; } = new(); + + + public string SelectedRoleName { get; set; } = string.Empty; + public string SelectedComplexName { get; set; } = string.Empty; +} \ No newline at end of file diff --git a/Brizco.Domain/Dtos/SmallDtos/ApplicationUserSDto.cs b/Brizco.Domain/Dtos/SmallDtos/ApplicationUserSDto.cs index 2620341..0d1283f 100644 --- a/Brizco.Domain/Dtos/SmallDtos/ApplicationUserSDto.cs +++ b/Brizco.Domain/Dtos/SmallDtos/ApplicationUserSDto.cs @@ -12,4 +12,5 @@ public class ApplicationUserSDto : BaseDto public SignUpStatus SignUpStatus { get; set; } public string SelectedRoleName { get; set; } = string.Empty; public string SelectedComplexName { get; set; } = string.Empty; + public string InternationalId { get; set; } = string.Empty; } \ No newline at end of file diff --git a/Brizco.Domain/Dtos/SmallDtos/ComplexUserRoleSDto.cs b/Brizco.Domain/Dtos/SmallDtos/ComplexUserRoleSDto.cs new file mode 100644 index 0000000..874b3b0 --- /dev/null +++ b/Brizco.Domain/Dtos/SmallDtos/ComplexUserRoleSDto.cs @@ -0,0 +1,14 @@ +using Brizco.Domain.Entities.Complex; + +namespace Brizco.Domain.Dtos.SmallDtos; + +public class ComplexUserRoleSDto : BaseDto +{ + public Guid RoleId { get; set; } + public Guid ComplexUserId { get; set; } + + + public Guid UserId { get; set; } + public Guid ComplexId { get; set; } + +} \ No newline at end of file diff --git a/Brizco.Domain/Dtos/SmallDtos/ComplexUserSDto.cs b/Brizco.Domain/Dtos/SmallDtos/ComplexUserSDto.cs index 64c6ed3..5e83e63 100644 --- a/Brizco.Domain/Dtos/SmallDtos/ComplexUserSDto.cs +++ b/Brizco.Domain/Dtos/SmallDtos/ComplexUserSDto.cs @@ -4,6 +4,11 @@ namespace Brizco.Domain.Dtos.SmallDtos; public class ComplexUserSDto : BaseDto { + public string FirstName { get; set; } = string.Empty; + public string LastName { get; set; } = string.Empty; + public string InternationalId { get; set; } = string.Empty; + public string ComplexName { get; set; } = string.Empty; + public Guid UserId { get; set; } public Guid ComplexId { get; set; } } \ No newline at end of file diff --git a/Brizco.Domain/Entities/Complex/Aggregate.Complex.cs b/Brizco.Domain/Entities/Complex/Aggregate.Complex.cs index 53613ee..7ca04e3 100644 --- a/Brizco.Domain/Entities/Complex/Aggregate.Complex.cs +++ b/Brizco.Domain/Entities/Complex/Aggregate.Complex.cs @@ -7,10 +7,24 @@ public partial class Complex return new Complex(name,address,supportPhone); } - public ComplexUser AddComplexUser(Guid userId, Guid roleId) + public ComplexUser AddComplexUser(Guid userId) { - var complex = new ComplexUser(userId, this.Id, roleId); + var complex = ComplexUser.Create(userId, this.Id); this.Users.Add(complex); return complex; } -} \ No newline at end of file +} +public partial class ComplexUser +{ + public static ComplexUser Create(Guid userId,Guid complexId) + { + return new ComplexUser(userId,complexId); + } + + public ComplexUserRole AddRole(Guid roleId) + { + var role = new ComplexUserRole(this.Id, roleId); + this.Roles.Add(role); + return role; + } +} diff --git a/Brizco.Domain/Entities/Complex/ComplexUser.cs b/Brizco.Domain/Entities/Complex/ComplexUser.cs index 8f4a865..a7d3dd7 100644 --- a/Brizco.Domain/Entities/Complex/ComplexUser.cs +++ b/Brizco.Domain/Entities/Complex/ComplexUser.cs @@ -3,24 +3,23 @@ namespace Brizco.Domain.Entities.Complex; [AdaptTwoWays("[name]SDto", IgnoreAttributes = new[] { typeof(AdaptIgnoreAttribute) }, MapType = MapType.Map | MapType.MapToTarget | MapType.Projection)] [GenerateMapper] -public class ComplexUser : ApiEntity +public partial class ComplexUser : ApiEntity { public ComplexUser() { } - public ComplexUser(Guid userId, Guid complexId, Guid roleId) + public ComplexUser(Guid userId, Guid complexId) { UserId = userId; ComplexId = complexId; - RoleId = roleId; } public Guid UserId { get; internal set; } public Guid ComplexId { get; internal set; } - public Guid RoleId { get; internal set; } - public ApplicationRole? Role { get; internal set; } public ApplicationUser? User { get; internal set; } public Complex? Complex { get; internal set; } + + public List Roles { get; internal set; } = new(); } \ No newline at end of file diff --git a/Brizco.Domain/Entities/Complex/ComplexUserRole.cs b/Brizco.Domain/Entities/Complex/ComplexUserRole.cs new file mode 100644 index 0000000..7a7685b --- /dev/null +++ b/Brizco.Domain/Entities/Complex/ComplexUserRole.cs @@ -0,0 +1,22 @@ +using Brizco.Domain.Entities.User; + +namespace Brizco.Domain.Entities.Complex; +[AdaptTwoWays("[name]SDto", IgnoreAttributes = new[] { typeof(AdaptIgnoreAttribute) }, MapType = MapType.Map | MapType.MapToTarget | MapType.Projection)] +[GenerateMapper] +public class ComplexUserRole : ApiEntity +{ + public ComplexUserRole() + { + + } + public ComplexUserRole(Guid complexUserId, Guid roleId) + { + ComplexUserId = complexUserId; + RoleId = roleId; + } + public Guid ComplexUserId { get; internal set; } + public ComplexUser? ComplexUser { get; internal set; } + + public Guid RoleId { get; internal set; } + public ApplicationRole? Role { get; internal set; } +} \ No newline at end of file diff --git a/Brizco.Domain/Entities/Shift/ShiftDay.cs b/Brizco.Domain/Entities/Shift/ShiftDay.cs index db5c8af..f31bf4d 100644 --- a/Brizco.Domain/Entities/Shift/ShiftDay.cs +++ b/Brizco.Domain/Entities/Shift/ShiftDay.cs @@ -10,10 +10,11 @@ public class ShiftDay : ApiEntity internal ShiftDay(DayOfWeek dayOfWeek,Guid shiftId) { DayOfWeek = dayOfWeek; + ShiftId = shiftId; } - public DayOfWeek DayOfWeek { get; private set; } + public DayOfWeek DayOfWeek { get; internal set; } - public Guid ShiftId { get; private set; } - public Shift? Shift { get; private set; } + public Guid ShiftId { get; internal set; } + public Shift? Shift { get; internal set; } } \ No newline at end of file diff --git a/Brizco.Domain/Entities/Task/Aggregate.Task.cs b/Brizco.Domain/Entities/Task/Aggregate.Task.cs index 7aa6db3..357dda5 100644 --- a/Brizco.Domain/Entities/Task/Aggregate.Task.cs +++ b/Brizco.Domain/Entities/Task/Aggregate.Task.cs @@ -32,6 +32,15 @@ public partial class Task complexId); } + + public TaskDay SetDay(DayOfWeek dayOfWeek) + { + var taskDay = new TaskDay(dayOfWeek, Id); + Days.Add(taskDay); + return taskDay; + } + + public void AddShift(params Guid[] shiftIds) { foreach (var shiftId in shiftIds) diff --git a/Brizco.Domain/Entities/Task/Task.cs b/Brizco.Domain/Entities/Task/Task.cs index 9a9b8a3..1a31b79 100644 --- a/Brizco.Domain/Entities/Task/Task.cs +++ b/Brizco.Domain/Entities/Task/Task.cs @@ -60,5 +60,7 @@ public partial class Task : ApiEntity public List Shifts { get; internal set; } = new(); + public List Days { get; internal set; } + public List Roles { get; internal set; } = new(); } diff --git a/Brizco.Domain/Entities/Task/TaskDay.cs b/Brizco.Domain/Entities/Task/TaskDay.cs new file mode 100644 index 0000000..d90b858 --- /dev/null +++ b/Brizco.Domain/Entities/Task/TaskDay.cs @@ -0,0 +1,20 @@ +namespace Brizco.Domain.Entities.Task; + +public class TaskDay +{ + public TaskDay() + { + + } + + internal TaskDay(DayOfWeek dayOfWeek, Guid shiftId) + { + DayOfWeek = dayOfWeek; + TaskId = shiftId; + } + + public DayOfWeek DayOfWeek { get; internal set; } + + public Guid TaskId { get; internal set; } + public Task? Task { get; internal set; } +} \ No newline at end of file diff --git a/Brizco.Domain/Entities/User/ApplicationUser.cs b/Brizco.Domain/Entities/User/ApplicationUser.cs index 2d60db9..a7c1dda 100644 --- a/Brizco.Domain/Entities/User/ApplicationUser.cs +++ b/Brizco.Domain/Entities/User/ApplicationUser.cs @@ -1,9 +1,12 @@ namespace Brizco.Domain.Entities.User; +[AdaptTwoWays("[name]SDto", IgnoreAttributes = new[] { typeof(AdaptIgnoreAttribute) }, MapType = MapType.Map | MapType.MapToTarget | MapType.Projection)] +[GenerateMapper] public class ApplicationUser : IdentityUser { public string FirstName { get; set; } = string.Empty; public string LastName { get; set; } = string.Empty; + public string InternationalId { get; set; } = string.Empty; public DateTime BirthDate { get; set; } public Gender Gender { get; set; } public SignUpStatus SignUpStatus { get; set; } diff --git a/Brizco.Domain/Mappers/ApplicationUserMapper.g.cs b/Brizco.Domain/Mappers/ApplicationUserMapper.g.cs new file mode 100644 index 0000000..e09daa1 --- /dev/null +++ b/Brizco.Domain/Mappers/ApplicationUserMapper.g.cs @@ -0,0 +1,99 @@ +using System; +using System.Linq.Expressions; +using Brizco.Domain.Dtos.SmallDtos; +using Brizco.Domain.Entities.User; + +namespace Brizco.Domain.Mappers +{ + public static partial class ApplicationUserMapper + { + public static ApplicationUser AdaptToApplicationUser(this ApplicationUserSDto p1) + { + return p1 == null ? null : new ApplicationUser() + { + FirstName = p1.FirstName, + LastName = p1.LastName, + InternationalId = p1.InternationalId, + BirthDate = p1.BirthDate, + Gender = p1.Gender, + SignUpStatus = p1.SignUpStatus, + Id = p1.Id, + PhoneNumber = p1.PhoneNumber + }; + } + public static ApplicationUser AdaptTo(this ApplicationUserSDto p2, ApplicationUser p3) + { + if (p2 == null) + { + return null; + } + ApplicationUser result = p3 ?? new ApplicationUser(); + + result.FirstName = p2.FirstName; + result.LastName = p2.LastName; + result.InternationalId = p2.InternationalId; + result.BirthDate = p2.BirthDate; + result.Gender = p2.Gender; + result.SignUpStatus = p2.SignUpStatus; + result.Id = p2.Id; + result.PhoneNumber = p2.PhoneNumber; + return result; + + } + public static Expression> ProjectToApplicationUser => p4 => new ApplicationUser() + { + FirstName = p4.FirstName, + LastName = p4.LastName, + InternationalId = p4.InternationalId, + BirthDate = p4.BirthDate, + Gender = p4.Gender, + SignUpStatus = p4.SignUpStatus, + Id = p4.Id, + PhoneNumber = p4.PhoneNumber + }; + public static ApplicationUserSDto AdaptToSDto(this ApplicationUser p5) + { + return p5 == null ? null : new ApplicationUserSDto() + { + PhoneNumber = p5.PhoneNumber, + FirstName = p5.FirstName, + LastName = p5.LastName, + BirthDate = p5.BirthDate, + Gender = p5.Gender, + SignUpStatus = p5.SignUpStatus, + InternationalId = p5.InternationalId, + Id = p5.Id + }; + } + public static ApplicationUserSDto AdaptTo(this ApplicationUser p6, ApplicationUserSDto p7) + { + if (p6 == null) + { + return null; + } + ApplicationUserSDto result = p7 ?? new ApplicationUserSDto(); + + result.PhoneNumber = p6.PhoneNumber; + result.FirstName = p6.FirstName; + result.LastName = p6.LastName; + result.BirthDate = p6.BirthDate; + result.Gender = p6.Gender; + result.SignUpStatus = p6.SignUpStatus; + result.InternationalId = p6.InternationalId; + result.Id = p6.Id; + return result; + + } + public static Expression> ProjectToSDto => p8 => new ApplicationUserSDto() + { + PhoneNumber = p8.PhoneNumber, + FirstName = p8.FirstName, + LastName = p8.LastName, + BirthDate = p8.BirthDate, + Gender = p8.Gender, + SignUpStatus = p8.SignUpStatus, + InternationalId = p8.InternationalId, + Id = p8.Id + }; + } +} \ No newline at end of file diff --git a/Brizco.Domain/Mappers/ComplexUserRoleMapper.g.cs b/Brizco.Domain/Mappers/ComplexUserRoleMapper.g.cs new file mode 100644 index 0000000..f8d3e92 --- /dev/null +++ b/Brizco.Domain/Mappers/ComplexUserRoleMapper.g.cs @@ -0,0 +1,69 @@ +using System; +using System.Linq.Expressions; +using Brizco.Domain.Dtos.SmallDtos; +using Brizco.Domain.Entities.Complex; + +namespace Brizco.Domain.Mappers +{ + public static partial class ComplexUserRoleMapper + { + public static ComplexUserRole AdaptToComplexUserRole(this ComplexUserRoleSDto p1) + { + return p1 == null ? null : new ComplexUserRole() + { + ComplexUserId = p1.ComplexUserId, + RoleId = p1.RoleId, + Id = p1.Id + }; + } + public static ComplexUserRole AdaptTo(this ComplexUserRoleSDto p2, ComplexUserRole p3) + { + if (p2 == null) + { + return null; + } + ComplexUserRole result = p3 ?? new ComplexUserRole(); + + result.ComplexUserId = p2.ComplexUserId; + result.RoleId = p2.RoleId; + result.Id = p2.Id; + return result; + + } + public static Expression> ProjectToComplexUserRole => p4 => new ComplexUserRole() + { + ComplexUserId = p4.ComplexUserId, + RoleId = p4.RoleId, + Id = p4.Id + }; + public static ComplexUserRoleSDto AdaptToSDto(this ComplexUserRole p5) + { + return p5 == null ? null : new ComplexUserRoleSDto() + { + RoleId = p5.RoleId, + ComplexUserId = p5.ComplexUserId, + Id = p5.Id + }; + } + public static ComplexUserRoleSDto AdaptTo(this ComplexUserRole p6, ComplexUserRoleSDto p7) + { + if (p6 == null) + { + return null; + } + ComplexUserRoleSDto result = p7 ?? new ComplexUserRoleSDto(); + + result.RoleId = p6.RoleId; + result.ComplexUserId = p6.ComplexUserId; + result.Id = p6.Id; + return result; + + } + public static Expression> ProjectToSDto => p8 => new ComplexUserRoleSDto() + { + RoleId = p8.RoleId, + ComplexUserId = p8.ComplexUserId, + Id = p8.Id + }; + } +} \ No newline at end of file diff --git a/Brizco.Domain/MapsterRegister.cs b/Brizco.Domain/MapsterRegister.cs index 6e53f52..2f01a30 100644 --- a/Brizco.Domain/MapsterRegister.cs +++ b/Brizco.Domain/MapsterRegister.cs @@ -1,4 +1,5 @@ -using Brizco.Domain.Entities.Shift; +using Brizco.Domain.Entities.Complex; +using Brizco.Domain.Entities.Shift; using Mapster; namespace Brizco.Domain; @@ -8,8 +9,14 @@ public class MapsterRegister : IRegister public void Register(TypeAdapterConfig config) { config.NewConfig() - .Map("Days", org => org.Days != null ? org.Days.Select(d=>d.DayOfWeek).ToList() - : new List()) + .Map("Days", org => org.Days != null ? org.Days.Select(d=>d.DayOfWeek).ToList() : new List()) + .TwoWays(); + + config.NewConfig() + .Map(s=>s.ComplexName,o=>o.Complex!=null ? o.Complex.Name : string.Empty) + .Map(s=>s.FirstName,o=>o.User!=null ? o.User.FirstName : string.Empty) + .Map(s=>s.LastName,o=>o.User!=null ? o.User.LastName : string.Empty) + .Map(s=>s.InternationalId,o=>o.User!=null ? o.User.InternationalId : string.Empty) .TwoWays(); } } \ No newline at end of file