Files
Backend-Api/CompanyManagment.EFCore/Repository/RollCallRepository.cs

743 lines
33 KiB
C#

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using _0_Framework.Application;
using _0_Framework.InfraStructure;
using Company.Domain.RollCallAgg;
using CompanyManagment.App.Contracts.HolidayItem;
using CompanyManagment.App.Contracts.RollCall;
using MD.PersianDateTime.Standard;
using Microsoft.EntityFrameworkCore;
namespace CompanyManagment.EFCore.Repository;
public class RollCallRepository : RepositoryBase<long, RollCall>, IRollCallRepository
{
private readonly CompanyContext _context;
private readonly IHolidayItemApplication _holidayItemApplication;
public RollCallRepository(CompanyContext context, IHolidayItemApplication holidayItemApplication) : base(context)
{
_context = context;
_holidayItemApplication = holidayItemApplication;
}
public EditRollCall GetByEmployeeIdAndWorkshopId(long employeeId, long workshopId)
{
throw new NotImplementedException();
}
public EditRollCall GetById(long id)
{
throw new NotImplementedException();
}
public List<RollCallViewModel> Search(RollCallSearchModel searchModel)
{
throw new NotImplementedException();
}
#region Pooya
public List<RollCallsByDateViewModel> GetRollCallWorkFlowsCutByBgService(long workshopId, DateTime start, DateTime end)
{
var rollCalls = _context.RollCalls
.Where(x => x.RollCallModifyType == RollCallModifyType.CutByBgService && x.WorkshopId == workshopId &&
x.StartDate.Value.Date >= start.Date && x.StartDate.Value.Date <= end.Date).ToList();
var names = _context.RollCallEmployees.Where(x => x.WorkshopId == workshopId)
.Select(x => new { x.EmployeeId, x.WorkshopId, x.EmployeeFullName }).ToList();
return rollCalls.GroupBy(x => x.StartDate!.Value.Date)
.Select(g => new RollCallsByDateViewModel()
{
DateGr = g.Key,
DateFa = g.Key.ToFarsi(),
ActiveEmployees = g.Select(x => new RollCallViewModel()
{
EmployeeId = x.EmployeeId,
EmployeeFullName = names.FirstOrDefault(y => y.EmployeeId == x.EmployeeId)?.EmployeeFullName ?? "",
WorkshopId = x.WorkshopId,
Id = x.id,
StartDate = x.StartDate,
EndDate = x.EndDate
})
})
.ToList();
}
public int GetCountCutRollCallByBgService(long accId, long workshopId)
{
return _context.RollCalls.Where(x =>
x.WorkshopId == workshopId && x.RollCallModifyType == RollCallModifyType.CutByBgService)
.GroupBy(x => x.StartDate!.Value.Date)
.Count();
}
public IEnumerable<RollCallViewModel> GetNotSlicedRollCallsByWorkshopId(long workshopId, DateTime durationStart, DateTime durationEnd)
{
if (durationEnd.Date >= DateTime.Now.Date)
durationEnd = DateTime.Now.AddDays(-1).Date;
var names = _context.RollCallEmployees.Where(x => x.WorkshopId == workshopId).ToList();
var rollCalls = _context.RollCalls.Where(x => x.WorkshopId == workshopId &&
x.StartDate.Value.Date >= durationStart && x.StartDate.Value.Date <= durationEnd && x.EndDate.HasValue).ToList();
if (rollCalls == null || !rollCalls.Any())
return new List<RollCallViewModel>();
return rollCalls.GroupBy(x => x.StartDate.Value.Date).SelectMany(x =>
x.GroupBy(y => y.EmployeeId).Where(y => y.Count() == 1)
.SelectMany(y => y)).Select(x => new RollCallViewModel
{
Id = x.id,
StartDate = x.StartDate.Value,
EndDate = x.EndDate.Value,
EmployeeId = x.EmployeeId,
DateGr = x.StartDate.Value.Date,
EmployeeFullName = names.FirstOrDefault(y => y.EmployeeId == x.EmployeeId)?.EmployeeFullName ?? ""
});
}
//حضور غیاب فیش حقوقی
public List<CheckoutDailyRollCallViewModel> GetEmployeeRollCallsForMonth(long employeeId, long workshopId, DateTime startMonthDay, DateTime endMonthDay)
{
var rollCalls = _context.RollCalls.Where(x =>
x.EmployeeId == employeeId && x.WorkshopId == workshopId && x.StartDate != null && x.EndDate != null && x.RollCallModifyType != RollCallModifyType.Undefined &&
x.StartDate.Value.Date >= startMonthDay && x.StartDate.Value.Date <= endMonthDay).ToList();
var year = Convert.ToInt32(startMonthDay.ToFarsi().Substring(0, 4));
var month = Convert.ToInt32(startMonthDay.ToFarsi().Substring(5, 2));
var firstDayOfCurrentMonth = new DateTime(year, month, 1, new PersianCalendar());
if (month == 12)
{
year += 1;
month = 1;
}
else
month += 1;
var nextMonthDate = new DateTime(year, month, 1, new PersianCalendar());
var lastDayOfCurrentMonth = nextMonthDate.AddDays(-1);
int dateRange = (int)(lastDayOfCurrentMonth - firstDayOfCurrentMonth).TotalDays + 1;
//all the dates from start to end, to be compared with present days to get absent dates
var completeDaysList = Enumerable.Range(0, dateRange).Select(offset => startMonthDay.AddDays(offset).Date);
var absentRecords = completeDaysList
.ExceptBy(rollCalls.Select(x => x.StartDate!.Value.Date), y => y.Date.Date)
.Select(x => new CheckoutDailyRollCallViewModel()
{
StartDate1 = null,
EndDate1 = null,
DateTimeGr = x.Date.Date,
DayOfWeek = x.Date.DayOfWeek.ToString(),
RollCallDateFa = x.Date.ToFarsi()
});
var presentDays = rollCalls.GroupBy(x => x.StartDate!.Value.Date).Select(x =>
{
var orderedRollcalls = x.OrderBy(y => y.StartDate!.Value);
return new CheckoutDailyRollCallViewModel()
{
StartDate1 = orderedRollcalls.FirstOrDefault().StartDate.Value.ToString("HH:mm"),
EndDate1 = orderedRollcalls.FirstOrDefault().EndDate.Value.ToString("HH:mm"),
StartDate2 = orderedRollcalls.Skip(1).FirstOrDefault()?.StartDate?.ToString("HH:mm") ?? "",
EndDate2 = orderedRollcalls.Skip(1).FirstOrDefault()?.EndDate?.ToString("HH:mm") ?? "",
TotalhourseSpan =
new TimeSpan(x.Where(y => y.EndDate != null).Sum(y => (y.EndDate - y.StartDate)!.Value.Ticks)),
DayOfWeek = x.Key.DayOfWeek.DayOfWeeKToPersian(),
RollCallDateFa = x.Key.Date.ToFarsi(),
DateTimeGr = x.Key.Date,
IsSliced = x.Count() > 1
};
});
presentDays = presentDays.Select(x => new CheckoutDailyRollCallViewModel
{
StartDate1 = x.StartDate1,
EndDate1 = x.EndDate1,
EndDate2 = x.EndDate2,
StartDate2 = x.StartDate2,
TotalWorkingHours = $"{(int)(x.TotalhourseSpan.TotalHours)}:{x.TotalhourseSpan.Minutes.ToString("00")}",
DayOfWeek = x.DayOfWeek,
RollCallDateFa = x.RollCallDateFa,
DateTimeGr = x.DateTimeGr,
IsSliced = x.IsSliced,
});
return presentDays.Concat(absentRecords).OrderBy(x => x.DateTimeGr).ToList();
}
//جستجوی سوابق حضور غیاب بر اساس کارمند
public EmployeeRollCallsByMonthViewModel GetEmployeeRollCallsHistory(long employeeId, long workshopId,
DateTime? startDateTime, DateTime? endDateTime, DateTime? exactDateTime, DateTime? dateIndex)
{
//get RollCallEmployee and RollCallEmployeeStatus for that employee in that workshop
var employeeRollCallStatuses = _context.RollCallEmployees.Include(x => x.EmployeesStatus)
.FirstOrDefault(x => x.EmployeeId == employeeId && x.WorkshopId == workshopId);
//if none was found return empty
if (employeeRollCallStatuses == null)
return new();
//this list will have all the months which employee was active in
var activeMonths = new List<PersianDateTime>();
//filling the list
foreach (var status in employeeRollCallStatuses.EmployeesStatus)
{
var persianEndDate = new PersianDateTime(status.EndDate.Date);
var persianStartDate = new PersianDateTime(status.StartDate.Date);
var persianStartFirstDayOfMonth = new PersianDateTime(persianStartDate.Year, persianStartDate.Month, 1);
for (PersianDateTime start = persianStartFirstDayOfMonth; start <= persianEndDate && start < PersianDateTime.Today.Date; start = start.AddMonths(1))
{
activeMonths.Add(start);
}
}
//might have duplicated records, this is the reason for distinct
var activeMonthsList = activeMonths.OrderByDescending(x => x.Date).Distinct().ToList();
PersianDateTime startSearch = new();
PersianDateTime endSearch = new();
//if search has these parameters below
if (startDateTime.HasValue && endDateTime.HasValue)
{
//change them to persian date time and save them
startSearch = new PersianDateTime(startDateTime.Value);
endSearch = new PersianDateTime(endDateTime.Value);
//get the months that include these dates
activeMonthsList = activeMonthsList.Where(x => x.Year >= startSearch.Year && x.Month >= startSearch.Month && x.Year <= endSearch.Year && x.Month <= endSearch.Month).ToList();
}
//if exact datetime is given
if (exactDateTime.HasValue)
{
//start and end will be the same date
startSearch = new PersianDateTime(exactDateTime.Value);
endSearch = startSearch;
//get the
activeMonthsList = activeMonthsList.Where(x => x.Year >= startSearch.Year && x.Month >= startSearch.Month && x.Year <= endSearch.Year && x.Month <= endSearch.Month).ToList();
}
if (dateIndex != null)
{
var persianDateIndex = new PersianDateTime(dateIndex.Value);
var dateIndexFirstOfMonth = persianDateIndex.AddDays(-(persianDateIndex.Day - 1));
activeMonthsList = activeMonthsList.Where(x => dateIndexFirstOfMonth >= x).ToList();
}
if (!activeMonthsList.Any()) return new();
//get the last month which user was active in
PersianDateTime selectedMonthPersian = activeMonthsList.First();
DateTime selectedMonthFirstDay = selectedMonthPersian;
DateTime nextMonthFirstDay = selectedMonthPersian.AddMonths(1);
var statusesOfMonth = employeeRollCallStatuses.EmployeesStatus.Where(x => x.EndDate >= selectedMonthFirstDay &&
x.StartDate < nextMonthFirstDay);
var leavesQuery =
_context.LeaveList.Where(x => (x.LeaveType == "استعلاجی" || (x.LeaveType == "استحقاقی" && x.PaidLeaveType == "روزانه")) &&
x.IsAccepted &&
x.EndLeave >= selectedMonthFirstDay && x.StartLeave < nextMonthFirstDay && x.WorkshopId == workshopId && x.EmployeeId == employeeId);
//var rollCalls = _context.RollCalls.Where(x =>
// x.EmployeeId == employeeId && !leavesQuery.Any(y =>
// y.StartLeave.Date <= x.StartDate.Value.Date && y.EndLeave.Date >= x.StartDate.Value.Date) &&
// x.WorkshopId == workshopId && x.StartDate != null &&
// x.StartDate >= selectedMonthFirstDay && x.StartDate < nextMonthFirstDay && x.RollCallModifyType != RollCallModifyType.Undefined);
//changeByfarrokhi
#region changeByfarrokhi
var rollCalls = _context.RollCalls.Where(x =>
x.EmployeeId == employeeId &&
x.WorkshopId == workshopId && x.StartDate != null &&
x.StartDate >= selectedMonthFirstDay && x.StartDate < nextMonthFirstDay && x.RollCallModifyType != RollCallModifyType.Undefined);
#endregion
var personnelCode =
_context.PersonnelCodeSet.FirstOrDefault(x => x.EmployeeId == employeeId && x.WorkshopId == workshopId)?.PersonnelCode;
var employeeName = _context.RollCallEmployees.Where(x => x.WorkshopId == workshopId).Select(x => new { x.EmployeeId, x.EmployeeFullName })
.FirstOrDefault(x => x.EmployeeId == employeeId);
var rollCallsList = rollCalls.ToList();
var leavesList = leavesQuery.ToList();
int dateRange = (int)(nextMonthFirstDay - selectedMonthFirstDay).TotalDays;
var todayDate = DateTime.Now.Date;
//all the dates from start to end, to be compared with present days to get absent dates
var completeDaysList = Enumerable.Range(0, dateRange).Select(offset => selectedMonthFirstDay.AddDays(offset).Date).Where(x => x.Date < todayDate);
//if user search range is within a month for example, we dont want 30/31/29 days for month, we want it to be the size of the search range
//user input = 2024/04/15~2024/04/21, output days count is 21-15+1=6 days from 15th to 21st
if (exactDateTime.HasValue || (startDateTime.HasValue && endDateTime.HasValue))
completeDaysList = completeDaysList.Where(x => x.Date >= startSearch.Date && x.Date <= endSearch.Date);
var result = completeDaysList.Where(x => !rollCallsList.Any(y => y.StartDate.Value.Date == x.Date && y.EndDate == null) &&
statusesOfMonth.Any(y => x >= y.StartDate.Date && x <= y.EndDate.Date))
.Select(x =>
{
var leave = leavesList.FirstOrDefault(y => y.EndLeave >= x.Date.Date && y.StartLeave <= x.Date.Date);
return new RollCallViewModel()
{
DateGr = x.Date.Date,
DateFa = x.Date.Date.ToFarsi(),
RollCallTimesList = rollCallsList.Where(y => x.Date.Date == y.StartDate!.Value.Date).Select(y =>
new RollCallTimeViewModel()
{
StartDate = y.StartDate.Value.ToString("HH:mm"),
EndDate = y.EndDate!.Value.ToString("HH:mm")
}),
TotalWorkingHoursSpan = new TimeSpan(rollCallsList.Where(y => x.Date.Date == y.StartDate!.Value.Date)
.Sum(y => (y.EndDate!.Value - y.StartDate.Value).Ticks)),
Reason = leave?.LeaveType ?? "",
HasLeave = (leave?.PaidLeaveType == "روزانه" || leave?.LeaveType == "استعلاجی") ? true : false
};
});
result = result.Select(x => new RollCallViewModel()
{
EmployeeFullName = employeeName.EmployeeFullName,
EmployeeId = employeeId,
PersonnelCode = personnelCode.ToString(),
DateGr = x.DateGr,
DateFa = x.DateFa,
DayOfWeekFa = x.DateGr.DayOfWeek.DayOfWeeKToPersian(),
IsHoliday = _holidayItemApplication.IsHoliday(x.DateGr),
IsAbsent = !x.RollCallTimesList.Any(),
RollCallTimesList = x.RollCallTimesList,
TotalWorkingHours = $"{(int)x.TotalWorkingHoursSpan.TotalHours}:{x.TotalWorkingHoursSpan.Minutes.ToString("00")}",
}).ToList();
return new EmployeeRollCallsByMonthViewModel()
{
PersianMonthName = selectedMonthPersian.ToString("MMMM"),
PersianYear = selectedMonthPersian.ToString("yyyy"),
DateGr = selectedMonthFirstDay,
RollCalls = result.OrderByDescending(x => x.DateGr),
DateIndex = activeMonthsList.Count > 1 ? activeMonthsList.Skip(1).First().ToString("yyyy/MM/dd") : null
};
}
public void AddRange(List<RollCall> rollCalls)
{
_context.RollCalls.AddRange(rollCalls);
}
//سوابق غیبت
public List<RollCallsByDateViewModel> GetWorkshopAbsentHistory(long workshopId, DateTime startSearch, DateTime endSearch)
{
if (endSearch.Date == DateTime.Now.Date)
endSearch = endSearch.AddDays(-1);
//get leaves for workshop that have been activated in dateIndex date
var leavesQuery = _context.LeaveList.Where(x => x.WorkshopId == workshopId &&
x.IsAccepted && (x.LeaveType == "استعلاجی" || (x.LeaveType == "استحقاقی" && x.PaidLeaveType == "روزانه")) &&
x.EndLeave.Date >= startSearch.Date && x.StartLeave.Date <= endSearch.Date);
//roll calls for current workshop where shift start is in dateIndex date (filters today's shifts)
var rollCallsQuery = _context.RollCalls
.Where(x => x.WorkshopId == workshopId && x.StartDate.HasValue &&
x.StartDate.Value.Date >= startSearch.Date && x.StartDate.Value.Date <= endSearch.Date && x.RollCallModifyType != RollCallModifyType.Undefined &&
x.RollCallModifyType != RollCallModifyType.CutByBgService);
//get active employees of workshop in dateIndex date
var activeEmployeesQuery =
_context.RollCallEmployees.Include(x => x.EmployeesStatus)
.Where(x => x.WorkshopId == workshopId && x.EmployeesStatus.Any(y => y.EndDate.Date >= startSearch && y.StartDate.Date <= endSearch));
var rollCallsList = rollCallsQuery.ToList();
var activatedEmployeesList = activeEmployeesQuery.ToList();
var leavesList = leavesQuery.ToList();
int daysCount = (int)((endSearch.Date - startSearch.Date).TotalDays + 1);
List<DateTime> days = Enumerable.Range(0, daysCount).Select(x => startSearch.Date.AddDays(x)).ToList();
List<RollCallsByDateViewModel> result = new();
foreach (var day in days)
{
var item = new RollCallsByDateViewModel()
{
DateGr = day,
DateFa = day.ToFarsi(),
ActiveEmployees = activatedEmployeesList.Where(x => x.EmployeesStatus.Any(y => y.StartDate.Date <= day && y.EndDate.Date >= day) &&
!leavesList.Any(y => y.EmployeeId == x.EmployeeId && y.StartLeave.Date <= day && y.EndLeave.Date >= day) &&
!rollCallsList.Any(rc => rc.EmployeeId == x.EmployeeId && rc.StartDate.Value.Date == day.Date))
.Select(x => new RollCallViewModel()
{
EmployeeId = x.EmployeeId,
EmployeeFullName = x.EmployeeFullName,
Id = x.id,
WorkshopId = x.WorkshopId
}),
IsHoliday = _holidayItemApplication.IsHoliday(day),
IsFriday = day.DayOfWeek == DayOfWeek.Friday
};
result.Add(item);
}
return result;
}
//سوابق حضور غیاب کارگاه
public RollCallsByDateViewModel GetWorkshopRollCallHistory(RollCallSearchModel searchModel)
{
//initialize
DateTime searchDurationEnd = DateTime.Now.AddDays(-1).Date;
DateTime searchDurationStart = searchDurationEnd.AddDays(-16);
//override if user has entered inputs (dates must be validated in the application layer)
if (!string.IsNullOrWhiteSpace(searchModel.StarDateFa) && !string.IsNullOrWhiteSpace(searchModel.StarDateFa))
{
searchDurationEnd = searchModel.EndDateFa.ToGeorgianDateTime().Date;
searchDurationStart = searchModel.StarDateFa.ToGeorgianDateTime().AddDays(-1).Date;
}
else
if (!string.IsNullOrWhiteSpace(searchModel.ExactDateFa))
{
searchDurationEnd = searchModel.ExactDateFa.ToGeorgianDateTime().Date;
searchDurationStart = searchModel.ExactDateFa.ToGeorgianDateTime().AddDays(-1).Date;
}
if (searchDurationEnd < searchDurationStart)
return new();
DateTime dateIndex = searchDurationEnd.AddDays(-1 * (searchModel.DateIndex)).Date;
if (dateIndex <= searchDurationStart)
return new();
//get leaves for workshop that have been activated in dateIndex date
var leavesQuery = _context.LeaveList.Where(x => x.WorkshopId == searchModel.WorkshopId &&
x.IsAccepted && (x.LeaveType == "استعلاجی" || (x.LeaveType == "استحقاقی" && x.PaidLeaveType == "روزانه")) &&
x.EndLeave.Date >= dateIndex && x.StartLeave.Date <= dateIndex);
//roll calls for current workshop where shift start is in dateIndex date (filters today's shifts)
var rollCallsQuery = _context.RollCalls
.Where(x => x.WorkshopId == searchModel.WorkshopId && x.StartDate.HasValue && x.StartDate < DateTime.Now.Date &&
x.StartDate.Value.Date == dateIndex.Date);
//get active employees of workshop in dateIndex date
var activeEmployeesQuery =
_context.RollCallEmployees.Include(x => x.EmployeesStatus)
.Where(x => x.WorkshopId == searchModel.WorkshopId && x.EmployeesStatus.Any(y => y.EndDate.Date >= dateIndex && y.StartDate.Date <= dateIndex)
&& !rollCallsQuery.Any(rc => rc.EmployeeId == x.EmployeeId && !rc.EndDate.HasValue));
if (searchModel.EmployeeId > 0)
{
rollCallsQuery = rollCallsQuery.Where(x => x.EmployeeId == searchModel.EmployeeId);
activeEmployeesQuery = activeEmployeesQuery.Where(x => x.EmployeeId == searchModel.EmployeeId);
leavesQuery = leavesQuery.Where(x => x.EmployeeId == searchModel.EmployeeId);
}
var personnelCodeList =
_context.PersonnelCodeSet.Where(x => activeEmployeesQuery.Any(y => y.EmployeeId == x.EmployeeId && y.WorkshopId == x.WorkshopId));
var activatedEmployeesList = activeEmployeesQuery.ToList();
rollCallsQuery = rollCallsQuery.Where(x => x.EndDate.HasValue);
var rollCallsList = rollCallsQuery.ToList();
var leavesList = leavesQuery.ToList();
rollCallsList = rollCallsList.Where(x => leavesList.All(y => y.EmployeeId != x.EmployeeId)).ToList();
var result = new RollCallsByDateViewModel()
{
DateGr = dateIndex,
DayOfWeekFa = dateIndex.DayOfWeek.DayOfWeeKToPersian(),
IsHoliday = _holidayItemApplication.IsHoliday(dateIndex),
DateFa = dateIndex.ToFarsi(),
ActiveEmployees = activatedEmployeesList.Select(x =>
{
var leave = leavesList.FirstOrDefault(y => y.EmployeeId == x.EmployeeId);
var employeeRollCallsForDate = rollCallsList.Where(y => y.EmployeeId == x.EmployeeId).ToList();
return new RollCallViewModel()
{
EmployeeFullName = x.EmployeeFullName,
EmployeeId = x.EmployeeId,
Reason = leave == null ? "" : $"{leave.LeaveType}-{leave.PaidLeaveType}",
RollCallTimesList = employeeRollCallsForDate.Select(y => new RollCallTimeViewModel()
{
EndDate = y.EndDate!.Value.ToString("HH:mm"),
StartDate = y.StartDate!.Value.ToString("HH:mm")
}),
HasLeave = leave != null,
IsAbsent = !employeeRollCallsForDate.Any(),
TotalWorkingHoursSpan = new TimeSpan(employeeRollCallsForDate.Sum(y => (y.EndDate!.Value - y.StartDate!.Value).Ticks)),
PersonnelCode = personnelCodeList.FirstOrDefault(y => y.EmployeeId == x.EmployeeId)?.PersonnelCode.ToString()
};
})
};
result.ActiveEmployees = result.ActiveEmployees.Select(x => new RollCallViewModel()
{
EmployeeFullName = x.EmployeeFullName,
EmployeeId = x.EmployeeId,
Reason = x.Reason,
RollCallTimesList = x.RollCallTimesList,
HasLeave = x.HasLeave,
IsAbsent = x.IsAbsent,
PersonnelCode = x.PersonnelCode,
TotalWorkingHours = $"{(int)x.TotalWorkingHoursSpan.TotalHours}:{(x.TotalWorkingHoursSpan.Minutes):00}"
});
return result;
}
//گزارش آنلاین حضور غیاب کارگاه
public CurrentDayRollCall GetWorkshopCurrentDayRollCalls(long workshopId)
{
var date = DateTime.Now.Date;
//get active leaves for workshop which are active today and accepted and are either روزانه and استحقاقی or استعلاجی
var leaves = _context.LeaveList
.Where(x =>
(x.WorkshopId == workshopId && x.EndLeave.Date >= date && x.StartLeave.Date <= date && x.IsAccepted) &&
((x.LeaveType == "استعلاجی" || (x.LeaveType == "استحقاقی" && x.PaidLeaveType == "روزانه")) || (x.LeaveType == "استحقاقی" && x.PaidLeaveType == "ساعتی" && x.StartLeave <= DateTime.Now && x.EndLeave >= DateTime.Now))
);
var personnelCodes = _context.PersonnelCodeSet.Where(x => x.WorkshopId == workshopId).ToList();
//get currently working employees with leftWork table
//var workingEmployees =
// _context.LeftWorkList.Where(x => x.WorkshopId == workshopId && x.StartWorkDate < date && x.LeftWorkDate.Date > date);
//get activated employees
var activeEmployees =
_context.RollCallEmployees.Include(x => x.EmployeesStatus)
.Where(x => x.WorkshopId == workshopId && x.IsActiveString == "true" && x.EmployeesStatus.Any(y =>
y.StartDate.Date <= date &&
y.EndDate.Date >= date));
//get today's roll calls
var rollCallsQuery = _context.RollCalls.Where(x =>
x.WorkshopId == workshopId && (x.StartDate.Value.Date == date || x.EndDate == null));
var mustBePresent = activeEmployees.Where(x => !leaves.Any(y => y.EmployeeId == x.EmployeeId));
var filteredRollCallQuery = rollCallsQuery.Where(x => mustBePresent
.Any(y => x.EmployeeId == y.EmployeeId)).ToList();
var nameReferences = activeEmployees.ToList();
//presents list is ready
var presentEmployees = filteredRollCallQuery.GroupBy(x => x.EmployeeId).Select(x => new RollCallViewModel()
{
PersonnelCode = personnelCodes
.FirstOrDefault(y => y.EmployeeId == x.Key)?
.PersonnelCode.ToString(),
EmployeeFullName = nameReferences.FirstOrDefault(y => x.Key == y.EmployeeId).EmployeeFullName,
EmployeeId = x.FirstOrDefault()!.EmployeeId,
TotalWorkingHoursSpan = new TimeSpan(x.Where(y => y.EndDate != null).Sum(y => (y.EndDate!.Value - y.StartDate!.Value).Ticks)),
RollCallTimesList = x.Select(y => new RollCallTimeViewModel()
{
StartDate = y.StartDate!.Value.ToString("HH:mm"),
EndDate = y.EndDate?.ToString("HH:mm")
}).ToList()
});
presentEmployees = presentEmployees.Select(x => new RollCallViewModel()
{
PersonnelCode = x.PersonnelCode,
EmployeeFullName = x.EmployeeFullName,
EmployeeId = x.EmployeeId,
TotalWorkingHours =
$"{(int)x.TotalWorkingHoursSpan.TotalHours}:{x.TotalWorkingHoursSpan.Minutes.ToString("00")}",
RollCallTimesList = x.RollCallTimesList
}).OrderBy(x => x.RollCallTimesList.Any(y => y.EndDate != null)).ToList();
//absent ones are those who are active and not on the roll call list
var absentsQuery = activeEmployees.AsEnumerable()
.ExceptBy(presentEmployees.Select(x => x.EmployeeId), e => e.EmployeeId).ToList();
//get today's active leaves
var employeesWithLeave = leaves.AsEnumerable()
.Where(x => absentsQuery.Any(y => y.EmployeeId == x.EmployeeId))
.Select(x => new { x.EmployeeId, x.LeaveType }).ToList();
//join leave and absents
var absentsViewModel = absentsQuery.Select(x => new AbsentEmployeeViewModel()
{
PersonnelCode = personnelCodes
.FirstOrDefault(y => y.EmployeeId == x.EmployeeId)?
.PersonnelCode.ToString(),
EmployeeId = x.EmployeeId,
EmployeeFullName = nameReferences.FirstOrDefault(y => x.EmployeeId == y.EmployeeId).EmployeeFullName,
HasLeave = employeesWithLeave.Any(y => y.EmployeeId == x.EmployeeId),
Reason = employeesWithLeave.FirstOrDefault(y => y.EmployeeId == x.EmployeeId)?.LeaveType
}).ToList();
return new CurrentDayRollCall()
{
AbsentEmployees = absentsViewModel.ToList(),
PresentEmployees = presentEmployees.OrderByDescending(x => x.RollCallTimesList.Any(y => string.IsNullOrWhiteSpace(y.EndDate)))
.ThenByDescending(x => x.RollCallTimesList.Max(y => y.StartDate)).ToList()
};
}
public void RemoveEmployeeRollCallsInDate(long workshopId, long employeeId, DateTime date)
{
var rollCalls = _context.RollCalls.Where(x => x.WorkshopId == workshopId && x.EmployeeId == employeeId && x.StartDate.Value.Date == date.Date);
if (!rollCalls.Any())
return;
_context.RollCalls.RemoveRange(rollCalls);
}
public List<RollCallViewModel> GetWorkshopEmployeeRollCallsForDate(long workshopId, long employeeId, DateTime date)
{
var names = _context.RollCallEmployees.Where(x => x.WorkshopId == workshopId && x.EmployeeId == employeeId).Select(x => new
{
x.EmployeeId,
x.EmployeeFullName
}).ToList();
var rollcalls = _context.RollCalls
.Where(x => x.WorkshopId == workshopId && x.EmployeeId == employeeId && x.StartDate.Value.Date == date.Date)
.Select(x => new RollCallViewModel()
{
Id = x.id,
StartDate = x.StartDate.Value,
EndDate = x.EndDate.Value,
DateFa = x.StartDate.Value.Date.ToFarsi(),
StartDateFa = x.StartDate.Value.ToFarsi(),
EndDateFa = x.EndDate != null ? x.EndDate.Value.ToFarsi() : null
}).ToList();
return rollcalls.Select(x => new RollCallViewModel()
{
Id = x.Id,
StartDate = x.StartDate,
EndDate = x.EndDate,
StartTimeString = x.StartDate!.Value.ToString("HH:mm"),
EndTimeString = x.EndDate?.ToString("HH:mm"),
DateFa = x.DateFa,
StartDateFa = x.StartDateFa,
EndDateFa = x.EndDateFa,
EmployeeId = names.FirstOrDefault(e => e.EmployeeId == employeeId)!.EmployeeId,
EmployeeFullName = names.FirstOrDefault(e => e.EmployeeId == employeeId)!.EmployeeFullName
}).ToList();
}
public RollCallViewModel GetDetails(long rollCallId)
{
var entity = _context.RollCalls.FirstOrDefault(x => x.id == rollCallId);
if (entity == null)
return null;
var name = _context.RollCallEmployees.FirstOrDefault(x => x.WorkshopId == entity.WorkshopId && x.EmployeeId == entity.EmployeeId).EmployeeFullName;
return new RollCallViewModel
{
WorkshopId = entity.WorkshopId,
EmployeeId = entity.EmployeeId,
StartDate = entity.StartDate.Value,
EndDate = entity.EndDate.Value,
EmployeeFullName = name,
Id = entity.id,
DateGr = entity.StartDate.Value.Date
};
}
#endregion
public long Flag(long employeeId, long workshopId)
{
var checkDate = DateTime.Now.AddDays(-3);
var query = _context.RollCalls
.Where(x => x.EmployeeId == employeeId && x.WorkshopId == workshopId && x.CreationDate >= checkDate);
if (query.Any())
{
var checkLastOne = query.OrderByDescending(x => x.StartDate).FirstOrDefault();
if (checkLastOne != null && checkLastOne.EndDate == null)
return checkLastOne.id;
return 0;
}
else
{
return 0;
}
}
public string CheckRepeat(long employeeId, long workshopId)
{
var validSpan = new TimeSpan(0, 0, 2, 0);
var checkDate = DateTime.Now.AddDays(-3);
var query = _context.RollCalls
.Where(x => x.EmployeeId == employeeId && x.WorkshopId == workshopId && x.CreationDate >= checkDate);
if (query.Any())
{
var checkTime = DateTime.Now;
var checkLastOne = query.OrderByDescending(x => x.StartDate).FirstOrDefault();
if (checkLastOne != null && checkLastOne.EndDate == null && checkLastOne.RollCallModifyType == RollCallModifyType.None)
{
var checkSpan = (DateTime.Now - checkLastOne.StartDate);
if (checkSpan < validSpan)
{
return "IncomRegistred-InvalidOut";
}
}
if (checkLastOne != null && checkLastOne.EndDate != null && checkLastOne.RollCallModifyType == RollCallModifyType.None)
{
var checkSpan = (DateTime.Now - checkLastOne.EndDate);
if (checkSpan < validSpan)
{
return "outRegistred-InvalidIncom";
}
}
return "Valid";
}
else
{
return "Valid";
}
}
}