diff --git a/Marco.Pms.Services/Controllers/MasterController.cs b/Marco.Pms.Services/Controllers/MasterController.cs index 0f34a05..3f00d2e 100644 --- a/Marco.Pms.Services/Controllers/MasterController.cs +++ b/Marco.Pms.Services/Controllers/MasterController.cs @@ -882,6 +882,13 @@ namespace Marco.Pms.Services.Controllers var response = await _masterService.CreateExpenseTypeAsync(dto, loggedInEmployee, tenantId); return StatusCode(response.StatusCode, response); } + [HttpPut("expenses-type/edit/{id}")] + public async Task UpdateExpenseType(Guid id, ExpensesTypeMasterDto dto) + { + var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); + var response = await _masterService.UpdateExpenseTypeAsync(id, dto, loggedInEmployee, tenantId); + return StatusCode(response.StatusCode, response); + } #endregion diff --git a/Marco.Pms.Services/Service/MasterService.cs b/Marco.Pms.Services/Service/MasterService.cs index 919ccdc..a03c8ef 100644 --- a/Marco.Pms.Services/Service/MasterService.cs +++ b/Marco.Pms.Services/Service/MasterService.cs @@ -1,12 +1,15 @@ 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.EntityFrameworkCore; @@ -19,17 +22,23 @@ namespace Marco.Pms.Services.Service private readonly ILoggingService _logger; private readonly PermissionServices _permission; private readonly IMapper _mapper; + private readonly UtilityMongoDBHelper _updateLogHelper; + private readonly CacheUpdateHelper _cache; public MasterService( ApplicationDbContext context, ILoggingService logger, PermissionServices permission, - IMapper mapper) + IMapper mapper, + UtilityMongoDBHelper updateLogHelper, + CacheUpdateHelper cache) { _context = context; _logger = logger; _permission = permission; _mapper = mapper; + _updateLogHelper = updateLogHelper; + _cache = cache; } #region =================================================================== Expenses Type APIs =================================================================== @@ -97,6 +106,77 @@ namespace Marco.Pms.Services.Service 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 Upload expenses for this project", 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("New 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); + } + } #endregion diff --git a/Marco.Pms.Services/Service/ServiceInterfaces/IMasterService.cs b/Marco.Pms.Services/Service/ServiceInterfaces/IMasterService.cs index 7269ee0..67217c4 100644 --- a/Marco.Pms.Services/Service/ServiceInterfaces/IMasterService.cs +++ b/Marco.Pms.Services/Service/ServiceInterfaces/IMasterService.cs @@ -9,6 +9,7 @@ namespace Marco.Pms.Services.Service.ServiceInterfaces #region =================================================================== Expenses Type APIs =================================================================== Task> GetExpenseTypeListAsync(Employee loggedInEmployee, Guid tenantId); Task> CreateExpenseTypeAsync(ExpensesTypeMasterDto model, Employee loggedInEmployee, Guid tenantId); + Task> UpdateExpenseTypeAsync(Guid id, ExpensesTypeMasterDto model, Employee loggedInEmployee, Guid tenantId); #endregion #region =================================================================== Expenses Status APIs ===================================================================