diff --git a/Marco.Pms.Services/Controllers/DirectoryController.cs b/Marco.Pms.Services/Controllers/DirectoryController.cs index 5731065..431122e 100644 --- a/Marco.Pms.Services/Controllers/DirectoryController.cs +++ b/Marco.Pms.Services/Controllers/DirectoryController.cs @@ -80,6 +80,7 @@ namespace Marco.Pms.Services.Controllers var response = await _directoryService.GetOrganizationListAsync(tenantId, loggedInEmployee); return Ok(response); } + [HttpGet("designations")] public async Task GetDesignationList() { @@ -88,6 +89,14 @@ namespace Marco.Pms.Services.Controllers return Ok(response); } + [HttpGet("contact/filter")] + public async Task GetContactFilterObject() + { + var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); + var response = await _directoryService.GetContactFilterObjectAsync(tenantId, loggedInEmployee); + return StatusCode(response.StatusCode, response); + } + #endregion [HttpPost] @@ -161,6 +170,14 @@ namespace Marco.Pms.Services.Controllers return StatusCode(response.StatusCode, response); } + [HttpGet("notes/filter")] + public async Task GetContactNotesFilterObject() + { + var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); + var response = await _directoryService.GetContactNotesFilterObjectAsync(tenantId, loggedInEmployee); + return StatusCode(response.StatusCode, response); + } + [HttpPut("note/{id}")] public async Task UpdateContactNote(Guid id, [FromBody] UpdateContactNoteDto noteDto) { diff --git a/Marco.Pms.Services/Helpers/DirectoryHelper.cs b/Marco.Pms.Services/Helpers/DirectoryHelper.cs deleted file mode 100644 index 9722974..0000000 --- a/Marco.Pms.Services/Helpers/DirectoryHelper.cs +++ /dev/null @@ -1,1556 +0,0 @@ -using Marco.Pms.DataAccess.Data; -using Marco.Pms.Model.Directory; -using Marco.Pms.Model.Dtos.Directory; -using Marco.Pms.Model.Entitlements; -using Marco.Pms.Model.Mapper; -using Marco.Pms.Model.Projects; -using Marco.Pms.Model.Utilities; -using Marco.Pms.Model.ViewModels.Directory; -using Marco.Pms.Model.ViewModels.Master; -using Marco.Pms.Model.ViewModels.Projects; -using Marco.Pms.Services.Service; -using MarcoBMS.Services.Helpers; -using MarcoBMS.Services.Service; -using Microsoft.EntityFrameworkCore; - -namespace Marco.Pms.Services.Helpers -{ - public class DirectoryHelper - { - private readonly ApplicationDbContext _context; - private readonly ILoggingService _logger; - private readonly UserHelper _userHelper; - private readonly PermissionServices _permissionServices; - - public DirectoryHelper(ApplicationDbContext context, ILoggingService logger, UserHelper userHelper, PermissionServices permissionServices) - { - _context = context; - _logger = logger; - _userHelper = userHelper; - _permissionServices = permissionServices; - } - - public async Task> GetListOfContacts(string? search, bool active, ContactFilterDto? filterDto, Guid? projectId) - { - Guid tenantId = _userHelper.GetTenantId(); - var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); - var assignedRoleIds = await _context.EmployeeRoleMappings.Where(r => r.EmployeeId == LoggedInEmployee.Id).Select(r => r.RoleId).ToListAsync(); - var permissionIds = await _context.RolePermissionMappings.Where(rp => assignedRoleIds.Contains(rp.ApplicationRoleId)).Select(rp => rp.FeaturePermissionId).Distinct().ToListAsync(); - List? employeeBuckets = await _context.EmployeeBucketMappings.Where(eb => eb.EmployeeId == LoggedInEmployee.Id).ToListAsync(); - List bucketIds = employeeBuckets.Select(c => c.BucketId).ToList(); - if (permissionIds.Contains(PermissionsMaster.DirectoryAdmin)) - { - var buckets = await _context.Buckets.Where(b => b.TenantId == tenantId).ToListAsync(); - bucketIds = buckets.Select(b => b.Id).ToList(); - } - else if (permissionIds.Contains(PermissionsMaster.DirectoryAdmin) || permissionIds.Contains(PermissionsMaster.DirectoryUser)) - { - var buckets = await _context.Buckets.Where(b => b.CreatedByID == LoggedInEmployee.Id).ToListAsync(); - var createdBucketIds = buckets.Select(b => b.Id).ToList(); - bucketIds.AddRange(createdBucketIds); - bucketIds = bucketIds.Distinct().ToList(); - } - else - { - _logger.LogWarning("Employee {EmployeeId} attemped to access a contacts, but do not have permission", LoggedInEmployee.Id); - return ApiResponse.ErrorResponse("You don't have permission", "You don't have permission", 401); - } - - List filterbucketIds = bucketIds; - if (filterDto != null && filterDto.BucketIds != null && filterDto.BucketIds.Count > 0) - { - filterbucketIds = filterDto.BucketIds; - } - List? contactBuckets = await _context.ContactBucketMappings.Where(cb => bucketIds.Contains(cb.BucketId)).ToListAsync(); - List contactIds = contactBuckets.Where(b => filterbucketIds.Contains(b.BucketId)).Select(cb => cb.ContactId).ToList(); - List contacts = new List(); - - var contactProjects = await _context.ContactProjectMappings.Where(p => contactIds.Contains(p.ContactId)).ToListAsync(); - - if (projectId != null && projectId != Guid.Empty) - { - contactProjects = contactProjects.Where(p => p.ProjectId == projectId).ToList(); - contactIds = contactProjects.Select(p => p.ContactId).Distinct().ToList(); - } - - if (filterDto != null && filterDto.CategoryIds != null && filterDto.CategoryIds.Count > 0) - { - var categoryIds = filterDto.CategoryIds; - contacts = await _context.Contacts.Include(c => c.ContactCategory).Where(c => contactIds.Contains(c.Id) && categoryIds.Contains(c.ContactCategoryId ?? Guid.Empty) && c.TenantId == tenantId && c.IsActive == active).ToListAsync(); - } - else - { - contacts = await _context.Contacts.Include(c => c.ContactCategory).Where(c => contactIds.Contains(c.Id) && c.TenantId == tenantId && c.IsActive == active).ToListAsync(); - } - - var phoneNo = await _context.ContactsPhones.Where(p => contactIds.Contains(p.ContactId)).ToListAsync(); - var Emails = await _context.ContactsEmails.Where(E => contactIds.Contains(E.ContactId)).ToListAsync(); - var Tags = await _context.ContactTagMappings.Where(t => contactIds.Contains(t.ContactId)).ToListAsync(); - - List TagIds = Tags.Select(t => t.ContactTagId).ToList(); - - var TagList = await _context.ContactTagMasters.Where(t => TagIds.Contains(t.Id)).ToListAsync(); - - if (search != null && search != string.Empty) - { - List filteredContactIds = new List(); - phoneNo = phoneNo.Where(p => Compare(p.PhoneNumber, search)).ToList(); - filteredContactIds = phoneNo.Select(p => p.ContactId).ToList(); - - Emails = Emails.Where(e => Compare(e.EmailAddress, search)).ToList(); - filteredContactIds.AddRange(Emails.Select(e => e.ContactId).ToList()); - filteredContactIds = filteredContactIds.Distinct().ToList(); - - contacts = contacts.Where(c => Compare(c.Name, search) || Compare(c.Organization, search) || filteredContactIds.Contains(c.Id)).ToList(); - } - - List list = new List(); - - foreach (var contact in contacts) - { - - ContactVM contactVM = new ContactVM(); - List contactEmailVms = new List(); - List contactPhoneVms = new List(); - - List conatctTagVms = new List(); - var phones = phoneNo.Where(p => p.ContactId == contact.Id).ToList(); - var emails = Emails.Where(e => e.ContactId == contact.Id).ToList(); - var tagMappingss = Tags.Where(t => t.ContactId == contact.Id).ToList(); - var projectMapping = contactProjects.Where(p => p.ContactId == contact.Id).ToList(); - var bucketMapping = contactBuckets.Where(b => b.ContactId == contact.Id).ToList(); - - - if (emails != null && emails.Count > 0) - { - foreach (var email in emails) - { - ContactEmailVM emailVM = new ContactEmailVM(); - emailVM = email.ToContactEmailVMFromContactEmail(); - contactEmailVms.Add(emailVM); - } - } - - if (phones != null && phones.Count > 0) - { - foreach (var phone in phones) - { - ContactPhoneVM phoneVM = new ContactPhoneVM(); - phoneVM = phone.ToContactPhoneVMFromContactPhone(); - contactPhoneVms.Add(phoneVM); - } - - } - if (tagMappingss != null && tagMappingss.Count > 0) - { - foreach (var tagMapping in tagMappingss) - { - ContactTagVM tagVM = new ContactTagVM(); ; - var tag = TagList.Find(t => t.Id == tagMapping.ContactTagId); - - tagVM = tag != null ? tag.ToContactTagVMFromContactTagMaster() : new ContactTagVM(); - conatctTagVms.Add(tagVM); - - - } - } - contactVM = contact.ToContactVMFromContact(); - - if (projectMapping != null && projectMapping.Count > 0) - { - contactVM.ProjectIds = projectMapping.Select(p => p.ProjectId).ToList(); - } - if (bucketMapping != null && bucketMapping.Count > 0) - { - contactVM.BucketIds = bucketMapping.Select(p => p.BucketId).ToList(); - } - - contactVM.ContactEmails = contactEmailVms; - contactVM.ContactPhones = contactPhoneVms; - contactVM.Tags = conatctTagVms; - - list.Add(contactVM); - } - _logger.LogInfo("{count} contacts are fetched by Employee with ID {LoggedInEmployeeId}", list.Count, LoggedInEmployee.Id); - return ApiResponse.SuccessResponse(list, System.String.Format("{0} contacts fetched successfully", list.Count), 200); - - } - public async Task> GetContactsListByBucketId(Guid id) - { - Guid tenantId = _userHelper.GetTenantId(); - var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); - if (id != Guid.Empty) - { - Bucket? bucket = await _context.Buckets.FirstOrDefaultAsync(b => b.Id == id && b.TenantId == tenantId); - if (bucket == null) - { - _logger.LogInfo("Employee ID {EmployeeId} attempted access to bucket ID {BucketId}, but not found in database", LoggedInEmployee.Id); - return ApiResponse.ErrorResponse("Bucket not found", "Bucket not found", 404); - } - List? employeeBuckets = await _context.EmployeeBucketMappings.Where(em => em.BucketId == id).ToListAsync(); - var assignedRoleIds = await _context.EmployeeRoleMappings.Where(r => r.EmployeeId == LoggedInEmployee.Id).Select(r => r.RoleId).ToListAsync(); - var permissionIds = await _context.RolePermissionMappings.Where(rp => assignedRoleIds.Contains(rp.ApplicationRoleId)).Select(rp => rp.FeaturePermissionId).Distinct().ToListAsync(); - - EmployeeBucketMapping? employeeBucket = null; - if (permissionIds.Contains(PermissionsMaster.DirectoryAdmin)) - { - employeeBucket = employeeBuckets.FirstOrDefault(); - } - else if (permissionIds.Contains(PermissionsMaster.DirectoryAdmin) || permissionIds.Contains(PermissionsMaster.DirectoryUser)) - { - employeeBucket = employeeBuckets.FirstOrDefault(eb => eb.EmployeeId == LoggedInEmployee.Id); - } - else - { - _logger.LogWarning("Employee {EmployeeId} attemped to access a contacts with in bucket {BucketId}, but do not have permission", LoggedInEmployee.Id, id); - return ApiResponse.ErrorResponse("You don't have permission", "You don't have permission", 401); - } - - if (employeeBucket == null) - { - _logger.LogInfo("Employee ID {EmployeeId} does not have access to bucket ID {BucketId}", LoggedInEmployee.Id); - return ApiResponse.ErrorResponse("You do not have access to this bucket.", "You do not have access to this bucket.", 401); - } - - List contactBucket = await _context.ContactBucketMappings.Where(cb => cb.BucketId == id).ToListAsync() ?? new List(); - List contactVMs = new List(); - if (contactBucket.Count > 0) - { - var contactIds = contactBucket.Select(cb => cb.ContactId).ToList(); - List contacts = await _context.Contacts.Include(c => c.ContactCategory).Where(c => contactIds.Contains(c.Id) && c.IsActive).ToListAsync(); - List phones = await _context.ContactsPhones.Where(p => contactIds.Contains(p.ContactId)).ToListAsync(); - List emails = await _context.ContactsEmails.Where(e => contactIds.Contains(e.ContactId)).ToListAsync(); - - List? tags = await _context.ContactTagMappings.Where(ct => contactIds.Contains(ct.ContactId)).ToListAsync(); - List? contactProjects = await _context.ContactProjectMappings.Where(cp => contactIds.Contains(cp.ContactId)).ToListAsync(); - List? contactBuckets = await _context.ContactBucketMappings.Where(cp => contactIds.Contains(cp.ContactId)).ToListAsync(); - - List tagIds = new List(); - List tagMasters = new List(); - if (tags.Count > 0) - { - tagIds = tags.Select(ct => ct.ContactTagId).ToList(); - tagMasters = await _context.ContactTagMasters.Where(t => tagIds.Contains(t.Id)).ToListAsync(); - } - - if (contacts.Count > 0) - { - - - foreach (var contact in contacts) - { - List? emailVMs = new List(); - List? phoneVMs = new List(); - List? tagVMs = new List(); - - List contactPhones = phones.Where(p => p.ContactId == contact.Id).ToList(); - List contactEmails = emails.Where(e => e.ContactId == contact.Id).ToList(); - - List? contactTags = tags.Where(t => t.ContactId == contact.Id).ToList(); - List? projectMappings = contactProjects.Where(cp => cp.ContactId == contact.Id).ToList(); - List? bucketMappings = contactBuckets.Where(cb => cb.ContactId == contact.Id).ToList(); - - if (contactPhones.Count > 0) - { - foreach (var phone in contactPhones) - { - ContactPhoneVM phoneVM = phone.ToContactPhoneVMFromContactPhone(); - phoneVMs.Add(phoneVM); - } - } - if (contactEmails.Count > 0) - { - foreach (var email in contactEmails) - { - ContactEmailVM emailVM = email.ToContactEmailVMFromContactEmail(); - emailVMs.Add(emailVM); - } - } - if (contactTags.Count > 0) - { - foreach (var contactTag in contactTags) - { - ContactTagMaster? tagMaster = tagMasters.Find(t => t.Id == contactTag.ContactTagId); - if (tagMaster != null) - { - ContactTagVM tagVM = tagMaster.ToContactTagVMFromContactTagMaster(); - tagVMs.Add(tagVM); - } - } - } - ContactVM contactVM = contact.ToContactVMFromContact(); - contactVM.ContactEmails = emailVMs; - contactVM.ContactPhones = phoneVMs; - contactVM.Tags = tagVMs; - contactVM.ProjectIds = projectMappings.Select(cp => cp.ProjectId).ToList(); - contactVM.BucketIds = bucketMappings.Select(cb => cb.BucketId).ToList(); - contactVMs.Add(contactVM); - } - } - - } - _logger.LogInfo("{count} contact from Bucket {BucketId} fetched by Employee {EmployeeId}", contactVMs.Count, id, LoggedInEmployee.Id); - return ApiResponse.SuccessResponse(contactVMs, $"{contactVMs.Count} contacts fetched successfully", 200); - } - _logger.LogInfo("Employee ID {EmployeeId} sent an empty Bucket id", LoggedInEmployee.Id); - return ApiResponse.ErrorResponse("Bucket ID is empty", "Bucket ID is empty", 400); - } - public async Task> CreateContact(CreateContactDto createContact) - { - Guid tenantId = _userHelper.GetTenantId(); - var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); - if (createContact != null) - { - List phones = new List(); - List emails = new List(); - List contactBucketMappings = new List(); - List contactTagMappings = new List(); - - Contact? contact = createContact.ToContactFromCreateContactDto(tenantId, LoggedInEmployee.Id); - - _context.Contacts.Add(contact); - await _context.SaveChangesAsync(); - _logger.LogInfo("Contact with ID {ContactId} created by Employee with ID {LoggedInEmployeeId}", contact.Id, LoggedInEmployee.Id); - - var tags = await _context.ContactTagMasters.Where(t => t.TenantId == tenantId).ToListAsync(); - var tagNames = tags.Select(t => t.Name.ToLower()).ToList(); - var buckets = await _context.Buckets.Where(b => b.TenantId == tenantId).Select(b => b.Id).ToListAsync(); - var projects = await _context.Projects.Where(p => p.TenantId == tenantId).Select(p => p.Id).ToListAsync(); - - if (createContact.ContactPhones != null) - { - - foreach (var contactPhone in createContact.ContactPhones) - { - ContactPhone phone = contactPhone.ToContactPhoneFromCreateContactPhoneDto(tenantId, contact.Id); - phones.Add(phone); - } - _context.ContactsPhones.AddRange(phones); - _logger.LogInfo("{count} phone number are saved in contact with ID {ContactId} by employee with ID {LoggedEmployeeId}", phones.Count, contact.Id, LoggedInEmployee.Id); - } - if (createContact.ContactEmails != null) - { - - foreach (var contactEmail in createContact.ContactEmails) - { - ContactEmail email = contactEmail.ToContactEmailFromCreateContactEmailDto(tenantId, contact.Id); - emails.Add(email); - } - _context.ContactsEmails.AddRange(emails); - _logger.LogInfo("{count} email addresses are saved in contact with ID {ContactId} by employee with ID {LoggedEmployeeId}", emails.Count, contact.Id, LoggedInEmployee.Id); - } - - if (createContact.BucketIds != null) - { - foreach (var bucket in createContact.BucketIds) - { - if (buckets.Contains(bucket)) - { - ContactBucketMapping bucketMapping = new ContactBucketMapping - { - BucketId = bucket, - ContactId = contact.Id - }; - contactBucketMappings.Add(bucketMapping); - } - } - _context.ContactBucketMappings.AddRange(contactBucketMappings); - _logger.LogInfo("Contact with ID {ContactId} added to {count} number of buckets by employee with ID {LoggedEmployeeId}", contact.Id, contactBucketMappings.Count, LoggedInEmployee.Id); - } - - if (createContact.ProjectIds != null) - { - List projectMappings = new List(); - foreach (var projectId in createContact.ProjectIds) - { - if (projects.Contains(projectId)) - { - ContactProjectMapping projectMapping = new ContactProjectMapping - { - ProjectId = projectId, - ContactId = contact.Id, - TenantId = tenantId - }; - projectMappings.Add(projectMapping); - } - } - _context.ContactProjectMappings.AddRange(projectMappings); - _logger.LogInfo("Contact with ID {ContactId} added to {count} number of project by employee with ID {LoggedEmployeeId}", contact.Id, projectMappings.Count, LoggedInEmployee.Id); - } - - if (createContact.Tags != null) - { - foreach (var tag in createContact.Tags) - { - if (tagNames.Contains(tag.Name.ToLower())) - { - ContactTagMaster existingTag = tags.Find(t => t.Name == tag.Name) ?? new ContactTagMaster(); - _context.ContactTagMappings.Add(new ContactTagMapping - { - ContactId = contact.Id, - ContactTagId = tag.Id ?? existingTag.Id - }); - } - else if (tag.Id == null || tags.Where(t => t.Name == tag.Name) == null) - { - var newtag = new ContactTagMaster - { - Name = tag.Name, - TenantId = tenantId - }; - _context.ContactTagMasters.Add(newtag); - ContactTagMapping tagMapping = new ContactTagMapping - { - ContactTagId = newtag.Id, - ContactId = contact.Id - }; - contactTagMappings.Add(tagMapping); - } - } - - _context.ContactTagMappings.AddRange(contactTagMappings); - _logger.LogInfo("{count} number of tags added to Contact with ID {ContactId} by employee with ID {LoggedEmployeeId}", contactTagMappings.Count, contact.Id, LoggedInEmployee.Id); - } - await _context.SaveChangesAsync(); - - ContactVM contactVM = new ContactVM(); - List phoneVMs = new List(); - - contact = await _context.Contacts.Include(c => c.ContactCategory).FirstOrDefaultAsync(c => c.Id == contact.Id) ?? new Contact(); - var tagIds = contactTagMappings.Select(t => t.ContactTagId).ToList(); - tags = await _context.ContactTagMasters.Where(t => t.TenantId == tenantId && tagIds.Contains(t.Id)).ToListAsync(); - List contactProjects = await _context.ContactProjectMappings.Where(cp => cp.ContactId == contact.Id).ToListAsync(); - List bucketMappings = await _context.ContactBucketMappings.Where(cb => cb.ContactId == contact.Id).ToListAsync(); - foreach (var phone in phones) - { - ContactPhoneVM phoneVM = phone.ToContactPhoneVMFromContactPhone(); - phoneVMs.Add(phoneVM); - } - List emailVMs = new List(); - foreach (var email in emails) - { - ContactEmailVM emailVM = email.ToContactEmailVMFromContactEmail(); - emailVMs.Add(emailVM); - } - List tagVMs = new List(); - foreach (var contactTagMapping in contactTagMappings) - { - ContactTagVM tagVM = new ContactTagVM(); - var tag = tags.Find(t => t.Id == contactTagMapping.ContactTagId); - tagVM = tag != null ? tag.ToContactTagVMFromContactTagMaster() : new ContactTagVM(); - tagVMs.Add(tagVM); - } - - - contactVM = contact.ToContactVMFromContact(); - contactVM.ContactPhones = phoneVMs; - contactVM.ContactEmails = emailVMs; - contactVM.Tags = tagVMs; - contactVM.ProjectIds = contactProjects.Select(cp => cp.ProjectId).ToList(); - contactVM.BucketIds = bucketMappings.Select(cb => cb.BucketId).ToList(); - - return ApiResponse.SuccessResponse(contactVM, "Contact Created Successfully", 200); - } - _logger.LogWarning("Employee with ID {LoggedInEmployeeId} sended empty payload", LoggedInEmployee.Id); - return ApiResponse.ErrorResponse("User Send empty Payload", "User Send empty Payload", 400); - } - public async Task> UpdateContact(Guid id, UpdateContactDto updateContact) - { - Guid tenantId = _userHelper.GetTenantId(); - var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); - if (updateContact != null) - { - if (updateContact.Id != id) - { - _logger.LogWarning("Employee with ID {LoggedInEmployeeId} sended different ID in payload and path parameter", LoggedInEmployee.Id); - return ApiResponse.ErrorResponse("Invalid data", "Invalid data", 400); - } - Contact? contact = await _context.Contacts.AsNoTracking().FirstOrDefaultAsync(c => c.Id == id && c.IsActive && c.TenantId == tenantId); - if (contact == null) - { - _logger.LogWarning("Employee with ID {LoggedInEmployeeId} tries to update contact with ID {ContactId} is not found in database", LoggedInEmployee.Id); - return ApiResponse.ErrorResponse("Contact not found", "Contact not found", 404); - } - - var assignedRoleIds = await _context.EmployeeRoleMappings.Where(r => r.EmployeeId == LoggedInEmployee.Id).Select(r => r.RoleId).ToListAsync(); - var permissionIds = await _context.RolePermissionMappings.Where(rp => assignedRoleIds.Contains(rp.ApplicationRoleId)).Select(rp => rp.FeaturePermissionId).Distinct().ToListAsync(); - List? employeeBuckets = await _context.EmployeeBucketMappings.Where(eb => eb.EmployeeId == LoggedInEmployee.Id).ToListAsync(); - List bucketIds = employeeBuckets.Select(c => c.BucketId).ToList(); - if (permissionIds.Contains(PermissionsMaster.DirectoryAdmin)) - { - var buckets = await _context.Buckets.Where(b => b.TenantId == tenantId).ToListAsync(); - bucketIds = buckets.Select(b => b.Id).ToList(); - } - else if (permissionIds.Contains(PermissionsMaster.DirectoryAdmin) || permissionIds.Contains(PermissionsMaster.DirectoryUser)) - { - var buckets = await _context.Buckets.Where(b => b.CreatedByID == LoggedInEmployee.Id).ToListAsync(); - var createdBucketIds = buckets.Select(b => b.Id).ToList(); - bucketIds.AddRange(createdBucketIds); - bucketIds = bucketIds.Distinct().ToList(); - } - else - { - _logger.LogWarning("Employee {EmployeeId} attemped to update a contact, but do not have permission", LoggedInEmployee.Id); - return ApiResponse.ErrorResponse("You don't have permission", "You don't have permission", 401); - } - - List contactBuckets = await _context.ContactBucketMappings.AsNoTracking().Where(m => m.ContactId == contact.Id && bucketIds.Contains(m.BucketId)).ToListAsync(); - bucketIds = contactBuckets.Select(b => b.BucketId).Distinct().ToList(); - - - - var newContact = updateContact.ToContactFromUpdateContactDto(tenantId, contact); - newContact.UpdatedById = LoggedInEmployee.Id; - newContact.UpdatedAt = DateTime.UtcNow; - _context.Contacts.Update(newContact); - await _context.SaveChangesAsync(); - - List phones = await _context.ContactsPhones.AsNoTracking().Where(p => p.ContactId == contact.Id).ToListAsync(); - var phoneIds = phones.Select(p => p.Id).ToList(); - List emails = await _context.ContactsEmails.AsNoTracking().Where(p => p.ContactId == contact.Id).ToListAsync(); - var emailIds = emails.Select(p => p.Id).ToList(); - - - - List contactTags = await _context.ContactTagMappings.AsNoTracking().Where(m => m.ContactId == contact.Id).ToListAsync(); - var tagIds = contactTags.Select(t => t.ContactTagId).Distinct().ToList(); - - - List contactProjects = await _context.ContactProjectMappings.AsNoTracking().Where(m => m.ContactId == contact.Id).ToListAsync(); - var projectIds = contactProjects.Select(t => t.ProjectId).Distinct().ToList(); - - List tags = await _context.ContactTagMasters.Where(t => tagIds.Contains(t.Id)).ToListAsync(); - List allTags = await _context.ContactTagMasters.Where(t => t.TenantId == tenantId).ToListAsync(); - var tagNames = allTags.Select(t => t.Name.ToLower()).ToList(); - - if (updateContact.ContactPhones != null) - { - var updatedPhoneIds = updateContact.ContactPhones.Select(p => p.Id).Distinct().ToList(); - foreach (var phoneDto in updateContact.ContactPhones) - { - var phone = phoneDto.ToContactPhoneFromUpdateContactPhoneDto(tenantId, contact.Id); - if (phoneDto.Id != null && phoneDto.Id != Guid.Empty && phoneIds.Contains(phone.Id)) - { - _context.ContactsPhones.Update(phone); - } - else - { - _context.ContactsPhones.Add(phone); - } - } - foreach (var phone in phones) - { - - if (!updatedPhoneIds.Contains(phone.Id)) - { - _context.ContactsPhones.Remove(phone); - } - } - } - else if (phones != null) - { - _context.ContactsPhones.RemoveRange(phones); - } - - if (updateContact.ContactEmails != null) - { - var updateEmailIds = updateContact.ContactEmails.Select(p => p.Id).Distinct().ToList(); - - foreach (var emailDto in updateContact.ContactEmails) - { - var email = emailDto.ToContactEmailFromUpdateContactEmailDto(tenantId, contact.Id); - if (emailDto.Id != null && emailDto.Id != Guid.Empty && emailIds.Contains(email.Id)) - { - _context.ContactsEmails.Update(email); - } - else - { - _context.ContactsEmails.Add(email); - } - } - foreach (var email in emails) - { - - if (!updateEmailIds.Contains(email.Id)) - { - _context.ContactsEmails.Remove(email); - } - } - } - else if (emails != null) - { - _context.ContactsEmails.RemoveRange(emails); - } - - if (updateContact.BucketIds != null) - { - foreach (var bucketId in updateContact.BucketIds) - { - if (!bucketIds.Contains(bucketId)) - { - _context.ContactBucketMappings.Add(new ContactBucketMapping - { - BucketId = bucketId, - ContactId = contact.Id - }); - } - } - foreach (var bucketMapping in contactBuckets) - { - if (!updateContact.BucketIds.Contains(bucketMapping.BucketId)) - { - _context.ContactBucketMappings.Remove(bucketMapping); - } - } - } - else if (contactBuckets != null) - { - _context.ContactBucketMappings.RemoveRange(contactBuckets); - } - - if (updateContact.ProjectIds != null) - { - foreach (var ProjectId in updateContact.ProjectIds) - { - if (!projectIds.Contains(ProjectId)) - { - _context.ContactProjectMappings.Add(new ContactProjectMapping - { - ProjectId = ProjectId, - ContactId = contact.Id, - TenantId = tenantId - }); - } - } - - foreach (var projectMapping in contactProjects) - { - if (!updateContact.ProjectIds.Contains(projectMapping.ProjectId)) - { - _context.ContactProjectMappings.Remove(projectMapping); - } - } - } - else if (contactProjects != null) - { - _context.ContactProjectMappings.RemoveRange(contactProjects); - } - - if (updateContact.Tags != null) - { - var updatedTagIds = updateContact.Tags.Select(t => t.Id).Distinct().ToList(); - foreach (var tag in updateContact.Tags) - { - var namecheck = tagNames.Contains(tag.Name.ToLower()); - var idCheck = (!tagIds.Contains(tag.Id ?? Guid.Empty)); - var test = namecheck && idCheck; - if (test) - { - ContactTagMaster existingTag = tags.Find(t => t.Name == tag.Name) ?? new ContactTagMaster(); - _context.ContactTagMappings.Add(new ContactTagMapping - { - ContactId = contact.Id, - ContactTagId = tag.Id ?? existingTag.Id - }); - } - else if (tag.Id == null || tag.Id == Guid.Empty) - { - ContactTagMaster contactTag = new ContactTagMaster - { - Name = tag.Name, - Description = "", - TenantId = tenantId - }; - _context.ContactTagMasters.Add(contactTag); - - _context.ContactTagMappings.Add(new ContactTagMapping - { - ContactId = contact.Id, - ContactTagId = contactTag.Id - }); - } - } - foreach (var contactTag in contactTags) - { - if (!updatedTagIds.Contains(contactTag.ContactTagId)) - { - _context.ContactTagMappings.Remove(contactTag); - } - } - } - else if (contactTags != null) - { - _context.ContactTagMappings.RemoveRange(contactTags); - } - _context.DirectoryUpdateLogs.Add(new DirectoryUpdateLog - { - RefereanceId = contact.Id, - UpdatedById = LoggedInEmployee.Id, - UpdateAt = DateTime.UtcNow - }); - - await _context.SaveChangesAsync(); - - contact = await _context.Contacts.Include(c => c.ContactCategory).FirstOrDefaultAsync(c => c.Id == id && c.IsActive && c.TenantId == tenantId) ?? new Contact(); - phones = await _context.ContactsPhones.AsNoTracking().Where(p => p.ContactId == contact.Id).ToListAsync(); - emails = await _context.ContactsEmails.AsNoTracking().Where(p => p.ContactId == contact.Id).ToListAsync(); - contactTags = await _context.ContactTagMappings.AsNoTracking().Where(m => m.ContactId == contact.Id).ToListAsync(); - contactBuckets = await _context.ContactBucketMappings.AsNoTracking().Where(cb => cb.ContactId == contact.Id).ToListAsync(); - contactProjects = await _context.ContactProjectMappings.AsNoTracking().Where(cp => cp.ContactId == contact.Id).ToListAsync(); - tagIds = contactTags.Select(t => t.ContactTagId).Distinct().ToList(); - tags = await _context.ContactTagMasters.Where(t => tagIds.Contains(t.Id)).ToListAsync(); - - ContactVM contactVM = new ContactVM(); - List phoneVMs = new List(); - foreach (var phone in phones) - { - ContactPhoneVM phoneVM = phone.ToContactPhoneVMFromContactPhone(); - phoneVMs.Add(phoneVM); - } - List emailVMs = new List(); - foreach (var email in emails) - { - ContactEmailVM emailVM = email.ToContactEmailVMFromContactEmail(); - emailVMs.Add(emailVM); - } - List tagVMs = new List(); - foreach (var contactTagMapping in contactTags) - { - ContactTagVM tagVM = new ContactTagVM(); - var tag = tags.Find(t => t.Id == contactTagMapping.ContactTagId); - tagVM = tag != null ? tag.ToContactTagVMFromContactTagMaster() : new ContactTagVM(); - tagVMs.Add(tagVM); - } - - - contactVM = contact.ToContactVMFromContact(); - contactVM.ContactPhones = phoneVMs; - contactVM.ContactEmails = emailVMs; - contactVM.Tags = tagVMs; - contactVM.BucketIds = contactBuckets.Select(cb => cb.BucketId).ToList(); - contactVM.ProjectIds = contactProjects.Select(cp => cp.ProjectId).ToList(); - - _logger.LogInfo("Conatct {ContactId} has been updated by employee {EmployeeId}", contact.Id, LoggedInEmployee.Id); - return ApiResponse.SuccessResponse(contactVM, "Contact Updated Successfully", 200); - } - _logger.LogWarning("Employee with ID {LoggedInEmployeeId} sended empty payload", LoggedInEmployee.Id); - return ApiResponse.ErrorResponse("User Send empty Payload", "User Send empty Payload", 400); - } - public async Task> GetContactProfile(Guid id) - { - Guid tenantId = _userHelper.GetTenantId(); - var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); - var hasAdminPermission = await _permissionServices.HasPermission(PermissionsMaster.DirectoryAdmin, LoggedInEmployee.Id); - if (id != Guid.Empty) - { - Contact? contact = await _context.Contacts.Include(c => c.ContactCategory).Include(c => c.CreatedBy).FirstOrDefaultAsync(c => c.Id == id && c.IsActive); - if (contact == null) - { - _logger.LogWarning("Employee with ID {LoggedInEmployeeId} tries to update contact with ID {ContactId} is not found in database", LoggedInEmployee.Id); - return ApiResponse.ErrorResponse("Contact not found", "Contact not found", 404); - } - ContactProfileVM contactVM = contact.ToContactProfileVMFromContact(); - DirectoryUpdateLog? updateLog = await _context.DirectoryUpdateLogs.Include(l => l.Employee).Where(l => l.RefereanceId == contact.Id).OrderByDescending(l => l.UpdateAt).FirstOrDefaultAsync(); - if (updateLog != null) - { - contactVM.UpdatedAt = updateLog.UpdateAt; - contactVM.UpdatedBy = updateLog.Employee != null ? updateLog.Employee.ToBasicEmployeeVMFromEmployee() : null; - } - - List? phones = await _context.ContactsPhones.Where(p => p.ContactId == contact.Id).ToListAsync(); - if (phones.Any()) - { - List? phoneVMs = new List(); - foreach (var phone in phones) - { - ContactPhoneVM phoneVM = phone.ToContactPhoneVMFromContactPhone(); - phoneVMs.Add(phoneVM); - } - contactVM.ContactPhones = phoneVMs; - } - - List? emails = await _context.ContactsEmails.Where(e => e.ContactId == contact.Id).ToListAsync(); - if (emails.Any()) - { - List? emailVMs = new List(); - foreach (var email in emails) - { - ContactEmailVM emailVM = email.ToContactEmailVMFromContactEmail(); - emailVMs.Add(emailVM); - } - contactVM.ContactEmails = emailVMs; - } - - List? contactProjects = await _context.ContactProjectMappings.Where(cp => cp.ContactId == contact.Id).ToListAsync(); - if (contactProjects.Any()) - { - List projectIds = contactProjects.Select(cp => cp.ProjectId).ToList(); - List? projects = await _context.Projects.Where(p => projectIds.Contains(p.Id) && p.TenantId == tenantId).ToListAsync(); - List? projectVMs = new List(); - foreach (var project in projects) - { - BasicProjectVM projectVM = new BasicProjectVM - { - Id = project.Id, - Name = project.Name - }; - projectVMs.Add(projectVM); - } - contactVM.Projects = projectVMs; - } - List? contactBuckets = await _context.ContactBucketMappings.Where(cb => cb.ContactId == contact.Id).ToListAsync(); - List? employeeBuckets = await _context.EmployeeBucketMappings.Where(eb => eb.EmployeeId == LoggedInEmployee.Id).ToListAsync(); - if (contactBuckets.Any() && (employeeBuckets.Any() || hasAdminPermission)) - { - List contactBucketIds = contactBuckets.Select(cb => cb.BucketId).ToList(); - List employeeBucketIds = employeeBuckets.Select(eb => eb.BucketId).ToList(); - List? buckets = null; - if (hasAdminPermission) - { - buckets = await _context.Buckets.Where(b => contactBucketIds.Contains(b.Id)).ToListAsync(); - } - else - { - buckets = await _context.Buckets.Where(b => contactBucketIds.Contains(b.Id) && employeeBucketIds.Contains(b.Id)).ToListAsync(); - } - List? bucketVMs = new List(); - foreach (var bucket in buckets) - { - BucketVM bucketVM = bucket.ToBucketVMFromBucket(); - bucketVMs.Add(bucketVM); - } - contactVM.Buckets = bucketVMs; - } - List? contactTags = await _context.ContactTagMappings.Where(ct => ct.ContactId == contact.Id).ToListAsync(); - if (contactTags.Any()) - { - List tagIds = contactTags.Select(ct => ct.ContactTagId).ToList(); - List tagMasters = await _context.ContactTagMasters.Where(t => tagIds.Contains(t.Id)).ToListAsync(); - List tagVMs = new List(); - foreach (var tagMaster in tagMasters) - { - ContactTagVM tagVM = tagMaster.ToContactTagVMFromContactTagMaster(); - tagVMs.Add(tagVM); - } - contactVM.Tags = tagVMs; - } - //List? notes = await _context.ContactNotes.Where(n => n.ContactId == contact.Id && n.IsActive).ToListAsync(); - //if (notes.Any()) - //{ - // List? noteIds = notes.Select(n => n.Id).ToList(); - // List? noteUpdateLogs = await _context.DirectoryUpdateLogs.Include(l => l.Employee).Where(l => noteIds.Contains(l.RefereanceId)).OrderByDescending(l => l.UpdateAt).ToListAsync(); - // List? noteVMs = new List(); - // foreach (var note in notes) - // { - // DirectoryUpdateLog? noteUpdateLog = noteUpdateLogs.Where(n => n.RefereanceId == note.Id).OrderByDescending(l => l.UpdateAt).FirstOrDefault(); - // ContactNoteVM noteVM = note.ToContactNoteVMFromContactNote(); - // if (noteUpdateLog != null) - // { - // noteVM.UpdatedAt = noteUpdateLog.UpdateAt; - // noteVM.UpdatedBy = noteUpdateLog.Employee != null ? noteUpdateLog.Employee.ToBasicEmployeeVMFromEmployee() : null; - // } - // noteVMs.Add(noteVM); - // } - // contactVM.Notes = noteVMs; - //} - _logger.LogInfo("Employee ID {EmployeeId} fetched profile of contact {COntactId}", LoggedInEmployee.Id, contact.Id); - return ApiResponse.SuccessResponse(contactVM, "Contact profile fetched successfully"); - - } - _logger.LogInfo("Employee ID {EmployeeId} sent an empty contact id", LoggedInEmployee.Id); - return ApiResponse.ErrorResponse("Contact ID is empty", "Contact ID is empty", 400); - } - public async Task> GetOrganizationList() - { - // Step 1: Retrieve tenant and employee context - Guid tenantId = _userHelper.GetTenantId(); - var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); - - _logger.LogInfo("GetOrganizationList called by EmployeeId: {EmployeeId} for TenantId: {TenantId}", - loggedInEmployee.Id, tenantId); - - // Step 2: Fetch distinct, non-empty organization names - var organizationList = await _context.Contacts - .Where(c => c.TenantId == tenantId && !string.IsNullOrWhiteSpace(c.Organization)) - .Select(c => c.Organization.Trim()) - .Distinct() - .ToListAsync(); - - _logger.LogInfo("EmployeeId: {EmployeeId} fetched {Count} organization names from TenantId: {TenantId}", - loggedInEmployee.Id, organizationList.Count, tenantId); - - // Step 3: Return success response - return ApiResponse.SuccessResponse( - organizationList, - $"{organizationList.Count} records of organization names fetched from contacts", - 200 - ); - } - public async Task> GetDesignationList() - { - // Step 1: Get tenant and logged-in employee details - Guid tenantId = _userHelper.GetTenantId(); - var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); - - _logger.LogInfo("GetDesignationList called by EmployeeId: {EmployeeId} in TenantId: {TenantId}", - loggedInEmployee.Id, tenantId); - - // Step 2: Fetch distinct, non-null designations from contacts - var designationList = await _context.Contacts - .Where(c => c.TenantId == tenantId && !string.IsNullOrWhiteSpace(c.Designation)) - .Select(c => c.Designation.Trim()) - .Distinct() - .ToListAsync(); - - _logger.LogInfo("EmployeeId: {EmployeeId} fetched {Count} designations from TenantId: {TenantId}", - loggedInEmployee.Id, designationList.Count, tenantId); - - // Step 3: Return result - return ApiResponse.SuccessResponse( - designationList, - $"{designationList.Count} records of designation fetched from contacts", - 200 - ); - } - public async Task> DeleteContact(Guid id, bool active) - { - // Step 1: Get tenant and logged-in employee info - Guid tenantId = _userHelper.GetTenantId(); - var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); - - _logger.LogInfo("DeleteContact called by EmployeeId: {EmployeeId} for ContactId: {ContactId} with Active: {IsActive}", - loggedInEmployee.Id, id, active); - - // Step 2: Validate contact ID - if (id == Guid.Empty) - { - _logger.LogWarning("Empty contact ID received from EmployeeId: {EmployeeId}", loggedInEmployee.Id); - return ApiResponse.ErrorResponse("Contact ID is empty", "Contact ID is empty", 400); - } - - // Step 3: Check if contact exists under current tenant - var contact = await _context.Contacts - .FirstOrDefaultAsync(c => c.Id == id && c.TenantId == tenantId); - - if (contact == null) - { - _logger.LogWarning("EmployeeId {EmployeeId} attempted to delete non-existent contact Id: {ContactId}", loggedInEmployee.Id, id); - return ApiResponse.ErrorResponse("Contact not found", "Contact not found", 404); - } - - // Step 4: Soft delete or restore contact - contact.IsActive = active; - - // Step 5: Log the update in DirectoryUpdateLog - _context.DirectoryUpdateLogs.Add(new DirectoryUpdateLog - { - RefereanceId = contact.Id, - UpdatedById = loggedInEmployee.Id, - UpdateAt = DateTime.UtcNow - }); - - await _context.SaveChangesAsync(); - - string status = active ? "restored" : "deleted"; - _logger.LogInfo("Contact {ContactId} successfully {Status} by EmployeeId: {EmployeeId}", - contact.Id, status, loggedInEmployee.Id); - - // Step 6: Return success response - return ApiResponse.SuccessResponse(new { }, $"Contact {status} successfully", 200); - } - - // -------------------------------- Contact Notes -------------------------------- - - /// - /// Retrieves a paginated list of contact notes based on user permissions. - /// - /// The number of items per page. - /// The current page number. - /// An ApiResponse containing the paginated notes or an error message. - 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) - { - _logger.LogWarning("GetListOFAllNotes: LoggedInEmployee is null. Cannot proceed."); - return ApiResponse.ErrorResponse("Unauthorized", "Employee not found.", 401); - } - - // --- 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 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)) - { - _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); - var assignedBucketIds = await _context.EmployeeBucketMappings - .Where(eb => eb.EmployeeId == loggedInEmployee.Id) - .Select(eb => eb.BucketId) - .ToListAsync(); - - 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); - } - - 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); - } - - 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 - pageSize = pageSize < 1 ? 25 : pageSize; // Default to 25 if less than 1 - pageNumber = pageNumber < 1 ? 1 : pageNumber; // Default to 1 if less than 1 - - // Get total count BEFORE applying Skip/Take for accurate pagination metadata - int totalRecords = await notesQuery.CountAsync(); - int totalPages = (int)Math.Ceiling((double)totalRecords / pageSize); - - int skip = (pageNumber - 1) * pageSize; - - // --- Apply Ordering and Pagination in the database --- - List notes = await notesQuery - .OrderByDescending(cn => (cn.UpdatedAt != null ? cn.UpdatedAt : cn.CreatedAt)) // Order by updated date or created date - .Skip(skip) - .Take(pageSize) - .ToListAsync(); - - _logger.LogInfo("GetListOFAllNotes: Fetched {Count} notes for page {PageNumber} of {TotalPages} total pages. Total records: {TotalRecords}.", - notes.Count, pageNumber, totalPages, totalRecords); - - // --- 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()) - .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.SuccessResponse(response, $"{noteVMS.Count} notes fetched successfully.", 200); - } - public async Task> 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 notes = new List(); - 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? updateLogs = await _context.DirectoryUpdateLogs.Include(l => l.Employee).Where(l => noteIds.Contains(l.RefereanceId)).ToListAsync(); - //List? noteVMs = new List(); - List? 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.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.ErrorResponse("Contact not found", "Contact not found", 404); - } - public async Task> CreateContactNote(CreateContactNoteDto noteDto) - { - 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); - _context.ContactNotes.Add(note); - await _context.SaveChangesAsync(); - ContactNoteVM noteVM = note.ToContactNoteVMFromContactNote(); - _logger.LogInfo("Employee {EmployeeId} Added note at contact {ContactId}", LoggedInEmployee.Id, contact.Id); - return ApiResponse.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); - return ApiResponse.ErrorResponse("Contact not found", "Contact not found", 404); - } - _logger.LogWarning("Employee with ID {LoggedInEmployeeId} sended empty payload", LoggedInEmployee.Id); - return ApiResponse.ErrorResponse("User Send empty Payload", "User Send empty Payload", 400); - } - public async Task> UpdateContactNote(Guid id, UpdateContactNoteDto noteDto) - { - Guid tenantId = _userHelper.GetTenantId(); - var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); - if (noteDto != null && id == noteDto.Id) - { - 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); - if (contactNote != null) - { - contactNote.Note = noteDto.Note; - contactNote.UpdatedById = LoggedInEmployee.Id; - contactNote.UpdatedAt = DateTime.UtcNow; - - _context.DirectoryUpdateLogs.Add(new DirectoryUpdateLog - { - RefereanceId = id, - UpdatedById = LoggedInEmployee.Id, - UpdateAt = DateTime.UtcNow - }); - - await _context.SaveChangesAsync(); - ContactNoteVM noteVM = contactNote.ToContactNoteVMFromContactNote(); - noteVM.UpdatedAt = DateTime.UtcNow; - noteVM.UpdatedBy = LoggedInEmployee.ToBasicEmployeeVMFromEmployee(); - - _logger.LogInfo("Employee {EmployeeId} updated note {NoteId} at contact {ContactId}", LoggedInEmployee.Id, noteVM.Id, contact.Id); - return ApiResponse.SuccessResponse(noteVM, "Note updated successfully", 200); - } - _logger.LogWarning("Employee with ID {LoggedInEmployeeId} attempted to update a note {NoteId} to contact with ID {ContactId}, but the Note was not found in the database.", LoggedInEmployee.Id, noteDto.Id, noteDto.ContactId); - return ApiResponse.ErrorResponse("Note not found", "Note not found", 404); - } - _logger.LogWarning("Employee with ID {LoggedInEmployeeId} attempted to update a note {NoteId} to contact with ID {ContactId}, but the contact was not found in the database.", LoggedInEmployee.Id, noteDto.Id, noteDto.ContactId); - return ApiResponse.ErrorResponse("Contact not found", "Contact not found", 404); - } - _logger.LogWarning("Employee with ID {LoggedInEmployeeId} sended empty payload", LoggedInEmployee.Id); - return ApiResponse.ErrorResponse("User Send empty Payload", "User Send empty Payload", 400); - } - public async Task> DeleteContactNote(Guid id, bool active) - { - Guid tenantId = _userHelper.GetTenantId(); - var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); - - ContactNote? note = await _context.ContactNotes.FirstOrDefaultAsync(n => n.Id == id && n.TenantId == tenantId); - if (note != null) - { - note.IsActive = active; - note.UpdatedById = LoggedInEmployee.Id; - note.UpdatedAt = DateTime.UtcNow; - - _context.DirectoryUpdateLogs.Add(new DirectoryUpdateLog - { - RefereanceId = id, - UpdatedById = LoggedInEmployee.Id, - UpdateAt = DateTime.UtcNow - }); - await _context.SaveChangesAsync(); - _logger.LogInfo("Employee {EmployeeId} deleted note {NoteId}", LoggedInEmployee.Id, id); - } - - _logger.LogWarning("Employee {EmployeeId} tries to delete contact note {NoteId} but not found in database", LoggedInEmployee.Id, id); - return ApiResponse.SuccessResponse(new { }, "Note deleted successfully", 200); - } - - // -------------------------------- Bucket -------------------------------- - - public async Task> GetBucketList() - { - Guid tenantId = _userHelper.GetTenantId(); - var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); - var assignedRoleIds = await _context.EmployeeRoleMappings.Where(r => r.EmployeeId == LoggedInEmployee.Id).Select(r => r.RoleId).ToListAsync(); - var permissionIds = await _context.RolePermissionMappings.Where(rp => assignedRoleIds.Contains(rp.ApplicationRoleId)).Select(rp => rp.FeaturePermissionId).Distinct().ToListAsync(); - - List employeeBuckets = await _context.EmployeeBucketMappings.Where(b => b.EmployeeId == LoggedInEmployee.Id).ToListAsync(); - var bucketIds = employeeBuckets.Select(b => b.BucketId).ToList(); - - List bucketList = new List(); - if (permissionIds.Contains(PermissionsMaster.DirectoryAdmin)) - { - bucketList = await _context.Buckets.Include(b => b.CreatedBy).Where(b => b.TenantId == tenantId).ToListAsync(); - bucketIds = bucketList.Select(b => b.Id).ToList(); - } - else if (permissionIds.Contains(PermissionsMaster.DirectoryAdmin) || permissionIds.Contains(PermissionsMaster.DirectoryUser)) - { - bucketList = await _context.Buckets.Include(b => b.CreatedBy).Where(b => bucketIds.Contains(b.Id) || b.CreatedByID == LoggedInEmployee.Id).ToListAsync(); - } - else - { - _logger.LogWarning("Employee {EmployeeId} attemped to access a buckets list, but do not have permission", LoggedInEmployee.Id); - return ApiResponse.ErrorResponse("You don't have permission", "You don't have permission", 401); - } - - List employeeBucketVM = await _context.EmployeeBucketMappings.Where(b => bucketIds.Contains(b.BucketId)).ToListAsync(); - - List bucketVMs = new List(); - if (bucketList.Any()) - { - bucketIds = bucketList.Select(b => b.Id).ToList(); - List? contactBucketMappings = await _context.ContactBucketMappings.Where(cb => bucketIds.Contains(cb.BucketId)).ToListAsync(); - foreach (var bucket in bucketList) - { - List employeeBucketMappings = employeeBucketVM.Where(eb => eb.BucketId == bucket.Id).ToList(); - var emplyeeIds = employeeBucketMappings.Select(eb => eb.EmployeeId).ToList(); - List? contactBuckets = contactBucketMappings.Where(cb => cb.BucketId == bucket.Id).ToList(); - AssignBucketVM bucketVM = bucket.ToAssignBucketVMFromBucket(); - if (bucketVM.CreatedBy != null) - { - emplyeeIds.Add(bucketVM.CreatedBy.Id); - } - bucketVM.EmployeeIds = emplyeeIds.Distinct().ToList(); - bucketVM.NumberOfContacts = contactBuckets.Count; - bucketVMs.Add(bucketVM); - } - } - - _logger.LogInfo("{count} Buckets are fetched by Employee with ID {LoggedInEmployeeId}", bucketVMs.Count, LoggedInEmployee.Id); - return ApiResponse.SuccessResponse(bucketVMs, $"{bucketVMs.Count} buckets fetched successfully", 200); - } - public async Task> CreateBucket(CreateBucketDto bucketDto) - { - Guid tenantId = _userHelper.GetTenantId(); - var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); - if (bucketDto != null) - { - var assignedRoleIds = await _context.EmployeeRoleMappings.Where(r => r.EmployeeId == LoggedInEmployee.Id).Select(r => r.RoleId).ToListAsync(); - var permissionIds = await _context.RolePermissionMappings.Where(rp => assignedRoleIds.Contains(rp.ApplicationRoleId)).Select(rp => rp.FeaturePermissionId).Distinct().ToListAsync(); - var demo = !permissionIds.Contains(PermissionsMaster.DirectoryUser); - if (!permissionIds.Contains(PermissionsMaster.DirectoryAdmin) && !permissionIds.Contains(PermissionsMaster.DirectoryAdmin) && !permissionIds.Contains(PermissionsMaster.DirectoryUser)) - { - _logger.LogWarning("Employee {EmployeeId} attemped to create a bucket, but do not have permission", LoggedInEmployee.Id); - return ApiResponse.ErrorResponse("You don't have permission", "You don't have permission", 401); - } - - var existingBucket = await _context.Buckets.FirstOrDefaultAsync(b => b.Name == bucketDto.Name); - if (existingBucket != null) - { - _logger.LogWarning("Employee ID {LoggedInEmployeeId} attempted to create an existing bucket.", LoggedInEmployee.Id); - return ApiResponse.ErrorResponse("Bucket already existed", "Bucket already existed", 409); - } - Bucket bucket = new Bucket - { - Name = bucketDto.Name, - Description = bucketDto.Description, - CreatedAt = DateTime.UtcNow, - CreatedByID = LoggedInEmployee.Id, - TenantId = tenantId - }; - _context.Buckets.Add(bucket); - - EmployeeBucketMapping employeeBucket = new EmployeeBucketMapping - { - EmployeeId = LoggedInEmployee.Id, - BucketId = bucket.Id - }; - - _context.EmployeeBucketMappings.Add(employeeBucket); - await _context.SaveChangesAsync(); - bucket = await _context.Buckets.Include(b => b.CreatedBy).FirstOrDefaultAsync(b => b.Id == bucket.Id) ?? new Bucket(); - BucketVM bucketVM = bucket.ToBucketVMFromBucket(); - _logger.LogInfo("Employee Id {LoggedInEmployeeId} creayted new bucket {BucketId}", LoggedInEmployee.Id, bucket.Id); - return ApiResponse.SuccessResponse(bucketVM, "Bucket Created SuccessFully", 200); - } - _logger.LogWarning("Employee with ID {LoggedInEmployeeId} sended empty payload", LoggedInEmployee.Id); - return ApiResponse.ErrorResponse("User Send empty Payload", "User Send empty Payload", 400); - } - public async Task> UpdateBucket(Guid id, UpdateBucketDto bucketDto) - { - Guid tenantId = _userHelper.GetTenantId(); - var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); - if (bucketDto != null && id == bucketDto.Id) - { - var assignedRoleIds = await _context.EmployeeRoleMappings.Where(r => r.EmployeeId == LoggedInEmployee.Id).Select(r => r.RoleId).ToListAsync(); - var permissionIds = await _context.RolePermissionMappings.Where(rp => assignedRoleIds.Contains(rp.ApplicationRoleId)).Select(rp => rp.FeaturePermissionId).Distinct().ToListAsync(); - var employeeBuckets = await _context.EmployeeBucketMappings.Where(eb => eb.BucketId == id).ToListAsync(); - var bucketIds = employeeBuckets.Where(eb => eb.EmployeeId == LoggedInEmployee.Id).Select(eb => eb.BucketId).ToList(); - Bucket? bucket = await _context.Buckets.Include(b => b.CreatedBy).FirstOrDefaultAsync(b => b.Id == bucketDto.Id && b.TenantId == tenantId); - - if (bucket == null) - { - _logger.LogWarning("Employee ID {LoggedInEmployeeId} attempted to update a bucket but not found in database.", LoggedInEmployee.Id); - return ApiResponse.ErrorResponse("Bucket not found", "Bucket not found", 404); - } - - Bucket? accessableBucket = null; - if (permissionIds.Contains(PermissionsMaster.DirectoryAdmin)) - { - accessableBucket = bucket; - } - else if (permissionIds.Contains(PermissionsMaster.DirectoryAdmin) && bucketIds.Contains(id)) - { - accessableBucket = bucket; - } - else if (permissionIds.Contains(PermissionsMaster.DirectoryUser)) - { - if (bucket.CreatedByID == LoggedInEmployee.Id) - { - accessableBucket = bucket; - } - } - if (accessableBucket == null) - { - _logger.LogWarning("Employee {EmployeeId} attempted to access bucket {BucketId} without the necessary permissions.", LoggedInEmployee.Id, bucket.Id); - return ApiResponse.ErrorResponse("You don't have permission to access this bucket", "You don't have permission to access this bucket", 401); - } - - bucket.Name = bucketDto.Name ?? ""; - bucket.Description = bucketDto.Description ?? ""; - - _context.DirectoryUpdateLogs.Add(new DirectoryUpdateLog - { - RefereanceId = bucketDto.Id, - UpdatedById = LoggedInEmployee.Id, - UpdateAt = DateTime.UtcNow - }); - - await _context.SaveChangesAsync(); - - AssignBucketVM bucketVM = bucket.ToAssignBucketVMFromBucket(); - List employeeBucketMappings = employeeBuckets.Where(eb => eb.BucketId == bucket.Id).ToList(); - List contactBuckets = await _context.ContactBucketMappings.Where(eb => eb.BucketId == bucket.Id).ToListAsync(); - var employeeIds = employeeBucketMappings.Select(eb => eb.EmployeeId).ToList(); - bucketVM.EmployeeIds = employeeIds; - bucketVM.NumberOfContacts = contactBuckets.Count; - - _logger.LogInfo("Employee Id {LoggedInEmployeeId} Updated new bucket {BucketId}", LoggedInEmployee.Id, bucket.Id); - return ApiResponse.SuccessResponse(bucketVM, "Bucket update successFully", 200); - } - _logger.LogWarning("Employee with ID {LoggedInEmployeeId} sended empty payload", LoggedInEmployee.Id); - return ApiResponse.ErrorResponse("User Send empty Payload", "User Send empty Payload", 400); - } - public async Task> AssignBucket(Guid bucketId, List assignBuckets) - { - Guid tenantId = _userHelper.GetTenantId(); - var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); - if (assignBuckets != null && bucketId != Guid.Empty) - { - var assignedRoleIds = await _context.EmployeeRoleMappings.Where(r => r.EmployeeId == LoggedInEmployee.Id).Select(r => r.RoleId).ToListAsync(); - var permissionIds = await _context.RolePermissionMappings.Where(rp => assignedRoleIds.Contains(rp.ApplicationRoleId)).Select(rp => rp.FeaturePermissionId).Distinct().ToListAsync(); - - Bucket? bucket = await _context.Buckets.Include(b => b.CreatedBy).FirstOrDefaultAsync(b => b.Id == bucketId && b.TenantId == tenantId); - - if (bucket == null) - { - _logger.LogWarning("Employee ID {LoggedInEmployeeId} attempted to update a bucket but not found in database.", LoggedInEmployee.Id); - return ApiResponse.ErrorResponse("Bucket not found", "Bucket not found", 404); - } - var employeeBuckets = await _context.EmployeeBucketMappings.Where(eb => eb.BucketId == bucketId).ToListAsync(); - var bucketIds = employeeBuckets.Where(eb => eb.EmployeeId == LoggedInEmployee.Id).Select(eb => eb.BucketId).ToList(); - var employeeBucketIds = employeeBuckets.Select(eb => eb.EmployeeId).ToList(); - Bucket? accessableBucket = null; - if (permissionIds.Contains(PermissionsMaster.DirectoryAdmin)) - { - accessableBucket = bucket; - } - else if (permissionIds.Contains(PermissionsMaster.DirectoryAdmin) && bucketIds.Contains(bucketId)) - { - accessableBucket = bucket; - } - else if (permissionIds.Contains(PermissionsMaster.DirectoryUser)) - { - if (bucket.CreatedByID == LoggedInEmployee.Id) - { - accessableBucket = bucket; - } - } - if (accessableBucket == null) - { - _logger.LogWarning("Employee {EmployeeId} attempted to access bucket {BucketId} without the necessary permissions.", LoggedInEmployee.Id, bucket.Id); - return ApiResponse.ErrorResponse("You don't have permission to access this bucket", "You don't have permission to access this bucket", 401); - } - var employeeIds = await _context.Employees.Where(e => e.TenantId == tenantId && e.IsActive).Select(e => e.Id).ToListAsync(); - int assignedEmployee = 0; - int removededEmployee = 0; - foreach (var assignBucket in assignBuckets) - { - if (employeeIds.Contains(assignBucket.EmployeeId)) - { - if (assignBucket.IsActive && !employeeBucketIds.Contains(assignBucket.EmployeeId)) - { - EmployeeBucketMapping employeeBucketMapping = new EmployeeBucketMapping - { - EmployeeId = assignBucket.EmployeeId, - BucketId = bucketId - }; - _context.EmployeeBucketMappings.Add(employeeBucketMapping); - assignedEmployee += 1; - } - else if (!assignBucket.IsActive) - { - EmployeeBucketMapping? employeeBucketMapping = employeeBuckets.FirstOrDefault(eb => eb.BucketId == bucketId && eb.EmployeeId == assignBucket.EmployeeId); - if (employeeBucketMapping != null) - { - _context.EmployeeBucketMappings.Remove(employeeBucketMapping); - removededEmployee += 1; - } - } - } - } - - _context.DirectoryUpdateLogs.Add(new DirectoryUpdateLog - { - RefereanceId = bucketId, - UpdatedById = LoggedInEmployee.Id, - UpdateAt = DateTime.UtcNow - }); - - await _context.SaveChangesAsync(); - - AssignBucketVM bucketVM = bucket.ToAssignBucketVMFromBucket(); - List employeeBucketMappings = await _context.EmployeeBucketMappings.Where(eb => eb.BucketId == bucket.Id).ToListAsync(); - List contactBuckets = await _context.ContactBucketMappings.Where(eb => eb.BucketId == bucket.Id).ToListAsync(); - employeeIds = employeeBucketMappings.Select(eb => eb.EmployeeId).ToList(); - bucketVM.EmployeeIds = employeeIds; - bucketVM.NumberOfContacts = contactBuckets.Count; - - if (assignedEmployee > 0) - { - _logger.LogInfo("Employee {EmployeeId} assigned bucket {BucketId} to {conut} number of employees", LoggedInEmployee.Id, bucketId, assignedEmployee); - } - if (removededEmployee > 0) - { - _logger.LogWarning("Employee {EmployeeId} removed {conut} number of employees from bucket {BucketId}", LoggedInEmployee.Id, removededEmployee, bucketId); - } - return ApiResponse.SuccessResponse(bucketVM, "Details updated successfully", 200); - } - _logger.LogWarning("Employee with ID {LoggedInEmployeeId} sended empty payload", LoggedInEmployee.Id); - return ApiResponse.ErrorResponse("User Send empty Payload", "User Send empty Payload", 400); - } - public async Task> DeleteBucket(Guid id) - { - Guid tenantId = _userHelper.GetTenantId(); - var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); - - Bucket? bucket = await _context.Buckets.FirstOrDefaultAsync(n => n.Id == id && n.TenantId == tenantId); - - if (bucket != null) - { - List? employeeBuckets = await _context.EmployeeBucketMappings.Where(eb => eb.BucketId == id).ToListAsync(); - List? contactBuckets = await _context.ContactBucketMappings.Where(eb => eb.BucketId == id).ToListAsync(); - - if (contactBuckets.Any()) - { - _logger.LogInfo("Employee {EmployeeId} attempted to deleted bucket {BucketId},but bucket have contacts in it.", LoggedInEmployee.Id, id); - return ApiResponse.ErrorResponse("This bucket can not be deleted", "This bucket can not be deleted", 400); - } - - var assignedRoleIds = await _context.EmployeeRoleMappings.Where(r => r.EmployeeId == LoggedInEmployee.Id).Select(r => r.RoleId).ToListAsync(); - var permissionIds = await _context.RolePermissionMappings.Where(rp => assignedRoleIds.Contains(rp.ApplicationRoleId)).Select(rp => rp.FeaturePermissionId).Distinct().ToListAsync(); - var bucketIds = employeeBuckets.Where(eb => eb.EmployeeId == LoggedInEmployee.Id).Select(eb => eb.BucketId).ToList(); - - Bucket? accessableBucket = null; - if (permissionIds.Contains(PermissionsMaster.DirectoryAdmin)) - { - accessableBucket = bucket; - } - else if (permissionIds.Contains(PermissionsMaster.DirectoryAdmin) && bucketIds.Contains(id)) - { - accessableBucket = bucket; - } - else if (permissionIds.Contains(PermissionsMaster.DirectoryUser)) - { - if (bucket.CreatedByID == LoggedInEmployee.Id) - { - accessableBucket = bucket; - } - } - if (accessableBucket == null) - { - _logger.LogWarning("Employee {EmployeeId} attempted to access bucket {BucketId} without the necessary permissions.", LoggedInEmployee.Id, bucket.Id); - return ApiResponse.ErrorResponse("You don't have permission to access this bucket", "You don't have permission to access this bucket", 401); - } - - _context.EmployeeBucketMappings.RemoveRange(employeeBuckets); - _context.Buckets.Remove(bucket); - _context.DirectoryUpdateLogs.Add(new DirectoryUpdateLog - { - RefereanceId = id, - UpdatedById = LoggedInEmployee.Id, - UpdateAt = DateTime.UtcNow - }); - await _context.SaveChangesAsync(); - _logger.LogInfo("Employee {EmployeeId} deleted bucket {BucketId} and related entries", LoggedInEmployee.Id, id); - return ApiResponse.SuccessResponse(new { }, "Bucket deleted successfully", 200); - } - - _logger.LogWarning("Employee {EmployeeId} tries to delete bucket {BucketId} but not found in database", LoggedInEmployee.Id, id); - return ApiResponse.SuccessResponse(new { }, "Bucket deleted successfully", 200); - } - - // -------------------------------- Helper -------------------------------- - - private bool Compare(string sentence, string search) - { - sentence = sentence.Trim().ToLower(); - search = search.Trim().ToLower(); - - // Check for exact substring - bool result = sentence.IndexOf(search, StringComparison.OrdinalIgnoreCase) >= 0; - return result; - } - } -} \ No newline at end of file diff --git a/Marco.Pms.Services/Program.cs b/Marco.Pms.Services/Program.cs index 0d9a3ef..71b4e28 100644 --- a/Marco.Pms.Services/Program.cs +++ b/Marco.Pms.Services/Program.cs @@ -186,7 +186,6 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); -builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); diff --git a/Marco.Pms.Services/Service/DirectoryService.cs b/Marco.Pms.Services/Service/DirectoryService.cs index 83b4079..5fa811f 100644 --- a/Marco.Pms.Services/Service/DirectoryService.cs +++ b/Marco.Pms.Services/Service/DirectoryService.cs @@ -819,6 +819,106 @@ namespace Marco.Pms.Services.Service } } + /// + /// Fetches filter options (Buckets and Contact Categories) based on user permissions + /// for a given tenant. + /// + /// The tenant ID. + /// The employee making the request. + /// ApiResponse with Buckets and Contact Categories. + public async Task> GetContactFilterObjectAsync(Guid tenantId, Employee loggedInEmployee) + { + try + { + _logger.LogInfo("Started fetching contact filters for TenantId: {TenantId}, EmployeeId: {EmployeeId}", + tenantId, loggedInEmployee.Id); + + // Step 1: Determine accessible bucket IDs based on permissions + var (hasAdminPermission, hasManagerPermission, hasUserPermission) = await CheckPermissionsAsync(loggedInEmployee.Id); + List? accessibleBucketIds = null; + + if (hasAdminPermission) + { + // Admin → Has access to all buckets in the tenant + accessibleBucketIds = await _context.Buckets + .Where(b => b.TenantId == tenantId) + .Select(b => b.Id) + .ToListAsync(); + + _logger.LogDebug("Admin access granted. Fetched {Count} tenant buckets.", accessibleBucketIds.Count); + } + else if (hasManagerPermission || hasUserPermission) + { + // Manager/User → Only mapped buckets + accessibleBucketIds = await _context.EmployeeBucketMappings + .Where(eb => eb.EmployeeId == loggedInEmployee.Id) + .Select(eb => eb.BucketId) + .ToListAsync(); + + _logger.LogDebug("Manager/User access granted. Fetched {Count} mapped buckets for EmployeeId: {EmployeeId}", + accessibleBucketIds.Count, loggedInEmployee.Id); + } + else + { + _logger.LogWarning("No permissions found for EmployeeId: {EmployeeId}. Returning empty bucket list.", loggedInEmployee.Id); + } + + // Step 2: Fetch available buckets (accessible OR personally created by the employee) + var buckets = await _context.Buckets + .Where(b => + (accessibleBucketIds != null && accessibleBucketIds.Contains(b.Id) && b.TenantId == tenantId) + || b.CreatedByID == loggedInEmployee.Id) + .Select(b => new + { + Id = b.Id, + Name = b.Name + }) + .OrderBy(b => b.Name) + .Distinct() // Ensures no duplicates (LINQ to Entities distinct works with anonymous types) + .ToListAsync(); + + accessibleBucketIds = buckets.Select(b => b.Id).ToList(); + + _logger.LogInfo("Fetched {Count} buckets for EmployeeId: {EmployeeId}", buckets.Count, loggedInEmployee.Id); + + // Step 3: Fetch contact categories mapped to the retrieved buckets + var contactCategories = await _context.ContactBucketMappings + .AsNoTracking() // Optimized since we are reading only + .Include(cb => cb.Contact) + .ThenInclude(c => c!.ContactCategory) + .Where(cb => + accessibleBucketIds.Contains(cb.BucketId) && + cb.Contact != null && + cb.Contact!.ContactCategory != null) + .Select(cb => new + { + Id = cb.Contact!.ContactCategory!.Id, + Name = cb.Contact.ContactCategory.Name + }) + .OrderBy(cc => cc.Name) + .Distinct() + .ToListAsync(); + + _logger.LogInfo("{Count} contact categories fetched for EmployeeId: {EmployeeId}", contactCategories.Count, loggedInEmployee.Id); + + // Step 4: Prepare response payload + var response = new + { + Buckets = buckets, + ContactCategories = contactCategories + }; + + _logger.LogInfo("Successfully returning filters for TenantId: {TenantId}, EmployeeId: {EmployeeId}", tenantId, loggedInEmployee.Id); + return ApiResponse.SuccessResponse(response, "Filters for contact fetched successfully", 200); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error while fetching contact filters for TenantId: {TenantId}, EmployeeId: {EmployeeId}", tenantId, loggedInEmployee.Id); + return ApiResponse.ErrorResponse("An error occurred while fetching filters", 500); + } + } + + #endregion #region =================================================================== Contact Post APIs =================================================================== @@ -1661,6 +1761,125 @@ namespace Marco.Pms.Services.Service StatusCodes.Status200OK); } + /// + /// Fetches filter objects (CreatedBy employees and Organizations) for Contact Notes + /// accessible by the logged-in employee, based on permissions. + /// + /// The tenant ID. + /// The employee requesting filters. + /// ApiResponse containing CreatedBy and Organizations filter options. + public async Task> GetContactNotesFilterObjectAsync(Guid tenantId, Employee loggedInEmployee) + { + try + { + _logger.LogInfo("Started fetching Contact Notes filters for TenantId: {TenantId}, EmployeeId: {EmployeeId}", + tenantId, loggedInEmployee.Id); + + // Step 1: Fetch accessible bucket IDs based on permissions + var (hasAdminPermission, hasManagerPermission, hasUserPermission) = await CheckPermissionsAsync(loggedInEmployee.Id); + List? accessibleBucketIds = null; + + if (hasAdminPermission) + { + // Admin → Access to all buckets in the tenant + accessibleBucketIds = await _context.Buckets + .Where(b => b.TenantId == tenantId) + .Select(b => b.Id) + .ToListAsync(); + + _logger.LogDebug("Admin access granted. Found {Count} buckets.", accessibleBucketIds.Count); + } + else if (hasManagerPermission || hasUserPermission) + { + // Manager/User → Access to mapped buckets only + accessibleBucketIds = await _context.EmployeeBucketMappings + .Where(eb => eb.EmployeeId == loggedInEmployee.Id) + .Select(eb => eb.BucketId) + .ToListAsync(); + + _logger.LogDebug("Manager/User access granted. Found {Count} mapped buckets for EmployeeId: {EmployeeId}.", + accessibleBucketIds.Count, loggedInEmployee.Id); + } + else + { + _logger.LogWarning("No permissions found for EmployeeId: {EmployeeId}. Returning empty filters.", loggedInEmployee.Id); + } + + // Step 2: Fetch Contact IDs from ContactBucketMappings + var contactIds = await _context.ContactBucketMappings + .Where(cb => accessibleBucketIds != null && accessibleBucketIds.Contains(cb.BucketId)) + .Select(cb => cb.ContactId) + .Distinct() // ensures no duplicate contact IDs + .ToListAsync(); + + _logger.LogInfo("Fetched {Count} contact Ids from accessible buckets.", contactIds.Count); + + // Step 3: Fetch Contacts related to Contact Notes for those contactIds + var contacts = await _context.ContactNotes + .AsNoTracking() // no need to track since it’s for read-only filters + .Include(cn => cn.Contact) + .ThenInclude(c => c!.CreatedBy) + .Where(cn => + contactIds.Contains(cn.ContactId) && + cn.Contact != null && + cn.Contact.CreatedBy != null && + cn.TenantId == tenantId) + .Select(cn => cn.Contact!) + .Distinct() // avoid duplicate contacts from multiple notes + .ToListAsync(); + + _logger.LogInfo("Fetched {Count} unique contacts with notes.", contacts.Count); + + // Step 4: Build organization filters + var organizations = contacts + .Where(c => !string.IsNullOrEmpty(c.Organization)) // filter out null/empty orgs + .Select(c => new + { + Id = c.Organization, // Using organization string as unique identifier + Name = c.Organization + }) + .Distinct() + .OrderBy(o => o.Name) + .ToList(); + + _logger.LogInfo("Extracted {Count} unique organizations from contacts.", organizations.Count); + + // Step 5: Build CreatedBy filters (employees who created the contacts) + var createdBy = contacts + .Select(c => new + { + Id = c.CreatedBy!.Id, + Name = $"{c.CreatedBy.FirstName} {c.CreatedBy.LastName}".Trim() + }) + .Distinct() + .OrderBy(e => e.Name) + .ToList(); + + _logger.LogInfo("Extracted {Count} unique CreatedBy employees from contacts.", createdBy.Count); + + // Step 6: Build response + var response = new + { + CreatedBy = createdBy, + Organizations = organizations + }; + + _logger.LogInfo("Successfully returning Contact Notes filters for TenantId: {TenantId}, EmployeeId: {EmployeeId}", + tenantId, loggedInEmployee.Id); + + return ApiResponse.SuccessResponse(response, "Filters for contact notes fetched successfully", 200); + } + catch (Exception ex) + { + _logger.LogError(ex, + "Error occurred while fetching Contact Notes filters for TenantId: {TenantId}, EmployeeId: {EmployeeId}", + tenantId, loggedInEmployee.Id); + + return ApiResponse.ErrorResponse("An error occurred while fetching filters", 500); + } + } + + /// /// Creates a note for a given contact under the specified tenant. /// Ensures that the contact exists and belongs to the tenant before adding the note. @@ -1915,7 +2134,6 @@ namespace Marco.Pms.Services.Service } } - #endregion #region =================================================================== Bucket APIs =================================================================== diff --git a/Marco.Pms.Services/Service/ServiceInterfaces/IDirectoryService.cs b/Marco.Pms.Services/Service/ServiceInterfaces/IDirectoryService.cs index c7d7d45..49db0c7 100644 --- a/Marco.Pms.Services/Service/ServiceInterfaces/IDirectoryService.cs +++ b/Marco.Pms.Services/Service/ServiceInterfaces/IDirectoryService.cs @@ -12,6 +12,7 @@ namespace Marco.Pms.Services.Service.ServiceInterfaces Task> GetContactProfileAsync(Guid id, Guid tenantId, Employee loggedInEmployee); Task> GetOrganizationListAsync(Guid tenantId, Employee loggedInEmployee); Task> GetDesignationListAsync(Guid tenantId, Employee loggedInEmployee); + Task> GetContactFilterObjectAsync(Guid tenantId, Employee loggedInEmployee); Task> CreateContactAsync(CreateContactDto createContact, Guid tenantId, Employee loggedInEmployee); Task> UpdateContactAsync(Guid id, UpdateContactDto updateContact, Guid tenantId, Employee loggedInEmployee); Task> DeleteContactAsync(Guid id, bool active, Guid tenantId, Employee loggedInEmployee); @@ -22,6 +23,7 @@ namespace Marco.Pms.Services.Service.ServiceInterfaces Task> GetListOFAllNotesAsync(Guid? projectId, int pageSize, int pageNumber, Guid tenantId, Employee loggedInEmployee); Task> GetNoteListByContactIdAsync(Guid id, bool active, Guid tenantId, Employee loggedInEmployee); + Task> GetContactNotesFilterObjectAsync(Guid tenantId, Employee loggedInEmployee); Task> CreateContactNoteAsync(CreateContactNoteDto noteDto, Guid tenantId, Employee loggedInEmployee); Task> UpdateContactNoteAsync(Guid id, UpdateContactNoteDto noteDto, Guid tenantId, Employee loggedInEmployee); Task> DeleteContactNoteAsync(Guid id, bool active, Guid tenantId, Employee loggedInEmployee);