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)) // .Select(x=> new { x.WorkshopId, x.EmployeeId }); //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).AsSplitQuery().AsNoTracking() // .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).AsSplitQuery() // .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(); // یک بار keyها رو آماده می‌کنیم var activeEmployeeKeys = _companyContext.LeftWorkList .Where(x => workshops.Contains(x.WorkshopId) && x.LeftWorkDate.AddDays(-1) >= DateTime.Now) .Select(x => new { x.WorkshopId, x.EmployeeId }); var employeeClientTempKeys = _companyContext.EmployeeClientTemps .Where(x => workshops.Contains(x.WorkshopId)) .Select(x => new { x.WorkshopId, x.EmployeeId }); var allValidKeys = activeEmployeeKeys .Union(employeeClientTempKeys); // کوئری اصلی بدون Include و بدون GroupBy var employeeDocs = _companyContext.EmployeeDocuments .Where(x => workshops.Contains(x.WorkshopId) && allValidKeys.Any(k => k.WorkshopId == x.WorkshopId && k.EmployeeId == x.EmployeeId) && !x.IsConfirmed && !x.IsSentToChecker && ( x.EmployeeDocumentItemCollection.Any(y => y.DocumentStatus == DocumentStatus.SubmittedByClient) || x.HasRejectedItems || employeeClientTempKeys.Any(k => k.WorkshopId == x.WorkshopId && k.EmployeeId == x.EmployeeId) )) .Select(x => new { x.WorkshopId, WorkshopName = x.Workshop.WorkshopName, x.EmployeeId }) .AsNoTracking() .ToList(); // Group در حافظه با سرعت بیشتر var grouped = employeeDocs .GroupBy(x => new { x.WorkshopId, x.WorkshopName }) .Select(g => new WorkshopWithEmployeeDocumentsViewModel { WorkshopId = g.Key.WorkshopId, WorkshopFullName = g.Key.WorkshopName, EmployeesWithoutDocumentCount = g.Count() }) .ToList(); // گرفتن کارفرماها فقط برای ورکشاپ‌هایی که توی لیست بالا هستن var workshopIds = grouped.Select(x => x.WorkshopId).ToList(); var employers = _companyContext.WorkshopEmployers .Where(x => workshopIds.Contains(x.WorkshopId)) .Include(x => x.Employer) .AsSplitQuery() .AsNoTracking() .GroupBy(x => x.WorkshopId) .Select(g => g.FirstOrDefault()) .ToList(); // اضافه کردن اسم کارفرما grouped.ForEach(x => { var employer = employers.FirstOrDefault(y => y.WorkshopId == x.WorkshopId)?.Employer; x.EmployerName = employer?.FullName; }); // فیلتر نهایی return grouped .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 activeEmployeeIds = _companyContext.LeftWorkList .Where(x => x.WorkshopId == workshopId && x.LeftWorkDate.AddDays(-1) >= DateTime.Today) .Select(x => new { x.EmployeeId, FullName = x.Employee.FName + " " + x.Employee.LName, x.Employee.Gender }).ToList(); var activeEmployeeIdList = activeEmployeeIds.Select(x => x.EmployeeId).ToList(); //var EDItemsList = _companyContext.EmployeeDocumentItems // .Where(x => x.WorkshopId == workshopId && // x.DocumentStatus != DocumentStatus.Unsubmitted && // activeEmployeeIdList.Contains(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 EDItemsList = _companyContext.EmployeeDocumentItems .Where(x => x.WorkshopId == workshopId && x.DocumentStatus != DocumentStatus.Unsubmitted && activeEmployeeIdList.Contains(x.EmployeeId) && x.EmployeeDocuments.IsSentToChecker == false && (x.DocumentStatus == DocumentStatus.SubmittedByClient || x.EmployeeDocuments.HasRejectedItems)) .Include(x=>x.EmployeeDocuments).ToList() .GroupBy(x => new { x.EmployeeId, x.DocumentLabel }) .Select(g => g.OrderByDescending(x => x.CreationDate).Select(y => new { y.EmployeeDocumentId, Id = y.id, y.EmployeeDocuments.Gender, y.DocumentLabel, y.DocumentStatus, y.MediaId, y.RejectionReason, y.EmployeeId, y.CreationDate, y.EmployeeDocuments.IsSentToChecker, y.EmployeeDocuments.IsConfirmed }).FirstOrDefault()) .ToList(); var tempEmployeeIds = _companyContext.EmployeeClientTemps .Where(x => x.WorkshopId == workshopId) .Select(x => x.EmployeeId) .ToList(); var tempEmployees = _companyContext.Employees .Where(x => tempEmployeeIds.Contains(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 && tempEmployeeIds.Contains(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); var allEmployeeDocuments = EDItemsList.Concat(tempEmployeeDocuments).ToList(); var allEmployees = activeEmployeeIds.Concat(tempEmployees).ToList(); //get medias for current documents of employees var mediaIds = allEmployeeDocuments.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 = allEmployeeDocuments .GroupBy(x => x.EmployeeId) .Select(group => { var employee = allEmployees.First(e => e.EmployeeId == group.Key); var employeeLatestConfirmedDocuments = group .Where(y => y.EmployeeId == group.Key && (y.DocumentStatus == DocumentStatus.SubmittedByClient || y.DocumentStatus == DocumentStatus.SubmittedByAdmin || y.DocumentStatus == DocumentStatus.Rejected || y.DocumentStatus == DocumentStatus.Confirmed)) .Select(y => new EmployeeDocumentItemViewModel() { Status = y.DocumentStatus, MediaId = y.MediaId, DocumentItemLabel = y.DocumentLabel, Id = y.Id, RejectionMessage = y.RejectionReason, StatusString = y.DocumentStatus.ToString() }).ToList(); return new EmployeeDocumentsViewModel { EmployeeId = group.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 = allEmployees.First(y => y.EmployeeId == group.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), }; }) .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(); } public async Task> GetWorkshopDocumentCreatedEmployeeForAdmin(List workshops, long roleId) { 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 && employeeClientTemp.Any(temp => x.EmployeeId == temp.EmployeeId && temp.WorkshopId == x.WorkshopId)) .GroupBy(x => x.WorkshopId).Select(x => new WorkshopWithEmployeeDocumentsViewModel() { WorkshopId = x.Key, WorkshopFullName = x.FirstOrDefault().Workshop.WorkshopName, EmployeesWithoutDocumentCount = x.Count() }); var workshopEmployers = await _companyContext.WorkshopEmployers.Include(x => x.Employer) .Where(x => query.Any(y => y.WorkshopId == x.WorkshopId)) .GroupBy(x => x.WorkshopId).Select(x => x.FirstOrDefault()).ToListAsync(); var result = await query.ToListAsync(); 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 async Task> GetWorkshopDocumentRejectedForAdmin(List workshops, long roleId) { var now = DateTime.Now; // دریافت فقط اطلاعات مورد نیاز var employeeDocumentsQuery = _companyContext.EmployeeDocuments .Where(x => workshops.Contains(x.WorkshopId) && x.IsSentToChecker == false && x.HasRejectedItems) .Where(x => x.EmployeeDocumentItemCollection .Any(i => i.DocumentStatus == DocumentStatus.Rejected && (roleId == 1 ? i.UploaderType == UserType.Admin : i.UploaderRoleId == roleId))) .Select(x => new { x.WorkshopId, WorkshopName = x.Workshop.WorkshopName }) .GroupBy(x => new { x.WorkshopId, x.WorkshopName }) .Select(g => new WorkshopWithEmployeeDocumentsViewModel { WorkshopId = g.Key.WorkshopId, WorkshopFullName = g.Key.WorkshopName, EmployeesWithoutDocumentCount = g.Count() }); var result = await employeeDocumentsQuery.ToListAsync(); // واکشی کارفرماها var workshopIds = result.Select(x => x.WorkshopId).ToList(); var workshopEmployers = await _companyContext.WorkshopEmployers .Include(x => x.Employer) .Where(x => workshopIds.Contains(x.WorkshopId)) .GroupBy(x => x.WorkshopId) .Select(g => g.FirstOrDefault()) .ToListAsync(); // افزودن نام کارفرما به نتیجه foreach (var item in result) { var employer = workshopEmployers.FirstOrDefault(x => x.WorkshopId == item.WorkshopId)?.Employer; item.EmployerName = employer?.FullName; } return result .Where(x => x.EmployeesWithoutDocumentCount > 0) .OrderByDescending(x => x.EmployeesWithoutDocumentCount) .ToList(); } public async Task> GetRejectedItemsByWorkshopIdAndRoleForAdminWorkFlow(long workshopId, long roleId) { var edItemsQuery = _companyContext.EmployeeDocumentItems .Where(x => x.WorkshopId == workshopId && x.DocumentStatus == DocumentStatus.Rejected && x.EmployeeDocuments.IsSentToChecker == false && x.EmployeeDocuments.HasRejectedItems) .Include(x => x.EmployeeDocuments).AsSplitQuery(); if (roleId != 1) { edItemsQuery = edItemsQuery.Where(x => x.UploaderRoleId == roleId); } var edItemsRaw = await edItemsQuery.ToListAsync(); // ← ابتدا همه داده‌ها گرفته شود var edItemsGrouped = edItemsRaw .GroupBy(x => new { x.EmployeeId, x.DocumentLabel }) .Select(x => x.OrderByDescending(y => y.CreationDate).First()) .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 }) .ToList(); //get medias for current documents of employees var mediaIds = edItemsGrouped.Select(x => x.MediaId).ToList(); var mediasList = await _accountContext.Medias .Where(x => mediaIds.Contains(x.id)) .Select(x => new MediaViewModel { Id = x.id, Path = x.Path }) .ToListAsync(); var employeeIds = edItemsGrouped.Select(x => x.EmployeeId).ToList(); var employees = _companyContext.Employees.Where(x => employeeIds.Contains(x.id)).ToList(); var result = edItemsGrouped.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 employeeInfo = employees.First(e => e.id == x.Key); //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 = employeeInfo.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(); result.ForEach(x => { x.EmployeePicture.PicturePath = GetThumbnailPathFromFilePath(x.EmployeePicture.PicturePath); x.IdCardPage1.PicturePath = GetThumbnailPathFromFilePath(x.IdCardPage1.PicturePath); x.IdCardPage2.PicturePath = GetThumbnailPathFromFilePath(x.IdCardPage2.PicturePath); x.IdCardPage3.PicturePath = GetThumbnailPathFromFilePath(x.IdCardPage3.PicturePath); x.IdCardPage4.PicturePath = GetThumbnailPathFromFilePath(x.IdCardPage4.PicturePath); x.NationalCardFront.PicturePath = GetThumbnailPathFromFilePath(x.NationalCardFront.PicturePath); x.NationalCardRear.PicturePath = GetThumbnailPathFromFilePath(x.NationalCardRear.PicturePath); x.MilitaryServiceCard.PicturePath = GetThumbnailPathFromFilePath(x.MilitaryServiceCard.PicturePath); }); return result; } public async Task> GetCreatedEmployeesWorkshopDocumentForAdmin(List workshops, long roleId) { if (!StaticWorkshopAccounts.EmployeeDocumentWorkFlowRoleIds.Contains(roleId)) { return new List(); } // Step 1: Get employee client temps in memory var employeeClientTempData = await _companyContext.EmployeeClientTemps .Where(x => workshops.Contains(x.WorkshopId)) .Select(x => new { x.WorkshopId, x.EmployeeId }) .ToListAsync(); // Step 2: Get employee documents with simplified filter var employeeDocuments = await _companyContext.EmployeeDocuments .Where(x => workshops.Contains(x.WorkshopId) && !x.IsConfirmed && !x.IsSentToChecker) .Select(x => new { x.id, x.WorkshopId, x.EmployeeId, x.IsConfirmed, x.IsSentToChecker, WorkshopName = x.Workshop.WorkshopName }) .ToListAsync(); var filteredDocuments = employeeDocuments .Where(x => employeeClientTempData.Any(temp => temp.WorkshopId == x.WorkshopId && temp.EmployeeId == x.EmployeeId)) .ToList(); var groupedByWorkshop = filteredDocuments .GroupBy(x => x.WorkshopId) .Select(g => new { WorkshopId = g.Key, WorkshopName = g.First().WorkshopName, Count = g.Count() }) .ToList(); // Step 5: Get workshop employers for the filtered workshops var workshopIds = groupedByWorkshop.Select(x => x.WorkshopId).ToList(); var workshopEmployers = await _companyContext.WorkshopEmployers .Where(x => workshopIds.Contains(x.WorkshopId)) .Include(x => x.Employer) .GroupBy(x => x.WorkshopId) .Select(g => g.FirstOrDefault()) .ToListAsync(); // Step 6: Build result var res = groupedByWorkshop .Select(x => new WorkshopWithEmployeeDocumentsViewModel() { WorkshopId = x.WorkshopId, WorkshopFullName = x.WorkshopName, EmployeesWithoutDocumentCount = x.Count, EmployerName = workshopEmployers .FirstOrDefault(y => y.WorkshopId == x.WorkshopId)? .Employer?.FullName }) .Where(x => x.EmployeesWithoutDocumentCount > 0) .OrderByDescending(x => x.EmployeesWithoutDocumentCount) .ToList(); return res; //var employeeClientTemp = _companyContext.EmployeeClientTemps.Where(x => workshops.Contains(x.WorkshopId)); // var query = _companyContext.EmployeeDocuments // .Where(x => workshops.Contains(x.WorkshopId) && // employeeClientTemp.Any(temp => x.EmployeeId == temp.EmployeeId && temp.WorkshopId == x.WorkshopId) && x.IsConfirmed == false &&x.IsSentToChecker == false) // .Include(x => x.Workshop).Include(x => x.EmployeeDocumentItemCollection) // .GroupBy(x => x.WorkshopId).Select(x => new WorkshopWithEmployeeDocumentsViewModel() // { // WorkshopId = x.Key, // WorkshopFullName = x.FirstOrDefault().Workshop.WorkshopFullName, // EmployeesWithoutDocumentCount = x.Count() // }); // var workshopEmployers = await _companyContext.WorkshopEmployers.Include(x => x.Employer) // .Where(x => query.Any(y => y.WorkshopId == x.WorkshopId)) // .GroupBy(x => x.WorkshopId).Select(x => x.FirstOrDefault()).ToListAsync(); // var result = await query.ToListAsync(); // 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 async Task> GetCreatedEmployeesDocumentByWorkshopIdForAdmin(long workshopId) { var employeeClientTemp = _companyContext.EmployeeClientTemps.Where(x => workshopId == x.WorkshopId); var EDItemsList = await _companyContext.EmployeeDocuments .Where(x => workshopId == x.WorkshopId && employeeClientTemp.Any(temp => x.EmployeeId == temp.EmployeeId && temp.WorkshopId == x.WorkshopId)) .Include(x => x.EmployeeDocumentItemCollection) .Where(x => 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 }) .ToListAsync(); //get medias for current documents of employees var mediaIds = EDItemsList.Select(x => x.MediaId).ToList(); var mediasList = await _accountContext.Medias.Where(x => mediaIds.Contains(x.id)) .Select(x => new MediaViewModel() { Id = x.id, Path = x.Path }).ToListAsync(); var result = EDItemsList.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 = employeeClientTemp.First(y => y.EmployeeId == x.Key).EmployeeFullName, 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(); result.ForEach(x => { x.EmployeePicture.PicturePath = GetThumbnailPathFromFilePath(x.EmployeePicture.PicturePath); x.IdCardPage1.PicturePath = GetThumbnailPathFromFilePath(x.IdCardPage1.PicturePath); x.IdCardPage2.PicturePath = GetThumbnailPathFromFilePath(x.IdCardPage2.PicturePath); x.IdCardPage3.PicturePath = GetThumbnailPathFromFilePath(x.IdCardPage3.PicturePath); x.IdCardPage4.PicturePath = GetThumbnailPathFromFilePath(x.IdCardPage4.PicturePath); x.NationalCardFront.PicturePath = GetThumbnailPathFromFilePath(x.NationalCardFront.PicturePath); x.NationalCardRear.PicturePath = GetThumbnailPathFromFilePath(x.NationalCardRear.PicturePath); x.MilitaryServiceCard.PicturePath = GetThumbnailPathFromFilePath(x.MilitaryServiceCard.PicturePath); }); return result; } public async Task> GetClientRejectedDocumentWorkshopsForAdmin(List workshops, long roleId) { var now = DateTime.Now; // آماده‌سازی activeEmployees یک‌بار با EF و انتقال به حافظه var activeEmployees = _companyContext.LeftWorkList .Where(x => workshops.Contains(x.WorkshopId) && x.LeftWorkDate.AddDays(-1) >= now) .Select(x => new { x.WorkshopId, x.EmployeeId }); var clientTemp = _companyContext.EmployeeClientTemps .Where(x => workshops.Contains(x.WorkshopId)) .Select(x => new { x.WorkshopId, x.EmployeeId }); var leftWorkTemp = _companyContext.LeftWorkTemps .Where(x => workshops.Contains(x.WorkshopId)) .Select(x => new { x.WorkshopId, x.EmployeeId }); // ترکیب کل لیست‌ها در حافظه var allActiveEmployees = activeEmployees .Concat(clientTemp) .Concat(leftWorkTemp).ToList(); var contractingPartyIds = _companyContext.WorkshopEmployers.Where(x => workshops.Contains(x.WorkshopId)) .Include(x => x.Employer).Select(x => x.Employer.ContractingPartyId).Distinct().ToList(); var accountIds = await _companyContext.ContractingPartyAccounts .Where(x => contractingPartyIds.Contains(x.PersonalContractingPartyId)).Select(x => x.AccountId) .ToListAsync(); var query =await _companyContext.EmployeeDocuments .Where(x => workshops.Contains(x.WorkshopId)) .Include(x => x.Workshop).Include(x => x.EmployeeDocumentItemCollection) .Where(x => x.IsSentToChecker == false && x.HasRejectedItems && x.EmployeeDocumentItemCollection.Any(i => i.DocumentStatus == DocumentStatus.Rejected && accountIds.Contains(i.UploaderId))) .GroupBy(x => x.WorkshopId).Select(x => new WorkshopWithEmployeeDocumentsViewModel() { WorkshopId = x.Key, WorkshopFullName = x.FirstOrDefault().Workshop.WorkshopName, EmployeesWithoutDocumentCount = x.Count(), EmployeeId = x.First().EmployeeId }).ToListAsync(); query = query.Where(x => (allActiveEmployees.Any(y => y.WorkshopId == x.WorkshopId && y.EmployeeId == x.EmployeeId))).ToList(); var resWorkshopIds = query.Select(x => x.WorkshopId).ToList(); var workshopEmployers = await _companyContext.WorkshopEmployers.Include(x => x.Employer) .Where(x => resWorkshopIds.Contains(x.WorkshopId)) .GroupBy(x => x.WorkshopId).Select(x => x.FirstOrDefault()).ToListAsync(); var result = query; 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 async Task> GetClientRejectedDocumentByWorkshopIdForAdmin(long workshopId) { var employeeIdsInWorkshop = await _companyContext.LeftWorkList .Where(x => x.WorkshopId == workshopId && x.LeftWorkDate.AddDays(-1) >= DateTime.Today) .Select(x => new { x.EmployeeId, FullName = x.Employee.FName + " " + x.Employee.LName }) .Union( _companyContext.EmployeeClientTemps .Where(x => x.WorkshopId == workshopId) .Select(x => new { x.EmployeeId, FullName = x.EmployeeFullName }) ) .Union( _companyContext.LeftWorkTemps .Where(x => x.WorkshopId == workshopId) .Join(_companyContext.Employees, x => x.EmployeeId, e => e.id, (x, e) => new { x.EmployeeId, FullName = e.FName + " " + e.LName }) ) .Distinct() .ToListAsync(); var employeeIdList = employeeIdsInWorkshop.Select(x => x.EmployeeId).ToList(); var EDItemsList = await _companyContext.EmployeeDocumentItems .Where(x => x.WorkshopId == workshopId && x.DocumentStatus == DocumentStatus.Rejected && employeeIdList.Contains(x.EmployeeId) &&x.UploaderType == UserType.Client) .Include(x => x.EmployeeDocuments) .Where(x => x.EmployeeDocuments.IsSentToChecker == false && 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()).ToListAsync(); //get medias for current documents of employees var mediaIds = EDItemsList.Select(x => x.MediaId).ToList(); var mediasList = await _accountContext.Medias.Where(x => mediaIds.Contains(x.id)) .Select(x => new MediaViewModel() { Id = x.id, Path = x.Path }).ToListAsync(); var result = EDItemsList.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 employeeInfo = employeeIdsInWorkshop.First(e => e.EmployeeId == x.Key); //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 = employeeInfo.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(); result.ForEach(x => { x.EmployeePicture.PicturePath = GetThumbnailPathFromFilePath(x.EmployeePicture.PicturePath); x.IdCardPage1.PicturePath = GetThumbnailPathFromFilePath(x.IdCardPage1.PicturePath); x.IdCardPage2.PicturePath = GetThumbnailPathFromFilePath(x.IdCardPage2.PicturePath); x.IdCardPage3.PicturePath = GetThumbnailPathFromFilePath(x.IdCardPage3.PicturePath); x.IdCardPage4.PicturePath = GetThumbnailPathFromFilePath(x.IdCardPage4.PicturePath); x.NationalCardFront.PicturePath = GetThumbnailPathFromFilePath(x.NationalCardFront.PicturePath); x.NationalCardRear.PicturePath = GetThumbnailPathFromFilePath(x.NationalCardRear.PicturePath); x.MilitaryServiceCard.PicturePath = GetThumbnailPathFromFilePath(x.MilitaryServiceCard.PicturePath); }); return result; } public async Task> GetClientRejectedDocumentForClient(long workshopId, long accountId) { var employeeIdsInWorkshop = await _companyContext.LeftWorkList .Where(x => x.WorkshopId == workshopId && x.LeftWorkDate.AddDays(-1) >= DateTime.Today) .Select(x => new { x.EmployeeId, FullName = x.Employee.FName + " " + x.Employee.LName }) .Union( _companyContext.EmployeeClientTemps .Where(x => x.WorkshopId == workshopId) .Select(x => new { x.EmployeeId, FullName = x.EmployeeFullName }) ) .Union( _companyContext.LeftWorkTemps .Where(x => x.WorkshopId == workshopId) .Join(_companyContext.Employees, x => x.EmployeeId, e => e.id, (x, e) => new { x.EmployeeId, FullName = e.FName + " " + e.LName }) ) .Distinct() .ToListAsync(); var employeeIdList = employeeIdsInWorkshop.Select(x => x.EmployeeId).ToList(); var EDItemsList = await _companyContext.EmployeeDocumentItems .Where(x => x.WorkshopId == workshopId && x.DocumentStatus == DocumentStatus.Rejected && employeeIdList.Contains(x.EmployeeId) && x.UploaderId == accountId) .Include(x => x.EmployeeDocuments) .Where(x => x.EmployeeDocuments.IsSentToChecker == false && 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()).ToListAsync(); //get medias for current documents of employees var mediaIds = EDItemsList.Select(x => x.MediaId).ToList(); var mediasList = await _accountContext.Medias.Where(x => mediaIds.Contains(x.id)) .Select(x => new MediaViewModel() { Id = x.id, Path = x.Path }).ToListAsync(); var result = EDItemsList.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(); var employeeInfo = employeeIdsInWorkshop.First(e => e.EmployeeId == x.Key); 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 = employeeInfo.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(); result.ForEach(x => { x.EmployeePicture.PicturePath = GetThumbnailPathFromFilePath(x.EmployeePicture.PicturePath); x.IdCardPage1.PicturePath = GetThumbnailPathFromFilePath(x.IdCardPage1.PicturePath); x.IdCardPage2.PicturePath = GetThumbnailPathFromFilePath(x.IdCardPage2.PicturePath); x.IdCardPage3.PicturePath = GetThumbnailPathFromFilePath(x.IdCardPage3.PicturePath); x.IdCardPage4.PicturePath = GetThumbnailPathFromFilePath(x.IdCardPage4.PicturePath); x.NationalCardFront.PicturePath = GetThumbnailPathFromFilePath(x.NationalCardFront.PicturePath); x.NationalCardRear.PicturePath = GetThumbnailPathFromFilePath(x.NationalCardRear.PicturePath); x.MilitaryServiceCard.PicturePath = GetThumbnailPathFromFilePath(x.MilitaryServiceCard.PicturePath); }); return result; } //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(); //} #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, MediaId = medias.FirstOrDefault(x => x.Id == item.MediaId)?.Id ?? 0, }; } private static string GetThumbnailPathFromFilePath(string filePath) { return string.IsNullOrWhiteSpace(filePath) ? string.Empty : Path.Combine(Path.GetDirectoryName(filePath)!, Path.GetFileNameWithoutExtension(filePath) + $"-thumbnail{Path.GetExtension(filePath)}"); } 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 }