Merge pull request #134 from dikstub-rssa/fix/refactor-vanilia

Fix/refactor vanilia
This commit is contained in:
Dwi Atmoko Purbo Sakti
2025-11-10 15:48:18 +07:00
committed by GitHub
58 changed files with 1276 additions and 775 deletions
+9 -9
View File
@@ -1,9 +1,9 @@
package main
import (
m "simrs-vx/internal/interface/migration"
)
func main() {
m.Migrate(m.Main)
}
package main
import (
m "simrs-vx/internal/interface/migration"
)
func main() {
m.Migrate(m.Main)
}
@@ -0,0 +1,6 @@
-- Modify "Ambulatory" table
ALTER TABLE "public"."Ambulatory" DROP COLUMN "VisitMode_Code";
-- Modify "InternalReference" table
ALTER TABLE "public"."InternalReference" ADD COLUMN "Status_Code" text NULL;
-- Modify "Rehab" table
ALTER TABLE "public"."Rehab" ADD COLUMN "Parent_Encounter_Id" bigint NULL, ADD COLUMN "ExpiredAt" timestamptz NULL, ADD COLUMN "VisitMode_Code" text NULL, ADD COLUMN "Status_Code" text NULL;
@@ -0,0 +1,2 @@
-- Modify "Rehab" table
ALTER TABLE "public"."Rehab" DROP COLUMN "Doctor_Id";
@@ -0,0 +1,14 @@
-- Modify "Consultation" table
ALTER TABLE "public"."Consultation" ADD COLUMN "DstUnit_Code" text NULL, ADD COLUMN "DstDoctor_Code" text NULL;
-- Modify "ControlLetter" table
ALTER TABLE "public"."ControlLetter" ADD COLUMN "Unit_Code" text NULL, ADD COLUMN "Specialist_Code" text NULL, ADD COLUMN "Subspecialist_Code" text NULL, ADD COLUMN "Doctor_Code" text NULL;
-- Modify "Encounter" table
ALTER TABLE "public"."Encounter" ADD COLUMN "Specialist_Code" text NULL, ADD COLUMN "Subspecialist_Code" text NULL, ADD COLUMN "Appointment_Doctor_Code" text NULL, ADD COLUMN "Responsible_Doctor_Code" text NULL;
-- Modify "InternalReference" table
ALTER TABLE "public"."InternalReference" ADD COLUMN "Unit_Code" text NULL, ADD COLUMN "Doctor_Code" text NULL;
-- Modify "PracticeSchedule" table
ALTER TABLE "public"."PracticeSchedule" ADD COLUMN "Doctor_Code" text NULL;
-- Modify "ResponsibleDoctorHist" table
ALTER TABLE "public"."ResponsibleDoctorHist" ADD COLUMN "Doctor_Code" text NULL;
-- Modify "TherapyProtocol" table
ALTER TABLE "public"."TherapyProtocol" ADD COLUMN "Doctor_Code" text NULL;
@@ -0,0 +1,14 @@
-- Modify "Consultation" table
ALTER TABLE "public"."Consultation" DROP CONSTRAINT "fk_Consultation_DstDoctor", DROP CONSTRAINT "fk_Consultation_DstUnit", DROP COLUMN "DstUnit_Id", DROP COLUMN "DstDoctor_Id", ALTER COLUMN "DstUnit_Code" TYPE character varying(10), ALTER COLUMN "DstDoctor_Code" TYPE character varying(20), ADD CONSTRAINT "fk_Consultation_DstDoctor" FOREIGN KEY ("DstDoctor_Code") REFERENCES "public"."Doctor" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION, ADD CONSTRAINT "fk_Consultation_DstUnit" FOREIGN KEY ("DstUnit_Code") REFERENCES "public"."Unit" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION;
-- Modify "ControlLetter" table
ALTER TABLE "public"."ControlLetter" DROP CONSTRAINT "fk_ControlLetter_Doctor", DROP CONSTRAINT "fk_ControlLetter_Specialist", DROP CONSTRAINT "fk_ControlLetter_Subspecialist", DROP CONSTRAINT "fk_ControlLetter_Unit", DROP COLUMN "Unit_Id", DROP COLUMN "Specialist_Id", DROP COLUMN "Subspecialist_Id", DROP COLUMN "Doctor_Id", ALTER COLUMN "Unit_Code" TYPE character varying(10), ALTER COLUMN "Specialist_Code" TYPE character varying(10), ALTER COLUMN "Subspecialist_Code" TYPE character varying(10), ALTER COLUMN "Doctor_Code" TYPE character varying(20), ADD CONSTRAINT "fk_ControlLetter_Doctor" FOREIGN KEY ("Doctor_Code") REFERENCES "public"."Doctor" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION, ADD CONSTRAINT "fk_ControlLetter_Specialist" FOREIGN KEY ("Specialist_Code") REFERENCES "public"."Specialist" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION, ADD CONSTRAINT "fk_ControlLetter_Subspecialist" FOREIGN KEY ("Subspecialist_Code") REFERENCES "public"."Subspecialist" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION, ADD CONSTRAINT "fk_ControlLetter_Unit" FOREIGN KEY ("Unit_Code") REFERENCES "public"."Unit" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION;
-- Modify "Encounter" table
ALTER TABLE "public"."Encounter" DROP CONSTRAINT "fk_Encounter_Appointment_Doctor", DROP CONSTRAINT "fk_Encounter_Responsible_Doctor", DROP CONSTRAINT "fk_Encounter_Specialist", DROP CONSTRAINT "fk_Encounter_Subspecialist", DROP COLUMN "Specialist_Id", DROP COLUMN "Subspecialist_Id", DROP COLUMN "Responsible_Doctor_Id", DROP COLUMN "Appointment_Doctor_Id", ALTER COLUMN "Specialist_Code" TYPE character varying(10), ALTER COLUMN "Subspecialist_Code" TYPE character varying(10), ALTER COLUMN "Appointment_Doctor_Code" TYPE character varying(20), ALTER COLUMN "Responsible_Doctor_Code" TYPE character varying(20), ADD COLUMN "Unit_Code" text NULL, ADD COLUMN "InsuranceCompany_Code" text NULL, ADD CONSTRAINT "fk_Encounter_Appointment_Doctor" FOREIGN KEY ("Appointment_Doctor_Code") REFERENCES "public"."Doctor" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION, ADD CONSTRAINT "fk_Encounter_Responsible_Doctor" FOREIGN KEY ("Responsible_Doctor_Code") REFERENCES "public"."Doctor" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION, ADD CONSTRAINT "fk_Encounter_Specialist" FOREIGN KEY ("Specialist_Code") REFERENCES "public"."Specialist" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION, ADD CONSTRAINT "fk_Encounter_Subspecialist" FOREIGN KEY ("Subspecialist_Code") REFERENCES "public"."Subspecialist" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION;
-- Modify "InternalReference" table
ALTER TABLE "public"."InternalReference" DROP CONSTRAINT "fk_InternalReference_Doctor", DROP CONSTRAINT "fk_InternalReference_Unit", DROP COLUMN "Unit_Id", DROP COLUMN "Doctor_Id", ALTER COLUMN "Unit_Code" TYPE character varying(10), ALTER COLUMN "Doctor_Code" TYPE character varying(20), ADD CONSTRAINT "fk_InternalReference_Doctor" FOREIGN KEY ("Doctor_Code") REFERENCES "public"."Doctor" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION, ADD CONSTRAINT "fk_InternalReference_Unit" FOREIGN KEY ("Unit_Code") REFERENCES "public"."Unit" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION;
-- Modify "PracticeSchedule" table
ALTER TABLE "public"."PracticeSchedule" DROP CONSTRAINT "fk_PracticeSchedule_Doctor", DROP COLUMN "Doctor_Id", ALTER COLUMN "Doctor_Code" TYPE character varying(20), ADD CONSTRAINT "fk_PracticeSchedule_Doctor" FOREIGN KEY ("Doctor_Code") REFERENCES "public"."Doctor" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION;
-- Modify "ResponsibleDoctorHist" table
ALTER TABLE "public"."ResponsibleDoctorHist" DROP CONSTRAINT "fk_ResponsibleDoctorHist_Doctor", DROP COLUMN "Doctor_Id", ALTER COLUMN "Doctor_Code" TYPE character varying(20), ADD CONSTRAINT "fk_ResponsibleDoctorHist_Doctor" FOREIGN KEY ("Doctor_Code") REFERENCES "public"."Doctor" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION;
-- Modify "TherapyProtocol" table
ALTER TABLE "public"."TherapyProtocol" DROP CONSTRAINT "fk_TherapyProtocol_Doctor", DROP COLUMN "Doctor_Id", ALTER COLUMN "Doctor_Code" TYPE character varying(20), ADD CONSTRAINT "fk_TherapyProtocol_Doctor" FOREIGN KEY ("Doctor_Code") REFERENCES "public"."Doctor" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION;
@@ -0,0 +1,4 @@
-- Modify "Chemo" table
ALTER TABLE "public"."Chemo" ADD COLUMN "SrcUnit_Code" text NULL;
-- Modify "Encounter" table
ALTER TABLE "public"."Encounter" DROP CONSTRAINT "fk_Encounter_InsuranceCompany", DROP CONSTRAINT "fk_Encounter_Unit", DROP COLUMN "Unit_Id", DROP COLUMN "InsuranceCompany_Id", ALTER COLUMN "Unit_Code" TYPE character varying(10), ALTER COLUMN "InsuranceCompany_Code" TYPE character varying(20), ADD CONSTRAINT "fk_Encounter_InsuranceCompany" FOREIGN KEY ("InsuranceCompany_Code") REFERENCES "public"."InsuranceCompany" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION, ADD CONSTRAINT "fk_Encounter_Unit" FOREIGN KEY ("Unit_Code") REFERENCES "public"."Unit" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION;
@@ -0,0 +1,2 @@
-- Modify "Chemo" table
ALTER TABLE "public"."Chemo" DROP CONSTRAINT "fk_Chemo_SrcUnit", DROP COLUMN "SrcUnit_Id", ALTER COLUMN "SrcUnit_Code" TYPE character varying(10), ADD CONSTRAINT "fk_Chemo_SrcUnit" FOREIGN KEY ("SrcUnit_Code") REFERENCES "public"."Unit" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION;
+17 -11
View File
@@ -1,4 +1,4 @@
h1:6umIsneejLUg0V9wUaB2HuCvEHD+2v/dwbxg+y23+wo=
h1:4mUEGaMHpVG5OAo3DgtsqGkPtWwCZDAk0H5y2cG1QP4=
20250904105930.sql h1:MEM6blCgke9DzWQSTnLzasbPIrcHssNNrJqZpSkEo6k=
20250904141448.sql h1:J8cmYNk4ZrG9fhfbi2Z1IWz7YkfvhFqTzrLFo58BPY0=
20250908062237.sql h1:Pu23yEW/aKkwozHoOuROvHS/GK4ngARJGdO7FB7HZuI=
@@ -85,13 +85,19 @@ h1:6umIsneejLUg0V9wUaB2HuCvEHD+2v/dwbxg+y23+wo=
20251106090021.sql h1:4JwdKgO8T46YhyWVJUxpRIwudBDlG8QN1brSOYmgQ20=
20251106144745.sql h1:nqnQCzGrVJaq8ilOEOGXeRUL1dolj+OPWKuP8A92FRA=
20251107012049.sql h1:Pff4UqltGS3clSlGr0qq8CQM56L29wyxY0FC/N/YAhU=
20251107064812.sql h1:jjpcAi0B/geEOKWmmR6+1UhWMhjstWhWQcz9lUWrtTY=
20251107064937.sql h1:1nPu0THBf+YquFIJSE4pc1dA7r3EydH92cpp26ozysw=
20251107071420.sql h1:Q+e+OqjdiuK/sghDQ5NxjU+u2zYl+vh/eRBlUz9Idhg=
20251107074318.sql h1:VbOWMw2rClEWgMnDSejXPqXkFoQ4odVsHn3/UAEiCYA=
20251107075050.sql h1:ZZaKJEWXIJ94/0/2Gzzz+HXjmebEs5eP8iUIot26/c8=
20251107080604.sql h1:aq+tINa0ULCZlJcUK2jaeGh6rRH4jJz3e2NrK47m0Ec=
20251107081830.sql h1:Bl9kniyLWeMqd3nrvgCgiUpdcJWp8qX1F41JAM1WbiE=
20251107091033.sql h1:ETTCaAHBT6wipXrEGXIepxLMdD2LNzprPAp99+jnW0w=
20251107091209.sql h1:BUI9JlTzZxCdVHsrRbOye7m47AJEvXNhCaCVv/HzILs=
20251107091541.sql h1:/tW2uXv/o0Q2E4lQzlYNgEftvDqjf3c2AQpZ83Vb6zc=
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=
@@ -6,9 +6,8 @@ import (
)
type CreateDto struct {
Encounter_Id *uint `json:"encounter_id"`
Class_Code ere.AmbulatoryClassCode `json:"class_code" validate:"maxLength=10"`
VisitMode_Code ere.VisitModeCode `json:"visitMode_code"`
Encounter_Id *uint `json:"encounter_id"`
Class_Code ere.AmbulatoryClassCode `json:"class_code" validate:"maxLength=10"`
}
type ReadListDto struct {
@@ -50,9 +49,8 @@ type ResponseDto struct {
func (d Ambulatory) ToResponse() ResponseDto {
resp := ResponseDto{
Encounter_Id: d.Encounter_Id,
Class_Code: d.Class_Code,
VisitMode_Code: d.VisitMode_Code,
Encounter_Id: d.Encounter_Id,
Class_Code: d.Class_Code,
}
resp.Main = d.Main
return resp
@@ -6,8 +6,7 @@ import (
)
type Ambulatory struct {
ecore.Main // adjust this according to the needs
Encounter_Id *uint `json:"encounter_id"`
Class_Code ere.AmbulatoryClassCode `json:"class_code" gorm:"size:10"`
VisitMode_Code ere.VisitModeCode `json:"visitMode_code"`
ecore.Main // adjust this according to the needs
Encounter_Id *uint `json:"encounter_id"`
Class_Code ere.AmbulatoryClassCode `json:"class_code" gorm:"size:10"`
}
+4 -4
View File
@@ -20,7 +20,7 @@ import (
type CreateDto struct {
Encounter_Id *uint `json:"encounter_id"`
Status_Code erc.DataVerifiedCode `json:"status_code"`
SrcUnit_Id *uint `json:"srcUnit_id"`
SrcUnit_Code *string `json:"srcUnit_code"`
}
type ReadListDto struct {
@@ -33,7 +33,7 @@ type FilterDto struct {
Encounter_Id *uint `json:"encounter-id"`
Status_Code *erc.DataVerifiedCode `json:"status-code"`
VerifiedBy_User_Id *uint `json:"verifiedBy-user-id"`
SrcUnit_Id *uint `json:"srcUnit-id"`
SrcUnit_Code *string `json:"srcUnit-code"`
}
type ReadDetailDto struct {
@@ -72,7 +72,7 @@ type ResponseDto struct {
VerifiedAt *time.Time `json:"verifiedAt"`
VerifiedBy_User_Id *uint `json:"verifiedBy_user_id"`
VerifiedBy *eus.User `json:"verifiedBy,omitempty"`
SrcUnit_Id *uint `json:"srcUnit_id"`
SrcUnit_Code *string `json:"srcUnit_code"`
SrcUnit *eun.Unit `json:"srcUnit,omitempty"`
}
@@ -84,7 +84,7 @@ func (d Chemo) ToResponse() ResponseDto {
VerifiedAt: d.VerifiedAt,
VerifiedBy_User_Id: d.VerifiedBy_User_Id,
VerifiedBy: d.VerifiedBy,
SrcUnit_Id: d.SrcUnit_Id,
SrcUnit_Code: d.SrcUnit_Code,
SrcUnit: d.SrcUnit,
}
resp.Main = d.Main
@@ -19,8 +19,8 @@ type Chemo struct {
VerifiedAt *time.Time `json:"verifiedAt"`
VerifiedBy_User_Id *uint `json:"verifiedBy_user_id"`
VerifiedBy *eus.User `json:"verifiedBy,omitempty" gorm:"foreignKey:VerifiedBy_User_Id;references:Id"`
SrcUnit_Id *uint `json:"src_unit_id"`
SrcUnit *eun.Unit `json:"src_unit,omitempty" gorm:"foreignKey:SrcUnit_Id;references:Id"`
SrcUnit_Code *string `json:"src_unit_code"`
SrcUnit *eun.Unit `json:"src_unit,omitempty" gorm:"foreignKey:SrcUnit_Code;references:Code"`
Bed *string `json:"bed" gorm:"size:1024"`
Needs *string `json:"needs" gorm:"size:2048"`
}
@@ -20,7 +20,7 @@ type CreateDto struct {
Encounter_Id *uint `json:"encounter_id"`
Date *time.Time `json:"date"`
Problem *string `json:"problem" validate:"maxLength=10240"`
DstUnit_Id *uint `json:"dstUnit_id"`
DstUnit_Code *string `json:"dstUnit_code"`
}
type ReadListDto struct {
@@ -30,9 +30,9 @@ type ReadListDto struct {
}
type FilterDto struct {
Encounter_Id *uint `json:"encounter-id"`
DstUnit_Id *uint `json:"dstUnit-id"`
DstDoctor_Id *uint `json:"dstDoctor-id"`
Encounter_Id *uint `json:"encounter-id"`
DstUnit_Code *string `json:"dstUnit-code"`
DstDoctor_Code *string `json:"dstDoctor-code"`
}
type ReadDetailDto struct {
@@ -63,29 +63,29 @@ type MetaDto struct {
type ResponseDto struct {
ecore.Main
Encounter_Id *uint `json:"encounter_id"`
Encounter *ee.Encounter `json:"encounter,omitempty"`
Date *time.Time `json:"date"`
Problem *string `json:"problem"`
Solution *string `json:"solution"`
DstUnit_Id *uint `json:"dstUnit_id"`
DstUnit *eu.Unit `json:"dstUnit,omitempty"`
DstDoctor_Id *uint `json:"dstDoctor_id"`
DstDoctor *ed.Doctor `json:"dstDoctor,omitempty"`
RepliedAt *time.Time `json:"repliedAt"`
Encounter_Id *uint `json:"encounter_id"`
Encounter *ee.Encounter `json:"encounter,omitempty"`
Date *time.Time `json:"date"`
Problem *string `json:"problem"`
Solution *string `json:"solution"`
DstUnit_Code *string `json:"dstUnit_code"`
DstUnit *eu.Unit `json:"dstUnit,omitempty"`
DstDoctor_Code *string `json:"dstDoctor_code"`
DstDoctor *ed.Doctor `json:"dstDoctor,omitempty"`
RepliedAt *time.Time `json:"repliedAt"`
}
func (d Consultation) ToResponse() ResponseDto {
resp := ResponseDto{
Encounter_Id: d.Encounter_Id,
Encounter: d.Encounter,
Date: d.Date,
Problem: d.Problem,
Solution: d.Solution,
DstUnit_Id: d.DstUnit_Id,
DstUnit: d.DstUnit,
DstDoctor_Id: d.DstDoctor_Id,
DstDoctor: d.DstDoctor,
Encounter_Id: d.Encounter_Id,
Encounter: d.Encounter,
Date: d.Date,
Problem: d.Problem,
Solution: d.Solution,
DstUnit_Code: d.DstUnit_Code,
DstUnit: d.DstUnit,
DstDoctor_Code: d.DstDoctor_Code,
DstDoctor: d.DstDoctor,
}
resp.Main = d.Main
return resp
@@ -15,11 +15,11 @@ type Consultation struct {
Encounter *ee.Encounter `json:"encounter" gorm:"foreignKey:Encounter_Id;references:Id"`
Date *time.Time `json:"date"`
Problem *string `json:"case" gorm:"size:10240"`
Solution *string `json:"solution" gorm:"size:10240"`
DstUnit_Id *uint `json:"dstUnit_id"`
DstUnit *eu.Unit `json:"dstUnit" gorm:"foreignKey:DstUnit_Id;references:Id"`
DstDoctor_Id *uint `json:"dstDoctor_id"`
DstDoctor *ed.Doctor `json:"dstDoctor" gorm:"foreignKey:DstDoctor_Id;references:Id"`
RepliedAt *time.Time `json:"repliedAt"`
Problem *string `json:"case" gorm:"size:10240"`
Solution *string `json:"solution" gorm:"size:10240"`
DstUnit_Code *string `json:"dstUnit_code"`
DstUnit *eu.Unit `json:"dstUnit" gorm:"foreignKey:DstUnit_Code;references:Code"`
DstDoctor_Code *string `json:"dstDoctor_code"`
DstDoctor *ed.Doctor `json:"dstDoctor" gorm:"foreignKey:DstDoctor_Code;references:Code"`
RepliedAt *time.Time `json:"repliedAt"`
}
@@ -5,7 +5,6 @@ import (
"time"
// internal - lib
pa "simrs-vx/internal/lib/auth"
// internal - domain - base-entities
ecore "simrs-vx/internal/domain/base-entities/core"
@@ -20,12 +19,12 @@ import (
)
type CreateDto struct {
Encounter_Id *uint `json:"encounter_id"`
Unit_Id *uint `json:"unit_id"`
Specialist_Id *uint `json:"specialist_id"`
Subspecialist_Id *uint `json:"subspecialist_id"`
Doctor_Id *uint `json:"doctor_id"`
Date *time.Time `json:"date"`
Encounter_Id *uint `json:"encounter_id"`
Unit_Code *string `json:"unit_code"`
Specialist_Code *string `json:"specialist_code"`
Subspecialist_Code *string `json:"subspecialist_code"`
Doctor_Code *string `json:"doctor_code"`
Date *time.Time `json:"date"`
}
type ReadListDto struct {
@@ -35,12 +34,12 @@ type ReadListDto struct {
}
type FilterDto struct {
Encounter_Id *uint `json:"encounter-id"`
Unit_Id *uint `json:"unit-id"`
Specialist_Id *uint `json:"specialist-id"`
Subspecialist_Id *uint `json:"subspecialist-id"`
Doctor_Id *uint `json:"doctor-id"`
Date *time.Time `json:"date"`
Encounter_Id *uint `json:"encounter-id"`
Unit_Code *string `json:"unit-code"`
Specialist_Code *string `json:"specialist-code"`
Subspecialist_Code *string `json:"subspecialist-code"`
Doctor_Code *string `json:"doctor-code"`
Date *time.Time `json:"date"`
}
type ReadDetailDto struct {
@@ -57,13 +56,6 @@ type DeleteDto struct {
Id uint `json:"id"`
}
type ReplyDto struct {
Id uint `json:"id"`
Solution *string `json:"solution"`
pa.AuthInfo
}
type MetaDto struct {
PageNumber int `json:"page_number"`
PageSize int `json:"page_size"`
@@ -72,32 +64,32 @@ type MetaDto struct {
type ResponseDto struct {
ecore.Main
Encounter_Id *uint `json:"encounter_id"`
Encounter *ee.Encounter `json:"encounter,omitempty"`
Unit_Id *uint `json:"unit_id"`
Unit *eu.Unit `json:"unit,omitempty"`
Specialist_Id *uint `json:"specialist_id"`
Specialist *es.Specialist `json:"specialist,omitempty"`
Subspecialist_Id *uint `json:"subspecialist_id"`
Subspecialist *ess.Subspecialist `json:"subspecialist,omitempty"`
Doctor_Id *uint `json:"doctor_id"`
Doctor *ed.Doctor `json:"doctor,omitempty"`
Date *time.Time `json:"date"`
Encounter_Id *uint `json:"encounter_id"`
Encounter *ee.Encounter `json:"encounter,omitempty"`
Unit_Code *string `json:"unit_code"`
Unit *eu.Unit `json:"unit,omitempty"`
Specialist_Code *string `json:"specialist_code"`
Specialist *es.Specialist `json:"specialist,omitempty"`
Subspecialist_Code *string `json:"subspecialist_code"`
Subspecialist *ess.Subspecialist `json:"subspecialist,omitempty"`
Doctor_Code *string `json:"doctor_code"`
Doctor *ed.Doctor `json:"doctor,omitempty"`
Date *time.Time `json:"date"`
}
func (d ControlLetter) ToResponse() ResponseDto {
resp := ResponseDto{
Encounter_Id: d.Encounter_Id,
Encounter: d.Encounter,
Unit_Id: d.Unit_Id,
Unit: d.Unit,
Specialist_Id: d.Specialist_Id,
Specialist: d.Specialist,
Subspecialist_Id: d.Subspecialist_Id,
Subspecialist: d.Subspecialist,
Doctor_Id: d.Doctor_Id,
Doctor: d.Doctor,
Date: d.Date,
Encounter_Id: d.Encounter_Id,
Encounter: d.Encounter,
Unit_Code: d.Unit_Code,
Unit: d.Unit,
Specialist_Code: d.Specialist_Code,
Specialist: d.Specialist,
Subspecialist_Code: d.Subspecialist_Code,
Subspecialist: d.Subspecialist,
Doctor_Code: d.Doctor_Code,
Doctor: d.Doctor,
Date: d.Date,
}
resp.Main = d.Main
return resp
@@ -12,16 +12,16 @@ import (
)
type ControlLetter struct {
ecore.Main // adjust this according to the needs
Encounter_Id *uint `json:"encounter_id"`
Encounter *ee.Encounter `json:"encounter" gorm:"foreignKey:Encounter_Id;references:Id"`
Unit_Id *uint `json:"unit_id"`
Unit *eu.Unit `json:"unit" gorm:"foreignKey:Unit_Id;references:Id"`
Specialist_Id *uint `json:"specialist_id"`
Specialist *es.Specialist `json:"specialist" gorm:"foreignKey:Specialist_Id;references:Id"`
Subspecialist_Id *uint `json:"subspecialist_id"`
Subspecialist *ess.Subspecialist `json:"subspecialist" gorm:"foreignKey:Subspecialist_Id;references:Id"`
Doctor_Id *uint `json:"doctor_id"`
Doctor *ed.Doctor `json:"doctor" gorm:"foreignKey:Doctor_Id;references:Id"`
Date *time.Time `json:"date"`
ecore.Main // adjust this according to the needs
Encounter_Id *uint `json:"encounter_id"`
Encounter *ee.Encounter `json:"encounter" gorm:"foreignKey:Encounter_Id;references:Id"`
Unit_Code *string `json:"unit_code"`
Unit *eu.Unit `json:"unit" gorm:"foreignKey:Unit_Code;references:Code"`
Specialist_Code *string `json:"specialist_code"`
Specialist *es.Specialist `json:"specialist" gorm:"foreignKey:Specialist_Code;references:Code"`
Subspecialist_Code *string `json:"subspecialist_code"`
Subspecialist *ess.Subspecialist `json:"subspecialist" gorm:"foreignKey:Subspecialist_Code;references:Code"`
Doctor_Code *string `json:"doctor_code"`
Doctor *ed.Doctor `json:"doctor" gorm:"foreignKey:Doctor_Code;references:Code"`
Date *time.Time `json:"date"`
}
+4 -3
View File
@@ -38,7 +38,7 @@ type FilterDto struct {
}
type ReadDetailDto struct {
Id uint16 `json:"id"`
Id *uint16 `json:"id"`
Code *string `json:"code"`
Employee_Id *uint `json:"employee_id"`
IHS_Number *string `json:"ihs_number"`
@@ -46,12 +46,13 @@ type ReadDetailDto struct {
}
type UpdateDto struct {
Id uint `json:"id"`
Id *uint `json:"id"`
CreateDto
}
type DeleteDto struct {
Id uint `json:"id"`
Id uint `json:"id"`
Code *string `json:"code"`
}
type MetaDto struct {
+86 -47
View File
@@ -1,6 +1,13 @@
package encounter
import (
eam "simrs-vx/internal/domain/main-entities/ambulatory"
edc "simrs-vx/internal/domain/main-entities/death-cause"
eem "simrs-vx/internal/domain/main-entities/emergency"
eip "simrs-vx/internal/domain/main-entities/inpatient"
eir "simrs-vx/internal/domain/main-entities/internal-reference"
er "simrs-vx/internal/domain/main-entities/rehab/base"
// std
"time"
@@ -19,7 +26,6 @@ import (
ea "simrs-vx/internal/domain/main-entities/appointment"
ed "simrs-vx/internal/domain/main-entities/doctor"
ee "simrs-vx/internal/domain/main-entities/employee"
eir "simrs-vx/internal/domain/main-entities/internal-reference"
ep "simrs-vx/internal/domain/main-entities/patient"
es "simrs-vx/internal/domain/main-entities/specialist"
ess "simrs-vx/internal/domain/main-entities/subspecialist"
@@ -27,29 +33,31 @@ import (
)
type CreateDto struct {
Patient_Id *uint `json:"patient_id"`
RegisteredAt *time.Time `json:"registeredAt"`
Class_Code ere.EncounterClassCode `json:"class_code" validate:"maxLength=10"`
SubClass_Code *string `json:"subClass_code" validate:"maxLength=10"` // for sub
Infra_Id *uint16 `json:"infra_id"` // for inpatient
Unit_Id *uint `json:"unit_id"`
Specialist_Id *uint16 `json:"specialist_id"`
Subspecialist_Id *uint16 `json:"subspecialist_id"`
VisitDate time.Time `json:"visitDate"`
PaymentMethod_Code erc.PaymentMethodCode `json:"paymentMethod_code" gorm:"size:10"`
InsuranceCompany_Id *uint `json:"insuranceCompany_id"`
Member_Number *string `json:"member_number" validate:"maxLength=20"`
Ref_Number *string `json:"ref_number" validate:"maxLength=20"`
Trx_Number *string `json:"trx_number" validate:"maxLength=20"`
Appointment_Doctor_Id *uint `json:"appointment_doctor_id"`
Adm_Employee_Id *uint `json:"-"`
Responsible_Doctor_Id *uint `json:"responsible_doctor_id"`
RefSource_Name *string `json:"refSource_name" validate:"maxLength=100"`
Appointment_Id *uint `json:"appointment_id"`
RefTypeCode ere.RefTypeCode `json:"refTypeCode"`
NewStatus bool `json:"newStatus"`
VisitMode_Code *ere.VisitModeCode `json:"visitMode_code"` // if subClass_Code is rehab
AllocatedVisitCount *int `json:"allocatedVisitCount"` // if subClass_Code is rehab and VisitMode_Code is "adm"
Patient_Id *uint `json:"patient_id"`
RegisteredAt *time.Time `json:"registeredAt"`
Class_Code ere.EncounterClassCode `json:"class_code" validate:"maxLength=10"`
SubClass_Code *string `json:"subClass_code" validate:"maxLength=10"` // for sub
Infra_Id *uint16 `json:"infra_id"` // for inpatient
Unit_Code *string `json:"unit_code"`
Specialist_Code *string `json:"specialist_code"`
Subspecialist_Code *string `json:"subspecialist_code"`
VisitDate time.Time `json:"visitDate"`
PaymentMethod_Code erc.PaymentMethodCode `json:"paymentMethod_code" gorm:"size:10"`
InsuranceCompany_Code *string `json:"insuranceCompany_code"`
Member_Number *string `json:"member_number" validate:"maxLength=20"`
Ref_Number *string `json:"ref_number" validate:"maxLength=20"`
Trx_Number *string `json:"trx_number" validate:"maxLength=20"`
Appointment_Doctor_Code *string `json:"appointment_doctor_code"`
Adm_Employee_Id *uint `json:"-"`
Responsible_Doctor_Code *string `json:"responsible_doctor_code"`
RefSource_Name *string `json:"refSource_name" validate:"maxLength=100"`
Appointment_Id *uint `json:"appointment_id"`
RefTypeCode ere.RefTypeCode `json:"refTypeCode"`
NewStatus bool `json:"newStatus"`
Id uint `json:"-"`
RecentEncounterAdm *Encounter `json:"-"` // if subClass_Code is rehab
VisitMode_Code ere.VisitModeCode `json:"-"` // if subClass_Code is rehab
pa.AuthInfo
}
@@ -67,12 +75,12 @@ type FilterDto struct {
Patient *ep.Patient `json:"patient,omitempty"`
RegisteredAt *time.Time `json:"registeredAt"`
Class_Code ere.EncounterClassCode `json:"class-code" validate:"maxLength=10"`
Unit_Id *uint `json:"unit-id"`
Specialist_Id *uint16 `json:"specialist-id"`
Subspecialist_Id *uint16 `json:"subspecialist-id"`
Unit_Code *string `json:"unit-code"`
Specialist_Code *string `json:"specialist-code"`
Subspecialist_Code *string `json:"subspecialist-code"`
VisitDate time.Time `json:"visitDate"`
Appoinment_Doctor_Id *uint `json:"appointment-doctor-id"`
Responsible_Doctor_Id *uint `json:"responsible-doctor-id"`
Appoinment_Doctor_Code *string `json:"appointment-doctor-code"`
Responsible_Doctor_Code *string `json:"responsible-doctor-code"`
DischargeMethod_Code ere.DischargeMethodCode `json:"dischargeMethod-code" validate:"maxLength=10"`
RefSource_Name *string `json:"refSource-name" validate:"maxLength=100"`
Appointment_Id *uint `json:"appointment-id"`
@@ -114,15 +122,25 @@ type DischargeDto struct {
AdmDischargeEducation *string `json:"admDischargeEducation"`
DischargeReason *string `json:"dischargeReason"`
DeathCause *string `json:"deathCause"`
InternalReferences *[]eir.CreateDto `json:"internalReferences,omitempty"`
}
type CheckinDto struct {
Id uint `json:"id"`
Responsible_Doctor_Id *uint `json:"responsible_doctor_id"`
Adm_Employee_Id *uint `json:"adm_employee_id"`
StartedAt *time.Time `json:"startedAt"`
FinishedAt *time.Time `json:"finishedAt"`
Id uint `json:"id"`
Responsible_Doctor_Code *string `json:"responsible_doctor_code"`
Adm_Employee_Id *uint `json:"adm_employee_id"`
StartedAt *time.Time `json:"startedAt"`
FinishedAt *time.Time `json:"finishedAt"`
}
type SwitchUnitDto struct {
Id uint `json:"id"`
PolySwitchCode *ere.PolySwitchCode `json:"polySwitchCode"`
InternalReferences *[]eir.CreateDto `json:"internalReferences" validate:"required"`
}
type ApproveUnitDto struct {
Id uint `json:"id"`
InternalReferences_Id uint16 `json:"internalReferences_id" validate:"required"`
}
type ResponseDto struct {
@@ -131,21 +149,21 @@ type ResponseDto struct {
Patient *ep.Patient `json:"patient,omitempty"`
RegisteredAt *time.Time `json:"registeredAt"`
Class_Code ere.EncounterClassCode `json:"class_code"`
Unit_Id *uint `json:"unit_id"`
Specialist_Id *uint16 `json:"specialist_id"`
Unit_Code *string `json:"unit_code"`
Specialist_Code *string `json:"specialist_code"`
Specialist *es.Specialist `json:"specialist,omitempty"`
Subspecialist_Id *uint16 `json:"subspecialist_id"`
Subspecialist_Code *string `json:"subspecialist_code"`
Subspecialist *ess.Subspecialist `json:"subspecialist,omitempty"`
Unit *eu.Unit `json:"unit,omitempty"`
VisitDate time.Time `json:"visitDate"`
PaymentMethod_Code erc.PaymentMethodCode `json:"paymentMethod_code"`
InsuranceCompany_Id *uint `json:"insuranceCompany_id"`
InsuranceCompany_Code *string `json:"insuranceCompany_code"`
Member_Number *string `json:"member_number"`
Ref_Number *string `json:"ref_number"`
Trx_Number *string `json:"trx_number"`
Appointment_Doctor_Id *uint `json:"appointment_doctor_id"`
Appointment_Doctor_Code *string `json:"appointment_doctor_code"`
Appointment_Doctor *ed.Doctor `json:"appointment_doctor,omitempty"`
Responsible_Doctor_Id *uint `json:"responsible_doctor_id"`
Responsible_Doctor_Code *string `json:"responsible_doctor_code"`
Responsible_Doctor *ed.Doctor `json:"responsible_doctor,omitempty"`
Adm_Employee_Id *uint `json:"adm_employee_id"`
Adm_Employee *ee.Employee `json:"adm_employee,omitempty"`
@@ -159,6 +177,17 @@ type ResponseDto struct {
DischargeReason *string `json:"dischargeReason"`
Status_Code erc.DataStatusCode `json:"status_code"`
VclaimSep *evs.VclaimSep `json:"vclaimSep,omitempty"`
StartedAt *time.Time `json:"startedAt"`
FinishedAt *time.Time `json:"finishedAt"`
Discharge_Date *time.Time `json:"discharge_date"`
InternalReferences *[]eir.InternalReference `json:"internalReferences,omitempty"`
DeathCause *edc.DeathCause `json:"deathCause,omitempty"`
NewStatus bool `json:"newStatus"`
Ambulatory *eam.Ambulatory `json:"ambulatory,omitempty"`
Emergency *eem.Emergency `json:"emergency,omitempty"`
Inpatient *eip.Inpatient `json:"inpatient,omitempty"`
Rehab *er.Basic `json:"rehab,omitempty"`
RehabChildren *[]er.Basic `json:"rehabChildren,omitempty"`
}
func (d Encounter) ToResponse() ResponseDto {
@@ -167,23 +196,23 @@ func (d Encounter) ToResponse() ResponseDto {
Patient: d.Patient,
RegisteredAt: d.RegisteredAt,
Class_Code: d.Class_Code,
Unit_Id: d.Unit_Id,
Unit_Code: d.Unit_Code,
Unit: d.Unit,
Specialist_Id: d.Specialist_Id,
Specialist_Code: d.Specialist_Code,
Specialist: d.Specialist,
Subspecialist_Id: d.Subspecialist_Id,
Subspecialist_Code: d.Subspecialist_Code,
Subspecialist: d.Subspecialist,
VisitDate: d.VisitDate,
PaymentMethod_Code: d.PaymentMethod_Code,
InsuranceCompany_Id: d.InsuranceCompany_Id,
InsuranceCompany_Code: d.InsuranceCompany_Code,
Member_Number: d.Member_Number,
Ref_Number: d.Ref_Number,
Trx_Number: d.Trx_Number,
Appointment_Doctor_Id: d.Appointment_Doctor_Id,
Appointment_Doctor_Code: d.Appointment_Doctor_Code,
Appointment_Doctor: d.Appointment_Doctor,
Adm_Employee_Id: d.Adm_Employee_Id,
Adm_Employee: d.Adm_Employee,
Responsible_Doctor_Id: d.Responsible_Doctor_Id,
Responsible_Doctor_Code: d.Responsible_Doctor_Code,
Responsible_Doctor: d.Responsible_Doctor,
Discharge_Method_Code: d.Discharge_Method_Code,
RefSource_Name: d.RefSource_Name,
@@ -195,6 +224,16 @@ func (d Encounter) ToResponse() ResponseDto {
DischargeReason: d.DischargeReason,
Status_Code: d.Status_Code,
VclaimSep: d.VclaimSep,
StartedAt: d.StartedAt,
FinishedAt: d.FinishedAt,
Discharge_Date: d.Discharge_Date,
InternalReferences: d.InternalReferences,
DeathCause: d.DeathCause,
NewStatus: d.NewStatus,
Emergency: d.Emergency,
Inpatient: d.Inpatient,
Rehab: d.Rehab,
RehabChildren: d.RehabChildren,
}
resp.Main = d.Main
return resp
@@ -29,28 +29,28 @@ type Encounter struct {
Patient *ep.Patient `json:"patient,omitempty" gorm:"foreignKey:Patient_Id;references:Id"`
RegisteredAt *time.Time `json:"registeredAt"`
Class_Code ere.EncounterClassCode `json:"class_code" gorm:"not null;size:10"`
Unit_Id *uint `json:"unit_id"`
Unit *eu.Unit `json:"unit,omitempty" gorm:"foreignKey:Unit_Id;references:Id"`
Specialist_Id *uint16 `json:"specialist_id"`
Specialist *es.Specialist `json:"specialist,omitempty" gorm:"foreignKey:Specialist_Id;references:Id"`
Subspecialist_Id *uint16 `json:"subspecialist_id"`
Subspecialist *ess.Subspecialist `json:"subspecialist,omitempty" gorm:"foreignKey:Subspecialist_Id;references:Id"`
Unit_Code *string `json:"unit_code"`
Unit *eu.Unit `json:"unit,omitempty" gorm:"foreignKey:Unit_Code;references:Code"`
Specialist_Code *string `json:"specialist_code"`
Specialist *es.Specialist `json:"specialist,omitempty" gorm:"foreignKey:Specialist_Code;references:Code"`
Subspecialist_Code *string `json:"subspecialist_code"`
Subspecialist *ess.Subspecialist `json:"subspecialist,omitempty" gorm:"foreignKey:Subspecialist_Code;references:Code"`
VisitDate time.Time `json:"visitDate"`
StartedAt *time.Time `json:"startedAt"`
FinishedAt *time.Time `json:"finishedAt"`
PaymentMethod_Code erc.PaymentMethodCode `json:"paymentMethod_code" gorm:"size:10"`
InsuranceCompany_Id *uint `json:"insuranceCompany_id"`
InsuranceCompany *ei.InsuranceCompany `json:"insuranceCompany,omitempty" gorm:"foreignKey:InsuranceCompany_Id;references:Id"`
InsuranceCompany_Code *string `json:"insuranceCompany_code"`
InsuranceCompany *ei.InsuranceCompany `json:"insuranceCompany,omitempty" gorm:"foreignKey:InsuranceCompany_Code;references:Code"`
Member_Number *string `json:"memberNumber" gorm:"unique;size:20"`
RefType_Code *ere.RefTypeCode `json:"refType_code"`
Ref_Number *string `json:"refNumber" gorm:"unique;size:20"`
Trx_Number *string `json:"trxNumber" gorm:"unique;size:20"`
Appointment_Doctor_Id *uint `json:"appointment_doctor_id"`
Appointment_Doctor *ed.Doctor `json:"appointment_doctor,omitempty" gorm:"foreignKey:Appointment_Doctor_Id;references:Id"`
Appointment_Doctor_Code *string `json:"appointment_doctor_code"`
Appointment_Doctor *ed.Doctor `json:"appointment_doctor,omitempty" gorm:"foreignKey:Appointment_Doctor_Code;references:Code"`
Adm_Employee_Id *uint `json:"adm_employee_id"`
Adm_Employee *ee.Employee `json:"adm_employee,omitempty" gorm:"foreignKey:Adm_Employee_Id;references:Id"`
Responsible_Doctor_Id *uint `json:"responsible_doctor_id"`
Responsible_Doctor *ed.Doctor `json:"responsible_doctor,omitempty" gorm:"foreignKey:Responsible_Doctor_Id;references:Id"`
Responsible_Doctor_Code *string `json:"responsible_doctor_code"`
Responsible_Doctor *ed.Doctor `json:"responsible_doctor,omitempty" gorm:"foreignKey:Responsible_Doctor_Code;references:Code"`
Discharge_Method_Code *ere.DischargeMethodCode `json:"discharge_method_code" gorm:"size:16"`
RefSource_Name *string `json:"refSource_name" gorm:"size:100"`
Appointment_Id *uint `json:"appointment_id"`
@@ -69,6 +69,7 @@ type Encounter struct {
Emergency *eem.Emergency `json:"emergency,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"`
Inpatient *eip.Inpatient `json:"inpatient,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"`
Rehab *er.Basic `json:"rehab,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"`
RehabChildren *[]er.Basic `json:"rehabChildren,omitempty" gorm:"foreignKey:Parent_Encounter_Id;references:Id"`
}
func (d Encounter) IsDone() bool {
@@ -1,15 +1,18 @@
package internal_reference
import (
erc "simrs-vx/internal/domain/references/common"
ecore "simrs-vx/internal/domain/base-entities/core"
ed "simrs-vx/internal/domain/main-entities/doctor"
eu "simrs-vx/internal/domain/main-entities/unit"
)
type CreateDto struct {
Encounter_Id *uint `json:"-"`
Unit_Id *uint16 `json:"unit_id"`
Doctor_Id *uint `json:"doctor_Id"`
Encounter_Id *uint `json:"-"`
Unit_Code *string `json:"unit_code"`
Doctor_Code *string `json:"doctor_code"`
Status_Code erc.DataApprovalCode `json:"status_code"`
}
type ReadListDto struct {
@@ -19,9 +22,10 @@ type ReadListDto struct {
}
type FilterDto struct {
Encounter_Id *uint `json:"encounter-id"`
Unit_Id *uint `json:"unit-id"`
Doctor_Id *uint `json:"doctor-id"`
Encounter_Id *uint `json:"encounter-id"`
Unit_Code *uint `json:"unit-code"`
Doctor_Code *uint `json:"doctor-code"`
Status_Code erc.DataApprovalCode `json:"status-code"`
}
type ReadDetailDto struct {
@@ -46,20 +50,22 @@ type MetaDto struct {
type ResponseDto struct {
ecore.Main
Encounter_Id *uint `json:"encounter_id"`
Unit_Id *uint16 `json:"unit_id"`
Unit *eu.Unit `json:"unit,omitempty"`
Doctor_Id *uint `json:"doctor_id"`
Doctor *ed.Doctor `json:"doctor,omitempty"`
Encounter_Id *uint `json:"encounter_id"`
Unit_Code *string `json:"unit_code"`
Unit *eu.Unit `json:"unit,omitempty"`
Doctor_Code *string `json:"doctor_id"`
Doctor *ed.Doctor `json:"doctor,omitempty"`
Status_Code *erc.DataApprovalCode `json:"status_code"`
}
func (d InternalReference) ToResponse() ResponseDto {
resp := ResponseDto{
Encounter_Id: d.Encounter_Id,
Unit_Id: d.Unit_Id,
Unit_Code: d.Unit_Code,
Unit: d.Unit,
Doctor_Id: d.Doctor_Id,
Doctor_Code: d.Doctor_Code,
Doctor: d.Doctor,
Status_Code: d.Status_Code,
}
resp.Main = d.Main
return resp
@@ -1,6 +1,8 @@
package internal_reference
import (
erc "simrs-vx/internal/domain/references/common"
ecore "simrs-vx/internal/domain/base-entities/core"
ed "simrs-vx/internal/domain/main-entities/doctor"
eu "simrs-vx/internal/domain/main-entities/unit"
@@ -8,9 +10,10 @@ import (
type InternalReference struct {
ecore.Main
Encounter_Id *uint `json:"encounter_id"`
Unit_Id *uint16 `json:"unit_id"`
Unit *eu.Unit `json:"unit,omitempty" gorm:"foreignKey:Unit_Id;references:Id"`
Doctor_Id *uint `json:"doctor_id"`
Doctor *ed.Doctor `json:"doctor,omitempty" gorm:"foreignKey:Doctor_Id;references:Id"`
Encounter_Id *uint `json:"encounter_id"`
Unit_Code *string `json:"unit_code"`
Unit *eu.Unit `json:"unit,omitempty" gorm:"foreignKey:Unit_Code;references:Code"`
Doctor_Code *string `json:"doctor_code"`
Doctor *ed.Doctor `json:"doctor,omitempty" gorm:"foreignKey:Doctor_Code;references:Code"`
Status_Code *erc.DataApprovalCode `json:"status_code"`
}
+4 -3
View File
@@ -29,19 +29,20 @@ type FilterDto struct {
Infra_Code *string `json:"infra-code"`
}
type ReadDetailDto struct {
Id uint16 `json:"id"`
Id *uint16 `json:"id"`
Code *string `json:"code"`
Employee_Id *uint `json:"employee_id"`
IHS_Number *string `json:"ihs_number"`
}
type UpdateDto struct {
Id uint `json:"id"`
Id *uint `json:"id"`
CreateDto
}
type DeleteDto struct {
Id uint `json:"id"`
Id *uint `json:"id"`
Code *string `json:"code"`
}
type MetaDto struct {
@@ -6,11 +6,11 @@ import (
)
type CreateDto struct {
Doctor_Id *uint `json:"doctor_id"`
Unit_Code *string `json:"unit_code"`
Day_Code *erc.DayCode `json:"day_code"`
StartTime *string `json:"startTime" validate:"maxLength=5"`
EndTime *string `json:"endTime" validate:"maxLength=5"`
Doctor_Code *string `json:"doctor_code"`
Unit_Code *string `json:"unit_code"`
Day_Code *erc.DayCode `json:"day_code"`
StartTime *string `json:"startTime" validate:"maxLength=5"`
EndTime *string `json:"endTime" validate:"maxLength=5"`
}
type ReadListDto struct {
@@ -20,11 +20,11 @@ type ReadListDto struct {
}
type FilterDto struct {
Doctor_Id *uint `json:"doctor-id"`
Unit_Code *string `json:"unit-code"`
Day_Code *erc.DayCode `json:"day-code"`
StartTime *string `json:"startTime"`
EndTime *string `json:"endTime"`
Doctor_Code *string `json:"doctor-code"`
Unit_Code *string `json:"unit-code"`
Day_Code *erc.DayCode `json:"day-code"`
StartTime *string `json:"startTime"`
EndTime *string `json:"endTime"`
}
type ReadDetailDto struct {
@@ -48,20 +48,20 @@ type MetaDto struct {
type ResponseDto struct {
ecore.Main
Doctor_Id *uint `json:"doctor_id"`
Unit_Code *string `json:"unit_code"`
Day_Code *erc.DayCode `json:"day_code"`
StartTime *string `json:"startTime"`
EndTime *string `json:"endTime"`
Doctor_Code *string `json:"doctor_code"`
Unit_Code *string `json:"unit_code"`
Day_Code *erc.DayCode `json:"day_code"`
StartTime *string `json:"startTime"`
EndTime *string `json:"endTime"`
}
func (d PracticeSchedule) ToResponse() ResponseDto {
resp := ResponseDto{
Doctor_Id: d.Doctor_Id,
Unit_Code: d.Unit_Code,
Day_Code: d.Day_Code,
StartTime: d.StartTime,
EndTime: d.EndTime,
Doctor_Code: d.Doctor_Code,
Unit_Code: d.Unit_Code,
Day_Code: d.Day_Code,
StartTime: d.StartTime,
EndTime: d.EndTime,
}
resp.Main = d.Main
return resp
@@ -8,12 +8,12 @@ import (
)
type PracticeSchedule struct {
ecore.Main // adjust this according to the needs
Doctor_Id *uint `json:"doctor_id"`
Doctor *ed.Doctor `json:"doctor,omitempty" gorm:"foreignKey:Doctor_Id;references:Id"`
Unit_Code *string `json:"unit_code"`
Unit *eu.Unit `json:"unit,omitempty" gorm:"foreignKey:Unit_Code;references:Code"`
Day_Code *erc.DayCode `json:"day_code"`
StartTime *string `json:"startTime" gorm:"size:5"`
EndTime *string `json:"endTime" gorm:"size:5"`
ecore.Main // adjust this according to the needs
Doctor_Code *string `json:"doctor_code"`
Doctor *ed.Doctor `json:"doctor,omitempty" gorm:"foreignKey:Doctor_Code;references:Code"`
Unit_Code *string `json:"unit_code"`
Unit *eu.Unit `json:"unit,omitempty" gorm:"foreignKey:Unit_Code;references:Code"`
Day_Code *erc.DayCode `json:"day_code"`
StartTime *string `json:"startTime" gorm:"size:5"`
EndTime *string `json:"endTime" gorm:"size:5"`
}
@@ -1,16 +1,21 @@
package base
import (
erc "simrs-vx/internal/domain/references/common"
ere "simrs-vx/internal/domain/references/encounter"
"time"
ecore "simrs-vx/internal/domain/base-entities/core"
ed "simrs-vx/internal/domain/main-entities/doctor"
)
type Basic struct {
ecore.Main // adjust this according to the needs
Encounter_Id *uint `json:"encounter_id"`
Doctor_Id *uint `json:"doctor_id"`
Doctor *ed.Doctor `json:"doctor,omitempty" gorm:"foreignKey:Doctor_Id;references:Id"`
AllocatedVisitCount *int `json:"allocatedVisitCount"`
ecore.Main // adjust this according to the needs
Parent_Encounter_Id *uint `json:"parent_encounter_id"`
Encounter_Id *uint `json:"encounter_id"`
AllocatedVisitCount *int `json:"allocatedVisitCount"`
ExpiredAt *time.Time `json:"expiredAt"`
VisitMode_Code *ere.VisitModeCode `json:"visitMode_code"`
Status_Code *erc.DataStatusCode `json:"status_code"`
}
func (Basic) TableName() string {
+23 -12
View File
@@ -1,14 +1,20 @@
package rehab
import (
erc "simrs-vx/internal/domain/references/common"
ere "simrs-vx/internal/domain/references/encounter"
ecore "simrs-vx/internal/domain/base-entities/core"
ed "simrs-vx/internal/domain/main-entities/doctor"
"time"
)
type CreateDto struct {
Encounter_Id *uint `json:"encounter_id"`
Doctor_Id *uint `json:"doctor_id"`
AllocatedVisitCount *int `json:"allocatedVisitCount"`
Encounter_Id *uint `json:"encounter_id"`
Parent_Encounter_Id *uint `json:"parent_encounter_id"`
AllocatedVisitCount *int `json:"allocatedVisitCount"`
ExpiredAt *time.Time `json:"expiredAt"`
VisitMode_Code ere.VisitModeCode `json:"visitMode_code"`
Status_Code erc.DataStatusCode `json:"status_code"`
}
type ReadListDto struct {
@@ -18,8 +24,9 @@ type ReadListDto struct {
}
type FilterDto struct {
Encounter_Id *uint `json:"encounter-id"`
Doctor_Id *uint `json:"doctor-id"`
Encounter_Id *uint `json:"encounter-id"`
Parent_Encounter_Id *uint `json:"parent-encounter-id"`
VisitMode_Code ere.VisitModeCode `json:"visitMode-code"`
}
type ReadDetailDto struct {
@@ -44,18 +51,22 @@ type MetaDto struct {
type ResponseDto struct {
ecore.Main
Encounter_Id *uint `json:"encounter_id"`
Doctor_Id *uint `json:"doctor_id"`
Doctor *ed.Doctor `json:"doctor,omitempty"`
AllocatedVisitCount *int `json:"allocatedVisitCount"`
Encounter_Id *uint `json:"encounter_id"`
Parent_Encounter_Id *uint `json:"parent_encounter_id"`
AllocatedVisitCount *int `json:"allocatedVisitCount"`
ExpiredAt *time.Time `json:"expiredAt"`
VisitMode_Code *ere.VisitModeCode `json:"visitMode_code"`
Status_Code *erc.DataStatusCode `json:"status_code"`
}
func (d Rehab) ToResponse() ResponseDto {
resp := ResponseDto{
Encounter_Id: d.Encounter_Id,
Doctor_Id: d.Doctor_Id,
Doctor: d.Doctor,
Parent_Encounter_Id: d.Parent_Encounter_Id,
AllocatedVisitCount: d.AllocatedVisitCount,
ExpiredAt: d.ExpiredAt,
VisitMode_Code: d.VisitMode_Code,
Status_Code: d.Status_Code,
}
resp.Main = d.Main
return resp
@@ -8,7 +8,7 @@ import (
type CreateDto struct {
Encounter_Id *uint `json:"encounter_id"`
Doctor_Id *uint `json:"doctor_id"`
Doctor_Code *string `json:"doctor_code"`
StartedAt *time.Time `json:"startedAt"`
FinishedAt *time.Time `json:"finishedAt"`
}
@@ -22,7 +22,7 @@ type ReadListDto struct {
type FilterDto struct {
Encounter_Id *uint `json:"encounter-id"`
Doctor_Id *uint `json:"doctor-id"`
Doctor_Code *string `json:"doctor-code"`
StartedAt *time.Time `json:"startedAt"`
FinishedAt *time.Time `json:"finishedAt"`
}
@@ -50,7 +50,7 @@ type MetaDto struct {
type ResponseDto struct {
ecore.Main // adjust this according to the needs
Encounter_Id *uint `json:"encounter_id"`
Doctor_Id *uint `json:"doctor_id"`
Doctor_Code *string `json:"doctor_code"`
Doctor *ed.Doctor `json:"doctor,omitempty"`
StartedAt *time.Time `json:"startedAt"`
FinishedAt *time.Time `json:"finishedAt"`
@@ -59,7 +59,7 @@ type ResponseDto struct {
func (d ResponsibleDoctorHist) ToResponse() ResponseDto {
resp := ResponseDto{
Encounter_Id: d.Encounter_Id,
Doctor_Id: d.Doctor_Id,
Doctor_Code: d.Doctor_Code,
Doctor: d.Doctor,
StartedAt: d.StartedAt,
FinishedAt: d.FinishedAt,
@@ -9,8 +9,8 @@ import (
type ResponsibleDoctorHist struct {
ecore.Main // adjust this according to the needs
Encounter_Id *uint `json:"encounter_id"`
Doctor_Id *uint `json:"doctor_id"`
Doctor *ed.Doctor `json:"doctor,omitempty" gorm:"foreignKey:Doctor_Id;references:Id"`
Doctor_Code *string `json:"doctor_code"`
Doctor *ed.Doctor `json:"doctor,omitempty" gorm:"foreignKey:Doctor_Code;references:Code"`
StartedAt *time.Time `json:"startedAt"`
FinishedAt *time.Time `json:"finishedAt"`
}
@@ -53,7 +53,7 @@ type MetaDto struct {
type ResponseDto struct {
ecore.SmallMain
Subspecialist_Code *string `json:"subspecialist_id"`
Subspecialist_Code *string `json:"subspecialist_code"`
Subspecialist *es.Subspecialist `json:"subspecialist,omitempty"`
Code string `json:"code"`
Name string `json:"name"`
@@ -9,7 +9,7 @@ import (
type CreateDto struct {
Encounter_Id *uint `json:"encounter_id"`
Doctor_Id *uint `json:"doctor_id"`
Doctor_Code *string `json:"doctor_code"`
Anamnesis *string `json:"anamnesis" validate:"maxLength=2048"`
MedicalDiagnoses *string `json:"medicalDiagnoses"`
FunctionDiagnoses *string `json:"functionDiagnoses"`
@@ -31,8 +31,8 @@ type ReadListDto struct {
}
type FilterDto struct {
Encounter_Id *uint `json:"encounter-id"`
Doctor_Id *uint `json:"doctor-id"`
Encounter_Id *uint `json:"encounter-id"`
Doctor_Code *string `json:"doctor-code"`
}
type ReadDetailDto struct {
@@ -59,7 +59,7 @@ type ResponseDto struct {
ecore.Main
Encounter_Id *uint `json:"encounter_id"`
Encounter *ee.Encounter `json:"encounter,omitempty"`
Doctor_Id *uint `json:"doctor_id"`
Doctor_Code *string `json:"doctor_code"`
Doctor *ed.Doctor `json:"doctor,omitempty"`
Anamnesis *string `json:"anamnesis"`
MedicalDiagnoses *string `json:"medicalDiagnoses"`
@@ -79,7 +79,7 @@ func (d TherapyProtocol) ToResponse() ResponseDto {
resp := ResponseDto{
Encounter_Id: d.Encounter_Id,
Encounter: d.Encounter,
Doctor_Id: d.Doctor_Id,
Doctor_Code: d.Doctor_Code,
Doctor: d.Doctor,
Anamnesis: d.Anamnesis,
MedicalDiagnoses: d.MedicalDiagnoses,
@@ -13,8 +13,8 @@ type TherapyProtocol struct {
Encounter_Id *uint `json:"encounter_id" gorm:"not null"`
Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"`
Doctor_Id *uint `json:"doctor_id"`
Doctor *ed.Doctor `json:"doctor,omitempty" gorm:"foreignKey:Doctor_Id;references:Id"`
Doctor_Code *string `json:"doctor_code"`
Doctor *ed.Doctor `json:"doctor,omitempty" gorm:"foreignKey:Doctor_Code;references:Code"`
Anamnesis *string `json:"anamnesis" gorm:"size:2048"`
MedicalDiagnoses *string `json:"medicalDiagnoses"`
+25 -25
View File
@@ -2,26 +2,26 @@
package clinical
type (
SubjectCode string
ObjectCode string
AssessmentCode string
PlanCode string
InstructionCode string
HeadToToeCode string
McuUrgencyLevelCode string
McuScopeCode string
SoapiTypeCode string
MedicalAction string
VehicleTypeCode string
GeneralEduCode string
SpecialEduCode string
EduAssessmentCode string
AbilityCode string
WillCode string
MedObstacleCode string
LearnMethodCode string
LangClassCode string
TranslatorSrcCode string
SubjectCode string
ObjectCode string
AssessmentCode string
PlanCode string
InstructionCode string
HeadToToeCode string
McuUrgencyLevelCode string
McuScopeCode string
SoapiTypeCode string
MedicalActionTypeCode string
VehicleTypeCode string
GeneralEduCode string
SpecialEduCode string
EduAssessmentCode string
AbilityCode string
WillCode string
MedObstacleCode string
LearnMethodCode string
LangClassCode string
TranslatorSrcCode string
)
const (
@@ -124,11 +124,11 @@ const (
STCProgress SoapiTypeCode = "progress" // CPPT
STCDevRecord SoapiTypeCode = "dev-record" // Catatan Perkembangan
MAChemo MedicalAction = "chemo"
MAHemo MedicalAction = "hemo"
MAThalasemia MedicalAction = "thalasemia"
MAEchocardio MedicalAction = "echocardio"
MASpirometry MedicalAction = "spirometry"
MATCChemo MedicalActionTypeCode = "chemo"
MATCHemo MedicalActionTypeCode = "hemo"
MATCThalasemia MedicalActionTypeCode = "thalasemia"
MATCEchocardio MedicalActionTypeCode = "echocardio"
MATCSpirometry MedicalActionTypeCode = "spirometry"
VTCAmbulance VehicleTypeCode = "ambulance" // Ambulans
VTCTransport VehicleTypeCode = "transport" // Transport
@@ -15,6 +15,7 @@ type (
DataAvailabilityCode string
DataVerifiedCode string
CrudCode string
DataApprovalCode string
)
const (
@@ -96,6 +97,10 @@ const (
CCRead CrudCode = "r" // Read
CCUpdate CrudCode = "u" // Update
CCDelete CrudCode = "d" // Delete
DACNew DataApprovalCode = "new"
DACApproved DataApprovalCode = "approved"
DACRejected DataApprovalCode = "rejected"
)
func GetDayCodes() map[DayCode]string {
@@ -18,6 +18,7 @@ type (
AllPaymentMethodCode string
SEPRefTypeCode string
VisitModeCode string
PolySwitchCode string
)
const (
@@ -107,6 +108,9 @@ const (
VMCAdm VisitModeCode = "adm"
VMCSeries VisitModeCode = "series"
PSCConsulPoly PolySwitchCode = "consul-poly" // Konsultasi Poliklinik Lain
PSCConsulExecutive PolySwitchCode = "consul-executive" // Konsultasi Antar Dokter Eksekutif
)
func (ec EncounterClassCode) Code() string {
@@ -33,19 +33,19 @@ func (obj myBase) GetList(w http.ResponseWriter, r *http.Request) {
}
func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) {
id := rw.ValidateInt(w, "code", r.PathValue("code"))
if id <= 0 {
code := rw.ValidateString(w, "code", r.PathValue("code"))
if code == "" {
return
}
dto := e.ReadDetailDto{}
dto.Id = uint16(id)
dto.Code = &code
res, err := u.ReadDetail(dto)
rw.DataResponse(w, res, err)
}
func (obj myBase) Update(w http.ResponseWriter, r *http.Request) {
id := rw.ValidateInt(w, "code", r.PathValue("code"))
if id <= 0 {
code := rw.ValidateString(w, "code", r.PathValue("code"))
if code == "" {
return
}
@@ -53,19 +53,19 @@ func (obj myBase) Update(w http.ResponseWriter, r *http.Request) {
if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
return
}
dto.Id = uint(id)
dto.Code = &code
res, err := u.Update(dto)
rw.DataResponse(w, res, err)
}
func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) {
id := rw.ValidateInt(w, "code", r.PathValue("code"))
if id <= 0 {
code := rw.ValidateString(w, "code", r.PathValue("code"))
if code == "" {
return
}
dto := e.DeleteDto{}
dto.Id = uint(id)
dto.Code = &code
res, err := u.Delete(dto)
rw.DataResponse(w, res, err)
}
@@ -3,18 +3,17 @@ package encounter
import (
"net/http"
pa "simrs-vx/internal/lib/auth"
d "github.com/karincake/dodol"
rw "github.com/karincake/risoles"
sf "github.com/karincake/semprit"
// ua "github.com/karincake/tumpeng/auth/svc"
erc "simrs-vx/internal/domain/references/common"
e "simrs-vx/internal/domain/main-entities/encounter"
u "simrs-vx/internal/use-case/main-use-case/encounter"
erc "simrs-vx/internal/domain/references/common"
pa "simrs-vx/internal/lib/auth"
d "github.com/karincake/dodol"
)
type myBase struct{}
@@ -31,7 +30,13 @@ func (obj myBase) Create(w http.ResponseWriter, r *http.Request) {
if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
return
}
if valid := validateRequestCreate(w, dto); !valid {
// validate SubClass
if err := verifyClassCode(dto); err != nil {
rw.DataResponse(w, nil, d.FieldError{
Code: dataValidationFail,
Message: err.Error(),
})
return
}
@@ -192,3 +197,40 @@ func (obj myBase) Skip(w http.ResponseWriter, r *http.Request) {
res, err := u.UpdateStatusCode(dto)
rw.DataResponse(w, res, err)
}
func (obj myBase) RequestSwitchUnit(w http.ResponseWriter, r *http.Request) {
dto := e.SwitchUnitDto{}
id := rw.ValidateInt(w, "id", r.PathValue("id"))
if id <= 0 {
return
}
if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
return
}
// validate request body
if valid := validateRequestSwitchUnit(w, dto); !valid {
return
}
dto.Id = uint(id)
res, err := u.RequestSwitchUnit(dto)
rw.DataResponse(w, res, err)
}
func (obj myBase) ApproveSwitchUnit(w http.ResponseWriter, r *http.Request) {
dto := e.ApproveUnitDto{}
id := rw.ValidateInt(w, "id", r.PathValue("id"))
if id <= 0 {
return
}
if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
return
}
dto.Id = uint(id)
res, err := u.ApproveSwitchUnit(dto)
rw.DataResponse(w, res, err)
}
@@ -1,10 +1,14 @@
package encounter
import (
"errors"
"fmt"
"net/http"
e "simrs-vx/internal/domain/main-entities/encounter"
ere "simrs-vx/internal/domain/references/encounter"
ua "simrs-vx/internal/use-case/main-use-case/ambulatory"
ue "simrs-vx/internal/use-case/main-use-case/emergency"
ui "simrs-vx/internal/use-case/main-use-case/inpatient"
d "github.com/karincake/dodol"
rw "github.com/karincake/risoles"
@@ -12,51 +16,41 @@ import (
const dataValidationFail = "data-validation-fail"
func verifyClassCode(input e.CreateDto) (err error) {
switch input.Class_Code {
case ere.ECAmbulatory:
_, err = ua.CheckClassCode(input.SubClass_Code)
case ere.ECEmergency:
_, err = ue.CheckClassCode(input.SubClass_Code)
case ere.ECInpatient:
_, err = ui.CheckClassCode(input.SubClass_Code)
default:
return errors.New("invalid encounter class code")
}
if err != nil {
return
}
return nil
}
func validateRequestCheckout(w http.ResponseWriter, i e.DischargeDto) (valid bool) {
switch *i.Discharge_Method_Code {
case ere.DMCDeath:
if i.DeathCause == nil {
rw.DataResponse(w, nil, d.FieldError{
Code: dataValidationFail,
Message: "deathCause required if discharge_method_code is death",
})
return
}
case ere.DMCConsulPoly, ere.DMCConsulExecutive:
if i.InternalReferences == nil {
rw.DataResponse(w, nil, d.FieldError{
Code: dataValidationFail,
Message: fmt.Sprintf("internalReferences required if discharge_method_code is %s", *i.Discharge_Method_Code),
})
return
}
for _, v := range *i.InternalReferences {
if v.Unit_Id == nil {
rw.DataResponse(w, nil, d.FieldError{
Code: dataValidationFail,
Message: "internalReferences.unit_id required",
})
return
}
if v.Doctor_Id == nil {
rw.DataResponse(w, nil, d.FieldError{
Code: dataValidationFail,
Message: "internalReferences.doctor_id required",
})
return
}
}
if *i.Discharge_Method_Code == ere.DMCDeath && i.DeathCause == nil {
rw.DataResponse(w, nil, d.FieldError{
Code: dataValidationFail,
Message: "deathCause required if discharge_method_code is death",
})
return
}
return true
}
func validateRequestCheckIn(w http.ResponseWriter, i e.CheckinDto) (valid bool) {
if i.Responsible_Doctor_Id == nil {
if i.Responsible_Doctor_Code == nil {
rw.DataResponse(w, nil, d.FieldError{
Code: dataValidationFail,
Message: "responsible_doctor_id required",
Message: "responsible_doctor_code required",
})
return
}
@@ -64,18 +58,30 @@ func validateRequestCheckIn(w http.ResponseWriter, i e.CheckinDto) (valid bool)
return true
}
func validateRequestCreate(w http.ResponseWriter, i e.CreateDto) (valid bool) {
switch {
case i.Class_Code == ere.ECAmbulatory:
// field allocatedVisitCount required if ambulatory visitMode_Code is adm
if ere.AmbulatoryClassCode(*i.SubClass_Code) == ere.ACCRehab && *i.VisitMode_Code == ere.VMCAdm {
if *i.AllocatedVisitCount == 0 {
rw.DataResponse(w, nil, d.FieldError{
Code: dataValidationFail,
Message: "allocatedVisitCount required",
})
return
}
func validateRequestSwitchUnit(w http.ResponseWriter, i e.SwitchUnitDto) (valid bool) {
if i.InternalReferences == nil {
rw.DataResponse(w, nil, d.FieldError{
Code: dataValidationFail,
Message: fmt.Sprintf("internalReferences required"),
})
return
}
for _, v := range *i.InternalReferences {
if v.Unit_Code == nil {
rw.DataResponse(w, nil, d.FieldError{
Code: dataValidationFail,
Message: "internalReferences.unit_code required",
})
return
}
if v.Doctor_Code == nil {
rw.DataResponse(w, nil, d.FieldError{
Code: dataValidationFail,
Message: "internalReferences.doctor_code required",
})
return
}
}
+13 -11
View File
@@ -145,17 +145,19 @@ func SetRoutes() http.Handler {
hc.RegCrud(r, "/v1/material-order-item", materialorderitem.O)
hk.GroupRoutes("/v1/encounter", r, auth.GuardMW, hk.MapHandlerFunc{
"GET /": encounter.O.GetList,
"GET /{id}": encounter.O.GetDetail,
"POST /": encounter.O.Create,
"PATCH /{id}": encounter.O.Update,
"DELETE /{id}": encounter.O.Delete,
"PATCH /{id}/check-out": encounter.O.CheckOut,
"PATCH /{id}/check-in": encounter.O.CheckIn,
"PATCH /{id}/proccess": encounter.O.Process,
"PATCH /{id}/cancel": encounter.O.Cancel,
"PATCH /{id}/reject": encounter.O.Reject,
"PATCH /{id}/skip": encounter.O.Skip,
"GET /": encounter.O.GetList,
"GET /{id}": encounter.O.GetDetail,
"POST /": encounter.O.Create,
"PATCH /{id}": encounter.O.Update,
"DELETE /{id}": encounter.O.Delete,
"PATCH /{id}/check-out": encounter.O.CheckOut,
"PATCH /{id}/check-in": encounter.O.CheckIn,
"PATCH /{id}/proccess": encounter.O.Process,
"PATCH /{id}/cancel": encounter.O.Cancel,
"PATCH /{id}/reject": encounter.O.Reject,
"PATCH /{id}/skip": encounter.O.Skip,
"PATCH /{id}/req-switch-unit": encounter.O.RequestSwitchUnit,
"PATCH /{id}/approve-switch-unit": encounter.O.ApproveSwitchUnit,
})
hk.GroupRoutes("/v1/mcu-order", r, auth.GuardMW, hk.MapHandlerFunc{
"GET /": mcuorder.O.GetList,
@@ -33,19 +33,19 @@ func (obj myBase) GetList(w http.ResponseWriter, r *http.Request) {
}
func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) {
id := rw.ValidateInt(w, "code", r.PathValue("code"))
if id <= 0 {
code := rw.ValidateString(w, "code", r.PathValue("code"))
if code == "" {
return
}
dto := e.ReadDetailDto{}
dto.Id = uint16(id)
dto.Code = &code
res, err := u.ReadDetail(dto)
rw.DataResponse(w, res, err)
}
func (obj myBase) Update(w http.ResponseWriter, r *http.Request) {
id := rw.ValidateInt(w, "code", r.PathValue("code"))
if id <= 0 {
code := rw.ValidateString(w, "code", r.PathValue("code"))
if code == "" {
return
}
@@ -53,19 +53,19 @@ func (obj myBase) Update(w http.ResponseWriter, r *http.Request) {
if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
return
}
dto.Id = uint(id)
dto.Code = &code
res, err := u.Update(dto)
rw.DataResponse(w, res, err)
}
func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) {
id := rw.ValidateInt(w, "code", r.PathValue("code"))
if id <= 0 {
code := rw.ValidateString(w, "code", r.PathValue("code"))
if code == "" {
return
}
dto := e.DeleteDto{}
dto.Id = uint(id)
dto.Code = &code
res, err := u.Delete(dto)
rw.DataResponse(w, res, err)
}
@@ -22,7 +22,6 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Ambulatory) {
data.Encounter_Id = inputSrc.Encounter_Id
data.Class_Code = inputSrc.Class_Code
data.VisitMode_Code = inputSrc.VisitMode_Code
}
func CheckClassCode(input *string) (ere.AmbulatoryClassCode, error) {
@@ -313,12 +313,12 @@ func ExtractToken(r *http.Request, tokenType TokenType) (data *pa.AuthInfo, err
data.User_ContractPosition_code = checkStrClaims(claims, "contractPosition_code")
data.Employee_Position_Code = checkStrPtrClaims(claims, "employee_position_code")
data.Doctor_Code = checkStrPtrClaims(claims, "doctor_string")
data.Nurse_Code = checkStrPtrClaims(claims, "nurse_string")
data.Midwife_Code = checkStrPtrClaims(claims, "midwife_string")
data.Nutritionist_Code = checkStrPtrClaims(claims, "nutritionist_string")
data.Laborant_Code = checkStrPtrClaims(claims, "laborant_string")
data.Pharmachist_Code = checkStrPtrClaims(claims, "pharmachist_string")
data.Doctor_Code = checkStrPtrClaims(claims, "doctor_code")
data.Nurse_Code = checkStrPtrClaims(claims, "nurse_code")
data.Midwife_Code = checkStrPtrClaims(claims, "midwife_code")
data.Nutritionist_Code = checkStrPtrClaims(claims, "nutritionist_code")
data.Laborant_Code = checkStrPtrClaims(claims, "laborant_code")
data.Pharmachist_Code = checkStrPtrClaims(claims, "pharmachist_code")
data.Intern_Position_Code = checkStrPtrClaims(claims, "intern_position_code")
data.Employee_Id = checkUntPtrClaims(claims, "employee_id")
return
@@ -19,5 +19,5 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Chemo) {
data.Encounter_Id = inputSrc.Encounter_Id
data.Status_Code = inputSrc.Status_Code
data.SrcUnit_Id = inputSrc.SrcUnit_Id
data.SrcUnit_Code = inputSrc.SrcUnit_Code
}
@@ -7,8 +7,6 @@ import (
e "simrs-vx/internal/domain/main-entities/consultation"
ue "simrs-vx/internal/use-case/main-use-case/encounter"
ud "simrs-vx/internal/use-case/main-use-case/doctor"
dg "github.com/karincake/apem/db-gorm-pg"
d "github.com/karincake/dodol"
@@ -314,12 +312,7 @@ func Reply(input e.ReplyDto) (*d.Data, error) {
return pl.SetLogError(&event, input)
}
doctor_id, err := ud.GetIdByUserId(&input.AuthInfo.User_Id, &event, tx)
if err != nil {
return err
}
if data.DstDoctor_Id != nil && data.DstDoctor_Id != doctor_id {
if data.DstDoctor_Code != nil && data.DstDoctor_Code != input.AuthInfo.Doctor_Code {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-handled-mismatch",
@@ -329,7 +322,7 @@ func Reply(input e.ReplyDto) (*d.Data, error) {
return pl.SetLogError(&event, input)
}
data.DstDoctor_Id = doctor_id
data.DstDoctor_Code = input.AuthInfo.Doctor_Code
data.Solution = input.Solution
data.RepliedAt = pu.GetTimeNow()
err = tx.Save(&data).Error
@@ -20,5 +20,5 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Consultation) {
data.Encounter_Id = inputSrc.Encounter_Id
data.Date = inputSrc.Date
data.Problem = inputSrc.Problem
data.DstUnit_Id = inputSrc.DstUnit_Id
data.DstUnit_Code = inputSrc.DstUnit_Code
}
@@ -18,9 +18,9 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.ControlLetter) {
}
data.Encounter_Id = inputSrc.Encounter_Id
data.Unit_Id = inputSrc.Unit_Id
data.Specialist_Id = inputSrc.Specialist_Id
data.Subspecialist_Id = inputSrc.Subspecialist_Id
data.Doctor_Id = inputSrc.Doctor_Id
data.Unit_Code = inputSrc.Unit_Code
data.Specialist_Code = inputSrc.Specialist_Code
data.Subspecialist_Code = inputSrc.Subspecialist_Code
data.Doctor_Code = inputSrc.Doctor_Code
data.Date = inputSrc.Date
}
@@ -166,7 +166,7 @@ func ReadDetail(input e.ReadDetailDto) (*d.Data, error) {
}
func Update(input e.UpdateDto) (*d.Data, error) {
rdDto := e.ReadDetailDto{Id: uint16(input.Id)}
rdDto := e.ReadDetailDto{Code: input.Code}
var data *e.Doctor
var err error
@@ -222,7 +222,7 @@ func Update(input e.UpdateDto) (*d.Data, error) {
}
func Delete(input e.DeleteDto) (*d.Data, error) {
rdDto := e.ReadDetailDto{Id: uint16(input.Id)}
rdDto := e.ReadDetailDto{Code: input.Code}
var data *e.Doctor
var err error
@@ -84,7 +84,7 @@ func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e
if input.Employee_Id != nil {
tx = tx.Where("\"Employee_Id\" = ?", *input.Employee_Id)
}
if input.Id > 0 {
if input.Id != nil {
tx = tx.Where("\"Id\" = ?", input.Id)
}
if err := tx.First(&data).Error; err != nil {
+243 -168
View File
@@ -2,7 +2,7 @@ package encounter
import (
"errors"
authhelper "simrs-vx/internal/lib/auth"
"fmt"
"strconv"
"time"
@@ -17,28 +17,18 @@ import (
ere "simrs-vx/internal/domain/references/encounter"
eaeh "simrs-vx/internal/domain/main-entities/adm-employee-hist"
ea "simrs-vx/internal/domain/main-entities/ambulatory"
ec "simrs-vx/internal/domain/main-entities/chemo"
edc "simrs-vx/internal/domain/main-entities/death-cause"
ed "simrs-vx/internal/domain/main-entities/doctor"
ee "simrs-vx/internal/domain/main-entities/emergency"
eem "simrs-vx/internal/domain/main-entities/employee"
e "simrs-vx/internal/domain/main-entities/encounter"
ei "simrs-vx/internal/domain/main-entities/inpatient"
er "simrs-vx/internal/domain/main-entities/rehab"
eir "simrs-vx/internal/domain/main-entities/internal-reference"
erdh "simrs-vx/internal/domain/main-entities/responsible-doctor-hist"
es "simrs-vx/internal/domain/main-entities/soapi"
uaeh "simrs-vx/internal/use-case/main-use-case/adm-employee-hist"
ua "simrs-vx/internal/use-case/main-use-case/ambulatory"
uc "simrs-vx/internal/use-case/main-use-case/chemo"
udc "simrs-vx/internal/use-case/main-use-case/death-cause"
ud "simrs-vx/internal/use-case/main-use-case/doctor"
ue "simrs-vx/internal/use-case/main-use-case/emergency"
uem "simrs-vx/internal/use-case/main-use-case/employee"
ui "simrs-vx/internal/use-case/main-use-case/inpatient"
ur "simrs-vx/internal/use-case/main-use-case/rehab"
us "simrs-vx/internal/use-case/main-use-case/soapi"
uir "simrs-vx/internal/use-case/main-use-case/internal-reference"
urdh "simrs-vx/internal/use-case/main-use-case/responsible-doctor-hist"
)
const source = "encounter"
@@ -46,8 +36,11 @@ const source = "encounter"
var now = time.Now()
func Create(input e.CreateDto) (*d.Data, error) {
data := e.Encounter{}
createSoapi := []es.CreateDto{}
var (
data e.Encounter
recentSoapiDataforCopy []es.CreateDto
err error
)
event := pl.Event{
Feature: "Create",
@@ -57,51 +50,36 @@ func Create(input e.CreateDto) (*d.Data, error) {
// Start log
pl.SetLogInfo(&event, input, "started", "create")
// validate SubClass
var subCode interface{}
subCode, err := verifyClassCode(input)
if err != nil {
return nil, err
}
// verify whether the allocated visit count has not exceeded the limit
if input.Class_Code == ere.ECAmbulatory && subCode.(ere.AmbulatoryClassCode) == ere.ACCRehab &&
*input.VisitMode_Code == ere.VMCSeries {
dataEncounter, valid, err := verifyAllocatedVisitCount(input, &event)
// validate rehab bpjs
if input.RefTypeCode == ere.RTCBpjs && input.Class_Code == ere.ECAmbulatory && ere.AmbulatoryClassCode(*input.SubClass_Code) == ere.ACCRehab {
// get latest rehab data
recentRehabData, err := getLatestRehabData(input, &event)
if err != nil {
return nil, err
}
if !valid {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "visit-limit-exceeded",
Detail: "Encounter has exceeded the allowed number of visits",
Raw: errors.New("visit count exceeds allowed limit"),
if recentRehabData != nil {
// determine VisitModeCode
input.VisitMode_Code, input.RecentEncounterAdm, err = determineVisitMode(recentRehabData, input, &event)
if err != nil {
return nil, err
}
return nil, pl.SetLogError(&event, input)
} else {
input.VisitMode_Code = ere.VMCAdm
}
// get data soapi
createSoapi, err = getSoapiEncounterAdm(dataEncounter, &event)
if err != nil {
return nil, err
// if visitMode_Code is series, then get data soapi for copy
if input.VisitMode_Code == ere.VMCSeries {
// get data soapi
recentSoapiDataforCopy, err = getSoapiEncounterAdm(*input.RecentEncounterAdm, &event)
if err != nil {
return nil, err
}
}
}
// check if patient is new in the hospital
dataPatient, err := ReadList(e.ReadListDto{
FilterDto: e.FilterDto{Patient_Id: input.Patient_Id},
AuthInfo: authhelper.AuthInfo{User_Id: input.User_Id}})
if err != nil {
return nil, err
}
if list, ok := dataPatient.Data.([]e.ResponseDto); ok {
if len(list) < 1 {
input.NewStatus = true
}
}
input.NewStatus, err = identifyPatientStatus(input)
err = dg.I.Transaction(func(tx *gorm.DB) error {
mwRunner := newMiddlewareRunner(&event, tx)
@@ -122,74 +100,18 @@ func Create(input e.CreateDto) (*d.Data, error) {
return err
} else {
data = *resData
input.Id = data.Id
}
switch input.Class_Code {
case ere.ECAmbulatory:
subCodeAmbulatory := subCode.(ere.AmbulatoryClassCode)
ambCreate := ea.CreateDto{
Encounter_Id: &data.Id,
Class_Code: subCodeAmbulatory,
VisitMode_Code: *input.VisitMode_Code,
}
_, err = ua.CreateData(ambCreate, &event, tx)
if err != nil {
return err
}
if subCodeAmbulatory == ere.ACCChemo {
chemoCreate := ec.CreateDto{
Encounter_Id: &data.Id,
Status_Code: erc.DVCNew,
SrcUnit_Id: input.Unit_Id,
}
_, err = uc.CreateData(chemoCreate, &event, tx)
if err != nil {
return err
}
}
if subCodeAmbulatory == ere.ACCRehab && *input.VisitMode_Code == ere.VMCAdm {
// create data rehab
if _, err = ur.CreateData(er.CreateDto{
Encounter_Id: &data.Id,
Doctor_Id: input.Appointment_Doctor_Id,
AllocatedVisitCount: input.AllocatedVisitCount}, &event, tx); err != nil {
return err
}
} else if subCodeAmbulatory == ere.ACCRehab && *input.VisitMode_Code == ere.VMCSeries {
// Insert Soapi
if err = us.CreateBulkData(createSoapi, data.Id, &event, tx); err != nil {
return err
}
}
case ere.ECEmergency:
emerCreate := ee.CreateDto{
Encounter_Id: &data.Id,
Class_Code: subCode.(ere.EmergencyClassCode),
}
_, err = ue.CreateData(emerCreate, &event, tx)
if err != nil {
return err
}
case ere.ECInpatient:
inpCreate := ei.CreateDto{
Encounter_Id: &data.Id,
Class_Code: subCode.(ere.InpatientClassCode),
Infra_Id: input.Infra_Id,
}
_, err = ui.CreateData(inpCreate, &event, tx)
if err != nil {
return err
}
default:
return errors.New("invalid encounter class code")
// insert ambulatory/emergency/inpatient
err = insertdataClassCode(input, recentSoapiDataforCopy, &event, tx)
if err != nil {
return err
}
// insert adm_employee_hist
if _, err := uaeh.CreateData(eaeh.CreateDto{
Encounter_Id: &data.Main.Id,
Encounter_Id: &data.Id,
Employee_Id: data.Adm_Employee_Id,
StartedAt: &now}, &event, tx); err != nil {
return err
@@ -441,7 +363,7 @@ func Delete(input e.DeleteDto) (*d.Data, error) {
}
func CheckOut(input e.DischargeDto) (*d.Data, error) {
rdDto := e.ReadDetailDto{Id: uint16(input.Id), Includes: "Ambulatory"}
rdDto := e.ReadDetailDto{Id: uint16(input.Id), Includes: "Ambulatory,Rehab"}
var data *e.Encounter
var err error
@@ -471,10 +393,16 @@ func CheckOut(input e.DischargeDto) (*d.Data, error) {
if data.Ambulatory != nil && (data.Ambulatory.Class_Code == ere.ACCReg || data.Ambulatory.Class_Code == ere.ACCRehab) {
// validate if soapi exist
err = getSoapiByTypeCode(input.Id, *data.Ambulatory, &event, "check-out")
if err != nil {
if err = getSoapiByTypeCode(data, &event, "check-out"); err != nil {
return err
}
if data.Ambulatory.Class_Code == ere.ACCRehab {
// verify and update rehabData if visit count has reached the allowed limit
if err = verifyRehabLimit(data, &event, tx); err != nil {
return err
}
}
} else {
// chemo TBC
if err := checkSoapiByDocExists(data.Id, &event, tx); err != nil {
@@ -497,26 +425,20 @@ func CheckOut(input e.DischargeDto) (*d.Data, error) {
}
// update finishedAt in latest responsible_doctor_hist
if err = updateLatestResponsibleDoctorHist(e.CheckinDto{Id: input.Id, StartedAt: &now}, &event, tx); err != nil {
if err = updateLatestResponsibleDoctorHist(e.CheckinDto{Id: input.Id, FinishedAt: &now}, &event, tx); err != nil {
return err
}
// update finishedAt in latest adm_employee_hist
if err = updateLatestAdmEmployeeHist(e.CheckinDto{Id: input.Id, StartedAt: &now}, &event, tx); err != nil {
if err = updateLatestAdmEmployeeHist(e.CheckinDto{Id: input.Id, FinishedAt: &now}, &event, tx); err != nil {
return err
}
switch *input.Discharge_Method_Code {
case ere.DMCDeath:
// insert data death-cause
// insert data death-cause
if *input.Discharge_Method_Code == ere.DMCDeath {
if _, err = udc.CreateData(edc.CreateDto{Encounter_Id: &input.Id, Value: input.DeathCause}, &event, tx); err != nil {
return err
}
case ere.DMCConsulPoly, ere.DMCConsulExecutive:
// bulk insert internal-references
if err = createInternalReferences(input, &event, tx); err != nil {
return err
}
}
pl.SetLogInfo(&event, nil, "complete")
@@ -645,25 +567,25 @@ func CheckIn(input e.CheckinDto) (*d.Data, error) {
// validate if soapi exist
if data.Ambulatory != nil && (data.Ambulatory.Class_Code == ere.ACCReg || data.Ambulatory.Class_Code == ere.ACCRehab) {
err = getSoapiByTypeCode(input.Id, *data.Ambulatory, &event, "check-in")
err = getSoapiByTypeCode(data, &event, "check-in")
if err != nil {
return err
}
}
// Insert responsible_doctor_hist if responsible_doctor_id has changed && update latest history
if data.Responsible_Doctor_Id == nil || *input.Responsible_Doctor_Id != *data.Responsible_Doctor_Id {
// Upsert responsible_doctor_hist if responsible_doctor_code has changed
if data.Responsible_Doctor_Code == nil || *input.Responsible_Doctor_Code != *data.Responsible_Doctor_Code {
// upsert responsibleDoctorHist
if err = upsertResponsibleDoctorHist(erdh.CreateDto{
Encounter_Id: &data.Id,
Doctor_Id: input.Responsible_Doctor_Id,
Doctor_Code: input.Responsible_Doctor_Code,
StartedAt: input.StartedAt,
}, &event, tx); err != nil {
return err
}
}
// Insert adm_employee_hist if adm_employee_id has changed && update latest history
// Upsert adm_employee_hist if adm_employee_id has changed
if input.Adm_Employee_Id != nil && *input.Adm_Employee_Id != *data.Adm_Employee_Id {
// upsert admEmployeeHist
if err = upsertAdmEmployeeHist(eaeh.CreateDto{
@@ -680,15 +602,6 @@ func CheckIn(input e.CheckinDto) (*d.Data, error) {
return err
}
if data.Ambulatory.Class_Code == ere.ACCRehab {
if err := updateRehabDoctor(er.UpdateDto{CreateDto: er.CreateDto{
Encounter_Id: &data.Id,
Doctor_Id: input.Responsible_Doctor_Id,
}}, &event, tx); err != nil {
return err
}
}
pl.SetLogInfo(&event, nil, "complete")
return nil
@@ -708,43 +621,205 @@ func CheckIn(input e.CheckinDto) (*d.Data, error) {
}, nil
}
func validateForeignKey(input e.CheckinDto) error {
// validate employee_Id
if input.Adm_Employee_Id != nil {
if _, err := uem.ReadDetail(eem.ReadDetailDto{Id: uint16(*input.Adm_Employee_Id)}); err != nil {
func RequestSwitchUnit(input e.SwitchUnitDto) (*d.Data, error) {
rdDto := e.ReadDetailDto{Id: uint16(input.Id), Includes: "Responsible_Doctor"}
var data *e.Encounter
var err error
event := pl.Event{
Feature: "RequestSwitchUnit",
Source: source,
}
// Start log
pl.SetLogInfo(&event, input, "started", "checkOut")
unitCodes := make(map[string]struct{})
doctorCodes := make(map[string]struct{})
for _, ref := range *input.InternalReferences {
if ref.Unit_Code != nil {
unitCodes[*ref.Unit_Code] = struct{}{}
}
if ref.Doctor_Code != nil {
doctorCodes[*ref.Doctor_Code] = struct{}{}
}
}
// validate unit
if err = validateUnitCodes(unitCodes, &event); err != nil {
return nil, err
}
// validate doctor
if err = validateDoctorCodes(doctorCodes, &event); err != nil {
return nil, err
}
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
}
}
// validate doctor_id
if input.Responsible_Doctor_Id != nil {
if _, err := ud.ReadDetail(ed.ReadDetailDto{Id: uint16(*input.Responsible_Doctor_Id)}); err != nil {
//if data.IsDone() {
// event.Status = "failed"
// event.ErrInfo = pl.ErrorInfo{
// Code: "data-state-mismatch",
// Detail: "encounter is done",
// Raw: errors.New("encounter is done"),
// }
// return pl.SetLogError(&event, input)
//}
// verify Soapi exist for current responsible doctor
dataSoapi, err := getSoapiByResponsibleDoctor(*data, &event)
if err != nil {
return err
}
if len(dataSoapi) < 1 {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "missing-soapi",
Detail: fmt.Sprintf("Missing soapi from latest responsible doctor"),
}
return pl.SetLogError(&event, input)
}
// bulk internal references
if err := uir.CreateBulkData(*input.InternalReferences, input.Id, &event, tx); err != nil {
return err
}
pl.SetLogInfo(&event, nil, "complete")
return nil
})
if err != nil {
return nil, err
}
return nil
return &d.Data{
Meta: d.IS{
"source": source,
"structure": "single-data",
"status": "requestSwitchUnit",
},
Data: data.ToResponse(),
}, nil
}
func verifyClassCode(input e.CreateDto) (subCode interface{}, err error) {
switch input.Class_Code {
case ere.ECAmbulatory:
subCode, err = ua.CheckClassCode(input.SubClass_Code)
if err != nil {
return nil, err
}
case ere.ECEmergency:
subCode, err = ue.CheckClassCode(input.SubClass_Code)
if err != nil {
return nil, err
}
case ere.ECInpatient:
subCode, err = ui.CheckClassCode(input.SubClass_Code)
if err != nil {
return nil, err
}
default:
return nil, errors.New("invalid encounter class code")
func ApproveSwitchUnit(input e.ApproveUnitDto) (*d.Data, error) {
rdDto := e.ReadDetailDto{Id: uint16(input.Id), Includes: "Responsible_Doctor"}
var data *e.Encounter
var err error
event := pl.Event{
Feature: "ApproveSwitchUnit",
Source: source,
}
return
// Start log
pl.SetLogInfo(&event, input, "started", "approveSwitchUnit")
err = dg.I.Transaction(func(tx *gorm.DB) error {
pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail")
if data, err = ReadDetailData(rdDto, &event, tx); err != nil {
return err
}
// get internal reference
irData, err := uir.ReadDetailData(eir.ReadDetailDto{
Id: input.InternalReferences_Id, Includes: "Doctor"}, &event, tx)
if err != nil {
return err
}
if *irData.Status_Code != erc.DACNew {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-state-mismatch",
Detail: "internal references is approve",
Raw: errors.New("internal references is approve"),
}
return pl.SetLogError(&event, input)
}
//if data.IsDone() {
// event.Status = "failed"
// event.ErrInfo = pl.ErrorInfo{
// Code: "data-state-mismatch",
// Detail: "encounter is done",
// Raw: errors.New("encounter is done"),
// }
// return pl.SetLogError(&event, input)
//}
// verify Soapi exist for current responsible doctor
dataSoapi, err := getSoapiByResponsibleDoctor(*data, &event)
if err != nil {
return err
}
if len(dataSoapi) < 1 {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "missing-soapi",
Detail: fmt.Sprintf("Missing soapi from latest responsible doctor"),
}
return pl.SetLogError(&event, input)
}
// update internal reference
if err = uir.UpdateData(eir.UpdateDto{
Id: input.InternalReferences_Id,
CreateDto: eir.CreateDto{
Encounter_Id: &input.Id,
Doctor_Code: irData.Doctor_Code,
Unit_Code: irData.Unit_Code,
Status_Code: erc.DACApproved,
}}, irData, &event, tx); err != nil {
return err
}
// update encounter
if err = updateEncounterApproveSwitchUnit(*irData, &event, tx); err != nil {
return err
}
// update latest responsible doctor hist
if err = updateLatestResponsibleDoctorHist(e.CheckinDto{Id: input.Id, FinishedAt: &now}, &event, tx); err != nil {
return err
}
// create responsible doctor based on internal reference data
if _, err = urdh.CreateData(erdh.CreateDto{
Encounter_Id: &input.Id,
Doctor_Code: irData.Doctor_Code,
StartedAt: &now,
}, &event, tx); err != nil {
return err
}
// update data response
data.Responsible_Doctor_Code = irData.Doctor_Code
data.Unit_Code = irData.Unit_Code //
data.Specialist_Code = irData.Doctor.Specialist_Code
data.Subspecialist_Code = irData.Doctor.Subspecialist_Code
pl.SetLogInfo(&event, nil, "complete")
return nil
})
if err != nil {
return nil, err
}
return &d.Data{
Meta: d.IS{
"source": source,
"structure": "single-data",
"status": "updated",
},
Data: data.ToResponse(),
}, nil
}
@@ -10,6 +10,8 @@ import (
"strings"
"time"
authhelper "simrs-vx/internal/lib/auth"
dg "github.com/karincake/apem/db-gorm-pg"
"gorm.io/gorm"
@@ -23,9 +25,13 @@ import (
eaeh "simrs-vx/internal/domain/main-entities/adm-employee-hist"
ea "simrs-vx/internal/domain/main-entities/ambulatory"
ec "simrs-vx/internal/domain/main-entities/chemo"
edo "simrs-vx/internal/domain/main-entities/device-order"
ed "simrs-vx/internal/domain/main-entities/doctor"
ee "simrs-vx/internal/domain/main-entities/emergency"
eem "simrs-vx/internal/domain/main-entities/employee"
e "simrs-vx/internal/domain/main-entities/encounter"
ei "simrs-vx/internal/domain/main-entities/inpatient"
emo "simrs-vx/internal/domain/main-entities/material-order"
emco "simrs-vx/internal/domain/main-entities/mcu-order"
em "simrs-vx/internal/domain/main-entities/medication"
@@ -36,19 +42,26 @@ import (
epi "simrs-vx/internal/domain/main-entities/prescription-item"
er "simrs-vx/internal/domain/main-entities/rehab"
erdh "simrs-vx/internal/domain/main-entities/responsible-doctor-hist"
es "simrs-vx/internal/domain/main-entities/soapi"
eu "simrs-vx/internal/domain/main-entities/unit"
// udo "simrs-vx/internal/use-case/main-use-case/device-order"
es "simrs-vx/internal/domain/main-entities/soapi"
uaeh "simrs-vx/internal/use-case/main-use-case/adm-employee-hist"
uir "simrs-vx/internal/use-case/main-use-case/internal-reference"
ua "simrs-vx/internal/use-case/main-use-case/ambulatory"
uc "simrs-vx/internal/use-case/main-use-case/chemo"
ud "simrs-vx/internal/use-case/main-use-case/doctor"
ue "simrs-vx/internal/use-case/main-use-case/emergency"
uem "simrs-vx/internal/use-case/main-use-case/employee"
ui "simrs-vx/internal/use-case/main-use-case/inpatient"
um "simrs-vx/internal/use-case/main-use-case/medication"
umei "simrs-vx/internal/use-case/main-use-case/medication-item"
umi "simrs-vx/internal/use-case/main-use-case/medicine-mix"
ummi "simrs-vx/internal/use-case/main-use-case/medicine-mix-item"
up "simrs-vx/internal/use-case/main-use-case/prescription"
upi "simrs-vx/internal/use-case/main-use-case/prescription-item"
ur "simrs-vx/internal/use-case/main-use-case/rehab"
urdh "simrs-vx/internal/use-case/main-use-case/responsible-doctor-hist"
us "simrs-vx/internal/use-case/main-use-case/soapi"
)
func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Encounter) {
@@ -63,18 +76,18 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Encounter) {
data.Patient_Id = inputSrc.Patient_Id
data.RegisteredAt = inputSrc.RegisteredAt
data.Class_Code = inputSrc.Class_Code
data.Unit_Id = inputSrc.Unit_Id
data.Specialist_Id = inputSrc.Specialist_Id
data.Subspecialist_Id = inputSrc.Subspecialist_Id
data.Unit_Code = inputSrc.Unit_Code
data.Specialist_Code = inputSrc.Specialist_Code
data.Subspecialist_Code = inputSrc.Subspecialist_Code
data.VisitDate = inputSrc.VisitDate
data.PaymentMethod_Code = inputSrc.PaymentMethod_Code
data.InsuranceCompany_Id = inputSrc.InsuranceCompany_Id
data.InsuranceCompany_Code = inputSrc.InsuranceCompany_Code
data.Member_Number = inputSrc.Member_Number
data.Ref_Number = inputSrc.Ref_Number
data.Trx_Number = inputSrc.Trx_Number
data.Appointment_Doctor_Id = inputSrc.Appointment_Doctor_Id
data.Appointment_Doctor_Code = inputSrc.Appointment_Doctor_Code
data.Adm_Employee_Id = inputSrc.Adm_Employee_Id
data.Responsible_Doctor_Id = inputSrc.Responsible_Doctor_Id
data.Responsible_Doctor_Code = inputSrc.Responsible_Doctor_Code
data.RefSource_Name = inputSrc.RefSource_Name
data.Appointment_Id = inputSrc.Appointment_Id
data.Status_Code = erc.DSCProcess
@@ -83,11 +96,11 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Encounter) {
}
func setDataUpdate(src e.UpdateDto, dst *e.Encounter) {
dst.Appointment_Doctor_Id = src.Appointment_Doctor_Id
dst.Responsible_Doctor_Id = src.Responsible_Doctor_Id
dst.Unit_Id = src.Unit_Id
dst.Specialist_Id = src.Specialist_Id
dst.Subspecialist_Id = src.Subspecialist_Id
dst.Appointment_Doctor_Code = src.Appointment_Doctor_Code
dst.Responsible_Doctor_Code = src.Responsible_Doctor_Code
dst.Unit_Code = src.Unit_Code
dst.Specialist_Code = src.Specialist_Code
dst.Subspecialist_Code = src.Subspecialist_Code
dst.VisitDate = src.VisitDate
}
@@ -104,6 +117,19 @@ func setDataDischarge(src e.DischargeDto, dst *e.Encounter) {
dst.FinishedAt = &now
}
func setDataUpdateStatus(src e.UpdateStatusDto, dst *e.Encounter) {
dst.Status_Code = src.StatusCode
}
func setDataCheckIn(src e.CheckinDto, dst *e.Encounter) {
if src.Adm_Employee_Id != nil {
dst.Adm_Employee_Id = src.Adm_Employee_Id
}
dst.Responsible_Doctor_Code = src.Responsible_Doctor_Code
dst.StartedAt = src.StartedAt
}
func checkSoapiByDocExists(encounter_id uint, event *pl.Event, tx *gorm.DB) error {
pl.SetLogInfo(event, nil, "started", "checkSoapiByDocExists")
var soapies []es.Soapi
@@ -335,113 +361,6 @@ func getMcuOrders(encounter_id uint, event *pl.Event, tx *gorm.DB) error {
return nil
}
func setDataUpdateStatus(src e.UpdateStatusDto, dst *e.Encounter) {
dst.Status_Code = src.StatusCode
}
func setDataCheckIn(src e.CheckinDto, dst *e.Encounter) {
if src.Adm_Employee_Id != nil {
dst.Adm_Employee_Id = src.Adm_Employee_Id
}
dst.Responsible_Doctor_Id = src.Responsible_Doctor_Id
dst.StartedAt = src.StartedAt
}
func createInternalReferences(input e.DischargeDto, event *pl.Event, tx *gorm.DB) error {
unitIDs := make(map[uint16]struct{})
doctorIDs := make(map[uint]struct{})
for _, ref := range *input.InternalReferences {
if ref.Unit_Id != nil {
unitIDs[*ref.Unit_Id] = struct{}{}
}
if ref.Doctor_Id != nil {
doctorIDs[*ref.Doctor_Id] = struct{}{}
}
}
// validate unitIds
if len(unitIDs) > 0 {
var ids []uint16
for id := range unitIDs {
ids = append(ids, id)
}
units, err := getUnits(ids, event, tx)
if err != nil {
return fmt.Errorf("failed to fetch units: %w", err)
}
if len(units) != len(ids) {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-validation-fail",
Detail: "unit_id not found",
}
return pl.SetLogError(event, nil)
}
}
// validate doctorIds
if len(doctorIDs) > 0 {
var ids []uint
for id := range doctorIDs {
ids = append(ids, id)
}
doctors, err := getDoctors(ids, event, tx)
if err != nil {
return fmt.Errorf("failed to fetch doctors: %w", err)
}
if len(doctors) != len(ids) {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-validation-fail",
Detail: "doctor_id not found",
}
return pl.SetLogError(event, nil)
}
}
if err := uir.CreateBulkData(*input.InternalReferences, input.Id, event, tx); err != nil {
return err
}
return nil
}
func getUnits(unitIds []uint16, event *pl.Event, tx *gorm.DB) ([]eu.Unit, error) {
pl.SetLogInfo(event, nil, "started", "getUnits")
var units []eu.Unit
err := tx.Where("\"Id\" IN ?", unitIds).Find(&units).Error
if err != nil {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-get-fail",
Detail: "get units",
Raw: err,
}
return nil, pl.SetLogError(event, nil)
}
return units, nil
}
func getDoctors(doctorIds []uint, event *pl.Event, tx *gorm.DB) ([]ed.Doctor, error) {
pl.SetLogInfo(event, nil, "started", "getDoctors")
var doctors []ed.Doctor
err := tx.Where("\"Id\" IN ?", doctorIds).Find(&doctors).Error
if err != nil {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-get-fail",
Detail: "get doctors",
Raw: err,
}
return nil, pl.SetLogError(event, nil)
}
return doctors, nil
}
func upsertResponsibleDoctorHist(input erdh.CreateDto, event *pl.Event, dbx ...*gorm.DB) error {
pl.SetLogInfo(event, nil, "started", "DBCreate")
@@ -476,9 +395,9 @@ func upsertResponsibleDoctorHist(input erdh.CreateDto, event *pl.Event, dbx ...*
default:
// Update
if err := tx.Model(&latest).Updates(map[string]interface{}{
"Doctor_Id": input.Doctor_Id,
"StartedAt": input.StartedAt,
"UpdatedAt": time.Now(),
"Doctor_Code": input.Doctor_Code,
"StartedAt": input.StartedAt,
"UpdatedAt": time.Now(),
}).Error; err != nil {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
@@ -566,7 +485,7 @@ func updateLatestResponsibleDoctorHist(input e.CheckinDto, event *pl.Event, dbx
result := tx.
Model(&erdh.ResponsibleDoctorHist{}).
Where("\"Id\" = (?)", subQuery).
Update("\"FinishedAt\"", input.StartedAt)
Update("\"FinishedAt\"", input.FinishedAt)
if result.Error != nil {
event.Status = "failed"
@@ -607,7 +526,7 @@ func updateLatestAdmEmployeeHist(input e.CheckinDto, event *pl.Event, dbx ...*go
result := tx.
Model(&eaeh.AdmEmployeeHist{}).
Where("\"Id\" = (?)", subQuery).
Update("\"FinishedAt\"", input.StartedAt)
Update("\"FinishedAt\"", input.FinishedAt)
if result.Error != nil {
event.Status = "failed"
@@ -628,9 +547,7 @@ func updateLatestAdmEmployeeHist(input e.CheckinDto, event *pl.Event, dbx ...*go
return nil
}
func getSoapiEncounterAdm(enc e.Encounter, event *pl.Event) (dataSoapi []es.CreateDto, err error) {
var data []es.Soapi
func getSoapiByResponsibleDoctor(enc e.Encounter, event *pl.Event) (data []es.Soapi, err error) {
pl.SetLogInfo(event, enc, "started", "DBReadList")
if enc.Responsible_Doctor == nil {
@@ -653,21 +570,22 @@ func getSoapiEncounterAdm(enc e.Encounter, event *pl.Event) (dataSoapi []es.Crea
if err != nil {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Raw: err,
Raw: err,
Code: "read-fail",
Detail: "Database read failed",
}
if errors.Is(err, gorm.ErrRecordNotFound) {
event.ErrInfo.Code = "data-not-found"
event.ErrInfo.Detail = "Data not found"
return nil, pl.SetLogError(event, enc)
}
event.ErrInfo.Code = "read-fail"
event.ErrInfo.Detail = "Database read failed"
return nil, pl.SetLogError(event, enc)
}
pl.SetLogInfo(event, nil, "complete")
return
}
func getSoapiEncounterAdm(enc e.Encounter, event *pl.Event) (dataSoapi []es.CreateDto, err error) {
data, err := getSoapiByResponsibleDoctor(enc, event)
if err != nil {
return nil, err
}
for _, s := range data {
// set data soapi for copy
@@ -690,39 +608,46 @@ func getSoapiEncounterAdm(enc e.Encounter, event *pl.Event) (dataSoapi []es.Crea
return
}
func getSoapiByTypeCode(encounterId uint, dataAmbulatory ea.Ambulatory, event *pl.Event, mode string) (err error) {
pl.SetLogInfo(event, encounterId, "started", "DBReadList")
func getSoapiByTypeCode(encounter *e.Encounter, event *pl.Event, mode string) (err error) {
pl.SetLogInfo(event, encounter, "started", "DBReadList")
var (
dataSoapi []es.Soapi
amb = encounter.Ambulatory
rehab = encounter.Rehab
)
// Set Query for get data Soapi
tx := dg.I.
Model(&es.Soapi{}).
Joins("JOIN \"Employee\" ON \"Employee\".\"Id\" = \"Soapi\".\"Employee_Id\"").
Where("\"Encounter_Id\" = ?", encounterId).
Where("\"Encounter_Id\" = ?", encounter.Id).
Where("\"Employee\".\"Position_Code\" = ?", erg.EPCDoc)
// Set Case
switch {
case dataAmbulatory.Class_Code == ere.ACCReg:
case amb.Class_Code == ere.ACCReg:
tx = tx.Where("\"Soapi\".\"TypeCode\" = ?", ercl.STCEEarlyMedic)
case dataAmbulatory.Class_Code == ere.ACCRehab && dataAmbulatory.VisitMode_Code == ere.VMCAdm:
case amb.Class_Code == ere.ACCRehab && *rehab.VisitMode_Code == ere.VMCAdm:
tx = tx.Where("\"Soapi\".\"TypeCode\" IN ?", []ercl.SoapiTypeCode{ercl.STCEEarlyMedic, ercl.STCFunc, ercl.STCEarlyRehab})
case dataAmbulatory.Class_Code == ere.ACCRehab && dataAmbulatory.VisitMode_Code == ere.VMCSeries:
case amb.Class_Code == ere.ACCRehab && *rehab.VisitMode_Code == ere.VMCSeries:
tx = tx.Where("\"Soapi\".\"TypeCode\" = ?", ercl.STCEarlyRehab)
}
if err = tx.Find(&dataSoapi).Error; err != nil {
return setDBError(event, err, encounterId)
return setDBError(event, err, encounter)
}
pl.SetLogInfo(event, nil, "complete")
return validateExistedSoapi(dataSoapi, &dataAmbulatory, event, mode)
return validateExistedSoapi(dataSoapi, encounter, event, mode)
}
func validateExistedSoapi(dataSoapi []es.Soapi, dataAmbulatory *ea.Ambulatory, event *pl.Event, mode string) error {
func validateExistedSoapi(dataSoapi []es.Soapi, dataEncounter *e.Encounter, event *pl.Event, mode string) error {
var (
amb = dataEncounter.Ambulatory
rehab = dataEncounter.Rehab
)
typeExist := make(map[ercl.SoapiTypeCode]bool)
for _, s := range dataSoapi {
typeExist[s.TypeCode] = true
@@ -731,11 +656,11 @@ func validateExistedSoapi(dataSoapi []es.Soapi, dataAmbulatory *ea.Ambulatory, e
required := []ercl.SoapiTypeCode{}
switch {
case dataAmbulatory.Class_Code == ere.ACCReg:
case amb.Class_Code == ere.ACCReg:
required = []ercl.SoapiTypeCode{ercl.STCEEarlyMedic}
case dataAmbulatory.Class_Code == ere.ACCRehab && dataAmbulatory.VisitMode_Code == ere.VMCAdm:
case amb.Class_Code == ere.ACCRehab && *rehab.VisitMode_Code == ere.VMCAdm:
required = []ercl.SoapiTypeCode{ercl.STCEEarlyMedic, ercl.STCFunc, ercl.STCEarlyRehab}
case dataAmbulatory.Class_Code == ere.ACCRehab && dataAmbulatory.VisitMode_Code == ere.VMCSeries:
case amb.Class_Code == ere.ACCRehab && *rehab.VisitMode_Code == ere.VMCSeries:
required = []ercl.SoapiTypeCode{ercl.STCEarlyRehab}
}
@@ -762,6 +687,241 @@ func validateExistedSoapi(dataSoapi []es.Soapi, dataAmbulatory *ea.Ambulatory, e
return nil
}
func identifyPatientStatus(input e.CreateDto) (isNewPatient bool, err error) {
dataPatient, err := ReadList(e.ReadListDto{
FilterDto: e.FilterDto{Patient_Id: input.Patient_Id},
AuthInfo: authhelper.AuthInfo{User_Id: input.User_Id}})
if err != nil {
return
}
if list, ok := dataPatient.Data.([]e.ResponseDto); ok {
if len(list) < 1 {
isNewPatient = true
}
}
return
}
func determineVisitMode(recentRehabData *er.Rehab, input e.CreateDto, event *pl.Event) (ere.VisitModeCode, *e.Encounter, error) {
var (
visitModeCode ere.VisitModeCode
recentAdmEncounterData e.Encounter
isQuotaValid bool
err error
)
switch *recentRehabData.Status_Code {
case erc.DSCProcess:
visitModeCode = ere.VMCSeries
// verify whether the allocated visit count has not exceeded the limit
recentAdmEncounterData, isQuotaValid, err = verifyAllocatedVisitCount(input, event)
if err != nil {
return "", nil, err
}
if !isQuotaValid {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "visit-limit-exceeded",
Detail: "Encounter has exceeded the allowed number of visits",
Raw: errors.New("visit count exceeds allowed limit"),
}
return "", nil, pl.SetLogError(event, input)
}
if recentRehabData.ExpiredAt != nil && recentRehabData.ExpiredAt.Before(*pu.GetTimeNow()) {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "visit-limit-exceeded",
Detail: "Encounter period has expired",
Raw: errors.New("encounter expired"),
}
return "", nil, pl.SetLogError(event, input)
}
case erc.DSCDone:
visitModeCode = ere.VMCAdm
default:
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "invalid-status",
Detail: fmt.Sprintf("Unknown rehab status: %v", *recentRehabData.Status_Code),
Raw: errors.New("unsupported rehab status"),
}
return "", nil, pl.SetLogError(event, input)
}
return visitModeCode, &recentAdmEncounterData, nil
}
func insertdataClassCode(input e.CreateDto, soapiData []es.CreateDto, event *pl.Event, tx *gorm.DB) (err error) {
switch input.Class_Code {
case ere.ECAmbulatory:
subCode := ere.AmbulatoryClassCode(*input.SubClass_Code)
ambCreate := ea.CreateDto{
Encounter_Id: &input.Id,
Class_Code: subCode,
}
// create data Ambulatory
_, err = ua.CreateData(ambCreate, event, tx)
if err != nil {
return err
}
// insert chemo/rehab
err = insertDataSubClassAmbulatory(input, soapiData, event, tx)
if err != nil {
return err
}
case ere.ECEmergency:
subCode := ere.EmergencyClassCode(*input.SubClass_Code)
emerCreate := ee.CreateDto{
Encounter_Id: &input.Id,
Class_Code: subCode,
}
// create data emergency
_, err = ue.CreateData(emerCreate, event, tx)
if err != nil {
return err
}
case ere.ECInpatient:
subCode := ere.InpatientClassCode(*input.SubClass_Code)
inpCreate := ei.CreateDto{
Encounter_Id: &input.Id,
Class_Code: subCode,
Infra_Id: input.Infra_Id,
}
// create data inpatient
_, err = ui.CreateData(inpCreate, event, tx)
if err != nil {
return err
}
default:
return errors.New("invalid encounter class code")
}
return
}
func insertDataSubClassAmbulatory(input e.CreateDto, soapiData []es.CreateDto, event *pl.Event, tx *gorm.DB) (err error) {
subCode := ere.AmbulatoryClassCode(*input.SubClass_Code)
switch {
case subCode == ere.ACCChemo:
chemoCreate := ec.CreateDto{
Encounter_Id: &input.Id,
Status_Code: erc.DVCNew,
SrcUnit_Code: input.Unit_Code,
}
// create data chemo
_, err = uc.CreateData(chemoCreate, event, tx)
if err != nil {
return err
}
case subCode == ere.ACCRehab:
rehabData := er.CreateDto{
Encounter_Id: &input.Id,
VisitMode_Code: input.VisitMode_Code,
Status_Code: erc.DSCProcess,
}
// if visitMode_code is series, then bulk insert soapi
if input.VisitMode_Code == ere.VMCSeries {
rehabData.Parent_Encounter_Id = &input.RecentEncounterAdm.Id
// Insert Soapi
if err = us.CreateBulkData(soapiData, input.Id, event, tx); err != nil {
return err
}
}
// create rehab
if _, err = ur.CreateData(rehabData, event, tx); err != nil {
return err
}
}
return
}
func verifyRehabLimit(data *e.Encounter, event *pl.Event, tx *gorm.DB) error {
// get data encounter adm
encounterAdmData, _, err := verifyAllocatedVisitCount(e.CreateDto{Patient_Id: data.Patient_Id}, event)
if err != nil {
return err
}
// Check if the visit count has reached the allowed limit
// Mark latest rehab status as 'done' if exceeded.
if len(*encounterAdmData.RehabChildren) >= *encounterAdmData.Rehab.AllocatedVisitCount {
err = updateRehabStatus(er.UpdateDto{
Id: uint16(data.Rehab.Id),
CreateDto: er.CreateDto{Status_Code: erc.DSCDone}}, event, tx)
if err != nil {
return err
}
}
return nil
}
func updateRehabStatus(input er.UpdateDto, event *pl.Event, dbx ...*gorm.DB) error {
pl.SetLogInfo(event, "started", "DBUpdate")
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
} else {
tx = dg.I
}
result := tx.
Model(&er.Rehab{}).
Where("\"Id\" = (?)", input.Id).
Update("\"Status_Code\"", input.Status_Code)
if result.Error != nil {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-update-fail",
Detail: "Database update failed",
Raw: result.Error,
}
return pl.SetLogError(event, input)
}
pl.SetLogInfo(event, nil, "complete")
return nil
}
func validateForeignKey(input e.CheckinDto) error {
// validate employee_Id
if input.Adm_Employee_Id != nil {
if _, err := uem.ReadDetail(eem.ReadDetailDto{Id: uint16(*input.Adm_Employee_Id)}); err != nil {
return err
}
}
// validate doctor_Code
if input.Responsible_Doctor_Code != nil {
if _, err := ud.ReadDetail(ed.ReadDetailDto{Code: input.Responsible_Doctor_Code}); err != nil {
return err
}
}
return nil
}
func setSoapiError(event *pl.Event, detail string) error {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
@@ -781,31 +941,82 @@ func setDBError(event *pl.Event, err error, ctx any) error {
return pl.SetLogError(event, ctx)
}
func updateRehabDoctor(input er.UpdateDto, event *pl.Event, dbx ...*gorm.DB) error {
pl.SetLogInfo(event, "started", "DBUpdate")
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
} else {
tx = dg.I
}
result := tx.
Model(&er.Rehab{}).
Where("\"Encounter_Id\" = (?)", input.Encounter_Id).
Update("\"Doctor_Id\"", input.Doctor_Id)
if result.Error != nil {
func getUnits(unitIds []string, event *pl.Event) ([]eu.Unit, error) {
pl.SetLogInfo(event, nil, "started", "getUnits")
var units []eu.Unit
err := dg.I.Where("\"Code\" IN ?", unitIds).Find(&units).Error
if err != nil {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-update-fail",
Detail: "Database update failed",
Raw: result.Error,
Code: "data-get-fail",
Detail: "get units",
Raw: err,
}
return nil, pl.SetLogError(event, nil)
}
return units, nil
}
func getDoctors(doctorIds []string, event *pl.Event) ([]ed.Doctor, error) {
pl.SetLogInfo(event, nil, "started", "getDoctors")
var doctors []ed.Doctor
err := dg.I.Where("\"Code\" IN ?", doctorIds).Find(&doctors).Error
if err != nil {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-get-fail",
Detail: "get doctors",
Raw: err,
}
return nil, pl.SetLogError(event, nil)
}
return doctors, nil
}
func validateUnitCodes(unitCodes map[string]struct{}, event *pl.Event) error {
if len(unitCodes) > 0 {
var codes []string
for code := range unitCodes {
codes = append(codes, code)
}
units, err := getUnits(codes, event)
if err != nil {
return fmt.Errorf("failed to fetch units: %w", err)
}
if len(units) != len(codes) {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-validation-fail",
Detail: "unit_code not found",
}
return pl.SetLogError(event, nil)
}
}
return nil
}
func validateDoctorCodes(doctorCodes map[string]struct{}, event *pl.Event) error {
if len(doctorCodes) > 0 {
var codes []string
for code := range doctorCodes {
codes = append(codes, code)
}
doctors, err := getDoctors(codes, event)
if err != nil {
return fmt.Errorf("failed to fetch doctors: %w", err)
}
if len(doctors) != len(codes) {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-validation-fail",
Detail: "doctor_code not found",
}
return pl.SetLogError(event, nil)
}
return pl.SetLogError(event, input)
}
pl.SetLogInfo(event, nil, "complete")
return nil
}
@@ -3,7 +3,7 @@ package encounter
import (
// std
"errors"
ere "simrs-vx/internal/domain/references/encounter"
eir "simrs-vx/internal/domain/main-entities/internal-reference"
// external
dg "github.com/karincake/apem/db-gorm-pg"
@@ -15,9 +15,14 @@ import (
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
ere "simrs-vx/internal/domain/references/encounter"
e "simrs-vx/internal/domain/main-entities/encounter"
er "simrs-vx/internal/domain/main-entities/rehab"
)
const ErrorReadFailed = "Database read failed"
func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Encounter, error) {
pl.SetLogInfo(event, nil, "started", "DBCreate")
@@ -59,7 +64,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.En
tx = tx.Model(&e.Encounter{})
if input.AuthInfo.Doctor_Code != nil {
tx.Where("\"Responsible_Doctor_Id\" = ?", *input.AuthInfo.Doctor_Code) // TODO: fix this
tx.Where("\"Responsible_Doctor_Code\" = ?", *input.AuthInfo.Doctor_Code) //
}
tx.Scopes(gh.Preload(input.Includes)).
@@ -251,20 +256,49 @@ func updateCheckInData(input e.CheckinDto, data *e.Encounter, event *pl.Event, d
return nil
}
func getLatestRehabData(i e.CreateDto, event *pl.Event) (recentRehabData *er.Rehab, err error) {
pl.SetLogInfo(event, nil, "started", "DBGetLatestRehab")
var (
tx = dg.I
)
err = tx.
Joins("JOIN \"Encounter\" ON \"Encounter\".\"Id\" = \"Rehab\".\"Encounter_Id\"").
Where("\"Encounter\".\"Patient_Id\" = ?", i.Patient_Id).
Order("\"CreatedAt\" DESC").
First(&recentRehabData).Error
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "read-recentRehab-fail",
Detail: ErrorReadFailed,
Raw: err,
}
return nil, pl.SetLogError(event, i)
}
return
}
func verifyAllocatedVisitCount(i e.CreateDto, event *pl.Event) (e.Encounter, bool, error) {
pl.SetLogInfo(event, nil, "started", "DBGetRecentEncounterAdm")
var (
tx = dg.I
recentEncounterAdm e.Encounter
countEncounterSeries int64
tx = dg.I
recentEncounterAdm e.Encounter
valid = true
)
err := tx.
Scopes(gh.Preload("Rehab,Responsible_Doctor")).
Joins("JOIN \"Ambulatory\" ON \"Ambulatory\".\"Encounter_Id\" = \"Encounter\".\"Id\"").
Where("\"Patient_Id\" = ?", i.Patient_Id).
Where("\"Ambulatory\".\"Class_Code\" = ? AND \"Ambulatory\".\"VisitMode_Code\" = ?", ere.ACCRehab, ere.VMCAdm).
Scopes(gh.Preload("RehabChildren,Rehab,Responsible_Doctor")).
Joins("JOIN \"Rehab\" ON \"Rehab\".\"Encounter_Id\" = \"Encounter\".\"Id\"").
Where("\"Encounter\".\"Patient_Id\" = ?", i.Patient_Id).
Where("\"Rehab\".\"VisitMode_Code\" = ?", ere.VMCAdm).
Order("\"CreatedAt\" DESC").
First(&recentEncounterAdm).Error
if err != nil {
@@ -277,22 +311,41 @@ func verifyAllocatedVisitCount(i e.CreateDto, event *pl.Event) (e.Encounter, boo
return e.Encounter{}, false, pl.SetLogError(event, i)
}
err = tx.
Model(&e.Encounter{}).
Joins("JOIN \"Ambulatory\" ON \"Ambulatory\".\"Encounter_Id\" = \"Encounter\".\"Id\"").
Where("\"Patient_Id\" = ?", i.Patient_Id).
Where("\"Ambulatory\".\"Class_Code\" = ? AND \"Ambulatory\".\"VisitMode_Code\" = ?", ere.ACCRehab, ere.VMCSeries).
Where("\"Encounter\".\"CreatedAt\" > ?", recentEncounterAdm.CreatedAt).
Count(&countEncounterSeries).Error
if err != nil {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "read-countEncounter-fail",
Detail: "Database read failed",
Raw: err,
}
return e.Encounter{}, false, pl.SetLogError(event, i)
// validate count rehab children
if recentEncounterAdm.RehabChildren != nil && len(*recentEncounterAdm.RehabChildren) > 0 {
valid = len(*recentEncounterAdm.RehabChildren) < *recentEncounterAdm.Rehab.AllocatedVisitCount
}
return recentEncounterAdm, countEncounterSeries < int64(*recentEncounterAdm.Rehab.AllocatedVisitCount), nil
return recentEncounterAdm, valid, nil
}
func updateEncounterApproveSwitchUnit(input eir.InternalReference, event *pl.Event, dbx ...*gorm.DB) (err error) {
pl.SetLogInfo(event, nil, "started", "DBCreate")
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
} else {
tx = dg.I
}
if err := tx.Model(&e.Encounter{}).
Where("\"Id\" = ?", input.Encounter_Id).
Updates(map[string]interface{}{
"Responsible_Doctor_Code": input.Doctor_Code,
"Unit_Code": input.Unit_Code,
"Specialist_Code": input.Doctor.Specialist_Code,
"Subspecialist_Code": input.Doctor.Subspecialist_Code,
}).Error; err != nil {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "update-fail",
Detail: "Failed to update encounter approve switch unit",
Raw: err,
}
return pl.SetLogError(event, input)
}
pl.SetLogInfo(event, input, "complete")
return nil
}
@@ -6,6 +6,7 @@ package internal_reference
import (
ir "simrs-vx/internal/domain/main-entities/internal-reference"
erc "simrs-vx/internal/domain/references/common"
)
func setData[T *ir.CreateDto | *ir.UpdateDto](input T, data *ir.InternalReference) {
@@ -18,18 +19,21 @@ func setData[T *ir.CreateDto | *ir.UpdateDto](input T, data *ir.InternalReferenc
}
data.Encounter_Id = inputSrc.Encounter_Id
data.Unit_Id = inputSrc.Unit_Id
data.Doctor_Id = inputSrc.Doctor_Id
data.Unit_Code = inputSrc.Unit_Code
data.Doctor_Code = inputSrc.Doctor_Code
data.Status_Code = &inputSrc.Status_Code
}
func setBulkData(input []ir.CreateDto, encounterId uint) []ir.InternalReference {
var data []ir.InternalReference
for _, v := range input {
statusCode := erc.DACNew
data = append(data, ir.InternalReference{
Encounter_Id: &encounterId,
Unit_Id: v.Unit_Id,
Doctor_Id: v.Doctor_Id,
Unit_Code: v.Unit_Code,
Doctor_Code: v.Doctor_Code,
Status_Code: &statusCode,
})
}
@@ -166,7 +166,7 @@ func ReadDetail(input e.ReadDetailDto) (*d.Data, error) {
}
func Update(input e.UpdateDto) (*d.Data, error) {
rdDto := e.ReadDetailDto{Id: uint16(input.Id)}
rdDto := e.ReadDetailDto{Code: input.Code}
var data *e.Nurse
var err error
@@ -222,7 +222,7 @@ func Update(input e.UpdateDto) (*d.Data, error) {
}
func Delete(input e.DeleteDto) (*d.Data, error) {
rdDto := e.ReadDetailDto{Id: uint16(input.Id)}
rdDto := e.ReadDetailDto{Code: input.Code}
var data *e.Nurse
var err error
+1 -1
View File
@@ -84,7 +84,7 @@ func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e
if input.Employee_Id != nil {
tx = tx.Where("\"Employee_Id\" = ?", *input.Employee_Id)
}
if input.Id > 0 {
if input.Id != nil {
tx = tx.Where("\"Id\" = ?", input.Id)
}
if err := tx.First(&data).Error; err != nil {
@@ -17,7 +17,7 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.PracticeSchedule) {
inputSrc = &inputTemp.CreateDto
}
data.Doctor_Id = inputSrc.Doctor_Id
data.Doctor_Code = inputSrc.Doctor_Code
data.Unit_Code = inputSrc.Unit_Code
data.Day_Code = inputSrc.Day_Code
data.StartTime = inputSrc.StartTime
@@ -18,6 +18,9 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Rehab) {
}
data.Encounter_Id = inputSrc.Encounter_Id
data.Doctor_Id = inputSrc.Doctor_Id
data.Parent_Encounter_Id = inputSrc.Parent_Encounter_Id
data.AllocatedVisitCount = inputSrc.AllocatedVisitCount
data.ExpiredAt = inputSrc.ExpiredAt
data.VisitMode_Code = &inputSrc.VisitMode_Code
data.Status_Code = &inputSrc.Status_Code
}
@@ -18,7 +18,7 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.ResponsibleDoctorHi
}
data.Encounter_Id = inputSrc.Encounter_Id
data.Doctor_Id = inputSrc.Doctor_Id
data.Doctor_Code = inputSrc.Doctor_Code
data.StartedAt = inputSrc.StartedAt
data.FinishedAt = inputSrc.FinishedAt
}
@@ -299,9 +299,9 @@ func validateForeignKey(input e.CreateDto) error {
}
}
// validate doctor_id
if input.Doctor_Id != nil {
if _, err := ud.ReadDetail(ed.ReadDetailDto{Id: uint16(*input.Doctor_Id)}); err != nil {
// validate doctor_code
if input.Doctor_Code != nil {
if _, err := ud.ReadDetail(ed.ReadDetailDto{Code: input.Doctor_Code}); err != nil {
return err
}
}
@@ -18,7 +18,7 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.TherapyProtocol) {
}
data.Encounter_Id = inputSrc.Encounter_Id
data.Doctor_Id = inputSrc.Doctor_Id
data.Doctor_Code = inputSrc.Doctor_Code
data.Anamnesis = inputSrc.Anamnesis
data.MedicalDiagnoses = inputSrc.MedicalDiagnoses
data.FunctionDiagnoses = inputSrc.FunctionDiagnoses