diff --git a/Controllers/RecruitController.cs b/Controllers/RecruitController.cs index 7860e19..18e58fd 100644 --- a/Controllers/RecruitController.cs +++ b/Controllers/RecruitController.cs @@ -7,6 +7,7 @@ using BMA.EHR.Recruit.Service.Models.Recruits; using BMA.EHR.Recruit.Service.Requests.Recruits; using BMA.EHR.Recruit.Service.Responses; using BMA.EHR.Recruit.Service.Services; +using BMA.EHR.Recurit.Service.Data; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; @@ -23,2021 +24,2088 @@ using System.Text; namespace BMA.EHR.Recruit.Service.Controllers { - [Route("api/v{version:apiVersion}/recruit")] - [ApiVersion("1.0")] - [ApiController] - [Produces("application/json")] - [Authorize] - [SwaggerTag("จัดการข้อมูลการสอบแข่งขัน")] - public class RecruitController : BaseController - { - #region " Fields " - - private readonly ApplicationDbContext _context; - private readonly MinIOService _minioService; - private readonly IWebHostEnvironment _webHostEnvironment; - private readonly RecruitService _recruitService; - - private readonly IHttpContextAccessor _httpContextAccessor; - private readonly ILogger _logger; - - #endregion - - #region " Constructor and Destructor " - - public RecruitController(ApplicationDbContext context, - MinIOService minioService, - IWebHostEnvironment webHostEnvironment, - RecruitService recruitService, - IHttpContextAccessor httpContextAccessor, - ILogger logger) - { - _context = context; - _minioService = minioService; - _webHostEnvironment = webHostEnvironment; - _recruitService = recruitService; - _httpContextAccessor = httpContextAccessor; - _logger = logger; - } - - #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 " - - #region " Private " - - private int GetColumnIndex(string[] columns, string name, bool partial = false) - { - try - { - if (partial) - return Array.FindIndex(columns, x => x.Contains(name)) + 1; - else - return Array.FindIndex(columns, x => x == name) + 1; - } - catch - { - return 0; - } - - } - - private string CalculateDiff(DateTime d1, DateTime d2) - { - if (d1 > d2) return "ข้อมูลไม่ถูกต้อง"; - - TimeSpan sp = d2.Subtract(d1); - int yy = sp.Days / 365; - int mm = (sp.Days - (yy * 365)) / 30; - int dd = (sp.Days - (yy * 365) - (mm * 30)); - - var sb = new StringBuilder(); - sb.Clear(); - sb.Append(yy == 0 ? "" : $"{yy} ปี "); - sb.Append(mm == 0 ? "" : $"{mm} เดือน "); - //sb.Append(dd == 0 ? "" : $"{dd} วัน "); - - return sb.ToString(); - } - - private async Task GetExamCount(Guid exam) - { - try - { - return await _context.RecruitPayments.AsQueryable() - .Include(x => x.Recruit) - .ThenInclude(x => x.RecruitImport) - .Where(x => x.Recruit.RecruitImport.Id == exam) - .CountAsync(); - } - catch - { - throw; - } - } - - private async Task GetPassExamCount(Guid exam) - { - try - { - return await _context.RecruitScores.AsQueryable() - .Include(x => x.ScoreImport) - .Where(x => x.ScoreImport.Id == exam) - .Where(x => x.ExamStatus == "ผ่าน") - .CountAsync(); - } - catch - { - throw; - } - } - - private async Task GetScoreCount(Guid exam) - { - try - { - return await _context.RecruitScores.AsQueryable() - .Include(x => x.ScoreImport) - .Where(x => x.ScoreImport.Id == exam) - .CountAsync(); - } - catch - { - throw; - } - } - - #endregion - - #region " Ex. Upload, Download and Delete file " - - /// - /// ตัวอย่างในการเขียน api เพื่อทำการ upload file - /// - /// - /// เมื่อทำการ upload สำเร็จ - /// ค่าตัวแปรที่ส่งมาไม่ถูกต้อง - /// ไม่ได้ Login เข้าระบบ - /// เมื่อเกิดข้อผิดพลาดในการทำงาน - [HttpPost("upload"), DisableRequestSizeLimit] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - [AllowAnonymous] - public async Task> UploadFile() - { - try - { - if (Request.Form.Files == null || Request.Form.Files.Count == 0) - { - return Error(GlobalMessages.NoFileToUpload); - } - - var file = Request.Form.Files[0]; - var doc = await _minioService.UploadFileAsync(file); - - return Success(doc); - } - catch (Exception ex) - { - return Error(ex); - } - } - - /// - /// ตัวอย่างในการเขียน api เพื่อทำการ delete file - /// - /// รหัสไฟล์ในฐานข้อมูล - /// - /// เมื่อทำการ delete file สำเร็จ - /// ค่าตัวแปรที่ส่งมาไม่ถูกต้อง - /// ไม่ได้ Login เข้าระบบ - /// เมื่อเกิดข้อผิดพลาดในการทำงาน - [HttpGet("delete/{id:length(36)}")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - [AllowAnonymous] - public async Task> DeleteFile(Guid id) - { - try - { - await _minioService.DeleteFileAsync(id); - - return Success(); - } - catch (Exception ex) - { - return Error(ex); - } - } - - /// - /// ตัวอย่างในการเขียน api เพื่อทำการ download file - /// - /// รหัสไฟล์ในฐานข้อมูล - /// - /// เมื่อทำการ download file สำเร็จ - /// ค่าตัวแปรที่ส่งมาไม่ถูกต้อง - /// ไม่ได้ Login เข้าระบบ - /// เมื่อเกิดข้อผิดพลาดในการทำงาน - [HttpGet("download/{id:length(36)}")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - [AllowAnonymous] - public async Task> DownloadFile(Guid id) - { - try - { - var file_data = await _minioService.DownloadFileAsync(id); - - Response.Headers["Content-Disposition"] = $"inline; filename={file_data.FileName}"; - - var ret = new FileContentResult(file_data.FileContent, file_data.FileType) - { - FileDownloadName = file_data.FileName - }; - - return ret; - } - catch (Exception ex) - { - return Error(ex); - } - } - - - #endregion - - #region " จัดการรอบการสมัครสอบแข่งขัน " - - /// - /// แสดงข้อมูลรอบการสอบแข่งขัน - /// - /// - /// เมื่อทำการอ่านข้อมูลจาก Relational Database สำเร็จ - /// ค่าตัวแปรที่ส่งมาไม่ถูกต้อง - /// ไม่ได้ Login เข้าระบบ - /// เมื่อเกิดข้อผิดพลาดในการทำงาน - [HttpGet("period")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task> GetPeriodsAsync() - { - try - { - var data = await _context.RecruitImports.AsQueryable() - .Include(x => x.ImportFile) - .Include(x => x.Recruits) - .Include(x => x.ScoreImport) - .ThenInclude(x => x.ImportFile) - .Include(x => x.ScoreImport) - .ThenInclude(x => x.Scores) - .OrderByDescending(x => x.Year) - .ThenByDescending(x => x.Order) - .Select(x => new - { - x.Id, - x.Year, - x.Name, - x.Order, - ImportDate = x.CreatedAt.Date.ToThaiShortDate(), - ExamCount = x.Recruits.Count(), - Score = x.ScoreImport == null ? null : - new - { - ID = x.ScoreImport.Id, - ImportYear = x.ScoreImport.Year, - ImportDate = x.CreatedAt.Date.ToThaiShortDate(), - ScoreCount = x.ScoreImport.Scores.Count(), - - } - }) - .ToListAsync(); - - return Success(data); - } - catch (Exception ex) - { - return Error(ex); - } - } - - /// - /// แสดงข้อมูลรอบการสอบแข่งขันเป็นรายการ - /// - /// รหัสรอบการสอบแข่งขัน - /// - /// เมื่อทำการอ่านข้อมูลจาก Relational Database สำเร็จ - /// ค่าตัวแปรที่ส่งมาไม่ถูกต้อง - /// ไม่ได้ Login เข้าระบบ - /// เมื่อเกิดข้อผิดพลาดในการทำงาน - [HttpGet("period/{id:length(36)}")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task> GetPeriodByIdAsync(Guid id) - { - try - { - var data = await _context.RecruitImports.AsQueryable() - .Include(x => x.RecruitImages) - .ThenInclude(x => x.Document) - .Include(x => x.RecruitDocuments) - .ThenInclude(x => x.Document) - .Include(x => x.ImportFile) - .Include(x => x.Recruits) - .ThenInclude(x => x.Addresses) - .Include(x => x.Recruits) - .ThenInclude(x => x.Occupations) - .Include(x => x.Recruits) - .ThenInclude(x => x.Certificates) - .Include(x => x.Recruits) - .ThenInclude(x => x.Educations) - .Include(x => x.Recruits) - .ThenInclude(x => x.Payments) - .Include(x => x.Recruits) - .ThenInclude(x => x.Documents) - .ThenInclude(x => x.DocumentFile) - .FirstOrDefaultAsync(x => x.Id == id); - - var new_image = new List(); - foreach (var p in data.RecruitImages) - { - new_image.Add(new - { - p.Id, - p.Document.FileName, - p.Document.FileSize, - p.Document.FileType, - detail = _minioService.GetFilePath(p.Document.Id).Result, - }); - } - - // re create doc list - var new_doc = new List(); - foreach (var p in data.RecruitDocuments) - { - new_doc.Add(new - { - p.Id, - p.Document.FileName, - p.Document.FileSize, - p.Document.FileType, - detail = _minioService.GetFilePath(p.Document.Id).Result, - }); - } - - return Success(new { periods = data, images = new_image, files = new_doc }); - } - catch (Exception ex) - { - return Error(ex); - } - } - - - /// - /// เพิ่มข้อมูลรอบการจัดสอบแข่งขัน - /// - /// Request parameters - /// - /// เมื่อทำการเพิ่มข้อมูลสำเร็จ - /// ค่าตัวแปรที่ส่งมาไม่ถูกต้อง - /// ไม่ได้ Login เข้าระบบ - /// เมื่อเกิดข้อผิดพลาดในการทำงาน - [HttpPost("period")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task> PostPeriodAsync([FromBody] PostRecruitImportRequest req) - { - try - { - if (req == null) - return Error(GlobalMessages.InvalidRequestParam, (int)HttpStatusCode.BadRequest); - - var import = new RecruitImport - { - Year = req.Year, - Name = req.Name, - Order = req.Order, - Detail = req.Detail, - Fee = req.Fee, - AnnouncementStartDate = req.AnnouncementStartDate, - AnnouncementEndDate = req.AnnouncementEndDate, - RegisterStartDate = req.RegisterStartDate, - RegisterEndDate = req.RegisterEndDate, - ExamDate = req.ExamDate, - PaymentStartDate = req.PaymentStartDate, - PaymentEndDate = req.PaymentEndDate, - Note = req.Note, - AnnouncementDate = req.AnnouncementDate, - }; - await _context.RecruitImports.AddAsync(import); - - await _context.SaveChangesAsync(); - - return Success(import); - } - catch (Exception ex) - { - return Error(ex); - } - } - - /// - /// แก้ไขข้อมูลรอบการจัดสอบแข่งขัน - /// - /// รหัสรอบการสอบแข่งขัน - /// Request parameters - /// - /// เมื่อทำการเพิ่มข้อมูลสำเร็จ - /// ค่าตัวแปรที่ส่งมาไม่ถูกต้อง - /// ไม่ได้ Login เข้าระบบ - /// เมื่อเกิดข้อผิดพลาดในการทำงาน - [HttpPut("period/{id:length(36)}"), DisableRequestSizeLimit] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task> PutPeriodAsync(Guid id, [FromBody] PostRecruitImportRequest req) - { - try - { - var data = await _context.RecruitImports.AsQueryable().FirstOrDefaultAsync(x => x.Id == id); - - if (data == null) - return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); - - data.Name = req.Name; - data.Year = req.Year; - data.Order = req.Order; - data.Detail = req.Detail; - data.Fee = req.Fee; - data.AnnouncementEndDate = req.AnnouncementEndDate; - data.AnnouncementStartDate = req.AnnouncementStartDate; - data.RegisterStartDate = req.RegisterStartDate; - data.RegisterEndDate = req.RegisterEndDate; - data.PaymentEndDate = req.PaymentEndDate; - data.PaymentStartDate = req.PaymentStartDate; - data.ExamDate = req.ExamDate; - data.Note = req.Note; - data.AnnouncementDate = req.AnnouncementDate; - - await _context.SaveChangesAsync(); - - return Success(data); - - } - catch (Exception ex) - { - return Error(ex); - } - } - - - /// - /// ลบข้อมูลรอบการจัดสอบแข่งขัน - /// - /// รหัสรอบการสอบแข่งขัน - /// - /// เมื่อทำการลบข้อมูลสำเร็จ - /// ค่าตัวแปรที่ส่งมาไม่ถูกต้อง - /// ไม่ได้ Login เข้าระบบ - /// เมื่อเกิดข้อผิดพลาดในการทำงาน - [HttpDelete("period/{id:length(36)}")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task> DeletePeriodAsync(Guid id) - { - try - { - var data = await _context.RecruitImports.AsQueryable() - .Include(x => x.ImportFile) - .Include(x => x.Recruits) - .ThenInclude(x => x.Addresses) - .Include(x => x.Recruits) - .ThenInclude(x => x.Occupations) - .Include(x => x.Recruits) - .ThenInclude(x => x.Certificates) - .Include(x => x.Recruits) - .ThenInclude(x => x.Educations) - .Include(x => x.Recruits) - .ThenInclude(x => x.Payments) - .Include(x => x.Recruits) - .ThenInclude(x => x.Documents) - .ThenInclude(x => x.DocumentFile) - .Include(x => x.ScoreImport) - .ThenInclude(x => x.ImportFile) - .Include(x => x.ScoreImport) - .ThenInclude(x => x.Scores) - .FirstOrDefaultAsync(x => x.Id == id); - - _context.RecruitImports.Remove(data); - await _context.SaveChangesAsync(); - - return Success(); - } - catch (Exception ex) - { - return Error(ex); - } - } - - #endregion - - #region " Candidate Files " - - /// - /// แสดงข้อมูลสำหรับหน้าจอ รายการนำเข้าข้อมูลผู้สมัครสอบแข่งขัน - /// - /// - /// เมื่อแสดงรายการข้อมูลสำเร็จ - /// ค่าตัวแปรที่ส่งมาไม่ถูกต้อง - /// ไม่ได้ Login เข้าระบบ - /// เมื่อเกิดข้อผิดพลาดในการทำงาน - [HttpGet("candidate")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task> GetCandidateFilesAsync() - { - try - { - var data = await _context.RecruitImports.AsQueryable() - .Include(x => x.ImportFile) - .Include(x => x.Recruits) - .Include(x => x.ScoreImport) - .ThenInclude(x => x.ImportFile) - .Include(x => x.ScoreImport) - .ThenInclude(x => x.Scores) - .OrderByDescending(x => x.Year) - .ThenByDescending(x => x.Order) - .Select(x => new - { - x.Id, - x.Year, - x.Name, - x.Order, - ImportDate = x.CreatedAt.Date.ToThaiShortDate(), - ExamCount = x.Recruits.Count(), - Score = x.ScoreImport == null ? null : - new - { - ID = x.ScoreImport.Id, - ImportYear = x.ScoreImport.Year, - ImportDate = x.CreatedAt.Date.ToThaiShortDate(), - ScoreCount = x.ScoreImport.Scores.Count(), - - } - }) - .ToListAsync(); - - return Success(data); - } - catch (Exception ex) - { - return Error(ex); - } - } - - - /// - /// นำเข้ารายชื่อผู้สมัครสอบแข่งขัน - /// - /// - /// เมื่อทำนำเข้าข้อมูลสำเร็จ - /// ค่าตัวแปรที่ส่งมาไม่ถูกต้อง - /// ไม่ได้ Login เข้าระบบ - /// เมื่อเกิดข้อผิดพลาดในการทำงาน - [HttpPost("candidate"), DisableRequestSizeLimit] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task> ImportCandidateFileAsync([FromForm] PostRecruitImportRequest req) - { - var tmpDir = Path.Combine(_webHostEnvironment.ContentRootPath, "tmp"); - if (!Directory.Exists(tmpDir)) - Directory.CreateDirectory(tmpDir); - - var importFile = Path.Combine(tmpDir, $"c_{DateTime.Now.ToString("ddMMyyyyHHmmss")}.xlsx"); - var import_doc_id = ""; - - try - { - if (Request.Form.Files == null || Request.Form.Files.Count == 0) - { - return Error(GlobalMessages.NoFileToUpload); - } - - var file = Request.Form.Files[0]; - var doc = await _minioService.UploadFileAsync(file); - import_doc_id = doc.Id.ToString("D"); - - var fileContent = (await _minioService.DownloadFileAsync(doc.Id)).FileContent; - - // สร้างรอบการบรรจุ โดยเอาเข้ามูลมาใส่จาก Request - var imported = new RecruitImport - { - Year = req.Year, - Order = req.Order, - Name = req.Name, - ImportFile = doc, - CreatedAt = DateTime.Now, - CreatedUserId = UserId ?? "", - CreatedFullName = FullName ?? "System Administrator", - ImportHostories = new List - { - new RecruitImportHistory - { - Description = "นำเข้าข้อมูลผู้สมัครสอบแข่งขัน", - CreatedAt = DateTime.Now, - CreatedUserId = UserId ?? "", - CreatedFullName = FullName ?? "System Administrator", - } - } - }; - - await _context.RecruitImports.AddAsync(imported); - - // import datafile - System.IO.File.WriteAllBytes(importFile, fileContent); - - using (var c_package = new ExcelPackage(new FileInfo(importFile))) - { - // loop from sheet2 to end - - for (int i = 1; i < c_package.Workbook.Worksheets.Count; i++) - { - var workSheet = c_package.Workbook.Worksheets[i]; - var totalRows = workSheet.Dimension.Rows; - var cols = workSheet.GetHeaderColumns(); - - int row = 2; - - while (row <= totalRows) - { - var cell1 = workSheet?.Cells[row, 1]?.GetValue(); - if (cell1 == "" || cell1 == null) break; - - var r = new Models.Recruits.Recruit(); - r.ExamId = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.ExamID)]?.GetValue(); - r.CitizenId = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.PersonalID)]?.GetValue(); - r.Prefix = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Prefix)]?.GetValue(); - r.FirstName = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.FirstName)]?.GetValue(); - r.LastName = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.LastName)]?.GetValue(); - r.Gendor = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Gender)]?.GetValue(); - r.National = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.National)]?.GetValue().IsNull(""); - r.Race = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Race)]?.GetValue().IsNull(""); - r.Religion = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Religion)]?.GetValue().IsNull(""); - r.DateOfBirth = Convert.ToDateTime(workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.DateOfBirth)]?.GetValue().ToDateTime(DateTimeFormat.Ymd, "-")); - r.Marry = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Marry)]?.GetValue(); - r.Isspecial = "N"; - r.CitizenCardIssuer = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.PersonalCardIssue)]?.GetValue(); - r.CitizenCardExpireDate = Convert.ToDateTime(workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.PersonalCardExpireDate)]?.GetValue().ToDateTime(DateTimeFormat.Ymd, "-")); - r.ApplyDate = (DateTime)workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.ApplyDate)]?.GetValue(); - r.PositionName = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.PositionName)]?.GetValue().IsNull(""); - - - // address - r.Addresses.Add(new RecruitAddress() - { - Address = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Address)]?.GetValue() ?? "", - Moo = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Moo)]?.GetValue() ?? "", - Soi = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Soi)]?.GetValue() ?? "", - Road = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Road)]?.GetValue() ?? "", - District = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.District)]?.GetValue() ?? "", - Amphur = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Amphur)]?.GetValue() ?? "", - Province = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Province)]?.GetValue() ?? "", - ZipCode = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.ZipCode)]?.GetValue() ?? "", - Telephone = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Telephone)]?.GetValue() ?? "", - Mobile = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Mobile)]?.GetValue() ?? "", - Address1 = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Address1)]?.GetValue() ?? "", - Moo1 = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Moo1)]?.GetValue() ?? "", - Soi1 = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Soi1)]?.GetValue() ?? "", - Road1 = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Road1)]?.GetValue() ?? "", - District1 = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.District1)]?.GetValue() ?? "", - Amphur1 = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Amphur1)]?.GetValue() ?? "", - Province1 = "", - ZipCode1 = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.ZipCode1)]?.GetValue() ?? "", - }); - - // payment - r.Payments.Add(new RecruitPayment() - { - PaymentId = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.PaymentID)]?.GetValue() ?? "", - CompanyCode = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.CompanyCode)]?.GetValue() ?? "", - TextFile = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.TextFile)]?.GetValue() ?? "", - BankCode = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.BankCode)]?.GetValue() ?? "", - AccountNumber = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.AccouontNumer)]?.GetValue() ?? "", - TransDate = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.TransDate)]?.GetValue() ?? "", - TransTime = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.TransTime)]?.GetValue() ?? "", - CustomerName = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.CustomerName)]?.GetValue() ?? "", - RefNo1 = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.RefNo1)]?.GetValue() ?? "", - TermBranch = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.TermBranch)]?.GetValue() ?? "", - TellerId = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.TellerID)]?.GetValue() ?? "", - CreditDebit = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.CreditDebit)]?.GetValue() ?? "", - PaymentType = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Type)]?.GetValue(), - ChequeNo = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.ChequeNo)]?.GetValue() ?? "", - Amount = (decimal)workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Amount)]?.GetValue(), - ChqueBankCode = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.ChqBankCode)]?.GetValue() ?? "" - }); - - // occupation - r.Occupations.Add(new RecruitOccupation() - { - Occupation = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Occupation)]?.GetValue() ?? "", - Position = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Position)]?.GetValue() ?? "", - Workplace = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Workplace)]?.GetValue() ?? "", - Telephone = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.WorkplaceTelephone)]?.GetValue() ?? "", - WorkAge = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.WorkAge)]?.GetValue() ?? "", - }); - - // certificate - r.Certificates.Add(new RecruitCertificate() - { - CertificateNo = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.CertificateNo)]?.GetValue() ?? "", - Description = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.CertificateDesc)]?.GetValue() ?? "", - IssueDate = Convert.ToDateTime(workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.CertificateIssueDate)]?.GetValue().ToDateTime(DateTimeFormat.Ymd, "-")), - ExpiredDate = Convert.ToDateTime(workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.CertificateExpireDate)]?.GetValue().ToDateTime(DateTimeFormat.Ymd, "-")) - }); - - r.Educations.Add(new RecruitEducation() - { - Degree = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Degree)]?.GetValue() ?? "", - Major = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Major)]?.GetValue() ?? "", - MajorGroupId = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.MajorGroupID)]?.GetValue() ?? "", - MajorGroupName = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.MajorGroupName)]?.GetValue() ?? "", - University = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.University)]?.GetValue() ?? "", - GPA = (double)workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.GPA)]?.GetValue(), - Specialist = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.SpecialList)]?.GetValue() ?? "", - HighDegree = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.HighDegree)]?.GetValue() ?? "", - BachelorDate = Convert.ToDateTime(workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.BachelorDate)]?.GetValue().ToDateTime(DateTimeFormat.Ymd, "-")) - }); - - r.RecruitImport = imported; - _context.Recruits.Add(r); - - //imported.Recruits.Add(r); - row++; - - } - } - } - - // finally save to database - - _context.SaveChanges(); - - return Success(); - - } - catch (Exception ex) - { - await _minioService.DeleteFileAsync(Guid.Parse(import_doc_id)); - return Error(ex); - } - finally - { - if (System.IO.File.Exists(importFile)) - System.IO.File.Delete(importFile); - } - } - - /// - /// ลบข้อมูลนำข้อมูลผู้สมัครสอบแข่งขัน - /// - /// รหัสรอบการสอบแข่งขัน - /// - /// เมื่อทำนำเข้าข้อมูลสำเร็จ - /// ค่าตัวแปรที่ส่งมาไม่ถูกต้อง - /// ไม่ได้ Login เข้าระบบ - /// เมื่อเกิดข้อผิดพลาดในการทำงาน - [HttpDelete("candidate/{id:length(36)}")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task> DeleteCandidateFileAsync(Guid id) - { - try - { - var data = await _context.RecruitImports.AsQueryable() - .Include(x => x.ImportHostories) - .Include(x => x.ImportFile) - .Include(x => x.Recruits) - .ThenInclude(x => x.Addresses) - .Include(x => x.Recruits) - .ThenInclude(x => x.Occupations) - .Include(x => x.Recruits) - .ThenInclude(x => x.Certificates) - .Include(x => x.Recruits) - .ThenInclude(x => x.Educations) - .Include(x => x.Recruits) - .ThenInclude(x => x.Payments) - .Include(x => x.Recruits) - .ThenInclude(x => x.Documents) - .ThenInclude(x => x.DocumentFile) - .Include(x => x.ScoreImport) - .ThenInclude(x => x.ImportFile) - .Include(x => x.ScoreImport) - .ThenInclude(x => x.Scores) - .FirstOrDefaultAsync(x => x.Id == id); - - if (data == null) - return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); - - var rec_import_id = data.ImportFile.Id.ToString("D"); - var score_import_id = data.ScoreImport != null ? data.ScoreImport.ImportFile.Id.ToString("D") : "-"; - - _context.RecruitImports.Remove(data); - await _context.SaveChangesAsync(); - - // delete upload candidate file - await _minioService.DeleteFileAsync(Guid.Parse(rec_import_id)); - - // delete score file - if (score_import_id != "-") - await _minioService.DeleteFileAsync(Guid.Parse(score_import_id)); - - return Success(); - } - catch (Exception ex) - { - return Error(ex); - } - } - - /// - /// แสดงประวัติการนำเข้าข้อมูลการสอบแข่งขัน - /// - /// รหัสรอบการสอบแข่งขัน - /// - /// เมื่อทำนำเข้าข้อมูลสำเร็จ - /// ค่าตัวแปรที่ส่งมาไม่ถูกต้อง - /// ไม่ได้ Login เข้าระบบ - /// เมื่อเกิดข้อผิดพลาดในการทำงาน - [HttpGet("history/{id:length(36)}")] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task> GetImportHistoryAsync(Guid id) - { - try - { - var data = await _context.RecruitImportHistories.AsQueryable() - .Include(x => x.RecruitImport) - .Where(x => x.RecruitImport.Id == id) - .OrderByDescending(x => x.CreatedAt) - .ToListAsync(); - - return Success(data); - } - catch (Exception ex) - { - return Error(ex); - } - } - - - /// - /// นำเข้ารายชื่อผู้สมัครสอบแข่งขัน - /// - /// รหัสรอบการสอบแข่งขัน - /// - /// เมื่อทำนำเข้าข้อมูลสำเร็จ - /// ค่าตัวแปรที่ส่งมาไม่ถูกต้อง - /// ไม่ได้ Login เข้าระบบ - /// เมื่อเกิดข้อผิดพลาดในการทำงาน - [HttpPost("candidate/{id:length(36)}"), DisableRequestSizeLimit] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status400BadRequest)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task> ImportCandidateFileByIdAsync(Guid id) - { - var tmpDir = Path.Combine(_webHostEnvironment.ContentRootPath, "tmp"); - if (!Directory.Exists(tmpDir)) - Directory.CreateDirectory(tmpDir); - - var importFile = Path.Combine(tmpDir, $"c_{DateTime.Now.ToString("ddMMyyyyHHmmss")}.xlsx"); - var import_doc_id = ""; - - try - { - if (Request.Form.Files == null || Request.Form.Files.Count == 0) - { - return Error(GlobalMessages.NoFileToUpload); - } - - var imported = await _context.RecruitImports.AsQueryable() - .Include(x => x.ImportHostories) - .Include(x => x.ImportFile) - .Include(x => x.Recruits) - .ThenInclude(x => x.Addresses) - .Include(x => x.Recruits) - .ThenInclude(x => x.Occupations) - .Include(x => x.Recruits) - .ThenInclude(x => x.Certificates) - .Include(x => x.Recruits) - .ThenInclude(x => x.Educations) - .Include(x => x.Recruits) - .ThenInclude(x => x.Payments) - .Include(x => x.Recruits) - .FirstOrDefaultAsync(x => x.Id == id); - - if (imported == null) - return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); - - if (imported.Recruits != null) - { - // remove old score data - _context.Recruits.RemoveRange(imported.Recruits); - await _context.SaveChangesAsync(); - } - - var file = Request.Form.Files[0]; - var doc = await _minioService.UploadFileAsync(file); - import_doc_id = doc.Id.ToString("D"); - - var fileContent = (await _minioService.DownloadFileAsync(doc.Id)).FileContent; - - // สร้างรอบการบรรจุ โดยเอาเข้ามูลมาใส่จาก Request - imported.ImportHostories.Add(new RecruitImportHistory - { - Description = "นำเข้าข้อมูลผู้สมัครสอบแข่งขัน", - CreatedAt = DateTime.Now, - CreatedUserId = UserId ?? "", - CreatedFullName = FullName ?? "System Administrator", - }); - - //await _context.RecruitImports.AddAsync(imported); - - // import datafile - System.IO.File.WriteAllBytes(importFile, fileContent); - - using (var c_package = new ExcelPackage(new FileInfo(importFile))) - { - // loop from sheet2 to end - - for (int i = 1; i < c_package.Workbook.Worksheets.Count; i++) - { - var workSheet = c_package.Workbook.Worksheets[i]; - var totalRows = workSheet.Dimension.Rows; - var cols = workSheet.GetHeaderColumns(); - - int row = 2; - - while (row <= totalRows) - { - var cell1 = workSheet?.Cells[row, 1]?.GetValue(); - if (cell1 == "" || cell1 == null) break; - - var r = new Models.Recruits.Recruit(); - r.ExamId = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.ExamID)]?.GetValue(); - r.CitizenId = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.PersonalID)]?.GetValue(); - r.Prefix = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Prefix)]?.GetValue(); - r.FirstName = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.FirstName)]?.GetValue(); - r.LastName = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.LastName)]?.GetValue(); - r.Gendor = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Gender)]?.GetValue(); - r.National = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.National)]?.GetValue().IsNull(""); - r.Race = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Race)]?.GetValue().IsNull(""); - r.Religion = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Religion)]?.GetValue().IsNull(""); - r.DateOfBirth = Convert.ToDateTime(workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.DateOfBirth)]?.GetValue().ToDateTime(DateTimeFormat.Ymd, "-")); - r.Marry = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Marry)]?.GetValue(); - r.Isspecial = "N"; - r.CitizenCardIssuer = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.PersonalCardIssue)]?.GetValue(); - r.CitizenCardExpireDate = Convert.ToDateTime(workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.PersonalCardExpireDate)]?.GetValue().ToDateTime(DateTimeFormat.Ymd, "-")); - r.ApplyDate = (DateTime)workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.ApplyDate)]?.GetValue(); - r.PositionName = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.PositionName)]?.GetValue().IsNull(""); - - // address - r.Addresses.Add(new RecruitAddress() - { - Address = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Address)]?.GetValue() ?? "", - Moo = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Moo)]?.GetValue() ?? "", - Soi = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Soi)]?.GetValue() ?? "", - Road = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Road)]?.GetValue() ?? "", - District = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.District)]?.GetValue() ?? "", - Amphur = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Amphur)]?.GetValue() ?? "", - Province = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Province)]?.GetValue() ?? "", - ZipCode = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.ZipCode)]?.GetValue() ?? "", - Telephone = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Telephone)]?.GetValue() ?? "", - Mobile = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Mobile)]?.GetValue() ?? "", - Address1 = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Address1)]?.GetValue() ?? "", - Moo1 = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Moo1)]?.GetValue() ?? "", - Soi1 = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Soi1)]?.GetValue() ?? "", - Road1 = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Road1)]?.GetValue() ?? "", - District1 = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.District1)]?.GetValue() ?? "", - Amphur1 = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Amphur1)]?.GetValue() ?? "", - Province1 = "", - ZipCode1 = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.ZipCode1)]?.GetValue() ?? "", - }); - - // payment - r.Payments.Add(new RecruitPayment() - { - PaymentId = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.PaymentID)]?.GetValue() ?? "", - CompanyCode = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.CompanyCode)]?.GetValue() ?? "", - TextFile = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.TextFile)]?.GetValue() ?? "", - BankCode = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.BankCode)]?.GetValue() ?? "", - AccountNumber = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.AccouontNumer)]?.GetValue() ?? "", - TransDate = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.TransDate)]?.GetValue() ?? "", - TransTime = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.TransTime)]?.GetValue() ?? "", - CustomerName = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.CustomerName)]?.GetValue() ?? "", - RefNo1 = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.RefNo1)]?.GetValue() ?? "", - TermBranch = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.TermBranch)]?.GetValue() ?? "", - TellerId = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.TellerID)]?.GetValue() ?? "", - CreditDebit = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.CreditDebit)]?.GetValue() ?? "", - PaymentType = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Type)]?.GetValue(), - ChequeNo = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.ChequeNo)]?.GetValue() ?? "", - Amount = (decimal)workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Amount)]?.GetValue(), - ChqueBankCode = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.ChqBankCode)]?.GetValue() ?? "" - }); - - // occupation - r.Occupations.Add(new RecruitOccupation() - { - Occupation = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Occupation)]?.GetValue() ?? "", - Position = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Position)]?.GetValue() ?? "", - Workplace = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Workplace)]?.GetValue() ?? "", - Telephone = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.WorkplaceTelephone)]?.GetValue() ?? "", - WorkAge = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.WorkAge)]?.GetValue() ?? "", - }); - - // certificate - r.Certificates.Add(new RecruitCertificate() - { - CertificateNo = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.CertificateNo)]?.GetValue() ?? "", - Description = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.CertificateDesc)]?.GetValue() ?? "", - IssueDate = Convert.ToDateTime(workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.CertificateIssueDate)]?.GetValue().ToDateTime(DateTimeFormat.Ymd, "-")), - ExpiredDate = Convert.ToDateTime(workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.CertificateExpireDate)]?.GetValue().ToDateTime(DateTimeFormat.Ymd, "-")) - }); - - r.Educations.Add(new RecruitEducation() - { - Degree = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Degree)]?.GetValue() ?? "", - Major = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Major)]?.GetValue() ?? "", - MajorGroupId = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.MajorGroupID)]?.GetValue() ?? "", - MajorGroupName = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.MajorGroupName)]?.GetValue() ?? "", - University = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.University)]?.GetValue() ?? "", - GPA = (double)workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.GPA)]?.GetValue(), - Specialist = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.SpecialList)]?.GetValue() ?? "", - HighDegree = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.HighDegree)]?.GetValue() ?? "", - BachelorDate = Convert.ToDateTime(workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.BachelorDate)]?.GetValue().ToDateTime(DateTimeFormat.Ymd, "-")) - }); - - r.RecruitImport = imported; - _context.Recruits.Add(r); - - //imported.Recruits.Add(r); - row++; - - } - } - } - - // finally save to database - - _context.SaveChanges(); - - return Success(); - - } - catch (Exception ex) - { - await _minioService.DeleteFileAsync(Guid.Parse(import_doc_id)); - return Error(ex); - } - finally - { - if (System.IO.File.Exists(importFile)) - System.IO.File.Delete(importFile); - } - } - - #endregion - - #region " Score File " - - [HttpPost("score/{id:length(36)}"), DisableRequestSizeLimit] - public async Task> ImportScoreFileAsync(Guid id) - { - var tmpDir = Path.Combine(_webHostEnvironment.ContentRootPath, "tmp"); - if (!Directory.Exists(tmpDir)) - Directory.CreateDirectory(tmpDir); - - var importFile = Path.Combine(tmpDir, $"s_{DateTime.Now.ToString("ddMMyyyyHHmmss")}.xlsx"); - var import_doc_id = ""; - - try - { - if (Request.Form.Files == null || Request.Form.Files.Count == 0) - { - return Error(GlobalMessages.NoFileToUpload); - } - - var rec_import = await _context.RecruitImports.AsQueryable() - .Include(x => x.ScoreImport) - .ThenInclude(x => x.Scores) - .Include(x => x.ImportHostories) - .FirstOrDefaultAsync(x => x.Id == id); - - if (rec_import == null) - return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); - - if (rec_import.ScoreImport != null) - { - // remove old score data - if (rec_import.ScoreImport.Scores != null) - { - _context.RecruitScores.RemoveRange(rec_import.ScoreImport.Scores); - await _context.SaveChangesAsync(); - } - } - - var file = Request.Form.Files[0]; - var doc = await _minioService.UploadFileAsync(file); - import_doc_id = doc.Id.ToString("D"); - var fileContent = (await _minioService.DownloadFileAsync(doc.Id)).FileContent; - - // create import history - rec_import.ImportHostories.Add(new RecruitImportHistory - { - Description = "นำเข้าข้อมูลผลคะแนนสอบ", - CreatedAt = DateTime.Now, - CreatedUserId = UserId ?? "", - CreatedFullName = FullName ?? "System Administrator", - }); - - // create new file import - var imported = new ScoreImport - { - Year = rec_import.Year, - ImportFile = doc, - Scores = new List() - }; - - // import datafile - System.IO.File.WriteAllBytes(importFile, fileContent); - - using (var c_package = new ExcelPackage(new FileInfo(importFile))) - { - // loop from sheet2 to end - for (int i = 1; i < c_package.Workbook.Worksheets.Count; i++) - { - var workSheet = c_package.Workbook.Worksheets[i]; - var totalRows = workSheet.Dimension.Rows; - var cols = workSheet.GetHeaderColumns(); - - int row = 8; - - while (row <= totalRows) - { - var cell1 = workSheet?.Cells[row, 1]?.GetValue(); - if (cell1 == "" || cell1 == null) break; - - var r = new RecruitScore(); - r.ExamId = workSheet?.Cells[row, 2]?.GetValue(); - - r.FullA = (int)workSheet?.Cells[7, 7]?.GetValue().Replace("(", "").Replace(")", "").Replace("คะแนน", "").Trim().ToInteger(); - r.SumA = workSheet?.Cells[row, 7]?.GetValue() == "ขส." ? 0 : (int)workSheet?.Cells[row, 7]?.GetValue().Replace(".00", "").ToInteger(); - r.PercentageA = workSheet?.Cells[row, 8]?.GetValue() == "ขส." ? 0.0 : (double)workSheet?.Cells[row, 8]?.GetValue(); - r.AStatus = workSheet?.Cells[row, 9]?.GetValue(); - - r.FullB = (int)workSheet?.Cells[7, 12]?.GetValue().Replace("(", "").Replace(")", "").Replace("คะแนน", "").Trim().ToInteger(); - r.SumB = workSheet?.Cells[row, 12]?.GetValue() == "ขส." ? 0 : (int)workSheet?.Cells[row, 12]?.GetValue().Replace(".00", "").ToInteger(); - r.PercentageB = workSheet?.Cells[row, 13]?.GetValue() == "ขส." ? 0.0 : (double)workSheet?.Cells[row, 13]?.GetValue(); - r.BStatus = workSheet?.Cells[row, 14]?.GetValue(); - - r.SumAB = workSheet?.Cells[row, 15]?.GetValue() == "ขส." ? 0 : (int)workSheet?.Cells[row, 15]?.GetValue().Replace(".00", "").ToInteger(); - r.ABStatus = workSheet?.Cells[row, 17]?.GetValue(); - - r.FullC = (int)workSheet?.Cells[7, 20]?.GetValue().Replace("(", "").Replace(")", "").Replace("คะแนน", "").Trim().ToInteger(); - r.SumC = workSheet?.Cells[row, 20]?.GetValue() == "ขส." ? 0 : (int)workSheet?.Cells[row, 20]?.GetValue().Replace(".00", "").ToInteger(); - r.PercentageC = workSheet?.Cells[row, 21]?.GetValue() == "ขส." ? 0.0 : (double)workSheet?.Cells[row, 21]?.GetValue(); - r.CStatus = workSheet?.Cells[row, 22]?.GetValue(); - - r.ExamStatus = workSheet?.Cells[row, 24]?.GetValue(); - r.Number = workSheet?.Cells[row, 25]?.GetValue() ?? ""; - r.Major = workSheet.Name; - - - imported.Scores.Add(r); - row++; - } - } - } - - // finally save to database - rec_import.ScoreImport = imported; - await _context.SaveChangesAsync(); - - return Success(); - - } - catch (Exception ex) - { - await _minioService.DeleteFileAsync(Guid.Parse(import_doc_id)); - return Error(ex); - } - finally - { - if (System.IO.File.Exists(importFile)) - System.IO.File.Delete(importFile); - } - } - - #endregion - - #region " Exam Information " - - /// - /// แสดงข้อมูลสำหรับหน้าจอ : รายการข้อมูลผู้สมัครสอบ - /// - [HttpGet("exam")] - public async Task> GetExamResultAsync() - { - try - { - var data = await _context.RecruitImports.AsQueryable() - .OrderByDescending(x => x.Year) - .ThenByDescending(x => x.Order) - .Select(x => new - { - x.Id, - ExamYear = x.Year.ToThaiYear(), - ExamOrder = x.Order, - Description = x.Name, - }) - .ToListAsync(); - - var result = new List(); - - foreach (var d in data) - { - result.Add(new - { - ExamYear = d.ExamYear, - Decription = d.Description, - ExamCount = await GetExamCount(d.Id), - PassCount = await GetPassExamCount(d.Id), - NotPassCount = (await GetExamCount(d.Id) - await GetPassExamCount(d.Id)) - }); - } - - return Success(result); - } - catch (Exception ex) - { - return Error(ex); - } - } - - [HttpPost("exam/{id:length(36)}")] - public ActionResult GetExamResultById([FromBody] RecruitExamRequest req, Guid id) - { - try - { - var p_Id = new MySqlParameter("@id", id); - var data = new List(); - using (var cmd = _context.Database.GetDbConnection().CreateCommand()) - { - cmd.CommandTimeout = 0; - var sb = new StringBuilder(); - cmd.Parameters.Clear(); - sb.Clear(); - sb.Append(" SELECT * "); - sb.Append(" FROM exam_info "); - sb.Append(" WHERE recruit_import_id = @id "); - cmd.Parameters.Add(p_Id); - - if (req.ExamAttribute != null && req.ExamAttribute != "") - { - sb.Append(" AND examAttribute = @a "); - cmd.Parameters.Add(new MySqlParameter("@a", req.ExamAttribute)); - } - - if (req.ExamResult != null && req.ExamResult != "") - { - sb.Append(" AND result = @r "); - cmd.Parameters.Add(new MySqlParameter("@r", req.ExamResult)); - } - - cmd.CommandText = sb.ToString(); - - _context.Database.OpenConnection(); - var da = new MySqlDataAdapter(cmd as MySqlCommand); - var dt = new DataTable(); - da.Fill(dt); - - foreach (DataRow dr in dt.Rows) - { - data.Add(new - { - examID = dr["examID"].ToString(), - profileID = dr["profileID"].ToString(), - prefix = dr["prefix"].ToString(), - fullName = dr["fullName"].ToString(), - dateOfBirth = dr["dateofbirth"] == null ? "" : Convert.ToDateTime(dr["dateofbirth"]).ToThaiShortDate(), - gender = dr["gender"].ToString(), - degree = dr["degree"].ToString(), - major = dr["major"].ToString(), - majorgroup = dr["majorgroup"].ToString(), - certificateNo = dr["certificateno"].ToString(), - certificateIssueDate = dr["certificateIssueDate"] == null ? "" : Convert.ToDateTime(dr["certificateIssueDate"]).ToThaiShortDate(), - ExamScore = dr["score"] == null ? 0 : dr["score"].ToString().ToInteger(), - ExamResult = dr["result"].ToString(), - ExamAttribute = dr["examAttribute"].ToString(), - Remark = dr["remark"].ToString(), - IsSpecial = dr["isspecial"].ToString(), - applyDate = dr["applydate"] == null ? "" : Convert.ToDateTime(dr["applydate"]).ToThaiShortDate(), - university = dr["university"].ToString(), - position_name = dr["position_name"].ToString(), - exam_name = dr["exam_name"].ToString(), - exam_order = dr["exam_order"].ToString(), - score_year = Convert.ToInt32(dr["score_year"]).ToThaiYear().ToString(), - }); - } - - } - - dynamic header = null; - using (var cmd = _context.Database.GetDbConnection().CreateCommand()) - { - var sb = new StringBuilder(); - cmd.CommandTimeout = 0; - cmd.Parameters.Clear(); - sb.Clear(); - sb.Append(" SELECT * "); - sb.Append(" FROM sum_exam_info "); - sb.Append(" WHERE recruit_import_id = @id "); - cmd.Parameters.Add(p_Id); - - cmd.CommandText = sb.ToString(); - - - _context.Database.OpenConnection(); - MySqlDataAdapter da = new MySqlDataAdapter(cmd as MySqlCommand); - DataTable dt = new DataTable(); - da.Fill(dt); - if (dt.Rows.Count == 0) - { - header = new - { - count = 0, - pass = 0, - notpass = 0 - }; - } - else - { - var dr = dt.Rows[0]; - header = new - { - count = dr["count"].ToString().ToInteger(), - pass = dr["pass"].ToString().ToInteger(), - notpass = dr["notpass"].ToString().ToInteger() - }; - } - } - - return Success(new - { - data = data, - header = header, - }); - } - catch (Exception ex) - { - return Error(ex); - } - } - - [HttpGet("exam/{id:length(36)}/{examId}")] - public async Task> GetExamResultByPersonAsync(Guid id, string examId) - { - try - { - var data = await _context.Recruits.AsQueryable() - .Include(x => x.RecruitImport) - .Include(x => x.Documents) - .ThenInclude(x => x.DocumentFile) - .Where(x => x.RecruitImport.Id == id) - .Where(x => x.ExamId == examId) - .Join(_context.RecruitScores.AsQueryable() - .Include(x => x.ScoreImport), - rc => new { rc.RecruitImport.Year, rc.ExamId }, - sc => new { sc.ScoreImport.Year, sc.ExamId }, - (p, sr) => new - { - ExamID = p.ExamId, - ProfileID = p.CitizenId, - p.Prefix, - FullName = $"{p.FirstName} {p.LastName}", - DateOfBirth = p.DateOfBirth.ToThaiShortDate(), - Gender = p.Gendor, - Degree = p.Educations.First().Degree, - Major = p.Educations.First().Major, - CertificateNo = p.Certificates.First().CertificateNo, - CertificateIssueDate = p.Certificates.First().IssueDate.ToThaiShortDate(), - ExamResult = sr == null ? "" : sr.ExamStatus, - ExamAttribute = _recruitService.CheckValidCertificate(p.Certificates.First().IssueDate, 5) ? "มีคุณสมบัติ" : "ไม่มีคุณสมบัติ", - IsSpecial = p.Isspecial, - Remark = p.Remark, - University = p.Educations.First().University, - PositionName = p.PositionName, - ExamName = p.RecruitImport.Name, - ExamOrder = p.RecruitImport.Order, - ExamYear = p.RecruitImport.Year.ToThaiYear(), - Score = sr == null ? 0 : sr.SumA + sr.SumB + sr.SumC, - Number = sr == null ? "" : sr.Number, - ExamCount = _recruitService.GetExamCount(p.CitizenId), - ScoreExpire = p.RecruitImport.AnnouncementDate == null ? "" : p.RecruitImport.AnnouncementDate.Value.AddYears(2).ToThaiShortDate(), - ScoreResult = sr == null ? null : new - { - ScoreAFull = sr.FullA, - ScoreA = sr.SumA, - ScoreBFull = sr.FullB, - ScoreB = sr.SumB, - ScoreCFull = sr.FullC, - ScoreC = sr.SumC, - ScoreSumFull = sr.FullA + sr.FullB + sr.FullC, - ScoreSum = sr.SumA + sr.SumB + sr.SumC, - ExamResult = sr.ExamStatus - }, - Attachments = p.Documents.Select(a => new - { - FileName = a.DocumentFile.FileName, - DocumentId = a.DocumentFile.Id - }) - }) - .FirstOrDefaultAsync(); - - return Success(data); - } - catch (Exception ex) - { - return Error(ex); - } - } - - #endregion - - #region " For CMS " - - [HttpGet("competitive")] - [AllowAnonymous] - public IActionResult GetPeriodForCMS([FromQuery] int limit = 0) - { - try - { - var this_year = DateTime.Now.Year.ToCeYear(); - - var periods = (from r in _context.RecruitImports.AsQueryable().Include(x => x.RecruitImages) - where r.Year == this_year - orderby r.AnnouncementStartDate descending - select new - { - id = r.Id, - title = $"{r.Name} ครั้งที่ {r.Order}/{r.Year.ToThaiYear()}", - category = "สำนักงาน ก.ก.", - category_id = 1, - announcement_startDate = r.AnnouncementStartDate == null ? "" : r.AnnouncementStartDate.Value.ToString("yyyy-MM-dd"), - announcement_endDate = r.AnnouncementEndDate == null ? "" : r.AnnouncementEndDate.Value.ToString("yyyy-MM-dd"), - announcementExam = true, - register_startDate = r.RegisterStartDate == null ? "" : r.RegisterStartDate.Value.ToString("yyyy-MM-dd"), - register_endDate = r.RegisterEndDate == null ? "" : r.RegisterEndDate.Value.ToString("yyyy-MM-dd"), - payment_startDate = r.PaymentStartDate == null ? "" : r.PaymentStartDate.Value.ToString("yyyy-MM-dd"), - payment_endDate = r.PaymentEndDate == null ? "" : r.PaymentEndDate.Value.ToString("yyyy-MM-dd"), - exam_date = r.ExamDate == null ? "" : r.ExamDate.Value.ToString("yyyy-MM-dd"), - image = r.RecruitImages.OrderBy(o => o.CreatedAt).FirstOrDefault() == null ? "" : - r.RecruitImages.OrderBy(o => o.CreatedAt).FirstOrDefault().Document.Id.ToString("D") - }) - - .ToList(); - - - //var periods = _context.RecruitImports.AsQueryable() - // .Where(x => x.Year == this_year) - // .Include(x => x.RecruitImages) - // .Select(r => new - // { - // id = r.Id, - // title = $"{r.Name} ครั้งที่ {r.Order}/{r.Year.ToThaiYear()}", - // category = "สำนักงาน ก.ก.", - // category_id = 1, - // announcement_startDate = r.AnnouncementStartDate == null ? "" : r.AnnouncementStartDate.Value.ToString("yyyy-mm-dd"), - // announcement_endDate = r.AnnouncementEndDate == null ? "" : r.AnnouncementEndDate.Value.ToString("yyyy-MM-dd"), - // announcementExam = true, - // register_startDate = r.RegisterStartDate == null ? "" : r.RegisterStartDate.Value.ToString("yyyy-MM-dd"), - // register_endDate = r.RegisterEndDate == null ? "" : r.RegisterEndDate.Value.ToString("yyyy-MM-dd"), - // payment_startDate = r.PaymentStartDate == null ? "" : r.PaymentStartDate.Value.ToString("yyyy-MM-dd"), - // payment_endDate = r.PaymentEndDate == null ? "" : r.PaymentEndDate.Value.ToString("yyyy-MM-dd"), - // exam_date = r.ExamDate == null ? "" : r.ExamDate.Value.ToString("yyyy-MM-dd"), - // image = r.RecruitImages.OrderBy(o => o.CreatedAt).FirstOrDefault() == null ? "" : - // r.RecruitImages.OrderBy(o => o.CreatedAt).FirstOrDefault().Document.Id.ToString("D") - // }) - // .OrderByDescending(x => x.announcement_startDate) - // .ToList(); - - - if (limit > 0) - periods = periods.Take(limit).ToList(); - - - var result = new List(); - foreach (var p in periods) - { - result.Add(new - { - p.id, - p.title, - p.category, - p.category_id, - p.announcementExam, - p.announcement_startDate, - p.announcement_endDate, - p.register_endDate, - p.register_startDate, - p.payment_startDate, - p.payment_endDate, - p.exam_date, - image = p.image == "" ? "" : _minioService.GetFilePath(Guid.Parse(p.image)).Result, - }); - } - - return Ok(result); - } - catch (Exception ex) - { - return StatusCode(500, ex.Message); - } - } - - [HttpGet("competitive/{id:length(36)}")] - [AllowAnonymous] - public IActionResult GetPeriodForCMSById(Guid id) - { - try - { - var periods = (from r in _context.RecruitImports.AsQueryable() - .Include(x => x.RecruitDocuments) - .ThenInclude(x => x.Document) - .Include(x => x.RecruitImages) - .ThenInclude(x => x.Document) - where r.Id == id - select new - { - id = r.Id, - title = $"{r.Name} ครั้งที่ {r.Order}/{r.Year.ToThaiYear()}", - detail = r.Detail, - category = "สำนักงาน ก.ก.", - category_id = 1, - announcement_startDate = r.AnnouncementStartDate == null ? "" : r.AnnouncementStartDate.Value.ToString("yyyy-MM-dd"), - announcement_endDate = r.AnnouncementEndDate == null ? "" : r.AnnouncementEndDate.Value.ToString("yyyy-MM-dd"), - start = r.AnnouncementStartDate == null ? "" : r.AnnouncementStartDate.Value.ToString("yyyy-mm-dd"), - end = r.AnnouncementEndDate == null ? "" : r.AnnouncementEndDate.Value.ToString("yyyy-MM-dd"), - announcementExam = true, - register_startDate = r.RegisterStartDate == null ? "" : r.RegisterStartDate.Value.ToString("yyyy-MM-dd"), - register_endDate = r.RegisterEndDate == null ? "" : r.RegisterEndDate.Value.ToString("yyyy-MM-dd"), - payment_startDate = r.PaymentStartDate == null ? "" : r.PaymentStartDate.Value.ToString("yyyy-MM-dd"), - payment_endDate = r.PaymentEndDate == null ? "" : r.PaymentEndDate.Value.ToString("yyyy-MM-dd"), - examDate = r.ExamDate == null ? "" : r.ExamDate.Value.ToString("yyyy-MM-dd"), - Images = r.RecruitImages.OrderBy(x => x.CreatedAt).Select(s => new - { - Title = s.Document.FileName, - Url = s.Document.Id.ToString("D") - }).ToList(), - Files = r.RecruitDocuments.OrderBy(x => x.CreatedAt).Select(s => new - { - Title = s.Document.FileName, - Url = s.Document.Id.ToString("D") - }).ToList(), - }).FirstOrDefault(); - - // re create image list - var new_image = new List(); - foreach (var p in periods.Images) - { - new_image.Add(new - { - Title = p.Title, - Url = _minioService.GetFilePath(Guid.Parse(p.Url)).Result, - }); - } - - // re create doc list - var new_doc = new List(); - foreach (var p in periods.Files) - { - new_doc.Add(new - { - Title = p.Title, - Url = _minioService.GetFilePath(Guid.Parse(p.Url)).Result, - }); - } - - var result = new - { - periods.id, - periods.title, - periods.detail, - periods.category, - periods.category_id, - periods.announcement_endDate, - periods.announcement_startDate, - periods.start, - periods.end, - periods.announcementExam, - periods.register_endDate, - periods.register_startDate, - periods.payment_endDate, - periods.payment_startDate, - periods.examDate, - images = new_image, - files = new_doc - }; - - - return Ok(result); - } - catch (Exception ex) - { - return StatusCode(500, ex.Message); - } - } - - - #endregion - - #region " Export Excel " - - [HttpGet("export/exam/{id:length(36)}")] - public async Task> ExportExamAsync(Guid id) - { - var data = await _context.RecruitImports.AsQueryable() - .Include(x => x.Recruits) - .FirstOrDefaultAsync(x => x.Id == id); - - if (data == null) - return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); - - var header = $"{data.Name} ครั้งที่ {data.Order}/{data.Year.ToThaiYear()}"; - - var template_dir = Path.Combine(_webHostEnvironment.ContentRootPath, "Templates"); - - var template_file = Path.Combine(template_dir, "ExamList.xlsx"); - - var tmpDir = Path.Combine(_webHostEnvironment.ContentRootPath, "tmp"); - if (!Directory.Exists(tmpDir)) - Directory.CreateDirectory(tmpDir); - - var exportFile = Path.Combine(tmpDir, $"ExamList_{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx"); - try - { - // copy template - System.IO.File.Copy(template_file, exportFile); - - using (var excel = new ExcelPackage(new FileInfo(exportFile))) - { - var workSheet = excel.Workbook.Worksheets[0]; - - - workSheet.Cells[1, 2].Value = header; - var recruits = data.Recruits.OrderBy(x => x.ExamId).ToList(); - - var row = 4; // start at row 4 - foreach (var item in recruits) - { - workSheet.Cells[row, 1].Value = item.ExamId; - workSheet.Cells[row, 2].Value = item.CitizenId; - workSheet.Cells[row, 3].Value = $"{item.Prefix}{item.FirstName} {item.LastName}"; - workSheet.Cells[row, 4].Value = item.PositionName; - - row++; - } - - excel.Save(); - - using (FileStream fs = new FileStream(exportFile, FileMode.Open, FileAccess.Read)) - { - byte[] bytes = System.IO.File.ReadAllBytes(exportFile); - fs.Read(bytes, 0, System.Convert.ToInt32(fs.Length)); - fs.Close(); - - var fname = Path.GetFileName(exportFile); - - Response.Headers["Content-Disposition"] = $"inline; filename={fname}"; - - var ret = new FileContentResult(bytes, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") - { - FileDownloadName = fname - }; - - return ret; - } - } - } - catch (Exception ex) - { - return Error(ex, "ไม่สามารถส่งออกรายชื่อผู้มีสิทธิ์สอบได้!!"); - } - finally - { - if (System.IO.File.Exists(exportFile)) - System.IO.File.Delete(exportFile); - } - } - - [HttpGet("export/pass-exam/{id:length(36)}")] - public async Task> ExportPassExamAsync(Guid id) - { - var data = await _context.RecruitImports.AsQueryable() - .Include(x => x.Recruits) - .FirstOrDefaultAsync(x => x.Id == id); - - var data_pass = await _context.RecruitImports.AsQueryable() - .Include(x => x.ScoreImport) - .ThenInclude(x => x.Scores) - .FirstOrDefaultAsync(x => x.Id == id); - - if (data == null) - return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); - - if (data_pass == null) - return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); - - var header = $"{data.Name} ครั้งที่ {data.Order}/{data.Year.ToThaiYear()}"; - - var template_dir = Path.Combine(_webHostEnvironment.ContentRootPath, "Templates"); - - var template_file = Path.Combine(template_dir, "PassAExamList.xlsx"); - - var tmpDir = Path.Combine(_webHostEnvironment.ContentRootPath, "tmp"); - if (!Directory.Exists(tmpDir)) - Directory.CreateDirectory(tmpDir); - - var exportFile = Path.Combine(tmpDir, $"PassExamList_{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx"); - - try - { - var result = (from r in data.Recruits.ToList() - join s in data_pass.ScoreImport.Scores.Where(x => x.AStatus == "ผ่าน").ToList() on r.ExamId equals s.ExamId - select new - { - r.ExamId, - r.CitizenId, - r.Prefix, - r.FirstName, - r.LastName, - s.FullA, - s.SumA, - s.AStatus, - - }).ToList(); - - // copy template - System.IO.File.Copy(template_file, exportFile); - - using (var excel = new ExcelPackage(new FileInfo(exportFile))) - { - var workSheet = excel.Workbook.Worksheets[0]; - - - workSheet.Cells[1, 2].Value = header; - var recruits = data.Recruits.OrderBy(x => x.ExamId).ToList(); - - var row = 4; // start at row 4 - foreach (var item in result) - { - workSheet.Cells[row, 1].Value = item.ExamId; - workSheet.Cells[row, 2].Value = item.CitizenId; - workSheet.Cells[row, 3].Value = $"{item.Prefix}{item.FirstName} {item.LastName}"; - workSheet.Cells[row, 4].Value = item.FullA; - workSheet.Cells[row, 5].Value = item.SumA; - workSheet.Cells[row, 6].Value = item.AStatus; - - row++; - } - - excel.Save(); - - using (FileStream fs = new FileStream(exportFile, FileMode.Open, FileAccess.Read)) - { - byte[] bytes = System.IO.File.ReadAllBytes(exportFile); - fs.Read(bytes, 0, System.Convert.ToInt32(fs.Length)); - fs.Close(); - - var fname = Path.GetFileName(exportFile); - - Response.Headers["Content-Disposition"] = $"inline; filename={fname}"; - - var ret = new FileContentResult(bytes, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") - { - FileDownloadName = fname - }; - - return ret; - } - } - } - catch (Exception ex) - { - return Error(ex, "ไม่สามารถส่งออกรายชื่อผู้สอบผ่านได้!!"); - } - finally - { - if (System.IO.File.Exists(exportFile)) - System.IO.File.Delete(exportFile); - } - } - - [HttpGet("export/pass/{id:length(36)}")] - public async Task> ExportPassExamResultAsync(Guid id) - { - var data = await _context.RecruitImports.AsQueryable() - .Include(x => x.Recruits) - .FirstOrDefaultAsync(x => x.Id == id); - - var data_pass = await _context.RecruitImports.AsQueryable() - .Include(x => x.ScoreImport) - .ThenInclude(x => x.Scores) - .FirstOrDefaultAsync(x => x.Id == id); - - if (data == null) - return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); - - if (data_pass == null) - return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); - - var header = $"{data.Name} ครั้งที่ {data.Order}/{data.Year.ToThaiYear()}"; - - var template_dir = Path.Combine(_webHostEnvironment.ContentRootPath, "Templates"); - - var template_file = Path.Combine(template_dir, "PassExamList.xlsx"); - - var tmpDir = Path.Combine(_webHostEnvironment.ContentRootPath, "tmp"); - if (!Directory.Exists(tmpDir)) - Directory.CreateDirectory(tmpDir); - - var exportFile = Path.Combine(tmpDir, $"PassExamList_{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx"); - - try - { - var result = (from r in data.Recruits.ToList() - join s in data_pass.ScoreImport.Scores.Where(x => x.ExamStatus == "ผ่าน").ToList() on r.ExamId equals s.ExamId - select new - { - r.ExamId, - r.CitizenId, - r.Prefix, - r.FirstName, - r.LastName, - Full = s.FullA + s.FullB + s.FullC, - Sum = s.SumA + s.SumB + s.SumC, - Status = s.ExamStatus, - r.PositionName, - s.Number - }).ToList(); - - // copy template - System.IO.File.Copy(template_file, exportFile); - - using (var excel = new ExcelPackage(new FileInfo(exportFile))) - { - var workSheet = excel.Workbook.Worksheets[0]; - - - workSheet.Cells[1, 2].Value = header; - var recruits = data.Recruits.OrderBy(x => x.ExamId).ToList(); - - var row = 4; // start at row 4 - foreach (var item in result) - { - workSheet.Cells[row, 1].Value = item.ExamId; - workSheet.Cells[row, 2].Value = item.CitizenId; - workSheet.Cells[row, 3].Value = $"{item.Prefix}{item.FirstName} {item.LastName}"; - workSheet.Cells[row, 4].Value = item.Full; - workSheet.Cells[row, 5].Value = item.Sum; - workSheet.Cells[row, 6].Value = item.Status; - workSheet.Cells[row, 7].Value = item.Number; - workSheet.Cells[row, 8].Value = item.PositionName; - - row++; - } - - excel.Save(); - - using (FileStream fs = new FileStream(exportFile, FileMode.Open, FileAccess.Read)) - { - byte[] bytes = System.IO.File.ReadAllBytes(exportFile); - fs.Read(bytes, 0, System.Convert.ToInt32(fs.Length)); - fs.Close(); - - var fname = Path.GetFileName(exportFile); - - Response.Headers["Content-Disposition"] = $"inline; filename={fname}"; - - var ret = new FileContentResult(bytes, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") - { - FileDownloadName = fname - }; - - return ret; - } - } - } - catch (Exception ex) - { - return Error(ex, "ไม่สามารถส่งออกรายชื่อผู้สอบผ่านได้!!"); - } - finally - { - if (System.IO.File.Exists(exportFile)) - System.IO.File.Delete(exportFile); - } - } - - #endregion - - #region " Image and Document " - - /// - /// Upload Image หรือ เอกสารในรอบการสอบ - /// - /// ประเภทเอกสาร - /// รหัสรอบสมัคร - /// - /// เมื่อทำการอ่านข้อมูลรอบการสมัครสอบ และ คนสมัครสอบในรอบสำเร็จ - /// ไม่ได้ Login เข้าระบบ - /// เมื่อเกิดข้อผิดพลาดในการทำงาน - [HttpPut("{type}/{importId:length(36)}"), DisableRequestSizeLimit] - [ProducesResponseType(StatusCodes.Status200OK)] - [ProducesResponseType(StatusCodes.Status401Unauthorized)] - [ProducesResponseType(StatusCodes.Status500InternalServerError)] - public async Task> UpdateDocAsync(string type, Guid importId) - { - try - { - if (Request.Form.Files == null || Request.Form.Files.Count == 0) - { - return Error(GlobalMessages.NoFileToUpload); - } - - var files = Request.Form.Files; - if (type == "img") - { - await _recruitService.UpdateImageAsync(importId, files); - } - else - { - await _recruitService.UpdateDocAsync(importId, files); - } - - return Success(); - } - catch (Exception ex) - { - return Error(ex); - } - } - - /// - /// ลบ Image หรือ เอกสารในรอบการสอบ - /// - /// ประเภทเอกสาร - /// รหัสไฟล์ - /// - /// เมื่อทำรายการสำเร็จ - /// ไม่ได้ Login เข้าระบบ - /// เมื่อเกิดข้อผิดพลาดในการทำงาน - [HttpDelete("{type}/{docId:length(36)}")] - public async Task> DeleteDocAsync(string type, Guid docId) - { - try - { - if (type == "img") - { - await _recruitService.DeleteImageAsync(docId); - } - else - { - await _recruitService.DeleteDocAsync(docId); - } - - return Success(); - } - catch (Exception ex) - { - return Error(ex, "ไม่สามารถลบไฟล์ได้"); - } - } - - #endregion - - #endregion - } + [Route("api/v{version:apiVersion}/recruit")] + [ApiVersion("1.0")] + [ApiController] + [Produces("application/json")] + [Authorize] + [SwaggerTag("จัดการข้อมูลการสอบแข่งขัน")] + public class RecruitController : BaseController + { + #region " Fields " + + private readonly ApplicationDbContext _context; + private readonly MetadataDbContext _contextMetadata; + private readonly MinIOService _minioService; + private readonly IWebHostEnvironment _webHostEnvironment; + private readonly RecruitService _recruitService; + + private readonly IHttpContextAccessor _httpContextAccessor; + private readonly ILogger _logger; + + #endregion + + #region " Constructor and Destructor " + + public RecruitController(ApplicationDbContext context, + MetadataDbContext contextMetadata, + MinIOService minioService, + IWebHostEnvironment webHostEnvironment, + RecruitService recruitService, + IHttpContextAccessor httpContextAccessor, + ILogger logger) + { + _context = context; + _contextMetadata = contextMetadata; + _minioService = minioService; + _webHostEnvironment = webHostEnvironment; + _recruitService = recruitService; + _httpContextAccessor = httpContextAccessor; + _logger = logger; + } + + #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 " + + #region " Private " + + private int GetColumnIndex(string[] columns, string name, bool partial = false) + { + try + { + if (partial) + return Array.FindIndex(columns, x => x.Contains(name)) + 1; + else + return Array.FindIndex(columns, x => x == name) + 1; + } + catch + { + return 0; + } + + } + + private string CalculateDiff(DateTime d1, DateTime d2) + { + if (d1 > d2) return "ข้อมูลไม่ถูกต้อง"; + + TimeSpan sp = d2.Subtract(d1); + int yy = sp.Days / 365; + int mm = (sp.Days - (yy * 365)) / 30; + int dd = (sp.Days - (yy * 365) - (mm * 30)); + + var sb = new StringBuilder(); + sb.Clear(); + sb.Append(yy == 0 ? "" : $"{yy} ปี "); + sb.Append(mm == 0 ? "" : $"{mm} เดือน "); + //sb.Append(dd == 0 ? "" : $"{dd} วัน "); + + return sb.ToString(); + } + + private async Task GetExamCount(Guid exam) + { + try + { + return await _context.RecruitPayments.AsQueryable() + .Include(x => x.Recruit) + .ThenInclude(x => x.RecruitImport) + .Where(x => x.Recruit.RecruitImport.Id == exam) + .CountAsync(); + } + catch + { + throw; + } + } + + private async Task GetPassExamCount(Guid exam) + { + try + { + return await _context.RecruitScores.AsQueryable() + .Include(x => x.ScoreImport) + .Where(x => x.ScoreImport.Id == exam) + .Where(x => x.ExamStatus == "ผ่าน") + .CountAsync(); + } + catch + { + throw; + } + } + + private async Task GetScoreCount(Guid exam) + { + try + { + return await _context.RecruitScores.AsQueryable() + .Include(x => x.ScoreImport) + .Where(x => x.ScoreImport.Id == exam) + .CountAsync(); + } + catch + { + throw; + } + } + private List GetAllIdByRoot(Guid id) + { + try + { + var ret = new List(); + + var oc = _contextMetadata.Organizations.FirstOrDefault(x => x.Id == id && x.IsActive); + if (oc != null) + ret.Add(oc.Id); + + var child = _contextMetadata.Organizations.AsQueryable().Where(x => x.ParentId == id && x.IsActive).ToList(); + if (child.Any()) + { + foreach (var item in child) + { + ret.AddRange(GetAllIdByRoot(item.Id)); + } + } + + return ret; + } + catch + { + throw; + } + } + + #endregion + + #region " Ex. Upload, Download and Delete file " + + /// + /// ตัวอย่างในการเขียน api เพื่อทำการ upload file + /// + /// + /// เมื่อทำการ upload สำเร็จ + /// ค่าตัวแปรที่ส่งมาไม่ถูกต้อง + /// ไม่ได้ Login เข้าระบบ + /// เมื่อเกิดข้อผิดพลาดในการทำงาน + [HttpPost("upload"), DisableRequestSizeLimit] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + [AllowAnonymous] + public async Task> UploadFile() + { + try + { + if (Request.Form.Files == null || Request.Form.Files.Count == 0) + { + return Error(GlobalMessages.NoFileToUpload); + } + + var file = Request.Form.Files[0]; + var doc = await _minioService.UploadFileAsync(file); + + return Success(doc); + } + catch (Exception ex) + { + return Error(ex); + } + } + + /// + /// ตัวอย่างในการเขียน api เพื่อทำการ delete file + /// + /// รหัสไฟล์ในฐานข้อมูล + /// + /// เมื่อทำการ delete file สำเร็จ + /// ค่าตัวแปรที่ส่งมาไม่ถูกต้อง + /// ไม่ได้ Login เข้าระบบ + /// เมื่อเกิดข้อผิดพลาดในการทำงาน + [HttpGet("delete/{id:length(36)}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + [AllowAnonymous] + public async Task> DeleteFile(Guid id) + { + try + { + await _minioService.DeleteFileAsync(id); + + return Success(); + } + catch (Exception ex) + { + return Error(ex); + } + } + + /// + /// ตัวอย่างในการเขียน api เพื่อทำการ download file + /// + /// รหัสไฟล์ในฐานข้อมูล + /// + /// เมื่อทำการ download file สำเร็จ + /// ค่าตัวแปรที่ส่งมาไม่ถูกต้อง + /// ไม่ได้ Login เข้าระบบ + /// เมื่อเกิดข้อผิดพลาดในการทำงาน + [HttpGet("download/{id:length(36)}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + [AllowAnonymous] + public async Task> DownloadFile(Guid id) + { + try + { + var file_data = await _minioService.DownloadFileAsync(id); + + Response.Headers["Content-Disposition"] = $"inline; filename={file_data.FileName}"; + + var ret = new FileContentResult(file_data.FileContent, file_data.FileType) + { + FileDownloadName = file_data.FileName + }; + + return ret; + } + catch (Exception ex) + { + return Error(ex); + } + } + + + #endregion + + #region " จัดการรอบการสมัครสอบแข่งขัน " + + /// + /// แสดงข้อมูลรอบการสอบแข่งขัน + /// + /// + /// เมื่อทำการอ่านข้อมูลจาก Relational Database สำเร็จ + /// ค่าตัวแปรที่ส่งมาไม่ถูกต้อง + /// ไม่ได้ Login เข้าระบบ + /// เมื่อเกิดข้อผิดพลาดในการทำงาน + [HttpGet("period")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task> GetPeriodsAsync() + { + try + { + var data = await _context.RecruitImports.AsQueryable() + .Include(x => x.ImportFile) + .Include(x => x.Recruits) + .Include(x => x.ScoreImport) + .ThenInclude(x => x.ImportFile) + .Include(x => x.ScoreImport) + .ThenInclude(x => x.Scores) + .OrderByDescending(x => x.Year) + .ThenByDescending(x => x.Order) + .Select(x => new + { + x.Id, + x.Year, + x.Name, + x.Order, + ImportDate = x.CreatedAt.Date.ToThaiShortDate(), + ExamCount = x.Recruits.Count(), + Score = x.ScoreImport == null ? null : + new + { + ID = x.ScoreImport.Id, + ImportYear = x.ScoreImport.Year, + ImportDate = x.CreatedAt.Date.ToThaiShortDate(), + ScoreCount = x.ScoreImport.Scores.Count(), + + } + }) + .ToListAsync(); + + return Success(data); + } + catch (Exception ex) + { + return Error(ex); + } + } + + /// + /// แสดงข้อมูลรอบการสอบแข่งขันเป็นรายการ + /// + /// รหัสรอบการสอบแข่งขัน + /// + /// เมื่อทำการอ่านข้อมูลจาก Relational Database สำเร็จ + /// ค่าตัวแปรที่ส่งมาไม่ถูกต้อง + /// ไม่ได้ Login เข้าระบบ + /// เมื่อเกิดข้อผิดพลาดในการทำงาน + [HttpGet("period/{id:length(36)}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task> GetPeriodByIdAsync(Guid id) + { + try + { + var data = await _context.RecruitImports.AsQueryable() + .Include(x => x.RecruitImages) + .ThenInclude(x => x.Document) + .Include(x => x.RecruitDocuments) + .ThenInclude(x => x.Document) + .Include(x => x.ImportFile) + .Include(x => x.Recruits) + .ThenInclude(x => x.Addresses) + .Include(x => x.Recruits) + .ThenInclude(x => x.Occupations) + .Include(x => x.Recruits) + .ThenInclude(x => x.Certificates) + .Include(x => x.Recruits) + .ThenInclude(x => x.Educations) + .Include(x => x.Recruits) + .ThenInclude(x => x.Payments) + .Include(x => x.Recruits) + .ThenInclude(x => x.Documents) + .ThenInclude(x => x.DocumentFile) + .FirstOrDefaultAsync(x => x.Id == id); + + var new_image = new List(); + foreach (var p in data.RecruitImages) + { + new_image.Add(new + { + p.Id, + p.Document.FileName, + p.Document.FileSize, + p.Document.FileType, + detail = _minioService.GetFilePath(p.Document.Id).Result, + }); + } + + // re create doc list + var new_doc = new List(); + foreach (var p in data.RecruitDocuments) + { + new_doc.Add(new + { + p.Id, + p.Document.FileName, + p.Document.FileSize, + p.Document.FileType, + detail = _minioService.GetFilePath(p.Document.Id).Result, + }); + } + + return Success(new { periods = data, images = new_image, files = new_doc }); + } + catch (Exception ex) + { + return Error(ex); + } + } + + + /// + /// เพิ่มข้อมูลรอบการจัดสอบแข่งขัน + /// + /// Request parameters + /// + /// เมื่อทำการเพิ่มข้อมูลสำเร็จ + /// ค่าตัวแปรที่ส่งมาไม่ถูกต้อง + /// ไม่ได้ Login เข้าระบบ + /// เมื่อเกิดข้อผิดพลาดในการทำงาน + [HttpPost("period")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task> PostPeriodAsync([FromBody] PostRecruitImportRequest req) + { + try + { + if (req == null) + return Error(GlobalMessages.InvalidRequestParam, (int)HttpStatusCode.BadRequest); + + var import = new RecruitImport + { + Year = req.Year, + Name = req.Name, + Order = req.Order, + Detail = req.Detail, + Fee = req.Fee, + AnnouncementStartDate = req.AnnouncementStartDate, + AnnouncementEndDate = req.AnnouncementEndDate, + RegisterStartDate = req.RegisterStartDate, + RegisterEndDate = req.RegisterEndDate, + ExamDate = req.ExamDate, + PaymentStartDate = req.PaymentStartDate, + PaymentEndDate = req.PaymentEndDate, + Note = req.Note, + AnnouncementDate = req.AnnouncementDate, + }; + await _context.RecruitImports.AddAsync(import); + + await _context.SaveChangesAsync(); + + return Success(import); + } + catch (Exception ex) + { + return Error(ex); + } + } + + /// + /// แก้ไขข้อมูลรอบการจัดสอบแข่งขัน + /// + /// รหัสรอบการสอบแข่งขัน + /// Request parameters + /// + /// เมื่อทำการเพิ่มข้อมูลสำเร็จ + /// ค่าตัวแปรที่ส่งมาไม่ถูกต้อง + /// ไม่ได้ Login เข้าระบบ + /// เมื่อเกิดข้อผิดพลาดในการทำงาน + [HttpPut("period/{id:length(36)}"), DisableRequestSizeLimit] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task> PutPeriodAsync(Guid id, [FromBody] PostRecruitImportRequest req) + { + try + { + var data = await _context.RecruitImports.AsQueryable().FirstOrDefaultAsync(x => x.Id == id); + + if (data == null) + return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); + + data.Name = req.Name; + data.Year = req.Year; + data.Order = req.Order; + data.Detail = req.Detail; + data.Fee = req.Fee; + data.AnnouncementEndDate = req.AnnouncementEndDate; + data.AnnouncementStartDate = req.AnnouncementStartDate; + data.RegisterStartDate = req.RegisterStartDate; + data.RegisterEndDate = req.RegisterEndDate; + data.PaymentEndDate = req.PaymentEndDate; + data.PaymentStartDate = req.PaymentStartDate; + data.ExamDate = req.ExamDate; + data.Note = req.Note; + data.AnnouncementDate = req.AnnouncementDate; + + await _context.SaveChangesAsync(); + + return Success(data); + + } + catch (Exception ex) + { + return Error(ex); + } + } + + + /// + /// ลบข้อมูลรอบการจัดสอบแข่งขัน + /// + /// รหัสรอบการสอบแข่งขัน + /// + /// เมื่อทำการลบข้อมูลสำเร็จ + /// ค่าตัวแปรที่ส่งมาไม่ถูกต้อง + /// ไม่ได้ Login เข้าระบบ + /// เมื่อเกิดข้อผิดพลาดในการทำงาน + [HttpDelete("period/{id:length(36)}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task> DeletePeriodAsync(Guid id) + { + try + { + var data = await _context.RecruitImports.AsQueryable() + .Include(x => x.ImportFile) + .Include(x => x.Recruits) + .ThenInclude(x => x.Addresses) + .Include(x => x.Recruits) + .ThenInclude(x => x.Occupations) + .Include(x => x.Recruits) + .ThenInclude(x => x.Certificates) + .Include(x => x.Recruits) + .ThenInclude(x => x.Educations) + .Include(x => x.Recruits) + .ThenInclude(x => x.Payments) + .Include(x => x.Recruits) + .ThenInclude(x => x.Documents) + .ThenInclude(x => x.DocumentFile) + .Include(x => x.ScoreImport) + .ThenInclude(x => x.ImportFile) + .Include(x => x.ScoreImport) + .ThenInclude(x => x.Scores) + .FirstOrDefaultAsync(x => x.Id == id); + + _context.RecruitImports.Remove(data); + await _context.SaveChangesAsync(); + + return Success(); + } + catch (Exception ex) + { + return Error(ex); + } + } + + #endregion + + #region " Candidate Files " + + /// + /// แสดงข้อมูลสำหรับหน้าจอ รายการนำเข้าข้อมูลผู้สมัครสอบแข่งขัน + /// + /// + /// เมื่อแสดงรายการข้อมูลสำเร็จ + /// ค่าตัวแปรที่ส่งมาไม่ถูกต้อง + /// ไม่ได้ Login เข้าระบบ + /// เมื่อเกิดข้อผิดพลาดในการทำงาน + [HttpGet("candidate")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task> GetCandidateFilesAsync() + { + try + { + var data = await _context.RecruitImports.AsQueryable() + .Include(x => x.ImportFile) + .Include(x => x.Recruits) + .Include(x => x.ScoreImport) + .ThenInclude(x => x.ImportFile) + .Include(x => x.ScoreImport) + .ThenInclude(x => x.Scores) + .OrderByDescending(x => x.Year) + .ThenByDescending(x => x.Order) + .Select(x => new + { + x.Id, + x.Year, + x.Name, + x.Order, + ImportDate = x.CreatedAt.Date.ToThaiShortDate(), + ExamCount = x.Recruits.Count(), + Score = x.ScoreImport == null ? null : + new + { + ID = x.ScoreImport.Id, + ImportYear = x.ScoreImport.Year, + ImportDate = x.CreatedAt.Date.ToThaiShortDate(), + ScoreCount = x.ScoreImport.Scores.Count(), + + }, + x.CreatedUserId, + }) + .ToListAsync(); + var profileOrganizations = await _contextMetadata.ProfileOrganizations.AsQueryable() + .ToListAsync(); + var _periodExams = (from x in data + join po in profileOrganizations on Guid.Parse(x.CreatedUserId) equals po?.UserId into poGroup + from po in poGroup.DefaultIfEmpty() + select new + { + x.Id, + x.Year, + x.Name, + x.Order, + x.ImportDate, + x.ExamCount, + x.Score, + x.CreatedUserId, + OcId = po == null ? null : po.OrganizationId, + }).AsQueryable() + .ToList(); + + var roles = _httpContextAccessor?.HttpContext?.User?.FindAll(ClaimTypes.Role)?.Select(c => c.Value).ToList(); + if (!roles.Contains("head")) + { + var criteria = new List(); + var profileOrganization = await _contextMetadata.ProfileOrganizations.AsQueryable() + .FirstOrDefaultAsync(x => x.UserId == Guid.Parse(UserId)); + + if (profileOrganization == null) + return Success(new List()); + + var ocId = _contextMetadata.Organizations.AsQueryable() + .FirstOrDefault(x => x.Id == profileOrganization.OrganizationId); + if (ocId == null) + return Success(new List()); + criteria = GetAllIdByRoot(ocId.Id); + if (criteria.Any()) + _periodExams = _periodExams.Where(x => x.CreatedUserId == UserId || criteria.Contains(x.OcId == null ? Guid.Parse("00000000-0000-0000-0000-000000000000") : x.OcId)).ToList(); + } + + return Success(_periodExams); + } + catch (Exception ex) + { + return Error(ex); + } + } + + + /// + /// นำเข้ารายชื่อผู้สมัครสอบแข่งขัน + /// + /// + /// เมื่อทำนำเข้าข้อมูลสำเร็จ + /// ค่าตัวแปรที่ส่งมาไม่ถูกต้อง + /// ไม่ได้ Login เข้าระบบ + /// เมื่อเกิดข้อผิดพลาดในการทำงาน + [HttpPost("candidate"), DisableRequestSizeLimit] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task> ImportCandidateFileAsync([FromForm] PostRecruitImportRequest req) + { + var tmpDir = Path.Combine(_webHostEnvironment.ContentRootPath, "tmp"); + if (!Directory.Exists(tmpDir)) + Directory.CreateDirectory(tmpDir); + + var importFile = Path.Combine(tmpDir, $"c_{DateTime.Now.ToString("ddMMyyyyHHmmss")}.xlsx"); + var import_doc_id = ""; + + try + { + if (Request.Form.Files == null || Request.Form.Files.Count == 0) + { + return Error(GlobalMessages.NoFileToUpload); + } + + var file = Request.Form.Files[0]; + var doc = await _minioService.UploadFileAsync(file); + import_doc_id = doc.Id.ToString("D"); + + var fileContent = (await _minioService.DownloadFileAsync(doc.Id)).FileContent; + + // สร้างรอบการบรรจุ โดยเอาเข้ามูลมาใส่จาก Request + var imported = new RecruitImport + { + Year = req.Year, + Order = req.Order, + Name = req.Name, + ImportFile = doc, + CreatedAt = DateTime.Now, + CreatedUserId = UserId ?? "", + CreatedFullName = FullName ?? "System Administrator", + ImportHostories = new List + { + new RecruitImportHistory + { + Description = "นำเข้าข้อมูลผู้สมัครสอบแข่งขัน", + CreatedAt = DateTime.Now, + CreatedUserId = UserId ?? "", + CreatedFullName = FullName ?? "System Administrator", + } + } + }; + + await _context.RecruitImports.AddAsync(imported); + + // import datafile + System.IO.File.WriteAllBytes(importFile, fileContent); + + using (var c_package = new ExcelPackage(new FileInfo(importFile))) + { + // loop from sheet2 to end + + for (int i = 1; i < c_package.Workbook.Worksheets.Count; i++) + { + var workSheet = c_package.Workbook.Worksheets[i]; + var totalRows = workSheet.Dimension.Rows; + var cols = workSheet.GetHeaderColumns(); + + int row = 2; + + while (row <= totalRows) + { + var cell1 = workSheet?.Cells[row, 1]?.GetValue(); + if (cell1 == "" || cell1 == null) break; + + var r = new Models.Recruits.Recruit(); + r.ExamId = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.ExamID)]?.GetValue(); + r.CitizenId = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.PersonalID)]?.GetValue(); + r.Prefix = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Prefix)]?.GetValue(); + r.FirstName = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.FirstName)]?.GetValue(); + r.LastName = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.LastName)]?.GetValue(); + r.Gendor = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Gender)]?.GetValue(); + r.National = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.National)]?.GetValue().IsNull(""); + r.Race = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Race)]?.GetValue().IsNull(""); + r.Religion = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Religion)]?.GetValue().IsNull(""); + r.DateOfBirth = Convert.ToDateTime(workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.DateOfBirth)]?.GetValue().ToDateTime(DateTimeFormat.Ymd, "-")); + r.Marry = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Marry)]?.GetValue(); + r.Isspecial = "N"; + r.CitizenCardIssuer = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.PersonalCardIssue)]?.GetValue(); + r.CitizenCardExpireDate = Convert.ToDateTime(workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.PersonalCardExpireDate)]?.GetValue().ToDateTime(DateTimeFormat.Ymd, "-")); + r.ApplyDate = (DateTime)workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.ApplyDate)]?.GetValue(); + r.PositionName = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.PositionName)]?.GetValue().IsNull(""); + + + // address + r.Addresses.Add(new RecruitAddress() + { + Address = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Address)]?.GetValue() ?? "", + Moo = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Moo)]?.GetValue() ?? "", + Soi = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Soi)]?.GetValue() ?? "", + Road = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Road)]?.GetValue() ?? "", + District = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.District)]?.GetValue() ?? "", + Amphur = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Amphur)]?.GetValue() ?? "", + Province = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Province)]?.GetValue() ?? "", + ZipCode = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.ZipCode)]?.GetValue() ?? "", + Telephone = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Telephone)]?.GetValue() ?? "", + Mobile = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Mobile)]?.GetValue() ?? "", + Address1 = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Address1)]?.GetValue() ?? "", + Moo1 = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Moo1)]?.GetValue() ?? "", + Soi1 = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Soi1)]?.GetValue() ?? "", + Road1 = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Road1)]?.GetValue() ?? "", + District1 = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.District1)]?.GetValue() ?? "", + Amphur1 = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Amphur1)]?.GetValue() ?? "", + Province1 = "", + ZipCode1 = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.ZipCode1)]?.GetValue() ?? "", + }); + + // payment + r.Payments.Add(new RecruitPayment() + { + PaymentId = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.PaymentID)]?.GetValue() ?? "", + CompanyCode = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.CompanyCode)]?.GetValue() ?? "", + TextFile = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.TextFile)]?.GetValue() ?? "", + BankCode = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.BankCode)]?.GetValue() ?? "", + AccountNumber = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.AccouontNumer)]?.GetValue() ?? "", + TransDate = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.TransDate)]?.GetValue() ?? "", + TransTime = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.TransTime)]?.GetValue() ?? "", + CustomerName = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.CustomerName)]?.GetValue() ?? "", + RefNo1 = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.RefNo1)]?.GetValue() ?? "", + TermBranch = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.TermBranch)]?.GetValue() ?? "", + TellerId = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.TellerID)]?.GetValue() ?? "", + CreditDebit = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.CreditDebit)]?.GetValue() ?? "", + PaymentType = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Type)]?.GetValue(), + ChequeNo = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.ChequeNo)]?.GetValue() ?? "", + Amount = (decimal)workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Amount)]?.GetValue(), + ChqueBankCode = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.ChqBankCode)]?.GetValue() ?? "" + }); + + // occupation + r.Occupations.Add(new RecruitOccupation() + { + Occupation = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Occupation)]?.GetValue() ?? "", + Position = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Position)]?.GetValue() ?? "", + Workplace = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Workplace)]?.GetValue() ?? "", + Telephone = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.WorkplaceTelephone)]?.GetValue() ?? "", + WorkAge = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.WorkAge)]?.GetValue() ?? "", + }); + + // certificate + r.Certificates.Add(new RecruitCertificate() + { + CertificateNo = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.CertificateNo)]?.GetValue() ?? "", + Description = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.CertificateDesc)]?.GetValue() ?? "", + IssueDate = Convert.ToDateTime(workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.CertificateIssueDate)]?.GetValue().ToDateTime(DateTimeFormat.Ymd, "-")), + ExpiredDate = Convert.ToDateTime(workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.CertificateExpireDate)]?.GetValue().ToDateTime(DateTimeFormat.Ymd, "-")) + }); + + r.Educations.Add(new RecruitEducation() + { + Degree = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Degree)]?.GetValue() ?? "", + Major = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Major)]?.GetValue() ?? "", + MajorGroupId = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.MajorGroupID)]?.GetValue() ?? "", + MajorGroupName = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.MajorGroupName)]?.GetValue() ?? "", + University = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.University)]?.GetValue() ?? "", + GPA = (double)workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.GPA)]?.GetValue(), + Specialist = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.SpecialList)]?.GetValue() ?? "", + HighDegree = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.HighDegree)]?.GetValue() ?? "", + BachelorDate = Convert.ToDateTime(workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.BachelorDate)]?.GetValue().ToDateTime(DateTimeFormat.Ymd, "-")) + }); + + r.RecruitImport = imported; + _context.Recruits.Add(r); + + //imported.Recruits.Add(r); + row++; + + } + } + } + + // finally save to database + + _context.SaveChanges(); + + return Success(); + + } + catch (Exception ex) + { + await _minioService.DeleteFileAsync(Guid.Parse(import_doc_id)); + return Error(ex); + } + finally + { + if (System.IO.File.Exists(importFile)) + System.IO.File.Delete(importFile); + } + } + + /// + /// ลบข้อมูลนำข้อมูลผู้สมัครสอบแข่งขัน + /// + /// รหัสรอบการสอบแข่งขัน + /// + /// เมื่อทำนำเข้าข้อมูลสำเร็จ + /// ค่าตัวแปรที่ส่งมาไม่ถูกต้อง + /// ไม่ได้ Login เข้าระบบ + /// เมื่อเกิดข้อผิดพลาดในการทำงาน + [HttpDelete("candidate/{id:length(36)}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task> DeleteCandidateFileAsync(Guid id) + { + try + { + var data = await _context.RecruitImports.AsQueryable() + .Include(x => x.ImportHostories) + .Include(x => x.ImportFile) + .Include(x => x.Recruits) + .ThenInclude(x => x.Addresses) + .Include(x => x.Recruits) + .ThenInclude(x => x.Occupations) + .Include(x => x.Recruits) + .ThenInclude(x => x.Certificates) + .Include(x => x.Recruits) + .ThenInclude(x => x.Educations) + .Include(x => x.Recruits) + .ThenInclude(x => x.Payments) + .Include(x => x.Recruits) + .ThenInclude(x => x.Documents) + .ThenInclude(x => x.DocumentFile) + .Include(x => x.ScoreImport) + .ThenInclude(x => x.ImportFile) + .Include(x => x.ScoreImport) + .ThenInclude(x => x.Scores) + .FirstOrDefaultAsync(x => x.Id == id); + + if (data == null) + return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); + + var rec_import_id = data.ImportFile.Id.ToString("D"); + var score_import_id = data.ScoreImport != null ? data.ScoreImport.ImportFile.Id.ToString("D") : "-"; + + _context.RecruitImports.Remove(data); + await _context.SaveChangesAsync(); + + // delete upload candidate file + await _minioService.DeleteFileAsync(Guid.Parse(rec_import_id)); + + // delete score file + if (score_import_id != "-") + await _minioService.DeleteFileAsync(Guid.Parse(score_import_id)); + + return Success(); + } + catch (Exception ex) + { + return Error(ex); + } + } + + /// + /// แสดงประวัติการนำเข้าข้อมูลการสอบแข่งขัน + /// + /// รหัสรอบการสอบแข่งขัน + /// + /// เมื่อทำนำเข้าข้อมูลสำเร็จ + /// ค่าตัวแปรที่ส่งมาไม่ถูกต้อง + /// ไม่ได้ Login เข้าระบบ + /// เมื่อเกิดข้อผิดพลาดในการทำงาน + [HttpGet("history/{id:length(36)}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task> GetImportHistoryAsync(Guid id) + { + try + { + var data = await _context.RecruitImportHistories.AsQueryable() + .Include(x => x.RecruitImport) + .Where(x => x.RecruitImport.Id == id) + .OrderByDescending(x => x.CreatedAt) + .ToListAsync(); + + return Success(data); + } + catch (Exception ex) + { + return Error(ex); + } + } + + + /// + /// นำเข้ารายชื่อผู้สมัครสอบแข่งขัน + /// + /// รหัสรอบการสอบแข่งขัน + /// + /// เมื่อทำนำเข้าข้อมูลสำเร็จ + /// ค่าตัวแปรที่ส่งมาไม่ถูกต้อง + /// ไม่ได้ Login เข้าระบบ + /// เมื่อเกิดข้อผิดพลาดในการทำงาน + [HttpPost("candidate/{id:length(36)}"), DisableRequestSizeLimit] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task> ImportCandidateFileByIdAsync(Guid id) + { + var tmpDir = Path.Combine(_webHostEnvironment.ContentRootPath, "tmp"); + if (!Directory.Exists(tmpDir)) + Directory.CreateDirectory(tmpDir); + + var importFile = Path.Combine(tmpDir, $"c_{DateTime.Now.ToString("ddMMyyyyHHmmss")}.xlsx"); + var import_doc_id = ""; + + try + { + if (Request.Form.Files == null || Request.Form.Files.Count == 0) + { + return Error(GlobalMessages.NoFileToUpload); + } + + var imported = await _context.RecruitImports.AsQueryable() + .Include(x => x.ImportHostories) + .Include(x => x.ImportFile) + .Include(x => x.Recruits) + .ThenInclude(x => x.Addresses) + .Include(x => x.Recruits) + .ThenInclude(x => x.Occupations) + .Include(x => x.Recruits) + .ThenInclude(x => x.Certificates) + .Include(x => x.Recruits) + .ThenInclude(x => x.Educations) + .Include(x => x.Recruits) + .ThenInclude(x => x.Payments) + .Include(x => x.Recruits) + .FirstOrDefaultAsync(x => x.Id == id); + + if (imported == null) + return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); + + if (imported.Recruits != null) + { + // remove old score data + _context.Recruits.RemoveRange(imported.Recruits); + await _context.SaveChangesAsync(); + } + + var file = Request.Form.Files[0]; + var doc = await _minioService.UploadFileAsync(file); + import_doc_id = doc.Id.ToString("D"); + + var fileContent = (await _minioService.DownloadFileAsync(doc.Id)).FileContent; + + // สร้างรอบการบรรจุ โดยเอาเข้ามูลมาใส่จาก Request + imported.ImportHostories.Add(new RecruitImportHistory + { + Description = "นำเข้าข้อมูลผู้สมัครสอบแข่งขัน", + CreatedAt = DateTime.Now, + CreatedUserId = UserId ?? "", + CreatedFullName = FullName ?? "System Administrator", + }); + + //await _context.RecruitImports.AddAsync(imported); + + // import datafile + System.IO.File.WriteAllBytes(importFile, fileContent); + + using (var c_package = new ExcelPackage(new FileInfo(importFile))) + { + // loop from sheet2 to end + + for (int i = 1; i < c_package.Workbook.Worksheets.Count; i++) + { + var workSheet = c_package.Workbook.Worksheets[i]; + var totalRows = workSheet.Dimension.Rows; + var cols = workSheet.GetHeaderColumns(); + + int row = 2; + + while (row <= totalRows) + { + var cell1 = workSheet?.Cells[row, 1]?.GetValue(); + if (cell1 == "" || cell1 == null) break; + + var r = new Models.Recruits.Recruit(); + r.ExamId = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.ExamID)]?.GetValue(); + r.CitizenId = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.PersonalID)]?.GetValue(); + r.Prefix = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Prefix)]?.GetValue(); + r.FirstName = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.FirstName)]?.GetValue(); + r.LastName = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.LastName)]?.GetValue(); + r.Gendor = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Gender)]?.GetValue(); + r.National = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.National)]?.GetValue().IsNull(""); + r.Race = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Race)]?.GetValue().IsNull(""); + r.Religion = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Religion)]?.GetValue().IsNull(""); + r.DateOfBirth = Convert.ToDateTime(workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.DateOfBirth)]?.GetValue().ToDateTime(DateTimeFormat.Ymd, "-")); + r.Marry = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Marry)]?.GetValue(); + r.Isspecial = "N"; + r.CitizenCardIssuer = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.PersonalCardIssue)]?.GetValue(); + r.CitizenCardExpireDate = Convert.ToDateTime(workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.PersonalCardExpireDate)]?.GetValue().ToDateTime(DateTimeFormat.Ymd, "-")); + r.ApplyDate = (DateTime)workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.ApplyDate)]?.GetValue(); + r.PositionName = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.PositionName)]?.GetValue().IsNull(""); + + // address + r.Addresses.Add(new RecruitAddress() + { + Address = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Address)]?.GetValue() ?? "", + Moo = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Moo)]?.GetValue() ?? "", + Soi = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Soi)]?.GetValue() ?? "", + Road = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Road)]?.GetValue() ?? "", + District = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.District)]?.GetValue() ?? "", + Amphur = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Amphur)]?.GetValue() ?? "", + Province = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Province)]?.GetValue() ?? "", + ZipCode = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.ZipCode)]?.GetValue() ?? "", + Telephone = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Telephone)]?.GetValue() ?? "", + Mobile = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Mobile)]?.GetValue() ?? "", + Address1 = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Address1)]?.GetValue() ?? "", + Moo1 = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Moo1)]?.GetValue() ?? "", + Soi1 = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Soi1)]?.GetValue() ?? "", + Road1 = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Road1)]?.GetValue() ?? "", + District1 = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.District1)]?.GetValue() ?? "", + Amphur1 = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Amphur1)]?.GetValue() ?? "", + Province1 = "", + ZipCode1 = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.ZipCode1)]?.GetValue() ?? "", + }); + + // payment + r.Payments.Add(new RecruitPayment() + { + PaymentId = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.PaymentID)]?.GetValue() ?? "", + CompanyCode = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.CompanyCode)]?.GetValue() ?? "", + TextFile = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.TextFile)]?.GetValue() ?? "", + BankCode = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.BankCode)]?.GetValue() ?? "", + AccountNumber = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.AccouontNumer)]?.GetValue() ?? "", + TransDate = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.TransDate)]?.GetValue() ?? "", + TransTime = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.TransTime)]?.GetValue() ?? "", + CustomerName = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.CustomerName)]?.GetValue() ?? "", + RefNo1 = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.RefNo1)]?.GetValue() ?? "", + TermBranch = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.TermBranch)]?.GetValue() ?? "", + TellerId = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.TellerID)]?.GetValue() ?? "", + CreditDebit = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.CreditDebit)]?.GetValue() ?? "", + PaymentType = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Type)]?.GetValue(), + ChequeNo = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.ChequeNo)]?.GetValue() ?? "", + Amount = (decimal)workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Amount)]?.GetValue(), + ChqueBankCode = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.ChqBankCode)]?.GetValue() ?? "" + }); + + // occupation + r.Occupations.Add(new RecruitOccupation() + { + Occupation = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Occupation)]?.GetValue() ?? "", + Position = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Position)]?.GetValue() ?? "", + Workplace = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Workplace)]?.GetValue() ?? "", + Telephone = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.WorkplaceTelephone)]?.GetValue() ?? "", + WorkAge = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.WorkAge)]?.GetValue() ?? "", + }); + + // certificate + r.Certificates.Add(new RecruitCertificate() + { + CertificateNo = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.CertificateNo)]?.GetValue() ?? "", + Description = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.CertificateDesc)]?.GetValue() ?? "", + IssueDate = Convert.ToDateTime(workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.CertificateIssueDate)]?.GetValue().ToDateTime(DateTimeFormat.Ymd, "-")), + ExpiredDate = Convert.ToDateTime(workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.CertificateExpireDate)]?.GetValue().ToDateTime(DateTimeFormat.Ymd, "-")) + }); + + r.Educations.Add(new RecruitEducation() + { + Degree = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Degree)]?.GetValue() ?? "", + Major = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.Major)]?.GetValue() ?? "", + MajorGroupId = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.MajorGroupID)]?.GetValue() ?? "", + MajorGroupName = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.MajorGroupName)]?.GetValue() ?? "", + University = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.University)]?.GetValue() ?? "", + GPA = (double)workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.GPA)]?.GetValue(), + Specialist = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.SpecialList)]?.GetValue() ?? "", + HighDegree = workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.HighDegree)]?.GetValue() ?? "", + BachelorDate = Convert.ToDateTime(workSheet?.Cells[row, GetColumnIndex(cols, CandidateFileHeader.BachelorDate)]?.GetValue().ToDateTime(DateTimeFormat.Ymd, "-")) + }); + + r.RecruitImport = imported; + _context.Recruits.Add(r); + + //imported.Recruits.Add(r); + row++; + + } + } + } + + // finally save to database + + _context.SaveChanges(); + + return Success(); + + } + catch (Exception ex) + { + await _minioService.DeleteFileAsync(Guid.Parse(import_doc_id)); + return Error(ex); + } + finally + { + if (System.IO.File.Exists(importFile)) + System.IO.File.Delete(importFile); + } + } + + #endregion + + #region " Score File " + + [HttpPost("score/{id:length(36)}"), DisableRequestSizeLimit] + public async Task> ImportScoreFileAsync(Guid id) + { + var tmpDir = Path.Combine(_webHostEnvironment.ContentRootPath, "tmp"); + if (!Directory.Exists(tmpDir)) + Directory.CreateDirectory(tmpDir); + + var importFile = Path.Combine(tmpDir, $"s_{DateTime.Now.ToString("ddMMyyyyHHmmss")}.xlsx"); + var import_doc_id = ""; + + try + { + if (Request.Form.Files == null || Request.Form.Files.Count == 0) + { + return Error(GlobalMessages.NoFileToUpload); + } + + var rec_import = await _context.RecruitImports.AsQueryable() + .Include(x => x.ScoreImport) + .ThenInclude(x => x.Scores) + .Include(x => x.ImportHostories) + .FirstOrDefaultAsync(x => x.Id == id); + + if (rec_import == null) + return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); + + if (rec_import.ScoreImport != null) + { + // remove old score data + if (rec_import.ScoreImport.Scores != null) + { + _context.RecruitScores.RemoveRange(rec_import.ScoreImport.Scores); + await _context.SaveChangesAsync(); + } + } + + var file = Request.Form.Files[0]; + var doc = await _minioService.UploadFileAsync(file); + import_doc_id = doc.Id.ToString("D"); + var fileContent = (await _minioService.DownloadFileAsync(doc.Id)).FileContent; + + // create import history + rec_import.ImportHostories.Add(new RecruitImportHistory + { + Description = "นำเข้าข้อมูลผลคะแนนสอบ", + CreatedAt = DateTime.Now, + CreatedUserId = UserId ?? "", + CreatedFullName = FullName ?? "System Administrator", + }); + + // create new file import + var imported = new ScoreImport + { + Year = rec_import.Year, + ImportFile = doc, + Scores = new List() + }; + + // import datafile + System.IO.File.WriteAllBytes(importFile, fileContent); + + using (var c_package = new ExcelPackage(new FileInfo(importFile))) + { + // loop from sheet2 to end + for (int i = 1; i < c_package.Workbook.Worksheets.Count; i++) + { + var workSheet = c_package.Workbook.Worksheets[i]; + var totalRows = workSheet.Dimension.Rows; + var cols = workSheet.GetHeaderColumns(); + + int row = 8; + + while (row <= totalRows) + { + var cell1 = workSheet?.Cells[row, 1]?.GetValue(); + if (cell1 == "" || cell1 == null) break; + + var r = new RecruitScore(); + r.ExamId = workSheet?.Cells[row, 2]?.GetValue(); + + r.FullA = (int)workSheet?.Cells[7, 7]?.GetValue().Replace("(", "").Replace(")", "").Replace("คะแนน", "").Trim().ToInteger(); + r.SumA = workSheet?.Cells[row, 7]?.GetValue() == "ขส." ? 0 : (int)workSheet?.Cells[row, 7]?.GetValue().Replace(".00", "").ToInteger(); + r.PercentageA = workSheet?.Cells[row, 8]?.GetValue() == "ขส." ? 0.0 : (double)workSheet?.Cells[row, 8]?.GetValue(); + r.AStatus = workSheet?.Cells[row, 9]?.GetValue(); + + r.FullB = (int)workSheet?.Cells[7, 12]?.GetValue().Replace("(", "").Replace(")", "").Replace("คะแนน", "").Trim().ToInteger(); + r.SumB = workSheet?.Cells[row, 12]?.GetValue() == "ขส." ? 0 : (int)workSheet?.Cells[row, 12]?.GetValue().Replace(".00", "").ToInteger(); + r.PercentageB = workSheet?.Cells[row, 13]?.GetValue() == "ขส." ? 0.0 : (double)workSheet?.Cells[row, 13]?.GetValue(); + r.BStatus = workSheet?.Cells[row, 14]?.GetValue(); + + r.SumAB = workSheet?.Cells[row, 15]?.GetValue() == "ขส." ? 0 : (int)workSheet?.Cells[row, 15]?.GetValue().Replace(".00", "").ToInteger(); + r.ABStatus = workSheet?.Cells[row, 17]?.GetValue(); + + r.FullC = (int)workSheet?.Cells[7, 20]?.GetValue().Replace("(", "").Replace(")", "").Replace("คะแนน", "").Trim().ToInteger(); + r.SumC = workSheet?.Cells[row, 20]?.GetValue() == "ขส." ? 0 : (int)workSheet?.Cells[row, 20]?.GetValue().Replace(".00", "").ToInteger(); + r.PercentageC = workSheet?.Cells[row, 21]?.GetValue() == "ขส." ? 0.0 : (double)workSheet?.Cells[row, 21]?.GetValue(); + r.CStatus = workSheet?.Cells[row, 22]?.GetValue(); + + r.ExamStatus = workSheet?.Cells[row, 24]?.GetValue(); + r.Number = workSheet?.Cells[row, 25]?.GetValue() ?? ""; + r.Major = workSheet.Name; + + + imported.Scores.Add(r); + row++; + } + } + } + + // finally save to database + rec_import.ScoreImport = imported; + await _context.SaveChangesAsync(); + + return Success(); + + } + catch (Exception ex) + { + await _minioService.DeleteFileAsync(Guid.Parse(import_doc_id)); + return Error(ex); + } + finally + { + if (System.IO.File.Exists(importFile)) + System.IO.File.Delete(importFile); + } + } + + #endregion + + #region " Exam Information " + + /// + /// แสดงข้อมูลสำหรับหน้าจอ : รายการข้อมูลผู้สมัครสอบ + /// + [HttpGet("exam")] + public async Task> GetExamResultAsync() + { + try + { + var data = await _context.RecruitImports.AsQueryable() + .OrderByDescending(x => x.Year) + .ThenByDescending(x => x.Order) + .Select(x => new + { + x.Id, + ExamYear = x.Year.ToThaiYear(), + ExamOrder = x.Order, + Description = x.Name, + }) + .ToListAsync(); + + var result = new List(); + + foreach (var d in data) + { + result.Add(new + { + ExamYear = d.ExamYear, + Decription = d.Description, + ExamCount = await GetExamCount(d.Id), + PassCount = await GetPassExamCount(d.Id), + NotPassCount = (await GetExamCount(d.Id) - await GetPassExamCount(d.Id)) + }); + } + + return Success(result); + } + catch (Exception ex) + { + return Error(ex); + } + } + + [HttpPost("exam/{id:length(36)}")] + public ActionResult GetExamResultById([FromBody] RecruitExamRequest req, Guid id) + { + try + { + var p_Id = new MySqlParameter("@id", id); + var data = new List(); + using (var cmd = _context.Database.GetDbConnection().CreateCommand()) + { + cmd.CommandTimeout = 0; + var sb = new StringBuilder(); + cmd.Parameters.Clear(); + sb.Clear(); + sb.Append(" SELECT * "); + sb.Append(" FROM exam_info "); + sb.Append(" WHERE recruit_import_id = @id "); + cmd.Parameters.Add(p_Id); + + if (req.ExamAttribute != null && req.ExamAttribute != "") + { + sb.Append(" AND examAttribute = @a "); + cmd.Parameters.Add(new MySqlParameter("@a", req.ExamAttribute)); + } + + if (req.ExamResult != null && req.ExamResult != "") + { + sb.Append(" AND result = @r "); + cmd.Parameters.Add(new MySqlParameter("@r", req.ExamResult)); + } + + cmd.CommandText = sb.ToString(); + + _context.Database.OpenConnection(); + var da = new MySqlDataAdapter(cmd as MySqlCommand); + var dt = new DataTable(); + da.Fill(dt); + + foreach (DataRow dr in dt.Rows) + { + data.Add(new + { + examID = dr["examID"].ToString(), + profileID = dr["profileID"].ToString(), + prefix = dr["prefix"].ToString(), + fullName = dr["fullName"].ToString(), + dateOfBirth = dr["dateofbirth"] == null ? "" : Convert.ToDateTime(dr["dateofbirth"]).ToThaiShortDate(), + gender = dr["gender"].ToString(), + degree = dr["degree"].ToString(), + major = dr["major"].ToString(), + majorgroup = dr["majorgroup"].ToString(), + certificateNo = dr["certificateno"].ToString(), + certificateIssueDate = dr["certificateIssueDate"] == null ? "" : Convert.ToDateTime(dr["certificateIssueDate"]).ToThaiShortDate(), + ExamScore = dr["score"] == null ? 0 : dr["score"].ToString().ToInteger(), + ExamResult = dr["result"].ToString(), + ExamAttribute = dr["examAttribute"].ToString(), + Remark = dr["remark"].ToString(), + IsSpecial = dr["isspecial"].ToString(), + applyDate = dr["applydate"] == null ? "" : Convert.ToDateTime(dr["applydate"]).ToThaiShortDate(), + university = dr["university"].ToString(), + position_name = dr["position_name"].ToString(), + exam_name = dr["exam_name"].ToString(), + exam_order = dr["exam_order"].ToString(), + score_year = Convert.ToInt32(dr["score_year"]).ToThaiYear().ToString(), + }); + } + + } + + dynamic header = null; + using (var cmd = _context.Database.GetDbConnection().CreateCommand()) + { + var sb = new StringBuilder(); + cmd.CommandTimeout = 0; + cmd.Parameters.Clear(); + sb.Clear(); + sb.Append(" SELECT * "); + sb.Append(" FROM sum_exam_info "); + sb.Append(" WHERE recruit_import_id = @id "); + cmd.Parameters.Add(p_Id); + + cmd.CommandText = sb.ToString(); + + + _context.Database.OpenConnection(); + MySqlDataAdapter da = new MySqlDataAdapter(cmd as MySqlCommand); + DataTable dt = new DataTable(); + da.Fill(dt); + if (dt.Rows.Count == 0) + { + header = new + { + count = 0, + pass = 0, + notpass = 0 + }; + } + else + { + var dr = dt.Rows[0]; + header = new + { + count = dr["count"].ToString().ToInteger(), + pass = dr["pass"].ToString().ToInteger(), + notpass = dr["notpass"].ToString().ToInteger() + }; + } + } + + return Success(new + { + data = data, + header = header, + }); + } + catch (Exception ex) + { + return Error(ex); + } + } + + [HttpGet("exam/{id:length(36)}/{examId}")] + public async Task> GetExamResultByPersonAsync(Guid id, string examId) + { + try + { + var data = await _context.Recruits.AsQueryable() + .Include(x => x.RecruitImport) + .Include(x => x.Documents) + .ThenInclude(x => x.DocumentFile) + .Where(x => x.RecruitImport.Id == id) + .Where(x => x.ExamId == examId) + .Join(_context.RecruitScores.AsQueryable() + .Include(x => x.ScoreImport), + rc => new { rc.RecruitImport.Year, rc.ExamId }, + sc => new { sc.ScoreImport.Year, sc.ExamId }, + (p, sr) => new + { + ExamID = p.ExamId, + ProfileID = p.CitizenId, + p.Prefix, + FullName = $"{p.FirstName} {p.LastName}", + DateOfBirth = p.DateOfBirth.ToThaiShortDate(), + Gender = p.Gendor, + Degree = p.Educations.First().Degree, + Major = p.Educations.First().Major, + CertificateNo = p.Certificates.First().CertificateNo, + CertificateIssueDate = p.Certificates.First().IssueDate.ToThaiShortDate(), + ExamResult = sr == null ? "" : sr.ExamStatus, + ExamAttribute = _recruitService.CheckValidCertificate(p.Certificates.First().IssueDate, 5) ? "มีคุณสมบัติ" : "ไม่มีคุณสมบัติ", + IsSpecial = p.Isspecial, + Remark = p.Remark, + University = p.Educations.First().University, + PositionName = p.PositionName, + ExamName = p.RecruitImport.Name, + ExamOrder = p.RecruitImport.Order, + ExamYear = p.RecruitImport.Year.ToThaiYear(), + Score = sr == null ? 0 : sr.SumA + sr.SumB + sr.SumC, + Number = sr == null ? "" : sr.Number, + ExamCount = _recruitService.GetExamCount(p.CitizenId), + ScoreExpire = p.RecruitImport.AnnouncementDate == null ? "" : p.RecruitImport.AnnouncementDate.Value.AddYears(2).ToThaiShortDate(), + ScoreResult = sr == null ? null : new + { + ScoreAFull = sr.FullA, + ScoreA = sr.SumA, + ScoreBFull = sr.FullB, + ScoreB = sr.SumB, + ScoreCFull = sr.FullC, + ScoreC = sr.SumC, + ScoreSumFull = sr.FullA + sr.FullB + sr.FullC, + ScoreSum = sr.SumA + sr.SumB + sr.SumC, + ExamResult = sr.ExamStatus + }, + Attachments = p.Documents.Select(a => new + { + FileName = a.DocumentFile.FileName, + DocumentId = a.DocumentFile.Id + }) + }) + .FirstOrDefaultAsync(); + + return Success(data); + } + catch (Exception ex) + { + return Error(ex); + } + } + + #endregion + + #region " For CMS " + + [HttpGet("competitive")] + [AllowAnonymous] + public IActionResult GetPeriodForCMS([FromQuery] int limit = 0) + { + try + { + var this_year = DateTime.Now.Year.ToCeYear(); + + var periods = (from r in _context.RecruitImports.AsQueryable().Include(x => x.RecruitImages) + where r.Year == this_year + orderby r.AnnouncementStartDate descending + select new + { + id = r.Id, + title = $"{r.Name} ครั้งที่ {r.Order}/{r.Year.ToThaiYear()}", + category = "สำนักงาน ก.ก.", + category_id = 1, + announcement_startDate = r.AnnouncementStartDate == null ? "" : r.AnnouncementStartDate.Value.ToString("yyyy-MM-dd"), + announcement_endDate = r.AnnouncementEndDate == null ? "" : r.AnnouncementEndDate.Value.ToString("yyyy-MM-dd"), + announcementExam = true, + register_startDate = r.RegisterStartDate == null ? "" : r.RegisterStartDate.Value.ToString("yyyy-MM-dd"), + register_endDate = r.RegisterEndDate == null ? "" : r.RegisterEndDate.Value.ToString("yyyy-MM-dd"), + payment_startDate = r.PaymentStartDate == null ? "" : r.PaymentStartDate.Value.ToString("yyyy-MM-dd"), + payment_endDate = r.PaymentEndDate == null ? "" : r.PaymentEndDate.Value.ToString("yyyy-MM-dd"), + exam_date = r.ExamDate == null ? "" : r.ExamDate.Value.ToString("yyyy-MM-dd"), + image = r.RecruitImages.OrderBy(o => o.CreatedAt).FirstOrDefault() == null ? "" : + r.RecruitImages.OrderBy(o => o.CreatedAt).FirstOrDefault().Document.Id.ToString("D") + }) + + .ToList(); + + + //var periods = _context.RecruitImports.AsQueryable() + // .Where(x => x.Year == this_year) + // .Include(x => x.RecruitImages) + // .Select(r => new + // { + // id = r.Id, + // title = $"{r.Name} ครั้งที่ {r.Order}/{r.Year.ToThaiYear()}", + // category = "สำนักงาน ก.ก.", + // category_id = 1, + // announcement_startDate = r.AnnouncementStartDate == null ? "" : r.AnnouncementStartDate.Value.ToString("yyyy-mm-dd"), + // announcement_endDate = r.AnnouncementEndDate == null ? "" : r.AnnouncementEndDate.Value.ToString("yyyy-MM-dd"), + // announcementExam = true, + // register_startDate = r.RegisterStartDate == null ? "" : r.RegisterStartDate.Value.ToString("yyyy-MM-dd"), + // register_endDate = r.RegisterEndDate == null ? "" : r.RegisterEndDate.Value.ToString("yyyy-MM-dd"), + // payment_startDate = r.PaymentStartDate == null ? "" : r.PaymentStartDate.Value.ToString("yyyy-MM-dd"), + // payment_endDate = r.PaymentEndDate == null ? "" : r.PaymentEndDate.Value.ToString("yyyy-MM-dd"), + // exam_date = r.ExamDate == null ? "" : r.ExamDate.Value.ToString("yyyy-MM-dd"), + // image = r.RecruitImages.OrderBy(o => o.CreatedAt).FirstOrDefault() == null ? "" : + // r.RecruitImages.OrderBy(o => o.CreatedAt).FirstOrDefault().Document.Id.ToString("D") + // }) + // .OrderByDescending(x => x.announcement_startDate) + // .ToList(); + + + if (limit > 0) + periods = periods.Take(limit).ToList(); + + + var result = new List(); + foreach (var p in periods) + { + result.Add(new + { + p.id, + p.title, + p.category, + p.category_id, + p.announcementExam, + p.announcement_startDate, + p.announcement_endDate, + p.register_endDate, + p.register_startDate, + p.payment_startDate, + p.payment_endDate, + p.exam_date, + image = p.image == "" ? "" : _minioService.GetFilePath(Guid.Parse(p.image)).Result, + }); + } + + return Ok(result); + } + catch (Exception ex) + { + return StatusCode(500, ex.Message); + } + } + + [HttpGet("competitive/{id:length(36)}")] + [AllowAnonymous] + public IActionResult GetPeriodForCMSById(Guid id) + { + try + { + var periods = (from r in _context.RecruitImports.AsQueryable() + .Include(x => x.RecruitDocuments) + .ThenInclude(x => x.Document) + .Include(x => x.RecruitImages) + .ThenInclude(x => x.Document) + where r.Id == id + select new + { + id = r.Id, + title = $"{r.Name} ครั้งที่ {r.Order}/{r.Year.ToThaiYear()}", + detail = r.Detail, + category = "สำนักงาน ก.ก.", + category_id = 1, + announcement_startDate = r.AnnouncementStartDate == null ? "" : r.AnnouncementStartDate.Value.ToString("yyyy-MM-dd"), + announcement_endDate = r.AnnouncementEndDate == null ? "" : r.AnnouncementEndDate.Value.ToString("yyyy-MM-dd"), + start = r.AnnouncementStartDate == null ? "" : r.AnnouncementStartDate.Value.ToString("yyyy-mm-dd"), + end = r.AnnouncementEndDate == null ? "" : r.AnnouncementEndDate.Value.ToString("yyyy-MM-dd"), + announcementExam = true, + register_startDate = r.RegisterStartDate == null ? "" : r.RegisterStartDate.Value.ToString("yyyy-MM-dd"), + register_endDate = r.RegisterEndDate == null ? "" : r.RegisterEndDate.Value.ToString("yyyy-MM-dd"), + payment_startDate = r.PaymentStartDate == null ? "" : r.PaymentStartDate.Value.ToString("yyyy-MM-dd"), + payment_endDate = r.PaymentEndDate == null ? "" : r.PaymentEndDate.Value.ToString("yyyy-MM-dd"), + examDate = r.ExamDate == null ? "" : r.ExamDate.Value.ToString("yyyy-MM-dd"), + Images = r.RecruitImages.OrderBy(x => x.CreatedAt).Select(s => new + { + Title = s.Document.FileName, + Url = s.Document.Id.ToString("D") + }).ToList(), + Files = r.RecruitDocuments.OrderBy(x => x.CreatedAt).Select(s => new + { + Title = s.Document.FileName, + Url = s.Document.Id.ToString("D") + }).ToList(), + }).FirstOrDefault(); + + // re create image list + var new_image = new List(); + foreach (var p in periods.Images) + { + new_image.Add(new + { + Title = p.Title, + Url = _minioService.GetFilePath(Guid.Parse(p.Url)).Result, + }); + } + + // re create doc list + var new_doc = new List(); + foreach (var p in periods.Files) + { + new_doc.Add(new + { + Title = p.Title, + Url = _minioService.GetFilePath(Guid.Parse(p.Url)).Result, + }); + } + + var result = new + { + periods.id, + periods.title, + periods.detail, + periods.category, + periods.category_id, + periods.announcement_endDate, + periods.announcement_startDate, + periods.start, + periods.end, + periods.announcementExam, + periods.register_endDate, + periods.register_startDate, + periods.payment_endDate, + periods.payment_startDate, + periods.examDate, + images = new_image, + files = new_doc + }; + + + return Ok(result); + } + catch (Exception ex) + { + return StatusCode(500, ex.Message); + } + } + + + #endregion + + #region " Export Excel " + + [HttpGet("export/exam/{id:length(36)}")] + public async Task> ExportExamAsync(Guid id) + { + var data = await _context.RecruitImports.AsQueryable() + .Include(x => x.Recruits) + .FirstOrDefaultAsync(x => x.Id == id); + + if (data == null) + return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); + + var header = $"{data.Name} ครั้งที่ {data.Order}/{data.Year.ToThaiYear()}"; + + var template_dir = Path.Combine(_webHostEnvironment.ContentRootPath, "Templates"); + + var template_file = Path.Combine(template_dir, "ExamList.xlsx"); + + var tmpDir = Path.Combine(_webHostEnvironment.ContentRootPath, "tmp"); + if (!Directory.Exists(tmpDir)) + Directory.CreateDirectory(tmpDir); + + var exportFile = Path.Combine(tmpDir, $"ExamList_{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx"); + try + { + // copy template + System.IO.File.Copy(template_file, exportFile); + + using (var excel = new ExcelPackage(new FileInfo(exportFile))) + { + var workSheet = excel.Workbook.Worksheets[0]; + + + workSheet.Cells[1, 2].Value = header; + var recruits = data.Recruits.OrderBy(x => x.ExamId).ToList(); + + var row = 4; // start at row 4 + foreach (var item in recruits) + { + workSheet.Cells[row, 1].Value = item.ExamId; + workSheet.Cells[row, 2].Value = item.CitizenId; + workSheet.Cells[row, 3].Value = $"{item.Prefix}{item.FirstName} {item.LastName}"; + workSheet.Cells[row, 4].Value = item.PositionName; + + row++; + } + + excel.Save(); + + using (FileStream fs = new FileStream(exportFile, FileMode.Open, FileAccess.Read)) + { + byte[] bytes = System.IO.File.ReadAllBytes(exportFile); + fs.Read(bytes, 0, System.Convert.ToInt32(fs.Length)); + fs.Close(); + + var fname = Path.GetFileName(exportFile); + + Response.Headers["Content-Disposition"] = $"inline; filename={fname}"; + + var ret = new FileContentResult(bytes, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") + { + FileDownloadName = fname + }; + + return ret; + } + } + } + catch (Exception ex) + { + return Error(ex, "ไม่สามารถส่งออกรายชื่อผู้มีสิทธิ์สอบได้!!"); + } + finally + { + if (System.IO.File.Exists(exportFile)) + System.IO.File.Delete(exportFile); + } + } + + [HttpGet("export/pass-exam/{id:length(36)}")] + public async Task> ExportPassExamAsync(Guid id) + { + var data = await _context.RecruitImports.AsQueryable() + .Include(x => x.Recruits) + .FirstOrDefaultAsync(x => x.Id == id); + + var data_pass = await _context.RecruitImports.AsQueryable() + .Include(x => x.ScoreImport) + .ThenInclude(x => x.Scores) + .FirstOrDefaultAsync(x => x.Id == id); + + if (data == null) + return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); + + if (data_pass == null) + return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); + + var header = $"{data.Name} ครั้งที่ {data.Order}/{data.Year.ToThaiYear()}"; + + var template_dir = Path.Combine(_webHostEnvironment.ContentRootPath, "Templates"); + + var template_file = Path.Combine(template_dir, "PassAExamList.xlsx"); + + var tmpDir = Path.Combine(_webHostEnvironment.ContentRootPath, "tmp"); + if (!Directory.Exists(tmpDir)) + Directory.CreateDirectory(tmpDir); + + var exportFile = Path.Combine(tmpDir, $"PassExamList_{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx"); + + try + { + var result = (from r in data.Recruits.ToList() + join s in data_pass.ScoreImport.Scores.Where(x => x.AStatus == "ผ่าน").ToList() on r.ExamId equals s.ExamId + select new + { + r.ExamId, + r.CitizenId, + r.Prefix, + r.FirstName, + r.LastName, + s.FullA, + s.SumA, + s.AStatus, + + }).ToList(); + + // copy template + System.IO.File.Copy(template_file, exportFile); + + using (var excel = new ExcelPackage(new FileInfo(exportFile))) + { + var workSheet = excel.Workbook.Worksheets[0]; + + + workSheet.Cells[1, 2].Value = header; + var recruits = data.Recruits.OrderBy(x => x.ExamId).ToList(); + + var row = 4; // start at row 4 + foreach (var item in result) + { + workSheet.Cells[row, 1].Value = item.ExamId; + workSheet.Cells[row, 2].Value = item.CitizenId; + workSheet.Cells[row, 3].Value = $"{item.Prefix}{item.FirstName} {item.LastName}"; + workSheet.Cells[row, 4].Value = item.FullA; + workSheet.Cells[row, 5].Value = item.SumA; + workSheet.Cells[row, 6].Value = item.AStatus; + + row++; + } + + excel.Save(); + + using (FileStream fs = new FileStream(exportFile, FileMode.Open, FileAccess.Read)) + { + byte[] bytes = System.IO.File.ReadAllBytes(exportFile); + fs.Read(bytes, 0, System.Convert.ToInt32(fs.Length)); + fs.Close(); + + var fname = Path.GetFileName(exportFile); + + Response.Headers["Content-Disposition"] = $"inline; filename={fname}"; + + var ret = new FileContentResult(bytes, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") + { + FileDownloadName = fname + }; + + return ret; + } + } + } + catch (Exception ex) + { + return Error(ex, "ไม่สามารถส่งออกรายชื่อผู้สอบผ่านได้!!"); + } + finally + { + if (System.IO.File.Exists(exportFile)) + System.IO.File.Delete(exportFile); + } + } + + [HttpGet("export/pass/{id:length(36)}")] + public async Task> ExportPassExamResultAsync(Guid id) + { + var data = await _context.RecruitImports.AsQueryable() + .Include(x => x.Recruits) + .FirstOrDefaultAsync(x => x.Id == id); + + var data_pass = await _context.RecruitImports.AsQueryable() + .Include(x => x.ScoreImport) + .ThenInclude(x => x.Scores) + .FirstOrDefaultAsync(x => x.Id == id); + + if (data == null) + return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); + + if (data_pass == null) + return Error(GlobalMessages.DataNotFound, StatusCodes.Status404NotFound); + + var header = $"{data.Name} ครั้งที่ {data.Order}/{data.Year.ToThaiYear()}"; + + var template_dir = Path.Combine(_webHostEnvironment.ContentRootPath, "Templates"); + + var template_file = Path.Combine(template_dir, "PassExamList.xlsx"); + + var tmpDir = Path.Combine(_webHostEnvironment.ContentRootPath, "tmp"); + if (!Directory.Exists(tmpDir)) + Directory.CreateDirectory(tmpDir); + + var exportFile = Path.Combine(tmpDir, $"PassExamList_{DateTime.Now.ToString("yyyyMMddHHmmss")}.xlsx"); + + try + { + var result = (from r in data.Recruits.ToList() + join s in data_pass.ScoreImport.Scores.Where(x => x.ExamStatus == "ผ่าน").ToList() on r.ExamId equals s.ExamId + select new + { + r.ExamId, + r.CitizenId, + r.Prefix, + r.FirstName, + r.LastName, + Full = s.FullA + s.FullB + s.FullC, + Sum = s.SumA + s.SumB + s.SumC, + Status = s.ExamStatus, + r.PositionName, + s.Number + }).ToList(); + + // copy template + System.IO.File.Copy(template_file, exportFile); + + using (var excel = new ExcelPackage(new FileInfo(exportFile))) + { + var workSheet = excel.Workbook.Worksheets[0]; + + + workSheet.Cells[1, 2].Value = header; + var recruits = data.Recruits.OrderBy(x => x.ExamId).ToList(); + + var row = 4; // start at row 4 + foreach (var item in result) + { + workSheet.Cells[row, 1].Value = item.ExamId; + workSheet.Cells[row, 2].Value = item.CitizenId; + workSheet.Cells[row, 3].Value = $"{item.Prefix}{item.FirstName} {item.LastName}"; + workSheet.Cells[row, 4].Value = item.Full; + workSheet.Cells[row, 5].Value = item.Sum; + workSheet.Cells[row, 6].Value = item.Status; + workSheet.Cells[row, 7].Value = item.Number; + workSheet.Cells[row, 8].Value = item.PositionName; + + row++; + } + + excel.Save(); + + using (FileStream fs = new FileStream(exportFile, FileMode.Open, FileAccess.Read)) + { + byte[] bytes = System.IO.File.ReadAllBytes(exportFile); + fs.Read(bytes, 0, System.Convert.ToInt32(fs.Length)); + fs.Close(); + + var fname = Path.GetFileName(exportFile); + + Response.Headers["Content-Disposition"] = $"inline; filename={fname}"; + + var ret = new FileContentResult(bytes, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") + { + FileDownloadName = fname + }; + + return ret; + } + } + } + catch (Exception ex) + { + return Error(ex, "ไม่สามารถส่งออกรายชื่อผู้สอบผ่านได้!!"); + } + finally + { + if (System.IO.File.Exists(exportFile)) + System.IO.File.Delete(exportFile); + } + } + + #endregion + + #region " Image and Document " + + /// + /// Upload Image หรือ เอกสารในรอบการสอบ + /// + /// ประเภทเอกสาร + /// รหัสรอบสมัคร + /// + /// เมื่อทำการอ่านข้อมูลรอบการสมัครสอบ และ คนสมัครสอบในรอบสำเร็จ + /// ไม่ได้ Login เข้าระบบ + /// เมื่อเกิดข้อผิดพลาดในการทำงาน + [HttpPut("{type}/{importId:length(36)}"), DisableRequestSizeLimit] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status401Unauthorized)] + [ProducesResponseType(StatusCodes.Status500InternalServerError)] + public async Task> UpdateDocAsync(string type, Guid importId) + { + try + { + if (Request.Form.Files == null || Request.Form.Files.Count == 0) + { + return Error(GlobalMessages.NoFileToUpload); + } + + var files = Request.Form.Files; + if (type == "img") + { + await _recruitService.UpdateImageAsync(importId, files); + } + else + { + await _recruitService.UpdateDocAsync(importId, files); + } + + return Success(); + } + catch (Exception ex) + { + return Error(ex); + } + } + + /// + /// ลบ Image หรือ เอกสารในรอบการสอบ + /// + /// ประเภทเอกสาร + /// รหัสไฟล์ + /// + /// เมื่อทำรายการสำเร็จ + /// ไม่ได้ Login เข้าระบบ + /// เมื่อเกิดข้อผิดพลาดในการทำงาน + [HttpDelete("{type}/{docId:length(36)}")] + public async Task> DeleteDocAsync(string type, Guid docId) + { + try + { + if (type == "img") + { + await _recruitService.DeleteImageAsync(docId); + } + else + { + await _recruitService.DeleteDocAsync(docId); + } + + return Success(); + } + catch (Exception ex) + { + return Error(ex, "ไม่สามารถลบไฟล์ได้"); + } + } + + #endregion + + #endregion + } } \ No newline at end of file diff --git a/Data/MetadataDbContext.cs b/Data/MetadataDbContext.cs new file mode 100644 index 0000000..7c8cbbc --- /dev/null +++ b/Data/MetadataDbContext.cs @@ -0,0 +1,38 @@ +using Microsoft.EntityFrameworkCore; + +namespace BMA.EHR.Recurit.Service.Data +{ + public class MetadataDbContext : DbContext + { + public MetadataDbContext(DbContextOptions options) + : base(options) + { + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + } + + // The following configures EF to create a Sqlite database file in the + // special "local" folder for your platform. + protected override void OnConfiguring(DbContextOptionsBuilder options) + { + // if (!options.IsConfigured) + // { + // var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"; + // var configurationBuilder = new ConfigurationBuilder() + // .AddJsonFile("appsettings.json", optional: true, true) + // .AddJsonFile($"appsettings.{environment}.json", true, true) + // .AddEnvironmentVariables() + // .Build(); + + // var historyConnection = configurationBuilder.GetConnectionString("HistoryConnection"); + // options.UseMySql(historyConnection, ServerVersion.AutoDetect(historyConnection)); + + // } + } + public DbSet ProfileOrganizations { get; set; } + public DbSet Organizations { get; set; } + + } +} diff --git a/Models/HR/OrganizationEntity.cs b/Models/HR/OrganizationEntity.cs new file mode 100644 index 0000000..84154bb --- /dev/null +++ b/Models/HR/OrganizationEntity.cs @@ -0,0 +1,74 @@ +using Microsoft.EntityFrameworkCore; +using System.ComponentModel.DataAnnotations.Schema; +using BMA.EHR.Recruit.Service.Models; + +namespace BMA.EHR.Profile.Service.Models.HR +{ + public class OrganizationEntity : EntityBase + { + + //[ForeignKey("OrganizationOrganizationId")] + //public OrganizationOrganization? OrganizationOrganization_OrganizationOrganizationId { get; set; } + + [Column(Order = 2), Comment("OrganizationOrganizationId")] + public Guid? OrganizationOrganizationId { get; set; } + + //[ForeignKey("OrganizationShortNameId")] + //public OrganizationShortName? OrganizationShortName_OrganizationShortNameId { get; set; } + + [Column(Order = 3), Comment("OrganizationShortNameId")] + public Guid? OrganizationShortNameId { get; set; } + + //[ForeignKey("OrganizationTypeId")] + //public OrganizationType? OrganizationType_OrganizationTypeId { get; set; } + + [Column(Order = 4), Comment("OrganizationTypeId")] + public Guid? OrganizationTypeId { get; set; } + + //[ForeignKey("OrganizationLevelId")] + //public OrganizationLevel? OrganizationLevel_OrganizationLevelId { get; set; } + + [Column(Order = 5), Comment("OrganizationLevelId")] + public Guid? OrganizationLevelId { get; set; } + + //[ForeignKey("OrganizationTelExternalId")] + //public OrganizationTelExternal? OrganizationTelExternal_OrganizationTelExternalId { get; set; } + + [Column(Order = 6), Comment("OrganizationTelExternalId")] + public Guid? OrganizationTelExternalId { get; set; } + + //[ForeignKey("OrganizationTelInternalId")] + //public OrganizationTelInternal? OrganizationTelInternal_OrganizationTelInternalId { get; set; } + + [Column(Order = 7), Comment("OrganizationTelInternalId")] + public Guid? OrganizationTelInternalId { get; set; } + + //[ForeignKey("OrganizationFaxId")] + //public OrganizationFax? OrganizationFax_OrganizationFaxId { get; set; } + + [Column(Order = 8), Comment("OrganizationFaxId")] + public Guid? OrganizationFaxId { get; set; } + + [ForeignKey("ParentId")] + public OrganizationEntity? Organization_ParentId { get; set; } + + [Column(Order = 9), Comment("ParentId")] + public Guid? ParentId { get; set; } + + [Column(Order = 10), Comment("OrganizationAgencyId")] + public Guid? OrganizationAgencyId { get; set; } + + [Column(Order = 11), Comment("OrganizationGovernmentAgencyId")] + public Guid? OrganizationGovernmentAgencyId { get; set; } + + [Column(Order = 12), Comment("OrganizationOrder")] + public int? OrganizationOrder { get; set; } + + [Column(Order = 13), Comment("OrganizationUserNote")] + public string? OrganizationUserNote { get; set; } + public bool IsActive { get; set; } = true; + + public List Organizations { get; } = new(); + + } +} diff --git a/Models/HR/ProfileOrganization.cs b/Models/HR/ProfileOrganization.cs new file mode 100644 index 0000000..8c48351 --- /dev/null +++ b/Models/HR/ProfileOrganization.cs @@ -0,0 +1,11 @@ + +using BMA.EHR.Recruit.Service.Models; + +namespace BMA.EHR.Profile.Service.Models.HR +{ + public class ProfileOrganization : EntityBase + { + public Guid? OrganizationId { get; set; } + public Guid? UserId { get; set; } + } +} diff --git a/Program.cs b/Program.cs index d5c2111..8718819 100644 --- a/Program.cs +++ b/Program.cs @@ -16,6 +16,7 @@ using BMA.EHR.Recruit.Service.Data; using BMA.EHR.Recruit.Service; using Microsoft.AspNetCore.Mvc.ApiExplorer; using BMA.EHR.Recruit.Service.Services; +using BMA.EHR.Recurit.Service.Data; var builder = WebApplication.CreateBuilder(args); var issuer = builder.Configuration["Jwt:Issuer"]; @@ -74,7 +75,10 @@ BsonSerializer.RegisterSerializer(new DateTimeSerializer(BsonType.String)); // Register DbContext var defaultConnection = builder.Configuration.GetConnectionString("DefaultConnection"); builder.Services.AddDbContext(options => - options.UseMySql(defaultConnection, ServerVersion.AutoDetect(defaultConnection)), ServiceLifetime.Transient); + options.UseMySql(defaultConnection, ServerVersion.AutoDetect(defaultConnection))); +var metadataConnection = builder.Configuration.GetConnectionString("MetadataConnection"); +builder.Services.AddDbContext(options => + options.UseMySql(metadataConnection, ServerVersion.AutoDetect(metadataConnection))); // Add config CORS builder.Services.AddCors(options => options.AddDefaultPolicy(builder => diff --git a/appsettings.Development.json b/appsettings.Development.json index 0872841..b9958cb 100644 --- a/appsettings.Development.json +++ b/appsettings.Development.json @@ -14,7 +14,8 @@ "AllowedHosts": "*", "ConnectionStrings": { "MongoConnection": "mongodb://127.0.0.1:27017", - "DefaultConnection": "server=192.168.1.9;user=root;password=adminVM123;port=3306;database=bma_recruit;Convert Zero Datetime=True;Allow User Variables=true;Pooling=True;" + "DefaultConnection": "server=192.168.1.9;user=root;password=adminVM123;port=3306;database=bma_recruit;Convert Zero Datetime=True;Allow User Variables=true;Pooling=True;", + "MetadataConnection": "server=127.0.0.1;user=root;password=P@ssw0rd;port=3308;database=bma_ehr;Convert Zero Datetime=True;Allow User Variables=true;Pooling=True;" }, "Jwt": { "Key": "HP-FnQMUj9msHMSD3T9HtdEnphAKoCJLEl85CIqROFI", diff --git a/appsettings.json b/appsettings.json index 099e355..3f28a1e 100644 --- a/appsettings.json +++ b/appsettings.json @@ -14,7 +14,8 @@ "AllowedHosts": "*", "ConnectionStrings": { "MongoConnection": "mongodb://admin:adminVM123@127.0.0.1:27017", - "DefaultConnection": "server=192.168.1.9;user=root;password=adminVM123;port=3306;database=bma_recruit;Convert Zero Datetime=True;Allow User Variables=true;Pooling=True;" + "DefaultConnection": "server=192.168.1.9;user=root;password=adminVM123;port=3306;database=bma_recruit;Convert Zero Datetime=True;Allow User Variables=true;Pooling=True;", + "MetadataConnection": "server=192.168.1.9;user=root;password=adminVM123;database=bma_ehr;Convert Zero Datetime=True;Allow User Variables=true;Pooling=True;" }, "Jwt": { "Key": "HP-FnQMUj9msHMSD3T9HtdEnphAKoCJLEl85CIqROFI",