diff --git a/cmd/simgos-sync-migration/migrations/20251126115527.sql b/cmd/simgos-sync-migration/migrations/20251126115527.sql new file mode 100644 index 00000000..49ca1e5c --- /dev/null +++ b/cmd/simgos-sync-migration/migrations/20251126115527.sql @@ -0,0 +1,36 @@ +-- Create "InternalReferenceLink" table +CREATE TABLE "public"."InternalReferenceLink" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "Simx_Id" bigint NULL, + "Simgos_Id" bigint NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "uni_InternalReferenceLink_Simgos_Id" UNIQUE ("Simgos_Id"), + CONSTRAINT "uni_InternalReferenceLink_Simx_Id" UNIQUE ("Simx_Id") +); +-- Create "InternalReferenceSimgosLog" table +CREATE TABLE "public"."InternalReferenceSimgosLog" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "Value" text NULL, + "Date" timestamptz NULL, + "Status" text NULL, + "ErrMessage" text NULL, + PRIMARY KEY ("Id") +); +-- Create "InternalReferenceSimxLog" table +CREATE TABLE "public"."InternalReferenceSimxLog" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "Value" text NULL, + "Date" timestamptz NULL, + "Status" text NULL, + "ErrMessage" text NULL, + PRIMARY KEY ("Id") +); diff --git a/cmd/simgos-sync-migration/migrations/atlas.sum b/cmd/simgos-sync-migration/migrations/atlas.sum index 07e5fbaf..497ac414 100644 --- a/cmd/simgos-sync-migration/migrations/atlas.sum +++ b/cmd/simgos-sync-migration/migrations/atlas.sum @@ -1,6 +1,7 @@ -h1:keVmwgYtvwxSqkq+7nB0BA25JFYRAVBpBBu5eA4Q9Hw= +h1:UdPzQZ17yyNN9HVuyrFFHj5KjLj4m6/e7s9frkdpQVU= 20251113035508.sql h1:rjDlu6yDdy5xv6nrCOr7NialrLSLT23pzduYNq29Hf0= 20251114071129.sql h1:Z0GQ5bJo3C+tplaWzxT8n3J9HLkEaVsRVp5nn7bmYow= 20251117041601.sql h1:l/RPG5mObqCSBjO4mzG+wTq2ieSycvlfOSz4czpUdWY= -20251118082246.sql h1:VFnYls2DBC8tJm2aw0iBcbWGLsKezYdOHJJV9iS7MjI= -20251118082915.sql h1:tAm67fXrH+8IJCjKbJroIqc1uQyqCnuGJnQtLmw7D20= +20251118082246.sql h1:xLUwA+EvKWIg3X/TJvu7rqbtBzONiINfag5NJpMV29E= +20251118082915.sql h1:hP6FmUVFuADIN2cDg2Z1l7Wx7PQRb+IYQDvKD7J8VAM= +20251126115527.sql h1:+2bp2nWTTqaPpKKfy5ZYSr6b1nEUXFG3tIw4r3OEnAQ= diff --git a/internal/domain/main-entities/encounter/dto.go b/internal/domain/main-entities/encounter/dto.go index bd2953eb..8dd9a0a1 100644 --- a/internal/domain/main-entities/encounter/dto.go +++ b/internal/domain/main-entities/encounter/dto.go @@ -164,11 +164,11 @@ type SwitchUnitDto struct { pa.AuthInfo } -type ApproveUnitDto struct { +type ApproveCancelUnitDto struct { Id uint `json:"id"` - InternalReferences_Id uint16 `json:"internalReferences_id" validate:"required"` - Doctor_Code *string `json:"doctor_code"` - Nurse_Code *string `json:"-"` + InternalReferences_Id uint `json:"internalReferences_id" validate:"required"` + Dst_Doctor_Code *string `json:"dst_doctor_code"` + pa.AuthInfo } diff --git a/internal/domain/main-entities/internal-reference/dto.go b/internal/domain/main-entities/internal-reference/dto.go index 0653d2ac..d3771c4d 100644 --- a/internal/domain/main-entities/internal-reference/dto.go +++ b/internal/domain/main-entities/internal-reference/dto.go @@ -32,17 +32,17 @@ type FilterDto struct { } type ReadDetailDto struct { - Id uint16 `json:"id"` + Id uint `json:"id"` Includes string `json:"includes"` } type UpdateDto struct { - Id uint16 `json:"id"` + Id uint `json:"id"` CreateDto } type DeleteDto struct { - Id uint16 `json:"id"` + Id uint `json:"id"` } type MetaDto struct { diff --git a/internal/domain/sync-entities/internal-reference/entity.go b/internal/domain/sync-entities/internal-reference/entity.go new file mode 100644 index 00000000..567e6489 --- /dev/null +++ b/internal/domain/sync-entities/internal-reference/entity.go @@ -0,0 +1,29 @@ +package internal_reference + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + erc "simrs-vx/internal/domain/references/common" + "time" +) + +type InternalReferenceLink struct { + ecore.Main + Simx_Id uint `json:"simx_id" gorm:"unique"` + Simgos_Id uint `json:"simgos_id" gorm:"unique"` +} + +type InternalReferenceSimxLog struct { + ecore.Main + Value *string `json:"value"` + Date *time.Time `json:"date"` + Status erc.ProcessStatusCode `json:"status"` + ErrMessage *string `json:"errMessage"` +} + +type InternalReferenceSimgosLog struct { + ecore.Main + Value *string `json:"value"` + Date *time.Time `json:"date"` + Status erc.ProcessStatusCode `json:"status"` + ErrMessage *string `json:"errMessage"` +} diff --git a/internal/interface/main-handler/encounter/handler.go b/internal/interface/main-handler/encounter/handler.go index 688d6904..7ac31393 100644 --- a/internal/interface/main-handler/encounter/handler.go +++ b/internal/interface/main-handler/encounter/handler.go @@ -174,9 +174,15 @@ func (obj myBase) Process(w http.ResponseWriter, r *http.Request) { return } + authInfo, err := pa.GetAuthInfo(r) + if err != nil { + rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil) + } + dto := e.UpdateStatusDto{ Id: uint(id), StatusCode: erc.DSCProcess, + AuthInfo: *authInfo, } res, err := u.UpdateStatusCode(dto) @@ -197,9 +203,9 @@ func (obj myBase) Cancel(w http.ResponseWriter, r *http.Request) { dto := e.UpdateStatusDto{ Id: uint(id), StatusCode: erc.DSCCancel, + AuthInfo: *authInfo, } - dto.AuthInfo = *authInfo res, err := u.UpdateStatusCode(dto) rw.DataResponse(w, res, err) } @@ -250,13 +256,19 @@ func (obj myBase) RequestSwitchUnit(w http.ResponseWriter, r *http.Request) { return } + authInfo, err := pa.GetAuthInfo(r) + if err != nil { + rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil) + } + + dto.AuthInfo = *authInfo 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{} + dto := e.ApproveCancelUnitDto{} id := rw.ValidateInt(w, "id", r.PathValue("id")) if id <= 0 { return @@ -266,7 +278,37 @@ func (obj myBase) ApproveSwitchUnit(w http.ResponseWriter, r *http.Request) { return } + authInfo, err := pa.GetAuthInfo(r) + if err != nil { + rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil) + } + + dto.AuthInfo = *authInfo dto.Id = uint(id) + res, err := u.ApproveSwitchUnit(dto) rw.DataResponse(w, res, err) } + +func (obj myBase) CancelSwitchUnit(w http.ResponseWriter, r *http.Request) { + dto := e.ApproveCancelUnitDto{} + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id <= 0 { + return + } + + if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { + return + } + + authInfo, err := pa.GetAuthInfo(r) + if err != nil { + rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil) + } + + dto.AuthInfo = *authInfo + dto.Id = uint(id) + + res, err := u.CancelSwitchUnit(dto) + rw.DataResponse(w, res, err) +} diff --git a/internal/interface/main-handler/encounter/request-validation.go b/internal/interface/main-handler/encounter/request-validation.go index 76fcab4d..67d8a63c 100644 --- a/internal/interface/main-handler/encounter/request-validation.go +++ b/internal/interface/main-handler/encounter/request-validation.go @@ -60,6 +60,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 == nil { + rw.DataResponse(w, nil, d.FieldError{ + Code: dataValidationFail, + Message: fmt.Sprintf("polySwitchCode required"), + }) + return + } + if *i.PolySwitchCode != ere.PSCConsulPoly && *i.PolySwitchCode != ere.PSCConsulExecutive { rw.DataResponse(w, nil, d.FieldError{ Code: dataValidationFail, diff --git a/internal/interface/main-handler/internal-reference/handler.go b/internal/interface/main-handler/internal-reference/handler.go index c46c974d..a3193501 100644 --- a/internal/interface/main-handler/internal-reference/handler.go +++ b/internal/interface/main-handler/internal-reference/handler.go @@ -39,7 +39,7 @@ func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) { dto := eir.ReadDetailDto{} sf.UrlQueryParam(&dto, *r.URL) - dto.Id = uint16(id) + dto.Id = uint(id) res, err := uir.ReadDetail(dto) rw.DataResponse(w, res, err) } @@ -54,7 +54,7 @@ func (obj myBase) Update(w http.ResponseWriter, r *http.Request) { if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { return } - dto.Id = uint16(id) + dto.Id = uint(id) res, err := uir.Update(dto) rw.DataResponse(w, res, err) } @@ -66,7 +66,7 @@ func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) { } dto := eir.DeleteDto{} - dto.Id = uint16(id) + dto.Id = uint(id) res, err := uir.Delete(dto) rw.DataResponse(w, res, err) } diff --git a/internal/interface/main-handler/main-handler.go b/internal/interface/main-handler/main-handler.go index 7b919e5f..46aa74e5 100644 --- a/internal/interface/main-handler/main-handler.go +++ b/internal/interface/main-handler/main-handler.go @@ -175,6 +175,7 @@ func SetRoutes() http.Handler { "PATCH /{id}/skip": encounter.O.Skip, "PATCH /{id}/req-switch-unit": encounter.O.RequestSwitchUnit, "PATCH /{id}/approve-switch-unit": encounter.O.ApproveSwitchUnit, + "PATCH /{id}/cancel-switch-unit": encounter.O.CancelSwitchUnit, }) hk.GroupRoutes("/v1/mcu-order", r, auth.GuardMW, hk.MapHandlerFunc{ "GET /": mcuorder.O.GetList, diff --git a/internal/interface/migration/simgossync-entities.go b/internal/interface/migration/simgossync-entities.go index b10c8607..7b37a842 100644 --- a/internal/interface/migration/simgossync-entities.go +++ b/internal/interface/migration/simgossync-entities.go @@ -5,6 +5,7 @@ import ( division "simrs-vx/internal/domain/sync-entities/division" encounter "simrs-vx/internal/domain/sync-entities/encounter" installation "simrs-vx/internal/domain/sync-entities/installation" + internalreference "simrs-vx/internal/domain/sync-entities/internal-reference" patient "simrs-vx/internal/domain/sync-entities/patient" specialist "simrs-vx/internal/domain/sync-entities/specialist" subspecialist "simrs-vx/internal/domain/sync-entities/subspecialist" @@ -34,5 +35,8 @@ func getSyncEntities() []any { &encounter.EncounterLink{}, &encounter.EncounterSimxLog{}, &encounter.EncounterSimgosLog{}, + &internalreference.InternalReferenceLink{}, + &internalreference.InternalReferenceSimxLog{}, + &internalreference.InternalReferenceSimgosLog{}, } } diff --git a/internal/interface/simgos-sync-handler/new/encounter/handler.go b/internal/interface/simgos-sync-handler/new/encounter/handler.go index be7a6e1e..aef2f7d2 100644 --- a/internal/interface/simgos-sync-handler/new/encounter/handler.go +++ b/internal/interface/simgos-sync-handler/new/encounter/handler.go @@ -86,3 +86,33 @@ func (obj myBase) UpdateStatus(w http.ResponseWriter, r *http.Request) { res, err := u.UpdateStatus(dto) rw.DataResponse(w, res, err) } + +func (obj myBase) RequestSwitchUnit(w http.ResponseWriter, r *http.Request) { + dto := e.Encounter{} + if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { + return + } + + res, err := u.RequestSwitchUnit(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) ApproveSwitchUnit(w http.ResponseWriter, r *http.Request) { + dto := e.ApproveCancelUnitDto{} + if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { + return + } + + res, err := u.ApproveSwitchUnit(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) CancelSwitchUnit(w http.ResponseWriter, r *http.Request) { + dto := e.ApproveCancelUnitDto{} + if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { + return + } + + res, err := u.CancelSwitchUnit(dto) + rw.DataResponse(w, res, err) +} diff --git a/internal/interface/simgos-sync-handler/simgos-sync-handler.go b/internal/interface/simgos-sync-handler/simgos-sync-handler.go index 5a1ffc8b..5d52d40b 100644 --- a/internal/interface/simgos-sync-handler/simgos-sync-handler.go +++ b/internal/interface/simgos-sync-handler/simgos-sync-handler.go @@ -56,13 +56,16 @@ func SetRoutes() http.Handler { "POST /nomr": patient.O.GenerateNomr, }) hk.GroupRoutes(prefixnew+"/v1/encounter", r, hk.MapHandlerFunc{ - "POST /": encounter.O.Create, - "POST /log": encounter.O.CreateLog, - "PATCH /{id}": encounter.O.Update, - "DELETE /{id}": encounter.O.Delete, - "PATCH /{id}/checkin": encounter.O.Checkin, - "PATCH /{id}/checkout": encounter.O.Checkout, - "PATCH /{id}/update-status": encounter.O.UpdateStatus, + "POST /": encounter.O.Create, + "POST /log": encounter.O.CreateLog, + "PATCH /{id}": encounter.O.Update, + "DELETE /{id}": encounter.O.Delete, + "PATCH /{id}/checkin": encounter.O.Checkin, + "PATCH /{id}/checkout": encounter.O.Checkout, + "PATCH /{id}/update-status": encounter.O.UpdateStatus, + "PATCH /{id}/req-switch-unit": encounter.O.RequestSwitchUnit, + "PATCH /{id}/approve-switch-unit": encounter.O.ApproveSwitchUnit, + "PATCH /{id}/cancel-switch-unit": encounter.O.CancelSwitchUnit, }) /******************** SvcToNew ******************/ diff --git a/internal/use-case/main-use-case/doctor/lib.go b/internal/use-case/main-use-case/doctor/lib.go index 12b62176..827802fa 100644 --- a/internal/use-case/main-use-case/doctor/lib.go +++ b/internal/use-case/main-use-case/doctor/lib.go @@ -87,6 +87,9 @@ func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e if input.Id != nil { tx = tx.Where("\"Id\" = ?", input.Id) } + if input.Code != nil { + tx = tx.Where("\"Code\" = ?", input.Code) + } if err := tx.First(&data).Error; err != nil { if processedErr := pu.HandleReadError(err, event, source, input.Id, data); processedErr != nil { return nil, processedErr diff --git a/internal/use-case/main-use-case/encounter/case.go b/internal/use-case/main-use-case/encounter/case.go index da143d54..07f055a8 100644 --- a/internal/use-case/main-use-case/encounter/case.go +++ b/internal/use-case/main-use-case/encounter/case.go @@ -605,6 +605,8 @@ func UpdateStatusCode(input e.UpdateStatusDto) (*d.Data, error) { } if input.StatusCode == erc.DSCProcess || input.StatusCode == erc.DSCCancel { + data.Status_Code = input.StatusCode + mwRunner.setMwType(pu.MWTPre) // Run pre-middleware if err := mwRunner.RunUpdateStatusMiddleware(updatestatusEncounter, data); err != nil { @@ -725,7 +727,7 @@ func CheckIn(input e.CheckinDto) (*d.Data, error) { } func RequestSwitchUnit(input e.SwitchUnitDto) (*d.Data, error) { - rdDto := e.ReadDetailDto{Id: input.Id, Includes: "Responsible_Doctor"} + rdDto := e.ReadDetailDto{Id: input.Id, Includes: "Responsible_Nurse.Employee.User,Responsible_Doctor.Employee"} var data *e.Encounter var err error @@ -765,6 +767,8 @@ func RequestSwitchUnit(input e.SwitchUnitDto) (*d.Data, error) { } input.Src_Nurse_Code = input.AuthInfo.Nurse_Code + mwRunner := newMiddlewareRunner(&event) + err = dg.I.Transaction(func(tx *gorm.DB) error { pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail") if data, err = ReadDetailData(rdDto, &event, tx); err != nil { @@ -807,19 +811,25 @@ func RequestSwitchUnit(input e.SwitchUnitDto) (*d.Data, error) { } // read the newest data encounter for sync - dataEncounter, err := ReadDetailData(e.ReadDetailDto{Id: data.Id, Includes: "InternalReferences,Responsible_Nurse"}, &event, tx) + dataEncounter, err := ReadDetailData(e.ReadDetailDto{Id: data.Id, Includes: "InternalReferences,Responsible_Nurse.Employee.User"}, &event, tx) if err != nil { return err } - pl.SetLogInfo(&event, nil, "complete") + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunRequestSwitchUnitMiddleware(requestSwitchEncounter, dataEncounter); err != nil { + return err + } return nil }) - if err != nil { + if err = runLogMiddleware(err, input, mwRunner); err != nil { return nil, err } + pl.SetLogInfo(&event, nil, "complete") + return &d.Data{ Meta: d.IS{ "source": source, @@ -830,8 +840,8 @@ func RequestSwitchUnit(input e.SwitchUnitDto) (*d.Data, error) { }, nil } -func ApproveSwitchUnit(input e.ApproveUnitDto) (*d.Data, error) { - rdDto := e.ReadDetailDto{Id: input.Id, Includes: "Responsible_Doctor"} +func ApproveSwitchUnit(input e.ApproveCancelUnitDto) (*d.Data, error) { + rdDto := e.ReadDetailDto{Id: input.Id, Includes: "Responsible_Doctor.Employee"} var ( data *e.Encounter err error @@ -850,7 +860,8 @@ func ApproveSwitchUnit(input e.ApproveUnitDto) (*d.Data, error) { if err != nil { return nil, err } - input.Nurse_Code = input.AuthInfo.Nurse_Code + + mwRunner := newMiddlewareRunner(&event) err = dg.I.Transaction(func(tx *gorm.DB) error { pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail") @@ -858,6 +869,16 @@ func ApproveSwitchUnit(input e.ApproveUnitDto) (*d.Data, error) { 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) + } + // get internalReference based on internalReferences_Id irData, err := uir.ReadDetailData(eir.ReadDetailDto{ Id: input.InternalReferences_Id, Includes: "Doctor"}, &event, tx) @@ -875,16 +896,6 @@ func ApproveSwitchUnit(input e.ApproveUnitDto) (*d.Data, error) { 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) - } - // Approve-Switch-Requests can only be processed if the previous responsible doctor has completed their SOAPI. dataSoapi, err := getSoapiByResponsibleDoctor(*data, &event) if err != nil { @@ -900,8 +911,8 @@ func ApproveSwitchUnit(input e.ApproveUnitDto) (*d.Data, error) { } // Set doctor_code; nil indicates no change. - if input.Doctor_Code == nil { - input.Doctor_Code = irData.Doctor_Code + if input.Dst_Doctor_Code == nil { + input.Dst_Doctor_Code = irData.Doctor_Code } // update internal reference @@ -909,7 +920,7 @@ func ApproveSwitchUnit(input e.ApproveUnitDto) (*d.Data, error) { Id: input.InternalReferences_Id, CreateDto: eir.CreateDto{ Status_Code: erc.DACApproved, - Doctor_Code: input.Doctor_Code, + Doctor_Code: input.Dst_Doctor_Code, Nurse_Code: input.Nurse_Code}}, irData, &event, tx); err != nil { return err } @@ -919,14 +930,110 @@ func ApproveSwitchUnit(input e.ApproveUnitDto) (*d.Data, error) { return err } - pl.SetLogInfo(&event, nil, "complete") + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunApproveSwitchUnitMiddleware(approveSwitchEncounter, &input); err != nil { + return err + } return nil }) + if err = runLogMiddleware(err, input, mwRunner); err != nil { + return nil, err + } + + pl.SetLogInfo(&event, nil, "complete") + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "single-data", + "status": "updated", + }, + Data: data.ToResponse(), + }, nil + +} + +func CancelSwitchUnit(input e.ApproveCancelUnitDto) (*d.Data, error) { + rdDto := e.ReadDetailDto{Id: input.Id} + var ( + data *e.Encounter + err error + ) + + event := pl.Event{ + Feature: "CancelSwitchUnit", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "cancelSwitchUnit") + + roleAllowed := []string{string(erg.EPCNur)} + err = validateAuth(input.AuthInfo, roleAllowed, "request-switch-poly", &event) if err != nil { return nil, err } + mwRunner := newMiddlewareRunner(&event) + + 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) + } + + // get internalReference based on internalReferences_Id + irData, err := uir.ReadDetailData(eir.ReadDetailDto{ + Id: input.InternalReferences_Id}, &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) + } + + // update internal reference + if err = uir.UpdateData(eir.UpdateDto{ + Id: input.InternalReferences_Id, + CreateDto: eir.CreateDto{ + Status_Code: erc.DACCanceled, + Nurse_Code: input.Nurse_Code}}, irData, &event, tx); err != nil { + return err + } + + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunCancelSwitchUnitMiddleware(cancelSwitchEncounter, &input); err != nil { + return err + } + return nil + }) + + if err = runLogMiddleware(err, input, mwRunner); err != nil { + return nil, err + } + + pl.SetLogInfo(&event, nil, "complete") + return &d.Data{ Meta: d.IS{ "source": source, diff --git a/internal/use-case/main-use-case/encounter/helper.go b/internal/use-case/main-use-case/encounter/helper.go index f3042b89..b6f24a0b 100644 --- a/internal/use-case/main-use-case/encounter/helper.go +++ b/internal/use-case/main-use-case/encounter/helper.go @@ -122,6 +122,7 @@ 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 + dst.Status_Code = erc.DSCProcess } func setDischargeMethodCode(code ere.PolySwitchCode) *ere.DischargeMethodCode { diff --git a/internal/use-case/main-use-case/encounter/lib.go b/internal/use-case/main-use-case/encounter/lib.go index b0280e0d..0b14b925 100644 --- a/internal/use-case/main-use-case/encounter/lib.go +++ b/internal/use-case/main-use-case/encounter/lib.go @@ -343,7 +343,7 @@ func verifyAllocatedVisitCount(i e.CreateDto, event *pl.Event) (e.Encounter, boo return recentEncounterAdm, valid, nil } -func updateEncounterApproveSwitchUnit(input e.ApproveUnitDto, event *pl.Event, dbx ...*gorm.DB) (err error) { +func updateEncounterApproveSwitchUnit(input e.ApproveCancelUnitDto, event *pl.Event, dbx ...*gorm.DB) (err error) { pl.SetLogInfo(event, nil, "started", "DBCreate") var tx *gorm.DB @@ -356,7 +356,7 @@ func updateEncounterApproveSwitchUnit(input e.ApproveUnitDto, event *pl.Event, d if err := tx.Model(&e.Encounter{}). Where("\"Id\" = ?", input.Id). Updates(map[string]interface{}{ - "Responsible_Doctor_Code": input.Doctor_Code, + "Responsible_Doctor_Code": input.Dst_Doctor_Code, "Responsible_Nurse_Code": input.Nurse_Code, }).Error; err != nil { event.Status = "failed" diff --git a/internal/use-case/main-use-case/encounter/middleware-runner.go b/internal/use-case/main-use-case/encounter/middleware-runner.go index ef1cb283..59bcfd9d 100644 --- a/internal/use-case/main-use-case/encounter/middleware-runner.go +++ b/internal/use-case/main-use-case/encounter/middleware-runner.go @@ -27,7 +27,6 @@ func newMiddlewareRunner(event *pl.Event) *middlewareRunner { } } -// ExecuteCreateMiddleware executes create middleware func (me *middlewareRunner) RunCreateMiddleware(middlewares []createMw, input *e.Encounter) error { if !me.SyncOn { return nil @@ -47,7 +46,6 @@ func (me *middlewareRunner) RunCreateMiddleware(middlewares []createMw, input *e return nil } -// ExecuteCreateMiddleware executes create middleware func (me *middlewareRunner) RunCreateLogMiddleware(middlewares []createLogMw, input *esync.SimxLogDto) error { if !me.SyncOn { return nil @@ -199,6 +197,60 @@ func (me *middlewareRunner) RunUpdateStatusMiddleware(middlewares []updateStatus return nil } +func (me *middlewareRunner) RunRequestSwitchUnitMiddleware(middleware requestSwitchUnitMw, input *e.Encounter) error { + if !me.SyncOn { + return nil + } + + logData := pu.GetLogData(input, nil) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + + return nil +} + +func (me *middlewareRunner) RunApproveSwitchUnitMiddleware(middleware approveSwitchUnitMw, input *e.ApproveCancelUnitDto) error { + if !me.SyncOn { + return nil + } + + logData := pu.GetLogData(input, nil) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + + return nil +} + +func (me *middlewareRunner) RunCancelSwitchUnitMiddleware(middleware cancelSwitchUnitMw, input *e.ApproveCancelUnitDto) error { + if !me.SyncOn { + return nil + } + + logData := pu.GetLogData(input, nil) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + + return nil +} + func (me *middlewareRunner) setMwType(mwType pu.MWType) { me.MwType = mwType } diff --git a/internal/use-case/main-use-case/encounter/middleware.go b/internal/use-case/main-use-case/encounter/middleware.go index fe941372..306e4bca 100644 --- a/internal/use-case/main-use-case/encounter/middleware.go +++ b/internal/use-case/main-use-case/encounter/middleware.go @@ -22,4 +22,8 @@ func init() { updatestatusEncounter = append(updatestatusEncounter, updateStatusMw{Name: "sync-update-status-encounter", Func: plugin.UpdateStatus}) + + requestSwitchEncounter = requestSwitchUnitMw{Name: "sync-request-switch-unit-encounter", Func: plugin.RequestSwitchUnit} + approveSwitchEncounter = approveSwitchUnitMw{Name: "sync-approve-switch-unit-encounter", Func: plugin.ApproveSwitchUnit} + cancelSwitchEncounter = cancelSwitchUnitMw{Name: "sync-cancel-switch-unit-encounter", Func: plugin.CancelSwitchUnit} } diff --git a/internal/use-case/main-use-case/encounter/tycovar.go b/internal/use-case/main-use-case/encounter/tycovar.go index f25ad45b..2b268378 100644 --- a/internal/use-case/main-use-case/encounter/tycovar.go +++ b/internal/use-case/main-use-case/encounter/tycovar.go @@ -59,6 +59,21 @@ type updateStatusMw struct { Func func(input *e.Encounter) error } +type requestSwitchUnitMw struct { + Name string + Func func(input *e.Encounter) error +} + +type approveSwitchUnitMw struct { + Name string + Func func(input *e.ApproveCancelUnitDto) error +} + +type cancelSwitchUnitMw struct { + Name string + Func func(input *e.ApproveCancelUnitDto) error +} + type UpdateMw = updateMw type DeleteMw = deleteMw @@ -76,3 +91,6 @@ var deletePostMw []readDetailMw var checkinEncounterMw checkinMw var checkoutEncounter checkoutMw var updatestatusEncounter []updateStatusMw +var requestSwitchEncounter requestSwitchUnitMw +var approveSwitchEncounter approveSwitchUnitMw +var cancelSwitchEncounter cancelSwitchUnitMw diff --git a/internal/use-case/simgos-sync-plugin/new/encounter/plugin.go b/internal/use-case/simgos-sync-plugin/new/encounter/plugin.go index 7e779aec..a6334fdb 100644 --- a/internal/use-case/simgos-sync-plugin/new/encounter/plugin.go +++ b/internal/use-case/simgos-sync-plugin/new/encounter/plugin.go @@ -49,6 +49,24 @@ func UpdateStatus(input *e.Encounter) error { return helper.DoJsonRequest(input, "PATCH", endpoint) } +func RequestSwitchUnit(input *e.Encounter) error { + prefixEndpoint := getPrefixEndpoint() + endpoint := fmt.Sprintf("%s/%v/req-switch-unit", prefixEndpoint, input.Id) + return helper.DoJsonRequest(input, "PATCH", endpoint) +} + +func ApproveSwitchUnit(input *e.ApproveCancelUnitDto) error { + prefixEndpoint := getPrefixEndpoint() + endpoint := fmt.Sprintf("%s/%v/approve-switch-unit", prefixEndpoint, input.Id) + return helper.DoJsonRequest(input, "PATCH", endpoint) +} + +func CancelSwitchUnit(input *e.ApproveCancelUnitDto) error { + prefixEndpoint := getPrefixEndpoint() + endpoint := fmt.Sprintf("%s/%v/cancel-switch-unit", prefixEndpoint, input.Id) + return helper.DoJsonRequest(input, "PATCH", endpoint) +} + func getPrefixEndpoint() string { return fmt.Sprintf("%s%s/v1/encounter", sync.O.Host, sync.O.Prefix) } 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 9b62c7c8..59e7e345 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 @@ -10,8 +10,11 @@ import ( e "simrs-vx/internal/domain/main-entities/encounter" etp "simrs-vx/internal/domain/simgos-entities/t-pendaftaran" - esync "simrs-vx/internal/domain/sync-entities/encounter" + synce "simrs-vx/internal/domain/sync-entities/encounter" + syncir "simrs-vx/internal/domain/sync-entities/internal-reference" elog "simrs-vx/internal/domain/sync-entities/log" + + utph "simrs-vx/internal/use-case/simgos-sync-use-case/new/internal-reference" ) const source = "encounter" @@ -19,7 +22,7 @@ const source = "encounter" func Create(input e.Encounter) (*d.Data, error) { var ( sgData *etp.TPendaftaran - syncLink *esync.EncounterLink + syncLink *synce.EncounterLink err error ) @@ -337,6 +340,10 @@ func UpdateStatus(input e.Encounter) (*d.Data, error) { } func RequestSwitchUnit(input e.Encounter) (*d.Data, error) { + var ( + syncLinkInternal *[]syncir.InternalReferenceLink + ) + event := pl.Event{ Feature: "RequestSwitchUnit", Source: source, @@ -357,23 +364,33 @@ func RequestSwitchUnit(input e.Encounter) (*d.Data, error) { return nil, err } - 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 { + err = db.WithDualTx(func(tx *db.Dualtx) error { + // Step 3: Update TPendaftaran + if err = UpdateTPendaftaranData(input, tpendaftaran, "update-status", &event, tx.Simgos); err != nil { return err } - // Step 3: Insert TPemeriksaanHist - if _, err := CreateBulkTPemeriksaanHistData(input, tpendaftaran, &event, tx); err != nil { + // Step 4: Bulk Insert TPemeriksaanHist + tPemeriksanHistory, err := utph.CreateSimgosData(input, tpendaftaran, &event, tx.Simgos) + if err != nil { return err } - // Step 4: BulkInsert To Link + // Step 5: Bulk Insert To Link + if syncLinkInternal, err = utph.CreateBulkLinkData(*input.InternalReferences, *tPemeriksanHistory, &event, tx.Sync); err != nil { + return err + } return nil }) + if err != nil { + if syncLinkInternal != nil { + go func() { _ = utph.DeleteLinkData(syncLinkInternal, &event) }() + } + return nil, err + } + pl.SetLogInfo(&event, nil, "complete") return &d.Data{ @@ -385,23 +402,23 @@ func RequestSwitchUnit(input e.Encounter) (*d.Data, error) { }, nil } -func ApproveSwitchUnit(input e.ApproveUnitDto) (*d.Data, error) { +func ApproveSwitchUnit(input e.ApproveCancelUnitDto) (*d.Data, error) { event := pl.Event{ - Feature: "RequestSwitchUnit", + Feature: "ApproveSwitchUnit", Source: source, } // Start log - pl.SetLogInfo(&event, input, "started", "request-switch-unit") + pl.SetLogInfo(&event, input, "started", "approve-switch-unit") - // STEP 1: Get Link - syncLink, err := ReadDetailLinkData(input.Id, &event) + // STEP 1: Get InternalReference Link + syncLink, err := utph.ReadDetailLinkData(input.InternalReferences_Id, &event) if err != nil { return nil, err } - // STEP 2: Get Simgos - tpendaftaran, err := ReadTPendaftaranDetailData(syncLink.Simgos_Id, &event) + // STEP 2: Get TPemeriksaanHist + tPemeriksaanHist, err := utph.ReadDetailSimgosData(syncLink.Simgos_Id, &event) if err != nil { return nil, err } @@ -409,7 +426,49 @@ func ApproveSwitchUnit(input e.ApproveUnitDto) (*d.Data, error) { tx := db.NewTx() err = tx.Simgos.Transaction(func(tx *gorm.DB) error { // Step 3: Update TPemeriksaanHist - if _, err := CreateBulkTPemeriksaanHistData(input, tpendaftaran, &event, tx); err != nil { + if err := utph.UpdateSimgosData(input, tPemeriksaanHist, "approve", &event, tx); err != nil { + return err + } + + return nil + }) + + pl.SetLogInfo(&event, nil, "complete") + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "single-data", + "status": "updated", + }, + }, nil +} + +func CancelSwitchUnit(input e.ApproveCancelUnitDto) (*d.Data, error) { + event := pl.Event{ + Feature: "CancelSwitchUnit", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "cancel-switch-unit") + + // STEP 1: Get InternalReference Link + syncLink, err := utph.ReadDetailLinkData(input.InternalReferences_Id, &event) + if err != nil { + return nil, err + } + + // STEP 2: Get TPemeriksaanHist + tPemeriksaanHist, err := utph.ReadDetailSimgosData(syncLink.Simgos_Id, &event) + if err != nil { + return nil, err + } + + tx := db.NewTx() + err = tx.Simgos.Transaction(func(tx *gorm.DB) error { + // Step 3: Update TPemeriksaanHist + if err := utph.UpdateSimgosData(input, tPemeriksaanHist, "cancel", &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 ac763d00..1d48ea97 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 @@ -125,29 +125,9 @@ func setDataUpdateStatus(input e.Encounter, data *etp.TPendaftaran) { 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 - //} - + if input.Discharge_Method_Code != nil { + setStatus(input.Discharge_Method_Code, data) + } } func setDataCheckIn(input e.Encounter, data *etp.TPendaftaran) { 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 bbb887e3..47d50802 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 @@ -138,6 +138,25 @@ func CreateLinkData(simxId, simgosId uint, event *pl.Event, dbx ...*gorm.DB) (*e return &data, nil } +func CreateBulkLinkData(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 ReadDetailLinkData(simxId uint, event *pl.Event) (*esync.EncounterLink, error) { pl.SetLogInfo(event, simxId, "started", "DBReadDetail") data := esync.EncounterLink{} @@ -219,26 +238,7 @@ func CreateBulkTPemeriksaanHistData(input e.Encounter, data *etp.TPendaftaran, e 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 { +func UpdateTPemeriksaanHistData(input e.ApproveCancelUnitDto, data *etph.TPemeriksaanHist, event *pl.Event, dbx ...*gorm.DB) error { pl.SetLogInfo(event, input, "started", "DBUpdateTPemeriksaanHist") var tx *gorm.DB diff --git a/internal/use-case/simgos-sync-use-case/new/internal-reference/helper.go b/internal/use-case/simgos-sync-use-case/new/internal-reference/helper.go new file mode 100644 index 00000000..9cb55785 --- /dev/null +++ b/internal/use-case/simgos-sync-use-case/new/internal-reference/helper.go @@ -0,0 +1,103 @@ +/* +DESCRIPTION: +Any functions that are used internally by the use-case +*/ +package internal_reference + +import ( + "encoding/json" + eir "simrs-vx/internal/domain/main-entities/internal-reference" + erc "simrs-vx/internal/domain/references/common" + "strconv" + + e "simrs-vx/internal/domain/main-entities/encounter" + + etph "simrs-vx/internal/domain/simgos-entities/t-pemeriksaan-hist" + etp "simrs-vx/internal/domain/simgos-entities/t-pendaftaran" + + esync "simrs-vx/internal/domain/sync-entities/internal-reference" + esyncLog "simrs-vx/internal/domain/sync-entities/log" +) + +func setCreateDataSimgos(input e.Encounter, data *etp.TPendaftaran) (hist []etph.TPemeriksaanHist) { + if enc := input.InternalReferences; enc != nil { + for i, ref := range *enc { + hist = append(hist, etph.TPemeriksaanHist{ + Idxdaftar: &data.Idxdaftar, + Kdpoly: stringtouint(*ref.Unit_Code), + DokterPengonsul: stringtouint(*ref.SrcDoctor_Code), + DokterPenerima: stringtouint(*ref.Doctor_Code), + }) + + // set user konsul + if n := input.Responsible_Nurse; n != nil { + if emp := n.Employee; emp != nil { + if u := emp.User; u != nil { + hist[i].UserKonsul = &u.Name + } + } + } + + // setaktif + aktif := uint16(1) + hist[i].StAktif = &aktif + } + } + return +} + +func setUpdateApproveDataSimgos(input e.ApproveCancelUnitDto, data *etph.TPemeriksaanHist) { + data.DokterPenerima = stringtouint(*input.Dst_Doctor_Code) + data.StartKonsul = &now + data.UserPenerima = &input.User_Name + data.MasukPoly = data.StartKonsul + return +} + +func setUpdateCancelDataSimgos(input e.ApproveCancelUnitDto, data *etph.TPemeriksaanHist) { + data.UserBatal = &input.User_Name + data.TglBatal = &now + + aktif := uint16(0) + data.StAktif = &aktif + + return +} + +func setDataSimxLog(input *esyncLog.SimxLogDto) (data esync.InternalReferenceSimxLog) { + // encode to JSON + jsonData, _ := json.MarshalIndent(input.Payload, "", " ") + jsonString := string(jsonData) + + var status erc.ProcessStatusCode + if input.IsSuccess { + status = erc.PSCSuccess + } else { + status = erc.PSCFailed + if input.ErrMessage != nil { + data.ErrMessage = input.ErrMessage + } + } + + data.Value = &jsonString + data.Date = &now + data.Status = status + + return +} + +func setDataSimxLink(ir []eir.InternalReference, tph []etph.TPemeriksaanHist) (data []esync.InternalReferenceLink) { + for i := range len(ir) { + data = append(data, esync.InternalReferenceLink{ + Simx_Id: ir[i].Id, + Simgos_Id: tph[i].IdPemeriksaanHist, + }) + } + return +} + +func stringtouint(v string) *uint { + u, _ := strconv.Atoi(v) + point := uint(u) + return &point +} diff --git a/internal/use-case/simgos-sync-use-case/new/internal-reference/lib.go b/internal/use-case/simgos-sync-use-case/new/internal-reference/lib.go new file mode 100644 index 00000000..2263f230 --- /dev/null +++ b/internal/use-case/simgos-sync-use-case/new/internal-reference/lib.go @@ -0,0 +1,173 @@ +package internal_reference + +import ( + plh "simrs-vx/pkg/lib-helper" + pl "simrs-vx/pkg/logger" + pu "simrs-vx/pkg/use-case-helper" + "time" + + dg "github.com/karincake/apem/db-gorm-pg" + "gorm.io/gorm" + + e "simrs-vx/internal/domain/main-entities/encounter" + eir "simrs-vx/internal/domain/main-entities/internal-reference" + + etph "simrs-vx/internal/domain/simgos-entities/t-pemeriksaan-hist" + etp "simrs-vx/internal/domain/simgos-entities/t-pendaftaran" + + esync "simrs-vx/internal/domain/sync-entities/internal-reference" + esynclog "simrs-vx/internal/domain/sync-entities/log" +) + +const source = "internal-reference" + +var now = time.Now() + +func CreateSimgosData(input e.Encounter, dataDaftar *etp.TPendaftaran, event *pl.Event, dbx ...*gorm.DB) (*[]etph.TPemeriksaanHist, error) { + pl.SetLogInfo(event, nil, "started", "DBCreate") + + data := setCreateDataSimgos(input, dataDaftar) + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.IS["simrs"] + } + + if err := tx.Create(&data).Error; err != nil { + return nil, plh.HandleCreateError(input, event, err) + } + + pl.SetLogInfo(event, nil, "complete") + return &data, nil +} + +func ReadDetailSimgosData(simgosId uint, event *pl.Event) (*etph.TPemeriksaanHist, error) { + pl.SetLogInfo(event, simgosId, "started", "DBReadDetail") + data := etph.TPemeriksaanHist{} + + var tx = dg.IS["simrs"] + + if err := tx. + Where("\"id_pemeriksaanhist\" = ?", simgosId). + First(&data).Error; err != nil { + if processedErr := pu.HandleReadError(err, event, source, simgosId, data); processedErr != nil { + return nil, processedErr + } + } + + pl.SetLogInfo(event, nil, "complete") + return &data, nil +} + +func UpdateSimgosData(input e.ApproveCancelUnitDto, data *etph.TPemeriksaanHist, method string, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, input, "started", "DBUpdate") + + switch method { + case "approve": + setUpdateApproveDataSimgos(input, data) + case "cancel": + setUpdateCancelDataSimgos(input, data) + } + + 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 +} + +func CreateBulkLinkData(ir []eir.InternalReference, tph []etph.TPemeriksaanHist, event *pl.Event, dbx ...*gorm.DB) (*[]esync.InternalReferenceLink, error) { + pl.SetLogInfo(event, nil, "started", "DBCreate") + data := setDataSimxLink(ir, tph) + + 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 ReadDetailLinkData(simxId uint, event *pl.Event) (*esync.InternalReferenceLink, error) { + pl.SetLogInfo(event, simxId, "started", "DBReadDetail") + data := esync.InternalReferenceLink{} + + var tx = dg.I + + if err := tx. + Where("\"Simx_Id\" = ?", simxId). + First(&data).Error; err != nil { + if processedErr := pu.HandleReadError(err, event, source, simxId, data); processedErr != nil { + return nil, processedErr + } + } + + pl.SetLogInfo(event, nil, "complete") + return &data, nil +} + +func DeleteLinkData(data *[]esync.InternalReferenceLink, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, data, "started", "DBDelete") + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Delete(*data).Error; err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-delete-fail", + Detail: "Database delete failed", + Raw: err, + } + return pl.SetLogError(event, data) + } + + pl.SetLogInfo(event, nil, "complete") + return nil +} + +func CreateLogData(input esynclog.SimxLogDto, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, nil, "started", "DBCreate") + data := setDataSimxLog(&input) + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Create(&data).Error; err != nil { + return plh.HandleCreateError(input, event, err) + } + + pl.SetLogInfo(event, nil, "complete") + return nil +} diff --git a/internal/use-case/simgos-sync-use-case/new/internal-reference/middleware-runner.go b/internal/use-case/simgos-sync-use-case/new/internal-reference/middleware-runner.go new file mode 100644 index 00000000..344bbe93 --- /dev/null +++ b/internal/use-case/simgos-sync-use-case/new/internal-reference/middleware-runner.go @@ -0,0 +1,103 @@ +package internal_reference + +import ( + e "simrs-vx/internal/domain/main-entities/internal-reference" + pl "simrs-vx/pkg/logger" + pu "simrs-vx/pkg/use-case-helper" + + "gorm.io/gorm" +) + +type middlewareRunner struct { + Event *pl.Event + Tx *gorm.DB + MwType pu.MWType +} + +// NewMiddlewareExecutor creates a new middleware executor +func newMiddlewareRunner(event *pl.Event, tx *gorm.DB) *middlewareRunner { + return &middlewareRunner{ + Event: event, + Tx: tx, + } +} + +// ExecuteCreateMiddleware executes create middleware +func (me *middlewareRunner) RunCreateMiddleware(middlewares []createMw, input *e.CreateDto, data *e.InternalReference) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) RunReadListMiddleware(middlewares []readListMw, input *e.ReadListDto, data *e.InternalReference) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) RunReadDetailMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.InternalReference) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) RunUpdateMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.InternalReference) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) RunDeleteMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.InternalReference) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) setMwType(mwType pu.MWType) { + me.MwType = mwType +} diff --git a/internal/use-case/simgos-sync-use-case/new/internal-reference/middleware.go b/internal/use-case/simgos-sync-use-case/new/internal-reference/middleware.go new file mode 100644 index 00000000..2afd1eaf --- /dev/null +++ b/internal/use-case/simgos-sync-use-case/new/internal-reference/middleware.go @@ -0,0 +1,9 @@ +package internal_reference + +// example of middleware +// func init() { +// createPreMw = append(createPreMw, +// CreateMw{Name: "modif-input", Func: pm.ModifInput}, +// CreateMw{Name: "check-data", Func: pm.CheckData}, +// ) +// } diff --git a/internal/use-case/simgos-sync-use-case/new/internal-reference/tycovar.go b/internal/use-case/simgos-sync-use-case/new/internal-reference/tycovar.go new file mode 100644 index 00000000..4cb6c572 --- /dev/null +++ b/internal/use-case/simgos-sync-use-case/new/internal-reference/tycovar.go @@ -0,0 +1,44 @@ +/* +DESCRIPTION: +A sample, part of the package that contains type, constants, and/or variables. + +In this sample it also provides type and variable regarding the needs of the +middleware to separate from main use-case which has the basic CRUD +functionality. The purpose of this is to make the code more maintainable. +*/ +package internal_reference + +import ( + "gorm.io/gorm" + + e "simrs-vx/internal/domain/main-entities/internal-reference" +) + +type createMw struct { + Name string + Func func(input *e.CreateDto, data *e.InternalReference, tx *gorm.DB) error +} + +type readListMw struct { + Name string + Func func(input *e.ReadListDto, data *e.InternalReference, tx *gorm.DB) error +} + +type readDetailMw struct { + Name string + Func func(input *e.ReadDetailDto, data *e.InternalReference, tx *gorm.DB) error +} + +type UpdateMw = readDetailMw +type DeleteMw = readDetailMw + +var createPreMw []createMw // preprocess middleware +var createPostMw []createMw // postprocess middleware +var readListPreMw []readListMw // .. +var readListPostMw []readListMw // .. +var readDetailPreMw []readDetailMw +var readDetailPostMw []readDetailMw +var updatePreMw []readDetailMw +var updatePostMw []readDetailMw +var deletePreMw []readDetailMw +var deletePostMw []readDetailMw