Compare commits
519 commits
command-1.
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a2fe424b87 | ||
|
|
5021c00dd3 | ||
|
|
bf5dc2cf19 | ||
|
|
f6c8b4f754 | ||
|
|
65ca175f98 | ||
|
|
5f678b2898 | ||
|
|
ae417e4777 | ||
|
|
a2dc4b5b82 | ||
|
|
c55648a3cc | ||
|
|
bc29952e83 | ||
|
|
f4f56b1c21 | ||
|
|
baf828ac85 | ||
|
|
be1f6dd84e | ||
|
|
fcea84bdb8 | ||
|
|
5d090fa7bd | ||
|
|
030098c0b9 | ||
|
|
6843e3ff3f | ||
|
|
2cdae3578e | ||
|
|
71966eb4e9 | ||
|
|
e926866918 | ||
|
|
35179d8cfc | ||
|
|
4a8d349415 | ||
|
|
7d2be029b6 | ||
|
|
d75cf39d7b | ||
|
|
db3d531aa9 | ||
|
|
e17895de81 | ||
|
|
e09a6d0ea6 | ||
|
|
4c44bdf237 | ||
| 6f1ca58f04 | |||
| a956f0b0dd | |||
|
|
f0c493a026 | ||
|
|
fe5c2cd7c1 | ||
|
|
c4209400ff | ||
|
|
d6a7f1a5ca | ||
|
|
f50efc632b | ||
| 5f9c49f479 | |||
| 48aab28e04 | |||
| 1f7951dc4c | |||
|
|
d3a174faa0 | ||
|
|
afa5c85393 | ||
| 077b60b1c3 | |||
| efc96dfb6d | |||
|
|
4827906d1d | ||
|
|
8ae822d05b | ||
|
|
71a4748d39 | ||
|
|
ad70043264 | ||
|
|
513956c861 | ||
|
|
a48f3fa804 | ||
|
|
dc5ac329e2 | ||
|
|
3f98e07419 | ||
| ce4558c240 | |||
| 6a38f000ba | |||
|
|
f50ad38503 | ||
| aeb2ceea6f | |||
| e96f606c85 | |||
|
|
81dc7f4544 | ||
|
|
a16ef7ac55 | ||
|
|
f6bf1ab026 | ||
|
|
caa01088c6 | ||
|
|
782d1526b5 | ||
|
|
04ac35c10b | ||
|
|
02abedc973 | ||
| 8415ffc92d | |||
| 64c75cd9d5 | |||
|
|
22e04d90fe | ||
|
|
2146e0e0ca | ||
|
|
3f8ae1ede9 | ||
|
|
c2795d6891 | ||
|
|
6e5284b3c7 | ||
|
|
76697c4f63 | ||
|
|
e5f6a44f5f | ||
|
|
583569682d | ||
|
|
9f756771cd | ||
|
|
219b172073 | ||
|
|
ecf660e4cf | ||
|
|
0365fad723 | ||
|
|
20e8dfddd6 | ||
|
|
91c479ef9e | ||
|
|
80fcda61cf | ||
|
|
f02413f2b2 | ||
|
|
1739aa8057 | ||
|
|
bc3bba547f | ||
|
|
4161fcc1cf | ||
|
|
6d0921a76a | ||
|
|
df7bebe0ba | ||
|
|
82a45b6811 | ||
|
|
63d983f831 | ||
|
|
e326e43ae6 | ||
|
|
4dab3c5cd9 | ||
|
|
4bd46d13e5 | ||
|
|
132a59b946 | ||
|
|
740a9984c9 | ||
|
|
5b0fcd0680 | ||
|
|
2bdb8bb733 | ||
|
|
aed1e8a58d | ||
|
|
fb3cb2aa94 | ||
|
|
b5025c382f | ||
|
|
4e2113eef2 | ||
|
|
ffcf95c210 | ||
|
|
e4bcfee80c | ||
|
|
a173a7dc3c | ||
|
|
361ded2078 | ||
|
|
1379dab556 | ||
|
|
d8039379ad | ||
|
|
2d4116d79a | ||
|
|
c65a4a04ac | ||
|
|
d58c7dc07e | ||
|
|
bb329f86de | ||
|
|
b3298e88c6 | ||
|
|
04d0067ee8 | ||
|
|
c035c13405 | ||
|
|
2e9db2d42c | ||
|
|
1389df0225 | ||
|
|
058027ea29 | ||
|
|
ee2d16925a | ||
|
|
42f3813a7a | ||
|
|
7bafbf5001 | ||
|
|
db99630e0d | ||
|
|
34ec9bb77c | ||
|
|
5606e8b50a | ||
|
|
ee4e9c3699 | ||
|
|
6efeec3f1f | ||
|
|
c34fe35506 | ||
|
|
678329b5df | ||
|
|
057b51390e | ||
|
|
8950073485 | ||
|
|
bf92f6933e | ||
|
|
cea1c4b64e | ||
|
|
cef41506a8 | ||
| bceb4d3096 | |||
|
|
06956284d7 | ||
|
|
6b8eddcbc0 | ||
|
|
a4a5d13203 | ||
|
|
69b89dfc90 | ||
|
|
ea694bfda2 | ||
|
|
6691303ea7 | ||
|
|
8ea572d46c | ||
|
|
2ecef0792c | ||
|
|
1cf780ecd0 | ||
|
|
bf6ea555fc | ||
|
|
8fa105606b | ||
|
|
47c0cfc62a | ||
|
|
932d5e75c7 | ||
|
|
a50153f32c | ||
|
|
d85bab11b2 | ||
|
|
82c31a0f57 | ||
|
|
2cd7798dd9 | ||
|
|
759a51ab58 | ||
|
|
3dee5f7166 | ||
|
|
8732c34564 | ||
|
|
91e6b1b35b | ||
|
|
c1ac687101 | ||
|
|
de1773880b | ||
|
|
c91e6c8030 | ||
|
|
d8f1126764 | ||
|
|
7ba429bb64 | ||
|
|
3e3bfff7ba | ||
|
|
19b79a162d | ||
|
|
a09d5937f9 | ||
|
|
aef81e9f4e | ||
|
|
6427cb4344 | ||
|
|
252d8b5fa3 | ||
|
|
58aca3a328 | ||
|
|
818ff38e99 | ||
|
|
23bbd9791e | ||
|
|
7e0f0485fd | ||
|
|
b1df33dc20 | ||
|
|
6902236f48 | ||
|
|
4562029e6e | ||
|
|
4650f7a2ab | ||
|
|
f866435897 | ||
|
|
006cea048d | ||
|
|
9a74b690cd | ||
|
|
2ee36af763 | ||
|
|
cd99179621 | ||
|
|
c20e1b48bd | ||
|
|
5b054f9948 | ||
|
|
3e34aaa178 | ||
|
|
ddb35f525a | ||
|
|
ecca345407 | ||
|
|
7e613ab2e6 | ||
|
|
7eade164e9 | ||
|
|
256da24caf | ||
|
|
869defcc7e | ||
|
|
65feb994ee | ||
|
|
d748308419 | ||
|
|
b8df2d4024 | ||
|
|
c42aaa38f6 | ||
|
|
ddaa339e9f | ||
|
|
d70ed254c0 | ||
|
|
de91fd0fa2 | ||
|
|
7d3ec6c74e | ||
| 1b7bdd82e6 | |||
|
|
a8271c8d79 | ||
|
|
14fd9d5262 | ||
|
|
c81220a049 | ||
|
|
e5e7c77880 | ||
|
|
a2ac05ed61 | ||
|
|
2410574d42 | ||
|
|
682c88c2db | ||
|
|
05ec0cccce | ||
|
|
35310f7854 | ||
|
|
1d8ef79373 | ||
|
|
c693364fe1 | ||
|
|
4f18a97d0b | ||
|
|
d3cc0781cf | ||
|
|
639d41649c | ||
|
|
358fd47b99 | ||
|
|
970319e8c2 | ||
|
|
09a7208074 | ||
|
|
7775ea85c3 | ||
|
|
19000b2e42 | ||
|
|
1a0e712a1c | ||
|
|
c25bef0672 | ||
|
|
659e06a08d | ||
|
|
0a170fd259 | ||
|
|
5c05f1123a | ||
|
|
06b53ddeaa | ||
|
|
46504c9e30 | ||
|
|
e80f89117c | ||
|
|
4c189fdc4a | ||
|
|
90eb94cee3 | ||
|
|
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 | |||
| 3ae9be5869 |
218 changed files with 122111 additions and 4881 deletions
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"
|
||||
6
.github/workflows/release_Retirement.yaml
vendored
6
.github/workflows/release_Retirement.yaml
vendored
|
|
@ -1,9 +1,9 @@
|
|||
name: release-dev
|
||||
run-name: release-dev ${{ github.actor }}
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "retirement-[0-9]+.[0-9]+.[0-9]+"
|
||||
# push:
|
||||
# tags:
|
||||
# - "retirement-[0-9]+.[0-9]+.[0-9]+"
|
||||
workflow_dispatch:
|
||||
env:
|
||||
REGISTRY: docker.frappet.com
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
name: release-dev
|
||||
run-name: release-dev ${{ github.actor }}
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "consumer-[0-9]+.[0-9]+.[0-9]+"
|
||||
# push:
|
||||
# tags:
|
||||
# - "consumer-[0-9]+.[0-9]+.[0-9]+"
|
||||
workflow_dispatch:
|
||||
env:
|
||||
REGISTRY: docker.frappet.com
|
||||
|
|
|
|||
6
.github/workflows/release_command.yaml
vendored
6
.github/workflows/release_command.yaml
vendored
|
|
@ -1,9 +1,9 @@
|
|||
name: release-dev
|
||||
run-name: release-dev ${{ github.actor }}
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "command-[0-9]+.[0-9]+.[0-9]+"
|
||||
# push:
|
||||
# tags:
|
||||
# - "command-[0-9]+.[0-9]+.[0-9]+"
|
||||
workflow_dispatch:
|
||||
env:
|
||||
REGISTRY: docker.frappet.com
|
||||
|
|
|
|||
6
.github/workflows/release_discipline.yaml
vendored
6
.github/workflows/release_discipline.yaml
vendored
|
|
@ -1,9 +1,9 @@
|
|||
name: release-dev
|
||||
run-name: release-dev ${{ github.actor }}
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "discipline-[0-9]+.[0-9]+.[0-9]+"
|
||||
# push:
|
||||
# tags:
|
||||
# - "discipline-[0-9]+.[0-9]+.[0-9]+"
|
||||
workflow_dispatch:
|
||||
env:
|
||||
REGISTRY: docker.frappet.com
|
||||
|
|
|
|||
6
.github/workflows/release_insignia.yaml
vendored
6
.github/workflows/release_insignia.yaml
vendored
|
|
@ -1,9 +1,9 @@
|
|||
name: release-dev
|
||||
run-name: release-dev ${{ github.actor }}
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "insignia-[0-9]+.[0-9]+.[0-9]+"
|
||||
# push:
|
||||
# tags:
|
||||
# - "insignia-[0-9]+.[0-9]+.[0-9]+"
|
||||
workflow_dispatch:
|
||||
env:
|
||||
REGISTRY: docker.frappet.com
|
||||
|
|
|
|||
8
.github/workflows/release_leave.yaml
vendored
8
.github/workflows/release_leave.yaml
vendored
|
|
@ -1,9 +1,9 @@
|
|||
name: release-dev
|
||||
run-name: release-dev ${{ github.actor }}
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "leave-[0-9]+.[0-9]+.[0-9]+"
|
||||
# push:
|
||||
# tags:
|
||||
# - "leave-[0-9]+.[0-9]+.[0-9]+"
|
||||
workflow_dispatch:
|
||||
env:
|
||||
REGISTRY: docker.frappet.com
|
||||
|
|
@ -57,7 +57,7 @@ jobs:
|
|||
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
|
||||
uses: appleboy/ssh-action@v1
|
||||
with:
|
||||
host: ${{env.DEPLOY_HOST}}
|
||||
username: frappet
|
||||
|
|
|
|||
6
.github/workflows/release_placement.yaml
vendored
6
.github/workflows/release_placement.yaml
vendored
|
|
@ -1,9 +1,9 @@
|
|||
name: release-dev
|
||||
run-name: release-dev ${{ github.actor }}
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "placement-[0-9]+.[0-9]+.[0-9]+"
|
||||
# push:
|
||||
# tags:
|
||||
# - "placement-[0-9]+.[0-9]+.[0-9]+"
|
||||
workflow_dispatch:
|
||||
env:
|
||||
REGISTRY: docker.frappet.com
|
||||
|
|
|
|||
6
.github/workflows/release_report.yaml
vendored
6
.github/workflows/release_report.yaml
vendored
|
|
@ -1,9 +1,9 @@
|
|||
name: release-dev
|
||||
run-name: release-dev ${{ github.actor }}
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "reportv2-[0-9]+.[0-9]+.[0-9]+"
|
||||
# push:
|
||||
# tags:
|
||||
# - "reportv2-[0-9]+.[0-9]+.[0-9]+"
|
||||
workflow_dispatch:
|
||||
env:
|
||||
REGISTRY: docker.frappet.com
|
||||
|
|
|
|||
6
.gitignore
vendored
6
.gitignore
vendored
|
|
@ -374,3 +374,9 @@ MigrationBackup/
|
|||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
|
||||
# VS Code C# Dev Kit cache
|
||||
*.lscache
|
||||
|
||||
# Claude Code
|
||||
.claude/
|
||||
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": {
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ namespace BMA.EHR.Application
|
|||
services.AddTransient<UserDutyTimeRepository>();
|
||||
services.AddTransient<AdditionalCheckRequestRepository>();
|
||||
services.AddTransient<UserCalendarRepository>();
|
||||
services.AddTransient<CheckInJobStatusRepository>();
|
||||
|
||||
services.AddTransient<LeaveTypeRepository>();
|
||||
services.AddTransient<LeaveRequestRepository>();
|
||||
|
|
@ -60,6 +61,8 @@ namespace BMA.EHR.Application
|
|||
|
||||
services.AddTransient<MinIOLeaveService>();
|
||||
|
||||
services.AddTransient<LeaveProcessJobStatusRepository>();
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -919,7 +919,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
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();
|
||||
|
|
@ -934,7 +934,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var _client = new HttpClient())
|
||||
{
|
||||
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
_client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
_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();
|
||||
|
|
@ -986,7 +986,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
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();
|
||||
|
|
@ -1001,7 +1001,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var _client = new HttpClient())
|
||||
{
|
||||
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
_client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
_client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Get, _apiUrl);
|
||||
var _res = await _client.SendAsync(_req);
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
|
|
@ -1423,7 +1423,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
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();
|
||||
|
|
@ -1440,7 +1440,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var _client = new HttpClient())
|
||||
{
|
||||
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
_client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
_client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Get, _apiUrl);
|
||||
var _res = await _client.SendAsync(_req);
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
|
|
@ -1534,7 +1534,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
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();
|
||||
|
|
@ -1550,7 +1550,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var _client = new HttpClient())
|
||||
{
|
||||
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
_client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
_client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Get, _apiUrl);
|
||||
var _res = await _client.SendAsync(_req);
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
|
|
@ -1603,7 +1603,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
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();
|
||||
|
|
@ -1832,7 +1832,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
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();
|
||||
|
|
@ -1849,7 +1849,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var _client = new HttpClient())
|
||||
{
|
||||
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
_client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
_client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Get, _apiUrl);
|
||||
var _res = await _client.SendAsync(_req);
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
|
|
@ -1905,7 +1905,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
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();
|
||||
|
|
@ -1922,7 +1922,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var _client = new HttpClient())
|
||||
{
|
||||
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
_client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
_client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Get, _apiUrl);
|
||||
var _res = await _client.SendAsync(_req);
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
|
|
@ -1978,7 +1978,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
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();
|
||||
|
|
@ -1995,7 +1995,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var _client = new HttpClient())
|
||||
{
|
||||
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
_client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
_client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Get, _apiUrl);
|
||||
var _res = await _client.SendAsync(_req);
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
|
|
@ -2051,7 +2051,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
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();
|
||||
|
|
@ -2068,7 +2068,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var _client = new HttpClient())
|
||||
{
|
||||
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
_client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
_client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Get, _apiUrl);
|
||||
var _res = await _client.SendAsync(_req);
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
|
|
@ -2124,7 +2124,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
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();
|
||||
|
|
@ -2141,7 +2141,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var _client = new HttpClient())
|
||||
{
|
||||
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
_client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
_client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Get, _apiUrl);
|
||||
var _res = await _client.SendAsync(_req);
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
|
|
@ -2197,7 +2197,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
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();
|
||||
|
|
@ -2214,7 +2214,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var _client = new HttpClient())
|
||||
{
|
||||
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
_client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
_client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Get, _apiUrl);
|
||||
var _res = await _client.SendAsync(_req);
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
|
|
@ -2270,7 +2270,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
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();
|
||||
|
|
@ -2287,7 +2287,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var _client = new HttpClient())
|
||||
{
|
||||
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
_client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
_client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Get, _apiUrl);
|
||||
var _res = await _client.SendAsync(_req);
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
|
|
@ -2340,7 +2340,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
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();
|
||||
|
|
@ -2355,7 +2355,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var _client = new HttpClient())
|
||||
{
|
||||
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
_client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
_client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Get, _apiUrl);
|
||||
var _res = await _client.SendAsync(_req);
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
|
|
@ -2409,7 +2409,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
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();
|
||||
|
|
@ -2462,7 +2462,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
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();
|
||||
|
|
@ -2515,7 +2515,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
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();
|
||||
|
|
@ -2568,7 +2568,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
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();
|
||||
|
|
@ -2621,7 +2621,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
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();
|
||||
|
|
@ -2673,7 +2673,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
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();
|
||||
|
|
@ -2725,7 +2725,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
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();
|
||||
|
|
@ -2994,7 +2994,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrl);
|
||||
var _res = await client.PostAsJsonAsync(apiUrl, new
|
||||
{
|
||||
|
|
@ -3046,7 +3046,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
foreach (var edu in placementProfile.PlacementEducations)
|
||||
{
|
||||
var _res = await client.PostAsJsonAsync(apiUrlEdu, new
|
||||
|
|
@ -3083,7 +3083,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
foreach (var cer in placementProfile.PlacementCertificates)
|
||||
{
|
||||
var _res = await client.PostAsJsonAsync(apiUrlCer, new
|
||||
|
|
@ -3104,7 +3104,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlSalary, new
|
||||
{
|
||||
profileId = profileId,
|
||||
|
|
@ -3135,7 +3135,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrlOrg);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
{
|
||||
|
|
@ -3287,7 +3287,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrlSalary);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlSalary, new
|
||||
{
|
||||
|
|
@ -3319,7 +3319,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrlOrg);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
{
|
||||
|
|
@ -3468,7 +3468,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrlSalary);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlSalary, new
|
||||
{
|
||||
|
|
@ -3500,7 +3500,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrlOrg);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
{
|
||||
|
|
@ -3649,7 +3649,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrlSalary);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlSalary, new
|
||||
{
|
||||
|
|
@ -3681,7 +3681,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrlOrg);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
{
|
||||
|
|
@ -3832,7 +3832,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrlSalary);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlSalary, new
|
||||
{
|
||||
|
|
@ -3864,7 +3864,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrlOrg);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
{
|
||||
|
|
@ -4017,7 +4017,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrlSalary);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlSalary, new
|
||||
{
|
||||
|
|
@ -4049,7 +4049,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrlOrg);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
{
|
||||
|
|
@ -4199,7 +4199,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrlSalary);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlSalary, new
|
||||
{
|
||||
|
|
@ -4231,7 +4231,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrlOrg);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
{
|
||||
|
|
@ -4382,7 +4382,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrlSalary);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlSalary, new
|
||||
{
|
||||
|
|
@ -4409,7 +4409,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrlLeave);
|
||||
string? _null = null;
|
||||
var _res = await client.PostAsJsonAsync(apiUrlLeave, new
|
||||
|
|
@ -4560,7 +4560,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrlSalary);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlSalary, new
|
||||
{
|
||||
|
|
@ -4587,7 +4587,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrlLeave);
|
||||
string? _null = null;
|
||||
var _res = await client.PostAsJsonAsync(apiUrlLeave, new
|
||||
|
|
@ -4928,7 +4928,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrl);
|
||||
var _res = await client.PostAsJsonAsync(apiUrl, new
|
||||
{
|
||||
|
|
@ -5085,7 +5085,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrl);
|
||||
var _res = await client.PostAsJsonAsync(apiUrl, new
|
||||
{
|
||||
|
|
@ -5262,7 +5262,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrlSalary);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlSalary, new
|
||||
{
|
||||
|
|
@ -5440,7 +5440,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrlSalary);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlSalary, new
|
||||
{
|
||||
|
|
@ -5472,7 +5472,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrlOrg);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
{
|
||||
|
|
@ -5626,7 +5626,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrlSalary);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlSalary, new
|
||||
{
|
||||
|
|
@ -5805,7 +5805,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrlSalary);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlSalary, new
|
||||
{
|
||||
|
|
@ -5986,7 +5986,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrl);
|
||||
var _res = await client.PostAsJsonAsync(apiUrl, new
|
||||
{
|
||||
|
|
@ -6001,7 +6001,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrlSalary);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlSalary, new
|
||||
{
|
||||
|
|
@ -6182,7 +6182,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrl);
|
||||
var _res = await client.PostAsJsonAsync(apiUrl, new
|
||||
{
|
||||
|
|
@ -6197,7 +6197,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrlSalary);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlSalary, new
|
||||
{
|
||||
|
|
@ -6371,7 +6371,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrl);
|
||||
var _res = await client.PostAsJsonAsync(apiUrl, new
|
||||
{
|
||||
|
|
@ -6452,7 +6452,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var req = new HttpRequestMessage(HttpMethod.Post, _apiUrl);
|
||||
var res = await client.PostAsJsonAsync(_apiUrl, new { result = dataSend });
|
||||
var result = await res.Content.ReadAsStringAsync();
|
||||
|
|
@ -6549,7 +6549,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrl);
|
||||
var _res = await client.PostAsJsonAsync(apiUrl, new
|
||||
{
|
||||
|
|
@ -6630,7 +6630,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var req = new HttpRequestMessage(HttpMethod.Post, _apiUrl);
|
||||
var res = await client.PostAsJsonAsync(_apiUrl, new { result = dataSend });
|
||||
var result = await res.Content.ReadAsStringAsync();
|
||||
|
|
@ -6719,7 +6719,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var req = new HttpRequestMessage(HttpMethod.Post, apiUrl);
|
||||
var res = await client.PostAsJsonAsync(apiUrl, new { result = data });
|
||||
var result = await res.Content.ReadAsStringAsync();
|
||||
|
|
@ -6877,7 +6877,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrlSalary);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlSalary, new
|
||||
{
|
||||
|
|
@ -6906,7 +6906,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrlOrg);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
{
|
||||
|
|
@ -7062,7 +7062,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Put, apiUrl);
|
||||
var _res = await client.PutAsJsonAsync(apiUrl, new
|
||||
{
|
||||
|
|
@ -7215,7 +7215,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrlSalary);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlSalary, new
|
||||
{
|
||||
|
|
@ -7244,7 +7244,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrlOrg);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
{
|
||||
|
|
@ -7385,7 +7385,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var req = new HttpRequestMessage(HttpMethod.Post, apiUrl);
|
||||
var res = await client.PostAsJsonAsync(apiUrl, new { result = data });
|
||||
var result = await res.Content.ReadAsStringAsync();
|
||||
|
|
@ -7411,7 +7411,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrl2);
|
||||
var _res = await client.PostAsJsonAsync(apiUrl2, new
|
||||
{
|
||||
|
|
@ -7544,7 +7544,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var req = new HttpRequestMessage(HttpMethod.Post, apiUrl);
|
||||
var res = await client.PostAsJsonAsync(apiUrl, new { result = data });
|
||||
var result = await res.Content.ReadAsStringAsync();
|
||||
|
|
@ -7570,7 +7570,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrl2);
|
||||
var _res = await client.PostAsJsonAsync(apiUrl2, new
|
||||
{
|
||||
|
|
@ -7704,7 +7704,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var req = new HttpRequestMessage(HttpMethod.Post, apiUrl);
|
||||
var res = await client.PostAsJsonAsync(apiUrl, new { result = data });
|
||||
var result = await res.Content.ReadAsStringAsync();
|
||||
|
|
@ -7730,7 +7730,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrl2);
|
||||
var _res = await client.PostAsJsonAsync(apiUrl2, new
|
||||
{
|
||||
|
|
@ -7864,7 +7864,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var req = new HttpRequestMessage(HttpMethod.Post, apiUrl);
|
||||
var res = await client.PostAsJsonAsync(apiUrl, new { result = data });
|
||||
var result = await res.Content.ReadAsStringAsync();
|
||||
|
|
@ -7890,7 +7890,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrl2);
|
||||
var _res = await client.PostAsJsonAsync(apiUrl2, new
|
||||
{
|
||||
|
|
@ -8024,7 +8024,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var req = new HttpRequestMessage(HttpMethod.Post, apiUrl);
|
||||
var res = await client.PostAsJsonAsync(apiUrl, new { result = data });
|
||||
var result = await res.Content.ReadAsStringAsync();
|
||||
|
|
@ -8050,7 +8050,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrl2);
|
||||
var _res = await client.PostAsJsonAsync(apiUrl2, new
|
||||
{
|
||||
|
|
@ -8184,7 +8184,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var req = new HttpRequestMessage(HttpMethod.Post, apiUrl);
|
||||
var res = await client.PostAsJsonAsync(apiUrl, new { result = data });
|
||||
var result = await res.Content.ReadAsStringAsync();
|
||||
|
|
@ -8210,7 +8210,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrl2);
|
||||
var _res = await client.PostAsJsonAsync(apiUrl2, new
|
||||
{
|
||||
|
|
@ -8344,7 +8344,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var req = new HttpRequestMessage(HttpMethod.Post, apiUrl);
|
||||
var res = await client.PostAsJsonAsync(apiUrl, new { result = data });
|
||||
var result = await res.Content.ReadAsStringAsync();
|
||||
|
|
@ -8370,7 +8370,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrl2);
|
||||
var _res = await client.PostAsJsonAsync(apiUrl2, new
|
||||
{
|
||||
|
|
@ -8504,7 +8504,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var req = new HttpRequestMessage(HttpMethod.Post, apiUrl);
|
||||
var res = await client.PostAsJsonAsync(apiUrl, new { result = data });
|
||||
var result = await res.Content.ReadAsStringAsync();
|
||||
|
|
@ -8530,7 +8530,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrl2);
|
||||
var _res = await client.PostAsJsonAsync(apiUrl2, new
|
||||
{
|
||||
|
|
@ -8663,7 +8663,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var req = new HttpRequestMessage(HttpMethod.Post, apiUrl);
|
||||
var res = await client.PostAsJsonAsync(apiUrl, new { result = data });
|
||||
var result = await res.Content.ReadAsStringAsync();
|
||||
|
|
@ -8806,7 +8806,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var req = new HttpRequestMessage(HttpMethod.Post, apiUrl);
|
||||
var res = await client.PostAsJsonAsync(apiUrl, new { result = data });
|
||||
var result = await res.Content.ReadAsStringAsync();
|
||||
|
|
@ -8949,7 +8949,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var req = new HttpRequestMessage(HttpMethod.Post, apiUrl);
|
||||
var res = await client.PostAsJsonAsync(apiUrl, new { result = data });
|
||||
var result = await res.Content.ReadAsStringAsync();
|
||||
|
|
@ -9091,7 +9091,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var req = new HttpRequestMessage(HttpMethod.Post, apiUrl);
|
||||
var res = await client.PostAsJsonAsync(apiUrl, new { result = data });
|
||||
var result = await res.Content.ReadAsStringAsync();
|
||||
|
|
@ -9234,7 +9234,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var req = new HttpRequestMessage(HttpMethod.Post, apiUrl);
|
||||
var res = await client.PostAsJsonAsync(apiUrl, new { result = data });
|
||||
var result = await res.Content.ReadAsStringAsync();
|
||||
|
|
@ -9612,7 +9612,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrl);
|
||||
string? _null = null;
|
||||
var _res = await client.PostAsJsonAsync(apiUrl, new
|
||||
|
|
@ -9628,7 +9628,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Post, apiUrlSalary);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlSalary, new
|
||||
{
|
||||
|
|
@ -11388,7 +11388,7 @@ namespace BMA.EHR.Application.Repositories.Commands
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
foreach (var insignia in Insignias)
|
||||
{
|
||||
var _res = await client.PostAsJsonAsync(apiUrlInsig, new
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ namespace BMA.EHR.Application.Repositories
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
{
|
||||
refId = cronjobNoti.DisciplineComplaint_Profiles.Select(x => x.PersonId),
|
||||
|
|
@ -91,7 +91,7 @@ namespace BMA.EHR.Application.Repositories
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
{
|
||||
refId = cronjobNoti.DisciplineInvestigate_ProfileComplaints.Select(x => x.PersonId),
|
||||
|
|
@ -132,7 +132,7 @@ namespace BMA.EHR.Application.Repositories
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
{
|
||||
refId = cronjobNoti.DisciplineDisciplinary_ProfileComplaintInvestigates.Select(x => x.PersonId),
|
||||
|
|
|
|||
|
|
@ -53,15 +53,18 @@ namespace BMA.EHR.Application.Repositories
|
|||
|
||||
#region " For Call External API "
|
||||
|
||||
protected async Task<string> GetExternalAPIAsync(string apiPath, string accessToken, string apiKey)
|
||||
protected async Task<string> GetExternalAPIAsync(string apiPath, string accessToken, string apiKey, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
// กำหนด timeout เป็น 30 นาที
|
||||
using var timeoutCts = new CancellationTokenSource(TimeSpan.FromMinutes(30));
|
||||
using var combinedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutCts.Token);
|
||||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", apiKey);
|
||||
var _res = await client.GetAsync(apiPath);
|
||||
client.DefaultRequestHeaders.Add("api-key", apiKey);
|
||||
var _res = await client.GetAsync(apiPath,cancellationToken: combinedCts.Token);
|
||||
if (_res.IsSuccessStatusCode)
|
||||
{
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
|
|
@ -77,10 +80,13 @@ namespace BMA.EHR.Application.Repositories
|
|||
}
|
||||
}
|
||||
|
||||
protected async Task<string> SendExternalAPIAsync(HttpMethod method, string apiPath, string accessToken, object? body, string apiKey)
|
||||
protected async Task<string> SendExternalAPIAsync(HttpMethod method, string apiPath, string accessToken, object? body, string apiKey, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
// กำหนด timeout เป็น 30 นาที
|
||||
using var timeoutCts = new CancellationTokenSource(TimeSpan.FromMinutes(30));
|
||||
using var combinedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutCts.Token);
|
||||
// สร้าง request message
|
||||
var request = new HttpRequestMessage(method, apiPath);
|
||||
|
||||
|
|
@ -91,8 +97,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
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);
|
||||
client.DefaultRequestHeaders.Add("api-key", apiKey);
|
||||
var _res = await client.SendAsync(request, combinedCts.Token);
|
||||
if (_res.IsSuccessStatusCode)
|
||||
{
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
|
|
@ -109,10 +115,13 @@ namespace BMA.EHR.Application.Repositories
|
|||
}
|
||||
|
||||
|
||||
protected async Task<string> PostExternalAPIAsync(string apiPath, string accessToken, object? body, string apiKey)
|
||||
public async Task<string> PostExternalAPIAsync(string apiPath, string accessToken, object? body, string apiKey, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
// กำหนด timeout เป็น 30 นาที
|
||||
using var timeoutCts = new CancellationTokenSource(TimeSpan.FromMinutes(30));
|
||||
using var combinedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutCts.Token);
|
||||
var json = JsonConvert.SerializeObject(body);
|
||||
var stringContent = new StringContent(json, Encoding.UTF8, "application/json");
|
||||
//stringContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
|
||||
|
|
@ -120,8 +129,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
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);
|
||||
client.DefaultRequestHeaders.Add("api-key", apiKey);
|
||||
var _res = await client.PostAsync(apiPath, stringContent, combinedCts.Token);
|
||||
if (_res.IsSuccessStatusCode)
|
||||
{
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
|
|
@ -137,10 +146,13 @@ namespace BMA.EHR.Application.Repositories
|
|||
}
|
||||
}
|
||||
|
||||
protected async Task<bool> PostExternalAPIBooleanAsync(string apiPath, string accessToken, object? body, string apiKey)
|
||||
protected async Task<bool> PostExternalAPIBooleanAsync(string apiPath, string accessToken, object? body, string apiKey, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
// กำหนด timeout เป็น 30 นาที
|
||||
using var timeoutCts = new CancellationTokenSource(TimeSpan.FromMinutes(30));
|
||||
using var combinedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutCts.Token);
|
||||
var json = JsonConvert.SerializeObject(body);
|
||||
var stringContent = new StringContent(json, UnicodeEncoding.UTF8, "application/json");
|
||||
stringContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
|
||||
|
|
@ -148,8 +160,8 @@ namespace BMA.EHR.Application.Repositories
|
|||
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);
|
||||
client.DefaultRequestHeaders.Add("api-key", apiKey);
|
||||
var _res = await client.PostAsync(apiPath, stringContent, combinedCts.Token);
|
||||
return _res.IsSuccessStatusCode;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -2,8 +2,11 @@
|
|||
using BMA.EHR.Domain.Models.Base;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Newtonsoft.Json;
|
||||
using System.IO.Pipes;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Security.Claims;
|
||||
using System.Text;
|
||||
|
||||
namespace BMA.EHR.Application.Repositories.Leaves
|
||||
{
|
||||
|
|
@ -43,6 +46,38 @@ namespace BMA.EHR.Application.Repositories.Leaves
|
|||
|
||||
#region " Methods "
|
||||
|
||||
public async Task<string> PostExternalAPIAsync(string apiPath, string accessToken, object? body, string apiKey, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
// กำหนด timeout เป็น 30 นาที
|
||||
using var timeoutCts = new CancellationTokenSource(TimeSpan.FromMinutes(30));
|
||||
using var combinedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutCts.Token);
|
||||
var json = JsonConvert.SerializeObject(body);
|
||||
var stringContent = new StringContent(json, Encoding.UTF8, "application/json");
|
||||
//stringContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
|
||||
|
||||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api-key", apiKey);
|
||||
var _res = await client.PostAsync(apiPath, stringContent, combinedCts.Token);
|
||||
if (_res.IsSuccessStatusCode)
|
||||
{
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
|
||||
return _result;
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public virtual async Task<IReadOnlyList<T>> GetAllAsync()
|
||||
{
|
||||
return await _dbSet.ToListAsync();
|
||||
|
|
@ -68,6 +103,24 @@ namespace BMA.EHR.Application.Repositories.Leaves
|
|||
return entity;
|
||||
}
|
||||
|
||||
public virtual async Task<IReadOnlyList<T>> AddRangeAsync(List<T> entities)
|
||||
{
|
||||
foreach (var entity in entities)
|
||||
{
|
||||
if (entity is EntityBase)
|
||||
{
|
||||
(entity as EntityBase).CreatedUserId = UserId ?? "";
|
||||
(entity as EntityBase).CreatedFullName = FullName ?? "System Administrator";
|
||||
(entity as EntityBase).CreatedAt = DateTime.Now;
|
||||
}
|
||||
}
|
||||
|
||||
await _dbSet.AddRangeAsync(entities);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
|
||||
return entities;
|
||||
}
|
||||
|
||||
public virtual async Task<T> UpdateAsync(T entity)
|
||||
{
|
||||
if (entity is EntityBase)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
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;
|
||||
|
|
@ -8,6 +9,7 @@ using BMA.EHR.Domain.Shared;
|
|||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
||||
{
|
||||
|
|
@ -22,6 +24,12 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
private readonly IConfiguration _configuration;
|
||||
private readonly EmailSenderService _emailSenderService;
|
||||
|
||||
/// <summary>
|
||||
/// Keyed locks to serialize get-or-create for LeaveBeginning rows by (ProfileId, LeaveYear, LeaveTypeId).
|
||||
/// Prevents duplicate inserts when concurrent requests (e.g. UI calling /user/check twice) hit the same key.
|
||||
/// </summary>
|
||||
private static readonly ConcurrentDictionary<string, SemaphoreSlim> _getOrAddLocks = new();
|
||||
|
||||
#endregion
|
||||
|
||||
#region " Constructor and Destuctor "
|
||||
|
|
@ -78,7 +86,8 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
|
||||
public async Task UpdateLeaveUsageAsync(int year, Guid typeId, Guid userId, double day)
|
||||
{
|
||||
var pf = await _userProfileRepository.GetProfileByKeycloakIdAsync(userId, AccessToken);
|
||||
// var pf = await _userProfileRepository.GetProfileByKeycloakIdAsync(userId, AccessToken);
|
||||
var pf = await _userProfileRepository.GetProfileByKeycloakIdNew2Async(userId, AccessToken);
|
||||
if (pf == null)
|
||||
{
|
||||
throw new Exception(GlobalMessages.DataNotFound);
|
||||
|
|
@ -88,7 +97,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
.Include(x => x.LeaveType)
|
||||
.FirstOrDefaultAsync(x => x.LeaveYear == year && x.LeaveTypeId == typeId && x.ProfileId == pf.Id);
|
||||
|
||||
if(data == null)
|
||||
if (data == null)
|
||||
{
|
||||
throw new Exception(GlobalMessages.DataNotFound);
|
||||
}
|
||||
|
|
@ -97,10 +106,56 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task UpdateLeaveCountAsync(int year, Guid typeId, Guid userId, int count)
|
||||
{
|
||||
// var pf = await _userProfileRepository.GetProfileByKeycloakIdAsync(userId, AccessToken);
|
||||
var pf = await _userProfileRepository.GetProfileByKeycloakIdNew2Async(userId, AccessToken);
|
||||
if (pf == null)
|
||||
{
|
||||
throw new Exception(GlobalMessages.DataNotFound);
|
||||
}
|
||||
|
||||
var data = await _dbContext.Set<LeaveBeginning>()
|
||||
.Include(x => x.LeaveType)
|
||||
.FirstOrDefaultAsync(x => x.LeaveYear == year && x.LeaveTypeId == typeId && x.ProfileId == pf.Id);
|
||||
|
||||
if (data == null)
|
||||
{
|
||||
throw new Exception(GlobalMessages.DataNotFound);
|
||||
}
|
||||
data.LeaveCount += count;
|
||||
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task ProcessEarlyLeaveRequest(int year)
|
||||
{
|
||||
// Get Early Leave Request (กรองตามปีงบประมาณ: 1 ต.ค. (year-1) – 30 ก.ย. (year))
|
||||
var fiscalStart = new DateTime(year - 1, 10, 1);
|
||||
var fiscalEnd = new DateTime(year, 9, 30);
|
||||
|
||||
var leaveReq = await _dbContext.Set<LeaveRequest>()
|
||||
.Include(x => x.Type)
|
||||
.Where(x => x.LeaveStatus == "APPROVE")
|
||||
.Where(x => x.LeaveStartDate.Date <= fiscalEnd && x.LeaveEndDate.Date >= fiscalStart)
|
||||
.ToListAsync();
|
||||
|
||||
foreach (var leave in leaveReq)
|
||||
{
|
||||
await GetByYearAndTypeIdForUserWithUpdateAsync(year, leave.Type.Id, leave.KeycloakUserId);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task ProcessEarlyLeaveRequestSchedule()
|
||||
{
|
||||
int year = DateTime.Now.Year;
|
||||
await ProcessEarlyLeaveRequest(year);
|
||||
}
|
||||
|
||||
public async Task<LeaveBeginning?> GetByYearAndTypeIdForUserAsync(int year, Guid typeId, Guid userId)
|
||||
{
|
||||
var pf = await _userProfileRepository.GetProfileByKeycloakIdAsync(userId, AccessToken);
|
||||
// var pf = await _userProfileRepository.GetProfileByKeycloakIdAsync(userId, AccessToken);
|
||||
var pf = await _userProfileRepository.GetProfileByKeycloakIdNew2Async(userId, AccessToken);
|
||||
if (pf == null)
|
||||
{
|
||||
throw new Exception(GlobalMessages.DataNotFound);
|
||||
|
|
@ -110,9 +165,348 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
|
||||
var leaveType = await _dbContext.Set<LeaveType>().FirstOrDefaultAsync(x => x.Id == typeId);
|
||||
|
||||
var data = await _dbContext.Set<LeaveBeginning>()
|
||||
LeaveBeginning Factory()
|
||||
{
|
||||
var limit = 0.0;
|
||||
|
||||
var prev = _dbContext.Set<LeaveBeginning>()
|
||||
.Include(x => x.LeaveType)
|
||||
.FirstOrDefaultAsync(x => x.LeaveYear == year && x.LeaveTypeId == typeId && x.ProfileId == pf.Id);
|
||||
.FirstOrDefault(x => x.LeaveYear == year - 1 && x.LeaveTypeId == typeId && x.ProfileId == pf.Id);
|
||||
|
||||
// คำนวณปีงบประมาณจาก startDate (ปีงบประมาณเริ่ม 1 ต.ค. และสิ้นสุด 30 ก.ย.)
|
||||
var isCurrentYear = DateTime.Now.Year == year;
|
||||
|
||||
|
||||
var prevRemain = 0.0;
|
||||
if (prev != null)
|
||||
{
|
||||
prevRemain = 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)
|
||||
{
|
||||
|
|
@ -125,7 +519,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
var prevRemain = 0.0;
|
||||
if (prev != null)
|
||||
{
|
||||
prevRemain = prev.LeaveDays - prev.LeaveDaysUsed;
|
||||
prevRemain = prev.LeaveDays - (prev.LeaveDaysUsed ?? 0.0);
|
||||
}
|
||||
|
||||
if (govAge >= 180)
|
||||
|
|
@ -155,15 +549,39 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
FirstName = pf.FirstName,
|
||||
LastName = pf.LastName,
|
||||
LeaveDaysUsed = 0,
|
||||
LeaveDays = leaveType?.Code == "LV-005" ? limit : 0
|
||||
LeaveDays = leaveType?.Code == "LV-005" ? limit : 0,
|
||||
RootDnaId = profile.RootDnaId,
|
||||
Child1DnaId = profile.Child1DnaId,
|
||||
Child2DnaId = profile.Child2DnaId,
|
||||
Child3DnaId = profile.Child3DnaId,
|
||||
Child4DnaId = profile.Child4DnaId
|
||||
};
|
||||
|
||||
_dbContext.Set<LeaveBeginning>().Add(data);
|
||||
updateList.Add(data);
|
||||
}
|
||||
result.Add(data);
|
||||
}
|
||||
if (!updateList.Any())
|
||||
{
|
||||
await _dbContext.Set<LeaveBeginning>().AddRangeAsync(updateList);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
return data;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,8 +8,11 @@ using BMA.EHR.Domain.Shared;
|
|||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System.IO.Compression;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Net.Http.Json;
|
||||
using BMA.EHR.Application.Repositories.Leaves.TimeAttendants;
|
||||
using BMA.EHR.Domain.Models.Leave.TimeAttendants;
|
||||
|
||||
namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
||||
{
|
||||
|
|
@ -28,6 +31,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
private readonly MinIOLeaveService _minIOService;
|
||||
|
||||
private readonly LeaveBeginningRepository _leaveBeginningRepository;
|
||||
private readonly ProcessUserTimeStampRepository _processUserTimeStampRepository;
|
||||
|
||||
private readonly string URL = string.Empty;
|
||||
|
||||
|
|
@ -43,7 +47,8 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
EmailSenderService emailSenderService,
|
||||
IApplicationDBContext appDbContext,
|
||||
MinIOLeaveService minIOService,
|
||||
LeaveBeginningRepository leaveBeginningRepository) : base(dbContext, httpContextAccessor)
|
||||
LeaveBeginningRepository leaveBeginningRepository,
|
||||
ProcessUserTimeStampRepository processUserTimeStampRepository) : base(dbContext, httpContextAccessor)
|
||||
{
|
||||
_dbContext = dbContext;
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
|
|
@ -57,6 +62,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
Console.WriteLine($"URL : {URL}");
|
||||
_minIOService = minIOService;
|
||||
_leaveBeginningRepository = leaveBeginningRepository;
|
||||
_processUserTimeStampRepository = processUserTimeStampRepository;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
@ -252,7 +258,8 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
|
||||
public async Task<List<LeaveRequest>> GetLeaveRequestByYearAsync(int year, Guid userId)
|
||||
{
|
||||
var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(userId, AccessToken);
|
||||
// var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(userId, AccessToken);
|
||||
var profile = await _userProfileRepository.GetProfileByKeycloakIdNew2Async(userId, AccessToken);
|
||||
|
||||
if (profile == null)
|
||||
{
|
||||
|
|
@ -273,6 +280,57 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
return data;
|
||||
}
|
||||
|
||||
public async Task<List<LeaveRequest>> GetLeaveRequestByYearForAdminAsync(int year, string role, string? nodeId, int? node)
|
||||
{
|
||||
var rawData = _dbContext.Set<LeaveRequest>().AsQueryable().AsNoTracking()
|
||||
.Include(x => x.Type)
|
||||
.Where(x => x.LeaveStatus != "REJECT" && x.LeaveStatus != "DELETE");
|
||||
//.ToListAsync();
|
||||
if (year != 0)
|
||||
{
|
||||
var startFiscalDate = new DateTime(year - 1, 10, 1);
|
||||
var endFiscalDate = new DateTime(year, 9, 30);
|
||||
rawData = rawData.Where(x => x.LeaveStartDate.Date >= startFiscalDate && x.LeaveStartDate.Date <= endFiscalDate);
|
||||
}
|
||||
|
||||
if (role == "OWNER")
|
||||
{
|
||||
node = null;
|
||||
}
|
||||
if (role == "OWNER" || role == "CHILD")
|
||||
{
|
||||
rawData = rawData
|
||||
.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))))));
|
||||
}
|
||||
else if (role == "BROTHER")
|
||||
{
|
||||
rawData = rawData
|
||||
.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)))));
|
||||
}
|
||||
else if (role == "ROOT")
|
||||
{
|
||||
rawData = rawData
|
||||
.Where(x => x.RootDnaId == Guid.Parse(nodeId!));
|
||||
}
|
||||
// else if (role == "PARENT")
|
||||
// {
|
||||
// rawData = rawData
|
||||
// .Where(x => x.RootDnaId == Guid.Parse(nodeId!) && x.Child1DnaId != null);
|
||||
// }
|
||||
else if (role == "NORMAL")
|
||||
{
|
||||
rawData = rawData
|
||||
.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);
|
||||
}
|
||||
|
||||
return await rawData.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<List<LeaveRequest>> GetLeaveRequestByUserIdAsync(Guid keycloakUserId, int year, Guid type, string status)
|
||||
{
|
||||
var rawData = _dbContext.Set<LeaveRequest>().AsQueryable().AsNoTracking()
|
||||
|
|
@ -280,7 +338,12 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
.Where(x => x.KeycloakUserId == keycloakUserId);
|
||||
|
||||
if (year != 0)
|
||||
rawData = rawData.Where(x => x.LeaveStartDate.Year == year);
|
||||
{
|
||||
var startFiscalDate = new DateTime(year - 1, 10, 1);
|
||||
var endFiscalDate = new DateTime(year, 9, 30);
|
||||
rawData = rawData.Where(x => x.LeaveStartDate.Date >= startFiscalDate && x.LeaveStartDate.Date <= endFiscalDate);
|
||||
}
|
||||
//rawData = rawData.Where(x => x.LeaveStartDate.Year == year);
|
||||
|
||||
if (type != Guid.Empty)
|
||||
rawData = rawData.Where(x => x.Type.Id == type);
|
||||
|
|
@ -296,7 +359,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
var rawData = _dbContext.Set<LeaveRequest>().AsNoTracking()
|
||||
.Include(x => x.Type)
|
||||
.Where(x => x.LeaveStatus != "DRAFT")
|
||||
.OrderByDescending(x => x.CreatedAt)
|
||||
.OrderByDescending(x => (x.DateSendLeave ?? x.CreatedAt))
|
||||
.AsQueryable();
|
||||
|
||||
if (year != 0)
|
||||
|
|
@ -322,11 +385,15 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
var rawData = _dbContext.Set<LeaveRequest>().AsNoTracking()
|
||||
.Include(x => x.Type)
|
||||
.Where(x => x.LeaveStatus != "DRAFT")
|
||||
.OrderByDescending(x => x.CreatedAt)
|
||||
.OrderByDescending(x => (x.DateSendLeave ?? x.CreatedAt))
|
||||
.AsQueryable();
|
||||
|
||||
// fix issue : 1830
|
||||
if (year != 0)
|
||||
rawData = rawData.Where(x => x.LeaveStartDate.Year == year);
|
||||
{
|
||||
var startFiscalDate = new DateTime(year - 1, 10, 1);
|
||||
var endFiscalDate = new DateTime(year, 9, 30);
|
||||
rawData = rawData.Where(x => x.LeaveStartDate >= startFiscalDate && x.LeaveStartDate <= endFiscalDate);
|
||||
}
|
||||
|
||||
if (type != Guid.Empty)
|
||||
rawData = rawData.Where(x => x.Type.Id == type);
|
||||
|
|
@ -349,15 +416,30 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
rawData = rawData
|
||||
.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))))));
|
||||
}
|
||||
else if (role == "BROTHER")
|
||||
{
|
||||
rawData = rawData
|
||||
.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)))));
|
||||
}
|
||||
else if (role == "ROOT")
|
||||
{
|
||||
rawData = rawData
|
||||
.Where(x => x.RootDnaId == Guid.Parse(nodeId!));
|
||||
}
|
||||
// else if (role == "PARENT")
|
||||
// {
|
||||
// rawData = rawData
|
||||
// .Where(x => x.RootDnaId == Guid.Parse(nodeId!) && x.Child1DnaId != null);
|
||||
// }
|
||||
else if (role == "NORMAL")
|
||||
{
|
||||
rawData = rawData
|
||||
.Where(x => node == 0 ? x.Child1DnaId == null : (node == 1 ? x.Child2DnaId == null : (node == 2 ? x.Child3DnaId == null : (node == 3 ? x.Child4DnaId == null : true))));
|
||||
.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);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -370,7 +452,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
.Include(x => x.Type)
|
||||
.Where(x => keycloakIdList.Contains(x.KeycloakUserId))
|
||||
.Where(x => x.LeaveStatus != "DRAFT")
|
||||
.OrderByDescending(x => x.CreatedAt)
|
||||
.OrderByDescending(x =>(x.DateSendLeave ?? x.CreatedAt))
|
||||
.AsQueryable();
|
||||
|
||||
if (year != 0)
|
||||
|
|
@ -419,7 +501,8 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
|
||||
public async Task<double> GetSumLeaveByTypeForUserAsync(Guid keycloakUserId, Guid leaveTypeId, int year)
|
||||
{
|
||||
var pf = await _userProfileRepository.GetProfileByKeycloakIdAsync(keycloakUserId, AccessToken);
|
||||
// var pf = await _userProfileRepository.GetProfileByKeycloakIdAsync(keycloakUserId, AccessToken);
|
||||
var pf = await _userProfileRepository.GetProfileByKeycloakIdNew2Async(keycloakUserId, AccessToken);
|
||||
if (pf == null)
|
||||
throw new Exception(GlobalMessages.DataNotFound);
|
||||
|
||||
|
|
@ -444,7 +527,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
//.Where(x => x.LeaveStatus != "REJECT" && x.LeaveStatus != "DELETE")
|
||||
.ToListAsync();
|
||||
|
||||
return data.Sum(x => x.LeaveTotal) + (beginningLeave == null ? 0 : beginningLeave.LeaveDaysUsed);
|
||||
return data.Sum(x => x.LeaveTotal) + (beginningLeave == null ? 0 : (beginningLeave.LeaveDaysUsed ?? 0.0));
|
||||
}
|
||||
|
||||
//public async Task<double> GetSumApproveLeaveByTypeForUserAsync(Guid keycloakUserId, Guid leaveTypeId, int year)
|
||||
|
|
@ -475,11 +558,12 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
return data;
|
||||
}
|
||||
|
||||
public async Task<LeaveRequest?> GetLastLeaveRequestByTypeForUserAsync(Guid keycloakUserId, Guid leaveTypeId,DateTime beforeDate)
|
||||
public async Task<LeaveRequest?> GetLastLeaveRequestByTypeForUserAsync(Guid keycloakUserId, Guid leaveTypeId, DateTime beforeDate)
|
||||
{
|
||||
var data = await _dbContext.Set<LeaveRequest>().AsQueryable().AsNoTracking()
|
||||
.Include(x => x.Type)
|
||||
.Where(x => x.LeaveStartDate.Date < beforeDate.Date)
|
||||
//.Where(x => x.CreatedAt < beforeDate)
|
||||
.Where(x => x.KeycloakUserId == keycloakUserId)
|
||||
.Where(x => x.Type.Id == leaveTypeId)
|
||||
.Where(x => x.LeaveStatus == "APPROVE" || x.LeaveStatus == "DELETING")
|
||||
|
|
@ -490,6 +574,22 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
return data;
|
||||
}
|
||||
|
||||
public async Task<LeaveRequest?> GetLastLeaveRequestByTypeForUserAsync2(Guid keycloakUserId, Guid leaveTypeId, DateTime beforeDate)
|
||||
{
|
||||
var data = await _dbContext.Set<LeaveRequest>().AsQueryable().AsNoTracking()
|
||||
.Include(x => x.Type)
|
||||
//.Where(x => x.LeaveStartDate.Date < beforeDate.Date)
|
||||
.Where(x => (x.DateSendLeave ?? x.CreatedAt) < beforeDate)
|
||||
.Where(x => x.KeycloakUserId == keycloakUserId)
|
||||
.Where(x => x.Type.Id == leaveTypeId)
|
||||
.Where(x => x.LeaveStatus == "APPROVE" || x.LeaveStatus == "DELETING")
|
||||
//.Where(x => x.LeaveStatus != "REJECT" && x.LeaveStatus != "DELETE")
|
||||
.OrderByDescending(x => (x.DateSendLeave ?? x.CreatedAt))
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public async Task<List<LeaveRequest>> GetCancelLeaveRequestForAdminAsync(int year, Guid type, string status, string role, string? nodeId, int? node)
|
||||
{
|
||||
var rawData = _dbContext.Set<LeaveRequest>().AsNoTracking()
|
||||
|
|
@ -497,8 +597,14 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
.Where(x => x.LeaveStatus == "DELETE" || x.LeaveStatus == "DELETING")
|
||||
.AsQueryable();
|
||||
|
||||
// if (year != 0)
|
||||
// rawData = rawData.Where(x => x.LeaveStartDate.Year == year);
|
||||
if (year != 0)
|
||||
rawData = rawData.Where(x => x.LeaveStartDate.Year == year);
|
||||
{
|
||||
var startFiscalDate = new DateTime(year - 1, 10, 1);
|
||||
var endFiscalDate = new DateTime(year, 9, 30);
|
||||
rawData = rawData.Where(x => x.LeaveStartDate.Date >= startFiscalDate && x.LeaveStartDate.Date <= endFiscalDate);
|
||||
}
|
||||
|
||||
if (type != Guid.Empty)
|
||||
rawData = rawData.Where(x => x.Type.Id == type);
|
||||
|
|
@ -516,15 +622,30 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
rawData = rawData
|
||||
.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))))));
|
||||
}
|
||||
else if (role == "BROTHER")
|
||||
{
|
||||
rawData = rawData
|
||||
.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)))));
|
||||
}
|
||||
else if (role == "ROOT")
|
||||
{
|
||||
rawData = rawData
|
||||
.Where(x => x.RootDnaId == Guid.Parse(nodeId!));
|
||||
}
|
||||
// else if (role == "PARENT")
|
||||
// {
|
||||
// rawData = rawData
|
||||
// .Where(x => x.RootDnaId == Guid.Parse(nodeId!) && x.Child1DnaId != null);
|
||||
// }
|
||||
else if (role == "NORMAL")
|
||||
{
|
||||
rawData = rawData
|
||||
.Where(x => node == 0 ? x.Child1DnaId == null : (node == 1 ? x.Child2DnaId == null : (node == 2 ? x.Child3DnaId == null : (node == 3 ? x.Child4DnaId == null : true))));
|
||||
.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);
|
||||
}
|
||||
|
||||
return await rawData.ToListAsync();
|
||||
|
|
@ -534,7 +655,8 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
{
|
||||
try
|
||||
{
|
||||
var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(data.KeycloakUserId, AccessToken ?? "");
|
||||
// var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(data.KeycloakUserId, AccessToken ?? "");
|
||||
var profile = await _userProfileRepository.GetProfileByKeycloakIdNew2Async(data.KeycloakUserId, AccessToken ?? "");
|
||||
if (profile == null)
|
||||
{
|
||||
throw new Exception(GlobalMessages.DataNotFound);
|
||||
|
|
@ -551,14 +673,24 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
// TODO : Update ไปตาราง beginning
|
||||
if (data.ApproveStep == "st4") // ถ้ามีการอนุมัติจากผู้มีอำนาจแล้ว
|
||||
{
|
||||
await _leaveBeginningRepository.UpdateLeaveUsageAsync(data.LeaveStartDate.Year, data.Type.Id, data.KeycloakUserId, -1 * data.LeaveTotal);
|
||||
|
||||
var toDay = data.LeaveStartDate.Date;
|
||||
var thisYear = data.LeaveStartDate.Year;
|
||||
if (toDay >= new DateTime(thisYear, 10, 1) && toDay <= new DateTime(thisYear, 12, 31))
|
||||
{
|
||||
thisYear = thisYear + 1;
|
||||
}
|
||||
await _leaveBeginningRepository.UpdateLeaveUsageAsync(thisYear, data.Type.Id, data.KeycloakUserId, -1 * data.LeaveTotal);
|
||||
// update leave count ลดลง 1 ครั้ง
|
||||
await _leaveBeginningRepository.UpdateLeaveCountAsync(thisYear, data.Type.Id, data.KeycloakUserId, -1);
|
||||
|
||||
|
||||
var _baseAPI = _configuration["API"];
|
||||
var apiUrlSalary = $"{_baseAPI}/org/profile/leave/cancel/{data.Id}";
|
||||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
|
||||
var request = new HttpRequestMessage(HttpMethod.Patch, apiUrlSalary);
|
||||
|
||||
|
|
@ -600,7 +732,8 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
throw new Exception(GlobalMessages.DataNotFound);
|
||||
}
|
||||
|
||||
var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(rawData.KeycloakUserId, AccessToken ?? "");
|
||||
// var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(rawData.KeycloakUserId, AccessToken ?? "");
|
||||
var profile = await _userProfileRepository.GetProfileByKeycloakIdNew2Async(rawData.KeycloakUserId, AccessToken ?? "");
|
||||
if (profile == null)
|
||||
{
|
||||
throw new Exception(GlobalMessages.DataNotFound);
|
||||
|
|
@ -616,14 +749,24 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
// TODO : Update ไปตาราง beginning
|
||||
if (rawData.ApproveStep == "st4") // ถ้ามีการอนุมัติจากผู้มีอำนาจแล้ว
|
||||
{
|
||||
await _leaveBeginningRepository.UpdateLeaveUsageAsync(rawData.LeaveStartDate.Year, rawData.Type.Id, rawData.KeycloakUserId, -1 * rawData.LeaveTotal);
|
||||
|
||||
var toDay = rawData.LeaveStartDate.Date;
|
||||
var thisYear = rawData.LeaveStartDate.Year;
|
||||
if (toDay >= new DateTime(thisYear, 10, 1) && toDay <= new DateTime(thisYear, 12, 31))
|
||||
{
|
||||
thisYear = thisYear + 1;
|
||||
}
|
||||
|
||||
await _leaveBeginningRepository.UpdateLeaveUsageAsync(thisYear, rawData.Type.Id, rawData.KeycloakUserId, -1 * rawData.LeaveTotal);
|
||||
// update leave count ลดลง 1 ครั้ง
|
||||
await _leaveBeginningRepository.UpdateLeaveCountAsync(thisYear, rawData.Type.Id, rawData.KeycloakUserId, -1);
|
||||
|
||||
var _baseAPI = _configuration["API"];
|
||||
var apiUrlSalary = $"{_baseAPI}/org/profile/leave/cancel/{rawData.Id}";
|
||||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
|
||||
var request = new HttpRequestMessage(HttpMethod.Patch, apiUrlSalary);
|
||||
|
||||
|
|
@ -652,7 +795,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
.OrderBy(x => x.Seq)
|
||||
.ToList();
|
||||
|
||||
foreach(var commander in commanders)
|
||||
foreach (var commander in commanders)
|
||||
{
|
||||
var noti1 = new Notification
|
||||
{
|
||||
|
|
@ -678,7 +821,8 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
throw new Exception(GlobalMessages.DataNotFound);
|
||||
}
|
||||
|
||||
var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(rawData.KeycloakUserId, AccessToken ?? "");
|
||||
// var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(rawData.KeycloakUserId, AccessToken ?? "");
|
||||
var profile = await _userProfileRepository.GetProfileByKeycloakIdNew2Async(rawData.KeycloakUserId, AccessToken ?? "");
|
||||
if (profile == null)
|
||||
{
|
||||
throw new Exception(GlobalMessages.DataNotFound);
|
||||
|
|
@ -765,6 +909,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
|
||||
|
||||
rawData.LeaveStatus = "NEW";
|
||||
rawData.DateSendLeave = DateTime.Now; // Update วันที่ยื่นลาเป็นวันที่ปัจจุบัน
|
||||
//rawData.ApproveStep = "st2";
|
||||
|
||||
await UpdateAsync(rawData);
|
||||
|
|
@ -788,6 +933,10 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
.Where(x => x.ApproveType!.ToUpper() == "COMMANDER")
|
||||
.OrderBy(x => x.Seq)
|
||||
.FirstOrDefault();
|
||||
|
||||
// fix: If no commander, skip notification
|
||||
if (firstCommander != null)
|
||||
{
|
||||
// Send Notification
|
||||
var noti1 = new Notification
|
||||
{
|
||||
|
|
@ -797,6 +946,27 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
Payload = $"{URL}/leave/detail/{id}",
|
||||
};
|
||||
_appDbContext.Set<Notification>().Add(noti1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// มีแต่ approver อย่างเดียว
|
||||
var firstApprover = rawData.Approvers
|
||||
.Where(x => x.ApproveType!.ToUpper() == "APPROVER")
|
||||
.OrderBy(x => x.Seq)
|
||||
.FirstOrDefault();
|
||||
if(firstApprover != null)
|
||||
{
|
||||
// Send Notification
|
||||
var noti2 = new Notification
|
||||
{
|
||||
Body = $"การขอลาของคุณ {rawData.FirstName} {rawData.LastName} รอรับการอนุมัติจากคุณ",
|
||||
ReceiverUserId = firstApprover!.ProfileId,
|
||||
Type = "",
|
||||
Payload = $"{URL}/leave/detail/{id}",
|
||||
};
|
||||
_appDbContext.Set<Notification>().Add(noti2);
|
||||
}
|
||||
}
|
||||
await _appDbContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
|
|
@ -866,7 +1036,9 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
|
||||
approver.ApproveStatus = "APPROVE";
|
||||
approver.Comment = reason;
|
||||
|
||||
approver.LastUpdateFullName = FullName ?? "";
|
||||
approver.LastUpdateUserId = userId.ToString("D");
|
||||
approver.LastUpdatedAt = DateTime.Now;
|
||||
//await _dbContext.SaveChangesAsync();
|
||||
|
||||
if (approver.Seq != maxSeq)
|
||||
|
|
@ -956,7 +1128,9 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
|
||||
approver.ApproveStatus = "REJECT";
|
||||
approver.Comment = reason;
|
||||
|
||||
approver.LastUpdateFullName = FullName ?? "";
|
||||
approver.LastUpdateUserId = userId.ToString("D");
|
||||
approver.LastUpdatedAt = DateTime.Now;
|
||||
if (approver.Seq != maxSeq)
|
||||
{
|
||||
|
||||
|
|
@ -1014,10 +1188,18 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
throw new Exception(GlobalMessages.DataNotFound);
|
||||
}
|
||||
|
||||
// ถ้าไม่มี commander ข้ามไปเช็ค approver ได้เลย
|
||||
var commanders = rawData.Approvers
|
||||
.Where(x => x.ApproveType!.ToUpper() == "COMMANDER")
|
||||
.OrderBy(x => x.Seq)
|
||||
.ToList();
|
||||
if (commanders.Count > 0 && commanders != null)
|
||||
{
|
||||
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();
|
||||
|
|
@ -1044,7 +1226,9 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
|
||||
approver.ApproveStatus = "APPROVE";
|
||||
approver.Comment = reason;
|
||||
|
||||
approver.LastUpdateFullName = FullName ?? "";
|
||||
approver.LastUpdateUserId = userId.ToString("D");
|
||||
approver.LastUpdatedAt = DateTime.Now;
|
||||
if (approver.Seq != maxSeq)
|
||||
{
|
||||
var nextApprover = approvers.FirstOrDefault(x => x.Seq == approver.Seq + 1);
|
||||
|
|
@ -1063,7 +1247,8 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
}
|
||||
else
|
||||
{
|
||||
var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(rawData.KeycloakUserId, AccessToken);
|
||||
// var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(rawData.KeycloakUserId, AccessToken);
|
||||
var profile = await _userProfileRepository.GetProfileByKeycloakIdNew2Async(rawData.KeycloakUserId, AccessToken);
|
||||
if (profile == null)
|
||||
{
|
||||
throw new Exception(GlobalMessages.DataNotFound);
|
||||
|
|
@ -1075,8 +1260,17 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
|
||||
await UpdateWithTrackingAsync(rawData);
|
||||
|
||||
var toDay = rawData.LeaveStartDate.Date;
|
||||
var thisYear = rawData.LeaveStartDate.Year;
|
||||
if (toDay >= new DateTime(thisYear, 10, 1) && toDay <= new DateTime(thisYear, 12, 31))
|
||||
{
|
||||
thisYear = thisYear + 1;
|
||||
}
|
||||
|
||||
// TODO : Update ไปตาราง beginning
|
||||
await _leaveBeginningRepository.UpdateLeaveUsageAsync(rawData.LeaveStartDate.Year, rawData.Type.Id, rawData.KeycloakUserId, rawData.LeaveTotal);
|
||||
await _leaveBeginningRepository.UpdateLeaveUsageAsync(thisYear, rawData.Type.Id, rawData.KeycloakUserId, rawData.LeaveTotal);
|
||||
// update leave count เพิ่มขึ้น 1 ครั้ง
|
||||
await _leaveBeginningRepository.UpdateLeaveCountAsync(thisYear, rawData.Type.Id, rawData.KeycloakUserId, 1);
|
||||
|
||||
|
||||
var _baseAPI = _configuration["API"];
|
||||
|
|
@ -1087,7 +1281,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlSalary, new
|
||||
{
|
||||
profileId = profile.Id,
|
||||
|
|
@ -1100,6 +1294,8 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
status = "approve",
|
||||
reason = rawData.LeaveDetail,
|
||||
leaveId = rawData.Id,
|
||||
leaveSubTypeName = rawData.LeaveSubTypeName,
|
||||
coupleDayLevelCountry = rawData.CoupleDayLevelCountry,
|
||||
});
|
||||
// var _result = await _res.Content.ReadAsStringAsync();
|
||||
}
|
||||
|
|
@ -1110,7 +1306,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlSalary, new
|
||||
{
|
||||
profileEmployeeId = profile.Id,
|
||||
|
|
@ -1123,6 +1319,8 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
status = "approve",
|
||||
reason = rawData.LeaveDetail,
|
||||
leaveId = rawData.Id,
|
||||
leaveSubTypeName = rawData.LeaveSubTypeName,
|
||||
coupleDayLevelCountry = rawData.CoupleDayLevelCountry,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1132,9 +1330,68 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
}
|
||||
await _appDbContext.SaveChangesAsync();
|
||||
|
||||
// insert to process timestamp
|
||||
// ปรับสถานะการลงเวลา
|
||||
if (rawData.LeaveStartDate.Date == rawData.LeaveEndDate.Date)
|
||||
{
|
||||
var processCheckIn = await _dbContext.Set<ProcessUserTimeStamp>()
|
||||
.Where(x => x.KeycloakUserId == rawData.KeycloakUserId)
|
||||
.Where(x => x.CheckIn.Date == rawData.LeaveStartDate.Date)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
|
||||
if (processCheckIn is not null)
|
||||
{
|
||||
switch (rawData.LeaveRange.Trim().ToUpper())
|
||||
{
|
||||
case "MORNING":
|
||||
processCheckIn.CheckInStatus = "NORMAL";
|
||||
break;
|
||||
case "AFTERNOON":
|
||||
processCheckIn.CheckOutStatus = "NORMAL";
|
||||
break;
|
||||
case "ALL":
|
||||
processCheckIn.CheckInStatus = "NORMAL";
|
||||
processCheckIn.CheckOutStatus = "NORMAL";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
var from = rawData.LeaveStartDate.Date;
|
||||
var to = rawData.LeaveEndDate.Date;
|
||||
for (var day = from.Date; day <= to.Date; day = day.AddDays(1))
|
||||
{
|
||||
var processCheckIn = await _dbContext.Set<ProcessUserTimeStamp>()
|
||||
.Where(x => x.KeycloakUserId == rawData.KeycloakUserId)
|
||||
.Where(x => x.CheckIn.Date == day.Date)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
if (processCheckIn is not null)
|
||||
{
|
||||
switch (rawData.LeaveRange.Trim().ToUpper())
|
||||
{
|
||||
case "MORNING":
|
||||
processCheckIn.CheckInStatus = "NORMAL";
|
||||
break;
|
||||
case "AFTERNOON":
|
||||
processCheckIn.CheckOutStatus = "NORMAL";
|
||||
break;
|
||||
case "ALL":
|
||||
processCheckIn.CheckInStatus = "NORMAL";
|
||||
processCheckIn.CheckOutStatus = "NORMAL";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
await _dbContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
// Send Noti
|
||||
var noti = new Notification
|
||||
{
|
||||
|
|
@ -1160,10 +1417,18 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
throw new Exception(GlobalMessages.DataNotFound);
|
||||
}
|
||||
|
||||
// ถ้าไม่มี commander ข้ามไปเช็ค approver ได้เลย
|
||||
var commanders = rawData.Approvers
|
||||
.Where(x => x.ApproveType!.ToUpper() == "COMMANDER")
|
||||
.OrderBy(x => x.Seq)
|
||||
.ToList();
|
||||
if (commanders.Count > 0 && commanders != null)
|
||||
{
|
||||
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();
|
||||
|
|
@ -1190,7 +1455,9 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
|
||||
approver.ApproveStatus = "REJECT";
|
||||
approver.Comment = reason;
|
||||
|
||||
approver.LastUpdateFullName = FullName ?? "";
|
||||
approver.LastUpdateUserId = userId.ToString("D");
|
||||
approver.LastUpdatedAt = DateTime.Now;
|
||||
if (approver.Seq != maxSeq)
|
||||
{
|
||||
var nextApprover = approvers.FirstOrDefault(x => x.Seq == approver.Seq + 1);
|
||||
|
|
@ -1209,7 +1476,8 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
}
|
||||
else
|
||||
{
|
||||
var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(rawData.KeycloakUserId, AccessToken);
|
||||
// var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(rawData.KeycloakUserId, AccessToken);
|
||||
var profile = await _userProfileRepository.GetProfileByKeycloakIdNew2Async(rawData.KeycloakUserId, AccessToken);
|
||||
if (profile == null)
|
||||
{
|
||||
throw new Exception(GlobalMessages.DataNotFound);
|
||||
|
|
@ -1282,7 +1550,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
KeycloakUserId = pf.Keycloak == null ? Guid.Empty : pf.Keycloak.Value,
|
||||
LeaveTypeId = b.LeaveTypeId,
|
||||
LeaveTypeCode = b.LeaveType!.Code,
|
||||
SumLeaveDay = b.LeaveDaysUsed
|
||||
SumLeaveDay = b.LeaveDaysUsed ?? 0.0
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1454,7 +1722,8 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
KeycloakUserId = grp.Key.KeycloakUserId,
|
||||
LeaveTypeId = grp.Key.LeaveTypeId,
|
||||
LeaveTypeCode = grp.Key.LeaveTypeCode,
|
||||
SumLeaveDay = grp.Sum(x => x.LeaveTotal)
|
||||
SumLeaveDay = grp.Sum(x => x.LeaveTotal),
|
||||
CountLeaveDay = grp.Count()
|
||||
})
|
||||
.ToList();
|
||||
|
||||
|
|
@ -1463,38 +1732,14 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
|
||||
public async Task<List<GetSumApproveLeaveByRootDto>> GetSumApproveLeaveByRootAndRange(DateTime startDate, DateTime endDate, string type, string role, string? nodeId, int? node, string? nodeIdByReq, int? nodeByReq)
|
||||
{
|
||||
// var _nodeId = Guid.Parse(nodeId);
|
||||
var data = new List<LeaveRequest>();
|
||||
//if (role == "OWNER" || role == "CHILD")
|
||||
//{
|
||||
// data = await _dbContext.Set<LeaveRequest>().AsQueryable()
|
||||
// .Include(x => x.Type)
|
||||
// .Where(x => x.ProfileType == type.Trim().ToUpper())
|
||||
// .Where(x => x.LeaveStartDate.Date >= startDate.Date && x.LeaveStartDate.Date <= endDate.Date)
|
||||
// .Where(x => node == 4 ? x.Child4Id == Guid.Parse(nodeId) : (node == 3 ? x.Child3Id == Guid.Parse(nodeId) : (node == 2 ? x.Child2Id == Guid.Parse(nodeId) : (node == 1 ? x.Child1Id == Guid.Parse(nodeId) : (node == 0 ? x.RootId == Guid.Parse(nodeId) : (node == null ? true : true))))))
|
||||
// .Where(x => x.LeaveStatus == "APPROVE" || x.LeaveStatus == "DELETING").ToListAsync();
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// data = await _dbContext.Set<LeaveRequest>().AsQueryable()
|
||||
// .Include(x => x.Type)
|
||||
// .Where(x => x.ProfileType == type.Trim().ToUpper())
|
||||
// .Where(x => x.LeaveStartDate.Date >= startDate.Date && x.LeaveStartDate.Date <= endDate.Date)
|
||||
// .Where(x => node == 4 ? x.Child4Id == Guid.Parse(nodeId) : (node == 3 ? x.Child3Id == Guid.Parse(nodeId) : (node == 2 ? x.Child2Id == Guid.Parse(nodeId) : (node == 1 ? x.Child1Id == Guid.Parse(nodeId) : (node == 0 ? x.RootId == Guid.Parse(nodeId) : (node == null ? true : true))))))
|
||||
// .Where(x => node == 0 ? x.Child1Id == null : (node == 1 ? x.Child2Id == null : (node == 2 ? x.Child3Id == null : (node == 3 ? x.Child4Id == null : true))))
|
||||
// .Where(x => x.LeaveStatus == "APPROVE" || x.LeaveStatus == "DELETING").ToListAsync();
|
||||
//}
|
||||
data = await _dbContext.Set<LeaveRequest>().AsQueryable()
|
||||
.Include(x => x.Type)
|
||||
.Where(x => x.ProfileType == type.Trim().ToUpper())
|
||||
.Where(x => x.LeaveStartDate.Date >= startDate.Date && x.LeaveStartDate.Date <= endDate.Date)
|
||||
.Where(x => x.LeaveStatus == "APPROVE" || x.LeaveStatus == "DELETING").ToListAsync();
|
||||
// กรองตามสิทธิ์ admin ก่อน
|
||||
if (role == "OWNER")
|
||||
{
|
||||
node = null;
|
||||
}
|
||||
if (role == "OWNER" || role == "CHILD")
|
||||
if (role == "CHILD")
|
||||
{
|
||||
data = data.Where(x =>
|
||||
node == 4 ? x.Child4DnaId == Guid.Parse(nodeId) :
|
||||
|
|
@ -1505,25 +1750,40 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
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.Child1DnaId == null :
|
||||
node == 1 ? x.Child2DnaId == null :
|
||||
node == 2 ? x.Child3DnaId == null :
|
||||
node == 3 ? x.Child4DnaId == null :
|
||||
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")
|
||||
if (role == "ROOT" || role == "OWNER" || role == "CHILD" || role == "BROTHER" || role == "PARENT")
|
||||
{
|
||||
data = data
|
||||
.Where(x => nodeByReq == 4 ? x.Child4Id == Guid.Parse(nodeIdByReq) : nodeByReq == 3 ? x.Child3Id == Guid.Parse(nodeIdByReq) : nodeByReq == 2 ? x.Child2Id == Guid.Parse(nodeIdByReq) : nodeByReq == 1 ? x.Child1Id == Guid.Parse(nodeIdByReq) : nodeByReq == 0 ? x.RootId == Guid.Parse(nodeIdByReq) : true)
|
||||
.Where(x => nodeByReq == 4 ? x.Child4DnaId == Guid.Parse(nodeIdByReq) : nodeByReq == 3 ? x.Child3DnaId == Guid.Parse(nodeIdByReq) : nodeByReq == 2 ? x.Child2DnaId == Guid.Parse(nodeIdByReq) : nodeByReq == 1 ? x.Child1DnaId == Guid.Parse(nodeIdByReq) : nodeByReq == 0 ? x.RootDnaId == Guid.Parse(nodeIdByReq) : true)
|
||||
.ToList();
|
||||
}
|
||||
// รายงานการลางานจำแนกตามเพศฯ Template ให้หน่วยงานแสดงก่อนส่วนราชการ
|
||||
|
|
@ -1531,18 +1791,29 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
var organizationName = $"{org.Root ?? ""}{(!string.IsNullOrEmpty(org.Child1) ? "/" + org.Child1 : "")}{(!string.IsNullOrEmpty(org.Child2) ? "/" + org.Child2 : "")}{(!string.IsNullOrEmpty(org.Child3) ? "/" + org.Child3 : "")}{(!string.IsNullOrEmpty(org.Child4) ? "/" + org.Child4 : "")}";
|
||||
if (data.Count > 0)
|
||||
{
|
||||
var res = (from d in data
|
||||
var grouped = data.GroupBy(d => nodeByReq switch
|
||||
{
|
||||
0 => d.Root,
|
||||
1 => d.Child1,
|
||||
2 => d.Child2,
|
||||
3 => d.Child3,
|
||||
4 => d.Child4,
|
||||
_ => d.Root
|
||||
});
|
||||
var res = (/*from d in data
|
||||
group d by new { d.Root, d.Child1, d.Child2, d.Child3, d.Child4 } into grp
|
||||
orderby grp.Key.Root, grp.Key.Child1, grp.Key.Child2, grp.Key.Child3, grp.Key.Child4
|
||||
orderby grp.Key.Root, grp.Key.Child1, grp.Key.Child2, grp.Key.Child3, grp.Key.Child4*/
|
||||
from grp in grouped
|
||||
orderby grp.Key
|
||||
select new GetSumApproveLeaveByRootDto
|
||||
{
|
||||
//Root = $"{grp.Key.Root}{(!string.IsNullOrEmpty(grp.Key.Child1) ? "/" + grp.Key.Child1 : "")}{(!string.IsNullOrEmpty(grp.Key.Child2) ? "/" + grp.Key.Child2 : "")}{(!string.IsNullOrEmpty(grp.Key.Child3) ? "/" + grp.Key.Child3 : "")}{(!string.IsNullOrEmpty(grp.Key.Child4) ? "/" + grp.Key.Child4 : "")}",
|
||||
Root = organizationName,
|
||||
SumLeaveDay = grp.Sum(x => x.LeaveTotal),
|
||||
sickDayCountMale = grp.Where(x => x.Gender == "ชาย" && x.LeaveTypeCode == "LV-001").Sum(x => x.LeaveTotal),
|
||||
maternityDayCountMale = grp.Where(x => x.Gender == "ชาย" && x.LeaveTypeCode == "LV-002").Sum(x => x.LeaveTotal),
|
||||
wifeDayCountMale = grp.Where(x => x.Gender == "ชาย" && x.LeaveTypeCode == "LV-003").Sum(x => x.LeaveTotal),
|
||||
personalDayCountMale = grp.Where(x => x.Gender == "ชาย" && x.LeaveTypeCode == "LV-004").Sum(x => x.LeaveTotal),
|
||||
personalDayCountMale = grp.Where(x => x.Gender == "ชาย" && x.LeaveTypeCode == "LV-002").Sum(x => x.LeaveTotal),
|
||||
maternityDayCountMale = grp.Where(x => x.Gender == "ชาย" && x.LeaveTypeCode == "LV-003").Sum(x => x.LeaveTotal),
|
||||
wifeDayCountMale = grp.Where(x => x.Gender == "ชาย" && x.LeaveTypeCode == "LV-004").Sum(x => x.LeaveTotal),
|
||||
restDayCountMale = grp.Where(x => x.Gender == "ชาย" && x.LeaveTypeCode == "LV-005").Sum(x => x.LeaveTotal),
|
||||
ordainDayCountMale = grp.Where(x => x.Gender == "ชาย" && x.LeaveTypeCode == "LV-006").Sum(x => x.LeaveTotal),
|
||||
absentDayCountMale = grp.Where(x => x.Gender == "ชาย" && x.LeaveTypeCode == "LV-007").Sum(x => x.LeaveTotal),
|
||||
|
|
@ -1552,9 +1823,9 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
therapyDayCountMale = grp.Where(x => x.Gender == "ชาย" && x.LeaveTypeCode == "LV-011").Sum(x => x.LeaveTotal),
|
||||
|
||||
sickDayCountFemale = grp.Where(x => x.Gender == "หญิง" && x.LeaveTypeCode == "LV-001").Sum(x => x.LeaveTotal),
|
||||
maternityDayCountFemale = grp.Where(x => x.Gender == "หญิง" && x.LeaveTypeCode == "LV-002").Sum(x => x.LeaveTotal),
|
||||
wifeDayCountFemale = grp.Where(x => x.Gender == "หญิง" && x.LeaveTypeCode == "LV-003").Sum(x => x.LeaveTotal),
|
||||
personalDayCountFemale = grp.Where(x => x.Gender == "หญิง" && x.LeaveTypeCode == "LV-004").Sum(x => x.LeaveTotal),
|
||||
personalDayCountFemale = grp.Where(x => x.Gender == "หญิง" && x.LeaveTypeCode == "LV-002").Sum(x => x.LeaveTotal),
|
||||
maternityDayCountFemale = grp.Where(x => x.Gender == "หญิง" && x.LeaveTypeCode == "LV-003").Sum(x => x.LeaveTotal),
|
||||
wifeDayCountFemale = grp.Where(x => x.Gender == "หญิง" && x.LeaveTypeCode == "LV-004").Sum(x => x.LeaveTotal),
|
||||
restDayCountFemale = grp.Where(x => x.Gender == "หญิง" && x.LeaveTypeCode == "LV-005").Sum(x => x.LeaveTotal),
|
||||
ordainDayCountFemale = grp.Where(x => x.Gender == "หญิง" && x.LeaveTypeCode == "LV-006").Sum(x => x.LeaveTotal),
|
||||
absentDayCountFemale = grp.Where(x => x.Gender == "หญิง" && x.LeaveTypeCode == "LV-007").Sum(x => x.LeaveTotal),
|
||||
|
|
@ -1564,9 +1835,9 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
therapyDayCountFemale = grp.Where(x => x.Gender == "หญิง" && x.LeaveTypeCode == "LV-011").Sum(x => x.LeaveTotal),
|
||||
|
||||
sickDayCountNo = grp.Where(x => x.Gender != "ชาย" && x.Gender != "หญิง" && x.LeaveTypeCode == "LV-001").Sum(x => x.LeaveTotal),
|
||||
maternityDayCountNo = grp.Where(x => x.Gender != "ชาย" && x.Gender != "หญิง" && x.LeaveTypeCode == "LV-002").Sum(x => x.LeaveTotal),
|
||||
wifeDayCountNo = grp.Where(x => x.Gender != "ชาย" && x.Gender != "หญิง" && x.LeaveTypeCode == "LV-003").Sum(x => x.LeaveTotal),
|
||||
personalDayCountNo = grp.Where(x => x.Gender != "ชาย" && x.Gender != "หญิง" && x.LeaveTypeCode == "LV-004").Sum(x => x.LeaveTotal),
|
||||
personalDayCountNo = grp.Where(x => x.Gender != "ชาย" && x.Gender != "หญิง" && x.LeaveTypeCode == "LV-002").Sum(x => x.LeaveTotal),
|
||||
maternityDayCountNo = grp.Where(x => x.Gender != "ชาย" && x.Gender != "หญิง" && x.LeaveTypeCode == "LV-003").Sum(x => x.LeaveTotal),
|
||||
wifeDayCountNo = grp.Where(x => x.Gender != "ชาย" && x.Gender != "หญิง" && x.LeaveTypeCode == "LV-004").Sum(x => x.LeaveTotal),
|
||||
restDayCountNo = grp.Where(x => x.Gender != "ชาย" && x.Gender != "หญิง" && x.LeaveTypeCode == "LV-005").Sum(x => x.LeaveTotal),
|
||||
ordainDayCountNo = grp.Where(x => x.Gender != "ชาย" && x.Gender != "หญิง" && x.LeaveTypeCode == "LV-006").Sum(x => x.LeaveTotal),
|
||||
absentDayCountNo = grp.Where(x => x.Gender != "ชาย" && x.Gender != "หญิง" && x.LeaveTypeCode == "LV-007").Sum(x => x.LeaveTotal),
|
||||
|
|
@ -1653,6 +1924,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
.Include(x => x.Type)
|
||||
.Where(x => x.KeycloakUserId == keycloakUserId)
|
||||
.Where(x => x.Type.Id == leaveTypeId)
|
||||
//.Where(x => x.CreatedAt >= startDate && x.CreatedAt <= endDate)
|
||||
.Where(x => x.LeaveStartDate.Date >= startDate.Date && x.LeaveStartDate.Date <= endDate.Date)
|
||||
.Where(x => x.LeaveStatus == "APPROVE" || x.LeaveStatus == "DELETING")
|
||||
.ToListAsync();
|
||||
|
|
@ -1663,6 +1935,139 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
return 0;
|
||||
}
|
||||
|
||||
public async Task<double> GetSumApproveLeaveTotalByTypeAndRangeForUser2(Guid keycloakUserId, Guid leaveTypeId, DateTime startDate, DateTime endDate, DateTime sendLeaveDate)
|
||||
{
|
||||
// startDate/endDate คือขอบเขตปีงบประมาณ (fiscalStart/fiscalEnd) ที่ caller ส่งมา
|
||||
// ใช้ LeaveStartDate เป็นหลักในการ filter เพื่อให้กรณียื่นลาล่วงหน้าข้ามปีงบประมาณ
|
||||
// ถูกนับในปีงบประมาณของวันลาจริง (ไม่ใช้วันที่ยื่นลา)
|
||||
var data = await _dbContext.Set<LeaveRequest>().AsQueryable().AsNoTracking()
|
||||
.Include(x => x.Type)
|
||||
.Where(x => x.KeycloakUserId == keycloakUserId)
|
||||
.Where(x => x.Type.Id == leaveTypeId)
|
||||
.Where(x => (x.DateSendLeave ?? x.CreatedAt) < sendLeaveDate)
|
||||
.Where(x => x.LeaveStartDate.Date >= startDate.Date && x.LeaveStartDate.Date <= endDate.Date)
|
||||
.Where(x => x.LeaveStatus == "APPROVE" || x.LeaveStatus == "DELETING")
|
||||
.ToListAsync();
|
||||
|
||||
if (data.Count > 0)
|
||||
return data.Sum(x => x.LeaveTotal);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
public async Task<double> GetSumApproveLeaveTotalByTypeAndRangeForUserBefore(Guid keycloakUserId, Guid leaveTypeId, DateTime startDate, DateTime endDate,DateTime sendLeaveDate)
|
||||
{
|
||||
var data = await _dbContext.Set<LeaveRequest>().AsQueryable().AsNoTracking()
|
||||
.Include(x => x.Type)
|
||||
.Where(x => x.KeycloakUserId == keycloakUserId)
|
||||
.Where(x => x.Type.Id == leaveTypeId)
|
||||
.Where(x => (x.DateSendLeave ?? x.CreatedAt) < sendLeaveDate)
|
||||
.Where(x => x.LeaveStartDate.Date >= startDate.Date && x.LeaveStartDate.Date <= endDate.Date)
|
||||
.Where(x => x.LeaveStatus == "APPROVE" || x.LeaveStatus == "DELETING")
|
||||
.ToListAsync();
|
||||
|
||||
if (data.Count > 0)
|
||||
return data.Sum(x => x.LeaveTotal);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
public async Task<double> GetSumApproveLeaveTotalByTypeAndRangeForUserByProfile(Guid profileId, Guid leaveTypeId, DateTime startDate, DateTime endDate,DateTime sendLeaveDate)
|
||||
{
|
||||
var data = await _dbContext.Set<LeaveRequest>().AsQueryable().AsNoTracking()
|
||||
.Include(x => x.Type)
|
||||
.Where(x => x.ProfileId == profileId)
|
||||
.Where(x => x.Type.Id == leaveTypeId)
|
||||
.Where(x => (x.DateSendLeave ?? x.CreatedAt) < sendLeaveDate)
|
||||
.Where(x => x.LeaveStartDate.Date >= startDate.Date && x.LeaveStartDate.Date <= endDate.Date)
|
||||
.Where(x => x.LeaveStatus == "APPROVE" || x.LeaveStatus == "DELETING")
|
||||
.ToListAsync();
|
||||
|
||||
if (data.Count > 0)
|
||||
return data.Sum(x => x.LeaveTotal);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
public async Task<int> GetSumApproveLeaveCountByTypeAndRangeForUserByProfile(Guid profileId, Guid leaveTypeId, DateTime startDate, DateTime endDate, DateTime sendLeaveDate)
|
||||
{
|
||||
var data = await _dbContext.Set<LeaveRequest>().AsQueryable().AsNoTracking()
|
||||
.Include(x => x.Type)
|
||||
.Where(x => x.ProfileId == profileId)
|
||||
.Where(x => x.Type.Id == leaveTypeId)
|
||||
.Where(x => (x.DateSendLeave ?? x.CreatedAt) < sendLeaveDate)
|
||||
.Where(x => x.LeaveStartDate.Date >= startDate.Date && x.LeaveStartDate.Date <= endDate.Date)
|
||||
.Where(x => x.LeaveStatus == "APPROVE" || x.LeaveStatus == "DELETING")
|
||||
.ToListAsync();
|
||||
|
||||
return data.Count;
|
||||
}
|
||||
|
||||
public async Task<int> GetSumApproveLeaveCountByTypeAndRangeForUser2(Guid keycloakUserId, Guid leaveTypeId, DateTime startDate, DateTime endDate, DateTime sendLeaveDate)
|
||||
{
|
||||
var data = await _dbContext.Set<LeaveRequest>().AsQueryable().AsNoTracking()
|
||||
.Include(x => x.Type)
|
||||
.Where(x => x.KeycloakUserId == keycloakUserId)
|
||||
.Where(x => x.Type.Id == leaveTypeId)
|
||||
.Where(x => (x.DateSendLeave ?? x.CreatedAt) < sendLeaveDate)
|
||||
.Where(x => x.LeaveStartDate.Date >= startDate.Date && x.LeaveStartDate.Date <= endDate.Date)
|
||||
.Where(x => x.LeaveStatus == "APPROVE" || x.LeaveStatus == "DELETING")
|
||||
.ToListAsync();
|
||||
|
||||
return data.Count;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// วันลาที่สร้างแบบร่างยังไม่ได้ยื่น
|
||||
/// </summary>
|
||||
/// <param name="keycloakUserId"></param>
|
||||
/// <param name="leaveTypeId"></param>
|
||||
/// <param name="startDate"></param>
|
||||
/// <param name="endDate"></param>
|
||||
/// <param name="sendLeaveDate"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<double> GetSumDraftLeaveTotalByTypeAndRangeForUser2(Guid keycloakUserId, Guid leaveTypeId, DateTime startDate, DateTime endDate, DateTime sendLeaveDate)
|
||||
{
|
||||
var data = await _dbContext.Set<LeaveRequest>().AsQueryable().AsNoTracking()
|
||||
.Include(x => x.Type)
|
||||
.Where(x => x.KeycloakUserId == keycloakUserId)
|
||||
.Where(x => x.Type.Id == leaveTypeId)
|
||||
.Where(x => (x.DateSendLeave ?? x.CreatedAt) < sendLeaveDate)
|
||||
.Where(x => x.LeaveStartDate.Date >= startDate.Date && x.LeaveStartDate.Date <= endDate.Date)
|
||||
.Where(x => x.LeaveStatus == "DRAFT")
|
||||
.ToListAsync();
|
||||
|
||||
if (data.Count > 0)
|
||||
return data.Sum(x => x.LeaveTotal);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// วันลาที่ยื่นแล้วรอพิจารณา
|
||||
/// </summary>
|
||||
/// <param name="keycloakUserId"></param>
|
||||
/// <param name="leaveTypeId"></param>
|
||||
/// <param name="startDate"></param>
|
||||
/// <param name="endDate"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<double> GetSumNewLeaveTotalByTypeAndRangeForUser2(Guid keycloakUserId, Guid leaveTypeId, DateTime startDate, DateTime endDate,DateTime sendLeaveDate)
|
||||
{
|
||||
var data = await _dbContext.Set<LeaveRequest>().AsQueryable().AsNoTracking()
|
||||
.Include(x => x.Type)
|
||||
.Where(x => x.KeycloakUserId == keycloakUserId)
|
||||
.Where(x => x.Type.Id == leaveTypeId)
|
||||
.Where(x => (x.DateSendLeave ?? x.CreatedAt) < sendLeaveDate)
|
||||
.Where(x => x.LeaveStartDate.Date >= startDate.Date && x.LeaveStartDate.Date <= endDate.Date)
|
||||
.Where(x => (x.LeaveStatus == "NEW" || x.LeaveStatus == "PENDING"))
|
||||
.ToListAsync();
|
||||
|
||||
if (data.Count > 0)
|
||||
return data.Sum(x => x.LeaveTotal);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
public async Task<int> GetCountApproveLeaveByTypeAndRangeForUser(Guid keycloakUserId, Guid leaveTypeId, DateTime startDate, DateTime endDate)
|
||||
{
|
||||
var data = await _dbContext.Set<LeaveRequest>().AsQueryable().AsNoTracking()
|
||||
|
|
@ -1670,6 +2075,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.LeaveRequests
|
|||
.Where(x => x.KeycloakUserId == keycloakUserId)
|
||||
.Where(x => x.Type.Id == leaveTypeId)
|
||||
.Where(x => x.LeaveStartDate.Date >= startDate.Date && x.LeaveStartDate.Date <= endDate.Date)
|
||||
//.Where(x => x.CreatedAt >= startDate && x.CreatedAt <= endDate)
|
||||
.Where(x => x.LeaveStatus == "APPROVE" || x.LeaveStatus == "DELETING")
|
||||
.ToListAsync();
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ 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
|
||||
{
|
||||
|
|
@ -72,7 +74,8 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
|||
await base.AddAsync(entity);
|
||||
|
||||
var userId = UserId != null ? Guid.Parse(UserId) : Guid.Empty;
|
||||
var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(userId, AccessToken ?? "");
|
||||
// var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(userId, AccessToken ?? "");
|
||||
var profile = await _userProfileRepository.GetProfileByKeycloakIdNew2Async(userId, AccessToken ?? "");
|
||||
|
||||
// fix issue : SIT ระบบบันทึกเวลาปฏิบัติงาน>>ลงเวลากรณีพิเศษ (ไม่มีแจ้งเตือนไปยังผู้บังคับบัญชา) #969
|
||||
// send noti + inbox + mail
|
||||
|
|
@ -142,7 +145,7 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
|||
}
|
||||
}
|
||||
|
||||
public async Task<List<AdditionalCheckRequest>> GetAdditionalCheckRequestsByAdminRole(int year, int month, string role, string nodeId, int? node)
|
||||
public async Task<List<AdditionalCheckRequest>> GetAdditionalCheckRequestsByAdminRole(int year, int month, string role, string nodeId, int? node, string? keyword)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -150,6 +153,17 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
|||
.Where(x => (x.CheckDate.Year == year && x.CheckDate.Month == month))
|
||||
.OrderByDescending(x => x.CreatedAt.Date)
|
||||
.ToListAsync();
|
||||
|
||||
if (!string.IsNullOrEmpty(keyword))
|
||||
{
|
||||
data = data.Where(x =>
|
||||
(
|
||||
(x.Prefix ?? "") + (x.FirstName ?? "") + " " + (x.LastName ?? "")).Contains(keyword)
|
||||
|| x.Description.Contains(keyword)
|
||||
|
||||
).ToList();
|
||||
}
|
||||
|
||||
if (role == "OWNER")
|
||||
{
|
||||
node = null;
|
||||
|
|
@ -160,16 +174,36 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
|||
.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.Child1DnaId == null : (node == 1 ? x.Child2DnaId == null : (node == 2 ? x.Child3DnaId == null : (node == 3 ? x.Child4DnaId == null : true))))
|
||||
.ToList();
|
||||
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;
|
||||
}
|
||||
|
|
@ -179,6 +213,79 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
|||
}
|
||||
}
|
||||
|
||||
public async Task<List<AdditionalCheckRequest>> GetAdditionalCheckRequestsByAdminRole2(DateTime startDate, DateTime endDate, string role, string nodeId, int? node, string? keyword, string? status)
|
||||
{
|
||||
try
|
||||
{
|
||||
var data = await _dbContext.Set<AdditionalCheckRequest>().AsQueryable()
|
||||
.Where(x => (x.CheckDate.Date >= startDate.Date && x.CheckDate.Date <= endDate.Date))
|
||||
.OrderByDescending(x => x.CreatedAt.Date)
|
||||
.ToListAsync();
|
||||
|
||||
if(!string.IsNullOrEmpty(status))
|
||||
data = data.Where(x => x.Status == status).ToList();
|
||||
|
||||
|
||||
if (!string.IsNullOrEmpty(keyword))
|
||||
{
|
||||
data = data.Where(x =>
|
||||
(
|
||||
(x.Prefix ?? "") + (x.FirstName ?? "") + " " + (x.LastName ?? "")).Contains(keyword)
|
||||
|| x.Description.Contains(keyword)
|
||||
|
||||
).ToList();
|
||||
}
|
||||
|
||||
if (role == "OWNER")
|
||||
{
|
||||
node = null;
|
||||
}
|
||||
if (role == "OWNER" || role == "CHILD")
|
||||
{
|
||||
data = data
|
||||
.Where(x => node == 4 ? x.Child4DnaId == Guid.Parse(nodeId!) : (node == 3 ? x.Child3DnaId == Guid.Parse(nodeId!) : (node == 2 ? x.Child2DnaId == Guid.Parse(nodeId!) : (node == 1 ? x.Child1DnaId == Guid.Parse(nodeId!) : (node == 0 ? x.RootDnaId == Guid.Parse(nodeId!) : (node == null ? true : true))))))
|
||||
.ToList();
|
||||
}
|
||||
else if (role == "BROTHER")
|
||||
{
|
||||
data = data
|
||||
.Where(x => node == 4 ? x.Child3DnaId == Guid.Parse(nodeId!) : (node == 3 ? x.Child2DnaId == Guid.Parse(nodeId!) : (node == 2 ? x.Child1DnaId == Guid.Parse(nodeId!) : (node == 1 || node == 0 ? x.RootDnaId == Guid.Parse(nodeId!) : (node == null ? true : true)))))
|
||||
.ToList();
|
||||
}
|
||||
else if (role == "ROOT")
|
||||
{
|
||||
data = data
|
||||
.Where(x => x.RootDnaId == Guid.Parse(nodeId!)).ToList();
|
||||
}
|
||||
// else if (role == "PARENT")
|
||||
// {
|
||||
// data = data
|
||||
// .Where(x => x.RootDnaId == Guid.Parse(nodeId!) && x.Child1DnaId != null && x.Child1DnaId != Guid.Empty).ToList();
|
||||
// }
|
||||
else if (role == "NORMAL")
|
||||
{
|
||||
data = data.Where(x =>
|
||||
node == 0 ? x.RootDnaId == Guid.Parse(nodeId!) &&
|
||||
(x.Child1DnaId == Guid.Empty || x.Child1DnaId == null) :
|
||||
node == 1 ? x.Child1DnaId == Guid.Parse(nodeId!) &&
|
||||
(x.Child2DnaId == Guid.Empty || x.Child2DnaId == null) :
|
||||
node == 2 ? x.Child2DnaId == Guid.Parse(nodeId!) &&
|
||||
(x.Child3DnaId == Guid.Empty || x.Child3DnaId == null) :
|
||||
node == 3 ? x.Child3DnaId == Guid.Parse(nodeId!) &&
|
||||
(x.Child4DnaId == Guid.Empty || x.Child4DnaId == null) :
|
||||
node == 4 ? x.Child4DnaId == Guid.Parse(nodeId!) :
|
||||
true
|
||||
).ToList();
|
||||
}
|
||||
return data;
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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; }
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -141,37 +141,13 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
|||
|
||||
public async Task<List<ProcessUserTimeStamp>> GetTimestampByDateLateAsync(string type, string role, string nodeId, int? node, string nodeIdByReq, int? nodeByReq, DateTime StartDate, DateTime EndDate)
|
||||
{
|
||||
var _nodeId = role != "OWNER" ? Guid.Parse(nodeId) : Guid.Parse("00000000-0000-0000-0000-000000000000");
|
||||
var data = new List<ProcessUserTimeStamp>();
|
||||
//if (role == "OWNER" || role == "CHILD")
|
||||
//{
|
||||
// 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())
|
||||
// .Where(x => node == 4 ? x.Child4Id == _nodeId : (node == 3 ? x.Child3Id == _nodeId : (node == 2 ? x.Child2Id == _nodeId : (node == 1 ? x.Child1Id == _nodeId : (node == 0 ? x.RootId == _nodeId : true)))))
|
||||
// .ToListAsync();
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// 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())
|
||||
// .Where(x => node == 4 ? x.Child4Id == _nodeId : (node == 3 ? x.Child3Id == _nodeId : (node == 2 ? x.Child2Id == _nodeId : (node == 1 ? x.Child1Id == _nodeId : (node == 0 ? x.RootId == _nodeId : true)))))
|
||||
// .Where(x => node == 0 ? x.Child1Id == null : (node == 1 ? x.Child2Id == null : (node == 2 ? x.Child3Id == null : (node == 3 ? x.Child4Id == null : true))))
|
||||
// .ToListAsync();
|
||||
//}
|
||||
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 == "OWNER")
|
||||
{
|
||||
node = null;
|
||||
}
|
||||
if (role == "OWNER" || role == "CHILD")
|
||||
if (role == "CHILD")
|
||||
{
|
||||
data = data.Where(x =>
|
||||
node == 4 ? x.Child4DnaId == Guid.Parse(nodeId) :
|
||||
|
|
@ -182,29 +158,44 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
|||
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.Child1DnaId == null :
|
||||
node == 1 ? x.Child2DnaId == null :
|
||||
node == 2 ? x.Child3DnaId == null :
|
||||
node == 3 ? x.Child4DnaId == null :
|
||||
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")
|
||||
if (role == "ROOT" || role == "OWNER" || role == "CHILD" || role == "BROTHER" || role == "PARENT")
|
||||
{
|
||||
data = data.Where(x =>
|
||||
nodeByReq == 4 ? x.Child4Id == Guid.Parse(nodeIdByReq) :
|
||||
nodeByReq == 3 ? x.Child3Id == Guid.Parse(nodeIdByReq) :
|
||||
nodeByReq == 2 ? x.Child2Id == Guid.Parse(nodeIdByReq) :
|
||||
nodeByReq == 1 ? x.Child1Id == Guid.Parse(nodeIdByReq) :
|
||||
nodeByReq == 0 ? x.RootId == Guid.Parse(nodeIdByReq) : true
|
||||
nodeByReq == 4 ? x.Child4DnaId == Guid.Parse(nodeIdByReq) :
|
||||
nodeByReq == 3 ? x.Child3DnaId == Guid.Parse(nodeIdByReq) :
|
||||
nodeByReq == 2 ? x.Child2DnaId == Guid.Parse(nodeIdByReq) :
|
||||
nodeByReq == 1 ? x.Child1DnaId == Guid.Parse(nodeIdByReq) :
|
||||
nodeByReq == 0 ? x.RootDnaId == Guid.Parse(nodeIdByReq) : true
|
||||
).ToList();
|
||||
}
|
||||
return data;
|
||||
|
|
@ -222,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)
|
||||
|
|
@ -233,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>()
|
||||
|
|
@ -282,17 +289,34 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
|||
.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.Child1DnaId == null : (node == 1 ? x.Child2DnaId == null : (node == 2 ? x.Child3DnaId == null : (node == 3 ? x.Child4DnaId == null : true))))
|
||||
.ToList();
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,14 +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 <= DateTime.Now.Date)
|
||||
.Where(x => x.EffectiveDate.Value.Date <= effectiveDate.Value.Date)
|
||||
.OrderByDescending(x => x.EffectiveDate)
|
||||
.FirstOrDefaultAsync();
|
||||
.FirstOrDefaultAsync(combinedCts.Token);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,12 +74,16 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
|||
return data;
|
||||
}
|
||||
|
||||
public async Task<UserTimeStamp?> GetLastRecord(Guid keycloakId)
|
||||
public async Task<UserTimeStamp?> GetLastRecord(Guid keycloakId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
// กำหนด timeout เป็น 30 นาที
|
||||
using var timeoutCts = new CancellationTokenSource(TimeSpan.FromMinutes(30));
|
||||
using var combinedCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutCts.Token);
|
||||
|
||||
var data = await _dbContext.Set<UserTimeStamp>()
|
||||
.Where(u => u.KeycloakUserId == keycloakId)
|
||||
.OrderByDescending(u => u.CheckIn)
|
||||
.FirstOrDefaultAsync();
|
||||
.FirstOrDefaultAsync(combinedCts.Token);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
|
@ -124,17 +128,34 @@ namespace BMA.EHR.Application.Repositories.Leaves.TimeAttendants
|
|||
.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.Child1DnaId == null : (node == 1 ? x.Child2DnaId == null : (node == 2 ? x.Child3DnaId == null : (node == 3 ? x.Child4DnaId == null : true))))
|
||||
.ToList();
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,12 +51,13 @@ namespace BMA.EHR.Application.Repositories.MessageQueue
|
|||
// // throw new Exception(GlobalMessages.DataNotFound);
|
||||
// }
|
||||
|
||||
var apiUrl = $"{_configuration["API"]}/org/profile/keycloak/position";
|
||||
//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"]);
|
||||
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();
|
||||
|
|
|
|||
|
|
@ -55,12 +55,13 @@ namespace BMA.EHR.Application.Repositories.MessageQueue
|
|||
// // throw new Exception(GlobalMessages.DataNotFound);
|
||||
// }
|
||||
|
||||
var apiUrl = $"{_configuration["API"]}/org/profile/keycloak/position";
|
||||
//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"]);
|
||||
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();
|
||||
|
|
@ -131,12 +132,13 @@ namespace BMA.EHR.Application.Repositories.MessageQueue
|
|||
// {
|
||||
// return 0;
|
||||
// }
|
||||
var apiUrl = $"{_configuration["API"]}/org/profile/keycloak/position";
|
||||
//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"]);
|
||||
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();
|
||||
|
|
@ -185,6 +187,44 @@ namespace BMA.EHR.Application.Repositories.MessageQueue
|
|||
}
|
||||
}
|
||||
|
||||
private async Task<string> GetMyProfileIdAsync()
|
||||
{
|
||||
var apiUrl = $"{_configuration["API"]}/org/dotnet/get-profileId";
|
||||
var response = await GetExternalAPIAsync(apiUrl, AccessToken!, _configuration["API_KEY"]!);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(response))
|
||||
return string.Empty;
|
||||
|
||||
var org = JsonConvert.DeserializeObject<OrgRequest>(response);
|
||||
if (org == null || org.result == null)
|
||||
return string.Empty;
|
||||
|
||||
return org.result.profileId ?? string.Empty;
|
||||
}
|
||||
|
||||
public async Task<int> DeleteAllMyNotificationsAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
var profileId = await GetMyProfileIdAsync();
|
||||
if (string.IsNullOrEmpty(profileId))
|
||||
return 0;
|
||||
|
||||
var notifications = await _dbContext.Set<Notification>()
|
||||
.Where(x => x.ReceiverUserId == Guid.Parse(profileId))
|
||||
.Where(x => x.DeleteDate == null)
|
||||
.ToListAsync();
|
||||
|
||||
_dbContext.Set<Notification>().RemoveRange(notifications);
|
||||
await _dbContext.SaveChangesAsync();
|
||||
return notifications.Count;
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task PushNotificationAsync(Guid ReceiverUserId, string Subject, string Body, string Payload = "", string NotiLink = "", bool IsSendInbox = false, bool IsSendMail = false)
|
||||
{
|
||||
try
|
||||
|
|
@ -227,7 +267,7 @@ namespace BMA.EHR.Application.Repositories.MessageQueue
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
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();
|
||||
|
|
@ -287,7 +327,7 @@ namespace BMA.EHR.Application.Repositories.MessageQueue
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
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();
|
||||
|
|
@ -361,7 +401,7 @@ namespace BMA.EHR.Application.Repositories.MessageQueue
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
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();
|
||||
|
|
@ -434,7 +474,7 @@ namespace BMA.EHR.Application.Repositories.MessageQueue
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
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();
|
||||
|
|
@ -504,7 +544,7 @@ namespace BMA.EHR.Application.Repositories.MessageQueue
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
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();
|
||||
|
|
@ -566,7 +606,7 @@ namespace BMA.EHR.Application.Repositories.MessageQueue
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
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();
|
||||
|
|
|
|||
|
|
@ -49,12 +49,16 @@ namespace BMA.EHR.Application.Repositories.MetaData
|
|||
|
||||
public async Task<int> GetHolidayCountAsync(DateTime startDate, DateTime endDate, string category = "NORMAL")
|
||||
{
|
||||
var data = await _dbContext.Set<Holiday>().AsQueryable()
|
||||
var query = _dbContext.Set<Holiday>().AsQueryable()
|
||||
.Where(x => x.Category == category)
|
||||
.Where(x => x.HolidayDate.Date >= startDate && x.HolidayDate.Date <= endDate)
|
||||
.CountAsync();
|
||||
.Where(x => x.HolidayDate.Date >= startDate && x.HolidayDate.Date <= endDate);
|
||||
|
||||
return data;
|
||||
if (category == "NORMAL")
|
||||
query = query.Where(x => x.HolidayDate.DayOfWeek != DayOfWeek.Saturday && x.HolidayDate.DayOfWeek != DayOfWeek.Sunday);
|
||||
else
|
||||
query = query.Where(x => x.HolidayDate.DayOfWeek != DayOfWeek.Sunday);
|
||||
|
||||
return await query.CountAsync();
|
||||
}
|
||||
|
||||
public List<DateTime> GetWeekEnd(DateTime startDate, DateTime endDate, string category = "NORMAL")
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ using System.Net.Http.Headers;
|
|||
using Microsoft.Extensions.Configuration;
|
||||
using System.Security.Claims;
|
||||
using System.Net.Http.Json;
|
||||
using BMA.EHR.Application.Responses.Leaves;
|
||||
|
||||
namespace BMA.EHR.Application.Repositories
|
||||
{
|
||||
|
|
@ -60,8 +61,12 @@ namespace BMA.EHR.Application.Repositories
|
|||
{
|
||||
client.DefaultRequestHeaders.Authorization =
|
||||
new AuthenticationHeaderValue("Bearer", AccessToken.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
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;
|
||||
}
|
||||
|
|
@ -72,6 +77,39 @@ namespace BMA.EHR.Application.Repositories
|
|||
}
|
||||
}
|
||||
|
||||
public async Task<GetPermissionWithActingResultDto?> GetPermissionWithActingAPIAsync(string action, string system)
|
||||
{
|
||||
try
|
||||
{
|
||||
var apiPath = $"{_configuration["API"]}/org/permission/dotnet-acting/{action}/{system}";
|
||||
|
||||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization =
|
||||
new AuthenticationHeaderValue("Bearer", AccessToken.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var req = await client.GetAsync(apiPath);
|
||||
if (!req.IsSuccessStatusCode)
|
||||
{
|
||||
throw new Exception("Error calling permission API");
|
||||
}
|
||||
var apiResult = await req.Content.ReadAsStringAsync();
|
||||
//return res;
|
||||
|
||||
if (apiResult != null)
|
||||
{
|
||||
var raw = JsonConvert.DeserializeObject<GetPermissionWithActingResultDto>(apiResult);
|
||||
return raw;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<dynamic> GetPermissionOrgAPIAsync(string action, string system, string profileId)
|
||||
{
|
||||
try
|
||||
|
|
@ -81,7 +119,7 @@ namespace BMA.EHR.Application.Repositories
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var req = await client.GetAsync(apiPath);
|
||||
var res = await req.Content.ReadAsStringAsync();
|
||||
return res;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
p.Id,
|
||||
AvatarId = p.ProfileImg == null ? Guid.Parse("00000000-0000-0000-0000-000000000000") : p.ProfileImg.Id,
|
||||
ExamIdenNumber = p.ExamIdenNumber == null ? "-" : p.ExamIdenNumber.ToThaiNumber(),
|
||||
PositionName = p.PositionExam == null ? "-" : p.PositionExam.PositionName.ToThaiNumber(),
|
||||
PositionLevelName = p.PositionExam == null ? "-" : p.PositionExam.PositionLevelName.ToThaiNumber(),
|
||||
PeriodExamName = p.PeriodExam == null ? "-" : p.PeriodExam.Name.ToThaiNumber(),
|
||||
PeriodExamRound = p.PeriodExam == null ? "-" : p.PeriodExam.Round.ToString().ToThaiNumber(),
|
||||
PeriodExamYear = p.PeriodExam == null ? "-" : (p.PeriodExam.Year + 543).ToString().ToThaiNumber(),
|
||||
|
||||
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().ToThaiNumber(),
|
||||
Age = p.DateOfBirth == null ? "-" : p.DateOfBirth.Value.CalculateAgeStrV2(0, 0).ToThaiNumber(),
|
||||
CitizenId = p.CitizenId == null ? "-" : p.CitizenId.ToThaiNumber(),
|
||||
|
||||
EducationLevelExamName = p.Educations.FirstOrDefault() == null ? "-" : p.Educations.FirstOrDefault().EducationLevelExamName.ToThaiNumber(),
|
||||
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.ToThaiNumber(),
|
||||
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().ToThaiNumber(),
|
||||
EducationScores = p.Educations.FirstOrDefault() == null ? "-" : p.Educations.FirstOrDefault().EducationScores.ToThaiNumber(),
|
||||
EducationType = p.Educations.FirstOrDefault() == null ? "-" : p.Educations.FirstOrDefault().EducationType,
|
||||
EducationLevelHighName = p.Educations.FirstOrDefault() == null ? "-" : p.Educations.FirstOrDefault().EducationLevelHighName,
|
||||
|
||||
OccupationPositionType = p.OccupationPositionType == "other" ? "ผู้ปฏิบัติงานอื่นในกรุงเทพมหานคร" : (p.OccupationPositionType == "temp" ? "ลูกจ้างชั่วคราว" : (p.OccupationPositionType == "prem" ? "ลูกจ้างประจำ" : "-")),
|
||||
OccupationPosition = p.OccupationPosition == null ? "-" : p.OccupationPosition,
|
||||
OccupationSalary = p.OccupationSalary == null ? "-" : p.OccupationSalary.Value.ToString("N0").ToThaiNumber(),
|
||||
OccupationGroup = p.OccupationGroup == null ? "-" : p.OccupationGroup,
|
||||
OccupationPile = p.OccupationPile == null ? "-" : p.OccupationPile,
|
||||
OccupationOrg = p.OccupationOrg == null ? "-" : p.OccupationOrg,
|
||||
OccupationTelephone = p.OccupationTelephone == null ? "-" : p.OccupationTelephone.ToThaiNumber(),
|
||||
|
||||
CareersTotal = sb.ToString().ToThaiNumber(),
|
||||
// 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.ToThaiNumber(),
|
||||
RegistProvinceName = p.RegistProvinceName == null ? "-" : p.RegistProvinceName,
|
||||
RegistDistrictName = p.RegistDistrictName == null ? "-" : p.RegistDistrictName,
|
||||
RegistSubDistrictName = p.RegistSubDistrictName == null ? "-" : p.RegistSubDistrictName,
|
||||
RegistZipCode = p.RegistZipCode == null ? "-" : p.RegistZipCode.ToThaiNumber(),
|
||||
CurrentAddress = p.CurrentAddress == null ? (p.RegistAddress == null ? "-" : p.RegistAddress.ToThaiNumber()) : p.CurrentAddress.ToThaiNumber(),
|
||||
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.ToThaiNumber()) : p.CurrentZipCode.ToThaiNumber(),
|
||||
Telephone = p.Telephone == null ? "-" : p.Telephone.ToThaiNumber(),
|
||||
Email = p.Email == null ? "-" : p.Email,
|
||||
|
||||
ContactFullName = $"{p.ContactPrefixName}{p.ContactFirstname} {p.ContactLastname}",
|
||||
ContactRelations = p.ContactRelations == null ? "-" : p.ContactRelations,
|
||||
ContactTel = p.ContactTel == null ? "-" : p.ContactTel.ToThaiNumber(),
|
||||
|
||||
RegisterDate = p.RegisterDate == null ? "-" : p.RegisterDate.Value.ToThaiFullDate().ToThaiNumber(),
|
||||
})
|
||||
.Include(p => p.PeriodExam)
|
||||
.Include(p => p.Educations)
|
||||
.Include(p => p.PositionExam)
|
||||
.Include(p => p.ProfileImg)
|
||||
.FirstOrDefaultAsync();
|
||||
if (data == null)
|
||||
|
||||
if (candidate == null)
|
||||
throw new Exception(GlobalMessages.CandidateNotFound);
|
||||
return data;
|
||||
|
||||
List<string> editorConfirmLists;
|
||||
|
||||
var textOnly = string.IsNullOrEmpty(candidate.PeriodExam?.EditorConfirm)
|
||||
? null
|
||||
: Regex.Replace(
|
||||
candidate.PeriodExam.EditorConfirm,
|
||||
"<[^>]+>",
|
||||
string.Empty
|
||||
)
|
||||
.Replace(" ", " ")
|
||||
.Trim();
|
||||
|
||||
if (!string.IsNullOrEmpty(textOnly))
|
||||
{
|
||||
// ลบข้อความทั้งหมดก่อน "1." เพื่อให้เริ่มต้นที่ข้อแรกเสมอ
|
||||
var cleanedText = Regex.Replace(textOnly, @"^.*?1\.", "1.").Trim();
|
||||
|
||||
// ถ้าข้อ 3 จบด้วย "มาตรา 1374." แล้วเลข 4. ติดกับประโยค ให้แทรกขึ้นบรรทัดใหม่เป็นข้อ 4.
|
||||
if (!cleanedText.Contains("\n4.") && Regex.IsMatch(cleanedText, @"1374\.\s*"))
|
||||
{
|
||||
cleanedText = Regex.Replace(cleanedText, @"1374\.\s*", "137\n4. ");
|
||||
}
|
||||
|
||||
// แยกข้อความเป็นแต่ละข้อ โดย 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> { "-" };
|
||||
}
|
||||
|
||||
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(),
|
||||
|
||||
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 = $"{candidate.ContactPrefixName}{candidate.ContactFirstname} {candidate.ContactLastname}",
|
||||
ContactRelations = candidate.ContactRelations ?? "-",
|
||||
ContactTel = candidate.ContactTel ?? "-",
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
@ -176,10 +229,10 @@ namespace BMA.EHR.Application.Repositories.Reports
|
|||
{
|
||||
Position = item.Position,
|
||||
Type = item.Type,
|
||||
DurationStart = item.DurationStart.ToThaiNumber(),
|
||||
DurationEnd = item.DurationEnd.ToThaiNumber(),
|
||||
RangeDate = item.RangeDate.ToThaiNumber(),
|
||||
Index = retVal.ToString().ToThaiNumber(),
|
||||
DurationStart = item.DurationStart,
|
||||
DurationEnd = item.DurationEnd,
|
||||
RangeDate = item.RangeDate,
|
||||
Index = retVal.ToString(),
|
||||
};
|
||||
data.Add(_data);
|
||||
retVal++;
|
||||
|
|
|
|||
|
|
@ -893,7 +893,7 @@ namespace BMA.EHR.Application.Repositories.Reports
|
|||
select new
|
||||
{
|
||||
RowNo = 1,
|
||||
DepartmentName = _userProfileRepository.GetOc(g.Key.OcId, 0, AccessToken).Root, //_organizationCommonRepository.GetOrganizationNameFullPath(g.Key.OcId, false, false),
|
||||
DepartmentName = _userProfileRepository.GetOc(g.Key.OcId, 0, AccessToken)?.Root ?? "-", //_organizationCommonRepository.GetOrganizationNameFullPath(g.Key.OcId, false, false),
|
||||
G1Male = g.Sum(x => x.Gendor == "ชาย" && x.RequestInsigniaName == "เหรียญจักรพรรดิมาลา" ? 1 : 0),
|
||||
G1Female = g.Sum(x => x.Gendor == "หญิง" && x.RequestInsigniaName == "เหรียญจักรพรรดิมาลา" ? 1 : 0),
|
||||
G2Male = g.Sum(x => x.Gendor == "ชาย" ? 1 : 0),
|
||||
|
|
@ -1236,7 +1236,7 @@ namespace BMA.EHR.Application.Repositories.Reports
|
|||
var _apiUrl = $"{_baseAPI}/org/unauthorize/calculateEvaluation/{type}";
|
||||
using (var _client = new HttpClient())
|
||||
{
|
||||
_client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
_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();
|
||||
|
|
@ -1575,6 +1575,11 @@ namespace BMA.EHR.Application.Repositories.Reports
|
|||
}
|
||||
}
|
||||
|
||||
public void CalculateInsigniaRequestBkkByType(string type = "officer")
|
||||
{
|
||||
CalInsigniaRequestBkkByType(type).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
//คำนวนผู้ได้รับเครื่องราชฯ
|
||||
public async Task CalInsigniaRequestBkkByType(string type = "officer")
|
||||
{
|
||||
|
|
@ -1583,12 +1588,10 @@ namespace BMA.EHR.Application.Repositories.Reports
|
|||
.AsQueryable()
|
||||
.ToListAsync();
|
||||
insigniaPeriods = insigniaPeriods
|
||||
.Where(x => x.StartDate < DateTime.Now.Date || x.InsigniaRequests.Count == 0).ToList();
|
||||
.Where(x => x.StartDate <= DateTime.Now.Date && x.InsigniaRequests.Where(x => x.ProfileType!.ToLower().Trim() == type.Trim().ToLower()).Count() == 0).ToList();
|
||||
|
||||
foreach (var insigniaPeriod in insigniaPeriods)
|
||||
{
|
||||
if (insigniaPeriod.StartDate >= DateTime.Now.Date || insigniaPeriod.InsigniaRequests.Count > 0)
|
||||
continue;
|
||||
var organizations = await _userProfileRepository.GetActiveRootLatestAsync(AccessToken);
|
||||
if (organizations == null)
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ namespace BMA.EHR.Application.Repositories.Reports
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var req = new HttpRequestMessage(HttpMethod.Get, api_url);
|
||||
var res = await client.SendAsync(req);
|
||||
var result = await res.Content.ReadAsStringAsync();
|
||||
|
|
@ -161,7 +161,7 @@ namespace BMA.EHR.Application.Repositories.Reports
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var req = new HttpRequestMessage(HttpMethod.Get, api_url);
|
||||
var res = await client.SendAsync(req);
|
||||
var result = await res.Content.ReadAsStringAsync();
|
||||
|
|
@ -433,7 +433,7 @@ namespace BMA.EHR.Application.Repositories.Reports
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var req = new HttpRequestMessage(HttpMethod.Get, api_url);
|
||||
var res = await client.SendAsync(req);
|
||||
var result = await res.Content.ReadAsStringAsync();
|
||||
|
|
@ -642,7 +642,7 @@ namespace BMA.EHR.Application.Repositories.Reports
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var req = new HttpRequestMessage(HttpMethod.Get, api_url);
|
||||
var res = await client.SendAsync(req);
|
||||
var result = await res.Content.ReadAsStringAsync();
|
||||
|
|
@ -894,7 +894,7 @@ namespace BMA.EHR.Application.Repositories.Reports
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var req = new HttpRequestMessage(HttpMethod.Get, api_url);
|
||||
var res = await client.SendAsync(req);
|
||||
var result = await res.Content.ReadAsStringAsync();
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ namespace BMA.EHR.Application.Repositories.Reports
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Get, apiUrl);
|
||||
var _res = await client.SendAsync(_req);
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
|
|
@ -192,7 +192,7 @@ namespace BMA.EHR.Application.Repositories.Reports
|
|||
}).ToList();
|
||||
}
|
||||
string SignDate = retireHistorys.SignDate != null ? DateTime.Parse(retireHistorys.SignDate.ToString()).ToThaiFullDate().ToString().ToThaiNumber() : "-";
|
||||
return new { SignDate, retireHistorys.Detail, retireHistorys.Id, retireHistorys.CreatedAt, Year = retireHistorys.Year.ToThaiYear().ToString().ToThaiNumber(), retireHistorys.Round, retireHistorys.Type, retireHistorys.TypeReport, Total = retireHistorys.Total.ToString().ToThaiNumber(), profiles = mapProfiles };
|
||||
return new { SignDate, Detail = retireHistorys.Detail.ToThaiNumber(), retireHistorys.Id, retireHistorys.CreatedAt, Year = retireHistorys.Year.ToThaiYear().ToString().ToThaiNumber(), retireHistorys.Round, retireHistorys.Type, retireHistorys.TypeReport, Total = retireHistorys.Total.ToString().ToThaiNumber(), profiles = mapProfiles };
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -312,7 +312,7 @@ namespace BMA.EHR.Application.Repositories.Reports
|
|||
root = (isDuplicateRoot ? "" : profile.root + "\n") +
|
||||
(isDuplicateHospital || !hospital.ToObject<List<string>>().Contains(profile.child1) ? "" : profile.child1 + "\n") +
|
||||
(isDuplicatePosType ? "" : $"ตำแหน่งประเภท{profile.posTypeName}" + "\n") +
|
||||
(isDuplicatePosLevel ? "" : $"ระดับ{profile.posLevelName}"),
|
||||
(isDuplicatePosLevel ? "" : $"ระดับ{profile.posLevelName}").ToThaiNumber(),
|
||||
child = (profile.posExecutiveName == null ? "" : profile.posExecutiveName + "\n") +
|
||||
(profile.child4 == null ? "" : profile.child4 + "\n") +
|
||||
(profile.child3 == null ? "" : profile.child3 + "\n") +
|
||||
|
|
@ -326,7 +326,7 @@ namespace BMA.EHR.Application.Repositories.Reports
|
|||
}).ToList();
|
||||
}
|
||||
string SignDate = retire.SignDate != null ? DateTime.Parse(retire.SignDate.ToString()).ToThaiFullDate().ToString().ToThaiNumber() : "-";
|
||||
return new { SignDate, retire.Detail, retire.Id, retire.CreatedAt, Year = retire.Year.ToThaiYear().ToString().ToThaiNumber(), retire.Round, retire.Type, retire.TypeReport, Total = profile_retire.Count.ToString().ToThaiNumber(), profiles = mapProfiles };
|
||||
return new { SignDate, Detail = retire.Detail.ToThaiNumber(), retire.Id, retire.CreatedAt, Year = retire.Year.ToThaiYear().ToString().ToThaiNumber(), retire.Round, retire.Type, retire.TypeReport, Total = profile_retire.Count.ToString().ToThaiNumber(), profiles = mapProfiles };
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ namespace BMA.EHR.Application.Repositories
|
|||
// using (var client = new HttpClient())
|
||||
// {
|
||||
// client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
// client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
// client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
|
||||
// var jsonBody = JsonConvert.SerializeObject(body);
|
||||
// var content = new StringContent(jsonBody, Encoding.UTF8, "application/json");
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ namespace BMA.EHR.Application.Repositories
|
|||
{
|
||||
try
|
||||
{
|
||||
var apiPath = $"{_configuration["API"]}/org/dotnet/root/officer/{rootId}";
|
||||
var apiPath = $"{_configuration["API"]}/org/unauthorize/root/officer/{rootId}";
|
||||
var apiKey = _configuration["API_KEY"];
|
||||
|
||||
|
||||
|
|
@ -132,7 +132,7 @@ namespace BMA.EHR.Application.Repositories
|
|||
{
|
||||
try
|
||||
{
|
||||
var apiPath = $"{_configuration["API"]}/org/dotnet/find/employee/position";
|
||||
var apiPath = $"{_configuration["API"]}/org/unauthorize/find/employee/position";
|
||||
var apiKey = _configuration["API_KEY"];
|
||||
|
||||
var body = new
|
||||
|
|
@ -146,7 +146,7 @@ namespace BMA.EHR.Application.Repositories
|
|||
// สร้าง HTTP content
|
||||
//var body = new StringContent(bodyJson, Encoding.UTF8, "application/json");
|
||||
|
||||
var apiResult = await PostExternalAPIAsync(apiPath, accessToken, body, apiKey);
|
||||
var apiResult = await PostExternalAPIAsync(apiPath, accessToken ?? "", body, apiKey);
|
||||
|
||||
if (apiResult != null)
|
||||
{
|
||||
|
|
@ -157,7 +157,7 @@ namespace BMA.EHR.Application.Repositories
|
|||
|
||||
return null;
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
|
@ -186,6 +186,78 @@ namespace BMA.EHR.Application.Repositories
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public async Task<GetProfileByKeycloakIdDto?> GetProfileByKeycloakIdNewAsync(Guid keycloakId, string? accessToken,CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
var apiPath = $"{_configuration["API"]}/org/dotnet/by-keycloak/{keycloakId}";
|
||||
var apiKey = _configuration["API_KEY"];
|
||||
|
||||
var apiResult = await GetExternalAPIAsync(apiPath, accessToken ?? "", apiKey, cancellationToken);
|
||||
if (apiResult != null)
|
||||
{
|
||||
var raw = JsonConvert.DeserializeObject<GetProfileByKeycloakIdResultDto>(apiResult);
|
||||
if (raw != null)
|
||||
return raw.Result;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<GetProfileByKeycloakIdDto?> GetProfileByKeycloakIdNew2Async(Guid keycloakId, string? accessToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
var apiPath = $"{_configuration["API"]}/org/dotnet/by-keycloak2/{keycloakId}";
|
||||
var apiKey = _configuration["API_KEY"];
|
||||
|
||||
var apiResult = await GetExternalAPIAsync(apiPath, accessToken ?? "", apiKey);
|
||||
if (apiResult != null)
|
||||
{
|
||||
var raw = JsonConvert.DeserializeObject<GetProfileByKeycloakIdResultDto>(apiResult);
|
||||
if (raw != null)
|
||||
return raw.Result;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<GetProfileByKeycloakIdDto?> GetProfileByCheckInAsync(Guid keycloakId, string? accessToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
var apiPath = $"{_configuration["API"]}/org/dotnet/check-keycloak/{keycloakId}";
|
||||
var apiKey = _configuration["API_KEY"];
|
||||
|
||||
var apiResult = await GetExternalAPIAsync(apiPath, accessToken ?? "", apiKey);
|
||||
if (apiResult != null)
|
||||
{
|
||||
var raw = JsonConvert.DeserializeObject<GetProfileByKeycloakIdResultDto>(apiResult);
|
||||
if (raw != null)
|
||||
return raw.Result;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public async Task<GetProfileLeaveByKeycloakDto?> GetProfileLeaveByKeycloakIdAsync(Guid keycloakId, string? accessToken)
|
||||
{
|
||||
try
|
||||
|
|
@ -209,6 +281,66 @@ namespace BMA.EHR.Application.Repositories
|
|||
}
|
||||
}
|
||||
|
||||
public async Task<List<GetOcStaff>?> GetOCStaffAsync(Guid profileId, string? accessToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
var apiPath = $"{_configuration["API"]}/org/dotnet/find-staff";
|
||||
var apiKey = _configuration["API_KEY"];
|
||||
var body = new
|
||||
{
|
||||
assignId = "SYS_LEAVE_LIST",
|
||||
profileId = profileId
|
||||
};
|
||||
|
||||
//var profiles = new List<GetOcStaff>();
|
||||
|
||||
var apiResult = await PostExternalAPIAsync(apiPath, accessToken ?? "", body, apiKey);
|
||||
if (apiResult != null)
|
||||
{
|
||||
var raw = JsonConvert.DeserializeObject<GetOcStaffResultDto>(apiResult);
|
||||
if (raw != null)
|
||||
return raw.Result;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<GetProfileLeaveByKeycloakDto?> GetProfileLeaveReportByKeycloakIdAsync(Guid keycloakId, string? accessToken, string? report)
|
||||
{
|
||||
try
|
||||
{
|
||||
var apiPath = $"{_configuration["API"]}/org/dotnet/profile-leave/keycloak";
|
||||
var apiKey = _configuration["API_KEY"];
|
||||
var body = new
|
||||
{
|
||||
keycloakId = keycloakId,
|
||||
report = report
|
||||
};
|
||||
|
||||
//var profiles = new List<SearchProfileDto>();
|
||||
|
||||
var apiResult = await PostExternalAPIAsync(apiPath, accessToken, body, apiKey);
|
||||
if (apiResult != null)
|
||||
{
|
||||
var raw = JsonConvert.DeserializeObject<GetProfileLeaveByKeycloakResultDto>(apiResult);
|
||||
if (raw != null)
|
||||
return raw.Result;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<GetProfileByKeycloakIdDto?> GetProfileByProfileIdAsync(Guid profileId, string? accessToken)
|
||||
{
|
||||
try
|
||||
|
|
@ -232,6 +364,31 @@ namespace BMA.EHR.Application.Repositories
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public async Task<GetProfileByKeycloakIdDto?> GetProfileByProfileIdNoAuthAsync(Guid profileId, string? accessToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
var apiPath = $"{_configuration["API"]}/org/unauthorize/profile/{profileId}";
|
||||
var apiKey = _configuration["API_KEY"];
|
||||
|
||||
var apiResult = await GetExternalAPIAsync(apiPath, accessToken ?? "", apiKey);
|
||||
if (apiResult != null)
|
||||
{
|
||||
var raw = JsonConvert.DeserializeObject<GetProfileByKeycloakIdResultDto>(apiResult);
|
||||
if (raw != null)
|
||||
return raw.Result;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public async Task<bool> UpdateDutyTimeAsync(Guid profileId, Guid roundId, DateTime effectiveDate, string? accessToken)
|
||||
{
|
||||
try
|
||||
|
|
@ -520,7 +677,7 @@ namespace BMA.EHR.Application.Repositories
|
|||
}
|
||||
}
|
||||
|
||||
public async Task<List<GetProfileByKeycloakIdRootDto>> GetProfileByAdminRole(string? accessToken, int? node, string? nodeId, string role, string? revisionId)
|
||||
public async Task<List<GetProfileByKeycloakIdRootDto>> GetProfileByAdminRole(string? accessToken, int? node, string? nodeId, string role, string? revisionId, int? reqNode, string? reqNodeId, DateTime? startDate, DateTime? endDate)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -532,6 +689,10 @@ namespace BMA.EHR.Application.Repositories
|
|||
nodeId = nodeId,
|
||||
role = role,
|
||||
revisionId = revisionId,
|
||||
reqNode = reqNode,
|
||||
reqNodeId = reqNodeId,
|
||||
//startDate = startDate,
|
||||
//endDate = endDate
|
||||
};
|
||||
|
||||
var profiles = new List<SearchProfileDto>();
|
||||
|
|
@ -552,6 +713,187 @@ namespace BMA.EHR.Application.Repositories
|
|||
}
|
||||
}
|
||||
|
||||
public async Task<List<GetProfileByKeycloakIdRootDto>> GetProfileByAdminRolev2(string? accessToken, int? node, string? nodeId, string role, string? revisionId, int? reqNode, string? reqNodeId, DateTime? startDate, DateTime? endDate)
|
||||
{
|
||||
try
|
||||
{
|
||||
var apiPath = $"{_configuration["API"]}/org/dotnet/officer-by-admin-rolev2";
|
||||
var apiKey = _configuration["API_KEY"];
|
||||
var body = new
|
||||
{
|
||||
node = node,
|
||||
nodeId = nodeId,
|
||||
role = role,
|
||||
// revisionId = revisionId,
|
||||
reqNode = reqNode,
|
||||
reqNodeId = reqNodeId,
|
||||
// startDate = startDate,
|
||||
// endDate = endDate
|
||||
date = endDate
|
||||
};
|
||||
Console.WriteLine(body);
|
||||
|
||||
var profiles = new List<SearchProfileDto>();
|
||||
|
||||
var apiResult = await PostExternalAPIAsync(apiPath, accessToken, body, apiKey);
|
||||
if (apiResult != null)
|
||||
{
|
||||
var raw = JsonConvert.DeserializeObject<GetListProfileByKeycloakIdRootResultDto>(apiResult);
|
||||
if (raw != null)
|
||||
return raw.Result;
|
||||
}
|
||||
|
||||
return new List<GetProfileByKeycloakIdRootDto>();
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<List<GetProfileByKeycloakIdRootDto>> GetProfileByAdminRolev3(string? accessToken, int? node, string? nodeId, string role, string? revisionId, int? reqNode, string? reqNodeId, DateTime? startDate, DateTime? endDate)
|
||||
{
|
||||
try
|
||||
{
|
||||
var apiPath = $"{_configuration["API"]}/org/dotnet/officer-by-admin-rolev3";
|
||||
var apiKey = _configuration["API_KEY"];
|
||||
var body = new
|
||||
{
|
||||
node = node,
|
||||
nodeId = nodeId,
|
||||
role = role,
|
||||
// revisionId = revisionId,
|
||||
reqNode = reqNode,
|
||||
reqNodeId = reqNodeId,
|
||||
startDate = startDate,
|
||||
endDate = endDate
|
||||
};
|
||||
|
||||
var profiles = new List<SearchProfileDto>();
|
||||
|
||||
var apiResult = await PostExternalAPIAsync(apiPath, accessToken, body, apiKey);
|
||||
if (apiResult != null)
|
||||
{
|
||||
var raw = JsonConvert.DeserializeObject<GetListProfileByKeycloakIdRootResultDto>(apiResult);
|
||||
if (raw != null)
|
||||
return raw.Result;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<List<GetProfileByKeycloakIdRootDto>> GetAllOfficerByRootDnaId(string? rootDnaId, DateTime date)
|
||||
{
|
||||
try
|
||||
{
|
||||
var apiPath = $"{_configuration["API"]}/org/unauthorize/officer-list";
|
||||
var apiKey = _configuration["API_KEY"];
|
||||
var body = new
|
||||
{
|
||||
reqNode = 0,
|
||||
reqNodeId = rootDnaId,
|
||||
date = date
|
||||
};
|
||||
//Console.WriteLine(body);
|
||||
|
||||
var profiles = new List<SearchProfileDto>();
|
||||
|
||||
var apiResult = await PostExternalAPIAsync(apiPath, "", body, apiKey);
|
||||
if (apiResult != null)
|
||||
{
|
||||
var raw = JsonConvert.DeserializeObject<GetListProfileByKeycloakIdRootResultDto>(apiResult);
|
||||
if (raw != null)
|
||||
return raw.Result;
|
||||
else
|
||||
return new List<GetProfileByKeycloakIdRootDto>();
|
||||
}
|
||||
else
|
||||
return new List<GetProfileByKeycloakIdRootDto>();
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<List<GetProfileByKeycloakIdRootDto>> GetAllEmployeeByRootDnaId(string? rootDnaId, DateTime date)
|
||||
{
|
||||
try
|
||||
{
|
||||
var apiPath = $"{_configuration["API"]}/org/unauthorize/employee-list";
|
||||
var apiKey = _configuration["API_KEY"];
|
||||
var body = new
|
||||
{
|
||||
reqNode = 0,
|
||||
reqNodeId = rootDnaId,
|
||||
startDate = date,
|
||||
endDate = date
|
||||
};
|
||||
//Console.WriteLine(body);
|
||||
|
||||
var profiles = new List<SearchProfileDto>();
|
||||
|
||||
var apiResult = await PostExternalAPIAsync(apiPath, "", body, apiKey);
|
||||
if (apiResult != null)
|
||||
{
|
||||
var raw = JsonConvert.DeserializeObject<GetListProfileByKeycloakIdRootResultDto>(apiResult);
|
||||
if (raw != null)
|
||||
return raw.Result;
|
||||
else
|
||||
return new List<GetProfileByKeycloakIdRootDto>();
|
||||
}
|
||||
else
|
||||
return new List<GetProfileByKeycloakIdRootDto>();
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<List<GetProfileByKeycloakIdRootDto>> GetProfileByAdminRolev4(string? accessToken, int? node, string? nodeId, string role, string? revisionId, int? reqNode, string? reqNodeId, DateTime? startDate, DateTime? endDate)
|
||||
{
|
||||
try
|
||||
{
|
||||
var apiPath = $"{_configuration["API"]}/org/dotnet/officer-by-admin-rolev4";
|
||||
var apiKey = _configuration["API_KEY"];
|
||||
var body = new
|
||||
{
|
||||
node = node,
|
||||
nodeId = nodeId,
|
||||
role = role,
|
||||
// revisionId = revisionId,
|
||||
reqNode = reqNode,
|
||||
reqNodeId = reqNodeId,
|
||||
// startDate = startDate,
|
||||
// endDate = endDate
|
||||
date = endDate
|
||||
};
|
||||
Console.WriteLine(body);
|
||||
|
||||
var profiles = new List<SearchProfileDto>();
|
||||
|
||||
var apiResult = await PostExternalAPIAsync(apiPath, accessToken, body, apiKey);
|
||||
if (apiResult != null)
|
||||
{
|
||||
var raw = JsonConvert.DeserializeObject<GetListProfileByKeycloakIdRootResultDto>(apiResult);
|
||||
if (raw != null)
|
||||
return raw.Result;
|
||||
}
|
||||
|
||||
return new List<GetProfileByKeycloakIdRootDto>();
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<List<GetProfileByKeycloakIdRootDto>> GetProfileWithKeycloakAllOfficerRetireFilterAndRevision(string? accessToken, int? node, string? nodeId, bool isAll, bool? isRetirement, string? revisionId)
|
||||
{
|
||||
try
|
||||
|
|
@ -684,7 +1026,7 @@ namespace BMA.EHR.Application.Repositories
|
|||
}
|
||||
}
|
||||
|
||||
public async Task<List<GetProfileByKeycloakIdRootDto>> GetEmployeeByAdminRole(string? accessToken, int? node, string? nodeId, string role, string? revisionId)
|
||||
public async Task<List<GetProfileByKeycloakIdRootDto>> GetEmployeeByAdminRole(string? accessToken, int? node, string? nodeId, string role, string? revisionId, int? reqNode, string? reqNodeId, DateTime? startDate, DateTime? endDate)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -696,6 +1038,10 @@ namespace BMA.EHR.Application.Repositories
|
|||
nodeId = nodeId,
|
||||
role = role,
|
||||
revisionId = revisionId,
|
||||
reqNode = reqNode,
|
||||
reqNodeId = reqNodeId,
|
||||
startDate = startDate,
|
||||
endDate = endDate
|
||||
};
|
||||
|
||||
var profiles = new List<SearchProfileDto>();
|
||||
|
|
@ -716,7 +1062,43 @@ namespace BMA.EHR.Application.Repositories
|
|||
}
|
||||
}
|
||||
|
||||
public async Task<List<SearchProfileDto>> SearchProfile(string? citizenId, string? firstName, string? lastName, string accessToken, string? role, string? nodeId, int? node)
|
||||
public async Task<List<GetProfileByKeycloakIdRootDto>> GetEmployeeByAdminRolev2(string? accessToken, int? node, string? nodeId, string role, string? revisionId, int? reqNode, string? reqNodeId, DateTime? startDate, DateTime? endDate)
|
||||
{
|
||||
try
|
||||
{
|
||||
var apiPath = $"{_configuration["API"]}/org/dotnet/employee-by-admin-rolev2";
|
||||
var apiKey = _configuration["API_KEY"];
|
||||
var body = new
|
||||
{
|
||||
node = node,
|
||||
nodeId = nodeId,
|
||||
role = role,
|
||||
// isRetirement
|
||||
reqNode = reqNode,
|
||||
reqNodeId = reqNodeId,
|
||||
date = endDate
|
||||
};
|
||||
Console.WriteLine(body);
|
||||
|
||||
var profiles = new List<SearchProfileDto>();
|
||||
|
||||
var apiResult = await PostExternalAPIAsync(apiPath, accessToken, body, apiKey);
|
||||
if (apiResult != null)
|
||||
{
|
||||
var raw = JsonConvert.DeserializeObject<GetListProfileByKeycloakIdRootResultDto>(apiResult);
|
||||
if (raw != null)
|
||||
return raw.Result;
|
||||
}
|
||||
|
||||
return new List<GetProfileByKeycloakIdRootDto>();
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<GetProfileByKeycloakIdRootAddTotalDto> SearchProfile(string? citizenId, string? firstName, string? lastName, string accessToken, int page, int pageSize, string? role, string? nodeId, int? node,string? selectedNodeId,int? selectedNode )
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -730,41 +1112,27 @@ namespace BMA.EHR.Application.Repositories
|
|||
role = role,
|
||||
nodeId = nodeId,
|
||||
node = node,
|
||||
page = page,
|
||||
pageSize = pageSize,
|
||||
selectedNodeId = selectedNodeId,
|
||||
selectedNode = selectedNode
|
||||
};
|
||||
|
||||
var profiles = new List<SearchProfileDto>();
|
||||
var profiles = new List<GetProfileByKeycloakIdRootDto>();
|
||||
var total = 0;
|
||||
|
||||
var apiResult = await PostExternalAPIAsync(apiPath, accessToken, body, apiKey);
|
||||
if (apiResult != null)
|
||||
{
|
||||
var raw = JsonConvert.DeserializeObject<SearchProfileResultDto>(apiResult);
|
||||
var raw = JsonConvert.DeserializeObject<GetListProfileByKeycloakIdRootResultAddTotalDto>(apiResult);
|
||||
if (raw != null && raw.Result != null)
|
||||
{
|
||||
profiles.AddRange(raw.Result);
|
||||
profiles = raw.Result.Data;
|
||||
total = raw.Result.Total;
|
||||
}
|
||||
}
|
||||
|
||||
return profiles;
|
||||
|
||||
//var data = _dbContext.Set<Profile>().AsQueryable()
|
||||
// .Where(x => x.ProfileType == "officer");
|
||||
|
||||
|
||||
//if (citizenId != null)
|
||||
// data = data.Where(x => x.CitizenId!.Contains(citizenId));
|
||||
|
||||
//if (firstName != null)
|
||||
// data = data.Where(x => x.FirstName!.Contains(firstName));
|
||||
|
||||
//if (lastName != null)
|
||||
// data = data.Where(x => x.LastName!.Contains(lastName));
|
||||
|
||||
//data = data.Include(x => x.Prefix)
|
||||
// .Include(x => x.Position)
|
||||
// .Include(x => x.PositionLevel)
|
||||
// .Include(x => x.PosNo);
|
||||
|
||||
//return await data.ToListAsync();
|
||||
return new GetProfileByKeycloakIdRootAddTotalDto { Data = profiles, Total = total };
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
|
@ -772,7 +1140,7 @@ namespace BMA.EHR.Application.Repositories
|
|||
}
|
||||
}
|
||||
|
||||
public async Task<List<SearchProfileDto>> SearchProfileEmployee(string? citizenId, string? firstName, string? lastName, string accessToken, string? role, string? nodeId, int? node)
|
||||
public async Task<GetProfileByKeycloakIdRootAddTotalDto> SearchProfileEmployee(string? citizenId, string? firstName, string? lastName, string accessToken, int page, int pageSize, string? role, string? nodeId, int? node)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -786,41 +1154,25 @@ namespace BMA.EHR.Application.Repositories
|
|||
role = role,
|
||||
nodeId = nodeId,
|
||||
node = node,
|
||||
page = page,
|
||||
pageSize = pageSize,
|
||||
};
|
||||
|
||||
var profiles = new List<SearchProfileDto>();
|
||||
var profiles = new List<GetProfileByKeycloakIdRootDto>();
|
||||
var total = 0;
|
||||
|
||||
var apiResult = await PostExternalAPIAsync(apiPath, accessToken, body, apiKey);
|
||||
if (apiResult != null)
|
||||
{
|
||||
var raw = JsonConvert.DeserializeObject<SearchProfileResultDto>(apiResult);
|
||||
var raw = JsonConvert.DeserializeObject<GetListProfileByKeycloakIdRootResultAddTotalDto>(apiResult);
|
||||
if (raw != null && raw.Result != null)
|
||||
{
|
||||
profiles.AddRange(raw.Result);
|
||||
profiles.AddRange(raw.Result.Data);
|
||||
total = raw.Result.Total;
|
||||
}
|
||||
}
|
||||
|
||||
return profiles;
|
||||
|
||||
|
||||
//var data = _dbContext.Set<Profile>().AsQueryable()
|
||||
// .Where(x => x.ProfileType == "employee");
|
||||
|
||||
|
||||
//if (citizenId != null)
|
||||
// data = data.Where(x => x.CitizenId!.Contains(citizenId));
|
||||
|
||||
//if (firstName != null)
|
||||
// data = data.Where(x => x.FirstName!.Contains(firstName));
|
||||
|
||||
//if (lastName != null)
|
||||
// data = data.Where(x => x.LastName!.Contains(lastName));
|
||||
|
||||
//data = data.Include(x => x.Prefix);
|
||||
////.Include(x => x.PosNoEmployee);
|
||||
|
||||
|
||||
//return await data.ToListAsync();
|
||||
return new GetProfileByKeycloakIdRootAddTotalDto { Data = profiles, Total = total };
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
|
@ -966,7 +1318,7 @@ namespace BMA.EHR.Application.Repositories
|
|||
}
|
||||
}
|
||||
|
||||
public GetOrganizationResponseDTO? GetOc(Guid ocId, int level, string? accessToken)
|
||||
public GetOrganizationResponseDTO? GetOcByNodeId(Guid ocId, int level, string? accessToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -997,6 +1349,38 @@ namespace BMA.EHR.Application.Repositories
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public GetOrganizationResponseDTO? GetOc(Guid ocId, int level, string? accessToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
var apiPath = $"{_configuration["API"]}/org/find/allv2";
|
||||
var apiKey = _configuration["API_KEY"];
|
||||
var body = new
|
||||
{
|
||||
nodeId = ocId,
|
||||
node = level
|
||||
|
||||
};
|
||||
|
||||
var apiResult = PostExternalAPIAsync(apiPath, accessToken ?? "", body, apiKey).Result;
|
||||
if (apiResult != null)
|
||||
{
|
||||
var raw = JsonConvert.DeserializeObject<GetOrganizationResponseResultDTO>(apiResult);
|
||||
if (raw != null && raw.Result != null)
|
||||
{
|
||||
return raw.Result;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public GetProfileByIdDto GetOfficerProfileById(Guid id, string? accessToken)
|
||||
{
|
||||
try
|
||||
|
|
@ -1116,7 +1500,7 @@ namespace BMA.EHR.Application.Repositories
|
|||
{
|
||||
try
|
||||
{
|
||||
var apiPath = $"{_configuration["API"]}/org/active/root/all";
|
||||
var apiPath = $"{_configuration["API"]}/org/unauthorize/active/root/all";
|
||||
var apiKey = _configuration["API_KEY"];
|
||||
|
||||
var apiResult = await GetExternalAPIAsync(apiPath, accessToken ?? "", apiKey);
|
||||
|
|
@ -1154,6 +1538,29 @@ namespace BMA.EHR.Application.Repositories
|
|||
|
||||
}
|
||||
|
||||
public async Task PostInsigniaMessageToSocket(string message, string userId, string? accessToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
var apiPath = $"{_configuration["API"]}/org/through-socket/notify";
|
||||
var apiKey = _configuration["API_KEY"];
|
||||
|
||||
var body = new
|
||||
{
|
||||
message = message,
|
||||
userId = userId
|
||||
};
|
||||
|
||||
var apiResult = await PostExternalAPIBooleanAsync(apiPath, accessToken ?? "", body, apiKey);
|
||||
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public async Task PostProfileEmpInsigniaAsync(PostProfileEmpInsigniaDto body, string? accessToken)
|
||||
{
|
||||
try
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using BMA.EHR.Domain.Shared;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace BMA.EHR.Application.Responses.Leaves
|
||||
{
|
||||
public class GetPermissionWithActingDto
|
||||
{
|
||||
public string privilege {get; set;} = string.Empty;
|
||||
public bool isAct {get; set;} = false;
|
||||
public List<ActingPermission> posMasterActs {get; set;} = new();
|
||||
}
|
||||
|
||||
public class ActingPermission
|
||||
{
|
||||
public string posNo {get; set;} = string.Empty;
|
||||
//public string? privilege {get; set;} = "PARENT";
|
||||
[JsonConverter(typeof(PrivilegeConverter))]
|
||||
public string privilege {get; set;} = "CHILD";
|
||||
|
||||
public Guid? rootDnaId {get; set;}
|
||||
public Guid? child1DnaId {get; set;}
|
||||
public Guid? child2DnaId {get; set;}
|
||||
public Guid? child3DnaId {get; set;}
|
||||
public Guid? child4DnaId {get; set;}
|
||||
}
|
||||
|
||||
public class GetPermissionWithActingResultDto
|
||||
{
|
||||
public int status {get; set;} = 0;
|
||||
public string message {get; set;} = string.Empty;
|
||||
public GetPermissionWithActingDto result {get; set;} = new();
|
||||
}
|
||||
}
|
||||
|
|
@ -2,19 +2,27 @@
|
|||
{
|
||||
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; }
|
||||
public int? Amount { get; set; } = 0;
|
||||
public string? TelephoneNumber { get; set; } = string.Empty;
|
||||
public string PositionName { 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; }
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
public string LeaveTypeCode { get; set; } = string.Empty;
|
||||
|
||||
public double SumLeaveDay { get; set; }
|
||||
public double SumLeaveDay { get; set; } = 0.0;
|
||||
|
||||
public int CountLeaveDay { get; set; } = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,5 +37,11 @@ namespace BMA.EHR.Application.Responses.Organizations
|
|||
public string? Child4 { get; set; }
|
||||
|
||||
public string? Child4ShortName { get; set; }
|
||||
|
||||
public Guid? RootDnaId { get; set; }
|
||||
public Guid? Child1DnaId { get; set; }
|
||||
public Guid? Child2DnaId { get; set; }
|
||||
public Guid? Child3DnaId { get; set; }
|
||||
public Guid? Child4DnaId { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,4 +8,12 @@
|
|||
|
||||
public List<GetProfileByKeycloakIdRootDto> Result { get; set; } = new();
|
||||
}
|
||||
public class GetListProfileByKeycloakIdRootResultAddTotalDto
|
||||
{
|
||||
public string Message { get; set; } = string.Empty;
|
||||
|
||||
public int Status { get; set; } = -1;
|
||||
|
||||
public GetProfileByKeycloakIdRootAddTotalDto Result { get; set; } = new();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
35
BMA.EHR.Application/Responses/Profiles/GetOcStaff.cs
Normal file
35
BMA.EHR.Application/Responses/Profiles/GetOcStaff.cs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BMA.EHR.Application.Responses.Profiles
|
||||
{
|
||||
public class GetOcStaff
|
||||
{
|
||||
public Guid ProfileId { get; set; }
|
||||
public Guid Keycloak { get; set; }
|
||||
public string FullName { get; set; } = null!;
|
||||
public Guid? RootId { get; set; }
|
||||
public Guid? OrgChild1Id { get; set; }
|
||||
public Guid? OrgChild2Id { get; set; }
|
||||
public Guid? OrgChild3Id { get; set; }
|
||||
public Guid? OrgChild4Id { get; set; }
|
||||
public Guid? RootDnaId { get; set; }
|
||||
public Guid? Child1DnaId { get; set; }
|
||||
public Guid? Child2DnaId { get; set; }
|
||||
public Guid? Child3DnaId { get; set; }
|
||||
public Guid? Child4DnaId { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public class GetOcStaffResultDto
|
||||
{
|
||||
public string Message { get; set; } = string.Empty;
|
||||
|
||||
public int Status { get; set; } = -1;
|
||||
|
||||
public List<GetOcStaff> Result { get; set; } = new();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -44,6 +44,8 @@ namespace BMA.EHR.Application.Responses.Profiles
|
|||
public string? ProfileType { get; set; }
|
||||
public bool? IsLeave { get; set; }
|
||||
|
||||
public bool? IsProbation { get; set; }
|
||||
|
||||
public string? Root { get; set; }
|
||||
public string? Child1 { get; set; }
|
||||
public string? Child2 { get; set; }
|
||||
|
|
@ -81,6 +83,8 @@ namespace BMA.EHR.Application.Responses.Profiles
|
|||
|
||||
public string? PositionLeaveName { get; set; }
|
||||
|
||||
public string? PosExecutiveName { get; set; }
|
||||
|
||||
public string? CommanderPositionName { get; set; } = string.Empty;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,5 +22,21 @@ namespace BMA.EHR.Application.Responses.Profiles
|
|||
public string? OrgChild3Id { get; set; }
|
||||
public string? OrgChild4Id { get; set; }
|
||||
|
||||
public DateTime? DateStart { get; set; }
|
||||
|
||||
public DateTime? DateAppoint { get; set; }
|
||||
|
||||
public string? RootDnaId { get; set; }
|
||||
public string? Child1DnaId { get; set; }
|
||||
public string? Child2DnaId { get; set; }
|
||||
public string? Child3DnaId { get; set; }
|
||||
public string? Child4DnaId { get; set; }
|
||||
}
|
||||
|
||||
public class GetProfileByKeycloakIdRootAddTotalDto
|
||||
{
|
||||
public List<GetProfileByKeycloakIdRootDto> Data { get; set; } = new();
|
||||
|
||||
public int Total { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
24
BMA.EHR.CheckInConsumer/.dockerignore
Normal file
24
BMA.EHR.CheckInConsumer/.dockerignore
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
# Build artifacts
|
||||
bin/
|
||||
obj/
|
||||
|
||||
# IDE / tooling
|
||||
Properties/
|
||||
.vs/
|
||||
.vscode/
|
||||
.idea/
|
||||
|
||||
# Source control
|
||||
.git/
|
||||
.gitignore
|
||||
|
||||
# Documentation
|
||||
*.md
|
||||
|
||||
# Docker
|
||||
Dockerfile
|
||||
.dockerignore
|
||||
|
||||
# OS files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
83
BMA.EHR.CheckInConsumer/CHANGELOG-checkin-speedup.md
Normal file
83
BMA.EHR.CheckInConsumer/CHANGELOG-checkin-speedup.md
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
# สรุปการปรับปรุงระบบลงเวลา (CheckInConsumer)
|
||||
|
||||
วันที่แก้ไข: 23 มิถุนายน 2026
|
||||
|
||||
---
|
||||
|
||||
## ปัญหาเดิม
|
||||
|
||||
ตอนที่พนักงานลงเวลาพร้อมกันจำนวนมาก (ประมาณ 2,000 รายการ) ระบบประมวลผลทีละรายการ ทำให้ต้องรอคิวนานถึง **22 นาที** กว่าจะประมวลผลเสร็จทั้งหมด
|
||||
|
||||
เปรียบเทียบเหมือน **โต๊ะบัญชี 1 คน รับคิวทีละคน** ทั้งที่มีคนรอ 2,000 คน → คิวยาวมาก
|
||||
|
||||
---
|
||||
|
||||
## วิธีที่แก้ (เข้าใจง่าย ๆ)
|
||||
|
||||
### 1. เพิ่มคนช่วยประมวลผลพร้อมกัน (Concurrency)
|
||||
- **ก่อน:** ประมวลผลทีละรายการ (เหมือนมีโต๊ะบัญชี 1 โต๊ะ)
|
||||
- **หลัง:** ประมวลผลพร้อมกันได้สูงสุด **5 รายการ** (เหมือนเปิดโต๊ะบัญชี 5 โต๊ะ)
|
||||
|
||||
> ผลที่ได้: เวลารอคิวลดลงจาก **22 นาที → ประมาณ 4–5 นาที**
|
||||
|
||||
### 2. จัดคิวล่วงหน้าให้ RabbitMQ (Prefetch)
|
||||
- **ก่อน:** ระบบดึงข้อมูลมาทีละชิ้น ทำให้เสียเวลารอส่งต่อ
|
||||
- **หลัง:** ระบบดึงข้อมูลมาเป็นชุด ๆ ละ 20 ชิ้นไว้เตรียมพร้อม → ลดเวลารอระหว่างรายการ
|
||||
|
||||
### 3. ลดเวลารอเมื่อ API มีปัญหา (Timeout)
|
||||
- **ก่อน:** ถ้า API ค้าง ระบบจะรอนานถึง **5 นาที** ต่อรายการ
|
||||
- **หลัง:** ลดเหลือ **1 นาที** → รายการที่มีปัญหาจะถูกปฏิเสธเร็วขึ้น ไม่ทำให้คิวค้าง
|
||||
|
||||
### 4. ปรับปรุงการเชื่อมต่อ HTTP
|
||||
- เปลี่ยนระบบเชื่อมต่อให้รองรับการส่งคำขอหลายรายการพร้อมกันโดยไม่สะดุด
|
||||
|
||||
---
|
||||
|
||||
## ตัวเลขเปรียบเทียบ
|
||||
|
||||
| รายการ | ก่อนแก้ | หลังแก้ |
|
||||
|---|---|---|
|
||||
| จำนวนรายการที่ประมวลผลพร้อมกัน | 1 | 5 |
|
||||
| เวลารอคิวสูงสุด (2,000 รายการ) | ~22 นาที | ~4–5 นาที |
|
||||
| เวลารอเมื่อ API มีปัญหา | 5 นาที | 1 นาที |
|
||||
|
||||
---
|
||||
|
||||
## ไฟล์ที่แก้ไข
|
||||
|
||||
1. **`Program.cs`** — โค้ดหลักของตัวประมวลผลคิว
|
||||
2. **`appsettings.json`** — ไฟล์ตั้งค่าระบบ
|
||||
|
||||
---
|
||||
|
||||
## วิธีปรับความเร็วเพิ่มเติม (ไม่ต้องเขียนโค้ดใหม่)
|
||||
|
||||
ถ้าหลังทดสอบแล้วเห็นว่าระบบรับได้ และอยากให้เร็วขึ้นอีก ให้แก้ไขไฟล์ `appsettings.json` แล้ว restart โปรแกรมได้เลย:
|
||||
|
||||
```json
|
||||
{
|
||||
"MaxConcurrency": 10, ← เพิ่มจาก 5 เป็น 10 (ประมวลผลพร้อมกัน 10 รายการ)
|
||||
"PrefetchCount": 50, ← ควรตั้งเป็น ประมาณ MaxConcurrency × 2 ขึ้นไป
|
||||
"HttpTimeoutSeconds": 60 ← เวลารอ API วินาที
|
||||
}
|
||||
```
|
||||
|
||||
**ค่าที่ใช้และผลที่คาดการณ์:**
|
||||
- `MaxConcurrency = 5` → ใช้เวลา ~4–5 นาที (ค่าเริ่มต้นปลอดภัย)
|
||||
- `MaxConcurrency = 10` → ใช้เวลา ~2–3 นาที
|
||||
- `MaxConcurrency = 20` → ใช้เวลา ~1–2 นาที (ต้องตรวจสอบว่าระบบหลังบ้านรับไหวก่อน)
|
||||
|
||||
---
|
||||
|
||||
## ข้อควรระวัง / คำแนะนำ
|
||||
|
||||
1. **ควรทดสอบในระบบทดสอบก่อน** โดยดูว่า
|
||||
- ไม่มี error ในระบบหลัก (API)
|
||||
- ฐานข้อมูลไม่ช้าผิดปกติ
|
||||
- ไม่พบปัญหาลงเวลาซ้ำซ้อน
|
||||
|
||||
2. ถ้าพบปัญหา เช่น
|
||||
- มี error ใน API → **ลด** `MaxConcurrency` เหลือ 2 หรือ 3
|
||||
- ลงเวลาซ้ำ → แจ้งทีมเทคนิคเพื่อแก้ฝั่ง API เพิ่มเติม
|
||||
|
||||
3. **ค่า `MaxConcurrency = 5` เป็นค่าปลอดภัย** เพราะระบบ API ด้านหลังยังมีข้อจำกัดอยู่บางส่วน หากต้องการเพิ่มให้สูงกว่านี้ (เช่น 20–50) ควรปรึกษาทีมเทคนิคเพื่อปรับปรุงฝั่ง API ก่อน
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
## See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
|
||||
## See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
|
||||
#
|
||||
## This stage is used when running from VS in fast mode (Default for Debug configuration)
|
||||
#FROM mcr.microsoft.com/dotnet/runtime:8.0 AS base
|
||||
|
|
@ -21,6 +21,7 @@
|
|||
#ARG BUILD_CONFIGURATION=Release
|
||||
#RUN dotnet publish "BMA.EHR.CheckInConsumer.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
|
||||
#
|
||||
|
||||
## This stage is used in production or when running from VS in regular mode (Default when not using the Debug configuration)
|
||||
#FROM base AS final
|
||||
#WORKDIR /app
|
||||
|
|
@ -29,30 +30,25 @@
|
|||
|
||||
|
||||
# ใช้ official .NET SDK image สำหรับการ build
|
||||
# Note: Build context = repository root (ตามที่ GitHub Actions ใช้)
|
||||
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
|
||||
|
||||
# กำหนด working directory ภายใน container
|
||||
WORKDIR /src
|
||||
|
||||
# คัดลอกไฟล์ .csproj และ restore dependencies
|
||||
# COPY *.csproj ./
|
||||
COPY . ./
|
||||
RUN dotnet restore
|
||||
# copy เฉพาะ .csproj ก่อน เพื่อใช้ layer caching (restore เร็ว เก็บ cache นาน)
|
||||
COPY BMA.EHR.CheckInConsumer/BMA.EHR.CheckInConsumer.csproj ./BMA.EHR.CheckInConsumer/
|
||||
WORKDIR /src/BMA.EHR.CheckInConsumer
|
||||
RUN dotnet restore "BMA.EHR.CheckInConsumer.csproj"
|
||||
|
||||
# คัดลอกไฟล์ทั้งหมดและ build
|
||||
COPY . ./
|
||||
RUN dotnet build -c Release -o /app/build
|
||||
# WORKDIR "/src/BMA.EHR.CheckInConsumer"
|
||||
# RUN dotnet build "BMA.EHR.CheckInConsumer.csproj" -c Release -o /app/build
|
||||
# คัดลอก source ที่เหลือแล้ว publish
|
||||
COPY BMA.EHR.CheckInConsumer/ ./
|
||||
RUN dotnet publish "BMA.EHR.CheckInConsumer.csproj" -c Release -o /app/publish /p:UseAppHost=false
|
||||
|
||||
# ใช้ stage ใหม่สำหรับการ runtime
|
||||
# ใช้ stage ใหม่สำหรับ runtime (image เล็กลง)
|
||||
FROM mcr.microsoft.com/dotnet/runtime:8.0 AS runtime
|
||||
|
||||
# กำหนด working directory สำหรับ runtime
|
||||
WORKDIR /app
|
||||
|
||||
# คัดลอกไฟล์จาก build stage มายัง runtime stage
|
||||
COPY --from=build /app/build .
|
||||
COPY --from=build /app/publish .
|
||||
|
||||
# ระบุ entry point ของแอปพลิเคชัน
|
||||
ENTRYPOINT ["dotnet", "BMA.EHR.CheckInConsumer.dll"]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using RabbitMQ.Client;
|
||||
using RabbitMQ.Client.Events;
|
||||
using System.Text;
|
||||
|
|
@ -18,66 +18,101 @@ var user = configuration["Rabbit:User"] ?? "";
|
|||
var pass = configuration["Rabbit:Password"] ?? "";
|
||||
var queue = configuration["Rabbit:Queue"] ?? "basic-queue";
|
||||
|
||||
// Concurrency & prefetch (configurable via appsettings.json)
|
||||
var maxConcurrency = int.TryParse(configuration["MaxConcurrency"], out var c) && c > 0 ? c : 5;
|
||||
var prefetchCount = ushort.TryParse(configuration["PrefetchCount"], out var p) && p > 0 ? p : (ushort)20;
|
||||
var httpTimeoutSec = int.TryParse(configuration["HttpTimeoutSeconds"], out var t) && t > 0 ? t : 60;
|
||||
|
||||
WriteToConsole($"Config -> MaxConcurrency: {maxConcurrency}, PrefetchCount: {prefetchCount}, HttpTimeout: {httpTimeoutSec}s");
|
||||
|
||||
// create connection
|
||||
var factory = new ConnectionFactory()
|
||||
{
|
||||
//Uri = new Uri("amqp://admin:P@ssw0rd@192.168.4.11:5672")
|
||||
HostName = host,// หรือ hostname ของ RabbitMQ Server ที่คุณใช้
|
||||
UserName = user, // ใส่ชื่อผู้ใช้ของคุณ
|
||||
Password = pass // ใส่รหัสผ่านของคุณ
|
||||
HostName = host,
|
||||
UserName = user,
|
||||
Password = pass,
|
||||
DispatchConsumersAsync = true
|
||||
};
|
||||
|
||||
using var connection = factory.CreateConnection();
|
||||
using var channel = connection.CreateModel();
|
||||
|
||||
//channel.QueueDeclare(queue: "bma-checkin-queue", durable: true, exclusive: false, autoDelete: false, arguments: null);
|
||||
channel.QueueDeclare(queue: queue, durable: true, exclusive: false, autoDelete: false, arguments: null);
|
||||
|
||||
var consumer = new EventingBasicConsumer(channel);
|
||||
// Prefetch: RabbitMQ จะส่ง message หลายตัวมาที่ consumer พร้อมกัน (ลด network round-trip)
|
||||
channel.BasicQos(prefetchSize: 0, prefetchCount: prefetchCount, global: false);
|
||||
|
||||
consumer.Received += async (model, ea) =>
|
||||
// HttpClient แบบ SocketsHttpHandler พร้อม connection pooling รองรับ concurrent requests
|
||||
var socketsHandler = new SocketsHttpHandler
|
||||
{
|
||||
MaxConnectionsPerServer = maxConcurrency * 2,
|
||||
PooledConnectionLifetime = TimeSpan.FromMinutes(2),
|
||||
PooledConnectionIdleTimeout = TimeSpan.FromSeconds(30)
|
||||
};
|
||||
using var httpClient = new HttpClient(socketsHandler);
|
||||
httpClient.Timeout = TimeSpan.FromSeconds(httpTimeoutSec);
|
||||
|
||||
// SemaphoreSlim คุมจำนวน message ที่ประมวลผลพร้อมกัน (เนื่องจาก API มีข้อจำกัดเรื่อง concurrency)
|
||||
using var semaphore = new SemaphoreSlim(maxConcurrency, maxConcurrency);
|
||||
|
||||
var consumer = new AsyncEventingBasicConsumer(channel);
|
||||
|
||||
consumer.Received += (model, ea) =>
|
||||
{
|
||||
// รอ semaphore ก่อนเริ่มประมวลผล
|
||||
semaphore.WaitAsync().ContinueWith(async _ =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var body = ea.Body.ToArray();
|
||||
var message = Encoding.UTF8.GetString(body);
|
||||
await CallRestApi(message);
|
||||
|
||||
// convert string into object
|
||||
//var request = JsonConvert.DeserializeObject<CheckInRequest>(message);
|
||||
//using (var db = new ApplicationDbContext())
|
||||
//{
|
||||
// var item = new AttendantItem
|
||||
// {
|
||||
// Name = request.Name,
|
||||
// CheckInDateTime = request.CheckInDateTime,
|
||||
// };
|
||||
// db.AttendantItems.Add(item);
|
||||
// db.SaveChanges();
|
||||
WriteToConsole($"Received message: {message}");
|
||||
|
||||
// WriteToConsole($"ได้รับคำขอจาก Queue: {message}");
|
||||
// WriteToConsole($"ตอบกลับจาก REST API: {JsonConvert.SerializeObject(item)}");
|
||||
//}
|
||||
var success = await CallRestApi(message, httpClient, configuration);
|
||||
|
||||
WriteToConsole($"ได้รับคำขอจาก Queue: {message}");
|
||||
//WriteToConsole($"ตอบกลับจาก REST API: {JsonConvert.SerializeObject(item)}");
|
||||
if (success)
|
||||
{
|
||||
channel.BasicAck(ea.DeliveryTag, multiple: false);
|
||||
WriteToConsole("Message processed successfully");
|
||||
}
|
||||
else
|
||||
{
|
||||
channel.BasicNack(ea.DeliveryTag, multiple: false, requeue: false);
|
||||
WriteToConsole("Message processing failed - message rejected");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
WriteToConsole($"Error processing message: {ex.Message}");
|
||||
channel.BasicNack(ea.DeliveryTag, multiple: false, requeue: false);
|
||||
}
|
||||
finally
|
||||
{
|
||||
semaphore.Release();
|
||||
}
|
||||
}, TaskScheduler.Default).ConfigureAwait(false);
|
||||
|
||||
return Task.CompletedTask;
|
||||
};
|
||||
|
||||
//channel.BasicConsume(queue: "bma-checkin-queue", autoAck: true, consumer: consumer);
|
||||
channel.BasicConsume(queue: queue, autoAck: true, consumer: consumer);
|
||||
channel.BasicConsume(queue: queue, autoAck: false, consumer: consumer);
|
||||
|
||||
//Console.WriteLine("\nPress 'Enter' to exit the process...");
|
||||
WriteToConsole("Consumer started. Waiting for messages...");
|
||||
|
||||
// Keep the application running
|
||||
await Task.Delay(-1);
|
||||
|
||||
static void WriteToConsole(string message)
|
||||
{
|
||||
Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} : {message}");
|
||||
Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss} : {message}");
|
||||
}
|
||||
|
||||
async Task CallRestApi(string requestData)
|
||||
static async Task<bool> CallRestApi(string requestData, HttpClient client, IConfiguration configuration)
|
||||
{
|
||||
using var client = new HttpClient();
|
||||
try
|
||||
{
|
||||
var apiPath = $"{configuration["API"]}/leave/process-check-in";
|
||||
|
||||
var content = new StringContent(requestData, Encoding.UTF8, "application/json");
|
||||
|
||||
var response = await client.PostAsync(apiPath, content);
|
||||
|
|
@ -85,17 +120,34 @@ async Task CallRestApi(string requestData)
|
|||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
var responseContent = await response.Content.ReadAsStringAsync();
|
||||
WriteToConsole(responseContent);
|
||||
WriteToConsole($"API Success: {responseContent}");
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
var errorMessage = await response.Content.ReadAsStringAsync();
|
||||
var res = JsonSerializer.Deserialize<ResponseObject>(errorMessage);
|
||||
WriteToConsole($"Error: {res.Message}");
|
||||
WriteToConsole($"API Error ({response.StatusCode}): {res?.Message ?? errorMessage}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (HttpRequestException ex)
|
||||
{
|
||||
WriteToConsole($"HTTP Error: {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
catch (TaskCanceledException ex)
|
||||
{
|
||||
WriteToConsole($"Timeout: {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
WriteToConsole($"Unexpected Error: {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class ResponseObject
|
||||
{
|
||||
[JsonPropertyName("status")]
|
||||
|
|
@ -111,28 +163,14 @@ public class ResponseObject
|
|||
public class CheckTimeDtoRB
|
||||
{
|
||||
public Guid? CheckInId { get; set; }
|
||||
|
||||
|
||||
public double Lat { get; set; } = 0;
|
||||
|
||||
|
||||
public double Lon { get; set; } = 0;
|
||||
|
||||
|
||||
public string POI { get; set; } = string.Empty;
|
||||
|
||||
|
||||
public bool IsLocation { get; set; } = true;
|
||||
|
||||
public string? LocationName { get; set; } = string.Empty;
|
||||
|
||||
public string? Remark { get; set; } = string.Empty;
|
||||
|
||||
public Guid? UserId { get; set; }
|
||||
|
||||
public DateTime? CurrentDate { get; set; }
|
||||
|
||||
public string? CheckInFileName { get; set; }
|
||||
|
||||
public byte[]? CheckInFileBytes { get; set; }
|
||||
}
|
||||
|
|
@ -1,9 +1,12 @@
|
|||
{
|
||||
"Rabbit": {
|
||||
"Host": "192.168.1.40",
|
||||
"Host": "192.168.1.63",
|
||||
"User": "admin",
|
||||
"Password": "Test123456",
|
||||
"Queue": "bma-checkin-queue"
|
||||
"Password": "12345678",
|
||||
"Queue": "hrms-checkin-queue-dev"
|
||||
},
|
||||
"API": "https://localhost:7283/api/v1"
|
||||
"API": "https://localhost:7283/api/v1",
|
||||
"MaxConcurrency": 5,
|
||||
"PrefetchCount": 20,
|
||||
"HttpTimeoutSeconds": 60
|
||||
}
|
||||
|
|
@ -8,14 +8,15 @@ using BMA.EHR.Infrastructure.Persistence;
|
|||
// using BMA.EHR.Placement.Service.Requests;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Swashbuckle.AspNetCore.Annotations;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Security.Claims;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
using Swashbuckle.AspNetCore.Annotations;
|
||||
using System.Linq;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Security.Claims;
|
||||
|
||||
namespace BMA.EHR.DisciplineComplaint.Service.Controllers
|
||||
{
|
||||
|
|
@ -133,6 +134,7 @@ namespace BMA.EHR.DisciplineComplaint.Service.Controllers
|
|||
where x.Title.Contains(keyword) ||
|
||||
(x.Appellant == null ? false : x.Appellant.Contains(keyword))
|
||||
select x).ToList();
|
||||
|
||||
if (status.Trim().ToUpper() != "ALL")
|
||||
data_search = data_search.Where(x => x.Status.Contains(status.Trim().ToUpper())).ToList();
|
||||
|
||||
|
|
@ -165,7 +167,7 @@ namespace BMA.EHR.DisciplineComplaint.Service.Controllers
|
|||
.ToList();
|
||||
}
|
||||
|
||||
var data = data_search
|
||||
var query = data_search
|
||||
.Select(x => new
|
||||
{
|
||||
Id = x.Id,//id ข้อมูลเรื่องร้องเรียน
|
||||
|
|
@ -179,11 +181,75 @@ namespace BMA.EHR.DisciplineComplaint.Service.Controllers
|
|||
DateReceived = x.DateReceived,//วันที่รับเรื่อง
|
||||
Status = x.Status,//สถานะเรื่องร้องเรียน มีดังนี้ ใหม่ (NEW), ยุติเรื่อง (STOP), มีมูลส่งไปสืบสวนแล้ว (SEND_INVESTIGATE)
|
||||
Result = x.Result,
|
||||
})
|
||||
.OrderByDescending(x => x.DateConsideration)
|
||||
});
|
||||
|
||||
bool desc = req.descending ?? false;
|
||||
if (!string.IsNullOrEmpty(req.sortBy))
|
||||
{
|
||||
switch (req.sortBy)
|
||||
{
|
||||
case "title":
|
||||
query = desc ? query.OrderByDescending(x => x.Title)
|
||||
: query.OrderBy(x => x.Title);
|
||||
break;
|
||||
|
||||
case "respondentType":
|
||||
query = desc ? query.OrderByDescending(x => x.RespondentType)
|
||||
: query.OrderBy(x => x.RespondentType);
|
||||
break;
|
||||
|
||||
case "appellant":
|
||||
query = desc ? query.OrderByDescending(x => x.Appellant)
|
||||
: query.OrderBy(x => x.Appellant);
|
||||
break;
|
||||
|
||||
case "offenseDetails":
|
||||
query = desc ? query.OrderByDescending(x => x.OffenseDetails)
|
||||
: query.OrderBy(x => x.OffenseDetails);
|
||||
break;
|
||||
|
||||
case "createdAt":
|
||||
query = desc ? query.OrderByDescending(x => x.CreatedAt)
|
||||
: query.OrderBy(x => x.CreatedAt);
|
||||
break;
|
||||
|
||||
case "levelConsideration":
|
||||
query = desc ? query.OrderByDescending(x => x.LevelConsideration)
|
||||
: query.OrderBy(x => x.LevelConsideration);
|
||||
break;
|
||||
|
||||
case "dateConsideration":
|
||||
query = desc ? query.OrderByDescending(x => x.DateConsideration)
|
||||
: query.OrderBy(x => x.DateConsideration);
|
||||
break;
|
||||
|
||||
case "dateReceived":
|
||||
query = desc ? query.OrderByDescending(x => x.DateReceived)
|
||||
: query.OrderBy(x => x.DateReceived);
|
||||
break;
|
||||
|
||||
case "status":
|
||||
query = desc ? query.OrderByDescending(x => x.Status)
|
||||
: query.OrderBy(x => x.Status);
|
||||
break;
|
||||
|
||||
case "result":
|
||||
query = desc ? query.OrderByDescending(x => x.Result)
|
||||
: query.OrderBy(x => x.Result);
|
||||
break;
|
||||
|
||||
default:
|
||||
query = query.OrderByDescending(x => x.DateConsideration);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var data = query
|
||||
.Skip((page - 1) * pageSize)
|
||||
.Take(pageSize)
|
||||
.ToList();
|
||||
|
||||
return Success(new { data, total = data_search.Count() });
|
||||
}
|
||||
|
||||
|
|
@ -771,7 +837,7 @@ namespace BMA.EHR.DisciplineComplaint.Service.Controllers
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
{
|
||||
refId = persons.Select(x => x.PersonId),
|
||||
|
|
|
|||
|
|
@ -90,14 +90,15 @@ namespace BMA.EHR.DisciplineComplaint_Appeal.Service.Controllers
|
|||
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
|
||||
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
|
||||
[HttpGet("user")]
|
||||
public async Task<ActionResult<ResponseObject>> GetDisciplineUser(string status = "ALL", string type = "ALL", int year = 0, int page = 1, int pageSize = 25, string keyword = "")
|
||||
public async Task<ActionResult<ResponseObject>> GetDisciplineUser(string status = "ALL", string type = "ALL", int year = 0, int page = 1, int pageSize = 25, string keyword = "", string? sortBy = null, bool descending = false)
|
||||
{
|
||||
var id = "";
|
||||
var apiUrl = $"{_configuration["API"]}/org/profile/keycloak/position";
|
||||
//var apiUrl = $"{_configuration["API"]}/org/profile/keycloak/position";
|
||||
var apiUrl = $"{_configuration["API"]}/org/dotnet/get-profileId";
|
||||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Get, apiUrl);
|
||||
var _res = await client.SendAsync(_req);
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
|
|
@ -125,7 +126,7 @@ namespace BMA.EHR.DisciplineComplaint_Appeal.Service.Controllers
|
|||
data_search = data_search.Where(x => x.Type == type).ToList();
|
||||
if (year != 0)
|
||||
data_search = data_search.Where(x => x.Year == year).ToList();
|
||||
var data = data_search
|
||||
var query = data_search
|
||||
.Select(x => new
|
||||
{
|
||||
Id = x.Id,
|
||||
|
|
@ -141,8 +142,42 @@ namespace BMA.EHR.DisciplineComplaint_Appeal.Service.Controllers
|
|||
ProfileId = x.ProfileId,
|
||||
LastUpdatedAt = x.LastUpdatedAt,
|
||||
CreatedAt = x.CreatedAt
|
||||
})
|
||||
.OrderByDescending(x => x.CreatedAt)
|
||||
});
|
||||
if (!string.IsNullOrEmpty(sortBy))
|
||||
{
|
||||
{
|
||||
if (sortBy == "title")
|
||||
query = descending ? query.OrderByDescending(x => x.Title) : query.OrderBy(x => x.Title);
|
||||
else if (sortBy == "year")
|
||||
query = descending ? query.OrderByDescending(x => x.Year) : query.OrderBy(x => x.Year);
|
||||
else if (sortBy == "status")
|
||||
query = descending ? query.OrderByDescending(x => x.Status) : query.OrderBy(x => x.Status);
|
||||
else if (sortBy == "description")
|
||||
query = descending ? query.OrderByDescending(x => x.Description) : query.OrderBy(x => x.Description);
|
||||
else if (sortBy == "type")
|
||||
query = descending ? query.OrderByDescending(x => x.Type) : query.OrderBy(x => x.Type);
|
||||
else if (sortBy == "caseType")
|
||||
query = descending ? query.OrderByDescending(x => x.CaseType) : query.OrderBy(x => x.CaseType);
|
||||
else if (sortBy == "caseNumber")
|
||||
query = descending ? query.OrderByDescending(x => x.CaseNumber) : query.OrderBy(x => x.CaseNumber);
|
||||
else if (sortBy == "fullname")
|
||||
query = descending ? query.OrderByDescending(x => x.Fullname) : query.OrderBy(x => x.Fullname);
|
||||
else if (sortBy == "citizenId")
|
||||
query = descending ? query.OrderByDescending(x => x.CitizenId) : query.OrderBy(x => x.CitizenId);
|
||||
else if (sortBy == "lastUpdatedAt")
|
||||
query = descending ? query.OrderByDescending(x => x.LastUpdatedAt) : query.OrderBy(x => x.LastUpdatedAt);
|
||||
else if (sortBy == "createdAt")
|
||||
query = descending ? query.OrderByDescending(x => x.CreatedAt) : query.OrderBy(x => x.CreatedAt);
|
||||
else
|
||||
query = query.OrderByDescending(x => x.CreatedAt); // default
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
query = query.OrderByDescending(x => x.CreatedAt);
|
||||
}
|
||||
|
||||
var data = query
|
||||
.Skip((page - 1) * pageSize)
|
||||
.Take(pageSize)
|
||||
.ToList();
|
||||
|
|
@ -323,14 +358,15 @@ namespace BMA.EHR.DisciplineComplaint_Appeal.Service.Controllers
|
|||
[HttpPost()]
|
||||
public async Task<ActionResult<ResponseObject>> CreateDiscipline([FromForm] DisciplineComplaint_AppealRequest req)
|
||||
{
|
||||
var apiUrl = $"{_configuration["API"]}/org/profile/keycloak/position";
|
||||
//var apiUrl = $"{_configuration["API"]}/org/profile/keycloak/position";
|
||||
var apiUrl = $"{_configuration["API"]}/org/dotnet/get-profileId";
|
||||
var id = "";
|
||||
var type = "";
|
||||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization =
|
||||
new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _req = new HttpRequestMessage(HttpMethod.Get, apiUrl);
|
||||
var _res = await client.SendAsync(_req);
|
||||
var _result = await _res.Content.ReadAsStringAsync();
|
||||
|
|
@ -351,7 +387,7 @@ namespace BMA.EHR.DisciplineComplaint_Appeal.Service.Controllers
|
|||
Description = req.Description,
|
||||
Status = "NEW",
|
||||
Type = req.Type.Trim().ToUpper(),
|
||||
Year = req.Year == null ? DateTime.Now.Year : req.Year,
|
||||
Year = req.Year == null ? DateTime.Now.CalculateFisicalYear() : req.Year,
|
||||
CaseType = req.CaseType,
|
||||
CaseNumber = req.CaseNumber,
|
||||
Fullname = req.Fullname,
|
||||
|
|
@ -370,7 +406,7 @@ namespace BMA.EHR.DisciplineComplaint_Appeal.Service.Controllers
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _apiUrl = $"{_configuration["API"]}/org/profile/profileid/position/{id}";
|
||||
var _req = new HttpRequestMessage(HttpMethod.Get, _apiUrl);
|
||||
var _res = await client.SendAsync(_req);
|
||||
|
|
@ -445,7 +481,7 @@ namespace BMA.EHR.DisciplineComplaint_Appeal.Service.Controllers
|
|||
{
|
||||
client.DefaultRequestHeaders.Authorization =
|
||||
new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var __res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
{
|
||||
refId = new List<Guid> { Guid.Parse(id) },
|
||||
|
|
@ -509,7 +545,7 @@ namespace BMA.EHR.DisciplineComplaint_Appeal.Service.Controllers
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var apiUrl = $"{_configuration["API"]}/org/profile/profileid/position/{req.ProfileId}";
|
||||
var _req = new HttpRequestMessage(HttpMethod.Get, apiUrl);
|
||||
var _res = await client.SendAsync(_req);
|
||||
|
|
@ -583,7 +619,7 @@ namespace BMA.EHR.DisciplineComplaint_Appeal.Service.Controllers
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var __res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
{
|
||||
refId = new List<Guid> { Guid.Parse(req.ProfileId) },
|
||||
|
|
@ -712,7 +748,7 @@ namespace BMA.EHR.DisciplineComplaint_Appeal.Service.Controllers
|
|||
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
|
||||
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
|
||||
[HttpGet("admin")]
|
||||
public async Task<ActionResult<ResponseObject>> GetDisciplineAdmin(string status = "ALL", string type = "ALL", int year = 0, int page = 1, int pageSize = 25, string keyword = "")
|
||||
public async Task<ActionResult<ResponseObject>> GetDisciplineAdmin(string status = "ALL", string type = "ALL", int year = 0, int page = 1, int pageSize = 25, string keyword = "", string? sortBy = "", bool? descending = false)
|
||||
{
|
||||
var getPermission = await _permission.GetPermissionAPIAsync("LIST", "SYS_DISCIPLINE_APPEAL");
|
||||
var jsonData = JsonConvert.DeserializeObject<JObject>(getPermission);
|
||||
|
|
@ -738,7 +774,19 @@ namespace BMA.EHR.DisciplineComplaint_Appeal.Service.Controllers
|
|||
? profileAdmin?.RootDnaId
|
||||
: "";
|
||||
}
|
||||
else if (role == "ROOT")
|
||||
if (role == "BROTHER")
|
||||
{
|
||||
nodeId = profileAdmin?.Node == 4
|
||||
? profileAdmin?.Child3DnaId
|
||||
: profileAdmin?.Node == 3
|
||||
? profileAdmin?.Child2DnaId
|
||||
: profileAdmin?.Node == 2
|
||||
? profileAdmin?.Child1DnaId
|
||||
: profileAdmin?.Node == 1 || profileAdmin?.Node == 0
|
||||
? profileAdmin?.RootDnaId
|
||||
: "";
|
||||
}
|
||||
else if (role == "ROOT" /*|| role == "PARENT"*/)
|
||||
{
|
||||
nodeId = profileAdmin?.RootDnaId;
|
||||
}
|
||||
|
|
@ -768,17 +816,33 @@ namespace BMA.EHR.DisciplineComplaint_Appeal.Service.Controllers
|
|||
data_search = data_search
|
||||
.Where(x => node == 4 ? x.child4DnaId == nodeId : (node == 3 ? x.child3DnaId == nodeId : (node == 2 ? x.child2DnaId == nodeId : (node == 1 ? x.child1DnaId == nodeId : (node == 0 ? x.rootDnaId == nodeId : (node == null ? true : true)))))).ToList();
|
||||
}
|
||||
else if (role == "BROTHER")
|
||||
{
|
||||
data_search = data_search
|
||||
.Where(x => node == 4 ? x.child3DnaId == nodeId : (node == 3 ? x.child2DnaId == nodeId : (node == 2 ? x.child1DnaId == nodeId : (node == 1 || node == 0 ? x.rootDnaId == nodeId : (node == null ? true : true))))).ToList();
|
||||
}
|
||||
else if (role == "ROOT")
|
||||
{
|
||||
data_search = data_search
|
||||
.Where(x => x.rootDnaId == nodeId).ToList();
|
||||
}
|
||||
// else if (role == "PARENT")
|
||||
// {
|
||||
// data_search = data_search
|
||||
// .Where(x => x.rootDnaId == nodeId && x.child1DnaId != null).ToList();
|
||||
// }
|
||||
else if (role == "NORMAL")
|
||||
{
|
||||
data_search = data_search
|
||||
.Where(x => node == 0 ? x.child1DnaId == null : (node == 1 ? x.child2DnaId == null : (node == 2 ? x.child3DnaId == null : (node == 3 ? x.child4DnaId == null : true)))).ToList();
|
||||
data_search = data_search.Where(x =>
|
||||
node == 0 ? x.rootDnaId == nodeId && x.child1DnaId == null :
|
||||
node == 1 ? x.child1DnaId == nodeId && x.child2DnaId == null :
|
||||
node == 2 ? x.child2DnaId == nodeId && x.child3DnaId == null :
|
||||
node == 3 ? x.child3DnaId == nodeId && x.child4DnaId == null :
|
||||
node == 4 ? x.child4DnaId == nodeId :
|
||||
true
|
||||
).ToList();
|
||||
}
|
||||
var data = data_search
|
||||
var query = data_search
|
||||
.Select(x => new
|
||||
{
|
||||
Id = x.Id,
|
||||
|
|
@ -794,12 +858,76 @@ namespace BMA.EHR.DisciplineComplaint_Appeal.Service.Controllers
|
|||
ProfileId = x.ProfileId,
|
||||
LastUpdatedAt = x.LastUpdatedAt,
|
||||
profileType = x.profileType
|
||||
})
|
||||
});
|
||||
bool desc = descending ?? false;
|
||||
if (!string.IsNullOrEmpty(sortBy))
|
||||
{
|
||||
switch (sortBy)
|
||||
{
|
||||
case "title":
|
||||
query = desc ? query.OrderByDescending(x => x.Title)
|
||||
: query.OrderBy(x => x.Title);
|
||||
break;
|
||||
|
||||
case "description":
|
||||
query = desc ? query.OrderByDescending(x => x.Description)
|
||||
: query.OrderBy(x => x.Description);
|
||||
break;
|
||||
|
||||
case "status":
|
||||
query = desc ? query.OrderByDescending(x => x.Status)
|
||||
: query.OrderBy(x => x.Status);
|
||||
break;
|
||||
|
||||
case "type":
|
||||
query = desc ? query.OrderByDescending(x => x.Type)
|
||||
: query.OrderBy(x => x.Type);
|
||||
break;
|
||||
|
||||
case "year":
|
||||
query = desc ? query.OrderByDescending(x => x.Year)
|
||||
: query.OrderBy(x => x.Year);
|
||||
break;
|
||||
|
||||
case "caseType":
|
||||
query = desc ? query.OrderByDescending(x => x.CaseType)
|
||||
: query.OrderBy(x => x.CaseType);
|
||||
break;
|
||||
|
||||
case "caseNumber":
|
||||
query = desc ? query.OrderByDescending(x => x.CaseNumber)
|
||||
: query.OrderBy(x => x.CaseNumber);
|
||||
break;
|
||||
|
||||
case "fullname":
|
||||
query = desc ? query.OrderByDescending(x => x.Fullname)
|
||||
: query.OrderBy(x => x.Fullname);
|
||||
break;
|
||||
|
||||
case "lastUpdatedAt":
|
||||
query = desc ? query.OrderByDescending(x => x.LastUpdatedAt)
|
||||
: query.OrderBy(x => x.LastUpdatedAt);
|
||||
break;
|
||||
|
||||
case "profileType":
|
||||
query = desc ? query.OrderByDescending(x => x.profileType)
|
||||
: query.OrderBy(x => x.profileType);
|
||||
break;
|
||||
|
||||
default:
|
||||
query = query
|
||||
.OrderByDescending(x => x.profileType)
|
||||
.ThenByDescending(x => x.LastUpdatedAt)
|
||||
.ThenByDescending(x => x.LastUpdatedAt);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var data = query
|
||||
.Skip((page - 1) * pageSize)
|
||||
.Take(pageSize)
|
||||
.ToList();
|
||||
|
||||
return Success(new { data, total = data_search.Count() });
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ namespace BMA.EHR.DisciplineDirector.Service.Controllers
|
|||
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
|
||||
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
|
||||
[HttpGet("{path}")]
|
||||
public async Task<ActionResult<ResponseObject>> GetDiscipline(string path, int page = 1, int pageSize = 25, string keyword = "")
|
||||
public async Task<ActionResult<ResponseObject>> GetDiscipline(string path, int page = 1, int pageSize = 25, string keyword = "", string? sortBy = "", bool? descending = false)
|
||||
{
|
||||
// สิทธิ์การเข้าถึง
|
||||
path = path.Trim().ToUpper();
|
||||
|
|
@ -105,7 +105,7 @@ namespace BMA.EHR.DisciplineDirector.Service.Controllers
|
|||
x.Qualification.Contains(keyword)) &&
|
||||
(_permiss != "OWNER" && x.RootDnaId == profile.RootDnaId || _permiss == "OWNER" && true)
|
||||
select x).ToList();
|
||||
var data = data_search
|
||||
var query = data_search
|
||||
.Select(x => new
|
||||
{
|
||||
Id = x.Id,
|
||||
|
|
@ -118,7 +118,66 @@ namespace BMA.EHR.DisciplineDirector.Service.Controllers
|
|||
Qualification = x.Qualification,
|
||||
TotalInvestigate = x.DisciplineInvestigate_Directors.Count(),
|
||||
TotalDisciplinary = x.DisciplineDisciplinary_DirectorInvestigates.Count(),
|
||||
})
|
||||
});
|
||||
|
||||
bool desc = descending ?? false;
|
||||
if (!string.IsNullOrEmpty(sortBy))
|
||||
{
|
||||
if (sortBy == "position")
|
||||
{
|
||||
query = desc ? query.OrderByDescending(x => x.Position)
|
||||
: query.OrderBy(x => x.Position);
|
||||
}
|
||||
else if (sortBy == "prefix" || sortBy == "firstName" || sortBy == "lastName")
|
||||
{
|
||||
query = desc ?
|
||||
query
|
||||
//.OrderByDescending(x => x.Prefix)
|
||||
.OrderByDescending(x => x.FirstName)
|
||||
.ThenByDescending(x => x.LastName) :
|
||||
query
|
||||
//.OrderBy(x => x.Prefix)
|
||||
.OrderBy(x => x.FirstName)
|
||||
.ThenBy(x => x.LastName);
|
||||
}
|
||||
else if (sortBy == "email")
|
||||
{
|
||||
{
|
||||
query = desc ? query.OrderByDescending(x => x.Email)
|
||||
: query.OrderBy(x => x.Email);
|
||||
}
|
||||
}
|
||||
else if (sortBy == "phone")
|
||||
{
|
||||
{
|
||||
query = desc ? query.OrderByDescending(x => x.Phone)
|
||||
: query.OrderBy(x => x.Phone);
|
||||
}
|
||||
}
|
||||
else if (sortBy == "qualification")
|
||||
{
|
||||
{
|
||||
query = desc ? query.OrderByDescending(x => x.Qualification)
|
||||
: query.OrderBy(x => x.Qualification);
|
||||
}
|
||||
}
|
||||
else if (sortBy == "totalInvestigate")
|
||||
{
|
||||
{
|
||||
query = desc ? query.OrderByDescending(x => x.TotalInvestigate)
|
||||
: query.OrderBy(x => x.TotalInvestigate);
|
||||
}
|
||||
}
|
||||
else if (sortBy == "totalDisciplinary")
|
||||
{
|
||||
{
|
||||
query = desc ? query.OrderByDescending(x => x.TotalDisciplinary)
|
||||
: query.OrderBy(x => x.TotalDisciplinary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var data = query
|
||||
.Skip((page - 1) * pageSize)
|
||||
.Take(pageSize)
|
||||
.ToList();
|
||||
|
|
@ -333,7 +392,7 @@ namespace BMA.EHR.DisciplineDirector.Service.Controllers
|
|||
return Error(new Exception(GlobalMessages.DataNotFound), StatusCodes.Status404NotFound);
|
||||
|
||||
var userId = UserId == null ? Guid.Empty : Guid.Parse(UserId);
|
||||
var profile = await _userProfileRepository.GetProfileByKeycloakIdAsync(userId, token.Replace("Bearer ", ""));
|
||||
var profile = await _userProfileRepository.GetProfileByKeycloakIdNewAsync(userId, token.Replace("Bearer ", ""));
|
||||
if (profile == null)
|
||||
return Error(GlobalMessages.DataNotFound);
|
||||
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ namespace BMA.EHR.DisciplineDisciplinary.Service.Controllers
|
|||
.ToList();
|
||||
}
|
||||
|
||||
var data = data_search
|
||||
var query = data_search
|
||||
.Select(x => new
|
||||
{
|
||||
Id = x.Id,//id ข้อมูลเรื่องสอบสวน
|
||||
|
|
@ -179,11 +179,75 @@ namespace BMA.EHR.DisciplineDisciplinary.Service.Controllers
|
|||
CreatedAt = x.CreatedAt,//วันที่สร้างเรื่องสอบสวน
|
||||
DisciplinaryDateStart = x.DisciplinaryDateStart, //วันที่เริ่มการสอบสวน
|
||||
DisciplinaryDateEnd = x.DisciplinaryDateEnd, //วันที่สิ้นสุดการสอบสวน
|
||||
})
|
||||
.OrderByDescending(x => x.DisciplinaryDateStart)
|
||||
});
|
||||
|
||||
bool desc = req.descending ?? false;
|
||||
if (!string.IsNullOrEmpty(req.sortBy))
|
||||
{
|
||||
switch (req.sortBy)
|
||||
{
|
||||
case "title":
|
||||
query = desc ? query.OrderByDescending(x => x.Title)
|
||||
: query.OrderBy(x => x.Title);
|
||||
break;
|
||||
|
||||
case "respondentType":
|
||||
query = desc ? query.OrderByDescending(x => x.RespondentType)
|
||||
: query.OrderBy(x => x.RespondentType);
|
||||
break;
|
||||
|
||||
case "offenseDetails":
|
||||
query = desc ? query.OrderByDescending(x => x.OffenseDetails)
|
||||
: query.OrderBy(x => x.OffenseDetails);
|
||||
break;
|
||||
|
||||
case "disciplinaryFaultLevel":
|
||||
query = desc ? query.OrderByDescending(x => x.DisciplinaryFaultLevel)
|
||||
: query.OrderBy(x => x.DisciplinaryFaultLevel);
|
||||
break;
|
||||
|
||||
case "disciplinaryCaseFault":
|
||||
query = desc ? query.OrderByDescending(x => x.DisciplinaryCaseFault)
|
||||
: query.OrderBy(x => x.DisciplinaryCaseFault);
|
||||
break;
|
||||
|
||||
case "status":
|
||||
query = desc ? query.OrderByDescending(x => x.Status)
|
||||
: query.OrderBy(x => x.Status);
|
||||
break;
|
||||
|
||||
case "dateReceived":
|
||||
query = desc ? query.OrderByDescending(x => x.DateReceived)
|
||||
: query.OrderBy(x => x.DateReceived);
|
||||
break;
|
||||
|
||||
case "createdAt":
|
||||
query = desc ? query.OrderByDescending(x => x.CreatedAt)
|
||||
: query.OrderBy(x => x.CreatedAt);
|
||||
break;
|
||||
|
||||
case "disciplinaryDateStart":
|
||||
query = desc ? query.OrderByDescending(x => x.DisciplinaryDateStart)
|
||||
: query.OrderBy(x => x.DisciplinaryDateStart);
|
||||
break;
|
||||
|
||||
case "disciplinaryDateEnd":
|
||||
query = desc ? query.OrderByDescending(x => x.DisciplinaryDateEnd)
|
||||
: query.OrderBy(x => x.DisciplinaryDateEnd);
|
||||
break;
|
||||
|
||||
default:
|
||||
query = query.OrderByDescending(x => x.DisciplinaryDateStart);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var data = query
|
||||
.Skip((page - 1) * pageSize)
|
||||
.Take(pageSize)
|
||||
.ToList();
|
||||
|
||||
return Success(new { data, total = data_search.Count() });
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ namespace BMA.EHR.DisciplineInvestigate.Service.Controllers
|
|||
.ToList();
|
||||
}
|
||||
|
||||
var data = data_search
|
||||
var query = data_search
|
||||
.Select(x => new
|
||||
{
|
||||
Id = x.Id,//id ข้อมูลเรื่องสืบสวน
|
||||
|
|
@ -174,11 +174,76 @@ namespace BMA.EHR.DisciplineInvestigate.Service.Controllers
|
|||
CreatedAt = x.CreatedAt,//วันที่สร้างเรื่องสืบสวน
|
||||
InvestigationDetail = x.InvestigationDetail,
|
||||
InvestigationStatusResult = x.InvestigationStatusResult,
|
||||
})
|
||||
.OrderByDescending(x => x.InvestigationDateStart)
|
||||
});
|
||||
|
||||
bool desc = req.descending ?? false;
|
||||
if (!string.IsNullOrEmpty(req.sortBy))
|
||||
{
|
||||
switch (req.sortBy)
|
||||
{
|
||||
case "title":
|
||||
query = desc ? query.OrderByDescending(x => x.Title)
|
||||
: query.OrderBy(x => x.Title);
|
||||
break;
|
||||
|
||||
case "respondentType":
|
||||
query = desc ? query.OrderByDescending(x => x.RespondentType)
|
||||
: query.OrderBy(x => x.RespondentType);
|
||||
break;
|
||||
|
||||
case "offenseDetails":
|
||||
query = desc ? query.OrderByDescending(x => x.OffenseDetails)
|
||||
: query.OrderBy(x => x.OffenseDetails);
|
||||
break;
|
||||
|
||||
case "status":
|
||||
query = desc ? query.OrderByDescending(x => x.Status)
|
||||
: query.OrderBy(x => x.Status);
|
||||
break;
|
||||
|
||||
case "investigationDateStart":
|
||||
query = desc ? query.OrderByDescending(x => x.InvestigationDateStart)
|
||||
: query.OrderBy(x => x.InvestigationDateStart);
|
||||
break;
|
||||
|
||||
case "investigationDateEnd":
|
||||
query = desc ? query.OrderByDescending(x => x.InvestigationDateEnd)
|
||||
: query.OrderBy(x => x.InvestigationDateEnd);
|
||||
break;
|
||||
|
||||
case "dateReceived":
|
||||
query = desc ? query.OrderByDescending(x => x.DateReceived)
|
||||
: query.OrderBy(x => x.DateReceived);
|
||||
break;
|
||||
|
||||
case "createdAt":
|
||||
query = desc ? query.OrderByDescending(x => x.CreatedAt)
|
||||
: query.OrderBy(x => x.CreatedAt);
|
||||
break;
|
||||
|
||||
case "investigationDetail":
|
||||
query = desc ? query.OrderByDescending(x => x.InvestigationDetail)
|
||||
: query.OrderBy(x => x.InvestigationDetail);
|
||||
break;
|
||||
|
||||
case "investigationStatusResult":
|
||||
query = desc ? query.OrderByDescending(x => x.InvestigationStatusResult)
|
||||
: query.OrderBy(x => x.InvestigationStatusResult);
|
||||
break;
|
||||
|
||||
default:
|
||||
query = query.OrderByDescending(x => x.InvestigationDateStart);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var data = query
|
||||
.Skip((page - 1) * pageSize)
|
||||
.Take(pageSize)
|
||||
.ToList();
|
||||
|
||||
return Success(new { data, total = data_search.Count() });
|
||||
}
|
||||
|
||||
|
|
@ -902,7 +967,7 @@ namespace BMA.EHR.DisciplineInvestigate.Service.Controllers
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", _configuration["API_KEY"]);
|
||||
client.DefaultRequestHeaders.Add("api-key", _configuration["API_KEY"]);
|
||||
var _res = await client.PostAsJsonAsync(apiUrlOrg, new
|
||||
{
|
||||
refId = persons.Select(x => x.PersonId),
|
||||
|
|
|
|||
|
|
@ -74,20 +74,6 @@ namespace BMA.EHR.DisciplineSuspend.Service.Controllers
|
|||
{
|
||||
return Error(jsonData["message"]?.ToString(), StatusCodes.Status403Forbidden);
|
||||
}
|
||||
//var profile = new List<GetProfileByKeycloakIdRootDto>();
|
||||
//if (type.Trim().ToUpper() == "OFFICER")
|
||||
//{
|
||||
// profile = await _userProfileRepository.GetProfileWithKeycloakAllOfficer(AccessToken, req.node, req.nodeId, jsonData["result"] == "OWNER" || jsonData["result"] == "CHILD");
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// profile = await _userProfileRepository.GetProfileWithKeycloakAllEmployee(AccessToken, req.node, req.nodeId, jsonData["result"] == "OWNER" || jsonData["result"] == "CHILD");
|
||||
//}
|
||||
|
||||
//if (req.posLevel != null || req.posType != null)
|
||||
//{
|
||||
// profile = profile.Where(x => x.PositionType == req.posType || x.PositionLevel == req.posLevel).ToList();
|
||||
//}
|
||||
|
||||
var data_search1 = await _context.DisciplineComplaints
|
||||
.Include(x => x.DisciplineComplaint_Profiles)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,17 +1,21 @@
|
|||
using BMA.EHR.Application.Repositories;
|
||||
using BMA.EHR.Application.Repositories.MessageQueue;
|
||||
using BMA.EHR.Application.Responses.Profiles;
|
||||
using BMA.EHR.Discipline.Service.Requests;
|
||||
using BMA.EHR.Domain.Common;
|
||||
using BMA.EHR.Domain.Models.Discipline;
|
||||
using BMA.EHR.Domain.Shared;
|
||||
using BMA.EHR.Infrastructure.Persistence;
|
||||
using Elasticsearch.Net;
|
||||
|
||||
// using BMA.EHR.Placement.Service.Requests;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Swashbuckle.AspNetCore.Annotations;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
|
||||
namespace BMA.EHR.DisciplineSuspend.Service.Controllers
|
||||
|
|
@ -28,24 +32,25 @@ namespace BMA.EHR.DisciplineSuspend.Service.Controllers
|
|||
private readonly MinIODisciplineService _documentService;
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
private readonly PermissionRepository _permission;
|
||||
|
||||
private readonly UserProfileRepository _userProfileRepository;
|
||||
public DisciplineSuspendController(DisciplineDbContext context,
|
||||
MinIODisciplineService documentService,
|
||||
IHttpContextAccessor httpContextAccessor,
|
||||
PermissionRepository permission)
|
||||
PermissionRepository permission,
|
||||
UserProfileRepository userProfileRepository)
|
||||
{
|
||||
// _repository = repository;
|
||||
_context = context;
|
||||
_documentService = documentService;
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
_permission = permission;
|
||||
_userProfileRepository = userProfileRepository;
|
||||
}
|
||||
|
||||
#region " Properties "
|
||||
|
||||
private string? UserId => _httpContextAccessor?.HttpContext?.User?.FindFirst(ClaimTypes.NameIdentifier)?.Value;
|
||||
|
||||
private string? FullName => _httpContextAccessor?.HttpContext?.User?.FindFirst("name")?.Value;
|
||||
private string? AccessToken => _httpContextAccessor?.HttpContext?.Request.Headers["Authorization"];
|
||||
|
||||
#endregion
|
||||
|
||||
|
|
@ -58,7 +63,7 @@ namespace BMA.EHR.DisciplineSuspend.Service.Controllers
|
|||
/// <response code="401">ไม่ได้ Login เข้าระบบ</response>
|
||||
/// <response code="500">เมื่อเกิดข้อผิดพลาดในการทำงาน</response>
|
||||
[HttpGet()]
|
||||
public async Task<ActionResult<ResponseObject>> GetDisciplineSuspend(DateTime? startDate, DateTime? endDate, int page = 1, int pageSize = 25, string keyword = "", string profileType = "")
|
||||
public async Task<ActionResult<ResponseObject>> GetDisciplineSuspend(DateTime? startDate, DateTime? endDate, int page = 1, int pageSize = 25, string keyword = "", string profileType = "", string? sortBy = "", bool? descending = false, string? status="")
|
||||
{
|
||||
var getPermission = await _permission.GetPermissionAPIAsync("LIST", "SYS_DISCIPLINE_SUSPENDED");
|
||||
var jsonData = JsonConvert.DeserializeObject<JObject>(getPermission);
|
||||
|
|
@ -66,10 +71,52 @@ namespace BMA.EHR.DisciplineSuspend.Service.Controllers
|
|||
{
|
||||
return Error(jsonData["message"]?.ToString(), StatusCodes.Status403Forbidden);
|
||||
}
|
||||
|
||||
// ถ้า FE ส่ง status = PENDING กรอง start/end suspend not null
|
||||
bool isPending =
|
||||
!string.IsNullOrEmpty(profileType) &&
|
||||
!string.IsNullOrEmpty(status) &&
|
||||
status.Trim().ToUpper() == "PENDING";
|
||||
|
||||
// กรองสิทธิ์
|
||||
string role = jsonData["result"]?.ToString() ?? "";
|
||||
var nodeId = string.Empty;
|
||||
var profileAdmin = new GetUserOCAllDto();
|
||||
profileAdmin = await _userProfileRepository.GetUserOCAll(Guid.Parse(UserId!), AccessToken);
|
||||
if (role == "NORMAL" || role == "CHILD")
|
||||
{
|
||||
nodeId = profileAdmin?.Node == 4
|
||||
? profileAdmin?.Child4DnaId
|
||||
: profileAdmin?.Node == 3
|
||||
? profileAdmin?.Child3DnaId
|
||||
: profileAdmin?.Node == 2
|
||||
? profileAdmin?.Child2DnaId
|
||||
: profileAdmin?.Node == 1
|
||||
? profileAdmin?.Child1DnaId
|
||||
: profileAdmin?.Node == 0
|
||||
? profileAdmin?.RootDnaId
|
||||
: "";
|
||||
}
|
||||
else if (role == "BROTHER")
|
||||
{
|
||||
nodeId = profileAdmin?.Node == 4
|
||||
? profileAdmin?.Child3DnaId
|
||||
: profileAdmin?.Node == 3
|
||||
? profileAdmin?.Child2DnaId
|
||||
: profileAdmin?.Node == 2
|
||||
? profileAdmin?.Child1DnaId
|
||||
: profileAdmin?.Node == 1 || profileAdmin?.Node == 0
|
||||
? profileAdmin?.RootDnaId
|
||||
: "";
|
||||
}
|
||||
else if (role == "ROOT" /*|| role == "PARENT"*/)
|
||||
{
|
||||
nodeId = profileAdmin?.RootDnaId;
|
||||
}
|
||||
var data_search = (from x in _context.DisciplineReport_Profiles.Include(x => x.DisciplineDisciplinary)
|
||||
where
|
||||
(
|
||||
endDate != null && startDate != null?
|
||||
endDate != null && startDate != null ?
|
||||
(
|
||||
(x.StartDateSuspend.Value.Date >= startDate.Value.Date && x.StartDateSuspend.Value.Date <= endDate.Value.Date) ||
|
||||
(x.EndDateSuspend.Value.Date >= startDate.Value.Date && x.EndDateSuspend.Value.Date <= endDate.Value.Date) ||
|
||||
|
|
@ -93,8 +140,55 @@ namespace BMA.EHR.DisciplineSuspend.Service.Controllers
|
|||
(profileType.ToUpper() == "OFFICER" && x.profileType == "OFFICER") ||
|
||||
(profileType.ToUpper() == "EMPLOYEE" && x.profileType == "EMPLOYEE")
|
||||
)
|
||||
&&
|
||||
(
|
||||
!string.IsNullOrEmpty(status) ? x.Status!.Trim().ToUpper() == status : true
|
||||
)
|
||||
// ถ้า FE ส่ง status = PENDING กรอง start/end suspend not null
|
||||
&&
|
||||
(
|
||||
isPending
|
||||
? x.StartDateSuspend != null && x.EndDateSuspend != null
|
||||
: true
|
||||
)
|
||||
&&
|
||||
(
|
||||
role == "OWNER"
|
||||
? true
|
||||
: role == "ROOT"
|
||||
? x.rootDnaId == nodeId
|
||||
: role == "CHILD"
|
||||
? (
|
||||
profileAdmin.Node == 4 ? x.child4DnaId == nodeId :
|
||||
profileAdmin.Node == 3 ? x.child3DnaId == nodeId :
|
||||
profileAdmin.Node == 2 ? x.child2DnaId == nodeId :
|
||||
profileAdmin.Node == 1 ? x.child1DnaId == nodeId :
|
||||
profileAdmin.Node == 0 ? x.rootDnaId == nodeId :
|
||||
true
|
||||
)
|
||||
: role == "BROTHER"
|
||||
? (
|
||||
profileAdmin.Node == 4 ? x.child3DnaId == nodeId :
|
||||
profileAdmin.Node == 3 ? x.child2DnaId == nodeId :
|
||||
profileAdmin.Node == 2 ? x.child1DnaId == nodeId :
|
||||
(
|
||||
profileAdmin.Node == 1 || profileAdmin.Node == 0
|
||||
)
|
||||
? x.rootDnaId == nodeId : true
|
||||
)
|
||||
: role == "NORMAL"
|
||||
? (
|
||||
profileAdmin.Node == 0 ? x.rootDnaId == nodeId && x.child1DnaId == null :
|
||||
profileAdmin.Node == 1 ? x.child1DnaId == nodeId && x.child2DnaId == null :
|
||||
profileAdmin.Node == 2 ? x.child2DnaId == nodeId && x.child3DnaId == null :
|
||||
profileAdmin.Node == 3 ? x.child3DnaId == nodeId && x.child4DnaId == null :
|
||||
profileAdmin.Node == 4 ? x.child4DnaId == nodeId :
|
||||
true
|
||||
)
|
||||
: true
|
||||
)
|
||||
select x).ToList();
|
||||
var data = data_search
|
||||
var query = data_search
|
||||
.Select(x => new
|
||||
{
|
||||
Id = x.Id,
|
||||
|
|
@ -145,13 +239,70 @@ namespace BMA.EHR.DisciplineSuspend.Service.Controllers
|
|||
DisciplinaryCaseFault = x.DisciplineDisciplinary.DisciplinaryCaseFault,//กรณีความผิด
|
||||
profileType = x.profileType,
|
||||
CreatedAt = x.CreatedAt,
|
||||
})
|
||||
.OrderByDescending(x => x.profileType)
|
||||
});
|
||||
|
||||
bool desc = descending ?? false;
|
||||
if (!string.IsNullOrEmpty(sortBy))
|
||||
{
|
||||
if (sortBy == "title")
|
||||
{
|
||||
query = desc ? query.OrderByDescending(x => x.Title)
|
||||
: query.OrderBy(x => x.Title);
|
||||
}
|
||||
else if (sortBy == "prefix" || sortBy == "firstName" || sortBy == "lastName")
|
||||
{
|
||||
query = desc ?
|
||||
query.OrderByDescending(x => x.FirstName).ThenByDescending(x => x.LastName) :
|
||||
query.OrderBy(x => x.FirstName).ThenBy(x => x.LastName);
|
||||
}
|
||||
else if (sortBy == "position")
|
||||
{
|
||||
query = desc ? query.OrderByDescending(x => x.Position)
|
||||
: query.OrderBy(x => x.Position);
|
||||
}
|
||||
else if (sortBy == "positionType" || sortBy == "positionLevel")
|
||||
{
|
||||
query = desc ?
|
||||
query
|
||||
.OrderByDescending(x => x.PositionType)
|
||||
.ThenByDescending(x => x.PositionLevel) :
|
||||
query
|
||||
.OrderBy(x => x.PositionType)
|
||||
.ThenBy(x => x.PositionLevel);
|
||||
}
|
||||
else if (sortBy == "organization")
|
||||
{
|
||||
query = desc ? query.OrderByDescending(x => x.Organization)
|
||||
: query.OrderBy(x => x.Organization);
|
||||
}
|
||||
else if (sortBy == "startDateSuspend")
|
||||
{
|
||||
query = desc ? query.OrderByDescending(x => x.StartDateSuspend)
|
||||
: query.OrderBy(x => x.StartDateSuspend);
|
||||
}
|
||||
else if (sortBy == "endDateSuspend")
|
||||
{
|
||||
query = desc ? query.OrderByDescending(x => x.EndDateSuspend)
|
||||
: query.OrderBy(x => x.EndDateSuspend);
|
||||
}
|
||||
else if (sortBy == "descriptionSuspend")
|
||||
{
|
||||
query = desc ? query.OrderByDescending(x => x.DescriptionSuspend)
|
||||
: query.OrderBy(x => x.DescriptionSuspend);
|
||||
}
|
||||
else
|
||||
{
|
||||
query = query.OrderByDescending(x => x.profileType)
|
||||
.ThenByDescending(x => x.CreatedAt)
|
||||
.ThenByDescending(x => x.CitizenId)
|
||||
.ThenByDescending(x => x.CitizenId);
|
||||
}
|
||||
}
|
||||
|
||||
var data = query
|
||||
.Skip((page - 1) * pageSize)
|
||||
.Take(pageSize)
|
||||
.ToList();
|
||||
|
||||
return Success(new { data, total = data_search.Count() });
|
||||
}
|
||||
|
||||
|
|
@ -180,7 +331,7 @@ namespace BMA.EHR.DisciplineSuspend.Service.Controllers
|
|||
.Select(x => new
|
||||
{
|
||||
Id = x.Id,
|
||||
PersonId = x.PersonId,
|
||||
ProfileId = x.PersonId,
|
||||
CitizenId = x.CitizenId,
|
||||
Prefix = x.Prefix,
|
||||
FirstName = x.FirstName,
|
||||
|
|
|
|||
|
|
@ -76,6 +76,8 @@ namespace BMA.EHR.Discipline.Service.Requests
|
|||
public string? levelConsideration { get; set; } // ระดับการพิจารณา
|
||||
public DateTime? dateConsiderationStart { get; set; } // วันที่เริ่มต้นการพิจารณา
|
||||
public DateTime? dateConsiderationEnd { get; set; } // วันที่สิ้นสุดการพิจารณา
|
||||
public string? sortBy { get; set; }
|
||||
public bool? descending { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,6 +48,8 @@ namespace BMA.EHR.Discipline.Service.Requests
|
|||
public DateTime? disciplinaryDateEnd { get; set; } // วันที่สิ้นสุดสอบสวน
|
||||
public DateTime? dateReceivedStart { get; set; } // วันที่เริ่มต้นรับเรื่อง
|
||||
public DateTime? dateReceivedEnd { get; set; } // วันที่สิ้นสุดรับเรื่อง
|
||||
public string? sortBy { get; set; }
|
||||
public bool? descending { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@ namespace BMA.EHR.Discipline.Service.Requests
|
|||
public DateTime? dateReceivedStart { get; set; } // วันที่เริ่มต้นรับเรื่อง
|
||||
public DateTime? dateReceivedEnd { get; set; } // วันที่สิ้นสุดรับเรื่อง
|
||||
public string? investigationStatusResult { get; set; } // ผลการสืบสวน
|
||||
public string? sortBy { get; set; }
|
||||
public bool? descending { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ namespace BMA.EHR.Discipline.Service.Requests
|
|||
public string? resultTitleType { get; set; } // ประเภทของเรื่อง
|
||||
public string? resultOc { get; set; } // หน่วยงาน/ส่วนราชการ
|
||||
public int? resultYear { get; set; } // ปีงบประมาณ
|
||||
public string? sortBy { get; set; }
|
||||
public bool? descending { get; set; }
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,4 +8,12 @@ namespace BMA.EHR.Discipline.Service.Requests
|
|||
public string[] refIds { get; set; }
|
||||
public string? status { get; set; }
|
||||
}
|
||||
|
||||
public class ReportPersonAndCommandRequest
|
||||
{
|
||||
public string[] refIds { get; set; }
|
||||
public string? status { get; set; }
|
||||
public string? commandTypeId { get; set; }
|
||||
public string? commandCode { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using BMA.EHR.Domain.Shared;
|
||||
using BMA.EHR.Domain.Extensions;
|
||||
using BMA.EHR.Domain.Shared;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
|
|
@ -81,6 +82,23 @@ namespace BMA.EHR.Domain.Common
|
|||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region " Properties "
|
||||
|
||||
protected string? EmpType => User.GetEmpType();
|
||||
protected Guid? OrgChild1DnaId => User.GetOrgChild1DnaId();
|
||||
protected Guid? OrgChild2DnaId => User.GetOrgChild2DnaId();
|
||||
protected Guid? OrgChild3DnaId => User.GetOrgChild3DnaId();
|
||||
protected Guid? OrgChild4DnaId => User.GetOrgChild4DnaId();
|
||||
protected Guid? OrgRootDnaId => User.GetOrgRootDnaId();
|
||||
protected Guid? ProfileId => User.GetProfileId();
|
||||
protected string? Prefix => User.GetPrefix();
|
||||
protected string? FullNameFromClaim => User.GetName();
|
||||
|
||||
protected string? FirstName => User.GetFirstName();
|
||||
protected string? LastName => User.GetLastName();
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
|
|
|||
39
BMA.EHR.Domain/Common/TokenUserInfo.cs
Normal file
39
BMA.EHR.Domain/Common/TokenUserInfo.cs
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
namespace BMA.EHR.Domain.Common
|
||||
{
|
||||
public class TokenUserInfo
|
||||
{
|
||||
// Existing properties
|
||||
public string KeycloakId { get; set; } = string.Empty;
|
||||
public string? PreferredUsername { get; set; }
|
||||
public string? GivenName { get; set; }
|
||||
public string? FamilyName { get; set; }
|
||||
|
||||
// New properties to add
|
||||
public string? EmpType { get; set; }
|
||||
public Guid? OrgChild1DnaId { get; set; }
|
||||
public Guid? OrgChild2DnaId { get; set; }
|
||||
public Guid? OrgChild3DnaId { get; set; }
|
||||
public Guid? OrgChild4DnaId { get; set; }
|
||||
public Guid? OrgRootDnaId { get; set; }
|
||||
public Guid? ProfileId { get; set; }
|
||||
public string? Prefix { get; set; }
|
||||
public string? Name { get; set; }
|
||||
}
|
||||
|
||||
// Claim type constants
|
||||
public static class BmaClaimTypes
|
||||
{
|
||||
public const string EmpType = "empType";
|
||||
public const string OrgChild1DnaId = "orgChild1DnaId";
|
||||
public const string OrgChild2DnaId = "orgChild2DnaId";
|
||||
public const string OrgChild3DnaId = "orgChild3DnaId";
|
||||
public const string OrgChild4DnaId = "orgChild4DnaId";
|
||||
public const string OrgRootDnaId = "orgRootDnaId";
|
||||
public const string ProfileId = "profileId";
|
||||
public const string Prefix = "prefix";
|
||||
public const string Name = "name";
|
||||
public const string GivenName = "given_name";
|
||||
public const string FamilyName = "family_name";
|
||||
public const string PreferredUsername = "preferred_username";
|
||||
}
|
||||
}
|
||||
32
BMA.EHR.Domain/Extensions/ClaimsPrincipalExtensions.cs
Normal file
32
BMA.EHR.Domain/Extensions/ClaimsPrincipalExtensions.cs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
using BMA.EHR.Domain.Common;
|
||||
using System.Security.Claims;
|
||||
|
||||
namespace BMA.EHR.Domain.Extensions
|
||||
{
|
||||
public static class ClaimsPrincipalExtensions
|
||||
{
|
||||
public static string? GetClaimValue(this ClaimsPrincipal user, string claimType)
|
||||
{
|
||||
return user?.FindFirst(claimType)?.Value;
|
||||
}
|
||||
|
||||
public static Guid? GetGuidClaim(this ClaimsPrincipal user, string claimType)
|
||||
{
|
||||
var value = user?.GetClaimValue(claimType);
|
||||
return Guid.TryParse(value, out var guid) ? guid : null;
|
||||
}
|
||||
|
||||
// Convenience methods for common claims
|
||||
public static string? GetEmpType(this ClaimsPrincipal user) => user.GetClaimValue(BmaClaimTypes.EmpType);
|
||||
public static Guid? GetOrgChild1DnaId(this ClaimsPrincipal user) => user.GetGuidClaim(BmaClaimTypes.OrgChild1DnaId);
|
||||
public static Guid? GetOrgChild2DnaId(this ClaimsPrincipal user) => user.GetGuidClaim(BmaClaimTypes.OrgChild2DnaId);
|
||||
public static Guid? GetOrgChild3DnaId(this ClaimsPrincipal user) => user.GetGuidClaim(BmaClaimTypes.OrgChild3DnaId);
|
||||
public static Guid? GetOrgChild4DnaId(this ClaimsPrincipal user) => user.GetGuidClaim(BmaClaimTypes.OrgChild4DnaId);
|
||||
public static Guid? GetOrgRootDnaId(this ClaimsPrincipal user) => user.GetGuidClaim(BmaClaimTypes.OrgRootDnaId);
|
||||
public static Guid? GetProfileId(this ClaimsPrincipal user) => user.GetGuidClaim(BmaClaimTypes.ProfileId);
|
||||
public static string? GetPrefix(this ClaimsPrincipal user) => user.GetClaimValue(BmaClaimTypes.Prefix);
|
||||
public static string? GetName(this ClaimsPrincipal user) => user.GetClaimValue(BmaClaimTypes.Name);
|
||||
public static string? GetFirstName(this ClaimsPrincipal user) => user.GetClaimValue(BmaClaimTypes.GivenName);
|
||||
public static string? GetLastName(this ClaimsPrincipal user) => user.GetClaimValue(BmaClaimTypes.FamilyName);
|
||||
}
|
||||
}
|
||||
|
|
@ -174,6 +174,29 @@ namespace BMA.EHR.Domain.Extensions
|
|||
}
|
||||
}
|
||||
|
||||
public static (int Years, int Months, int Days) GetDifference(this DateTime from, DateTime to)
|
||||
{
|
||||
if (from > to) (from, to) = (to, from); // swap ถ้าลำดับสลับ
|
||||
|
||||
int years = to.Year - from.Year;
|
||||
int months = to.Month - from.Month;
|
||||
int days = to.Day - from.Day;
|
||||
|
||||
if (days < 0)
|
||||
{
|
||||
months--;
|
||||
days += DateTime.DaysInMonth(to.Year, to.Month == 1 ? 12 : to.Month - 1);
|
||||
}
|
||||
|
||||
if (months < 0)
|
||||
{
|
||||
years--;
|
||||
months += 12;
|
||||
}
|
||||
|
||||
return (years, months, days);
|
||||
}
|
||||
|
||||
public static int CalculateAge(this DateTime date, int plusYear = 0, int subtractYear = 0)
|
||||
{
|
||||
try
|
||||
|
|
@ -424,6 +447,18 @@ namespace BMA.EHR.Domain.Extensions
|
|||
};
|
||||
}
|
||||
|
||||
public static int CalculateFisicalYear(this DateTime value)
|
||||
{
|
||||
if (value.Month >= 10)
|
||||
{
|
||||
return value.Year + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return value.Year;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
|
|
|||
|
|
@ -18,6 +18,10 @@ namespace BMA.EHR.Domain.Middlewares
|
|||
{
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly IConfiguration _configuration;
|
||||
private static ElasticClient? _elasticClient;
|
||||
private static readonly object _lock = new object();
|
||||
private static readonly Dictionary<string, (GetProfileByKeycloakIdLocal Profile, DateTime ExpiryTime)> _profileCache = new();
|
||||
private static readonly TimeSpan _cacheExpiry = TimeSpan.FromMinutes(10);
|
||||
|
||||
private string Uri = "";
|
||||
private string IndexFormat = "";
|
||||
|
|
@ -31,19 +35,28 @@ namespace BMA.EHR.Domain.Middlewares
|
|||
Uri = _configuration["ElasticConfiguration:Uri"] ?? "http://192.168.1.40:9200";
|
||||
IndexFormat = _configuration["ElasticConfiguration:IndexFormat"] ?? "bma-ehr-log-index";
|
||||
SystemName = _configuration["ElasticConfiguration:SystemName"] ?? "Unknown";
|
||||
|
||||
// สร้าง ElasticClient แค่ครั้งเดียว
|
||||
if (_elasticClient == null)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
if (_elasticClient == null)
|
||||
{
|
||||
var settings = new ConnectionSettings(new Uri(Uri))
|
||||
.DefaultIndex(IndexFormat)
|
||||
.DisableDirectStreaming() // เพิ่มประสิทธิภาพ
|
||||
.RequestTimeout(TimeSpan.FromSeconds(5)); // กำหนด timeout
|
||||
_elasticClient = new ElasticClient(settings);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext context)
|
||||
{
|
||||
Console.WriteLine("=== CombinedErrorHandlerAndLoggingMiddleware Start ===");
|
||||
|
||||
var settings = new ConnectionSettings(new Uri(Uri))
|
||||
.DefaultIndex(IndexFormat);
|
||||
var client = new ElasticClient(settings);
|
||||
|
||||
var startTime = DateTime.UtcNow;
|
||||
var stopwatch = Stopwatch.StartNew();
|
||||
string? responseBodyJson = null;
|
||||
string? requestBodyJson = null;
|
||||
Exception? caughtException = null;
|
||||
|
||||
|
|
@ -64,27 +77,41 @@ namespace BMA.EHR.Domain.Middlewares
|
|||
string keycloakId = Guid.Empty.ToString("D");
|
||||
var token = context.Request.Headers["Authorization"];
|
||||
GetProfileByKeycloakIdLocal? pf = null;
|
||||
var tokenUserInfo = await ExtractTokenUserInfoAsync(token);
|
||||
|
||||
// ลองดึง keycloakId จาก JWT token ก่อน (ถ้ามี)
|
||||
try
|
||||
{
|
||||
keycloakId = await ExtractKeycloakIdFromToken(token);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Error extracting keycloakId from token: {ex.Message}");
|
||||
}
|
||||
// Store tokenUserInfo in HttpContext.Items for controllers to use
|
||||
context.Items["TokenUserInfo"] = tokenUserInfo;
|
||||
|
||||
try
|
||||
{
|
||||
// ดึง keycloakId จาก JWT token
|
||||
keycloakId = tokenUserInfo.KeycloakId;
|
||||
|
||||
// ดึง profile จาก claims หรือ cache หรือ API
|
||||
if (Guid.TryParse(keycloakId, out var parsedId) && parsedId != Guid.Empty)
|
||||
{
|
||||
pf = await GetProfileByKeycloakIdAsync(parsedId, token);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
// Build profile from token claims if available
|
||||
if (tokenUserInfo.OrgRootDnaId.HasValue && tokenUserInfo.ProfileId.HasValue)
|
||||
{
|
||||
Console.WriteLine($"Error getting profile: {ex.Message}");
|
||||
pf = new GetProfileByKeycloakIdLocal
|
||||
{
|
||||
Id = tokenUserInfo.ProfileId.Value,
|
||||
CitizenId = tokenUserInfo.PreferredUsername,
|
||||
Prefix = tokenUserInfo.Prefix,
|
||||
FirstName = tokenUserInfo.GivenName,
|
||||
LastName = tokenUserInfo.FamilyName,
|
||||
RootDnaId = tokenUserInfo.OrgRootDnaId,
|
||||
Child1DnaId = tokenUserInfo.OrgChild1DnaId,
|
||||
Child2DnaId = tokenUserInfo.OrgChild2DnaId,
|
||||
Child3DnaId = tokenUserInfo.OrgChild3DnaId,
|
||||
Child4DnaId = tokenUserInfo.OrgChild4DnaId,
|
||||
};
|
||||
Console.WriteLine($"[INFO] Using claims for profile - OrgRootDnaId: {pf.RootDnaId}, ProfileId: {pf.Id}");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fallback to API only if critical claims are missing
|
||||
Console.WriteLine("[WARN] Critical claims missing, falling back to API call");
|
||||
pf = await GetProfileWithCacheAsync(parsedId, token);
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
|
|
@ -103,17 +130,17 @@ namespace BMA.EHR.Domain.Middlewares
|
|||
Console.WriteLine($"Updated keycloakId from authenticated user: {keycloakId}");
|
||||
|
||||
// อัพเดต profile ด้วย keycloakId ที่ถูกต้อง
|
||||
try
|
||||
{
|
||||
if (Guid.TryParse(keycloakId, out var parsedId))
|
||||
{
|
||||
pf = await GetProfileByKeycloakIdAsync(parsedId, token);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Error updating profile after authentication: {ex.Message}");
|
||||
}
|
||||
// try
|
||||
// {
|
||||
// if (Guid.TryParse(keycloakId, out var parsedId))
|
||||
// {
|
||||
// //pf = await GetProfileByKeycloakIdAsync(parsedId, token);
|
||||
// }
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// Console.WriteLine($"Error updating profile after authentication: {ex.Message}");
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -142,14 +169,48 @@ namespace BMA.EHR.Domain.Middlewares
|
|||
finally
|
||||
{
|
||||
stopwatch.Stop();
|
||||
await LogRequest(context, client, startTime, stopwatch, pf, keycloakId, requestBodyJson, memoryStream, caughtException);
|
||||
|
||||
// เขียนข้อมูลกลับไปยัง original Response body
|
||||
// อ่านข้อมูล response ก่อนที่ stream จะถูก dispose
|
||||
string? responseBodyForLogging = null;
|
||||
if (memoryStream.Length > 0)
|
||||
{
|
||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||
using var reader = new StreamReader(memoryStream, leaveOpen: true);
|
||||
responseBodyForLogging = await reader.ReadToEndAsync();
|
||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||
}
|
||||
|
||||
// เก็บข้อมูลที่จำเป็นจาก HttpContext ก่อนที่มันจะถูก dispose
|
||||
var logData = new
|
||||
{
|
||||
RemoteIpAddress = context.Connection.RemoteIpAddress?.ToString(),
|
||||
HostValue = context.Request.Host.Value,
|
||||
Method = context.Request.Method,
|
||||
Path = context.Request.Path.ToString(),
|
||||
QueryString = context.Request.QueryString.ToString(),
|
||||
StatusCode = context.Response.StatusCode,
|
||||
ContentType = context.Response.ContentType ?? ""
|
||||
};
|
||||
|
||||
// เขียนข้อมูลกลับไปยัง original Response body ก่อน
|
||||
if (memoryStream.Length > 0)
|
||||
{
|
||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||
await memoryStream.CopyToAsync(originalBodyStream);
|
||||
}
|
||||
|
||||
// ทำ logging แบบ await
|
||||
Console.WriteLine("[DEBUG] Starting logging...");
|
||||
try
|
||||
{
|
||||
await LogRequestAsync(_elasticClient!, startTime, stopwatch, pf, keycloakId, requestBodyJson, responseBodyForLogging, caughtException, logData);
|
||||
Console.WriteLine("[DEBUG] Logging completed successfully");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"[ERROR] Logging error: {ex.Message}");
|
||||
Console.WriteLine($"[ERROR] Stack trace: {ex.StackTrace}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -262,7 +323,7 @@ namespace BMA.EHR.Domain.Middlewares
|
|||
{
|
||||
Console.WriteLine($"Formatting response for status: {statusCode}");
|
||||
|
||||
var responseModel = CreateResponseModel(statusCode,message);
|
||||
var responseModel = CreateResponseModel(statusCode, message);
|
||||
|
||||
// Clear memory stream และเขียน response ใหม่
|
||||
memoryStream.SetLength(0);
|
||||
|
|
@ -291,7 +352,7 @@ namespace BMA.EHR.Domain.Middlewares
|
|||
{
|
||||
Console.WriteLine($"Creating response body for {statusCode} status");
|
||||
|
||||
var responseModel = CreateResponseModel(statusCode,message);
|
||||
var responseModel = CreateResponseModel(statusCode, message);
|
||||
response.ContentType = "application/json; charset=utf-8";
|
||||
|
||||
var jsonOptions = new JsonSerializerOptions
|
||||
|
|
@ -379,15 +440,16 @@ namespace BMA.EHR.Domain.Middlewares
|
|||
}
|
||||
}
|
||||
|
||||
private async Task LogRequest(HttpContext context, ElasticClient client, DateTime startTime, Stopwatch stopwatch,
|
||||
GetProfileByKeycloakIdLocal? pf, string keycloakId, string? requestBodyJson, MemoryStream memoryStream, Exception? caughtException)
|
||||
private async Task LogRequestAsync(ElasticClient client, DateTime startTime, Stopwatch stopwatch,
|
||||
GetProfileByKeycloakIdLocal? pf, string keycloakId, string? requestBodyJson, string? responseBodyForLogging, Exception? caughtException, dynamic contextData)
|
||||
{
|
||||
Console.WriteLine("[DEBUG] LogRequestAsync called");
|
||||
try
|
||||
{
|
||||
var processTime = stopwatch.ElapsedMilliseconds;
|
||||
var endTime = DateTime.UtcNow;
|
||||
|
||||
var statusCode = caughtException != null ? (int)HttpStatusCode.InternalServerError : context.Response.StatusCode;
|
||||
var statusCode = caughtException != null ? (int)HttpStatusCode.InternalServerError : (int)contextData.StatusCode;
|
||||
|
||||
var logType = caughtException != null ? "error" : statusCode switch
|
||||
{
|
||||
|
|
@ -399,20 +461,14 @@ namespace BMA.EHR.Domain.Middlewares
|
|||
string? message = null;
|
||||
string? responseBodyJson = null;
|
||||
|
||||
// อ่านข้อมูลจาก Response
|
||||
if (memoryStream.Length > 0)
|
||||
// ใช้ response body ที่ส่งมาจากการอ่านก่อนหน้า
|
||||
if (!string.IsNullOrEmpty(responseBodyForLogging))
|
||||
{
|
||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||
var responseBody = new StreamReader(memoryStream).ReadToEnd();
|
||||
|
||||
if (!string.IsNullOrEmpty(responseBody))
|
||||
{
|
||||
var contentType = context.Response.ContentType;
|
||||
var contentType = (string)contextData.ContentType;
|
||||
var isFileResponse = !contentType.StartsWith("application/json") && !contentType.StartsWith("text/html") && (
|
||||
contentType.StartsWith("application/") ||
|
||||
contentType.StartsWith("image/") ||
|
||||
contentType.StartsWith("audio/") ||
|
||||
context.Response.Headers.ContainsKey("Content-Disposition")
|
||||
contentType.StartsWith("audio/")
|
||||
);
|
||||
|
||||
if (isFileResponse)
|
||||
|
|
@ -422,38 +478,27 @@ namespace BMA.EHR.Domain.Middlewares
|
|||
}
|
||||
else
|
||||
{
|
||||
// ใช้ response body ที่มีอยู่แล้วโดยไม่ serialize ซ้ำ
|
||||
responseBodyJson = responseBodyForLogging;
|
||||
|
||||
try
|
||||
{
|
||||
var jsonOptions = new JsonSerializerOptions
|
||||
{
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
|
||||
WriteIndented = true,
|
||||
Converters = { new DateTimeFixConverter() }
|
||||
};
|
||||
responseBodyJson = JsonSerializer.Serialize(JsonSerializer.Deserialize<object>(responseBody), jsonOptions);
|
||||
|
||||
var json = JsonSerializer.Deserialize<JsonElement>(responseBody);
|
||||
var json = JsonSerializer.Deserialize<JsonElement>(responseBodyForLogging);
|
||||
if (json.ValueKind == JsonValueKind.Array)
|
||||
{
|
||||
message = "success";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (json.TryGetProperty("message", out var messageElement))
|
||||
else if (json.TryGetProperty("message", out var messageElement))
|
||||
{
|
||||
message = messageElement.GetString();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
responseBodyJson = responseBody;
|
||||
message = caughtException?.Message ?? "Unknown error";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (caughtException != null)
|
||||
{
|
||||
|
|
@ -463,15 +508,16 @@ namespace BMA.EHR.Domain.Middlewares
|
|||
var logData = new
|
||||
{
|
||||
logType = logType,
|
||||
ip = context.Connection.RemoteIpAddress?.ToString(),
|
||||
rootId = pf?.RootId,
|
||||
ip = (string)contextData.RemoteIpAddress,
|
||||
//rootId = pf?.RootId,
|
||||
rootId = pf?.RootDnaId,
|
||||
systemName = SystemName,
|
||||
startTimeStamp = startTime.ToString("o"),
|
||||
endTimeStamp = endTime.ToString("o"),
|
||||
processTime = processTime,
|
||||
host = context.Request.Host.Value,
|
||||
method = context.Request.Method,
|
||||
endpoint = context.Request.Path + context.Request.QueryString,
|
||||
host = (string)contextData.HostValue,
|
||||
method = (string)contextData.Method,
|
||||
endpoint = (string)contextData.Path + (string)contextData.QueryString,
|
||||
responseCode = statusCode == 304 ? "200" : statusCode.ToString(),
|
||||
responseDescription = message,
|
||||
input = requestBodyJson,
|
||||
|
|
@ -482,11 +528,19 @@ namespace BMA.EHR.Domain.Middlewares
|
|||
exception = caughtException?.ToString()
|
||||
};
|
||||
|
||||
await client.IndexDocumentAsync(logData);
|
||||
Console.WriteLine($"[DEBUG] Sending log to Elasticsearch: {logType} - {(string)contextData.Method} {(string)contextData.Path}");
|
||||
var response = await client.IndexDocumentAsync(logData);
|
||||
Console.WriteLine($"[DEBUG] Elasticsearch response: IsValid={response.IsValid}, Index={response.Index}");
|
||||
|
||||
if (!response.IsValid)
|
||||
{
|
||||
Console.WriteLine($"[ERROR] Elasticsearch error: {response.OriginalException?.Message ?? response.ServerError?.ToString()}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Error logging request: {ex.Message}");
|
||||
Console.WriteLine($"[ERROR] Error logging request: {ex.Message}");
|
||||
Console.WriteLine($"[ERROR] Stack trace: {ex.StackTrace}");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -501,7 +555,7 @@ namespace BMA.EHR.Domain.Middlewares
|
|||
statusCode == (int)HttpStatusCode.InternalServerError;
|
||||
}
|
||||
|
||||
private static ResponseObject CreateResponseModel(int statusCode,string? error)
|
||||
private static ResponseObject CreateResponseModel(int statusCode, string? error)
|
||||
{
|
||||
var message = statusCode switch
|
||||
{
|
||||
|
|
@ -536,11 +590,19 @@ namespace BMA.EHR.Domain.Middlewares
|
|||
|
||||
private async Task<string> ExtractKeycloakIdFromToken(string? authorizationHeader)
|
||||
{
|
||||
var tokenInfo = await ExtractTokenUserInfoAsync(authorizationHeader);
|
||||
return tokenInfo.KeycloakId;
|
||||
}
|
||||
|
||||
private async Task<TokenUserInfo> ExtractTokenUserInfoAsync(string? authorizationHeader)
|
||||
{
|
||||
var defaultResult = new TokenUserInfo { KeycloakId = Guid.Empty.ToString("D") };
|
||||
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(authorizationHeader) || !authorizationHeader.StartsWith("Bearer "))
|
||||
{
|
||||
return Guid.Empty.ToString("D");
|
||||
return defaultResult;
|
||||
}
|
||||
|
||||
var token = authorizationHeader.Replace("Bearer ", "");
|
||||
|
|
@ -549,15 +611,18 @@ namespace BMA.EHR.Domain.Middlewares
|
|||
var parts = token.Split('.');
|
||||
if (parts.Length != 3)
|
||||
{
|
||||
return Guid.Empty.ToString("D");
|
||||
return defaultResult;
|
||||
}
|
||||
|
||||
// Decode Base64 payload
|
||||
// Decode Base64Url payload (JWT uses Base64Url encoding, not standard Base64)
|
||||
var payload = parts[1];
|
||||
|
||||
// แปลง Base64Url เป็น Base64 ก่อน
|
||||
payload = payload.Replace('-', '+').Replace('_', '/');
|
||||
|
||||
// เพิ่ม padding ถ้าจำเป็น
|
||||
var padLength = 4 - (payload.Length % 4);
|
||||
if (padLength != 4)
|
||||
if (padLength < 4)
|
||||
{
|
||||
payload += new string('=', padLength);
|
||||
}
|
||||
|
|
@ -567,31 +632,136 @@ namespace BMA.EHR.Domain.Middlewares
|
|||
|
||||
Console.WriteLine($"JWT Payload: {payloadJson}");
|
||||
|
||||
// Parse JSON และดึง sub (subject) claim
|
||||
// Parse JSON และดึง claims ต่างๆ
|
||||
var jsonDoc = JsonDocument.Parse(payloadJson);
|
||||
var result = new TokenUserInfo();
|
||||
|
||||
// ลองหา keycloak ID ใน claims ต่างๆ
|
||||
string? keycloakId = null;
|
||||
|
||||
// ดึง keycloak ID
|
||||
if (jsonDoc.RootElement.TryGetProperty("sub", out var subElement))
|
||||
{
|
||||
keycloakId = subElement.GetString();
|
||||
result.KeycloakId = subElement.GetString() ?? Guid.Empty.ToString("D");
|
||||
}
|
||||
else if (jsonDoc.RootElement.TryGetProperty("nameid", out var nameidElement))
|
||||
{
|
||||
keycloakId = nameidElement.GetString();
|
||||
result.KeycloakId = nameidElement.GetString() ?? Guid.Empty.ToString("D");
|
||||
}
|
||||
else if (jsonDoc.RootElement.TryGetProperty("user_id", out var userIdElement))
|
||||
{
|
||||
keycloakId = userIdElement.GetString();
|
||||
result.KeycloakId = userIdElement.GetString() ?? Guid.Empty.ToString("D");
|
||||
}
|
||||
else
|
||||
{
|
||||
result.KeycloakId = Guid.Empty.ToString("D");
|
||||
}
|
||||
|
||||
return keycloakId ?? Guid.Empty.ToString("D");
|
||||
// ดึง preferred_username
|
||||
if (jsonDoc.RootElement.TryGetProperty("preferred_username", out var preferredUsernameElement))
|
||||
{
|
||||
result.PreferredUsername = preferredUsernameElement.GetString();
|
||||
Console.WriteLine($"Extracted preferred_username: {result.PreferredUsername}");
|
||||
}
|
||||
|
||||
// ดึง given_name
|
||||
if (jsonDoc.RootElement.TryGetProperty("given_name", out var givenNameElement))
|
||||
{
|
||||
result.GivenName = givenNameElement.GetString();
|
||||
Console.WriteLine($"Extracted given_name: {result.GivenName}");
|
||||
}
|
||||
|
||||
// ดึง family_name
|
||||
if (jsonDoc.RootElement.TryGetProperty("family_name", out var familyNameElement))
|
||||
{
|
||||
result.FamilyName = familyNameElement.GetString();
|
||||
Console.WriteLine($"Extracted family_name: {result.FamilyName}");
|
||||
}
|
||||
|
||||
// ดึง empType
|
||||
if (jsonDoc.RootElement.TryGetProperty("empType", out var empTypeElement))
|
||||
{
|
||||
result.EmpType = empTypeElement.GetString();
|
||||
Console.WriteLine($"Extracted empType: {result.EmpType}");
|
||||
}
|
||||
|
||||
// ดึง orgChild1DnaId
|
||||
if (jsonDoc.RootElement.TryGetProperty("orgChild1DnaId", out var orgChild1Element))
|
||||
{
|
||||
if (Guid.TryParse(orgChild1Element.GetString(), out var orgChild1Guid))
|
||||
{
|
||||
result.OrgChild1DnaId = orgChild1Guid;
|
||||
Console.WriteLine($"Extracted orgChild1DnaId: {result.OrgChild1DnaId}");
|
||||
}
|
||||
}
|
||||
|
||||
// ดึง orgChild2DnaId
|
||||
if (jsonDoc.RootElement.TryGetProperty("orgChild2DnaId", out var orgChild2Element))
|
||||
{
|
||||
if (Guid.TryParse(orgChild2Element.GetString(), out var orgChild2Guid))
|
||||
{
|
||||
result.OrgChild2DnaId = orgChild2Guid;
|
||||
Console.WriteLine($"Extracted orgChild2DnaId: {result.OrgChild2DnaId}");
|
||||
}
|
||||
}
|
||||
|
||||
// ดึง orgChild3DnaId
|
||||
if (jsonDoc.RootElement.TryGetProperty("orgChild3DnaId", out var orgChild3Element))
|
||||
{
|
||||
if (Guid.TryParse(orgChild3Element.GetString(), out var orgChild3Guid))
|
||||
{
|
||||
result.OrgChild3DnaId = orgChild3Guid;
|
||||
Console.WriteLine($"Extracted orgChild3DnaId: {result.OrgChild3DnaId}");
|
||||
}
|
||||
}
|
||||
|
||||
// ดึง orgChild4DnaId
|
||||
if (jsonDoc.RootElement.TryGetProperty("orgChild4DnaId", out var orgChild4Element))
|
||||
{
|
||||
if (Guid.TryParse(orgChild4Element.GetString(), out var orgChild4Guid))
|
||||
{
|
||||
result.OrgChild4DnaId = orgChild4Guid;
|
||||
Console.WriteLine($"Extracted orgChild4DnaId: {result.OrgChild4DnaId}");
|
||||
}
|
||||
}
|
||||
|
||||
// ดึง orgRootDnaId
|
||||
if (jsonDoc.RootElement.TryGetProperty("orgRootDnaId", out var orgRootElement))
|
||||
{
|
||||
if (Guid.TryParse(orgRootElement.GetString(), out var orgRootGuid))
|
||||
{
|
||||
result.OrgRootDnaId = orgRootGuid;
|
||||
Console.WriteLine($"Extracted orgRootDnaId: {result.OrgRootDnaId}");
|
||||
}
|
||||
}
|
||||
|
||||
// ดึง profileId
|
||||
if (jsonDoc.RootElement.TryGetProperty("profileId", out var profileIdElement))
|
||||
{
|
||||
if (Guid.TryParse(profileIdElement.GetString(), out var profileIdGuid))
|
||||
{
|
||||
result.ProfileId = profileIdGuid;
|
||||
Console.WriteLine($"Extracted profileId: {result.ProfileId}");
|
||||
}
|
||||
}
|
||||
|
||||
// ดึง prefix
|
||||
if (jsonDoc.RootElement.TryGetProperty("prefix", out var prefixElement))
|
||||
{
|
||||
result.Prefix = prefixElement.GetString();
|
||||
Console.WriteLine($"Extracted prefix: {result.Prefix}");
|
||||
}
|
||||
|
||||
// ดึง name
|
||||
if (jsonDoc.RootElement.TryGetProperty("name", out var nameElement))
|
||||
{
|
||||
result.Name = nameElement.GetString();
|
||||
Console.WriteLine($"Extracted name: {result.Name}");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Error extracting keycloak ID from token: {ex.Message}");
|
||||
return Guid.Empty.ToString("D");
|
||||
Console.WriteLine($"Error extracting token user info: {ex.Message}");
|
||||
return defaultResult;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -602,7 +772,7 @@ namespace BMA.EHR.Domain.Middlewares
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", apiKey);
|
||||
client.DefaultRequestHeaders.Add("api-key", apiKey);
|
||||
var _res = await client.GetAsync(apiPath);
|
||||
if (_res.IsSuccessStatusCode)
|
||||
{
|
||||
|
|
@ -622,7 +792,8 @@ namespace BMA.EHR.Domain.Middlewares
|
|||
{
|
||||
try
|
||||
{
|
||||
var apiPath = $"{_configuration["API"]}/org/dotnet/keycloak/{keycloakId}";
|
||||
//var apiPath = $"{_configuration["API"]}/org/dotnet/by-keycloak/{keycloakId}";
|
||||
var apiPath = $"{_configuration["API"]}/org/dotnet/user-logs/{keycloakId}";
|
||||
var apiKey = _configuration["API_KEY"];
|
||||
|
||||
var apiResult = await GetExternalAPIAsync(apiPath, accessToken ?? "", apiKey);
|
||||
|
|
@ -637,7 +808,58 @@ namespace BMA.EHR.Domain.Middlewares
|
|||
}
|
||||
catch
|
||||
{
|
||||
throw;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<GetProfileByKeycloakIdLocal?> GetProfileWithCacheAsync(Guid keycloakId, string? accessToken)
|
||||
{
|
||||
var cacheKey = keycloakId.ToString();
|
||||
|
||||
// ตรวจสอบ cache
|
||||
lock (_profileCache)
|
||||
{
|
||||
if (_profileCache.TryGetValue(cacheKey, out var cached))
|
||||
{
|
||||
if (cached.ExpiryTime > DateTime.UtcNow)
|
||||
{
|
||||
return cached.Profile;
|
||||
}
|
||||
// ลบ cache ที่หมดอายุ
|
||||
_profileCache.Remove(cacheKey);
|
||||
}
|
||||
}
|
||||
|
||||
// ดึงข้อมูลจาก API
|
||||
try
|
||||
{
|
||||
var profile = await GetProfileByKeycloakIdAsync(keycloakId, accessToken);
|
||||
if (profile != null)
|
||||
{
|
||||
// เก็บใน cache
|
||||
lock (_profileCache)
|
||||
{
|
||||
_profileCache[cacheKey] = (profile, DateTime.UtcNow.Add(_cacheExpiry));
|
||||
|
||||
// ลบ cache เก่าที่เกิน 1000 รายการ
|
||||
if (_profileCache.Count > 1000)
|
||||
{
|
||||
var expiredKeys = _profileCache
|
||||
.Where(x => x.Value.ExpiryTime < DateTime.UtcNow)
|
||||
.Select(x => x.Key)
|
||||
.ToList();
|
||||
foreach (var key in expiredKeys)
|
||||
{
|
||||
_profileCache.Remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return profile;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ namespace BMA.EHR.Domain.Middlewares
|
|||
using (var client = new HttpClient())
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken.Replace("Bearer ", ""));
|
||||
client.DefaultRequestHeaders.Add("api_key", apiKey);
|
||||
client.DefaultRequestHeaders.Add("api-key", apiKey);
|
||||
var _res = await client.GetAsync(apiPath);
|
||||
if (_res.IsSuccessStatusCode)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -15,5 +15,7 @@ namespace BMA.EHR.Domain.Models.Insignias
|
|||
[Comment("Fk Table InsigniaManage")]
|
||||
public InsigniaManage InsigniaManage { get; set; }
|
||||
public virtual List<InsigniaManageProfile> InsigniaManageProfiles { get; set; } = new List<InsigniaManageProfile>();
|
||||
|
||||
public Guid? RootDnaId { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,10 +24,29 @@ namespace BMA.EHR.Domain.Models.Leave.Requests
|
|||
[Required, Comment("ปีงบประมาณ")]
|
||||
public int LeaveYear { get; set; } = 0;
|
||||
|
||||
[Required, Comment("จำนวนวันลายกมา")]
|
||||
[Required, Comment("จำนวนวันลาทั้งหมด")]
|
||||
public double LeaveDays { get; set; } = 0.0;
|
||||
|
||||
[Required, Comment("จำนวนวันลาที่ใช้ไป")]
|
||||
public double LeaveDaysUsed { get; set; } = 0.0;
|
||||
[Comment("จำนวนวันลาที่ใช้ไป")]
|
||||
public double? LeaveDaysUsed { get; set; } = 0.0;
|
||||
|
||||
[Comment("จำนวนครั้งที่ลาสะสม")]
|
||||
public int? LeaveCount { get; set; } = 0;
|
||||
|
||||
public Guid? RootDnaId { get; set; }
|
||||
|
||||
public Guid? Child1DnaId { get; set; }
|
||||
|
||||
public Guid? Child2DnaId { get; set; }
|
||||
|
||||
public Guid? Child3DnaId { get; set; }
|
||||
|
||||
public Guid? Child4DnaId { get; set; }
|
||||
|
||||
[Required, Comment("จำนวนวันลายกมา")]
|
||||
public double BeginningLeaveDays { get; set; } = 0.0;
|
||||
|
||||
[Comment("จำนวนครั้งที่ลายกมา")]
|
||||
public int BeginningLeaveCount { get; set; } = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -210,5 +210,7 @@ namespace BMA.EHR.Domain.Models.Leave.Requests
|
|||
|
||||
public Guid? Child4DnaId { get; set; } = Guid.Empty;
|
||||
|
||||
public DateTime? DateSendLeave { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using BMA.EHR.Domain.Models.Base;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace BMA.EHR.Domain.Models.Leave.Requests
|
||||
{
|
||||
|
|
@ -16,6 +17,18 @@ namespace BMA.EHR.Domain.Models.Leave.Requests
|
|||
|
||||
public string PositionName { get; set; } = string.Empty;
|
||||
|
||||
[Comment("ประเภทระดับตำแหน่ง")]
|
||||
public string PositionLevelName { get; set; } = string.Empty;
|
||||
|
||||
[Comment("ตำแหน่งทางการบริหาร")]
|
||||
public string PosExecutiveName { get; set; } = string.Empty;
|
||||
|
||||
[Comment("สังกัด")]
|
||||
public string OrganizationName { get; set; } = string.Empty;
|
||||
|
||||
[Comment("ตำแหน่งใต้ลายเช็นต์")]
|
||||
public string? PositionSign { get; set; } = string.Empty;
|
||||
|
||||
public Guid ProfileId { get; set; } = Guid.Empty;
|
||||
|
||||
public Guid KeycloakId { get; set; } = Guid.Empty;
|
||||
|
|
@ -25,5 +38,10 @@ namespace BMA.EHR.Domain.Models.Leave.Requests
|
|||
public string Comment { get; set; } = string.Empty;
|
||||
|
||||
public string? ApproveType { get; set; } = string.Empty; // ผู้บังคับบัญชา = commander, ผู้มีอำนาจอนุมัติ = Approver
|
||||
|
||||
|
||||
public bool IsAct { get; set; } = false;
|
||||
|
||||
public string KeyId { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
using BMA.EHR.Domain.Models.Base;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace BMA.EHR.Domain.Models.Leave.TimeAttendants
|
||||
{
|
||||
public class CheckInJobStatus : EntityBase
|
||||
{
|
||||
[Required, Comment("Task ID สำหรับติดตามสถานะงาน")]
|
||||
public Guid TaskId { get; set; } = Guid.Empty;
|
||||
|
||||
[Required, Comment("รหัส User ของ Keycloak")]
|
||||
public Guid KeycloakUserId { get; set; } = Guid.Empty;
|
||||
|
||||
[Comment("วันเวลาที่สร้างงาน")]
|
||||
public DateTime CreatedDate { get; set; } = DateTime.Now;
|
||||
|
||||
[Comment("วันเวลาที่เริ่มประมวลผล")]
|
||||
public DateTime? ProcessingDate { get; set; }
|
||||
|
||||
[Comment("วันเวลาที่เสร็จสิ้นการประมวลผล")]
|
||||
public DateTime? CompletedDate { get; set; }
|
||||
|
||||
[Required, Comment("สถานะงาน: PENDING, PROCESSING, COMPLETED, FAILED")]
|
||||
public string Status { get; set; } = "PENDING";
|
||||
|
||||
[Comment("ประเภทการลงเวลา: CHECK_IN, CHECK_OUT")]
|
||||
public string? CheckType { get; set; }
|
||||
|
||||
[Comment("CheckInId สำหรับ Check-Out")]
|
||||
public Guid? CheckInId { get; set; }
|
||||
|
||||
[Comment("ข้อความแสดงข้อผิดพลาด")]
|
||||
public string? ErrorMessage { get; set; }
|
||||
|
||||
[Comment("ข้อมูลเพิ่มเติม (JSON)")]
|
||||
public string? AdditionalData { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using BMA.EHR.Domain.Models.Base;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace BMA.EHR.Domain.Models.Leave.TimeAttendants
|
||||
{
|
||||
public class LeaveProcessJobStatus: EntityBase
|
||||
{
|
||||
[Required, Comment("วันเริ่มต้น")]
|
||||
public DateTime StartDate { get; set; }
|
||||
|
||||
[Required, Comment("วันสิ้นสุด")]
|
||||
public DateTime EndDate { get; set; }
|
||||
|
||||
[Required, Comment("รหัส Root DNA Id")]
|
||||
public Guid RootDnaId { get; set; } = Guid.Empty;
|
||||
|
||||
[Comment("วันเวลาที่สร้างงาน")]
|
||||
public DateTime CreatedDate { get; set; } = DateTime.Now;
|
||||
|
||||
[Comment("วันเวลาที่เริ่มประมวลผล")]
|
||||
public DateTime? ProcessingDate { get; set; }
|
||||
|
||||
[Comment("วันเวลาที่เสร็จสิ้นการประมวลผล")]
|
||||
public DateTime? CompletedDate { get; set; }
|
||||
|
||||
[Required, Comment("สถานะงาน: PENDING, PROCESSING, COMPLETED, FAILED")]
|
||||
public string Status { get; set; } = "PENDING";
|
||||
|
||||
[Comment("ข้อความแสดงข้อผิดพลาด")]
|
||||
public string? ErrorMessage { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -119,6 +119,10 @@ namespace BMA.EHR.Domain.Models.Placement
|
|||
public string? position { get; set; }
|
||||
[Comment("ตำแหน่งทางการบริหาร")]
|
||||
public string? PositionExecutive { get; set; }
|
||||
|
||||
[Comment("id ตำแหน่งทางการบริหาร")]
|
||||
public string? posExecutiveId { get; set; }
|
||||
|
||||
[Comment("id ประเภทตำแหน่ง")]
|
||||
public string? posTypeId { get; set; }
|
||||
[Comment("ชื่อประเภทตำแหน่ง")]
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ namespace BMA.EHR.Domain.Models.Placement
|
|||
[Comment("ตำแหน่งปัจจุบัน กลุ่ม/ฝ่าย")]
|
||||
public string? OccupationGroup { get; set; }
|
||||
[Comment("ตำแหน่งปัจจุบัน เงินเดือน")]
|
||||
public int? OccupationSalary { get; set; }
|
||||
public double? OccupationSalary { get; set; }
|
||||
[Comment("ตำแหน่งปัจจุบัน สังกัด")]
|
||||
public string? OccupationPosition { get; set; }
|
||||
[Comment("ตำแหน่งปัจจุบัน ประเภทราชการ")]
|
||||
|
|
@ -321,6 +321,10 @@ namespace BMA.EHR.Domain.Models.Placement
|
|||
public string? positionName { get; set; }
|
||||
[Comment("ตำแหน่งทางการบริหาร")]
|
||||
public string? PositionExecutive { get; set; }
|
||||
|
||||
[Comment("id ตำแหน่งทางการบริหาร")]
|
||||
public string? posExecutiveId { get; set; }
|
||||
|
||||
[Comment("สายงาน")]
|
||||
public string? positionField { get; set; }
|
||||
[Comment("id ประเภทตำแหน่ง")]
|
||||
|
|
|
|||
|
|
@ -64,6 +64,10 @@ namespace BMA.EHR.Domain.Models.Placement
|
|||
public string? profileId { get; set; }
|
||||
[Comment("คำนำหน้า")]
|
||||
public string? prefix { get; set; }
|
||||
|
||||
[Comment("ยศ")]
|
||||
public string? rank { get; set; }
|
||||
|
||||
[Comment("ชื่อ")]
|
||||
public string? firstName { get; set; }
|
||||
[Comment("นามสกุล")]
|
||||
|
|
@ -128,6 +132,10 @@ namespace BMA.EHR.Domain.Models.Placement
|
|||
public string? position { get; set; }
|
||||
[Comment("ตำแหน่งทางการบริหาร")]
|
||||
public string? PositionExecutive { get; set; }
|
||||
|
||||
[Comment("id ตำแหน่งทางการบริหาร")]
|
||||
public string? posExecutiveId { get; set; }
|
||||
|
||||
[Comment("id ประเภทตำแหน่ง")]
|
||||
public string? posTypeId { get; set; }
|
||||
[Comment("ชื่อประเภทตำแหน่ง")]
|
||||
|
|
|
|||
|
|
@ -173,6 +173,10 @@ namespace BMA.EHR.Domain.Models.Retirement
|
|||
public string? position { get; set; }
|
||||
[Comment("ตำแหน่งทางการบริหาร")]
|
||||
public string? PositionExecutive { get; set; }
|
||||
|
||||
[Comment("id ตำแหน่งทางการบริหาร")]
|
||||
public string? posExecutiveId { get; set; }
|
||||
|
||||
[Comment("id ประเภทตำแหน่ง")]
|
||||
public string? posTypeId { get; set; }
|
||||
[Comment("ชื่อประเภทตำแหน่ง")]
|
||||
|
|
|
|||
|
|
@ -267,7 +267,7 @@ namespace BMA.EHR.Domain.ModelsExam.Candidate
|
|||
[Comment("ตำแหน่งปัจจุบัน กลุ่ม/ฝ่าย")]
|
||||
public string? OccupationGroup { get; set; }
|
||||
[Comment("ตำแหน่งปัจจุบัน เงินเดือน")]
|
||||
public int? OccupationSalary { get; set; }
|
||||
public double? OccupationSalary { get; set; }
|
||||
[Comment("ตำแหน่งปัจจุบัน สังกัด")]
|
||||
public string? OccupationPosition { get; set; }
|
||||
[Comment("ตำแหน่งปัจจุบัน ประเภทราชการ")]
|
||||
|
|
|
|||
|
|
@ -33,5 +33,8 @@ namespace BMA.EHR.Domain.ModelsExam.Candidate
|
|||
|
||||
[Comment("รหัสประจำตำแหน่งที่สอบ")]
|
||||
public string? Code { get; set; }
|
||||
|
||||
[Comment("ขีดจำกัดวุฒิการศึกษา")]
|
||||
public string? EducationLevel { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
public static readonly string DataNotFound = "ไม่พบข้อมูลในระบบ";
|
||||
|
||||
public static readonly string ProfileNotFound = "ไม่พบข้อมูลในระบบทะเบียนประวัติ";
|
||||
|
||||
public static readonly string NotAuthorized = "กรุณาเข้าสู่ระบบก่อนใช้งาน!";
|
||||
|
||||
public static readonly string ForbiddenAccess = "คุณไม่ได้รับอนุญาติให้เข้าใช้งาน!";
|
||||
|
|
|
|||
30
BMA.EHR.Domain/Shared/PrivilegeConverter.cs
Normal file
30
BMA.EHR.Domain/Shared/PrivilegeConverter.cs
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace BMA.EHR.Domain.Shared
|
||||
{
|
||||
public class PrivilegeConverter : JsonConverter
|
||||
{
|
||||
public override bool CanConvert(Type objectType)
|
||||
{
|
||||
return objectType == typeof(string);
|
||||
}
|
||||
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
if (reader.TokenType == JsonToken.Null)
|
||||
{
|
||||
return "EMPTY";
|
||||
}
|
||||
return reader.Value;
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
{
|
||||
writer.WriteValue(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -20,8 +20,6 @@ namespace BMA.EHR.Infrastructure
|
|||
public static IServiceCollection AddLeavePersistence(this IServiceCollection services,
|
||||
IConfiguration configuration)
|
||||
{
|
||||
|
||||
|
||||
// leave db context
|
||||
var connectionStringLeave = configuration.GetConnectionString("LeaveConnection");
|
||||
|
||||
|
|
@ -31,6 +29,10 @@ namespace BMA.EHR.Infrastructure
|
|||
{
|
||||
b.MigrationsAssembly(typeof(LeaveDbContext).Assembly.FullName);
|
||||
b.MigrationsHistoryTable("__LeaveMigrationsHistory");
|
||||
b.EnableRetryOnFailure(
|
||||
maxRetryCount: 5,
|
||||
maxRetryDelay: System.TimeSpan.FromSeconds(30),
|
||||
errorNumbersToAdd: null);
|
||||
|
||||
}),
|
||||
ServiceLifetime.Transient);
|
||||
|
|
@ -43,8 +45,6 @@ namespace BMA.EHR.Infrastructure
|
|||
public static IServiceCollection AddDisciplinePersistence(this IServiceCollection services,
|
||||
IConfiguration configuration)
|
||||
{
|
||||
|
||||
|
||||
// discipline db context
|
||||
var connectionStringDiscipline = configuration.GetConnectionString("DisciplineConnection");
|
||||
|
||||
|
|
@ -54,7 +54,10 @@ namespace BMA.EHR.Infrastructure
|
|||
{
|
||||
b.MigrationsAssembly(typeof(DisciplineDbContext).Assembly.FullName);
|
||||
b.MigrationsHistoryTable("__DisciplineMigrationsHistory");
|
||||
|
||||
b.EnableRetryOnFailure(
|
||||
maxRetryCount: 5,
|
||||
maxRetryDelay: System.TimeSpan.FromSeconds(30),
|
||||
errorNumbersToAdd: null);
|
||||
}),
|
||||
ServiceLifetime.Transient);
|
||||
|
||||
|
|
@ -67,8 +70,6 @@ namespace BMA.EHR.Infrastructure
|
|||
IConfiguration configuration)
|
||||
{
|
||||
services.AddTransient<MinIOService>();
|
||||
|
||||
|
||||
var connectionString = configuration.GetConnectionString("DefaultConnection");
|
||||
|
||||
services.AddDbContext<ApplicationDBContext>(options =>
|
||||
|
|
@ -77,10 +78,15 @@ namespace BMA.EHR.Infrastructure
|
|||
{
|
||||
b.MigrationsAssembly(typeof(ApplicationDBContext).Assembly.FullName);
|
||||
b.MigrationsHistoryTable("__EHRMigrationsHistory");
|
||||
b.EnableRetryOnFailure(
|
||||
maxRetryCount: 5,
|
||||
maxRetryDelay: System.TimeSpan.FromSeconds(30),
|
||||
errorNumbersToAdd: null);
|
||||
|
||||
}),
|
||||
ServiceLifetime.Transient);
|
||||
|
||||
|
||||
services.AddTransient<IApplicationDBContext>(provider => provider.GetService<ApplicationDBContext>());
|
||||
|
||||
var connectionStringExam = configuration.GetConnectionString("ExamConnection");
|
||||
|
|
@ -91,6 +97,10 @@ namespace BMA.EHR.Infrastructure
|
|||
{
|
||||
b.MigrationsAssembly(typeof(ApplicationDBExamContext).Assembly.FullName);
|
||||
b.MigrationsHistoryTable("__EHRMigrationsHistory");
|
||||
b.EnableRetryOnFailure(
|
||||
maxRetryCount: 5,
|
||||
maxRetryDelay: System.TimeSpan.FromSeconds(30),
|
||||
errorNumbersToAdd: null);
|
||||
|
||||
}),
|
||||
ServiceLifetime.Transient);
|
||||
|
|
|
|||
|
|
@ -16,8 +16,6 @@ namespace BMA.EHR.Infrastructure.MessageQueue
|
|||
{
|
||||
#region " Fields "
|
||||
|
||||
private readonly UserProfileRepository _userProfileRepository;
|
||||
private readonly InsigniaPeriodsRepository _insigniaPeriodsRepository;
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
private const string INSIGNIA_QUEUE = "bma_insignia_request";
|
||||
|
||||
|
|
@ -30,16 +28,12 @@ namespace BMA.EHR.Infrastructure.MessageQueue
|
|||
|
||||
#region " Constructor and Destructor "
|
||||
|
||||
public RabbitMQConsumer(UserProfileRepository userProfileRepository,
|
||||
InsigniaPeriodsRepository insigniaPeriodsRepository,
|
||||
IHttpContextAccessor httpContextAccessor,
|
||||
public RabbitMQConsumer(IHttpContextAccessor httpContextAccessor,
|
||||
IServiceScopeFactory serviceScopeFactory,
|
||||
IConfiguration configuration)
|
||||
{
|
||||
_serviceScopeFactory = serviceScopeFactory;
|
||||
_configuration = configuration;
|
||||
_userProfileRepository = userProfileRepository;
|
||||
_insigniaPeriodsRepository = insigniaPeriodsRepository;
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
|
||||
var host = _configuration["RabbitMQ:URL"];
|
||||
|
|
@ -85,7 +79,7 @@ namespace BMA.EHR.Infrastructure.MessageQueue
|
|||
var userRepo = scope.ServiceProvider.GetRequiredService<UserProfileRepository>();
|
||||
var insigniaRepo = scope.ServiceProvider.GetRequiredService<InsigniaPeriodsRepository>();
|
||||
|
||||
var selectPeriod = await _insigniaPeriodsRepository.GetByIdAsync(periodId);
|
||||
var selectPeriod = await insigniaRepo.GetByIdAsync(periodId);
|
||||
if (selectPeriod == null)
|
||||
{
|
||||
throw new Exception(GlobalMessages.InsigniaPeriodNotFound);
|
||||
|
|
|
|||
21243
BMA.EHR.Infrastructure/Migrations/20251117105514_update_table_PlacementProfile_and_Candidate.Designer.cs
generated
Normal file
21243
BMA.EHR.Infrastructure/Migrations/20251117105514_update_table_PlacementProfile_and_Candidate.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
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