diff --git a/Marco.Pms.Model/ViewModels/Expenses/ExpenseList.cs b/Marco.Pms.Model/ViewModels/Expenses/ExpenseList.cs new file mode 100644 index 0000000..198102d --- /dev/null +++ b/Marco.Pms.Model/ViewModels/Expenses/ExpenseList.cs @@ -0,0 +1,23 @@ +using Marco.Pms.Model.ViewModels.Activities; +using Marco.Pms.Model.ViewModels.Master; +using Marco.Pms.Model.ViewModels.Projects; + +namespace Marco.Pms.Model.ViewModels.Expanses +{ + public class ExpenseList + { + public Guid Id { get; set; } + public ProjectInfoVM? Project { get; set; } + public ExpensesTypeMasterVM? ExpensesType { get; set; } + public PaymentModeMatserVM? PaymentMode { get; set; } + public BasicEmployeeVM? PaidBy { get; set; } + public BasicEmployeeVM? CreatedBy { get; set; } + public DateTime TransactionDate { get; set; } + public DateTime CreatedAt { get; set; } + public string SupplerName { get; set; } = string.Empty; + public double Amount { get; set; } + public ExpensesStatusMasterVM? Status { get; set; } + public List? NextStatus { get; set; } + public bool PreApproved { get; set; } = false; + } +} diff --git a/Marco.Pms.Model/ViewModels/Master/ExpensesStatusMasterVM.cs b/Marco.Pms.Model/ViewModels/Master/ExpensesStatusMasterVM.cs new file mode 100644 index 0000000..f772695 --- /dev/null +++ b/Marco.Pms.Model/ViewModels/Master/ExpensesStatusMasterVM.cs @@ -0,0 +1,10 @@ +namespace Marco.Pms.Model.ViewModels.Master +{ + public class ExpensesStatusMasterVM + { + public Guid Id { get; set; } + public string Name { get; set; } = string.Empty; + public string Description { get; set; } = string.Empty; + public bool IsSystem { get; set; } = false; + } +} diff --git a/Marco.Pms.Model/ViewModels/Master/ExpensesTypeMasterVM.cs b/Marco.Pms.Model/ViewModels/Master/ExpensesTypeMasterVM.cs new file mode 100644 index 0000000..f4551d3 --- /dev/null +++ b/Marco.Pms.Model/ViewModels/Master/ExpensesTypeMasterVM.cs @@ -0,0 +1,10 @@ +namespace Marco.Pms.Model.ViewModels.Master +{ + public class ExpensesTypeMasterVM + { + public Guid Id { get; set; } + public string Name { get; set; } = string.Empty; + public bool NoOfPersonsRequired { get; set; } + public string Description { get; set; } = string.Empty; + } +} diff --git a/Marco.Pms.Model/ViewModels/Master/PaymentModeMatserVM.cs b/Marco.Pms.Model/ViewModels/Master/PaymentModeMatserVM.cs new file mode 100644 index 0000000..de7716a --- /dev/null +++ b/Marco.Pms.Model/ViewModels/Master/PaymentModeMatserVM.cs @@ -0,0 +1,9 @@ +namespace Marco.Pms.Model.ViewModels.Master +{ + public class PaymentModeMatserVM + { + public Guid Id { get; set; } + public string Name { get; set; } = string.Empty; + public string Description { get; set; } = string.Empty; + } +} diff --git a/Marco.Pms.Services/Controllers/ExpanseController.cs b/Marco.Pms.Services/Controllers/ExpenseController.cs similarity index 73% rename from Marco.Pms.Services/Controllers/ExpanseController.cs rename to Marco.Pms.Services/Controllers/ExpenseController.cs index 9f85454..ccde41d 100644 --- a/Marco.Pms.Services/Controllers/ExpanseController.cs +++ b/Marco.Pms.Services/Controllers/ExpenseController.cs @@ -1,8 +1,11 @@ -using Marco.Pms.DataAccess.Data; +using AutoMapper; +using Marco.Pms.DataAccess.Data; using Marco.Pms.Model.Dtos.Expenses; using Marco.Pms.Model.Entitlements; using Marco.Pms.Model.Expenses; using Marco.Pms.Model.Utilities; +using Marco.Pms.Model.ViewModels.Expanses; +using Marco.Pms.Model.ViewModels.Master; using Marco.Pms.Services.Service; using MarcoBMS.Services.Helpers; using MarcoBMS.Services.Service; @@ -18,42 +21,100 @@ namespace Marco.Pms.Services.Controllers [Route("api/[controller]")] [ApiController] [Authorize] - public class ExpanseController : ControllerBase + public class ExpenseController : ControllerBase { private readonly ApplicationDbContext _context; private readonly UserHelper _userHelper; private readonly PermissionServices _permission; private readonly ILoggingService _logger; private readonly S3UploadService _s3Service; + private readonly IMapper _mapper; private readonly Guid tenantId; - public ExpanseController( + public ExpenseController( ApplicationDbContext context, UserHelper userHelper, PermissionServices permission, ILoggingService logger, - S3UploadService s3Service) + S3UploadService s3Service, + IMapper mapper) { _context = context; _userHelper = userHelper; _permission = permission; _logger = logger; - tenantId = userHelper.GetTenantId(); _s3Service = s3Service; + _mapper = mapper; + tenantId = userHelper.GetTenantId(); } [HttpGet("list")] - public async Task Get() + public async Task GetExpensesList() { - var expensesList = await _context.Expenses + var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); + var loggedInEmployeeId = loggedInEmployee.Id; + + List? expensesList = null; + var expensesListQuery = _context.Expenses .Include(e => e.ExpensesType) .Include(e => e.Project) .Include(e => e.PaidBy) + .ThenInclude(e => e!.JobRole) .Include(e => e.PaymentMode) .Include(e => e.Status) .Include(e => e.CreatedBy) - .Where(e => e.TenantId == tenantId) + .Where(e => e.TenantId == tenantId); + + var HasViewAllPermission = await _permission.HasPermission(PermissionsMaster.ExpenseViewAll, loggedInEmployeeId); + var HasViewSelfPermission = await _permission.HasPermission(PermissionsMaster.ExpenseViewSelf, loggedInEmployeeId); + + if (HasViewAllPermission) + { + expensesList = await expensesListQuery.ToListAsync(); + } + else if (HasViewSelfPermission) + { + expensesList = await expensesListQuery.Where(e => e.CreatedById == loggedInEmployeeId).ToListAsync(); + } + + if (expensesList == null) + { + _logger.LogInfo("No Expense found for employee {EmployeeId}", loggedInEmployeeId); + return Ok(ApiResponse.SuccessResponse(new List(), "No Expense found for current user", 200)); + } + + //ImageFilter? imageFilter = null; + //if (!string.IsNullOrWhiteSpace(filter)) + //{ + // try + // { + // var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; + // //string unescapedJsonString = JsonSerializer.Deserialize(filter, options) ?? ""; + // //imageFilter = JsonSerializer.Deserialize(unescapedJsonString, options); + // imageFilter = JsonSerializer.Deserialize(filter, options); + // } + // catch (Exception ex) + // { + // _logger.LogWarning("[GetImageList] Failed to parse filter: {Message}", ex.Message); + // } + //} + + + var response = _mapper.Map>(expensesList); + + var statusIds = expensesList.Select(e => e.StatusId).ToList(); + + var statusMappings = await _context.ExpensesStatusMapping + .Include(sm => sm.NextStatus) + .Where(sm => statusIds.Contains(sm.StatusId)) .ToListAsync(); - return StatusCode(200, ApiResponse.SuccessResponse(expensesList)); + + foreach (var expense in response) + { + var statusMapping = statusMappings.Where(sm => sm.StatusId == expense.Status?.Id).Select(sm => _mapper.Map(sm.NextStatus)).ToList(); + expense.NextStatus = statusMapping; + + } + return StatusCode(200, ApiResponse.SuccessResponse(response, $"{response.Count} records of expenses for you fetched successfully", 200)); } [HttpGet("details/{id}")] diff --git a/Marco.Pms.Services/MappingProfiles/MappingProfile.cs b/Marco.Pms.Services/MappingProfiles/MappingProfile.cs index 2706083..fad5b78 100644 --- a/Marco.Pms.Services/MappingProfiles/MappingProfile.cs +++ b/Marco.Pms.Services/MappingProfiles/MappingProfile.cs @@ -2,10 +2,14 @@ using AutoMapper; using Marco.Pms.Model.Dtos.Master; using Marco.Pms.Model.Dtos.Project; using Marco.Pms.Model.Employees; +using Marco.Pms.Model.Expenses; using Marco.Pms.Model.Master; using Marco.Pms.Model.MongoDBModels; using Marco.Pms.Model.Projects; +using Marco.Pms.Model.ViewModels.Activities; using Marco.Pms.Model.ViewModels.Employee; +using Marco.Pms.Model.ViewModels.Expanses; +using Marco.Pms.Model.ViewModels.Master; using Marco.Pms.Model.ViewModels.Projects; namespace Marco.Pms.Services.MappingProfiles @@ -63,6 +67,17 @@ namespace Marco.Pms.Services.MappingProfiles #region ======================================================= Employee ======================================================= CreateMap(); + CreateMap() + .ForMember( + dest => dest.JobRoleName, + opt => opt.MapFrom(src => src.JobRole != null ? src.JobRole.Name : "")); + #endregion + + #region ======================================================= Expenses ======================================================= + + CreateMap(); + + #endregion #region ======================================================= Master ======================================================= @@ -72,6 +87,9 @@ namespace Marco.Pms.Services.MappingProfiles // Explicitly and safely convert nullable Guid to non-nullable Guid opt => opt.MapFrom(src => src.Id != null ? src.Id : Guid.Empty) ); + CreateMap(); + CreateMap(); + CreateMap(); #endregion } }