665 lines
36 KiB
C#

using AutoMapper;
using Marco.Pms.DataAccess.Data;
using Marco.Pms.Helpers.Utility;
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.MongoDBModels.Utility;
using Marco.Pms.Model.Utilities;
using Marco.Pms.Model.ViewModels.Master;
using Marco.Pms.Services.Helpers;
using Marco.Pms.Services.Service.ServiceInterfaces;
using MarcoBMS.Services.Service;
using Microsoft.CodeAnalysis;
using Microsoft.EntityFrameworkCore;
namespace Marco.Pms.Services.Service
{
public class MasterService : IMasterService
{
private readonly IDbContextFactory<ApplicationDbContext> _dbContextFactory;
private readonly ApplicationDbContext _context;
private readonly ILoggingService _logger;
private readonly PermissionServices _permission;
private readonly IMapper _mapper;
private readonly UtilityMongoDBHelper _updateLogHelper;
private readonly CacheUpdateHelper _cache;
public MasterService(
IDbContextFactory<ApplicationDbContext> dbContextFactory,
ApplicationDbContext context,
ILoggingService logger,
PermissionServices permission,
IMapper mapper,
UtilityMongoDBHelper updateLogHelper,
CacheUpdateHelper cache)
{
_dbContextFactory = dbContextFactory;
_context = context;
_logger = logger;
_permission = permission;
_mapper = mapper;
_updateLogHelper = updateLogHelper;
_cache = cache;
}
#region =================================================================== Expenses Type APIs ===================================================================
public async Task<ApiResponse<object>> GetExpenseTypeListAsync(Employee loggedInEmployee, Guid tenantId)
{
try
{
// Validation if employee is taking action in same tenant
if (tenantId != loggedInEmployee.TenantId)
{
_logger.LogWarning("Employee {EmployeeId} attempted to fetch the list of expense type from different tenant", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Access Denied", "User do not have access for this information", 403);
}
// Featching the list of Expenses Type.
var typeList = await _context.ExpensesTypeMaster.Where(et => et.TenantId == tenantId).ToListAsync();
var response = _mapper.Map<List<ExpensesTypeMasterVM>>(typeList);
_logger.LogInfo("{Count} records of expense type have been fetched successfully by employee {EmployeeId}", response.Count, loggedInEmployee.Id);
return ApiResponse<object>.SuccessResponse(response, $"{response.Count} records of expense type have been fetched successfully.", 200);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error occured while fetching list of expense type list by employee {EmployeeId}", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Internal Error occured", ExceptionMapper(ex), 500);
}
}
public async Task<ApiResponse<object>> CreateExpenseTypeAsync(ExpensesTypeMasterDto 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 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 Manage masters", 403);
}
var expensesType = _mapper.Map<ExpensesTypeMaster>(model);
expensesType.TenantId = tenantId;
_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);
}
}
public async Task<ApiResponse<object>> UpdateExpenseTypeAsync(Guid id, ExpensesTypeMasterDto 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 update expense type in different tenant", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Access Denied", "User do not have access for this information", 403);
}
// Checking permssion for managing masters
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 Manage masters", 403);
}
// Validating the prvided data
if (model.Id != id)
{
_logger.LogWarning("Employee {EmployeeId} provide different Ids in payload and path variable", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Invalid Data", "User has send invalid payload", 400);
}
var expensesType = await _context.ExpensesTypeMaster.AsNoTracking().FirstOrDefaultAsync(et => et.Id == model.Id.Value && et.TenantId == tenantId);
// Checking if expense type exists
if (expensesType == null)
{
_logger.LogWarning("Employee {EmployeeId} tries to update expense type, but not found in database", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Expense Type not found", "Expense Type not found", 404);
}
// Mapping ExpensesTypeMaster to BsonDocument
var existingEntityBson = _updateLogHelper.EntityToBsonDocument(expensesType);
// Mapping ExpensesTypeMasterDto to ExpensesTypeMaster
_mapper.Map(model, expensesType);
_context.ExpensesTypeMaster.Update(expensesType);
await _context.SaveChangesAsync();
_logger.LogInfo("Expense Type {ExpensesTypeId} was updated by employee {EmployeeId}", expensesType.Id, loggedInEmployee.Id);
// Saving the old entity in mongoDB
var mongoDBTask = _updateLogHelper.PushToUpdateLogsAsync(new UpdateLogsObject
{
EntityId = expensesType.Id.ToString(),
UpdatedById = loggedInEmployee.Id.ToString(),
OldObject = existingEntityBson,
UpdatedAt = DateTime.UtcNow
}, "ExpensesTypeMasterModificationLog");
// Mapping ExpensesTypeMaster to ExpensesTypeMasterVM
var response = _mapper.Map<ExpensesTypeMasterVM>(expensesType);
return ApiResponse<object>.SuccessResponse(response, "Expense type updated Successfully", 200);
}
catch (DbUpdateException dbEx)
{
_logger.LogError(dbEx, "Database Exception occured while updating 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 updating expense type by employee {EmployeeId}", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Internal Error occured", ExceptionMapper(ex), 500);
}
}
public async Task<ApiResponse<object>> DeleteExpenseTypeAsync(Guid id, bool isActive, Employee loggedInEmployee, Guid tenantId)
{
string action = isActive ? "delete" : "restore";
try
{
// Validation if employee is taking action in same tenant
if (tenantId != loggedInEmployee.TenantId)
{
_logger.LogWarning("Employee {EmployeeId} attempted to {Action} expense type in different tenant", loggedInEmployee.Id, action);
return ApiResponse<object>.ErrorResponse("Access Denied", "User do not have access for this information", 403);
}
// Checking permssion for managing masters
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 Manage masters", 403);
}
var expensesType = await _context.ExpensesTypeMaster.FirstOrDefaultAsync(et => et.Id == id && et.TenantId == tenantId);
// Checking if expense type exists
if (expensesType == null)
{
_logger.LogWarning("Employee {EmployeeId} tries to {Action} expense type, but not found in database", loggedInEmployee.Id, action);
return ApiResponse<object>.ErrorResponse("Expense Type not found", "Expense Type not found", 404);
}
// Mapping ExpensesTypeMaster to BsonDocument
var existingEntityBson = _updateLogHelper.EntityToBsonDocument(expensesType);
expensesType.IsActive = isActive;
await _context.SaveChangesAsync();
_logger.LogInfo("Expense Type {ExpensesTypeId} was {Action}d by employee {EmployeeId}", expensesType.Id, action, loggedInEmployee.Id);
// Saving the old entity in mongoDB
var mongoDBTask = _updateLogHelper.PushToUpdateLogsAsync(new UpdateLogsObject
{
EntityId = expensesType.Id.ToString(),
UpdatedById = loggedInEmployee.Id.ToString(),
OldObject = existingEntityBson,
UpdatedAt = DateTime.UtcNow
}, "ExpensesTypeMasterModificationLog");
// Mapping ExpensesTypeMaster to ExpensesTypeMasterVM
var response = _mapper.Map<ExpensesTypeMasterVM>(expensesType);
return ApiResponse<object>.SuccessResponse(response, $"Expense type {action}d Successfully", 200);
}
catch (DbUpdateException dbEx)
{
_logger.LogError(dbEx, "Database Exception occured while {Action}ing expense type by employee {EmployeeId}", action, loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Internal Error occured", ExceptionMapper(dbEx), 500);
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception occured while {Action}ing expense type by employee {EmployeeId}", action, loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Internal Error occured", ExceptionMapper(ex), 500);
}
}
#endregion
#region =================================================================== Expenses Status APIs ===================================================================
public async Task<ApiResponse<object>> GetExpensesStatusListAsync(Employee loggedInEmployee, Guid tenantId)
{
try
{
// Validation if employee is taking action in same tenant
if (tenantId != loggedInEmployee.TenantId)
{
_logger.LogWarning("Employee {EmployeeId} attempted to fetch the list of expense status from different tenant", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Access Denied", "User do not have access for this information", 403);
}
// Featching the list of Expenses Status.
var statusList = await _context.ExpensesStatusMaster.Where(es => es.TenantId == tenantId).ToListAsync();
var response = _mapper.Map<List<ExpensesStatusMasterVM>>(statusList);
var statusIds = statusList.Select(s => s.Id).ToList();
var permissionStatusMapping = await _context.StatusPermissionMapping
.Where(ps => statusIds.Contains(ps.StatusId))
.GroupBy(ps => ps.StatusId)
.Select(g => new
{
StatusId = g.Key,
PermissionIds = g.Select(ps => ps.PermissionId).ToList()
}).ToListAsync();
foreach (var status in response)
{
status.PermissionIds = permissionStatusMapping.Where(ps => ps.StatusId == status.Id).Select(ps => ps.PermissionIds).FirstOrDefault();
}
_logger.LogInfo("{Count} records of expense status have been fetched successfully by employee {EmployeeId}", response.Count, loggedInEmployee.Id);
return ApiResponse<object>.SuccessResponse(response, $"{response.Count} records of expense status have been fetched successfully.", 200);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error occured while fetching list of expense sattus list by employee {EmployeeId}", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Internal Error occured", ExceptionMapper(ex), 500);
}
}
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 Manage masters", 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);
}
}
public async Task<ApiResponse<object>> UpdateExpensesStatusAsync(Guid id, 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);
}
// Checking permssion for managing masters
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 Manage masters", 403);
}
// Validating the prvided data
if (model.Id != id)
{
_logger.LogWarning("Employee {EmployeeId} provide different Ids in payload and path variable", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Invalid Data", "User has send invalid payload", 400);
}
// featching expenses status and permissions parallelly
var expensesStatusTask = Task.Run(async () =>
{
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
return await dbContext.ExpensesStatusMaster.AsNoTracking()
.FirstOrDefaultAsync(et => et.Id == model.Id.Value && et.TenantId == tenantId);
});
var permissionStatusMappingsTask = Task.Run(async () =>
{
await using var dbContext = await _dbContextFactory.CreateDbContextAsync();
return await dbContext.StatusPermissionMapping
.AsNoTracking()
.Where(ps => ps.StatusId == model.Id.Value && ps.TenantId == tenantId)
.ToListAsync();
});
await Task.WhenAll(expensesStatusTask, permissionStatusMappingsTask);
var expensesStatus = expensesStatusTask.Result;
// Checking if Expense Status exists
if (expensesStatus == null)
{
_logger.LogWarning("Employee {EmployeeId} tries to update Expense Status, but not found in database", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Expense Status not found", "Expense Status not found", 404);
}
// Mapping ExpensesStatusMaster to BsonDocument
var existingEntityBson = _updateLogHelper.EntityToBsonDocument(expensesStatus);
// Mapping ExpensesStatusMasterDto to ExpensesStatusMaster
_mapper.Map(model, expensesStatus);
_context.ExpensesStatusMaster.Update(expensesStatus);
var permissionStatusMappings = permissionStatusMappingsTask.Result;
var permissionIds = permissionStatusMappings.Select(ps => ps.PermissionId).ToList();
if (model.PermissionIds != null)
{
var newPermissionStatusMappings = model.PermissionIds.Where(p => !permissionIds.Contains(p)).Select(p => new StatusPermissionMapping
{
PermissionId = p,
StatusId = expensesStatus.Id,
TenantId = tenantId
}).ToList();
var deletedPermissionStatusMappings = permissionStatusMappings.Where(ps => !model.PermissionIds.Contains(ps.PermissionId)).ToList();
_context.StatusPermissionMapping.AddRange(newPermissionStatusMappings);
_context.StatusPermissionMapping.RemoveRange(deletedPermissionStatusMappings);
}
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);
}
}
public async Task<ApiResponse<object>> DeleteExpensesStatusAsync(Guid id, bool isActive, Employee loggedInEmployee, Guid tenantId)
{
string action = isActive ? "delete" : "restore";
try
{
// Validation if employee is taking action in same tenant
if (tenantId != loggedInEmployee.TenantId)
{
_logger.LogWarning("Employee {EmployeeId} attempted to {Action} Expense Status in different tenant", loggedInEmployee.Id, action);
return ApiResponse<object>.ErrorResponse("Access Denied", "User do not have access for this information", 403);
}
// Checking permssion for managing masters
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 Manage masters", 403);
}
var expensesStatus = await _context.ExpensesStatusMaster.FirstOrDefaultAsync(et => et.Id == id && et.TenantId == tenantId);
// Checking if Expense Status exists
if (expensesStatus == null)
{
_logger.LogWarning("Employee {EmployeeId} tries to {Action} Expense Status, but not found in database", loggedInEmployee.Id, action);
return ApiResponse<object>.ErrorResponse("Expense Status not found", "Expense Status not found", 404);
}
// Mapping ExpensesStatusMaster to BsonDocument
var existingEntityBson = _updateLogHelper.EntityToBsonDocument(expensesStatus);
expensesStatus.IsActive = isActive;
await _context.SaveChangesAsync();
_logger.LogInfo("Expense Status {ExpensesStatusId} was {Action}d by employee {EmployeeId}", expensesStatus.Id, action, loggedInEmployee.Id);
// Saving the old entity in mongoDB
var mongoDBTask = _updateLogHelper.PushToUpdateLogsAsync(new UpdateLogsObject
{
EntityId = expensesStatus.Id.ToString(),
UpdatedById = loggedInEmployee.Id.ToString(),
OldObject = existingEntityBson,
UpdatedAt = DateTime.UtcNow
}, "ExpensesStatusMasterModificationLog");
// Mapping ExpensesStatusMaster to ExpensesStatusMasterVM
var response = _mapper.Map<ExpensesStatusMasterVM>(expensesStatus);
return ApiResponse<object>.SuccessResponse(response, $"Expense Status {action}d Successfully", 200);
}
catch (DbUpdateException dbEx)
{
_logger.LogError(dbEx, "Database Exception occured while {Action}ing Expense Status by employee {EmployeeId}", action, loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Internal Error occured", ExceptionMapper(dbEx), 500);
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception occured while {Action}ing Expense Status by employee {EmployeeId}", action, loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Internal Error occured", ExceptionMapper(ex), 500);
}
}
#endregion
#region =================================================================== Payment mode APIs ===================================================================
public async Task<ApiResponse<object>> GetPaymentModeListAsync(Employee loggedInEmployee, Guid tenantId)
{
try
{
// Validation if employee is taking action in same tenant
if (tenantId != loggedInEmployee.TenantId)
{
_logger.LogWarning("Employee {EmployeeId} attempted to fetch the list of payment modes from different tenant", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Access Denied", "User do not have access for this information", 403);
}
// Featching the list of Payment Modes.
var paymentModes = await _context.PaymentModeMatser.Where(pm => pm.TenantId == tenantId).ToListAsync();
var response = _mapper.Map<List<PaymentModeMatserVM>>(paymentModes);
_logger.LogInfo("{Count} records of payment modes have been fetched successfully by employee {EmployeeId}", response.Count, loggedInEmployee.Id);
return ApiResponse<object>.SuccessResponse(response, $"{response.Count} records of payment modes have been fetched successfully.", 200);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error occured while featching list of payment modes list by employee {EmployeeId}", loggedInEmployee.Id);
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 Manage masters", 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);
}
}
public async Task<ApiResponse<object>> UpdatePaymentModeAsync(Guid id, 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 update Payment Mode in different tenant", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Access Denied", "User do not have access for this information", 403);
}
// Checking permssion for managing masters
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 Manage masters", 403);
}
// Validating the prvided data
if (model.Id != id)
{
_logger.LogWarning("Employee {EmployeeId} provide different Ids in payload and path variable", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Invalid Data", "User has send invalid payload", 400);
}
var paymentMode = await _context.PaymentModeMatser.AsNoTracking().FirstOrDefaultAsync(et => et.Id == model.Id.Value && et.TenantId == tenantId);
// Checking if Payment Mode exists
if (paymentMode == null)
{
_logger.LogWarning("Employee {EmployeeId} tries to update Payment Mode, but not found in database", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Payment Mode not found", "Payment Mode not found", 404);
}
// Mapping PaymentModeMatser to BsonDocument
var existingEntityBson = _updateLogHelper.EntityToBsonDocument(paymentMode);
// Mapping PaymentModeMatserDto to PaymentModeMatser
_mapper.Map(model, paymentMode);
_context.PaymentModeMatser.Update(paymentMode);
await _context.SaveChangesAsync();
_logger.LogInfo("Payment Mode {PaymentModeId} was updated by employee {EmployeeId}", paymentMode.Id, loggedInEmployee.Id);
// Saving the old entity in mongoDB
var mongoDBTask = _updateLogHelper.PushToUpdateLogsAsync(new UpdateLogsObject
{
EntityId = paymentMode.Id.ToString(),
UpdatedById = loggedInEmployee.Id.ToString(),
OldObject = existingEntityBson,
UpdatedAt = DateTime.UtcNow
}, "PaymentModeMasterModificationLog");
// Mapping PaymentModeMatser to PaymentModeMatserVM
var response = _mapper.Map<PaymentModeMatserVM>(paymentMode);
return ApiResponse<object>.SuccessResponse(response, "Payment Mode updated Successfully", 200);
}
catch (DbUpdateException dbEx)
{
_logger.LogError(dbEx, "Database Exception occured while updating 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 updating Payment Mode by employee {EmployeeId}", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Internal Error occured", ExceptionMapper(ex), 500);
}
}
#endregion
#region =================================================================== Helper Function ===================================================================
private static object ExceptionMapper(Exception ex)
{
return new
{
Message = ex.Message,
StackTrace = ex.StackTrace,
Source = ex.Source,
InnerException = new
{
Message = ex.InnerException?.Message,
StackTrace = ex.InnerException?.StackTrace,
Source = ex.InnerException?.Source,
}
};
}
#endregion
}
}