From 98409f5b8757e538314da71d7923d2aa3653978f Mon Sep 17 00:00:00 2001 From: "ashutosh.nehete" Date: Fri, 30 May 2025 16:57:10 +0530 Subject: [PATCH] Implement an API to store employee information with a captured image and update employee information. --- .../Dtos/Employees/CreateUserDto.cs | 18 +- Marco.Pms.Model/Mapper/EmployeeMapper.cs | 35 ++- .../ViewModels/Employee/EmployeeVM.cs | 2 +- .../Controllers/EmployeeController.cs | 199 ++++++------------ 4 files changed, 110 insertions(+), 144 deletions(-) diff --git a/Marco.Pms.Model/Dtos/Employees/CreateUserDto.cs b/Marco.Pms.Model/Dtos/Employees/CreateUserDto.cs index 13ddffb..f9d31d3 100644 --- a/Marco.Pms.Model/Dtos/Employees/CreateUserDto.cs +++ b/Marco.Pms.Model/Dtos/Employees/CreateUserDto.cs @@ -30,21 +30,15 @@ // public int TenantId { get; set; } } - public class CreateQuickUserDto + public class MobileUserManageDto { - public Guid Id { get; set; } - public string? FirstName { get; set; } + public Guid? Id { get; set; } + public string FirstName { get; set; } = string.Empty; public string? LastName { get; set; } - + public string PhoneNumber { get; set; } = string.Empty; public string? Gender { get; set; } - - public string? CurrentAddress { get; set; } - public string? PhoneNumber { get; set; } - - public string? EmergencyPhoneNumber { get; set; } - public string? EmergencyContactPerson { get; set; } - - public Guid? JobRoleId { get; set; } + public Guid JobRoleId { get; set; } + public string? ProfileImage { get; set; } } } diff --git a/Marco.Pms.Model/Mapper/EmployeeMapper.cs b/Marco.Pms.Model/Mapper/EmployeeMapper.cs index e20085a..8086496 100644 --- a/Marco.Pms.Model/Mapper/EmployeeMapper.cs +++ b/Marco.Pms.Model/Mapper/EmployeeMapper.cs @@ -1,4 +1,5 @@ -using Marco.Pms.Model.Employees; +using Marco.Pms.Model.Dtos.Employees; +using Marco.Pms.Model.Employees; using Marco.Pms.Model.ViewModels.Activities; using Marco.Pms.Model.ViewModels.Employee; @@ -8,6 +9,11 @@ namespace Marco.Pms.Model.Mapper { public static EmployeeVM ToEmployeeVMFromEmployee(this Employee model) { + string? base64String = null; + if ((model.Photo != null)) + { + base64String = Convert.ToBase64String(model.Photo); + } return new EmployeeVM { Id = model.Id, @@ -27,7 +33,7 @@ namespace Marco.Pms.Model.Mapper PanNumber = model.PanNumber, PermanentAddress = model.PermanentAddress, PhoneNumber = model.PhoneNumber, - Photo = model.Photo, + Photo = base64String, IsActive = model.IsActive, IsSystem = model.IsSystem, JoiningDate = model.JoiningDate @@ -45,5 +51,30 @@ namespace Marco.Pms.Model.Mapper JobRoleName = employee.JobRole != null ? employee.JobRole.Name : "" }; } + public static Employee ToEmployeeFromMobileUserManageDto(this MobileUserManageDto model, Guid TenantId, byte[]? image) + { + return new Employee + { + ApplicationUserId = null, + FirstName = model.FirstName, + LastName = model.LastName, + Email = string.Empty, + TenantId = TenantId, + CurrentAddress = string.Empty, + BirthDate = null, + EmergencyPhoneNumber = string.Empty, + EmergencyContactPerson = string.Empty, + AadharNumber = string.Empty, + Gender = model.Gender, + MiddleName = string.Empty, + PanNumber = string.Empty, + PermanentAddress = string.Empty, + PhoneNumber = model.PhoneNumber, + Photo = image, + JobRoleId = model.JobRoleId, + JoiningDate = null, + + }; + } } } diff --git a/Marco.Pms.Model/ViewModels/Employee/EmployeeVM.cs b/Marco.Pms.Model/ViewModels/Employee/EmployeeVM.cs index c4d2f18..8373ec2 100644 --- a/Marco.Pms.Model/ViewModels/Employee/EmployeeVM.cs +++ b/Marco.Pms.Model/ViewModels/Employee/EmployeeVM.cs @@ -23,7 +23,7 @@ public bool IsActive { get; set; } = true; public string? PanNumber { get; set; } - public byte[]? Photo { get; set; } // To store the captured photo + public string? Photo { get; set; } // To store the captured photo public string? ApplicationUserId { get; set; } diff --git a/Marco.Pms.Services/Controllers/EmployeeController.cs b/Marco.Pms.Services/Controllers/EmployeeController.cs index 7ba85b4..208f680 100644 --- a/Marco.Pms.Services/Controllers/EmployeeController.cs +++ b/Marco.Pms.Services/Controllers/EmployeeController.cs @@ -84,8 +84,6 @@ namespace MarcoBMS.Services.Controllers } } - - [HttpGet] [Route("list/{projectid?}")] public async Task GetEmployeesByProject(Guid? projectid, [FromQuery] bool ShowInactive) @@ -103,6 +101,7 @@ namespace MarcoBMS.Services.Controllers return Ok(ApiResponse.SuccessResponse(result, "Filter applied.", 200)); } + [HttpGet] [Route("search/{name}/{projectid?}")] public async Task SearchEmployee(string name, Guid? projectid) @@ -264,145 +263,90 @@ namespace MarcoBMS.Services.Controllers Employee newEmployee = GetNewEmployeeModel(model, tenantId, string.Empty); _context.Employees.Add(newEmployee); } - try - { - await _context.SaveChangesAsync(); - } - catch (Exception ex) - { - return BadRequest(ex.InnerException?.Message ?? ex.Message); - } + await _context.SaveChangesAsync(); responsemessage = "User created successfully."; } return Ok(ApiResponse.SuccessResponse("Success.", responsemessage, 200)); } - //[HttpPost("manage-mobile")] - //public async Task CreateUserMoblie([FromBody] CreateUserDto model) - //{ - // Guid tenantId = _userHelper.GetTenantId(); - // if (model == null) - // return BadRequest(ApiResponse.ErrorResponse("Invalid data", "Invaild Data", 400)); - // if (model.FirstName == null && model.PhoneNumber == null) - // return BadRequest(ApiResponse.ErrorResponse("Invalid data", "Invaild Data", 400)); + [HttpPost("manage-mobile")] + public async Task CreateUserMoblie([FromBody] MobileUserManageDto model) + { + Guid tenantId = _userHelper.GetTenantId(); + if (model == null) + { + _logger.LogWarning("User submitted empty or null employee information during employee creation or update in tenant {TenantId}", tenantId); + return BadRequest(ApiResponse.ErrorResponse("Invalid data", "Invaild Data", 400)); + } - // string responsemessage = ""; + if (string.IsNullOrWhiteSpace(model.FirstName) || string.IsNullOrWhiteSpace(model.PhoneNumber)) + { + _logger.LogWarning("User submitted empty or null first name or phone number during employee creation or update in tenant {TenantId}", tenantId); + return BadRequest(ApiResponse.ErrorResponse("First name and phone number are required fields.", "First name and phone number are required fields.", 400)); + } - // if (model.Email != null) - // { - // // Check if user already exists by email - // IdentityUser? existingUser = await _userHelper.GetRegisteredUser(model.Email); - // var existingEmployee = await _context.Employees.FirstOrDefaultAsync(e => e.Id == model.Id && e.IsActive == true); - // var demo = existingUser != new IdentityUser(); - // if (existingUser != null) - // { - // /* Identity user Exists - Create/update employee Employee */ + if (model.Id == null) + { + byte[]? imageBytes = null; + if (!string.IsNullOrWhiteSpace(model.ProfileImage)) + { + try + { + imageBytes = Convert.FromBase64String(model.ProfileImage); + } + catch (FormatException) + { + return BadRequest(ApiResponse.ErrorResponse("Invalid image format.", "Invalid image format", 400)); + } + } + Employee employee = model.ToEmployeeFromMobileUserManageDto(tenantId, imageBytes); + _context.Employees.Add(employee); + await _context.SaveChangesAsync(); - // // Update Employee record - // existingEmployee = await _context.Employees.FirstOrDefaultAsync(e => e.Email == model.Email && e.Id == model.Id && e.IsActive == true); - // if (existingEmployee != null) - // { - // existingEmployee = GetUpdateEmployeeModel(model, existingEmployee, existingUser); + EmployeeVM employeeVM = employee.ToEmployeeVMFromEmployee(); - // _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 Conflict(ApiResponse.ErrorResponse("Email already exist", "Email already exist", 409)); - // } + _logger.LogInfo($"Employee {employee.FirstName} {employee.LastName} created in tenant {tenantId}"); + return Ok(ApiResponse.SuccessResponse(employeeVM, "Employee created successfully", 200)); + } + else + { + Employee? existingEmployee = await _context.Employees.FirstOrDefaultAsync(e => e.Id == model.Id.Value); + if (existingEmployee == null) + { + _logger.LogError("User tries to update employee {EmployeeId} but not found in database", model.Id); + return NotFound(ApiResponse.ErrorResponse("Employee not found", "Employee not found", 404)); + } + byte[]? imageBytes = null; + if (!string.IsNullOrWhiteSpace(model.ProfileImage)) + { + try + { + imageBytes = Convert.FromBase64String(model.ProfileImage); + } + catch (FormatException) + { + return BadRequest(ApiResponse.ErrorResponse("Invalid image format.", "Invalid image format", 400)); + } + } + imageBytes ??= existingEmployee.Photo; - // } - // else - // { - // var user = new ApplicationUser - // { - // UserName = model.Email, - // Email = model.Email, - // EmailConfirmed = true, - // TenantId = tenantId + existingEmployee.FirstName = model.FirstName; + existingEmployee.LastName = model.LastName; + existingEmployee.Gender = model.Gender; + existingEmployee.PhoneNumber = model.PhoneNumber; + existingEmployee.JobRoleId = model.JobRoleId; + existingEmployee.Photo = imageBytes; - // }; + await _context.SaveChangesAsync(); - // // 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)); + EmployeeVM employeeVM = existingEmployee.ToEmployeeVMFromEmployee(); - // if (existingEmployee == null) - // { - // 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); - // } - - // } - // else - // { - // existingEmployee.Email = model.Email; - // existingEmployee = GetUpdateEmployeeModel(model, existingEmployee, existingUser); - - // _context.Employees.Update(existingEmployee); - // 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 (existingEmployee.FirstName != null) - // { - // await _emailSender.SendResetPasswordEmailOnRegister(user.Email, existingEmployee.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 && e.IsActive == true); - // 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, string.Empty); - // _context.Employees.Add(newEmployee); - // } - // try - // { - // await _context.SaveChangesAsync(); - // } - // catch (Exception ex) - // { - // return BadRequest(ex.InnerException?.Message ?? ex.Message); - // } - // responsemessage = "User created successfully."; - - // } - // return Ok(ApiResponse.SuccessResponse("Success.", responsemessage, 200)); - //} + _logger.LogInfo($"Employee {existingEmployee.FirstName} {existingEmployee.LastName} updated in tenant {tenantId}"); + return Ok(ApiResponse.SuccessResponse(employeeVM, "Employee updated successfully", 200)); + } + } [HttpDelete("{id}")] public async Task SuspendEmployee(Guid id) @@ -484,7 +428,6 @@ namespace MarcoBMS.Services.Controllers } return Ok(ApiResponse.SuccessResponse(new { }, "Employee Suspended successfully", 200)); } - private static Employee GetNewEmployeeModel(CreateUserDto model, Guid TenantId, string ApplicationUserId) { var newEmployee = new Employee @@ -511,7 +454,6 @@ namespace MarcoBMS.Services.Controllers }; return newEmployee; } - private static Employee GetUpdateEmployeeModel(CreateUserDto model, Employee existingEmployee, IdentityUser? existingIdentityUser = null) { if (existingEmployee.ApplicationUserId == null && existingIdentityUser != null) @@ -536,7 +478,6 @@ namespace MarcoBMS.Services.Controllers return existingEmployee; } - private static async Task GetFileDetails(IFormFile file) { FileDetails info = new FileDetails();