Merge pull request #215 from dikstub-rssa/feat/chemo-plan

Feat/chemo plan
This commit is contained in:
Dwi Atmoko Purbo Sakti
2025-12-15 15:22:41 +07:00
committed by GitHub
28 changed files with 1477 additions and 354 deletions
+30 -19
View File
@@ -11,13 +11,14 @@ import (
)
type CreateDto struct {
Parent_Id *uint `json:"parent_id"`
SeriesNumber *uint16 `json:"seriesNumber"`
CycleNumber *uint `json:"cycleNumber"`
PlanDate *time.Time `json:"planDate"`
RealizationDate *time.Time `json:"realizationDate"`
Notes *string `json:"notes"`
Status ere.StatusProtocolChemo `json:"status"`
Parent_Id *uint `json:"parent_id"`
SeriesNumber *uint16 `json:"seriesNumber"`
CycleNumber *uint `json:"cycleNumber"`
PlanDate *time.Time `json:"planDate"`
RealizationDate *time.Time `json:"realizationDate"`
Notes *string `json:"notes"`
Status *ere.StatusProtocolChemo `json:"status"`
Encounter_Id *uint `json:"encounter_id"`
}
type ReadListDto struct {
@@ -32,17 +33,27 @@ 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 FailDto struct {
Id uint `json:"id"`
Reasons string `json:"reasons" validate:"required"`
}
type FailReason struct {
Date *time.Time `json:"date"`
FailReason string `json:"failReason"`
Encounter_Id *uint `json:"encounter_id"`
}
type MetaDto struct {
@@ -53,15 +64,15 @@ type MetaDto struct {
type ResponseDto struct {
ecore.Main
Parent_Id *uint `json:"parent_id"` // chemo.Id
Protocol_Id *uint `json:"protocol_id"`
SeriesNumber *uint16 `json:"seriesNumber"` // series ke -
CycleNumber *uint `json:"cycleNumber"` // cycle ke -
PlanDate *time.Time `json:"planDate"`
RealizationDate *time.Time `json:"realizationDate"`
Notes *string `json:"notes"`
Status ere.StatusProtocolChemo `json:"status"`
Reasons *string `json:"reasons"`
Parent_Id *uint `json:"parent_id"` // chemo.Id
Protocol_Id *uint `json:"protocol_id"`
SeriesNumber *uint16 `json:"seriesNumber"` // series ke -
CycleNumber *uint `json:"cycleNumber"` // cycle ke -
PlanDate *time.Time `json:"planDate"`
RealizationDate *time.Time `json:"realizationDate"`
Notes *string `json:"notes"`
Status *ere.StatusProtocolChemo `json:"status"`
Reasons *string `json:"reasons"`
}
func (d ChemoPlan) ToResponse() ResponseDto {
@@ -11,15 +11,15 @@ import (
type ChemoPlan struct {
ecore.Main
Parent_Id *uint `json:"parent_id"` // chemo.Id
Protocol_Id *uint `json:"protocol_id"`
SeriesNumber *uint16 `json:"seriesNumber"` // series ke -
CycleNumber *uint `json:"cycleNumber"` // cycle ke -
PlanDate *time.Time `json:"planDate"`
RealizationDate *time.Time `json:"realizationDate"`
Notes *string `json:"notes"`
Status ere.StatusProtocolChemo `json:"status"`
Encounter_Id *uint `json:"encounter_id"`
Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"`
Reasons *string `json:"reasons"` // json
Parent_Id *uint `json:"parent_id"` // chemo.Id
Protocol_Id *uint `json:"protocol_id"`
SeriesNumber *uint16 `json:"seriesNumber"` // series ke -
CycleNumber *uint `json:"cycleNumber"` // cycle ke -
PlanDate *time.Time `json:"planDate"`
RealizationDate *time.Time `json:"realizationDate"`
Notes *string `json:"notes"`
Status *ere.StatusProtocolChemo `json:"status"`
Encounter_Id *uint `json:"encounter_id"`
Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"`
Reasons *string `json:"reasons"` // json
}
@@ -1,6 +1,8 @@
package chemo_protocol
import (
eus "simrs-vx/internal/domain/main-entities/user"
pa "simrs-vx/internal/lib/auth"
// std
"time"
@@ -11,19 +13,25 @@ import (
ecore "simrs-vx/internal/domain/base-entities/core"
ec "simrs-vx/internal/domain/main-entities/chemo"
ep "simrs-vx/internal/domain/main-entities/chemo-plan"
)
type CreateDto struct {
Chemo_Id *uint `json:"chemo_id"`
Patient_Weight *float32 `json:"patient_weight"`
Patient_Height *float32 `json:"patient_height"`
Diagnoses *string `json:"diagnoses"`
Interval *uint `json:"interval"`
Cycle *uint `json:"cycle"`
Series *uint16 `json:"series"`
StartDate *time.Time `json:"startDate"`
EndDate *time.Time `json:"endDate"`
Status_Code erc.DataVerifiedCode `json:"-"`
Encounter_Id *uint `json:"encounter_id" validate:"required"`
Chemo_Id *uint `json:"chemo_id" validate:"required"`
Patient_Weight *float32 `json:"patient_weight"`
Patient_Height *float32 `json:"patient_height"`
Diagnoses *string `json:"diagnoses" validate:"required"`
Interval *uint `json:"interval" validate:"required"`
Cycle *uint `json:"cycle" validate:"required"`
Series *uint16 `json:"series" validate:"required"`
StartDate *time.Time `json:"startDate"`
EndDate *time.Time `json:"endDate"`
Patient_Id *uint `json:"patient_id"`
ChemoPlans *[]ep.CreateDto `json:"chemoPlans" validate:"required"`
Id *uint `json:"-"`
Status_Code erc.DataVerifiedCode `json:"-"`
}
type ReadListDto struct {
@@ -33,21 +41,29 @@ type ReadListDto struct {
}
type FilterDto struct {
Chemo_Id *uint `json:"chemo-id"`
Chemo_Id *uint `json:"chemo-id"`
Patient_Id *uint `json:"patient-id"`
}
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 VerifyDto struct {
Id uint `json:"id"`
Status_Code erc.DataVerifiedCode `json:"-"`
pa.AuthInfo
}
type MetaDto struct {
@@ -58,32 +74,42 @@ type MetaDto struct {
type ResponseDto struct {
ecore.Main
Chemo_Id *uint `json:"chemo_id"`
Chemo *ec.Chemo `json:"chemo,omitempty"`
Patient_Weight *float32 `json:"patient_weight"`
Patient_Height *float32 `json:"patient_height"`
Diagnoses *string `json:"diagnoses"`
Interval *uint `json:"interval"`
Cycle *uint `json:"cycle"`
Series *uint16 `json:"series"`
StartDate *time.Time `json:"startDate"`
EndDate *time.Time `json:"endDate"`
Status_Code erc.DataVerifiedCode `json:"status_code"`
Chemo_Id *uint `json:"chemo_id"`
Chemo *ec.Chemo `json:"chemo,omitempty"`
Patient_Weight *float32 `json:"patient_weight"`
Patient_Height *float32 `json:"patient_height"`
Diagnoses *string `json:"diagnoses"`
Interval *uint `json:"interval"`
Cycle *uint `json:"cycle"`
Series *uint16 `json:"series"`
StartDate *time.Time `json:"startDate"`
EndDate *time.Time `json:"endDate"`
Status_Code erc.DataVerifiedCode `json:"status_code"`
VerifiedAt *time.Time `json:"verifiedAt"`
VerifiedBy_User_Id *uint `json:"verifiedBy_user_id"`
VerifiedBy *eus.User `json:"verifiedBy,omitempty"`
ChemoPlans *[]ep.ChemoPlan `json:"chemoPlans,omitempty"`
Patient_Id *uint `json:"patient_id"`
}
func (d ChemoProtocol) ToResponse() ResponseDto {
resp := ResponseDto{
Chemo_Id: d.Chemo_Id,
Chemo: d.Chemo,
Patient_Weight: d.Patient_Weight,
Patient_Height: d.Patient_Height,
Diagnoses: d.Diagnoses,
Interval: d.Interval,
Cycle: d.Cycle,
Series: d.Series,
StartDate: d.StartDate,
EndDate: d.EndDate,
Status_Code: d.Status_Code,
Chemo_Id: d.Chemo_Id,
Chemo: d.Chemo,
Patient_Weight: d.Patient_Weight,
Patient_Height: d.Patient_Height,
Diagnoses: d.Diagnoses,
Interval: d.Interval,
Cycle: d.Cycle,
Series: d.Series,
StartDate: d.StartDate,
EndDate: d.EndDate,
Status_Code: d.Status_Code,
VerifiedAt: d.VerifiedAt,
VerifiedBy_User_Id: d.VerifiedBy_User_Id,
VerifiedBy: d.VerifiedBy,
ChemoPlans: d.ChemoPlans,
Patient_Id: d.Patient_Id,
}
resp.Main = d.Main
return resp
+13 -5
View File
@@ -3,6 +3,9 @@ package chemo
import (
ed "simrs-vx/internal/domain/main-entities/doctor"
es "simrs-vx/internal/domain/main-entities/specialist"
ere "simrs-vx/internal/domain/references/encounter"
// std
"time"
// internal - lib
@@ -21,6 +24,7 @@ type CreateDto struct {
Encounter_Id *uint `json:"encounter_id"`
Status_Code erc.DataVerifiedCode `json:"status_code"`
Specialist_Code *string `json:"specialist_code"`
Class_Code ere.ChemoClassCode `json:"class_code"`
}
type ReadListDto struct {
@@ -34,28 +38,32 @@ type FilterDto struct {
Status_Code *erc.DataVerifiedCode `json:"status-code"`
VerifiedBy_User_Id *uint `json:"verifiedBy-user-id"`
Specialist_Code *string `json:"specialist-code"`
Patient_Id *uint `json:"patient-id"`
Class_Code ere.ChemoClassCode `json:"class-code"`
}
type ReadDetailDto struct {
Id uint16 `json:"id"`
Id uint `json:"id"`
Includes string `json:"includes"`
FilterDto
}
type UpdateDto struct {
Id uint16 `json:"id"`
Id uint `json:"id"`
CreateDto
}
type DeleteDto struct {
Id uint16 `json:"id"`
Id uint `json:"id"`
}
type VerifyDto struct {
Id uint16 `json:"id"`
Id uint `json:"id"`
Status_Code erc.DataVerifiedCode `json:"status_code"`
Bed *string `json:"bed"`
Needs *string `json:"needs"`
Doctor_Code *string `json:"doctor_code" validate:"required"`
NextChemoDate *time.Time `json:"nextChemoDate"`
NextChemoDate *time.Time `json:"nextChemoDate" validate:"required"`
pa.AuthInfo
}
@@ -117,6 +117,7 @@ type FilterDto struct {
MedicalDischargeEducation *string `json:"medicalDischargeEducation"`
AdmDischargeEducation *string `json:"admDischargeEducation"`
DischargeReason *string `json:"dischargeReason"`
ChemoClass *ere.ChemoClassCode `json:"chemo-class"`
}
type ReadDetailDto struct {
@@ -130,9 +130,9 @@ const (
ETCEncounter EntityTypeCode = "encounter"
ETCMCU EntityTypeCode = "mcu"
SPCComplete StatusProtocolChemo = "complete"
SPCPlanned StatusProtocolChemo = "planned"
SPCSchedule StatusProtocolChemo = "schedule"
SPCComplete StatusProtocolChemo = "complete" // Terealisasi
SPCPlanned StatusProtocolChemo = "planned" // Terencana
SPCSchedule StatusProtocolChemo = "schedule" // Terjadwal
)
func (ec EncounterClassCode) Code() string {
@@ -0,0 +1,88 @@
package chemo_protocol
import (
"net/http"
rw "github.com/karincake/risoles"
sf "github.com/karincake/semprit"
e "simrs-vx/internal/domain/main-entities/chemo-plan"
ep "simrs-vx/internal/domain/main-entities/chemo-protocol"
u "simrs-vx/internal/use-case/main-use-case/chemo-plan"
)
type myBase struct{}
var O myBase
func (obj myBase) Create(w http.ResponseWriter, r *http.Request) {
dto := ep.CreateDto{}
if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
return
}
res, err := u.Create(dto)
rw.DataResponse(w, res, err)
}
func (obj myBase) GetList(w http.ResponseWriter, r *http.Request) {
dto := e.ReadListDto{}
sf.UrlQueryParam(&dto, *r.URL)
res, err := u.ReadList(dto)
rw.DataResponse(w, res, err)
}
func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) {
id := rw.ValidateInt(w, "id", r.PathValue("id"))
if id <= 0 {
return
}
dto := e.ReadDetailDto{}
sf.UrlQueryParam(&dto, *r.URL)
dto.Id = uint(id)
res, err := u.ReadDetail(dto)
rw.DataResponse(w, res, err)
}
func (obj myBase) Update(w http.ResponseWriter, r *http.Request) {
id := rw.ValidateInt(w, "id", r.PathValue("id"))
if id <= 0 {
return
}
dto := e.UpdateDto{}
if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
return
}
dto.Id = uint(id)
res, err := u.Update(dto)
rw.DataResponse(w, res, err)
}
func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) {
id := rw.ValidateInt(w, "id", r.PathValue("id"))
if id <= 0 {
return
}
dto := e.DeleteDto{}
dto.Id = uint(id)
res, err := u.Delete(dto)
rw.DataResponse(w, res, err)
}
func (obj myBase) Fail(w http.ResponseWriter, r *http.Request) {
id := rw.ValidateInt(w, "id", r.PathValue("id"))
if id <= 0 {
return
}
dto := e.FailDto{}
if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
return
}
dto.Id = uint(id)
res, err := u.Fail(dto)
rw.DataResponse(w, res, err)
}
@@ -2,7 +2,10 @@ package chemo_protocol
import (
"net/http"
erc "simrs-vx/internal/domain/references/common"
pa "simrs-vx/internal/lib/auth"
d "github.com/karincake/dodol"
rw "github.com/karincake/risoles"
sf "github.com/karincake/semprit"
@@ -39,7 +42,7 @@ func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) {
dto := e.ReadDetailDto{}
sf.UrlQueryParam(&dto, *r.URL)
dto.Id = uint16(id)
dto.Id = uint(id)
res, err := u.ReadDetail(dto)
rw.DataResponse(w, res, err)
}
@@ -54,7 +57,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 := u.Update(dto)
rw.DataResponse(w, res, err)
}
@@ -66,7 +69,46 @@ func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) {
}
dto := e.DeleteDto{}
dto.Id = uint16(id)
dto.Id = uint(id)
res, err := u.Delete(dto)
rw.DataResponse(w, res, err)
}
func (obj myBase) Verify(w http.ResponseWriter, r *http.Request) {
id := rw.ValidateInt(w, "id", r.PathValue("id"))
if id <= 0 {
return
}
dto := e.VerifyDto{}
dto.Id = uint(id)
authInfo, err := pa.GetAuthInfo(r)
if err != nil {
rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil)
}
dto.AuthInfo = *authInfo
dto.Status_Code = erc.DVCVerified
res, err := u.Verify(dto)
rw.DataResponse(w, res, err)
}
func (obj myBase) Reject(w http.ResponseWriter, r *http.Request) {
id := rw.ValidateInt(w, "id", r.PathValue("id"))
if id <= 0 {
return
}
dto := e.VerifyDto{}
dto.Id = uint(id)
authInfo, err := pa.GetAuthInfo(r)
if err != nil {
rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil)
}
dto.AuthInfo = *authInfo
dto.Status_Code = erc.DVCRejected
res, err := u.Verify(dto)
rw.DataResponse(w, res, err)
}
@@ -3,20 +3,16 @@ package chemo
import (
"net/http"
rw "github.com/karincake/risoles"
sf "github.com/karincake/semprit"
// ua "github.com/karincake/tumpeng/auth/svc"
e "simrs-vx/internal/domain/main-entities/chemo"
erc "simrs-vx/internal/domain/references/common"
u "simrs-vx/internal/use-case/main-use-case/chemo"
pa "simrs-vx/internal/lib/auth"
d "github.com/karincake/dodol"
rw "github.com/karincake/risoles"
sf "github.com/karincake/semprit"
erc "simrs-vx/internal/domain/references/common"
e "simrs-vx/internal/domain/main-entities/chemo"
u "simrs-vx/internal/use-case/main-use-case/chemo"
)
type myBase struct{}
@@ -45,7 +41,8 @@ func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) {
return
}
dto := e.ReadDetailDto{}
dto.Id = uint16(id)
sf.UrlQueryParam(&dto, *r.URL)
dto.Id = uint(id)
res, err := u.ReadDetail(dto)
rw.DataResponse(w, res, err)
}
@@ -60,7 +57,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 := u.Update(dto)
rw.DataResponse(w, res, err)
}
@@ -72,7 +69,7 @@ func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) {
}
dto := e.DeleteDto{}
dto.Id = uint16(id)
dto.Id = uint(id)
res, err := u.Delete(dto)
rw.DataResponse(w, res, err)
}
@@ -88,7 +85,7 @@ func (obj myBase) Verify(w http.ResponseWriter, r *http.Request) {
return
}
dto.Id = uint16(id)
dto.Id = uint(id)
authInfo, err := pa.GetAuthInfo(r)
if err != nil {
rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil)
@@ -107,7 +104,7 @@ func (obj myBase) Reject(w http.ResponseWriter, r *http.Request) {
}
dto := e.VerifyDto{}
dto.Id = uint16(id)
dto.Id = uint(id)
authInfo, err := pa.GetAuthInfo(r)
if err != nil {
rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil)
@@ -9,7 +9,6 @@ import (
ambulancetransportrequest "simrs-vx/internal/interface/main-handler/ambulance-transport-req"
auth "simrs-vx/internal/interface/main-handler/authentication"
chemo "simrs-vx/internal/interface/main-handler/chemo"
chemoprotocol "simrs-vx/internal/interface/main-handler/chemo-protocol"
consultation "simrs-vx/internal/interface/main-handler/consultation"
controlletter "simrs-vx/internal/interface/main-handler/control-letter"
counter "simrs-vx/internal/interface/main-handler/counter"
@@ -82,6 +81,8 @@ import (
/******************** sources ********************/
antibioticsrc "simrs-vx/internal/interface/main-handler/antibiotic-src"
antibioticsrccat "simrs-vx/internal/interface/main-handler/antibiotic-src-category"
chemoplan "simrs-vx/internal/interface/main-handler/chemo-plan"
chemoprotocol "simrs-vx/internal/interface/main-handler/chemo-protocol"
device "simrs-vx/internal/interface/main-handler/device"
diagnosesrc "simrs-vx/internal/interface/main-handler/diagnose-src"
division "simrs-vx/internal/interface/main-handler/division"
@@ -314,7 +315,18 @@ func SetRoutes() http.Handler {
"PATCH /{id}/verify": therapyprotocol.O.Verify,
"PATCH /{id}/reject": therapyprotocol.O.Reject,
})
hc.RegCrud(r, "/v1/chemo-protocol", chemoprotocol.O)
hk.GroupRoutes("/v1/chemo-protocol", r, auth.GuardMW, hk.MapHandlerFunc{
"GET /": chemoprotocol.O.GetList,
"GET /{id}": chemoprotocol.O.GetDetail,
"POST /": chemoprotocol.O.Create,
"PATCH /{id}": chemoprotocol.O.Update,
"DELETE /{id}": chemoprotocol.O.Delete,
"PATCH /{id}/verify": chemoprotocol.O.Verify,
"PATCH /{id}/reject": chemoprotocol.O.Reject,
})
hk.GroupRoutes("/v1/chemo-plan", r, auth.GuardMW, hk.MapHandlerFunc{
"PATCH /{id}/fail": chemoplan.O.Fail,
})
hc.RegCrud(r, "/v1/upload-file", uploadfile.O)
hc.RegCrud(r, "/v1/encounter-document", encounterdocument.O)
hc.RegCrud(r, "/v1/general-consent", generalconsent.O)
@@ -0,0 +1,317 @@
package chemo_plan
import (
ere "simrs-vx/internal/domain/references/encounter"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
"strconv"
dg "github.com/karincake/apem/db-gorm-pg"
d "github.com/karincake/dodol"
"gorm.io/gorm"
erc "simrs-vx/internal/domain/references/common"
e "simrs-vx/internal/domain/main-entities/chemo-plan"
ep "simrs-vx/internal/domain/main-entities/chemo-protocol"
)
const source = "chemo-plan"
func Create(input ep.CreateDto) (*d.Data, error) {
data := []e.ChemoPlan{}
event := pl.Event{
Feature: "Create",
Source: source,
}
// Start log
pl.SetLogInfo(&event, input, "started", "create")
err := dg.I.Transaction(func(tx *gorm.DB) error {
input.Status_Code = erc.DVCNew
if resData, err := CreateData(&input, &event, tx); err != nil {
return err
} else {
data = *resData
}
pl.SetLogInfo(&event, nil, "complete")
return nil
})
if err != nil {
return nil, err
}
return &d.Data{
Meta: d.II{
"source": source,
"structure": "single-data",
"status": "created",
},
Data: e.ToResponseList(data),
}, nil
}
func ReadList(input e.ReadListDto) (*d.Data, error) {
var data *e.ChemoPlan
var dataList []e.ChemoPlan
var metaList *e.MetaDto
var err error
event := pl.Event{
Feature: "ReadList",
Source: source,
}
// Start log
pl.SetLogInfo(&event, input, "started", "readList")
err = dg.I.Transaction(func(tx *gorm.DB) error {
mwRunner := newMiddlewareRunner(&event, tx)
mwRunner.setMwType(pu.MWTPre)
// Run pre-middleware
if err := mwRunner.RunReadListMiddleware(readListPreMw, &input, data); err != nil {
return err
}
if dataList, metaList, err = ReadListData(input, &event, tx); err != nil {
return err
}
mwRunner.setMwType(pu.MWTPost)
// Run post-middleware
if err := mwRunner.RunReadListMiddleware(readListPostMw, &input, data); err != nil {
return err
}
return nil
})
if err != nil {
return nil, err
}
return &d.Data{
Meta: d.IS{
"source": source,
"structure": "list-data",
"status": "fetched",
"page_number": strconv.Itoa(metaList.PageNumber),
"page_size": strconv.Itoa(metaList.PageSize),
"record_totalCount": strconv.Itoa(metaList.Count),
"record_currentCount": strconv.Itoa(len(dataList)),
},
Data: e.ToResponseList(dataList),
}, nil
}
func ReadDetail(input e.ReadDetailDto) (*d.Data, error) {
var data *e.ChemoPlan
var err error
event := pl.Event{
Feature: "ReadDetail",
Source: source,
}
// Start log
pl.SetLogInfo(&event, input, "started", "readDetail")
err = dg.I.Transaction(func(tx *gorm.DB) error {
mwRunner := newMiddlewareRunner(&event, tx)
mwRunner.setMwType(pu.MWTPre)
// Run pre-middleware
if err := mwRunner.RunReadDetailMiddleware(readDetailPreMw, &input, data); err != nil {
return err
}
if data, err = ReadDetailData(input, &event, tx); err != nil {
return err
}
mwRunner.setMwType(pu.MWTPost)
// Run post-middleware
if err := mwRunner.RunReadDetailMiddleware(readDetailPostMw, &input, data); err != nil {
return err
}
return nil
})
if err != nil {
return nil, err
}
return &d.Data{
Meta: d.IS{
"source": source,
"structure": "single-data",
"status": "fetched",
},
Data: data.ToResponse(),
}, nil
}
func Update(input e.UpdateDto) (*d.Data, error) {
rdDto := e.ReadDetailDto{Id: input.Id}
var data *e.ChemoPlan
var err error
event := pl.Event{
Feature: "Update",
Source: source,
}
// Start log
pl.SetLogInfo(&event, input, "started", "update")
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 err := UpdateData(data, "", &event, tx); 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": "updated",
},
Data: data.ToResponse(),
}, nil
}
func Delete(input e.DeleteDto) (*d.Data, error) {
rdDto := e.ReadDetailDto{Id: input.Id}
var data *e.ChemoPlan
var err error
event := pl.Event{
Feature: "Delete",
Source: source,
}
// Start log
pl.SetLogInfo(&event, input, "started", "delete")
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
}
mwRunner := newMiddlewareRunner(&event, tx)
mwRunner.setMwType(pu.MWTPre)
// Run pre-middleware
if err := mwRunner.RunDeleteMiddleware(readDetailPreMw, &rdDto, data); err != nil {
return err
}
if err := DeleteData(data, &event, tx); err != nil {
return err
}
mwRunner.setMwType(pu.MWTPost)
// Run post-middleware
if err := mwRunner.RunDeleteMiddleware(readDetailPostMw, &rdDto, data); err != nil {
return err
}
return nil
})
if err != nil {
return nil, err
}
return &d.Data{
Meta: d.IS{
"source": source,
"structure": "single-data",
"status": "deleted",
},
Data: data.ToResponse(),
}, nil
}
func Fail(input e.FailDto) (*d.Data, error) {
rdDto := e.ReadDetailDto{Id: input.Id}
var data *e.ChemoPlan
var err error
event := pl.Event{
Feature: "Chemo-Fail",
Source: source,
}
// Start log
pl.SetLogInfo(&event, input, "started", "update")
if data, err = ReadDetailData(rdDto, &event); err != nil {
return nil, err
}
dataSoapi, err := getSoapiByEncounterId(*data.Encounter_Id, &event)
if err != nil {
return nil, err
}
if dataSoapi != nil && len(*dataSoapi) > 0 {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "soapi-exist",
Detail: "cancel soapi to proceed",
}
return nil, pl.SetLogError(&event, data)
}
if *data.Status != ere.SPCPlanned {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "invalid-chemo-status",
Detail: "only chemo plans with status 'planned' can be deleted.",
}
}
err = dg.I.Transaction(func(tx *gorm.DB) error {
if err := UpdateFailData(input, data, &event, tx); 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": "updated",
},
Data: data.ToResponse(),
}, nil
}
@@ -0,0 +1,90 @@
/*
DESCRIPTION:
Any functions that are used internally by the use-case
*/
package chemo_plan
import (
"encoding/json"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
"time"
dg "github.com/karincake/apem/db-gorm-pg"
ere "simrs-vx/internal/domain/references/encounter"
e "simrs-vx/internal/domain/main-entities/chemo-plan"
ep "simrs-vx/internal/domain/main-entities/chemo-protocol"
es "simrs-vx/internal/domain/main-entities/soapi"
)
var now = time.Now()
func setDataCreate(input *ep.CreateDto) (data []e.ChemoPlan) {
for _, c := range *input.ChemoPlans {
data = append(data, e.ChemoPlan{
Parent_Id: input.Chemo_Id,
Protocol_Id: input.Id,
SeriesNumber: c.SeriesNumber,
CycleNumber: c.CycleNumber,
PlanDate: c.PlanDate,
})
}
return
}
func setDataCreateSoapi(data *e.ChemoPlan) {
data.RealizationDate = &now
status := ere.SPCComplete
data.Status = &status
}
func setDataDeleteSoapi(data *e.ChemoPlan) {
status := ere.SPCPlanned
data.Status = &status
}
func setDatafail(input e.FailDto, data *e.ChemoPlan) {
data.RealizationDate = nil
status := ere.SPCSchedule
data.Status = &status
var reasons []e.FailReason
if data.Reasons != nil {
json.Unmarshal([]byte(*data.Reasons), &reasons)
}
reasons = append(reasons, e.FailReason{
FailReason: input.Reasons,
Date: &now,
Encounter_Id: data.Encounter_Id,
})
if b, err := json.Marshal(reasons); err == nil {
jsonStr := string(b)
data.Reasons = &jsonStr
}
}
func getSoapiByEncounterId(encounterId uint, event *pl.Event) (*[]es.Soapi, error) {
pl.SetLogInfo(event, encounterId, "started", "DBReadDetail")
var data []es.Soapi
var tx = dg.I
if err := tx.
Model(&es.Soapi{}).
Where(`"Encounter_Id" = ?`, encounterId).
Find(&data).Error; err != nil {
if processedErr := pu.HandleReadError(err, event, source, encounterId, data); processedErr != nil {
return nil, processedErr
}
}
pl.SetLogInfo(event, nil, "complete")
return &data, nil
}
@@ -0,0 +1,178 @@
package chemo_plan
import (
"errors"
plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
"gorm.io/gorm"
dg "github.com/karincake/apem/db-gorm-pg"
gh "github.com/karincake/getuk"
e "simrs-vx/internal/domain/main-entities/chemo-plan"
ep "simrs-vx/internal/domain/main-entities/chemo-protocol"
)
func CreateData(input *ep.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*[]e.ChemoPlan, error) {
pl.SetLogInfo(event, nil, "started", "DBCreate")
data := setDataCreate(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 nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
return &data, nil
}
func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.ChemoPlan, *e.MetaDto, error) {
pl.SetLogInfo(event, input, "started", "DBReadList")
data := []e.ChemoPlan{}
pagination := gh.Pagination{}
count := int64(0)
meta := e.MetaDto{}
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
} else {
tx = dg.I
}
tx = tx.
Model(&e.ChemoPlan{}).
Scopes(gh.Preload(input.Includes)).
Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Find(&data).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, &meta, nil
}
return nil, nil, plh.HandleListError(input, event, err)
}
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
pl.SetLogInfo(event, nil, "complete")
return data, &meta, nil
}
func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.ChemoPlan, error) {
pl.SetLogInfo(event, input, "started", "DBReadDetail")
data := e.ChemoPlan{}
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
} else {
tx = dg.I
}
if err := tx.
Scopes(gh.Preload(input.Includes)).
First(&data, input.Id).
Error; err != nil {
if processedErr := pu.HandleReadError(err, event, source, input.Id, data); processedErr != nil {
return nil, processedErr
}
}
pl.SetLogInfo(event, nil, "complete")
return &data, nil
}
func UpdateData(data *e.ChemoPlan, method string, event *pl.Event, dbx ...*gorm.DB) error {
pl.SetLogInfo(event, data, "started", "DBUpdate")
switch method {
case "c":
setDataCreateSoapi(data)
case "d":
setDataDeleteSoapi(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, data)
}
pl.SetLogInfo(event, nil, "complete")
return nil
}
func DeleteData(data *e.ChemoPlan, 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 UpdateFailData(input e.FailDto, data *e.ChemoPlan, event *pl.Event, dbx ...*gorm.DB) error {
pl.SetLogInfo(event, data, "started", "DBUpdate")
setDatafail(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, data)
}
pl.SetLogInfo(event, nil, "complete")
return nil
}
@@ -0,0 +1,103 @@
package chemo_plan
import (
e "simrs-vx/internal/domain/main-entities/chemo-plan"
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.ChemoPlan) 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.ChemoPlan) 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.ChemoPlan) 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.ChemoPlan) 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.ChemoPlan) 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
}
@@ -0,0 +1,9 @@
package chemo_plan
// example of middleware
// func init() {
// createPreMw = append(createPreMw,
// CreateMw{Name: "modif-input", Func: pm.ModifInput},
// CreateMw{Name: "check-data", Func: pm.CheckData},
// )
// }
@@ -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 chemo_plan
import (
"gorm.io/gorm"
e "simrs-vx/internal/domain/main-entities/chemo-plan"
)
type createMw struct {
Name string
Func func(input *e.CreateDto, data *e.ChemoPlan, tx *gorm.DB) error
}
type readListMw struct {
Name string
Func func(input *e.ReadListDto, data *e.ChemoPlan, tx *gorm.DB) error
}
type readDetailMw struct {
Name string
Func func(input *e.ReadDetailDto, data *e.ChemoPlan, 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
@@ -1,6 +1,7 @@
package chemo_protocol
import (
"errors"
"strconv"
dg "github.com/karincake/apem/db-gorm-pg"
@@ -11,13 +12,22 @@ import (
"gorm.io/gorm"
erc "simrs-vx/internal/domain/references/common"
ec "simrs-vx/internal/domain/main-entities/chemo"
e "simrs-vx/internal/domain/main-entities/chemo-protocol"
ee "simrs-vx/internal/domain/main-entities/encounter"
uc "simrs-vx/internal/use-case/main-use-case/chemo"
ucp "simrs-vx/internal/use-case/main-use-case/chemo-plan"
ue "simrs-vx/internal/use-case/main-use-case/encounter"
)
const source = "chemo-protocol"
func Create(input e.CreateDto) (*d.Data, error) {
data := e.ChemoProtocol{}
var err error
event := pl.Event{
Feature: "Create",
@@ -27,23 +37,43 @@ 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 {
mwRunner := newMiddlewareRunner(&event, tx)
mwRunner.setMwType(pu.MWTPre)
// Run pre-middleware
if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil {
return err
if input.Patient_Id == nil {
// get encounter
dataEncounter, err := ue.ReadDetailData(ee.ReadDetailDto{Id: *input.Encounter_Id}, &event)
if err != nil {
return nil, err
}
input.Patient_Id = dataEncounter.Patient_Id
input.Status_Code = erc.DVCNew
}
// get chemo
dataChemo, err := uc.ReadDetailData(ec.ReadDetailDto{Id: *input.Chemo_Id}, &event)
if err != nil {
return nil, err
}
if dataChemo.Status_Code != erc.DVCVerified {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-validation-fail",
Detail: "chemo must be verified",
}
return nil, pl.SetLogError(&event, input)
}
err = dg.I.Transaction(func(tx *gorm.DB) error {
// Insert Chemo-Protocol
if resData, err := CreateData(input, &event, tx); err != nil {
return err
} else {
data = *resData
}
mwRunner.setMwType(pu.MWTPost)
// Run post-middleware
if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil {
// Insert Chemo-Plans
input.Id = &data.Id
if data.ChemoPlans, err = ucp.CreateData(&input, &event, tx); err != nil {
return err
}
@@ -80,6 +110,15 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
// Start log
pl.SetLogInfo(&event, input, "started", "readList")
if input.Patient_Id == nil {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-validation-fail",
Detail: "patient-id is required",
}
return nil, pl.SetLogError(&event, input)
}
err = dg.I.Transaction(func(tx *gorm.DB) error {
mwRunner := newMiddlewareRunner(&event, tx)
mwRunner.setMwType(pu.MWTPre)
@@ -275,3 +314,65 @@ func Delete(input e.DeleteDto) (*d.Data, error) {
}, nil
}
func Verify(input e.VerifyDto) (*d.Data, error) {
rdDto := e.ReadDetailDto{Id: input.Id}
var data *e.ChemoProtocol
var err error
event := pl.Event{
Feature: "Verify",
Source: source,
}
// Start log
pl.SetLogInfo(&event, input, "started", "verify")
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.Status_Code != erc.DVCNew {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-state-mismatch",
Detail: "data is not new",
Raw: errors.New("data is not new"),
}
return pl.SetLogError(&event, input)
}
data.VerifiedAt = pu.GetTimeNow()
data.Status_Code = erc.DVCVerified
data.VerifiedBy_User_Id = &input.AuthInfo.User_Id
err = tx.Save(&data).Error
if 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
})
if err != nil {
}
return &d.Data{
Meta: d.IS{
"source": source,
"structure": "single-data",
"status": "verify",
},
Data: data.ToResponse(),
}, nil
}
@@ -17,9 +17,15 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.ChemoProtocol) {
inputSrc = &inputTemp.CreateDto
}
data.Chemo_Id = inputSrc.Chemo_Id
data.Patient_Weight = inputSrc.Patient_Weight
data.Patient_Height = inputSrc.Patient_Height
data.Diagnoses = inputSrc.Diagnoses
data.Interval = inputSrc.Interval
data.Cycle = inputSrc.Cycle
data.Series = inputSrc.Series
data.StartDate = inputSrc.StartDate
data.EndDate = inputSrc.EndDate
data.Status_Code = inputSrc.Status_Code
data.Patient_Id = inputSrc.Patient_Id
}
@@ -2,7 +2,6 @@ package chemo_protocol
import (
"errors"
plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
+26 -27
View File
@@ -4,10 +4,6 @@ import (
"errors"
"strconv"
e "simrs-vx/internal/domain/main-entities/chemo"
erc "simrs-vx/internal/domain/references/common"
dg "github.com/karincake/apem/db-gorm-pg"
d "github.com/karincake/dodol"
@@ -15,9 +11,13 @@ import (
pu "simrs-vx/pkg/use-case-helper"
"gorm.io/gorm"
erc "simrs-vx/internal/domain/references/common"
e "simrs-vx/internal/domain/main-entities/chemo"
)
const source = "division"
const source = "chemo"
func Create(input e.CreateDto) (*d.Data, error) {
data := e.Chemo{}
@@ -70,7 +70,6 @@ func Create(input e.CreateDto) (*d.Data, error) {
}
func ReadList(input e.ReadListDto) (*d.Data, error) {
var data *e.Chemo
var dataList []e.Chemo
var metaList *e.MetaDto
var err error
@@ -83,28 +82,17 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
// Start log
pl.SetLogInfo(&event, input, "started", "readList")
err = dg.I.Transaction(func(tx *gorm.DB) error {
mwRunner := newMiddlewareRunner(&event, tx)
mwRunner.setMwType(pu.MWTPre)
// Run pre-middleware
if err := mwRunner.RunReadListMiddleware(readListPreMw, &input, data); err != nil {
return err
if input.Patient_Id == nil {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-validation-fail",
Detail: "patient-id is required",
}
return nil, pl.SetLogError(&event, input)
}
if dataList, metaList, err = ReadListData(input, &event, tx); err != nil {
return err
}
mwRunner.setMwType(pu.MWTPost)
// Run post-middleware
if err := mwRunner.RunReadListMiddleware(readListPostMw, &input, data); err != nil {
return err
}
return nil
})
if err != nil {
input.Encounter_Id = nil
if dataList, metaList, err = ReadListData(input, &event); err != nil {
return nil, err
}
@@ -134,6 +122,15 @@ func ReadDetail(input e.ReadDetailDto) (*d.Data, error) {
// Start log
pl.SetLogInfo(&event, input, "started", "readDetail")
if input.Encounter_Id == nil {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-validation-fail",
Detail: "Encounter-Id is required",
}
return nil, pl.SetLogError(&event, input)
}
err = dg.I.Transaction(func(tx *gorm.DB) error {
mwRunner := newMiddlewareRunner(&event, tx)
mwRunner.setMwType(pu.MWTPre)
@@ -309,10 +306,12 @@ func Verify(input e.VerifyDto) (*d.Data, error) {
}
data.VerifiedAt = pu.GetTimeNow()
data.Status_Code = input.Status_Code
data.Status_Code = erc.DVCVerified
data.VerifiedBy_User_Id = &input.AuthInfo.User_Id
data.Bed = input.Bed
data.Needs = input.Needs
data.Doctor_Code = input.Doctor_Code
data.NextChemoDate = input.NextChemoDate
err = tx.Save(&data).Error
if err != nil {
@@ -20,4 +20,5 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Chemo) {
data.Encounter_Id = inputSrc.Encounter_Id
data.Status_Code = inputSrc.Status_Code
data.Specialist_Code = inputSrc.Specialist_Code
data.Class_Code = inputSrc.Class_Code
}
+12 -1
View File
@@ -47,8 +47,16 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Ch
tx = dg.I
}
if input.Class_Code != "" {
tx = tx.Where(`"Chemo"."Class_Code" = ?`, input.Class_Code)
input.Class_Code = ""
}
tx = tx.
Model(&e.Chemo{}).
Joins(`LEFT JOIN "Encounter" "e" ON "e"."Id" = "Chemo"."Encounter_Id"`).
Joins(`LEFT JOIN "Patient" "p" ON "e"."Patient_Id" = "p"."Id"`).
Where(`"p"."Id" = ?`, input.Patient_Id).
Scopes(gh.Preload(input.Includes)).
Scopes(gh.Filter(input.FilterDto)).
Count(&count).
@@ -81,7 +89,10 @@ func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e
tx = dg.I
}
if err := tx.First(&data, input.Id).Error; err != nil {
if err := tx.
Scopes(gh.Preload(input.Includes)).
Scopes(gh.Filter(input.FilterDto)).
First(&data, input.Id).Error; err != nil {
if processedErr := pu.HandleReadError(err, event, source, input.Id, data); processedErr != nil {
return nil, processedErr
}
@@ -7,7 +7,6 @@ package encounter
import (
"errors"
"fmt"
un "simrs-vx/internal/use-case/main-use-case/nurse"
"strings"
"time"
@@ -24,9 +23,10 @@ import (
ere "simrs-vx/internal/domain/references/encounter"
erg "simrs-vx/internal/domain/references/organization"
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"
ecpl "simrs-vx/internal/domain/main-entities/chemo-plan"
ecp "simrs-vx/internal/domain/main-entities/chemo-protocol"
edo "simrs-vx/internal/domain/main-entities/device-order"
ed "simrs-vx/internal/domain/main-entities/doctor"
ee "simrs-vx/internal/domain/main-entities/emergency"
@@ -42,12 +42,9 @@ import (
ep "simrs-vx/internal/domain/main-entities/prescription"
epi "simrs-vx/internal/domain/main-entities/prescription-item"
er "simrs-vx/internal/domain/main-entities/rehab"
erdh "simrs-vx/internal/domain/main-entities/responsible-doctor-hist"
es "simrs-vx/internal/domain/main-entities/soapi"
esp "simrs-vx/internal/domain/main-entities/specialist"
// udo "simrs-vx/internal/use-case/main-use-case/device-order"
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"
ud "simrs-vx/internal/use-case/main-use-case/doctor"
@@ -58,10 +55,10 @@ import (
umi "simrs-vx/internal/use-case/main-use-case/medicine-mix"
ummi "simrs-vx/internal/use-case/main-use-case/medicine-mix-item"
_ "simrs-vx/internal/use-case/main-use-case/nurse"
un "simrs-vx/internal/use-case/main-use-case/nurse"
up "simrs-vx/internal/use-case/main-use-case/prescription"
upi "simrs-vx/internal/use-case/main-use-case/prescription-item"
ur "simrs-vx/internal/use-case/main-use-case/rehab"
urdh "simrs-vx/internal/use-case/main-use-case/responsible-doctor-hist"
us "simrs-vx/internal/use-case/main-use-case/soapi"
)
@@ -396,192 +393,6 @@ func getMcuOrders(encounter_id uint, event *pl.Event, tx *gorm.DB) error {
return nil
}
func upsertResponsibleDoctorHist(input erdh.CreateDto, event *pl.Event, dbx ...*gorm.DB) error {
pl.SetLogInfo(event, nil, "started", "DBCreate")
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
} else {
tx = dg.I
}
var latest erdh.ResponsibleDoctorHist
err := tx.
Where("\"Encounter_Id\" = ?", input.Encounter_Id).
Order("\"CreatedAt\" DESC").
Limit(1).
First(&latest).Error
switch {
case errors.Is(err, gorm.ErrRecordNotFound):
// Insert
if _, err = urdh.CreateData(input, event, tx); err != nil {
return err
}
case err != nil:
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "read-fail",
Detail: "Failed to read responsible doctor history",
Raw: err,
}
return pl.SetLogError(event, input)
default:
// Update
if err := tx.Model(&latest).Updates(map[string]interface{}{
"Doctor_Code": input.Doctor_Code,
"StartedAt": input.StartedAt,
"UpdatedAt": time.Now(),
}).Error; err != nil {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "update-fail",
Detail: "Failed to update responsible doctor history",
Raw: err,
}
return pl.SetLogError(event, input)
}
}
pl.SetLogInfo(event, input, "complete")
return nil
}
func upsertAdmEmployeeHist(input eaeh.CreateDto, event *pl.Event, dbx ...*gorm.DB) error {
pl.SetLogInfo(event, nil, "started", "DBCreate")
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
} else {
tx = dg.I
}
var latest eaeh.AdmEmployeeHist
err := tx.
Where("\"Encounter_Id\" = ?", input.Encounter_Id).
Order("\"CreatedAt\" DESC").
Limit(1).
First(&latest).Error
switch {
case errors.Is(err, gorm.ErrRecordNotFound):
// Insert
if _, err = uaeh.CreateData(input, event, tx); err != nil {
return err
}
case err != nil:
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "read-fail",
Detail: "Failed to read responsible doctor history",
Raw: err,
}
return pl.SetLogError(event, input)
default:
// Update
if err := tx.Model(&latest).Updates(map[string]interface{}{
"Employee_Id": input.Employee_Id,
"StartedAt": input.StartedAt,
"UpdatedAt": time.Now(),
}).Error; err != nil {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "update-fail",
Detail: "Failed to update responsible doctor history",
Raw: err,
}
return pl.SetLogError(event, input)
}
}
pl.SetLogInfo(event, input, "complete")
return nil
}
func updateLatestResponsibleDoctorHist(input e.CheckinDto, event *pl.Event, dbx ...*gorm.DB) error {
pl.SetLogInfo(event, "started", "DBUpdate")
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
} else {
tx = dg.I
}
subQuery := tx.
Select("\"Id\"").
Model(&erdh.ResponsibleDoctorHist{}).
Where("\"Encounter_Id\" = ?", input.Id).
Order("\"CreatedAt\" DESC").
Limit(1)
result := tx.
Model(&erdh.ResponsibleDoctorHist{}).
Where("\"Id\" = (?)", subQuery).
Update("\"FinishedAt\"", input.FinishedAt)
if result.Error != nil {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-update-fail",
Detail: "Database update failed",
Raw: result.Error,
}
return pl.SetLogError(event, input)
}
if result.RowsAffected == 0 {
pl.SetLogInfo(event, input, "no previous data found to update")
return nil
}
pl.SetLogInfo(event, nil, "complete")
return nil
}
func updateLatestAdmEmployeeHist(input e.CheckinDto, event *pl.Event, dbx ...*gorm.DB) error {
pl.SetLogInfo(event, "started", "DBUpdate")
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
} else {
tx = dg.I
}
subQuery := tx.
Select("\"Id\"").
Model(&eaeh.AdmEmployeeHist{}).
Where("\"Encounter_Id\" = ?", input.Id).
Order("\"CreatedAt\" DESC").
Limit(1)
result := tx.
Model(&eaeh.AdmEmployeeHist{}).
Where("\"Id\" = (?)", subQuery).
Update("\"FinishedAt\"", input.FinishedAt)
if result.Error != nil {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-update-fail",
Detail: "Database update failed",
Raw: result.Error,
}
return pl.SetLogError(event, input)
}
if result.RowsAffected == 0 {
pl.SetLogInfo(event, input, "no previous data found to update")
return nil
}
pl.SetLogInfo(event, nil, "complete")
return nil
}
func getSoapiByResponsibleDoctor(enc e.Encounter, event *pl.Event) (data []es.Soapi, err error) {
pl.SetLogInfo(event, enc, "started", "DBReadList")
@@ -849,13 +660,31 @@ func insertdataClassCode(input e.CreateDto, soapiData []es.CreateDto, event *pl.
func insertDataSubClassAmbulatory(input e.CreateDto, soapiData []es.CreateDto, event *pl.Event, tx *gorm.DB) (err error) {
subCode := ere.AmbulatoryClassCode(*input.SubClass_Code)
var chemoPlan *ecpl.ChemoPlan
switch {
case subCode == ere.ACCChemo:
// validate if encounter Chemo valid
chemoPlan, err = validateChemo(*input.Patient_Id, event)
if err != nil {
return err
}
if chemoPlan == nil {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-not-found",
Detail: "chemo plan not found",
}
return pl.SetLogError(event, input)
}
chemoCreate := ec.CreateDto{
Encounter_Id: &input.Id,
Status_Code: erc.DVCNew,
Status_Code: erc.DVCVerified,
Specialist_Code: input.Specialist_Code,
Class_Code: ere.CCCAct,
}
// create data chemo
@@ -864,6 +693,13 @@ func insertDataSubClassAmbulatory(input e.CreateDto, soapiData []es.CreateDto, e
return err
}
// set chemo-plan to planned
chemoPlan.Encounter_Id = &input.Id
err = updateChemoPlan(chemoPlan, event, tx)
if err != nil {
return err
}
case subCode == ere.ACCRehab:
rehabData := er.CreateDto{
Encounter_Id: &input.Id,
@@ -1009,18 +845,18 @@ func getDoctors(doctorIds []string, event *pl.Event) ([]ed.Doctor, error) {
return doctors, nil
}
func validateSpecialistCodes(unitCodes map[string]struct{}, event *pl.Event) error {
if len(unitCodes) > 0 {
func validateSpecialistCodes(speCodes map[string]struct{}, event *pl.Event) error {
if len(speCodes) > 0 {
var codes []string
for code := range unitCodes {
for code := range speCodes {
codes = append(codes, code)
}
units, err := getSpecialists(codes, event)
specialists, err := getSpecialists(codes, event)
if err != nil {
return fmt.Errorf("failed to fetch units: %w", err)
}
if len(units) != len(codes) {
if len(specialists) != len(codes) {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-validation-fail",
@@ -1056,3 +892,127 @@ func validateDoctorCodes(doctorCodes map[string]struct{}, event *pl.Event) error
return nil
}
func updateChemoPlan(data *ecpl.ChemoPlan, event *pl.Event, dbx ...*gorm.DB) error {
pl.SetLogInfo(event, nil, "started", "getChemoFromEncounter")
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
} else {
tx = dg.I
}
err := tx.Model(&data).Updates(map[string]interface{}{
`"Status"`: ere.SPCPlanned,
`"Encounter_Id"`: data.Encounter_Id}).Error
if err != nil {
return err
}
pl.SetLogInfo(event, nil, "complete")
return nil
}
func getChemoProtocol(patientId uint, event *pl.Event) (*ecp.ChemoProtocol, error) {
pl.SetLogInfo(event, nil, "started", "getChemoProtocol")
data := ecp.ChemoProtocol{}
var tx = dg.I
tx = tx.Model(&ecp.ChemoProtocol{}).
Joins(`LEFT JOIN "ChemoPlan" cp ON cp."Protocol_Id" = "ChemoProtocol"."Id"`).
Where(`"ChemoProtocol"."Patient_Id" = ?`, patientId).
Preload("ChemoPlans", func(db *gorm.DB) *gorm.DB {
return db.
Where(`"Status" IS NULL OR "Status" = ?`, ere.SPCSchedule).
Order(`"Id" ASC`).
Limit(1)
}).
Order(`"CreatedAt" DESC`).
First(&data)
if err := tx.Error; err != nil {
return nil, err
}
pl.SetLogInfo(event, nil, "complete")
return &data, nil
}
func validateChemo(patientId uint, event *pl.Event) (*ecpl.ChemoPlan, error) {
// get chemo adm
chemoAdm, err := getChemoAdm(patientId, event)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-not-found",
Detail: "patient doesn't have active chemo",
}
return nil, pl.SetLogError(event, patientId)
}
return nil, err
}
// validate is chemo verified
if chemoAdm.Status_Code != erc.DVCVerified {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-not-match",
Detail: fmt.Sprintf("chemo not yet verified"),
}
return nil, pl.SetLogError(event, chemoAdm)
}
// get chemo protocol
chemoProtocol, err := getChemoProtocol(patientId, event)
if err != nil {
return nil, err
}
if chemoProtocol.Status_Code != erc.DVCVerified {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-not-match",
Detail: fmt.Sprintf("protocol chemo not yet verified"),
}
return nil, pl.SetLogError(event, chemoProtocol)
}
if now.Before(*chemoProtocol.StartDate) || now.After(*chemoProtocol.EndDate) {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "invalid-date-range",
Detail: "chemo cannot be performed because the current date is outside the allowed treatment window.",
}
return nil, pl.SetLogError(event, chemoProtocol)
}
if chemoProtocol.ChemoPlans == nil || len(*chemoProtocol.ChemoPlans) == 0 {
return nil, nil
}
// Return the first chemo plan
return &(*chemoProtocol.ChemoPlans)[0], nil
}
func getChemoAdm(patientId uint, event *pl.Event) (*ec.Chemo, error) {
pl.SetLogInfo(event, nil, "started", "getChemoProtocol")
data := ec.Chemo{}
var tx = dg.I
tx = tx.Model(&ec.Chemo{}).
Joins(`LEFT JOIN "Encounter" e ON e."Id" = "Chemo"."Encounter_Id"`).
Where(`e."Patient_Id" = ? AND "Chemo"."Class_Code" = ?`, patientId, ere.CCCAdm).
Order(`"CreatedAt" DESC`).
First(&data)
if err := tx.Error; err != nil {
return nil, err
}
pl.SetLogInfo(event, nil, "complete")
return &data, nil
}
@@ -59,10 +59,11 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.En
} else {
tx = dg.I
}
tx = tx.Model(&e.Encounter{})
if input.AuthInfo.Doctor_Code != nil {
tx.Where("\"Responsible_Doctor_Code\" = ?", *input.AuthInfo.Doctor_Code) //
tx = tx.Where("\"Responsible_Doctor_Code\" = ?", *input.AuthInfo.Doctor_Code) //
}
if input.StartDate != nil && input.EndDate != nil {
@@ -75,7 +76,8 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.En
if input.Patient_Identifier != nil {
tx = tx.Joins("JOIN \"Patient\" ON \"Patient\".\"Id\" = \"Encounter\".\"Patient_Id\"").
Joins("JOIN \"Person\" ON \"Person\".\"Id\" = \"Patient\".\"Person_Id\"").Where("\"Person\".\"Name\" ILIKE ? OR \"Patient\".\"Number\" = ?", "%"+*input.Patient_Identifier+"%", *input.Patient_Identifier)
Joins("JOIN \"Person\" ON \"Person\".\"Id\" = \"Patient\".\"Person_Id\"").
Where("\"Person\".\"Name\" ILIKE ? OR \"Patient\".\"Number\" = ?", "%"+*input.Patient_Identifier+"%", *input.Patient_Identifier)
}
// TODO: getuk lib need to be updated to support this
@@ -83,20 +85,23 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.En
tx = tx.Where("\"Encounter\".\"Status_Code\" = ?", *input.Status_Code)
}
// if input.Specialist_Code != nil {
// tx = tx.Where("\"Encounter\".\"Specialist_Code\" = ?", *input.Specialist_Code)
// }
if input.Specialist_Code != nil {
tx = tx.Where("\"Encounter\".\"Specialist_Code\" = ?", *input.Specialist_Code)
}
if input.PaymentMethod_Code != nil {
tx = tx.Where("\"Encounter\".\"PaymentMethod_Code\" = ?", *input.PaymentMethod_Code)
}
tx = tx.Debug().
Scopes(gh.Filter(input.FilterDto)).
Scopes(gh.Preload(input.Includes)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if input.ChemoClass != nil {
tx = tx.Joins(`RIGHT JOIN "Chemo" "c" ON "c"."Encounter_Id" = "Encounter"."Id"`).
Where(`"c"."Class_Code" = ?`, *input.ChemoClass)
}
// count
if err := tx.Count(&count).Error; err != nil {
return nil, nil, plh.HandleListError(input, event, err)
}
// tx.Debug().Scopes(gh.Preload(input.Includes)).
// Scopes(gh.Filter(input.FilterDto)).
@@ -104,7 +109,11 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.En
// Scopes(gh.Paginate(input, &pagination)).
// Order("\"CreatedAt\" DESC")
if err := tx.Find(&data).Error; err != nil {
if err := tx.
Scopes(gh.Preload(input.Includes)).
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC").
Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
@@ -47,7 +47,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Pr
tx = dg.I
}
tx = tx.Debug().
tx = tx.
Model(&e.PrescriptionItem{}).
Scopes(gh.Preload(input.Includes)).
Scopes(gh.Filter(input.FilterDto)).
+35 -9
View File
@@ -2,19 +2,20 @@ package soapi
import (
"errors"
erc "simrs-vx/internal/domain/references/common"
esync "simrs-vx/internal/domain/sync-entities/log"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
"strconv"
e "simrs-vx/internal/domain/main-entities/soapi"
dg "github.com/karincake/apem/db-gorm-pg"
d "github.com/karincake/dodol"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
"gorm.io/gorm"
erc "simrs-vx/internal/domain/references/common"
e "simrs-vx/internal/domain/main-entities/soapi"
esync "simrs-vx/internal/domain/sync-entities/log"
ucp "simrs-vx/internal/use-case/main-use-case/chemo-plan"
)
const source = "soapi"
@@ -41,13 +42,26 @@ func Create(input e.CreateDto) (*d.Data, error) {
return nil, pl.SetLogError(&event, input)
}
err := dg.I.Transaction(func(tx *gorm.DB) error {
chemoPlan, err := validateIfEncounterIsChemo(*input.Encounter_Id, "c", &event)
if err != nil {
return nil, err
}
err = dg.I.Transaction(func(tx *gorm.DB) error {
if resData, err := CreateData(input, &event, tx); err != nil {
return err
} else {
data = *resData
}
// update chemoPlan
if chemoPlan != nil {
chemoPlan.Encounter_Id = input.Encounter_Id
if err = ucp.UpdateData(chemoPlan, "c", &event, tx); err != nil {
return err
}
}
// get detail for sync
soapiData, err := ReadDetailData(e.ReadDetailDto{
Id: data.Id,
@@ -238,6 +252,18 @@ func Delete(input e.DeleteDto) (*d.Data, error) {
return err
}
// update chemoPlan
chemoPlan, err := validateIfEncounterIsChemo(*data.Encounter_Id, "d", &event)
if err != nil {
return err
}
if chemoPlan != nil {
if err = ucp.UpdateData(chemoPlan, "d", &event, tx); err != nil {
return err
}
}
mwRunner.setMwType(pu.MWTPre)
// Run pre-middleware
if err = mwRunner.ExecuteIfSyncOn(func() error {
@@ -5,6 +5,17 @@ Any functions that are used internally by the use-case
package soapi
import (
"errors"
pl "simrs-vx/pkg/logger"
dg "github.com/karincake/apem/db-gorm-pg"
"gorm.io/gorm"
ere "simrs-vx/internal/domain/references/encounter"
ecpl "simrs-vx/internal/domain/main-entities/chemo-plan"
ecp "simrs-vx/internal/domain/main-entities/chemo-protocol"
ee "simrs-vx/internal/domain/main-entities/encounter"
e "simrs-vx/internal/domain/main-entities/soapi"
)
@@ -39,3 +50,77 @@ func setBulkData(input []e.CreateDto, encounterId uint) []e.Soapi {
return data
}
func validateIfEncounterIsChemo(encounterId uint, method string, event *pl.Event) (*ecpl.ChemoPlan, error) {
// get encounter
enc, err := getEncounter(encounterId, event)
if err != nil {
return nil, err
}
// Encounter must be Ambulatory and NOT Rehab
a := enc.Ambulatory
if a == nil || a.Class_Code == ere.ACCRehab {
return nil, nil
}
// get chemo protocol
chemo, err := getChemo(*enc.Patient_Id, enc.Id, event)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, pl.SetLogError(event, nil)
}
if chemo.ChemoPlans == nil || len(*chemo.ChemoPlans) == 0 {
return nil, nil
}
// Return the first chemo plan
return &(*chemo.ChemoPlans)[0], nil
}
func getEncounter(encounterId uint, event *pl.Event) (*ee.Encounter, error) {
pl.SetLogInfo(event, nil, "started", "getEncounter")
data := ee.Encounter{}
var tx = dg.I
err := tx.Model(&ee.Encounter{}).
Joins(`LEFT JOIN "Ambulatory" a ON a."Encounter_Id" = "Encounter"."Id"`).
Where(`"Encounter"."Id" = ?`, encounterId).
Where(`"Encounter"."Class_Code" = ?`, ere.ECAmbulatory).
Preload("Ambulatory").
First(&data).Error
if err != nil {
return nil, err
}
pl.SetLogInfo(event, nil, "complete")
return &data, nil
}
func getChemo(patientId, encounterId uint, event *pl.Event) (*ecp.ChemoProtocol, error) {
pl.SetLogInfo(event, nil, "started", "getChemo")
data := ecp.ChemoProtocol{}
var tx = dg.I
tx = tx.Model(&ecp.ChemoProtocol{}).
Joins(`LEFT JOIN "ChemoPlan" cp ON cp."Protocol_Id" = "ChemoProtocol"."Id"`).
Where(`"ChemoProtocol"."Patient_Id" = ?`, patientId).
Preload("ChemoPlans", func(db *gorm.DB) *gorm.DB {
return db.
Where(`"Encounter_Id" = ?`, encounterId)
}).
First(&data)
if err := tx.Error; err != nil {
return nil, err
}
pl.SetLogInfo(event, nil, "complete")
return &data, nil
}
@@ -31,7 +31,7 @@ func CreateSimgosData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*esi
tx = dg.IS["simrs"]
}
if err := tx.Debug().Create(&data).Error; err != nil {
if err := tx.Create(&data).Error; err != nil {
return nil, plh.HandleCreateError(input, event, err)
}