378 lines
15 KiB
C#

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<IdentityUser> _userManager;
private readonly IEmailSender _emailSender;
private readonly EmployeeHelper _employeeHelper;
private readonly UserHelper _userHelper;
private readonly IConfiguration _configuration;
public EmployeeController(UserManager<IdentityUser> 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<IActionResult> GetRoles(int employeeId)
{
if (!ModelState.IsValid)
{
var errors = ModelState.Values
.SelectMany(v => v.Errors)
.Select(e => e.ErrorMessage)
.ToList();
return BadRequest(ApiResponse<object>.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<EmployeeRolesVM> roles = new List<EmployeeRolesVM>();
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<object>.SuccessResponse(roles, "Success.", 200));
}
else
{
return BadRequest(ApiResponse<object>.ErrorResponse("This employee has no assigned permissions.", "This employee has no assigned permissions.", 400));
}
}
[HttpPost]
[Route("roles")]
public async Task<IActionResult> ManageRoles([FromBody] List<EmployeeRoleDot> employeeRoleDots)
{
if (!ModelState.IsValid)
{
var errors = ModelState.Values
.SelectMany(v => v.Errors)
.Select(e => e.ErrorMessage)
.ToList();
return BadRequest(ApiResponse<object>.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<object>.ErrorResponse(ex.Message, ex, 400));
}
return Ok(ApiResponse<object>.SuccessResponse("success", "Roles modified.", 200));
}
[HttpGet]
[Route("list/{projectid?}")]
public async Task<IActionResult> GetEmployeesByProject(int? projectid)
{
if (!ModelState.IsValid)
{
var errors = ModelState.Values
.SelectMany(v => v.Errors)
.Select(e => e.ErrorMessage)
.ToList();
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid data", errors, 400));
}
var result = await _employeeHelper.GetEmployeeByProjectId(GetTenantId(), projectid);
return Ok(ApiResponse<object>.SuccessResponse(result, "Filter applied.", 200));
}
[HttpGet]
[Route("search/{name}/{projectid?}")]
public async Task<IActionResult> SearchEmployee(string name, int? projectid)
{
if (!ModelState.IsValid)
{
var errors = ModelState.Values
.SelectMany(v => v.Errors)
.Select(e => e.ErrorMessage)
.ToList();
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid data", errors, 400));
}
var result = await _employeeHelper.SearchEmployeeByProjectId(GetTenantId(), name.ToLower(), projectid);
return Ok(ApiResponse<object>.SuccessResponse(result, "Filter applied.", 200));
}
[HttpGet]
[Route("profile/get/{employeeId}")]
public async Task<IActionResult> GetEmployeeProfileById(int employeeId)
{
if (!ModelState.IsValid)
{
var errors = ModelState.Values
.SelectMany(v => v.Errors)
.Select(e => e.ErrorMessage)
.ToList();
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid data", errors, 400));
}
Employee emp = await _employeeHelper.GetEmployeeByID(employeeId);
EmployeeVM employeeVM = EmployeeMapper.ToEmployeeVMFromEmployee(emp);
return Ok(ApiResponse<object>.SuccessResponse(employeeVM, "Employee Profile.", 200));
}
private int GetTenantId()
{
return _userHelper.GetTenantId();
}
//[HttpPost("manage/quick")]
//public async Task<IActionResult> CreateQuickUser([FromBody] CreateQuickUserDto model)
//{
// return Ok("Pending implementation");
//}
[HttpPost("manage")]
public async Task<IActionResult> CreateUser([FromForm] CreateUserDto model)
{
int tenantId = _userHelper.GetTenantId();
if (model == null)
return BadRequest(ApiResponse<object>.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);
var existingEmployee = await _context.Employees.FirstOrDefaultAsync(e => e.Id == model.Id);
if (existingUser != null)
{
/* Identity user Exists - Create/update employee Employee */
// Update Employee record
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<object>.ErrorResponse("Email already exist", "Email already exist", 400));
}
}
else
{
var user = new ApplicationUser
{
UserName = model.Email,
Email = model.Email,
EmailConfirmed = true,
TenantId = tenantId
};
// Create Identity User
var result = await _userManager.CreateAsync(user, "User@123");
if (!result.Succeeded)
return Ok(ApiResponse<object>.ErrorResponse("Failed to create user", result.Errors, 400));
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);
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<object>.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<FileDetails> 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;
}
}
}