Compare commits

...

3 Commits

6 changed files with 205 additions and 21 deletions

View File

@ -0,0 +1,12 @@
namespace Marco.Pms.Model.Dtos.Master
{
public class ExpensesStatusMasterDto
{
public Guid? Id { get; set; }
public required string Name { get; set; } = string.Empty;
public string DisplayName { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public List<Guid>? PermissionIds { get; set; }
public required string? Color { get; set; }
}
}

View File

@ -0,0 +1,9 @@
namespace Marco.Pms.Model.Dtos.Master
{
public class PaymentModeMatserDto
{
public Guid? Id { get; set; }
public string Name { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
}
}

View File

@ -879,7 +879,7 @@ namespace Marco.Pms.Services.Controllers
public async Task<IActionResult> CreateExpenseType(ExpensesTypeMasterDto dto)
{
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _masterService.GetExpenseTypeListAsync(loggedInEmployee, tenantId);
var response = await _masterService.CreateExpenseTypeAsync(dto, loggedInEmployee, tenantId);
return StatusCode(response.StatusCode, response);
}
@ -888,10 +888,10 @@ namespace Marco.Pms.Services.Controllers
#region =================================================================== Expenses Status APIs ===================================================================
[HttpGet("expenses-status")]
public async Task<IActionResult> GetExpenseStatusList()
public async Task<IActionResult> GetExpensesStatusList()
{
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _masterService.GetExpenseStatusListAsync(loggedInEmployee, tenantId);
var response = await _masterService.GetExpensesStatusListAsync(loggedInEmployee, tenantId);
return StatusCode(response.StatusCode, response);
}
@ -908,6 +908,13 @@ namespace Marco.Pms.Services.Controllers
return StatusCode(response.StatusCode, response);
}
[HttpPost("payment-mode")]
public async Task<IActionResult> CreatePaymentMode(PaymentModeMatserDto dto)
{
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _masterService.CreatePaymentModeAsync(dto, loggedInEmployee, tenantId);
return StatusCode(response.StatusCode, response);
}
#endregion
}

View File

