diff --git a/internal/domain/main-entities/mcu-order-sub-item/entity.go b/internal/domain/main-entities/mcu-order-sub-item/entity.go index c3f77361..83ae4d53 100644 --- a/internal/domain/main-entities/mcu-order-sub-item/entity.go +++ b/internal/domain/main-entities/mcu-order-sub-item/entity.go @@ -17,3 +17,7 @@ type McuOrderSubItem struct { Result *string `json:"result"` Status_Code erc.DataStatusCode `json:"status_code"` } + +func (d McuOrderSubItem) IsCompleted() bool { + return d.Status_Code == erc.DSCDone +} diff --git a/internal/interface/main-handler/main-handler.go b/internal/interface/main-handler/main-handler.go index b57ad997..121a2c8d 100644 --- a/internal/interface/main-handler/main-handler.go +++ b/internal/interface/main-handler/main-handler.go @@ -120,7 +120,6 @@ func SetRoutes() http.Handler { hc.RegCrud(r, "/v1/prescription-item", prescriptionitem.O) hc.RegCrud(r, "/v1/device-order-item", deviceorderitem.O) hc.RegCrud(r, "/v1/material-order-item", materialorderitem.O) - hc.RegCrud(r, "/v1/mcu-order-sub-item", mcuordersubitem.O) hk.GroupRoutes("/v1/mcu-order", r, hk.MapHandlerFunc{ "GET /": mcuorder.O.GetList, "GET /{id}": mcuorder.O.GetDetail, @@ -136,8 +135,17 @@ func SetRoutes() http.Handler { "POST /": mcuorderitem.O.Create, "PATCH /{id}": mcuorderitem.O.Update, "DELETE /{id}": mcuorderitem.O.Delete, + "PATCH /{id}/complete": mcuorderitem.O.Complete, "PATCH /{id}/set-schedule": mcuorderitem.O.SetSchedule, }) + hk.GroupRoutes("/v1/mcu-order-sub-item", r, hk.MapHandlerFunc{ + "GET /": mcuordersubitem.O.GetList, + "GET /{id}": mcuordersubitem.O.GetDetail, + "POST /": mcuordersubitem.O.Create, + "PATCH /{id}": mcuordersubitem.O.Update, + "DELETE /{id}": mcuordersubitem.O.Delete, + "PATCH /{id}/complete": mcuordersubitem.O.Complete, + }) hk.GroupRoutes("/v1/encounter", r, hk.MapHandlerFunc{ "GET /": encounter.O.GetList, "GET /{id}": encounter.O.GetDetail, diff --git a/internal/interface/main-handler/mcu-order-item/handler.go b/internal/interface/main-handler/mcu-order-item/handler.go index f407a044..75f5ad6a 100644 --- a/internal/interface/main-handler/mcu-order-item/handler.go +++ b/internal/interface/main-handler/mcu-order-item/handler.go @@ -70,6 +70,18 @@ func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) { rw.DataResponse(w, res, err) } +func (obj myBase) Complete(w http.ResponseWriter, r *http.Request) { + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id <= 0 { + return + } + + dto := e.ReadDetailDto{} + dto.Id = uint(id) + res, err := u.Complete(dto) + rw.DataResponse(w, res, err) +} + func (obj myBase) SetSchedule(w http.ResponseWriter, r *http.Request) { id := rw.ValidateInt(w, "id", r.PathValue("id")) if id <= 0 { diff --git a/internal/interface/main-handler/mcu-order-sub-item/handler.go b/internal/interface/main-handler/mcu-order-sub-item/handler.go index e36426e0..8e8f8c79 100644 --- a/internal/interface/main-handler/mcu-order-sub-item/handler.go +++ b/internal/interface/main-handler/mcu-order-sub-item/handler.go @@ -69,3 +69,15 @@ func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) { res, err := u.Delete(dto) rw.DataResponse(w, res, err) } + +func (obj myBase) Complete(w http.ResponseWriter, r *http.Request) { + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id <= 0 { + return + } + + dto := e.ReadDetailDto{} + dto.Id = uint(id) + res, err := u.Complete(dto) + rw.DataResponse(w, res, err) +} diff --git a/internal/use-case/main-use-case/device-order/case.go b/internal/use-case/main-use-case/device-order/case.go index 96c510c0..66dc1949 100644 --- a/internal/use-case/main-use-case/device-order/case.go +++ b/internal/use-case/main-use-case/device-order/case.go @@ -6,6 +6,8 @@ import ( e "simrs-vx/internal/domain/main-entities/device-order" + ue "simrs-vx/internal/use-case/main-use-case/encounter" + erc "simrs-vx/internal/domain/references/common" dg "github.com/karincake/apem/db-gorm-pg" @@ -38,6 +40,11 @@ func Create(input e.CreateDto) (*d.Data, error) { return err } + // check if encounter is done + if ue.IsDone(*input.Encounter_Id, &event, tx) { + return errors.New("encounter is already done") + } + if resData, err := CreateData(input, &event, tx); err != nil { return err } else { diff --git a/internal/use-case/main-use-case/encounter/case.go b/internal/use-case/main-use-case/encounter/case.go index 437e6b55..c63579cf 100644 --- a/internal/use-case/main-use-case/encounter/case.go +++ b/internal/use-case/main-use-case/encounter/case.go @@ -380,7 +380,9 @@ func CheckOut(input e.DischargeDto) (*d.Data, error) { } if err := createMedication(data.Id, &event, tx); err != nil { - return err + if !pu.IsDataNotFoundError(err) { + return err + } } pl.SetLogInfo(&event, nil, "complete") diff --git a/internal/use-case/main-use-case/encounter/lib.go b/internal/use-case/main-use-case/encounter/lib.go index a0aaa94b..8653cdbf 100644 --- a/internal/use-case/main-use-case/encounter/lib.go +++ b/internal/use-case/main-use-case/encounter/lib.go @@ -178,3 +178,27 @@ func UpdateDischargeData(input e.DischargeDto, data *e.Encounter, event *pl.Even pl.SetLogInfo(event, nil, "complete") return nil } + +func IsDone(encounter_id uint, event *pl.Event, dbx ...*gorm.DB) bool { + pl.SetLogInfo(event, nil, "started", "DBIsDone") + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + var data e.Encounter + if err := tx.Where("\"Id\" = ?", encounter_id).First(&data).Error; err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-get-fail", + Detail: "Database get failed", + Raw: err, + } + return false + } + + pl.SetLogInfo(event, nil, "complete") + return data.IsDone() +} diff --git a/internal/use-case/main-use-case/material-order-item/case.go b/internal/use-case/main-use-case/material-order-item/case.go index 497c3b02..32d7875d 100644 --- a/internal/use-case/main-use-case/material-order-item/case.go +++ b/internal/use-case/main-use-case/material-order-item/case.go @@ -1,10 +1,13 @@ package materialorderitem import ( + "errors" "strconv" e "simrs-vx/internal/domain/main-entities/material-order-item" + umo "simrs-vx/internal/use-case/main-use-case/material-order" + dg "github.com/karincake/apem/db-gorm-pg" d "github.com/karincake/dodol" @@ -35,6 +38,11 @@ func Create(input e.CreateDto) (*d.Data, error) { return err } + // check if materialOrder is done + if umo.IsCompleted(*input.MaterialOrder_Id, &event, tx) { + return errors.New("materialOrder is already done") + } + if resData, err := CreateData(input, &event, tx); err != nil { return err } else { diff --git a/internal/use-case/main-use-case/material-order/case.go b/internal/use-case/main-use-case/material-order/case.go index 28f41704..bed63695 100644 --- a/internal/use-case/main-use-case/material-order/case.go +++ b/internal/use-case/main-use-case/material-order/case.go @@ -6,6 +6,8 @@ import ( e "simrs-vx/internal/domain/main-entities/material-order" + ue "simrs-vx/internal/use-case/main-use-case/encounter" + erc "simrs-vx/internal/domain/references/common" dg "github.com/karincake/apem/db-gorm-pg" @@ -38,6 +40,11 @@ func Create(input e.CreateDto) (*d.Data, error) { return err } + // check if encounter is done + if ue.IsDone(*input.Encounter_Id, &event, tx) { + return errors.New("encounter is already done") + } + if resData, err := CreateData(input, &event, tx); err != nil { return err } else { diff --git a/internal/use-case/main-use-case/material-order/lib.go b/internal/use-case/main-use-case/material-order/lib.go index 27b91ce1..135aaf54 100644 --- a/internal/use-case/main-use-case/material-order/lib.go +++ b/internal/use-case/main-use-case/material-order/lib.go @@ -153,3 +153,27 @@ func DeleteData(data *e.MaterialOrder, event *pl.Event, dbx ...*gorm.DB) error { pl.SetLogInfo(event, nil, "complete") return nil } + +func IsCompleted(materialOrder_id uint, event *pl.Event, dbx ...*gorm.DB) bool { + pl.SetLogInfo(event, nil, "started", "DBIsCompleted") + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + var data e.MaterialOrder + if err := tx.Where("\"Id\" = ?", materialOrder_id).First(&data).Error; err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-get-fail", + Detail: "Database get failed", + Raw: err, + } + return false + } + + pl.SetLogInfo(event, nil, "complete") + return data.IsCompleted() +} diff --git a/internal/use-case/main-use-case/mcu-order-item/case.go b/internal/use-case/main-use-case/mcu-order-item/case.go index 899b8120..2b1cacd1 100644 --- a/internal/use-case/main-use-case/mcu-order-item/case.go +++ b/internal/use-case/main-use-case/mcu-order-item/case.go @@ -6,6 +6,10 @@ import ( e "simrs-vx/internal/domain/main-entities/mcu-order-item" + umo "simrs-vx/internal/use-case/main-use-case/mcu-order" + + erc "simrs-vx/internal/domain/references/common" + dg "github.com/karincake/apem/db-gorm-pg" d "github.com/karincake/dodol" @@ -36,6 +40,11 @@ func Create(input e.CreateDto) (*d.Data, error) { return err } + // check if mcuOrder is done + if umo.IsCompleted(*input.McuOrder_Id, &event, tx) { + return errors.New("mcuOrder is already done") + } + if resData, err := CreateData(input, &event, tx); err != nil { return err } else { @@ -279,6 +288,63 @@ func Delete(input e.DeleteDto) (*d.Data, error) { } +func Complete(input e.ReadDetailDto) (*d.Data, error) { + var data *e.McuOrderItem + var err error + + event := pl.Event{ + Feature: "Complete", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "complete") + + err = dg.I.Transaction(func(tx *gorm.DB) error { + data, err = ReadDetailData(input, &event, tx) + if err != nil { + return err + } + + if data.IsCompleted() { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-state-mismatch", + Detail: "mcuOrderItem is already completed", + Raw: errors.New("mcuOrderItem is already completed"), + } + return pl.SetLogError(&event, input) + } + + data.Status_Code = erc.DSCDone + 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 + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "single-data", + "status": "fetched", + }, + Data: data.ToResponse(), + }, nil +} + func SetSchedule(input e.SetScheduleDto) (*d.Data, error) { rdDto := e.ReadDetailDto{Id: input.Id} var data *e.McuOrderItem diff --git a/internal/use-case/main-use-case/mcu-order-item/lib.go b/internal/use-case/main-use-case/mcu-order-item/lib.go index be5c0374..40ebf33d 100644 --- a/internal/use-case/main-use-case/mcu-order-item/lib.go +++ b/internal/use-case/main-use-case/mcu-order-item/lib.go @@ -153,3 +153,27 @@ func DeleteData(data *e.McuOrderItem, event *pl.Event, dbx ...*gorm.DB) error { pl.SetLogInfo(event, nil, "complete") return nil } + +func IsCompleted(mcuOrderItem_id uint, event *pl.Event, dbx ...*gorm.DB) bool { + pl.SetLogInfo(event, nil, "started", "DBIsCompleted") + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + var data e.McuOrderItem + if err := tx.Where("\"Id\" = ?", mcuOrderItem_id).First(&data).Error; err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-get-fail", + Detail: "Database get failed", + Raw: err, + } + return false + } + + pl.SetLogInfo(event, nil, "complete") + return data.IsCompleted() +} diff --git a/internal/use-case/main-use-case/mcu-order-sub-item/case.go b/internal/use-case/main-use-case/mcu-order-sub-item/case.go index bf3e4ce9..88684bff 100644 --- a/internal/use-case/main-use-case/mcu-order-sub-item/case.go +++ b/internal/use-case/main-use-case/mcu-order-sub-item/case.go @@ -1,10 +1,15 @@ package mcuordersubitem import ( + "errors" "strconv" e "simrs-vx/internal/domain/main-entities/mcu-order-sub-item" + umoi "simrs-vx/internal/use-case/main-use-case/mcu-order-item" + + erc "simrs-vx/internal/domain/references/common" + dg "github.com/karincake/apem/db-gorm-pg" d "github.com/karincake/dodol" @@ -35,6 +40,11 @@ func Create(input e.CreateDto) (*d.Data, error) { return err } + // check if mcuOrderItem is done + if umoi.IsCompleted(*input.McuOrderItem_Id, &event, tx) { + return errors.New("mcuOrderItem is already done") + } + if resData, err := CreateData(input, &event, tx); err != nil { return err } else { @@ -277,3 +287,60 @@ func Delete(input e.DeleteDto) (*d.Data, error) { }, nil } + +func Complete(input e.ReadDetailDto) (*d.Data, error) { + var data *e.McuOrderSubItem + var err error + + event := pl.Event{ + Feature: "Complete", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "complete") + + err = dg.I.Transaction(func(tx *gorm.DB) error { + data, err = ReadDetailData(input, &event, tx) + if err != nil { + return err + } + + if data.IsCompleted() { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-state-mismatch", + Detail: "mcuOrderSubItem is already completed", + Raw: errors.New("mcuOrderSubItem is already completed"), + } + return pl.SetLogError(&event, input) + } + + data.Status_Code = erc.DSCDone + 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 + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "single-data", + "status": "fetched", + }, + Data: data.ToResponse(), + }, nil +} diff --git a/internal/use-case/main-use-case/mcu-order/case.go b/internal/use-case/main-use-case/mcu-order/case.go index 57de98fb..158a4995 100644 --- a/internal/use-case/main-use-case/mcu-order/case.go +++ b/internal/use-case/main-use-case/mcu-order/case.go @@ -6,6 +6,8 @@ import ( e "simrs-vx/internal/domain/main-entities/mcu-order" + ue "simrs-vx/internal/use-case/main-use-case/encounter" + erc "simrs-vx/internal/domain/references/common" dg "github.com/karincake/apem/db-gorm-pg" @@ -38,6 +40,11 @@ func Create(input e.CreateDto) (*d.Data, error) { return err } + // check if encounter is done + if ue.IsDone(*input.Encounter_Id, &event, tx) { + return errors.New("encounter is already done") + } + if resData, err := CreateData(input, &event, tx); err != nil { return err } else { diff --git a/internal/use-case/main-use-case/mcu-order/lib.go b/internal/use-case/main-use-case/mcu-order/lib.go index 1cfd7adc..048e6129 100644 --- a/internal/use-case/main-use-case/mcu-order/lib.go +++ b/internal/use-case/main-use-case/mcu-order/lib.go @@ -153,3 +153,27 @@ func DeleteData(data *e.McuOrder, event *pl.Event, dbx ...*gorm.DB) error { pl.SetLogInfo(event, nil, "complete") return nil } + +func IsCompleted(mcuOrder_id uint, event *pl.Event, dbx ...*gorm.DB) bool { + pl.SetLogInfo(event, nil, "started", "DBIsCompleted") + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + var data e.McuOrder + if err := tx.Where("\"Id\" = ?", mcuOrder_id).First(&data).Error; err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-get-fail", + Detail: "Database get failed", + Raw: err, + } + return false + } + + pl.SetLogInfo(event, nil, "complete") + return data.IsCompleted() +} diff --git a/internal/use-case/main-use-case/mcu-sub-src/helper.go b/internal/use-case/main-use-case/mcu-sub-src/helper.go index 071d5f38..95444d5a 100644 --- a/internal/use-case/main-use-case/mcu-sub-src/helper.go +++ b/internal/use-case/main-use-case/mcu-sub-src/helper.go @@ -37,7 +37,7 @@ func createItem(input *e.CreateDto, event *pl.Event, tx *gorm.DB) error { itemCreate := ei.CreateDto{ Code: pu.AddPrefix("mcuSub-", input.Code), Name: input.Name, - ItemGroup_Code: ero.ITGCMCU, + ItemGroup_Code: ero.ITGCMCUSub, // Uom_Code: &input.Uom_Code, // Infra_Id: input.Infra_Id, } diff --git a/internal/use-case/main-use-case/prescription/case.go b/internal/use-case/main-use-case/prescription/case.go index 9b0baeb2..43c0a9e9 100644 --- a/internal/use-case/main-use-case/prescription/case.go +++ b/internal/use-case/main-use-case/prescription/case.go @@ -277,3 +277,62 @@ func Delete(input e.DeleteDto) (*d.Data, error) { }, nil } + +// func Approve(input e.ReadDetailDto) (*d.Data, error) { +// var data *e.Prescription +// var err error + +// event := pl.Event{ +// Feature: "Approve", +// Source: source, +// } + +// // Start log +// pl.SetLogInfo(&event, input, "started", "approve") + +// err = dg.I.Transaction(func(tx *gorm.DB) error { +// data, err = ReadDetailData(input, &event, tx) +// if err != nil { +// return err +// } + +// if data.IsApproved() { +// event.Status = "failed" +// event.ErrInfo = pl.ErrorInfo{ +// Code: "data-state-mismatch", +// Detail: "prescription is already approved", +// Raw: errors.New("prescription is already approved"), +// } +// return pl.SetLogError(&event, input) +// } + +// data.Status_Code = erc.DSCApproved +// 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 +// }) + +// if err != nil { +// return nil, err +// } + +// return &d.Data{ +// Meta: d.IS{ +// "source": source, +// "structure": "single-data", +// "status": "approved", +// }, +// Data: data.ToResponse(), +// }, nil + +// } diff --git a/pkg/use-case-helper/use-case-helper.go b/pkg/use-case-helper/use-case-helper.go index 9fd8351d..04a8eada 100644 --- a/pkg/use-case-helper/use-case-helper.go +++ b/pkg/use-case-helper/use-case-helper.go @@ -103,6 +103,13 @@ func HandleMiddlewareError(event *pl.Event, mwType, mwName string, logData inter return pl.SetLogError(event, logData) } +func IsDataNotFoundError(err error) bool { + if err == nil { + return false + } + return strings.Contains(err.Error(), "code: data-notFound") +} + func AddPrefix(prefix string, str string) string { return prefix + str }