2023-03-24 15:16:00 +07:00
|
|
|
using BMA.EHR.Recruit.Service.Core;
|
|
|
|
|
using BMA.EHR.Recruit.Service.Data;
|
|
|
|
|
using BMA.EHR.Recruit.Service.Models.Recruits;
|
|
|
|
|
using BMA.EHR.Recruit.Service.Requests.Recruits;
|
2023-03-17 14:24:43 +07:00
|
|
|
using BMA.EHR.Recruit.Service.Responses;
|
|
|
|
|
using BMA.EHR.Recruit.Service.Services;
|
|
|
|
|
using Microsoft.AspNetCore.Authorization;
|
|
|
|
|
using Microsoft.AspNetCore.Mvc;
|
2023-03-24 15:16:00 +07:00
|
|
|
using Microsoft.EntityFrameworkCore;
|
2023-03-17 14:24:43 +07:00
|
|
|
using Swashbuckle.AspNetCore.Annotations;
|
2023-03-24 15:16:00 +07:00
|
|
|
using System.Net;
|
|
|
|
|
using System.Text;
|
2023-03-17 14:24:43 +07:00
|
|
|
|
|
|
|
|
namespace BMA.EHR.Recruit.Service.Controllers
|
|
|
|
|
{
|
2023-03-25 21:01:46 +07:00
|
|
|
[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;
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region " Constructor and Destructor "
|
|
|
|
|
|
|
|
|
|
public RecruitController(ApplicationDbContext context,
|
|
|
|
|
MinIOService minioService,
|
|
|
|
|
IWebHostEnvironment webHostEnvironment,
|
|
|
|
|
RecruitService recruitService)
|
|
|
|
|
{
|
|
|
|
|
_context = context;
|
|
|
|
|
_minioService = minioService;
|
|
|
|
|
_webHostEnvironment = webHostEnvironment;
|
|
|
|
|
_recruitService = recruitService;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#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<int> 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<int> 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<int> 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 "
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// ตัวอย่างในการเขียน api เพื่อทำการ upload file
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
2023-03-31 16:12:19 +07:00
|
|
|
/// <response code="200">เมื่อทำการ upload สำเร็จ</response>
|
2023-03-25 21:01:46 +07:00
|
|
|
/// <response code="400">ค่าตัวแปรที่ส่งมาไม่ถูกต้อง</response>
|
|
|
|
|
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
|
|
|
|
|
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
|
|
|
|
|
[HttpPost("upload"), DisableRequestSizeLimit]
|
|
|
|
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
|
|
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
|
|
|
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
|
|
|
|
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
|
|
|
|
[AllowAnonymous]
|
|
|
|
|
public async Task<ActionResult<ResponseObject>> 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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-31 16:12:19 +07:00
|
|
|
/// <summary>
|
|
|
|
|
/// ตัวอย่างในการเขียน api เพื่อทำการ delete file
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="id">รหัสไฟล์ในฐานข้อมูล</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
/// <response code="200">เมื่อทำการ delete file สำเร็จ</response>
|
|
|
|
|
/// <response code="400">ค่าตัวแปรที่ส่งมาไม่ถูกต้อง</response>
|
|
|
|
|
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
|
|
|
|
|
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
|
2023-03-25 21:01:46 +07:00
|
|
|
[HttpGet("delete/{id:length(36)}")]
|
2023-03-31 16:12:19 +07:00
|
|
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
|
|
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
|
|
|
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
|
|
|
|
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
2023-03-25 21:01:46 +07:00
|
|
|
[AllowAnonymous]
|
|
|
|
|
public async Task<ActionResult<ResponseObject>> DeleteFile(Guid id)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
await _minioService.DeleteFileAsync(id);
|
|
|
|
|
|
|
|
|
|
return Success();
|
|
|
|
|
}
|
2023-04-03 12:19:09 +07:00
|
|
|
catch (Exception ex)
|
2023-03-25 21:01:46 +07:00
|
|
|
{
|
|
|
|
|
return Error(ex);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-31 16:12:19 +07:00
|
|
|
/// <summary>
|
|
|
|
|
/// ตัวอย่างในการเขียน api เพื่อทำการ download file
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="id">รหัสไฟล์ในฐานข้อมูล</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
/// <response code="200">เมื่อทำการ download file สำเร็จ</response>
|
|
|
|
|
/// <response code="400">ค่าตัวแปรที่ส่งมาไม่ถูกต้อง</response>
|
|
|
|
|
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
|
|
|
|
|
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
|
2023-03-25 21:01:46 +07:00
|
|
|
[HttpGet("download/{id:length(36)}")]
|
2023-03-31 16:12:19 +07:00
|
|
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
|
|
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
|
|
|
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
|
|
|
|
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
2023-03-25 21:01:46 +07:00
|
|
|
[AllowAnonymous]
|
|
|
|
|
public async Task<ActionResult<ResponseObject>> 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 " จัดการรอบการสมัครสอบแข่งขัน "
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// แสดงข้อมูลรอบการสอบแข่งขัน
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
/// <response code="200">เมื่อทำการอ่านข้อมูลจาก Relational Database สำเร็จ</response>
|
|
|
|
|
/// <response code="400">ค่าตัวแปรที่ส่งมาไม่ถูกต้อง</response>
|
|
|
|
|
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
|
|
|
|
|
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
|
2023-04-03 12:19:09 +07:00
|
|
|
[HttpGet("period")]
|
2023-03-25 21:01:46 +07:00
|
|
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
|
|
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
|
|
|
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
|
|
|
|
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
2023-04-03 12:19:09 +07:00
|
|
|
public async Task<ActionResult<ResponseObject>> GetPeriodsAsync()
|
2023-03-25 21:01:46 +07:00
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var data = await _context.RecruitImports.AsQueryable()
|
|
|
|
|
.OrderByDescending(x => x.Year)
|
|
|
|
|
.ThenByDescending(x => x.Order)
|
|
|
|
|
.ToListAsync();
|
|
|
|
|
|
|
|
|
|
return Success(data);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
return Error(ex);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2023-04-03 09:18:43 +07:00
|
|
|
/// แสดงข้อมูลรอบการสอบแข่งขันเป็นรายการ
|
2023-03-25 21:01:46 +07:00
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="id">รหัสรอบการสอบแข่งขัน</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
/// <response code="200">เมื่อทำการอ่านข้อมูลจาก Relational Database สำเร็จ</response>
|
|
|
|
|
/// <response code="400">ค่าตัวแปรที่ส่งมาไม่ถูกต้อง</response>
|
|
|
|
|
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
|
|
|
|
|
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
|
2023-04-03 12:19:09 +07:00
|
|
|
[HttpGet("period/{id:length(36)}")]
|
2023-03-25 21:01:46 +07:00
|
|
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
|
|
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
|
|
|
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
|
|
|
|
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
2023-04-03 12:19:09 +07:00
|
|
|
public async Task<ActionResult<ResponseObject>> GetPeriodByIdAsync(Guid id)
|
2023-03-25 21:01:46 +07:00
|
|
|
{
|
|
|
|
|
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)
|
|
|
|
|
.FirstOrDefaultAsync(x => x.Id == id);
|
|
|
|
|
|
|
|
|
|
return Success(data);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
return Error(ex);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// เพิ่มข้อมูลรอบการจัดสอบแข่งขัน
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="req">Request parameters</param>
|
|
|
|
|
/// <returns></returns>
|
2023-04-03 12:19:09 +07:00
|
|
|
/// <response code="200">เมื่อทำการเพิ่มข้อมูลสำเร็จ</response>
|
2023-03-25 21:01:46 +07:00
|
|
|
/// <response code="400">ค่าตัวแปรที่ส่งมาไม่ถูกต้อง</response>
|
|
|
|
|
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
|
|
|
|
|
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
|
|
|
|
|
[HttpPost("period")]
|
|
|
|
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
|
|
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
|
|
|
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
|
|
|
|
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
|
|
|
|
public async Task<ActionResult<ResponseObject>> PostPeriodAsync([FromBody] PostRecruitImportRequest req)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
if (req == null)
|
|
|
|
|
return Error(GlobalMessages.InvalidRequestParam, (int)HttpStatusCode.BadRequest);
|
|
|
|
|
|
|
|
|
|
await _context.RecruitImports.AddAsync(new RecruitImport
|
|
|
|
|
{
|
|
|
|
|
Year = req.Year,
|
|
|
|
|
Name = req.Name,
|
|
|
|
|
Order = req.Order,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
await _context.SaveChangesAsync();
|
|
|
|
|
|
|
|
|
|
return Success();
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
return Error(ex);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-03 12:19:09 +07:00
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// ลบข้อมูลรอบการจัดสอบแข่งขัน
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="id">รหัสรอบการสอบแข่งขัน</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
/// <response code="200">เมื่อทำการลบข้อมูลสำเร็จ</response>
|
|
|
|
|
/// <response code="400">ค่าตัวแปรที่ส่งมาไม่ถูกต้อง</response>
|
|
|
|
|
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
|
|
|
|
|
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
|
|
|
|
|
[HttpDelete("period/{id:length(36)}")]
|
|
|
|
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
|
|
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
|
|
|
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
|
|
|
|
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
|
|
|
|
public async Task<ActionResult<ResponseObject>> 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)
|
|
|
|
|
.FirstOrDefaultAsync(x => x.Id == id);
|
|
|
|
|
|
|
|
|
|
_context.RecruitImports.Remove(data);
|
|
|
|
|
await _context.SaveChangesAsync();
|
|
|
|
|
|
|
|
|
|
return Success();
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
return Error(ex);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-25 21:01:46 +07:00
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
2023-03-17 14:24:43 +07:00
|
|
|
}
|