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.Utilities; using Marco.Pms.Model.ViewModels.Directory; using Marco.Pms.Model.ViewModels.Master; 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; public DirectoryHelper(ApplicationDbContext context, ILoggingService logger, UserHelper userHelper) { _context = context; _logger = logger; _userHelper = userHelper; } public async Task> GetListOfContacts() { Guid tenantId = _userHelper.GetTenantId(); var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); var contacts = await _context.Contacts.Where(c => c.TenantId == tenantId).ToListAsync(); List contactIds = contacts.Select(c => c.Id).ToList(); var phoneNo = await _context.ContactsPhones.Where(p => contactIds.Contains(p.ContactId)).ToListAsync(); var Emails = await _context.ContactsEmails.Where(E => contactIds.Contains(E.ContactId)).ToListAsync(); var Tags = await _context.ContactTagMappings.Where(t => contactIds.Contains(t.ContactId)).ToListAsync(); List TagIds = Tags.Select(t => t.ContactTagtId).ToList(); var TagList = await _context.ContactTagMasters.Where(t => TagIds.Contains(t.Id)).ToListAsync(); List list = new List(); foreach (var contact in contacts) { ContactVM contactVM = new ContactVM(); List contactEmailVms = new List(); List contactPhoneVms = new List(); List conatctTagVms = new List(); var phones = phoneNo.Where(p => p.ContactId == contact.Id).ToList(); var emails = Emails.Where(e => e.ContactId == contact.Id).ToList(); var tagMappingss = Tags.Where(t => t.ContactId == contact.Id).ToList(); if (emails != null) { foreach (var email in emails) { ContactEmailVM emailVM = new ContactEmailVM(); emailVM = email.ToContactEmailVMFromContactEmail(); contactEmailVms.Add(emailVM); } } if (phones != null) { foreach (var phone in phones) { ContactPhoneVM phoneVM = new ContactPhoneVM(); phoneVM = phone.ToContactPhoneVMFromContactPhone(); contactPhoneVms.Add(phoneVM); } } if (tagMappingss != null) { foreach (var tagMapping in tagMappingss) { ContactTagVM tagVM = new ContactTagVM(); ; var tag = TagList.Find(t => t.Id == tagMapping.ContactTagtId); tagVM = tag != null ? tag.ToContactTagVMFromContactTagMaster() : new ContactTagVM(); conatctTagVms.Add(tagVM); } } contactVM = contact.ToContactVMFromContact(); contactVM.ContactEmails = contactEmailVms; contactVM.ContactPhones = contactPhoneVms; contactVM.Tags = conatctTagVms; list.Add(contactVM); } _logger.LogInfo("{count} contacts are fetched by Employee with ID {LoggedInEmployeeId}", list.Count, LoggedInEmployee.Id); return ApiResponse.SuccessResponse(list, System.String.Format("{0} contacts fetched successfully", list.Count), 200); } public async Task> CreateContact(CreateContactDto createContact) { Guid tenantId = _userHelper.GetTenantId(); var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); if (createContact != null) { List phones = new List(); List emails = new List(); List contactBucketMappings = new List(); List contactTagMappings = new List(); Contact? contact = createContact.ToContactFromCreateContactDto(tenantId, LoggedInEmployee.Id); _context.Contacts.Add(contact); await _context.SaveChangesAsync(); _logger.LogInfo("Contact with ID {ContactId} created by Employee with ID {LoggedInEmployeeId}", contact.Id, LoggedInEmployee.Id); var tags = await _context.ContactTagMasters.Where(t => t.TenantId == tenantId).ToListAsync(); var buckets = await _context.Buckets.Where(b => b.TenantId == tenantId).Select(b => b.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, LoggedInEmployee.Id); } if (createContact.Tags != null) { foreach (var tag in createContact.Tags) { if (tag.Id != null && tags.Where(t => t.Id == tag.Id) != null) { ContactTagMapping tagMapping = new ContactTagMapping { ContactTagtId = tag.Id != null ? tag.Id.Value : Guid.Empty, ContactId = contact.Id }; contactTagMappings.Add(tagMapping); } else if (tag.Id == null || tags.Where(t => t.Name == tag.Name) == null) { var newtag = new ContactTagMaster { Name = tag.Name }; _context.ContactTagMasters.Add(newtag); ContactTagMapping tagMapping = new ContactTagMapping { ContactTagtId = newtag.Id, ContactId = contact.Id }; contactTagMappings.Add(tagMapping); } } _context.ContactTagMappings.AddRange(contactTagMappings); } await _context.SaveChangesAsync(); ContactVM contactVM = new ContactVM(); List phoneVMs = new List(); foreach (var phone in phones) { ContactPhoneVM phoneVM = phone.ToContactPhoneVMFromContactPhone(); phoneVMs.Add(phoneVM); } List emailVMs = new List(); foreach (var email in emails) { ContactEmailVM emailVM = email.ToContactEmailVMFromContactEmail(); emailVMs.Add(emailVM); } List tagVMs = new List(); foreach (var contactTagMapping in contactTagMappings) { ContactTagVM tagVM = new ContactTagVM(); var tag = tags.Find(t => t.Id == contactTagMapping.ContactTagtId); tagVM = tag != null ? tag.ToContactTagVMFromContactTagMaster() : new ContactTagVM(); tagVMs.Add(tagVM); } contactVM = contact.ToContactVMFromContact(); contactVM.ContactPhones = phoneVMs; contactVM.ContactEmails = emailVMs; contactVM.Tags = tagVMs; return ApiResponse.SuccessResponse(contactVM, "Contact Created Successfully", 200); } _logger.LogWarning("Employee with ID {LoggedInEmployeeId} sended empty payload", LoggedInEmployee.Id); return ApiResponse.ErrorResponse("User Send empty Payload", "User Send empty Payload", 400); } public async Task> UpdateContact(Guid id, UpdateContactDto updateContact) { Guid tenantId = _userHelper.GetTenantId(); var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); if (updateContact != null) { if (updateContact.Id != id) { _logger.LogWarning("Employee with ID {LoggedInEmployeeId} sended different ID in payload and path parameter", LoggedInEmployee.Id); return ApiResponse.ErrorResponse("Invalid data", "Invalid data", 400); } Contact? contact = await _context.Contacts.FirstOrDefaultAsync(c => c.Id == id && c.TenantId == tenantId); if (contact == null) { _logger.LogWarning("Employee with ID {LoggedInEmployeeId} tries to update contact with ID {ContactId} is not found in database", LoggedInEmployee.Id); return ApiResponse.ErrorResponse("Contact not found", "Contact not found", 404); } var newContact = updateContact.ToContactFromUpdateContactDto(tenantId); List phones = await _context.ContactsPhones.AsNoTracking().Where(p => p.ContactId == contact.Id).ToListAsync(); var phoneIds = phones.Select(p => p.Id).ToList(); List emails = await _context.ContactsEmails.AsNoTracking().Where(p => p.ContactId == contact.Id).ToListAsync(); var emailIds = emails.Select(p => p.Id).ToList(); List contactBuckets = await _context.ContactBucketMappings.AsNoTracking().Where(m => m.ContactId == contact.Id).ToListAsync(); var bucketIds = contactBuckets.Select(b => b.BucketId).Distinct().ToList(); List contactTags = await _context.ContactTagMappings.AsNoTracking().Where(m => m.ContactId == contact.Id).ToListAsync(); var tagIds = contactTags.Select(t => t.ContactTagtId).Distinct().ToList(); List tags = await _context.ContactTagMasters.Where(t => tagIds.Contains(t.Id)).ToListAsync(); 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.Tags != null) { var updatedTagIds = updateContact.Tags.Select(t => t.Id).Distinct().ToList(); foreach (var tag in updateContact.Tags) { if (tag.Id != null && !tagIds.Contains(tag.Id.Value)) { _context.ContactTagMappings.Add(new ContactTagMapping { ContactId = contact.Id, ContactTagtId = tag.Id.Value }); } else if (tag.Id == null || tag.Id == Guid.Empty) { ContactTagMaster contactTag = new ContactTagMaster { Name = tag.Name, Description = "" }; _context.ContactTagMasters.Add(contactTag); _context.ContactTagMappings.Add(new ContactTagMapping { ContactId = contact.Id, ContactTagtId = contactTag.Id }); } } foreach (var contactTag in contactTags) { if (!updatedTagIds.Contains(contactTag.Id)) { _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(); 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(); ContactVM contactVM = new ContactVM(); List phoneVMs = new List(); foreach (var phone in phones) { ContactPhoneVM phoneVM = phone.ToContactPhoneVMFromContactPhone(); phoneVMs.Add(phoneVM); } List emailVMs = new List(); foreach (var email in emails) { ContactEmailVM emailVM = email.ToContactEmailVMFromContactEmail(); emailVMs.Add(emailVM); } List tagVMs = new List(); foreach (var contactTagMapping in contactTags) { ContactTagVM tagVM = new ContactTagVM(); var tag = tags.Find(t => t.Id == contactTagMapping.ContactTagtId); tagVM = tag != null ? tag.ToContactTagVMFromContactTagMaster() : new ContactTagVM(); tagVMs.Add(tagVM); } contactVM = contact.ToContactVMFromContact(); contactVM.ContactPhones = phoneVMs; contactVM.ContactEmails = emailVMs; contactVM.Tags = tagVMs; _logger.LogInfo("Conatct {ContactId} has been updated by employee {EmployeeId}", contact.Id, LoggedInEmployee.Id); return ApiResponse.SuccessResponse(contactVM, "Contact Updated Successfully", 200); } _logger.LogWarning("Employee with ID {LoggedInEmployeeId} sended empty payload", LoggedInEmployee.Id); return ApiResponse.ErrorResponse("User Send empty Payload", "User Send empty Payload", 400); } // -------------------------------- Bucket -------------------------------- public async Task> GetBucketList() { Guid tenantId = _userHelper.GetTenantId(); var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); List employeeBuckets = await _context.EmployeeBucketMappings.Where(b => b.EmployeeId == LoggedInEmployee.Id).ToListAsync(); var bucketIds = employeeBuckets.Select(b => b.BucketId).ToList(); List bucketList = await _context.Buckets.Where(b => bucketIds.Contains(b.Id)).ToListAsync(); List bucketVMs = new List(); foreach (var bucket in bucketList) { BucketVM bucketVM = bucket.ToBucketVMFromBucket(); bucketVMs.Add(bucketVM); } _logger.LogInfo("{count} Buckets are fetched by Employee with ID {LoggedInEmployeeId}", bucketVMs.Count, LoggedInEmployee.Id); return ApiResponse.SuccessResponse(bucketVMs, System.String.Format("{0} buckets fetched successfully", bucketVMs.Count), 200); } } }