diff --git a/assets/language/id/data.json b/assets/language/id/data.json index 9e064e9a..4f76a8ff 100644 --- a/assets/language/id/data.json +++ b/assets/language/id/data.json @@ -5,7 +5,8 @@ "payload-bad": "struktur data tidak sesuai standar", "auth-required": "butuh autentikasi", - "auth-missingHeader": "Header autentikasi tidak ditemukan", + "auth-getData-failed": "gagal mengambil data user", + "auth-missingHeader": "header autentikasi tidak ditemukan", "auth-forbidden": "tidak diijinkan", "auth-login-success": "login berhasil", "auth-login-incorrect": "Username atau Password Tidak Sesuai", diff --git a/cmd/main-api/config.yml-example b/cmd/main-api/config.yml-example index f131a725..60b1644c 100644 --- a/cmd/main-api/config.yml-example +++ b/cmd/main-api/config.yml-example @@ -63,4 +63,7 @@ bpjsCfg: corsCfg: allowedOrigins: - http://example.com - allowedMethod: \ No newline at end of file + allowedMethod: + +bpjsCfg: + baseUrl: \ No newline at end of file diff --git a/cmd/main-migration/migrations/20251102002037.sql b/cmd/main-migration/migrations/20251102002037.sql new file mode 100644 index 00000000..14a39ae1 --- /dev/null +++ b/cmd/main-migration/migrations/20251102002037.sql @@ -0,0 +1,6 @@ +-- Modify "McuOrder" table +ALTER TABLE "public"."McuOrder" ADD COLUMN "Scope_Code" character varying(10) NULL; +-- Create index "idx_McuOrder_Scope_Code" to table: "McuOrder" +CREATE INDEX "idx_McuOrder_Scope_Code" ON "public"."McuOrder" ("Scope_Code"); +-- Create index "idx_McuSrcCategory_Scope_Code" to table: "McuSrcCategory" +CREATE INDEX "idx_McuSrcCategory_Scope_Code" ON "public"."McuSrcCategory" ("Scope_Code"); diff --git a/cmd/main-migration/migrations/20251102091932.sql b/cmd/main-migration/migrations/20251102091932.sql new file mode 100644 index 00000000..f10eadd3 --- /dev/null +++ b/cmd/main-migration/migrations/20251102091932.sql @@ -0,0 +1,2 @@ +-- Rename a column from "McuUrgencyLevel_Code" to "UrgencyLevel_Code" +ALTER TABLE "public"."McuOrder" RENAME COLUMN "McuUrgencyLevel_Code" TO "UrgencyLevel_Code"; diff --git a/cmd/main-migration/migrations/20251103081637.sql b/cmd/main-migration/migrations/20251103081637.sql new file mode 100644 index 00000000..ca898d90 --- /dev/null +++ b/cmd/main-migration/migrations/20251103081637.sql @@ -0,0 +1,17 @@ +-- Create "ControlLetter" table +CREATE TABLE "public"."ControlLetter" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "Encounter_Id" bigint NULL, + "Unit_Id" bigint NULL, + "Specialist_Id" bigint NULL, + "Subspecialist_Id" bigint NULL, + "Date" timestamptz NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "fk_ControlLetter_Encounter" FOREIGN KEY ("Encounter_Id") REFERENCES "public"."Encounter" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT "fk_ControlLetter_Specialist" FOREIGN KEY ("Specialist_Id") REFERENCES "public"."Specialist" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT "fk_ControlLetter_Subspecialist" FOREIGN KEY ("Subspecialist_Id") REFERENCES "public"."Subspecialist" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT "fk_ControlLetter_Unit" FOREIGN KEY ("Unit_Id") REFERENCES "public"."Unit" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION +); diff --git a/cmd/main-migration/migrations/atlas.sum b/cmd/main-migration/migrations/atlas.sum index 2c4fb649..eca39d6d 100644 --- a/cmd/main-migration/migrations/atlas.sum +++ b/cmd/main-migration/migrations/atlas.sum @@ -1,68 +1,67 @@ -h1:fy7zM85i70X6PkLcypubf4GA17KSCQpjrSNRRLdWyjM= -20250904105930.sql h1:MEM6blCgke9DzWQSTnLzasbPIrcHssNNrJqZpSkEo6k= -20250904141448.sql h1:J8cmYNk4ZrG9fhfbi2Z1IWz7YkfvhFqTzrLFo58BPY0= -20250908062237.sql h1:Pu23yEW/aKkwozHoOuROvHS/GK4ngARJGdO7FB7HZuI= -20250908062323.sql h1:oXl6Z143tOpIl4EfP4B8JNU8LrMvVmHEtCgAfiB4gs8= -20250908073811.sql h1:m2aNXfnGxnLq1+rVWrh4f60q7fhyhV3gEwNu/OIqQlE= -20250908073839.sql h1:cPk54xjLdMs26uY8ZHjNWLuyfAMzV7Zb0/9oJQrsw04= -20250910055902.sql h1:5xwjAV6QbtZT9empTJKfhyAjdknbHzb15B0Ku5dzqtQ= -20250915123412.sql h1:D83xaU2YlDEd21HLup/YQpQ2easMToYCyy/oK6AFgQs= -20250916043819.sql h1:ekoTJsBqQZ8G8n0qJ03d13+eoNoc7sAUEQGA5D/CCxk= -20250917040616.sql h1:zoCnmcXuM7AVv85SmN7RmFglCgJnoDmpRWExH0LAc9Q= -20250917040751.sql h1:J1xyRrh32y1+lezwAyNwPcUQ6ABBSgbvzNLva4SVdQU= -20250917045138.sql h1:jKe1Z0uOLG4SGBYM+S/3P+/zMPztmgoderD5swnMuCg= -20250917093645.sql h1:cNI3Pbz1R3LxvIXLuexafJFCXUXrmuFCgXXJ2sG+FW0= -20250918073552.sql h1:RJ1SvMzP6aeWnoPVD3eVAmIQOkcp6Php8z3QRri6v4g= -20250918073742.sql h1:+cEsnJTJFybe2fR69ZoOiX2R6c6iITl4m6WTZ1hjyzY= -20250918074745.sql h1:2hNVQCXF/dVYXAh+T/7oBFgERGWxzVb2FXJjwkFWGCI= -20250923025134.sql h1:Ykz/qpHiGDXPsCsWTjydQFVSibZP2D+h2fIeb2h2JGA= -20250924051317.sql h1:yQuW6SwJxIOM5fcxeAaie5lSm1oLysU/C2hH2xNCVoQ= -20250929034321.sql h1:101FJ8VH12mrZWlt/X1gvKUGOhoiF8tFbjiapAjnHzg= -20250929034428.sql h1:i+pROD9p+g5dOmmZma6WF/0Hw5g3Ha28NN85iTo1K34= -20250930025550.sql h1:+F+CsCUXD/ql0tHGEow70GhPBX1ZybVn+bh/T4YMh7Y= -20250930140351.sql h1:9AAEG1AnOAH+o0+oHL5G7I8vqlWOhwRlCGyyCpT/y1Q= -20251002085604.sql h1:3xZ68eYp4urXRnvotNH1XvG2mYOSDV/j3zHEZ/txg5E= -20251003032030.sql h1:HB+mQ2lXMNomHDpaRhB/9IwYI9/YiDO5eOJ+nAQH/jw= -20251005060450.sql h1:LbtCE2b+8osM3CvnmQJH1uCPtn+d7WchsslBOz8bL3Q= -20251006041122.sql h1:MlS7f21z06sutnf9dIekt5fuHJr4lgcQ4uCuCXAGsfc= -20251006045658.sql h1:3FmGCPCzjgMPdWDRodZTsx3KVaodd9zB9ilib69aewk= -20251006045928.sql h1:Z5g31PmnzNwk/OKdODcxZGm8fjJQdMFK32Xfnt3bRHg= -20251007022859.sql h1:FO03zEfaNEk/aXwY81d5Lp3MoBB9kPQuXlXJ4BPiSR8= -20251008031337.sql h1:l+sxUAGvcTfj3I6kAFHo+T6AYodC9k9GkR+jaKO2xXc= -20251008031554.sql h1:AqrVfIhSzY3PCy8ZlP5W91wn2iznfIuj5qQfubp6/94= -20251008052346.sql h1:nxnXmooIJ6r1mmzwnw+6efxLfc/k9h2aE6RMptPRons= -20251008073620.sql h1:6YsJp1W4SmQJ1lxpqF27BBlDC1zqhw7Yhc7pLzQTY6M= -20251009042854.sql h1:nkBV+R6j0fg7/JY6wH3eb5Vv0asJLnXmb6lINfT/GLQ= -20251009052657.sql h1:EPvdsib5rzCGPryd10HShGKvFPwM/R5S2lIVwtYxpms= -20251010031743.sql h1:T8IZmx8/btRFKLzTe78MzcBsPJNodnLvB0tby9QkirQ= -20251010070721.sql h1:5NQUk/yOV6sABLCB7swx++YIOyJe6MnU+yt1nRzde5w= -20251010072711.sql h1:ZJNqR2piyu8xJhBvVABSlnGEoKSKae3wuEs+wshPe4k= -20251013044536.sql h1:0Xjw8fNILiT8nnfrJDZgQnPf3dntmIoilbapnih8AE4= -20251013051438.sql h1:lfSuw5mgJnePBJamvhZ81osFIouXeiIEiSZ/evdwo48= -20251013081808.sql h1:ijgjNX08G6GBjA/ks8EKtb7P7Y7Cg7zbhqEOruGnv6M= -20251014060047.sql h1:0jqj49WTtneEIMQDBoo4c095ZGi8sCrA8NnHBrPU6D8= -20251014063537.sql h1:VZLXol0PTsTW21Epg6vBPsztWkDtcxup9F/z88EGgIg= -20251014063720.sql h1:2HVUyCV0ud3BJJDH2GEKZN/+IWLFPCsN1KqhP6csO14= -20251015045455.sql h1:MeLWmMhAOAz8b15Dd7IAQnt6JxjSml02XCXK22C0Lpg= -20251016010845.sql h1:4BncQdDOasRZJkzVJrSJJA7091A9VPNVx/faUCUPhBM= -20251016011023.sql h1:9JB9eFZKURK5RoCVDKR6glSvdJ8NTXrN7K/4q51zkz4= -20251016062912.sql h1:ACNn0fe+EMqUt3hoY+Dr3uqAV/QICBa1+mIW7fUc9Fk= -20251017060617.sql h1:4T3t9ifWrEQTPMSM0XJ98pF7Qdt+UfgtMui17bhrnWI= -20251017082207.sql h1:8vLG1l/saRRMHXkyA4nelJyjaSddhZd6r7R+Uo4JS/c= -20251018032635.sql h1:2xey5gnO3y2XSOrU8MLlIfoylPKbRGDRtHDD07B3MbQ= -20251018040322.sql h1:k/pdNiSoT8zFPqNQ/avOD0vYkNh3BTD64IlHrfVXr7I= -20251019093915.sql h1:hFcQE0y+p5dZiVwePGsRGto9m/q6kJNiUZbVDd5Rnjk= -20251020062553.sql h1:Iw7hulcm5iRQlfW+ygA4iTPxLqkxx6h9vXMXEwUAHKs= -20251021041042.sql h1:wMgSivBV2A0NDcsLmKGIp0kMcVh2IODSG9b4dgzCaOM= -20251021075552.sql h1:8gfSMAglflNO6L0sSzxFNEubYN8/O4thT7OQT+WH+3M= -20251023044432.sql h1:MkvajJs3bfk9+wHvQ43/ccAluJEBARm1gWr1u92ccLA= -20251024034832.sql h1:x3s3VEVYLOSKLAFxJGb2+c1FyTMMvPE+9k4Ew7rKQaI= -20251024074315.sql h1:EjAjelgi5qAfcRq/8vPTlGGYHvAKxNTllm8f0SzZDns= -20251025013451.sql h1:6hnuIiwYiG+6nLhOY/+Yyn+I6ZCFNRZxrJNqBV6HLqE= -20251025013609.sql h1:evPJaTD8WxYRMOJZHkSr7ONLx9PYxT+ankzQt9c/sJ0= -20251027075128.sql h1:/iFQBM1sytjqpyQSOx61q33gnorMgxTiFVSuL6bQqsM= -20251027091406.sql h1:eCZGtUkxAzEAqpC9UsGpP8Df9mS0DEOqSl885LgqpvM= -20251031082443.sql h1:ajvi2G8OGvcmB2pJ1SoX/09ALHLWKNh84RSonVhJqAc= -20251031084657.sql h1:86mNMS/oMNhewetTvLMFvEz1J6AANePHkE0fOztqHTM= -20251102115856.sql h1:H1pqgG/uonIc8iHVZVBR2CLg/iRR4alsvC4Rty/GXH8= -20251102141135.sql h1:icypnR4c5x7v6rKZNyhUREh3udLz5iX2yk7yEfRF7xM= +h1:DcO8hW6ltApCY7bmxeSji280ls5j97uZeEb034pHQqY= +20250904105930.sql h1:Vv4vCurl7m7/ZB6TjRpkubHpQ4RYwSUn0QHdzfoGpzY= +20250904141448.sql h1:FYCHH9Os4KkrZMDu/jR8FMP+wLMRW+Mb0PkLU/9BRDg= +20250908062237.sql h1:oanBpKZd+akPu2I/xYhUSbd0G5tAFbXzKLER/Zs8ENI= +20250908062323.sql h1:miNG9COddXkD1jGTgaROMAZ618eT6oiLGiJhXWnQwhE= +20250908073811.sql h1:gOi5cnGG1htlpfizybYmUIT0vYjZTBfXiI0nPSYK2u8= +20250908073839.sql h1:cWNDA4YikjoOteAJuNLFILjQUJPFB6o8Wxreiek4QyI= +20250910055902.sql h1:nxxOGnU0BbH/v3IPgeIOXOwH8d3tKomw7h6FTeMnnBs= +20250915123412.sql h1:mz7SiWfrdf0qE1VTSAAnA/147d6gyp6ry5vZ2bR9SH0= +20250916043819.sql h1:RHXVtmMkB6wfv06HfPyHMBmUfIpFt1xveafNz0kwKnE= +20250917040616.sql h1:MYVDht+akBlzQGKNu2hTTTLPEcH1bxT/Q8MK6WEtuhs= +20250917040751.sql h1:J79YyS2JzWgh5oKXMTgh67uo3gLxKaAsxRiZmSIfjBs= +20250917045138.sql h1:/SM1N4O8X3yxpoJgMEARmS1uOkuLKsTOy4PLsRCOKaQ= +20250917093645.sql h1:PNBTGZ7s10e5b5+Tie8YfVQBN0zKtJ5T34oK1iOUEb4= +20250918073552.sql h1:jG7+g3i8ODYaJdcdZz12v3nbsZ5mB9wG6kWnGyTQIRI= +20250918073742.sql h1:j+rgw7puxE7s+phqPVZHmPk0af3rcaA56Itp86y1suY= +20250918074745.sql h1:rPmP4DXs6OnY4Vp+xO/z9jFpJt/RrJ52SJJjIIxeDvc= +20250923025134.sql h1:2r6pcwnBSU5Y9Czk1OHBoh4yZXiMtEca9X8843fTEX0= +20250924051317.sql h1:iUAk2gsGoEGIPQ0lEEUp8maMSId8emNbP+kP712ABIA= +20250929034321.sql h1:UlpALNVmdi95zOIT0yc6ZyTj9bBjQEIpZhvgrc52M+k= +20250929034428.sql h1:feF+H4nDyHh5bdx48Oiz0A1qecZfi6v3qTTdjzJ45Dg= +20250930025550.sql h1:6XT1kXI3Z3ZIxxmvT7poufZWWCW0QiejZPaFV5wBnjI= +20250930140351.sql h1:HxnmAbh9gCy8jwl/9ycGktiByaUripsjFFvohofY2CY= +20251002085604.sql h1:SjLPi+ZN6qDccK3DaEQCgNsZpPwr5kynWXwbwEsziCI= +20251003032030.sql h1:oHfxNSuqTxU8Zaf9H+h8TuUb1Da03wcyc6hZjDrUQ2s= +20251005060450.sql h1:GIuCcrd4MwjmXpvbzDzPYL18BV3QaZZ+Y2FmEzjvi0E= +20251006041122.sql h1:uNDQbSw0M08lYoMvUNlQtS3iDzpPM1ixT13ugSAoWjE= +20251006045658.sql h1:z+t7yCK54Q4SSiF9kUyUhkYB2F+kzSW9TB7ogxd9wzw= +20251006045928.sql h1:1lATLFLp4BWwGZqAjZdP0Dc6ypNXiYcwjoNkqGa8NFE= +20251007022859.sql h1:HXXwWrkyvzJzJGAt9mGskCRBBV/c1JfPmfjDocmJhQ4= +20251008031337.sql h1:Ln5pCF3Hxa5foHZLcds+z/us2eH6VAhhEj3w0TAGlVs= +20251008031554.sql h1:aB4MUS2lmqG0//4HKUWorcPSpWya0VC4QItvGyskEVI= +20251008052346.sql h1:MI3AZgU5XcwZT2OvvlWAxdRtL0eJ3jjRwt56IY1+pRU= +20251008073620.sql h1:sztWXuSNYwpEraaSapSsYwno75LO5H/N7ob7OJQ8X/A= +20251009042854.sql h1:TnPXj+dCJls3IU//cuqJZymyBzZMKs7ayazfgtAFRxM= +20251009052657.sql h1:leXbs0CP8r5dRilmYyLRk1MICqak3ea1/LWMtFrijqQ= +20251010031743.sql h1:SgHNY/lQ88G2F4nZyMfiOkDntb+gtOR+nEQLqXBTwv4= +20251010070721.sql h1:AnJnhXsMzDvK4AFgYw6B16Kpo/hljrZtcpc9m2VOSHQ= +20251010072711.sql h1:aXPTtNwLcTuw8C/yAxwxvqs0ayEjNzI1uuE0vE3ERa8= +20251013044536.sql h1:7Pq6JcvTpPBYDCW2dz3HdgUwY65HlhEVWy9TiG8iONE= +20251013051438.sql h1:X6t8bkqpUYYokBunSufMQUe5vCg0VyO6dxbm7ngosUc= +20251013081808.sql h1:495pLguXL2Ozh+ycn4UYZgZbn6WbjXNbyZUc3JU8qhI= +20251014060047.sql h1:nCgImMRGHhziiW57O1ofWaXCAPGaCOHN7PldQ3OSmM4= +20251014063537.sql h1:2cLmID79jP6cuQ1YJaWTtghFiM1GtHMC0ZQl30Hpy1M= +20251014063720.sql h1:bzLKKVAjSHgDFoiI/glj7t1ETlSAKx+AlsIAaP0ru2g= +20251015045455.sql h1:S547+UugQhlTRcn1Lm1IfqT5RNPttIWIiD+RTx69YaE= +20251016010845.sql h1:c9DUvxl17pUkf0azdYGM/YDzYxIJkLcfZOcMI4rL+R0= +20251016011023.sql h1:u3ivg83bXgYHBbojbWpemLxPE9Dmmj53B6LXo664jxw= +20251016062912.sql h1:W9n1hWchfYkqNX9LO9uxFxEXAb/iY+Pexjnhmp6PbgI= +20251017060617.sql h1:VU6yZ2+LfHpDZ3+TIH40t3F5YXPCpTppuF9+uSqa4b8= +20251017082207.sql h1:QshZslfedckz7iDpSGmPyY9sP6dy6ckHbs8L1TuXIA4= +20251018032635.sql h1:M1U/9W/F9wlW5YDmVAmHFfUJU7FWFaX0DblpfZcYWrE= +20251018040322.sql h1:Zk/vw0e6AzWFO2ElLOzB+OrSz6k+h1Ynxp0TImAzxwY= +20251019093915.sql h1:3Q0kPiZwJnHn5rAvdh0w1LBdiA7W2xBmZWncoPXb044= +20251020062553.sql h1:mJwC/J8GzPAIXckNMvy1f/Nguk2VVf8roD/Raclhbao= +20251021041042.sql h1:d1BAOGAQhqr+oOwcpAVozUsTh457VSDEk2qQFavGG58= +20251021075552.sql h1:TNChGQ1Zlr/1iQ6qvK4iDTAJpe6L/z/M6e/O0SkQVaM= +20251023044432.sql h1:GA2AdJk2ULyjr6igtu9C/CEi4YUIks8r9jXGGaCvPsk= +20251024034832.sql h1:RXmbEhMkOLK5g1QL6up8iRPcwYfo89oLP26ZHvrUK9o= +20251024074315.sql h1:3GnPQSbuAAfMa8oWDyBjhXqn1j1zunY/w0ydX0IGPrA= +20251025013451.sql h1:5eNrA9LDxA4i5CCP7wSyOgFZ6t6jBWVil+oGzJpkJ2E= +20251025013609.sql h1:+N6EHc1kv3hqf16CUhXe+UITPmoxOPfi4MECLmJXNrc= +20251027075128.sql h1:PQflgsjce/p2ClbybLtdehdPNDcMZ9Lb1vd98xd0K8E= +20251027091406.sql h1:bYXV57GvodCMjg0/ox+XKGIAGhrDlVuJ1wO4foNEKtQ= +20251102002037.sql h1:ZcwULsJU2lI9t5pX7ukmfAHSx4ZxdxLUX6jzLDc2SrU= +20251102091932.sql h1:A6y9j4wAqm4/HfMDxhpy/ChDn3UNRVN99KGgSCX+e18= +20251103081637.sql h1:RFqJNhJItSwJQaMP5IcQ14mL7eQ3EJjGZua9zLWzwMU= diff --git a/internal/domain/bpjs-entities/member/dto.go b/internal/domain/bpjs-entities/member/dto.go index f9c95655..e61a9f74 100644 --- a/internal/domain/bpjs-entities/member/dto.go +++ b/internal/domain/bpjs-entities/member/dto.go @@ -4,7 +4,6 @@ type ReadListDto struct { ReferenceType ReferenceType `json:"-"` PathValue1 string `json:"-"` PathValue2 string `json:"-"` - PathValue3 string `json:"-"` } type ReferenceType string diff --git a/internal/domain/bpjs-entities/vclaim-member/dto.go b/internal/domain/bpjs-entities/vclaim-member/dto.go index 5914deb6..34638abb 100644 --- a/internal/domain/bpjs-entities/vclaim-member/dto.go +++ b/internal/domain/bpjs-entities/vclaim-member/dto.go @@ -1 +1,61 @@ package vclaimmember + +import ecore "simrs-vx/internal/domain/base-entities/core" + +type CreateDto struct { + CardNumber *string `json:"cardNumber" validate:"maxLength=20"` + Person_Id *uint `json:"person_id"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Sort string `json:"sort"` + Pagination ecore.Pagination +} + +type FilterDto struct { + CardNumber *string `json:"cardNumber"` +} + +type ReadDetailDto struct { + Id uint `json:"id"` + CardNumber *string `json:"cardNumber"` +} + +type UpdateDto struct { + Id uint `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint `json:"id"` + CardNumber *string `json:"cardNumber"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.Main + CardNumber *string `json:"cardNumber"` +} + +func (d VclaimMember) ToResponse() ResponseDto { + resp := ResponseDto{ + CardNumber: d.CardNumber, + } + resp.Main = d.Main + return resp +} + +func ToResponseList(data []VclaimMember) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/adime/dto.go b/internal/domain/main-entities/adime/dto.go index 49257154..cb9b675a 100644 --- a/internal/domain/main-entities/adime/dto.go +++ b/internal/domain/main-entities/adime/dto.go @@ -1,13 +1,16 @@ package adime import ( + // std "time" + // internal - lib + pa "simrs-vx/internal/lib/auth" + + // internal - domain ecore "simrs-vx/internal/domain/base-entities/core" eem "simrs-vx/internal/domain/main-entities/employee" ee "simrs-vx/internal/domain/main-entities/encounter" - - pa "simrs-vx/pkg/auth-helper" ) type CreateDto struct { diff --git a/internal/domain/main-entities/adm-employee-hist/dto.go b/internal/domain/main-entities/adm-employee-hist/dto.go new file mode 100644 index 00000000..9a5d838f --- /dev/null +++ b/internal/domain/main-entities/adm-employee-hist/dto.go @@ -0,0 +1,78 @@ +package adm_employee_hist + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + ee "simrs-vx/internal/domain/main-entities/employee" + "time" +) + +type CreateDto struct { + Encounter_Id *uint `json:"encounter_id"` + Employee_Id *uint `json:"employee_id"` + StartedAt *time.Time `json:"startedAt"` + FinishedAt *time.Time `json:"finishedAt"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Sort string `json:"sort"` + Pagination ecore.Pagination +} + +type FilterDto struct { + Encounter_Id *uint `json:"encounter-id"` + Employee_Id *uint `json:"employee-id"` + StartedAt *time.Time `json:"startedAt"` + FinishedAt *time.Time `json:"finishedAt"` +} + +type ReadDetailDto struct { + Id uint16 `json:"id"` + Code *string `json:"code"` + Includes string `json:"includes"` +} + +type UpdateDto struct { + Id uint16 `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint16 `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.Main // adjust this according to the needs + Encounter_Id *uint `json:"encounter_id"` + Employee_Id *uint `json:"employee_id"` + Employee *ee.Employee `json:"employee,omitempty"` + StartedAt *time.Time `json:"startedAt"` + FinishedAt *time.Time `json:"finishedAt"` +} + +func (d AdmEmployeeHist) ToResponse() ResponseDto { + resp := ResponseDto{ + Encounter_Id: d.Encounter_Id, + Employee_Id: d.Employee_Id, + Employee: d.Employee, + StartedAt: d.StartedAt, + FinishedAt: d.FinishedAt, + } + resp.Main = d.Main + return resp +} + +func ToResponseList(data []AdmEmployeeHist) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/chemo/dto.go b/internal/domain/main-entities/chemo/dto.go index 19e5f803..8317b259 100644 --- a/internal/domain/main-entities/chemo/dto.go +++ b/internal/domain/main-entities/chemo/dto.go @@ -1,16 +1,20 @@ package chemo import ( + // std "time" + // internal - lib + pa "simrs-vx/internal/lib/auth" + + // internal - domain - references + erc "simrs-vx/internal/domain/references/common" + + // internal - domain - main-entities ecore "simrs-vx/internal/domain/base-entities/core" ee "simrs-vx/internal/domain/main-entities/encounter" eun "simrs-vx/internal/domain/main-entities/unit" eus "simrs-vx/internal/domain/main-entities/user" - - erc "simrs-vx/internal/domain/references/common" - - pa "simrs-vx/pkg/auth-helper" ) type CreateDto struct { diff --git a/internal/domain/main-entities/consultation/dto.go b/internal/domain/main-entities/consultation/dto.go index 1b0e3cc5..33868dd0 100644 --- a/internal/domain/main-entities/consultation/dto.go +++ b/internal/domain/main-entities/consultation/dto.go @@ -1,14 +1,19 @@ package consultation import ( + // std "time" + // internal - lib + pa "simrs-vx/internal/lib/auth" + + // internal - domain - base-entities ecore "simrs-vx/internal/domain/base-entities/core" + + // internal - domain - main-entities ed "simrs-vx/internal/domain/main-entities/doctor" ee "simrs-vx/internal/domain/main-entities/encounter" eu "simrs-vx/internal/domain/main-entities/unit" - - pa "simrs-vx/pkg/auth-helper" ) type CreateDto struct { diff --git a/internal/domain/main-entities/control-letter/dto.go b/internal/domain/main-entities/control-letter/dto.go new file mode 100644 index 00000000..270ff7b5 --- /dev/null +++ b/internal/domain/main-entities/control-letter/dto.go @@ -0,0 +1,104 @@ +package controlletter + +import ( + // std + "time" + + // internal - lib + pa "simrs-vx/internal/lib/auth" + + // internal - domain - base-entities + ecore "simrs-vx/internal/domain/base-entities/core" + + // internal - domain - main-entities + + ee "simrs-vx/internal/domain/main-entities/encounter" + es "simrs-vx/internal/domain/main-entities/specialist" + ess "simrs-vx/internal/domain/main-entities/subspecialist" + eu "simrs-vx/internal/domain/main-entities/unit" +) + +type CreateDto struct { + Encounter_Id *uint `json:"encounter_id"` + Unit_Id *uint `json:"unit_id"` + Specialist_Id *uint `json:"specialist_id"` + Subspecialist_Id *uint `json:"subspecialist_id"` + Date *time.Time `json:"date"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Pagination ecore.Pagination +} + +type FilterDto struct { + Encounter_Id *uint `json:"encounter-id"` + Unit_Id *uint `json:"unit-id"` + Specialist_Id *uint `json:"specialist-id"` + Subspecialist_Id *uint `json:"subspecialist-id"` + Date *time.Time `json:"date"` +} + +type ReadDetailDto struct { + Id uint16 `json:"id"` +} + +type UpdateDto struct { + Id uint `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint `json:"id"` +} + +type ReplyDto struct { + Id uint `json:"id"` + Solution *string `json:"solution"` + + pa.AuthInfo +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.Main + Encounter_Id *uint `json:"encounter_id"` + Encounter *ee.Encounter `json:"encounter" gorm:"foreignKey:Encounter_Id;references:Id"` + Unit_Id *uint `json:"unit_id"` + Unit *eu.Unit `json:"unit" gorm:"foreignKey:Unit_Id;references:Id"` + Specialist_Id *uint `json:"specialist_id"` + Specialist *es.Specialist `json:"specialist" gorm:"foreignKey:Specialist_Id;references:Id"` + Subspecialist_Id *uint `json:"subspecialist_id"` + Subspecialist *ess.Subspecialist `json:"subspecialist" gorm:"foreignKey:Subspecialist_Id;references:Id"` + Date *time.Time `json:"date"` +} + +func (d ControlLetter) ToResponse() ResponseDto { + resp := ResponseDto{ + Encounter_Id: d.Encounter_Id, + Encounter: d.Encounter, + Unit_Id: d.Unit_Id, + Unit: d.Unit, + Specialist_Id: d.Specialist_Id, + Specialist: d.Specialist, + Subspecialist_Id: d.Subspecialist_Id, + Subspecialist: d.Subspecialist, + Date: d.Date, + } + resp.Main = d.Main + return resp +} + +func ToResponseList(data []ControlLetter) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/control-letter/entity.go b/internal/domain/main-entities/control-letter/entity.go new file mode 100644 index 00000000..9cf74a68 --- /dev/null +++ b/internal/domain/main-entities/control-letter/entity.go @@ -0,0 +1,24 @@ +package controlletter + +import ( + "time" + + ecore "simrs-vx/internal/domain/base-entities/core" + ee "simrs-vx/internal/domain/main-entities/encounter" + es "simrs-vx/internal/domain/main-entities/specialist" + ess "simrs-vx/internal/domain/main-entities/subspecialist" + eu "simrs-vx/internal/domain/main-entities/unit" +) + +type ControlLetter struct { + ecore.Main // adjust this according to the needs + Encounter_Id *uint `json:"encounter_id"` + Encounter *ee.Encounter `json:"encounter" gorm:"foreignKey:Encounter_Id;references:Id"` + Unit_Id *uint `json:"unit_id"` + Unit *eu.Unit `json:"unit" gorm:"foreignKey:Unit_Id;references:Id"` + Specialist_Id *uint `json:"specialist_id"` + Specialist *es.Specialist `json:"specialist" gorm:"foreignKey:Specialist_Id;references:Id"` + Subspecialist_Id *uint `json:"subspecialist_id"` + Subspecialist *ess.Subspecialist `json:"subspecialist" gorm:"foreignKey:Subspecialist_Id;references:Id"` + Date *time.Time `json:"date"` +} diff --git a/internal/domain/main-entities/device-order/dto.go b/internal/domain/main-entities/device-order/dto.go index 01ef34b2..3d944941 100644 --- a/internal/domain/main-entities/device-order/dto.go +++ b/internal/domain/main-entities/device-order/dto.go @@ -1,13 +1,18 @@ package deviceorder import ( - ecore "simrs-vx/internal/domain/base-entities/core" - ed "simrs-vx/internal/domain/main-entities/doctor" - ee "simrs-vx/internal/domain/main-entities/encounter" + // internal - lib + pa "simrs-vx/internal/lib/auth" + // internal - domain - base-entities + ecore "simrs-vx/internal/domain/base-entities/core" + + // internal - domain - references erc "simrs-vx/internal/domain/references/common" - pa "simrs-vx/pkg/auth-helper" + // internal - domain - main-entities + ed "simrs-vx/internal/domain/main-entities/doctor" + ee "simrs-vx/internal/domain/main-entities/encounter" ) type CreateDto struct { diff --git a/internal/domain/main-entities/encounter/dto.go b/internal/domain/main-entities/encounter/dto.go index 4a30281d..89f12caf 100644 --- a/internal/domain/main-entities/encounter/dto.go +++ b/internal/domain/main-entities/encounter/dto.go @@ -1,9 +1,20 @@ package encounter import ( + // std "time" + // internal - lib + pa "simrs-vx/internal/lib/auth" + + // internal - domain - base-entities ecore "simrs-vx/internal/domain/base-entities/core" + + // internal - domain - references + erc "simrs-vx/internal/domain/references/common" + ere "simrs-vx/internal/domain/references/encounter" + + // internal - domain - main-entities evs "simrs-vx/internal/domain/bpjs-entities/vclaim-sep" ea "simrs-vx/internal/domain/main-entities/appointment" ed "simrs-vx/internal/domain/main-entities/doctor" @@ -13,11 +24,6 @@ import ( es "simrs-vx/internal/domain/main-entities/specialist" ess "simrs-vx/internal/domain/main-entities/subspecialist" eu "simrs-vx/internal/domain/main-entities/unit" - - erc "simrs-vx/internal/domain/references/common" - ere "simrs-vx/internal/domain/references/encounter" - - pa "simrs-vx/pkg/auth-helper" ) type CreateDto struct { @@ -40,6 +46,8 @@ type CreateDto struct { Responsible_Doctor_Id *uint `json:"responsible_doctor_id"` RefSource_Name *string `json:"refSource_name" validate:"maxLength=100"` Appointment_Id *uint `json:"appointment_id"` + RefTypeCode ere.RefTypeCode `json:"refTypeCode"` + NewStatus bool `json:"newStatus"` pa.AuthInfo } @@ -48,6 +56,8 @@ type ReadListDto struct { FilterDto Includes string `json:"includes"` Pagination ecore.Pagination + + pa.AuthInfo } type FilterDto struct { @@ -105,6 +115,14 @@ type DischargeDto struct { InternalReferences *[]eir.CreateDto `json:"internalReferences,omitempty"` } +type CheckinDto struct { + Id uint `json:"id"` + Responsible_Doctor_Id *uint `json:"responsible_doctor_id"` + Adm_Employee_Id *uint `json:"adm_employee_id"` + StartedAt *time.Time `json:"startedAt"` + FinishedAt *time.Time `json:"finishedAt"` +} + type ResponseDto struct { ecore.Main Patient_Id *uint `json:"patient_id"` diff --git a/internal/domain/main-entities/material-order/dto.go b/internal/domain/main-entities/material-order/dto.go index 5485d2dd..bd4f5c91 100644 --- a/internal/domain/main-entities/material-order/dto.go +++ b/internal/domain/main-entities/material-order/dto.go @@ -1,13 +1,18 @@ package materialorder import ( - ecore "simrs-vx/internal/domain/base-entities/core" - ed "simrs-vx/internal/domain/main-entities/doctor" - ee "simrs-vx/internal/domain/main-entities/encounter" + // internal - lib + pa "simrs-vx/internal/lib/auth" + // internal - domain - base-entities + ecore "simrs-vx/internal/domain/base-entities/core" + + // internal - domain - references erc "simrs-vx/internal/domain/references/common" - pa "simrs-vx/pkg/auth-helper" + // internal - domain - main-entities + ed "simrs-vx/internal/domain/main-entities/doctor" + ee "simrs-vx/internal/domain/main-entities/encounter" ) type CreateDto struct { diff --git a/internal/domain/main-entities/mcu-order-item/dto.go b/internal/domain/main-entities/mcu-order-item/dto.go index 64e56a85..75e02184 100644 --- a/internal/domain/main-entities/mcu-order-item/dto.go +++ b/internal/domain/main-entities/mcu-order-item/dto.go @@ -23,8 +23,8 @@ type ReadListDto struct { } type FilterDto struct { - McuOrder_Id *uint `json:"mcuOrder-id"` - McuSrc_Id *uint `json:"mcuSrc-id"` + McuOrder_Id *uint `json:"mcu-order-id"` + McuSrc_Id *uint `json:"mcu-src-id"` Result *string `json:"result"` Status_Code erc.DataStatusCode `json:"status-code"` } diff --git a/internal/domain/main-entities/mcu-order/dto.go b/internal/domain/main-entities/mcu-order/dto.go index caf3ef58..3d042c2f 100644 --- a/internal/domain/main-entities/mcu-order/dto.go +++ b/internal/domain/main-entities/mcu-order/dto.go @@ -1,26 +1,33 @@ package mcuorder import ( - ecore "simrs-vx/internal/domain/base-entities/core" - ed "simrs-vx/internal/domain/main-entities/doctor" - ee "simrs-vx/internal/domain/main-entities/encounter" + // std "time" + // internal - lib + pa "simrs-vx/internal/lib/auth" + + // internal - domain - base-entities + ecore "simrs-vx/internal/domain/base-entities/core" + + // internal - domain - references ercl "simrs-vx/internal/domain/references/clinical" erc "simrs-vx/internal/domain/references/common" - pa "simrs-vx/pkg/auth-helper" + // internal - domain - main-entities + ed "simrs-vx/internal/domain/main-entities/doctor" + ee "simrs-vx/internal/domain/main-entities/encounter" ) type CreateDto struct { - Encounter_Id *uint `json:"encounter_id"` - Status_Code erc.DataStatusCode `json:"status_code" gorm:"not null;size:10"` - Doctor_Id *uint `json:"doctor_id"` - SpecimenPickTime *time.Time `json:"specimenPickTime"` - ExaminationDate *time.Time `json:"examinationDate"` - Number uint8 `json:"number"` - Temperature float64 `json:"temperature"` - McuUrgencyLevel_Code ercl.McuUrgencyLevelCode `json:"mcuUrgencyLevel_code""` + Encounter_Id *uint `json:"encounter_id"` + Status_Code erc.DataStatusCode `json:"status_code" gorm:"not null;size:10"` + Doctor_Id *uint `json:"doctor_id"` + SpecimenPickTime *time.Time `json:"specimenPickTime"` + ExaminationDate *time.Time `json:"examinationDate"` + Number uint8 `json:"number"` + Temperature float64 `json:"temperature"` + UrgencyLevel_Code ercl.McuUrgencyLevelCode `json:"urgencyLevel_code"` pa.AuthInfo } @@ -32,17 +39,19 @@ type ReadListDto struct { } type FilterDto struct { - Encounter_Id *uint `json:"encounter-id"` - Status_Code erc.DataStatusCode `json:"status-code" gorm:"not null;size:10"` - Doctor_Id *uint `json:"doctor-id"` - SpecimenPickTime *time.Time `json:"specimenPickTime"` - ExaminationDate *time.Time `json:"examinationDate"` - Number uint8 `json:"number"` - Temperature float64 `json:"temperature"` - McuUrgencyLevel_Code ercl.McuUrgencyLevelCode `json:"mcuUrgencyLevel-code""` + Encounter_Id *uint `json:"encounter-id"` + Status_Code erc.DataStatusCode `json:"status-code" gorm:"not null;size:10"` + Doctor_Id *uint `json:"doctor-id"` + SpecimenPickTime *time.Time `json:"specimenPickTime"` + ExaminationDate *time.Time `json:"examinationDate"` + Number uint8 `json:"number"` + Temperature float64 `json:"temperature"` + UrgencyLevel_Code ercl.McuUrgencyLevelCode `json:"urgency-level-code"` + Scope_Code ercl.McuUrgencyLevelCode `json:"scope-code"` } type ReadDetailDto struct { - Id uint `json:"id"` + Id uint `json:"id"` + Includes string `json:"includes"` } type UpdateDto struct { @@ -66,30 +75,30 @@ type MetaDto struct { } type ResponseDto struct { ecore.Main - Encounter_Id *uint `json:"encounter_id"` - Encounter *ee.Encounter `json:"encounter,omitempty"` - Status_Code erc.DataStatusCode `json:"status_code" gorm:"not null;size:10"` - Doctor_Id *uint `json:"doctor_id"` - Doctor *ed.Doctor `json:"doctor,omitempty"` - SpecimenPickTime *time.Time `json:"specimenPickTime"` - ExaminationDate *time.Time `json:"examinationDate"` - Number uint8 `json:"number"` - Temperature float64 `json:"temperature"` - McuUrgencyLevel_Code ercl.McuUrgencyLevelCode `json:"mcuUrgencyLevel_code""` + Encounter_Id *uint `json:"encounter_id"` + Encounter *ee.Encounter `json:"encounter,omitempty"` + Status_Code erc.DataStatusCode `json:"status_code" gorm:"not null;size:10"` + Doctor_Id *uint `json:"doctor_id"` + Doctor *ed.Doctor `json:"doctor,omitempty"` + SpecimenPickTime *time.Time `json:"specimenPickTime"` + ExaminationDate *time.Time `json:"examinationDate"` + Number uint8 `json:"number"` + Temperature float64 `json:"temperature"` + UrgencyLevel_Code ercl.McuUrgencyLevelCode `json:"urgencyLevel_code""` } func (d McuOrder) ToResponse() ResponseDto { resp := ResponseDto{ - Encounter_Id: d.Encounter_Id, - Encounter: d.Encounter, - Status_Code: d.Status_Code, - Doctor_Id: d.Doctor_Id, - Doctor: d.Doctor, - SpecimenPickTime: d.SpecimenPickTime, - ExaminationDate: d.ExaminationDate, - Number: d.Number, - Temperature: d.Temperature, - McuUrgencyLevel_Code: d.McuUrgencyLevel_Code, + Encounter_Id: d.Encounter_Id, + Encounter: d.Encounter, + Status_Code: d.Status_Code, + Doctor_Id: d.Doctor_Id, + Doctor: d.Doctor, + SpecimenPickTime: d.SpecimenPickTime, + ExaminationDate: d.ExaminationDate, + Number: d.Number, + Temperature: d.Temperature, + UrgencyLevel_Code: d.UrgencyLevel_Code, } resp.Main = d.Main return resp diff --git a/internal/domain/main-entities/mcu-order/entity.go b/internal/domain/main-entities/mcu-order/entity.go index 1c72a2ba..d2b81e58 100644 --- a/internal/domain/main-entities/mcu-order/entity.go +++ b/internal/domain/main-entities/mcu-order/entity.go @@ -8,20 +8,22 @@ import ( ercl "simrs-vx/internal/domain/references/clinical" erc "simrs-vx/internal/domain/references/common" + ere "simrs-vx/internal/domain/references/encounter" ) type McuOrder struct { - ecore.Main // adjust this according to the needs - Encounter_Id *uint `json:"encounter_id"` - Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"` - Status_Code erc.DataStatusCode `json:"status_code" gorm:"not null;size:10"` - Doctor_Id *uint `json:"doctor_id"` - Doctor *ed.Doctor `json:"doctor,omitempty" gorm:"foreignKey:Doctor_Id;references:Id"` - SpecimenPickTime *time.Time `json:"specimenPickTime"` - ExaminationDate *time.Time `json:"examinationDate"` - Number uint8 `json:"number"` - Temperature float64 `json:"temperature"` - McuUrgencyLevel_Code ercl.McuUrgencyLevelCode `json:"mcuUrgencyLevel_code" gorm:"not null;size:15"` + ecore.Main // adjust this according to the needs + Encounter_Id *uint `json:"encounter_id"` + Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"` + Status_Code erc.DataStatusCode `json:"status_code" gorm:"not null;size:10"` + Doctor_Id *uint `json:"doctor_id"` + Doctor *ed.Doctor `json:"doctor,omitempty" gorm:"foreignKey:Doctor_Id;references:Id"` + SpecimenPickTime *time.Time `json:"specimenPickTime"` + ExaminationDate *time.Time `json:"examinationDate"` + Number uint8 `json:"number"` + Temperature float64 `json:"temperature"` + UrgencyLevel_Code ercl.McuUrgencyLevelCode `json:"urgencyLevel_code" gorm:"not null;size:15"` + Scope_Code *ere.CheckupScopeCode `json:"scope_code" gorm:"index;size:10"` } func (d McuOrder) IsCompleted() bool { diff --git a/internal/domain/main-entities/mcu-src-category/entity.go b/internal/domain/main-entities/mcu-src-category/entity.go index 21c266e3..3a0d08ca 100644 --- a/internal/domain/main-entities/mcu-src-category/entity.go +++ b/internal/domain/main-entities/mcu-src-category/entity.go @@ -9,5 +9,5 @@ type McuSrcCategory struct { ecore.SmallMain // adjust this according to the needs Code string `json:"code" gorm:"unique;size:20"` Name string `json:"name" gorm:"size:50"` - Scope_Code *ere.CheckupScopeCode `json:"scope_code" gorm:"size:10"` + Scope_Code *ere.CheckupScopeCode `json:"scope_code" gorm:"index;size:10"` } diff --git a/internal/domain/main-entities/mcu-src/dto.go b/internal/domain/main-entities/mcu-src/dto.go index 96586057..7ab13428 100644 --- a/internal/domain/main-entities/mcu-src/dto.go +++ b/internal/domain/main-entities/mcu-src/dto.go @@ -22,7 +22,7 @@ type ReadListDto struct { type FilterDto struct { Code string `json:"code"` Name string `json:"name"` - McuSrcCategory_Code *string `json:"mcuSrcCategory-code"` + McuSrcCategory_Code *string `json:"mcu-src-category-code"` Search string `json:"search" gormhelper:"searchColumns=Code,Name"` } diff --git a/internal/domain/main-entities/medication-item-dist/dto.go b/internal/domain/main-entities/medication-item-dist/dto.go index 9790895a..6936bdbc 100644 --- a/internal/domain/main-entities/medication-item-dist/dto.go +++ b/internal/domain/main-entities/medication-item-dist/dto.go @@ -1,12 +1,17 @@ package medicationitem import ( - ecore "simrs-vx/internal/domain/base-entities/core" - emi "simrs-vx/internal/domain/main-entities/medication-item" - - pa "simrs-vx/pkg/auth-helper" - + // std "time" + + // internal - lib + pa "simrs-vx/internal/lib/auth" + + // internal - domain - base-entities + ecore "simrs-vx/internal/domain/base-entities/core" + + // internal - domain - main-entities + emi "simrs-vx/internal/domain/main-entities/medication-item" ) type CreateDto struct { diff --git a/internal/domain/main-entities/medication/dto.go b/internal/domain/main-entities/medication/dto.go index c2cf9d14..928b926c 100644 --- a/internal/domain/main-entities/medication/dto.go +++ b/internal/domain/main-entities/medication/dto.go @@ -1,15 +1,21 @@ package medication import ( + // std "time" - ecore "simrs-vx/internal/domain/base-entities/core" - ee "simrs-vx/internal/domain/main-entities/encounter" - ep "simrs-vx/internal/domain/main-entities/pharmacist" + // internal - lib + pa "simrs-vx/internal/lib/auth" + // internal - domain - base-entities + ecore "simrs-vx/internal/domain/base-entities/core" + + // internal - domain - references erc "simrs-vx/internal/domain/references/common" - pa "simrs-vx/pkg/auth-helper" + // internal - domain - main-entities + ee "simrs-vx/internal/domain/main-entities/encounter" + ep "simrs-vx/internal/domain/main-entities/pharmacist" ) type CreateDto struct { diff --git a/internal/domain/main-entities/patient/dto.go b/internal/domain/main-entities/patient/dto.go index 4927a50e..1190ce22 100644 --- a/internal/domain/main-entities/patient/dto.go +++ b/internal/domain/main-entities/patient/dto.go @@ -13,18 +13,23 @@ import ( erc "simrs-vx/internal/domain/references/common" ere "simrs-vx/internal/domain/references/encounter" + + pa "simrs-vx/internal/lib/auth" ) type CreateDto struct { - Person_Id *uint `json:"-"` - Person *ep.UpdateDto `json:"person"` - NewBornStatus bool `json:"newBornStatus"` - PersonAddresses []epa.UpdateDto `json:"personAddresses"` - PersonContacts []epc.UpdateDto `json:"personContacts"` - PersonRelatives []epr.UpdateDto `json:"personRelatives"` - PersonInsurances []epi.UpdateDto `json:"personInsurances"` - RegisteredAt *time.Time `json:"registeredAt"` - Status_Code erc.ActiveStatusCode `json:"status_code" validate:"maxLength=10"` + Person_Id *uint `json:"-"` + Person *ep.UpdateDto `json:"person"` + NewBornStatus bool `json:"newBornStatus"` + PersonAddresses []epa.UpdateDto `json:"personAddresses"` + PersonContacts []epc.UpdateDto `json:"personContacts"` + PersonRelatives []epr.UpdateDto `json:"personRelatives"` + PersonInsurances []epi.UpdateDto `json:"personInsurances"` + RegisteredAt *time.Time `json:"registeredAt"` + RegisteredBy_User_Name *string `json:"registeredBy_user_name" validate:"maxLength=100"` + Status_Code erc.ActiveStatusCode `json:"status_code" validate:"maxLength=10"` + + pa.AuthInfo } type ReadListDto struct { diff --git a/internal/domain/main-entities/person/dto.go b/internal/domain/main-entities/person/dto.go index 7fb6a235..588379df 100644 --- a/internal/domain/main-entities/person/dto.go +++ b/internal/domain/main-entities/person/dto.go @@ -4,6 +4,7 @@ import ( "time" ecore "simrs-vx/internal/domain/base-entities/core" + evm "simrs-vx/internal/domain/bpjs-entities/vclaim-member" ee "simrs-vx/internal/domain/main-entities/ethnic" epa "simrs-vx/internal/domain/main-entities/person-address" epc "simrs-vx/internal/domain/main-entities/person-contact" @@ -14,24 +15,27 @@ import ( ) type CreateDto struct { - Name string `json:"name" validate:"maxLength=150"` - FrontTitle *string `json:"frontTitle" validate:"maxLength=50"` - EndTitle *string `json:"endTitle" validate:"maxLength=50"` - BirthDate *time.Time `json:"birthDate,omitempty"` - BirthRegency_Code *string `json:"birthRegency_code" validate:"maxLength=4"` - Gender_Code *erp.GenderCode `json:"gender_code"` - ResidentIdentityNumber *string `json:"residentIdentityNumber" validate:"nik;maxLength=16"` - PassportNumber *string `json:"passportNumber" validate:"maxLength=20"` - DrivingLicenseNumber *string `json:"drivingLicenseNumber" validate:"maxLength=20"` - Religion_Code *erp.ReligionCode `json:"religion_code" validate:"maxLength=10"` - Education_Code *erp.EducationCode `json:"education_code" validate:"maxLength=10"` - Ocupation_Code *erp.OcupationCode `json:"occupation_code" validate:"maxLength=15"` - Ocupation_Name *string `json:"occupation_name" validate:"maxLength=50"` - Nationality *string `json:"nationality" validate:"maxLength=50"` - Ethnic_Code *string `json:"ethnic_code" validate:"maxLength=20"` - Language_Code *string `json:"language_code" validate:"maxLength=10"` - CommunicationIssueStatus bool `json:"communicationIssueStatus"` - Disability *string `json:"disability" validate:"maxLength=100"` + Name string `json:"name" validate:"maxLength=150"` + FrontTitle *string `json:"frontTitle" validate:"maxLength=50"` + EndTitle *string `json:"endTitle" validate:"maxLength=50"` + BirthDate *time.Time `json:"birthDate,omitempty"` + BirthRegency_Code *string `json:"birthRegency_code" validate:"maxLength=4"` + Gender_Code *erp.GenderCode `json:"gender_code"` + ResidentIdentityNumber *string `json:"residentIdentityNumber" validate:"nik;maxLength=16"` + PassportNumber *string `json:"passportNumber" validate:"maxLength=20"` + DrivingLicenseNumber *string `json:"drivingLicenseNumber" validate:"maxLength=20"` + Religion_Code *erp.ReligionCode `json:"religion_code" validate:"maxLength=10"` + Education_Code *erp.EducationCode `json:"education_code" validate:"maxLength=10"` + Ocupation_Code *erp.OcupationCode `json:"occupation_code" validate:"maxLength=15"` + Ocupation_Name *string `json:"occupation_name" validate:"maxLength=50"` + MaritalStatus_Code *erp.MaritalStatusCode `json:"maritalStatus_code" validate:"maxLength=10"` + Confidence *string `json:"confidence" validate:"maxLength=512"` + Nationality *string `json:"nationality" validate:"maxLength=50"` + Ethnic_Code *string `json:"ethnic_code" validate:"maxLength=20"` + Language_Code *string `json:"language_code" validate:"maxLength=10"` + CommunicationIssueStatus bool `json:"communicationIssueStatus"` + Disability *string `json:"disability" validate:"maxLength=100"` + VclaimMember_CardNumber *string `json:"vclaimMember_cardNumber" validate:"maxLength=20"` } type ReadListDto struct { @@ -86,33 +90,36 @@ type MetaDto struct { type ResponseDto struct { ecore.Main - Name string `json:"name"` - FrontTitle *string `json:"frontTitle"` - EndTitle *string `json:"endTitle"` - BirthDate *time.Time `json:"birthDate,omitempty"` - BirthRegency_Code *string `json:"birthRegency_code"` - BirthRegency *er.Regency `json:"birthRegency,omitempty"` - Gender_Code *erp.GenderCode `json:"gender_code"` - ResidentIdentityNumber *string `json:"residentIdentityNumber"` - PassportNumber *string `json:"passportNumber"` - DrivingLicenseNumber *string `json:"drivingLicenseNumber"` - Religion_Code *erp.ReligionCode `json:"religion_code"` - Education_Code *erp.EducationCode `json:"education_code"` - Ocupation_Code *erp.OcupationCode `json:"occupation_code"` - Ocupation_Name *string `json:"occupation_name"` - Nationality *string `json:"nationality"` - Ethnic_Code *string `json:"ethnic_code"` - Ethnic *ee.Ethnic `json:"ethnic,omitempty"` - Addresses *[]epa.PersonAddress `json:"addresses,omitempty"` - Contacts *[]epc.PersonContact `json:"contacts,omitempty"` - Relatives *[]epr.PersonRelative `json:"relatives,omitempty"` - Language_Code *string `json:"language_code"` - CommunicationIssueStatus bool `json:"communicationIssueStatus"` - Disability *string `json:"disability"` - ResidentIdentityFileUrl *string `json:"residentIdentityFileUrl"` - PassportFileUrl *string `json:"passportFileUrl"` - DrivingLicenseFileUrl *string `json:"drivingLicenseFileUrl"` - FamilyIdentityFileUrl *string `json:"familyIdentityFileUrl"` + Name string `json:"name"` + FrontTitle *string `json:"frontTitle"` + EndTitle *string `json:"endTitle"` + BirthDate *time.Time `json:"birthDate,omitempty"` + BirthRegency_Code *string `json:"birthRegency_code"` + BirthRegency *er.Regency `json:"birthRegency,omitempty"` + Gender_Code *erp.GenderCode `json:"gender_code"` + ResidentIdentityNumber *string `json:"residentIdentityNumber"` + PassportNumber *string `json:"passportNumber"` + DrivingLicenseNumber *string `json:"drivingLicenseNumber"` + Religion_Code *erp.ReligionCode `json:"religion_code"` + Education_Code *erp.EducationCode `json:"education_code"` + Ocupation_Code *erp.OcupationCode `json:"occupation_code"` + Ocupation_Name *string `json:"occupation_name"` + MaritalStatus_Code *erp.MaritalStatusCode `json:"maritalStatus_code"` + Confidence *string `json:"confidence"` + Nationality *string `json:"nationality"` + Ethnic_Code *string `json:"ethnic_code"` + Ethnic *ee.Ethnic `json:"ethnic,omitempty"` + Addresses *[]epa.PersonAddress `json:"addresses,omitempty"` + Contacts *[]epc.PersonContact `json:"contacts,omitempty"` + Relatives *[]epr.PersonRelative `json:"relatives,omitempty"` + Language_Code *string `json:"language_code"` + CommunicationIssueStatus bool `json:"communicationIssueStatus"` + Disability *string `json:"disability"` + ResidentIdentityFileUrl *string `json:"residentIdentityFileUrl"` + PassportFileUrl *string `json:"passportFileUrl"` + DrivingLicenseFileUrl *string `json:"drivingLicenseFileUrl"` + FamilyIdentityFileUrl *string `json:"familyIdentityFileUrl"` + VclaimMember *evm.VclaimMember `json:"vclaimMember,omitempty"` } func (d *Person) ToResponse() ResponseDto { @@ -131,6 +138,8 @@ func (d *Person) ToResponse() ResponseDto { Education_Code: d.Education_Code, Ocupation_Code: d.Ocupation_Code, Ocupation_Name: d.Ocupation_Name, + MaritalStatus_Code: d.MaritalStatus_Code, + Confidence: d.Confidence, Nationality: d.Nationality, Ethnic_Code: d.Ethnic_Code, Ethnic: d.Ethnic, @@ -144,6 +153,7 @@ func (d *Person) ToResponse() ResponseDto { PassportFileUrl: d.PassportFileUrl, DrivingLicenseFileUrl: d.DrivingLicenseFileUrl, FamilyIdentityFileUrl: d.FamilyIdentityFileUrl, + VclaimMember: d.VclaimMember, } resp.Main = d.Main return resp diff --git a/internal/domain/main-entities/prescription/dto.go b/internal/domain/main-entities/prescription/dto.go index 431f1e2d..f0c6901e 100644 --- a/internal/domain/main-entities/prescription/dto.go +++ b/internal/domain/main-entities/prescription/dto.go @@ -7,6 +7,8 @@ import ( ed "simrs-vx/internal/domain/main-entities/doctor" ee "simrs-vx/internal/domain/main-entities/encounter" + pa "simrs-vx/internal/lib/auth" + erc "simrs-vx/internal/domain/references/common" ) @@ -15,6 +17,8 @@ type CreateDto struct { Doctor_Id *uint `json:"doctor_id"` IssuedAt *time.Time `json:"issuedAt"` Status_Code erc.DataStatusCode `json:"status_code"` + + pa.AuthInfo } type ReadListDto struct { @@ -30,8 +34,9 @@ type FilterDto struct { Status_Code *erc.DataStatusCode `json:"status-code"` } type ReadDetailDto struct { - Id uint `json:"id"` - Encounter_Id *uint `json:"encounter_id"` + Id uint `json:"id"` + Encounter_Id *uint `json:"encounter_id"` + Includes string `json:"includes"` } type UpdateDto struct { diff --git a/internal/domain/main-entities/responsible-doctor-hist/dto.go b/internal/domain/main-entities/responsible-doctor-hist/dto.go new file mode 100644 index 00000000..342faffa --- /dev/null +++ b/internal/domain/main-entities/responsible-doctor-hist/dto.go @@ -0,0 +1,78 @@ +package responsible_doctor_hist + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + ed "simrs-vx/internal/domain/main-entities/doctor" + "time" +) + +type CreateDto struct { + Encounter_Id *uint `json:"encounter_id"` + Doctor_Id *uint `json:"doctor_id"` + StartedAt *time.Time `json:"startedAt"` + FinishedAt *time.Time `json:"finishedAt"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Sort string `json:"sort"` + Pagination ecore.Pagination +} + +type FilterDto struct { + Encounter_Id *uint `json:"encounter-id"` + Doctor_Id *uint `json:"doctor-id"` + StartedAt *time.Time `json:"startedAt"` + FinishedAt *time.Time `json:"finishedAt"` +} + +type ReadDetailDto struct { + Id uint16 `json:"id"` + Code *string `json:"code"` + Includes string `json:"includes"` +} + +type UpdateDto struct { + Id uint16 `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint16 `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.Main // adjust this according to the needs + Encounter_Id *uint `json:"encounter_id"` + Doctor_Id *uint `json:"doctor_id"` + Doctor *ed.Doctor `json:"doctor,omitempty"` + StartedAt *time.Time `json:"startedAt"` + FinishedAt *time.Time `json:"finishedAt"` +} + +func (d ResponsibleDoctorHist) ToResponse() ResponseDto { + resp := ResponseDto{ + Encounter_Id: d.Encounter_Id, + Doctor_Id: d.Doctor_Id, + Doctor: d.Doctor, + StartedAt: d.StartedAt, + FinishedAt: d.FinishedAt, + } + resp.Main = d.Main + return resp +} + +func ToResponseList(data []ResponsibleDoctorHist) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/sbar/dto.go b/internal/domain/main-entities/sbar/dto.go index 46cf69a8..1664fb5f 100644 --- a/internal/domain/main-entities/sbar/dto.go +++ b/internal/domain/main-entities/sbar/dto.go @@ -1,13 +1,18 @@ package sbar import ( + // std "time" + // internal - lib + pa "simrs-vx/internal/lib/auth" + + // internal - domain - base-entities ecore "simrs-vx/internal/domain/base-entities/core" + + // internal - domain - main-entities eem "simrs-vx/internal/domain/main-entities/employee" ee "simrs-vx/internal/domain/main-entities/encounter" - - pa "simrs-vx/pkg/auth-helper" ) type CreateDto struct { diff --git a/internal/domain/main-entities/soapi/dto.go b/internal/domain/main-entities/soapi/dto.go index 418a7fb8..b8f1b827 100644 --- a/internal/domain/main-entities/soapi/dto.go +++ b/internal/domain/main-entities/soapi/dto.go @@ -9,7 +9,7 @@ import ( erc "simrs-vx/internal/domain/references/clinical" - pa "simrs-vx/pkg/auth-helper" + pa "simrs-vx/internal/lib/auth" ) type CreateDto struct { diff --git a/internal/domain/main-entities/specialist/dto.go b/internal/domain/main-entities/specialist/dto.go index 2cd4acee..8724b9c5 100644 --- a/internal/domain/main-entities/specialist/dto.go +++ b/internal/domain/main-entities/specialist/dto.go @@ -4,6 +4,7 @@ import ( ecore "simrs-vx/internal/domain/base-entities/core" espb "simrs-vx/internal/domain/main-entities/specialist-position/base" essb "simrs-vx/internal/domain/main-entities/subspecialist/base" + eu "simrs-vx/internal/domain/main-entities/unit" ) type CreateDto struct { @@ -52,6 +53,7 @@ type ResponseDto struct { Code string `json:"code"` Name string `json:"name"` Unit_Id *uint16 `json:"unit_id"` + Unit *eu.Unit `json:"unit,omitempty"` SpecialistPositions []espb.Basic `json:"specialistPositions,omitempty"` Subspecialists []essb.Basic `json:"subspecialists,omitempty"` } @@ -60,6 +62,7 @@ func (d Specialist) ToResponse() ResponseDto { resp := ResponseDto{ Code: d.Code, Name: d.Name, + Unit: d.Unit, Unit_Id: d.Unit_Id, SpecialistPositions: d.SpecialistPositions, Subspecialists: d.Subspecialists, diff --git a/internal/domain/main-entities/subspecialist/dto.go b/internal/domain/main-entities/subspecialist/dto.go index ed0c97aa..9a93394d 100644 --- a/internal/domain/main-entities/subspecialist/dto.go +++ b/internal/domain/main-entities/subspecialist/dto.go @@ -2,6 +2,7 @@ package subspecialist import ( ecore "simrs-vx/internal/domain/base-entities/core" + es "simrs-vx/internal/domain/main-entities/specialist" espb "simrs-vx/internal/domain/main-entities/subspecialist-position/base" ) @@ -48,10 +49,11 @@ type MetaDto struct { type ResponseDto struct { ecore.SmallMain - Code string `json:"code"` - Name string `json:"name"` - Specialist_Id *uint16 `json:"specialist_id"` - Subspecialist []espb.Basic `json:"subspecialistPositions,omitempty"` + Code string `json:"code"` + Name string `json:"name"` + Specialist_Id *uint16 `json:"specialist_id"` + Specialist *es.Specialist `json:"specialist,omitempty"` + Subspecialist []espb.Basic `json:"subspecialistPositions,omitempty"` } func (d Subspecialist) ToResponse() ResponseDto { @@ -59,6 +61,7 @@ func (d Subspecialist) ToResponse() ResponseDto { Code: d.Code, Name: d.Name, Specialist_Id: d.Specialist_Id, + Specialist: d.Specialist, Subspecialist: d.SubspecialistPositions, } resp.SmallMain = d.SmallMain diff --git a/internal/domain/main-entities/unit/dto.go b/internal/domain/main-entities/unit/dto.go index ce1dd505..e47afed9 100644 --- a/internal/domain/main-entities/unit/dto.go +++ b/internal/domain/main-entities/unit/dto.go @@ -50,11 +50,11 @@ type MetaDto struct { type ResponseDto struct { ecore.SmallMain - Installation_Id *uint16 `json:"installation_id"` - Installation *ei.Installation - Code string `json:"code"` - Name string `json:"name"` - UnitPositions []eipb.Basic `json:"unitPositions,omitempty"` + Installation_Id *uint16 `json:"installation_id"` + Installation *ei.Installation `json:"installation,omitempty"` + Code string `json:"code"` + Name string `json:"name"` + UnitPositions []eipb.Basic `json:"unitPositions,omitempty"` } func (d Unit) ToResponse() ResponseDto { diff --git a/internal/interface/main-handler/adime/handler.go b/internal/interface/main-handler/adime/handler.go index 9eabb0af..715f5faf 100644 --- a/internal/interface/main-handler/adime/handler.go +++ b/internal/interface/main-handler/adime/handler.go @@ -11,7 +11,7 @@ import ( e "simrs-vx/internal/domain/main-entities/adime" u "simrs-vx/internal/use-case/main-use-case/adime" - pa "simrs-vx/pkg/auth-helper" + pa "simrs-vx/internal/lib/auth" d "github.com/karincake/dodol" ) diff --git a/internal/interface/main-handler/adm-employee-hist/handler.go b/internal/interface/main-handler/adm-employee-hist/handler.go new file mode 100644 index 00000000..176d8a68 --- /dev/null +++ b/internal/interface/main-handler/adm-employee-hist/handler.go @@ -0,0 +1,71 @@ +package adm_employee_hist + +import ( + "net/http" + + rw "github.com/karincake/risoles" + sf "github.com/karincake/semprit" + + // ua "github.com/karincake/tumpeng/auth/svc" + + e "simrs-vx/internal/domain/main-entities/adm-employee-hist" + u "simrs-vx/internal/use-case/main-use-case/adm-employee-hist" +) + +type myBase struct{} + +var O myBase + +func (obj myBase) Create(w http.ResponseWriter, r *http.Request) { + dto := e.CreateDto{} + if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { + return + } + res, err := u.Create(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) GetList(w http.ResponseWriter, r *http.Request) { + dto := e.ReadListDto{} + sf.UrlQueryParam(&dto, *r.URL) + res, err := u.ReadList(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) { + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id <= 0 { + return + } + dto := e.ReadDetailDto{} + dto.Id = uint16(id) + res, err := u.ReadDetail(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) Update(w http.ResponseWriter, r *http.Request) { + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id <= 0 { + return + } + + dto := e.UpdateDto{} + if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { + return + } + dto.Id = uint16(id) + res, err := u.Update(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) { + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id <= 0 { + return + } + + dto := e.DeleteDto{} + dto.Id = uint16(id) + res, err := u.Delete(dto) + rw.DataResponse(w, res, err) +} diff --git a/internal/interface/main-handler/authentication/handler.go b/internal/interface/main-handler/authentication/handler.go index 01d4fb89..709f33a3 100644 --- a/internal/interface/main-handler/authentication/handler.go +++ b/internal/interface/main-handler/authentication/handler.go @@ -10,7 +10,7 @@ import ( m "simrs-vx/internal/domain/main-entities/user" s "simrs-vx/internal/use-case/main-use-case/authentication" - pa "simrs-vx/pkg/auth-helper" + pa "simrs-vx/internal/lib/auth" ) func Login(w http.ResponseWriter, r *http.Request) { diff --git a/internal/interface/main-handler/chemo/handler.go b/internal/interface/main-handler/chemo/handler.go index ee8c0435..90552020 100644 --- a/internal/interface/main-handler/chemo/handler.go +++ b/internal/interface/main-handler/chemo/handler.go @@ -14,7 +14,7 @@ import ( u "simrs-vx/internal/use-case/main-use-case/chemo" - pa "simrs-vx/pkg/auth-helper" + pa "simrs-vx/internal/lib/auth" d "github.com/karincake/dodol" ) diff --git a/internal/interface/main-handler/consultation/handler.go b/internal/interface/main-handler/consultation/handler.go index 2be1cbdd..2810d2f3 100644 --- a/internal/interface/main-handler/consultation/handler.go +++ b/internal/interface/main-handler/consultation/handler.go @@ -11,7 +11,7 @@ import ( e "simrs-vx/internal/domain/main-entities/consultation" u "simrs-vx/internal/use-case/main-use-case/consultation" - pa "simrs-vx/pkg/auth-helper" + pa "simrs-vx/internal/lib/auth" d "github.com/karincake/dodol" ) diff --git a/internal/interface/main-handler/device-order/handler.go b/internal/interface/main-handler/device-order/handler.go index 42135e58..12999301 100644 --- a/internal/interface/main-handler/device-order/handler.go +++ b/internal/interface/main-handler/device-order/handler.go @@ -9,7 +9,7 @@ import ( e "simrs-vx/internal/domain/main-entities/device-order" u "simrs-vx/internal/use-case/main-use-case/device-order" - pa "simrs-vx/pkg/auth-helper" + pa "simrs-vx/internal/lib/auth" d "github.com/karincake/dodol" ) diff --git a/internal/interface/main-handler/encounter/handler.go b/internal/interface/main-handler/encounter/handler.go index df3320ef..ed8b1fbc 100644 --- a/internal/interface/main-handler/encounter/handler.go +++ b/internal/interface/main-handler/encounter/handler.go @@ -12,7 +12,7 @@ import ( u "simrs-vx/internal/use-case/main-use-case/encounter" erc "simrs-vx/internal/domain/references/common" - pa "simrs-vx/pkg/auth-helper" + pa "simrs-vx/internal/lib/auth" d "github.com/karincake/dodol" ) @@ -36,7 +36,12 @@ func (obj myBase) Create(w http.ResponseWriter, r *http.Request) { } func (obj myBase) GetList(w http.ResponseWriter, r *http.Request) { + authInfo, err := pa.GetAuthInfo(r) + if err != nil { + rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil) + } dto := e.ReadListDto{} + dto.AuthInfo = *authInfo sf.UrlQueryParam(&dto, *r.URL) res, err := u.ReadList(dto) rw.DataResponse(w, res, err) @@ -102,6 +107,27 @@ func (obj myBase) CheckOut(w http.ResponseWriter, r *http.Request) { rw.DataResponse(w, res, err) } +func (obj myBase) CheckIn(w http.ResponseWriter, r *http.Request) { + dto := e.CheckinDto{} + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id <= 0 { + return + } + + if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { + return + } + + // validate request body + if valid := validateRequestCheckIn(w, dto); !valid { + return + } + + dto.Id = uint(id) + res, err := u.CheckIn(dto) + rw.DataResponse(w, res, err) +} + func (obj myBase) Process(w http.ResponseWriter, r *http.Request) { id := rw.ValidateInt(w, "id", r.PathValue("id")) if id <= 0 { diff --git a/internal/interface/main-handler/encounter/request-validation.go b/internal/interface/main-handler/encounter/request-validation.go index 182dd12e..025298fc 100644 --- a/internal/interface/main-handler/encounter/request-validation.go +++ b/internal/interface/main-handler/encounter/request-validation.go @@ -10,9 +10,9 @@ import ( rw "github.com/karincake/risoles" ) -func validateRequestCheckout(w http.ResponseWriter, i e.DischargeDto) (valid bool) { - const dataValidationFail = "" +const dataValidationFail = "data-validation-fail" +func validateRequestCheckout(w http.ResponseWriter, i e.DischargeDto) (valid bool) { switch *i.Discharge_Method_Code { case ere.DMCDeath: if i.DeathCause == nil { @@ -51,3 +51,15 @@ func validateRequestCheckout(w http.ResponseWriter, i e.DischargeDto) (valid boo } return true } + +func validateRequestCheckIn(w http.ResponseWriter, i e.CheckinDto) (valid bool) { + if i.Responsible_Doctor_Id == nil { + rw.DataResponse(w, nil, d.FieldError{ + Code: dataValidationFail, + Message: "responsible_doctor_id required", + }) + return + } + + return true +} diff --git a/internal/interface/main-handler/main-handler.go b/internal/interface/main-handler/main-handler.go index 6a98487f..bedf3b71 100644 --- a/internal/interface/main-handler/main-handler.go +++ b/internal/interface/main-handler/main-handler.go @@ -5,6 +5,7 @@ import ( /******************** main / transaction ********************/ adime "simrs-vx/internal/interface/main-handler/adime" + admemployeehist "simrs-vx/internal/interface/main-handler/adm-employee-hist" ambulancetransportrequest "simrs-vx/internal/interface/main-handler/ambulance-transport-req" auth "simrs-vx/internal/interface/main-handler/authentication" chemo "simrs-vx/internal/interface/main-handler/chemo" @@ -27,6 +28,7 @@ import ( practiceschedule "simrs-vx/internal/interface/main-handler/practice-schedule" prescription "simrs-vx/internal/interface/main-handler/prescription" prescriptionitem "simrs-vx/internal/interface/main-handler/prescription-item" + responsibledoctorhist "simrs-vx/internal/interface/main-handler/responsible-doctor-hist" sbar "simrs-vx/internal/interface/main-handler/sbar" soapi "simrs-vx/internal/interface/main-handler/soapi" @@ -48,6 +50,7 @@ import ( hk "github.com/karincake/hongkue" /******************** infra ********************/ + ibpjs "simrs-vx/internal/infra/bpjs" gs "simrs-vx/internal/infra/gorm-setting" minio "simrs-vx/internal/infra/minio" ssdb "simrs-vx/internal/infra/ss-db" @@ -116,6 +119,7 @@ func SetRoutes() http.Handler { a.RegisterExtCall(lh.Populate) a.RegisterExtCall(minio.Connect) a.RegisterExtCall(mh.I.SetClient) + a.RegisterExtCall(ibpjs.SetConfig) a.RegisterExtCall(validation.RegisterValidation) r := http.NewServeMux() @@ -135,6 +139,20 @@ func SetRoutes() http.Handler { hc.RegCrud(r, "/v1/prescription-item", prescriptionitem.O) hc.RegCrud(r, "/v1/device-order-item", deviceorderitem.O) hc.RegCrud(r, "/v1/material-order-item", materialorderitem.O) + + hk.GroupRoutes("/v1/encounter", r, auth.GuardMW, hk.MapHandlerFunc{ + "GET /": encounter.O.GetList, + "GET /{id}": encounter.O.GetDetail, + "POST /": encounter.O.Create, + "PATCH /{id}": encounter.O.Update, + "DELETE /{id}": encounter.O.Delete, + "PATCH /{id}/check-out": encounter.O.CheckOut, + "PATCH /{id}/check-in": encounter.O.CheckIn, + "PATCH /{id}/proccess": encounter.O.Process, + "PATCH /{id}/cancel": encounter.O.Cancel, + "PATCH /{id}/reject": encounter.O.Reject, + "PATCH /{id}/skip": encounter.O.Skip, + }) hk.GroupRoutes("/v1/mcu-order", r, auth.GuardMW, hk.MapHandlerFunc{ "GET /": mcuorder.O.GetList, "GET /{id}": mcuorder.O.GetDetail, @@ -153,7 +171,7 @@ func SetRoutes() http.Handler { "PATCH /{id}/complete": mcuorderitem.O.Complete, "PATCH /{id}/set-schedule": mcuorderitem.O.SetSchedule, }) - hk.GroupRoutes("/v1/prescription", r, hk.MapHandlerFunc{ + hk.GroupRoutes("/v1/prescription", r, auth.GuardMW, hk.MapHandlerFunc{ "GET /": prescription.O.GetList, "GET /{id}": prescription.O.GetDetail, "POST /": prescription.O.Create, @@ -161,7 +179,7 @@ func SetRoutes() http.Handler { "DELETE /{id}": prescription.O.Delete, "PATCH /{id}/approve": prescription.O.Approve, }) - hk.GroupRoutes("/v1/mcu-order-sub-item", r, hk.MapHandlerFunc{ + hk.GroupRoutes("/v1/mcu-order-sub-item", r, auth.GuardMW, hk.MapHandlerFunc{ "GET /": mcuordersubitem.O.GetList, "GET /{id}": mcuordersubitem.O.GetDetail, "POST /": mcuordersubitem.O.Create, @@ -169,18 +187,6 @@ func SetRoutes() http.Handler { "DELETE /{id}": mcuordersubitem.O.Delete, "PATCH /{id}/complete": mcuordersubitem.O.Complete, }) - hk.GroupRoutes("/v1/encounter", r, auth.GuardMW, hk.MapHandlerFunc{ - "GET /": encounter.O.GetList, - "GET /{id}": encounter.O.GetDetail, - "POST /": encounter.O.Create, - "PATCH /{id}": encounter.O.Update, - "DELETE /{id}": encounter.O.Delete, - "PATCH /{id}/checkout": encounter.O.CheckOut, - "PATCH /{id}/proccess": encounter.O.Process, - "PATCH /{id}/cancel": encounter.O.Cancel, - "PATCH /{id}/reject": encounter.O.Reject, - "PATCH /{id}/skip": encounter.O.Skip, - }) hk.GroupRoutes("/v1/medication", r, auth.GuardMW, hk.MapHandlerFunc{ "GET /": medication.O.GetList, "GET /{id}": medication.O.GetDetail, @@ -190,7 +196,7 @@ func SetRoutes() http.Handler { "PATCH /{id}/complete": medication.O.Complete, }) - hk.GroupRoutes("/v1/medication-item", r, hk.MapHandlerFunc{ + hk.GroupRoutes("/v1/medication-item", r, auth.GuardMW, hk.MapHandlerFunc{ "GET /": medicationitem.O.GetList, "GET /{id}": medicationitem.O.GetDetail, "POST /": medicationitem.O.Create, @@ -247,6 +253,8 @@ func SetRoutes() http.Handler { hc.RegCrud(r, "/v1/internal-reference", internalreference.O) hc.RegCrud(r, "/v1/ambulance-transport-req", ambulancetransportrequest.O) + hc.RegCrud(r, "/v1/responsible-doctor-hist", responsibledoctorhist.O) + hc.RegCrud(r, "/v1/adm-employee-hist", admemployeehist.O) /******************** actor ********************/ hc.RegCrud(r, "/v1/person", person.O) diff --git a/internal/interface/main-handler/material-order/handler.go b/internal/interface/main-handler/material-order/handler.go index ae8777cb..34c2b142 100644 --- a/internal/interface/main-handler/material-order/handler.go +++ b/internal/interface/main-handler/material-order/handler.go @@ -11,7 +11,7 @@ import ( e "simrs-vx/internal/domain/main-entities/material-order" u "simrs-vx/internal/use-case/main-use-case/material-order" - pa "simrs-vx/pkg/auth-helper" + pa "simrs-vx/internal/lib/auth" d "github.com/karincake/dodol" ) diff --git a/internal/interface/main-handler/mcu-order/handler.go b/internal/interface/main-handler/mcu-order/handler.go index bcd07a05..ac4aca9f 100644 --- a/internal/interface/main-handler/mcu-order/handler.go +++ b/internal/interface/main-handler/mcu-order/handler.go @@ -11,7 +11,7 @@ import ( e "simrs-vx/internal/domain/main-entities/mcu-order" u "simrs-vx/internal/use-case/main-use-case/mcu-order" - pa "simrs-vx/pkg/auth-helper" + pa "simrs-vx/internal/lib/auth" d "github.com/karincake/dodol" ) @@ -47,6 +47,7 @@ func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) { return } dto := e.ReadDetailDto{} + sf.UrlQueryParam(&dto, *r.URL) dto.Id = uint(id) res, err := u.ReadDetail(dto) rw.DataResponse(w, res, err) diff --git a/internal/interface/main-handler/medication-item-dist/handler.go b/internal/interface/main-handler/medication-item-dist/handler.go index 6c4b659f..9dd00d2b 100644 --- a/internal/interface/main-handler/medication-item-dist/handler.go +++ b/internal/interface/main-handler/medication-item-dist/handler.go @@ -6,7 +6,7 @@ import ( rw "github.com/karincake/risoles" sf "github.com/karincake/semprit" - pa "simrs-vx/pkg/auth-helper" + pa "simrs-vx/internal/lib/auth" e "simrs-vx/internal/domain/main-entities/medication-item-dist" u "simrs-vx/internal/use-case/main-use-case/medication-item-dist" diff --git a/internal/interface/main-handler/medication/handler.go b/internal/interface/main-handler/medication/handler.go index 272eae56..12fb6c84 100644 --- a/internal/interface/main-handler/medication/handler.go +++ b/internal/interface/main-handler/medication/handler.go @@ -6,7 +6,7 @@ import ( rw "github.com/karincake/risoles" sf "github.com/karincake/semprit" - pa "simrs-vx/pkg/auth-helper" + pa "simrs-vx/internal/lib/auth" e "simrs-vx/internal/domain/main-entities/medication" u "simrs-vx/internal/use-case/main-use-case/medication" diff --git a/internal/interface/main-handler/prescription/handler.go b/internal/interface/main-handler/prescription/handler.go index fe73e3fe..24d73372 100644 --- a/internal/interface/main-handler/prescription/handler.go +++ b/internal/interface/main-handler/prescription/handler.go @@ -7,6 +7,9 @@ import ( sf "github.com/karincake/semprit" // ua "github.com/karincake/tumpeng/auth/svc" + d "github.com/karincake/dodol" + + pa "simrs-vx/internal/lib/auth" e "simrs-vx/internal/domain/main-entities/prescription" u "simrs-vx/internal/use-case/main-use-case/prescription" @@ -21,6 +24,11 @@ func (obj myBase) Create(w http.ResponseWriter, r *http.Request) { if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { return } + authInfo, err := pa.GetAuthInfo(r) + if err != nil { + rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil) + } + dto.AuthInfo = *authInfo res, err := u.Create(dto) rw.DataResponse(w, res, err) } diff --git a/internal/interface/main-handler/responsible-doctor-hist/handler.go b/internal/interface/main-handler/responsible-doctor-hist/handler.go new file mode 100644 index 00000000..4b07df8a --- /dev/null +++ b/internal/interface/main-handler/responsible-doctor-hist/handler.go @@ -0,0 +1,71 @@ +package responsible_doctor_hist + +import ( + "net/http" + + rw "github.com/karincake/risoles" + sf "github.com/karincake/semprit" + + // ua "github.com/karincake/tumpeng/auth/svc" + + e "simrs-vx/internal/domain/main-entities/responsible-doctor-hist" + u "simrs-vx/internal/use-case/main-use-case/responsible-doctor-hist" +) + +type myBase struct{} + +var O myBase + +func (obj myBase) Create(w http.ResponseWriter, r *http.Request) { + dto := e.CreateDto{} + if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { + return + } + res, err := u.Create(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) GetList(w http.ResponseWriter, r *http.Request) { + dto := e.ReadListDto{} + sf.UrlQueryParam(&dto, *r.URL) + res, err := u.ReadList(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) { + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id <= 0 { + return + } + dto := e.ReadDetailDto{} + dto.Id = uint16(id) + res, err := u.ReadDetail(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) Update(w http.ResponseWriter, r *http.Request) { + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id <= 0 { + return + } + + dto := e.UpdateDto{} + if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { + return + } + dto.Id = uint16(id) + res, err := u.Update(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) { + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id <= 0 { + return + } + + dto := e.DeleteDto{} + dto.Id = uint16(id) + res, err := u.Delete(dto) + rw.DataResponse(w, res, err) +} diff --git a/internal/interface/main-handler/sbar/handler.go b/internal/interface/main-handler/sbar/handler.go index 7fac1e00..bcf63c8a 100644 --- a/internal/interface/main-handler/sbar/handler.go +++ b/internal/interface/main-handler/sbar/handler.go @@ -11,7 +11,7 @@ import ( e "simrs-vx/internal/domain/main-entities/sbar" u "simrs-vx/internal/use-case/main-use-case/sbar" - pa "simrs-vx/pkg/auth-helper" + pa "simrs-vx/internal/lib/auth" d "github.com/karincake/dodol" ) diff --git a/internal/interface/main-handler/soapi/handler.go b/internal/interface/main-handler/soapi/handler.go index f5446b82..fe50b7d2 100644 --- a/internal/interface/main-handler/soapi/handler.go +++ b/internal/interface/main-handler/soapi/handler.go @@ -11,7 +11,7 @@ import ( e "simrs-vx/internal/domain/main-entities/soapi" u "simrs-vx/internal/use-case/main-use-case/soapi" - pa "simrs-vx/pkg/auth-helper" + pa "simrs-vx/internal/lib/auth" d "github.com/karincake/dodol" ) diff --git a/internal/interface/migration/main-entities.go b/internal/interface/migration/main-entities.go index a46b27dd..fac22ea6 100644 --- a/internal/interface/migration/main-entities.go +++ b/internal/interface/migration/main-entities.go @@ -8,6 +8,7 @@ import ( appointment "simrs-vx/internal/domain/main-entities/appointment" chemo "simrs-vx/internal/domain/main-entities/chemo" consultation "simrs-vx/internal/domain/main-entities/consultation" + controlletter "simrs-vx/internal/domain/main-entities/control-letter" counter "simrs-vx/internal/domain/main-entities/counter" deathcause "simrs-vx/internal/domain/main-entities/death-cause" device "simrs-vx/internal/domain/main-entities/device" @@ -194,6 +195,7 @@ func getMainEntities() []any { &responsibledoctorhist.ResponsibleDoctorHist{}, &admemployeehist.AdmEmployeeHist{}, &vclaimmember.VclaimMember{}, + &controlletter.ControlLetter{}, &rehab.Rehab{}, } } diff --git a/internal/lib/.keep b/internal/lib/.keep new file mode 100644 index 00000000..e69de29b diff --git a/pkg/auth-helper/auth-helper.go b/internal/lib/auth/auth.go similarity index 93% rename from pkg/auth-helper/auth-helper.go rename to internal/lib/auth/auth.go index 934d8d61..3efa980f 100644 --- a/pkg/auth-helper/auth-helper.go +++ b/internal/lib/auth/auth.go @@ -1,4 +1,4 @@ -package authhelper +package auth import ( "errors" diff --git a/pkg/auth-helper/tycovar.go b/internal/lib/auth/tycovar.go similarity index 83% rename from pkg/auth-helper/tycovar.go rename to internal/lib/auth/tycovar.go index 06618350..881a9072 100644 --- a/pkg/auth-helper/tycovar.go +++ b/internal/lib/auth/tycovar.go @@ -1,4 +1,4 @@ -package authhelper +package auth import ( ero "simrs-vx/internal/domain/references/organization" @@ -6,16 +6,23 @@ import ( type AuthKey struct{} +// const AuthKey = struct{}{} type AuthInfo struct { Uuid string User_Id uint User_Name string User_ContractPosition_code string Employee_Position_Code *string + Employee_Id *int + Doctor_Id *int + Nurse_Id *int + Midwife_Id *int + Nutritionist_Id *int + Laborant_Id *int + Pharmachist_Id *int Intern_Position_Code *string - User_DivisionPositions []DivisionPosition - // User_DivisionPositions []DivisionPosition - // User_Position_Code string + Roles []string + // User_DivisionPositions []DivisionPosition } type DivisionPosition struct { diff --git a/internal/use-case/bpjs-use-case/vclaim-member/case.go b/internal/use-case/bpjs-use-case/vclaim-member/case.go new file mode 100644 index 00000000..14c6aaff --- /dev/null +++ b/internal/use-case/bpjs-use-case/vclaim-member/case.go @@ -0,0 +1,341 @@ +package vclaimmember + +import ( + "strconv" + + e "simrs-vx/internal/domain/bpjs-entities/vclaim-member" + // evsh "simrs-vx/internal/domain/bpjs-entities/vclaim-sep-hist" + + dg "github.com/karincake/apem/db-gorm-pg" + d "github.com/karincake/dodol" + + pl "simrs-vx/pkg/logger" + pu "simrs-vx/pkg/use-case-helper" + + "gorm.io/gorm" +) + +const source = "vclaim-member" + +func Create(input e.CreateDto) (*d.Data, error) { + data := e.VclaimMember{} + + event := pl.Event{ + Feature: "Create", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "create") + + err := dg.I.Transaction(func(tx *gorm.DB) error { + mwRunner := newMiddlewareRunner(&event, tx) + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil { + return err + } + + if resData, err := CreateData(input, &event, tx); err != nil { + return err + } else { + data = *resData + } + + mwRunner.setMwType(pu.MWTPost) + // Run post-middleware + if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil { + return err + } + + pl.SetLogInfo(&event, nil, "complete") + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.II{ + "source": source, + "structure": "single-data", + "status": "created", + }, + Data: data.ToResponse(), + }, nil +} + +func ReadList(input e.ReadListDto) (*d.Data, error) { + var data *e.VclaimMember + var dataList []e.VclaimMember + var metaList *e.MetaDto + var err error + + event := pl.Event{ + Feature: "ReadList", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "readList") + + err = dg.I.Transaction(func(tx *gorm.DB) error { + mwRunner := newMiddlewareRunner(&event, tx) + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunReadListMiddleware(readListPreMw, &input, data); err != nil { + return err + } + + if dataList, metaList, err = ReadListData(input, &event, tx); err != nil { + return err + } + + mwRunner.setMwType(pu.MWTPost) + // Run post-middleware + if err := mwRunner.RunReadListMiddleware(readListPostMw, &input, data); err != nil { + return err + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "list-data", + "status": "fetched", + "page_number": strconv.Itoa(metaList.PageNumber), + "page_size": strconv.Itoa(metaList.PageSize), + "record_totalCount": strconv.Itoa(metaList.Count), + "record_currentCount": strconv.Itoa(len(dataList)), + }, + Data: e.ToResponseList(dataList), + }, nil +} + +func ReadDetail(input e.ReadDetailDto) (*d.Data, error) { + var data *e.VclaimMember + var err error + + event := pl.Event{ + Feature: "ReadDetail", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "readDetail") + + err = dg.I.Transaction(func(tx *gorm.DB) error { + mwRunner := newMiddlewareRunner(&event, tx) + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunReadDetailMiddleware(readDetailPreMw, &input, data); err != nil { + return err + } + + if data, err = ReadDetailData(input, &event, tx); err != nil { + return err + } + + mwRunner.setMwType(pu.MWTPost) + // Run post-middleware + if err := mwRunner.RunReadDetailMiddleware(readDetailPostMw, &input, data); err != nil { + return err + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "single-data", + "status": "fetched", + }, + Data: data.ToResponse(), + }, nil +} + +func Update(input e.UpdateDto) (*d.Data, error) { + rdDto := e.ReadDetailDto{CardNumber: input.CardNumber} + var data *e.VclaimMember + var err error + + event := pl.Event{ + Feature: "Update", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "update") + + err = dg.I.Transaction(func(tx *gorm.DB) error { + pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail") + if data, err = ReadDetailData(rdDto, &event, tx); err != nil { + return err + } + + mwRunner := newMiddlewareRunner(&event, tx) + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunUpdateMiddleware(readDetailPreMw, &rdDto, data); err != nil { + return err + } + + if err := UpdateData(input, data, &event, tx); err != nil { + return err + } + + pl.SetLogInfo(&event, nil, "complete") + + mwRunner.setMwType(pu.MWTPost) + // Run post-middleware + if err := mwRunner.RunUpdateMiddleware(readDetailPostMw, &rdDto, data); err != nil { + return err + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "single-data", + "status": "updated", + }, + Data: data.ToResponse(), + }, nil + +} + +func Delete(input e.DeleteDto) (*d.Data, error) { + rdDto := e.ReadDetailDto{CardNumber: input.CardNumber} + var data *e.VclaimMember + var err error + + event := pl.Event{ + Feature: "Delete", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "delete") + + err = dg.I.Transaction(func(tx *gorm.DB) error { + pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail") + if data, err = ReadDetailData(rdDto, &event, tx); err != nil { + return err + } + + mwRunner := newMiddlewareRunner(&event, tx) + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunDeleteMiddleware(readDetailPreMw, &rdDto, data); err != nil { + return err + } + + if err := DeleteData(data, &event, tx); err != nil { + return err + } + + mwRunner.setMwType(pu.MWTPost) + // Run post-middleware + if err := mwRunner.RunDeleteMiddleware(readDetailPostMw, &rdDto, data); err != nil { + return err + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "single-data", + "status": "deleted", + }, + Data: data.ToResponse(), + }, nil + +} + +// func CreateOrUpdate(input e.CreateDto) (*d.Data, error) { +// rdDto := e.ReadDetailDto{CardNumber: input.CardNumber} +// var data *e.VclaimMember +// var err error + +// event := pl.Event{ +// Feature: "CreateOrUpdate", +// Source: source, +// } + +// // Start log +// pl.SetLogInfo(&event, input, "started", "createOrUpdate") + +// err = dg.I.Transaction(func(tx *gorm.DB) error { +// pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail") +// if data, err = ReadDetailData(rdDto, &event, tx); err != nil { +// return err +// } + +// mwRunner := newMiddlewareRunner(&event, tx) +// mwRunner.setMwType(pu.MWTPre) +// // Run pre-middleware +// if err := mwRunner.RunCreateMiddleware(createPreMw, &input, data); err != nil { +// return err +// } + +// if data.Person_Id == input.Person_Id { +// return nil +// } +// if err := UpdateData(e.UpdateDto{CreateDto: input}, data, &event, tx); err != nil { +// return err +// } + +// // if err := CreateOrUpdateData(input, data, &event, tx); err != nil { +// // return err +// // } + +// pl.SetLogInfo(&event, nil, "complete") + +// mwRunner.setMwType(pu.MWTPost) +// // Run post-middleware +// if err := mwRunner.RunCreateMiddleware(createPostMw, &input, data); err != nil { +// return err +// } + +// return nil +// }) + +// if err != nil { +// return nil, err +// } + +// return &d.Data{ +// Meta: d.II{ +// "source": source, +// "structure": "single-data", +// "status": "created", +// }, +// Data: data.ToResponse(), +// }, nil + +// } diff --git a/internal/use-case/bpjs-use-case/vclaim-member/helper.go b/internal/use-case/bpjs-use-case/vclaim-member/helper.go new file mode 100644 index 00000000..c2789e58 --- /dev/null +++ b/internal/use-case/bpjs-use-case/vclaim-member/helper.go @@ -0,0 +1,22 @@ +/* +DESCRIPTION: +Any functions that are used internally by the use-case +*/ +package vclaimmember + +import ( + e "simrs-vx/internal/domain/bpjs-entities/vclaim-member" +) + +func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.VclaimMember) { + var inputSrc *e.CreateDto + if inputT, ok := any(input).(*e.CreateDto); ok { + inputSrc = inputT + } else { + inputTemp := any(input).(*e.UpdateDto) + inputSrc = &inputTemp.CreateDto + } + + data.CardNumber = inputSrc.CardNumber + data.Person_Id = inputSrc.Person_Id +} diff --git a/internal/use-case/bpjs-use-case/vclaim-member/lib.go b/internal/use-case/bpjs-use-case/vclaim-member/lib.go new file mode 100644 index 00000000..3c477298 --- /dev/null +++ b/internal/use-case/bpjs-use-case/vclaim-member/lib.go @@ -0,0 +1,179 @@ +package vclaimmember + +import ( + e "simrs-vx/internal/domain/bpjs-entities/vclaim-member" + + plh "simrs-vx/pkg/lib-helper" + pl "simrs-vx/pkg/logger" + pu "simrs-vx/pkg/use-case-helper" + + dg "github.com/karincake/apem/db-gorm-pg" + gh "github.com/karincake/getuk" + "gorm.io/gorm" +) + +func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.VclaimMember, error) { + pl.SetLogInfo(event, nil, "started", "DBCreate") + + data := e.VclaimMember{} + setData(&input, &data) + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Create(&data).Error; err != nil { + return nil, plh.HandleCreateError(input, event, err) + } + + pl.SetLogInfo(event, nil, "complete") + return &data, nil +} + +func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.VclaimMember, *e.MetaDto, error) { + pl.SetLogInfo(event, input, "started", "DBReadList") + data := []e.VclaimMember{} + pagination := gh.Pagination{} + count := int64(0) + meta := e.MetaDto{} + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + tx = tx. + Model(&e.VclaimMember{}). + Scopes(gh.Preload(input.Includes)). + Scopes(gh.Filter(input.FilterDto)). + Count(&count). + Scopes(gh.Paginate(input, &pagination)). + Scopes(gh.Sort(input.Sort)) + + if err := tx.Find(&data).Error; err != nil { + if err == gorm.ErrRecordNotFound { + return nil, &meta, nil + } + return nil, nil, plh.HandleListError(input, event, err) + } + + meta.Count = int(count) + meta.PageNumber = pagination.PageNumber + meta.PageSize = pagination.PageSize + + pl.SetLogInfo(event, nil, "complete") + return data, &meta, nil +} + +func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.VclaimMember, error) { + pl.SetLogInfo(event, input, "started", "DBReadDetail") + data := e.VclaimMember{} + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if input.CardNumber != nil { + tx = tx.Where("\"CardNumber\" = ?", *input.CardNumber) + } + if input.Id != 0 { + tx = tx.Where("\"Id\" = ?", input.Id) + } + + if err := tx.First(&data).Error; err != nil { + if processedErr := pu.HandleReadError(err, event, source, input.Id, data); processedErr != nil { + return nil, processedErr + } + } + + pl.SetLogInfo(event, nil, "complete") + return &data, nil +} + +func UpdateData(input e.UpdateDto, data *e.VclaimMember, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, data, "started", "DBUpdate") + setData(&input, data) + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Save(&data).Error; err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-update-fail", + Detail: "Database update failed", + Raw: err, + } + return pl.SetLogError(event, input) + } + + pl.SetLogInfo(event, nil, "complete") + return nil +} + +func DeleteData(data *e.VclaimMember, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, data, "started", "DBDelete") + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Delete(&data).Error; err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-delete-fail", + Detail: "Database delete failed", + Raw: err, + } + return pl.SetLogError(event, data) + } + + pl.SetLogInfo(event, nil, "complete") + return nil +} + +func CreateOrUpdateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, nil, "started", "createOrUpdateData") + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + data, err := ReadDetailData(e.ReadDetailDto{CardNumber: input.CardNumber}, event, tx) + if err != nil { + if !pu.IsDataNotFoundError(err) { + return err + } + } + + if data == nil { + if _, err := CreateData(input, event, tx); err != nil { + return err + } + } else { + if err := UpdateData(e.UpdateDto{CreateDto: input}, data, event, tx); err != nil { + return err + } + } + + pl.SetLogInfo(event, nil, "complete") + return nil + +} diff --git a/internal/use-case/bpjs-use-case/vclaim-member/middleware-runner.go b/internal/use-case/bpjs-use-case/vclaim-member/middleware-runner.go new file mode 100644 index 00000000..452a06e0 --- /dev/null +++ b/internal/use-case/bpjs-use-case/vclaim-member/middleware-runner.go @@ -0,0 +1,103 @@ +package vclaimmember + +import ( + e "simrs-vx/internal/domain/bpjs-entities/vclaim-member" + pl "simrs-vx/pkg/logger" + pu "simrs-vx/pkg/use-case-helper" + + "gorm.io/gorm" +) + +type middlewareRunner struct { + Event *pl.Event + Tx *gorm.DB + MwType pu.MWType +} + +// NewMiddlewareExecutor creates a new middleware executor +func newMiddlewareRunner(event *pl.Event, tx *gorm.DB) *middlewareRunner { + return &middlewareRunner{ + Event: event, + Tx: tx, + } +} + +// ExecuteCreateMiddleware executes create middleware +func (me *middlewareRunner) RunCreateMiddleware(middlewares []createMw, input *e.CreateDto, data *e.VclaimMember) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) RunReadListMiddleware(middlewares []readListMw, input *e.ReadListDto, data *e.VclaimMember) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) RunReadDetailMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.VclaimMember) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) RunUpdateMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.VclaimMember) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) RunDeleteMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.VclaimMember) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) setMwType(mwType pu.MWType) { + me.MwType = mwType +} diff --git a/internal/use-case/bpjs-use-case/vclaim-member/middleware.go b/internal/use-case/bpjs-use-case/vclaim-member/middleware.go new file mode 100644 index 00000000..56404d79 --- /dev/null +++ b/internal/use-case/bpjs-use-case/vclaim-member/middleware.go @@ -0,0 +1,13 @@ +package vclaimmember + +// import ( +// pvs "simrs-vx/internal/use-case/bpjs-plugin/vclaim-member" +// ) + +// // example of middleware +// func init() { +// createPreMw = append(createPreMw, +// createMw{Name: "create-sep", Func: pvs.CreateSep}, +// ) + +// } diff --git a/internal/use-case/bpjs-use-case/vclaim-member/tycovar.go b/internal/use-case/bpjs-use-case/vclaim-member/tycovar.go new file mode 100644 index 00000000..dafb1227 --- /dev/null +++ b/internal/use-case/bpjs-use-case/vclaim-member/tycovar.go @@ -0,0 +1,44 @@ +/* +DESCRIPTION: +A sample, part of the package that contains type, constants, and/or variables. + +In this sample it also provides type and variable regarding the needs of the +middleware to separate from main use-case which has the basic CRUD +functionality. The purpose of this is to make the code more maintainable. +*/ +package vclaimmember + +import ( + "gorm.io/gorm" + + e "simrs-vx/internal/domain/bpjs-entities/vclaim-member" +) + +type createMw struct { + Name string + Func func(input *e.CreateDto, data *e.VclaimMember, tx *gorm.DB) error +} + +type readListMw struct { + Name string + Func func(input *e.ReadListDto, data *e.VclaimMember, tx *gorm.DB) error +} + +type readDetailMw struct { + Name string + Func func(input *e.ReadDetailDto, data *e.VclaimMember, tx *gorm.DB) error +} + +type UpdateMw = readDetailMw +type DeleteMw = readDetailMw + +var createPreMw []createMw // preprocess middleware +var createPostMw []createMw // postprocess middleware +var readListPreMw []readListMw // .. +var readListPostMw []readListMw // .. +var readDetailPreMw []readDetailMw +var readDetailPostMw []readDetailMw +var updatePreMw []readDetailMw +var updatePostMw []readDetailMw +var deletePreMw []readDetailMw +var deletePostMw []readDetailMw diff --git a/internal/use-case/main-use-case/adime/case.go b/internal/use-case/main-use-case/adime/case.go index 01d101ae..bc7d4e98 100644 --- a/internal/use-case/main-use-case/adime/case.go +++ b/internal/use-case/main-use-case/adime/case.go @@ -5,9 +5,6 @@ import ( "strconv" e "simrs-vx/internal/domain/main-entities/adime" - ee "simrs-vx/internal/domain/main-entities/employee" - - ue "simrs-vx/internal/use-case/main-use-case/employee" dg "github.com/karincake/apem/db-gorm-pg" d "github.com/karincake/dodol" @@ -49,11 +46,13 @@ func Create(input e.CreateDto) (*d.Data, error) { return pl.SetLogError(&event, input) } - employee, err := ue.ReadDetailData(ee.ReadDetailDto{User_Id: &input.AuthInfo.User_Id}, &event, tx) - if err != nil { - return err + if input.AuthInfo.Employee_Id != nil { + v := uint(*input.AuthInfo.Employee_Id) + input.Employee_Id = &v + } else { + input.Employee_Id = nil } - input.Employee_Id = &employee.Id + if resData, err := CreateData(input, &event, tx); err != nil { return err } else { diff --git a/internal/use-case/main-use-case/adm-employee-hist/case.go b/internal/use-case/main-use-case/adm-employee-hist/case.go new file mode 100644 index 00000000..51851584 --- /dev/null +++ b/internal/use-case/main-use-case/adm-employee-hist/case.go @@ -0,0 +1,276 @@ +package adm_employee_hist + +import ( + e "simrs-vx/internal/domain/main-entities/adm-employee-hist" + "strconv" + + dg "github.com/karincake/apem/db-gorm-pg" + d "github.com/karincake/dodol" + + pl "simrs-vx/pkg/logger" + pu "simrs-vx/pkg/use-case-helper" + + "gorm.io/gorm" +) + +const source = "adm-employee-hist" + +func Create(input e.CreateDto) (*d.Data, error) { + data := e.AdmEmployeeHist{} + + event := pl.Event{ + Feature: "Create", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "create") + + err := dg.I.Transaction(func(tx *gorm.DB) error { + mwRunner := newMiddlewareRunner(&event, tx) + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil { + return err + } + + if resData, err := CreateData(input, &event, tx); err != nil { + return err + } else { + data = *resData + } + + mwRunner.setMwType(pu.MWTPost) + // Run post-middleware + if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil { + return err + } + + pl.SetLogInfo(&event, nil, "complete") + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.II{ + "source": source, + "structure": "single-data", + "status": "created", + }, + Data: data.ToResponse(), + }, nil +} + +func ReadList(input e.ReadListDto) (*d.Data, error) { + var data *e.AdmEmployeeHist + var dataList []e.AdmEmployeeHist + var metaList *e.MetaDto + var err error + + event := pl.Event{ + Feature: "ReadList", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "readList") + + err = dg.I.Transaction(func(tx *gorm.DB) error { + mwRunner := newMiddlewareRunner(&event, tx) + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunReadListMiddleware(readListPreMw, &input, data); err != nil { + return err + } + + if dataList, metaList, err = ReadListData(input, &event, tx); err != nil { + return err + } + + mwRunner.setMwType(pu.MWTPost) + // Run post-middleware + if err := mwRunner.RunReadListMiddleware(readListPostMw, &input, data); err != nil { + return err + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "list-data", + "status": "fetched", + "page_number": strconv.Itoa(metaList.PageNumber), + "page_size": strconv.Itoa(metaList.PageSize), + "record_totalCount": strconv.Itoa(metaList.Count), + "record_currentCount": strconv.Itoa(len(dataList)), + }, + Data: e.ToResponseList(dataList), + }, nil +} + +func ReadDetail(input e.ReadDetailDto) (*d.Data, error) { + var data *e.AdmEmployeeHist + var err error + + event := pl.Event{ + Feature: "ReadDetail", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "readDetail") + + err = dg.I.Transaction(func(tx *gorm.DB) error { + mwRunner := newMiddlewareRunner(&event, tx) + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunReadDetailMiddleware(readDetailPreMw, &input, data); err != nil { + return err + } + + if data, err = ReadDetailData(input, &event, tx); err != nil { + return err + } + + mwRunner.setMwType(pu.MWTPost) + // Run post-middleware + if err := mwRunner.RunReadDetailMiddleware(readDetailPostMw, &input, data); err != nil { + return err + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "single-data", + "status": "fetched", + }, + Data: data.ToResponse(), + }, nil +} + +func Update(input e.UpdateDto) (*d.Data, error) { + rdDto := e.ReadDetailDto{Id: input.Id} + var data *e.AdmEmployeeHist + var err error + + event := pl.Event{ + Feature: "Update", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "update") + + err = dg.I.Transaction(func(tx *gorm.DB) error { + pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail") + if data, err = ReadDetailData(rdDto, &event, tx); err != nil { + return err + } + + mwRunner := newMiddlewareRunner(&event, tx) + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunUpdateMiddleware(readDetailPreMw, &rdDto, data); err != nil { + return err + } + + if err := UpdateData(input, data, &event, tx); err != nil { + return err + } + + pl.SetLogInfo(&event, nil, "complete") + + mwRunner.setMwType(pu.MWTPost) + // Run post-middleware + if err := mwRunner.RunUpdateMiddleware(readDetailPostMw, &rdDto, data); err != nil { + return err + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "single-data", + "status": "updated", + }, + Data: data.ToResponse(), + }, nil + +} + +func Delete(input e.DeleteDto) (*d.Data, error) { + rdDto := e.ReadDetailDto{Id: input.Id} + var data *e.AdmEmployeeHist + var err error + + event := pl.Event{ + Feature: "Delete", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "delete") + + err = dg.I.Transaction(func(tx *gorm.DB) error { + pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail") + if data, err = ReadDetailData(rdDto, &event, tx); err != nil { + return err + } + + mwRunner := newMiddlewareRunner(&event, tx) + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunDeleteMiddleware(readDetailPreMw, &rdDto, data); err != nil { + return err + } + + if err := DeleteData(data, &event, tx); err != nil { + return err + } + + mwRunner.setMwType(pu.MWTPost) + // Run post-middleware + if err := mwRunner.RunDeleteMiddleware(readDetailPostMw, &rdDto, data); err != nil { + return err + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "single-data", + "status": "deleted", + }, + Data: data.ToResponse(), + }, nil + +} diff --git a/internal/use-case/main-use-case/adm-employee-hist/helper.go b/internal/use-case/main-use-case/adm-employee-hist/helper.go new file mode 100644 index 00000000..19363f0e --- /dev/null +++ b/internal/use-case/main-use-case/adm-employee-hist/helper.go @@ -0,0 +1,24 @@ +/* +DESCRIPTION: +Any functions that are used internally by the use-case +*/ +package adm_employee_hist + +import ( + e "simrs-vx/internal/domain/main-entities/adm-employee-hist" +) + +func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.AdmEmployeeHist) { + var inputSrc *e.CreateDto + if inputT, ok := any(input).(*e.CreateDto); ok { + inputSrc = inputT + } else { + inputTemp := any(input).(*e.UpdateDto) + inputSrc = &inputTemp.CreateDto + } + + data.Encounter_Id = inputSrc.Encounter_Id + data.Employee_Id = inputSrc.Employee_Id + data.StartedAt = inputSrc.StartedAt + data.FinishedAt = inputSrc.FinishedAt +} diff --git a/internal/use-case/main-use-case/adm-employee-hist/lib.go b/internal/use-case/main-use-case/adm-employee-hist/lib.go new file mode 100644 index 00000000..dc03b28a --- /dev/null +++ b/internal/use-case/main-use-case/adm-employee-hist/lib.go @@ -0,0 +1,156 @@ +package adm_employee_hist + +import ( + "errors" + e "simrs-vx/internal/domain/main-entities/adm-employee-hist" + + plh "simrs-vx/pkg/lib-helper" + pl "simrs-vx/pkg/logger" + pu "simrs-vx/pkg/use-case-helper" + + dg "github.com/karincake/apem/db-gorm-pg" + gh "github.com/karincake/getuk" + "gorm.io/gorm" +) + +func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.AdmEmployeeHist, error) { + pl.SetLogInfo(event, nil, "started", "DBCreate") + + data := e.AdmEmployeeHist{} + setData(&input, &data) + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Create(&data).Error; err != nil { + return nil, plh.HandleCreateError(input, event, err) + } + + pl.SetLogInfo(event, nil, "complete") + return &data, nil +} + +func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.AdmEmployeeHist, *e.MetaDto, error) { + pl.SetLogInfo(event, input, "started", "DBReadList") + data := []e.AdmEmployeeHist{} + pagination := gh.Pagination{} + count := int64(0) + meta := e.MetaDto{} + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + tx = tx. + Model(&e.AdmEmployeeHist{}). + Scopes(gh.Preload(input.Includes)). + Scopes(gh.Filter(input.FilterDto)). + Count(&count). + Scopes(gh.Paginate(input, &pagination)). + Scopes(gh.Sort(input.Sort)) + + if err := tx.Find(&data).Error; err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, &meta, nil + } + return nil, nil, plh.HandleListError(input, event, err) + } + + meta.Count = int(count) + meta.PageNumber = pagination.PageNumber + meta.PageSize = pagination.PageSize + + pl.SetLogInfo(event, nil, "complete") + return data, &meta, nil +} + +func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.AdmEmployeeHist, error) { + pl.SetLogInfo(event, input, "started", "DBReadDetail") + data := e.AdmEmployeeHist{} + + var tx, getData *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + switch { + case input.Id != 0: + getData = tx.First(&data, input.Id) + case input.Code != nil && *input.Code != "": + getData = tx.Where("code = ?", *input.Code).First(&data) + default: + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-read-detail-fail", + Detail: "either Id or Code must be provided", + } + + return nil, pl.SetLogError(event, nil) + } + + if err := getData.Error; err != nil { + if processedErr := pu.HandleReadError(err, event, source, input.Id, data); processedErr != nil { + return nil, processedErr + } + } + + pl.SetLogInfo(event, nil, "complete") + return &data, nil +} + +func UpdateData(input e.UpdateDto, data *e.AdmEmployeeHist, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, data, "started", "DBUpdate") + setData(&input, data) + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Save(&data).Error; err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-update-fail", + Detail: "Database update failed", + Raw: err, + } + return pl.SetLogError(event, input) + } + + pl.SetLogInfo(event, nil, "complete") + return nil +} + +func DeleteData(data *e.AdmEmployeeHist, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, data, "started", "DBDelete") + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Delete(&data).Error; err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-delete-fail", + Detail: "Database delete failed", + Raw: err, + } + return pl.SetLogError(event, data) + } + + pl.SetLogInfo(event, nil, "complete") + return nil +} diff --git a/internal/use-case/main-use-case/adm-employee-hist/middleware-runner.go b/internal/use-case/main-use-case/adm-employee-hist/middleware-runner.go new file mode 100644 index 00000000..45f736b5 --- /dev/null +++ b/internal/use-case/main-use-case/adm-employee-hist/middleware-runner.go @@ -0,0 +1,103 @@ +package adm_employee_hist + +import ( + e "simrs-vx/internal/domain/main-entities/adm-employee-hist" + pl "simrs-vx/pkg/logger" + pu "simrs-vx/pkg/use-case-helper" + + "gorm.io/gorm" +) + +type middlewareRunner struct { + Event *pl.Event + Tx *gorm.DB + MwType pu.MWType +} + +// NewMiddlewareExecutor creates a new middleware executor +func newMiddlewareRunner(event *pl.Event, tx *gorm.DB) *middlewareRunner { + return &middlewareRunner{ + Event: event, + Tx: tx, + } +} + +// ExecuteCreateMiddleware executes create middleware +func (me *middlewareRunner) RunCreateMiddleware(middlewares []createMw, input *e.CreateDto, data *e.AdmEmployeeHist) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) RunReadListMiddleware(middlewares []readListMw, input *e.ReadListDto, data *e.AdmEmployeeHist) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) RunReadDetailMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.AdmEmployeeHist) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) RunUpdateMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.AdmEmployeeHist) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) RunDeleteMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.AdmEmployeeHist) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) setMwType(mwType pu.MWType) { + me.MwType = mwType +} diff --git a/internal/use-case/main-use-case/adm-employee-hist/middleware.go b/internal/use-case/main-use-case/adm-employee-hist/middleware.go new file mode 100644 index 00000000..ad6ae298 --- /dev/null +++ b/internal/use-case/main-use-case/adm-employee-hist/middleware.go @@ -0,0 +1,9 @@ +package adm_employee_hist + +// example of middleware +// func init() { +// createPreMw = append(createPreMw, +// CreateMw{Name: "modif-input", Func: pm.ModifInput}, +// CreateMw{Name: "check-data", Func: pm.CheckData}, +// ) +// } diff --git a/internal/use-case/main-use-case/adm-employee-hist/tycovar.go b/internal/use-case/main-use-case/adm-employee-hist/tycovar.go new file mode 100644 index 00000000..0827026d --- /dev/null +++ b/internal/use-case/main-use-case/adm-employee-hist/tycovar.go @@ -0,0 +1,44 @@ +/* +DESCRIPTION: +A sample, part of the package that contains type, constants, and/or variables. + +In this sample it also provides type and variable regarding the needs of the +middleware to separate from main use-case which has the basic CRUD +functionality. The purpose of this is to make the code more maintainable. +*/ +package adm_employee_hist + +import ( + "gorm.io/gorm" + + e "simrs-vx/internal/domain/main-entities/adm-employee-hist" +) + +type createMw struct { + Name string + Func func(input *e.CreateDto, data *e.AdmEmployeeHist, tx *gorm.DB) error +} + +type readListMw struct { + Name string + Func func(input *e.ReadListDto, data *e.AdmEmployeeHist, tx *gorm.DB) error +} + +type readDetailMw struct { + Name string + Func func(input *e.ReadDetailDto, data *e.AdmEmployeeHist, tx *gorm.DB) error +} + +type UpdateMw = readDetailMw +type DeleteMw = readDetailMw + +var createPreMw []createMw // preprocess middleware +var createPostMw []createMw // postprocess middleware +var readListPreMw []readListMw // .. +var readListPostMw []readListMw // .. +var readDetailPreMw []readDetailMw +var readDetailPostMw []readDetailMw +var updatePreMw []readDetailMw +var updatePostMw []readDetailMw +var deletePreMw []readDetailMw +var deletePostMw []readDetailMw diff --git a/internal/use-case/main-use-case/authentication/case.go b/internal/use-case/main-use-case/authentication/case.go index 5b9952a3..6c645208 100644 --- a/internal/use-case/main-use-case/authentication/case.go +++ b/internal/use-case/main-use-case/authentication/case.go @@ -13,12 +13,13 @@ import ( "simrs-vx/internal/domain/main-entities/intern" eu "simrs-vx/internal/domain/main-entities/user" - pa "simrs-vx/pkg/auth-helper" + pa "simrs-vx/internal/lib/auth" el "simrs-vx/pkg/logger" p "simrs-vx/pkg/password" ed "simrs-vx/internal/domain/main-entities/doctor" ee "simrs-vx/internal/domain/main-entities/employee" + em "simrs-vx/internal/domain/main-entities/midwife" en "simrs-vx/internal/domain/main-entities/nurse" erc "simrs-vx/internal/domain/references/common" erg "simrs-vx/internal/domain/references/organization" @@ -127,6 +128,7 @@ func GenToken(input eu.LoginDto) (*d.Data, error) { // employee position if employee.Id > 0 && employee.Position_Code != nil { + atClaims["employee_position_code"] = *employee.Position_Code switch *employee.Position_Code { case erg.EPCDoc: doctor := ed.Doctor{} @@ -147,13 +149,21 @@ func GenToken(input eu.LoginDto) (*d.Data, error) { outputData["subspecialist_id"] = doctor.Subspecialist_Id } case erg.EPCNur: - nurse := en.Nurse{} - dg.I.Where("\"Employee_Id\" = ?", employee.Id).First(&nurse) - if nurse.Id == 0 { + empData := en.Nurse{} + dg.I.Where("\"Employee_Id\" = ?", employee.Id).First(&empData) + if empData.Id == 0 { return nil, d.FieldErrors{"authentication": d.FieldError{Code: "auth-noNurse", Message: el.GenMessage("auth-noNurse")}} } - atClaims["nurse_id"] = nurse.Id - outputData["nurse_id"] = nurse.Id + atClaims["nurse_id"] = empData.Id + outputData["nurse_id"] = empData.Id + case erg.EPCMwi: + empData := em.Midwife{} + dg.I.Where("\"Employee_Id\" = ?", employee.Id).First(&empData) + if empData.Id == 0 { + return nil, d.FieldErrors{"authentication": d.FieldError{Code: "auth-noNurse", Message: el.GenMessage("auth-noNurse")}} + } + atClaims["nurse_id"] = empData.Id + outputData["nurse_id"] = empData.Id } errorGetPosition := d.FieldErrors{"authentication": d.FieldError{Code: "auth-getData-failed", Message: el.GenMessage("auth-getData-failed")}} @@ -200,6 +210,8 @@ func GenToken(input eu.LoginDto) (*d.Data, error) { intern := intern.Intern{} dg.I.Where("\"User_Id\" = ?", user.Id).First(&intern) role = append(role, "int-"+string(*intern.Position_Code)) + case erg.CSCSys: + role = append(role, "system") } atClaims["roles"] = role outputData["roles"] = role @@ -287,43 +299,23 @@ func ExtractToken(r *http.Request, tokenType TokenType) (data *pa.AuthInfo, err if accessUuidRedis.String() == "" { return nil, d.FieldError{Code: "token-unidentified", Message: el.GenMessage("token-unidentified")} } - user_name := fmt.Sprintf("%v", claims["user_name"]) - // user_email := "" - // if v, exist := claims["user_email"]; exist && v != nil { - // user_email = v.(string) - // } - // ref_id := 0 - // if v, exist := claims["user_ref_id"]; exist && v != nil { - // tmp := v.(float64) - // ref_id = int(tmp) - // } - // position_code := "" - // if v, exist := claims["user_position_code"]; exist && v != nil { - // position_code = v.(string) - // } - // data = &AuthInfo{ - // Uuid: accessUuid, - // User_Id: int(user_id), - // User_Name: user_name, - // User_Email: user_email, - // User_Ref_Id: ref_id, - // User_Position_Code: position_code, - contractPosition_code := "" - if v, exist := claims["contractPosition_code"]; exist && v != nil { - contractPosition_code = v.(string) - } - employee_position_code := "" - if v, exist := claims["employee_position_code"]; exist && v != nil { - employee_position_code = v.(string) - } data = &pa.AuthInfo{ - Uuid: accessUuid, - User_Id: uint(user_id), - User_Name: user_name, - User_ContractPosition_code: contractPosition_code, - Employee_Position_Code: &employee_position_code, + Uuid: accessUuid, + User_Id: uint(user_id), + User_Name: fmt.Sprintf("%v", claims["user_name"]), } + + data.User_ContractPosition_code = checkStrClaims(claims, "contractPosition_code") + data.Employee_Position_Code = checkStrPtrClaims(claims, "employee_position_code") + data.Doctor_Id = checkIntPtrClaims(claims, "doctor_id") + data.Nurse_Id = checkIntPtrClaims(claims, "nurse_id") + data.Midwife_Id = checkIntPtrClaims(claims, "midwife_id") + data.Nutritionist_Id = checkIntPtrClaims(claims, "nutritionist_id") + data.Laborant_Id = checkIntPtrClaims(claims, "laborant_id") + data.Pharmachist_Id = checkIntPtrClaims(claims, "pharmachist_id") + data.Intern_Position_Code = checkStrPtrClaims(claims, "intern_position_code") + data.Employee_Id = checkIntPtrClaims(claims, "employee_id") return } return nil, d.FieldError{Code: "token", Message: "token-invalid"} @@ -332,3 +324,33 @@ func ExtractToken(r *http.Request, tokenType TokenType) (data *pa.AuthInfo, err func GetConfig() { a.ParseCfg(&authCfg) } + +func checkStrClaims(claim map[string]interface{}, key string) string { + if v, exist := claim[key]; exist && v != nil { + return v.(string) + } + return "" +} + +func checkStrPtrClaims(claim map[string]interface{}, key string) *string { + if v, exist := claim[key]; exist && v != nil { + val := v.(string) + return &val + } + return nil +} + +func checkIntClaims(claim map[string]interface{}, key string) int { + if v, exist := claim[key]; exist && v != nil { + return v.(int) + } + return 0 +} + +func checkIntPtrClaims(claim map[string]interface{}, key string) *int { + if v, exist := claim[key]; exist && v != nil { + val := int(v.(float64)) + return &val + } + return nil +} diff --git a/internal/use-case/main-use-case/authentication/helper.go b/internal/use-case/main-use-case/authentication/helper.go index 87473386..bec64518 100644 --- a/internal/use-case/main-use-case/authentication/helper.go +++ b/internal/use-case/main-use-case/authentication/helper.go @@ -28,10 +28,6 @@ func getAndCheck(input, condition any) (eCode string) { return "" } -func getDocName(id uint) string { - return "authentication" -} - func getDivisionPosition(employee_id uint) ([]string, error) { var result []string diff --git a/internal/use-case/main-use-case/encounter/case.go b/internal/use-case/main-use-case/encounter/case.go index 04eedfff..11b17e2b 100644 --- a/internal/use-case/main-use-case/encounter/case.go +++ b/internal/use-case/main-use-case/encounter/case.go @@ -2,37 +2,48 @@ package encounter import ( "errors" + authhelper "simrs-vx/internal/lib/auth" "strconv" + "time" - ea "simrs-vx/internal/domain/main-entities/ambulatory" - ec "simrs-vx/internal/domain/main-entities/chemo" - edc "simrs-vx/internal/domain/main-entities/death-cause" - ee "simrs-vx/internal/domain/main-entities/emergency" - eem "simrs-vx/internal/domain/main-entities/employee" - e "simrs-vx/internal/domain/main-entities/encounter" - ei "simrs-vx/internal/domain/main-entities/inpatient" - - ua "simrs-vx/internal/use-case/main-use-case/ambulatory" - uc "simrs-vx/internal/use-case/main-use-case/chemo" - udc "simrs-vx/internal/use-case/main-use-case/death-cause" - ue "simrs-vx/internal/use-case/main-use-case/emergency" - uem "simrs-vx/internal/use-case/main-use-case/employee" - ui "simrs-vx/internal/use-case/main-use-case/inpatient" - - erc "simrs-vx/internal/domain/references/common" - ere "simrs-vx/internal/domain/references/encounter" + dg "github.com/karincake/apem/db-gorm-pg" + d "github.com/karincake/dodol" + "gorm.io/gorm" pl "simrs-vx/pkg/logger" pu "simrs-vx/pkg/use-case-helper" - dg "github.com/karincake/apem/db-gorm-pg" - d "github.com/karincake/dodol" + erc "simrs-vx/internal/domain/references/common" + ere "simrs-vx/internal/domain/references/encounter" - "gorm.io/gorm" + eaeh "simrs-vx/internal/domain/main-entities/adm-employee-hist" + ea "simrs-vx/internal/domain/main-entities/ambulatory" + ec "simrs-vx/internal/domain/main-entities/chemo" + edc "simrs-vx/internal/domain/main-entities/death-cause" + ed "simrs-vx/internal/domain/main-entities/doctor" + ee "simrs-vx/internal/domain/main-entities/emergency" + eem "simrs-vx/internal/domain/main-entities/employee" + e "simrs-vx/internal/domain/main-entities/encounter" + ei "simrs-vx/internal/domain/main-entities/inpatient" + erdh "simrs-vx/internal/domain/main-entities/responsible-doctor-hist" + es "simrs-vx/internal/domain/main-entities/soapi" + + uaeh "simrs-vx/internal/use-case/main-use-case/adm-employee-hist" + ua "simrs-vx/internal/use-case/main-use-case/ambulatory" + uc "simrs-vx/internal/use-case/main-use-case/chemo" + udc "simrs-vx/internal/use-case/main-use-case/death-cause" + ud "simrs-vx/internal/use-case/main-use-case/doctor" + ue "simrs-vx/internal/use-case/main-use-case/emergency" + uem "simrs-vx/internal/use-case/main-use-case/employee" + ui "simrs-vx/internal/use-case/main-use-case/inpatient" + urdh "simrs-vx/internal/use-case/main-use-case/responsible-doctor-hist" + us "simrs-vx/internal/use-case/main-use-case/soapi" ) const source = "encounter" +var now = time.Now() + func Create(input e.CreateDto) (*d.Data, error) { data := e.Encounter{} @@ -44,7 +55,21 @@ func Create(input e.CreateDto) (*d.Data, error) { // Start log pl.SetLogInfo(&event, input, "started", "create") - err := dg.I.Transaction(func(tx *gorm.DB) error { + // check if patient is new in the hospital + dataPatient, err := ReadList(e.ReadListDto{ + FilterDto: e.FilterDto{Patient_Id: input.Patient_Id}, + AuthInfo: authhelper.AuthInfo{User_Id: input.User_Id}}) + if err != nil { + return nil, err + } + + if list, ok := dataPatient.Data.([]e.ResponseDto); ok { + if len(list) < 1 { + input.NewStatus = true + } + } + + err = dg.I.Transaction(func(tx *gorm.DB) error { mwRunner := newMiddlewareRunner(&event, tx) mwRunner.setMwType(pu.MWTPre) // Run pre-middleware @@ -122,6 +147,15 @@ func Create(input e.CreateDto) (*d.Data, error) { return errors.New("invalid encounter class code") } + // insert adm_employee_hist + if _, err := uaeh.Create(eaeh.CreateDto{ + Encounter_Id: &data.Main.Id, + Employee_Id: data.Adm_Employee_Id, + StartedAt: &now, + }); err != nil { + return err + } + mwRunner.setMwType(pu.MWTPost) // Run post-middleware if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil { @@ -414,6 +448,16 @@ func CheckOut(input e.DischargeDto) (*d.Data, error) { } } + // update finishedAt in latest responsible_doctor_hist + if err = updateLatestResponsibleDoctorHist(e.CheckinDto{Id: input.Id, StartedAt: &now}, &event, tx); err != nil { + return err + } + + // update finishedAt in latest adm_employee_hist + if err = updateLatestAdmEmployeeHist(e.CheckinDto{Id: input.Id, StartedAt: &now}, &event, tx); err != nil { + return err + } + switch *input.Discharge_Method_Code { case ere.DMCDeath: // insert data death-cause @@ -511,3 +555,136 @@ func UpdateStatusCode(input e.UpdateStatusDto) (*d.Data, error) { }, nil } + +func CheckIn(input e.CheckinDto) (*d.Data, error) { + rdDto := e.ReadDetailDto{Id: uint16(input.Id)} + var data *e.Encounter + var err error + + event := pl.Event{ + Feature: "CheckIn", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "checkIn") + + // validate foreign key + if err := validateForeignKey(input); err != nil { + return nil, err + } + + // set startedAt + if input.StartedAt == nil { + input.StartedAt = &now + } + + // validate if soapi exist + dataSoapi, err := us.ReadList(es.ReadListDto{FilterDto: es.FilterDto{Encounter_Id: &input.Id}}) + if err != nil { + return nil, err + } + + if list, ok := dataSoapi.Data.([]es.ResponseDto); ok { + if len(list) > 0 { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-state-mismatch", + Detail: "soapi already exist", + Raw: errors.New("soapi already exist"), + } + return nil, pl.SetLogError(&event, input) + } + } + + err = dg.I.Transaction(func(tx *gorm.DB) error { + pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail") + if data, err = ReadDetailData(rdDto, &event, tx); err != nil { + return err + } + + if data.IsDone() { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-state-mismatch", + Detail: "encounter is done", + Raw: errors.New("encounter is done"), + } + return pl.SetLogError(&event, input) + } + + // Insert responsible_doctor_hist if responsible_doctor_id has changed && update latest history + if data.Responsible_Doctor_Id == nil || *input.Responsible_Doctor_Id != *data.Responsible_Doctor_Id { + // update finishedAt in latest responsible_doctor_hist + if err = updateLatestResponsibleDoctorHist(input, &event, tx); err != nil { + return err + } + + //insert responsible_doctor_hist + if _, err = urdh.Create(erdh.CreateDto{ + Encounter_Id: &input.Id, + Doctor_Id: input.Responsible_Doctor_Id, + StartedAt: input.StartedAt, + }); err != nil { + return err + } + } + + // Insert adm_employee_hist if adm_employee_id has changed && update latest history + if input.Adm_Employee_Id != nil && *input.Adm_Employee_Id != *data.Adm_Employee_Id { + // update finishedAt in latest adm_employee_hist + if err = updateLatestAdmEmployeeHist(input, &event, tx); err != nil { + return err + } + + // insert responsible_doctor_hist + if _, err = uaeh.Create(eaeh.CreateDto{ + Encounter_Id: &input.Id, + Employee_Id: input.Adm_Employee_Id, + StartedAt: input.StartedAt, + }); err != nil { + return err + } + } + + // update encounter data + if err := updateCheckInData(input, data, &event, tx); err != nil { + return err + } + + pl.SetLogInfo(&event, nil, "complete") + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "single-data", + "status": "checkIn", + }, + Data: data.ToResponse(), + }, nil +} + +func validateForeignKey(input e.CheckinDto) error { + // validate employee_Id + if input.Adm_Employee_Id != nil { + if _, err := uem.ReadDetail(eem.ReadDetailDto{Id: uint16(*input.Adm_Employee_Id)}); err != nil { + return err + } + } + + // validate doctor_id + if input.Responsible_Doctor_Id != nil { + if _, err := ud.ReadDetail(ed.ReadDetailDto{Id: uint16(*input.Responsible_Doctor_Id)}); err != nil { + return err + } + } + + return nil +} diff --git a/internal/use-case/main-use-case/encounter/helper.go b/internal/use-case/main-use-case/encounter/helper.go index 41fd6a51..c5eb155e 100644 --- a/internal/use-case/main-use-case/encounter/helper.go +++ b/internal/use-case/main-use-case/encounter/helper.go @@ -69,6 +69,8 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Encounter) { data.RefSource_Name = inputSrc.RefSource_Name data.Appointment_Id = inputSrc.Appointment_Id data.Status_Code = erc.DSCProcess + data.RefType_Code = &inputSrc.RefTypeCode + data.NewStatus = inputSrc.NewStatus } func setDataUpdate(src e.UpdateDto, dst *e.Encounter) { @@ -90,6 +92,7 @@ func setDataDischarge(src e.DischargeDto, dst *e.Encounter) { now := time.Now() dst.Discharge_Date = &now + dst.FinishedAt = &now } func checkSoapiByDocExists(encounter_id uint, event *pl.Event, tx *gorm.DB) error { @@ -327,6 +330,15 @@ func setDataUpdateStatus(src e.UpdateStatusDto, dst *e.Encounter) { dst.Status_Code = src.StatusCode } +func setDataCheckIn(src e.CheckinDto, dst *e.Encounter) { + if src.Adm_Employee_Id != nil { + dst.Adm_Employee_Id = src.Adm_Employee_Id + } + + dst.Responsible_Doctor_Id = src.Responsible_Doctor_Id + dst.StartedAt = src.StartedAt +} + func createInternalReferences(input e.DischargeDto, event *pl.Event, tx *gorm.DB) error { unitIDs := make(map[uint16]struct{}) doctorIDs := make(map[uint]struct{}) diff --git a/internal/use-case/main-use-case/encounter/lib.go b/internal/use-case/main-use-case/encounter/lib.go index ccc4b811..3327bcfa 100644 --- a/internal/use-case/main-use-case/encounter/lib.go +++ b/internal/use-case/main-use-case/encounter/lib.go @@ -1,15 +1,22 @@ package encounter import ( - e "simrs-vx/internal/domain/main-entities/encounter" + // std + "errors" + // external + dg "github.com/karincake/apem/db-gorm-pg" + gh "github.com/karincake/getuk" + "gorm.io/gorm" + // pkg plh "simrs-vx/pkg/lib-helper" pl "simrs-vx/pkg/logger" pu "simrs-vx/pkg/use-case-helper" - dg "github.com/karincake/apem/db-gorm-pg" - gh "github.com/karincake/getuk" - "gorm.io/gorm" + // internal + eaeh "simrs-vx/internal/domain/main-entities/adm-employee-hist" + e "simrs-vx/internal/domain/main-entities/encounter" + erdh "simrs-vx/internal/domain/main-entities/responsible-doctor-hist" ) func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Encounter, error) { @@ -34,6 +41,10 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Encount } func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Encounter, *e.MetaDto, error) { + if input.AuthInfo.User_Id == 0 { + return nil, nil, plh.HandleListError(input, event, errors.New("user_id is required")) + } + pl.SetLogInfo(event, input, "started", "DBReadList") data := []e.Encounter{} pagination := gh.Pagination{} @@ -46,10 +57,13 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.En } else { tx = dg.I } + tx = tx.Model(&e.Encounter{}) - tx = tx. - Model(&e.Encounter{}). - Scopes(gh.Preload(input.Includes)). + if input.AuthInfo.Doctor_Id != nil { + tx.Where("\"Responsible_Doctor_Id\" = ?", *input.AuthInfo.Doctor_Id) + } + + tx.Scopes(gh.Preload(input.Includes)). Scopes(gh.Filter(input.FilterDto)). Count(&count). Scopes(gh.Paginate(input, &pagination)). @@ -212,3 +226,110 @@ func UpdateStatusData(input e.UpdateStatusDto, data *e.Encounter, event *pl.Even pl.SetLogInfo(event, nil, "complete") return nil } + +func updateCheckInData(input e.CheckinDto, data *e.Encounter, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, data, "started", "DBUpdate") + setDataCheckIn(input, data) + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Save(&data).Error; err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-update-fail", + Detail: "Database update failed", + Raw: err, + } + return pl.SetLogError(event, input) + } + + pl.SetLogInfo(event, nil, "complete") + return nil +} + +func updateLatestResponsibleDoctorHist(input e.CheckinDto, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, "started", "DBUpdate") + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + subQuery := tx. + Select("\"Id\""). + Model(&erdh.ResponsibleDoctorHist{}). + Where("\"Encounter_Id\" = ?", input.Id). + Order("\"CreatedAt\" DESC"). + Limit(1) + + result := tx. + Model(&erdh.ResponsibleDoctorHist{}). + Where("\"Id\" = (?)", subQuery). + Update("\"FinishedAt\"", input.StartedAt) + + if result.Error != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-update-fail", + Detail: "Database update failed", + Raw: result.Error, + } + return pl.SetLogError(event, input) + } + + if result.RowsAffected == 0 { + pl.SetLogInfo(event, input, "no previous data found to update") + return nil + } + + pl.SetLogInfo(event, nil, "complete") + return nil +} + +func updateLatestAdmEmployeeHist(input e.CheckinDto, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, "started", "DBUpdate") + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + subQuery := tx. + Select("\"Id\""). + Model(&eaeh.AdmEmployeeHist{}). + Where("\"Encounter_Id\" = ?", input.Id). + Order("\"CreatedAt\" DESC"). + Limit(1) + + result := tx. + Model(&eaeh.AdmEmployeeHist{}). + Where("\"Id\" = (?)", subQuery). + Update("\"FinishedAt\"", input.StartedAt) + + if result.Error != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-update-fail", + Detail: "Database update failed", + Raw: result.Error, + } + return pl.SetLogError(event, input) + } + + if result.RowsAffected == 0 { + pl.SetLogInfo(event, input, "no previous data found to update") + return nil + } + + pl.SetLogInfo(event, nil, "complete") + return nil +} diff --git a/internal/use-case/main-use-case/mcu-order-item/lib.go b/internal/use-case/main-use-case/mcu-order-item/lib.go index e53f1c2f..4b5bb04f 100644 --- a/internal/use-case/main-use-case/mcu-order-item/lib.go +++ b/internal/use-case/main-use-case/mcu-order-item/lib.go @@ -15,9 +15,6 @@ import ( func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.McuOrderItem, error) { pl.SetLogInfo(event, nil, "started", "DBCreate") - data := e.McuOrderItem{} - setData(&input, &data) - var tx *gorm.DB if len(dbx) > 0 { tx = dbx[0] @@ -25,6 +22,20 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.McuOrde tx = dg.I } + deletedData := e.McuOrderItem{} + tx.Unscoped(). + Where("\"McuOrder_Id\" = ? AND \"McuSrc_Id\" = ?", *input.McuOrder_Id, input.McuSrc_Id). + First(&deletedData) + if deletedData.Id != 0 { + if err := tx.Unscoped().Model(e.McuOrderItem{}).Where("\"Id\" = ?", deletedData.Id).Update("\"DeletedAt\"", nil).Error; err != nil { + return nil, plh.HandleCreateError(input, event, err) + } + return &deletedData, nil + } + + data := e.McuOrderItem{} + setData(&input, &data) + if err := tx.Create(&data).Error; err != nil { return nil, plh.HandleCreateError(input, event, err) } diff --git a/internal/use-case/main-use-case/mcu-order/helper.go b/internal/use-case/main-use-case/mcu-order/helper.go index 8c7115b6..c7d6fc6f 100644 --- a/internal/use-case/main-use-case/mcu-order/helper.go +++ b/internal/use-case/main-use-case/mcu-order/helper.go @@ -26,6 +26,6 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.McuOrder) { data.ExaminationDate = inputSrc.ExaminationDate data.Number = inputSrc.Number data.Temperature = inputSrc.Temperature - data.McuUrgencyLevel_Code = inputSrc.McuUrgencyLevel_Code + data.UrgencyLevel_Code = inputSrc.UrgencyLevel_Code data.Doctor_Id = inputSrc.Doctor_Id } diff --git a/internal/use-case/main-use-case/mcu-order/lib.go b/internal/use-case/main-use-case/mcu-order/lib.go index ccb63db9..c659be5b 100644 --- a/internal/use-case/main-use-case/mcu-order/lib.go +++ b/internal/use-case/main-use-case/mcu-order/lib.go @@ -81,7 +81,7 @@ func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e tx = dg.I } - if err := tx.First(&data, input.Id).Error; err != nil { + if err := tx.Scopes(gh.Preload(input.Includes)).First(&data, input.Id).Error; err != nil { if processedErr := pu.HandleReadError(err, event, source, input.Id, data); processedErr != nil { return nil, processedErr } diff --git a/internal/use-case/main-use-case/patient/case.go b/internal/use-case/main-use-case/patient/case.go index b52215ac..cee92a77 100644 --- a/internal/use-case/main-use-case/patient/case.go +++ b/internal/use-case/main-use-case/patient/case.go @@ -4,8 +4,10 @@ import ( "errors" "strconv" + evm "simrs-vx/internal/domain/bpjs-entities/vclaim-member" e "simrs-vx/internal/domain/main-entities/patient" + uvm "simrs-vx/internal/use-case/bpjs-use-case/vclaim-member" upe "simrs-vx/internal/use-case/main-use-case/person" upa "simrs-vx/internal/use-case/main-use-case/person-address" upc "simrs-vx/internal/use-case/main-use-case/person-contact" @@ -49,6 +51,12 @@ func Create(input e.CreateDto) (*d.Data, error) { input.Person_Id = person_id } + if input.Person.VclaimMember_CardNumber != nil && input.Person.ResidentIdentityNumber != nil { + if err := uvm.CreateOrUpdateData(evm.CreateDto{CardNumber: input.Person.VclaimMember_CardNumber, Person_Id: input.Person_Id}, &event, tx); err != nil { + return err + } + } + for idx := range input.PersonAddresses { input.PersonAddresses[idx].Person_Id = *input.Person_Id } diff --git a/internal/use-case/main-use-case/patient/helper.go b/internal/use-case/main-use-case/patient/helper.go index 8abfeaf3..aac8d677 100644 --- a/internal/use-case/main-use-case/patient/helper.go +++ b/internal/use-case/main-use-case/patient/helper.go @@ -12,6 +12,7 @@ import ( "time" e "simrs-vx/internal/domain/main-entities/patient" + ibpjs "simrs-vx/internal/infra/bpjs" pl "simrs-vx/pkg/logger" pmh "simrs-vx/pkg/minio-helper" @@ -135,3 +136,13 @@ func removeUploadedFile(bucket, fileUrl string, event *pl.Event) error { pl.SetLogInfo(event, nil, "complete") return nil } + +func endpointMapper(noBpjs string) string { + today := getTodayDate() + return fmt.Sprintf("%speserta/nokartu?noKartu=%s&tglpelayanan=%s", ibpjs.O.BaseUrl, noBpjs, today) + +} + +func getTodayDate() string { + return time.Now().Format("2006-01-02") +} diff --git a/internal/use-case/main-use-case/patient/middleware.go b/internal/use-case/main-use-case/patient/middleware.go index 5fe75e0a..6b0175dc 100644 --- a/internal/use-case/main-use-case/patient/middleware.go +++ b/internal/use-case/main-use-case/patient/middleware.go @@ -1,9 +1,65 @@ package patient +import ( + "encoding/json" + "fmt" + "io" + "net/http" + + e "simrs-vx/internal/domain/main-entities/patient" + + "gorm.io/gorm" +) + // example of middleware -// func init() { -// createPreMw = append(createPreMw, -// CreateMw{Name: "modif-input", Func: pm.ModifInput}, -// CreateMw{Name: "check-data", Func: pm.CheckData}, -// ) -// } +func init() { + createPreMw = append(createPreMw, + createMw{Name: "check-vclaim-member", Func: checkVclaimMember}, + ) +} + +func checkVclaimMember(input *e.CreateDto, data *e.Patient, tx *gorm.DB) error { + if input.Person.VclaimMember_CardNumber != nil && input.Person.ResidentIdentityNumber != nil { + return isVclaimMemberMatch(input) + } + return nil +} + +func isVclaimMemberMatch(input *e.CreateDto) error { + endpoint := endpointMapper(*input.Person.VclaimMember_CardNumber) + req, err := http.NewRequest("GET", endpoint, nil) + if err != nil { + return err + } + req.Header.Set("Content-Type", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return err + } + + var data BPJSResponse + + if err := json.Unmarshal(body, &data); err != nil { + return fmt.Errorf("failed to parse response JSON: %w", err) + } + + if data.MetaData.Code != "200" { + return fmt.Errorf("failed to get vclaim member: %s", data.MetaData.Message) + } + + if data.Response.Peserta.NoKartu == "" || data.Response.Peserta.NIK == "" { + return fmt.Errorf("failed to get vclaim member: noKartu or nik is empty") + } + + if data.Response.Peserta.NIK != *input.Person.ResidentIdentityNumber { + return fmt.Errorf("nik(residentIdentityNumber) is not match with bpjs number(vclaimMember_cardNumber)") + } + return nil +} diff --git a/internal/use-case/main-use-case/patient/tycovar.go b/internal/use-case/main-use-case/patient/tycovar.go index d7e9abfe..29e5c368 100644 --- a/internal/use-case/main-use-case/patient/tycovar.go +++ b/internal/use-case/main-use-case/patient/tycovar.go @@ -42,3 +42,16 @@ var updatePreMw []readDetailMw var updatePostMw []readDetailMw var deletePreMw []readDetailMw var deletePostMw []readDetailMw + +type BPJSResponse struct { + MetaData struct { + Code string `json:"code"` + Message string `json:"message"` + } `json:"metaData"` + Response *struct { + Peserta struct { + NoKartu string `json:"noKartu"` + NIK string `json:"nik"` + } `json:"peserta"` + } `json:"response"` +} diff --git a/internal/use-case/main-use-case/person/helper.go b/internal/use-case/main-use-case/person/helper.go index 61a2f18c..3760f3b2 100644 --- a/internal/use-case/main-use-case/person/helper.go +++ b/internal/use-case/main-use-case/person/helper.go @@ -30,6 +30,8 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Person) { data.Education_Code = inputSrc.Education_Code data.Ocupation_Code = inputSrc.Ocupation_Code data.Ocupation_Name = inputSrc.Ocupation_Name + data.MaritalStatus_Code = inputSrc.MaritalStatus_Code + data.Confidence = inputSrc.Confidence data.Nationality = inputSrc.Nationality data.Ethnic_Code = inputSrc.Ethnic_Code data.Language_Code = inputSrc.Language_Code diff --git a/internal/use-case/main-use-case/prescription/lib.go b/internal/use-case/main-use-case/prescription/lib.go index 013952f8..52025c89 100644 --- a/internal/use-case/main-use-case/prescription/lib.go +++ b/internal/use-case/main-use-case/prescription/lib.go @@ -89,7 +89,7 @@ func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e tx = tx.Where("\"Id\" = ?", input.Id) } - if err := tx.First(&data).Error; err != nil { + if err := tx.Scopes(gh.Preload(input.Includes)).First(&data).Error; err != nil { if processedErr := pu.HandleReadError(err, event, source, input.Id, data); processedErr != nil { return nil, processedErr } diff --git a/internal/use-case/main-use-case/responsible-doctor-hist/case.go b/internal/use-case/main-use-case/responsible-doctor-hist/case.go new file mode 100644 index 00000000..3451a88f --- /dev/null +++ b/internal/use-case/main-use-case/responsible-doctor-hist/case.go @@ -0,0 +1,276 @@ +package responsible_doctor_hist + +import ( + e "simrs-vx/internal/domain/main-entities/responsible-doctor-hist" + "strconv" + + dg "github.com/karincake/apem/db-gorm-pg" + d "github.com/karincake/dodol" + + pl "simrs-vx/pkg/logger" + pu "simrs-vx/pkg/use-case-helper" + + "gorm.io/gorm" +) + +const source = "responsible-doctor-hist" + +func Create(input e.CreateDto) (*d.Data, error) { + data := e.ResponsibleDoctorHist{} + + event := pl.Event{ + Feature: "Create", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "create") + + err := dg.I.Transaction(func(tx *gorm.DB) error { + mwRunner := newMiddlewareRunner(&event, tx) + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil { + return err + } + + if resData, err := CreateData(input, &event, tx); err != nil { + return err + } else { + data = *resData + } + + mwRunner.setMwType(pu.MWTPost) + // Run post-middleware + if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil { + return err + } + + pl.SetLogInfo(&event, nil, "complete") + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.II{ + "source": source, + "structure": "single-data", + "status": "created", + }, + Data: data.ToResponse(), + }, nil +} + +func ReadList(input e.ReadListDto) (*d.Data, error) { + var data *e.ResponsibleDoctorHist + var dataList []e.ResponsibleDoctorHist + var metaList *e.MetaDto + var err error + + event := pl.Event{ + Feature: "ReadList", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "readList") + + err = dg.I.Transaction(func(tx *gorm.DB) error { + mwRunner := newMiddlewareRunner(&event, tx) + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunReadListMiddleware(readListPreMw, &input, data); err != nil { + return err + } + + if dataList, metaList, err = ReadListData(input, &event, tx); err != nil { + return err + } + + mwRunner.setMwType(pu.MWTPost) + // Run post-middleware + if err := mwRunner.RunReadListMiddleware(readListPostMw, &input, data); err != nil { + return err + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "list-data", + "status": "fetched", + "page_number": strconv.Itoa(metaList.PageNumber), + "page_size": strconv.Itoa(metaList.PageSize), + "record_totalCount": strconv.Itoa(metaList.Count), + "record_currentCount": strconv.Itoa(len(dataList)), + }, + Data: e.ToResponseList(dataList), + }, nil +} + +func ReadDetail(input e.ReadDetailDto) (*d.Data, error) { + var data *e.ResponsibleDoctorHist + var err error + + event := pl.Event{ + Feature: "ReadDetail", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "readDetail") + + err = dg.I.Transaction(func(tx *gorm.DB) error { + mwRunner := newMiddlewareRunner(&event, tx) + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunReadDetailMiddleware(readDetailPreMw, &input, data); err != nil { + return err + } + + if data, err = ReadDetailData(input, &event, tx); err != nil { + return err + } + + mwRunner.setMwType(pu.MWTPost) + // Run post-middleware + if err := mwRunner.RunReadDetailMiddleware(readDetailPostMw, &input, data); err != nil { + return err + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "single-data", + "status": "fetched", + }, + Data: data.ToResponse(), + }, nil +} + +func Update(input e.UpdateDto) (*d.Data, error) { + rdDto := e.ReadDetailDto{Id: input.Id} + var data *e.ResponsibleDoctorHist + var err error + + event := pl.Event{ + Feature: "Update", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "update") + + err = dg.I.Transaction(func(tx *gorm.DB) error { + pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail") + if data, err = ReadDetailData(rdDto, &event, tx); err != nil { + return err + } + + mwRunner := newMiddlewareRunner(&event, tx) + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunUpdateMiddleware(readDetailPreMw, &rdDto, data); err != nil { + return err + } + + if err := UpdateData(input, data, &event, tx); err != nil { + return err + } + + pl.SetLogInfo(&event, nil, "complete") + + mwRunner.setMwType(pu.MWTPost) + // Run post-middleware + if err := mwRunner.RunUpdateMiddleware(readDetailPostMw, &rdDto, data); err != nil { + return err + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "single-data", + "status": "updated", + }, + Data: data.ToResponse(), + }, nil + +} + +func Delete(input e.DeleteDto) (*d.Data, error) { + rdDto := e.ReadDetailDto{Id: input.Id} + var data *e.ResponsibleDoctorHist + var err error + + event := pl.Event{ + Feature: "Delete", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "delete") + + err = dg.I.Transaction(func(tx *gorm.DB) error { + pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail") + if data, err = ReadDetailData(rdDto, &event, tx); err != nil { + return err + } + + mwRunner := newMiddlewareRunner(&event, tx) + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunDeleteMiddleware(readDetailPreMw, &rdDto, data); err != nil { + return err + } + + if err := DeleteData(data, &event, tx); err != nil { + return err + } + + mwRunner.setMwType(pu.MWTPost) + // Run post-middleware + if err := mwRunner.RunDeleteMiddleware(readDetailPostMw, &rdDto, data); err != nil { + return err + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "single-data", + "status": "deleted", + }, + Data: data.ToResponse(), + }, nil + +} diff --git a/internal/use-case/main-use-case/responsible-doctor-hist/helper.go b/internal/use-case/main-use-case/responsible-doctor-hist/helper.go new file mode 100644 index 00000000..6efd1097 --- /dev/null +++ b/internal/use-case/main-use-case/responsible-doctor-hist/helper.go @@ -0,0 +1,24 @@ +/* +DESCRIPTION: +Any functions that are used internally by the use-case +*/ +package responsible_doctor_hist + +import ( + e "simrs-vx/internal/domain/main-entities/responsible-doctor-hist" +) + +func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.ResponsibleDoctorHist) { + var inputSrc *e.CreateDto + if inputT, ok := any(input).(*e.CreateDto); ok { + inputSrc = inputT + } else { + inputTemp := any(input).(*e.UpdateDto) + inputSrc = &inputTemp.CreateDto + } + + data.Encounter_Id = inputSrc.Encounter_Id + data.Doctor_Id = inputSrc.Doctor_Id + data.StartedAt = inputSrc.StartedAt + data.FinishedAt = inputSrc.FinishedAt +} diff --git a/internal/use-case/main-use-case/responsible-doctor-hist/lib.go b/internal/use-case/main-use-case/responsible-doctor-hist/lib.go new file mode 100644 index 00000000..d91294fe --- /dev/null +++ b/internal/use-case/main-use-case/responsible-doctor-hist/lib.go @@ -0,0 +1,156 @@ +package responsible_doctor_hist + +import ( + "errors" + e "simrs-vx/internal/domain/main-entities/responsible-doctor-hist" + + plh "simrs-vx/pkg/lib-helper" + pl "simrs-vx/pkg/logger" + pu "simrs-vx/pkg/use-case-helper" + + dg "github.com/karincake/apem/db-gorm-pg" + gh "github.com/karincake/getuk" + "gorm.io/gorm" +) + +func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.ResponsibleDoctorHist, error) { + pl.SetLogInfo(event, nil, "started", "DBCreate") + + data := e.ResponsibleDoctorHist{} + setData(&input, &data) + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Create(&data).Error; err != nil { + return nil, plh.HandleCreateError(input, event, err) + } + + pl.SetLogInfo(event, nil, "complete") + return &data, nil +} + +func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.ResponsibleDoctorHist, *e.MetaDto, error) { + pl.SetLogInfo(event, input, "started", "DBReadList") + data := []e.ResponsibleDoctorHist{} + pagination := gh.Pagination{} + count := int64(0) + meta := e.MetaDto{} + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + tx = tx. + Model(&e.ResponsibleDoctorHist{}). + Scopes(gh.Preload(input.Includes)). + Scopes(gh.Filter(input.FilterDto)). + Count(&count). + Scopes(gh.Paginate(input, &pagination)). + Scopes(gh.Sort(input.Sort)) + + if err := tx.Find(&data).Error; err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, &meta, nil + } + return nil, nil, plh.HandleListError(input, event, err) + } + + meta.Count = int(count) + meta.PageNumber = pagination.PageNumber + meta.PageSize = pagination.PageSize + + pl.SetLogInfo(event, nil, "complete") + return data, &meta, nil +} + +func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.ResponsibleDoctorHist, error) { + pl.SetLogInfo(event, input, "started", "DBReadDetail") + data := e.ResponsibleDoctorHist{} + + var tx, getData *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + switch { + case input.Id != 0: + getData = tx.First(&data, input.Id) + case input.Code != nil && *input.Code != "": + getData = tx.Where("code = ?", *input.Code).First(&data) + default: + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-read-detail-fail", + Detail: "either Id or Code must be provided", + } + + return nil, pl.SetLogError(event, nil) + } + + if err := getData.Error; err != nil { + if processedErr := pu.HandleReadError(err, event, source, input.Id, data); processedErr != nil { + return nil, processedErr + } + } + + pl.SetLogInfo(event, nil, "complete") + return &data, nil +} + +func UpdateData(input e.UpdateDto, data *e.ResponsibleDoctorHist, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, data, "started", "DBUpdate") + setData(&input, data) + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Save(&data).Error; err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-update-fail", + Detail: "Database update failed", + Raw: err, + } + return pl.SetLogError(event, input) + } + + pl.SetLogInfo(event, nil, "complete") + return nil +} + +func DeleteData(data *e.ResponsibleDoctorHist, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, data, "started", "DBDelete") + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Delete(&data).Error; err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-delete-fail", + Detail: "Database delete failed", + Raw: err, + } + return pl.SetLogError(event, data) + } + + pl.SetLogInfo(event, nil, "complete") + return nil +} diff --git a/internal/use-case/main-use-case/responsible-doctor-hist/middleware-runner.go b/internal/use-case/main-use-case/responsible-doctor-hist/middleware-runner.go new file mode 100644 index 00000000..0b107557 --- /dev/null +++ b/internal/use-case/main-use-case/responsible-doctor-hist/middleware-runner.go @@ -0,0 +1,103 @@ +package responsible_doctor_hist + +import ( + e "simrs-vx/internal/domain/main-entities/responsible-doctor-hist" + pl "simrs-vx/pkg/logger" + pu "simrs-vx/pkg/use-case-helper" + + "gorm.io/gorm" +) + +type middlewareRunner struct { + Event *pl.Event + Tx *gorm.DB + MwType pu.MWType +} + +// NewMiddlewareExecutor creates a new middleware executor +func newMiddlewareRunner(event *pl.Event, tx *gorm.DB) *middlewareRunner { + return &middlewareRunner{ + Event: event, + Tx: tx, + } +} + +// ExecuteCreateMiddleware executes create middleware +func (me *middlewareRunner) RunCreateMiddleware(middlewares []createMw, input *e.CreateDto, data *e.ResponsibleDoctorHist) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) RunReadListMiddleware(middlewares []readListMw, input *e.ReadListDto, data *e.ResponsibleDoctorHist) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) RunReadDetailMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.ResponsibleDoctorHist) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) RunUpdateMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.ResponsibleDoctorHist) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) RunDeleteMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.ResponsibleDoctorHist) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) setMwType(mwType pu.MWType) { + me.MwType = mwType +} diff --git a/internal/use-case/main-use-case/responsible-doctor-hist/middleware.go b/internal/use-case/main-use-case/responsible-doctor-hist/middleware.go new file mode 100644 index 00000000..324938e8 --- /dev/null +++ b/internal/use-case/main-use-case/responsible-doctor-hist/middleware.go @@ -0,0 +1,9 @@ +package responsible_doctor_hist + +// example of middleware +// func init() { +// createPreMw = append(createPreMw, +// CreateMw{Name: "modif-input", Func: pm.ModifInput}, +// CreateMw{Name: "check-data", Func: pm.CheckData}, +// ) +// } diff --git a/internal/use-case/main-use-case/responsible-doctor-hist/tycovar.go b/internal/use-case/main-use-case/responsible-doctor-hist/tycovar.go new file mode 100644 index 00000000..aac1d18c --- /dev/null +++ b/internal/use-case/main-use-case/responsible-doctor-hist/tycovar.go @@ -0,0 +1,44 @@ +/* +DESCRIPTION: +A sample, part of the package that contains type, constants, and/or variables. + +In this sample it also provides type and variable regarding the needs of the +middleware to separate from main use-case which has the basic CRUD +functionality. The purpose of this is to make the code more maintainable. +*/ +package responsible_doctor_hist + +import ( + "gorm.io/gorm" + + e "simrs-vx/internal/domain/main-entities/responsible-doctor-hist" +) + +type createMw struct { + Name string + Func func(input *e.CreateDto, data *e.ResponsibleDoctorHist, tx *gorm.DB) error +} + +type readListMw struct { + Name string + Func func(input *e.ReadListDto, data *e.ResponsibleDoctorHist, tx *gorm.DB) error +} + +type readDetailMw struct { + Name string + Func func(input *e.ReadDetailDto, data *e.ResponsibleDoctorHist, tx *gorm.DB) error +} + +type UpdateMw = readDetailMw +type DeleteMw = readDetailMw + +var createPreMw []createMw // preprocess middleware +var createPostMw []createMw // postprocess middleware +var readListPreMw []readListMw // .. +var readListPostMw []readListMw // .. +var readDetailPreMw []readDetailMw +var readDetailPostMw []readDetailMw +var updatePreMw []readDetailMw +var updatePostMw []readDetailMw +var deletePreMw []readDetailMw +var deletePostMw []readDetailMw diff --git a/internal/use-case/main-use-case/sbar/case.go b/internal/use-case/main-use-case/sbar/case.go index 6c92f2b0..45045e35 100644 --- a/internal/use-case/main-use-case/sbar/case.go +++ b/internal/use-case/main-use-case/sbar/case.go @@ -4,11 +4,8 @@ import ( "errors" "strconv" - ee "simrs-vx/internal/domain/main-entities/employee" e "simrs-vx/internal/domain/main-entities/sbar" - ue "simrs-vx/internal/use-case/main-use-case/employee" - dg "github.com/karincake/apem/db-gorm-pg" d "github.com/karincake/dodol" @@ -49,11 +46,13 @@ func Create(input e.CreateDto) (*d.Data, error) { return pl.SetLogError(&event, input) } - employee, err := ue.ReadDetailData(ee.ReadDetailDto{User_Id: &input.AuthInfo.User_Id}, &event, tx) - if err != nil { - return err + if input.AuthInfo.Employee_Id != nil { + v := uint(*input.AuthInfo.Employee_Id) + input.Employee_Id = &v + } else { + input.Employee_Id = nil } - input.Employee_Id = &employee.Id + if resData, err := CreateData(input, &event, tx); err != nil { return err } else { diff --git a/internal/use-case/main-use-case/soapi/case.go b/internal/use-case/main-use-case/soapi/case.go index fd06e140..3dc8e195 100644 --- a/internal/use-case/main-use-case/soapi/case.go +++ b/internal/use-case/main-use-case/soapi/case.go @@ -4,11 +4,8 @@ import ( "errors" "strconv" - ee "simrs-vx/internal/domain/main-entities/employee" e "simrs-vx/internal/domain/main-entities/soapi" - ue "simrs-vx/internal/use-case/main-use-case/employee" - dg "github.com/karincake/apem/db-gorm-pg" d "github.com/karincake/dodol" @@ -49,11 +46,13 @@ func Create(input e.CreateDto) (*d.Data, error) { return pl.SetLogError(&event, input) } - employee, err := ue.ReadDetailData(ee.ReadDetailDto{User_Id: &input.AuthInfo.User_Id}, &event, tx) - if err != nil { - return err + if input.AuthInfo.Employee_Id != nil { + v := uint(*input.AuthInfo.Employee_Id) + input.Employee_Id = &v + } else { + input.Employee_Id = nil } - input.Employee_Id = &employee.Id + if resData, err := CreateData(input, &event, tx); err != nil { return err } else { diff --git a/pkg/use-case-helper/use-case-helper.go b/pkg/use-case-helper/use-case-helper.go index 8c41266f..0df8fe3e 100644 --- a/pkg/use-case-helper/use-case-helper.go +++ b/pkg/use-case-helper/use-case-helper.go @@ -97,7 +97,7 @@ func HandleMiddlewareError(event *pl.Event, mwType, mwName string, logData inter event.Status = "failed" event.ErrInfo = pl.ErrorInfo{ Code: GetMiddlewareErrorCode(MWType(mwType)), - Detail: fmt.Sprintf("%s middleware %s failed", mwType, mwName), + Detail: fmt.Sprintf("%s middleware %s failed: %s", mwType, mwName, err.Error()), Raw: err, } return pl.SetLogError(event, logData)