Organization_Management #142

Merged
ashutosh.nehete merged 92 commits from Organization_Management into main 2025-09-30 09:05:14 +00:00
8 changed files with 6344 additions and 36 deletions
Showing only changes of commit d6145ee0ba - Show all commits

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,92 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Marco.Pms.DataAccess.Migrations
{
/// <inheritdoc />
public partial class Added_Forgin_Key_For_Approver : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Attendes_Employees_EmployeeID",
table: "Attendes");
migrationBuilder.RenameColumn(
name: "EmployeeID",
table: "Attendes",
newName: "EmployeeId");
migrationBuilder.RenameColumn(
name: "ApprovedBy",
table: "Attendes",
newName: "ApprovedById");
migrationBuilder.RenameIndex(
name: "IX_Attendes_EmployeeID",
table: "Attendes",
newName: "IX_Attendes_EmployeeId");
migrationBuilder.CreateIndex(
name: "IX_Attendes_ApprovedById",
table: "Attendes",
column: "ApprovedById");
migrationBuilder.AddForeignKey(
name: "FK_Attendes_Employees_ApprovedById",
table: "Attendes",
column: "ApprovedById",
principalTable: "Employees",
principalColumn: "Id");
migrationBuilder.AddForeignKey(
name: "FK_Attendes_Employees_EmployeeId",
table: "Attendes",
column: "EmployeeId",
principalTable: "Employees",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Attendes_Employees_ApprovedById",
table: "Attendes");
migrationBuilder.DropForeignKey(
name: "FK_Attendes_Employees_EmployeeId",
table: "Attendes");
migrationBuilder.DropIndex(
name: "IX_Attendes_ApprovedById",
table: "Attendes");
migrationBuilder.RenameColumn(
name: "EmployeeId",
table: "Attendes",
newName: "EmployeeID");
migrationBuilder.RenameColumn(
name: "ApprovedById",
table: "Attendes",
newName: "ApprovedBy");
migrationBuilder.RenameIndex(
name: "IX_Attendes_EmployeeId",
table: "Attendes",
newName: "IX_Attendes_EmployeeID");
migrationBuilder.AddForeignKey(
name: "FK_Attendes_Employees_EmployeeID",
table: "Attendes",
column: "EmployeeID",
principalTable: "Employees",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
}
}
}

View File

@ -172,7 +172,7 @@ namespace Marco.Pms.DataAccess.Migrations
b.Property<int>("Activity") b.Property<int>("Activity")
.HasColumnType("int"); .HasColumnType("int");
b.Property<Guid?>("ApprovedBy") b.Property<Guid?>("ApprovedById")
.HasColumnType("char(36)"); .HasColumnType("char(36)");
b.Property<DateTime>("AttendanceDate") b.Property<DateTime>("AttendanceDate")
@ -185,7 +185,7 @@ namespace Marco.Pms.DataAccess.Migrations
b.Property<DateTime>("Date") b.Property<DateTime>("Date")
.HasColumnType("datetime(6)"); .HasColumnType("datetime(6)");
b.Property<Guid>("EmployeeID") b.Property<Guid>("EmployeeId")
.HasColumnType("char(36)"); .HasColumnType("char(36)");
b.Property<DateTime?>("InTime") b.Property<DateTime?>("InTime")
@ -205,7 +205,9 @@ namespace Marco.Pms.DataAccess.Migrations
b.HasKey("Id"); b.HasKey("Id");
b.HasIndex("EmployeeID"); b.HasIndex("ApprovedById");
b.HasIndex("EmployeeId");
b.HasIndex("TenantId"); b.HasIndex("TenantId");
@ -4701,7 +4703,11 @@ namespace Marco.Pms.DataAccess.Migrations
{ {
b.HasOne("Marco.Pms.Model.Employees.Employee", "Approver") b.HasOne("Marco.Pms.Model.Employees.Employee", "Approver")
.WithMany() .WithMany()
.HasForeignKey("EmployeeID") .HasForeignKey("ApprovedById");
b.HasOne("Marco.Pms.Model.Employees.Employee", "Employee")
.WithMany()
.HasForeignKey("EmployeeId")
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
.IsRequired(); .IsRequired();
@ -4713,6 +4719,8 @@ namespace Marco.Pms.DataAccess.Migrations
b.Navigation("Approver"); b.Navigation("Approver");
b.Navigation("Employee");
b.Navigation("Tenant"); b.Navigation("Tenant");
}); });

