Files
Backend-Api/CompanyManagment.EFCore/Repository/RollCallRepository.cs
2024-08-29 15:00:22 +03:30

363 lines
15 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.RollCall;
using Microsoft.EntityFrameworkCore;
namespace CompanyManagment.EFCore.Repository;
public class RollCallRepository : RepositoryBase<long, RollCall>, IRollCallRepository
{
private readonly CompanyContext _context;
public RollCallRepository(CompanyContext context) : base(context)
{
_context = context;
}
public EditRollCall GetByEmployeeIdAndWorkshopId(long employeeId, long workshopId)
{
throw new NotImplementedException();
}
public EditRollCall GetById(long id)
{
throw new NotImplementedException();
}
public List<RollCallViewModel> GetCurrentDay(RollCallSearchModel searchModel)
{
//PersonnelCode = _context.PersonnelCodeSet.FirstOrDefault(e => e.EmployeeId == x.EmployeeId && e.WorkshopId == x.WorkshopId).PersonnelCode.ToString(),
var rawQuery = _context.RollCalls.Where(x => x.WorkshopId == searchModel.WorkshopId && x.StartDate >= DateTime.Now.Date).Select(x => new RollCallViewModel()
{
EmployeeId = x.EmployeeId,
WorkshopId = x.WorkshopId,
EmployeeFullName = x.EmployeeFullName,
Id = x.id,
Month = x.Month,
Year = x.Year,
StartDate = x.StartDate,
EndDate = x.EndDate,
PersonnelCode = _context.PersonnelCodeSet
.FirstOrDefault(a => a.EmployeeId == x.EmployeeId && a.WorkshopId == x.WorkshopId).PersonnelCode
.ToString(),
});
var groupedQuery = rawQuery.GroupBy(x => x.EmployeeId).Select(x => new RollCallViewModel()
{
EmployeeId = x.First().EmployeeId,
WorkshopId = x.First().WorkshopId,
EmployeeFullName = x.First().EmployeeFullName,
Id = x.First().Id,
Month = x.First().Month,
Year = x.First().Year,
RollCallTimesList = x.Select(d => new RollCallTimeViewModel()
{
StartDate = d.StartDate != null ? d.StartDate.Value.ToString("HH:mm") : "--:--",
EndDate = d.EndDate != null ? d.EndDate.Value.ToString("HH:mm") : "--:--"
}).ToList(),
PersonnelCode = x.First().PersonnelCode,
}).AsEnumerable();
var orderedEnum = groupedQuery.OrderBy(x => Convert.ToInt32(x.PersonnelCode));
var query = orderedEnum.Select(x => new RollCallViewModel()
{
EmployeeId = x.EmployeeId,
WorkshopId = x.WorkshopId,
EndDate = x.EndDate,
StartDate = x.StartDate,
Id = x.Id,
EmployeeFullName = x.EmployeeFullName,
Month = x.Month,
Year = x.Year,
RollCallTimesList = x.RollCallTimesList,
PersonnelCode = x.PersonnelCode
});
return query.Skip(searchModel.PageIndex).Take(30).ToList();
}
public List<RollCallViewModel> Search(RollCallSearchModel searchModel)
{
throw new NotImplementedException();
}
#region Pooya
//حضور غیاب فیش حقوقی
public List<CheckoutDailyRollCallViewModel> GetEmployeeRollCallsForDuration(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.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()
{
StartDate = null,
EndDate = null,
DateTimeGr = x.Date.Date,
DayOfWeek = x.Date.DayOfWeek.ToString(),
TotalWorkingHours = Convert.ToString(0),
RollCallDateFa = x.Date.ToFarsi()
});
var presentDays = rollCalls.GroupBy(x => x.StartDate!.Value.Date).Select(x => new CheckoutDailyRollCallViewModel()
{
StartDate = x.Min(y => y.StartDate)!.Value.ToString("HH:mm"),
EndDate = x.Max(y => y.EndDate)!.Value.ToString("HH:mm"),
TotalWorkingHours = x.Where(y => y.EndDate != null).Sum(y => (y.EndDate - y.StartDate)!.Value.TotalHours).ToString("F2"),
DayOfWeek = x.Key.DayOfWeek.DayOfWeeKToPersian(),
RollCallDateFa = x.Key.Date.ToFarsi(),
DateTimeGr = x.Key.Date,
IsSliced = x.Count() > 1
});
return presentDays.Concat(absentRecords).OrderBy(x => x.DateTimeGr).ToList();
}
//سوابق حضور غیاب کارگاه
public RollCallsByDateViewModel GetWorkshopRollCallHistory(RollCallSearchModel searchModel)
{
//initialize
DateTime searchDurationStart = DateTime.Now.AddDays(-1).Date;
DateTime searchDurationEnd = searchDurationStart.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))
{
searchDurationStart = searchModel.StarDateFa.ToGeorgianDateTime().Date;
searchDurationEnd = searchModel.EndDateFa.ToGeorgianDateTime().AddDays(-1).Date;
}
else
if (!string.IsNullOrWhiteSpace(searchModel.ExactDateFa))
{
searchDurationStart = searchModel.ExactDateFa.ToGeorgianDateTime().Date;
searchDurationEnd = searchModel.ExactDateFa.ToGeorgianDateTime().AddDays(-1).Date;
}
if (searchDurationStart < searchDurationEnd)
return new();
DateTime dateIndex = searchDurationStart.AddDays(-1 * (searchModel.DateIndex)).Date;
if (dateIndex <= searchDurationEnd)
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.EndDate.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));
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));
var rollCallsList = rollCallsQuery.ToList();
var activatedEmployeesList = activeEmployeesQuery.ToList();
var leavesList = leavesQuery.ToList();
rollCallsList = rollCallsList.Where(x => leavesList.All(y => y.EmployeeId != x.EmployeeId)).ToList();
var result = new RollCallsByDateViewModel()
{
DateGr = 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:ss"),
StartDate = y.StartDate!.Value.ToString("HH:mm:ss")
}),
TotalWorkingHours = employeeRollCallsForDate.Sum(y => (y.EndDate!.Value - y.StartDate!.Value).TotalHours),
PersonnelCode = personnelCodeList.FirstOrDefault(y => y.EmployeeId == x.EmployeeId)?.PersonnelCode.ToString()
};
})
};
return result;
}
//گزارش آنلاین حضور غیاب کارگاه
public CurrentDayRollCall GetWorkshopCurrentDayRollCalls(long workshopId)
{
//get today's roll calls
var rollCallsQuery = _context.RollCalls.Where(x =>
x.WorkshopId == workshopId && x.StartDate.Value.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 >= DateTime.Now.Date && x.StartLeave.Date <= DateTime.Now.Date &&
x.IsAccepted && (x.LeaveType == "استعلاجی" || (x.LeaveType == "استحقاقی" && x.PaidLeaveType == "روزانه")));
//get currently working employees with leftWork table
var workingEmployees =
_context.LeftWorkList.Where(x => x.WorkshopId == workshopId && x.StartWorkDate < DateTime.Now.Date && x.LeftWorkDate.Date > DateTime.Now.Date);
//get activated employees
var activeEmployees =
_context.RollCallEmployees.Include(x => x.EmployeesStatus)
.Where(x => x.WorkshopId == workshopId && x.EmployeesStatus.Any(y =>
y.StartDate.Date <= DateTime.Now.Date &&
y.EndDate.Date >= DateTime.Now.Date));
var mustBePresent = activeEmployees.Where(x => !leaves.Any(y => y.EmployeeId == x.EmployeeId) &&
workingEmployees.Any(y => y.EmployeeId == x.EmployeeId));
//filter roll calls for active and currently working employees only
var filteredRollCallQuery = rollCallsQuery.Where(x => mustBePresent
.Any(y => x.EmployeeId == y.EmployeeId))
.Where(x => workingEmployees.Any(y => y.EmployeeId == x.EmployeeId)).ToList();
//presents list is ready
var presentEmployees = filteredRollCallQuery.GroupBy(x => x.EmployeeId).Select(x => new RollCallViewModel()
{
EmployeeFullName = x.FirstOrDefault()!.EmployeeFullName,
EmployeeId = x.FirstOrDefault()!.EmployeeId,
TotalWorkingHours = x.Where(y => y.EndDate != null).Sum(y => (y.EndDate!.Value - y.StartDate!.Value).TotalHours),
RollCallTimesList = x.Select(y => new RollCallTimeViewModel()
{
StartDate = y.StartDate!.Value.ToString("HH:mm:ss"),
EndDate = y.EndDate?.ToString("HH:mm:ss")
}).ToList()
}).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 = _context.LeaveList.Where(x =>
x.EndLeave.Date >= DateTime.Now.Date && x.StartLeave.Date <= DateTime.Now.Date &&
x.WorkshopId == workshopId && (x.LeaveType == "استعلاجی" || (x.LeaveType == "استحقاقی" && x.PaidLeaveType == "روزانه")))
.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 = _context.PersonnelCodeSet
.FirstOrDefault(y => y.EmployeeId == x.EmployeeId && y.WorkshopId == workshopId)
!.PersonnelCode.ToString(),
EmployeeId = x.EmployeeId,
EmployeeFullName = x.EmployeeFullName,
Reason = employeesWithLeave.Any(y => y.EmployeeId == x.EmployeeId)
? employeesWithLeave.FirstOrDefault(y => y.EmployeeId == x.EmployeeId)!.LeaveType
: ""
}).ToList();
return new CurrentDayRollCall()
{
AbsentEmployees = absentsViewModel.ToList(),
PresentEmployees = presentEmployees.ToList()
};
}
#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;
}
}
}