using System.Security.Claims; using BMA.EHR.Recurit.Exam.Service.Core; using BMA.EHR.Recurit.Exam.Service.Data; using BMA.EHR.Recurit.Exam.Service.Models; using BMA.EHR.Recurit.Exam.Service.Request; using BMA.EHR.Recurit.Exam.Service.Response; using Microsoft.EntityFrameworkCore; namespace BMA.EHR.Recurit.Exam.Service.Services { public class CandidateService { #region " Fields " private readonly ApplicationDbContext _context; private readonly IHttpContextAccessor _httpContextAccessor; #endregion #region " Constructor and Destructor " public CandidateService(ApplicationDbContext context, IHttpContextAccessor httpContextAccessor) { _context = context; _httpContextAccessor = httpContextAccessor; } #endregion #region " Properties " private string? UserId => _httpContextAccessor?.HttpContext?.User?.FindFirst(ClaimTypes.NameIdentifier)?.Value; private string? FullName => _httpContextAccessor?.HttpContext?.User?.FindFirst("name")?.Value; #endregion #region " Methods " public async Task GetsAsync(string candidateId) { var candidate = await _context.Candidates.AsQueryable() .Include(x => x.Prefix) .Include(x => x.Relationship) .Include(x => x.CitizenProvince) .Include(x => x.CitizenDistrict) .Include(x => x.RegistProvince) .Include(x => x.RegistDistrict) .Include(x => x.RegistSubDistrict) .Include(x => x.CurrentProvince) .Include(x => x.CurrentDistrict) .Include(x => x.CurrentSubDistrict) .Include(x => x.MarryPrefix) .Include(x => x.FatherPrefix) .Include(x => x.MotherPrefix) .FirstOrDefaultAsync(x => x.Id == Guid.Parse(candidateId)); if (candidate == null) throw new Exception(GlobalMessages.CandidateNotFound); return candidate; } public async Task GetsAsyncInformation(string examId) { var exam = await _context.PeriodExams.AsQueryable() .FirstOrDefaultAsync(x => x.Id == Guid.Parse(examId)); if (exam == null) throw new Exception(GlobalMessages.ExamNotFound); return await _context.Candidates.AsQueryable() .Where(x => x.PeriodExam == exam && x.UserId == UserId) .Select(x => new CandidateInformationResponseItem { Prefix = x.Prefix, PrefixId = x.Prefix != null ? x.Prefix.Id.ToString() : null, FirstName = x.FirstName, LastName = x.LastName, Nationality = x.Nationality, DateOfBirth = x.DateOfBirth, Relationship = x.Relationship, RelationshipId = x.Relationship != null ? x.Relationship.Id.ToString() : null, CitizenProvince = x.CitizenProvince, CitizenProvinceId = x.CitizenProvince != null ? x.CitizenProvince.Id.ToString() : null, CitizenDistrict = x.CitizenDistrict, CitizenDistrictId = x.CitizenDistrict != null ? x.CitizenDistrict.Id.ToString() : null, CitizenDate = x.CitizenDate, Email = x.Email, CitizenId = x.CitizenId, Telephone = x.Telephone, MobilePhone = x.MobilePhone, Knowledge = x.Knowledge, }) .FirstOrDefaultAsync(); } public async Task GetsAsyncAddress(string examId) { var exam = await _context.PeriodExams.AsQueryable() .FirstOrDefaultAsync(x => x.Id == Guid.Parse(examId)); if (exam == null) throw new Exception(GlobalMessages.ExamNotFound); return await _context.Candidates.AsQueryable() .Where(x => x.PeriodExam == exam && x.UserId == UserId) .Select(x => new CandidateAddressResponseItem { RegistAddress = x.RegistAddress, RegistProvince = x.RegistProvince, RegistProvinceId = x.RegistProvince != null ? x.RegistProvince.Id.ToString() : null, RegistDistrict = x.RegistDistrict, RegistDistrictId = x.RegistDistrict != null ? x.RegistDistrict.Id.ToString() : null, RegistSubDistrict = x.RegistSubDistrict, RegistSubDistrictId = x.RegistSubDistrict != null ? x.RegistSubDistrict.Id.ToString() : null, RegistZipCode = x.RegistZipCode, RegistSame = x.RegistSame, CurrentAddress = x.CurrentAddress, CurrentProvince = x.CurrentProvince, CurrentProvinceId = x.CurrentProvince != null ? x.CurrentProvince.Id.ToString() : null, CurrentDistrict = x.CurrentDistrict, CurrentDistrictId = x.CurrentDistrict != null ? x.CurrentDistrict.Id.ToString() : null, CurrentSubDistrict = x.CurrentSubDistrict, CurrentSubDistrictId = x.CurrentSubDistrict != null ? x.CurrentSubDistrict.Id.ToString() : null, CurrentZipCode = x.CurrentZipCode, }) .FirstOrDefaultAsync(); } public async Task GetsAsyncFamily(string examId) { var exam = await _context.PeriodExams.AsQueryable() .FirstOrDefaultAsync(x => x.Id == Guid.Parse(examId)); if (exam == null) throw new Exception(GlobalMessages.ExamNotFound); return await _context.Candidates.AsQueryable() .Where(x => x.PeriodExam == exam && x.UserId == UserId) .Select(x => new CandidateFamilyResponseItem { Marry = x.Marry, MarryPrefix = x.MarryPrefix, MarryPrefixId = x.MarryPrefix != null ? x.MarryPrefix.Id.ToString() : null, MarryFirstName = x.MarryFirstName, MarryLastName = x.MarryLastName, MarryOccupation = x.MarryOccupation, MarryNationality = x.MarryNationality, FatherPrefix = x.FatherPrefix, FatherPrefixId = x.FatherPrefix != null ? x.FatherPrefix.Id.ToString() : null, FatherFirstName = x.FatherFirstName, FatherLastName = x.FatherLastName, FatherOccupation = x.FatherOccupation, FatherNationality = x.FatherNationality, MotherPrefix = x.MotherPrefix, MotherPrefixId = x.MotherPrefix != null ? x.MotherPrefix.Id.ToString() : null, MotherFirstName = x.MotherFirstName, MotherLastName = x.MotherLastName, MotherOccupation = x.MotherOccupation, MotherNationality = x.MotherNationality, }) .FirstOrDefaultAsync(); } public async Task GetsAsyncOccupation(string examId) { var exam = await _context.PeriodExams.AsQueryable() .FirstOrDefaultAsync(x => x.Id == Guid.Parse(examId)); if (exam == null) throw new Exception(GlobalMessages.ExamNotFound); return await _context.Candidates.AsQueryable() .Where(x => x.PeriodExam == exam && x.UserId == UserId) .Select(x => new CandidateOccupationResponseItem { OccupationType = x.OccupationType, OccupationCompany = x.OccupationCompany, OccupationDepartment = x.OccupationDepartment, OccupationEmail = x.OccupationEmail, OccupationTelephone = x.OccupationTelephone, OccupationPosition = x.OccupationPosition, }) .FirstOrDefaultAsync(); } public async Task> GetsAsyncCareer(string examId) { var exam = await _context.PeriodExams.AsQueryable() .FirstOrDefaultAsync(x => x.Id == Guid.Parse(examId)); if (exam == null) throw new Exception(GlobalMessages.ExamNotFound); var candidate = await _context.Candidates.AsQueryable() .FirstOrDefaultAsync(x => x.PeriodExam == exam && x.UserId == UserId); return await _context.Careers.AsQueryable() .Where(x => x.Candidate == candidate) .OrderBy(d => d.DurationStart) .ToListAsync(); } public async Task> GetsAsyncEducation(string examId) { var exam = await _context.PeriodExams.AsQueryable() .FirstOrDefaultAsync(x => x.Id == Guid.Parse(examId)); if (exam == null) throw new Exception(GlobalMessages.ExamNotFound); var candidate = await _context.Candidates.AsQueryable() .FirstOrDefaultAsync(x => x.PeriodExam == exam && x.UserId == UserId); return await _context.Educations.AsQueryable() .Include(x => x.EducationLevel) .Where(x => x.Candidate == candidate) .OrderBy(d => d.DurationStart) .ToListAsync(); } public async Task GetsAsyncRegisterExam(string examId) { var exam = await _context.PeriodExams.AsQueryable() .FirstOrDefaultAsync(x => x.Id == Guid.Parse(examId)); if (exam == null) throw new Exception(GlobalMessages.ExamNotFound); var candidate = await _context.Candidates.AsQueryable() .FirstOrDefaultAsync(x => x.PeriodExam == exam && x.UserId == UserId); return candidate != null; } public async Task CreateAsyncCandidate(string examId) { var exam = await _context.PeriodExams.AsQueryable() .FirstOrDefaultAsync(x => x.Id == Guid.Parse(examId)); if (exam == null) throw new Exception(GlobalMessages.ExamNotFound); var _candidateNumber = await _context.Candidates.AsQueryable() .CountAsync(x => x.PeriodExam == exam); var _candidate = await _context.Candidates.AsQueryable() .FirstOrDefaultAsync(x => x.PeriodExam == exam && x.UserId == UserId); if (_candidate == null) { var candidate = new Candidate { PeriodExam = exam, CreatedAt = DateTime.Now, CreatedUserId = UserId ?? "", LastUpdatedAt = DateTime.Now, LastUpdateUserId = UserId ?? "", CreatedFullName = FullName ?? "", LastUpdateFullName = FullName ?? "", UserId = UserId ?? "", SeatNumber = "CDC-" + (_candidateNumber + 1), }; await _context.Candidates.AddAsync(candidate); await _context.SaveChangesAsync(); return candidate.Id.ToString(); } else { _candidate.LastUpdatedAt = DateTime.Now; _candidate.LastUpdateUserId = UserId ?? ""; _candidate.LastUpdateFullName = FullName ?? ""; return _candidate.Id.ToString(); } } public async Task UpdateAsyncInformation(string examId, CandidateInformationResponseItem updated) { var candidateId = await CreateAsyncCandidate(examId); var candidate = await _context.Candidates.AsQueryable() .FirstOrDefaultAsync(x => x.Id == Guid.Parse(candidateId)); if (candidate == null) throw new Exception(GlobalMessages.ExamNotFound); if (updated.PrefixId != null) { var prefix = await _context.Prefixes.AsQueryable() .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.PrefixId)); if (prefix == null) throw new Exception(GlobalMessages.PrefixNotFound); candidate.Prefix = prefix; } if (updated.RelationshipId != null) { var relationship = await _context.Relationships.AsQueryable() .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.RelationshipId)); if (relationship == null) throw new Exception(GlobalMessages.RelationshipNotFound); candidate.Relationship = relationship; } if (updated.CitizenProvinceId != null) { var citizenProvince = await _context.Provinces.AsQueryable() .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.CitizenProvinceId)); if (citizenProvince == null) throw new Exception(GlobalMessages.ProvinceNotFound); candidate.CitizenProvince = citizenProvince; } if (updated.CitizenDistrictId != null) { var citizenDistrict = await _context.Districts.AsQueryable() .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.CitizenDistrictId)); if (citizenDistrict == null) throw new Exception(GlobalMessages.DistrictNotFound); candidate.CitizenDistrict = citizenDistrict; } candidate.FirstName = updated.FirstName; candidate.LastName = updated.LastName; candidate.Nationality = updated.Nationality; candidate.DateOfBirth = updated.DateOfBirth; candidate.Email = updated.Email; candidate.CitizenId = updated.CitizenId; candidate.CitizenDate = updated.CitizenDate; candidate.Telephone = updated.Telephone; candidate.MobilePhone = updated.MobilePhone; candidate.Knowledge = updated.Knowledge; await _context.SaveChangesAsync(); } public async Task UpdateAsyncAddress(string examId, CandidateAddressResponseItem updated) { var candidateId = await CreateAsyncCandidate(examId); var candidate = await _context.Candidates.AsQueryable() .FirstOrDefaultAsync(x => x.Id == Guid.Parse(candidateId)); if (candidate == null) throw new Exception(GlobalMessages.ExamNotFound); if (updated.RegistProvinceId != null) { var registProvince = await _context.Provinces.AsQueryable() .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.RegistProvinceId)); if (registProvince == null) throw new Exception(GlobalMessages.ProvinceNotFound); candidate.RegistProvince = registProvince; } if (updated.RegistDistrictId != null) { var registDistrict = await _context.Districts.AsQueryable() .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.RegistDistrictId)); if (registDistrict == null) throw new Exception(GlobalMessages.DistrictNotFound); candidate.RegistDistrict = registDistrict; } if (updated.RegistSubDistrictId != null) { var registSubDistrict = await _context.SubDistricts.AsQueryable() .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.RegistSubDistrictId)); if (registSubDistrict == null) throw new Exception(GlobalMessages.SubDistrictNotFound); candidate.RegistSubDistrict = registSubDistrict; candidate.RegistZipCode = registSubDistrict.ZipCode; } if (updated.CurrentProvinceId != null) { var currentProvince = await _context.Provinces.AsQueryable() .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.CurrentProvinceId)); if (currentProvince == null) throw new Exception(GlobalMessages.ProvinceNotFound); candidate.CurrentProvince = currentProvince; } if (updated.CurrentDistrictId != null) { var currentDistrict = await _context.Districts.AsQueryable() .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.CurrentDistrictId)); if (currentDistrict == null) throw new Exception(GlobalMessages.DistrictNotFound); candidate.CurrentDistrict = currentDistrict; } if (updated.CurrentSubDistrictId != null) { var currentSubDistrict = await _context.SubDistricts.AsQueryable() .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.CurrentSubDistrictId)); if (currentSubDistrict == null) throw new Exception(GlobalMessages.SubDistrictNotFound); candidate.CurrentSubDistrict = currentSubDistrict; candidate.CurrentZipCode = currentSubDistrict.ZipCode; } candidate.RegistAddress = updated.RegistAddress; candidate.RegistSame = updated.RegistSame == null ? null : updated.RegistSame; candidate.CurrentAddress = updated.CurrentAddress; await _context.SaveChangesAsync(); } public async Task UpdateAsyncFamily(string examId, CandidateFamilyResponseItem updated) { var candidateId = await CreateAsyncCandidate(examId); var candidate = await _context.Candidates.AsQueryable() .FirstOrDefaultAsync(x => x.Id == Guid.Parse(candidateId)); if (candidate == null) throw new Exception(GlobalMessages.ExamNotFound); if (updated.MarryPrefixId != null) { var prefix = await _context.Prefixes.AsQueryable() .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.MarryPrefixId)); if (prefix == null) throw new Exception(GlobalMessages.PrefixNotFound); candidate.MarryPrefix = prefix; } if (updated.FatherPrefixId != null) { var prefix = await _context.Prefixes.AsQueryable() .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.FatherPrefixId)); if (prefix == null) throw new Exception(GlobalMessages.PrefixNotFound); candidate.FatherPrefix = prefix; } if (updated.MotherPrefixId != null) { var prefix = await _context.Prefixes.AsQueryable() .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.MotherPrefixId)); if (prefix == null) throw new Exception(GlobalMessages.PrefixNotFound); candidate.MotherPrefix = prefix; } candidate.Marry = updated.Marry == null ? null : updated.Marry; candidate.MarryFirstName = updated.MarryFirstName; candidate.MarryLastName = updated.MarryLastName; candidate.MarryOccupation = updated.MarryOccupation; candidate.MarryNationality = updated.MarryNationality; candidate.FatherFirstName = updated.FatherFirstName; candidate.FatherLastName = updated.FatherLastName; candidate.FatherOccupation = updated.FatherOccupation; candidate.FatherNationality = updated.FatherNationality; candidate.MotherFirstName = updated.MotherFirstName; candidate.MotherLastName = updated.MotherLastName; candidate.MotherOccupation = updated.MotherOccupation; candidate.MotherNationality = updated.MotherNationality; await _context.SaveChangesAsync(); } public async Task UpdateAsyncOccupation(string examId, CandidateOccupationResponseItem updated) { var candidateId = await CreateAsyncCandidate(examId); var candidate = await _context.Candidates.AsQueryable() .FirstOrDefaultAsync(x => x.Id == Guid.Parse(candidateId)); if (candidate == null) throw new Exception(GlobalMessages.ExamNotFound); candidate.OccupationType = updated.OccupationType; candidate.OccupationCompany = updated.OccupationCompany; candidate.OccupationDepartment = updated.OccupationDepartment; candidate.OccupationEmail = updated.OccupationEmail; candidate.OccupationTelephone = updated.OccupationTelephone; candidate.OccupationPosition = updated.OccupationPosition; await _context.SaveChangesAsync(); } public async Task CreateAsyncCareer(string examId, CandidateCareerResponseItem updated) { var candidateId = await CreateAsyncCandidate(examId); var candidate = await _context.Candidates.AsQueryable() .FirstOrDefaultAsync(x => x.Id == Guid.Parse(candidateId)); var career = new Career { Candidate = candidate, Name = updated.Name, Position = updated.Position, Salary = updated.Salary, DurationStart = updated.DurationStart, DurationEnd = updated.DurationEnd, Reason = updated.Reason, CreatedAt = DateTime.Now, CreatedUserId = UserId ?? "", LastUpdatedAt = DateTime.Now, LastUpdateUserId = UserId ?? "", CreatedFullName = FullName ?? "", LastUpdateFullName = FullName ?? "", }; await _context.Careers.AddAsync(career); await _context.SaveChangesAsync(); } public async Task CreateAsyncEducation(string examId, CandidateEducationResponseItem updated) { var candidateId = await CreateAsyncCandidate(examId); var candidate = await _context.Candidates.AsQueryable() .FirstOrDefaultAsync(x => x.Id == Guid.Parse(candidateId)); var educationLevel = await _context.EducationLevels.AsQueryable() .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.EducationLevelId)); if (educationLevel == null) throw new Exception(GlobalMessages.EducationLevelNotFound); var education = new Education { Candidate = candidate, EducationLevel = educationLevel, Major = updated.Major, Scores = updated.Scores, Name = updated.Name, DurationStart = updated.DurationStart, DurationEnd = updated.DurationEnd, CreatedAt = DateTime.Now, CreatedUserId = UserId ?? "", LastUpdatedAt = DateTime.Now, LastUpdateUserId = UserId ?? "", CreatedFullName = FullName ?? "", LastUpdateFullName = FullName ?? "", }; await _context.Educations.AddAsync(education); await _context.SaveChangesAsync(); } public async Task UpdateAsyncCareer(string careerId, CandidateCareerResponseItem updated) { var career = await _context.Careers.AsQueryable() .FirstOrDefaultAsync(x => x.Id == Guid.Parse(careerId)); if (career == null) throw new Exception(GlobalMessages.CareerNotFound); career.Name = updated.Name; career.Position = updated.Position; career.Salary = updated.Salary; career.DurationStart = updated.DurationStart; career.DurationEnd = updated.DurationEnd; career.Reason = updated.Reason; career.LastUpdatedAt = DateTime.Now; career.LastUpdateUserId = UserId ?? ""; career.LastUpdateFullName = FullName ?? ""; await _context.SaveChangesAsync(); } public async Task DeleteAsyncCareer(string careerId) { var career = await _context.Careers.AsQueryable() .FirstOrDefaultAsync(x => x.Id == Guid.Parse(careerId)); if (career == null) throw new Exception(GlobalMessages.CareerNotFound); _context.Careers.Remove(career); await _context.SaveChangesAsync(); } public async Task UpdateAsyncEducation(string educationId, CandidateEducationResponseItem updated) { var education = await _context.Educations.AsQueryable() .FirstOrDefaultAsync(x => x.Id == Guid.Parse(educationId)); if (education == null) throw new Exception(GlobalMessages.EducationNotFound); var educationLevel = await _context.EducationLevels.AsQueryable() .FirstOrDefaultAsync(x => x.Id == Guid.Parse(updated.EducationLevelId)); if (educationLevel == null) throw new Exception(GlobalMessages.EducationLevelNotFound); education.EducationLevel = educationLevel; education.Major = updated.Major; education.Scores = updated.Scores; education.Name = updated.Name; education.DurationStart = updated.DurationStart; education.DurationEnd = updated.DurationEnd; education.LastUpdatedAt = DateTime.Now; education.LastUpdateUserId = UserId ?? ""; education.LastUpdateFullName = FullName ?? ""; await _context.SaveChangesAsync(); } public async Task DeleteAsyncEducation(string educationId) { var education = await _context.Educations.AsQueryable() .FirstOrDefaultAsync(x => x.Id == Guid.Parse(educationId)); if (education == null) throw new Exception(GlobalMessages.EducationNotFound); _context.Educations.Remove(education); await _context.SaveChangesAsync(); } public async Task GetStatusCandidateService(string examId) { var exam = await _context.PeriodExams.AsQueryable() .FirstOrDefaultAsync(x => x.Id == Guid.Parse(examId)); if (exam == null) throw new Exception(GlobalMessages.ExamNotFound); var candidate = await _context.Candidates.AsQueryable() .FirstOrDefaultAsync(x => x.PeriodExam == exam && x.UserId == UserId); if (candidate == null) throw new Exception(GlobalMessages.CandidateNotFound); return candidate.Status; } public async Task UserCheckCandidateService(string examId, string status) { var exam = await _context.PeriodExams.AsQueryable() .FirstOrDefaultAsync(x => x.Id == Guid.Parse(examId)); if (exam == null) throw new Exception(GlobalMessages.ExamNotFound); var candidate = await _context.Candidates.AsQueryable() .FirstOrDefaultAsync(x => x.PeriodExam == exam && x.UserId == UserId); if (candidate == null) throw new Exception(GlobalMessages.CandidateNotFound); candidate.Status = status; await _context.SaveChangesAsync(); } public async Task AdminCheckCandidateService(string candidateId, string status, RequestApprove item) { var candidate = await _context.Candidates.AsQueryable() .FirstOrDefaultAsync(x => x.Id == Guid.Parse(candidateId)); if (candidate == null) throw new Exception(GlobalMessages.CandidateNotFound); if (status != "rejectDelete") { candidate.Status = status; if (status == "rejectRegister" || status == "rejectPayment") { candidate.RejectDetail = item.Reason; } } else { _context.Candidates.Remove(candidate); } await _context.SaveChangesAsync(); } public async Task AdminPassCandidateService(string candidateId, string status) { var candidate = await _context.Candidates.AsQueryable() .FirstOrDefaultAsync(x => x.Id == Guid.Parse(candidateId)); if (candidate == null) throw new Exception(GlobalMessages.CandidateNotFound); candidate.Status = status; await _context.SaveChangesAsync(); } #endregion } }