using BMA.EHR.Application.Common.Interfaces; using BMA.EHR.Domain.Extensions; using BMA.EHR.Domain.ModelsExam.Candidate; using BMA.EHR.Domain.Shared; using Microsoft.AspNetCore.Hosting; using Microsoft.EntityFrameworkCore; using System.Text; using System.Text.RegularExpressions; using static BMA.EHR.Domain.Extensions.DateTimeExtension; namespace BMA.EHR.Application.Repositories.Reports { public class CandidateReportRepository { #region " Fields " private readonly IApplicationDBContext _dbContext; private readonly IApplicationDBExamContext _dbExamContext; private readonly IWebHostEnvironment _hostingEnvironment; private readonly MinIOService _documentService; private readonly OrganizationCommonRepository _organizationCommonRepository; #endregion #region " Constructor and Destructor " public CandidateReportRepository(IApplicationDBContext dbContext, IApplicationDBExamContext dbExamContext, MinIOService documentService, OrganizationCommonRepository organizationCommonRepository, IWebHostEnvironment hostEnvironment) { _dbContext = dbContext; _dbExamContext = dbExamContext; _hostingEnvironment = hostEnvironment; _organizationCommonRepository = organizationCommonRepository; _documentService = documentService; } #endregion #region " Methods " #region ใบสมัครสอบ public async Task GetExamCandidateAsync(Guid id) { var careers = await _dbExamContext.Set() .AsQueryable() .Where(x => x.Candidate.Id == id) .ToListAsync(); var yearDiff = 0; var monthDiff = 0; var dayDiff = 0; var sb = new StringBuilder(); foreach (var career in careers) { if (career.DurationEnd < career.DurationStart) { var rangeObj = career.DurationEnd.CalculateBetweenDateV2Value(career.DurationStart); yearDiff = yearDiff + rangeObj.years; monthDiff = monthDiff + rangeObj.months; dayDiff = dayDiff + rangeObj.days; } else { var rangeObj = career.DurationStart.CalculateBetweenDateV2Value(career.DurationEnd); yearDiff = yearDiff + rangeObj.years; monthDiff = monthDiff + rangeObj.months; dayDiff = dayDiff + rangeObj.days; } if (dayDiff >= 30) { monthDiff = monthDiff + (int)(dayDiff / 30); dayDiff = dayDiff % 30; } if (monthDiff >= 12) { yearDiff = yearDiff + (int)(monthDiff / 12); monthDiff = monthDiff % 12; } sb.Clear(); sb.Append(yearDiff == 0 ? "" : $"{yearDiff} ปี "); sb.Append(monthDiff == 0 ? "" : $"{monthDiff} เดือน "); sb.Append(dayDiff == 0 ? "" : $"{dayDiff} วัน "); } var candidate = await _dbExamContext.Set() .Where(x => x.Id == id) .Include(p => p.PeriodExam) .Include(p => p.Educations) .Include(p => p.PositionExam) .Include(p => p.ProfileImg) .FirstOrDefaultAsync(); if (candidate == null) throw new Exception(GlobalMessages.CandidateNotFound); List editorConfirmLists; var textOnly = string.IsNullOrEmpty(candidate.PeriodExam?.EditorConfirm) ? null : Regex.Replace( candidate.PeriodExam.EditorConfirm, "<[^>]+>", string.Empty ) .Replace(" ", " ") .Trim(); if (!string.IsNullOrEmpty(textOnly)) { // ลบข้อความทั้งหมดก่อน "1." เพื่อให้เริ่มต้นที่ข้อแรกเสมอ var cleanedText = Regex.Replace(textOnly, @"^.*?1\.", "1.").Trim(); // ถ้าข้อ 3 จบด้วย "มาตรา 1374." แล้วเลข 4. ติดกับประโยค ให้แทรกขึ้นบรรทัดใหม่เป็นข้อ 4. if (!cleanedText.Contains("\n4.") && Regex.IsMatch(cleanedText, @"1374\.\s*")) { cleanedText = Regex.Replace(cleanedText, @"1374\.\s*", "137\n4. "); } // แยกข้อความเป็นแต่ละข้อ โดย split เมื่อเจอ pattern "ตัวเลข. " // ใช้ lookahead (?=...) เพื่อไม่กินตัวเลขทิ้ง และให้ตัวเลขยังอยู่ในผลลัพธ์ editorConfirmLists = Regex.Split(cleanedText, @"(?=\d+\. )") .Where(s => !string.IsNullOrWhiteSpace(s)) .Select(s => s.Replace("\n", "").Replace("\r", "").Trim()) .ToList(); } else { editorConfirmLists = new List { "-" }; } return new { candidate.Id, AvatarId = candidate.ProfileImg?.Id ?? Guid.Empty, ExamIdenNumber = candidate.ExamIdenNumber ?? "-", PositionName = candidate.PositionExam?.PositionName ?? "-", PositionLevelName = candidate.PositionExam?.PositionLevelName ?? "-", PeriodExamName = candidate.PeriodExam?.Name ?? "-", PeriodExamRound = candidate.PeriodExam?.Round.ToString() ?? "-", PeriodExamYear = candidate.PeriodExam != null ? (candidate.PeriodExam.Year + 543).ToString() : "-", FullName = $"{candidate.PrefixName}{candidate.FirstName} {candidate.LastName}", Religion = candidate.ReligionName ?? "-", Nationality = candidate.Nationality ?? "-", DateOfBirth = candidate.DateOfBirth?.ToThaiFullDate2() ?? "-", Age = candidate.DateOfBirth?.CalculateAgeStrV2(0, 0) ?? "-", CitizenId = candidate.CitizenId ?? "-", EducationLevelExamName = candidate.Educations.FirstOrDefault()?.EducationLevelExamName ?? "-", EducationName = (candidate.Educations.FirstOrDefault()?.EducationLevelExamName is "ปริญญาตรี" or "ปริญญาโท" or "ปริญญาเอก") ? candidate.Educations.FirstOrDefault()?.EducationName : null, EducationMajor = candidate.Educations.FirstOrDefault()?.EducationMajor ?? "-", EducationLocation = candidate.Educations.FirstOrDefault()?.EducationLocation ?? "-", EducationEndDate = candidate.Educations.FirstOrDefault()?.EducationEndDate?.ToThaiFullDate2() ?? "-", EducationScores = candidate.Educations.FirstOrDefault()?.EducationScores ?? "-", EducationType = candidate.Educations.FirstOrDefault()?.EducationType ?? "-", EducationLevelHighName = candidate.Educations.FirstOrDefault()?.EducationLevelHighName ?? "-", OccupationPositionType = candidate.OccupationPositionType == "other" ? "ผู้ปฏิบัติงานอื่นในกรุงเทพมหานคร" : candidate.OccupationPositionType == "temp" ? "ลูกจ้างชั่วคราว" : candidate.OccupationPositionType == "prem" ? "ลูกจ้างประจำ" : "-", OccupationPosition = candidate.OccupationPosition ?? "-", OccupationSalary = candidate.OccupationSalary.HasValue ? (candidate.OccupationSalary.Value % 1 == 0 ? candidate.OccupationSalary.Value.ToString("N0") : candidate.OccupationSalary.Value.ToString("N2")) : "-", OccupationGroup = candidate.OccupationGroup ?? "-", OccupationPile = candidate.OccupationPile ?? "-", OccupationOrg = candidate.OccupationOrg ?? "-", OccupationTelephone = candidate.OccupationTelephone ?? "-", CareersTotal = sb.ToString(), RegistAddress = candidate.RegistAddress ?? "-", RegistProvinceName = candidate.RegistProvinceName ?? "-", RegistDistrictName = candidate.RegistDistrictName ?? "-", RegistSubDistrictName = candidate.RegistSubDistrictName ?? "-", RegistZipCode = candidate.RegistZipCode ?? "-", CurrentAddress = candidate.CurrentAddress ?? candidate.RegistAddress ?? "-", CurrentProvinceName = candidate.CurrentProvinceName ?? candidate.RegistProvinceName ?? "-", CurrentDistrictName = candidate.CurrentDistrictName ?? candidate.RegistDistrictName ?? "-", CurrentSubDistrictName = candidate.CurrentSubDistrictName ?? candidate.RegistSubDistrictName ?? "-", CurrentZipCode = candidate.CurrentZipCode ?? candidate.RegistZipCode ?? "-", Telephone = candidate.Telephone ?? "-", Email = candidate.Email ?? "-", ContactFullName = $"{candidate.ContactPrefixName}{candidate.ContactFirstname} {candidate.ContactLastname}", ContactRelations = candidate.ContactRelations ?? "-", ContactTel = candidate.ContactTel ?? "-", RegisterDate = candidate.RegisterDate?.ToThaiFullDate() ?? "-", IsBachelors = candidate.PositionExam != null && !string.IsNullOrEmpty(candidate.PositionExam.PositionLevelName) && candidate.PositionExam.PositionLevelName.Trim() == "ปฏิบัติการ" ? new List { new { label = "ชื่อปริญญา", value = candidate.Educations.FirstOrDefault()?.EducationName ?? "-" }, new { label = "สาขาวิชา/วิชาเอก", value = candidate.Educations.FirstOrDefault()?.EducationMajor ?? "-" } } : new List { new { label = "สาขาวิชา/วิชาเอก", value = candidate.Educations.FirstOrDefault()?.EducationMajor ?? "-" } }, EditorConfirms = editorConfirmLists }; } public async Task GetExamCareerCandidateAsync(Guid id) { var items = await _dbExamContext.Set().AsQueryable() .Where(x => x.Candidate != null) .Where(x => x.Candidate.Id == id) .OrderBy(x => x.DurationStart) .Select(p => new { Position = p.Position, Type = p.Type, DurationStart = p.DurationStart.ToThaiShortDate2(), DurationEnd = p.DurationEnd.ToThaiShortDate2(), RangeDate = p.RangeDate, }) .ToListAsync(); int retVal = 1; var data = new List(); foreach (var item in items) { var _data = new { Position = item.Position, Type = item.Type, DurationStart = item.DurationStart, DurationEnd = item.DurationEnd, RangeDate = item.RangeDate, Index = retVal.ToString(), }; data.Add(_data); retVal++; } return data; } public async Task GetExamAvatarCandidateAsync(Guid id) { var data = await _dbExamContext.Set().AsQueryable() .Where(x => x.Id == id) .Select(p => new { AvatarId = p.ProfileImg == null ? Guid.Parse("00000000-0000-0000-0000-000000000000") : p.ProfileImg.Id, }) .FirstOrDefaultAsync(); if (data == null) throw new Exception(GlobalMessages.CandidateNotFound); return data.AvatarId; } #endregion #endregion } }