diff --git a/internal/domain/main-entities/encounter/dto.go b/internal/domain/main-entities/encounter/dto.go index 4a30281d..ae8d1c5f 100644 --- a/internal/domain/main-entities/encounter/dto.go +++ b/internal/domain/main-entities/encounter/dto.go @@ -105,6 +105,17 @@ type DischargeDto struct { InternalReferences *[]eir.CreateDto `json:"internalReferences,omitempty"` } +type CheckinDto struct { + Id uint `json:"id"` + Responsible_Doctor_Id *uint `json:"responsible_doctor_id"` + Responsible_Doctor_StartedAt *time.Time `json:"responsible_doctor_startedAt"` + Responsible_Doctor_FinishedAt *time.Time `json:"responsible_doctor_finishedAt"` + + Adm_Employee_Id *uint `json:"adm_employee_id"` + Adm_Employee_StartedAt *time.Time `json:"adm_employee_startedAt"` + Adm_Employee_FinishedAt *time.Time `json:"adm_employee_finishedAt"` +} + type ResponseDto struct { ecore.Main Patient_Id *uint `json:"patient_id"` diff --git a/internal/interface/main-handler/encounter/handler.go b/internal/interface/main-handler/encounter/handler.go index df3320ef..85b8746d 100644 --- a/internal/interface/main-handler/encounter/handler.go +++ b/internal/interface/main-handler/encounter/handler.go @@ -102,6 +102,27 @@ func (obj myBase) CheckOut(w http.ResponseWriter, r *http.Request) { rw.DataResponse(w, res, err) } +func (obj myBase) CheckIn(w http.ResponseWriter, r *http.Request) { + dto := e.CheckinDto{} + 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 := validateRequestCheckIn(w, dto); !valid { + return + } + + dto.Id = uint(id) + res, err := u.CheckIn(dto) + rw.DataResponse(w, res, err) +} + func (obj myBase) Process(w http.ResponseWriter, r *http.Request) { id := rw.ValidateInt(w, "id", r.PathValue("id")) if id <= 0 { diff --git a/internal/interface/main-handler/encounter/request-validation.go b/internal/interface/main-handler/encounter/request-validation.go index 182dd12e..9e92ea88 100644 --- a/internal/interface/main-handler/encounter/request-validation.go +++ b/internal/interface/main-handler/encounter/request-validation.go @@ -10,9 +10,9 @@ import ( rw "github.com/karincake/risoles" ) -func validateRequestCheckout(w http.ResponseWriter, i e.DischargeDto) (valid bool) { - const dataValidationFail = "" +const dataValidationFail = "data-validation-fail" +func validateRequestCheckout(w http.ResponseWriter, i e.DischargeDto) (valid bool) { switch *i.Discharge_Method_Code { case ere.DMCDeath: if i.DeathCause == nil { @@ -51,3 +51,15 @@ func validateRequestCheckout(w http.ResponseWriter, i e.DischargeDto) (valid boo } return true } + +func validateRequestCheckIn(w http.ResponseWriter, i e.CheckinDto) (valid bool) { + if i.Responsible_Doctor_Id == nil && i.Adm_Employee_Id == nil { + rw.DataResponse(w, nil, d.FieldError{ + Code: dataValidationFail, + Message: "responsible_doctor_id or adm_employee_id required", + }) + return + } + + return true +} diff --git a/internal/interface/main-handler/main-handler.go b/internal/interface/main-handler/main-handler.go index 89b55f26..23b532c2 100644 --- a/internal/interface/main-handler/main-handler.go +++ b/internal/interface/main-handler/main-handler.go @@ -172,16 +172,17 @@ func SetRoutes() http.Handler { "PATCH /{id}/complete": mcuordersubitem.O.Complete, }) 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}/checkout": encounter.O.CheckOut, - "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, }) hk.GroupRoutes("/v1/medication", r, auth.GuardMW, hk.MapHandlerFunc{ "GET /": medication.O.GetList, diff --git a/internal/use-case/main-use-case/adm-employee-hist/case.go b/internal/use-case/main-use-case/adm-employee-hist/case.go index 13e308bf..51851584 100644 --- a/internal/use-case/main-use-case/adm-employee-hist/case.go +++ b/internal/use-case/main-use-case/adm-employee-hist/case.go @@ -2,13 +2,8 @@ package adm_employee_hist import ( e "simrs-vx/internal/domain/main-entities/adm-employee-hist" - eem "simrs-vx/internal/domain/main-entities/employee" - ee "simrs-vx/internal/domain/main-entities/encounter" "strconv" - uem "simrs-vx/internal/use-case/main-use-case/employee" - ue "simrs-vx/internal/use-case/main-use-case/encounter" - dg "github.com/karincake/apem/db-gorm-pg" d "github.com/karincake/dodol" @@ -39,10 +34,6 @@ func Create(input e.CreateDto) (*d.Data, error) { return err } - if err := validateForeignKey(input); err != nil { - return err - } - if resData, err := CreateData(input, &event, tx); err != nil { return err } else { @@ -200,10 +191,6 @@ func Update(input e.UpdateDto) (*d.Data, error) { return err } - if err := validateForeignKey(input.CreateDto); err != nil { - return err - } - if err := UpdateData(input, data, &event, tx); err != nil { return err } @@ -287,17 +274,3 @@ func Delete(input e.DeleteDto) (*d.Data, error) { }, nil } - -func validateForeignKey(input e.CreateDto) error { - // validate encounter_id - if _, err := ue.ReadDetail(ee.ReadDetailDto{Id: uint16(*input.Encounter_Id)}); err != nil { - return err - } - - // validate doctor_id - if _, err := uem.ReadDetail(eem.ReadDetailDto{Id: uint16(*input.Employee_Id)}); err != nil { - return err - } - - return nil -} diff --git a/internal/use-case/main-use-case/encounter/case.go b/internal/use-case/main-use-case/encounter/case.go index 04eedfff..4e41954e 100644 --- a/internal/use-case/main-use-case/encounter/case.go +++ b/internal/use-case/main-use-case/encounter/case.go @@ -4,20 +4,26 @@ import ( "errors" "strconv" + 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" + erdh "simrs-vx/internal/domain/main-entities/responsible-doctor-hist" + 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" + urdh "simrs-vx/internal/use-case/main-use-case/responsible-doctor-hist" erc "simrs-vx/internal/domain/references/common" ere "simrs-vx/internal/domain/references/encounter" @@ -511,3 +517,102 @@ func UpdateStatusCode(input e.UpdateStatusDto) (*d.Data, error) { }, nil } + +func CheckIn(input e.CheckinDto) (*d.Data, error) { + rdDto := e.ReadDetailDto{Id: uint16(input.Id)} + var data *e.Encounter + var err error + + event := pl.Event{ + Feature: "CheckIn", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "checkIn") + + // validate foreign key + if err := validateForeignKey(input); 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 + } + + 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 err := updateCheckInData(input, data, &event, tx); err != nil { + return err + } + + if input.Responsible_Doctor_Id != nil { + // insert responsible_doctor_hist + if _, err = urdh.Create(erdh.CreateDto{ + Encounter_Id: &input.Id, + Doctor_Id: input.Responsible_Doctor_Id, + StartedAt: input.Responsible_Doctor_StartedAt, + FinishedAt: input.Responsible_Doctor_FinishedAt, + }); err != nil { + return err + } + } + + if input.Adm_Employee_Id != nil { + // insert responsible_doctor_hist + if _, err = uaeh.Create(eaeh.CreateDto{ + Encounter_Id: &input.Id, + Employee_Id: input.Adm_Employee_Id, + StartedAt: input.Adm_Employee_StartedAt, + FinishedAt: input.Adm_Employee_FinishedAt, + }); err != nil { + return err + } + } + + 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": "checkIn", + }, + Data: data.ToResponse(), + }, 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_id + if input.Responsible_Doctor_Id != nil { + if _, err := ud.ReadDetail(ed.ReadDetailDto{Id: uint16(*input.Responsible_Doctor_Id)}); err != nil { + return err + } + } + + 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 41fd6a51..878a472f 100644 --- a/internal/use-case/main-use-case/encounter/helper.go +++ b/internal/use-case/main-use-case/encounter/helper.go @@ -327,6 +327,11 @@ func setDataUpdateStatus(src e.UpdateStatusDto, dst *e.Encounter) { dst.Status_Code = src.StatusCode } +func setDataCheckIn(src e.CheckinDto, dst *e.Encounter) { + dst.Responsible_Doctor_Id = src.Responsible_Doctor_Id + dst.Adm_Employee_Id = src.Adm_Employee_Id +} + func createInternalReferences(input e.DischargeDto, event *pl.Event, tx *gorm.DB) error { unitIDs := make(map[uint16]struct{}) doctorIDs := make(map[uint]struct{}) diff --git a/internal/use-case/main-use-case/encounter/lib.go b/internal/use-case/main-use-case/encounter/lib.go index ccc4b811..d1dd1afd 100644 --- a/internal/use-case/main-use-case/encounter/lib.go +++ b/internal/use-case/main-use-case/encounter/lib.go @@ -212,3 +212,28 @@ func UpdateStatusData(input e.UpdateStatusDto, data *e.Encounter, event *pl.Even 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") + setDataCheckIn(input, data) + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Save(&data).Error; err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-update-fail", + Detail: "Database update failed", + Raw: err, + } + return pl.SetLogError(event, input) + } + + pl.SetLogInfo(event, nil, "complete") + return nil +} diff --git a/internal/use-case/main-use-case/responsible-doctor-hist/case.go b/internal/use-case/main-use-case/responsible-doctor-hist/case.go index 591c6dd7..3451a88f 100644 --- a/internal/use-case/main-use-case/responsible-doctor-hist/case.go +++ b/internal/use-case/main-use-case/responsible-doctor-hist/case.go @@ -1,14 +1,9 @@ package responsible_doctor_hist import ( - ed "simrs-vx/internal/domain/main-entities/doctor" - ee "simrs-vx/internal/domain/main-entities/encounter" e "simrs-vx/internal/domain/main-entities/responsible-doctor-hist" "strconv" - ud "simrs-vx/internal/use-case/main-use-case/doctor" - ue "simrs-vx/internal/use-case/main-use-case/encounter" - dg "github.com/karincake/apem/db-gorm-pg" d "github.com/karincake/dodol" @@ -39,10 +34,6 @@ func Create(input e.CreateDto) (*d.Data, error) { return err } - if err := validateForeignKey(input); err != nil { - return err - } - if resData, err := CreateData(input, &event, tx); err != nil { return err } else { @@ -200,10 +191,6 @@ func Update(input e.UpdateDto) (*d.Data, error) { return err } - if err := validateForeignKey(input.CreateDto); err != nil { - return err - } - if err := UpdateData(input, data, &event, tx); err != nil { return err } @@ -287,17 +274,3 @@ func Delete(input e.DeleteDto) (*d.Data, error) { }, nil } - -func validateForeignKey(input e.CreateDto) error { - // validate encounter_id - if _, err := ue.ReadDetail(ee.ReadDetailDto{Id: uint16(*input.Encounter_Id)}); err != nil { - return err - } - - // validate doctor_id - if _, err := ud.ReadDetail(ed.ReadDetailDto{Id: uint16(*input.Doctor_Id)}); err != nil { - return err - } - - return nil -}