697 lines
33 KiB
C#
697 lines
33 KiB
C#
using BMA.EHR.Application.Repositories;
|
|
using BMA.EHR.Application.Repositories.Leaves.TimeAttendants;
|
|
using BMA.EHR.Domain.Common;
|
|
using BMA.EHR.Domain.Models.Leave.TimeAttendants;
|
|
using BMA.EHR.Domain.Shared;
|
|
using BMA.EHR.Infrastructure.Persistence;
|
|
using BMA.EHR.Leave.Service.DTOs.CheckIn;
|
|
using BMA.EHR.Leave.Service.DTOs.DutyTime;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Swashbuckle.AspNetCore.Annotations;
|
|
using System.ComponentModel.DataAnnotations;
|
|
using System.Security.Claims;
|
|
|
|
namespace BMA.EHR.Leave.Service.Controllers
|
|
{
|
|
[Route("api/v{version:apiVersion}/leave")]
|
|
[ApiVersion("1.0")]
|
|
[ApiController]
|
|
[Produces("application/json")]
|
|
[Authorize]
|
|
[SwaggerTag("API ระบบลงเวลาและการลา")]
|
|
public class LeaveController : BaseController
|
|
{
|
|
#region " Fields "
|
|
|
|
private readonly DutyTimeRepository _dutyTimeRepository;
|
|
private readonly LeaveDbContext _context;
|
|
private readonly IHttpContextAccessor _httpContextAccessor;
|
|
private readonly IWebHostEnvironment _hostingEnvironment;
|
|
private readonly IConfiguration _configuration;
|
|
private readonly UserProfileRepository _userProfileRepository;
|
|
private readonly UserTimeStampRepository _userTimeStampRepository;
|
|
private readonly MinIOService _minIOService;
|
|
private readonly ProcessUserTimeStampRepository _processUserTimeStampRepository;
|
|
|
|
private readonly string _bucketName = "check-in";
|
|
|
|
#endregion
|
|
|
|
#region " Constuctor and Destructor "
|
|
|
|
public LeaveController(DutyTimeRepository dutyTimeRepository,
|
|
LeaveDbContext context,
|
|
IHttpContextAccessor httpContextAccessor,
|
|
IWebHostEnvironment hostingEnvironment,
|
|
IConfiguration configuration,
|
|
UserProfileRepository userProfileRepository,
|
|
UserTimeStampRepository userTimeStampRepository,
|
|
MinIOService minIOService,
|
|
ProcessUserTimeStampRepository processUserTimeStampRepository)
|
|
{
|
|
_dutyTimeRepository = dutyTimeRepository;
|
|
_context = context;
|
|
_httpContextAccessor = httpContextAccessor;
|
|
_hostingEnvironment = hostingEnvironment;
|
|
_configuration = configuration;
|
|
_userProfileRepository = userProfileRepository;
|
|
_userTimeStampRepository = userTimeStampRepository;
|
|
_minIOService = minIOService;
|
|
_processUserTimeStampRepository = processUserTimeStampRepository;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region " Properties "
|
|
|
|
private string? UserId => _httpContextAccessor?.HttpContext?.User?.FindFirst(ClaimTypes.NameIdentifier)?.Value;
|
|
|
|
private string? FullName => _httpContextAccessor?.HttpContext?.User?.FindFirst("name")?.Value;
|
|
|
|
private bool? PlacementAdmin => _httpContextAccessor?.HttpContext?.User?.IsInRole("placement1");
|
|
|
|
private Guid OcId
|
|
{
|
|
get
|
|
{
|
|
if (UserId != null || UserId != "")
|
|
return _userProfileRepository.GetUserOCId(Guid.Parse(UserId!));
|
|
else
|
|
return Guid.Empty;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region " Methods "
|
|
|
|
#region " Duty Time รอบการทำงาน "
|
|
|
|
/// <summary>
|
|
/// LV1_004 - ข้อมูลทั้งหมดของรอบการปฏิบัติงาน (ADMIN)
|
|
/// </summary>
|
|
/// <returns>
|
|
/// </returns>
|
|
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
|
|
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
|
|
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
|
|
[HttpGet("duty-time")]
|
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
|
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
|
public async Task<ActionResult<ResponseObject>> GetAllAsync()
|
|
{
|
|
var data = await _dutyTimeRepository.GetAllAsync();
|
|
|
|
return Success(data);
|
|
}
|
|
|
|
/// <summary>
|
|
/// ข้อมูลของรอบการปฏิบัติงาน (ADMIN)
|
|
/// </summary>
|
|
/// <returns>
|
|
/// </returns>
|
|
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
|
|
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
|
|
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
|
|
[HttpGet("duty-time/{id:guid}")]
|
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
|
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
|
public async Task<ActionResult<ResponseObject>> GetByIdAsync(Guid id)
|
|
{
|
|
var data = await _dutyTimeRepository.GetByIdAsync(id);
|
|
|
|
return Success(data);
|
|
}
|
|
|
|
/// <summary>
|
|
/// LV1_001 - สร้างรอบการปฏิบัติงาน (ADMIN)
|
|
/// </summary>
|
|
/// <returns>
|
|
/// </returns>
|
|
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
|
|
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
|
|
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
|
|
[HttpPost("duty-time")]
|
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
|
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
|
public async Task<ActionResult<ResponseObject>> PostAsync([FromBody] CreateDutyTimeDto data)
|
|
{
|
|
// validate
|
|
var startMorning = TimeOnly.Parse(data.StartTimeMorning);
|
|
var endMorning = TimeOnly.Parse(data.EndTimeMorning);
|
|
var startAfternoon = TimeOnly.Parse(data.StartTimeAfternoon);
|
|
var endAfternoon = TimeOnly.Parse(data.EndTimeAfternoon);
|
|
|
|
if (startMorning >= endMorning)
|
|
{
|
|
throw new Exception(GlobalMessages.StartTimeGreaterEnd);
|
|
}
|
|
|
|
if (startAfternoon >= endAfternoon)
|
|
{
|
|
throw new Exception(GlobalMessages.StartTimeGreaterEnd);
|
|
}
|
|
|
|
var oldData = await _dutyTimeRepository.GetAllAsync();
|
|
if (oldData == null || oldData.Count == 0)
|
|
{
|
|
var inserted = new DutyTime
|
|
{
|
|
Id = Guid.NewGuid(),
|
|
Description = data.Description,
|
|
StartTimeMorning = data.StartTimeMorning,
|
|
EndTimeMorning = data.EndTimeMorning,
|
|
StartTimeAfternoon = data.StartTimeAfternoon,
|
|
EndTimeAfternoon = data.EndTimeAfternoon,
|
|
IsActive = true,
|
|
IsDefault = true,
|
|
};
|
|
|
|
var ret = await _dutyTimeRepository.AddAsync(inserted);
|
|
|
|
return Success(ret);
|
|
}
|
|
else
|
|
{
|
|
if (data.IsDefault)
|
|
{
|
|
foreach (var d in oldData)
|
|
{
|
|
d.IsDefault = false;
|
|
await _dutyTimeRepository.UpdateAsync(d);
|
|
}
|
|
}
|
|
|
|
var inserted = new DutyTime
|
|
{
|
|
Id = Guid.NewGuid(),
|
|
Description = data.Description,
|
|
StartTimeMorning = data.StartTimeMorning,
|
|
EndTimeMorning = data.EndTimeMorning,
|
|
StartTimeAfternoon = data.StartTimeAfternoon,
|
|
EndTimeAfternoon = data.EndTimeAfternoon,
|
|
IsActive = true,
|
|
IsDefault = data.IsDefault,
|
|
};
|
|
|
|
var ret = await _dutyTimeRepository.AddAsync(inserted);
|
|
|
|
return Success(ret);
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// LV1_002 - แก้ไขรอบการปฏิบัติงาน (ADMIN)
|
|
/// </summary>
|
|
/// <returns>
|
|
/// </returns>
|
|
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
|
|
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
|
|
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
|
|
[HttpPut("duty-time/{id:guid}")]
|
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
|
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
|
public async Task<ActionResult<ResponseObject>> PutAsync(Guid id, [FromBody] UpdateDutyTimeDto data)
|
|
{
|
|
var oldData = await _dutyTimeRepository.GetByIdAsync(id);
|
|
if (oldData == null)
|
|
{
|
|
throw new Exception(GlobalMessages.DataNotFound);
|
|
}
|
|
else
|
|
{
|
|
var oldDataList = await _dutyTimeRepository.GetAllAsync();
|
|
if (data.IsDefault)
|
|
{
|
|
foreach (var d in oldDataList)
|
|
{
|
|
d.IsDefault = false;
|
|
await _dutyTimeRepository.UpdateAsync(d);
|
|
}
|
|
}
|
|
|
|
oldData.Description = data.Description;
|
|
oldData.IsDefault = data.IsDefault;
|
|
oldData.IsActive = data.IsActive;
|
|
|
|
await _dutyTimeRepository.UpdateAsync(oldData);
|
|
|
|
return Success(oldData);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// LV1_003 - ลบรอบการปฏิบัติงาน (ADMIN)
|
|
/// </summary>
|
|
/// <returns>
|
|
/// </returns>
|
|
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
|
|
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
|
|
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
|
|
[HttpDelete("duty-time/{id:guid}")]
|
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
|
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
|
public async Task<ActionResult<ResponseObject>> DeleteAsync(Guid id)
|
|
{
|
|
var oldData = await _dutyTimeRepository.GetByIdAsync(id);
|
|
if (oldData == null)
|
|
{
|
|
throw new Exception(GlobalMessages.DataNotFound);
|
|
}
|
|
else
|
|
{
|
|
if (oldData.IsActive || oldData.IsDefault)
|
|
{
|
|
throw new Exception("ไม่สามารถลบรอบการปฏิบัติงานที่ยังใช้งานอยู่ได้");
|
|
}
|
|
|
|
await _dutyTimeRepository.DeleteAsync(oldData);
|
|
return Success();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// LV1_012 - ข้อมูลทั้งหมดของรอบการปฏิบัติงานที่ active (ADMIN)
|
|
/// </summary>
|
|
/// <returns>
|
|
/// </returns>
|
|
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
|
|
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
|
|
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
|
|
[HttpGet("round")]
|
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
|
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
|
public async Task<ActionResult<ResponseObject>> GetAllActiveAsync()
|
|
{
|
|
var data = await _dutyTimeRepository.GetAllActiveAsync();
|
|
|
|
return Success(data);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region " Check-In Check-Out ลงเวลา "
|
|
|
|
/// <summary>
|
|
/// LV1_006 - เช็คเวลาต้องลงเวลาเข้าหรือออกงาน (USER)
|
|
/// </summary>
|
|
/// <returns>
|
|
/// </returns>
|
|
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
|
|
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
|
|
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
|
|
[HttpGet("check-time")]
|
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
|
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
|
public async Task<ActionResult<ResponseObject>> CheckTimeAsync()
|
|
{
|
|
var userId = UserId == null ? Guid.Empty : Guid.Parse(UserId);
|
|
var data = await _userTimeStampRepository.GetLastRecord(userId);
|
|
|
|
// TODO : รอดุึงรอบที่ผูกกับ user
|
|
var duty = await _dutyTimeRepository.GetDefaultAsync();
|
|
CheckInResultDto ret;
|
|
|
|
if (data == null)
|
|
{
|
|
ret = new CheckInResultDto
|
|
{
|
|
StartTimeMorning = duty == null ? "00:00" : duty.StartTimeMorning,
|
|
EndTimeMorning = duty == null ? "00:00" : duty.EndTimeMorning,
|
|
StartTimeAfternoon = duty == null ? "00:00" : duty.StartTimeAfternoon,
|
|
EndTimeAfternoon = duty == null ? "00:00" : duty.EndTimeAfternoon,
|
|
Description = duty == null ? "-" : duty.Description,
|
|
CheckInTime = null,
|
|
CheckInId = null,
|
|
};
|
|
}
|
|
else
|
|
{
|
|
ret = new CheckInResultDto
|
|
{
|
|
StartTimeMorning = duty == null ? "00:00" : duty.StartTimeMorning,
|
|
EndTimeMorning = duty == null ? "00:00" : duty.EndTimeMorning,
|
|
StartTimeAfternoon = duty == null ? "00:00" : duty.StartTimeAfternoon,
|
|
EndTimeAfternoon = duty == null ? "00:00" : duty.EndTimeAfternoon,
|
|
Description = duty == null ? "-" : duty.Description,
|
|
CheckInTime = data.CheckIn,
|
|
CheckInId = data.CheckOut == null ? data.Id : null,
|
|
};
|
|
}
|
|
|
|
return Success(ret);
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// LV1_005 - ลงเวลาเข้า-ออกงาน (USER)
|
|
/// </summary>
|
|
/// <returns>
|
|
/// </returns>
|
|
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
|
|
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
|
|
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
|
|
[HttpPost("check-in"), DisableRequestSizeLimit]
|
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
|
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
|
public async Task<ActionResult<ResponseObject>> CheckInAsync([FromForm] CheckTimeDto data)
|
|
{
|
|
if (data.Img == null) throw new Exception(GlobalMessages.NoFileToUpload);
|
|
var currentDate = DateTime.Now;
|
|
|
|
var fileName = $"{_bucketName}/{UserId}/{DateTime.Now.ToString("dd-MM-yyyy")}/{data.Img.FileName}";
|
|
using (var ms = new MemoryStream())
|
|
{
|
|
data.Img.CopyTo(ms);
|
|
await _minIOService.UploadFileAsync(fileName, ms);
|
|
}
|
|
|
|
var currentCheckInProcess = await _processUserTimeStampRepository.GetTimestampByDateAsync(Guid.Parse(UserId), currentDate);
|
|
|
|
// create check in object
|
|
if (data.CheckInId == null)
|
|
{
|
|
// validate duplicate check in
|
|
var currentCheckIn = await _userTimeStampRepository.GetTimestampByDateAsync(Guid.Parse(UserId), currentDate);
|
|
|
|
|
|
|
|
if (currentCheckIn != null)
|
|
{
|
|
return Error(new Exception("ไม่สามารถลงเวลาได้ เนืองจากมีการลงเวลาในวันนี้แล้ว!"), (int)StatusCodes.Status400BadRequest);
|
|
}
|
|
|
|
|
|
var checkin = new UserTimeStamp
|
|
{
|
|
KeycloakUserId = UserId != null ? Guid.Parse(UserId) : Guid.Empty,
|
|
CheckInLat = data.Lat,
|
|
CheckInLon = data.Lon,
|
|
IsLocationCheckIn = data.IsLocation,
|
|
CheckInLocationName = data.LocationName,
|
|
CheckInPOI = data.POI,
|
|
CheckInRemark = data.Remark,
|
|
CheckInImageUrl = fileName,
|
|
CheckIn = currentDate
|
|
};
|
|
|
|
// process - รอทำใน queue
|
|
var checkin_process = new ProcessUserTimeStamp
|
|
{
|
|
KeycloakUserId = UserId != null ? Guid.Parse(UserId) : Guid.Empty,
|
|
CheckInLat = data.Lat,
|
|
CheckInLon = data.Lon,
|
|
IsLocationCheckIn = data.IsLocation,
|
|
CheckInLocationName = data.LocationName,
|
|
CheckInPOI = data.POI,
|
|
CheckInRemark = data.Remark,
|
|
CheckInImageUrl = fileName,
|
|
CheckIn = currentDate
|
|
};
|
|
|
|
await _userTimeStampRepository.AddAsync(checkin);
|
|
await _processUserTimeStampRepository.AddAsync(checkin_process);
|
|
}
|
|
else
|
|
{
|
|
var checkout = await _userTimeStampRepository.GetByIdAsync(data.CheckInId.Value);
|
|
var checkout_process = await _processUserTimeStampRepository.GetByIdAsync(currentCheckInProcess.Id);
|
|
|
|
|
|
if (checkout != null)
|
|
{
|
|
checkout.CheckOutLat = data.Lat;
|
|
checkout.CheckOutLon = data.Lon;
|
|
checkout.IsLocationCheckOut = data.IsLocation;
|
|
checkout.CheckOutLocationName = data.LocationName;
|
|
checkout.CheckOutPOI = data.POI;
|
|
checkout.CheckOutRemark = data.Remark;
|
|
checkout.CheckOutImageUrl = fileName;
|
|
checkout.CheckOut = currentDate;
|
|
|
|
await _userTimeStampRepository.UpdateAsync(checkout);
|
|
}
|
|
else
|
|
{
|
|
return Error(new Exception(GlobalMessages.DataNotFound), (int)StatusCodes.Status404NotFound);
|
|
}
|
|
|
|
if (checkout_process != null)
|
|
{
|
|
checkout_process.CheckOutLat = data.Lat;
|
|
checkout_process.CheckOutLon = data.Lon;
|
|
checkout_process.IsLocationCheckOut = data.IsLocation;
|
|
checkout_process.CheckOutLocationName = data.LocationName;
|
|
checkout_process.CheckOutPOI = data.POI;
|
|
checkout_process.CheckOutRemark = data.Remark;
|
|
checkout_process.CheckOutImageUrl = fileName;
|
|
checkout_process.CheckOut = currentDate;
|
|
|
|
await _processUserTimeStampRepository.UpdateAsync(checkout_process);
|
|
}
|
|
else
|
|
{
|
|
return Error(new Exception(GlobalMessages.DataNotFound), (int)StatusCodes.Status404NotFound);
|
|
}
|
|
|
|
}
|
|
|
|
return Success(new { date = currentDate });
|
|
}
|
|
|
|
/// <summary>
|
|
/// LV1_007 - ประวัติการลงเวลา (USER)
|
|
/// </summary>
|
|
/// <returns>
|
|
/// </returns>
|
|
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
|
|
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
|
|
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
|
|
[HttpGet("check-in/history")]
|
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
|
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
|
public async Task<ActionResult<ResponseObject>> CheckInHistoryAsync(int year, int page = 1, int pageSize = 10, string keyword = "")
|
|
{
|
|
var userId = UserId == null ? Guid.Empty : Guid.Parse(UserId);
|
|
|
|
// TODO : รอดุึงรอบที่ผูกกับ user
|
|
var duty = await _dutyTimeRepository.GetDefaultAsync();
|
|
|
|
if (duty == null)
|
|
{
|
|
return Error(new Exception(GlobalMessages.DataNotFound), (int)StatusCodes.Status404NotFound);
|
|
}
|
|
|
|
var checkin_base = DateTime.Parse($"{DateTime.Now.ToString("yyyy-MM-dd")} {duty.StartTimeMorning}");
|
|
var checkout_base = DateTime.Parse($"{DateTime.Now.ToString("yyyy-MM-dd")} {duty.EndTimeAfternoon}");
|
|
|
|
var data = (await _userTimeStampRepository.GetTimeStampHistoryAsync(userId, year, page, pageSize, keyword))
|
|
.Select(d => new CheckInHistoryDto
|
|
{
|
|
CheckInId = d.Id,
|
|
|
|
CheckInDate = d.CheckIn.Date,
|
|
CheckInTime = d.CheckIn.ToString("HH:mm:ss"),
|
|
CheckInLocation = d.CheckInPOI,
|
|
CheckInStatus = DateTime.Parse(d.CheckIn.ToString("yyyy-MM-dd HH:mm")) >
|
|
DateTime.Parse($"{d.CheckIn.Date.ToString("yyyy-MM-dd")} {duty.StartTimeMorning}") ?
|
|
"LATE" :
|
|
"NORMAL",
|
|
CheckOutDate = d.CheckOut == null ? null : d.CheckOut.Value.Date,
|
|
CheckOutTime = d.CheckOut == null ? "" : d.CheckOut.Value.ToString("HH:mm:ss"),
|
|
CheckOutLocation = d.CheckOutPOI ?? "",
|
|
CheckOutStatus = d.CheckOut == null ? null : DateTime.Parse(d.CheckOut.Value.ToString("yyyy-MM-dd HH:mm")) <
|
|
DateTime.Parse($"{d.CheckIn.Date.ToString("yyyy-MM-dd")} {duty.EndTimeAfternoon}") ?
|
|
"LATE" :
|
|
"NORMAL",
|
|
|
|
})
|
|
.ToList();
|
|
|
|
return Success(data);
|
|
}
|
|
|
|
/// <summary>
|
|
/// LV1_010 - รายการลงเวลาปฏิบัติงาน (ADMIN)
|
|
/// </summary>
|
|
/// <returns>
|
|
/// </returns>
|
|
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
|
|
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
|
|
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
|
|
[HttpGet("log-record")]
|
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
|
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
|
public async Task<ActionResult<ResponseObject>> LogRecordAsync([Required] DateTime startDate, [Required] DateTime endDate, int page = 1, int pageSize = 10, string keyword = "")
|
|
{
|
|
if (startDate.Date > endDate.Date)
|
|
{
|
|
return Error(new Exception("วันเริ่มต้นต้องมีค่าน้อยกว่าหรือเท่ากับวันสิ้นสุด"), (int)StatusCodes.Status400BadRequest);
|
|
}
|
|
|
|
var count = await _userTimeStampRepository.CountRecordAsync();
|
|
|
|
|
|
var imgUrl = $"{_configuration["MinIO:Endpoint"]}{_configuration["MinIO:BucketName"]}";
|
|
var data = (await _userTimeStampRepository.GetTimeStampHistoryForAdminAsync(startDate, endDate, page, pageSize, keyword))
|
|
.Select(d => new CheckInHistoryForAdminDto
|
|
{
|
|
Id = d.Id,
|
|
FullName = _userProfileRepository.GetUserFullName(d.KeycloakUserId),
|
|
|
|
CheckInDate = d.CheckIn.Date,
|
|
CheckInTime = d.CheckIn.ToString("HH:mm:ss"),
|
|
CheckInLocation = d.CheckInPOI,
|
|
CheckInLat = d.CheckInLat,
|
|
CheckInLon = d.CheckInLon,
|
|
//CheckInImageUrl = $"{imgUrl}/{d.CheckInImageUrl}",
|
|
|
|
CheckOutDate = d.CheckOut == null ? null : d.CheckOut.Value.Date,
|
|
CheckOutTime = d.CheckOut == null ? "" : d.CheckOut.Value.ToString("HH:mm:ss"),
|
|
CheckOutLocation = d.CheckOut == null ? "" : d.CheckOutPOI,
|
|
CheckOutLat = d.CheckOut == null ? null : d.CheckOutLat,
|
|
CheckOutLon = d.CheckOut == null ? null : d.CheckOutLon,
|
|
//CheckOutImageUrl = d.CheckOut == null ? "" : $"{imgUrl}/{d.CheckOutImageUrl}",
|
|
})
|
|
.ToList();
|
|
|
|
|
|
return Success(new { data = data, total = count });
|
|
}
|
|
|
|
/// <summary>
|
|
/// LV1_011 - รายละเอียดการลงเวลาปฎิบัติงานรายบุคคล
|
|
/// </summary>
|
|
/// <returns>
|
|
/// </returns>
|
|
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
|
|
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
|
|
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
|
|
[HttpGet("time-record/{id:guid}")]
|
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
|
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
|
public async Task<ActionResult<ResponseObject>> GetTimeRecordAsync([Required] Guid id)
|
|
{
|
|
var imgUrl = $"{_configuration["MinIO:Endpoint"]}{_configuration["MinIO:BucketName"]}";
|
|
var d = (await _userTimeStampRepository.GetTimeStampById(id));
|
|
if (d == null)
|
|
{
|
|
throw new Exception(GlobalMessages.DataNotFound);
|
|
}
|
|
else
|
|
{
|
|
var result = new CheckInDetailForAdminDto
|
|
{
|
|
Id = d.Id,
|
|
FullName = _userProfileRepository.GetUserFullName(d.KeycloakUserId),
|
|
|
|
CheckInDate = d.CheckIn.Date,
|
|
CheckInTime = d.CheckIn.ToString("HH:mm:ss"),
|
|
CheckInLocation = d.CheckInPOI,
|
|
CheckInLat = d.CheckInLat,
|
|
CheckInLon = d.CheckInLon,
|
|
CheckInImg = $"{imgUrl}/{d.CheckInImageUrl}",
|
|
|
|
CheckOutDate = d.CheckOut == null ? null : d.CheckOut.Value.Date,
|
|
CheckOutTime = d.CheckOut == null ? "" : d.CheckOut.Value.ToString("HH:mm:ss"),
|
|
CheckOutLocation = d.CheckOut == null ? "" : d.CheckOutPOI,
|
|
CheckOutLat = d.CheckOut == null ? null : d.CheckOutLat,
|
|
CheckOutLon = d.CheckOut == null ? null : d.CheckOutLon,
|
|
CheckOutImg = d.CheckOut == null ? "" : $"{imgUrl}/{d.CheckOutImageUrl}",
|
|
};
|
|
|
|
return Success(result);
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// LV1_009 - รายการลงเวลาปฏิบัติงานที่ประมวลผลแล้ว (ADMIN)
|
|
/// </summary>
|
|
/// <returns>
|
|
/// </returns>
|
|
/// <response code="200">เมื่อทำรายการสำเร็จ</response>
|
|
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
|
|
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
|
|
[HttpGet("time-record")]
|
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
|
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
|
public async Task<ActionResult<ResponseObject>> GetTimeRecordAsync([Required] DateTime startDate, [Required] DateTime endDate, int page = 1, int pageSize = 10,string status = "NORMAL", string keyword = "")
|
|
{
|
|
if (startDate.Date > endDate.Date)
|
|
{
|
|
return Error(new Exception("วันเริ่มต้นต้องมีค่าน้อยกว่าหรือเท่ากับวันสิ้นสุด"), (int)StatusCodes.Status400BadRequest);
|
|
}
|
|
|
|
var userId = UserId == null ? Guid.Empty : Guid.Parse(UserId);
|
|
|
|
// TODO : รอดุึงรอบที่ผูกกับ user
|
|
var duty = await _dutyTimeRepository.GetDefaultAsync();
|
|
|
|
if (duty == null)
|
|
{
|
|
return Error(new Exception(GlobalMessages.DataNotFound), (int)StatusCodes.Status404NotFound);
|
|
}
|
|
|
|
var checkin_base = DateTime.Parse($"{DateTime.Now.ToString("yyyy-MM-dd")} {duty.StartTimeMorning}");
|
|
var checkout_base = DateTime.Parse($"{DateTime.Now.ToString("yyyy-MM-dd")} {duty.EndTimeAfternoon}");
|
|
|
|
var count = await _processUserTimeStampRepository.CountRecordAsync();
|
|
|
|
var imgUrl = $"{_configuration["MinIO:Endpoint"]}{_configuration["MinIO:BucketName"]}";
|
|
var data = (await _processUserTimeStampRepository.GetTimeStampHistoryForAdminAsync(startDate, endDate, page, pageSize, keyword))
|
|
.Select(d => new CheckInProcessHistoryForAdminDto
|
|
{
|
|
Id = d.Id,
|
|
FullName = _userProfileRepository.GetUserFullName(d.KeycloakUserId),
|
|
|
|
CheckInDate = d.CheckIn.Date,
|
|
CheckInTime = d.CheckIn.ToString("HH:mm:ss"),
|
|
CheckInLocation = d.CheckInPOI,
|
|
CheckInLat = d.CheckInLat,
|
|
CheckInLon = d.CheckInLon,
|
|
CheckInStatus = DateTime.Parse(d.CheckIn.ToString("yyyy-MM-dd HH:mm")) >
|
|
DateTime.Parse($"{d.CheckIn.Date.ToString("yyyy-MM-dd")} {duty.StartTimeMorning}") ?
|
|
"LATE" :
|
|
"NORMAL",
|
|
//CheckInImageUrl = $"{imgUrl}/{d.CheckInImageUrl}",
|
|
|
|
CheckOutDate = d.CheckOut == null ? null : d.CheckOut.Value.Date,
|
|
CheckOutTime = d.CheckOut == null ? "" : d.CheckOut.Value.ToString("HH:mm:ss"),
|
|
CheckOutLocation = d.CheckOut == null ? "" : d.CheckOutPOI,
|
|
CheckOutLat = d.CheckOut == null ? null : d.CheckOutLat,
|
|
CheckOutLon = d.CheckOut == null ? null : d.CheckOutLon,
|
|
CheckOutStatus = d.CheckOut == null ? null : DateTime.Parse(d.CheckOut.Value.ToString("yyyy-MM-dd HH:mm")) <
|
|
DateTime.Parse($"{d.CheckIn.Date.ToString("yyyy-MM-dd")} {duty.EndTimeAfternoon}") ?
|
|
"LATE" :
|
|
"NORMAL",
|
|
//CheckOutImageUrl = d.CheckOut == null ? "" : $"{imgUrl}/{d.CheckOutImageUrl}",
|
|
})
|
|
.Where(x => x.CheckInStatus == status || x.CheckOutStatus == status)
|
|
.ToList();
|
|
|
|
|
|
return Success(new { data = data, total = count });
|
|
}
|
|
|
|
#endregion
|
|
|
|
#endregion
|
|
}
|
|
}
|