Files
Backend-Api/CompanyManagment.EFCore/Repository/EmployeeDocumentsRepository.cs
mahan ef865d9c68 Add Skill navigation to Phase/ProjectSection, refactor logic
- Add Skill navigation properties to PhaseSection and ProjectSection, with EF Core mappings and migration for foreign keys and indexes.
- Refactor SetSkillFlags in GetProjectsListQueryHandler for clarity and efficiency; use eager loading for Skill.
- Add HasRemainingTime() to TaskSection and enforce time check in ChangeStatusSectionCommandHandler.
- Optimize EmployeeDocumentsRepository queries; add EmployeeId to WorkshopWithEmployeeDocumentsViewModel.
- Improve CustomExceptionHandler to handle FluentValidation exceptions and return proper status codes.
- Add FluentValidation package reference and perform minor code cleanups.
2025-12-15 20:56:32 +03:30

1774 lines
88 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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<long, EmployeeDocuments>, 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<long> 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<EmployeeDocumentItem> 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<EmployeeDocumentsViewModel> 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<EmployeeDocumentsViewModel> 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> 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<EmployeeDocumentsViewModel> 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> 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<WorkshopWithEmployeeDocumentsViewModel> GetWorkshopsWithDocumentsAwaitingReviewForAdminWorkFlow(List<long> 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<WorkshopWithEmployeeDocumentsViewModel> GetWorkshopsWithNewEmployeesWithoutDocuments(List<long> 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<EmployeeDocumentsViewModel> 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;
}
/// <summary>
/// برای دریافت لیست کارگاه های آپلود کرده در لیست چکر
/// </summary>
public List<WorkshopWithEmployeeDocumentsViewModel> 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<WorkshopWithEmployeeDocumentsViewModel> 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<EmployeeDocumentsViewModel> 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<int> GetCheckerWorkFlowCount()
{
return await _companyContext.EmployeeDocumentItems.Include(x => x.EmployeeDocuments)
.CountAsync(x => x.DocumentStatus == DocumentStatus.SubmittedByAdmin || x.DocumentStatus == DocumentStatus.SubmittedByClient);
}
public async Task<int> GetAdminWorkFlowCountForNewEmployees(List<long> 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<int> GetAdminWorkFlowCountForSubmittedAndRejectedDocuments(List<long> 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<EmployeeDocumentsViewModel> 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<ICollection<WorkshopWithEmployeeDocumentsViewModel>> GetWorkshopDocumentCreatedEmployeeForAdmin(List<long> 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<ICollection<WorkshopWithEmployeeDocumentsViewModel>> GetWorkshopDocumentRejectedForAdmin(List<long> 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<List<EmployeeDocumentsViewModel>> 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<List<WorkshopWithEmployeeDocumentsViewModel>> GetCreatedEmployeesWorkshopDocumentForAdmin(List<long> workshops, long roleId)
{
if (!StaticWorkshopAccounts.EmployeeDocumentWorkFlowRoleIds.Contains(roleId))
{
return new List<WorkshopWithEmployeeDocumentsViewModel>();
}
// 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<List<EmployeeDocumentsViewModel>> 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<List<WorkshopWithEmployeeDocumentsViewModel>> GetClientRejectedDocumentWorkshopsForAdmin(List<long> 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<List<EmployeeDocumentsViewModel>> 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<List<EmployeeDocumentsViewModel>> 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<WorkshopWithEmployeeDocumentsViewModel> GetWorkshopsWithNewEmployeesWithoutDocuments(List<long> 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<EmployeeDocumentItem> 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<EmployeeDocumentItem> 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<EmployeeDocumentItem> items,
List<MediaViewModel> 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<EmployeeDocumentItemViewModel> items,
List<MediaViewModel> 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
}