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 _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 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> 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.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>(typeList); _logger.LogInfo("{Count} records of expense type have been fetched successfully by employee {EmployeeId}", response.Count, loggedInEmployee.Id); return ApiResponse.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.ErrorResponse("Internal Error occured", ExceptionMapper(ex), 500); } } public async Task> 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.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.ErrorResponse("Access Denied.", "You do not have permission to Manage masters", 403); } var expensesType = _mapper.Map(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(expensesType); return ApiResponse.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.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.ErrorResponse("Internal Error occured", ExceptionMapper(ex), 500); } } public async Task> 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.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.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.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.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(expensesType); return ApiResponse.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.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.ErrorResponse("Internal Error occured", ExceptionMapper(ex), 500); } } public async Task> 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.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.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.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(expensesType); return ApiResponse.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.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.ErrorResponse("Internal Error occured", ExceptionMapper(ex), 500); } } #endregion #region =================================================================== Expenses Status APIs =================================================================== public async Task> 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.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>(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.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.ErrorResponse("Internal Error occured", ExceptionMapper(ex), 500); } } public async Task> 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.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.ErrorResponse("Access Denied.", "You do not have permission to Manage masters", 403); } // Mapping the DTO to ExpensesStatusMaster Model var expensesStatus = _mapper.Map(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(expensesStatus); return ApiResponse.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.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.ErrorResponse("Internal Error occured", ExceptionMapper(ex), 500); } } public async Task> 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.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.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.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.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(expensesStatus); return ApiResponse.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.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.ErrorResponse("Internal Error occured", ExceptionMapper(ex), 500); } } public async Task> 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.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.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.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(expensesStatus); return ApiResponse.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.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.ErrorResponse("Internal Error occured", ExceptionMapper(ex), 500); } } #endregion #region =================================================================== Payment mode APIs =================================================================== public async Task> 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.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>(paymentModes); _logger.LogInfo("{Count} records of payment modes have been fetched successfully by employee {EmployeeId}", response.Count, loggedInEmployee.Id); return ApiResponse.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.ErrorResponse("Internal Error occured while featching list of payment modes list", ExceptionMapper(ex), 500); } } public async Task> 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.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.ErrorResponse("Access Denied.", "You do not have permission to Manage masters", 403); } // Mapping the DTO to PaymentModeMatser Model var paymentMode = _mapper.Map(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(paymentMode); return ApiResponse.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.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.ErrorResponse("Internal Error occured", ExceptionMapper(ex), 500); } } public async Task> 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.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.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.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.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(paymentMode); return ApiResponse.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.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.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 } }