diff --git a/cmd/main-migration/migrations/20251126064057.sql b/cmd/main-migration/migrations/20251126064057.sql new file mode 100644 index 00000000..fd823ff9 --- /dev/null +++ b/cmd/main-migration/migrations/20251126064057.sql @@ -0,0 +1,2 @@ +-- Modify "InternalReference" table +ALTER TABLE "public"."InternalReference" ADD COLUMN "SrcDoctor_Code" character varying(20) NULL, ADD COLUMN "SrcNurse_Code" character varying(20) NULL, ADD COLUMN "Nurse_Code" character varying(20) NULL, ADD CONSTRAINT "fk_InternalReference_Nurse" FOREIGN KEY ("Nurse_Code") REFERENCES "public"."Nurse" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION, ADD CONSTRAINT "fk_InternalReference_SrcDoctor" FOREIGN KEY ("SrcDoctor_Code") REFERENCES "public"."Doctor" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION, ADD CONSTRAINT "fk_InternalReference_SrcNurse" FOREIGN KEY ("SrcNurse_Code") REFERENCES "public"."Nurse" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION; diff --git a/cmd/main-migration/migrations/atlas.sum b/cmd/main-migration/migrations/atlas.sum index 719dffff..363efe04 100644 --- a/cmd/main-migration/migrations/atlas.sum +++ b/cmd/main-migration/migrations/atlas.sum @@ -1,4 +1,4 @@ -h1:u2pc+PayIbiG5HRFUzun7cApIwlt9SMNTl74DtPz1xg= +h1:U9vdficFramvwnH40psSuRxzUuq6EPJwLcr9MvVTq7s= 20250904105930.sql h1:MEM6blCgke9DzWQSTnLzasbPIrcHssNNrJqZpSkEo6k= 20250904141448.sql h1:J8cmYNk4ZrG9fhfbi2Z1IWz7YkfvhFqTzrLFo58BPY0= 20250908062237.sql h1:Pu23yEW/aKkwozHoOuROvHS/GK4ngARJGdO7FB7HZuI= @@ -129,4 +129,5 @@ h1:u2pc+PayIbiG5HRFUzun7cApIwlt9SMNTl74DtPz1xg= 20251120074415.sql h1:NNUeJVA03EeBHJhHqPXEZoDv/PnC6yK1/cRhmukyaJo= 20251121033803.sql h1:/vfvFX/3pzSCIHnSbMUT9EMBDykOpVkvyfeTEle9Vas= 20251124071457.sql h1:qg2dhCL9YwD13xnfJ175lW/p6MGfzFKaBqd908FByRc= -20251125125303.sql h1:P94UsZOeo7b0r2yLoSGBfj0+PcMTf4Y10lF+Rl9FxAE= +20251125125303.sql h1:4JSFv1Pmhbe9tqpLXgO63OwYnGsalStgUXKVWPyc1YE= +20251126064057.sql h1:+lByIo0zAsHVSFzQGVMuymFQajyl7fRNqgs9d/76y+E= diff --git a/internal/domain/main-entities/encounter/dto.go b/internal/domain/main-entities/encounter/dto.go index 273cdf31..bd2953eb 100644 --- a/internal/domain/main-entities/encounter/dto.go +++ b/internal/domain/main-entities/encounter/dto.go @@ -158,11 +158,18 @@ type SwitchUnitDto struct { Id uint `json:"id"` PolySwitchCode *ere.PolySwitchCode `json:"polySwitchCode"` InternalReferences *[]eir.CreateDto `json:"internalReferences" validate:"required"` + + Src_Doctor_Code *string `json:"-"` + Src_Nurse_Code *string `json:"-"` + pa.AuthInfo } type ApproveUnitDto struct { - Id uint `json:"id"` - InternalReferences_Id uint16 `json:"internalReferences_id" validate:"required"` + Id uint `json:"id"` + InternalReferences_Id uint16 `json:"internalReferences_id" validate:"required"` + Doctor_Code *string `json:"doctor_code"` + Nurse_Code *string `json:"-"` + pa.AuthInfo } type ResponseDto struct { diff --git a/internal/domain/main-entities/internal-reference/dto.go b/internal/domain/main-entities/internal-reference/dto.go index 6ce50a77..0653d2ac 100644 --- a/internal/domain/main-entities/internal-reference/dto.go +++ b/internal/domain/main-entities/internal-reference/dto.go @@ -9,10 +9,13 @@ import ( ) type CreateDto struct { - Encounter_Id *uint `json:"-"` - Unit_Code *string `json:"unit_code"` - Doctor_Code *string `json:"doctor_code"` - Status_Code erc.DataApprovalCode `json:"status_code"` + Encounter_Id *uint `json:"-"` + Unit_Code *string `json:"unit_code"` + Doctor_Code *string `json:"doctor_code"` + Nurse_Code *string `json:"nurse_code"` + Status_Code erc.DataApprovalCode `json:"status_code"` + SrcDoctor_Code *string `json:"srcDoctor_code"` + SrcNurse_Code *string `json:"srcNurse_code"` } type ReadListDto struct { diff --git a/internal/domain/main-entities/internal-reference/entity.go b/internal/domain/main-entities/internal-reference/entity.go index ae6307bb..90859710 100644 --- a/internal/domain/main-entities/internal-reference/entity.go +++ b/internal/domain/main-entities/internal-reference/entity.go @@ -5,15 +5,22 @@ import ( ecore "simrs-vx/internal/domain/base-entities/core" ed "simrs-vx/internal/domain/main-entities/doctor" + en "simrs-vx/internal/domain/main-entities/nurse" eu "simrs-vx/internal/domain/main-entities/unit" ) type InternalReference struct { ecore.Main - Encounter_Id *uint `json:"encounter_id"` - Unit_Code *string `json:"unit_code"` - Unit *eu.Unit `json:"unit,omitempty" gorm:"foreignKey:Unit_Code;references:Code"` - Doctor_Code *string `json:"doctor_code"` - Doctor *ed.Doctor `json:"doctor,omitempty" gorm:"foreignKey:Doctor_Code;references:Code"` - Status_Code *erc.DataApprovalCode `json:"status_code"` + Encounter_Id *uint `json:"encounter_id"` + Unit_Code *string `json:"unit_code"` + Unit *eu.Unit `json:"unit,omitempty" gorm:"foreignKey:Unit_Code;references:Code"` + Doctor_Code *string `json:"doctor_code"` + Doctor *ed.Doctor `json:"doctor,omitempty" gorm:"foreignKey:Doctor_Code;references:Code"` + Status_Code *erc.DataApprovalCode `json:"status_code"` + SrcDoctor_Code *string `json:"srcDoctor_code"` + SrcDoctor *ed.Doctor `json:"srcDoctor,omitempty" gorm:"foreignKey:SrcDoctor_Code;references:Code"` + SrcNurse_Code *string `json:"srcNurse_code"` + SrcNurse *en.Nurse `json:"srcNurse,omitempty" gorm:"foreignKey:SrcNurse_Code;references:Code"` + Nurse_Code *string `json:"nurse_code"` + Nurse *en.Nurse `json:"nurse,omitempty" gorm:"foreignKey:Nurse_Code;references:Code"` } diff --git a/internal/domain/references/clinical/clinical.go b/internal/domain/references/clinical/clinical.go index f5190297..30a4fe8a 100644 --- a/internal/domain/references/clinical/clinical.go +++ b/internal/domain/references/clinical/clinical.go @@ -117,12 +117,14 @@ const ( MULCPF McuUrgencyLevelCode = "priority-form" // Form Prioritas MULCRT McuUrgencyLevelCode = "routine" // Pemeriksaan Rutin - //STCEarlyNurse SoapiTypeCode = "early-nurse" // Kajian Awal Medis - STCEEarlyMedic SoapiTypeCode = "early-medic" // Kajian Awal Rehab Medis - STCEarlyRehab SoapiTypeCode = "early-rehab" // Kajian Awal Rehab Medik - STCFunc SoapiTypeCode = "function" // Assessment Fungsi - STCProgress SoapiTypeCode = "progress" // CPPT - STCDevRecord SoapiTypeCode = "dev-record" // Catatan Perkembangan + STCEarlyNurse SoapiTypeCode = "early-nursery" // Kajian Awal Keperawatan + STCEEarlyMedic SoapiTypeCode = "early-medic" // Kajian Awal Rehab Medis + STCEarlyRehab SoapiTypeCode = "early-rehab" // Kajian Awal Rehab Medik + STCFunc SoapiTypeCode = "function" // Assessment Fungsi + STCProgress SoapiTypeCode = "progress" // CPPT + STCDevRecord SoapiTypeCode = "dev-record" // Catatan Perkembangan + STCKfrAdm SoapiTypeCode = "kfr-adm" // soapi untuk kfr + STCKfrSeries SoapiTypeCode = "kfr-series" // soapi untuk kfr MATCChemo MedicalActionTypeCode = "chemo" MATCHemo MedicalActionTypeCode = "hemo" diff --git a/internal/domain/references/common/common.go b/internal/domain/references/common/common.go index 96febd75..3a449057 100644 --- a/internal/domain/references/common/common.go +++ b/internal/domain/references/common/common.go @@ -106,6 +106,7 @@ const ( DACNew DataApprovalCode = "new" DACApproved DataApprovalCode = "approved" DACRejected DataApprovalCode = "rejected" + DACCanceled DataApprovalCode = "canceled" PSCSuccess ProcessStatusCode = "success" PSCFailed ProcessStatusCode = "failed" diff --git a/internal/domain/references/encounter/encounter.go b/internal/domain/references/encounter/encounter.go index a1fc3b31..231baa9b 100644 --- a/internal/domain/references/encounter/encounter.go +++ b/internal/domain/references/encounter/encounter.go @@ -122,6 +122,7 @@ const ( DTCSIPP DocTypeCode = "vclaim-sipp" // SIPP DTCGC DocTypeCode = "general-consent" DTCVSCL DocTypeCode = "vclaim-control-letter" // vclaim control letter + DTCResume DocTypeCode = "resume" // Resume ETCPerson EntityTypeCode = "person" ETCEncounter EntityTypeCode = "encounter" diff --git a/internal/interface/main-handler/encounter/request-validation.go b/internal/interface/main-handler/encounter/request-validation.go index 79cc832c..76fcab4d 100644 --- a/internal/interface/main-handler/encounter/request-validation.go +++ b/internal/interface/main-handler/encounter/request-validation.go @@ -59,6 +59,14 @@ func validateRequestCheckIn(w http.ResponseWriter, i e.CheckinDto) (valid bool) } func validateRequestSwitchUnit(w http.ResponseWriter, i e.SwitchUnitDto) (valid bool) { + // validate poly-switch-code + if *i.PolySwitchCode != ere.PSCConsulPoly && *i.PolySwitchCode != ere.PSCConsulExecutive { + rw.DataResponse(w, nil, d.FieldError{ + Code: dataValidationFail, + Message: "invalid PolySwitchCode", + }) + } + if i.InternalReferences == nil { rw.DataResponse(w, nil, d.FieldError{ Code: dataValidationFail, diff --git a/internal/use-case/main-use-case/encounter/case.go b/internal/use-case/main-use-case/encounter/case.go index 2eac5083..da143d54 100644 --- a/internal/use-case/main-use-case/encounter/case.go +++ b/internal/use-case/main-use-case/encounter/case.go @@ -22,14 +22,12 @@ import ( edc "simrs-vx/internal/domain/main-entities/death-cause" e "simrs-vx/internal/domain/main-entities/encounter" eir "simrs-vx/internal/domain/main-entities/internal-reference" - erdh "simrs-vx/internal/domain/main-entities/responsible-doctor-hist" es "simrs-vx/internal/domain/main-entities/soapi" esync "simrs-vx/internal/domain/sync-entities/log" uv "simrs-vx/internal/use-case/bpjs-use-case/vclaim-reference" udc "simrs-vx/internal/use-case/main-use-case/death-cause" uir "simrs-vx/internal/use-case/main-use-case/internal-reference" - urdh "simrs-vx/internal/use-case/main-use-case/responsible-doctor-hist" us "simrs-vx/internal/use-case/main-use-case/soapi" ) @@ -432,7 +430,7 @@ func CheckOut(input e.DischargeDto) (*d.Data, error) { // Start log pl.SetLogInfo(&event, input, "started", "checkOut") - roleAllowed := []string{string(erg.EPCNur), string(erg.EPCDoc)} + roleAllowed := []string{string(erg.EPCNur)} err = validateAuth(input.AuthInfo, roleAllowed, "checkOut-encounter", &event) if err != nil { return nil, err @@ -500,15 +498,20 @@ func CheckOut(input e.DischargeDto) (*d.Data, error) { // perform additional validation when discharge_method_code is "consul-poly" or "consul-executive" if *data.Discharge_Method_Code == ere.DMCConsulPoly || *data.Discharge_Method_Code == ere.DMCConsulExecutive { for _, v := range *data.InternalReferences { - + if *v.Status_Code == erc.DACNew { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-state-mismatch", + Detail: "checkout is not allowed because the internal-reference status is 'new'", + Raw: errors.New("internal-referral status not done yet"), + } + return pl.SetLogError(&event, input) + } } } - // read newest data encounter for sync - dataEncounter, err := ReadDetailData(e.ReadDetailDto{ - Id: data.Id, - Includes: "DeathCause"}, - &event, tx) + // read the newest data encounter for sync + dataEncounter, err := ReadDetailData(e.ReadDetailDto{Id: data.Id, Includes: "DeathCause"}, &event, tx) if err != nil { return err } @@ -597,7 +600,7 @@ func UpdateStatusCode(input e.UpdateStatusDto) (*d.Data, error) { } } - if err := UpdateStatusData(input, data, &event, tx); err != nil { + if err := UpdateStatusData(input, &event, tx); err != nil { return err } @@ -690,10 +693,8 @@ func CheckIn(input e.CheckinDto) (*d.Data, error) { return err } - dataEncounter, err := ReadDetailData(e.ReadDetailDto{ - Id: data.Id, - Includes: "Responsible_Nurse.Employee.User"}, - &event, tx) + // read the newest data encounter for sync + dataEncounter, err := ReadDetailData(e.ReadDetailDto{Id: data.Id, Includes: "Responsible_Nurse.Employee.User"}, &event, tx) if err != nil { return err } @@ -757,23 +758,31 @@ func RequestSwitchUnit(input e.SwitchUnitDto) (*d.Data, error) { return nil, err } + roleAllowed := []string{string(erg.EPCNur)} + err = validateAuth(input.AuthInfo, roleAllowed, "request-switch-poly", &event) + if err != nil { + return nil, err + } + input.Src_Nurse_Code = input.AuthInfo.Nurse_Code + err = dg.I.Transaction(func(tx *gorm.DB) error { pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail") if data, err = ReadDetailData(rdDto, &event, tx); err != nil { return err } + input.Src_Doctor_Code = data.Responsible_Doctor_Code - //if data.IsDone() { - // event.Status = "failed" - // event.ErrInfo = pl.ErrorInfo{ - // Code: "data-state-mismatch", - // Detail: "encounter is done", - // Raw: errors.New("encounter is done"), - // } - // return pl.SetLogError(&event, input) - //} + if data.IsDone() { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-state-mismatch", + Detail: "encounter is done", + Raw: errors.New("encounter is done"), + } + return pl.SetLogError(&event, input) + } - // verify Soapi exist for current responsible doctor + // Poly-Switch-Requests can only be processed if the previous responsible doctor has completed their SOAPI. dataSoapi, err := getSoapiByResponsibleDoctor(*data, &event) if err != nil { return err @@ -787,12 +796,21 @@ func RequestSwitchUnit(input e.SwitchUnitDto) (*d.Data, error) { return pl.SetLogError(&event, input) } - // bulk internal references - if err := uir.CreateBulkData(*input.InternalReferences, input.Id, &event, tx); err != nil { + // update encounter discharge_method_code + if err = UpdateDischargeMethod(input, &event, tx); err != nil { return err } - // TODO: update status encounter, finishedAt + // bulk internal references + if err := uir.CreateBulkData(&input, &event, tx); err != nil { + return err + } + + // read the newest data encounter for sync + dataEncounter, err := ReadDetailData(e.ReadDetailDto{Id: data.Id, Includes: "InternalReferences,Responsible_Nurse"}, &event, tx) + if err != nil { + return err + } pl.SetLogInfo(&event, nil, "complete") return nil @@ -814,8 +832,10 @@ func RequestSwitchUnit(input e.SwitchUnitDto) (*d.Data, error) { func ApproveSwitchUnit(input e.ApproveUnitDto) (*d.Data, error) { rdDto := e.ReadDetailDto{Id: input.Id, Includes: "Responsible_Doctor"} - var data *e.Encounter - var err error + var ( + data *e.Encounter + err error + ) event := pl.Event{ Feature: "ApproveSwitchUnit", @@ -825,13 +845,20 @@ func ApproveSwitchUnit(input e.ApproveUnitDto) (*d.Data, error) { // Start log pl.SetLogInfo(&event, input, "started", "approveSwitchUnit") + roleAllowed := []string{string(erg.EPCNur)} + err = validateAuth(input.AuthInfo, roleAllowed, "request-switch-poly", &event) + if err != nil { + return nil, err + } + input.Nurse_Code = input.AuthInfo.Nurse_Code + 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 + // get internalReference based on internalReferences_Id irData, err := uir.ReadDetailData(eir.ReadDetailDto{ Id: input.InternalReferences_Id, Includes: "Doctor"}, &event, tx) if err != nil { @@ -858,7 +885,7 @@ func ApproveSwitchUnit(input e.ApproveUnitDto) (*d.Data, error) { return pl.SetLogError(&event, input) } - // verify Soapi exist for current responsible doctor + // Approve-Switch-Requests can only be processed if the previous responsible doctor has completed their SOAPI. dataSoapi, err := getSoapiByResponsibleDoctor(*data, &event) if err != nil { return err @@ -872,43 +899,26 @@ func ApproveSwitchUnit(input e.ApproveUnitDto) (*d.Data, error) { return pl.SetLogError(&event, input) } + // Set doctor_code; nil indicates no change. + if input.Doctor_Code == nil { + input.Doctor_Code = irData.Doctor_Code + } + // update internal reference if err = uir.UpdateData(eir.UpdateDto{ Id: input.InternalReferences_Id, CreateDto: eir.CreateDto{ - Encounter_Id: &input.Id, - Doctor_Code: irData.Doctor_Code, - Unit_Code: irData.Unit_Code, - Status_Code: erc.DACApproved, - }}, irData, &event, tx); err != nil { + Status_Code: erc.DACApproved, + Doctor_Code: input.Doctor_Code, + Nurse_Code: input.Nurse_Code}}, irData, &event, tx); err != nil { return err } // update encounter - if err = updateEncounterApproveSwitchUnit(*irData, &event, tx); err != nil { + if err = updateEncounterApproveSwitchUnit(input, &event, tx); err != nil { return err } - // update latest responsible doctor hist - if err = updateLatestResponsibleDoctorHist(e.CheckinDto{Id: input.Id, FinishedAt: &now}, &event, tx); err != nil { - 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 }) diff --git a/internal/use-case/main-use-case/encounter/helper.go b/internal/use-case/main-use-case/encounter/helper.go index cdc07a8f..f3042b89 100644 --- a/internal/use-case/main-use-case/encounter/helper.go +++ b/internal/use-case/main-use-case/encounter/helper.go @@ -118,16 +118,25 @@ 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) { dst.Responsible_Nurse_Code = src.Responsible_Nurse_Code dst.Responsible_Doctor_Code = src.Responsible_Doctor_Code dst.StartedAt = src.StartedAt } +func setDischargeMethodCode(code ere.PolySwitchCode) *ere.DischargeMethodCode { + var dcm ere.DischargeMethodCode + + switch code { + case ere.PSCConsulPoly: + dcm = ere.DMCConsulPoly + case ere.PSCConsulExecutive: + dcm = ere.DMCConsulExecutive + } + + return &dcm +} + func checkSoapiByDocExists(encounter_id uint, event *pl.Event, tx *gorm.DB) error { pl.SetLogInfo(event, nil, "started", "checkSoapiByDocExists") var soapies []es.Soapi diff --git a/internal/use-case/main-use-case/encounter/lib.go b/internal/use-case/main-use-case/encounter/lib.go index ef189ad4..b0280e0d 100644 --- a/internal/use-case/main-use-case/encounter/lib.go +++ b/internal/use-case/main-use-case/encounter/lib.go @@ -3,7 +3,6 @@ package encounter import ( // std "errors" - eir "simrs-vx/internal/domain/main-entities/internal-reference" // external dg "github.com/karincake/apem/db-gorm-pg" gh "github.com/karincake/getuk" @@ -205,9 +204,8 @@ func IsDone(encounter_id uint, event *pl.Event, dbx ...*gorm.DB) bool { return data.IsDone() } -func UpdateStatusData(input e.UpdateStatusDto, data *e.Encounter, event *pl.Event, dbx ...*gorm.DB) error { - pl.SetLogInfo(event, data, "started", "DBUpdate") - setDataUpdateStatus(input, data) +func UpdateStatusData(input e.UpdateStatusDto, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, input, "started", "DBUpdateStatus") var tx *gorm.DB if len(dbx) > 0 { @@ -216,22 +214,49 @@ func UpdateStatusData(input e.UpdateStatusDto, data *e.Encounter, event *pl.Even tx = dg.I } - if err := tx.Save(&data).Error; err != nil { + if err := tx.Model(&e.Encounter{}). + Where("\"Id\" = ?", input.Id). + Update("Status_Code", input.StatusCode).Error; err != nil { event.Status = "failed" event.ErrInfo = pl.ErrorInfo{ - Code: "data-update-fail", - Detail: "Database update failed", + Code: "update-fail", + Detail: "Failed to update status code", + Raw: err, + } + return pl.SetLogError(event, input) + } + + return nil +} + +func UpdateDischargeMethod(input e.SwitchUnitDto, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, input, "started", "DBUpdateDischargeMethod") + dischargeCode := setDischargeMethodCode(*input.PolySwitchCode) + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Model(&e.Encounter{}). + Where("\"Id\" = ?", input.Id). + Update("Discharge_Method_Code", dischargeCode).Error; err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "update-fail", + Detail: "Failed to update discharge method code", Raw: err, } return pl.SetLogError(event, input) } - pl.SetLogInfo(event, nil, "complete") return nil } func updateCheckInData(input e.CheckinDto, data *e.Encounter, event *pl.Event, dbx ...*gorm.DB) error { - pl.SetLogInfo(event, data, "started", "DBUpdate") + pl.SetLogInfo(event, data, "started", "DBUpdateCheckin") setDataCheckIn(input, data) var tx *gorm.DB @@ -318,7 +343,7 @@ func verifyAllocatedVisitCount(i e.CreateDto, event *pl.Event) (e.Encounter, boo return recentEncounterAdm, valid, nil } -func updateEncounterApproveSwitchUnit(input eir.InternalReference, event *pl.Event, dbx ...*gorm.DB) (err error) { +func updateEncounterApproveSwitchUnit(input e.ApproveUnitDto, event *pl.Event, dbx ...*gorm.DB) (err error) { pl.SetLogInfo(event, nil, "started", "DBCreate") var tx *gorm.DB @@ -329,10 +354,10 @@ func updateEncounterApproveSwitchUnit(input eir.InternalReference, event *pl.Eve } if err := tx.Model(&e.Encounter{}). - Where("\"Id\" = ?", input.Encounter_Id). + Where("\"Id\" = ?", input.Id). Updates(map[string]interface{}{ "Responsible_Doctor_Code": input.Doctor_Code, - "Unit_Code": input.Unit_Code, + "Responsible_Nurse_Code": input.Nurse_Code, }).Error; err != nil { event.Status = "failed" event.ErrInfo = pl.ErrorInfo{ diff --git a/internal/use-case/main-use-case/internal-reference/helper.go b/internal/use-case/main-use-case/internal-reference/helper.go index 234eb770..26b8903f 100644 --- a/internal/use-case/main-use-case/internal-reference/helper.go +++ b/internal/use-case/main-use-case/internal-reference/helper.go @@ -5,35 +5,41 @@ Any functions that are used internally by the use-case package internal_reference import ( + e "simrs-vx/internal/domain/main-entities/encounter" ir "simrs-vx/internal/domain/main-entities/internal-reference" erc "simrs-vx/internal/domain/references/common" ) -func setData[T *ir.CreateDto | *ir.UpdateDto](input T, data *ir.InternalReference) { - var inputSrc *ir.CreateDto - if inputT, ok := any(input).(*ir.CreateDto); ok { - inputSrc = inputT - } else { - inputTemp := any(input).(*ir.UpdateDto) - inputSrc = &inputTemp.CreateDto - } +func setDataCreate(input *ir.CreateDto, data *ir.InternalReference) { + data.Encounter_Id = input.Encounter_Id + data.Unit_Code = input.Unit_Code - data.Encounter_Id = inputSrc.Encounter_Id - data.Unit_Code = inputSrc.Unit_Code - data.Doctor_Code = inputSrc.Doctor_Code - data.Status_Code = &inputSrc.Status_Code + data.Doctor_Code = input.Doctor_Code + data.SrcDoctor_Code = input.SrcDoctor_Code + + data.Nurse_Code = input.Nurse_Code + data.SrcNurse_Code = input.SrcNurse_Code + data.Status_Code = &input.Status_Code } -func setBulkData(input []ir.CreateDto, encounterId uint) []ir.InternalReference { +func setDataUpdate(input *ir.UpdateDto, data *ir.InternalReference) { + data.Doctor_Code = input.Doctor_Code + data.Nurse_Code = input.Nurse_Code + data.Status_Code = &input.Status_Code +} + +func setBulkData(input *e.SwitchUnitDto) []ir.InternalReference { var data []ir.InternalReference - for _, v := range input { + for _, v := range *input.InternalReferences { statusCode := erc.DACNew data = append(data, ir.InternalReference{ - Encounter_Id: &encounterId, - Unit_Code: v.Unit_Code, - Doctor_Code: v.Doctor_Code, - Status_Code: &statusCode, + Encounter_Id: &input.Id, + Unit_Code: v.Unit_Code, + Doctor_Code: v.Doctor_Code, + Status_Code: &statusCode, + SrcDoctor_Code: input.Src_Doctor_Code, + SrcNurse_Code: input.Src_Nurse_Code, }) } diff --git a/internal/use-case/main-use-case/internal-reference/lib.go b/internal/use-case/main-use-case/internal-reference/lib.go index bf852dc6..0aa54b4b 100644 --- a/internal/use-case/main-use-case/internal-reference/lib.go +++ b/internal/use-case/main-use-case/internal-reference/lib.go @@ -2,6 +2,7 @@ package internal_reference import ( "errors" + e "simrs-vx/internal/domain/main-entities/encounter" eir "simrs-vx/internal/domain/main-entities/internal-reference" plh "simrs-vx/pkg/lib-helper" pl "simrs-vx/pkg/logger" @@ -16,7 +17,7 @@ func CreateData(input eir.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*eir.Int pl.SetLogInfo(event, nil, "started", "DBCreate") data := eir.InternalReference{} - setData(&input, &data) + setDataCreate(&input, &data) var tx *gorm.DB if len(dbx) > 0 { @@ -97,7 +98,7 @@ func ReadDetailData(input eir.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) ( func UpdateData(input eir.UpdateDto, data *eir.InternalReference, event *pl.Event, dbx ...*gorm.DB) error { pl.SetLogInfo(event, data, "started", "DBUpdate") - setData(&input, data) + setDataUpdate(&input, data) var tx *gorm.DB if len(dbx) > 0 { @@ -143,10 +144,10 @@ func DeleteData(data *eir.InternalReference, event *pl.Event, dbx ...*gorm.DB) e return nil } -func CreateBulkData(input []eir.CreateDto, encounterId uint, event *pl.Event, dbx ...*gorm.DB) error { +func CreateBulkData(input *e.SwitchUnitDto, event *pl.Event, dbx ...*gorm.DB) error { pl.SetLogInfo(event, nil, "started", "DBCreate") - data := setBulkData(input, encounterId) + data := setBulkData(input) var tx *gorm.DB if len(dbx) > 0 { diff --git a/internal/use-case/simgos-sync-use-case/new/encounter/case.go b/internal/use-case/simgos-sync-use-case/new/encounter/case.go index 56edb70a..9b62c7c8 100644 --- a/internal/use-case/simgos-sync-use-case/new/encounter/case.go +++ b/internal/use-case/simgos-sync-use-case/new/encounter/case.go @@ -278,6 +278,8 @@ func CheckOut(input e.Encounter) (*d.Data, error) { return err } + // TODO: Update TPemeriksaanHistory end_konsul if internal reference exist + return nil }) @@ -367,6 +369,8 @@ func RequestSwitchUnit(input e.Encounter) (*d.Data, error) { return err } + // Step 4: BulkInsert To Link + return nil }) @@ -381,7 +385,7 @@ func RequestSwitchUnit(input e.Encounter) (*d.Data, error) { }, nil } -func ApproveSwitchUnit(input e.Encounter) (*d.Data, error) { +func ApproveSwitchUnit(input e.ApproveUnitDto) (*d.Data, error) { event := pl.Event{ Feature: "RequestSwitchUnit", Source: source, @@ -404,12 +408,7 @@ func ApproveSwitchUnit(input e.Encounter) (*d.Data, error) { tx := db.NewTx() err = tx.Simgos.Transaction(func(tx *gorm.DB) error { - // Step 2: Update TPendaftaran - if err = UpdateTPendaftaranData(input, tpendaftaran, "update-status", &event, tx); err != nil { - return err - } - - // Step 3: Insert TPemeriksaanHist + // Step 3: Update TPemeriksaanHist if _, err := CreateBulkTPemeriksaanHistData(input, tpendaftaran, &event, tx); err != nil { return err } diff --git a/internal/use-case/simgos-sync-use-case/new/encounter/helper.go b/internal/use-case/simgos-sync-use-case/new/encounter/helper.go index aaef624d..ac763d00 100644 --- a/internal/use-case/simgos-sync-use-case/new/encounter/helper.go +++ b/internal/use-case/simgos-sync-use-case/new/encounter/helper.go @@ -122,7 +122,32 @@ func setDataUpdateStatus(input e.Encounter, data *etp.TPendaftaran) { if input.Status_Code == erc.DSCCancel { data.Status = 11 + return } + + setStatus(input.Discharge_Method_Code, data) + //if *input.Discharge_Method_Code == ere.DMCConsulPoly || + // *input.Discharge_Method_Code == ere.DMCConsulExecutive { + // + // if u := input.Unit; u != nil { + // data.PoliNameHfis = &u.Name + // } + // + // if d := input.Responsible_Doctor; d != nil { + // if d.Specialist_Code != nil { + // data.SpesialisIdHfis = d.Specialist_Code + // } + // + // if emp := d.Employee; emp != nil { + // if p := emp.Person; p != nil { + // data.DokterNameHfis = &p.Name + // } + // } + // } + // + // data.DokterIdHfis = nil + //} + } func setDataCheckIn(input e.Encounter, data *etp.TPendaftaran) { @@ -153,7 +178,6 @@ func setDataCheckOut(input e.Encounter, data *etp.TPendaftaran) { setStatus(input.Discharge_Method_Code, data) if data.Status == 8 || data.Status == 3 { if dc := input.DeathCause; dc != nil { - var dcSrc []DeathCauseSrc _ = json.Unmarshal([]byte(*dc.Value), &dcSrc) @@ -190,15 +214,17 @@ func setDataRequestSwitchUnit(input e.Encounter, data *etp.TPendaftaran) (hist [ hist = append(hist, etph.TPemeriksaanHist{ Idxdaftar: &data.Idxdaftar, Kdpoly: stringtouint(*ref.Unit_Code), - DokterPengonsul: stringtouint(*input.Responsible_Doctor_Code), + DokterPengonsul: stringtouint(*ref.SrcDoctor_Code), DokterPenerima: stringtouint(*ref.Doctor_Code), StartKonsul: &now, }) // set user konsul - if emp := input.Adm_Employee; emp != nil { - if u := emp.User; u != nil { - hist[i].UserKonsul = &u.Name + if n := input.Responsible_Nurse; n != nil { + if emp := n.Employee; emp != nil { + if u := emp.User; u != nil { + hist[i].UserKonsul = &u.Name + } } } @@ -256,24 +282,12 @@ func setStatus(code *ere.DischargeMethodCode, data *etp.TPendaftaran) { data.Status = 7 case ere.DMCConsulPoly: data.Status = 5 - data.PoliNameHfis = nil - data.SpesialisIdHfis = nil - data.DokterNameHfis = nil - data.DokterIdHfis = nil case ere.DMCExtRef: data.Status = 6 case ere.DMCConsulChDay: data.Status = 12 - data.PoliNameHfis = nil - data.SpesialisIdHfis = nil - data.DokterNameHfis = nil - data.DokterIdHfis = nil case ere.DMCEmergency: data.Status = 10 - data.PoliNameHfis = nil - data.SpesialisIdHfis = nil - data.DokterNameHfis = nil - data.DokterIdHfis = nil case ere.DMCEmergencyCovid: data.Status = 13 case ere.DMCConsulExecutive: diff --git a/internal/use-case/simgos-sync-use-case/new/encounter/lib.go b/internal/use-case/simgos-sync-use-case/new/encounter/lib.go index 3312193d..bbb887e3 100644 --- a/internal/use-case/simgos-sync-use-case/new/encounter/lib.go +++ b/internal/use-case/simgos-sync-use-case/new/encounter/lib.go @@ -218,3 +218,46 @@ func CreateBulkTPemeriksaanHistData(input e.Encounter, data *etp.TPendaftaran, e pl.SetLogInfo(event, nil, "complete") return hist, nil } + +func CreateLinkData(simxId, simgosId uint, event *pl.Event, dbx ...*gorm.DB) (*esync.EncounterLink, error) { + pl.SetLogInfo(event, nil, "started", "DBCreate") + data := setDataSimxLink(simxId, simgosId) + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Create(&data).Error; err != nil { + return nil, plh.HandleCreateError(data, event, err) + } + + pl.SetLogInfo(event, nil, "complete") + return &data, nil +} + +func UpdateTPemeriksaanHistData(input e.ApproveUnitDto, data *etph.TPemeriksaanHist, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, input, "started", "DBUpdateTPemeriksaanHist") + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.IS["simrs"] + } + + if err := tx.Save(&data).Error; err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-update-fail", + Detail: "Database update failed", + Raw: err, + } + return pl.SetLogError(event, input) + } + + pl.SetLogInfo(event, nil, "complete") + return nil +}