Removed Project ForignKey From ProjectContactMapping Table
This commit is contained in:
parent
c7a73e78fb
commit
64aab7d712
File diff suppressed because one or more lines are too long
@ -0,0 +1,39 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace Marco.Pms.DataAccess.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class Removed_Project_ForignKey_From_ProjectContactMapping_Table : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "FK_ContactProjectMappings_Projects_ProjectId",
|
||||||
|
table: "ContactProjectMappings");
|
||||||
|
|
||||||
|
migrationBuilder.DropIndex(
|
||||||
|
name: "IX_ContactProjectMappings_ProjectId",
|
||||||
|
table: "ContactProjectMappings");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_ContactProjectMappings_ProjectId",
|
||||||
|
table: "ContactProjectMappings",
|
||||||
|
column: "ProjectId");
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "FK_ContactProjectMappings_Projects_ProjectId",
|
||||||
|
table: "ContactProjectMappings",
|
||||||
|
column: "ProjectId",
|
||||||
|
principalTable: "Projects",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -898,8 +898,6 @@ namespace Marco.Pms.DataAccess.Migrations
|
|||||||
|
|
||||||
b.HasIndex("ContactId");
|
b.HasIndex("ContactId");
|
||||||
|
|
||||||
b.HasIndex("ProjectId");
|
|
||||||
|
|
||||||
b.HasIndex("TenantId");
|
b.HasIndex("TenantId");
|
||||||
|
|
||||||
b.ToTable("ContactProjectMappings");
|
b.ToTable("ContactProjectMappings");
|
||||||
@ -6865,12 +6863,6 @@ namespace Marco.Pms.DataAccess.Migrations
|
|||||||
.OnDelete(DeleteBehavior.Cascade)
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
|
|
||||||
b.HasOne("Marco.Pms.Model.Projects.Project", "Project")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("ProjectId")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant")
|
b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant")
|
||||||
.WithMany()
|
.WithMany()
|
||||||
.HasForeignKey("TenantId")
|
.HasForeignKey("TenantId")
|
||||||
@ -6879,8 +6871,6 @@ namespace Marco.Pms.DataAccess.Migrations
|
|||||||
|
|
||||||
b.Navigation("Contact");
|
b.Navigation("Contact");
|
||||||
|
|
||||||
b.Navigation("Project");
|
|
||||||
|
|
||||||
b.Navigation("Tenant");
|
b.Navigation("Tenant");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using Marco.Pms.Model.Utilities;
|
||||||
using Marco.Pms.Model.Projects;
|
|
||||||
using Marco.Pms.Model.Utilities;
|
|
||||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
namespace Marco.Pms.Model.Directory
|
namespace Marco.Pms.Model.Directory
|
||||||
{
|
{
|
||||||
@ -9,9 +8,6 @@ namespace Marco.Pms.Model.Directory
|
|||||||
{
|
{
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
public Guid ProjectId { get; set; }
|
public Guid ProjectId { get; set; }
|
||||||
[ValidateNever]
|
|
||||||
[ForeignKey("ProjectId")]
|
|
||||||
public Project? Project { get; set; }
|
|
||||||
public Guid ContactId { get; set; }
|
public Guid ContactId { get; set; }
|
||||||
[ValidateNever]
|
[ValidateNever]
|
||||||
[ForeignKey("ContactId")]
|
[ForeignKey("ContactId")]
|
||||||
|
|||||||
@ -474,6 +474,12 @@ namespace Marco.Pms.Services.Service
|
|||||||
|
|
||||||
return await _dbContext.ContactsEmails.Where(e => contactIds.Contains(e.ContactId)).ToListAsync();
|
return await _dbContext.ContactsEmails.Where(e => contactIds.Contains(e.ContactId)).ToListAsync();
|
||||||
});
|
});
|
||||||
|
await Task.WhenAll(contactTask, phoneTask, emailTask);
|
||||||
|
|
||||||
|
var contacts = contactTask.Result;
|
||||||
|
var phones = phoneTask.Result;
|
||||||
|
var emails = emailTask.Result;
|
||||||
|
|
||||||
var tagTask = Task.Run(async () =>
|
var tagTask = Task.Run(async () =>
|
||||||
{
|
{
|
||||||
await using var _dbContext = await _dbContextFactory.CreateDbContextAsync();
|
await using var _dbContext = await _dbContextFactory.CreateDbContextAsync();
|
||||||
@ -493,11 +499,8 @@ namespace Marco.Pms.Services.Service
|
|||||||
return await _dbContext.ContactBucketMappings.Where(cb => contactIds.Contains(cb.ContactId)).ToListAsync();
|
return await _dbContext.ContactBucketMappings.Where(cb => contactIds.Contains(cb.ContactId)).ToListAsync();
|
||||||
});
|
});
|
||||||
|
|
||||||
await Task.WhenAll(contactTask);
|
await Task.WhenAll(tagTask, contactProjectTask, contactBucketTask);
|
||||||
|
|
||||||
var contacts = contactTask.Result;
|
|
||||||
var phones = phoneTask.Result;
|
|
||||||
var emails = emailTask.Result;
|
|
||||||
var tags = tagTask.Result;
|
var tags = tagTask.Result;
|
||||||
var contactProjects = contactProjectTask.Result;
|
var contactProjects = contactProjectTask.Result;
|
||||||
var contactBuckets = contactBucketTask.Result;
|
var contactBuckets = contactBucketTask.Result;
|
||||||
@ -587,6 +590,13 @@ namespace Marco.Pms.Services.Service
|
|||||||
_logger.LogWarning("Employee with ID {LoggedInEmployeeId} tries to update contact with ID {ContactId} is not found in database", loggedInEmployeeId);
|
_logger.LogWarning("Employee with ID {LoggedInEmployeeId} tries to update contact with ID {ContactId} is not found in database", loggedInEmployeeId);
|
||||||
return ApiResponse<object>.ErrorResponse("Contact not found", "Contact not found", 404);
|
return ApiResponse<object>.ErrorResponse("Contact not found", "Contact not found", 404);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var projectIds = await dbContext.ContactProjectMappings
|
||||||
|
.AsNoTracking()
|
||||||
|
.Where(cp => cp.ContactId == contact.Id && cp.TenantId == tenantId)
|
||||||
|
.Select(cp => cp.ProjectId)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
ContactProfileVM contactVM = _mapper.Map<ContactProfileVM>(contact);
|
ContactProfileVM contactVM = _mapper.Map<ContactProfileVM>(contact);
|
||||||
|
|
||||||
var phonesTask = Task.Run(async () =>
|
var phonesTask = Task.Run(async () =>
|
||||||
@ -609,21 +619,26 @@ namespace Marco.Pms.Services.Service
|
|||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
});
|
});
|
||||||
|
|
||||||
var contactProjectsTask = Task.Run(async () =>
|
var infraProjectTask = Task.Run(async () =>
|
||||||
{
|
{
|
||||||
await using var taskDbContext = await _dbContextFactory.CreateDbContextAsync();
|
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||||
return await taskDbContext.ContactProjectMappings
|
return await context.Projects.Where(p => projectIds.Contains(p.Id) && p.TenantId == tenantId).Select(p => _mapper.Map<BasicProjectVM>(p)).ToListAsync();
|
||||||
.AsNoTracking()
|
|
||||||
.Include(cp => cp.Project)
|
|
||||||
.Where(cp => cp.ContactId == contact.Id && cp.Project != null && cp.Project.TenantId == tenantId)
|
|
||||||
.Select(cp => new BasicProjectVM
|
|
||||||
{
|
|
||||||
Id = cp.Project!.Id,
|
|
||||||
Name = cp.Project.Name
|
|
||||||
})
|
|
||||||
.ToListAsync();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var serviceProjectTask = Task.Run(async () =>
|
||||||
|
{
|
||||||
|
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||||
|
return await context.ServiceProjects.Where(sp => projectIds.Contains(sp.Id) && sp.TenantId == tenantId).Select(sp => _mapper.Map<BasicProjectVM>(sp)).ToListAsync();
|
||||||
|
});
|
||||||
|
|
||||||
|
await Task.WhenAll(phonesTask, emailsTask, infraProjectTask, serviceProjectTask);
|
||||||
|
|
||||||
|
contactVM.ContactPhones = phonesTask.Result;
|
||||||
|
contactVM.ContactEmails = emailsTask.Result;
|
||||||
|
var projects = infraProjectTask.Result;
|
||||||
|
projects.AddRange(serviceProjectTask.Result);
|
||||||
|
contactVM.Projects = projects;
|
||||||
|
|
||||||
var contactBucketsTask = Task.Run(async () =>
|
var contactBucketsTask = Task.Run(async () =>
|
||||||
{
|
{
|
||||||
await using var taskDbContext = await _dbContextFactory.CreateDbContextAsync();
|
await using var taskDbContext = await _dbContextFactory.CreateDbContextAsync();
|
||||||
@ -679,12 +694,10 @@ namespace Marco.Pms.Services.Service
|
|||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
});
|
});
|
||||||
|
|
||||||
await Task.WhenAll(phonesTask, emailsTask, contactProjectsTask, contactBucketsTask, contactTagsTask, contactNotesTask);
|
await Task.WhenAll(contactBucketsTask, contactTagsTask, contactNotesTask);
|
||||||
contactVM.ContactPhones = phonesTask.Result;
|
|
||||||
contactVM.ContactEmails = emailsTask.Result;
|
|
||||||
contactVM.Tags = contactTagsTask.Result;
|
contactVM.Tags = contactTagsTask.Result;
|
||||||
contactVM.Buckets = contactBucketsTask.Result;
|
contactVM.Buckets = contactBucketsTask.Result;
|
||||||
contactVM.Projects = contactProjectsTask.Result;
|
|
||||||
contactVM.Notes = contactNotesTask.Result;
|
contactVM.Notes = contactNotesTask.Result;
|
||||||
_logger.LogInfo("Employee ID {EmployeeId} fetched profile of contact {ContactId}", loggedInEmployeeId, contact.Id);
|
_logger.LogInfo("Employee ID {EmployeeId} fetched profile of contact {ContactId}", loggedInEmployeeId, contact.Id);
|
||||||
return ApiResponse<object>.SuccessResponse(contactVM, "Contact profile fetched successfully");
|
return ApiResponse<object>.SuccessResponse(contactVM, "Contact profile fetched successfully");
|
||||||
@ -3289,11 +3302,18 @@ namespace Marco.Pms.Services.Service
|
|||||||
{
|
{
|
||||||
if (!(dto.ProjectIds?.Any() ?? false)) return new List<ContactProjectMapping>();
|
if (!(dto.ProjectIds?.Any() ?? false)) return new List<ContactProjectMapping>();
|
||||||
|
|
||||||
var validProjectIds = await _context.Projects
|
var infraProjectIds = await _context.Projects
|
||||||
.Where(p => dto.ProjectIds.Contains(p.Id) && p.TenantId == tenantId)
|
.Where(p => dto.ProjectIds.Contains(p.Id) && p.TenantId == tenantId)
|
||||||
.Select(p => p.Id)
|
.Select(p => p.Id)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
|
var serviceProjectIds = await _context.ServiceProjects
|
||||||
|
.Where(sp => dto.ProjectIds.Contains(sp.Id) && sp.IsActive && sp.TenantId == tenantId)
|
||||||
|
.Select(sp => sp.Id)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
var validProjectIds = infraProjectIds.Concat(serviceProjectIds).Distinct().Where(p => p != Guid.Empty).ToList();
|
||||||
|
|
||||||
var mappings = validProjectIds.Select(projectId => new ContactProjectMapping
|
var mappings = validProjectIds.Select(projectId => new ContactProjectMapping
|
||||||
{
|
{
|
||||||
ProjectId = projectId,
|
ProjectId = projectId,
|
||||||
|
|||||||
@ -442,12 +442,20 @@ namespace Marco.Pms.Services.Service
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves the filter object for expenses.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="loggedInEmployee">The logged-in employee.</param>
|
||||||
|
/// <param name="tenantId">The tenant ID.</param>
|
||||||
|
/// <returns>The API response containing the filter object.</returns>
|
||||||
public async Task<ApiResponse<object>> GetFilterObjectAsync(Employee loggedInEmployee, Guid tenantId)
|
public async Task<ApiResponse<object>> GetFilterObjectAsync(Employee loggedInEmployee, Guid tenantId)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
// Log the start of the operation
|
||||||
_logger.LogInfo("Fetching expenses for tenant: {TenantId}", tenantId);
|
_logger.LogInfo("Fetching expenses for tenant: {TenantId}", tenantId);
|
||||||
|
|
||||||
|
// Fetch expenses with related entities
|
||||||
var expenses = await _context.Expenses
|
var expenses = await _context.Expenses
|
||||||
.Include(e => e.PaidBy)
|
.Include(e => e.PaidBy)
|
||||||
.Include(e => e.CreatedBy)
|
.Include(e => e.CreatedBy)
|
||||||
@ -456,10 +464,13 @@ namespace Marco.Pms.Services.Service
|
|||||||
.Where(e => e.TenantId == tenantId)
|
.Where(e => e.TenantId == tenantId)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
|
// Log the number of fetched expenses
|
||||||
_logger.LogInfo("Fetched {ExpenseCount} expenses", expenses.Count);
|
_logger.LogInfo("Fetched {ExpenseCount} expenses", expenses.Count);
|
||||||
|
|
||||||
|
// Get project IDs from fetched expenses
|
||||||
var projectIds = expenses.Select(e => e.ProjectId).ToList();
|
var projectIds = expenses.Select(e => e.ProjectId).ToList();
|
||||||
|
|
||||||
|
// Fetch projects from infrastructure and service layers in parallel
|
||||||
var infraProjectTask = Task.Run(async () =>
|
var infraProjectTask = Task.Run(async () =>
|
||||||
{
|
{
|
||||||
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||||
@ -479,30 +490,42 @@ namespace Marco.Pms.Services.Service
|
|||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Wait for both tasks to complete
|
||||||
await Task.WhenAll(infraProjectTask, serviceProjectTask);
|
await Task.WhenAll(infraProjectTask, serviceProjectTask);
|
||||||
|
|
||||||
|
// Combine the results of both tasks
|
||||||
var projects = infraProjectTask.Result;
|
var projects = infraProjectTask.Result;
|
||||||
projects.AddRange(serviceProjectTask.Result);
|
projects.AddRange(serviceProjectTask.Result);
|
||||||
|
|
||||||
|
// Log the number of fetched projects
|
||||||
_logger.LogInfo("Fetched {ProjectCount} projects", projects.Count);
|
_logger.LogInfo("Fetched {ProjectCount} projects", projects.Count);
|
||||||
|
|
||||||
// Construct the final object from the results of the completed tasks.
|
// Construct the final object from the results of the completed tasks.
|
||||||
var response = new
|
var response = new
|
||||||
{
|
{
|
||||||
Projects = projects,
|
Projects = projects,
|
||||||
|
// Fetch distinct paid by entities from fetched expenses
|
||||||
PaidBy = expenses.Where(e => e.PaidBy != null).Select(e => new { Id = e.PaidBy!.Id, Name = $"{e.PaidBy.FirstName} {e.PaidBy.LastName}" }).Distinct().ToList(),
|
PaidBy = expenses.Where(e => e.PaidBy != null).Select(e => new { Id = e.PaidBy!.Id, Name = $"{e.PaidBy.FirstName} {e.PaidBy.LastName}" }).Distinct().ToList(),
|
||||||
|
// Fetch distinct created by entities from fetched expenses
|
||||||
CreatedBy = expenses.Where(e => e.CreatedBy != null).Select(e => new { Id = e.CreatedBy!.Id, Name = $"{e.CreatedBy.FirstName} {e.CreatedBy.LastName}" }).Distinct().ToList(),
|
CreatedBy = expenses.Where(e => e.CreatedBy != null).Select(e => new { Id = e.CreatedBy!.Id, Name = $"{e.CreatedBy.FirstName} {e.CreatedBy.LastName}" }).Distinct().ToList(),
|
||||||
|
// Fetch distinct status entities from fetched expenses
|
||||||
Status = expenses.Where(e => e.Status != null).Select(e => new { Id = e.Status!.Id, Name = e.Status.Name }).Distinct().ToList(),
|
Status = expenses.Where(e => e.Status != null).Select(e => new { Id = e.Status!.Id, Name = e.Status.Name }).Distinct().ToList(),
|
||||||
|
// Fetch distinct expense category entities from fetched expenses
|
||||||
ExpenseCategory = expenses.Where(e => e.ExpenseCategory != null).Select(e => new { Id = e.ExpenseCategory!.Id, Name = e.ExpenseCategory.Name }).Distinct().ToList()
|
ExpenseCategory = expenses.Where(e => e.ExpenseCategory != null).Select(e => new { Id = e.ExpenseCategory!.Id, Name = e.ExpenseCategory.Name }).Distinct().ToList()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Log the successful completion of the operation
|
||||||
_logger.LogInfo("Successfully fetched the filter list");
|
_logger.LogInfo("Successfully fetched the filter list");
|
||||||
|
|
||||||
|
// Return the success response
|
||||||
return ApiResponse<object>.SuccessResponse(response, "Successfully fetched the filter list", 200);
|
return ApiResponse<object>.SuccessResponse(response, "Successfully fetched the filter list", 200);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
// Log the exception
|
||||||
_logger.LogError(ex, "Exception occurred while fetching the list filters for expenses");
|
_logger.LogError(ex, "Exception occurred while fetching the list filters for expenses");
|
||||||
|
|
||||||
|
// Return the error response
|
||||||
return ApiResponse<object>.ErrorResponse("Internal Exception Occurred", ExceptionMapper(ex), 500);
|
return ApiResponse<object>.ErrorResponse("Internal Exception Occurred", ExceptionMapper(ex), 500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user