diff --git a/internal/domain/main-entities/mcu-order-item/dto.go b/internal/domain/main-entities/mcu-order-item/dto.go index 91ce3bdc..24aba1b8 100644 --- a/internal/domain/main-entities/mcu-order-item/dto.go +++ b/internal/domain/main-entities/mcu-order-item/dto.go @@ -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 diff --git a/internal/domain/main-entities/mcu-order-item/entity.go b/internal/domain/main-entities/mcu-order-item/entity.go index f1ae0cc8..6a4441d0 100644 --- a/internal/domain/main-entities/mcu-order-item/entity.go +++ b/internal/domain/main-entities/mcu-order-item/entity.go @@ -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 +} diff --git a/internal/domain/main-entities/mcu-order-sub-item/dto.go b/internal/domain/main-entities/mcu-order-sub-item/dto.go index d59d2ccf..cb250200 100644 --- a/internal/domain/main-entities/mcu-order-sub-item/dto.go +++ b/internal/domain/main-entities/mcu-order-sub-item/dto.go @@ -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 { 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/domain/main-entities/mcu-order/dto.go b/internal/domain/main-entities/mcu-order/dto.go index 418fb02c..4dcabce4 100644 --- a/internal/domain/main-entities/mcu-order/dto.go +++ b/internal/domain/main-entities/mcu-order/dto.go @@ -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 diff --git a/internal/domain/main-entities/mcu-order/entity.go b/internal/domain/main-entities/mcu-order/entity.go index 134485e5..96721caf 100644 --- a/internal/domain/main-entities/mcu-order/entity.go +++ b/internal/domain/main-entities/mcu-order/entity.go @@ -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 +} diff --git a/internal/domain/main-entities/mcu-src/dto.go b/internal/domain/main-entities/mcu-src/dto.go index 56ab9f57..2d0e9827 100644 --- a/internal/domain/main-entities/mcu-src/dto.go +++ b/internal/domain/main-entities/mcu-src/dto.go @@ -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 { diff --git a/internal/domain/main-entities/mcu-sub-src/dto.go b/internal/domain/main-entities/mcu-sub-src/dto.go index eec34ead..a6d0a804 100644 --- a/internal/domain/main-entities/mcu-sub-src/dto.go +++ b/internal/domain/main-entities/mcu-sub-src/dto.go @@ -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 { diff --git a/internal/domain/main-entities/medication-item/dto.go b/internal/domain/main-entities/medication-item/dto.go index 00edb045..ce2f9193 100644 --- a/internal/domain/main-entities/medication-item/dto.go +++ b/internal/domain/main-entities/medication-item/dto.go @@ -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 diff --git a/internal/domain/main-entities/medication/dto.go b/internal/domain/main-entities/medication/dto.go index 7242b9d5..86c77b2f 100644 --- a/internal/domain/main-entities/medication/dto.go +++ b/internal/domain/main-entities/medication/dto.go @@ -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 { diff --git a/internal/domain/main-entities/medicine-mix-item/dto.go b/internal/domain/main-entities/medicine-mix-item/dto.go index 1be930e1..b00114c5 100644 --- a/internal/domain/main-entities/medicine-mix-item/dto.go +++ b/internal/domain/main-entities/medicine-mix-item/dto.go @@ -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 diff --git a/internal/domain/main-entities/person-relative/dto.go b/internal/domain/main-entities/person-relative/dto.go index 4f28cbf8..deb29886 100644 --- a/internal/domain/main-entities/person-relative/dto.go +++ b/internal/domain/main-entities/person-relative/dto.go @@ -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 } diff --git a/internal/domain/main-entities/prescription-item/dto.go b/internal/domain/main-entities/prescription-item/dto.go index f23a6610..f46b8bc9 100644 --- a/internal/domain/main-entities/prescription-item/dto.go +++ b/internal/domain/main-entities/prescription-item/dto.go @@ -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 diff --git a/internal/domain/main-entities/prescription/dto.go b/internal/domain/main-entities/prescription/dto.go index b87d6f12..107509e1 100644 --- a/internal/domain/main-entities/prescription/dto.go +++ b/internal/domain/main-entities/prescription/dto.go @@ -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 diff --git a/internal/domain/main-entities/prescription/entity.go b/internal/domain/main-entities/prescription/entity.go index 20386bf4..bdc2d2fb 100644 --- a/internal/domain/main-entities/prescription/entity.go +++ b/internal/domain/main-entities/prescription/entity.go @@ -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 +} diff --git a/internal/domain/references/organization/organization.go b/internal/domain/references/organization/organization.go index 30aa25b5..1f655466 100644 --- a/internal/domain/references/organization/organization.go +++ b/internal/domain/references/organization/organization.go @@ -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" diff --git a/internal/interface/main-handler/encounter/handler.go b/internal/interface/main-handler/encounter/handler.go index c2634a91..7484b302 100644 --- a/internal/interface/main-handler/encounter/handler.go +++ b/internal/interface/main-handler/encounter/handler.go @@ -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) } diff --git a/internal/interface/main-handler/main-handler.go b/internal/interface/main-handler/main-handler.go index cc14eaf1..930e30f1 100644 --- a/internal/interface/main-handler/main-handler.go +++ b/internal/interface/main-handler/main-handler.go @@ -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) diff --git a/internal/interface/main-handler/mcu-order-item/handler.go b/internal/interface/main-handler/mcu-order-item/handler.go index a3a4bcc8..75f5ad6a 100644 --- a/internal/interface/main-handler/mcu-order-item/handler.go +++ b/internal/interface/main-handler/mcu-order-item/handler.go @@ -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) +} diff --git a/internal/interface/main-handler/mcu-order-sub-item/handler.go b/internal/interface/main-handler/mcu-order-sub-item/handler.go new file mode 100644 index 00000000..8e8f8c79 --- /dev/null +++ b/internal/interface/main-handler/mcu-order-sub-item/handler.go @@ -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) +} diff --git a/internal/interface/main-handler/mcu-order/handler.go b/internal/interface/main-handler/mcu-order/handler.go index 77e19669..44a635a5 100644 --- a/internal/interface/main-handler/mcu-order/handler.go +++ b/internal/interface/main-handler/mcu-order/handler.go @@ -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) +} diff --git a/internal/interface/main-handler/mcu-sub-src/handler.go b/internal/interface/main-handler/mcu-sub-src/handler.go new file mode 100644 index 00000000..949be715 --- /dev/null +++ b/internal/interface/main-handler/mcu-sub-src/handler.go @@ -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) +} diff --git a/internal/interface/main-handler/medication/handler.go b/internal/interface/main-handler/medication/handler.go index b847eb5b..272eae56 100644 --- a/internal/interface/main-handler/medication/handler.go +++ b/internal/interface/main-handler/medication/handler.go @@ -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) } diff --git a/internal/interface/main-handler/prescription/handler.go b/internal/interface/main-handler/prescription/handler.go index 25ee9469..fe73e3fe 100644 --- a/internal/interface/main-handler/prescription/handler.go +++ b/internal/interface/main-handler/prescription/handler.go @@ -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) +} 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/device/helper.go b/internal/use-case/main-use-case/device/helper.go index 63d51664..08964464 100644 --- a/internal/use-case/main-use-case/device/helper.go +++ b/internal/use-case/main-use-case/device/helper.go @@ -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 { diff --git a/internal/use-case/main-use-case/encounter/case.go b/internal/use-case/main-use-case/encounter/case.go index ed8fa816..c63579cf 100644 --- a/internal/use-case/main-use-case/encounter/case.go +++ b/internal/use-case/main-use-case/encounter/case.go @@ -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 diff --git a/internal/use-case/main-use-case/encounter/helper.go b/internal/use-case/main-use-case/encounter/helper.go index b40783b7..5bf73d14 100644 --- a/internal/use-case/main-use-case/encounter/helper.go +++ b/internal/use-case/main-use-case/encounter/helper.go @@ -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 +} 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/material/helper.go b/internal/use-case/main-use-case/material/helper.go index ce0d8a2e..9cfefe27 100644 --- a/internal/use-case/main-use-case/material/helper.go +++ b/internal/use-case/main-use-case/material/helper.go @@ -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 { 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 74323143..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 @@ -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 +} diff --git a/internal/use-case/main-use-case/mcu-order-item/helper.go b/internal/use-case/main-use-case/mcu-order-item/helper.go index 48eaaf09..a2694ecd 100644 --- a/internal/use-case/main-use-case/mcu-order-item/helper.go +++ b/internal/use-case/main-use-case/mcu-order-item/helper.go @@ -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 } 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 new file mode 100644 index 00000000..88684bff --- /dev/null +++ b/internal/use-case/main-use-case/mcu-order-sub-item/case.go @@ -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 +} diff --git a/internal/use-case/main-use-case/mcu-order-sub-item/helper.go b/internal/use-case/main-use-case/mcu-order-sub-item/helper.go new file mode 100644 index 00000000..f8d9c30f --- /dev/null +++ b/internal/use-case/main-use-case/mcu-order-sub-item/helper.go @@ -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 +} diff --git a/internal/use-case/main-use-case/mcu-order-sub-item/lib.go b/internal/use-case/main-use-case/mcu-order-sub-item/lib.go new file mode 100644 index 00000000..edfee9cd --- /dev/null +++ b/internal/use-case/main-use-case/mcu-order-sub-item/lib.go @@ -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 +} diff --git a/internal/use-case/main-use-case/mcu-order-sub-item/middleware-runner.go b/internal/use-case/main-use-case/mcu-order-sub-item/middleware-runner.go new file mode 100644 index 00000000..04b7323f --- /dev/null +++ b/internal/use-case/main-use-case/mcu-order-sub-item/middleware-runner.go @@ -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 +} diff --git a/internal/use-case/main-use-case/mcu-order-sub-item/middleware.go b/internal/use-case/main-use-case/mcu-order-sub-item/middleware.go new file mode 100644 index 00000000..8dda3302 --- /dev/null +++ b/internal/use-case/main-use-case/mcu-order-sub-item/middleware.go @@ -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}, +// ) +// } diff --git a/internal/use-case/main-use-case/mcu-order-sub-item/tycovar.go b/internal/use-case/main-use-case/mcu-order-sub-item/tycovar.go new file mode 100644 index 00000000..58b67a88 --- /dev/null +++ b/internal/use-case/main-use-case/mcu-order-sub-item/tycovar.go @@ -0,0 +1,44 @@ +/* +DESCRIPTION: +A sample, part of the package that contains type, constants, and/or variables. + +In this sample it also provides type and variable regarding the needs of the +middleware to separate from main use-case which has the basic CRUD +functionality. The purpose of this is to make the code more maintainable. +*/ +package 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 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 b000ffc8..158a4995 100644 --- a/internal/use-case/main-use-case/mcu-order/case.go +++ b/internal/use-case/main-use-case/mcu-order/case.go @@ -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 +} diff --git a/internal/use-case/main-use-case/mcu-order/helper.go b/internal/use-case/main-use-case/mcu-order/helper.go index cb0b9878..65c95bff 100644 --- a/internal/use-case/main-use-case/mcu-order/helper.go +++ b/internal/use-case/main-use-case/mcu-order/helper.go @@ -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 } 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-src/case.go b/internal/use-case/main-use-case/mcu-src/case.go index ae7a1860..f0e7589a 100644 --- a/internal/use-case/main-use-case/mcu-src/case.go +++ b/internal/use-case/main-use-case/mcu-src/case.go @@ -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 { diff --git a/internal/use-case/main-use-case/mcu-src/helper.go b/internal/use-case/main-use-case/mcu-src/helper.go index 820dbfa7..3c7dc31c 100644 --- a/internal/use-case/main-use-case/mcu-src/helper.go +++ b/internal/use-case/main-use-case/mcu-src/helper.go @@ -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 } diff --git a/internal/use-case/main-use-case/mcu-sub-src/case.go b/internal/use-case/main-use-case/mcu-sub-src/case.go new file mode 100644 index 00000000..e977931f --- /dev/null +++ b/internal/use-case/main-use-case/mcu-sub-src/case.go @@ -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 + +} 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 new file mode 100644 index 00000000..95444d5a --- /dev/null +++ b/internal/use-case/main-use-case/mcu-sub-src/helper.go @@ -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 +} diff --git a/internal/use-case/main-use-case/mcu-sub-src/lib.go b/internal/use-case/main-use-case/mcu-sub-src/lib.go new file mode 100644 index 00000000..711dabdd --- /dev/null +++ b/internal/use-case/main-use-case/mcu-sub-src/lib.go @@ -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 +} diff --git a/internal/use-case/main-use-case/mcu-sub-src/middleware-runner.go b/internal/use-case/main-use-case/mcu-sub-src/middleware-runner.go new file mode 100644 index 00000000..89d328ed --- /dev/null +++ b/internal/use-case/main-use-case/mcu-sub-src/middleware-runner.go @@ -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 +} diff --git a/internal/use-case/main-use-case/mcu-sub-src/middleware.go b/internal/use-case/main-use-case/mcu-sub-src/middleware.go new file mode 100644 index 00000000..a58ac781 --- /dev/null +++ b/internal/use-case/main-use-case/mcu-sub-src/middleware.go @@ -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}, +// ) +// } diff --git a/internal/use-case/main-use-case/mcu-sub-src/tycovar.go b/internal/use-case/main-use-case/mcu-sub-src/tycovar.go new file mode 100644 index 00000000..7522ada4 --- /dev/null +++ b/internal/use-case/main-use-case/mcu-sub-src/tycovar.go @@ -0,0 +1,44 @@ +/* +DESCRIPTION: +A sample, part of the package that contains type, constants, and/or variables. + +In this sample it also provides type and variable regarding the needs of the +middleware to separate from main use-case which has the basic CRUD +functionality. The purpose of this is to make the code more maintainable. +*/ +package 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 diff --git a/internal/use-case/main-use-case/medication/case.go b/internal/use-case/main-use-case/medication/case.go index ec096f29..c4a97373 100644 --- a/internal/use-case/main-use-case/medication/case.go +++ b/internal/use-case/main-use-case/medication/case.go @@ -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 }) diff --git a/internal/use-case/main-use-case/medication/helper.go b/internal/use-case/main-use-case/medication/helper.go index 52676431..63290cb1 100644 --- a/internal/use-case/main-use-case/medication/helper.go +++ b/internal/use-case/main-use-case/medication/helper.go @@ -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 +} diff --git a/internal/use-case/main-use-case/medication/lib.go b/internal/use-case/main-use-case/medication/lib.go index 95488f11..227eb27b 100644 --- a/internal/use-case/main-use-case/medication/lib.go +++ b/internal/use-case/main-use-case/medication/lib.go @@ -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 } diff --git a/internal/use-case/main-use-case/medicine-mix-item/helper.go b/internal/use-case/main-use-case/medicine-mix-item/helper.go index d4ac8020..0a64f30c 100644 --- a/internal/use-case/main-use-case/medicine-mix-item/helper.go +++ b/internal/use-case/main-use-case/medicine-mix-item/helper.go @@ -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 } diff --git a/internal/use-case/main-use-case/medicine-mix/lib.go b/internal/use-case/main-use-case/medicine-mix/lib.go index 6a2cf257..162399db 100644 --- a/internal/use-case/main-use-case/medicine-mix/lib.go +++ b/internal/use-case/main-use-case/medicine-mix/lib.go @@ -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 diff --git a/internal/use-case/main-use-case/nurse/lib.go b/internal/use-case/main-use-case/nurse/lib.go index 468b41c2..adbd1b76 100644 --- a/internal/use-case/main-use-case/nurse/lib.go +++ b/internal/use-case/main-use-case/nurse/lib.go @@ -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 { diff --git a/internal/use-case/main-use-case/person-relative/helper.go b/internal/use-case/main-use-case/person-relative/helper.go index 48883d5a..b0624521 100644 --- a/internal/use-case/main-use-case/person-relative/helper.go +++ b/internal/use-case/main-use-case/person-relative/helper.go @@ -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 } diff --git a/internal/use-case/main-use-case/pharmacist/lib.go b/internal/use-case/main-use-case/pharmacist/lib.go index e9478d70..0038591a 100644 --- a/internal/use-case/main-use-case/pharmacist/lib.go +++ b/internal/use-case/main-use-case/pharmacist/lib.go @@ -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 { diff --git a/internal/use-case/main-use-case/prescription-item/helper.go b/internal/use-case/main-use-case/prescription-item/helper.go index 000522d5..47efc3f9 100644 --- a/internal/use-case/main-use-case/prescription-item/helper.go +++ b/internal/use-case/main-use-case/prescription-item/helper.go @@ -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 } diff --git a/internal/use-case/main-use-case/prescription-item/lib.go b/internal/use-case/main-use-case/prescription-item/lib.go index 800096fd..70913046 100644 --- a/internal/use-case/main-use-case/prescription-item/lib.go +++ b/internal/use-case/main-use-case/prescription-item/lib.go @@ -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 diff --git a/internal/use-case/main-use-case/prescription/case.go b/internal/use-case/main-use-case/prescription/case.go index 9b0baeb2..ce9bc9ba 100644 --- a/internal/use-case/main-use-case/prescription/case.go +++ b/internal/use-case/main-use-case/prescription/case.go @@ -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 + +} diff --git a/internal/use-case/main-use-case/prescription/helper.go b/internal/use-case/main-use-case/prescription/helper.go index 768d11bd..7c61469b 100644 --- a/internal/use-case/main-use-case/prescription/helper.go +++ b/internal/use-case/main-use-case/prescription/helper.go @@ -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 } diff --git a/internal/use-case/main-use-case/prescription/lib.go b/internal/use-case/main-use-case/prescription/lib.go index bf1fe36b..bff59916 100644 --- a/internal/use-case/main-use-case/prescription/lib.go +++ b/internal/use-case/main-use-case/prescription/lib.go @@ -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 } diff --git a/pkg/use-case-helper/use-case-helper.go b/pkg/use-case-helper/use-case-helper.go index a16a9ba2..04a8eada 100644 --- a/pkg/use-case-helper/use-case-helper.go +++ b/pkg/use-case-helper/use-case-helper.go @@ -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 +}