View File

@ -1,8 +1,8 @@
using System.ComponentModel.DataAnnotations.Schema; using Marco.Pms.Model.Dtos.Attendance;
using Marco.Pms.Model.Dtos.Attendance;
using Marco.Pms.Model.Employees; 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;
namespace Marco.Pms.Model.AttendanceModule namespace Marco.Pms.Model.AttendanceModule
{ {
@ -10,9 +10,11 @@ namespace Marco.Pms.Model.AttendanceModule
{ {
public Guid Id { get; set; } public Guid Id { get; set; }
public string Comment { get; set; } = string.Empty; public string Comment { get; set; } = string.Empty;
public Guid EmployeeID { get; set; } public Guid EmployeeId { get; set; }
[ForeignKey("EmployeeId")]
[ValidateNever]
public Employee? Employee { get; set; }
public DateTime Date { get; set; } public DateTime Date { get; set; }
public Guid ProjectID { get; set; } public Guid ProjectID { get; set; }
@ -22,8 +24,9 @@ namespace Marco.Pms.Model.AttendanceModule
public bool IsApproved { get; set; } public bool IsApproved { get; set; }
public ATTENDANCE_MARK_TYPE Activity { get; set; } public ATTENDANCE_MARK_TYPE Activity { get; set; }
public Guid? ApprovedBy { get; set; } public Guid? ApprovedById { get; set; }
[ForeignKey("EmployeeID")]
[ForeignKey("ApprovedById")]
[ValidateNever] [ValidateNever]
public Employee? Approver { get; set; } public Employee? Approver { get; set; }
} }

View File

@ -107,7 +107,7 @@ namespace MarcoBMS.Services.Controllers
_logger.LogWarning("The employee Id sent by user is empty"); _logger.LogWarning("The employee Id sent by user is empty");
return BadRequest(ApiResponse<object>.ErrorResponse("Employee ID is required and must not be Empty.", "Employee ID is required and must not be empty.", 400)); return BadRequest(ApiResponse<object>.ErrorResponse("Employee ID is required and must not be Empty.", "Employee ID is required and must not be empty.", 400));
} }
List<Attendance> attendances = await _context.Attendes.Where(c => c.EmployeeID == employeeId && c.TenantId == TenantId && c.AttendanceDate.Date >= fromDate && c.AttendanceDate.Date <= toDate).ToListAsync(); List<Attendance> attendances = await _context.Attendes.Where(c => c.EmployeeId == employeeId && c.TenantId == TenantId && c.AttendanceDate.Date >= fromDate && c.AttendanceDate.Date <= toDate).ToListAsync();
Employee? employee = await _context.Employees.Include(e => e.JobRole).FirstOrDefaultAsync(e => e.Id == employeeId && e.TenantId == TenantId && e.IsActive); Employee? employee = await _context.Employees.Include(e => e.JobRole).FirstOrDefaultAsync(e => e.Id == employeeId && e.TenantId == TenantId && e.IsActive);
List<EmployeeAttendanceVM> results = new List<EmployeeAttendanceVM>(); List<EmployeeAttendanceVM> results = new List<EmployeeAttendanceVM>();
@ -211,7 +211,7 @@ namespace MarcoBMS.Services.Controllers
CheckOutTime = attendance.OutTime, CheckOutTime = attendance.OutTime,
Activity = attendance.Activity Activity = attendance.Activity
}; };
teamMember = projectteam.Find(x => x.EmployeeId == attendance.EmployeeID); teamMember = projectteam.Find(x => x.EmployeeId == attendance.EmployeeId);
if (teamMember != null) if (teamMember != null)
{ {
result1.EmployeeAvatar = null; result1.EmployeeAvatar = null;
@ -239,7 +239,7 @@ namespace MarcoBMS.Services.Controllers
else if (hasSelfAttendancePermission) else if (hasSelfAttendancePermission)
{ {
List<Attendance> lstAttendances = await _context.Attendes List<Attendance> lstAttendances = await _context.Attendes
.Where(c => c.ProjectID == projectId && c.EmployeeID == LoggedInEmployee.Id && c.AttendanceDate.Date >= fromDate.Date && c.AttendanceDate.Date <= toDate.Date && c.TenantId == tenantId) .Where(c => c.ProjectID == projectId && c.EmployeeId == LoggedInEmployee.Id && c.AttendanceDate.Date >= fromDate.Date && c.AttendanceDate.Date <= toDate.Date && c.TenantId == tenantId)
.ToListAsync(); .ToListAsync();
var projectAllocationQuery = _context.ProjectAllocations var projectAllocationQuery = _context.ProjectAllocations
@ -372,7 +372,7 @@ namespace MarcoBMS.Services.Controllers
foreach (Attendance attende in lstAttendance) foreach (Attendance attende in lstAttendance)
{ {
var teamMember = projectteam.Find(m => m.EmployeeId == attende.EmployeeID); var teamMember = projectteam.Find(m => m.EmployeeId == attende.EmployeeId);
if (teamMember != null && teamMember.Employee != null && teamMember.Employee.JobRole != null) if (teamMember != null && teamMember.Employee != null && teamMember.Employee.JobRole != null)
{ {
var result1 = new EmployeeAttendanceVM() var result1 = new EmployeeAttendanceVM()
@ -382,7 +382,7 @@ namespace MarcoBMS.Services.Controllers
CheckOutTime = attende.OutTime, CheckOutTime = attende.OutTime,
Activity = attende.Activity, Activity = attende.Activity,
EmployeeAvatar = null, EmployeeAvatar = null,
EmployeeId = attende.EmployeeID, EmployeeId = attende.EmployeeId,
FirstName = teamMember.Employee.FirstName, FirstName = teamMember.Employee.FirstName,
LastName = teamMember.Employee.LastName, LastName = teamMember.Employee.LastName,
JobRoleName = teamMember.Employee.JobRole.Name, JobRoleName = teamMember.Employee.JobRole.Name,
@ -476,7 +476,7 @@ namespace MarcoBMS.Services.Controllers
{ {
attendance.IsApproved = true; attendance.IsApproved = true;
attendance.Activity = ATTENDANCE_MARK_TYPE.REGULARIZE; attendance.Activity = ATTENDANCE_MARK_TYPE.REGULARIZE;
attendance.ApprovedBy = currentEmployee.Id; attendance.ApprovedById = currentEmployee.Id;
// do nothing // do nothing
} }
else if (recordAttendanceDot.Action == ATTENDANCE_MARK_TYPE.REGULARIZE_REJECT) else if (recordAttendanceDot.Action == ATTENDANCE_MARK_TYPE.REGULARIZE_REJECT)
@ -497,7 +497,7 @@ namespace MarcoBMS.Services.Controllers
attendance.AttendanceDate = recordAttendanceDot.Date; attendance.AttendanceDate = recordAttendanceDot.Date;
// attendance.Activity = recordAttendanceDot.Action; // attendance.Activity = recordAttendanceDot.Action;
attendance.Comment = recordAttendanceDot.Comment; attendance.Comment = recordAttendanceDot.Comment;
attendance.EmployeeID = recordAttendanceDot.EmployeeID; attendance.EmployeeId = recordAttendanceDot.EmployeeID;
attendance.ProjectID = recordAttendanceDot.ProjectID; attendance.ProjectID = recordAttendanceDot.ProjectID;
attendance.Date = DateTime.UtcNow; attendance.Date = DateTime.UtcNow;
@ -572,7 +572,7 @@ namespace MarcoBMS.Services.Controllers
var name = $"{vm.FirstName} {vm.LastName}"; var name = $"{vm.FirstName} {vm.LastName}";
await _firebase.SendAttendanceMessageAsync(attendance.ProjectID, name, recordAttendanceDot.Action, attendance.EmployeeID, TenantId); await _firebase.SendAttendanceMessageAsync(attendance.ProjectID, name, recordAttendanceDot.Action, attendance.EmployeeId, TenantId);
}); });
@ -640,7 +640,7 @@ namespace MarcoBMS.Services.Controllers
TenantId = tenantId, TenantId = tenantId,
AttendanceDate = recordAttendanceDot.Date, AttendanceDate = recordAttendanceDot.Date,
Comment = recordAttendanceDot.Comment, Comment = recordAttendanceDot.Comment,
EmployeeID = recordAttendanceDot.EmployeeID, EmployeeId = recordAttendanceDot.EmployeeID,
ProjectID = recordAttendanceDot.ProjectID, ProjectID = recordAttendanceDot.ProjectID,
Date = DateTime.UtcNow, Date = DateTime.UtcNow,
InTime = finalDateTime, InTime = finalDateTime,
@ -781,7 +781,7 @@ namespace MarcoBMS.Services.Controllers
var name = $"{vm.FirstName} {vm.LastName}"; var name = $"{vm.FirstName} {vm.LastName}";
await _firebase.SendAttendanceMessageAsync(attendance.ProjectID, name, recordAttendanceDot.Action, attendance.EmployeeID, tenantId); await _firebase.SendAttendanceMessageAsync(attendance.ProjectID, name, recordAttendanceDot.Action, attendance.EmployeeId, tenantId);
}); });
@ -856,7 +856,7 @@ namespace MarcoBMS.Services.Controllers
//var member = emp.Where(e => e.Id == teamMember.EmployeeId); //var member = emp.Where(e => e.Id == teamMember.EmployeeId);
var attendance = lstAttendance.Find(x => x.EmployeeID == teamMember.EmployeeId) ?? new Attendance(); var attendance = lstAttendance.Find(x => x.EmployeeId == teamMember.EmployeeId) ?? new Attendance();
if (attendance != null) if (attendance != null)
{ {
result1.Id = attendance.Id; result1.Id = attendance.Id;
@ -881,7 +881,7 @@ namespace MarcoBMS.Services.Controllers
// This query fetches the employee's project allocation and their attendance in a single trip. // This query fetches the employee's project allocation and their attendance in a single trip.
Attendance lstAttendance = await _context.Attendes Attendance lstAttendance = await _context.Attendes
.FirstOrDefaultAsync(c => c.ProjectID == projectId && c.EmployeeID == employeeId && c.AttendanceDate.Date == forDate && c.TenantId == tenantId) ?? new Attendance(); .FirstOrDefaultAsync(c => c.ProjectID == projectId && c.EmployeeId == employeeId && c.AttendanceDate.Date == forDate && c.TenantId == tenantId) ?? new Attendance();
var projectAllocationQuery = _context.ProjectAllocations var projectAllocationQuery = _context.ProjectAllocations
.Include(pa => pa.Employee) .Include(pa => pa.Employee)

View File

@ -235,7 +235,7 @@ namespace Marco.Pms.Services.Controllers
int inTodays = await _context.Attendes int inTodays = await _context.Attendes
.Where(a => a.InTime >= today && a.InTime < tomorrow && .Where(a => a.InTime >= today && a.InTime < tomorrow &&
finalProjectIds.Contains(a.ProjectID)) finalProjectIds.Contains(a.ProjectID))
.Select(a => a.EmployeeID) .Select(a => a.EmployeeId)
.Distinct() .Distinct()
.CountAsync(); .CountAsync();
@ -354,7 +354,7 @@ namespace Marco.Pms.Services.Controllers
Guid tenantId = _userHelper.GetTenantId(); Guid tenantId = _userHelper.GetTenantId();
var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
var attendance = await _context.Attendes.Where(a => a.EmployeeID == LoggedInEmployee.Id && a.TenantId == tenantId).ToListAsync(); var attendance = await _context.Attendes.Where(a => a.EmployeeId == LoggedInEmployee.Id && a.TenantId == tenantId).ToListAsync();
if (attendance.Any()) if (attendance.Any())
{ {
var pendingRegularization = attendance.Where(a => a.Activity == ATTENDANCE_MARK_TYPE.REQUEST_REGULARIZE).ToList().Count; var pendingRegularization = attendance.Where(a => a.Activity == ATTENDANCE_MARK_TYPE.REQUEST_REGULARIZE).ToList().Count;
@ -395,12 +395,12 @@ namespace Marco.Pms.Services.Controllers
var employeeIds = projectAllocation.Select(p => p.EmployeeId).Distinct().ToList(); var employeeIds = projectAllocation.Select(p => p.EmployeeId).Distinct().ToList();
List<Employee>? employees = await _context.Employees.Where(e => employeeIds.Contains(e.Id)).ToListAsync(); List<Employee>? employees = await _context.Employees.Where(e => employeeIds.Contains(e.Id)).ToListAsync();
var attendances = await _context.Attendes.Where(a => employeeIds.Contains(a.EmployeeID) && a.ProjectID == projectId && a.InTime.HasValue && a.InTime.Value.Date == currentDate.Date).ToListAsync(); var attendances = await _context.Attendes.Where(a => employeeIds.Contains(a.EmployeeId) && a.ProjectID == projectId && a.InTime.HasValue && a.InTime.Value.Date == currentDate.Date).ToListAsync();
List<EmployeeAttendanceVM> employeeAttendanceVMs = new List<EmployeeAttendanceVM>(); List<EmployeeAttendanceVM> employeeAttendanceVMs = new List<EmployeeAttendanceVM>();
foreach (var attendance in attendances) foreach (var attendance in attendances)
{ {
Employee? employee = employees.FirstOrDefault(e => e.Id == attendance.EmployeeID); Employee? employee = employees.FirstOrDefault(e => e.Id == attendance.EmployeeId);
if (employee != null) if (employee != null)
{ {
EmployeeAttendanceVM employeeAttendanceVM = new EmployeeAttendanceVM EmployeeAttendanceVM employeeAttendanceVM = new EmployeeAttendanceVM
@ -579,7 +579,7 @@ namespace Marco.Pms.Services.Controllers
.ToList(); .ToList();
int presentCount = attendances int presentCount = attendances
.Count(a => employeeIds.Contains(a.EmployeeID) && a.InTime!.Value.Date == date); .Count(a => employeeIds.Contains(a.EmployeeId) && a.InTime!.Value.Date == date);
overviewList.Add(new AttendanceOverviewVM overviewList.Add(new AttendanceOverviewVM
{ {

View File

@ -1098,7 +1098,7 @@ namespace MarcoBMS.Services.Controllers
} }
} }
} }
var attendance = await _context.Attendes.Where(a => a.EmployeeID == employee.Id && (a.OutTime == null || a.Activity == ATTENDANCE_MARK_TYPE.REQUEST_REGULARIZE)).ToListAsync(); var attendance = await _context.Attendes.Where(a => a.EmployeeId == employee.Id && (a.OutTime == null || a.Activity == ATTENDANCE_MARK_TYPE.REQUEST_REGULARIZE)).ToListAsync();
if (attendance.Count != 0) if (attendance.Count != 0)
{ {
_logger.LogWarning("Employee with ID {EmployeeId} have any pending check-out or regularization requests", employee.Id); _logger.LogWarning("Employee with ID {EmployeeId} have any pending check-out or regularization requests", employee.Id);

View File

@ -71,11 +71,11 @@ namespace Marco.Pms.Services.Helpers
.Where(a => a.ProjectID == projectId && a.InTime != null && a.InTime.Value.Date == reportDate) .Where(a => a.ProjectID == projectId && a.InTime != null && a.InTime.Value.Date == reportDate)
.ToListAsync(); .ToListAsync();
var checkedInEmployeeIds = attendances.Select(a => a.EmployeeID).Distinct().ToHashSet(); var checkedInEmployeeIds = attendances.Select(a => a.EmployeeId).Distinct().ToHashSet();
var checkoutPendingIds = attendances.Where(a => a.OutTime == null).Select(a => a.EmployeeID).Distinct().ToHashSet(); var checkoutPendingIds = attendances.Where(a => a.OutTime == null).Select(a => a.EmployeeId).Distinct().ToHashSet();
var regularizationIds = attendances var regularizationIds = attendances
.Where(a => a.Activity == ATTENDANCE_MARK_TYPE.REQUEST_REGULARIZE) .Where(a => a.Activity == ATTENDANCE_MARK_TYPE.REQUEST_REGULARIZE)
.Select(a => a.EmployeeID).Distinct().ToHashSet(); .Select(a => a.EmployeeId).Distinct().ToHashSet();
// Preload buildings, floors, areas // Preload buildings, floors, areas
List<BuildingMongoDBVM>? buildings = null; List<BuildingMongoDBVM>? buildings = null;
@ -246,7 +246,7 @@ namespace Marco.Pms.Services.Helpers
// Attendance details // Attendance details
var performedAttendance = attendances.Select(att => var performedAttendance = attendances.Select(att =>
{ {
var alloc = projectAllocations.FirstOrDefault(p => p.EmployeeId == att.EmployeeID); var alloc = projectAllocations.FirstOrDefault(p => p.EmployeeId == att.EmployeeId);
var role = jobRoles.FirstOrDefault(r => r.Id == alloc?.JobRoleId); var role = jobRoles.FirstOrDefault(r => r.Id == alloc?.JobRoleId);
string name = $"{alloc?.Employee?.FirstName ?? ""} {alloc?.Employee?.LastName ?? ""}"; string name = $"{alloc?.Employee?.FirstName ?? ""} {alloc?.Employee?.LastName ?? ""}";
@ -326,11 +326,11 @@ namespace Marco.Pms.Services.Helpers
.Where(a => a.ProjectID == projectId && a.InTime != null && a.InTime.Value.Date == reportDate) .Where(a => a.ProjectID == projectId && a.InTime != null && a.InTime.Value.Date == reportDate)
.ToListAsync(); .ToListAsync();
var checkedInEmployeeIds = attendances.Select(a => a.EmployeeID).Distinct().ToHashSet(); var checkedInEmployeeIds = attendances.Select(a => a.EmployeeId).Distinct().ToHashSet();
var checkoutPendingIds = attendances.Where(a => a.OutTime == null).Select(a => a.EmployeeID).Distinct().ToHashSet(); var checkoutPendingIds = attendances.Where(a => a.OutTime == null).Select(a => a.EmployeeId).Distinct().ToHashSet();
var regularizationIds = attendances var regularizationIds = attendances
.Where(a => a.Activity == ATTENDANCE_MARK_TYPE.REQUEST_REGULARIZE) .Where(a => a.Activity == ATTENDANCE_MARK_TYPE.REQUEST_REGULARIZE)
.Select(a => a.EmployeeID).Distinct().ToHashSet(); .Select(a => a.EmployeeId).Distinct().ToHashSet();
// Preload buildings, floors, areas // Preload buildings, floors, areas
List<BuildingMongoDBVM>? buildings = null; List<BuildingMongoDBVM>? buildings = null;
@ -501,7 +501,7 @@ namespace Marco.Pms.Services.Helpers
// Attendance details // Attendance details
var performedAttendance = attendances.Select(att => var performedAttendance = attendances.Select(att =>
{ {
var alloc = projectAllocations.FirstOrDefault(p => p.EmployeeId == att.EmployeeID); var alloc = projectAllocations.FirstOrDefault(p => p.EmployeeId == att.EmployeeId);
var role = jobRoles.FirstOrDefault(r => r.Id == alloc?.JobRoleId); var role = jobRoles.FirstOrDefault(r => r.Id == alloc?.JobRoleId);
string name = $"{alloc?.Employee?.FirstName ?? ""} {alloc?.Employee?.LastName ?? ""}"; string name = $"{alloc?.Employee?.FirstName ?? ""} {alloc?.Employee?.LastName ?? ""}";