Compare commits
222 commits
placement-
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a2fe424b87 | ||
|
|
5021c00dd3 | ||
|
|
bf5dc2cf19 | ||
|
|
f6c8b4f754 | ||
|
|
65ca175f98 | ||
|
|
5f678b2898 | ||
|
|
ae417e4777 | ||
|
|
a2dc4b5b82 | ||
|
|
c55648a3cc | ||
|
|
bc29952e83 | ||
|
|
f4f56b1c21 | ||
|
|
baf828ac85 | ||
|
|
be1f6dd84e | ||
|
|
fcea84bdb8 | ||
|
|
5d090fa7bd | ||
|
|
030098c0b9 | ||
|
|
6843e3ff3f | ||
|
|
2cdae3578e | ||
|
|
71966eb4e9 | ||
|
|
e926866918 | ||
|
|
35179d8cfc | ||
|
|
4a8d349415 | ||
|
|
7d2be029b6 | ||
|
|
d75cf39d7b | ||
|
|
db3d531aa9 | ||
|
|
e17895de81 | ||
|
|
e09a6d0ea6 | ||
|
|
4c44bdf237 | ||
| 6f1ca58f04 | |||
| a956f0b0dd | |||
|
|
f0c493a026 | ||
|
|
fe5c2cd7c1 | ||
|
|
c4209400ff | ||
|
|
d6a7f1a5ca | ||
|
|
f50efc632b | ||
| 5f9c49f479 | |||
| 48aab28e04 | |||
| 1f7951dc4c | |||
|
|
d3a174faa0 | ||
|
|
afa5c85393 | ||
| 077b60b1c3 | |||
| efc96dfb6d | |||
|
|
4827906d1d | ||
|
|
8ae822d05b | ||
|
|
71a4748d39 | ||
|
|
ad70043264 | ||
|
|
513956c861 | ||
|
|
a48f3fa804 | ||
|
|
dc5ac329e2 | ||
|
|
3f98e07419 | ||
| ce4558c240 | |||
| 6a38f000ba | |||
|
|
f50ad38503 | ||
| aeb2ceea6f | |||
| e96f606c85 | |||
|
|
81dc7f4544 | ||
|
|
a16ef7ac55 | ||
|
|
f6bf1ab026 | ||
|
|
caa01088c6 | ||
|
|
782d1526b5 | ||
|
|
04ac35c10b | ||
|
|
02abedc973 | ||
| 8415ffc92d | |||
| 64c75cd9d5 | |||
|
|
22e04d90fe | ||
|
|
2146e0e0ca | ||
|
|
3f8ae1ede9 | ||
|
|
c2795d6891 | ||
|
|
6e5284b3c7 | ||
|
|
76697c4f63 | ||
|
|
e5f6a44f5f | ||
|
|
583569682d | ||
|
|
9f756771cd | ||
|
|
219b172073 | ||
|
|
ecf660e4cf | ||
|
|
0365fad723 | ||
|
|
20e8dfddd6 | ||
|
|
91c479ef9e | ||
|
|
80fcda61cf | ||
|
|
f02413f2b2 | ||
|
|
1739aa8057 | ||
|
|
bc3bba547f | ||
|
|
4161fcc1cf | ||
|
|
6d0921a76a | ||
|
|
df7bebe0ba | ||
|
|
82a45b6811 | ||
|
|
63d983f831 | ||
|
|
e326e43ae6 | ||
|
|
4dab3c5cd9 | ||
|
|
4bd46d13e5 | ||
|
|
132a59b946 | ||
|
|
740a9984c9 | ||
|
|
5b0fcd0680 | ||
|
|
2bdb8bb733 | ||
|
|
aed1e8a58d | ||
|
|
fb3cb2aa94 | ||
|
|
b5025c382f | ||
|
|
4e2113eef2 | ||
|
|
ffcf95c210 | ||
|
|
e4bcfee80c | ||
|
|
a173a7dc3c | ||
|
|
361ded2078 | ||
|
|
1379dab556 | ||
|
|
d8039379ad | ||
|
|
2d4116d79a | ||
|
|
c65a4a04ac | ||
|
|
d58c7dc07e | ||
|
|
bb329f86de | ||
|
|
b3298e88c6 | ||
|
|
04d0067ee8 | ||
|
|
c035c13405 | ||
|
|
2e9db2d42c | ||
|
|
1389df0225 | ||
|
|
058027ea29 | ||
|
|
ee2d16925a | ||
|
|
42f3813a7a | ||
|
|
7bafbf5001 | ||
|
|
db99630e0d | ||
|
|
34ec9bb77c | ||
|
|
5606e8b50a | ||
|
|
ee4e9c3699 | ||
|
|
6efeec3f1f | ||
|
|
c34fe35506 | ||
|
|
678329b5df | ||
|
|
057b51390e | ||
|
|
8950073485 | ||
|
|
bf92f6933e | ||
|
|
cea1c4b64e | ||
|
|
cef41506a8 | ||
| bceb4d3096 | |||
|
|
06956284d7 | ||
|
|
6b8eddcbc0 | ||
|
|
a4a5d13203 | ||
|
|
69b89dfc90 | ||
|
|
ea694bfda2 | ||
|
|
6691303ea7 | ||
|
|
8ea572d46c | ||
|
|
2ecef0792c | ||
|
|
1cf780ecd0 | ||
|
|
bf6ea555fc | ||
|
|
8fa105606b | ||
|
|
47c0cfc62a | ||
|
|
932d5e75c7 | ||
|
|
a50153f32c | ||
|
|
d85bab11b2 | ||
|
|
82c31a0f57 | ||
|
|
2cd7798dd9 | ||
|
|
759a51ab58 | ||
|
|
3dee5f7166 | ||
|
|
8732c34564 | ||
|
|
91e6b1b35b | ||
|
|
c1ac687101 | ||
|
|
de1773880b | ||
|
|
c91e6c8030 | ||
|
|
d8f1126764 | ||
|
|
7ba429bb64 | ||
|
|
3e3bfff7ba | ||
|
|
19b79a162d | ||
|
|
a09d5937f9 | ||
|
|
aef81e9f4e | ||
|
|
6427cb4344 | ||
|
|
252d8b5fa3 | ||
|
|
58aca3a328 | ||
|
|
818ff38e99 | ||
|
|
23bbd9791e | ||
|
|
7e0f0485fd | ||
|
|
b1df33dc20 | ||
|
|
6902236f48 | ||
|
|
4562029e6e | ||
|
|
4650f7a2ab | ||
|
|
f866435897 | ||
|
|
006cea048d | ||
|
|
9a74b690cd | ||
|
|
2ee36af763 | ||
|
|
cd99179621 | ||
|
|
c20e1b48bd | ||
|
|
5b054f9948 | ||
|
|
3e34aaa178 | ||
|
|
ddb35f525a | ||
|
|
ecca345407 | ||
|
|
7e613ab2e6 | ||
|
|
7eade164e9 | ||
|
|
256da24caf | ||
|
|
869defcc7e | ||
|
|
65feb994ee | ||
|
|
d748308419 | ||
|
|
b8df2d4024 | ||
|
|
c42aaa38f6 | ||
|
|
ddaa339e9f | ||
|
|
d70ed254c0 | ||
|
|
de91fd0fa2 | ||
|
|
7d3ec6c74e | ||
| 1b7bdd82e6 | |||
|
|
a8271c8d79 | ||
|
|
14fd9d5262 | ||
|
|
c81220a049 | ||
|
|
e5e7c77880 | ||
|
|
a2ac05ed61 | ||
|
|
2410574d42 | ||
|
|
682c88c2db | ||
|
|
05ec0cccce | ||
|
|
35310f7854 | ||
|
|
1d8ef79373 | ||
|
|
c693364fe1 | ||
|
|
4f18a97d0b | ||
|
|
d3cc0781cf | ||
|
|
639d41649c | ||
|
|
358fd47b99 | ||
|
|
970319e8c2 | ||
|
|
09a7208074 | ||
|
|
7775ea85c3 | ||
|
|
19000b2e42 | ||
|
|
1a0e712a1c | ||
|
|
c25bef0672 | ||
|
|
659e06a08d | ||
|
|
0a170fd259 | ||
|
|
5c05f1123a | ||
|
|
06b53ddeaa | ||
|
|
46504c9e30 | ||
|
|
e80f89117c | ||
|
|
4c189fdc4a | ||
|
|
90eb94cee3 |
131 changed files with 62779 additions and 2099 deletions
8
.gitignore
vendored
8
.gitignore
vendored
|
|
@ -373,4 +373,10 @@ MigrationBackup/
|
|||
.ionide/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
FodyWeavers.xsd
|
||||
|
||||
# VS Code C# Dev Kit cache
|
||||
*.lscache
|
||||
|
||||
# Claude Code
|
||||
.claude/
|
||||
25
.vscode/launch.json
vendored
25
.vscode/launch.json
vendored
|
|
@ -26,6 +26,31 @@
|
|||
"/Views": "${workspaceFolder}/Views"
|
||||
}
|
||||
},
|
||||
{
|
||||
// Use IntelliSense to find out which attributes exist for C# debugging
|
||||
// Use hover for the description of the existing attributes
|
||||
// For further information visit https://github.com/dotnet/vscode-csharp/blob/main/debugger-launchjson.md.
|
||||
"name": ".NET Core Launch (web) - Insignia",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
// If you have changed target frameworks, make sure to update the program path.
|
||||
"program": "${workspaceFolder}/BMA.EHR.Insignia/bin/Debug/net7.0/BMA.EHR.Insignia.dll",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}/BMA.EHR.Insignia",
|
||||
"stopAtEntry": false,
|
||||
// Enable launching a web browser when ASP.NET Core starts. For more information: https://aka.ms/VSCode-CS-LaunchJson-WebBrowser
|
||||
"serverReadyAction": {
|
||||
"action": "openExternally",
|
||||
"pattern": "\\bNow listening on:\\s+(https?://\\S+)"
|
||||
},
|
||||
"env": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"sourceFileMap": {
|
||||
"/Views": "${workspaceFolder}/Views"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": ".NET Core Attach",
|
||||
"type": "coreclr",
|
||||
|
|
|
|||
|
|
@ -61,6 +61,8 @@ namespace BMA.EHR.Application
|
|||
|
||||
services.AddTransient<MinIOLeaveService>();
|
||||
|
||||
services.AddTransient<LeaveProcessJobStatusRepository>();
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -53,15 +53,18 @@ namespace BMA.EHR.Application.Repositories
|
|||
|
||||
#region " For Call External API "
|
||||
|
||||
protected async Task<string> GetExternalAPIAsync(string apiPath, string accessToken, string apiKey)
|
||||
protected async Task<string> GetExternalAPIAsync(string apiPath, string accessToken, string apiKey, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
// กำหนด timeout เป็น 30 นาที
|
||||
using var timeoutCts = new CancellationTokenSource(TimeSpan.FromMinutes(30));
|
||||
using var combinedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutCts.Token);
|
||||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api-key", apiKey);
|
||||
var _res = await client.GetAsync(apiPath);
|
||||
var _res = await client.GetAsync(apiPath,cancellationToken: combinedCts.Token);
|
||||
if (_res.IsSuccessStatusCode)
|
||||
{
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
|
|
@ -77,10 +80,13 @@ namespace BMA.EHR.Application.Repositories
|
|||
}
|
||||
}
|
||||
|
||||
protected async Task<string> SendExternalAPIAsync(HttpMethod method, string apiPath, string accessToken, object? body, string apiKey)
|
||||
protected async Task<string> SendExternalAPIAsync(HttpMethod method, string apiPath, string accessToken, object? body, string apiKey, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
// กำหนด timeout เป็น 30 นาที
|
||||
using var timeoutCts = new CancellationTokenSource(TimeSpan.FromMinutes(30));
|
||||
using var combinedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutCts.Token);
|
||||
// สร้าง request message
|
||||
var request = new HttpRequestMessage(method, apiPath);
|
||||
|
||||
|
|
@ -92,7 +98,7 @@ namespace BMA.EHR.Application.Repositories
|
|||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api-key", apiKey);
|
||||
var _res = await client.SendAsync(request);
|
||||
var _res = await client.SendAsync(request, combinedCts.Token);
|
||||
if (_res.IsSuccessStatusCode)
|
||||
{
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
|
|
@ -109,11 +115,13 @@ namespace BMA.EHR.Application.Repositories
|
|||
}
|
||||
|
||||
|
||||
protected async Task<string> PostExternalAPIAsync(string apiPath, string accessToken, object? body, string apiKey)
|
||||
public async Task<string> PostExternalAPIAsync(string apiPath, string accessToken, object? body, string apiKey, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
// กำหนด timeout เป็น 30 นาที
|
||||
using var timeoutCts = new CancellationTokenSource(TimeSpan.FromMinutes(30));
|
||||
using var combinedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutCts.Token);
|
||||
var json = JsonConvert.SerializeObject(body);
|
||||
var stringContent = new StringContent(json, Encoding.UTF8, "application/json");
|
||||
//stringContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
|
||||
|
|
@ -122,7 +130,7 @@ namespace BMA.EHR.Application.Repositories
|
|||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api-key", apiKey);
|
||||
var _res = await client.PostAsync(apiPath, stringContent);
|
||||
var _res = await client.PostAsync(apiPath, stringContent, combinedCts.Token);
|
||||
if (_res.IsSuccessStatusCode)
|
||||
{
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
|
|
@ -138,10 +146,13 @@ namespace BMA.EHR.Application.Repositories
|
|||
}
|
||||
}
|
||||
|
||||
protected async Task<bool> PostExternalAPIBooleanAsync(string apiPath, string accessToken, object? body, string apiKey)
|
||||
protected async Task<bool> PostExternalAPIBooleanAsync(string apiPath, string accessToken, object? body, string apiKey, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
// กำหนด timeout เป็น 30 นาที
|
||||
using var timeoutCts = new CancellationTokenSource(TimeSpan.FromMinutes(30));
|
||||
using var combinedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutCts.Token);
|
||||
var json = JsonConvert.SerializeObject(body);
|
||||
var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json");
|
||||
stringContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
|
||||
|
|
@ -150,7 +161,7 @@ namespace BMA.EHR.Application.Repositories
|
|||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api-key", apiKey);
|
||||
var _res = await client.PostAsync(apiPath, stringContent);
|
||||
var _res = await client.PostAsync(apiPath, stringContent, combinedCts.Token);
|
||||
return _res.IsSuccessStatusCode;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -280,8 +280,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix ?? "")}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position ?? "",
|
||||
Rank = p.PosLevel ?? "",
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
PosNo = p.PosNo,
|
||||
PositionLevelId = p.PosLevelId,
|
||||
PositionLevelName = p.PosLevel,
|
||||
|
|
@ -425,8 +425,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix ?? "")}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position ?? "",
|
||||
Rank = p.PosLevel ?? "",
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
PosNo = p.PosNo,
|
||||
PositionLevelId = p.PosLevelId,
|
||||
PositionLevelName = p.PosLevel,
|
||||
|
|
@ -571,8 +571,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix ?? "")}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position ?? "",
|
||||
Rank = p.PosLevel ?? "",
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
PosNo = p.PosNo,
|
||||
PositionLevelId = p.PosLevel == null
|
||||
? Guid.Parse("00000000-0000-0000-0000-000000000000")
|
||||
|
|
@ -794,8 +794,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix ?? "")}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position ?? "",
|
||||
Rank = p.PosLevel ?? "",
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
PosNo = p.PosNo,
|
||||
PositionLevelId = p.PosLevelId,
|
||||
PositionLevelName = p.PosLevel,
|
||||
|
|
@ -939,8 +939,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix ?? "")}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position ?? "",
|
||||
Rank = p.PosLevel ?? "",
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
PosNo = p.PosNo,
|
||||
PositionLevelId = p.PosLevelId,
|
||||
PositionLevelName = p.PosLevel,
|
||||
|
|
@ -1081,8 +1081,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix ?? "")}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position ?? "",
|
||||
Rank = p.PosLevel ?? "",
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
PosNo = p.PosNo,
|
||||
PositionLevelId = p.PosLevelId,
|
||||
PositionLevelName = p.PosLevel,
|
||||
|
|
@ -1301,8 +1301,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix ?? "")}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position ?? "",
|
||||
Rank = p.PosLevel ?? "",
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
PosNo = p.PosNo ?? "",
|
||||
PositionLevelId = p.PosLevelId,
|
||||
PositionLevelName = p.PosLevel,
|
||||
|
|
@ -1443,8 +1443,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix == null ? null : p.Prefix)}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position == null ? "" : p.Position,
|
||||
Rank = p.PosLevel ?? "",
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
LastInsignia = p.ProfileInsignia == null || p.ProfileInsignia.Count == 0 ? "" :
|
||||
p.ProfileInsignia
|
||||
.Where(x => x.InsigniaId.HasValue && x.InsigniaId.Value != GetInsigniaByName("เหรียญจักรพรรดิมาลา")?.Id)
|
||||
|
|
@ -1591,8 +1591,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix == null ? null : p.Prefix)}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position == null ? "" : p.Position,
|
||||
Rank = p.PosLevel ?? "",
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
LastInsignia = p.ProfileInsignia == null || p.ProfileInsignia.Count == 0 ? "" :
|
||||
p.ProfileInsignia
|
||||
.Where(x => x.InsigniaId.HasValue && x.InsigniaId.Value != GetInsigniaByName("เหรียญจักรพรรดิมาลา")?.Id)
|
||||
|
|
@ -1738,8 +1738,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix == null ? null : p.Prefix)}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position == null ? "" : p.Position,
|
||||
Rank = p.PosLevel ?? "",
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
LastInsignia = p.ProfileInsignia == null || p.ProfileInsignia.Count == 0 ? "" :
|
||||
p.ProfileInsignia
|
||||
.Where(x => x.InsigniaId.HasValue && x.InsigniaId.Value != GetInsigniaByName("เหรียญจักรพรรดิมาลา")?.Id)
|
||||
|
|
@ -1992,8 +1992,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix == null ? null : p.Prefix)}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position == null ? null : p.Position,
|
||||
Rank = p.PosLevel ?? "",
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
LastInsignia = p.ProfileInsignia == null || p.ProfileInsignia.Count == 0 ? "" :
|
||||
p.ProfileInsignia
|
||||
.Where(x => x.InsigniaId.HasValue && x.InsigniaId.Value != GetInsigniaByName("เหรียญจักรพรรดิมาลา")?.Id)
|
||||
|
|
@ -2139,8 +2139,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix == null ? null : p.Prefix)}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position == null ? null : p.Position,
|
||||
Rank = p.PosLevel ?? "",
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
LastInsignia = p.ProfileInsignia == null || p.ProfileInsignia.Count == 0 ? "" :
|
||||
p.ProfileInsignia
|
||||
.Where(x => x.InsigniaId.HasValue && x.InsigniaId.Value != GetInsigniaByName("เหรียญจักรพรรดิมาลา")?.Id)
|
||||
|
|
@ -2358,8 +2358,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix == null ? null : p.Prefix)}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position == null ? null : p.Position,
|
||||
Rank = p.PosLevel ?? "",
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
LastInsignia = p.ProfileInsignia == null || p.ProfileInsignia.Count == 0 ? "" :
|
||||
p.ProfileInsignia
|
||||
.Where(x => x.InsigniaId.HasValue && x.InsigniaId.Value != GetInsigniaByName("เหรียญจักรพรรดิมาลา")?.Id)
|
||||
|
|
@ -2510,8 +2510,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix == null ? null : p.Prefix)}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position == null ? null : p.Position,
|
||||
Rank = p.PosLevel ?? "",
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
LastInsignia = p.ProfileInsignia == null || p.ProfileInsignia.Count == 0 ? "" :
|
||||
p.ProfileInsignia
|
||||
.Where(x => x.InsigniaId.HasValue && x.InsigniaId.Value != GetInsigniaByName("เหรียญจักรพรรดิมาลา")?.Id)
|
||||
|
|
@ -2730,8 +2730,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix == null ? null : p.Prefix)}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position == null ? null : p.Position,
|
||||
Rank = p.PosLevel ?? "",
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
LastInsignia = p.ProfileInsignia == null || p.ProfileInsignia.Count == 0 ? "" :
|
||||
p.ProfileInsignia
|
||||
.Where(x => x.InsigniaId.HasValue && x.InsigniaId.Value != GetInsigniaByName("เหรียญจักรพรรดิมาลา")?.Id)
|
||||
|
|
@ -2883,8 +2883,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix == null ? null : p.Prefix)}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position == null ? null : p.Position,
|
||||
Rank = p.PosLevel ?? "",
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
LastInsignia = p.ProfileInsignia == null || p.ProfileInsignia.Count == 0 ? "" :
|
||||
p.ProfileInsignia
|
||||
.Where(x => x.InsigniaId.HasValue && x.InsigniaId.Value != GetInsigniaByName("เหรียญจักรพรรดิมาลา")?.Id)
|
||||
|
|
@ -3045,8 +3045,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix == null ? null : p.Prefix)}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position == null ? null : p.Position,
|
||||
Rank = p.PosLevel ?? "",
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
LastInsignia = p.ProfileInsignia == null || p.ProfileInsignia.Count == 0 ? "" :
|
||||
p.ProfileInsignia
|
||||
.Where(x => x.InsigniaId.HasValue && x.InsigniaId.Value != GetInsigniaByName("เหรียญจักรพรรดิมาลา")?.Id)
|
||||
|
|
@ -3292,8 +3292,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix == null ? null : p.Prefix)}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position == null ? null : p.Position,
|
||||
Rank = p.PosLevel ?? "",
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
LastInsignia = p.ProfileInsignia == null || p.ProfileInsignia.Count == 0 ? "" :
|
||||
p.ProfileInsignia
|
||||
.Where(x => x.InsigniaId.HasValue && x.InsigniaId.Value != GetInsigniaByName("เหรียญจักรพรรดิมาลา")?.Id)
|
||||
|
|
@ -3498,8 +3498,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix == null ? null : p.Prefix)}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position == null ? null : p.Position,
|
||||
Rank = p.PosLevel ?? "",
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
LastInsignia = p.ProfileInsignia == null || p.ProfileInsignia.Count == 0 ? "" :
|
||||
p.ProfileInsignia
|
||||
.Where(x => x.InsigniaId.HasValue && x.InsigniaId.Value != GetInsigniaByName("เหรียญจักรพรรดิมาลา")?.Id)
|
||||
|
|
@ -3657,8 +3657,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix == null ? null : p.Prefix)}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position == null ? null : p.Position,
|
||||
Rank = p.PosLevel ?? "",
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
LastInsignia = p.ProfileInsignia == null || p.ProfileInsignia.Count == 0 ? "" :
|
||||
p.ProfileInsignia
|
||||
.Where(x => x.InsigniaId.HasValue && x.InsigniaId.Value != GetInsigniaByName("เหรียญจักรพรรดิมาลา")?.Id)
|
||||
|
|
@ -3819,8 +3819,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix == null ? null : p.Prefix)}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position == null ? null : p.Position,
|
||||
Rank = p.PosLevel ?? "",
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
LastInsignia = p.ProfileInsignia == null || p.ProfileInsignia.Count == 0 ? "" :
|
||||
p.ProfileInsignia
|
||||
.Where(x => x.InsigniaId.HasValue && x.InsigniaId.Value != GetInsigniaByName("เหรียญจักรพรรดิมาลา")?.Id)
|
||||
|
|
@ -4065,8 +4065,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix == null ? null : p.Prefix)}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position == null ? null : p.Position,
|
||||
Rank = p.PosLevel ?? "",
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
LastInsignia = p.ProfileInsignia == null || p.ProfileInsignia.Count == 0 ? "" :
|
||||
p.ProfileInsignia
|
||||
.Where(x => x.InsigniaId.HasValue && x.InsigniaId.Value != GetInsigniaByName("เหรียญจักรพรรดิมาลา")?.Id)
|
||||
|
|
@ -4207,8 +4207,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix == null ? null : p.Prefix)}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position == null ? null : p.Position,
|
||||
Rank = p.PosLevel ?? "",
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
LastInsignia = p.ProfileInsignia == null || p.ProfileInsignia.Count == 0 ? "" :
|
||||
p.ProfileInsignia
|
||||
.Where(x => x.InsigniaId.HasValue && x.InsigniaId.Value != GetInsigniaByName("เหรียญจักรพรรดิมาลา")?.Id)
|
||||
|
|
@ -4442,8 +4442,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix == null ? null : p.Prefix)}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position == null ? null : p.Position,
|
||||
Rank = p.PosLevel ?? "",
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
LastInsignia = p.ProfileInsignia == null || p.ProfileInsignia.Count == 0 ? "" :
|
||||
p.ProfileInsignia
|
||||
.Where(x => x.InsigniaId.HasValue && x.InsigniaId.Value != GetInsigniaByName("เหรียญจักรพรรดิมาลา")?.Id)
|
||||
|
|
@ -4602,8 +4602,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix == null ? null : p.Prefix)}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position == null ? null : p.Position,
|
||||
Rank = p.PosLevel ?? "",
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
LastInsignia = p.ProfileInsignia == null || p.ProfileInsignia.Count == 0 ? "" :
|
||||
p.ProfileInsignia
|
||||
.Where(x => x.InsigniaId.HasValue && x.InsigniaId.Value != GetInsigniaByName("เหรียญจักรพรรดิมาลา")?.Id)
|
||||
|
|
@ -4764,8 +4764,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix == null ? null : p.Prefix)}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position == null ? null : p.Position,
|
||||
Rank = p.PosLevel ?? "",
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
LastInsignia = p.ProfileInsignia == null || p.ProfileInsignia.Count == 0 ? "" :
|
||||
p.ProfileInsignia
|
||||
.Where(x => x.InsigniaId.HasValue && x.InsigniaId.Value != GetInsigniaByName("เหรียญจักรพรรดิมาลา")?.Id)
|
||||
|
|
@ -5008,8 +5008,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix == null ? null : p.Prefix)}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position == null ? null : p.Position,
|
||||
Rank = p.PosLevel ?? "",
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
LastInsignia = p.ProfileInsignia == null || p.ProfileInsignia.Count == 0 ? "" :
|
||||
p.ProfileInsignia
|
||||
.Where(x => x.InsigniaId.HasValue && x.InsigniaId.Value != GetInsigniaByName("เหรียญจักรพรรดิมาลา")?.Id)
|
||||
|
|
@ -5176,8 +5176,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix == null ? null : p.Prefix)}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position == null ? null : p.Position,
|
||||
Rank = p.PosLevel ?? "",
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
LastInsignia = p.ProfileInsignia == null || p.ProfileInsignia.Count == 0 ? "" :
|
||||
p.ProfileInsignia
|
||||
.Where(x => x.InsigniaId.HasValue && x.InsigniaId.Value != GetInsigniaByName("เหรียญจักรพรรดิมาลา")?.Id)
|
||||
|
|
@ -5344,8 +5344,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix == null ? null : p.Prefix)}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position == null ? null : p.Position,
|
||||
Rank = p.PosLevel ?? "",
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
LastInsignia = p.ProfileInsignia == null || p.ProfileInsignia.Count == 0 ? "" :
|
||||
p.ProfileInsignia
|
||||
.Where(x => x.InsigniaId.HasValue && x.InsigniaId.Value != GetInsigniaByName("เหรียญจักรพรรดิมาลา")?.Id)
|
||||
|
|
@ -5594,8 +5594,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix == null ? null : p.Prefix)}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position == null ? null : p.Position,
|
||||
Rank = p.PosLevel ?? "",
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
LastInsignia = p.ProfileInsignia == null || p.ProfileInsignia.Count == 0 ? "" :
|
||||
p.ProfileInsignia
|
||||
.Where(x => x.InsigniaId.HasValue && x.InsigniaId.Value != GetInsigniaByName("เหรียญจักรพรรดิมาลา")?.Id)
|
||||
|
|
@ -5762,8 +5762,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix == null ? null : p.Prefix)}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position == null ? null : p.Position,
|
||||
Rank = p.PosLevel ?? "",
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
LastInsignia = p.ProfileInsignia == null || p.ProfileInsignia.Count == 0 ? "" :
|
||||
p.ProfileInsignia
|
||||
.Where(x => x.InsigniaId.HasValue && x.InsigniaId.Value != GetInsigniaByName("เหรียญจักรพรรดิมาลา")?.Id)
|
||||
|
|
@ -5930,8 +5930,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix == null ? null : p.Prefix)}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position == null ? null : p.Position,
|
||||
Rank = p.PosLevel ?? "",
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
LastInsignia = p.ProfileInsignia == null || p.ProfileInsignia.Count == 0 ? "" :
|
||||
p.ProfileInsignia
|
||||
.Where(x => x.InsigniaId.HasValue && x.InsigniaId.Value != GetInsigniaByName("เหรียญจักรพรรดิมาลา")?.Id)
|
||||
|
|
@ -6176,8 +6176,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix == null ? null : p.Prefix)}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position == null ? "" : p.Position,
|
||||
Rank = p.PosLevel ?? "",
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
LastInsignia = p.ProfileInsignia == null || p.ProfileInsignia.Count == 0 ? "" :
|
||||
p.ProfileInsignia
|
||||
.Where(x => x.InsigniaId.HasValue && x.InsigniaId.Value != GetInsigniaByName("เหรียญจักรพรรดิมาลา")?.Id)
|
||||
|
|
@ -6334,8 +6334,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix == null ? null : p.Prefix)}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position == null ? "" : p.Position,
|
||||
Rank = p.PosLevel ?? "",
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
LastInsignia = p.ProfileInsignia == null || p.ProfileInsignia.Count == 0 ? "" :
|
||||
p.ProfileInsignia
|
||||
.Where(x => x.InsigniaId.HasValue && x.InsigniaId.Value != GetInsigniaByName("เหรียญจักรพรรดิมาลา")?.Id)
|
||||
|
|
@ -6563,8 +6563,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix == null ? null : p.Prefix)}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position == null ? "" : p.Position,
|
||||
Rank = p.PosLevel ?? "",
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
LastInsignia = p.ProfileInsignia == null || p.ProfileInsignia.Count == 0 ? "" :
|
||||
p.ProfileInsignia
|
||||
.Where(x => x.InsigniaId.HasValue && x.InsigniaId.Value != GetInsigniaByName("เหรียญจักรพรรดิมาลา")?.Id)
|
||||
|
|
@ -6725,8 +6725,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix == null ? null : p.Prefix)}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position == null ? "" : p.Position,
|
||||
Rank = p.PosLevel ?? "",
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
LastInsignia = p.ProfileInsignia == null || p.ProfileInsignia.Count == 0 ? "" :
|
||||
p.ProfileInsignia
|
||||
.Where(x => x.InsigniaId.HasValue && x.InsigniaId.Value != GetInsigniaByName("เหรียญจักรพรรดิมาลา")?.Id)
|
||||
|
|
@ -6888,8 +6888,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix == null ? null : p.Prefix)}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position == null ? null : p.Position,
|
||||
Rank = p.PosLevel ?? "",
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
LastInsignia = p.ProfileInsignia == null || p.ProfileInsignia.Count == 0 ? "" :
|
||||
p.ProfileInsignia
|
||||
.Where(x => x.InsigniaId.HasValue && x.InsigniaId.Value != GetInsigniaByName("เหรียญจักรพรรดิมาลา")?.Id)
|
||||
|
|
@ -7130,8 +7130,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix == null ? null : p.Prefix)}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position == null ? null : p.Position,
|
||||
Rank = p.PosLevel ?? "",
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
LastInsignia = p.ProfileInsignia == null || p.ProfileInsignia.Count == 0 ? "" :
|
||||
p.ProfileInsignia
|
||||
.Where(x => x.InsigniaId.HasValue && x.InsigniaId.Value != GetInsigniaByName("เหรียญจักรพรรดิมาลา")?.Id)
|
||||
|
|
@ -7292,8 +7292,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix == null ? null : p.Prefix)}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position == null ? null : p.Position,
|
||||
Rank = p.PosLevel ?? "",
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
LastInsignia = p.ProfileInsignia == null || p.ProfileInsignia.Count == 0 ? "" :
|
||||
p.ProfileInsignia
|
||||
.Where(x => x.InsigniaId.HasValue && x.InsigniaId.Value != GetInsigniaByName("เหรียญจักรพรรดิมาลา")?.Id)
|
||||
|
|
@ -7454,8 +7454,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix == null ? null : p.Prefix)}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position == null ? null : p.Position,
|
||||
Rank = p.PosLevel ?? "",
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
LastInsignia = p.ProfileInsignia == null || p.ProfileInsignia.Count == 0 ? "" :
|
||||
p.ProfileInsignia
|
||||
.Where(x => x.InsigniaId.HasValue && x.InsigniaId.Value != GetInsigniaByName("เหรียญจักรพรรดิมาลา")?.Id)
|
||||
|
|
@ -7667,8 +7667,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix == null ? null : p.Prefix)}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position == null ? null : p.Position,
|
||||
Rank = p.PosLevel ?? "",
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
LastInsignia = p.ProfileInsignia == null || p.ProfileInsignia.Count == 0 ? "" :
|
||||
p.ProfileInsignia
|
||||
.Where(x => x.InsigniaId.HasValue && x.InsigniaId.Value != GetInsigniaByName("เหรียญจักรพรรดิมาลา")?.Id)
|
||||
|
|
@ -7835,8 +7835,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix == null ? null : p.Prefix)}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position == null ? null : p.Position,
|
||||
Rank = p.PosLevel ?? "",
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
LastInsignia = p.ProfileInsignia == null || p.ProfileInsignia.Count == 0 ? "" :
|
||||
p.ProfileInsignia
|
||||
.Where(x => x.InsigniaId.HasValue && x.InsigniaId.Value != GetInsigniaByName("เหรียญจักรพรรดิมาลา")?.Id)
|
||||
|
|
@ -8003,8 +8003,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix == null ? null : p.Prefix)}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position == null ? null : p.Position,
|
||||
Rank = p.PosLevel ?? "",
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
LastInsignia = p.ProfileInsignia == null || p.ProfileInsignia.Count == 0 ? "" :
|
||||
p.ProfileInsignia
|
||||
.Where(x => x.InsigniaId.HasValue && x.InsigniaId.Value != GetInsigniaByName("เหรียญจักรพรรดิมาลา")?.Id)
|
||||
|
|
@ -8625,8 +8625,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
FullName = $"{(p.Prefix ?? "")}{p.FirstName} {p.LastName}",
|
||||
Position = p.Position ?? "",
|
||||
Rank = p.PosLevel ?? "",
|
||||
ProfileDateAppoint = p.DateAppoint.Value,
|
||||
GovAge = p.DateAppoint.Value.CalculateGovAgeStr(0, 0),
|
||||
ProfileDateAppoint = p.DateAppoint!.Value,
|
||||
GovAge = p.DateStart!.Value.CalculateGovAgeStr(0, 0),
|
||||
PosNo = p.PosNo,
|
||||
PositionLevelId = p.PosLevelId,
|
||||
PositionLevelName = p.PosLevel,
|
||||
|
|
|
|||
|
|
@ -2,8 +2,11 @@
|
|||
using BMA.EHR.Domain.Models.Base;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Newtonsoft.Json;
|
||||
using System.IO.Pipes;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Security.Claims;
|
||||
using System.Text;
|
||||
|
||||
namespace BMA.EHR.Application.Repositories.Leaves
|
||||
{
|
||||
|
|
@ -43,6 +46,38 @@ namespace BMA.EHR.Application.Repositories.Leaves
|
|||
|
||||
#region " Methods "
|
||||
|
||||
public async Task<string> PostExternalAPIAsync(string apiPath, string accessToken, object? body, string apiKey, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
// กำหนด timeout เป็น 30 นาที
|
||||
using var timeoutCts = new CancellationTokenSource(TimeSpan.FromMinutes(30));
|
||||
using var combinedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutCts.Token);
|
||||
var json = JsonConvert.SerializeObject(body);
|
||||
var stringContent = new StringContent(json, Encoding.UTF8, "application/json");
|
||||
//stringContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
|
||||
|
||||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api-key", apiKey);
|
||||
var _res = await client.PostAsync(apiPath, stringContent, combinedCts.Token);
|
||||
if (_res.IsSuccessStatusCode)
|
||||
{
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
|
||||
return _result;
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public virtual async Task<IReadOnlyList<T>> GetAllAsync()
|
||||
{
|
||||
return await _dbSet.ToListAsync();
|
||||
|
|
@ -68,6 +103,24 @@ namespace BMA.EHR.Application.Repositories.Leaves
|
|||
return entity;
|
||||
}
|
||||
|
||||
public virtual async Task<IReadOnlyList<T>> AddRangeAsync(List<T> entities)
|
||||
{
|
||||
foreach (var entity in entities)
|
||||
{
|
||||
if (entity is EntityBase)
|
||||
{
|
||||
(entity as EntityBase).CreatedUserId = UserId ?? "";
|
||||
(entity as EntityBase).CreatedFullName = FullName ?? "System Administrator";
|
||||
(entity as EntityBase).CreatedAt = DateTime.Now;
|
||||
}
|
||||
}
|
||||
|
||||
await _dbSet.AddRangeAsync(entities);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
|
||||
return entities;
|
||||
}
|
||||
|
||||
public virtual async Task<T> UpdateAsync(T entity)
|
||||
{
|
||||
if (entity is EntityBase)
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ using BMA.EHR.Domain.Shared;
|
|||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
||||
{
|
||||
|
|
@ -23,6 +24,12 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
private readonly IConfiguration _configuration;
|
||||
private readonly EmailSenderService _emailSenderService;
|
||||
|
||||
/// <summary>
|
||||
/// Keyed locks to serialize get-or-create for LeaveBeginning rows by (ProfileId, LeaveYear, LeaveTypeId).
|
||||
/// Prevents duplicate inserts when concurrent requests (e.g. UI calling /user/check twice) hit the same key.
|
||||
/// </summary>
|
||||
private static readonly ConcurrentDictionary<string, SemaphoreSlim> _getOrAddLocks = new();
|
||||
|
||||
#endregion
|
||||
|
||||
#region " Constructor and Destuctor "
|
||||
|
|
@ -79,7 +86,8 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
|
||||
public async Task UpdateLeaveUsageAsync(int year, Guid typeId, Guid userId, double day)
|
||||
{
|
||||
var pf = await _userProfileRepository.GetProfileByKeycloakIdAsync(userId, AccessToken);
|
||||
// var pf = await _userProfileRepository.GetProfileByKeycloakIdAsync(userId, AccessToken);
|
||||
var pf = await _userProfileRepository.GetProfileByKeycloakIdNew2Async(userId, AccessToken);
|
||||
if (pf == null)
|
||||
{
|
||||
throw new Exception(GlobalMessages.DataNotFound);
|
||||
|
|
@ -98,9 +106,56 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task UpdateLeaveCountAsync(int year, Guid typeId, Guid userId, int count)
|
||||
{
|
||||
// var pf = await _userProfileRepository.GetProfileByKeycloakIdAsync(userId, AccessToken);
|
||||
var pf = await _userProfileRepository.GetProfileByKeycloakIdNew2Async(userId, AccessToken);
|
||||
if (pf == null)
|
||||
{
|
||||
throw new Exception(GlobalMessages.DataNotFound);
|
||||
}
|
||||
|
||||
var data = await _dbContext.Set<LeaveBeginning>()
|
||||
.Include(x => x.LeaveType)
|
||||
.FirstOrDefaultAsync(x => x.LeaveYear == year && x.LeaveTypeId == typeId && x.ProfileId == pf.Id);
|
||||
|
||||
if (data == null)
|
||||
{
|
||||
throw new Exception(GlobalMessages.DataNotFound);
|
||||
}
|
||||
data.LeaveCount += count;
|
||||
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task ProcessEarlyLeaveRequest(int year)
|
||||
{
|
||||
// Get Early Leave Request (กรองตามปีงบประมาณ: 1 ต.ค. (year-1) – 30 ก.ย. (year))
|
||||
var fiscalStart = new DateTime(year - 1, 10, 1);
|
||||
var fiscalEnd = new DateTime(year, 9, 30);
|
||||
|
||||
var leaveReq = await _dbContext.Set<LeaveRequest>()
|
||||
.Include(x => x.Type)
|
||||
.Where(x => x.LeaveStatus == "APPROVE")
|
||||
.Where(x => x.LeaveStartDate.Date <= fiscalEnd && x.LeaveEndDate.Date >= fiscalStart)
|
||||
.ToListAsync();
|
||||
|
||||
foreach (var leave in leaveReq)
|
||||
{
|
||||
await GetByYearAndTypeIdForUserWithUpdateAsync(year, leave.Type.Id, leave.KeycloakUserId);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task ProcessEarlyLeaveRequestSchedule()
|
||||
{
|
||||
int year = DateTime.Now.Year;
|
||||
await ProcessEarlyLeaveRequest(year);
|
||||
}
|
||||
|
||||
public async Task<LeaveBeginning?> GetByYearAndTypeIdForUserAsync(int year, Guid typeId, Guid userId)
|
||||
{
|
||||
var pf = await _userProfileRepository.GetProfileByKeycloakIdAsync(userId, AccessToken);
|
||||
// var pf = await _userProfileRepository.GetProfileByKeycloakIdAsync(userId, AccessToken);
|
||||
var pf = await _userProfileRepository.GetProfileByKeycloakIdNew2Async(userId, AccessToken);
|
||||
if (pf == null)
|
||||
{
|
||||
throw new Exception(GlobalMessages.DataNotFound);
|
||||
|
|
@ -110,22 +165,22 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
|
||||
var leaveType = await _dbContext.Set<LeaveType>().FirstOrDefaultAsync(x => x.Id == typeId);
|
||||
|
||||
var data = await _dbContext.Set<LeaveBeginning>()
|
||||
.Include(x => x.LeaveType)
|
||||
.FirstOrDefaultAsync(x => x.LeaveYear == year && x.LeaveTypeId == typeId && x.ProfileId == pf.Id);
|
||||
|
||||
if (data == null)
|
||||
LeaveBeginning Factory()
|
||||
{
|
||||
var limit = 0.0;
|
||||
|
||||
var prev = await _dbContext.Set<LeaveBeginning>()
|
||||
var prev = _dbContext.Set<LeaveBeginning>()
|
||||
.Include(x => x.LeaveType)
|
||||
.FirstOrDefaultAsync(x => x.LeaveYear == year - 1 && x.LeaveTypeId == typeId && x.ProfileId == pf.Id);
|
||||
.FirstOrDefault(x => x.LeaveYear == year - 1 && x.LeaveTypeId == typeId && x.ProfileId == pf.Id);
|
||||
|
||||
// คำนวณปีงบประมาณจาก startDate (ปีงบประมาณเริ่ม 1 ต.ค. และสิ้นสุด 30 ก.ย.)
|
||||
var isCurrentYear = DateTime.Now.Year == year;
|
||||
|
||||
|
||||
var prevRemain = 0.0;
|
||||
if (prev != null)
|
||||
{
|
||||
prevRemain = prev.LeaveDays - prev.LeaveDaysUsed;
|
||||
prevRemain = isCurrentYear ? prev.LeaveDays - (prev.LeaveDaysUsed ?? 0.0) : 0.0;
|
||||
}
|
||||
|
||||
if (govAge >= 180)
|
||||
|
|
@ -146,7 +201,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
limit = 0.0;
|
||||
}
|
||||
|
||||
data = new LeaveBeginning
|
||||
return new LeaveBeginning
|
||||
{
|
||||
LeaveYear = year,
|
||||
LeaveTypeId = typeId,
|
||||
|
|
@ -162,36 +217,110 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
Child3DnaId = pf.Child3DnaId,
|
||||
Child4DnaId = pf.Child4DnaId
|
||||
};
|
||||
}
|
||||
|
||||
_dbContext.Set<LeaveBeginning>().Add(data);
|
||||
return await GetOrAddForUserAsync(year, typeId, pf.Id, Factory);
|
||||
}
|
||||
|
||||
public async Task<LeaveBeginning?> GetByYearAndTypeIdForUserWithUpdateAsync(int year, Guid typeId, Guid userId)
|
||||
{
|
||||
// var pf = await _userProfileRepository.GetProfileByKeycloakIdAsync(userId, AccessToken);
|
||||
var pf = await _userProfileRepository.GetProfileByKeycloakIdNew2Async(userId, AccessToken);
|
||||
if (pf == null)
|
||||
{
|
||||
throw new Exception(GlobalMessages.DataNotFound);
|
||||
}
|
||||
|
||||
var govAge = (pf?.DateStart?.Date ?? DateTime.Now.Date).DiffDay(DateTime.Now.Date);
|
||||
|
||||
var leaveType = await _dbContext.Set<LeaveType>().FirstOrDefaultAsync(x => x.Id == typeId);
|
||||
|
||||
|
||||
var limit = 0.0;
|
||||
|
||||
var prev = _dbContext.Set<LeaveBeginning>()
|
||||
.Include(x => x.LeaveType)
|
||||
.FirstOrDefault(x => x.LeaveYear == year - 1 && x.LeaveTypeId == typeId && x.ProfileId == pf.Id);
|
||||
|
||||
var prevRemain = 0.0;
|
||||
|
||||
|
||||
|
||||
if (prev != null)
|
||||
{
|
||||
prevRemain = prev.LeaveDays - (prev.LeaveDaysUsed ?? 0.0);
|
||||
}
|
||||
|
||||
if (govAge >= 180)
|
||||
{
|
||||
if (govAge >= 3650)
|
||||
{
|
||||
limit = 10 + prevRemain;
|
||||
if (limit > 30) limit = 30;
|
||||
}
|
||||
else
|
||||
{
|
||||
limit = 10 + prevRemain;
|
||||
if (limit > 20) limit = 20;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
limit = 0.0;
|
||||
}
|
||||
|
||||
var data = await _dbContext.Set<LeaveBeginning>()
|
||||
.Where(x => x.LeaveYear == year && x.LeaveTypeId == typeId && x.ProfileId == pf.Id)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
if (data != null)
|
||||
{
|
||||
data.LeaveDays = leaveType?.Code == "LV-005" ? limit : 0;
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
// return new LeaveBeginning
|
||||
// {
|
||||
// LeaveYear = year,
|
||||
// LeaveTypeId = typeId,
|
||||
// ProfileId = pf.Id,
|
||||
// Prefix = pf.Prefix,
|
||||
// FirstName = pf.FirstName,
|
||||
// LastName = pf.LastName,
|
||||
// LeaveDaysUsed = 0,
|
||||
// LeaveDays = leaveType?.Code == "LV-005" ? limit : 0,
|
||||
// RootDnaId = pf.RootDnaId,
|
||||
// Child1DnaId = pf.Child1DnaId,
|
||||
// Child2DnaId = pf.Child2DnaId,
|
||||
// Child3DnaId = pf.Child3DnaId,
|
||||
// Child4DnaId = pf.Child4DnaId
|
||||
// };
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public async Task<LeaveBeginning?> GetByYearAndTypeIdForUser(int year, Guid typeId, GetProfileByKeycloakIdDto? pf)
|
||||
{
|
||||
var govAge = (pf?.DateStart?.Date ?? DateTime.Now.Date).DiffDay(DateTime.Now.Date);
|
||||
|
||||
var leaveType = await _dbContext.Set<LeaveType>().FirstOrDefaultAsync(x => x.Id == typeId);
|
||||
|
||||
var data = await _dbContext.Set<LeaveBeginning>()
|
||||
.Include(x => x.LeaveType)
|
||||
.FirstOrDefaultAsync(x => x.LeaveYear == year && x.LeaveTypeId == typeId && x.ProfileId == pf.Id);
|
||||
|
||||
if (data == null)
|
||||
LeaveBeginning Factory()
|
||||
{
|
||||
var limit = 0.0;
|
||||
|
||||
var prev = await _dbContext.Set<LeaveBeginning>()
|
||||
var prev = _dbContext.Set<LeaveBeginning>()
|
||||
.Include(x => x.LeaveType)
|
||||
.FirstOrDefaultAsync(x => x.LeaveYear == year - 1 && x.LeaveTypeId == typeId && x.ProfileId == pf.Id);
|
||||
.FirstOrDefault(x => x.LeaveYear == year - 1 && x.LeaveTypeId == typeId && x.ProfileId == pf.Id);
|
||||
|
||||
// คำนวณปีงบประมาณจาก startDate (ปีงบประมาณเริ่ม 1 ต.ค. และสิ้นสุด 30 ก.ย.)
|
||||
var isCurrentYear = DateTime.Now.Year == year;
|
||||
|
||||
var prevRemain = 0.0;
|
||||
if (prev != null)
|
||||
{
|
||||
prevRemain = prev.LeaveDays - prev.LeaveDaysUsed;
|
||||
prevRemain = isCurrentYear ? prev.LeaveDays - (prev.LeaveDaysUsed ?? 0.0) : 0.0;
|
||||
}
|
||||
|
||||
if (govAge >= 180)
|
||||
|
|
@ -212,7 +341,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
limit = 0.0;
|
||||
}
|
||||
|
||||
data = new LeaveBeginning
|
||||
return new LeaveBeginning
|
||||
{
|
||||
LeaveYear = year,
|
||||
LeaveTypeId = typeId,
|
||||
|
|
@ -228,17 +357,15 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
Child3DnaId = pf.Child3DnaId,
|
||||
Child4DnaId = pf.Child4DnaId
|
||||
};
|
||||
|
||||
_dbContext.Set<LeaveBeginning>().Add(data);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
return data;
|
||||
return await GetOrAddForUserAsync(year, typeId, pf.Id, Factory);
|
||||
}
|
||||
|
||||
public async Task<LeaveBeginning?> GetByYearAndTypeIdForUser2Async(int year, Guid typeId, Guid userId)
|
||||
{
|
||||
var pf = await _userProfileRepository.GetProfileByKeycloakIdAsync(userId, AccessToken);
|
||||
// var pf = await _userProfileRepository.GetProfileByKeycloakIdAsync(userId, AccessToken);
|
||||
var pf = await _userProfileRepository.GetProfileByKeycloakIdNew2Async(userId, AccessToken);
|
||||
if (pf == null)
|
||||
{
|
||||
return null;
|
||||
|
|
@ -248,22 +375,21 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
|
||||
var leaveType = await _dbContext.Set<LeaveType>().FirstOrDefaultAsync(x => x.Id == typeId);
|
||||
|
||||
var data = await _dbContext.Set<LeaveBeginning>()
|
||||
.Include(x => x.LeaveType)
|
||||
.FirstOrDefaultAsync(x => x.LeaveYear == year && x.LeaveTypeId == typeId && x.ProfileId == pf.Id);
|
||||
|
||||
if (data == null)
|
||||
LeaveBeginning Factory()
|
||||
{
|
||||
var limit = 0.0;
|
||||
|
||||
var prev = await _dbContext.Set<LeaveBeginning>()
|
||||
var prev = _dbContext.Set<LeaveBeginning>()
|
||||
.Include(x => x.LeaveType)
|
||||
.FirstOrDefaultAsync(x => x.LeaveYear == year - 1 && x.LeaveTypeId == typeId && x.ProfileId == pf.Id);
|
||||
.FirstOrDefault(x => x.LeaveYear == year - 1 && x.LeaveTypeId == typeId && x.ProfileId == pf.Id);
|
||||
|
||||
// คำนวณปีงบประมาณจาก startDate (ปีงบประมาณเริ่ม 1 ต.ค. และสิ้นสุด 30 ก.ย.)
|
||||
var isCurrentYear = DateTime.Now.Year == year;
|
||||
|
||||
var prevRemain = 0.0;
|
||||
if (prev != null)
|
||||
{
|
||||
prevRemain = prev.LeaveDays - prev.LeaveDaysUsed;
|
||||
prevRemain = isCurrentYear ? prev.LeaveDays - (prev.LeaveDaysUsed ?? 0.0) : 0.0;
|
||||
}
|
||||
|
||||
if (govAge >= 180)
|
||||
|
|
@ -284,7 +410,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
limit = 0.0;
|
||||
}
|
||||
|
||||
data = new LeaveBeginning
|
||||
return new LeaveBeginning
|
||||
{
|
||||
LeaveYear = year,
|
||||
LeaveTypeId = typeId,
|
||||
|
|
@ -300,17 +426,59 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
Child3DnaId = pf.Child3DnaId,
|
||||
Child4DnaId = pf.Child4DnaId
|
||||
};
|
||||
|
||||
_dbContext.Set<LeaveBeginning>().Add(data);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
return data;
|
||||
return await GetOrAddForUserAsync(year, typeId, pf.Id, Factory);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get-or-create a LeaveBeginning row for (ProfileId, LeaveYear, LeaveTypeId) with concurrency protection.
|
||||
/// Uses a keyed SemaphoreSlim to serialize within-process requests, and re-queries after acquiring the lock.
|
||||
/// If a cross-process insert wins (unique index violation), the duplicate key exception is caught and the row
|
||||
/// created by the winner is returned.
|
||||
/// </summary>
|
||||
private async Task<LeaveBeginning?> GetOrAddForUserAsync(int year, Guid typeId, Guid profileId, Func<LeaveBeginning> factory)
|
||||
{
|
||||
var key = $"{profileId}_{year}_{typeId}";
|
||||
var semaphore = _getOrAddLocks.GetOrAdd(key, _ => new SemaphoreSlim(1, 1));
|
||||
await semaphore.WaitAsync();
|
||||
try
|
||||
{
|
||||
// Re-query inside the lock — another thread may have created it while we waited.
|
||||
var existing = await _dbContext.Set<LeaveBeginning>()
|
||||
.Include(x => x.LeaveType)
|
||||
.FirstOrDefaultAsync(x => x.LeaveYear == year && x.LeaveTypeId == typeId && x.ProfileId == profileId);
|
||||
if (existing != null)
|
||||
{
|
||||
return existing;
|
||||
}
|
||||
|
||||
var entity = factory();
|
||||
_dbContext.Set<LeaveBeginning>().Add(entity);
|
||||
try
|
||||
{
|
||||
await _dbContext.SaveChangesAsync();
|
||||
return entity;
|
||||
}
|
||||
catch (DbUpdateException)
|
||||
{
|
||||
// Cross-process/cross-server race hit the unique index (IX_LeaveBeginnings_ProfileId_LeaveYear_LeaveTypeId).
|
||||
// Detach the failed insert and return the row created by the winner.
|
||||
_dbContext.Detach(entity);
|
||||
var winner = await _dbContext.Set<LeaveBeginning>()
|
||||
.Include(x => x.LeaveType)
|
||||
.FirstOrDefaultAsync(x => x.LeaveYear == year && x.LeaveTypeId == typeId && x.ProfileId == profileId);
|
||||
return winner;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
semaphore.Release();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<List<LeaveBeginning>> GetAllByYearAndTypeAsync(int year, Guid typeId, List<ProfileData> userIdList)
|
||||
{
|
||||
|
||||
|
||||
var updateList = new List<LeaveBeginning>();
|
||||
var result = new List<LeaveBeginning>();
|
||||
|
|
@ -351,7 +519,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
var prevRemain = 0.0;
|
||||
if (prev != null)
|
||||
{
|
||||
prevRemain = prev.LeaveDays - prev.LeaveDaysUsed;
|
||||
prevRemain = prev.LeaveDays - (prev.LeaveDaysUsed ?? 0.0);
|
||||
}
|
||||
|
||||
if (govAge >= 180)
|
||||
|
|
@ -413,5 +581,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
public string LastName { get; set; } = string.Empty;
|
||||
|
||||
public DateTime? DateStart { get; set; } = null;
|
||||
|
||||
public DateTime? DateAppoint { get; set; } = null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ using Microsoft.Extensions.Configuration;
|
|||
using System.IO.Compression;
|
||||
using System.Net.Http.Headers;
|
||||
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
|
||||
{
|
||||
|
|
@ -29,6 +31,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
private readonly MinIOLeaveService _minIOService;
|
||||
|
||||
private readonly LeaveBeginningRepository _leaveBeginningRepository;
|
||||
private readonly ProcessUserTimeStampRepository _processUserTimeStampRepository;
|
||||
|
||||
private readonly string URL = string.Empty;
|
||||
|
||||
|
|
@ -44,7 +47,8 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
EmailSenderService emailSenderService,
|
||||
IApplicationDBContext appDbContext,
|
||||
MinIOLeaveService minIOService,
|
||||
LeaveBeginningRepository leaveBeginningRepository) : base(dbContext, httpContextAccessor)
|
||||
LeaveBeginningRepository leaveBeginningRepository,
|
||||
ProcessUserTimeStampRepository processUserTimeStampRepository) : base(dbContext, httpContextAccessor)
|
||||
{
|
||||
_dbContext = dbContext;
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
|
|
@ -58,6 +62,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
Console.WriteLine($"URL : {URL}");
|
||||
_minIOService = minIOService;
|
||||
_leaveBeginningRepository = leaveBeginningRepository;
|
||||
_processUserTimeStampRepository = processUserTimeStampRepository;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
@ -253,7 +258,8 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
|
||||
public async Task<List<LeaveRequest>> GetLeaveRequestByYearAsync(int year, Guid userId)
|
||||
{
|
||||
var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(userId, AccessToken);
|
||||
// var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(userId, AccessToken);
|
||||
var profile = await _userProfileRepository.GetProfileByKeycloakIdNew2Async(userId, AccessToken);
|
||||
|
||||
if (profile == null)
|
||||
{
|
||||
|
|
@ -306,11 +312,11 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
rawData = rawData
|
||||
.Where(x => x.RootDnaId == Guid.Parse(nodeId!));
|
||||
}
|
||||
else if (role == "PARENT")
|
||||
{
|
||||
rawData = rawData
|
||||
.Where(x => x.RootDnaId == Guid.Parse(nodeId!) && x.Child1DnaId != null);
|
||||
}
|
||||
// else if (role == "PARENT")
|
||||
// {
|
||||
// rawData = rawData
|
||||
// .Where(x => x.RootDnaId == Guid.Parse(nodeId!) && x.Child1DnaId != null);
|
||||
// }
|
||||
else if (role == "NORMAL")
|
||||
{
|
||||
rawData = rawData
|
||||
|
|
@ -353,7 +359,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
var rawData = _dbContext.Set<LeaveRequest>().AsNoTracking()
|
||||
.Include(x => x.Type)
|
||||
.Where(x => x.LeaveStatus != "DRAFT")
|
||||
.OrderByDescending(x => x.CreatedAt)
|
||||
.OrderByDescending(x => (x.DateSendLeave ?? x.CreatedAt))
|
||||
.AsQueryable();
|
||||
|
||||
if (year != 0)
|
||||
|
|
@ -379,7 +385,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
var rawData = _dbContext.Set<LeaveRequest>().AsNoTracking()
|
||||
.Include(x => x.Type)
|
||||
.Where(x => x.LeaveStatus != "DRAFT")
|
||||
.OrderByDescending(x => x.CreatedAt)
|
||||
.OrderByDescending(x => (x.DateSendLeave ?? x.CreatedAt))
|
||||
.AsQueryable();
|
||||
// fix issue : 1830
|
||||
if (year != 0)
|
||||
|
|
@ -420,11 +426,11 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
rawData = rawData
|
||||
.Where(x => x.RootDnaId == Guid.Parse(nodeId!));
|
||||
}
|
||||
else if (role == "PARENT")
|
||||
{
|
||||
rawData = rawData
|
||||
.Where(x => x.RootDnaId == Guid.Parse(nodeId!) && x.Child1DnaId != null);
|
||||
}
|
||||
// else if (role == "PARENT")
|
||||
// {
|
||||
// rawData = rawData
|
||||
// .Where(x => x.RootDnaId == Guid.Parse(nodeId!) && x.Child1DnaId != null);
|
||||
// }
|
||||
else if (role == "NORMAL")
|
||||
{
|
||||
rawData = rawData
|
||||
|
|
@ -446,7 +452,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
.Include(x => x.Type)
|
||||
.Where(x => keycloakIdList.Contains(x.KeycloakUserId))
|
||||
.Where(x => x.LeaveStatus != "DRAFT")
|
||||
.OrderByDescending(x => x.CreatedAt)
|
||||
.OrderByDescending(x =>(x.DateSendLeave ?? x.CreatedAt))
|
||||
.AsQueryable();
|
||||
|
||||
if (year != 0)
|
||||
|
|
@ -495,7 +501,8 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
|
||||
public async Task<double> GetSumLeaveByTypeForUserAsync(Guid keycloakUserId, Guid leaveTypeId, int year)
|
||||
{
|
||||
var pf = await _userProfileRepository.GetProfileByKeycloakIdAsync(keycloakUserId, AccessToken);
|
||||
// var pf = await _userProfileRepository.GetProfileByKeycloakIdAsync(keycloakUserId, AccessToken);
|
||||
var pf = await _userProfileRepository.GetProfileByKeycloakIdNew2Async(keycloakUserId, AccessToken);
|
||||
if (pf == null)
|
||||
throw new Exception(GlobalMessages.DataNotFound);
|
||||
|
||||
|
|
@ -520,7 +527,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
//.Where(x => x.LeaveStatus != "REJECT" && x.LeaveStatus != "DELETE")
|
||||
.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)
|
||||
|
|
@ -556,6 +563,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
var data = await _dbContext.Set<LeaveRequest>().AsQueryable().AsNoTracking()
|
||||
.Include(x => x.Type)
|
||||
.Where(x => x.LeaveStartDate.Date < beforeDate.Date)
|
||||
//.Where(x => x.CreatedAt < beforeDate)
|
||||
.Where(x => x.KeycloakUserId == keycloakUserId)
|
||||
.Where(x => x.Type.Id == leaveTypeId)
|
||||
.Where(x => x.LeaveStatus == "APPROVE" || x.LeaveStatus == "DELETING")
|
||||
|
|
@ -566,6 +574,22 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
return data;
|
||||
}
|
||||
|
||||
public async Task<LeaveRequest?> GetLastLeaveRequestByTypeForUserAsync2(Guid keycloakUserId, Guid leaveTypeId, DateTime beforeDate)
|
||||
{
|
||||
var data = await _dbContext.Set<LeaveRequest>().AsQueryable().AsNoTracking()
|
||||
.Include(x => x.Type)
|
||||
//.Where(x => x.LeaveStartDate.Date < beforeDate.Date)
|
||||
.Where(x => (x.DateSendLeave ?? x.CreatedAt) < beforeDate)
|
||||
.Where(x => x.KeycloakUserId == keycloakUserId)
|
||||
.Where(x => x.Type.Id == leaveTypeId)
|
||||
.Where(x => x.LeaveStatus == "APPROVE" || x.LeaveStatus == "DELETING")
|
||||
//.Where(x => x.LeaveStatus != "REJECT" && x.LeaveStatus != "DELETE")
|
||||
.OrderByDescending(x => (x.DateSendLeave ?? x.CreatedAt))
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public async Task<List<LeaveRequest>> GetCancelLeaveRequestForAdminAsync(int year, Guid type, string status, string role, string? nodeId, int? node)
|
||||
{
|
||||
var rawData = _dbContext.Set<LeaveRequest>().AsNoTracking()
|
||||
|
|
@ -608,11 +632,11 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
rawData = rawData
|
||||
.Where(x => x.RootDnaId == Guid.Parse(nodeId!));
|
||||
}
|
||||
else if (role == "PARENT")
|
||||
{
|
||||
rawData = rawData
|
||||
.Where(x => x.RootDnaId == Guid.Parse(nodeId!) && x.Child1DnaId != null);
|
||||
}
|
||||
// else if (role == "PARENT")
|
||||
// {
|
||||
// rawData = rawData
|
||||
// .Where(x => x.RootDnaId == Guid.Parse(nodeId!) && x.Child1DnaId != null);
|
||||
// }
|
||||
else if (role == "NORMAL")
|
||||
{
|
||||
rawData = rawData
|
||||
|
|
@ -631,7 +655,8 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
{
|
||||
try
|
||||
{
|
||||
var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(data.KeycloakUserId, AccessToken ?? "");
|
||||
// var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(data.KeycloakUserId, AccessToken ?? "");
|
||||
var profile = await _userProfileRepository.GetProfileByKeycloakIdNew2Async(data.KeycloakUserId, AccessToken ?? "");
|
||||
if (profile == null)
|
||||
{
|
||||
throw new Exception(GlobalMessages.DataNotFound);
|
||||
|
|
@ -656,6 +681,9 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
thisYear = thisYear + 1;
|
||||
}
|
||||
await _leaveBeginningRepository.UpdateLeaveUsageAsync(thisYear, data.Type.Id, data.KeycloakUserId, -1 * data.LeaveTotal);
|
||||
// update leave count ลดลง 1 ครั้ง
|
||||
await _leaveBeginningRepository.UpdateLeaveCountAsync(thisYear, data.Type.Id, data.KeycloakUserId, -1);
|
||||
|
||||
|
||||
var _baseAPI = _configuration["API"];
|
||||
var apiUrlSalary = $"{_baseAPI}/org/profile/leave/cancel/{data.Id}";
|
||||
|
|
@ -704,7 +732,8 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
throw new Exception(GlobalMessages.DataNotFound);
|
||||
}
|
||||
|
||||
var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(rawData.KeycloakUserId, AccessToken ?? "");
|
||||
// var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(rawData.KeycloakUserId, AccessToken ?? "");
|
||||
var profile = await _userProfileRepository.GetProfileByKeycloakIdNew2Async(rawData.KeycloakUserId, AccessToken ?? "");
|
||||
if (profile == null)
|
||||
{
|
||||
throw new Exception(GlobalMessages.DataNotFound);
|
||||
|
|
@ -729,6 +758,8 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
}
|
||||
|
||||
await _leaveBeginningRepository.UpdateLeaveUsageAsync(thisYear, rawData.Type.Id, rawData.KeycloakUserId, -1 * rawData.LeaveTotal);
|
||||
// update leave count ลดลง 1 ครั้ง
|
||||
await _leaveBeginningRepository.UpdateLeaveCountAsync(thisYear, rawData.Type.Id, rawData.KeycloakUserId, -1);
|
||||
|
||||
var _baseAPI = _configuration["API"];
|
||||
var apiUrlSalary = $"{_baseAPI}/org/profile/leave/cancel/{rawData.Id}";
|
||||
|
|
@ -790,7 +821,8 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
throw new Exception(GlobalMessages.DataNotFound);
|
||||
}
|
||||
|
||||
var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(rawData.KeycloakUserId, AccessToken ?? "");
|
||||
// var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(rawData.KeycloakUserId, AccessToken ?? "");
|
||||
var profile = await _userProfileRepository.GetProfileByKeycloakIdNew2Async(rawData.KeycloakUserId, AccessToken ?? "");
|
||||
if (profile == null)
|
||||
{
|
||||
throw new Exception(GlobalMessages.DataNotFound);
|
||||
|
|
@ -877,6 +909,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
|
||||
|
||||
rawData.LeaveStatus = "NEW";
|
||||
rawData.DateSendLeave = DateTime.Now; // Update วันที่ยื่นลาเป็นวันที่ปัจจุบัน
|
||||
//rawData.ApproveStep = "st2";
|
||||
|
||||
await UpdateAsync(rawData);
|
||||
|
|
@ -1214,7 +1247,8 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
}
|
||||
else
|
||||
{
|
||||
var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(rawData.KeycloakUserId, AccessToken);
|
||||
// var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(rawData.KeycloakUserId, AccessToken);
|
||||
var profile = await _userProfileRepository.GetProfileByKeycloakIdNew2Async(rawData.KeycloakUserId, AccessToken);
|
||||
if (profile == null)
|
||||
{
|
||||
throw new Exception(GlobalMessages.DataNotFound);
|
||||
|
|
@ -1235,6 +1269,8 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
|
||||
// TODO : Update ไปตาราง beginning
|
||||
await _leaveBeginningRepository.UpdateLeaveUsageAsync(thisYear, rawData.Type.Id, rawData.KeycloakUserId, rawData.LeaveTotal);
|
||||
// update leave count เพิ่มขึ้น 1 ครั้ง
|
||||
await _leaveBeginningRepository.UpdateLeaveCountAsync(thisYear, rawData.Type.Id, rawData.KeycloakUserId, 1);
|
||||
|
||||
|
||||
var _baseAPI = _configuration["API"];
|
||||
|
|
@ -1258,6 +1294,8 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
status = "approve",
|
||||
reason = rawData.LeaveDetail,
|
||||
leaveId = rawData.Id,
|
||||
leaveSubTypeName = rawData.LeaveSubTypeName,
|
||||
coupleDayLevelCountry = rawData.CoupleDayLevelCountry,
|
||||
});
|
||||
// var _result = await _res.Content.ReadAsStringAsync();
|
||||
}
|
||||
|
|
@ -1281,6 +1319,8 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
status = "approve",
|
||||
reason = rawData.LeaveDetail,
|
||||
leaveId = rawData.Id,
|
||||
leaveSubTypeName = rawData.LeaveSubTypeName,
|
||||
coupleDayLevelCountry = rawData.CoupleDayLevelCountry,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1290,9 +1330,68 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
}
|
||||
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
|
||||
var noti = new Notification
|
||||
{
|
||||
|
|
@ -1377,7 +1476,8 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
}
|
||||
else
|
||||
{
|
||||
var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(rawData.KeycloakUserId, AccessToken);
|
||||
// var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(rawData.KeycloakUserId, AccessToken);
|
||||
var profile = await _userProfileRepository.GetProfileByKeycloakIdNew2Async(rawData.KeycloakUserId, AccessToken);
|
||||
if (profile == null)
|
||||
{
|
||||
throw new Exception(GlobalMessages.DataNotFound);
|
||||
|
|
@ -1450,7 +1550,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
KeycloakUserId = pf.Keycloak == null ? Guid.Empty : pf.Keycloak.Value,
|
||||
LeaveTypeId = b.LeaveTypeId,
|
||||
LeaveTypeCode = b.LeaveType!.Code,
|
||||
SumLeaveDay = b.LeaveDaysUsed
|
||||
SumLeaveDay = b.LeaveDaysUsed ?? 0.0
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1664,10 +1764,10 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
{
|
||||
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).ToList();
|
||||
}
|
||||
// else if (role == "PARENT")
|
||||
// {
|
||||
// data = data.Where(x => x.RootDnaId == Guid.Parse(nodeId) && x.Child1DnaId != null).ToList();
|
||||
// }
|
||||
else if (role == "NORMAL")
|
||||
{
|
||||
data = data.Where(x =>
|
||||
|
|
@ -1683,7 +1783,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
if (role == "ROOT" || role == "OWNER" || role == "CHILD" || role == "BROTHER" || role == "PARENT")
|
||||
{
|
||||
data = data
|
||||
.Where(x => nodeByReq == 4 ? x.Child4Id == Guid.Parse(nodeIdByReq) : nodeByReq == 3 ? x.Child3Id == Guid.Parse(nodeIdByReq) : nodeByReq == 2 ? x.Child2Id == Guid.Parse(nodeIdByReq) : nodeByReq == 1 ? x.Child1Id == Guid.Parse(nodeIdByReq) : nodeByReq == 0 ? x.RootId == Guid.Parse(nodeIdByReq) : true)
|
||||
.Where(x => nodeByReq == 4 ? x.Child4DnaId == Guid.Parse(nodeIdByReq) : nodeByReq == 3 ? x.Child3DnaId == Guid.Parse(nodeIdByReq) : nodeByReq == 2 ? x.Child2DnaId == Guid.Parse(nodeIdByReq) : nodeByReq == 1 ? x.Child1DnaId == Guid.Parse(nodeIdByReq) : nodeByReq == 0 ? x.RootDnaId == Guid.Parse(nodeIdByReq) : true)
|
||||
.ToList();
|
||||
}
|
||||
// รายงานการลางานจำแนกตามเพศฯ Template ให้หน่วยงานแสดงก่อนส่วนราชการ
|
||||
|
|
@ -1824,6 +1924,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
.Include(x => x.Type)
|
||||
.Where(x => x.KeycloakUserId == keycloakUserId)
|
||||
.Where(x => x.Type.Id == leaveTypeId)
|
||||
//.Where(x => x.CreatedAt >= startDate && x.CreatedAt <= endDate)
|
||||
.Where(x => x.LeaveStartDate.Date >= startDate.Date && x.LeaveStartDate.Date <= endDate.Date)
|
||||
.Where(x => x.LeaveStatus == "APPROVE" || x.LeaveStatus == "DELETING")
|
||||
.ToListAsync();
|
||||
|
|
@ -1834,6 +1935,139 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
return 0;
|
||||
}
|
||||
|
||||
public async Task<double> GetSumApproveLeaveTotalByTypeAndRangeForUser2(Guid keycloakUserId, Guid leaveTypeId, DateTime startDate, DateTime endDate, DateTime sendLeaveDate)
|
||||
{
|
||||
// startDate/endDate คือขอบเขตปีงบประมาณ (fiscalStart/fiscalEnd) ที่ caller ส่งมา
|
||||
// ใช้ LeaveStartDate เป็นหลักในการ filter เพื่อให้กรณียื่นลาล่วงหน้าข้ามปีงบประมาณ
|
||||
// ถูกนับในปีงบประมาณของวันลาจริง (ไม่ใช้วันที่ยื่นลา)
|
||||
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) < sendLeaveDate)
|
||||
.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<double> GetSumApproveLeaveTotalByTypeAndRangeForUserBefore(Guid keycloakUserId, Guid leaveTypeId, DateTime startDate, DateTime endDate,DateTime sendLeaveDate)
|
||||
{
|
||||
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) < sendLeaveDate)
|
||||
.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<double> GetSumApproveLeaveTotalByTypeAndRangeForUserByProfile(Guid profileId, Guid leaveTypeId, DateTime startDate, DateTime endDate,DateTime sendLeaveDate)
|
||||
{
|
||||
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) < sendLeaveDate)
|
||||
.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, DateTime sendLeaveDate)
|
||||
{
|
||||
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) < sendLeaveDate)
|
||||
.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, DateTime sendLeaveDate)
|
||||
{
|
||||
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) < sendLeaveDate)
|
||||
.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>
|
||||
/// <param name="keycloakUserId"></param>
|
||||
/// <param name="leaveTypeId"></param>
|
||||
/// <param name="startDate"></param>
|
||||
/// <param name="endDate"></param>
|
||||
/// <param name="sendLeaveDate"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<double> GetSumDraftLeaveTotalByTypeAndRangeForUser2(Guid keycloakUserId, Guid leaveTypeId, DateTime startDate, DateTime endDate, DateTime sendLeaveDate)
|
||||
{
|
||||
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) < sendLeaveDate)
|
||||
.Where(x => x.LeaveStartDate.Date >= startDate.Date && x.LeaveStartDate.Date <= endDate.Date)
|
||||
.Where(x => x.LeaveStatus == "DRAFT")
|
||||
.ToListAsync();
|
||||
|
||||
if (data.Count > 0)
|
||||
return data.Sum(x => x.LeaveTotal);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// วันลาที่ยื่นแล้วรอพิจารณา
|
||||
/// </summary>
|
||||
/// <param name="keycloakUserId"></param>
|
||||
/// <param name="leaveTypeId"></param>
|
||||
/// <param name="startDate"></param>
|
||||
/// <param name="endDate"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<double> GetSumNewLeaveTotalByTypeAndRangeForUser2(Guid keycloakUserId, Guid leaveTypeId, DateTime startDate, DateTime endDate,DateTime sendLeaveDate)
|
||||
{
|
||||
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) < sendLeaveDate)
|
||||
.Where(x => x.LeaveStartDate.Date >= startDate.Date && x.LeaveStartDate.Date <= endDate.Date)
|
||||
.Where(x => (x.LeaveStatus == "NEW" || x.LeaveStatus == "PENDING"))
|
||||
.ToListAsync();
|
||||
|
||||
if (data.Count > 0)
|
||||
return data.Sum(x => x.LeaveTotal);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
public async Task<int> GetCountApproveLeaveByTypeAndRangeForUser(Guid keycloakUserId, Guid leaveTypeId, DateTime startDate, DateTime endDate)
|
||||
{
|
||||
var data = await _dbContext.Set<LeaveRequest>().AsQueryable().AsNoTracking()
|
||||
|
|
@ -1841,6 +2075,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
.Where(x => x.KeycloakUserId == keycloakUserId)
|
||||
.Where(x => x.Type.Id == leaveTypeId)
|
||||
.Where(x => x.LeaveStartDate.Date >= startDate.Date && x.LeaveStartDate.Date <= endDate.Date)
|
||||
//.Where(x => x.CreatedAt >= startDate && x.CreatedAt <= endDate)
|
||||
.Where(x => x.LeaveStatus == "APPROVE" || x.LeaveStatus == "DELETING")
|
||||
.ToListAsync();
|
||||
|
||||
|
|
|
|||
|
|
@ -74,7 +74,8 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
|||
await base.AddAsync(entity);
|
||||
|
||||
var userId = UserId != null ? Guid.Parse(UserId) : Guid.Empty;
|
||||
var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(userId, AccessToken ?? "");
|
||||
// var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(userId, AccessToken ?? "");
|
||||
var profile = await _userProfileRepository.GetProfileByKeycloakIdNew2Async(userId, AccessToken ?? "");
|
||||
|
||||
// fix issue : SIT ระบบบันทึกเวลาปฏิบัติงาน>>ลงเวลากรณีพิเศษ (ไม่มีแจ้งเตือนไปยังผู้บังคับบัญชา) #969
|
||||
// send noti + inbox + mail
|
||||
|
|
@ -144,7 +145,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
|||
}
|
||||
}
|
||||
|
||||
public async Task<List<AdditionalCheckRequest>> GetAdditionalCheckRequestsByAdminRole(int year, int month, string role, string nodeId, int? node)
|
||||
public async Task<List<AdditionalCheckRequest>> GetAdditionalCheckRequestsByAdminRole(int year, int month, string role, string nodeId, int? node, string? keyword)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -152,6 +153,17 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
|||
.Where(x => (x.CheckDate.Year == year && x.CheckDate.Month == month))
|
||||
.OrderByDescending(x => x.CreatedAt.Date)
|
||||
.ToListAsync();
|
||||
|
||||
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;
|
||||
|
|
@ -173,11 +185,11 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
|||
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 == "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 =>
|
||||
|
|
@ -201,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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,6 +114,62 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
|||
return job!;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ดึงข้อมูลงานที่ค้างอยู่ในสถานะ PENDING หรือ PROCESSING เกินเวลาที่กำหนด (นาที)
|
||||
/// </summary>
|
||||
public async Task<List<CheckInJobStatus>> GetStalePendingOrProcessingJobsAsync(int timeoutMinutes = 30)
|
||||
{
|
||||
//var cutoffDate = DateTime.Now.AddMinutes(-timeoutMinutes);
|
||||
var cutoffDate = DateTime.Now.AddMinutes(-timeoutMinutes);
|
||||
var staleJobs = await _dbContext.Set<CheckInJobStatus>()
|
||||
.Where(x => (x.Status == "PENDING" || x.Status == "PROCESSING")
|
||||
&& x.CreatedDate <= cutoffDate)
|
||||
.OrderBy(x => x.CreatedDate)
|
||||
.ToListAsync();
|
||||
|
||||
return staleJobs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ดึงข้อมูลงานที่ค้างอยู่ในสถานะ PENDING หรือ PROCESSING เกินเวลาที่กำหนด (นาที) ของ user คนใดคนหนึ่ง
|
||||
/// </summary>
|
||||
public async Task<List<CheckInJobStatus>> GetStalePendingOrProcessingJobsByUserAsync(Guid userId, int timeoutMinutes = 30)
|
||||
{
|
||||
var cutoffDate = DateTime.Now.AddMinutes(-timeoutMinutes);
|
||||
//var cutoffDate = new DateTime(2026, 5, 28, 23, 59, 59);
|
||||
var staleJobs = await _dbContext.Set<CheckInJobStatus>()
|
||||
.Where(x => x.KeycloakUserId == userId
|
||||
&& (x.Status == "PENDING" || x.Status == "PROCESSING")
|
||||
&& x.CreatedDate < cutoffDate)
|
||||
.OrderBy(x => x.CreatedDate)
|
||||
.ToListAsync();
|
||||
|
||||
return staleJobs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Mark งานที่ค้างเกินเวลาที่กำหนดเป็น FAILED
|
||||
/// </summary>
|
||||
public async Task<int> MarkStaleJobsAsFailedAsync(int timeoutMinutes = 30)
|
||||
{
|
||||
var staleJobs = await GetStalePendingOrProcessingJobsAsync(timeoutMinutes);
|
||||
|
||||
foreach (var job in staleJobs)
|
||||
{
|
||||
job.Status = "FAILED";
|
||||
job.CompletedDate = DateTime.Now;
|
||||
job.ErrorMessage = $"งานค้างในสถานะ {job.Status} เกิน {timeoutMinutes} นาที ระบบทำเครื่องหมายเป็น FAILED อัตโนมัติ";
|
||||
}
|
||||
|
||||
if (staleJobs.Any())
|
||||
{
|
||||
_dbContext.Set<CheckInJobStatus>().UpdateRange(staleJobs);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
return staleJobs.Count;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ล้างข้อมูล Job Status ที่เก่าเกิน X วัน
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -61,9 +61,12 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
|||
return await _dbContext.Set<DutyTime>().Where(x => x.IsActive).ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<DutyTime?> GetDefaultAsync()
|
||||
public async Task<DutyTime?> GetDefaultAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
return await _dbContext.Set<DutyTime>().Where(x => x.IsDefault).FirstOrDefaultAsync();
|
||||
// กำหนด timeout เป็น 30 นาที
|
||||
using var timeoutCts = new CancellationTokenSource(TimeSpan.FromMinutes(30));
|
||||
using var combinedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutCts.Token);
|
||||
return await _dbContext.Set<DutyTime>().Where(x => x.IsDefault).FirstOrDefaultAsync(combinedCts.Token);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
|||
|
|
@ -0,0 +1,795 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Text.Json;
|
||||
using System.IO;
|
||||
using BMA.EHR.Application.Common.Interfaces;
|
||||
using BMA.EHR.Application.Repositories.Leaves.LeaveRequests;
|
||||
using BMA.EHR.Application.Repositories.MetaData;
|
||||
using BMA.EHR.Application.Responses.Profiles;
|
||||
using BMA.EHR.Domain.Extensions;
|
||||
using BMA.EHR.Domain.Models.Leave.TimeAttendants;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
||||
{
|
||||
public class LeaveProcessJobStatusRepository: GenericLeaveRepository<Guid, LeaveProcessJobStatus>
|
||||
{
|
||||
#region " Fields "
|
||||
|
||||
private readonly ILeaveDbContext _dbContext;
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
private readonly UserProfileRepository _userProfileRepository;
|
||||
private readonly HolidayRepository _holidayRepository;
|
||||
private readonly DutyTimeRepository _dutyTimeRepository;
|
||||
private readonly UserDutyTimeRepository _userDutyTimeRepository;
|
||||
private readonly ProcessUserTimeStampRepository _processUserTimeStampRepository;
|
||||
private readonly LeaveRequestRepository _leaveRequestRepository;
|
||||
private readonly IConfiguration _configuration;
|
||||
private readonly IWebHostEnvironment _env;
|
||||
|
||||
#endregion
|
||||
|
||||
#region " Constructor and Destructor "
|
||||
|
||||
public LeaveProcessJobStatusRepository(ILeaveDbContext dbContext,
|
||||
IHttpContextAccessor httpContextAccessor,
|
||||
UserProfileRepository userProfileRepository,
|
||||
HolidayRepository holidayRepository,
|
||||
DutyTimeRepository dutyTimeRepository,
|
||||
UserDutyTimeRepository userDutyTimeRepository,
|
||||
ProcessUserTimeStampRepository processUserTimeStampRepository,
|
||||
LeaveRequestRepository leaveRequestRepository,
|
||||
IConfiguration configuration,
|
||||
IWebHostEnvironment env) : base(dbContext, httpContextAccessor)
|
||||
{
|
||||
_dbContext = dbContext;
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
_userProfileRepository = userProfileRepository;
|
||||
_holidayRepository = holidayRepository;
|
||||
_configuration = configuration;
|
||||
_leaveRequestRepository = leaveRequestRepository;
|
||||
_dutyTimeRepository = dutyTimeRepository;
|
||||
_userDutyTimeRepository = userDutyTimeRepository;
|
||||
_processUserTimeStampRepository = processUserTimeStampRepository;
|
||||
_env = env;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region " Methods "
|
||||
|
||||
/// <summary>
|
||||
/// ดึงข้อมูล Job Status จาก TaskId
|
||||
/// </summary>
|
||||
public async Task<LeaveProcessJobStatus?> GetByTaskIdAsync(Guid id)
|
||||
{
|
||||
var data = await _dbContext.Set<LeaveProcessJobStatus>()
|
||||
.Where(x => x.Id == id)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ดึงข้อมูล Job Status จาก UserId และสถานะ
|
||||
/// </summary>
|
||||
public async Task<List<LeaveProcessJobStatus>> GetByUserIdAndStatusAsync(Guid userId, string status)
|
||||
{
|
||||
var data = await _dbContext.Set<LeaveProcessJobStatus>()
|
||||
.Where(x => x.CreatedUserId == userId.ToString("D") && x.Status == status)
|
||||
.OrderByDescending(x => x.CreatedDate)
|
||||
.ToListAsync();
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ดึงข้อมูล Job Status จาก UserId
|
||||
/// </summary>
|
||||
public async Task<List<LeaveProcessJobStatus>> GetByUserIdAsync(Guid userId)
|
||||
{
|
||||
var data = await _dbContext.Set<LeaveProcessJobStatus>()
|
||||
.Where(x => x.CreatedUserId == userId.ToString("D"))
|
||||
.OrderByDescending(x => x.CreatedDate)
|
||||
.ToListAsync();
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ดึงข้อมูล Job Status ที่ยัง pending หรือ processing
|
||||
/// </summary>
|
||||
public async Task<List<LeaveProcessJobStatus>> GetPendingOrProcessingJobsAsync(Guid userId)
|
||||
{
|
||||
var data = await _dbContext.Set<LeaveProcessJobStatus>()
|
||||
.Where(x => x.CreatedUserId == userId.ToString("D") &&
|
||||
(x.Status == "PENDING" || x.Status == "PROCESSING"))
|
||||
//.OrderByDescending(x => x.CreatedDate)
|
||||
.ToListAsync();
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public async Task<List<LeaveProcessJobStatus>> GetPendingJobsAsync()
|
||||
{
|
||||
var data = await _dbContext.Set<LeaveProcessJobStatus>()
|
||||
.Where(x => x.Status == "PENDING")
|
||||
.ToListAsync();
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// อัปเดตสถานะเป็น Processing
|
||||
/// </summary>
|
||||
public async Task<LeaveProcessJobStatus> UpdateToProcessingAsync(Guid id)
|
||||
{
|
||||
var job = await GetByTaskIdAsync(id);
|
||||
if (job != null)
|
||||
{
|
||||
job.Status = "PROCESSING";
|
||||
job.ProcessingDate = DateTime.Now;
|
||||
await UpdateAsync(job);
|
||||
}
|
||||
return job!;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// อัปเดตสถานะเป็น Completed
|
||||
/// </summary>
|
||||
public async Task<LeaveProcessJobStatus> UpdateToCompletedAsync(Guid id, string? additionalData = null)
|
||||
{
|
||||
var job = await GetByTaskIdAsync(id);
|
||||
if (job != null)
|
||||
{
|
||||
job.Status = "COMPLETED";
|
||||
job.CompletedDate = DateTime.Now;
|
||||
await UpdateAsync(job);
|
||||
}
|
||||
return job!;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// อัปเดตสถานะเป็น Failed
|
||||
/// </summary>
|
||||
public async Task<LeaveProcessJobStatus> UpdateToFailedAsync(Guid id, string errorMessage)
|
||||
{
|
||||
var job = await GetByTaskIdAsync(id);
|
||||
if (job != null)
|
||||
{
|
||||
job.Status = "FAILED";
|
||||
job.CompletedDate = DateTime.Now;
|
||||
job.ErrorMessage = errorMessage;
|
||||
await UpdateAsync(job);
|
||||
}
|
||||
return job!;
|
||||
}
|
||||
|
||||
public async Task ProcessTaskAsync(Guid rootDnaId, DateTime? startDate, DateTime? endDate)
|
||||
{
|
||||
|
||||
var profiles = new List<GetProfileByKeycloakIdRootDto>();
|
||||
var dateStart = startDate?.Date ?? DateTime.Now.Date;
|
||||
var dateEnd = endDate?.Date ?? DateTime.Now.Date;
|
||||
|
||||
var holidays = await _holidayRepository.GetHolidayAsync(dateStart, dateEnd);
|
||||
var weekend = _holidayRepository.GetWeekEnd(dateStart, dateEnd);
|
||||
var excludeDates = holidays.Union(weekend).ToList();
|
||||
|
||||
var dateList = new List<LoopDate>();
|
||||
for (DateTime i = dateStart; i <= dateEnd; i = i.AddDays(1))
|
||||
{
|
||||
if (holidays.Contains(i))
|
||||
{
|
||||
var d = await _holidayRepository.GetHolidayAsync(i);
|
||||
dateList.Add(new LoopDate
|
||||
{
|
||||
date = i,
|
||||
isHoliday = true,
|
||||
isWeekEnd = false,
|
||||
dateRemark = d
|
||||
});
|
||||
}
|
||||
else if (weekend.Contains(i))
|
||||
{
|
||||
dateList.Add(new LoopDate
|
||||
{
|
||||
date = i,
|
||||
isHoliday = true,
|
||||
isWeekEnd = false,
|
||||
dateRemark = "วันหยุด"
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
dateList.Add(new LoopDate
|
||||
{
|
||||
date = i,
|
||||
isHoliday = false,
|
||||
isWeekEnd = false,
|
||||
dateRemark = ""
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var defaultRound = await _dutyTimeRepository.GetDefaultAsync();
|
||||
if (defaultRound == null)
|
||||
{
|
||||
throw new Exception("ไม่พบรอบการลงเวลา Default");
|
||||
}
|
||||
|
||||
var employees = new List<DateResultReport>();
|
||||
|
||||
foreach (var dd in dateList.Where(x => !x.isHoliday && !x.isWeekEnd))
|
||||
{
|
||||
profiles = await _userProfileRepository.GetAllOfficerByRootDnaId(rootDnaId.ToString(),dd.date);
|
||||
foreach (var p in profiles)
|
||||
{
|
||||
var count = 1;
|
||||
var keycloakUserId = p.Keycloak ?? Guid.Empty;
|
||||
|
||||
var timeStamps = await _processUserTimeStampRepository.GetTimestampByDateAsync(keycloakUserId, dd.date);
|
||||
|
||||
var fullName = $"{p.Prefix}{p.FirstName} {p.LastName}";
|
||||
|
||||
var effectiveDate = await _userDutyTimeRepository.GetLastEffectRound(p.Id, dd.date);
|
||||
var roundId = effectiveDate != null ? effectiveDate.DutyTimeId : Guid.Empty;
|
||||
var userRound = await _dutyTimeRepository.GetByIdAsync(roundId);
|
||||
|
||||
var duty = userRound ?? defaultRound;
|
||||
|
||||
// check วันลาของแต่ละคน
|
||||
var leaveReq = await _leaveRequestRepository.GetLeavePeriodAsync(keycloakUserId, dd.date);
|
||||
var remarkStr = string.Empty;
|
||||
var status = string.Empty;
|
||||
var stampType = string.Empty;
|
||||
var stampAmount = 0.0;
|
||||
|
||||
if (leaveReq != null)
|
||||
{
|
||||
switch (leaveReq.Type.Code.ToUpper())
|
||||
{
|
||||
case "LV-001":
|
||||
case "LV-002":
|
||||
case "LV-005":
|
||||
remarkStr += leaveReq.Type.Name;
|
||||
var leaveRange = leaveReq.LeaveRange == null ? "" : leaveReq.LeaveRange.ToUpper();
|
||||
|
||||
if(leaveReq.LeaveStartDate.Date == leaveReq.LeaveEndDate.Date)
|
||||
{
|
||||
if (leaveRange == "MORNING")
|
||||
remarkStr += "ครึ่งวันเช้า";
|
||||
else if (leaveRange == "AFTERNOON")
|
||||
remarkStr += "ครึ่งวันบ่าย";
|
||||
|
||||
|
||||
// var leaveRangeEnd = leaveReq.LeaveRangeEnd == null ? "" : leaveReq.LeaveRangeEnd.ToUpper();
|
||||
// if (leaveRangeEnd == "MORNING")
|
||||
// remarkStr += "ครึ่งวันเช้า";
|
||||
// else if (leaveRangeEnd == "AFTERNOON")
|
||||
// remarkStr += "ครึ่งวันบ่าย";
|
||||
|
||||
var leaveRangeEnd = leaveReq.LeaveRangeEnd == null ? "" : leaveReq.LeaveRangeEnd.ToUpper();
|
||||
if (leaveRange != leaveRangeEnd)
|
||||
{
|
||||
if (leaveRangeEnd == "MORNING")
|
||||
remarkStr += " - ครึ่งวันเช้า";
|
||||
else if (leaveRangeEnd == "AFTERNOON")
|
||||
remarkStr += " - ครึ่งวันบ่าย";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(dd.date == leaveReq.LeaveStartDate.Date)
|
||||
{
|
||||
if (leaveRange == "MORNING")
|
||||
remarkStr += "ครึ่งวันเช้า";
|
||||
else if (leaveRange == "AFTERNOON")
|
||||
remarkStr += "ครึ่งวันบ่าย";
|
||||
}
|
||||
else if(dd.date == leaveReq.LeaveEndDate.Date)
|
||||
{
|
||||
var leaveRangeEnd = leaveReq.LeaveRangeEnd == null ? "" : leaveReq.LeaveRangeEnd.ToUpper();
|
||||
if (leaveRangeEnd == "MORNING")
|
||||
remarkStr += "ครึ่งวันเช้า";
|
||||
else if (leaveRangeEnd == "AFTERNOON")
|
||||
remarkStr += "ครึ่งวันบ่าย";
|
||||
else
|
||||
remarkStr += "เต็มวัน";
|
||||
}
|
||||
else
|
||||
{
|
||||
remarkStr += "เต็มวัน";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
default:
|
||||
remarkStr += leaveReq.Type.Name;
|
||||
break;
|
||||
}
|
||||
status = "LEAVE";
|
||||
if(leaveReq.LeaveStartDate.Date == dd.date)
|
||||
{
|
||||
stampType = leaveReq.LeaveRange ?? "";
|
||||
stampAmount = leaveReq.LeaveRange != "ALL" ? 0.5 : 1;
|
||||
}
|
||||
else if(leaveReq.LeaveEndDate.Date == dd.date)
|
||||
{
|
||||
stampAmount = leaveReq.LeaveRangeEnd != "ALL" ? 0.5 : 1;
|
||||
stampType = leaveReq.LeaveRangeEnd ?? "";
|
||||
}
|
||||
else
|
||||
stampAmount = leaveReq.LeaveRange != "ALL" || leaveReq.LeaveRangeEnd != "ALL" ? 0.5 : 1;
|
||||
if(stampType == "ALL") stampType = "FULL_DAY";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (timeStamps == null)
|
||||
{
|
||||
if (dd.date <= DateTime.Now.Date)
|
||||
{
|
||||
remarkStr = "ขาดราชการ";
|
||||
status = "ABSENT";
|
||||
stampType = "FULL_DAY";
|
||||
stampAmount = 1;
|
||||
if (dd.isHoliday == true)
|
||||
{
|
||||
remarkStr = $"วันหยุด ({dd.dateRemark})";
|
||||
status = "HOLIDAY";
|
||||
}
|
||||
else if (dd.isWeekEnd)
|
||||
{
|
||||
remarkStr = dd.dateRemark;
|
||||
status = "WEEKEND";
|
||||
}
|
||||
}
|
||||
else remarkStr = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
// check status ของการลงเวลา
|
||||
if (timeStamps.CheckOut != null)
|
||||
{
|
||||
if (timeStamps.CheckOutStatus == "ABSENT")
|
||||
{
|
||||
remarkStr = "ขาดราชการ" + (!timeStamps.IsLocationCheckOut ? $" (นอกสถานที่:{timeStamps.CheckOutLocationName})".Trim() : "");
|
||||
status = "ABSENT";
|
||||
stampType = "FULL_DAY";
|
||||
stampAmount = 1;
|
||||
}
|
||||
else if (timeStamps.CheckInStatus == "ABSENT")
|
||||
{
|
||||
remarkStr = "ขาดราชการ" + (!timeStamps.IsLocationCheckIn ? $" (นอกสถานที่:{timeStamps.CheckInLocationName})".Trim() : "");
|
||||
status = "ABSENT";
|
||||
stampType = "FULL_DAY";
|
||||
stampAmount = 1;
|
||||
}
|
||||
else if (timeStamps.CheckInStatus == "LATE")
|
||||
{
|
||||
remarkStr = "สาย" + (!timeStamps.IsLocationCheckIn ? $" (นอกสถานที่:{timeStamps.CheckInLocationName})".Trim() : "");
|
||||
status = "LATE";
|
||||
stampType = "FULL_DAY";
|
||||
stampAmount = 1;
|
||||
//lateTotal += 1;
|
||||
}
|
||||
else
|
||||
remarkStr = !timeStamps.IsLocationCheckIn ? $" นอกสถานที่:{timeStamps.CheckInLocationName}".Trim() : "";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (timeStamps.CheckInStatus == "ABSENT")
|
||||
{
|
||||
status = "ABSENT";
|
||||
stampType = "FULL_DAY";
|
||||
stampAmount = 1;
|
||||
remarkStr = "ขาดราชการ" + (!timeStamps.IsLocationCheckIn ? $" (นอกสถานที่:{timeStamps.CheckInLocationName})".Trim() : "");
|
||||
}
|
||||
else if (timeStamps.CheckInStatus == "LATE")
|
||||
{
|
||||
status = "LATE";
|
||||
stampType = "FULL_DAY";
|
||||
stampAmount = 1;
|
||||
remarkStr = "สาย" + (!timeStamps.IsLocationCheckIn ? $" (นอกสถานที่:{timeStamps.CheckInLocationName})".Trim() : "");
|
||||
//lateTotal += 1;
|
||||
}
|
||||
else
|
||||
remarkStr = !timeStamps.IsLocationCheckIn ? $" นอกสถานที่:{timeStamps.CheckInLocationName}".Trim() : "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var emp = new DateResultReport
|
||||
{
|
||||
profileId = p.Id.ToString(),
|
||||
stampDate = dd.date,
|
||||
stampType = stampType,
|
||||
stampAmount = stampAmount,
|
||||
remark = remarkStr,
|
||||
status = status
|
||||
};
|
||||
|
||||
employees.Add(emp);
|
||||
count++;
|
||||
}
|
||||
|
||||
// Write employees to JSON file
|
||||
// var fileName = $"employees_{DateTime.Now:yyyyMMdd_HHmmss}.txt";
|
||||
// var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Exports", fileName);
|
||||
|
||||
// // Ensure directory exists
|
||||
// var directory = Path.GetDirectoryName(filePath);
|
||||
// if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
|
||||
// {
|
||||
// Directory.CreateDirectory(directory);
|
||||
// }
|
||||
|
||||
// var jsonOptions = new JsonSerializerOptions
|
||||
// {
|
||||
// WriteIndented = true,
|
||||
// Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
|
||||
// };
|
||||
|
||||
// var jsonContent = JsonSerializer.Serialize(employees, jsonOptions);
|
||||
// await File.WriteAllTextAsync(filePath, jsonContent);
|
||||
}
|
||||
|
||||
//call api
|
||||
var apiPath = $"{_configuration["API"]}/org/unauthorize/profile/absent-late/batch";
|
||||
var apiKey = _configuration["API_KEY"];
|
||||
var body = new
|
||||
{
|
||||
records = employees.Where(x => x.status == "ABSENT" || x.status == "LATE").ToList()
|
||||
};
|
||||
|
||||
var apiResult = await PostExternalAPIAsync(apiPath, AccessToken ?? "", body, apiKey);
|
||||
if(apiResult == "")
|
||||
{
|
||||
throw new Exception($"เรียก API {apiPath} ไม่สำเร็จ");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task ProcessEmpTaskAsync(Guid rootDnaId, DateTime? startDate, DateTime? endDate)
|
||||
{
|
||||
|
||||
var profiles = new List<GetProfileByKeycloakIdRootDto>();
|
||||
var dateStart = startDate?.Date ?? DateTime.Now.Date;
|
||||
var dateEnd = endDate?.Date ?? DateTime.Now.Date;
|
||||
|
||||
var holidays = await _holidayRepository.GetHolidayAsync(dateStart, dateEnd);
|
||||
var weekend = _holidayRepository.GetWeekEnd(dateStart, dateEnd);
|
||||
var excludeDates = holidays.Union(weekend).ToList();
|
||||
|
||||
var dateList = new List<LoopDate>();
|
||||
for (DateTime i = dateStart; i <= dateEnd; i = i.AddDays(1))
|
||||
{
|
||||
if (holidays.Contains(i))
|
||||
{
|
||||
var d = await _holidayRepository.GetHolidayAsync(i);
|
||||
dateList.Add(new LoopDate
|
||||
{
|
||||
date = i,
|
||||
isHoliday = true,
|
||||
isWeekEnd = false,
|
||||
dateRemark = d
|
||||
});
|
||||
}
|
||||
else if (weekend.Contains(i))
|
||||
{
|
||||
dateList.Add(new LoopDate
|
||||
{
|
||||
date = i,
|
||||
isHoliday = true,
|
||||
isWeekEnd = false,
|
||||
dateRemark = "วันหยุด"
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
dateList.Add(new LoopDate
|
||||
{
|
||||
date = i,
|
||||
isHoliday = false,
|
||||
isWeekEnd = false,
|
||||
dateRemark = ""
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var defaultRound = await _dutyTimeRepository.GetDefaultAsync();
|
||||
if (defaultRound == null)
|
||||
{
|
||||
throw new Exception("ไม่พบรอบการลงเวลา Default");
|
||||
}
|
||||
|
||||
var employees = new List<DateResultReport>();
|
||||
|
||||
foreach (var dd in dateList.Where(x => !x.isHoliday && !x.isWeekEnd))
|
||||
{
|
||||
profiles = await _userProfileRepository.GetAllEmployeeByRootDnaId(rootDnaId.ToString(),dd.date);
|
||||
foreach (var p in profiles)
|
||||
{
|
||||
var count = 1;
|
||||
var keycloakUserId = p.Keycloak ?? Guid.Empty;
|
||||
|
||||
var timeStamps = await _processUserTimeStampRepository.GetTimestampByDateAsync(keycloakUserId, dd.date);
|
||||
|
||||
var fullName = $"{p.Prefix}{p.FirstName} {p.LastName}";
|
||||
|
||||
var effectiveDate = await _userDutyTimeRepository.GetLastEffectRound(p.Id, dd.date);
|
||||
var roundId = effectiveDate != null ? effectiveDate.DutyTimeId : Guid.Empty;
|
||||
var userRound = await _dutyTimeRepository.GetByIdAsync(roundId);
|
||||
|
||||
var duty = userRound ?? defaultRound;
|
||||
|
||||
// check วันลาของแต่ละคน
|
||||
var leaveReq = await _leaveRequestRepository.GetLeavePeriodAsync(keycloakUserId, dd.date);
|
||||
var remarkStr = string.Empty;
|
||||
var status = string.Empty;
|
||||
var stampType = string.Empty;
|
||||
var stampAmount = 0.0;
|
||||
|
||||
if (leaveReq != null)
|
||||
{
|
||||
switch (leaveReq.Type.Code.ToUpper())
|
||||
{
|
||||
case "LV-001":
|
||||
case "LV-002":
|
||||
case "LV-005":
|
||||
remarkStr += leaveReq.Type.Name;
|
||||
var leaveRange = leaveReq.LeaveRange == null ? "" : leaveReq.LeaveRange.ToUpper();
|
||||
|
||||
if(leaveReq.LeaveStartDate.Date == leaveReq.LeaveEndDate.Date)
|
||||
{
|
||||
if (leaveRange == "MORNING")
|
||||
remarkStr += "ครึ่งวันเช้า";
|
||||
else if (leaveRange == "AFTERNOON")
|
||||
remarkStr += "ครึ่งวันบ่าย";
|
||||
|
||||
|
||||
// var leaveRangeEnd = leaveReq.LeaveRangeEnd == null ? "" : leaveReq.LeaveRangeEnd.ToUpper();
|
||||
// if (leaveRangeEnd == "MORNING")
|
||||
// remarkStr += "ครึ่งวันเช้า";
|
||||
// else if (leaveRangeEnd == "AFTERNOON")
|
||||
// remarkStr += "ครึ่งวันบ่าย";
|
||||
|
||||
var leaveRangeEnd = leaveReq.LeaveRangeEnd == null ? "" : leaveReq.LeaveRangeEnd.ToUpper();
|
||||
if (leaveRange != leaveRangeEnd)
|
||||
{
|
||||
if (leaveRangeEnd == "MORNING")
|
||||
remarkStr += " - ครึ่งวันเช้า";
|
||||
else if (leaveRangeEnd == "AFTERNOON")
|
||||
remarkStr += " - ครึ่งวันบ่าย";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(dd.date == leaveReq.LeaveStartDate.Date)
|
||||
{
|
||||
if (leaveRange == "MORNING")
|
||||
remarkStr += "ครึ่งวันเช้า";
|
||||
else if (leaveRange == "AFTERNOON")
|
||||
remarkStr += "ครึ่งวันบ่าย";
|
||||
}
|
||||
else if(dd.date == leaveReq.LeaveEndDate.Date)
|
||||
{
|
||||
var leaveRangeEnd = leaveReq.LeaveRangeEnd == null ? "" : leaveReq.LeaveRangeEnd.ToUpper();
|
||||
if (leaveRangeEnd == "MORNING")
|
||||
remarkStr += "ครึ่งวันเช้า";
|
||||
else if (leaveRangeEnd == "AFTERNOON")
|
||||
remarkStr += "ครึ่งวันบ่าย";
|
||||
}
|
||||
else
|
||||
{
|
||||
remarkStr += "เต็มวัน";
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
remarkStr += leaveReq.Type.Name;
|
||||
break;
|
||||
}
|
||||
status = "LEAVE";
|
||||
if(leaveReq.LeaveStartDate.Date == dd.date)
|
||||
{
|
||||
stampType = leaveReq.LeaveRange ?? "";
|
||||
stampAmount = leaveReq.LeaveRange != "ALL" ? 0.5 : 1;
|
||||
}
|
||||
else if(leaveReq.LeaveEndDate.Date == dd.date)
|
||||
{
|
||||
stampAmount = leaveReq.LeaveRangeEnd != "ALL" ? 0.5 : 1;
|
||||
stampType = leaveReq.LeaveRangeEnd ?? "";
|
||||
}
|
||||
else
|
||||
stampAmount = leaveReq.LeaveRange != "ALL" || leaveReq.LeaveRangeEnd != "ALL" ? 0.5 : 1;
|
||||
if(stampType == "ALL") stampType = "FULL_DAY";
|
||||
//stampAmount = leaveReq.LeaveRange != "ALL" || leaveReq.LeaveRangeEnd != "ALL" ? 0.5 : 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (timeStamps == null)
|
||||
{
|
||||
if (dd.date <= DateTime.Now.Date)
|
||||
{
|
||||
remarkStr = "ขาดราชการ";
|
||||
status = "ABSENT";
|
||||
stampType = "FULL_DAY";
|
||||
stampAmount = 1;
|
||||
if (dd.isHoliday == true)
|
||||
{
|
||||
remarkStr = $"วันหยุด ({dd.dateRemark})";
|
||||
status = "HOLIDAY";
|
||||
}
|
||||
else if (dd.isWeekEnd)
|
||||
{
|
||||
remarkStr = dd.dateRemark;
|
||||
status = "WEEKEND";
|
||||
}
|
||||
}
|
||||
else remarkStr = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
// check status ของการลงเวลา
|
||||
if (timeStamps.CheckOut != null)
|
||||
{
|
||||
if (timeStamps.CheckOutStatus == "ABSENT")
|
||||
{
|
||||
remarkStr = "ขาดราชการ" + (!timeStamps.IsLocationCheckOut ? $" (นอกสถานที่:{timeStamps.CheckOutLocationName})".Trim() : "");
|
||||
status = "ABSENT";
|
||||
stampType = "FULL_DAY";
|
||||
stampAmount = 1;
|
||||
}
|
||||
else if (timeStamps.CheckInStatus == "ABSENT")
|
||||
{
|
||||
remarkStr = "ขาดราชการ" + (!timeStamps.IsLocationCheckIn ? $" (นอกสถานที่:{timeStamps.CheckInLocationName})".Trim() : "");
|
||||
status = "ABSENT";
|
||||
stampType = "FULL_DAY";
|
||||
stampAmount = 1;
|
||||
}
|
||||
else if (timeStamps.CheckInStatus == "LATE")
|
||||
{
|
||||
remarkStr = "สาย" + (!timeStamps.IsLocationCheckIn ? $" (นอกสถานที่:{timeStamps.CheckInLocationName})".Trim() : "");
|
||||
status = "LATE";
|
||||
stampType = "FULL_DAY";
|
||||
stampAmount = 1;
|
||||
//lateTotal += 1;
|
||||
}
|
||||
else
|
||||
remarkStr = !timeStamps.IsLocationCheckIn ? $" นอกสถานที่:{timeStamps.CheckInLocationName}".Trim() : "";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (timeStamps.CheckInStatus == "ABSENT")
|
||||
{
|
||||
status = "ABSENT";
|
||||
stampType = "FULL_DAY";
|
||||
stampAmount = 1;
|
||||
remarkStr = "ขาดราชการ" + (!timeStamps.IsLocationCheckIn ? $" (นอกสถานที่:{timeStamps.CheckInLocationName})".Trim() : "");
|
||||
}
|
||||
else if (timeStamps.CheckInStatus == "LATE")
|
||||
{
|
||||
status = "LATE";
|
||||
stampType = "FULL_DAY";
|
||||
stampAmount = 1;
|
||||
remarkStr = "สาย" + (!timeStamps.IsLocationCheckIn ? $" (นอกสถานที่:{timeStamps.CheckInLocationName})".Trim() : "");
|
||||
//lateTotal += 1;
|
||||
}
|
||||
else
|
||||
remarkStr = !timeStamps.IsLocationCheckIn ? $" นอกสถานที่:{timeStamps.CheckInLocationName}".Trim() : "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var emp = new DateResultReport
|
||||
{
|
||||
profileId = p.Id.ToString(),
|
||||
stampDate = dd.date,
|
||||
stampType = stampType,
|
||||
stampAmount = stampAmount,
|
||||
remark = remarkStr,
|
||||
status = status
|
||||
};
|
||||
|
||||
employees.Add(emp);
|
||||
count++;
|
||||
}
|
||||
|
||||
// Write employees to JSON file
|
||||
// var fileName = $"employees_{DateTime.Now:yyyyMMdd_HHmmss}.txt";
|
||||
// var filePath = Path.Combine(_env.ContentRootPath, "Exports", fileName);
|
||||
|
||||
// // Ensure directory exists
|
||||
// var directory = Path.GetDirectoryName(filePath);
|
||||
// if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
|
||||
// {
|
||||
// Directory.CreateDirectory(directory);
|
||||
// }
|
||||
|
||||
// var jsonOptions = new JsonSerializerOptions
|
||||
// {
|
||||
// WriteIndented = true,
|
||||
// Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
|
||||
// };
|
||||
|
||||
// var jsonContent = JsonSerializer.Serialize(employees, jsonOptions);
|
||||
// Console.WriteLine($"Writing file to: {filePath}");
|
||||
// await File.WriteAllTextAsync(filePath, jsonContent);
|
||||
// Console.WriteLine($"File written successfully: {fileName}");
|
||||
}
|
||||
|
||||
// call api
|
||||
var apiPath = $"{_configuration["API"]}/org/unauthorize/profile-employee/absent-late/batch";
|
||||
var apiKey = _configuration["API_KEY"];
|
||||
var body = new
|
||||
{
|
||||
records = employees.Where(x => x.status == "ABSENT" || x.status == "LATE").ToList()
|
||||
};
|
||||
|
||||
var apiResult = await PostExternalAPIAsync(apiPath, AccessToken ?? "", body, apiKey);
|
||||
if(apiResult == "")
|
||||
{
|
||||
throw new Exception($"เรียก API {apiPath} ไม่สำเร็จ");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public async Task ProcessPendingJobsAsync()
|
||||
{
|
||||
var pendingJobs = await GetPendingJobsAsync();
|
||||
Console.WriteLine($"พบงานที่ค้างอยู่ในสถานะ PENDING จำนวน {pendingJobs.Count} งาน");
|
||||
|
||||
foreach (var job in pendingJobs)
|
||||
{
|
||||
try
|
||||
{
|
||||
// อัปเดตสถานะเป็น Processing
|
||||
await UpdateToProcessingAsync(job.Id);
|
||||
|
||||
// ทำงานที่ต้องการที่นี่ (เช่น เรียก API, ประมวลผลข้อมูล ฯลฯ)
|
||||
await ProcessTaskAsync(job.RootDnaId,job.StartDate, job.EndDate);
|
||||
await ProcessEmpTaskAsync(job.RootDnaId,job.StartDate, job.EndDate);
|
||||
|
||||
// อัปเดตสถานะเป็น Completed
|
||||
await UpdateToCompletedAsync(job.Id);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// หากเกิดข้อผิดพลาด อัปเดตสถานะเป็น Failed พร้อมข้อความแสดงข้อผิดพลาด
|
||||
await UpdateToFailedAsync(job.Id, ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
class LoopDate
|
||||
{
|
||||
public DateTime date { get; set; }
|
||||
|
||||
public bool isHoliday { get; set; }
|
||||
|
||||
public bool isWeekEnd { get; set; }
|
||||
|
||||
public string dateRemark { get; set; }
|
||||
|
||||
}
|
||||
|
||||
class DateResultReport
|
||||
{
|
||||
public string? profileId { get; set; }
|
||||
public DateTime stampDate { get; set; }
|
||||
public string stampType { get; set; }
|
||||
public double stampAmount { get; set; }
|
||||
public string remark { get; set; }
|
||||
public string status { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -172,10 +172,10 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
|||
{
|
||||
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).ToList();
|
||||
}
|
||||
// else if (role == "PARENT")
|
||||
// {
|
||||
// data = data.Where(x => x.RootDnaId == Guid.Parse(nodeId) && x.Child1DnaId != null).ToList();
|
||||
// }
|
||||
else if (role == "NORMAL")
|
||||
{
|
||||
data = data.Where(x =>
|
||||
|
|
@ -191,11 +191,11 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
|||
if (role == "ROOT" || role == "OWNER" || role == "CHILD" || role == "BROTHER" || role == "PARENT")
|
||||
{
|
||||
data = data.Where(x =>
|
||||
nodeByReq == 4 ? x.Child4Id == Guid.Parse(nodeIdByReq) :
|
||||
nodeByReq == 3 ? x.Child3Id == Guid.Parse(nodeIdByReq) :
|
||||
nodeByReq == 2 ? x.Child2Id == Guid.Parse(nodeIdByReq) :
|
||||
nodeByReq == 1 ? x.Child1Id == Guid.Parse(nodeIdByReq) :
|
||||
nodeByReq == 0 ? x.RootId == Guid.Parse(nodeIdByReq) : true
|
||||
nodeByReq == 4 ? x.Child4DnaId == Guid.Parse(nodeIdByReq) :
|
||||
nodeByReq == 3 ? x.Child3DnaId == Guid.Parse(nodeIdByReq) :
|
||||
nodeByReq == 2 ? x.Child2DnaId == Guid.Parse(nodeIdByReq) :
|
||||
nodeByReq == 1 ? x.Child1DnaId == Guid.Parse(nodeIdByReq) :
|
||||
nodeByReq == 0 ? x.RootDnaId == Guid.Parse(nodeIdByReq) : true
|
||||
).ToList();
|
||||
}
|
||||
return data;
|
||||
|
|
@ -227,6 +227,19 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
|||
return data;
|
||||
}
|
||||
|
||||
public async Task<List<ProcessUserTimeStamp>> GetTimeStampHistoryAsync2(Guid keycloakId, int year)
|
||||
{
|
||||
var fiscalDateStart = new DateTime(year - 1, 10, 1);
|
||||
var fiscalDateEnd = new DateTime(year, 9, 30);
|
||||
|
||||
var data = await _dbContext.Set<ProcessUserTimeStamp>()
|
||||
.Where(u => u.KeycloakUserId == keycloakId)
|
||||
.Where(u => u.CheckIn.Date >= fiscalDateStart && u.CheckIn.Date <= fiscalDateEnd)
|
||||
.OrderByDescending(u => u.CheckIn.Date)
|
||||
.ToListAsync();
|
||||
return data;
|
||||
}
|
||||
|
||||
public async Task<int> GetTimeStampHistoryForAdminCountAsync(DateTime startDate, DateTime endDate)
|
||||
{
|
||||
var data = await _dbContext.Set<ProcessUserTimeStamp>()
|
||||
|
|
@ -288,12 +301,12 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
|||
.Where(x => x.RootDnaId == Guid.Parse(nodeId!))
|
||||
.ToList();
|
||||
}
|
||||
else if (role == "PARENT")
|
||||
{
|
||||
data = data
|
||||
.Where(x => x.RootDnaId == Guid.Parse(nodeId!) && x.Child1DnaId != null)
|
||||
.ToList();
|
||||
}
|
||||
// else if (role == "PARENT")
|
||||
// {
|
||||
// data = data
|
||||
// .Where(x => x.RootDnaId == Guid.Parse(nodeId!) && x.Child1DnaId != null)
|
||||
// .ToList();
|
||||
// }
|
||||
else if (role == "NORMAL")
|
||||
{
|
||||
data = data.Where(x =>
|
||||
|
|
|
|||
|
|
@ -101,14 +101,17 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
|||
return data;
|
||||
}
|
||||
|
||||
public async Task<UserDutyTime?> GetLastEffectRound(Guid profileId, DateTime? effectiveDate = null)
|
||||
public async Task<UserDutyTime?> GetLastEffectRound(Guid profileId, DateTime? effectiveDate = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
// กำหนด timeout เป็น 30 นาที
|
||||
using var timeoutCts = new CancellationTokenSource(TimeSpan.FromMinutes(30));
|
||||
using var combinedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutCts.Token);
|
||||
effectiveDate ??= DateTime.Now;
|
||||
var data = await _dbContext.Set<UserDutyTime>()
|
||||
.Where(x => x.ProfileId == profileId)
|
||||
.Where(x => x.EffectiveDate.Value.Date <= effectiveDate.Value.Date)
|
||||
.OrderByDescending(x => x.EffectiveDate)
|
||||
.FirstOrDefaultAsync();
|
||||
.FirstOrDefaultAsync(combinedCts.Token);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,12 +74,16 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
|||
return data;
|
||||
}
|
||||
|
||||
public async Task<UserTimeStamp?> GetLastRecord(Guid keycloakId)
|
||||
public async Task<UserTimeStamp?> GetLastRecord(Guid keycloakId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
// กำหนด timeout เป็น 30 นาที
|
||||
using var timeoutCts = new CancellationTokenSource(TimeSpan.FromMinutes(30));
|
||||
using var combinedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutCts.Token);
|
||||
|
||||
var data = await _dbContext.Set<UserTimeStamp>()
|
||||
.Where(u => u.KeycloakUserId == keycloakId)
|
||||
.OrderByDescending(u => u.CheckIn)
|
||||
.FirstOrDefaultAsync();
|
||||
.FirstOrDefaultAsync(combinedCts.Token);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
|
@ -136,12 +140,12 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
|||
.Where(x => x.RootDnaId == Guid.Parse(nodeId!))
|
||||
.ToList();
|
||||
}
|
||||
else if (role == "PARENT")
|
||||
{
|
||||
data = data
|
||||
.Where(x => x.RootDnaId == Guid.Parse(nodeId!) && x.Child1DnaId != null)
|
||||
.ToList();
|
||||
}
|
||||
// else if (role == "PARENT")
|
||||
// {
|
||||
// data = data
|
||||
// .Where(x => x.RootDnaId == Guid.Parse(nodeId!) && x.Child1DnaId != null)
|
||||
// .ToList();
|
||||
// }
|
||||
else if (role == "NORMAL")
|
||||
{
|
||||
data = data.Where(x =>
|
||||
|
|
|
|||
|
|
@ -187,6 +187,44 @@ namespace BMA.EHR.Application.Repositories.MessageQueue
|
|||
}
|
||||
}
|
||||
|
||||
private async Task<string> GetMyProfileIdAsync()
|
||||
{
|
||||
var apiUrl = $"{_configuration["API"]}/org/dotnet/get-profileId";
|
||||
var response = await GetExternalAPIAsync(apiUrl, AccessToken!, _configuration["API_KEY"]!);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(response))
|
||||
return string.Empty;
|
||||
|
||||
var org = JsonConvert.DeserializeObject<OrgRequest>(response);
|
||||
if (org == null || org.result == null)
|
||||
return string.Empty;
|
||||
|
||||
return org.result.profileId ?? string.Empty;
|
||||
}
|
||||
|
||||
public async Task<int> DeleteAllMyNotificationsAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
var profileId = await GetMyProfileIdAsync();
|
||||
if (string.IsNullOrEmpty(profileId))
|
||||
return 0;
|
||||
|
||||
var notifications = await _dbContext.Set<Notification>()
|
||||
.Where(x => x.ReceiverUserId == Guid.Parse(profileId))
|
||||
.Where(x => x.DeleteDate == null)
|
||||
.ToListAsync();
|
||||
|
||||
_dbContext.Set<Notification>().RemoveRange(notifications);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
return notifications.Count;
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task PushNotificationAsync(Guid ReceiverUserId, string Subject, string Body, string Payload = "", string NotiLink = "", bool IsSendInbox = false, bool IsSendMail = false)
|
||||
{
|
||||
try
|
||||
|
|
|
|||
|
|
@ -49,12 +49,16 @@ namespace BMA.EHR.Application.Repositories.MetaData
|
|||
|
||||
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.HolidayDate.Date >= startDate && x.HolidayDate.Date <= endDate)
|
||||
.CountAsync();
|
||||
.Where(x => x.HolidayDate.Date >= startDate && x.HolidayDate.Date <= endDate);
|
||||
|
||||
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")
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ using System.Net.Http.Headers;
|
|||
using Microsoft.Extensions.Configuration;
|
||||
using System.Security.Claims;
|
||||
using System.Net.Http.Json;
|
||||
using BMA.EHR.Application.Responses.Leaves;
|
||||
|
||||
namespace BMA.EHR.Application.Repositories
|
||||
{
|
||||
|
|
@ -76,6 +77,39 @@ namespace BMA.EHR.Application.Repositories
|
|||
}
|
||||
}
|
||||
|
||||
public async Task<GetPermissionWithActingResultDto?> GetPermissionWithActingAPIAsync(string action, string system)
|
||||
{
|
||||
try
|
||||
{
|
||||
var apiPath = $"{_configuration["API"]}/org/permission/dotnet-acting/{action}/{system}";
|
||||
|
||||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization =
|
||||
new AuthenticationHeaderValue("Bearer", AccessToken.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var req = await client.GetAsync(apiPath);
|
||||
if (!req.IsSuccessStatusCode)
|
||||
{
|
||||
throw new Exception("Error calling permission API");
|
||||
}
|
||||
var apiResult = await req.Content.ReadAsStringAsync();
|
||||
//return res;
|
||||
|
||||
if (apiResult != null)
|
||||
{
|
||||
var raw = JsonConvert.DeserializeObject<GetPermissionWithActingResultDto>(apiResult);
|
||||
return raw;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<dynamic> GetPermissionOrgAPIAsync(string action, string system, string profileId)
|
||||
{
|
||||
try
|
||||
|
|
|
|||
|
|
@ -2,24 +2,40 @@
|
|||
using BMA.EHR.Domain.Models.Placement;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System.Net.Http.Headers;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace BMA.EHR.Application.Repositories
|
||||
{
|
||||
/// <summary>
|
||||
/// Response model จาก Org API (check-isLeave)
|
||||
/// </summary>
|
||||
public class OrgProfileResult
|
||||
{
|
||||
public string citizenId { get; set; } = "";
|
||||
public string? profileId { get; set; }
|
||||
public bool isLeave { get; set; }
|
||||
public bool isActive { get; set; }
|
||||
}
|
||||
|
||||
public class PlacementRepository : GenericRepository<Guid, Placement>
|
||||
{
|
||||
#region " Fields "
|
||||
|
||||
private readonly IApplicationDBContext _dbContext;
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
#endregion
|
||||
|
||||
#region " Constructor and Destructor "
|
||||
|
||||
public PlacementRepository(IApplicationDBContext dbContext, IHttpContextAccessor httpContextAccessor) : base(dbContext, httpContextAccessor)
|
||||
public PlacementRepository(IApplicationDBContext dbContext, IHttpContextAccessor httpContextAccessor, IConfiguration configuration) : base(dbContext, httpContextAccessor)
|
||||
{
|
||||
_dbContext = dbContext;
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
_configuration = configuration;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
@ -76,6 +92,148 @@ namespace BMA.EHR.Application.Repositories
|
|||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Job อัพเดทสถานะผู้สอบผ่านที่ลาออกไปแล้วแต่ยังไม่ส่งไปออกคำสั่ง
|
||||
/// และอัพเดทบุคคลภายนอกที่เข้ามาอยู่ในระบบแล้ว
|
||||
/// ทำงานทุกวันเวลา 05:00 น.
|
||||
/// </summary>
|
||||
public async Task UpdateStatusPlacementProfiles()
|
||||
{
|
||||
Console.WriteLine("[Job:UpdateStatusPlacementProfiles] === STARTED ===");
|
||||
|
||||
// 1. Query ทั้ง 2 กรณี: ทุกคนที่ยังไม่ DONE
|
||||
var allCitizenIds = await _dbContext.Set<PlacementProfile>()
|
||||
.Where(p => !string.IsNullOrEmpty(p.CitizenId)
|
||||
&& p.PlacementStatus != "DONE"
|
||||
// && p.CitizenId == "2536721883131"
|
||||
)
|
||||
.Select(p => new { p.CitizenId, p.IsOfficer })
|
||||
.ToListAsync();
|
||||
|
||||
if (!allCitizenIds.Any())
|
||||
{
|
||||
Console.WriteLine("[Job:UpdateStatusPlacementProfiles] No profiles to process");
|
||||
return;
|
||||
}
|
||||
|
||||
var officerCount = allCitizenIds.Count(x => x.IsOfficer == true);
|
||||
var notOfficerCount = allCitizenIds.Count(x => x.IsOfficer == false);
|
||||
Console.WriteLine($"[Job:UpdateStatusPlacementProfiles] พบข้าราชการ {officerCount} คน, บุคคลภายนอก {notOfficerCount} คน");
|
||||
|
||||
// 2. ส่ง citizenIds ทั้งหมดไป Org API ครั้งเดียว
|
||||
var citizenIds = allCitizenIds.Select(x => x.CitizenId).Distinct().ToList();
|
||||
var apiUrl = $"{_configuration["API"]}/org/dotnet/check-isLeave";
|
||||
|
||||
List<OrgProfileResult> orgResults = new();
|
||||
|
||||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
|
||||
var payload = new { citizenIds };
|
||||
var jsonPayload = JsonConvert.SerializeObject(payload);
|
||||
var content = new StringContent(jsonPayload, System.Text.Encoding.UTF8, "application/json");
|
||||
|
||||
try
|
||||
{
|
||||
var response = await client.PostAsync(apiUrl, content);
|
||||
var result = await response.Content.ReadAsStringAsync();
|
||||
|
||||
var responseObj = JsonConvert.DeserializeAnonymousType(result, new
|
||||
{
|
||||
status = 0,
|
||||
message = "",
|
||||
result = new List<OrgProfileResult>()
|
||||
});
|
||||
|
||||
orgResults = responseObj?.result ?? new();
|
||||
Console.WriteLine($"[Job:UpdateStatusPlacementProfiles] Org API ตอบกลับ {orgResults.Count} รายการ");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"[Job:UpdateStatusPlacementProfiles] Call API failed: {ex.Message}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!orgResults.Any())
|
||||
{
|
||||
Console.WriteLine("[Job:UpdateStatusPlacementProfiles] ไม่มีรายการต้องอัปเดต");
|
||||
Console.WriteLine("[Job:UpdateStatusPlacementProfiles] === COMPLETED ===");
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. แยกข้อมูลตามเงื่อนไข
|
||||
var leaveCitizenIds = orgResults.Where(x => x.isLeave).Select(x => x.citizenId).ToList();
|
||||
var inSystemProfiles = orgResults.Where(x => x.isActive && !x.isLeave && !string.IsNullOrEmpty(x.profileId)).ToList();
|
||||
|
||||
Console.WriteLine($"[Job:UpdateStatusPlacementProfiles] ลาออก {leaveCitizenIds.Count} รายการ, อยู่ที่ทะเบียนประวัติ {inSystemProfiles.Count} รายการ");
|
||||
|
||||
// 4. Split Batch Update (500 รายการ/batch)
|
||||
var batchSize = 500;
|
||||
var totalUpdated = 0;
|
||||
|
||||
// 4.1 Update คนลาออก → IsOfficer = false
|
||||
if (leaveCitizenIds.Any())
|
||||
{
|
||||
var totalBatches = (int)Math.Ceiling((double)leaveCitizenIds.Count / batchSize);
|
||||
for (int i = 0; i < totalBatches; i++)
|
||||
{
|
||||
var batch = leaveCitizenIds.Skip(i * batchSize).Take(batchSize).ToList();
|
||||
|
||||
var profilesToUpdate = await _dbContext.Set<PlacementProfile>()
|
||||
.Where(p => !string.IsNullOrEmpty(p.CitizenId)
|
||||
&& batch.Contains(p.CitizenId)
|
||||
&& p.IsOfficer == true)
|
||||
.ToListAsync();
|
||||
|
||||
foreach (var profile in profilesToUpdate)
|
||||
{
|
||||
profile.profileId = null;
|
||||
profile.IsOfficer = false;
|
||||
}
|
||||
|
||||
await _dbContext.SaveChangesAsync();
|
||||
totalUpdated += profilesToUpdate.Count;
|
||||
Console.WriteLine($"[Job:UpdateStatusPlacementProfiles] [ลาออก] Batch {i + 1}/{totalBatches} → อัปเดต {profilesToUpdate.Count} รายการ");
|
||||
}
|
||||
}
|
||||
|
||||
// 4.2 Update คนที่อยู่ในทะเบียนประวัติ → profileId + IsOfficer = true
|
||||
if (inSystemProfiles.Any())
|
||||
{
|
||||
var totalBatches = (int)Math.Ceiling((double)inSystemProfiles.Count / batchSize);
|
||||
for (int i = 0; i < totalBatches; i++)
|
||||
{
|
||||
var batch = inSystemProfiles.Skip(i * batchSize).Take(batchSize).ToList();
|
||||
var batchCitizenIds = batch.Select(x => x.citizenId).ToList();
|
||||
|
||||
var profilesToUpdate = await _dbContext.Set<PlacementProfile>()
|
||||
.Where(p => !string.IsNullOrEmpty(p.CitizenId)
|
||||
&& batchCitizenIds.Contains(p.CitizenId)
|
||||
&& p.IsOfficer == false)
|
||||
.ToListAsync();
|
||||
|
||||
foreach (var profile in profilesToUpdate)
|
||||
{
|
||||
var orgProfile = batch.FirstOrDefault(x => x.citizenId == profile.CitizenId);
|
||||
if (orgProfile != null)
|
||||
{
|
||||
profile.profileId = orgProfile.profileId;
|
||||
profile.IsOfficer = true;
|
||||
}
|
||||
}
|
||||
|
||||
await _dbContext.SaveChangesAsync();
|
||||
totalUpdated += profilesToUpdate.Count;
|
||||
Console.WriteLine($"[Job:UpdateStatusPlacementProfiles] [เข้าระบบ] Batch {i + 1}/{totalBatches} → อัปเดต {profilesToUpdate.Count} รายการ");
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine($"[Job:UpdateStatusPlacementProfiles] อัปเดตรวมทั้งหมด {totalUpdated} รายการ");
|
||||
Console.WriteLine("[Job:UpdateStatusPlacementProfiles] === COMPLETED ===");
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -893,7 +893,7 @@ namespace BMA.EHR.Application.Repositories.Reports
|
|||
select new
|
||||
{
|
||||
RowNo = 1,
|
||||
DepartmentName = _userProfileRepository.GetOc(g.Key.OcId, 0, AccessToken).Root, //_organizationCommonRepository.GetOrganizationNameFullPath(g.Key.OcId, false, false),
|
||||
DepartmentName = _userProfileRepository.GetOc(g.Key.OcId, 0, AccessToken)?.Root ?? "-", //_organizationCommonRepository.GetOrganizationNameFullPath(g.Key.OcId, false, false),
|
||||
G1Male = g.Sum(x => x.Gendor == "ชาย" && x.RequestInsigniaName == "เหรียญจักรพรรดิมาลา" ? 1 : 0),
|
||||
G1Female = g.Sum(x => x.Gendor == "หญิง" && x.RequestInsigniaName == "เหรียญจักรพรรดิมาลา" ? 1 : 0),
|
||||
G2Male = g.Sum(x => x.Gendor == "ชาย" ? 1 : 0),
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@ namespace BMA.EHR.Application.Repositories.Reports
|
|||
}).ToList();
|
||||
}
|
||||
string SignDate = retireHistorys.SignDate != null ? DateTime.Parse(retireHistorys.SignDate.ToString()).ToThaiFullDate().ToString().ToThaiNumber() : "-";
|
||||
return new { SignDate, retireHistorys.Detail, retireHistorys.Id, retireHistorys.CreatedAt, Year = retireHistorys.Year.ToThaiYear().ToString().ToThaiNumber(), retireHistorys.Round, retireHistorys.Type, retireHistorys.TypeReport, Total = retireHistorys.Total.ToString().ToThaiNumber(), profiles = mapProfiles };
|
||||
return new { SignDate, Detail = retireHistorys.Detail.ToThaiNumber(), retireHistorys.Id, retireHistorys.CreatedAt, Year = retireHistorys.Year.ToThaiYear().ToString().ToThaiNumber(), retireHistorys.Round, retireHistorys.Type, retireHistorys.TypeReport, Total = retireHistorys.Total.ToString().ToThaiNumber(), profiles = mapProfiles };
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -312,7 +312,7 @@ namespace BMA.EHR.Application.Repositories.Reports
|
|||
root = (isDuplicateRoot ? "" : profile.root + "\n") +
|
||||
(isDuplicateHospital || !hospital.ToObject<List<string>>().Contains(profile.child1) ? "" : profile.child1 + "\n") +
|
||||
(isDuplicatePosType ? "" : $"ตำแหน่งประเภท{profile.posTypeName}" + "\n") +
|
||||
(isDuplicatePosLevel ? "" : $"ระดับ{profile.posLevelName}"),
|
||||
(isDuplicatePosLevel ? "" : $"ระดับ{profile.posLevelName}").ToThaiNumber(),
|
||||
child = (profile.posExecutiveName == null ? "" : profile.posExecutiveName + "\n") +
|
||||
(profile.child4 == null ? "" : profile.child4 + "\n") +
|
||||
(profile.child3 == null ? "" : profile.child3 + "\n") +
|
||||
|
|
@ -326,7 +326,7 @@ namespace BMA.EHR.Application.Repositories.Reports
|
|||
}).ToList();
|
||||
}
|
||||
string SignDate = retire.SignDate != null ? DateTime.Parse(retire.SignDate.ToString()).ToThaiFullDate().ToString().ToThaiNumber() : "-";
|
||||
return new { SignDate, retire.Detail, retire.Id, retire.CreatedAt, Year = retire.Year.ToThaiYear().ToString().ToThaiNumber(), retire.Round, retire.Type, retire.TypeReport, Total = profile_retire.Count.ToString().ToThaiNumber(), profiles = mapProfiles };
|
||||
return new { SignDate, Detail = retire.Detail.ToThaiNumber(), retire.Id, retire.CreatedAt, Year = retire.Year.ToThaiYear().ToString().ToThaiNumber(), retire.Round, retire.Type, retire.TypeReport, Total = profile_retire.Count.ToString().ToThaiNumber(), profiles = mapProfiles };
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
|
|
|||
|
|
@ -186,13 +186,61 @@ namespace BMA.EHR.Application.Repositories
|
|||
}
|
||||
}
|
||||
|
||||
public async Task<GetProfileByKeycloakIdDto?> GetProfileByKeycloakIdNewAsync(Guid keycloakId, string? accessToken)
|
||||
|
||||
|
||||
public async Task<GetProfileByKeycloakIdDto?> GetProfileByKeycloakIdNewAsync(Guid keycloakId, string? accessToken,CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
var apiPath = $"{_configuration["API"]}/org/dotnet/by-keycloak/{keycloakId}";
|
||||
var apiKey = _configuration["API_KEY"];
|
||||
|
||||
var apiResult = await GetExternalAPIAsync(apiPath, accessToken ?? "", apiKey, cancellationToken);
|
||||
if (apiResult != null)
|
||||
{
|
||||
var raw = JsonConvert.DeserializeObject<GetProfileByKeycloakIdResultDto>(apiResult);
|
||||
if (raw != null)
|
||||
return raw.Result;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<GetProfileByKeycloakIdDto?> GetProfileByKeycloakIdNew2Async(Guid keycloakId, string? accessToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
var apiPath = $"{_configuration["API"]}/org/dotnet/by-keycloak2/{keycloakId}";
|
||||
var apiKey = _configuration["API_KEY"];
|
||||
|
||||
var apiResult = await GetExternalAPIAsync(apiPath, accessToken ?? "", apiKey);
|
||||
if (apiResult != null)
|
||||
{
|
||||
var raw = JsonConvert.DeserializeObject<GetProfileByKeycloakIdResultDto>(apiResult);
|
||||
if (raw != null)
|
||||
return raw.Result;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<GetProfileByKeycloakIdDto?> GetProfileByCheckInAsync(Guid keycloakId, string? accessToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
var apiPath = $"{_configuration["API"]}/org/dotnet/check-keycloak/{keycloakId}";
|
||||
var apiKey = _configuration["API_KEY"];
|
||||
|
||||
var apiResult = await GetExternalAPIAsync(apiPath, accessToken ?? "", apiKey);
|
||||
if (apiResult != null)
|
||||
{
|
||||
|
|
@ -233,6 +281,36 @@ namespace BMA.EHR.Application.Repositories
|
|||
}
|
||||
}
|
||||
|
||||
public async Task<List<GetOcStaff>?> GetOCStaffAsync(Guid profileId, string? accessToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
var apiPath = $"{_configuration["API"]}/org/dotnet/find-staff";
|
||||
var apiKey = _configuration["API_KEY"];
|
||||
var body = new
|
||||
{
|
||||
assignId = "SYS_LEAVE_LIST",
|
||||
profileId = profileId
|
||||
};
|
||||
|
||||
//var profiles = new List<GetOcStaff>();
|
||||
|
||||
var apiResult = await PostExternalAPIAsync(apiPath, accessToken ?? "", body, apiKey);
|
||||
if (apiResult != null)
|
||||
{
|
||||
var raw = JsonConvert.DeserializeObject<GetOcStaffResultDto>(apiResult);
|
||||
if (raw != null)
|
||||
return raw.Result;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<GetProfileLeaveByKeycloakDto?> GetProfileLeaveReportByKeycloakIdAsync(Guid keycloakId, string? accessToken, string? report)
|
||||
{
|
||||
try
|
||||
|
|
@ -245,7 +323,7 @@ namespace BMA.EHR.Application.Repositories
|
|||
report = report
|
||||
};
|
||||
|
||||
var profiles = new List<SearchProfileDto>();
|
||||
//var profiles = new List<SearchProfileDto>();
|
||||
|
||||
var apiResult = await PostExternalAPIAsync(apiPath, accessToken, body, apiKey);
|
||||
if (apiResult != null)
|
||||
|
|
@ -286,6 +364,31 @@ namespace BMA.EHR.Application.Repositories
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public async Task<GetProfileByKeycloakIdDto?> GetProfileByProfileIdNoAuthAsync(Guid profileId, string? accessToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
var apiPath = $"{_configuration["API"]}/org/unauthorize/profile/{profileId}";
|
||||
var apiKey = _configuration["API_KEY"];
|
||||
|
||||
var apiResult = await GetExternalAPIAsync(apiPath, accessToken ?? "", apiKey);
|
||||
if (apiResult != null)
|
||||
{
|
||||
var raw = JsonConvert.DeserializeObject<GetProfileByKeycloakIdResultDto>(apiResult);
|
||||
if (raw != null)
|
||||
return raw.Result;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public async Task<bool> UpdateDutyTimeAsync(Guid profileId, Guid roundId, DateTime effectiveDate, string? accessToken)
|
||||
{
|
||||
try
|
||||
|
|
@ -684,6 +787,75 @@ namespace BMA.EHR.Application.Repositories
|
|||
}
|
||||
}
|
||||
|
||||
public async Task<List<GetProfileByKeycloakIdRootDto>> GetAllOfficerByRootDnaId(string? rootDnaId, DateTime date)
|
||||
{
|
||||
try
|
||||
{
|
||||
var apiPath = $"{_configuration["API"]}/org/unauthorize/officer-list";
|
||||
var apiKey = _configuration["API_KEY"];
|
||||
var body = new
|
||||
{
|
||||
reqNode = 0,
|
||||
reqNodeId = rootDnaId,
|
||||
date = date
|
||||
};
|
||||
//Console.WriteLine(body);
|
||||
|
||||
var profiles = new List<SearchProfileDto>();
|
||||
|
||||
var apiResult = await PostExternalAPIAsync(apiPath, "", body, apiKey);
|
||||
if (apiResult != null)
|
||||
{
|
||||
var raw = JsonConvert.DeserializeObject<GetListProfileByKeycloakIdRootResultDto>(apiResult);
|
||||
if (raw != null)
|
||||
return raw.Result;
|
||||
else
|
||||
return new List<GetProfileByKeycloakIdRootDto>();
|
||||
}
|
||||
else
|
||||
return new List<GetProfileByKeycloakIdRootDto>();
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<List<GetProfileByKeycloakIdRootDto>> GetAllEmployeeByRootDnaId(string? rootDnaId, DateTime date)
|
||||
{
|
||||
try
|
||||
{
|
||||
var apiPath = $"{_configuration["API"]}/org/unauthorize/employee-list";
|
||||
var apiKey = _configuration["API_KEY"];
|
||||
var body = new
|
||||
{
|
||||
reqNode = 0,
|
||||
reqNodeId = rootDnaId,
|
||||
startDate = date,
|
||||
endDate = date
|
||||
};
|
||||
//Console.WriteLine(body);
|
||||
|
||||
var profiles = new List<SearchProfileDto>();
|
||||
|
||||
var apiResult = await PostExternalAPIAsync(apiPath, "", body, apiKey);
|
||||
if (apiResult != null)
|
||||
{
|
||||
var raw = JsonConvert.DeserializeObject<GetListProfileByKeycloakIdRootResultDto>(apiResult);
|
||||
if (raw != null)
|
||||
return raw.Result;
|
||||
else
|
||||
return new List<GetProfileByKeycloakIdRootDto>();
|
||||
}
|
||||
else
|
||||
return new List<GetProfileByKeycloakIdRootDto>();
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<List<GetProfileByKeycloakIdRootDto>> GetProfileByAdminRolev4(string? accessToken, int? node, string? nodeId, string role, string? revisionId, int? reqNode, string? reqNodeId, DateTime? startDate, DateTime? endDate)
|
||||
{
|
||||
try
|
||||
|
|
@ -890,7 +1062,43 @@ namespace BMA.EHR.Application.Repositories
|
|||
}
|
||||
}
|
||||
|
||||
public async Task<GetProfileByKeycloakIdRootAddTotalDto> SearchProfile(string? citizenId, string? firstName, string? lastName, string accessToken, int page, int pageSize, string? role, string? nodeId, int? node)
|
||||
public async Task<List<GetProfileByKeycloakIdRootDto>> GetEmployeeByAdminRolev2(string? accessToken, int? node, string? nodeId, string role, string? revisionId, int? reqNode, string? reqNodeId, DateTime? startDate, DateTime? endDate)
|
||||
{
|
||||
try
|
||||
{
|
||||
var apiPath = $"{_configuration["API"]}/org/dotnet/employee-by-admin-rolev2";
|
||||
var apiKey = _configuration["API_KEY"];
|
||||
var body = new
|
||||
{
|
||||
node = node,
|
||||
nodeId = nodeId,
|
||||
role = role,
|
||||
// isRetirement
|
||||
reqNode = reqNode,
|
||||
reqNodeId = reqNodeId,
|
||||
date = endDate
|
||||
};
|
||||
Console.WriteLine(body);
|
||||
|
||||
var profiles = new List<SearchProfileDto>();
|
||||
|
||||
var apiResult = await PostExternalAPIAsync(apiPath, accessToken, body, apiKey);
|
||||
if (apiResult != null)
|
||||
{
|
||||
var raw = JsonConvert.DeserializeObject<GetListProfileByKeycloakIdRootResultDto>(apiResult);
|
||||
if (raw != null)
|
||||
return raw.Result;
|
||||
}
|
||||
|
||||
return new List<GetProfileByKeycloakIdRootDto>();
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<GetProfileByKeycloakIdRootAddTotalDto> SearchProfile(string? citizenId, string? firstName, string? lastName, string accessToken, int page, int pageSize, string? role, string? nodeId, int? node,string? selectedNodeId,int? selectedNode )
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -906,6 +1114,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
node = node,
|
||||
page = page,
|
||||
pageSize = pageSize,
|
||||
selectedNodeId = selectedNodeId,
|
||||
selectedNode = selectedNode
|
||||
};
|
||||
|
||||
var profiles = new List<GetProfileByKeycloakIdRootDto>();
|
||||
|
|
@ -1108,6 +1318,38 @@ namespace BMA.EHR.Application.Repositories
|
|||
}
|
||||
}
|
||||
|
||||
public GetOrganizationResponseDTO? GetOcByNodeId(Guid ocId, int level, string? accessToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
var apiPath = $"{_configuration["API"]}/org/find/all";
|
||||
var apiKey = _configuration["API_KEY"];
|
||||
var body = new
|
||||
{
|
||||
nodeId = ocId,
|
||||
node = level
|
||||
|
||||
};
|
||||
|
||||
var apiResult = PostExternalAPIAsync(apiPath, accessToken ?? "", body, apiKey).Result;
|
||||
if (apiResult != null)
|
||||
{
|
||||
var raw = JsonConvert.DeserializeObject<GetOrganizationResponseResultDTO>(apiResult);
|
||||
if (raw != null && raw.Result != null)
|
||||
{
|
||||
return raw.Result;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public GetOrganizationResponseDTO? GetOc(Guid ocId, int level, string? accessToken)
|
||||
{
|
||||
try
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using BMA.EHR.Domain.Shared;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace BMA.EHR.Application.Responses.Leaves
|
||||
{
|
||||
public class GetPermissionWithActingDto
|
||||
{
|
||||
public string privilege {get; set;} = string.Empty;
|
||||
public bool isAct {get; set;} = false;
|
||||
public List<ActingPermission> posMasterActs {get; set;} = new();
|
||||
}
|
||||
|
||||
public class ActingPermission
|
||||
{
|
||||
public string posNo {get; set;} = string.Empty;
|
||||
//public string? privilege {get; set;} = "PARENT";
|
||||
[JsonConverter(typeof(PrivilegeConverter))]
|
||||
public string privilege {get; set;} = "CHILD";
|
||||
|
||||
public Guid? rootDnaId {get; set;}
|
||||
public Guid? child1DnaId {get; set;}
|
||||
public Guid? child2DnaId {get; set;}
|
||||
public Guid? child3DnaId {get; set;}
|
||||
public Guid? child4DnaId {get; set;}
|
||||
}
|
||||
|
||||
public class GetPermissionWithActingResultDto
|
||||
{
|
||||
public int status {get; set;} = 0;
|
||||
public string message {get; set;} = string.Empty;
|
||||
public GetPermissionWithActingDto result {get; set;} = new();
|
||||
}
|
||||
}
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
public string Age { get; set; } = string.Empty;
|
||||
public DateTime DateAppoint { get; set; }
|
||||
public DateTime DateCurrent { get; set; }
|
||||
public int Amount { get; set; }
|
||||
public int? Amount { get; set; } = 0;
|
||||
public string? TelephoneNumber { get; set; } = string.Empty;
|
||||
public string Position { get; set; } = string.Empty;
|
||||
public string PosLevel { get; set; } = string.Empty;
|
||||
|
|
|
|||
35
BMA.EHR.Application/Responses/Profiles/GetOcStaff.cs
Normal file
35
BMA.EHR.Application/Responses/Profiles/GetOcStaff.cs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BMA.EHR.Application.Responses.Profiles
|
||||
{
|
||||
public class GetOcStaff
|
||||
{
|
||||
public Guid ProfileId { get; set; }
|
||||
public Guid Keycloak { get; set; }
|
||||
public string FullName { get; set; } = null!;
|
||||
public Guid? RootId { get; set; }
|
||||
public Guid? OrgChild1Id { get; set; }
|
||||
public Guid? OrgChild2Id { get; set; }
|
||||
public Guid? OrgChild3Id { get; set; }
|
||||
public Guid? OrgChild4Id { get; set; }
|
||||
public Guid? RootDnaId { get; set; }
|
||||
public Guid? Child1DnaId { get; set; }
|
||||
public Guid? Child2DnaId { get; set; }
|
||||
public Guid? Child3DnaId { get; set; }
|
||||
public Guid? Child4DnaId { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public class GetOcStaffResultDto
|
||||
{
|
||||
public string Message { get; set; } = string.Empty;
|
||||
|
||||
public int Status { get; set; } = -1;
|
||||
|
||||
public List<GetOcStaff> Result { get; set; } = new();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -44,6 +44,8 @@ namespace BMA.EHR.Application.Responses.Profiles
|
|||
public string? ProfileType { get; set; }
|
||||
public bool? IsLeave { get; set; }
|
||||
|
||||
public bool? IsProbation { get; set; }
|
||||
|
||||
public string? Root { get; set; }
|
||||
public string? Child1 { get; set; }
|
||||
public string? Child2 { get; set; }
|
||||
|
|
|
|||
|
|
@ -25,6 +25,12 @@ namespace BMA.EHR.Application.Responses.Profiles
|
|||
public DateTime? DateStart { get; set; }
|
||||
|
||||
public DateTime? DateAppoint { get; set; }
|
||||
|
||||
public string? RootDnaId { get; set; }
|
||||
public string? Child1DnaId { get; set; }
|
||||
public string? Child2DnaId { get; set; }
|
||||
public string? Child3DnaId { get; set; }
|
||||
public string? Child4DnaId { get; set; }
|
||||
}
|
||||
|
||||
public class GetProfileByKeycloakIdRootAddTotalDto
|
||||
|
|
|
|||
24
BMA.EHR.CheckInConsumer/.dockerignore
Normal file
24
BMA.EHR.CheckInConsumer/.dockerignore
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
# Build artifacts
|
||||
bin/
|
||||
obj/
|
||||
|
||||
# IDE / tooling
|
||||
Properties/
|
||||
.vs/
|
||||
.vscode/
|
||||
.idea/
|
||||
|
||||
# Source control
|
||||
.git/
|
||||
.gitignore
|
||||
|
||||
# Documentation
|
||||
*.md
|
||||
|
||||
# Docker
|
||||
Dockerfile
|
||||
.dockerignore
|
||||
|
||||
# OS files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
83
BMA.EHR.CheckInConsumer/CHANGELOG-checkin-speedup.md
Normal file
83
BMA.EHR.CheckInConsumer/CHANGELOG-checkin-speedup.md
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
# สรุปการปรับปรุงระบบลงเวลา (CheckInConsumer)
|
||||
|
||||
วันที่แก้ไข: 23 มิถุนายน 2026
|
||||
|
||||
---
|
||||
|
||||
## ปัญหาเดิม
|
||||
|
||||
ตอนที่พนักงานลงเวลาพร้อมกันจำนวนมาก (ประมาณ 2,000 รายการ) ระบบประมวลผลทีละรายการ ทำให้ต้องรอคิวนานถึง **22 นาที** กว่าจะประมวลผลเสร็จทั้งหมด
|
||||
|
||||
เปรียบเทียบเหมือน **โต๊ะบัญชี 1 คน รับคิวทีละคน** ทั้งที่มีคนรอ 2,000 คน → คิวยาวมาก
|
||||
|
||||
---
|
||||
|
||||
## วิธีที่แก้ (เข้าใจง่าย ๆ)
|
||||
|
||||
### 1. เพิ่มคนช่วยประมวลผลพร้อมกัน (Concurrency)
|
||||
- **ก่อน:** ประมวลผลทีละรายการ (เหมือนมีโต๊ะบัญชี 1 โต๊ะ)
|
||||
- **หลัง:** ประมวลผลพร้อมกันได้สูงสุด **5 รายการ** (เหมือนเปิดโต๊ะบัญชี 5 โต๊ะ)
|
||||
|
||||
> ผลที่ได้: เวลารอคิวลดลงจาก **22 นาที → ประมาณ 4–5 นาที**
|
||||
|
||||
### 2. จัดคิวล่วงหน้าให้ RabbitMQ (Prefetch)
|
||||
- **ก่อน:** ระบบดึงข้อมูลมาทีละชิ้น ทำให้เสียเวลารอส่งต่อ
|
||||
- **หลัง:** ระบบดึงข้อมูลมาเป็นชุด ๆ ละ 20 ชิ้นไว้เตรียมพร้อม → ลดเวลารอระหว่างรายการ
|
||||
|
||||
### 3. ลดเวลารอเมื่อ API มีปัญหา (Timeout)
|
||||
- **ก่อน:** ถ้า API ค้าง ระบบจะรอนานถึง **5 นาที** ต่อรายการ
|
||||
- **หลัง:** ลดเหลือ **1 นาที** → รายการที่มีปัญหาจะถูกปฏิเสธเร็วขึ้น ไม่ทำให้คิวค้าง
|
||||
|
||||
### 4. ปรับปรุงการเชื่อมต่อ HTTP
|
||||
- เปลี่ยนระบบเชื่อมต่อให้รองรับการส่งคำขอหลายรายการพร้อมกันโดยไม่สะดุด
|
||||
|
||||
---
|
||||
|
||||
## ตัวเลขเปรียบเทียบ
|
||||
|
||||
| รายการ | ก่อนแก้ | หลังแก้ |
|
||||
|---|---|---|
|
||||
| จำนวนรายการที่ประมวลผลพร้อมกัน | 1 | 5 |
|
||||
| เวลารอคิวสูงสุด (2,000 รายการ) | ~22 นาที | ~4–5 นาที |
|
||||
| เวลารอเมื่อ API มีปัญหา | 5 นาที | 1 นาที |
|
||||
|
||||
---
|
||||
|
||||
## ไฟล์ที่แก้ไข
|
||||
|
||||
1. **`Program.cs`** — โค้ดหลักของตัวประมวลผลคิว
|
||||
2. **`appsettings.json`** — ไฟล์ตั้งค่าระบบ
|
||||
|
||||
---
|
||||
|
||||
## วิธีปรับความเร็วเพิ่มเติม (ไม่ต้องเขียนโค้ดใหม่)
|
||||
|
||||
ถ้าหลังทดสอบแล้วเห็นว่าระบบรับได้ และอยากให้เร็วขึ้นอีก ให้แก้ไขไฟล์ `appsettings.json` แล้ว restart โปรแกรมได้เลย:
|
||||
|
||||
```json
|
||||
{
|
||||
"MaxConcurrency": 10, ← เพิ่มจาก 5 เป็น 10 (ประมวลผลพร้อมกัน 10 รายการ)
|
||||
"PrefetchCount": 50, ← ควรตั้งเป็น ประมาณ MaxConcurrency × 2 ขึ้นไป
|
||||
"HttpTimeoutSeconds": 60 ← เวลารอ API วินาที
|
||||
}
|
||||
```
|
||||
|
||||
**ค่าที่ใช้และผลที่คาดการณ์:**
|
||||
- `MaxConcurrency = 5` → ใช้เวลา ~4–5 นาที (ค่าเริ่มต้นปลอดภัย)
|
||||
- `MaxConcurrency = 10` → ใช้เวลา ~2–3 นาที
|
||||
- `MaxConcurrency = 20` → ใช้เวลา ~1–2 นาที (ต้องตรวจสอบว่าระบบหลังบ้านรับไหวก่อน)
|
||||
|
||||
---
|
||||
|
||||
## ข้อควรระวัง / คำแนะนำ
|
||||
|
||||
1. **ควรทดสอบในระบบทดสอบก่อน** โดยดูว่า
|
||||
- ไม่มี error ในระบบหลัก (API)
|
||||
- ฐานข้อมูลไม่ช้าผิดปกติ
|
||||
- ไม่พบปัญหาลงเวลาซ้ำซ้อน
|
||||
|
||||
2. ถ้าพบปัญหา เช่น
|
||||
- มี error ใน API → **ลด** `MaxConcurrency` เหลือ 2 หรือ 3
|
||||
- ลงเวลาซ้ำ → แจ้งทีมเทคนิคเพื่อแก้ฝั่ง API เพิ่มเติม
|
||||
|
||||
3. **ค่า `MaxConcurrency = 5` เป็นค่าปลอดภัย** เพราะระบบ API ด้านหลังยังมีข้อจำกัดอยู่บางส่วน หากต้องการเพิ่มให้สูงกว่านี้ (เช่น 20–50) ควรปรึกษาทีมเทคนิคเพื่อปรับปรุงฝั่ง API ก่อน
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
## See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
|
||||
## See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
|
||||
#
|
||||
## This stage is used when running from VS in fast mode (Default for Debug configuration)
|
||||
#FROM mcr.microsoft.com/dotnet/runtime:8.0 AS base
|
||||
|
|
@ -21,6 +21,7 @@
|
|||
#ARG BUILD_CONFIGURATION=Release
|
||||
#RUN dotnet publish "BMA.EHR.CheckInConsumer.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
|
||||
#
|
||||
|
||||
## This stage is used in production or when running from VS in regular mode (Default when not using the Debug configuration)
|
||||
#FROM base AS final
|
||||
#WORKDIR /app
|
||||
|
|
@ -29,30 +30,25 @@
|
|||
|
||||
|
||||
# ใช้ official .NET SDK image สำหรับการ build
|
||||
# Note: Build context = repository root (ตามที่ GitHub Actions ใช้)
|
||||
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
|
||||
|
||||
# กำหนด working directory ภายใน container
|
||||
WORKDIR /src
|
||||
|
||||
# คัดลอกไฟล์ .csproj และ restore dependencies
|
||||
# COPY *.csproj ./
|
||||
COPY . ./
|
||||
RUN dotnet restore
|
||||
# copy เฉพาะ .csproj ก่อน เพื่อใช้ layer caching (restore เร็ว เก็บ cache นาน)
|
||||
COPY BMA.EHR.CheckInConsumer/BMA.EHR.CheckInConsumer.csproj ./BMA.EHR.CheckInConsumer/
|
||||
WORKDIR /src/BMA.EHR.CheckInConsumer
|
||||
RUN dotnet restore "BMA.EHR.CheckInConsumer.csproj"
|
||||
|
||||
# คัดลอกไฟล์ทั้งหมดและ build
|
||||
COPY . ./
|
||||
RUN dotnet build -c Release -o /app/build
|
||||
# WORKDIR "/src/BMA.EHR.CheckInConsumer"
|
||||
# RUN dotnet build "BMA.EHR.CheckInConsumer.csproj" -c Release -o /app/build
|
||||
# คัดลอก source ที่เหลือแล้ว publish
|
||||
COPY BMA.EHR.CheckInConsumer/ ./
|
||||
RUN dotnet publish "BMA.EHR.CheckInConsumer.csproj" -c Release -o /app/publish /p:UseAppHost=false
|
||||
|
||||
# ใช้ stage ใหม่สำหรับการ runtime
|
||||
# ใช้ stage ใหม่สำหรับ runtime (image เล็กลง)
|
||||
FROM mcr.microsoft.com/dotnet/runtime:8.0 AS runtime
|
||||
|
||||
# กำหนด working directory สำหรับ runtime
|
||||
WORKDIR /app
|
||||
|
||||
# คัดลอกไฟล์จาก build stage มายัง runtime stage
|
||||
COPY --from=build /app/build .
|
||||
COPY --from=build /app/publish .
|
||||
|
||||
# ระบุ entry point ของแอปพลิเคชัน
|
||||
ENTRYPOINT ["dotnet", "BMA.EHR.CheckInConsumer.dll"]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using RabbitMQ.Client;
|
||||
using RabbitMQ.Client.Events;
|
||||
using System.Text;
|
||||
|
|
@ -18,80 +18,133 @@ var user = configuration["Rabbit:User"] ?? "";
|
|||
var pass = configuration["Rabbit:Password"] ?? "";
|
||||
var queue = configuration["Rabbit:Queue"] ?? "basic-queue";
|
||||
|
||||
// Concurrency & prefetch (configurable via appsettings.json)
|
||||
var maxConcurrency = int.TryParse(configuration["MaxConcurrency"], out var c) && c > 0 ? c : 5;
|
||||
var prefetchCount = ushort.TryParse(configuration["PrefetchCount"], out var p) && p > 0 ? p : (ushort)20;
|
||||
var httpTimeoutSec = int.TryParse(configuration["HttpTimeoutSeconds"], out var t) && t > 0 ? t : 60;
|
||||
|
||||
WriteToConsole($"Config -> MaxConcurrency: {maxConcurrency}, PrefetchCount: {prefetchCount}, HttpTimeout: {httpTimeoutSec}s");
|
||||
|
||||
// create connection
|
||||
var factory = new ConnectionFactory()
|
||||
{
|
||||
//Uri = new Uri("amqp://admin:P@ssw0rd@192.168.4.11:5672")
|
||||
HostName = host,// หรือ hostname ของ RabbitMQ Server ที่คุณใช้
|
||||
UserName = user, // ใส่ชื่อผู้ใช้ของคุณ
|
||||
Password = pass // ใส่รหัสผ่านของคุณ
|
||||
HostName = host,
|
||||
UserName = user,
|
||||
Password = pass,
|
||||
DispatchConsumersAsync = true
|
||||
};
|
||||
|
||||
using var connection = factory.CreateConnection();
|
||||
using var channel = connection.CreateModel();
|
||||
|
||||
//channel.QueueDeclare(queue: "bma-checkin-queue", durable: true, exclusive: false, autoDelete: false, arguments: null);
|
||||
channel.QueueDeclare(queue: queue, durable: true, exclusive: false, autoDelete: false, arguments: null);
|
||||
|
||||
var consumer = new EventingBasicConsumer(channel);
|
||||
// Prefetch: RabbitMQ จะส่ง message หลายตัวมาที่ consumer พร้อมกัน (ลด network round-trip)
|
||||
channel.BasicQos(prefetchSize: 0, prefetchCount: prefetchCount, global: false);
|
||||
|
||||
consumer.Received += async (model, ea) =>
|
||||
// HttpClient แบบ SocketsHttpHandler พร้อม connection pooling รองรับ concurrent requests
|
||||
var socketsHandler = new SocketsHttpHandler
|
||||
{
|
||||
var body = ea.Body.ToArray();
|
||||
var message = Encoding.UTF8.GetString(body);
|
||||
await CallRestApi(message);
|
||||
MaxConnectionsPerServer = maxConcurrency * 2,
|
||||
PooledConnectionLifetime = TimeSpan.FromMinutes(2),
|
||||
PooledConnectionIdleTimeout = TimeSpan.FromSeconds(30)
|
||||
};
|
||||
using var httpClient = new HttpClient(socketsHandler);
|
||||
httpClient.Timeout = TimeSpan.FromSeconds(httpTimeoutSec);
|
||||
|
||||
// convert string into object
|
||||
//var request = JsonConvert.DeserializeObject<CheckInRequest>(message);
|
||||
//using (var db = new ApplicationDbContext())
|
||||
//{
|
||||
// var item = new AttendantItem
|
||||
// {
|
||||
// Name = request.Name,
|
||||
// CheckInDateTime = request.CheckInDateTime,
|
||||
// };
|
||||
// db.AttendantItems.Add(item);
|
||||
// db.SaveChanges();
|
||||
// SemaphoreSlim คุมจำนวน message ที่ประมวลผลพร้อมกัน (เนื่องจาก API มีข้อจำกัดเรื่อง concurrency)
|
||||
using var semaphore = new SemaphoreSlim(maxConcurrency, maxConcurrency);
|
||||
|
||||
// WriteToConsole($"ได้รับคำขอจาก Queue: {message}");
|
||||
// WriteToConsole($"ตอบกลับจาก REST API: {JsonConvert.SerializeObject(item)}");
|
||||
//}
|
||||
var consumer = new AsyncEventingBasicConsumer(channel);
|
||||
|
||||
WriteToConsole($"ได้รับคำขอจาก Queue: {message}");
|
||||
//WriteToConsole($"ตอบกลับจาก REST API: {JsonConvert.SerializeObject(item)}");
|
||||
consumer.Received += (model, ea) =>
|
||||
{
|
||||
// รอ semaphore ก่อนเริ่มประมวลผล
|
||||
semaphore.WaitAsync().ContinueWith(async _ =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var body = ea.Body.ToArray();
|
||||
var message = Encoding.UTF8.GetString(body);
|
||||
|
||||
WriteToConsole($"Received message: {message}");
|
||||
|
||||
var success = await CallRestApi(message, httpClient, configuration);
|
||||
|
||||
if (success)
|
||||
{
|
||||
channel.BasicAck(ea.DeliveryTag, multiple: false);
|
||||
WriteToConsole("Message processed successfully");
|
||||
}
|
||||
else
|
||||
{
|
||||
channel.BasicNack(ea.DeliveryTag, multiple: false, requeue: false);
|
||||
WriteToConsole("Message processing failed - message rejected");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
WriteToConsole($"Error processing message: {ex.Message}");
|
||||
channel.BasicNack(ea.DeliveryTag, multiple: false, requeue: false);
|
||||
}
|
||||
finally
|
||||
{
|
||||
semaphore.Release();
|
||||
}
|
||||
}, TaskScheduler.Default).ConfigureAwait(false);
|
||||
|
||||
return Task.CompletedTask;
|
||||
};
|
||||
|
||||
//channel.BasicConsume(queue: "bma-checkin-queue", autoAck: true, consumer: consumer);
|
||||
channel.BasicConsume(queue: queue, autoAck: true, consumer: consumer);
|
||||
channel.BasicConsume(queue: queue, autoAck: false, consumer: consumer);
|
||||
|
||||
//Console.WriteLine("\nPress 'Enter' to exit the process...");
|
||||
WriteToConsole("Consumer started. Waiting for messages...");
|
||||
|
||||
// Keep the application running
|
||||
await Task.Delay(-1);
|
||||
|
||||
static void WriteToConsole(string message)
|
||||
{
|
||||
Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} : {message}");
|
||||
Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss} : {message}");
|
||||
}
|
||||
|
||||
async Task CallRestApi(string requestData)
|
||||
static async Task<bool> CallRestApi(string requestData, HttpClient client, IConfiguration configuration)
|
||||
{
|
||||
using var client = new HttpClient();
|
||||
var apiPath = $"{configuration["API"]}/leave/process-check-in";
|
||||
|
||||
var content = new StringContent(requestData, Encoding.UTF8, "application/json");
|
||||
|
||||
var response = await client.PostAsync(apiPath, content);
|
||||
|
||||
if (response.IsSuccessStatusCode)
|
||||
try
|
||||
{
|
||||
var responseContent = await response.Content.ReadAsStringAsync();
|
||||
WriteToConsole(responseContent);
|
||||
var apiPath = $"{configuration["API"]}/leave/process-check-in";
|
||||
var content = new StringContent(requestData, Encoding.UTF8, "application/json");
|
||||
|
||||
var response = await client.PostAsync(apiPath, content);
|
||||
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
var responseContent = await response.Content.ReadAsStringAsync();
|
||||
WriteToConsole($"API Success: {responseContent}");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
var errorMessage = await response.Content.ReadAsStringAsync();
|
||||
var res = JsonSerializer.Deserialize<ResponseObject>(errorMessage);
|
||||
WriteToConsole($"API Error ({response.StatusCode}): {res?.Message ?? errorMessage}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
catch (HttpRequestException ex)
|
||||
{
|
||||
var errorMessage = await response.Content.ReadAsStringAsync();
|
||||
var res = JsonSerializer.Deserialize<ResponseObject>(errorMessage);
|
||||
WriteToConsole($"Error: {res.Message}");
|
||||
WriteToConsole($"HTTP Error: {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
catch (TaskCanceledException ex)
|
||||
{
|
||||
WriteToConsole($"Timeout: {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
WriteToConsole($"Unexpected Error: {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -110,28 +163,14 @@ public class ResponseObject
|
|||
public class CheckTimeDtoRB
|
||||
{
|
||||
public Guid? CheckInId { get; set; }
|
||||
|
||||
|
||||
public double Lat { get; set; } = 0;
|
||||
|
||||
|
||||
public double Lon { get; set; } = 0;
|
||||
|
||||
|
||||
public string POI { get; set; } = string.Empty;
|
||||
|
||||
|
||||
public bool IsLocation { get; set; } = true;
|
||||
|
||||
public string? LocationName { get; set; } = string.Empty;
|
||||
|
||||
public string? Remark { get; set; } = string.Empty;
|
||||
|
||||
public Guid? UserId { get; set; }
|
||||
|
||||
public DateTime? CurrentDate { get; set; }
|
||||
|
||||
public string? CheckInFileName { get; set; }
|
||||
|
||||
public byte[]? CheckInFileBytes { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,5 +5,8 @@
|
|||
"Password": "12345678",
|
||||
"Queue": "hrms-checkin-queue-dev"
|
||||
},
|
||||
"API": "https://localhost:7283/api/v1"
|
||||
"API": "https://localhost:7283/api/v1",
|
||||
"MaxConcurrency": 5,
|
||||
"PrefetchCount": 20,
|
||||
"HttpTimeoutSeconds": 60
|
||||
}
|
||||
|
|
|
|||
|
|
@ -786,7 +786,7 @@ namespace BMA.EHR.DisciplineComplaint_Appeal.Service.Controllers
|
|||
? profileAdmin?.RootDnaId
|
||||
: "";
|
||||
}
|
||||
else if (role == "ROOT" || role == "PARENT")
|
||||
else if (role == "ROOT" /*|| role == "PARENT"*/)
|
||||
{
|
||||
nodeId = profileAdmin?.RootDnaId;
|
||||
}
|
||||
|
|
@ -826,11 +826,11 @@ namespace BMA.EHR.DisciplineComplaint_Appeal.Service.Controllers
|
|||
data_search = data_search
|
||||
.Where(x => x.rootDnaId == nodeId).ToList();
|
||||
}
|
||||
else if (role == "PARENT")
|
||||
{
|
||||
data_search = data_search
|
||||
.Where(x => x.rootDnaId == nodeId && x.child1DnaId != null).ToList();
|
||||
}
|
||||
// else if (role == "PARENT")
|
||||
// {
|
||||
// data_search = data_search
|
||||
// .Where(x => x.rootDnaId == nodeId && x.child1DnaId != null).ToList();
|
||||
// }
|
||||
else if (role == "NORMAL")
|
||||
{
|
||||
data_search = data_search.Where(x =>
|
||||
|
|
|
|||
|
|
@ -392,7 +392,7 @@ namespace BMA.EHR.DisciplineDirector.Service.Controllers
|
|||
return Error(new Exception(GlobalMessages.DataNotFound), StatusCodes.Status404NotFound);
|
||||
|
||||
var userId = UserId == null ? Guid.Empty : Guid.Parse(UserId);
|
||||
var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(userId, token.Replace("Bearer ", ""));
|
||||
var profile = await _userProfileRepository.GetProfileByKeycloakIdNewAsync(userId, token.Replace("Bearer ", ""));
|
||||
if (profile == null)
|
||||
return Error(GlobalMessages.DataNotFound);
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -71,6 +71,13 @@ namespace BMA.EHR.DisciplineSuspend.Service.Controllers
|
|||
{
|
||||
return Error(jsonData["message"]?.ToString(), StatusCodes.Status403Forbidden);
|
||||
}
|
||||
|
||||
// ถ้า FE ส่ง status = PENDING กรอง start/end suspend not null
|
||||
bool isPending =
|
||||
!string.IsNullOrEmpty(profileType) &&
|
||||
!string.IsNullOrEmpty(status) &&
|
||||
status.Trim().ToUpper() == "PENDING";
|
||||
|
||||
// กรองสิทธิ์
|
||||
string role = jsonData["result"]?.ToString() ?? "";
|
||||
var nodeId = string.Empty;
|
||||
|
|
@ -102,14 +109,14 @@ namespace BMA.EHR.DisciplineSuspend.Service.Controllers
|
|||
? profileAdmin?.RootDnaId
|
||||
: "";
|
||||
}
|
||||
else if (role == "ROOT" || role == "PARENT")
|
||||
else if (role == "ROOT" /*|| role == "PARENT"*/)
|
||||
{
|
||||
nodeId = profileAdmin?.RootDnaId;
|
||||
}
|
||||
var data_search = (from x in _context.DisciplineReport_Profiles.Include(x => x.DisciplineDisciplinary)
|
||||
where
|
||||
(
|
||||
endDate != null && startDate != null?
|
||||
endDate != null && startDate != null ?
|
||||
(
|
||||
(x.StartDateSuspend.Value.Date >= startDate.Value.Date && x.StartDateSuspend.Value.Date <= endDate.Value.Date) ||
|
||||
(x.EndDateSuspend.Value.Date >= startDate.Value.Date && x.EndDateSuspend.Value.Date <= endDate.Value.Date) ||
|
||||
|
|
@ -137,14 +144,19 @@ namespace BMA.EHR.DisciplineSuspend.Service.Controllers
|
|||
(
|
||||
!string.IsNullOrEmpty(status) ? x.Status!.Trim().ToUpper() == status : true
|
||||
)
|
||||
// ถ้า FE ส่ง status = PENDING กรอง start/end suspend not null
|
||||
&&
|
||||
(
|
||||
isPending
|
||||
? x.StartDateSuspend != null && x.EndDateSuspend != null
|
||||
: true
|
||||
)
|
||||
&&
|
||||
(
|
||||
role == "OWNER"
|
||||
? true
|
||||
: role == "ROOT"
|
||||
? x.rootDnaId == nodeId
|
||||
: role == "PARENT"
|
||||
? x.rootDnaId == nodeId && x.child1DnaId != null
|
||||
: role == "CHILD"
|
||||
? (
|
||||
profileAdmin.Node == 4 ? x.child4DnaId == nodeId :
|
||||
|
|
@ -177,125 +189,119 @@ namespace BMA.EHR.DisciplineSuspend.Service.Controllers
|
|||
)
|
||||
select x).ToList();
|
||||
var query = data_search
|
||||
.Select(x => new
|
||||
{
|
||||
Id = x.Id,
|
||||
CitizenId = x.CitizenId,
|
||||
Prefix = x.Prefix,
|
||||
FirstName = x.FirstName,
|
||||
LastName = x.LastName,
|
||||
ProfileId = x.PersonId,
|
||||
Organization = x.Organization,
|
||||
root = x.root,
|
||||
rootId = x.rootId,
|
||||
rootDnaId = x.rootDnaId,
|
||||
rootShortName = x.rootShortName,
|
||||
child1 = x.child1,
|
||||
child1Id = x.child1Id,
|
||||
child1DnaId = x.child1DnaId,
|
||||
child1ShortName = x.child1ShortName,
|
||||
child2 = x.child2,
|
||||
child2Id = x.child2Id,
|
||||
child2DnaId = x.child2DnaId,
|
||||
child2ShortName = x.child2ShortName,
|
||||
child3 = x.child3,
|
||||
child3Id = x.child3Id,
|
||||
child3DnaId = x.child3DnaId,
|
||||
child3ShortName = x.child3ShortName,
|
||||
child4 = x.child4,
|
||||
child4Id = x.child4Id,
|
||||
child4DnaId = x.child4DnaId,
|
||||
child4ShortName = x.child4ShortName,
|
||||
posMasterNo = x.posMasterNo,
|
||||
posTypeId = x.posTypeId,
|
||||
posTypeName = x.posTypeName,
|
||||
posLevelId = x.posLevelId,
|
||||
posLevelName = x.posLevelName,
|
||||
.Select(x => new
|
||||
{
|
||||
Id = x.Id,
|
||||
CitizenId = x.CitizenId,
|
||||
Prefix = x.Prefix,
|
||||
FirstName = x.FirstName,
|
||||
LastName = x.LastName,
|
||||
ProfileId = x.PersonId,
|
||||
Organization = x.Organization,
|
||||
root = x.root,
|
||||
rootId = x.rootId,
|
||||
rootDnaId = x.rootDnaId,
|
||||
rootShortName = x.rootShortName,
|
||||
child1 = x.child1,
|
||||
child1Id = x.child1Id,
|
||||
child1DnaId = x.child1DnaId,
|
||||
child1ShortName = x.child1ShortName,
|
||||
child2 = x.child2,
|
||||
child2Id = x.child2Id,
|
||||
child2DnaId = x.child2DnaId,
|
||||
child2ShortName = x.child2ShortName,
|
||||
child3 = x.child3,
|
||||
child3Id = x.child3Id,
|
||||
child3DnaId = x.child3DnaId,
|
||||
child3ShortName = x.child3ShortName,
|
||||
child4 = x.child4,
|
||||
child4Id = x.child4Id,
|
||||
child4DnaId = x.child4DnaId,
|
||||
child4ShortName = x.child4ShortName,
|
||||
posMasterNo = x.posMasterNo,
|
||||
posTypeId = x.posTypeId,
|
||||
posTypeName = x.posTypeName,
|
||||
posLevelId = x.posLevelId,
|
||||
posLevelName = x.posLevelName,
|
||||
|
||||
Position = x.Position,
|
||||
PosNo = x.PosNo,
|
||||
PositionLevel = x.PositionLevel == null ? "" : x.PositionLevel,
|
||||
PositionType = x.PositionType == null ? "" : x.PositionType,
|
||||
Salary = x.Salary,
|
||||
Status = x.Status,
|
||||
DescriptionSuspend = x.DescriptionSuspend,
|
||||
StartDateSuspend = x.StartDateSuspend,
|
||||
EndDateSuspend = x.EndDateSuspend,
|
||||
Title = x.DisciplineDisciplinary.Title,
|
||||
OffenseDetails = x.DisciplineDisciplinary.OffenseDetails,//ลักษณะความผิด
|
||||
DisciplinaryFaultLevel = x.DisciplineDisciplinary.DisciplinaryFaultLevel,//ระดับโทษความผิด
|
||||
DisciplinaryCaseFault = x.DisciplineDisciplinary.DisciplinaryCaseFault,//กรณีความผิด
|
||||
profileType = x.profileType,
|
||||
CreatedAt = x.CreatedAt,
|
||||
});
|
||||
Position = x.Position,
|
||||
PosNo = x.PosNo,
|
||||
PositionLevel = x.PositionLevel == null ? "" : x.PositionLevel,
|
||||
PositionType = x.PositionType == null ? "" : x.PositionType,
|
||||
Salary = x.Salary,
|
||||
Status = x.Status,
|
||||
DescriptionSuspend = x.DescriptionSuspend,
|
||||
StartDateSuspend = x.StartDateSuspend,
|
||||
EndDateSuspend = x.EndDateSuspend,
|
||||
Title = x.DisciplineDisciplinary.Title,
|
||||
OffenseDetails = x.DisciplineDisciplinary.OffenseDetails,//ลักษณะความผิด
|
||||
DisciplinaryFaultLevel = x.DisciplineDisciplinary.DisciplinaryFaultLevel,//ระดับโทษความผิด
|
||||
DisciplinaryCaseFault = x.DisciplineDisciplinary.DisciplinaryCaseFault,//กรณีความผิด
|
||||
profileType = x.profileType,
|
||||
CreatedAt = x.CreatedAt,
|
||||
});
|
||||
|
||||
bool desc = descending ?? false;
|
||||
if (!string.IsNullOrEmpty(sortBy))
|
||||
{
|
||||
if (sortBy == "title")
|
||||
{
|
||||
query = desc ? query.OrderByDescending(x => x.Title)
|
||||
: query.OrderBy(x => x.Title);
|
||||
}
|
||||
else if (sortBy == "prefix" || sortBy == "firstName" || sortBy == "lastName")
|
||||
{
|
||||
query = desc ?
|
||||
query
|
||||
//.OrderByDescending(x => x.Prefix)
|
||||
.OrderByDescending(x => x.FirstName)
|
||||
.ThenByDescending(x => x.LastName) :
|
||||
query
|
||||
//.OrderBy(x => x.Prefix)
|
||||
.OrderBy(x => x.FirstName)
|
||||
.ThenBy(x => x.LastName);
|
||||
}
|
||||
else if (sortBy == "position")
|
||||
{
|
||||
query = desc ? query.OrderByDescending(x => x.Position)
|
||||
: query.OrderBy(x => x.Position);
|
||||
}
|
||||
else if (sortBy == "positionType" || sortBy == "positionLevel")
|
||||
{
|
||||
query = desc ?
|
||||
query
|
||||
.OrderByDescending(x => x.PositionType)
|
||||
.ThenByDescending(x => x.PositionLevel) :
|
||||
query
|
||||
.OrderBy(x => x.PositionType)
|
||||
.ThenBy(x => x.PositionLevel);
|
||||
}
|
||||
else if (sortBy == "organization")
|
||||
{
|
||||
query = desc ? query.OrderByDescending(x => x.Organization)
|
||||
: query.OrderBy(x => x.Organization);
|
||||
}
|
||||
else if (sortBy == "startDateSuspend")
|
||||
{
|
||||
query = desc ? query.OrderByDescending(x => x.StartDateSuspend)
|
||||
: query.OrderBy(x => x.StartDateSuspend);
|
||||
}
|
||||
else if (sortBy == "endDateSuspend")
|
||||
{
|
||||
query = desc ? query.OrderByDescending(x => x.EndDateSuspend)
|
||||
: query.OrderBy(x => x.EndDateSuspend);
|
||||
}
|
||||
else if (sortBy == "descriptionSuspend")
|
||||
{
|
||||
query = desc ? query.OrderByDescending(x => x.DescriptionSuspend)
|
||||
: query.OrderBy(x => x.DescriptionSuspend);
|
||||
}
|
||||
else
|
||||
{
|
||||
query = query.OrderByDescending(x => x.profileType)
|
||||
.ThenByDescending(x => x.CreatedAt)
|
||||
.ThenByDescending(x => x.CitizenId);
|
||||
}
|
||||
}
|
||||
bool desc = descending ?? false;
|
||||
if (!string.IsNullOrEmpty(sortBy))
|
||||
{
|
||||
if (sortBy == "title")
|
||||
{
|
||||
query = desc ? query.OrderByDescending(x => x.Title)
|
||||
: query.OrderBy(x => x.Title);
|
||||
}
|
||||
else if (sortBy == "prefix" || sortBy == "firstName" || sortBy == "lastName")
|
||||
{
|
||||
query = desc ?
|
||||
query.OrderByDescending(x => x.FirstName).ThenByDescending(x => x.LastName) :
|
||||
query.OrderBy(x => x.FirstName).ThenBy(x => x.LastName);
|
||||
}
|
||||
else if (sortBy == "position")
|
||||
{
|
||||
query = desc ? query.OrderByDescending(x => x.Position)
|
||||
: query.OrderBy(x => x.Position);
|
||||
}
|
||||
else if (sortBy == "positionType" || sortBy == "positionLevel")
|
||||
{
|
||||
query = desc ?
|
||||
query
|
||||
.OrderByDescending(x => x.PositionType)
|
||||
.ThenByDescending(x => x.PositionLevel) :
|
||||
query
|
||||
.OrderBy(x => x.PositionType)
|
||||
.ThenBy(x => x.PositionLevel);
|
||||
}
|
||||
else if (sortBy == "organization")
|
||||
{
|
||||
query = desc ? query.OrderByDescending(x => x.Organization)
|
||||
: query.OrderBy(x => x.Organization);
|
||||
}
|
||||
else if (sortBy == "startDateSuspend")
|
||||
{
|
||||
query = desc ? query.OrderByDescending(x => x.StartDateSuspend)
|
||||
: query.OrderBy(x => x.StartDateSuspend);
|
||||
}
|
||||
else if (sortBy == "endDateSuspend")
|
||||
{
|
||||
query = desc ? query.OrderByDescending(x => x.EndDateSuspend)
|
||||
: query.OrderBy(x => x.EndDateSuspend);
|
||||
}
|
||||
else if (sortBy == "descriptionSuspend")
|
||||
{
|
||||
query = desc ? query.OrderByDescending(x => x.DescriptionSuspend)
|
||||
: query.OrderBy(x => x.DescriptionSuspend);
|
||||
}
|
||||
else
|
||||
{
|
||||
query = query.OrderByDescending(x => x.profileType)
|
||||
.ThenByDescending(x => x.CreatedAt)
|
||||
.ThenByDescending(x => x.CitizenId);
|
||||
}
|
||||
}
|
||||
|
||||
var data = query
|
||||
.Skip((page - 1) * pageSize)
|
||||
.Take(pageSize)
|
||||
.ToList();
|
||||
var data = query
|
||||
.Skip((page - 1) * pageSize)
|
||||
.Take(pageSize)
|
||||
.ToList();
|
||||
|
||||
return Success(new { data, total = data_search.Count() });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,4 +8,12 @@ namespace BMA.EHR.Discipline.Service.Requests
|
|||
public string[] refIds { get; set; }
|
||||
public string? status { get; set; }
|
||||
}
|
||||
|
||||
public class ReportPersonAndCommandRequest
|
||||
{
|
||||
public string[] refIds { get; set; }
|
||||
public string? status { get; set; }
|
||||
public string? commandTypeId { get; set; }
|
||||
public string? commandCode { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using BMA.EHR.Domain.Shared;
|
||||
using BMA.EHR.Domain.Extensions;
|
||||
using BMA.EHR.Domain.Shared;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
|
|
@ -81,6 +82,23 @@ namespace BMA.EHR.Domain.Common
|
|||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region " Properties "
|
||||
|
||||
protected string? EmpType => User.GetEmpType();
|
||||
protected Guid? OrgChild1DnaId => User.GetOrgChild1DnaId();
|
||||
protected Guid? OrgChild2DnaId => User.GetOrgChild2DnaId();
|
||||
protected Guid? OrgChild3DnaId => User.GetOrgChild3DnaId();
|
||||
protected Guid? OrgChild4DnaId => User.GetOrgChild4DnaId();
|
||||
protected Guid? OrgRootDnaId => User.GetOrgRootDnaId();
|
||||
protected Guid? ProfileId => User.GetProfileId();
|
||||
protected string? Prefix => User.GetPrefix();
|
||||
protected string? FullNameFromClaim => User.GetName();
|
||||
|
||||
protected string? FirstName => User.GetFirstName();
|
||||
protected string? LastName => User.GetLastName();
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
|
|
|||
39
BMA.EHR.Domain/Common/TokenUserInfo.cs
Normal file
39
BMA.EHR.Domain/Common/TokenUserInfo.cs
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
namespace BMA.EHR.Domain.Common
|
||||
{
|
||||
public class TokenUserInfo
|
||||
{
|
||||
// Existing properties
|
||||
public string KeycloakId { get; set; } = string.Empty;
|
||||
public string? PreferredUsername { get; set; }
|
||||
public string? GivenName { get; set; }
|
||||
public string? FamilyName { get; set; }
|
||||
|
||||
// New properties to add
|
||||
public string? EmpType { get; set; }
|
||||
public Guid? OrgChild1DnaId { get; set; }
|
||||
public Guid? OrgChild2DnaId { get; set; }
|
||||
public Guid? OrgChild3DnaId { get; set; }
|
||||
public Guid? OrgChild4DnaId { get; set; }
|
||||
public Guid? OrgRootDnaId { get; set; }
|
||||
public Guid? ProfileId { get; set; }
|
||||
public string? Prefix { get; set; }
|
||||
public string? Name { get; set; }
|
||||
}
|
||||
|
||||
// Claim type constants
|
||||
public static class BmaClaimTypes
|
||||
{
|
||||
public const string EmpType = "empType";
|
||||
public const string OrgChild1DnaId = "orgChild1DnaId";
|
||||
public const string OrgChild2DnaId = "orgChild2DnaId";
|
||||
public const string OrgChild3DnaId = "orgChild3DnaId";
|
||||
public const string OrgChild4DnaId = "orgChild4DnaId";
|
||||
public const string OrgRootDnaId = "orgRootDnaId";
|
||||
public const string ProfileId = "profileId";
|
||||
public const string Prefix = "prefix";
|
||||
public const string Name = "name";
|
||||
public const string GivenName = "given_name";
|
||||
public const string FamilyName = "family_name";
|
||||
public const string PreferredUsername = "preferred_username";
|
||||
}
|
||||
}
|
||||
32
BMA.EHR.Domain/Extensions/ClaimsPrincipalExtensions.cs
Normal file
32
BMA.EHR.Domain/Extensions/ClaimsPrincipalExtensions.cs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
using BMA.EHR.Domain.Common;
|
||||
using System.Security.Claims;
|
||||
|
||||
namespace BMA.EHR.Domain.Extensions
|
||||
{
|
||||
public static class ClaimsPrincipalExtensions
|
||||
{
|
||||
public static string? GetClaimValue(this ClaimsPrincipal user, string claimType)
|
||||
{
|
||||
return user?.FindFirst(claimType)?.Value;
|
||||
}
|
||||
|
||||
public static Guid? GetGuidClaim(this ClaimsPrincipal user, string claimType)
|
||||
{
|
||||
var value = user?.GetClaimValue(claimType);
|
||||
return Guid.TryParse(value, out var guid) ? guid : null;
|
||||
}
|
||||
|
||||
// Convenience methods for common claims
|
||||
public static string? GetEmpType(this ClaimsPrincipal user) => user.GetClaimValue(BmaClaimTypes.EmpType);
|
||||
public static Guid? GetOrgChild1DnaId(this ClaimsPrincipal user) => user.GetGuidClaim(BmaClaimTypes.OrgChild1DnaId);
|
||||
public static Guid? GetOrgChild2DnaId(this ClaimsPrincipal user) => user.GetGuidClaim(BmaClaimTypes.OrgChild2DnaId);
|
||||
public static Guid? GetOrgChild3DnaId(this ClaimsPrincipal user) => user.GetGuidClaim(BmaClaimTypes.OrgChild3DnaId);
|
||||
public static Guid? GetOrgChild4DnaId(this ClaimsPrincipal user) => user.GetGuidClaim(BmaClaimTypes.OrgChild4DnaId);
|
||||
public static Guid? GetOrgRootDnaId(this ClaimsPrincipal user) => user.GetGuidClaim(BmaClaimTypes.OrgRootDnaId);
|
||||
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? 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);
|
||||
}
|
||||
}
|
||||
|
|
@ -174,6 +174,29 @@ namespace BMA.EHR.Domain.Extensions
|
|||
}
|
||||
}
|
||||
|
||||
public static (int Years, int Months, int Days) GetDifference(this DateTime from, DateTime to)
|
||||
{
|
||||
if (from > to) (from, to) = (to, from); // swap ถ้าลำดับสลับ
|
||||
|
||||
int years = to.Year - from.Year;
|
||||
int months = to.Month - from.Month;
|
||||
int days = to.Day - from.Day;
|
||||
|
||||
if (days < 0)
|
||||
{
|
||||
months--;
|
||||
days += DateTime.DaysInMonth(to.Year, to.Month == 1 ? 12 : to.Month - 1);
|
||||
}
|
||||
|
||||
if (months < 0)
|
||||
{
|
||||
years--;
|
||||
months += 12;
|
||||
}
|
||||
|
||||
return (years, months, days);
|
||||
}
|
||||
|
||||
public static int CalculateAge(this DateTime date, int plusYear = 0, int subtractYear = 0)
|
||||
{
|
||||
try
|
||||
|
|
|
|||
|
|
@ -79,13 +79,39 @@ namespace BMA.EHR.Domain.Middlewares
|
|||
GetProfileByKeycloakIdLocal? pf = null;
|
||||
var tokenUserInfo = await ExtractTokenUserInfoAsync(token);
|
||||
|
||||
// Store tokenUserInfo in HttpContext.Items for controllers to use
|
||||
context.Items["TokenUserInfo"] = tokenUserInfo;
|
||||
|
||||
// ดึง keycloakId จาก JWT token
|
||||
keycloakId = tokenUserInfo.KeycloakId;
|
||||
|
||||
// ดึง profile จาก cache หรือ API
|
||||
// ดึง profile จาก claims หรือ cache หรือ API
|
||||
if (Guid.TryParse(keycloakId, out var parsedId) && parsedId != Guid.Empty)
|
||||
{
|
||||
pf = await GetProfileWithCacheAsync(parsedId, token);
|
||||
// Build profile from token claims if available
|
||||
if (tokenUserInfo.OrgRootDnaId.HasValue && tokenUserInfo.ProfileId.HasValue)
|
||||
{
|
||||
pf = new GetProfileByKeycloakIdLocal
|
||||
{
|
||||
Id = tokenUserInfo.ProfileId.Value,
|
||||
CitizenId = tokenUserInfo.PreferredUsername,
|
||||
Prefix = tokenUserInfo.Prefix,
|
||||
FirstName = tokenUserInfo.GivenName,
|
||||
LastName = tokenUserInfo.FamilyName,
|
||||
RootDnaId = tokenUserInfo.OrgRootDnaId,
|
||||
Child1DnaId = tokenUserInfo.OrgChild1DnaId,
|
||||
Child2DnaId = tokenUserInfo.OrgChild2DnaId,
|
||||
Child3DnaId = tokenUserInfo.OrgChild3DnaId,
|
||||
Child4DnaId = tokenUserInfo.OrgChild4DnaId,
|
||||
};
|
||||
Console.WriteLine($"[INFO] Using claims for profile - OrgRootDnaId: {pf.RootDnaId}, ProfileId: {pf.Id}");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fallback to API only if critical claims are missing
|
||||
Console.WriteLine("[WARN] Critical claims missing, falling back to API call");
|
||||
pf = await GetProfileWithCacheAsync(parsedId, token);
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
|
|
@ -649,6 +675,87 @@ namespace BMA.EHR.Domain.Middlewares
|
|||
Console.WriteLine($"Extracted family_name: {result.FamilyName}");
|
||||
}
|
||||
|
||||
// ดึง empType
|
||||
if (jsonDoc.RootElement.TryGetProperty("empType", out var empTypeElement))
|
||||
{
|
||||
result.EmpType = empTypeElement.GetString();
|
||||
Console.WriteLine($"Extracted empType: {result.EmpType}");
|
||||
}
|
||||
|
||||
// ดึง orgChild1DnaId
|
||||
if (jsonDoc.RootElement.TryGetProperty("orgChild1DnaId", out var orgChild1Element))
|
||||
{
|
||||
if (Guid.TryParse(orgChild1Element.GetString(), out var orgChild1Guid))
|
||||
{
|
||||
result.OrgChild1DnaId = orgChild1Guid;
|
||||
Console.WriteLine($"Extracted orgChild1DnaId: {result.OrgChild1DnaId}");
|
||||
}
|
||||
}
|
||||
|
||||
// ดึง orgChild2DnaId
|
||||
if (jsonDoc.RootElement.TryGetProperty("orgChild2DnaId", out var orgChild2Element))
|
||||
{
|
||||
if (Guid.TryParse(orgChild2Element.GetString(), out var orgChild2Guid))
|
||||
{
|
||||
result.OrgChild2DnaId = orgChild2Guid;
|
||||
Console.WriteLine($"Extracted orgChild2DnaId: {result.OrgChild2DnaId}");
|
||||
}
|
||||
}
|
||||
|
||||
// ดึง orgChild3DnaId
|
||||
if (jsonDoc.RootElement.TryGetProperty("orgChild3DnaId", out var orgChild3Element))
|
||||
{
|
||||
if (Guid.TryParse(orgChild3Element.GetString(), out var orgChild3Guid))
|
||||
{
|
||||
result.OrgChild3DnaId = orgChild3Guid;
|
||||
Console.WriteLine($"Extracted orgChild3DnaId: {result.OrgChild3DnaId}");
|
||||
}
|
||||
}
|
||||
|
||||
// ดึง orgChild4DnaId
|
||||
if (jsonDoc.RootElement.TryGetProperty("orgChild4DnaId", out var orgChild4Element))
|
||||
{
|
||||
if (Guid.TryParse(orgChild4Element.GetString(), out var orgChild4Guid))
|
||||
{
|
||||
result.OrgChild4DnaId = orgChild4Guid;
|
||||
Console.WriteLine($"Extracted orgChild4DnaId: {result.OrgChild4DnaId}");
|
||||
}
|
||||
}
|
||||
|
||||
// ดึง orgRootDnaId
|
||||
if (jsonDoc.RootElement.TryGetProperty("orgRootDnaId", out var orgRootElement))
|
||||
{
|
||||
if (Guid.TryParse(orgRootElement.GetString(), out var orgRootGuid))
|
||||
{
|
||||
result.OrgRootDnaId = orgRootGuid;
|
||||
Console.WriteLine($"Extracted orgRootDnaId: {result.OrgRootDnaId}");
|
||||
}
|
||||
}
|
||||
|
||||
// ดึง profileId
|
||||
if (jsonDoc.RootElement.TryGetProperty("profileId", out var profileIdElement))
|
||||
{
|
||||
if (Guid.TryParse(profileIdElement.GetString(), out var profileIdGuid))
|
||||
{
|
||||
result.ProfileId = profileIdGuid;
|
||||
Console.WriteLine($"Extracted profileId: {result.ProfileId}");
|
||||
}
|
||||
}
|
||||
|
||||
// ดึง prefix
|
||||
if (jsonDoc.RootElement.TryGetProperty("prefix", out var prefixElement))
|
||||
{
|
||||
result.Prefix = prefixElement.GetString();
|
||||
Console.WriteLine($"Extracted prefix: {result.Prefix}");
|
||||
}
|
||||
|
||||
// ดึง name
|
||||
if (jsonDoc.RootElement.TryGetProperty("name", out var nameElement))
|
||||
{
|
||||
result.Name = nameElement.GetString();
|
||||
Console.WriteLine($"Extracted name: {result.Name}");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
@ -767,14 +874,6 @@ namespace BMA.EHR.Domain.Middlewares
|
|||
}
|
||||
|
||||
// Model classes
|
||||
public class TokenUserInfo
|
||||
{
|
||||
public string KeycloakId { get; set; } = string.Empty;
|
||||
public string? PreferredUsername { get; set; }
|
||||
public string? GivenName { get; set; }
|
||||
public string? FamilyName { get; set; }
|
||||
}
|
||||
|
||||
public class GetProfileByKeycloakIdLocal
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
|
|
|
|||
|
|
@ -24,11 +24,14 @@ namespace BMA.EHR.Domain.Models.Leave.Requests
|
|||
[Required, Comment("ปีงบประมาณ")]
|
||||
public int LeaveYear { get; set; } = 0;
|
||||
|
||||
[Required, Comment("จำนวนวันลายกมา")]
|
||||
[Required, Comment("จำนวนวันลาทั้งหมด")]
|
||||
public double LeaveDays { get; set; } = 0.0;
|
||||
|
||||
[Required, Comment("จำนวนวันลาที่ใช้ไป")]
|
||||
public double LeaveDaysUsed { get; set; } = 0.0;
|
||||
[Comment("จำนวนวันลาที่ใช้ไป")]
|
||||
public double? LeaveDaysUsed { get; set; } = 0.0;
|
||||
|
||||
[Comment("จำนวนครั้งที่ลาสะสม")]
|
||||
public int? LeaveCount { get; set; } = 0;
|
||||
|
||||
public Guid? RootDnaId { get; set; }
|
||||
|
||||
|
|
@ -39,5 +42,11 @@ namespace BMA.EHR.Domain.Models.Leave.Requests
|
|||
public Guid? Child3DnaId { get; set; }
|
||||
|
||||
public Guid? Child4DnaId { get; set; }
|
||||
|
||||
[Required, Comment("จำนวนวันลายกมา")]
|
||||
public double BeginningLeaveDays { get; set; } = 0.0;
|
||||
|
||||
[Comment("จำนวนครั้งที่ลายกมา")]
|
||||
public int BeginningLeaveCount { get; set; } = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -210,5 +210,7 @@ namespace BMA.EHR.Domain.Models.Leave.Requests
|
|||
|
||||
public Guid? Child4DnaId { get; set; } = Guid.Empty;
|
||||
|
||||
public DateTime? DateSendLeave { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,5 +38,10 @@ namespace BMA.EHR.Domain.Models.Leave.Requests
|
|||
public string Comment { get; set; } = string.Empty;
|
||||
|
||||
public string? ApproveType { get; set; } = string.Empty; // ผู้บังคับบัญชา = commander, ผู้มีอำนาจอนุมัติ = Approver
|
||||
|
||||
|
||||
public bool IsAct { get; set; } = false;
|
||||
|
||||
public string KeyId { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using BMA.EHR.Domain.Models.Base;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace BMA.EHR.Domain.Models.Leave.TimeAttendants
|
||||
{
|
||||
public class LeaveProcessJobStatus: EntityBase
|
||||
{
|
||||
[Required, Comment("วันเริ่มต้น")]
|
||||
public DateTime StartDate { get; set; }
|
||||
|
||||
[Required, Comment("วันสิ้นสุด")]
|
||||
public DateTime EndDate { get; set; }
|
||||
|
||||
[Required, Comment("รหัส Root DNA Id")]
|
||||
public Guid RootDnaId { get; set; } = Guid.Empty;
|
||||
|
||||
[Comment("วันเวลาที่สร้างงาน")]
|
||||
public DateTime CreatedDate { get; set; } = DateTime.Now;
|
||||
|
||||
[Comment("วันเวลาที่เริ่มประมวลผล")]
|
||||
public DateTime? ProcessingDate { get; set; }
|
||||
|
||||
[Comment("วันเวลาที่เสร็จสิ้นการประมวลผล")]
|
||||
public DateTime? CompletedDate { get; set; }
|
||||
|
||||
[Required, Comment("สถานะงาน: PENDING, PROCESSING, COMPLETED, FAILED")]
|
||||
public string Status { get; set; } = "PENDING";
|
||||
|
||||
[Comment("ข้อความแสดงข้อผิดพลาด")]
|
||||
public string? ErrorMessage { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -119,6 +119,10 @@ namespace BMA.EHR.Domain.Models.Placement
|
|||
public string? position { get; set; }
|
||||
[Comment("ตำแหน่งทางการบริหาร")]
|
||||
public string? PositionExecutive { get; set; }
|
||||
|
||||
[Comment("id ตำแหน่งทางการบริหาร")]
|
||||
public string? posExecutiveId { get; set; }
|
||||
|
||||
[Comment("id ประเภทตำแหน่ง")]
|
||||
public string? posTypeId { get; set; }
|
||||
[Comment("ชื่อประเภทตำแหน่ง")]
|
||||
|
|
|
|||
|
|
@ -321,6 +321,10 @@ namespace BMA.EHR.Domain.Models.Placement
|
|||
public string? positionName { get; set; }
|
||||
[Comment("ตำแหน่งทางการบริหาร")]
|
||||
public string? PositionExecutive { get; set; }
|
||||
|
||||
[Comment("id ตำแหน่งทางการบริหาร")]
|
||||
public string? posExecutiveId { get; set; }
|
||||
|
||||
[Comment("สายงาน")]
|
||||
public string? positionField { get; set; }
|
||||
[Comment("id ประเภทตำแหน่ง")]
|
||||
|
|
|
|||
|
|
@ -64,6 +64,10 @@ namespace BMA.EHR.Domain.Models.Placement
|
|||
public string? profileId { get; set; }
|
||||
[Comment("คำนำหน้า")]
|
||||
public string? prefix { get; set; }
|
||||
|
||||
[Comment("ยศ")]
|
||||
public string? rank { get; set; }
|
||||
|
||||
[Comment("ชื่อ")]
|
||||
public string? firstName { get; set; }
|
||||
[Comment("นามสกุล")]
|
||||
|
|
@ -128,6 +132,10 @@ namespace BMA.EHR.Domain.Models.Placement
|
|||
public string? position { get; set; }
|
||||
[Comment("ตำแหน่งทางการบริหาร")]
|
||||
public string? PositionExecutive { get; set; }
|
||||
|
||||
[Comment("id ตำแหน่งทางการบริหาร")]
|
||||
public string? posExecutiveId { get; set; }
|
||||
|
||||
[Comment("id ประเภทตำแหน่ง")]
|
||||
public string? posTypeId { get; set; }
|
||||
[Comment("ชื่อประเภทตำแหน่ง")]
|
||||
|
|
|
|||
|
|
@ -173,6 +173,10 @@ namespace BMA.EHR.Domain.Models.Retirement
|
|||
public string? position { get; set; }
|
||||
[Comment("ตำแหน่งทางการบริหาร")]
|
||||
public string? PositionExecutive { get; set; }
|
||||
|
||||
[Comment("id ตำแหน่งทางการบริหาร")]
|
||||
public string? posExecutiveId { get; set; }
|
||||
|
||||
[Comment("id ประเภทตำแหน่ง")]
|
||||
public string? posTypeId { get; set; }
|
||||
[Comment("ชื่อประเภทตำแหน่ง")]
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
public static readonly string DataNotFound = "ไม่พบข้อมูลในระบบ";
|
||||
|
||||
public static readonly string ProfileNotFound = "ไม่พบข้อมูลในระบบทะเบียนประวัติ";
|
||||
|
||||
public static readonly string NotAuthorized = "กรุณาเข้าสู่ระบบก่อนใช้งาน!";
|
||||
|
||||
public static readonly string ForbiddenAccess = "คุณไม่ได้รับอนุญาติให้เข้าใช้งาน!";
|
||||
|
|
|
|||
30
BMA.EHR.Domain/Shared/PrivilegeConverter.cs
Normal file
30
BMA.EHR.Domain/Shared/PrivilegeConverter.cs
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace BMA.EHR.Domain.Shared
|
||||
{
|
||||
public class PrivilegeConverter : JsonConverter
|
||||
{
|
||||
public override bool CanConvert(Type objectType)
|
||||
{
|
||||
return objectType == typeof(string);
|
||||
}
|
||||
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
if (reader.TokenType == JsonToken.Null)
|
||||
{
|
||||
return "EMPTY";
|
||||
}
|
||||
return reader.Value;
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
{
|
||||
writer.WriteValue(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
21266
BMA.EHR.Infrastructure/Migrations/20260521081933_update_Tables_add_posExecutiveId.Designer.cs
generated
Normal file
21266
BMA.EHR.Infrastructure/Migrations/20260521081933_update_Tables_add_posExecutiveId.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,66 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace BMA.EHR.Infrastructure.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class update_Tables_add_posExecutiveId : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "posExecutiveId",
|
||||
table: "RetirementOthers",
|
||||
type: "longtext",
|
||||
nullable: true,
|
||||
comment: "id ตำแหน่งทางการบริหาร")
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "posExecutiveId",
|
||||
table: "PlacementReceives",
|
||||
type: "longtext",
|
||||
nullable: true,
|
||||
comment: "id ตำแหน่งทางการบริหาร")
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "posExecutiveId",
|
||||
table: "PlacementProfiles",
|
||||
type: "longtext",
|
||||
nullable: true,
|
||||
comment: "id ตำแหน่งทางการบริหาร")
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "posExecutiveId",
|
||||
table: "PlacementAppointments",
|
||||
type: "longtext",
|
||||
nullable: true,
|
||||
comment: "id ตำแหน่งทางการบริหาร")
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "posExecutiveId",
|
||||
table: "RetirementOthers");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "posExecutiveId",
|
||||
table: "PlacementReceives");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "posExecutiveId",
|
||||
table: "PlacementProfiles");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "posExecutiveId",
|
||||
table: "PlacementAppointments");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -11721,6 +11721,10 @@ namespace BMA.EHR.Infrastructure.Migrations
|
|||
.HasColumnType("longtext")
|
||||
.HasComment("id revision");
|
||||
|
||||
b.Property<string>("posExecutiveId")
|
||||
.HasColumnType("longtext")
|
||||
.HasComment("id ตำแหน่งทางการบริหาร");
|
||||
|
||||
b.Property<string>("posLevelId")
|
||||
.HasColumnType("longtext")
|
||||
.HasComment("id ระดับตำแหน่ง");
|
||||
|
|
@ -13108,6 +13112,10 @@ namespace BMA.EHR.Infrastructure.Migrations
|
|||
.HasColumnType("longtext")
|
||||
.HasComment("ชื่อหน่วยงาน");
|
||||
|
||||
b.Property<string>("posExecutiveId")
|
||||
.HasColumnType("longtext")
|
||||
.HasComment("id ตำแหน่งทางการบริหาร");
|
||||
|
||||
b.Property<string>("posLevelId")
|
||||
.HasColumnType("longtext")
|
||||
.HasComment("id ระดับตำแหน่ง");
|
||||
|
|
@ -13613,6 +13621,10 @@ namespace BMA.EHR.Infrastructure.Migrations
|
|||
.HasColumnType("longtext")
|
||||
.HasComment("id revision");
|
||||
|
||||
b.Property<string>("posExecutiveId")
|
||||
.HasColumnType("longtext")
|
||||
.HasComment("id ตำแหน่งทางการบริหาร");
|
||||
|
||||
b.Property<string>("posLevelId")
|
||||
.HasColumnType("longtext")
|
||||
.HasComment("id ระดับตำแหน่ง");
|
||||
|
|
@ -13693,6 +13705,10 @@ namespace BMA.EHR.Infrastructure.Migrations
|
|||
.HasColumnType("longtext")
|
||||
.HasComment("profile Id");
|
||||
|
||||
b.Property<string>("rank")
|
||||
.HasColumnType("longtext")
|
||||
.HasComment("ยศ");
|
||||
|
||||
b.Property<string>("root")
|
||||
.HasColumnType("longtext")
|
||||
.HasComment("ชื่อหน่วยงาน root");
|
||||
|
|
@ -15799,6 +15815,10 @@ namespace BMA.EHR.Infrastructure.Migrations
|
|||
.HasColumnType("longtext")
|
||||
.HasComment("id revision");
|
||||
|
||||
b.Property<string>("posExecutiveId")
|
||||
.HasColumnType("longtext")
|
||||
.HasComment("id ตำแหน่งทางการบริหาร");
|
||||
|
||||
b.Property<string>("posLevelId")
|
||||
.HasColumnType("longtext")
|
||||
.HasComment("id ระดับตำแหน่ง");
|
||||
|
|
|
|||
1709
BMA.EHR.Infrastructure/Migrations/LeaveDb/20260205034753_Add LeaveCount to LeaveBeginning.Designer.cs
generated
Normal file
1709
BMA.EHR.Infrastructure/Migrations/LeaveDb/20260205034753_Add LeaveCount to LeaveBeginning.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.LeaveDb
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddLeaveCounttoLeaveBeginning : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "LeaveCount",
|
||||
table: "LeaveBeginnings",
|
||||
type: "int",
|
||||
nullable: false,
|
||||
defaultValue: 0,
|
||||
comment: "จำนวนครั้งที่ลาสะสม");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "LeaveCount",
|
||||
table: "LeaveBeginnings");
|
||||
}
|
||||
}
|
||||
}
|
||||
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 AddBeginningLeaveandLeaveCounttoLeaveBeginning : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<double>(
|
||||
name: "LeaveDays",
|
||||
table: "LeaveBeginnings",
|
||||
type: "double",
|
||||
nullable: false,
|
||||
comment: "จำนวนวันลาทั้งหมด",
|
||||
oldClrType: typeof(double),
|
||||
oldType: "double",
|
||||
oldComment: "จำนวนวันลายกมา");
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "BeginningLeaveCount",
|
||||
table: "LeaveBeginnings",
|
||||
type: "int",
|
||||
nullable: false,
|
||||
defaultValue: 0,
|
||||
comment: "จำนวนครั้งที่ลายกมา");
|
||||
|
||||
migrationBuilder.AddColumn<double>(
|
||||
name: "BeginningLeaveDays",
|
||||
table: "LeaveBeginnings",
|
||||
type: "double",
|
||||
nullable: false,
|
||||
defaultValue: 0.0,
|
||||
comment: "จำนวนวันลายกมา");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "BeginningLeaveCount",
|
||||
table: "LeaveBeginnings");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "BeginningLeaveDays",
|
||||
table: "LeaveBeginnings");
|
||||
|
||||
migrationBuilder.AlterColumn<double>(
|
||||
name: "LeaveDays",
|
||||
table: "LeaveBeginnings",
|
||||
type: "double",
|
||||
nullable: false,
|
||||
comment: "จำนวนวันลายกมา",
|
||||
oldClrType: typeof(double),
|
||||
oldType: "double",
|
||||
oldComment: "จำนวนวันลาทั้งหมด");
|
||||
}
|
||||
}
|
||||
}
|
||||
1802
BMA.EHR.Infrastructure/Migrations/LeaveDb/20260330020909_Add Leave Process Job Status.Designer.cs
generated
Normal file
1802
BMA.EHR.Infrastructure/Migrations/LeaveDb/20260330020909_Add Leave Process Job Status.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,54 @@
|
|||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace BMA.EHR.Infrastructure.Migrations.LeaveDb
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddLeaveProcessJobStatus : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "LeaveProcessJobStatuses",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false, comment: "PrimaryKey", collation: "ascii_general_ci"),
|
||||
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false, comment: "สร้างข้อมูลเมื่อ"),
|
||||
CreatedUserId = table.Column<string>(type: "varchar(40)", maxLength: 40, nullable: false, comment: "User Id ที่สร้างข้อมูล")
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
LastUpdatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: true, comment: "แก้ไขข้อมูลล่าสุดเมื่อ"),
|
||||
LastUpdateUserId = table.Column<string>(type: "varchar(40)", maxLength: 40, nullable: false, comment: "User Id ที่แก้ไขข้อมูลล่าสุด")
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
CreatedFullName = table.Column<string>(type: "varchar(200)", maxLength: 200, nullable: false, comment: "ชื่อ User ที่สร้างข้อมูล")
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
LastUpdateFullName = table.Column<string>(type: "varchar(200)", maxLength: 200, nullable: false, comment: "ชื่อ User ที่แก้ไขข้อมูลล่าสุด")
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
StartDate = table.Column<DateTime>(type: "datetime(6)", nullable: false, comment: "วันเริ่มต้น"),
|
||||
EndDate = table.Column<DateTime>(type: "datetime(6)", nullable: false, comment: "วันสิ้นสุด"),
|
||||
RootDnaId = table.Column<Guid>(type: "char(36)", nullable: false, comment: "รหัส Root DNA Id", collation: "ascii_general_ci"),
|
||||
CreatedDate = table.Column<DateTime>(type: "datetime(6)", nullable: false, comment: "วันเวลาที่สร้างงาน"),
|
||||
ProcessingDate = table.Column<DateTime>(type: "datetime(6)", nullable: true, comment: "วันเวลาที่เริ่มประมวลผล"),
|
||||
CompletedDate = table.Column<DateTime>(type: "datetime(6)", nullable: true, comment: "วันเวลาที่เสร็จสิ้นการประมวลผล"),
|
||||
Status = table.Column<string>(type: "longtext", nullable: false, comment: "สถานะงาน: PENDING, PROCESSING, COMPLETED, FAILED")
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
ErrorMessage = table.Column<string>(type: "longtext", nullable: true, comment: "ข้อความแสดงข้อผิดพลาด")
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_LeaveProcessJobStatuses", x => x.Id);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "LeaveProcessJobStatuses");
|
||||
}
|
||||
}
|
||||
}
|
||||
1805
BMA.EHR.Infrastructure/Migrations/LeaveDb/20260423083625_Add DateSendLeave.Designer.cs
generated
Normal file
1805
BMA.EHR.Infrastructure/Migrations/LeaveDb/20260423083625_Add DateSendLeave.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,29 @@
|
|||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace BMA.EHR.Infrastructure.Migrations.LeaveDb
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddDateSendLeave : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<DateTime>(
|
||||
name: "DateSendLeave",
|
||||
table: "LeaveRequests",
|
||||
type: "datetime(6)",
|
||||
nullable: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "DateSendLeave",
|
||||
table: "LeaveRequests");
|
||||
}
|
||||
}
|
||||
}
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -50,7 +50,7 @@ namespace BMA.EHR.Infrastructure.Migrations.LeaveDb
|
|||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Document");
|
||||
b.ToTable("Document", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BMA.EHR.Domain.Models.Leave.Commons.LeaveType", b =>
|
||||
|
|
@ -116,7 +116,7 @@ namespace BMA.EHR.Infrastructure.Migrations.LeaveDb
|
|||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("LeaveTypes");
|
||||
b.ToTable("LeaveTypes", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BMA.EHR.Domain.Models.Leave.Requests.LeaveBeginning", b =>
|
||||
|
|
@ -128,6 +128,14 @@ namespace BMA.EHR.Infrastructure.Migrations.LeaveDb
|
|||
.HasComment("PrimaryKey")
|
||||
.HasAnnotation("Relational:JsonPropertyName", "id");
|
||||
|
||||
b.Property<int>("BeginningLeaveCount")
|
||||
.HasColumnType("int")
|
||||
.HasComment("จำนวนครั้งที่ลายกมา");
|
||||
|
||||
b.Property<double>("BeginningLeaveDays")
|
||||
.HasColumnType("double")
|
||||
.HasComment("จำนวนวันลายกมา");
|
||||
|
||||
b.Property<Guid?>("Child1DnaId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
|
|
@ -184,11 +192,15 @@ namespace BMA.EHR.Infrastructure.Migrations.LeaveDb
|
|||
.HasColumnOrder(102)
|
||||
.HasComment("แก้ไขข้อมูลล่าสุดเมื่อ");
|
||||
|
||||
b.Property<int?>("LeaveCount")
|
||||
.HasColumnType("int")
|
||||
.HasComment("จำนวนครั้งที่ลาสะสม");
|
||||
|
||||
b.Property<double>("LeaveDays")
|
||||
.HasColumnType("double")
|
||||
.HasComment("จำนวนวันลายกมา");
|
||||
.HasComment("จำนวนวันลาทั้งหมด");
|
||||
|
||||
b.Property<double>("LeaveDaysUsed")
|
||||
b.Property<double?>("LeaveDaysUsed")
|
||||
.HasColumnType("double")
|
||||
.HasComment("จำนวนวันลาที่ใช้ไป");
|
||||
|
||||
|
|
@ -214,7 +226,7 @@ namespace BMA.EHR.Infrastructure.Migrations.LeaveDb
|
|||
|
||||
b.HasIndex("LeaveTypeId");
|
||||
|
||||
b.ToTable("LeaveBeginnings");
|
||||
b.ToTable("LeaveBeginnings", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BMA.EHR.Domain.Models.Leave.Requests.LeaveDocument", b =>
|
||||
|
|
@ -276,7 +288,7 @@ namespace BMA.EHR.Infrastructure.Migrations.LeaveDb
|
|||
|
||||
b.HasIndex("LeaveRequestId");
|
||||
|
||||
b.ToTable("LeaveDocuments");
|
||||
b.ToTable("LeaveDocuments", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BMA.EHR.Domain.Models.Leave.Requests.LeaveRequest", b =>
|
||||
|
|
@ -416,6 +428,9 @@ namespace BMA.EHR.Infrastructure.Migrations.LeaveDb
|
|||
b.Property<DateTime?>("DateAppoint")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<DateTime?>("DateSendLeave")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<string>("Dear")
|
||||
.HasColumnType("longtext")
|
||||
.HasComment("เรียนใคร");
|
||||
|
|
@ -652,7 +667,7 @@ namespace BMA.EHR.Infrastructure.Migrations.LeaveDb
|
|||
|
||||
b.HasIndex("TypeId");
|
||||
|
||||
b.ToTable("LeaveRequests");
|
||||
b.ToTable("LeaveRequests", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BMA.EHR.Domain.Models.Leave.Requests.LeaveRequestApprover", b =>
|
||||
|
|
@ -698,6 +713,13 @@ namespace BMA.EHR.Infrastructure.Migrations.LeaveDb
|
|||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<bool>("IsAct")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<string>("KeyId")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<Guid>("KeycloakId")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
|
|
@ -764,7 +786,7 @@ namespace BMA.EHR.Infrastructure.Migrations.LeaveDb
|
|||
|
||||
b.HasIndex("LeaveRequestId");
|
||||
|
||||
b.ToTable("LeaveRequestApprovers");
|
||||
b.ToTable("LeaveRequestApprovers", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BMA.EHR.Domain.Models.Leave.TimeAttendants.AdditionalCheckRequest", b =>
|
||||
|
|
@ -879,7 +901,7 @@ namespace BMA.EHR.Infrastructure.Migrations.LeaveDb
|
|||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("AdditionalCheckRequests");
|
||||
b.ToTable("AdditionalCheckRequests", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BMA.EHR.Domain.Models.Leave.TimeAttendants.CheckInJobStatus", b =>
|
||||
|
|
@ -972,7 +994,7 @@ namespace BMA.EHR.Infrastructure.Migrations.LeaveDb
|
|||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("CheckInJobStatuses");
|
||||
b.ToTable("CheckInJobStatuses", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BMA.EHR.Domain.Models.Leave.TimeAttendants.DutyTime", b =>
|
||||
|
|
@ -1057,7 +1079,92 @@ namespace BMA.EHR.Infrastructure.Migrations.LeaveDb
|
|||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("DutyTimes");
|
||||
b.ToTable("DutyTimes", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BMA.EHR.Domain.Models.Leave.TimeAttendants.LeaveProcessJobStatus", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("char(36)")
|
||||
.HasColumnOrder(0)
|
||||
.HasComment("PrimaryKey")
|
||||
.HasAnnotation("Relational:JsonPropertyName", "id");
|
||||
|
||||
b.Property<DateTime?>("CompletedDate")
|
||||
.HasColumnType("datetime(6)")
|
||||
.HasComment("วันเวลาที่เสร็จสิ้นการประมวลผล");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)")
|
||||
.HasColumnOrder(100)
|
||||
.HasComment("สร้างข้อมูลเมื่อ");
|
||||
|
||||
b.Property<DateTime>("CreatedDate")
|
||||
.HasColumnType("datetime(6)")
|
||||
.HasComment("วันเวลาที่สร้างงาน");
|
||||
|
||||
b.Property<string>("CreatedFullName")
|
||||
.IsRequired()
|
||||
.HasMaxLength(200)
|
||||
.HasColumnType("varchar(200)")
|
||||
.HasColumnOrder(104)
|
||||
.HasComment("ชื่อ User ที่สร้างข้อมูล");
|
||||
|
||||
b.Property<string>("CreatedUserId")
|
||||
.IsRequired()
|
||||
.HasMaxLength(40)
|
||||
.HasColumnType("varchar(40)")
|
||||
.HasColumnOrder(101)
|
||||
.HasComment("User Id ที่สร้างข้อมูล");
|
||||
|
||||
b.Property<DateTime>("EndDate")
|
||||
.HasColumnType("datetime(6)")
|
||||
.HasComment("วันสิ้นสุด");
|
||||
|
||||
b.Property<string>("ErrorMessage")
|
||||
.HasColumnType("longtext")
|
||||
.HasComment("ข้อความแสดงข้อผิดพลาด");
|
||||
|
||||
b.Property<string>("LastUpdateFullName")
|
||||
.IsRequired()
|
||||
.HasMaxLength(200)
|
||||
.HasColumnType("varchar(200)")
|
||||
.HasColumnOrder(105)
|
||||
.HasComment("ชื่อ User ที่แก้ไขข้อมูลล่าสุด");
|
||||
|
||||
b.Property<string>("LastUpdateUserId")
|
||||
.IsRequired()
|
||||
.HasMaxLength(40)
|
||||
.HasColumnType("varchar(40)")
|
||||
.HasColumnOrder(103)
|
||||
.HasComment("User Id ที่แก้ไขข้อมูลล่าสุด");
|
||||
|
||||
b.Property<DateTime?>("LastUpdatedAt")
|
||||
.HasColumnType("datetime(6)")
|
||||
.HasColumnOrder(102)
|
||||
.HasComment("แก้ไขข้อมูลล่าสุดเมื่อ");
|
||||
|
||||
b.Property<DateTime?>("ProcessingDate")
|
||||
.HasColumnType("datetime(6)")
|
||||
.HasComment("วันเวลาที่เริ่มประมวลผล");
|
||||
|
||||
b.Property<Guid>("RootDnaId")
|
||||
.HasColumnType("char(36)")
|
||||
.HasComment("รหัส Root DNA Id");
|
||||
|
||||
b.Property<DateTime>("StartDate")
|
||||
.HasColumnType("datetime(6)")
|
||||
.HasComment("วันเริ่มต้น");
|
||||
|
||||
b.Property<string>("Status")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext")
|
||||
.HasComment("สถานะงาน: PENDING, PROCESSING, COMPLETED, FAILED");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("LeaveProcessJobStatuses", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BMA.EHR.Domain.Models.Leave.TimeAttendants.ProcessUserTimeStamp", b =>
|
||||
|
|
@ -1268,7 +1375,7 @@ namespace BMA.EHR.Infrastructure.Migrations.LeaveDb
|
|||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("ProcessUserTimeStamps");
|
||||
b.ToTable("ProcessUserTimeStamps", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BMA.EHR.Domain.Models.Leave.TimeAttendants.UserCalendar", b =>
|
||||
|
|
@ -1329,7 +1436,7 @@ namespace BMA.EHR.Infrastructure.Migrations.LeaveDb
|
|||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("UserCalendars");
|
||||
b.ToTable("UserCalendars", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BMA.EHR.Domain.Models.Leave.TimeAttendants.UserDutyTime", b =>
|
||||
|
|
@ -1418,7 +1525,7 @@ namespace BMA.EHR.Infrastructure.Migrations.LeaveDb
|
|||
|
||||
b.HasIndex("DutyTimeId");
|
||||
|
||||
b.ToTable("UserDutyTimes");
|
||||
b.ToTable("UserDutyTimes", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BMA.EHR.Domain.Models.Leave.TimeAttendants.UserTimeStamp", b =>
|
||||
|
|
@ -1612,7 +1719,7 @@ namespace BMA.EHR.Infrastructure.Migrations.LeaveDb
|
|||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("UserTimeStamps");
|
||||
b.ToTable("UserTimeStamps", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("BMA.EHR.Domain.Models.Leave.Requests.LeaveBeginning", b =>
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@ namespace BMA.EHR.Infrastructure.Persistence
|
|||
|
||||
#endregion
|
||||
|
||||
public DbSet<LeaveProcessJobStatus> LeaveProcessJobStatuses { get; set; }
|
||||
|
||||
|
||||
public LeaveDbContext(DbContextOptions<LeaveDbContext> options) : base(options)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -331,7 +331,7 @@ namespace BMA.EHR.Insignia.Service.Controllers
|
|||
if (req.Total + total > insigniaManage.Total)
|
||||
return Error(GlobalMessages.InsigniaManageOrgLimit);
|
||||
|
||||
var ocData = _userProfileRepository.GetOc(req.OrganizationOrganizationId, 0, AccessToken);
|
||||
var ocData = _userProfileRepository.GetOcByNodeId(req.OrganizationOrganizationId, 0, AccessToken);
|
||||
var root = ocData?.Root ?? null;
|
||||
var rootDnaId = ocData?.RootDnaId ?? null;
|
||||
await _context.InsigniaManageOrganiations.AddAsync(
|
||||
|
|
@ -407,6 +407,10 @@ namespace BMA.EHR.Insignia.Service.Controllers
|
|||
if (uppdated == null)
|
||||
return Error(GlobalMessages.InsigniaManageNotFound);
|
||||
|
||||
var ocData = _userProfileRepository.GetOcByNodeId(uppdated.OrganizationId, 0, AccessToken);
|
||||
var root = ocData?.Root ?? null;
|
||||
var rootDnaId = ocData?.RootDnaId ?? null;
|
||||
|
||||
var insigniaManage = await _context.InsigniaManages.AsQueryable()
|
||||
.Include(x => x.InsigniaManageOrganiations)
|
||||
.FirstOrDefaultAsync(x => x.Id == uppdated.InsigniaManage.Id);
|
||||
|
|
@ -416,6 +420,9 @@ namespace BMA.EHR.Insignia.Service.Controllers
|
|||
if (req.Total + total > insigniaManage.Total)
|
||||
return Error(GlobalMessages.InsigniaManageOrgLimit);
|
||||
|
||||
uppdated.Organization = root;
|
||||
uppdated.RootDnaId = rootDnaId;
|
||||
|
||||
uppdated.Total = req.Total;
|
||||
uppdated.LastUpdateFullName = FullName ?? "System Administrator";
|
||||
uppdated.LastUpdateUserId = UserId ?? "";
|
||||
|
|
@ -639,7 +646,7 @@ namespace BMA.EHR.Insignia.Service.Controllers
|
|||
? profileAdmin?.RootDnaId
|
||||
: "";
|
||||
}
|
||||
else if (role == "ROOT" || role == "PARENT")
|
||||
else if (role == "ROOT" /*|| role == "PARENT"*/)
|
||||
{
|
||||
nodeId = profileAdmin?.RootDnaId;
|
||||
}
|
||||
|
|
@ -724,11 +731,11 @@ namespace BMA.EHR.Insignia.Service.Controllers
|
|||
rawData = rawData
|
||||
.Where(x => x.RootDnaId == Guid.Parse(nodeId!)).ToList();
|
||||
}
|
||||
else if (role == "PARENT")
|
||||
{
|
||||
rawData = rawData
|
||||
.Where(x => x.RootDnaId == Guid.Parse(nodeId!) && x.Child1DnaId != null).ToList();
|
||||
}
|
||||
// else if (role == "PARENT")
|
||||
// {
|
||||
// rawData = rawData
|
||||
// .Where(x => x.RootDnaId == Guid.Parse(nodeId!) && x.Child1DnaId != null).ToList();
|
||||
// }
|
||||
else if (role == "NORMAL")
|
||||
{
|
||||
rawData = rawData.Where(x =>
|
||||
|
|
@ -943,7 +950,7 @@ namespace BMA.EHR.Insignia.Service.Controllers
|
|||
? profileAdmin?.RootDnaId
|
||||
: "";
|
||||
}
|
||||
else if (role == "ROOT" || role == "PARENT")
|
||||
else if (role == "ROOT" /*|| role == "PARENT"*/)
|
||||
{
|
||||
nodeId = profileAdmin?.RootDnaId;
|
||||
}
|
||||
|
|
@ -1026,11 +1033,11 @@ namespace BMA.EHR.Insignia.Service.Controllers
|
|||
rawData = rawData
|
||||
.Where(x => x.RootDnaId == Guid.Parse(nodeId!)).ToList();
|
||||
}
|
||||
else if (role == "PARENT")
|
||||
{
|
||||
rawData = rawData
|
||||
.Where(x => x.RootDnaId == Guid.Parse(nodeId!) && x.Child1DnaId != null).ToList();
|
||||
}
|
||||
// else if (role == "PARENT")
|
||||
// {
|
||||
// rawData = rawData
|
||||
// .Where(x => x.RootDnaId == Guid.Parse(nodeId!) && x.Child1DnaId != null).ToList();
|
||||
// }
|
||||
else if (role == "NORMAL")
|
||||
{
|
||||
rawData = rawData.Where(x =>
|
||||
|
|
|
|||
|
|
@ -2641,6 +2641,8 @@ namespace BMA.EHR.Insignia.Service.Controllers
|
|||
{
|
||||
if (item.CitizanId == null) continue;
|
||||
var _profile = await _userProfileRepository.GetOfficerProfileByCitizenId(item.CitizanId, AccessToken);
|
||||
if (_profile == null)
|
||||
continue;
|
||||
var profile = insigniaNote.InsigniaNoteProfiles.FirstOrDefault(x => x.ProfileId == _profile.Id);
|
||||
if (profile == null)
|
||||
{
|
||||
|
|
@ -3096,7 +3098,7 @@ namespace BMA.EHR.Insignia.Service.Controllers
|
|||
var doc = await _documentService.UploadFileAsync(file, file.FileName);
|
||||
insigniaNoteProfile.DocReturnInsignia = doc;
|
||||
}
|
||||
var root = _userProfileRepository.GetOc(req.OrgId, 0, AccessToken)?.Root ?? null;
|
||||
var root = _userProfileRepository.GetOcByNodeId(req.OrgId, 0, AccessToken)?.Root ?? null;
|
||||
if (req.OrgId != Guid.Parse("00000000-0000-0000-0000-000000000000"))
|
||||
{
|
||||
if (root == null)
|
||||
|
|
@ -3146,7 +3148,10 @@ namespace BMA.EHR.Insignia.Service.Controllers
|
|||
var doc = await _documentService.UploadFileAsync(file, file.FileName);
|
||||
insigniaNoteProfile.DocReceiveInsignia = doc;
|
||||
}
|
||||
var root = _userProfileRepository.GetOc(req.OrgId, 0, AccessToken)?.Root ?? null;
|
||||
|
||||
var orgData = _userProfileRepository.GetOcByNodeId(req.OrgId,0, AccessToken);
|
||||
var root = orgData?.Root ?? null;
|
||||
var rootDnaId = orgData?.RootDnaId ?? null;
|
||||
if (req.OrgId != Guid.Parse("00000000-0000-0000-0000-000000000000"))
|
||||
{
|
||||
if (root == null)
|
||||
|
|
@ -3157,6 +3162,7 @@ namespace BMA.EHR.Insignia.Service.Controllers
|
|||
root = "สำนักนายกรัฐมนตรี";
|
||||
}
|
||||
insigniaNoteProfile.OrgReceiveInsignia = root;
|
||||
insigniaNoteProfile.RootDnaId = rootDnaId;
|
||||
insigniaNoteProfile.OrgReceiveInsigniaId = req.OrgId;
|
||||
insigniaNoteProfile.DateReceiveInsignia = req.Date;
|
||||
insigniaNoteProfile.LastUpdateFullName = FullName ?? "System Administrator";
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ var builder = WebApplication.CreateBuilder(args);
|
|||
{
|
||||
options.ServerName = "Insignia-Server"; // ← ระบุชื่อ server
|
||||
options.WorkerCount = 5; // ←
|
||||
options.Queues = new[] { "insignia" }; // ← worker จะรันเฉพาะ queue "insignia"
|
||||
options.Queues = new[] { "insignia","default" }; // ← worker จะรันเฉพาะ queue "insignia"
|
||||
});
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -31,10 +31,11 @@
|
|||
//"DisciplineConnection": "server=hrms.chin.in.th;user=root;password=ey2qVVyyqGYw8CyA7h8X72559r2Ad84K;port=53636;database=hrms_discipline;Convert Zero Datetime=True;Allow User Variables=true;Pooling=True;"
|
||||
},
|
||||
"Jwt": {
|
||||
//"Key": "j7C9RO_p4nRtuwCH4z9Db_A_6We42tkD_p4lZtDrezc",
|
||||
//"Issuer": "https://hrms-id.chin.in.th/realms/hrms"
|
||||
"Key": "HP-FnQMUj9msHMSD3T9HtdEnphAKoCJLEl85CIqROFI",
|
||||
"Issuer": "https://id.frappet.synology.me/realms/hrms"
|
||||
//"Key": "HP-FnQMUj9msHMSD3T9HtdEnphAKoCJLEl85CIqROFI",
|
||||
"Key": "j7C9RO_p4nRtuwCH4z9Db_A_6We42tkD_p4lZtDrezc",
|
||||
"Issuer": "https://hrmsbkk-id.case-collection.com/realms/hrms"
|
||||
//"Key": "xY2VR-EFvvNPsMs39u8ooVBWQL6mPwrNJOh3koJFTgU",
|
||||
//"Issuer": "https://hrms-id.bangkok.go.th/realms/hrms"
|
||||
},
|
||||
"EPPlus": {
|
||||
"ExcelPackage": {
|
||||
|
|
@ -55,11 +56,17 @@
|
|||
"Node": {
|
||||
"API": "https://bma-ehr.frappet.synology.me/api/v1/probation"
|
||||
},
|
||||
"API": "https://bma-ehr.frappet.synology.me/api/v1",
|
||||
"RabbitMQ": {
|
||||
"URL": "localhost",
|
||||
"UserName": "frappet",
|
||||
"Password": "FPTadmin2357"
|
||||
},
|
||||
"Domain": "https://hrmsbkk.case-collection.com",
|
||||
"APIPROBATION": "https://hrmsbkk.case-collection.com/api/v1/probation",
|
||||
"API": "https://hrmsbkk.case-collection.com/api/v1",
|
||||
"APIV2": "https://hrmsbkk.case-collection.com/api/v2",
|
||||
"VITE_URL_MGT": "https://hrmsbkk-mgt.case-collection.com",
|
||||
//"API": "https://bma-ehr.frappet.synology.me/api/v1",
|
||||
//"API": "https://bma-hrms.bangkok.go.th/api/v1",
|
||||
"API_KEY": "fKRL16yyEgbyTEJdsMw2h64tGSCmkW685PRtM3CygzX1JOSdptT9UJtpgWwKM8FybRTJups3GTFwj27ZRvlPdIkv3XgCoVJaD5LmR06ozuEPvCCRSdp2WFthg08V5xHc56fTPfZLpr1VmXrhd6dvYhHIqKkQUJR02Rlkss11cLRWEQOssEFVA4xdu2J5DIRO1EM5m7wRRvEwcDB4mYRXD9HH52SMq6iYqUWEWsMwLdbk7QW9yYESUEuzMW5gWrb6vIeWZxJV5bTz1PcWUyR7eO9Fyw1F5DiQYc9JgzTC1mW7cv31fEtTtrfbJYKIb5EbWilqIEUKC6A0UKBDDek35ML0006cqRVm0pvdOH6jeq7VQyYrhdXe59dBEyhYGUIfozoVBvW7Up4QBuOMjyPjSqJPlMBKwaseptfrblxQV1AOOivSBpf1ZcQyOZ8JktRtKUDSuXsmG0lsXwFlI3JCeSHdpVdgZWFYcJPegqfrB6KotR02t9AVkpLs1ZWrixwz"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@
|
|||
<PackageReference Include="Microsoft.IdentityModel.Logging" Version="6.31.0" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.18.1" />
|
||||
<PackageReference Include="NEST" Version="7.17.5" />
|
||||
<PackageReference Include="NodaTime" Version="3.3.0" />
|
||||
<PackageReference Include="runtime.osx.10.10-x64.CoreCompat.System.Drawing" Version="6.0.5.128" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="7.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
|
||||
|
|
@ -73,6 +74,9 @@
|
|||
<Content Update="wwwroot\keycloak.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="wwwroot\blank.jpeg">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
private readonly IConfiguration _configuration;
|
||||
private readonly UserProfileRepository _userProfileRepository;
|
||||
private readonly PermissionRepository _permission;
|
||||
private readonly LeaveRequestRepository _leaveRequestRepository;
|
||||
|
||||
#endregion
|
||||
|
||||
|
|
@ -44,7 +45,8 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
IWebHostEnvironment hostingEnvironment,
|
||||
IConfiguration configuration,
|
||||
UserProfileRepository userProfileRepository,
|
||||
PermissionRepository permission)
|
||||
PermissionRepository permission,
|
||||
LeaveRequestRepository leaveRequestRepository)
|
||||
{
|
||||
_leaveBeginningRepository = leaveBeginningRepository;
|
||||
_context = context;
|
||||
|
|
@ -53,6 +55,7 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
_configuration = configuration;
|
||||
_userProfileRepository = userProfileRepository;
|
||||
_permission = permission;
|
||||
_leaveRequestRepository = leaveRequestRepository;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
@ -141,7 +144,7 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
? profileAdmin?.RootDnaId
|
||||
: "";
|
||||
}
|
||||
else if (role == "ROOT" || role == "PARENT")
|
||||
else if (role == "ROOT" /*|| role == "PARENT"*/)
|
||||
{
|
||||
nodeId = profileAdmin?.RootDnaId;
|
||||
}
|
||||
|
|
@ -166,11 +169,11 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
resData = resData
|
||||
.Where(x => x.RootDnaId == Guid.Parse(nodeId!)).ToList();
|
||||
}
|
||||
else if (role == "PARENT")
|
||||
{
|
||||
resData = resData
|
||||
.Where(x => x.RootDnaId == Guid.Parse(nodeId!) && x.Child1DnaId != null).ToList();
|
||||
}
|
||||
// else if (role == "PARENT")
|
||||
// {
|
||||
// resData = resData
|
||||
// .Where(x => x.RootDnaId == Guid.Parse(nodeId!) && x.Child1DnaId != null).ToList();
|
||||
// }
|
||||
else if (role == "NORMAL")
|
||||
{
|
||||
resData = resData
|
||||
|
|
@ -201,6 +204,9 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
item.LeaveYear,
|
||||
item.LeaveDays,
|
||||
item.LeaveDaysUsed,
|
||||
item.LeaveCount,
|
||||
item.BeginningLeaveDays,
|
||||
item.BeginningLeaveCount,
|
||||
item.CreatedAt,
|
||||
item.CreatedFullName,
|
||||
item.LastUpdatedAt,
|
||||
|
|
@ -372,6 +378,15 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
try
|
||||
{
|
||||
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 jsonData = JsonConvert.DeserializeObject<JObject>(getPermission);
|
||||
|
|
@ -383,17 +398,41 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
if (leaveBeginning == null)
|
||||
return Error("ไม่พบข้อมูลที่ต้องการแก้ไข", StatusCodes.Status404NotFound);
|
||||
|
||||
|
||||
var profile = await _userProfileRepository.GetProfileByProfileIdAsync(req.ProfileId, AccessToken);
|
||||
if (profile == null)
|
||||
{
|
||||
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,endFiscalDate.AddDays(1));
|
||||
var systemLeaveCount = await _leaveRequestRepository.GetSumApproveLeaveCountByTypeAndRangeForUserByProfile(req.ProfileId, req.LeaveTypeId, startFiscalDate, endFiscalDate,endFiscalDate.AddDays(1));
|
||||
|
||||
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.LeaveYear = req.LeaveYear;
|
||||
leaveBeginning.LeaveDays = req.LeaveDays;
|
||||
leaveBeginning.LeaveDaysUsed = req.LeaveDaysUsed;
|
||||
|
||||
|
||||
leaveBeginning.ProfileId = req.ProfileId;
|
||||
leaveBeginning.Prefix = profile.Prefix;
|
||||
|
|
@ -434,6 +473,17 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
try
|
||||
{
|
||||
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 jsonData = JsonConvert.DeserializeObject<JObject>(getPermission);
|
||||
if (jsonData["status"]?.ToString() != "200")
|
||||
|
|
@ -458,10 +508,26 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
}
|
||||
|
||||
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.LeaveYear = req.LeaveYear;
|
||||
leaveBeginning.LeaveDays = req.LeaveDays;
|
||||
leaveBeginning.LeaveDaysUsed = req.LeaveDaysUsed;
|
||||
|
||||
|
||||
leaveBeginning.ProfileId = req.ProfileId;
|
||||
leaveBeginning.Prefix = profile.Prefix;
|
||||
|
|
@ -489,6 +555,126 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
}
|
||||
}
|
||||
|
||||
[HttpPut("schedule")]
|
||||
[AllowAnonymous]
|
||||
public async Task<ActionResult<ResponseObject>> ScheduleUpdateLeaveBeginningAsync([FromBody] ScheduleEditLeaveBeginningDto req)
|
||||
{
|
||||
try
|
||||
{
|
||||
var profile = await _userProfileRepository.GetProfileByProfileIdNoAuthAsync(req.ProfileId, AccessToken);
|
||||
if(profile == null)
|
||||
{
|
||||
return Error("ไม่พบข้อมูลข้าราชการหรือลูกจ้าง", StatusCodes.Status404NotFound);
|
||||
}
|
||||
// check duplicate
|
||||
var oldData = await _context.LeaveBeginnings.FirstOrDefaultAsync(x => x.ProfileId == req.ProfileId
|
||||
&& x.LeaveTypeId == req.LeaveTypeId
|
||||
&& x.LeaveYear == req.LeaveYear);
|
||||
|
||||
if (oldData is not null)
|
||||
{
|
||||
//return Error("ไม่สามารถบันทึกข้อมูล เนื่องจากมีข้อมูลในระบบแล้ว");
|
||||
oldData.LeaveTypeId = req.LeaveTypeId;
|
||||
oldData.LeaveYear = req.LeaveYear;
|
||||
oldData.LeaveDays = req.LeaveDays;
|
||||
// oldData.LeaveDaysUsed = req.LeaveDaysUsed;
|
||||
// oldData.LeaveCount = req.LeaveCount;
|
||||
// oldData.BeginningLeaveDays = req.BeginningLeaveDays;
|
||||
// oldData.BeginningLeaveCount = req.BeginningLeaveCount;
|
||||
|
||||
oldData.ProfileId = req.ProfileId;
|
||||
oldData.Prefix = profile.Prefix;
|
||||
oldData.FirstName = profile.FirstName;
|
||||
oldData.LastName = profile.LastName;
|
||||
oldData.RootDnaId = profile.RootDnaId;
|
||||
oldData.Child1DnaId = profile.Child1DnaId;
|
||||
oldData.Child2DnaId = profile.Child2DnaId;
|
||||
oldData.Child3DnaId = profile.Child3DnaId;
|
||||
oldData.Child4DnaId = profile.Child4DnaId;
|
||||
|
||||
oldData.LastUpdateUserId = "";
|
||||
oldData.LastUpdateFullName = "System";
|
||||
oldData.LastUpdatedAt = DateTime.Now;
|
||||
|
||||
await _leaveBeginningRepository.UpdateAsync(oldData);
|
||||
}
|
||||
else
|
||||
{
|
||||
var leaveBeginning = new LeaveBeginning();
|
||||
leaveBeginning.LeaveTypeId = req.LeaveTypeId;
|
||||
leaveBeginning.LeaveYear = req.LeaveYear;
|
||||
leaveBeginning.LeaveDays = req.LeaveDays;
|
||||
leaveBeginning.LeaveDaysUsed = 0;
|
||||
leaveBeginning.LeaveCount = 0;
|
||||
leaveBeginning.BeginningLeaveDays = 0;
|
||||
leaveBeginning.BeginningLeaveCount = 0;
|
||||
|
||||
leaveBeginning.ProfileId = req.ProfileId;
|
||||
leaveBeginning.Prefix = profile.Prefix;
|
||||
leaveBeginning.FirstName = profile.FirstName;
|
||||
leaveBeginning.LastName = profile.LastName;
|
||||
|
||||
leaveBeginning.RootDnaId = profile.RootDnaId;
|
||||
leaveBeginning.Child1DnaId = profile.Child1DnaId;
|
||||
leaveBeginning.Child2DnaId = profile.Child2DnaId;
|
||||
leaveBeginning.Child3DnaId = profile.Child3DnaId;
|
||||
leaveBeginning.Child4DnaId = profile.Child4DnaId;
|
||||
|
||||
leaveBeginning.CreatedUserId = "";
|
||||
leaveBeginning.CreatedFullName = "System";
|
||||
leaveBeginning.CreatedAt = DateTime.Now;
|
||||
|
||||
await _leaveBeginningRepository.AddAsync(leaveBeginning);
|
||||
}
|
||||
return Success();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Error(ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[HttpPut("schedule/update-dna")]
|
||||
[AllowAnonymous]
|
||||
public async Task<ActionResult<ResponseObject>> ScheduleUpdateDnaAsync([FromBody] List<ScheduleUpdateDnaDto> req)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach(var item in req)
|
||||
{
|
||||
// var profile = await _userProfileRepository.GetProfileByProfileIdNoAuthAsync(item.ProfileId, AccessToken);
|
||||
// if(profile == null)
|
||||
// {
|
||||
// return Error("ไม่พบข้อมูลข้าราชการหรือลูกจ้าง", StatusCodes.Status404NotFound);
|
||||
// }
|
||||
// check duplicate
|
||||
var oldData = await _context.LeaveBeginnings.Where(x => x.ProfileId == item.ProfileId).ToListAsync();
|
||||
|
||||
foreach(var o in oldData)
|
||||
{
|
||||
o.RootDnaId = item.RootDnaId;
|
||||
o.Child1DnaId = item.Child1DnaId;
|
||||
o.Child2DnaId = item.Child2DnaId;
|
||||
o.Child3DnaId = item.Child3DnaId;
|
||||
o.Child4DnaId = item.Child4DnaId;
|
||||
|
||||
o.LastUpdateUserId = "";
|
||||
o.LastUpdateFullName = "System";
|
||||
o.LastUpdatedAt = DateTime.Now;
|
||||
|
||||
await _leaveBeginningRepository.UpdateAsync(o);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return Success();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Error(ex);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -7,6 +7,7 @@ using BMA.EHR.Application.Responses.Profiles;
|
|||
using BMA.EHR.Domain.Common;
|
||||
using BMA.EHR.Domain.Extensions;
|
||||
using BMA.EHR.Domain.Models.Leave.Requests;
|
||||
using BMA.EHR.Domain.Models.Leave.TimeAttendants;
|
||||
using BMA.EHR.Domain.Shared;
|
||||
using BMA.EHR.Leave.Service.DTOs.Reports;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
|
|
@ -149,18 +150,35 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
}
|
||||
|
||||
var fullName = $"{profile!.Prefix}{profile!.FirstName} {profile!.LastName}";
|
||||
|
||||
|
||||
var lastLeaveRequest =
|
||||
await _leaveRequestRepository.GetLastLeaveRequestByTypeForUserAsync(data.KeycloakUserId,
|
||||
data.Type.Id, data.LeaveStartDate.Date);
|
||||
await _leaveRequestRepository.GetLastLeaveRequestByTypeForUserAsync2(data.KeycloakUserId,
|
||||
data.Type.Id, data.CreatedAt);
|
||||
|
||||
var fiscalYear = data.LeaveStartDate.Month >= 10 ? data.LeaveStartDate.Year + 1 : data.LeaveStartDate.Year;
|
||||
var fiscalStart = new DateTime(fiscalYear - 1, 10, 1);
|
||||
var fiscalEnd = new DateTime(fiscalYear, 9, 30);
|
||||
|
||||
var startFiscalYear = (new DateTime(data.LeaveStartDate.Year - 1, 10, 1)).Date;
|
||||
var endFiscalYear = (data.DateSendLeave ?? data.CreatedAt);
|
||||
var sendLeaveDate = data.DateSendLeave ?? data.CreatedAt;
|
||||
|
||||
var thisYear = data.LeaveStartDate.Year;
|
||||
var toDay = data.LeaveStartDate.Date;
|
||||
if (toDay >= new DateTime(toDay.Year, 10, 1) && toDay <= new DateTime(toDay.Year, 12, 31))
|
||||
thisYear = thisYear + 1;
|
||||
var leaveData = await _leaveBeginningRepository.GetByYearAndTypeIdForUser2Async(thisYear, data.Type.Id, data.KeycloakUserId);
|
||||
var sumLeave = await _leaveRequestRepository.GetSumApproveLeaveTotalByTypeAndRangeForUserBefore(data.KeycloakUserId, data.Type.Id, fiscalStart, fiscalEnd, sendLeaveDate);
|
||||
if (leaveData != null)
|
||||
{
|
||||
sumLeave += leaveData.BeginningLeaveDays;
|
||||
}
|
||||
|
||||
var startFiscalYear = new DateTime(data.LeaveStartDate.Year - 1, 10, 1);
|
||||
var endFiscalYear = data.LeaveStartDate.Date.AddDays(-1); // นับจากวันที่ยื่นลา
|
||||
var sumLeave = await _leaveRequestRepository.GetSumApproveLeaveTotalByTypeAndRangeForUser(data.KeycloakUserId, data.Type.Id, startFiscalYear, endFiscalYear);
|
||||
var Oc = profile.isCommission == false
|
||||
? profile.Oc.ToThaiNumber()
|
||||
: profile.Oc.Replace("สำนักงานคณะกรรมการข้าราชการกรุงเทพมหานคร", "สำนักงาน ก.ก.").ToThaiNumber();
|
||||
var approveResult = await GetApproverData(data.Approvers, profile.isCommission);
|
||||
var approveResult = await GetApproverData(data.Approvers);
|
||||
|
||||
return new
|
||||
{
|
||||
|
|
@ -169,7 +187,7 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
data = new
|
||||
{
|
||||
leaveWrote = data.LeaveWrote.ToThaiNumber() ?? "",
|
||||
dateSendLeave = data.CreatedAt.Date.ToThaiShortDate().ToThaiNumber(),
|
||||
dateSendLeave = data.DateSendLeave != null ? data.DateSendLeave.Value.Date.ToThaiShortDate().ToThaiNumber() : data.CreatedAt.Date.ToThaiShortDate().ToThaiNumber(),
|
||||
leaveTypeName = data.Type.Name,
|
||||
leaveSubTypeName = data.LeaveSubTypeName != null ? data.LeaveSubTypeName.ToThaiNumber() : "",
|
||||
dear = data.CommanderPosition == null ? data.Dear : data.CommanderPosition.ToThaiNumber(),
|
||||
|
|
@ -204,6 +222,8 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
leaveNumber = data.LeaveNumber.ToThaiNumber(),
|
||||
LeaveLastStart = lastLeaveRequest == null ? "" : lastLeaveRequest.LeaveStartDate.Date.ToThaiShortDate().ToThaiNumber(),
|
||||
LeaveLastEnd = lastLeaveRequest == null ? "" : lastLeaveRequest.LeaveEndDate.Date.ToThaiShortDate().ToThaiNumber(),
|
||||
|
||||
LeaveLastTotal = lastLeaveRequest == null ? "0".ToThaiNumber() : lastLeaveRequest.LeaveTotal.ToString().ToThaiNumber(),
|
||||
|
||||
LeaveSummary = sumLeave.ToString().ToThaiNumber(),
|
||||
LeaveRemain = (data.Type.Limit - sumLeave).ToString().ToThaiNumber(),
|
||||
|
|
@ -251,7 +271,7 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
var Oc = profile.isCommission == false
|
||||
? profile.Oc.ToThaiNumber()
|
||||
: profile.Oc.Replace("สำนักงานคณะกรรมการข้าราชการกรุงเทพมหานคร", "สำนักงาน ก.ก.").ToThaiNumber();
|
||||
var approveResult = await GetApproverData(data.Approvers, profile.isCommission);
|
||||
var approveResult = await GetApproverData(data.Approvers);
|
||||
return new
|
||||
{
|
||||
template = "leave10",
|
||||
|
|
@ -259,7 +279,7 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
data = new
|
||||
{
|
||||
leaveWrote = data.LeaveWrote.ToThaiNumber() ?? "",
|
||||
dateSendLeave = data.CreatedAt.Date.ToThaiShortDate().ToThaiNumber(),
|
||||
dateSendLeave = data.DateSendLeave != null ? data.DateSendLeave.Value.Date.ToThaiShortDate().ToThaiNumber() : data.CreatedAt.Date.ToThaiShortDate().ToThaiNumber(),
|
||||
leaveTypeName = data.Type.Name,
|
||||
leaveSubTypeName = data.LeaveSubTypeName != null ? data.LeaveSubTypeName.ToThaiNumber() : "",
|
||||
dear = data.CommanderPosition == null ? data.Dear : data.CommanderPosition.ToThaiNumber(),
|
||||
|
|
@ -319,21 +339,30 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
var fullName = $"{profile!.Prefix}{profile!.FirstName} {profile!.LastName}";
|
||||
|
||||
var startFiscalYear = new DateTime(data.LeaveStartDate.Year - 1, 10, 1);
|
||||
var endFiscalYear = data.LeaveStartDate.Date.AddDays(-1); // นับจากวันที่ยื่นลา
|
||||
var endFiscalYear = (data.DateSendLeave ?? data.CreatedAt);
|
||||
|
||||
var fiscalYear = data.LeaveStartDate.Month >= 10 ? data.LeaveStartDate.Year + 1 : data.LeaveStartDate.Year;
|
||||
var fiscalStart = new DateTime(fiscalYear - 1, 10, 1);
|
||||
var fiscalEnd = new DateTime(fiscalYear, 9, 30);
|
||||
|
||||
var thisYear = data.LeaveStartDate.Year;
|
||||
var toDay = data.LeaveStartDate.Date;
|
||||
if (toDay >= new DateTime(toDay.Year, 10, 1) && toDay <= new DateTime(toDay.Year, 12, 31))
|
||||
thisYear = thisYear + 1;
|
||||
|
||||
var leaveData = await _leaveBeginningRepository.GetByYearAndTypeIdForUser2Async(thisYear, data.Type.Id, data.KeycloakUserId);
|
||||
var leaveData = await _leaveBeginningRepository.GetByYearAndTypeIdForUser2Async(fiscalYear, data.Type.Id, data.KeycloakUserId);
|
||||
//var leaveData = await _leaveBeginningRepository.GetByYearAndTypeIdForUser2Async(thisYear, rawData.Type.Id, rawData.KeycloakUserId);
|
||||
//var leaveSummary = leaveData == null ? 0.0 : leaveData.LeaveDaysUsed;
|
||||
|
||||
//var sumLeave = await _leaveRequestRepository.GetSumApproveLeaveTotalByTypeAndRangeForUser(data.KeycloakUserId, data.Type.Id, startFiscalYear, endFiscalYear);
|
||||
|
||||
var sendLeaveDate = data.DateSendLeave ?? data.CreatedAt;
|
||||
|
||||
var sumLeave = await _leaveRequestRepository.GetSumApproveLeaveTotalByTypeAndRangeForUser(data.KeycloakUserId, data.Type.Id, startFiscalYear, endFiscalYear);
|
||||
var sumLeave = await _leaveRequestRepository.GetSumApproveLeaveTotalByTypeAndRangeForUserBefore(data.KeycloakUserId, data.Type.Id, fiscalStart, fiscalEnd, sendLeaveDate);
|
||||
if (leaveData != null)
|
||||
{
|
||||
sumLeave += leaveData.BeginningLeaveDays;
|
||||
}
|
||||
|
||||
//var sumLeave = leaveData == null ? 0.0 : leaveData.LeaveDaysUsed;
|
||||
var leaveLimit = leaveData == null ? 0.0 : leaveData.LeaveDays;
|
||||
|
|
@ -341,7 +370,7 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
var Oc = profile.isCommission == false
|
||||
? profile.Oc.ToThaiNumber()
|
||||
: profile.Oc.Replace("สำนักงานคณะกรรมการข้าราชการกรุงเทพมหานคร", "สำนักงาน ก.ก.").ToThaiNumber();
|
||||
var approveResult = await GetApproverData(data.Approvers, profile.isCommission);
|
||||
var approveResult = await GetApproverData(data.Approvers);
|
||||
return new
|
||||
{
|
||||
template = "leave11",
|
||||
|
|
@ -349,7 +378,7 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
data = new
|
||||
{
|
||||
leaveWrote = data.LeaveWrote.ToThaiNumber() ?? "",
|
||||
dateSendLeave = data.CreatedAt.Date.ToThaiShortDate().ToThaiNumber(),
|
||||
dateSendLeave = data.DateSendLeave != null ? data.DateSendLeave.Value.Date.ToThaiShortDate().ToThaiNumber() : data.CreatedAt.Date.ToThaiShortDate().ToThaiNumber(),
|
||||
leaveTypeName = data.Type.Name,
|
||||
leaveSubTypeName = data.LeaveSubTypeName != null ? data.LeaveSubTypeName.ToThaiNumber() : "",
|
||||
dear = data.CommanderPosition == null ? data.Dear : data.CommanderPosition.ToThaiNumber(),
|
||||
|
|
@ -434,7 +463,7 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
var Oc = profile.isCommission == false
|
||||
? profile.Oc.ToThaiNumber()
|
||||
: profile.Oc.Replace("สำนักงานคณะกรรมการข้าราชการกรุงเทพมหานคร", "สำนักงาน ก.ก.").ToThaiNumber();
|
||||
var approveResult = await GetApproverData(data.Approvers, profile.isCommission);
|
||||
var approveResult = await GetApproverData(data.Approvers);
|
||||
if (isHajj == true)
|
||||
{
|
||||
return new
|
||||
|
|
@ -444,7 +473,7 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
data = new
|
||||
{
|
||||
leaveWrote = data.LeaveWrote.ToThaiNumber() ?? "",
|
||||
dateSendLeave = data.CreatedAt.Date.ToThaiShortDate().ToThaiNumber(),
|
||||
dateSendLeave = data.DateSendLeave != null ? data.DateSendLeave.Value.Date.ToThaiShortDate().ToThaiNumber() : data.CreatedAt.Date.ToThaiShortDate().ToThaiNumber(),
|
||||
leaveTypeName = data.Type.Name,
|
||||
leaveSubTypeName = data.LeaveSubTypeName != null ? data.LeaveSubTypeName.ToThaiNumber() : "",
|
||||
dear = data.CommanderPosition == null ? data.Dear : data.CommanderPosition.ToThaiNumber(),
|
||||
|
|
@ -498,7 +527,7 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
data = new
|
||||
{
|
||||
leaveWrote = data.LeaveWrote.ToThaiNumber() ?? "",
|
||||
dateSendLeave = data.CreatedAt.Date.ToThaiShortDate().ToThaiNumber(),
|
||||
dateSendLeave = data.DateSendLeave != null ? data.DateSendLeave.Value.Date.ToThaiShortDate().ToThaiNumber() : data.CreatedAt.Date.ToThaiShortDate().ToThaiNumber(),
|
||||
leaveTypeName = data.Type.Name,
|
||||
leaveSubTypeName = data.LeaveSubTypeName != null ? data.LeaveSubTypeName.ToThaiNumber() : "",
|
||||
dear = data.CommanderPosition == null ? data.Dear : data.CommanderPosition.ToThaiNumber(),
|
||||
|
|
@ -577,7 +606,7 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
var Oc = profile.isCommission == false
|
||||
? profile.Oc.ToThaiNumber()
|
||||
: profile.Oc.Replace("สำนักงานคณะกรรมการข้าราชการกรุงเทพมหานคร", "สำนักงาน ก.ก.").ToThaiNumber();
|
||||
var approveResult = await GetApproverData(data.Approvers, profile.isCommission);
|
||||
var approveResult = await GetApproverData(data.Approvers);
|
||||
return new
|
||||
{
|
||||
template = "leave14",
|
||||
|
|
@ -585,7 +614,7 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
data = new
|
||||
{
|
||||
leaveWrote = data.LeaveWrote.ToThaiNumber() ?? "",
|
||||
dateSendLeave = data.CreatedAt.Date.ToThaiShortDate().ToThaiNumber(),
|
||||
dateSendLeave = data.DateSendLeave != null ? data.DateSendLeave.Value.Date.ToThaiShortDate().ToThaiNumber() : data.CreatedAt.Date.ToThaiShortDate().ToThaiNumber(),
|
||||
leaveTypeName = data.Type.Name,
|
||||
leaveSubTypeName = data.LeaveSubTypeName != null ? data.LeaveSubTypeName.ToThaiNumber() : "",
|
||||
dear = data.CommanderPosition == null ? data.Dear : data.CommanderPosition.ToThaiNumber(),
|
||||
|
|
@ -658,7 +687,7 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
var Oc = profile.isCommission == false
|
||||
? profile.Oc.ToThaiNumber()
|
||||
: profile.Oc.Replace("สำนักงานคณะกรรมการข้าราชการกรุงเทพมหานคร", "สำนักงาน ก.ก.").ToThaiNumber();
|
||||
var approveResult = await GetApproverData(data.Approvers, profile.isCommission);
|
||||
var approveResult = await GetApproverData(data.Approvers);
|
||||
return new
|
||||
{
|
||||
template = "leave15",
|
||||
|
|
@ -666,7 +695,7 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
data = new
|
||||
{
|
||||
leaveWrote = data.LeaveWrote.ToThaiNumber() ?? "",
|
||||
dateSendLeave = data.CreatedAt.Date.ToThaiShortDate().ToThaiNumber(),
|
||||
dateSendLeave = data.DateSendLeave != null ? data.DateSendLeave.Value.Date.ToThaiShortDate().ToThaiNumber() : data.CreatedAt.Date.ToThaiShortDate().ToThaiNumber(),
|
||||
leaveTypeName = data.Type.Name,
|
||||
leaveSubTypeName = data.LeaveSubTypeName != null ? data.LeaveSubTypeName.ToThaiNumber() : "",
|
||||
dear = data.CommanderPosition == null ? data.Dear : data.CommanderPosition.ToThaiNumber(),
|
||||
|
|
@ -761,7 +790,7 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
var Oc = profile.isCommission == false
|
||||
? profile.Oc.ToThaiNumber()
|
||||
: profile.Oc.Replace("สำนักงานคณะกรรมการข้าราชการกรุงเทพมหานคร", "สำนักงาน ก.ก.").ToThaiNumber();
|
||||
var approveResult = await GetApproverData(data.Approvers, profile.isCommission);
|
||||
var approveResult = await GetApproverData(data.Approvers);
|
||||
return new
|
||||
{
|
||||
template = "leave16",
|
||||
|
|
@ -769,7 +798,7 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
data = new
|
||||
{
|
||||
leaveWrote = data.LeaveWrote.ToThaiNumber() ?? "",
|
||||
dateSendLeave = data.CreatedAt.Date.ToThaiShortDate().ToThaiNumber(),
|
||||
dateSendLeave = data.DateSendLeave != null ? data.DateSendLeave.Value.Date.ToThaiShortDate().ToThaiNumber() : data.CreatedAt.Date.ToThaiShortDate().ToThaiNumber(),
|
||||
leaveTypeName = data.Type.Name,
|
||||
leaveSubTypeName = data.LeaveSubTypeName != null ? data.LeaveSubTypeName.ToThaiNumber() : "",
|
||||
dear = data.CommanderPosition == null ? data.Dear : data.CommanderPosition.ToThaiNumber(),
|
||||
|
|
@ -880,7 +909,7 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
var Oc = profile.isCommission == false
|
||||
? profile.Oc.ToThaiNumber()
|
||||
: profile.Oc.Replace("สำนักงานคณะกรรมการข้าราชการกรุงเทพมหานคร", "สำนักงาน ก.ก.").ToThaiNumber();
|
||||
var approveResult = await GetApproverData(data.Approvers, profile.isCommission);
|
||||
var approveResult = await GetApproverData(data.Approvers);
|
||||
return new
|
||||
{
|
||||
template = "leave17",
|
||||
|
|
@ -888,7 +917,7 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
data = new
|
||||
{
|
||||
leaveWrote = data.LeaveWrote.ToThaiNumber() ?? "",
|
||||
dateSendLeave = data.CreatedAt.Date.ToThaiShortDate().ToThaiNumber(),
|
||||
dateSendLeave = data.DateSendLeave != null ? data.DateSendLeave.Value.Date.ToThaiShortDate().ToThaiNumber() : data.CreatedAt.Date.ToThaiShortDate().ToThaiNumber(),
|
||||
leaveTypeName = data.Type.Name,
|
||||
leaveSubTypeName = data.LeaveSubTypeName != null ? data.LeaveSubTypeName.ToThaiNumber() : "",
|
||||
dear = data.CommanderPosition == null ? data.Dear : data.CommanderPosition.ToThaiNumber(),
|
||||
|
|
@ -976,7 +1005,7 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
var Oc = profile.isCommission == false
|
||||
? profile.Oc.ToThaiNumber()
|
||||
: profile.Oc.Replace("สำนักงานคณะกรรมการข้าราชการกรุงเทพมหานคร", "สำนักงาน ก.ก.").ToThaiNumber();
|
||||
var approveResult = await GetApproverData(data.Approvers, profile.isCommission);
|
||||
var approveResult = await GetApproverData(data.Approvers);
|
||||
return new
|
||||
{
|
||||
template = "leave18",
|
||||
|
|
@ -984,7 +1013,7 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
data = new
|
||||
{
|
||||
leaveWrote = data.LeaveWrote.ToThaiNumber() ?? "",
|
||||
dateSendLeave = data.CreatedAt.Date.ToThaiShortDate().ToThaiNumber(),
|
||||
dateSendLeave = data.DateSendLeave != null ? data.DateSendLeave.Value.Date.ToThaiShortDate().ToThaiNumber() : data.CreatedAt.Date.ToThaiShortDate().ToThaiNumber(),
|
||||
leaveTypeName = data.Type.Name,
|
||||
leaveSubTypeName = data.LeaveSubTypeName != null ? data.LeaveSubTypeName.ToThaiNumber() : "",
|
||||
dear = data.CommanderPosition == null ? data.Dear : data.CommanderPosition.ToThaiNumber(),
|
||||
|
|
@ -1202,7 +1231,7 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
var Oc = profile.isCommission == false
|
||||
? profile.Oc.ToThaiNumber()
|
||||
: profile.Oc.Replace("สำนักงานคณะกรรมการข้าราชการกรุงเทพมหานคร", "สำนักงาน ก.ก.").ToThaiNumber();
|
||||
var approveResult = await GetApproverData(data.Approvers, profile.isCommission);
|
||||
var approveResult = await GetApproverData(data.Approvers);
|
||||
var result = new
|
||||
{
|
||||
template = "แบบใบขอยกเลิกวันลา",
|
||||
|
|
@ -1210,7 +1239,7 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
data = new
|
||||
{
|
||||
leaveWrote = data.CancelLeaveWrote!.ToThaiNumber() ?? "",
|
||||
dateSendLeave = data.CreatedAt.Date.ToThaiShortDate().ToThaiNumber(),
|
||||
dateSendLeave = data.DateSendLeave != null ? data.DateSendLeave.Value.Date.ToThaiShortDate().ToThaiNumber() : data.CreatedAt.Date.ToThaiShortDate().ToThaiNumber(),
|
||||
leaveTypeName = data.Type.Name,
|
||||
fullname = fullName,
|
||||
position = string.IsNullOrEmpty(profile.Position) ? "-" : profile.Position,
|
||||
|
|
@ -1324,7 +1353,7 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
? profileAdmin?.RootDnaId
|
||||
: "";
|
||||
}
|
||||
else if (role == "ROOT" || role == "PARENT")
|
||||
else if (role == "ROOT" /*|| role == "PARENT"*/)
|
||||
{
|
||||
nodeId = profileAdmin?.RootDnaId;
|
||||
}
|
||||
|
|
@ -1335,7 +1364,7 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
}
|
||||
else
|
||||
{
|
||||
profile = await _userProfileRepository.GetEmployeeByAdminRole(AccessToken, profileAdmin?.Node, nodeId, role, req.revisionId, req.node, req.nodeId, req.StartDate.Date, req.EndDate.Date);
|
||||
profile = await _userProfileRepository.GetEmployeeByAdminRolev2(AccessToken, profileAdmin?.Node, nodeId, role, req.revisionId, req.node, req.nodeId, req.StartDate.Date, req.EndDate.Date);
|
||||
}
|
||||
// get leave day
|
||||
var leaveDays = await _leaveRequestRepository.GetSumApproveLeaveByTypeAndRange(req.StartDate, req.EndDate);
|
||||
|
|
@ -1360,6 +1389,7 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
FirstName = x.FirstName ?? "",
|
||||
LastName = x.LastName ?? "",
|
||||
DateStart = x.DateStart ?? x.DateAppoint,
|
||||
DateAppoint = x.DateAppoint,
|
||||
}).Distinct().ToList();
|
||||
|
||||
var beginningData = await _leaveBeginningRepository.GetAllByYearAsync(year);
|
||||
|
|
@ -1388,57 +1418,57 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
var sickDaySum = beginningData.FirstOrDefault(x => x.ProfileId == p.Id && x.LeaveType.Code == "LV-001");
|
||||
var sickDay = leaveDays.FirstOrDefault(x => x.KeycloakUserId == keycloakUserId && x.LeaveTypeCode == "LV-001");
|
||||
var sickDayCount = sickDaySum != null ? sickDaySum.LeaveDaysUsed : 0;
|
||||
var sickCount = sickDay != null ? sickDay.CountLeaveDay : 0;
|
||||
var sickCount = sickDaySum != null ? sickDaySum.LeaveCount : 0;
|
||||
|
||||
var personalDaySum = beginningData.FirstOrDefault(x => x.ProfileId == p.Id && x.LeaveType.Code == "LV-002");
|
||||
var personalDay = leaveDays.FirstOrDefault(x => x.KeycloakUserId == keycloakUserId && x.LeaveTypeCode == "LV-002");
|
||||
var personalDayCount = personalDaySum != null ? personalDaySum.LeaveDaysUsed : 0;
|
||||
var personalCount = personalDay != null ? personalDay.CountLeaveDay : 0;
|
||||
var personalCount = personalDaySum != null ? personalDaySum.LeaveCount : 0;
|
||||
|
||||
var maternityDaySum = beginningData.FirstOrDefault(x => x.ProfileId == p.Id && x.LeaveType.Code == "LV-003");
|
||||
var maternityDay = leaveDays.FirstOrDefault(x => x.KeycloakUserId == keycloakUserId && x.LeaveTypeCode == "LV-003");
|
||||
var maternityDayCount = maternityDaySum != null ? maternityDaySum.LeaveDaysUsed : 0;
|
||||
var maternityCount = maternityDay != null ? maternityDay.CountLeaveDay : 0;
|
||||
var maternityCount = maternityDaySum != null ? maternityDaySum.LeaveCount : 0;
|
||||
|
||||
var wifeDaySum = beginningData.FirstOrDefault(x => x.ProfileId == p.Id && x.LeaveType.Code == "LV-004");
|
||||
var wifeDay = leaveDays.FirstOrDefault(x => x.KeycloakUserId == keycloakUserId && x.LeaveTypeCode == "LV-004");
|
||||
var wifeDayCount = wifeDaySum != null ? wifeDaySum.LeaveDaysUsed : 0;
|
||||
var wifeCount = wifeDay != null ? wifeDay.CountLeaveDay : 0;
|
||||
var wifeCount = wifeDaySum != null ? wifeDaySum.LeaveCount : 0;
|
||||
|
||||
var restDaySum = beginningData.FirstOrDefault(x => x.ProfileId == p.Id && x.LeaveType.Code == "LV-005");
|
||||
var restDay = leaveDays.FirstOrDefault(x => x.KeycloakUserId == keycloakUserId && x.LeaveTypeCode == "LV-005");
|
||||
var restDayCount = restDaySum != null ? restDaySum.LeaveDaysUsed : 0;
|
||||
var restCount = restDay != null ? restDay.CountLeaveDay : 0;
|
||||
var restCount = restDaySum != null ? restDaySum.LeaveCount : 0;
|
||||
|
||||
var ordainDaySum = beginningData.FirstOrDefault(x => x.ProfileId == p.Id && x.LeaveType.Code == "LV-006");
|
||||
var ordainDay = leaveDays.FirstOrDefault(x => x.KeycloakUserId == keycloakUserId && x.LeaveTypeCode == "LV-006");
|
||||
var ordainDayCount = ordainDaySum != null ? ordainDaySum.LeaveDaysUsed : 0;
|
||||
var ordainCount = ordainDay != null ? ordainDay.CountLeaveDay : 0;
|
||||
var ordainCount = ordainDaySum != null ? ordainDaySum.LeaveCount : 0;
|
||||
|
||||
var absentDaySum = beginningData.FirstOrDefault(x => x.ProfileId == p.Id && x.LeaveType.Code == "LV-007");
|
||||
var absentDay = leaveDays.FirstOrDefault(x => x.KeycloakUserId == keycloakUserId && x.LeaveTypeCode == "LV-007");
|
||||
var absentDayCount = absentDaySum != null ? absentDaySum.LeaveDaysUsed : 0;
|
||||
var absentCount = absentDay != null ? absentDay.CountLeaveDay : 0;
|
||||
var absentCount = absentDaySum != null ? absentDaySum.LeaveCount : 0;
|
||||
|
||||
var studyDaySum = beginningData.FirstOrDefault(x => x.ProfileId == p.Id && x.LeaveType.Code == "LV-008");
|
||||
var studyDay = leaveDays.FirstOrDefault(x => x.KeycloakUserId == keycloakUserId && x.LeaveTypeCode == "LV-008");
|
||||
var studyDayCount = studyDaySum != null ? studyDaySum.LeaveDaysUsed : 0;
|
||||
var studyCount = studyDay != null ? studyDay.CountLeaveDay : 0;
|
||||
var studyCount = studyDaySum != null ? studyDaySum.LeaveCount : 0;
|
||||
|
||||
var agencyDaySum = beginningData.FirstOrDefault(x => x.ProfileId == p.Id && x.LeaveType.Code == "LV-009");
|
||||
var agencyDay = leaveDays.FirstOrDefault(x => x.KeycloakUserId == keycloakUserId && x.LeaveTypeCode == "LV-009");
|
||||
var agencyDayCount = agencyDaySum != null ? agencyDaySum.LeaveDaysUsed : 0;
|
||||
var agencyCount = agencyDay != null ? agencyDay.CountLeaveDay : 0;
|
||||
var agencyCount = agencyDaySum != null ? agencyDaySum.LeaveCount : 0;
|
||||
|
||||
var coupleDaySum = beginningData.FirstOrDefault(x => x.ProfileId == p.Id && x.LeaveType.Code == "LV-010");
|
||||
var coupleDay = leaveDays.FirstOrDefault(x => x.KeycloakUserId == keycloakUserId && x.LeaveTypeCode == "LV-010");
|
||||
var coupleDayCount = coupleDaySum != null ? coupleDaySum.LeaveDaysUsed : 0;
|
||||
var coupleCount = coupleDay != null ? coupleDay.CountLeaveDay : 0;
|
||||
var coupleCount = coupleDaySum != null ? coupleDaySum.LeaveCount : 0;
|
||||
|
||||
var therapyDaySum = beginningData.FirstOrDefault(x => x.ProfileId == p.Id && x.LeaveType.Code == "LV-011");
|
||||
var therapyDay = leaveDays.FirstOrDefault(x => x.KeycloakUserId == keycloakUserId && x.LeaveTypeCode == "LV-011");
|
||||
var therapyDayCount = therapyDaySum != null ? therapyDaySum.LeaveDaysUsed : 0;
|
||||
var therapyCount = therapyDay != null ? therapyDay.CountLeaveDay : 0;
|
||||
var therapyCount = therapyDaySum != null ? therapyDaySum.LeaveCount : 0;
|
||||
|
||||
var timeStamps = await _processUserTimeStampRepository.GetTimeStampHistoryByRangeForUserAsync(p.Keycloak ?? Guid.Empty, req.StartDate, req.EndDate);
|
||||
|
||||
|
|
@ -1515,17 +1545,21 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
coupleCount = coupleCount,
|
||||
therapyCount = therapyCount,
|
||||
|
||||
leaveTotal = sickCount +
|
||||
maternityCount +
|
||||
wifeCount +
|
||||
personalCount +
|
||||
restCount +
|
||||
ordainCount +
|
||||
absentCount +
|
||||
studyCount +
|
||||
agencyCount +
|
||||
coupleCount +
|
||||
therapyCount
|
||||
// ระบบนับจำนวนครั้ง วันลาพักผ่อนด้วย ซึ่งตามระเบียบไม่ให้นับจำนวนครั้งวันลาพักผ่อนครับ จำนวนครั้งนับเฉพาะ ป่วย กับ กิจ
|
||||
leaveTotal = sickCount +
|
||||
personalCount
|
||||
|
||||
// leaveTotal = sickCount +
|
||||
// maternityCount +
|
||||
// wifeCount +
|
||||
// personalCount +
|
||||
// restCount +
|
||||
// ordainCount +
|
||||
// absentCount +
|
||||
// studyCount +
|
||||
// agencyCount +
|
||||
// coupleCount +
|
||||
// therapyCount
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -1653,18 +1687,22 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
agencyCount = agencyCount,
|
||||
coupleCount = coupleCount,
|
||||
therapyCount = therapyCount,
|
||||
|
||||
// ระบบนับจำนวนครั้ง วันลาพักผ่อนด้วย ซึ่งตามระเบียบไม่ให้นับจำนวนครั้งวันลาพักผ่อนครับ จำนวนครั้งนับเฉพาะ ป่วย กับ กิจ
|
||||
leaveTotal = sickCount +
|
||||
personalCount
|
||||
|
||||
leaveTotal = sickCount +
|
||||
maternityCount +
|
||||
wifeCount +
|
||||
personalCount +
|
||||
restCount +
|
||||
ordainCount +
|
||||
absentCount +
|
||||
studyCount +
|
||||
agencyCount +
|
||||
coupleCount +
|
||||
therapyCount
|
||||
// leaveTotal = sickCount +
|
||||
// maternityCount +
|
||||
// wifeCount +
|
||||
// personalCount +
|
||||
// restCount +
|
||||
// ordainCount +
|
||||
// absentCount +
|
||||
// studyCount +
|
||||
// agencyCount +
|
||||
// coupleCount +
|
||||
// therapyCount
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -1953,7 +1991,7 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
? profileAdmin?.RootDnaId
|
||||
: "";
|
||||
}
|
||||
else if (role == "ROOT" || role == "PARENT")
|
||||
else if (role == "ROOT" /*|| role == "PARENT"*/)
|
||||
{
|
||||
nodeId = profileAdmin?.RootDnaId;
|
||||
}
|
||||
|
|
@ -2074,20 +2112,68 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
case "LV-005":
|
||||
remarkStr += leaveReq.Type.Name;
|
||||
var leaveRange = leaveReq.LeaveRange == null ? "" : leaveReq.LeaveRange.ToUpper();
|
||||
if (leaveRange == "MORNING")
|
||||
remarkStr += "ครึ่งวันเช้า";
|
||||
else if (leaveRange == "AFTERNOON")
|
||||
remarkStr += "ครึ่งวันบ่าย";
|
||||
|
||||
|
||||
var leaveRangeEnd = leaveReq.LeaveRangeEnd == null ? "" : leaveReq.LeaveRangeEnd.ToUpper();
|
||||
if (leaveRange != leaveRangeEnd)
|
||||
if(leaveReq.LeaveStartDate.Date == leaveReq.LeaveEndDate.Date)
|
||||
{
|
||||
if (leaveRangeEnd == "MORNING")
|
||||
remarkStr += " - ครึ่งวันเช้า";
|
||||
else if (leaveRangeEnd == "AFTERNOON")
|
||||
remarkStr += " - ครึ่งวันบ่าย";
|
||||
if (leaveRange == "MORNING")
|
||||
remarkStr += "ครึ่งวันเช้า";
|
||||
else if (leaveRange == "AFTERNOON")
|
||||
remarkStr += "ครึ่งวันบ่าย";
|
||||
|
||||
|
||||
// var leaveRangeEnd = leaveReq.LeaveRangeEnd == null ? "" : leaveReq.LeaveRangeEnd.ToUpper();
|
||||
// if (leaveRangeEnd == "MORNING")
|
||||
// remarkStr += "ครึ่งวันเช้า";
|
||||
// else if (leaveRangeEnd == "AFTERNOON")
|
||||
// remarkStr += "ครึ่งวันบ่าย";
|
||||
|
||||
var leaveRangeEnd = leaveReq.LeaveRangeEnd == null ? "" : leaveReq.LeaveRangeEnd.ToUpper();
|
||||
if (leaveRange != leaveRangeEnd)
|
||||
{
|
||||
if (leaveRangeEnd == "MORNING")
|
||||
remarkStr += " - ครึ่งวันเช้า";
|
||||
else if (leaveRangeEnd == "AFTERNOON")
|
||||
remarkStr += " - ครึ่งวันบ่าย";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(dd.date == leaveReq.LeaveStartDate.Date)
|
||||
{
|
||||
if (leaveRange == "MORNING")
|
||||
remarkStr += "ครึ่งวันเช้า";
|
||||
else if (leaveRange == "AFTERNOON")
|
||||
remarkStr += "ครึ่งวันบ่าย";
|
||||
}
|
||||
else if(dd.date == leaveReq.LeaveEndDate.Date)
|
||||
{
|
||||
var leaveRangeEnd = leaveReq.LeaveRangeEnd == null ? "" : leaveReq.LeaveRangeEnd.ToUpper();
|
||||
if (leaveRangeEnd == "MORNING")
|
||||
remarkStr += "ครึ่งวันเช้า";
|
||||
else if (leaveRangeEnd == "AFTERNOON")
|
||||
remarkStr += "ครึ่งวันบ่าย";
|
||||
}
|
||||
else
|
||||
{
|
||||
remarkStr += "เต็มวัน";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// if (leaveRange == "MORNING")
|
||||
// remarkStr += "ครึ่งวันเช้า";
|
||||
// else if (leaveRange == "AFTERNOON")
|
||||
// remarkStr += "ครึ่งวันบ่าย";
|
||||
|
||||
|
||||
// var leaveRangeEnd = leaveReq.LeaveRangeEnd == null ? "" : leaveReq.LeaveRangeEnd.ToUpper();
|
||||
// if (leaveRange != leaveRangeEnd)
|
||||
// {
|
||||
// if (leaveRangeEnd == "MORNING")
|
||||
// remarkStr += " - ครึ่งวันเช้า";
|
||||
// else if (leaveRangeEnd == "AFTERNOON")
|
||||
// remarkStr += " - ครึ่งวันบ่าย";
|
||||
// }
|
||||
break;
|
||||
default:
|
||||
remarkStr += leaveReq.Type.Name;
|
||||
|
|
@ -2295,7 +2381,7 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
? profileAdmin?.RootDnaId
|
||||
: "";
|
||||
}
|
||||
else if (role == "ROOT" || role == "PARENT")
|
||||
else if (role == "ROOT" /*|| role == "PARENT"*/)
|
||||
{
|
||||
nodeId = profileAdmin?.RootDnaId;
|
||||
}
|
||||
|
|
@ -2306,7 +2392,7 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
}
|
||||
else
|
||||
{
|
||||
profile = await _userProfileRepository.GetEmployeeByAdminRole(AccessToken, profileAdmin?.Node, nodeId, role, req.revisionId, req.node, req.nodeId, req.StartDate.Date, req.EndDate.Date);
|
||||
profile = await _userProfileRepository.GetEmployeeByAdminRolev2(AccessToken, profileAdmin?.Node, nodeId, role, req.revisionId, req.node, req.nodeId, req.StartDate.Date, req.EndDate.Date);
|
||||
}
|
||||
// Child กรองตามที่ fe ส่งมาอีกชั้น
|
||||
if ((role == "ROOT" || role == "OWNER" || role == "CHILD" || role == "PARENT" || role == "BROTHER") /*&& req.node > profileAdmin?.Node*/)
|
||||
|
|
@ -2370,6 +2456,15 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
var workTotal = 0;
|
||||
var seminarTotal = 0;
|
||||
|
||||
var wfaTotal = 0; //ปฏิบัติงานนอกสถานที่
|
||||
var outOfficeTotal = 0; //ขออนุญาติิิออกนอกสถานที่
|
||||
var oneStopSrvrTotal = 0; //จุดบริการด่วนมหานคร
|
||||
var otherTotal = 0; //อื่นๆ
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
var defaultRound = await _dutyTimeRepository.GetDefaultAsync();
|
||||
if (defaultRound == null)
|
||||
{
|
||||
|
|
@ -2404,26 +2499,72 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
case "LV-005":
|
||||
remarkStr += leaveReq.Type.Name;
|
||||
var leaveRange = leaveReq.LeaveRange == null ? "" : leaveReq.LeaveRange.ToUpper();
|
||||
if (leaveRange == "MORNING")
|
||||
remarkStr += "ครึ่งวันเช้า";
|
||||
else if (leaveRange == "AFTERNOON")
|
||||
remarkStr += "ครึ่งวันบ่าย";
|
||||
if(leaveReq.LeaveStartDate.Date == leaveReq.LeaveEndDate.Date)
|
||||
{
|
||||
if (leaveRange == "MORNING")
|
||||
remarkStr += "ครึ่งวันเช้า";
|
||||
else if (leaveRange == "AFTERNOON")
|
||||
remarkStr += "ครึ่งวันบ่าย";
|
||||
|
||||
|
||||
// var leaveRangeEnd = leaveReq.LeaveRangeEnd == null ? "" : leaveReq.LeaveRangeEnd.ToUpper();
|
||||
// if (leaveRangeEnd == "MORNING")
|
||||
// var leaveRangeEnd = leaveReq.LeaveRangeEnd == null ? "" : leaveReq.LeaveRangeEnd.ToUpper();
|
||||
// if (leaveRangeEnd == "MORNING")
|
||||
// remarkStr += "ครึ่งวันเช้า";
|
||||
// else if (leaveRangeEnd == "AFTERNOON")
|
||||
// remarkStr += "ครึ่งวันบ่าย";
|
||||
|
||||
var leaveRangeEnd = leaveReq.LeaveRangeEnd == null ? "" : leaveReq.LeaveRangeEnd.ToUpper();
|
||||
if (leaveRange != leaveRangeEnd)
|
||||
{
|
||||
if (leaveRangeEnd == "MORNING")
|
||||
remarkStr += " - ครึ่งวันเช้า";
|
||||
else if (leaveRangeEnd == "AFTERNOON")
|
||||
remarkStr += " - ครึ่งวันบ่าย";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(dd.date == leaveReq.LeaveStartDate.Date)
|
||||
{
|
||||
if (leaveRange == "MORNING")
|
||||
remarkStr += "ครึ่งวันเช้า";
|
||||
else if (leaveRange == "AFTERNOON")
|
||||
remarkStr += "ครึ่งวันบ่าย";
|
||||
}
|
||||
else if(dd.date == leaveReq.LeaveEndDate.Date)
|
||||
{
|
||||
var leaveRangeEnd = leaveReq.LeaveRangeEnd == null ? "" : leaveReq.LeaveRangeEnd.ToUpper();
|
||||
if (leaveRangeEnd == "MORNING")
|
||||
remarkStr += "ครึ่งวันเช้า";
|
||||
else if (leaveRangeEnd == "AFTERNOON")
|
||||
remarkStr += "ครึ่งวันบ่าย";
|
||||
}
|
||||
else
|
||||
{
|
||||
remarkStr += "เต็มวัน";
|
||||
}
|
||||
}
|
||||
|
||||
// if (leaveRange == "MORNING")
|
||||
// remarkStr += "ครึ่งวันเช้า";
|
||||
// else if (leaveRangeEnd == "AFTERNOON")
|
||||
// else if (leaveRange == "AFTERNOON")
|
||||
// remarkStr += "ครึ่งวันบ่าย";
|
||||
|
||||
var leaveRangeEnd = leaveReq.LeaveRangeEnd == null ? "" : leaveReq.LeaveRangeEnd.ToUpper();
|
||||
if (leaveRange != leaveRangeEnd)
|
||||
{
|
||||
if (leaveRangeEnd == "MORNING")
|
||||
remarkStr += " - ครึ่งวันเช้า";
|
||||
else if (leaveRangeEnd == "AFTERNOON")
|
||||
remarkStr += " - ครึ่งวันบ่าย";
|
||||
}
|
||||
|
||||
// // var leaveRangeEnd = leaveReq.LeaveRangeEnd == null ? "" : leaveReq.LeaveRangeEnd.ToUpper();
|
||||
// // if (leaveRangeEnd == "MORNING")
|
||||
// // remarkStr += "ครึ่งวันเช้า";
|
||||
// // else if (leaveRangeEnd == "AFTERNOON")
|
||||
// // remarkStr += "ครึ่งวันบ่าย";
|
||||
|
||||
// var leaveRangeEnd = leaveReq.LeaveRangeEnd == null ? "" : leaveReq.LeaveRangeEnd.ToUpper();
|
||||
// if (leaveRange != leaveRangeEnd)
|
||||
// {
|
||||
// if (leaveRangeEnd == "MORNING")
|
||||
// remarkStr += " - ครึ่งวันเช้า";
|
||||
// else if (leaveRangeEnd == "AFTERNOON")
|
||||
// remarkStr += " - ครึ่งวันบ่าย";
|
||||
// }
|
||||
break;
|
||||
default:
|
||||
remarkStr += leaveReq.Type.Name;
|
||||
|
|
@ -2507,10 +2648,19 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
workTotal += 1;
|
||||
if (!timeStamps.IsLocationCheckIn)
|
||||
{
|
||||
if (timeStamps.CheckInLocationName == "ปฏิบัติงานที่บ้าน")
|
||||
if (timeStamps.CheckInLocationName!.Contains("ปฏิบัติงานที่บ้าน"))
|
||||
wfhTotal += 1;
|
||||
else if (timeStamps.CheckInLocationName == "ไปประชุม / อบรม / สัมมนา")
|
||||
seminarTotal += 1;
|
||||
else if (timeStamps.CheckInLocationName.Contains("ปฏิบัติงานนอกสถานที่"))
|
||||
wfaTotal += 1;
|
||||
else if (timeStamps.CheckInLocationName.Contains("ขออนุญาตออกนอกสถานที่"))
|
||||
outOfficeTotal += 1;
|
||||
else if (timeStamps.CheckInLocationName.Contains("ปฏิบัติงานในจุดบริการด่วนมหานคร"))
|
||||
oneStopSrvrTotal += 1;
|
||||
else otherTotal += 1;
|
||||
// else if (timeStamps.CheckInLocationName.Contains("อื่นๆ"))
|
||||
// otherTotal += 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2661,19 +2811,36 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
worksheet.Cells[lastRow + 2, 8].Value = "อบรม ประชุม สัมมนาฯ";
|
||||
worksheet.Cells[lastRow + 2, 9].Value = seminarTotal;
|
||||
worksheet.Cells[lastRow + 2, 10].Value = "คน";
|
||||
worksheet.Cells[lastRow + 3, 8].Value = "ปฎิบัติงานนอกสถานที่";
|
||||
worksheet.Cells[lastRow + 3, 9].Value = wfaTotal;
|
||||
worksheet.Cells[lastRow + 3, 10].Value = "คน";
|
||||
worksheet.Cells[lastRow + 4, 8].Value = "ขออนุญาตออกนอกสถานที่";
|
||||
worksheet.Cells[lastRow + 4, 9].Value = outOfficeTotal;
|
||||
worksheet.Cells[lastRow + 4, 10].Value = "คน";
|
||||
worksheet.Cells[lastRow + 5, 8].Value = "ปฎิบัติงานในจุดบริการด่วนมหานคร";
|
||||
worksheet.Cells[lastRow + 5, 9].Value = oneStopSrvrTotal;
|
||||
worksheet.Cells[lastRow + 5, 10].Value = "คน";
|
||||
worksheet.Cells[lastRow + 6, 8].Value = "อื่นๆ";
|
||||
worksheet.Cells[lastRow + 6, 9].Value = otherTotal;
|
||||
worksheet.Cells[lastRow + 6, 10].Value = "คน";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
worksheet.Cells[lastRow + 3, 2].Value = "ลาป่วย/ลากิจ";
|
||||
worksheet.Cells[lastRow + 3, 5].Value = sickTotal;
|
||||
worksheet.Cells[lastRow + 3, 6].Value = "คน";
|
||||
worksheet.Cells[lastRow + 4, 2].Value = "มาสาย";
|
||||
worksheet.Cells[lastRow + 4, 5].Value = lateTotal;
|
||||
worksheet.Cells[lastRow + 4, 6].Value = "คน";
|
||||
worksheet.Cells[lastRow + 6, 2].Value = "เรียน";
|
||||
worksheet.Cells[lastRow + 7, 2].Value = "เพื่อโปรดทราบ";
|
||||
worksheet.Cells[lastRow + 7, 9].Value = "ทราบ";
|
||||
worksheet.Cells[lastRow + 7, 9].Style.Font.Bold = true;
|
||||
worksheet.Cells[lastRow + 7, 9].Style.Font.Size = 22;
|
||||
worksheet.Cells[lastRow + 8, 2].Value = "................................";
|
||||
worksheet.Cells[lastRow + 8, 9].Value = "................................";
|
||||
worksheet.Cells[lastRow + 8, 2].Value = "เรียน";
|
||||
worksheet.Cells[lastRow + 9, 2].Value = "เพื่อโปรดทราบ";
|
||||
worksheet.Cells[lastRow + 9, 9].Value = "ทราบ";
|
||||
worksheet.Cells[lastRow + 9, 9].Style.Font.Bold = true;
|
||||
worksheet.Cells[lastRow + 9, 9].Style.Font.Size = 22;
|
||||
worksheet.Cells[lastRow + 10, 2].Value = "................................";
|
||||
worksheet.Cells[lastRow + 10, 9].Value = "................................";
|
||||
worksheet.Cells[worksheet.Dimension.Address].AutoFitColumns();
|
||||
var fileBytes = package.GetAsByteArray();
|
||||
return File(fileBytes, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "TimeStampRecords.xlsx");
|
||||
|
|
@ -2740,29 +2907,45 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
? profileAdmin?.RootDnaId
|
||||
: "";
|
||||
}
|
||||
else if (role == "ROOT" || role == "PARENT")
|
||||
else if (role == "ROOT" /*|| role == "PARENT"*/)
|
||||
{
|
||||
nodeId = profileAdmin?.RootDnaId;
|
||||
}
|
||||
var getDefaultRound = await _dutyTimeRepository.GetDefaultAsync();
|
||||
if (getDefaultRound == null)
|
||||
{
|
||||
return Error("ไม่พบรอบลงเวลา Default", StatusCodes.Status404NotFound);
|
||||
}
|
||||
|
||||
var userTimeStamps = await _processUserTimeStampRepository.GetTimestampByDateLateAsync(type.Trim().ToUpper(), role, nodeId, profileAdmin.Node, req.nodeId, req.node, req.StartDate, req.EndDate);
|
||||
foreach (var p in userTimeStamps)
|
||||
{
|
||||
var fullName = $"{p.Prefix}{p.FirstName} {p.LastName}";
|
||||
|
||||
var effectiveDate = await _userDutyTimeRepository.GetLastEffectRound(p.Id);
|
||||
UserDutyTime? effectiveDate = null;
|
||||
|
||||
effectiveDate = await _userDutyTimeRepository.GetLastEffectRound(p.ProfileId ?? Guid.Empty);
|
||||
//return Error($"{data.Id} PF{data.FirstName} {data.LastName} : {GlobalMessages.DataNotFound}", StatusCodes.Status404NotFound);
|
||||
|
||||
//var userRound = await _dutyTimeRepository.GetByIdAsync(profile.DutyTimeId ?? Guid.Empty);
|
||||
var roundId = effectiveDate != null ? effectiveDate.DutyTimeId : Guid.Empty;
|
||||
var userRound = await _dutyTimeRepository.GetByIdAsync(roundId);
|
||||
|
||||
var duty = userRound;
|
||||
if (duty == null)
|
||||
{
|
||||
duty = await _dutyTimeRepository.GetDefaultAsync();
|
||||
if (duty == null)
|
||||
{
|
||||
return Error("ไม่พบรอบการลงเวลา Default", StatusCodes.Status404NotFound);
|
||||
}
|
||||
}
|
||||
var duty = userRound ?? getDefaultRound;
|
||||
|
||||
// var effectiveDate = await _userDutyTimeRepository.GetLastEffectRound(p.Id);
|
||||
// var roundId = effectiveDate != null ? effectiveDate.DutyTimeId : Guid.Empty;
|
||||
// var userRound = await _dutyTimeRepository.GetByIdAsync(roundId);
|
||||
|
||||
// var duty = userRound;
|
||||
// if (duty == null)
|
||||
// {
|
||||
// duty = await _dutyTimeRepository.GetDefaultAsync();
|
||||
// if (duty == null)
|
||||
// {
|
||||
// return Error("ไม่พบรอบการลงเวลา Default", StatusCodes.Status404NotFound);
|
||||
// }
|
||||
// }
|
||||
DateTime? checkIn = p.CheckIn;
|
||||
DateTime? checkOut = p.CheckOut ?? null;
|
||||
var emp = new
|
||||
|
|
@ -2861,13 +3044,21 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
? profileAdmin?.RootDnaId
|
||||
: "";
|
||||
}
|
||||
else if (role == "ROOT" || role == "PARENT")
|
||||
else if (role == "ROOT" /*|| role == "PARENT"*/)
|
||||
{
|
||||
nodeId = profileAdmin?.RootDnaId;
|
||||
}
|
||||
|
||||
var leaveDays = await _leaveRequestRepository.GetSumApproveLeaveByRootAndRange(req.StartDate, req.EndDate, type, jsonData["result"]?.ToString(), nodeId, profileAdmin?.Node, req.nodeId, req.node);
|
||||
var enddate = req.EndDate.Date == req.StartDate.Date ? "" : $" - {req.EndDate.Date.ToThaiShortDate().ToThaiNumber()}";
|
||||
|
||||
// var thisYear = req.StartDate.Year;
|
||||
// var toDay = req.StartDate.Date;
|
||||
// if (toDay >= new DateTime(toDay.Year, 10, 1) && toDay <= new DateTime(toDay.Year, 12, 31))
|
||||
// thisYear = thisYear + 1;
|
||||
|
||||
// var leaveData = await _leaveBeginningRepository.GetByYearAndTypeIdForUser2Async(thisYear, type, data.KeycloakUserId);
|
||||
|
||||
var result = new
|
||||
{
|
||||
template = "leave2",
|
||||
|
|
@ -2888,7 +3079,7 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
}
|
||||
#endregion
|
||||
|
||||
private async Task<object> GetApproverData(List<LeaveRequestApprover> list, bool? isCommission = false)
|
||||
private async Task<object> GetApproverData(List<LeaveRequestApprover> list)
|
||||
{
|
||||
var _default = new
|
||||
{
|
||||
|
|
@ -2919,10 +3110,10 @@ namespace BMA.EHR.Leave.Service.Controllers
|
|||
: $"{x.PositionName}{x.PositionLevelName}").ToThaiNumber(),
|
||||
posExOrg = !string.IsNullOrEmpty(x.PositionLevelName) &&
|
||||
(x.PositionLevelName.Contains("อำนวยการ") || x.PositionLevelName.Contains("บริหาร"))
|
||||
? new[] { (isCommission == false ? x!.OrganizationName : x!.OrganizationName.Replace("สำนักงานคณะกรรมการข้าราชการกรุงเทพมหานคร", "สำนักงาน ก.ก.")).ToThaiNumber() }
|
||||
? new[] { (x!.OrganizationName.Replace("สำนักงานคณะกรรมการข้าราชการกรุงเทพมหานคร", "สำนักงาน ก.ก.")).ToThaiNumber() }
|
||||
: !string.IsNullOrEmpty(x.PosExecutiveName)
|
||||
? new[] { (x.PosExecutiveName.ToThaiNumber()), (isCommission == false ? x!.OrganizationName : x!.OrganizationName.Replace("สำนักงานคณะกรรมการข้าราชการกรุงเทพมหานคร", "สำนักงาน ก.ก.")).ToThaiNumber() }
|
||||
: new[] { (isCommission == false ? x!.OrganizationName : x!.OrganizationName.Replace("สำนักงานคณะกรรมการข้าราชการกรุงเทพมหานคร", "สำนักงาน ก.ก.")).ToThaiNumber() },
|
||||
? new[] { x.PosExecutiveName.ToThaiNumber(), x!.OrganizationName.Replace("สำนักงานคณะกรรมการข้าราชการกรุงเทพมหานคร", "สำนักงาน ก.ก.").ToThaiNumber() }
|
||||
: new[] { x!.OrganizationName.Replace("สำนักงานคณะกรรมการข้าราชการกรุงเทพมหานคร", "สำนักงาน ก.ก.").ToThaiNumber() },
|
||||
positionSign = !string.IsNullOrEmpty(x.PositionSign)
|
||||
? x.PositionSign.Replace("\r", "").Replace("\n", " ").ToThaiNumber()
|
||||
: "............................................",
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -12,4 +12,21 @@
|
|||
|
||||
public string Reason { get; set; }
|
||||
}
|
||||
|
||||
public class ApproveRequestListItemDto
|
||||
{
|
||||
/// <summary>
|
||||
/// id ของ record รายการคำขอลงเวลาพิเศษนั้นๆ
|
||||
/// </summary>
|
||||
public Guid RecId { get; set; }
|
||||
public string CheckInTime { get; set; }
|
||||
|
||||
public string CheckOutTime { get; set; }
|
||||
|
||||
public string CheckInStatus { get; set; }
|
||||
|
||||
public string CheckOutStatus { get; set; }
|
||||
|
||||
public string Reason { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,4 +12,25 @@ namespace BMA.EHR.Leave.Service.DTOs.ChangeRound
|
|||
|
||||
public string Remark { get; set; }
|
||||
}
|
||||
|
||||
public class CreateChangeRoundMultipleDto
|
||||
{
|
||||
public Guid ProfileId { get; set; }
|
||||
|
||||
public Guid RoundId { get; set; }
|
||||
|
||||
public DateTime EffectiveDate { get; set; }
|
||||
|
||||
public string Remark { get; set; }
|
||||
|
||||
public Guid? RootDnaId { get; set; }
|
||||
public Guid? Child1DnaId { get; set; }
|
||||
public Guid? Child2DnaId { get; set; }
|
||||
public Guid? Child3DnaId { get; set; }
|
||||
public Guid? Child4DnaId { get; set; }
|
||||
|
||||
public string? Prefix { get; set; }
|
||||
public string? FirstName { get; set; }
|
||||
public string? LastName { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,5 +17,9 @@
|
|||
public string? sortBy { get; set; }
|
||||
|
||||
public bool? descending { get; set; }
|
||||
|
||||
public Guid? SelectedNodeId { get; set; }
|
||||
|
||||
public int? SelectedNode { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,5 +17,11 @@
|
|||
public string LeaveTimeAfterNoon { get;set; }
|
||||
|
||||
public DateTime? EffectiveDate { get; set; }
|
||||
|
||||
public string? RootDnaId { get; set; }
|
||||
public string? Child1DnaId { get; set; }
|
||||
public string? Child2DnaId { get; set; }
|
||||
public string? Child3DnaId { get; set; }
|
||||
public string? Child4DnaId { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,10 +14,19 @@ namespace BMA.EHR.Leave.Service.DTOs.LeaveBeginnings
|
|||
[Required, Comment("ปีงบประมาณ")]
|
||||
public int LeaveYear { get; set; } = 0;
|
||||
|
||||
[Required, Comment("จำนวนวันลายกมา")]
|
||||
[Required, Comment("จำนวนวันลาที่ได้รับ")]
|
||||
public double LeaveDays { get; set; } = 0.0;
|
||||
|
||||
[Required, Comment("จำนวนวันลาที่ใช้ไป")]
|
||||
public double LeaveDaysUsed { get; set; } = 0.0;
|
||||
|
||||
[Required, Comment("จำนวนครั้งที่ลาสะสม")]
|
||||
public int LeaveCount { get; set; } = 0;
|
||||
|
||||
[Required, Comment("จำนวนวันลายกมา")]
|
||||
public double BeginningLeaveDays { get; set; } = 0.0;
|
||||
|
||||
[Comment("จำนวนครั้งที่ลายกมา")]
|
||||
public int BeginningLeaveCount { get; set; } = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,47 @@ namespace BMA.EHR.Leave.Service.DTOs.LeaveBeginnings
|
|||
[Required, Comment("จำนวนวันลายกมา")]
|
||||
public double LeaveDays { get; set; } = 0.0;
|
||||
|
||||
[Required, Comment("จำนวนวันลาที่ใช้ไป")]
|
||||
public double LeaveDaysUsed { get; set; } = 0.0;
|
||||
[Comment("จำนวนวันลาที่ใช้ไป")]
|
||||
public double? LeaveDaysUsed { get; set; }
|
||||
|
||||
[Comment("จำนวนครั้งที่ลาสะสม")]
|
||||
public int? LeaveCount { get; set; }
|
||||
|
||||
[Required, Comment("จำนวนวันลายกมาก่อนใช้ระบบ")]
|
||||
public double BeginningLeaveDays { get; set; } = 0.0;
|
||||
|
||||
[Comment("จำนวนครั้งที่ลายกมาก่อนใช้ระบบ")]
|
||||
public int BeginningLeaveCount { get; set; } = 0;
|
||||
}
|
||||
|
||||
|
||||
public class ScheduleEditLeaveBeginningDto
|
||||
{
|
||||
[Required]
|
||||
public Guid ProfileId { get; set; } = Guid.Empty;
|
||||
|
||||
[Required]
|
||||
public Guid LeaveTypeId { get; set; } = Guid.Empty;
|
||||
|
||||
[Required, Comment("ปีงบประมาณ")]
|
||||
public int LeaveYear { get; set; } = 0;
|
||||
|
||||
[Required, Comment("จำนวนวันลายกมา")]
|
||||
public double LeaveDays { get; set; } = 0.0;
|
||||
}
|
||||
|
||||
public class ScheduleUpdateDnaDto
|
||||
{
|
||||
[Required]
|
||||
public Guid ProfileId { get; set; } = Guid.Empty;
|
||||
|
||||
// [Required, Comment("ปีงบประมาณ")]
|
||||
// public int LeaveYear { get; set; } = 0;
|
||||
|
||||
public Guid? RootDnaId { get; set; }
|
||||
public Guid? Child1DnaId { get; set; }
|
||||
public Guid? Child2DnaId { get; set; }
|
||||
public Guid? Child3DnaId { get; set; }
|
||||
public Guid? Child4DnaId { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
23
BMA.EHR.Leave/DTOs/LeaveRequest/CreateLeaveProcessJobDto.cs
Normal file
23
BMA.EHR.Leave/DTOs/LeaveRequest/CreateLeaveProcessJobDto.cs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BMA.EHR.Leave.Service.DTOs.LeaveRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// ข้อมูลสำหรับสร้าง Job ประมวลผลวันลา โดยมีช่วงวันที่เริ่มต้นและสิ้นสุดของการประมวลผลวันลา
|
||||
/// </summary>
|
||||
public class CreateLeaveProcessJobDto
|
||||
{
|
||||
/// <summary>
|
||||
/// วันที่เริ่มต้นของการประมวลผลวันลา
|
||||
/// </summary>
|
||||
public DateTime StartDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// วันที่สิ้นสุดของการประมวลผลวันลา
|
||||
/// </summary>
|
||||
public DateTime EndDate { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -147,6 +147,10 @@ namespace BMA.EHR.Leave.Service.DTOs.LeaveRequest
|
|||
public List<GetLeaveApproverDto> Approvers { get; set; } = new();
|
||||
|
||||
public Guid? KeycloakUserId { get; set; } = Guid.Empty;
|
||||
|
||||
|
||||
public double LeaveDraftSummary { get; set; } = 0;
|
||||
public double LeaveWaitingSummary { get; set; } = 0;
|
||||
}
|
||||
|
||||
public class GetLeaveApproverDto
|
||||
|
|
@ -170,5 +174,8 @@ namespace BMA.EHR.Leave.Service.DTOs.LeaveRequest
|
|||
public string ApproveStatus { get; set; } = string.Empty;
|
||||
|
||||
public string Comment { get; set; } = string.Empty;
|
||||
|
||||
public bool isAct { get; set; } = false;
|
||||
public string keyId { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,5 +51,10 @@
|
|||
public string? CurrentProvince { get; set; }
|
||||
|
||||
public string? CurrentZipCode { get; set; }
|
||||
|
||||
public int GovAge { get; set; } = 0;
|
||||
|
||||
public double LeaveDraftSummary { get; set; } = 0;
|
||||
public double LeaveWaitingSummary { get; set; } = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,5 +37,11 @@ namespace BMA.EHR.Leave.Service.DTOs.LeaveRequest
|
|||
[JsonProperty("organizationName")]
|
||||
public string OrganizationName { get; set; } = string.Empty;
|
||||
|
||||
[JsonProperty("isAct")]
|
||||
public bool isAct { get; set; } = false;
|
||||
|
||||
[JsonProperty("keyId")]
|
||||
public string keyId { get; set; } = string.Empty;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,11 +18,13 @@ using System.Text;
|
|||
using Hangfire;
|
||||
using Hangfire.MySql;
|
||||
using System.Transactions;
|
||||
using BMA.EHR.Application.Repositories.Leaves.LeaveRequests;
|
||||
using BMA.EHR.Leave.Service.Filters;
|
||||
using Hangfire.Common;
|
||||
using BMA.EHR.Application.Repositories.Leaves.TimeAttendants;
|
||||
using BMA.EHR.Leave.Service.Extensions;
|
||||
using BMA.EHR.Leave.Service.Services;
|
||||
using BMA.EHR.Leave.Services;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
// ตั้ง TimeZone เป็น Asia/Bangkok ในโค้ด
|
||||
|
|
@ -95,8 +97,16 @@ builder.Services.AddLeaveApplication();
|
|||
builder.Services.AddPersistence(builder.Configuration);
|
||||
builder.Services.AddLeavePersistence(builder.Configuration);
|
||||
builder.Services.AddTransient<HolidayService>();
|
||||
builder.Services.AddTransient<NotificationService>();
|
||||
|
||||
// Configure HttpClient with increased timeout for long-running operations (e.g., RabbitMQ Management API)
|
||||
builder.Services.AddHttpClient();
|
||||
builder.Services.AddTransient(sp =>
|
||||
{
|
||||
var httpClient = sp.GetRequiredService<IHttpClientFactory>().CreateClient();
|
||||
httpClient.Timeout = TimeSpan.FromMinutes(10); // Set timeout to 10 minutes
|
||||
return httpClient;
|
||||
});
|
||||
|
||||
builder.Services.AddControllers(options =>
|
||||
{
|
||||
|
|
@ -112,7 +122,7 @@ builder.Services.AddHealthChecks();
|
|||
builder.Services.AddRabbitMqConnectionPooling(builder.Configuration);
|
||||
|
||||
// Add Hangfire services.
|
||||
var defaultConnection = builder.Configuration.GetConnectionString("DefaultConnection");
|
||||
var hangfireConnection = builder.Configuration.GetConnectionString("defaultConnection");
|
||||
|
||||
builder.Services.AddHangfire(configuration => configuration
|
||||
.SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
|
||||
|
|
@ -120,19 +130,24 @@ builder.Services.AddHangfire(configuration => configuration
|
|||
.UseRecommendedSerializerSettings()
|
||||
.UseStorage(
|
||||
new MySqlStorage(
|
||||
defaultConnection,
|
||||
hangfireConnection,
|
||||
new MySqlStorageOptions
|
||||
{
|
||||
TransactionIsolationLevel = IsolationLevel.ReadCommitted,
|
||||
QueuePollInterval = TimeSpan.FromSeconds(15),
|
||||
JobExpirationCheckInterval = TimeSpan.FromHours(1),
|
||||
CountersAggregateInterval = TimeSpan.FromMinutes(5),
|
||||
PrepareSchemaIfNecessary = true,
|
||||
DashboardJobListLimit = 50000,
|
||||
TransactionTimeout = TimeSpan.FromMinutes(1),
|
||||
TablesPrefix = "Hangfire"
|
||||
InvisibilityTimeout = TimeSpan.FromHours(3),
|
||||
TablesPrefix = "Hangfire_Leave"
|
||||
})));
|
||||
builder.Services.AddHangfireServer();
|
||||
builder.Services.AddHangfireServer(options =>
|
||||
{
|
||||
options.ServerName = "Leave-Server"; // ← ระบุชื่อ server
|
||||
options.WorkerCount = 5; // ←
|
||||
options.Queues = new[] { "leave","default" }; // ← worker จะรันเฉพาะ queue "leave"
|
||||
});
|
||||
|
||||
|
||||
var app = builder.Build();
|
||||
|
|
@ -180,9 +195,42 @@ app.UseHangfireDashboard("/hangfire", new DashboardOptions()
|
|||
var manager = new RecurringJobManager();
|
||||
if (manager != null)
|
||||
{
|
||||
manager.AddOrUpdate("ปรับปรุงรอบการลงเวลาทำงาน", Job.FromExpression<UserDutyTimeRepository>(x => x.UpdateUserDutyTime()), "0 1 * * *", bangkokTimeZone);
|
||||
manager.AddOrUpdate("ปรับปรุงรอบการลงเวลาทำงาน", Job.FromExpression<UserDutyTimeRepository>(x => x.UpdateUserDutyTime()), "0 1 * * *",
|
||||
new RecurringJobOptions
|
||||
{
|
||||
TimeZone = bangkokTimeZone,
|
||||
QueueName = "leave"
|
||||
});
|
||||
// ทำความสะอาดข้อมูล CheckIn Job Status ที่เก่ากว่า 30 วัน - รันทุกวันเวลา 02:00 น.
|
||||
manager.AddOrUpdate("ทำความสะอาดข้อมูล CheckIn Job Status", Job.FromExpression<CheckInJobStatusRepository>(x => x.CleanupOldJobsAsync(30)), "0 2 * * *", bangkokTimeZone);
|
||||
manager.AddOrUpdate("ทำความสะอาดข้อมูล CheckIn Job Status", Job.FromExpression<CheckInJobStatusRepository>(x => x.CleanupOldJobsAsync(30)), "0 2 * * *",
|
||||
new RecurringJobOptions
|
||||
{
|
||||
TimeZone = bangkokTimeZone,
|
||||
QueueName = "leave"
|
||||
});
|
||||
|
||||
manager.AddOrUpdate("Proceess Beginning สำหรับการลาล่วงหน้า", Job.FromExpression<LeaveBeginningRepository>(x => x.ProcessEarlyLeaveRequestSchedule()), "0 1 1 10 *",
|
||||
new RecurringJobOptions
|
||||
{
|
||||
TimeZone = bangkokTimeZone,
|
||||
QueueName = "leave"
|
||||
});
|
||||
|
||||
|
||||
// ตรวจสอบและ mark งาน CheckIn ที่ค้างเกิน 30 นาทีเป็น FAILED - รันทุก 15 นาที
|
||||
// manager.AddOrUpdate("ตรวจสอบงาน CheckIn ที่ค้างเกินเวลา", Job.FromExpression<CheckInJobStatusRepository>(x => x.MarkStaleJobsAsFailedAsync(30)), "*/15 * * * *",
|
||||
// new RecurringJobOptions
|
||||
// {
|
||||
// TimeZone = bangkokTimeZone,
|
||||
// QueueName = "leave"
|
||||
// });
|
||||
//
|
||||
// manager.AddOrUpdate("ประมวลผลงานที่ค้างอยู่ในสถานะ Pending หรือ Processing", Job.FromExpression<LeaveProcessJobStatusRepository>(x => x.ProcessPendingJobsAsync()), "0 3 * * *",
|
||||
// new RecurringJobOptions
|
||||
// {
|
||||
// TimeZone = bangkokTimeZone,
|
||||
// QueueName = "leave" // ← กำหนด queue
|
||||
// });
|
||||
}
|
||||
|
||||
// apply migrations
|
||||
|
|
|
|||
58
BMA.EHR.Leave/Services/NotificationService.cs
Normal file
58
BMA.EHR.Leave/Services/NotificationService.cs
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
|
||||
namespace BMA.EHR.Leave.Services;
|
||||
|
||||
public class NotificationService
|
||||
{
|
||||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
private readonly ILogger<NotificationService> _logger;
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
private const string NotifyEndpoint = "https://hrmsbkk.case-collection.com/api/v1/org/through-socket/notify-from-token";
|
||||
|
||||
public NotificationService(IHttpClientFactory httpClientFactory, ILogger<NotificationService> logger, IConfiguration configuration)
|
||||
{
|
||||
_httpClientFactory = httpClientFactory;
|
||||
_logger = logger;
|
||||
_configuration = configuration;
|
||||
}
|
||||
|
||||
public async Task SendNotificationAsync(string? token, bool error, string message)
|
||||
{
|
||||
if (string.IsNullOrEmpty(token))
|
||||
{
|
||||
_logger.LogWarning("Cannot send import notification: token is null or empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var client = _httpClientFactory.CreateClient("default");
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
|
||||
var payload = new
|
||||
{
|
||||
error,
|
||||
message
|
||||
};
|
||||
|
||||
var json = JsonConvert.SerializeObject(payload);
|
||||
var content = new StringContent(json, Encoding.UTF8, "application/json");
|
||||
|
||||
var response = await client.PostAsync(NotifyEndpoint, content);
|
||||
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
var responseBody = await response.Content.ReadAsStringAsync();
|
||||
_logger.LogWarning("Import notification failed with status {StatusCode}: {Body}", response.StatusCode, responseBody);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Failed to send import notification: {Message}", ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -19,20 +19,19 @@
|
|||
// "ExamConnection": "server=192.168.1.80;user=root;password=adminVM123;port=3306;database=hrms_exam;Convert Zero Datetime=True;Allow User Variables=true;Pooling=True;",
|
||||
// "LeaveConnection": "server=192.168.1.80;user=root;password=adminVM123;port=3306;database=hrms_leave;Convert Zero Datetime=True;Allow User Variables=true;Pooling=True;"
|
||||
|
||||
"DefaultConnection": "server=192.168.1.63;user=root;password=12345678;port=3306;database=hrms;Convert Zero Datetime=True;Allow User Variables=true;Pooling=True;",
|
||||
"ExamConnection": "server=192.168.1.63;user=root;password=12345678;port=3306;database=hrms_exam;Convert Zero Datetime=True;Allow User Variables=true;Pooling=True;",
|
||||
"LeaveConnection": "server=192.168.1.63;user=root;password=12345678;port=3306;database=hrms_leave;Convert Zero Datetime=True;Allow User Variables=true;Pooling=True;"
|
||||
"DefaultConnection": "Server=192.168.1.63;User ID=root;Password=12345678;Port=3306;Database=hrms;Allow User Variables=True;Convert Zero Datetime=True;Pooling=True;",
|
||||
"ExamConnection": "Server=192.168.1.63;User ID=root;Password=12345678;Port=3306;Database=hrms_exam;Allow User Variables=True;Convert Zero Datetime=True;Pooling=True;",
|
||||
"LeaveConnection": "Server=192.168.1.63;User ID=root;Password=12345678;Port=3306;Database=hrms_leave;Allow User Variables=True;Convert Zero Datetime=True;Pooling=True;"
|
||||
|
||||
// "DefaultConnection": "server=172.27.17.68;user=user;password=cDldaqkwESWvuZ37Gr0n;port=3306;database=hrms;Convert Zero Datetime=True;Allow User Variables=true;Pooling=True;",
|
||||
// "ExamConnection": "server=172.27.17.68;user=user;password=cDldaqkwESWvuZ37Gr0n;port=3306;database=hrms_exam;Convert Zero Datetime=True;Allow User Variables=true;Pooling=True;",
|
||||
// "LeaveConnection": "server=172.27.17.68;user=user;password=cDldaqkwESWvuZ37Gr0n;port=3306;database=hrms_leave;Convert Zero Datetime=True;Allow User Variables=true;Pooling=True;"
|
||||
// "DefaultConnection": "server=127.0.0.1;user=root;password=ey2qVVyyqGYw8CyA7h8X72559r2Ad84K;port=13306;database=hrms;Convert Zero Datetime=True;Allow User Variables=true;Pooling=True;Connection Timeout=180;",
|
||||
// "ExamConnection": "server=127.0.0.1;user=root;password=ey2qVVyyqGYw8CyA7h8X72559r2Ad84K;port=13306;database=hrms_exam;Convert Zero Datetime=True;Allow User Variables=true;Pooling=True;Connection Timeout=180;",
|
||||
// "LeaveConnection": "server=127.0.0.1;user=root;password=ey2qVVyyqGYw8CyA7h8X72559r2Ad84K;port=13306;database=hrms_leave;Convert Zero Datetime=True;Allow User Variables=true;Pooling=True;Connection Timeout=180;"
|
||||
},
|
||||
"Jwt": {
|
||||
//"Key": "HP-FnQMUj9msHMSD3T9HtdEnphAKoCJLEl85CIqROFI",
|
||||
"Key": "j7C9RO_p4nRtuwCH4z9Db_A_6We42tkD_p4lZtDrezc",
|
||||
"Issuer": "https://hrmsbkk-id.case-collection.com/realms/hrms"
|
||||
//"Key": "xY2VR-EFvvNPsMs39u8ooVBWQL6mPwrNJOh3koJFTgU",
|
||||
//"Issuer": "https://hrms-id.bangkok.go.th/realms/hrms"
|
||||
// "Key": "xY2VR-EFvvNPsMs39u8ooVBWQL6mPwrNJOh3koJFTgU",
|
||||
// "Issuer": "https://hrms-id.bangkok.go.th/realms/hrms"
|
||||
},
|
||||
"EPPlus": {
|
||||
"ExcelPackage": {
|
||||
|
|
@ -44,6 +43,10 @@
|
|||
"AccessKey": "iwvzjyjgz0BKtLPmMpPu",
|
||||
"SecretKey": "Yv56vwctYdIspDknRJ46xztcBDzteGF3elZiDcAr",
|
||||
"BucketName": "hrms-fpt"
|
||||
// "Endpoint": "https://hrms-s3.bangkok.go.th/",
|
||||
// "AccessKey": "frappet",
|
||||
// "SecretKey": "FPTadmin2357",
|
||||
// "BucketName": "bma-ehr-fpt"
|
||||
},
|
||||
"Protocol": "HTTPS",
|
||||
"Node": {
|
||||
|
|
@ -55,6 +58,11 @@
|
|||
"Password": "12345678",
|
||||
"Queue": "hrms-checkin-queue-dev",
|
||||
"URL": "http://192.168.1.63:9122/api/queues/%2F/"
|
||||
// "Host": "172.27.17.68",
|
||||
// "User": "admin",
|
||||
// "Password": "admin123456",
|
||||
// "Queue": "hrms-checkin-queue",
|
||||
// "URL": "http://172.27.17.68:9122/api/queues/%2F/"
|
||||
},
|
||||
"Mail": {
|
||||
"Server": "mail.bangkok.go.th",
|
||||
|
|
@ -68,7 +76,10 @@
|
|||
"API": "https://hrmsbkk.case-collection.com/api/v1",
|
||||
"APIV2": "https://hrmsbkk.case-collection.com/api/v2",
|
||||
"VITE_URL_MGT": "https://hrmsbkk-mgt.case-collection.com",
|
||||
//"API": "https://bma-ehr.frappet.synology.me/api/v1",
|
||||
//"API": "https://bma-hrms.bangkok.go.th/api/v1",
|
||||
// "Domain": "https://hrms.bangkok.go.th",
|
||||
// "APIPROBATION": "https://hrms.bangkok.go.th/api/v1/probation",
|
||||
// "API": "https://hrms.bangkok.go.th/api/v1",
|
||||
// "APIV2": "https://hrms.bangkok.go.th/api/v2",
|
||||
// "VITE_URL_MGT": "https://hrms-mgt.bangkok.go.th",
|
||||
"API_KEY": "fKRL16yyEgbyTEJdsMw2h64tGSCmkW685PRtM3CygzX1JOSdptT9UJtpgWwKM8FybRTJups3GTFwj27ZRvlPdIkv3XgCoVJaD5LmR06ozuEPvCCRSdp2WFthg08V5xHc56fTPfZLpr1VmXrhd6dvYhHIqKkQUJR02Rlkss11cLRWEQOssEFVA4xdu2J5DIRO1EM5m7wRRvEwcDB4mYRXD9HH52SMq6iYqUWEWsMwLdbk7QW9yYESUEuzMW5gWrb6vIeWZxJV5bTz1PcWUyR7eO9Fyw1F5DiQYc9JgzTC1mW7cv31fEtTtrfbJYKIb5EbWilqIEUKC6A0UKBDDek35ML0006cqRVm0pvdOH6jeq7VQyYrhdXe59dBEyhYGUIfozoVBvW7Up4QBuOMjyPjSqJPlMBKwaseptfrblxQV1AOOivSBpf1ZcQyOZ8JktRtKUDSuXsmG0lsXwFlI3JCeSHdpVdgZWFYcJPegqfrB6KotR02t9AVkpLs1ZWrixwz"
|
||||
}
|
||||
|
|
|
|||
BIN
BMA.EHR.Leave/wwwroot/blank.jpeg
Normal file
BIN
BMA.EHR.Leave/wwwroot/blank.jpeg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
|
|
@ -184,6 +184,31 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ลบ Notification ทั้งหมดของ user ที่ login (Hard delete)
|
||||
/// </summary>
|
||||
/// <returns>จำนวนรายการที่ถูกลบ</returns>
|
||||
/// <response code="200">เมื่อทำการลบข้อมูลจาก Relational Database สำเร็จ</response>
|
||||
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
|
||||
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
|
||||
[HttpDelete("my-notifications")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
||||
public async Task<ActionResult<ResponseObject>> PermanentDeleteAllMyNotificationsAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
var affectedRows = await _notificationRepository.DeleteAllMyNotificationsAsync();
|
||||
|
||||
return Success(affectedRows);
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
? profileAdmin?.RootDnaId
|
||||
: "";
|
||||
}
|
||||
else if (role == "ROOT" || role == "PARENT")
|
||||
else if (role == "ROOT" /*|| role == "PARENT"*/)
|
||||
{
|
||||
nodeId = profileAdmin?.RootDnaId;
|
||||
}
|
||||
|
|
@ -239,11 +239,11 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
placementAppointments = placementAppointments
|
||||
.Where(x => x.rootDnaId == nodeId).ToList();
|
||||
}
|
||||
else if (role == "PARENT")
|
||||
{
|
||||
placementAppointments = placementAppointments
|
||||
.Where(x => x.rootDnaId == nodeId && x.child1DnaId != null).ToList();
|
||||
}
|
||||
// else if (role == "PARENT")
|
||||
// {
|
||||
// placementAppointments = placementAppointments
|
||||
// .Where(x => x.rootDnaId == nodeId && x.child1DnaId != null).ToList();
|
||||
// }
|
||||
else if (role == "NORMAL")
|
||||
{
|
||||
placementAppointments = placementAppointments.Where(x =>
|
||||
|
|
@ -554,7 +554,7 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
placementAppointment.positionAreaOld = org.result.positionArea;
|
||||
placementAppointment.PositionLevelOld = org.result.posLevelName;
|
||||
placementAppointment.PositionTypeOld = org.result.posTypeName;
|
||||
placementAppointment.PositionNumberOld = org.result.nodeShortName + " " + org.result.posMasterNo;
|
||||
placementAppointment.PositionNumberOld = org.result.posNo;
|
||||
placementAppointment.OrganizationOld = (org.result.child4 == null ? "" : org.result.child4 + "\n") +
|
||||
(org.result.child3 == null ? "" : org.result.child3 + "\n") +
|
||||
(org.result.child2 == null ? "" : org.result.child2 + "\n") +
|
||||
|
|
@ -676,6 +676,7 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
uppdated.posMasterNo = req.posMasterNo;
|
||||
uppdated.position = req.positionName;
|
||||
uppdated.PositionExecutive = req.posExecutiveName;
|
||||
uppdated.posExecutiveId = req.posExecutiveId;
|
||||
uppdated.positionExecutiveField = req.positionExecutiveField;
|
||||
uppdated.positionArea = req.positionArea;
|
||||
uppdated.positionField = req.positionField;
|
||||
|
|
@ -1010,10 +1011,14 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
positionExecutive = p.PositionExecutive,
|
||||
positionExecutiveField = p.positionExecutiveField,
|
||||
positionArea = p.positionArea,
|
||||
positionTypeId = p.posTypeId,
|
||||
positionType = p.posTypeName,
|
||||
positionLevelId = p.posLevelId,
|
||||
positionLevel = p.posLevelName,
|
||||
posmasterId = p.posmasterId,
|
||||
positionId = p.positionId,
|
||||
posExecutiveId = p.posExecutiveId,
|
||||
positionField = p.positionField,
|
||||
commandId = r.commandId,
|
||||
orgRoot = p.root,
|
||||
orgChild1 = p.child1,
|
||||
|
|
@ -1036,24 +1041,39 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
remark = r.remark,
|
||||
}).ToList();
|
||||
|
||||
var baseAPIOrg = _configuration["API"];
|
||||
var apiUrlOrg = $"{baseAPIOrg}/org/command/excexute/salary-current";
|
||||
using (var client = new HttpClient())
|
||||
#region Old: Circular Flow
|
||||
// var baseAPIOrg = _configuration["API"];
|
||||
// var apiUrlOrg = $"{baseAPIOrg}/org/command/excexute/salary-current";
|
||||
// using (var client = new HttpClient())
|
||||
// {
|
||||
// client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
// client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
// var _res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
// {
|
||||
// data = resultData,
|
||||
// });
|
||||
// var _result = await _res.Content.ReadAsStringAsync();
|
||||
// if (_res.IsSuccessStatusCode)
|
||||
// {
|
||||
// data.ForEach(profile => profile.Status = "DONE");
|
||||
// await _context.SaveChangesAsync();
|
||||
// }
|
||||
// }
|
||||
#endregion
|
||||
|
||||
// New: Linear Flow - Task #224 ปรับให้เป็น process ที่ควรบันทึกตามลำดับ
|
||||
var now = DateTime.Now;
|
||||
data.ForEach(profile =>
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
{
|
||||
data = resultData,
|
||||
});
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
if (_res.IsSuccessStatusCode)
|
||||
{
|
||||
data.ForEach(profile => profile.Status = "DONE");
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
return Success();
|
||||
profile.Status = "DONE";
|
||||
profile.LastUpdateFullName = FullName ?? "System Administrator";
|
||||
profile.LastUpdateUserId = UserId ?? "";
|
||||
profile.LastUpdatedAt = now;
|
||||
});
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
// Return resultData for Node to process directly (Linear Flow)
|
||||
return Success(resultData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -1222,10 +1242,14 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
positionExecutive = p.PositionExecutive,
|
||||
positionExecutiveField = p.positionExecutiveField,
|
||||
positionArea = p.positionArea,
|
||||
positionTypeId = p.posTypeId,
|
||||
positionType = p.posTypeName,
|
||||
positionLevelId = p.posLevelId,
|
||||
positionLevel = p.posLevelName,
|
||||
posmasterId = p.posmasterId,
|
||||
positionId = p.positionId,
|
||||
posExecutiveId = p.posExecutiveId,
|
||||
positionField = p.positionField,
|
||||
commandId = r.commandId,
|
||||
orgRoot = p.root,
|
||||
orgChild1 = p.child1,
|
||||
|
|
@ -1248,24 +1272,39 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
remark = r.remark,
|
||||
}).ToList();
|
||||
|
||||
var baseAPIOrg = _configuration["API"];
|
||||
var apiUrlOrg = $"{baseAPIOrg}/org/command/excexute/salary-current";
|
||||
using (var client = new HttpClient())
|
||||
#region Old: Circular Flow
|
||||
// var baseAPIOrg = _configuration["API"];
|
||||
// var apiUrlOrg = $"{baseAPIOrg}/org/command/excexute/salary-current";
|
||||
// using (var client = new HttpClient())
|
||||
// {
|
||||
// client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
// client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
// var _res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
// {
|
||||
// data = resultData,
|
||||
// });
|
||||
// var _result = await _res.Content.ReadAsStringAsync();
|
||||
// if (_res.IsSuccessStatusCode)
|
||||
// {
|
||||
// data.ForEach(profile => profile.Status = "DONE");
|
||||
// await _context.SaveChangesAsync();
|
||||
// }
|
||||
// }
|
||||
#endregion
|
||||
|
||||
// New: Linear Flow - Task #224 ปรับให้เป็น process ที่ควรบันทึกตามลำดับ
|
||||
var now = DateTime.Now;
|
||||
data.ForEach(profile =>
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
{
|
||||
data = resultData,
|
||||
});
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
if (_res.IsSuccessStatusCode)
|
||||
{
|
||||
data.ForEach(profile => profile.Status = "DONE");
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
return Success();
|
||||
profile.Status = "DONE";
|
||||
profile.LastUpdateFullName = FullName ?? "System Administrator";
|
||||
profile.LastUpdateUserId = UserId ?? "";
|
||||
profile.LastUpdatedAt = now;
|
||||
});
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
// Return resultData for Node to process directly (Linear Flow)
|
||||
return Success(resultData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -1448,24 +1487,39 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
remark = r.remark,
|
||||
}).ToList();
|
||||
|
||||
var baseAPIOrg = _configuration["API"];
|
||||
var apiUrlOrg = $"{baseAPIOrg}/org/command/excexute/salary-employee-current";
|
||||
using (var client = new HttpClient())
|
||||
#region Old: Circular Flow
|
||||
// var baseAPIOrg = _configuration["API"];
|
||||
// var apiUrlOrg = $"{baseAPIOrg}/org/command/excexute/salary-employee-current";
|
||||
// using (var client = new HttpClient())
|
||||
// {
|
||||
// client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
// client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
// var _res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
// {
|
||||
// data = resultData,
|
||||
// });
|
||||
// var _result = await _res.Content.ReadAsStringAsync();
|
||||
// if (_res.IsSuccessStatusCode)
|
||||
// {
|
||||
// data.ForEach(profile => profile.Status = "DONE");
|
||||
// await _context.SaveChangesAsync();
|
||||
// }
|
||||
// }
|
||||
#endregion
|
||||
|
||||
// New: Linear Flow - Task #224 ปรับให้เป็น process ที่ควรบันทึกตามลำดับ
|
||||
var now = DateTime.Now;
|
||||
data.ForEach(profile =>
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
{
|
||||
data = resultData,
|
||||
});
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
if (_res.IsSuccessStatusCode)
|
||||
{
|
||||
data.ForEach(profile => profile.Status = "DONE");
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
return Success();
|
||||
profile.Status = "DONE";
|
||||
profile.LastUpdateFullName = FullName ?? "System Administrator";
|
||||
profile.LastUpdateUserId = UserId ?? "";
|
||||
profile.LastUpdatedAt = now;
|
||||
});
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
// Return resultData for Node to process directly (Linear Flow)
|
||||
return Success(resultData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -1653,24 +1707,39 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
remark = r.remark,
|
||||
}).ToList();
|
||||
|
||||
var baseAPIOrg = _configuration["API"];
|
||||
var apiUrlOrg = $"{baseAPIOrg}/org/command/excexute/salary-employee-current";
|
||||
using (var client = new HttpClient())
|
||||
#region Old: Circular Flow
|
||||
// var baseAPIOrg = _configuration["API"];
|
||||
// var apiUrlOrg = $"{baseAPIOrg}/org/command/excexute/salary-employee-current";
|
||||
// using (var client = new HttpClient())
|
||||
// {
|
||||
// client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
// client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
// var _res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
// {
|
||||
// data = resultData,
|
||||
// });
|
||||
// var _result = await _res.Content.ReadAsStringAsync();
|
||||
// if (_res.IsSuccessStatusCode)
|
||||
// {
|
||||
// data.ForEach(profile => profile.Status = "DONE");
|
||||
// await _context.SaveChangesAsync();
|
||||
// }
|
||||
// }
|
||||
#endregion
|
||||
|
||||
// New: Linear Flow - Task #224 ปรับให้เป็น process ที่ควรบันทึกตามลำดับ
|
||||
var now = DateTime.Now;
|
||||
data.ForEach(profile =>
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
{
|
||||
data = resultData,
|
||||
});
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
if (_res.IsSuccessStatusCode)
|
||||
{
|
||||
data.ForEach(profile => profile.Status = "DONE");
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
return Success();
|
||||
profile.Status = "DONE";
|
||||
profile.LastUpdateFullName = FullName ?? "System Administrator";
|
||||
profile.LastUpdateUserId = UserId ?? "";
|
||||
profile.LastUpdatedAt = now;
|
||||
});
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
// Return resultData for Node to process directly (Linear Flow)
|
||||
return Success(resultData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -1851,10 +1920,14 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
positionExecutive = p.PositionExecutive,
|
||||
positionExecutiveField = p.positionExecutiveField,
|
||||
positionArea = p.positionArea,
|
||||
positionTypeId = p.posTypeId,
|
||||
positionType = p.posTypeName,
|
||||
positionLevelId = p.posLevelId,
|
||||
positionLevel = p.posLevelName,
|
||||
posmasterId = p.posmasterId,
|
||||
positionId = p.positionId,
|
||||
posExecutiveId = p.posExecutiveId,
|
||||
positionField = p.positionField,
|
||||
commandId = r.commandId,
|
||||
orgRoot = p.root,
|
||||
orgChild1 = p.child1,
|
||||
|
|
@ -1877,24 +1950,39 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
remark = r.remark,
|
||||
}).ToList();
|
||||
|
||||
var baseAPIOrg = _configuration["API"];
|
||||
var apiUrlOrg = $"{baseAPIOrg}/org/command/excexute/salary-current";
|
||||
using (var client = new HttpClient())
|
||||
#region Old: Circular Flow
|
||||
// var baseAPIOrg = _configuration["API"];
|
||||
// var apiUrlOrg = $"{baseAPIOrg}/org/command/excexute/salary-current";
|
||||
// using (var client = new HttpClient())
|
||||
// {
|
||||
// client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
// client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
// var _res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
// {
|
||||
// data = resultData,
|
||||
// });
|
||||
// var _result = await _res.Content.ReadAsStringAsync();
|
||||
// if (_res.IsSuccessStatusCode)
|
||||
// {
|
||||
// data.ForEach(profile => profile.Status = "DONE");
|
||||
// await _context.SaveChangesAsync();
|
||||
// }
|
||||
// }
|
||||
#endregion
|
||||
|
||||
// New: Linear Flow - Task #224 ปรับให้เป็น process ที่ควรบันทึกตามลำดับ
|
||||
var now = DateTime.Now;
|
||||
data.ForEach(profile =>
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
{
|
||||
data = resultData,
|
||||
});
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
if (_res.IsSuccessStatusCode)
|
||||
{
|
||||
data.ForEach(profile => profile.Status = "DONE");
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
return Success();
|
||||
profile.Status = "DONE";
|
||||
profile.LastUpdateFullName = FullName ?? "System Administrator";
|
||||
profile.LastUpdateUserId = UserId ?? "";
|
||||
profile.LastUpdatedAt = now;
|
||||
});
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
// Return resultData for Node to process directly (Linear Flow)
|
||||
return Success(resultData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -1986,7 +2074,7 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// ออกคำสั่ง C-PM-47
|
||||
/// ออกคำสั่ง C-PM-47 โปรดเกล้าฯ แต่งตั้งให้ดำรงตำแหน่ง
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <response code="200"></response>
|
||||
|
|
@ -2016,6 +2104,8 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
positionLevel = p.posLevelName,
|
||||
posmasterId = p.posmasterId,
|
||||
positionId = p.positionId,
|
||||
posExecutiveId = p.posExecutiveId,
|
||||
positionField = p.positionField,
|
||||
commandId = r.commandId,
|
||||
orgRoot = p.root,
|
||||
orgChild1 = p.child1,
|
||||
|
|
@ -2038,24 +2128,39 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
remark = r.remark,
|
||||
}).ToList();
|
||||
|
||||
var baseAPIOrg = _configuration["API"];
|
||||
var apiUrlOrg = $"{baseAPIOrg}/org/command/excexute/salary-current";
|
||||
using (var client = new HttpClient())
|
||||
#region Old: Circular Flow
|
||||
// var baseAPIOrg = _configuration["API"];
|
||||
// var apiUrlOrg = $"{baseAPIOrg}/org/command/excexute/salary-current";
|
||||
// using (var client = new HttpClient())
|
||||
// {
|
||||
// client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
// client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
// var _res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
// {
|
||||
// data = resultData,
|
||||
// });
|
||||
// var _result = await _res.Content.ReadAsStringAsync();
|
||||
// if (_res.IsSuccessStatusCode)
|
||||
// {
|
||||
// data.ForEach(profile => profile.Status = "DONE");
|
||||
// await _context.SaveChangesAsync();
|
||||
// }
|
||||
// }
|
||||
#endregion
|
||||
|
||||
// New: Linear Flow - Task #224 ปรับให้เป็น process ที่ควรบันทึกตามลำดับ
|
||||
var now = DateTime.Now;
|
||||
data.ForEach(profile =>
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
{
|
||||
data = resultData,
|
||||
});
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
if (_res.IsSuccessStatusCode)
|
||||
{
|
||||
data.ForEach(profile => profile.Status = "DONE");
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
return Success();
|
||||
profile.Status = "DONE";
|
||||
profile.LastUpdateFullName = FullName ?? "System Administrator";
|
||||
profile.LastUpdateUserId = UserId ?? "";
|
||||
profile.LastUpdatedAt = now;
|
||||
});
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
// Return resultData for Node to process directly (Linear Flow)
|
||||
return Success(resultData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
? profileAdmin?.RootDnaId
|
||||
: "";
|
||||
}
|
||||
else if (role == "ROOT" || role == "PARENT")
|
||||
else if (role == "ROOT" /*|| role == "PARENT"*/)
|
||||
{
|
||||
nodeId = profileAdmin?.RootDnaId;
|
||||
}
|
||||
|
|
@ -232,11 +232,11 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
placementAppointments = placementAppointments
|
||||
.Where(x => x.rootDnaId == nodeId).ToList();
|
||||
}
|
||||
else if (role == "PARENT")
|
||||
{
|
||||
placementAppointments = placementAppointments
|
||||
.Where(x => x.rootDnaId == nodeId && x.child1DnaId != null).ToList();
|
||||
}
|
||||
// else if (role == "PARENT")
|
||||
// {
|
||||
// placementAppointments = placementAppointments
|
||||
// .Where(x => x.rootDnaId == nodeId && x.child1DnaId != null).ToList();
|
||||
// }
|
||||
else if (role == "NORMAL")
|
||||
{
|
||||
placementAppointments = placementAppointments.Where(x =>
|
||||
|
|
@ -542,7 +542,7 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
placementAppointment.positionOld = org.result.position;
|
||||
placementAppointment.PositionLevelOld = org.result.posLevelName;
|
||||
placementAppointment.PositionTypeOld = org.result.posTypeName;
|
||||
placementAppointment.PositionNumberOld = org.result.nodeShortName + " " + org.result.posMasterNo;
|
||||
placementAppointment.PositionNumberOld = org.result.posNo;
|
||||
placementAppointment.OrganizationOld = (org.result.child4 == null ? "" : org.result.child4 + "\n") +
|
||||
(org.result.child3 == null ? "" : org.result.child3 + "\n") +
|
||||
(org.result.child2 == null ? "" : org.result.child2 + "\n") +
|
||||
|
|
|
|||
|
|
@ -62,9 +62,9 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
#region " Properties "
|
||||
|
||||
private string? UserId => _httpContextAccessor?.HttpContext?.User?.FindFirst(ClaimTypes.NameIdentifier)?.Value;
|
||||
|
||||
private string? FullName => _httpContextAccessor?.HttpContext?.User?.FindFirst("name")?.Value;
|
||||
private string? token => _httpContextAccessor.HttpContext.Request.Headers["Authorization"];
|
||||
//private bool isSuperAdmin => _httpContextAccessor?.HttpContext?.User?.IsInRole("SUPER_ADMIN") ?? false;
|
||||
|
||||
#endregion
|
||||
|
||||
|
|
@ -140,6 +140,7 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
public async Task<ActionResult<ResponseObject>> GetExamByPlacement(Guid examId)
|
||||
{
|
||||
var getWorkflow = await _permission.GetPermissionAPIWorkflowAsync(examId.ToString(), "SYS_PLACEMENT_PASS");
|
||||
var role = string.Empty;
|
||||
if (getWorkflow == false)
|
||||
{
|
||||
var getPermission = await _permission.GetPermissionAPIAsync("GET", "SYS_PLACEMENT_PASS");
|
||||
|
|
@ -148,6 +149,7 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
{
|
||||
return Error(jsonData["message"]?.ToString(), StatusCodes.Status403Forbidden);
|
||||
}
|
||||
role = jsonData["result"]?.ToString();
|
||||
}
|
||||
|
||||
var rootId = "";
|
||||
|
|
@ -167,7 +169,7 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
if (_res.IsSuccessStatusCode)
|
||||
{
|
||||
var org = JsonConvert.DeserializeObject<OrgRequestAct>(_result);
|
||||
if (org.result.isOfficer == false)
|
||||
if (org.result.isOfficer == false && role?.Trim().ToUpper() != "OWNER")
|
||||
{
|
||||
rootId = org.result.rootId == null ? "" : org.result.rootId;
|
||||
// child1Id = org.result.child1Id == null ? "" : org.result.child1Id;
|
||||
|
|
@ -302,7 +304,7 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
}
|
||||
return Success(result1);
|
||||
}
|
||||
if (org.result.isOfficer == true)
|
||||
if (org.result.isOfficer == true || role?.Trim().ToUpper() == "OWNER")
|
||||
{
|
||||
var data = await _context.PlacementProfiles.Where(x => x.Placement.Id == examId).Select(x => new
|
||||
{
|
||||
|
|
@ -690,6 +692,13 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
public async Task<ActionResult<ResponseObject>> GetDashboardByPlacement(Guid examId)
|
||||
{
|
||||
|
||||
var role = string.Empty;
|
||||
var getPermission = await _permission.GetPermissionAPIAsync("GET", "SYS_PLACEMENT_PASS");
|
||||
var jsonData = JsonConvert.DeserializeObject<JObject>(getPermission);
|
||||
if (jsonData["status"]?.ToString() == "200")
|
||||
{
|
||||
role = jsonData["result"]?.ToString();
|
||||
}
|
||||
|
||||
var rootId = "";
|
||||
var child1Id = "";
|
||||
|
|
@ -709,7 +718,7 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
if (_res.IsSuccessStatusCode)
|
||||
{
|
||||
var org = JsonConvert.DeserializeObject<OrgRequestAct>(_result);
|
||||
if (org.result.isOfficer == false)
|
||||
if (org.result.isOfficer == false && role?.Trim().ToUpper() != "OWNER")
|
||||
{
|
||||
rootId = org.result.rootId == null ? "" : org.result.rootId;
|
||||
// child1Id = org.result.child1Id == null ? "" : org.result.child1Id;
|
||||
|
|
@ -733,7 +742,7 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
|
||||
return Success(placement);
|
||||
}
|
||||
if (org.result.isOfficer == true)
|
||||
if (org.result.isOfficer == true || role?.Trim().ToUpper() == "OWNER")
|
||||
{
|
||||
var placement = await _context.Placements
|
||||
.Where(x => x.Id == examId)
|
||||
|
|
@ -852,6 +861,91 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
return Success();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// API อัพเดทสถานะเป็นบรรจุ
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <response code="200"></response>
|
||||
/// <response code="400">ค่าตัวแปรที่ส่งมาไม่ถูกต้อง</response>
|
||||
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
|
||||
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
|
||||
[HttpPost("pass/update-status")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
||||
public async Task<ActionResult<ResponseObject>> PersonUpdateStatus([FromBody] PersonUpdateStatusRequest req)
|
||||
{
|
||||
var getPermission = await _permission.GetPermissionAPIAsync("UPDATE", "SYS_PLACEMENT_PASS");
|
||||
var jsonData = JsonConvert.DeserializeObject<JObject>(getPermission);
|
||||
if (jsonData["status"]?.ToString() != "200")
|
||||
{
|
||||
return Error(jsonData["message"]?.ToString(), StatusCodes.Status403Forbidden);
|
||||
}
|
||||
string role = jsonData["result"]?.ToString();
|
||||
if (role != "OWNER")
|
||||
{
|
||||
return Error(jsonData["message"]?.ToString(), StatusCodes.Status403Forbidden);
|
||||
}
|
||||
|
||||
var person = await _context.PlacementProfiles
|
||||
.FirstOrDefaultAsync(x => x.Id == req.PersonalId);
|
||||
if (person == null)
|
||||
return Error(GlobalMessages.DataNotFound, 404);
|
||||
|
||||
person.PlacementStatus = "DONE";
|
||||
person.LastUpdateFullName = FullName ?? "System Administrator";
|
||||
person.LastUpdateUserId = UserId ?? "";
|
||||
person.LastUpdatedAt = DateTime.Now;
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
return Success();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// API สำหรับยกเลิกการส่งตัว
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <response code="200"></response>
|
||||
/// <response code="400">ค่าตัวแปรที่ส่งมาไม่ถูกต้อง</response>
|
||||
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
|
||||
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
|
||||
[HttpPost("update/draft-status")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
|
||||
public async Task<ActionResult<ResponseObject>> PersonUpdateDraftStatus([FromBody] PersonUpdateStatusRequest req)
|
||||
{
|
||||
var getPermission = await _permission.GetPermissionAPIAsync("UPDATE", "SYS_PLACEMENT_PASS");
|
||||
var jsonData = JsonConvert.DeserializeObject<JObject>(getPermission);
|
||||
if (jsonData["status"]?.ToString() != "200")
|
||||
return Error(jsonData["message"]?.ToString(), StatusCodes.Status403Forbidden);
|
||||
|
||||
string role = jsonData["result"]?.ToString();
|
||||
if (role != "OWNER")
|
||||
return Error(jsonData["message"]?.ToString(), StatusCodes.Status403Forbidden);
|
||||
|
||||
var person = await _context.PlacementProfiles
|
||||
.FirstOrDefaultAsync(x => x.Id == req.PersonalId);
|
||||
if (person == null)
|
||||
return Error(GlobalMessages.DataNotFound, 404);
|
||||
|
||||
if (person.PlacementStatus == "REPORT")
|
||||
return Error("ไม่สามารถยกเลิกการส่งตัวได้ เนื่องจากส่งไปออกคำสั่งแล้ว");
|
||||
|
||||
if (person.PlacementStatus == "DONE")
|
||||
return Error("ไม่สามารถยกเลิกการส่งตัวได้ เนื่องจากบรรจุไปแล้ว");
|
||||
|
||||
person.Draft = false;
|
||||
person.LastUpdateFullName = FullName ?? "System Administrator";
|
||||
person.LastUpdateUserId = UserId ?? "";
|
||||
person.LastUpdatedAt = DateTime.Now;
|
||||
await _context.SaveChangesAsync();
|
||||
return Success();
|
||||
}
|
||||
|
||||
[HttpGet("pass/deferment/{personalId:length(36)}")]
|
||||
public async Task<ActionResult<ResponseObject>> GetPersonDeferment(Guid personalId)
|
||||
{
|
||||
|
|
@ -971,6 +1065,7 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
person.positionId = req.positionId;
|
||||
person.posMasterNo = req.posMasterNo;
|
||||
person.positionName = req.positionName;
|
||||
person.posExecutiveId = req.posExecutiveId;
|
||||
person.PositionExecutive = req.posExecutiveName;
|
||||
person.positionExecutiveField = req.positionExecutiveField;
|
||||
person.positionArea = req.positionArea;
|
||||
|
|
@ -1359,6 +1454,10 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
profile.posTypeName = null;
|
||||
profile.posLevelId = null;
|
||||
profile.posLevelName = null;
|
||||
profile.PositionExecutive = null;
|
||||
profile.posExecutiveId = null;
|
||||
profile.positionArea = null;
|
||||
profile.positionExecutiveField = null;
|
||||
|
||||
// profile.PositionLevel = null;
|
||||
// profile.PositionType = null;
|
||||
|
|
@ -1716,16 +1815,27 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
[HttpPost("recruit/report/excecute")]
|
||||
public async Task<ActionResult<ResponseObject>> PostReportExecuteRecruit([FromBody] ReportExecuteRequest req)
|
||||
{
|
||||
Console.WriteLine($"[RecruitReportExcecute] Starting execution at {DateTime.Now}");
|
||||
|
||||
try
|
||||
{
|
||||
Console.WriteLine($"[RecruitReportExcecute] Request received with {req?.refIds?.Length ?? 0} refIds");
|
||||
|
||||
var placementProfile = await _context.PlacementProfiles
|
||||
.Include(x => x.PlacementCertificates)
|
||||
.Include(x => x.PlacementEducations)
|
||||
.Where(x => req.refIds.Select(x => x.refId).Contains(x.Id.ToString()))
|
||||
.ToListAsync();
|
||||
|
||||
Console.WriteLine($"[RecruitReportExcecute] Found {placementProfile?.Count ?? 0} placement profiles");
|
||||
|
||||
if (placementProfile == null)
|
||||
{
|
||||
Console.Error.WriteLine("[RecruitReportExcecute] PlacementProfile is null - returning NotFound");
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
Console.WriteLine("[RecruitReportExcecute] Building resultData from placement profiles and refIds");
|
||||
|
||||
var resultData = (from p in placementProfile
|
||||
join r in req.refIds
|
||||
|
|
@ -1749,7 +1859,7 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
isLeave = false,
|
||||
dateRetire = (DateTime?)null,
|
||||
dateAppoint = r.commandDateAffect,
|
||||
dateStart = r.commandDateAffect,
|
||||
dateStart = p.ReportingDate,
|
||||
govAgeAbsent = 0,
|
||||
govAgePlus = 0,
|
||||
birthDate = (p.DateOfBirth == null || p.DateOfBirth == DateTime.MinValue) ? (DateTime?)null : p.DateOfBirth,
|
||||
|
|
@ -1842,7 +1952,14 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
bodyPosition = new
|
||||
{
|
||||
posmasterId = p.posmasterId,
|
||||
positionId = p.positionId
|
||||
positionId = p.positionId,
|
||||
positionName = p.positionName,
|
||||
positionField = p.positionField,
|
||||
posTypeId = p.posTypeId,
|
||||
posLevelId = p.posLevelId,
|
||||
posExecutiveId = p.posExecutiveId,
|
||||
positionExecutiveField = p.positionExecutiveField,
|
||||
positionArea = p.positionArea,
|
||||
},
|
||||
bodyMarry = new
|
||||
{
|
||||
|
|
@ -1871,40 +1988,76 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
},
|
||||
}).ToList();
|
||||
|
||||
var apiUrl = $"{_configuration["API"]}/org/command/excexute/create-officer-profile";
|
||||
using (var client = new HttpClient())
|
||||
Console.WriteLine($"[RecruitReportExcecute] resultData built successfully with {resultData?.Count ?? 0} records");
|
||||
#region Old: Circular Flow
|
||||
// Console.WriteLine($"[RecruitReportExcecute] Calling external API: {_configuration["API"]}/org/command/excexute/create-officer-profile");
|
||||
// var apiUrl = $"{_configuration["API"]}/org/command/excexute/create-officer-profile";
|
||||
// using (var client = new HttpClient())
|
||||
// {
|
||||
// client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
// client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
// var _req = new HttpRequestMessage(HttpMethod.Post, apiUrl);
|
||||
// var _res = await client.PostAsJsonAsync(apiUrl, new
|
||||
// {
|
||||
// data = resultData
|
||||
// });
|
||||
// var _result = await _res.Content.ReadAsStringAsync();
|
||||
// Console.WriteLine($"[RecruitReportExcecute] External API response status: {_res.StatusCode}");
|
||||
// if (_res.IsSuccessStatusCode)
|
||||
// {
|
||||
// Console.WriteLine("[RecruitReportExcecute] External API call successful - updating placement profiles");
|
||||
// placementProfile.ForEach(profile =>
|
||||
// {
|
||||
// profile.PlacementStatus = "DONE";
|
||||
// if (req.refIds.Length > 0)
|
||||
// {
|
||||
// profile.commandId = req.refIds[0].commandId;
|
||||
// profile.refCommandCode = req.refIds[0].commandCode;
|
||||
// profile.refCommandDate = req.refIds[0].commandDateAffect;
|
||||
// profile.refCommandName = req.refIds[0].commandName;
|
||||
// profile.refCommandNo = $"{req.refIds[0].commandNo}/{req.refIds[0].commandYear.ToThaiYear()}";
|
||||
// profile.templateDoc = req.refIds[0].remark;
|
||||
// }
|
||||
// });
|
||||
// Console.WriteLine($"[RecruitReportExcecute] Saving changes to database for {placementProfile.Count} profiles");
|
||||
// await _context.SaveChangesAsync();
|
||||
// Console.WriteLine("[RecruitReportExcecute] Database save completed successfully");
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Console.Error.WriteLine($"[RecruitReportExcecute] External API call failed with status: {_res.StatusCode}");
|
||||
// Console.Error.WriteLine($"[RecruitReportExcecute] Response content: {_result}");
|
||||
// }
|
||||
// }
|
||||
#endregion
|
||||
|
||||
// New: Linear Flow
|
||||
var now = DateTime.Now;
|
||||
placementProfile.ForEach(profile =>
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrl);
|
||||
var _res = await client.PostAsJsonAsync(apiUrl, new
|
||||
profile.PlacementStatus = "DONE";
|
||||
profile.LastUpdateFullName = FullName ?? "System Administrator";
|
||||
profile.LastUpdateUserId = UserId ?? "";
|
||||
profile.LastUpdatedAt = now;
|
||||
if (req.refIds.Length > 0)
|
||||
{
|
||||
data = resultData
|
||||
});
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
if (_res.IsSuccessStatusCode)
|
||||
{
|
||||
placementProfile.ForEach(profile =>
|
||||
{
|
||||
profile.PlacementStatus = "DONE";
|
||||
if (req.refIds.Length > 0)
|
||||
{
|
||||
profile.commandId = req.refIds[0].commandId;
|
||||
profile.refCommandCode = req.refIds[0].commandCode;
|
||||
profile.refCommandDate = req.refIds[0].commandDateAffect;
|
||||
profile.refCommandName = req.refIds[0].commandName;
|
||||
profile.refCommandNo = $"{req.refIds[0].commandNo}/{req.refIds[0].commandYear.ToThaiYear()}";
|
||||
profile.templateDoc = req.refIds[0].remark;
|
||||
}
|
||||
});
|
||||
await _context.SaveChangesAsync();
|
||||
profile.commandId = req.refIds[0].commandId;
|
||||
profile.refCommandCode = req.refIds[0].commandCode;
|
||||
profile.refCommandDate = req.refIds[0].commandDateAffect;
|
||||
profile.refCommandName = req.refIds[0].commandName;
|
||||
profile.refCommandNo = $"{req.refIds[0].commandNo}/{req.refIds[0].commandYear.ToThaiYear()}";
|
||||
profile.templateDoc = req.refIds[0].remark;
|
||||
}
|
||||
}
|
||||
|
||||
return Success();
|
||||
});
|
||||
Console.WriteLine($"[RecruitReportExcecute] Saving changes to database for {placementProfile.Count} profiles");
|
||||
await _context.SaveChangesAsync();
|
||||
Console.WriteLine($"[RecruitReportExcecute] Process completed successfully at {DateTime.Now}");
|
||||
return Success(resultData);
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.Error.WriteLine($"[RecruitReportExcecute] Error occurred: {ex.Message}");
|
||||
Console.Error.WriteLine($"[RecruitReportExcecute] Stack trace: {ex.StackTrace}");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
|
@ -1951,7 +2104,7 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
.Where(x => req.refIds.Contains(x.Id.ToString()))
|
||||
// .Where(x => x.PlacementStatus.ToUpper() == "REPORT")
|
||||
.ToListAsync();
|
||||
placementProfiles.ForEach(profile => profile.PlacementStatus = "PREPARE-CONTAI");
|
||||
placementProfiles.ForEach(profile => profile.PlacementStatus = "PREPARE-CONTAIN");
|
||||
await _context.SaveChangesAsync();
|
||||
return Success();
|
||||
}
|
||||
|
|
@ -2066,8 +2219,11 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
[HttpPost("candidate/report/excecute")]
|
||||
public async Task<ActionResult<ResponseObject>> PostReportExecuteCandidate([FromBody] ReportExecuteRequest req)
|
||||
{
|
||||
Console.WriteLine($"[CandidateReportExcecute] Starting execution at {DateTime.Now}");
|
||||
|
||||
try
|
||||
{
|
||||
Console.WriteLine($"[CandidateReportExcecute] Request received with {req?.refIds?.Length ?? 0} refIds");
|
||||
var placementProfile = await _context.PlacementProfiles
|
||||
.Include(x => x.PlacementCertificates)
|
||||
.Include(x => x.PlacementEducations)
|
||||
|
|
@ -2075,8 +2231,15 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
.Where(x => req.refIds.Select(x => x.refId).Contains(x.Id.ToString()))
|
||||
.ToListAsync();
|
||||
|
||||
Console.WriteLine($"[CandidateReportExcecute] Found {placementProfile?.Count ?? 0} placement profiles");
|
||||
|
||||
if (placementProfile == null)
|
||||
{
|
||||
Console.Error.WriteLine("[CandidateReportExcecute] PlacementProfile is null - returning NotFound");
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
Console.WriteLine("[CandidateReportExcecute] Building resultData from placement profiles and refIds");
|
||||
|
||||
var resultData = (from p in placementProfile
|
||||
join r in req.refIds
|
||||
|
|
@ -2198,7 +2361,14 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
bodyPosition = new
|
||||
{
|
||||
posmasterId = p.posmasterId,
|
||||
positionId = p.positionId
|
||||
positionId = p.positionId,
|
||||
positionName = p.positionName,
|
||||
positionField = p.positionField,
|
||||
posTypeId = p.posTypeId,
|
||||
posLevelId = p.posLevelId,
|
||||
posExecutiveId = p.posExecutiveId,
|
||||
positionExecutiveField = p.positionExecutiveField,
|
||||
positionArea = p.positionArea,
|
||||
},
|
||||
bodyMarry = new
|
||||
{
|
||||
|
|
@ -2227,43 +2397,78 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
},
|
||||
}).ToList();
|
||||
|
||||
var apiUrl = $"{_configuration["API"]}/org/command/excexute/create-officer-profile";
|
||||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrl);
|
||||
var _res = await client.PostAsJsonAsync(apiUrl, new
|
||||
{
|
||||
data = resultData
|
||||
});
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
if (_res.IsSuccessStatusCode)
|
||||
{
|
||||
placementProfile.ForEach(profile =>
|
||||
{
|
||||
profile.PlacementStatus = "DONE";
|
||||
if (req.refIds.Length > 0)
|
||||
{
|
||||
profile.commandId = req.refIds[0].commandId;
|
||||
profile.refCommandCode = req.refIds[0].commandCode;
|
||||
profile.refCommandDate = req.refIds[0].commandDateAffect;
|
||||
profile.refCommandName = req.refIds[0].commandName;
|
||||
profile.refCommandNo = $"{req.refIds[0].commandNo}/{req.refIds[0].commandYear.ToThaiYear()}";
|
||||
profile.templateDoc = req.refIds[0].remark;
|
||||
}
|
||||
});
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
Console.WriteLine($"[CandidateReportExcecute] resultData built successfully with {resultData?.Count ?? 0} records");
|
||||
|
||||
// // update placementstatus
|
||||
// placementProfile.ForEach(profile => profile.PlacementStatus = "DONE");
|
||||
// await _context.SaveChangesAsync();
|
||||
return Success();
|
||||
#region Old: Circular Flow
|
||||
// Console.WriteLine($"[CandidateReportExcecute] Calling external API: {_configuration["API"]}/org/command/excexute/create-officer-profile");
|
||||
// var apiUrl = $"{_configuration["API"]}/org/command/excexute/create-officer-profile";
|
||||
// using (var client = new HttpClient())
|
||||
// {
|
||||
// client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
// client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
// var _req = new HttpRequestMessage(HttpMethod.Post, apiUrl);
|
||||
// var _res = await client.PostAsJsonAsync(apiUrl, new
|
||||
// {
|
||||
// data = resultData
|
||||
// });
|
||||
// var _result = await _res.Content.ReadAsStringAsync();
|
||||
// Console.WriteLine($"[CandidateReportExcecute] External API response status: {_res.StatusCode}");
|
||||
// if (_res.IsSuccessStatusCode)
|
||||
// {
|
||||
// Console.WriteLine("[CandidateReportExcecute] External API call successful - updating placement profiles");
|
||||
// placementProfile.ForEach(profile =>
|
||||
// {
|
||||
// profile.PlacementStatus = "DONE";
|
||||
// if (req.refIds.Length > 0)
|
||||
// {
|
||||
// profile.commandId = req.refIds[0].commandId;
|
||||
// profile.refCommandCode = req.refIds[0].commandCode;
|
||||
// profile.refCommandDate = req.refIds[0].commandDateAffect;
|
||||
// profile.refCommandName = req.refIds[0].commandName;
|
||||
// profile.refCommandNo = $"{req.refIds[0].commandNo}/{req.refIds[0].commandYear.ToThaiYear()}";
|
||||
// profile.templateDoc = req.refIds[0].remark;
|
||||
// }
|
||||
// });
|
||||
// Console.WriteLine($"[CandidateReportExcecute] Saving changes to database for {placementProfile.Count} profiles");
|
||||
// await _context.SaveChangesAsync();
|
||||
// Console.WriteLine("[CandidateReportExcecute] Database save completed successfully");
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Console.Error.WriteLine($"[CandidateReportExcecute] External API call failed with status: {_res.StatusCode}");
|
||||
// Console.Error.WriteLine($"[CandidateReportExcecute] Response content: {_result}");
|
||||
// }
|
||||
// }
|
||||
#endregion
|
||||
|
||||
// New: Linear Flow
|
||||
var now = DateTime.Now;
|
||||
placementProfile.ForEach(profile =>
|
||||
{
|
||||
profile.PlacementStatus = "DONE";
|
||||
profile.LastUpdateFullName = FullName ?? "System Administrator";
|
||||
profile.LastUpdateUserId = UserId ?? "";
|
||||
profile.LastUpdatedAt = now;
|
||||
if (req.refIds.Length > 0)
|
||||
{
|
||||
profile.commandId = req.refIds[0].commandId;
|
||||
profile.refCommandCode = req.refIds[0].commandCode;
|
||||
profile.refCommandDate = req.refIds[0].commandDateAffect;
|
||||
profile.refCommandName = req.refIds[0].commandName;
|
||||
profile.refCommandNo = $"{req.refIds[0].commandNo}/{req.refIds[0].commandYear.ToThaiYear()}";
|
||||
profile.templateDoc = req.refIds[0].remark;
|
||||
}
|
||||
});
|
||||
Console.WriteLine($"[CandidateReportExcecute] Saving changes to database for {placementProfile.Count} profiles");
|
||||
await _context.SaveChangesAsync();
|
||||
Console.WriteLine($"[CandidateReportExcecute] Process completed successfully at {DateTime.Now}");
|
||||
// Return resultData for Node to process directly (Linear Flow)
|
||||
return Success(resultData);
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.Error.WriteLine($"[CandidateReportExcecute] Error occurred: {ex.Message}");
|
||||
Console.Error.WriteLine($"[CandidateReportExcecute] Stack trace: {ex.StackTrace}");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
|
@ -2447,6 +2652,8 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
var data = await _context.PlacementProfiles
|
||||
.Where(x => req.refIds.Select(x => x.refId).Contains(x.Id.ToString()))
|
||||
.ToListAsync();
|
||||
|
||||
|
||||
var resultData = (from p in data
|
||||
join r in req.refIds
|
||||
on p.Id.ToString() equals r.refId
|
||||
|
|
@ -2460,10 +2667,14 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
positionExecutive = p.PositionExecutive,
|
||||
positionExecutiveField = p.positionExecutiveField,
|
||||
positionArea = p.positionArea,
|
||||
positionTypeId = p.posTypeId,
|
||||
positionType = p.posTypeName,
|
||||
positionLevelId = p.posLevelId,
|
||||
positionLevel = p.posLevelName,
|
||||
posmasterId = p.posmasterId,
|
||||
positionId = p.positionId,
|
||||
posExecutiveId = p.posExecutiveId,
|
||||
positionField = p.positionField,
|
||||
commandId = r.commandId,
|
||||
orgRoot = p.root,
|
||||
orgChild1 = p.child1,
|
||||
|
|
@ -2486,24 +2697,39 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
remark = r.remark,
|
||||
}).ToList();
|
||||
|
||||
var baseAPIOrg = _configuration["API"];
|
||||
var apiUrlOrg = $"{baseAPIOrg}/org/command/excexute/salary-current";
|
||||
using (var client = new HttpClient())
|
||||
#region Old: Circular Flow
|
||||
// var baseAPIOrg = _configuration["API"];
|
||||
// var apiUrlOrg = $"{baseAPIOrg}/org/command/excexute/salary-current";
|
||||
// using (var client = new HttpClient())
|
||||
// {
|
||||
// client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
// client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
// var _res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
// {
|
||||
// data = resultData,
|
||||
// });
|
||||
// //// var _result = await _res.Content.ReadAsStringAsync();
|
||||
// //// if (_res.IsSuccessStatusCode)
|
||||
// //// {
|
||||
// //// data.ForEach(profile => profile.PlacementStatus = "DONE");
|
||||
// //// await _context.SaveChangesAsync();
|
||||
// //// }
|
||||
// }
|
||||
#endregion
|
||||
|
||||
// New: Linear Flow - Task #224 ปรับให้เป็น process ที่ควรบันทึกตามลำดับ
|
||||
var now = DateTime.Now;
|
||||
data.ForEach(profile =>
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
{
|
||||
data = resultData,
|
||||
});
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
if (_res.IsSuccessStatusCode)
|
||||
{
|
||||
data.ForEach(profile => profile.PlacementStatus = "DONE");
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
return Success();
|
||||
profile.PlacementStatus = "DONE";
|
||||
profile.LastUpdateFullName = FullName ?? "System Administrator";
|
||||
profile.LastUpdateUserId = UserId ?? "";
|
||||
profile.LastUpdatedAt = now;
|
||||
});
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
// Return resultData for Node to process directly (Linear Flow)
|
||||
return Success(resultData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -2683,6 +2909,8 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
var data = await _context.PlacementProfiles
|
||||
.Where(x => req.refIds.Select(x => x.refId).Contains(x.Id.ToString()))
|
||||
.ToListAsync();
|
||||
|
||||
|
||||
var resultData = (from p in data
|
||||
join r in req.refIds
|
||||
on p.Id.ToString() equals r.refId
|
||||
|
|
@ -2696,10 +2924,14 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
positionExecutive = p.PositionExecutive,
|
||||
positionExecutiveField = p.positionExecutiveField,
|
||||
positionArea = p.positionArea,
|
||||
positionTypeId = p.posTypeId,
|
||||
positionType = p.posTypeName,
|
||||
positionLevelId = p.posLevelId,
|
||||
positionLevel = p.posLevelName,
|
||||
posmasterId = p.posmasterId,
|
||||
positionId = p.positionId,
|
||||
posExecutiveId = p.posExecutiveId,
|
||||
positionField = p.positionField,
|
||||
commandId = r.commandId,
|
||||
orgRoot = p.root,
|
||||
orgChild1 = p.child1,
|
||||
|
|
@ -2722,24 +2954,39 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
remark = r.remark,
|
||||
}).ToList();
|
||||
|
||||
var baseAPIOrg = _configuration["API"];
|
||||
var apiUrlOrg = $"{baseAPIOrg}/org/command/excexute/salary-current";
|
||||
using (var client = new HttpClient())
|
||||
#region Old: Circular Flow
|
||||
// var baseAPIOrg = _configuration["API"];
|
||||
// var apiUrlOrg = $"{baseAPIOrg}/org/command/excexute/salary-current";
|
||||
// using (var client = new HttpClient())
|
||||
// {
|
||||
// client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
// client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
// var _res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
// {
|
||||
// data = resultData,
|
||||
// });
|
||||
// //// var _result = await _res.Content.ReadAsStringAsync();
|
||||
// //// if (_res.IsSuccessStatusCode)
|
||||
// //// {
|
||||
// //// data.ForEach(profile => profile.PlacementStatus = "DONE");
|
||||
// //// await _context.SaveChangesAsync();
|
||||
// //// }
|
||||
// }
|
||||
#endregion
|
||||
|
||||
// New: Linear Flow - Task #224 ปรับให้เป็น process ที่ควรบันทึกตามลำดับ
|
||||
var now = DateTime.Now;
|
||||
data.ForEach(profile =>
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
{
|
||||
data = resultData,
|
||||
});
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
if (_res.IsSuccessStatusCode)
|
||||
{
|
||||
data.ForEach(profile => profile.PlacementStatus = "DONE");
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
return Success();
|
||||
profile.PlacementStatus = "DONE";
|
||||
profile.LastUpdateFullName = FullName ?? "System Administrator";
|
||||
profile.LastUpdateUserId = UserId ?? "";
|
||||
profile.LastUpdatedAt = now;
|
||||
});
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
// Return resultData for Node to process directly (Linear Flow)
|
||||
return Success(resultData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -2904,6 +3151,8 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
var data = await _context.PlacementProfiles
|
||||
.Where(x => req.refIds.Select(x => x.refId).Contains(x.Id.ToString()))
|
||||
.ToListAsync();
|
||||
|
||||
|
||||
var resultData = (from p in data
|
||||
join r in req.refIds
|
||||
on p.Id.ToString() equals r.refId
|
||||
|
|
@ -2921,6 +3170,8 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
positionLevel = p.posLevelName,
|
||||
posmasterId = p.posmasterId,
|
||||
positionId = p.positionId,
|
||||
posExecutiveId = p.posExecutiveId,
|
||||
positionField = p.positionField,
|
||||
commandId = r.commandId,
|
||||
orgRoot = p.root,
|
||||
orgChild1 = p.child1,
|
||||
|
|
@ -2943,24 +3194,39 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
remark = r.remark,
|
||||
}).ToList();
|
||||
|
||||
var baseAPIOrg = _configuration["API"];
|
||||
var apiUrlOrg = $"{baseAPIOrg}/org/command/excexute/salary-current";
|
||||
using (var client = new HttpClient())
|
||||
#region Old: Circular Flow
|
||||
// var baseAPIOrg = _configuration["API"];
|
||||
// var apiUrlOrg = $"{baseAPIOrg}/org/command/excexute/salary-current";
|
||||
// using (var client = new HttpClient())
|
||||
// {
|
||||
// client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
// client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
// var _res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
// {
|
||||
// data = resultData,
|
||||
// });
|
||||
// //// var _result = await _res.Content.ReadAsStringAsync();
|
||||
// //// if (_res.IsSuccessStatusCode)
|
||||
// //// {
|
||||
// //// data.ForEach(profile => profile.PlacementStatus = "DONE");
|
||||
// //// await _context.SaveChangesAsync();
|
||||
// //// }
|
||||
// }
|
||||
#endregion
|
||||
|
||||
// New: Linear Flow - Task #224 ปรับให้เป็น process ที่ควรบันทึกตามลำดับ
|
||||
var now = DateTime.Now;
|
||||
data.ForEach(profile =>
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
{
|
||||
data = resultData,
|
||||
});
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
if (_res.IsSuccessStatusCode)
|
||||
{
|
||||
data.ForEach(profile => profile.PlacementStatus = "DONE");
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
return Success();
|
||||
profile.PlacementStatus = "DONE";
|
||||
profile.LastUpdateFullName = FullName ?? "System Administrator";
|
||||
profile.LastUpdateUserId = UserId ?? "";
|
||||
profile.LastUpdatedAt = now;
|
||||
});
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
// Return resultData for Node to process directly (Linear Flow)
|
||||
return Success(resultData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
? profileAdmin?.RootDnaId
|
||||
: "";
|
||||
}
|
||||
else if (role == "ROOT" || role == "PARENT")
|
||||
else if (role == "ROOT" /*|| role == "PARENT"*/)
|
||||
{
|
||||
nodeId = profileAdmin?.RootDnaId;
|
||||
}
|
||||
|
|
@ -148,6 +148,7 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
p.child4OldId,
|
||||
p.child4ShortNameOld,
|
||||
p.PositionOld,
|
||||
p.PositionNumberOld,
|
||||
p.PositionExecutiveOld,
|
||||
p.positionExecutiveFieldOld,
|
||||
p.positionAreaOld,
|
||||
|
|
@ -193,11 +194,11 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
placementOfficers = placementOfficers
|
||||
.Where(x => x.rootDnaOldId == nodeId).ToList();
|
||||
}
|
||||
else if (role == "PARENT")
|
||||
{
|
||||
placementOfficers = placementOfficers
|
||||
.Where(x => x.rootDnaOldId == nodeId && x.child1DnaOldId != null).ToList();
|
||||
}
|
||||
// else if (role == "PARENT")
|
||||
// {
|
||||
// placementOfficers = placementOfficers
|
||||
// .Where(x => x.rootDnaOldId == nodeId && x.child1DnaOldId != null).ToList();
|
||||
// }
|
||||
else if (role == "NORMAL")
|
||||
{
|
||||
placementOfficers = placementOfficers.Where(x =>
|
||||
|
|
@ -493,7 +494,7 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
placementOfficer.positionAreaOld = org.result.positionArea;
|
||||
placementOfficer.PositionLevelOld = org.result.posLevelName;
|
||||
placementOfficer.PositionTypeOld = org.result.posTypeName;
|
||||
placementOfficer.PositionNumberOld = org.result.nodeShortName + " " + org.result.posMasterNo;
|
||||
placementOfficer.PositionNumberOld = org.result.posNo;
|
||||
placementOfficer.OrganizationOld = (org.result.child4 == null ? "" : org.result.child4 + "\n") +
|
||||
(org.result.child3 == null ? "" : org.result.child3 + "\n") +
|
||||
(org.result.child2 == null ? "" : org.result.child2 + "\n") +
|
||||
|
|
@ -758,6 +759,7 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
var data = await _context.PlacementOfficers
|
||||
.Where(x => req.refIds.Select(x => x.refId).Contains(x.Id.ToString()))
|
||||
.ToListAsync();
|
||||
|
||||
var resultData = (from p in data
|
||||
join r in req.refIds
|
||||
on p.Id.ToString() equals r.refId
|
||||
|
|
@ -799,29 +801,46 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
remark = r.remark,
|
||||
}).ToList();
|
||||
|
||||
var baseAPIOrg = _configuration["API"];
|
||||
var apiUrlOrg = $"{baseAPIOrg}/org/command/excexute/salary";
|
||||
using (var client = new HttpClient())
|
||||
#region Old: Circular Flow
|
||||
// var baseAPIOrg = _configuration["API"];
|
||||
// var apiUrlOrg = $"{baseAPIOrg}/org/command/excexute/salary";
|
||||
// using (var client = new HttpClient())
|
||||
// {
|
||||
// client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
// client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
// var _res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
// {
|
||||
// data = resultData,
|
||||
// });
|
||||
// //// var _result = await _res.Content.ReadAsStringAsync();
|
||||
// //// if (_res.IsSuccessStatusCode)
|
||||
// //// {
|
||||
// //// foreach (var profile in data)
|
||||
// //// {
|
||||
// //// profile.Status = "DONE";
|
||||
// //// profile.commandNo = resultData.Count > 0 ? $"{resultData[0].commandNo}/{resultData[0].commandYear.ToThaiYear()}" : null;
|
||||
// //// }
|
||||
// //// await _context.SaveChangesAsync();
|
||||
// //// }
|
||||
// }
|
||||
#endregion
|
||||
|
||||
// New: Linear Flow - Task #224 ปรับให้เป็น process ที่ควรบันทึกตามลำดับ
|
||||
var firstRef = req.refIds.FirstOrDefault();
|
||||
var commandNoText = firstRef != null ? $"{firstRef.commandNo}/{firstRef.commandYear.ToThaiYear()}" : null;
|
||||
var now = DateTime.Now;
|
||||
data.ForEach(profile =>
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
{
|
||||
data = resultData,
|
||||
});
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
if (_res.IsSuccessStatusCode)
|
||||
{
|
||||
//data.ForEach(profile => profile.Status = "DONE");
|
||||
foreach (var profile in data)
|
||||
{
|
||||
profile.Status = "DONE";
|
||||
profile.commandNo = resultData.Count > 0 ? $"{resultData[0].commandNo}/{resultData[0].commandYear.ToThaiYear()}" : null;
|
||||
}
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
return Success();
|
||||
profile.Status = "DONE";
|
||||
profile.commandNo = commandNoText;
|
||||
profile.LastUpdateFullName = FullName ?? "System Administrator";
|
||||
profile.LastUpdateUserId = UserId ?? "";
|
||||
profile.LastUpdatedAt = now;
|
||||
});
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
// Return resultData for Node to process directly (Linear Flow)
|
||||
return Success(resultData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
? profileAdmin?.RootDnaId
|
||||
: "";
|
||||
}
|
||||
else if (role == "ROOT" || role == "PARENT")
|
||||
else if (role == "ROOT" /*|| role == "PARENT"*/)
|
||||
{
|
||||
nodeId = profileAdmin?.RootDnaId;
|
||||
}
|
||||
|
|
@ -129,6 +129,7 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
{
|
||||
p.Id,
|
||||
p.prefix,
|
||||
p.rank,
|
||||
p.firstName,
|
||||
p.lastName,
|
||||
p.citizenId,
|
||||
|
|
@ -231,11 +232,11 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
placementReceives = placementReceives
|
||||
.Where(x => (x.rootDnaId == nodeId) || (x.CreatedUserId == UserId)).ToList();
|
||||
}
|
||||
else if (role == "PARENT")
|
||||
{
|
||||
placementReceives = placementReceives
|
||||
.Where(x => x.rootDnaId == nodeId && x.child1DnaId != null).ToList();
|
||||
}
|
||||
// else if (role == "PARENT")
|
||||
// {
|
||||
// placementReceives = placementReceives
|
||||
// .Where(x => x.rootDnaId == nodeId && x.child1DnaId != null).ToList();
|
||||
// }
|
||||
else if (role == "NORMAL")
|
||||
{
|
||||
placementReceives = placementReceives.Where(x =>
|
||||
|
|
@ -280,6 +281,7 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
// ProfileId = p.Profile.Id,
|
||||
p.citizenId,
|
||||
p.prefix,
|
||||
p.rank,
|
||||
p.firstName,
|
||||
p.lastName,
|
||||
p.DateOfBirth,
|
||||
|
|
@ -377,6 +379,7 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
// data.ProfileId,
|
||||
data.citizenId,
|
||||
data.prefix,
|
||||
data.rank,
|
||||
data.firstName,
|
||||
data.lastName,
|
||||
data.DateOfBirth,
|
||||
|
|
@ -484,6 +487,7 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
// Profile = profile,
|
||||
citizenId = req.citizenId,
|
||||
prefix = req.prefix,
|
||||
rank = req.rank,
|
||||
firstName = req.firstName,
|
||||
lastName = req.lastName,
|
||||
DateOfBirth = req.BirthDate,
|
||||
|
|
@ -510,9 +514,8 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
{
|
||||
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
|
||||
Console.Write($"[PlacementReceiveController] Check-Citizen API-Key : {_configuration["API_KEY"]}");
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlCheckCitizen, new
|
||||
|
||||
{
|
||||
|
|
@ -537,6 +540,7 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
Console.Write("[PlacementReceiveController] Check-Position");
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Get, apiUrl);
|
||||
var _res = await client.SendAsync(_req);
|
||||
|
|
@ -586,7 +590,7 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
placementReceive.positionAreaOld = org.result.positionArea;
|
||||
placementReceive.PositionLevelOld = org.result.posLevelName;
|
||||
placementReceive.PositionTypeOld = org.result.posTypeName;
|
||||
placementReceive.PositionNumberOld = org.result.nodeShortName + " " + org.result.posMasterNo;
|
||||
placementReceive.PositionNumberOld = org.result.posNo;
|
||||
placementReceive.OrganizationOld = (org.result.child4 == null ? "" : org.result.child4 + "\n") +
|
||||
(org.result.child3 == null ? "" : org.result.child3 + "\n") +
|
||||
(org.result.child2 == null ? "" : org.result.child2 + "\n") +
|
||||
|
|
@ -778,6 +782,7 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
uppdated.posMasterNo = req.posMasterNo;
|
||||
uppdated.position = req.positionName;
|
||||
uppdated.PositionExecutive = req.posExecutiveName;
|
||||
uppdated.posExecutiveId = req.posExecutiveId;
|
||||
uppdated.positionExecutiveField = req.positionExecutiveField;
|
||||
uppdated.positionArea = req.positionArea;
|
||||
uppdated.positionField = req.positionField;
|
||||
|
|
@ -826,7 +831,7 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
|
||||
var _res = await client.PostAsJsonAsync(apiUrlCheckCitizen, new
|
||||
|
||||
|
|
@ -852,6 +857,7 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
uppdated.Gender = req.Gender;
|
||||
uppdated.citizenId = req.citizenId;
|
||||
uppdated.prefix = req.prefix;
|
||||
uppdated.rank = req.rank;
|
||||
uppdated.firstName = req.firstName;
|
||||
uppdated.lastName = req.lastName;
|
||||
uppdated.DateOfBirth = req.DateOfBirth;
|
||||
|
|
@ -917,6 +923,61 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
return Success();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// API ลบรายการรับโอน (ADMIN)
|
||||
/// </summary>
|
||||
/// <param name="id">Id รับโอน</param>
|
||||
/// <returns></returns>
|
||||
/// <response code="200"></response>
|
||||
/// <response code="400">ค่าตัวแปรที่ส่งมาไม่ถูกต้อง</response>
|
||||
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
|
||||
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
|
||||
[HttpDelete("admin/{id:length(36)}")]
|
||||
public async Task<ActionResult<ResponseObject>> DeleteForAdminAsync(Guid id)
|
||||
{
|
||||
var jsonData = await _permission.GetPermissionWithActingAPIAsync("DELETE", "SYS_TRANSFER_RECEIVE");
|
||||
if (jsonData!.status != 200)
|
||||
{
|
||||
return Error(jsonData.message, StatusCodes.Status403Forbidden);
|
||||
}
|
||||
// ตรวจสอบว่า role ต้องเป็น OWNER เท่านั้น
|
||||
if (jsonData.result.privilege != "OWNER")
|
||||
{
|
||||
return Error("ไม่มีสิทธิ์ในการลบรายการรับโอน", StatusCodes.Status403Forbidden);
|
||||
}
|
||||
var deleted = await _context.PlacementReceives.AsQueryable()
|
||||
.Include(x => x.PlacementReceiveDocs)
|
||||
.ThenInclude(x => x.Document)
|
||||
.FirstOrDefaultAsync(x => x.Id == id);
|
||||
if (deleted == null)
|
||||
return NotFound();
|
||||
|
||||
// ห้ามลบเฉพาะสถานะ REPORT, WAITING, DONE
|
||||
if (new[] { "REPORT", "WAITING", "DONE" }.Contains(deleted.Status))
|
||||
{
|
||||
return Error("ไม่สามารถลบรายการรับโอนสถานะนี้ได้");
|
||||
}
|
||||
|
||||
var placementReceiveDocs = new List<dynamic>();
|
||||
foreach (var doc in deleted.PlacementReceiveDocs)
|
||||
{
|
||||
if (doc.Document != null)
|
||||
placementReceiveDocs.Add(doc.Document.Id);
|
||||
}
|
||||
_context.PlacementReceiveDocs.RemoveRange(deleted.PlacementReceiveDocs);
|
||||
await _context.SaveChangesAsync();
|
||||
_context.PlacementReceives.Remove(deleted);
|
||||
foreach (var doc in placementReceiveDocs)
|
||||
{
|
||||
if (doc != null)
|
||||
await _documentService.DeleteFileAsync(doc);
|
||||
}
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
return Success();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// สั่งรายชื่อไปออกคำสั่ง
|
||||
/// </summary>
|
||||
|
|
@ -1120,117 +1181,150 @@ namespace BMA.EHR.Placement.Service.Controllers
|
|||
[HttpPost("command/report/excecute")]
|
||||
public async Task<ActionResult<ResponseObject>> PostReportExecute([FromBody] ReportExecuteRequest req)
|
||||
{
|
||||
var data = await _context.PlacementReceives
|
||||
.Include(x => x.Avatar)
|
||||
.Where(x => req.refIds.Select(x => x.refId).Contains(x.Id.ToString()))
|
||||
.ToListAsync();
|
||||
var resultData = (from p in data
|
||||
join r in req.refIds
|
||||
on p.Id.ToString() equals r.refId
|
||||
select new
|
||||
{
|
||||
bodyProfile = new
|
||||
{
|
||||
rank = string.Empty,
|
||||
prefix = p.prefix == null ? string.Empty : p.prefix,
|
||||
firstName = p.firstName == null ? string.Empty : p.firstName,
|
||||
lastName = p.lastName == null ? string.Empty : p.lastName,
|
||||
citizenId = p.citizenId == null ? string.Empty : p.citizenId,
|
||||
position = p.position == null ? string.Empty : p.position,
|
||||
posLevelId = p.posLevelId == null ? string.Empty : p.posLevelId,
|
||||
posTypeId = p.posTypeId == null ? string.Empty : p.posTypeId,
|
||||
email = (String?)null,
|
||||
phone = p.TelephoneNumber == null ? string.Empty : p.TelephoneNumber,
|
||||
keycloak = string.Empty,
|
||||
isProbation = false,
|
||||
isLeave = false,
|
||||
dateRetire = (DateTime?)null,
|
||||
dateAppoint = r.commandDateAffect,
|
||||
dateStart = r.commandDateAffect,
|
||||
govAgeAbsent = 0,
|
||||
govAgePlus = 0,
|
||||
birthDate = (p.DateOfBirth == null || p.DateOfBirth == DateTime.MinValue) ? (DateTime?)null : p.DateOfBirth,
|
||||
reasonSameDate = (DateTime?)null,
|
||||
ethnicity = p.Race == null ? string.Empty : p.Race,
|
||||
telephoneNumber = (String?)null,
|
||||
nationality = p.Nationality == null ? string.Empty : p.Nationality,
|
||||
gender = p.Gender == null ? string.Empty : p.Gender,
|
||||
relationship = p.Relationship == null ? string.Empty : p.Relationship,
|
||||
religion = p.Religion == null ? string.Empty : p.Religion,
|
||||
bloodGroup = p.BloodGroup == null ? string.Empty : p.BloodGroup,
|
||||
registrationAddress = (String?)null,
|
||||
registrationProvinceId = (String?)null,
|
||||
registrationDistrictId = (String?)null,
|
||||
registrationSubDistrictId = (String?)null,
|
||||
registrationZipCode = (String?)null,
|
||||
currentAddress = (String?)null,
|
||||
currentProvinceId = (String?)null,
|
||||
currentDistrictId = (String?)null,
|
||||
currentSubDistrictId = (String?)null,
|
||||
currentZipCode = (String?)null,
|
||||
amount = r.amount,
|
||||
amountSpecial = r.amountSpecial,
|
||||
objectRefId = p.Avatar != null && p.Avatar?.ObjectRefId != null ? p.Avatar?.ObjectRefId.ToString("D") : null,
|
||||
},
|
||||
bodySalarys = new
|
||||
{
|
||||
profileId = p.profileId,
|
||||
amount = r.amount,
|
||||
amountSpecial = r.amountSpecial,
|
||||
positionSalaryAmount = r.positionSalaryAmount,
|
||||
mouthSalaryAmount = r.mouthSalaryAmount,
|
||||
positionExecutive = p.PositionExecutive,
|
||||
positionExecutiveField = p.positionExecutiveField,
|
||||
positionArea = p.positionArea,
|
||||
positionType = p.posTypeName,
|
||||
positionLevel = p.posLevelName,
|
||||
commandId = r.commandId,
|
||||
orgRoot = p.root,
|
||||
orgChild1 = p.child1,
|
||||
orgChild2 = p.child2,
|
||||
orgChild3 = p.child3,
|
||||
orgChild4 = p.child4,
|
||||
commandNo = r.commandNo,
|
||||
commandYear = r.commandYear,
|
||||
posNo = p.posMasterNo?.ToString(),
|
||||
posNoAbb = p.node == 4 ? $"{p.child4ShortName}" :
|
||||
p.node == 3 ? $"{p.child3ShortName}" :
|
||||
p.node == 2 ? $"{p.child2ShortName}" :
|
||||
p.node == 1 ? $"{p.child1ShortName}" :
|
||||
p.node == 0 ? $"{p.rootShortName}" : "",
|
||||
commandDateAffect = r.commandDateAffect,
|
||||
commandDateSign = r.commandDateSign,
|
||||
positionName = p.position,
|
||||
commandCode = r.commandCode,
|
||||
commandName = r.commandName,
|
||||
remark = r.remark,
|
||||
},
|
||||
bodyPosition = new
|
||||
{
|
||||
posmasterId = p.posmasterId,
|
||||
positionId = p.positionId
|
||||
}
|
||||
}).ToList();
|
||||
|
||||
var baseAPIOrg = _configuration["API"];
|
||||
//var apiUrlOrg = $"{baseAPIOrg}/org/command/excexute/salary-current";
|
||||
var apiUrlOrg = $"{_configuration["API"]}/org/command/excexute/create-officer-profile";
|
||||
using (var client = new HttpClient())
|
||||
Console.WriteLine($"[ReceiveReportExcecute] Starting execution at {DateTime.Now}");
|
||||
try
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
var data = await _context.PlacementReceives
|
||||
.Include(x => x.Avatar)
|
||||
.Where(x => req.refIds.Select(x => x.refId).Contains(x.Id.ToString()))
|
||||
.ToListAsync();
|
||||
|
||||
var resultData = (from p in data
|
||||
join r in req.refIds
|
||||
on p.Id.ToString() equals r.refId
|
||||
select new
|
||||
{
|
||||
bodyProfile = new
|
||||
{
|
||||
rank = string.IsNullOrEmpty(p.rank) ? string.Empty : p.rank,
|
||||
prefix = p.prefix == null ? string.Empty : p.prefix,
|
||||
firstName = p.firstName == null ? string.Empty : p.firstName,
|
||||
lastName = p.lastName == null ? string.Empty : p.lastName,
|
||||
citizenId = p.citizenId == null ? string.Empty : p.citizenId,
|
||||
position = p.position == null ? string.Empty : p.position,
|
||||
posLevelId = p.posLevelId == null ? string.Empty : p.posLevelId,
|
||||
posTypeId = p.posTypeId == null ? string.Empty : p.posTypeId,
|
||||
email = (String?)null,
|
||||
phone = p.TelephoneNumber == null ? string.Empty : p.TelephoneNumber,
|
||||
keycloak = string.Empty,
|
||||
isProbation = false,
|
||||
isLeave = false,
|
||||
dateRetire = (DateTime?)null,
|
||||
dateAppoint = r.commandDateAffect,
|
||||
dateStart = r.commandDateAffect,
|
||||
govAgeAbsent = 0,
|
||||
govAgePlus = 0,
|
||||
birthDate = (p.DateOfBirth == null || p.DateOfBirth == DateTime.MinValue) ? (DateTime?)null : p.DateOfBirth,
|
||||
reasonSameDate = (DateTime?)null,
|
||||
ethnicity = p.Race == null ? string.Empty : p.Race,
|
||||
telephoneNumber = (String?)null,
|
||||
nationality = p.Nationality == null ? string.Empty : p.Nationality,
|
||||
gender = p.Gender == null ? string.Empty : p.Gender,
|
||||
relationship = p.Relationship == null ? string.Empty : p.Relationship,
|
||||
religion = p.Religion == null ? string.Empty : p.Religion,
|
||||
bloodGroup = p.BloodGroup == null ? string.Empty : p.BloodGroup,
|
||||
registrationAddress = (String?)null,
|
||||
registrationProvinceId = (String?)null,
|
||||
registrationDistrictId = (String?)null,
|
||||
registrationSubDistrictId = (String?)null,
|
||||
registrationZipCode = (String?)null,
|
||||
currentAddress = (String?)null,
|
||||
currentProvinceId = (String?)null,
|
||||
currentDistrictId = (String?)null,
|
||||
currentSubDistrictId = (String?)null,
|
||||
currentZipCode = (String?)null,
|
||||
amount = r.amount,
|
||||
amountSpecial = r.amountSpecial,
|
||||
objectRefId = p.Avatar != null && p.Avatar?.ObjectRefId != null ? p.Avatar?.ObjectRefId.ToString("D") : null,
|
||||
},
|
||||
bodySalarys = new
|
||||
{
|
||||
profileId = p.profileId,
|
||||
amount = r.amount,
|
||||
amountSpecial = r.amountSpecial,
|
||||
positionSalaryAmount = r.positionSalaryAmount,
|
||||
mouthSalaryAmount = r.mouthSalaryAmount,
|
||||
positionExecutive = p.PositionExecutive,
|
||||
positionExecutiveField = p.positionExecutiveField,
|
||||
positionArea = p.positionArea,
|
||||
positionType = p.posTypeName,
|
||||
positionLevel = p.posLevelName,
|
||||
commandId = r.commandId,
|
||||
orgRoot = p.root,
|
||||
orgChild1 = p.child1,
|
||||
orgChild2 = p.child2,
|
||||
orgChild3 = p.child3,
|
||||
orgChild4 = p.child4,
|
||||
commandNo = r.commandNo,
|
||||
commandYear = r.commandYear,
|
||||
posNo = p.posMasterNo?.ToString(),
|
||||
posNoAbb = p.node == 4 ? $"{p.child4ShortName}" :
|
||||
p.node == 3 ? $"{p.child3ShortName}" :
|
||||
p.node == 2 ? $"{p.child2ShortName}" :
|
||||
p.node == 1 ? $"{p.child1ShortName}" :
|
||||
p.node == 0 ? $"{p.rootShortName}" : "",
|
||||
commandDateAffect = r.commandDateAffect,
|
||||
commandDateSign = r.commandDateSign,
|
||||
positionName = p.position,
|
||||
commandCode = r.commandCode,
|
||||
commandName = r.commandName,
|
||||
remark = r.remark,
|
||||
},
|
||||
bodyPosition = new
|
||||
{
|
||||
posmasterId = p.posmasterId,
|
||||
positionId = p.positionId,
|
||||
positionName = p.position,
|
||||
positionField = p.positionField,
|
||||
posTypeId = p.posTypeId,
|
||||
posLevelId = p.posLevelId,
|
||||
posExecutiveId = p.posExecutiveId,
|
||||
positionExecutiveField = p.positionExecutiveField,
|
||||
positionArea = p.positionArea,
|
||||
}
|
||||
}).ToList();
|
||||
|
||||
Console.WriteLine($"[ReceiveReportExcecute] resultData built successfully with {resultData?.Count ?? 0} records");
|
||||
#region Old: Circular Flow
|
||||
// var baseAPIOrg = _configuration["API"];
|
||||
// var apiUrlOrg = $"{_configuration["API"]}/org/command/excexute/create-officer-profile";
|
||||
// using (var client = new HttpClient())
|
||||
// {
|
||||
// client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
// client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
// var _res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
// {
|
||||
// data = resultData,
|
||||
// });
|
||||
// // // var _result = await _res.Content.ReadAsStringAsync();
|
||||
// // // if (_res.IsSuccessStatusCode)
|
||||
// // // {
|
||||
// // // data.ForEach(profile => profile.Status = "DONE");
|
||||
// // // await _context.SaveChangesAsync();
|
||||
// // // }
|
||||
// }
|
||||
#endregion
|
||||
|
||||
// New: Linear Flow
|
||||
var now = DateTime.Now;
|
||||
data.ForEach(profile =>
|
||||
{
|
||||
data = resultData,
|
||||
profile.Status = "DONE";
|
||||
profile.LastUpdateFullName = FullName ?? "System Administrator";
|
||||
profile.LastUpdateUserId = UserId ?? "";
|
||||
profile.LastUpdatedAt = now;
|
||||
});
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
if (_res.IsSuccessStatusCode)
|
||||
{
|
||||
data.ForEach(profile => profile.Status = "DONE");
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
Console.WriteLine($"[ReceiveReportExcecute] Saving changes to database for {data.Count} profiles");
|
||||
await _context.SaveChangesAsync();
|
||||
Console.WriteLine($"[ReceiveReportExcecute] Process completed successfully at {DateTime.Now}");
|
||||
return Success(resultData);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.Error.WriteLine($"[ReceiveReportExcecute] Error occurred: {ex.Message}");
|
||||
Console.Error.WriteLine($"[ReceiveReportExcecute] Stack trace: {ex.StackTrace}");
|
||||
throw;
|
||||
}
|
||||
return Success();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue