From 86a073164da8f828303bc59f6a78d6d62d37f3fd Mon Sep 17 00:00:00 2001 From: dpurbosakti Date: Wed, 17 Sep 2025 11:47:03 +0700 Subject: [PATCH] wip encounter + medication --- .../main-entities/medication-item/dto.go | 8 +++ .../domain/main-entities/medication/dto.go | 7 +- .../main-entities/prescription-item/dto.go | 4 ++ .../domain/main-entities/prescription/dto.go | 36 ++++++---- .../main-handler/medication/handler.go | 8 +-- .../main-handler/prescription/handler.go | 6 +- .../main-use-case/encounter/helper.go | 51 ++++++++++++++ .../use-case/main-use-case/medication/case.go | 4 ++ .../main-use-case/medication/helper.go | 69 ++++++++++--------- .../use-case/main-use-case/medication/lib.go | 10 ++- .../main-use-case/prescription-item/helper.go | 1 + .../main-use-case/prescription/helper.go | 1 + .../main-use-case/prescription/lib.go | 10 ++- pkg/use-case-helper/use-case-helper.go | 6 ++ 14 files changed, 164 insertions(+), 57 deletions(-) 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/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..e693a1c2 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/interface/main-handler/medication/handler.go b/internal/interface/main-handler/medication/handler.go index b847eb5b..5037f2eb 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) } @@ -88,7 +88,7 @@ func (obj myBase) Complete(w http.ResponseWriter, r *http.Request) { 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..1ac30d97 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,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) } diff --git a/internal/use-case/main-use-case/encounter/helper.go b/internal/use-case/main-use-case/encounter/helper.go index b40783b7..94f196bb 100644 --- a/internal/use-case/main-use-case/encounter/helper.go +++ b/internal/use-case/main-use-case/encounter/helper.go @@ -8,7 +8,17 @@ import ( "errors" e "simrs-vx/internal/domain/main-entities/encounter" es "simrs-vx/internal/domain/main-entities/soapi" + + // ep "simrs-vx/internal/domain/main-entities/prescription" + // epi "simrs-vx/internal/domain/main-entities/prescription-item" + // em "simrs-vx/internal/domain/main-entities/medication" + + // up "simrs-vx/internal/use-case/main-use-case/prescription" + // upi "simrs-vx/internal/use-case/main-use-case/prescription-item" + // um "simrs-vx/internal/use-case/main-use-case/medication" + 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 +108,44 @@ 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{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 { +// continue +// } +// // medication, err := um.ReadDetailData(e.ReadDetailDto{Id: prescriptionItem.Medication_Id}, event, tx) +// // if err != nil { +// // return err +// // } +// // if medication.IsCompleted() { +// // continue +// // } +// // createMedicationItemDist(medication.Id, event, tx) +// } +// } 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..374eaf1f 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,32 @@ 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}} + 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/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/helper.go b/internal/use-case/main-use-case/prescription/helper.go index 768d11bd..13f8f2e6 100644 --- a/internal/use-case/main-use-case/prescription/helper.go +++ b/internal/use-case/main-use-case/prescription/helper.go @@ -20,4 +20,5 @@ 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 } 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..9fd8351d 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" @@ -126,3 +127,8 @@ func kebabToPascal(input string) string { } return strings.Join(parts, "") } + +func GetTimeNow() *time.Time { + tmp := time.Now() + return &tmp +}