using _0_Framework.InfraStructure; using AccountMangement.Infrastructure.EFCore; using Company.Domain.EmployeeDocumentItemAgg; using Company.Domain.EmployeeDocumentsAgg; using CompanyManagment.App.Contracts.EmployeeDocuments; using CompanyManagment.App.Contracts.Workshop; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; using _0_Framework.Application; using AccountManagement.Application.Contracts.Media; using Company.Domain.empolyerAgg; using Company.Domain.LeftWorkAgg; using System.Collections; namespace CompanyManagment.EFCore.Repository; public class EmployeeDocumentsRepository : RepositoryBase, IEmployeeDocumentsRepository { private readonly CompanyContext _companyContext; private readonly AccountContext _accountContext; private readonly IEmployerRepository _employerRepository; public EmployeeDocumentsRepository(CompanyContext context, AccountContext accountContext, IEmployerRepository employerRepository) : base(context) { _companyContext = context; _accountContext = accountContext; _employerRepository = employerRepository; } public List GetEmployeeIds(long workshopId) { var query = _companyContext.EmployeeDocuments.Include(x => x.Employee).Where(x => x.WorkshopId == workshopId); return query.Select(x => x.EmployeeId).ToList(); } public EmployeeDocuments GetByEmployeeIdWorkshopId(long employeeId, long workshopId) { return _companyContext.EmployeeDocuments.FirstOrDefault(x => x.EmployeeId == employeeId && x.WorkshopId == workshopId); } public EmployeeDocuments GetByEmployeeIdWorkshopIdWithItems(long employeeId, long workshopId) { return _companyContext.EmployeeDocuments.Include(x => x.EmployeeDocumentItemCollection) .FirstOrDefault(x => x.EmployeeId == employeeId && x.WorkshopId == workshopId); } public EmployeeDocuments GetByIdWithItems(long employeeDocumentsId) { return _companyContext.EmployeeDocuments.Include(x => x.EmployeeDocumentItemCollection) .FirstOrDefault(x => x.id == employeeDocumentsId); } public EmployeeDocumentsViewModel GetViewModelByEmployeeIdWorkshopId(long employeeId, long workshopId) { var entity = _companyContext.EmployeeDocuments.Include(x => x.Employee) .Include(x => x.EmployeeDocumentItemCollection) .FirstOrDefault(x => x.EmployeeId == employeeId && x.WorkshopId == workshopId); if (entity == null) return null; List currentConfirmedDocuments = entity.EmployeeDocumentItemCollection.GroupBy(x => x.DocumentLabel) .Select(x => x.MaxBy(y => y.CreationDate)).Where(x => x.DocumentStatus == DocumentStatus.Confirmed).ToList(); var medias = _accountContext.Medias.Where(x => currentConfirmedDocuments .Any(y => y.MediaId == x.id)) .Select(x => new MediaViewModel { Id = x.id, Path = x.Path }).ToList(); return new EmployeeDocumentsViewModel() { EducationalDegree = GetByLabelAndLoadMedia(currentConfirmedDocuments,medias,DocumentItemLabel.EducationalDegree), IdCardPage1= GetByLabelAndLoadMedia(currentConfirmedDocuments, medias, DocumentItemLabel.IdCardPage1), IdCardPage2 = GetByLabelAndLoadMedia(currentConfirmedDocuments, medias, DocumentItemLabel.IdCardPage2), IdCardPage3 = GetByLabelAndLoadMedia(currentConfirmedDocuments, medias, DocumentItemLabel.IdCardPage3), IdCardPage4 = GetByLabelAndLoadMedia(currentConfirmedDocuments, medias, DocumentItemLabel.IdCardPage4), MilitaryServiceCard = GetByLabelAndLoadMedia(currentConfirmedDocuments, medias, DocumentItemLabel.MilitaryServiceCard), NationalCardRear = GetByLabelAndLoadMedia(currentConfirmedDocuments, medias, DocumentItemLabel.NationalCardRear), NationalCardFront = GetByLabelAndLoadMedia(currentConfirmedDocuments, medias, DocumentItemLabel.NationalCardFront), EmployeePicture= GetByLabelAndLoadMedia(currentConfirmedDocuments, medias, DocumentItemLabel.EmployeePicture), EmployeeFullName = entity.Employee.FullName, Id = entity.id }; } public List SearchEmployeesWithActiveLeftWork(SearchEmployeeDocuments cmd) { //take employeeDocuments for workshop var query = _companyContext.EmployeeDocuments.Include(x => x.Employee).Where(x => x.WorkshopId == cmd.WorkshopId); if (!string.IsNullOrWhiteSpace(cmd.EmployeeName)) { query = query.Where(x => x.Employee.FullName.Contains(cmd.EmployeeName)); } //get leftworks for employees selected var passedLeftWorks = _companyContext.LeftWorkList.Where(x => query.Any(y => y.EmployeeId == x.EmployeeId && y.WorkshopId == x.WorkshopId) && x.LeftWorkDate <= DateTime.Now.Date) .Select(x => x.EmployeeId).AsEnumerable(); var documents = query.Where(x => passedLeftWorks.All(y => x.EmployeeId != y)) .OrderByDescending(x => x.id).Skip(cmd.PageIndex).Take(30).ToList(); var currentDocs = documents.SelectMany(y =>y.EmployeeDocumentItemCollection.Where(z=>z.DocumentStatus != DocumentStatus.Unsubmitted && z.DocumentStatus != DocumentStatus.Deleted)).Select(y => y.MediaId).ToList(); //get medias for current documents of employees var medias = _accountContext.Medias.Where(x => currentDocs.Contains(x.id)).Select(x => new MediaViewModel() { Id = x.id,Path=x.Path }).ToList(); return documents.Select(x => { var employeeCurrentConfirmedDocuments = x.EmployeeDocumentItemCollection.Where(y => x.EmployeeId == y.EmployeeId).ToList(); return new EmployeeDocumentsViewModel { Id = x.id, EmployeeId = x.EmployeeId, EmployeeFullName = x.Employee.FullName, IdCardPage1 = GetByLabelAndLoadMedia(employeeCurrentConfirmedDocuments, medias, DocumentItemLabel.IdCardPage1), IdCardPage2 = GetByLabelAndLoadMedia(employeeCurrentConfirmedDocuments, medias, DocumentItemLabel.IdCardPage2), IdCardPage3 = GetByLabelAndLoadMedia(employeeCurrentConfirmedDocuments, medias, DocumentItemLabel.IdCardPage3), IdCardPage4 = GetByLabelAndLoadMedia(employeeCurrentConfirmedDocuments, medias, DocumentItemLabel.IdCardPage4), EducationalDegree = GetByLabelAndLoadMedia(employeeCurrentConfirmedDocuments, medias, DocumentItemLabel.EducationalDegree), NationalCardFront = GetByLabelAndLoadMedia(employeeCurrentConfirmedDocuments, medias, DocumentItemLabel.NationalCardFront), NationalCardRear = GetByLabelAndLoadMedia(employeeCurrentConfirmedDocuments, medias, DocumentItemLabel.NationalCardRear), MilitaryServiceCard = GetByLabelAndLoadMedia(employeeCurrentConfirmedDocuments, medias, DocumentItemLabel.MilitaryServiceCard), EmployeePicture = GetByLabelAndLoadMedia(employeeCurrentConfirmedDocuments, medias, DocumentItemLabel.EmployeePicture), }; }).ToList(); } public List SearchForClient(SearchEmployeeDocuments cmd) { //take employeeDocuments for workshop var query = _companyContext.EmployeeDocuments.Include(x => x.Employee) .Include(x => x.EmployeeDocumentItemCollection) .Where(x => x.WorkshopId == cmd.WorkshopId); if (!string.IsNullOrWhiteSpace(cmd.EmployeeName)) { query = query.Where(x => (x.Employee.FName + " " + x.Employee.LName).Contains(cmd.EmployeeName)); } var now = DateTime.Now.Date; //پرسنل قرارداد این کارگاه var contractEmployees = _companyContext.LeftWorkList .Where(x => x.WorkshopId == cmd.WorkshopId); //پرسنل فعال در قرارداد var contractActiveEmployeeIds = contractEmployees .Where(x => x.LeftWorkDate == new DateTime(2121, 3, 21) && x.StartWorkDate.Date <= now).Select(x => x.EmployeeId).ToList(); //پرسنل غیر فعال قرارداد var contractDeActivedEmployeeIds = contractEmployees .Where(x => x.LeftWorkDate.Date <= now && !contractActiveEmployeeIds.Contains(x.EmployeeId)) .Select(x => x.EmployeeId).ToList(); //پرسنل بیمه این کارگاه var insuranceEmployees = _companyContext.LeftWorkInsuranceList .Where(x => x.WorkshopId == cmd.WorkshopId); //پرسنل فعال در بیمه var insuranceActiveEmployeeIds = insuranceEmployees .Where(x => x.LeftWorkDate == null && x.StartWorkDate.Date <= now).Select(x => x.EmployeeId).ToList(); //پرسنل غیر فعال بیمه var insuranceDeActivedEmployeeIds = insuranceEmployees .Where(x => x.LeftWorkDate.Value.Date <= now && !contractActiveEmployeeIds.Contains(x.EmployeeId)) .Select(x => x.EmployeeId).ToList(); // پرسنل هر دو لیست که غیر فعال هستند var activeEmployees = contractActiveEmployeeIds.Concat(insuranceActiveEmployeeIds).Distinct().ToList(); // پرسنل هر دو لیست که فعال هستند var deActiveEmployees = contractDeActivedEmployeeIds.Concat(insuranceDeActivedEmployeeIds).Distinct().ToList(); //پرسنل غیر فعالی که یا در هر دو غیرفعال هستند یا فقط در یکی استارت خورده و غیر فعال شده اند var deActivedEmployeesIdlist = deActiveEmployees.Where(x => !activeEmployees.Contains(x)).ToList(); List employeeDocuments; switch (cmd.Mode) { // case EmployeeDocumentSearchMode.All: //employeeDocuments = query.OrderBy(x => passedLeftWorks.Any(y => x.EmployeeId == y)) // .Skip(cmd.PageIndex).Take(30).ToList(); //break; case EmployeeDocumentSearchMode.ActiveEmployees: employeeDocuments = query.Where(q => deActivedEmployeesIdlist.All(deActived => q.EmployeeId != deActived)) .OrderByDescending(x => x.id).Skip(cmd.PageIndex).Take(30).ToList(); break; case EmployeeDocumentSearchMode.DeactiveEmployees: employeeDocuments = query.Where(x => deActivedEmployeesIdlist.Any(deActived => x.EmployeeId == deActived)) .OrderByDescending(x => x.id).Skip(cmd.PageIndex).Take(30).ToList(); break; default: employeeDocuments = new(); break; } var employer = _employerRepository.GetEmployerByWorkshopId(cmd.WorkshopId).FirstOrDefault(); string employerFullName = employer.EmployerFullName; var currentItemsMediaId = employeeDocuments.SelectMany(y => y.EmployeeDocumentItemCollection) .Where(y=>y.DocumentStatus != DocumentStatus.Unsubmitted || y.UploaderType == UserType.Client) .GroupBy(x=>new{x.WorkshopId,x.EmployeeId,x.DocumentLabel}).Select(x=> x.MaxBy(y=>y.CreationDate)).Select(z => z.MediaId).ToList(); var personnelCodes = _companyContext.PersonnelCodeSet.Where(x => x.WorkshopId == cmd.WorkshopId).ToList(); //get medias for current documents of employees var medias = _accountContext.Medias.Where(x => currentItemsMediaId.Contains(x.id)) .Select(x => new MediaViewModel(){ Id = x.id,Path= x.Path }).ToList(); return employeeDocuments.Select(x => { var employeeLatestConfirmedDocuments = employeeDocuments.Where(y=>x.EmployeeId==y.EmployeeId) .SelectMany(y=> GetAllCurrentDocuments(y,UserType.Client)).ToList(); return new EmployeeDocumentsViewModel { Id = x.id, EmployeeId = x.EmployeeId, IdCardPage1 = GetByLabelAndLoadMedia(employeeLatestConfirmedDocuments,medias,DocumentItemLabel.IdCardPage1), IdCardPage2 = GetByLabelAndLoadMedia(employeeLatestConfirmedDocuments, medias, DocumentItemLabel.IdCardPage2), IdCardPage3= GetByLabelAndLoadMedia(employeeLatestConfirmedDocuments, medias, DocumentItemLabel.IdCardPage3), IdCardPage4= GetByLabelAndLoadMedia(employeeLatestConfirmedDocuments, medias, DocumentItemLabel.IdCardPage4), EducationalDegree = GetByLabelAndLoadMedia(employeeLatestConfirmedDocuments, medias, DocumentItemLabel.EducationalDegree), EmployeeFullName = x.Employee.FullName, NationalCardFront =GetByLabelAndLoadMedia(employeeLatestConfirmedDocuments, medias, DocumentItemLabel.NationalCardFront), NationalCardRear =GetByLabelAndLoadMedia(employeeLatestConfirmedDocuments, medias, DocumentItemLabel.NationalCardRear), MilitaryServiceCard= GetByLabelAndLoadMedia(employeeLatestConfirmedDocuments, medias, DocumentItemLabel.MilitaryServiceCard), EmployeePicture = GetByLabelAndLoadMedia(employeeLatestConfirmedDocuments, medias, DocumentItemLabel.EmployeePicture), IsBlack = deActivedEmployeesIdlist.Any(y => y == x.EmployeeId) ? "true" : "false", EmployerFullName = employerFullName, IsSentToChecker = x.IsSentToChecker, PersonnelCode = personnelCodes.FirstOrDefault(y=>y.EmployeeId == x.EmployeeId)?.PersonnelCode??0 }; }).OrderBy(x=>x.PersonnelCode).ToList(); } public List SearchForAdmin(SearchEmployeeDocuments cmd) { //take employeeDocuments for workshop var query = _companyContext.EmployeeDocuments.Include(x => x.Employee) .Include(x => x.EmployeeDocumentItemCollection).Where(x => x.WorkshopId == cmd.WorkshopId); if (!string.IsNullOrWhiteSpace(cmd.EmployeeName)) { query = query.Where(x => (x.Employee.FName + " " + x.Employee.LName).Contains(cmd.EmployeeName)); } var now = DateTime.Now.Date; //پرسنل قرارداد این کارگاه var contractEmployees = _companyContext.LeftWorkList .Where(x => x.WorkshopId == cmd.WorkshopId); //پرسنل فعال در قرارداد var contractActiveEmployeeIds = contractEmployees .Where(x=> x.LeftWorkDate == new DateTime(2121, 3, 21) && x.StartWorkDate.Date <= now).Select(x => x.EmployeeId).ToList(); //پرسنل غیر فعال قرارداد var contractDeActivedEmployeeIds = contractEmployees .Where(x=> x.LeftWorkDate.Date <= now && !contractActiveEmployeeIds.Contains(x.EmployeeId)) .Select(x=>x.EmployeeId).ToList(); //پرسنل بیمه این کارگاه var insuranceEmployees = _companyContext.LeftWorkInsuranceList .Where(x => x.WorkshopId == cmd.WorkshopId); //پرسنل فعال در بیمه var insuranceActiveEmployeeIds = insuranceEmployees .Where(x => x.LeftWorkDate == null && x.StartWorkDate.Date <= now).Select(x => x.EmployeeId).ToList(); //پرسنل غیر فعال بیمه var insuranceDeActivedEmployeeIds = insuranceEmployees .Where(x => x.LeftWorkDate.Value.Date <= now && !contractActiveEmployeeIds.Contains(x.EmployeeId)) .Select(x => x.EmployeeId).ToList(); // پرسنل هر دو لیست که غیر فعال هستند var activeEmployees = contractActiveEmployeeIds.Concat(insuranceActiveEmployeeIds).Distinct().ToList(); // پرسنل هر دو لیست که فعال هستند var deActiveEmployees = contractDeActivedEmployeeIds.Concat(insuranceDeActivedEmployeeIds).Distinct().ToList(); //پرسنل غیر فعالی که یا در هر دو غیرفعال هستند یا فقط در یکی استارت خورده و غیر فعال شده اند var deActivedEmployeesIdlist = deActiveEmployees.Where(x => !activeEmployees.Contains(x)).ToList(); List employeeDocuments; switch (cmd.Mode) { //case EmployeeDocumentSearchMode.All: // employeeDocuments = query.OrderBy(x => passedLeftWorks.Any(y => x.EmployeeId == y)).Skip(cmd.PageIndex).Take(30).ToList(); // break; case EmployeeDocumentSearchMode.ActiveEmployees: employeeDocuments = query.Where(q => deActivedEmployeesIdlist.All(deActived => q.EmployeeId != deActived)) .OrderByDescending(x => x.id).Skip(cmd.PageIndex).Take(30).ToList(); break; case EmployeeDocumentSearchMode.DeactiveEmployees: employeeDocuments = query.Where(x => deActivedEmployeesIdlist.Any(deActived => x.EmployeeId == deActived)) .OrderByDescending(x => x.id).Skip(cmd.PageIndex).Take(30).ToList(); break; default: employeeDocuments = new(); break; } var employer = _employerRepository.GetEmployerByWorkshopId(cmd.WorkshopId).FirstOrDefault(); string employerFullName = employer.EmployerFullName; var currentItemsMediaId = employeeDocuments.SelectMany(y => GetAllCurrentDocuments(y,UserType.Admin)) .Select(y => y.MediaId).ToList(); //get medias for current documents of employees var personnelCodes = _companyContext.PersonnelCodeSet.Where(x => x.WorkshopId == cmd.WorkshopId).ToList(); var medias = _accountContext.Medias.Where(x => currentItemsMediaId.Contains(x.id)) .Select(x => new MediaViewModel() { Id = x.id, Path = x.Path }).ToList(); return employeeDocuments.Select(x => { var employeeLatestConfirmedDocuments = employeeDocuments.Where(y => x.EmployeeId == y.EmployeeId) .SelectMany(y => GetAllCurrentDocuments(y, UserType.Admin)).ToList(); return new EmployeeDocumentsViewModel { Id = x.id, EmployeeId = x.EmployeeId, IdCardPage1 = GetByLabelAndLoadMedia(employeeLatestConfirmedDocuments, medias, DocumentItemLabel.IdCardPage1), IdCardPage2 = GetByLabelAndLoadMedia(employeeLatestConfirmedDocuments, medias, DocumentItemLabel.IdCardPage2), IdCardPage3 = GetByLabelAndLoadMedia(employeeLatestConfirmedDocuments, medias, DocumentItemLabel.IdCardPage3), IdCardPage4 = GetByLabelAndLoadMedia(employeeLatestConfirmedDocuments, medias, DocumentItemLabel.IdCardPage4), EducationalDegree = GetByLabelAndLoadMedia(employeeLatestConfirmedDocuments, medias, DocumentItemLabel.EducationalDegree), EmployeeFullName = x.Employee.FullName, NationalCardFront = GetByLabelAndLoadMedia(employeeLatestConfirmedDocuments, medias, DocumentItemLabel.NationalCardFront), NationalCardRear = GetByLabelAndLoadMedia(employeeLatestConfirmedDocuments, medias, DocumentItemLabel.NationalCardRear), MilitaryServiceCard = GetByLabelAndLoadMedia(employeeLatestConfirmedDocuments, medias, DocumentItemLabel.MilitaryServiceCard), EmployeePicture = GetByLabelAndLoadMedia(employeeLatestConfirmedDocuments, medias, DocumentItemLabel.EmployeePicture), IsBlack = deActivedEmployeesIdlist.Any(y => y == x.EmployeeId) ? "true" : "false", EmployerFullName = employerFullName, PersonnelCode = personnelCodes.FirstOrDefault(y => y.EmployeeId == x.EmployeeId)?.PersonnelCode ?? 0 }; }).OrderBy(x=>x.PersonnelCode).ToList(); } public List GetWorkshopsWithDocumentsAwaitingReviewForAdminWorkFlow(List workshops) { var activeEmployees = _companyContext.LeftWorkList .Where(x => workshops.Contains(x.WorkshopId) && x.LeftWorkDate.AddDays(-1) >= DateTime.Now) .Select(x => new { x.WorkshopId, x.EmployeeId }); var employeeClientTemp = _companyContext.EmployeeClientTemps.Where(x => workshops.Contains(x.WorkshopId)); var query = _companyContext.EmployeeDocuments .Where(x => workshops.Contains(x.WorkshopId) && (activeEmployees.Any(y => y.WorkshopId == x.WorkshopId && y.EmployeeId == x.EmployeeId) || employeeClientTemp.Any(temp => x.EmployeeId == temp.EmployeeId && temp.WorkshopId == x.WorkshopId)) && x.IsConfirmed == false) .Include(x => x.Workshop).Include(x => x.EmployeeDocumentItemCollection) .Where(x => x.IsSentToChecker == false && (x.EmployeeDocumentItemCollection.Any(y => y.DocumentStatus == DocumentStatus.SubmittedByClient) || employeeClientTemp.Any(temp => x.EmployeeId == temp.EmployeeId && temp.WorkshopId == x.WorkshopId) || x.HasRejectedItems)) .GroupBy(x => x.WorkshopId).Select(x => new WorkshopWithEmployeeDocumentsViewModel() { WorkshopId = x.Key, WorkshopFullName = x.FirstOrDefault().Workshop.WorkshopName, EmployeesWithoutDocumentCount = x.Count() }); var workshopEmployers = _companyContext.WorkshopEmployers.Include(x => x.Employer) .Where(x => query.Any(y => y.WorkshopId == x.WorkshopId)) .GroupBy(x => x.WorkshopId).Select(x => x.FirstOrDefault()).ToList(); var result = query.ToList(); result.ForEach(x => { var employer = workshopEmployers.FirstOrDefault(y => y.WorkshopId == x.WorkshopId)?.Employer; x.EmployerName = employer.FullName; //x.SubmittedItems.ForEach(y=>y.PicturePath= medias.FirstOrDefault(z=>z.id == y.MediaId)?.Path ?? ""); }); return result.Where(x => x.EmployeesWithoutDocumentCount > 0).OrderByDescending(x => x.EmployeesWithoutDocumentCount).ToList(); } //ToDo آپلود مدارک و افزودن پرسنل //public List GetWorkshopsWithNewEmployeesWithoutDocuments(List workshops) //{ // var newEmployees = _companyContext.LeftWorkTemps.Where(x => workshops.Contains(x.WorkshopId)) // .Select(x => new { x.WorkshopId, x.EmployeeId }); // var query = _companyContext.EmployeeDocuments // .Where(x => workshops.Contains(x.WorkshopId) && // newEmployees.Any(y => y.WorkshopId == x.WorkshopId && y.EmployeeId == x.EmployeeId)) // .Include(x => x.Workshop).Include(x => x.EmployeeDocumentItemCollection) // .GroupBy(x => x.WorkshopId).Select(x => new WorkshopWithEmployeeDocumentsViewModel() // { // WorkshopId = x.Key, // WorkshopFullName = x.FirstOrDefault().Workshop.WorkshopName, // EmployeesWithoutDocumentCount = x.Count() // }); // var workshopEmployers = _companyContext.WorkshopEmployers.Include(x => x.Employer) // .Where(x => query.Any(y => y.WorkshopId == x.WorkshopId)) // .GroupBy(x => x.WorkshopId).Select(x => x.FirstOrDefault()).ToList(); // var result = query.ToList(); // result.ForEach(x => // { // var employer = workshopEmployers.FirstOrDefault(y => y.WorkshopId == x.WorkshopId)?.Employer; // x.EmployerName = employer.FullName; // //x.SubmittedItems.ForEach(y=>y.PicturePath= medias.FirstOrDefault(z=>z.id == y.MediaId)?.Path ?? ""); // }); // return result.Where(x => x.EmployeesWithoutDocumentCount > 0).OrderByDescending(x => x.EmployeesWithoutDocumentCount).ToList(); //} public List GetByWorkshopIdWithItemsForAdminWorkFlow(long workshopId) { var activeEmployeesInWorkshop = _companyContext.LeftWorkList .Where(x => workshopId == x.WorkshopId && x.LeftWorkDate.AddDays(-1) >= DateTime.Today) .Include(x => x.Employee).ThenInclude(x => x.EmployeeDocuments) .Select(x => new { x.EmployeeId, FullName = x.Employee.FName + " " + x.Employee.LName, x.Employee.Gender }); var EDItemsList = _companyContext.EmployeeDocumentItems .Where(x => x.WorkshopId == workshopId && x.DocumentStatus != DocumentStatus.Unsubmitted && activeEmployeesInWorkshop.Any(y => y.EmployeeId == x.EmployeeId)) .Include(x => x.EmployeeDocuments) .Where(x => x.EmployeeDocuments.IsSentToChecker == false && ((x.DocumentStatus == DocumentStatus.SubmittedByClient) || x.EmployeeDocuments.HasRejectedItems)) .GroupBy(x => new { x.EmployeeId, x.DocumentLabel }) .Select(x => x.Select(y => new { y.EmployeeDocumentId, Id = y.id, y.EmployeeDocuments.Gender, y.DocumentLabel, y.DocumentStatus, y.MediaId, y.RejectionReason, y.EmployeeId, y.CreationDate, IsSentToChecker = y.EmployeeDocuments.IsSentToChecker, y.EmployeeDocuments.IsConfirmed }).OrderByDescending(y => y.CreationDate).First()).ToList(); var employeeClientTemp = _companyContext.EmployeeClientTemps.Where(x => x.WorkshopId == workshopId); var tempEmployees = _companyContext.Employees.Where(x => employeeClientTemp.Any(a => a.EmployeeId == x.id)) .Select(x => new { EmployeeId = x.id, FullName = x.FName + " " + x.LName, x.Gender }).ToList(); var tempEmployeeDocuments = _companyContext.EmployeeDocuments .Where(x => x.WorkshopId == workshopId && employeeClientTemp.Any(e => e.EmployeeId == x.EmployeeId) && x.IsSentToChecker == false && x.IsConfirmed == false) .SelectMany(x => x.EmployeeDocumentItemCollection.DefaultIfEmpty(), // اگر خالی بود، مقدار پیش‌فرض ایجاد کن (documents, y) => new { EmployeeDocumentId = documents.id, // اگر null بود مقدار نداشته باشد Id = y != null ? y.id : 0, documents.Gender, DocumentLabel = y != null ? y.DocumentLabel : default, DocumentStatus = y != null ? y.DocumentStatus : default, MediaId = y != null ? y.MediaId : 0, RejectionReason = y != null ? y.RejectionReason : default, EmployeeId = y != null ? y.EmployeeId : documents.EmployeeId, // اگر مقدار نداشت از EmployeeDocuments پر کن CreationDate = y != null ? y.CreationDate : documents.CreationDate, IsSentToChecker = documents.IsSentToChecker, IsConfirmed = documents.IsConfirmed }) .ToList(); var enumerable = EDItemsList.Concat(tempEmployeeDocuments); var activeEmployeesInWorkshopList = activeEmployeesInWorkshop.ToList().Concat(tempEmployees); //get medias for current documents of employees var mediaIds = enumerable.Select(x => x.MediaId).ToList(); var mediasList = _accountContext.Medias.Where(x => mediaIds.Contains(x.id)) .Select(x => new MediaViewModel() { Id = x.id, Path = x.Path }).ToList(); var result = enumerable.GroupBy(x => x.EmployeeId) .Select(x => { //var requiredDocs = EmployeeDocumentRequiredItems.GetByGender(x.Gender); var employeeLatestConfirmedDocuments = x .Where(y => y.EmployeeId == x.Key && (y.DocumentStatus == DocumentStatus.SubmittedByClient || y.DocumentStatus == DocumentStatus.SubmittedByAdmin || y.DocumentStatus == DocumentStatus.Rejected)) .Select(y => new EmployeeDocumentItemViewModel() { Status = y.DocumentStatus, MediaId = y.MediaId, DocumentItemLabel = y.DocumentLabel, Id = y.Id, RejectionMessage = y.RejectionReason, StatusString = y.DocumentStatus.ToString() }).ToList(); //var requiredItemsUploaded = employeeLatestConfirmedDocuments // .Where(y => requiredDocs.Contains(y.DocumentItemLabel)).Select(y => y.DocumentItemLabel) // .ToList(); return new EmployeeDocumentsViewModel() { EmployeeId = x.Key, IdCardPage1 = GetByLabelAndLoadMedia(employeeLatestConfirmedDocuments, mediasList, DocumentItemLabel.IdCardPage1), IdCardPage2 = GetByLabelAndLoadMedia(employeeLatestConfirmedDocuments, mediasList, DocumentItemLabel.IdCardPage2), IdCardPage3 = GetByLabelAndLoadMedia(employeeLatestConfirmedDocuments, mediasList, DocumentItemLabel.IdCardPage3), IdCardPage4 = GetByLabelAndLoadMedia(employeeLatestConfirmedDocuments, mediasList, DocumentItemLabel.IdCardPage4), EducationalDegree = GetByLabelAndLoadMedia(employeeLatestConfirmedDocuments, mediasList, DocumentItemLabel.EducationalDegree), EmployeeFullName = activeEmployeesInWorkshopList.First(y => y.EmployeeId == x.Key).FullName, NationalCardFront = GetByLabelAndLoadMedia(employeeLatestConfirmedDocuments, mediasList, DocumentItemLabel.NationalCardFront), NationalCardRear = GetByLabelAndLoadMedia(employeeLatestConfirmedDocuments, mediasList, DocumentItemLabel.NationalCardRear), MilitaryServiceCard = GetByLabelAndLoadMedia(employeeLatestConfirmedDocuments, mediasList, DocumentItemLabel.MilitaryServiceCard), EmployeePicture = GetByLabelAndLoadMedia(employeeLatestConfirmedDocuments, mediasList, DocumentItemLabel.EmployeePicture), //RequiredDocumentsUploaded = requiredItemsUploaded, //RequiredDocuments = requiredDocs }; }).ToList(); return result; } /// /// برای دریافت لیست کارگاه های آپلود کرده در لیست چکر /// public List GetWorkshopsWithUploadedDocuments() { var itemsQuery = _companyContext.EmployeeDocumentItems .Where(x => x.DocumentStatus != DocumentStatus.Unsubmitted) .Include(x => x.EmployeeDocuments) .ThenInclude(x => x.Workshop).ThenInclude(x=>x.WorkshopEmployers).ThenInclude(x=>x.Employer) .GroupBy(x=>x.WorkshopId).Select(x => new WorkshopWithEmployeeDocumentsViewModel() { SubmittedItemsCount = x.Count(y => y.DocumentStatus == DocumentStatus.SubmittedByAdmin || y.DocumentStatus == DocumentStatus.SubmittedByClient), WorkshopId = x.Key, WorkshopFullName = x.First().EmployeeDocuments.Workshop.WorkshopName, EmployerName = x.First().EmployeeDocuments.Workshop.WorkshopEmployers.First().Employer.FullName }); //var workshopIds = itemsQuery.Select(x => x.WorkshopId); // var workshopEmployers = _companyContext.WorkshopEmployers.Include(x => x.Employer) // .Where(x=> workshopIds.Contains(x.WorkshopId)) // .GroupBy(x => x.WorkshopId).Select(x => x.FirstOrDefault()).ToList(); //var mediaIds = _companyContext.EmployeeDocumentItems.Where(x=>x.DocumentStatus==DocumentStatus.Submitted).Select(x=>x.EmployeeDocumentId).ToList(); //var medias = // _accountContext.Medias.Where(x =>mediaIds.Contains(x.id)).ToList(); // list.ForEach(x => // { // var employer = workshopEmployers.FirstOrDefault(y => y.WorkshopId == x.WorkshopId)?.Employer; //x.EmployerName = employer.FullName; // x.SubmittedItemsCount = x.SubmittedItems.Count(y=>y.Status == DocumentStatus.SubmittedByAdmin); // //x.SubmittedItems.ForEach(y=>y.PicturePath= medias.FirstOrDefault(z=>z.id == y.MediaId)?.Path ?? ""); // }); return itemsQuery.Where(x=>x.SubmittedItemsCount > 0).OrderByDescending(x=>x.SubmittedItemsCount).ToList(); } public List GetWorkshopsWithDocumentsAwaitingReviewForCheckerWorkFlow() { var query = _companyContext.EmployeeDocuments .Include(x => x.Workshop); var workshopEmployers = _companyContext.WorkshopEmployers.Include(x => x.Employer) .Where(x => query.Any(y=>y.WorkshopId == x.WorkshopId)) .GroupBy(x => x.WorkshopId).ToList() .Select(x => new { x.Key, x.FirstOrDefault()!.Employer }).ToList(); var result = query .GroupBy(x => x.WorkshopId).ToList().Select(x => new WorkshopWithEmployeeDocumentsViewModel() { SubmittedItemsCount = x.Count(), WorkshopId = x.Key, WorkshopFullName = x.FirstOrDefault().Workshop.WorkshopName, }).ToList(); result.ForEach(x => { var employer = workshopEmployers.FirstOrDefault().Employer; x.EmployerName = employer.FullName; }); return result; } public List GetByWorkshopIdWithItemsForChecker(long workshopId, bool onlyConfirmed) { //todo: optimize here var workshopDocuments = _companyContext.EmployeeDocuments.Where(x => x.WorkshopId == workshopId) .Include(x => x.EmployeeDocumentItemCollection) .Where(x=>x.EmployeeDocumentItemCollection.Any(y => y.DocumentStatus != DocumentStatus.Unsubmitted)); var employeesList = _companyContext.Employees.Where(x => workshopDocuments.Any(y => y.EmployeeId == x.id)) .Select(x => new { Id = x.id, FullName = (x.FName + " " + x.LName) }).ToList(); var employer = _companyContext.WorkshopEmployers.Include(x => x.Employer) .FirstOrDefault(x => x.WorkshopId == workshopId)!.Employer; var employerName = employer.FullName; //var employerName = employer.IsLegal == "حقیقی" ? (employer.FName + " " + employer.LName) : employer.LName; var workshopDocumentsList = workshopDocuments.ToList(); var workshopDocumentsListWithConfirmed = workshopDocumentsList.Select(x => new { EmployeeDocuments = x, EmployeeDocumentItemCollection = x.EmployeeDocumentItemCollection.Where(y=> y.DocumentStatus != DocumentStatus.Unsubmitted) .GroupBy(y => y.DocumentLabel) .Select(y => y.MaxBy(z => z.CreationDate)) . ToList() }).ToList(); var workshopName = _companyContext.Workshops.FirstOrDefault(x => x.id == workshopId)?.WorkshopFullName ?? ""; var mediaIds = workshopDocumentsList.SelectMany(x => x.EmployeeDocumentItemCollection) .Select(x => x.MediaId).ToList(); var mediasList = _accountContext.Medias.Where(x=>mediaIds.Contains(x.id)) .Select(x => new MediaViewModel() { Id = x.id, Path = x.Path }).ToList(); if (onlyConfirmed) workshopDocumentsListWithConfirmed=workshopDocumentsListWithConfirmed.Where(x => x.EmployeeDocumentItemCollection.All(y => y.DocumentStatus != DocumentStatus.SubmittedByAdmin)).ToList(); else workshopDocumentsListWithConfirmed = workshopDocumentsListWithConfirmed.Where(x => x.EmployeeDocumentItemCollection.Any(y => y.DocumentStatus is DocumentStatus.SubmittedByAdmin or DocumentStatus.SubmittedByClient)).ToList(); return workshopDocumentsListWithConfirmed.Select(x => new EmployeeDocumentsViewModel() { Id=x.EmployeeDocuments.id, EmployeeFullName = employeesList.FirstOrDefault(y=>y.Id==x.EmployeeDocuments.EmployeeId)?.FullName ?? "", EmployeeId = x.EmployeeDocuments.EmployeeId, WorkshopId = workshopId, WorkshopName = workshopName, Gender = x.EmployeeDocuments.Gender, EducationalDegree = GetByLabelAndLoadMedia(x.EmployeeDocumentItemCollection,mediasList, DocumentItemLabel.EducationalDegree), IdCardPage1 = GetByLabelAndLoadMedia(x.EmployeeDocumentItemCollection, mediasList, DocumentItemLabel.IdCardPage1), IdCardPage2 = GetByLabelAndLoadMedia(x.EmployeeDocumentItemCollection, mediasList, DocumentItemLabel.IdCardPage2), IdCardPage3 = GetByLabelAndLoadMedia(x.EmployeeDocumentItemCollection, mediasList, DocumentItemLabel.IdCardPage3), IdCardPage4 = GetByLabelAndLoadMedia(x.EmployeeDocumentItemCollection, mediasList, DocumentItemLabel.IdCardPage4), NationalCardFront = GetByLabelAndLoadMedia(x.EmployeeDocumentItemCollection, mediasList, DocumentItemLabel.NationalCardFront), NationalCardRear = GetByLabelAndLoadMedia(x.EmployeeDocumentItemCollection, mediasList, DocumentItemLabel.NationalCardRear), MilitaryServiceCard = GetByLabelAndLoadMedia(x.EmployeeDocumentItemCollection, mediasList, DocumentItemLabel.MilitaryServiceCard), EmployeePicture = GetByLabelAndLoadMedia(x.EmployeeDocumentItemCollection, mediasList, DocumentItemLabel.EmployeePicture), SubmittedItemsCount = x.EmployeeDocumentItemCollection.Count(y=>y.DocumentStatus is DocumentStatus.SubmittedByAdmin or DocumentStatus.SubmittedByClient), RejectedItemsCount = x.EmployeeDocumentItemCollection.Count(y => y.DocumentStatus == DocumentStatus.Rejected), ConfirmedItemsCount = x.EmployeeDocumentItemCollection.Count(y => y.DocumentStatus == DocumentStatus.Confirmed), EmployerFullName = employerName, IsSentToChecker = x.EmployeeDocuments.IsSentToChecker }).Where(x=>x.SubmittedItemsCount > 0 || x.RejectedItemsCount > 0 || x.ConfirmedItemsCount > 0) .OrderByDescending(x=>x.SubmittedItemsCount).ToList(); } public async Task GetCheckerWorkFlowCount() { return await _companyContext.EmployeeDocumentItems.Include(x => x.EmployeeDocuments) .CountAsync(x => x.DocumentStatus == DocumentStatus.SubmittedByAdmin || x.DocumentStatus == DocumentStatus.SubmittedByClient); } public async Task GetAdminWorkFlowCountForNewEmployees(List workshopIds) { //New employees created by client should have their documents uploaded or confirmed var newEmployeesInWorkshop = _companyContext.EmployeeClientTemps.Where(x => workshopIds.Contains(x.WorkshopId)); var duty = _companyContext.EmployeeDocuments .CountAsync(x => workshopIds.Contains(x.WorkshopId) && newEmployeesInWorkshop.Any(y => y.EmployeeId == x.EmployeeId) && x.IsSentToChecker == false && x.IsConfirmed == false); return await duty; } public async Task GetAdminWorkFlowCountForSubmittedAndRejectedDocuments(List workshopIds) { //Uploaded items done by client should be reviewed by admin before proceeding to checker var activeEmployeesInWorkshop = _companyContext.LeftWorkList .Where(x => workshopIds.Contains(x.WorkshopId) && x.LeftWorkDate.AddDays(-1) >= DateTime.Today); var dutyCount = _companyContext.EmployeeDocuments .CountAsync(x => workshopIds.Contains(x.WorkshopId) && activeEmployeesInWorkshop.Any(y => y.EmployeeId == x.EmployeeId) && x.IsSentToChecker == false && (x.EmployeeDocumentItemCollection.Any(y => y.DocumentStatus == DocumentStatus.SubmittedByClient) || x.HasRejectedItems)); return await dutyCount; } public List GetDocumentsAwaitingReviewByWorkshopIdForCheckerWorkFlow(long workshopId) { //todo: optimize here var workshopDocuments = _companyContext.EmployeeDocuments.Where(x => x.WorkshopId == workshopId) .Include(x => x.EmployeeDocumentItemCollection) .Where(x => x.IsSentToChecker); var employeesList = _companyContext.Employees.Where(x => workshopDocuments.Any(y => y.EmployeeId == x.id)) .Select(x => new { Id = x.id, FullName = (x.FName + " " + x.LName) }).ToList(); var employer = _companyContext.WorkshopEmployers.Include(x => x.Employer) .FirstOrDefault(x => x.WorkshopId == workshopId)!.Employer; var employerName = employer.FullName; //var employerName = employer.IsLegal == "حقیقی" ? (employer.FName + " " + employer.LName) : employer.LName; var workshopDocumentsList = workshopDocuments.ToList(); var workshopDocumentsListWithConfirmed = workshopDocumentsList.Select(x => new { EmployeeDocuments = x, EmployeeDocumentItemCollection = x.EmployeeDocumentItemCollection .Where(y => y.DocumentStatus != DocumentStatus.Unsubmitted) .GroupBy(y => y.DocumentLabel) .Select(y => y.MaxBy(z => z.CreationDate)).ToList() }).ToList(); var workshopName = _companyContext.Workshops.FirstOrDefault(x => x.id == workshopId)?.WorkshopFullName ?? ""; var mediaIds = workshopDocumentsList.SelectMany(x => x.EmployeeDocumentItemCollection) .Where(x => x.DocumentStatus != DocumentStatus.Unsubmitted).Select(x => x.MediaId).ToList(); var mediasList = _accountContext.Medias.Where(x => mediaIds.Contains(x.id)) .Select(x => new MediaViewModel() { Id = x.id, Path = x.Path }).ToList(); workshopDocumentsListWithConfirmed = workshopDocumentsListWithConfirmed.Where(x => x.EmployeeDocumentItemCollection.Any(y => y.DocumentStatus is DocumentStatus.SubmittedByAdmin or DocumentStatus.SubmittedByClient)).ToList(); return workshopDocumentsListWithConfirmed.Select(x => new EmployeeDocumentsViewModel() { Id = x.EmployeeDocuments.id, EmployeeFullName = employeesList.FirstOrDefault(y => y.Id == x.EmployeeDocuments.EmployeeId)?.FullName ?? "", EmployeeId = x.EmployeeDocuments.EmployeeId, WorkshopId = workshopId, WorkshopName = workshopName, Gender = x.EmployeeDocuments.Gender, EducationalDegree = GetByLabelAndLoadMedia(x.EmployeeDocumentItemCollection, mediasList, DocumentItemLabel.EducationalDegree), IdCardPage1 = GetByLabelAndLoadMedia(x.EmployeeDocumentItemCollection, mediasList, DocumentItemLabel.IdCardPage1), IdCardPage2 = GetByLabelAndLoadMedia(x.EmployeeDocumentItemCollection, mediasList, DocumentItemLabel.IdCardPage2), IdCardPage3 = GetByLabelAndLoadMedia(x.EmployeeDocumentItemCollection, mediasList, DocumentItemLabel.IdCardPage3), IdCardPage4 = GetByLabelAndLoadMedia(x.EmployeeDocumentItemCollection, mediasList, DocumentItemLabel.IdCardPage4), NationalCardFront = GetByLabelAndLoadMedia(x.EmployeeDocumentItemCollection, mediasList, DocumentItemLabel.NationalCardFront), NationalCardRear = GetByLabelAndLoadMedia(x.EmployeeDocumentItemCollection, mediasList, DocumentItemLabel.NationalCardRear), MilitaryServiceCard = GetByLabelAndLoadMedia(x.EmployeeDocumentItemCollection, mediasList, DocumentItemLabel.MilitaryServiceCard), EmployeePicture = GetByLabelAndLoadMedia(x.EmployeeDocumentItemCollection, mediasList, DocumentItemLabel.EmployeePicture), SubmittedItemsCount = x.EmployeeDocumentItemCollection.Count(y => y.DocumentStatus == DocumentStatus.SubmittedByAdmin), RejectedItemsCount = x.EmployeeDocumentItemCollection.Count(y => y.DocumentStatus == DocumentStatus.Rejected), ConfirmedItemsCount = x.EmployeeDocumentItemCollection.Count(y => y.DocumentStatus == DocumentStatus.Confirmed), EmployerFullName = employerName, IsSentToChecker = x.EmployeeDocuments.IsSentToChecker }).Where(x => x.SubmittedItemsCount > 0) .OrderByDescending(x => x.SubmittedItemsCount).ToList(); } #region Private Methods private static List GetCurrentConfirmedDocumentItemsFromEmployeeDocumentItems(EmployeeDocuments entity) { return entity.EmployeeDocumentItemCollection.Where(x => x.DocumentStatus == DocumentStatus.Confirmed) .GroupBy(x => x.DocumentLabel) .Select(x => x.MaxBy(y => y.CreationDate)).ToList(); } private static List GetAllCurrentDocuments(EmployeeDocuments entity,UserType userType) { return entity.EmployeeDocumentItemCollection.Where(x=>x.DocumentStatus != DocumentStatus.Unsubmitted || x.UploaderType == userType) .GroupBy(x => x.DocumentLabel).Select(x => x.OrderByDescending(y => y.CreationDate).First()).ToList(); } private static EmployeeDocumentItemViewModel GetByLabelAndLoadMedia(List items, List medias, DocumentItemLabel label) { if (items == null || items.Count == 0) return new(); var item = items.FirstOrDefault(x => x.DocumentLabel == label); if (item == null || item.MediaId == 0) return new(); return new EmployeeDocumentItemViewModel() { DocumentItemLabel = label, Id = item.id, StatusString = item.DocumentStatus.ToString().ToLower(), Status = item.DocumentStatus, PicturePath = medias.FirstOrDefault(x => x.Id == item.MediaId)?.Path ?? "", RejectionMessage = item.RejectionReason }; } private static EmployeeDocumentItemViewModel GetByLabelAndLoadMedia(List items, List medias, DocumentItemLabel label) { if (items == null || items.Count == 0) return new(); var item = items.FirstOrDefault(x => x.DocumentItemLabel == label); if (item == null || item.MediaId == 0) return new(); item.PicturePath = medias.FirstOrDefault(x => x.Id == item.MediaId)?.Path ?? ""; return item; } #endregion }