Compare commits
1669 commits
command-1.
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
b10ff45d07 | ||
|
|
02487d91ff | ||
|
|
839c357842 | ||
|
|
cbc2a1a88d | ||
|
|
e8ffb82ead | ||
|
|
54c8152752 | ||
|
|
4f28b4e9e0 | ||
|
|
982dfc33d1 | ||
|
|
2e6a81ff31 | ||
|
|
22a7a8c17c | ||
|
|
c1d689ebfa | ||
|
|
ecf5ada7ed | ||
|
|
9bd6017ded | ||
|
|
e1c7688913 | ||
|
|
4e4eec3d84 | ||
|
|
2f366374fa | ||
|
|
2b737de23b | ||
|
|
d945deae4f | ||
|
|
d3501e831c | ||
|
|
c3901d56b3 | ||
|
|
27b3773c79 | ||
|
|
5219934e05 | ||
|
|
15f5d7cae7 | ||
|
|
d7b257f0ce | ||
|
|
e3a228773e | ||
|
|
90eea1ac7f | ||
|
|
a463df5716 | ||
|
|
60602d99c4 | ||
|
|
9442d3b29f | ||
|
|
3532df32fd | ||
|
|
6c8e79b1bc | ||
|
|
0ab75b2a19 | ||
|
|
1aab307f6a | ||
|
|
93a83b34e6 | ||
|
|
79e0fe7f1b | ||
|
|
21f82d69e1 | ||
|
|
b5c82f4243 | ||
|
|
b0715e3da6 | ||
|
|
510f1cd78a | ||
|
|
83a915f92c | ||
|
|
094789bfb1 | ||
|
|
64c1021c52 | ||
|
|
5ec7933b3c | ||
|
|
9e529ed19b | ||
|
|
3e8c3d998e | ||
|
|
3a6e4501fd | ||
|
|
5415019b3c | ||
|
|
86790cf9f3 | ||
|
|
127909d29d | ||
|
|
6907607a06 | ||
|
|
0233d92931 | ||
|
|
90ea986831 | ||
|
|
1c3ce46bcb | ||
| 398679cbcc | |||
| d831b208de | |||
|
|
49cb60dee7 | ||
|
|
5cdef791f3 | ||
|
|
7b97cd09a3 | ||
|
|
3f13557b31 | ||
|
|
95cd49ecbc | ||
|
|
6e531e4d16 | ||
|
|
99accd44e3 | ||
| a540912202 | |||
| 0690337422 | |||
| 8c1a219084 | |||
| 9dfd5efafc | |||
| 98adc74792 | |||
|
|
14eb80a30e | ||
|
|
e8dfe976a2 | ||
| 8f491c1b12 | |||
| a6de2791c4 | |||
| a739d52c46 | |||
| 4865bab7e2 | |||
| f9ca9b52af | |||
|
|
be57524f1b | ||
|
|
517755d758 | ||
|
|
05689b5338 | ||
|
|
a381ff1528 | ||
|
|
ed04bf8258 | ||
|
|
909042445c | ||
|
|
cb074e3e25 | ||
|
|
7e71f528ab | ||
|
|
adb8e31308 | ||
|
|
0b0cc53e07 | ||
| 72b9c6e31e | |||
| 9fe3c82a9b | |||
|
|
8973e1b78f | ||
|
|
4a94aae6e3 | ||
|
|
7caf1cc8d6 | ||
| c87e467a6e | |||
| d10c86e0cb | |||
| 2b1d6852c9 | |||
| bde1aa21c9 | |||
| 8bb31b4e73 | |||
| 804a4cf85f | |||
|
|
b03be82f7c | ||
|
|
b2fcc4a5b9 | ||
| ed26d8443c | |||
| b55e1d1f63 | |||
|
|
99838ba1ff | ||
|
|
fd8e0e78b6 | ||
| 37281fc036 | |||
| fb282915d1 | |||
|
|
80dca3dfac | ||
|
|
3b58d38eb1 | ||
| 121e605699 | |||
| 97c9064ab5 | |||
|
|
e0d253cc68 | ||
|
|
d5c2c54eaa | ||
| 90cb343941 | |||
| d6497a5d51 | |||
|
|
9becd892f5 | ||
|
|
cc8cd77560 | ||
|
|
7e039b798d | ||
|
|
795502a93c | ||
|
|
d703337b4b | ||
|
|
18ab28e335 | ||
|
|
ff66aebdfa | ||
|
|
e023ed65f7 | ||
|
|
d7ebe9cdca | ||
|
|
02a5eacd0f | ||
|
|
199d0c90e3 | ||
|
|
328f54b4e3 | ||
|
|
0e21e10d24 | ||
|
|
88a48577e9 | ||
|
|
23a6058eba | ||
|
|
07dd715e16 | ||
|
|
ec04665f39 | ||
|
|
0a58075428 | ||
| b6862b93bf | |||
| b51cf9a919 | |||
|
|
14cc614864 | ||
|
|
59fd20c879 | ||
|
|
fc68cb0101 | ||
|
|
6b9767449c | ||
|
|
51f1a4c563 | ||
|
|
2981f865b3 | ||
|
|
b4e303e0a7 | ||
|
|
08fb06ca84 | ||
| ec3b267a6c | |||
| a047787fb4 | |||
|
|
21c10d66f5 | ||
|
|
7778f6cccd | ||
|
|
436370312e | ||
|
|
5451c49dbe | ||
|
|
27112a060c | ||
|
|
f78d188979 | ||
|
|
f2d17c3a38 | ||
|
|
48792f0d31 | ||
|
|
d2569d8cef | ||
|
|
db7626ce69 | ||
| e9d48d1930 | |||
| 62aa25793b | |||
|
|
a9bacdc6ae | ||
|
|
cf9ae391a5 | ||
|
|
c1416a2a33 | ||
|
|
84df3d4b86 | ||
|
|
079641c7ad | ||
|
|
287c11dfd5 | ||
|
|
b1afbe53ef | ||
|
|
17259598c9 | ||
|
|
d1bda77fa9 | ||
|
|
14fd93ae95 | ||
|
|
842ed531f5 | ||
|
|
223a78ce9e | ||
|
|
65e85b7194 | ||
|
|
16cc6b5111 | ||
|
|
7ee1477ee2 | ||
|
|
0065468568 | ||
|
|
ee0bb692ec | ||
|
|
b4cc522fef | ||
|
|
b478b9eded | ||
| 5dab116166 | |||
| a85749010a | |||
| b345091905 | |||
| b1c0ab8266 | |||
| 3fd9d05cd2 | |||
|
|
87c4f85bf6 | ||
|
|
f081034e36 | ||
|
|
998ca38da8 | ||
|
|
2187142668 | ||
|
|
36aea81d54 | ||
|
|
5fc3cfa3b4 | ||
|
|
4375ca0da8 | ||
| 2295aedc3a | |||
|
|
54358ac845 | ||
|
|
d65107ad40 | ||
|
|
755dd9d06e | ||
| 5007b6f10d | |||
|
|
0f45792e74 | ||
|
|
451757be65 | ||
|
|
503805b194 | ||
|
|
720027b26c | ||
|
|
cd3c356d02 | ||
|
|
55f0dc6876 | ||
|
|
4fb82bf25a | ||
|
|
c0f4cd3bdf | ||
|
|
f8a71f6624 | ||
|
|
85e1c95f97 | ||
| 7d9c3fa46b | |||
| d6e4426e08 | |||
| 821c4614c3 | |||
| fbcd1b6984 | |||
|
|
81658054f8 | ||
|
|
f97e643ac1 | ||
|
|
84ab5e79d6 | ||
| 51962eea16 | |||
|
|
ed1bb838ce | ||
|
|
8ba9d349db | ||
|
|
559765dd86 | ||
|
|
4ba48d0e70 | ||
|
|
5f0a0b1a46 | ||
|
|
3d9f922fc9 | ||
|
|
fe4a174bf7 | ||
|
|
f784205412 | ||
|
|
0dcabaa25d | ||
|
|
4494939c5f | ||
|
|
7ddc1debfc | ||
|
|
9e8fe1b30a | ||
| 1ec8e51c37 | |||
| 12c8bc5014 | |||
|
|
ad6a458973 | ||
|
|
f9d1dd9f38 | ||
|
|
5efb1c99c6 | ||
|
|
946721ffb2 | ||
|
|
8529c3d801 | ||
|
|
97dd104429 | ||
|
|
d0599aedea | ||
|
|
ddf899ce5d | ||
|
|
1e275748a0 | ||
|
|
389adeec2f | ||
|
|
faf62f1985 | ||
|
|
8d37024b6c | ||
|
|
1f3632744d | ||
|
|
9de97f9d90 | ||
|
|
2aa66acfd0 | ||
| 95c62accef | |||
|
|
e51ca439f9 | ||
|
|
edbd337ab6 | ||
|
|
373e2a06d8 | ||
|
|
777f4d0930 | ||
|
|
be45cf58b8 | ||
|
|
081260a83b | ||
|
|
77eaca72b3 | ||
| 6fb574f9de | |||
| 0dcd76c302 | |||
| 33e8bf5ab7 | |||
| 6d42484297 | |||
| f1c3163116 | |||
| 9a4e49eb88 | |||
| 69af557f95 | |||
| e52d6430b0 | |||
| 45f6c5626e | |||
| 063e54c4e0 | |||
| 7254b1ed87 | |||
| a892fe9ee3 | |||
| 0fe60d3212 | |||
| cd7ac8de17 | |||
| aa1708474b | |||
| 87e6f88cf6 | |||
| d0c5bafdba | |||
| 643b6903d9 | |||
| 5c0f8877a4 | |||
| f1540de911 | |||
| 2a02bdf9f7 | |||
|
|
463d439a1a | ||
|
|
e08dc350fe | ||
|
|
aa904079a2 | ||
| c6c49ffaff | |||
| 51fc5c6395 | |||
|
|
a0cfb23350 | ||
|
|
9eae970ff3 | ||
| 6bba1b19ce | |||
| 777c9563ca | |||
| 62867d54c3 | |||
| 3c34245d1c | |||
| 5561817fa4 | |||
| ba7dae2bd8 | |||
| 829149a091 | |||
| d4e0661964 | |||
| 2abb32f74b | |||
| 7d680658e4 | |||
| d0cad2de8b | |||
| b01031e919 | |||
| 57a6d9a6c6 | |||
| 0516b289fe | |||
| fc26ab4064 | |||
| 223c891782 | |||
| 83926c534f | |||
| bfe1caa984 | |||
| 91a3aef5d7 | |||
| cbd1e8029d | |||
| bdd613b40f | |||
| 507d50dfe3 | |||
| fb6a82be14 | |||
| 8001dd0c11 | |||
|
|
348edeff85 | ||
| 3ae9be5869 | |||
|
|
75ddebba37 | ||
| 2d9f546023 | |||
| 29b161bf76 | |||
|
|
f65dd53cec | ||
| 8c2e4be638 | |||
| 711a8eeff6 | |||
|
|
0da5907eba | ||
|
|
ef9fafecfc | ||
|
|
0ee17ef586 | ||
|
|
b89f394f1e | ||
|
|
af45365920 | ||
|
|
59a3aaa2d8 | ||
|
|
8be20b1365 | ||
|
|
f72d705101 | ||
|
|
4130604ca8 | ||
|
|
7af3618287 | ||
|
|
a781de2499 | ||
| 14b15a9816 | |||
|
|
0c9ec3dd43 | ||
|
|
f6594f9773 | ||
|
|
009de80c3f | ||
|
|
593e5a3f57 | ||
|
|
71dc9f05d3 | ||
|
|
23d86f632e | ||
| e3a57b0159 | |||
| 7016df503a | |||
|
|
708ef29ebe | ||
|
|
1f41b96844 | ||
| ce8736b083 | |||
| 0223ff5d9b | |||
|
|
b40d4e2765 | ||
|
|
b548d8fea6 | ||
|
|
ac037aff4b | ||
|
|
d3be22cfbd | ||
|
|
757035a4b0 | ||
|
|
3384c520d7 | ||
|
|
aef2d3381a | ||
|
|
ac6e4f5c1f | ||
|
|
0b9d3b16ac | ||
|
|
1b861c1a65 | ||
|
|
6b73a0aa47 | ||
|
|
6d90951000 | ||
|
|
8b3eaf0664 | ||
|
|
53e547f168 | ||
|
|
e58bda8e9e | ||
|
|
c348dae155 | ||
| f2d01b8505 | |||
|
|
0e74ad730c | ||
|
|
7d431d7882 | ||
|
|
8e890af48f | ||
|
|
d6a3bdc8ba | ||
|
|
18be7bee37 | ||
|
|
94446fe6fd | ||
|
|
c657398e72 | ||
|
|
015d2ea956 | ||
|
|
8f9b40c303 | ||
| 419866bb70 | |||
| 6308ffbc8f | |||
|
|
89a90099a7 | ||
|
|
2e77371316 | ||
|
|
f4b3eeac76 | ||
|
|
298b61fc67 | ||
|
|
2a0e1f7623 | ||
|
|
1887c62e18 | ||
|
|
6d3d14445f | ||
|
|
c6fee999eb | ||
|
|
0baa85e857 | ||
|
|
f9d8fa285f | ||
|
|
b9931ce2e4 | ||
|
|
1038d2e894 | ||
|
|
1624b2f365 | ||
|
|
ba6bfdaedf | ||
|
|
27acadbb07 | ||
|
|
3e8e461ebe | ||
|
|
8870139cbe | ||
|
|
058c762eb2 | ||
|
|
065fafc3d7 | ||
|
|
1e5676e8ab | ||
|
|
30ff1ae15c | ||
|
|
1ef8544833 | ||
|
|
ea25f5252b | ||
|
|
826aa8db19 | ||
|
|
b1ad88c37b | ||
|
|
9e84bddb65 | ||
|
|
ea55d21f51 | ||
|
|
e790b50f58 | ||
|
|
360580535a | ||
|
|
9070378060 | ||
|
|
2d7459da25 | ||
|
|
326a258e2b | ||
| bc8b681900 | |||
| 706edbd0f0 | |||
|
|
b528f0a81d | ||
|
|
afb2cfa189 | ||
|
|
61407c342b | ||
|
|
588e13c3f5 | ||
| 4bf0593b0e | |||
| b0cfc2eee9 | |||
| fdae099855 | |||
| 9bde6a9895 | |||
|
|
b747e3ae68 | ||
|
|
40babdf1a7 | ||
|
|
7e3ae58b33 | ||
|
|
dff98272dd | ||
|
|
237567e5ab | ||
|
|
a494020d37 | ||
|
|
78a47bc735 | ||
|
|
13709c65ef | ||
|
|
d539f6fa4a | ||
|
|
ffecbf7df2 | ||
|
|
b260e4067f | ||
|
|
6ad83ecc53 | ||
|
|
175232148b | ||
|
|
be9545f37c | ||
|
|
75d8434935 | ||
|
|
22304e7186 | ||
|
|
fb76f5737a | ||
|
|
c49375718d | ||
|
|
db84cdbf29 | ||
|
|
96246d5853 | ||
| e0ed1fc240 | |||
| 25f6ebcdd7 | |||
|
|
ad72bc7ff6 | ||
|
|
cf6f0feef5 | ||
|
|
97b5bd1176 | ||
|
|
88270a230f | ||
|
|
7b55e16e7d | ||
|
|
c3c9c85d30 | ||
|
|
d0e39e385b | ||
|
|
de72adc3ae | ||
|
|
87715ff7cc | ||
|
|
dc2603d107 | ||
|
|
9483d537ce | ||
|
|
216d7c02fb | ||
|
|
2547590ce8 | ||
|
|
fd25873348 | ||
|
|
d9be2426c4 | ||
|
|
22a3914072 | ||
|
|
355f5b9591 | ||
|
|
513eb223be | ||
|
|
afef4fde9f | ||
|
|
4b43104400 | ||
|
|
28f8971e7f | ||
|
|
2f37334444 | ||
|
|
b1380d4a2f | ||
|
|
c832465e71 | ||
|
|
a2efb8d9af | ||
|
|
7bfa69e19e | ||
|
|
dc3c5a82a1 | ||
|
|
5c789232f1 | ||
|
|
164ed56671 | ||
|
|
51b849f882 | ||
|
|
851c024171 | ||
|
|
3beba561fc | ||
| 6e1965ba79 | |||
| 5df7a9e20f | |||
| 3e58fd1339 | |||
|
|
852e4ee03d | ||
|
|
3a09367e88 | ||
|
|
afb7b60a19 | ||
|
|
a32c12460a | ||
|
|
9af97134f4 | ||
|
|
5a33e4690d | ||
|
|
a81b8d50fb | ||
|
|
c7dd897909 | ||
|
|
741eccd933 | ||
|
|
3f31f68c60 | ||
|
|
2f1cd53493 | ||
|
|
9e953cd5d6 | ||
|
|
e653b0e40a | ||
|
|
847b89da23 | ||
|
|
af9ae3e763 | ||
|
|
f09cea096f | ||
|
|
4cc57322c0 | ||
|
|
496917c34c | ||
|
|
41bcc2a1ef | ||
|
|
0367e33768 | ||
|
|
f71cb56a40 | ||
|
|
0451b9e3e1 | ||
|
|
c1597c4a5c | ||
|
|
e277279f78 | ||
|
|
4815b43864 | ||
|
|
d43d151e75 | ||
|
|
d3b22ecf48 | ||
|
|
e452bd9255 | ||
|
|
64eb77674a | ||
|
|
2d0475246a | ||
|
|
e351adb5fa | ||
|
|
47e5df9ba9 | ||
|
|
eeb82dcbe1 | ||
|
|
f3d74681f3 | ||
|
|
f2a0b754b3 | ||
|
|
9f3388eb20 | ||
|
|
95513f0e10 | ||
|
|
37bd6cf6ee | ||
|
|
48baf99adf | ||
|
|
4da9dc6946 | ||
|
|
2b8713cbe0 | ||
|
|
0b407f3c68 | ||
|
|
8ce58201e9 | ||
|
|
3880ce6985 | ||
|
|
e55001e234 | ||
|
|
8f8bcd9cc8 | ||
|
|
01590c4894 | ||
|
|
e345331381 | ||
|
|
089e70c7c7 | ||
|
|
4d500fcdcd | ||
|
|
fffa6bc374 | ||
|
|
21029ca9ce | ||
|
|
ed0bde9780 | ||
| 06a6019e97 | |||
| 23b6070785 | |||
|
|
2240c383c7 | ||
|
|
505df8e8b1 | ||
|
|
5ba93feb52 | ||
|
|
ae3d5dab70 | ||
|
|
4382e779d7 | ||
|
|
42bdb66440 | ||
| f96aa09cc7 | |||
| ff89c2c791 | |||
|
|
249911b931 | ||
|
|
66d4a08f3c | ||
|
|
9bf7ee2e9a | ||
|
|
b5c967c5fc | ||
|
|
665e861303 | ||
|
|
c1a0a8c2b5 | ||
|
|
05e56ff6f7 | ||
|
|
10571679f1 | ||
|
|
a931dad4d9 | ||
|
|
a5404cef72 | ||
|
|
c25cb43720 | ||
|
|
34f0499986 | ||
|
|
7d39720121 | ||
|
|
91fc939b6d | ||
|
|
ca1a2c05c3 | ||
|
|
6f9116ead5 | ||
|
|
749b2b68a1 | ||
|
|
746f435ca8 | ||
|
|
16f6eb7b50 | ||
|
|
9d2dd44549 | ||
|
|
a710ebd297 | ||
|
|
124109bf57 | ||
|
|
414dae40cc | ||
|
|
ae2112f23a | ||
| c0383da15d | |||
|
|
28544df284 | ||
|
|
d54db7b58f | ||
|
|
04b17729e0 | ||
|
|
a7b8c2786c | ||
|
|
db483ce18d | ||
|
|
b90a0ad489 | ||
|
|
4ca6b7d842 | ||
|
|
16b0990454 | ||
|
|
92847e6be2 | ||
|
|
19c30e69df | ||
|
|
b4c169be75 | ||
|
|
e39c6f62c8 | ||
|
|
dd3c614679 | ||
|
|
e635e4ff61 | ||
|
|
ddc3d268be | ||
|
|
193cffa7c4 | ||
|
|
56501b5bcd | ||
|
|
0f705431d4 | ||
|
|
2730ac9174 | ||
|
|
b61e36e532 | ||
|
|
7b6e5635ea | ||
|
|
15385286da | ||
|
|
6b453b8bdf | ||
|
|
bec082a554 | ||
|
|
3659d03d94 | ||
|
|
d0b8c4ee35 | ||
|
|
cd54079a47 | ||
|
|
d408d875db | ||
|
|
58f52cbb84 | ||
|
|
1552225e9c | ||
|
|
5c215b9213 | ||
|
|
ed98f171ba | ||
|
|
e57274d446 | ||
|
|
bfc49ee9a6 | ||
|
|
0697cdd3ee | ||
|
|
4340454e41 | ||
|
|
c89ecf8cda | ||
|
|
864c348531 | ||
|
|
7db251aea9 | ||
|
|
ccb183dc95 | ||
|
|
28b573bfb8 | ||
|
|
885478f672 | ||
|
|
59be7ac619 | ||
|
|
50f3d22090 | ||
|
|
6fd3fff0c8 | ||
|
|
c6663b35c3 | ||
|
|
a4d2e5dc15 | ||
|
|
db20be6e50 | ||
|
|
221f700722 | ||
|
|
0bc0fb2c99 | ||
|
|
887d015276 | ||
|
|
179d61cc16 | ||
|
|
f68eae8120 | ||
|
|
d0a6f21e05 | ||
|
|
928df2d62c | ||
|
|
81d22c9f05 | ||
|
|
337bff8853 | ||
|
|
07e8136188 | ||
|
|
7716a6fd02 | ||
|
|
38edf0ea41 | ||
|
|
1d3f8973e0 | ||
|
|
e947f08f8e | ||
|
|
24d9da8412 | ||
|
|
e51ab03a5c | ||
|
|
e160e1e552 | ||
|
|
6dd057516f | ||
|
|
b1d198133f | ||
|
|
acd931f6f0 | ||
|
|
039431b3ce | ||
|
|
9f55dcb5a9 | ||
|
|
c0ff9d4eb2 | ||
|
|
4a13a7b06a | ||
|
|
9136cb8d8a | ||
|
|
9e9b3316e9 | ||
|
|
734b29c77c | ||
|
|
82a2dc42e6 | ||
|
|
31625d0418 | ||
|
|
26be9d691f | ||
|
|
18d93995aa | ||
|
|
34b8562ffe | ||
| 5f80de81a4 | |||
| 1054227c65 | |||
|
|
c5a57a1f1f | ||
|
|
c16f364b8a | ||
|
|
c9ed721cc0 | ||
|
|
8d7ca40e00 | ||
|
|
7b78dc6ce8 | ||
|
|
4cda0b52c8 | ||
|
|
ef9a42a97a | ||
|
|
8d1b37aef7 | ||
|
|
3542906e41 | ||
|
|
066f49cad7 | ||
|
|
775e72ba70 | ||
|
|
4e3faab969 | ||
|
|
94100e304e | ||
|
|
9e466a2422 | ||
|
|
15d8bb4365 | ||
|
|
0fb3fd1d06 | ||
|
|
60a46c9232 | ||
|
|
8460a96db0 | ||
|
|
1424b03aac | ||
|
|
dd8e87b994 | ||
|
|
9be78c8bdc | ||
|
|
3ba0607a80 | ||
|
|
44cd46effc | ||
| 3779128e6c | |||
| bcb7c7781c | |||
|
|
e4dccb5c1f | ||
|
|
f1460dd384 | ||
|
|
559d682dfd | ||
|
|
65fbf4582a | ||
|
|
92451af236 | ||
|
|
54e634d006 | ||
|
|
a7bf381d0a | ||
|
|
fcf76349f6 | ||
| a4c629b9bd | |||
| 6cb0ddff6b | |||
|
|
484ff73667 | ||
|
|
c1a20aca35 | ||
|
|
0ec841f826 | ||
|
|
eaa54a13f7 | ||
|
|
0af37b0ecc | ||
|
|
b8fef58b28 | ||
|
|
1b6cc4f014 | ||
|
|
71a1c48392 | ||
|
|
0cb17540b0 | ||
|
|
a8a988a372 | ||
|
|
de85a8f369 | ||
|
|
12fab7cc1f | ||
|
|
b812fab46a | ||
|
|
86fa8f5d41 | ||
|
|
11db0315e7 | ||
|
|
4bbb71d6e2 | ||
|
|
6c84542e94 | ||
|
|
2a6bef472b | ||
| 123501378b | |||
| dc8a3dc39c | |||
| 7a9053f5ce | |||
|
|
6f7b9bf3e6 | ||
|
|
950b5c4604 | ||
|
|
db8f425877 | ||
|
|
bf61ae65de | ||
|
|
86e711d616 | ||
|
|
772c9482aa | ||
|
|
8980c4a2ee | ||
|
|
3b95c4d2d1 | ||
|
|
4487214e95 | ||
|
|
b96f49bd54 | ||
|
|
7ba9a6df5a | ||
|
|
22f4fce080 | ||
|
|
e028dc5cf5 | ||
| 3882e11454 | |||
|
|
19ff8f2d65 | ||
|
|
35c6bc97a1 | ||
|
|
01dc27099e | ||
|
|
3d0994b29b | ||
|
|
e092604b97 | ||
|
|
11c84e0013 | ||
|
|
cea4e472e8 | ||
|
|
9b0f1f0b3e | ||
|
|
12aceb5e00 | ||
| 9718ff149c | |||
| 2120cd8014 | |||
| f74c8a1e38 | |||
| cdc0d9d1ee | |||
| ad0edf92a6 | |||
|
|
5953893e74 | ||
|
|
0e159182b0 | ||
|
|
ae990c0c5f | ||
| aa31ac0f06 | |||
| 8c530d9769 | |||
| 9e513d3f1a | |||
|
|
ea34087f11 | ||
|
|
764a27fbd5 | ||
|
|
077d20a779 | ||
|
|
da9ed437dc | ||
|
|
f953e24515 | ||
|
|
f4055d01c3 | ||
|
|
f6c6fe069d | ||
| 719bf7c44f | |||
| 7843da3bde | |||
|
|
e77757e324 | ||
|
|
b6aa239b57 | ||
|
|
5971933bab | ||
|
|
b40e6ad198 | ||
|
|
e1e9a89d6d | ||
|
|
fd17afb145 | ||
|
|
fec4095617 | ||
|
|
970e368ce4 | ||
|
|
45e4402b13 | ||
|
|
98f493ec97 | ||
|
|
91196ec876 | ||
|
|
5ea175ca77 | ||
|
|
2490c549e1 | ||
|
|
dbe6916782 | ||
|
|
08c144066b | ||
|
|
74281c697c | ||
|
|
a4447b9014 | ||
|
|
4fc2ee5ca0 | ||
|
|
5ec9580e96 | ||
| 4988427f9f | |||
| f332823819 | |||
| 252fe0ff9a | |||
| 9ec411eebb | |||
|
|
800a9a8f50 | ||
|
|
ce5f2e3389 | ||
|
|
056a768ac9 | ||
|
|
6d44f6e9c3 | ||
|
|
8a27795586 | ||
| 780eebea4d | |||
|
|
59edf6a716 | ||
| f81806f59f | |||
|
|
fe690f639d | ||
|
|
cb197caaf2 | ||
|
|
e6a73f1d19 | ||
|
|
177cefcccc | ||
| a0cc5b62ff | |||
|
|
339de6132e | ||
|
|
049a289467 | ||
|
|
7098a8620d | ||
|
|
cec878cb94 | ||
|
|
e7ba802279 | ||
|
|
01f16eaef4 | ||
|
|
e42dd1926b | ||
|
|
204a1abc4d | ||
|
|
9f0c03921d | ||
|
|
8b7bfb5ea0 | ||
|
|
7d88493a54 | ||
|
|
7d4642a2f3 | ||
|
|
b2141b0be7 | ||
|
|
b07b75c699 | ||
|
|
6616fc72a0 | ||
|
|
87e8c17309 | ||
|
|
8a3baab88f | ||
|
|
d0e5089a06 | ||
|
|
535fa21b87 | ||
|
|
0efa5badc1 | ||
|
|
3aa94c7b34 | ||
|
|
5c27f0d28d | ||
|
|
6d4f2f965a | ||
|
|
2852615d62 | ||
|
|
6afb95fe1b | ||
|
|
752b1a5479 | ||
|
|
cfb00597ba | ||
|
|
b1f9378424 | ||
|
|
9774291573 | ||
|
|
ff4019978f | ||
|
|
78bbfb7107 | ||
|
|
a8dc4b82db | ||
|
|
92e6d1ebfc | ||
|
|
0c32520802 | ||
|
|
f70fbff8f0 | ||
|
|
b861ddcdc7 | ||
|
|
50b3dde54e | ||
| 5380dad68e | |||
|
|
92b1c01efc | ||
| 43fb8a3b61 | |||
| 681f9ec0e4 | |||
|
|
ac1f371bbb | ||
|
|
f8932def1d | ||
|
|
9d4f1368d3 | ||
|
|
68f379bd59 | ||
|
|
35f590e1f3 | ||
|
|
afb1f83bdf | ||
|
|
74b2a817d3 | ||
|
|
19e913f68f | ||
|
|
d692ea4359 | ||
|
|
1bec091856 | ||
|
|
ae513bbbd5 | ||
|
|
d516e265e0 | ||
|
|
37d1ff3f40 | ||
|
|
2095cd7fb4 | ||
|
|
2ece06d82c | ||
|
|
102b5e21dc | ||
|
|
082f4b2f59 | ||
|
|
1b04e2dfc3 | ||
|
|
ed0af9661c | ||
|
|
97b050779a | ||
|
|
a6b256a39c | ||
|
|
549bbfcf52 | ||
| 322d4218bc | |||
| 68346f8096 | |||
| 3ee1da6a12 | |||
| d9dd45338e | |||
| 91afbdf2e3 | |||
| d1b3160847 | |||
|
|
825fbf6a2d | ||
|
|
dba085d55a | ||
| 164dc819ab | |||
| b636233bfd | |||
| 223e876152 | |||
|
|
294fc79425 | ||
|
|
304a742dac | ||
|
|
c7aa109479 | ||
| 4dc69285ea | |||
|
|
5604d7076e | ||
|
|
74f05fccfe | ||
|
|
febc07623b | ||
|
|
e170061cff | ||
|
|
66d44bdb93 | ||
|
|
fd6ba2253c | ||
|
|
67d88228c8 | ||
|
|
910dc53808 | ||
|
|
5b02c27c3f | ||
|
|
564a23988d | ||
|
|
ad70e8164c | ||
|
|
5d1f3755f7 | ||
|
|
8566987275 | ||
|
|
935e6e5a4b | ||
|
|
38d149c213 | ||
|
|
26ee5e476a | ||
|
|
d9d1a99497 | ||
|
|
3bb92d337a | ||
|
|
e18c9dbfa2 | ||
|
|
3bc9ee2c94 | ||
|
|
2573ce1a16 | ||
| 8dffddc425 | |||
| f5c76a5fac | |||
| f2fa09c01f | |||
| f9656fedcb | |||
|
|
229c83a565 | ||
|
|
90a958adde | ||
|
|
a521eb345d | ||
|
|
39acbb7f95 | ||
|
|
9f985b0bfc | ||
|
|
d88394984b | ||
|
|
00e8424329 | ||
|
|
7630cb4277 | ||
|
|
eef2e809dc | ||
|
|
fa10260013 | ||
|
|
a28ade80bf | ||
| 3f7c3e6852 | |||
| 9af64446e8 | |||
|
|
0b760a253f | ||
| b64bf10419 | |||
| cd957427cf | |||
|
|
83dce29faf | ||
|
|
7efd4c87cc | ||
|
|
d0369d5dda | ||
|
|
b1b8d96e57 | ||
|
|
e54dc98b48 | ||
|
|
692acf831a | ||
|
|
52a3d00a65 | ||
|
|
f3f2d25280 | ||
|
|
e409277518 | ||
|
|
0afd9a2a8d | ||
|
|
b042f471b4 | ||
|
|
72a7a73673 | ||
|
|
cfa675ac32 | ||
|
|
8c34bf857a | ||
|
|
93a7e25603 | ||
|
|
6b2348f070 | ||
|
|
1afe331397 | ||
|
|
035395f5a5 | ||
|
|
787383857f | ||
|
|
5a248f212d | ||
|
|
962d7ec7ff | ||
|
|
6a3868fd0d | ||
|
|
a1815ed7e7 | ||
|
|
30281ff2ab | ||
|
|
af420225d8 | ||
|
|
00c2370b19 | ||
|
|
ae3d705187 | ||
|
|
3e4299fb4c | ||
|
|
76ddcfc614 | ||
|
|
10196f44a8 | ||
|
|
58f7ab83e3 | ||
|
|
5f92b0c536 | ||
|
|
de61f55a0d | ||
|
|
2d0d5eb2b8 | ||
|
|
4b8c059677 | ||
|
|
ef5ec7dd85 | ||
|
|
3bf7cba244 | ||
|
|
bf97558614 | ||
|
|
8813668b43 | ||
|
|
b532eefa61 | ||
|
|
771b9b940a | ||
|
|
e15568b561 | ||
|
|
cc71cfbc38 | ||
|
|
449e31ba2a | ||
|
|
db2dd8b6bc | ||
|
|
82c6f5df4e | ||
|
|
eaeaaf94b1 | ||
|
|
12448ba0a4 | ||
|
|
348da62370 | ||
|
|
9cc90131e6 | ||
|
|
2510009cc6 | ||
|
|
5e891b96b7 | ||
|
|
1967ca004d | ||
|
|
c0d86a5b57 | ||
|
|
2bc134298f | ||
|
|
00568ad943 | ||
|
|
5f12c8279f | ||
|
|
db7b45013b | ||
|
|
965f9cff8a | ||
|
|
954a0fb9d8 | ||
|
|
e00740aa41 | ||
|
|
40b8c9ce77 | ||
|
|
15160c2018 | ||
|
|
7cd06be198 | ||
|
|
b5fb9ac84d | ||
|
|
57012f450d | ||
|
|
eb5de77b2d | ||
| 93d0c2711f | |||
|
|
be18edf0a6 | ||
|
|
de452596e8 | ||
|
|
d0415c8c25 | ||
|
|
f3e8330241 | ||
|
|
519ef2f143 | ||
|
|
e7753c280d | ||
|
|
c34d22a95d | ||
|
|
4822110533 | ||
|
|
9e99e985cd | ||
|
|
d08b4ca723 | ||
|
|
4dcb2c467d | ||
|
|
a678ce4553 | ||
|
|
fa7e81d89f | ||
|
|
b303d3c11b | ||
|
|
88c138762f | ||
|
|
62f2fd85cc | ||
|
|
5d8a0b842a | ||
|
|
c18d9a392a | ||
|
|
b06c128ca2 | ||
|
|
817f7a91ac | ||
|
|
2ddff83103 | ||
|
|
bebd9620a5 | ||
|
|
a951378b1f | ||
|
|
50a16d55e4 | ||
|
|
2efc1910f6 | ||
|
|
528e9a63e4 | ||
|
|
5f303cce48 | ||
|
|
dff4d05665 | ||
|
|
560cdae209 | ||
|
|
3cad108cef | ||
|
|
ddb541c819 | ||
|
|
4970659f0a | ||
|
|
0f75dad798 | ||
|
|
8e4ed43a9d | ||
|
|
df1e5dd103 | ||
|
|
f792fd713a | ||
|
|
52e993d0e6 | ||
|
|
0f74869a8c | ||
|
|
119fa939ab | ||
|
|
1de9e837f4 | ||
|
|
46f45d361a | ||
|
|
e7728d71bd | ||
|
|
2960934af9 | ||
|
|
b98b02ac98 | ||
|
|
ae67d4381d | ||
|
|
6713ec6cf0 | ||
|
|
0df7f2ebf3 | ||
|
|
489a350ff1 | ||
|
|
a31447c278 | ||
|
|
c724246081 | ||
|
|
4cb5ff7102 | ||
|
|
6c095a27f7 | ||
|
|
b041933e5c | ||
|
|
4c80c26508 | ||
|
|
6f3d6f9d72 | ||
|
|
29f8740114 | ||
|
|
248d400666 | ||
|
|
1a8d4a051c | ||
|
|
b0765fa2ca | ||
|
|
400ed73809 | ||
|
|
5e4394fd33 | ||
|
|
d356332718 | ||
|
|
6eb4862eb3 | ||
|
|
76c722137d | ||
|
|
3c1182ff26 | ||
|
|
b9814bd346 | ||
|
|
bafb56efb9 | ||
|
|
5ef296851b | ||
|
|
20eced3e86 | ||
|
|
57e8d68d96 | ||
|
|
9aa3c4dcb4 | ||
|
|
5dac4819ad | ||
|
|
f58ba90f62 | ||
|
|
f2df44cf6a | ||
|
|
d8d3838d5c | ||
|
|
380bb5ec60 | ||
|
|
03a6d208be | ||
|
|
142f87ce57 | ||
|
|
4bec812d25 | ||
|
|
835b0ce337 | ||
|
|
75a6dd7e68 | ||
| 3bbf4e26e7 | |||
| cea266afdb | |||
|
|
33be7f1121 | ||
|
|
cf56ef9297 | ||
|
|
83fc05c774 | ||
|
|
e989d6c584 | ||
|
|
a583dc7c42 | ||
|
|
f8f63e312f | ||
|
|
617176f1b0 | ||
|
|
5f753d8c4e | ||
|
|
111b638d9e | ||
|
|
38259fdea5 | ||
|
|
e5f8b5b9f0 | ||
|
|
6b680cb9dd | ||
|
|
5e77bb23f3 | ||
|
|
15cb83db64 | ||
|
|
3bac0e2e88 | ||
|
|
0de7d62679 | ||
|
|
ab4fb64f83 | ||
|
|
7f0ced5a2d | ||
|
|
edd5bfe0c2 | ||
|
|
1c7b3b1c6c | ||
|
|
d5a44b5ec0 | ||
|
|
c694f08dbe | ||
|
|
c8b5c6eaa9 | ||
|
|
3e63a99ce0 | ||
|
|
8ef340b75b | ||
|
|
74655b87ff | ||
|
|
037435b3bc | ||
|
|
85d9754db6 | ||
|
|
d128960111 | ||
|
|
61b6f77d85 | ||
|
|
a8bd7e3dab | ||
|
|
345de97657 | ||
|
|
5c016fafbd | ||
|
|
dd170565b5 | ||
|
|
7655b11690 | ||
|
|
1290da7211 | ||
|
|
604b234c4b | ||
|
|
e862829246 | ||
|
|
79ce6fc569 | ||
|
|
2f3a68254e | ||
|
|
93f8fa5832 | ||
|
|
569f0f7fd9 | ||
|
|
ac60b954d4 | ||
|
|
63a9d4226c | ||
|
|
7309ba9855 | ||
|
|
197bcd2307 | ||
|
|
9dc513f7a9 | ||
|
|
78ebcd3a4e | ||
|
|
a2bc5f116b | ||
|
|
4cf3f15fb8 | ||
|
|
a09a732ff1 | ||
|
|
9567181117 | ||
|
|
d5a2042d35 | ||
|
|
3419a314e1 | ||
|
|
065d3e91bf | ||
|
|
f908a3b065 | ||
|
|
64f0e99283 | ||
|
|
1374757bf2 | ||
|
|
139969b324 | ||
|
|
bce6732bdb | ||
|
|
0e5946db71 | ||
|
|
874d310b35 | ||
|
|
a3ed79227b | ||
|
|
27aa7a773d | ||
|
|
9b6db93a5f | ||
|
|
14b3c386e0 | ||
|
|
938bfe0c4f | ||
| d3d7179c48 | |||
| a0cc233846 | |||
| 47e8290cd2 | |||
|
|
2a3d9d004f | ||
|
|
3ac91dfd28 | ||
|
|
9f41ca5dd4 | ||
|
|
04b20e49c9 | ||
| 0c80c69b12 | |||
|
|
ec8a6de291 | ||
|
|
c842aad1e9 | ||
| e030d54b9a | |||
|
|
f5130a4c3c | ||
|
|
0cb940a927 | ||
| e5bb186925 | |||
|
|
bdded23e1a | ||
| c954185717 | |||
| 05a5897dc7 | |||
|
|
7a96917926 | ||
| a1cd8ac9a3 | |||
| a84a1a7776 | |||
| f1ab73fd39 | |||
|
|
90f3a7bfe5 | ||
| 1496c1a438 | |||
| 048a17224b | |||
| c34399b855 | |||
| 0456e7b727 | |||
|
|
99a3cfd052 | ||
|
|
e8cf09b7ac | ||
|
|
e59f242427 | ||
|
|
bb9e79b06c | ||
|
|
069f427459 | ||
|
|
d67e0450e5 | ||
| f85c0cf636 | |||
| 0fd8e81d71 | |||
|
|
3fefb1bb43 | ||
|
|
55ac7afc1d | ||
| 172a917086 | |||
|
|
711431a5b7 | ||
|
|
8097555951 | ||
|
|
0151704cd5 | ||
|
|
b3c752d2e6 | ||
|
|
4023a710e7 | ||
|
|
67f6be635c | ||
|
|
a098620b7b | ||
|
|
689c425acb | ||
|
|
722a1e33a8 | ||
|
|
bba2fcf2a9 | ||
|
|
affa53c633 | ||
|
|
759d98be61 | ||
|
|
d823d3a4ae | ||
|
|
a64c5491d4 | ||
|
|
e53a4639a6 | ||
|
|
1b83e2bf19 | ||
|
|
26ed6c4703 | ||
|
|
5319aa607b | ||
|
|
7bccbb9632 | ||
|
|
5a208ebb17 | ||
|
|
426d064476 | ||
|
|
a0008b6254 | ||
|
|
aea156e22f | ||
|
|
6c37bc5e72 | ||
|
|
8575cb7141 | ||
|
|
114ef1c01e | ||
|
|
f8c62a1cde | ||
|
|
f5355728ab | ||
|
|
0bac3630ec | ||
|
|
a27f3551d8 | ||
|
|
cf7a79166a | ||
|
|
c0749bdc20 | ||
|
|
127f21dc43 | ||
|
|
e1533a5c23 | ||
|
|
f0fe68d851 | ||
|
|
f827ed558c | ||
|
|
1095c0c81f | ||
|
|
169b3428e7 | ||
|
|
451d5d28bc | ||
|
|
6a9e069920 | ||
|
|
c9e2c91ab4 | ||
|
|
794f066bb8 | ||
|
|
c9a4fb674e | ||
|
|
02402542b2 | ||
|
|
f6341eb399 | ||
|
|
b67c666f81 | ||
|
|
8c540b6568 | ||
|
|
6bb5c90964 | ||
|
|
197f8f7150 | ||
|
|
c802ab718f | ||
|
|
c62981e93c | ||
|
|
36541f075a | ||
|
|
35c9d32f8b | ||
|
|
033fc915d0 | ||
|
|
bcf0c0bfdb | ||
|
|
a2a8aee819 | ||
|
|
1960f243d0 | ||
|
|
1a6fe487aa | ||
|
|
8e6a45952a | ||
|
|
5731ac6f3d | ||
|
|
96a2c8d94f | ||
|
|
49eb785a92 | ||
|
|
6a789e0804 | ||
|
|
6b89316ab6 | ||
|
|
2ae1b13440 | ||
|
|
9dd0f1e037 | ||
|
|
8411968b17 | ||
|
|
dfa87f98bb | ||
|
|
00186924fb | ||
|
|
338163de35 | ||
|
|
8a4d843fa2 | ||
|
|
03ac050ef9 | ||
|
|
fec199cdd9 | ||
|
|
99027059c5 | ||
|
|
33f979c5ad | ||
|
|
43e6593599 | ||
|
|
940405e2e6 | ||
|
|
b707c25f89 | ||
|
|
36effb3431 | ||
|
|
907b7143ff | ||
|
|
92a162f93e | ||
|
|
7d8a80e9df | ||
|
|
186a3ee76a | ||
|
|
b37ca083ba | ||
|
|
41d28c4d7f | ||
|
|
54b90e1472 | ||
|
|
6b9407f02a | ||
|
|
bef050f835 | ||
|
|
ec4d0ea309 | ||
|
|
b3fb153bbf | ||
|
|
f0b8724698 | ||
|
|
12733ea779 | ||
|
|
8ad90f18f0 | ||
|
|
a393be5c64 | ||
|
|
4a1a935112 | ||
|
|
9c696be46e | ||
|
|
aaa180e217 | ||
|
|
6614e3a2fb | ||
|
|
0b6ba817f6 | ||
|
|
e556eeb314 | ||
|
|
a911648907 | ||
|
|
89ef146c19 | ||
|
|
8902080336 | ||
|
|
d3034c1a06 | ||
|
|
0a0e2c3ca1 | ||
|
|
59340500b7 | ||
|
|
9d90c98800 | ||
|
|
d858010414 | ||
|
|
b753901b95 | ||
|
|
0b13d5ccf2 | ||
|
|
5ccb5f64b8 | ||
|
|
56d5eb0228 | ||
|
|
e27577bccb | ||
|
|
5770b41ad7 | ||
|
|
8799fcbcbc | ||
|
|
a302956a6d | ||
|
|
2ad923c737 | ||
|
|
b738a50675 | ||
|
|
8b80d44b8e | ||
|
|
4c0ee142f5 | ||
|
|
4a6f53cbd6 | ||
|
|
ca90b44c74 | ||
|
|
f5ec2a57e5 | ||
|
|
0fcccfb9ec | ||
|
|
509aefabff | ||
|
|
619f54d8a9 | ||
|
|
e51f4472c2 | ||
|
|
3b6d444ad6 | ||
|
|
84bb010535 | ||
|
|
0234925827 | ||
|
|
bc37746aa5 | ||
|
|
8d700d273f | ||
|
|
f1ad524b89 | ||
|
|
320fb3386e | ||
|
|
38be118e15 | ||
|
|
6c42209217 | ||
|
|
a9eabbab2e | ||
|
|
00bf1f9cc8 | ||
|
|
6554971c3c | ||
|
|
d94e54b72d | ||
|
|
29d892a20e | ||
|
|
2a20ac3d9d | ||
|
|
e060bd04ce | ||
|
|
ef9e5739ad | ||
|
|
08ea6d1253 | ||
|
|
2678b7fc59 | ||
|
|
a2615c7b52 | ||
|
|
a1f866bcbe | ||
|
|
8f318e62da | ||
|
|
7c0b7f1aa7 | ||
|
|
b0062b57a1 | ||
|
|
02c5d5b6ca | ||
|
|
451806fd00 | ||
|
|
4cc64ab2c0 | ||
|
|
da6e4acc52 | ||
|
|
cdfb282c32 | ||
|
|
8d58afdcde | ||
|
|
2fc1587d18 | ||
|
|
31ac8f9299 | ||
|
|
ae1cccb600 | ||
|
|
d7677ac2a5 | ||
|
|
6591679d79 | ||
|
|
4d1a853472 | ||
|
|
26ccf67dad | ||
|
|
def2b8f7fe | ||
|
|
37c666062f | ||
|
|
8b10a65d2a | ||
|
|
417c7b0071 | ||
|
|
92e298c745 | ||
|
|
410db00812 | ||
|
|
88f627a2c6 | ||
|
|
6586fe0bab | ||
|
|
b3ed889433 | ||
|
|
70f45340be | ||
|
|
d7bed1516f | ||
|
|
509a9933b0 | ||
|
|
0ed2d4c389 | ||
|
|
41474b407d | ||
|
|
a35cc0bdef | ||
|
|
468bd38e0b | ||
|
|
860e83c463 | ||
|
|
ab129896ae | ||
|
|
c1cfaa3b6d | ||
|
|
877e7f19c9 | ||
| 1086b9c4af | |||
| c06cc7bcf6 | |||
|
|
334d87889b | ||
|
|
89db1cf5cc | ||
|
|
2c29e71ca2 | ||
| 4ff98c7e44 | |||
| f82a224aee | |||
| b3fa16310f | |||
|
|
1134267acf | ||
|
|
f9a3c8c318 | ||
|
|
c85bece782 | ||
|
|
e47eca3235 | ||
|
|
0495d0f647 | ||
|
|
c60c647a81 | ||
|
|
89b4c71dbd | ||
|
|
2d2869120d | ||
|
|
10c64c0595 | ||
|
|
18aa77b3ad | ||
|
|
1ae6f5e8d1 | ||
|
|
730b86a5d4 | ||
|
|
27fd503d9e | ||
|
|
699bafc59f | ||
|
|
8e967a1fa8 | ||
|
|
bb87b8f809 | ||
|
|
1c8c0bc537 | ||
|
|
70815b47f2 | ||
|
|
a89b8e0453 | ||
|
|
6c09c68c5c | ||
|
|
ee2aa136b9 | ||
|
|
ee72e497e2 | ||
|
|
3f5797458f | ||
|
|
e6be7912ef | ||
|
|
b7120551b5 | ||
|
|
bd7fe04395 | ||
|
|
b7fd1b38a6 | ||
|
|
206ce4b2b1 | ||
|
|
d47df139ed | ||
|
|
ee2a0f1e36 | ||
|
|
be1c390bb8 | ||
|
|
94980d9157 | ||
|
|
1828685e0e | ||
|
|
66d491a2af | ||
|
|
b7f19d7077 | ||
|
|
afe16503ee | ||
|
|
63b02dcc4c | ||
|
|
2a3a151f34 | ||
|
|
fb6a83b36a | ||
|
|
4df68a5605 | ||
|
|
2a17eff17d | ||
|
|
94c43e5479 | ||
|
|
7876063288 | ||
|
|
083d48c24c | ||
|
|
9491a3db29 | ||
|
|
db712d586a | ||
|
|
18d75f4b04 | ||
|
|
57164f5d45 | ||
|
|
dc91f81262 | ||
|
|
0afe06fac0 | ||
|
|
66c97a162b | ||
| b89c3301e3 | |||
|
|
82e97ded24 | ||
|
|
0ed8935b4c | ||
|
|
1393969516 | ||
|
|
adada88230 | ||
|
|
06af1fc632 | ||
|
|
eea8e1ff81 | ||
|
|
e5be00e7f3 | ||
|
|
8752877b52 | ||
|
|
e45cf014b1 | ||
|
|
c704556891 | ||
|
|
1f4cee21c7 | ||
|
|
e52e9e0c05 | ||
|
|
b99330e94b | ||
|
|
eab1371eb1 | ||
|
|
d303cf6c06 | ||
|
|
b2fc8eb288 | ||
|
|
70f5686bf9 | ||
|
|
2f51a4e26e | ||
|
|
96fdea3b35 | ||
|
|
491ee1a302 | ||
|
|
1d9da7c856 | ||
|
|
8f278b608d | ||
|
|
c031311429 | ||
|
|
293c238d84 | ||
|
|
49fdfa62db | ||
|
|
31c21469ec | ||
|
|
e86c9c5dc1 | ||
|
|
ffd8974cb6 | ||
|
|
4ae2566a72 | ||
|
|
9de3ad7ca0 | ||
|
|
f2a0d1ca86 | ||
|
|
47c1f7dac0 | ||
|
|
34da86653f | ||
|
|
c0d7aa92cc | ||
|
|
5baa3f096b | ||
|
|
3b4a641525 | ||
|
|
0f4356bc86 | ||
|
|
89d4d677de | ||
|
|
38db4ed802 | ||
|
|
5e7322caed | ||
|
|
2dd5aa1e33 | ||
|
|
9b81e22599 | ||
|
|
1c1347bb93 | ||
|
|
33526755ac | ||
|
|
78b0ad7d1d | ||
|
|
a1bd2ec4b8 | ||
|
|
ce746e4034 | ||
|
|
00ffa455fd | ||
|
|
73ece9ee40 | ||
|
|
c6619f1253 | ||
|
|
9412f09f71 | ||
|
|
ee4ef41547 | ||
|
|
f76b2bfaa9 | ||
|
|
4bc76d3211 | ||
|
|
bb637bca36 | ||
|
|
eba7e0b656 | ||
|
|
45b87f54c7 | ||
|
|
f60beb9f36 | ||
|
|
9ebef6aedf | ||
|
|
f48d020536 | ||
|
|
77c9a90a08 | ||
|
|
a5a2c32f2d | ||
|
|
23aa59a416 | ||
|
|
640976c90d | ||
|
|
45703e5596 | ||
|
|
7f1a3e2f80 | ||
|
|
1c27d7eae2 | ||
|
|
3e9278784a | ||
|
|
4c40a50eb3 | ||
|
|
82e6ce6d11 |
901 changed files with 2204322 additions and 26020 deletions
|
|
@ -23,3 +23,11 @@
|
|||
**/values.dev.yaml
|
||||
LICENSE
|
||||
README.md
|
||||
.git
|
||||
**/bin/
|
||||
**/obj/
|
||||
.vscode/
|
||||
.dockerignore
|
||||
.gitignore
|
||||
README.md
|
||||
*.md
|
||||
83
.forgejo/workflows/build-checkin.yml
Normal file
83
.forgejo/workflows/build-checkin.yml
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
name: Build & Deploy Checkin Service
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "checkin-dev[0-9]+.[0-9]+.[0-9]+"
|
||||
- "checkin-dev[0-9]+.[0-9]+.[0-9]+*"
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
REGISTRY: ${{ vars.CONTAINER_REGISTRY }}
|
||||
REGISTRY_USERNAME: ${{ vars.CONTAINER_REGISTRY_USERNAME }}
|
||||
REGISTRY_PASSWORD: ${{ secrets.CONTAINER_REGISTRY_PASSWORD }}
|
||||
CONTAINER_IMAGE_NAME: ${{ vars.CONTAINER_REGISTRY }}/${{ vars.CONTAINER_IMAGE_OWNER }}
|
||||
IMAGE_VERSION: latest
|
||||
SERVICE_NAME: hrms-api-checkin
|
||||
DISCORD_WEBHOOK: ${{ vars.DISCORD_WEBHOOK }}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Tag Version
|
||||
shell: bash
|
||||
run: |
|
||||
if [[ "${{ github.event_name }}" == "push" ]]; then
|
||||
VERSION=$(echo "${{ github.ref_name }}" | sed 's/checkin-dev//g')
|
||||
echo "IMAGE_VERSION=${VERSION}" >> $GITHUB_ENV
|
||||
else
|
||||
echo "IMAGE_VERSION=${{ env.IMAGE_VERSION }}-${{ github.run_number }}" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: Login in to registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ env.REGISTRY_USERNAME }}
|
||||
password: ${{ env.REGISTRY_PASSWORD }}
|
||||
|
||||
- name: Build and push docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
platforms: linux/amd64
|
||||
context: .
|
||||
file: ./BMA.EHR.CheckInConsumer/Dockerfile
|
||||
tags: ${{ env.CONTAINER_IMAGE_NAME }}/${{ env.SERVICE_NAME }}:latest,${{ env.CONTAINER_IMAGE_NAME }}/${{ env.SERVICE_NAME }}:${{ env.IMAGE_VERSION }}
|
||||
push: true
|
||||
|
||||
- name: Remote Deploy
|
||||
uses: appleboy/ssh-action@v1.2.1
|
||||
with:
|
||||
host: ${{ vars.SSH_DEPLOY_HOST }}
|
||||
port: ${{ vars.SSH_DEPLOY_PORT }}
|
||||
username: ${{ secrets.SSH_DEPLOY_USER }}
|
||||
password: ${{ secrets.SSH_DEPLOY_PASSWORD }}
|
||||
script: |
|
||||
cd ~/repo
|
||||
./replace-env.sh API_CHECKIN "${{ env.IMAGE_VERSION }}"
|
||||
./deploy.sh ${{ env.SERVICE_NAME }}
|
||||
|
||||
- name: Discord Notification
|
||||
if: always()
|
||||
run: |
|
||||
STATUS="${{ job.status == 'success' && '✅ Success' || '❌ Failed' }}"
|
||||
COLOR="${{ job.status == 'success' && '3066993' || '15158332' }}"
|
||||
TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||
curl -H "Content-Type: application/json" \
|
||||
-X POST \
|
||||
-d "{
|
||||
\"embeds\": [{
|
||||
\"title\": \"$STATUS\",
|
||||
\"description\": \"**Build & Deploy**\\n- Image: \`${{ env.CONTAINER_IMAGE_NAME }}/${{ env.SERVICE_NAME }}\`\\n- Version: \`${{ env.IMAGE_VERSION }}\`\\n- By: \`${{ gitea.actor }}\`\",
|
||||
\"color\": $COLOR,
|
||||
\"footer\": {
|
||||
\"text\": \"Release Notification\",
|
||||
\"icon_url\": \"https://example.com/success-icon.png\"
|
||||
},
|
||||
\"timestamp\": \"$TIMESTAMP\"
|
||||
}]
|
||||
}" \
|
||||
${{ env.DISCORD_WEBHOOK }}
|
||||
83
.forgejo/workflows/build-discipline.yml
Normal file
83
.forgejo/workflows/build-discipline.yml
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
name: Build & Deploy Discipline Service
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "discipline-dev[0-9]+.[0-9]+.[0-9]+"
|
||||
- "discipline-dev[0-9]+.[0-9]+.[0-9]+*"
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
REGISTRY: ${{ vars.CONTAINER_REGISTRY }}
|
||||
REGISTRY_USERNAME: ${{ vars.CONTAINER_REGISTRY_USERNAME }}
|
||||
REGISTRY_PASSWORD: ${{ secrets.CONTAINER_REGISTRY_PASSWORD }}
|
||||
CONTAINER_IMAGE_NAME: ${{ vars.CONTAINER_REGISTRY }}/${{ vars.CONTAINER_IMAGE_OWNER }}
|
||||
IMAGE_VERSION: latest
|
||||
SERVICE_NAME: hrms-api-discipline
|
||||
DISCORD_WEBHOOK: ${{ vars.DISCORD_WEBHOOK }}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Tag Version
|
||||
shell: bash
|
||||
run: |
|
||||
if [[ "${{ github.event_name }}" == "push" ]]; then
|
||||
VERSION=$(echo "${{ github.ref_name }}" | sed 's/discipline-dev//g')
|
||||
echo "IMAGE_VERSION=${VERSION}" >> $GITHUB_ENV
|
||||
else
|
||||
echo "IMAGE_VERSION=${{ env.IMAGE_VERSION }}-${{ github.run_number }}" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: Login in to registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ env.REGISTRY_USERNAME }}
|
||||
password: ${{ env.REGISTRY_PASSWORD }}
|
||||
|
||||
- name: Build and push docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
platforms: linux/amd64
|
||||
context: .
|
||||
file: ./BMA.EHR.Discipline.Service/Dockerfile
|
||||
tags: ${{ env.CONTAINER_IMAGE_NAME }}/${{ env.SERVICE_NAME }}:latest,${{ env.CONTAINER_IMAGE_NAME }}/${{ env.SERVICE_NAME }}:${{ env.IMAGE_VERSION }}
|
||||
push: true
|
||||
|
||||
- name: Remote Deploy
|
||||
uses: appleboy/ssh-action@v1.2.1
|
||||
with:
|
||||
host: ${{ vars.SSH_DEPLOY_HOST }}
|
||||
port: ${{ vars.SSH_DEPLOY_PORT }}
|
||||
username: ${{ secrets.SSH_DEPLOY_USER }}
|
||||
password: ${{ secrets.SSH_DEPLOY_PASSWORD }}
|
||||
script: |
|
||||
cd ~/repo
|
||||
./replace-env.sh API_DISCIPLINE "${{ env.IMAGE_VERSION }}"
|
||||
./deploy.sh ${{ env.SERVICE_NAME }}
|
||||
|
||||
- name: Discord Notification
|
||||
if: always()
|
||||
run: |
|
||||
STATUS="${{ job.status == 'success' && '✅ Success' || '❌ Failed' }}"
|
||||
COLOR="${{ job.status == 'success' && '3066993' || '15158332' }}"
|
||||
TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||
curl -H "Content-Type: application/json" \
|
||||
-X POST \
|
||||
-d "{
|
||||
\"embeds\": [{
|
||||
\"title\": \"$STATUS\",
|
||||
\"description\": \"**Build & Deploy**\\n- Image: \`${{ env.CONTAINER_IMAGE_NAME }}/${{ env.SERVICE_NAME }}\`\\n- Version: \`${{ env.IMAGE_VERSION }}\`\\n- By: \`${{ gitea.actor }}\`\",
|
||||
\"color\": $COLOR,
|
||||
\"footer\": {
|
||||
\"text\": \"Release Notification\",
|
||||
\"icon_url\": \"https://example.com/success-icon.png\"
|
||||
},
|
||||
\"timestamp\": \"$TIMESTAMP\"
|
||||
}]
|
||||
}" \
|
||||
${{ env.DISCORD_WEBHOOK }}
|
||||
83
.forgejo/workflows/build-insignia.yml
Normal file
83
.forgejo/workflows/build-insignia.yml
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
name: Build & Deploy Insignia Service
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "insignia-dev[0-9]+.[0-9]+.[0-9]+"
|
||||
- "insignia-dev[0-9]+.[0-9]+.[0-9]+*"
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
REGISTRY: ${{ vars.CONTAINER_REGISTRY }}
|
||||
REGISTRY_USERNAME: ${{ vars.CONTAINER_REGISTRY_USERNAME }}
|
||||
REGISTRY_PASSWORD: ${{ secrets.CONTAINER_REGISTRY_PASSWORD }}
|
||||
CONTAINER_IMAGE_NAME: ${{ vars.CONTAINER_REGISTRY }}/${{ vars.CONTAINER_IMAGE_OWNER }}
|
||||
IMAGE_VERSION: latest
|
||||
SERVICE_NAME: hrms-api-insignia
|
||||
DISCORD_WEBHOOK: ${{ vars.DISCORD_WEBHOOK }}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Tag Version
|
||||
shell: bash
|
||||
run: |
|
||||
if [[ "${{ github.event_name }}" == "push" ]]; then
|
||||
VERSION=$(echo "${{ github.ref_name }}" | sed 's/insignia-dev//g')
|
||||
echo "IMAGE_VERSION=${VERSION}" >> $GITHUB_ENV
|
||||
else
|
||||
echo "IMAGE_VERSION=${{ env.IMAGE_VERSION }}-${{ github.run_number }}" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: Login in to registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ env.REGISTRY_USERNAME }}
|
||||
password: ${{ env.REGISTRY_PASSWORD }}
|
||||
|
||||
- name: Build and push docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
platforms: linux/amd64
|
||||
context: .
|
||||
file: ./BMA.EHR.Insignia/Dockerfile
|
||||
tags: ${{ env.CONTAINER_IMAGE_NAME }}/${{ env.SERVICE_NAME }}:latest,${{ env.CONTAINER_IMAGE_NAME }}/${{ env.SERVICE_NAME }}:${{ env.IMAGE_VERSION }}
|
||||
push: true
|
||||
|
||||
- name: Remote Deploy
|
||||
uses: appleboy/ssh-action@v1.2.1
|
||||
with:
|
||||
host: ${{ vars.SSH_DEPLOY_HOST }}
|
||||
port: ${{ vars.SSH_DEPLOY_PORT }}
|
||||
username: ${{ secrets.SSH_DEPLOY_USER }}
|
||||
password: ${{ secrets.SSH_DEPLOY_PASSWORD }}
|
||||
script: |
|
||||
cd ~/repo
|
||||
./replace-env.sh API_INSIGNIA "${{ env.IMAGE_VERSION }}"
|
||||
./deploy.sh ${{ env.SERVICE_NAME }}
|
||||
|
||||
- name: Discord Notification
|
||||
if: always()
|
||||
run: |
|
||||
STATUS="${{ job.status == 'success' && '✅ Success' || '❌ Failed' }}"
|
||||
COLOR="${{ job.status == 'success' && '3066993' || '15158332' }}"
|
||||
TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||
curl -H "Content-Type: application/json" \
|
||||
-X POST \
|
||||
-d "{
|
||||
\"embeds\": [{
|
||||
\"title\": \"$STATUS\",
|
||||
\"description\": \"**Build & Deploy**\\n- Image: \`${{ env.CONTAINER_IMAGE_NAME }}/${{ env.SERVICE_NAME }}\`\\n- Version: \`${{ env.IMAGE_VERSION }}\`\\n- By: \`${{ gitea.actor }}\`\",
|
||||
\"color\": $COLOR,
|
||||
\"footer\": {
|
||||
\"text\": \"Release Notification\",
|
||||
\"icon_url\": \"https://example.com/success-icon.png\"
|
||||
},
|
||||
\"timestamp\": \"$TIMESTAMP\"
|
||||
}]
|
||||
}" \
|
||||
${{ env.DISCORD_WEBHOOK }}
|
||||
83
.forgejo/workflows/build-leave.yml
Normal file
83
.forgejo/workflows/build-leave.yml
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
name: Build & Deploy Leave Service
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "leave-dev[0-9]+.[0-9]+.[0-9]+"
|
||||
- "leave-dev[0-9]+.[0-9]+.[0-9]+*"
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
REGISTRY: ${{ vars.CONTAINER_REGISTRY }}
|
||||
REGISTRY_USERNAME: ${{ vars.CONTAINER_REGISTRY_USERNAME }}
|
||||
REGISTRY_PASSWORD: ${{ secrets.CONTAINER_REGISTRY_PASSWORD }}
|
||||
CONTAINER_IMAGE_NAME: ${{ vars.CONTAINER_REGISTRY }}/${{ vars.CONTAINER_IMAGE_OWNER }}
|
||||
IMAGE_VERSION: latest
|
||||
SERVICE_NAME: hrms-api-leave
|
||||
DISCORD_WEBHOOK: ${{ vars.DISCORD_WEBHOOK }}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Tag Version
|
||||
shell: bash
|
||||
run: |
|
||||
if [[ "${{ github.event_name }}" == "push" ]]; then
|
||||
VERSION=$(echo "${{ github.ref_name }}" | sed 's/leave-dev//g')
|
||||
echo "IMAGE_VERSION=${VERSION}" >> $GITHUB_ENV
|
||||
else
|
||||
echo "IMAGE_VERSION=${{ env.IMAGE_VERSION }}-${{ github.run_number }}" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: Login in to registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ env.REGISTRY_USERNAME }}
|
||||
password: ${{ env.REGISTRY_PASSWORD }}
|
||||
|
||||
- name: Build and push docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
platforms: linux/amd64
|
||||
context: .
|
||||
file: ./BMA.EHR.Leave/Dockerfile
|
||||
tags: ${{ env.CONTAINER_IMAGE_NAME }}/${{ env.SERVICE_NAME }}:latest,${{ env.CONTAINER_IMAGE_NAME }}/${{ env.SERVICE_NAME }}:${{ env.IMAGE_VERSION }}
|
||||
push: true
|
||||
|
||||
- name: Remote Deploy
|
||||
uses: appleboy/ssh-action@v1.2.1
|
||||
with:
|
||||
host: ${{ vars.SSH_DEPLOY_HOST }}
|
||||
port: ${{ vars.SSH_DEPLOY_PORT }}
|
||||
username: ${{ secrets.SSH_DEPLOY_USER }}
|
||||
password: ${{ secrets.SSH_DEPLOY_PASSWORD }}
|
||||
script: |
|
||||
cd ~/repo
|
||||
./replace-env.sh API_LEAVE "${{ env.IMAGE_VERSION }}"
|
||||
./deploy.sh ${{ env.SERVICE_NAME }}
|
||||
|
||||
- name: Discord Notification
|
||||
if: always()
|
||||
run: |
|
||||
STATUS="${{ job.status == 'success' && '✅ Success' || '❌ Failed' }}"
|
||||
COLOR="${{ job.status == 'success' && '3066993' || '15158332' }}"
|
||||
TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||
curl -H "Content-Type: application/json" \
|
||||
-X POST \
|
||||
-d "{
|
||||
\"embeds\": [{
|
||||
\"title\": \"$STATUS\",
|
||||
\"description\": \"**Build & Deploy**\\n- Image: \`${{ env.CONTAINER_IMAGE_NAME }}/${{ env.SERVICE_NAME }}\`\\n- Version: \`${{ env.IMAGE_VERSION }}\`\\n- By: \`${{ gitea.actor }}\`\",
|
||||
\"color\": $COLOR,
|
||||
\"footer\": {
|
||||
\"text\": \"Release Notification\",
|
||||
\"icon_url\": \"https://example.com/success-icon.png\"
|
||||
},
|
||||
\"timestamp\": \"$TIMESTAMP\"
|
||||
}]
|
||||
}" \
|
||||
${{ env.DISCORD_WEBHOOK }}
|
||||
83
.forgejo/workflows/build-placement.yml
Normal file
83
.forgejo/workflows/build-placement.yml
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
name: Build & Deploy Placement Service
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "placement-dev[0-9]+.[0-9]+.[0-9]+"
|
||||
- "placement-dev[0-9]+.[0-9]+.[0-9]+*"
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
REGISTRY: ${{ vars.CONTAINER_REGISTRY }}
|
||||
REGISTRY_USERNAME: ${{ vars.CONTAINER_REGISTRY_USERNAME }}
|
||||
REGISTRY_PASSWORD: ${{ secrets.CONTAINER_REGISTRY_PASSWORD }}
|
||||
CONTAINER_IMAGE_NAME: ${{ vars.CONTAINER_REGISTRY }}/${{ vars.CONTAINER_IMAGE_OWNER }}
|
||||
IMAGE_VERSION: latest
|
||||
SERVICE_NAME: hrms-api-placement
|
||||
DISCORD_WEBHOOK: ${{ vars.DISCORD_WEBHOOK }}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Tag Version
|
||||
shell: bash
|
||||
run: |
|
||||
if [[ "${{ github.event_name }}" == "push" ]]; then
|
||||
VERSION=$(echo "${{ github.ref_name }}" | sed 's/placement-dev//g')
|
||||
echo "IMAGE_VERSION=${VERSION}" >> $GITHUB_ENV
|
||||
else
|
||||
echo "IMAGE_VERSION=${{ env.IMAGE_VERSION }}-${{ github.run_number }}" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: Login in to registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ env.REGISTRY_USERNAME }}
|
||||
password: ${{ env.REGISTRY_PASSWORD }}
|
||||
|
||||
- name: Build and push docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
platforms: linux/amd64
|
||||
context: .
|
||||
file: ./BMA.EHR.Placement.Service/Dockerfile
|
||||
tags: ${{ env.CONTAINER_IMAGE_NAME }}/${{ env.SERVICE_NAME }}:latest,${{ env.CONTAINER_IMAGE_NAME }}/${{ env.SERVICE_NAME }}:${{ env.IMAGE_VERSION }}
|
||||
push: true
|
||||
|
||||
- name: Remote Deploy
|
||||
uses: appleboy/ssh-action@v1.2.1
|
||||
with:
|
||||
host: ${{ vars.SSH_DEPLOY_HOST }}
|
||||
port: ${{ vars.SSH_DEPLOY_PORT }}
|
||||
username: ${{ secrets.SSH_DEPLOY_USER }}
|
||||
password: ${{ secrets.SSH_DEPLOY_PASSWORD }}
|
||||
script: |
|
||||
cd ~/repo
|
||||
./replace-env.sh API_PLACEMENT "${{ env.IMAGE_VERSION }}"
|
||||
./deploy.sh ${{ env.SERVICE_NAME }}
|
||||
|
||||
- name: Discord Notification
|
||||
if: always()
|
||||
run: |
|
||||
STATUS="${{ job.status == 'success' && '✅ Success' || '❌ Failed' }}"
|
||||
COLOR="${{ job.status == 'success' && '3066993' || '15158332' }}"
|
||||
TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||
curl -H "Content-Type: application/json" \
|
||||
-X POST \
|
||||
-d "{
|
||||
\"embeds\": [{
|
||||
\"title\": \"$STATUS\",
|
||||
\"description\": \"**Build & Deploy**\\n- Image: \`${{ env.CONTAINER_IMAGE_NAME }}/${{ env.SERVICE_NAME }}\`\\n- Version: \`${{ env.IMAGE_VERSION }}\`\\n- By: \`${{ gitea.actor }}\`\",
|
||||
\"color\": $COLOR,
|
||||
\"footer\": {
|
||||
\"text\": \"Release Notification\",
|
||||
\"icon_url\": \"https://example.com/success-icon.png\"
|
||||
},
|
||||
\"timestamp\": \"$TIMESTAMP\"
|
||||
}]
|
||||
}" \
|
||||
${{ env.DISCORD_WEBHOOK }}
|
||||
83
.forgejo/workflows/build-retirement.yml
Normal file
83
.forgejo/workflows/build-retirement.yml
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
name: Build & Deploy Retirement Service
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "retirement-dev[0-9]+.[0-9]+.[0-9]+"
|
||||
- "retirement-dev[0-9]+.[0-9]+.[0-9]+*"
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
REGISTRY: ${{ vars.CONTAINER_REGISTRY }}
|
||||
REGISTRY_USERNAME: ${{ vars.CONTAINER_REGISTRY_USERNAME }}
|
||||
REGISTRY_PASSWORD: ${{ secrets.CONTAINER_REGISTRY_PASSWORD }}
|
||||
CONTAINER_IMAGE_NAME: ${{ vars.CONTAINER_REGISTRY }}/${{ vars.CONTAINER_IMAGE_OWNER }}
|
||||
IMAGE_VERSION: latest
|
||||
SERVICE_NAME: hrms-api-retirement
|
||||
DISCORD_WEBHOOK: ${{ vars.DISCORD_WEBHOOK }}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Tag Version
|
||||
shell: bash
|
||||
run: |
|
||||
if [[ "${{ github.event_name }}" == "push" ]]; then
|
||||
VERSION=$(echo "${{ github.ref_name }}" | sed 's/retirement-dev//g')
|
||||
echo "IMAGE_VERSION=${VERSION}" >> $GITHUB_ENV
|
||||
else
|
||||
echo "IMAGE_VERSION=${{ env.IMAGE_VERSION }}-${{ github.run_number }}" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: Login in to registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ env.REGISTRY_USERNAME }}
|
||||
password: ${{ env.REGISTRY_PASSWORD }}
|
||||
|
||||
- name: Build and push docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
platforms: linux/amd64
|
||||
context: .
|
||||
file: ./BMA.EHR.Retirement.Service/Dockerfile
|
||||
tags: ${{ env.CONTAINER_IMAGE_NAME }}/${{ env.SERVICE_NAME }}:latest,${{ env.CONTAINER_IMAGE_NAME }}/${{ env.SERVICE_NAME }}:${{ env.IMAGE_VERSION }}
|
||||
push: true
|
||||
|
||||
- name: Remote Deploy
|
||||
uses: appleboy/ssh-action@v1.2.1
|
||||
with:
|
||||
host: ${{ vars.SSH_DEPLOY_HOST }}
|
||||
port: ${{ vars.SSH_DEPLOY_PORT }}
|
||||
username: ${{ secrets.SSH_DEPLOY_USER }}
|
||||
password: ${{ secrets.SSH_DEPLOY_PASSWORD }}
|
||||
script: |
|
||||
cd ~/repo
|
||||
./replace-env.sh API_RETIREMENT "${{ env.IMAGE_VERSION }}"
|
||||
./deploy.sh ${{ env.SERVICE_NAME }}
|
||||
|
||||
- name: Discord Notification
|
||||
if: always()
|
||||
run: |
|
||||
STATUS="${{ job.status == 'success' && '✅ Success' || '❌ Failed' }}"
|
||||
COLOR="${{ job.status == 'success' && '3066993' || '15158332' }}"
|
||||
TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||
curl -H "Content-Type: application/json" \
|
||||
-X POST \
|
||||
-d "{
|
||||
\"embeds\": [{
|
||||
\"title\": \"$STATUS\",
|
||||
\"description\": \"**Build & Deploy**\\n- Image: \`${{ env.CONTAINER_IMAGE_NAME }}/${{ env.SERVICE_NAME }}\`\\n- Version: \`${{ env.IMAGE_VERSION }}\`\\n- By: \`${{ gitea.actor }}\`\",
|
||||
\"color\": $COLOR,
|
||||
\"footer\": {
|
||||
\"text\": \"Release Notification\",
|
||||
\"icon_url\": \"https://example.com/success-icon.png\"
|
||||
},
|
||||
\"timestamp\": \"$TIMESTAMP\"
|
||||
}]
|
||||
}" \
|
||||
${{ env.DISCORD_WEBHOOK }}
|
||||
22
.github/workflows/discord-notify.yml
vendored
Normal file
22
.github/workflows/discord-notify.yml
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
name: Discord PR Notify
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened]
|
||||
|
||||
jobs:
|
||||
discord:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Send Discord
|
||||
run: |
|
||||
curl -X POST "${{ secrets.DISCORD_WEBHOOK_PULLREQUEST }}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"embeds": [{
|
||||
"title": "🔔 **Service:** ${{ github.repository }}",
|
||||
"description": "👤 **Author:** ${{ github.event.pull_request.user.login }}\n🌿 **Branch:** ${{ github.event.pull_request.head.ref }} → ${{ github.event.pull_request.base.ref }}\n📦 **Pull Request:** [#${{ github.event.pull_request.number }} - ${{ github.event.pull_request.title }}](${{ github.event.pull_request.html_url }})",
|
||||
"color": 5814783,
|
||||
"timestamp": "${{ github.event.pull_request.created_at }}"
|
||||
}]
|
||||
}'
|
||||
101
.github/workflows/dockerhub-release-checkin.yaml
vendored
Normal file
101
.github/workflows/dockerhub-release-checkin.yaml
vendored
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
name: DockerHub Release - CheckIn Consumer
|
||||
run-name: DockerHub Release - CheckIn Consumer by ${{ github.actor }}
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "checkin-[0-9]+.[0-9]+.[0-9]+"
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
IMAGE_VER:
|
||||
description: "Image version (e.g., latest, v1.0.0)"
|
||||
required: false
|
||||
default: "latest"
|
||||
|
||||
env:
|
||||
DOCKERHUB_REGISTRY: docker.io
|
||||
IMAGE_NAME: hrms-api-checkin
|
||||
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
|
||||
|
||||
jobs:
|
||||
release-to-dockerhub:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set output tags
|
||||
id: vars
|
||||
run: echo "tag=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Generate version
|
||||
id: gen_ver
|
||||
run: |
|
||||
if [[ $GITHUB_REF == 'refs/tags/'* ]]; then
|
||||
IMAGE_VER=${{ steps.vars.outputs.tag }}
|
||||
else
|
||||
IMAGE_VER=${{ github.event.inputs.IMAGE_VER }}
|
||||
fi
|
||||
if [[ $IMAGE_VER == '' ]]; then
|
||||
IMAGE_VER='test-vBeta'
|
||||
fi
|
||||
echo "image_ver=${IMAGE_VER}" >> $GITHUB_OUTPUT
|
||||
echo "Generated version: ${IMAGE_VER}"
|
||||
|
||||
- name: Display version
|
||||
run: |
|
||||
echo "Git Ref: $GITHUB_REF"
|
||||
echo "Image Version: ${{ steps.gen_ver.outputs.image_ver }}"
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{env.DOCKERHUB_REGISTRY}}
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
file: BMA.EHR.CheckInConsumer/Dockerfile
|
||||
platforms: linux/amd64
|
||||
push: true
|
||||
tags: |
|
||||
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}:${{ steps.gen_ver.outputs.image_ver }}
|
||||
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}:latest
|
||||
labels: |
|
||||
org.opencontainers.image.title=BMA EHR CheckIn Consumer
|
||||
org.opencontainers.image.description=HRMS CheckIn Consumer Service
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
|
||||
- name: Notify Discord on success
|
||||
if: success()
|
||||
env:
|
||||
IMAGE_VER: ${{ steps.gen_ver.outputs.image_ver }}
|
||||
run: |
|
||||
TAG_INFO="Tag: ${IMAGE_VER:-unknown}"
|
||||
REF_INFO="Ref: ${GITHUB_REF}"
|
||||
ACTOR_INFO="Actor: ${GITHUB_ACTOR}"
|
||||
MSG="✅ DockerHub release succeeded\n${TAG_INFO}\n${REF_INFO}\n${ACTOR_INFO}"
|
||||
curl -s -H "Content-Type: application/json" \
|
||||
-X POST \
|
||||
-d "{\"content\":\"${MSG}\"}" \
|
||||
"$DISCORD_WEBHOOK"
|
||||
|
||||
- name: Notify Discord on failure
|
||||
if: failure()
|
||||
env:
|
||||
IMAGE_VER: ${{ steps.gen_ver.outputs.image_ver }}
|
||||
run: |
|
||||
TAG_INFO="Tag: ${IMAGE_VER:-unknown}"
|
||||
REF_INFO="Ref: ${GITHUB_REF}"
|
||||
ACTOR_INFO="Actor: ${GITHUB_ACTOR}"
|
||||
MSG="❌ DockerHub release failed\n${TAG_INFO}\n${REF_INFO}\n${ACTOR_INFO}"
|
||||
curl -s -H "Content-Type: application/json" \
|
||||
-X POST \
|
||||
-d "{\"content\":\"${MSG}\"}" \
|
||||
"$DISCORD_WEBHOOK"
|
||||
101
.github/workflows/dockerhub-release-command.yaml
vendored
Normal file
101
.github/workflows/dockerhub-release-command.yaml
vendored
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
name: DockerHub Release - Command Service
|
||||
run-name: DockerHub Release - Command Service by ${{ github.actor }}
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "command-[0-9]+.[0-9]+.[0-9]+"
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
IMAGE_VER:
|
||||
description: "Image version (e.g., latest, v1.0.0)"
|
||||
required: false
|
||||
default: "latest"
|
||||
|
||||
env:
|
||||
DOCKERHUB_REGISTRY: docker.io
|
||||
IMAGE_NAME: hrms-api-command
|
||||
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
|
||||
|
||||
jobs:
|
||||
release-to-dockerhub:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set output tags
|
||||
id: vars
|
||||
run: echo "tag=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Generate version
|
||||
id: gen_ver
|
||||
run: |
|
||||
if [[ $GITHUB_REF == 'refs/tags/'* ]]; then
|
||||
IMAGE_VER=${{ steps.vars.outputs.tag }}
|
||||
else
|
||||
IMAGE_VER=${{ github.event.inputs.IMAGE_VER }}
|
||||
fi
|
||||
if [[ $IMAGE_VER == '' ]]; then
|
||||
IMAGE_VER='test-vBeta'
|
||||
fi
|
||||
echo "image_ver=${IMAGE_VER}" >> $GITHUB_OUTPUT
|
||||
echo "Generated version: ${IMAGE_VER}"
|
||||
|
||||
- name: Display version
|
||||
run: |
|
||||
echo "Git Ref: $GITHUB_REF"
|
||||
echo "Image Version: ${{ steps.gen_ver.outputs.image_ver }}"
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{env.DOCKERHUB_REGISTRY}}
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
file: BMA.EHR.Command.Service/Dockerfile
|
||||
platforms: linux/amd64
|
||||
push: true
|
||||
tags: |
|
||||
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}:${{ steps.gen_ver.outputs.image_ver }}
|
||||
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}:latest
|
||||
labels: |
|
||||
org.opencontainers.image.title=BMA EHR Command Service
|
||||
org.opencontainers.image.description=HRMS Command API Service
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
|
||||
- name: Notify Discord on success
|
||||
if: success()
|
||||
env:
|
||||
IMAGE_VER: ${{ steps.gen_ver.outputs.image_ver }}
|
||||
run: |
|
||||
TAG_INFO="Tag: ${IMAGE_VER:-unknown}"
|
||||
REF_INFO="Ref: ${GITHUB_REF}"
|
||||
ACTOR_INFO="Actor: ${GITHUB_ACTOR}"
|
||||
MSG="✅ DockerHub release succeeded\n${TAG_INFO}\n${REF_INFO}\n${ACTOR_INFO}"
|
||||
curl -s -H "Content-Type: application/json" \
|
||||
-X POST \
|
||||
-d "{\"content\":\"${MSG}\"}" \
|
||||
"$DISCORD_WEBHOOK"
|
||||
|
||||
- name: Notify Discord on failure
|
||||
if: failure()
|
||||
env:
|
||||
IMAGE_VER: ${{ steps.gen_ver.outputs.image_ver }}
|
||||
run: |
|
||||
TAG_INFO="Tag: ${IMAGE_VER:-unknown}"
|
||||
REF_INFO="Ref: ${GITHUB_REF}"
|
||||
ACTOR_INFO="Actor: ${GITHUB_ACTOR}"
|
||||
MSG="❌ DockerHub release failed\n${TAG_INFO}\n${REF_INFO}\n${ACTOR_INFO}"
|
||||
curl -s -H "Content-Type: application/json" \
|
||||
-X POST \
|
||||
-d "{\"content\":\"${MSG}\"}" \
|
||||
"$DISCORD_WEBHOOK"
|
||||
101
.github/workflows/dockerhub-release-discipline.yaml
vendored
Normal file
101
.github/workflows/dockerhub-release-discipline.yaml
vendored
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
name: DockerHub Release - Discipline Service
|
||||
run-name: DockerHub Release - Discipline Service by ${{ github.actor }}
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "discipline-[0-9]+.[0-9]+.[0-9]+"
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
IMAGE_VER:
|
||||
description: "Image version (e.g., latest, v1.0.0)"
|
||||
required: false
|
||||
default: "latest"
|
||||
|
||||
env:
|
||||
DOCKERHUB_REGISTRY: docker.io
|
||||
IMAGE_NAME: hrms-api-discipline
|
||||
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
|
||||
|
||||
jobs:
|
||||
release-to-dockerhub:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set output tags
|
||||
id: vars
|
||||
run: echo "tag=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Generate version
|
||||
id: gen_ver
|
||||
run: |
|
||||
if [[ $GITHUB_REF == 'refs/tags/'* ]]; then
|
||||
IMAGE_VER=${{ steps.vars.outputs.tag }}
|
||||
else
|
||||
IMAGE_VER=${{ github.event.inputs.IMAGE_VER }}
|
||||
fi
|
||||
if [[ $IMAGE_VER == '' ]]; then
|
||||
IMAGE_VER='test-vBeta'
|
||||
fi
|
||||
echo "image_ver=${IMAGE_VER}" >> $GITHUB_OUTPUT
|
||||
echo "Generated version: ${IMAGE_VER}"
|
||||
|
||||
- name: Display version
|
||||
run: |
|
||||
echo "Git Ref: $GITHUB_REF"
|
||||
echo "Image Version: ${{ steps.gen_ver.outputs.image_ver }}"
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{env.DOCKERHUB_REGISTRY}}
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
file: BMA.EHR.Discipline.Service/Dockerfile
|
||||
platforms: linux/amd64
|
||||
push: true
|
||||
tags: |
|
||||
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}:${{ steps.gen_ver.outputs.image_ver }}
|
||||
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}:latest
|
||||
labels: |
|
||||
org.opencontainers.image.title=BMA EHR Discipline Service
|
||||
org.opencontainers.image.description=HRMS Discipline API Service
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
|
||||
- name: Notify Discord on success
|
||||
if: success()
|
||||
env:
|
||||
IMAGE_VER: ${{ steps.gen_ver.outputs.image_ver }}
|
||||
run: |
|
||||
TAG_INFO="Tag: ${IMAGE_VER:-unknown}"
|
||||
REF_INFO="Ref: ${GITHUB_REF}"
|
||||
ACTOR_INFO="Actor: ${GITHUB_ACTOR}"
|
||||
MSG="✅ DockerHub release succeeded\n${TAG_INFO}\n${REF_INFO}\n${ACTOR_INFO}"
|
||||
curl -s -H "Content-Type: application/json" \
|
||||
-X POST \
|
||||
-d "{\"content\":\"${MSG}\"}" \
|
||||
"$DISCORD_WEBHOOK"
|
||||
|
||||
- name: Notify Discord on failure
|
||||
if: failure()
|
||||
env:
|
||||
IMAGE_VER: ${{ steps.gen_ver.outputs.image_ver }}
|
||||
run: |
|
||||
TAG_INFO="Tag: ${IMAGE_VER:-unknown}"
|
||||
REF_INFO="Ref: ${GITHUB_REF}"
|
||||
ACTOR_INFO="Actor: ${GITHUB_ACTOR}"
|
||||
MSG="❌ DockerHub release failed\n${TAG_INFO}\n${REF_INFO}\n${ACTOR_INFO}"
|
||||
curl -s -H "Content-Type: application/json" \
|
||||
-X POST \
|
||||
-d "{\"content\":\"${MSG}\"}" \
|
||||
"$DISCORD_WEBHOOK"
|
||||
101
.github/workflows/dockerhub-release-insignia.yaml
vendored
Normal file
101
.github/workflows/dockerhub-release-insignia.yaml
vendored
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
name: DockerHub Release - Insignia Service
|
||||
run-name: DockerHub Release - Insignia Service by ${{ github.actor }}
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "insignia-[0-9]+.[0-9]+.[0-9]+"
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
IMAGE_VER:
|
||||
description: "Image version (e.g., latest, v1.0.0)"
|
||||
required: false
|
||||
default: "latest"
|
||||
|
||||
env:
|
||||
DOCKERHUB_REGISTRY: docker.io
|
||||
IMAGE_NAME: hrms-api-insignia
|
||||
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
|
||||
|
||||
jobs:
|
||||
release-to-dockerhub:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set output tags
|
||||
id: vars
|
||||
run: echo "tag=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Generate version
|
||||
id: gen_ver
|
||||
run: |
|
||||
if [[ $GITHUB_REF == 'refs/tags/'* ]]; then
|
||||
IMAGE_VER=${{ steps.vars.outputs.tag }}
|
||||
else
|
||||
IMAGE_VER=${{ github.event.inputs.IMAGE_VER }}
|
||||
fi
|
||||
if [[ $IMAGE_VER == '' ]]; then
|
||||
IMAGE_VER='test-vBeta'
|
||||
fi
|
||||
echo "image_ver=${IMAGE_VER}" >> $GITHUB_OUTPUT
|
||||
echo "Generated version: ${IMAGE_VER}"
|
||||
|
||||
- name: Display version
|
||||
run: |
|
||||
echo "Git Ref: $GITHUB_REF"
|
||||
echo "Image Version: ${{ steps.gen_ver.outputs.image_ver }}"
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{env.DOCKERHUB_REGISTRY}}
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
file: BMA.EHR.Insignia/Dockerfile
|
||||
platforms: linux/amd64
|
||||
push: true
|
||||
tags: |
|
||||
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}:${{ steps.gen_ver.outputs.image_ver }}
|
||||
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}:latest
|
||||
labels: |
|
||||
org.opencontainers.image.title=BMA EHR Insignia Service
|
||||
org.opencontainers.image.description=HRMS Insignia API Service
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
|
||||
- name: Notify Discord on success
|
||||
if: success()
|
||||
env:
|
||||
IMAGE_VER: ${{ steps.gen_ver.outputs.image_ver }}
|
||||
run: |
|
||||
TAG_INFO="Tag: ${IMAGE_VER:-unknown}"
|
||||
REF_INFO="Ref: ${GITHUB_REF}"
|
||||
ACTOR_INFO="Actor: ${GITHUB_ACTOR}"
|
||||
MSG="✅ DockerHub release succeeded\n${TAG_INFO}\n${REF_INFO}\n${ACTOR_INFO}"
|
||||
curl -s -H "Content-Type: application/json" \
|
||||
-X POST \
|
||||
-d "{\"content\":\"${MSG}\"}" \
|
||||
"$DISCORD_WEBHOOK"
|
||||
|
||||
- name: Notify Discord on failure
|
||||
if: failure()
|
||||
env:
|
||||
IMAGE_VER: ${{ steps.gen_ver.outputs.image_ver }}
|
||||
run: |
|
||||
TAG_INFO="Tag: ${IMAGE_VER:-unknown}"
|
||||
REF_INFO="Ref: ${GITHUB_REF}"
|
||||
ACTOR_INFO="Actor: ${GITHUB_ACTOR}"
|
||||
MSG="❌ DockerHub release failed\n${TAG_INFO}\n${REF_INFO}\n${ACTOR_INFO}"
|
||||
curl -s -H "Content-Type: application/json" \
|
||||
-X POST \
|
||||
-d "{\"content\":\"${MSG}\"}" \
|
||||
"$DISCORD_WEBHOOK"
|
||||
119
.github/workflows/dockerhub-release-leave.yaml
vendored
Normal file
119
.github/workflows/dockerhub-release-leave.yaml
vendored
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
name: DockerHub Release - Leave Service
|
||||
run-name: DockerHub Release - Leave Service by ${{ github.actor }}
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "leave-[0-9]+.[0-9]+.[0-9]+"
|
||||
# branches:
|
||||
# - main
|
||||
# - develop
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
IMAGE_VER:
|
||||
description: "Image version (e.g., latest, v1.0.0)"
|
||||
required: false
|
||||
default: "latest"
|
||||
|
||||
env:
|
||||
DOCKERHUB_REGISTRY: docker.io
|
||||
IMAGE_NAME: hrms-api-leave
|
||||
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
|
||||
|
||||
jobs:
|
||||
release-to-dockerhub:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set output tags
|
||||
id: vars
|
||||
run: echo "tag=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Generate version
|
||||
id: gen_ver
|
||||
run: |
|
||||
if [[ $GITHUB_REF == 'refs/tags/'* ]]; then
|
||||
IMAGE_VER=${{ steps.vars.outputs.tag }}
|
||||
elif [[ $GITHUB_REF == 'refs/heads/'* ]]; then
|
||||
BRANCH_NAME=${GITHUB_REF#refs/heads/}
|
||||
IMAGE_VER="${BRANCH_NAME}-latest"
|
||||
else
|
||||
IMAGE_VER=${{ github.event.inputs.IMAGE_VER }}
|
||||
fi
|
||||
if [[ $IMAGE_VER == '' ]]; then
|
||||
IMAGE_VER='test-vBeta'
|
||||
fi
|
||||
echo "image_ver=${IMAGE_VER}" >> $GITHUB_OUTPUT
|
||||
echo "Generated version: ${IMAGE_VER}"
|
||||
|
||||
- name: Display version
|
||||
run: |
|
||||
echo "Git Ref: $GITHUB_REF"
|
||||
echo "Image Version: ${{ steps.gen_ver.outputs.image_ver }}"
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{env.DOCKERHUB_REGISTRY}}
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Extract metadata for Docker
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}
|
||||
tags: |
|
||||
type=ref,event=tag
|
||||
type=ref,event=branch
|
||||
type=raw,value=${{ steps.gen_ver.outputs.image_ver }}
|
||||
type=raw,value=latest,enable={{is_default_branch}}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
file: BMA.EHR.Leave/Dockerfile
|
||||
platforms: linux/amd64
|
||||
push: true
|
||||
tags: |
|
||||
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}:${{ steps.gen_ver.outputs.image_ver }}
|
||||
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}:latest
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
|
||||
- name: Image digest
|
||||
run: echo "Image pushed with digest ${{ steps.build.outputs.digest }}"
|
||||
|
||||
- name: Notify Discord on success
|
||||
if: success()
|
||||
env:
|
||||
IMAGE_VER: ${{ steps.gen_ver.outputs.image_ver }}
|
||||
run: |
|
||||
TAG_INFO="Tag: ${IMAGE_VER:-unknown}"
|
||||
REF_INFO="Ref: ${GITHUB_REF}"
|
||||
ACTOR_INFO="Actor: ${GITHUB_ACTOR}"
|
||||
MSG="✅ DockerHub release succeeded\n${TAG_INFO}\n${REF_INFO}\n${ACTOR_INFO}"
|
||||
curl -s -H "Content-Type: application/json" \
|
||||
-X POST \
|
||||
-d "{\"content\":\"${MSG}\"}" \
|
||||
"$DISCORD_WEBHOOK"
|
||||
|
||||
- name: Notify Discord on failure
|
||||
if: failure()
|
||||
env:
|
||||
IMAGE_VER: ${{ steps.gen_ver.outputs.image_ver }}
|
||||
run: |
|
||||
TAG_INFO="Tag: ${IMAGE_VER:-unknown}"
|
||||
REF_INFO="Ref: ${GITHUB_REF}"
|
||||
ACTOR_INFO="Actor: ${GITHUB_ACTOR}"
|
||||
MSG="❌ DockerHub release failed\n${TAG_INFO}\n${REF_INFO}\n${ACTOR_INFO}"
|
||||
curl -s -H "Content-Type: application/json" \
|
||||
-X POST \
|
||||
-d "{\"content\":\"${MSG}\"}" \
|
||||
"$DISCORD_WEBHOOK"
|
||||
101
.github/workflows/dockerhub-release-placement.yaml
vendored
Normal file
101
.github/workflows/dockerhub-release-placement.yaml
vendored
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
name: DockerHub Release - Placement Service
|
||||
run-name: DockerHub Release - Placement Service by ${{ github.actor }}
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "placement-[0-9]+.[0-9]+.[0-9]+"
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
IMAGE_VER:
|
||||
description: "Image version (e.g., latest, v1.0.0)"
|
||||
required: false
|
||||
default: "latest"
|
||||
|
||||
env:
|
||||
DOCKERHUB_REGISTRY: docker.io
|
||||
IMAGE_NAME: hrms-api-placement
|
||||
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
|
||||
|
||||
jobs:
|
||||
release-to-dockerhub:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set output tags
|
||||
id: vars
|
||||
run: echo "tag=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Generate version
|
||||
id: gen_ver
|
||||
run: |
|
||||
if [[ $GITHUB_REF == 'refs/tags/'* ]]; then
|
||||
IMAGE_VER=${{ steps.vars.outputs.tag }}
|
||||
else
|
||||
IMAGE_VER=${{ github.event.inputs.IMAGE_VER }}
|
||||
fi
|
||||
if [[ $IMAGE_VER == '' ]]; then
|
||||
IMAGE_VER='test-vBeta'
|
||||
fi
|
||||
echo "image_ver=${IMAGE_VER}" >> $GITHUB_OUTPUT
|
||||
echo "Generated version: ${IMAGE_VER}"
|
||||
|
||||
- name: Display version
|
||||
run: |
|
||||
echo "Git Ref: $GITHUB_REF"
|
||||
echo "Image Version: ${{ steps.gen_ver.outputs.image_ver }}"
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{env.DOCKERHUB_REGISTRY}}
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
file: BMA.EHR.Placement.Service/Dockerfile
|
||||
platforms: linux/amd64
|
||||
push: true
|
||||
tags: |
|
||||
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}:${{ steps.gen_ver.outputs.image_ver }}
|
||||
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}:latest
|
||||
labels: |
|
||||
org.opencontainers.image.title=BMA EHR Placement Service
|
||||
org.opencontainers.image.description=HRMS Placement API Service
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
|
||||
- name: Notify Discord on success
|
||||
if: success()
|
||||
env:
|
||||
IMAGE_VER: ${{ steps.gen_ver.outputs.image_ver }}
|
||||
run: |
|
||||
TAG_INFO="Tag: ${IMAGE_VER:-unknown}"
|
||||
REF_INFO="Ref: ${GITHUB_REF}"
|
||||
ACTOR_INFO="Actor: ${GITHUB_ACTOR}"
|
||||
MSG="✅ DockerHub release succeeded\n${TAG_INFO}\n${REF_INFO}\n${ACTOR_INFO}"
|
||||
curl -s -H "Content-Type: application/json" \
|
||||
-X POST \
|
||||
-d "{\"content\":\"${MSG}\"}" \
|
||||
"$DISCORD_WEBHOOK"
|
||||
|
||||
- name: Notify Discord on failure
|
||||
if: failure()
|
||||
env:
|
||||
IMAGE_VER: ${{ steps.gen_ver.outputs.image_ver }}
|
||||
run: |
|
||||
TAG_INFO="Tag: ${IMAGE_VER:-unknown}"
|
||||
REF_INFO="Ref: ${GITHUB_REF}"
|
||||
ACTOR_INFO="Actor: ${GITHUB_ACTOR}"
|
||||
MSG="❌ DockerHub release failed\n${TAG_INFO}\n${REF_INFO}\n${ACTOR_INFO}"
|
||||
curl -s -H "Content-Type: application/json" \
|
||||
-X POST \
|
||||
-d "{\"content\":\"${MSG}\"}" \
|
||||
"$DISCORD_WEBHOOK"
|
||||
101
.github/workflows/dockerhub-release-reportv2.yaml
vendored
Normal file
101
.github/workflows/dockerhub-release-reportv2.yaml
vendored
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
name: DockerHub Release - Report Service
|
||||
run-name: DockerHub Release - Report Service by ${{ github.actor }}
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "reportv2-[0-9]+.[0-9]+.[0-9]+"
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
IMAGE_VER:
|
||||
description: "Image version (e.g., latest, v1.0.0)"
|
||||
required: false
|
||||
default: "latest"
|
||||
|
||||
env:
|
||||
DOCKERHUB_REGISTRY: docker.io
|
||||
IMAGE_NAME: hrms-api-reportv2
|
||||
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
|
||||
|
||||
jobs:
|
||||
release-to-dockerhub:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set output tags
|
||||
id: vars
|
||||
run: echo "tag=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Generate version
|
||||
id: gen_ver
|
||||
run: |
|
||||
if [[ $GITHUB_REF == 'refs/tags/'* ]]; then
|
||||
IMAGE_VER=${{ steps.vars.outputs.tag }}
|
||||
else
|
||||
IMAGE_VER=${{ github.event.inputs.IMAGE_VER }}
|
||||
fi
|
||||
if [[ $IMAGE_VER == '' ]]; then
|
||||
IMAGE_VER='test-vBeta'
|
||||
fi
|
||||
echo "image_ver=${IMAGE_VER}" >> $GITHUB_OUTPUT
|
||||
echo "Generated version: ${IMAGE_VER}"
|
||||
|
||||
- name: Display version
|
||||
run: |
|
||||
echo "Git Ref: $GITHUB_REF"
|
||||
echo "Image Version: ${{ steps.gen_ver.outputs.image_ver }}"
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{env.DOCKERHUB_REGISTRY}}
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
file: BMA.EHR.Report.Service/Dockerfile
|
||||
platforms: linux/amd64
|
||||
push: true
|
||||
tags: |
|
||||
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}:${{ steps.gen_ver.outputs.image_ver }}
|
||||
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}:latest
|
||||
labels: |
|
||||
org.opencontainers.image.title=BMA EHR Report Service
|
||||
org.opencontainers.image.description=HRMS Report API Service
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
|
||||
- name: Notify Discord on success
|
||||
if: success()
|
||||
env:
|
||||
IMAGE_VER: ${{ steps.gen_ver.outputs.image_ver }}
|
||||
run: |
|
||||
TAG_INFO="Tag: ${IMAGE_VER:-unknown}"
|
||||
REF_INFO="Ref: ${GITHUB_REF}"
|
||||
ACTOR_INFO="Actor: ${GITHUB_ACTOR}"
|
||||
MSG="✅ DockerHub release succeeded\n${TAG_INFO}\n${REF_INFO}\n${ACTOR_INFO}"
|
||||
curl -s -H "Content-Type: application/json" \
|
||||
-X POST \
|
||||
-d "{\"content\":\"${MSG}\"}" \
|
||||
"$DISCORD_WEBHOOK"
|
||||
|
||||
- name: Notify Discord on failure
|
||||
if: failure()
|
||||
env:
|
||||
IMAGE_VER: ${{ steps.gen_ver.outputs.image_ver }}
|
||||
run: |
|
||||
TAG_INFO="Tag: ${IMAGE_VER:-unknown}"
|
||||
REF_INFO="Ref: ${GITHUB_REF}"
|
||||
ACTOR_INFO="Actor: ${GITHUB_ACTOR}"
|
||||
MSG="❌ DockerHub release failed\n${TAG_INFO}\n${REF_INFO}\n${ACTOR_INFO}"
|
||||
curl -s -H "Content-Type: application/json" \
|
||||
-X POST \
|
||||
-d "{\"content\":\"${MSG}\"}" \
|
||||
"$DISCORD_WEBHOOK"
|
||||
101
.github/workflows/dockerhub-release-retirement.yaml
vendored
Normal file
101
.github/workflows/dockerhub-release-retirement.yaml
vendored
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
name: DockerHub Release - Retirement Service
|
||||
run-name: DockerHub Release - Retirement Service by ${{ github.actor }}
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "retirement-[0-9]+.[0-9]+.[0-9]+"
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
IMAGE_VER:
|
||||
description: "Image version (e.g., latest, v1.0.0)"
|
||||
required: false
|
||||
default: "latest"
|
||||
|
||||
env:
|
||||
DOCKERHUB_REGISTRY: docker.io
|
||||
IMAGE_NAME: hrms-api-retirement
|
||||
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
|
||||
|
||||
jobs:
|
||||
release-to-dockerhub:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set output tags
|
||||
id: vars
|
||||
run: echo "tag=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Generate version
|
||||
id: gen_ver
|
||||
run: |
|
||||
if [[ $GITHUB_REF == 'refs/tags/'* ]]; then
|
||||
IMAGE_VER=${{ steps.vars.outputs.tag }}
|
||||
else
|
||||
IMAGE_VER=${{ github.event.inputs.IMAGE_VER }}
|
||||
fi
|
||||
if [[ $IMAGE_VER == '' ]]; then
|
||||
IMAGE_VER='test-vBeta'
|
||||
fi
|
||||
echo "image_ver=${IMAGE_VER}" >> $GITHUB_OUTPUT
|
||||
echo "Generated version: ${IMAGE_VER}"
|
||||
|
||||
- name: Display version
|
||||
run: |
|
||||
echo "Git Ref: $GITHUB_REF"
|
||||
echo "Image Version: ${{ steps.gen_ver.outputs.image_ver }}"
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{env.DOCKERHUB_REGISTRY}}
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
file: BMA.EHR.Retirement.Service/Dockerfile
|
||||
platforms: linux/amd64
|
||||
push: true
|
||||
tags: |
|
||||
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}:${{ steps.gen_ver.outputs.image_ver }}
|
||||
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}:latest
|
||||
labels: |
|
||||
org.opencontainers.image.title=BMA EHR Retirement Service
|
||||
org.opencontainers.image.description=HRMS Retirement API Service
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
|
||||
- name: Notify Discord on success
|
||||
if: success()
|
||||
env:
|
||||
IMAGE_VER: ${{ steps.gen_ver.outputs.image_ver }}
|
||||
run: |
|
||||
TAG_INFO="Tag: ${IMAGE_VER:-unknown}"
|
||||
REF_INFO="Ref: ${GITHUB_REF}"
|
||||
ACTOR_INFO="Actor: ${GITHUB_ACTOR}"
|
||||
MSG="✅ DockerHub release succeeded\n${TAG_INFO}\n${REF_INFO}\n${ACTOR_INFO}"
|
||||
curl -s -H "Content-Type: application/json" \
|
||||
-X POST \
|
||||
-d "{\"content\":\"${MSG}\"}" \
|
||||
"$DISCORD_WEBHOOK"
|
||||
|
||||
- name: Notify Discord on failure
|
||||
if: failure()
|
||||
env:
|
||||
IMAGE_VER: ${{ steps.gen_ver.outputs.image_ver }}
|
||||
run: |
|
||||
TAG_INFO="Tag: ${IMAGE_VER:-unknown}"
|
||||
REF_INFO="Ref: ${GITHUB_REF}"
|
||||
ACTOR_INFO="Actor: ${GITHUB_ACTOR}"
|
||||
MSG="❌ DockerHub release failed\n${TAG_INFO}\n${REF_INFO}\n${ACTOR_INFO}"
|
||||
curl -s -H "Content-Type: application/json" \
|
||||
-X POST \
|
||||
-d "{\"content\":\"${MSG}\"}" \
|
||||
"$DISCORD_WEBHOOK"
|
||||
76
.github/workflows/release_Retirement.yaml
vendored
76
.github/workflows/release_Retirement.yaml
vendored
|
|
@ -3,30 +3,31 @@ run-name: release-dev ${{ github.actor }}
|
|||
on:
|
||||
# push:
|
||||
# tags:
|
||||
# - 'v[0-9]+.[0-9]+.[0-9]+'
|
||||
# tags-ignore:
|
||||
# - '2.*'
|
||||
# Allow run workflow manually from Action tab
|
||||
# - "retirement-[0-9]+.[0-9]+.[0-9]+"
|
||||
workflow_dispatch:
|
||||
env:
|
||||
REGISTRY: docker.frappet.com
|
||||
IMAGE_NAME: ehr/bma-ehr-retirement-service
|
||||
DEPLOY_HOST: frappet.com
|
||||
COMPOSE_PATH: /home/frappet/docker/bma-ehr-retirement
|
||||
DEPLOY_PORT: 10102
|
||||
# COMPOSE_PATH: /home/frappet/docker/bma-ehr
|
||||
COMPOSE_PATH: /home/frappet/docker/bma/bma-ehr-retirement
|
||||
TOKEN_LINE: uxuK5hDzS2DsoC5piJBrWRLiz8GgY7iMZZldOWsDDF0
|
||||
|
||||
jobs:
|
||||
# act workflow_dispatch -W .github/workflows/release_retirement.yaml --input IMAGE_VER=retirement-1.0.0 -s DOCKER_USER=sorawit -s DOCKER_PASS=P@ssword -s SSH_PASSWORD=P@ssw0rd
|
||||
# act workflow_dispatch -W .github/workflows/release_retirement.yaml --input IMAGE_VER=latest -s DOCKER_USER=admin -s DOCKER_PASS=FPTadmin2357 -s SSH_PASSWORD=FPTadmin2357
|
||||
release-dev:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
# skip Set up QEMU because it fail on act and container
|
||||
- name: Set output tags
|
||||
id: vars
|
||||
run: echo "tag=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT
|
||||
- name: Gen Version
|
||||
id: gen_ver
|
||||
run: |
|
||||
if [[ $GITHUB_REF == 'refs/tags/'* ]]; then
|
||||
IMAGE_VER='${GITHUB_REF/refs\/tags\//}'
|
||||
IMAGE_VER=${{ steps.vars.outputs.tag }}
|
||||
else
|
||||
IMAGE_VER=${{ github.event.inputs.IMAGE_VER }}
|
||||
fi
|
||||
|
|
@ -34,7 +35,7 @@ jobs:
|
|||
IMAGE_VER='test-vBeta'
|
||||
fi
|
||||
echo '::set-output name=image_ver::'$IMAGE_VER
|
||||
- name: Test Version
|
||||
- name: Check Version
|
||||
run: |
|
||||
echo $GITHUB_REF
|
||||
echo ${{ steps.gen_ver.outputs.image_ver }}
|
||||
|
|
@ -61,27 +62,46 @@ jobs:
|
|||
host: ${{env.DEPLOY_HOST}}
|
||||
username: frappet
|
||||
password: ${{ secrets.SSH_PASSWORD }}
|
||||
port: 22
|
||||
port: ${{env.DEPLOY_PORT}}
|
||||
script: |
|
||||
cd "${{env.COMPOSE_PATH}}"
|
||||
docker-compose pull
|
||||
docker-compose up -d
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
echo "${{ steps.gen_ver.outputs.image_ver }}"> success
|
||||
- uses: snow-actions/line-notify@v1.1.0
|
||||
- name: Notify Discord Success
|
||||
if: success()
|
||||
with:
|
||||
access_token: ${{ env.TOKEN_LINE }}
|
||||
message: |
|
||||
-Success✅✅✅
|
||||
Image: ${{env.IMAGE_NAME}}
|
||||
Version: ${{ github.event.inputs.IMAGE_VER }}
|
||||
By: ${{secrets.DOCKER_USER}}
|
||||
- uses: snow-actions/line-notify@v1.1.0
|
||||
run: |
|
||||
curl -H "Content-Type: application/json" \
|
||||
-X POST \
|
||||
-d '{
|
||||
"embeds": [{
|
||||
"title": "✅ Deployment Success!",
|
||||
"description": "**Details:**\n- Image: `${{env.IMAGE_NAME}}`\n- Version: `${{ steps.gen_ver.outputs.image_ver }}`\n- Deployed by: `${{github.actor}}`",
|
||||
"color": 3066993,
|
||||
"footer": {
|
||||
"text": "Release Notification",
|
||||
"icon_url": "https://example.com/success-icon.png"
|
||||
},
|
||||
"timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"
|
||||
}]
|
||||
}' \
|
||||
${{ secrets.DISCORD_WEBHOOK }}
|
||||
|
||||
- name: Notify Discord Failure
|
||||
if: failure()
|
||||
with:
|
||||
access_token: ${{ env.TOKEN_LINE }}
|
||||
message: |
|
||||
-Failure❌❌❌
|
||||
Image: ${{env.IMAGE_NAME}}
|
||||
Version: ${{ github.event.inputs.IMAGE_VER }}
|
||||
By: ${{secrets.DOCKER_USER}}
|
||||
run: |
|
||||
curl -H "Content-Type: application/json" \
|
||||
-X POST \
|
||||
-d '{
|
||||
"embeds": [{
|
||||
"title": "❌ Deployment Failed!",
|
||||
"description": "**Details:**\n- Image: `${{env.IMAGE_NAME}}`\n- Version: `${{ steps.gen_ver.outputs.image_ver }}`\n- Attempted by: `${{github.actor}}`",
|
||||
"color": 15158332,
|
||||
"footer": {
|
||||
"text": "Release Notification",
|
||||
"icon_url": "https://example.com/failure-icon.png"
|
||||
},
|
||||
"timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"
|
||||
}]
|
||||
}' \
|
||||
${{ secrets.DISCORD_WEBHOOK }}
|
||||
|
|
|
|||
90
.github/workflows/release_checkin_consumer.yaml
vendored
Normal file
90
.github/workflows/release_checkin_consumer.yaml
vendored
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
name: release-dev
|
||||
run-name: release-dev ${{ github.actor }}
|
||||
on:
|
||||
# push:
|
||||
# tags:
|
||||
# - "consumer-[0-9]+.[0-9]+.[0-9]+"
|
||||
workflow_dispatch:
|
||||
env:
|
||||
REGISTRY: docker.frappet.com
|
||||
IMAGE_NAME: ehr/bma-ehr-checkin-consumer
|
||||
DEPLOY_HOST: frappet.com
|
||||
DEPLOY_PORT: 10102
|
||||
# COMPOSE_PATH: /home/frappet/docker/bma-ehr
|
||||
COMPOSE_PATH: /home/frappet/docker/bma/bma-ehr-leave
|
||||
TOKEN_LINE: uxuK5hDzS2DsoC5piJBrWRLiz8GgY7iMZZldOWsDDF0
|
||||
|
||||
jobs:
|
||||
# act workflow_dispatch -W .github/workflows/release_leave.yaml --input IMAGE_VER=leave-1.0.0 -s DOCKER_USER=sorawit -s DOCKER_PASS=P@ssword -s SSH_PASSWORD=P@ssw0rd
|
||||
release-dev:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
# skip Set up QEMU because it fail on act and container
|
||||
# Gen Version try to get version from tag or inut
|
||||
- name: Set output tags
|
||||
id: vars
|
||||
run: echo "tag=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT
|
||||
- name: Gen Version
|
||||
id: gen_ver
|
||||
run: |
|
||||
if [[ $GITHUB_REF == 'refs/tags/'* ]]; then
|
||||
IMAGE_VER=${{ steps.vars.outputs.tag }}
|
||||
else
|
||||
IMAGE_VER=${{ github.event.inputs.IMAGE_VER }}
|
||||
fi
|
||||
if [[ $IMAGE_VER == '' ]]; then
|
||||
IMAGE_VER='test-vBeta'
|
||||
fi
|
||||
echo '::set-output name=image_ver::'$IMAGE_VER
|
||||
- name: Check Version
|
||||
run: |
|
||||
echo $GITHUB_REF
|
||||
echo ${{ steps.gen_ver.outputs.image_ver }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
- name: Login in to registry
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ${{env.REGISTRY}}
|
||||
username: ${{secrets.DOCKER_USER}}
|
||||
password: ${{secrets.DOCKER_PASS}}
|
||||
- name: Build and push docker image
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64
|
||||
file: BMA.EHR.CheckInConsumer/Dockerfile
|
||||
push: true
|
||||
tags: ${{env.REGISTRY}}/${{env.IMAGE_NAME}}:${{ steps.gen_ver.outputs.image_ver }},${{env.REGISTRY}}/${{env.IMAGE_NAME}}:latest
|
||||
- name: Remote Deployment
|
||||
uses: appleboy/ssh-action@v0.1.8
|
||||
with:
|
||||
host: ${{env.DEPLOY_HOST}}
|
||||
username: frappet
|
||||
password: ${{ secrets.SSH_PASSWORD }}
|
||||
port: 10102
|
||||
script: |
|
||||
cd "${{env.COMPOSE_PATH}}"
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
echo "${{ steps.gen_ver.outputs.image_ver }}"> success
|
||||
- uses: snow-actions/line-notify@v1.1.0
|
||||
if: success()
|
||||
with:
|
||||
access_token: ${{ secrets.TOKEN_LINE }}
|
||||
message: |
|
||||
-Success✅✅✅
|
||||
Image: ${{env.IMAGE_NAME}}
|
||||
Version: ${{ steps.gen_ver.outputs.IMAGE_VER }}
|
||||
By: ${{secrets.DOCKER_USER}}
|
||||
- uses: snow-actions/line-notify@v1.1.0
|
||||
if: failure()
|
||||
with:
|
||||
access_token: ${{ secrets.TOKEN_LINE }}
|
||||
message: |
|
||||
-Failure❌❌❌
|
||||
Image: ${{env.IMAGE_NAME}}
|
||||
Version: ${{ steps.gen_ver.outputs.IMAGE_VER }}
|
||||
By: ${{secrets.DOCKER_USER}}
|
||||
76
.github/workflows/release_command.yaml
vendored
76
.github/workflows/release_command.yaml
vendored
|
|
@ -3,30 +3,31 @@ run-name: release-dev ${{ github.actor }}
|
|||
on:
|
||||
# push:
|
||||
# tags:
|
||||
# - 'v[0-9]+.[0-9]+.[0-9]+'
|
||||
# tags-ignore:
|
||||
# - '2.*'
|
||||
# Allow run workflow manually from Action tab
|
||||
# - "command-[0-9]+.[0-9]+.[0-9]+"
|
||||
workflow_dispatch:
|
||||
env:
|
||||
REGISTRY: docker.frappet.com
|
||||
IMAGE_NAME: ehr/bma-ehr-command-service
|
||||
DEPLOY_HOST: frappet.com
|
||||
COMPOSE_PATH: /home/frappet/docker/bma-ehr-command
|
||||
DEPLOY_PORT: 10102
|
||||
# COMPOSE_PATH: /home/frappet/docker/bma-ehr
|
||||
COMPOSE_PATH: /home/frappet/docker/bma/bma-ehr-command
|
||||
TOKEN_LINE: uxuK5hDzS2DsoC5piJBrWRLiz8GgY7iMZZldOWsDDF0
|
||||
|
||||
jobs:
|
||||
# act workflow_dispatch -W .github/workflows/release_command.yaml --input IMAGE_VER=command-1.0.0 -s DOCKER_USER=sorawit -s DOCKER_PASS=P@ssword -s SSH_PASSWORD=P@ssw0rd
|
||||
# act workflow_dispatch -W .github/workflows/release_command.yaml --input IMAGE_VER=latest -s DOCKER_USER=admin -s DOCKER_PASS=FPTadmin2357 -s SSH_PASSWORD=FPTadmin2357
|
||||
release-dev:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
# skip Set up QEMU because it fail on act and container
|
||||
- name: Set output tags
|
||||
id: vars
|
||||
run: echo "tag=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT
|
||||
- name: Gen Version
|
||||
id: gen_ver
|
||||
run: |
|
||||
if [[ $GITHUB_REF == 'refs/tags/'* ]]; then
|
||||
IMAGE_VER='${GITHUB_REF/refs\/tags\//}'
|
||||
IMAGE_VER=${{ steps.vars.outputs.tag }}
|
||||
else
|
||||
IMAGE_VER=${{ github.event.inputs.IMAGE_VER }}
|
||||
fi
|
||||
|
|
@ -34,7 +35,7 @@ jobs:
|
|||
IMAGE_VER='test-vBeta'
|
||||
fi
|
||||
echo '::set-output name=image_ver::'$IMAGE_VER
|
||||
- name: Test Version
|
||||
- name: Check Version
|
||||
run: |
|
||||
echo $GITHUB_REF
|
||||
echo ${{ steps.gen_ver.outputs.image_ver }}
|
||||
|
|
@ -61,27 +62,46 @@ jobs:
|
|||
host: ${{env.DEPLOY_HOST}}
|
||||
username: frappet
|
||||
password: ${{ secrets.SSH_PASSWORD }}
|
||||
port: 22
|
||||
port: ${{env.DEPLOY_PORT}}
|
||||
script: |
|
||||
cd "${{env.COMPOSE_PATH}}"
|
||||
docker-compose pull
|
||||
docker-compose up -d
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
echo "${{ steps.gen_ver.outputs.image_ver }}"> success
|
||||
- uses: snow-actions/line-notify@v1.1.0
|
||||
- name: Notify Discord Success
|
||||
if: success()
|
||||
with:
|
||||
access_token: ${{ env.TOKEN_LINE }}
|
||||
message: |
|
||||
-Success✅✅✅
|
||||
Image: ${{env.IMAGE_NAME}}
|
||||
Version: ${{ github.event.inputs.IMAGE_VER }}
|
||||
By: ${{secrets.DOCKER_USER}}
|
||||
- uses: snow-actions/line-notify@v1.1.0
|
||||
run: |
|
||||
curl -H "Content-Type: application/json" \
|
||||
-X POST \
|
||||
-d '{
|
||||
"embeds": [{
|
||||
"title": "✅ Deployment Success!",
|
||||
"description": "**Details:**\n- Image: `${{env.IMAGE_NAME}}`\n- Version: `${{ steps.gen_ver.outputs.image_ver }}`\n- Deployed by: `${{github.actor}}`",
|
||||
"color": 3066993,
|
||||
"footer": {
|
||||
"text": "Release Notification",
|
||||
"icon_url": "https://example.com/success-icon.png"
|
||||
},
|
||||
"timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"
|
||||
}]
|
||||
}' \
|
||||
${{ secrets.DISCORD_WEBHOOK }}
|
||||
|
||||
- name: Notify Discord Failure
|
||||
if: failure()
|
||||
with:
|
||||
access_token: ${{ env.TOKEN_LINE }}
|
||||
message: |
|
||||
-Failure❌❌❌
|
||||
Image: ${{env.IMAGE_NAME}}
|
||||
Version: ${{ github.event.inputs.IMAGE_VER }}
|
||||
By: ${{secrets.DOCKER_USER}}
|
||||
run: |
|
||||
curl -H "Content-Type: application/json" \
|
||||
-X POST \
|
||||
-d '{
|
||||
"embeds": [{
|
||||
"title": "❌ Deployment Failed!",
|
||||
"description": "**Details:**\n- Image: `${{env.IMAGE_NAME}}`\n- Version: `${{ steps.gen_ver.outputs.image_ver }}`\n- Attempted by: `${{github.actor}}`",
|
||||
"color": 15158332,
|
||||
"footer": {
|
||||
"text": "Release Notification",
|
||||
"icon_url": "https://example.com/failure-icon.png"
|
||||
},
|
||||
"timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"
|
||||
}]
|
||||
}' \
|
||||
${{ secrets.DISCORD_WEBHOOK }}
|
||||
|
|
|
|||
76
.github/workflows/release_discipline.yaml
vendored
76
.github/workflows/release_discipline.yaml
vendored
|
|
@ -3,30 +3,31 @@ run-name: release-dev ${{ github.actor }}
|
|||
on:
|
||||
# push:
|
||||
# tags:
|
||||
# - 'v[0-9]+.[0-9]+.[0-9]+'
|
||||
# tags-ignore:
|
||||
# - '2.*'
|
||||
# Allow run workflow manually from Action tab
|
||||
# - "discipline-[0-9]+.[0-9]+.[0-9]+"
|
||||
workflow_dispatch:
|
||||
env:
|
||||
REGISTRY: docker.frappet.com
|
||||
IMAGE_NAME: ehr/bma-ehr-discipline-service
|
||||
DEPLOY_HOST: frappet.com
|
||||
COMPOSE_PATH: /home/frappet/docker/bma-ehr-discipline
|
||||
DEPLOY_PORT: 10102
|
||||
# COMPOSE_PATH: /home/frappet/docker/bma-ehr
|
||||
COMPOSE_PATH: /home/frappet/docker/bma/bma-ehr-discipline
|
||||
TOKEN_LINE: uxuK5hDzS2DsoC5piJBrWRLiz8GgY7iMZZldOWsDDF0
|
||||
|
||||
jobs:
|
||||
# act workflow_dispatch -W .github/workflows/release_discipline.yaml --input IMAGE_VER=discipline-1.0.0 -s DOCKER_USER=sorawit -s DOCKER_PASS=P@ssword -s SSH_PASSWORD=P@ssw0rd
|
||||
# act workflow_dispatch -W .github/workflows/release_discipline.yaml --input IMAGE_VER=latest -s DOCKER_USER=admin -s DOCKER_PASS=FPTadmin2357 -s SSH_PASSWORD=FPTadmin2357
|
||||
release-dev:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
# skip Set up QEMU because it fail on act and container
|
||||
- name: Set output tags
|
||||
id: vars
|
||||
run: echo "tag=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT
|
||||
- name: Gen Version
|
||||
id: gen_ver
|
||||
run: |
|
||||
if [[ $GITHUB_REF == 'refs/tags/'* ]]; then
|
||||
IMAGE_VER='${GITHUB_REF/refs\/tags\//}'
|
||||
IMAGE_VER=${{ steps.vars.outputs.tag }}
|
||||
else
|
||||
IMAGE_VER=${{ github.event.inputs.IMAGE_VER }}
|
||||
fi
|
||||
|
|
@ -34,7 +35,7 @@ jobs:
|
|||
IMAGE_VER='test-vBeta'
|
||||
fi
|
||||
echo '::set-output name=image_ver::'$IMAGE_VER
|
||||
- name: Test Version
|
||||
- name: Check Version
|
||||
run: |
|
||||
echo $GITHUB_REF
|
||||
echo ${{ steps.gen_ver.outputs.image_ver }}
|
||||
|
|
@ -61,27 +62,46 @@ jobs:
|
|||
host: ${{env.DEPLOY_HOST}}
|
||||
username: frappet
|
||||
password: ${{ secrets.SSH_PASSWORD }}
|
||||
port: 22
|
||||
port: ${{env.DEPLOY_PORT}}
|
||||
script: |
|
||||
cd "${{env.COMPOSE_PATH}}"
|
||||
docker-compose pull
|
||||
docker-compose up -d
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
echo "${{ steps.gen_ver.outputs.image_ver }}"> success
|
||||
- uses: snow-actions/line-notify@v1.1.0
|
||||
- name: Notify Discord Success
|
||||
if: success()
|
||||
with:
|
||||
access_token: ${{ env.TOKEN_LINE }}
|
||||
message: |
|
||||
-Success✅✅✅
|
||||
Image: ${{env.IMAGE_NAME}}
|
||||
Version: ${{ github.event.inputs.IMAGE_VER }}
|
||||
By: ${{secrets.DOCKER_USER}}
|
||||
- uses: snow-actions/line-notify@v1.1.0
|
||||
run: |
|
||||
curl -H "Content-Type: application/json" \
|
||||
-X POST \
|
||||
-d '{
|
||||
"embeds": [{
|
||||
"title": "✅ Deployment Success!",
|
||||
"description": "**Details:**\n- Image: `${{env.IMAGE_NAME}}`\n- Version: `${{ steps.gen_ver.outputs.image_ver }}`\n- Deployed by: `${{github.actor}}`",
|
||||
"color": 3066993,
|
||||
"footer": {
|
||||
"text": "Release Notification",
|
||||
"icon_url": "https://example.com/success-icon.png"
|
||||
},
|
||||
"timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"
|
||||
}]
|
||||
}' \
|
||||
${{ secrets.DISCORD_WEBHOOK }}
|
||||
|
||||
- name: Notify Discord Failure
|
||||
if: failure()
|
||||
with:
|
||||
access_token: ${{ env.TOKEN_LINE }}
|
||||
message: |
|
||||
-Failure❌❌❌
|
||||
Image: ${{env.IMAGE_NAME}}
|
||||
Version: ${{ github.event.inputs.IMAGE_VER }}
|
||||
By: ${{secrets.DOCKER_USER}}
|
||||
run: |
|
||||
curl -H "Content-Type: application/json" \
|
||||
-X POST \
|
||||
-d '{
|
||||
"embeds": [{
|
||||
"title": "❌ Deployment Failed!",
|
||||
"description": "**Details:**\n- Image: `${{env.IMAGE_NAME}}`\n- Version: `${{ steps.gen_ver.outputs.image_ver }}`\n- Attempted by: `${{github.actor}}`",
|
||||
"color": 15158332,
|
||||
"footer": {
|
||||
"text": "Release Notification",
|
||||
"icon_url": "https://example.com/failure-icon.png"
|
||||
},
|
||||
"timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"
|
||||
}]
|
||||
}' \
|
||||
${{ secrets.DISCORD_WEBHOOK }}
|
||||
|
|
|
|||
84
.github/workflows/release_insignia.yaml
vendored
84
.github/workflows/release_insignia.yaml
vendored
|
|
@ -3,30 +3,31 @@ run-name: release-dev ${{ github.actor }}
|
|||
on:
|
||||
# push:
|
||||
# tags:
|
||||
# - 'v[0-9]+.[0-9]+.[0-9]+'
|
||||
# tags-ignore:
|
||||
# - '2.*'
|
||||
# Allow run workflow manually from Action tab
|
||||
# - "insignia-[0-9]+.[0-9]+.[0-9]+"
|
||||
workflow_dispatch:
|
||||
env:
|
||||
REGISTRY: docker.frappet.com
|
||||
IMAGE_NAME: ehr/bma-ehr-insignia-service
|
||||
DEPLOY_HOST: frappet.com
|
||||
COMPOSE_PATH: /home/frappet/docker/bma-ehr-insignia
|
||||
DEPLOY_PORT: 10102
|
||||
# COMPOSE_PATH: /home/frappet/docker/bma-ehr
|
||||
COMPOSE_PATH: /home/frappet/docker/bma/bma-ehr-insignia
|
||||
TOKEN_LINE: uxuK5hDzS2DsoC5piJBrWRLiz8GgY7iMZZldOWsDDF0
|
||||
|
||||
jobs:
|
||||
# act workflow_dispatch -W .github/workflows/release_insignia.yaml --input IMAGE_VER=insignia-1.0.0 -s DOCKER_USER=sorawit -s DOCKER_PASS=P@ssword -s SSH_PASSWORD=P@ssw0rd
|
||||
# act workflow_dispatch -W .github/workflows/release_insignia.yaml --input IMAGE_VER=latest -s DOCKER_USER=admin -s DOCKER_PASS=FPTadmin2357 -s SSH_PASSWORD=FPTadmin2357
|
||||
release-dev:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
# skip Set up QEMU because it fail on act and container
|
||||
- name: Set output tags
|
||||
id: vars
|
||||
run: echo "tag=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT
|
||||
- name: Gen Version
|
||||
id: gen_ver
|
||||
run: |
|
||||
if [[ $GITHUB_REF == 'refs/tags/'* ]]; then
|
||||
IMAGE_VER='${GITHUB_REF/refs\/tags\//}'
|
||||
IMAGE_VER=${{ steps.vars.outputs.tag }}
|
||||
else
|
||||
IMAGE_VER=${{ github.event.inputs.IMAGE_VER }}
|
||||
fi
|
||||
|
|
@ -34,10 +35,11 @@ jobs:
|
|||
IMAGE_VER='test-vBeta'
|
||||
fi
|
||||
echo '::set-output name=image_ver::'$IMAGE_VER
|
||||
- name: Test Version
|
||||
- name: Check Version
|
||||
run: |
|
||||
echo $GITHUB_REF
|
||||
echo ${{ steps.gen_ver.outputs.image_ver }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
- name: Login in to registry
|
||||
|
|
@ -46,42 +48,60 @@ jobs:
|
|||
registry: ${{env.REGISTRY}}
|
||||
username: ${{secrets.DOCKER_USER}}
|
||||
password: ${{secrets.DOCKER_PASS}}
|
||||
- name: Build and load local docker image
|
||||
- name: Build and push docker image
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64
|
||||
file: BMA.EHR.Insignia.Service/Dockerfile
|
||||
file: BMA.EHR.Insignia/Dockerfile
|
||||
push: true
|
||||
tags: ${{env.REGISTRY}}/${{env.IMAGE_NAME}}:${{ steps.gen_ver.outputs.image_ver }},${{env.REGISTRY}}/${{env.IMAGE_NAME}}:latest
|
||||
|
||||
- name: Reload docker compose
|
||||
- name: Remote Deployment
|
||||
uses: appleboy/ssh-action@v0.1.8
|
||||
with:
|
||||
host: ${{env.DEPLOY_HOST}}
|
||||
username: frappet
|
||||
password: ${{ secrets.SSH_PASSWORD }}
|
||||
port: 22
|
||||
port: 10102
|
||||
script: |
|
||||
cd "${{env.COMPOSE_PATH}}"
|
||||
docker-compose pull
|
||||
docker-compose up -d
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
echo "${{ steps.gen_ver.outputs.image_ver }}"> success
|
||||
- uses: snow-actions/line-notify@v1.1.0
|
||||
- name: Notify Discord Success
|
||||
if: success()
|
||||
with:
|
||||
access_token: ${{ env.TOKEN_LINE }}
|
||||
message: |
|
||||
-Success✅✅✅
|
||||
Image: ${{env.IMAGE_NAME}}
|
||||
Version: ${{ github.event.inputs.IMAGE_VER }}
|
||||
By: ${{secrets.DOCKER_USER}}
|
||||
- uses: snow-actions/line-notify@v1.1.0
|
||||
run: |
|
||||
curl -H "Content-Type: application/json" \
|
||||
-X POST \
|
||||
-d '{
|
||||
"embeds": [{
|
||||
"title": "✅ Deployment Success!",
|
||||
"description": "**Details:**\n- Image: `${{env.IMAGE_NAME}}`\n- Version: `${{ steps.gen_ver.outputs.image_ver }}`\n- Deployed by: `${{github.actor}}`",
|
||||
"color": 3066993,
|
||||
"footer": {
|
||||
"text": "Release Notification",
|
||||
"icon_url": "https://example.com/success-icon.png"
|
||||
},
|
||||
"timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"
|
||||
}]
|
||||
}' \
|
||||
${{ secrets.DISCORD_WEBHOOK }}
|
||||
|
||||
- name: Notify Discord Failure
|
||||
if: failure()
|
||||
with:
|
||||
access_token: ${{ env.TOKEN_LINE }}
|
||||
message: |
|
||||
-Failure❌❌❌
|
||||
Image: ${{env.IMAGE_NAME}}
|
||||
Version: ${{ github.event.inputs.IMAGE_VER }}
|
||||
By: ${{secrets.DOCKER_USER}}
|
||||
run: |
|
||||
curl -H "Content-Type: application/json" \
|
||||
-X POST \
|
||||
-d '{
|
||||
"embeds": [{
|
||||
"title": "❌ Deployment Failed!",
|
||||
"description": "**Details:**\n- Image: `${{env.IMAGE_NAME}}`\n- Version: `${{ steps.gen_ver.outputs.image_ver }}`\n- Attempted by: `${{github.actor}}`",
|
||||
"color": 15158332,
|
||||
"footer": {
|
||||
"text": "Release Notification",
|
||||
"icon_url": "https://example.com/failure-icon.png"
|
||||
},
|
||||
"timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"
|
||||
}]
|
||||
}' \
|
||||
${{ secrets.DISCORD_WEBHOOK }}
|
||||
|
|
|
|||
88
.github/workflows/release_leave.yaml
vendored
88
.github/workflows/release_leave.yaml
vendored
|
|
@ -3,30 +3,31 @@ run-name: release-dev ${{ github.actor }}
|
|||
on:
|
||||
# push:
|
||||
# tags:
|
||||
# - 'v[0-9]+.[0-9]+.[0-9]+'
|
||||
# tags-ignore:
|
||||
# - '2.*'
|
||||
# Allow run workflow manually from Action tab
|
||||
# - "leave-[0-9]+.[0-9]+.[0-9]+"
|
||||
workflow_dispatch:
|
||||
env:
|
||||
REGISTRY: docker.frappet.com
|
||||
IMAGE_NAME: ehr/bma-ehr-leave-service
|
||||
DEPLOY_HOST: frappet.com
|
||||
COMPOSE_PATH: /home/frappet/docker/bma-ehr-leave
|
||||
DEPLOY_PORT: 10102
|
||||
# COMPOSE_PATH: /home/frappet/docker/bma-ehr
|
||||
COMPOSE_PATH: /home/frappet/docker/bma/bma-ehr-leave
|
||||
TOKEN_LINE: uxuK5hDzS2DsoC5piJBrWRLiz8GgY7iMZZldOWsDDF0
|
||||
|
||||
jobs:
|
||||
# act workflow_dispatch -W .github/workflows/release_leave.yaml --input IMAGE_VER=leave-1.0.0 -s DOCKER_USER=sorawit -s DOCKER_PASS=P@ssword -s SSH_PASSWORD=P@ssw0rd
|
||||
# act workflow_dispatch -W .github/workflows/release_leave.yaml --input IMAGE_VER=latest -s DOCKER_USER=admin -s DOCKER_PASS=FPTadmin2357 -s SSH_PASSWORD=FPTadmin2357
|
||||
release-dev:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
# skip Set up QEMU because it fail on act and container
|
||||
- name: Set output tags
|
||||
id: vars
|
||||
run: echo "tag=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT
|
||||
- name: Gen Version
|
||||
id: gen_ver
|
||||
run: |
|
||||
if [[ $GITHUB_REF == 'refs/tags/'* ]]; then
|
||||
IMAGE_VER='${GITHUB_REF/refs\/tags\//}'
|
||||
IMAGE_VER=${{ steps.vars.outputs.tag }}
|
||||
else
|
||||
IMAGE_VER=${{ github.event.inputs.IMAGE_VER }}
|
||||
fi
|
||||
|
|
@ -34,10 +35,11 @@ jobs:
|
|||
IMAGE_VER='test-vBeta'
|
||||
fi
|
||||
echo '::set-output name=image_ver::'$IMAGE_VER
|
||||
- name: Test Version
|
||||
- name: Check Version
|
||||
run: |
|
||||
echo $GITHUB_REF
|
||||
echo ${{ steps.gen_ver.outputs.image_ver }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
- name: Login in to registry
|
||||
|
|
@ -46,42 +48,60 @@ jobs:
|
|||
registry: ${{env.REGISTRY}}
|
||||
username: ${{secrets.DOCKER_USER}}
|
||||
password: ${{secrets.DOCKER_PASS}}
|
||||
- name: Build and load local docker image
|
||||
uses: docker/build-push-action@v5
|
||||
- name: Build and push docker image
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64
|
||||
file: BMA.EHR.Leave.Service/Dockerfile
|
||||
file: BMA.EHR.Leave/Dockerfile
|
||||
push: true
|
||||
tags: ${{env.REGISTRY}}/${{env.IMAGE_NAME}}:${{ steps.gen_ver.outputs.image_ver }},${{env.REGISTRY}}/${{env.IMAGE_NAME}}:latest
|
||||
|
||||
- name: Reload docker compose
|
||||
uses: appleboy/ssh-action@v0.1.8
|
||||
- name: Remote Deployment
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{env.DEPLOY_HOST}}
|
||||
username: frappet
|
||||
password: ${{ secrets.SSH_PASSWORD }}
|
||||
port: 22
|
||||
port: 10102
|
||||
script: |
|
||||
cd "${{env.COMPOSE_PATH}}"
|
||||
docker-compose pull
|
||||
docker-compose up -d
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
echo "${{ steps.gen_ver.outputs.image_ver }}"> success
|
||||
- uses: snow-actions/line-notify@v1.1.0
|
||||
- name: Notify Discord Success
|
||||
if: success()
|
||||
with:
|
||||
access_token: ${{ env.TOKEN_LINE }}
|
||||
message: |
|
||||
-Success✅✅✅
|
||||
Image: ${{env.IMAGE_NAME}}
|
||||
Version: ${{ github.event.inputs.IMAGE_VER }}
|
||||
By: ${{secrets.DOCKER_USER}}
|
||||
- uses: snow-actions/line-notify@v1.1.0
|
||||
run: |
|
||||
curl -H "Content-Type: application/json" \
|
||||
-X POST \
|
||||
-d '{
|
||||
"embeds": [{
|
||||
"title": "✅ Deployment Success!",
|
||||
"description": "**Details:**\n- Image: `${{env.IMAGE_NAME}}`\n- Version: `${{ steps.gen_ver.outputs.image_ver }}`\n- Deployed by: `${{github.actor}}`",
|
||||
"color": 3066993,
|
||||
"footer": {
|
||||
"text": "Release Notification",
|
||||
"icon_url": "https://example.com/success-icon.png"
|
||||
},
|
||||
"timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"
|
||||
}]
|
||||
}' \
|
||||
${{ secrets.DISCORD_WEBHOOK }}
|
||||
|
||||
- name: Notify Discord Failure
|
||||
if: failure()
|
||||
with:
|
||||
access_token: ${{ env.TOKEN_LINE }}
|
||||
message: |
|
||||
-Failure❌❌❌
|
||||
Image: ${{env.IMAGE_NAME}}
|
||||
Version: ${{ github.event.inputs.IMAGE_VER }}
|
||||
By: ${{secrets.DOCKER_USER}}
|
||||
run: |
|
||||
curl -H "Content-Type: application/json" \
|
||||
-X POST \
|
||||
-d '{
|
||||
"embeds": [{
|
||||
"title": "❌ Deployment Failed!",
|
||||
"description": "**Details:**\n- Image: `${{env.IMAGE_NAME}}`\n- Version: `${{ steps.gen_ver.outputs.image_ver }}`\n- Attempted by: `${{github.actor}}`",
|
||||
"color": 15158332,
|
||||
"footer": {
|
||||
"text": "Release Notification",
|
||||
"icon_url": "https://example.com/failure-icon.png"
|
||||
},
|
||||
"timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"
|
||||
}]
|
||||
}' \
|
||||
${{ secrets.DISCORD_WEBHOOK }}
|
||||
|
|
|
|||
107
.github/workflows/release_metadata.yaml
vendored
Normal file
107
.github/workflows/release_metadata.yaml
vendored
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
name: release-dev
|
||||
run-name: release-dev ${{ github.actor }}
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "metadata-[0-9]+.[0-9]+.[0-9]+"
|
||||
workflow_dispatch:
|
||||
env:
|
||||
REGISTRY: docker.frappet.com
|
||||
IMAGE_NAME: ehr/bma-ehr-metadata-service
|
||||
DEPLOY_HOST: frappet.com
|
||||
DEPLOY_PORT: 10102
|
||||
# COMPOSE_PATH: /home/frappet/docker/bma-ehr
|
||||
COMPOSE_PATH: /home/frappet/docker/bma/bma-ehr-metadata
|
||||
TOKEN_LINE: uxuK5hDzS2DsoC5piJBrWRLiz8GgY7iMZZldOWsDDF0
|
||||
|
||||
jobs:
|
||||
# act workflow_dispatch -W .github/workflows/release_metadata.yaml --input IMAGE_VER=latest -s DOCKER_USER=admin -s DOCKER_PASS=FPTadmin2357 -s SSH_PASSWORD=FPTadmin2357
|
||||
release-dev:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set output tags
|
||||
id: vars
|
||||
run: echo "tag=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT
|
||||
- name: Gen Version
|
||||
id: gen_ver
|
||||
run: |
|
||||
if [[ $GITHUB_REF == 'refs/tags/'* ]]; then
|
||||
IMAGE_VER=${{ steps.vars.outputs.tag }}
|
||||
else
|
||||
IMAGE_VER=${{ github.event.inputs.IMAGE_VER }}
|
||||
fi
|
||||
if [[ $IMAGE_VER == '' ]]; then
|
||||
IMAGE_VER='test-vBeta'
|
||||
fi
|
||||
echo '::set-output name=image_ver::'$IMAGE_VER
|
||||
- name: Check Version
|
||||
run: |
|
||||
echo $GITHUB_REF
|
||||
echo ${{ steps.gen_ver.outputs.image_ver }}
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
- name: Login in to registry
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ${{env.REGISTRY}}
|
||||
username: ${{secrets.DOCKER_USER}}
|
||||
password: ${{secrets.DOCKER_PASS}}
|
||||
- name: Build and load local docker image
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64
|
||||
file: BMA.EHR.MetaData.Service/Dockerfile
|
||||
push: true
|
||||
tags: ${{env.REGISTRY}}/${{env.IMAGE_NAME}}:${{ steps.gen_ver.outputs.image_ver }},${{env.REGISTRY}}/${{env.IMAGE_NAME}}:latest
|
||||
|
||||
- name: Reload docker compose
|
||||
uses: appleboy/ssh-action@v0.1.8
|
||||
with:
|
||||
host: ${{env.DEPLOY_HOST}}
|
||||
username: frappet
|
||||
password: ${{ secrets.SSH_PASSWORD }}
|
||||
port: ${{env.DEPLOY_PORT}}
|
||||
script: |
|
||||
cd "${{env.COMPOSE_PATH}}"
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
echo "${{ steps.gen_ver.outputs.image_ver }}"> success
|
||||
- name: Notify Discord Success
|
||||
if: success()
|
||||
run: |
|
||||
curl -H "Content-Type: application/json" \
|
||||
-X POST \
|
||||
-d '{
|
||||
"embeds": [{
|
||||
"title": "✅ Deployment Success!",
|
||||
"description": "**Details:**\n- Image: `${{env.IMAGE_NAME}}`\n- Version: `${{ steps.gen_ver.outputs.image_ver }}`\n- Deployed by: `${{github.actor}}`",
|
||||
"color": 3066993,
|
||||
"footer": {
|
||||
"text": "Release Notification",
|
||||
"icon_url": "https://example.com/success-icon.png"
|
||||
},
|
||||
"timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"
|
||||
}]
|
||||
}' \
|
||||
${{ secrets.DISCORD_WEBHOOK }}
|
||||
|
||||
- name: Notify Discord Failure
|
||||
if: failure()
|
||||
run: |
|
||||
curl -H "Content-Type: application/json" \
|
||||
-X POST \
|
||||
-d '{
|
||||
"embeds": [{
|
||||
"title": "❌ Deployment Failed!",
|
||||
"description": "**Details:**\n- Image: `${{env.IMAGE_NAME}}`\n- Version: `${{ steps.gen_ver.outputs.image_ver }}`\n- Attempted by: `${{github.actor}}`",
|
||||
"color": 15158332,
|
||||
"footer": {
|
||||
"text": "Release Notification",
|
||||
"icon_url": "https://example.com/failure-icon.png"
|
||||
},
|
||||
"timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"
|
||||
}]
|
||||
}' \
|
||||
${{ secrets.DISCORD_WEBHOOK }}
|
||||
10
.github/workflows/release_orgEmployee.yaml
vendored
10
.github/workflows/release_orgEmployee.yaml
vendored
|
|
@ -12,7 +12,9 @@ env:
|
|||
REGISTRY: docker.frappet.com
|
||||
IMAGE_NAME: ehr/bma-ehr-org-employee-service
|
||||
DEPLOY_HOST: frappet.com
|
||||
COMPOSE_PATH: /home/frappet/docker/bma-ehr-org-employee
|
||||
DEPLOY_PORT: 10102
|
||||
# COMPOSE_PATH: /home/frappet/docker/bma-ehr
|
||||
COMPOSE_PATH: /home/frappet/docker/bma/bma-ehr-org-employee
|
||||
TOKEN_LINE: uxuK5hDzS2DsoC5piJBrWRLiz8GgY7iMZZldOWsDDF0
|
||||
|
||||
jobs:
|
||||
|
|
@ -61,11 +63,11 @@ jobs:
|
|||
host: ${{env.DEPLOY_HOST}}
|
||||
username: frappet
|
||||
password: ${{ secrets.SSH_PASSWORD }}
|
||||
port: 22
|
||||
port: ${{env.DEPLOY_PORT}}
|
||||
script: |
|
||||
cd "${{env.COMPOSE_PATH}}"
|
||||
docker-compose pull
|
||||
docker-compose up -d
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
echo "${{ steps.gen_ver.outputs.image_ver }}"> success
|
||||
- uses: snow-actions/line-notify@v1.1.0
|
||||
if: success()
|
||||
|
|
|
|||
76
.github/workflows/release_placement.yaml
vendored
76
.github/workflows/release_placement.yaml
vendored
|
|
@ -3,30 +3,31 @@ run-name: release-dev ${{ github.actor }}
|
|||
on:
|
||||
# push:
|
||||
# tags:
|
||||
# - 'v[0-9]+.[0-9]+.[0-9]+'
|
||||
# tags-ignore:
|
||||
# - '2.*'
|
||||
# Allow run workflow manually from Action tab
|
||||
# - "placement-[0-9]+.[0-9]+.[0-9]+"
|
||||
workflow_dispatch:
|
||||
env:
|
||||
REGISTRY: docker.frappet.com
|
||||
IMAGE_NAME: ehr/bma-ehr-placement-service
|
||||
DEPLOY_HOST: frappet.com
|
||||
COMPOSE_PATH: /home/frappet/docker/bma-ehr-placement
|
||||
DEPLOY_PORT: 10102
|
||||
# COMPOSE_PATH: /home/frappet/docker/bma-ehr
|
||||
COMPOSE_PATH: /home/frappet/docker/bma/bma-ehr-placement
|
||||
TOKEN_LINE: uxuK5hDzS2DsoC5piJBrWRLiz8GgY7iMZZldOWsDDF0
|
||||
|
||||
jobs:
|
||||
# act workflow_dispatch -W .github/workflows/release_placement.yaml --input IMAGE_VER=placement-1.0.0 -s DOCKER_USER=sorawit -s DOCKER_PASS=P@ssword -s SSH_PASSWORD=P@ssw0rd
|
||||
# act workflow_dispatch -W .github/workflows/release_placement.yaml --input IMAGE_VER=latest -s DOCKER_USER=admin -s DOCKER_PASS=FPTadmin2357 -s SSH_PASSWORD=FPTadmin2357
|
||||
release-dev:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
# skip Set up QEMU because it fail on act and container
|
||||
- name: Set output tags
|
||||
id: vars
|
||||
run: echo "tag=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT
|
||||
- name: Gen Version
|
||||
id: gen_ver
|
||||
run: |
|
||||
if [[ $GITHUB_REF == 'refs/tags/'* ]]; then
|
||||
IMAGE_VER='${GITHUB_REF/refs\/tags\//}'
|
||||
IMAGE_VER=${{ steps.vars.outputs.tag }}
|
||||
else
|
||||
IMAGE_VER=${{ github.event.inputs.IMAGE_VER }}
|
||||
fi
|
||||
|
|
@ -34,7 +35,7 @@ jobs:
|
|||
IMAGE_VER='test-vBeta'
|
||||
fi
|
||||
echo '::set-output name=image_ver::'$IMAGE_VER
|
||||
- name: Test Version
|
||||
- name: Check Version
|
||||
run: |
|
||||
echo $GITHUB_REF
|
||||
echo ${{ steps.gen_ver.outputs.image_ver }}
|
||||
|
|
@ -61,27 +62,46 @@ jobs:
|
|||
host: ${{env.DEPLOY_HOST}}
|
||||
username: frappet
|
||||
password: ${{ secrets.SSH_PASSWORD }}
|
||||
port: 22
|
||||
port: ${{env.DEPLOY_PORT}}
|
||||
script: |
|
||||
cd "${{env.COMPOSE_PATH}}"
|
||||
docker-compose pull
|
||||
docker-compose up -d
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
echo "${{ steps.gen_ver.outputs.image_ver }}"> success
|
||||
- uses: snow-actions/line-notify@v1.1.0
|
||||
- name: Notify Discord Success
|
||||
if: success()
|
||||
with:
|
||||
access_token: ${{ env.TOKEN_LINE }}
|
||||
message: |
|
||||
-Success✅✅✅
|
||||
Image: ${{env.IMAGE_NAME}}
|
||||
Version: ${{ github.event.inputs.IMAGE_VER }}
|
||||
By: ${{secrets.DOCKER_USER}}
|
||||
- uses: snow-actions/line-notify@v1.1.0
|
||||
run: |
|
||||
curl -H "Content-Type: application/json" \
|
||||
-X POST \
|
||||
-d '{
|
||||
"embeds": [{
|
||||
"title": "✅ Deployment Success!",
|
||||
"description": "**Details:**\n- Image: `${{env.IMAGE_NAME}}`\n- Version: `${{ steps.gen_ver.outputs.image_ver }}`\n- Deployed by: `${{github.actor}}`",
|
||||
"color": 3066993,
|
||||
"footer": {
|
||||
"text": "Release Notification",
|
||||
"icon_url": "https://example.com/success-icon.png"
|
||||
},
|
||||
"timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"
|
||||
}]
|
||||
}' \
|
||||
${{ secrets.DISCORD_WEBHOOK }}
|
||||
|
||||
- name: Notify Discord Failure
|
||||
if: failure()
|
||||
with:
|
||||
access_token: ${{ env.TOKEN_LINE }}
|
||||
message: |
|
||||
-Failure❌❌❌
|
||||
Image: ${{env.IMAGE_NAME}}
|
||||
Version: ${{ github.event.inputs.IMAGE_VER }}
|
||||
By: ${{secrets.DOCKER_USER}}
|
||||
run: |
|
||||
curl -H "Content-Type: application/json" \
|
||||
-X POST \
|
||||
-d '{
|
||||
"embeds": [{
|
||||
"title": "❌ Deployment Failed!",
|
||||
"description": "**Details:**\n- Image: `${{env.IMAGE_NAME}}`\n- Version: `${{ steps.gen_ver.outputs.image_ver }}`\n- Attempted by: `${{github.actor}}`",
|
||||
"color": 15158332,
|
||||
"footer": {
|
||||
"text": "Release Notification",
|
||||
"icon_url": "https://example.com/failure-icon.png"
|
||||
},
|
||||
"timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"
|
||||
}]
|
||||
}' \
|
||||
${{ secrets.DISCORD_WEBHOOK }}
|
||||
|
|
|
|||
76
.github/workflows/release_report.yaml
vendored
76
.github/workflows/release_report.yaml
vendored
|
|
@ -3,30 +3,31 @@ run-name: release-dev ${{ github.actor }}
|
|||
on:
|
||||
# push:
|
||||
# tags:
|
||||
# - 'v[0-9]+.[0-9]+.[0-9]+'
|
||||
# tags-ignore:
|
||||
# - '2.*'
|
||||
# Allow run workflow manually from Action tab
|
||||
# - "reportv2-[0-9]+.[0-9]+.[0-9]+"
|
||||
workflow_dispatch:
|
||||
env:
|
||||
REGISTRY: docker.frappet.com
|
||||
IMAGE_NAME: ehr/bma-ehr-report-v2-service
|
||||
DEPLOY_HOST: frappet.com
|
||||
COMPOSE_PATH: /home/frappet/docker/bma-ehr-report-v2
|
||||
DEPLOY_PORT: 10102
|
||||
# COMPOSE_PATH: /home/frappet/docker/bma-ehr
|
||||
COMPOSE_PATH: /home/frappet/docker/bma/bma-ehr-report-v2
|
||||
TOKEN_LINE: uxuK5hDzS2DsoC5piJBrWRLiz8GgY7iMZZldOWsDDF0
|
||||
|
||||
jobs:
|
||||
# act workflow_dispatch -W .github/workflows/release_report.yaml --input IMAGE_VER=report-1.0.0 -s DOCKER_USER=sorawit -s DOCKER_PASS=P@ssword -s SSH_PASSWORD=P@ssw0rd
|
||||
# act workflow_dispatch -W .github/workflows/release_report.yaml --input IMAGE_VER=latest -s DOCKER_USER=admin -s DOCKER_PASS=FPTadmin2357 -s SSH_PASSWORD=FPTadmin2357
|
||||
release-dev:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
# skip Set up QEMU because it fail on act and container
|
||||
- name: Set output tags
|
||||
id: vars
|
||||
run: echo "tag=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT
|
||||
- name: Gen Version
|
||||
id: gen_ver
|
||||
run: |
|
||||
if [[ $GITHUB_REF == 'refs/tags/'* ]]; then
|
||||
IMAGE_VER='${GITHUB_REF/refs\/tags\//}'
|
||||
IMAGE_VER=${{ steps.vars.outputs.tag }}
|
||||
else
|
||||
IMAGE_VER=${{ github.event.inputs.IMAGE_VER }}
|
||||
fi
|
||||
|
|
@ -34,7 +35,7 @@ jobs:
|
|||
IMAGE_VER='test-vBeta'
|
||||
fi
|
||||
echo '::set-output name=image_ver::'$IMAGE_VER
|
||||
- name: Test Version
|
||||
- name: Check Version
|
||||
run: |
|
||||
echo $GITHUB_REF
|
||||
echo ${{ steps.gen_ver.outputs.image_ver }}
|
||||
|
|
@ -61,27 +62,46 @@ jobs:
|
|||
host: ${{env.DEPLOY_HOST}}
|
||||
username: frappet
|
||||
password: ${{ secrets.SSH_PASSWORD }}
|
||||
port: 22
|
||||
port: ${{env.DEPLOY_PORT}}
|
||||
script: |
|
||||
cd "${{env.COMPOSE_PATH}}"
|
||||
docker-compose pull
|
||||
docker-compose up -d
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
echo "${{ steps.gen_ver.outputs.image_ver }}"> success
|
||||
- uses: snow-actions/line-notify@v1.1.0
|
||||
- name: Notify Discord Success
|
||||
if: success()
|
||||
with:
|
||||
access_token: ${{ env.TOKEN_LINE }}
|
||||
message: |
|
||||
-Success✅✅✅
|
||||
Image: ${{env.IMAGE_NAME}}
|
||||
Version: ${{ github.event.inputs.IMAGE_VER }}
|
||||
By: ${{secrets.DOCKER_USER}}
|
||||
- uses: snow-actions/line-notify@v1.1.0
|
||||
run: |
|
||||
curl -H "Content-Type: application/json" \
|
||||
-X POST \
|
||||
-d '{
|
||||
"embeds": [{
|
||||
"title": "✅ Deployment Success!",
|
||||
"description": "**Details:**\n- Image: `${{env.IMAGE_NAME}}`\n- Version: `${{ steps.gen_ver.outputs.image_ver }}`\n- Deployed by: `${{github.actor}}`",
|
||||
"color": 3066993,
|
||||
"footer": {
|
||||
"text": "Release Notification",
|
||||
"icon_url": "https://example.com/success-icon.png"
|
||||
},
|
||||
"timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"
|
||||
}]
|
||||
}' \
|
||||
${{ secrets.DISCORD_WEBHOOK }}
|
||||
|
||||
- name: Notify Discord Failure
|
||||
if: failure()
|
||||
with:
|
||||
access_token: ${{ env.TOKEN_LINE }}
|
||||
message: |
|
||||
-Failure❌❌❌
|
||||
Image: ${{env.IMAGE_NAME}}
|
||||
Version: ${{ github.event.inputs.IMAGE_VER }}
|
||||
By: ${{secrets.DOCKER_USER}}
|
||||
run: |
|
||||
curl -H "Content-Type: application/json" \
|
||||
-X POST \
|
||||
-d '{
|
||||
"embeds": [{
|
||||
"title": "❌ Deployment Failed!",
|
||||
"description": "**Details:**\n- Image: `${{env.IMAGE_NAME}}`\n- Version: `${{ steps.gen_ver.outputs.image_ver }}`\n- Attempted by: `${{github.actor}}`",
|
||||
"color": 15158332,
|
||||
"footer": {
|
||||
"text": "Release Notification",
|
||||
"icon_url": "https://example.com/failure-icon.png"
|
||||
},
|
||||
"timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"
|
||||
}]
|
||||
}' \
|
||||
${{ secrets.DISCORD_WEBHOOK }}
|
||||
|
|
|
|||
2
.github/workflows/release_reportV2.yaml
vendored
2
.github/workflows/release_reportV2.yaml
vendored
|
|
@ -12,7 +12,7 @@ env:
|
|||
REGISTRY: docker.frappet.com
|
||||
IMAGE_NAME: ehr/bma-ehr-report-v2-service
|
||||
DEPLOY_HOST: frappet.com
|
||||
COMPOSE_PATH: /home/frappet/docker/bma-ehr-report-v2
|
||||
COMPOSE_PATH: /home/frappet/docker/bma-ehr
|
||||
TOKEN_LINE: uxuK5hDzS2DsoC5piJBrWRLiz8GgY7iMZZldOWsDDF0
|
||||
|
||||
jobs:
|
||||
|
|
|
|||
19
.gitignore
vendored
19
.gitignore
vendored
|
|
@ -16,6 +16,19 @@
|
|||
# Mono auto generated files
|
||||
mono_crash.*
|
||||
|
||||
# JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
||||
.idea/
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
out/
|
||||
.idea_modules/
|
||||
atlassian-ide-plugin.xml
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
|
|
@ -361,3 +374,9 @@ MigrationBackup/
|
|||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
|
||||
# VS Code C# Dev Kit cache
|
||||
*.lscache
|
||||
|
||||
# Claude Code
|
||||
.claude/
|
||||
13
.idea/.idea.BMA.EHR.Solution/.idea/.gitignore
generated
vendored
13
.idea/.idea.BMA.EHR.Solution/.idea/.gitignore
generated
vendored
|
|
@ -1,13 +0,0 @@
|
|||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Rider ignored files
|
||||
/contentModel.xml
|
||||
/.idea.BMA.EHR.Solution.iml
|
||||
/projectSettingsUpdater.xml
|
||||
/modules.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
1
.idea/.idea.BMA.EHR.Solution/.idea/.name
generated
1
.idea/.idea.BMA.EHR.Solution/.idea/.name
generated
|
|
@ -1 +0,0 @@
|
|||
BMA.EHR.Solution
|
||||
|
Before Width: | Height: | Size: 16 B |
11
.idea/.idea.BMA.EHR.Solution/.idea/aws.xml
generated
11
.idea/.idea.BMA.EHR.Solution/.idea/aws.xml
generated
|
|
@ -1,11 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="accountSettings">
|
||||
<option name="activeRegion" value="us-east-1" />
|
||||
<option name="recentlyUsedRegions">
|
||||
<list>
|
||||
<option value="us-east-1" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
4
.idea/.idea.BMA.EHR.Solution/.idea/encodings.xml
generated
4
.idea/.idea.BMA.EHR.Solution/.idea/encodings.xml
generated
|
|
@ -1,4 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
|
||||
</project>
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="UserContentModel">
|
||||
<attachedFolders />
|
||||
<explicitIncludes />
|
||||
<explicitExcludes />
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/.idea.BMA.EHR.Solution/.idea/vcs.xml
generated
6
.idea/.idea.BMA.EHR.Solution/.idea/vcs.xml
generated
|
|
@ -1,6 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
82
.onedev-buildspec.yml
Normal file
82
.onedev-buildspec.yml
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
version: 37
|
||||
jobs:
|
||||
- name: CI for UAT
|
||||
steps:
|
||||
- !CheckoutStep
|
||||
name: checkout code
|
||||
cloneCredential: !DefaultCredential {}
|
||||
withLfs: false
|
||||
withSubmodules: false
|
||||
condition: ALL_PREVIOUS_STEPS_WERE_SUCCESSFUL
|
||||
- !GenerateChecksumStep
|
||||
name: generate project checksum
|
||||
files: '**/*.csproj'
|
||||
targetFile: checksum
|
||||
condition: ALL_PREVIOUS_STEPS_WERE_SUCCESSFUL
|
||||
- !SetupCacheStep
|
||||
name: set up nuget cache
|
||||
key: nuget_packages_@file:checksum@
|
||||
loadKeys:
|
||||
- nuget_packages
|
||||
paths:
|
||||
- /root/.nuget/packages
|
||||
uploadStrategy: UPLOAD_IF_NOT_HIT
|
||||
condition: ALL_PREVIOUS_STEPS_WERE_SUCCESSFUL
|
||||
- !CommandStep
|
||||
name: test and analyze
|
||||
runInContainer: true
|
||||
image: mcr.microsoft.com/dotnet/sdk
|
||||
interpreter: !DefaultInterpreter
|
||||
commands: |
|
||||
set -e
|
||||
dotnet tool install -g roslynator.dotnet.cli
|
||||
dotnet test -l trx --collect:"XPlat Code Coverage"
|
||||
#/root/.dotnet/tools/roslynator analyze -o roslynator-analysis.xml
|
||||
useTTY: true
|
||||
condition: NEVER
|
||||
- !PublishTRXReportStep
|
||||
name: publish unit test report
|
||||
reportName: Unit Test
|
||||
filePatterns: '**/*.trx'
|
||||
condition: NEVER
|
||||
- !PublishCoberturaReportStep
|
||||
name: publish code coverage report
|
||||
reportName: Code Coverage
|
||||
filePatterns: '**/coverage.cobertura.xml'
|
||||
condition: NEVER
|
||||
- !PublishRoslynatorReportStep
|
||||
name: publish code problem report
|
||||
reportName: Code Problems
|
||||
filePatterns: roslynator-analysis.xml
|
||||
failThreshold: HIGH
|
||||
condition: NEVER
|
||||
- !SetBuildVersionStep
|
||||
name: set build version
|
||||
buildVersion: '@tag@'
|
||||
condition: ALL_PREVIOUS_STEPS_WERE_SUCCESSFUL
|
||||
- !BuildImageStep
|
||||
name: build docker image - Leave
|
||||
dockerfile: ./BMA.EHR.Leave/Dockerfile
|
||||
output: !RegistryOutput
|
||||
tags: hrms-git.chin.in.th/bma-hrms/hrms-api-leave:@build_version@ hrms-git.chin.in.th/bma-hrms/hrms-api-leave:latest
|
||||
condition: NEVER
|
||||
- !BuildImageStep
|
||||
name: build docker image - Checkin
|
||||
dockerfile: ./BMA.EHR.CheckInConsumer/Dockerfile
|
||||
output: !RegistryOutput
|
||||
tags: hrms-git.chin.in.th/bma-hrms/hrms-api-checkin:@build_version@ hrms-git.chin.in.th/bma-hrms/hrms-api-checkin:latest
|
||||
condition: NEVER
|
||||
- !BuildImageStep
|
||||
name: build docker image - Insignia
|
||||
dockerfile: ./BMA.EHR.Insignia/Dockerfile
|
||||
output: !RegistryOutput
|
||||
tags: hrms-git.chin.in.th/bma-hrms/hrms-api-insignia:@build_version@ hrms-git.chin.in.th/bma-hrms/hrms-api-insignia:latest
|
||||
condition: ALL_PREVIOUS_STEPS_WERE_SUCCESSFUL
|
||||
triggers:
|
||||
- !TagCreateTrigger
|
||||
tags: uat-*
|
||||
branches: main
|
||||
retryCondition: never
|
||||
maxRetries: 3
|
||||
retryDelay: 30
|
||||
timeout: 14400
|
||||
29
.vscode/launch.json
vendored
29
.vscode/launch.json
vendored
|
|
@ -10,9 +10,34 @@
|
|||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
// If you have changed target frameworks, make sure to update the program path.
|
||||
"program": "${workspaceFolder}/BMA.EHR.Leave.Service/bin/Debug/net7.0/BMA.EHR.Leave.Service.dll",
|
||||
"program": "${workspaceFolder}/BMA.EHR.Leave/bin/Debug/net7.0/BMA.EHR.Leave.dll",
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}/BMA.EHR.Leave.Service",
|
||||
"cwd": "${workspaceFolder}/BMA.EHR.Leave",
|
||||
"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"
|
||||
}
|
||||
},
|
||||
{
|
||||
// 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": {
|
||||
|
|
|
|||
|
|
@ -23,11 +23,12 @@ namespace BMA.EHR.Application
|
|||
services.AddTransient<CommandStatusRepository>();
|
||||
services.AddTransient<InsigniaPeriodsRepository>();
|
||||
services.AddTransient<RetirementRepository>();
|
||||
services.AddTransient<RetirementEmployeeRepository>();
|
||||
services.AddTransient<UserProfileRepository>();
|
||||
services.AddTransient<OrganizationCommonRepository>();
|
||||
services.AddTransient<InboxRepository>();
|
||||
services.AddTransient<NotificationRepository>();
|
||||
services.AddTransient<RetirementRepository>();
|
||||
//services.AddTransient<RetirementRepository>();
|
||||
services.AddTransient<RetireReportRepository>();
|
||||
services.AddTransient<InsigniaReportRepository>();
|
||||
services.AddTransient<CommandReportRepository>();
|
||||
|
|
@ -36,7 +37,7 @@ namespace BMA.EHR.Application
|
|||
services.AddTransient<EmailSenderService>();
|
||||
services.AddTransient<CandidateReportRepository>();
|
||||
services.AddTransient<MinIOExamService>();
|
||||
|
||||
services.AddTransient<PermissionRepository>();
|
||||
services.AddTransient<HolidayRepository>();
|
||||
|
||||
//services.AddTransient<UserDutyTimeRepository>();
|
||||
|
|
@ -52,12 +53,16 @@ namespace BMA.EHR.Application
|
|||
services.AddTransient<UserDutyTimeRepository>();
|
||||
services.AddTransient<AdditionalCheckRequestRepository>();
|
||||
services.AddTransient<UserCalendarRepository>();
|
||||
services.AddTransient<CheckInJobStatusRepository>();
|
||||
|
||||
services.AddTransient<LeaveTypeRepository>();
|
||||
services.AddTransient<LeaveRequestRepository>();
|
||||
services.AddTransient<LeaveBeginningRepository>();
|
||||
|
||||
services.AddTransient<MinIOLeaveService>();
|
||||
|
||||
services.AddTransient<LeaveProcessJobStatusRepository>();
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@
|
|||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
|
||||
<NoWarn>$(NoWarn);$(WarningsNotAsErrors)</NoWarn>
|
||||
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ namespace BMA.EHR.Application.Common.Interfaces
|
|||
|
||||
void Attatch<T>(T entity) where T : class;
|
||||
|
||||
void Detach<T>(T entity) where T : class;
|
||||
|
||||
Task<int> SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ namespace BMA.EHR.Application.Messaging
|
|||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
//throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,9 +1,14 @@
|
|||
using BMA.EHR.Application.Common.Interfaces;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Net.Http.Json;
|
||||
using BMA.EHR.Application.Common.Interfaces;
|
||||
using BMA.EHR.Application.Repositories.MessageQueue;
|
||||
using BMA.EHR.Domain.Models.Discipline;
|
||||
using BMA.EHR.Domain.Models.Retirement;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Newtonsoft.Json;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using BMA.EHR.Application.Requests;
|
||||
|
||||
namespace BMA.EHR.Application.Repositories
|
||||
{
|
||||
|
|
@ -13,33 +18,60 @@ namespace BMA.EHR.Application.Repositories
|
|||
private readonly IDisciplineDbContext _dbDisContext;
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
private readonly NotificationRepository _repositoryNoti;
|
||||
private readonly IConfiguration _configuration;
|
||||
public DisciplineRepository(IApplicationDBContext dbContext,
|
||||
IDisciplineDbContext dbDisContext,
|
||||
NotificationRepository repositoryNoti,
|
||||
IConfiguration configuration,
|
||||
IHttpContextAccessor httpContextAccessor) : base(dbContext, httpContextAccessor)
|
||||
{
|
||||
_dbContext = dbContext;
|
||||
_dbDisContext = dbDisContext;
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
_repositoryNoti = repositoryNoti;
|
||||
_configuration = configuration;
|
||||
}
|
||||
|
||||
//เรื่องร้องเรียน
|
||||
public async Task NotifyDisciplineComplaint()
|
||||
{
|
||||
var cronjobNotis = await _dbDisContext.Set<DisciplineComplaint>()
|
||||
.Include(x => x.DisciplineComplaint_Profiles)
|
||||
.Where(x => x.DateNotification != null)
|
||||
.Where(x => x.DateNotification.Value.Date == DateTime.Now.Date)
|
||||
.AsQueryable()
|
||||
.ToListAsync();
|
||||
foreach (var cronjobNoti in cronjobNotis)
|
||||
{
|
||||
await _repositoryNoti.PushNotificationAsync(
|
||||
Guid.Parse("08dbca3a-8b6a-4a4e-8b23-1f62e4f30ef6"),
|
||||
var baseAPIOrg = _configuration["API"];
|
||||
var apiUrlOrg = $"{baseAPIOrg}/org/workflow/find/director";
|
||||
var refId = new List<Guid>();
|
||||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
{
|
||||
refId = cronjobNoti.DisciplineComplaint_Profiles.Select(x => x.PersonId),
|
||||
});
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
var org = JsonConvert.DeserializeObject<DirectorRequest>(_result);
|
||||
if (_res.IsSuccessStatusCode)
|
||||
{
|
||||
refId = org.result.Select(x => Guid.Parse(x.id)).ToList();
|
||||
}
|
||||
}
|
||||
await _repositoryNoti.PushNotificationsAsync(
|
||||
refId.ToArray(),
|
||||
$"แจ้งเตือนบันทึกข้อมูลร้องเรียนก่อนวันสิ้นสุดเรื่อง {cronjobNoti.Title}",
|
||||
$"แจ้งเตือนบันทึกข้อมูลร้องเรียนก่อนวันสิ้นสุดเรื่อง {cronjobNoti.Title}"
|
||||
$"แจ้งเตือนบันทึกข้อมูลร้องเรียนก่อนวันสิ้นสุดเรื่อง {cronjobNoti.Title}",
|
||||
"",
|
||||
"",
|
||||
true,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
|
|
@ -47,15 +79,38 @@ namespace BMA.EHR.Application.Repositories
|
|||
public async Task NotifyDisciplineInvestigate()
|
||||
{
|
||||
var cronjobNotis = await _dbDisContext.Set<DisciplineInvestigate>()
|
||||
.Include(x => x.DisciplineInvestigate_ProfileComplaints)
|
||||
.Where(x => x.InvestigationDateEnd != null && x.InvestigationDateEnd.Value.Date.AddDays(-7) == DateTime.Now.Date)
|
||||
.AsQueryable()
|
||||
.ToListAsync();
|
||||
foreach (var cronjobNoti in cronjobNotis)
|
||||
{
|
||||
await _repositoryNoti.PushNotificationAsync(
|
||||
Guid.Parse("08dbca3a-8b6a-4a4e-8b23-1f62e4f30ef6"),
|
||||
var baseAPIOrg = _configuration["API"];
|
||||
var apiUrlOrg = $"{baseAPIOrg}/org/workflow/find/director";
|
||||
var refId = new List<Guid>();
|
||||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
{
|
||||
refId = cronjobNoti.DisciplineInvestigate_ProfileComplaints.Select(x => x.PersonId),
|
||||
});
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
var org = JsonConvert.DeserializeObject<DirectorRequest>(_result);
|
||||
if (_res.IsSuccessStatusCode)
|
||||
{
|
||||
refId = org.result.Select(x => Guid.Parse(x.id)).ToList();
|
||||
}
|
||||
}
|
||||
await _repositoryNoti.PushNotificationsAsync(
|
||||
refId.ToArray(),
|
||||
$"แจ้งเตือนบันทึกข้อมูลสืบสวนก่อนวันสิ้นสุดเรื่อง {cronjobNoti.Title}",
|
||||
$"แจ้งเตือนบันทึกข้อมูลสืบสวนก่อนวันสิ้นสุดเรื่อง {cronjobNoti.Title}"
|
||||
$"แจ้งเตือนบันทึกข้อมูลสืบสวนก่อนวันสิ้นสุดเรื่อง {cronjobNoti.Title}",
|
||||
"",
|
||||
"",
|
||||
true,
|
||||
true
|
||||
);
|
||||
}
|
||||
await _dbContext.SaveChangesAsync();
|
||||
|
|
@ -65,15 +120,38 @@ namespace BMA.EHR.Application.Repositories
|
|||
public async Task NotifyDisciplineDisciplinary()
|
||||
{
|
||||
var cronjobNotis = await _dbDisContext.Set<DisciplineDisciplinary>()
|
||||
.Include(x => x.DisciplineDisciplinary_ProfileComplaintInvestigates)
|
||||
.Where(x => x.DisciplinaryDateEnd != null && x.DisciplinaryDateEnd.Value.Date.AddDays(-7) == DateTime.Now.Date)
|
||||
.AsQueryable()
|
||||
.ToListAsync();
|
||||
foreach (var cronjobNoti in cronjobNotis)
|
||||
{
|
||||
await _repositoryNoti.PushNotificationAsync(
|
||||
Guid.Parse("08dbca3a-8b6a-4a4e-8b23-1f62e4f30ef6"),
|
||||
var baseAPIOrg = _configuration["API"];
|
||||
var apiUrlOrg = $"{baseAPIOrg}/org/workflow/find/director";
|
||||
var refId = new List<Guid>();
|
||||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
{
|
||||
refId = cronjobNoti.DisciplineDisciplinary_ProfileComplaintInvestigates.Select(x => x.PersonId),
|
||||
});
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
var org = JsonConvert.DeserializeObject<DirectorRequest>(_result);
|
||||
if (_res.IsSuccessStatusCode)
|
||||
{
|
||||
refId = org.result.Select(x => Guid.Parse(x.id)).ToList();
|
||||
}
|
||||
}
|
||||
await _repositoryNoti.PushNotificationsAsync(
|
||||
refId.ToArray(),
|
||||
$"แจ้งเตือนบันทึกข้อมูลสอบสวนก่อนวันสิ้นสุดเรื่อง {cronjobNoti.Title}",
|
||||
$"แจ้งเตือนบันทึกข้อมูลสอบสวนก่อนวันสิ้นสุดเรื่อง {cronjobNoti.Title}"
|
||||
$"แจ้งเตือนบันทึกข้อมูลสอบสวนก่อนวันสิ้นสุดเรื่อง {cronjobNoti.Title}",
|
||||
"",
|
||||
"",
|
||||
true,
|
||||
true
|
||||
);
|
||||
}
|
||||
await _dbContext.SaveChangesAsync();
|
||||
|
|
|
|||
|
|
@ -1,10 +1,16 @@
|
|||
using Amazon.S3.Model.Internal.MarshallTransformations;
|
||||
using Amazon.Runtime.Internal.Endpoints.StandardLibrary;
|
||||
using Amazon.S3.Model.Internal.MarshallTransformations;
|
||||
using BMA.EHR.Application.Common.Interfaces;
|
||||
using BMA.EHR.Domain.Models.Base;
|
||||
using BMA.EHR.Domain.Models.HR;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Security.Claims;
|
||||
using System.Text;
|
||||
|
||||
namespace BMA.EHR.Application.Repositories
|
||||
{
|
||||
|
|
@ -26,7 +32,7 @@ namespace BMA.EHR.Application.Repositories
|
|||
_dbContext = dbContext;
|
||||
_dbSet = _dbContext.Set<T>();
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
|
||||
// _configuration = configuration;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
@ -39,10 +45,134 @@ namespace BMA.EHR.Application.Repositories
|
|||
|
||||
protected bool? IsPlacementAdmin => _httpContextAccessor?.HttpContext?.User?.IsInRole("placement1");
|
||||
|
||||
protected string? AccessToken => _httpContextAccessor?.HttpContext?.Request.Headers["Authorization"];
|
||||
|
||||
#endregion
|
||||
|
||||
#region " Methods "
|
||||
|
||||
#region " For Call External API "
|
||||
|
||||
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,cancellationToken: combinedCts.Token);
|
||||
if (_res.IsSuccessStatusCode)
|
||||
{
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
|
||||
return _result;
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
||||
var json = JsonConvert.SerializeObject(body);
|
||||
request.Content = new StringContent(json, Encoding.UTF8, "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.SendAsync(request, combinedCts.Token);
|
||||
if (_res.IsSuccessStatusCode)
|
||||
{
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
|
||||
return _result;
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
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);
|
||||
return _res.IsSuccessStatusCode;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public async Task<Guid> GetProfileOrganizationAsync(string citizenId)
|
||||
{
|
||||
try
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -2,7 +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
|
||||
{
|
||||
|
|
@ -24,7 +28,6 @@ namespace BMA.EHR.Application.Repositories.Leaves
|
|||
_dbContext = dbContext;
|
||||
_dbSet = _dbContext.Set<T>();
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
@ -37,10 +40,44 @@ namespace BMA.EHR.Application.Repositories.Leaves
|
|||
|
||||
protected bool? IsPlacementAdmin => _httpContextAccessor?.HttpContext?.User?.IsInRole("placement1");
|
||||
|
||||
protected string? AccessToken => _httpContextAccessor?.HttpContext?.Request.Headers["Authorization"];
|
||||
|
||||
#endregion
|
||||
|
||||
#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();
|
||||
|
|
@ -66,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)
|
||||
|
|
@ -75,6 +130,7 @@ namespace BMA.EHR.Application.Repositories.Leaves
|
|||
(entity as EntityBase).LastUpdatedAt = DateTime.Now;
|
||||
}
|
||||
|
||||
//_dbContext.Detach(entity);
|
||||
_dbSet.Update(entity);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,587 @@
|
|||
using Amazon.S3.Model;
|
||||
using BMA.EHR.Application.Common.Interfaces;
|
||||
using BMA.EHR.Application.Messaging;
|
||||
using BMA.EHR.Application.Responses.Profiles;
|
||||
using BMA.EHR.Domain.Extensions;
|
||||
using BMA.EHR.Domain.Models.Leave.Commons;
|
||||
using BMA.EHR.Domain.Models.Leave.Requests;
|
||||
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
|
||||
{
|
||||
public class LeaveBeginningRepository : GenericLeaveRepository<Guid, LeaveBeginning>
|
||||
{
|
||||
#region " Fields "
|
||||
|
||||
private readonly ILeaveDbContext _dbContext;
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
private readonly OrganizationCommonRepository _organizationCommonRepository;
|
||||
private readonly UserProfileRepository _userProfileRepository;
|
||||
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 "
|
||||
|
||||
public LeaveBeginningRepository(ILeaveDbContext dbContext,
|
||||
IHttpContextAccessor httpContextAccessor,
|
||||
OrganizationCommonRepository organizationCommonRepository,
|
||||
UserProfileRepository userProfileRepository,
|
||||
IConfiguration configuration,
|
||||
EmailSenderService emailSenderService) : base(dbContext, httpContextAccessor)
|
||||
{
|
||||
_dbContext = dbContext;
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
_organizationCommonRepository = organizationCommonRepository;
|
||||
_userProfileRepository = userProfileRepository;
|
||||
_configuration = configuration;
|
||||
_emailSenderService = emailSenderService;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region " Properties "
|
||||
|
||||
protected Guid UserOrganizationId
|
||||
{
|
||||
get
|
||||
{
|
||||
if (UserId != null || UserId != "")
|
||||
return _userProfileRepository.GetUserOCId(Guid.Parse(UserId!), AccessToken);
|
||||
else
|
||||
return Guid.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public async Task<List<LeaveBeginning>> GetAllByYearAsync(int year)
|
||||
{
|
||||
return await _dbContext.Set<LeaveBeginning>()
|
||||
.Include(x => x.LeaveType)
|
||||
.Where(x => x.LeaveYear == year)
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<LeaveBeginning?> GetByYearAndTypeIdAsync(int year, Guid typeId)
|
||||
{
|
||||
var data = await _dbContext.Set<LeaveBeginning>()
|
||||
.Include(x => x.LeaveType)
|
||||
.FirstOrDefaultAsync(x => x.LeaveYear == year && x.LeaveTypeId == typeId);
|
||||
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public async Task UpdateLeaveUsageAsync(int year, Guid typeId, Guid userId, double day)
|
||||
{
|
||||
// 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.LeaveDaysUsed += day;
|
||||
|
||||
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.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);
|
||||
|
||||
LeaveBeginning Factory()
|
||||
{
|
||||
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);
|
||||
|
||||
// คำนวณปีงบประมาณจาก startDate (ปีงบประมาณเริ่ม 1 ต.ค. และสิ้นสุด 30 ก.ย.)
|
||||
var isCurrentYear = DateTime.Now.Year == year;
|
||||
|
||||
|
||||
var prevRemain = 0.0;
|
||||
if (prev != null)
|
||||
{
|
||||
prevRemain = isCurrentYear ? prev.LeaveDays - (prev.LeaveDaysUsed ?? 0.0) : 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;
|
||||
}
|
||||
|
||||
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 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);
|
||||
|
||||
LeaveBeginning Factory()
|
||||
{
|
||||
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);
|
||||
|
||||
// คำนวณปีงบประมาณจาก startDate (ปีงบประมาณเริ่ม 1 ต.ค. และสิ้นสุด 30 ก.ย.)
|
||||
var isCurrentYear = DateTime.Now.Year == year;
|
||||
|
||||
var prevRemain = 0.0;
|
||||
if (prev != null)
|
||||
{
|
||||
prevRemain = isCurrentYear ? prev.LeaveDays - (prev.LeaveDaysUsed ?? 0.0) : 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;
|
||||
}
|
||||
|
||||
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 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.GetProfileByKeycloakIdNew2Async(userId, AccessToken);
|
||||
if (pf == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var govAge = (pf?.DateStart?.Date ?? DateTime.Now.Date).DiffDay(DateTime.Now.Date);
|
||||
|
||||
var leaveType = await _dbContext.Set<LeaveType>().FirstOrDefaultAsync(x => x.Id == typeId);
|
||||
|
||||
LeaveBeginning Factory()
|
||||
{
|
||||
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);
|
||||
|
||||
// คำนวณปีงบประมาณจาก startDate (ปีงบประมาณเริ่ม 1 ต.ค. และสิ้นสุด 30 ก.ย.)
|
||||
var isCurrentYear = DateTime.Now.Year == year;
|
||||
|
||||
var prevRemain = 0.0;
|
||||
if (prev != null)
|
||||
{
|
||||
prevRemain = isCurrentYear ? prev.LeaveDays - (prev.LeaveDaysUsed ?? 0.0) : 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;
|
||||
}
|
||||
|
||||
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 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>();
|
||||
|
||||
var beginningList = await _dbContext.Set<LeaveBeginning>()
|
||||
.Include(x => x.LeaveType)
|
||||
.Where(x => x.LeaveYear == year && x.LeaveTypeId == typeId)
|
||||
.ToListAsync();
|
||||
|
||||
foreach (var pf in userIdList)
|
||||
{
|
||||
//var pf = await _userProfileRepository.GetProfileByKeycloakIdAsync(id, AccessToken);
|
||||
//if (pf == null)
|
||||
//{
|
||||
// continue; // Goto Next Id
|
||||
//}
|
||||
|
||||
var profile = await _userProfileRepository.GetProfileByProfileIdAsync(pf.Id, AccessToken);
|
||||
if (profile == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
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 = beginningList.FirstOrDefault(x => x.ProfileId == pf.Id);
|
||||
|
||||
if (data == null)
|
||||
{
|
||||
var limit = 0.0;
|
||||
|
||||
var prev = await _dbContext.Set<LeaveBeginning>()
|
||||
.Include(x => x.LeaveType)
|
||||
.FirstOrDefaultAsync(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;
|
||||
}
|
||||
|
||||
data = 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 = profile.RootDnaId,
|
||||
Child1DnaId = profile.Child1DnaId,
|
||||
Child2DnaId = profile.Child2DnaId,
|
||||
Child3DnaId = profile.Child3DnaId,
|
||||
Child4DnaId = profile.Child4DnaId
|
||||
};
|
||||
|
||||
updateList.Add(data);
|
||||
}
|
||||
result.Add(data);
|
||||
}
|
||||
if (!updateList.Any())
|
||||
{
|
||||
await _dbContext.Set<LeaveBeginning>().AddRangeAsync(updateList);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public class ProfileData
|
||||
{
|
||||
public Guid Id { get; set; } = Guid.Empty;
|
||||
|
||||
public string Prefix { get; set; } = string.Empty;
|
||||
|
||||
public string FirstName { get; set; } = string.Empty;
|
||||
|
||||
public string LastName { get; set; } = string.Empty;
|
||||
|
||||
public DateTime? DateStart { get; set; } = null;
|
||||
|
||||
public DateTime? DateAppoint { get; set; } = null;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -46,7 +46,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
get
|
||||
{
|
||||
if (UserId != null || UserId != "")
|
||||
return _userProfileRepository.GetUserOCId(Guid.Parse(UserId!));
|
||||
return _userProfileRepository.GetUserOCId(Guid.Parse(UserId!), AccessToken);
|
||||
else
|
||||
return Guid.Empty;
|
||||
}
|
||||
|
|
@ -57,7 +57,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
|
||||
public async Task<LeaveType?> GetLeaveTypeByCodeAsync(string code)
|
||||
{
|
||||
return await _dbContext.Set<LeaveType>().FirstOrDefaultAsync(x => x.Code == code);
|
||||
return await _dbContext.Set<LeaveType>().AsNoTracking().FirstOrDefaultAsync(x => x.Code == code);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,16 @@
|
|||
using BMA.EHR.Application.Common.Interfaces;
|
||||
using BMA.EHR.Application.Messaging;
|
||||
using BMA.EHR.Application.Repositories.Commands;
|
||||
using BMA.EHR.Application.Responses;
|
||||
using BMA.EHR.Domain.Extensions;
|
||||
using BMA.EHR.Domain.Models.Leave.TimeAttendants;
|
||||
using BMA.EHR.Domain.Models.Notifications;
|
||||
using BMA.EHR.Domain.Shared;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Serilog;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
||||
{
|
||||
|
|
@ -18,6 +24,8 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
|||
private readonly UserProfileRepository _userProfileRepository;
|
||||
private readonly IConfiguration _configuration;
|
||||
private readonly EmailSenderService _emailSenderService;
|
||||
private readonly IApplicationDBContext _appContext;
|
||||
private readonly CommandRepository _commandRepository;
|
||||
|
||||
#endregion
|
||||
|
||||
|
|
@ -28,7 +36,9 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
|||
OrganizationCommonRepository organizationCommonRepository,
|
||||
UserProfileRepository userProfileRepository,
|
||||
IConfiguration configuration,
|
||||
EmailSenderService emailSenderService) : base(dbContext, httpContextAccessor)
|
||||
EmailSenderService emailSenderService,
|
||||
IApplicationDBContext appContext,
|
||||
CommandRepository commandRepository) : base(dbContext, httpContextAccessor)
|
||||
{
|
||||
_dbContext = dbContext;
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
|
|
@ -36,6 +46,8 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
|||
_userProfileRepository = userProfileRepository;
|
||||
_configuration = configuration;
|
||||
_emailSenderService = emailSenderService;
|
||||
_appContext = appContext;
|
||||
_commandRepository = commandRepository;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
@ -47,7 +59,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
|||
get
|
||||
{
|
||||
if (UserId != null || UserId != "")
|
||||
return _userProfileRepository.GetUserOCId(Guid.Parse(UserId!));
|
||||
return _userProfileRepository.GetUserOCId(Guid.Parse(UserId!), AccessToken);
|
||||
else
|
||||
return Guid.Empty;
|
||||
}
|
||||
|
|
@ -57,6 +69,47 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
|||
|
||||
#region " Methods "
|
||||
|
||||
public override async Task<AdditionalCheckRequest> AddAsync(AdditionalCheckRequest entity)
|
||||
{
|
||||
await base.AddAsync(entity);
|
||||
|
||||
var userId = UserId != null ? Guid.Parse(UserId) : Guid.Empty;
|
||||
// var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(userId, AccessToken ?? "");
|
||||
var profile = await _userProfileRepository.GetProfileByKeycloakIdNew2Async(userId, AccessToken ?? "");
|
||||
|
||||
// fix issue : SIT ระบบบันทึกเวลาปฏิบัติงาน>>ลงเวลากรณีพิเศษ (ไม่มีแจ้งเตือนไปยังผู้บังคับบัญชา) #969
|
||||
// send noti + inbox + mail
|
||||
// send inbox and notification
|
||||
var subject_str = $"มีการขออนุมัติลงเวลากรณีพิเศษ";
|
||||
var body_str = $"โปรดพิจารณาคำร้องขอลงเวลาในกรณีพิเศษจาก {profile.Prefix}{profile.FirstName} {profile.LastName} ในวันที่ {entity.CheckDate.Date.ToThaiShortDate2()}";
|
||||
|
||||
var subject = subject_str;
|
||||
var body = body_str;
|
||||
_emailSenderService.SendMail(subject, body, "dev@frappet.com");
|
||||
|
||||
|
||||
var inbox = new Inbox
|
||||
{
|
||||
Subject = subject_str,
|
||||
Body = body_str,
|
||||
ReceiverUserId = profile.CommanderId == Guid.Empty || profile.CommanderId == null ? Guid.Parse("08dbca3a-8b6a-4a4e-8b23-1f62e4f30ef6") : profile.CommanderId.Value,
|
||||
Payload = "",
|
||||
};
|
||||
_appContext.Set<Inbox>().Add(inbox);
|
||||
|
||||
var noti = new Notification
|
||||
{
|
||||
Body = body_str,
|
||||
ReceiverUserId = profile.CommanderId == Guid.Empty || profile.CommanderId == null ? Guid.Parse("08dbca3a-8b6a-4a4e-8b23-1f62e4f30ef6") : profile.CommanderId.Value,
|
||||
Type = "",
|
||||
Payload = "",
|
||||
};
|
||||
_appContext.Set<Notification>().Add(noti);
|
||||
await _appContext.SaveChangesAsync();
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
public async Task<List<AdditionalCheckRequest>> GetAdditionalCheckRequestsByUserId(Guid keycloakId, int year, int month)
|
||||
{
|
||||
try
|
||||
|
|
@ -92,6 +145,147 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
|||
}
|
||||
}
|
||||
|
||||
public async Task<List<AdditionalCheckRequest>> GetAdditionalCheckRequestsByAdminRole(int year, int month, string role, string nodeId, int? node, string? keyword)
|
||||
{
|
||||
try
|
||||
{
|
||||
var data = await _dbContext.Set<AdditionalCheckRequest>().AsQueryable()
|
||||
.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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,191 @@
|
|||
using BMA.EHR.Application.Common.Interfaces;
|
||||
using BMA.EHR.Domain.Models.Leave.TimeAttendants;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
||||
{
|
||||
public class CheckInJobStatusRepository : GenericLeaveRepository<Guid, CheckInJobStatus>
|
||||
{
|
||||
#region " Fields "
|
||||
|
||||
private readonly ILeaveDbContext _dbContext;
|
||||
|
||||
#endregion
|
||||
|
||||
#region " Constructor and Destructor "
|
||||
|
||||
public CheckInJobStatusRepository(ILeaveDbContext dbContext,
|
||||
IHttpContextAccessor httpContextAccessor) : base(dbContext, httpContextAccessor)
|
||||
{
|
||||
_dbContext = dbContext;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region " Methods "
|
||||
|
||||
/// <summary>
|
||||
/// ดึงข้อมูล Job Status จาก TaskId
|
||||
/// </summary>
|
||||
public async Task<CheckInJobStatus?> GetByTaskIdAsync(Guid taskId)
|
||||
{
|
||||
var data = await _dbContext.Set<CheckInJobStatus>()
|
||||
.Where(x => x.TaskId == taskId)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ดึงข้อมูล Job Status จาก UserId และสถานะ
|
||||
/// </summary>
|
||||
public async Task<List<CheckInJobStatus>> GetByUserIdAndStatusAsync(Guid userId, string status)
|
||||
{
|
||||
var data = await _dbContext.Set<CheckInJobStatus>()
|
||||
.Where(x => x.KeycloakUserId == userId && x.Status == status)
|
||||
.OrderByDescending(x => x.CreatedDate)
|
||||
.ToListAsync();
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ดึงข้อมูล Job Status ที่ยัง pending หรือ processing
|
||||
/// </summary>
|
||||
public async Task<List<CheckInJobStatus>> GetPendingOrProcessingJobsAsync(Guid userId)
|
||||
{
|
||||
var data = await _dbContext.Set<CheckInJobStatus>()
|
||||
.Where(x => x.KeycloakUserId == userId &&
|
||||
(x.Status == "PENDING" || x.Status == "PROCESSING"))
|
||||
//.OrderByDescending(x => x.CreatedDate)
|
||||
.ToListAsync();
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// อัปเดตสถานะเป็น Processing
|
||||
/// </summary>
|
||||
public async Task<CheckInJobStatus> UpdateToProcessingAsync(Guid taskId)
|
||||
{
|
||||
var job = await GetByTaskIdAsync(taskId);
|
||||
if (job != null)
|
||||
{
|
||||
job.Status = "PROCESSING";
|
||||
job.ProcessingDate = DateTime.Now;
|
||||
await UpdateAsync(job);
|
||||
}
|
||||
return job!;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// อัปเดตสถานะเป็น Completed
|
||||
/// </summary>
|
||||
public async Task<CheckInJobStatus> UpdateToCompletedAsync(Guid taskId, string? additionalData = null)
|
||||
{
|
||||
var job = await GetByTaskIdAsync(taskId);
|
||||
if (job != null)
|
||||
{
|
||||
job.Status = "COMPLETED";
|
||||
job.CompletedDate = DateTime.Now;
|
||||
if (!string.IsNullOrEmpty(additionalData))
|
||||
{
|
||||
job.AdditionalData = additionalData;
|
||||
}
|
||||
await UpdateAsync(job);
|
||||
}
|
||||
return job!;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// อัปเดตสถานะเป็น Failed
|
||||
/// </summary>
|
||||
public async Task<CheckInJobStatus> UpdateToFailedAsync(Guid taskId, string errorMessage)
|
||||
{
|
||||
var job = await GetByTaskIdAsync(taskId);
|
||||
if (job != null)
|
||||
{
|
||||
job.Status = "FAILED";
|
||||
job.CompletedDate = DateTime.Now;
|
||||
job.ErrorMessage = errorMessage;
|
||||
await UpdateAsync(job);
|
||||
}
|
||||
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>
|
||||
public async Task<int> CleanupOldJobsAsync(int daysOld = 30)
|
||||
{
|
||||
var cutoffDate = DateTime.Now.AddDays(-daysOld);
|
||||
var oldJobs = await _dbContext.Set<CheckInJobStatus>()
|
||||
.Where(x => x.CreatedDate < cutoffDate)
|
||||
.ToListAsync();
|
||||
|
||||
_dbContext.Set<CheckInJobStatus>().RemoveRange(oldJobs);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
|
||||
return oldJobs.Count;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
@ -46,7 +46,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
|||
get
|
||||
{
|
||||
if (UserId != null || UserId != "")
|
||||
return _userProfileRepository.GetUserOCId(Guid.Parse(UserId!));
|
||||
return _userProfileRepository.GetUserOCId(Guid.Parse(UserId!), AccessToken);
|
||||
else
|
||||
return Guid.Empty;
|
||||
}
|
||||
|
|
@ -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; }
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -46,7 +46,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
|||
get
|
||||
{
|
||||
if (UserId != null || UserId != "")
|
||||
return _userProfileRepository.GetUserOCId(Guid.Parse(UserId!));
|
||||
return _userProfileRepository.GetUserOCId(Guid.Parse(UserId!), AccessToken);
|
||||
else
|
||||
return Guid.Empty;
|
||||
}
|
||||
|
|
@ -139,6 +139,68 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
|||
return data;
|
||||
}
|
||||
|
||||
public async Task<List<ProcessUserTimeStamp>> GetTimestampByDateLateAsync(string type, string role, string nodeId, int? node, string nodeIdByReq, int? nodeByReq, DateTime StartDate, DateTime EndDate)
|
||||
{
|
||||
var data = new List<ProcessUserTimeStamp>();
|
||||
data = await _dbContext.Set<ProcessUserTimeStamp>().AsQueryable()
|
||||
.Where(x => x.CheckInStatus == "LATE")
|
||||
.Where(u => u.CheckIn.Date >= StartDate && u.CheckIn.Date <= EndDate)
|
||||
.Where(x => x.ProfileType == type.Trim().ToUpper()).ToListAsync();
|
||||
// กรองตามสิทธิ์ admin ก่อน
|
||||
if (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).ToList();
|
||||
// }
|
||||
else if (role == "NORMAL")
|
||||
{
|
||||
data = data.Where(x =>
|
||||
node == 0 ? x.RootDnaId == Guid.Parse(nodeId!) && x.Child1DnaId == null :
|
||||
node == 1 ? x.Child1DnaId == Guid.Parse(nodeId!) && x.Child2DnaId == null :
|
||||
node == 2 ? x.Child2DnaId == Guid.Parse(nodeId!) && x.Child3DnaId == null :
|
||||
node == 3 ? x.Child3DnaId == Guid.Parse(nodeId!) && x.Child4DnaId == null :
|
||||
node == 4 ? x.Child4DnaId == Guid.Parse(nodeId!) :
|
||||
true
|
||||
).ToList();
|
||||
}
|
||||
// กรองตามที่ fe ส่งมา
|
||||
if (role == "ROOT" || role == "OWNER" || role == "CHILD" || role == "BROTHER" || role == "PARENT")
|
||||
{
|
||||
data = data.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();
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
public async Task<ProcessUserTimeStamp?> GetLastRecord(Guid keycloakId)
|
||||
{
|
||||
var data = await _dbContext.Set<ProcessUserTimeStamp>()
|
||||
|
|
@ -151,9 +213,12 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
|||
|
||||
public async Task<List<ProcessUserTimeStamp>> GetTimeStampHistoryAsync(Guid keycloakId, int year, int page = 1, int pageSize = 10, string keyword = "")
|
||||
{
|
||||
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.Year == year)
|
||||
.Where(u => u.CheckIn.Date >= fiscalDateStart && u.CheckIn.Date <= fiscalDateEnd)
|
||||
.OrderByDescending(u => u.CheckIn.Date)
|
||||
.Skip((page - 1) * pageSize)
|
||||
.Take(pageSize)
|
||||
|
|
@ -162,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>()
|
||||
|
|
@ -194,6 +272,55 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
|||
return data;
|
||||
}
|
||||
|
||||
public async Task<List<ProcessUserTimeStamp>> GetTimeStampHistoryForAdminRoleAsync(DateTime startDate, DateTime endDate, string role, string nodeId, int? node)
|
||||
{
|
||||
var data = await _dbContext.Set<ProcessUserTimeStamp>()
|
||||
.Where(u => u.CheckIn.Date >= startDate.Date && u.CheckIn.Date <= endDate.Date)
|
||||
.OrderBy(u => u.CheckIn)
|
||||
|
||||
.ToListAsync();
|
||||
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)
|
||||
// .ToList();
|
||||
// }
|
||||
else if (role == "NORMAL")
|
||||
{
|
||||
data = data.Where(x =>
|
||||
node == 0 ? x.RootDnaId == Guid.Parse(nodeId!) && x.Child1DnaId == null :
|
||||
node == 1 ? x.Child1DnaId == Guid.Parse(nodeId!) && x.Child2DnaId == null :
|
||||
node == 2 ? x.Child2DnaId == Guid.Parse(nodeId!) && x.Child3DnaId == null :
|
||||
node == 3 ? x.Child3DnaId == Guid.Parse(nodeId!) && x.Child4DnaId == null :
|
||||
node == 4 ? x.Child4DnaId == Guid.Parse(nodeId!) :
|
||||
true
|
||||
).ToList();
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
public async Task<ProcessUserTimeStamp?> GetTimeStampById(Guid id)
|
||||
{
|
||||
var data = await _dbContext.Set<ProcessUserTimeStamp>()
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
|||
get
|
||||
{
|
||||
if (UserId != null || UserId != "")
|
||||
return _userProfileRepository.GetUserOCId(Guid.Parse(UserId!));
|
||||
return _userProfileRepository.GetUserOCId(Guid.Parse(UserId!), AccessToken);
|
||||
else
|
||||
return Guid.Empty;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
|||
get
|
||||
{
|
||||
if (UserId != null || UserId != "")
|
||||
return _userProfileRepository.GetUserOCId(Guid.Parse(UserId!));
|
||||
return _userProfileRepository.GetUserOCId(Guid.Parse(UserId!), AccessToken);
|
||||
else
|
||||
return Guid.Empty;
|
||||
}
|
||||
|
|
@ -62,7 +62,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
|||
{
|
||||
var data = _dbContext.Set<UserDutyTime>()
|
||||
.Where(u => !u.IsProcess)
|
||||
.Where(u => u.EffectiveDate.Value.Date <= DateTime.Now.Date)
|
||||
.Where(u => u.EffectiveDate.Value.Date <= DateTime.Now.AddHours(7).Date)
|
||||
.ToList();
|
||||
|
||||
foreach (var d in data)
|
||||
|
|
@ -101,13 +101,17 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
|||
return data;
|
||||
}
|
||||
|
||||
public async Task<UserDutyTime?> GetLastEffectRound(Guid profileId)
|
||||
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.IsProcess)
|
||||
.Where(x => x.EffectiveDate.Value.Date <= effectiveDate.Value.Date)
|
||||
.OrderByDescending(x => x.EffectiveDate)
|
||||
.FirstOrDefaultAsync();
|
||||
.FirstOrDefaultAsync(combinedCts.Token);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
|||
get
|
||||
{
|
||||
if (UserId != null || UserId != "")
|
||||
return _userProfileRepository.GetUserOCId(Guid.Parse(UserId!));
|
||||
return _userProfileRepository.GetUserOCId(Guid.Parse(UserId!), AccessToken);
|
||||
else
|
||||
return Guid.Empty;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -107,6 +111,55 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
|||
return data;
|
||||
}
|
||||
|
||||
public async Task<List<UserTimeStamp>> GetTimeStampHistoryForAdminRoleAsync(DateTime startDate, DateTime endDate, string role, string nodeId, int? node)
|
||||
{
|
||||
var data = await _dbContext.Set<UserTimeStamp>()
|
||||
.Where(u => u.CheckIn.Date >= startDate.Date && u.CheckIn.Date <= endDate.Date)
|
||||
.OrderBy(u => u.CheckIn)
|
||||
|
||||
.ToListAsync();
|
||||
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)
|
||||
// .ToList();
|
||||
// }
|
||||
else if (role == "NORMAL")
|
||||
{
|
||||
data = data.Where(x =>
|
||||
node == 0 ? x.RootDnaId == Guid.Parse(nodeId!) && x.Child1DnaId == null :
|
||||
node == 1 ? x.Child1DnaId == Guid.Parse(nodeId!) && x.Child2DnaId == null :
|
||||
node == 2 ? x.Child2DnaId == Guid.Parse(nodeId!) && x.Child3DnaId == null :
|
||||
node == 3 ? x.Child3DnaId == Guid.Parse(nodeId!) && x.Child4DnaId == null :
|
||||
node == 4 ? x.Child4DnaId == Guid.Parse(nodeId!) :
|
||||
true
|
||||
).ToList();
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
public async Task<UserTimeStamp?> GetTimeStampById(Guid id)
|
||||
{
|
||||
var data = await _dbContext.Set<UserTimeStamp>()
|
||||
|
|
|
|||
|
|
@ -6,7 +6,9 @@ using BMA.EHR.Domain.Models.Notifications;
|
|||
using BMA.EHR.Domain.Shared;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Newtonsoft.Json;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace BMA.EHR.Application.Repositories.MessageQueue
|
||||
|
|
@ -17,38 +19,61 @@ namespace BMA.EHR.Application.Repositories.MessageQueue
|
|||
|
||||
private readonly IApplicationDBContext _dbContext;
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
#endregion
|
||||
|
||||
#region " Constructor and Destuctor "
|
||||
|
||||
public InboxRepository(IApplicationDBContext dbContext,
|
||||
IHttpContextAccessor httpContextAccessor) : base(dbContext, httpContextAccessor)
|
||||
IHttpContextAccessor httpContextAccessor,
|
||||
IConfiguration configuration) : base(dbContext, httpContextAccessor)
|
||||
{
|
||||
_dbContext = dbContext;
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
_configuration = configuration;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region " Methods "
|
||||
|
||||
public async Task<List<InboxResponse>> GetMyInboxAsync()
|
||||
public async Task<dynamic> GetMyInboxAsync(int page = 1, int pageSize = 25)
|
||||
{
|
||||
try
|
||||
{
|
||||
var profile = await _dbContext.Set<Profile>()
|
||||
.FirstOrDefaultAsync(p => p.KeycloakId == Guid.Parse(UserId!));
|
||||
// var profile = await _dbContext.Set<Profile>()
|
||||
// .FirstOrDefaultAsync(p => p.KeycloakId == Guid.Parse(UserId!));
|
||||
|
||||
if (profile == null)
|
||||
// if (profile == null)
|
||||
// {
|
||||
// return new List<InboxResponse>();
|
||||
// // throw new Exception(GlobalMessages.DataNotFound);
|
||||
// }
|
||||
|
||||
//var apiUrl = $"{_configuration["API"]}/org/profile/keycloak/position";
|
||||
var apiUrl = $"{_configuration["API"]}/org/dotnet/get-profileId";
|
||||
var profileId = "";
|
||||
using (var client = new HttpClient())
|
||||
{
|
||||
return new List<InboxResponse>();
|
||||
// throw new Exception(GlobalMessages.DataNotFound);
|
||||
}
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Get, apiUrl);
|
||||
var _res = await client.SendAsync(_req);
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
|
||||
var data = await _dbContext.Set<Inbox>()
|
||||
.Where(x => x.ReceiverUserId == profile.Id)
|
||||
.Where(x => x.IsOpen == false)
|
||||
var org = JsonConvert.DeserializeObject<OrgRequest>(_result);
|
||||
|
||||
if (org == null || org.result == null)
|
||||
return new List<InboxResponse>();
|
||||
profileId = org.result.profileId == null ? "" : org.result.profileId;
|
||||
}
|
||||
if (profileId == null || profileId == "")
|
||||
return new List<InboxResponse>();
|
||||
|
||||
var data_search = await _dbContext.Set<Inbox>()
|
||||
.Where(x => x.ReceiverUserId == Guid.Parse(profileId))
|
||||
.Where(x => x.DeleteDate == null)
|
||||
.OrderByDescending(x => x.ReceiveDate)
|
||||
.Select(x => new InboxResponse
|
||||
{
|
||||
|
|
@ -61,10 +86,15 @@ namespace BMA.EHR.Application.Repositories.MessageQueue
|
|||
OpenDate = x.OpenDate,
|
||||
Payload = x.Payload == "" ? null : JsonConvert.DeserializeObject<CommandPayload>(Regex.Unescape(x.Payload))
|
||||
})
|
||||
.Take(20)
|
||||
.ToListAsync();
|
||||
|
||||
return data;
|
||||
var data = data_search
|
||||
.Skip((page - 1) * pageSize)
|
||||
.Take(pageSize)
|
||||
.ToList();
|
||||
|
||||
var _data = new { data, total = data_search.Count(), totalNoti = data_search.Where(x => x.IsOpen == false).Count() };
|
||||
return _data;
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
|
@ -81,7 +111,7 @@ namespace BMA.EHR.Application.Repositories.MessageQueue
|
|||
|
||||
if (inbox != null)
|
||||
{
|
||||
inbox.IsOpen = true;
|
||||
inbox.DeleteDate = DateTime.Now;
|
||||
// _dbContext.Set<Inbox>().Remove(inbox);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
|
|
@ -101,6 +131,7 @@ namespace BMA.EHR.Application.Repositories.MessageQueue
|
|||
|
||||
if (inbox != null)
|
||||
{
|
||||
inbox.IsOpen = true;
|
||||
inbox.OpenDate = DateTime.Now;
|
||||
// _dbContext.Set<Inbox>().Remove(inbox);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@ using BMA.EHR.Domain.Models.Notifications;
|
|||
using BMA.EHR.Domain.Shared;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Newtonsoft.Json;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace BMA.EHR.Application.Repositories.MessageQueue
|
||||
|
|
@ -19,6 +21,7 @@ namespace BMA.EHR.Application.Repositories.MessageQueue
|
|||
private readonly IApplicationDBContext _dbContext;
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
private readonly EmailSenderService _emailSenderService;
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
#endregion
|
||||
|
||||
|
|
@ -26,49 +29,137 @@ namespace BMA.EHR.Application.Repositories.MessageQueue
|
|||
|
||||
public NotificationRepository(IApplicationDBContext dbContext,
|
||||
EmailSenderService emailSenderService,
|
||||
IHttpContextAccessor httpContextAccessor) : base(dbContext, httpContextAccessor)
|
||||
IHttpContextAccessor httpContextAccessor,
|
||||
IConfiguration configuration) : base(dbContext, httpContextAccessor)
|
||||
{
|
||||
_dbContext = dbContext;
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
_emailSenderService = emailSenderService;
|
||||
_configuration = configuration;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region " Methods "
|
||||
|
||||
public async Task<List<NotificationResponse>> GetMyNotificationAsync()
|
||||
public async Task<dynamic> GetMyNotificationAsync(int page = 1, int pageSize = 25)
|
||||
{
|
||||
try
|
||||
{
|
||||
var profile = await _dbContext.Set<Profile>()
|
||||
.FirstOrDefaultAsync(p => p.KeycloakId == Guid.Parse(UserId!));
|
||||
// var profile = await _dbContext.Set<Profile>()
|
||||
// .FirstOrDefaultAsync(p => p.KeycloakId == Guid.Parse(UserId!));
|
||||
|
||||
if (profile == null)
|
||||
// if (profile == null)
|
||||
// {
|
||||
// return new List<NotificationResponse>();
|
||||
// // throw new Exception(GlobalMessages.DataNotFound);
|
||||
// }
|
||||
|
||||
//var apiUrl = $"{_configuration["API"]}/org/profile/keycloak/position";
|
||||
var apiUrl = $"{_configuration["API"]}/org/dotnet/get-profileId";
|
||||
var profileId = "";
|
||||
using (var client = new HttpClient())
|
||||
{
|
||||
return new List<NotificationResponse>();
|
||||
// throw new Exception(GlobalMessages.DataNotFound);
|
||||
}
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Get, apiUrl);
|
||||
var _res = await client.SendAsync(_req);
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
|
||||
var data = await _dbContext.Set<Notification>()
|
||||
.Where(x => x.ReceiverUserId == profile.Id)
|
||||
.Where(x => x.IsOpen == false)
|
||||
var org = JsonConvert.DeserializeObject<OrgRequest>(_result);
|
||||
|
||||
if (org == null || org.result == null)
|
||||
return new List<InboxResponse>();
|
||||
profileId = org.result.profileId == null ? "" : org.result.profileId;
|
||||
}
|
||||
if (profileId == null || profileId == "")
|
||||
return new List<InboxResponse>();
|
||||
|
||||
var data_search = await _dbContext.Set<Notification>()
|
||||
.Where(x => x.ReceiverUserId == Guid.Parse(profileId))
|
||||
.Where(x => x.DeleteDate == null)
|
||||
.OrderByDescending(x => x.ReceiveDate)
|
||||
.ToListAsync();
|
||||
var totalNoti = data_search.Where(x => x.IsOpen == false).Count();
|
||||
var data = data_search
|
||||
.Skip((page - 1) * pageSize)
|
||||
.Take(pageSize)
|
||||
.Select(x => new NotificationResponse
|
||||
{
|
||||
Id = x.Id,
|
||||
Body = x.Body,
|
||||
ReceiverUserId = x.ReceiverUserId,
|
||||
KeycloakUserId = x.KeycloakUserId,
|
||||
IsOpen = x.IsOpen,
|
||||
Type = x.Type,
|
||||
ReceiveDate = x.ReceiveDate,
|
||||
OpenDate = x.OpenDate,
|
||||
Payload = x.Payload == "" ? null : JsonConvert.DeserializeObject<CommandPayload>(Regex.Unescape(x.Payload))
|
||||
})
|
||||
.Take(20)
|
||||
Payload = x.Payload
|
||||
}).ToList();
|
||||
|
||||
var data_opens = await _dbContext.Set<Notification>()
|
||||
.Where(x => x.ReceiverUserId == Guid.Parse(profileId))
|
||||
.Where(x => x.DeleteDate == null)
|
||||
.OrderByDescending(x => x.ReceiveDate)
|
||||
.Skip((page - 1) * pageSize)
|
||||
.Take(pageSize)
|
||||
// .Where(x => x.IsOpen == false)
|
||||
.ToListAsync();
|
||||
foreach (var data_open in data_opens)
|
||||
{
|
||||
data_open.IsOpen = true;
|
||||
data_open.OpenDate = DateTime.Now;
|
||||
}
|
||||
await _dbContext.SaveChangesAsync();
|
||||
|
||||
var _data = new { data, total = data_search.Count(), totalNoti = totalNoti };
|
||||
return _data;
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<dynamic> GetMyNotificationAsyncNoread()
|
||||
{
|
||||
try
|
||||
{
|
||||
// var profile = await _dbContext.Set<Profile>()
|
||||
// .FirstOrDefaultAsync(p => p.KeycloakId == Guid.Parse(UserId!));
|
||||
|
||||
// if (profile == null)
|
||||
// {
|
||||
// return 0;
|
||||
// }
|
||||
//var apiUrl = $"{_configuration["API"]}/org/profile/keycloak/position";
|
||||
var apiUrl = $"{_configuration["API"]}/org/dotnet/get-profileId";
|
||||
var profileId = "";
|
||||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Get, apiUrl);
|
||||
var _res = await client.SendAsync(_req);
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
|
||||
var org = JsonConvert.DeserializeObject<OrgRequest>(_result);
|
||||
|
||||
if (org == null || org.result == null)
|
||||
return 0;
|
||||
profileId = org.result.profileId == null ? "" : org.result.profileId;
|
||||
}
|
||||
if (profileId == null || profileId == "")
|
||||
return 0;
|
||||
|
||||
var data_search = await _dbContext.Set<Notification>()
|
||||
.Where(x => x.ReceiverUserId == Guid.Parse(profileId))
|
||||
.Where(x => x.DeleteDate == null)
|
||||
.Where(x => x.IsOpen == false)
|
||||
.OrderByDescending(x => x.ReceiveDate)
|
||||
.ToListAsync();
|
||||
|
||||
return data;
|
||||
return data_search.Count();
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
|
@ -85,7 +176,7 @@ namespace BMA.EHR.Application.Repositories.MessageQueue
|
|||
|
||||
if (notification != null)
|
||||
{
|
||||
notification.IsOpen = true;
|
||||
notification.DeleteDate = DateTime.Now;
|
||||
// _dbContext.Set<Notification>().Remove(notification);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
|
|
@ -96,19 +187,57 @@ namespace BMA.EHR.Application.Repositories.MessageQueue
|
|||
}
|
||||
}
|
||||
|
||||
public async Task PushNotificationAsync(Guid ReceiverUserId, string Subject, string Body, string Payload = "", bool IsSendInbox = false, bool IsSendMail = false)
|
||||
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 profile = await _dbContext.Set<Profile>().FirstOrDefaultAsync(x => x.Id == ReceiverUserId);
|
||||
if (profile != null)
|
||||
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
|
||||
{
|
||||
// var profile = await _dbContext.Set<Profile>().FirstOrDefaultAsync(x => x.Id == ReceiverUserId);
|
||||
//if (profile != null)
|
||||
//{
|
||||
_dbContext.Set<Notification>().Add(new Notification
|
||||
{
|
||||
Body = Body,
|
||||
ReceiverUserId = ReceiverUserId,
|
||||
Type = "",
|
||||
Payload = Payload,
|
||||
Payload = NotiLink,
|
||||
CreatedFullName = FullName ?? "System Administrator",
|
||||
CreatedUserId = UserId ?? "",
|
||||
CreatedAt = DateTime.Now,
|
||||
|
|
@ -134,7 +263,361 @@ namespace BMA.EHR.Application.Repositories.MessageQueue
|
|||
}
|
||||
if (IsSendMail == true)
|
||||
{
|
||||
_emailSenderService.SendMail(Subject, Body, "kittapath@frappet.com");
|
||||
var apiUrl = $"{_configuration["API"]}/org/dotnet/email/{ReceiverUserId}";
|
||||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Get, apiUrl);
|
||||
var _res = await client.SendAsync(_req);
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
|
||||
if (_res.IsSuccessStatusCode)
|
||||
{
|
||||
var org = JsonConvert.DeserializeObject<ResultRequest>(_result);
|
||||
if (org != null && org.result != null && org.result != "")
|
||||
_emailSenderService.SendMail(Subject, Body, org.result);
|
||||
}
|
||||
}
|
||||
}
|
||||
await _dbContext.SaveChangesAsync();
|
||||
//}
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
public async Task PushNotificationAsync2(Guid ReceiverUserId, string Subject, string Body, string Payload = "", string NotiLink = "", bool IsSendInbox = false, bool IsSendMail = false)
|
||||
{
|
||||
try
|
||||
{
|
||||
_dbContext.Set<Notification>().Add(new Notification
|
||||
{
|
||||
Body = Body,
|
||||
ReceiverUserId = ReceiverUserId,
|
||||
Type = "",
|
||||
Payload = NotiLink,
|
||||
CreatedFullName = FullName ?? "System Administrator",
|
||||
CreatedUserId = UserId ?? "",
|
||||
CreatedAt = DateTime.Now,
|
||||
LastUpdateFullName = FullName ?? "System Administrator",
|
||||
LastUpdateUserId = UserId ?? "",
|
||||
LastUpdatedAt = DateTime.Now,
|
||||
});
|
||||
/* if (IsSendInbox == true)
|
||||
{
|
||||
_dbContext.Set<Inbox>().Add(new Inbox
|
||||
{
|
||||
Subject = Subject,
|
||||
Body = Body,
|
||||
ReceiverUserId = ReceiverUserId,
|
||||
Payload = Payload,
|
||||
CreatedFullName = FullName ?? "System Administrator",
|
||||
CreatedUserId = UserId ?? "",
|
||||
CreatedAt = DateTime.Now,
|
||||
LastUpdateFullName = FullName ?? "System Administrator",
|
||||
LastUpdateUserId = UserId ?? "",
|
||||
LastUpdatedAt = DateTime.Now,
|
||||
});
|
||||
}*/
|
||||
if (IsSendMail == true)
|
||||
{
|
||||
var apiUrl = $"{_configuration["API"]}/org/dotnet/email/{ReceiverUserId}";
|
||||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Get, apiUrl);
|
||||
var _res = await client.SendAsync(_req);
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
|
||||
if (_res.IsSuccessStatusCode)
|
||||
{
|
||||
var org = JsonConvert.DeserializeObject<ResultRequest>(_result);
|
||||
if (org != null && org.result != null && org.result != "")
|
||||
_emailSenderService.SendMail(Subject, Body, org.result);
|
||||
}
|
||||
}
|
||||
}
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task PushEmailAsync(string Subject, string Body, string Email = "")
|
||||
{
|
||||
try
|
||||
{
|
||||
_emailSenderService.SendMail(Subject, Body, Email);
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task PushNotificationsAsync(Guid[] ReceiverUserIds, string Subject, string Body, string Payload = "", string NotiLink = "", bool IsSendInbox = false, bool IsSendMail = false)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (var ReceiverUserId in ReceiverUserIds)
|
||||
{
|
||||
_dbContext.Set<Notification>().Add(new Notification
|
||||
{
|
||||
Body = Body,
|
||||
ReceiverUserId = ReceiverUserId,
|
||||
Type = "",
|
||||
Payload = NotiLink,
|
||||
CreatedFullName = FullName ?? "System Administrator",
|
||||
CreatedUserId = UserId ?? "",
|
||||
CreatedAt = DateTime.Now,
|
||||
LastUpdateFullName = FullName ?? "System Administrator",
|
||||
LastUpdateUserId = UserId ?? "",
|
||||
LastUpdatedAt = DateTime.Now,
|
||||
});
|
||||
if (IsSendInbox == true)
|
||||
{
|
||||
_dbContext.Set<Inbox>().Add(new Inbox
|
||||
{
|
||||
Subject = Subject,
|
||||
Body = Body,
|
||||
ReceiverUserId = ReceiverUserId,
|
||||
Payload = Payload,
|
||||
CreatedFullName = FullName ?? "System Administrator",
|
||||
CreatedUserId = UserId ?? "",
|
||||
CreatedAt = DateTime.Now,
|
||||
LastUpdateFullName = FullName ?? "System Administrator",
|
||||
LastUpdateUserId = UserId ?? "",
|
||||
LastUpdatedAt = DateTime.Now,
|
||||
});
|
||||
}
|
||||
if (IsSendMail == true)
|
||||
{
|
||||
var apiUrl = $"{_configuration["API"]}/org/dotnet/email/{ReceiverUserId}";
|
||||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Get, apiUrl);
|
||||
var _res = await client.SendAsync(_req);
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
|
||||
if (_res.IsSuccessStatusCode)
|
||||
{
|
||||
var org = JsonConvert.DeserializeObject<ResultRequest>(_result);
|
||||
if (org != null && org.result != null && org.result != "")
|
||||
_emailSenderService.SendMail(Subject, Body, org.result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public class NotisLinkRequest
|
||||
{
|
||||
public Guid ReceiverUserId { get; set; }
|
||||
public string NotiLink { get; set; }
|
||||
}
|
||||
|
||||
public class ResultRequest
|
||||
{
|
||||
public string result { get; set; }
|
||||
}
|
||||
public async Task PushNotificationsLinkAsync(NotisLinkRequest[] ReceiverUserIds, string Subject, string Body, string Payload = "", bool IsSendInbox = false, bool IsSendMail = false)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (var ReceiverUserId in ReceiverUserIds)
|
||||
{
|
||||
_dbContext.Set<Notification>().Add(new Notification
|
||||
{
|
||||
Body = Body,
|
||||
ReceiverUserId = ReceiverUserId.ReceiverUserId,
|
||||
Type = "",
|
||||
Payload = ReceiverUserId.NotiLink,
|
||||
CreatedFullName = FullName ?? "System Administrator",
|
||||
CreatedUserId = UserId ?? "",
|
||||
CreatedAt = DateTime.Now,
|
||||
LastUpdateFullName = FullName ?? "System Administrator",
|
||||
LastUpdateUserId = UserId ?? "",
|
||||
LastUpdatedAt = DateTime.Now,
|
||||
});
|
||||
if (IsSendInbox == true)
|
||||
{
|
||||
_dbContext.Set<Inbox>().Add(new Inbox
|
||||
{
|
||||
Subject = Subject,
|
||||
Body = Body,
|
||||
ReceiverUserId = ReceiverUserId.ReceiverUserId,
|
||||
Payload = Payload,
|
||||
CreatedFullName = FullName ?? "System Administrator",
|
||||
CreatedUserId = UserId ?? "",
|
||||
CreatedAt = DateTime.Now,
|
||||
LastUpdateFullName = FullName ?? "System Administrator",
|
||||
LastUpdateUserId = UserId ?? "",
|
||||
LastUpdatedAt = DateTime.Now,
|
||||
});
|
||||
}
|
||||
if (IsSendMail == true)
|
||||
{
|
||||
var apiUrl = $"{_configuration["API"]}/org/dotnet/email/{ReceiverUserId.ReceiverUserId}";
|
||||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Get, apiUrl);
|
||||
var _res = await client.SendAsync(_req);
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
|
||||
if (_res.IsSuccessStatusCode)
|
||||
{
|
||||
var org = JsonConvert.DeserializeObject<ResultRequest>(_result);
|
||||
if (org != null && org.result != null && org.result != "")
|
||||
_emailSenderService.SendMail(Subject, Body, org.result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public class NotisLinkSendRequest
|
||||
{
|
||||
public Guid ReceiverUserId { get; set; }
|
||||
public string NotiLink { get; set; }
|
||||
public bool IsSendMail { get; set; }
|
||||
public bool IsSendInbox { get; set; }
|
||||
}
|
||||
public async Task PushNotificationsLinkSendAsync(NotisLinkSendRequest[] ReceiverUserIds, string Subject, string Body, string Payload = "")
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (var data in ReceiverUserIds)
|
||||
{
|
||||
_dbContext.Set<Notification>().Add(new Notification
|
||||
{
|
||||
Body = Body,
|
||||
ReceiverUserId = data.ReceiverUserId,
|
||||
Type = "",
|
||||
Payload = data.NotiLink,
|
||||
CreatedFullName = FullName ?? "System Administrator",
|
||||
CreatedUserId = UserId ?? "",
|
||||
CreatedAt = DateTime.Now,
|
||||
LastUpdateFullName = FullName ?? "System Administrator",
|
||||
LastUpdateUserId = UserId ?? "",
|
||||
LastUpdatedAt = DateTime.Now,
|
||||
});
|
||||
if (data.IsSendInbox == true)
|
||||
{
|
||||
_dbContext.Set<Inbox>().Add(new Inbox
|
||||
{
|
||||
Subject = Subject,
|
||||
Body = Body,
|
||||
ReceiverUserId = data.ReceiverUserId,
|
||||
Payload = Payload,
|
||||
CreatedFullName = FullName ?? "System Administrator",
|
||||
CreatedUserId = UserId ?? "",
|
||||
CreatedAt = DateTime.Now,
|
||||
LastUpdateFullName = FullName ?? "System Administrator",
|
||||
LastUpdateUserId = UserId ?? "",
|
||||
LastUpdatedAt = DateTime.Now,
|
||||
});
|
||||
}
|
||||
if (data.IsSendMail == true)
|
||||
{
|
||||
var apiUrl = $"{_configuration["API"]}/org/dotnet/email/{data.ReceiverUserId}";
|
||||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Get, apiUrl);
|
||||
var _res = await client.SendAsync(_req);
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
|
||||
if (_res.IsSuccessStatusCode)
|
||||
{
|
||||
var org = JsonConvert.DeserializeObject<ResultRequest>(_result);
|
||||
if (org != null && org.result != null && org.result != "")
|
||||
_emailSenderService.SendMail(Subject, Body, org.result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
public async Task PushNotificationAsyncV2(string? ReceiverUserId, string Subject, string Body, string Payload = "", bool IsSendInbox = false, bool IsSendMail = false)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (ReceiverUserId != null)
|
||||
{
|
||||
_dbContext.Set<Notification>().Add(new Notification
|
||||
{
|
||||
Body = Body,
|
||||
KeycloakUserId = ReceiverUserId,
|
||||
Type = "",
|
||||
Payload = Payload,
|
||||
CreatedFullName = FullName ?? "System Administrator",
|
||||
CreatedUserId = UserId ?? "",
|
||||
CreatedAt = DateTime.Now,
|
||||
LastUpdateFullName = FullName ?? "System Administrator",
|
||||
LastUpdateUserId = UserId ?? "",
|
||||
LastUpdatedAt = DateTime.Now,
|
||||
});
|
||||
if (IsSendInbox == true)
|
||||
{
|
||||
_dbContext.Set<Inbox>().Add(new Inbox
|
||||
{
|
||||
Subject = Subject,
|
||||
Body = Body,
|
||||
KeycloakUserId = ReceiverUserId,
|
||||
Payload = Payload,
|
||||
CreatedFullName = FullName ?? "System Administrator",
|
||||
CreatedUserId = UserId ?? "",
|
||||
CreatedAt = DateTime.Now,
|
||||
LastUpdateFullName = FullName ?? "System Administrator",
|
||||
LastUpdateUserId = UserId ?? "",
|
||||
LastUpdatedAt = DateTime.Now,
|
||||
});
|
||||
}
|
||||
if (IsSendMail == true)
|
||||
{
|
||||
var apiUrl = $"{_configuration["API"]}/org/dotnet/email/{ReceiverUserId}";
|
||||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Get, apiUrl);
|
||||
var _res = await client.SendAsync(_req);
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
|
||||
if (_res.IsSuccessStatusCode)
|
||||
{
|
||||
var org = JsonConvert.DeserializeObject<ResultRequest>(_result);
|
||||
if (org != null && org.result != null && org.result != "")
|
||||
_emailSenderService.SendMail(Subject, Body, org.result);
|
||||
}
|
||||
}
|
||||
}
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,21 +26,61 @@ namespace BMA.EHR.Application.Repositories.MetaData
|
|||
|
||||
#region " Methods "
|
||||
|
||||
public async Task<int> GetHolidayCountAsync(DateTime startDate, DateTime endDate, string category = "NORMAL")
|
||||
public async Task<string> GetHolidayAsync(DateTime date, string category = "NORMAL")
|
||||
{
|
||||
var data = await _dbContext.Set<Holiday>().AsQueryable()
|
||||
.Where(x => x.Category == category)
|
||||
.Where(x => x.HolidayDate.Date == date.Date)
|
||||
.Select(x => x.Name)
|
||||
.FirstOrDefaultAsync();
|
||||
return data ?? string.Empty;
|
||||
}
|
||||
|
||||
public async Task<List<DateTime>> GetHolidayAsync(DateTime startDate, DateTime endDate, string category = "NORMAL")
|
||||
{
|
||||
var data = await _dbContext.Set<Holiday>().AsQueryable()
|
||||
.Where(x => x.Category == category)
|
||||
.Where(x => x.HolidayDate.Date >= startDate && x.HolidayDate.Date <= endDate)
|
||||
.CountAsync();
|
||||
.Select(x => x.HolidayDate.Date)
|
||||
.ToListAsync();
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public async Task<int> GetHolidayCountAsync(DateTime startDate, DateTime endDate, string category = "NORMAL")
|
||||
{
|
||||
var query = _dbContext.Set<Holiday>().AsQueryable()
|
||||
.Where(x => x.Category == category)
|
||||
.Where(x => x.HolidayDate.Date >= startDate && x.HolidayDate.Date <= endDate);
|
||||
|
||||
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")
|
||||
{
|
||||
var dates = new List<DateTime>();
|
||||
|
||||
for (DateTime i = startDate; i <= endDate; i = i.AddDays(1))
|
||||
{
|
||||
dates.Add(i);
|
||||
}
|
||||
|
||||
if (category == "NORMAL")
|
||||
return dates.Where(d => d.DayOfWeek == DayOfWeek.Saturday || d.DayOfWeek == DayOfWeek.Sunday).ToList();
|
||||
else
|
||||
return dates.Where(d => d.DayOfWeek == DayOfWeek.Sunday).ToList();
|
||||
}
|
||||
|
||||
public int GetWeekEndCount(DateTime startDate, DateTime endDate, string category = "NORMAL")
|
||||
{
|
||||
var dates = new List<DateTime>();
|
||||
|
||||
for (DateTime i = startDate; i < endDate; i = i.AddDays(1))
|
||||
for (DateTime i = startDate; i <= endDate; i = i.AddDays(1))
|
||||
{
|
||||
dates.Add(i);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
using Amazon.S3;
|
||||
using Amazon.S3;
|
||||
using Amazon.S3.Model;
|
||||
using BMA.EHR.Domain.Shared;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
|
|
@ -37,7 +37,9 @@ namespace BMA.EHR.Application.Repositories
|
|||
var config = new AmazonS3Config
|
||||
{
|
||||
ServiceURL = _configuration["MinIO:Endpoint"],
|
||||
ForcePathStyle = true
|
||||
ForcePathStyle = true,
|
||||
SignatureVersion = "V4", // รองรับ MinIO
|
||||
AuthenticationRegion = "th-middle-rack-1" // บาง MinIO ใช้ region "us-east-1" โดย default
|
||||
};
|
||||
|
||||
_s3Client = new AmazonS3Client(_configuration["MinIO:AccessKey"], _configuration["MinIO:SecretKey"], config);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
using Amazon.S3;
|
||||
using Amazon.S3;
|
||||
using Amazon.S3.Model;
|
||||
using BMA.EHR.Domain.Models.Documents;
|
||||
using BMA.EHR.Domain.Shared;
|
||||
|
|
@ -40,7 +40,9 @@ namespace BMA.EHR.Application.Repositories
|
|||
var config = new AmazonS3Config
|
||||
{
|
||||
ServiceURL = _configuration["MinIO:Endpoint"],
|
||||
ForcePathStyle = true
|
||||
ForcePathStyle = true,
|
||||
SignatureVersion = "V4", // รองรับ MinIO
|
||||
AuthenticationRegion = "th-middle-rack-1" // บาง MinIO ใช้ region "us-east-1" โดย default
|
||||
};
|
||||
|
||||
_s3Client = new AmazonS3Client(_configuration["MinIO:AccessKey"], _configuration["MinIO:SecretKey"], config);
|
||||
|
|
|
|||
|
|
@ -43,7 +43,9 @@ namespace BMA.EHR.Application.Repositories
|
|||
var config = new AmazonS3Config
|
||||
{
|
||||
ServiceURL = _configuration["MinIO:Endpoint"],
|
||||
ForcePathStyle = true
|
||||
ForcePathStyle = true,
|
||||
SignatureVersion = "V4", // รองรับ MinIO
|
||||
AuthenticationRegion = "th-middle-rack-1" // บาง MinIO ใช้ region "us-east-1" โดย default
|
||||
};
|
||||
|
||||
_s3Client = new AmazonS3Client(_configuration["MinIO:AccessKey"], _configuration["MinIO:SecretKey"], config);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
using Amazon.S3;
|
||||
using Amazon.S3;
|
||||
using Amazon.S3.Model;
|
||||
using BMA.EHR.Application.Common.Interfaces;
|
||||
using BMA.EHR.Domain.Models.Documents;
|
||||
|
|
@ -39,7 +39,9 @@ namespace BMA.EHR.Application.Repositories
|
|||
var config = new AmazonS3Config
|
||||
{
|
||||
ServiceURL = _configuration["MinIO:Endpoint"],
|
||||
ForcePathStyle = true
|
||||
ForcePathStyle = true,
|
||||
SignatureVersion = "V4", // รองรับ MinIO
|
||||
AuthenticationRegion = "th-middle-rack-1" // บาง MinIO ใช้ region "us-east-1" โดย default
|
||||
};
|
||||
|
||||
_s3Client = new AmazonS3Client(_configuration["MinIO:AccessKey"], _configuration["MinIO:SecretKey"], config);
|
||||
|
|
@ -153,6 +155,40 @@ namespace BMA.EHR.Application.Repositories
|
|||
}
|
||||
}
|
||||
|
||||
public async Task<FormFile> GetImageToFormFileAsync(string refId)
|
||||
{
|
||||
try
|
||||
{
|
||||
using var memoryStream = new MemoryStream();
|
||||
var request = new GetObjectRequest
|
||||
{
|
||||
BucketName = _bucketName,
|
||||
Key = refId
|
||||
};
|
||||
|
||||
using var response = await _s3Client.GetObjectAsync(request);
|
||||
using var responseStream = response.ResponseStream;
|
||||
|
||||
await responseStream.CopyToAsync(memoryStream);
|
||||
|
||||
var finalBytes = memoryStream.ToArray();
|
||||
|
||||
var finalStream = new MemoryStream(finalBytes);
|
||||
var fileName = Path.GetFileName(refId);
|
||||
var contentType = response.Headers.ContentType ?? "image/jpeg";
|
||||
|
||||
return new FormFile(finalStream, 0, finalStream.Length, "file", fileName)
|
||||
{
|
||||
Headers = new HeaderDictionary(),
|
||||
ContentType = contentType
|
||||
};
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task DeleteFileAsync(Guid fileId)
|
||||
{
|
||||
try
|
||||
|
|
|
|||
169
BMA.EHR.Application/Repositories/PermissionRepository.cs
Normal file
169
BMA.EHR.Application/Repositories/PermissionRepository.cs
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
using BMA.EHR.Application.Common.Interfaces;
|
||||
using BMA.EHR.Application.Responses;
|
||||
using BMA.EHR.Domain.Models.MetaData;
|
||||
using BMA.EHR.Domain.Models.Organizations;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json;
|
||||
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
|
||||
{
|
||||
public class PermissionRepository
|
||||
{
|
||||
#region " Fields "
|
||||
|
||||
private readonly IApplicationDBContext _dbContext;
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
#endregion
|
||||
|
||||
#region " Constructor and Destuctor "
|
||||
|
||||
public PermissionRepository(IApplicationDBContext dbContext,
|
||||
IHttpContextAccessor httpContextAccessor,
|
||||
IConfiguration configuration)
|
||||
{
|
||||
_dbContext = dbContext;
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
_configuration = configuration;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region " Properties "
|
||||
|
||||
//protected string? UserId => _httpContextAccessor?.HttpContext?.User?.FindFirst(ClaimTypes.NameIdentifier)?.Value;
|
||||
|
||||
//protected string? FullName => _httpContextAccessor?.HttpContext?.User?.FindFirst("name")?.Value;
|
||||
|
||||
//protected bool? IsPlacementAdmin => _httpContextAccessor?.HttpContext?.User?.IsInRole("placement1");
|
||||
|
||||
protected string? AccessToken => _httpContextAccessor?.HttpContext?.Request.Headers["Authorization"];
|
||||
|
||||
#endregion
|
||||
|
||||
#region " Methods "
|
||||
|
||||
public async Task<dynamic> GetPermissionAPIAsync(string action, string system)
|
||||
{
|
||||
try
|
||||
{
|
||||
var apiPath = $"{_configuration["API"]}/org/permission/dotnet/{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 res = await req.Content.ReadAsStringAsync();
|
||||
return res;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
var apiPath = $"{_configuration["API"]}/org/permission/dotnet-org/{action}/{system}/{profileId}";
|
||||
|
||||
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);
|
||||
var res = await req.Content.ReadAsStringAsync();
|
||||
return res;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<dynamic> GetPermissionAPIWorkflowAsync(string refId, string sysName)
|
||||
{
|
||||
try
|
||||
{
|
||||
var apiPath = $"{_configuration["API"]}/org/workflow/keycloak/isofficer";
|
||||
|
||||
using (var client = new HttpClient())
|
||||
{
|
||||
var res = await client.PostAsJsonAsync(apiPath, new
|
||||
{
|
||||
data = new
|
||||
{
|
||||
refId = refId,
|
||||
sysName = sysName,
|
||||
},
|
||||
});
|
||||
var result = await res.Content.ReadAsStringAsync();
|
||||
if (res.IsSuccessStatusCode)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using BMA.EHR.Domain.Shared;
|
|||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using static BMA.EHR.Domain.Extensions.DateTimeExtension;
|
||||
|
||||
namespace BMA.EHR.Application.Repositories.Reports
|
||||
|
|
@ -82,76 +83,128 @@ namespace BMA.EHR.Application.Repositories.Reports
|
|||
sb.Append(monthDiff == 0 ? "" : $"{monthDiff} เดือน ");
|
||||
sb.Append(dayDiff == 0 ? "" : $"{dayDiff} วัน ");
|
||||
}
|
||||
var data = await _dbExamContext.Set<Candidate>().AsQueryable()
|
||||
var candidate = await _dbExamContext.Set<Candidate>()
|
||||
.Where(x => x.Id == id)
|
||||
.Select(p => new
|
||||
.Include(p => p.PeriodExam)
|
||||
.Include(p => p.Educations)
|
||||
.Include(p => p.PositionExam)
|
||||
.Include(p => p.ProfileImg)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
if (candidate == null)
|
||||
throw new Exception(GlobalMessages.CandidateNotFound);
|
||||
|
||||
List<string> editorConfirmLists;
|
||||
|
||||
var textOnly = string.IsNullOrEmpty(candidate.PeriodExam?.EditorConfirm)
|
||||
? null
|
||||
: Regex.Replace(
|
||||
candidate.PeriodExam.EditorConfirm,
|
||||
"<[^>]+>",
|
||||
string.Empty
|
||||
)
|
||||
.Replace(" ", " ")
|
||||
.Trim();
|
||||
|
||||
if (!string.IsNullOrEmpty(textOnly))
|
||||
{
|
||||
p.Id,
|
||||
AvatarId = p.ProfileImg == null ? Guid.Parse("00000000-0000-0000-0000-000000000000") : p.ProfileImg.Id,
|
||||
ExamIdenNumber = p.ExamIdenNumber == null ? "-" : p.ExamIdenNumber,
|
||||
PositionName = p.PositionExam == null ? "-" : p.PositionExam.PositionName,
|
||||
PositionLevelName = p.PositionExam == null ? "-" : p.PositionExam.PositionLevelName,
|
||||
PeriodExamName = p.PeriodExam == null ? "-" : p.PeriodExam.Name,
|
||||
PeriodExamRound = p.PeriodExam == null ? "-" : p.PeriodExam.Round.ToString(),
|
||||
PeriodExamYear = p.PeriodExam == null ? "-" : (p.PeriodExam.Year + 543).ToString(),
|
||||
// ลบข้อความทั้งหมดก่อน "1." เพื่อให้เริ่มต้นที่ข้อแรกเสมอ
|
||||
var cleanedText = Regex.Replace(textOnly, @"^.*?1\.", "1.").Trim();
|
||||
|
||||
FullName = $"{p.PrefixName}{p.FirstName} {p.LastName}",
|
||||
Religion = p.ReligionName == null ? "-" : p.ReligionName,
|
||||
Nationality = p.Nationality == null ? "-" : p.Nationality,
|
||||
DateOfBirth = p.DateOfBirth == null ? "-" : p.DateOfBirth.Value.ToThaiFullDate2(),
|
||||
Age = p.DateOfBirth == null ? "-" : p.DateOfBirth.Value.CalculateAgeStrV2(0, 0),
|
||||
CitizenId = p.CitizenId == null ? "-" : p.CitizenId,
|
||||
// ถ้าข้อ 3 จบด้วย "มาตรา 1374." แล้วเลข 4. ติดกับประโยค ให้แทรกขึ้นบรรทัดใหม่เป็นข้อ 4.
|
||||
if (!cleanedText.Contains("\n4.") && Regex.IsMatch(cleanedText, @"1374\.\s*"))
|
||||
{
|
||||
cleanedText = Regex.Replace(cleanedText, @"1374\.\s*", "137\n4. ");
|
||||
}
|
||||
|
||||
EducationLevelExamName = p.Educations.FirstOrDefault() == null ? "-" : p.Educations.FirstOrDefault().EducationLevelExamName,
|
||||
EducationName = p.Educations.FirstOrDefault() == null ? null : (p.Educations.FirstOrDefault().EducationLevelExamName == "ปริญญาตรี" || p.Educations.FirstOrDefault().EducationLevelExamName == "ปริญญาโท" || p.Educations.FirstOrDefault().EducationLevelExamName == "ปริญญาเอก" ? p.Educations.FirstOrDefault().EducationName : null),
|
||||
EducationMajor = p.Educations.FirstOrDefault() == null ? "-" : p.Educations.FirstOrDefault().EducationMajor,
|
||||
EducationLocation = p.Educations.FirstOrDefault() == null ? "-" : p.Educations.FirstOrDefault().EducationLocation,
|
||||
EducationEndDate = p.Educations.FirstOrDefault() == null || p.Educations.FirstOrDefault().EducationEndDate == null ? "-" : p.Educations.FirstOrDefault().EducationEndDate.Value.ToThaiFullDate2(),
|
||||
EducationScores = p.Educations.FirstOrDefault() == null ? "-" : p.Educations.FirstOrDefault().EducationScores,
|
||||
EducationType = p.Educations.FirstOrDefault() == null ? "-" : p.Educations.FirstOrDefault().EducationType,
|
||||
EducationLevelHighName = p.Educations.FirstOrDefault() == null ? "-" : p.Educations.FirstOrDefault().EducationLevelHighName,
|
||||
// แยกข้อความเป็นแต่ละข้อ โดย split เมื่อเจอ pattern "ตัวเลข. "
|
||||
// ใช้ lookahead (?=...) เพื่อไม่กินตัวเลขทิ้ง และให้ตัวเลขยังอยู่ในผลลัพธ์
|
||||
editorConfirmLists = Regex.Split(cleanedText, @"(?=\d+\. )")
|
||||
.Where(s => !string.IsNullOrWhiteSpace(s))
|
||||
.Select(s => s.Replace("\n", "").Replace("\r", "").Trim())
|
||||
.ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
editorConfirmLists = new List<string> { "-" };
|
||||
}
|
||||
|
||||
OccupationPositionType = p.OccupationPositionType == "other" ? "ผู้ปฏิบัติงานอื่นในกรุงเทพมหานคร" : (p.OccupationPositionType == "temp" ? "ลูกจ้างชั่วคราว" : (p.OccupationPositionType == "prem" ? "ลูกจ้างประจำ" : "-")),
|
||||
OccupationPosition = p.OccupationPosition == null ? "-" : p.OccupationPosition,
|
||||
OccupationSalary = p.OccupationSalary == null ? "-" : p.OccupationSalary.ToString(),
|
||||
OccupationGroup = p.OccupationGroup == null ? "-" : p.OccupationGroup,
|
||||
OccupationPile = p.OccupationPile == null ? "-" : p.OccupationPile,
|
||||
OccupationOrg = p.OccupationOrg == null ? "-" : p.OccupationOrg,
|
||||
OccupationTelephone = p.OccupationTelephone == null ? "-" : p.OccupationTelephone,
|
||||
return new
|
||||
{
|
||||
candidate.Id,
|
||||
AvatarId = candidate.ProfileImg?.Id ?? Guid.Empty,
|
||||
ExamIdenNumber = candidate.ExamIdenNumber ?? "-",
|
||||
PositionName = candidate.PositionExam?.PositionName ?? "-",
|
||||
PositionLevelName = candidate.PositionExam?.PositionLevelName ?? "-",
|
||||
PeriodExamName = candidate.PeriodExam?.Name ?? "-",
|
||||
PeriodExamRound = candidate.PeriodExam?.Round.ToString() ?? "-",
|
||||
PeriodExamYear = candidate.PeriodExam != null ? (candidate.PeriodExam.Year + 543).ToString() : "-",
|
||||
FullName = $"{candidate.PrefixName}{candidate.FirstName} {candidate.LastName}",
|
||||
Religion = candidate.ReligionName ?? "-",
|
||||
Nationality = candidate.Nationality ?? "-",
|
||||
DateOfBirth = candidate.DateOfBirth?.ToThaiFullDate2() ?? "-",
|
||||
Age = candidate.DateOfBirth?.CalculateAgeStrV2(0, 0) ?? "-",
|
||||
CitizenId = candidate.CitizenId ?? "-",
|
||||
|
||||
EducationLevelExamName = candidate.Educations.FirstOrDefault()?.EducationLevelExamName ?? "-",
|
||||
EducationName = (candidate.Educations.FirstOrDefault()?.EducationLevelExamName is "ปริญญาตรี" or "ปริญญาโท" or "ปริญญาเอก")
|
||||
? candidate.Educations.FirstOrDefault()?.EducationName
|
||||
: null,
|
||||
EducationMajor = candidate.Educations.FirstOrDefault()?.EducationMajor ?? "-",
|
||||
EducationLocation = candidate.Educations.FirstOrDefault()?.EducationLocation ?? "-",
|
||||
EducationEndDate = candidate.Educations.FirstOrDefault()?.EducationEndDate?.ToThaiFullDate2() ?? "-",
|
||||
EducationScores = candidate.Educations.FirstOrDefault()?.EducationScores ?? "-",
|
||||
EducationType = candidate.Educations.FirstOrDefault()?.EducationType ?? "-",
|
||||
EducationLevelHighName = candidate.Educations.FirstOrDefault()?.EducationLevelHighName ?? "-",
|
||||
|
||||
OccupationPositionType = candidate.OccupationPositionType == "other" ? "ผู้ปฏิบัติงานอื่นในกรุงเทพมหานคร" :
|
||||
candidate.OccupationPositionType == "temp" ? "ลูกจ้างชั่วคราว" :
|
||||
candidate.OccupationPositionType == "prem" ? "ลูกจ้างประจำ" : "-",
|
||||
OccupationPosition = candidate.OccupationPosition ?? "-",
|
||||
OccupationSalary = candidate.OccupationSalary.HasValue
|
||||
? (candidate.OccupationSalary.Value % 1 == 0
|
||||
? candidate.OccupationSalary.Value.ToString("N0")
|
||||
: candidate.OccupationSalary.Value.ToString("N2"))
|
||||
: "-",
|
||||
OccupationGroup = candidate.OccupationGroup ?? "-",
|
||||
OccupationPile = candidate.OccupationPile ?? "-",
|
||||
OccupationOrg = candidate.OccupationOrg ?? "-",
|
||||
OccupationTelephone = candidate.OccupationTelephone ?? "-",
|
||||
|
||||
CareersTotal = sb.ToString(),
|
||||
// Careers = p.Careers.Select(y => new
|
||||
// {
|
||||
// Position = y.Position,
|
||||
// Type = y.Type,
|
||||
// DurationStart = y.DurationStart.ToThaiShortDate2(),
|
||||
// DurationEnd = y.DurationEnd.ToThaiShortDate2(),
|
||||
// RangeDate = y.RangeDate,
|
||||
// }).ToList(),
|
||||
|
||||
RegistAddress = p.RegistAddress == null ? "-" : p.RegistAddress,
|
||||
RegistProvinceName = p.RegistProvinceName == null ? "-" : p.RegistProvinceName,
|
||||
RegistDistrictName = p.RegistDistrictName == null ? "-" : p.RegistDistrictName,
|
||||
RegistSubDistrictName = p.RegistSubDistrictName == null ? "-" : p.RegistSubDistrictName,
|
||||
RegistZipCode = p.RegistZipCode == null ? "-" : p.RegistZipCode,
|
||||
CurrentAddress = p.CurrentAddress == null ? (p.RegistAddress == null ? "-" : p.RegistAddress) : p.CurrentAddress,
|
||||
CurrentProvinceName = p.CurrentProvinceName == null ? (p.RegistProvinceName == null ? "-" : p.RegistProvinceName) : p.CurrentProvinceName,
|
||||
CurrentDistrictName = p.CurrentDistrictName == null ? (p.RegistDistrictName == null ? "-" : p.RegistDistrictName) : p.CurrentDistrictName,
|
||||
CurrentSubDistrictName = p.CurrentSubDistrictName == null ? (p.RegistSubDistrictName == null ? "-" : p.RegistSubDistrictName) : p.CurrentSubDistrictName,
|
||||
CurrentZipCode = p.CurrentZipCode == null ? (p.RegistZipCode == null ? "-" : p.RegistZipCode) : p.CurrentZipCode,
|
||||
Telephone = p.Telephone == null ? "-" : p.Telephone,
|
||||
Email = p.Email == null ? "-" : p.Email,
|
||||
RegistAddress = candidate.RegistAddress ?? "-",
|
||||
RegistProvinceName = candidate.RegistProvinceName ?? "-",
|
||||
RegistDistrictName = candidate.RegistDistrictName ?? "-",
|
||||
RegistSubDistrictName = candidate.RegistSubDistrictName ?? "-",
|
||||
RegistZipCode = candidate.RegistZipCode ?? "-",
|
||||
CurrentAddress = candidate.CurrentAddress ?? candidate.RegistAddress ?? "-",
|
||||
CurrentProvinceName = candidate.CurrentProvinceName ?? candidate.RegistProvinceName ?? "-",
|
||||
CurrentDistrictName = candidate.CurrentDistrictName ?? candidate.RegistDistrictName ?? "-",
|
||||
CurrentSubDistrictName = candidate.CurrentSubDistrictName ?? candidate.RegistSubDistrictName ?? "-",
|
||||
CurrentZipCode = candidate.CurrentZipCode ?? candidate.RegistZipCode ?? "-",
|
||||
Telephone = candidate.Telephone ?? "-",
|
||||
Email = candidate.Email ?? "-",
|
||||
|
||||
ContactFullName = $"{p.ContactPrefixName}{p.ContactFirstname} {p.ContactLastname}",
|
||||
ContactRelations = p.ContactRelations == null ? "-" : p.ContactRelations,
|
||||
ContactTel = p.ContactTel == null ? "-" : p.ContactTel,
|
||||
ContactFullName = $"{candidate.ContactPrefixName}{candidate.ContactFirstname} {candidate.ContactLastname}",
|
||||
ContactRelations = candidate.ContactRelations ?? "-",
|
||||
ContactTel = candidate.ContactTel ?? "-",
|
||||
|
||||
RegisterDate = p.RegisterDate == null ? "-" : p.RegisterDate.Value.ToThaiFullDate(),
|
||||
})
|
||||
.FirstOrDefaultAsync();
|
||||
if (data == null)
|
||||
throw new Exception(GlobalMessages.CandidateNotFound);
|
||||
return data;
|
||||
RegisterDate = candidate.RegisterDate?.ToThaiFullDate() ?? "-",
|
||||
|
||||
IsBachelors = candidate.PositionExam != null && !string.IsNullOrEmpty(candidate.PositionExam.PositionLevelName) && candidate.PositionExam.PositionLevelName.Trim() == "ปฏิบัติการ"
|
||||
? new List<object>
|
||||
{
|
||||
new { label = "ชื่อปริญญา", value = candidate.Educations.FirstOrDefault()?.EducationName ?? "-" },
|
||||
new { label = "สาขาวิชา/วิชาเอก", value = candidate.Educations.FirstOrDefault()?.EducationMajor ?? "-" }
|
||||
}
|
||||
: new List<object>
|
||||
{
|
||||
new { label = "สาขาวิชา/วิชาเอก", value = candidate.Educations.FirstOrDefault()?.EducationMajor ?? "-" }
|
||||
},
|
||||
|
||||
EditorConfirms = editorConfirmLists
|
||||
};
|
||||
}
|
||||
public async Task<dynamic> GetExamCareerCandidateAsync(Guid id)
|
||||
{
|
||||
|
|
@ -179,7 +232,7 @@ namespace BMA.EHR.Application.Repositories.Reports
|
|||
DurationStart = item.DurationStart,
|
||||
DurationEnd = item.DurationEnd,
|
||||
RangeDate = item.RangeDate,
|
||||
Index = retVal,
|
||||
Index = retVal.ToString(),
|
||||
};
|
||||
data.Add(_data);
|
||||
retVal++;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,4 +1,5 @@
|
|||
using System.Reflection.Metadata;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Reflection.Metadata;
|
||||
using BMA.EHR.Application.Common.Interfaces;
|
||||
using BMA.EHR.Application.Responses;
|
||||
using BMA.EHR.Domain.Extensions;
|
||||
|
|
@ -9,6 +10,7 @@ using Microsoft.AspNetCore.Hosting;
|
|||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace BMA.EHR.Application.Repositories.Reports
|
||||
|
|
@ -21,6 +23,7 @@ namespace BMA.EHR.Application.Repositories.Reports
|
|||
private readonly IWebHostEnvironment _hostingEnvironment;
|
||||
private readonly MinIOService _documentService;
|
||||
private readonly OrganizationCommonRepository _organizationCommonRepository;
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
#endregion
|
||||
|
||||
|
|
@ -29,12 +32,14 @@ namespace BMA.EHR.Application.Repositories.Reports
|
|||
public RetireReportRepository(IApplicationDBContext dbContext,
|
||||
MinIOService documentService,
|
||||
OrganizationCommonRepository organizationCommonRepository,
|
||||
IWebHostEnvironment hostEnvironment)
|
||||
IWebHostEnvironment hostEnvironment,
|
||||
IConfiguration configuration)
|
||||
{
|
||||
_dbContext = dbContext;
|
||||
_hostingEnvironment = hostEnvironment;
|
||||
_organizationCommonRepository = organizationCommonRepository;
|
||||
_documentService = documentService;
|
||||
_configuration = configuration;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
@ -64,12 +69,43 @@ namespace BMA.EHR.Application.Repositories.Reports
|
|||
//}
|
||||
|
||||
#region รายงานประกาศเกษียณ
|
||||
public async Task<dynamic> GetProfileRetirementdAsync(Guid retireId)
|
||||
public async Task<dynamic> GetProfileRetirementdAsync(Guid retireId, string token)
|
||||
{
|
||||
var retire = await _dbContext.Set<RetirementPeriod>()
|
||||
.Include(x => x.RetirementProfiles)
|
||||
.FirstOrDefaultAsync(x => x.Id == retireId);
|
||||
var retires = new List<dynamic>();
|
||||
// var retires = new List<dynamic>();
|
||||
var apiUrl = $"{_configuration["API"]}/org/root/search/sort";
|
||||
dynamic rootOrder = new List<string>();
|
||||
dynamic child1Order = new List<string>();
|
||||
dynamic child2Order = new List<string>();
|
||||
dynamic child3Order = new List<string>();
|
||||
dynamic child4Order = new List<string>();
|
||||
dynamic posTypeNameOrder = new List<string>();
|
||||
dynamic posLevelNameOrder = new List<string>();
|
||||
dynamic hospital = new List<string>();
|
||||
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.Get, apiUrl);
|
||||
var _res = await client.SendAsync(_req);
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
|
||||
var org = JsonConvert.DeserializeObject<dynamic>(_result);
|
||||
|
||||
if (org != null && org.result != null)
|
||||
{
|
||||
rootOrder = org.result.root;
|
||||
child1Order = org.result.child1;
|
||||
child2Order = org.result.child2;
|
||||
child3Order = org.result.child3;
|
||||
child4Order = org.result.child4;
|
||||
posTypeNameOrder = org.result.posTypeNameOrder;
|
||||
posLevelNameOrder = org.result.posLevelNameOrder;
|
||||
hospital = org.result.hospital;
|
||||
}
|
||||
}
|
||||
if (retire == null)
|
||||
{
|
||||
var retireHistorys = await _dbContext.Set<RetirementPeriodHistory>().AsQueryable()
|
||||
|
|
@ -120,12 +156,49 @@ namespace BMA.EHR.Application.Repositories.Reports
|
|||
{
|
||||
profiles = profiles.OrderBy(x => x.order).ToList();
|
||||
}
|
||||
return new { retireHistorys.Detail, retireHistorys.Id, retireHistorys.CreatedAt, Year = retireHistorys.Year.ToThaiYear().ToString().ToThaiNumber(), retireHistorys.Round, retireHistorys.Type, retireHistorys.TypeReport, Total = retireHistorys.Total.ToString().ToThaiNumber(), profile = profiles };
|
||||
var mapProfiles = new List<ProfileRetireJsonRequest>();
|
||||
// string previousRoot = null;
|
||||
// string previousPosTypeName = null;
|
||||
// string previousPosLevelName = null;
|
||||
if (profiles.Count > 0)
|
||||
{
|
||||
mapProfiles = profiles
|
||||
// .OrderBy(x => rootOrder.ToObject<List<string>>().IndexOf(x.root))
|
||||
// .ThenBy(x => posTypeNameOrder.ToObject<List<string>>().IndexOf(x.posTypeName ?? ""))
|
||||
// .ThenBy(x => posLevelNameOrder.ToObject<List<string>>().IndexOf(x.posLevelName ?? ""))
|
||||
.Select((profile, index) =>
|
||||
{
|
||||
// bool isDuplicateRoot = profile.root == previousRoot;
|
||||
// previousRoot = profile.root;
|
||||
// bool isDuplicatePosType = profile.posTypeName == previousPosTypeName;
|
||||
// previousPosTypeName = profile.posTypeName;
|
||||
// bool isDuplicatePosLevel = profile.posLevelName == previousPosLevelName;
|
||||
// previousPosLevelName = profile.posLevelName;
|
||||
return new ProfileRetireJsonRequest
|
||||
{
|
||||
order = retireHistorys.TypeReport == null ? (index + 1).ToString().ToThaiNumber() : $"{(index + 1).ToString().ToThaiNumber()}. ลำดับที่ {(profile.order).ToString().ToThaiNumber()}",
|
||||
fullName = $"{profile.prefix}{profile.firstName} {profile.lastName}",
|
||||
root = "",
|
||||
child = (profile.posExecutiveName == null ? "" : profile.posExecutiveName + "\n") +
|
||||
(profile.child4 == null ? "" : profile.child4 + "\n") +
|
||||
(profile.child3 == null ? "" : profile.child3 + "\n") +
|
||||
(profile.child2 == null ? "" : profile.child2 + "\n") +
|
||||
(profile.child1 == null ? "" : profile.child1 + "\n") +
|
||||
(profile.reason == null ? "" : profile.reason),
|
||||
position = profile.position != "" && profile.position != null ? profile.position : "-",
|
||||
posNo = profile.posNo != "" && profile.posNo != null ? profile.posNo?.ToThaiNumber() : "-",
|
||||
reason = profile.reason != "" && profile.reason != null ? profile.reason : "-",
|
||||
};
|
||||
}).ToList();
|
||||
}
|
||||
string SignDate = retireHistorys.SignDate != null ? DateTime.Parse(retireHistorys.SignDate.ToString()).ToThaiFullDate().ToString().ToThaiNumber() : "-";
|
||||
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
|
||||
{
|
||||
var profile_retire = await _dbContext.Set<RetirementProfile>()
|
||||
.Include(x => x.RetirementPeriod)
|
||||
.Where(x => x.RetirementPeriod == retire && (retire.TypeReport == null || retire.TypeReport == x.Remove))
|
||||
.OrderBy(x => x.Order)
|
||||
.Select(x => new
|
||||
|
|
@ -134,49 +207,126 @@ namespace BMA.EHR.Application.Repositories.Reports
|
|||
id = x.Id,
|
||||
reason = x.Reason,
|
||||
remove = x.Remove,
|
||||
profileId = x.Profile.Id,
|
||||
citizenId = x.Profile.CitizenId,
|
||||
prefix = x.Profile.Prefix == null ? "" : x.Profile.Prefix.Name,
|
||||
fullName = $"{(x.Profile.Prefix == null ? null : x.Profile.Prefix.Name)}{x.Profile.FirstName} {x.Profile.LastName}",
|
||||
organizationOrganization = x.Profile.OrganizationOrganization,
|
||||
ocId = x.Profile.OcId,
|
||||
position = x.Profile.Position == null ? "-" : x.Profile.Position.Name,
|
||||
positionType = x.Profile.PositionType == null ? "-" : x.Profile.PositionType.Name,
|
||||
positionExecutive = x.Profile.PositionExecutive,
|
||||
posNo = x.Profile.PosNo == null ? "-" : x.Profile.PosNo.Name,
|
||||
positionEmployeePosition = x.Profile.PositionEmployeePosition == null ? "-" : x.Profile.PositionEmployeePosition.Name,
|
||||
positionEmployeeLevel = x.Profile.PositionEmployeeLevel == null ? "-" : x.Profile.PositionEmployeeLevel.Name,
|
||||
positionEmployeeGroup = x.Profile.PositionEmployeeGroup == null ? "-" : x.Profile.PositionEmployeeGroup.Name,
|
||||
posNoEmployee = x.Profile.PosNoEmployee,
|
||||
profileId = x.profileId,
|
||||
prefix = x.prefix,
|
||||
firstName = x.firstName,
|
||||
lastName = x.lastName,
|
||||
citizenId = x.citizenId,
|
||||
root = x.root,
|
||||
rootId = x.rootId,
|
||||
rootShortName = x.rootShortName,
|
||||
child1 = x.child1,
|
||||
child1Id = x.child1Id,
|
||||
child1ShortName = x.child1ShortName,
|
||||
child2 = x.child2,
|
||||
child2Id = x.child2Id,
|
||||
child2ShortName = x.child2ShortName,
|
||||
child3 = x.child3,
|
||||
child3Id = x.child3Id,
|
||||
child3ShortName = x.child3ShortName,
|
||||
child4 = x.child4,
|
||||
child4Id = x.child4Id,
|
||||
child4ShortName = x.child4ShortName,
|
||||
posMasterNo = x.posMasterNo,
|
||||
position = x.position,
|
||||
posTypeId = x.posTypeId,
|
||||
posTypeName = x.posTypeName,
|
||||
posTypeRank = x.posTypeRank,
|
||||
posLevelId = x.posLevelId,
|
||||
posLevelName = x.posLevelName,
|
||||
posLevelRank = x.posLevelRank,
|
||||
posExecutiveId = x.posExecutiveId,
|
||||
posExecutiveName = x.posExecutiveName,
|
||||
posNo = x.posNo,
|
||||
})
|
||||
.ToListAsync();
|
||||
foreach (var r in profile_retire)
|
||||
// foreach (var r in profile_retire)
|
||||
// {
|
||||
// var data = new ProfileJsonRequest
|
||||
// {
|
||||
// order = r.order,
|
||||
// id = r.id,
|
||||
// reason = r.reason,
|
||||
// remove = r.remove,
|
||||
// profileId = r.profileId,
|
||||
// citizenId = r.citizenId,
|
||||
// prefix = r.prefix,
|
||||
// fullName = r.fullName,
|
||||
// organizationOrganization = r.organizationOrganization,
|
||||
// oc = r.ocId == null ? null : _organizationCommonRepository.GetOrganizationNameFullPath(r.ocId.Value),
|
||||
// position = r.position,
|
||||
// positionType = r.positionType,
|
||||
// positionExecutive = r.positionExecutive,
|
||||
// posNo = r.posNo,
|
||||
// positionEmployeePosition = r.positionEmployeePosition,
|
||||
// positionEmployeeLevel = r.positionEmployeeLevel,
|
||||
// positionEmployeeGroup = r.positionEmployeeGroup,
|
||||
// posNoEmployee = r.posNoEmployee,
|
||||
// };
|
||||
// retires.Add(data);
|
||||
// }
|
||||
var mapProfiles = new List<ProfileRetireJsonRequest>();
|
||||
string previousRoot = null;
|
||||
string previousChild1 = null;
|
||||
string previousPosTypeName = null;
|
||||
string previousPosLevelName = null;
|
||||
if (profile_retire.Count > 0)
|
||||
{
|
||||
var data = new ProfileJsonRequest
|
||||
if (retire.TypeReport == null)
|
||||
{
|
||||
order = r.order,
|
||||
id = r.id,
|
||||
reason = r.reason,
|
||||
remove = r.remove,
|
||||
profileId = r.profileId,
|
||||
citizenId = r.citizenId,
|
||||
prefix = r.prefix,
|
||||
fullName = r.fullName,
|
||||
organizationOrganization = r.organizationOrganization,
|
||||
oc = r.ocId == null ? null : _organizationCommonRepository.GetOrganizationNameFullPath(r.ocId.Value),
|
||||
position = r.position,
|
||||
positionType = r.positionType,
|
||||
positionExecutive = r.positionExecutive,
|
||||
posNo = r.posNo,
|
||||
positionEmployeePosition = r.positionEmployeePosition,
|
||||
positionEmployeeLevel = r.positionEmployeeLevel,
|
||||
positionEmployeeGroup = r.positionEmployeeGroup,
|
||||
posNoEmployee = r.posNoEmployee,
|
||||
};
|
||||
retires.Add(data);
|
||||
profile_retire = profile_retire
|
||||
.OrderBy(x => string.IsNullOrEmpty(x.root) ? int.MaxValue : rootOrder.ToObject<List<string>>().IndexOf(x.root))
|
||||
.ThenBy(x => child1Order.ToObject<List<string>>().IndexOf(x.child1 ?? ""))
|
||||
.ThenBy(x => child2Order.ToObject<List<string>>().IndexOf(x.child2 ?? ""))
|
||||
.ThenBy(x => child3Order.ToObject<List<string>>().IndexOf(x.child3 ?? ""))
|
||||
.ThenBy(x => child4Order.ToObject<List<string>>().IndexOf(x.child4 ?? ""))
|
||||
.ThenBy(x => posTypeNameOrder.ToObject<List<string>>().IndexOf(x.posTypeName ?? ""))
|
||||
.ThenBy(x => posLevelNameOrder.ToObject<List<string>>().IndexOf(x.posLevelName ?? ""))
|
||||
.ThenBy(x => x.posNo).ToList();
|
||||
}
|
||||
|
||||
return new { retire.Detail, retire.Id, retire.CreatedAt, Year = retire.Year.ToThaiYear().ToString().ToThaiNumber(), retire.Round, retire.Type, retire.TypeReport, Total = profile_retire.Count.ToString().ToThaiNumber(), profile = retires };
|
||||
mapProfiles = profile_retire.Select((profile, index) =>
|
||||
{
|
||||
bool isDuplicateRoot = profile.root == previousRoot;
|
||||
previousRoot = profile.root;
|
||||
if (isDuplicateRoot == false)
|
||||
{
|
||||
previousChild1 = null;
|
||||
previousPosTypeName = null;
|
||||
previousPosLevelName = null;
|
||||
}
|
||||
bool isDuplicateHospital = profile.child1 == previousChild1;
|
||||
previousChild1 = profile.child1;
|
||||
if (isDuplicateHospital == false)
|
||||
{
|
||||
previousPosTypeName = null;
|
||||
previousPosLevelName = null;
|
||||
}
|
||||
bool isDuplicatePosType = profile.posTypeName == previousPosTypeName;
|
||||
previousPosTypeName = profile.posTypeName;
|
||||
bool isDuplicatePosLevel = profile.posLevelName == previousPosLevelName;
|
||||
previousPosLevelName = profile.posLevelName;
|
||||
return new ProfileRetireJsonRequest
|
||||
{
|
||||
order = retire.TypeReport == null ? (index + 1).ToString().ToThaiNumber() : $"{(index + 1).ToString().ToThaiNumber()}. ลำดับที่ {(profile.order).ToString().ToThaiNumber()}",
|
||||
fullName = $"{profile.prefix}{profile.firstName} {profile.lastName}",
|
||||
root = (isDuplicateRoot ? "" : profile.root + "\n") +
|
||||
(isDuplicateHospital || !hospital.ToObject<List<string>>().Contains(profile.child1) ? "" : profile.child1 + "\n") +
|
||||
(isDuplicatePosType ? "" : $"ตำแหน่งประเภท{profile.posTypeName}" + "\n") +
|
||||
(isDuplicatePosLevel ? "" : $"ระดับ{profile.posLevelName}").ToThaiNumber(),
|
||||
child = (profile.posExecutiveName == null ? "" : profile.posExecutiveName + "\n") +
|
||||
(profile.child4 == null ? "" : profile.child4 + "\n") +
|
||||
(profile.child3 == null ? "" : profile.child3 + "\n") +
|
||||
(profile.child2 == null ? "" : profile.child2 + "\n") +
|
||||
(profile.child1 == null || hospital.ToObject<List<string>>().Contains(profile.child1) ? "" : profile.child1 + "\n") +
|
||||
(profile.reason == null ? "" : profile.reason),
|
||||
position = profile.position != "" && profile.position != null ? profile.position : "-",
|
||||
posNo = profile.posNo != "" && profile.posNo != null ? profile.posNo?.ToThaiNumber() : "-",
|
||||
reason = profile.reason != "" && profile.reason != null ? profile.reason : "-",
|
||||
};
|
||||
}).ToList();
|
||||
}
|
||||
string SignDate = retire.SignDate != null ? DateTime.Parse(retire.SignDate.ToString()).ToThaiFullDate().ToString().ToThaiNumber() : "-";
|
||||
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
|
||||
|
|
@ -189,23 +339,24 @@ namespace BMA.EHR.Application.Repositories.Reports
|
|||
.Select(p => new
|
||||
{
|
||||
p.Id,
|
||||
ProfileId = p.Profile.Id,
|
||||
Prefix = p.Profile.Prefix == null ? null : p.Profile.Prefix.Name,
|
||||
PrefixId = p.Profile.Prefix == null ? Guid.Parse("00000000-0000-0000-0000-000000000000") : p.Profile.Prefix.Id,
|
||||
p.Profile.FirstName,
|
||||
p.Profile.LastName,
|
||||
Position = p.Profile.Position == null ? null : p.Profile.Position.Name,
|
||||
PositionId = p.Profile.Position == null ? Guid.Parse("00000000-0000-0000-0000-000000000000") : p.Profile.Position.Id,
|
||||
PositionType = p.Profile.PositionType == null ? null : p.Profile.PositionType.Name,
|
||||
PositionTypeId = p.Profile.PositionType == null ? Guid.Parse("00000000-0000-0000-0000-000000000000") : p.Profile.PositionType.Id,
|
||||
p.Profile.PositionLine,
|
||||
p.Profile.PositionLineId,
|
||||
PositionLevel = p.Profile.PositionLevel == null ? null : p.Profile.PositionLevel.Name,
|
||||
PositionLevelId = p.Profile.PositionLevel == null ? Guid.Parse("00000000-0000-0000-0000-000000000000") : p.Profile.PositionLevel.Id,
|
||||
p.Profile.PositionExecutive,
|
||||
p.Profile.PositionExecutiveId,
|
||||
Organization = p.Profile.Oc,
|
||||
OrganizationId = p.Profile.OcId,
|
||||
p.prefix,
|
||||
p.profileId,
|
||||
p.firstName,
|
||||
p.lastName,
|
||||
p.root,
|
||||
p.rootShortName,
|
||||
p.child1,
|
||||
p.child1ShortName,
|
||||
p.child2,
|
||||
p.child2ShortName,
|
||||
p.child3,
|
||||
p.child3ShortName,
|
||||
p.child4,
|
||||
p.child4ShortName,
|
||||
p.posMasterNo,
|
||||
p.posLevelName,
|
||||
p.posTypeName,
|
||||
p.position,
|
||||
p.Number,
|
||||
p.Date,
|
||||
p.Location,
|
||||
|
|
@ -216,32 +367,38 @@ namespace BMA.EHR.Application.Repositories.Reports
|
|||
if (data == null)
|
||||
return null;
|
||||
|
||||
string Prefix = string.IsNullOrEmpty(data.Prefix.ToString()) ? string.Empty : data.Prefix.ToString();
|
||||
string FirstName = string.IsNullOrEmpty(data.FirstName.ToString()) ? string.Empty : data.FirstName.ToString();
|
||||
string LastName = string.IsNullOrEmpty(data.LastName.ToString()) ? string.Empty : data.LastName.ToString();
|
||||
string FullName = $"{Prefix} {FirstName} {LastName}";
|
||||
string Date = string.IsNullOrEmpty(data.Date.ToString()) ? "วันที่ - เดือน - พ.ศ. -" : DateTime.Parse(data.Date.ToString()).ToThaiFullDate().ToString().ToThaiNumber();
|
||||
// string Prefix = string.IsNullOrEmpty(data.Prefix.ToString()) ? string.Empty : data.Prefix.ToString();
|
||||
// string FirstName = string.IsNullOrEmpty(data.FirstName.ToString()) ? string.Empty : data.FirstName.ToString();
|
||||
// string LastName = string.IsNullOrEmpty(data.LastName.ToString()) ? string.Empty : data.LastName.ToString();
|
||||
// string FullName = $"{Prefix} {FirstName} {LastName}";
|
||||
string Date = string.IsNullOrEmpty(data.Date.ToString()) ? "-" : DateTime.Parse(data.Date.ToString()).ToThaiFullDate().ToString().ToThaiNumber();
|
||||
string CurrentDate = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd")).ToThaiFullDate().ToString().ToThaiNumber();
|
||||
return new
|
||||
{
|
||||
FullName,
|
||||
FullName = $"{data.prefix} {data.firstName} {data.lastName}",
|
||||
Date,
|
||||
CurrentDate,
|
||||
data.Position,
|
||||
data.PositionExecutive,
|
||||
data.PositionType,
|
||||
data.PositionLine,
|
||||
data.PositionLevel,
|
||||
data.Organization,
|
||||
data.PositionId,
|
||||
data.PositionExecutiveId,
|
||||
data.PositionTypeId,
|
||||
data.PositionLineId,
|
||||
data.PositionLevelId,
|
||||
data.OrganizationId,
|
||||
data.Number,
|
||||
data.Location,
|
||||
data.profileId,
|
||||
data.prefix,
|
||||
data.firstName,
|
||||
data.lastName,
|
||||
data.root,
|
||||
data.rootShortName,
|
||||
data.child1,
|
||||
data.child1ShortName,
|
||||
data.child2,
|
||||
data.child2ShortName,
|
||||
data.child3,
|
||||
data.child3ShortName,
|
||||
data.child4,
|
||||
data.child4ShortName,
|
||||
data.posMasterNo,
|
||||
data.posLevelName,
|
||||
data.posTypeName,
|
||||
Number = data.Number != null ? data.Number.ToThaiNumber() : "-",
|
||||
Location = data.Location != null ? data.Location.ToThaiNumber() : "-",
|
||||
data.Reason,
|
||||
Position = data.position,
|
||||
};
|
||||
}
|
||||
#endregion
|
||||
|
|
@ -250,7 +407,7 @@ namespace BMA.EHR.Application.Repositories.Reports
|
|||
public async Task<dynamic> GetHeadRetirementDeceasedAsync(Guid id)
|
||||
{
|
||||
var data = await _dbContext.Set<RetirementDeceased>().AsQueryable()
|
||||
.Include(x => x.Profile)
|
||||
// .Include(x => x.Profile)
|
||||
.Where(x => x.Id == id)
|
||||
.FirstOrDefaultAsync();
|
||||
var oc = "";
|
||||
|
|
@ -264,34 +421,34 @@ namespace BMA.EHR.Application.Repositories.Reports
|
|||
Send = "หัวหน้าสำนักงาน ก.ก.",
|
||||
};
|
||||
|
||||
if (data.Profile.OcId != null)
|
||||
{
|
||||
var organization = await _dbContext.Set<OrganizationEntity>().AsQueryable()
|
||||
.Where(x => x.Id == data.Profile.OcId)
|
||||
.FirstOrDefaultAsync();
|
||||
if (organization != null)
|
||||
{
|
||||
var organizationAgency = await _dbContext.Set<OrganizationEntity>().AsQueryable()
|
||||
.Where(x => x.Id == organization.OrganizationAgencyId)
|
||||
.FirstOrDefaultAsync();
|
||||
if (organizationAgency != null)
|
||||
{
|
||||
var agency = await _dbContext.Set<OrganizationEntity>().AsQueryable()
|
||||
.Where(x => x.Id == organizationAgency.Id)
|
||||
.FirstOrDefaultAsync();
|
||||
if (agency != null)
|
||||
{
|
||||
oc = agency.OrganizationOrganization?.Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// if (data.Profile.OcId != null)
|
||||
// {
|
||||
// var organization = await _dbContext.Set<OrganizationEntity>().AsQueryable()
|
||||
// .Where(x => x.Id == data.Profile.OcId)
|
||||
// .FirstOrDefaultAsync();
|
||||
// if (organization != null)
|
||||
// {
|
||||
// var organizationAgency = await _dbContext.Set<OrganizationEntity>().AsQueryable()
|
||||
// .Where(x => x.Id == organization.OrganizationAgencyId)
|
||||
// .FirstOrDefaultAsync();
|
||||
// if (organizationAgency != null)
|
||||
// {
|
||||
// var agency = await _dbContext.Set<OrganizationEntity>().AsQueryable()
|
||||
// .Where(x => x.Id == organizationAgency.Id)
|
||||
// .FirstOrDefaultAsync();
|
||||
// if (agency != null)
|
||||
// {
|
||||
// oc = agency.OrganizationOrganization?.Name;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
return new
|
||||
{
|
||||
Oc = oc,
|
||||
Number = $"กท /{data.CreatedAt.Year.ToThaiYear()}",
|
||||
Date = data.CreatedAt.ToThaiFullDate().ToString().ToThaiNumber(),
|
||||
Number = $"กท /{(data.CreatedAt.Year.ToThaiYear()).ToString().ToThaiNumber()}",
|
||||
Date = data.CreatedAt.ToThaiFullDate2().ToString().ToThaiNumber(),
|
||||
Subject = "ข้าราชการถึงแก่กรรม",
|
||||
Send = "หัวหน้าสำนักงาน ก.ก.",
|
||||
};
|
||||
|
|
@ -302,7 +459,7 @@ namespace BMA.EHR.Application.Repositories.Reports
|
|||
public async Task UploadFileRetirementDeceasedAsync(Guid id, Domain.Models.Documents.Document file)
|
||||
{
|
||||
var data = await _dbContext.Set<RetirementDeceased>().AsQueryable()
|
||||
.Include(x => x.Profile)
|
||||
// .Include(x => x.Profile)
|
||||
.Where(x => x.Id == id)
|
||||
.FirstOrDefaultAsync();
|
||||
if (data != null)
|
||||
|
|
@ -319,15 +476,16 @@ namespace BMA.EHR.Application.Repositories.Reports
|
|||
.Select(p => new
|
||||
{
|
||||
p.Id,
|
||||
Prefix = p.Profile.Prefix == null ? null : p.Profile.Prefix.Name,
|
||||
PrefixId = p.Profile.Prefix == null ? Guid.Parse("00000000-0000-0000-0000-000000000000") : p.Profile.Prefix.Id,
|
||||
p.Profile.FirstName,
|
||||
p.Profile.LastName,
|
||||
ProfileId = p.Profile.Id,
|
||||
p.prefix,
|
||||
p.firstName,
|
||||
p.lastName,
|
||||
p.profileId,
|
||||
p.Location,
|
||||
p.SendDate,
|
||||
p.ActiveDate,
|
||||
p.Reason,
|
||||
p.ReasonResign,
|
||||
p.Remark,
|
||||
p.Status,
|
||||
salary = p.AmountOld,
|
||||
p.ApproveReason,
|
||||
|
|
@ -347,23 +505,183 @@ namespace BMA.EHR.Application.Repositories.Reports
|
|||
p.CommanderRejectReason,
|
||||
p.CommanderRejectDate,
|
||||
p.RemarkHorizontal,
|
||||
Type = "OFFICER"
|
||||
})
|
||||
.FirstOrDefaultAsync();
|
||||
if (data == null)
|
||||
data = await _dbContext.Set<RetirementResignEmployee>().AsQueryable()
|
||||
.Where(x => x.Id == id)
|
||||
.Select(p => new
|
||||
{
|
||||
p.Id,
|
||||
p.prefix,
|
||||
p.firstName,
|
||||
p.lastName,
|
||||
p.profileId,
|
||||
p.Location,
|
||||
p.SendDate,
|
||||
p.ActiveDate,
|
||||
p.Reason,
|
||||
p.ReasonResign,
|
||||
p.Remark,
|
||||
p.Status,
|
||||
salary = p.AmountOld,
|
||||
p.ApproveReason,
|
||||
p.RejectReason,
|
||||
p.IsActive,
|
||||
p.CreatedAt,
|
||||
p.PositionTypeOld,
|
||||
p.PositionLevelOld,
|
||||
p.PositionNumberOld,
|
||||
p.OrganizationPositionOld,
|
||||
p.OligarchReject,
|
||||
p.OligarchApproveReason,
|
||||
p.OligarchRejectReason,
|
||||
p.OligarchRejectDate,
|
||||
p.CommanderReject,
|
||||
p.CommanderApproveReason,
|
||||
p.CommanderRejectReason,
|
||||
p.CommanderRejectDate,
|
||||
p.RemarkHorizontal,
|
||||
Type = "EMPLOYEE",
|
||||
})
|
||||
.FirstOrDefaultAsync();
|
||||
if (data == null)
|
||||
return null;
|
||||
|
||||
var approverPositionExecutiveName = "...............";
|
||||
var approverStatus = "☐ อนุญาต";
|
||||
var approverRejectStatus = "☐ ยับยั้งการลาออกไว้จนถึงวันที่...................";
|
||||
var approver = "...................";
|
||||
var approverPosition = "...................";
|
||||
|
||||
var diffDate = "☐ ไม่น้อยกว่า ๓๐ วัน ☐ น้อยกว่า ๓๐ วัน";
|
||||
if (data.SendDate.HasValue && data.ActiveDate.HasValue)
|
||||
{
|
||||
var time = data.ActiveDate.Value - data.SendDate.Value;
|
||||
var day = time.TotalDays;
|
||||
if (day < 30)
|
||||
{
|
||||
diffDate = "☐ ไม่น้อยกว่า ๓๐ วัน ☑ น้อยกว่า ๓๐ วัน";
|
||||
}
|
||||
else
|
||||
{
|
||||
diffDate = "☑ ไม่น้อยกว่า ๓๐ วัน ☐ น้อยกว่า ๓๐ วัน";
|
||||
}
|
||||
}
|
||||
|
||||
var commanderDateUpdate = "วันที่...................";
|
||||
var commanderStatus = "☐ อนุญาต ตั้งแต่วันที่...................";
|
||||
var commanderCommentApprove = "...................";
|
||||
var commanderRejectStatus = "☐ ยับยั้งการลาออกไว้จนถึงวันที่...................";
|
||||
var commanderCommentReject = "...................";
|
||||
var commander = "...................";
|
||||
var commanderPosition = "...................";
|
||||
|
||||
if (data.Type == "OFFICER")
|
||||
{
|
||||
var Approver = _dbContext.Set<RetirementResignApprover>()
|
||||
.Where(x => x.RetirementResign.Id == data.Id && x.ApproveType == "APPROVER")
|
||||
.ToList();
|
||||
var Commander = _dbContext.Set<RetirementResignApprover>()
|
||||
.Where(x => x.RetirementResign.Id == data.Id && x.ApproveType == "COMMANDER")
|
||||
.OrderByDescending(x => x.Seq)
|
||||
.ToList();
|
||||
if (Approver.Count > 0)
|
||||
{
|
||||
approverPositionExecutiveName = Approver[0].PositionExecutiveName;
|
||||
approverStatus = Approver[0].ApproveStatus == "APPROVE" ? "☑ อนุญาต" : approverStatus;
|
||||
approverRejectStatus = Approver[0].ApproveStatus == "REJECT"
|
||||
? $"☑ ยับยั้งการลาออกไว้จนถึง{(Approver[0].RejectDate != null ? DateTime.Parse(Approver[0].RejectDate.ToString()).ToThaiFullDate().ToString().ToThaiNumber() : "วันที่...................")}"
|
||||
: approverRejectStatus;
|
||||
approver = $"{Approver[0].Prefix}{Approver[0].FirstName} {Approver[0].LastName}";
|
||||
approverPosition = Approver[0].PositionName;
|
||||
}
|
||||
if (Commander.Count > 0)
|
||||
{
|
||||
commanderDateUpdate = Commander.Count > 1
|
||||
? Commander[1].LastUpdatedAt != null
|
||||
? DateTime.Parse(Commander[1].LastUpdatedAt.ToString()).ToThaiFullDate().ToString().ToThaiNumber()
|
||||
: commanderDateUpdate
|
||||
: Commander[0].LastUpdatedAt != null
|
||||
? DateTime.Parse(Commander[0].LastUpdatedAt.ToString()).ToThaiFullDate().ToString().ToThaiNumber()
|
||||
: commanderDateUpdate;
|
||||
commanderStatus = Commander[0].ApproveStatus == "APPROVE"
|
||||
? $"☑ อนุญาต ตั้งแต่{(Commander[0].LastUpdatedAt != null ? DateTime.Parse(Commander[0].LastUpdatedAt.ToString()).ToThaiFullDate().ToString().ToThaiNumber() : "วันที่...................")}"
|
||||
: commanderStatus;
|
||||
commanderCommentApprove = Commander[0].ApproveStatus == "APPROVE"
|
||||
? !string.IsNullOrWhiteSpace(Commander[0].Comment) ? Commander[0].Comment : commanderCommentApprove
|
||||
: commanderCommentApprove;
|
||||
commanderRejectStatus = Commander[0].ApproveStatus == "REJECT"
|
||||
? $"☑ ยับยั้งการลาออกไว้จนถึง{(Commander[0].RejectDate != null ? DateTime.Parse(Commander[0].RejectDate.ToString()).ToThaiFullDate().ToString().ToThaiNumber() : "วันที่...................")}"
|
||||
: approverRejectStatus;
|
||||
commanderCommentReject = Commander[0].ApproveStatus == "REJECT"
|
||||
? !string.IsNullOrWhiteSpace(Commander[0].Comment) ? Commander[0].Comment : commanderCommentReject
|
||||
: commanderCommentReject;
|
||||
commander = $"{Commander[0].Prefix}{Commander[0].FirstName} {Commander[0].LastName}";
|
||||
commanderPosition = Commander[0].PositionName;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var EmpApproves = _dbContext.Set<RetirementResignEmployeeApprover>()
|
||||
.Where(x => x.RetirementResignEmployee.Id == data.Id && x.ApproveType == "APPROVER")
|
||||
.ToList();
|
||||
var EmpCommander = _dbContext.Set<RetirementResignEmployeeApprover>()
|
||||
.Where(x => x.RetirementResignEmployee.Id == data.Id && x.ApproveType == "COMMANDER")
|
||||
.OrderByDescending(x => x.Seq)
|
||||
.ToList();
|
||||
if (EmpApproves.Count > 0)
|
||||
{
|
||||
approverPositionExecutiveName = EmpApproves[0].PositionExecutiveName;
|
||||
approverStatus = EmpApproves[0].ApproveStatus == "APPROVE" ? "☑ อนุญาต" : approverStatus;
|
||||
approverRejectStatus = EmpApproves[0].ApproveStatus == "REJECT"
|
||||
? $"☑ ยับยั้งการลาออกไว้จนถึง{(EmpApproves[0].RejectDate != null ? DateTime.Parse(EmpApproves[0].RejectDate.ToString()).ToThaiFullDate().ToString().ToThaiNumber() : "วันที่...................")}"
|
||||
: approverRejectStatus;
|
||||
approver = $"{EmpApproves[0].Prefix}{EmpApproves[0].FirstName} {EmpApproves[0].LastName}";
|
||||
approverPosition = EmpApproves[0].PositionName;
|
||||
}
|
||||
if (EmpCommander.Count > 0)
|
||||
{
|
||||
commanderDateUpdate = EmpCommander.Count > 1
|
||||
? EmpCommander[1].LastUpdatedAt != null
|
||||
? DateTime.Parse(EmpCommander[1].LastUpdatedAt.ToString()).ToThaiFullDate().ToString().ToThaiNumber()
|
||||
: commanderDateUpdate
|
||||
: EmpCommander[0].LastUpdatedAt != null
|
||||
? DateTime.Parse(EmpCommander[0].LastUpdatedAt.ToString()).ToThaiFullDate().ToString().ToThaiNumber()
|
||||
: commanderDateUpdate;
|
||||
commanderStatus = EmpCommander[0].ApproveStatus == "APPROVE"
|
||||
? $"☑ อนุญาต ตั้งแต่{(EmpCommander[0].LastUpdatedAt != null ? DateTime.Parse(EmpCommander[0].LastUpdatedAt.ToString()).ToThaiFullDate().ToString().ToThaiNumber() : "วันที่...................")}"
|
||||
: commanderStatus;
|
||||
commanderCommentApprove = EmpCommander[0].ApproveStatus == "APPROVE"
|
||||
? !string.IsNullOrWhiteSpace(EmpCommander[0].Comment) ? EmpCommander[0].Comment : commanderCommentApprove
|
||||
: commanderCommentApprove;
|
||||
commanderRejectStatus = EmpCommander[0].ApproveStatus == "REJECT"
|
||||
? $"☑ ยับยั้งการลาออกไว้จนถึง{(EmpCommander[0].RejectDate != null ? DateTime.Parse(EmpCommander[0].RejectDate.ToString()).ToThaiFullDate().ToString().ToThaiNumber() : "วันที่...................")}"
|
||||
: approverRejectStatus;
|
||||
commanderCommentReject = EmpCommander[0].ApproveStatus == "REJECT"
|
||||
? !string.IsNullOrWhiteSpace(EmpCommander[0].Comment) ? EmpCommander[0].Comment : commanderCommentReject
|
||||
: commanderCommentReject;
|
||||
commander = $"{EmpCommander[0].Prefix}{EmpCommander[0].FirstName} {EmpCommander[0].LastName}";
|
||||
commanderPosition = EmpCommander[0].PositionName;
|
||||
}
|
||||
}
|
||||
|
||||
var _data = new
|
||||
{
|
||||
data.Id,
|
||||
data.ProfileId,
|
||||
data.Prefix,
|
||||
data.FirstName,
|
||||
data.LastName,
|
||||
data.Location,
|
||||
FullName = $"{data.Prefix}{data.FirstName} {data.LastName}",
|
||||
SendDate = string.IsNullOrEmpty(data.SendDate.ToString())? string.Empty : DateTime.Parse(data.SendDate.ToString()).ToThaiFullDate().ToString().ToThaiNumber(),
|
||||
ActiveDate = string.IsNullOrEmpty(data.ActiveDate.ToString())? string.Empty : DateTime.Parse(data.ActiveDate.ToString()).ToThaiFullDate().ToString().ToThaiNumber(),
|
||||
data.profileId,
|
||||
data.prefix,
|
||||
data.firstName,
|
||||
data.lastName,
|
||||
Location = string.IsNullOrEmpty(data.Location) ? string.Empty : data.Location.ToThaiNumber(),
|
||||
FullName = $"{data.prefix}{data.firstName} {data.lastName}",
|
||||
SendDate = string.IsNullOrEmpty(data.SendDate.ToString()) ? string.Empty : DateTime.Parse(data.SendDate.ToString()).ToThaiFullDate().ToString().ToThaiNumber(),
|
||||
ActiveDate = string.IsNullOrEmpty(data.ActiveDate.ToString()) ? string.Empty : DateTime.Parse(data.ActiveDate.ToString()).ToThaiFullDate().ToString().ToThaiNumber(),
|
||||
data.Reason,
|
||||
data.ReasonResign,
|
||||
data.Remark,
|
||||
ReasonRemark = data.Reason == "OTHER" ? string.IsNullOrEmpty(data.Remark) ? data.ReasonResign : $"{data.ReasonResign}({data.Remark})" : data.ReasonResign,
|
||||
data.Status,
|
||||
data.salary,
|
||||
data.PositionTypeOld,
|
||||
|
|
@ -383,6 +701,19 @@ namespace BMA.EHR.Application.Repositories.Reports
|
|||
data.CommanderRejectReason,
|
||||
CommanderRejectDate = string.IsNullOrEmpty(data.CommanderRejectDate.ToString()) ? string.Empty : DateTime.Parse(data.CommanderRejectDate.ToString()).ToThaiFullDate().ToString().ToThaiNumber(),
|
||||
data.RemarkHorizontal,
|
||||
dear = approverPositionExecutiveName,
|
||||
approverStatus,
|
||||
approverRejectStatus,
|
||||
approver,
|
||||
approverPosition,
|
||||
diffDate,
|
||||
commanderDateUpdate,
|
||||
commanderStatus,
|
||||
commanderCommentApprove,
|
||||
commanderRejectStatus,
|
||||
commanderCommentReject,
|
||||
commander,
|
||||
commanderPosition
|
||||
};
|
||||
|
||||
return _data;
|
||||
|
|
|
|||
|
|
@ -32,19 +32,14 @@ namespace BMA.EHR.Application.Repositories.Reports
|
|||
public async Task<dynamic> GetData1Transfer(Guid id)
|
||||
{
|
||||
var data = await _dbContext.Set<PlacementTransfer>().AsQueryable()
|
||||
.Include(x => x.Profile)
|
||||
.Where(x => x.Id == id)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
var profile = await _dbContext.Set<Profile>().AsQueryable()
|
||||
.Include(x => x.Prefix)
|
||||
.Where(x => x.Id == data.Profile.Id).FirstOrDefaultAsync();
|
||||
|
||||
var prefix = string.IsNullOrEmpty(profile.Prefix.Name) ? string.Empty : profile.Prefix.Name;
|
||||
return new
|
||||
{
|
||||
CurrentDate = DateTime.Parse(DateTime.Now.ToString("yyyy-MM")).ToThaiFullDate().ToString().ToThaiNumber().Remove(0, 15),
|
||||
Name = $"{prefix}{data.Profile.FirstName} {data.Profile.LastName}",
|
||||
//CurrentDate = DateTime.Parse(DateTime.Now.ToString("yyyy-MM")).ToThaiFullDate().ToString().ToThaiNumber().Remove(0, 15),
|
||||
CurrentDate = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd")).ToThaiFullDate2().ToString().ToThaiNumber(),
|
||||
Name = $"{data.prefix}{data.firstName} {data.lastName}",
|
||||
};
|
||||
}
|
||||
#endregion
|
||||
|
|
@ -53,20 +48,14 @@ namespace BMA.EHR.Application.Repositories.Reports
|
|||
public async Task<dynamic> GetData2Transfer(Guid id)
|
||||
{
|
||||
var data = await _dbContext.Set<PlacementTransfer>().AsQueryable()
|
||||
.Include(x => x.Profile)
|
||||
.Where(x => x.Id == id)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
var profile = await _dbContext.Set<Profile>().AsQueryable()
|
||||
.Include(x => x.Prefix)
|
||||
.Where(x => x.Id == data.Profile.Id).FirstOrDefaultAsync();
|
||||
|
||||
var prefix = string.IsNullOrEmpty(profile.Prefix.Name) ? string.Empty : profile.Prefix.Name;
|
||||
return new
|
||||
{
|
||||
CurrentDate = DateTime.Parse(DateTime.Now.ToString("yyyy-MM")).ToThaiFullDate().ToString().ToThaiNumber().Remove(0, 15),
|
||||
CurrentDate = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd")).ToThaiFullDate2().ToString().ToThaiNumber(),
|
||||
Subject = $"ข้าราชการกรุงเทพมหานครสามัญขอโอน",
|
||||
Name = $"{prefix}{data.Profile.FirstName} {data.Profile.LastName}",
|
||||
Name = $"{data.prefix}{data.firstName} {data.lastName}",
|
||||
};
|
||||
}
|
||||
#endregion
|
||||
|
|
@ -75,20 +64,14 @@ namespace BMA.EHR.Application.Repositories.Reports
|
|||
public async Task<dynamic> GetData3Transfer(Guid id)
|
||||
{
|
||||
var data = await _dbContext.Set<PlacementTransfer>().AsQueryable()
|
||||
.Include(x => x.Profile)
|
||||
.Where(x => x.Id == id)
|
||||
.FirstOrDefaultAsync();
|
||||
var profile = await _dbContext.Set<Profile>().AsQueryable()
|
||||
|
||||
.Include(x => x.Prefix)
|
||||
.Where(x => x.Id == data.Profile.Id).FirstOrDefaultAsync();
|
||||
|
||||
var prefix = string.IsNullOrEmpty(profile.Prefix.Name) ? string.Empty : profile.Prefix.Name;
|
||||
return new
|
||||
{
|
||||
CurrentDate = DateTime.Parse(DateTime.Now.ToString("yyyy-MM")).ToThaiFullDate().ToString().ToThaiNumber().Remove(0, 15),
|
||||
CurrentDate = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd")).ToThaiFullDate2().ToString().ToThaiNumber(),
|
||||
Subject = $"ข้าราชการขอโอน",
|
||||
Name = $"{prefix}{data.Profile.FirstName} {data.Profile.LastName}",
|
||||
Name = $"{data.prefix}{data.firstName} {data.lastName}",
|
||||
Location = $"สำนักงานคณะกรรมการข้าราชการกรุงเทพมหานคร ๑๗๓ ถนนดินสอ กทม. ๑๐๒๐๐",
|
||||
};
|
||||
}
|
||||
#endregion
|
||||
|
|
@ -97,25 +80,19 @@ namespace BMA.EHR.Application.Repositories.Reports
|
|||
public async Task<dynamic> GetData4Transfer(Guid id)
|
||||
{
|
||||
var data = await _dbContext.Set<PlacementTransfer>().AsQueryable()
|
||||
.Include(x => x.Profile)
|
||||
.Where(x => x.Id == id)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
var profile = await _dbContext.Set<Profile>().AsQueryable()
|
||||
.Include(x => x.Prefix)
|
||||
.Where(x => x.Id == data.Profile.Id).FirstOrDefaultAsync();
|
||||
|
||||
var prefix = string.IsNullOrEmpty(profile.Prefix.Name) ? string.Empty : profile.Prefix.Name;
|
||||
return new
|
||||
{
|
||||
CurrentDate = DateTime.Parse(DateTime.Now.ToString("yyyy-MM")).ToThaiFullDate().ToString().ToThaiNumber().Remove(0, 15),
|
||||
CurrentDate = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd")).ToThaiFullDate2().ToString().ToThaiNumber(),
|
||||
Subject = $"ข้าราชการกรุงเทพมหานครสามัญขอโอน",
|
||||
Subject2 = $"ตรวจสอบหนี้สิน และภาระผูกพันกับกรุงเทพมหานครของข้าราชการ",
|
||||
Subject3 = $"ตรวจสอบหนี้สินและภาระผูกพันของข้าราชการ",
|
||||
Location = $"สำนักงานคณะกรรมการข้าราชการกรุงเทพมหานคร 173 ถนนดินสอ กทม. 10200",
|
||||
Name = $"{prefix}{data.Profile.FirstName} {data.Profile.LastName}",
|
||||
Position = $"{data.Profile.Position}",
|
||||
OrganizationOrganization = $"{data.Profile.OrganizationOrganization}",
|
||||
Location = $"สำนักงานคณะกรรมการข้าราชการกรุงเทพมหานคร ๑๗๓ ถนนดินสอ กทม. ๑๐๒๐๐",
|
||||
Name = $"{data.prefix}{data.firstName} {data.lastName}",
|
||||
Position = $"{data.PositionOld}",
|
||||
OrganizationOrganization = $"{data.Organization}",
|
||||
};
|
||||
}
|
||||
#endregion
|
||||
|
|
@ -124,25 +101,19 @@ namespace BMA.EHR.Application.Repositories.Reports
|
|||
public async Task<dynamic> GetData5Transfer(Guid id)
|
||||
{
|
||||
var data = await _dbContext.Set<PlacementTransfer>().AsQueryable()
|
||||
.Include(x => x.Profile)
|
||||
.Where(x => x.Id == id)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
var profile = await _dbContext.Set<Profile>().AsQueryable()
|
||||
.Include(x => x.Prefix)
|
||||
.Where(x => x.Id == data.Profile.Id).FirstOrDefaultAsync();
|
||||
|
||||
var prefix = string.IsNullOrEmpty(profile.Prefix.Name) ? string.Empty : profile.Prefix.Name;
|
||||
return new
|
||||
{
|
||||
CurrentDate = DateTime.Parse(DateTime.Now.ToString("yyyy-MM")).ToThaiFullDate().ToString().ToThaiNumber().Remove(0, 15),
|
||||
CurrentDate = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd")).ToThaiFullDate2().ToString().ToThaiNumber(),
|
||||
Subject = $"ข้าราชการกรุงเทพมหานครสามัญขอโอน",
|
||||
Subject2 = $"ตรวจสอบพฤติการณ์ทางวินัย และภาระหนี้สิน (เงินกู้สวัสดิการข้าราชการ) ของข้าราชการ",
|
||||
Subject3 = $"ตรวจสอบภาระผูกพันกับกรุงเทพมหานครเกี่ยวกับการลาศึกษา อบรม ของข้าราชการ",
|
||||
Location = $"สำนักงานคณะกรรมการข้าราชการกรุงเทพมหานคร 173 ถนนดินสอ กทม. 10200",
|
||||
Name = $"{prefix}{data.Profile.FirstName} {data.Profile.LastName}",
|
||||
Position = $"{data.Profile.Position}",
|
||||
OrganizationOrganization = $"{data.Profile.OrganizationOrganization}",
|
||||
Location = $"สำนักงานคณะกรรมการข้าราชการกรุงเทพมหานคร ๑๗๓ ถนนดินสอ กทม. ๑๐๒๐๐",
|
||||
Name = $"{data.prefix}{data.firstName} {data.lastName}",
|
||||
Position = $"{data.PositionOld}",
|
||||
OrganizationOrganization = $"{data.Organization}",
|
||||
};
|
||||
}
|
||||
#endregion
|
||||
|
|
@ -151,27 +122,21 @@ namespace BMA.EHR.Application.Repositories.Reports
|
|||
public async Task<dynamic> GetData6Transfer(Guid id)
|
||||
{
|
||||
var data = await _dbContext.Set<PlacementTransfer>().AsQueryable()
|
||||
.Include(x => x.Profile)
|
||||
.Where(x => x.Id == id)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
var profile = await _dbContext.Set<Profile>().AsQueryable()
|
||||
.Include(x => x.Prefix)
|
||||
.Where(x => x.Id == data.Profile.Id).FirstOrDefaultAsync();
|
||||
|
||||
var prefix = string.IsNullOrEmpty(profile.Prefix.Name) ? string.Empty : profile.Prefix.Name;
|
||||
return new
|
||||
{
|
||||
CurrentDate = DateTime.Parse(DateTime.Now.ToString("yyyy-MM")).ToThaiFullDate().ToString().ToThaiNumber().Remove(0, 15),
|
||||
CurrentDate = DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd")).ToThaiFullDate2().ToString().ToThaiNumber(),
|
||||
Subject = $"ข้าราชการกรุงเทพมหานครสามัญขอโอน",
|
||||
Subject2 = $"ตรวจสอบพฤติการณ์ทางวินัย และภาระหนี้สิน (เงินกู้สวัสดิการข้าราชการ) ของข้าราชการ",
|
||||
Subject3 = $"ตรวจสอบภาระผูกพันกับกรุงเทพมหานครเกี่ยวกับการลาศึกษา อบรม ของข้าราชการ",
|
||||
Subject4 = $"ตรวจสอบหนี้สิน และภาระผูกพันกับกรุงเทพมหานครของข้าราชการ",
|
||||
Subject5 = $"ตรวจสอบหนี้สินและภาระผูกพันของข้าราชการ",
|
||||
Location = $"สำนักงานคณะกรรมการข้าราชการกรุงเทพมหานคร 173 ถนนดินสอ กทม. 10200",
|
||||
Name = $"{prefix}{data.Profile.FirstName} {data.Profile.LastName}",
|
||||
Position = $"{data.Profile.Position}",
|
||||
OrganizationOrganization = $"{data.Profile.OrganizationOrganization}",
|
||||
Location = $"สำนักงานคณะกรรมการข้าราชการกรุงเทพมหานคร ๑๗๓ ถนนดินสอ กทม. ๑๐๒๐๐",
|
||||
Name = $"{data.prefix}{data.firstName} {data.lastName}",
|
||||
Position = $"{data.PositionOld}",
|
||||
OrganizationOrganization = $"{data.Organization}",
|
||||
};
|
||||
}
|
||||
#endregion
|
||||
|
|
|
|||
1027
BMA.EHR.Application/Repositories/RetirementEmployeeRepository.cs
Normal file
1027
BMA.EHR.Application/Repositories/RetirementEmployeeRepository.cs
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -1,8 +1,16 @@
|
|||
using BMA.EHR.Application.Common.Interfaces;
|
||||
using BMA.EHR.Application.Repositories.MessageQueue;
|
||||
using BMA.EHR.Domain.Models.Notifications;
|
||||
using BMA.EHR.Domain.Models.Retirement;
|
||||
using BMA.EHR.Domain.Shared;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Newtonsoft.Json;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Net.Http.Json;
|
||||
using System.Security.Claims;
|
||||
using System.Text;
|
||||
|
||||
namespace BMA.EHR.Application.Repositories
|
||||
{
|
||||
|
|
@ -11,15 +19,28 @@ namespace BMA.EHR.Application.Repositories
|
|||
private readonly IApplicationDBContext _dbContext;
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
private readonly NotificationRepository _repositoryNoti;
|
||||
private readonly IConfiguration _configuration;
|
||||
private readonly string URL = string.Empty;
|
||||
public RetirementRepository(IApplicationDBContext dbContext,
|
||||
NotificationRepository repositoryNoti,
|
||||
IHttpContextAccessor httpContextAccessor) : base(dbContext, httpContextAccessor)
|
||||
IHttpContextAccessor httpContextAccessor,
|
||||
UserProfileRepository userProfileRepository,
|
||||
IConfiguration configuration) : base(dbContext, httpContextAccessor)
|
||||
{
|
||||
_dbContext = dbContext;
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
_repositoryNoti = repositoryNoti;
|
||||
_configuration = configuration;
|
||||
URL = _configuration["VITE_URL_MGT"];
|
||||
}
|
||||
|
||||
#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"];
|
||||
|
||||
#endregion
|
||||
|
||||
//ปลดออก
|
||||
public async Task NotifyDischarge()
|
||||
{
|
||||
|
|
@ -34,11 +55,6 @@ namespace BMA.EHR.Application.Repositories
|
|||
cronjobNoti.Profile.IsLeave = true;
|
||||
cronjobNoti.Profile.LeaveReason = "DISCHARGE";
|
||||
cronjobNoti.Profile.LeaveDate = DateTime.Now;
|
||||
// await _repositoryNoti.PushNotificationAsync(
|
||||
// Guid.Parse("08db721d-ada0-4e64-89d3-7584a893d8b8"),
|
||||
// $"แจ้งเตือนการปลดออกของ {cronjobNoti.Profile.Prefix?.Name}{cronjobNoti.Profile.FirstName} {cronjobNoti.Profile.LastName}",
|
||||
// $"แจ้งเตือนการปลดออกของ {cronjobNoti.Profile.Prefix?.Name}{cronjobNoti.Profile.FirstName} {cronjobNoti.Profile.LastName}"
|
||||
// );
|
||||
}
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
|
|
@ -57,11 +73,6 @@ namespace BMA.EHR.Application.Repositories
|
|||
cronjobNoti.Profile.IsLeave = true;
|
||||
cronjobNoti.Profile.LeaveReason = "DISMISS";
|
||||
cronjobNoti.Profile.LeaveDate = DateTime.Now;
|
||||
// await _repositoryNoti.PushNotificationAsync(
|
||||
// Guid.Parse("08db721d-ada0-4e64-89d3-7584a893d8b8"),
|
||||
// $"แจ้งเตือนการปลดออกของ {cronjobNoti.Profile.Prefix?.Name}{cronjobNoti.Profile.FirstName} {cronjobNoti.Profile.LastName}",
|
||||
// $"แจ้งเตือนการปลดออกของ {cronjobNoti.Profile.Prefix?.Name}{cronjobNoti.Profile.FirstName} {cronjobNoti.Profile.LastName}"
|
||||
// );
|
||||
}
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
|
|
@ -70,23 +81,844 @@ namespace BMA.EHR.Application.Repositories
|
|||
public async Task NotifyOut()
|
||||
{
|
||||
var cronjobNotis = await _dbContext.Set<RetirementOut>()
|
||||
.Include(x => x.Profile)
|
||||
.ThenInclude(x => x.Prefix)
|
||||
//.Include(x => x.Profile)
|
||||
//.ThenInclude(x => x.Prefix)
|
||||
.Where(x => x.Date != null && x.Date.Value.Date == DateTime.Now.Date)
|
||||
.AsQueryable()
|
||||
.ToListAsync();
|
||||
foreach (var cronjobNoti in cronjobNotis)
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public void TestMethod()
|
||||
{
|
||||
cronjobNoti.Profile.IsLeave = true;
|
||||
cronjobNoti.Profile.LeaveReason = "LAYOFF";
|
||||
cronjobNoti.Profile.LeaveDate = DateTime.Now;
|
||||
// await _repositoryNoti.PushNotificationAsync(
|
||||
// Guid.Parse("08db721d-ada0-4e64-89d3-7584a893d8b8"),
|
||||
// $"แจ้งเตือนการปลดออกของ {cronjobNoti.Profile.Prefix?.Name}{cronjobNoti.Profile.FirstName} {cronjobNoti.Profile.LastName}",
|
||||
// $"แจ้งเตือนการปลดออกของ {cronjobNoti.Profile.Prefix?.Name}{cronjobNoti.Profile.FirstName} {cronjobNoti.Profile.LastName}"
|
||||
// );
|
||||
return;
|
||||
}
|
||||
public async Task<RetirementResign?> GetByIdAsync(Guid id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var data = await _dbContext.Set<RetirementResign>().AsQueryable()
|
||||
.Include(x => x.Approvers)
|
||||
.FirstOrDefaultAsync(x => x.Id == id);
|
||||
|
||||
return data;
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
}
|
||||
public async Task OfficerApproveRetirementResign(Guid id)
|
||||
{
|
||||
var rawData = await GetByIdAsync(id);
|
||||
if (rawData == null)
|
||||
{
|
||||
throw new Exception(GlobalMessages.DataNotFound);
|
||||
}
|
||||
|
||||
rawData.Status = "PENDING";
|
||||
if (rawData.ApproveStep == "st1")
|
||||
{
|
||||
rawData.ApproveStep = "st2";
|
||||
}
|
||||
else if (rawData.ApproveStep == "st3")
|
||||
{
|
||||
rawData.ApproveStep = "st4";
|
||||
// TODO: Send notification to 1st Approver
|
||||
var _firstCommander = rawData.Approvers
|
||||
.Where(x => x.ApproveType!.ToUpper() == "APPROVER")
|
||||
.OrderBy(x => x.Seq)
|
||||
.FirstOrDefault();
|
||||
// Send Notification
|
||||
var _noti1 = new Notification
|
||||
{
|
||||
Body = $"การขอลาออกของคุณ {rawData.firstName} {rawData.lastName} รอรับการอนุมัติจากคุณ",
|
||||
ReceiverUserId = _firstCommander!.ProfileId,
|
||||
Type = "",
|
||||
Payload = $"{URL}/retirement/resign-detail/{id}",
|
||||
};
|
||||
_dbContext.Set<Notification>().Add(_noti1);
|
||||
}
|
||||
|
||||
// TODO: Send notification to 1st Commander
|
||||
var firstCommander = rawData.Approvers
|
||||
.Where(x => x.ApproveType!.ToUpper() == "COMMANDER")
|
||||
.OrderBy(x => x.Seq)
|
||||
.FirstOrDefault();
|
||||
// Send Notification
|
||||
var noti1 = new Notification
|
||||
{
|
||||
Body = $"การขอลาออกของคุณ {rawData.firstName} {rawData.lastName} รอรับการอนุมัติจากคุณ",
|
||||
ReceiverUserId = firstCommander!.ProfileId,
|
||||
Type = "",
|
||||
Payload = $"{URL}/retirement/resign-detail/{id}",
|
||||
};
|
||||
_dbContext.Set<Notification>().Add(noti1);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task CommanderApproveRetirementResign(Guid id, string reason, DateTime? date)
|
||||
{
|
||||
// Get UserId from token
|
||||
var userId = UserId == null ? Guid.Empty : Guid.Parse(UserId);
|
||||
|
||||
|
||||
var rawData = await GetByIdAsync(id);
|
||||
if (rawData == null)
|
||||
{
|
||||
throw new Exception(GlobalMessages.DataNotFound);
|
||||
}
|
||||
|
||||
// if (rawData.ApproveStep != "st2")
|
||||
// {
|
||||
// throw new Exception("คำขอนี้ยังไม่ได้อยู่ในขั้นตอนที่สามารถอนุมัติได้ ไม่สามารถทำรายการได้");
|
||||
// }
|
||||
|
||||
var approvers = rawData.Approvers.Where(x => x.ApproveType!.ToUpper() == "COMMANDER").OrderBy(x => x.Seq).ToList();
|
||||
|
||||
var approver = approvers.FirstOrDefault(x => x.KeycloakId == userId);
|
||||
if (approver == null)
|
||||
{
|
||||
throw new Exception("คุณไม่มีสิทธิ์อนุมัติการลาออกในขั้นตอนนี้");
|
||||
}
|
||||
|
||||
// check prev approver มี action แล้วหรือไม่?
|
||||
var prevApprover = approvers.FirstOrDefault(x => x.Seq == approver.Seq - 1);
|
||||
|
||||
if (prevApprover != null)
|
||||
{
|
||||
if (prevApprover.ApproveStatus == "PENDING")
|
||||
{
|
||||
throw new Exception("ไม่สามารถทำการอนุมัติได้ เนื่องจากยังอยู่ระหว่างการพิจารณาโดยผู้บังคับบัญชารายก่อนหน้า");
|
||||
}
|
||||
}
|
||||
|
||||
var maxSeq = approvers.Max(x => x.Seq);
|
||||
|
||||
approver.ApproveStatus = "APPROVE";
|
||||
approver.Comment = reason;
|
||||
approver.RejectDate = date;
|
||||
|
||||
if (approver.Seq != maxSeq)
|
||||
{
|
||||
rawData.Status = "PENDING";
|
||||
|
||||
var nextApprover = approvers.FirstOrDefault(x => x.Seq == approver.Seq + 1);
|
||||
|
||||
// Send Noti
|
||||
var noti = new Notification
|
||||
{
|
||||
Body = $"การขอลาออกของคุณ {rawData.firstName} {rawData.lastName} รอรับการอนุมัติจากคุณ",
|
||||
ReceiverUserId = nextApprover!.ProfileId,
|
||||
Type = "",
|
||||
Payload = $"{URL}/retirement/resign-detail/{id}",
|
||||
};
|
||||
_dbContext.Set<Notification>().Add(noti);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
rawData.Status = "PENDING";
|
||||
rawData.ApproveStep = "st3";
|
||||
|
||||
if (rawData.Group == "1.1")
|
||||
{
|
||||
// TODO: Send notification to 1st Approver
|
||||
var firstCommander = rawData.Approvers
|
||||
.Where(x => x.ApproveType!.ToUpper() == "APPROVER")
|
||||
.OrderBy(x => x.Seq)
|
||||
.FirstOrDefault();
|
||||
|
||||
// Send Notification
|
||||
var noti1 = new Notification
|
||||
{
|
||||
Body = $"การขอลาออกของคุณ {rawData.firstName} {rawData.lastName} รอรับการอนุมัติจากคุณ",
|
||||
ReceiverUserId = firstCommander!.ProfileId,
|
||||
Type = "",
|
||||
Payload = $"{URL}/retirement/resign-detail/{id}",
|
||||
};
|
||||
_dbContext.Set<Notification>().Add(noti1);
|
||||
}
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task CommanderRejectRetirementResign(Guid id, string reason, DateTime? date)
|
||||
{
|
||||
// Get UserId from token
|
||||
var userId = UserId == null ? Guid.Empty : Guid.Parse(UserId);
|
||||
|
||||
|
||||
var rawData = await GetByIdAsync(id);
|
||||
if (rawData == null)
|
||||
{
|
||||
throw new Exception(GlobalMessages.DataNotFound);
|
||||
}
|
||||
|
||||
// if (rawData.ApproveStep != "st2")
|
||||
// {
|
||||
// throw new Exception("คำขอนี้ยังไม่ได้อยู่ในขั้นตอนที่สามารถอนุมัติได้ ไม่สามารถทำรายการได้");
|
||||
// }
|
||||
|
||||
// check commander approve
|
||||
var approvers = rawData.Approvers.Where(x => x.ApproveType!.ToUpper() == "COMMANDER").OrderBy(x => x.Seq).ToList();
|
||||
|
||||
var approver = approvers.FirstOrDefault(x => x.KeycloakId == userId);
|
||||
if (approver == null)
|
||||
{
|
||||
throw new Exception("คุณไม่มีสิทธิ์อนุมัติการลาออกในขั้นตอนนี้");
|
||||
}
|
||||
|
||||
// check prev approver มี action แล้วหรือไม่?
|
||||
var prevApprover = approvers.FirstOrDefault(x => x.Seq == approver.Seq - 1);
|
||||
|
||||
if (prevApprover != null)
|
||||
{
|
||||
if (prevApprover.ApproveStatus == "PENDING")
|
||||
{
|
||||
throw new Exception("ไม่สามารถทำการอนุมัติได้ เนื่องจากยังอยู่ระหว่างการพิจารณาโดยผู้บังคับบัญชารายก่อนหน้า");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var maxSeq = approvers.Max(x => x.Seq);
|
||||
|
||||
approver.ApproveStatus = "REJECT";
|
||||
approver.Comment = reason;
|
||||
approver.RejectDate = date;
|
||||
|
||||
if (approver.Seq != maxSeq)
|
||||
{
|
||||
|
||||
|
||||
var nextApprover = approvers.FirstOrDefault(x => x.Seq == approver.Seq + 1);
|
||||
// Send Noti
|
||||
var noti = new Notification
|
||||
{
|
||||
Body = $"การขอลาออกของคุณ {rawData.firstName} {rawData.lastName} รอรับการอนุมัติจากคุณ",
|
||||
ReceiverUserId = nextApprover!.ProfileId,
|
||||
Type = "",
|
||||
Payload = $"{URL}/retirement/resign-detail/{id}",
|
||||
};
|
||||
_dbContext.Set<Notification>().Add(noti);
|
||||
|
||||
rawData.Status = "PENDING";
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
rawData.Status = "PENDING";
|
||||
// rawData.LeaveComment = reason;
|
||||
// if (rawData.Group != "1.1")
|
||||
// {
|
||||
rawData.ApproveStep = "st3";
|
||||
// }
|
||||
|
||||
if (rawData.Group == "1.1")
|
||||
{
|
||||
// TODO: Send notification to 1st Approver
|
||||
var firstCommander = rawData.Approvers
|
||||
.Where(x => x.ApproveType!.ToUpper() == "APPROVER")
|
||||
.OrderBy(x => x.Seq)
|
||||
.FirstOrDefault();
|
||||
// Send Notification
|
||||
var noti1 = new Notification
|
||||
{
|
||||
Body = $"การขอลาออกของคุณ {rawData.firstName} {rawData.lastName} รอรับการอนุมัติจากคุณ",
|
||||
ReceiverUserId = firstCommander!.ProfileId,
|
||||
Type = "",
|
||||
Payload = $"{URL}/retirement/resign-detail/{id}",
|
||||
};
|
||||
_dbContext.Set<Notification>().Add(noti1);
|
||||
}
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public async Task ApproveRetirementResign(Guid id, string reason, DateTime? date)
|
||||
{
|
||||
// Get UserId from token
|
||||
var userId = UserId == null ? Guid.Empty : Guid.Parse(UserId);
|
||||
|
||||
var rawData = await GetByIdAsync(id);
|
||||
if (rawData == null)
|
||||
{
|
||||
throw new Exception(GlobalMessages.DataNotFound);
|
||||
}
|
||||
|
||||
// if (rawData.ApproveStep != "st3")
|
||||
// {
|
||||
// throw new Exception("คำขอนี้ยังไม่ได้อยู่ในขั้นตอนที่สามารถอนุมัติได้ ไม่สามารถทำรายการได้");
|
||||
// }
|
||||
|
||||
// check commander approve
|
||||
var approvers = rawData.Approvers.Where(x => x.ApproveType!.ToUpper() == "APPROVER").OrderBy(x => x.Seq).ToList();
|
||||
|
||||
var approver = approvers.FirstOrDefault(x => x.KeycloakId == userId);
|
||||
if (approver == null)
|
||||
{
|
||||
throw new Exception("คุณไม่มีสิทธิ์อนุมัติการลาออกในขั้นตอนนี้");
|
||||
}
|
||||
|
||||
// check prev approver มี action แล้วหรือไม่?
|
||||
var prevApprover = approvers.FirstOrDefault(x => x.Seq == approver.Seq - 1);
|
||||
|
||||
if (prevApprover != null)
|
||||
{
|
||||
if (prevApprover.ApproveStatus == "PENDING")
|
||||
{
|
||||
throw new Exception("ไม่สามารถทำการอนุมัติได้ เนื่องจากยังอยู่ระหว่างการพิจารณาโดยผู้บังคับบัญชารายก่อนหน้า");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var maxSeq = approvers.Max(x => x.Seq);
|
||||
|
||||
approver.ApproveStatus = "APPROVE";
|
||||
approver.Comment = reason;
|
||||
approver.RejectDate = date;
|
||||
|
||||
if (approver.Seq != maxSeq)
|
||||
{
|
||||
var nextApprover = approvers.FirstOrDefault(x => x.Seq == approver.Seq + 1);
|
||||
// Send Noti
|
||||
var noti1 = new Notification
|
||||
{
|
||||
Body = $"การขอลาออกของคุณ {rawData.firstName} {rawData.lastName} รอรับการอนุมัติจากคุณ",
|
||||
ReceiverUserId = nextApprover!.ProfileId,
|
||||
Type = "",
|
||||
Payload = "",
|
||||
};
|
||||
_dbContext.Set<Notification>().Add(noti1);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
rawData.Status = "APPROVE";
|
||||
// rawData.LeaveDirectorComment = reason;
|
||||
if (rawData.Group != "1.1")
|
||||
{
|
||||
rawData.ApproveStep = "st5";
|
||||
}
|
||||
else
|
||||
{
|
||||
rawData.ApproveStep = "st4";
|
||||
}
|
||||
|
||||
if (rawData.profileId != null)
|
||||
{
|
||||
// Send Noti
|
||||
var noti = new Notification
|
||||
{
|
||||
Body = $"การขอลาออกของคุณได้รับการอนุมัติ",
|
||||
ReceiverUserId = Guid.Parse(rawData.profileId),
|
||||
Type = "",
|
||||
Payload = "",
|
||||
};
|
||||
_dbContext.Set<Notification>().Add(noti);
|
||||
}
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public async Task RejectRetirementResign(Guid id, string reason, DateTime? date)
|
||||
{
|
||||
// Get UserId from token
|
||||
var userId = UserId == null ? Guid.Empty : Guid.Parse(UserId);
|
||||
|
||||
var rawData = await GetByIdAsync(id);
|
||||
if (rawData == null)
|
||||
{
|
||||
throw new Exception(GlobalMessages.DataNotFound);
|
||||
}
|
||||
|
||||
// if (rawData.ApproveStep != "st3")
|
||||
// {
|
||||
// throw new Exception("คำขอนี้ยังไม่ได้อยู่ในขั้นตอนที่สามารถอนุมัติได้ ไม่สามารถทำรายการได้");
|
||||
// }
|
||||
|
||||
// check commander approve
|
||||
var approvers = rawData.Approvers.Where(x => x.ApproveType!.ToUpper() == "APPROVER").OrderBy(x => x.Seq).ToList();
|
||||
|
||||
var approver = approvers.FirstOrDefault(x => x.KeycloakId == userId);
|
||||
if (approver == null)
|
||||
{
|
||||
throw new Exception("คุณไม่มีสิทธิ์อนุมัติการลาออกในขั้นตอนนี้");
|
||||
}
|
||||
|
||||
// check prev approver มี action แล้วหรือไม่?
|
||||
var prevApprover = approvers.FirstOrDefault(x => x.Seq == approver.Seq - 1);
|
||||
|
||||
if (prevApprover != null)
|
||||
{
|
||||
if (prevApprover.ApproveStatus == "PENDING")
|
||||
{
|
||||
throw new Exception("ไม่สามารถทำการอนุมัติได้ เนื่องจากยังอยู่ระหว่างการพิจารณาโดยผู้บังคับบัญชารายก่อนหน้า");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var maxSeq = approvers.Max(x => x.Seq);
|
||||
|
||||
approver.ApproveStatus = "REJECT";
|
||||
approver.Comment = reason;
|
||||
approver.RejectDate = date;
|
||||
|
||||
if (approver.Seq != maxSeq)
|
||||
{
|
||||
var nextApprover = approvers.FirstOrDefault(x => x.Seq == approver.Seq + 1);
|
||||
// Send Noti
|
||||
var noti1 = new Notification
|
||||
{
|
||||
Body = $"การขอลาออกของคุณ {rawData.firstName} {rawData.lastName} รอรับการอนุมัติจากคุณ",
|
||||
ReceiverUserId = nextApprover!.ProfileId,
|
||||
Type = "",
|
||||
Payload = "",
|
||||
};
|
||||
_dbContext.Set<Notification>().Add(noti1);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
rawData.Status = "REJECT";
|
||||
if (rawData.Group != "1.1")
|
||||
{
|
||||
rawData.ApproveStep = "st5";
|
||||
}
|
||||
else
|
||||
{
|
||||
rawData.ApproveStep = "st4";
|
||||
}
|
||||
|
||||
// Send Noti
|
||||
var noti = new Notification
|
||||
{
|
||||
Body = $"การขอลาออกของคุณไม่ได้รับการอนุมัติ \r\nเนื่องจาก{reason}",
|
||||
ReceiverUserId = Guid.Parse(rawData.profileId),
|
||||
Type = "",
|
||||
Payload = "",
|
||||
};
|
||||
_dbContext.Set<Notification>().Add(noti);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public async Task<RetirementResignCancel?> GetByIdCancelAsync(Guid id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var data = await _dbContext.Set<RetirementResignCancel>().AsQueryable()
|
||||
.Include(x => x.Approvers)
|
||||
.FirstOrDefaultAsync(x => x.Id == id);
|
||||
|
||||
return data;
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
}
|
||||
public async Task OfficerApproveRetirementResignCancel(Guid id)
|
||||
{
|
||||
var rawData = await GetByIdCancelAsync(id);
|
||||
if (rawData == null)
|
||||
{
|
||||
throw new Exception(GlobalMessages.DataNotFound);
|
||||
}
|
||||
|
||||
rawData.Status = "PENDING";
|
||||
if (rawData.ApproveStep == "st1")
|
||||
{
|
||||
rawData.ApproveStep = "st2";
|
||||
}
|
||||
else if (rawData.ApproveStep == "st3")
|
||||
{
|
||||
rawData.ApproveStep = "st4";
|
||||
// TODO: Send notification to 1st Approver
|
||||
var _firstCommander = rawData.Approvers
|
||||
.Where(x => x.ApproveType!.ToUpper() == "APPROVER")
|
||||
.OrderBy(x => x.Seq)
|
||||
.FirstOrDefault();
|
||||
// Send Notification
|
||||
var _noti1 = new Notification
|
||||
{
|
||||
Body = $"การขอยกเลิกลาออกของคุณ {rawData.firstName} {rawData.lastName} รอรับการอนุมัติจากคุณ",
|
||||
ReceiverUserId = _firstCommander!.ProfileId,
|
||||
Type = "",
|
||||
Payload = $"{URL}/retirement/resign-detail-reject/{rawData.Id}",
|
||||
};
|
||||
_dbContext.Set<Notification>().Add(_noti1);
|
||||
}
|
||||
|
||||
// TODO: Send notification to 1st Commander
|
||||
var firstCommander = rawData.Approvers
|
||||
.Where(x => x.ApproveType!.ToUpper() == "COMMANDER")
|
||||
.OrderBy(x => x.Seq)
|
||||
.FirstOrDefault();
|
||||
// Send Notification
|
||||
var noti1 = new Notification
|
||||
{
|
||||
Body = $"การขอยกเลิกลาออกของคุณ {rawData.firstName} {rawData.lastName} รอรับการอนุมัติจากคุณ",
|
||||
ReceiverUserId = firstCommander!.ProfileId,
|
||||
Type = "",
|
||||
Payload = $"{URL}/retirement/resign-detail-reject/{rawData.Id}",
|
||||
};
|
||||
_dbContext.Set<Notification>().Add(noti1);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task CommanderApproveRetirementResignCancel(Guid id, string reason, DateTime? date)
|
||||
{
|
||||
// Get UserId from token
|
||||
var userId = UserId == null ? Guid.Empty : Guid.Parse(UserId);
|
||||
|
||||
|
||||
var rawData = await GetByIdCancelAsync(id);
|
||||
if (rawData == null)
|
||||
{
|
||||
throw new Exception(GlobalMessages.DataNotFound);
|
||||
}
|
||||
|
||||
// if (rawData.ApproveStep != "st2")
|
||||
// {
|
||||
// throw new Exception("คำขอนี้ยังไม่ได้อยู่ในขั้นตอนที่สามารถอนุมัติได้ ไม่สามารถทำรายการได้");
|
||||
// }
|
||||
|
||||
var approvers = rawData.Approvers.Where(x => x.ApproveType!.ToUpper() == "COMMANDER").OrderBy(x => x.Seq).ToList();
|
||||
|
||||
var approver = approvers.FirstOrDefault(x => x.KeycloakId == userId);
|
||||
if (approver == null)
|
||||
{
|
||||
throw new Exception("คุณไม่มีสิทธิ์อนุมัติการลาออกในขั้นตอนนี้");
|
||||
}
|
||||
|
||||
// check prev approver มี action แล้วหรือไม่?
|
||||
var prevApprover = approvers.FirstOrDefault(x => x.Seq == approver.Seq - 1);
|
||||
|
||||
if (prevApprover != null)
|
||||
{
|
||||
if (prevApprover.ApproveStatus == "PENDING")
|
||||
{
|
||||
throw new Exception("ไม่สามารถทำการอนุมัติได้ เนื่องจากยังอยู่ระหว่างการพิจารณาโดยผู้บังคับบัญชารายก่อนหน้า");
|
||||
}
|
||||
}
|
||||
|
||||
var maxSeq = approvers.Max(x => x.Seq);
|
||||
|
||||
approver.ApproveStatus = "APPROVE";
|
||||
approver.Comment = reason;
|
||||
approver.RejectDate = date;
|
||||
|
||||
if (approver.Seq != maxSeq)
|
||||
{
|
||||
rawData.Status = "PENDING";
|
||||
|
||||
var nextApprover = approvers.FirstOrDefault(x => x.Seq == approver.Seq + 1);
|
||||
|
||||
// Send Noti
|
||||
var noti = new Notification
|
||||
{
|
||||
Body = $"การขอยกเลิกลาออกของคุณ {rawData.firstName} {rawData.lastName} รอรับการอนุมัติจากคุณ",
|
||||
ReceiverUserId = nextApprover!.ProfileId,
|
||||
Type = "",
|
||||
Payload = $"{URL}/retirement/resign-detail-reject/{rawData.Id}",
|
||||
};
|
||||
_dbContext.Set<Notification>().Add(noti);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
rawData.Status = "PENDING";
|
||||
rawData.ApproveStep = "st3";
|
||||
|
||||
if (rawData.Group == "1.1")
|
||||
{
|
||||
// TODO: Send notification to 1st Approver
|
||||
var firstCommander = rawData.Approvers
|
||||
.Where(x => x.ApproveType!.ToUpper() == "APPROVER")
|
||||
.OrderBy(x => x.Seq)
|
||||
.FirstOrDefault();
|
||||
|
||||
// Send Notification
|
||||
var noti1 = new Notification
|
||||
{
|
||||
Body = $"การขอยกเลิกลาออกของคุณ {rawData.firstName} {rawData.lastName} รอรับการอนุมัติจากคุณ",
|
||||
ReceiverUserId = firstCommander!.ProfileId,
|
||||
Type = "",
|
||||
Payload = $"{URL}/retirement/resign-detail-reject/{rawData.Id}",
|
||||
};
|
||||
_dbContext.Set<Notification>().Add(noti1);
|
||||
}
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task CommanderRejectRetirementResignCancel(Guid id, string reason, DateTime? date)
|
||||
{
|
||||
// Get UserId from token
|
||||
var userId = UserId == null ? Guid.Empty : Guid.Parse(UserId);
|
||||
|
||||
|
||||
var rawData = await GetByIdCancelAsync(id);
|
||||
if (rawData == null)
|
||||
{
|
||||
throw new Exception(GlobalMessages.DataNotFound);
|
||||
}
|
||||
|
||||
// if (rawData.ApproveStep != "st2")
|
||||
// {
|
||||
// throw new Exception("คำขอนี้ยังไม่ได้อยู่ในขั้นตอนที่สามารถอนุมัติได้ ไม่สามารถทำรายการได้");
|
||||
// }
|
||||
|
||||
// check commander approve
|
||||
var approvers = rawData.Approvers.Where(x => x.ApproveType!.ToUpper() == "COMMANDER").OrderBy(x => x.Seq).ToList();
|
||||
|
||||
var approver = approvers.FirstOrDefault(x => x.KeycloakId == userId);
|
||||
if (approver == null)
|
||||
{
|
||||
throw new Exception("คุณไม่มีสิทธิ์อนุมัติการลาออกในขั้นตอนนี้");
|
||||
}
|
||||
|
||||
// check prev approver มี action แล้วหรือไม่?
|
||||
var prevApprover = approvers.FirstOrDefault(x => x.Seq == approver.Seq - 1);
|
||||
|
||||
if (prevApprover != null)
|
||||
{
|
||||
if (prevApprover.ApproveStatus == "PENDING")
|
||||
{
|
||||
throw new Exception("ไม่สามารถทำการอนุมัติได้ เนื่องจากยังอยู่ระหว่างการพิจารณาโดยผู้บังคับบัญชารายก่อนหน้า");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var maxSeq = approvers.Max(x => x.Seq);
|
||||
|
||||
approver.ApproveStatus = "REJECT";
|
||||
approver.Comment = reason;
|
||||
approver.RejectDate = date;
|
||||
|
||||
if (approver.Seq != maxSeq)
|
||||
{
|
||||
|
||||
|
||||
var nextApprover = approvers.FirstOrDefault(x => x.Seq == approver.Seq + 1);
|
||||
// Send Noti
|
||||
var noti = new Notification
|
||||
{
|
||||
Body = $"การขอยกเลิกลาออกของคุณ {rawData.firstName} {rawData.lastName} รอรับการอนุมัติจากคุณ",
|
||||
ReceiverUserId = nextApprover!.ProfileId,
|
||||
Type = "",
|
||||
Payload = $"{URL}/retirement/resign-detail-reject/{rawData.Id}",
|
||||
};
|
||||
_dbContext.Set<Notification>().Add(noti);
|
||||
|
||||
rawData.Status = "PENDING";
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
rawData.Status = "PENDING";
|
||||
// rawData.LeaveComment = reason;
|
||||
// if (rawData.Group != "1.1")
|
||||
// {
|
||||
rawData.ApproveStep = "st3";
|
||||
// }
|
||||
|
||||
if (rawData.Group == "1.1")
|
||||
{
|
||||
// TODO: Send notification to 1st Approver
|
||||
var firstCommander = rawData.Approvers
|
||||
.Where(x => x.ApproveType!.ToUpper() == "APPROVER")
|
||||
.OrderBy(x => x.Seq)
|
||||
.FirstOrDefault();
|
||||
// Send Notification
|
||||
var noti1 = new Notification
|
||||
{
|
||||
Body = $"การขอยกเลิกลาออกของคุณ {rawData.firstName} {rawData.lastName} รอรับการอนุมัติจากคุณ",
|
||||
ReceiverUserId = firstCommander!.ProfileId,
|
||||
Type = "",
|
||||
Payload = $"{URL}/retirement/resign-detail-reject/{rawData.Id}",
|
||||
};
|
||||
_dbContext.Set<Notification>().Add(noti1);
|
||||
}
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public async Task ApproveRetirementResignCancel(Guid id, string reason, DateTime? date)
|
||||
{
|
||||
// Get UserId from token
|
||||
var userId = UserId == null ? Guid.Empty : Guid.Parse(UserId);
|
||||
|
||||
var rawData = await GetByIdCancelAsync(id);
|
||||
if (rawData == null)
|
||||
{
|
||||
throw new Exception(GlobalMessages.DataNotFound);
|
||||
}
|
||||
|
||||
// if (rawData.ApproveStep != "st3")
|
||||
// {
|
||||
// throw new Exception("คำขอนี้ยังไม่ได้อยู่ในขั้นตอนที่สามารถอนุมัติได้ ไม่สามารถทำรายการได้");
|
||||
// }
|
||||
|
||||
// check commander approve
|
||||
var approvers = rawData.Approvers.Where(x => x.ApproveType!.ToUpper() == "APPROVER").OrderBy(x => x.Seq).ToList();
|
||||
|
||||
var approver = approvers.FirstOrDefault(x => x.KeycloakId == userId);
|
||||
if (approver == null)
|
||||
{
|
||||
throw new Exception("คุณไม่มีสิทธิ์อนุมัติการลาออกในขั้นตอนนี้");
|
||||
}
|
||||
|
||||
// check prev approver มี action แล้วหรือไม่?
|
||||
var prevApprover = approvers.FirstOrDefault(x => x.Seq == approver.Seq - 1);
|
||||
|
||||
if (prevApprover != null)
|
||||
{
|
||||
if (prevApprover.ApproveStatus == "PENDING")
|
||||
{
|
||||
throw new Exception("ไม่สามารถทำการอนุมัติได้ เนื่องจากยังอยู่ระหว่างการพิจารณาโดยผู้บังคับบัญชารายก่อนหน้า");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var maxSeq = approvers.Max(x => x.Seq);
|
||||
|
||||
approver.ApproveStatus = "APPROVE";
|
||||
approver.Comment = reason;
|
||||
approver.RejectDate = date;
|
||||
|
||||
if (approver.Seq != maxSeq)
|
||||
{
|
||||
var nextApprover = approvers.FirstOrDefault(x => x.Seq == approver.Seq + 1);
|
||||
// Send Noti
|
||||
var noti1 = new Notification
|
||||
{
|
||||
Body = $"การขอยกเลิกลาออกของคุณ {rawData.firstName} {rawData.lastName} รอรับการอนุมัติจากคุณ",
|
||||
ReceiverUserId = nextApprover!.ProfileId,
|
||||
Type = "",
|
||||
Payload = "",
|
||||
};
|
||||
_dbContext.Set<Notification>().Add(noti1);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
rawData.Status = "APPROVE";
|
||||
// rawData.LeaveDirectorComment = reason;
|
||||
if (rawData.Group != "1.1")
|
||||
{
|
||||
rawData.ApproveStep = "st5";
|
||||
}
|
||||
else
|
||||
{
|
||||
rawData.ApproveStep = "st4";
|
||||
}
|
||||
|
||||
if (rawData.profileId != null)
|
||||
{
|
||||
// Send Noti
|
||||
var noti = new Notification
|
||||
{
|
||||
Body = $"การขอยกเลิกลาออกของคุณได้รับการอนุมัติ",
|
||||
ReceiverUserId = Guid.Parse(rawData.profileId),
|
||||
Type = "",
|
||||
Payload = "",
|
||||
};
|
||||
_dbContext.Set<Notification>().Add(noti);
|
||||
}
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public async Task RejectRetirementResignCancel(Guid id, string reason, DateTime? date)
|
||||
{
|
||||
// Get UserId from token
|
||||
var userId = UserId == null ? Guid.Empty : Guid.Parse(UserId);
|
||||
|
||||
var rawData = await GetByIdCancelAsync(id);
|
||||
if (rawData == null)
|
||||
{
|
||||
throw new Exception(GlobalMessages.DataNotFound);
|
||||
}
|
||||
|
||||
// if (rawData.ApproveStep != "st3")
|
||||
// {
|
||||
// throw new Exception("คำขอนี้ยังไม่ได้อยู่ในขั้นตอนที่สามารถอนุมัติได้ ไม่สามารถทำรายการได้");
|
||||
// }
|
||||
|
||||
// check commander approve
|
||||
var approvers = rawData.Approvers.Where(x => x.ApproveType!.ToUpper() == "APPROVER").OrderBy(x => x.Seq).ToList();
|
||||
|
||||
var approver = approvers.FirstOrDefault(x => x.KeycloakId == userId);
|
||||
if (approver == null)
|
||||
{
|
||||
throw new Exception("คุณไม่มีสิทธิ์อนุมัติการลาออกในขั้นตอนนี้");
|
||||
}
|
||||
|
||||
// check prev approver มี action แล้วหรือไม่?
|
||||
var prevApprover = approvers.FirstOrDefault(x => x.Seq == approver.Seq - 1);
|
||||
|
||||
if (prevApprover != null)
|
||||
{
|
||||
if (prevApprover.ApproveStatus == "PENDING")
|
||||
{
|
||||
throw new Exception("ไม่สามารถทำการอนุมัติได้ เนื่องจากยังอยู่ระหว่างการพิจารณาโดยผู้บังคับบัญชารายก่อนหน้า");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var maxSeq = approvers.Max(x => x.Seq);
|
||||
|
||||
approver.ApproveStatus = "REJECT";
|
||||
approver.Comment = reason;
|
||||
approver.RejectDate = date;
|
||||
|
||||
if (approver.Seq != maxSeq)
|
||||
{
|
||||
var nextApprover = approvers.FirstOrDefault(x => x.Seq == approver.Seq + 1);
|
||||
// Send Noti
|
||||
var noti1 = new Notification
|
||||
{
|
||||
Body = $"การขอยกเลิกลาออกของคุณ {rawData.firstName} {rawData.lastName} รอรับการอนุมัติจากคุณ",
|
||||
ReceiverUserId = nextApprover!.ProfileId,
|
||||
Type = "",
|
||||
Payload = "",
|
||||
};
|
||||
_dbContext.Set<Notification>().Add(noti1);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
rawData.Status = "REJECT";
|
||||
if (rawData.Group != "1.1")
|
||||
{
|
||||
rawData.ApproveStep = "st5";
|
||||
}
|
||||
else
|
||||
{
|
||||
rawData.ApproveStep = "st4";
|
||||
}
|
||||
|
||||
// Send Noti
|
||||
var noti = new Notification
|
||||
{
|
||||
Body = $"การขอยกเลิกลาออกของคุณไม่ได้รับการอนุมัติ \r\nเนื่องจาก{reason}",
|
||||
ReceiverUserId = Guid.Parse(rawData.profileId),
|
||||
Type = "",
|
||||
Payload = "",
|
||||
};
|
||||
_dbContext.Set<Notification>().Add(noti);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
13
BMA.EHR.Application/Requests/DirectorRequest.cs
Normal file
13
BMA.EHR.Application/Requests/DirectorRequest.cs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace BMA.EHR.Application.Requests
|
||||
{
|
||||
public class DirectorRequest
|
||||
{
|
||||
public DirectorRequestData[] result { get; set; }
|
||||
}
|
||||
public class DirectorRequestData
|
||||
{
|
||||
public string id { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -9,4 +9,18 @@ namespace BMA.EHR.Application.Requests
|
|||
public Guid? BorrowOrganizationId { get; set; }
|
||||
public Guid InsigniaNoteProfileId { get; set; }
|
||||
}
|
||||
|
||||
public class InsigniaReclaimRequest
|
||||
{
|
||||
public DateTime ReclaimDate { get; set; }
|
||||
public Guid InsigniaNoteProfileId { get; set; }
|
||||
|
||||
public string? ReclaimNote { get; set; }
|
||||
}
|
||||
|
||||
public class UpdateInsigniaReclaimRequest
|
||||
{
|
||||
public DateTime ReclaimDate { get; set; }
|
||||
public string? ReclaimNote { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ namespace BMA.EHR.Application.Requests
|
|||
public int Amount { get; set; }
|
||||
|
||||
public int Round { get; set; }
|
||||
public string[] EmpPosId { get; set; }
|
||||
public FormFile? File { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
public bool? MarkDiscipline { get; set; }
|
||||
public bool? MarkLeave { get; set; }
|
||||
public bool? MarkRate { get; set; }
|
||||
public bool? MarkInsignia { get; set; }
|
||||
public List<InsigniaRequestDoc>? Docs { get; set; }
|
||||
|
||||
public List<MatchingCondition> MatchingConditions { get; set; } = new List<MatchingCondition>();
|
||||
|
|
|
|||
|
|
@ -6,30 +6,76 @@ namespace BMA.EHR.Application.Requests
|
|||
{
|
||||
public Guid ProfileId { get; set; }
|
||||
|
||||
public string Prefix { get; set; }
|
||||
public string CitizenId { get; set; } = String.Empty;
|
||||
|
||||
public string FullName { get; set; }
|
||||
public string Prefix { get; set; } = String.Empty;
|
||||
|
||||
public string Position { get; set; }
|
||||
public string FirstName { get; set; } = String.Empty;
|
||||
|
||||
public string Rank { get; set; }
|
||||
public string LastName { get; set; } = String.Empty;
|
||||
|
||||
public string GovAge { get; set; }
|
||||
public DateTime? BirthDate { get; set; }
|
||||
|
||||
public DateTime? DateAppoint { get; set; }
|
||||
|
||||
public string? ProfileType { get; set; }
|
||||
|
||||
public string? PosTypeName { get; set; }
|
||||
|
||||
public string? PosLevelName { get; set; }
|
||||
|
||||
public string FullName { get; set; } = String.Empty;
|
||||
|
||||
public string Position { get; set; } = String.Empty;
|
||||
|
||||
public string Rank { get; set; } = String.Empty;
|
||||
|
||||
public string GovAge { get; set; } = String.Empty;
|
||||
|
||||
public double? Salary { get; set; }
|
||||
|
||||
public string LastInsignia { get; set; }
|
||||
public double? PositionSalary { get; set; }
|
||||
|
||||
public string LastInsignia { get; set; } = String.Empty;
|
||||
public Guid? LastInsigniaId { get; set; }
|
||||
|
||||
public Guid PosNo { get; set; }
|
||||
//public Guid PosNo { get; set; }
|
||||
|
||||
public InsigniaItem RequestInsignia { get; set; }
|
||||
public string PosNo { get; set; } = String.Empty;
|
||||
|
||||
public string Gender { get; set; }
|
||||
public InsigniaItem RequestInsignia { get; set; } = new();
|
||||
|
||||
public string Gender { get; set; } = String.Empty;
|
||||
|
||||
public int Seq { get; set; }
|
||||
|
||||
public double? Amount { get; set; }
|
||||
public double? PositionSalaryAmount { get; set; }
|
||||
public Guid? RootId { get; set; }
|
||||
public Guid? RootDnaId { get; set; }
|
||||
public string? Root { get; set; }
|
||||
public Guid? Child1Id { get; set; }
|
||||
public Guid? Child1DnaId { get; set; }
|
||||
public string? Child1 { get; set; }
|
||||
public Guid? Child2Id { get; set; }
|
||||
public Guid? Child2DnaId { get; set; }
|
||||
public string? Child2 { get; set; }
|
||||
public Guid? Child3Id { get; set; }
|
||||
public Guid? Child3DnaId { get; set; }
|
||||
public string? Child3 { get; set; }
|
||||
public Guid? Child4Id { get; set; }
|
||||
public Guid? Child4DnaId { get; set; }
|
||||
public string? Child4 { get; set; }
|
||||
|
||||
public List<MatchingCondition> MatchingConditions { get; set; } = new List<MatchingCondition>();
|
||||
|
||||
public bool? MarkDiscipline { get; set; } = false;
|
||||
|
||||
public bool? MarkLeave { get; set; } = false;
|
||||
|
||||
public bool? MarkRate { get; set; } = false;
|
||||
|
||||
public bool? MarkInsignia { get; set; } = false;
|
||||
}
|
||||
|
||||
public class MatchingCondition
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ namespace BMA.EHR.Application.Requests
|
|||
public string InsigniaName { get; set; }
|
||||
public string InsigniaPage { get; set; }
|
||||
public string InsigniaNo { get; set; }
|
||||
public int? Kp7InsigniaId { get; set; }
|
||||
public Guid Kp7InsigniaId { get; set; }
|
||||
}
|
||||
public class DocReceive
|
||||
{
|
||||
|
|
|
|||
|
|
@ -10,5 +10,9 @@
|
|||
public string name { get; set; }
|
||||
|
||||
public string url { get; set; }
|
||||
|
||||
public bool? isReport { get; set; }
|
||||
|
||||
public bool? isTemplate { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ namespace BMA.EHR.Application.Responses
|
|||
public class EvaluateAssignResponse
|
||||
{
|
||||
public bool successful { get; set; }
|
||||
public Data data { get; set; }
|
||||
public Data result { get; set; }
|
||||
|
||||
public class Data
|
||||
{
|
||||
|
|
@ -26,6 +26,8 @@ namespace BMA.EHR.Application.Responses
|
|||
public string Position { get; set; } = string.Empty;
|
||||
public string Department { get; set; } = string.Empty;
|
||||
public string Oc { get; set; } = string.Empty;
|
||||
public string PositionLevelName { get; set; } = string.Empty;
|
||||
|
||||
}
|
||||
|
||||
public class Commander
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ namespace BMA.EHR.Application.Responses
|
|||
public class EvaluateChairmanAssignResponse
|
||||
{
|
||||
public bool successful { get; set; }
|
||||
public Data data { get; set; }
|
||||
public Data result { get; set; }
|
||||
|
||||
public class Data
|
||||
{
|
||||
|
|
@ -26,6 +26,7 @@ namespace BMA.EHR.Application.Responses
|
|||
public string PositionLineId { get; set; } = string.Empty;
|
||||
public string OrganizationOrganization { get; set; } = string.Empty;
|
||||
public string Position { get; set; } = string.Empty;
|
||||
public string PositionLevelName { get; set; } = string.Empty;
|
||||
public string Department { get; set; } = string.Empty;
|
||||
public string Oc { get; set; } = string.Empty;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ namespace BMA.EHR.Application.Responses
|
|||
public class EvaluateRecordAssignResponse
|
||||
{
|
||||
public bool successful { get; set; }
|
||||
public Data data { get; set; }
|
||||
public Data result { get; set; }
|
||||
|
||||
public class Data
|
||||
{
|
||||
|
|
@ -26,6 +26,7 @@ namespace BMA.EHR.Application.Responses
|
|||
public string Department { get; set; }
|
||||
public string OrganizationOrganization { get; set; }
|
||||
public string Oc { get; set; }
|
||||
public string PositionLevelName { get; set; }
|
||||
}
|
||||
|
||||
public class Director
|
||||
|
|
@ -89,19 +90,20 @@ namespace BMA.EHR.Application.Responses
|
|||
public string role { get; set; }
|
||||
public DateTime createdAt { get; set; }
|
||||
public DateTime updatedAt { get; set; }
|
||||
public List<Achievement> achievements { get; set; }
|
||||
public Achievement achievements { get; set; }
|
||||
}
|
||||
|
||||
public class Achievement
|
||||
{
|
||||
public string evaluate_expect_desc { get; set; }
|
||||
public EvaluateExpectLevel evaluate_expect_level { get; set; }
|
||||
public string evaluate_output_desc { get; set; }
|
||||
public EvaluateOutputLevel evaluate_output_level { get; set; }
|
||||
// public string evaluate_expect_desc { get; set; }
|
||||
public List<EvaluateExpectLevel> evaluate_expect_level { get; set; }
|
||||
// public string evaluate_output_desc { get; set; }
|
||||
public List<EvaluateOutputLevel> evaluate_output_level { get; set; }
|
||||
}
|
||||
|
||||
public class EvaluateExpectLevel
|
||||
{
|
||||
public string? title { get; set; }
|
||||
public string col1 { get; set; }
|
||||
public string col2 { get; set; }
|
||||
public string col3 { get; set; }
|
||||
|
|
@ -111,6 +113,7 @@ namespace BMA.EHR.Application.Responses
|
|||
|
||||
public class EvaluateOutputLevel
|
||||
{
|
||||
public string? title { get; set; }
|
||||
public string col1 { get; set; }
|
||||
public string col2 { get; set; }
|
||||
public string col3 { get; set; }
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ namespace BMA.EHR.Application.Responses
|
|||
public class EvaluateResultAssignResponse
|
||||
{
|
||||
public bool successful { get; set; }
|
||||
public Data data { get; set; }
|
||||
public Data result { get; set; }
|
||||
|
||||
public class Data
|
||||
{
|
||||
|
|
@ -19,15 +19,19 @@ namespace BMA.EHR.Application.Responses
|
|||
|
||||
public class Commander
|
||||
{
|
||||
public string personal_id { get; set; }
|
||||
// public string personal_id { get; set; }
|
||||
public string name { get; set; }
|
||||
public string PositionId { get; set; }
|
||||
public string PositionLevelId { get; set; }
|
||||
public string PositionLineId { get; set; }
|
||||
public string Position { get; set; }
|
||||
public string Department { get; set; }
|
||||
public string OrganizationOrganization { get; set; }
|
||||
public string Oc { get; set; }
|
||||
// public string PositionId { get; set; }
|
||||
// public string PositionLevelId { get; set; }
|
||||
// public string PositionLineId { get; set; }
|
||||
public string position { get; set; }
|
||||
// public string Department { get; set; }
|
||||
// public string OrganizationOrganization { get; set; }
|
||||
// public string Oc { get; set; }
|
||||
public DateTime? dated { get; set; }
|
||||
public string posLevel { get; set; }
|
||||
public string posType { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public class Chairman
|
||||
|
|
@ -64,6 +68,7 @@ namespace BMA.EHR.Application.Responses
|
|||
public string PositionLevelId { get; set; }
|
||||
public string PositionLineId { get; set; }
|
||||
public string Position { get; set; }
|
||||
public string PositionLevelName { get; set; }
|
||||
public string Department { get; set; }
|
||||
public string OrganizationOrganization { get; set; }
|
||||
public string Oc { get; set; }
|
||||
|
|
@ -99,9 +104,9 @@ namespace BMA.EHR.Application.Responses
|
|||
public int pass_result { get; set; }
|
||||
public int expand_month { get; set; }
|
||||
public string reson { get; set; }
|
||||
public DateTime chairman_dated { get; set; }
|
||||
public DateTime director1_dated { get; set; }
|
||||
public DateTime director2_dated { get; set; }
|
||||
public DateTime? chairman_dated { get; set; }
|
||||
public DateTime? director1_dated { get; set; }
|
||||
public DateTime? director2_dated { get; set; }
|
||||
public string createdAt { get; set; }
|
||||
public string updatedAt { get; set; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
namespace BMA.EHR.Application.Responses.Insignias
|
||||
{
|
||||
public class PostProfileEmpInsigniaDto
|
||||
{
|
||||
public Guid profileEmployeeId { get; set; }
|
||||
|
||||
public int year { get; set; } = 0;
|
||||
|
||||
public string no { get; set; } = string.Empty;
|
||||
|
||||
public string volume { get; set; } = string.Empty;
|
||||
|
||||
public string section { get; set; } = string.Empty;
|
||||
|
||||
public string page { get; set; } = string.Empty;
|
||||
|
||||
public DateTime receiveDate { get; set; } = DateTime.MinValue;
|
||||
|
||||
public Guid insigniaId { get; set; }
|
||||
|
||||
public DateTime dateAnnounce { get; set; } = DateTime.MinValue;
|
||||
|
||||
public string issue { get; set; } = string.Empty;
|
||||
|
||||
public string volumeNo { get; set; } = string.Empty;
|
||||
|
||||
public DateTime? refCommandDate { get; set; }
|
||||
|
||||
public string refCommandNo { get; set; } = string.Empty;
|
||||
|
||||
public string note { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
namespace BMA.EHR.Application.Responses.Insignias
|
||||
{
|
||||
public class PostProfileInsigniaDto
|
||||
{
|
||||
public Guid profileId { get; set; }
|
||||
|
||||
public int year { get; set; } = 0;
|
||||
|
||||
public string no { get; set; } = string.Empty;
|
||||
|
||||
public string volume { get; set; } = string.Empty;
|
||||
|
||||
public string section { get; set; } = string.Empty;
|
||||
|
||||
public string page { get; set; } = string.Empty;
|
||||
|
||||
public DateTime receiveDate { get; set; } = DateTime.MinValue;
|
||||
|
||||
public Guid insigniaId { get; set; }
|
||||
|
||||
public DateTime dateAnnounce { get; set; } = DateTime.MinValue;
|
||||
|
||||
public string issue { get; set; } = string.Empty;
|
||||
|
||||
public string volumeNo { get; set; } = string.Empty;
|
||||
|
||||
public DateTime? refCommandDate { get; set; }
|
||||
|
||||
public string refCommandNo { get; set; } = string.Empty;
|
||||
|
||||
public string note { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,8 +2,8 @@
|
|||
{
|
||||
public class KeyValueItemResponse
|
||||
{
|
||||
public Guid Id { get; set; } = Guid.Empty;
|
||||
public Guid? Id { get; set; } = Guid.Empty;
|
||||
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string? Name { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
namespace BMA.EHR.Application.Responses.Leaves
|
||||
{
|
||||
public class GetCountApproveLeaveByTypeDto
|
||||
{
|
||||
public Guid KeycloakUserId { get; set; }
|
||||
|
||||
public Guid LeaveTypeId { get; set; }
|
||||
|
||||
public string LeaveTypeCode { get; set; } = string.Empty;
|
||||
|
||||
public int CountLeave { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
namespace BMA.EHR.Application.Responses.Leaves
|
||||
{
|
||||
public class GetProfileLeaveByKeycloakDto
|
||||
{
|
||||
public string ProfileType { get; set; }
|
||||
public string Prefix { get; set; }
|
||||
public string FirstName { get; set; }
|
||||
public string LastName { get; set; }
|
||||
public string CitizenId { get; set; }
|
||||
public DateTime BirthDate { get; set; }
|
||||
public DateTime RetireDate { get; set; }
|
||||
public string GovAge { get; set; } = string.Empty;
|
||||
public string Age { get; set; } = string.Empty;
|
||||
public DateTime DateAppoint { get; set; }
|
||||
public DateTime DateCurrent { 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;
|
||||
public string PosType { get; set; } = string.Empty;
|
||||
public string? PositionLeaveName { get; set; }
|
||||
public string? PosExecutiveName { get; set; }
|
||||
public string CurrentAddress { get; set; } = string.Empty;
|
||||
public string Oc { get; set; } = string.Empty;
|
||||
public bool isCommission { get; set; } = false;
|
||||
public string Root { get; set; } = string.Empty;
|
||||
public string? Child1 { get; set; }
|
||||
public string? Child2 { get; set; }
|
||||
public string? Child3 { get; set; }
|
||||
public string? Child4 { get; set; }
|
||||
public List<ProfileLeavePosition> Positions { get; set; } = new();
|
||||
public List<ProfileLeaveEducation> Educations { get; set; } = new();
|
||||
}
|
||||
|
||||
public class ProfileLeavePosition
|
||||
{
|
||||
public string? PositionName { get; set; } = string.Empty;
|
||||
public DateTime DateStart { get; set; }
|
||||
public DateTime DateEnd { get; set; }
|
||||
public string? PositionType { get; set; } = string.Empty;
|
||||
public string? PositionLevel { get; set; } = string.Empty;
|
||||
public string? OrgRoot { get; set; } = string.Empty;
|
||||
public string? OrgChild1 { get; set; } = string.Empty;
|
||||
public string? OrgChild2 { get; set; } = string.Empty;
|
||||
public string? OrgChild3 { get; set; } = string.Empty;
|
||||
public string? OrgChild4 { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class ProfileLeaveEducation
|
||||
{
|
||||
public string EducationLevel { get; set; } = string.Empty;
|
||||
public string Institute { get; set; } = string.Empty;
|
||||
public string? Country { get; set; } = string.Empty;
|
||||
public DateTime? FinishDate { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
namespace BMA.EHR.Application.Responses.Leaves
|
||||
{
|
||||
public class GetProfileLeaveByKeycloakResultDto
|
||||
{
|
||||
public string Message { get; set; } = string.Empty;
|
||||
|
||||
public int Status { get; set; } = -1;
|
||||
|
||||
public GetProfileLeaveByKeycloakDto? Result { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
namespace BMA.EHR.Application.Responses.Leaves
|
||||
{
|
||||
public class GetSumApproveLeaveByRootDto
|
||||
{
|
||||
public string Root { get; set; } = string.Empty;
|
||||
|
||||
public double SumLeaveDay { get; set; }
|
||||
|
||||
public double sickDayCountMale { get; set; }
|
||||
public double maternityDayCountMale { get; set; }
|
||||
public double wifeDayCountMale { get; set; }
|
||||
public double personalDayCountMale { get; set; }
|
||||
public double restDayCountMale { get; set; }
|
||||
public double ordainDayCountMale { get; set; }
|
||||
public double absentDayCountMale { get; set; }
|
||||
public double studyDayCountMale { get; set; }
|
||||
public double agencyDayCountMale { get; set; }
|
||||
public double coupleDayCountMale { get; set; }
|
||||
public double therapyDayCountMale { get; set; }
|
||||
public double sickDayCountFemale { get; set; }
|
||||
public double maternityDayCountFemale { get; set; }
|
||||
public double wifeDayCountFemale { get; set; }
|
||||
public double personalDayCountFemale { get; set; }
|
||||
public double restDayCountFemale { get; set; }
|
||||
public double ordainDayCountFemale { get; set; }
|
||||
public double absentDayCountFemale { get; set; }
|
||||
public double studyDayCountFemale { get; set; }
|
||||
public double agencyDayCountFemale { get; set; }
|
||||
public double coupleDayCountFemale { get; set; }
|
||||
public double therapyDayCountFemale { get; set; }
|
||||
public double sickDayCountNo { get; set; }
|
||||
public double maternityDayCountNo { get; set; }
|
||||
public double wifeDayCountNo { get; set; }
|
||||
public double personalDayCountNo { get; set; }
|
||||
public double restDayCountNo { get; set; }
|
||||
public double ordainDayCountNo { get; set; }
|
||||
public double absentDayCountNo { get; set; }
|
||||
public double studyDayCountNo { get; set; }
|
||||
public double agencyDayCountNo { get; set; }
|
||||
public double coupleDayCountNo { get; set; }
|
||||
public double therapyDayCountNo { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
namespace BMA.EHR.Application.Responses.Leaves
|
||||
{
|
||||
public class GetSumApproveLeaveByTypeDto
|
||||
{
|
||||
public Guid KeycloakUserId { get; set; }
|
||||
|
||||
public Guid LeaveTypeId { get; set; }
|
||||
|
||||
public string LeaveTypeCode { get; set; } = string.Empty;
|
||||
|
||||
public double SumLeaveDay { get; set; } = 0.0;
|
||||
|
||||
public int CountLeaveDay { get; set; } = 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -7,9 +7,11 @@
|
|||
|
||||
public Guid ReceiverUserId { get; set; } = Guid.Empty;
|
||||
|
||||
public string? KeycloakUserId { get; set; }
|
||||
|
||||
public string Type { get; set; } = "TEXT";
|
||||
|
||||
public CommandPayload Payload { get; set; } = new();
|
||||
public string Payload { get; set; } = string.Empty;
|
||||
|
||||
public bool IsOpen { get; set; } = false;
|
||||
|
||||
|
|
|
|||
49
BMA.EHR.Application/Responses/OrgRequest.cs
Normal file
49
BMA.EHR.Application/Responses/OrgRequest.cs
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
using BMA.EHR.Domain.Models.MetaData;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace BMA.EHR.Application.Responses
|
||||
{
|
||||
public class OrgRequest
|
||||
{
|
||||
public OrgRequestData result { get; set; } = new();
|
||||
}
|
||||
public class OrgRequestData
|
||||
{
|
||||
public string? profileId { get; set; }
|
||||
public string? prefix { get; set; }
|
||||
public string? firstName { get; set; }
|
||||
public string? lastName { get; set; }
|
||||
public string? citizenId { get; set; }
|
||||
public string? root { get; set; }
|
||||
public string? rootId { get; set; }
|
||||
public string? rootShortName { get; set; }
|
||||
public string? child1 { get; set; }
|
||||
public string? child1Id { get; set; }
|
||||
public string? child1ShortName { get; set; }
|
||||
public string? child2 { get; set; }
|
||||
public string? child2Id { get; set; }
|
||||
public string? child2ShortName { get; set; }
|
||||
public string? child3 { get; set; }
|
||||
public string? child3Id { get; set; }
|
||||
public string? child3ShortName { get; set; }
|
||||
public string? child4 { get; set; }
|
||||
public string? child4Id { get; set; }
|
||||
public string? child4ShortName { get; set; }
|
||||
public string? node { get; set; }
|
||||
public string? nodeId { get; set; }
|
||||
public string? nodeShortName { get; set; }
|
||||
public int? posMasterNo { get; set; }
|
||||
public string? position { get; set; }
|
||||
public string? posTypeId { get; set; }
|
||||
public string? posTypeName { get; set; }
|
||||
public int? posTypeRank { get; set; }
|
||||
public string? posLevelId { get; set; }
|
||||
public string? posLevelName { get; set; }
|
||||
public int? posLevelRank { get; set; }
|
||||
public string? posExecutiveId { get; set; }
|
||||
public string? posExecutiveName { get; set; }
|
||||
public string? posNo { get; set; }
|
||||
public string? organization { get; set; }
|
||||
public double? salary { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
namespace BMA.EHR.Application.Responses.Organizations
|
||||
{
|
||||
public class GetActiveRootDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public Guid CreatedUserId { get; set; }
|
||||
public DateTime LastUpdatedAt { get; set; }
|
||||
public Guid LastUpdateUserId { get; set; }
|
||||
public string CreatedFullName { get; set; } = string.Empty;
|
||||
public string LastUpdateFullName { get; set; } = string.Empty;
|
||||
public string OrgRootName { get; set; } = string.Empty;
|
||||
public string OrgRevisionId { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
namespace BMA.EHR.Application.Responses.Organizations
|
||||
{
|
||||
public class GetActiveRootResultDto
|
||||
{
|
||||
public string Message { get; set; } = string.Empty;
|
||||
|
||||
public int Status { get; set; } = -1;
|
||||
|
||||
public List<GetActiveRootDto> Result { get; set; } = new();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
namespace BMA.EHR.Application.Responses.Organizations
|
||||
{
|
||||
public class GetIsOfficerDto
|
||||
{
|
||||
public bool isOfficer { get; set; }
|
||||
public bool isStaff { get; set; }
|
||||
public bool isDirector { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
namespace BMA.EHR.Application.Responses.Organizations
|
||||
{
|
||||
public class GetIsOfficerResultDto
|
||||
{
|
||||
public string Message { get; set; } = string.Empty;
|
||||
|
||||
public int Status { get; set; } = -1;
|
||||
|
||||
public GetIsOfficerDto Result { get; set; } = new();
|
||||
}
|
||||
}
|
||||
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