using System.Data; using System.Net; using Marco.Pms.DataAccess.Data; using Marco.Pms.Model.Dtos.Employees; using Marco.Pms.Model.Employees; using Marco.Pms.Model.Entitlements; using Marco.Pms.Model.Mapper; using Marco.Pms.Model.Utilities; using Marco.Pms.Model.ViewModels; using Marco.Pms.Model.ViewModels.Employee; using MarcoBMS.Services.Helpers; using MarcoBMS.Services.Service; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; namespace MarcoBMS.Services.Controllers { [Route("api/[controller]")] [ApiController] [Authorize] public class EmployeeController : ControllerBase { private readonly ApplicationDbContext _context; private readonly UserManager _userManager; private readonly IEmailSender _emailSender; private readonly EmployeeHelper _employeeHelper; private readonly UserHelper _userHelper; private readonly IConfiguration _configuration; public EmployeeController(UserManager userManager, IEmailSender emailSender, ApplicationDbContext context, EmployeeHelper employeeHelper, UserHelper userHelper, IConfiguration configuration) { _context = context; _userManager = userManager; _emailSender = emailSender; _employeeHelper = employeeHelper; _userHelper = userHelper; _configuration = configuration; } [HttpGet] [Route("roles/{employeeId?}")] public async Task GetRoles(int employeeId) { if (!ModelState.IsValid) { var errors = ModelState.Values .SelectMany(v => v.Errors) .Select(e => e.ErrorMessage) .ToList(); return BadRequest(ApiResponse.ErrorResponse("Invalid data", errors, 400)); } int tenantId = GetTenantId(); var empRoles = await _context.EmployeeRoleMappings.Where(c => c.EmployeeId == employeeId).Include(c => c.Role).Include(c => c.Employee).ToListAsync(); if (empRoles.Any()) { List roles = new List(); foreach (EmployeeRoleMapping mapping in empRoles) { roles.Add(new EmployeeRolesVM() { Id = mapping.Id, EmployeeId = mapping.EmployeeId, Name = mapping.Role.Role, Description = mapping.Role.Description, IsEnabled = mapping.IsEnabled, RoleId = mapping.RoleId, }); } return Ok(ApiResponse.SuccessResponse(roles, "Success.", 200)); } else { return BadRequest(ApiResponse.ErrorResponse("This employee has no assigned permissions.", "This employee has no assigned permissions.", 400)); } } [HttpPost] [Route("roles")] public async Task ManageRoles([FromBody] List employeeRoleDots) { if (!ModelState.IsValid) { var errors = ModelState.Values .SelectMany(v => v.Errors) .Select(e => e.ErrorMessage) .ToList(); return BadRequest(ApiResponse.ErrorResponse("Invalid data", errors, 400)); } int TenantId = GetTenantId(); try { foreach (EmployeeRoleDot role in employeeRoleDots) { EmployeeRoleMapping mapping = role.ToEmployeeRoleMappingFromEmployeeRoleDot(TenantId); var existingItem = await _context.EmployeeRoleMappings.AsNoTracking().SingleOrDefaultAsync(c => c.Id == mapping.Id); if (existingItem == null) { _context.EmployeeRoleMappings.Add(mapping); } else { _context.EmployeeRoleMappings.Update(mapping); } } await _context.SaveChangesAsync(); } catch (Exception ex) { return BadRequest(ApiResponse.ErrorResponse(ex.Message, ex, 400)); } return Ok(ApiResponse.SuccessResponse("success", "Roles modified.", 200)); } [HttpGet] [Route("list/{projectid?}")] public async Task GetEmployeesByProject(int? projectid) { if (!ModelState.IsValid) { var errors = ModelState.Values .SelectMany(v => v.Errors) .Select(e => e.ErrorMessage) .ToList(); return BadRequest(ApiResponse.ErrorResponse("Invalid data", errors, 400)); } var result = await _employeeHelper.GetEmployeeByProjectId(GetTenantId(), projectid); return Ok(ApiResponse.SuccessResponse(result, "Filter applied.", 200)); } [HttpGet] [Route("search/{name}/{projectid?}")] public async Task SearchEmployee(string name, int? projectid) { if (!ModelState.IsValid) { var errors = ModelState.Values .SelectMany(v => v.Errors) .Select(e => e.ErrorMessage) .ToList(); return BadRequest(ApiResponse.ErrorResponse("Invalid data", errors, 400)); } var result = await _employeeHelper.SearchEmployeeByProjectId(GetTenantId(), name.ToLower(), projectid); return Ok(ApiResponse.SuccessResponse(result, "Filter applied.", 200)); } [HttpGet] [Route("profile/get/{employeeId}")] public async Task GetEmployeeProfileById(int employeeId) { if (!ModelState.IsValid) { var errors = ModelState.Values .SelectMany(v => v.Errors) .Select(e => e.ErrorMessage) .ToList(); return BadRequest(ApiResponse.ErrorResponse("Invalid data", errors, 400)); } Employee emp = await _employeeHelper.GetEmployeeByID(employeeId); EmployeeVM employeeVM = EmployeeMapper.ToEmployeeVMFromEmployee(emp); return Ok(ApiResponse.SuccessResponse(employeeVM, "Employee Profile.", 200)); } private int GetTenantId() { return _userHelper.GetTenantId(); } //[HttpPost("manage/quick")] //public async Task CreateQuickUser([FromBody] CreateQuickUserDto model) //{ // return Ok("Pending implementation"); //} [HttpPost("manage")] public async Task CreateUser([FromForm] CreateUserDto model) { if (model == null) return BadRequest(ApiResponse.ErrorResponse("Invalid data", "Invaild Data", 400)); int TenantId = GetTenantId(); string responsemessage = ""; if (model.Email != null) { // Check if user already exists by email IdentityUser? existingUser = await _userHelper.GetRegisteredUser(model.Email); if (existingUser != null) { /* Identity user Exists - Create/update employee Employee */ // Update Employee record var existingEmployee = await _context.Employees.FirstOrDefaultAsync(e => e.Email == model.Email && e.Id == model.Id); if (existingEmployee != null) { existingEmployee = GetUpdateEmployeeModel(model, existingEmployee, existingUser); _context.Employees.Update(existingEmployee); await _context.SaveChangesAsync(); responsemessage = "User updated successfully."; } else { // Create Employee record if missing //Employee newEmployee = GetNewEmployeeModel(model, TenantId, existingUser.Id); //_context.Employees.Add(newEmployee); return BadRequest(ApiResponse.ErrorResponse("Email already exist", "Email already exist", 400)); } } else { var user = new ApplicationUser { UserName = model.Email, Email = model.Email, EmailConfirmed = true }; // Create Identity User var result = await _userManager.CreateAsync(user, "User@123"); if (!result.Succeeded) return Ok(ApiResponse.ErrorResponse("Failed to create user", result.Errors, 400)); Employee newEmployee = GetNewEmployeeModel(model, TenantId, user.Id); _context.Employees.Add(newEmployee); await _context.SaveChangesAsync(); /* SEND USER REGISTRATION MAIL*/ var token = await _userManager.GeneratePasswordResetTokenAsync(user); var resetLink = $"{_configuration["AppSettings:WebFrontendUrl"]}/reset-password?token={WebUtility.UrlEncode(token)}"; if (newEmployee.FirstName != null) { await _emailSender.SendResetPasswordEmailOnRegister(user.Email, newEmployee.FirstName, resetLink); } responsemessage = "User created successfully. Password reset link is sent to registered email"; } } else { var existingEmployee = await _context.Employees.FirstOrDefaultAsync(e => e.Id == model.Id); if (existingEmployee != null) { existingEmployee = GetUpdateEmployeeModel(model, existingEmployee); _context.Employees.Update(existingEmployee); responsemessage = "User updated successfully."; } else { // Create Employee record if missing Employee newEmployee = GetNewEmployeeModel(model, TenantId, null); _context.Employees.Add(newEmployee); } await _context.SaveChangesAsync(); responsemessage = "User created successfully."; } return Ok(ApiResponse.SuccessResponse("Success.",responsemessage, 200)); } #nullable disable private static Employee GetNewEmployeeModel(CreateUserDto model, int TenantId, string ApplicationUserId) { var newEmployee = new Employee { ApplicationUserId = ApplicationUserId, FirstName = model.FirstName, LastName = model.LastName, Email = model.Email, TenantId = TenantId, CurrentAddress = model.CurrentAddress, BirthDate = Convert.ToDateTime(model.BirthDate), EmergencyPhoneNumber = model.EmergencyPhoneNumber, EmergencyContactPerson = model.EmergencyContactPerson, AadharNumber = model.AadharNumber, Gender = model.Gender, MiddleName = model.MiddleName, PanNumber = model.PanNumber, PermanentAddress = model.PermanentAddress, PhoneNumber = model.PhoneNumber, Photo = null, // GetFileDetails(model.Photo).Result.FileData, JobRoleId = Convert.ToInt32(model.JobRoleId), JoiningDate = Convert.ToDateTime(model.JoiningDate), }; return newEmployee; } private static Employee GetUpdateEmployeeModel(CreateUserDto model, Employee existingEmployee, IdentityUser existingIdentityUser = null) { if (existingEmployee.ApplicationUserId == null && existingIdentityUser != null) { existingEmployee.ApplicationUserId = existingIdentityUser.Id; } existingEmployee.FirstName = model.FirstName; existingEmployee.LastName = model.LastName; existingEmployee.CurrentAddress = model.CurrentAddress; existingEmployee.BirthDate = Convert.ToDateTime(model.BirthDate); existingEmployee.JoiningDate = Convert.ToDateTime(model.JoiningDate); existingEmployee.EmergencyPhoneNumber = model.EmergencyPhoneNumber; existingEmployee.EmergencyContactPerson = model.EmergencyContactPerson; existingEmployee.AadharNumber = model.AadharNumber; existingEmployee.Gender = model.Gender; existingEmployee.MiddleName = model.MiddleName; existingEmployee.PanNumber = model.PanNumber; existingEmployee.PermanentAddress = model.PermanentAddress; existingEmployee.PhoneNumber = model.PhoneNumber; existingEmployee.Photo = null; // GetFileDetails(model.Photo).Result.FileData, existingEmployee.JobRoleId = Convert.ToInt32(model.JobRoleId); return existingEmployee; } private static async Task GetFileDetails(IFormFile file) { FileDetails info = new FileDetails(); info.ContentType = file.ContentType; info.FileName = file.FileName; using (var memoryStream = new MemoryStream()) { await file.CopyToAsync(memoryStream); info.FileData = memoryStream.ToArray(); } return info; } } }