Optimized the get list Notes API

This commit is contained in:
ashutosh.nehete 2025-08-08 11:47:18 +05:30
parent 830accbe98
commit ef41990d7f
3 changed files with 202 additions and 163 deletions

View File

@ -127,17 +127,18 @@ namespace Marco.Pms.Services.Controllers
#region =================================================================== Contact Notes APIs ===================================================================
[HttpGet("notes")]
public async Task<IActionResult> GetListOFAllNotes([FromQuery] Guid? projectId, [FromQuery] int? pageSize, [FromQuery] int pageNumber)
public async Task<IActionResult> GetListOFAllNotes([FromQuery] Guid? projectId, [FromQuery] int pageSize = 20, [FromQuery] int pageNumber = 1)
{
var response = await _directoryService.GetListOFAllNotes(projectId, pageSize ?? 25, pageNumber);
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _directoryService.GetListOFAllNotesAsync(projectId, pageSize, pageNumber, tenantId, loggedInEmployee);
return StatusCode(response.StatusCode, response);
}
[HttpPost("note")]
public async Task<IActionResult> CreateContactNote([FromBody] CreateContactNoteDto noteDto)
{
var response = await _directoryService.CreateContactNote(noteDto);
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _directoryService.CreateContactNote(noteDto, tenantId, loggedInEmployee); ;
if (response.StatusCode == 200)
{
return Ok(response);
@ -155,7 +156,8 @@ namespace Marco.Pms.Services.Controllers
[HttpGet("notes/{ContactId}")]
public async Task<IActionResult> GetNoteListByContactId(Guid contactId, [FromQuery] bool active = true)
{
var response = await _directoryService.GetNoteListByContactId(contactId, active);
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var response = await _directoryService.GetNoteListByContactId(contactId, active, tenantId, loggedInEmployee);
if (response.StatusCode == 200)
{
return Ok(response);

View File

@ -560,7 +560,9 @@ namespace Marco.Pms.Services.Service
.AsNoTracking() // Use AsNoTracking for read-only operations to improve performance.
.Include(c => c.ContactCategory)
.Include(c => c.CreatedBy)
.ThenInclude(e => e!.JobRole)
.Include(c => c.UpdatedBy)
.ThenInclude(e => e!.JobRole)
.FirstOrDefaultAsync(c => c.Id == id && c.IsActive && c.TenantId == tenantId);
if (contact == null)
{
@ -611,6 +613,7 @@ namespace Marco.Pms.Services.Service
.AsNoTracking()
.Include(cb => cb.Bucket)
.ThenInclude(b => b!.CreatedBy)
.ThenInclude(e => e!.JobRole)
.Where(cb => cb.ContactId == contact.Id && cb.Bucket != null && cb.Bucket.TenantId == tenantId);
if (hasAdminPermission)
@ -649,7 +652,9 @@ namespace Marco.Pms.Services.Service
return await taskDbContext.ContactNotes
.AsNoTracking()
.Include(cn => cn.Createdby)
.ThenInclude(e => e!.JobRole)
.Include(cn => cn.UpdatedBy)
.ThenInclude(e => e!.JobRole)
.Include(cn => cn.Contact)
.Where(cn => cn.ContactId == contact.Id && cn.Createdby != null && cn.Createdby.TenantId == tenantId)
.Select(cn => _mapper.Map<ContactNoteVM>(cn))
@ -1240,193 +1245,216 @@ namespace Marco.Pms.Services.Service
#region =================================================================== Contact Notes APIs ===================================================================
/// <summary>
/// Retrieves a paginated list of contact notes based on user permissions.
/// </summary>
/// <param name="pageSize">The number of items per page.</param>
/// <param name="pageNumber">The current page number.</param>
/// <returns>An ApiResponse containing the paginated notes or an error message.</returns>
public async Task<ApiResponse<object>> GetListOFAllNotes(Guid? projectId, int pageSize, int pageNumber)
public async Task<ApiResponse<object>> GetListOFAllNotesAsync(Guid? projectId, int pageSize, int pageNumber, Guid tenantId, Employee loggedInEmployee)
{
_logger.LogInfo("Attempting to fetch list of all notes. PageSize: {PageSize}, PageNumber: {PageNumber}", pageSize, pageNumber);
_logger.LogInfo("Initiating GetListOFAllNotesAsync. TenantId: {TenantId}, ProjectId: {ProjectId}, PageSize: {PageSize}, PageNumber: {PageNumber}, EmployeeId: {EmployeeId}",
tenantId, projectId ?? Guid.Empty, pageSize, pageNumber, loggedInEmployee.Id);
Guid tenantId = _userHelper.GetTenantId();
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
List<Guid>? projectContactIds = null;
if (loggedInEmployee == null)
// Ensure user context is present
if (loggedInEmployee.Id == Guid.Empty || tenantId == Guid.Empty)
{
_logger.LogWarning("GetListOFAllNotes: LoggedInEmployee is null. Cannot proceed.");
_logger.LogWarning("Unauthorized: LoggedInEmployee is null.");
return ApiResponse<object>.ErrorResponse("Unauthorized", "Employee not found.", 403);
}
// --- Permission Checks ---
var hasAdminPermission = await _permissionServices.HasPermission(PermissionsMaster.DirectoryAdmin, loggedInEmployee.Id);
var hasManagerPermission = await _permissionServices.HasPermission(PermissionsMaster.DirectoryAdmin, loggedInEmployee.Id);
var hasUserPermission = await _permissionServices.HasPermission(PermissionsMaster.DirectoryUser, loggedInEmployee.Id);
IQueryable<ContactNote> 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
if (!hasAdminPermission && !(hasManagerPermission || hasUserPermission))
try
{
_logger.LogWarning("GetListOFAllNotes: User {EmployeeId} does not have required permissions to access notes for TenantId: {TenantId}", loggedInEmployee.Id, tenantId);
// Use a context instance per method call for safety in parallel scenarios
await using var context = _dbContextFactory.CreateDbContext();
// Permission checks (parallel as they're independent)
var (hasAdminPermission, hasManagerPermission, hasUserPermission) = await CheckPermissionsAsync(loggedInEmployee.Id);
// Access control
if (!hasAdminPermission && !hasManagerPermission && !hasUserPermission)
{
_logger.LogWarning("Access Denied. EmployeeId: {EmployeeId}, TenantId: {TenantId}", loggedInEmployee.Id, tenantId);
return ApiResponse<object>.ErrorResponse("Access Denied", "You don't have access to view notes.", 403);
}
// Build base query
IQueryable<ContactNote> notesQuery = context.ContactNotes
.Include(cn => cn.UpdatedBy)
.ThenInclude(e => e!.JobRole)
.Include(cn => cn.Createdby)
.ThenInclude(e => e!.JobRole)
.Include(cn => cn.Contact)
.Where(cn => cn.TenantId == tenantId);
// Fetch associated contact IDs for project (if filtering by project)
List<Guid>? projectContactIds = null;
if (projectId.HasValue)
{
projectContactIds = await context.ContactProjectMappings
.Where(pc => pc.ProjectId == projectId.Value)
.Select(pc => pc.ContactId)
.ToListAsync();
}
if (!hasAdminPermission) // Manager/User filtering
{
_logger.LogInfo("Non-admin user. Applying bucket-based filtering. EmployeeId: {EmployeeId}", loggedInEmployee.Id);
// Get assigned bucket IDs
var assignedBucketIds = await context.EmployeeBucketMappings
.Where(eb => eb.EmployeeId == loggedInEmployee.Id)
.Select(eb => eb.BucketId)
.ToListAsync();
if (!assignedBucketIds.Any())
{
_logger.LogInfo("No assigned buckets for user: {EmployeeId}", loggedInEmployee.Id);
return ApiResponse<object>.SuccessResponse(new
{
CurrentPage = pageNumber,
TotalPages = 0,
Data = new List<ContactNoteVM>()
}, "No notes found based on assigned buckets.", 200);
}
// Contacts based on assigned buckets, further filtered by project (if provided)
var contactBucketQuery = context.ContactBucketMappings
.Where(cb => assignedBucketIds.Contains(cb.BucketId));
if (projectContactIds != null)
{
contactBucketQuery = contactBucketQuery.Where(cb => projectContactIds.Contains(cb.ContactId));
}
var contactIds = await contactBucketQuery.Select(cb => cb.ContactId).Distinct().ToListAsync();
if (!contactIds.Any())
{
_logger.LogInfo("No contacts found for assigned buckets for user: {EmployeeId}", loggedInEmployee.Id);
return ApiResponse<object>.SuccessResponse(new
{
CurrentPage = pageNumber,
TotalPages = 0,
Data = new List<ContactNoteVM>()
}, "No notes found for associated contacts.", 200);
}
notesQuery = notesQuery.Where(cn => contactIds.Contains(cn.ContactId));
}
else
{
// Admin: If project specified, filter notes further
if (projectContactIds != null)
notesQuery = notesQuery.Where(cn => projectContactIds.Contains(cn.ContactId));
}
// Pagination safeguard
pageSize = pageSize < 1 ? 25 : pageSize;
pageNumber = pageNumber < 1 ? 1 : pageNumber;
// Accurate pagination metadata
int totalRecords = await notesQuery.CountAsync();
int totalPages = (int)Math.Ceiling(totalRecords / (double)pageSize);
// Fetch paginated, ordered results
List<ContactNote> notes = await notesQuery
.OrderByDescending(cn => cn.UpdatedAt ?? cn.CreatedAt)
.Skip((pageNumber - 1) * pageSize)
.Take(pageSize)
.ToListAsync();
_logger.LogInfo("Notes fetched: {Count}, Page: {PageNumber}/{TotalPages}, EmployeeId: {EmployeeId}, TenantId: {TenantId}",
notes.Count, pageNumber, totalPages, loggedInEmployee.Id, tenantId);
// In-memory mapping to ViewModel
var noteVms = _mapper.Map<List<ContactNoteVM>>(notes);
var response = new
{
CurrentPage = pageNumber,
PageSize = pageSize,
TotalPages = totalPages,
TotalRecords = totalRecords,
Data = noteVms
};
_logger.LogInfo("Notes mapped to ViewModel for TenantId: {TenantId}, EmployeeId: {EmployeeId}", tenantId, loggedInEmployee.Id);
return ApiResponse<object>.SuccessResponse(response, $"{noteVms.Count} notes fetched successfully.", 200);
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception occurred in GetListOFAllNotesAsync. TenantId: {TenantId}, EmployeeId: {EmployeeId}", tenantId, loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Internal Server Error", "An error occurred while fetching notes. Please try again later.", 500);
}
}
public async Task<ApiResponse<object>> GetNoteListByContactId(Guid id, bool active, Guid tenantId, Employee loggedInEmployee)
{
var (hasAdminPermission, hasManagerPermission, hasUserPermission) = await CheckPermissionsAsync(loggedInEmployee.Id);
if (!hasAdminPermission && !hasManagerPermission && !hasUserPermission)
{
_logger.LogWarning("Access Denied. EmployeeId: {EmployeeId}, TenantId: {TenantId} Do not have permission", loggedInEmployee.Id, tenantId);
return ApiResponse<object>.ErrorResponse("Access Denied", "You don't have access to view notes.", 403);
}
if (projectId != null)
Contact? contact = await _context.Contacts.FirstOrDefaultAsync(c => c.Id == id && c.IsActive && c.TenantId == tenantId);
if (contact == null)
{
projectContactIds = await _context.ContactProjectMappings
.Where(pc => pc.ProjectId == projectId)
.Select(pc => pc.ContactId)
.ToListAsync();
_logger.LogWarning("Employee with ID {LoggedInEmployeeId} attempted to fetch a list notes from contact with ID {ContactId}, but the contact was not found in the database.", loggedInEmployee.Id, id);
return ApiResponse<object>.ErrorResponse("Contact not found", "Contact not found", 404);
}
if (!hasAdminPermission) // If not an admin, apply additional filtering
if (!hasAdminPermission && (hasManagerPermission || hasUserPermission))
{
_logger.LogInfo("GetListOFAllNotes: User {EmployeeId} is not an admin. Applying manager/user specific filters.", loggedInEmployee.Id);
var assignedBucketIds = await _context.EmployeeBucketMappings
.Where(eb => eb.EmployeeId == loggedInEmployee.Id)
.Select(eb => eb.BucketId)
.ToListAsync();
if (!assignedBucketIds.Any())
var bucketIds = await _context.EmployeeBucketMappings.Where(em => em.EmployeeId == loggedInEmployee.Id).Select(em => em.BucketId).ToListAsync();
var hasContactAccess = await _context.ContactBucketMappings.AnyAsync(cb => bucketIds.Contains(cb.BucketId) && cb.ContactId == contact.Id);
if (!hasContactAccess)
{
_logger.LogInfo("GetListOFAllNotes: User {EmployeeId} has no assigned buckets. Returning empty list.", loggedInEmployee.Id);
return ApiResponse<object>.SuccessResponse(new { CurrentPage = pageNumber, TotalPages = 0, Data = new List<ContactNoteVM>() }, "No notes found based on assigned buckets.", 200);
}
List<Guid>? 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<object>.SuccessResponse(new { CurrentPage = pageNumber, TotalPages = 0, Data = new List<ContactNoteVM>() }, "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));
_logger.LogWarning("Access Denied. EmployeeId: {EmployeeId}, TenantId: {TenantId} Do not have access of bucket", loggedInEmployee.Id, tenantId);
return ApiResponse<object>.ErrorResponse("Access Denied", "You don't have access to view notes.", 403);
}
}
// --- Pagination Logic ---
// Ensure pageSize and pageNumber are valid
pageSize = pageSize < 1 ? 25 : pageSize; // Default to 25 if less than 1
pageNumber = pageNumber < 1 ? 1 : pageNumber; // Default to 1 if less than 1
var notesQuery = _context.ContactNotes
.Include(n => n.Createdby)
.ThenInclude(e => e!.JobRole)
.Include(n => n.UpdatedBy)
.ThenInclude(e => e!.JobRole)
.Where(n => n.ContactId == contact.Id && n.TenantId == tenantId);
// Get total count BEFORE applying Skip/Take for accurate pagination metadata
int totalRecords = await notesQuery.CountAsync();
int totalPages = (int)Math.Ceiling((double)totalRecords / pageSize);
if (active)
{
notesQuery = notesQuery.Where(n => n.IsActive);
}
int skip = (pageNumber - 1) * pageSize;
List<ContactNote> notes = await notesQuery.ToListAsync();
// --- Apply Ordering and Pagination in the database ---
List<ContactNote> notes = await notesQuery
.OrderByDescending(cn => (cn.UpdatedAt != null ? cn.UpdatedAt : cn.CreatedAt)) // Order by updated date or created date
.Skip((pageNumber - 1) * pageSize)
.Take(pageSize)
var noteIds = notes.Select(n => n.Id).ToList();
List<DirectoryUpdateLog>? updateLogs = await _context.DirectoryUpdateLogs
.Include(l => l.Employee)
.ThenInclude(e => e!.JobRole)
.Where(l => noteIds.Contains(l.RefereanceId))
.ToListAsync();
_logger.LogInfo("GetListOFAllNotes: Fetched {Count} notes for page {PageNumber} of {TotalPages} total pages. Total records: {TotalRecords}.",
notes.Count, pageNumber, totalPages, totalRecords);
List<ContactNoteVM> noteVMs = _mapper.Map<List<ContactNoteVM>>(notes);
// --- 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<ContactNoteVM> noteVMS = notes
.Select(cn => cn.ToContactNoteVMFromContactNote())
.ToList();
var response = new
{
CurrentPage = pageNumber,
PageSize = pageSize, // Include pageSize in response for client clarity
TotalPages = totalPages,
TotalRecords = totalRecords, // Add total records for client
Data = noteVMS
};
_logger.LogInfo("GetListOFAllNotes: Successfully retrieved notes and mapped to ViewModel for TenantId: {TenantId}.", tenantId);
return ApiResponse<object>.SuccessResponse(response, $"{noteVMS.Count} notes fetched successfully.", 200);
_logger.LogInfo("{count} contact-notes record from contact {ContactId} fetched by Employee {EmployeeId}", noteVMs.Count, id, loggedInEmployee.Id);
return ApiResponse<object>.SuccessResponse(noteVMs, $"{noteVMs.Count} contact-notes record fetched successfully", 200);
}
public async Task<ApiResponse<object>> GetNoteListByContactId(Guid id, bool active)
{
Guid tenantId = _userHelper.GetTenantId();
var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
Contact? contact = await _context.Contacts.FirstOrDefaultAsync(c => c.Id == id && c.IsActive && c.TenantId == tenantId);
if (contact != null)
{
List<ContactNote> notes = new List<ContactNote>();
if (active)
{
notes = await _context.ContactNotes
.Include(n => n.Createdby)
.Include(n => n.UpdatedBy)
.Where(n => n.ContactId == contact.Id && n.IsActive && n.TenantId == tenantId)
.ToListAsync();
}
else
{
notes = await _context.ContactNotes
.Include(n => n.Createdby)
.Include(n => n.UpdatedBy)
.Where(n => n.ContactId == contact.Id && n.TenantId == tenantId)
.ToListAsync();
}
var noteIds = notes.Select(n => n.Id).ToList();
List<DirectoryUpdateLog>? updateLogs = await _context.DirectoryUpdateLogs.Include(l => l.Employee).Where(l => noteIds.Contains(l.RefereanceId)).ToListAsync();
//List<ContactNoteVM>? noteVMs = new List<ContactNoteVM>();
List<ContactNoteVM>? noteVMs = notes.Select(n => n.ToContactNoteVMFromContactNote()).ToList();
_logger.LogInfo("{count} contact-notes record from contact {ContactId} fetched by Employee {EmployeeId}", noteVMs.Count, id, LoggedInEmployee.Id);
return ApiResponse<object>.SuccessResponse(noteVMs, $"{noteVMs.Count} contact-notes record fetched successfully", 200);
}
_logger.LogWarning("Employee with ID {LoggedInEmployeeId} attempted to fetch a list notes from contact with ID {ContactId}, but the contact was not found in the database.", LoggedInEmployee.Id, id);
return ApiResponse<object>.ErrorResponse("Contact not found", "Contact not found", 404);
}
public async Task<ApiResponse<object>> CreateContactNote(CreateContactNoteDto noteDto)
public async Task<ApiResponse<object>> CreateContactNote(CreateContactNoteDto noteDto, Guid tenantId, Employee loggedInEmployee)
{
Guid tenantId = _userHelper.GetTenantId();
var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
if (noteDto != null)
{
Contact? contact = await _context.Contacts.FirstOrDefaultAsync(c => c.Id == noteDto.ContactId && c.IsActive && c.TenantId == tenantId);
if (contact != null)
{
ContactNote note = noteDto.ToContactNoteFromCreateContactNoteDto(tenantId, LoggedInEmployee.Id);
ContactNote note = noteDto.ToContactNoteFromCreateContactNoteDto(tenantId, loggedInEmployee.Id);
_context.ContactNotes.Add(note);
await _context.SaveChangesAsync();
ContactNoteVM noteVM = note.ToContactNoteVMFromContactNote();
_logger.LogInfo("Employee {EmployeeId} Added note at contact {ContactId}", LoggedInEmployee.Id, contact.Id);
_logger.LogInfo("Employee {EmployeeId} Added note at contact {ContactId}", loggedInEmployee.Id, contact.Id);
return ApiResponse<object>.SuccessResponse(noteVM, "Note added successfully", 200);
}
_logger.LogWarning("Employee with ID {LoggedInEmployeeId} attempted to add a note to contact with ID {ContactId}, but the contact was not found in the database.", LoggedInEmployee.Id, noteDto.ContactId);
_logger.LogWarning("Employee with ID {LoggedInEmployeeId} attempted to add a note to contact with ID {ContactId}, but the contact was not found in the database.", loggedInEmployee.Id, noteDto.ContactId);
return ApiResponse<object>.ErrorResponse("Contact not found", "Contact not found", 404);
}
_logger.LogWarning("Employee with ID {LoggedInEmployeeId} sended empty payload", LoggedInEmployee.Id);
_logger.LogWarning("Employee with ID {LoggedInEmployeeId} sended empty payload", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("User Send empty Payload", "User Send empty Payload", 400);
}
public async Task<ApiResponse<object>> UpdateContactNote(Guid id, UpdateContactNoteDto noteDto)
@ -1438,7 +1466,11 @@ namespace Marco.Pms.Services.Service
Contact? contact = await _context.Contacts.FirstOrDefaultAsync(c => c.Id == noteDto.ContactId && c.TenantId == tenantId);
if (contact != null)
{
ContactNote? contactNote = await _context.ContactNotes.Include(cn => cn.Createdby).Include(cn => cn.Contact).FirstOrDefaultAsync(n => n.Id == noteDto.Id && n.ContactId == contact.Id && n.IsActive);
ContactNote? contactNote = await _context.ContactNotes
.Include(cn => cn.Createdby)
.ThenInclude(e => e!.JobRole)
.Include(cn => cn.Contact)
.FirstOrDefaultAsync(n => n.Id == noteDto.Id && n.ContactId == contact.Id && n.IsActive);
if (contactNote != null)
{
contactNote.Note = noteDto.Note;
@ -1519,6 +1551,7 @@ namespace Marco.Pms.Services.Service
// Admin gets all buckets for the tenant
bucketList = await _context.Buckets
.Include(b => b.CreatedBy)
.ThenInclude(e => e!.JobRole)
.Where(b => b.TenantId == tenantId)
.ToListAsync();
@ -1536,6 +1569,7 @@ namespace Marco.Pms.Services.Service
bucketList = await _context.Buckets
.Include(b => b.CreatedBy)
.ThenInclude(e => e!.JobRole)
.Where(b => bucketIds.Contains(b.Id) || b.CreatedByID == loggedInEmployee.Id)
.ToListAsync();
@ -1779,7 +1813,6 @@ namespace Marco.Pms.Services.Service
return ApiResponse<object>.ErrorResponse("An unexpected error occurred. Please try again later.", "Internal server error", 500);
}
}
public async Task<ApiResponse<object>> AssignBucketAsync(Guid bucketId, List<AssignBucketDto> assignBuckets, Guid tenantId, Employee loggedInEmployee)
{
// Validate input payload
@ -1794,8 +1827,10 @@ namespace Marco.Pms.Services.Service
// Load the bucket with related CreatedBy and validate tenant
var bucket = await _context.Buckets.Include(b => b.CreatedBy)
.FirstOrDefaultAsync(b => b.Id == bucketId && b.TenantId == tenantId);
var bucket = await _context.Buckets
.Include(b => b.CreatedBy)
.ThenInclude(e => e!.JobRole)
.FirstOrDefaultAsync(b => b.Id == bucketId && b.TenantId == tenantId);
if (bucket == null)
{
@ -1931,7 +1966,6 @@ namespace Marco.Pms.Services.Service
return ApiResponse<object>.SuccessResponse(bucketVm, "Bucket details updated successfully", 200);
}
public async Task<ApiResponse<object>> DeleteBucketAsync(Guid id, Guid tenantId, Employee loggedInEmployee)
{
try

View File

@ -16,9 +16,12 @@ namespace Marco.Pms.Services.Service.ServiceInterfaces
Task<ApiResponse<object>> DeleteContactAsync(Guid id, bool active, Guid tenantId, Employee loggedInEmployee);
Task<ApiResponse<object>> GetListOFAllNotes(Guid? projectId, int pageSize, int pageNumber);
Task<ApiResponse<object>> GetNoteListByContactId(Guid id, bool active);
Task<ApiResponse<object>> CreateContactNote(CreateContactNoteDto noteDto);
Task<ApiResponse<object>> GetListOFAllNotesAsync(Guid? projectId, int pageSize, int pageNumber, Guid tenantId, Employee loggedInEmployee);
Task<ApiResponse<object>> GetNoteListByContactId(Guid id, bool active, Guid tenantId, Employee loggedInEmployee);
Task<ApiResponse<object>> CreateContactNote(CreateContactNoteDto noteDto, Guid tenantId, Employee loggedInEmployee);
Task<ApiResponse<object>> UpdateContactNote(Guid id, UpdateContactNoteDto noteDto);
Task<ApiResponse<object>> DeleteContactNote(Guid id, bool active);