From 9149c4e546b11c2cfb5e0362c147468556c32a4d Mon Sep 17 00:00:00 2001 From: "ashutosh.nehete" Date: Fri, 27 Jun 2025 10:58:29 +0530 Subject: [PATCH] Filtered conatct notes by projects and added contact name and organization name in list VM --- Marco.Pms.Model/Mapper/DirectoryMapper.cs | 18 ++++++- .../ViewModels/Directory/ContactNoteListVM.cs | 18 +++++++ .../Controllers/DirectoryController.cs | 6 +-- Marco.Pms.Services/Helpers/DirectoryHelper.cs | 49 +++++++++++++++---- .../Service/StartupDataSeeder.cs | 10 ++-- 5 files changed, 83 insertions(+), 18 deletions(-) create mode 100644 Marco.Pms.Model/ViewModels/Directory/ContactNoteListVM.cs diff --git a/Marco.Pms.Model/Mapper/DirectoryMapper.cs b/Marco.Pms.Model/Mapper/DirectoryMapper.cs index faf0539..9f7d2dc 100644 --- a/Marco.Pms.Model/Mapper/DirectoryMapper.cs +++ b/Marco.Pms.Model/Mapper/DirectoryMapper.cs @@ -240,5 +240,21 @@ namespace Marco.Pms.Model.Mapper IsActive = note.IsActive }; } + public static ContactNoteListVM ToContactNoteListVMFromContactNote(this ContactNote note) + { + return new ContactNoteListVM + { + Id = note.Id, + Note = note.Note, + ContactName = note.Contact?.Name, + OrganizationName = note.Contact?.Organization, + ContactId = note.ContactId, + CreatedAt = note.CreatedAt, + UpdatedAt = note.UpdatedAt, + CreatedBy = note.Createdby != null ? note.Createdby.ToBasicEmployeeVMFromEmployee() : null, + UpdatedBy = note.UpdatedBy != null ? note.UpdatedBy.ToBasicEmployeeVMFromEmployee() : null, + IsActive = note.IsActive + }; + } } -} +} \ No newline at end of file diff --git a/Marco.Pms.Model/ViewModels/Directory/ContactNoteListVM.cs b/Marco.Pms.Model/ViewModels/Directory/ContactNoteListVM.cs new file mode 100644 index 0000000..68451ed --- /dev/null +++ b/Marco.Pms.Model/ViewModels/Directory/ContactNoteListVM.cs @@ -0,0 +1,18 @@ +using Marco.Pms.Model.ViewModels.Activities; + +namespace Marco.Pms.Model.ViewModels.Directory +{ + public class ContactNoteListVM + { + public Guid Id { get; set; } + public string? Note { get; set; } + public string? ContactName { get; set; } + public string? OrganizationName { get; set; } + public DateTime CreatedAt { get; set; } + public BasicEmployeeVM? CreatedBy { get; set; } + public DateTime? UpdatedAt { get; set; } + public BasicEmployeeVM? UpdatedBy { get; set; } + public Guid ContactId { get; set; } + public bool IsActive { get; set; } + } +} diff --git a/Marco.Pms.Services/Controllers/DirectoryController.cs b/Marco.Pms.Services/Controllers/DirectoryController.cs index 0555868..4a0e41e 100644 --- a/Marco.Pms.Services/Controllers/DirectoryController.cs +++ b/Marco.Pms.Services/Controllers/DirectoryController.cs @@ -159,9 +159,9 @@ namespace Marco.Pms.Services.Controllers // -------------------------------- Contact Notes -------------------------------- [HttpGet("notes")] - public async Task GetListOFAllNotes([FromQuery] int? pageSize, [FromQuery] int pageNumber) + public async Task GetListOFAllNotes([FromQuery] Guid? projectId, [FromQuery] int? pageSize, [FromQuery] int pageNumber) { - var response = await _directoryHelper.GetListOFAllNotes(pageSize ?? 25, pageNumber); + var response = await _directoryHelper.GetListOFAllNotes(projectId, pageSize ?? 25, pageNumber); return StatusCode(response.StatusCode, response); } @@ -345,4 +345,4 @@ namespace Marco.Pms.Services.Controllers } } } -} +} \ No newline at end of file diff --git a/Marco.Pms.Services/Helpers/DirectoryHelper.cs b/Marco.Pms.Services/Helpers/DirectoryHelper.cs index 2d06785..301c708 100644 --- a/Marco.Pms.Services/Helpers/DirectoryHelper.cs +++ b/Marco.Pms.Services/Helpers/DirectoryHelper.cs @@ -904,12 +904,13 @@ namespace Marco.Pms.Services.Helpers /// The number of items per page. /// The current page number. /// An ApiResponse containing the paginated notes or an error message. - public async Task> GetListOFAllNotes(int pageSize, int pageNumber) + public async Task> GetListOFAllNotes(Guid? projectId, int pageSize, int pageNumber) { _logger.LogInfo("Attempting to fetch list of all notes. PageSize: {PageSize}, PageNumber: {PageNumber}", pageSize, pageNumber); Guid tenantId = _userHelper.GetTenantId(); var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); + List? projectContactIds = null; if (loggedInEmployee == null) { @@ -925,6 +926,7 @@ namespace Marco.Pms.Services.Helpers IQueryable notesQuery = _context.ContactNotes .Include(cn => cn.UpdatedBy) .Include(cn => cn.Createdby) // Assuming 'CreatedBy' (PascalCase) + .Include(cn => cn.Contact) .Where(cn => cn.TenantId == tenantId) .AsQueryable(); // Start building the query @@ -933,7 +935,13 @@ namespace Marco.Pms.Services.Helpers _logger.LogWarning("GetListOFAllNotes: User {EmployeeId} does not have required permissions to access notes for TenantId: {TenantId}", loggedInEmployee.Id, tenantId); return ApiResponse.ErrorResponse("Access Denied", "You don't have access to view notes.", 403); } - + if (projectId != null) + { + projectContactIds = await _context.ContactProjectMappings + .Where(pc => pc.ProjectId == projectId) + .Select(pc => pc.ContactId) + .ToListAsync(); + } if (!hasAdminPermission) // If not an admin, apply additional filtering { _logger.LogInfo("GetListOFAllNotes: User {EmployeeId} is not an admin. Applying manager/user specific filters.", loggedInEmployee.Id); @@ -945,22 +953,41 @@ namespace Marco.Pms.Services.Helpers if (!assignedBucketIds.Any()) { _logger.LogInfo("GetListOFAllNotes: User {EmployeeId} has no assigned buckets. Returning empty list.", loggedInEmployee.Id); - return ApiResponse.SuccessResponse(new { CurrentPage = pageNumber, TotalPages = 0, Data = new List() }, "No notes found based on assigned buckets.", 200); + return ApiResponse.SuccessResponse(new { CurrentPage = pageNumber, TotalPages = 0, Data = new List() }, "No notes found based on assigned buckets.", 200); } - var contactIds = await _context.ContactBucketMappings + List? contactIds = null; + + if (projectContactIds == null) + { + contactIds = await _context.ContactBucketMappings .Where(cb => assignedBucketIds.Contains(cb.BucketId)) .Select(cb => cb.ContactId) .ToListAsync(); + } + else + { + contactIds = await _context.ContactBucketMappings + .Where(cb => assignedBucketIds.Contains(cb.BucketId) && projectContactIds.Contains(cb.ContactId)) + .Select(cb => cb.ContactId) + .ToListAsync(); + } if (!contactIds.Any()) { _logger.LogInfo("GetListOFAllNotes: No contacts found for assigned buckets for user {EmployeeId}. Returning empty list.", loggedInEmployee.Id); - return ApiResponse.SuccessResponse(new { CurrentPage = pageNumber, TotalPages = 0, Data = new List() }, "No notes found for associated contacts.", 200); + return ApiResponse.SuccessResponse(new { CurrentPage = pageNumber, TotalPages = 0, Data = new List() }, "No notes found for associated contacts.", 200); } notesQuery = notesQuery.Where(cn => contactIds.Contains(cn.ContactId)); } + else + { + if (projectContactIds != null) + { + notesQuery = notesQuery.Where(cn => projectContactIds.Contains(cn.ContactId)); + } + } // --- Pagination Logic --- // Ensure pageSize and pageNumber are valid @@ -986,8 +1013,9 @@ namespace Marco.Pms.Services.Helpers // --- Map to ViewModel (in-memory) --- // This mapping is done in memory because ToBasicEmployeeVMFromEmployee() is likely a C# method // that cannot be translated to SQL by Entity Framework. - List noteVMS = notes - .Select(cn => cn.ToContactNoteVMFromContactNote()) + + List noteVMS = notes + .Select(cn => cn.ToContactNoteListVMFromContactNote()) .ToList(); var response = new @@ -1068,7 +1096,7 @@ namespace Marco.Pms.Services.Helpers Contact? contact = await _context.Contacts.FirstOrDefaultAsync(c => c.Id == noteDto.ContactId && c.IsActive && c.TenantId == tenantId); if (contact != null) { - ContactNote? contactNote = await _context.ContactNotes.FirstOrDefaultAsync(n => n.Id == noteDto.Id && n.ContactId == contact.Id && n.IsActive); + ContactNote? contactNote = await _context.ContactNotes.Include(cn => cn.Createdby).FirstOrDefaultAsync(n => n.Id == noteDto.Id && n.ContactId == contact.Id && n.IsActive); if (contactNote != null) { contactNote.Note = noteDto.Note; @@ -1108,6 +1136,9 @@ namespace Marco.Pms.Services.Helpers if (note != null) { note.IsActive = active; + note.UpdatedById = LoggedInEmployee.Id; + note.UpdatedAt = DateTime.UtcNow; + _context.DirectoryUpdateLogs.Add(new DirectoryUpdateLog { RefereanceId = id, @@ -1452,4 +1483,4 @@ namespace Marco.Pms.Services.Helpers return result; } } -} +} \ No newline at end of file diff --git a/Marco.Pms.Services/Service/StartupDataSeeder.cs b/Marco.Pms.Services/Service/StartupDataSeeder.cs index a3e04f9..10d6f71 100644 --- a/Marco.Pms.Services/Service/StartupDataSeeder.cs +++ b/Marco.Pms.Services/Service/StartupDataSeeder.cs @@ -98,23 +98,23 @@ namespace Marco.Pms.Services.Service IsSystem = true, JoiningDate = Convert.ToDateTime("2000-04-20 10:11:17.588000"), }; - if ((!await dbContext.Employees.Where(e => e.FirstName == "Admin").AnyAsync()) && (jobRole != null ? jobRole.Id : Guid.Empty) != Guid.Empty) + if ((!await dbContext.Employees.Where(e => e.Email == "admin@marcoaiot.com").AnyAsync()) && jobRole?.Id != Guid.Empty) { await dbContext.Employees.AddAsync(employee); } else { - employee = await dbContext.Employees.Where(e => e.FirstName == "Admin").FirstOrDefaultAsync(); + employee = await dbContext.Employees.Where(e => e.Email == "admin@marcoaiot.com").FirstOrDefaultAsync(); } await dbContext.SaveChangesAsync(); if (!await dbContext.EmployeeRoleMappings.AnyAsync()) { await dbContext.EmployeeRoleMappings.AddAsync(new EmployeeRoleMapping { - EmployeeId = employee != null ? employee.Id : Guid.Empty, + EmployeeId = employee?.Id ?? Guid.Empty, IsEnabled = true, TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26"), - RoleId = role != null ? role.Id : Guid.Empty + RoleId = role?.Id ?? Guid.Empty }); } if (!await dbContext.RolePermissionMappings.AnyAsync()) @@ -136,4 +136,4 @@ namespace Marco.Pms.Services.Service public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask; } -} +} \ No newline at end of file