1349 lines
		
	
	
		
			77 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			1349 lines
		
	
	
		
			77 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using Marco.Pms.DataAccess.Data;
 | 
						|
using Marco.Pms.Model.Directory;
 | 
						|
using Marco.Pms.Model.Dtos.Directory;
 | 
						|
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 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 Guid directoryAdmin;
 | 
						|
        private readonly Guid directoryManager;
 | 
						|
        private readonly Guid directoryUser;
 | 
						|
 | 
						|
        public DirectoryHelper(ApplicationDbContext context, ILoggingService logger, UserHelper userHelper)
 | 
						|
        {
 | 
						|
            _context = context;
 | 
						|
            _logger = logger;
 | 
						|
            _userHelper = userHelper;
 | 
						|
            directoryAdmin = Guid.Parse("4286a13b-bb40-4879-8c6d-18e9e393beda");
 | 
						|
            directoryManager = Guid.Parse("62668630-13ce-4f52-a0f0-db38af2230c5");
 | 
						|
            directoryUser = Guid.Parse("0f919170-92d4-4337-abd3-49b66fc871bb");
 | 
						|
        }
 | 
						|
 | 
						|
 | 
						|
 | 
						|
        public async Task<ApiResponse<object>> 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<EmployeeBucketMapping>? employeeBuckets = await _context.EmployeeBucketMappings.Where(eb => eb.EmployeeId == LoggedInEmployee.Id).ToListAsync();
 | 
						|
            List<Guid> bucketIds = employeeBuckets.Select(c => c.BucketId).ToList();
 | 
						|
            if (permissionIds.Contains(directoryAdmin))
 | 
						|
            {
 | 
						|
                var buckets = await _context.Buckets.Where(b => b.TenantId == tenantId).ToListAsync();
 | 
						|
                bucketIds = buckets.Select(b => b.Id).ToList();
 | 
						|
            }
 | 
						|
            else if (permissionIds.Contains(directoryManager) || permissionIds.Contains(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.LogError("Employee {EmployeeId} attemped to access a contacts, but do not have permission", LoggedInEmployee.Id);
 | 
						|
                return ApiResponse<object>.ErrorResponse("You don't have permission", "You don't have permission", 401);
 | 
						|
            }
 | 
						|
 | 
						|
            List<Guid> filterbucketIds = bucketIds;
 | 
						|
            if (filterDto != null && filterDto.BucketIds != null && filterDto.BucketIds.Count > 0)
 | 
						|
            {
 | 
						|
                filterbucketIds = filterDto.BucketIds;
 | 
						|
            }
 | 
						|
            List<ContactBucketMapping>? contactBuckets = await _context.ContactBucketMappings.Where(cb => bucketIds.Contains(cb.BucketId)).ToListAsync();
 | 
						|
            List<Guid> contactIds = contactBuckets.Where(b => filterbucketIds.Contains(b.BucketId)).Select(cb => cb.ContactId).ToList();
 | 
						|
            List<Contact> contacts = new List<Contact>();
 | 
						|
 | 
						|
            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<Guid> 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<Guid> filteredContactIds = new List<Guid>();
 | 
						|
                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<ContactVM> list = new List<ContactVM>();
 | 
						|
 | 
						|
            foreach (var contact in contacts)
 | 
						|
            {
 | 
						|
 | 
						|
                ContactVM contactVM = new ContactVM();
 | 
						|
                List<ContactEmailVM> contactEmailVms = new List<ContactEmailVM>();
 | 
						|
                List<ContactPhoneVM> contactPhoneVms = new List<ContactPhoneVM>();
 | 
						|
 | 
						|
                List<ContactTagVM> conatctTagVms = new List<ContactTagVM>();
 | 
						|
                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<object>.SuccessResponse(list, System.String.Format("{0} contacts fetched successfully", list.Count), 200);
 | 
						|
 | 
						|
        }
 | 
						|
        public async Task<ApiResponse<object>> 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<object>.ErrorResponse("Bucket not found", "Bucket not found", 404);
 | 
						|
                }
 | 
						|
                List<EmployeeBucketMapping>? 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(directoryAdmin))
 | 
						|
                {
 | 
						|
                    employeeBucket = employeeBuckets.FirstOrDefault();
 | 
						|
                }
 | 
						|
                else if (permissionIds.Contains(directoryManager) || permissionIds.Contains(directoryUser))
 | 
						|
                {
 | 
						|
                    employeeBucket = employeeBuckets.FirstOrDefault(eb => eb.EmployeeId == LoggedInEmployee.Id);
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    _logger.LogError("Employee {EmployeeId} attemped to access a contacts with in bucket {BucketId}, but do not have permission", LoggedInEmployee.Id, id);
 | 
						|
                    return ApiResponse<object>.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<object>.ErrorResponse("You do not have access to this bucket.", "You do not have access to this bucket.", 401);
 | 
						|
                }
 | 
						|
 | 
						|
                List<ContactBucketMapping> contactBucket = await _context.ContactBucketMappings.Where(cb => cb.BucketId == id).ToListAsync() ?? new List<ContactBucketMapping>();
 | 
						|
                List<ContactVM> contactVMs = new List<ContactVM>();
 | 
						|
                if (contactBucket.Count > 0)
 | 
						|
                {
 | 
						|
                    var contactIds = contactBucket.Select(cb => cb.ContactId).ToList();
 | 
						|
                    List<Contact> contacts = await _context.Contacts.Include(c => c.ContactCategory).Where(c => contactIds.Contains(c.Id) && c.IsActive).ToListAsync();
 | 
						|
                    List<ContactPhone> phones = await _context.ContactsPhones.Where(p => contactIds.Contains(p.ContactId)).ToListAsync();
 | 
						|
                    List<ContactEmail> emails = await _context.ContactsEmails.Where(e => contactIds.Contains(e.ContactId)).ToListAsync();
 | 
						|
 | 
						|
                    List<ContactTagMapping>? tags = await _context.ContactTagMappings.Where(ct => contactIds.Contains(ct.ContactId)).ToListAsync();
 | 
						|
                    List<ContactProjectMapping>? contactProjects = await _context.ContactProjectMappings.Where(cp => contactIds.Contains(cp.ContactId)).ToListAsync();
 | 
						|
                    List<ContactBucketMapping>? contactBuckets = await _context.ContactBucketMappings.Where(cp => contactIds.Contains(cp.ContactId)).ToListAsync();
 | 
						|
 | 
						|
                    List<Guid> tagIds = new List<Guid>();
 | 
						|
                    List<ContactTagMaster> tagMasters = new List<ContactTagMaster>();
 | 
						|
                    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<ContactEmailVM>? emailVMs = new List<ContactEmailVM>();
 | 
						|
                            List<ContactPhoneVM>? phoneVMs = new List<ContactPhoneVM>();
 | 
						|
                            List<ContactTagVM>? tagVMs = new List<ContactTagVM>();
 | 
						|
 | 
						|
                            List<ContactPhone> contactPhones = phones.Where(p => p.ContactId == contact.Id).ToList();
 | 
						|
                            List<ContactEmail> contactEmails = emails.Where(e => e.ContactId == contact.Id).ToList();
 | 
						|
 | 
						|
                            List<ContactTagMapping>? contactTags = tags.Where(t => t.ContactId == contact.Id).ToList();
 | 
						|
                            List<ContactProjectMapping>? projectMappings = contactProjects.Where(cp => cp.ContactId == contact.Id).ToList();
 | 
						|
                            List<ContactBucketMapping>? 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<object>.SuccessResponse(contactVMs, $"{contactVMs.Count} contacts fetched successfully", 200);
 | 
						|
            }
 | 
						|
            _logger.LogInfo("Employee ID {EmployeeId} sent an empty Bucket id", LoggedInEmployee.Id);
 | 
						|
            return ApiResponse<object>.ErrorResponse("Bucket ID is empty", "Bucket ID is empty", 400);
 | 
						|
        }
 | 
						|
        public async Task<ApiResponse<object>> CreateContact(CreateContactDto createContact)
 | 
						|
        {
 | 
						|
            Guid tenantId = _userHelper.GetTenantId();
 | 
						|
            var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
 | 
						|
            if (createContact != null)
 | 
						|
            {
 | 
						|
                List<ContactPhone> phones = new List<ContactPhone>();
 | 
						|
                List<ContactEmail> emails = new List<ContactEmail>();
 | 
						|
                List<ContactBucketMapping> contactBucketMappings = new List<ContactBucketMapping>();
 | 
						|
                List<ContactTagMapping> contactTagMappings = new List<ContactTagMapping>();
 | 
						|
 | 
						|
                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<ContactProjectMapping> projectMappings = new List<ContactProjectMapping>();
 | 
						|
                    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<ContactPhoneVM> phoneVMs = new List<ContactPhoneVM>();
 | 
						|
 | 
						|
                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<ContactProjectMapping> contactProjects = await _context.ContactProjectMappings.Where(cp => cp.ContactId == contact.Id).ToListAsync();
 | 
						|
                List<ContactBucketMapping> bucketMappings = await _context.ContactBucketMappings.Where(cb => cb.ContactId == contact.Id).ToListAsync();
 | 
						|
                foreach (var phone in phones)
 | 
						|
                {
 | 
						|
                    ContactPhoneVM phoneVM = phone.ToContactPhoneVMFromContactPhone();
 | 
						|
                    phoneVMs.Add(phoneVM);
 | 
						|
                }
 | 
						|
                List<ContactEmailVM> emailVMs = new List<ContactEmailVM>();
 | 
						|
                foreach (var email in emails)
 | 
						|
                {
 | 
						|
                    ContactEmailVM emailVM = email.ToContactEmailVMFromContactEmail();
 | 
						|
                    emailVMs.Add(emailVM);
 | 
						|
                }
 | 
						|
                List<ContactTagVM> tagVMs = new List<ContactTagVM>();
 | 
						|
                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<object>.SuccessResponse(contactVM, "Contact Created Successfully", 200);
 | 
						|
            }
 | 
						|
            _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>> 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<object>.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<object>.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<EmployeeBucketMapping>? employeeBuckets = await _context.EmployeeBucketMappings.Where(eb => eb.EmployeeId == LoggedInEmployee.Id).ToListAsync();
 | 
						|
                List<Guid> bucketIds = employeeBuckets.Select(c => c.BucketId).ToList();
 | 
						|
                if (permissionIds.Contains(directoryAdmin))
 | 
						|
                {
 | 
						|
                    var buckets = await _context.Buckets.Where(b => b.TenantId == tenantId).ToListAsync();
 | 
						|
                    bucketIds = buckets.Select(b => b.Id).ToList();
 | 
						|
                }
 | 
						|
                else if (permissionIds.Contains(directoryManager) || permissionIds.Contains(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.LogError("Employee {EmployeeId} attemped to update a contact, but do not have permission", LoggedInEmployee.Id);
 | 
						|
                    return ApiResponse<object>.ErrorResponse("You don't have permission", "You don't have permission", 401);
 | 
						|
                }
 | 
						|
 | 
						|
                List<ContactBucketMapping> 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);
 | 
						|
                _context.Contacts.Update(newContact);
 | 
						|
                await _context.SaveChangesAsync();
 | 
						|
 | 
						|
                List<ContactPhone> phones = await _context.ContactsPhones.AsNoTracking().Where(p => p.ContactId == contact.Id).ToListAsync();
 | 
						|
                var phoneIds = phones.Select(p => p.Id).ToList();
 | 
						|
                List<ContactEmail> emails = await _context.ContactsEmails.AsNoTracking().Where(p => p.ContactId == contact.Id).ToListAsync();
 | 
						|
                var emailIds = emails.Select(p => p.Id).ToList();
 | 
						|
 | 
						|
 | 
						|
 | 
						|
                List<ContactTagMapping> contactTags = await _context.ContactTagMappings.AsNoTracking().Where(m => m.ContactId == contact.Id).ToListAsync();
 | 
						|
                var tagIds = contactTags.Select(t => t.ContactTagId).Distinct().ToList();
 | 
						|
 | 
						|
 | 
						|
                List<ContactProjectMapping> contactProjects = await _context.ContactProjectMappings.AsNoTracking().Where(m => m.ContactId == contact.Id).ToListAsync();
 | 
						|
                var projectIds = contactProjects.Select(t => t.ProjectId).Distinct().ToList();
 | 
						|
 | 
						|
                List<ContactTagMaster> tags = await _context.ContactTagMasters.Where(t => tagIds.Contains(t.Id)).ToListAsync();
 | 
						|
                List<ContactTagMaster> 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<ContactPhoneVM> phoneVMs = new List<ContactPhoneVM>();
 | 
						|
                foreach (var phone in phones)
 | 
						|
                {
 | 
						|
                    ContactPhoneVM phoneVM = phone.ToContactPhoneVMFromContactPhone();
 | 
						|
                    phoneVMs.Add(phoneVM);
 | 
						|
                }
 | 
						|
                List<ContactEmailVM> emailVMs = new List<ContactEmailVM>();
 | 
						|
                foreach (var email in emails)
 | 
						|
                {
 | 
						|
                    ContactEmailVM emailVM = email.ToContactEmailVMFromContactEmail();
 | 
						|
                    emailVMs.Add(emailVM);
 | 
						|
                }
 | 
						|
                List<ContactTagVM> tagVMs = new List<ContactTagVM>();
 | 
						|
                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<object>.SuccessResponse(contactVM, "Contact Updated Successfully", 200);
 | 
						|
            }
 | 
						|
            _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>> GetContactProfile(Guid id)
 | 
						|
        {
 | 
						|
            Guid tenantId = _userHelper.GetTenantId();
 | 
						|
            var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
 | 
						|
            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<object>.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<ContactPhone>? phones = await _context.ContactsPhones.Where(p => p.ContactId == contact.Id).ToListAsync();
 | 
						|
                if (phones.Any())
 | 
						|
                {
 | 
						|
                    List<ContactPhoneVM>? phoneVMs = new List<ContactPhoneVM>();
 | 
						|
                    foreach (var phone in phones)
 | 
						|
                    {
 | 
						|
                        ContactPhoneVM phoneVM = phone.ToContactPhoneVMFromContactPhone();
 | 
						|
                        phoneVMs.Add(phoneVM);
 | 
						|
                    }
 | 
						|
                    contactVM.ContactPhones = phoneVMs;
 | 
						|
                }
 | 
						|
 | 
						|
                List<ContactEmail>? emails = await _context.ContactsEmails.Where(e => e.ContactId == contact.Id).ToListAsync();
 | 
						|
                if (emails.Any())
 | 
						|
                {
 | 
						|
                    List<ContactEmailVM>? emailVMs = new List<ContactEmailVM>();
 | 
						|
                    foreach (var email in emails)
 | 
						|
                    {
 | 
						|
                        ContactEmailVM emailVM = email.ToContactEmailVMFromContactEmail();
 | 
						|
                        emailVMs.Add(emailVM);
 | 
						|
                    }
 | 
						|
                    contactVM.ContactEmails = emailVMs;
 | 
						|
                }
 | 
						|
 | 
						|
                List<ContactProjectMapping>? contactProjects = await _context.ContactProjectMappings.Where(cp => cp.ContactId == contact.Id).ToListAsync();
 | 
						|
                if (contactProjects.Any())
 | 
						|
                {
 | 
						|
                    List<Guid> projectIds = contactProjects.Select(cp => cp.ProjectId).ToList();
 | 
						|
                    List<Project>? projects = await _context.Projects.Where(p => projectIds.Contains(p.Id) && p.TenantId == tenantId).ToListAsync();
 | 
						|
                    List<BasicProjectVM>? projectVMs = new List<BasicProjectVM>();
 | 
						|
                    foreach (var project in projects)
 | 
						|
                    {
 | 
						|
                        BasicProjectVM projectVM = new BasicProjectVM
 | 
						|
                        {
 | 
						|
                            Id = project.Id,
 | 
						|
                            Name = project.Name
 | 
						|
                        };
 | 
						|
                        projectVMs.Add(projectVM);
 | 
						|
                    }
 | 
						|
                    contactVM.Projects = projectVMs;
 | 
						|
                }
 | 
						|
                List<ContactBucketMapping>? contactBuckets = await _context.ContactBucketMappings.Where(cb => cb.ContactId == contact.Id).ToListAsync();
 | 
						|
                List<EmployeeBucketMapping>? employeeBuckets = await _context.EmployeeBucketMappings.Where(eb => eb.EmployeeId == LoggedInEmployee.Id).ToListAsync();
 | 
						|
                if (contactBuckets.Any() && employeeBuckets.Any())
 | 
						|
                {
 | 
						|
                    List<Guid> contactBucketIds = contactBuckets.Select(cb => cb.BucketId).ToList();
 | 
						|
                    List<Guid> employeeBucketIds = employeeBuckets.Select(eb => eb.BucketId).ToList();
 | 
						|
                    List<Bucket>? buckets = await _context.Buckets.Where(b => contactBucketIds.Contains(b.Id) && employeeBucketIds.Contains(b.Id)).ToListAsync();
 | 
						|
                    List<BucketVM>? bucketVMs = new List<BucketVM>();
 | 
						|
                    foreach (var bucket in buckets)
 | 
						|
                    {
 | 
						|
                        BucketVM bucketVM = bucket.ToBucketVMFromBucket();
 | 
						|
                        bucketVMs.Add(bucketVM);
 | 
						|
                    }
 | 
						|
                    contactVM.Buckets = bucketVMs;
 | 
						|
                }
 | 
						|
                List<ContactTagMapping>? contactTags = await _context.ContactTagMappings.Where(ct => ct.ContactId == contact.Id).ToListAsync();
 | 
						|
                if (contactTags.Any())
 | 
						|
                {
 | 
						|
                    List<Guid> tagIds = contactTags.Select(ct => ct.ContactTagId).ToList();
 | 
						|
                    List<ContactTagMaster> tagMasters = await _context.ContactTagMasters.Where(t => tagIds.Contains(t.Id)).ToListAsync();
 | 
						|
                    List<ContactTagVM> tagVMs = new List<ContactTagVM>();
 | 
						|
                    foreach (var tagMaster in tagMasters)
 | 
						|
                    {
 | 
						|
                        ContactTagVM tagVM = tagMaster.ToContactTagVMFromContactTagMaster();
 | 
						|
                        tagVMs.Add(tagVM);
 | 
						|
                    }
 | 
						|
                    contactVM.Tags = tagVMs;
 | 
						|
                }
 | 
						|
                List<ContactNote>? notes = await _context.ContactNotes.Where(n => n.ContactId == contact.Id && n.IsActive).ToListAsync();
 | 
						|
                if (notes.Any())
 | 
						|
                {
 | 
						|
                    List<Guid>? noteIds = notes.Select(n => n.Id).ToList();
 | 
						|
                    List<DirectoryUpdateLog>? noteUpdateLogs = await _context.DirectoryUpdateLogs.Include(l => l.Employee).Where(l => noteIds.Contains(l.RefereanceId)).OrderByDescending(l => l.UpdateAt).ToListAsync();
 | 
						|
                    List<ContactNoteVM>? noteVMs = new List<ContactNoteVM>();
 | 
						|
                    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<object>.SuccessResponse(contactVM, "Contact profile fetched successfully");
 | 
						|
 | 
						|
            }
 | 
						|
            _logger.LogInfo("Employee ID {EmployeeId} sent an empty contact id", LoggedInEmployee.Id);
 | 
						|
            return ApiResponse<object>.ErrorResponse("Contact ID is empty", "Contact ID is empty", 400);
 | 
						|
        }
 | 
						|
        public async Task<ApiResponse<object>> GetOrganizationList()
 | 
						|
        {
 | 
						|
            Guid tenantId = _userHelper.GetTenantId();
 | 
						|
            var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
 | 
						|
 | 
						|
            var organizationList = await _context.Contacts.Where(c => c.TenantId == tenantId).Select(c => c.Organization).Distinct().ToListAsync();
 | 
						|
            _logger.LogInfo("Employee {EmployeeId} fetched list of organizations in a tenant {TenantId}", LoggedInEmployee.Id, tenantId);
 | 
						|
            return ApiResponse<object>.SuccessResponse(organizationList, $"{organizationList.Count} records of organization names fetched from contacts", 200);
 | 
						|
        }
 | 
						|
        public async Task<ApiResponse<object>> DeleteContact(Guid id, bool active)
 | 
						|
        {
 | 
						|
            Guid tenantId = _userHelper.GetTenantId();
 | 
						|
            var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
 | 
						|
            if (id != Guid.Empty)
 | 
						|
            {
 | 
						|
                Contact? contact = await _context.Contacts.FirstOrDefaultAsync(c => c.Id == id && c.TenantId == tenantId);
 | 
						|
                if (contact == null)
 | 
						|
                {
 | 
						|
                    _logger.LogWarning("Employee with ID {LoggedInEmployeeId} tries to delete contact with ID {ContactId} is not found in database", LoggedInEmployee.Id);
 | 
						|
                    return ApiResponse<object>.ErrorResponse("Contact not found", "Contact not found", 404);
 | 
						|
                }
 | 
						|
                contact.IsActive = active;
 | 
						|
 | 
						|
                _context.DirectoryUpdateLogs.Add(new DirectoryUpdateLog
 | 
						|
                {
 | 
						|
                    RefereanceId = contact.Id,
 | 
						|
                    UpdatedById = LoggedInEmployee.Id,
 | 
						|
                    UpdateAt = DateTime.UtcNow
 | 
						|
                });
 | 
						|
 | 
						|
                await _context.SaveChangesAsync();
 | 
						|
                _logger.LogInfo("Contact {ContactId} has been deleted by Employee {Employee}", id, LoggedInEmployee.Id);
 | 
						|
                return ApiResponse<object>.SuccessResponse(new { }, "Contact is deleted Successfully", 200);
 | 
						|
            }
 | 
						|
            _logger.LogInfo("Employee ID {EmployeeId} sent an empty contact id", LoggedInEmployee.Id);
 | 
						|
            return ApiResponse<object>.ErrorResponse("Contact ID is empty", "Contact ID is empty", 400);
 | 
						|
        }
 | 
						|
 | 
						|
        // -------------------------------- Contact Notes  --------------------------------
 | 
						|
 | 
						|
        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.Where(n => n.ContactId == contact.Id && n.IsActive && n.TenantId == tenantId).ToListAsync();
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    notes = await _context.ContactNotes.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>();
 | 
						|
                foreach (var note in notes)
 | 
						|
                {
 | 
						|
                    ContactNoteVM noteVM = note.ToContactNoteVMFromContactNote();
 | 
						|
                    DirectoryUpdateLog? updateLog = updateLogs.Where(l => l.RefereanceId == note.Id).OrderByDescending(l => l.UpdateAt).FirstOrDefault();
 | 
						|
                    if (updateLog != null)
 | 
						|
                    {
 | 
						|
                        noteVM.UpdatedAt = updateLog.UpdateAt;
 | 
						|
                        noteVM.UpdatedBy = updateLog.Employee != null ? updateLog.Employee.ToBasicEmployeeVMFromEmployee() : null;
 | 
						|
                    }
 | 
						|
                    else
 | 
						|
                    {
 | 
						|
                        noteVM.UpdatedAt = note.CreatedAt;
 | 
						|
                        noteVM.UpdatedBy = note.Createdby != null ? note.Createdby.ToBasicEmployeeVMFromEmployee() : null;
 | 
						|
                    }
 | 
						|
                    noteVMs.Add(noteVM);
 | 
						|
 | 
						|
                }
 | 
						|
                _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)
 | 
						|
        {
 | 
						|
            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<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);
 | 
						|
                return ApiResponse<object>.ErrorResponse("Contact not found", "Contact not found", 404);
 | 
						|
            }
 | 
						|
            _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)
 | 
						|
        {
 | 
						|
            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.IsActive && c.TenantId == tenantId);
 | 
						|
                if (contact != null)
 | 
						|
                {
 | 
						|
                    ContactNote? contactNote = await _context.ContactNotes.FirstOrDefaultAsync(n => n.Id == noteDto.Id && n.ContactId == contact.Id && n.IsActive);
 | 
						|
                    if (contactNote != null)
 | 
						|
                    {
 | 
						|
                        contactNote.Note = noteDto.Note;
 | 
						|
 | 
						|
                        _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<object>.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<object>.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<object>.ErrorResponse("Contact not found", "Contact not found", 404);
 | 
						|
            }
 | 
						|
            _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>> 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;
 | 
						|
                _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<object>.SuccessResponse(new { }, "Note deleted successfully", 200);
 | 
						|
        }
 | 
						|
 | 
						|
        // -------------------------------- Bucket  --------------------------------
 | 
						|
 | 
						|
        public async Task<ApiResponse<object>> 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<EmployeeBucketMapping> employeeBuckets = await _context.EmployeeBucketMappings.Where(b => b.EmployeeId == LoggedInEmployee.Id).ToListAsync();
 | 
						|
            var bucketIds = employeeBuckets.Select(b => b.BucketId).ToList();
 | 
						|
            List<EmployeeBucketMapping> employeeBucketVM = await _context.EmployeeBucketMappings.Where(b => bucketIds.Contains(b.BucketId)).ToListAsync();
 | 
						|
            List<Bucket> bucketList = new List<Bucket>();
 | 
						|
            if (permissionIds.Contains(directoryAdmin))
 | 
						|
            {
 | 
						|
                bucketList = await _context.Buckets.Include(b => b.CreatedBy).Where(b => b.TenantId == tenantId).ToListAsync();
 | 
						|
            }
 | 
						|
            else if (permissionIds.Contains(directoryManager) || permissionIds.Contains(directoryUser))
 | 
						|
            {
 | 
						|
                bucketList = await _context.Buckets.Include(b => b.CreatedBy).Where(b => bucketIds.Contains(b.Id) || b.CreatedByID == LoggedInEmployee.Id).ToListAsync();
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                _logger.LogError("Employee {EmployeeId} attemped to access a buckets list, but do not have permission", LoggedInEmployee.Id);
 | 
						|
                return ApiResponse<object>.ErrorResponse("You don't have permission", "You don't have permission", 401);
 | 
						|
            }
 | 
						|
 | 
						|
            List<AssignBucketVM> bucketVMs = new List<AssignBucketVM>();
 | 
						|
            if (bucketList.Any())
 | 
						|
            {
 | 
						|
                bucketIds = bucketList.Select(b => b.Id).ToList();
 | 
						|
                List<ContactBucketMapping>? contactBucketMappings = await _context.ContactBucketMappings.Where(cb => bucketIds.Contains(cb.BucketId)).ToListAsync();
 | 
						|
                foreach (var bucket in bucketList)
 | 
						|
                {
 | 
						|
                    List<EmployeeBucketMapping> employeeBucketMappings = employeeBucketVM.Where(eb => eb.BucketId == bucket.Id).ToList();
 | 
						|
                    var emplyeeIds = employeeBucketMappings.Select(eb => eb.EmployeeId).ToList();
 | 
						|
                    List<ContactBucketMapping>? contactBuckets = contactBucketMappings.Where(cb => cb.BucketId == bucket.Id).ToList();
 | 
						|
                    AssignBucketVM bucketVM = bucket.ToAssignBucketVMFromBucket();
 | 
						|
                    bucketVM.EmployeeIds = emplyeeIds;
 | 
						|
                    bucketVM.NumberOfContacts = contactBuckets.Count;
 | 
						|
                    bucketVMs.Add(bucketVM);
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            _logger.LogInfo("{count} Buckets are fetched by Employee with ID {LoggedInEmployeeId}", bucketVMs.Count, LoggedInEmployee.Id);
 | 
						|
            return ApiResponse<object>.SuccessResponse(bucketVMs, $"{bucketVMs.Count} buckets fetched successfully", 200);
 | 
						|
        }
 | 
						|
        public async Task<ApiResponse<object>> 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(directoryUser);
 | 
						|
                if (!permissionIds.Contains(directoryAdmin) && !permissionIds.Contains(directoryManager) && !permissionIds.Contains(directoryUser))
 | 
						|
                {
 | 
						|
                    _logger.LogError("Employee {EmployeeId} attemped to create a bucket, but do not have permission", LoggedInEmployee.Id);
 | 
						|
                    return ApiResponse<object>.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<object>.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<object>.SuccessResponse(bucketVM, "Bucket Created SuccessFully", 200);
 | 
						|
            }
 | 
						|
            _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>> 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<object>.ErrorResponse("Bucket not found", "Bucket not found", 404);
 | 
						|
                }
 | 
						|
 | 
						|
                Bucket? accessableBucket = null;
 | 
						|
                if (permissionIds.Contains(directoryAdmin))
 | 
						|
                {
 | 
						|
                    accessableBucket = bucket;
 | 
						|
                }
 | 
						|
                else if (permissionIds.Contains(directoryManager) && bucketIds.Contains(id))
 | 
						|
                {
 | 
						|
                    accessableBucket = bucket;
 | 
						|
                }
 | 
						|
                else if (permissionIds.Contains(directoryUser))
 | 
						|
                {
 | 
						|
                    if (bucket.CreatedByID == LoggedInEmployee.Id)
 | 
						|
                    {
 | 
						|
                        accessableBucket = bucket;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
                if (accessableBucket == null)
 | 
						|
                {
 | 
						|
                    _logger.LogError("Employee {EmployeeId} attempted to access bucket {BucketId} without the necessary permissions.", LoggedInEmployee.Id, bucket.Id);
 | 
						|
                    return ApiResponse<object>.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<EmployeeBucketMapping> employeeBucketMappings = employeeBuckets.Where(eb => eb.BucketId == bucket.Id).ToList();
 | 
						|
                List<ContactBucketMapping> 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<object>.SuccessResponse(bucketVM, "Bucket update successFully", 200);
 | 
						|
            }
 | 
						|
            _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>> AssignBucket(Guid bucketId, List<AssignBucketDto> 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<object>.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(directoryAdmin))
 | 
						|
                {
 | 
						|
                    accessableBucket = bucket;
 | 
						|
                }
 | 
						|
                else if (permissionIds.Contains(directoryManager) && bucketIds.Contains(bucketId))
 | 
						|
                {
 | 
						|
                    accessableBucket = bucket;
 | 
						|
                }
 | 
						|
                else if (permissionIds.Contains(directoryUser))
 | 
						|
                {
 | 
						|
                    if (bucket.CreatedByID == LoggedInEmployee.Id)
 | 
						|
                    {
 | 
						|
                        accessableBucket = bucket;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
                if (accessableBucket == null)
 | 
						|
                {
 | 
						|
                    _logger.LogError("Employee {EmployeeId} attempted to access bucket {BucketId} without the necessary permissions.", LoggedInEmployee.Id, bucket.Id);
 | 
						|
                    return ApiResponse<object>.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
 | 
						|
                        {
 | 
						|
                            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<EmployeeBucketMapping> employeeBucketMappings = await _context.EmployeeBucketMappings.Where(eb => eb.BucketId == bucket.Id).ToListAsync();
 | 
						|
                List<ContactBucketMapping> 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.LogError("Employee {EmployeeId} removed {conut} number of employees from bucket {BucketId}", LoggedInEmployee.Id, removededEmployee, bucketId);
 | 
						|
                }
 | 
						|
                return ApiResponse<object>.SuccessResponse(bucketVM, "Details updated successfully", 200);
 | 
						|
            }
 | 
						|
            _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>> 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<EmployeeBucketMapping>? employeeBuckets = await _context.EmployeeBucketMappings.Where(eb => eb.BucketId == id).ToListAsync();
 | 
						|
                List<ContactBucketMapping>? 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<object>.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(directoryAdmin))
 | 
						|
                {
 | 
						|
                    accessableBucket = bucket;
 | 
						|
                }
 | 
						|
                else if (permissionIds.Contains(directoryManager) && bucketIds.Contains(id))
 | 
						|
                {
 | 
						|
                    accessableBucket = bucket;
 | 
						|
                }
 | 
						|
                else if (permissionIds.Contains(directoryUser))
 | 
						|
                {
 | 
						|
                    if (bucket.CreatedByID == LoggedInEmployee.Id)
 | 
						|
                    {
 | 
						|
                        accessableBucket = bucket;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
                if (accessableBucket == null)
 | 
						|
                {
 | 
						|
                    _logger.LogError("Employee {EmployeeId} attempted to access bucket {BucketId} without the necessary permissions.", LoggedInEmployee.Id, bucket.Id);
 | 
						|
                    return ApiResponse<object>.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<object>.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<object>.SuccessResponse(new { }, "Bucket deleted successfully", 200);
 | 
						|
        }
 | 
						|
        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;
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 |