From 88e7f99e6d6e3e1a27e65665d32ee0de6aa67bee Mon Sep 17 00:00:00 2001 From: vanilia Date: Mon, 27 Oct 2025 17:10:00 +0700 Subject: [PATCH] improve check-in --- .../domain/main-entities/encounter/dto.go | 2 + .../use-case/main-use-case/encounter/case.go | 113 +++++++++++++----- .../main-use-case/encounter/helper.go | 5 + .../use-case/main-use-case/encounter/lib.go | 30 +++-- 4 files changed, 113 insertions(+), 37 deletions(-) diff --git a/internal/domain/main-entities/encounter/dto.go b/internal/domain/main-entities/encounter/dto.go index b552ba86..89f12caf 100644 --- a/internal/domain/main-entities/encounter/dto.go +++ b/internal/domain/main-entities/encounter/dto.go @@ -46,6 +46,8 @@ type CreateDto struct { Responsible_Doctor_Id *uint `json:"responsible_doctor_id"` RefSource_Name *string `json:"refSource_name" validate:"maxLength=100"` Appointment_Id *uint `json:"appointment_id"` + RefTypeCode ere.RefTypeCode `json:"refTypeCode"` + NewStatus bool `json:"newStatus"` pa.AuthInfo } diff --git a/internal/use-case/main-use-case/encounter/case.go b/internal/use-case/main-use-case/encounter/case.go index 6786eb51..c55b5b4b 100644 --- a/internal/use-case/main-use-case/encounter/case.go +++ b/internal/use-case/main-use-case/encounter/case.go @@ -2,12 +2,21 @@ package encounter import ( "errors" - eaeh "simrs-vx/internal/domain/main-entities/adm-employee-hist" - erdh "simrs-vx/internal/domain/main-entities/responsible-doctor-hist" - uaeh "simrs-vx/internal/use-case/main-use-case/adm-employee-hist" - urdh "simrs-vx/internal/use-case/main-use-case/responsible-doctor-hist" + authhelper "simrs-vx/internal/lib/auth" "strconv" + "time" + dg "github.com/karincake/apem/db-gorm-pg" + d "github.com/karincake/dodol" + "gorm.io/gorm" + + pl "simrs-vx/pkg/logger" + pu "simrs-vx/pkg/use-case-helper" + + erc "simrs-vx/internal/domain/references/common" + 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" @@ -16,8 +25,10 @@ import ( eem "simrs-vx/internal/domain/main-entities/employee" e "simrs-vx/internal/domain/main-entities/encounter" ei "simrs-vx/internal/domain/main-entities/inpatient" - erc "simrs-vx/internal/domain/references/common" - ere "simrs-vx/internal/domain/references/encounter" + 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" @@ -25,18 +36,14 @@ import ( 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" - - pl "simrs-vx/pkg/logger" - pu "simrs-vx/pkg/use-case-helper" - - dg "github.com/karincake/apem/db-gorm-pg" - d "github.com/karincake/dodol" - - "gorm.io/gorm" + urdh "simrs-vx/internal/use-case/main-use-case/responsible-doctor-hist" + us "simrs-vx/internal/use-case/main-use-case/soapi" ) const source = "encounter" +var now = time.Now() + func Create(input e.CreateDto) (*d.Data, error) { data := e.Encounter{} @@ -48,7 +55,21 @@ func Create(input e.CreateDto) (*d.Data, error) { // Start log pl.SetLogInfo(&event, input, "started", "create") - err := dg.I.Transaction(func(tx *gorm.DB) error { + // check if patient is new in the hospital + dataPatient, err := ReadList(e.ReadListDto{ + FilterDto: e.FilterDto{Patient_Id: input.Patient_Id}, + AuthInfo: authhelper.AuthInfo{User_Id: input.User_Id}}) + if err != nil { + return nil, err + } + + if list, ok := dataPatient.Data.([]e.ResponseDto); ok { + if len(list) < 1 { + input.NewStatus = true + } + } + + err = dg.I.Transaction(func(tx *gorm.DB) error { mwRunner := newMiddlewareRunner(&event, tx) mwRunner.setMwType(pu.MWTPre) // Run pre-middleware @@ -126,6 +147,15 @@ func Create(input e.CreateDto) (*d.Data, error) { return errors.New("invalid encounter class code") } + // insert adm_employee_hist + if _, err := uaeh.Create(eaeh.CreateDto{ + Encounter_Id: &data.Main.Id, + Employee_Id: data.Adm_Employee_Id, + StartedAt: &now, + }); err != nil { + return err + } + mwRunner.setMwType(pu.MWTPost) // Run post-middleware if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil { @@ -418,6 +448,16 @@ func CheckOut(input e.DischargeDto) (*d.Data, error) { } } + // update finishedAt in latest responsible_doctor_hist + if err = updateLatestResponsibleDoctorHist(e.CheckinDto{Id: input.Id, StartedAt: &now}, &event, tx); err != nil { + return err + } + + // update finishedAt in latest adm_employee_hist + if err = updateLatestAdmEmployeeHist(e.CheckinDto{Id: input.Id, StartedAt: &now}, &event, tx); err != nil { + return err + } + switch *input.Discharge_Method_Code { case ere.DMCDeath: // insert data death-cause @@ -534,6 +574,22 @@ func CheckIn(input e.CheckinDto) (*d.Data, error) { return nil, err } + dataSoapi, err := us.ReadList(es.ReadListDto{FilterDto: es.FilterDto{Encounter_Id: &input.Id}}) + if err != nil { + return nil, err + } + if list, ok := dataSoapi.Data.([]es.ResponseDto); ok { + if len(list) > 0 { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-state-mismatch", + Detail: "soapi already exist", + Raw: errors.New("soapi already exist"), + } + return nil, pl.SetLogError(&event, input) + } + } + err = dg.I.Transaction(func(tx *gorm.DB) error { pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail") if data, err = ReadDetailData(rdDto, &event, tx); err != nil { @@ -551,20 +607,23 @@ func CheckIn(input e.CheckinDto) (*d.Data, error) { } // Insert responsible_doctor_hist if responsible_doctor_id has changed && update latest history - if input.Responsible_Doctor_Id != nil && *input.Responsible_Doctor_Id != *data.Responsible_Doctor_Id { - // update finishedAt in latest responsible_doctor_hist - if err = updateLatestResponsibleDoctorHist(input, &event, tx); err != nil { - return err + if input.Responsible_Doctor_Id != nil { + if data.Responsible_Doctor_Id == nil || *input.Responsible_Doctor_Id != *data.Responsible_Doctor_Id { + // update finishedAt in latest responsible_doctor_hist + if err = updateLatestResponsibleDoctorHist(input, &event, tx); err != nil { + return err + } + + //insert responsible_doctor_hist + if _, err = urdh.Create(erdh.CreateDto{ + Encounter_Id: &input.Id, + Doctor_Id: input.Responsible_Doctor_Id, + StartedAt: input.StartedAt, + }); err != nil { + return err + } } - //insert responsible_doctor_hist - if _, err = urdh.Create(erdh.CreateDto{ - Encounter_Id: &input.Id, - Doctor_Id: input.Responsible_Doctor_Id, - StartedAt: input.StartedAt, - }); err != nil { - return err - } } // Insert adm_employee_hist if adm_employee_id has changed && update latest history diff --git a/internal/use-case/main-use-case/encounter/helper.go b/internal/use-case/main-use-case/encounter/helper.go index 2e74eff6..d2647a38 100644 --- a/internal/use-case/main-use-case/encounter/helper.go +++ b/internal/use-case/main-use-case/encounter/helper.go @@ -69,6 +69,8 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Encounter) { data.RefSource_Name = inputSrc.RefSource_Name data.Appointment_Id = inputSrc.Appointment_Id data.Status_Code = erc.DSCProcess + data.RefType_Code = &inputSrc.RefTypeCode + data.NewStatus = inputSrc.NewStatus } func setDataUpdate(src e.UpdateDto, dst *e.Encounter) { @@ -90,6 +92,7 @@ func setDataDischarge(src e.DischargeDto, dst *e.Encounter) { now := time.Now() dst.Discharge_Date = &now + dst.FinishedAt = &now } func checkSoapiByDocExists(encounter_id uint, event *pl.Event, tx *gorm.DB) error { @@ -335,6 +338,8 @@ func setDataCheckIn(src e.CheckinDto, dst *e.Encounter) { if src.Adm_Employee_Id != nil { dst.Adm_Employee_Id = src.Adm_Employee_Id } + + dst.StartedAt = src.StartedAt } func createInternalReferences(input e.DischargeDto, event *pl.Event, tx *gorm.DB) error { diff --git a/internal/use-case/main-use-case/encounter/lib.go b/internal/use-case/main-use-case/encounter/lib.go index 6e960e49..3327bcfa 100644 --- a/internal/use-case/main-use-case/encounter/lib.go +++ b/internal/use-case/main-use-case/encounter/lib.go @@ -3,8 +3,6 @@ package encounter import ( // std "errors" - "fmt" - // external dg "github.com/karincake/apem/db-gorm-pg" gh "github.com/karincake/getuk" @@ -271,21 +269,26 @@ func updateLatestResponsibleDoctorHist(input e.CheckinDto, event *pl.Event, dbx Order("\"CreatedAt\" DESC"). Limit(1) - fmt.Println(subQuery) - - if err := tx. + result := tx. Model(&erdh.ResponsibleDoctorHist{}). Where("\"Id\" = (?)", subQuery). - Update("\"FinishedAt\"", input.StartedAt).Error; err != nil { + Update("\"FinishedAt\"", input.StartedAt) + + if result.Error != nil { event.Status = "failed" event.ErrInfo = pl.ErrorInfo{ Code: "data-update-fail", Detail: "Database update failed", - Raw: err, + Raw: result.Error, } return pl.SetLogError(event, input) } + if result.RowsAffected == 0 { + pl.SetLogInfo(event, input, "no previous data found to update") + return nil + } + pl.SetLogInfo(event, nil, "complete") return nil } @@ -307,19 +310,26 @@ func updateLatestAdmEmployeeHist(input e.CheckinDto, event *pl.Event, dbx ...*go Order("\"CreatedAt\" DESC"). Limit(1) - if err := tx. + result := tx. Model(&eaeh.AdmEmployeeHist{}). Where("\"Id\" = (?)", subQuery). - Update("\"FinishedAt\"", input.StartedAt).Error; err != nil { + Update("\"FinishedAt\"", input.StartedAt) + + if result.Error != nil { event.Status = "failed" event.ErrInfo = pl.ErrorInfo{ Code: "data-update-fail", Detail: "Database update failed", - Raw: err, + Raw: result.Error, } return pl.SetLogError(event, input) } + if result.RowsAffected == 0 { + pl.SetLogInfo(event, input, "no previous data found to update") + return nil + } + pl.SetLogInfo(event, nil, "complete") return nil }