@ -188,15 +188,16 @@ namespace Marco.Pms.Services.MappingProfiles
#endregion
#region ======================================================= Master =======================================================
#region ======================================================= Expenses Type Master =======================================================
CreateMap<ExpensesTypeMasterDto, ExpensesTypeMaster>()
.ForMember(
dest => dest.Id,
// Explicitly and safely convert nullable Guid to non-nullable Guid
opt => opt.MapFrom(src => src.Id != null ? src.Id : Guid.Empty)
opt => opt.MapFrom(src => src.Id ?? Guid.Empty)
);
CreateMap<ExpensesTypeMaster, ExpensesTypeMasterVM>();
CreateMap<ExpensesStatusMaster, ExpensesStatusMasterVM>();
CreateMap<PaymentModeMatser, PaymentModeMatserVM>();
CreateMap<ExpensesTypeMaster, ExpensesTypeMasterMongoDB>()
.ForMember(
@ -205,10 +206,23 @@ namespace Marco.Pms.Services.MappingProfiles
.ForMember(
dest => dest.TenantId,
opt => opt.MapFrom(src => src.TenantId.ToString()));
CreateMap<ExpensesTypeMasterMongoDB, ExpensesTypeMasterVM>()
.ForMember(
dest => dest.Id,
opt => opt.MapFrom(src => Guid.Parse(src.Id)));
#endregion
#region ======================================================= Expenses Status Master =======================================================
CreateMap<ExpensesStatusMasterDto, ExpensesStatusMaster>()
.ForMember(
dest => dest.Id,
opt => opt.MapFrom(src => src.Id ?? Guid.Empty))
.ForMember(
dest => dest.DisplayName,
opt => opt.MapFrom(src => string.IsNullOrWhiteSpace(src.DisplayName) ? src.Name : src.DisplayName));
CreateMap<ExpensesStatusMaster, ExpensesStatusMasterVM>();
CreateMap<ExpensesStatusMaster, ExpensesStatusMasterMongoDB>()
.ForMember(
@ -217,10 +231,22 @@ namespace Marco.Pms.Services.MappingProfiles
.ForMember(
dest => dest.TenantId,
opt => opt.MapFrom(src => src.TenantId.ToString()));
CreateMap<ExpensesStatusMasterMongoDB, ExpensesStatusMasterVM>()
.ForMember(
dest => dest.Id,
opt => opt.MapFrom(src => Guid.Parse(src.Id)));
#endregion
#region ======================================================= Payment Mode Matser =======================================================
CreateMap<PaymentModeMatserDto, PaymentModeMatser>()
.ForMember(
dest => dest.Id,
// Explicitly and safely convert nullable Guid to non-nullable Guid
opt => opt.MapFrom(src => src.Id ?? Guid.Empty)
);
CreateMap<PaymentModeMatser, PaymentModeMatserVM>();
CreateMap<PaymentModeMatser, PaymentModeMatserMongoDB>()
.ForMember(
@ -229,11 +255,13 @@ namespace Marco.Pms.Services.MappingProfiles
.ForMember(
dest => dest.TenantId,
opt => opt.MapFrom(src => src.TenantId.ToString()));
CreateMap<PaymentModeMatserMongoDB, PaymentModeMatserVM>()
.ForMember(
dest => dest.Id,
opt => opt.MapFrom(src => Guid.Parse(src.Id)));
#endregion
#endregion

View File

@ -3,6 +3,7 @@ using Marco.Pms.DataAccess.Data;
using Marco.Pms.Model.Dtos.Master;
using Marco.Pms.Model.Employees;
using Marco.Pms.Model.Entitlements;
using Marco.Pms.Model.Expenses;
using Marco.Pms.Model.Master;
using Marco.Pms.Model.Utilities;
using Marco.Pms.Model.ViewModels.Master;
@ -58,27 +59,49 @@ namespace Marco.Pms.Services.Service
}
}
public async Task<ApiResponse<object>> CreateExpenseTypeAsync(ExpensesTypeMasterDto dto, Employee loggedInEmployee, Guid tenantId)
public async Task<ApiResponse<object>> CreateExpenseTypeAsync(ExpensesTypeMasterDto model, Employee loggedInEmployee, Guid tenantId)
{
var hasManagePermission = await _permission.HasPermission(PermissionsMaster.ManageMasters, loggedInEmployee.Id);
if (!hasManagePermission)
try
{
_logger.LogWarning("Access DENIED for employee {EmployeeId} for managing EXPANSES TYPE MASTER.", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Access Denied.", "You do not have permission to Upload expenses for this project", 403);
}
var expensesType = _mapper.Map<ExpensesTypeMaster>(dto);
_context.ExpensesTypeMaster.Add(expensesType);
await _context.SaveChangesAsync();
_logger.LogInfo("New Expense Type {ExpensesTypeId} was added by employee {EmployeeId}", expensesType.Id, loggedInEmployee.Id);
// Validation if employee is taking action in same tenant
if (tenantId != loggedInEmployee.TenantId)
{
_logger.LogWarning("Employee {EmployeeId} attempted to add new expense type in different tenant", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Access Denied", "User do not have access for this information", 403);
}
var hasManagePermission = await _permission.HasPermission(PermissionsMaster.ManageMasters, loggedInEmployee.Id);
if (!hasManagePermission)
{
_logger.LogWarning("Access DENIED for employee {EmployeeId} for managing EXPANSES TYPE MASTER.", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Access Denied.", "You do not have permission to Upload expenses for this project", 403);
}
var expensesType = _mapper.Map<ExpensesTypeMaster>(model);
expensesType.TenantId = tenantId;
var response = _mapper.Map<ExpensesTypeMasterVM>(expensesType);
return ApiResponse<object>.SuccessResponse(response, "Expense type craeted Successfully", 201);
_context.ExpensesTypeMaster.Add(expensesType);
await _context.SaveChangesAsync();
_logger.LogInfo("New Expense Type {ExpensesTypeId} was added by employee {EmployeeId}", expensesType.Id, loggedInEmployee.Id);
var response = _mapper.Map<ExpensesTypeMasterVM>(expensesType);
return ApiResponse<object>.SuccessResponse(response, "Expense type craeted Successfully", 201);
}
catch (DbUpdateException dbEx)
{
_logger.LogError(dbEx, "Database Exception occured while adding new expense type by employee {EmployeeId}", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Internal Error occured", ExceptionMapper(dbEx), 500);
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception occured while adding new expense type by employee {EmployeeId}", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Internal Error occured", ExceptionMapper(ex), 500);
}
}
#endregion
#region =================================================================== Expenses Status APIs ===================================================================
public async Task<ApiResponse<object>> GetExpenseStatusListAsync(Employee loggedInEmployee, Guid tenantId)
public async Task<ApiResponse<object>> GetExpensesStatusListAsync(Employee loggedInEmployee, Guid tenantId)
{
try
@ -119,6 +142,59 @@ namespace Marco.Pms.Services.Service
}
}
public async Task<ApiResponse<object>> CreateExpensesStatusAsync(ExpensesStatusMasterDto model, Employee loggedInEmployee, Guid tenantId)
{
try
{
// Validation if employee is taking action in same tenant
if (tenantId != loggedInEmployee.TenantId)
{
_logger.LogWarning("Employee {EmployeeId} attempted to add new Expense Status in different tenant", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Access Denied", "User do not have access for this information", 403);
}
var hasManagePermission = await _permission.HasPermission(PermissionsMaster.ManageMasters, loggedInEmployee.Id);
if (!hasManagePermission)
{
_logger.LogWarning("Access DENIED for employee {EmployeeId} for managing EXPENSE STATUS MASTER.", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Access Denied.", "You do not have permission to Upload expenses for this project", 403);
}
// Mapping the DTO to ExpensesStatusMaster Model
var expensesStatus = _mapper.Map<ExpensesStatusMaster>(model);
expensesStatus.TenantId = tenantId;
_context.ExpensesStatusMaster.Add(expensesStatus);
if (model.PermissionIds?.Any() ?? false)
{
var permissionStatusMappings = model.PermissionIds.Select(p => new StatusPermissionMapping
{
PermissionId = p,
StatusId = expensesStatus.Id,
TenantId = tenantId
}).ToList();
_context.StatusPermissionMapping.AddRange(permissionStatusMappings);
}
await _context.SaveChangesAsync();
_logger.LogInfo("New Expense Status {ExpensesStatusId} was added by employee {EmployeeId}", expensesStatus.Id, loggedInEmployee.Id);
// Mapping the ExpensesStatusMaster Model to View Model
var response = _mapper.Map<ExpensesStatusMasterVM>(expensesStatus);
return ApiResponse<object>.SuccessResponse(response, "Expense Status craeted Successfully", 201);
}
catch (DbUpdateException dbEx)
{
_logger.LogError(dbEx, "Database Exception occured while adding new Expense Status by employee {EmployeeId}", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Internal Error occured", ExceptionMapper(dbEx), 500);
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception occured while adding new Expense Status by employee {EmployeeId}", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Internal Error occured", ExceptionMapper(ex), 500);
}
}
#endregion
@ -147,7 +223,47 @@ namespace Marco.Pms.Services.Service
return ApiResponse<object>.ErrorResponse("Internal Error occured while featching list of payment modes list", ExceptionMapper(ex), 500);
}
}
public async Task<ApiResponse<object>> CreatePaymentModeAsync(PaymentModeMatserDto model, Employee loggedInEmployee, Guid tenantId)
{
try
{
// Validation if employee is taking action in same tenant
if (tenantId != loggedInEmployee.TenantId)
{
_logger.LogWarning("Employee {EmployeeId} attempted to add new payment mode in different tenant", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Access Denied", "User do not have access for this information", 403);
}
var hasManagePermission = await _permission.HasPermission(PermissionsMaster.ManageMasters, loggedInEmployee.Id);
if (!hasManagePermission)
{
_logger.LogWarning("Access DENIED for employee {EmployeeId} for managing PAYMENT MODE MASTER.", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Access Denied.", "You do not have permission to Upload expenses for this project", 403);
}
// Mapping the DTO to PaymentModeMatser Model
var paymentMode = _mapper.Map<PaymentModeMatser>(model);
paymentMode.TenantId = tenantId;
_context.PaymentModeMatser.Add(paymentMode);
await _context.SaveChangesAsync();
_logger.LogInfo("New Payment Mode {PaymentModeId} was added by employee {EmployeeId}", paymentMode.Id, loggedInEmployee.Id);
// Mapping the PaymentModeMatser Model to View Model
var response = _mapper.Map<PaymentModeMatserVM>(paymentMode);
return ApiResponse<object>.SuccessResponse(response, "Payment Mode craeted Successfully", 201);
}
catch (DbUpdateException dbEx)
{
_logger.LogError(dbEx, "Database Exception occured while adding new payment mode by employee {EmployeeId}", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Internal Error occured", ExceptionMapper(dbEx), 500);
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception occured while adding new payment mode by employee {EmployeeId}", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Internal Error occured", ExceptionMapper(ex), 500);
}
}
#endregion

View File

@ -1,12 +1,24 @@
using Marco.Pms.Model.Employees;
using Marco.Pms.Model.Dtos.Master;
using Marco.Pms.Model.Employees;
using Marco.Pms.Model.Utilities;
namespace Marco.Pms.Services.Service.ServiceInterfaces
{
public interface IMasterService
{
#region =================================================================== Expenses Type APIs ===================================================================
Task<ApiResponse<object>> GetExpenseTypeListAsync(Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> GetExpenseStatusListAsync(Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> CreateExpenseTypeAsync(ExpensesTypeMasterDto model, Employee loggedInEmployee, Guid tenantId);
#endregion
#region =================================================================== Expenses Status APIs ===================================================================
Task<ApiResponse<object>> GetExpensesStatusListAsync(Employee loggedInEmployee, Guid tenantId);
#endregion
#region =================================================================== Payment mode APIs ===================================================================
Task<ApiResponse<object>> GetPaymentModeListAsync(Employee loggedInEmployee, Guid tenantId);
Task<ApiResponse<object>> CreatePaymentModeAsync(PaymentModeMatserDto model, Employee loggedInEmployee, Guid tenantId);
#endregion
}
}