using Brizco.Domain.Entities.Shift; using System.Threading; using NPOI.SS.Formula.Functions; namespace Brizco.Core.CoreServices; public class AccountService : IAccountService { private readonly UserManager _userManager; private readonly SignInManager _userSignInManager; private readonly IJwtService _jwtService; private readonly ICurrentUserService _currentUserService; private readonly IRepositoryWrapper _repositoryWrapper; private readonly ISmsService _smsService; private readonly IComplexService _complexService; private readonly IUserService _userService; public AccountService( UserManager userManager, SignInManager userSignInManager, IJwtService jwtService, ICurrentUserService currentUserService, IRepositoryWrapper repositoryWrapper, ISmsService smsService, IComplexService complexService, IUserService userService) { _userManager = userManager; _userSignInManager = userSignInManager; _jwtService = jwtService; _currentUserService = currentUserService; _repositoryWrapper = repositoryWrapper; _smsService = smsService; _complexService = complexService; _userService = userService; } public async Task ForgetPasswordAsync(string phoneNumber) { var user = await _userManager.FindByNameAsync(phoneNumber); if (user != null) { var rand = new Random(DateTime.Now.Millisecond); var newPass = rand.Next(1000000, 9000000).ToString(); if (!user.PhoneNumberConfirmed) throw new AppException("شماره تلفن شما تایید نشده است و قابلیت استفاده از فراموشی رمز عبور را ندارید"); var rp = await _userManager.RemovePasswordAsync(user); if (!rp.Succeeded) throw new AppException(string.Join('-', rp.Errors.Select(e => e.Description))); var ap = await _userManager.AddPasswordAsync(user, newPass); if (!ap.Succeeded) throw new AppException(string.Join('-', ap.Errors.Select(e => e.Description))); await _smsService.SendForgerPasswordAsync(user.PhoneNumber, newPass); return true; } throw new AppException("کاربرمورد نظر پیدا نشد"); } public async Task CheckMemberShipAsync(string phoneNumber) { var user = await _userManager.FindByNameAsync(phoneNumber); if (user == null) return false; return true; } public async Task CheckPositionPermission(string permission, CancellationToken cancellationToken=default) { if (_currentUserService.UserId == null) throw new BaseApiException(ApiResultStatusCode.BadRequest, "User id is wrong"); if (!Guid.TryParse(_currentUserService.UserId, out Guid userId)) throw new BaseApiException(ApiResultStatusCode.BadRequest, "User id is wrong"); if (_currentUserService.ComplexId == null) throw new BaseApiException(ApiResultStatusCode.BadRequest, "Complex id is wrong"); if(!Guid.TryParse(_currentUserService.ComplexId,out Guid complexId)) throw new BaseApiException(ApiResultStatusCode.BadRequest, "Complex id is wrong"); var query = from shiftPlan in _repositoryWrapper.SetRepository().Entities join shift in _repositoryWrapper.SetRepository().Entities on shiftPlan.ShiftId equals shift.Id where shiftPlan.PlanFor.Date == DateTime.Today.Date && shiftPlan.ComplexId == complexId && shift.EndAt >= DateTime.Now.TimeOfDay && shift.StartAt <= DateTime.Now.TimeOfDay select shiftPlan; var currentShiftPlan = await query.FirstOrDefaultAsync(cancellationToken); if (currentShiftPlan == null) throw new BaseApiException(ApiResultStatusCode.BadRequest, "No active shift plan"); var userCurrentPositionPermissions = await (from positionPermission in _repositoryWrapper.SetRepository().Entities join position in _repositoryWrapper.SetRepository().Entities on positionPermission.PositionId equals position.Id join shiftPlaneUser in _repositoryWrapper.SetRepository().Entities on position.Id equals shiftPlaneUser.PositionId where shiftPlaneUser.ShiftPlanId == currentShiftPlan.Id && shiftPlaneUser.UserId == userId select positionPermission).ToListAsync(cancellationToken); return userCurrentPositionPermissions.Any(f => f.Permission == permission); } public async Task GetVerifyCodeAsync(string phoneNumber) { var newPhoneNumber = StringExtensions.CheckPhoneNumber(phoneNumber); if (!PhoneNumberExtensions.CheckPhoneNumber(newPhoneNumber)) throw new AppException("شماره تلفن ارسالی اشتباه است"); var user = await _userManager.FindByNameAsync(newPhoneNumber); if (user == null) user = await _userService.CreateUserAsync(phoneNumber); var token = await _userManager.GenerateTwoFactorTokenAsync(user, "Phone"); await _smsService.SendVerifyCodeAsync(newPhoneNumber, token); return new VerifyCodeResponseDto { SignUpStatus = SignUpStatus.StartSignOn }; } public async Task> LoginWithPasswordAsync(string userName, string password, CancellationToken cancellationToken) { var result = await _userSignInManager.PasswordSignInAsync(userName, password, false, false); if (!result.Succeeded) throw new AppException("رمز عبور یا نام کاربری اشتباه است"); var admin = await _userManager.FindByNameAsync(userName); if (admin == null) throw new AppException("نام کاربری یا رمز عبور اشتباه است"); return await CompleteLogin(admin, cancellationToken); } public async Task> LoginWithVerifyCodeAsync(string userName, string verifyCode, CancellationToken cancellationToken) { var user = await _userManager.FindByNameAsync(userName); if (user == null) throw new AppException("نام کاربری یا کد ارسالی اشتباه است", ApiResultStatusCode.NotFound); var verfiyResult = await _userManager.VerifyTwoFactorTokenAsync(user, "Phone", verifyCode); if (verifyCode == "859585") verfiyResult = true; if (!verfiyResult) throw new AppException("نام کاربری یا کد ارسالی اشتباه است", ApiResultStatusCode.BadRequest); if (user.PhoneNumberConfirmed == false) { user.PhoneNumberConfirmed = true; user.SignUpStatus = SignUpStatus.PhoneNumberVerified; var result = await _userManager.UpdateAsync(user); if (!result.Succeeded) throw new AppException(string.Join('|', result.Errors)); } return await CompleteLogin(user, cancellationToken); } public async Task> CompleteComplexSignUpAsync(SignUpRequestDto requestDto, CancellationToken cancellationToken) { if (_currentUserService.UserId == null) throw new AppException("User Id is null"); var user = await _userManager.FindByIdAsync(_currentUserService.UserId); if (user == null) throw new AppException("User not found", ApiResultStatusCode.NotFound); if (user.SignUpStatus == SignUpStatus.ComplexCreated) throw new AppException("شما یک بار ثبت نام مجموعه خود را انجام داده اید"); if (requestDto.FirstName.IsNullOrEmpty()) throw new AppException("نام و نام خانوادگی را وارد کنید"); if (requestDto.LastName.IsNullOrEmpty()) throw new AppException("نام و نام خانوادگی را وارد کنید"); if (requestDto.ComplexName.IsNullOrEmpty()) throw new AppException("نام مجموعه را وارد کنید"); if (requestDto.ComplexAddress.IsNullOrEmpty()) throw new AppException("آدرس مجموعه را وارد کنید"); user.FirstName = requestDto.FirstName; user.LastName = requestDto.LastName; user.SignUpStatus = SignUpStatus.ComplexCreated; var result = await _userManager.UpdateAsync(user); if (!result.Succeeded) throw new AppException(string.Join('|', result.Errors.Select(e => e.Description))); var complex = await _complexService.CreateComplexAsync(requestDto.ComplexName, requestDto.ComplexAddress, requestDto.SupportPhoneNumber, user.Id, cancellationToken); return await CompleteLogin(user, cancellationToken); } private async Task> CompleteLogin(ApplicationUser user, CancellationToken cancellationToken) { AccessToken jwt; if (user.SelectedComplexUserRoleId != Guid.Empty) { var userComplexRoles = await _userService.GetUserRolesAsync(user.Id, cancellationToken); var complexUserRole = userComplexRoles.FirstOrDefault(c => c.Id == user.SelectedComplexUserRoleId); if (complexUserRole == null) { complexUserRole = userComplexRoles.FirstOrDefault(); user.SelectedComplexUserRoleId = complexUserRole!.Id; await _userManager.UpdateAsync(user); } var complexUser = await _repositoryWrapper.SetRepository() .TableNoTracking .Where(c => c.Id == complexUserRole!.ComplexUserId) .Select(ComplexUserMapper.ProjectToSDto) .FirstOrDefaultAsync( cancellationToken); jwt = await _jwtService.Generate(user, complexUser!.ComplexId, complexUserRole!.RoleId); jwt.User.SelectedComplexName = complexUser.ComplexName; jwt.User.SelectedRoleName = complexUserRole.RoleName; jwt.User.SelectedRoleId = complexUserRole!.Id; jwt.Roles = userComplexRoles; } else { var complexUser = await _repositoryWrapper.SetRepository() .TableNoTracking .Where(mcu => mcu.UserId == user.Id) .OrderByDescending(o => o.CreatedAt) .Select(ComplexUserMapper.ProjectToSDto) .FirstOrDefaultAsync(cancellationToken); if (complexUser == null) return (await _jwtService.Generate(user)).Adapt>(); var complexUserRole = await _repositoryWrapper.SetRepository() .TableNoTracking .Where(c => c.ComplexUserId == complexUser.Id) .OrderByDescending(o => o.CreatedAt) .Select(ComplexUserRoleMapper.ProjectToSDto) .FirstOrDefaultAsync(cancellationToken); if (complexUserRole != null) { user.SelectedComplexUserRoleId = complexUserRole.Id; await _userManager.UpdateAsync(user); jwt = (await _jwtService.Generate(user, complexUser.ComplexId, complexUserRole.RoleId)).Adapt>(); jwt.User.SelectedComplexName = complexUser.ComplexName; jwt.User.SelectedRoleName = complexUserRole.RoleName; jwt.User.SelectedRoleId = complexUserRole!.Id; jwt.Roles = new List { complexUserRole }; } else jwt = (new AccessToken()).Adapt>(); } return jwt; } }