Merge branch 'feat/orders' of github.com:dikstub-rssa/simrs-be into feat/be-consultation-28

This commit is contained in:
dpurbosakti
2025-09-23 10:04:09 +07:00
67 changed files with 2551 additions and 147 deletions
@@ -5,13 +5,15 @@ import (
emo "simrs-vx/internal/domain/main-entities/mcu-order"
ems "simrs-vx/internal/domain/main-entities/mcu-src"
erc "simrs-vx/internal/domain/references/common"
"time"
)
type CreateDto struct {
McuOrder_Id *uint `json:"mcuOrder_id"`
McuSrc_Id *uint `json:"mcuSrc_id"`
Result *string `json:"result"`
Status_Code erc.DataStatusCode `json:"status_code"`
McuOrder_Id *uint `json:"mcuOrder_id"`
McuSrc_Id *uint `json:"mcuSrc_id"`
Result *string `json:"result"`
Status_Code erc.DataStatusCode `json:"status_code"`
ExaminationDate *time.Time `json:"examinationDate"`
}
type ReadListDto struct {
@@ -31,16 +33,21 @@ type FilterDto struct {
NoPagination int `json:"no_pagination"`
}
type ReadDetailDto struct {
Id uint16 `json:"id"`
Id uint `json:"id"`
}
type UpdateDto struct {
Id uint16 `json:"id"`
Id uint `json:"id"`
CreateDto
}
type DeleteDto struct {
Id uint16 `json:"id"`
Id uint `json:"id"`
}
type SetScheduleDto struct {
Id uint `json:"id"`
ExaminationDate *time.Time `json:"examinationDate"`
}
type MetaDto struct {
@@ -51,22 +58,24 @@ type MetaDto struct {
type ResponseDto struct {
ecore.Main
McuOrder_Id *uint `json:"mcuOrder_id"`
McuOrder *emo.McuOrder `json:"mcuOrder,omitempty"`
McuSrc_Id *uint `json:"mcuSrc_id"`
McuSrc *ems.McuSrc `json:"mcuSrc,omitempty"`
Result *string `json:"result"`
Status_Code erc.DataStatusCode `json:"status_code"`
McuOrder_Id *uint `json:"mcuOrder_id"`
McuOrder *emo.McuOrder `json:"mcuOrder,omitempty"`
McuSrc_Id *uint `json:"mcuSrc_id"`
McuSrc *ems.McuSrc `json:"mcuSrc,omitempty"`
Result *string `json:"result"`
Status_Code erc.DataStatusCode `json:"status_code"`
ExaminationDate *time.Time `json:"examinationDate"`
}
func (d McuOrderItem) ToResponse() ResponseDto {
resp := ResponseDto{
McuOrder_Id: d.McuOrder_Id,
McuOrder: d.McuOrder,
McuSrc_Id: d.McuSrc_Id,
McuSrc: d.McuSrc,
Result: d.Result,
Status_Code: d.Status_Code,
McuOrder_Id: d.McuOrder_Id,
McuOrder: d.McuOrder,
McuSrc_Id: d.McuSrc_Id,
McuSrc: d.McuSrc,
Result: d.Result,
Status_Code: d.Status_Code,
ExaminationDate: d.ExaminationDate,
}
resp.Main = d.Main
return resp
@@ -19,3 +19,7 @@ type McuOrderItem struct {
Result *string `json:"result"`
Status_Code erc.DataStatusCode `json:"status_code"`
}
func (d McuOrderItem) IsCompleted() bool {
return d.Status_Code == erc.DSCDone
}
@@ -31,16 +31,16 @@ type FilterDto struct {
NoPagination int `json:"no_pagination"`
}
type ReadDetailDto struct {
Id uint16 `json:"id"`
Id uint `json:"id"`
}
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 {
@@ -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
}
+46 -20
View File
@@ -4,13 +4,20 @@ import (
ecore "simrs-vx/internal/domain/base-entities/core"
ed "simrs-vx/internal/domain/main-entities/doctor"
ee "simrs-vx/internal/domain/main-entities/encounter"
ercl "simrs-vx/internal/domain/references/clinical"
erc "simrs-vx/internal/domain/references/common"
"time"
)
type CreateDto struct {
Encounter_Id *uint `json:"encounter_id"`
Status_Code erc.DataStatusCode `json:"status_code" gorm:"not null;size:10"`
Doctor_Id *uint `json:"doctor_id"`
Encounter_Id *uint `json:"encounter_id"`
Status_Code erc.DataStatusCode `json:"status_code" gorm:"not null;size:10"`
Doctor_Id *uint `json:"doctor_id"`
SpecimenPickTime *time.Time `json:"specimenPickTime"`
ExaminationDate *time.Time `json:"examinationDate"`
Number uint8 `json:"number"`
Temperature float64 `json:"temperature"`
McuUrgencyLevel_Code ercl.McuUrgencyLevelCode `json:"mcuUrgencyLevel_code""`
}
type ReadListDto struct {
@@ -20,25 +27,35 @@ type ReadListDto struct {
}
type FilterDto struct {
Encounter_Id *uint `json:"encounter_id"`
Status_Code erc.DataStatusCode `json:"status_code" gorm:"not null;size:10"`
Doctor_Id *uint `json:"doctor_id"`
Encounter_Id *uint `json:"encounter_id"`
Status_Code erc.DataStatusCode `json:"status_code" gorm:"not null;size:10"`
Doctor_Id *uint `json:"doctor_id"`
SpecimenPickTime *time.Time `json:"specimenPickTime"`
ExaminationDate *time.Time `json:"examinationDate"`
Number uint8 `json:"number"`
Temperature float64 `json:"temperature"`
McuUrgencyLevel_Code ercl.McuUrgencyLevelCode `json:"mcuUrgencyLevel_code""`
Page int `json:"page"`
PageSize int `json:"page_size"`
NoPagination int `json:"no_pagination"`
}
type ReadDetailDto struct {
Id uint16 `json:"id"`
Id uint `json:"id"`
}
type UpdateDto struct {
Id uint16 `json:"id"`
Id uint `json:"id"`
CreateDto
}
type DeleteDto struct {
Id uint16 `json:"id"`
Id uint `json:"id"`
}
type SetScheduleDto struct {
Id uint `json:"id"`
ExaminationDate *time.Time `json:"examinationDate"`
}
type MetaDto struct {
@@ -46,23 +63,32 @@ type MetaDto struct {
PageSize int `json:"page_size"`
Count int `json:"count"`
}
type ResponseDto struct {
ecore.Main
Encounter_Id *uint `json:"encounter_id"`
Encounter *ee.Encounter `json:"encounter,omitempty"`
Status_Code erc.DataStatusCode `json:"status_code" gorm:"not null;size:10"`
Doctor_Id *uint `json:"doctor_id"`
Doctor *ed.Doctor `json:"doctor,omitempty"`
Encounter_Id *uint `json:"encounter_id"`
Encounter *ee.Encounter `json:"encounter,omitempty"`
Status_Code erc.DataStatusCode `json:"status_code" gorm:"not null;size:10"`
Doctor_Id *uint `json:"doctor_id"`
Doctor *ed.Doctor `json:"doctor,omitempty"`
SpecimenPickTime *time.Time `json:"specimenPickTime"`
ExaminationDate *time.Time `json:"examinationDate"`
Number uint8 `json:"number"`
Temperature float64 `json:"temperature"`
McuUrgencyLevel_Code ercl.McuUrgencyLevelCode `json:"mcuUrgencyLevel_code""`
}
func (d McuOrder) ToResponse() ResponseDto {
resp := ResponseDto{
Encounter_Id: d.Encounter_Id,
Encounter: d.Encounter,
Status_Code: d.Status_Code,
Doctor_Id: d.Doctor_Id,
Doctor: d.Doctor,
Encounter_Id: d.Encounter_Id,
Encounter: d.Encounter,
Status_Code: d.Status_Code,
Doctor_Id: d.Doctor_Id,
Doctor: d.Doctor,
SpecimenPickTime: d.SpecimenPickTime,
ExaminationDate: d.ExaminationDate,
Number: d.Number,
Temperature: d.Temperature,
McuUrgencyLevel_Code: d.McuUrgencyLevel_Code,
}
resp.Main = d.Main
return resp
@@ -23,3 +23,7 @@ type McuOrder struct {
Temperature float64 `json:"temperature"`
McuUrgencyLevel_Code ercl.McuUrgencyLevelCode `json:"mcuUrgencyLevel_code" gorm:"not null;size:15"`
}
func (d McuOrder) IsCompleted() bool {
return d.Status_Code == erc.DSCDone
}
@@ -9,6 +9,7 @@ type CreateDto struct {
Code string `json:"code" validate:"maxLength=20"`
Name string `json:"name" validate:"maxLength=50"`
CheckupCategory_Code *string `json:"checkupCategory_code" validate:"maxLength=20"`
Item_Id *uint `json:"item_id"`
}
type ReadListDto struct {
@@ -10,6 +10,7 @@ type CreateDto struct {
Code string `json:"code" validate:"maxLength=20"`
Name string `json:"name" validate:"maxLength=50"`
McuSrc_Id *uint `json:"mcuSrc_id"`
Item_Id *uint `json:"item_id"`
}
type ReadListDto struct {
@@ -17,6 +17,8 @@ type CreateDto struct {
Interval uint8 `json:"interval"`
IntervalUnit_Code erc.TimeUnitCode `json:"intervalUnit_code"`
IsRedeemed bool `json:"isRedeemed"`
Quantity float64 `json:"quantity"`
Note *string `json:"note" gorm:"size:1024"`
}
type ReadListDto struct {
@@ -34,6 +36,8 @@ type FilterDto struct {
Interval uint8 `json:"interval"`
IntervalUnit_Code erc.TimeUnitCode `json:"intervalUnit_code"`
IsRedeemed bool `json:"isRedeemed"`
Quantity float64 `json:"quantity"`
Note *string `json:"note" gorm:"size:1024"`
Page int `json:"page"`
PageSize int `json:"page_size"`
@@ -71,6 +75,8 @@ type ResponseDto struct {
Interval uint8 `json:"interval"`
IntervalUnit_Code erc.TimeUnitCode `json:"intervalUnit_code"`
IsRedeemed bool `json:"isRedeemed"`
Quantity float64 `json:"quantity"`
Note *string `json:"note" gorm:"size:1024"`
}
func (d MedicationItem) ToResponse() ResponseDto {
@@ -86,6 +92,8 @@ func (d MedicationItem) ToResponse() ResponseDto {
Interval: d.Interval,
IntervalUnit_Code: d.IntervalUnit_Code,
IsRedeemed: d.IsRedeemed,
Quantity: d.Quantity,
Note: d.Note,
}
resp.Main = d.Main
return resp
@@ -35,18 +35,19 @@ type FilterDto struct {
NoPagination int `json:"no_pagination"`
}
type ReadDetailDto struct {
Id uint16 `json:"id"`
Id uint `json:"id"`
Encounter_Id *uint `json:"encounter_id"`
pa.AuthInfo
}
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 {
@@ -6,9 +6,10 @@ import (
)
type CreateDto struct {
MedicineMix_Id *uint `json:"medicineMix_id"`
Medicine_Id *uint `json:"medicine_id"`
Dose *uint8 `json:"dose"`
MedicineMix_Id *uint `json:"medicineMix_id"`
Medicine_Id *uint `json:"medicine_id"`
Dose *uint8 `json:"dose"`
Note *string `json:"note" gom:"size:1024"`
}
type ReadListDto struct {
@@ -18,9 +19,10 @@ type ReadListDto struct {
}
type FilterDto struct {
MedicineMix_Id *uint `json:"medicineMix_id"`
Medicine_Id *uint `json:"medicine_id"`
Dose *uint8 `json:"dose"`
MedicineMix_Id *uint `json:"medicineMix_id"`
Medicine_Id *uint `json:"medicine_id"`
Dose *uint8 `json:"dose"`
Note *string `json:"note" gom:"size:1024"`
Page int `json:"page"`
PageSize int `json:"page_size"`
@@ -52,6 +54,7 @@ type ResponseDto struct {
Medicine_Id *uint `json:"medicine_id"`
Medicine *em.Medicine `json:"medicine,omitempty"`
Dose *uint8 `json:"dose"`
Note *string `json:"note" gom:"size:1024"`
}
func (d MedicineMixItem) ToResponse() ResponseDto {
@@ -60,6 +63,7 @@ func (d MedicineMixItem) ToResponse() ResponseDto {
Medicine_Id: d.Medicine_Id,
Medicine: d.Medicine,
Dose: d.Dose,
Note: d.Note,
}
resp.Main = d.Main
return resp
@@ -84,7 +84,20 @@ type ResponseDto struct {
}
func (d *PersonRelative) ToResponse() ResponseDto {
resp := ResponseDto{}
resp := ResponseDto{
Person_Id: d.Person_Id,
Relationship_Code: d.Relationship_Code,
Name: d.Name,
Address: d.Address,
Village_Code: d.Village_Code,
Village: d.Village,
Gender_Code: d.Gender_Code,
PhoneNumber: d.PhoneNumber,
Education_Code: d.Education_Code,
Occupation_Code: d.Occupation_Code,
Occupation_Name: d.Occupation_Name,
Responsible: d.Responsible,
}
resp.Main = d.Main
return resp
}
@@ -16,6 +16,7 @@ type CreateDto struct {
Usage float64 `json:"usage"`
Interval uint8 `json:"interval"`
IntervalUnit_Code erc.TimeUnitCode `json:"intervalUnit_code"`
Quantity float64 `json:"quantity"`
}
type ReadListDto struct {
@@ -32,6 +33,7 @@ type FilterDto struct {
Usage float64 `json:"usage"`
Interval uint8 `json:"interval"`
IntervalUnit_Code erc.TimeUnitCode `json:"intervalUnit_code"`
Quantity float64 `json:"quantity"`
Page int `json:"page"`
PageSize int `json:"page_size"`
@@ -68,6 +70,7 @@ type ResponseDto struct {
Usage float64 `json:"usage"`
Interval uint8 `json:"interval"`
IntervalUnit_Code erc.TimeUnitCode `json:"intervalUnit_code"`
Quantity float64 `json:"quantity"`
}
func (d PrescriptionItem) ToResponse() ResponseDto {
@@ -82,6 +85,7 @@ func (d PrescriptionItem) ToResponse() ResponseDto {
Usage: d.Usage,
Interval: d.Interval,
IntervalUnit_Code: d.IntervalUnit_Code,
Quantity: d.Quantity,
}
resp.Main = d.Main
return resp
@@ -4,13 +4,17 @@ import (
ecore "simrs-vx/internal/domain/base-entities/core"
ed "simrs-vx/internal/domain/main-entities/doctor"
ee "simrs-vx/internal/domain/main-entities/encounter"
"time"
erc "simrs-vx/internal/domain/references/common"
)
type CreateDto struct {
Encounter_Id *uint `json:"encounter_id"`
Doctor_Id *uint `json:"doctor_id"`
IssuedAt *time.Time `json:"issuedAt"`
Encounter_Id *uint `json:"encounter_id"`
Doctor_Id *uint `json:"doctor_id"`
IssuedAt *time.Time `json:"issuedAt"`
Status_Code erc.DataStatusCode `json:"status_code"`
}
type ReadListDto struct {
@@ -20,25 +24,27 @@ type ReadListDto struct {
}
type FilterDto struct {
Encounter_Id *uint `json:"encounter_id"`
Doctor_Id *uint `json:"doctor_id"`
IssuedAt *time.Time `json:"issuedAt"`
Encounter_Id *uint `json:"encounter_id"`
Doctor_Id *uint `json:"doctor_id"`
IssuedAt *time.Time `json:"issuedAt"`
Status_Code *erc.DataStatusCode `json:"status_code"`
Page int `json:"page"`
PageSize int `json:"page_size"`
NoPagination int `json:"no_pagination"`
}
type ReadDetailDto struct {
Id uint16 `json:"id"`
Id uint `json:"id"`
Encounter_Id *uint `json:"encounter_id"`
}
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 {
@@ -49,11 +55,12 @@ type MetaDto struct {
type ResponseDto struct {
ecore.Main
Encounter_Id *uint `json:"encounter_id"`
Encounter *ee.Encounter `json:"encounter,omitempty"`
Doctor_Id *uint `json:"doctor_id"`
Doctor *ed.Doctor `json:"doctor,omitempty"`
IssuedAt *time.Time `json:"issuedAt"`
Encounter_Id *uint `json:"encounter_id"`
Encounter *ee.Encounter `json:"encounter,omitempty"`
Doctor_Id *uint `json:"doctor_id"`
Doctor *ed.Doctor `json:"doctor,omitempty"`
IssuedAt *time.Time `json:"issuedAt"`
Status_Code erc.DataStatusCode `json:"status_code"`
}
func (d Prescription) ToResponse() ResponseDto {
@@ -63,6 +70,7 @@ func (d Prescription) ToResponse() ResponseDto {
Doctor_Id: d.Doctor_Id,
Doctor: d.Doctor,
IssuedAt: d.IssuedAt,
Status_Code: d.Status_Code,
}
resp.Main = d.Main
return resp
@@ -19,3 +19,7 @@ type Prescription struct {
IssuedAt *time.Time `json:"issuedAt"`
Status_Code erc.DataStatusCode `json:"status_code"`
}
func (d Prescription) IsApproved() bool {
return d.Status_Code == erc.DSCDone
}
@@ -23,6 +23,8 @@ const (
ITGCMedicine ItemGroupCode = "medicine"
ITGCDevice ItemGroupCode = "device"
ITGCMaterial ItemGroupCode = "material"
ITGCMCU ItemGroupCode = "mcu"
ITGCMCUSub ItemGroupCode = "mcuSub"
ITGCEmpFee ItemGroupCode = "employee-fee"
ITGCDocFee ItemGroupCode = "doctor-fee"
@@ -72,9 +72,14 @@ func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) {
func (obj myBase) CheckOut(w http.ResponseWriter, r *http.Request) {
dto := e.DischargeDto{}
id := rw.ValidateInt(w, "id", r.PathValue("id"))
if id <= 0 {
return
}
if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
return
}
dto.Id = uint(id)
res, err := u.CheckOut(dto)
rw.DataResponse(w, res, err)
}
+59 -26
View File
@@ -14,6 +14,7 @@ import (
materialorderitem "simrs-vx/internal/interface/main-handler/material-order-item"
mcuorder "simrs-vx/internal/interface/main-handler/mcu-order"
mcuorderitem "simrs-vx/internal/interface/main-handler/mcu-order-item"
mcuordersubitem "simrs-vx/internal/interface/main-handler/mcu-order-sub-item"
medication "simrs-vx/internal/interface/main-handler/medication"
medicationitem "simrs-vx/internal/interface/main-handler/medication-item"
medicationitemdist "simrs-vx/internal/interface/main-handler/medication-item-dist"
@@ -68,6 +69,7 @@ import (
material "simrs-vx/internal/interface/main-handler/material"
mcusrc "simrs-vx/internal/interface/main-handler/mcu-src"
mcusrccategory "simrs-vx/internal/interface/main-handler/mcu-src-category"
mcusubsrc "simrs-vx/internal/interface/main-handler/mcu-sub-src"
medicalactionsrc "simrs-vx/internal/interface/main-handler/medical-action-src"
medicalactionsrcitem "simrs-vx/internal/interface/main-handler/medical-action-src-item"
medicine "simrs-vx/internal/interface/main-handler/medicine"
@@ -111,24 +113,45 @@ func SetRoutes() http.Handler {
hc.RegCrud(r, "/v1/counter", counter.O)
hc.RegCrud(r, "/v1/medicine-mix", medicicinemix.O)
hc.RegCrud(r, "/v1/medicine-mix-item", medicicinemixitem.O)
/******************** actor ********************/
hk.GroupRoutes("/v1/user", r, hk.MapHandlerFunc{
"GET /": user.O.GetList,
"GET /{id}": user.O.GetDetail,
"POST /": user.O.Create,
"PATCH /{id}": user.O.Update,
"DELETE /{id}": user.O.Delete,
"PATCH /{id}/block": user.O.Block,
"PATCH /{id}/active": user.O.Active,
hc.RegCrud(r, "/v1/soapi", auth.GuardMW, soapi.O)
hc.RegCrud(r, "/v1/adime", auth.GuardMW, adime.O)
hc.RegCrud(r, "/v1/sbar", auth.GuardMW, sbar.O)
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)
hk.GroupRoutes("/v1/mcu-order", r, hk.MapHandlerFunc{
"GET /": mcuorder.O.GetList,
"GET /{id}": mcuorder.O.GetDetail,
"POST /": mcuorder.O.Create,
"PATCH /{id}": mcuorder.O.Update,
"DELETE /{id}": mcuorder.O.Delete,
"PATCH /{id}/complete": mcuorder.O.Complete,
"PATCH /{id}/set-schedule": mcuorder.O.SetSchedule,
})
hk.GroupRoutes("/v1/patient", r, hk.MapHandlerFunc{
"GET /": patient.O.GetList,
"GET /{id}": patient.O.GetDetail,
"POST /": patient.O.Create,
"PATCH /{id}": patient.O.Update,
"DELETE /{id}": patient.O.Delete,
"GET /by-identifier": patient.O.Search,
hk.GroupRoutes("/v1/mcu-order-item", r, hk.MapHandlerFunc{
"GET /": mcuorderitem.O.GetList,
"GET /{id}": mcuorderitem.O.GetDetail,
"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/prescription", r, hk.MapHandlerFunc{
"GET /": prescription.O.GetList,
"GET /{id}": prescription.O.GetDetail,
"POST /": prescription.O.Create,
"PATCH /{id}": prescription.O.Update,
"DELETE /{id}": prescription.O.Delete,
"PATCH /{id}/approve": prescription.O.Approve,
})
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,
@@ -183,9 +206,7 @@ func SetRoutes() http.Handler {
"PATCH /{id}/complete": materialorder.O.Complete,
})
hc.RegCrud(r, "/v1/soapi", auth.GuardMW, soapi.O)
hc.RegCrud(r, "/v1/adime", auth.GuardMW, adime.O)
hc.RegCrud(r, "/v1/sbar", auth.GuardMW, sbar.O)
/******************** actor ********************/
hc.RegCrud(r, "/v1/person", person.O)
hc.RegCrud(r, "/v1/person-address", personaddress.O)
hc.RegCrud(r, "/v1/person-contact", personcontact.O)
@@ -194,12 +215,23 @@ func SetRoutes() http.Handler {
hc.RegCrud(r, "/v1/nurse", nurse.O)
hc.RegCrud(r, "/v1/nutritionist", nutritionist.O)
hc.RegCrud(r, "/v1/pharmacist", pharmacist.O)
hc.RegCrud(r, "/v1/prescription", prescription.O)
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", mcuorder.O)
hc.RegCrud(r, "/v1/mcu-order-item", mcuorderitem.O)
hk.GroupRoutes("/v1/user", r, hk.MapHandlerFunc{
"GET /": user.O.GetList,
"GET /{id}": user.O.GetDetail,
"POST /": user.O.Create,
"PATCH /{id}": user.O.Update,
"DELETE /{id}": user.O.Delete,
"PATCH /{id}/block": user.O.Block,
"PATCH /{id}/active": user.O.Active,
})
hk.GroupRoutes("/v1/patient", r, hk.MapHandlerFunc{
"GET /": patient.O.GetList,
"GET /{id}": patient.O.GetDetail,
"POST /": patient.O.Create,
"PATCH /{id}": patient.O.Update,
"DELETE /{id}": patient.O.Delete,
"GET /by-identifier": patient.O.Search,
})
/******************** sources ********************/
hc.RegCrud(r, "/v1/division", division.O)
@@ -228,6 +260,7 @@ func SetRoutes() http.Handler {
hc.RegCrud(r, "/v1/language", language.O)
hc.RegCrud(r, "/v1/specialist", specialist.O)
hc.RegCrud(r, "/v1/subspecialist", subspecialist.O)
hc.RegCrud(r, "/v1/mcu-sub-src", mcusubsrc.O)
hc.RegCrud(r, "/v1/village", village.O)
hc.RegCrud(r, "/v1/district", district.O)
@@ -38,7 +38,7 @@ func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) {
return
}
dto := e.ReadDetailDto{}
dto.Id = uint16(id)
dto.Id = uint(id)
res, err := u.ReadDetail(dto)
rw.DataResponse(w, res, err)
}
@@ -53,7 +53,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)
}
@@ -65,7 +65,34 @@ 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) 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 {
return
}
dto := e.SetScheduleDto{}
if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
return
}
dto.Id = uint(id)
res, err := u.SetSchedule(dto)
rw.DataResponse(w, res, err)
}
@@ -0,0 +1,83 @@
package mcuordersubitem
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/mcu-order-sub-item"
u "simrs-vx/internal/use-case/main-use-case/mcu-order-sub-item"
)
type myBase struct{}
var O myBase
func (obj myBase) Create(w http.ResponseWriter, r *http.Request) {
dto := e.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{}
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) 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)
}
@@ -38,7 +38,7 @@ func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) {
return
}
dto := e.ReadDetailDto{}
dto.Id = uint16(id)
dto.Id = uint(id)
res, err := u.ReadDetail(dto)
rw.DataResponse(w, res, err)
}
@@ -53,7 +53,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)
}
@@ -65,7 +65,34 @@ 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) 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 {
return
}
dto := e.SetScheduleDto{}
if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
return
}
dto.Id = uint(id)
res, err := u.SetSchedule(dto)
rw.DataResponse(w, res, err)
}
@@ -0,0 +1,71 @@
package mcusubsrc
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/mcu-sub-src"
u "simrs-vx/internal/use-case/main-use-case/mcu-sub-src"
)
type myBase struct{}
var O myBase
func (obj myBase) Create(w http.ResponseWriter, r *http.Request) {
dto := e.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{}
dto.Id = uint16(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 = uint16(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 = uint16(id)
res, err := u.Delete(dto)
rw.DataResponse(w, res, err)
}
@@ -40,7 +40,7 @@ func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) {
return
}
dto := e.ReadDetailDto{}
dto.Id = uint16(id)
dto.Id = uint(id)
res, err := u.ReadDetail(dto)
rw.DataResponse(w, res, err)
}
@@ -55,7 +55,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)
}
@@ -67,7 +67,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)
}
@@ -84,11 +84,8 @@ func (obj myBase) Complete(w http.ResponseWriter, r *http.Request) {
}
dto := e.ReadDetailDto{}
if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
return
}
dto.AuthInfo = *authInfo
dto.Id = uint16(id)
dto.Id = uint(id)
res, err := u.Complete(dto)
rw.DataResponse(w, res, err)
}
@@ -38,7 +38,7 @@ func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) {
return
}
dto := e.ReadDetailDto{}
dto.Id = uint16(id)
dto.Id = uint(id)
res, err := u.ReadDetail(dto)
rw.DataResponse(w, res, err)
}
@@ -53,7 +53,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)
}
@@ -65,7 +65,19 @@ 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) Approve(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.Approve(dto)
rw.DataResponse(w, res, err)
}
@@ -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 {
@@ -31,6 +31,7 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Device) {
data.Name = inputSrc.Name
data.Uom_Code = inputSrc.Uom_Code
data.Item_Id = inputSrc.Item_Id
data.Infra_Id = inputSrc.Infra_Id
}
func createItem(input *e.CreateDto, event *pl.Event, tx *gorm.DB) error {
@@ -379,6 +379,12 @@ func CheckOut(input e.DischargeDto) (*d.Data, error) {
return err
}
if err := createMedication(data.Id, &event, tx); err != nil {
if !pu.IsDataNotFoundError(err) {
return err
}
}
pl.SetLogInfo(&event, nil, "complete")
return nil
@@ -8,7 +8,23 @@ import (
"errors"
e "simrs-vx/internal/domain/main-entities/encounter"
es "simrs-vx/internal/domain/main-entities/soapi"
em "simrs-vx/internal/domain/main-entities/medication"
emei "simrs-vx/internal/domain/main-entities/medication-item"
emi "simrs-vx/internal/domain/main-entities/medicine-mix"
emmi "simrs-vx/internal/domain/main-entities/medicine-mix-item"
ep "simrs-vx/internal/domain/main-entities/prescription"
epi "simrs-vx/internal/domain/main-entities/prescription-item"
um "simrs-vx/internal/use-case/main-use-case/medication"
umei "simrs-vx/internal/use-case/main-use-case/medication-item"
umi "simrs-vx/internal/use-case/main-use-case/medicine-mix"
ummi "simrs-vx/internal/use-case/main-use-case/medicine-mix-item"
up "simrs-vx/internal/use-case/main-use-case/prescription"
upi "simrs-vx/internal/use-case/main-use-case/prescription-item"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
erc "simrs-vx/internal/domain/references/common"
ero "simrs-vx/internal/domain/references/organization"
@@ -98,3 +114,94 @@ func checkSoapiByDocExists(encounter_id uint, event *pl.Event, tx *gorm.DB) erro
}
return pl.SetLogError(event, nil)
}
func createMedication(encounter_id uint, event *pl.Event, tx *gorm.DB) error {
pl.SetLogInfo(event, nil, "started", "createMedication")
prescription, err := up.ReadDetailData(ep.ReadDetailDto{Encounter_Id: &encounter_id}, event, tx)
if err != nil {
return err
}
prescriptionItem, _, err := upi.ReadListData(epi.ReadListDto{FilterDto: epi.FilterDto{Prescription_Id: &prescription.Id}}, event, tx)
if err != nil {
return err
}
if len(prescriptionItem) == 0 {
return nil
}
medicationCreate := em.CreateDto{
Encounter_Id: &encounter_id,
IssuedAt: pu.GetTimeNow(),
}
medication, err := um.CreateData(medicationCreate, event, tx)
if err != nil {
return err
}
for _, prescriptionItem := range prescriptionItem {
if prescriptionItem.IsMix {
medMix_id, err := createMedicineMixAndItem(*prescriptionItem.MedicineMix, event, tx)
if err != nil {
return err
}
prescriptionItem.MedicineMix_Id = medMix_id
}
err := createMedicationItem(medication.Id, prescriptionItem, event, tx)
if err != nil {
return err
}
}
return nil
}
func createMedicineMixAndItem(input emi.MedicineMix, event *pl.Event, tx *gorm.DB) (*uint, error) {
pl.SetLogInfo(event, nil, "started", "createMedicineMix")
medicineMixCreate := emi.CreateDto{
Name: input.Name,
}
medicineMix, err := umi.CreateData(medicineMixCreate, event, tx)
if err != nil {
return nil, err
}
// recreate medicineMixItem with new medicineMix_id to keep medMixItem remain the same for prescriptionItem that is created
for _, medicineMixItem := range input.MixItems {
medicineMixItemCreate := emmi.CreateDto{
MedicineMix_Id: &medicineMix.Id,
Medicine_Id: medicineMixItem.Medicine_Id,
Dose: medicineMixItem.Dose,
}
_, err := ummi.CreateData(medicineMixItemCreate, event, tx)
if err != nil {
return nil, err
}
}
return &medicineMix.Id, nil
}
func createMedicationItem(medication_id uint, input epi.PrescriptionItem, event *pl.Event, tx *gorm.DB) error {
pl.SetLogInfo(event, nil, "started", "createMedicationItem")
medicationItemCreate := emei.CreateDto{
Medication_Id: &medication_id,
IsMix: input.IsMix,
Medicine_Id: input.Medicine_Id,
MedicineMix_Id: input.MedicineMix_Id,
Usage: input.Usage,
Interval: input.Interval,
IntervalUnit_Code: input.IntervalUnit_Code,
Quantity: input.Quantity,
}
_, err := umei.CreateData(medicationItemCreate, event, tx)
if err != nil {
return err
}
return nil
}
@@ -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()
}
@@ -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 {
@@ -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 {
@@ -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()
}
@@ -31,6 +31,7 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Material) {
data.Uom_Code = inputSrc.Uom_Code
data.Stock = inputSrc.Stock
data.Item_Id = inputSrc.Item_Id
data.Infra_Id = inputSrc.Infra_Id
}
func createItem(input *e.CreateDto, event *pl.Event, tx *gorm.DB) error {
@@ -1,10 +1,15 @@
package mcuorderitem
import (
"errors"
"strconv"
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"
@@ -35,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 {
@@ -277,3 +287,113 @@ func Delete(input e.DeleteDto) (*d.Data, error) {
}, nil
}
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
var err error
event := pl.Event{
Feature: "SetSchedule",
Source: source,
}
// Start log
pl.SetLogInfo(&event, input, "started", "setSchedule")
err = dg.I.Transaction(func(tx *gorm.DB) error {
pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail")
data, err = ReadDetailData(rdDto, &event, tx)
if err != nil {
return err
}
if data.IsCompleted() {
return errors.New("data already completed")
}
data.ExaminationDate = input.ExaminationDate
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": "setSchedule",
},
Data: data.ToResponse(),
}, nil
}
@@ -21,4 +21,5 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.McuOrderItem) {
data.McuSrc_Id = inputSrc.McuSrc_Id
data.Result = inputSrc.Result
data.Status_Code = inputSrc.Status_Code
data.ExaminationDate = inputSrc.ExaminationDate
}
@@ -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()
}
@@ -0,0 +1,346 @@
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"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
"gorm.io/gorm"
)
const source = "mcu-order-sub-item"
func Create(input e.CreateDto) (*d.Data, error) {
data := e.McuOrderSubItem{}
event := pl.Event{
Feature: "Create",
Source: source,
}
// 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
}
// 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 {
data = *resData
}
mwRunner.setMwType(pu.MWTPost)
// Run post-middleware
if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil {
return err
}
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: data.ToResponse(),
}, nil
}
func ReadList(input e.ReadListDto) (*d.Data, error) {
var data *e.McuOrderSubItem
var dataList []e.McuOrderSubItem
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 len(input.Includes) > 0 {
input.Preloads = pu.GetPreloads(input.Includes)
}
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),
},
Data: e.ToResponseList(dataList),
}, nil
}
func ReadDetail(input e.ReadDetailDto) (*d.Data, error) {
var data *e.McuOrderSubItem
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.McuOrderSubItem
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
}
mwRunner := newMiddlewareRunner(&event, tx)
mwRunner.setMwType(pu.MWTPre)
// Run pre-middleware
if err := mwRunner.RunUpdateMiddleware(readDetailPreMw, &rdDto, data); err != nil {
return err
}
if err := UpdateData(input, data, &event, tx); err != nil {
return err
}
pl.SetLogInfo(&event, nil, "complete")
mwRunner.setMwType(pu.MWTPost)
// Run post-middleware
if err := mwRunner.RunUpdateMiddleware(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": "updated",
},
Data: data.ToResponse(),
}, nil
}
func Delete(input e.DeleteDto) (*d.Data, error) {
rdDto := e.ReadDetailDto{Id: input.Id}
var data *e.McuOrderSubItem
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 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
}
@@ -0,0 +1,24 @@
/*
DESCRIPTION:
Any functions that are used internally by the use-case
*/
package mcuordersubitem
import (
e "simrs-vx/internal/domain/main-entities/mcu-order-sub-item"
)
func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.McuOrderSubItem) {
var inputSrc *e.CreateDto
if inputT, ok := any(input).(*e.CreateDto); ok {
inputSrc = inputT
} else {
inputTemp := any(input).(*e.UpdateDto)
inputSrc = &inputTemp.CreateDto
}
data.McuSubSrc_Id = inputSrc.McuSubSrc_Id
data.McuOrderItem_Id = inputSrc.McuOrderItem_Id
data.Result = inputSrc.Result
data.Status_Code = inputSrc.Status_Code
}
@@ -0,0 +1,155 @@
package mcuordersubitem
import (
e "simrs-vx/internal/domain/main-entities/mcu-order-sub-item"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
dg "github.com/karincake/apem/db-gorm-pg"
gh "github.com/karincake/getuk"
"gorm.io/gorm"
)
func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.McuOrderSubItem, error) {
pl.SetLogInfo(event, nil, "started", "DBCreate")
data := e.McuOrderSubItem{}
setData(&input, &data)
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
} else {
tx = dg.I
}
if err := tx.Create(&data).Error; err != nil {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-create-fail",
Detail: "Database insert failed",
Raw: err,
}
return nil, pl.SetLogError(event, input)
}
pl.SetLogInfo(event, nil, "complete")
return &data, nil
}
func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.McuOrderSubItem, *e.MetaDto, error) {
pl.SetLogInfo(event, input, "started", "DBReadList")
data := []e.McuOrderSubItem{}
pagination := gh.Pagination{}
count := int64(0)
meta := e.MetaDto{}
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
} else {
tx = dg.I
}
if len(input.Preloads) > 0 {
for _, preload := range input.Preloads {
tx = tx.Preload(preload)
}
}
tx = tx.
Model(&e.McuOrderSubItem{}).
Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-get-fail",
Detail: "Database get failed",
Raw: err,
}
return nil, nil, pl.SetLogError(event, input)
}
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.McuOrderSubItem, error) {
pl.SetLogInfo(event, input, "started", "DBReadDetail")
data := e.McuOrderSubItem{}
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
} else {
tx = dg.I
}
if err := tx.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(input e.UpdateDto, data *e.McuOrderSubItem, event *pl.Event, dbx ...*gorm.DB) error {
pl.SetLogInfo(event, data, "started", "DBUpdate")
setData(&input, data)
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
} else {
tx = dg.I
}
if err := tx.Save(&data).Error; err != nil {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-update-fail",
Detail: "Database update failed",
Raw: err,
}
return pl.SetLogError(event, input)
}
pl.SetLogInfo(event, nil, "complete")
return nil
}
func DeleteData(data *e.McuOrderSubItem, 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
}
@@ -0,0 +1,103 @@
package mcuordersubitem
import (
e "simrs-vx/internal/domain/main-entities/mcu-order-sub-item"
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.McuOrderSubItem) 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.McuOrderSubItem) 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.McuOrderSubItem) 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.McuOrderSubItem) 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.McuOrderSubItem) 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 mcuordersubitem
// 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 mcuordersubitem
import (
"gorm.io/gorm"
e "simrs-vx/internal/domain/main-entities/mcu-order-sub-item"
)
type createMw struct {
Name string
Func func(input *e.CreateDto, data *e.McuOrderSubItem, tx *gorm.DB) error
}
type readListMw struct {
Name string
Func func(input *e.ReadListDto, data *e.McuOrderSubItem, tx *gorm.DB) error
}
type readDetailMw struct {
Name string
Func func(input *e.ReadDetailDto, data *e.McuOrderSubItem, 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,10 +1,15 @@
package mcuorder
import (
"errors"
"strconv"
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"
d "github.com/karincake/dodol"
@@ -35,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 {
@@ -277,3 +287,107 @@ func Delete(input e.DeleteDto) (*d.Data, error) {
}, nil
}
func Complete(input e.ReadDetailDto) (*d.Data, error) {
var data *e.McuOrder
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() {
return errors.New("data already completed")
}
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.McuOrder
var err error
event := pl.Event{
Feature: "SetSchedule",
Source: source,
}
// Start log
pl.SetLogInfo(&event, input, "started", "setSchedule")
err = dg.I.Transaction(func(tx *gorm.DB) error {
pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail")
data, err = ReadDetailData(rdDto, &event, tx)
if err != nil {
return err
}
if data.IsCompleted() {
return errors.New("data already completed")
}
data.ExaminationDate = input.ExaminationDate
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": "setSchedule",
},
Data: data.ToResponse(),
}, nil
}
@@ -20,4 +20,9 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.McuOrder) {
data.Encounter_Id = inputSrc.Encounter_Id
data.Status_Code = inputSrc.Status_Code
data.Doctor_Id = inputSrc.Doctor_Id
data.SpecimenPickTime = inputSrc.SpecimenPickTime
data.ExaminationDate = inputSrc.ExaminationDate
data.Number = inputSrc.Number
data.Temperature = inputSrc.Temperature
data.McuUrgencyLevel_Code = inputSrc.McuUrgencyLevel_Code
}
@@ -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()
}
@@ -34,6 +34,10 @@ func Create(input e.CreateDto) (*d.Data, error) {
return err
}
if err := createItem(&input, &event, tx); err != nil {
return err
}
if resData, err := CreateData(input, &event, tx); err != nil {
return err
} else {
@@ -5,7 +5,17 @@ Any functions that are used internally by the use-case
package mcusrc
import (
ei "simrs-vx/internal/domain/main-entities/item"
e "simrs-vx/internal/domain/main-entities/mcu-src"
ui "simrs-vx/internal/use-case/main-use-case/item"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
ero "simrs-vx/internal/domain/references/organization"
"gorm.io/gorm"
)
func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.McuSrc) {
@@ -20,4 +30,22 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.McuSrc) {
data.Code = inputSrc.Code
data.Name = inputSrc.Name
data.CheckupCategory_Code = inputSrc.CheckupCategory_Code
data.Item_Id = inputSrc.Item_Id
}
func createItem(input *e.CreateDto, event *pl.Event, tx *gorm.DB) error {
itemCreate := ei.CreateDto{
Code: pu.AddPrefix("mcu-", input.Code),
Name: input.Name,
ItemGroup_Code: ero.ITGCMCU,
// Uom_Code: &input.Uom_Code,
// Infra_Id: input.Infra_Id,
}
item, err := ui.CreateData(itemCreate, event, tx)
if err != nil {
return err
}
input.Item_Id = &item.Id
return nil
}
@@ -0,0 +1,282 @@
package mcusubsrc
import (
e "simrs-vx/internal/domain/main-entities/mcu-sub-src"
"strconv"
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"
)
const source = "mcu-sub-src"
func Create(input e.CreateDto) (*d.Data, error) {
data := e.McuSubSrc{}
event := pl.Event{
Feature: "Create",
Source: source,
}
// 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 err := createItem(&input, &event, tx); err != nil {
return err
}
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 {
return err
}
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: data.ToResponse(),
}, nil
}
func ReadList(input e.ReadListDto) (*d.Data, error) {
var data *e.McuSubSrc
var dataList []e.McuSubSrc
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 len(input.Includes) > 0 {
input.Preloads = pu.GetPreloads(input.Includes)
}
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),
},
Data: e.ToResponseList(dataList),
}, nil
}
func ReadDetail(input e.ReadDetailDto) (*d.Data, error) {
var data *e.McuSubSrc
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.McuSubSrc
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
}
mwRunner := newMiddlewareRunner(&event, tx)
mwRunner.setMwType(pu.MWTPre)
// Run pre-middleware
if err := mwRunner.RunUpdateMiddleware(readDetailPreMw, &rdDto, data); err != nil {
return err
}
if err := UpdateData(input, data, &event, tx); err != nil {
return err
}
pl.SetLogInfo(&event, nil, "complete")
mwRunner.setMwType(pu.MWTPost)
// Run post-middleware
if err := mwRunner.RunUpdateMiddleware(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": "updated",
},
Data: data.ToResponse(),
}, nil
}
func Delete(input e.DeleteDto) (*d.Data, error) {
rdDto := e.ReadDetailDto{Id: input.Id}
var data *e.McuSubSrc
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
}
@@ -0,0 +1,51 @@
/*
DESCRIPTION:
Any functions that are used internally by the use-case
*/
package mcusubsrc
import (
ei "simrs-vx/internal/domain/main-entities/item"
e "simrs-vx/internal/domain/main-entities/mcu-sub-src"
ui "simrs-vx/internal/use-case/main-use-case/item"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
ero "simrs-vx/internal/domain/references/organization"
"gorm.io/gorm"
)
func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.McuSubSrc) {
var inputSrc *e.CreateDto
if inputT, ok := any(input).(*e.CreateDto); ok {
inputSrc = inputT
} else {
inputTemp := any(input).(*e.UpdateDto)
inputSrc = &inputTemp.CreateDto
}
data.Code = inputSrc.Code
data.Name = inputSrc.Name
data.McuSrc_Id = inputSrc.McuSrc_Id
data.Item_Id = inputSrc.Item_Id
}
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.ITGCMCUSub,
// Uom_Code: &input.Uom_Code,
// Infra_Id: input.Infra_Id,
}
item, err := ui.CreateData(itemCreate, event, tx)
if err != nil {
return err
}
input.Item_Id = &item.Id
return nil
}
@@ -0,0 +1,155 @@
package mcusubsrc
import (
e "simrs-vx/internal/domain/main-entities/mcu-sub-src"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
dg "github.com/karincake/apem/db-gorm-pg"
gh "github.com/karincake/getuk"
"gorm.io/gorm"
)
func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.McuSubSrc, error) {
pl.SetLogInfo(event, nil, "started", "DBCreate")
data := e.McuSubSrc{}
setData(&input, &data)
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
} else {
tx = dg.I
}
if err := tx.Create(&data).Error; err != nil {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-create-fail",
Detail: "Database insert failed",
Raw: err,
}
return nil, pl.SetLogError(event, input)
}
pl.SetLogInfo(event, nil, "complete")
return &data, nil
}
func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.McuSubSrc, *e.MetaDto, error) {
pl.SetLogInfo(event, input, "started", "DBReadList")
data := []e.McuSubSrc{}
pagination := gh.Pagination{}
count := int64(0)
meta := e.MetaDto{}
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
} else {
tx = dg.I
}
if len(input.Preloads) > 0 {
for _, preload := range input.Preloads {
tx = tx.Preload(preload)
}
}
tx = tx.
Model(&e.McuSubSrc{}).
Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-get-fail",
Detail: "Database get failed",
Raw: err,
}
return nil, nil, pl.SetLogError(event, input)
}
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.McuSubSrc, error) {
pl.SetLogInfo(event, input, "started", "DBReadDetail")
data := e.McuSubSrc{}
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
} else {
tx = dg.I
}
if err := tx.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(input e.UpdateDto, data *e.McuSubSrc, event *pl.Event, dbx ...*gorm.DB) error {
pl.SetLogInfo(event, data, "started", "DBUpdate")
setData(&input, data)
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
} else {
tx = dg.I
}
if err := tx.Save(&data).Error; err != nil {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-update-fail",
Detail: "Database update failed",
Raw: err,
}
return pl.SetLogError(event, input)
}
pl.SetLogInfo(event, nil, "complete")
return nil
}
func DeleteData(data *e.McuSubSrc, 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
}
@@ -0,0 +1,103 @@
package mcusubsrc
import (
e "simrs-vx/internal/domain/main-entities/mcu-sub-src"
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.McuSubSrc) 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.McuSubSrc) 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.McuSubSrc) 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.McuSubSrc) 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.McuSubSrc) 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 mcusubsrc
// 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 mcusubsrc
import (
"gorm.io/gorm"
e "simrs-vx/internal/domain/main-entities/mcu-sub-src"
)
type createMw struct {
Name string
Func func(input *e.CreateDto, data *e.McuSubSrc, tx *gorm.DB) error
}
type readListMw struct {
Name string
Func func(input *e.ReadListDto, data *e.McuSubSrc, tx *gorm.DB) error
}
type readDetailMw struct {
Name string
Func func(input *e.ReadDetailDto, data *e.McuSubSrc, 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
@@ -332,6 +332,10 @@ func Complete(input e.ReadDetailDto) (*d.Data, error) {
return pl.SetLogError(&event, input)
}
if err := createMedicationItemDist(&data.Id, &event, tx); err != nil {
return err
}
pl.SetLogInfo(&event, nil, "complete")
return nil
})
@@ -6,10 +6,17 @@ package medication
import (
e "simrs-vx/internal/domain/main-entities/medication"
// emi "simrs-vx/internal/domain/main-entities/medication-item"
// emid "simrs-vx/internal/domain/main-entities/medication-item-dist"
// umi "simrs-vx/internal/use-case/main-use-case/medication-item"
// umid "simrs-vx/internal/use-case/main-use-case/medication-item-dist"
emi "simrs-vx/internal/domain/main-entities/medication-item"
emid "simrs-vx/internal/domain/main-entities/medication-item-dist"
umi "simrs-vx/internal/use-case/main-use-case/medication-item"
umid "simrs-vx/internal/use-case/main-use-case/medication-item-dist"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
dg "github.com/karincake/apem/db-gorm-pg"
"gorm.io/gorm"
)
func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Medication) {
@@ -27,32 +34,33 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Medication) {
data.Status_Code = inputSrc.Status_Code
}
// func createMedicationItemDist(medication_id *uint, event *pl.Event, dbx ...*gorm.DB) error {
// pl.SetLogInfo(event, nil, "started", "createMedicationItemDist")
// var tx *gorm.DB
// if len(dbx) > 0 {
// tx = dbx[0]
// } else {
// tx = dg.I
// }
func createMedicationItemDist(medication_id *uint, event *pl.Event, dbx ...*gorm.DB) error {
pl.SetLogInfo(event, nil, "started", "createMedicationItemDist")
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
} else {
tx = dg.I
}
// filterMI := emi.ReadListDto{FilterDto: emi.FilterDto{Medication_Id: medication_id, IsRedeemed: true}}
// medicationItemList, _, err := umi.ReadListData(filterMI, event, tx)
// if err != nil {
// return err
// }
// for _, medicationItem := range medicationItemList {
// midCreate := emid.CreateDto{
// MedicationItem_Id: &medicationItem.Id,
// DateTime: medicationItem.MedicationItem.DateTime,
// Remain: medicationItem.MedicationItem.Remain,
// Nurse_Id: medicationItem.MedicationItem.Nurse_Id,
// }
// if err := umid.Create(midCreate); err != nil {
// return err
// }
// }
filterMI := emi.ReadListDto{FilterDto: emi.FilterDto{Medication_Id: medication_id, IsRedeemed: true}, Preloads: []string{"MedicineMix"}}
medicationItemList, _, err := umi.ReadListData(filterMI, event, tx)
if err != nil {
return err
}
// Nurse id isn't set here because it will be set when medItemDist is consumed by the nurse who is logged in and performing the consume action, so it isn't needed here.
for _, medicationItem := range medicationItemList {
midCreate := emid.CreateDto{
MedicationItem_Id: &medicationItem.Id,
DateTime: pu.GetTimeNow(),
Remain: medicationItem.Quantity,
}
if _, err := umid.CreateData(midCreate, event, tx); err != nil {
return err
}
// pl.SetLogInfo(event, nil, "complete")
// return nil
// }
}
pl.SetLogInfo(event, nil, "complete")
return nil
}
@@ -96,7 +96,15 @@ 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 input.Encounter_Id != nil {
tx = tx.Where("\"Encounter_Id\" = ?", *input.Encounter_Id)
}
if input.Id != 0 {
tx = tx.Where("\"Id\" = ?", input.Id)
}
if err := tx.First(&data).Error; err != nil {
if processedErr := pu.HandleReadError(err, event, source, input.Id, data); processedErr != nil {
return nil, processedErr
}
@@ -20,4 +20,5 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.MedicineMixItem) {
data.MedicineMix_Id = inputSrc.MedicineMix_Id
data.Medicine_Id = inputSrc.Medicine_Id
data.Dose = inputSrc.Dose
data.Note = inputSrc.Note
}
@@ -51,6 +51,8 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Me
tx = dg.I
}
tx = tx.Preload("MixItems")
tx = tx.
Model(&e.MedicineMix{}).
Scopes(gh.Filter(input)).
@@ -90,6 +92,8 @@ func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e
tx = dg.I
}
tx = tx.Preload("MixItems")
if err := tx.First(&data, input.Id).Error; err != nil {
if processedErr := pu.HandleReadError(err, event, source, input.Id, data); processedErr != nil {
return nil, processedErr
+3 -3
View File
@@ -172,9 +172,9 @@ func GetIdByUserId(user_id *uint, event *pl.Event, dbx ...*gorm.DB) (*uint, erro
var nurse_id uint
err := tx.Model(&e.Nurse{}).
Select("Nurse.Id as nurse_id").
Joins("JOIN Employee e ON e.Id = Nurse.Employee_Id").
Where("e.User_Id = ?", user_id).
Select("\"Nurse\".\"Id\" as nurse_id").
Joins("JOIN \"Employee\" AS e ON e.\"Id\" = \"Nurse\".\"Employee_Id\"").
Where("e.\"User_Id\" = ?", user_id).
Scan(&nurse_id).Error
if err != nil {
@@ -27,4 +27,5 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.PersonRelative) {
data.Education_Code = inputSrc.Education_Code
data.Occupation_Code = inputSrc.Occupation_Code
data.Occupation_Name = inputSrc.Occupation_Name
data.Responsible = inputSrc.Responsible
}
@@ -172,9 +172,9 @@ func GetIdByUserId(user_id *uint, event *pl.Event, dbx ...*gorm.DB) (*uint, erro
var pharmacist_id uint
err := tx.Model(&e.Pharmacist{}).
Select("Pharmacist.Id as pharmacist_id").
Joins("JOIN Employee e ON e.Id = Pharmacist.Employee_Id").
Where("e.User_Id = ?", user_id).
Select("\"Pharmacist\".\"Id\" as pharmacist_id").
Joins("JOIN \"Employee\" as e ON e.\"Id\" = \"Pharmacist\".\"Employee_Id\"").
Where("e.\"User_Id\" = ?", user_id).
Scan(&pharmacist_id).Error
if err != nil {
@@ -24,4 +24,5 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.PrescriptionItem) {
data.Usage = inputSrc.Usage
data.Interval = inputSrc.Interval
data.IntervalUnit_Code = inputSrc.IntervalUnit_Code
data.Quantity = inputSrc.Quantity
}
@@ -51,6 +51,8 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Pr
tx = dg.I
}
tx = tx.Preload("MedicineMix").Preload("MedicineMix.MixItems")
if len(input.Preloads) > 0 {
for _, preload := range input.Preloads {
tx = tx.Preload(preload)
@@ -96,6 +98,8 @@ func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e
tx = dg.I
}
tx = tx.Preload("MedicineMix").Preload("MedicineMix.MixItems")
if err := tx.First(&data, input.Id).Error; err != nil {
if processedErr := pu.HandleReadError(err, event, source, input.Id, data); processedErr != nil {
return nil, processedErr
@@ -1,10 +1,13 @@
package prescription
import (
"errors"
"strconv"
e "simrs-vx/internal/domain/main-entities/prescription"
erc "simrs-vx/internal/domain/references/common"
dg "github.com/karincake/apem/db-gorm-pg"
d "github.com/karincake/dodol"
@@ -277,3 +280,66 @@ 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.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)
}
if err := createMedication(input.Id, &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": "approved",
},
Data: data.ToResponse(),
}, nil
}
@@ -5,7 +5,23 @@ Any functions that are used internally by the use-case
package prescription
import (
em "simrs-vx/internal/domain/main-entities/medication"
emei "simrs-vx/internal/domain/main-entities/medication-item"
emi "simrs-vx/internal/domain/main-entities/medicine-mix"
emmi "simrs-vx/internal/domain/main-entities/medicine-mix-item"
e "simrs-vx/internal/domain/main-entities/prescription"
epi "simrs-vx/internal/domain/main-entities/prescription-item"
um "simrs-vx/internal/use-case/main-use-case/medication"
umei "simrs-vx/internal/use-case/main-use-case/medication-item"
umi "simrs-vx/internal/use-case/main-use-case/medicine-mix"
ummi "simrs-vx/internal/use-case/main-use-case/medicine-mix-item"
upi "simrs-vx/internal/use-case/main-use-case/prescription-item"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
"gorm.io/gorm"
)
func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Prescription) {
@@ -20,4 +36,96 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Prescription) {
data.Encounter_Id = inputSrc.Encounter_Id
data.Doctor_Id = inputSrc.Doctor_Id
data.IssuedAt = inputSrc.IssuedAt
data.Status_Code = inputSrc.Status_Code
}
func createMedication(prescription_id uint, event *pl.Event, tx *gorm.DB) error {
pl.SetLogInfo(event, nil, "started", "createMedication")
prescription, err := ReadDetailData(e.ReadDetailDto{Id: prescription_id}, event, tx)
if err != nil {
return err
}
prescriptionItem, _, err := upi.ReadListData(epi.ReadListDto{FilterDto: epi.FilterDto{Prescription_Id: &prescription.Id}}, event, tx)
if err != nil {
return err
}
if len(prescriptionItem) == 0 {
return nil
}
medicationCreate := em.CreateDto{
Encounter_Id: prescription.Encounter_Id,
IssuedAt: pu.GetTimeNow(),
}
medication, err := um.CreateData(medicationCreate, event, tx)
if err != nil {
return err
}
for _, prescriptionItem := range prescriptionItem {
if prescriptionItem.IsMix {
medMix_id, err := createMedicineMixAndItem(*prescriptionItem.MedicineMix, event, tx)
if err != nil {
return err
}
prescriptionItem.MedicineMix_Id = medMix_id
}
err := createMedicationItem(medication.Id, prescriptionItem, event, tx)
if err != nil {
return err
}
}
return nil
}
func createMedicineMixAndItem(input emi.MedicineMix, event *pl.Event, tx *gorm.DB) (*uint, error) {
pl.SetLogInfo(event, nil, "started", "createMedicineMix")
medicineMixCreate := emi.CreateDto{
Name: input.Name,
}
medicineMix, err := umi.CreateData(medicineMixCreate, event, tx)
if err != nil {
return nil, err
}
// recreate medicineMixItem with new medicineMix_id to keep medMixItem remain the same for prescriptionItem that is created
for _, medicineMixItem := range input.MixItems {
medicineMixItemCreate := emmi.CreateDto{
MedicineMix_Id: &medicineMix.Id,
Medicine_Id: medicineMixItem.Medicine_Id,
Dose: medicineMixItem.Dose,
}
_, err := ummi.CreateData(medicineMixItemCreate, event, tx)
if err != nil {
return nil, err
}
}
return &medicineMix.Id, nil
}
func createMedicationItem(medication_id uint, input epi.PrescriptionItem, event *pl.Event, tx *gorm.DB) error {
pl.SetLogInfo(event, nil, "started", "createMedicationItem")
medicationItemCreate := emei.CreateDto{
Medication_Id: &medication_id,
IsMix: input.IsMix,
Medicine_Id: input.Medicine_Id,
MedicineMix_Id: input.MedicineMix_Id,
Usage: input.Usage,
Interval: input.Interval,
IntervalUnit_Code: input.IntervalUnit_Code,
Quantity: input.Quantity,
}
_, err := umei.CreateData(medicationItemCreate, event, tx)
if err != nil {
return err
}
return nil
}
@@ -96,7 +96,15 @@ 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 input.Encounter_Id != nil {
tx = tx.Where("\"Encounter_Id\" = ?", *input.Encounter_Id)
}
if input.Id != 0 {
tx = tx.Where("\"Id\" = ?", input.Id)
}
if err := tx.First(&data).Error; err != nil {
if processedErr := pu.HandleReadError(err, event, source, input.Id, data); processedErr != nil {
return nil, processedErr
}
+13
View File
@@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"strings"
"time"
pl "simrs-vx/pkg/logger"
@@ -102,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
}
@@ -126,3 +134,8 @@ func kebabToPascal(input string) string {
}
return strings.Join(parts, "")
}
func GetTimeNow() *time.Time {
tmp := time.Now()
return &tmp
}