diff --git a/cmd/main-api/config.yml-example b/cmd/main-api/config.yml-example index 3f5caa33..5915c46c 100644 --- a/cmd/main-api/config.yml-example +++ b/cmd/main-api/config.yml-example @@ -72,7 +72,8 @@ syncUrlCfg: enable: false targetHost: prefix: new-to-old - source: new-app + oldSource: new-app + newSource: new-app secretKey: new-world-order!! docsCfg: diff --git a/cmd/main-migration/migrations/20251125125303.sql b/cmd/main-migration/migrations/20251125125303.sql new file mode 100644 index 00000000..56d16371 --- /dev/null +++ b/cmd/main-migration/migrations/20251125125303.sql @@ -0,0 +1,2 @@ +-- Modify "Encounter" table +ALTER TABLE "public"."Encounter" ADD COLUMN "Responsible_Nurse_Code" character varying(20) NULL, ADD CONSTRAINT "fk_Encounter_Responsible_Nurse" FOREIGN KEY ("Responsible_Nurse_Code") REFERENCES "public"."Nurse" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION; diff --git a/cmd/main-migration/migrations/20251126064057.sql b/cmd/main-migration/migrations/20251126064057.sql new file mode 100644 index 00000000..fd823ff9 --- /dev/null +++ b/cmd/main-migration/migrations/20251126064057.sql @@ -0,0 +1,2 @@ +-- Modify "InternalReference" table +ALTER TABLE "public"."InternalReference" ADD COLUMN "SrcDoctor_Code" character varying(20) NULL, ADD COLUMN "SrcNurse_Code" character varying(20) NULL, ADD COLUMN "Nurse_Code" character varying(20) NULL, ADD CONSTRAINT "fk_InternalReference_Nurse" FOREIGN KEY ("Nurse_Code") REFERENCES "public"."Nurse" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION, ADD CONSTRAINT "fk_InternalReference_SrcDoctor" FOREIGN KEY ("SrcDoctor_Code") REFERENCES "public"."Doctor" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION, ADD CONSTRAINT "fk_InternalReference_SrcNurse" FOREIGN KEY ("SrcNurse_Code") REFERENCES "public"."Nurse" ("Code") 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 707ee3ca..449ff1d4 100644 --- a/cmd/main-migration/migrations/atlas.sum +++ b/cmd/main-migration/migrations/atlas.sum @@ -1,4 +1,4 @@ -h1:87NyL1nIRuVvOiLbfdC1+PF+v2R/joAnBYyh2CrlGdU= +h1:Y8m8OmsumTaAfXfYYXHlZS0+OqbAqFfM3a55nmibOUE= 20250904105930.sql h1:MEM6blCgke9DzWQSTnLzasbPIrcHssNNrJqZpSkEo6k= 20250904141448.sql h1:J8cmYNk4ZrG9fhfbi2Z1IWz7YkfvhFqTzrLFo58BPY0= 20250908062237.sql h1:Pu23yEW/aKkwozHoOuROvHS/GK4ngARJGdO7FB7HZuI= @@ -75,57 +75,59 @@ h1:87NyL1nIRuVvOiLbfdC1+PF+v2R/joAnBYyh2CrlGdU= 20251106040137.sql h1:ppcqkVoT0o9jZcjI/TN7LuaPxXhJQhnIXEJtloP/46o= 20251106041333.sql h1:2JkxyelQ/EeB+boL5bfpnzefw32ttEGKvKchtQjWmAU= 20251106042006.sql h1:ruppYa1kAJQUU3ufQBbKGMcXrGbGJJiRPclT+dNc/YQ= -20251106050412.sql h1:1002KYtHd8AwrQTMewbs/PPHDylHDghigE/3S7PVdMA= -20251106063418.sql h1:jPW/gBnbFl4RO39lQ0ZMDtYA6xbhyD6CgQupT50HmaY= -20251106071906.sql h1:leYGKxR3EQn794aOehf0sd/ZPmOnvBMZPy5/anGmRB4= -20251106073157.sql h1:KASMzjjjk5UB7Zj8lCRtM1utc4ZnDjlnpZbtTe3vONE= -20251106074218.sql h1:Z5q5deOvLaZDPhiVTN9st3/s56RepBa2YOyrMXBdj4A= -20251106081846.sql h1:P+VsWwhGt60adDIZuE/Aa38JVp/yX1rnsdpXpxASodw= -20251106082844.sql h1:Dmi5A8i9frQZvdXYPwc7f8CisZtBH8liSXq1rI6z1iM= -20251106090021.sql h1:4JwdKgO8T46YhyWVJUxpRIwudBDlG8QN1brSOYmgQ20= -20251106144745.sql h1:nqnQCzGrVJaq8ilOEOGXeRUL1dolj+OPWKuP8A92FRA= -20251107012049.sql h1:Pff4UqltGS3clSlGr0qq8CQM56L29wyxY0FC/N/YAhU= -20251107064812.sql h1:GB9a0ZfMYTIoGNmKUG+XcYUsTnRMFfT4/dAD71uCPc4= -20251107064937.sql h1:IC5pw1Ifj30hiE6dr5NMHXaSHoQI+vRd40N5ABgBHRI= -20251107071420.sql h1:9NO3iyLEXEtWa2kSRjM/8LyzuVIk6pdFL2SuheWjB08= -20251107074318.sql h1:7fHbSRrdjOmHh/xwnjCLwoiB5cW5zeH+uxLV0vZbkIA= -20251107075050.sql h1:np+3uTOnU9QNtK7Knaw8eRMhkyB9AwrtSNHphOBxbHY= -20251107080604.sql h1:cXDBLPJDVWLTG6yEJqkJsOQ7p7VYxLM2SY+mwO8qSHo= -20251107081830.sql h1:/S7OQZo4ZnK80t28g/JyiOTZtmWG/dP5Wg2zXNMQ/iE= -20251107091033.sql h1:/cbkF1nO/IjNSIfDJJx456KJtQ9rWFXOBFAkR/M2xiE= -20251107091209.sql h1:jrLQOUeV8ji2fg0pnEcs1bw4ANUxzTSMXC/rrHLIY+M= -20251107091541.sql h1:6UqbhQQRmzA2+eKu5lIvkwOkk+lH70QLZC8Pjpjcq68= -20251110012217.sql h1:C9HpX0iyHzKjyNv/5DSAn2MCHj6MX4p5UQ/NrY7QD0w= -20251110012306.sql h1:J54yb27d30LBbYp9n1P66gFVRlxPguKu0kxmWIBBG8g= -20251110052049.sql h1:232T2x8xTczJl9nk4jxJpZXhoOGYthhxjJ7nK8Jd8vg= -20251110062042.sql h1:WnfVUXrzYoj8qdkkjO9/JQQ8agGd4GfSHQdMjo7LDAg= -20251110063202.sql h1:hSzGfwVMWa6q3vwIQZUkxKgBNCzHjB+6GKy54zfV+oQ= -20251110063633.sql h1:/VpofIAqNS1CnazEnpW/+evbzn9Kew3xDW48r57M+Xg= -20251110085551.sql h1:bFZwSmfvVbTUr/enWB82WqjG88gpqcZ6s45btUvO0uo= -20251110091516.sql h1:KkJMwPQuaZQhiqnKrNQrgP12gw9rV8T3P2o3mtGTcvY= -20251110091948.sql h1:I4odAYrJdvNf1jPw6ppDC0XdI7v6vKBACg/ABwUgA7I= -20251110092729.sql h1:l1out8soEmVP6dNjaIOtGYo6QDcoJZRI8X1sjZ5ZGmo= -20251110093522.sql h1:nsz8jCxGjEdr/bz9g+4ozfZzIP803xONjVmucad1GMc= -20251110100258.sql h1:IBqt1VZj5WjQ+l9aAFGHOCCBtzb03KlLLihFLut7itg= -20251110100545.sql h1:6/LV7751iyKxE2xI6vO1zly+aHUwxXD/IBwLcVpKxqM= -20251110155448.sql h1:kFPobJB+cpflsXBAWUwy3lohuWvrb/VRlXnhJWl7i3Y= -20251111072601.sql h1:ch8F+yVhsSM5xY+TwMLY3PxdLa4Wuhtj76oyw79R7Js= -20251111073546.sql h1:cCv0NPscADAOBahRVqtDWFs6G2t7n+4a+RwlF8vk/c4= -20251111074148.sql h1:70TsV83u1gQ5TktI13K7NQiyCCa35Td2aR6CNtKUa4U= -20251111074652.sql h1:ddfQ/sRKMezPM75xBFTGytUQX5AwZ3znrJVpg73gKPA= -20251111082257.sql h1:ZsdLY1ROouos0l3oS0lkeSiuKLEUGbVvBhpcM2AVhkw= -20251111111017.sql h1:qrJ93dNtQwcuAvpsP/lAK/H63C4cinXrsVaPmWsTqkU= -20251113101344.sql h1:xaOZvAUP1fFfnO+syEFOzJUIg5lTfBe5AWHPbBWuCLA= -20251113120533.sql h1:f3/U1Ve2yF2zSMhkt+xtwF8wUYfUKYwgbNeGfE37EW4= -20251114062746.sql h1:FInLaEFQByESEwFJKuKnuUSTKmcDpi3ZXaxkKwz2+D8= -20251117005942.sql h1:wD3BWrUSmo1HlW16V3lkaBkJvbAZ0fNk77te7J9NhOc= -20251117075427.sql h1:TqU9VKZa3I8YNXUGQWY3WVBYN+1FvyyaKy0hB1jgAho= -20251118074929.sql h1:p1KsWqCuR1JXA/jVO5BmOhCcaQ8clT7t0YRszAhPFbg= -20251119063438.sql h1:NVGM0X/LHD37EaPl8SNzkNiZDJ7AB1QR+LLwLh6WRdg= -20251119065730.sql h1:U5lzk1WvMB0bw3kwckou7jkEt4bwdYItwHr2Vxqe7w4= -20251119072302.sql h1:qCuI2WMEMF/XNbjV+RXPjBnuCKLu1Fia+mR9HiLWBIs= -20251119072450.sql h1:Xg+bTwqGyKPNFEQhJylvpz1wifdfmDJvcAq6vmNf0Ng= -20251120005512.sql h1:Ek6qpacAI/qVuTYxKno+uJyzn7s5z9pf3t7VA8gTzm4= -20251120074415.sql h1:NNUeJVA03EeBHJhHqPXEZoDv/PnC6yK1/cRhmukyaJo= -20251121033803.sql h1:/vfvFX/3pzSCIHnSbMUT9EMBDykOpVkvyfeTEle9Vas= -20251124071457.sql h1:HBaNJQIzUe6wK8CgBxamuKor7ZiAASzgkkXzL6kWsjY= +20251106050412.sql h1:MiEMJ1HCFYnalKuq3Z38xJeogfBAMqsTv2sG4EF8dDw= +20251106063418.sql h1:y3veDJPjKekOWLCZek/LgQwXPRhZtOppTfUXiqoL95s= +20251106071906.sql h1:/TUZA3XpMY23qEJXdkTwlzrNMvSSl6JJniPcgAttBaw= +20251106073157.sql h1:78txeibJ602DMD7huD618ZSMt6phSRzDNPTlo0PGyrc= +20251106074218.sql h1:8Xz7WywrtUnSxOHhlal53gG9rE7r86LFUt5zBFe/mIs= +20251106081846.sql h1:jp91Bf5bxGXMiUB1VIuN6y768vb2iWwow44WfCE5J5k= +20251106082844.sql h1:RHYzRO4G1fSWwf+xc/3QezZ/Iil67cZPIgNpNz3TNhQ= +20251106090021.sql h1:dFDk6mq+zjbYWmfWIrHf9DiKvvoXHjrr0++zssMTWP8= +20251106144745.sql h1:aHcr23iBFqCHer5D/SsPMXBCLjGqUYvWYfRU8jSJgIw= +20251107012049.sql h1:hu/7NHhnAkT4xK0RNtqmMDdH1Bo5EZbl7itDRjiCT+g= +20251107064812.sql h1:sfCXDQYnMf0ddrQ9oYljWJLLSt9NJjJV6o8VS3p7aZE= +20251107064937.sql h1:DlYGJ9LZFwZyR7jBP5zaGB128aIc4HAixBKPYCz9EkY= +20251107071420.sql h1:ynCdZAd2utLl+FhtWZwtahNXgIVOvuk3s/rOq7lfXA4= +20251107074318.sql h1:WE9cPhibWtZ0dbu1VEGirTeY6ijFYGMNhHdBtM32kOc= +20251107075050.sql h1:8tvneruqdynDOaJK1+0z4CH7YXZStZpGdqwIeOMLik4= +20251107080604.sql h1:8c4jd4Tql7tcdhbI9NS0tgvN+ADu9FnCf8wMUbmW7A0= +20251107081830.sql h1:SAAe3lmsm9vGXuSEsDdl7ad0EAxP5CMmFRDEgp9M7yY= +20251107091033.sql h1:JLdX/u7GUdBfjrPrMSNAqc8HtSoj0YA9iW9Vc6FJZdw= +20251107091209.sql h1:CzhYtwAwT+GHrbqcagnJE+v3mbl/rObf1IJaLCKlzrs= +20251107091541.sql h1:+3ZyWJTftDY2JeWThXuIxGWpUBnyMPyOyY4jBjdWYJI= +20251110012217.sql h1:f4Z8TuGc+XMSJ+Ekn4/PeHRE2FlHWkc5gKPJB0hAX7c= +20251110012306.sql h1:ENPyI6Kjdk6qKJQb0yJ6MCTDPAmO1WD/uhKuCSl+jYo= +20251110052049.sql h1:OrQ0acnyoQLKnTitZfnBcVr5jDslF59OFLaqT7SpdVs= +20251110062042.sql h1:9KwldQt0NpVPR86L0T4hlkfHAGau+7CiZYgu5rF+yhg= +20251110063202.sql h1:A117DuZmZ6U0jWHA3DISnr+yvBjKIr1ObrUr047YezQ= +20251110063633.sql h1:qTiC0F19JnhUIXF4LGJQ21jEV6kKGyhTr1x2kimFqPQ= +20251110085551.sql h1:HZcJM0RSC6HBaUSjKBE8MgDG8Vn9f3LmwA/OnT9Cp7I= +20251110091516.sql h1:W3AQhQLgirEWuCObbLl+Prdrbq6k6EEY1xcoWsmbog4= +20251110091948.sql h1:3tsITMrZr/T+L4wqUMz8sHS229jCJl4T0Nu3dMccxH8= +20251110092729.sql h1:uU+k88RH/e0Ns4/SmJl03RVYPscBAPuiLfxR6CJqaf0= +20251110093522.sql h1:O7upSj8VNjzvroL4IU59bfxKATOkAVGBArcUbVNq9aM= +20251110100258.sql h1://JSArUMNI3/gAtYDx2VN94C198SFW0ANjgs+p6eCRM= +20251110100545.sql h1:ENPOqeJYRpMI4e8VCKwaQgaql8se6pIidAhG2cjskBg= +20251110155448.sql h1:VW9KE0jxWy4flZ28sdXmhY6JWd6eKAX/cVL8KWRVii4= +20251111072601.sql h1:99WWzGjcDDFNC2cHRfPu4MBLWNrgPMY5HAYUbmIcVRA= +20251111073546.sql h1:iIGwFNfUgStdczw/PXTH3SD84xAyxrbZICofc3M8TMk= +20251111074148.sql h1:mzkezSKwCV2bTZ/0BHiTCX5qAy4uHpwar1xzwAH15Ko= +20251111074652.sql h1:lYh4/3BHV24pgPC0pP4RUKb+XtL/6AsZGPItRpnzBiQ= +20251111082257.sql h1:+cIZ1lf8HYGSL6t6U88plLKk8nOO1YVdV7h3YOM84ds= +20251111111017.sql h1:xzlhR2xLfOj4ddYlesS+bpEeDrxiAf5ILNOspsbZjBU= +20251113101344.sql h1:vSzThY3p6XYTj0dJ2uFVkHmlytyrFAnGE58CJLx364I= +20251113120533.sql h1:lfjgdqRGo/EohrVw8sWlFbDjh3ASTsfQ6pr3qjafqvc= +20251114062746.sql h1:6DLYjfJ60PkAABZTXvOwSE+xrU25oyoX7gpYlBnA9cw= +20251117005942.sql h1:0XoJKca8IOaB9QKFVF/qPY7jKcIgh6m/LODQuE06SAs= +20251117075427.sql h1:LhY2urosfoSu1/vkHmgsNP4JA4DuWBs9gL59yMqcF8M= +20251118074929.sql h1:3RWBD6BziQVw6WSfthgoVuhTELHER9NrIuZm4hY/F1A= +20251119063438.sql h1:EVTG3ZrHjCmM95YPASZTRPiwHrG6e33A2vO4hLSAaBQ= +20251119065730.sql h1:s98wnZOCW6NbnwDS3H53XIQ60u6B9bDwBLNvy5+Rn64= +20251119072302.sql h1:ZL+VHekLYqgNtOFKlj02WHrAk11dtTxQkmyTKE8IOzY= +20251119072450.sql h1:SiJy2vpSvoPFw4J1SW7HjGSJzrqR62NsjRYAeabV+kc= +20251120005512.sql h1:hJUaWXYJ3HiSquBTw8OKhymjA4O43ehAMGfiOY8W87Q= +20251120074415.sql h1:dNmcqZHqfZwi/wtYvO/pSFgImN2scXL0p/7g0+HLp0s= +20251121033803.sql h1:onlddYGo+tQdGaEdJPqdsx3sncGnwEvqMSCksF6vjjI= +20251124071457.sql h1:ikQLIXFikUbkUd55uJBmEvqLGEC9t0db+Om4TQsWP7M= +20251125125303.sql h1:OLKbNPO36AHtIDursW9AeBvf60sahQKC1iOjHmpx0MA= +20251126064057.sql h1:6al3PTWbw/WGiBcrRrVWppOMLtG+eRaH/qSLbnmh1kQ= diff --git a/cmd/simgos-sync-migration/migrations/20251126115527.sql b/cmd/simgos-sync-migration/migrations/20251126115527.sql new file mode 100644 index 00000000..49ca1e5c --- /dev/null +++ b/cmd/simgos-sync-migration/migrations/20251126115527.sql @@ -0,0 +1,36 @@ +-- Create "InternalReferenceLink" table +CREATE TABLE "public"."InternalReferenceLink" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "Simx_Id" bigint NULL, + "Simgos_Id" bigint NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "uni_InternalReferenceLink_Simgos_Id" UNIQUE ("Simgos_Id"), + CONSTRAINT "uni_InternalReferenceLink_Simx_Id" UNIQUE ("Simx_Id") +); +-- Create "InternalReferenceSimgosLog" table +CREATE TABLE "public"."InternalReferenceSimgosLog" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "Value" text NULL, + "Date" timestamptz NULL, + "Status" text NULL, + "ErrMessage" text NULL, + PRIMARY KEY ("Id") +); +-- Create "InternalReferenceSimxLog" table +CREATE TABLE "public"."InternalReferenceSimxLog" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "Value" text NULL, + "Date" timestamptz NULL, + "Status" text NULL, + "ErrMessage" text NULL, + PRIMARY KEY ("Id") +); diff --git a/cmd/simgos-sync-migration/migrations/atlas.sum b/cmd/simgos-sync-migration/migrations/atlas.sum index 07e5fbaf..497ac414 100644 --- a/cmd/simgos-sync-migration/migrations/atlas.sum +++ b/cmd/simgos-sync-migration/migrations/atlas.sum @@ -1,6 +1,7 @@ -h1:keVmwgYtvwxSqkq+7nB0BA25JFYRAVBpBBu5eA4Q9Hw= +h1:UdPzQZ17yyNN9HVuyrFFHj5KjLj4m6/e7s9frkdpQVU= 20251113035508.sql h1:rjDlu6yDdy5xv6nrCOr7NialrLSLT23pzduYNq29Hf0= 20251114071129.sql h1:Z0GQ5bJo3C+tplaWzxT8n3J9HLkEaVsRVp5nn7bmYow= 20251117041601.sql h1:l/RPG5mObqCSBjO4mzG+wTq2ieSycvlfOSz4czpUdWY= -20251118082246.sql h1:VFnYls2DBC8tJm2aw0iBcbWGLsKezYdOHJJV9iS7MjI= -20251118082915.sql h1:tAm67fXrH+8IJCjKbJroIqc1uQyqCnuGJnQtLmw7D20= +20251118082246.sql h1:xLUwA+EvKWIg3X/TJvu7rqbtBzONiINfag5NJpMV29E= +20251118082915.sql h1:hP6FmUVFuADIN2cDg2Z1l7Wx7PQRb+IYQDvKD7J8VAM= +20251126115527.sql h1:+2bp2nWTTqaPpKKfy5ZYSr6b1nEUXFG3tIw4r3OEnAQ= diff --git a/internal/domain/main-entities/encounter/dto.go b/internal/domain/main-entities/encounter/dto.go index 849a5834..8dd9a0a1 100644 --- a/internal/domain/main-entities/encounter/dto.go +++ b/internal/domain/main-entities/encounter/dto.go @@ -1,14 +1,6 @@ package encounter import ( - eam "simrs-vx/internal/domain/main-entities/ambulatory" - edc "simrs-vx/internal/domain/main-entities/death-cause" - eem "simrs-vx/internal/domain/main-entities/emergency" - eed "simrs-vx/internal/domain/main-entities/encounter-document" - eip "simrs-vx/internal/domain/main-entities/inpatient" - eir "simrs-vx/internal/domain/main-entities/internal-reference" - er "simrs-vx/internal/domain/main-entities/rehab/base" - // std "time" @@ -24,10 +16,18 @@ import ( // internal - domain - main-entities evs "simrs-vx/internal/domain/bpjs-entities/vclaim-sep" + eam "simrs-vx/internal/domain/main-entities/ambulatory" ea "simrs-vx/internal/domain/main-entities/appointment" + edc "simrs-vx/internal/domain/main-entities/death-cause" ed "simrs-vx/internal/domain/main-entities/doctor" + eem "simrs-vx/internal/domain/main-entities/emergency" ee "simrs-vx/internal/domain/main-entities/employee" + eed "simrs-vx/internal/domain/main-entities/encounter-document" + eip "simrs-vx/internal/domain/main-entities/inpatient" + eir "simrs-vx/internal/domain/main-entities/internal-reference" + en "simrs-vx/internal/domain/main-entities/nurse" ep "simrs-vx/internal/domain/main-entities/patient" + er "simrs-vx/internal/domain/main-entities/rehab/base" es "simrs-vx/internal/domain/main-entities/specialist" ess "simrs-vx/internal/domain/main-entities/subspecialist" eu "simrs-vx/internal/domain/main-entities/unit" @@ -65,15 +65,15 @@ type CreateDto struct { } type TRujukan struct { - NoSep string `json:"noSep"` + NoSep string `json:"noSep"` // Surat Eligibilitas Peserta TglRujukan string `json:"tglRujukan"` - PpkDirujuk string `json:"ppkDirujuk"` - JnsPelayanan string `json:"jnsPelayanan"` + PpkDirujuk string `json:"ppkDirujuk"` // PPK (Provider Pelayanan Kesehatan) -> kode RS tujuan + JnsPelayanan string `json:"jnsPelayanan"` // Jenis pelayanan yang dimintakan; 1 = RawatInap; 2 = RawatJalan Catatan string `json:"catatan"` - DiagRujukan string `json:"diagRujukan"` - TipeRujukan string `json:"tipeRujukan"` - PoliRujukan string `json:"poliRujukan"` - User string `json:"user"` + DiagRujukan string `json:"diagRujukan"` // Kode Diagnosa + TipeRujukan string `json:"tipeRujukan"` // 0 = Rujukan Penuh; 1 = Rujukan Partial (hanya untuk tindakan tertentu); 2 = Balik (dikembalikan ke faskes asal) + PoliRujukan string `json:"poliRujukan"` // Kode Poli Tujuan + User string `json:"user"` // user yang membuat rujukan } type ReadListDto struct { @@ -105,24 +105,24 @@ type FilterDto struct { } type ReadDetailDto struct { - Id uint16 `json:"id"` + Id uint `json:"id"` Includes string `json:"includes"` } type UpdateDto struct { - Id uint16 `json:"id"` + Id uint `json:"id"` CreateDto } type UpdateStatusDto struct { - Id uint16 `json:"id"` + Id uint `json:"id"` StatusCode erc.DataStatusCode `json:"status_code"` pa.AuthInfo } type DeleteDto struct { - Id uint16 `json:"id"` + Id uint `json:"id"` pa.AuthInfo } @@ -147,7 +147,7 @@ type DischargeDto struct { type CheckinDto struct { Id uint `json:"id"` Responsible_Doctor_Code *string `json:"responsible_doctor_code"` - Adm_Employee_Id *uint `json:"adm_employee_id"` + Responsible_Nurse_Code *string `json:"responsible_nurse_code"` StartedAt *time.Time `json:"startedAt"` FinishedAt *time.Time `json:"finishedAt"` @@ -158,11 +158,18 @@ type SwitchUnitDto struct { Id uint `json:"id"` PolySwitchCode *ere.PolySwitchCode `json:"polySwitchCode"` InternalReferences *[]eir.CreateDto `json:"internalReferences" validate:"required"` + + Src_Doctor_Code *string `json:"-"` + Src_Nurse_Code *string `json:"-"` + pa.AuthInfo } -type ApproveUnitDto struct { - Id uint `json:"id"` - InternalReferences_Id uint16 `json:"internalReferences_id" validate:"required"` +type ApproveCancelUnitDto struct { + Id uint `json:"id"` + InternalReferences_Id uint `json:"internalReferences_id" validate:"required"` + Dst_Doctor_Code *string `json:"dst_doctor_code"` + + pa.AuthInfo } type ResponseDto struct { @@ -211,6 +218,8 @@ type ResponseDto struct { Rehab *er.Basic `json:"rehab,omitempty"` RehabChildren *[]er.Basic `json:"rehabChildren,omitempty"` EncounterDocuments *[]eed.EncounterDocument `json:"encounterDocuments,omitempty"` + Responsible_Nurse_Code *string `json:"responsible_nurse_code"` + Responsible_Nurse *en.Nurse `json:"responsible_nurse,omitempty"` } func (d Encounter) ToResponse() ResponseDto { @@ -258,6 +267,8 @@ func (d Encounter) ToResponse() ResponseDto { Rehab: d.Rehab, RehabChildren: d.RehabChildren, EncounterDocuments: d.EncounterDocuments, + Responsible_Nurse_Code: d.Responsible_Nurse_Code, + Responsible_Nurse: d.Responsible_Nurse, } resp.Main = d.Main return resp diff --git a/internal/domain/main-entities/encounter/entity.go b/internal/domain/main-entities/encounter/entity.go index 0cbf5da1..d1458f7c 100644 --- a/internal/domain/main-entities/encounter/entity.go +++ b/internal/domain/main-entities/encounter/entity.go @@ -20,6 +20,7 @@ import ( eip "simrs-vx/internal/domain/main-entities/inpatient" ei "simrs-vx/internal/domain/main-entities/insurance-company" eir "simrs-vx/internal/domain/main-entities/internal-reference" + en "simrs-vx/internal/domain/main-entities/nurse" ep "simrs-vx/internal/domain/main-entities/patient" er "simrs-vx/internal/domain/main-entities/rehab/base" es "simrs-vx/internal/domain/main-entities/specialist" @@ -77,6 +78,8 @@ type Encounter struct { EncounterDocuments *[]eed.EncounterDocument `json:"encounterDocuments,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"` GeneralConsents *[]egc.GeneralConsent `json:"generalConsents,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"` VclaimReference *evr.VclaimReference `json:"vclaimReference,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"` + Responsible_Nurse_Code *string `json:"responsible_nurse_code"` + Responsible_Nurse *en.Nurse `json:"responsible_nurse,omitempty" gorm:"foreignKey:Responsible_Nurse_Code;references:Code"` } func (d Encounter) IsDone() bool { diff --git a/internal/domain/main-entities/internal-reference/dto.go b/internal/domain/main-entities/internal-reference/dto.go index 6ce50a77..d3771c4d 100644 --- a/internal/domain/main-entities/internal-reference/dto.go +++ b/internal/domain/main-entities/internal-reference/dto.go @@ -9,10 +9,13 @@ import ( ) type CreateDto struct { - Encounter_Id *uint `json:"-"` - Unit_Code *string `json:"unit_code"` - Doctor_Code *string `json:"doctor_code"` - Status_Code erc.DataApprovalCode `json:"status_code"` + Encounter_Id *uint `json:"-"` + Unit_Code *string `json:"unit_code"` + Doctor_Code *string `json:"doctor_code"` + Nurse_Code *string `json:"nurse_code"` + Status_Code erc.DataApprovalCode `json:"status_code"` + SrcDoctor_Code *string `json:"srcDoctor_code"` + SrcNurse_Code *string `json:"srcNurse_code"` } type ReadListDto struct { @@ -29,17 +32,17 @@ type FilterDto struct { } type ReadDetailDto struct { - Id uint16 `json:"id"` + Id uint `json:"id"` Includes string `json:"includes"` } type UpdateDto struct { - Id uint16 `json:"id"` + Id uint `json:"id"` CreateDto } type DeleteDto struct { - Id uint16 `json:"id"` + Id uint `json:"id"` } type MetaDto struct { diff --git a/internal/domain/main-entities/internal-reference/entity.go b/internal/domain/main-entities/internal-reference/entity.go index ae6307bb..90859710 100644 --- a/internal/domain/main-entities/internal-reference/entity.go +++ b/internal/domain/main-entities/internal-reference/entity.go @@ -5,15 +5,22 @@ import ( ecore "simrs-vx/internal/domain/base-entities/core" ed "simrs-vx/internal/domain/main-entities/doctor" + en "simrs-vx/internal/domain/main-entities/nurse" eu "simrs-vx/internal/domain/main-entities/unit" ) type InternalReference struct { ecore.Main - Encounter_Id *uint `json:"encounter_id"` - Unit_Code *string `json:"unit_code"` - Unit *eu.Unit `json:"unit,omitempty" gorm:"foreignKey:Unit_Code;references:Code"` - Doctor_Code *string `json:"doctor_code"` - Doctor *ed.Doctor `json:"doctor,omitempty" gorm:"foreignKey:Doctor_Code;references:Code"` - Status_Code *erc.DataApprovalCode `json:"status_code"` + Encounter_Id *uint `json:"encounter_id"` + Unit_Code *string `json:"unit_code"` + Unit *eu.Unit `json:"unit,omitempty" gorm:"foreignKey:Unit_Code;references:Code"` + Doctor_Code *string `json:"doctor_code"` + Doctor *ed.Doctor `json:"doctor,omitempty" gorm:"foreignKey:Doctor_Code;references:Code"` + Status_Code *erc.DataApprovalCode `json:"status_code"` + SrcDoctor_Code *string `json:"srcDoctor_code"` + SrcDoctor *ed.Doctor `json:"srcDoctor,omitempty" gorm:"foreignKey:SrcDoctor_Code;references:Code"` + SrcNurse_Code *string `json:"srcNurse_code"` + SrcNurse *en.Nurse `json:"srcNurse,omitempty" gorm:"foreignKey:SrcNurse_Code;references:Code"` + Nurse_Code *string `json:"nurse_code"` + Nurse *en.Nurse `json:"nurse,omitempty" gorm:"foreignKey:Nurse_Code;references:Code"` } diff --git a/internal/domain/references/common/common.go b/internal/domain/references/common/common.go index 96febd75..3a449057 100644 --- a/internal/domain/references/common/common.go +++ b/internal/domain/references/common/common.go @@ -106,6 +106,7 @@ const ( DACNew DataApprovalCode = "new" DACApproved DataApprovalCode = "approved" DACRejected DataApprovalCode = "rejected" + DACCanceled DataApprovalCode = "canceled" PSCSuccess ProcessStatusCode = "success" PSCFailed ProcessStatusCode = "failed" diff --git a/internal/domain/references/encounter/encounter.go b/internal/domain/references/encounter/encounter.go index 6cf4e568..231baa9b 100644 --- a/internal/domain/references/encounter/encounter.go +++ b/internal/domain/references/encounter/encounter.go @@ -95,10 +95,10 @@ const ( RTCPrivate RefTypeCode = "private" // Swasta RTCBpjs RefTypeCode = "bpjs" // BPJS - APMCJkn AllPaymentMethodCode = "jkn" // JKN - APMCJkmm AllPaymentMethodCode = "jkmm" // JKMM - APMCSpm AllPaymentMethodCode = "spm" // SPM - APMCPks AllPaymentMethodCode = "pks" // PKS + APMCJkn AllPaymentMethodCode = "jkn" // JKN -> Jaminan Kesehatan Nasional -> BPJS Kesehatan + APMCJkmm AllPaymentMethodCode = "jkmm" // JKMM -> Jaminan Kesehatan Masyarakat Miskin -> Dibiayai oleh APBD daerah + APMCSpm AllPaymentMethodCode = "spm" // SPM -> Surat Pernyataan Miskin + APMCPks AllPaymentMethodCode = "pks" // PKS -> Perjanjian Kerjasama -> Pembayaran melalui instansi atau perusahaan yang memiliki kontrak dengan rumah sakit APMCUmum AllPaymentMethodCode = "umum" SRTCInternal SEPRefTypeCode = "internal" // Rujukan Internal diff --git a/internal/domain/simgos-entities/m-polihfis/entity.go b/internal/domain/simgos-entities/m-polihfis/entity.go index b9eb7b56..8bed236d 100644 --- a/internal/domain/simgos-entities/m-polihfis/entity.go +++ b/internal/domain/simgos-entities/m-polihfis/entity.go @@ -1,4 +1,4 @@ -package division +package m_polihfis type MPolihfis struct { Id uint `json:"id" gorm:"primaryKey;autoIncrement;column:id"` diff --git a/internal/domain/simgos-entities/m-poly/entity.go b/internal/domain/simgos-entities/m-poly/entity.go index 52fe20eb..aff4bc1e 100644 --- a/internal/domain/simgos-entities/m-poly/entity.go +++ b/internal/domain/simgos-entities/m-poly/entity.go @@ -1,7 +1,7 @@ package m_poly type MPoly struct { - Kode uint `json:"kode" gorm:"primaryKey;autoIncrement;column:kode"` + Kode uint `json:"kode" gorm:"primaryKey;column:kode"` Nama string `json:"nama" gorm:"column:nama"` Jenispoly uint `json:"jenispoly" gorm:"column:jenispoly"` } diff --git a/internal/domain/simgos-entities/t-pendaftaran/entity.go b/internal/domain/simgos-entities/t-pendaftaran/entity.go index 682aabeb..08222653 100644 --- a/internal/domain/simgos-entities/t-pendaftaran/entity.go +++ b/internal/domain/simgos-entities/t-pendaftaran/entity.go @@ -82,7 +82,6 @@ type TPendaftaran struct { DokterNameHfis *string `json:"dokter_name_hfis" gorm:"column:dokter_name_hfis"` DokterIdHfis *string `json:"dokter_id_hfis" gorm:"column:dokter_id_hfis"` StatusBridging *string `json:"status_bridging" gorm:"column:status_bridging"` - NoSpri *string `json:"no_spri" gorm:"column:no_spri"` } func (TPendaftaran) TableName() string { diff --git a/internal/domain/sync-entities/internal-reference/entity.go b/internal/domain/sync-entities/internal-reference/entity.go new file mode 100644 index 00000000..567e6489 --- /dev/null +++ b/internal/domain/sync-entities/internal-reference/entity.go @@ -0,0 +1,29 @@ +package internal_reference + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + erc "simrs-vx/internal/domain/references/common" + "time" +) + +type InternalReferenceLink struct { + ecore.Main + Simx_Id uint `json:"simx_id" gorm:"unique"` + Simgos_Id uint `json:"simgos_id" gorm:"unique"` +} + +type InternalReferenceSimxLog struct { + ecore.Main + Value *string `json:"value"` + Date *time.Time `json:"date"` + Status erc.ProcessStatusCode `json:"status"` + ErrMessage *string `json:"errMessage"` +} + +type InternalReferenceSimgosLog struct { + ecore.Main + Value *string `json:"value"` + Date *time.Time `json:"date"` + Status erc.ProcessStatusCode `json:"status"` + ErrMessage *string `json:"errMessage"` +} diff --git a/internal/infra/sync-cfg/tycovar.go b/internal/infra/sync-cfg/tycovar.go index ebc3ca19..a7534f82 100644 --- a/internal/infra/sync-cfg/tycovar.go +++ b/internal/infra/sync-cfg/tycovar.go @@ -1,9 +1,9 @@ package synccfg -var O PartnerCfg = PartnerCfg{} // old +var O SyncPartnerCfg = SyncPartnerCfg{} // old // Used by sync itself, so any partner should be stated here -type PartnerCfg struct { +type SyncPartnerCfg struct { OldSource string `yaml:"oldSource"` OldSecretKey string `yaml:"oldSecretKey"` OldHost string `yaml:"oldHost"` diff --git a/internal/infra/sync-consumer-cfg/tycovar.go b/internal/infra/sync-consumer-cfg/tycovar.go index 1a5cba26..f60cc588 100644 --- a/internal/infra/sync-consumer-cfg/tycovar.go +++ b/internal/infra/sync-consumer-cfg/tycovar.go @@ -1,11 +1,12 @@ package synccfg -var O SyncUrlCfg = SyncUrlCfg{} // old +var O SyncUrlCfg = SyncUrlCfg{} // new type SyncUrlCfg struct { Prefix string `yaml:"prefix"` TargetHost string `yaml:"targetHost"` Enable bool `yaml:"enable"` - Source string `yaml:"source"` + OldSource string `yaml:"oldSource"` + NewSource string `yaml:"newSource"` SecretKey string `yaml:"secretKey"` } diff --git a/internal/interface/main-handler/authentication/handler.go b/internal/interface/main-handler/authentication/handler.go index f0625af7..ffaf145b 100644 --- a/internal/interface/main-handler/authentication/handler.go +++ b/internal/interface/main-handler/authentication/handler.go @@ -9,12 +9,13 @@ import ( sp "github.com/karincake/semprit" sr "github.com/karincake/serabi" + is "simrs-vx/internal/infra/sync-consumer-cfg" + pa "simrs-vx/internal/lib/auth" + m "simrs-vx/internal/domain/main-entities/user" mf "simrs-vx/internal/domain/main-entities/user-fes" - pa "simrs-vx/internal/lib/auth" - s "simrs-vx/internal/use-case/main-use-case/authentication" - esga "simrs-vx/internal/domain/sync-entities/authentication" + s "simrs-vx/internal/use-case/main-use-case/authentication" ) func Login(w http.ResponseWriter, r *http.Request) { @@ -68,6 +69,10 @@ func Logout(w http.ResponseWriter, r *http.Request) { } func GuardMW(next http.Handler) http.Handler { + var ( + accessDetail *pa.AuthInfo + err error + ) return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Check if it's from sync credential := esga.CredentialDto{} @@ -75,23 +80,26 @@ func GuardMW(next http.Handler) http.Handler { credential.SecretKey = r.Header.Get("X-Sync-SecretKey") credential.UserName = r.Header.Get("X-Sync-UserName") if credential.Source != "" || credential.SecretKey != "" || credential.UserName != "" { - // TODO: ngecall fungsi untuk dapat dari DB menlengkapi authinfo - accessDetail, err := s.GetAuthInfoByUserName(credential.UserName) + // validate secretKey and source + if credential.SecretKey != is.O.SecretKey || credential.Source != is.O.OldSource { + rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "invalid consumer credential"}, nil) + return + } + + accessDetail, err = s.GetAuthInfoByUserName(credential.UserName) + if err != nil { + rw.WriteJSON(w, http.StatusUnauthorized, err.(d.FieldError), nil) + return + } + } else { + // Normal flow goes here + accessDetail, err = s.ExtractToken(r, s.AccessToken) if err != nil { rw.WriteJSON(w, http.StatusUnauthorized, err.(d.FieldError), nil) return } - ctx := context.WithValue(r.Context(), pa.AuthKey{}, accessDetail) - next.ServeHTTP(w, r.WithContext(ctx)) - return } - // Normal flow goes here - accessDetail, err := s.ExtractToken(r, s.AccessToken) - if err != nil { - rw.WriteJSON(w, http.StatusUnauthorized, err.(d.FieldError), nil) - return - } ctx := context.WithValue(r.Context(), pa.AuthKey{}, accessDetail) next.ServeHTTP(w, r.WithContext(ctx)) }) diff --git a/internal/interface/main-handler/encounter/handler.go b/internal/interface/main-handler/encounter/handler.go index 0c87b7b2..7ac31393 100644 --- a/internal/interface/main-handler/encounter/handler.go +++ b/internal/interface/main-handler/encounter/handler.go @@ -64,7 +64,7 @@ func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) { } dto := e.ReadDetailDto{} sf.UrlQueryParam(&dto, *r.URL) - dto.Id = uint16(id) + dto.Id = uint(id) res, err := u.ReadDetail(dto) rw.DataResponse(w, res, err) } @@ -84,7 +84,7 @@ func (obj myBase) Update(w http.ResponseWriter, r *http.Request) { if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { return } - dto.Id = uint16(id) + dto.Id = uint(id) dto.AuthInfo = *authInfo res, err := u.Update(dto) @@ -103,7 +103,7 @@ func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) { } dto := e.DeleteDto{} - dto.Id = uint16(id) + dto.Id = uint(id) dto.AuthInfo = *authInfo res, err := u.Delete(dto) @@ -174,9 +174,15 @@ func (obj myBase) Process(w http.ResponseWriter, r *http.Request) { return } + authInfo, err := pa.GetAuthInfo(r) + if err != nil { + rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil) + } + dto := e.UpdateStatusDto{ - Id: uint16(id), + Id: uint(id), StatusCode: erc.DSCProcess, + AuthInfo: *authInfo, } res, err := u.UpdateStatusCode(dto) @@ -195,11 +201,11 @@ func (obj myBase) Cancel(w http.ResponseWriter, r *http.Request) { } dto := e.UpdateStatusDto{ - Id: uint16(id), + Id: uint(id), StatusCode: erc.DSCCancel, + AuthInfo: *authInfo, } - dto.AuthInfo = *authInfo res, err := u.UpdateStatusCode(dto) rw.DataResponse(w, res, err) } @@ -211,7 +217,7 @@ func (obj myBase) Reject(w http.ResponseWriter, r *http.Request) { } dto := e.UpdateStatusDto{ - Id: uint16(id), + Id: uint(id), StatusCode: erc.DSCRejected, } @@ -226,7 +232,7 @@ func (obj myBase) Skip(w http.ResponseWriter, r *http.Request) { } dto := e.UpdateStatusDto{ - Id: uint16(id), + Id: uint(id), StatusCode: erc.DSCSkipped, } @@ -250,13 +256,19 @@ func (obj myBase) RequestSwitchUnit(w http.ResponseWriter, r *http.Request) { return } + authInfo, err := pa.GetAuthInfo(r) + if err != nil { + rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil) + } + + dto.AuthInfo = *authInfo dto.Id = uint(id) res, err := u.RequestSwitchUnit(dto) rw.DataResponse(w, res, err) } func (obj myBase) ApproveSwitchUnit(w http.ResponseWriter, r *http.Request) { - dto := e.ApproveUnitDto{} + dto := e.ApproveCancelUnitDto{} id := rw.ValidateInt(w, "id", r.PathValue("id")) if id <= 0 { return @@ -266,7 +278,37 @@ func (obj myBase) ApproveSwitchUnit(w http.ResponseWriter, r *http.Request) { return } + authInfo, err := pa.GetAuthInfo(r) + if err != nil { + rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil) + } + + dto.AuthInfo = *authInfo dto.Id = uint(id) + res, err := u.ApproveSwitchUnit(dto) rw.DataResponse(w, res, err) } + +func (obj myBase) CancelSwitchUnit(w http.ResponseWriter, r *http.Request) { + dto := e.ApproveCancelUnitDto{} + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id <= 0 { + return + } + + 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 + dto.Id = uint(id) + + res, err := u.CancelSwitchUnit(dto) + rw.DataResponse(w, res, err) +} diff --git a/internal/interface/main-handler/encounter/request-validation.go b/internal/interface/main-handler/encounter/request-validation.go index 79cc832c..67d8a63c 100644 --- a/internal/interface/main-handler/encounter/request-validation.go +++ b/internal/interface/main-handler/encounter/request-validation.go @@ -59,6 +59,22 @@ func validateRequestCheckIn(w http.ResponseWriter, i e.CheckinDto) (valid bool) } func validateRequestSwitchUnit(w http.ResponseWriter, i e.SwitchUnitDto) (valid bool) { + // validate poly-switch-code + if i.PolySwitchCode == nil { + rw.DataResponse(w, nil, d.FieldError{ + Code: dataValidationFail, + Message: fmt.Sprintf("polySwitchCode required"), + }) + return + } + + if *i.PolySwitchCode != ere.PSCConsulPoly && *i.PolySwitchCode != ere.PSCConsulExecutive { + rw.DataResponse(w, nil, d.FieldError{ + Code: dataValidationFail, + Message: "invalid PolySwitchCode", + }) + } + if i.InternalReferences == nil { rw.DataResponse(w, nil, d.FieldError{ Code: dataValidationFail, diff --git a/internal/interface/main-handler/internal-reference/handler.go b/internal/interface/main-handler/internal-reference/handler.go index c46c974d..a3193501 100644 --- a/internal/interface/main-handler/internal-reference/handler.go +++ b/internal/interface/main-handler/internal-reference/handler.go @@ -39,7 +39,7 @@ func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) { dto := eir.ReadDetailDto{} sf.UrlQueryParam(&dto, *r.URL) - dto.Id = uint16(id) + dto.Id = uint(id) res, err := uir.ReadDetail(dto) rw.DataResponse(w, res, err) } @@ -54,7 +54,7 @@ func (obj myBase) Update(w http.ResponseWriter, r *http.Request) { if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { return } - dto.Id = uint16(id) + dto.Id = uint(id) res, err := uir.Update(dto) rw.DataResponse(w, res, err) } @@ -66,7 +66,7 @@ func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) { } dto := eir.DeleteDto{} - dto.Id = uint16(id) + dto.Id = uint(id) res, err := uir.Delete(dto) rw.DataResponse(w, res, err) } diff --git a/internal/interface/main-handler/main-handler.go b/internal/interface/main-handler/main-handler.go index c8f3fd00..a763f40b 100644 --- a/internal/interface/main-handler/main-handler.go +++ b/internal/interface/main-handler/main-handler.go @@ -175,6 +175,7 @@ func SetRoutes() http.Handler { "PATCH /{id}/skip": encounter.O.Skip, "PATCH /{id}/req-switch-unit": encounter.O.RequestSwitchUnit, "PATCH /{id}/approve-switch-unit": encounter.O.ApproveSwitchUnit, + "PATCH /{id}/cancel-switch-unit": encounter.O.CancelSwitchUnit, }) hk.GroupRoutes("/v1/mcu-order", r, auth.GuardMW, hk.MapHandlerFunc{ "GET /": mcuorder.O.GetList, diff --git a/internal/interface/migration/simgossync-entities.go b/internal/interface/migration/simgossync-entities.go index b10c8607..7b37a842 100644 --- a/internal/interface/migration/simgossync-entities.go +++ b/internal/interface/migration/simgossync-entities.go @@ -5,6 +5,7 @@ import ( division "simrs-vx/internal/domain/sync-entities/division" encounter "simrs-vx/internal/domain/sync-entities/encounter" installation "simrs-vx/internal/domain/sync-entities/installation" + internalreference "simrs-vx/internal/domain/sync-entities/internal-reference" patient "simrs-vx/internal/domain/sync-entities/patient" specialist "simrs-vx/internal/domain/sync-entities/specialist" subspecialist "simrs-vx/internal/domain/sync-entities/subspecialist" @@ -34,5 +35,8 @@ func getSyncEntities() []any { &encounter.EncounterLink{}, &encounter.EncounterSimxLog{}, &encounter.EncounterSimgosLog{}, + &internalreference.InternalReferenceLink{}, + &internalreference.InternalReferenceSimxLog{}, + &internalreference.InternalReferenceSimgosLog{}, } } diff --git a/internal/interface/simgos-sync-handler/new/encounter/handler.go b/internal/interface/simgos-sync-handler/new/encounter/handler.go index e6b0515a..aef2f7d2 100644 --- a/internal/interface/simgos-sync-handler/new/encounter/handler.go +++ b/internal/interface/simgos-sync-handler/new/encounter/handler.go @@ -51,7 +51,7 @@ func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) { } dto := e.DeleteDto{} - dto.Id = uint16(id) + dto.Id = uint(id) res, err := u.Delete(dto) rw.DataResponse(w, res, err) @@ -77,12 +77,42 @@ func (obj myBase) Checkout(w http.ResponseWriter, r *http.Request) { rw.DataResponse(w, res, err) } -func (obj myBase) Cancel(w http.ResponseWriter, r *http.Request) { +func (obj myBase) UpdateStatus(w http.ResponseWriter, r *http.Request) { dto := e.Encounter{} if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { return } - res, err := u.Cancel(dto) + res, err := u.UpdateStatus(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) RequestSwitchUnit(w http.ResponseWriter, r *http.Request) { + dto := e.Encounter{} + if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { + return + } + + res, err := u.RequestSwitchUnit(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) ApproveSwitchUnit(w http.ResponseWriter, r *http.Request) { + dto := e.ApproveCancelUnitDto{} + if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { + return + } + + res, err := u.ApproveSwitchUnit(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) CancelSwitchUnit(w http.ResponseWriter, r *http.Request) { + dto := e.ApproveCancelUnitDto{} + if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { + return + } + + res, err := u.CancelSwitchUnit(dto) rw.DataResponse(w, res, err) } diff --git a/internal/interface/simgos-sync-handler/simgos-sync-handler.go b/internal/interface/simgos-sync-handler/simgos-sync-handler.go index bd675978..f120b1cb 100644 --- a/internal/interface/simgos-sync-handler/simgos-sync-handler.go +++ b/internal/interface/simgos-sync-handler/simgos-sync-handler.go @@ -6,7 +6,7 @@ import ( /******************** infra ********************/ gs "simrs-vx/internal/infra/gorm-setting" simgosdb "simrs-vx/internal/infra/simgos-db" - sync "simrs-vx/internal/infra/sync-consumer-cfg" + sync "simrs-vx/internal/infra/sync-cfg" /******************** pkg ********************/ cmw "simrs-vx/pkg/cors-manager-mw" @@ -60,13 +60,16 @@ func SetRoutes() http.Handler { "POST /nomr": patient.O.GenerateNomr, }) hk.GroupRoutes(prefixnew+"/v1/encounter", r, hk.MapHandlerFunc{ - "POST /": encounter.O.Create, - "POST /log": encounter.O.CreateLog, - "PATCH /{id}": encounter.O.Update, - "DELETE /{id}": encounter.O.Delete, - "PATCH /{id}/checkin": encounter.O.Checkin, - "PATCH /{id}/checkout": encounter.O.Checkout, - "PATCH /{id}/cancel": encounter.O.Cancel, + "POST /": encounter.O.Create, + "POST /log": encounter.O.CreateLog, + "PATCH /{id}": encounter.O.Update, + "DELETE /{id}": encounter.O.Delete, + "PATCH /{id}/checkin": encounter.O.Checkin, + "PATCH /{id}/checkout": encounter.O.Checkout, + "PATCH /{id}/update-status": encounter.O.UpdateStatus, + "PATCH /{id}/req-switch-unit": encounter.O.RequestSwitchUnit, + "PATCH /{id}/approve-switch-unit": encounter.O.ApproveSwitchUnit, + "PATCH /{id}/cancel-switch-unit": encounter.O.CancelSwitchUnit, }) /******************** SvcToNew ******************/ diff --git a/internal/use-case/main-use-case/authentication/case.go b/internal/use-case/main-use-case/authentication/case.go index 2f47c43d..04a88c9b 100644 --- a/internal/use-case/main-use-case/authentication/case.go +++ b/internal/use-case/main-use-case/authentication/case.go @@ -180,9 +180,7 @@ func VerifyToken(r *http.Request, tokenType TokenType) (data *jwt.Token, errCode } func GetAuthInfoByUserName(userName string) (data *pa.AuthInfo, err error) { - // disini isi var `data` - // return error jika terjadi apa2 - return + return getAuthByUserName(userName) } func ExtractToken(r *http.Request, tokenType TokenType) (data *pa.AuthInfo, err error) { diff --git a/internal/use-case/main-use-case/authentication/helper.go b/internal/use-case/main-use-case/authentication/helper.go index 7af3afa5..d8c54751 100644 --- a/internal/use-case/main-use-case/authentication/helper.go +++ b/internal/use-case/main-use-case/authentication/helper.go @@ -2,6 +2,7 @@ package authentication import ( "fmt" + pa "simrs-vx/internal/lib/auth" "strconv" "time" @@ -10,10 +11,13 @@ import ( dg "github.com/karincake/apem/db-gorm-pg" ms "github.com/karincake/apem/ms-redis" d "github.com/karincake/dodol" + gh "github.com/karincake/getuk" l "github.com/karincake/lepet" pl "simrs-vx/pkg/logger" + erg "simrs-vx/internal/domain/references/organization" + edp "simrs-vx/internal/domain/main-entities/division-position" ed "simrs-vx/internal/domain/main-entities/doctor" ee "simrs-vx/internal/domain/main-entities/employee" @@ -26,7 +30,6 @@ import ( essp "simrs-vx/internal/domain/main-entities/subspecialist-position" eup "simrs-vx/internal/domain/main-entities/unit-position" eu "simrs-vx/internal/domain/main-entities/user" - erg "simrs-vx/internal/domain/references/organization" udp "simrs-vx/internal/use-case/main-use-case/division-position" uip "simrs-vx/internal/use-case/main-use-case/installation-position" @@ -334,3 +337,71 @@ func populateRoles(user *eu.User, input eu.LoginDto, atClaims jwt.MapClaims, out return nil } + +func getAuthByUserName(username string) (auth *pa.AuthInfo, err error) { + // get employee + emp := ee.Employee{} + if err = dg.I. + Joins(`JOIN "User" u ON u."Id" = "Employee"."User_Id"`). + Where(`u."Name" = ?`, username). + Scopes(gh.Preload("User")). + First(&emp).Error; err != nil { + return nil, err + } + + auth = &pa.AuthInfo{ + User_Id: *emp.User_Id, + User_Name: emp.User.Name, + User_ContractPosition_Code: string(emp.User.ContractPosition_Code), + Employee_Position_Code: strPtr(string(*emp.Position_Code)), + Employee_Id: &emp.Id, + Sync: true, + } + + // set map table + tableMap := map[erg.EmployeePositionCode]string{ + erg.EPCDoc: "Doctor", + erg.EPCNur: "Nurse", + erg.EPCMwi: "Midwife", + erg.EPCNut: "Nutritionist", + erg.EPCLab: "Laborant", + erg.EPCPha: "Pharmachist", + } + + table := tableMap[*emp.Position_Code] + if table == "" { + return + } + + type CodeResult struct { + Code string + } + var result CodeResult + + err = dg.I.Table(table). + Select("Code"). + Where("\"Employee_Id\" = ?", emp.Id). + First(&result).Error + if err != nil { + return nil, err + } + + // set map for code + setterMap := map[erg.EmployeePositionCode]func(string){ + erg.EPCDoc: func(v string) { auth.Doctor_Code = &v }, + erg.EPCNur: func(v string) { auth.Nurse_Code = &v }, + erg.EPCMwi: func(v string) { auth.Midwife_Code = &v }, + erg.EPCNut: func(v string) { auth.Nutritionist_Code = &v }, + erg.EPCLab: func(v string) { auth.Laborant_Code = &v }, + erg.EPCPha: func(v string) { auth.Pharmachist_Code = &v }, + } + + setter := setterMap[*emp.Position_Code] + setter(result.Code) + + return +} + +func strPtr(s string) *string { + return &s +} diff --git a/internal/use-case/main-use-case/doctor/lib.go b/internal/use-case/main-use-case/doctor/lib.go index 12b62176..827802fa 100644 --- a/internal/use-case/main-use-case/doctor/lib.go +++ b/internal/use-case/main-use-case/doctor/lib.go @@ -87,6 +87,9 @@ func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e if input.Id != nil { tx = tx.Where("\"Id\" = ?", input.Id) } + if input.Code != nil { + tx = tx.Where("\"Code\" = ?", input.Code) + } if err := tx.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/edu-assessment/case.go b/internal/use-case/main-use-case/edu-assessment/case.go index 230f0679..525274ca 100644 --- a/internal/use-case/main-use-case/edu-assessment/case.go +++ b/internal/use-case/main-use-case/edu-assessment/case.go @@ -37,7 +37,7 @@ func Create(input e.CreateDto) (*d.Data, error) { } // validate encounter_id - _, err := ue.ReadDetail(ee.ReadDetailDto{Id: uint16(*input.Encounter_Id)}) + _, err := ue.ReadDetail(ee.ReadDetailDto{Id: *input.Encounter_Id}) if err != nil { return err } diff --git a/internal/use-case/main-use-case/encounter/case.go b/internal/use-case/main-use-case/encounter/case.go index 438ad45c..bc4ba1ba 100644 --- a/internal/use-case/main-use-case/encounter/case.go +++ b/internal/use-case/main-use-case/encounter/case.go @@ -19,19 +19,15 @@ import ( erg "simrs-vx/internal/domain/references/organization" ev "simrs-vx/internal/domain/bpjs-entities/vclaim-reference" - eaeh "simrs-vx/internal/domain/main-entities/adm-employee-hist" edc "simrs-vx/internal/domain/main-entities/death-cause" e "simrs-vx/internal/domain/main-entities/encounter" eir "simrs-vx/internal/domain/main-entities/internal-reference" - erdh "simrs-vx/internal/domain/main-entities/responsible-doctor-hist" es "simrs-vx/internal/domain/main-entities/soapi" esync "simrs-vx/internal/domain/sync-entities/log" uv "simrs-vx/internal/use-case/bpjs-use-case/vclaim-reference" - uaeh "simrs-vx/internal/use-case/main-use-case/adm-employee-hist" udc "simrs-vx/internal/use-case/main-use-case/death-cause" uir "simrs-vx/internal/use-case/main-use-case/internal-reference" - urdh "simrs-vx/internal/use-case/main-use-case/responsible-doctor-hist" us "simrs-vx/internal/use-case/main-use-case/soapi" ) @@ -118,7 +114,6 @@ func Create(input e.CreateDto) (*d.Data, error) { // insert vclaimReference if vr := input.VclaimReference; vr != nil { t, _ := time.Parse("2006-01-02", vr.TglRujukan) - _, err = uv.CreateData(ev.CreateDto{ Encounter_Id: &data.Id, Date: &t, @@ -127,17 +122,11 @@ func Create(input e.CreateDto) (*d.Data, error) { Number: &vr.NoSep}, &event, tx) } - // insert adm_employee_hist (employee with role reg for create) - if _, err = uaeh.CreateData(eaeh.CreateDto{ - Encounter_Id: &data.Id, - Employee_Id: data.Adm_Employee_Id, - StartedAt: &now}, &event, tx); err != nil { - return err - } - dataEncounter, err := ReadDetailData(e.ReadDetailDto{ - Id: uint16(data.Id), - Includes: "Adm_Employee.User,Patient.Person.Relatives,Patient.Person.VclaimMember,VclaimReference"}, + Id: data.Id, + Includes: "Adm_Employee.User,Patient.Person.Relatives," + + "Patient.Person.VclaimMember,VclaimReference," + + "Patient.Person.Contacts,Patient.Person.Addresses"}, &event, tx) if err != nil { return err @@ -311,7 +300,7 @@ func Update(input e.UpdateDto) (*d.Data, error) { } dataEncounter, err := ReadDetailData(e.ReadDetailDto{ - Id: uint16(data.Id), + Id: data.Id, Includes: "Adm_Employee.User,Patient.Person.Relatives,Patient.Person.VclaimMember"}, &event, tx) if err != nil { @@ -429,7 +418,7 @@ func Delete(input e.DeleteDto) (*d.Data, error) { } func CheckOut(input e.DischargeDto) (*d.Data, error) { - rdDto := e.ReadDetailDto{Id: uint16(input.Id), Includes: "Ambulatory,Rehab"} + rdDto := e.ReadDetailDto{Id: input.Id, Includes: "Ambulatory,Rehab,InternalReferences"} var data *e.Encounter var err error @@ -441,7 +430,7 @@ func CheckOut(input e.DischargeDto) (*d.Data, error) { // Start log pl.SetLogInfo(&event, input, "started", "checkOut") - roleAllowed := []string{string(erg.EPCNur), string(erg.EPCDoc)} + roleAllowed := []string{string(erg.EPCNur)} err = validateAuth(input.AuthInfo, roleAllowed, "checkOut-encounter", &event) if err != nil { return nil, err @@ -466,7 +455,7 @@ func CheckOut(input e.DischargeDto) (*d.Data, error) { } if data.Ambulatory != nil && (data.Ambulatory.Class_Code == ere.ACCReg || data.Ambulatory.Class_Code == ere.ACCRehab) { - // validate if soapi exist + // Validate SOAPI completeness: abort checkout if any required SOAPI is missing. if err = getSoapiByTypeCode(data, &event, "check-out"); err != nil { return err } @@ -478,12 +467,13 @@ func CheckOut(input e.DischargeDto) (*d.Data, error) { } } } else { - // chemo TBC + // TODO: chemo TBC (to be confirm) if err := checkSoapiByDocExists(data.Id, &event, tx); err != nil { return err } } + // update encounter if err := updateDischargeData(input, data, &event, tx); err != nil { return err } @@ -498,16 +488,6 @@ func CheckOut(input e.DischargeDto) (*d.Data, error) { } } - // update finishedAt in latest responsible_doctor_hist - if err = updateLatestResponsibleDoctorHist(e.CheckinDto{Id: input.Id, FinishedAt: &now}, &event, tx); err != nil { - return err - } - - // update finishedAt in latest adm_employee_hist - if err = updateLatestAdmEmployeeHist(e.CheckinDto{Id: input.Id, FinishedAt: &now}, &event, tx); err != nil { - return err - } - // insert data death-cause if *input.Discharge_Method_Code == ere.DMCDeath { if _, err = udc.CreateData(edc.CreateDto{Encounter_Id: &input.Id, Value: input.DeathCause}, &event, tx); err != nil { @@ -515,10 +495,23 @@ func CheckOut(input e.DischargeDto) (*d.Data, error) { } } - dataEncounter, err := ReadDetailData(e.ReadDetailDto{ - Id: uint16(data.Id), - Includes: "DeathCause"}, - &event, tx) + // perform additional validation when discharge_method_code is "consul-poly" or "consul-executive" + if *data.Discharge_Method_Code == ere.DMCConsulPoly || *data.Discharge_Method_Code == ere.DMCConsulExecutive { + for _, v := range *data.InternalReferences { + if *v.Status_Code == erc.DACNew { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-state-mismatch", + Detail: "checkout is not allowed because the internal-reference status is 'new'", + Raw: errors.New("internal-referral status not done yet"), + } + return pl.SetLogError(&event, input) + } + } + } + + // read the newest data encounter for sync + dataEncounter, err := ReadDetailData(e.ReadDetailDto{Id: data.Id, Includes: "DeathCause"}, &event, tx) if err != nil { return err } @@ -560,6 +553,14 @@ func UpdateStatusCode(input e.UpdateStatusDto) (*d.Data, error) { // Start log pl.SetLogInfo(&event, input, "started", "update") + + // TODO: Only "supervisi pendaftaran" could cancel encounter + roleAllowed := []string{string(erg.EPCReg), string(erg.EPCNur), string(erg.EPCDoc)} + err = validateAuth(input.AuthInfo, roleAllowed, "update-status-encounter", &event) + if err != nil { + return nil, err + } + mwRunner := newMiddlewareRunner(&event) err = dg.I.Transaction(func(tx *gorm.DB) error { @@ -581,34 +582,6 @@ func UpdateStatusCode(input e.UpdateStatusDto) (*d.Data, error) { if input.StatusCode == erc.DSCCancel { // TODO: Prevent cancellation if the billing has been verified - // TODO: Only "supervisi pendaftaran" could cancel encounter - roleAllowedToCancel := []string{ - string(erg.EPCReg), - string(erg.EPCNur), - string(erg.EPCDoc), - } - - // check if user has employee position - if !input.AuthInfo.HasEmployeePosition() { - event.Status = "failed" - event.ErrInfo = pl.ErrorInfo{ - Code: "auth-forbidden", - Detail: "user has no employee position", - Raw: errors.New("authentication failed"), - } - return pl.SetLogError(&event, input) - } - - if input.AuthInfo.Employee_Position_Code != nil && !pu.Contains(roleAllowedToCancel, *input.AuthInfo.Employee_Position_Code) { - event.Status = "failed" - event.ErrInfo = pl.ErrorInfo{ - Code: "auth-forbidden", - Detail: "user position is not allowed, only user with registration, nurse, or doctor position is allowed to cancel encounter", - Raw: errors.New("authentication failed"), - } - return pl.SetLogError(&event, input) - } - // Prevent cancellation if soapi exist dataSoapi, _, err := us.ReadListData(es.ReadListDto{ FilterDto: es.FilterDto{Encounter_Id: &data.Id}}, &event, tx) @@ -627,11 +600,13 @@ func UpdateStatusCode(input e.UpdateStatusDto) (*d.Data, error) { } } - if err := UpdateStatusData(input, data, &event, tx); err != nil { + if err := UpdateStatusData(input, &event, tx); err != nil { return err } - if input.StatusCode == erc.DSCCancel { + if input.StatusCode == erc.DSCProcess || input.StatusCode == erc.DSCCancel { + data.Status_Code = input.StatusCode + mwRunner.setMwType(pu.MWTPre) // Run pre-middleware if err := mwRunner.RunUpdateStatusMiddleware(updatestatusEncounter, data); err != nil { @@ -642,10 +617,12 @@ func UpdateStatusCode(input e.UpdateStatusDto) (*d.Data, error) { return nil }) - if err != nil { + if err = runLogMiddleware(err, input, mwRunner); err != nil { return nil, err } + pl.SetLogInfo(&event, nil, "complete") + return &d.Data{ Meta: d.IS{ "source": source, @@ -658,7 +635,7 @@ func UpdateStatusCode(input e.UpdateStatusDto) (*d.Data, error) { } func CheckIn(input e.CheckinDto) (*d.Data, error) { - rdDto := e.ReadDetailDto{Id: uint16(input.Id), Includes: "Rehab,Ambulatory"} + rdDto := e.ReadDetailDto{Id: input.Id, Includes: "Rehab,Ambulatory"} var data *e.Encounter var err error @@ -675,10 +652,10 @@ func CheckIn(input e.CheckinDto) (*d.Data, error) { if err != nil { return nil, err } - input.Adm_Employee_Id = input.AuthInfo.Employee_Id + input.Responsible_Nurse_Code = input.AuthInfo.Nurse_Code // validate foreign key - if err := validateForeignKey(input); err != nil { + if err := validateForeignKey(input, &event); err != nil { return nil, err } @@ -705,7 +682,7 @@ func CheckIn(input e.CheckinDto) (*d.Data, error) { return pl.SetLogError(&event, input) } - // validate if soapi exist + // prevent repeated check-in. If SOAPI already exists, block the check-in process. if data.Ambulatory != nil && (data.Ambulatory.Class_Code == ere.ACCReg || data.Ambulatory.Class_Code == ere.ACCRehab) { err = getSoapiByTypeCode(data, &event, "check-in") if err != nil { @@ -713,39 +690,13 @@ func CheckIn(input e.CheckinDto) (*d.Data, error) { } } - // Upsert responsible_doctor_hist if responsible_doctor_code has changed - if data.Responsible_Doctor_Code == nil || *input.Responsible_Doctor_Code != *data.Responsible_Doctor_Code { - // upsert responsibleDoctorHist - if err = upsertResponsibleDoctorHist(erdh.CreateDto{ - Encounter_Id: &data.Id, - Doctor_Code: input.Responsible_Doctor_Code, - StartedAt: input.StartedAt, - }, &event, tx); err != nil { - return err - } - } - - // Upsert adm_employee_hist if adm_employee_id has changed - if *input.Adm_Employee_Id != *data.Adm_Employee_Id { - // upsert admEmployeeHist - if err = upsertAdmEmployeeHist(eaeh.CreateDto{ - Encounter_Id: &data.Id, - Employee_Id: input.Adm_Employee_Id, - StartedAt: input.StartedAt, - }, &event, tx); err != nil { - return err - } - } - // update encounter data if err := updateCheckInData(input, data, &event, tx); err != nil { return err } - dataEncounter, err := ReadDetailData(e.ReadDetailDto{ - Id: uint16(data.Id), - Includes: "Adm_Employee.User"}, - &event, tx) + // read the newest data encounter for sync + dataEncounter, err := ReadDetailData(e.ReadDetailDto{Id: data.Id, Includes: "Responsible_Nurse.Employee.User"}, &event, tx) if err != nil { return err } @@ -776,7 +727,7 @@ func CheckIn(input e.CheckinDto) (*d.Data, error) { } func RequestSwitchUnit(input e.SwitchUnitDto) (*d.Data, error) { - rdDto := e.ReadDetailDto{Id: uint16(input.Id), Includes: "Responsible_Doctor"} + rdDto := e.ReadDetailDto{Id: input.Id, Includes: "Responsible_Nurse.Employee.User,Responsible_Doctor.Employee"} var data *e.Encounter var err error @@ -809,23 +760,33 @@ func RequestSwitchUnit(input e.SwitchUnitDto) (*d.Data, error) { return nil, err } + roleAllowed := []string{string(erg.EPCNur)} + err = validateAuth(input.AuthInfo, roleAllowed, "request-switch-poly", &event) + if err != nil { + return nil, err + } + input.Src_Nurse_Code = input.AuthInfo.Nurse_Code + + mwRunner := newMiddlewareRunner(&event) + 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 } + input.Src_Doctor_Code = data.Responsible_Doctor_Code - //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) - //} + 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) + } - // verify Soapi exist for current responsible doctor + // Poly-Switch-Requests can only be processed if the previous responsible doctor has completed their SOAPI. dataSoapi, err := getSoapiByResponsibleDoctor(*data, &event) if err != nil { return err @@ -839,21 +800,36 @@ func RequestSwitchUnit(input e.SwitchUnitDto) (*d.Data, error) { return pl.SetLogError(&event, input) } - // bulk internal references - if err := uir.CreateBulkData(*input.InternalReferences, input.Id, &event, tx); err != nil { + // update encounter discharge_method_code + if err = UpdateDischargeMethod(input, &event, tx); err != nil { return err } - // TODO: update status encounter, finishedAt + // bulk internal references + if err := uir.CreateBulkData(&input, &event, tx); err != nil { + return err + } - pl.SetLogInfo(&event, nil, "complete") + // read the newest data encounter for sync + dataEncounter, err := ReadDetailData(e.ReadDetailDto{Id: data.Id, Includes: "InternalReferences,Responsible_Nurse.Employee.User"}, &event, tx) + if err != nil { + return err + } + + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunRequestSwitchUnitMiddleware(requestSwitchEncounter, dataEncounter); err != nil { + return err + } return nil }) - if err != nil { + if err = runLogMiddleware(err, input, mwRunner); err != nil { return nil, err } + pl.SetLogInfo(&event, nil, "complete") + return &d.Data{ Meta: d.IS{ "source": source, @@ -864,10 +840,12 @@ func RequestSwitchUnit(input e.SwitchUnitDto) (*d.Data, error) { }, nil } -func ApproveSwitchUnit(input e.ApproveUnitDto) (*d.Data, error) { - rdDto := e.ReadDetailDto{Id: uint16(input.Id), Includes: "Responsible_Doctor"} - var data *e.Encounter - var err error +func ApproveSwitchUnit(input e.ApproveCancelUnitDto) (*d.Data, error) { + rdDto := e.ReadDetailDto{Id: input.Id, Includes: "Responsible_Doctor.Employee"} + var ( + data *e.Encounter + err error + ) event := pl.Event{ Feature: "ApproveSwitchUnit", @@ -877,13 +855,31 @@ func ApproveSwitchUnit(input e.ApproveUnitDto) (*d.Data, error) { // Start log pl.SetLogInfo(&event, input, "started", "approveSwitchUnit") + roleAllowed := []string{string(erg.EPCNur)} + err = validateAuth(input.AuthInfo, roleAllowed, "request-switch-poly", &event) + if err != nil { + return nil, err + } + + mwRunner := newMiddlewareRunner(&event) + 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 } - // get internal reference + 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) + } + + // get internalReference based on internalReferences_Id irData, err := uir.ReadDetailData(eir.ReadDetailDto{ Id: input.InternalReferences_Id, Includes: "Doctor"}, &event, tx) if err != nil { @@ -900,17 +896,7 @@ func ApproveSwitchUnit(input e.ApproveUnitDto) (*d.Data, error) { return pl.SetLogError(&event, input) } - //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) - //} - - // verify Soapi exist for current responsible doctor + // Approve-Switch-Requests can only be processed if the previous responsible doctor has completed their SOAPI. dataSoapi, err := getSoapiByResponsibleDoctor(*data, &event) if err != nil { return err @@ -924,51 +910,130 @@ func ApproveSwitchUnit(input e.ApproveUnitDto) (*d.Data, error) { return pl.SetLogError(&event, input) } + // Set doctor_code; nil indicates no change. + if input.Dst_Doctor_Code == nil { + input.Dst_Doctor_Code = irData.Doctor_Code + } + // update internal reference if err = uir.UpdateData(eir.UpdateDto{ Id: input.InternalReferences_Id, CreateDto: eir.CreateDto{ - Encounter_Id: &input.Id, - Doctor_Code: irData.Doctor_Code, - Unit_Code: irData.Unit_Code, - Status_Code: erc.DACApproved, - }}, irData, &event, tx); err != nil { + Status_Code: erc.DACApproved, + Doctor_Code: input.Dst_Doctor_Code, + Nurse_Code: input.Nurse_Code}}, irData, &event, tx); err != nil { return err } // update encounter - if err = updateEncounterApproveSwitchUnit(*irData, &event, tx); err != nil { + if err = updateEncounterApproveSwitchUnit(input, &event, tx); err != nil { return err } - // update latest responsible doctor hist - if err = updateLatestResponsibleDoctorHist(e.CheckinDto{Id: input.Id, FinishedAt: &now}, &event, tx); err != nil { + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunApproveSwitchUnitMiddleware(approveSwitchEncounter, &input); err != nil { return err } - - // create responsible doctor based on internal reference data - if _, err = urdh.CreateData(erdh.CreateDto{ - Encounter_Id: &input.Id, - Doctor_Code: irData.Doctor_Code, - StartedAt: &now, - }, &event, tx); err != nil { - return err - } - - // update data response - data.Responsible_Doctor_Code = irData.Doctor_Code - data.Unit_Code = irData.Unit_Code - data.Specialist_Code = irData.Doctor.Specialist_Code - data.Subspecialist_Code = irData.Doctor.Subspecialist_Code - - pl.SetLogInfo(&event, nil, "complete") return nil }) + if err = runLogMiddleware(err, input, mwRunner); err != nil { + return nil, err + } + + pl.SetLogInfo(&event, nil, "complete") + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "single-data", + "status": "updated", + }, + Data: data.ToResponse(), + }, nil + +} + +func CancelSwitchUnit(input e.ApproveCancelUnitDto) (*d.Data, error) { + rdDto := e.ReadDetailDto{Id: input.Id} + var ( + data *e.Encounter + err error + ) + + event := pl.Event{ + Feature: "CancelSwitchUnit", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "cancelSwitchUnit") + + roleAllowed := []string{string(erg.EPCNur)} + err = validateAuth(input.AuthInfo, roleAllowed, "request-switch-poly", &event) if err != nil { return nil, err } + mwRunner := newMiddlewareRunner(&event) + + 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) + } + + // get internalReference based on internalReferences_Id + irData, err := uir.ReadDetailData(eir.ReadDetailDto{ + Id: input.InternalReferences_Id}, &event, tx) + if err != nil { + return err + } + + if *irData.Status_Code != erc.DACNew { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-state-mismatch", + Detail: "internal references is approve", + Raw: errors.New("internal references is approve"), + } + return pl.SetLogError(&event, input) + } + + // update internal reference + if err = uir.UpdateData(eir.UpdateDto{ + Id: input.InternalReferences_Id, + CreateDto: eir.CreateDto{ + Status_Code: erc.DACCanceled, + Nurse_Code: input.Nurse_Code}}, irData, &event, tx); err != nil { + return err + } + + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunCancelSwitchUnitMiddleware(cancelSwitchEncounter, &input); err != nil { + return err + } + return nil + }) + + if err = runLogMiddleware(err, input, mwRunner); err != nil { + return nil, err + } + + pl.SetLogInfo(&event, nil, "complete") + return &d.Data{ Meta: d.IS{ "source": source, diff --git a/internal/use-case/main-use-case/encounter/helper.go b/internal/use-case/main-use-case/encounter/helper.go index ff4e0af1..02ade837 100644 --- a/internal/use-case/main-use-case/encounter/helper.go +++ b/internal/use-case/main-use-case/encounter/helper.go @@ -7,6 +7,7 @@ package encounter import ( "errors" "fmt" + un "simrs-vx/internal/use-case/main-use-case/nurse" "strings" "time" @@ -29,7 +30,6 @@ import ( edo "simrs-vx/internal/domain/main-entities/device-order" 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" emo "simrs-vx/internal/domain/main-entities/material-order" @@ -38,6 +38,7 @@ import ( emei "simrs-vx/internal/domain/main-entities/medication-item" emi "simrs-vx/internal/domain/main-entities/medicine-mix" emmi "simrs-vx/internal/domain/main-entities/medicine-mix-item" + en "simrs-vx/internal/domain/main-entities/nurse" ep "simrs-vx/internal/domain/main-entities/prescription" epi "simrs-vx/internal/domain/main-entities/prescription-item" er "simrs-vx/internal/domain/main-entities/rehab" @@ -51,12 +52,12 @@ import ( uc "simrs-vx/internal/use-case/main-use-case/chemo" 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" um "simrs-vx/internal/use-case/main-use-case/medication" umei "simrs-vx/internal/use-case/main-use-case/medication-item" umi "simrs-vx/internal/use-case/main-use-case/medicine-mix" ummi "simrs-vx/internal/use-case/main-use-case/medicine-mix-item" + _ "simrs-vx/internal/use-case/main-use-case/nurse" up "simrs-vx/internal/use-case/main-use-case/prescription" upi "simrs-vx/internal/use-case/main-use-case/prescription-item" ur "simrs-vx/internal/use-case/main-use-case/rehab" @@ -68,6 +69,7 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Encounter) { var inputSrc *e.CreateDto if inputT, ok := any(input).(*e.CreateDto); ok { inputSrc = inputT + data.Status_Code = erc.DSCNew } else { inputTemp := any(input).(*e.UpdateDto) inputSrc = &inputTemp.CreateDto @@ -90,7 +92,6 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Encounter) { data.Responsible_Doctor_Code = inputSrc.Responsible_Doctor_Code 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 } @@ -117,17 +118,24 @@ func setDataDischarge(src e.DischargeDto, dst *e.Encounter) { dst.FinishedAt = &now } -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_Nurse_Code = src.Responsible_Nurse_Code dst.Responsible_Doctor_Code = src.Responsible_Doctor_Code dst.StartedAt = src.StartedAt + dst.Status_Code = erc.DSCProcess +} + +func setDischargeMethodCode(code ere.PolySwitchCode) *ere.DischargeMethodCode { + var dcm ere.DischargeMethodCode + + switch code { + case ere.PSCConsulPoly: + dcm = ere.DMCConsulPoly + case ere.PSCConsulExecutive: + dcm = ere.DMCConsulExecutive + } + + return &dcm } func checkSoapiByDocExists(encounter_id uint, event *pl.Event, tx *gorm.DB) error { @@ -556,6 +564,7 @@ func getSoapiByResponsibleDoctor(enc e.Encounter, event *pl.Event) (data []es.So Code: "no responsible-doctor found", Detail: "Encounter does not have responsible-doctor", } + return nil, pl.SetLogError(event, enc) } err = dg.I. @@ -904,17 +913,17 @@ func updateRehabStatus(input er.UpdateDto, event *pl.Event, dbx ...*gorm.DB) err return nil } -func validateForeignKey(input e.CheckinDto) error { +func validateForeignKey(input e.CheckinDto, event *pl.Event) error { // validate employee_Id - if input.Adm_Employee_Id != nil { - if _, err := uem.ReadDetail(eem.ReadDetailDto{Id: uint16(*input.Adm_Employee_Id)}); err != nil { + if input.Responsible_Nurse_Code != nil { + if _, err := un.ReadDetailData(en.ReadDetailDto{Code: input.Responsible_Nurse_Code}, event); err != nil { return err } } // validate doctor_Code if input.Responsible_Doctor_Code != nil { - if _, err := ud.ReadDetail(ed.ReadDetailDto{Code: input.Responsible_Doctor_Code}); err != nil { + if _, err := ud.ReadDetailData(ed.ReadDetailDto{Code: input.Responsible_Doctor_Code}, event); err != nil { return err } } diff --git a/internal/use-case/main-use-case/encounter/lib.go b/internal/use-case/main-use-case/encounter/lib.go index ef189ad4..0b14b925 100644 --- a/internal/use-case/main-use-case/encounter/lib.go +++ b/internal/use-case/main-use-case/encounter/lib.go @@ -3,7 +3,6 @@ package encounter import ( // std "errors" - eir "simrs-vx/internal/domain/main-entities/internal-reference" // external dg "github.com/karincake/apem/db-gorm-pg" gh "github.com/karincake/getuk" @@ -205,9 +204,8 @@ func IsDone(encounter_id uint, event *pl.Event, dbx ...*gorm.DB) bool { return data.IsDone() } -func UpdateStatusData(input e.UpdateStatusDto, data *e.Encounter, event *pl.Event, dbx ...*gorm.DB) error { - pl.SetLogInfo(event, data, "started", "DBUpdate") - setDataUpdateStatus(input, data) +func UpdateStatusData(input e.UpdateStatusDto, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, input, "started", "DBUpdateStatus") var tx *gorm.DB if len(dbx) > 0 { @@ -216,22 +214,49 @@ func UpdateStatusData(input e.UpdateStatusDto, data *e.Encounter, event *pl.Even tx = dg.I } - if err := tx.Save(&data).Error; err != nil { + if err := tx.Model(&e.Encounter{}). + Where("\"Id\" = ?", input.Id). + Update("Status_Code", input.StatusCode).Error; err != nil { event.Status = "failed" event.ErrInfo = pl.ErrorInfo{ - Code: "data-update-fail", - Detail: "Database update failed", + Code: "update-fail", + Detail: "Failed to update status code", + Raw: err, + } + return pl.SetLogError(event, input) + } + + return nil +} + +func UpdateDischargeMethod(input e.SwitchUnitDto, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, input, "started", "DBUpdateDischargeMethod") + dischargeCode := setDischargeMethodCode(*input.PolySwitchCode) + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Model(&e.Encounter{}). + Where("\"Id\" = ?", input.Id). + Update("Discharge_Method_Code", dischargeCode).Error; err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "update-fail", + Detail: "Failed to update discharge method code", Raw: err, } return pl.SetLogError(event, input) } - 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") + pl.SetLogInfo(event, data, "started", "DBUpdateCheckin") setDataCheckIn(input, data) var tx *gorm.DB @@ -318,7 +343,7 @@ func verifyAllocatedVisitCount(i e.CreateDto, event *pl.Event) (e.Encounter, boo return recentEncounterAdm, valid, nil } -func updateEncounterApproveSwitchUnit(input eir.InternalReference, event *pl.Event, dbx ...*gorm.DB) (err error) { +func updateEncounterApproveSwitchUnit(input e.ApproveCancelUnitDto, event *pl.Event, dbx ...*gorm.DB) (err error) { pl.SetLogInfo(event, nil, "started", "DBCreate") var tx *gorm.DB @@ -329,10 +354,10 @@ func updateEncounterApproveSwitchUnit(input eir.InternalReference, event *pl.Eve } if err := tx.Model(&e.Encounter{}). - Where("\"Id\" = ?", input.Encounter_Id). + Where("\"Id\" = ?", input.Id). Updates(map[string]interface{}{ - "Responsible_Doctor_Code": input.Doctor_Code, - "Unit_Code": input.Unit_Code, + "Responsible_Doctor_Code": input.Dst_Doctor_Code, + "Responsible_Nurse_Code": input.Nurse_Code, }).Error; err != nil { event.Status = "failed" event.ErrInfo = pl.ErrorInfo{ diff --git a/internal/use-case/main-use-case/encounter/middleware-runner.go b/internal/use-case/main-use-case/encounter/middleware-runner.go index 1837c42e..4481443b 100644 --- a/internal/use-case/main-use-case/encounter/middleware-runner.go +++ b/internal/use-case/main-use-case/encounter/middleware-runner.go @@ -27,7 +27,6 @@ func newMiddlewareRunner(event *pl.Event) *middlewareRunner { } } -// ExecuteCreateMiddleware executes create middleware func (me *middlewareRunner) RunCreateMiddleware(middlewares []createMw, input *e.Encounter) error { if !me.SyncOn { return nil @@ -47,7 +46,6 @@ func (me *middlewareRunner) RunCreateMiddleware(middlewares []createMw, input *e return nil } -// ExecuteCreateMiddleware executes create middleware func (me *middlewareRunner) RunCreateLogMiddleware(middlewares []createLogMw, input *esync.SimxLogDto) error { if !me.SyncOn { return nil @@ -199,6 +197,60 @@ func (me *middlewareRunner) RunUpdateStatusMiddleware(middlewares []updateStatus return nil } +func (me *middlewareRunner) RunRequestSwitchUnitMiddleware(middleware requestSwitchUnitMw, input *e.Encounter) error { + if !me.SyncOn { + return nil + } + + logData := pu.GetLogData(input, nil) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input); 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) RunApproveSwitchUnitMiddleware(middleware approveSwitchUnitMw, input *e.ApproveCancelUnitDto) error { + if !me.SyncOn { + return nil + } + + logData := pu.GetLogData(input, nil) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input); 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) RunCancelSwitchUnitMiddleware(middleware cancelSwitchUnitMw, input *e.ApproveCancelUnitDto) error { + if !me.SyncOn { + return nil + } + + logData := pu.GetLogData(input, nil) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input); 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/encounter/middleware.go b/internal/use-case/main-use-case/encounter/middleware.go index fb2ce0a0..306e4bca 100644 --- a/internal/use-case/main-use-case/encounter/middleware.go +++ b/internal/use-case/main-use-case/encounter/middleware.go @@ -21,5 +21,9 @@ func init() { checkoutEncounter = checkoutMw{Name: "sync-checkout-encounter", Func: plugin.Checkout} updatestatusEncounter = append(updatestatusEncounter, - updateStatusMw{Name: "sync-update-status-encounter", Func: plugin.Cancel}) + updateStatusMw{Name: "sync-update-status-encounter", Func: plugin.UpdateStatus}) + + requestSwitchEncounter = requestSwitchUnitMw{Name: "sync-request-switch-unit-encounter", Func: plugin.RequestSwitchUnit} + approveSwitchEncounter = approveSwitchUnitMw{Name: "sync-approve-switch-unit-encounter", Func: plugin.ApproveSwitchUnit} + cancelSwitchEncounter = cancelSwitchUnitMw{Name: "sync-cancel-switch-unit-encounter", Func: plugin.CancelSwitchUnit} } diff --git a/internal/use-case/main-use-case/encounter/tycovar.go b/internal/use-case/main-use-case/encounter/tycovar.go index f25ad45b..2b268378 100644 --- a/internal/use-case/main-use-case/encounter/tycovar.go +++ b/internal/use-case/main-use-case/encounter/tycovar.go @@ -59,6 +59,21 @@ type updateStatusMw struct { Func func(input *e.Encounter) error } +type requestSwitchUnitMw struct { + Name string + Func func(input *e.Encounter) error +} + +type approveSwitchUnitMw struct { + Name string + Func func(input *e.ApproveCancelUnitDto) error +} + +type cancelSwitchUnitMw struct { + Name string + Func func(input *e.ApproveCancelUnitDto) error +} + type UpdateMw = updateMw type DeleteMw = deleteMw @@ -76,3 +91,6 @@ var deletePostMw []readDetailMw var checkinEncounterMw checkinMw var checkoutEncounter checkoutMw var updatestatusEncounter []updateStatusMw +var requestSwitchEncounter requestSwitchUnitMw +var approveSwitchEncounter approveSwitchUnitMw +var cancelSwitchEncounter cancelSwitchUnitMw diff --git a/internal/use-case/main-use-case/internal-reference/helper.go b/internal/use-case/main-use-case/internal-reference/helper.go index 234eb770..26b8903f 100644 --- a/internal/use-case/main-use-case/internal-reference/helper.go +++ b/internal/use-case/main-use-case/internal-reference/helper.go @@ -5,35 +5,41 @@ Any functions that are used internally by the use-case package internal_reference import ( + e "simrs-vx/internal/domain/main-entities/encounter" ir "simrs-vx/internal/domain/main-entities/internal-reference" erc "simrs-vx/internal/domain/references/common" ) -func setData[T *ir.CreateDto | *ir.UpdateDto](input T, data *ir.InternalReference) { - var inputSrc *ir.CreateDto - if inputT, ok := any(input).(*ir.CreateDto); ok { - inputSrc = inputT - } else { - inputTemp := any(input).(*ir.UpdateDto) - inputSrc = &inputTemp.CreateDto - } +func setDataCreate(input *ir.CreateDto, data *ir.InternalReference) { + data.Encounter_Id = input.Encounter_Id + data.Unit_Code = input.Unit_Code - data.Encounter_Id = inputSrc.Encounter_Id - data.Unit_Code = inputSrc.Unit_Code - data.Doctor_Code = inputSrc.Doctor_Code - data.Status_Code = &inputSrc.Status_Code + data.Doctor_Code = input.Doctor_Code + data.SrcDoctor_Code = input.SrcDoctor_Code + + data.Nurse_Code = input.Nurse_Code + data.SrcNurse_Code = input.SrcNurse_Code + data.Status_Code = &input.Status_Code } -func setBulkData(input []ir.CreateDto, encounterId uint) []ir.InternalReference { +func setDataUpdate(input *ir.UpdateDto, data *ir.InternalReference) { + data.Doctor_Code = input.Doctor_Code + data.Nurse_Code = input.Nurse_Code + data.Status_Code = &input.Status_Code +} + +func setBulkData(input *e.SwitchUnitDto) []ir.InternalReference { var data []ir.InternalReference - for _, v := range input { + for _, v := range *input.InternalReferences { statusCode := erc.DACNew data = append(data, ir.InternalReference{ - Encounter_Id: &encounterId, - Unit_Code: v.Unit_Code, - Doctor_Code: v.Doctor_Code, - Status_Code: &statusCode, + Encounter_Id: &input.Id, + Unit_Code: v.Unit_Code, + Doctor_Code: v.Doctor_Code, + Status_Code: &statusCode, + SrcDoctor_Code: input.Src_Doctor_Code, + SrcNurse_Code: input.Src_Nurse_Code, }) } diff --git a/internal/use-case/main-use-case/internal-reference/lib.go b/internal/use-case/main-use-case/internal-reference/lib.go index bf852dc6..0aa54b4b 100644 --- a/internal/use-case/main-use-case/internal-reference/lib.go +++ b/internal/use-case/main-use-case/internal-reference/lib.go @@ -2,6 +2,7 @@ package internal_reference import ( "errors" + e "simrs-vx/internal/domain/main-entities/encounter" eir "simrs-vx/internal/domain/main-entities/internal-reference" plh "simrs-vx/pkg/lib-helper" pl "simrs-vx/pkg/logger" @@ -16,7 +17,7 @@ func CreateData(input eir.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*eir.Int pl.SetLogInfo(event, nil, "started", "DBCreate") data := eir.InternalReference{} - setData(&input, &data) + setDataCreate(&input, &data) var tx *gorm.DB if len(dbx) > 0 { @@ -97,7 +98,7 @@ func ReadDetailData(input eir.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) ( func UpdateData(input eir.UpdateDto, data *eir.InternalReference, event *pl.Event, dbx ...*gorm.DB) error { pl.SetLogInfo(event, data, "started", "DBUpdate") - setData(&input, data) + setDataUpdate(&input, data) var tx *gorm.DB if len(dbx) > 0 { @@ -143,10 +144,10 @@ func DeleteData(data *eir.InternalReference, event *pl.Event, dbx ...*gorm.DB) e return nil } -func CreateBulkData(input []eir.CreateDto, encounterId uint, event *pl.Event, dbx ...*gorm.DB) error { +func CreateBulkData(input *e.SwitchUnitDto, event *pl.Event, dbx ...*gorm.DB) error { pl.SetLogInfo(event, nil, "started", "DBCreate") - data := setBulkData(input, encounterId) + data := setBulkData(input) var tx *gorm.DB if len(dbx) > 0 { diff --git a/internal/use-case/main-use-case/therapy-protocol/case.go b/internal/use-case/main-use-case/therapy-protocol/case.go index ed4f3a21..a332d675 100644 --- a/internal/use-case/main-use-case/therapy-protocol/case.go +++ b/internal/use-case/main-use-case/therapy-protocol/case.go @@ -359,7 +359,7 @@ func Verify(input e.VerifyDto) (*d.Data, error) { func validateForeignKey(input e.CreateDto) error { // validate encounter if input.Encounter_Id != nil { - if _, err := ue.ReadDetail(ee.ReadDetailDto{Id: uint16(*input.Encounter_Id)}); err != nil { + if _, err := ue.ReadDetail(ee.ReadDetailDto{Id: *input.Encounter_Id}); err != nil { return err } } diff --git a/internal/use-case/main-use-case/unit/case.go b/internal/use-case/main-use-case/unit/case.go index 1db6fb79..c73c2c1d 100644 --- a/internal/use-case/main-use-case/unit/case.go +++ b/internal/use-case/main-use-case/unit/case.go @@ -1,6 +1,7 @@ package unit import ( + "errors" e "simrs-vx/internal/domain/main-entities/unit" erc "simrs-vx/internal/domain/references/common" esync "simrs-vx/internal/domain/sync-entities/log" @@ -27,9 +28,22 @@ func Create(input e.CreateDto) (*d.Data, error) { // Start log pl.SetLogInfo(&event, input, "started", "create") + + // validate unit_code + _, err := strconv.Atoi(input.Code) + if err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "invalid_code_format", + Detail: "unit_code must be a valid integer", + Raw: errors.New("invalid unit_code format"), + } + return nil, pl.SetLogError(&event, input) + } + mwRunner := newMiddlewareRunner(&event) - err := dg.I.Transaction(func(tx *gorm.DB) error { + err = dg.I.Transaction(func(tx *gorm.DB) error { if resData, err := CreateData(input, &event, tx); err != nil { return err } else { diff --git a/internal/use-case/simgos-sync-plugin/new/division/plugin.go b/internal/use-case/simgos-sync-plugin/new/division/plugin.go index b67f19d6..f4d6a34b 100644 --- a/internal/use-case/simgos-sync-plugin/new/division/plugin.go +++ b/internal/use-case/simgos-sync-plugin/new/division/plugin.go @@ -1,165 +1,35 @@ package division import ( - "bytes" - "encoding/json" "fmt" - "io" - "net/http" + helper "simrs-vx/internal/use-case/simgos-sync-plugin/new" sync "simrs-vx/internal/infra/sync-consumer-cfg" e "simrs-vx/internal/domain/main-entities/division" elog "simrs-vx/internal/domain/sync-entities/log" - - d "github.com/karincake/dodol" ) func Create(input *e.CreateDto) error { - endpoint := getPrefixEndpoint() - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("POST", endpoint, bytes.NewReader(jsonData)) - 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() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "POST", getPrefixEndpoint()) } func CreateLog(input *elog.SimxLogDto) error { prefixEndpoint := getPrefixEndpoint() endpoint := prefixEndpoint + "/log" - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("POST", endpoint, bytes.NewReader(jsonData)) - 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() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "POST", endpoint) } func Update(input *e.UpdateDto) error { prefixEndpoint := getPrefixEndpoint() endpoint := fmt.Sprintf("%s/%v", prefixEndpoint, *input.Id) - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("PATCH", endpoint, bytes.NewReader(jsonData)) - 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() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "PATCH", endpoint) } func Delete(input *e.DeleteDto) error { prefixEndpoint := getPrefixEndpoint() endpoint := fmt.Sprintf("%s/%v", prefixEndpoint, *input.Id) - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("DELETE", endpoint, bytes.NewReader(jsonData)) - 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() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "DELETE", endpoint) } func getPrefixEndpoint() string { diff --git a/internal/use-case/simgos-sync-plugin/new/encounter/plugin.go b/internal/use-case/simgos-sync-plugin/new/encounter/plugin.go index bba5da31..2f5e2515 100644 --- a/internal/use-case/simgos-sync-plugin/new/encounter/plugin.go +++ b/internal/use-case/simgos-sync-plugin/new/encounter/plugin.go @@ -43,9 +43,27 @@ func Checkout(input *e.Encounter) error { return helper.DoJsonRequest(input, "PATCH", endpoint) } -func Cancel(input *e.Encounter) error { +func UpdateStatus(input *e.Encounter) error { prefixEndpoint := getPrefixEndpoint() - endpoint := fmt.Sprintf("%s/%v/cancel", prefixEndpoint, input.Id) + endpoint := fmt.Sprintf("%s/%v/update-status", prefixEndpoint, input.Id) + return helper.DoJsonRequest(input, "PATCH", endpoint) +} + +func RequestSwitchUnit(input *e.Encounter) error { + prefixEndpoint := getPrefixEndpoint() + endpoint := fmt.Sprintf("%s/%v/req-switch-unit", prefixEndpoint, input.Id) + return helper.DoJsonRequest(input, "PATCH", endpoint) +} + +func ApproveSwitchUnit(input *e.ApproveCancelUnitDto) error { + prefixEndpoint := getPrefixEndpoint() + endpoint := fmt.Sprintf("%s/%v/approve-switch-unit", prefixEndpoint, input.Id) + return helper.DoJsonRequest(input, "PATCH", endpoint) +} + +func CancelSwitchUnit(input *e.ApproveCancelUnitDto) error { + prefixEndpoint := getPrefixEndpoint() + endpoint := fmt.Sprintf("%s/%v/cancel-switch-unit", prefixEndpoint, input.Id) return helper.DoJsonRequest(input, "PATCH", endpoint) } diff --git a/internal/use-case/simgos-sync-plugin/new/installation/plugin.go b/internal/use-case/simgos-sync-plugin/new/installation/plugin.go index 6f1c12d6..40f0c153 100644 --- a/internal/use-case/simgos-sync-plugin/new/installation/plugin.go +++ b/internal/use-case/simgos-sync-plugin/new/installation/plugin.go @@ -1,165 +1,35 @@ package installation import ( - "bytes" - "encoding/json" "fmt" - "io" - "net/http" sync "simrs-vx/internal/infra/sync-consumer-cfg" + helper "simrs-vx/internal/use-case/simgos-sync-plugin/new" e "simrs-vx/internal/domain/main-entities/installation" elog "simrs-vx/internal/domain/sync-entities/log" - - d "github.com/karincake/dodol" ) func Create(input *e.CreateDto) error { - endpoint := getPrefixEndpoint() - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("POST", endpoint, bytes.NewReader(jsonData)) - 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() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "POST", getPrefixEndpoint()) } func CreateLog(input *elog.SimxLogDto) error { prefixEndpoint := getPrefixEndpoint() endpoint := prefixEndpoint + "/log" - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("POST", endpoint, bytes.NewReader(jsonData)) - 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() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "POST", endpoint) } func Update(input *e.UpdateDto) error { prefixEndpoint := getPrefixEndpoint() endpoint := fmt.Sprintf("%s/%v", prefixEndpoint, *input.Id) - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("PATCH", endpoint, bytes.NewReader(jsonData)) - 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() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "PATCH", endpoint) } func Delete(input *e.DeleteDto) error { prefixEndpoint := getPrefixEndpoint() endpoint := fmt.Sprintf("%s/%v", prefixEndpoint, *input.Id) - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("DELETE", endpoint, bytes.NewReader(jsonData)) - 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() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "DELETE", endpoint) } func getPrefixEndpoint() string { diff --git a/internal/use-case/simgos-sync-plugin/new/patient/plugin.go b/internal/use-case/simgos-sync-plugin/new/patient/plugin.go index 6f03299a..7678da47 100644 --- a/internal/use-case/simgos-sync-plugin/new/patient/plugin.go +++ b/internal/use-case/simgos-sync-plugin/new/patient/plugin.go @@ -1,11 +1,11 @@ package patient import ( - "bytes" "encoding/json" "fmt" "io" "net/http" + helper "simrs-vx/internal/use-case/simgos-sync-plugin/new" d "github.com/karincake/dodol" @@ -16,150 +16,25 @@ import ( ) func Create(input *e.Patient) error { - endpoint := getPrefixEndpoint() - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("POST", endpoint, bytes.NewReader(jsonData)) - 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() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "POST", getPrefixEndpoint()) } func CreateLog(input *elog.SimxLogDto) error { prefixEndpoint := getPrefixEndpoint() endpoint := prefixEndpoint + "/log" - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("POST", endpoint, bytes.NewReader(jsonData)) - 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() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "POST", endpoint) } func Update(input *e.Patient) error { prefixEndpoint := getPrefixEndpoint() endpoint := fmt.Sprintf("%s/%v", prefixEndpoint, input.Id) - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("PATCH", endpoint, bytes.NewReader(jsonData)) - 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() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "PATCH", endpoint) } func Delete(input *e.DeleteDto) error { prefixEndpoint := getPrefixEndpoint() endpoint := fmt.Sprintf("%s/%v", prefixEndpoint, input.Id) - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("DELETE", endpoint, bytes.NewReader(jsonData)) - 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() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "DELETE", endpoint) } func GenerateNomrPatient() (*string, error) { diff --git a/internal/use-case/simgos-sync-plugin/new/specialist/plugin.go b/internal/use-case/simgos-sync-plugin/new/specialist/plugin.go index 370a66dd..29da9d0a 100644 --- a/internal/use-case/simgos-sync-plugin/new/specialist/plugin.go +++ b/internal/use-case/simgos-sync-plugin/new/specialist/plugin.go @@ -1,165 +1,35 @@ package specialist import ( - "bytes" - "encoding/json" "fmt" - "io" - "net/http" + helper "simrs-vx/internal/use-case/simgos-sync-plugin/new" sync "simrs-vx/internal/infra/sync-consumer-cfg" e "simrs-vx/internal/domain/main-entities/specialist" elog "simrs-vx/internal/domain/sync-entities/log" - - d "github.com/karincake/dodol" ) func Create(input *e.CreateDto) error { - endpoint := getPrefixEndpoint() - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("POST", endpoint, bytes.NewReader(jsonData)) - 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() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "POST", getPrefixEndpoint()) } func CreateLog(input *elog.SimxLogDto) error { prefixEndpoint := getPrefixEndpoint() endpoint := prefixEndpoint + "/log" - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("POST", endpoint, bytes.NewReader(jsonData)) - 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() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "POST", endpoint) } func Update(input *e.UpdateDto) error { prefixEndpoint := getPrefixEndpoint() endpoint := fmt.Sprintf("%s/%v", prefixEndpoint, *input.Id) - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("PATCH", endpoint, bytes.NewReader(jsonData)) - 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() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "PATCH", endpoint) } func Delete(input *e.DeleteDto) error { prefixEndpoint := getPrefixEndpoint() endpoint := fmt.Sprintf("%s/%v", prefixEndpoint, *input.Id) - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("DELETE", endpoint, bytes.NewReader(jsonData)) - 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() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "DELETE", endpoint) } func getPrefixEndpoint() string { diff --git a/internal/use-case/simgos-sync-plugin/new/subspecialist/plugin.go b/internal/use-case/simgos-sync-plugin/new/subspecialist/plugin.go index 5fa831d1..0167936c 100644 --- a/internal/use-case/simgos-sync-plugin/new/subspecialist/plugin.go +++ b/internal/use-case/simgos-sync-plugin/new/subspecialist/plugin.go @@ -1,165 +1,35 @@ package subspecialist import ( - "bytes" - "encoding/json" "fmt" - "io" - "net/http" + helper "simrs-vx/internal/use-case/simgos-sync-plugin/new" sync "simrs-vx/internal/infra/sync-consumer-cfg" e "simrs-vx/internal/domain/main-entities/subspecialist" elog "simrs-vx/internal/domain/sync-entities/log" - - d "github.com/karincake/dodol" ) func Create(input *e.CreateDto) error { - endpoint := getPrefixEndpoint() - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("POST", endpoint, bytes.NewReader(jsonData)) - 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() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "POST", getPrefixEndpoint()) } func CreateLog(input *elog.SimxLogDto) error { prefixEndpoint := getPrefixEndpoint() endpoint := prefixEndpoint + "/log" - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("POST", endpoint, bytes.NewReader(jsonData)) - 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() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "POST", endpoint) } func Update(input *e.UpdateDto) error { prefixEndpoint := getPrefixEndpoint() endpoint := fmt.Sprintf("%s/%v", prefixEndpoint, *input.Id) - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("PATCH", endpoint, bytes.NewReader(jsonData)) - 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() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "PATCH", endpoint) } func Delete(input *e.DeleteDto) error { prefixEndpoint := getPrefixEndpoint() endpoint := fmt.Sprintf("%s/%v", prefixEndpoint, *input.Id) - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("DELETE", endpoint, bytes.NewReader(jsonData)) - 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() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "DELETE", endpoint) } func getPrefixEndpoint() string { diff --git a/internal/use-case/simgos-sync-plugin/new/unit/plugin.go b/internal/use-case/simgos-sync-plugin/new/unit/plugin.go index 36d240b5..f646f450 100644 --- a/internal/use-case/simgos-sync-plugin/new/unit/plugin.go +++ b/internal/use-case/simgos-sync-plugin/new/unit/plugin.go @@ -1,165 +1,35 @@ package unit import ( - "bytes" - "encoding/json" "fmt" - "io" - "net/http" + helper "simrs-vx/internal/use-case/simgos-sync-plugin/new" sync "simrs-vx/internal/infra/sync-consumer-cfg" e "simrs-vx/internal/domain/main-entities/unit" elog "simrs-vx/internal/domain/sync-entities/log" - - d "github.com/karincake/dodol" ) func Create(input *e.CreateDto) error { - endpoint := getPrefixEndpoint() - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("POST", endpoint, bytes.NewReader(jsonData)) - 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() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "POST", getPrefixEndpoint()) } func CreateLog(input *elog.SimxLogDto) error { prefixEndpoint := getPrefixEndpoint() endpoint := prefixEndpoint + "/log" - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("POST", endpoint, bytes.NewReader(jsonData)) - 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() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "POST", endpoint) } func Update(input *e.UpdateDto) error { prefixEndpoint := getPrefixEndpoint() endpoint := fmt.Sprintf("%s/%v", prefixEndpoint, *input.Id) - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("PATCH", endpoint, bytes.NewReader(jsonData)) - 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() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "PATCH", endpoint) } func Delete(input *e.DeleteDto) error { prefixEndpoint := getPrefixEndpoint() endpoint := fmt.Sprintf("%s/%v", prefixEndpoint, *input.Id) - - jsonData, err := json.Marshal(input) - if err != nil { - return fmt.Errorf("failed to encode JSON: %w", err) - } - - req, err := http.NewRequest("DELETE", endpoint, bytes.NewReader(jsonData)) - 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() - - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - - if resp.StatusCode != http.StatusOK { - errors := d.FieldError{} - _ = json.Unmarshal(bodyBytes, &errors) - - return fmt.Errorf(errors.Message) - } - - return nil + return helper.DoJsonRequest(input, "DELETE", endpoint) } func getPrefixEndpoint() string { diff --git a/internal/use-case/simgos-sync-use-case/new/encounter/case.go b/internal/use-case/simgos-sync-use-case/new/encounter/case.go index 6b4f7ab4..59e7e345 100644 --- a/internal/use-case/simgos-sync-use-case/new/encounter/case.go +++ b/internal/use-case/simgos-sync-use-case/new/encounter/case.go @@ -10,10 +10,11 @@ import ( e "simrs-vx/internal/domain/main-entities/encounter" etp "simrs-vx/internal/domain/simgos-entities/t-pendaftaran" - esync "simrs-vx/internal/domain/sync-entities/encounter" + synce "simrs-vx/internal/domain/sync-entities/encounter" + syncir "simrs-vx/internal/domain/sync-entities/internal-reference" elog "simrs-vx/internal/domain/sync-entities/log" - up "simrs-vx/internal/use-case/simgos-sync-use-case/new/patient" + utph "simrs-vx/internal/use-case/simgos-sync-use-case/new/internal-reference" ) const source = "encounter" @@ -21,7 +22,7 @@ const source = "encounter" func Create(input e.Encounter) (*d.Data, error) { var ( sgData *etp.TPendaftaran - syncLink *esync.EncounterLink + syncLink *synce.EncounterLink err error ) @@ -46,14 +47,8 @@ func Create(input e.Encounter) (*d.Data, error) { return err } - // STEP: 3 Get MPasien - dataPatient, err := up.ReadDetailSimgosByNomrData(sgData.Nomr, &event, tx.Simgos) - if err != nil { - return err - } - - // STEP 4: Update MPasien - err = updatePatient(*dataPatient, &event, tx.Simgos) + // STEP 3: Update MPasien + err = updatePatientCaraBayar(*sgData, &event, tx.Simgos) if err != nil { return err } @@ -123,13 +118,13 @@ func Update(input e.Encounter) (*d.Data, error) { pl.SetLogInfo(&event, input, "started", "update") // STEP 1: Get Link - syncLink, err := ReadDetailLinkData(uint16(input.Id), &event) + syncLink, err := ReadDetailLinkData(input.Id, &event) if err != nil { return nil, err } // STEP 2: Get Simgos - simgos, err := ReadTPendaftaranDetailData(uint16(syncLink.Simgos_Id), &event) + simgos, err := ReadTPendaftaranDetailData(syncLink.Simgos_Id, &event) if err != nil { return nil, err } @@ -137,7 +132,7 @@ func Update(input e.Encounter) (*d.Data, error) { tx := db.NewTx() err = tx.Simgos.Transaction(func(tx *gorm.DB) error { // Step 2: Update Simgos - if err = UpdateTPendaftaranData(input, *simgos, "update", &event, tx); err != nil { + if err = UpdateTPendaftaranData(input, simgos, "update", &event, tx); err != nil { return err } @@ -173,7 +168,7 @@ func Delete(input e.DeleteDto) (*d.Data, error) { } // STEP 2: Get Simgos - sgData, err := ReadTPendaftaranDetailData(uint16(syncLink.Simgos_Id), &event) + sgData, err := ReadTPendaftaranDetailData(syncLink.Simgos_Id, &event) if err != nil { return nil, err } @@ -226,13 +221,13 @@ func CheckIn(input e.Encounter) (*d.Data, error) { pl.SetLogInfo(&event, input, "started", "check-in") // STEP 1: Get Link - syncLink, err := ReadDetailLinkData(uint16(input.Id), &event) + syncLink, err := ReadDetailLinkData(input.Id, &event) if err != nil { return nil, err } // STEP 2: Get Simgos - simgos, err := ReadTPendaftaranDetailData(uint16(syncLink.Simgos_Id), &event) + simgos, err := ReadTPendaftaranDetailData(syncLink.Simgos_Id, &event) if err != nil { return nil, err } @@ -240,7 +235,7 @@ func CheckIn(input e.Encounter) (*d.Data, error) { tx := db.NewTx() err = tx.Simgos.Transaction(func(tx *gorm.DB) error { // Step 2: Update Simgos - if err = UpdateTPendaftaranData(input, *simgos, "check-in", &event, tx); err != nil { + if err = UpdateTPendaftaranData(input, simgos, "check-in", &event, tx); err != nil { return err } @@ -268,13 +263,13 @@ func CheckOut(input e.Encounter) (*d.Data, error) { pl.SetLogInfo(&event, input, "started", "check-out") // STEP 1: Get Link - syncLink, err := ReadDetailLinkData(uint16(input.Id), &event) + syncLink, err := ReadDetailLinkData(input.Id, &event) if err != nil { return nil, err } // STEP 2: Get Simgos - simgos, err := ReadTPendaftaranDetailData(uint16(syncLink.Simgos_Id), &event) + simgos, err := ReadTPendaftaranDetailData(syncLink.Simgos_Id, &event) if err != nil { return nil, err } @@ -282,10 +277,12 @@ func CheckOut(input e.Encounter) (*d.Data, error) { tx := db.NewTx() err = tx.Simgos.Transaction(func(tx *gorm.DB) error { // Step 2: Update Simgos - if err = UpdateTPendaftaranData(input, *simgos, "check-out", &event, tx); err != nil { + if err = UpdateTPendaftaranData(input, simgos, "check-out", &event, tx); err != nil { return err } + // TODO: Update TPemeriksaanHistory end_konsul if internal reference exist + return nil }) @@ -300,7 +297,7 @@ func CheckOut(input e.Encounter) (*d.Data, error) { }, nil } -func Cancel(input e.Encounter) (*d.Data, error) { +func UpdateStatus(input e.Encounter) (*d.Data, error) { event := pl.Event{ Feature: "Cancel", Source: source, @@ -310,13 +307,13 @@ func Cancel(input e.Encounter) (*d.Data, error) { pl.SetLogInfo(&event, input, "started", "cancel") // STEP 1: Get Link - syncLink, err := ReadDetailLinkData(uint16(input.Id), &event) + syncLink, err := ReadDetailLinkData(input.Id, &event) if err != nil { return nil, err } // STEP 2: Get Simgos - simgos, err := ReadTPendaftaranDetailData(uint16(syncLink.Simgos_Id), &event) + simgos, err := ReadTPendaftaranDetailData(syncLink.Simgos_Id, &event) if err != nil { return nil, err } @@ -324,7 +321,7 @@ func Cancel(input e.Encounter) (*d.Data, error) { tx := db.NewTx() err = tx.Simgos.Transaction(func(tx *gorm.DB) error { // Step 2: Update Simgos - if err = UpdateTPendaftaranData(input, *simgos, "update-status", &event, tx); err != nil { + if err = UpdateTPendaftaranData(input, simgos, "update-status", &event, tx); err != nil { return err } @@ -343,6 +340,10 @@ func Cancel(input e.Encounter) (*d.Data, error) { } func RequestSwitchUnit(input e.Encounter) (*d.Data, error) { + var ( + syncLinkInternal *[]syncir.InternalReferenceLink + ) + event := pl.Event{ Feature: "RequestSwitchUnit", Source: source, @@ -352,26 +353,80 @@ func RequestSwitchUnit(input e.Encounter) (*d.Data, error) { pl.SetLogInfo(&event, input, "started", "request-switch-unit") // STEP 1: Get Link - syncLink, err := ReadDetailLinkData(uint16(input.Id), &event) + syncLink, err := ReadDetailLinkData(input.Id, &event) if err != nil { return nil, err } // STEP 2: Get Simgos - tpendaftaran, err := ReadTPendaftaranDetailData(uint16(syncLink.Simgos_Id), &event) + tpendaftaran, err := ReadTPendaftaranDetailData(syncLink.Simgos_Id, &event) + if err != nil { + return nil, err + } + + err = db.WithDualTx(func(tx *db.Dualtx) error { + // Step 3: Update TPendaftaran + if err = UpdateTPendaftaranData(input, tpendaftaran, "update-status", &event, tx.Simgos); err != nil { + return err + } + + // Step 4: Bulk Insert TPemeriksaanHist + tPemeriksanHistory, err := utph.CreateSimgosData(input, tpendaftaran, &event, tx.Simgos) + if err != nil { + return err + } + + // Step 5: Bulk Insert To Link + if syncLinkInternal, err = utph.CreateBulkLinkData(*input.InternalReferences, *tPemeriksanHistory, &event, tx.Sync); err != nil { + return err + } + + return nil + }) + + if err != nil { + if syncLinkInternal != nil { + go func() { _ = utph.DeleteLinkData(syncLinkInternal, &event) }() + } + return nil, err + } + + pl.SetLogInfo(&event, nil, "complete") + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "single-data", + "status": "updated", + }, + }, nil +} + +func ApproveSwitchUnit(input e.ApproveCancelUnitDto) (*d.Data, error) { + event := pl.Event{ + Feature: "ApproveSwitchUnit", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "approve-switch-unit") + + // STEP 1: Get InternalReference Link + syncLink, err := utph.ReadDetailLinkData(input.InternalReferences_Id, &event) + if err != nil { + return nil, err + } + + // STEP 2: Get TPemeriksaanHist + tPemeriksaanHist, err := utph.ReadDetailSimgosData(syncLink.Simgos_Id, &event) if err != nil { return nil, err } tx := db.NewTx() err = tx.Simgos.Transaction(func(tx *gorm.DB) error { - // Step 2: Update TPendaftaran - if err = UpdateTPendaftaranData(input, *tpendaftaran, "update-status", &event, tx); err != nil { - return err - } - - // Step 3: Insert TPemeriksaanHist - if _, err := CreateBulkTPemeriksaanHistData(input, *tpendaftaran, &event, tx); err != nil { + // Step 3: Update TPemeriksaanHist + if err := utph.UpdateSimgosData(input, tPemeriksaanHist, "approve", &event, tx); err != nil { return err } @@ -389,36 +444,31 @@ func RequestSwitchUnit(input e.Encounter) (*d.Data, error) { }, nil } -func ApproveSwitchUnit(input e.Encounter) (*d.Data, error) { +func CancelSwitchUnit(input e.ApproveCancelUnitDto) (*d.Data, error) { event := pl.Event{ - Feature: "RequestSwitchUnit", + Feature: "CancelSwitchUnit", Source: source, } // Start log - pl.SetLogInfo(&event, input, "started", "request-switch-unit") + pl.SetLogInfo(&event, input, "started", "cancel-switch-unit") - // STEP 1: Get Link - syncLink, err := ReadDetailLinkData(uint16(input.Id), &event) + // STEP 1: Get InternalReference Link + syncLink, err := utph.ReadDetailLinkData(input.InternalReferences_Id, &event) if err != nil { return nil, err } - // STEP 2: Get Simgos - tpendaftaran, err := ReadTPendaftaranDetailData(uint16(syncLink.Simgos_Id), &event) + // STEP 2: Get TPemeriksaanHist + tPemeriksaanHist, err := utph.ReadDetailSimgosData(syncLink.Simgos_Id, &event) if err != nil { return nil, err } tx := db.NewTx() err = tx.Simgos.Transaction(func(tx *gorm.DB) error { - // Step 2: Update TPendaftaran - if err = UpdateTPendaftaranData(input, *tpendaftaran, "update-status", &event, tx); err != nil { - return err - } - - // Step 3: Insert TPemeriksaanHist - if _, err := CreateBulkTPemeriksaanHistData(input, *tpendaftaran, &event, tx); err != nil { + // Step 3: Update TPemeriksaanHist + if err := utph.UpdateSimgosData(input, tPemeriksaanHist, "cancel", &event, tx); err != nil { return err } diff --git a/internal/use-case/simgos-sync-use-case/new/encounter/helper.go b/internal/use-case/simgos-sync-use-case/new/encounter/helper.go index a64a0c4e..3a190d56 100644 --- a/internal/use-case/simgos-sync-use-case/new/encounter/helper.go +++ b/internal/use-case/simgos-sync-use-case/new/encounter/helper.go @@ -6,7 +6,6 @@ package encounter import ( "encoding/json" - epr "simrs-vx/internal/domain/main-entities/person-relative" erc "simrs-vx/internal/domain/references/common" ere "simrs-vx/internal/domain/references/encounter" erp "simrs-vx/internal/domain/references/person" @@ -14,6 +13,9 @@ import ( "strconv" e "simrs-vx/internal/domain/main-entities/encounter" + epa "simrs-vx/internal/domain/main-entities/person-address" + epc "simrs-vx/internal/domain/main-entities/person-contact" + epr "simrs-vx/internal/domain/main-entities/person-relative" ep "simrs-vx/internal/domain/simgos-entities/m-pasien" etph "simrs-vx/internal/domain/simgos-entities/t-pemeriksaan-hist" etp "simrs-vx/internal/domain/simgos-entities/t-pendaftaran" @@ -47,20 +49,29 @@ func setDataCreateTPendaftaran(input *e.Encounter) (data etp.TPendaftaran, err e } data.NoKunjung = uint(noKunjung) - setDataTPendaftaran(input, data) + if p := input.Patient.Person; p != nil { + mapRelative(p.Relatives, &data) + + if data.PenanggungjawabNama == "" { + data.PenanggungjawabHubungan = "DIRI SENDIRI" + data.PenanggungjawabNama = p.Name + mapContact(p.Contacts, &data) + mapAddress(p.Addresses, &data) + } + + if bpjs := p.VclaimMember; bpjs != nil { + data.Nokartu = *bpjs.CardNumber + } + } + + setDataTPendaftaran(input, &data) return } -func setDataTPendaftaran(input *e.Encounter, data etp.TPendaftaran) { +func setDataTPendaftaran(input *e.Encounter, data *etp.TPendaftaran) { data.Tglreg = input.RegisteredAt - // set kddokter - if d := input.Appointment_Doctor_Code; d != nil { - kddokter, _ := strconv.Atoi(*input.Appointment_Doctor_Code) - data.Kddokter = uint(kddokter) - } - // set kdpoly if p := input.Unit_Code; p != nil { kdpoly, _ := strconv.Atoi(*input.Unit_Code) @@ -82,22 +93,18 @@ func setDataTPendaftaran(input *e.Encounter, data etp.TPendaftaran) { } } - if ref := input.VclaimReference; ref != nil { - data.Ketrujuk = *ref.SrcCode - data.Norujukan = *ref.Number - data.Tglrujukan = ref.Date + // set data if payment_method bpjs + if input.RefSource_Name != nil { + data.Ketrujuk = *input.RefSource_Name data.Strujukan = 1 } else { data.Ketrujuk = "TR" data.Strujukan = 0 } - if p := input.Patient.Person; p != nil { - mapRelative(p.Relatives, data) - - if bpjs := p.VclaimMember; bpjs != nil { - data.Nokartu = *bpjs.CardNumber - } + if ref := input.VclaimReference; ref != nil { + data.Norujukan = *ref.Number + data.Tglrujukan = ref.Date } data.Jamreg = input.RegisteredAt @@ -107,16 +114,35 @@ func setDataTPendaftaran(input *e.Encounter, data etp.TPendaftaran) { return } -func setDataCheckIn(input e.Encounter, data etp.TPendaftaran) { +func setDataUpdateStatus(input e.Encounter, data *etp.TPendaftaran) { + switch input.Status_Code { + case erc.DSCProcess: + data.Masukpoly = &now + } + + if input.Status_Code == erc.DSCCancel { + data.Status = 11 + return + } + + if input.Discharge_Method_Code != nil { + setStatus(input.Discharge_Method_Code, data) + } +} + +func setDataCheckIn(input e.Encounter, data *etp.TPendaftaran) { // set kddokter kddokter, _ := strconv.Atoi(*input.Responsible_Doctor_Code) data.Kddokter = uint(kddokter) // set petugas_klinik - if data.PetugasKlinik != "" { - if a := input.Adm_Employee; a != nil { - if u := a.User; u != nil { - data.PetugasKlinik = u.Name + // only update once + if data.PetugasKlinik == "" { + if n := input.Responsible_Nurse; n != nil { + if emp := n.Employee; emp != nil { + if u := emp.User; u != nil { + data.PetugasKlinik = u.Name + } } } } @@ -125,21 +151,60 @@ func setDataCheckIn(input e.Encounter, data etp.TPendaftaran) { return } -func setDataRequestSwitchUnit(input e.Encounter, data etp.TPendaftaran) (hist []etph.TPemeriksaanHist) { +func setDataCheckOut(input e.Encounter, data *etp.TPendaftaran) { + data.Keluarpoly = input.FinishedAt + + // set status + setStatus(input.Discharge_Method_Code, data) + if data.Status == 8 || data.Status == 3 { + if dc := input.DeathCause; dc != nil { + var dcSrc []DeathCauseSrc + _ = json.Unmarshal([]byte(*dc.Value), &dcSrc) + + for i, v := range dcSrc { + switch i { + case 0: + data.SebabMati1 = &v.Name + data.IcdMati1 = &v.Code + case 1: + data.SebabMati2 = &v.Name + data.IcdMati2 = &v.Code + case 2: + data.SebabMati3 = &v.Name + data.IcdMati3 = &v.Code + default: + break + } + } + } + death := uint(1) + data.StMeninggal = &death + data.DtMeninggal = data.Keluarpoly + } + + setPelayanan := uint(1) + data.StPelayanan = &setPelayanan + + return +} + +func setDataRequestSwitchUnit(input e.Encounter, data *etp.TPendaftaran) (hist []etph.TPemeriksaanHist) { if enc := input.InternalReferences; enc != nil { for i, ref := range *enc { hist = append(hist, etph.TPemeriksaanHist{ Idxdaftar: &data.Idxdaftar, Kdpoly: stringtouint(*ref.Unit_Code), - DokterPengonsul: stringtouint(*input.Responsible_Doctor_Code), + DokterPengonsul: stringtouint(*ref.SrcDoctor_Code), DokterPenerima: stringtouint(*ref.Doctor_Code), StartKonsul: &now, }) // set user konsul - if emp := input.Adm_Employee; emp != nil { - if u := emp.User; u != nil { - hist[i].UserKonsul = &u.Name + if n := input.Responsible_Nurse; n != nil { + if emp := n.Employee; emp != nil { + if u := emp.User; u != nil { + hist[i].UserKonsul = &u.Name + } } } @@ -151,31 +216,7 @@ func setDataRequestSwitchUnit(input e.Encounter, data etp.TPendaftaran) (hist [] return } -func setDataCheckOut(input e.Encounter, data etp.TPendaftaran) { - data.Keluarpoly = input.Discharge_Date - - // set status - setStatus(input.Discharge_Method_Code, data) - if data.Status == 8 || data.Status == 3 { - if dc := input.DeathCause; dc != nil { - data.SebabMati1 = dc.Value - } - - } - - setPelayanan := uint(1) - data.StPelayanan = &setPelayanan - - return -} - -func setDataUpdateStatus(input e.Encounter, data etp.TPendaftaran) { - if input.Status_Code == erc.DSCCancel { - data.Status = 11 - } -} - -func setKdrujuk(input *ere.RefTypeCode, data etp.TPendaftaran) { +func setKdrujuk(input *ere.RefTypeCode, data *etp.TPendaftaran) { switch *input { case ere.RTCGov: data.Kdrujuk = 1 @@ -188,7 +229,7 @@ func setKdrujuk(input *ere.RefTypeCode, data etp.TPendaftaran) { } } -func setKdcarabayar(input ere.AllPaymentMethodCode, data etp.TPendaftaran) { +func setKdcarabayar(input ere.AllPaymentMethodCode, data *etp.TPendaftaran) { switch input { case ere.APMCPks: data.Kdcarabayar = 12 @@ -203,7 +244,7 @@ func setKdcarabayar(input ere.AllPaymentMethodCode, data etp.TPendaftaran) { } } -func setStatus(code *ere.DischargeMethodCode, data etp.TPendaftaran) { +func setStatus(code *ere.DischargeMethodCode, data *etp.TPendaftaran) { switch *code { case ere.DMCHome: data.Status = 1 @@ -221,24 +262,12 @@ func setStatus(code *ere.DischargeMethodCode, data etp.TPendaftaran) { data.Status = 7 case ere.DMCConsulPoly: data.Status = 5 - data.PoliNameHfis = nil - data.SpesialisIdHfis = nil - data.DokterNameHfis = nil - data.DokterIdHfis = nil case ere.DMCExtRef: data.Status = 6 case ere.DMCConsulChDay: data.Status = 12 - data.PoliNameHfis = nil - data.SpesialisIdHfis = nil - data.DokterNameHfis = nil - data.DokterIdHfis = nil case ere.DMCEmergency: data.Status = 10 - data.PoliNameHfis = nil - data.SpesialisIdHfis = nil - data.DokterNameHfis = nil - data.DokterIdHfis = nil case ere.DMCEmergencyCovid: data.Status = 13 case ere.DMCConsulExecutive: @@ -250,7 +279,7 @@ func setStatus(code *ere.DischargeMethodCode, data etp.TPendaftaran) { } } -func mapRelative(relative *[]epr.PersonRelative, data etp.TPendaftaran) { +func mapRelative(relative *[]epr.PersonRelative, data *etp.TPendaftaran) { if relative == nil || len(*relative) == 0 { return } @@ -322,10 +351,11 @@ func generateNoKunjung() (int, error) { // Lock rows for this prefix → prevents race condition if err := dg.IS["simrs"]. Table("t_pendaftaran"). - Select("COALESCE(MAX(no_kunjung),0)"). + Select("no_kunjung"). Where("tglreg = CURRENT_DATE"). Order("no_kunjung DESC"). Clauses(clause.Locking{Strength: "UPDATE"}). + Limit(1). Scan(&lastNumber).Error; err != nil { return 0, err } @@ -339,7 +369,7 @@ func stringtouint(v string) *uint { return &point } -func updatePatient(patient ep.MPasien, event *pl.Event, dbx ...*gorm.DB) error { +func updatePatientCaraBayar(input etp.TPendaftaran, event *pl.Event, dbx ...*gorm.DB) error { pl.SetLogInfo(event, nil, "started", "DBUpdate") var tx *gorm.DB @@ -350,19 +380,38 @@ func updatePatient(patient ep.MPasien, event *pl.Event, dbx ...*gorm.DB) error { } if err := tx.Model(&ep.MPasien{}). - Where("\"nomr\" = ?", patient.Nomr). - Updates(map[string]interface{}{ - "kdcarabayar": patient.Kdcarabayar, - }).Error; err != nil { + Where("\"nomr\" = ?", input.Nomr). + Update("kdcarabayar", input.Kdcarabayar).Error; err != nil { event.Status = "failed" event.ErrInfo = pl.ErrorInfo{ Code: "update-fail", Detail: "Failed to update patient", Raw: err, } - return pl.SetLogError(event, patient) + return pl.SetLogError(event, input) } - pl.SetLogInfo(event, patient, "complete") + pl.SetLogInfo(event, input, "complete") return nil } + +func mapContact(contact *[]epc.PersonContact, data *etp.TPendaftaran) { + if contact == nil || len(*contact) == 0 { + return + } + + for _, c := range *contact { + if c.Type_Code == erp.CTPhone || c.Type_Code == erp.CTMPhone { + data.PenanggungjawabPhone = c.Value + break + } + } +} + +func mapAddress(addresses *[]epa.PersonAddress, data *etp.TPendaftaran) { + if addresses == nil || len(*addresses) == 0 { + return + } + a := (*addresses)[0] + data.PenanggungjawabAlamat = a.Address +} diff --git a/internal/use-case/simgos-sync-use-case/new/encounter/lib.go b/internal/use-case/simgos-sync-use-case/new/encounter/lib.go index 064131e5..47d50802 100644 --- a/internal/use-case/simgos-sync-use-case/new/encounter/lib.go +++ b/internal/use-case/simgos-sync-use-case/new/encounter/lib.go @@ -41,7 +41,7 @@ func CreateTPendaftaranData(input e.Encounter, event *pl.Event, dbx ...*gorm.DB) return &data, nil } -func ReadTPendaftaranDetailData(simgosId uint16, event *pl.Event) (*etp.TPendaftaran, error) { +func ReadTPendaftaranDetailData(simgosId uint, event *pl.Event) (*etp.TPendaftaran, error) { pl.SetLogInfo(event, simgosId, "started", "DBReadDetail") data := etp.TPendaftaran{} @@ -59,7 +59,7 @@ func ReadTPendaftaranDetailData(simgosId uint16, event *pl.Event) (*etp.TPendaft return &data, nil } -func UpdateTPendaftaranData(input e.Encounter, data etp.TPendaftaran, method string, event *pl.Event, dbx ...*gorm.DB) error { +func UpdateTPendaftaranData(input e.Encounter, data *etp.TPendaftaran, method string, event *pl.Event, dbx ...*gorm.DB) error { pl.SetLogInfo(event, input, "started", "DBUpdate") switch method { @@ -138,7 +138,26 @@ func CreateLinkData(simxId, simgosId uint, event *pl.Event, dbx ...*gorm.DB) (*e return &data, nil } -func ReadDetailLinkData(simxId uint16, event *pl.Event) (*esync.EncounterLink, error) { +func CreateBulkLinkData(simxId, simgosId uint, event *pl.Event, dbx ...*gorm.DB) (*esync.EncounterLink, error) { + pl.SetLogInfo(event, nil, "started", "DBCreate") + data := setDataSimxLink(simxId, simgosId) + + 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(data, event, err) + } + + pl.SetLogInfo(event, nil, "complete") + return &data, nil +} + +func ReadDetailLinkData(simxId uint, event *pl.Event) (*esync.EncounterLink, error) { pl.SetLogInfo(event, simxId, "started", "DBReadDetail") data := esync.EncounterLink{} @@ -199,7 +218,7 @@ func CreateLogData(input esynclog.SimxLogDto, event *pl.Event, dbx ...*gorm.DB) return nil } -func CreateBulkTPemeriksaanHistData(input e.Encounter, data etp.TPendaftaran, event *pl.Event, dbx ...*gorm.DB) (hist []etph.TPemeriksaanHist, err error) { +func CreateBulkTPemeriksaanHistData(input e.Encounter, data *etp.TPendaftaran, event *pl.Event, dbx ...*gorm.DB) (hist []etph.TPemeriksaanHist, err error) { pl.SetLogInfo(event, nil, "started", "DBCreate") hist = setDataRequestSwitchUnit(input, data) @@ -218,3 +237,27 @@ func CreateBulkTPemeriksaanHistData(input e.Encounter, data etp.TPendaftaran, ev pl.SetLogInfo(event, nil, "complete") return hist, nil } + +func UpdateTPemeriksaanHistData(input e.ApproveCancelUnitDto, data *etph.TPemeriksaanHist, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, input, "started", "DBUpdateTPemeriksaanHist") + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.IS["simrs"] + } + + 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 +} diff --git a/internal/use-case/simgos-sync-use-case/new/encounter/tycovar.go b/internal/use-case/simgos-sync-use-case/new/encounter/tycovar.go index 17890a1b..7d3d19db 100644 --- a/internal/use-case/simgos-sync-use-case/new/encounter/tycovar.go +++ b/internal/use-case/simgos-sync-use-case/new/encounter/tycovar.go @@ -42,3 +42,10 @@ var updatePreMw []readDetailMw var updatePostMw []readDetailMw var deletePreMw []readDetailMw var deletePostMw []readDetailMw + +type DeathCauseSrc struct { + Id uint `json:"id"` + Code string `json:"code"` + Name string `json:"name"` + IndName string `json:"indName"` +} diff --git a/internal/use-case/simgos-sync-use-case/new/internal-reference/helper.go b/internal/use-case/simgos-sync-use-case/new/internal-reference/helper.go new file mode 100644 index 00000000..9cb55785 --- /dev/null +++ b/internal/use-case/simgos-sync-use-case/new/internal-reference/helper.go @@ -0,0 +1,103 @@ +/* +DESCRIPTION: +Any functions that are used internally by the use-case +*/ +package internal_reference + +import ( + "encoding/json" + eir "simrs-vx/internal/domain/main-entities/internal-reference" + erc "simrs-vx/internal/domain/references/common" + "strconv" + + e "simrs-vx/internal/domain/main-entities/encounter" + + etph "simrs-vx/internal/domain/simgos-entities/t-pemeriksaan-hist" + etp "simrs-vx/internal/domain/simgos-entities/t-pendaftaran" + + esync "simrs-vx/internal/domain/sync-entities/internal-reference" + esyncLog "simrs-vx/internal/domain/sync-entities/log" +) + +func setCreateDataSimgos(input e.Encounter, data *etp.TPendaftaran) (hist []etph.TPemeriksaanHist) { + if enc := input.InternalReferences; enc != nil { + for i, ref := range *enc { + hist = append(hist, etph.TPemeriksaanHist{ + Idxdaftar: &data.Idxdaftar, + Kdpoly: stringtouint(*ref.Unit_Code), + DokterPengonsul: stringtouint(*ref.SrcDoctor_Code), + DokterPenerima: stringtouint(*ref.Doctor_Code), + }) + + // set user konsul + if n := input.Responsible_Nurse; n != nil { + if emp := n.Employee; emp != nil { + if u := emp.User; u != nil { + hist[i].UserKonsul = &u.Name + } + } + } + + // setaktif + aktif := uint16(1) + hist[i].StAktif = &aktif + } + } + return +} + +func setUpdateApproveDataSimgos(input e.ApproveCancelUnitDto, data *etph.TPemeriksaanHist) { + data.DokterPenerima = stringtouint(*input.Dst_Doctor_Code) + data.StartKonsul = &now + data.UserPenerima = &input.User_Name + data.MasukPoly = data.StartKonsul + return +} + +func setUpdateCancelDataSimgos(input e.ApproveCancelUnitDto, data *etph.TPemeriksaanHist) { + data.UserBatal = &input.User_Name + data.TglBatal = &now + + aktif := uint16(0) + data.StAktif = &aktif + + return +} + +func setDataSimxLog(input *esyncLog.SimxLogDto) (data esync.InternalReferenceSimxLog) { + // encode to JSON + jsonData, _ := json.MarshalIndent(input.Payload, "", " ") + jsonString := string(jsonData) + + var status erc.ProcessStatusCode + if input.IsSuccess { + status = erc.PSCSuccess + } else { + status = erc.PSCFailed + if input.ErrMessage != nil { + data.ErrMessage = input.ErrMessage + } + } + + data.Value = &jsonString + data.Date = &now + data.Status = status + + return +} + +func setDataSimxLink(ir []eir.InternalReference, tph []etph.TPemeriksaanHist) (data []esync.InternalReferenceLink) { + for i := range len(ir) { + data = append(data, esync.InternalReferenceLink{ + Simx_Id: ir[i].Id, + Simgos_Id: tph[i].IdPemeriksaanHist, + }) + } + return +} + +func stringtouint(v string) *uint { + u, _ := strconv.Atoi(v) + point := uint(u) + return &point +} diff --git a/internal/use-case/simgos-sync-use-case/new/internal-reference/lib.go b/internal/use-case/simgos-sync-use-case/new/internal-reference/lib.go new file mode 100644 index 00000000..2263f230 --- /dev/null +++ b/internal/use-case/simgos-sync-use-case/new/internal-reference/lib.go @@ -0,0 +1,173 @@ +package internal_reference + +import ( + plh "simrs-vx/pkg/lib-helper" + pl "simrs-vx/pkg/logger" + pu "simrs-vx/pkg/use-case-helper" + "time" + + dg "github.com/karincake/apem/db-gorm-pg" + "gorm.io/gorm" + + e "simrs-vx/internal/domain/main-entities/encounter" + eir "simrs-vx/internal/domain/main-entities/internal-reference" + + etph "simrs-vx/internal/domain/simgos-entities/t-pemeriksaan-hist" + etp "simrs-vx/internal/domain/simgos-entities/t-pendaftaran" + + esync "simrs-vx/internal/domain/sync-entities/internal-reference" + esynclog "simrs-vx/internal/domain/sync-entities/log" +) + +const source = "internal-reference" + +var now = time.Now() + +func CreateSimgosData(input e.Encounter, dataDaftar *etp.TPendaftaran, event *pl.Event, dbx ...*gorm.DB) (*[]etph.TPemeriksaanHist, error) { + pl.SetLogInfo(event, nil, "started", "DBCreate") + + data := setCreateDataSimgos(input, dataDaftar) + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.IS["simrs"] + } + + if err := tx.Create(&data).Error; err != nil { + return nil, plh.HandleCreateError(input, event, err) + } + + pl.SetLogInfo(event, nil, "complete") + return &data, nil +} + +func ReadDetailSimgosData(simgosId uint, event *pl.Event) (*etph.TPemeriksaanHist, error) { + pl.SetLogInfo(event, simgosId, "started", "DBReadDetail") + data := etph.TPemeriksaanHist{} + + var tx = dg.IS["simrs"] + + if err := tx. + Where("\"id_pemeriksaanhist\" = ?", simgosId). + First(&data).Error; err != nil { + if processedErr := pu.HandleReadError(err, event, source, simgosId, data); processedErr != nil { + return nil, processedErr + } + } + + pl.SetLogInfo(event, nil, "complete") + return &data, nil +} + +func UpdateSimgosData(input e.ApproveCancelUnitDto, data *etph.TPemeriksaanHist, method string, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, input, "started", "DBUpdate") + + switch method { + case "approve": + setUpdateApproveDataSimgos(input, data) + case "cancel": + setUpdateCancelDataSimgos(input, data) + } + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.IS["simrs"] + } + + 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 CreateBulkLinkData(ir []eir.InternalReference, tph []etph.TPemeriksaanHist, event *pl.Event, dbx ...*gorm.DB) (*[]esync.InternalReferenceLink, error) { + pl.SetLogInfo(event, nil, "started", "DBCreate") + data := setDataSimxLink(ir, tph) + + 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(data, event, err) + } + + pl.SetLogInfo(event, nil, "complete") + return &data, nil +} + +func ReadDetailLinkData(simxId uint, event *pl.Event) (*esync.InternalReferenceLink, error) { + pl.SetLogInfo(event, simxId, "started", "DBReadDetail") + data := esync.InternalReferenceLink{} + + var tx = dg.I + + if err := tx. + Where("\"Simx_Id\" = ?", simxId). + First(&data).Error; err != nil { + if processedErr := pu.HandleReadError(err, event, source, simxId, data); processedErr != nil { + return nil, processedErr + } + } + + pl.SetLogInfo(event, nil, "complete") + return &data, nil +} + +func DeleteLinkData(data *[]esync.InternalReferenceLink, 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 CreateLogData(input esynclog.SimxLogDto, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, nil, "started", "DBCreate") + data := setDataSimxLog(&input) + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Create(&data).Error; err != nil { + return plh.HandleCreateError(input, event, err) + } + + pl.SetLogInfo(event, nil, "complete") + return nil +} diff --git a/internal/use-case/simgos-sync-use-case/new/internal-reference/middleware-runner.go b/internal/use-case/simgos-sync-use-case/new/internal-reference/middleware-runner.go new file mode 100644 index 00000000..344bbe93 --- /dev/null +++ b/internal/use-case/simgos-sync-use-case/new/internal-reference/middleware-runner.go @@ -0,0 +1,103 @@ +package internal_reference + +import ( + e "simrs-vx/internal/domain/main-entities/internal-reference" + 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.InternalReference) 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.InternalReference) 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.InternalReference) 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.InternalReference) 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.InternalReference) 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/simgos-sync-use-case/new/internal-reference/middleware.go b/internal/use-case/simgos-sync-use-case/new/internal-reference/middleware.go new file mode 100644 index 00000000..2afd1eaf --- /dev/null +++ b/internal/use-case/simgos-sync-use-case/new/internal-reference/middleware.go @@ -0,0 +1,9 @@ +package internal_reference + +// 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/simgos-sync-use-case/new/internal-reference/tycovar.go b/internal/use-case/simgos-sync-use-case/new/internal-reference/tycovar.go new file mode 100644 index 00000000..4cb6c572 --- /dev/null +++ b/internal/use-case/simgos-sync-use-case/new/internal-reference/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 internal_reference + +import ( + "gorm.io/gorm" + + e "simrs-vx/internal/domain/main-entities/internal-reference" +) + +type createMw struct { + Name string + Func func(input *e.CreateDto, data *e.InternalReference, tx *gorm.DB) error +} + +type readListMw struct { + Name string + Func func(input *e.ReadListDto, data *e.InternalReference, tx *gorm.DB) error +} + +type readDetailMw struct { + Name string + Func func(input *e.ReadDetailDto, data *e.InternalReference, 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/simgos-sync-use-case/new/patient/helper.go b/internal/use-case/simgos-sync-use-case/new/patient/helper.go index 14f516d5..532574b2 100644 --- a/internal/use-case/simgos-sync-use-case/new/patient/helper.go +++ b/internal/use-case/simgos-sync-use-case/new/patient/helper.go @@ -37,12 +37,15 @@ func setDataSimgos(input *e.Patient) (data esimgos.MPasien) { mapContact(input.Person.Contacts, &data) } - data.PenanggungjawabHubungan = "DIRI SENDIRI" - data.PenanggungjawabNama = input.Person.Name - data.PenanggungjawabPhone = data.Notelp - data.PenanggungjawabAlamat = data.Alamat - if input.Person != nil || input.Person.Relatives != nil { - mapRelative(input.Person.Relatives, &data) + if input.Person != nil { + data.PenanggungjawabHubungan = "DIRI SENDIRI" + data.PenanggungjawabNama = input.Person.Name + data.PenanggungjawabPhone = data.Notelp + data.PenanggungjawabAlamat = data.Alamat + + if input.Person.Relatives != nil { + mapRelative(input.Person.Relatives, &data) + } } data.Nip = input.RegisteredBy_User_Name diff --git a/internal/use-case/simgos-sync-use-case/new/specialist/helper.go b/internal/use-case/simgos-sync-use-case/new/specialist/helper.go index 4a155496..adce079f 100644 --- a/internal/use-case/simgos-sync-use-case/new/specialist/helper.go +++ b/internal/use-case/simgos-sync-use-case/new/specialist/helper.go @@ -14,7 +14,7 @@ import ( esync "simrs-vx/internal/domain/sync-entities/specialist" ) -func setDataSimgos[T *e.CreateDto | *e.UpdateDto](input T) (data esimgos.MPolihfis) { +func setDataSimgos[T *e.CreateDto | *e.UpdateDto](input T, data *esimgos.MPolihfis) { var inputSrc *e.CreateDto if inputT, ok := any(input).(*e.CreateDto); ok { inputSrc = inputT diff --git a/internal/use-case/simgos-sync-use-case/new/specialist/lib.go b/internal/use-case/simgos-sync-use-case/new/specialist/lib.go index c796af73..0aee2ceb 100644 --- a/internal/use-case/simgos-sync-use-case/new/specialist/lib.go +++ b/internal/use-case/simgos-sync-use-case/new/specialist/lib.go @@ -20,7 +20,8 @@ var now = time.Now() func CreateSimgosData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*esimgos.MPolihfis, error) { pl.SetLogInfo(event, nil, "started", "DBCreate") - data := setDataSimgos(&input) + data := esimgos.MPolihfis{} + setDataSimgos(&input, &data) var tx *gorm.DB if len(dbx) > 0 { @@ -29,7 +30,7 @@ func CreateSimgosData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*esi tx = dg.IS["simrs"] } - if err := tx.Create(&data).Error; err != nil { + if err := tx.Debug().Create(&data).Error; err != nil { return nil, plh.HandleCreateError(input, event, err) } @@ -58,7 +59,9 @@ func ReadDetailSimgosData(simgosId uint16, event *pl.Event) (*esimgos.MPolihfis, func UpdateSimgosData(input e.UpdateDto, dataSimgos *esync.SpecialistLink, event *pl.Event, dbx ...*gorm.DB) error { pl.SetLogInfo(event, input, "started", "DBUpdate") - data := setDataSimgos(&input) + data := esimgos.MPolihfis{} + + setDataSimgos(&input, &data) data.Id = dataSimgos.Simgos_Id var tx *gorm.DB diff --git a/internal/use-case/simgos-sync-use-case/new/unit/helper.go b/internal/use-case/simgos-sync-use-case/new/unit/helper.go index 667bb7f0..d7dfb1f6 100644 --- a/internal/use-case/simgos-sync-use-case/new/unit/helper.go +++ b/internal/use-case/simgos-sync-use-case/new/unit/helper.go @@ -7,6 +7,7 @@ package unit import ( "encoding/json" erc "simrs-vx/internal/domain/references/common" + "strconv" e "simrs-vx/internal/domain/main-entities/unit" @@ -27,6 +28,8 @@ func setDataSimgos[T *e.CreateDto | *e.UpdateDto](input T) (data esimgos.MPoly) data.Nama = inputSrc.Name data.Jenispoly = 0 + kodePoly, _ := strconv.Atoi(inputSrc.Code) + data.Kode = uint(kodePoly) return } diff --git a/pkg/dualtrx-helper/dualtrx-helper.go b/pkg/dualtrx-helper/dualtrx-helper.go index 2f16203c..144337c5 100644 --- a/pkg/dualtrx-helper/dualtrx-helper.go +++ b/pkg/dualtrx-helper/dualtrx-helper.go @@ -11,9 +11,12 @@ type Dualtx struct { } func NewDualtx() *Dualtx { + simgosTx := dg.IS["simrs"].Begin() + simgosTx.Exec(`SET LOCAL simx.sync_source = 'new'`) + return &Dualtx{ Sync: dg.I.Begin(), - Simgos: dg.IS["simrs"].Begin(), + Simgos: simgosTx, } }