using Marco.Pms.DataAccess.Data; using Marco.Pms.DataAccess.Repository.IRepository; 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 MarcoBMS.Services.Service; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using System.Data; namespace MarcoBMS.Services.Controllers { [Route("api/[controller]")] [ApiController] [Authorize] public class EmployeeController : ControllerBase { private readonly IUnitOfWork _unitOfWork; private readonly ApplicationDbContext _context; private readonly UserManager _userManager; private readonly IEmailSender _emailSender; public EmployeeController(UserManager userManager, IEmailSender emailSender, IEmployeeRepository empRepo, IUnitOfWork unitOfWork, ApplicationDbContext context) { _unitOfWork = unitOfWork; _context = context; _userManager = userManager; _emailSender = emailSender; } [HttpGet] [Route("roles/{employeeId?}")] public async Task GetRoles(int employeeId) { if (!ModelState.IsValid) { return BadRequest(ModelState); } int tenantId = GetTenantId(); var empRoles = _context.EmployeeRoleMappings.Where(c => c.EmployeeId == employeeId).Include(c => c.Role).Include(c => c.Employee).ToList(); 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 Ok(ApiResponse.SuccessResponse(new List(), "Success.", 200)); } } [HttpPost] [Route("roles")] public async Task ManageRoles([FromBody] List employeeRoleDots) { if (!ModelState.IsValid) return BadRequest(ModelState); 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 Ok(ApiResponse.SuccessResponse("success", "Roles modified.", 200)); } [HttpGet] [Route("search/{name}/{projectid?}")] public async Task SearchEmployee(string name, int? projectid) { if (!ModelState.IsValid) { return BadRequest(ModelState); } int TenantId = GetTenantId(); name = name.ToLower(); int tenantId = GetTenantId(); List employees = await _unitOfWork.Employee.GetAsync(c => c.TenantId == tenantId && (c.FirstName.ToLower().StartsWith(name) || c.MiddleName.ToLower().StartsWith(name) || c.LastName.ToLower().StartsWith(name))); employees = employees.Where(c => c.FirstName.ToLower().StartsWith(name) || c.MiddleName.ToLower().StartsWith(name) || c.LastName.ToLower().StartsWith(name)).ToList(); if (projectid != null) { // conditions to e checked after project assignment } return Ok(ApiResponse.SuccessResponse(employees, "Filter applied.", 200)); } [HttpGet] [Route("get/{projectid?}")] public async Task GetEmployee(int? projectid) { if (!ModelState.IsValid) { return BadRequest(ModelState); } int TenantId = GetTenantId(); List employees = await _unitOfWork.Employee.GetAsync(c => c.TenantId == TenantId); employees = employees.Where(c => c.TenantId == TenantId).ToList(); if (projectid != null) { // Fetch assigned project } return Ok(employees); } //[HttpGet] //[Route("attendance/project/{projectid?}")] //public async Task GetAttendanceList(int? projectid) //{ // if (!ModelState.IsValid) // { // return BadRequest(ModelState); // } // int TenantId = GetTenantId(); // DateTime today = DateTime.Today; // var result = from employee in _context.ProjectAllocations // join attendance in _context.Attendances // on employee.Id equals attendance.EmployeeID into attendanceGroup // from todayAttendance in attendanceGroup // //.Where(a => a.InTimeLog.InTime == today) // .DefaultIfEmpty() // LEFT JOIN // select new // { // ProjectID = projectid, // EmployeeId = employee.Id, // FirstName = employee.Employee.FirstName, // MiddleName = employee.Employee.MiddleName, // LastName = employee.Employee.LastName, // PhoneNumber = employee.Employee.PhoneNumber, // RoleId = employee.Employee.JobRoleId, // //InTime = todayAttendance.InTimeLog != null ? todayAttendance.InTimeLog.InTime : (DateTime?)null, // //OutTime = todayAttendance.OutTimeLog != null ? todayAttendance.OutTimeLog.OutTime : (DateTime?)null, // // WorkShift = todayAttendance.WorkShift, // Latitude = todayAttendance.InTimeLog != null ? todayAttendance.InTimeLog.Latitude : null, // Longitude = todayAttendance.InTimeLog != null ? todayAttendance.InTimeLog.Longitude : null, // Comment = todayAttendance.Comment, // }; // return Ok(result); //} private int GetTenantId() { var tenant = User.FindFirst("TenantId")?.Value; return (tenant != null ? Convert.ToInt32(tenant) : 1); } [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("Invalid user data."); int TenantId = GetTenantId(); if (model.Email != null) { // Check if user already exists by email var existingUser = await _userManager.FindByEmailAsync(model.Email); if (existingUser != null) { // Update existing user //existingUser.Email = model.Email; // No need to update email //var updateResult = await _userManager.UpdateAsync(existingUser); //if (!updateResult.Succeeded) // return BadRequest(updateResult.Errors); // Update Employee record var existingEmployee = await _context.Employees.FirstOrDefaultAsync(e => e.ApplicationUserId == existingUser.Id); if (existingEmployee != null) { existingEmployee.FirstName = model.FirstName; existingEmployee.LastName = model.LastName; existingEmployee.TenantId = TenantId; existingEmployee.Email = model.Email; existingEmployee.JobRoleId = Convert.ToInt32(model.JobRoleId); _context.Employees.Update(existingEmployee); } else { // Create Employee record if missing var newEmployee = new Employee { ApplicationUserId = existingUser.Id, FirstName = model.FirstName, LastName = model.LastName, Email = model.Email, TenantId = TenantId, CurrentAddress = model.CurrentAddress, BirthDate = Convert.ToDateTime(model.BirthDate), EmergencyPhoneNumber = model.EmergencyPhoneNumber, AadharNumber = model.AadharNumber, Gender = model.Gender, MiddleName = model.MiddleName, PanNumber = model.PanNumber, PeramnentAddress = model.PeramnentAddress, PhoneNumber = model.PhoneNumber, Photo = GetFileDetails(model.Photo).Result.FileData, JobRoleId = Convert.ToInt32(model.JobRoleId) }; _context.Employees.Add(newEmployee); } await _context.SaveChangesAsync(); return Ok(new { message = "User updated successfully." }); } 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 BadRequest(result.Errors); // Save Employee Data var employee = new Employee { FirstName = model.FirstName, LastName = model.LastName, Email = model.Email, TenantId = TenantId, CurrentAddress = model.CurrentAddress, BirthDate = Convert.ToDateTime(model.BirthDate), EmergencyPhoneNumber = model.EmergencyPhoneNumber, AadharNumber = model.AadharNumber, Gender = model.Gender, MiddleName = model.MiddleName, PanNumber = model.PanNumber, PeramnentAddress = model.PeramnentAddress, PhoneNumber = model.PhoneNumber, Photo = GetFileDetails(model.Photo).Result.FileData, JobRoleId = Convert.ToInt32(model.JobRoleId) }; _context.Employees.Add(employee); await _context.SaveChangesAsync(); var token = await _userManager.GeneratePasswordResetTokenAsync(user); var resetLink = Url.Action("ResetPassword", "Account", new { token, email = user.Email }, Request.Scheme); // Send Email await _emailSender.SendEmailAsync(user.Email, "Set Password", $"Click here to set your password: {resetLink}"); } else { var existingEmployee = await _context.Employees.FirstOrDefaultAsync(e => e.Id == model.Id); if (existingEmployee != null) { existingEmployee.FirstName = model.FirstName; existingEmployee.LastName = model.LastName; existingEmployee.TenantId = TenantId; _context.Employees.Update(existingEmployee); } else { // Create Employee record if missing var newEmployee = new Employee { ApplicationUserId = null, FirstName = model.FirstName, LastName = model.LastName, TenantId = TenantId, CurrentAddress = model.CurrentAddress, BirthDate = Convert.ToDateTime(model.BirthDate), EmergencyPhoneNumber = model.EmergencyPhoneNumber, AadharNumber = model.AadharNumber, Gender = model.Gender, MiddleName = model.MiddleName, PanNumber = model.PanNumber, PeramnentAddress = model.PeramnentAddress, PhoneNumber = model.PhoneNumber, Photo = GetFileDetails(model.Photo).Result.FileData }; _context.Employees.Add(newEmployee); } await _context.SaveChangesAsync(); } // Generate Password Reset Link return Ok(new { message = "User created successfully. Password reset link sent." }); } 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; } } }