Compare commits
17 commits
placement-
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0365fad723 | ||
|
|
20e8dfddd6 | ||
|
|
91c479ef9e | ||
|
|
80fcda61cf | ||
|
|
f02413f2b2 | ||
|
|
1739aa8057 | ||
|
|
bc3bba547f | ||
|
|
4161fcc1cf | ||
|
|
6d0921a76a | ||
|
|
df7bebe0ba | ||
|
|
82a45b6811 | ||
|
|
63d983f831 | ||
|
|
e326e43ae6 | ||
|
|
4dab3c5cd9 | ||
|
|
4bd46d13e5 | ||
|
|
132a59b946 | ||
|
|
740a9984c9 |
28 changed files with 25585 additions and 61 deletions
|
|
@ -149,7 +149,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
||||||
var prevRemain = 0.0;
|
var prevRemain = 0.0;
|
||||||
if (prev != null)
|
if (prev != null)
|
||||||
{
|
{
|
||||||
prevRemain = prev.LeaveDays - prev.LeaveDaysUsed;
|
prevRemain = prev.LeaveDays - (prev.LeaveDaysUsed ?? 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (govAge >= 180)
|
if (govAge >= 180)
|
||||||
|
|
@ -215,7 +215,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
||||||
var prevRemain = 0.0;
|
var prevRemain = 0.0;
|
||||||
if (prev != null)
|
if (prev != null)
|
||||||
{
|
{
|
||||||
prevRemain = prev.LeaveDays - prev.LeaveDaysUsed;
|
prevRemain = prev.LeaveDays - (prev.LeaveDaysUsed ?? 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (govAge >= 180)
|
if (govAge >= 180)
|
||||||
|
|
@ -288,7 +288,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
||||||
var prevRemain = 0.0;
|
var prevRemain = 0.0;
|
||||||
if (prev != null)
|
if (prev != null)
|
||||||
{
|
{
|
||||||
prevRemain = prev.LeaveDays - prev.LeaveDaysUsed;
|
prevRemain = prev.LeaveDays - (prev.LeaveDaysUsed ?? 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (govAge >= 180)
|
if (govAge >= 180)
|
||||||
|
|
@ -376,7 +376,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
||||||
var prevRemain = 0.0;
|
var prevRemain = 0.0;
|
||||||
if (prev != null)
|
if (prev != null)
|
||||||
{
|
{
|
||||||
prevRemain = prev.LeaveDays - prev.LeaveDaysUsed;
|
prevRemain = prev.LeaveDays - (prev.LeaveDaysUsed ?? 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (govAge >= 180)
|
if (govAge >= 180)
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,8 @@ using Microsoft.Extensions.Configuration;
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
using System.Net.Http.Json;
|
using System.Net.Http.Json;
|
||||||
|
using BMA.EHR.Application.Repositories.Leaves.TimeAttendants;
|
||||||
|
using BMA.EHR.Domain.Models.Leave.TimeAttendants;
|
||||||
|
|
||||||
namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
||||||
{
|
{
|
||||||
|
|
@ -29,6 +31,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
||||||
private readonly MinIOLeaveService _minIOService;
|
private readonly MinIOLeaveService _minIOService;
|
||||||
|
|
||||||
private readonly LeaveBeginningRepository _leaveBeginningRepository;
|
private readonly LeaveBeginningRepository _leaveBeginningRepository;
|
||||||
|
private readonly ProcessUserTimeStampRepository _processUserTimeStampRepository;
|
||||||
|
|
||||||
private readonly string URL = string.Empty;
|
private readonly string URL = string.Empty;
|
||||||
|
|
||||||
|
|
@ -44,7 +47,8 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
||||||
EmailSenderService emailSenderService,
|
EmailSenderService emailSenderService,
|
||||||
IApplicationDBContext appDbContext,
|
IApplicationDBContext appDbContext,
|
||||||
MinIOLeaveService minIOService,
|
MinIOLeaveService minIOService,
|
||||||
LeaveBeginningRepository leaveBeginningRepository) : base(dbContext, httpContextAccessor)
|
LeaveBeginningRepository leaveBeginningRepository,
|
||||||
|
ProcessUserTimeStampRepository processUserTimeStampRepository) : base(dbContext, httpContextAccessor)
|
||||||
{
|
{
|
||||||
_dbContext = dbContext;
|
_dbContext = dbContext;
|
||||||
_httpContextAccessor = httpContextAccessor;
|
_httpContextAccessor = httpContextAccessor;
|
||||||
|
|
@ -58,6 +62,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
||||||
Console.WriteLine($"URL : {URL}");
|
Console.WriteLine($"URL : {URL}");
|
||||||
_minIOService = minIOService;
|
_minIOService = minIOService;
|
||||||
_leaveBeginningRepository = leaveBeginningRepository;
|
_leaveBeginningRepository = leaveBeginningRepository;
|
||||||
|
_processUserTimeStampRepository = processUserTimeStampRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
@ -522,7 +527,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
||||||
//.Where(x => x.LeaveStatus != "REJECT" && x.LeaveStatus != "DELETE")
|
//.Where(x => x.LeaveStatus != "REJECT" && x.LeaveStatus != "DELETE")
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
return data.Sum(x => x.LeaveTotal) + (beginningLeave == null ? 0 : beginningLeave.LeaveDaysUsed);
|
return data.Sum(x => x.LeaveTotal) + (beginningLeave == null ? 0 : (beginningLeave.LeaveDaysUsed ?? 0.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
//public async Task<double> GetSumApproveLeaveByTypeForUserAsync(Guid keycloakUserId, Guid leaveTypeId, int year)
|
//public async Task<double> GetSumApproveLeaveByTypeForUserAsync(Guid keycloakUserId, Guid leaveTypeId, int year)
|
||||||
|
|
@ -1325,9 +1330,68 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
||||||
}
|
}
|
||||||
await _appDbContext.SaveChangesAsync();
|
await _appDbContext.SaveChangesAsync();
|
||||||
|
|
||||||
// insert to process timestamp
|
// ปรับสถานะการลงเวลา
|
||||||
|
if (rawData.LeaveStartDate.Date == rawData.LeaveEndDate.Date)
|
||||||
|
{
|
||||||
|
var processCheckIn = await _dbContext.Set<ProcessUserTimeStamp>()
|
||||||
|
.Where(x => x.KeycloakUserId == rawData.KeycloakUserId)
|
||||||
|
.Where(x => x.CheckIn.Date == rawData.LeaveStartDate.Date)
|
||||||
|
.FirstOrDefaultAsync();
|
||||||
|
|
||||||
|
|
||||||
|
if (processCheckIn is not null)
|
||||||
|
{
|
||||||
|
switch (rawData.LeaveRange.Trim().ToUpper())
|
||||||
|
{
|
||||||
|
case "MORNING":
|
||||||
|
processCheckIn.CheckInStatus = "NORMAL";
|
||||||
|
break;
|
||||||
|
case "AFTERNOON":
|
||||||
|
processCheckIn.CheckOutStatus = "NORMAL";
|
||||||
|
break;
|
||||||
|
case "ALL":
|
||||||
|
processCheckIn.CheckInStatus = "NORMAL";
|
||||||
|
processCheckIn.CheckOutStatus = "NORMAL";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await _dbContext.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var from = rawData.LeaveStartDate.Date;
|
||||||
|
var to = rawData.LeaveEndDate.Date;
|
||||||
|
for (var day = from.Date; day <= to.Date; day = day.AddDays(1))
|
||||||
|
{
|
||||||
|
var processCheckIn = await _dbContext.Set<ProcessUserTimeStamp>()
|
||||||
|
.Where(x => x.KeycloakUserId == rawData.KeycloakUserId)
|
||||||
|
.Where(x => x.CheckIn.Date == day.Date)
|
||||||
|
.FirstOrDefaultAsync();
|
||||||
|
|
||||||
|
if (processCheckIn is not null)
|
||||||
|
{
|
||||||
|
switch (rawData.LeaveRange.Trim().ToUpper())
|
||||||
|
{
|
||||||
|
case "MORNING":
|
||||||
|
processCheckIn.CheckInStatus = "NORMAL";
|
||||||
|
break;
|
||||||
|
case "AFTERNOON":
|
||||||
|
processCheckIn.CheckOutStatus = "NORMAL";
|
||||||
|
break;
|
||||||
|
case "ALL":
|
||||||
|
processCheckIn.CheckInStatus = "NORMAL";
|
||||||
|
processCheckIn.CheckOutStatus = "NORMAL";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await _dbContext.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
// Send Noti
|
// Send Noti
|
||||||
var noti = new Notification
|
var noti = new Notification
|
||||||
{
|
{
|
||||||
|
|
@ -1486,7 +1550,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
||||||
KeycloakUserId = pf.Keycloak == null ? Guid.Empty : pf.Keycloak.Value,
|
KeycloakUserId = pf.Keycloak == null ? Guid.Empty : pf.Keycloak.Value,
|
||||||
LeaveTypeId = b.LeaveTypeId,
|
LeaveTypeId = b.LeaveTypeId,
|
||||||
LeaveTypeCode = b.LeaveType!.Code,
|
LeaveTypeCode = b.LeaveType!.Code,
|
||||||
SumLeaveDay = b.LeaveDaysUsed
|
SumLeaveDay = b.LeaveDaysUsed ?? 0.0
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1877,7 +1941,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
||||||
.Include(x => x.Type)
|
.Include(x => x.Type)
|
||||||
.Where(x => x.KeycloakUserId == keycloakUserId)
|
.Where(x => x.KeycloakUserId == keycloakUserId)
|
||||||
.Where(x => x.Type.Id == leaveTypeId)
|
.Where(x => x.Type.Id == leaveTypeId)
|
||||||
.Where(x => ((x.DateSendLeave ?? x.CreatedAt).Date >= startDate && (x.DateSendLeave ??x.CreatedAt).Date < endDate))
|
.Where(x => ((x.DateSendLeave ?? x.CreatedAt) >= startDate && (x.DateSendLeave ??x.CreatedAt) <= endDate))
|
||||||
//.Where(x => x.LeaveStartDate.Date >= startDate.Date && x.LeaveStartDate.Date <= endDate.Date)
|
//.Where(x => x.LeaveStartDate.Date >= startDate.Date && x.LeaveStartDate.Date <= endDate.Date)
|
||||||
.Where(x => x.LeaveStatus == "APPROVE" || x.LeaveStatus == "DELETING")
|
.Where(x => x.LeaveStatus == "APPROVE" || x.LeaveStatus == "DELETING")
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
@ -1888,6 +1952,51 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<double> GetSumApproveLeaveTotalByTypeAndRangeForUserByProfile(Guid profileId, Guid leaveTypeId, DateTime startDate, DateTime endDate)
|
||||||
|
{
|
||||||
|
var data = await _dbContext.Set<LeaveRequest>().AsQueryable().AsNoTracking()
|
||||||
|
.Include(x => x.Type)
|
||||||
|
.Where(x => x.ProfileId == profileId)
|
||||||
|
.Where(x => x.Type.Id == leaveTypeId)
|
||||||
|
.Where(x => ((x.DateSendLeave ?? x.CreatedAt) >= startDate && (x.DateSendLeave ??x.CreatedAt) <= endDate))
|
||||||
|
//.Where(x => x.LeaveStartDate.Date >= startDate.Date && x.LeaveStartDate.Date <= endDate.Date)
|
||||||
|
.Where(x => x.LeaveStatus == "APPROVE" || x.LeaveStatus == "DELETING")
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
if (data.Count > 0)
|
||||||
|
return data.Sum(x => x.LeaveTotal);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> GetSumApproveLeaveCountByTypeAndRangeForUserByProfile(Guid profileId, Guid leaveTypeId, DateTime startDate, DateTime endDate)
|
||||||
|
{
|
||||||
|
var data = await _dbContext.Set<LeaveRequest>().AsQueryable().AsNoTracking()
|
||||||
|
.Include(x => x.Type)
|
||||||
|
.Where(x => x.ProfileId == profileId)
|
||||||
|
.Where(x => x.Type.Id == leaveTypeId)
|
||||||
|
.Where(x => ((x.DateSendLeave ?? x.CreatedAt) >= startDate && (x.DateSendLeave ??x.CreatedAt) <= endDate))
|
||||||
|
//.Where(x => x.LeaveStartDate.Date >= startDate.Date && x.LeaveStartDate.Date <= endDate.Date)
|
||||||
|
.Where(x => x.LeaveStatus == "APPROVE" || x.LeaveStatus == "DELETING")
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
return data.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> GetSumApproveLeaveCountByTypeAndRangeForUser2(Guid keycloakUserId, Guid leaveTypeId, DateTime startDate, DateTime endDate)
|
||||||
|
{
|
||||||
|
var data = await _dbContext.Set<LeaveRequest>().AsQueryable().AsNoTracking()
|
||||||
|
.Include(x => x.Type)
|
||||||
|
.Where(x => x.KeycloakUserId == keycloakUserId)
|
||||||
|
.Where(x => x.Type.Id == leaveTypeId)
|
||||||
|
.Where(x => ((x.DateSendLeave ?? x.CreatedAt) >= startDate && (x.DateSendLeave ??x.CreatedAt) <= endDate))
|
||||||
|
//.Where(x => x.LeaveStartDate.Date >= startDate.Date && x.LeaveStartDate.Date <= endDate.Date)
|
||||||
|
.Where(x => x.LeaveStatus == "APPROVE" || x.LeaveStatus == "DELETING")
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
return data.Count;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// วันลาที่สร้างแบบร่างยังไม่ได้ยื่น
|
/// วันลาที่สร้างแบบร่างยังไม่ได้ยื่น
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -1928,9 +2037,9 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
||||||
.Include(x => x.Type)
|
.Include(x => x.Type)
|
||||||
.Where(x => x.KeycloakUserId == keycloakUserId)
|
.Where(x => x.KeycloakUserId == keycloakUserId)
|
||||||
.Where(x => x.Type.Id == leaveTypeId)
|
.Where(x => x.Type.Id == leaveTypeId)
|
||||||
.Where(x => ((x.DateSendLeave ?? x.CreatedAt).Date >= startDate && (x.DateSendLeave ??x.CreatedAt).Date < endDate))
|
.Where(x => ((x.DateSendLeave ?? x.CreatedAt) >= startDate && (x.DateSendLeave ??x.CreatedAt) < endDate))
|
||||||
//.Where(x => x.LeaveStartDate.Date >= startDate.Date && x.LeaveStartDate.Date <= endDate.Date)
|
//.Where(x => x.LeaveStartDate.Date >= startDate.Date && x.LeaveStartDate.Date <= endDate.Date)
|
||||||
.Where(x => x.LeaveStatus == "NEW")
|
.Where(x => (x.LeaveStatus == "NEW" || x.LeaveStatus == "PENDING"))
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
if (data.Count > 0)
|
if (data.Count > 0)
|
||||||
|
|
|
||||||
|
|
@ -213,6 +213,79 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<List<AdditionalCheckRequest>> GetAdditionalCheckRequestsByAdminRole2(DateTime startDate, DateTime endDate, string role, string nodeId, int? node, string? keyword, string? status)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var data = await _dbContext.Set<AdditionalCheckRequest>().AsQueryable()
|
||||||
|
.Where(x => (x.CheckDate.Date >= startDate.Date && x.CheckDate.Date <= endDate.Date))
|
||||||
|
.OrderByDescending(x => x.CreatedAt.Date)
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
if(!string.IsNullOrEmpty(status))
|
||||||
|
data = data.Where(x => x.Status == status).ToList();
|
||||||
|
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(keyword))
|
||||||
|
{
|
||||||
|
data = data.Where(x =>
|
||||||
|
(
|
||||||
|
(x.Prefix ?? "") + (x.FirstName ?? "") + " " + (x.LastName ?? "")).Contains(keyword)
|
||||||
|
|| x.Description.Contains(keyword)
|
||||||
|
|
||||||
|
).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (role == "OWNER")
|
||||||
|
{
|
||||||
|
node = null;
|
||||||
|
}
|
||||||
|
if (role == "OWNER" || role == "CHILD")
|
||||||
|
{
|
||||||
|
data = data
|
||||||
|
.Where(x => node == 4 ? x.Child4DnaId == Guid.Parse(nodeId!) : (node == 3 ? x.Child3DnaId == Guid.Parse(nodeId!) : (node == 2 ? x.Child2DnaId == Guid.Parse(nodeId!) : (node == 1 ? x.Child1DnaId == Guid.Parse(nodeId!) : (node == 0 ? x.RootDnaId == Guid.Parse(nodeId!) : (node == null ? true : true))))))
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
else if (role == "BROTHER")
|
||||||
|
{
|
||||||
|
data = data
|
||||||
|
.Where(x => node == 4 ? x.Child3DnaId == Guid.Parse(nodeId!) : (node == 3 ? x.Child2DnaId == Guid.Parse(nodeId!) : (node == 2 ? x.Child1DnaId == Guid.Parse(nodeId!) : (node == 1 || node == 0 ? x.RootDnaId == Guid.Parse(nodeId!) : (node == null ? true : true)))))
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
else if (role == "ROOT")
|
||||||
|
{
|
||||||
|
data = data
|
||||||
|
.Where(x => x.RootDnaId == Guid.Parse(nodeId!)).ToList();
|
||||||
|
}
|
||||||
|
// else if (role == "PARENT")
|
||||||
|
// {
|
||||||
|
// data = data
|
||||||
|
// .Where(x => x.RootDnaId == Guid.Parse(nodeId!) && x.Child1DnaId != null && x.Child1DnaId != Guid.Empty).ToList();
|
||||||
|
// }
|
||||||
|
else if (role == "NORMAL")
|
||||||
|
{
|
||||||
|
data = data.Where(x =>
|
||||||
|
node == 0 ? x.RootDnaId == Guid.Parse(nodeId!) &&
|
||||||
|
(x.Child1DnaId == Guid.Empty || x.Child1DnaId == null) :
|
||||||
|
node == 1 ? x.Child1DnaId == Guid.Parse(nodeId!) &&
|
||||||
|
(x.Child2DnaId == Guid.Empty || x.Child2DnaId == null) :
|
||||||
|
node == 2 ? x.Child2DnaId == Guid.Parse(nodeId!) &&
|
||||||
|
(x.Child3DnaId == Guid.Empty || x.Child3DnaId == null) :
|
||||||
|
node == 3 ? x.Child3DnaId == Guid.Parse(nodeId!) &&
|
||||||
|
(x.Child4DnaId == Guid.Empty || x.Child4DnaId == null) :
|
||||||
|
node == 4 ? x.Child4DnaId == Guid.Parse(nodeId!) :
|
||||||
|
true
|
||||||
|
).ToList();
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,12 +49,16 @@ namespace BMA.EHR.Application.Repositories.MetaData
|
||||||
|
|
||||||
public async Task<int> GetHolidayCountAsync(DateTime startDate, DateTime endDate, string category = "NORMAL")
|
public async Task<int> GetHolidayCountAsync(DateTime startDate, DateTime endDate, string category = "NORMAL")
|
||||||
{
|
{
|
||||||
var data = await _dbContext.Set<Holiday>().AsQueryable()
|
var query = _dbContext.Set<Holiday>().AsQueryable()
|
||||||
.Where(x => x.Category == category)
|
.Where(x => x.Category == category)
|
||||||
.Where(x => x.HolidayDate.Date >= startDate && x.HolidayDate.Date <= endDate)
|
.Where(x => x.HolidayDate.Date >= startDate && x.HolidayDate.Date <= endDate);
|
||||||
.CountAsync();
|
|
||||||
|
|
||||||
return data;
|
if (category == "NORMAL")
|
||||||
|
query = query.Where(x => x.HolidayDate.DayOfWeek != DayOfWeek.Saturday && x.HolidayDate.DayOfWeek != DayOfWeek.Sunday);
|
||||||
|
else
|
||||||
|
query = query.Where(x => x.HolidayDate.DayOfWeek != DayOfWeek.Sunday);
|
||||||
|
|
||||||
|
return await query.CountAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<DateTime> GetWeekEnd(DateTime startDate, DateTime endDate, string category = "NORMAL")
|
public List<DateTime> GetWeekEnd(DateTime startDate, DateTime endDate, string category = "NORMAL")
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,9 @@ namespace BMA.EHR.Domain.Common
|
||||||
protected string? Prefix => User.GetPrefix();
|
protected string? Prefix => User.GetPrefix();
|
||||||
protected string? FullNameFromClaim => User.GetName();
|
protected string? FullNameFromClaim => User.GetName();
|
||||||
|
|
||||||
|
protected string? FirstName => User.GetFirstName();
|
||||||
|
protected string? LastName => User.GetLastName();
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
|
||||||
|
|
@ -26,5 +26,7 @@ namespace BMA.EHR.Domain.Extensions
|
||||||
public static Guid? GetProfileId(this ClaimsPrincipal user) => user.GetGuidClaim(BmaClaimTypes.ProfileId);
|
public static Guid? GetProfileId(this ClaimsPrincipal user) => user.GetGuidClaim(BmaClaimTypes.ProfileId);
|
||||||
public static string? GetPrefix(this ClaimsPrincipal user) => user.GetClaimValue(BmaClaimTypes.Prefix);
|
public static string? GetPrefix(this ClaimsPrincipal user) => user.GetClaimValue(BmaClaimTypes.Prefix);
|
||||||
public static string? GetName(this ClaimsPrincipal user) => user.GetClaimValue(BmaClaimTypes.Name);
|
public static string? GetName(this ClaimsPrincipal user) => user.GetClaimValue(BmaClaimTypes.Name);
|
||||||
|
public static string? GetFirstName(this ClaimsPrincipal user) => user.GetClaimValue(BmaClaimTypes.GivenName);
|
||||||
|
public static string? GetLastName(this ClaimsPrincipal user) => user.GetClaimValue(BmaClaimTypes.FamilyName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,11 +27,11 @@ namespace BMA.EHR.Domain.Models.Leave.Requests
|
||||||
[Required, Comment("จำนวนวันลาทั้งหมด")]
|
[Required, Comment("จำนวนวันลาทั้งหมด")]
|
||||||
public double LeaveDays { get; set; } = 0.0;
|
public double LeaveDays { get; set; } = 0.0;
|
||||||
|
|
||||||
[Required, Comment("จำนวนวันลาที่ใช้ไป")]
|
[Comment("จำนวนวันลาที่ใช้ไป")]
|
||||||
public double LeaveDaysUsed { get; set; } = 0.0;
|
public double? LeaveDaysUsed { get; set; } = 0.0;
|
||||||
|
|
||||||
[Comment("จำนวนครั้งที่ลาสะสม")]
|
[Comment("จำนวนครั้งที่ลาสะสม")]
|
||||||
public int LeaveCount { get; set; } = 0;
|
public int? LeaveCount { get; set; } = 0;
|
||||||
|
|
||||||
public Guid? RootDnaId { get; set; }
|
public Guid? RootDnaId { get; set; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,5 +38,10 @@ namespace BMA.EHR.Domain.Models.Leave.Requests
|
||||||
public string Comment { get; set; } = string.Empty;
|
public string Comment { get; set; } = string.Empty;
|
||||||
|
|
||||||
public string? ApproveType { get; set; } = string.Empty; // ผู้บังคับบัญชา = commander, ผู้มีอำนาจอนุมัติ = Approver
|
public string? ApproveType { get; set; } = string.Empty; // ผู้บังคับบัญชา = commander, ผู้มีอำนาจอนุมัติ = Approver
|
||||||
|
|
||||||
|
|
||||||
|
public bool IsAct { get; set; } = false;
|
||||||
|
|
||||||
|
public string KeyId { get; set; } = string.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,10 @@ namespace BMA.EHR.Domain.Models.Placement
|
||||||
public string? profileId { get; set; }
|
public string? profileId { get; set; }
|
||||||
[Comment("คำนำหน้า")]
|
[Comment("คำนำหน้า")]
|
||||||
public string? prefix { get; set; }
|
public string? prefix { get; set; }
|
||||||
|
|
||||||
|
[Comment("ยศ")]
|
||||||
|
public string? rank { get; set; }
|
||||||
|
|
||||||
[Comment("ชื่อ")]
|
[Comment("ชื่อ")]
|
||||||
public string? firstName { get; set; }
|
public string? firstName { get; set; }
|
||||||
[Comment("นามสกุล")]
|
[Comment("นามสกุล")]
|
||||||
|
|
|
||||||
21250
BMA.EHR.Infrastructure/Migrations/20260512073417_update_PlacementReceives_add_rank.Designer.cs
generated
Normal file
21250
BMA.EHR.Infrastructure/Migrations/20260512073417_update_PlacementReceives_add_rank.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,30 @@
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace BMA.EHR.Infrastructure.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class update_PlacementReceives_add_rank : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "rank",
|
||||||
|
table: "PlacementReceives",
|
||||||
|
type: "longtext",
|
||||||
|
nullable: true,
|
||||||
|
comment: "ยศ")
|
||||||
|
.Annotation("MySql:CharSet", "utf8mb4");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "rank",
|
||||||
|
table: "PlacementReceives");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -13693,6 +13693,10 @@ namespace BMA.EHR.Infrastructure.Migrations
|
||||||
.HasColumnType("longtext")
|
.HasColumnType("longtext")
|
||||||
.HasComment("profile Id");
|
.HasComment("profile Id");
|
||||||
|
|
||||||
|
b.Property<string>("rank")
|
||||||
|
.HasColumnType("longtext")
|
||||||
|
.HasComment("ยศ");
|
||||||
|
|
||||||
b.Property<string>("root")
|
b.Property<string>("root")
|
||||||
.HasColumnType("longtext")
|
.HasColumnType("longtext")
|
||||||
.HasComment("ชื่อหน่วยงาน root");
|
.HasComment("ชื่อหน่วยงาน root");
|
||||||
|
|
|
||||||
1805
BMA.EHR.Infrastructure/Migrations/LeaveDb/20260505035145_Change Field.Designer.cs
generated
Normal file
1805
BMA.EHR.Infrastructure/Migrations/LeaveDb/20260505035145_Change Field.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,62 @@
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace BMA.EHR.Infrastructure.Migrations.LeaveDb
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class ChangeField : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AlterColumn<double>(
|
||||||
|
name: "LeaveDaysUsed",
|
||||||
|
table: "LeaveBeginnings",
|
||||||
|
type: "double",
|
||||||
|
nullable: true,
|
||||||
|
comment: "จำนวนวันลาที่ใช้ไป",
|
||||||
|
oldClrType: typeof(double),
|
||||||
|
oldType: "double",
|
||||||
|
oldComment: "จำนวนวันลาที่ใช้ไป");
|
||||||
|
|
||||||
|
migrationBuilder.AlterColumn<int>(
|
||||||
|
name: "LeaveCount",
|
||||||
|
table: "LeaveBeginnings",
|
||||||
|
type: "int",
|
||||||
|
nullable: true,
|
||||||
|
comment: "จำนวนครั้งที่ลาสะสม",
|
||||||
|
oldClrType: typeof(int),
|
||||||
|
oldType: "int",
|
||||||
|
oldComment: "จำนวนครั้งที่ลาสะสม");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AlterColumn<double>(
|
||||||
|
name: "LeaveDaysUsed",
|
||||||
|
table: "LeaveBeginnings",
|
||||||
|
type: "double",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: 0.0,
|
||||||
|
comment: "จำนวนวันลาที่ใช้ไป",
|
||||||
|
oldClrType: typeof(double),
|
||||||
|
oldType: "double",
|
||||||
|
oldNullable: true,
|
||||||
|
oldComment: "จำนวนวันลาที่ใช้ไป");
|
||||||
|
|
||||||
|
migrationBuilder.AlterColumn<int>(
|
||||||
|
name: "LeaveCount",
|
||||||
|
table: "LeaveBeginnings",
|
||||||
|
type: "int",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: 0,
|
||||||
|
comment: "จำนวนครั้งที่ลาสะสม",
|
||||||
|
oldClrType: typeof(int),
|
||||||
|
oldType: "int",
|
||||||
|
oldNullable: true,
|
||||||
|
oldComment: "จำนวนครั้งที่ลาสะสม");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
1812
BMA.EHR.Infrastructure/Migrations/LeaveDb/20260511075931_Add Approver Field.Designer.cs
generated
Normal file
1812
BMA.EHR.Infrastructure/Migrations/LeaveDb/20260511075931_Add Approver Field.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,40 @@
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace BMA.EHR.Infrastructure.Migrations.LeaveDb
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class AddApproverField : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<bool>(
|
||||||
|
name: "IsAct",
|
||||||
|
table: "LeaveRequestApprovers",
|
||||||
|
type: "tinyint(1)",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: false);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<string>(
|
||||||
|
name: "KeyId",
|
||||||
|
table: "LeaveRequestApprovers",
|
||||||
|
type: "longtext",
|
||||||
|
nullable: false)
|
||||||
|
.Annotation("MySql:CharSet", "utf8mb4");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "IsAct",
|
||||||
|
table: "LeaveRequestApprovers");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "KeyId",
|
||||||
|
table: "LeaveRequestApprovers");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -192,7 +192,7 @@ namespace BMA.EHR.Infrastructure.Migrations.LeaveDb
|
||||||
.HasColumnOrder(102)
|
.HasColumnOrder(102)
|
||||||
.HasComment("แก้ไขข้อมูลล่าสุดเมื่อ");
|
.HasComment("แก้ไขข้อมูลล่าสุดเมื่อ");
|
||||||
|
|
||||||
b.Property<int>("LeaveCount")
|
b.Property<int?>("LeaveCount")
|
||||||
.HasColumnType("int")
|
.HasColumnType("int")
|
||||||
.HasComment("จำนวนครั้งที่ลาสะสม");
|
.HasComment("จำนวนครั้งที่ลาสะสม");
|
||||||
|
|
||||||
|
|
@ -200,7 +200,7 @@ namespace BMA.EHR.Infrastructure.Migrations.LeaveDb
|
||||||
.HasColumnType("double")
|
.HasColumnType("double")
|
||||||
.HasComment("จำนวนวันลาทั้งหมด");
|
.HasComment("จำนวนวันลาทั้งหมด");
|
||||||
|
|
||||||
b.Property<double>("LeaveDaysUsed")
|
b.Property<double?>("LeaveDaysUsed")
|
||||||
.HasColumnType("double")
|
.HasColumnType("double")
|
||||||
.HasComment("จำนวนวันลาที่ใช้ไป");
|
.HasComment("จำนวนวันลาที่ใช้ไป");
|
||||||
|
|
||||||
|
|
@ -713,6 +713,13 @@ namespace BMA.EHR.Infrastructure.Migrations.LeaveDb
|
||||||
.IsRequired()
|
.IsRequired()
|
||||||
.HasColumnType("longtext");
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<bool>("IsAct")
|
||||||
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
|
b.Property<string>("KeyId")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
b.Property<Guid>("KeycloakId")
|
b.Property<Guid>("KeycloakId")
|
||||||
.HasColumnType("char(36)");
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ namespace BMA.EHR.Leave.Service.Controllers
|
||||||
private readonly IConfiguration _configuration;
|
private readonly IConfiguration _configuration;
|
||||||
private readonly UserProfileRepository _userProfileRepository;
|
private readonly UserProfileRepository _userProfileRepository;
|
||||||
private readonly PermissionRepository _permission;
|
private readonly PermissionRepository _permission;
|
||||||
|
private readonly LeaveRequestRepository _leaveRequestRepository;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
@ -44,7 +45,8 @@ namespace BMA.EHR.Leave.Service.Controllers
|
||||||
IWebHostEnvironment hostingEnvironment,
|
IWebHostEnvironment hostingEnvironment,
|
||||||
IConfiguration configuration,
|
IConfiguration configuration,
|
||||||
UserProfileRepository userProfileRepository,
|
UserProfileRepository userProfileRepository,
|
||||||
PermissionRepository permission)
|
PermissionRepository permission,
|
||||||
|
LeaveRequestRepository leaveRequestRepository)
|
||||||
{
|
{
|
||||||
_leaveBeginningRepository = leaveBeginningRepository;
|
_leaveBeginningRepository = leaveBeginningRepository;
|
||||||
_context = context;
|
_context = context;
|
||||||
|
|
@ -53,6 +55,7 @@ namespace BMA.EHR.Leave.Service.Controllers
|
||||||
_configuration = configuration;
|
_configuration = configuration;
|
||||||
_userProfileRepository = userProfileRepository;
|
_userProfileRepository = userProfileRepository;
|
||||||
_permission = permission;
|
_permission = permission;
|
||||||
|
_leaveRequestRepository = leaveRequestRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
@ -375,6 +378,15 @@ namespace BMA.EHR.Leave.Service.Controllers
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var userId = UserId == null ? Guid.Empty : Guid.Parse(UserId);
|
var userId = UserId == null ? Guid.Empty : Guid.Parse(UserId);
|
||||||
|
// var profileId = ProfileId ?? Guid.Empty;
|
||||||
|
// var prefix = Prefix ?? "";
|
||||||
|
// var firstName = FirstName ?? "";
|
||||||
|
// var lastName = LastName ?? "";
|
||||||
|
// var rootDnaId = OrgRootDnaId ?? Guid.Empty;
|
||||||
|
// var child1DnaId = OrgChild1DnaId ?? Guid.Empty;
|
||||||
|
// var child2DnaId = OrgChild2DnaId ?? Guid.Empty;
|
||||||
|
// var child3DnaId = OrgChild3DnaId ?? Guid.Empty;
|
||||||
|
// var child4DnaId = OrgChild4DnaId ?? Guid.Empty;
|
||||||
|
|
||||||
var getPermission = await _permission.GetPermissionAPIAsync("UPDATE", "SYS_LEAVE_HISTORY");
|
var getPermission = await _permission.GetPermissionAPIAsync("UPDATE", "SYS_LEAVE_HISTORY");
|
||||||
var jsonData = JsonConvert.DeserializeObject<JObject>(getPermission);
|
var jsonData = JsonConvert.DeserializeObject<JObject>(getPermission);
|
||||||
|
|
@ -386,20 +398,41 @@ namespace BMA.EHR.Leave.Service.Controllers
|
||||||
if (leaveBeginning == null)
|
if (leaveBeginning == null)
|
||||||
return Error("ไม่พบข้อมูลที่ต้องการแก้ไข", StatusCodes.Status404NotFound);
|
return Error("ไม่พบข้อมูลที่ต้องการแก้ไข", StatusCodes.Status404NotFound);
|
||||||
|
|
||||||
|
|
||||||
var profile = await _userProfileRepository.GetProfileByProfileIdAsync(req.ProfileId, AccessToken);
|
var profile = await _userProfileRepository.GetProfileByProfileIdAsync(req.ProfileId, AccessToken);
|
||||||
if (profile == null)
|
if (profile == null)
|
||||||
{
|
{
|
||||||
return Error("ไม่พบข้อมูลข้าราชการหรือลูกจ้าง", StatusCodes.Status404NotFound);
|
return Error("ไม่พบข้อมูลข้าราชการหรือลูกจ้าง", StatusCodes.Status404NotFound);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var startFiscalDate = new DateTime(DateTime.Now.Year - 1, 10, 1);
|
||||||
|
var endFiscalDate = new DateTime(DateTime.Now.Year, 9, 30);
|
||||||
|
|
||||||
|
|
||||||
|
if (req.LeaveDaysUsed is null || req.LeaveCount is null)
|
||||||
|
{
|
||||||
|
var systemLeaveDays = await _leaveRequestRepository.GetSumApproveLeaveTotalByTypeAndRangeForUserByProfile(req.ProfileId, req.LeaveTypeId, startFiscalDate, endFiscalDate);
|
||||||
|
var systemLeaveCount = await _leaveRequestRepository.GetSumApproveLeaveCountByTypeAndRangeForUserByProfile(req.ProfileId, req.LeaveTypeId, startFiscalDate, endFiscalDate);
|
||||||
|
|
||||||
|
leaveBeginning.LeaveDaysUsed = req.BeginningLeaveDays + systemLeaveDays;
|
||||||
|
leaveBeginning.LeaveCount = req.BeginningLeaveCount + systemLeaveCount;
|
||||||
|
|
||||||
|
leaveBeginning.BeginningLeaveDays = req.BeginningLeaveDays;
|
||||||
|
leaveBeginning.BeginningLeaveCount = req.BeginningLeaveCount;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
leaveBeginning.LeaveDaysUsed = req.LeaveDaysUsed;
|
||||||
|
leaveBeginning.LeaveCount = req.LeaveCount;
|
||||||
|
leaveBeginning.BeginningLeaveDays = req.BeginningLeaveDays;
|
||||||
|
leaveBeginning.BeginningLeaveCount = req.BeginningLeaveCount;
|
||||||
|
//var systemLeaveDays = await _leaveRequestRepository.GetSumApproveLeaveTotalByTypeAndRangeForUser2(profile.Keycloak ?? Guid.Empty, req.LeaveTypeId, startFiscalDate, endFiscalDate);
|
||||||
|
//var systemLeaveCount = await _leaveRequestRepository.GetSumApproveLeaveCountByTypeAndRangeForUser2(profile.Keycloak ?? Guid.Empty, req.LeaveTypeId, startFiscalDate, endFiscalDate);
|
||||||
|
}
|
||||||
|
|
||||||
leaveBeginning.LeaveTypeId = req.LeaveTypeId;
|
leaveBeginning.LeaveTypeId = req.LeaveTypeId;
|
||||||
leaveBeginning.LeaveYear = req.LeaveYear;
|
leaveBeginning.LeaveYear = req.LeaveYear;
|
||||||
leaveBeginning.LeaveDays = req.LeaveDays;
|
leaveBeginning.LeaveDays = req.LeaveDays;
|
||||||
leaveBeginning.LeaveDaysUsed = req.LeaveDaysUsed;
|
|
||||||
leaveBeginning.LeaveCount = req.LeaveCount;
|
|
||||||
leaveBeginning.BeginningLeaveDays = req.BeginningLeaveDays;
|
|
||||||
leaveBeginning.BeginningLeaveCount = req.BeginningLeaveCount;
|
|
||||||
|
|
||||||
leaveBeginning.ProfileId = req.ProfileId;
|
leaveBeginning.ProfileId = req.ProfileId;
|
||||||
leaveBeginning.Prefix = profile.Prefix;
|
leaveBeginning.Prefix = profile.Prefix;
|
||||||
|
|
@ -440,6 +473,17 @@ namespace BMA.EHR.Leave.Service.Controllers
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var userId = UserId == null ? Guid.Empty : Guid.Parse(UserId);
|
var userId = UserId == null ? Guid.Empty : Guid.Parse(UserId);
|
||||||
|
|
||||||
|
// var profileId = ProfileId ?? Guid.Empty;
|
||||||
|
// var prefix = Prefix ?? "";
|
||||||
|
// var firstName = FirstName ?? "";
|
||||||
|
// var lastName = LastName ?? "";
|
||||||
|
// var rootDnaId = OrgRootDnaId ?? Guid.Empty;
|
||||||
|
// var child1DnaId = OrgChild1DnaId ?? Guid.Empty;
|
||||||
|
// var child2DnaId = OrgChild2DnaId ?? Guid.Empty;
|
||||||
|
// var child3DnaId = OrgChild3DnaId ?? Guid.Empty;
|
||||||
|
// var child4DnaId = OrgChild4DnaId ?? Guid.Empty;
|
||||||
|
|
||||||
var getPermission = await _permission.GetPermissionAPIAsync("CREATE", "SYS_LEAVE_HISTORY");
|
var getPermission = await _permission.GetPermissionAPIAsync("CREATE", "SYS_LEAVE_HISTORY");
|
||||||
var jsonData = JsonConvert.DeserializeObject<JObject>(getPermission);
|
var jsonData = JsonConvert.DeserializeObject<JObject>(getPermission);
|
||||||
if (jsonData["status"]?.ToString() != "200")
|
if (jsonData["status"]?.ToString() != "200")
|
||||||
|
|
@ -464,13 +508,26 @@ namespace BMA.EHR.Leave.Service.Controllers
|
||||||
}
|
}
|
||||||
|
|
||||||
var leaveBeginning = new LeaveBeginning();
|
var leaveBeginning = new LeaveBeginning();
|
||||||
|
|
||||||
|
if (req.LeaveDaysUsed is null || req.LeaveCount is null)
|
||||||
|
{
|
||||||
|
leaveBeginning.LeaveDaysUsed = req.BeginningLeaveDays;
|
||||||
|
leaveBeginning.LeaveCount = req.BeginningLeaveCount;
|
||||||
|
leaveBeginning.BeginningLeaveDays = req.BeginningLeaveDays;
|
||||||
|
leaveBeginning.BeginningLeaveCount = req.BeginningLeaveCount;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
leaveBeginning.LeaveDaysUsed = req.LeaveDaysUsed;
|
||||||
|
leaveBeginning.LeaveCount = req.LeaveCount;
|
||||||
|
leaveBeginning.BeginningLeaveDays = req.BeginningLeaveDays;
|
||||||
|
leaveBeginning.BeginningLeaveCount = req.BeginningLeaveCount;
|
||||||
|
}
|
||||||
|
|
||||||
leaveBeginning.LeaveTypeId = req.LeaveTypeId;
|
leaveBeginning.LeaveTypeId = req.LeaveTypeId;
|
||||||
leaveBeginning.LeaveYear = req.LeaveYear;
|
leaveBeginning.LeaveYear = req.LeaveYear;
|
||||||
leaveBeginning.LeaveDays = req.LeaveDays;
|
leaveBeginning.LeaveDays = req.LeaveDays;
|
||||||
leaveBeginning.LeaveDaysUsed = req.LeaveDaysUsed;
|
|
||||||
leaveBeginning.LeaveCount = req.LeaveCount;
|
|
||||||
leaveBeginning.BeginningLeaveDays = req.BeginningLeaveDays;
|
|
||||||
leaveBeginning.BeginningLeaveCount = req.BeginningLeaveCount;
|
|
||||||
|
|
||||||
leaveBeginning.ProfileId = req.ProfileId;
|
leaveBeginning.ProfileId = req.ProfileId;
|
||||||
leaveBeginning.Prefix = profile.Prefix;
|
leaveBeginning.Prefix = profile.Prefix;
|
||||||
|
|
|
||||||
|
|
@ -446,29 +446,30 @@ namespace BMA.EHR.Leave.Service.Controllers
|
||||||
public async Task<ActionResult<ResponseObject>> CheckTimeAsync(CancellationToken cancellationToken = default)
|
public async Task<ActionResult<ResponseObject>> CheckTimeAsync(CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
var userId = UserId == null ? Guid.Empty : Guid.Parse(UserId);
|
var userId = UserId == null ? Guid.Empty : Guid.Parse(UserId);
|
||||||
|
var profileId = ProfileId ?? Guid.Empty;
|
||||||
|
|
||||||
// Get user's last check-in record and profile in parallel
|
// Get user's last check-in record and profile in parallel
|
||||||
var dataTask = _userTimeStampRepository.GetLastRecord(userId);
|
var dataTask = _userTimeStampRepository.GetLastRecord(userId);
|
||||||
var profileTask = _userProfileRepository.GetProfileByKeycloakIdNew2Async(userId, AccessToken);
|
//var profileTask = _userProfileRepository.GetProfileByKeycloakIdNew2Async(userId, AccessToken);
|
||||||
var defaultRoundTask = _dutyTimeRepository.GetDefaultAsync();
|
var defaultRoundTask = _dutyTimeRepository.GetDefaultAsync();
|
||||||
|
|
||||||
await Task.WhenAll(dataTask, profileTask, defaultRoundTask);
|
await Task.WhenAll(dataTask, defaultRoundTask);
|
||||||
|
|
||||||
var data = await dataTask;
|
var data = await dataTask;
|
||||||
var profile = await profileTask;
|
//var profile = await profileTask;
|
||||||
var getDefaultRound = await defaultRoundTask;
|
var getDefaultRound = await defaultRoundTask;
|
||||||
|
|
||||||
if (profile == null)
|
// if (profile == null)
|
||||||
{
|
// {
|
||||||
throw new Exception(GlobalMessages.DataNotFound);
|
// throw new Exception(GlobalMessages.DataNotFound);
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (getDefaultRound == null)
|
if (getDefaultRound == null)
|
||||||
{
|
{
|
||||||
return Error("ไม่พบรอบลงเวลา Default", StatusCodes.Status404NotFound);
|
return Error("ไม่พบรอบลงเวลา Default", StatusCodes.Status404NotFound);
|
||||||
}
|
}
|
||||||
|
|
||||||
var effectiveDate = await _userDutyTimeRepository.GetLastEffectRound(profile.Id);
|
var effectiveDate = await _userDutyTimeRepository.GetLastEffectRound(profileId);
|
||||||
var roundId = effectiveDate != null ? effectiveDate.DutyTimeId : Guid.Empty;
|
var roundId = effectiveDate != null ? effectiveDate.DutyTimeId : Guid.Empty;
|
||||||
var userRound = await _dutyTimeRepository.GetByIdAsync(roundId);
|
var userRound = await _dutyTimeRepository.GetByIdAsync(roundId);
|
||||||
|
|
||||||
|
|
@ -1934,7 +1935,7 @@ namespace BMA.EHR.Leave.Service.Controllers
|
||||||
ProfileType = d.ProfileType ?? "",
|
ProfileType = d.ProfileType ?? "",
|
||||||
|
|
||||||
CheckInDate = d.CheckIn.Date,
|
CheckInDate = d.CheckIn.Date,
|
||||||
CheckInTime = d.CheckIn.ToString("HH:mm:ss"),
|
CheckInTime = d.CheckIn.ToString("HH:mm"),
|
||||||
CheckInLocation = d.CheckInPOI,
|
CheckInLocation = d.CheckInPOI,
|
||||||
CheckInLat = d.CheckInLat,
|
CheckInLat = d.CheckInLat,
|
||||||
CheckInLon = d.CheckInLon,
|
CheckInLon = d.CheckInLon,
|
||||||
|
|
@ -1945,7 +1946,7 @@ namespace BMA.EHR.Leave.Service.Controllers
|
||||||
CheckInLocationName = d.CheckInLocationName ?? "",
|
CheckInLocationName = d.CheckInLocationName ?? "",
|
||||||
|
|
||||||
CheckOutDate = d.CheckOut?.Date,
|
CheckOutDate = d.CheckOut?.Date,
|
||||||
CheckOutTime = d.CheckOut == null ? "" : d.CheckOut.Value.ToString("HH:mm:ss"),
|
CheckOutTime = d.CheckOut == null ? "" : d.CheckOut.Value.ToString("HH:mm"),
|
||||||
CheckOutLocation = d.CheckOut == null ? "" : d.CheckOutPOI,
|
CheckOutLocation = d.CheckOut == null ? "" : d.CheckOutPOI,
|
||||||
CheckOutLat = d.CheckOut == null ? null : d.CheckOutLat,
|
CheckOutLat = d.CheckOut == null ? null : d.CheckOutLat,
|
||||||
CheckOutLon = d.CheckOut == null ? null : d.CheckOutLon,
|
CheckOutLon = d.CheckOut == null ? null : d.CheckOutLon,
|
||||||
|
|
@ -3010,6 +3011,8 @@ namespace BMA.EHR.Leave.Service.Controllers
|
||||||
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
||||||
public async Task<ActionResult<ResponseObject>> CheckoutCheckAsync(string isSeminar = "N")
|
public async Task<ActionResult<ResponseObject>> CheckoutCheckAsync(string isSeminar = "N")
|
||||||
{
|
{
|
||||||
|
// "S" = Seminar, "N" = Normal, "O" = One Stop Service
|
||||||
|
|
||||||
var time = DateTime.Now;
|
var time = DateTime.Now;
|
||||||
|
|
||||||
var userId = UserId != null ? Guid.Parse(UserId) : Guid.Empty;
|
var userId = UserId != null ? Guid.Parse(UserId) : Guid.Empty;
|
||||||
|
|
@ -3041,9 +3044,11 @@ namespace BMA.EHR.Leave.Service.Controllers
|
||||||
|
|
||||||
//var endTime = DateTimeOffset.Parse($"{DateTime.Now.Date.ToString("yyyy-MM-dd")}T{duty.EndTimeAfternoon}:00.0000000+07:00").ToLocalTime().DateTime;
|
//var endTime = DateTimeOffset.Parse($"{DateTime.Now.Date.ToString("yyyy-MM-dd")}T{duty.EndTimeAfternoon}:00.0000000+07:00").ToLocalTime().DateTime;
|
||||||
|
|
||||||
//var endTime = DateTime.Parse($"{DateTime.Now.Date.ToString("yyyy-MM-dd")}T{duty.EndTimeAfternoon}:00.0000000+07:00");
|
//var endTime = DateTime.Parse($"{DateTime.Now.Date.ToString("yyyy-MM-dd")}T{duty.EndTimeAfternoon}:00.0000000+07:00");
|
||||||
var endTime = isSeminar.Trim().ToUpper() == "Y"
|
var endTime = isSeminar.Trim().ToUpper() == "S"
|
||||||
? DateTime.Parse($"{DateTime.Now.Date.ToString("yyyy-MM-dd")} 14:30")
|
? DateTime.Parse($"{DateTime.Now.Date.ToString("yyyy-MM-dd")} 14:30")
|
||||||
|
: isSeminar.Trim().ToUpper() == "O"
|
||||||
|
? DateTime.Parse($"{DateTime.Now.Date.ToString("yyyy-MM-dd")} 18:30")
|
||||||
: DateTime.Parse($"{DateTime.Now.Date.ToString("yyyy-MM-dd")} {duty.EndTimeAfternoon}");
|
: DateTime.Parse($"{DateTime.Now.Date.ToString("yyyy-MM-dd")} {duty.EndTimeAfternoon}");
|
||||||
|
|
||||||
var endTimeMorning = DateTime.Parse($"{DateTime.Now.Date.ToString("yyyy-MM-dd")} {duty.EndTimeMorning}");
|
var endTimeMorning = DateTime.Parse($"{DateTime.Now.Date.ToString("yyyy-MM-dd")} {duty.EndTimeMorning}");
|
||||||
|
|
@ -3132,7 +3137,16 @@ namespace BMA.EHR.Leave.Service.Controllers
|
||||||
return Error("ไม่สามารถขอลงเวลากรณีพิเศษในวันที่มากกว่าวันที่ปัจจุบันได้", StatusCodes.Status400BadRequest);
|
return Error("ไม่สามารถขอลงเวลากรณีพิเศษในวันที่มากกว่าวันที่ปัจจุบันได้", StatusCodes.Status400BadRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var userId = UserId != null ? Guid.Parse(UserId) : Guid.Empty;
|
var userId = UserId != null ? Guid.Parse(UserId) : Guid.Empty;
|
||||||
|
|
||||||
|
var checkin = await _userTimeStampRepository.GetTimestampByDateAsync(userId, req.CheckDate.Date);
|
||||||
|
if (checkin != null && checkin.CheckOut == null)
|
||||||
|
{
|
||||||
|
return Error("ระบบพบรายการลงเวลาของวันที่ต้องการแก้ไข แต่ยังไม่มีข้อมูลการลงเวลาออก กรุณาลงเวลาออกให้เรียบร้อยก่อนดำเนินการ");
|
||||||
|
}
|
||||||
|
|
||||||
var profile = await _userProfileRepository.GetProfileByKeycloakIdNew2Async(userId, AccessToken);
|
var profile = await _userProfileRepository.GetProfileByKeycloakIdNew2Async(userId, AccessToken);
|
||||||
if (profile == null)
|
if (profile == null)
|
||||||
{
|
{
|
||||||
|
|
@ -3180,7 +3194,7 @@ namespace BMA.EHR.Leave.Service.Controllers
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||||
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
||||||
public async Task<ActionResult<ResponseObject>> GetAdditionalCheckRequestAsync([Required] int year, [Required] int month, [Required] int page = 1, [Required] int pageSize = 10, string keyword = "", string? sortBy = "", bool? descending = false)
|
public async Task<ActionResult<ResponseObject>> GetAdditionalCheckRequestAsync([Required] DateTime startDate, [Required] DateTime endDate, [Required] int page = 1, [Required] int pageSize = 10, string keyword = "", string? sortBy = "", bool? descending = false,string? status = "")
|
||||||
{
|
{
|
||||||
var jsonData = await _permission.GetPermissionWithActingAPIAsync("LIST", "SYS_CHECKIN_SPECIAL");
|
var jsonData = await _permission.GetPermissionWithActingAPIAsync("LIST", "SYS_CHECKIN_SPECIAL");
|
||||||
//var jsonData = JsonConvert.DeserializeObject<GetPermissionWithActingResultDto>(getPermission);
|
//var jsonData = JsonConvert.DeserializeObject<GetPermissionWithActingResultDto>(getPermission);
|
||||||
|
|
@ -3225,7 +3239,7 @@ namespace BMA.EHR.Leave.Service.Controllers
|
||||||
}
|
}
|
||||||
|
|
||||||
//var rawData = await _additionalCheckRequestRepository.GetAdditionalCheckRequests(year, month);
|
//var rawData = await _additionalCheckRequestRepository.GetAdditionalCheckRequests(year, month);
|
||||||
var rawData = await _additionalCheckRequestRepository.GetAdditionalCheckRequestsByAdminRole(year, month, role, nodeId, profileAdmin?.Node, keyword);
|
var rawData = await _additionalCheckRequestRepository.GetAdditionalCheckRequestsByAdminRole2(startDate, endDate, role, nodeId, profileAdmin?.Node, keyword,status);
|
||||||
|
|
||||||
// ถ้ามีการรักษาการ
|
// ถ้ามีการรักษาการ
|
||||||
if (jsonData.result.isAct)
|
if (jsonData.result.isAct)
|
||||||
|
|
@ -3293,7 +3307,7 @@ namespace BMA.EHR.Leave.Service.Controllers
|
||||||
actNode = 0;
|
actNode = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
var rawDataAct = await _additionalCheckRequestRepository.GetAdditionalCheckRequestsByAdminRole(year, month, actRole, actNodeId, profileAdmin?.Node, keyword);
|
var rawDataAct = await _additionalCheckRequestRepository.GetAdditionalCheckRequestsByAdminRole2(startDate, endDate, actRole, actNodeId, profileAdmin?.Node, keyword,status);
|
||||||
if (rawDataAct != null)
|
if (rawDataAct != null)
|
||||||
{
|
{
|
||||||
if (rawData != null)
|
if (rawData != null)
|
||||||
|
|
@ -3809,6 +3823,10 @@ namespace BMA.EHR.Leave.Service.Controllers
|
||||||
"ABSENT" :
|
"ABSENT" :
|
||||||
"NORMAL",
|
"NORMAL",
|
||||||
CheckOutDescription = d.CheckOutRemark ?? "",
|
CheckOutDescription = d.CheckOutRemark ?? "",
|
||||||
|
IsLocationCheckIn = d.IsLocationCheckIn,
|
||||||
|
IsLocationCheckOut = d.IsLocationCheckOut,
|
||||||
|
CheckInLocationName = d.CheckInLocationName ?? "",
|
||||||
|
CheckOutLocationName = d.CheckOutLocationName ?? ""
|
||||||
};
|
};
|
||||||
|
|
||||||
return Success(result);
|
return Success(result);
|
||||||
|
|
@ -3873,6 +3891,7 @@ namespace BMA.EHR.Leave.Service.Controllers
|
||||||
{
|
{
|
||||||
resultCheckInDate = checkInData == null ? null : checkInData.CheckIn;
|
resultCheckInDate = checkInData == null ? null : checkInData.CheckIn;
|
||||||
resultCheckInTime = checkInData == null ? "00:00" : checkInData.CheckIn.ToString("HH:mm");
|
resultCheckInTime = checkInData == null ? "00:00" : checkInData.CheckIn.ToString("HH:mm");
|
||||||
|
resultCheckInLocation = checkInData == null ? "" : checkInData!.CheckInPOI;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.CheckOutEdit)
|
if (data.CheckOutEdit)
|
||||||
|
|
@ -3890,6 +3909,7 @@ namespace BMA.EHR.Leave.Service.Controllers
|
||||||
resultCheckOutTime = checkInData == null ? "00:00" :
|
resultCheckOutTime = checkInData == null ? "00:00" :
|
||||||
checkInData.CheckOut == null ? "00:00" :
|
checkInData.CheckOut == null ? "00:00" :
|
||||||
checkInData.CheckOut.Value.ToString("HH:mm");
|
checkInData.CheckOut.Value.ToString("HH:mm");
|
||||||
|
resultCheckOutLocation = checkInData == null ? "" : checkInData!.CheckOutPOI;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -157,7 +157,7 @@ namespace BMA.EHR.Leave.Service.Controllers
|
||||||
data.Type.Id, data.CreatedAt);
|
data.Type.Id, data.CreatedAt);
|
||||||
|
|
||||||
var startFiscalYear = (new DateTime(data.LeaveStartDate.Year - 1, 10, 1)).Date;
|
var startFiscalYear = (new DateTime(data.LeaveStartDate.Year - 1, 10, 1)).Date;
|
||||||
var endFiscalYear = (data.DateSendLeave ?? data.CreatedAt).Date;
|
var endFiscalYear = (data.DateSendLeave ?? data.CreatedAt);
|
||||||
|
|
||||||
var thisYear = data.LeaveStartDate.Year;
|
var thisYear = data.LeaveStartDate.Year;
|
||||||
var toDay = data.LeaveStartDate.Date;
|
var toDay = data.LeaveStartDate.Date;
|
||||||
|
|
|
||||||
|
|
@ -175,6 +175,9 @@ namespace BMA.EHR.Leave.Service.Controllers
|
||||||
LastUpdateFullName = FullName ?? "",
|
LastUpdateFullName = FullName ?? "",
|
||||||
LastUpdateUserId = UserId!,
|
LastUpdateUserId = UserId!,
|
||||||
LastUpdatedAt = DateTime.Now,
|
LastUpdatedAt = DateTime.Now,
|
||||||
|
|
||||||
|
IsAct = r.isAct,
|
||||||
|
KeyId = r.keyId
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -943,8 +946,8 @@ namespace BMA.EHR.Leave.Service.Controllers
|
||||||
OrganizationName = orgName, //profile.Oc ?? "",
|
OrganizationName = orgName, //profile.Oc ?? "",
|
||||||
|
|
||||||
LeaveLimit = leaveLimit, // จำนวนวันลาทั้งหมดในปีนั้นๆที่ลาได้ โดยรวมยอดที่เหลือจากปีก่อนมา (เอาค่ามาจากตาราง Beginning เลย)
|
LeaveLimit = leaveLimit, // จำนวนวันลาทั้งหมดในปีนั้นๆที่ลาได้ โดยรวมยอดที่เหลือจากปีก่อนมา (เอาค่ามาจากตาราง Beginning เลย)
|
||||||
LeaveTotal = sumLeave, // จำนวนวันลาที่ลาไปแล้วในปีนั้นๆ โดยเมื่อมีการอนุมัติลา จะมาบวกค่านี้ไปเรื่อยๆ (เอาค่ามาจากตาราง Beginning เลย)
|
LeaveTotal = sumLeave ?? 0, // จำนวนวันลาที่ลาไปแล้วในปีนั้นๆ โดยเมื่อมีการอนุมัติลา จะมาบวกค่านี้ไปเรื่อยๆ (เอาค่ามาจากตาราง Beginning เลย)
|
||||||
LeaveRemain = leaveLimit - sumLeave,
|
LeaveRemain = leaveLimit - (sumLeave ?? 0),
|
||||||
RestDayTotalOld = restOldDay, // เอา leaveLimit มาลบ 10 (LV-005)
|
RestDayTotalOld = restOldDay, // เอา leaveLimit มาลบ 10 (LV-005)
|
||||||
RestDayTotalCurrent = restCurrentDay,// 10 วันเสมอ (LV-005)
|
RestDayTotalCurrent = restCurrentDay,// 10 วันเสมอ (LV-005)
|
||||||
BirthDate = profile.BirthDate.Date,
|
BirthDate = profile.BirthDate.Date,
|
||||||
|
|
@ -2835,8 +2838,9 @@ namespace BMA.EHR.Leave.Service.Controllers
|
||||||
var leaveData = await _leaveBeginningRepository.GetByYearAndTypeIdForUser2Async(thisYear, rawData.Type.Id, rawData.KeycloakUserId);
|
var leaveData = await _leaveBeginningRepository.GetByYearAndTypeIdForUser2Async(thisYear, rawData.Type.Id, rawData.KeycloakUserId);
|
||||||
|
|
||||||
var startFiscalYear = new DateTime(rawData.LeaveStartDate.Year - 1, 10, 1);
|
var startFiscalYear = new DateTime(rawData.LeaveStartDate.Year - 1, 10, 1);
|
||||||
var endFiscalYear = rawData.CreatedAt;
|
var endFiscalYear = rawData.DateSendLeave ?? rawData.CreatedAt;
|
||||||
var endFiscalYear2 = new DateTime(rawData.LeaveStartDate.Year, 9, 30);
|
var endFiscalYear2 = new DateTime(rawData.LeaveStartDate.Year, 9, 30);
|
||||||
|
//var endFiscalYear3 = rawData.DateSendLeave ?? rawData.CreatedAt;
|
||||||
var leaveSummary = await _leaveRequestRepository.GetSumApproveLeaveTotalByTypeAndRangeForUser2(rawData.KeycloakUserId, rawData.Type.Id, startFiscalYear, endFiscalYear);
|
var leaveSummary = await _leaveRequestRepository.GetSumApproveLeaveTotalByTypeAndRangeForUser2(rawData.KeycloakUserId, rawData.Type.Id, startFiscalYear, endFiscalYear);
|
||||||
|
|
||||||
// วันลาแบบร่างและที่ยื่นลาไปแล้ว
|
// วันลาแบบร่างและที่ยื่นลาไปแล้ว
|
||||||
|
|
@ -2987,7 +2991,10 @@ namespace BMA.EHR.Leave.Service.Controllers
|
||||||
ApproveStatus = x.ApproveStatus,
|
ApproveStatus = x.ApproveStatus,
|
||||||
Comment = x.Comment,
|
Comment = x.Comment,
|
||||||
ProfileId = x.ProfileId,
|
ProfileId = x.ProfileId,
|
||||||
KeycloakId = x.KeycloakId
|
KeycloakId = x.KeycloakId,
|
||||||
|
isAct = x.IsAct,
|
||||||
|
keyId = x.KeyId
|
||||||
|
|
||||||
}).ToList();
|
}).ToList();
|
||||||
|
|
||||||
var approvers = rawData.Approvers.Where(x => x.ApproveType.ToUpper() == "APPROVER")
|
var approvers = rawData.Approvers.Where(x => x.ApproveType.ToUpper() == "APPROVER")
|
||||||
|
|
@ -3002,7 +3009,10 @@ namespace BMA.EHR.Leave.Service.Controllers
|
||||||
ApproveStatus = x.ApproveStatus,
|
ApproveStatus = x.ApproveStatus,
|
||||||
Comment = x.Comment,
|
Comment = x.Comment,
|
||||||
ProfileId = x.ProfileId,
|
ProfileId = x.ProfileId,
|
||||||
KeycloakId = x.KeycloakId
|
KeycloakId = x.KeycloakId,
|
||||||
|
|
||||||
|
isAct = x.IsAct,
|
||||||
|
keyId = x.KeyId
|
||||||
}).ToList();
|
}).ToList();
|
||||||
|
|
||||||
result.Approvers.AddRange(approvers);
|
result.Approvers.AddRange(approvers);
|
||||||
|
|
|
||||||
|
|
@ -17,16 +17,16 @@ namespace BMA.EHR.Leave.Service.DTOs.LeaveBeginnings
|
||||||
[Required, Comment("จำนวนวันลายกมา")]
|
[Required, Comment("จำนวนวันลายกมา")]
|
||||||
public double LeaveDays { get; set; } = 0.0;
|
public double LeaveDays { get; set; } = 0.0;
|
||||||
|
|
||||||
[Required, Comment("จำนวนวันลาที่ใช้ไป")]
|
[Comment("จำนวนวันลาที่ใช้ไป")]
|
||||||
public double LeaveDaysUsed { get; set; } = 0.0;
|
public double? LeaveDaysUsed { get; set; }
|
||||||
|
|
||||||
[Required, Comment("จำนวนครั้งที่ลาสะสม")]
|
[Comment("จำนวนครั้งที่ลาสะสม")]
|
||||||
public int LeaveCount { get; set; } = 0;
|
public int? LeaveCount { get; set; }
|
||||||
|
|
||||||
[Required, Comment("จำนวนวันลายกมา")]
|
[Required, Comment("จำนวนวันลายกมาก่อนใช้ระบบ")]
|
||||||
public double BeginningLeaveDays { get; set; } = 0.0;
|
public double BeginningLeaveDays { get; set; } = 0.0;
|
||||||
|
|
||||||
[Comment("จำนวนครั้งที่ลายกมา")]
|
[Comment("จำนวนครั้งที่ลายกมาก่อนใช้ระบบ")]
|
||||||
public int BeginningLeaveCount { get; set; } = 0;
|
public int BeginningLeaveCount { get; set; } = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -174,5 +174,8 @@ namespace BMA.EHR.Leave.Service.DTOs.LeaveRequest
|
||||||
public string ApproveStatus { get; set; } = string.Empty;
|
public string ApproveStatus { get; set; } = string.Empty;
|
||||||
|
|
||||||
public string Comment { get; set; } = string.Empty;
|
public string Comment { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public bool isAct { get; set; } = false;
|
||||||
|
public string keyId { get; set; } = string.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,5 +37,11 @@ namespace BMA.EHR.Leave.Service.DTOs.LeaveRequest
|
||||||
[JsonProperty("organizationName")]
|
[JsonProperty("organizationName")]
|
||||||
public string OrganizationName { get; set; } = string.Empty;
|
public string OrganizationName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[JsonProperty("isAct")]
|
||||||
|
public bool isAct { get; set; } = false;
|
||||||
|
|
||||||
|
[JsonProperty("keyId")]
|
||||||
|
public string keyId { get; set; } = string.Empty;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -129,6 +129,7 @@ namespace BMA.EHR.Placement.Service.Controllers
|
||||||
{
|
{
|
||||||
p.Id,
|
p.Id,
|
||||||
p.prefix,
|
p.prefix,
|
||||||
|
p.rank,
|
||||||
p.firstName,
|
p.firstName,
|
||||||
p.lastName,
|
p.lastName,
|
||||||
p.citizenId,
|
p.citizenId,
|
||||||
|
|
@ -280,6 +281,7 @@ namespace BMA.EHR.Placement.Service.Controllers
|
||||||
// ProfileId = p.Profile.Id,
|
// ProfileId = p.Profile.Id,
|
||||||
p.citizenId,
|
p.citizenId,
|
||||||
p.prefix,
|
p.prefix,
|
||||||
|
p.rank,
|
||||||
p.firstName,
|
p.firstName,
|
||||||
p.lastName,
|
p.lastName,
|
||||||
p.DateOfBirth,
|
p.DateOfBirth,
|
||||||
|
|
@ -377,6 +379,7 @@ namespace BMA.EHR.Placement.Service.Controllers
|
||||||
// data.ProfileId,
|
// data.ProfileId,
|
||||||
data.citizenId,
|
data.citizenId,
|
||||||
data.prefix,
|
data.prefix,
|
||||||
|
data.rank,
|
||||||
data.firstName,
|
data.firstName,
|
||||||
data.lastName,
|
data.lastName,
|
||||||
data.DateOfBirth,
|
data.DateOfBirth,
|
||||||
|
|
@ -484,6 +487,7 @@ namespace BMA.EHR.Placement.Service.Controllers
|
||||||
// Profile = profile,
|
// Profile = profile,
|
||||||
citizenId = req.citizenId,
|
citizenId = req.citizenId,
|
||||||
prefix = req.prefix,
|
prefix = req.prefix,
|
||||||
|
rank = req.rank,
|
||||||
firstName = req.firstName,
|
firstName = req.firstName,
|
||||||
lastName = req.lastName,
|
lastName = req.lastName,
|
||||||
DateOfBirth = req.BirthDate,
|
DateOfBirth = req.BirthDate,
|
||||||
|
|
@ -852,6 +856,7 @@ namespace BMA.EHR.Placement.Service.Controllers
|
||||||
uppdated.Gender = req.Gender;
|
uppdated.Gender = req.Gender;
|
||||||
uppdated.citizenId = req.citizenId;
|
uppdated.citizenId = req.citizenId;
|
||||||
uppdated.prefix = req.prefix;
|
uppdated.prefix = req.prefix;
|
||||||
|
uppdated.rank = req.rank;
|
||||||
uppdated.firstName = req.firstName;
|
uppdated.firstName = req.firstName;
|
||||||
uppdated.lastName = req.lastName;
|
uppdated.lastName = req.lastName;
|
||||||
uppdated.DateOfBirth = req.DateOfBirth;
|
uppdated.DateOfBirth = req.DateOfBirth;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,8 @@ namespace BMA.EHR.Placement.Service.Requests
|
||||||
public class PlacementReceiveEditRequest
|
public class PlacementReceiveEditRequest
|
||||||
{
|
{
|
||||||
public string citizenId { get; set; }
|
public string citizenId { get; set; }
|
||||||
public string prefix { get; set; }
|
public string? prefix { get; set; }
|
||||||
|
public string? rank { get; set; }
|
||||||
public string firstName { get; set; }
|
public string firstName { get; set; }
|
||||||
public string lastName { get; set; }
|
public string lastName { get; set; }
|
||||||
public DateTime DateOfBirth { get; set; }
|
public DateTime DateOfBirth { get; set; }
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,9 @@ namespace BMA.EHR.Placement.Service.Requests
|
||||||
public class PlacementReceiveRequest
|
public class PlacementReceiveRequest
|
||||||
{
|
{
|
||||||
public string citizenId { get; set; }
|
public string citizenId { get; set; }
|
||||||
public string prefix { get; set; }
|
|
||||||
|
public string? prefix { get; set; }
|
||||||
|
public string? rank { get; set; }
|
||||||
public string firstName { get; set; }
|
public string firstName { get; set; }
|
||||||
public string lastName { get; set; }
|
public string lastName { get; set; }
|
||||||
public DateTime BirthDate { get; set; }
|
public DateTime BirthDate { get; set; }
|
||||||
|
|
|
||||||
210
README.md
Normal file
210
README.md
Normal file
|
|
@ -0,0 +1,210 @@
|
||||||
|
# BMA.EHR - HRMS API Backend
|
||||||
|
|
||||||
|
ระบบบริหารจัดการทรัพยากรบุคคล (Human Resource Management System) พัฒนาด้วยสถาปัตยกรรม Microservices บน .NET
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Tech Stack
|
||||||
|
|
||||||
|
| Category | Technology |
|
||||||
|
| ----------------- | ----------------------------- |
|
||||||
|
| Framework | .NET 6.0 / 7.0 / 8.0 |
|
||||||
|
| Architecture | Clean Architecture, DDD, CQRS |
|
||||||
|
| Database | MySQL (Entity Framework Core) |
|
||||||
|
| Authentication | JWT + Keycloak |
|
||||||
|
| Message Queue | RabbitMQ |
|
||||||
|
| Object Storage | MinIO |
|
||||||
|
| Background Jobs | Hangfire |
|
||||||
|
| Logging | Serilog + Elasticsearch |
|
||||||
|
| Error Tracking | Sentry |
|
||||||
|
| API Documentation | Swagger / OpenAPI |
|
||||||
|
| Containerization | Docker |
|
||||||
|
| Testing | xUnit, k6 (Load Testing) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## โครงสร้างโปรเจกต์ (Project Structure)
|
||||||
|
|
||||||
|
```
|
||||||
|
BMA.EHR.Solution.sln
|
||||||
|
├── src/ # Core Libraries
|
||||||
|
│ ├── BMA.EHR.Domain/ # Domain layer (Entities, Business Rules)
|
||||||
|
│ ├── BMA.EHR.Application/ # Application layer (Use Cases, Interfaces)
|
||||||
|
│ └── BMA.EHR.Infrastructure/ # Infrastructure layer (Data Access, External Services)
|
||||||
|
│
|
||||||
|
└── Service/ # Microservices
|
||||||
|
├── BMA.EHR.Command.Service/ # Command/CQRS API Gateway
|
||||||
|
├── BMA.EHR.MetaData.Service/ # ข้อมูลอ้างอิง (คำนำหน้า, หมู่เลือด, ศาสนา ฯลฯ)
|
||||||
|
├── BMA.EHR.Placement.Service/ # การบริจาค/สั่งย้าย/แต่งตั้ง
|
||||||
|
├── BMA.EHR.OrganizationEmployee.Service/ # โครงสร้างองค์กรและบุคลากร
|
||||||
|
├── BMA.EHR.Discipline.Service/ # การ discipline บุคลากร
|
||||||
|
├── BMA.EHR.Retirement.Service/ # การเกษียณอายุราชการ
|
||||||
|
├── BMA.EHR.Report.Service/ # รายงาน
|
||||||
|
├── BMA.EHR.Insignia/ # เครื่องราชอิสริยาภรณ์
|
||||||
|
├── BMA.EHR.Leave/ # ระบบลา
|
||||||
|
└── BMA.EHR.CheckInConsumer/ # ลงเวลาปฏิบัติงาน
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## โมดูลหลัก (Key Modules)
|
||||||
|
|
||||||
|
### การบริหารทรัพยากรบุคคล
|
||||||
|
|
||||||
|
- **Placement Service** - สั่งย้าย, แต่งตั้ง, เลื่อนตำแหน่ง, โอนย้ายบุคลากร
|
||||||
|
- **Organization Employee Service** - จัดการโครงสร้างองค์กร, ตำแหน่ง, ข้อมูลบุคลากร
|
||||||
|
- **Leave Service** - การลางาน, การอนุมัติ, วันหยุดนักขัตฤกษ์, ยอดวันลาคงเหลือ
|
||||||
|
- **Discipline Service** - การดำเนินการ discipline, การสืบสวน, เอกสารที่เกี่ยวข้อง
|
||||||
|
- **Retirement Service** - การเกษียณอายุ, เอกสาร, สิทธิประโยชน์
|
||||||
|
- **Insignia Service** - เครื่องราชอิสริยาภรณ์และรางวัล
|
||||||
|
- **CheckIn Consumer** - ติดตามการลงเวลาปฏิบัติงาน
|
||||||
|
|
||||||
|
### ระบบสนับสนุน
|
||||||
|
|
||||||
|
- **Metadata Service** - ข้อมูลอ้างอิง (คำนำหน้าชื่อ, หมู่เลือด, ศาสนา, ระดับการศึกษา ฯลฯ)
|
||||||
|
- **Report Service** - สร้างรายงาน PDF/Excel
|
||||||
|
- **Command Service** - API Gateway สำหรับ CQRS command operations
|
||||||
|
|
||||||
|
### ฟีเจอร์เด่น
|
||||||
|
|
||||||
|
- **Real-time Notifications** - แจ้งเตือนผ่าน WebSocket
|
||||||
|
- **Background Processing** - งานที่กำหนดเวลาผ่าน Hangfire
|
||||||
|
- **Event-Driven Communication** - สื่อสารระหว่าง services ผ่าน RabbitMQ
|
||||||
|
- **Document Generation** - สร้างเอกสาร PDF/Excel
|
||||||
|
- **Audit Trail** - บันทึกประวัติการเปลี่ยนแปลงข้อมูลทั้งหมด
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## API Endpoints
|
||||||
|
|
||||||
|
API ใช้ versioning และสามารถดูรายละเอียดได้ผ่าน Swagger UI:
|
||||||
|
|
||||||
|
```
|
||||||
|
/api/v1/placement # การบริจาค/สั่งย้าย/แต่งตั้ง
|
||||||
|
/api/v1/leave # ระบบลา
|
||||||
|
/api/v1/discipline # การ discipline
|
||||||
|
/api/v1/organization # โครงสร้างองค์กร
|
||||||
|
/api/v1/metadata # ข้อมูลอ้างอิง
|
||||||
|
/api/v1/retirement # การเกษียณอายุ
|
||||||
|
/api/v1/insignia # เครื่องราชอิสริยาภรณ์
|
||||||
|
/api/v1/reports # รายงาน
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
- .NET SDK 6.0 / 7.0 / 8.0
|
||||||
|
- MySQL Server
|
||||||
|
- Keycloak (Authentication Server)
|
||||||
|
- RabbitMQ
|
||||||
|
- MinIO (Object Storage)
|
||||||
|
- Docker (สำหรับ deployment)
|
||||||
|
|
||||||
|
### Configuration
|
||||||
|
|
||||||
|
แต่ละ service มีไฟล์ `appsettings.json` สำหรับ config ดังนี้:
|
||||||
|
|
||||||
|
- **JWT Authentication** - เชื่อมต่อกับ Keycloak
|
||||||
|
- **Database Connection** - MySQL connection string
|
||||||
|
- **RabbitMQ** - Message queue connection
|
||||||
|
- **MinIO** - File storage endpoint
|
||||||
|
- **Elasticsearch** - Logging endpoint
|
||||||
|
- **Mail Server** - สำหรับส่งอีเมล
|
||||||
|
|
||||||
|
### Build & Run
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Restore dependencies
|
||||||
|
dotnet restore
|
||||||
|
|
||||||
|
# Build solution
|
||||||
|
dotnet build
|
||||||
|
|
||||||
|
# Run specific service
|
||||||
|
dotnet run --project Service/BMA.EHR.Command.Service
|
||||||
|
```
|
||||||
|
|
||||||
|
### Docker
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build Docker image
|
||||||
|
docker build -t bma-ehr-service .
|
||||||
|
|
||||||
|
# Run container
|
||||||
|
docker run -d -p 5000:80 bma-ehr-service
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
||||||
|
│ Swagger │ │ Client │ │ WebSocket │
|
||||||
|
│ UI │ │ Apps │ │ Clients │
|
||||||
|
└──────┬───────┘ └──────┬───────┘ └──────┬───────┘
|
||||||
|
│ │ │
|
||||||
|
└────────────────────┼────────────────────┘
|
||||||
|
│
|
||||||
|
┌────────▼────────┐
|
||||||
|
│ API Gateway │
|
||||||
|
│ (Keycloak JWT) │
|
||||||
|
└────────┬────────┘
|
||||||
|
│
|
||||||
|
┌────────────────────┼────────────────────┐
|
||||||
|
│ │ │
|
||||||
|
┌──────▼──────┐ ┌────────▼──────┐ ┌────────▼──────┐
|
||||||
|
│ Placement │ │ Leave │ │ Discipline │
|
||||||
|
│ Service │ │ Service │ │ Service │
|
||||||
|
└──────┬──────┘ └────────┬──────┘ └────────┬──────┘
|
||||||
|
│ │ │
|
||||||
|
└────────────────────┼────────────────────┘
|
||||||
|
│
|
||||||
|
┌─────────────▼──────────────┐
|
||||||
|
│ MySQL Database │
|
||||||
|
│ (Entity Framework) │
|
||||||
|
└────────────────────────────┘
|
||||||
|
|
||||||
|
┌────────────────────────────┐
|
||||||
|
│ RabbitMQ / MinIO / │
|
||||||
|
│ Elasticsearch / Hangfire │
|
||||||
|
└────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Dependencies ที่สำคัญ
|
||||||
|
|
||||||
|
| Package | หน้าที่ |
|
||||||
|
| --------------------- | ------------------------- |
|
||||||
|
| Entity Framework Core | ORM สำหรับ MySQL |
|
||||||
|
| Serilog | Structured Logging |
|
||||||
|
| Swashbuckle | API Documentation |
|
||||||
|
| Hangfire | Background Job Processing |
|
||||||
|
| EPPlus | สร้าง/อ่านไฟล์ Excel |
|
||||||
|
| iTextSharp | สร้างไฟล์ PDF |
|
||||||
|
| RabbitMQ.Client | Message Queue |
|
||||||
|
| NEST | Elasticsearch Client |
|
||||||
|
| ThaiBahtText | แปลงตัวเลขเป็นหน่วยบาทไทย |
|
||||||
|
| NodaTime | Date/Time Handling |
|
||||||
|
| Sentry | Error Tracking |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Run unit tests
|
||||||
|
dotnet test
|
||||||
|
|
||||||
|
# Run with coverage
|
||||||
|
dotnet test --collect:"XPlat Code Coverage"
|
||||||
|
|
||||||
|
# Run load tests (k6)
|
||||||
|
k6 run tests/load/*.js
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
Loading…
Add table
Add a link
Reference in a new issue