Compare commits
No commits in common. "fe1dfd729336f359060cc831d96db2830af4d99a" and "c5da400e6ba48062c0bc2949b99bfdef842dcc6e" have entirely different histories.
fe1dfd7293
...
c5da400e6b
@ -993,6 +993,11 @@ namespace Marco.Pms.DataAccess.Data
|
|||||||
);
|
);
|
||||||
|
|
||||||
modelBuilder.Entity<OrgTypeMaster>().HasData(
|
modelBuilder.Entity<OrgTypeMaster>().HasData(
|
||||||
|
new OrgTypeMaster
|
||||||
|
{
|
||||||
|
Id = Guid.Parse("743806fe-d991-4079-b223-e4e2da44f435"),
|
||||||
|
Name = "Tenant"
|
||||||
|
},
|
||||||
new OrgTypeMaster
|
new OrgTypeMaster
|
||||||
{
|
{
|
||||||
Id = Guid.Parse("5ee49bcd-b6d3-482f-9aaf-484afe04abec"),
|
Id = Guid.Parse("5ee49bcd-b6d3-482f-9aaf-484afe04abec"),
|
||||||
@ -1002,6 +1007,11 @@ namespace Marco.Pms.DataAccess.Data
|
|||||||
{
|
{
|
||||||
Id = Guid.Parse("a283356a-9b02-4029-afb7-e65c703efdd4"),
|
Id = Guid.Parse("a283356a-9b02-4029-afb7-e65c703efdd4"),
|
||||||
Name = "Sub-Contractor"
|
Name = "Sub-Contractor"
|
||||||
|
},
|
||||||
|
new OrgTypeMaster
|
||||||
|
{
|
||||||
|
Id = Guid.Parse("b1877a3b-8832-47b1-bbe3-dc7e98672f49"),
|
||||||
|
Name = "PMC"
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@ -1,84 +0,0 @@
|
|||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
namespace Marco.Pms.DataAccess.Migrations
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public partial class Added_Assigned_By_In_Mapping_Tables : Migration
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.AddColumn<Guid>(
|
|
||||||
name: "AssignedById",
|
|
||||||
table: "TenantOrgMappings",
|
|
||||||
type: "char(36)",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: new Guid("08dd8b35-d98b-44f1-896d-12aec3f035aa"),
|
|
||||||
collation: "ascii_general_ci");
|
|
||||||
|
|
||||||
migrationBuilder.AddColumn<Guid>(
|
|
||||||
name: "AssignedById",
|
|
||||||
table: "ProjectOrgMappings",
|
|
||||||
type: "char(36)",
|
|
||||||
nullable: false,
|
|
||||||
defaultValue: new Guid("08dd8b35-d98b-44f1-896d-12aec3f035aa"),
|
|
||||||
collation: "ascii_general_ci");
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "IX_TenantOrgMappings_AssignedById",
|
|
||||||
table: "TenantOrgMappings",
|
|
||||||
column: "AssignedById");
|
|
||||||
|
|
||||||
migrationBuilder.CreateIndex(
|
|
||||||
name: "IX_ProjectOrgMappings_AssignedById",
|
|
||||||
table: "ProjectOrgMappings",
|
|
||||||
column: "AssignedById");
|
|
||||||
|
|
||||||
migrationBuilder.AddForeignKey(
|
|
||||||
name: "FK_ProjectOrgMappings_Employees_AssignedById",
|
|
||||||
table: "ProjectOrgMappings",
|
|
||||||
column: "AssignedById",
|
|
||||||
principalTable: "Employees",
|
|
||||||
principalColumn: "Id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
|
|
||||||
migrationBuilder.AddForeignKey(
|
|
||||||
name: "FK_TenantOrgMappings_Employees_AssignedById",
|
|
||||||
table: "TenantOrgMappings",
|
|
||||||
column: "AssignedById",
|
|
||||||
principalTable: "Employees",
|
|
||||||
principalColumn: "Id",
|
|
||||||
onDelete: ReferentialAction.Cascade);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.DropForeignKey(
|
|
||||||
name: "FK_ProjectOrgMappings_Employees_AssignedById",
|
|
||||||
table: "ProjectOrgMappings");
|
|
||||||
|
|
||||||
migrationBuilder.DropForeignKey(
|
|
||||||
name: "FK_TenantOrgMappings_Employees_AssignedById",
|
|
||||||
table: "TenantOrgMappings");
|
|
||||||
|
|
||||||
migrationBuilder.DropIndex(
|
|
||||||
name: "IX_TenantOrgMappings_AssignedById",
|
|
||||||
table: "TenantOrgMappings");
|
|
||||||
|
|
||||||
migrationBuilder.DropIndex(
|
|
||||||
name: "IX_ProjectOrgMappings_AssignedById",
|
|
||||||
table: "ProjectOrgMappings");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "AssignedById",
|
|
||||||
table: "TenantOrgMappings");
|
|
||||||
|
|
||||||
migrationBuilder.DropColumn(
|
|
||||||
name: "AssignedById",
|
|
||||||
table: "ProjectOrgMappings");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because one or more lines are too long
@ -1,40 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional
|
|
||||||
|
|
||||||
namespace Marco.Pms.DataAccess.Migrations
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public partial class Deleted_Organization_Types : Migration
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.DeleteData(
|
|
||||||
table: "OrgTypeMasters",
|
|
||||||
keyColumn: "Id",
|
|
||||||
keyValue: new Guid("743806fe-d991-4079-b223-e4e2da44f435"));
|
|
||||||
|
|
||||||
migrationBuilder.DeleteData(
|
|
||||||
table: "OrgTypeMasters",
|
|
||||||
keyColumn: "Id",
|
|
||||||
keyValue: new Guid("b1877a3b-8832-47b1-bbe3-dc7e98672f49"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
migrationBuilder.InsertData(
|
|
||||||
table: "OrgTypeMasters",
|
|
||||||
columns: new[] { "Id", "Name" },
|
|
||||||
values: new object[,]
|
|
||||||
{
|
|
||||||
{ new Guid("743806fe-d991-4079-b223-e4e2da44f435"), "Tenant" },
|
|
||||||
{ new Guid("b1877a3b-8832-47b1-bbe3-dc7e98672f49"), "PMC" }
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -3588,6 +3588,11 @@ namespace Marco.Pms.DataAccess.Migrations
|
|||||||
b.ToTable("OrgTypeMasters");
|
b.ToTable("OrgTypeMasters");
|
||||||
|
|
||||||
b.HasData(
|
b.HasData(
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = new Guid("743806fe-d991-4079-b223-e4e2da44f435"),
|
||||||
|
Name = "Tenant"
|
||||||
|
},
|
||||||
new
|
new
|
||||||
{
|
{
|
||||||
Id = new Guid("5ee49bcd-b6d3-482f-9aaf-484afe04abec"),
|
Id = new Guid("5ee49bcd-b6d3-482f-9aaf-484afe04abec"),
|
||||||
@ -3597,6 +3602,11 @@ namespace Marco.Pms.DataAccess.Migrations
|
|||||||
{
|
{
|
||||||
Id = new Guid("a283356a-9b02-4029-afb7-e65c703efdd4"),
|
Id = new Guid("a283356a-9b02-4029-afb7-e65c703efdd4"),
|
||||||
Name = "Sub-Contractor"
|
Name = "Sub-Contractor"
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = new Guid("b1877a3b-8832-47b1-bbe3-dc7e98672f49"),
|
||||||
|
Name = "PMC"
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -3672,9 +3682,6 @@ namespace Marco.Pms.DataAccess.Migrations
|
|||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("char(36)");
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
b.Property<Guid>("AssignedById")
|
|
||||||
.HasColumnType("char(36)");
|
|
||||||
|
|
||||||
b.Property<DateTime>("AssignedDate")
|
b.Property<DateTime>("AssignedDate")
|
||||||
.HasColumnType("datetime(6)");
|
.HasColumnType("datetime(6)");
|
||||||
|
|
||||||
@ -3698,8 +3705,6 @@ namespace Marco.Pms.DataAccess.Migrations
|
|||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
b.HasIndex("AssignedById");
|
|
||||||
|
|
||||||
b.HasIndex("OrganizationId");
|
b.HasIndex("OrganizationId");
|
||||||
|
|
||||||
b.HasIndex("OrganizationTypeId");
|
b.HasIndex("OrganizationTypeId");
|
||||||
@ -3760,9 +3765,6 @@ namespace Marco.Pms.DataAccess.Migrations
|
|||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("char(36)");
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
b.Property<Guid>("AssignedById")
|
|
||||||
.HasColumnType("char(36)");
|
|
||||||
|
|
||||||
b.Property<DateTime>("AssignedDate")
|
b.Property<DateTime>("AssignedDate")
|
||||||
.HasColumnType("datetime(6)");
|
.HasColumnType("datetime(6)");
|
||||||
|
|
||||||
@ -3783,8 +3785,6 @@ namespace Marco.Pms.DataAccess.Migrations
|
|||||||
|
|
||||||
b.HasKey("Id");
|
b.HasKey("Id");
|
||||||
|
|
||||||
b.HasIndex("AssignedById");
|
|
||||||
|
|
||||||
b.HasIndex("OrganizationId");
|
b.HasIndex("OrganizationId");
|
||||||
|
|
||||||
b.HasIndex("TenantId");
|
b.HasIndex("TenantId");
|
||||||
@ -5737,12 +5737,6 @@ namespace Marco.Pms.DataAccess.Migrations
|
|||||||
|
|
||||||
modelBuilder.Entity("Marco.Pms.Model.OrganizationModel.ProjectOrgMapping", b =>
|
modelBuilder.Entity("Marco.Pms.Model.OrganizationModel.ProjectOrgMapping", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("Marco.Pms.Model.Employees.Employee", "AssignedBy")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("AssignedById")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.HasOne("Marco.Pms.Model.OrganizationModel.Organization", "Organization")
|
b.HasOne("Marco.Pms.Model.OrganizationModel.Organization", "Organization")
|
||||||
.WithMany()
|
.WithMany()
|
||||||
.HasForeignKey("OrganizationId")
|
.HasForeignKey("OrganizationId")
|
||||||
@ -5773,8 +5767,6 @@ namespace Marco.Pms.DataAccess.Migrations
|
|||||||
.OnDelete(DeleteBehavior.Cascade)
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
|
|
||||||
b.Navigation("AssignedBy");
|
|
||||||
|
|
||||||
b.Navigation("Organization");
|
b.Navigation("Organization");
|
||||||
|
|
||||||
b.Navigation("OrganizationType");
|
b.Navigation("OrganizationType");
|
||||||
@ -5815,12 +5807,6 @@ namespace Marco.Pms.DataAccess.Migrations
|
|||||||
|
|
||||||
modelBuilder.Entity("Marco.Pms.Model.OrganizationModel.TenantOrgMapping", b =>
|
modelBuilder.Entity("Marco.Pms.Model.OrganizationModel.TenantOrgMapping", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("Marco.Pms.Model.Employees.Employee", "AssignedBy")
|
|
||||||
.WithMany()
|
|
||||||
.HasForeignKey("AssignedById")
|
|
||||||
.OnDelete(DeleteBehavior.Cascade)
|
|
||||||
.IsRequired();
|
|
||||||
|
|
||||||
b.HasOne("Marco.Pms.Model.OrganizationModel.Organization", "Organization")
|
b.HasOne("Marco.Pms.Model.OrganizationModel.Organization", "Organization")
|
||||||
.WithMany()
|
.WithMany()
|
||||||
.HasForeignKey("OrganizationId")
|
.HasForeignKey("OrganizationId")
|
||||||
@ -5833,8 +5819,6 @@ namespace Marco.Pms.DataAccess.Migrations
|
|||||||
.OnDelete(DeleteBehavior.Cascade)
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
.IsRequired();
|
.IsRequired();
|
||||||
|
|
||||||
b.Navigation("AssignedBy");
|
|
||||||
|
|
||||||
b.Navigation("Organization");
|
b.Navigation("Organization");
|
||||||
|
|
||||||
b.Navigation("Tenant");
|
b.Navigation("Tenant");
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
using Marco.Pms.Model.Employees;
|
using Marco.Pms.Model.Utilities;
|
||||||
using Marco.Pms.Model.Utilities;
|
|
||||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
@ -28,12 +27,6 @@ namespace Marco.Pms.Model.OrganizationModel
|
|||||||
[ValidateNever]
|
[ValidateNever]
|
||||||
[ForeignKey("OrganizationTypeId")]
|
[ForeignKey("OrganizationTypeId")]
|
||||||
public OrgTypeMaster? OrganizationType { get; set; }
|
public OrgTypeMaster? OrganizationType { get; set; }
|
||||||
|
|
||||||
public Guid AssignedById { get; set; }
|
|
||||||
|
|
||||||
[ValidateNever]
|
|
||||||
[ForeignKey("AssignedById")]
|
|
||||||
public Employee? AssignedBy { get; set; }
|
|
||||||
public DateTime AssignedDate { get; set; }
|
public DateTime AssignedDate { get; set; }
|
||||||
public DateTime? CompletionDate { get; set; }
|
public DateTime? CompletionDate { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
using Marco.Pms.Model.Employees;
|
using Marco.Pms.Model.Utilities;
|
||||||
using Marco.Pms.Model.Utilities;
|
|
||||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
@ -15,11 +14,6 @@ namespace Marco.Pms.Model.OrganizationModel
|
|||||||
public Organization? Organization { get; set; }
|
public Organization? Organization { get; set; }
|
||||||
public double SPRID { get; set; }
|
public double SPRID { get; set; }
|
||||||
public bool IsActive { get; set; } = true;
|
public bool IsActive { get; set; } = true;
|
||||||
public Guid AssignedById { get; set; }
|
|
||||||
|
|
||||||
[ValidateNever]
|
|
||||||
[ForeignKey("AssignedById")]
|
|
||||||
public Employee? AssignedBy { get; set; }
|
|
||||||
public DateTime AssignedDate { get; set; }
|
public DateTime AssignedDate { get; set; }
|
||||||
public DateTime? ReassignedDate { get; set; }
|
public DateTime? ReassignedDate { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,19 +0,0 @@
|
|||||||
using Marco.Pms.Model.ViewModels.Activities;
|
|
||||||
using Marco.Pms.Model.ViewModels.Master;
|
|
||||||
|
|
||||||
namespace Marco.Pms.Model.ViewModels.Organization
|
|
||||||
{
|
|
||||||
public class ProjectOrganizationVM
|
|
||||||
{
|
|
||||||
public Guid Id { get; set; }
|
|
||||||
public string? Name { get; set; }
|
|
||||||
public string? Email { get; set; }
|
|
||||||
public string? ContactPerson { get; set; }
|
|
||||||
public double SPRID { get; set; }
|
|
||||||
public string? logoImage { get; set; }
|
|
||||||
public DateTime AssignedDate { get; set; }
|
|
||||||
public BasicEmployeeVM? AssignedBy { get; set; }
|
|
||||||
public ServiceMasterVM? Service { get; set; }
|
|
||||||
public DateTime? CompletionDate { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -19,7 +19,6 @@ using Microsoft.AspNetCore.Authorization;
|
|||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.SignalR;
|
using Microsoft.AspNetCore.SignalR;
|
||||||
using Microsoft.CodeAnalysis;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
@ -34,7 +33,7 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
{
|
{
|
||||||
|
|
||||||
private readonly ApplicationDbContext _context;
|
private readonly ApplicationDbContext _context;
|
||||||
private readonly IServiceScopeFactory _serviceScopeFactory;
|
private readonly IServiceScopeFactory _serviceScope;
|
||||||
private readonly UserManager<ApplicationUser> _userManager;
|
private readonly UserManager<ApplicationUser> _userManager;
|
||||||
private readonly IEmailSender _emailSender;
|
private readonly IEmailSender _emailSender;
|
||||||
private readonly EmployeeHelper _employeeHelper;
|
private readonly EmployeeHelper _employeeHelper;
|
||||||
@ -50,7 +49,7 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
private readonly Guid organizationId;
|
private readonly Guid organizationId;
|
||||||
|
|
||||||
|
|
||||||
public EmployeeController(IServiceScopeFactory serviceScopeFactory,
|
public EmployeeController(IServiceScopeFactory serviceScope,
|
||||||
UserManager<ApplicationUser> userManager,
|
UserManager<ApplicationUser> userManager,
|
||||||
IEmailSender emailSender,
|
IEmailSender emailSender,
|
||||||
ApplicationDbContext context,
|
ApplicationDbContext context,
|
||||||
@ -64,7 +63,7 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
IMapper mapper,
|
IMapper mapper,
|
||||||
GeneralHelper generalHelper)
|
GeneralHelper generalHelper)
|
||||||
{
|
{
|
||||||
_serviceScopeFactory = serviceScopeFactory;
|
_serviceScope = serviceScope;
|
||||||
_context = context;
|
_context = context;
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
_emailSender = emailSender;
|
_emailSender = emailSender;
|
||||||
@ -120,8 +119,9 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("list/{projectId?}")]
|
[HttpGet]
|
||||||
public async Task<IActionResult> GetEmployeesByProjectAsync(Guid? projectId, [FromQuery] bool showInactive = false)
|
[Route("list/{projectid?}")]
|
||||||
|
public async Task<IActionResult> GetEmployeesByProject(Guid? projectid, [FromQuery] bool ShowInactive)
|
||||||
{
|
{
|
||||||
// Step 1: Validate incoming request model state
|
// Step 1: Validate incoming request model state
|
||||||
if (!ModelState.IsValid)
|
if (!ModelState.IsValid)
|
||||||
@ -135,111 +135,55 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid data", errors, 400));
|
return BadRequest(ApiResponse<object>.ErrorResponse("Invalid data", errors, 400));
|
||||||
}
|
}
|
||||||
|
|
||||||
List<EmployeeVM> result = new List<EmployeeVM>();
|
// Step 2: Get logged-in employee
|
||||||
try
|
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
|
_logger.LogInfo("GetEmployeesByProject called by EmployeeId: {EmployeeId}, ProjectId: {ProjectId}, ShowInactive: {ShowInactive}",
|
||||||
|
loggedInEmployee.Id, projectid ?? Guid.Empty, ShowInactive);
|
||||||
|
|
||||||
|
// Step 3: Fetch project access and permissions
|
||||||
|
var projectIds = await _projectServices.GetMyProjectIdsAsync(tenantId, loggedInEmployee);
|
||||||
|
|
||||||
|
var hasViewAllEmployeesPermission = await _permission.HasPermission(PermissionsMaster.ViewAllEmployees, loggedInEmployee.Id);
|
||||||
|
var hasViewTeamMembersPermission = await _permission.HasPermission(PermissionsMaster.ViewTeamMembers, loggedInEmployee.Id);
|
||||||
|
|
||||||
|
List<EmployeeVM> result = new();
|
||||||
|
|
||||||
|
// Step 4: Determine access level and fetch employees accordingly
|
||||||
|
if (hasViewAllEmployeesPermission || projectid != null)
|
||||||
{
|
{
|
||||||
// Dependency injection scope for services
|
result = await _employeeHelper.GetEmployeeByProjectId(tenantId, projectid, ShowInactive);
|
||||||
using var scope = _serviceScopeFactory.CreateScope();
|
_logger.LogInfo("Employee list fetched using full access or specific project.");
|
||||||
|
}
|
||||||
|
else if (hasViewTeamMembersPermission && !ShowInactive)
|
||||||
|
{
|
||||||
|
var employeeIds = await _context.ProjectAllocations
|
||||||
|
.Where(pa => projectIds.Contains(pa.ProjectId) && pa.IsActive && pa.TenantId == tenantId)
|
||||||
|
.Select(pa => pa.EmployeeId)
|
||||||
|
.Distinct()
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
// Step 2: Get logged-in employee details
|
var employees = await _context.Employees
|
||||||
var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
.Include(fp => fp.JobRole)
|
||||||
_logger.LogInfo("GetEmployeesByProject called. EmployeeId: {EmployeeId}, ProjectId: {ProjectId}, showInactive: {ShowInactive}",
|
.Where(e => employeeIds.Contains(e.Id) && e.JobRole != null && e.IsActive && e.TenantId == tenantId)
|
||||||
loggedInEmployee.Id, projectId ?? Guid.Empty, showInactive);
|
|
||||||
|
|
||||||
// Step 3: Fetch permissions concurrently
|
|
||||||
var viewAllTask = Task.Run(async () =>
|
|
||||||
{
|
|
||||||
var _permission = scope.ServiceProvider.GetRequiredService<PermissionServices>();
|
|
||||||
return await _permission.HasPermission(PermissionsMaster.ViewAllEmployees, loggedInEmployee.Id);
|
|
||||||
});
|
|
||||||
var viewTeamTask = Task.Run(async () =>
|
|
||||||
{
|
|
||||||
var _permission = scope.ServiceProvider.GetRequiredService<PermissionServices>();
|
|
||||||
return await _permission.HasPermission(PermissionsMaster.ViewTeamMembers, loggedInEmployee.Id);
|
|
||||||
});
|
|
||||||
|
|
||||||
await Task.WhenAll(viewAllTask, viewTeamTask);
|
|
||||||
|
|
||||||
var hasViewAllEmployeesPermission = viewAllTask.Result;
|
|
||||||
var hasViewTeamMembersPermission = viewTeamTask.Result;
|
|
||||||
|
|
||||||
List<Employee> employees = new List<Employee>();
|
|
||||||
|
|
||||||
// Step 4: Query based on permission
|
|
||||||
if (hasViewAllEmployeesPermission && !projectId.HasValue)
|
|
||||||
{
|
|
||||||
// OrganizationId needs to be retrieved from loggedInEmployee or context based on your app's structure
|
|
||||||
var employeeQuery = _context.Employees
|
|
||||||
.AsNoTracking() // Optimize EF query for read-only operation[web:1][web:13][web:18]
|
|
||||||
.Include(e => e.JobRole)
|
|
||||||
.Where(e => e.OrganizationId == organizationId);
|
|
||||||
|
|
||||||
employeeQuery = showInactive
|
|
||||||
? employeeQuery.Where(e => !e.IsActive)
|
|
||||||
: employeeQuery.Where(e => e.IsActive);
|
|
||||||
|
|
||||||
employees = await employeeQuery.ToListAsync();
|
|
||||||
_logger.LogInfo("Employee list fetched with full access. Count: {Count}", employees.Count);
|
|
||||||
}
|
|
||||||
else if (hasViewTeamMembersPermission && !showInactive && !projectId.HasValue)
|
|
||||||
{
|
|
||||||
// Only active team members with limited permission
|
|
||||||
var projectIds = await _projectServices.GetMyProjectIdsAsync(tenantId, loggedInEmployee);
|
|
||||||
|
|
||||||
employees = await _context.ProjectAllocations
|
|
||||||
.AsNoTracking()
|
|
||||||
.Include(pa => pa.Employee)
|
|
||||||
.ThenInclude(e => e!.JobRole)
|
|
||||||
.Where(pa =>
|
|
||||||
projectIds.Contains(pa.ProjectId)
|
|
||||||
&& pa.IsActive
|
|
||||||
&& pa.Employee != null
|
|
||||||
&& pa.Employee.IsActive
|
|
||||||
&& pa.TenantId == tenantId)
|
|
||||||
.Select(pa => pa.Employee!)
|
|
||||||
.Distinct()
|
.Distinct()
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
_logger.LogInfo("Employee list fetched with limited access (active only). Count: {Count}", employees.Count);
|
result = employees.Select(e => e.ToEmployeeVMFromEmployee()).ToList();
|
||||||
}
|
|
||||||
|
|
||||||
// If a specific projectId is provided, override employee fetching to ensure strict project context
|
|
||||||
if (projectId.HasValue)
|
|
||||||
{
|
|
||||||
employees = await _context.ProjectAllocations
|
|
||||||
.AsNoTracking()
|
|
||||||
.Include(pa => pa.Employee)
|
|
||||||
.ThenInclude(e => e!.JobRole)
|
|
||||||
.Where(pa =>
|
|
||||||
pa.ProjectId == projectId
|
|
||||||
&& pa.IsActive
|
|
||||||
&& pa.Employee != null
|
|
||||||
&& pa.Employee.IsActive
|
|
||||||
&& pa.TenantId == tenantId)
|
|
||||||
.Select(pa => pa.Employee!)
|
|
||||||
.Distinct()
|
|
||||||
.ToListAsync();
|
|
||||||
|
|
||||||
_logger.LogInfo("Employee list fetched for specific project. ProjectId: {ProjectId}. Count: {Count}",
|
|
||||||
projectId, employees.Count);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 5: Map to view model
|
|
||||||
result = employees.Select(e => _mapper.Map<EmployeeVM>(e)).Distinct().ToList();
|
|
||||||
|
|
||||||
_logger.LogInfo("Employees successfully fetched. EmployeeId: {EmployeeId} for ProjectId: {ProjectId}. Final Count: {Count}",
|
|
||||||
loggedInEmployee.Id, projectId ?? Guid.Empty, result.Count);
|
|
||||||
|
|
||||||
|
_logger.LogInfo("Employee list fetched using limited access (active only).");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.LogWarning("Access denied for EmployeeId: {EmployeeId} - insufficient permissions.", loggedInEmployee.Id);
|
||||||
return Ok(ApiResponse<object>.SuccessResponse(result, "Filter applied.", 200));
|
return Ok(ApiResponse<object>.SuccessResponse(result, "Filter applied.", 200));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
// Step 6: Error logging and response[web:6]
|
|
||||||
_logger.LogError(ex, "Exception occurred while getting the list of employees");
|
|
||||||
return StatusCode(500, ApiResponse<object>.ErrorResponse("Internal server error. Please try again later.", null, 500));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Step 5: Log and return results
|
||||||
|
_logger.LogInfo("Employees fetched successfully by EmployeeId: {EmployeeId} for ProjectId: {ProjectId}. Count: {Count}",
|
||||||
|
loggedInEmployee.Id, projectid ?? Guid.Empty, result.Count);
|
||||||
|
|
||||||
|
return Ok(ApiResponse<object>.SuccessResponse(result, "Filter applied.", 200));
|
||||||
|
}
|
||||||
|
|
||||||
[HttpGet("basic")]
|
[HttpGet("basic")]
|
||||||
public async Task<IActionResult> GetEmployeesByProjectBasic(Guid? projectId, [FromQuery] string? searchString)
|
public async Task<IActionResult> GetEmployeesByProjectBasic(Guid? projectId, [FromQuery] string? searchString)
|
||||||
@ -913,7 +857,7 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
[HttpDelete("{id}")]
|
[HttpDelete("{id}")]
|
||||||
public async Task<IActionResult> SuspendEmployee(Guid id, [FromQuery] bool active = false)
|
public async Task<IActionResult> SuspendEmployee(Guid id, [FromQuery] bool active = false)
|
||||||
{
|
{
|
||||||
using var scope = _serviceScopeFactory.CreateScope();
|
using var scope = _serviceScope.CreateScope();
|
||||||
|
|
||||||
Guid tenantId = _userHelper.GetTenantId();
|
Guid tenantId = _userHelper.GetTenantId();
|
||||||
var LoggedEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
var LoggedEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
|
|||||||
@ -357,7 +357,6 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
SPRID = organization.SPRID,
|
SPRID = organization.SPRID,
|
||||||
AssignedDate = DateTime.UtcNow,
|
AssignedDate = DateTime.UtcNow,
|
||||||
IsActive = true,
|
IsActive = true,
|
||||||
AssignedById = loggedInEmployee.Id,
|
|
||||||
TenantId = project.TenantId
|
TenantId = project.TenantId
|
||||||
};
|
};
|
||||||
_context.TenantOrgMappings.Add(newServiceProviderTenantMapping);
|
_context.TenantOrgMappings.Add(newServiceProviderTenantMapping);
|
||||||
@ -366,21 +365,20 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
List<ProjectOrgMapping> projectOrgMappings = new List<ProjectOrgMapping>();
|
List<ProjectOrgMapping> projectOrgMappings = new List<ProjectOrgMapping>();
|
||||||
List<ProjectServiceMapping> projectServiceMappings = new List<ProjectServiceMapping>();
|
List<ProjectServiceMapping> projectServiceMappings = new List<ProjectServiceMapping>();
|
||||||
|
|
||||||
if (isPMC && model.OrganizationTypeId != ServiceProvider && model.OrganizationTypeId != SubContractorProvider)
|
|
||||||
{
|
|
||||||
return StatusCode(403, ApiResponse<object>.ErrorResponse("Access Denied", "You don't have access to assign this type of organization", 403));
|
|
||||||
}
|
|
||||||
if (isServiceProvider && model.OrganizationTypeId == ServiceProvider)
|
|
||||||
{
|
|
||||||
return StatusCode(403, ApiResponse<object>.ErrorResponse("Access Denied", "You don't have access to assign this type of organization", 403));
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var serviceId in model.ServiceIds)
|
foreach (var serviceId in model.ServiceIds)
|
||||||
{
|
{
|
||||||
var service = await _context.ServiceMasters.FirstOrDefaultAsync(s => s.Id == serviceId);
|
if (isPMC && model.OrganizationTypeId != ServiceProvider && model.OrganizationTypeId != SubContractorProvider)
|
||||||
if (service == null)
|
|
||||||
{
|
{
|
||||||
return NotFound(ApiResponse<object>.ErrorResponse("Service not found", "Service not found in database", 404));
|
continue;
|
||||||
|
}
|
||||||
|
if (isServiceProvider && model.OrganizationTypeId == ServiceProvider)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var isServiceExist = await _context.ServiceMasters.AnyAsync(s => s.Id == serviceId);
|
||||||
|
if (!isServiceExist)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
var projectService = projectServices.FirstOrDefault(ps => ps.ServiceId == serviceId);
|
var projectService = projectServices.FirstOrDefault(ps => ps.ServiceId == serviceId);
|
||||||
if (projectService == null)
|
if (projectService == null)
|
||||||
@ -405,17 +403,14 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
OrganizationTypeId = model.OrganizationTypeId,
|
OrganizationTypeId = model.OrganizationTypeId,
|
||||||
ParentOrganizationId = model.ParentOrganizationId ?? loggedInEmployee.OrganizationId,
|
ParentOrganizationId = model.ParentOrganizationId ?? loggedInEmployee.OrganizationId,
|
||||||
AssignedDate = DateTime.UtcNow,
|
AssignedDate = DateTime.UtcNow,
|
||||||
AssignedById = loggedInEmployee.Id,
|
|
||||||
TenantId = project.TenantId
|
TenantId = project.TenantId
|
||||||
};
|
};
|
||||||
var projectOrganization = projectOrganizations
|
var projectOrganization = projectOrganizations
|
||||||
.FirstOrDefault(po => po.ProjectService != null && po.ProjectService.ProjectId == project.Id && po.ProjectService.ServiceId == serviceId
|
.FirstOrDefault(po => po.ProjectService != null && po.ProjectService.ProjectId == project.Id && po.ProjectService.ServiceId == serviceId);
|
||||||
&& po.OrganizationId == model.OrganizationId);
|
if (projectOrganization == null)
|
||||||
if (projectOrganization != null)
|
|
||||||
{
|
{
|
||||||
return StatusCode(409, ApiResponse<object>.ErrorResponse("Organization is already assigned to this project", "Organization is already assigned to this project", 409));
|
projectOrgMappings.Add(projectOrgMapping);
|
||||||
}
|
}
|
||||||
projectOrgMappings.Add(projectOrgMapping);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (projectServiceMappings.Any())
|
if (projectServiceMappings.Any())
|
||||||
@ -500,7 +495,6 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
SPRID = organization.SPRID,
|
SPRID = organization.SPRID,
|
||||||
AssignedDate = DateTime.UtcNow,
|
AssignedDate = DateTime.UtcNow,
|
||||||
IsActive = true,
|
IsActive = true,
|
||||||
AssignedById = loggedInEmployee.Id,
|
|
||||||
TenantId = tenantId
|
TenantId = tenantId
|
||||||
};
|
};
|
||||||
_context.TenantOrgMappings.Add(newServiceProviderTenantMapping);
|
_context.TenantOrgMappings.Add(newServiceProviderTenantMapping);
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
|
|
||||||
using AutoMapper;
|
|
||||||
using Marco.Pms.DataAccess.Data;
|
using Marco.Pms.DataAccess.Data;
|
||||||
using Marco.Pms.Model.Employees;
|
using Marco.Pms.Model.Employees;
|
||||||
using Marco.Pms.Model.Mapper;
|
using Marco.Pms.Model.Mapper;
|
||||||
@ -14,12 +13,10 @@ namespace MarcoBMS.Services.Helpers
|
|||||||
{
|
{
|
||||||
private readonly ApplicationDbContext _context;
|
private readonly ApplicationDbContext _context;
|
||||||
private readonly ILoggingService _logger;
|
private readonly ILoggingService _logger;
|
||||||
private readonly IMapper _mapper;
|
public EmployeeHelper(ApplicationDbContext context, ILoggingService logger)
|
||||||
public EmployeeHelper(ApplicationDbContext context, ILoggingService logger, IMapper mapper)
|
|
||||||
{
|
{
|
||||||
_context = context;
|
_context = context;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_mapper = mapper;
|
|
||||||
}
|
}
|
||||||
public async Task<Employee> GetEmployeeByID(Guid EmployeeID)
|
public async Task<Employee> GetEmployeeByID(Guid EmployeeID)
|
||||||
{
|
{
|
||||||
@ -75,36 +72,38 @@ namespace MarcoBMS.Services.Helpers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<EmployeeVM>> GetEmployeeByProjectId(Guid organizationId, Guid tenantId, Guid? projectId, bool ShowInActive)
|
public async Task<List<EmployeeVM>> GetEmployeeByProjectId(Guid tenantId, Guid? projectId, bool ShowInActive)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
List<Employee> employees = new List<Employee>();
|
List<EmployeeVM> result = new List<EmployeeVM>();
|
||||||
if (projectId.HasValue)
|
if (projectId.HasValue)
|
||||||
{
|
{
|
||||||
employees = await _context.ProjectAllocations
|
var employeeIds = await _context.ProjectAllocations
|
||||||
.Include(pa => pa.Employee)
|
.Where(pa => projectId == pa.ProjectId && pa.IsActive && pa.TenantId == tenantId)
|
||||||
.ThenInclude(e => e!.JobRole)
|
.Select(pa => pa.EmployeeId)
|
||||||
.Where(pa => projectId == pa.ProjectId && pa.IsActive && pa.TenantId == tenantId && pa.Employee != null && pa.Employee.IsActive)
|
.Distinct()
|
||||||
.Select(pa => pa.Employee!)
|
.ToListAsync();
|
||||||
|
|
||||||
|
var employees = await _context.Employees
|
||||||
|
.Include(fp => fp.JobRole)
|
||||||
|
.Where(e => employeeIds.Contains(e.Id) && e.JobRole != null && e.IsActive && e.TenantId == tenantId)
|
||||||
.Distinct()
|
.Distinct()
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
result = employees.Select(e => e.ToEmployeeVMFromEmployee()).ToList();
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (ShowInActive)
|
else if (ShowInActive)
|
||||||
{
|
{
|
||||||
employees = await _context.Employees
|
result = await _context.Employees.Where(c => c.TenantId == tenantId && c.IsActive == false).Include(fp => fp.JobRole)
|
||||||
.Include(fp => fp.JobRole)
|
.Select(c => c.ToEmployeeVMFromEmployee()).ToListAsync();
|
||||||
.Where(c => c.OrganizationId == organizationId && c.IsActive == false)
|
|
||||||
.ToListAsync();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
employees = await _context.Employees
|
result = await _context.Employees.Where(c => c.TenantId == tenantId && c.IsActive == true).Include(fp => fp.JobRole)
|
||||||
.Include(fp => fp.JobRole)
|
.Select(c => c.ToEmployeeVMFromEmployee()).ToListAsync();
|
||||||
.Where(c => c.OrganizationId == organizationId && c.IsActive == true)
|
|
||||||
.ToListAsync();
|
|
||||||
}
|
}
|
||||||
var result = employees.Select(e => _mapper.Map<EmployeeVM>(e)).Distinct().ToList();
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|||||||
@ -2261,25 +2261,12 @@ namespace Marco.Pms.Services.Service
|
|||||||
|
|
||||||
var projectOrgMapping = await _context.ProjectOrgMappings
|
var projectOrgMapping = await _context.ProjectOrgMappings
|
||||||
.Include(po => po.ProjectService)
|
.Include(po => po.ProjectService)
|
||||||
.ThenInclude(ps => ps!.Service)
|
|
||||||
.Include(po => po.Organization)
|
.Include(po => po.Organization)
|
||||||
.Where(po => po.ProjectService != null && po.ProjectService.ProjectId == projectId && po.TenantId == tenantId)
|
.Where(po => po.ProjectService != null && po.ProjectService.ProjectId == projectId && po.TenantId == tenantId)
|
||||||
.Distinct()
|
.Distinct()
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
var response = projectOrgMapping.Where(po => po.Organization != null).Select(po => new ProjectOrganizationVM
|
var response = projectOrgMapping.Select(po => _mapper.Map<OrganizationVM>(po.Organization)).ToList();
|
||||||
{
|
|
||||||
Id = po.Organization!.Id,
|
|
||||||
Name = po.Organization.Name,
|
|
||||||
Email = po.Organization.Email,
|
|
||||||
ContactPerson = po.Organization.ContactPerson,
|
|
||||||
SPRID = po.Organization.SPRID,
|
|
||||||
logoImage = po.Organization.logoImage,
|
|
||||||
AssignedBy = _mapper.Map<BasicEmployeeVM>(po.AssignedBy),
|
|
||||||
Service = _mapper.Map<ServiceMasterVM>(po.ProjectService!.Service),
|
|
||||||
AssignedDate = po.AssignedDate,
|
|
||||||
CompletionDate = po.CompletionDate
|
|
||||||
}).ToList();
|
|
||||||
|
|
||||||
return ApiResponse<object>.SuccessResponse(response, "Successfully fetched the list of organization assigned to the project", 200);
|
return ApiResponse<object>.SuccessResponse(response, "Successfully fetched the list of organization assigned to the project", 200);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user