diff --git a/Marco.Pms.Services/Controllers/DirectoryController.cs b/Marco.Pms.Services/Controllers/DirectoryController.cs index 9eb06e0..ea9a80a 100644 --- a/Marco.Pms.Services/Controllers/DirectoryController.cs +++ b/Marco.Pms.Services/Controllers/DirectoryController.cs @@ -68,6 +68,37 @@ namespace Marco.Pms.Services.Controllers } } + [HttpPost("create/list")] + public async Task CreateMultipleContacts([FromBody] List createContacts) + { + if (!ModelState.IsValid) + { + var errors = ModelState.Values + .SelectMany(v => v.Errors) + .Select(e => e.ErrorMessage) + .ToList(); + _logger.LogWarning("User sent Invalid Date while marking attendance"); + return BadRequest(ApiResponse.ErrorResponse("Invalid data", errors, 400)); + } + + List successResponse = new List(); + List errorResponse = new List(); + foreach (var createContact in createContacts) + { + var response = await _directoryHelper.CreateMultipleContacts(createContact); + if (response.StatusCode == 200) + { + + successResponse.Add(response); + } + else + { + errorResponse.Add(response); + } + } + _logger.LogInfo("SucessCount : {SucessCount} , ErrorCount : {ErrorCount}", successResponse.Count, errorResponse.Count); + return Ok(errorResponse); + } [HttpPost] public async Task CreateContact([FromBody] CreateContactDto createContact) { diff --git a/Marco.Pms.Services/Helpers/DirectoryHelper.cs b/Marco.Pms.Services/Helpers/DirectoryHelper.cs index 3dd578e..b8f4a4d 100644 --- a/Marco.Pms.Services/Helpers/DirectoryHelper.cs +++ b/Marco.Pms.Services/Helpers/DirectoryHelper.cs @@ -3,7 +3,6 @@ using Marco.Pms.Model.Directory; using Marco.Pms.Model.Dtos.Directory; using Marco.Pms.Model.Entitlements; using Marco.Pms.Model.Mapper; -using Marco.Pms.Model.Projects; using Marco.Pms.Model.Utilities; using Marco.Pms.Model.ViewModels.Directory; using Marco.Pms.Model.ViewModels.Master; @@ -11,19 +10,23 @@ using Marco.Pms.Model.ViewModels.Projects; using Marco.Pms.Services.Service; using MarcoBMS.Services.Helpers; using MarcoBMS.Services.Service; +using Microsoft.CodeAnalysis; using Microsoft.EntityFrameworkCore; +using Project = Marco.Pms.Model.Projects.Project; namespace Marco.Pms.Services.Helpers { public class DirectoryHelper { + private readonly IDbContextFactory _dbContextFactory; private readonly ApplicationDbContext _context; private readonly ILoggingService _logger; private readonly UserHelper _userHelper; private readonly PermissionServices _permissionServices; - public DirectoryHelper(ApplicationDbContext context, ILoggingService logger, UserHelper userHelper, PermissionServices permissionServices) + public DirectoryHelper(IDbContextFactory dbContextFactory, ApplicationDbContext context, ILoggingService logger, UserHelper userHelper, PermissionServices permissionServices) { + _dbContextFactory = dbContextFactory; _context = context; _logger = logger; _userHelper = userHelper; @@ -295,12 +298,153 @@ namespace Marco.Pms.Services.Helpers _logger.LogInfo("Employee ID {EmployeeId} sent an empty Bucket id", LoggedInEmployee.Id); return ApiResponse.ErrorResponse("Bucket ID is empty", "Bucket ID is empty", 400); } + + public async Task> CreateMultipleContacts(CreateContactDto createContact) + { + Guid tenantId = _userHelper.GetTenantId(); + var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); + Contact? contact = createContact.ToContactFromCreateContactDto(tenantId, LoggedInEmployee.Id); + + _context.Contacts.Add(contact); + try + { + await _context.SaveChangesAsync(); + } + catch (DbUpdateException dbEx) + { + _logger.LogError(dbEx, "Databsae Exception occured while adding contact"); + return ApiResponse.ErrorResponse("Databsae Exception", createContact, 500); + } + _logger.LogInfo("Contact with ID {ContactId} created by Employee with ID {LoggedInEmployeeId}", contact.Id, LoggedInEmployee.Id); + var tagTask = Task.Run(async () => + { + await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); + return await dbContext.ContactTagMasters.Where(t => t.TenantId == tenantId).ToListAsync(); + }); + var bucketIdsTask = Task.Run(async () => + { + await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); + return await dbContext.Buckets.Where(b => b.TenantId == tenantId).Select(b => b.Id).ToListAsync(); + }); + var projectIdsTask = Task.Run(async () => + { + await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); + return await dbContext.Projects.Where(p => p.TenantId == tenantId).Select(p => p.Id).ToListAsync(); + }); + try + { + await Task.WhenAll(tagTask, bucketIdsTask, projectIdsTask); + } + catch (Exception dbEx) + { + _logger.LogError(dbEx, "Exception occured while fetching related table to contacts"); + return ApiResponse.ErrorResponse("Databsae Exception", createContact, 500); + } + + var tags = tagTask.Result; + var tagNames = tags.Select(t => t.Name.ToLower()).ToList(); + var bucketIds = bucketIdsTask.Result; + var projectIds = projectIdsTask.Result; + + if (createContact.ContactPhones != null) + { + + List phones = createContact.ContactPhones.Select(cp => cp.ToContactPhoneFromCreateContactPhoneDto(tenantId, contact.Id)).ToList(); + _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) + { + List emails = createContact.ContactEmails.Select(ce => ce.ToContactEmailFromCreateContactEmailDto(tenantId, contact.Id)).ToList(); + _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) + { + List contactBucketMappings = createContact.BucketIds + .Where(b => bucketIds.Contains(b)) + .Select(b => new ContactBucketMapping + { + BucketId = b, + ContactId = contact.Id + }).ToList(); + + _context.ContactBucketMappings.AddRange(contactBucketMappings); + + _logger.LogInfo("Contact with ID {ContactId} added to {count} number of buckets by employee with ID {LoggedEmployeeId}", contact.Id, contactBucketMappings.Count, LoggedInEmployee.Id); + } + + if (createContact.ProjectIds != null) + { + List projectMappings = createContact.ProjectIds + .Where(p => projectIds.Contains(p)) + .Select(p => new ContactProjectMapping + { + ProjectId = p, + ContactId = contact.Id, + TenantId = tenantId + }) + .ToList(); + _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) + { + List contactTagMappings = new List(); + 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); + } + try + { + await _context.SaveChangesAsync(); + + return ApiResponse.SuccessResponse(true); + } + catch (DbUpdateException dbEx) + { + _logger.LogError(dbEx, "Databsae Exception occured while adding related entries to contacts"); + return ApiResponse.ErrorResponse("Databsae Exception", createContact, 500); + } + } 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(); diff --git a/Marco.Pms.UtilityApplication/ApiService.cs b/Marco.Pms.UtilityApplication/ApiService.cs index 1d72521..362f8b8 100644 --- a/Marco.Pms.UtilityApplication/ApiService.cs +++ b/Marco.Pms.UtilityApplication/ApiService.cs @@ -1,10 +1,6 @@ using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Linq; using System.Net.Http; using System.Text; -using System.Threading.Tasks; namespace Marco.Pms.UtilityApplication { diff --git a/Marco.Pms.UtilityApplication/DirectoryHelper.cs b/Marco.Pms.UtilityApplication/DirectoryHelper.cs index bf1b511..8d3b823 100644 --- a/Marco.Pms.UtilityApplication/DirectoryHelper.cs +++ b/Marco.Pms.UtilityApplication/DirectoryHelper.cs @@ -1,29 +1,23 @@ using Marco.Pms.Model.Dtos.Directory; using OfficeOpenXml; -using System; -using System.Collections.Generic; using System.IO; -using System.Linq; using System.Net.Mail; -using System.Text; -using System.Threading.Tasks; namespace Marco.Pms.UtilityApplication { public class DirectoryHelper { - public async Task<(List, List) > GenerateCreateContactDto(List contactsData, List categoryMasters, List tagsMaster, List projectMaster) + public async Task<(List, List)> GenerateCreateContactDto(List contactsData, List categoryMasters, List tagsMaster, List projectMaster) { List lstCreateContactDto = new List(); List failedContacts = new List(); - CreateContactDto dto = null; foreach (Contacts contact in contactsData) { if (contact.Name != "") { - dto = new CreateContactDto(); + CreateContactDto dto = new CreateContactDto(); dto.Name = contact.Name; dto.Organization = contact.Organization; dto.Address = contact.Address; @@ -50,10 +44,10 @@ namespace Marco.Pms.UtilityApplication private List? GetContactTags(Contacts contact, List tagsMaster) { List result = new List(); - ContactTagDto dto = null; + foreach (string tag in contact.Tags.Split(",")) { - dto = new ContactTagDto(); + ContactTagDto dto = new ContactTagDto(); dto.Name = tag; var tagObject = tagsMaster.SingleOrDefault(c => c.Tag == tag.Trim()); dto.Id = (tagObject != null && tagObject.TagID != "" ? Guid.Parse(tagObject.TagID) : null);