diff --git a/assets/docs/resume.html b/assets/docs/resume.html new file mode 100644 index 00000000..4ad209ff --- /dev/null +++ b/assets/docs/resume.html @@ -0,0 +1,707 @@ + + +
+ +
+
+ |
+
+
+ PEMERINTAH PROVINSI JAWA TIMUR
+
+
+ RUMAH SAKIT UMUM DAERAH Dr. SAIFUL ANWAR
+
+
+ TERAKREDITASI KARS VERSI 2012 TINGKAT PARIPURNA
+
+
+ Jl. Jaksa Agung Suprapto No. 2 MALANG 65111
+
+ Telp. (0341) 362101, Fax. (0341) 362110
+ Email: rsu-drsaifulanwar@jatimprov.go.id
+ Website: www.rsudsaifulanwar.jatimprov.go.id
+ |
+
+
+ |
+
| + No. RM + | +: | +{{ .MedicalRecord }} | ++ Ruang/Klinik + | +: | +{{ .Unit }} | +
| + NIK + | +: | +{{ .NIK }} | ++ Kelas + | +: | +{{ .Class }} | +
| + Nama + | +: | +{{ .Name }} | ++ DPJP + | +: | +{{ .Doctor_Name }} | ++ + + |
| + Tempat/Tanggal Lahir + | +: | +{{ .BirthPlaceDate }} | +|||
| + Jenis Kelamin + | +: | +{{ .Gender }} | +|||
| + No. Telepon + | +: | +{{ .Phone }} | +
Medical Discharge Summary
+ + +(Diisi oleh Dokter Penanggung Jawab Pelayanan)
+| + Tanggal Masuk + | +: | +{{ .StartedAt }} | +
| + Tanggal Keluar + | +: | +{{ .FinishedAt }} | +
| + Diagnosis Masuk + | +: | +{{ .DiagnosisIn }} | +
| + Diagnosis Keluar + | +: | +{{ .DiagnosisOut }} | +
| + No + | ++ Diagnosa + | ++ Dasar Diagnosa + | ++ Kode ICD-10 + | +
|---|---|---|---|
| {{ if eq $index 0 }}1{{ else if eq $index 1 }}2{{ else if eq $index 2 }}3{{ else if eq $index 3 }}4{{ else if eq $index 4 }}5{{ else }}{{ $index }}{{ end }} | +{{ $diagnosis.DiagnosisName }} | +{{ $diagnosis.Basis }} | +{{ $diagnosis.ICD10 }} | +
| 2 | ++ | + | + |
| 1 | ++ | + | + |
| 2 | ++ | + | + |
(Diisi oleh Dokter Penanggung Jawab Pelayanan)
+ +| + Keluhan Utama + | +: | +{{ .MainComplaint }} | +
| + Riwayat Penyakit + | +: | +{{ .MedicalHistory }} | +
| + Pemeriksaan Fisik & Keadaan Umum + | +: | +{{ .PhysicalExamination }} | +
| + Pemeriksaan + | +: | +{{ .SupportingExamination }} | +
| + No + | ++ Tindakan + | ++ Dasar Tindakan + | ++ Kode ICD 9-CM + | +
|---|---|---|---|
| {{ if eq $index 0 }}1{{ else if eq $index 1 }}2{{ else if eq $index 2 }}3{{ else if eq $index 3 }}4{{ else if eq $index 4 }}5{{ else }}{{ $index }}{{ end }} | +{{ $action.Action }} | +{{ $action.Basis }} | +{{ $action.ICD9 }} | +
| 2 | ++ | + | + |
| 1 | ++ | + | + |
| 2 | ++ | + | + |
| + Tindakan Medis + | +: | +{{ .MedicalAction }} | +
+ Konsultasi+ |
| No | +Konsultasi | +Jawaban Konsultasi | +
|---|---|---|
| {{ if eq $index 0 }}1{{ else if eq $index 1 }}2{{ else if eq $index 2 }}3{{ else if eq $index 3 }}4{{ else if eq $index 4 }}5{{ else }}{{ $index }}{{ end }} | +{{ $consultation.Consultation }} | +{{ $consultation.ConsultationAnswer }} | +
| 2 | ||
| 1 | ||
| 2 |
| + Alergi + | +: | ++ {{ .Allergy}} + | +
+ Obat yang diberikan+
|
+
| Kesadaran | +: | +{{ .ConsciousnessLevel }} | +||||||||||||||||||||||||||||
|
+ Tanda Vital
+ Vital sign + |
+ : | +|||||||||||||||||||||||||||||
+
|
+ ||||||||||||||||||||||||||||||
| Keadaan Keluar | +: | +{{ .ConditionOnDischarge }} | +||||||||||||||||||||||||||||
| Cara Keluar
+ Patient discharge of hospital + |
+ : | +{{ .DischargeMethod }} | +||||||||||||||||||||||||||||
+ INSTRUKSI UNTUK TINDAK LANJUT+Follow up Consultation to + |
+
+ Kontrol Ke+Follow up Consultation to + |
+
+
|
+ |||||||||
+ Dalam keadaan darurat dapat menghubungi+In case of emergencycontact + |
+
+ IGD+(Accident & Emergency Instalation) + |
+
+
|
+ |||||||||
+ EDUKASI & RENCANA TINDAK LANJUT+Follow up plan (if necessary) + |
+
+
+ (bila diperlukan) + |
+
| + |
+ Malang, {{ .Date }} + Dokter Penanggung Jawab Pelayanan + |
+
| + | + ({{ .Doctor_Name }}) + | +
*) Data dapat berubah setelah pasien pulang sesuai prosedur
+ + + + \ No newline at end of file diff --git a/cmd/bpjs-api/config.yml-example b/cmd/bpjs-api/config.yml-example index 60b1644c..dcea2f07 100644 --- a/cmd/bpjs-api/config.yml-example +++ b/cmd/bpjs-api/config.yml-example @@ -57,9 +57,6 @@ corsCfg: satuSehatCfg: host: localhost:8200 -bpjsCfg: - host: localhost:8200 - corsCfg: allowedOrigins: - http://example.com diff --git a/cmd/main-api/config.yml-example b/cmd/main-api/config.yml-example index 5915c46c..fcc2f53d 100644 --- a/cmd/main-api/config.yml-example +++ b/cmd/main-api/config.yml-example @@ -57,9 +57,6 @@ corsCfg: satuSehatCfg: host: localhost:8200 -bpjsCfg: - host: localhost:8200 - corsCfg: allowedOrigins: - http://example.com diff --git a/cmd/main-migration/migrations/20251201081333.sql b/cmd/main-migration/migrations/20251201081333.sql new file mode 100644 index 00000000..876b32b7 --- /dev/null +++ b/cmd/main-migration/migrations/20251201081333.sql @@ -0,0 +1,13 @@ +-- Create "Screening" table +CREATE TABLE "public"."Screening" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "Encounter_Id" bigint NULL, + "Employee_Id" bigint NULL, + "Type" text NULL, + "Value" text NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "fk_Screening_Employee" FOREIGN KEY ("Employee_Id") REFERENCES "public"."Employee" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION +); diff --git a/cmd/main-migration/migrations/20251201104439.sql b/cmd/main-migration/migrations/20251201104439.sql new file mode 100644 index 00000000..50f60b6b --- /dev/null +++ b/cmd/main-migration/migrations/20251201104439.sql @@ -0,0 +1,19 @@ +-- Create "ActionReport" table +CREATE TABLE "public"."ActionReport" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "Encounter_Id" bigint NULL, + "Date" character varying(20) NOT NULL, + "Doctor_Code" character varying(10) NULL, + "Operator_Employe_Id" bigint NULL, + "Assistant_Employe_Id" bigint NULL, + "Instrumentor_Employe_Id" bigint NULL, + "Diagnose" character varying(1024) NULL, + "Procedures" character varying(10240) NULL, + "Nurse_Code" character varying(10) NULL, + "Value" text NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "fk_ActionReport_Encounter" FOREIGN KEY ("Encounter_Id") REFERENCES "public"."Encounter" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION +); diff --git a/cmd/main-migration/migrations/20251201113804.sql b/cmd/main-migration/migrations/20251201113804.sql new file mode 100644 index 00000000..0f5c5123 --- /dev/null +++ b/cmd/main-migration/migrations/20251201113804.sql @@ -0,0 +1,2 @@ +-- Modify "ActionReport" table +ALTER TABLE "public"."ActionReport" DROP COLUMN "Date", DROP COLUMN "Procedures"; diff --git a/cmd/main-migration/migrations/20251201113858.sql b/cmd/main-migration/migrations/20251201113858.sql new file mode 100644 index 00000000..fd6fddc9 --- /dev/null +++ b/cmd/main-migration/migrations/20251201113858.sql @@ -0,0 +1,2 @@ +-- Modify "ActionReport" table +ALTER TABLE "public"."ActionReport" ADD COLUMN "Date" timestamptz NOT NULL; diff --git a/cmd/main-migration/migrations/20251201114751.sql b/cmd/main-migration/migrations/20251201114751.sql new file mode 100644 index 00000000..6611b811 --- /dev/null +++ b/cmd/main-migration/migrations/20251201114751.sql @@ -0,0 +1,2 @@ +-- Modify "ActionReport" table +ALTER TABLE "public"."ActionReport" ADD CONSTRAINT "fk_ActionReport_Instrumentor_Employe" FOREIGN KEY ("Instrumentor_Employe_Id") REFERENCES "public"."Employee" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION, ADD CONSTRAINT "fk_ActionReport_Nurse" FOREIGN KEY ("Nurse_Code") REFERENCES "public"."Nurse" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION, ADD CONSTRAINT "fk_ActionReport_Operator_Employe" FOREIGN KEY ("Operator_Employe_Id") REFERENCES "public"."Employee" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION; diff --git a/cmd/main-migration/migrations/20251201114913.sql b/cmd/main-migration/migrations/20251201114913.sql new file mode 100644 index 00000000..5155ed37 --- /dev/null +++ b/cmd/main-migration/migrations/20251201114913.sql @@ -0,0 +1,2 @@ +-- Modify "ActionReport" table +ALTER TABLE "public"."ActionReport" ADD CONSTRAINT "fk_ActionReport_Doctor" FOREIGN KEY ("Doctor_Code") REFERENCES "public"."Doctor" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION; diff --git a/cmd/main-migration/migrations/20251202030445.sql b/cmd/main-migration/migrations/20251202030445.sql new file mode 100644 index 00000000..6026dd58 --- /dev/null +++ b/cmd/main-migration/migrations/20251202030445.sql @@ -0,0 +1,2 @@ +-- Modify "Screening" table +ALTER TABLE "public"."Screening" ADD COLUMN "Status" text NULL, ADD COLUMN "FileUrl" character varying(1024) NULL; diff --git a/cmd/main-migration/migrations/20251202044430.sql b/cmd/main-migration/migrations/20251202044430.sql new file mode 100644 index 00000000..308b72a7 --- /dev/null +++ b/cmd/main-migration/migrations/20251202044430.sql @@ -0,0 +1,2 @@ +-- Modify "Item" table +ALTER TABLE "public"."Item" ADD COLUMN "BuyingPrice" numeric NULL, ADD COLUMN "SellingPrice" numeric NULL; diff --git a/cmd/main-migration/migrations/20251202064000.sql b/cmd/main-migration/migrations/20251202064000.sql new file mode 100644 index 00000000..7fed5f08 --- /dev/null +++ b/cmd/main-migration/migrations/20251202064000.sql @@ -0,0 +1,2 @@ +-- Modify "Soapi" table +ALTER TABLE "public"."Soapi" ALTER COLUMN "TypeCode" TYPE character varying(15); diff --git a/cmd/main-migration/migrations/20251202130629.sql b/cmd/main-migration/migrations/20251202130629.sql new file mode 100644 index 00000000..88b685fe --- /dev/null +++ b/cmd/main-migration/migrations/20251202130629.sql @@ -0,0 +1,101 @@ +-- Modify "Consultation" table +ALTER TABLE "public"."Consultation" ALTER COLUMN "DstUnit_Code" TYPE character varying(20); +-- Modify "ControlLetter" table +ALTER TABLE "public"."ControlLetter" ALTER COLUMN "Unit_Code" TYPE character varying(20), ALTER COLUMN "Specialist_Code" TYPE character varying(20), ALTER COLUMN "Subspecialist_Code" TYPE character varying(20); +-- Modify "Encounter" table +ALTER TABLE "public"."Encounter" ALTER COLUMN "Specialist_Code" TYPE character varying(20), ALTER COLUMN "Subspecialist_Code" TYPE character varying(20), ALTER COLUMN "Unit_Code" TYPE character varying(20); +-- Modify "Chemo" table +ALTER TABLE "public"."Chemo" ALTER COLUMN "SrcUnit_Code" TYPE character varying(20); +-- Modify "Installation" table +ALTER TABLE "public"."Installation" ALTER COLUMN "Code" TYPE character varying(20); +-- Modify "InternalReference" table +ALTER TABLE "public"."InternalReference" ALTER COLUMN "Unit_Code" TYPE character varying(20); +-- Modify "PracticeSchedule" table +ALTER TABLE "public"."PracticeSchedule" ALTER COLUMN "Unit_Code" TYPE character varying(20); +-- Create "DevicePackage" table +CREATE TABLE "public"."DevicePackage" ( + "Id" serial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "Code" character varying(20) NOT NULL, + "Name" character varying(50) NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "uni_DevicePackage_Code" UNIQUE ("Code") +); +-- Create "DevicePackageItem" table +CREATE TABLE "public"."DevicePackageItem" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "DevicePackage_Code" character varying(20) NOT NULL, + "Device_Code" character varying(20) NOT NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "fk_DevicePackageItem_Device" FOREIGN KEY ("Device_Code") REFERENCES "public"."Device" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT "fk_DevicePackageItem_DevicePackage" FOREIGN KEY ("DevicePackage_Code") REFERENCES "public"."DevicePackage" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION +); +-- Create "MaterialPackage" table +CREATE TABLE "public"."MaterialPackage" ( + "Id" serial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "Code" character varying(20) NOT NULL, + "Name" character varying(50) NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "uni_MaterialPackage_Code" UNIQUE ("Code") +); +-- Create "MaterialPackageItem" table +CREATE TABLE "public"."MaterialPackageItem" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "MaterialPackage_Code" character varying(20) NOT NULL, + "Material_Code" character varying(20) NOT NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "fk_MaterialPackageItem_Material" FOREIGN KEY ("Material_Code") REFERENCES "public"."Material" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT "fk_MaterialPackageItem_MaterialPackage" FOREIGN KEY ("MaterialPackage_Code") REFERENCES "public"."MaterialPackage" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION +); +-- Modify "Infra" table +ALTER TABLE "public"."Infra" ALTER COLUMN "Code" TYPE character varying(20), ALTER COLUMN "InfraGroup_Code" TYPE character varying(20), ALTER COLUMN "Parent_Code" TYPE character varying(20); +-- Modify "Specialist" table +ALTER TABLE "public"."Specialist" ALTER COLUMN "Code" TYPE character varying(20), ALTER COLUMN "Unit_Code" TYPE character varying(20); +-- Modify "Subspecialist" table +ALTER TABLE "public"."Subspecialist" ALTER COLUMN "Code" TYPE character varying(20), ALTER COLUMN "Specialist_Code" TYPE character varying(20); +-- Modify "Unit" table +ALTER TABLE "public"."Unit" ALTER COLUMN "Code" TYPE character varying(20), ALTER COLUMN "Installation_Code" TYPE character varying(20); +-- Create "ProcedureRoom" table +CREATE TABLE "public"."ProcedureRoom" ( + "Id" serial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "Code" character varying(20) NULL, + "Infra_Code" character varying(20) NULL, + "Type_Code" character varying(10) NULL, + "Unit_Code" character varying(20) NULL, + "Specialist_Code" character varying(20) NULL, + "Subspecialist_Code" character varying(20) NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "uni_ProcedureRoom_Code" UNIQUE ("Code"), + CONSTRAINT "uni_ProcedureRoom_Infra_Code" UNIQUE ("Infra_Code"), + CONSTRAINT "fk_ProcedureRoom_Infra" FOREIGN KEY ("Infra_Code") REFERENCES "public"."Infra" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT "fk_ProcedureRoom_Specialist" FOREIGN KEY ("Specialist_Code") REFERENCES "public"."Specialist" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT "fk_ProcedureRoom_Subspecialist" FOREIGN KEY ("Subspecialist_Code") REFERENCES "public"."Subspecialist" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT "fk_ProcedureRoom_Unit" FOREIGN KEY ("Unit_Code") REFERENCES "public"."Unit" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION +); +-- Create "ProcedureRoomOrder" table +CREATE TABLE "public"."ProcedureRoomOrder" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "Encounter_Id" bigint NULL, + "Infra_Code" character varying(20) NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "fk_ProcedureRoomOrder_ProcedureRoom" FOREIGN KEY ("Infra_Code") REFERENCES "public"."ProcedureRoom" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION +); +-- Drop "Room" table +DROP TABLE "public"."Room"; diff --git a/cmd/main-migration/migrations/20251202160848.sql b/cmd/main-migration/migrations/20251202160848.sql new file mode 100644 index 00000000..8d77fe04 --- /dev/null +++ b/cmd/main-migration/migrations/20251202160848.sql @@ -0,0 +1,2 @@ +-- Modify "ProcedureRoomOrder" table +ALTER TABLE "public"."ProcedureRoomOrder" ADD COLUMN "MaterialPackage_Code" character varying(20) NULL, ADD CONSTRAINT "fk_ProcedureRoomOrder_MaterialPackage" FOREIGN KEY ("MaterialPackage_Code") REFERENCES "public"."MaterialPackage" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION; diff --git a/cmd/main-migration/migrations/20251202180207.sql b/cmd/main-migration/migrations/20251202180207.sql new file mode 100644 index 00000000..32c5b1dc --- /dev/null +++ b/cmd/main-migration/migrations/20251202180207.sql @@ -0,0 +1,2 @@ +-- Modify "ProcedureRoomOrder" table +ALTER TABLE "public"."ProcedureRoomOrder" ADD COLUMN "Status_Code" character varying(20) NULL; diff --git a/cmd/main-migration/migrations/20251202231005.sql b/cmd/main-migration/migrations/20251202231005.sql new file mode 100644 index 00000000..65fe436a --- /dev/null +++ b/cmd/main-migration/migrations/20251202231005.sql @@ -0,0 +1,14 @@ +-- Modify "MaterialPackageItem" table +ALTER TABLE "public"."MaterialPackageItem" ADD COLUMN "Count" integer NULL; +-- Create "ProcedureRoomOrderItem" table +CREATE TABLE "public"."ProcedureRoomOrderItem" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "ProcedureRoomOrder_Id" bigint NULL, + "ProcedureRoom_Code" character varying(20) NULL, + "Note" character varying(255) NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "fk_ProcedureRoomOrderItem_ProcedureRoom" FOREIGN KEY ("ProcedureRoom_Code") REFERENCES "public"."ProcedureRoom" ("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 449ff1d4..c949eadc 100644 --- a/cmd/main-migration/migrations/atlas.sum +++ b/cmd/main-migration/migrations/atlas.sum @@ -1,4 +1,4 @@ -h1:Y8m8OmsumTaAfXfYYXHlZS0+OqbAqFfM3a55nmibOUE= +h1:MO6ze6e6ClW/WxUyiZxT6Lmhz8BDgXmmYeLDSN4xEJw= 20250904105930.sql h1:MEM6blCgke9DzWQSTnLzasbPIrcHssNNrJqZpSkEo6k= 20250904141448.sql h1:J8cmYNk4ZrG9fhfbi2Z1IWz7YkfvhFqTzrLFo58BPY0= 20250908062237.sql h1:Pu23yEW/aKkwozHoOuROvHS/GK4ngARJGdO7FB7HZuI= @@ -75,59 +75,72 @@ h1:Y8m8OmsumTaAfXfYYXHlZS0+OqbAqFfM3a55nmibOUE= 20251106040137.sql h1:ppcqkVoT0o9jZcjI/TN7LuaPxXhJQhnIXEJtloP/46o= 20251106041333.sql h1:2JkxyelQ/EeB+boL5bfpnzefw32ttEGKvKchtQjWmAU= 20251106042006.sql h1:ruppYa1kAJQUU3ufQBbKGMcXrGbGJJiRPclT+dNc/YQ= -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= +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:qg2dhCL9YwD13xnfJ175lW/p6MGfzFKaBqd908FByRc= +20251125125303.sql h1:4JSFv1Pmhbe9tqpLXgO63OwYnGsalStgUXKVWPyc1YE= +20251126064057.sql h1:vAdhz5Nn/gGJy0UKZAEldeXv8HpHtJU/t8ygDVIbTsU= +20251201081333.sql h1:PoC8ADRdwDuohDTB74yW/DaB42igdYa4B6humbrEJBk= +20251201104439.sql h1:tpqdrOf9d2aGwZshqm62nG6SXnfVaO/g6A7z0efPS14= +20251201113804.sql h1:kIEmVoETJXBkab2Q+b3y/pP84eF8W2BdQ47amHCnc+c= +20251201113858.sql h1:KLXKZO5XTQPoEU0YLHE8Fhg9WPKpSN3wNgYPJ+RGFcg= +20251201114751.sql h1:HM17diiPknfSHAmP+kJGP6GzToaPU9/NT+KQBpf3Jq0= +20251201114913.sql h1:gqucFgHFFLA6n/Rdz486cZH5xkaJuwefESLJMJLDue8= +20251202030445.sql h1:QWBVfTepT7DaXP5E0BYoxNM0JwKIQ2qIMXzI4kbz/qE= +20251202044430.sql h1:4QZH9lz0GrQ9rzP1AJ+hJgGalNpp+8FCRckNK7xaTbU= +20251202064000.sql h1:/EN7sT1ol/91qW1aXWrzX+Mc3XOC/7f/LtfA0JRHpbg= +20251202130629.sql h1:9mvalqfhqGCdkcJepJDzHprU2xb0i5sYys1Htf62ioo= +20251202160848.sql h1:Kd2/TziKSMezrt4XgbjQcYvY/Lo9rX0qw7/Lz0/oyKk= +20251202180207.sql h1:IHmSMIO3ia+YV5GULixbdlV1joaUAWtnjQHPd8+HKiM= +20251202231005.sql h1:iVzsqbqmfncDXPPXoRqCQdcvgvLBv57TbzdbzQAmSVc= diff --git a/cmd/simgos-sync-migration/migrations/20251201093443.sql b/cmd/simgos-sync-migration/migrations/20251201093443.sql new file mode 100644 index 00000000..1ecce17e --- /dev/null +++ b/cmd/simgos-sync-migration/migrations/20251201093443.sql @@ -0,0 +1,36 @@ +-- Create "SoapiLink" table +CREATE TABLE "public"."SoapiLink" ( + "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_SoapiLink_Simgos_Id" UNIQUE ("Simgos_Id"), + CONSTRAINT "uni_SoapiLink_Simx_Id" UNIQUE ("Simx_Id") +); +-- Create "SoapiSimgosLog" table +CREATE TABLE "public"."SoapiSimgosLog" ( + "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 "SoapiSimxLog" table +CREATE TABLE "public"."SoapiSimxLog" ( + "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 497ac414..e82a5610 100644 --- a/cmd/simgos-sync-migration/migrations/atlas.sum +++ b/cmd/simgos-sync-migration/migrations/atlas.sum @@ -1,7 +1,8 @@ -h1:UdPzQZ17yyNN9HVuyrFFHj5KjLj4m6/e7s9frkdpQVU= +h1:6YZBXq/r79I5tuYyY1+CBzhZsSeukHSs8MyHCC5QuV4= 20251113035508.sql h1:rjDlu6yDdy5xv6nrCOr7NialrLSLT23pzduYNq29Hf0= 20251114071129.sql h1:Z0GQ5bJo3C+tplaWzxT8n3J9HLkEaVsRVp5nn7bmYow= 20251117041601.sql h1:l/RPG5mObqCSBjO4mzG+wTq2ieSycvlfOSz4czpUdWY= 20251118082246.sql h1:xLUwA+EvKWIg3X/TJvu7rqbtBzONiINfag5NJpMV29E= 20251118082915.sql h1:hP6FmUVFuADIN2cDg2Z1l7Wx7PQRb+IYQDvKD7J8VAM= -20251126115527.sql h1:+2bp2nWTTqaPpKKfy5ZYSr6b1nEUXFG3tIw4r3OEnAQ= +20251126115527.sql h1:Bvg+Y7k+h5s+/UaezUyJb7J7uzEJS7U5Z/RoCixcUtI= +20251201093443.sql h1:m18tksKG3OzbkxXkhfKUUqbkxnJ0VBPi3Cw34Tbywyc= diff --git a/internal/domain/bpjs-entities/control-plan/dto.go b/internal/domain/bpjs-entities/control-plan/dto.go new file mode 100644 index 00000000..2290707d --- /dev/null +++ b/internal/domain/bpjs-entities/control-plan/dto.go @@ -0,0 +1,7 @@ +package controlplan + +type ReadListDto struct { + PathValue1 string `json:"-"` // jenis kontrol + PathValue2 string `json:"-"` // kode poli + PathValue3 string `json:"-"` // tanggal +} diff --git a/internal/domain/bpjs-entities/control-plan/entity.go b/internal/domain/bpjs-entities/control-plan/entity.go new file mode 100644 index 00000000..1a07379a --- /dev/null +++ b/internal/domain/bpjs-entities/control-plan/entity.go @@ -0,0 +1,22 @@ +package controlplan + +type Response struct { + MetaData MetaData `json:"metaData"` + Response *ResponseItems `json:"response"` // nullable +} + +type MetaData struct { + Code string `json:"code"` + Message string `json:"message"` +} + +type ResponseItems struct { + List []DoctorSchedule `json:"list"` +} + +type DoctorSchedule struct { + JadwalPraktek string `json:"jadwalPraktek"` + Kapasitas string `json:"kapasitas"` + KodeDokter string `json:"kodeDokter"` + NamaDokter string `json:"namaDokter"` +} diff --git a/internal/domain/bpjs-entities/referral/dto.go b/internal/domain/bpjs-entities/referral/dto.go new file mode 100644 index 00000000..16113d24 --- /dev/null +++ b/internal/domain/bpjs-entities/referral/dto.go @@ -0,0 +1,5 @@ +package referral + +type ReadDetailDto struct { + Number *string `json:"number"` // nomor rujukan +} diff --git a/internal/domain/bpjs-entities/referral/entity.go b/internal/domain/bpjs-entities/referral/entity.go new file mode 100644 index 00000000..8977ee31 --- /dev/null +++ b/internal/domain/bpjs-entities/referral/entity.go @@ -0,0 +1,96 @@ +package referral + +type Response struct { + MetaData MetaData `json:"metaData"` + Response *ReferralDetail `json:"response"` // nullable +} + +type MetaData struct { + Code string `json:"code"` + Message string `json:"message"` +} + +type ReferralDetail struct { + AsalFaskes string `json:"asalFaskes"` + Rujukan RujukanDetail `json:"rujukan"` +} + +type RujukanDetail struct { + Diagnosa Diagnosa `json:"diagnosa"` + Keluhan *string `json:"keluhan"` // nullable + NoKunjungan string `json:"noKunjungan"` + Pelayanan Pelayanan `json:"pelayanan"` + Peserta Peserta `json:"peserta"` + PoliRujukan Poli `json:"poliRujukan"` + ProvPerujuk Provider `json:"provPerujuk"` + TglKunjungan string `json:"tglKunjungan"` +} + +type Diagnosa struct { + Kode string `json:"kode"` + Nama string `json:"nama"` +} + +type Pelayanan struct { + Kode string `json:"kode"` + Nama string `json:"nama"` +} + +type Peserta struct { + Cob Cob `json:"cob"` + HakKelas KeteranganKode `json:"hakKelas"` + Informasi Informasi `json:"informasi"` + JenisPeserta KeteranganKode `json:"jenisPeserta"` + Mr Mr `json:"mr"` + Nama string `json:"nama"` + Nik string `json:"nik"` + NoKartu string `json:"noKartu"` + Pisa string `json:"pisa"` + ProvUmum Provider `json:"provUmum"` + Sex string `json:"sex"` + StatusPeserta KeteranganKode `json:"statusPeserta"` + TglCetakKartu string `json:"tglCetakKartu"` + TglLahir string `json:"tglLahir"` + TglTAT string `json:"tglTAT"` + TglTMT string `json:"tglTMT"` + Umur Umur `json:"umur"` +} + +type Cob struct { + NmAsuransi *string `json:"nmAsuransi"` // nullable + NoAsuransi *string `json:"noAsuransi"` + TglTAT *string `json:"tglTAT"` + TglTMT *string `json:"tglTMT"` +} + +type KeteranganKode struct { + Keterangan string `json:"keterangan"` + Kode string `json:"kode"` +} + +type Informasi struct { + Dinsos *string `json:"dinsos"` + ESep *string `json:"eSEP"` + NoSKTM *string `json:"noSKTM"` + ProlanisPRB *string `json:"prolanisPRB"` +} + +type Mr struct { + NoMR string `json:"noMR"` + NoTelepon string `json:"noTelepon"` +} + +type Provider struct { + Kode string `json:"kdProvider" json:"kode"` // API sometimes uses different keys + NmProvider string `json:"nmProvider" json:"nama"` +} + +type Poli struct { + Kode string `json:"kode"` + Nama string `json:"nama"` +} + +type Umur struct { + UmurSaatPelayanan string `json:"umurSaatPelayanan"` + UmurSekarang string `json:"umurSekarang"` +} diff --git a/internal/domain/bpjs-entities/vclaim-sep/dto.go b/internal/domain/bpjs-entities/vclaim-sep/dto.go index 8a174688..2f4475b5 100644 --- a/internal/domain/bpjs-entities/vclaim-sep/dto.go +++ b/internal/domain/bpjs-entities/vclaim-sep/dto.go @@ -1,6 +1,7 @@ package vclaimsep import ( + "encoding/json" ecore "simrs-vx/internal/domain/base-entities/core" evsh "simrs-vx/internal/domain/bpjs-entities/vclaim-sep-hist" ) @@ -8,7 +9,7 @@ import ( type CreateDto struct { Encounter_Id *uint `json:"encounter_id"` Number *string `json:"number" validate:"maxLength=19"` - RequestPayload []byte `json:"requestPayload" validate:"maxLength=1024"` + RequestPayload string `json:"requestPayload" validate:"maxLength=1024"` VclaimSepHist evsh.CreateDto } @@ -25,8 +26,9 @@ type FilterDto struct { } type ReadDetailDto struct { - Id uint `json:"id"` - Number *string `json:"number"` + Id uint `json:"id"` + Number *string `json:"number"` + Encounter_Id *uint `json:"encounter_id"` } type UpdateDto struct { @@ -47,14 +49,16 @@ type MetaDto struct { type ResponseDto struct { ecore.Main - Encounter_Id *uint `json:"encounter_id"` - Number *string `json:"number"` + Encounter_Id *uint `json:"encounter_id"` + Number *string `json:"number"` + Detail *SepDetail `json:"detail,omitempty"` } func (d VclaimSep) ToResponse() ResponseDto { resp := ResponseDto{ Encounter_Id: d.Encounter_Id, Number: d.Number, + Detail: d.Detail, } resp.Main = d.Main return resp @@ -71,3 +75,130 @@ func ToResponseList(data []VclaimSep) []ResponseDto { func (c CreateDto) IsMessageSuccess() bool { return c.VclaimSepHist.Message == "Sukses" } + +func (c CreateDto) RequestPayloadIntoJson() ([]byte, error) { + payload := map[string]interface{}{} + err := json.Unmarshal([]byte(c.RequestPayload), &payload) + if err != nil { + return nil, err + } + return json.Marshal(payload) +} + +func (c CreateDto) RequestPayloadWithEncounterId() ([]byte, error) { + payload := map[string]interface{}{} + + err := json.Unmarshal([]byte(c.RequestPayload), &payload) + if err != nil { + return nil, err + } + + payload["encounter_id"] = c.Encounter_Id + + return json.Marshal(payload) +} + +type SepResponse struct { + MetaData MetaData `json:"metaData"` + Response *SepDetail `json:"response"` +} + +type MetaData struct { + Code string `json:"code"` + Message string `json:"message"` +} + +type SepDetail struct { + AssestmenPel AssestmenPel `json:"assestmenPel"` + Catatan string `json:"catatan"` + Cob string `json:"cob"` + Diagnosa string `json:"diagnosa"` + Dpjp Dpjp `json:"dpjp"` + ESep string `json:"eSEP"` + FlagProcedure FlagProcedure `json:"flagProcedure"` + Informasi any `json:"informasi"` // null = interface{} + JnsPelayanan string `json:"jnsPelayanan"` + Katarak string `json:"katarak"` + KdPenunjang KdPenunjang `json:"kdPenunjang"` + KdStatusKecelakaan string `json:"kdStatusKecelakaan"` + KelasRawat string `json:"kelasRawat"` + KlsRawat KlsRawat `json:"klsRawat"` + Kontrol Kontrol `json:"kontrol"` + LokasiKejadian LokasiKejadian `json:"lokasiKejadian"` + NmStatusKecelakaan string `json:"nmstatusKecelakaan"` + NoRujukan string `json:"noRujukan"` + NoSep string `json:"noSep"` + Penjamin any `json:"penjamin"` // null + Peserta Peserta `json:"peserta"` + Poli string `json:"poli"` + PoliEksekutif string `json:"poliEksekutif"` + TglSep string `json:"tglSep"` + TujuanKunj TujuanKunj `json:"tujuanKunj"` +} + +type AssestmenPel struct { + Kode string `json:"kode"` + Nama string `json:"nama"` +} + +type Dpjp struct { + KdDPJP string `json:"kdDPJP"` + NmDPJP string `json:"nmDPJP"` +} + +type FlagProcedure struct { + Kode string `json:"kode"` + Nama string `json:"nama"` +} + +type KdPenunjang struct { + Kode string `json:"kode"` + Nama string `json:"nama"` +} + +type KlsRawat struct { + KlsRawatHak string `json:"klsRawatHak"` + KlsRawatNaik *string `json:"klsRawatNaik"` // nullable + Pembiayaan *string `json:"pembiayaan"` // nullable + PenanggungJawab *string `json:"penanggungJawab"` // nullable +} + +type Kontrol struct { + KdDokter *string `json:"kdDokter"` // null + NmDokter *string `json:"nmDokter"` // null + NoSurat *string `json:"noSurat"` // null +} + +type LokasiKejadian struct { + KdKab *string `json:"kdKab"` + KdKec *string `json:"kdKec"` + KdProp *string `json:"kdProp"` + KetKejadian *string `json:"ketKejadian"` + Lokasi *string `json:"lokasi"` + TglKejadian *string `json:"tglKejadian"` +} + +type Peserta struct { + Asuransi any `json:"asuransi"` + HakKelas string `json:"hakKelas"` + JnsPeserta string `json:"jnsPeserta"` + Kelamin string `json:"kelamin"` + Nama string `json:"nama"` + NoKartu string `json:"noKartu"` + NoMR string `json:"noMr"` + TglLahir string `json:"tglLahir"` +} + +type TujuanKunj struct { + Kode string `json:"kode"` + Nama string `json:"nama"` +} + +type SepDeleteRequest struct { + Request struct { + TSep struct { + NoSep string `json:"noSep"` + User string `json:"user"` + } `json:"t_sep"` + } `json:"request"` +} diff --git a/internal/domain/bpjs-entities/vclaim-sep/entitiy.go b/internal/domain/bpjs-entities/vclaim-sep/entitiy.go index f175e4cb..6948d640 100644 --- a/internal/domain/bpjs-entities/vclaim-sep/entitiy.go +++ b/internal/domain/bpjs-entities/vclaim-sep/entitiy.go @@ -12,4 +12,5 @@ type VclaimSep struct { Number *string `json:"number" gorm:"unique;size:19"` Prints []*evsp.VclaimSepPrint `json:"prints,omitempty" gorm:"foreignKey:VclaimSep_Number;references:Number"` ControlLetters []*evscl.VclaimSepControlLetter `json:"controlLetters,omitempty" gorm:"foreignKey:VclaimSep_Number;references:Number"` + Detail *SepDetail `json:"detail,omitempty" gorm:"-"` } diff --git a/internal/domain/main-entities/action-report/dto.go b/internal/domain/main-entities/action-report/dto.go new file mode 100644 index 00000000..45c26d17 --- /dev/null +++ b/internal/domain/main-entities/action-report/dto.go @@ -0,0 +1,90 @@ +package actionreport + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + ee "simrs-vx/internal/domain/main-entities/encounter" + "time" + + pa "simrs-vx/internal/lib/auth" +) + +type CreateDto struct { + Encounter_Id uint64 `json:"encounter_id" validate:"required"` + Date *time.Time `json:"date" validate:"required"` + Doctor_Code string `json:"doctor_code" validate:"required"` + Operator_Employe_Id uint `json:"operator_employe_id" validate:"required"` + Assistant_Employe_Id uint `json:"assistant_employe_id" validate:"required"` + Instrumentor_Employe_Id uint `json:"instrumentor_employe_id" validate:"required"` + Diagnose *string `json:"diagnose"` + Nurse_Code string `json:"nurse_code" validate:"required"` + Value string `json:"value" validate:"required"` + + pa.AuthInfo +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Pagination ecore.Pagination +} + +type FilterDto struct { + Encounter_Id *uint `json:"encounter-id"` +} + +type ReadDetailDto struct { + Id uint16 `json:"id"` +} + +type UpdateDto struct { + Id uint16 `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint16 `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.Main + Encounter_Id uint64 `json:"encounter_id"` + Encounter *ee.Encounter `json:"encounter,omitempty"` + Date *time.Time `json:"date"` + Doctor_Code string `json:"doctor_code"` + Operator_Employe_Id uint `json:"operator_employe_id"` + Assistant_Employe_Id uint `json:"assistant_employe_id"` + Instrumentor_Employe_Id uint `json:"instrumentor_employe_id"` + Diagnose *string `json:"diagnose"` + Nurse_Code string `json:"nurse_code"` + Value *string `json:"value"` +} + +func (d ActionReport) ToResponse() ResponseDto { + resp := ResponseDto{ + Encounter_Id: d.Encounter_Id, + Encounter: d.Encounter, + Date: d.Date, + Doctor_Code: d.Doctor_Code, + Operator_Employe_Id: d.Operator_Employe_Id, + Assistant_Employe_Id: d.Assistant_Employe_Id, + Instrumentor_Employe_Id: d.Instrumentor_Employe_Id, + Nurse_Code: d.Nurse_Code, + Value: &d.Value, + } + resp.Main = d.Main + return resp +} + +func ToResponseList(data []ActionReport) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/action-report/entity.go b/internal/domain/main-entities/action-report/entity.go new file mode 100644 index 00000000..8447a2e5 --- /dev/null +++ b/internal/domain/main-entities/action-report/entity.go @@ -0,0 +1,51 @@ +package actionreport + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + ed "simrs-vx/internal/domain/main-entities/doctor" + eem "simrs-vx/internal/domain/main-entities/employee" + ee "simrs-vx/internal/domain/main-entities/encounter" + en "simrs-vx/internal/domain/main-entities/nurse" + "time" +) + +type ActionReport struct { + ecore.Main // adjust this according to the needs + Encounter_Id uint64 `json:"encounter_id" gorm:"foreignKey"` + Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"` + Date *time.Time `json:"date" gorm:"not null;size:20"` + Doctor_Code string `json:"doctor_code" gorm:"size:10"` + Doctor *ed.Doctor `json:"doctor,omitempty" gorm:"foreignKey:Doctor_Code;references:Code"` + Operator_Employe_Id uint `json:"operator_employe_id"` + Operator_Employe *eem.Employee `json:"operator_employe,omitempty" gorm:"foreignKey:Operator_Employe_Id;references:Id"` + Assistant_Employe_Id uint `json:"assistant_employe_id"` + Instrumentor_Employe_Id uint `json:"instrumentor_employe_id"` + Instrumentor_Employe *eem.Employee `json:"instrumentor_employe,omitempty" gorm:"foreignKey:Instrumentor_Employe_Id;references:Id"` + Diagnose *string `json:"diagnose" gorm:"size:1024"` + Nurse_Code string `json:"nurse_code" gorm:"size:10"` + Nurse *en.Nurse `json:"nurse,omitempty" gorm:"foreignKey:Nurse_Code;references:Code"` + Value string `json:"value"` + // SurgerySize_Code *string `json:"surgerySize_code" gorm:"size:10"` + // Billing_Code *string `json:"billing_code" gorm:"size:10"` + // SurgerySystem_Code *string `json:"surgerySystem_code" gorm:"size:10"` + // StartAt *string `json:"startAt" gorm:"size:20"` + // EndAt *string `json:"endAt" gorm:"size:20"` + // AnesthesiaStartAt *string `json:"anesthesiaStartAt" gorm:"size:20"` + // AnesthesiaEndAt *string `json:"anesthesiaEndAt" gorm:"size:20"` + // SurgeryType_Code *string `json:"surgeryType_code" gorm:"size:10"` + // SurgeryStage_Code *string `json:"surgeryStage_code" gorm:"size:10"` + // BornMortality_Code *string `json:"bornMortality_code" gorm:"size:10"` + // BornLocation_Code *string `json:"bornLocation_code" gorm:"size:10"` + // Weight *string `json:"weight" gorm:"size:10"` + // BornNotes *string `json:"bornNotes" gorm:"size:1024"` + // Description *string `json:"notes" gorm:"size:1024"` + // BleedingAmount *uint16 `json:"bleedingAmount" gorm:"size:10"` + // BloodInType_Code *string `json:"bloodInType_code" gorm:"size:10"` + // BloodInAmount *uint16 `json:"bloodInAmount" gorm:"size:10"` + // Brand *string `json:"brand" gorm:"size:100"` + // ImplantName *string `json:"implantName" gorm:"size:100"` + // ImplantRegisterNumber *string `json:"implantRegisterNumber" gorm:"size:100"` + // ImplantCompanionName *string `json:"implantCompanionName" gorm:"size:100"` + // SpecimentDest_Code *string `json:"specimentDest" gorm:"size:100"` + // TissueInfo *string `json:"tissueInfo" gorm:"size:100"` +} diff --git a/internal/domain/main-entities/device-package-item/device-package/dto.go b/internal/domain/main-entities/device-package-item/device-package/dto.go new file mode 100644 index 00000000..26aad58a --- /dev/null +++ b/internal/domain/main-entities/device-package-item/device-package/dto.go @@ -0,0 +1,63 @@ +package devicepackage + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" +) + +type CreateDto struct { + Code string `json:"code" validate:"maxLength=20"` + Name string `json:"name" validate:"maxLength=50"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Pagination ecore.Pagination +} + +type FilterDto struct { + Code string `json:"code"` + Name string `json:"name"` +} + +type ReadDetailDto struct { + Id uint16 `json:"id"` +} + +type UpdateDto struct { + Id uint16 `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint16 `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.SmallMain + Code string `json:"code"` + Name string `json:"name"` +} + +func (d DevicePackage) ToResponse() ResponseDto { + resp := ResponseDto{ + Code: d.Code, + Name: d.Name, + } + resp.SmallMain = d.SmallMain + return resp +} + +func ToResponseList(data []DevicePackage) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/device-package-item/device-package/entity.go b/internal/domain/main-entities/device-package-item/device-package/entity.go new file mode 100644 index 00000000..1c03b44d --- /dev/null +++ b/internal/domain/main-entities/device-package-item/device-package/entity.go @@ -0,0 +1,11 @@ +package devicepackage + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" +) + +type DevicePackage struct { + ecore.SmallMain + Code string `json:"code" gorm:"unique;size:20;not null"` + Name string `json:"name" gorm:"size:50"` +} diff --git a/internal/domain/main-entities/device-package-item/dto.go b/internal/domain/main-entities/device-package-item/dto.go new file mode 100644 index 00000000..a0a224ba --- /dev/null +++ b/internal/domain/main-entities/device-package-item/dto.go @@ -0,0 +1,69 @@ +package devicepackage + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + ed "simrs-vx/internal/domain/main-entities/device" + edp "simrs-vx/internal/domain/main-entities/device-package" +) + +type CreateDto struct { + DevicePackage_Code string `json:"devicePackage_code" validate:"maxLength=20"` + Device_Code string `json:"code" validate:"maxLength=20"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Pagination ecore.Pagination +} + +type FilterDto struct { + DevicePackage_Code string `json:"devicePackage-code"` + Device_Code string `json:"code"` +} + +type ReadDetailDto struct { + Id uint `json:"id"` +} + +type UpdateDto struct { + Id uint `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.Main + DevicePackage_Code string `json:"devicePackage_code"` + DevicePackage *edp.DevicePackage `json:"devicePackage,omitempty"` + Device_Code string `json:"code"` + Device *ed.Device `json:"device,omitempty"` +} + +func (d DevicePackageItem) ToResponse() ResponseDto { + resp := ResponseDto{ + DevicePackage_Code: d.DevicePackage_Code, + DevicePackage: d.DevicePackage, + Device_Code: d.Device_Code, + Device: d.Device, + } + resp.Id = d.Id + return resp +} + +func ToResponseList(data []DevicePackageItem) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/device-package-item/entity.go b/internal/domain/main-entities/device-package-item/entity.go new file mode 100644 index 00000000..476e24e2 --- /dev/null +++ b/internal/domain/main-entities/device-package-item/entity.go @@ -0,0 +1,15 @@ +package devicepackage + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + ed "simrs-vx/internal/domain/main-entities/device" + edp "simrs-vx/internal/domain/main-entities/device-package" +) + +type DevicePackageItem struct { + ecore.Main + DevicePackage_Code string `json:"devicePackage_code" gorm:"size:20;not null"` + DevicePackage *edp.DevicePackage `json:"devicePackage" gorm:"foreignKey:DevicePackage_Code;references:Code"` + Device_Code string `json:"code" gorm:"size:20;not null"` + Device *ed.Device `json:"device" gorm:"foreignKey:Device_Code;references:Code"` +} diff --git a/internal/domain/main-entities/device-package/dto.go b/internal/domain/main-entities/device-package/dto.go new file mode 100644 index 00000000..26aad58a --- /dev/null +++ b/internal/domain/main-entities/device-package/dto.go @@ -0,0 +1,63 @@ +package devicepackage + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" +) + +type CreateDto struct { + Code string `json:"code" validate:"maxLength=20"` + Name string `json:"name" validate:"maxLength=50"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Pagination ecore.Pagination +} + +type FilterDto struct { + Code string `json:"code"` + Name string `json:"name"` +} + +type ReadDetailDto struct { + Id uint16 `json:"id"` +} + +type UpdateDto struct { + Id uint16 `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint16 `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.SmallMain + Code string `json:"code"` + Name string `json:"name"` +} + +func (d DevicePackage) ToResponse() ResponseDto { + resp := ResponseDto{ + Code: d.Code, + Name: d.Name, + } + resp.SmallMain = d.SmallMain + return resp +} + +func ToResponseList(data []DevicePackage) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/device-package/entity.go b/internal/domain/main-entities/device-package/entity.go new file mode 100644 index 00000000..1c03b44d --- /dev/null +++ b/internal/domain/main-entities/device-package/entity.go @@ -0,0 +1,11 @@ +package devicepackage + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" +) + +type DevicePackage struct { + ecore.SmallMain + Code string `json:"code" gorm:"unique;size:20;not null"` + Name string `json:"name" gorm:"size:50"` +} diff --git a/internal/domain/main-entities/doctor/dto.go b/internal/domain/main-entities/doctor/dto.go index e3d1f3ee..c7eb0f6b 100644 --- a/internal/domain/main-entities/doctor/dto.go +++ b/internal/domain/main-entities/doctor/dto.go @@ -43,6 +43,7 @@ type ReadDetailDto struct { Employee_Id *uint `json:"employee_id"` IHS_Number *string `json:"ihs_number"` SIP_Number *string `json:"sip_number"` + Includes string `json:"includes"` } type UpdateDto struct { diff --git a/internal/domain/main-entities/encounter/entity.go b/internal/domain/main-entities/encounter/entity.go index d1458f7c..0b1da159 100644 --- a/internal/domain/main-entities/encounter/entity.go +++ b/internal/domain/main-entities/encounter/entity.go @@ -85,3 +85,10 @@ type Encounter struct { func (d Encounter) IsDone() bool { return d.Status_Code == erc.DSCDone } + +func (d Encounter) IsSameResponsibleDoctor(input *string) bool { + if input == nil { + return false + } + return *d.Responsible_Doctor_Code == *input +} diff --git a/internal/domain/main-entities/infra/dto.go b/internal/domain/main-entities/infra/dto.go index dfe271e5..63c5d4a4 100644 --- a/internal/domain/main-entities/infra/dto.go +++ b/internal/domain/main-entities/infra/dto.go @@ -3,15 +3,16 @@ package infra import ( ecore "simrs-vx/internal/domain/base-entities/core" ei "simrs-vx/internal/domain/main-entities/item" - erb "simrs-vx/internal/domain/main-entities/room/base" + + erb "simrs-vx/internal/domain/main-entities/procedure-room/base" ero "simrs-vx/internal/domain/references/organization" ) type CreateDto struct { - Code string `json:"code" validate:"maxLength=10"` + Code string `json:"code" validate:"maxLength=20"` Name string `json:"name" validate:"maxLength=50"` - InfraGroup_Code ero.InfraGroupCode `json:"infraGroup_code" validate:"maxLength=15"` + InfraGroup_Code ero.InfraGroupCode `json:"infraGroup_code" validate:"maxLength=20"` Parent_Code *string `json:"parent_code"` Item_Code *string `json:"-"` Unit_Code *string `json:"unit_code"` @@ -31,7 +32,7 @@ type ReadListDto struct { type FilterDto struct { Code string `json:"code"` Name string `json:"name"` - InfraGroup_Code ero.InfraGroupCode `json:"infraGroup-code"` + InfraGroup_Code ero.InfraGroupCode `json:"infra-group-code"` Parent_Code *string `json:"parent-code"` Item_Id *string `json:"item-code"` Search string `json:"search" gormhelper:"searchColumns=Code,Name"` @@ -69,7 +70,7 @@ type ResponseDto struct { Childrens []Infra `json:"childrens,omitempty"` Item_Code *string `json:"item_code"` Item *ei.Item `json:"item,omitempty"` - Rooms []erb.Basic `json:"rooms,omitempty"` + ProcedureRooms *erb.ProcedureRoom `json:"rooms,omitempty"` } func (d Infra) ToResponse() ResponseDto { @@ -79,10 +80,10 @@ func (d Infra) ToResponse() ResponseDto { InfraGroup_Code: d.InfraGroup_Code, Parent_Code: d.Parent_Code, // Parent: d.Parent, - Childrens: d.Childrens, - Item_Code: d.Item_Code, - Item: d.Item, - Rooms: d.Rooms, + Childrens: d.Childrens, + Item_Code: d.Item_Code, + Item: d.Item, + ProcedureRooms: d.ProcedureRooms, } resp.SmallMain = d.SmallMain return resp diff --git a/internal/domain/main-entities/infra/entity.go b/internal/domain/main-entities/infra/entity.go index 51cc8eaa..b9840db4 100644 --- a/internal/domain/main-entities/infra/entity.go +++ b/internal/domain/main-entities/infra/entity.go @@ -4,20 +4,20 @@ import ( ecore "simrs-vx/internal/domain/base-entities/core" ei "simrs-vx/internal/domain/main-entities/item" - erb "simrs-vx/internal/domain/main-entities/room/base" + erb "simrs-vx/internal/domain/main-entities/procedure-room/base" ero "simrs-vx/internal/domain/references/organization" ) type Infra struct { ecore.SmallMain // adjust this according to the needs - Code string `json:"code" gorm:"uniqueIndex;size:10;not null"` + Code string `json:"code" gorm:"uniqueIndex;size:20;not null"` Name string `json:"name" gorm:"size:50"` - InfraGroup_Code ero.InfraGroupCode `json:"infraGroup_code" gorm:"size:15"` - Parent_Code *string `json:"parent_code" gorm:"size:10"` + InfraGroup_Code ero.InfraGroupCode `json:"infraGroup_code" gorm:"size:20"` + Parent_Code *string `json:"parent_code" gorm:"size:20"` Parent *Infra `json:"parent" gorm:"foreignKey:Parent_Code;references:Code"` Childrens []Infra `json:"childrens" gorm:"foreignKey:Parent_Code;references:Code"` Item_Code *string `json:"item_code" gorm:"size:50"` Item *ei.Item `json:"item,omitempty" gorm:"foreignKey:Item_Code;references:Code"` - Rooms []erb.Basic `json:"rooms" gorm:"foreignKey:Infra_Code;references:Code"` + ProcedureRooms *erb.ProcedureRoom `json:"rooms" gorm:"foreignKey:Infra_Code;references:Code"` } diff --git a/internal/domain/main-entities/installation/dto.go b/internal/domain/main-entities/installation/dto.go index 5cc0ed5c..bd6fcc0e 100644 --- a/internal/domain/main-entities/installation/dto.go +++ b/internal/domain/main-entities/installation/dto.go @@ -9,9 +9,9 @@ import ( type CreateDto struct { Id *uint `json:"id"` - Code *string `json:"code" validate:"maxLength=10"` + Code *string `json:"code" validate:"maxLength=20"` Name string `json:"name" validate:"maxLength=50"` - EncounterClass_Code ere.EncounterClassCode `json:"encounterClass_code" validate:"maxLength=10"` + EncounterClass_Code ere.EncounterClassCode `json:"encounterClass_code" validate:"maxLength=20"` } type ReadListDto struct { diff --git a/internal/domain/main-entities/installation/entity.go b/internal/domain/main-entities/installation/entity.go index 5cc82430..6c3c0ecf 100644 --- a/internal/domain/main-entities/installation/entity.go +++ b/internal/domain/main-entities/installation/entity.go @@ -8,7 +8,7 @@ import ( type Installation struct { ecore.SmallMain // adjust this according to the needs - Code string `json:"code" gorm:"unique;size:10"` + Code string `json:"code" gorm:"unique;size:20"` Name string `json:"name" gorm:"size:50"` EncounterClass_Code ere.EncounterClassCode `json:"encounterClass_code" gorm:"size:10"` InstallationPositions []eipb.Basic `json:"installationPositions,omitempty" gorm:"foreignKey:Installation_Code;references:Code"` diff --git a/internal/domain/main-entities/item/dto.go b/internal/domain/main-entities/item/dto.go index f20ce217..686a5c17 100644 --- a/internal/domain/main-entities/item/dto.go +++ b/internal/domain/main-entities/item/dto.go @@ -62,6 +62,8 @@ type ResponseDto struct { Uom *eu.Uom `json:"uom,omitempty"` Infra_Code *string `json:"infra_code"` Stock *int `json:"stock"` + BuyingPrice *float64 `json:"buyingPrice"` + SellingPrice *float64 `json:"sellingPrice"` } func (d Item) ToResponse() ResponseDto { @@ -73,6 +75,8 @@ func (d Item) ToResponse() ResponseDto { Uom: d.Uom, Infra_Code: d.Infra_Code, Stock: d.Stock, + BuyingPrice: d.BuyingPrice, + SellingPrice: d.SellingPrice, } resp.Main = d.Main return resp diff --git a/internal/domain/main-entities/item/entity.go b/internal/domain/main-entities/item/entity.go index fc721713..55ca2d18 100644 --- a/internal/domain/main-entities/item/entity.go +++ b/internal/domain/main-entities/item/entity.go @@ -16,4 +16,6 @@ type Item struct { Uom *eu.Uom `json:"uom,omitempty" gorm:"foreignKey:Uom_Code;references:Code"` Infra_Code *string `json:"infra_code" gorm:"size:10"` Stock *int `json:"stock"` + BuyingPrice *float64 `json:"buyingPrice"` + SellingPrice *float64 `json:"settlingPrice"` } diff --git a/internal/domain/main-entities/material-package-item/dto.go b/internal/domain/main-entities/material-package-item/dto.go new file mode 100644 index 00000000..60b7e313 --- /dev/null +++ b/internal/domain/main-entities/material-package-item/dto.go @@ -0,0 +1,73 @@ +package materialpackage + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + em "simrs-vx/internal/domain/main-entities/material" + emp "simrs-vx/internal/domain/main-entities/material-package" +) + +type CreateDto struct { + MaterialPackage_Code string `json:"materialPackage_code" validate:"maxLength=20"` + Material_Code string `json:"material_code" validate:"maxLength=20"` + Count uint16 `json:"count" validate:"required"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Pagination ecore.Pagination + Sort string `json:"sort"` +} + +type FilterDto struct { + MaterialPackage_Code string `json:"material-package-code"` + Material_Code string `json:"material_code"` +} + +type ReadDetailDto struct { + Id uint `json:"id"` +} + +type UpdateDto struct { + Id uint `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.Main + MaterialPackage_Code string `json:"materialPackage_code"` + MaterialPackage *emp.MaterialPackage `json:"materialPackage,omitempty"` + Material_Code string `json:"material_code"` + Material *em.Material `json:"material,omitempty"` + Count *uint16 `json:"count"` +} + +func (d MaterialPackageItem) ToResponse() ResponseDto { + resp := ResponseDto{ + MaterialPackage_Code: d.MaterialPackage_Code, + MaterialPackage: d.MaterialPackage, + Material_Code: d.Material_Code, + Material: d.Material, + Count: d.Count, + } + resp.Id = d.Id + return resp +} + +func ToResponseList(data []MaterialPackageItem) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/material-package-item/entity.go b/internal/domain/main-entities/material-package-item/entity.go new file mode 100644 index 00000000..0c45969b --- /dev/null +++ b/internal/domain/main-entities/material-package-item/entity.go @@ -0,0 +1,16 @@ +package materialpackage + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + em "simrs-vx/internal/domain/main-entities/material" + emp "simrs-vx/internal/domain/main-entities/material-package" +) + +type MaterialPackageItem struct { + ecore.Main + MaterialPackage_Code string `json:"materialPackage_code" gorm:"size:20;not null"` + MaterialPackage *emp.MaterialPackage `json:"materialPackage" gorm:"foreignKey:MaterialPackage_Code;references:Code"` + Material_Code string `json:"code" gorm:"size:20;not null"` + Material *em.Material `json:"material" gorm:"foreignKey:Material_Code;references:Code"` + Count *uint16 `json:"count"` +} diff --git a/internal/domain/main-entities/material-package/dto.go b/internal/domain/main-entities/material-package/dto.go new file mode 100644 index 00000000..51dc1ab1 --- /dev/null +++ b/internal/domain/main-entities/material-package/dto.go @@ -0,0 +1,66 @@ +package materialpackage + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" +) + +type CreateDto struct { + Code string `json:"code" validate:"maxLength=20"` + Name string `json:"name" validate:"maxLength=50"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Pagination ecore.Pagination + Sort string `json:"sort"` +} + +type FilterDto struct { + Code string `json:"code"` + Name string `json:"name"` +} + +type ReadDetailDto struct { + Id *uint16 `json:"id"` + Code *string `json:"code"` +} + +type UpdateDto struct { + Id uint16 `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id *uint16 `json:"id"` + Code *string `json:"code"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.SmallMain + Code string `json:"code"` + Name string `json:"name"` +} + +func (d MaterialPackage) ToResponse() ResponseDto { + resp := ResponseDto{ + Code: d.Code, + Name: d.Name, + } + resp.SmallMain = d.SmallMain + return resp +} + +func ToResponseList(data []MaterialPackage) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/material-package/entity.go b/internal/domain/main-entities/material-package/entity.go new file mode 100644 index 00000000..4f3feeab --- /dev/null +++ b/internal/domain/main-entities/material-package/entity.go @@ -0,0 +1,11 @@ +package materialpackage + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" +) + +type MaterialPackage struct { + ecore.SmallMain + Code string `json:"code" gorm:"unique;size:20;not null"` + Name string `json:"name" gorm:"size:50"` +} diff --git a/internal/domain/main-entities/mcu-order-item/entity.go b/internal/domain/main-entities/mcu-order-item/entity.go index 48a57bac..7d4d757d 100644 --- a/internal/domain/main-entities/mcu-order-item/entity.go +++ b/internal/domain/main-entities/mcu-order-item/entity.go @@ -4,12 +4,14 @@ import ( emo "simrs-vx/internal/domain/main-entities/mcu-order" emoib "simrs-vx/internal/domain/main-entities/mcu-order-item/base" + emosi "simrs-vx/internal/domain/main-entities/mcu-order-sub-item/base" erc "simrs-vx/internal/domain/references/common" ) type McuOrderItem struct { emoib.McuOrderItem - McuOrder *emo.McuOrder `json:"mcuOrder,omitempty" gorm:"foreignKey:McuOrder_Id;references:Id"` + McuOrder *emo.McuOrder `json:"mcuOrder,omitempty" gorm:"foreignKey:McuOrder_Id;references:Id"` + Items []*emosi.McuOrderSubItem `json:"items" gorm:"foreignKey:McuOrderItem_Id;references:Id"` } func (d McuOrderItem) IsCompleted() bool { diff --git a/internal/domain/main-entities/mcu-order-sub-item/base/entity.go b/internal/domain/main-entities/mcu-order-sub-item/base/entity.go new file mode 100644 index 00000000..0022744b --- /dev/null +++ b/internal/domain/main-entities/mcu-order-sub-item/base/entity.go @@ -0,0 +1,15 @@ +package mcuordersubitem + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + + erc "simrs-vx/internal/domain/references/common" +) + +type McuOrderSubItem struct { + ecore.Main // adjust this according to the needs + McuSubSrc_Code *string `json:"mcuSubSrc_code" gorm:"uniqueIndex:idx_order_sub_src"` + McuOrderItem_Id *uint `json:"mcuOrderItem_id" gorm:"uniqueIndex:idx_order_sub_src"` + Result *string `json:"result"` + Status_Code erc.DataStatusCode `json:"status_code"` +} diff --git a/internal/domain/main-entities/mcu-order-sub-item/entity.go b/internal/domain/main-entities/mcu-order-sub-item/entity.go index a9bde496..b594a91b 100644 --- a/internal/domain/main-entities/mcu-order-sub-item/entity.go +++ b/internal/domain/main-entities/mcu-order-sub-item/entity.go @@ -5,17 +5,15 @@ import ( emoi "simrs-vx/internal/domain/main-entities/mcu-order-item" emss "simrs-vx/internal/domain/main-entities/mcu-sub-src" + emosi "simrs-vx/internal/domain/main-entities/mcu-order-sub-item/base" erc "simrs-vx/internal/domain/references/common" ) type McuOrderSubItem struct { - ecore.Main // adjust this according to the needs - McuSubSrc_Code *string `json:"mcuSubSrc_code" gorm:"uniqueIndex:idx_order_sub_src"` - McuSubSrc *emss.McuSubSrc `json:"mcuSubSrc,omitempty" gorm:"foreignKey:McuSubSrc_Code;references:Code"` - McuOrderItem_Id *uint `json:"mcuOrderItem_id" gorm:"uniqueIndex:idx_order_sub_src"` - McuOrderItem *emoi.McuOrderItem `json:"mcuOrderItem,omitempty" gorm:"foreignKey:McuOrderItem_Id;references:Id"` - Result *string `json:"result"` - Status_Code erc.DataStatusCode `json:"status_code"` + ecore.Main // adjust this according to the needs + McuSubSrc *emss.McuSubSrc `json:"mcuSubSrc,omitempty" gorm:"foreignKey:McuSubSrc_Code;references:Code"` + McuOrderItem *emoi.McuOrderItem `json:"mcuOrderItem,omitempty" gorm:"foreignKey:McuOrderItem_Id;references:Id"` + emosi.McuOrderSubItem } func (d McuOrderSubItem) IsCompleted() bool { diff --git a/internal/domain/main-entities/mcu-src-category/dto.go b/internal/domain/main-entities/mcu-src-category/dto.go index f9bb7d00..e1ef57d9 100644 --- a/internal/domain/main-entities/mcu-src-category/dto.go +++ b/internal/domain/main-entities/mcu-src-category/dto.go @@ -1,4 +1,4 @@ -package division +package mcusrccategory import ( ecore "simrs-vx/internal/domain/base-entities/core" @@ -20,10 +20,10 @@ type ReadListDto struct { } type FilterDto struct { - Code string `json:"code"` - Name string `json:"name"` - Scope_Code *erc.McuScopeCode `json:"scope-code"` - Search string `json:"search" gormhelper:"searchColumns=Code,Name"` + Code *string `json:"code"` + Name *string `json:"name"` + Scope_Code *string `json:"scope-code"` + Search string `json:"search" gormhelper:"searchColumns=Code,Name"` } type ReadDetailDto struct { diff --git a/internal/domain/main-entities/mcu-src-category/entity.go b/internal/domain/main-entities/mcu-src-category/entity.go index 8fc801b9..2175552c 100644 --- a/internal/domain/main-entities/mcu-src-category/entity.go +++ b/internal/domain/main-entities/mcu-src-category/entity.go @@ -1,4 +1,4 @@ -package division +package mcusrccategory import ( ecore "simrs-vx/internal/domain/base-entities/core" diff --git a/internal/domain/main-entities/person/entity.go b/internal/domain/main-entities/person/entity.go index 8d7f79a8..3c7d8629 100644 --- a/internal/domain/main-entities/person/entity.go +++ b/internal/domain/main-entities/person/entity.go @@ -10,6 +10,7 @@ import ( epi "simrs-vx/internal/domain/main-entities/person-insurance" epr "simrs-vx/internal/domain/main-entities/person-relative" er "simrs-vx/internal/domain/main-entities/regency" + "strings" erp "simrs-vx/internal/domain/references/person" @@ -58,3 +59,62 @@ func (d Person) IsSameResidentIdentityNumber(input *string) bool { } return d.ResidentIdentityNumber == input } + +func (d Person) GenderString() string { + if d.Gender_Code == nil { + return "" + } + switch *d.Gender_Code { + case erp.GCMale: + return "Laki-laki(L)" + case erp.GCFemale: + return "Perempuan(P)" + default: + return "" + } +} + +func (d Person) GetPhoneNumber() string { + if d.Contacts == nil { + return "" + } + for _, c := range *d.Contacts { + if c.Type_Code == erp.CTPhone || c.Type_Code == erp.CTMPhone { + return c.Value + } + } + return "" +} + +func (d Person) FullName() string { + name := strings.TrimSpace(d.Name) + if name == "" { + return "" + } + + parts := []string{} + + // Front title (dr., drs., etc) + if d.FrontTitle != nil { + ft := strings.TrimSpace(*d.FrontTitle) + if ft != "" { + parts = append(parts, ft) + } + } + + // Name (always included) + parts = append(parts, name) + + // Join front title + name + full := strings.Join(parts, " ") + + // End title → attach with comma + if d.EndTitle != nil { + et := strings.TrimSpace(*d.EndTitle) + if et != "" { + full = full + ", " + et + } + } + + return full +} diff --git a/internal/domain/main-entities/procedure-room-order-item/dto.go b/internal/domain/main-entities/procedure-room-order-item/dto.go new file mode 100644 index 00000000..4b564ce6 --- /dev/null +++ b/internal/domain/main-entities/procedure-room-order-item/dto.go @@ -0,0 +1,69 @@ +package procedureroomorder + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + epr "simrs-vx/internal/domain/main-entities/procedure-room" +) + +type CreateDto struct { + ProcedureRoomOrder_Id uint64 `json:"procedureRoomOrder_id"` + ProcedureRoom_Code string `json:"procedureRoom_code"` + Note string `json:"note"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Pagination ecore.Pagination +} + +type FilterDto struct { + Encounter_Id uint64 `json:"encounter-id"` +} + +type ReadDetailDto struct { + Id uint64 `json:"id"` + Includes string `json:"includes"` +} + +type UpdateDto struct { + Id uint64 `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint64 `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.BigMain + ProcedureRoomOrder_Id uint64 `json:"procedureRoomOrder_id"` + ProcedureRoom_Code string `json:"procedureRoom_code"` + ProcedureRoom *epr.ProcedureRoom `json:"procedureRoom,omitempty"` + Note string `json:"note"` +} + +func (d ProcedureRoomOrderItem) ToResponse() ResponseDto { + resp := ResponseDto{ + ProcedureRoomOrder_Id: d.ProcedureRoomOrder_Id, + ProcedureRoom_Code: d.ProcedureRoom_Code, + ProcedureRoom: d.ProcedureRoom, + Note: d.Note, + } + resp.Id = d.Id + return resp +} + +func ToResponseList(data []ProcedureRoomOrderItem) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/procedure-room-order-item/entity.go b/internal/domain/main-entities/procedure-room-order-item/entity.go new file mode 100644 index 00000000..4a737048 --- /dev/null +++ b/internal/domain/main-entities/procedure-room-order-item/entity.go @@ -0,0 +1,14 @@ +package procedureroomorder + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + epr "simrs-vx/internal/domain/main-entities/procedure-room" +) + +type ProcedureRoomOrderItem struct { + ecore.BigMain + ProcedureRoomOrder_Id uint64 `json:"procedureRoomOrder_id"` + ProcedureRoom_Code string `json:"procedureRoom_code" gorm:"size:20"` + ProcedureRoom *epr.ProcedureRoom `json:"procedureRoom,omitempty" gorm:"foreignKey:ProcedureRoom_Code;references:Code"` + Note string `json:"note" gorm:"size:255"` +} diff --git a/internal/domain/main-entities/procedure-room-order/dto.go b/internal/domain/main-entities/procedure-room-order/dto.go new file mode 100644 index 00000000..5810e756 --- /dev/null +++ b/internal/domain/main-entities/procedure-room-order/dto.go @@ -0,0 +1,74 @@ +package procedureroomorder + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + ec "simrs-vx/internal/domain/main-entities/encounter" + emp "simrs-vx/internal/domain/main-entities/material-package" + epr "simrs-vx/internal/domain/main-entities/procedure-room" + erc "simrs-vx/internal/domain/references/common" +) + +type CreateDto struct { + Encounter_Id uint64 `json:"encounter_id" validate:"required"` + Infra_Code string `json:"infra_code" validate:"required"` + MaterialPackage_Code string `json:"materialPackage_code" validate:"required"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Pagination ecore.Pagination +} + +type FilterDto struct { + Encounter_Id uint64 `json:"encounter-id"` +} + +type ReadDetailDto struct { + Id uint64 `json:"id"` +} + +type UpdateDto struct { + Id uint64 `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint64 `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.BigMain + Encounter_Id uint64 `json:"encounter_id"` + Encounter *ec.Encounter `json:"encounter,omitempty"` + Infra_Code string `json:"procedure"` + MaterialPackage_Code string `json:"materialPackage_code"` + Status_Code erc.DataStatusCode `json:"status_code"` + ProcedureRoom *epr.ProcedureRoom `json:"procedureRoom,omitempty"` + MaterialPackage *emp.MaterialPackage `json:"materialPackage,omitempty"` +} + +func (d ProcedureRoomOrder) ToResponse() ResponseDto { + resp := ResponseDto{ + Encounter_Id: d.Encounter_Id, + Infra_Code: d.Infra_Code, + MaterialPackage_Code: d.MaterialPackage_Code, + Status_Code: d.Status_Code, + } + resp.Id = d.Id + return resp +} + +func ToResponseList(data []ProcedureRoomOrder) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/procedure-room-order/entity.go b/internal/domain/main-entities/procedure-room-order/entity.go new file mode 100644 index 00000000..1ef7c178 --- /dev/null +++ b/internal/domain/main-entities/procedure-room-order/entity.go @@ -0,0 +1,19 @@ +package procedureroomorder + +import ( + erc "simrs-vx/internal/domain/references/common" + + ecore "simrs-vx/internal/domain/base-entities/core" + emp "simrs-vx/internal/domain/main-entities/material-package" + epr "simrs-vx/internal/domain/main-entities/procedure-room" +) + +type ProcedureRoomOrder struct { + ecore.BigMain + Encounter_Id uint64 `json:"encounter_id"` + Infra_Code string `json:"infra_code" gorm:"size:20"` + ProcedureRoom *epr.ProcedureRoom `json:"procedureRoom,omitempty" gorm:"foreignKey:Infra_Code;references:Code"` + MaterialPackage_Code string `json:"materialPackage_code" gorm:"size:20"` + MaterialPackage *emp.MaterialPackage `json:"materialPackage,omitempty" gorm:"foreignKey:MaterialPackage_Code;references:Code"` + Status_Code erc.DataStatusCode `json:"status_code" gorm:"size:20"` +} diff --git a/internal/domain/main-entities/procedure-room/base/entity.go b/internal/domain/main-entities/procedure-room/base/entity.go new file mode 100644 index 00000000..981dd4f2 --- /dev/null +++ b/internal/domain/main-entities/procedure-room/base/entity.go @@ -0,0 +1,21 @@ +package procedureroombase + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + ero "simrs-vx/internal/domain/references/organization" +) + +type ProcedureRoom struct { + ecore.SmallMain + Code string `json:"code" gorm:"unique;size:20"` // copied from infra code + Infra_Code *string `json:"infra_code" gorm:"size:20;unique"` + Type_Code *ero.ProdcedureRoomTypeCode `json:"type_code" gorm:"size:10"` + Unit_Code *string `json:"unit_code" gorm:"size:20"` + Specialist_Code *string `json:"specialist_code" gorm:"size:20"` + Subspecialist_Code *string `json:"subspecialist_code" gorm:"size:20"` +} + +// THIS IS ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ +// func (ProcedureRoom) TableName() string { +// return "Room" +// } diff --git a/internal/domain/main-entities/room/dto.go b/internal/domain/main-entities/procedure-room/dto.go similarity index 82% rename from internal/domain/main-entities/room/dto.go rename to internal/domain/main-entities/procedure-room/dto.go index 2ff41c3a..373e6cd9 100644 --- a/internal/domain/main-entities/room/dto.go +++ b/internal/domain/main-entities/procedure-room/dto.go @@ -1,4 +1,4 @@ -package room +package procedureroom import ( ecore "simrs-vx/internal/domain/base-entities/core" @@ -9,7 +9,9 @@ import ( ) type CreateDto struct { + Code *string `json:"code"` Infra_Code *string `json:"infra_code"` + Type_Code string `json:"type_code"` Unit_Code *string `json:"unit_code"` Specialist_Code *string `json:"specialist_code"` Subspecialist_Code *string `json:"subspecialist_code"` @@ -23,6 +25,7 @@ type ReadListDto struct { type FilterDto struct { Infra_Code *string `json:"infra-code"` + Type_Code string `json:"type_code"` Unit_Code *string `json:"unit-code"` Specialist_Code *string `json:"specialist-code"` Subspecialist_Code *string `json:"subspecialist-code"` @@ -49,6 +52,8 @@ type MetaDto struct { type ResponseDto struct { ecore.SmallMain + Code string `json:"code"` + Type_Code *string `json:"type_code"` Infra_Code *string `json:"infra_code"` Infra *ei.Infra `json:"infra,omitempty"` Unit_Code *string `json:"unit_code"` @@ -59,10 +64,12 @@ type ResponseDto struct { Subspecialist *ess.Subspecialist `json:"subspecialist,omitempty"` } -func (d Room) ToResponse() ResponseDto { +func (d ProcedureRoom) ToResponse() ResponseDto { resp := ResponseDto{ + Code: d.Code, Infra_Code: d.Infra_Code, Infra: d.Infra, + Type_Code: (*string)(d.Type_Code), Unit_Code: d.Unit_Code, Unit: d.Unit, Specialist_Code: d.Specialist_Code, @@ -74,7 +81,7 @@ func (d Room) ToResponse() ResponseDto { return resp } -func ToResponseList(data []Room) []ResponseDto { +func ToResponseList(data []ProcedureRoom) []ResponseDto { resp := make([]ResponseDto, len(data)) for i, u := range data { resp[i] = u.ToResponse() diff --git a/internal/domain/main-entities/procedure-room/entity.go b/internal/domain/main-entities/procedure-room/entity.go new file mode 100644 index 00000000..9be3ac69 --- /dev/null +++ b/internal/domain/main-entities/procedure-room/entity.go @@ -0,0 +1,17 @@ +package procedureroom + +import ( + ei "simrs-vx/internal/domain/main-entities/infra" + ebase "simrs-vx/internal/domain/main-entities/procedure-room/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" +) + +type ProcedureRoom struct { + ebase.ProcedureRoom + Infra *ei.Infra `json:"infra,omitempty" gorm:"foreignKey:Infra_Code;references:Code"` + Unit *eu.Unit `json:"unit,omitempty" gorm:"foreignKey:Unit_Code;references:Code"` + Specialist *es.Specialist `json:"specialist,omitempty" gorm:"foreignKey:Specialist_Code;references:Code"` + Subspecialist *ess.Subspecialist `json:"subspecialist,omitempty" gorm:"foreignKey:Subspecialist_Code;references:Code"` +} diff --git a/internal/domain/main-entities/resume/dto.go b/internal/domain/main-entities/resume/dto.go index ea9485d7..e7ddf09b 100644 --- a/internal/domain/main-entities/resume/dto.go +++ b/internal/domain/main-entities/resume/dto.go @@ -2,11 +2,19 @@ package resume import ( ecore "simrs-vx/internal/domain/base-entities/core" + "time" + + erc "simrs-vx/internal/domain/references/common" + + pa "simrs-vx/internal/lib/auth" ) type CreateDto struct { - Encounter_Id *uint `json:"encounter_id"` - Value *string `json:"value"` + Encounter_Id *uint `json:"encounter_id"` + Value *string `json:"value"` + Status_Code erc.DataVerifiedCode `json:"status_code"` + + pa.AuthInfo } type ReadListDto struct { @@ -16,11 +24,13 @@ type ReadListDto struct { } type FilterDto struct { - Encounter_Id *uint `json:"encounter-id"` + Encounter_Id *uint `json:"encounter-id"` + Doctor_Code *string `json:"doctor-code"` } type ReadDetailDto struct { - Id uint `json:"id"` + Id uint `json:"id"` + Includes string `json:"includes"` } type UpdateDto struct { @@ -30,6 +40,8 @@ type UpdateDto struct { type DeleteDto struct { Id uint `json:"id"` + + pa.AuthInfo } type MetaDto struct { @@ -40,16 +52,20 @@ type MetaDto struct { type ResponseDto struct { ecore.Main - Encounter_Id *uint `json:"encounter_id"` - Value *string `json:"value"` - FileUrl *string `json:"fileUrl"` + Encounter_Id *uint `json:"encounter_id"` + Doctor_Code *string `json:"doctor_code"` + Value *string `json:"value"` + FileUrl *string `json:"fileUrl"` + Status_Code erc.DataVerifiedCode `json:"status_code"` } func (d Resume) ToResponse() ResponseDto { resp := ResponseDto{ Encounter_Id: d.Encounter_Id, + Doctor_Code: d.Doctor_Code, Value: d.Value, FileUrl: d.FileUrl, + Status_Code: d.Status_Code, } resp.Main = d.Main return resp @@ -62,3 +78,105 @@ func ToResponseList(data []Resume) []ResponseDto { } return resp } + +// ValueDto is for resume value +type ValueDto struct { + Assessment Assessment `json:"assessment"` + Diagnosis Diagnosis `json:"diagnosis"` + Action Action `json:"action"` + Consultation Consultation `json:"consultation"` + Supporting SupportingExaminations `json:"supporting"` + Pharmacy PharmacyData `json:"pharmacy"` + Discharge DischargeCondition `json:"discharge"` + National NationalProgram `json:"national"` + Management Management `json:"management"` + Medication Medication `json:"medication"` +} + +type Assessment struct { + StartedAt *time.Time `json:"startedAt` + FinishedAt *time.Time `json:"finishedAt` + Doctor_Code string `json:"doctor_code` + DiagnosisIn string `json:"diagnosisIn` + AmbulatoryIndication string `json:"ambulatoryIndication"` + MainComplaint string `json:"mainComplaint"` + PhysicalExamination string `json:"physicalExamination"` + MedicalHistory string `json:"medicalHistory"` + MedicalDiagnosis string `json:"medicalDiagnosis"` +} + +type Diagnosis struct { + PrimaryDiagnosis DiagnosisEntry `json:"primaryDiagnosis"` + SecondaryDiagnosis []DiagnosisEntry `json:"secondaryDiagnosis"` +} + +type DiagnosisEntry struct { + DiagnosisName string `json:"diagnosis"` + ICD10 string `json:"icd_10"` + Basis string `json:"basis"` // Clinical basis of diagnosis / dasar diagnosa +} + +type Action struct { + PrimaryAction ActionEntry `json:"primaryAction"` + AdditionalActions []ActionEntry `json:"additionalActions"` + MedicalActions string `json:"medicalActions"` // free-text: "Tindakan Medis" +} + +type ActionEntry struct { + Action string `json:"action"` // Tindakan + ICD9 string `json:"icd_9"` // ICD-9 + Basis string `json:"basis"` // Dasar Tindakan +} + +type Consultation struct { + Consultations []ConsultationEntry `json:"consultations"` +} + +type ConsultationEntry struct { + Consultation string `json:"consultation"` // Konsultasi + ConsultationAnswer string `json:"consultationAnswer"` // Jawaban Konsultasi +} + +type SupportingExaminations struct { + Notes string `json:"notes"` // Free-text list of lab/imaging results +} + +type PharmacyData struct { + AllergySpecialConditions string `json:"allergySpecialConditions"` // Kelainan Khusus Alergi + OtherConditions string `json:"otherConditions"` // Kelainan Lain + TherapyDuringCare string `json:"therapyDuringCare"` // Terapi selama dirawat + TherapyAtDischarge string `json:"therapyAtDischarge"` // Terapi waktu pulang + FollowUpInstructions string `json:"followUpInstructions"` // Edukasi / Anjuran / Follow-up +} + +type DischargeCondition struct { + BloodPressureSystolic float64 `json:"bloodPressureSystolic"` // Tekanan Darah Sistol (mmHg) + BloodPressureDiastolic float64 `json:"bloodPressureDiastolic"` // Tekanan Darah Diastol (mmHg) + RespirationRate float64 `json:"respirationRate"` // Pernafasan (kali/menit) + HeartRate float64 `json:"heartRate"` // Denyut Jantung (kali/menit) + BodyTemperature float64 `json:"bodyTemperature"` // Suhu Tubuh (°C) + + ConsciousnessLevel string `json:"consciousnessLevel"` // Tingkat Kesadaran + PainScale int `json:"painScale"` // Skala Nyeri (0–10) +} + +type NationalProgram struct { + ProgramService string `json:"programService"` // e.g. "Antenatal Care" + ProgramServiceStatus string `json:"programServiceStatus"` // e.g. "Suspected" +} + +type Management struct { + NationalProgramService string `json:"nationalProgramService"` // e.g. selected program + FollowUpManagement string `json:"followUpManagement"` // e.g. further management plan + ConditionOnDischarge string `json:"conditionOnDischarge"` // e.g. "Stable" + DischargeMethod string `json:"dischargeMethod"` // e.g. "Discharged with Doctor's Approval" +} + +type MedicationEntry struct { + DuringTreatment string `json:"duringTreatment"` + AtDischarge string `json:"atDischarge"` +} + +type Medication struct { + Medications []MedicationEntry `json:"medications"` +} diff --git a/internal/domain/main-entities/resume/entity.go b/internal/domain/main-entities/resume/entity.go index 70050166..93a1d8cd 100644 --- a/internal/domain/main-entities/resume/entity.go +++ b/internal/domain/main-entities/resume/entity.go @@ -16,3 +16,15 @@ type Resume struct { FileUrl *string `json:"fileUrl" gorm:"size:1024"` Status_Code erc.DataVerifiedCode `json:"status_code" gorm:"not null;size:10"` } + +func (d Resume) IsNew() bool { + return d.Status_Code == erc.DVCNew +} + +func (d Resume) IsVerified() bool { + return d.Status_Code == erc.DVCVerified +} + +func (d Resume) IsValidated() bool { + return d.Status_Code == erc.DVCValidated +} diff --git a/internal/domain/main-entities/room/base/entity.go b/internal/domain/main-entities/room/base/entity.go deleted file mode 100644 index d5651ac9..00000000 --- a/internal/domain/main-entities/room/base/entity.go +++ /dev/null @@ -1,23 +0,0 @@ -package base - -import ( - ecore "simrs-vx/internal/domain/base-entities/core" - es "simrs-vx/internal/domain/main-entities/specialist" - ess "simrs-vx/internal/domain/main-entities/subspecialist" - eu "simrs-vx/internal/domain/main-entities/unit" -) - -type Basic struct { - ecore.SmallMain // adjust this according to the needs - Infra_Code *string `json:"infra_code" gorm:"size:10"` - Unit_Code *string `json:"unit_code" gorm:"size:10"` - Unit *eu.Unit `json:"unit,omitempty" gorm:"foreignKey:Unit_Code;references:Code"` - Specialist_Code *string `json:"specialist_code" gorm:"size:10"` - Specialist *es.Specialist `json:"specialist,omitempty" gorm:"foreignKey:Specialist_Code;references:Code"` - Subspecialist_Code *string `json:"subspecialist_code" gorm:"size:10"` - Subspecialist *ess.Subspecialist `json:"subspecialist,omitempty" gorm:"foreignKey:Subspecialist_Code;references:Code"` -} - -func (Basic) TableName() string { - return "Room" -} diff --git a/internal/domain/main-entities/room/entity.go b/internal/domain/main-entities/room/entity.go deleted file mode 100644 index 49fb8cc6..00000000 --- a/internal/domain/main-entities/room/entity.go +++ /dev/null @@ -1,11 +0,0 @@ -package room - -import ( - ei "simrs-vx/internal/domain/main-entities/infra" - ebase "simrs-vx/internal/domain/main-entities/room/base" -) - -type Room struct { - ebase.Basic - Infra *ei.Infra `json:"infra,omitempty" gorm:"foreignKey:Infra_Code;references:Code"` -} diff --git a/internal/domain/main-entities/screening/dto.go b/internal/domain/main-entities/screening/dto.go new file mode 100644 index 00000000..5dfed2c7 --- /dev/null +++ b/internal/domain/main-entities/screening/dto.go @@ -0,0 +1,86 @@ +package screening + +import ( + // std + + // internal - lib + pa "simrs-vx/internal/lib/auth" + + // internal - domain - base-entities + ecore "simrs-vx/internal/domain/base-entities/core" + + // internal - domain - main-entities + eem "simrs-vx/internal/domain/main-entities/employee" + + erc "simrs-vx/internal/domain/references/clinical" +) + +type CreateDto struct { + Encounter_Id *uint `json:"encounter_id"` + Employee_Id *uint `json:"-"` + Type erc.ScreeningFormTypeCode `json:"type"` + Value *string `json:"value"` + + pa.AuthInfo +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Pagination ecore.Pagination +} + +type FilterDto struct { + Encounter_Id *uint `json:"encounter-id"` + Employee_Id *uint `json:"employee-id"` + Type erc.ScreeningFormTypeCode `json:"type"` + Value *string `json:"value"` +} + +type ReadDetailDto struct { + Id uint16 `json:"id"` +} + +type UpdateDto struct { + Id uint16 `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint16 `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.Main + Encounter_Id *uint `json:"encounter_id"` + Employee_Id *uint `json:"employee_id"` + Employee *eem.Employee `json:"employee,omitempty"` + Type erc.ScreeningFormTypeCode `json:"type"` + Value *string `json:"value"` +} + +func (d Screening) ToResponse() ResponseDto { + resp := ResponseDto{ + Encounter_Id: d.Encounter_Id, + Employee_Id: d.Employee_Id, + Employee: d.Employee, + Type: d.Type, + Value: d.Value, + } + resp.Main = d.Main + return resp +} + +func ToResponseList(data []Screening) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/screening/entity.go b/internal/domain/main-entities/screening/entity.go new file mode 100644 index 00000000..a6284c16 --- /dev/null +++ b/internal/domain/main-entities/screening/entity.go @@ -0,0 +1,20 @@ +package screening + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + eem "simrs-vx/internal/domain/main-entities/employee" + + erc "simrs-vx/internal/domain/references/clinical" + erco "simrs-vx/internal/domain/references/common" +) + +type Screening struct { + ecore.Main // adjust this according to the needs + Encounter_Id *uint `json:"encounter_id"` + Employee_Id *uint `json:"employee_id"` + Employee *eem.Employee `json:"employee,omitempty" gorm:"foreignKey:Employee_Id;references:Id"` + Type erc.ScreeningFormTypeCode `json:"type"` + Status erco.DataVerifiedCode `json:"status"` + Value *string `json:"value"` + FileUrl *string `json:"fileUrl" gorm:"size:1024"` +} diff --git a/internal/domain/main-entities/soapi/entity.go b/internal/domain/main-entities/soapi/entity.go index 7e457ca9..d67f692a 100644 --- a/internal/domain/main-entities/soapi/entity.go +++ b/internal/domain/main-entities/soapi/entity.go @@ -17,6 +17,6 @@ type Soapi struct { Employee_Id *uint `json:"employee_id"` Employee *eem.Employee `json:"employee,omitempty" gorm:"foreignKey:Employee_Id;references:Id"` Time *time.Time `json:"time"` - TypeCode erc.SoapiTypeCode `json:"type_code" gorm:"size:11"` + TypeCode erc.SoapiTypeCode `json:"type_code" gorm:"size:15"` Value *string `json:"value"` } diff --git a/internal/domain/main-entities/specialist/entity.go b/internal/domain/main-entities/specialist/entity.go index 4fef90a5..0b5b7a5d 100644 --- a/internal/domain/main-entities/specialist/entity.go +++ b/internal/domain/main-entities/specialist/entity.go @@ -9,9 +9,9 @@ import ( type Specialist struct { ecore.SmallMain // adjust this according to the needs - Code string `json:"code" gorm:"unique;size:10"` + Code string `json:"code" gorm:"unique;size:20"` Name string `json:"name" gorm:"size:50"` - Unit_Code *string `json:"unit_code" gorm:"size:10"` + Unit_Code *string `json:"unit_code" gorm:"size:20"` Unit *eu.Unit `json:"unit,omitempty" gorm:"foreignKey:Unit_Code;references:Code"` SpecialistPositions []eub.Basic `json:"specialistPositions,omitempty" gorm:"foreignKey:Specialist_Code;references:Code"` Subspecialists []essb.Basic `json:"subspecialists,omitempty" gorm:"foreignKey:Specialist_Code;references:Code"` diff --git a/internal/domain/main-entities/subspecialist-position/dto.go b/internal/domain/main-entities/subspecialist-position/dto.go index 1c37a859..4918a8fe 100644 --- a/internal/domain/main-entities/subspecialist-position/dto.go +++ b/internal/domain/main-entities/subspecialist-position/dto.go @@ -8,7 +8,7 @@ import ( type CreateDto struct { Subspecialist_Code *string `json:"subspecialist_code" validate:"required"` - Code string `json:"code" validate:"maxLength=10;required"` + Code string `json:"code" validate:"maxLength=20;required"` Name string `json:"name" validate:"maxLength=30;required"` HeadStatus bool `json:"headStatus"` Employee_Id *uint `json:"employee_id"` diff --git a/internal/domain/main-entities/subspecialist/base/entity.go b/internal/domain/main-entities/subspecialist/base/entity.go index a94fb76d..9fe77039 100644 --- a/internal/domain/main-entities/subspecialist/base/entity.go +++ b/internal/domain/main-entities/subspecialist/base/entity.go @@ -6,9 +6,9 @@ import ( type Basic struct { ecore.SmallMain // adjust this according to the needs - Code string `json:"code" gorm:"unique;size:10"` + Code string `json:"code" gorm:"unique;size:20"` Name string `json:"name" gorm:"size:50"` - Specialist_Code *string `json:"specialist_code" gorm:"size:10"` + Specialist_Code *string `json:"specialist_code" gorm:"size:20"` } func (Basic) TableName() string { diff --git a/internal/domain/main-entities/subspecialist/dto.go b/internal/domain/main-entities/subspecialist/dto.go index 72959023..303da04f 100644 --- a/internal/domain/main-entities/subspecialist/dto.go +++ b/internal/domain/main-entities/subspecialist/dto.go @@ -8,7 +8,7 @@ import ( type CreateDto struct { Id *uint `json:"id"` - Code string `json:"code" validate:"maxLength=10"` + Code string `json:"code" validate:"maxLength=20"` Name string `json:"name" validate:"maxLength=50"` Specialist_Code *string `json:"specialist_code"` } diff --git a/internal/domain/main-entities/unit/dto.go b/internal/domain/main-entities/unit/dto.go index 7b071a84..76151cb7 100644 --- a/internal/domain/main-entities/unit/dto.go +++ b/internal/domain/main-entities/unit/dto.go @@ -9,7 +9,7 @@ import ( type CreateDto struct { Id *uint `json:"id"` Installation_Code *string `json:"installation_code"` - Code string `json:"code" validate:"maxLength=10"` + Code string `json:"code" validate:"maxLength=20"` Name string `json:"name" validate:"maxLength=50"` } diff --git a/internal/domain/main-entities/unit/entity.go b/internal/domain/main-entities/unit/entity.go index 97db9885..e8110db3 100644 --- a/internal/domain/main-entities/unit/entity.go +++ b/internal/domain/main-entities/unit/entity.go @@ -9,9 +9,9 @@ import ( type Unit struct { ecore.SmallMain // adjust this according to the needs - Installation_Code *string `json:"installation_code" gorm:"size:10"` + Installation_Code *string `json:"installation_code" gorm:"size:20"` Installation *ei.Installation `json:"installation" gorm:"foreignKey:Installation_Code;references:Code"` - Code string `json:"code" gorm:"unique;size:10"` + Code string `json:"code" gorm:"unique;size:20"` Name string `json:"name" gorm:"size:50"` Type_Code *ero.UnitTypeCode `json:"type_code"` UnitPositions []eub.Basic `json:"unitPositions,omitempty" gorm:"foreignKey:Unit_Code;references:Code"` diff --git a/internal/domain/references/clinical/clinical.go b/internal/domain/references/clinical/clinical.go index 30a4fe8a..a9d3fc2b 100644 --- a/internal/domain/references/clinical/clinical.go +++ b/internal/domain/references/clinical/clinical.go @@ -22,6 +22,14 @@ type ( LearnMethodCode string LangClassCode string TranslatorSrcCode string + ScreeningFormTypeCode string + SurgerySizeCode string + SurgerySystemCode string + SurgeryTypeCode string + SurgeryStageCode string + BornMortalityCode string + BornLocationCode string + SpecimentDestCode string ) const ( @@ -125,6 +133,7 @@ const ( STCDevRecord SoapiTypeCode = "dev-record" // Catatan Perkembangan STCKfrAdm SoapiTypeCode = "kfr-adm" // soapi untuk kfr STCKfrSeries SoapiTypeCode = "kfr-series" // soapi untuk kfr + STCAmbResume SoapiTypeCode = "amb-resume" // Rajal resume MATCChemo MedicalActionTypeCode = "chemo" MATCHemo MedicalActionTypeCode = "hemo" @@ -187,6 +196,45 @@ const ( TSCTeam TranslatorSrcCode = "team" // Tim Penerjemah TSCFamily TranslatorSrcCode = "family" // Keluarga + + SFTCA ScreeningFormTypeCode = "form-a" // Formu A + SFTCB ScreeningFormTypeCode = "form-b" // Formu B + MSCRadiology McuScopeCode = "radiology" + MSCCpLab McuScopeCode = "cp-lab" + MSCMicroLab McuScopeCode = "micro-lab" + MSCApLab McuScopeCode = "ap-lab" + + SSCSmall SurgerySizeCode = "" + SSCMedium SurgerySizeCode = "" + SSCLarge SurgerySizeCode = "" + SSCSpecial SurgerySizeCode = "" + + SSyCCito SurgerySystemCode = "" + SSyCUrgent SurgerySystemCode = "" + SSyCEfective SurgerySystemCode = "" + SSyCSpecial SurgerySystemCode = "" + + STCClean SurgeryTypeCode = "" + STCCleanCtm SurgeryTypeCode = "" + STCUncleanCtm SurgeryTypeCode = "" + STCUnclean SurgeryTypeCode = "" + + SStCFirst SurgeryStageCode = "" + SStCRepeat SurgeryStageCode = "" + + BMCAlive BornMortalityCode = "" + BMCDead BornMortalityCode = "" + + BLCExtMiw BornLocationCode = "" + BLCExtDoc BornLocationCode = "" + BLCTradMiw BornLocationCode = "" + BLCLocalMed BornLocationCode = "" + BLCExtParamedic BornLocationCode = "" + + SDCAp SpecimentDestCode = "" + SDCMicro SpecimentDestCode = "" + SDCLab SpecimentDestCode = "" + SDCNone SpecimentDestCode = "" ) type Soapi struct { @@ -311,3 +359,61 @@ type HeadToToe struct { Neuron string `json:"neuron,omitempty"` BodyOthers string `json:"body-others,omitempty"` } + +type RecordAction struct { + Procedures []string `json:"procedures"` + SurgerySize_Code *string `json:"surgerySize_code"` + Billing_Code *string `json:"billing_code"` + SurgerySystem_Code *string `json:"surgerySystem_code"` + StartAt *string `json:"startAt"` + EndAt *string `json:"endAt"` + AnesthesiaStartAt *string `json:"anesthesiaStartAt"` + AnesthesiaEndAt *string `json:"anesthesiaEndAt"` + SurgeryType_Code *string `json:"surgeryType_code"` + SurgeryStage_Code *string `json:"surgeryStage_code"` + BornMortality_Code *string `json:"bornMortality_code"` + BornLocation_Code *string `json:"bornLocation_code"` + Weight *string `json:"weight"` + BornNotes *string `json:"bornNotes" gorm:"size:1024"` + Description *string `json:"notes" gorm:"size:1024"` + BleedingAmount *uint16 `json:"bleedingAmount"` + BloodInType_Code *string `json:"bloodInType_code"` + BloodInAmount *uint16 `json:"bloodInAmount"` + Brand *string `json:"brand" gorm:"size:100"` + ImplantName *string `json:"implantName" gorm:"size:100"` + ImplantRegisterNumber *string `json:"implantRegisterNumber" gorm:"size:100"` + ImplantCompanionName *string `json:"implantCompanionName" gorm:"size:100"` + SpecimentDest_Code *string `json:"specimentDest" gorm:"size:100"` + TissueInfo []string `json:"tissueInfo" gorm:"size:100"` +} + +type SoapiSrc struct { + Id string `json:"id,omitempty"` + Code string `json:"code,omitempty"` + Name string `json:"name,omitempty"` + IndName string `json:"indName,omitempty"` +} + +type EarlyMedicValue struct { + Vaccinated bool `json:"vaccinated,omitempty"` + CaseStatus string `json:"case-status,omitempty"` + EncounterStatus string `json:"encounter-status,omitempty"` + PrimaryComplain string `json:"pri-complain,omitempty"` + CurrentDiseaseHistory string `json:"cur-disea-hist,omitempty"` + SpO2 int `json:"spo2,omitempty"` + SystolicBloodPressure int `json:"syst-bp,omitempty"` + DiastolicBloodPressure int `json:"diast-bp,omitempty"` + RespiratoryRate int `json:"resp-rate,omitempty"` + Pulse int `json:"pulse,omitempty"` + Weight int `json:"weight,omitempty"` + BloodType string `json:"blood-type,omitempty"` + Temperature int `json:"temp,omitempty"` + Height int `json:"height,omitempty"` + PhysicalExamination string `json:"physical-exam,omitempty"` + DiagnoseSrc []SoapiSrc `json:"diagnoseSrc,omitempty"` + ProcedureSrc []SoapiSrc `json:"procedureSrc,omitempty"` + EarlyMedicDiagnose string `json:"early-med-diag,omitempty"` + EarlyMedicPlan string `json:"early-med-plan,omitempty"` + Therapy string `json:"therapy,omitempty"` + ExpectedOutcome []SoapiSrc `json:"expected-outcome,omitempty"` +} diff --git a/internal/domain/references/encounter/encounter.go b/internal/domain/references/encounter/encounter.go index 231baa9b..ad6abe05 100644 --- a/internal/domain/references/encounter/encounter.go +++ b/internal/domain/references/encounter/encounter.go @@ -123,6 +123,7 @@ const ( DTCGC DocTypeCode = "general-consent" DTCVSCL DocTypeCode = "vclaim-control-letter" // vclaim control letter DTCResume DocTypeCode = "resume" // Resume + DTCScreening DocTypeCode = "screening" // Screening ETCPerson EntityTypeCode = "person" ETCEncounter EntityTypeCode = "encounter" diff --git a/internal/domain/references/organization/organization.go b/internal/domain/references/organization/organization.go index e12531cd..d20b828e 100644 --- a/internal/domain/references/organization/organization.go +++ b/internal/domain/references/organization/organization.go @@ -1,13 +1,15 @@ package organization type ( - ContractPositionCode string - EmployeePositionCode string - InternPosisitionCode string - ItemGroupCode string - InfraGroupCode string - UnitTypeCode string - DoctorFeeTypeCode string + ContractPositionCode string + EmployeePositionCode string + InternPosisitionCode string + ItemGroupCode string + InfraGroupCode string + ProdcedureRoomTypeCode string + UnitTypeCode string + DoctorFeeTypeCode string + ActionBillingCode string ) const ( @@ -24,6 +26,7 @@ const ( EPCLab EmployeePositionCode = "lab" // Laboran EPCPha EmployeePositionCode = "pha" // Farmasi EPCNom EmployeePositionCode = "nom" // Non Medic + EPCScr EmployeePositionCode = "scr" // Screening MPP // EPCPay EmployeePositionCode = "pay" // Pembayaran // EPCHur EmployeePositionCode = "hue" // Sumber Daya Manusia // EPCGea EmployeePositionCode = "gea" // Bagian Umum @@ -42,14 +45,17 @@ const ( ITGCDocFee ItemGroupCode = "doctor-fee" ITGCMedAct ItemGroupCode = "medical-action" - IFGCBuilding InfraGroupCode = "building" // Bangunan - IFGCFloor InfraGroupCode = "floor" // Lantai - IFGCRoom InfraGroupCode = "room" // Ruang - IFGCChamber InfraGroupCode = "chamber" // Kamar - IFGCBed InfraGroupCode = "bed" // Ranjang - IFGCWarehouse InfraGroupCode = "warehouse" // Gudang/Depo - IFGCCounter InfraGroupCode = "counter" // Counter - IFGCPubScreen InfraGroupCode = "public-screen" // Public Screen + IFGCBuilding InfraGroupCode = "building" // Bangunan + IFGCFloor InfraGroupCode = "floor" // Lantai + IFGCProcedureRoom InfraGroupCode = "procedure-room" // Ruang Tindakan + IFGCChamber InfraGroupCode = "chamber" // Kamar + IFGCBed InfraGroupCode = "bed" // Ranjang + IFGCWarehouse InfraGroupCode = "warehouse" // Gudang/Depo + IFGCCounter InfraGroupCode = "counter" // Counter + IFGCPubScreen InfraGroupCode = "public-screen" // Public Screen + + PRTCProcedure ProdcedureRoomTypeCode = "procedure" // Ringan + PRTCOperating ProdcedureRoomTypeCode = "operating" // Dikamarkan UTCReg UnitTypeCode = "reg" // Registrasi UTCExa UnitTypeCode = "exa" // Pemeriksaan @@ -62,4 +68,8 @@ const ( DFTCInp DoctorFeeTypeCode = "inpatient" // Rawat Inap DFTCEme DoctorFeeTypeCode = "emergency" // Darurat DFTCReh DoctorFeeTypeCode = "medic-rehab" // Rehab Medik + + ABCGeneral ActionBillingCode = "general" + ABCRegional ActionBillingCode = "regional" + ABCLocal ActionBillingCode = "local" ) diff --git a/internal/domain/simgos-entities/t-diagnosadanterapi/entity.go b/internal/domain/simgos-entities/t-diagnosadanterapi/entity.go new file mode 100644 index 00000000..2e77d362 --- /dev/null +++ b/internal/domain/simgos-entities/t-diagnosadanterapi/entity.go @@ -0,0 +1,51 @@ +package t_diagnosadanterapi + +import "time" + +type TDiagnosaDanTerapi struct { + Idxterapi uint `json:"idxterapi" gorm:"column:idxterapi;primaryKey"` + Idxdaftar uint `json:"idxdaftar" gorm:"column:idxdaftar"` + Nomr string `json:"nomr" gorm:"column:nomr"` + Tanggal time.Time `json:"tanggal" gorm:"column:tanggal"` + TekananDarah string `json:"tekanan_darah" gorm:"column:tekanan_darah"` + GolonganDarah string `json:"golongan_darah" gorm:"column:golongan_darah"` + TinggiBadan float64 `json:"tinggi_badan" gorm:"column:tinggi_badan"` + BeratBadan float64 `json:"berat_badan" gorm:"column:berat_badan"` + Diagnosa string `json:"diagnosa" gorm:"column:diagnosa"` + Komplikasi string `json:"komplikasi" gorm:"column:komplikasi"` + Terapi string `json:"terapi" gorm:"column:terapi"` + Anamnesa string `json:"anamnesa" gorm:"column:anamnesa"` + Kdpoly uint `json:"kdpoly" gorm:"column:kdpoly"` + Kddokter uint `json:"kddokter" gorm:"column:kddokter"` + Kdtujuanrujuk uint `json:"kdtujuanrujuk" gorm:"column:kdtujuanrujuk"` + Nip string `json:"nip" gorm:"column:nip"` + IcdCode string `json:"icd_code" gorm:"column:icd_code"` + KunjunganBl uint `json:"kunjungan_bl" gorm:"column:kunjungan_bl"` + KasusBl uint `json:"kasus_bl" gorm:"column:kasus_bl"` + Icdcm string `json:"icdcm" gorm:"column:icdcm"` + Icd9 string `json:"icd_9" gorm:"column:icd_9"` + Klb uint `json:"klb" gorm:"column:klb"` + Bedah uint `json:"bedah" gorm:"column:bedah"` + Jenis uint `json:"jenis" gorm:"column:jenis"` + Perawat string `json:"perawat" gorm:"column:perawat"` + Status string `json:"status" gorm:"column:status"` + PemeriksaanFisik string `json:"pemeriksaan_fisik" gorm:"column:pemeriksaan_fisik"` + RiwayatPasien string `json:"riwayat_pasien" gorm:"column:riwayat_pasien"` + TindakanMedis string `json:"tindakan_medis" gorm:"column:tindakan_medis"` + Rajal uint `json:"rajal" gorm:"column:rajal"` + UserBatal string `json:"user_batal" gorm:"column:user_batal"` + TglBatal *time.Time `json:"tgl_batal" gorm:"column:tgl_batal"` + SudahVaksin string `json:"sudah_vaksin" gorm:"column:sudah_vaksin"` + CreatedAt time.Time `json:"created_at" gorm:"column:created_at"` + DenyutJantung string `json:"denyut_jantung" gorm:"column:denyut_jantung"` + Pernapasan string `json:"pernapasan" gorm:"column:pernapasan"` + Suhu string `json:"suhu" gorm:"column:suhu"` + Sp02 string `json:"sp02" gorm:"column:sp02"` + TujuanPerawatan string `json:"tujuan_perawatan" gorm:"column:tujuan_perawatan"` + TargetCapaian string `json:"target_capaian" gorm:"column:target_capaian"` +} + +// TableName overrides the table name used by GORM +func (TDiagnosaDanTerapi) TableName() string { + return "t_diagnosadanterapi" +} diff --git a/internal/domain/simgos-entities/t-icd-cm/entity.go b/internal/domain/simgos-entities/t-icd-cm/entity.go new file mode 100644 index 00000000..198b29ea --- /dev/null +++ b/internal/domain/simgos-entities/t-icd-cm/entity.go @@ -0,0 +1,23 @@ +package t_icd_cm + +import "time" + +type TIcdCm struct { + Idx uint `json:"idx" gorm:"column:idx;primaryKey"` + Nomr string `json:"nomr" gorm:"column:nomr"` + Idxdaftar uint `json:"idxdaftar" gorm:"column:idxdaftar"` + Kddokter uint `json:"kddokter" gorm:"column:kddokter"` + Icd string `json:"icd" gorm:"column:icd"` + IcdVerified string `json:"icd_verified" gorm:"column:icd_verified"` + StatusRajal uint16 `json:"status_rajal" gorm:"column:status_rajal"` + Tanggal time.Time `json:"tanggal" gorm:"column:tanggal"` + StatusVerif uint16 `json:"status_verif" gorm:"column:status_verif"` + IcdVerifiedOrder uint16 `json:"icd_verified_order" gorm:"column:icd_verified_order"` + IcdVerifBy string `json:"icd_verif_by" gorm:"column:icd_verif_by"` + IcdVerifDate *time.Time `json:"icd_verif_date" gorm:"column:icd_verif_date"` + IcdActive uint16 `json:"icd_active" gorm:"column:icd_active"` +} + +func (TIcdCm) TableName() string { + return "t_icd_cm" +} diff --git a/internal/domain/simgos-entities/t-icd/entity.go b/internal/domain/simgos-entities/t-icd/entity.go new file mode 100644 index 00000000..f2191ecc --- /dev/null +++ b/internal/domain/simgos-entities/t-icd/entity.go @@ -0,0 +1,24 @@ +package t_icd + +import "time" + +type TIcd struct { + Idx uint `json:"idx" gorm:"column:idx;primaryKey"` + Nomr string `json:"nomr" gorm:"column:nomr"` + Idxdaftar uint `json:"idxdaftar" gorm:"column:idxdaftar"` + Kddokter uint `json:"kddokter" gorm:"column:kddokter"` + Icd string `json:"icd" gorm:"column:icd"` + IcdVerified string `json:"icd_verified" gorm:"column:icd_verified"` + StatusRajal uint16 `json:"status_rajal" gorm:"column:status_rajal"` + Tanggal time.Time `json:"tanggal" gorm:"column:tanggal"` + StatusVerif uint16 `json:"status_verif" gorm:"column:status_verif"` + IcdVerifiedOrder uint16 `json:"icd_verified_order" gorm:"column:icd_verified_order"` + IcdVerifBy string `json:"icd_verif_by" gorm:"column:icd_verif_by"` + IcdVerifDate *time.Time `json:"icd_verif_date" gorm:"column:icd_verif_date"` + IcdActive uint16 `json:"icd_active" gorm:"column:icd_active"` + StSebabMati uint16 `json:"st_sebab_mati" gorm:"column:st_sebab_mati"` +} + +func (TIcd) TableName() string { + return "t_icd" +} diff --git a/internal/domain/simgos-entities/t-rekammedik/entity.go b/internal/domain/simgos-entities/t-rekammedik/entity.go new file mode 100644 index 00000000..5df0ec83 --- /dev/null +++ b/internal/domain/simgos-entities/t-rekammedik/entity.go @@ -0,0 +1,22 @@ +package t_rekammedik + +import "time" + +type TRekammedik struct { + TglKirim *time.Time `json:"tgl_kirim" gorm:"column:tgl_kirim"` + TglTerima *time.Time `json:"tgl_terima" gorm:"column:tgl_terima"` + Idxdaftar int `json:"idxdaftar" gorm:"column:idxdaftar"` + Kdpoly int `json:"kdpoly" gorm:"column:kdpoly"` + Pengirim string `json:"pengirim" gorm:"column:pengirim"` + Penerima string `json:"penerima" gorm:"column:penerima"` + Statusrm int `json:"statusrm" gorm:"column:statusrm"` + PenerimaPoly string `json:"penerima_poly" gorm:"column:penerima_poly"` + JamKirimRm string `json:"jam_kirim_rm" gorm:"column:jam_kirim_rm"` + JamTerimaRm string `json:"jam_terima_rm" gorm:"column:jam_terima_rm"` + PjBerkasRm string `json:"pj_berkas_rm" gorm:"column:pj_berkas_rm"` + StatusFisikBerkas string `json:"status_fisik_berkas" gorm:"column:status_fisik_berkas"` +} + +func (TRekammedik) TableName() string { + return "t_rekammedik" +} diff --git a/internal/domain/sync-entities/soapi/entity.go b/internal/domain/sync-entities/soapi/entity.go new file mode 100644 index 00000000..0a1315c7 --- /dev/null +++ b/internal/domain/sync-entities/soapi/entity.go @@ -0,0 +1,29 @@ +package Soapi + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + erc "simrs-vx/internal/domain/references/common" + "time" +) + +type SoapiLink struct { + ecore.Main + Simx_Id uint `json:"simx_id" gorm:"unique"` + Simgos_Id uint `json:"simgos_id" gorm:"unique"` +} + +type SoapiSimxLog struct { + ecore.Main + Value *string `json:"value"` + Date *time.Time `json:"date"` + Status erc.ProcessStatusCode `json:"status"` + ErrMessage *string `json:"errMessage"` +} + +type SoapiSimgosLog 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-consumer-cfg/tycovar.go b/internal/infra/sync-consumer-cfg/tycovar.go index f60cc588..d2146c2b 100644 --- a/internal/infra/sync-consumer-cfg/tycovar.go +++ b/internal/infra/sync-consumer-cfg/tycovar.go @@ -1,12 +1,11 @@ package synccfg -var O SyncUrlCfg = SyncUrlCfg{} // new +var O SyncConsumerUrlCfg = SyncConsumerUrlCfg{} // old -type SyncUrlCfg struct { +type SyncConsumerUrlCfg struct { Prefix string `yaml:"prefix"` TargetHost string `yaml:"targetHost"` Enable bool `yaml:"enable"` - OldSource string `yaml:"oldSource"` - NewSource string `yaml:"newSource"` + Source string `yaml:"source"` SecretKey string `yaml:"secretKey"` } diff --git a/internal/interface/bpjs-handler/bpjs-handler.go b/internal/interface/bpjs-handler/bpjs-handler.go index 175bb667..4f000664 100644 --- a/internal/interface/bpjs-handler/bpjs-handler.go +++ b/internal/interface/bpjs-handler/bpjs-handler.go @@ -4,12 +4,12 @@ import ( "net/http" /******************** main / transaction ********************/ - member "simrs-vx/internal/interface/bpjs-handler/member" - monitoring "simrs-vx/internal/interface/bpjs-handler/monitoring" - reference "simrs-vx/internal/interface/bpjs-handler/reference" - vclaimsep "simrs-vx/internal/interface/bpjs-handler/vclaim-sep" - vclaimsephist "simrs-vx/internal/interface/bpjs-handler/vclaim-sep-hist" - vclaimsepprint "simrs-vx/internal/interface/bpjs-handler/vclaim-sep-print" + member "simrs-vx/internal/interface/main-handler/member" + monitoring "simrs-vx/internal/interface/main-handler/monitoring" + reference "simrs-vx/internal/interface/main-handler/reference" + vclaimsep "simrs-vx/internal/interface/main-handler/vclaim-sep" + vclaimsephist "simrs-vx/internal/interface/main-handler/vclaim-sep-hist" + vclaimsepprint "simrs-vx/internal/interface/main-handler/vclaim-sep-print" /******************** actor ********************/ @@ -49,7 +49,7 @@ func SetRoutes() http.Handler { hk.GroupRoutes("/v1/vclaim-sep", r, hk.MapHandlerFunc{ "POST /": vclaimsep.O.Create, - "PATCH /{id}": vclaimsep.O.Update, + "PATCH /{id}": vclaimsep.O.GetDetail, "DELETE /{id}": vclaimsep.O.Delete, }) diff --git a/internal/interface/main-handler/action-report/handler.go b/internal/interface/main-handler/action-report/handler.go new file mode 100644 index 00000000..0fdd1851 --- /dev/null +++ b/internal/interface/main-handler/action-report/handler.go @@ -0,0 +1,80 @@ +package soapi + +import ( + "net/http" + + rw "github.com/karincake/risoles" + sf "github.com/karincake/semprit" + + // ua "github.com/karincake/tumpeng/auth/svc" + + e "simrs-vx/internal/domain/main-entities/action-report" + u "simrs-vx/internal/use-case/main-use-case/action-report" + + pa "simrs-vx/internal/lib/auth" + + d "github.com/karincake/dodol" +) + +type myBase struct{} + +var O myBase + +func (obj myBase) Create(w http.ResponseWriter, r *http.Request) { + authInfo, err := pa.GetAuthInfo(r) + if err != nil { + rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil) + } + dto := e.CreateDto{} + if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { + return + } + dto.AuthInfo = *authInfo + res, err := u.Create(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) GetList(w http.ResponseWriter, r *http.Request) { + dto := e.ReadListDto{} + sf.UrlQueryParam(&dto, *r.URL) + res, err := u.ReadList(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) { + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id <= 0 { + return + } + dto := e.ReadDetailDto{} + dto.Id = uint16(id) + res, err := u.ReadDetail(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) Update(w http.ResponseWriter, r *http.Request) { + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id <= 0 { + return + } + + dto := e.UpdateDto{} + if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { + return + } + dto.Id = uint16(id) + res, err := u.Update(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) { + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id <= 0 { + return + } + + dto := e.DeleteDto{} + dto.Id = uint16(id) + res, err := u.Delete(dto) + rw.DataResponse(w, res, err) +} diff --git a/internal/interface/main-handler/antibiotic-src/handler.go b/internal/interface/main-handler/antibiotic-src/handler.go index 506472f8..5966e876 100644 --- a/internal/interface/main-handler/antibiotic-src/handler.go +++ b/internal/interface/main-handler/antibiotic-src/handler.go @@ -68,4 +68,4 @@ func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) { dto.Id = uint16(id) res, err := u.Delete(dto) rw.DataResponse(w, res, err) -} \ No newline at end of file +} diff --git a/internal/interface/main-handler/control-plan/handler.go b/internal/interface/main-handler/control-plan/handler.go new file mode 100644 index 00000000..382af58d --- /dev/null +++ b/internal/interface/main-handler/control-plan/handler.go @@ -0,0 +1,32 @@ +package controlplan + +import ( + "net/http" + + e "simrs-vx/internal/domain/bpjs-entities/control-plan" + u "simrs-vx/internal/use-case/bpjs-use-case/control-plan" + + d "github.com/karincake/dodol" + rw "github.com/karincake/risoles" +) + +func GetList(w http.ResponseWriter, r *http.Request) { + dto := e.ReadListDto{} + pValue1 := rw.ValidateString(w, "controlType", r.PathValue("controlType")) + if pValue1 == "" { + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "controlType is required"}, nil) + } + pValue2 := rw.ValidateString(w, "polyCode", r.PathValue("polyCode")) + if pValue2 == "" { + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "polyCode is required"}, nil) + } + pValue3 := rw.ValidateString(w, "date", r.PathValue("date")) + if pValue3 == "" { + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "date is required"}, nil) + } + dto.PathValue1 = pValue1 + dto.PathValue2 = pValue2 + dto.PathValue3 = pValue3 + res, err := u.ReadList(dto) + rw.DataResponse(w, res, err) +} diff --git a/internal/interface/main-handler/doctor/handler.go b/internal/interface/main-handler/doctor/handler.go index f62495d6..b700103a 100644 --- a/internal/interface/main-handler/doctor/handler.go +++ b/internal/interface/main-handler/doctor/handler.go @@ -38,6 +38,7 @@ func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) { return } dto := e.ReadDetailDto{} + sf.UrlQueryParam(&dto, *r.URL) dto.Code = &code res, err := u.ReadDetail(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 a763f40b..1080705e 100644 --- a/internal/interface/main-handler/main-handler.go +++ b/internal/interface/main-handler/main-handler.go @@ -4,6 +4,7 @@ import ( "net/http" /******************** main / transaction ********************/ + actionreport "simrs-vx/internal/interface/main-handler/action-report" adime "simrs-vx/internal/interface/main-handler/adime" admemployeehist "simrs-vx/internal/interface/main-handler/adm-employee-hist" ambulancetransportrequest "simrs-vx/internal/interface/main-handler/ambulance-transport-req" @@ -34,6 +35,7 @@ import ( prescription "simrs-vx/internal/interface/main-handler/prescription" prescriptionitem "simrs-vx/internal/interface/main-handler/prescription-item" responsibledoctorhist "simrs-vx/internal/interface/main-handler/responsible-doctor-hist" + resume "simrs-vx/internal/interface/main-handler/resume" sbar "simrs-vx/internal/interface/main-handler/sbar" soapi "simrs-vx/internal/interface/main-handler/soapi" uploadfile "simrs-vx/internal/interface/main-handler/upload-file" @@ -91,6 +93,8 @@ import ( itemprice "simrs-vx/internal/interface/main-handler/item-price" language "simrs-vx/internal/interface/main-handler/language" material "simrs-vx/internal/interface/main-handler/material" + materialpackage "simrs-vx/internal/interface/main-handler/material-package" + materialpackageitem "simrs-vx/internal/interface/main-handler/material-package-item" mcusrc "simrs-vx/internal/interface/main-handler/mcu-src" mcusrccategory "simrs-vx/internal/interface/main-handler/mcu-src-category" mcusubsrc "simrs-vx/internal/interface/main-handler/mcu-sub-src" @@ -119,9 +123,19 @@ import ( regency "simrs-vx/internal/interface/main-handler/regency" village "simrs-vx/internal/interface/main-handler/village" - ///// Internal + /******************** Internal ********************/ validation "simrs-vx/internal/interface/main-handler/helper/validation" "simrs-vx/internal/interface/main-handler/home" + + /******************** BPJS ********************/ + controlplan "simrs-vx/internal/interface/main-handler/control-plan" + member "simrs-vx/internal/interface/main-handler/member" + monitoring "simrs-vx/internal/interface/main-handler/monitoring" + reference "simrs-vx/internal/interface/main-handler/reference" + referral "simrs-vx/internal/interface/main-handler/referral" + vclaimsep "simrs-vx/internal/interface/main-handler/vclaim-sep" + vclaimsephist "simrs-vx/internal/interface/main-handler/vclaim-sep-hist" + vclaimsepprint "simrs-vx/internal/interface/main-handler/vclaim-sep-print" ) // One place route to relatively easier to manage, ESPECIALLY in tracking @@ -137,6 +151,7 @@ func SetRoutes() http.Handler { a.RegisterExtCall(validation.RegisterValidation) a.RegisterExtCall(sync.SetConfig) a.RegisterExtCall(docscfg.ParseCfg) + a.RegisterExtCall(ibpjs.SetConfig) r := http.NewServeMux() @@ -159,6 +174,7 @@ func SetRoutes() http.Handler { hc.RegCrud(r, "/v1/sbar", auth.GuardMW, sbar.O) hc.RegCrud(r, "/v1/prescription-item", prescriptionitem.O) hc.RegCrud(r, "/v1/device-order-item", deviceorderitem.O) + hc.RegCrud(r, "/v1/action-report", auth.GuardMW, actionreport.O) hc.RegCrud(r, "/v1/material-order-item", materialorderitem.O) hk.GroupRoutes("/v1/encounter", r, auth.GuardMW, hk.MapHandlerFunc{ @@ -289,6 +305,15 @@ func SetRoutes() http.Handler { hc.RegCrud(r, "/v1/encounter-document", encounterdocument.O) hc.RegCrud(r, "/v1/general-consent", generalconsent.O) r.HandleFunc("POST /v1/generate-file", generatefile.Generate) + hk.GroupRoutes("/v1/resume", r, auth.GuardMW, hk.MapHandlerFunc{ + "POST /": resume.Create, + "GET /": resume.GetList, + "GET /{id}": resume.GetDetail, + "PATCH /{id}": resume.Update, + "DELETE /{id}": resume.Delete, + "PATCH /{id}/verify": resume.Verify, + "PATCH /{id}/validate": resume.Validate, + }) /******************** actor ********************/ hc.RegCrud(r, "/v1/person", person.O) @@ -347,6 +372,8 @@ func SetRoutes() http.Handler { hc.RegCrudByCode(r, "/v1/medicine", medicine.O) hc.RegCrudByCode(r, "/v1/device", device.O) hc.RegCrudByCode(r, "/v1/material", material.O) + hc.RegCrudByCode(r, "/v1/material-package", materialpackage.O) + hc.RegCrud(r, "/v1/material-package-item", materialpackageitem.O) hc.RegCrud(r, "/v1/doctor-fee", doctorfee.O) hc.RegCrudByCode(r, "/v1/medical-action-src", medicalactionsrc.O) hc.RegCrud(r, "/v1/medical-action-src-item", medicalactionsrcitem.O) @@ -362,6 +389,51 @@ func SetRoutes() http.Handler { hc.RegCrudByCode(r, "/v1/province", province.O) hc.RegCrudByCode(r, "/v1/postal-region", postalregion.O) + /******************** BPJS ********************/ + hk.GroupRoutes("/v1/vclaim-sep", r, hk.MapHandlerFunc{ + "POST /": vclaimsep.O.Create, + "GET /{number}": vclaimsep.O.GetDetail, + "DELETE /{number}": vclaimsep.O.Delete, + }) + + hk.GroupRoutes("/v1/vclaim-sep-hist", r, hk.MapHandlerFunc{ + "GET /": vclaimsephist.O.GetList, + }) + + hk.GroupRoutes("/v1/vclaim-sep-print", r, hk.MapHandlerFunc{ + "POST /": vclaimsepprint.O.Create, + }) + + hk.GroupRoutes("/v1/reference", r, hk.MapHandlerFunc{ + "GET /province": reference.GetListProvince, + "GET /regency/{provinceCode}": reference.GetListCities, + "GET /district/{regencyCode}": reference.GetListDistrict, + "GET /diagnose/{keyword}": reference.GetListDiagnose, + "GET /diagnose-prb": reference.GetListDiagnosePrb, + "GET /medicine-prb/{keyword}": reference.GetListMedicinePrb, + "GET /unit/{unitCode}": reference.GetListUnit, + "GET /healthcare/{healthcare}/{healthcareType}": reference.GetListHealthcare, + "GET /responsible-doctor/{serviceType}/{serviceDate}/{specialistCode}": reference.GetListDoctor, + }) + + hk.GroupRoutes("/v1/member", r, hk.MapHandlerFunc{ + "GET /bpjs/{cardNumber}/{sepDate}": member.GetListByBpjsNumber, + "GET /nik/{nik}/{sepDate}": member.GetListByNik, + }) + + hk.GroupRoutes("/v1/monitoring", r, hk.MapHandlerFunc{ + "GET /visit/{date}/{serviceType}": monitoring.GetListVisit, + "GET /hist/{cardNumber}/{startDate}/{endDate}": monitoring.GetListHist, + }) + + hk.GroupRoutes("/v1/control-plan", r, hk.MapHandlerFunc{ + "GET /{controlType}/{polyCode}/{date}": controlplan.GetList, + }) + + hk.GroupRoutes("/v1/referral", r, hk.MapHandlerFunc{ + "GET /{number}": referral.GetList, + }) + ///// return cmw.SetCors(handlerlogger.SetLog(r)) } diff --git a/internal/interface/main-handler/material-package-item/handler.go b/internal/interface/main-handler/material-package-item/handler.go new file mode 100644 index 00000000..11deb6d9 --- /dev/null +++ b/internal/interface/main-handler/material-package-item/handler.go @@ -0,0 +1,71 @@ +package material + +import ( + "net/http" + + rw "github.com/karincake/risoles" + sf "github.com/karincake/semprit" + + // ua "github.com/karincake/tumpeng/auth/svc" + + e "simrs-vx/internal/domain/main-entities/material-package-item" + u "simrs-vx/internal/use-case/main-use-case/material-package-item" +) + +type myBase struct{} + +var O myBase + +func (obj myBase) Create(w http.ResponseWriter, r *http.Request) { + dto := e.CreateDto{} + if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { + return + } + res, err := u.Create(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) GetList(w http.ResponseWriter, r *http.Request) { + dto := e.ReadListDto{} + sf.UrlQueryParam(&dto, *r.URL) + res, err := u.ReadList(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) { + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id == 0 { + return + } + dto := e.ReadDetailDto{} + dto.Id = uint(id) + res, err := u.ReadDetail(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) Update(w http.ResponseWriter, r *http.Request) { + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id == 0 { + return + } + + dto := e.UpdateDto{} + if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { + return + } + dto.Id = uint(id) + res, err := u.Update(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) { + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id == 0 { + return + } + + dto := e.DeleteDto{} + dto.Id = uint(id) + res, err := u.Delete(dto) + rw.DataResponse(w, res, err) +} diff --git a/internal/interface/main-handler/material-package/handler.go b/internal/interface/main-handler/material-package/handler.go new file mode 100644 index 00000000..609d983e --- /dev/null +++ b/internal/interface/main-handler/material-package/handler.go @@ -0,0 +1,71 @@ +package material + +import ( + "net/http" + + rw "github.com/karincake/risoles" + sf "github.com/karincake/semprit" + + // ua "github.com/karincake/tumpeng/auth/svc" + + e "simrs-vx/internal/domain/main-entities/material-package" + u "simrs-vx/internal/use-case/main-use-case/material-package" +) + +type myBase struct{} + +var O myBase + +func (obj myBase) Create(w http.ResponseWriter, r *http.Request) { + dto := e.CreateDto{} + if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { + return + } + res, err := u.Create(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) GetList(w http.ResponseWriter, r *http.Request) { + dto := e.ReadListDto{} + sf.UrlQueryParam(&dto, *r.URL) + res, err := u.ReadList(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) { + code := rw.ValidateString(w, "code", r.PathValue("code")) + if code == "" { + return + } + dto := e.ReadDetailDto{} + dto.Code = &code + res, err := u.ReadDetail(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) Update(w http.ResponseWriter, r *http.Request) { + code := rw.ValidateString(w, "code", r.PathValue("code")) + if code == "" { + return + } + + dto := e.UpdateDto{} + if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { + return + } + dto.Code = code + res, err := u.Update(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) { + code := rw.ValidateString(w, "code", r.PathValue("code")) + if code == "" { + return + } + + dto := e.DeleteDto{} + dto.Code = &code + res, err := u.Delete(dto) + rw.DataResponse(w, res, err) +} diff --git a/internal/interface/bpjs-handler/member/handler.go b/internal/interface/main-handler/member/handler.go similarity index 74% rename from internal/interface/bpjs-handler/member/handler.go rename to internal/interface/main-handler/member/handler.go index 80881ee3..3b4c3ba1 100644 --- a/internal/interface/bpjs-handler/member/handler.go +++ b/internal/interface/main-handler/member/handler.go @@ -14,11 +14,11 @@ func GetListByBpjsNumber(w http.ResponseWriter, r *http.Request) { dto := e.ReadListDto{} pValue1 := rw.ValidateString(w, "cardNumber", r.PathValue("cardNumber")) if pValue1 == "" { - rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "cardNumber is required"}, nil) + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "cardNumber is required"}, nil) } pValue2 := rw.ValidateString(w, "sepDate", r.PathValue("sepDate")) if pValue2 == "" { - rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "sepDate is required"}, nil) + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "sepDate is required"}, nil) } dto.ReferenceType = e.RTBpjs dto.PathValue1 = pValue1 @@ -31,11 +31,11 @@ func GetListByNik(w http.ResponseWriter, r *http.Request) { dto := e.ReadListDto{} pValue1 := rw.ValidateString(w, "nik", r.PathValue("nik")) if pValue1 == "" { - rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "nik is required"}, nil) + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "nik is required"}, nil) } pValue2 := rw.ValidateString(w, "sepDate", r.PathValue("sepDate")) if pValue2 == "" { - rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "sepDate is required"}, nil) + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "sepDate is required"}, nil) } dto.ReferenceType = e.RTNik dto.PathValue1 = pValue1 diff --git a/internal/interface/bpjs-handler/monitoring/handler.go b/internal/interface/main-handler/monitoring/handler.go similarity index 73% rename from internal/interface/bpjs-handler/monitoring/handler.go rename to internal/interface/main-handler/monitoring/handler.go index cf82a5b9..aa8acdf4 100644 --- a/internal/interface/bpjs-handler/monitoring/handler.go +++ b/internal/interface/main-handler/monitoring/handler.go @@ -14,11 +14,11 @@ func GetListVisit(w http.ResponseWriter, r *http.Request) { dto := e.ReadListDto{} pValue1 := rw.ValidateString(w, "date", r.PathValue("date")) if pValue1 == "" { - rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "date is required"}, nil) + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "date is required"}, nil) } pValue2 := rw.ValidateString(w, "serviceType", r.PathValue("serviceType")) if pValue2 == "" { - rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "serviceType is required"}, nil) + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "serviceType is required"}, nil) } dto.ReferenceType = e.RTVisit dto.PathValue1 = pValue1 @@ -31,15 +31,15 @@ func GetListHist(w http.ResponseWriter, r *http.Request) { dto := e.ReadListDto{} pValue1 := rw.ValidateString(w, "cardNumber", r.PathValue("cardNumber")) if pValue1 == "" { - rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "cardNumber is required"}, nil) + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "cardNumber is required"}, nil) } pValue2 := rw.ValidateString(w, "startDate", r.PathValue("startDate")) if pValue2 == "" { - rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "startDate is required"}, nil) + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "startDate is required"}, nil) } pValue3 := rw.ValidateString(w, "endDate", r.PathValue("endDate")) if pValue3 == "" { - rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "endDate is required"}, nil) + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "endDate is required"}, nil) } dto.ReferenceType = e.RTHist dto.PathValue1 = pValue1 diff --git a/internal/interface/bpjs-handler/reference/handler.go b/internal/interface/main-handler/reference/handler.go similarity index 77% rename from internal/interface/bpjs-handler/reference/handler.go rename to internal/interface/main-handler/reference/handler.go index fb972af1..b9948eb3 100644 --- a/internal/interface/bpjs-handler/reference/handler.go +++ b/internal/interface/main-handler/reference/handler.go @@ -21,7 +21,7 @@ func GetListCities(w http.ResponseWriter, r *http.Request) { dto := e.ReadListDto{} pValue := rw.ValidateString(w, "provinceCode", r.PathValue("provinceCode")) if pValue == "" { - rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "provinceCode is required"}, nil) + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "provinceCode is required"}, nil) } dto.ReferenceType = e.RTCities dto.PathValue1 = pValue @@ -33,7 +33,7 @@ func GetListDistrict(w http.ResponseWriter, r *http.Request) { dto := e.ReadListDto{} pValue := rw.ValidateString(w, "regencyCode", r.PathValue("regencyCode")) if pValue == "" { - rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "regencyCode is required"}, nil) + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "regencyCode is required"}, nil) } dto.ReferenceType = e.RTDistrict dto.PathValue1 = pValue @@ -45,7 +45,7 @@ func GetListDiagnose(w http.ResponseWriter, r *http.Request) { dto := e.ReadListDto{} pValue := rw.ValidateString(w, "keyword", r.PathValue("keyword")) if pValue == "" { - rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "keyword is required"}, nil) + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "keyword is required"}, nil) } dto.ReferenceType = e.RTDiagnose dto.PathValue1 = pValue @@ -64,7 +64,7 @@ func GetListMedicinePrb(w http.ResponseWriter, r *http.Request) { dto := e.ReadListDto{} pValue := rw.ValidateString(w, "keyword", r.PathValue("keyword")) if pValue == "" { - rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "keyword is required"}, nil) + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "keyword is required"}, nil) } dto.ReferenceType = e.RTMedicinePrb dto.PathValue1 = pValue @@ -76,7 +76,7 @@ func GetListUnit(w http.ResponseWriter, r *http.Request) { dto := e.ReadListDto{} pValue := rw.ValidateString(w, "unitCode", r.PathValue("unitCode")) if pValue == "" { - rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "unitCode is required"}, nil) + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "unitCode is required"}, nil) } dto.ReferenceType = e.RTUnit dto.PathValue1 = pValue @@ -88,11 +88,11 @@ func GetListHealthcare(w http.ResponseWriter, r *http.Request) { dto := e.ReadListDto{} pValue1 := rw.ValidateString(w, "healthcare", r.PathValue("healthcare")) if pValue1 == "" { - rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "healthcare is required"}, nil) + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "healthcare is required"}, nil) } pValue2 := rw.ValidateString(w, "healthcareType", r.PathValue("healthcareType")) if pValue2 == "" { - rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "healthcareType is required"}, nil) + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "healthcareType is required"}, nil) } dto.ReferenceType = e.RTHealthcare dto.PathValue1 = pValue1 @@ -105,15 +105,15 @@ func GetListDoctor(w http.ResponseWriter, r *http.Request) { dto := e.ReadListDto{} pValue1 := rw.ValidateString(w, "serviceType", r.PathValue("serviceType")) if pValue1 == "" { - rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "serviceType is required"}, nil) + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "serviceType is required"}, nil) } pValue2 := rw.ValidateString(w, "serviceDate", r.PathValue("serviceDate")) if pValue2 == "" { - rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "serviceDate is required"}, nil) + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "serviceDate is required"}, nil) } pValue3 := rw.ValidateString(w, "specialistCode", r.PathValue("specialistCode")) if pValue3 == "" { - rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "specialistCode is required"}, nil) + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "specialistCode is required"}, nil) } dto.PathValue1 = pValue1 dto.PathValue2 = pValue2 diff --git a/internal/interface/main-handler/referral/handler.go b/internal/interface/main-handler/referral/handler.go new file mode 100644 index 00000000..94b66a78 --- /dev/null +++ b/internal/interface/main-handler/referral/handler.go @@ -0,0 +1,22 @@ +package referral + +import ( + "net/http" + + e "simrs-vx/internal/domain/bpjs-entities/referral" + u "simrs-vx/internal/use-case/bpjs-use-case/referral" + + d "github.com/karincake/dodol" + rw "github.com/karincake/risoles" +) + +func GetList(w http.ResponseWriter, r *http.Request) { + dto := e.ReadDetailDto{} + number := rw.ValidateString(w, "number", r.PathValue("number")) + if number == "" { + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "number is required"}, nil) + } + dto.Number = &number + res, err := u.ReadDetail(dto) + rw.DataResponse(w, res, err) +} diff --git a/internal/interface/main-handler/resume/handler.go b/internal/interface/main-handler/resume/handler.go new file mode 100644 index 00000000..24ac0b08 --- /dev/null +++ b/internal/interface/main-handler/resume/handler.go @@ -0,0 +1,125 @@ +package resume + +import ( + "net/http" + + d "github.com/karincake/dodol" + rw "github.com/karincake/risoles" + sf "github.com/karincake/semprit" + + // ua "github.com/karincake/tumpeng/auth/svc" + + e "simrs-vx/internal/domain/main-entities/resume" + u "simrs-vx/internal/use-case/main-use-case/resume" + + erc "simrs-vx/internal/domain/references/common" + + pa "simrs-vx/internal/lib/auth" +) + +func Create(w http.ResponseWriter, r *http.Request) { + authInfo, err := pa.GetAuthInfo(r) + if err != nil { + rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil) + } + dto := e.CreateDto{} + if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { + return + } + + dto.AuthInfo = *authInfo + res, err := u.Create(dto) + rw.DataResponse(w, res, err) +} + +func GetList(w http.ResponseWriter, r *http.Request) { + dto := e.ReadListDto{} + sf.UrlQueryParam(&dto, *r.URL) + res, err := u.ReadList(dto) + rw.DataResponse(w, res, err) +} + +func GetDetail(w http.ResponseWriter, r *http.Request) { + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id <= 0 { + return + } + dto := e.ReadDetailDto{} + sf.UrlQueryParam(&dto, *r.URL) + dto.Id = uint(id) + res, err := u.ReadDetail(dto) + rw.DataResponse(w, res, err) +} + +func Update(w http.ResponseWriter, r *http.Request) { + authInfo, err := pa.GetAuthInfo(r) + if err != nil { + rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil) + } + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id <= 0 { + return + } + + dto := e.UpdateDto{} + if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { + return + } + dto.Id = uint(id) + dto.AuthInfo = *authInfo + res, err := u.Update(dto) + rw.DataResponse(w, res, err) +} + +func Delete(w http.ResponseWriter, r *http.Request) { + authInfo, err := pa.GetAuthInfo(r) + if err != nil { + rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil) + } + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id <= 0 { + return + } + + dto := e.DeleteDto{} + dto.Id = uint(id) + dto.AuthInfo = *authInfo + res, err := u.Delete(dto) + rw.DataResponse(w, res, err) +} + +func Verify(w http.ResponseWriter, r *http.Request) { + authInfo, err := pa.GetAuthInfo(r) + if err != nil { + rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil) + } + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id <= 0 { + return + } + + dto := e.UpdateDto{} + dto.Id = uint(id) + dto.Status_Code = erc.DVCVerified + dto.AuthInfo = *authInfo + res, err := u.UpdateStatusCode(dto) + rw.DataResponse(w, res, err) +} + +func Validate(w http.ResponseWriter, r *http.Request) { + authInfo, err := pa.GetAuthInfo(r) + if err != nil { + rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil) + } + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id <= 0 { + return + } + + dto := e.UpdateDto{} + dto.Id = uint(id) + dto.Status_Code = erc.DVCValidated + dto.AuthInfo = *authInfo + res, err := u.UpdateStatusCode(dto) + rw.DataResponse(w, res, err) +} diff --git a/internal/interface/bpjs-handler/vclaim-sep-hist/handler.go b/internal/interface/main-handler/vclaim-sep-hist/handler.go similarity index 100% rename from internal/interface/bpjs-handler/vclaim-sep-hist/handler.go rename to internal/interface/main-handler/vclaim-sep-hist/handler.go diff --git a/internal/interface/bpjs-handler/vclaim-sep-print/handler.go b/internal/interface/main-handler/vclaim-sep-print/handler.go similarity index 100% rename from internal/interface/bpjs-handler/vclaim-sep-print/handler.go rename to internal/interface/main-handler/vclaim-sep-print/handler.go diff --git a/internal/interface/bpjs-handler/vclaim-sep/handler.go b/internal/interface/main-handler/vclaim-sep/handler.go similarity index 60% rename from internal/interface/bpjs-handler/vclaim-sep/handler.go rename to internal/interface/main-handler/vclaim-sep/handler.go index d40c76e9..1529e2d8 100644 --- a/internal/interface/bpjs-handler/vclaim-sep/handler.go +++ b/internal/interface/main-handler/vclaim-sep/handler.go @@ -1,7 +1,6 @@ package vclaimsep import ( - "io" "net/http" rw "github.com/karincake/risoles" @@ -16,14 +15,9 @@ var O myBase func (obj myBase) Create(w http.ResponseWriter, r *http.Request) { dto := e.CreateDto{} - body, err := io.ReadAll(r.Body) - if err != nil { - http.Error(w, "failed to read body", http.StatusBadRequest) + if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { return } - defer r.Body.Close() - - dto.RequestPayload = body res, err := u.Create(dto) rw.DataResponse(w, res, err) } @@ -35,39 +29,39 @@ func (obj myBase) Create(w http.ResponseWriter, r *http.Request) { // rw.DataResponse(w, res, err) // } -// func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) { -// id := rw.ValidateInt(w, "id", r.PathValue("id")) -// if id <= 0 { +func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) { + number := rw.ValidateString(w, "number", r.PathValue("number")) + if number <= "" { + return + } + dto := e.ReadDetailDto{} + dto.Number = &number + res, err := u.ReadDetail(dto) + rw.DataResponse(w, res, err) +} + +// func (obj myBase) Update(w http.ResponseWriter, r *http.Request) { +// number := rw.ValidateString(w, "number", r.PathValue("number")) +// if number != "" { // return // } -// dto := e.ReadDetailDto{} -// dto.Id = uint(id) -// res, err := u.ReadDetail(dto) + +// dto := e.UpdateDto{} +// if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { +// return +// } +// dto.Number = &number +// res, err := u.Update(dto) // rw.DataResponse(w, res, err) // } -func (obj myBase) Update(w http.ResponseWriter, r *http.Request) { - number := rw.ValidateString(w, "number", r.PathValue("number")) - if number != "" { - return - } - - dto := e.UpdateDto{} - if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { - return - } - dto.Number = &number - res, err := u.Update(dto) - rw.DataResponse(w, res, err) -} - func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) { - number := rw.ValidateString(w, "number", r.PathValue("number")) - if number != "" { + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id <= 0 { return } dto := e.DeleteDto{} - dto.Number = &number + dto.Id = uint(id) res, err := u.Delete(dto) rw.DataResponse(w, res, err) } diff --git a/internal/interface/migration/main-entities.go b/internal/interface/migration/main-entities.go index 0b4a62fd..34530d78 100644 --- a/internal/interface/migration/main-entities.go +++ b/internal/interface/migration/main-entities.go @@ -1,6 +1,7 @@ package migration import ( + actionreport "simrs-vx/internal/domain/main-entities/action-report" adime "simrs-vx/internal/domain/main-entities/adime" admemployeehist "simrs-vx/internal/domain/main-entities/adm-employee-hist" ambulancetransportreq "simrs-vx/internal/domain/main-entities/ambulance-transport-req" @@ -18,6 +19,8 @@ import ( device "simrs-vx/internal/domain/main-entities/device" deviceorder "simrs-vx/internal/domain/main-entities/device-order" deviceorderitem "simrs-vx/internal/domain/main-entities/device-order-item" + devicepackage "simrs-vx/internal/domain/main-entities/device-package" + devicepackageitem "simrs-vx/internal/domain/main-entities/device-package-item" diagnosesrc "simrs-vx/internal/domain/main-entities/diagnose-src" district "simrs-vx/internal/domain/main-entities/district" division "simrs-vx/internal/domain/main-entities/division" @@ -45,6 +48,8 @@ import ( material "simrs-vx/internal/domain/main-entities/material" materialorder "simrs-vx/internal/domain/main-entities/material-order" materialorderitem "simrs-vx/internal/domain/main-entities/material-order-item" + materialpackage "simrs-vx/internal/domain/main-entities/material-package" + materialpackageitem "simrs-vx/internal/domain/main-entities/material-package-item" mcuorder "simrs-vx/internal/domain/main-entities/mcu-order" mcuorderitem "simrs-vx/internal/domain/main-entities/mcu-order-item" mcuordersubitem "simrs-vx/internal/domain/main-entities/mcu-order-sub-item" @@ -77,14 +82,17 @@ import ( practiceschedule "simrs-vx/internal/domain/main-entities/practice-schedule" prescription "simrs-vx/internal/domain/main-entities/prescription" prescriptionitem "simrs-vx/internal/domain/main-entities/prescription-item" + procedureroom "simrs-vx/internal/domain/main-entities/procedure-room" + procedureroomorder "simrs-vx/internal/domain/main-entities/procedure-room-order" + procedureroomorderitem "simrs-vx/internal/domain/main-entities/procedure-room-order-item" proceduresrc "simrs-vx/internal/domain/main-entities/procedure-src" province "simrs-vx/internal/domain/main-entities/province" regency "simrs-vx/internal/domain/main-entities/regency" rehab "simrs-vx/internal/domain/main-entities/rehab" responsibledoctorhist "simrs-vx/internal/domain/main-entities/responsible-doctor-hist" resume "simrs-vx/internal/domain/main-entities/resume" - room "simrs-vx/internal/domain/main-entities/room" sbar "simrs-vx/internal/domain/main-entities/sbar" + screening "simrs-vx/internal/domain/main-entities/screening" soapi "simrs-vx/internal/domain/main-entities/soapi" specialist "simrs-vx/internal/domain/main-entities/specialist" specialistintern "simrs-vx/internal/domain/main-entities/specialist-intern" @@ -142,6 +150,7 @@ func getMainEntities() []any { &item.Item{}, &itemprice.ItemPrice{}, &infra.Infra{}, + &procedureroom.ProcedureRoom{}, &medicinegroup.MedicineGroup{}, &medicinemethod.MedicineMethod{}, &mcusrccategory.McuSrcCategory{}, @@ -161,13 +170,17 @@ func getMainEntities() []any { &personrelative.PersonRelative{}, &patient.Patient{}, &appointment.Appointment{}, + &devicepackage.DevicePackage{}, + &devicepackageitem.DevicePackageItem{}, + &materialpackage.MaterialPackage{}, + &materialpackageitem.MaterialPackageItem{}, + &vclaimsep.VclaimSep{}, &encounter.Encounter{}, &laborant.Laborant{}, &specialist.Specialist{}, &subspecialist.Subspecialist{}, &specialistintern.SpecialistIntern{}, - &room.Room{}, &soapi.Soapi{}, &sbar.Sbar{}, &adime.Adime{}, @@ -194,6 +207,9 @@ func getMainEntities() []any { &midwife.Midwife{}, &postalregion.PostalRegion{}, &internalreference.InternalReference{}, + &procedureroomorder.ProcedureRoomOrder{}, + &procedureroomorderitem.ProcedureRoomOrderItem{}, + &vclaimsephist.VclaimSepHist{}, &vclaimsepprint.VclaimSepPrint{}, &vehicle.Vehicle{}, @@ -217,5 +233,7 @@ func getMainEntities() []any { &vclaimsepcontrolletter.VclaimSepControlLetter{}, &resume.Resume{}, &vclaimreference.VclaimReference{}, + &screening.Screening{}, + &actionreport.ActionReport{}, } } diff --git a/internal/interface/migration/simgossync-entities.go b/internal/interface/migration/simgossync-entities.go index 7b37a842..2c479521 100644 --- a/internal/interface/migration/simgossync-entities.go +++ b/internal/interface/migration/simgossync-entities.go @@ -7,6 +7,7 @@ import ( 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" + soapi "simrs-vx/internal/domain/sync-entities/soapi" specialist "simrs-vx/internal/domain/sync-entities/specialist" subspecialist "simrs-vx/internal/domain/sync-entities/subspecialist" unit "simrs-vx/internal/domain/sync-entities/unit" @@ -38,5 +39,8 @@ func getSyncEntities() []any { &internalreference.InternalReferenceLink{}, &internalreference.InternalReferenceSimxLog{}, &internalreference.InternalReferenceSimgosLog{}, + &soapi.SoapiLink{}, + &soapi.SoapiSimxLog{}, + &soapi.SoapiSimgosLog{}, } } diff --git a/internal/use-case/bpjs-plugin/control-plan/helper.go b/internal/use-case/bpjs-plugin/control-plan/helper.go new file mode 100644 index 00000000..15af7238 --- /dev/null +++ b/internal/use-case/bpjs-plugin/control-plan/helper.go @@ -0,0 +1,11 @@ +package controlplan + +import ( + "fmt" + e "simrs-vx/internal/domain/bpjs-entities/control-plan" + ibpjs "simrs-vx/internal/infra/bpjs" +) + +func endpointMapper(input *e.ReadListDto) string { + return fmt.Sprintf("%sRencanaKontrol/jadwalDokter?jeniskontrol=%s&kodepoli=%s&tanggalkontrol=%s", ibpjs.O.BaseUrl, input.PathValue1, input.PathValue2, input.PathValue3) +} diff --git a/internal/use-case/bpjs-plugin/control-plan/plugin.go b/internal/use-case/bpjs-plugin/control-plan/plugin.go new file mode 100644 index 00000000..276750ca --- /dev/null +++ b/internal/use-case/bpjs-plugin/control-plan/plugin.go @@ -0,0 +1,37 @@ +package controlplan + +import ( + "encoding/json" + "fmt" + "io" + "net/http" + e "simrs-vx/internal/domain/bpjs-entities/control-plan" + + "gorm.io/gorm" +) + +func ReadList(input *e.ReadListDto, data *e.Response, tx *gorm.DB) error { + endpoint := endpointMapper(input) + req, err := http.NewRequest("GET", endpoint, nil) + if err != nil { + return err + } + req.Header.Set("Content-Type", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return err + } + + if err := json.Unmarshal(body, &data); err != nil { + return fmt.Errorf("failed to parse response JSON: %w", err) + } + + return nil +} diff --git a/internal/use-case/bpjs-plugin/referral/helper.go b/internal/use-case/bpjs-plugin/referral/helper.go new file mode 100644 index 00000000..169834be --- /dev/null +++ b/internal/use-case/bpjs-plugin/referral/helper.go @@ -0,0 +1,11 @@ +package referral + +import ( + "fmt" + e "simrs-vx/internal/domain/bpjs-entities/referral" + ibpjs "simrs-vx/internal/infra/bpjs" +) + +func endpointMapper(input *e.ReadDetailDto) string { + return fmt.Sprintf("%sRujukan/RS/%s", ibpjs.O.BaseUrl, *input.Number) +} diff --git a/internal/use-case/bpjs-plugin/referral/plugin.go b/internal/use-case/bpjs-plugin/referral/plugin.go new file mode 100644 index 00000000..225181e4 --- /dev/null +++ b/internal/use-case/bpjs-plugin/referral/plugin.go @@ -0,0 +1,37 @@ +package referral + +import ( + "encoding/json" + "fmt" + "io" + "net/http" + e "simrs-vx/internal/domain/bpjs-entities/referral" + + "gorm.io/gorm" +) + +func ReadDetail(input *e.ReadDetailDto, data *e.Response, tx *gorm.DB) error { + endpoint := endpointMapper(input) + req, err := http.NewRequest("GET", endpoint, nil) + if err != nil { + return err + } + req.Header.Set("Content-Type", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return err + } + + if err := json.Unmarshal(body, &data); err != nil { + return fmt.Errorf("failed to parse response JSON: %w", err) + } + + return nil +} diff --git a/internal/use-case/bpjs-plugin/vclaim-sep/plugin.go b/internal/use-case/bpjs-plugin/vclaim-sep/plugin.go index fd18763f..4588029f 100644 --- a/internal/use-case/bpjs-plugin/vclaim-sep/plugin.go +++ b/internal/use-case/bpjs-plugin/vclaim-sep/plugin.go @@ -14,7 +14,11 @@ import ( ) func CreateSep(input *e.CreateDto, data *e.VclaimSep, tx *gorm.DB) error { - req, err := http.NewRequest("POST", ibpjs.O.BaseUrl+"/sep", bytes.NewReader(input.RequestPayload)) + payload, err := input.RequestPayloadIntoJson() + if err != nil { + return err + } + req, err := http.NewRequest("POST", ibpjs.O.BaseUrl+"sep", bytes.NewBuffer(payload)) if err != nil { return err } @@ -43,7 +47,11 @@ func CreateSep(input *e.CreateDto, data *e.VclaimSep, tx *gorm.DB) error { } // Save request/response details in DTO for further use - input.VclaimSepHist.RequestPayload = string(input.RequestPayload) + reqPayload, err := input.RequestPayloadWithEncounterId() + if err != nil { + return err + } + input.VclaimSepHist.RequestPayload = string(reqPayload) input.VclaimSepHist.ResponseBody = string(body) input.VclaimSepHist.Message = msg input.Number = func() *string { @@ -56,3 +64,72 @@ func CreateSep(input *e.CreateDto, data *e.VclaimSep, tx *gorm.DB) error { return nil } + +func ReadDetailSep(input *e.ReadDetailDto, data *e.VclaimSep, tx *gorm.DB) error { + endpoint := fmt.Sprintf("sep/%s", input.Number) + req, err := http.NewRequest("GET", ibpjs.O.BaseUrl+endpoint, nil) + if err != nil { + return err + } + req.Header.Set("Content-Type", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return err + } + + var detail e.SepResponse + if err := json.Unmarshal(body, &detail); err != nil { + return fmt.Errorf("failed to parse response JSON: %w", err) + } + + data.Detail = detail.Response + + return nil +} + +func DeleteSep(input *e.DeleteDto, data *e.VclaimSep, tx *gorm.DB) error { + payload := e.SepDeleteRequest{} + payload.Request.TSep.NoSep = *input.Number + payload.Request.TSep.User = "Coba Ws" + + jsonPayload, err := json.Marshal(payload) + if err != nil { + return err + } + + req, err := http.NewRequest("DELETE", ibpjs.O.BaseUrl+"sep", bytes.NewBuffer(jsonPayload)) + if err != nil { + return err + } + + req.Header.Set("Content-Type", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return err + } + + var detail e.SepResponse + if err := json.Unmarshal(body, &detail); err != nil { + return fmt.Errorf("failed to parse response JSON: %w", err) + } + + if detail.MetaData.Message == SepNotFound { + return fmt.Errorf("sep with number %s not found", *data.Number) + } + + return nil +} diff --git a/internal/use-case/bpjs-plugin/vclaim-sep/tycovar.go b/internal/use-case/bpjs-plugin/vclaim-sep/tycovar.go index f057726e..7c19c44c 100644 --- a/internal/use-case/bpjs-plugin/vclaim-sep/tycovar.go +++ b/internal/use-case/bpjs-plugin/vclaim-sep/tycovar.go @@ -10,3 +10,5 @@ type vclaimResponse struct { } `json:"sep"` } `json:"response"` } + +const SepNotFound = "Data Tidak Ditemukan" diff --git a/internal/use-case/bpjs-use-case/control-plan/case.go b/internal/use-case/bpjs-use-case/control-plan/case.go new file mode 100644 index 00000000..764ea2ea --- /dev/null +++ b/internal/use-case/bpjs-use-case/control-plan/case.go @@ -0,0 +1,50 @@ +package controlplan + +import ( + e "simrs-vx/internal/domain/bpjs-entities/control-plan" + + dg "github.com/karincake/apem/db-gorm-pg" + + pl "simrs-vx/pkg/logger" + pu "simrs-vx/pkg/use-case-helper" + + "gorm.io/gorm" +) + +const source = "control-plan" + +func ReadList(input e.ReadListDto) (*e.Response, error) { + var data e.Response + var err error + + event := pl.Event{ + Feature: "ReadList", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "readList") + + err = dg.I.Transaction(func(tx *gorm.DB) error { + mwRunner := newMiddlewareRunner(&event, tx) + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunReadListMiddleware(readListPreMw, &input, &data); err != nil { + return err + } + + mwRunner.setMwType(pu.MWTPost) + // Run post-middleware + if err := mwRunner.RunReadListMiddleware(readListPostMw, &input, &data); err != nil { + return err + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &data, nil +} diff --git a/internal/use-case/bpjs-use-case/control-plan/middleware-runner.go b/internal/use-case/bpjs-use-case/control-plan/middleware-runner.go new file mode 100644 index 00000000..4c3db3d8 --- /dev/null +++ b/internal/use-case/bpjs-use-case/control-plan/middleware-runner.go @@ -0,0 +1,42 @@ +package controlplan + +import ( + e "simrs-vx/internal/domain/bpjs-entities/control-plan" + 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, + } +} + +func (me *middlewareRunner) RunReadListMiddleware(middlewares []readListMw, input *e.ReadListDto, data *e.Response) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) setMwType(mwType pu.MWType) { + me.MwType = mwType +} diff --git a/internal/use-case/bpjs-use-case/control-plan/middleware.go b/internal/use-case/bpjs-use-case/control-plan/middleware.go new file mode 100644 index 00000000..3478bb19 --- /dev/null +++ b/internal/use-case/bpjs-use-case/control-plan/middleware.go @@ -0,0 +1,12 @@ +package controlplan + +import ( + pcp "simrs-vx/internal/use-case/bpjs-plugin/control-plan" +) + +func init() { + readListPreMw = append(readListPreMw, + readListMw{Name: "readList-control-plan", Func: pcp.ReadList}, + ) + +} diff --git a/internal/use-case/bpjs-use-case/control-plan/tycovar.go b/internal/use-case/bpjs-use-case/control-plan/tycovar.go new file mode 100644 index 00000000..ea2b39a9 --- /dev/null +++ b/internal/use-case/bpjs-use-case/control-plan/tycovar.go @@ -0,0 +1,18 @@ +/* +member is peserta +*/ +package controlplan + +import ( + "gorm.io/gorm" + + e "simrs-vx/internal/domain/bpjs-entities/control-plan" +) + +type readListMw struct { + Name string + Func func(input *e.ReadListDto, data *e.Response, tx *gorm.DB) error +} + +var readListPreMw []readListMw // .. +var readListPostMw []readListMw // .. diff --git a/internal/use-case/bpjs-use-case/referral/case.go b/internal/use-case/bpjs-use-case/referral/case.go new file mode 100644 index 00000000..8818dc58 --- /dev/null +++ b/internal/use-case/bpjs-use-case/referral/case.go @@ -0,0 +1,50 @@ +package referral + +import ( + e "simrs-vx/internal/domain/bpjs-entities/referral" + + dg "github.com/karincake/apem/db-gorm-pg" + + pl "simrs-vx/pkg/logger" + pu "simrs-vx/pkg/use-case-helper" + + "gorm.io/gorm" +) + +const source = "referral" + +func ReadDetail(input e.ReadDetailDto) (*e.Response, error) { + var data e.Response + var err error + + event := pl.Event{ + Feature: "ReadDetail", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "readDetail") + + err = dg.I.Transaction(func(tx *gorm.DB) error { + mwRunner := newMiddlewareRunner(&event, tx) + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunReadDetailMiddleware(readDetailPreMw, &input, &data); err != nil { + return err + } + + mwRunner.setMwType(pu.MWTPost) + // Run post-middleware + if err := mwRunner.RunReadDetailMiddleware(readDetailPostMw, &input, &data); err != nil { + return err + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &data, nil +} diff --git a/internal/use-case/bpjs-use-case/referral/middleware-runner.go b/internal/use-case/bpjs-use-case/referral/middleware-runner.go new file mode 100644 index 00000000..10c26241 --- /dev/null +++ b/internal/use-case/bpjs-use-case/referral/middleware-runner.go @@ -0,0 +1,42 @@ +package referral + +import ( + e "simrs-vx/internal/domain/bpjs-entities/referral" + 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, + } +} + +func (me *middlewareRunner) RunReadDetailMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.Response) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) setMwType(mwType pu.MWType) { + me.MwType = mwType +} diff --git a/internal/use-case/bpjs-use-case/referral/middleware.go b/internal/use-case/bpjs-use-case/referral/middleware.go new file mode 100644 index 00000000..0296ae5a --- /dev/null +++ b/internal/use-case/bpjs-use-case/referral/middleware.go @@ -0,0 +1,12 @@ +package referral + +import ( + pr "simrs-vx/internal/use-case/bpjs-plugin/referral" +) + +func init() { + readDetailPreMw = append(readDetailPreMw, + readDetailMw{Name: "read-detail-referral", Func: pr.ReadDetail}, + ) + +} diff --git a/internal/use-case/bpjs-use-case/referral/tycovar.go b/internal/use-case/bpjs-use-case/referral/tycovar.go new file mode 100644 index 00000000..b1950977 --- /dev/null +++ b/internal/use-case/bpjs-use-case/referral/tycovar.go @@ -0,0 +1,18 @@ +/* +member is peserta +*/ +package referral + +import ( + "gorm.io/gorm" + + e "simrs-vx/internal/domain/bpjs-entities/referral" +) + +type readDetailMw struct { + Name string + Func func(input *e.ReadDetailDto, data *e.Response, tx *gorm.DB) error +} + +var readDetailPreMw []readDetailMw +var readDetailPostMw []readDetailMw diff --git a/internal/use-case/bpjs-use-case/vclaim-sep/case.go b/internal/use-case/bpjs-use-case/vclaim-sep/case.go index ac72d648..1d0e4aab 100644 --- a/internal/use-case/bpjs-use-case/vclaim-sep/case.go +++ b/internal/use-case/bpjs-use-case/vclaim-sep/case.go @@ -1,6 +1,7 @@ package vclaimsep import ( + "fmt" "strconv" e "simrs-vx/internal/domain/bpjs-entities/vclaim-sep" @@ -31,6 +32,17 @@ func Create(input e.CreateDto) (*d.Data, error) { pl.SetLogInfo(&event, input, "started", "create") err := dg.I.Transaction(func(tx *gorm.DB) error { + rDto := e.ReadDetailDto{Encounter_Id: input.Encounter_Id} + if vSep, err := ReadDetailData(rDto, &event, tx); err != nil { + if !pu.IsDataNotFoundError(err) { + return err + } + + if vSep != nil { + return fmt.Errorf("sep with encounter id %d already exist with number %s", input.Encounter_Id, *vSep.Number) + } + } + mwRunner := newMiddlewareRunner(&event, tx) mwRunner.setMwType(pu.MWTPre) // Run pre-middleware @@ -38,12 +50,12 @@ func Create(input e.CreateDto) (*d.Data, error) { return err } - if _, err := uvsh.CreateData(input.VclaimSepHist, &event, tx); err != nil { + if _, err := uvsh.CreateData(input.VclaimSepHist, &event); err != nil { return err } if !input.IsMessageSuccess() { - return nil + return fmt.Errorf("%s", input.VclaimSepHist.Message) } if resData, err := CreateData(input, &event, tx); err != nil { @@ -234,7 +246,7 @@ func Update(input e.UpdateDto) (*d.Data, error) { } func Delete(input e.DeleteDto) (*d.Data, error) { - rdDto := e.ReadDetailDto{Number: input.Number} + rdDto := e.ReadDetailDto{Id: input.Id} var data *e.VclaimSep var err error @@ -255,7 +267,7 @@ func Delete(input e.DeleteDto) (*d.Data, error) { mwRunner := newMiddlewareRunner(&event, tx) mwRunner.setMwType(pu.MWTPre) // Run pre-middleware - if err := mwRunner.RunDeleteMiddleware(readDetailPreMw, &rdDto, data); err != nil { + if err := mwRunner.RunDeleteMiddleware(deletePreMw, &e.DeleteDto{}, data); err != nil { return err } @@ -265,7 +277,7 @@ func Delete(input e.DeleteDto) (*d.Data, error) { mwRunner.setMwType(pu.MWTPost) // Run post-middleware - if err := mwRunner.RunDeleteMiddleware(readDetailPostMw, &rdDto, data); err != nil { + if err := mwRunner.RunDeleteMiddleware(deletePostMw, &e.DeleteDto{}, data); err != nil { return err } diff --git a/internal/use-case/bpjs-use-case/vclaim-sep/lib.go b/internal/use-case/bpjs-use-case/vclaim-sep/lib.go index 817c357c..82da0d45 100644 --- a/internal/use-case/bpjs-use-case/vclaim-sep/lib.go +++ b/internal/use-case/bpjs-use-case/vclaim-sep/lib.go @@ -87,6 +87,9 @@ func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e if input.Id != 0 { tx = tx.Where("\"Id\" = ?", input.Id) } + if input.Encounter_Id != nil { + tx = tx.Where("\"Encounter_Id\" = ?", *input.Encounter_Id) + } if err := tx.First(&data).Error; err != nil { if processedErr := pu.HandleReadError(err, event, source, input.Id, data); processedErr != nil { diff --git a/internal/use-case/bpjs-use-case/vclaim-sep/middleware-runner.go b/internal/use-case/bpjs-use-case/vclaim-sep/middleware-runner.go index dee35276..8e8522a6 100644 --- a/internal/use-case/bpjs-use-case/vclaim-sep/middleware-runner.go +++ b/internal/use-case/bpjs-use-case/vclaim-sep/middleware-runner.go @@ -83,7 +83,7 @@ func (me *middlewareRunner) RunUpdateMiddleware(middlewares []readDetailMw, inpu return nil } -func (me *middlewareRunner) RunDeleteMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.VclaimSep) error { +func (me *middlewareRunner) RunDeleteMiddleware(middlewares []deleteMw, input *e.DeleteDto, data *e.VclaimSep) error { for _, middleware := range middlewares { logData := pu.GetLogData(input, data) diff --git a/internal/use-case/bpjs-use-case/vclaim-sep/middleware.go b/internal/use-case/bpjs-use-case/vclaim-sep/middleware.go index 1ad0a853..08caba00 100644 --- a/internal/use-case/bpjs-use-case/vclaim-sep/middleware.go +++ b/internal/use-case/bpjs-use-case/vclaim-sep/middleware.go @@ -9,5 +9,10 @@ func init() { createPreMw = append(createPreMw, createMw{Name: "create-sep", Func: pvs.CreateSep}, ) - + readDetailPostMw = append(readDetailPostMw, + readDetailMw{Name: "read-detail-sep", Func: pvs.ReadDetailSep}, + ) + deletePreMw = append(deletePreMw, + deleteMw{Name: "delete-sep", Func: pvs.DeleteSep}, + ) } diff --git a/internal/use-case/bpjs-use-case/vclaim-sep/tycovar.go b/internal/use-case/bpjs-use-case/vclaim-sep/tycovar.go index 932bc355..be3b5d11 100644 --- a/internal/use-case/bpjs-use-case/vclaim-sep/tycovar.go +++ b/internal/use-case/bpjs-use-case/vclaim-sep/tycovar.go @@ -29,8 +29,12 @@ type readDetailMw struct { Func func(input *e.ReadDetailDto, data *e.VclaimSep, tx *gorm.DB) error } +type deleteMw struct { + Name string + Func func(input *e.DeleteDto, data *e.VclaimSep, tx *gorm.DB) error +} + type UpdateMw = readDetailMw -type DeleteMw = readDetailMw var createPreMw []createMw // preprocess middleware var createPostMw []createMw // postprocess middleware @@ -40,5 +44,5 @@ var readDetailPreMw []readDetailMw var readDetailPostMw []readDetailMw var updatePreMw []readDetailMw var updatePostMw []readDetailMw -var deletePreMw []readDetailMw -var deletePostMw []readDetailMw +var deletePreMw []deleteMw +var deletePostMw []deleteMw diff --git a/internal/use-case/main-use-case/action-report/case.go b/internal/use-case/main-use-case/action-report/case.go new file mode 100644 index 00000000..2ae0f268 --- /dev/null +++ b/internal/use-case/main-use-case/action-report/case.go @@ -0,0 +1,295 @@ +package actionreport + +import ( + "errors" + "strconv" + + e "simrs-vx/internal/domain/main-entities/action-report" + + dg "github.com/karincake/apem/db-gorm-pg" + d "github.com/karincake/dodol" + + pl "simrs-vx/pkg/logger" + pu "simrs-vx/pkg/use-case-helper" + + "gorm.io/gorm" +) + +const source = "action-report" + +func Create(input e.CreateDto) (*d.Data, error) { + data := e.ActionReport{} + + event := pl.Event{ + Feature: "Create", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "create") + + err := dg.I.Transaction(func(tx *gorm.DB) error { + mwRunner := newMiddlewareRunner(&event, tx) + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil { + return err + } + + if !input.AuthInfo.IsDoctor() && !input.AuthInfo.IsNurse() { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "auth-forbidden", + Detail: "user position is not allowed", + Raw: errors.New("authentication failed"), + } + return pl.SetLogError(&event, input) + } + + if input.AuthInfo.Employee_Id != nil { + v := uint(*input.AuthInfo.Employee_Id) + input.Employee_Id = &v + } else { + input.Employee_Id = nil + } + + if resData, err := CreateData(input, &event, tx); err != nil { + return err + } else { + data = *resData + } + + mwRunner.setMwType(pu.MWTPost) + // Run post-middleware + if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil { + return err + } + + pl.SetLogInfo(&event, nil, "complete") + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.II{ + "source": source, + "structure": "single-data", + "status": "created", + }, + Data: data.ToResponse(), + }, nil +} + +func ReadList(input e.ReadListDto) (*d.Data, error) { + var data *e.ActionReport + var dataList []e.ActionReport + var metaList *e.MetaDto + var err error + + event := pl.Event{ + Feature: "ReadList", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "readList") + + err = dg.I.Transaction(func(tx *gorm.DB) error { + mwRunner := newMiddlewareRunner(&event, tx) + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunReadListMiddleware(readListPreMw, &input, data); err != nil { + return err + } + + if dataList, metaList, err = ReadListData(input, &event, tx); err != nil { + return err + } + + mwRunner.setMwType(pu.MWTPost) + // Run post-middleware + if err := mwRunner.RunReadListMiddleware(readListPostMw, &input, data); err != nil { + return err + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "list-data", + "status": "fetched", + "page_number": strconv.Itoa(metaList.PageNumber), + "page_size": strconv.Itoa(metaList.PageSize), + "record_totalCount": strconv.Itoa(metaList.Count), + "record_currentCount": strconv.Itoa(len(dataList)), + }, + Data: e.ToResponseList(dataList), + }, nil +} + +func ReadDetail(input e.ReadDetailDto) (*d.Data, error) { + var data *e.ActionReport + var err error + + event := pl.Event{ + Feature: "ReadDetail", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "readDetail") + + err = dg.I.Transaction(func(tx *gorm.DB) error { + mwRunner := newMiddlewareRunner(&event, tx) + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunReadDetailMiddleware(readDetailPreMw, &input, data); err != nil { + return err + } + + if data, err = ReadDetailData(input, &event, tx); err != nil { + return err + } + + mwRunner.setMwType(pu.MWTPost) + // Run post-middleware + if err := mwRunner.RunReadDetailMiddleware(readDetailPostMw, &input, data); err != nil { + return err + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "single-data", + "status": "fetched", + }, + Data: data.ToResponse(), + }, nil +} + +func Update(input e.UpdateDto) (*d.Data, error) { + rdDto := e.ReadDetailDto{Id: input.Id} + var data *e.ActionReport + var err error + + event := pl.Event{ + Feature: "Update", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "update") + + err = dg.I.Transaction(func(tx *gorm.DB) error { + pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail") + if data, err = ReadDetailData(rdDto, &event, tx); err != nil { + return err + } + + mwRunner := newMiddlewareRunner(&event, tx) + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunUpdateMiddleware(readDetailPreMw, &rdDto, data); err != nil { + return err + } + + if err := UpdateData(input, data, &event, tx); err != nil { + return err + } + + pl.SetLogInfo(&event, nil, "complete") + + mwRunner.setMwType(pu.MWTPost) + // Run post-middleware + if err := mwRunner.RunUpdateMiddleware(readDetailPostMw, &rdDto, data); err != nil { + return err + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "single-data", + "status": "updated", + }, + Data: data.ToResponse(), + }, nil + +} + +func Delete(input e.DeleteDto) (*d.Data, error) { + rdDto := e.ReadDetailDto{Id: input.Id} + var data *e.ActionReport + var err error + + event := pl.Event{ + Feature: "Delete", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "delete") + + err = dg.I.Transaction(func(tx *gorm.DB) error { + pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail") + if data, err = ReadDetailData(rdDto, &event, tx); err != nil { + return err + } + + mwRunner := newMiddlewareRunner(&event, tx) + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunDeleteMiddleware(readDetailPreMw, &rdDto, data); err != nil { + return err + } + + if err := DeleteData(data, &event, tx); err != nil { + return err + } + + mwRunner.setMwType(pu.MWTPost) + // Run post-middleware + if err := mwRunner.RunDeleteMiddleware(readDetailPostMw, &rdDto, data); err != nil { + return err + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "single-data", + "status": "deleted", + }, + Data: data.ToResponse(), + }, nil + +} diff --git a/internal/use-case/main-use-case/action-report/helper.go b/internal/use-case/main-use-case/action-report/helper.go new file mode 100644 index 00000000..efe4532e --- /dev/null +++ b/internal/use-case/main-use-case/action-report/helper.go @@ -0,0 +1,28 @@ +/* +DESCRIPTION: +Any functions that are used internally by the use-case +*/ +package actionreport + +import ( + e "simrs-vx/internal/domain/main-entities/action-report" +) + +func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.ActionReport) { + var inputSrc *e.CreateDto + if inputT, ok := any(input).(*e.CreateDto); ok { + inputSrc = inputT + } else { + inputTemp := any(input).(*e.UpdateDto) + inputSrc = &inputTemp.CreateDto + } + + data.Encounter_Id = inputSrc.Encounter_Id + data.Date = inputSrc.Date + data.Doctor_Code = inputSrc.Doctor_Code + data.Operator_Employe_Id = inputSrc.Operator_Employe_Id + data.Assistant_Employe_Id = inputSrc.Assistant_Employe_Id + data.Instrumentor_Employe_Id = inputSrc.Instrumentor_Employe_Id + data.Nurse_Code = inputSrc.Nurse_Code + data.Value = inputSrc.Value +} diff --git a/internal/use-case/main-use-case/room/lib.go b/internal/use-case/main-use-case/action-report/lib.go similarity index 84% rename from internal/use-case/main-use-case/room/lib.go rename to internal/use-case/main-use-case/action-report/lib.go index 5e586248..5a272cce 100644 --- a/internal/use-case/main-use-case/room/lib.go +++ b/internal/use-case/main-use-case/action-report/lib.go @@ -1,7 +1,7 @@ -package room +package actionreport import ( - e "simrs-vx/internal/domain/main-entities/room" + e "simrs-vx/internal/domain/main-entities/action-report" plh "simrs-vx/pkg/lib-helper" pl "simrs-vx/pkg/logger" @@ -12,10 +12,10 @@ import ( "gorm.io/gorm" ) -func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Room, error) { +func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.ActionReport, error) { pl.SetLogInfo(event, nil, "started", "DBCreate") - data := e.Room{} + data := e.ActionReport{} setData(&input, &data) var tx *gorm.DB @@ -33,9 +33,9 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Room, e return &data, nil } -func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Room, *e.MetaDto, error) { +func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.ActionReport, *e.MetaDto, error) { pl.SetLogInfo(event, input, "started", "DBReadList") - data := []e.Room{} + data := []e.ActionReport{} pagination := gh.Pagination{} count := int64(0) meta := e.MetaDto{} @@ -48,7 +48,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Ro } tx = tx. - Model(&e.Room{}). + Model(&e.ActionReport{}). Scopes(gh.Preload(input.Includes)). Scopes(gh.Filter(input.FilterDto)). Count(&count). @@ -70,9 +70,9 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Ro return data, &meta, nil } -func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.Room, error) { +func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.ActionReport, error) { pl.SetLogInfo(event, input, "started", "DBReadDetail") - data := e.Room{} + data := e.ActionReport{} var tx *gorm.DB if len(dbx) > 0 { @@ -91,7 +91,7 @@ func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e return &data, nil } -func UpdateData(input e.UpdateDto, data *e.Room, event *pl.Event, dbx ...*gorm.DB) error { +func UpdateData(input e.UpdateDto, data *e.ActionReport, event *pl.Event, dbx ...*gorm.DB) error { pl.SetLogInfo(event, data, "started", "DBUpdate") setData(&input, data) @@ -116,7 +116,7 @@ func UpdateData(input e.UpdateDto, data *e.Room, event *pl.Event, dbx ...*gorm.D return nil } -func DeleteData(data *e.Room, event *pl.Event, dbx ...*gorm.DB) error { +func DeleteData(data *e.ActionReport, event *pl.Event, dbx ...*gorm.DB) error { pl.SetLogInfo(event, data, "started", "DBDelete") var tx *gorm.DB if len(dbx) > 0 { diff --git a/internal/use-case/main-use-case/action-report/middleware-runner.go b/internal/use-case/main-use-case/action-report/middleware-runner.go new file mode 100644 index 00000000..e2544169 --- /dev/null +++ b/internal/use-case/main-use-case/action-report/middleware-runner.go @@ -0,0 +1,103 @@ +package actionreport + +import ( + e "simrs-vx/internal/domain/main-entities/action-report" + 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.ActionReport) 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.ActionReport) 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.ActionReport) 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.ActionReport) 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.ActionReport) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) setMwType(mwType pu.MWType) { + me.MwType = mwType +} diff --git a/internal/use-case/main-use-case/action-report/middleware.go b/internal/use-case/main-use-case/action-report/middleware.go new file mode 100644 index 00000000..50254de2 --- /dev/null +++ b/internal/use-case/main-use-case/action-report/middleware.go @@ -0,0 +1,9 @@ +package actionreport + +// example of middleware +// func init() { +// createPreMw = append(createPreMw, +// CreateMw{Name: "modif-input", Func: pm.ModifInput}, +// CreateMw{Name: "check-data", Func: pm.CheckData}, +// ) +// } diff --git a/internal/use-case/main-use-case/action-report/tycovar.go b/internal/use-case/main-use-case/action-report/tycovar.go new file mode 100644 index 00000000..9eebfabd --- /dev/null +++ b/internal/use-case/main-use-case/action-report/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 actionreport + +import ( + "gorm.io/gorm" + + e "simrs-vx/internal/domain/main-entities/action-report" +) + +type createMw struct { + Name string + Func func(input *e.CreateDto, data *e.ActionReport, tx *gorm.DB) error +} + +type readListMw struct { + Name string + Func func(input *e.ReadListDto, data *e.ActionReport, tx *gorm.DB) error +} + +type readDetailMw struct { + Name string + Func func(input *e.ReadDetailDto, data *e.ActionReport, tx *gorm.DB) error +} + +type UpdateMw = readDetailMw +type DeleteMw = readDetailMw + +var createPreMw []createMw // preprocess middleware +var createPostMw []createMw // postprocess middleware +var readListPreMw []readListMw // .. +var readListPostMw []readListMw // .. +var readDetailPreMw []readDetailMw +var readDetailPostMw []readDetailMw +var updatePreMw []readDetailMw +var updatePostMw []readDetailMw +var deletePreMw []readDetailMw +var deletePostMw []readDetailMw diff --git a/internal/use-case/main-use-case/antibiotic-in-use/lib.go b/internal/use-case/main-use-case/antibiotic-in-use/lib.go index e6b2d13d..4a64ef2d 100644 --- a/internal/use-case/main-use-case/antibiotic-in-use/lib.go +++ b/internal/use-case/main-use-case/antibiotic-in-use/lib.go @@ -137,4 +137,4 @@ func DeleteData(data *e.AntibioticInUse, event *pl.Event, dbx ...*gorm.DB) error pl.SetLogInfo(event, nil, "complete") return nil -} \ No newline at end of file +} diff --git a/internal/use-case/main-use-case/antibiotic-in-use/middleware-runner.go b/internal/use-case/main-use-case/antibiotic-in-use/middleware-runner.go index de906bf8..580a47ba 100644 --- a/internal/use-case/main-use-case/antibiotic-in-use/middleware-runner.go +++ b/internal/use-case/main-use-case/antibiotic-in-use/middleware-runner.go @@ -100,4 +100,4 @@ func (me *middlewareRunner) RunDeleteMiddleware(middlewares []readDetailMw, inpu func (me *middlewareRunner) setMwType(mwType pu.MWType) { me.MwType = mwType -} \ No newline at end of file +} diff --git a/internal/use-case/main-use-case/antibiotic-in-use/middleware.go b/internal/use-case/main-use-case/antibiotic-in-use/middleware.go index f437fa0c..a232aec5 100644 --- a/internal/use-case/main-use-case/antibiotic-in-use/middleware.go +++ b/internal/use-case/main-use-case/antibiotic-in-use/middleware.go @@ -6,4 +6,4 @@ package antibioticinuse // CreateMw{Name: "modif-input", Func: pm.ModifInput}, // CreateMw{Name: "check-data", Func: pm.CheckData}, // ) -// } \ No newline at end of file +// } diff --git a/internal/use-case/main-use-case/antibiotic-in-use/tycovar.go b/internal/use-case/main-use-case/antibiotic-in-use/tycovar.go index f35c0065..81e502c0 100644 --- a/internal/use-case/main-use-case/antibiotic-in-use/tycovar.go +++ b/internal/use-case/main-use-case/antibiotic-in-use/tycovar.go @@ -41,4 +41,4 @@ var readDetailPostMw []readDetailMw var updatePreMw []readDetailMw var updatePostMw []readDetailMw var deletePreMw []readDetailMw -var deletePostMw []readDetailMw \ No newline at end of file +var deletePostMw []readDetailMw diff --git a/internal/use-case/main-use-case/antibiotic-src/case.go b/internal/use-case/main-use-case/antibiotic-src/case.go index e1ff1c44..9b108f65 100644 --- a/internal/use-case/main-use-case/antibiotic-src/case.go +++ b/internal/use-case/main-use-case/antibiotic-src/case.go @@ -277,4 +277,4 @@ func Delete(input e.DeleteDto) (*d.Data, error) { Data: data.ToResponse(), }, nil -} \ No newline at end of file +} diff --git a/internal/use-case/main-use-case/antibiotic-src/lib.go b/internal/use-case/main-use-case/antibiotic-src/lib.go index 24f91815..c9ede312 100644 --- a/internal/use-case/main-use-case/antibiotic-src/lib.go +++ b/internal/use-case/main-use-case/antibiotic-src/lib.go @@ -137,4 +137,4 @@ func DeleteData(data *e.AntibioticSrc, event *pl.Event, dbx ...*gorm.DB) error { pl.SetLogInfo(event, nil, "complete") return nil -} \ No newline at end of file +} diff --git a/internal/use-case/main-use-case/doctor/lib.go b/internal/use-case/main-use-case/doctor/lib.go index 827802fa..9efe2239 100644 --- a/internal/use-case/main-use-case/doctor/lib.go +++ b/internal/use-case/main-use-case/doctor/lib.go @@ -1,6 +1,7 @@ package doctor import ( + "fmt" e "simrs-vx/internal/domain/main-entities/doctor" plh "simrs-vx/pkg/lib-helper" @@ -90,7 +91,8 @@ func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e if input.Code != nil { tx = tx.Where("\"Code\" = ?", input.Code) } - if err := tx.First(&data).Error; err != nil { + fmt.Println(input.Includes) + if err := tx.Scopes(gh.Preload(input.Includes)).First(&data).Error; err != nil { if processedErr := pu.HandleReadError(err, event, source, input.Id, data); processedErr != nil { return nil, processedErr } diff --git a/internal/use-case/main-use-case/generate-file/case.go b/internal/use-case/main-use-case/generate-file/case.go index 39cb2f02..7c657640 100644 --- a/internal/use-case/main-use-case/generate-file/case.go +++ b/internal/use-case/main-use-case/generate-file/case.go @@ -1,26 +1,14 @@ package generatefile import ( - "encoding/json" "errors" - evs "simrs-vx/internal/domain/bpjs-entities/vclaim-sep" - evscl "simrs-vx/internal/domain/bpjs-entities/vclaim-sep-control-letter" - egc "simrs-vx/internal/domain/main-entities/general-consent" - - uvs "simrs-vx/internal/use-case/bpjs-use-case/vclaim-sep" - uvscl "simrs-vx/internal/use-case/bpjs-use-case/vclaim-sep-control-letter" - ugc "simrs-vx/internal/use-case/main-use-case/general-consent" - - pc "simrs-vx/pkg/conv-helper" pl "simrs-vx/pkg/logger" - pu "simrs-vx/pkg/use-case-helper" dg "github.com/karincake/apem/db-gorm-pg" d "github.com/karincake/dodol" "gorm.io/gorm" - erc "simrs-vx/internal/domain/references/common" ere "simrs-vx/internal/domain/references/encounter" ) @@ -32,133 +20,37 @@ func Generate(input GenerateDto) (*d.Data, error) { Source: source, } - var response ResponseDto + var ( + response *ResponseDto + err error + ) // Start log pl.SetLogInfo(&event, input, "started", "create") - err := dg.I.Transaction(func(tx *gorm.DB) error { + err = dg.I.Transaction(func(tx *gorm.DB) error { switch input.Type_Code { // general-consent case ere.DTCGC: - // get value from general consent by ref_id - gc, err := ugc.ReadDetailData(egc.ReadDetailDto{Id: uint(*pc.StringToUint64(*input.Ref_Id))}, &event) + response, err = generateGC(input, event, tx) if err != nil { return err } - if gc.FileUrl != nil { - if err := removeFile(string(input.EntityType_Code), *gc.FileUrl); err != nil { - return err - } - } - - // map template data - templateData := GeneralConsentPDF{} - if gc.Value != nil { - err := json.Unmarshal([]byte(*gc.Value), &templateData) - if err != nil { - event.ErrInfo = pl.ErrorInfo{ - Code: "data-unmarshal-fail", - Detail: err.Error(), - Raw: err, - } - return err - } - } else { - return errors.New("no value in this general consent") - } - - input.FormatType = erc.DFTCPDF - input.TemplateName = TDNGC - input.Encounter_Id = gc.Encounter_Id - templateData.Date = pu.FormatIndonesianDate(gc.CreatedAt) - - // generate file - urlPub, err := generateFile(input, templateData) - if err != nil { - return err - } - - gc.FileUrl = &urlPub - if err := dg.I.Save(&gc).Error; err != nil { - return err - } - - response = ResponseDto{ - FileUrl: urlPub, - } - // control-letter case ere.DTCVSCL: - // get value from control letter by ref_id - cl, err := uvscl.ReadDetailData(evscl.ReadDetailDto{Number: input.Ref_Id}, &event) - if err != nil { - if !pu.IsDataNotFoundError(err) { - return err - } - } - - if cl != nil && cl.FileUrl != nil { - if err := removeFile(string(input.EntityType_Code), *cl.FileUrl); err != nil { - return err - } - } - - // map template data - clData := VclaimControlLetter{} - if input.Data != nil { - err := json.Unmarshal([]byte(*input.Data), &clData) - if err != nil { - event.ErrInfo = pl.ErrorInfo{ - Code: "data-unmarshal-fail", - Detail: err.Error(), - Raw: err, - } - return err - } - } else { - return errors.New("there is no data to be used") - } - - if cl == nil { - createCL := evscl.CreateDto{ - VclaimSep_Number: &clData.VclaimSep.Number, - Number: &clData.Number, - Value: input.Data, - } - if cl, err = uvscl.CreateData(createCL, &event, tx); err != nil { - return err - } - - } - // get encounter id by vclaim sep number - vs, err := uvs.ReadDetailData(evs.ReadDetailDto{Number: &clData.VclaimSep.Number}, &event) + response, err = generateCL(input, event, tx) if err != nil { return err } - input.FormatType = erc.DFTCPDF - input.TemplateName = TDNCL - input.Encounter_Id = vs.Encounter_Id - input.UseA5Lanscape = true - - templateData := clData.generateTemplateData() - // generate file - urlPub, err := generateFile(input, templateData) + // resume + case ere.DTCResume: + response, err = generateResume(input, event, tx) if err != nil { return err } - cl.FileUrl = &urlPub - if err := tx.Save(&cl).Error; err != nil { - return err - } - - response = ResponseDto{ - FileUrl: urlPub, - } - default: return errors.New("invalid type code") } diff --git a/internal/use-case/main-use-case/generate-file/helper.go b/internal/use-case/main-use-case/generate-file/helper.go index 8cd3543f..6edd34d8 100644 --- a/internal/use-case/main-use-case/generate-file/helper.go +++ b/internal/use-case/main-use-case/generate-file/helper.go @@ -1,19 +1,36 @@ package generatefile import ( + "encoding/json" "errors" "fmt" "mime" "path/filepath" "time" + evs "simrs-vx/internal/domain/bpjs-entities/vclaim-sep" + evscl "simrs-vx/internal/domain/bpjs-entities/vclaim-sep-control-letter" + ee "simrs-vx/internal/domain/main-entities/encounter" + egc "simrs-vx/internal/domain/main-entities/general-consent" + er "simrs-vx/internal/domain/main-entities/resume" + + uvs "simrs-vx/internal/use-case/bpjs-use-case/vclaim-sep" + uvscl "simrs-vx/internal/use-case/bpjs-use-case/vclaim-sep-control-letter" + ue "simrs-vx/internal/use-case/main-use-case/encounter" + ugc "simrs-vx/internal/use-case/main-use-case/general-consent" + ur "simrs-vx/internal/use-case/main-use-case/resume" + erc "simrs-vx/internal/domain/references/common" docscfg "simrs-vx/internal/infra/docs-cfg" + pc "simrs-vx/pkg/conv-helper" pf "simrs-vx/pkg/file-helper" + pl "simrs-vx/pkg/logger" pm "simrs-vx/pkg/minio-helper" pp "simrs-vx/pkg/pdf-helper" pu "simrs-vx/pkg/use-case-helper" + + "gorm.io/gorm" ) // generate temporary file, upload to minio, generate public url, delete temporary file @@ -93,3 +110,232 @@ func removeFile(bucket, fileUrl string) error { } return nil } + +// generate general consent +func generateGC(input GenerateDto, event pl.Event, tx *gorm.DB) (*ResponseDto, error) { + // get value from general consent by ref_id + gc, err := ugc.ReadDetailData(egc.ReadDetailDto{Id: uint(*pc.StringToUint64(*input.Ref_Id))}, &event) + if err != nil { + return nil, err + } + + if gc.FileUrl != nil { + if err := removeFile(string(input.EntityType_Code), *gc.FileUrl); err != nil { + return nil, err + } + } + + // map template data + templateData := GeneralConsentPDF{} + if gc.Value != nil { + err := json.Unmarshal([]byte(*gc.Value), &templateData) + if err != nil { + event.ErrInfo = pl.ErrorInfo{ + Code: "data-unmarshal-fail", + Detail: err.Error(), + Raw: err, + } + return nil, err + } + } else { + return nil, errors.New("no value in this general consent") + } + + input.FormatType = erc.DFTCPDF + input.TemplateName = TDNGC + input.Encounter_Id = gc.Encounter_Id + templateData.Date = pu.FormatIndonesianDate(gc.CreatedAt) + + // generate file + urlPub, err := generateFile(input, templateData) + if err != nil { + return nil, err + } + + gc.FileUrl = &urlPub + if err := tx.Save(&gc).Error; err != nil { + return nil, err + } + + response := ResponseDto{ + FileUrl: urlPub, + } + + return &response, nil +} + +func generateCL(input GenerateDto, event pl.Event, tx *gorm.DB) (*ResponseDto, error) { + // get value from control letter by ref_id + cl, err := uvscl.ReadDetailData(evscl.ReadDetailDto{Number: input.Ref_Id}, &event) + if err != nil { + if !pu.IsDataNotFoundError(err) { + return nil, err + } + } + + if cl != nil && cl.FileUrl != nil { + if err := removeFile(string(input.EntityType_Code), *cl.FileUrl); err != nil { + return nil, err + } + } + + // map template data + clData := VclaimControlLetter{} + if input.Data != nil { + err := json.Unmarshal([]byte(*input.Data), &clData) + if err != nil { + event.ErrInfo = pl.ErrorInfo{ + Code: "data-unmarshal-fail", + Detail: err.Error(), + Raw: err, + } + return nil, err + } + } else { + return nil, errors.New("there is no data to be used") + } + + if cl == nil { + createCL := evscl.CreateDto{ + VclaimSep_Number: &clData.VclaimSep.Number, + Number: &clData.Number, + Value: input.Data, + } + if cl, err = uvscl.CreateData(createCL, &event, tx); err != nil { + return nil, err + } + + } + // get encounter id by vclaim sep number + vs, err := uvs.ReadDetailData(evs.ReadDetailDto{Number: &clData.VclaimSep.Number}, &event) + if err != nil { + return nil, err + } + + input.FormatType = erc.DFTCPDF + input.TemplateName = TDNCL + input.Encounter_Id = vs.Encounter_Id + input.UseA5Lanscape = true + + templateData := clData.generateTemplateData() + // generate file + urlPub, err := generateFile(input, templateData) + if err != nil { + return nil, err + } + + cl.FileUrl = &urlPub + if err := tx.Save(&cl).Error; err != nil { + return nil, err + } + + response := ResponseDto{ + FileUrl: urlPub, + } + + return &response, nil +} + +func generateResume(input GenerateDto, event pl.Event, tx *gorm.DB) (*ResponseDto, error) { + // get value from resume by ref_id + includes := "Doctor.Employee.Person" + r, err := ur.ReadDetailData(er.ReadDetailDto{Id: uint(*pc.StringToUint64(*input.Ref_Id)), Includes: includes}, &event) + if err != nil { + return nil, err + } + + if !r.IsValidated() { + return nil, errors.New("resume is not validated") + } + + if r.FileUrl != nil { + if err := removeFile(string(input.EntityType_Code), *r.FileUrl); err != nil { + return nil, err + } + } + + templateData, err := generateResumeTemplateData(*r, event, tx) + if err != nil { + return nil, err + } + + input.FormatType = erc.DFTCPDF + input.TemplateName = TDNR + input.Encounter_Id = r.Encounter_Id + + // generate file + urlPub, err := generateFile(input, templateData) + if err != nil { + return nil, err + } + + r.FileUrl = &urlPub + if err := tx.Save(&r).Error; err != nil { + return nil, err + } + + response := ResponseDto{ + FileUrl: urlPub, + } + + return &response, nil +} + +func generateResumeTemplateData(resume er.Resume, event pl.Event, tx *gorm.DB) (*ResumePDF, error) { + // get encounter + includes := "Patient,Patient.Person,Patient.Person.BirthRegency,Patient.Person.Contacts" + encounter, err := ue.ReadDetailData(ee.ReadDetailDto{Id: *resume.Encounter_Id, Includes: includes}, &event) + if err != nil { + return nil, err + } + + // map template data + rData := er.ValueDto{} + if resume.Value != nil { + err := json.Unmarshal([]byte(*resume.Value), &rData) + if err != nil { + event.ErrInfo = pl.ErrorInfo{ + Code: "data-unmarshal-fail", + Detail: err.Error(), + Raw: err, + } + return nil, err + } + } else { + return nil, errors.New("there is no data to be used") + } + templateData := ResumePDF{} + templateData.MedicalRecord = *encounter.Patient.Number + templateData.NIK = *encounter.Patient.Person.ResidentIdentityNumber + templateData.Name = encounter.Patient.Person.Name + templateData.BirthPlaceDate = pu.FormatPlaceAndDate(encounter.Patient.Person.BirthRegency.Name, *encounter.Patient.Person.BirthDate) + templateData.Gender = encounter.Patient.Person.GenderString() + templateData.Phone = encounter.Patient.Person.GetPhoneNumber() + // templateData.Class = get from vclaim sep eg. III + // templateData.Unit = get from vclaim sep eg. R.KERINCI - KLS 3 + templateData.Doctor_Name = resume.Doctor.Employee.Person.FullName() + templateData.StartedAt = *pc.TimeToStringWithFormat(encounter.StartedAt, "") + templateData.FinishedAt = *pc.TimeToStringWithFormat(encounter.FinishedAt, "") + templateData.DiagnosisIn = rData.Assessment.DiagnosisIn + templateData.Diagnosis = rData.Diagnosis.SecondaryDiagnosis + templateData.MainComplaint = rData.Assessment.MainComplaint + templateData.MedicalHistory = rData.Assessment.MedicalHistory + templateData.PhysicalExamination = rData.Assessment.PhysicalExamination + templateData.SupportingExamination = rData.Supporting.Notes + templateData.MedicalActions = rData.Action.AdditionalActions + templateData.MedicalAction = rData.Action.MedicalActions + templateData.Consultations = rData.Consultation.Consultations + templateData.Allergy = rData.Pharmacy.AllergySpecialConditions + templateData.ConsciousnessLevel = rData.Discharge.ConsciousnessLevel + templateData.BloodPressure = fmt.Sprintf("%.0f/%.0f", rData.Discharge.BloodPressureSystolic, rData.Discharge.BloodPressureDiastolic) + templateData.BodyTemperature = rData.Discharge.BodyTemperature + templateData.RespirationRate = rData.Discharge.RespirationRate + templateData.HeartRate = rData.Discharge.HeartRate + templateData.PainScale = rData.Discharge.PainScale + templateData.ConditionOnDischarge = rData.Management.ConditionOnDischarge + templateData.DischargeMethod = rData.Management.DischargeMethod + templateData.Medications = rData.Medication.Medications + templateData.Date = pu.GetTimeNow().Format("02-01-2006") + + return &templateData, nil +} diff --git a/internal/use-case/main-use-case/generate-file/tycovar.go b/internal/use-case/main-use-case/generate-file/tycovar.go index 2f6a0ced..a242f476 100644 --- a/internal/use-case/main-use-case/generate-file/tycovar.go +++ b/internal/use-case/main-use-case/generate-file/tycovar.go @@ -7,6 +7,8 @@ import ( erc "simrs-vx/internal/domain/references/common" ere "simrs-vx/internal/domain/references/encounter" + er "simrs-vx/internal/domain/main-entities/resume" + pu "simrs-vx/pkg/use-case-helper" ) @@ -32,6 +34,44 @@ type ControlLetterPDF struct { PrintDate string } +type ResumePDF struct { + MedicalRecord string + NIK string + Name string + BirthPlaceDate string + Gender string + Phone string + Class string + Unit string + Doctor_Name string + StartedAt string + FinishedAt string + DiagnosisIn string + DiagnosisOut string + Diagnosis []er.DiagnosisEntry + MainComplaint string + MedicalHistory string + PhysicalExamination string + SupportingExamination string + MedicalActions []er.ActionEntry + MedicalAction string + Consultations []er.ConsultationEntry + Allergy string + ConsciousnessLevel string + BloodPressure string + BodyTemperature float64 + RespirationRate float64 + HeartRate float64 + PainScale int + ConditionOnDischarge string + DischargeMethod string + Medications []er.MedicationEntry + // fasyankes + // date + // klinik + Date string +} + type GenerateDto struct { EntityType_Code ere.EntityTypeCode `json:"entityType_code" validate:"required"` Ref_Id *string `json:"ref_id" validate:"required"` @@ -83,6 +123,7 @@ type TemplateDocsName string const ( TDNGC TemplateDocsName = "general-consent.html" TDNCL TemplateDocsName = "control-letter.html" + TDNR TemplateDocsName = "resume.html" ) func (v VclaimControlLetter) generateTemplateData() ControlLetterPDF { diff --git a/internal/use-case/main-use-case/infra/case.go b/internal/use-case/main-use-case/infra/case.go index 4771f3cb..f3ba3854 100644 --- a/internal/use-case/main-use-case/infra/case.go +++ b/internal/use-case/main-use-case/infra/case.go @@ -37,7 +37,7 @@ func Create(input e.CreateDto) (*d.Data, error) { return err } - if input.InfraGroup_Code == ero.IFGCRoom { + if input.InfraGroup_Code == ero.IFGCProcedureRoom { if input.Parent_Code == nil { event.Status = "failed" event.ErrInfo = pl.ErrorInfo{ @@ -58,9 +58,9 @@ func Create(input e.CreateDto) (*d.Data, error) { data = *resData } - if input.InfraGroup_Code == ero.IFGCRoom { + if input.InfraGroup_Code == ero.IFGCProcedureRoom { input.Infra_Code = &data.Code - if err := createRoom(&input, &event, tx); err != nil { + if err := createProcedureRoom(&input, &event, tx); err != nil { return err } } diff --git a/internal/use-case/main-use-case/infra/helper.go b/internal/use-case/main-use-case/infra/helper.go index 81de5389..27c5442c 100644 --- a/internal/use-case/main-use-case/infra/helper.go +++ b/internal/use-case/main-use-case/infra/helper.go @@ -7,10 +7,10 @@ package infra import ( e "simrs-vx/internal/domain/main-entities/infra" ei "simrs-vx/internal/domain/main-entities/item" - er "simrs-vx/internal/domain/main-entities/room" + er "simrs-vx/internal/domain/main-entities/procedure-room" ero "simrs-vx/internal/domain/references/organization" ui "simrs-vx/internal/use-case/main-use-case/item" - ur "simrs-vx/internal/use-case/main-use-case/room" + ur "simrs-vx/internal/use-case/main-use-case/procedure-room" pl "simrs-vx/pkg/logger" pu "simrs-vx/pkg/use-case-helper" @@ -53,8 +53,9 @@ func createItem(input *e.CreateDto, event *pl.Event, tx *gorm.DB) error { return nil } -func createRoom(input *e.CreateDto, event *pl.Event, tx *gorm.DB) error { +func createProcedureRoom(input *e.CreateDto, event *pl.Event, tx *gorm.DB) error { roomCreate := er.CreateDto{ + Code: input.Infra_Code, Infra_Code: input.Infra_Code, Unit_Code: input.Unit_Code, Specialist_Code: input.Specialist_Code, diff --git a/internal/use-case/main-use-case/infra/lib.go b/internal/use-case/main-use-case/infra/lib.go index 5e0592c3..cd97d735 100644 --- a/internal/use-case/main-use-case/infra/lib.go +++ b/internal/use-case/main-use-case/infra/lib.go @@ -129,7 +129,7 @@ func UpdateData(input e.UpdateDto, data *e.Infra, event *pl.Event, dbx ...*gorm. // data.Parent = nil data.Childrens = nil data.Item = nil - data.Rooms = nil + data.ProcedureRooms = nil if err := tx.Save(&data).Error; err != nil { event.Status = "failed" diff --git a/internal/use-case/main-use-case/material-package-item/case.go b/internal/use-case/main-use-case/material-package-item/case.go new file mode 100644 index 00000000..ecd891a6 --- /dev/null +++ b/internal/use-case/main-use-case/material-package-item/case.go @@ -0,0 +1,276 @@ +package materialpackageorder + +import ( + e "simrs-vx/internal/domain/main-entities/material-package-item" + "strconv" + + dg "github.com/karincake/apem/db-gorm-pg" + d "github.com/karincake/dodol" + + pl "simrs-vx/pkg/logger" + pu "simrs-vx/pkg/use-case-helper" + + "gorm.io/gorm" +) + +const source = "material" + +func Create(input e.CreateDto) (*d.Data, error) { + data := e.MaterialPackageItem{} + + event := pl.Event{ + Feature: "Create", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "create") + + err := dg.I.Transaction(func(tx *gorm.DB) error { + mwRunner := newMiddlewareRunner(&event, tx) + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil { + return err + } + + if resData, err := CreateData(input, &event, tx); err != nil { + return err + } else { + data = *resData + } + + mwRunner.setMwType(pu.MWTPost) + // Run post-middleware + if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil { + return err + } + + pl.SetLogInfo(&event, nil, "complete") + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.II{ + "source": source, + "structure": "single-data", + "status": "created", + }, + Data: data.ToResponse(), + }, nil +} + +func ReadList(input e.ReadListDto) (*d.Data, error) { + var data *e.MaterialPackageItem + var dataList []e.MaterialPackageItem + var metaList *e.MetaDto + var err error + + event := pl.Event{ + Feature: "ReadList", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "readList") + + err = dg.I.Transaction(func(tx *gorm.DB) error { + mwRunner := newMiddlewareRunner(&event, tx) + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunReadListMiddleware(readListPreMw, &input, data); err != nil { + return err + } + + if dataList, metaList, err = ReadListData(input, &event, tx); err != nil { + return err + } + + mwRunner.setMwType(pu.MWTPost) + // Run post-middleware + if err := mwRunner.RunReadListMiddleware(readListPostMw, &input, data); err != nil { + return err + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "list-data", + "status": "fetched", + "page_number": strconv.Itoa(metaList.PageNumber), + "page_size": strconv.Itoa(metaList.PageSize), + "record_totalCount": strconv.Itoa(metaList.Count), + "record_currentCount": strconv.Itoa(len(dataList)), + }, + Data: e.ToResponseList(dataList), + }, nil +} + +func ReadDetail(input e.ReadDetailDto) (*d.Data, error) { + var data *e.MaterialPackageItem + var err error + + event := pl.Event{ + Feature: "ReadDetail", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "readDetail") + + err = dg.I.Transaction(func(tx *gorm.DB) error { + mwRunner := newMiddlewareRunner(&event, tx) + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunReadDetailMiddleware(readDetailPreMw, &input, data); err != nil { + return err + } + + if data, err = ReadDetailData(input, &event, tx); err != nil { + return err + } + + mwRunner.setMwType(pu.MWTPost) + // Run post-middleware + if err := mwRunner.RunReadDetailMiddleware(readDetailPostMw, &input, data); err != nil { + return err + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "single-data", + "status": "fetched", + }, + Data: data.ToResponse(), + }, nil +} + +func Update(input e.UpdateDto) (*d.Data, error) { + rdDto := e.ReadDetailDto{Id: input.Id} + var data *e.MaterialPackageItem + var err error + + event := pl.Event{ + Feature: "Update", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "update") + + err = dg.I.Transaction(func(tx *gorm.DB) error { + pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail") + if data, err = ReadDetailData(rdDto, &event, tx); err != nil { + return err + } + + mwRunner := newMiddlewareRunner(&event, tx) + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunUpdateMiddleware(readDetailPreMw, &rdDto, data); err != nil { + return err + } + + if err := UpdateData(input, data, &event, tx); err != nil { + return err + } + + pl.SetLogInfo(&event, nil, "complete") + + mwRunner.setMwType(pu.MWTPost) + // Run post-middleware + if err := mwRunner.RunUpdateMiddleware(readDetailPostMw, &rdDto, data); err != nil { + return err + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "single-data", + "status": "updated", + }, + Data: data.ToResponse(), + }, nil + +} + +func Delete(input e.DeleteDto) (*d.Data, error) { + rdDto := e.ReadDetailDto{Id: input.Id} + var data *e.MaterialPackageItem + var err error + + event := pl.Event{ + Feature: "Delete", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "delete") + + err = dg.I.Transaction(func(tx *gorm.DB) error { + pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail") + if data, err = ReadDetailData(rdDto, &event, tx); err != nil { + return err + } + + mwRunner := newMiddlewareRunner(&event, tx) + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunDeleteMiddleware(readDetailPreMw, &rdDto, data); err != nil { + return err + } + + if err := DeleteData(data, &event, tx); err != nil { + return err + } + + mwRunner.setMwType(pu.MWTPost) + // Run post-middleware + if err := mwRunner.RunDeleteMiddleware(readDetailPostMw, &rdDto, data); err != nil { + return err + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "single-data", + "status": "deleted", + }, + Data: data.ToResponse(), + }, nil + +} diff --git a/internal/use-case/main-use-case/material-package-item/helper.go b/internal/use-case/main-use-case/material-package-item/helper.go new file mode 100644 index 00000000..c175f776 --- /dev/null +++ b/internal/use-case/main-use-case/material-package-item/helper.go @@ -0,0 +1,22 @@ +/* +DESCRIPTION: +Any functions that are used internally by the use-case +*/ +package materialpackageorder + +import ( + e "simrs-vx/internal/domain/main-entities/material-package-item" +) + +func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.MaterialPackageItem) { + var inputSrc *e.CreateDto + if inputT, ok := any(input).(*e.CreateDto); ok { + inputSrc = inputT + } else { + inputTemp := any(input).(*e.UpdateDto) + inputSrc = &inputTemp.CreateDto + } + + data.MaterialPackage_Code = inputSrc.MaterialPackage_Code + data.Material_Code = inputSrc.Material_Code +} diff --git a/internal/use-case/main-use-case/material-package-item/lib.go b/internal/use-case/main-use-case/material-package-item/lib.go new file mode 100644 index 00000000..fc469249 --- /dev/null +++ b/internal/use-case/main-use-case/material-package-item/lib.go @@ -0,0 +1,140 @@ +package materialpackageorder + +import ( + e "simrs-vx/internal/domain/main-entities/material-package-item" + + plh "simrs-vx/pkg/lib-helper" + pl "simrs-vx/pkg/logger" + pu "simrs-vx/pkg/use-case-helper" + + dg "github.com/karincake/apem/db-gorm-pg" + gh "github.com/karincake/getuk" + "gorm.io/gorm" +) + +func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.MaterialPackageItem, error) { + pl.SetLogInfo(event, nil, "started", "DBCreate") + + data := e.MaterialPackageItem{} + setData(&input, &data) + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Create(&data).Error; err != nil { + return nil, plh.HandleCreateError(input, event, err) + } + + pl.SetLogInfo(event, nil, "complete") + return &data, nil +} + +func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.MaterialPackageItem, *e.MetaDto, error) { + pl.SetLogInfo(event, input, "started", "DBReadList") + data := []e.MaterialPackageItem{} + pagination := gh.Pagination{} + count := int64(0) + meta := e.MetaDto{} + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + tx = tx. + Model(&e.MaterialPackageItem{}). + Scopes(gh.Preload(input.Includes)). + Scopes(gh.Filter(input.FilterDto)). + Count(&count). + Scopes(gh.Paginate(input, &pagination)). + Scopes(gh.Sort(input.Sort)) + + if err := tx.Find(&data).Error; err != nil { + if err == gorm.ErrRecordNotFound { + return nil, &meta, nil + } + return nil, nil, plh.HandleListError(input, event, err) + } + + meta.Count = int(count) + meta.PageNumber = pagination.PageNumber + meta.PageSize = pagination.PageSize + + pl.SetLogInfo(event, nil, "complete") + return data, &meta, nil +} + +func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.MaterialPackageItem, error) { + pl.SetLogInfo(event, input, "started", "DBReadDetail") + data := e.MaterialPackageItem{} + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.First(&data, input.Id).Error; err != nil { + if processedErr := pu.HandleReadError(err, event, source, input.Id, data); processedErr != nil { + return nil, processedErr + } + } + + pl.SetLogInfo(event, nil, "complete") + return &data, nil +} + +func UpdateData(input e.UpdateDto, data *e.MaterialPackageItem, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, data, "started", "DBUpdate") + setData(&input, data) + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Save(&data).Error; err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-update-fail", + Detail: "Database update failed", + Raw: err, + } + return pl.SetLogError(event, input) + } + + pl.SetLogInfo(event, nil, "complete") + return nil +} + +func DeleteData(data *e.MaterialPackageItem, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, data, "started", "DBDelete") + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Delete(&data).Error; err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-delete-fail", + Detail: "Database delete failed", + Raw: err, + } + return pl.SetLogError(event, data) + } + + pl.SetLogInfo(event, nil, "complete") + return nil +} diff --git a/internal/use-case/main-use-case/material-package-item/middleware-runner.go b/internal/use-case/main-use-case/material-package-item/middleware-runner.go new file mode 100644 index 00000000..09dfb39b --- /dev/null +++ b/internal/use-case/main-use-case/material-package-item/middleware-runner.go @@ -0,0 +1,103 @@ +package materialpackageorder + +import ( + e "simrs-vx/internal/domain/main-entities/material-package-item" + 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.MaterialPackageItem) 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.MaterialPackageItem) 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.MaterialPackageItem) 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.MaterialPackageItem) 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.MaterialPackageItem) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) setMwType(mwType pu.MWType) { + me.MwType = mwType +} diff --git a/internal/use-case/main-use-case/material-package-item/middleware.go b/internal/use-case/main-use-case/material-package-item/middleware.go new file mode 100644 index 00000000..1d1186af --- /dev/null +++ b/internal/use-case/main-use-case/material-package-item/middleware.go @@ -0,0 +1,9 @@ +package materialpackageorder + +// example of middleware +// func init() { +// createPreMw = append(createPreMw, +// CreateMw{Name: "modif-input", Func: pm.ModifInput}, +// CreateMw{Name: "check-data", Func: pm.CheckData}, +// ) +// } diff --git a/internal/use-case/main-use-case/material-package-item/tycovar.go b/internal/use-case/main-use-case/material-package-item/tycovar.go new file mode 100644 index 00000000..a7e239f1 --- /dev/null +++ b/internal/use-case/main-use-case/material-package-item/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 materialpackageorder + +import ( + "gorm.io/gorm" + + e "simrs-vx/internal/domain/main-entities/material-package-item" +) + +type createMw struct { + Name string + Func func(input *e.CreateDto, data *e.MaterialPackageItem, tx *gorm.DB) error +} + +type readListMw struct { + Name string + Func func(input *e.ReadListDto, data *e.MaterialPackageItem, tx *gorm.DB) error +} + +type readDetailMw struct { + Name string + Func func(input *e.ReadDetailDto, data *e.MaterialPackageItem, tx *gorm.DB) error +} + +type UpdateMw = readDetailMw +type DeleteMw = readDetailMw + +var createPreMw []createMw // preprocess middleware +var createPostMw []createMw // postprocess middleware +var readListPreMw []readListMw // .. +var readListPostMw []readListMw // .. +var readDetailPreMw []readDetailMw +var readDetailPostMw []readDetailMw +var updatePreMw []readDetailMw +var updatePostMw []readDetailMw +var deletePreMw []readDetailMw +var deletePostMw []readDetailMw diff --git a/internal/use-case/main-use-case/material-package/case.go b/internal/use-case/main-use-case/material-package/case.go new file mode 100644 index 00000000..5e56517b --- /dev/null +++ b/internal/use-case/main-use-case/material-package/case.go @@ -0,0 +1,276 @@ +package materialpackage + +import ( + e "simrs-vx/internal/domain/main-entities/material-package" + "strconv" + + dg "github.com/karincake/apem/db-gorm-pg" + d "github.com/karincake/dodol" + + pl "simrs-vx/pkg/logger" + pu "simrs-vx/pkg/use-case-helper" + + "gorm.io/gorm" +) + +const source = "material" + +func Create(input e.CreateDto) (*d.Data, error) { + data := e.MaterialPackage{} + + event := pl.Event{ + Feature: "Create", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "create") + + err := dg.I.Transaction(func(tx *gorm.DB) error { + mwRunner := newMiddlewareRunner(&event, tx) + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil { + return err + } + + if resData, err := CreateData(input, &event, tx); err != nil { + return err + } else { + data = *resData + } + + mwRunner.setMwType(pu.MWTPost) + // Run post-middleware + if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil { + return err + } + + pl.SetLogInfo(&event, nil, "complete") + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.II{ + "source": source, + "structure": "single-data", + "status": "created", + }, + Data: data.ToResponse(), + }, nil +} + +func ReadList(input e.ReadListDto) (*d.Data, error) { + var data *e.MaterialPackage + var dataList []e.MaterialPackage + var metaList *e.MetaDto + var err error + + event := pl.Event{ + Feature: "ReadList", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "readList") + + err = dg.I.Transaction(func(tx *gorm.DB) error { + mwRunner := newMiddlewareRunner(&event, tx) + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunReadListMiddleware(readListPreMw, &input, data); err != nil { + return err + } + + if dataList, metaList, err = ReadListData(input, &event, tx); err != nil { + return err + } + + mwRunner.setMwType(pu.MWTPost) + // Run post-middleware + if err := mwRunner.RunReadListMiddleware(readListPostMw, &input, data); err != nil { + return err + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "list-data", + "status": "fetched", + "page_number": strconv.Itoa(metaList.PageNumber), + "page_size": strconv.Itoa(metaList.PageSize), + "record_totalCount": strconv.Itoa(metaList.Count), + "record_currentCount": strconv.Itoa(len(dataList)), + }, + Data: e.ToResponseList(dataList), + }, nil +} + +func ReadDetail(input e.ReadDetailDto) (*d.Data, error) { + var data *e.MaterialPackage + var err error + + event := pl.Event{ + Feature: "ReadDetail", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "readDetail") + + err = dg.I.Transaction(func(tx *gorm.DB) error { + mwRunner := newMiddlewareRunner(&event, tx) + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunReadDetailMiddleware(readDetailPreMw, &input, data); err != nil { + return err + } + + if data, err = ReadDetailData(input, &event, tx); err != nil { + return err + } + + mwRunner.setMwType(pu.MWTPost) + // Run post-middleware + if err := mwRunner.RunReadDetailMiddleware(readDetailPostMw, &input, data); err != nil { + return err + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "single-data", + "status": "fetched", + }, + Data: data.ToResponse(), + }, nil +} + +func Update(input e.UpdateDto) (*d.Data, error) { + rdDto := e.ReadDetailDto{Code: &input.Code} + var data *e.MaterialPackage + var err error + + event := pl.Event{ + Feature: "Update", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "update") + + err = dg.I.Transaction(func(tx *gorm.DB) error { + pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail") + if data, err = ReadDetailData(rdDto, &event, tx); err != nil { + return err + } + + mwRunner := newMiddlewareRunner(&event, tx) + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunUpdateMiddleware(readDetailPreMw, &rdDto, data); err != nil { + return err + } + + if err := UpdateData(input, data, &event, tx); err != nil { + return err + } + + pl.SetLogInfo(&event, nil, "complete") + + mwRunner.setMwType(pu.MWTPost) + // Run post-middleware + if err := mwRunner.RunUpdateMiddleware(readDetailPostMw, &rdDto, data); err != nil { + return err + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "single-data", + "status": "updated", + }, + Data: data.ToResponse(), + }, nil + +} + +func Delete(input e.DeleteDto) (*d.Data, error) { + rdDto := e.ReadDetailDto{Code: input.Code} + var data *e.MaterialPackage + var err error + + event := pl.Event{ + Feature: "Delete", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "delete") + + err = dg.I.Transaction(func(tx *gorm.DB) error { + pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail") + if data, err = ReadDetailData(rdDto, &event, tx); err != nil { + return err + } + + mwRunner := newMiddlewareRunner(&event, tx) + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunDeleteMiddleware(readDetailPreMw, &rdDto, data); err != nil { + return err + } + + if err := DeleteData(data, &event, tx); err != nil { + return err + } + + mwRunner.setMwType(pu.MWTPost) + // Run post-middleware + if err := mwRunner.RunDeleteMiddleware(readDetailPostMw, &rdDto, data); err != nil { + return err + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "single-data", + "status": "deleted", + }, + Data: data.ToResponse(), + }, nil + +} diff --git a/internal/use-case/main-use-case/material-package/helper.go b/internal/use-case/main-use-case/material-package/helper.go new file mode 100644 index 00000000..7d8e7a9a --- /dev/null +++ b/internal/use-case/main-use-case/material-package/helper.go @@ -0,0 +1,22 @@ +/* +DESCRIPTION: +Any functions that are used internally by the use-case +*/ +package materialpackage + +import ( + e "simrs-vx/internal/domain/main-entities/material-package" +) + +func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.MaterialPackage) { + var inputSrc *e.CreateDto + if inputT, ok := any(input).(*e.CreateDto); ok { + inputSrc = inputT + } else { + inputTemp := any(input).(*e.UpdateDto) + inputSrc = &inputTemp.CreateDto + } + + data.Code = inputSrc.Code + data.Name = inputSrc.Name +} diff --git a/internal/use-case/main-use-case/material-package/lib.go b/internal/use-case/main-use-case/material-package/lib.go new file mode 100644 index 00000000..d4d6ac50 --- /dev/null +++ b/internal/use-case/main-use-case/material-package/lib.go @@ -0,0 +1,146 @@ +package materialpackage + +import ( + e "simrs-vx/internal/domain/main-entities/material-package" + + plh "simrs-vx/pkg/lib-helper" + pl "simrs-vx/pkg/logger" + pu "simrs-vx/pkg/use-case-helper" + + dg "github.com/karincake/apem/db-gorm-pg" + gh "github.com/karincake/getuk" + "gorm.io/gorm" +) + +func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.MaterialPackage, error) { + pl.SetLogInfo(event, nil, "started", "DBCreate") + + data := e.MaterialPackage{} + setData(&input, &data) + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Create(&data).Error; err != nil { + return nil, plh.HandleCreateError(input, event, err) + } + + pl.SetLogInfo(event, nil, "complete") + return &data, nil +} + +func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.MaterialPackage, *e.MetaDto, error) { + pl.SetLogInfo(event, input, "started", "DBReadList") + data := []e.MaterialPackage{} + pagination := gh.Pagination{} + count := int64(0) + meta := e.MetaDto{} + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + tx = tx. + Model(&e.MaterialPackage{}). + Scopes(gh.Preload(input.Includes)). + Scopes(gh.Filter(input.FilterDto)). + Count(&count). + Scopes(gh.Paginate(input, &pagination)). + Scopes(gh.Sort(input.Sort)) + + if err := tx.Find(&data).Error; err != nil { + if err == gorm.ErrRecordNotFound { + return nil, &meta, nil + } + return nil, nil, plh.HandleListError(input, event, err) + } + + meta.Count = int(count) + meta.PageNumber = pagination.PageNumber + meta.PageSize = pagination.PageSize + + pl.SetLogInfo(event, nil, "complete") + return data, &meta, nil +} + +func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.MaterialPackage, error) { + pl.SetLogInfo(event, input, "started", "DBReadDetail") + data := e.MaterialPackage{} + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if input.Code != nil { + tx = tx.Where("\"Code\" = ?", *input.Code) + } else { + tx = tx.Where("\"Id\" = ?", *input.Id) + } + + if err := tx.First(&data).Error; err != nil { + if processedErr := pu.HandleReadError(err, event, source, input.Id, data); processedErr != nil { + return nil, processedErr + } + } + + pl.SetLogInfo(event, nil, "complete") + return &data, nil +} + +func UpdateData(input e.UpdateDto, data *e.MaterialPackage, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, data, "started", "DBUpdate") + setData(&input, data) + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Save(&data).Error; err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-update-fail", + Detail: "Database update failed", + Raw: err, + } + return pl.SetLogError(event, input) + } + + pl.SetLogInfo(event, nil, "complete") + return nil +} + +func DeleteData(data *e.MaterialPackage, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, data, "started", "DBDelete") + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Delete(&data).Error; err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-delete-fail", + Detail: "Database delete failed", + Raw: err, + } + return pl.SetLogError(event, data) + } + + pl.SetLogInfo(event, nil, "complete") + return nil +} diff --git a/internal/use-case/main-use-case/material-package/middleware-runner.go b/internal/use-case/main-use-case/material-package/middleware-runner.go new file mode 100644 index 00000000..b1ea182c --- /dev/null +++ b/internal/use-case/main-use-case/material-package/middleware-runner.go @@ -0,0 +1,103 @@ +package materialpackage + +import ( + e "simrs-vx/internal/domain/main-entities/material-package" + 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.MaterialPackage) 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.MaterialPackage) 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.MaterialPackage) 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.MaterialPackage) 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.MaterialPackage) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) setMwType(mwType pu.MWType) { + me.MwType = mwType +} diff --git a/internal/use-case/main-use-case/material-package/middleware.go b/internal/use-case/main-use-case/material-package/middleware.go new file mode 100644 index 00000000..85020e68 --- /dev/null +++ b/internal/use-case/main-use-case/material-package/middleware.go @@ -0,0 +1,9 @@ +package materialpackage + +// example of middleware +// func init() { +// createPreMw = append(createPreMw, +// CreateMw{Name: "modif-input", Func: pm.ModifInput}, +// CreateMw{Name: "check-data", Func: pm.CheckData}, +// ) +// } diff --git a/internal/use-case/main-use-case/material-package/tycovar.go b/internal/use-case/main-use-case/material-package/tycovar.go new file mode 100644 index 00000000..67aa3174 --- /dev/null +++ b/internal/use-case/main-use-case/material-package/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 materialpackage + +import ( + "gorm.io/gorm" + + e "simrs-vx/internal/domain/main-entities/material-package" +) + +type createMw struct { + Name string + Func func(input *e.CreateDto, data *e.MaterialPackage, tx *gorm.DB) error +} + +type readListMw struct { + Name string + Func func(input *e.ReadListDto, data *e.MaterialPackage, tx *gorm.DB) error +} + +type readDetailMw struct { + Name string + Func func(input *e.ReadDetailDto, data *e.MaterialPackage, tx *gorm.DB) error +} + +type UpdateMw = readDetailMw +type DeleteMw = readDetailMw + +var createPreMw []createMw // preprocess middleware +var createPostMw []createMw // postprocess middleware +var readListPreMw []readListMw // .. +var readListPostMw []readListMw // .. +var readDetailPreMw []readDetailMw +var readDetailPostMw []readDetailMw +var updatePreMw []readDetailMw +var updatePostMw []readDetailMw +var deletePreMw []readDetailMw +var deletePostMw []readDetailMw diff --git a/internal/use-case/main-use-case/mcu-order-item/case.go b/internal/use-case/main-use-case/mcu-order-item/case.go index 9037b771..e04feded 100644 --- a/internal/use-case/main-use-case/mcu-order-item/case.go +++ b/internal/use-case/main-use-case/mcu-order-item/case.go @@ -4,11 +4,7 @@ import ( "errors" "strconv" - e "simrs-vx/internal/domain/main-entities/mcu-order-item" - - umo "simrs-vx/internal/use-case/main-use-case/mcu-order" - - erc "simrs-vx/internal/domain/references/common" + "gorm.io/gorm" dg "github.com/karincake/apem/db-gorm-pg" d "github.com/karincake/dodol" @@ -16,7 +12,10 @@ import ( pl "simrs-vx/pkg/logger" pu "simrs-vx/pkg/use-case-helper" - "gorm.io/gorm" + e "simrs-vx/internal/domain/main-entities/mcu-order-item" + erc "simrs-vx/internal/domain/references/common" + + umo "simrs-vx/internal/use-case/main-use-case/mcu-order" ) const source = "mcu-order-item" diff --git a/internal/use-case/main-use-case/room/case.go b/internal/use-case/main-use-case/procedure-room/case.go similarity index 95% rename from internal/use-case/main-use-case/room/case.go rename to internal/use-case/main-use-case/procedure-room/case.go index eeb1cce1..0378b759 100644 --- a/internal/use-case/main-use-case/room/case.go +++ b/internal/use-case/main-use-case/procedure-room/case.go @@ -1,7 +1,7 @@ -package room +package procedureroom import ( - e "simrs-vx/internal/domain/main-entities/room" + e "simrs-vx/internal/domain/main-entities/procedure-room" "strconv" dg "github.com/karincake/apem/db-gorm-pg" @@ -16,7 +16,7 @@ import ( const source = "specialist" func Create(input e.CreateDto) (*d.Data, error) { - data := e.Room{} + data := e.ProcedureRoom{} event := pl.Event{ Feature: "Create", @@ -66,8 +66,8 @@ func Create(input e.CreateDto) (*d.Data, error) { } func ReadList(input e.ReadListDto) (*d.Data, error) { - var data *e.Room - var dataList []e.Room + var data *e.ProcedureRoom + var dataList []e.ProcedureRoom var metaList *e.MetaDto var err error @@ -119,7 +119,7 @@ func ReadList(input e.ReadListDto) (*d.Data, error) { } func ReadDetail(input e.ReadDetailDto) (*d.Data, error) { - var data *e.Room + var data *e.ProcedureRoom var err error event := pl.Event{ @@ -167,7 +167,7 @@ func ReadDetail(input e.ReadDetailDto) (*d.Data, error) { func Update(input e.UpdateDto) (*d.Data, error) { rdDto := e.ReadDetailDto{Id: uint16(input.Id)} - var data *e.Room + var data *e.ProcedureRoom var err error event := pl.Event{ @@ -223,7 +223,7 @@ func Update(input e.UpdateDto) (*d.Data, error) { func Delete(input e.DeleteDto) (*d.Data, error) { rdDto := e.ReadDetailDto{Id: uint16(input.Id)} - var data *e.Room + var data *e.ProcedureRoom var err error event := pl.Event{ diff --git a/internal/use-case/main-use-case/room/helper.go b/internal/use-case/main-use-case/procedure-room/helper.go similarity index 70% rename from internal/use-case/main-use-case/room/helper.go rename to internal/use-case/main-use-case/procedure-room/helper.go index 5e97a653..0101efef 100644 --- a/internal/use-case/main-use-case/room/helper.go +++ b/internal/use-case/main-use-case/procedure-room/helper.go @@ -2,13 +2,13 @@ DESCRIPTION: Any functions that are used internally by the use-case */ -package room +package procedureroom import ( - e "simrs-vx/internal/domain/main-entities/room" + e "simrs-vx/internal/domain/main-entities/procedure-room" ) -func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Room) { +func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.ProcedureRoom) { var inputSrc *e.CreateDto if inputT, ok := any(input).(*e.CreateDto); ok { inputSrc = inputT @@ -17,6 +17,7 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Room) { inputSrc = &inputTemp.CreateDto } + data.Code = *inputSrc.Infra_Code data.Infra_Code = inputSrc.Infra_Code data.Unit_Code = inputSrc.Unit_Code data.Specialist_Code = inputSrc.Specialist_Code diff --git a/internal/use-case/main-use-case/procedure-room/lib.go b/internal/use-case/main-use-case/procedure-room/lib.go new file mode 100644 index 00000000..f9e46d17 --- /dev/null +++ b/internal/use-case/main-use-case/procedure-room/lib.go @@ -0,0 +1,140 @@ +package procedureroom + +import ( + e "simrs-vx/internal/domain/main-entities/procedure-room" + + plh "simrs-vx/pkg/lib-helper" + pl "simrs-vx/pkg/logger" + pu "simrs-vx/pkg/use-case-helper" + + dg "github.com/karincake/apem/db-gorm-pg" + gh "github.com/karincake/getuk" + "gorm.io/gorm" +) + +func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.ProcedureRoom, error) { + pl.SetLogInfo(event, nil, "started", "DBCreate") + + data := e.ProcedureRoom{} + setData(&input, &data) + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Create(&data).Error; err != nil { + return nil, plh.HandleCreateError(input, event, err) + } + + pl.SetLogInfo(event, nil, "complete") + return &data, nil +} + +func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.ProcedureRoom, *e.MetaDto, error) { + pl.SetLogInfo(event, input, "started", "DBReadList") + data := []e.ProcedureRoom{} + pagination := gh.Pagination{} + count := int64(0) + meta := e.MetaDto{} + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + tx = tx. + Model(&e.ProcedureRoom{}). + Scopes(gh.Preload(input.Includes)). + Scopes(gh.Filter(input.FilterDto)). + Count(&count). + Scopes(gh.Paginate(input, &pagination)). + Order("\"CreatedAt\" DESC") + + if err := tx.Find(&data).Error; err != nil { + if err == gorm.ErrRecordNotFound { + return nil, &meta, nil + } + return nil, nil, plh.HandleListError(input, event, err) + } + + meta.Count = int(count) + meta.PageNumber = pagination.PageNumber + meta.PageSize = pagination.PageSize + + pl.SetLogInfo(event, nil, "complete") + return data, &meta, nil +} + +func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.ProcedureRoom, error) { + pl.SetLogInfo(event, input, "started", "DBReadDetail") + data := e.ProcedureRoom{} + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.First(&data, input.Id).Error; err != nil { + if processedErr := pu.HandleReadError(err, event, source, input.Id, data); processedErr != nil { + return nil, processedErr + } + } + + pl.SetLogInfo(event, nil, "complete") + return &data, nil +} + +func UpdateData(input e.UpdateDto, data *e.ProcedureRoom, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, data, "started", "DBUpdate") + setData(&input, data) + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Save(&data).Error; err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-update-fail", + Detail: "Database update failed", + Raw: err, + } + return pl.SetLogError(event, input) + } + + pl.SetLogInfo(event, nil, "complete") + return nil +} + +func DeleteData(data *e.ProcedureRoom, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, data, "started", "DBDelete") + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Delete(&data).Error; err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-delete-fail", + Detail: "Database delete failed", + Raw: err, + } + return pl.SetLogError(event, data) + } + + pl.SetLogInfo(event, nil, "complete") + return nil +} diff --git a/internal/use-case/main-use-case/procedure-room/middleware-runner.go b/internal/use-case/main-use-case/procedure-room/middleware-runner.go new file mode 100644 index 00000000..bc96f5c6 --- /dev/null +++ b/internal/use-case/main-use-case/procedure-room/middleware-runner.go @@ -0,0 +1,103 @@ +package procedureroom + +import ( + e "simrs-vx/internal/domain/main-entities/procedure-room" + 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.ProcedureRoom) 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.ProcedureRoom) 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.ProcedureRoom) 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.ProcedureRoom) 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.ProcedureRoom) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) setMwType(mwType pu.MWType) { + me.MwType = mwType +} diff --git a/internal/use-case/main-use-case/procedure-room/middleware.go b/internal/use-case/main-use-case/procedure-room/middleware.go new file mode 100644 index 00000000..c30fa7b1 --- /dev/null +++ b/internal/use-case/main-use-case/procedure-room/middleware.go @@ -0,0 +1,9 @@ +package procedureroom + +// example of middleware +// func init() { +// createPreMw = append(createPreMw, +// CreateMw{Name: "modif-input", Func: pm.ModifInput}, +// CreateMw{Name: "check-data", Func: pm.CheckData}, +// ) +// } diff --git a/internal/use-case/main-use-case/procedure-room/tycovar.go b/internal/use-case/main-use-case/procedure-room/tycovar.go new file mode 100644 index 00000000..ab9f660b --- /dev/null +++ b/internal/use-case/main-use-case/procedure-room/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 procedureroom + +import ( + "gorm.io/gorm" + + e "simrs-vx/internal/domain/main-entities/procedure-room" +) + +type createMw struct { + Name string + Func func(input *e.CreateDto, data *e.ProcedureRoom, tx *gorm.DB) error +} + +type readListMw struct { + Name string + Func func(input *e.ReadListDto, data *e.ProcedureRoom, tx *gorm.DB) error +} + +type readDetailMw struct { + Name string + Func func(input *e.ReadDetailDto, data *e.ProcedureRoom, tx *gorm.DB) error +} + +type UpdateMw = readDetailMw +type DeleteMw = readDetailMw + +var createPreMw []createMw // preprocess middleware +var createPostMw []createMw // postprocess middleware +var readListPreMw []readListMw // .. +var readListPostMw []readListMw // .. +var readDetailPreMw []readDetailMw +var readDetailPostMw []readDetailMw +var updatePreMw []readDetailMw +var updatePostMw []readDetailMw +var deletePreMw []readDetailMw +var deletePostMw []readDetailMw diff --git a/internal/use-case/main-use-case/resume/case.go b/internal/use-case/main-use-case/resume/case.go new file mode 100644 index 00000000..8f771794 --- /dev/null +++ b/internal/use-case/main-use-case/resume/case.go @@ -0,0 +1,391 @@ +package resume + +import ( + "errors" + "strconv" + + erc "simrs-vx/internal/domain/references/common" + + // main entities + ee "simrs-vx/internal/domain/main-entities/encounter" + e "simrs-vx/internal/domain/main-entities/resume" + + ue "simrs-vx/internal/use-case/main-use-case/encounter" + + pl "simrs-vx/pkg/logger" + pu "simrs-vx/pkg/use-case-helper" + + dg "github.com/karincake/apem/db-gorm-pg" + d "github.com/karincake/dodol" + "gorm.io/gorm" +) + +const source = "resume" + +func Create(input e.CreateDto) (*d.Data, error) { + data := e.Resume{} + + event := pl.Event{ + Feature: "Create", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "create") + + err := dg.I.Transaction(func(tx *gorm.DB) error { + if !input.AuthInfo.IsDoctor() { + return errors.New("user is not a doctor") + } + + mwRunner := newMiddlewareRunner(&event, tx) + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil { + return err + } + + // check if encounter is done + if ue.IsDone(*input.Encounter_Id, &event, tx) { + return errors.New("encounter is already done") + } + + if resData, err := CreateData(input, &event, tx); err != nil { + return err + } else { + data = *resData + } + + mwRunner.setMwType(pu.MWTPost) + // Run post-middleware + if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil { + return err + } + + pl.SetLogInfo(&event, nil, "complete") + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.II{ + "source": source, + "structure": "single-data", + "status": "created", + }, + Data: data.ToResponse(), + }, nil +} + +func ReadList(input e.ReadListDto) (*d.Data, error) { + var data *e.Resume + var dataList []e.Resume + var metaList *e.MetaDto + var err error + + event := pl.Event{ + Feature: "ReadList", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "readList") + + err = dg.I.Transaction(func(tx *gorm.DB) error { + mwRunner := newMiddlewareRunner(&event, tx) + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunReadListMiddleware(readListPreMw, &input, data); err != nil { + return err + } + + if dataList, metaList, err = ReadListData(input, &event, tx); err != nil { + return err + } + + mwRunner.setMwType(pu.MWTPost) + // Run post-middleware + if err := mwRunner.RunReadListMiddleware(readListPostMw, &input, data); err != nil { + return err + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "list-data", + "status": "fetched", + "page_number": strconv.Itoa(metaList.PageNumber), + "page_size": strconv.Itoa(metaList.PageSize), + "record_totalCount": strconv.Itoa(metaList.Count), + "record_currentCount": strconv.Itoa(len(dataList)), + }, + Data: e.ToResponseList(dataList), + }, nil +} + +func ReadDetail(input e.ReadDetailDto) (*d.Data, error) { + var data *e.Resume + var err error + + event := pl.Event{ + Feature: "ReadDetail", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "readDetail") + + err = dg.I.Transaction(func(tx *gorm.DB) error { + mwRunner := newMiddlewareRunner(&event, tx) + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunReadDetailMiddleware(readDetailPreMw, &input, data); err != nil { + return err + } + + if data, err = ReadDetailData(input, &event, tx); err != nil { + return err + } + + mwRunner.setMwType(pu.MWTPost) + // Run post-middleware + if err := mwRunner.RunReadDetailMiddleware(readDetailPostMw, &input, data); err != nil { + return err + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "single-data", + "status": "fetched", + }, + Data: data.ToResponse(), + }, nil +} + +func Update(input e.UpdateDto) (*d.Data, error) { + rdDto := e.ReadDetailDto{Id: input.Id} + var data *e.Resume + var err error + + event := pl.Event{ + Feature: "Update", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "update") + + err = dg.I.Transaction(func(tx *gorm.DB) error { + if !input.AuthInfo.IsDoctor() { + return errors.New("user is not a doctor") + } + + pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail") + if data, err = ReadDetailData(rdDto, &event, tx); err != nil { + return err + } + + mwRunner := newMiddlewareRunner(&event, tx) + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunUpdateMiddleware(readDetailPreMw, &rdDto, data); err != nil { + return err + } + + // check if encounter is done + if ue.IsDone(*input.Encounter_Id, &event, tx) { + return errors.New("encounter is already done") + } + + if err := UpdateData(input, data, &event, tx); err != nil { + return err + } + + // Get Updated Data + if data, err = ReadDetailData(rdDto, &event, tx); err != nil { + return err + } + + pl.SetLogInfo(&event, nil, "complete") + + mwRunner.setMwType(pu.MWTPost) + // Run post-middleware + if err := mwRunner.RunUpdateMiddleware(readDetailPostMw, &rdDto, data); err != nil { + return err + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "single-data", + "status": "updated", + }, + Data: data.ToResponse(), + }, nil + +} + +func Delete(input e.DeleteDto) (*d.Data, error) { + rdDto := e.ReadDetailDto{Id: uint(input.Id)} + var data *e.Resume + var err error + + event := pl.Event{ + Feature: "Delete", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "delete") + + err = dg.I.Transaction(func(tx *gorm.DB) error { + if !input.AuthInfo.IsDoctor() { + return errors.New("user is not a doctor") + } + + pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail") + if data, err = ReadDetailData(rdDto, &event, tx); err != nil { + return err + } + + mwRunner := newMiddlewareRunner(&event, tx) + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunDeleteMiddleware(readDetailPreMw, &rdDto, data); err != nil { + return err + } + + if err := DeleteData(data, &event, tx); err != nil { + return err + } + + mwRunner.setMwType(pu.MWTPost) + // Run post-middleware + if err := mwRunner.RunDeleteMiddleware(readDetailPostMw, &rdDto, data); err != nil { + return err + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "single-data", + "status": "deleted", + }, + Data: data.ToResponse(), + }, nil + +} + +func UpdateStatusCode(input e.UpdateDto) (*d.Data, error) { + rdDto := e.ReadDetailDto{Id: input.Id} + var data *e.Resume + var err error + + event := pl.Event{ + Feature: "UpdateStatusCode", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "updateStatusCode") + + err = dg.I.Transaction(func(tx *gorm.DB) error { + if !input.AuthInfo.IsDoctor() { + return errors.New("user is not a doctor") + } + + pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail") + if data, err = ReadDetailData(rdDto, &event, tx); err != nil { + return err + } + + enc, err := ue.ReadDetailData(ee.ReadDetailDto{Id: *data.Encounter_Id}, &event, tx) + if err != nil { + return err + } + + // check if encounter is done + if enc.IsDone() { + return errors.New("encounter is already done") + } + + switch input.Status_Code { + case erc.DVCValidated: + if data.IsNew() { + return errors.New("resume need to be verified first") + } + if data.IsValidated() { + return errors.New("resume already validated") + } + if !enc.IsSameResponsibleDoctor(input.AuthInfo.Doctor_Code) { + return errors.New("validation doctor is not the same as encounter responsible doctor") + } + + data.Status_Code = erc.DVCValidated + err = tx.Save(&data).Error + if err != nil { + return err + } + case erc.DVCVerified: + if data.IsValidated() { + return errors.New("resume already validated") + } + if data.IsVerified() { + return errors.New("resume already verified") + } + data.Status_Code = erc.DVCVerified + err = tx.Save(&data).Error + if err != nil { + return err + } + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "single-data", + "status": "updated", + }, + Data: data.ToResponse(), + }, nil +} diff --git a/internal/use-case/main-use-case/resume/helper.go b/internal/use-case/main-use-case/resume/helper.go new file mode 100644 index 00000000..794ae214 --- /dev/null +++ b/internal/use-case/main-use-case/resume/helper.go @@ -0,0 +1,26 @@ +/* +DESCRIPTION: +Any functions that are used internally by the use-case +*/ +package resume + +import ( + e "simrs-vx/internal/domain/main-entities/resume" + + erc "simrs-vx/internal/domain/references/common" +) + +func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Resume) { + var inputSrc *e.CreateDto + if inputT, ok := any(input).(*e.CreateDto); ok { + inputSrc = inputT + data.Status_Code = erc.DVCNew + } else { + inputTemp := any(input).(*e.UpdateDto) + inputSrc = &inputTemp.CreateDto + } + + data.Encounter_Id = inputSrc.Encounter_Id + data.Doctor_Code = inputSrc.AuthInfo.Doctor_Code + data.Value = inputSrc.Value +} diff --git a/internal/use-case/main-use-case/resume/lib.go b/internal/use-case/main-use-case/resume/lib.go new file mode 100644 index 00000000..02a2e27a --- /dev/null +++ b/internal/use-case/main-use-case/resume/lib.go @@ -0,0 +1,140 @@ +package resume + +import ( + "errors" + e "simrs-vx/internal/domain/main-entities/resume" + plh "simrs-vx/pkg/lib-helper" + pl "simrs-vx/pkg/logger" + pu "simrs-vx/pkg/use-case-helper" + + dg "github.com/karincake/apem/db-gorm-pg" + gh "github.com/karincake/getuk" + "gorm.io/gorm" +) + +func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Resume, error) { + pl.SetLogInfo(event, nil, "started", "DBCreate") + + data := e.Resume{} + setData(&input, &data) + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Create(&data).Error; err != nil { + return nil, plh.HandleCreateError(input, event, err) + } + + pl.SetLogInfo(event, nil, "complete") + return &data, nil +} + +func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Resume, *e.MetaDto, error) { + pl.SetLogInfo(event, input, "started", "DBReadList") + data := []e.Resume{} + pagination := gh.Pagination{} + count := int64(0) + meta := e.MetaDto{} + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + tx = tx. + Model(&e.Resume{}). + Scopes(gh.Preload(input.Includes)). + Scopes(gh.Filter(input.FilterDto)). + Count(&count). + Scopes(gh.Paginate(input, &pagination)). + Order("\"CreatedAt\" DESC") + + if err := tx.Find(&data).Error; err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, &meta, nil + } + return nil, nil, plh.HandleListError(input, event, err) + } + + meta.Count = int(count) + meta.PageNumber = pagination.PageNumber + meta.PageSize = pagination.PageSize + + pl.SetLogInfo(event, nil, "complete") + return data, &meta, nil +} + +func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.Resume, error) { + pl.SetLogInfo(event, input, "started", "DBReadDetail") + data := e.Resume{} + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Scopes(gh.Preload(input.Includes)).First(&data, input.Id).Error; err != nil { + if processedErr := pu.HandleReadError(err, event, source, input.Id, data); processedErr != nil { + return nil, processedErr + } + } + + pl.SetLogInfo(event, nil, "complete") + return &data, nil +} + +func UpdateData(input e.UpdateDto, data *e.Resume, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, data, "started", "DBUpdate") + setData(&input, data) + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Save(&data).Error; err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-update-fail", + Detail: "Database update failed", + Raw: err, + } + return pl.SetLogError(event, input) + } + + pl.SetLogInfo(event, nil, "complete") + return nil +} + +func DeleteData(data *e.Resume, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, data, "started", "DBDelete") + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Delete(&data).Error; err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-delete-fail", + Detail: "Database delete failed", + Raw: err, + } + return pl.SetLogError(event, data) + } + + pl.SetLogInfo(event, nil, "complete") + return nil +} diff --git a/internal/use-case/main-use-case/room/middleware-runner.go b/internal/use-case/main-use-case/resume/middleware-runner.go similarity index 88% rename from internal/use-case/main-use-case/room/middleware-runner.go rename to internal/use-case/main-use-case/resume/middleware-runner.go index eaeb46fd..e7f4cade 100644 --- a/internal/use-case/main-use-case/room/middleware-runner.go +++ b/internal/use-case/main-use-case/resume/middleware-runner.go @@ -1,7 +1,7 @@ -package room +package resume import ( - e "simrs-vx/internal/domain/main-entities/room" + e "simrs-vx/internal/domain/main-entities/resume" pl "simrs-vx/pkg/logger" pu "simrs-vx/pkg/use-case-helper" @@ -23,7 +23,7 @@ func newMiddlewareRunner(event *pl.Event, tx *gorm.DB) *middlewareRunner { } // ExecuteCreateMiddleware executes create middleware -func (me *middlewareRunner) RunCreateMiddleware(middlewares []createMw, input *e.CreateDto, data *e.Room) error { +func (me *middlewareRunner) RunCreateMiddleware(middlewares []createMw, input *e.CreateDto, data *e.Resume) error { for _, middleware := range middlewares { logData := pu.GetLogData(input, data) @@ -38,7 +38,7 @@ func (me *middlewareRunner) RunCreateMiddleware(middlewares []createMw, input *e return nil } -func (me *middlewareRunner) RunReadListMiddleware(middlewares []readListMw, input *e.ReadListDto, data *e.Room) error { +func (me *middlewareRunner) RunReadListMiddleware(middlewares []readListMw, input *e.ReadListDto, data *e.Resume) error { for _, middleware := range middlewares { logData := pu.GetLogData(input, data) @@ -53,7 +53,7 @@ func (me *middlewareRunner) RunReadListMiddleware(middlewares []readListMw, inpu return nil } -func (me *middlewareRunner) RunReadDetailMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.Room) error { +func (me *middlewareRunner) RunReadDetailMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.Resume) error { for _, middleware := range middlewares { logData := pu.GetLogData(input, data) @@ -68,7 +68,7 @@ func (me *middlewareRunner) RunReadDetailMiddleware(middlewares []readDetailMw, return nil } -func (me *middlewareRunner) RunUpdateMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.Room) error { +func (me *middlewareRunner) RunUpdateMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.Resume) error { for _, middleware := range middlewares { logData := pu.GetLogData(input, data) @@ -83,7 +83,7 @@ func (me *middlewareRunner) RunUpdateMiddleware(middlewares []readDetailMw, inpu return nil } -func (me *middlewareRunner) RunDeleteMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.Room) error { +func (me *middlewareRunner) RunDeleteMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.Resume) error { for _, middleware := range middlewares { logData := pu.GetLogData(input, data) diff --git a/internal/use-case/main-use-case/room/middleware.go b/internal/use-case/main-use-case/resume/middleware.go similarity index 93% rename from internal/use-case/main-use-case/room/middleware.go rename to internal/use-case/main-use-case/resume/middleware.go index 668f18e2..dc0aa8c9 100644 --- a/internal/use-case/main-use-case/room/middleware.go +++ b/internal/use-case/main-use-case/resume/middleware.go @@ -1,4 +1,4 @@ -package room +package resume // example of middleware // func init() { diff --git a/internal/use-case/main-use-case/room/tycovar.go b/internal/use-case/main-use-case/resume/tycovar.go similarity index 77% rename from internal/use-case/main-use-case/room/tycovar.go rename to internal/use-case/main-use-case/resume/tycovar.go index 789e3f6f..13f36d2a 100644 --- a/internal/use-case/main-use-case/room/tycovar.go +++ b/internal/use-case/main-use-case/resume/tycovar.go @@ -6,27 +6,27 @@ 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 room +package resume import ( "gorm.io/gorm" - e "simrs-vx/internal/domain/main-entities/room" + e "simrs-vx/internal/domain/main-entities/resume" ) type createMw struct { Name string - Func func(input *e.CreateDto, data *e.Room, tx *gorm.DB) error + Func func(input *e.CreateDto, data *e.Resume, tx *gorm.DB) error } type readListMw struct { Name string - Func func(input *e.ReadListDto, data *e.Room, tx *gorm.DB) error + Func func(input *e.ReadListDto, data *e.Resume, tx *gorm.DB) error } type readDetailMw struct { Name string - Func func(input *e.ReadDetailDto, data *e.Room, tx *gorm.DB) error + Func func(input *e.ReadDetailDto, data *e.Resume, tx *gorm.DB) error } type UpdateMw = readDetailMw diff --git a/pkg/conv-helper/conv-helper.go b/pkg/conv-helper/conv-helper.go index 03063c74..9b9bc44d 100644 --- a/pkg/conv-helper/conv-helper.go +++ b/pkg/conv-helper/conv-helper.go @@ -8,6 +8,8 @@ import ( "gorm.io/gorm" ) +const StandartDateTimeFormat = "2006-01-02 15:04:05" + // check string pointer, if nil return default value func StrConvDefault(f *string, def string) string { if f == nil { @@ -96,20 +98,12 @@ func BoolToString(f *bool) *string { return &t } -func TimeToString(f *time.Time) *string { - if f == nil { - return nil - } - t := f.Format("2006-01-02 15:04:05") - return &t -} - // Handling gorm.DeletedAt func DeletedAtToString(deletedAt *gorm.DeletedAt) *string { if deletedAt == nil || !deletedAt.Valid { return nil } - return TimeToString(&deletedAt.Time) + return TimeToStringWithFormat(&deletedAt.Time, "") } func BoolToFloat64(b bool) float64 { @@ -151,3 +145,17 @@ func StringToUint64(s string) *uint64 { } return &u } + +func TimeToStringWithFormat(t *time.Time, format string) *string { + result := "" + if t == nil || t.IsZero() { + return &result + } + + if format == "" { + format = StandartDateTimeFormat + } + + result = t.Format(format) + return &result +} diff --git a/pkg/use-case-helper/use-case-helper.go b/pkg/use-case-helper/use-case-helper.go index 019f9773..7d0ec17f 100644 --- a/pkg/use-case-helper/use-case-helper.go +++ b/pkg/use-case-helper/use-case-helper.go @@ -208,3 +208,13 @@ func GetLastTwoPathSegments(s string) string { // fallback: return entire string if less than 2 segments return strings.Trim(path, "/") } + +func FormatPlaceAndDate(place string, t time.Time) string { + // Ensure place is uppercase + place = strings.ToUpper(strings.TrimSpace(place)) + + // Format date: DD-MM-YYYY + dateStr := t.Format("02-01-2006") + + return place + ", " + dateStr +}