From 45d687c5ec4d6c414a9ce208c9ee53d3c5c414b2 Mon Sep 17 00:00:00 2001 From: dpurbosakti Date: Mon, 15 Sep 2025 14:07:30 +0700 Subject: [PATCH 1/6] wip --- .../main-entities/device-order-item/dto.go | 72 ++++++++++++++ .../main-entities/device-order-item/entity.go | 15 +++ .../domain/main-entities/device-order/dto.go | 65 +++++++++++++ .../main-entities/device-order/entity.go | 12 +++ .../main-entities/material-order-item/dto.go | 76 +++++++++++++++ .../material-order-item/entity.go | 16 ++++ .../main-entities/material-order/dto.go | 65 +++++++++++++ .../main-entities/material-order/entity.go | 12 +++ .../main-entities/mcu-order-item/dto.go | 81 ++++++++++++++++ .../main-entities/mcu-order-item/entity.go | 19 ++++ .../domain/main-entities/mcu-order/dto.go | 77 +++++++++++++++ .../domain/main-entities/mcu-order/entity.go | 18 ++++ .../main-entities/medication-item-dist/dto.go | 74 +++++++++++++++ .../medication-item-dist/entity.go | 15 +++ .../main-entities/medication-item/dto.go | 94 +++++++++++++++++++ .../main-entities/medication-item/entity.go | 22 +++++ .../domain/main-entities/medication/dto.go | 77 +++++++++++++++ .../domain/main-entities/medication/entity.go | 18 ++++ .../main-entities/prescription-item/dto.go | 91 ++++++++++++++++++ .../main-entities/prescription-item/entity.go | 22 +++++ .../domain/main-entities/prescription/dto.go | 77 +++++++++++++++ .../main-entities/prescription/entity.go | 17 ++++ 22 files changed, 1035 insertions(+) create mode 100644 internal/domain/main-entities/device-order-item/dto.go create mode 100644 internal/domain/main-entities/device-order-item/entity.go create mode 100644 internal/domain/main-entities/device-order/dto.go create mode 100644 internal/domain/main-entities/device-order/entity.go create mode 100644 internal/domain/main-entities/material-order-item/dto.go create mode 100644 internal/domain/main-entities/material-order-item/entity.go create mode 100644 internal/domain/main-entities/material-order/dto.go create mode 100644 internal/domain/main-entities/material-order/entity.go create mode 100644 internal/domain/main-entities/mcu-order-item/dto.go create mode 100644 internal/domain/main-entities/mcu-order-item/entity.go create mode 100644 internal/domain/main-entities/mcu-order/dto.go create mode 100644 internal/domain/main-entities/mcu-order/entity.go create mode 100644 internal/domain/main-entities/medication-item-dist/dto.go create mode 100644 internal/domain/main-entities/medication-item-dist/entity.go create mode 100644 internal/domain/main-entities/medication-item/dto.go create mode 100644 internal/domain/main-entities/medication-item/entity.go create mode 100644 internal/domain/main-entities/medication/dto.go create mode 100644 internal/domain/main-entities/medication/entity.go create mode 100644 internal/domain/main-entities/prescription-item/dto.go create mode 100644 internal/domain/main-entities/prescription-item/entity.go create mode 100644 internal/domain/main-entities/prescription/dto.go create mode 100644 internal/domain/main-entities/prescription/entity.go diff --git a/internal/domain/main-entities/device-order-item/dto.go b/internal/domain/main-entities/device-order-item/dto.go new file mode 100644 index 00000000..8b29a332 --- /dev/null +++ b/internal/domain/main-entities/device-order-item/dto.go @@ -0,0 +1,72 @@ +package deviceorderitem + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + ed "simrs-vx/internal/domain/main-entities/device" + edo "simrs-vx/internal/domain/main-entities/device-order" +) + +type CreateDto struct { + DeviceOrder_Id *uint `json:"deviceOrder_id"` + Device_Id *uint `json:"device_id"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Preloads []string `json:"-"` +} + +type FilterDto struct { + DeviceOrder_Id *uint `json:"deviceOrder_id"` + Device_Id *uint `json:"device_id"` + + Page int `json:"page"` + PageSize int `json:"page_size"` + NoPagination int `json:"no_pagination"` +} +type ReadDetailDto struct { + Id uint16 `json:"id"` +} + +type UpdateDto struct { + Id uint16 `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint16 `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.Main + DeviceOrder_Id *uint `json:"deviceOrder_id"` + DeviceOrder *edo.DeviceOrder `json:"deviceOrder,omitempty"` + Device_Id *uint `json:"device_id"` + Device *ed.Device `json:"device,omitempty"` +} + +func (d DeviceOrderItem) ToResponse() ResponseDto { + resp := ResponseDto{ + DeviceOrder_Id: d.DeviceOrder_Id, + DeviceOrder: d.DeviceOrder, + Device_Id: d.Device_Id, + Device: d.Device, + } + resp.Main = d.Main + return resp +} + +func ToResponseList(data []DeviceOrderItem) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/device-order-item/entity.go b/internal/domain/main-entities/device-order-item/entity.go new file mode 100644 index 00000000..536f0e13 --- /dev/null +++ b/internal/domain/main-entities/device-order-item/entity.go @@ -0,0 +1,15 @@ +package deviceorderitem + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + ed "simrs-vx/internal/domain/main-entities/device" + edo "simrs-vx/internal/domain/main-entities/device-order" +) + +type DeviceOrderItem struct { + ecore.Main // adjust this according to the needs + DeviceOrder_Id *uint `json:"deviceOrder_id"` + DeviceOrder *edo.DeviceOrder `json:"deviceOrder,omitempty" gorm:"foreignKey:DeviceOrder_Id;references:Id"` + Device_Id *uint `json:"device_id"` + Device *ed.Device `json:"device,omitempty" gorm:"foreignKey:Device_Id;references:Id"` +} diff --git a/internal/domain/main-entities/device-order/dto.go b/internal/domain/main-entities/device-order/dto.go new file mode 100644 index 00000000..cf2fc5ff --- /dev/null +++ b/internal/domain/main-entities/device-order/dto.go @@ -0,0 +1,65 @@ +package deviceorder + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + ee "simrs-vx/internal/domain/main-entities/encounter" +) + +type CreateDto struct { + Encounter_Id *uint `json:"encounter_id"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Preloads []string `json:"-"` +} + +type FilterDto struct { + Encounter_Id *uint `json:"encounter_id"` + + Page int `json:"page"` + PageSize int `json:"page_size"` + NoPagination int `json:"no_pagination"` +} +type ReadDetailDto struct { + Id uint16 `json:"id"` +} + +type UpdateDto struct { + Id uint16 `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint16 `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + 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"` +} + +func (d DeviceOrder) ToResponse() ResponseDto { + resp := ResponseDto{ + Encounter_Id: d.Encounter_Id, + Encounter: d.Encounter, + } + resp.Main = d.Main + return resp +} + +func ToResponseList(data []DeviceOrder) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/device-order/entity.go b/internal/domain/main-entities/device-order/entity.go new file mode 100644 index 00000000..b07067fc --- /dev/null +++ b/internal/domain/main-entities/device-order/entity.go @@ -0,0 +1,12 @@ +package deviceorder + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + ee "simrs-vx/internal/domain/main-entities/encounter" +) + +type DeviceOrder struct { + ecore.Main // adjust this according to the needs + Encounter_Id *uint `json:"encounter_id"` + Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"` +} diff --git a/internal/domain/main-entities/material-order-item/dto.go b/internal/domain/main-entities/material-order-item/dto.go new file mode 100644 index 00000000..81882e51 --- /dev/null +++ b/internal/domain/main-entities/material-order-item/dto.go @@ -0,0 +1,76 @@ +package materialorderitem + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + em "simrs-vx/internal/domain/main-entities/material" + emo "simrs-vx/internal/domain/main-entities/material-order" +) + +type CreateDto struct { + MaterialOrder_Id *uint `json:"materialOrder_id"` + Material_Id *uint `json:"material_id"` + Count *uint16 `json:"count"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Preloads []string `json:"-"` +} + +type FilterDto struct { + MaterialOrder_Id *uint `json:"materialOrder_id"` + Material_Id *uint `json:"material_id"` + Count *uint16 `json:"count"` + + Page int `json:"page"` + PageSize int `json:"page_size"` + NoPagination int `json:"no_pagination"` +} +type ReadDetailDto struct { + Id uint16 `json:"id"` +} + +type UpdateDto struct { + Id uint16 `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint16 `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.Main + MaterialOrder_Id *uint `json:"materialOrder_id"` + MaterialOrder *emo.MaterialOrder `json:"materialOrder,omitempty"` + Material_Id *uint `json:"material_id"` + Material *em.Material `json:"material,omitempty"` + Count *uint16 `json:"count"` +} + +func (d MaterialOrderItem) ToResponse() ResponseDto { + resp := ResponseDto{ + MaterialOrder_Id: d.MaterialOrder_Id, + MaterialOrder: d.MaterialOrder, + Material_Id: d.Material_Id, + Material: d.Material, + Count: d.Count, + } + resp.Main = d.Main + return resp +} + +func ToResponseList(data []MaterialOrderItem) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/material-order-item/entity.go b/internal/domain/main-entities/material-order-item/entity.go new file mode 100644 index 00000000..432a36b9 --- /dev/null +++ b/internal/domain/main-entities/material-order-item/entity.go @@ -0,0 +1,16 @@ +package materialorderitem + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + em "simrs-vx/internal/domain/main-entities/material" + emo "simrs-vx/internal/domain/main-entities/material-order" +) + +type MaterialOrderItem struct { + ecore.Main // adjust this according to the needs + MaterialOrder_Id *uint `json:"materialOrder_id"` + MaterialOrder *emo.MaterialOrder `json:"materialOrder,omitempty" gorm:"foreignKey:MaterialOrder_Id;references:Id"` + Material_Id *uint `json:"material_id"` + Material *em.Material `json:"material,omitempty" gorm:"foreignKey:Material_Id;references:Id"` + Count *uint16 `json:"count"` +} diff --git a/internal/domain/main-entities/material-order/dto.go b/internal/domain/main-entities/material-order/dto.go new file mode 100644 index 00000000..475ef7f8 --- /dev/null +++ b/internal/domain/main-entities/material-order/dto.go @@ -0,0 +1,65 @@ +package materialorder + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + ee "simrs-vx/internal/domain/main-entities/encounter" +) + +type CreateDto struct { + Encounter_Id *uint `json:"encounter_id"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Preloads []string `json:"-"` +} + +type FilterDto struct { + Encounter_Id *uint `json:"encounter_id"` + + Page int `json:"page"` + PageSize int `json:"page_size"` + NoPagination int `json:"no_pagination"` +} +type ReadDetailDto struct { + Id uint16 `json:"id"` +} + +type UpdateDto struct { + Id uint16 `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint16 `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + 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"` +} + +func (d MaterialOrder) ToResponse() ResponseDto { + resp := ResponseDto{ + Encounter_Id: d.Encounter_Id, + Encounter: d.Encounter, + } + resp.Main = d.Main + return resp +} + +func ToResponseList(data []MaterialOrder) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/material-order/entity.go b/internal/domain/main-entities/material-order/entity.go new file mode 100644 index 00000000..566659d3 --- /dev/null +++ b/internal/domain/main-entities/material-order/entity.go @@ -0,0 +1,12 @@ +package materialorder + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + ee "simrs-vx/internal/domain/main-entities/encounter" +) + +type MaterialOrder struct { + ecore.Main // adjust this according to the needs + Encounter_Id *uint `json:"encounter_id"` + Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"` +} diff --git a/internal/domain/main-entities/mcu-order-item/dto.go b/internal/domain/main-entities/mcu-order-item/dto.go new file mode 100644 index 00000000..91ce3bdc --- /dev/null +++ b/internal/domain/main-entities/mcu-order-item/dto.go @@ -0,0 +1,81 @@ +package mcuorderitem + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + 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" +) + +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"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Preloads []string `json:"-"` +} + +type FilterDto struct { + McuOrder_Id *uint `json:"mcuOrder_id"` + McuSrc_Id *uint `json:"mcuSrc_id"` + Result *string `json:"result"` + 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"` +} + +type UpdateDto struct { + Id uint16 `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint16 `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +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"` +} + +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, + } + resp.Main = d.Main + return resp +} + +func ToResponseList(data []McuOrderItem) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/mcu-order-item/entity.go b/internal/domain/main-entities/mcu-order-item/entity.go new file mode 100644 index 00000000..73b56a95 --- /dev/null +++ b/internal/domain/main-entities/mcu-order-item/entity.go @@ -0,0 +1,19 @@ +package mcuorderitem + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + 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" +) + +type McuOrderItem struct { + ecore.Main // adjust this according to the needs + McuOrder_Id *uint `json:"mcuOrder_id"` + McuOrder *emo.McuOrder `json:"mcuOrder,omitempty" gorm:"foreignKey:McuOrder_Id;references:Id"` + McuSrc_Id *uint `json:"mcuSrc_id"` + McuSrc *ems.McuSrc `json:"mcuSrc,omitempty" gorm:"foreignKey:McuSrc_Id;references:Id"` + Result *string `json:"result"` + Status_Code erc.DataStatusCode `json:"status_code"` +} diff --git a/internal/domain/main-entities/mcu-order/dto.go b/internal/domain/main-entities/mcu-order/dto.go new file mode 100644 index 00000000..418fb02c --- /dev/null +++ b/internal/domain/main-entities/mcu-order/dto.go @@ -0,0 +1,77 @@ +package mcuorder + +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" + erc "simrs-vx/internal/domain/references/common" +) + +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"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Preloads []string `json:"-"` +} + +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"` + + Page int `json:"page"` + PageSize int `json:"page_size"` + NoPagination int `json:"no_pagination"` +} +type ReadDetailDto struct { + Id uint16 `json:"id"` +} + +type UpdateDto struct { + Id uint16 `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint16 `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + 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"` +} + +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, + } + resp.Main = d.Main + return resp +} + +func ToResponseList(data []McuOrder) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/mcu-order/entity.go b/internal/domain/main-entities/mcu-order/entity.go new file mode 100644 index 00000000..326c761f --- /dev/null +++ b/internal/domain/main-entities/mcu-order/entity.go @@ -0,0 +1,18 @@ +package mcuorder + +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" + + erc "simrs-vx/internal/domain/references/common" +) + +type McuOrder struct { + ecore.Main // adjust this according to the needs + Encounter_Id *uint `json:"encounter_id"` + Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"` + Status_Code erc.DataStatusCode `json:"status_code" gorm:"not null;size:10"` + Doctor_Id *uint `json:"doctor_id"` + Doctor *ed.Doctor `json:"doctor,omitempty" gorm:"foreignKey:Doctor_Id;references:Id"` +} diff --git a/internal/domain/main-entities/medication-item-dist/dto.go b/internal/domain/main-entities/medication-item-dist/dto.go new file mode 100644 index 00000000..05278d81 --- /dev/null +++ b/internal/domain/main-entities/medication-item-dist/dto.go @@ -0,0 +1,74 @@ +package medicationitem + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + emi "simrs-vx/internal/domain/main-entities/medication-item" + "time" +) + +type CreateDto struct { + MedicationItem_Id *uint `json:"medicationItem_id"` + DateTime *time.Time `json:"dateTime"` + Remain *uint `json:"remain"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Preloads []string `json:"-"` +} + +type FilterDto struct { + MedicationItem_Id *uint `json:"medicationItem_id"` + DateTime *time.Time `json:"dateTime"` + Remain *uint `json:"remain"` + + Page int `json:"page"` + PageSize int `json:"page_size"` + NoPagination int `json:"no_pagination"` +} +type ReadDetailDto struct { + Id uint16 `json:"id"` +} + +type UpdateDto struct { + Id uint16 `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint16 `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.Main + MedicationItem_Id *uint `json:"medicationItem_id"` + MedicationItem *emi.MedicationItem `json:"medicationItem,omitempty"` + DateTime *time.Time `json:"dateTime"` + Remain *uint `json:"remain"` +} + +func (d MedicationItemDist) ToResponse() ResponseDto { + resp := ResponseDto{ + MedicationItem_Id: d.MedicationItem_Id, + MedicationItem: d.MedicationItem, + DateTime: d.DateTime, + Remain: d.Remain, + } + resp.Main = d.Main + return resp +} + +func ToResponseList(data []MedicationItemDist) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/medication-item-dist/entity.go b/internal/domain/main-entities/medication-item-dist/entity.go new file mode 100644 index 00000000..5bd56912 --- /dev/null +++ b/internal/domain/main-entities/medication-item-dist/entity.go @@ -0,0 +1,15 @@ +package medicationitem + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + emi "simrs-vx/internal/domain/main-entities/medication-item" + "time" +) + +type MedicationItemDist struct { + ecore.Main // adjust this according to the needs + MedicationItem_Id *uint `json:"medicationItem_id"` + MedicationItem *emi.MedicationItem `json:"medicationItem,omitempty" gorm:"foreignKey:MedicationItem_Id;references:Id"` + DateTime *time.Time `json:"dateTime"` + Remain *uint `json:"remain"` +} diff --git a/internal/domain/main-entities/medication-item/dto.go b/internal/domain/main-entities/medication-item/dto.go new file mode 100644 index 00000000..2b4e0ed1 --- /dev/null +++ b/internal/domain/main-entities/medication-item/dto.go @@ -0,0 +1,94 @@ +package medicationitem + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + eme "simrs-vx/internal/domain/main-entities/medication" + em "simrs-vx/internal/domain/main-entities/medicine" + emm "simrs-vx/internal/domain/main-entities/medicine-mix" +) + +type CreateDto struct { + Medication_Id *uint `json:"medication_id"` + IsMix bool `json:"isMix"` + Medicine_Id *uint `json:"medicine_id"` + MedicineMix_Id *uint `json:"medicineMix_id"` + Usage uint8 `json:"usage"` + Interval uint8 `json:"interval"` + // IntervalUnit_Code +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Preloads []string `json:"-"` +} + +type FilterDto struct { + Medication_Id *uint `json:"medication_id"` + IsMix bool `json:"isMix"` + Medicine_Id *uint `json:"medicine_id"` + MedicineMix_Id *uint `json:"medicineMix_id"` + Usage uint8 `json:"usage"` + Interval uint8 `json:"interval"` + // IntervalUnit_Code + + Page int `json:"page"` + PageSize int `json:"page_size"` + NoPagination int `json:"no_pagination"` +} +type ReadDetailDto struct { + Id uint16 `json:"id"` +} + +type UpdateDto struct { + Id uint16 `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint16 `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.Main + Medication_Id *uint `json:"medication_id"` + Medication *eme.Medication `json:"medication,omitempty"` + IsMix bool `json:"isMix"` + Medicine_Id *uint `json:"medicine_id"` + Medicine *em.Medicine `json:"medicine,omitempty"` + MedicineMix_Id *uint `json:"medicineMix_id"` + MedicineMix *emm.MedicineMix `json:"medicineMix,omitempty"` + Usage uint8 `json:"usage"` + Interval uint8 `json:"interval"` + // IntervalUnit_Code +} + +func (d MedicationItem) ToResponse() ResponseDto { + resp := ResponseDto{ + Medication_Id: d.Medication_Id, + Medication: d.Medication, + IsMix: d.IsMix, + Medicine_Id: d.Medicine_Id, + Medicine: d.Medicine, + MedicineMix_Id: d.MedicineMix_Id, + MedicineMix: d.MedicineMix, + Usage: d.Usage, + Interval: d.Interval, + } + resp.Main = d.Main + return resp +} + +func ToResponseList(data []MedicationItem) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/medication-item/entity.go b/internal/domain/main-entities/medication-item/entity.go new file mode 100644 index 00000000..160b7dec --- /dev/null +++ b/internal/domain/main-entities/medication-item/entity.go @@ -0,0 +1,22 @@ +package medicationitem + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + eme "simrs-vx/internal/domain/main-entities/medication" + em "simrs-vx/internal/domain/main-entities/medicine" + emm "simrs-vx/internal/domain/main-entities/medicine-mix" +) + +type MedicationItem struct { + ecore.Main // adjust this according to the needs + Medication_Id *uint `json:"medication_id"` + Medication *eme.Medication `json:"medication,omitempty" gorm:"foreignKey:Medication_Id;references:Id"` + IsMix bool `json:"isMix"` + Medicine_Id *uint `json:"medicine_id"` + Medicine *em.Medicine `json:"medicine,omitempty" gorm:"foreignKey:Medicine_Id;references:Id"` + MedicineMix_Id *uint `json:"medicineMix_id"` + MedicineMix *emm.MedicineMix `json:"medicineMix,omitempty" gorm:"foreignKey:MedicineMix_Id;references:Id"` + Usage uint8 `json:"usage"` + Interval uint8 `json:"interval"` + // IntervalUnit_Code +} diff --git a/internal/domain/main-entities/medication/dto.go b/internal/domain/main-entities/medication/dto.go new file mode 100644 index 00000000..1bc1c774 --- /dev/null +++ b/internal/domain/main-entities/medication/dto.go @@ -0,0 +1,77 @@ +package medication + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + ee "simrs-vx/internal/domain/main-entities/encounter" + ep "simrs-vx/internal/domain/main-entities/pharmacist" + "time" +) + +type CreateDto struct { + Encounter_Id *uint `json:"encounter_id"` + IssuedAt *time.Time `json:"issuedAt"` + Pharmacist_Id *uint `json:"pharmacist_id"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Preloads []string `json:"-"` +} + +type FilterDto struct { + Encounter_Id *uint `json:"encounter_id"` + IssuedAt *time.Time `json:"issuedAt"` + Pharmacist_Id *uint `json:"pharmacist_id"` + + Page int `json:"page"` + PageSize int `json:"page_size"` + NoPagination int `json:"no_pagination"` +} +type ReadDetailDto struct { + Id uint16 `json:"id"` +} + +type UpdateDto struct { + Id uint16 `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint16 `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + 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"` + IssuedAt *time.Time `json:"issuedAt"` + Pharmacist_Id *uint `json:"pharmacist_id"` + Pharmacist *ep.Pharmacist `json:"pharmacist,omitempty"` +} + +func (d Medication) ToResponse() ResponseDto { + resp := ResponseDto{ + Encounter_Id: d.Encounter_Id, + Encounter: d.Encounter, + IssuedAt: d.IssuedAt, + Pharmacist_Id: d.Pharmacist_Id, + Pharmacist: d.Pharmacist, + } + resp.Main = d.Main + return resp +} + +func ToResponseList(data []Medication) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/medication/entity.go b/internal/domain/main-entities/medication/entity.go new file mode 100644 index 00000000..f18af23c --- /dev/null +++ b/internal/domain/main-entities/medication/entity.go @@ -0,0 +1,18 @@ +package medication + +import ( + "time" + + ecore "simrs-vx/internal/domain/base-entities/core" + ee "simrs-vx/internal/domain/main-entities/encounter" + ep "simrs-vx/internal/domain/main-entities/pharmacist" +) + +type Medication struct { + ecore.Main // adjust this according to the needs + Encounter_Id *uint `json:"encounter_id"` + Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"` + IssuedAt *time.Time `json:"issuedAt"` + Pharmacist_Id *uint `json:"pharmacist_id"` + Pharmacist *ep.Pharmacist `json:"pharmacist,omitempty" gorm:"foreignKey:Pharmacist_Id;references:Id"` +} diff --git a/internal/domain/main-entities/prescription-item/dto.go b/internal/domain/main-entities/prescription-item/dto.go new file mode 100644 index 00000000..9d28a511 --- /dev/null +++ b/internal/domain/main-entities/prescription-item/dto.go @@ -0,0 +1,91 @@ +package prescriptionitem + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + em "simrs-vx/internal/domain/main-entities/medicine" + emm "simrs-vx/internal/domain/main-entities/medicine-mix" + ep "simrs-vx/internal/domain/main-entities/prescription" +) + +type CreateDto struct { + Prescription_Id *uint `json:"prescription_id"` + IsMix bool `json:"isMix"` + Medicine_Id *uint `json:"medicine_id"` + MedicineMix_Id *uint `json:"medicineMix_id"` + Usage uint8 `json:"usage"` + Interval uint8 `json:"interval"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Preloads []string `json:"-"` +} + +type FilterDto struct { + Prescription_Id *uint `json:"prescription_id"` + IsMix bool `json:"isMix"` + Medicine_Id *uint `json:"medicine_id"` + MedicineMix_Id *uint `json:"medicineMix_id"` + Usage uint8 `json:"usage"` + Interval uint8 `json:"interval"` + + Page int `json:"page"` + PageSize int `json:"page_size"` + NoPagination int `json:"no_pagination"` +} +type ReadDetailDto struct { + Id uint16 `json:"id"` +} + +type UpdateDto struct { + Id uint16 `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint16 `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.Main + Prescription_Id *uint `json:"prescription_id"` + Prescription *ep.Prescription `json:"prescription,omitempty"` + IsMix bool `json:"isMix"` + Medicine_Id *uint `json:"medicine_id"` + Medicine *em.Medicine `json:"medicine,omitempty"` + MedicineMix_Id *uint `json:"medicineMix_id"` + MedicineMix *emm.MedicineMix `json:"medicineMix,omitempty"` + Usage uint8 `json:"usage"` + Interval uint8 `json:"interval"` +} + +func (d PrescriptionItem) ToResponse() ResponseDto { + resp := ResponseDto{ + Prescription_Id: d.Prescription_Id, + Prescription: d.Prescription, + IsMix: d.IsMix, + Medicine_Id: d.Medicine_Id, + Medicine: d.Medicine, + MedicineMix_Id: d.MedicineMix_Id, + MedicineMix: d.MedicineMix, + Usage: d.Usage, + Interval: d.Interval, + } + resp.Main = d.Main + return resp +} + +func ToResponseList(data []PrescriptionItem) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/prescription-item/entity.go b/internal/domain/main-entities/prescription-item/entity.go new file mode 100644 index 00000000..3898e170 --- /dev/null +++ b/internal/domain/main-entities/prescription-item/entity.go @@ -0,0 +1,22 @@ +package prescriptionitem + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + em "simrs-vx/internal/domain/main-entities/medicine" + emm "simrs-vx/internal/domain/main-entities/medicine-mix" + ep "simrs-vx/internal/domain/main-entities/prescription" +) + +type PrescriptionItem struct { + ecore.Main // adjust this according to the needs + Prescription_Id *uint `json:"prescription_id"` + Prescription *ep.Prescription `json:"prescription,omitempty" gorm:"foreignKey:Prescription_Id;references:Id"` + IsMix bool `json:"isMix"` + Medicine_Id *uint `json:"medicine_id"` + Medicine *em.Medicine `json:"medicine,omitempty" gorm:"foreignKey:Medicine_Id;references:Id"` + MedicineMix_Id *uint `json:"medicineMix_id"` + MedicineMix *emm.MedicineMix `json:"medicineMix,omitempty" gorm:"foreignKey:MedicineMix_Id;references:Id"` + Usage uint8 `json:"usage"` + Interval uint8 `json:"interval"` + // IntervalUnit_Code +} diff --git a/internal/domain/main-entities/prescription/dto.go b/internal/domain/main-entities/prescription/dto.go new file mode 100644 index 00000000..b87d6f12 --- /dev/null +++ b/internal/domain/main-entities/prescription/dto.go @@ -0,0 +1,77 @@ +package prescription + +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" +) + +type CreateDto struct { + Encounter_Id *uint `json:"encounter_id"` + Doctor_Id *uint `json:"doctor_id"` + IssuedAt *time.Time `json:"issuedAt"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Preloads []string `json:"-"` +} + +type FilterDto struct { + Encounter_Id *uint `json:"encounter_id"` + Doctor_Id *uint `json:"doctor_id"` + IssuedAt *time.Time `json:"issuedAt"` + + Page int `json:"page"` + PageSize int `json:"page_size"` + NoPagination int `json:"no_pagination"` +} +type ReadDetailDto struct { + Id uint16 `json:"id"` +} + +type UpdateDto struct { + Id uint16 `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint16 `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + 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"` + Doctor_Id *uint `json:"doctor_id"` + Doctor *ed.Doctor `json:"doctor,omitempty"` + IssuedAt *time.Time `json:"issuedAt"` +} + +func (d Prescription) ToResponse() ResponseDto { + resp := ResponseDto{ + Encounter_Id: d.Encounter_Id, + Encounter: d.Encounter, + Doctor_Id: d.Doctor_Id, + Doctor: d.Doctor, + IssuedAt: d.IssuedAt, + } + resp.Main = d.Main + return resp +} + +func ToResponseList(data []Prescription) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/prescription/entity.go b/internal/domain/main-entities/prescription/entity.go new file mode 100644 index 00000000..bf3e7930 --- /dev/null +++ b/internal/domain/main-entities/prescription/entity.go @@ -0,0 +1,17 @@ +package prescription + +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" +) + +type Prescription struct { + ecore.Main // adjust this according to the needs + Encounter_Id *uint `json:"encounter_id"` + Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"` + Doctor_Id *uint `json:"doctor_id"` + Doctor *ed.Doctor `json:"doctor,omitempty" gorm:"foreignKey:Doctor_Id;references:Id"` + IssuedAt *time.Time `json:"issuedAt"` +} From b4dca13bc40fcc4ddf19dfc59daff6da69bf72ff Mon Sep 17 00:00:00 2001 From: dpurbosakti Date: Mon, 15 Sep 2025 14:11:53 +0700 Subject: [PATCH 2/6] regis entities for orders, not running diff yet --- internal/interface/migration/main-entities.go | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/internal/interface/migration/main-entities.go b/internal/interface/migration/main-entities.go index 62e7ee76..4e544a59 100644 --- a/internal/interface/migration/main-entities.go +++ b/internal/interface/migration/main-entities.go @@ -6,6 +6,8 @@ import ( appointment "simrs-vx/internal/domain/main-entities/appointment" counter "simrs-vx/internal/domain/main-entities/counter" device "simrs-vx/internal/domain/main-entities/device" + deviceorder "simrs-vx/internal/domain/main-entities/device-order" + deviceorderitem "simrs-vx/internal/domain/main-entities/device-order-item" diagnosesrc "simrs-vx/internal/domain/main-entities/diagnose-src" district "simrs-vx/internal/domain/main-entities/district" division "simrs-vx/internal/domain/main-entities/division" @@ -25,10 +27,17 @@ import ( laborant "simrs-vx/internal/domain/main-entities/laborant" language "simrs-vx/internal/domain/main-entities/language" material "simrs-vx/internal/domain/main-entities/material" + materialorder "simrs-vx/internal/domain/main-entities/material-order" + materialorderitem "simrs-vx/internal/domain/main-entities/material-order-item" + mcuorder "simrs-vx/internal/domain/main-entities/mcu-order" + mcuorderitem "simrs-vx/internal/domain/main-entities/mcu-order-item" mcusrc "simrs-vx/internal/domain/main-entities/mcu-src" mcusrccategory "simrs-vx/internal/domain/main-entities/mcu-src-category" medicalactionsrc "simrs-vx/internal/domain/main-entities/medical-action-src" medicalactionsrcitem "simrs-vx/internal/domain/main-entities/medical-action-src-item" + medication "simrs-vx/internal/domain/main-entities/medication" + medicationitem "simrs-vx/internal/domain/main-entities/medication-item" + medicationitemdist "simrs-vx/internal/domain/main-entities/medication-item-dist" medicine "simrs-vx/internal/domain/main-entities/medicine" medicinegroup "simrs-vx/internal/domain/main-entities/medicine-group" medicinemethod "simrs-vx/internal/domain/main-entities/medicine-method" @@ -44,6 +53,8 @@ import ( pharmacist "simrs-vx/internal/domain/main-entities/pharmacist" pharmacycompany "simrs-vx/internal/domain/main-entities/pharmacy-company" practiceschedule "simrs-vx/internal/domain/main-entities/practice-schedule" + prescription "simrs-vx/internal/domain/main-entities/prescription" + prescriptionitem "simrs-vx/internal/domain/main-entities/prescription-item" proceduresrc "simrs-vx/internal/domain/main-entities/procedure-src" province "simrs-vx/internal/domain/main-entities/province" regency "simrs-vx/internal/domain/main-entities/regency" @@ -117,5 +128,16 @@ func getMainEntities() []any { &emergency.Emergency{}, &inpatient.Inpatient{}, &ambulatory.Ambulatory{}, + &prescription.Prescription{}, + &prescriptionitem.PrescriptionItem{}, + &medication.Medication{}, + &medicationitem.MedicationItem{}, + &medicationitemdist.MedicationItemDist{}, + &deviceorder.DeviceOrder{}, + &deviceorderitem.DeviceOrderItem{}, + &materialorder.MaterialOrder{}, + &materialorderitem.MaterialOrderItem{}, + &mcuorder.McuOrder{}, + &mcuorderitem.McuOrderItem{}, } } From 178fe7894017339ed719ec7eba45e4954829d4ca Mon Sep 17 00:00:00 2001 From: dpurbosakti Date: Mon, 15 Sep 2025 14:52:13 +0700 Subject: [PATCH 3/6] add crud for orders --- .../main-handler/device-order-item/handler.go | 71 +++++ .../main-handler/device-order/handler.go | 71 +++++ .../interface/main-handler/main-handler.go | 22 ++ .../material-order-item/handler.go | 71 +++++ .../main-handler/material-order/handler.go | 71 +++++ .../main-handler/mcu-order-item/handler.go | 71 +++++ .../main-handler/mcu-order/handler.go | 71 +++++ .../medication-item-dist/handler.go | 71 +++++ .../main-handler/medication-item/handler.go | 71 +++++ .../main-handler/medication/handler.go | 71 +++++ .../main-handler/prescription-item/handler.go | 71 +++++ .../main-handler/prescription/handler.go | 71 +++++ .../main-use-case/device-order-item/case.go | 279 ++++++++++++++++++ .../main-use-case/device-order-item/helper.go | 22 ++ .../main-use-case/device-order-item/lib.go | 155 ++++++++++ .../device-order-item/middleware-runner.go | 103 +++++++ .../device-order-item/middleware.go | 9 + .../device-order-item/tycovar.go | 44 +++ .../main-use-case/device-order/case.go | 279 ++++++++++++++++++ .../main-use-case/device-order/helper.go | 21 ++ .../main-use-case/device-order/lib.go | 155 ++++++++++ .../device-order/middleware-runner.go | 103 +++++++ .../main-use-case/device-order/middleware.go | 9 + .../main-use-case/device-order/tycovar.go | 44 +++ .../main-use-case/material-order-item/case.go | 279 ++++++++++++++++++ .../material-order-item/helper.go | 23 ++ .../main-use-case/material-order-item/lib.go | 155 ++++++++++ .../material-order-item/middleware-runner.go | 103 +++++++ .../material-order-item/middleware.go | 9 + .../material-order-item/tycovar.go | 44 +++ .../main-use-case/material-order/case.go | 279 ++++++++++++++++++ .../main-use-case/material-order/helper.go | 21 ++ .../main-use-case/material-order/lib.go | 155 ++++++++++ .../material-order/middleware-runner.go | 103 +++++++ .../material-order/middleware.go | 9 + .../main-use-case/material-order/tycovar.go | 44 +++ .../main-use-case/mcu-order-item/case.go | 279 ++++++++++++++++++ .../main-use-case/mcu-order-item/helper.go | 24 ++ .../main-use-case/mcu-order-item/lib.go | 155 ++++++++++ .../mcu-order-item/middleware-runner.go | 103 +++++++ .../mcu-order-item/middleware.go | 9 + .../main-use-case/mcu-order-item/tycovar.go | 44 +++ .../use-case/main-use-case/mcu-order/case.go | 279 ++++++++++++++++++ .../main-use-case/mcu-order/helper.go | 23 ++ .../use-case/main-use-case/mcu-order/lib.go | 155 ++++++++++ .../mcu-order/middleware-runner.go | 103 +++++++ .../main-use-case/mcu-order/middleware.go | 9 + .../main-use-case/mcu-order/tycovar.go | 44 +++ .../medication-item-dist/case.go | 279 ++++++++++++++++++ .../medication-item-dist/helper.go | 23 ++ .../main-use-case/medication-item-dist/lib.go | 155 ++++++++++ .../medication-item-dist/middleware-runner.go | 103 +++++++ .../medication-item-dist/middleware.go | 9 + .../medication-item-dist/tycovar.go | 44 +++ .../main-use-case/medication-item/case.go | 279 ++++++++++++++++++ .../main-use-case/medication-item/helper.go | 26 ++ .../main-use-case/medication-item/lib.go | 155 ++++++++++ .../medication-item/middleware-runner.go | 103 +++++++ .../medication-item/middleware.go | 9 + .../main-use-case/medication-item/tycovar.go | 44 +++ .../use-case/main-use-case/medication/case.go | 279 ++++++++++++++++++ .../main-use-case/medication/helper.go | 23 ++ .../use-case/main-use-case/medication/lib.go | 155 ++++++++++ .../medication/middleware-runner.go | 103 +++++++ .../main-use-case/medication/middleware.go | 9 + .../main-use-case/medication/tycovar.go | 44 +++ .../main-use-case/prescription-item/case.go | 279 ++++++++++++++++++ .../main-use-case/prescription-item/helper.go | 26 ++ .../main-use-case/prescription-item/lib.go | 155 ++++++++++ .../prescription-item/middleware-runner.go | 103 +++++++ .../prescription-item/middleware.go | 9 + .../prescription-item/tycovar.go | 44 +++ .../main-use-case/prescription/case.go | 279 ++++++++++++++++++ .../main-use-case/prescription/helper.go | 23 ++ .../main-use-case/prescription/lib.go | 155 ++++++++++ .../prescription/middleware-runner.go | 103 +++++++ .../main-use-case/prescription/middleware.go | 9 + .../main-use-case/prescription/tycovar.go | 44 +++ 78 files changed, 7548 insertions(+) create mode 100644 internal/interface/main-handler/device-order-item/handler.go create mode 100644 internal/interface/main-handler/device-order/handler.go create mode 100644 internal/interface/main-handler/material-order-item/handler.go create mode 100644 internal/interface/main-handler/material-order/handler.go create mode 100644 internal/interface/main-handler/mcu-order-item/handler.go create mode 100644 internal/interface/main-handler/mcu-order/handler.go create mode 100644 internal/interface/main-handler/medication-item-dist/handler.go create mode 100644 internal/interface/main-handler/medication-item/handler.go create mode 100644 internal/interface/main-handler/medication/handler.go create mode 100644 internal/interface/main-handler/prescription-item/handler.go create mode 100644 internal/interface/main-handler/prescription/handler.go create mode 100644 internal/use-case/main-use-case/device-order-item/case.go create mode 100644 internal/use-case/main-use-case/device-order-item/helper.go create mode 100644 internal/use-case/main-use-case/device-order-item/lib.go create mode 100644 internal/use-case/main-use-case/device-order-item/middleware-runner.go create mode 100644 internal/use-case/main-use-case/device-order-item/middleware.go create mode 100644 internal/use-case/main-use-case/device-order-item/tycovar.go create mode 100644 internal/use-case/main-use-case/device-order/case.go create mode 100644 internal/use-case/main-use-case/device-order/helper.go create mode 100644 internal/use-case/main-use-case/device-order/lib.go create mode 100644 internal/use-case/main-use-case/device-order/middleware-runner.go create mode 100644 internal/use-case/main-use-case/device-order/middleware.go create mode 100644 internal/use-case/main-use-case/device-order/tycovar.go create mode 100644 internal/use-case/main-use-case/material-order-item/case.go create mode 100644 internal/use-case/main-use-case/material-order-item/helper.go create mode 100644 internal/use-case/main-use-case/material-order-item/lib.go create mode 100644 internal/use-case/main-use-case/material-order-item/middleware-runner.go create mode 100644 internal/use-case/main-use-case/material-order-item/middleware.go create mode 100644 internal/use-case/main-use-case/material-order-item/tycovar.go create mode 100644 internal/use-case/main-use-case/material-order/case.go create mode 100644 internal/use-case/main-use-case/material-order/helper.go create mode 100644 internal/use-case/main-use-case/material-order/lib.go create mode 100644 internal/use-case/main-use-case/material-order/middleware-runner.go create mode 100644 internal/use-case/main-use-case/material-order/middleware.go create mode 100644 internal/use-case/main-use-case/material-order/tycovar.go create mode 100644 internal/use-case/main-use-case/mcu-order-item/case.go create mode 100644 internal/use-case/main-use-case/mcu-order-item/helper.go create mode 100644 internal/use-case/main-use-case/mcu-order-item/lib.go create mode 100644 internal/use-case/main-use-case/mcu-order-item/middleware-runner.go create mode 100644 internal/use-case/main-use-case/mcu-order-item/middleware.go create mode 100644 internal/use-case/main-use-case/mcu-order-item/tycovar.go create mode 100644 internal/use-case/main-use-case/mcu-order/case.go create mode 100644 internal/use-case/main-use-case/mcu-order/helper.go create mode 100644 internal/use-case/main-use-case/mcu-order/lib.go create mode 100644 internal/use-case/main-use-case/mcu-order/middleware-runner.go create mode 100644 internal/use-case/main-use-case/mcu-order/middleware.go create mode 100644 internal/use-case/main-use-case/mcu-order/tycovar.go create mode 100644 internal/use-case/main-use-case/medication-item-dist/case.go create mode 100644 internal/use-case/main-use-case/medication-item-dist/helper.go create mode 100644 internal/use-case/main-use-case/medication-item-dist/lib.go create mode 100644 internal/use-case/main-use-case/medication-item-dist/middleware-runner.go create mode 100644 internal/use-case/main-use-case/medication-item-dist/middleware.go create mode 100644 internal/use-case/main-use-case/medication-item-dist/tycovar.go create mode 100644 internal/use-case/main-use-case/medication-item/case.go create mode 100644 internal/use-case/main-use-case/medication-item/helper.go create mode 100644 internal/use-case/main-use-case/medication-item/lib.go create mode 100644 internal/use-case/main-use-case/medication-item/middleware-runner.go create mode 100644 internal/use-case/main-use-case/medication-item/middleware.go create mode 100644 internal/use-case/main-use-case/medication-item/tycovar.go create mode 100644 internal/use-case/main-use-case/medication/case.go create mode 100644 internal/use-case/main-use-case/medication/helper.go create mode 100644 internal/use-case/main-use-case/medication/lib.go create mode 100644 internal/use-case/main-use-case/medication/middleware-runner.go create mode 100644 internal/use-case/main-use-case/medication/middleware.go create mode 100644 internal/use-case/main-use-case/medication/tycovar.go create mode 100644 internal/use-case/main-use-case/prescription-item/case.go create mode 100644 internal/use-case/main-use-case/prescription-item/helper.go create mode 100644 internal/use-case/main-use-case/prescription-item/lib.go create mode 100644 internal/use-case/main-use-case/prescription-item/middleware-runner.go create mode 100644 internal/use-case/main-use-case/prescription-item/middleware.go create mode 100644 internal/use-case/main-use-case/prescription-item/tycovar.go create mode 100644 internal/use-case/main-use-case/prescription/case.go create mode 100644 internal/use-case/main-use-case/prescription/helper.go create mode 100644 internal/use-case/main-use-case/prescription/lib.go create mode 100644 internal/use-case/main-use-case/prescription/middleware-runner.go create mode 100644 internal/use-case/main-use-case/prescription/middleware.go create mode 100644 internal/use-case/main-use-case/prescription/tycovar.go diff --git a/internal/interface/main-handler/device-order-item/handler.go b/internal/interface/main-handler/device-order-item/handler.go new file mode 100644 index 00000000..42dfd510 --- /dev/null +++ b/internal/interface/main-handler/device-order-item/handler.go @@ -0,0 +1,71 @@ +package deviceorderitem + +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/device-order-item" + u "simrs-vx/internal/use-case/main-use-case/device-order-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 = 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/device-order/handler.go b/internal/interface/main-handler/device-order/handler.go new file mode 100644 index 00000000..d9b55d6a --- /dev/null +++ b/internal/interface/main-handler/device-order/handler.go @@ -0,0 +1,71 @@ +package deviceorder + +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/device-order" + u "simrs-vx/internal/use-case/main-use-case/device-order" +) + +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/main-handler.go b/internal/interface/main-handler/main-handler.go index 363e9ad1..db155f73 100644 --- a/internal/interface/main-handler/main-handler.go +++ b/internal/interface/main-handler/main-handler.go @@ -7,10 +7,21 @@ import ( adime "simrs-vx/internal/interface/main-handler/adime" auth "simrs-vx/internal/interface/main-handler/authentication" counter "simrs-vx/internal/interface/main-handler/counter" + deviceorder "simrs-vx/internal/interface/main-handler/device-order" + deviceorderitem "simrs-vx/internal/interface/main-handler/device-order-item" encounter "simrs-vx/internal/interface/main-handler/encounter" + materialorder "simrs-vx/internal/interface/main-handler/material-order" + 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" + 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" medicicinemix "simrs-vx/internal/interface/main-handler/medicine-mix" medicicinemixitem "simrs-vx/internal/interface/main-handler/medicine-mix-item" practiceschedule "simrs-vx/internal/interface/main-handler/practice-schedule" + prescription "simrs-vx/internal/interface/main-handler/prescription" + prescriptionitem "simrs-vx/internal/interface/main-handler/prescription-item" sbar "simrs-vx/internal/interface/main-handler/sbar" soapi "simrs-vx/internal/interface/main-handler/soapi" @@ -139,6 +150,17 @@ 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/medication", medication.O) + hc.RegCrud(r, "/v1/medication-item", medicationitem.O) + hc.RegCrud(r, "/v1/medication-item-dist", medicationitemdist.O) + hc.RegCrud(r, "/v1/device-order", deviceorder.O) + hc.RegCrud(r, "/v1/device-order-item", deviceorderitem.O) + hc.RegCrud(r, "/v1/material-order", materialorder.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) /******************** sources ********************/ hc.RegCrud(r, "/v1/division", division.O) diff --git a/internal/interface/main-handler/material-order-item/handler.go b/internal/interface/main-handler/material-order-item/handler.go new file mode 100644 index 00000000..3b25f1d3 --- /dev/null +++ b/internal/interface/main-handler/material-order-item/handler.go @@ -0,0 +1,71 @@ +package materialorderitem + +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/material-order-item" + u "simrs-vx/internal/use-case/main-use-case/material-order-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 = 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/material-order/handler.go b/internal/interface/main-handler/material-order/handler.go new file mode 100644 index 00000000..cfea48f7 --- /dev/null +++ b/internal/interface/main-handler/material-order/handler.go @@ -0,0 +1,71 @@ +package materialorder + +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/material-order" + u "simrs-vx/internal/use-case/main-use-case/material-order" +) + +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/mcu-order-item/handler.go b/internal/interface/main-handler/mcu-order-item/handler.go new file mode 100644 index 00000000..a3a4bcc8 --- /dev/null +++ b/internal/interface/main-handler/mcu-order-item/handler.go @@ -0,0 +1,71 @@ +package mcuorderitem + +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-item" + u "simrs-vx/internal/use-case/main-use-case/mcu-order-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 = 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/mcu-order/handler.go b/internal/interface/main-handler/mcu-order/handler.go new file mode 100644 index 00000000..77e19669 --- /dev/null +++ b/internal/interface/main-handler/mcu-order/handler.go @@ -0,0 +1,71 @@ +package mcuorder + +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" + u "simrs-vx/internal/use-case/main-use-case/mcu-order" +) + +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-item-dist/handler.go b/internal/interface/main-handler/medication-item-dist/handler.go new file mode 100644 index 00000000..956a98ae --- /dev/null +++ b/internal/interface/main-handler/medication-item-dist/handler.go @@ -0,0 +1,71 @@ +package medicationitemdist + +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/medication-item-dist" + u "simrs-vx/internal/use-case/main-use-case/medication-item-dist" +) + +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-item/handler.go b/internal/interface/main-handler/medication-item/handler.go new file mode 100644 index 00000000..b5a5e6ae --- /dev/null +++ b/internal/interface/main-handler/medication-item/handler.go @@ -0,0 +1,71 @@ +package medicationitem + +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/medication-item" + u "simrs-vx/internal/use-case/main-use-case/medication-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 = 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 new file mode 100644 index 00000000..269c2e6f --- /dev/null +++ b/internal/interface/main-handler/medication/handler.go @@ -0,0 +1,71 @@ +package medication + +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/medication" + u "simrs-vx/internal/use-case/main-use-case/medication" +) + +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/prescription-item/handler.go b/internal/interface/main-handler/prescription-item/handler.go new file mode 100644 index 00000000..faab4849 --- /dev/null +++ b/internal/interface/main-handler/prescription-item/handler.go @@ -0,0 +1,71 @@ +package prescriptionitem + +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/prescription-item" + u "simrs-vx/internal/use-case/main-use-case/prescription-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 = 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/prescription/handler.go b/internal/interface/main-handler/prescription/handler.go new file mode 100644 index 00000000..25ee9469 --- /dev/null +++ b/internal/interface/main-handler/prescription/handler.go @@ -0,0 +1,71 @@ +package prescription + +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/prescription" + u "simrs-vx/internal/use-case/main-use-case/prescription" +) + +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/use-case/main-use-case/device-order-item/case.go b/internal/use-case/main-use-case/device-order-item/case.go new file mode 100644 index 00000000..d4920979 --- /dev/null +++ b/internal/use-case/main-use-case/device-order-item/case.go @@ -0,0 +1,279 @@ +package deviceorderitem + +import ( + "strconv" + + e "simrs-vx/internal/domain/main-entities/device-order-item" + + 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 = "device-order-item" + +func Create(input e.CreateDto) (*d.Data, error) { + data := e.DeviceOrderItem{} + + 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 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.DeviceOrderItem + var dataList []e.DeviceOrderItem + 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.DeviceOrderItem + 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.DeviceOrderItem + 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.DeviceOrderItem + 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/device-order-item/helper.go b/internal/use-case/main-use-case/device-order-item/helper.go new file mode 100644 index 00000000..d618afae --- /dev/null +++ b/internal/use-case/main-use-case/device-order-item/helper.go @@ -0,0 +1,22 @@ +/* +DESCRIPTION: +Any functions that are used internally by the use-case +*/ +package deviceorderitem + +import ( + e "simrs-vx/internal/domain/main-entities/device-order-item" +) + +func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.DeviceOrderItem) { + var inputSrc *e.CreateDto + if inputT, ok := any(input).(*e.CreateDto); ok { + inputSrc = inputT + } else { + inputTemp := any(input).(*e.UpdateDto) + inputSrc = &inputTemp.CreateDto + } + + data.DeviceOrder_Id = inputSrc.DeviceOrder_Id + data.Device_Id = inputSrc.Device_Id +} diff --git a/internal/use-case/main-use-case/device-order-item/lib.go b/internal/use-case/main-use-case/device-order-item/lib.go new file mode 100644 index 00000000..ab36a7a1 --- /dev/null +++ b/internal/use-case/main-use-case/device-order-item/lib.go @@ -0,0 +1,155 @@ +package deviceorderitem + +import ( + e "simrs-vx/internal/domain/main-entities/device-order-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.DeviceOrderItem, error) { + pl.SetLogInfo(event, nil, "started", "DBCreate") + + data := e.DeviceOrderItem{} + 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.DeviceOrderItem, *e.MetaDto, error) { + pl.SetLogInfo(event, input, "started", "DBReadList") + data := []e.DeviceOrderItem{} + 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.DeviceOrderItem{}). + 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.DeviceOrderItem, error) { + pl.SetLogInfo(event, input, "started", "DBReadDetail") + data := e.DeviceOrderItem{} + + 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.DeviceOrderItem, 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.DeviceOrderItem, 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/device-order-item/middleware-runner.go b/internal/use-case/main-use-case/device-order-item/middleware-runner.go new file mode 100644 index 00000000..6722ef63 --- /dev/null +++ b/internal/use-case/main-use-case/device-order-item/middleware-runner.go @@ -0,0 +1,103 @@ +package deviceorderitem + +import ( + e "simrs-vx/internal/domain/main-entities/device-order-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.DeviceOrderItem) 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.DeviceOrderItem) 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.DeviceOrderItem) 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.DeviceOrderItem) 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.DeviceOrderItem) 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/device-order-item/middleware.go b/internal/use-case/main-use-case/device-order-item/middleware.go new file mode 100644 index 00000000..c43a462b --- /dev/null +++ b/internal/use-case/main-use-case/device-order-item/middleware.go @@ -0,0 +1,9 @@ +package deviceorderitem + +// 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/device-order-item/tycovar.go b/internal/use-case/main-use-case/device-order-item/tycovar.go new file mode 100644 index 00000000..b5801749 --- /dev/null +++ b/internal/use-case/main-use-case/device-order-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 deviceorderitem + +import ( + "gorm.io/gorm" + + e "simrs-vx/internal/domain/main-entities/device-order-item" +) + +type createMw struct { + Name string + Func func(input *e.CreateDto, data *e.DeviceOrderItem, tx *gorm.DB) error +} + +type readListMw struct { + Name string + Func func(input *e.ReadListDto, data *e.DeviceOrderItem, tx *gorm.DB) error +} + +type readDetailMw struct { + Name string + Func func(input *e.ReadDetailDto, data *e.DeviceOrderItem, 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/device-order/case.go b/internal/use-case/main-use-case/device-order/case.go new file mode 100644 index 00000000..c4f1ebe5 --- /dev/null +++ b/internal/use-case/main-use-case/device-order/case.go @@ -0,0 +1,279 @@ +package deviceorder + +import ( + "strconv" + + e "simrs-vx/internal/domain/main-entities/device-order" + + 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 = "device-order" + +func Create(input e.CreateDto) (*d.Data, error) { + data := e.DeviceOrder{} + + 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 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.DeviceOrder + var dataList []e.DeviceOrder + 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.DeviceOrder + 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.DeviceOrder + 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.DeviceOrder + 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/device-order/helper.go b/internal/use-case/main-use-case/device-order/helper.go new file mode 100644 index 00000000..975ef50b --- /dev/null +++ b/internal/use-case/main-use-case/device-order/helper.go @@ -0,0 +1,21 @@ +/* +DESCRIPTION: +Any functions that are used internally by the use-case +*/ +package deviceorder + +import ( + e "simrs-vx/internal/domain/main-entities/device-order" +) + +func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.DeviceOrder) { + var inputSrc *e.CreateDto + if inputT, ok := any(input).(*e.CreateDto); ok { + inputSrc = inputT + } else { + inputTemp := any(input).(*e.UpdateDto) + inputSrc = &inputTemp.CreateDto + } + + data.Encounter_Id = inputSrc.Encounter_Id +} diff --git a/internal/use-case/main-use-case/device-order/lib.go b/internal/use-case/main-use-case/device-order/lib.go new file mode 100644 index 00000000..20f344c3 --- /dev/null +++ b/internal/use-case/main-use-case/device-order/lib.go @@ -0,0 +1,155 @@ +package deviceorder + +import ( + e "simrs-vx/internal/domain/main-entities/device-order" + 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.DeviceOrder, error) { + pl.SetLogInfo(event, nil, "started", "DBCreate") + + data := e.DeviceOrder{} + 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.DeviceOrder, *e.MetaDto, error) { + pl.SetLogInfo(event, input, "started", "DBReadList") + data := []e.DeviceOrder{} + 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.DeviceOrder{}). + 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.DeviceOrder, error) { + pl.SetLogInfo(event, input, "started", "DBReadDetail") + data := e.DeviceOrder{} + + 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.DeviceOrder, 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.DeviceOrder, 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/device-order/middleware-runner.go b/internal/use-case/main-use-case/device-order/middleware-runner.go new file mode 100644 index 00000000..7628d931 --- /dev/null +++ b/internal/use-case/main-use-case/device-order/middleware-runner.go @@ -0,0 +1,103 @@ +package deviceorder + +import ( + e "simrs-vx/internal/domain/main-entities/device-order" + 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.DeviceOrder) 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.DeviceOrder) 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.DeviceOrder) 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.DeviceOrder) 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.DeviceOrder) 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/device-order/middleware.go b/internal/use-case/main-use-case/device-order/middleware.go new file mode 100644 index 00000000..a8765213 --- /dev/null +++ b/internal/use-case/main-use-case/device-order/middleware.go @@ -0,0 +1,9 @@ +package deviceorder + +// 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/device-order/tycovar.go b/internal/use-case/main-use-case/device-order/tycovar.go new file mode 100644 index 00000000..9faa49d6 --- /dev/null +++ b/internal/use-case/main-use-case/device-order/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 deviceorder + +import ( + "gorm.io/gorm" + + e "simrs-vx/internal/domain/main-entities/device-order" +) + +type createMw struct { + Name string + Func func(input *e.CreateDto, data *e.DeviceOrder, tx *gorm.DB) error +} + +type readListMw struct { + Name string + Func func(input *e.ReadListDto, data *e.DeviceOrder, tx *gorm.DB) error +} + +type readDetailMw struct { + Name string + Func func(input *e.ReadDetailDto, data *e.DeviceOrder, 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/material-order-item/case.go b/internal/use-case/main-use-case/material-order-item/case.go new file mode 100644 index 00000000..497c3b02 --- /dev/null +++ b/internal/use-case/main-use-case/material-order-item/case.go @@ -0,0 +1,279 @@ +package materialorderitem + +import ( + "strconv" + + e "simrs-vx/internal/domain/main-entities/material-order-item" + + 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 = "material-order-item" + +func Create(input e.CreateDto) (*d.Data, error) { + data := e.MaterialOrderItem{} + + 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 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.MaterialOrderItem + var dataList []e.MaterialOrderItem + 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.MaterialOrderItem + 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.MaterialOrderItem + 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.MaterialOrderItem + 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/material-order-item/helper.go b/internal/use-case/main-use-case/material-order-item/helper.go new file mode 100644 index 00000000..25e89a21 --- /dev/null +++ b/internal/use-case/main-use-case/material-order-item/helper.go @@ -0,0 +1,23 @@ +/* +DESCRIPTION: +Any functions that are used internally by the use-case +*/ +package materialorderitem + +import ( + e "simrs-vx/internal/domain/main-entities/material-order-item" +) + +func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.MaterialOrderItem) { + var inputSrc *e.CreateDto + if inputT, ok := any(input).(*e.CreateDto); ok { + inputSrc = inputT + } else { + inputTemp := any(input).(*e.UpdateDto) + inputSrc = &inputTemp.CreateDto + } + + data.MaterialOrder_Id = inputSrc.MaterialOrder_Id + data.Material_Id = inputSrc.Material_Id + data.Count = inputSrc.Count +} diff --git a/internal/use-case/main-use-case/material-order-item/lib.go b/internal/use-case/main-use-case/material-order-item/lib.go new file mode 100644 index 00000000..4daf147c --- /dev/null +++ b/internal/use-case/main-use-case/material-order-item/lib.go @@ -0,0 +1,155 @@ +package materialorderitem + +import ( + e "simrs-vx/internal/domain/main-entities/material-order-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.MaterialOrderItem, error) { + pl.SetLogInfo(event, nil, "started", "DBCreate") + + data := e.MaterialOrderItem{} + 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.MaterialOrderItem, *e.MetaDto, error) { + pl.SetLogInfo(event, input, "started", "DBReadList") + data := []e.MaterialOrderItem{} + 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.MaterialOrderItem{}). + 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.MaterialOrderItem, error) { + pl.SetLogInfo(event, input, "started", "DBReadDetail") + data := e.MaterialOrderItem{} + + 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.MaterialOrderItem, 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.MaterialOrderItem, 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/material-order-item/middleware-runner.go b/internal/use-case/main-use-case/material-order-item/middleware-runner.go new file mode 100644 index 00000000..4cb38f03 --- /dev/null +++ b/internal/use-case/main-use-case/material-order-item/middleware-runner.go @@ -0,0 +1,103 @@ +package materialorderitem + +import ( + e "simrs-vx/internal/domain/main-entities/material-order-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.MaterialOrderItem) 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.MaterialOrderItem) 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.MaterialOrderItem) 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.MaterialOrderItem) 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.MaterialOrderItem) 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/material-order-item/middleware.go b/internal/use-case/main-use-case/material-order-item/middleware.go new file mode 100644 index 00000000..1ed7165d --- /dev/null +++ b/internal/use-case/main-use-case/material-order-item/middleware.go @@ -0,0 +1,9 @@ +package materialorderitem + +// 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/material-order-item/tycovar.go b/internal/use-case/main-use-case/material-order-item/tycovar.go new file mode 100644 index 00000000..adad9821 --- /dev/null +++ b/internal/use-case/main-use-case/material-order-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 materialorderitem + +import ( + "gorm.io/gorm" + + e "simrs-vx/internal/domain/main-entities/material-order-item" +) + +type createMw struct { + Name string + Func func(input *e.CreateDto, data *e.MaterialOrderItem, tx *gorm.DB) error +} + +type readListMw struct { + Name string + Func func(input *e.ReadListDto, data *e.MaterialOrderItem, tx *gorm.DB) error +} + +type readDetailMw struct { + Name string + Func func(input *e.ReadDetailDto, data *e.MaterialOrderItem, 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/material-order/case.go b/internal/use-case/main-use-case/material-order/case.go new file mode 100644 index 00000000..f566015f --- /dev/null +++ b/internal/use-case/main-use-case/material-order/case.go @@ -0,0 +1,279 @@ +package materialorder + +import ( + "strconv" + + e "simrs-vx/internal/domain/main-entities/material-order" + + 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 = "material-order" + +func Create(input e.CreateDto) (*d.Data, error) { + data := e.MaterialOrder{} + + 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 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.MaterialOrder + var dataList []e.MaterialOrder + 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.MaterialOrder + 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.MaterialOrder + 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.MaterialOrder + 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/material-order/helper.go b/internal/use-case/main-use-case/material-order/helper.go new file mode 100644 index 00000000..565d2487 --- /dev/null +++ b/internal/use-case/main-use-case/material-order/helper.go @@ -0,0 +1,21 @@ +/* +DESCRIPTION: +Any functions that are used internally by the use-case +*/ +package materialorder + +import ( + e "simrs-vx/internal/domain/main-entities/material-order" +) + +func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.MaterialOrder) { + var inputSrc *e.CreateDto + if inputT, ok := any(input).(*e.CreateDto); ok { + inputSrc = inputT + } else { + inputTemp := any(input).(*e.UpdateDto) + inputSrc = &inputTemp.CreateDto + } + + data.Encounter_Id = inputSrc.Encounter_Id +} diff --git a/internal/use-case/main-use-case/material-order/lib.go b/internal/use-case/main-use-case/material-order/lib.go new file mode 100644 index 00000000..27b91ce1 --- /dev/null +++ b/internal/use-case/main-use-case/material-order/lib.go @@ -0,0 +1,155 @@ +package materialorder + +import ( + e "simrs-vx/internal/domain/main-entities/material-order" + 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.MaterialOrder, error) { + pl.SetLogInfo(event, nil, "started", "DBCreate") + + data := e.MaterialOrder{} + 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.MaterialOrder, *e.MetaDto, error) { + pl.SetLogInfo(event, input, "started", "DBReadList") + data := []e.MaterialOrder{} + 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.MaterialOrder{}). + 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.MaterialOrder, error) { + pl.SetLogInfo(event, input, "started", "DBReadDetail") + data := e.MaterialOrder{} + + 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.MaterialOrder, 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.MaterialOrder, 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/material-order/middleware-runner.go b/internal/use-case/main-use-case/material-order/middleware-runner.go new file mode 100644 index 00000000..0e872c9e --- /dev/null +++ b/internal/use-case/main-use-case/material-order/middleware-runner.go @@ -0,0 +1,103 @@ +package materialorder + +import ( + e "simrs-vx/internal/domain/main-entities/material-order" + 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.MaterialOrder) 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.MaterialOrder) 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.MaterialOrder) 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.MaterialOrder) 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.MaterialOrder) 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/material-order/middleware.go b/internal/use-case/main-use-case/material-order/middleware.go new file mode 100644 index 00000000..e6bb67d6 --- /dev/null +++ b/internal/use-case/main-use-case/material-order/middleware.go @@ -0,0 +1,9 @@ +package materialorder + +// 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/material-order/tycovar.go b/internal/use-case/main-use-case/material-order/tycovar.go new file mode 100644 index 00000000..5aaff1ce --- /dev/null +++ b/internal/use-case/main-use-case/material-order/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 materialorder + +import ( + "gorm.io/gorm" + + e "simrs-vx/internal/domain/main-entities/material-order" +) + +type createMw struct { + Name string + Func func(input *e.CreateDto, data *e.MaterialOrder, tx *gorm.DB) error +} + +type readListMw struct { + Name string + Func func(input *e.ReadListDto, data *e.MaterialOrder, tx *gorm.DB) error +} + +type readDetailMw struct { + Name string + Func func(input *e.ReadDetailDto, data *e.MaterialOrder, 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-item/case.go b/internal/use-case/main-use-case/mcu-order-item/case.go new file mode 100644 index 00000000..74323143 --- /dev/null +++ b/internal/use-case/main-use-case/mcu-order-item/case.go @@ -0,0 +1,279 @@ +package mcuorderitem + +import ( + "strconv" + + e "simrs-vx/internal/domain/main-entities/mcu-order-item" + + 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-item" + +func Create(input e.CreateDto) (*d.Data, error) { + data := e.McuOrderItem{} + + 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 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.McuOrderItem + var dataList []e.McuOrderItem + 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.McuOrderItem + 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.McuOrderItem + 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.McuOrderItem + 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-order-item/helper.go b/internal/use-case/main-use-case/mcu-order-item/helper.go new file mode 100644 index 00000000..48eaaf09 --- /dev/null +++ b/internal/use-case/main-use-case/mcu-order-item/helper.go @@ -0,0 +1,24 @@ +/* +DESCRIPTION: +Any functions that are used internally by the use-case +*/ +package mcuorderitem + +import ( + e "simrs-vx/internal/domain/main-entities/mcu-order-item" +) + +func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.McuOrderItem) { + var inputSrc *e.CreateDto + if inputT, ok := any(input).(*e.CreateDto); ok { + inputSrc = inputT + } else { + inputTemp := any(input).(*e.UpdateDto) + inputSrc = &inputTemp.CreateDto + } + + data.McuOrder_Id = inputSrc.McuOrder_Id + data.McuSrc_Id = inputSrc.McuSrc_Id + data.Result = inputSrc.Result + data.Status_Code = inputSrc.Status_Code +} 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 new file mode 100644 index 00000000..be5c0374 --- /dev/null +++ b/internal/use-case/main-use-case/mcu-order-item/lib.go @@ -0,0 +1,155 @@ +package mcuorderitem + +import ( + e "simrs-vx/internal/domain/main-entities/mcu-order-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.McuOrderItem, error) { + pl.SetLogInfo(event, nil, "started", "DBCreate") + + data := e.McuOrderItem{} + 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.McuOrderItem, *e.MetaDto, error) { + pl.SetLogInfo(event, input, "started", "DBReadList") + data := []e.McuOrderItem{} + 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.McuOrderItem{}). + 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.McuOrderItem, error) { + pl.SetLogInfo(event, input, "started", "DBReadDetail") + data := e.McuOrderItem{} + + 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.McuOrderItem, 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.McuOrderItem, 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-item/middleware-runner.go b/internal/use-case/main-use-case/mcu-order-item/middleware-runner.go new file mode 100644 index 00000000..d80da394 --- /dev/null +++ b/internal/use-case/main-use-case/mcu-order-item/middleware-runner.go @@ -0,0 +1,103 @@ +package mcuorderitem + +import ( + e "simrs-vx/internal/domain/main-entities/mcu-order-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.McuOrderItem) 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.McuOrderItem) 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.McuOrderItem) 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.McuOrderItem) 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.McuOrderItem) 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-item/middleware.go b/internal/use-case/main-use-case/mcu-order-item/middleware.go new file mode 100644 index 00000000..33e97e3d --- /dev/null +++ b/internal/use-case/main-use-case/mcu-order-item/middleware.go @@ -0,0 +1,9 @@ +package mcuorderitem + +// 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-item/tycovar.go b/internal/use-case/main-use-case/mcu-order-item/tycovar.go new file mode 100644 index 00000000..4e3f10b2 --- /dev/null +++ b/internal/use-case/main-use-case/mcu-order-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 mcuorderitem + +import ( + "gorm.io/gorm" + + e "simrs-vx/internal/domain/main-entities/mcu-order-item" +) + +type createMw struct { + Name string + Func func(input *e.CreateDto, data *e.McuOrderItem, tx *gorm.DB) error +} + +type readListMw struct { + Name string + Func func(input *e.ReadListDto, data *e.McuOrderItem, tx *gorm.DB) error +} + +type readDetailMw struct { + Name string + Func func(input *e.ReadDetailDto, data *e.McuOrderItem, 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 new file mode 100644 index 00000000..b000ffc8 --- /dev/null +++ b/internal/use-case/main-use-case/mcu-order/case.go @@ -0,0 +1,279 @@ +package mcuorder + +import ( + "strconv" + + e "simrs-vx/internal/domain/main-entities/mcu-order" + + 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" + +func Create(input e.CreateDto) (*d.Data, error) { + data := e.McuOrder{} + + 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 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.McuOrder + var dataList []e.McuOrder + 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.McuOrder + 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.McuOrder + 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.McuOrder + 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-order/helper.go b/internal/use-case/main-use-case/mcu-order/helper.go new file mode 100644 index 00000000..cb0b9878 --- /dev/null +++ b/internal/use-case/main-use-case/mcu-order/helper.go @@ -0,0 +1,23 @@ +/* +DESCRIPTION: +Any functions that are used internally by the use-case +*/ +package mcuorder + +import ( + e "simrs-vx/internal/domain/main-entities/mcu-order" +) + +func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.McuOrder) { + var inputSrc *e.CreateDto + if inputT, ok := any(input).(*e.CreateDto); ok { + inputSrc = inputT + } else { + inputTemp := any(input).(*e.UpdateDto) + inputSrc = &inputTemp.CreateDto + } + + data.Encounter_Id = inputSrc.Encounter_Id + data.Status_Code = inputSrc.Status_Code + data.Doctor_Id = inputSrc.Doctor_Id +} diff --git a/internal/use-case/main-use-case/mcu-order/lib.go b/internal/use-case/main-use-case/mcu-order/lib.go new file mode 100644 index 00000000..1cfd7adc --- /dev/null +++ b/internal/use-case/main-use-case/mcu-order/lib.go @@ -0,0 +1,155 @@ +package mcuorder + +import ( + e "simrs-vx/internal/domain/main-entities/mcu-order" + 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.McuOrder, error) { + pl.SetLogInfo(event, nil, "started", "DBCreate") + + data := e.McuOrder{} + 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.McuOrder, *e.MetaDto, error) { + pl.SetLogInfo(event, input, "started", "DBReadList") + data := []e.McuOrder{} + 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.McuOrder{}). + 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.McuOrder, error) { + pl.SetLogInfo(event, input, "started", "DBReadDetail") + data := e.McuOrder{} + + 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.McuOrder, 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.McuOrder, 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/middleware-runner.go b/internal/use-case/main-use-case/mcu-order/middleware-runner.go new file mode 100644 index 00000000..00db4da6 --- /dev/null +++ b/internal/use-case/main-use-case/mcu-order/middleware-runner.go @@ -0,0 +1,103 @@ +package mcuorder + +import ( + e "simrs-vx/internal/domain/main-entities/mcu-order" + 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.McuOrder) 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.McuOrder) 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.McuOrder) 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.McuOrder) 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.McuOrder) 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/middleware.go b/internal/use-case/main-use-case/mcu-order/middleware.go new file mode 100644 index 00000000..7c033a49 --- /dev/null +++ b/internal/use-case/main-use-case/mcu-order/middleware.go @@ -0,0 +1,9 @@ +package mcuorder + +// 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/tycovar.go b/internal/use-case/main-use-case/mcu-order/tycovar.go new file mode 100644 index 00000000..a4c8de62 --- /dev/null +++ b/internal/use-case/main-use-case/mcu-order/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 mcuorder + +import ( + "gorm.io/gorm" + + e "simrs-vx/internal/domain/main-entities/mcu-order" +) + +type createMw struct { + Name string + Func func(input *e.CreateDto, data *e.McuOrder, tx *gorm.DB) error +} + +type readListMw struct { + Name string + Func func(input *e.ReadListDto, data *e.McuOrder, tx *gorm.DB) error +} + +type readDetailMw struct { + Name string + Func func(input *e.ReadDetailDto, data *e.McuOrder, 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-item-dist/case.go b/internal/use-case/main-use-case/medication-item-dist/case.go new file mode 100644 index 00000000..c2b87993 --- /dev/null +++ b/internal/use-case/main-use-case/medication-item-dist/case.go @@ -0,0 +1,279 @@ +package medicationitemdist + +import ( + "strconv" + + e "simrs-vx/internal/domain/main-entities/medication-item-dist" + + 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 = "medication-item-dist" + +func Create(input e.CreateDto) (*d.Data, error) { + data := e.MedicationItemDist{} + + 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 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.MedicationItemDist + var dataList []e.MedicationItemDist + 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.MedicationItemDist + 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.MedicationItemDist + 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.MedicationItemDist + 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/medication-item-dist/helper.go b/internal/use-case/main-use-case/medication-item-dist/helper.go new file mode 100644 index 00000000..eadc8958 --- /dev/null +++ b/internal/use-case/main-use-case/medication-item-dist/helper.go @@ -0,0 +1,23 @@ +/* +DESCRIPTION: +Any functions that are used internally by the use-case +*/ +package medicationitemdist + +import ( + e "simrs-vx/internal/domain/main-entities/medication-item-dist" +) + +func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.MedicationItemDist) { + var inputSrc *e.CreateDto + if inputT, ok := any(input).(*e.CreateDto); ok { + inputSrc = inputT + } else { + inputTemp := any(input).(*e.UpdateDto) + inputSrc = &inputTemp.CreateDto + } + + data.MedicationItem_Id = inputSrc.MedicationItem_Id + data.DateTime = inputSrc.DateTime + data.Remain = inputSrc.Remain +} diff --git a/internal/use-case/main-use-case/medication-item-dist/lib.go b/internal/use-case/main-use-case/medication-item-dist/lib.go new file mode 100644 index 00000000..f39b8753 --- /dev/null +++ b/internal/use-case/main-use-case/medication-item-dist/lib.go @@ -0,0 +1,155 @@ +package medicationitemdist + +import ( + e "simrs-vx/internal/domain/main-entities/medication-item-dist" + 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.MedicationItemDist, error) { + pl.SetLogInfo(event, nil, "started", "DBCreate") + + data := e.MedicationItemDist{} + 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.MedicationItemDist, *e.MetaDto, error) { + pl.SetLogInfo(event, input, "started", "DBReadList") + data := []e.MedicationItemDist{} + 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.MedicationItemDist{}). + 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.MedicationItemDist, error) { + pl.SetLogInfo(event, input, "started", "DBReadDetail") + data := e.MedicationItemDist{} + + 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.MedicationItemDist, 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.MedicationItemDist, 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/medication-item-dist/middleware-runner.go b/internal/use-case/main-use-case/medication-item-dist/middleware-runner.go new file mode 100644 index 00000000..8dc45e4f --- /dev/null +++ b/internal/use-case/main-use-case/medication-item-dist/middleware-runner.go @@ -0,0 +1,103 @@ +package medicationitemdist + +import ( + e "simrs-vx/internal/domain/main-entities/medication-item-dist" + 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.MedicationItemDist) 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.MedicationItemDist) 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.MedicationItemDist) 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.MedicationItemDist) 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.MedicationItemDist) 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/medication-item-dist/middleware.go b/internal/use-case/main-use-case/medication-item-dist/middleware.go new file mode 100644 index 00000000..e519da96 --- /dev/null +++ b/internal/use-case/main-use-case/medication-item-dist/middleware.go @@ -0,0 +1,9 @@ +package medicationitemdist + +// 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/medication-item-dist/tycovar.go b/internal/use-case/main-use-case/medication-item-dist/tycovar.go new file mode 100644 index 00000000..38334e8b --- /dev/null +++ b/internal/use-case/main-use-case/medication-item-dist/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 medicationitemdist + +import ( + "gorm.io/gorm" + + e "simrs-vx/internal/domain/main-entities/medication-item-dist" +) + +type createMw struct { + Name string + Func func(input *e.CreateDto, data *e.MedicationItemDist, tx *gorm.DB) error +} + +type readListMw struct { + Name string + Func func(input *e.ReadListDto, data *e.MedicationItemDist, tx *gorm.DB) error +} + +type readDetailMw struct { + Name string + Func func(input *e.ReadDetailDto, data *e.MedicationItemDist, 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-item/case.go b/internal/use-case/main-use-case/medication-item/case.go new file mode 100644 index 00000000..1573a5a7 --- /dev/null +++ b/internal/use-case/main-use-case/medication-item/case.go @@ -0,0 +1,279 @@ +package medicationitem + +import ( + "strconv" + + e "simrs-vx/internal/domain/main-entities/medication-item" + + 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 = "medication-item" + +func Create(input e.CreateDto) (*d.Data, error) { + data := e.MedicationItem{} + + 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 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.MedicationItem + var dataList []e.MedicationItem + 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.MedicationItem + 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.MedicationItem + 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.MedicationItem + 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/medication-item/helper.go b/internal/use-case/main-use-case/medication-item/helper.go new file mode 100644 index 00000000..67b8a204 --- /dev/null +++ b/internal/use-case/main-use-case/medication-item/helper.go @@ -0,0 +1,26 @@ +/* +DESCRIPTION: +Any functions that are used internally by the use-case +*/ +package medicationitem + +import ( + e "simrs-vx/internal/domain/main-entities/medication-item" +) + +func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.MedicationItem) { + var inputSrc *e.CreateDto + if inputT, ok := any(input).(*e.CreateDto); ok { + inputSrc = inputT + } else { + inputTemp := any(input).(*e.UpdateDto) + inputSrc = &inputTemp.CreateDto + } + + data.Medication_Id = inputSrc.Medication_Id + data.IsMix = inputSrc.IsMix + data.Medicine_Id = inputSrc.Medicine_Id + data.MedicineMix_Id = inputSrc.MedicineMix_Id + data.Usage = inputSrc.Usage + data.Interval = inputSrc.Interval +} diff --git a/internal/use-case/main-use-case/medication-item/lib.go b/internal/use-case/main-use-case/medication-item/lib.go new file mode 100644 index 00000000..3dbab755 --- /dev/null +++ b/internal/use-case/main-use-case/medication-item/lib.go @@ -0,0 +1,155 @@ +package medicationitem + +import ( + e "simrs-vx/internal/domain/main-entities/medication-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.MedicationItem, error) { + pl.SetLogInfo(event, nil, "started", "DBCreate") + + data := e.MedicationItem{} + 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.MedicationItem, *e.MetaDto, error) { + pl.SetLogInfo(event, input, "started", "DBReadList") + data := []e.MedicationItem{} + 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.MedicationItem{}). + 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.MedicationItem, error) { + pl.SetLogInfo(event, input, "started", "DBReadDetail") + data := e.MedicationItem{} + + 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.MedicationItem, 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.MedicationItem, 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/medication-item/middleware-runner.go b/internal/use-case/main-use-case/medication-item/middleware-runner.go new file mode 100644 index 00000000..875f8235 --- /dev/null +++ b/internal/use-case/main-use-case/medication-item/middleware-runner.go @@ -0,0 +1,103 @@ +package medicationitem + +import ( + e "simrs-vx/internal/domain/main-entities/medication-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.MedicationItem) 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.MedicationItem) 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.MedicationItem) 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.MedicationItem) 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.MedicationItem) 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/medication-item/middleware.go b/internal/use-case/main-use-case/medication-item/middleware.go new file mode 100644 index 00000000..5fa37ffe --- /dev/null +++ b/internal/use-case/main-use-case/medication-item/middleware.go @@ -0,0 +1,9 @@ +package medicationitem + +// 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/medication-item/tycovar.go b/internal/use-case/main-use-case/medication-item/tycovar.go new file mode 100644 index 00000000..04d1d95b --- /dev/null +++ b/internal/use-case/main-use-case/medication-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 medicationitem + +import ( + "gorm.io/gorm" + + e "simrs-vx/internal/domain/main-entities/medication-item" +) + +type createMw struct { + Name string + Func func(input *e.CreateDto, data *e.MedicationItem, tx *gorm.DB) error +} + +type readListMw struct { + Name string + Func func(input *e.ReadListDto, data *e.MedicationItem, tx *gorm.DB) error +} + +type readDetailMw struct { + Name string + Func func(input *e.ReadDetailDto, data *e.MedicationItem, 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 new file mode 100644 index 00000000..df23a586 --- /dev/null +++ b/internal/use-case/main-use-case/medication/case.go @@ -0,0 +1,279 @@ +package medication + +import ( + "strconv" + + e "simrs-vx/internal/domain/main-entities/medication" + + 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 = "medication" + +func Create(input e.CreateDto) (*d.Data, error) { + data := e.Medication{} + + 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 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.Medication + var dataList []e.Medication + 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.Medication + 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.Medication + 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.Medication + 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/medication/helper.go b/internal/use-case/main-use-case/medication/helper.go new file mode 100644 index 00000000..f2d545ac --- /dev/null +++ b/internal/use-case/main-use-case/medication/helper.go @@ -0,0 +1,23 @@ +/* +DESCRIPTION: +Any functions that are used internally by the use-case +*/ +package medication + +import ( + e "simrs-vx/internal/domain/main-entities/medication" +) + +func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Medication) { + var inputSrc *e.CreateDto + if inputT, ok := any(input).(*e.CreateDto); ok { + inputSrc = inputT + } else { + inputTemp := any(input).(*e.UpdateDto) + inputSrc = &inputTemp.CreateDto + } + + data.Encounter_Id = inputSrc.Encounter_Id + data.IssuedAt = inputSrc.IssuedAt + data.Pharmacist_Id = inputSrc.Pharmacist_Id +} diff --git a/internal/use-case/main-use-case/medication/lib.go b/internal/use-case/main-use-case/medication/lib.go new file mode 100644 index 00000000..95488f11 --- /dev/null +++ b/internal/use-case/main-use-case/medication/lib.go @@ -0,0 +1,155 @@ +package medication + +import ( + e "simrs-vx/internal/domain/main-entities/medication" + 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.Medication, error) { + pl.SetLogInfo(event, nil, "started", "DBCreate") + + data := e.Medication{} + 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.Medication, *e.MetaDto, error) { + pl.SetLogInfo(event, input, "started", "DBReadList") + data := []e.Medication{} + 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.Medication{}). + 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.Medication, error) { + pl.SetLogInfo(event, input, "started", "DBReadDetail") + data := e.Medication{} + + 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.Medication, 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.Medication, 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/medication/middleware-runner.go b/internal/use-case/main-use-case/medication/middleware-runner.go new file mode 100644 index 00000000..88d9b728 --- /dev/null +++ b/internal/use-case/main-use-case/medication/middleware-runner.go @@ -0,0 +1,103 @@ +package medication + +import ( + e "simrs-vx/internal/domain/main-entities/medication" + 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.Medication) 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.Medication) 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.Medication) 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.Medication) 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.Medication) 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/medication/middleware.go b/internal/use-case/main-use-case/medication/middleware.go new file mode 100644 index 00000000..0eac76a7 --- /dev/null +++ b/internal/use-case/main-use-case/medication/middleware.go @@ -0,0 +1,9 @@ +package medication + +// 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/medication/tycovar.go b/internal/use-case/main-use-case/medication/tycovar.go new file mode 100644 index 00000000..5c9cbd8b --- /dev/null +++ b/internal/use-case/main-use-case/medication/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 medication + +import ( + "gorm.io/gorm" + + e "simrs-vx/internal/domain/main-entities/medication" +) + +type createMw struct { + Name string + Func func(input *e.CreateDto, data *e.Medication, tx *gorm.DB) error +} + +type readListMw struct { + Name string + Func func(input *e.ReadListDto, data *e.Medication, tx *gorm.DB) error +} + +type readDetailMw struct { + Name string + Func func(input *e.ReadDetailDto, data *e.Medication, 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/prescription-item/case.go b/internal/use-case/main-use-case/prescription-item/case.go new file mode 100644 index 00000000..a6dd7be1 --- /dev/null +++ b/internal/use-case/main-use-case/prescription-item/case.go @@ -0,0 +1,279 @@ +package prescriptionitem + +import ( + "strconv" + + e "simrs-vx/internal/domain/main-entities/prescription-item" + + 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 = "prescription-item" + +func Create(input e.CreateDto) (*d.Data, error) { + data := e.PrescriptionItem{} + + 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 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.PrescriptionItem + var dataList []e.PrescriptionItem + 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.PrescriptionItem + 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.PrescriptionItem + 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.PrescriptionItem + 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/prescription-item/helper.go b/internal/use-case/main-use-case/prescription-item/helper.go new file mode 100644 index 00000000..e63ca8c7 --- /dev/null +++ b/internal/use-case/main-use-case/prescription-item/helper.go @@ -0,0 +1,26 @@ +/* +DESCRIPTION: +Any functions that are used internally by the use-case +*/ +package prescriptionitem + +import ( + e "simrs-vx/internal/domain/main-entities/prescription-item" +) + +func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.PrescriptionItem) { + var inputSrc *e.CreateDto + if inputT, ok := any(input).(*e.CreateDto); ok { + inputSrc = inputT + } else { + inputTemp := any(input).(*e.UpdateDto) + inputSrc = &inputTemp.CreateDto + } + + data.Prescription_Id = inputSrc.Prescription_Id + data.IsMix = inputSrc.IsMix + data.Medicine_Id = inputSrc.Medicine_Id + data.MedicineMix_Id = inputSrc.MedicineMix_Id + data.Usage = inputSrc.Usage + data.Interval = inputSrc.Interval +} diff --git a/internal/use-case/main-use-case/prescription-item/lib.go b/internal/use-case/main-use-case/prescription-item/lib.go new file mode 100644 index 00000000..800096fd --- /dev/null +++ b/internal/use-case/main-use-case/prescription-item/lib.go @@ -0,0 +1,155 @@ +package prescriptionitem + +import ( + e "simrs-vx/internal/domain/main-entities/prescription-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.PrescriptionItem, error) { + pl.SetLogInfo(event, nil, "started", "DBCreate") + + data := e.PrescriptionItem{} + 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.PrescriptionItem, *e.MetaDto, error) { + pl.SetLogInfo(event, input, "started", "DBReadList") + data := []e.PrescriptionItem{} + 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.PrescriptionItem{}). + 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.PrescriptionItem, error) { + pl.SetLogInfo(event, input, "started", "DBReadDetail") + data := e.PrescriptionItem{} + + 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.PrescriptionItem, 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.PrescriptionItem, 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/prescription-item/middleware-runner.go b/internal/use-case/main-use-case/prescription-item/middleware-runner.go new file mode 100644 index 00000000..04d5aa00 --- /dev/null +++ b/internal/use-case/main-use-case/prescription-item/middleware-runner.go @@ -0,0 +1,103 @@ +package prescriptionitem + +import ( + e "simrs-vx/internal/domain/main-entities/prescription-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.PrescriptionItem) 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.PrescriptionItem) 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.PrescriptionItem) 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.PrescriptionItem) 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.PrescriptionItem) 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/prescription-item/middleware.go b/internal/use-case/main-use-case/prescription-item/middleware.go new file mode 100644 index 00000000..23d4fe7a --- /dev/null +++ b/internal/use-case/main-use-case/prescription-item/middleware.go @@ -0,0 +1,9 @@ +package prescriptionitem + +// 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/prescription-item/tycovar.go b/internal/use-case/main-use-case/prescription-item/tycovar.go new file mode 100644 index 00000000..9ec60a94 --- /dev/null +++ b/internal/use-case/main-use-case/prescription-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 prescriptionitem + +import ( + "gorm.io/gorm" + + e "simrs-vx/internal/domain/main-entities/prescription-item" +) + +type createMw struct { + Name string + Func func(input *e.CreateDto, data *e.PrescriptionItem, tx *gorm.DB) error +} + +type readListMw struct { + Name string + Func func(input *e.ReadListDto, data *e.PrescriptionItem, tx *gorm.DB) error +} + +type readDetailMw struct { + Name string + Func func(input *e.ReadDetailDto, data *e.PrescriptionItem, 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/prescription/case.go b/internal/use-case/main-use-case/prescription/case.go new file mode 100644 index 00000000..9b0baeb2 --- /dev/null +++ b/internal/use-case/main-use-case/prescription/case.go @@ -0,0 +1,279 @@ +package prescription + +import ( + "strconv" + + e "simrs-vx/internal/domain/main-entities/prescription" + + 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 = "prescription" + +func Create(input e.CreateDto) (*d.Data, error) { + data := e.Prescription{} + + 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 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.Prescription + var dataList []e.Prescription + 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.Prescription + 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.Prescription + 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.Prescription + 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/prescription/helper.go b/internal/use-case/main-use-case/prescription/helper.go new file mode 100644 index 00000000..768d11bd --- /dev/null +++ b/internal/use-case/main-use-case/prescription/helper.go @@ -0,0 +1,23 @@ +/* +DESCRIPTION: +Any functions that are used internally by the use-case +*/ +package prescription + +import ( + e "simrs-vx/internal/domain/main-entities/prescription" +) + +func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Prescription) { + var inputSrc *e.CreateDto + if inputT, ok := any(input).(*e.CreateDto); ok { + inputSrc = inputT + } else { + inputTemp := any(input).(*e.UpdateDto) + inputSrc = &inputTemp.CreateDto + } + + data.Encounter_Id = inputSrc.Encounter_Id + data.Doctor_Id = inputSrc.Doctor_Id + data.IssuedAt = inputSrc.IssuedAt +} diff --git a/internal/use-case/main-use-case/prescription/lib.go b/internal/use-case/main-use-case/prescription/lib.go new file mode 100644 index 00000000..bf1fe36b --- /dev/null +++ b/internal/use-case/main-use-case/prescription/lib.go @@ -0,0 +1,155 @@ +package prescription + +import ( + e "simrs-vx/internal/domain/main-entities/prescription" + 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.Prescription, error) { + pl.SetLogInfo(event, nil, "started", "DBCreate") + + data := e.Prescription{} + 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.Prescription, *e.MetaDto, error) { + pl.SetLogInfo(event, input, "started", "DBReadList") + data := []e.Prescription{} + 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.Prescription{}). + 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.Prescription, error) { + pl.SetLogInfo(event, input, "started", "DBReadDetail") + data := e.Prescription{} + + 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.Prescription, 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.Prescription, 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/prescription/middleware-runner.go b/internal/use-case/main-use-case/prescription/middleware-runner.go new file mode 100644 index 00000000..e5ccb023 --- /dev/null +++ b/internal/use-case/main-use-case/prescription/middleware-runner.go @@ -0,0 +1,103 @@ +package prescription + +import ( + e "simrs-vx/internal/domain/main-entities/prescription" + 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.Prescription) 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.Prescription) 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.Prescription) 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.Prescription) 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.Prescription) 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/prescription/middleware.go b/internal/use-case/main-use-case/prescription/middleware.go new file mode 100644 index 00000000..6a61bfc6 --- /dev/null +++ b/internal/use-case/main-use-case/prescription/middleware.go @@ -0,0 +1,9 @@ +package prescription + +// 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/prescription/tycovar.go b/internal/use-case/main-use-case/prescription/tycovar.go new file mode 100644 index 00000000..ab938fce --- /dev/null +++ b/internal/use-case/main-use-case/prescription/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 prescription + +import ( + "gorm.io/gorm" + + e "simrs-vx/internal/domain/main-entities/prescription" +) + +type createMw struct { + Name string + Func func(input *e.CreateDto, data *e.Prescription, tx *gorm.DB) error +} + +type readListMw struct { + Name string + Func func(input *e.ReadListDto, data *e.Prescription, tx *gorm.DB) error +} + +type readDetailMw struct { + Name string + Func func(input *e.ReadDetailDto, data *e.Prescription, 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 From 29f0ff688762fb768533fd92d189d9f67bc2477e Mon Sep 17 00:00:00 2001 From: dpurbosakti Date: Mon, 15 Sep 2025 19:36:26 +0700 Subject: [PATCH 4/6] add migration for several order tables --- .../migrations/20250915123412.sql | 146 ++++++++++++++++++ cmd/main-migration/migrations/atlas.sum | 3 +- .../main-entities/medication-item/dto.go | 68 ++++---- .../main-entities/medication-item/entity.go | 24 +-- .../main-entities/prescription-item/dto.go | 65 ++++---- .../main-entities/prescription-item/entity.go | 24 +-- 6 files changed, 244 insertions(+), 86 deletions(-) create mode 100644 cmd/main-migration/migrations/20250915123412.sql diff --git a/cmd/main-migration/migrations/20250915123412.sql b/cmd/main-migration/migrations/20250915123412.sql new file mode 100644 index 00000000..5bb948f0 --- /dev/null +++ b/cmd/main-migration/migrations/20250915123412.sql @@ -0,0 +1,146 @@ +-- Create "DeviceOrder" table +CREATE TABLE "public"."DeviceOrder" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "Encounter_Id" bigint NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "fk_DeviceOrder_Encounter" FOREIGN KEY ("Encounter_Id") REFERENCES "public"."Encounter" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION +); +-- Create "DeviceOrderItem" table +CREATE TABLE "public"."DeviceOrderItem" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "DeviceOrder_Id" bigint NULL, + "Device_Id" bigint NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "fk_DeviceOrderItem_Device" FOREIGN KEY ("Device_Id") REFERENCES "public"."Device" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT "fk_DeviceOrderItem_DeviceOrder" FOREIGN KEY ("DeviceOrder_Id") REFERENCES "public"."DeviceOrder" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION +); +-- Create "MaterialOrder" table +CREATE TABLE "public"."MaterialOrder" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "Encounter_Id" bigint NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "fk_MaterialOrder_Encounter" FOREIGN KEY ("Encounter_Id") REFERENCES "public"."Encounter" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION +); +-- Create "MaterialOrderItem" table +CREATE TABLE "public"."MaterialOrderItem" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "MaterialOrder_Id" bigint NULL, + "Material_Id" bigint NULL, + "Count" integer NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "fk_MaterialOrderItem_Material" FOREIGN KEY ("Material_Id") REFERENCES "public"."Material" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT "fk_MaterialOrderItem_MaterialOrder" FOREIGN KEY ("MaterialOrder_Id") REFERENCES "public"."MaterialOrder" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION +); +-- Create "McuOrder" table +CREATE TABLE "public"."McuOrder" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "Encounter_Id" bigint NULL, + "Status_Code" character varying(10) NOT NULL, + "Doctor_Id" bigint NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "fk_McuOrder_Doctor" FOREIGN KEY ("Doctor_Id") REFERENCES "public"."Doctor" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT "fk_McuOrder_Encounter" FOREIGN KEY ("Encounter_Id") REFERENCES "public"."Encounter" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION +); +-- Create "McuOrderItem" table +CREATE TABLE "public"."McuOrderItem" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "McuOrder_Id" bigint NULL, + "McuSrc_Id" bigint NULL, + "Result" text NULL, + "Status_Code" text NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "fk_McuOrderItem_McuOrder" FOREIGN KEY ("McuOrder_Id") REFERENCES "public"."McuOrder" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT "fk_McuOrderItem_McuSrc" FOREIGN KEY ("McuSrc_Id") REFERENCES "public"."McuSrc" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION +); +-- Create "Medication" table +CREATE TABLE "public"."Medication" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "Encounter_Id" bigint NULL, + "IssuedAt" timestamptz NULL, + "Pharmacist_Id" bigint NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "fk_Medication_Encounter" FOREIGN KEY ("Encounter_Id") REFERENCES "public"."Encounter" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT "fk_Medication_Pharmacist" FOREIGN KEY ("Pharmacist_Id") REFERENCES "public"."Pharmacist" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION +); +-- Create "MedicationItem" table +CREATE TABLE "public"."MedicationItem" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "Medication_Id" bigint NULL, + "IsMix" boolean NULL, + "Medicine_Id" bigint NULL, + "MedicineMix_Id" bigint NULL, + "Usage" smallint NULL, + "Interval" smallint NULL, + "IntervalUnit_Code" text NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "fk_MedicationItem_Medication" FOREIGN KEY ("Medication_Id") REFERENCES "public"."Medication" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT "fk_MedicationItem_Medicine" FOREIGN KEY ("Medicine_Id") REFERENCES "public"."Medicine" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT "fk_MedicationItem_MedicineMix" FOREIGN KEY ("MedicineMix_Id") REFERENCES "public"."MedicineMix" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION +); +-- Create "MedicationItemDist" table +CREATE TABLE "public"."MedicationItemDist" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "MedicationItem_Id" bigint NULL, + "DateTime" timestamptz NULL, + "Remain" bigint NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "fk_MedicationItemDist_MedicationItem" FOREIGN KEY ("MedicationItem_Id") REFERENCES "public"."MedicationItem" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION +); +-- Create "Prescription" table +CREATE TABLE "public"."Prescription" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "Encounter_Id" bigint NULL, + "Doctor_Id" bigint NULL, + "IssuedAt" timestamptz NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "fk_Prescription_Doctor" FOREIGN KEY ("Doctor_Id") REFERENCES "public"."Doctor" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT "fk_Prescription_Encounter" FOREIGN KEY ("Encounter_Id") REFERENCES "public"."Encounter" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION +); +-- Create "PrescriptionItem" table +CREATE TABLE "public"."PrescriptionItem" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "Prescription_Id" bigint NULL, + "IsMix" boolean NULL, + "Medicine_Id" bigint NULL, + "MedicineMix_Id" bigint NULL, + "Usage" smallint NULL, + "Interval" smallint NULL, + "IntervalUnit_Code" text NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "fk_PrescriptionItem_Medicine" FOREIGN KEY ("Medicine_Id") REFERENCES "public"."Medicine" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT "fk_PrescriptionItem_MedicineMix" FOREIGN KEY ("MedicineMix_Id") REFERENCES "public"."MedicineMix" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT "fk_PrescriptionItem_Prescription" FOREIGN KEY ("Prescription_Id") REFERENCES "public"."Prescription" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION +); diff --git a/cmd/main-migration/migrations/atlas.sum b/cmd/main-migration/migrations/atlas.sum index 3482f994..7bc09afb 100644 --- a/cmd/main-migration/migrations/atlas.sum +++ b/cmd/main-migration/migrations/atlas.sum @@ -1,4 +1,4 @@ -h1:BLtMDgAdnqZbCj3HUbiTlyYtA87C4LcP/uquCbM6GSE= +h1:vKW524Os6+DLuWTIk2ogb2LnlRoaYqgz1GLvvmc2KYA= 20250904105930.sql h1:MEM6blCgke9DzWQSTnLzasbPIrcHssNNrJqZpSkEo6k= 20250904141448.sql h1:J8cmYNk4ZrG9fhfbi2Z1IWz7YkfvhFqTzrLFo58BPY0= 20250908062237.sql h1:Pu23yEW/aKkwozHoOuROvHS/GK4ngARJGdO7FB7HZuI= @@ -6,3 +6,4 @@ h1:BLtMDgAdnqZbCj3HUbiTlyYtA87C4LcP/uquCbM6GSE= 20250908073811.sql h1:m2aNXfnGxnLq1+rVWrh4f60q7fhyhV3gEwNu/OIqQlE= 20250908073839.sql h1:cPk54xjLdMs26uY8ZHjNWLuyfAMzV7Zb0/9oJQrsw04= 20250910055902.sql h1:5xwjAV6QbtZT9empTJKfhyAjdknbHzb15B0Ku5dzqtQ= +20250915123412.sql h1:CndzsEFauRnieT/Qv/kqZ5Gr49g6f127Tq/fskHAPwg= diff --git a/internal/domain/main-entities/medication-item/dto.go b/internal/domain/main-entities/medication-item/dto.go index 2b4e0ed1..59ae7688 100644 --- a/internal/domain/main-entities/medication-item/dto.go +++ b/internal/domain/main-entities/medication-item/dto.go @@ -5,16 +5,17 @@ import ( eme "simrs-vx/internal/domain/main-entities/medication" em "simrs-vx/internal/domain/main-entities/medicine" emm "simrs-vx/internal/domain/main-entities/medicine-mix" + erc "simrs-vx/internal/domain/references/common" ) type CreateDto struct { - Medication_Id *uint `json:"medication_id"` - IsMix bool `json:"isMix"` - Medicine_Id *uint `json:"medicine_id"` - MedicineMix_Id *uint `json:"medicineMix_id"` - Usage uint8 `json:"usage"` - Interval uint8 `json:"interval"` - // IntervalUnit_Code + Medication_Id *uint `json:"medication_id"` + IsMix bool `json:"isMix"` + Medicine_Id *uint `json:"medicine_id"` + MedicineMix_Id *uint `json:"medicineMix_id"` + Usage uint8 `json:"usage"` + Interval uint8 `json:"interval"` + IntervalUnit_Code erc.TimeUnitCode `json:"intervalUnit_code"` } type ReadListDto struct { @@ -24,13 +25,13 @@ type ReadListDto struct { } type FilterDto struct { - Medication_Id *uint `json:"medication_id"` - IsMix bool `json:"isMix"` - Medicine_Id *uint `json:"medicine_id"` - MedicineMix_Id *uint `json:"medicineMix_id"` - Usage uint8 `json:"usage"` - Interval uint8 `json:"interval"` - // IntervalUnit_Code + Medication_Id *uint `json:"medication_id"` + IsMix bool `json:"isMix"` + Medicine_Id *uint `json:"medicine_id"` + MedicineMix_Id *uint `json:"medicineMix_id"` + Usage uint8 `json:"usage"` + Interval uint8 `json:"interval"` + IntervalUnit_Code erc.TimeUnitCode `json:"intervalUnit_code"` Page int `json:"page"` PageSize int `json:"page_size"` @@ -57,29 +58,30 @@ type MetaDto struct { type ResponseDto struct { ecore.Main - Medication_Id *uint `json:"medication_id"` - Medication *eme.Medication `json:"medication,omitempty"` - IsMix bool `json:"isMix"` - Medicine_Id *uint `json:"medicine_id"` - Medicine *em.Medicine `json:"medicine,omitempty"` - MedicineMix_Id *uint `json:"medicineMix_id"` - MedicineMix *emm.MedicineMix `json:"medicineMix,omitempty"` - Usage uint8 `json:"usage"` - Interval uint8 `json:"interval"` - // IntervalUnit_Code + Medication_Id *uint `json:"medication_id"` + Medication *eme.Medication `json:"medication,omitempty"` + IsMix bool `json:"isMix"` + Medicine_Id *uint `json:"medicine_id"` + Medicine *em.Medicine `json:"medicine,omitempty"` + MedicineMix_Id *uint `json:"medicineMix_id"` + MedicineMix *emm.MedicineMix `json:"medicineMix,omitempty"` + Usage uint8 `json:"usage"` + Interval uint8 `json:"interval"` + IntervalUnit_Code erc.TimeUnitCode `json:"intervalUnit_code"` } func (d MedicationItem) ToResponse() ResponseDto { resp := ResponseDto{ - Medication_Id: d.Medication_Id, - Medication: d.Medication, - IsMix: d.IsMix, - Medicine_Id: d.Medicine_Id, - Medicine: d.Medicine, - MedicineMix_Id: d.MedicineMix_Id, - MedicineMix: d.MedicineMix, - Usage: d.Usage, - Interval: d.Interval, + Medication_Id: d.Medication_Id, + Medication: d.Medication, + IsMix: d.IsMix, + Medicine_Id: d.Medicine_Id, + Medicine: d.Medicine, + MedicineMix_Id: d.MedicineMix_Id, + MedicineMix: d.MedicineMix, + Usage: d.Usage, + Interval: d.Interval, + IntervalUnit_Code: d.IntervalUnit_Code, } resp.Main = d.Main return resp diff --git a/internal/domain/main-entities/medication-item/entity.go b/internal/domain/main-entities/medication-item/entity.go index 160b7dec..ef7f20ea 100644 --- a/internal/domain/main-entities/medication-item/entity.go +++ b/internal/domain/main-entities/medication-item/entity.go @@ -5,18 +5,20 @@ import ( eme "simrs-vx/internal/domain/main-entities/medication" em "simrs-vx/internal/domain/main-entities/medicine" emm "simrs-vx/internal/domain/main-entities/medicine-mix" + + erc "simrs-vx/internal/domain/references/common" ) type MedicationItem struct { - ecore.Main // adjust this according to the needs - Medication_Id *uint `json:"medication_id"` - Medication *eme.Medication `json:"medication,omitempty" gorm:"foreignKey:Medication_Id;references:Id"` - IsMix bool `json:"isMix"` - Medicine_Id *uint `json:"medicine_id"` - Medicine *em.Medicine `json:"medicine,omitempty" gorm:"foreignKey:Medicine_Id;references:Id"` - MedicineMix_Id *uint `json:"medicineMix_id"` - MedicineMix *emm.MedicineMix `json:"medicineMix,omitempty" gorm:"foreignKey:MedicineMix_Id;references:Id"` - Usage uint8 `json:"usage"` - Interval uint8 `json:"interval"` - // IntervalUnit_Code + ecore.Main // adjust this according to the needs + Medication_Id *uint `json:"medication_id"` + Medication *eme.Medication `json:"medication,omitempty" gorm:"foreignKey:Medication_Id;references:Id"` + IsMix bool `json:"isMix"` + Medicine_Id *uint `json:"medicine_id"` + Medicine *em.Medicine `json:"medicine,omitempty" gorm:"foreignKey:Medicine_Id;references:Id"` + MedicineMix_Id *uint `json:"medicineMix_id"` + MedicineMix *emm.MedicineMix `json:"medicineMix,omitempty" gorm:"foreignKey:MedicineMix_Id;references:Id"` + Usage uint8 `json:"usage"` + Interval uint8 `json:"interval"` + IntervalUnit_Code erc.TimeUnitCode `json:"intervalUnit_code"` } diff --git a/internal/domain/main-entities/prescription-item/dto.go b/internal/domain/main-entities/prescription-item/dto.go index 9d28a511..a87daaae 100644 --- a/internal/domain/main-entities/prescription-item/dto.go +++ b/internal/domain/main-entities/prescription-item/dto.go @@ -5,15 +5,17 @@ import ( em "simrs-vx/internal/domain/main-entities/medicine" emm "simrs-vx/internal/domain/main-entities/medicine-mix" ep "simrs-vx/internal/domain/main-entities/prescription" + erc "simrs-vx/internal/domain/references/common" ) type CreateDto struct { - Prescription_Id *uint `json:"prescription_id"` - IsMix bool `json:"isMix"` - Medicine_Id *uint `json:"medicine_id"` - MedicineMix_Id *uint `json:"medicineMix_id"` - Usage uint8 `json:"usage"` - Interval uint8 `json:"interval"` + Prescription_Id *uint `json:"prescription_id"` + IsMix bool `json:"isMix"` + Medicine_Id *uint `json:"medicine_id"` + MedicineMix_Id *uint `json:"medicineMix_id"` + Usage uint8 `json:"usage"` + Interval uint8 `json:"interval"` + IntervalUnit_Code erc.TimeUnitCode `json:"intervalUnit_code"` } type ReadListDto struct { @@ -23,12 +25,13 @@ type ReadListDto struct { } type FilterDto struct { - Prescription_Id *uint `json:"prescription_id"` - IsMix bool `json:"isMix"` - Medicine_Id *uint `json:"medicine_id"` - MedicineMix_Id *uint `json:"medicineMix_id"` - Usage uint8 `json:"usage"` - Interval uint8 `json:"interval"` + Prescription_Id *uint `json:"prescription_id"` + IsMix bool `json:"isMix"` + Medicine_Id *uint `json:"medicine_id"` + MedicineMix_Id *uint `json:"medicineMix_id"` + Usage uint8 `json:"usage"` + Interval uint8 `json:"interval"` + IntervalUnit_Code erc.TimeUnitCode `json:"intervalUnit_code"` Page int `json:"page"` PageSize int `json:"page_size"` @@ -55,28 +58,30 @@ type MetaDto struct { type ResponseDto struct { ecore.Main - Prescription_Id *uint `json:"prescription_id"` - Prescription *ep.Prescription `json:"prescription,omitempty"` - IsMix bool `json:"isMix"` - Medicine_Id *uint `json:"medicine_id"` - Medicine *em.Medicine `json:"medicine,omitempty"` - MedicineMix_Id *uint `json:"medicineMix_id"` - MedicineMix *emm.MedicineMix `json:"medicineMix,omitempty"` - Usage uint8 `json:"usage"` - Interval uint8 `json:"interval"` + Prescription_Id *uint `json:"prescription_id"` + Prescription *ep.Prescription `json:"prescription,omitempty"` + IsMix bool `json:"isMix"` + Medicine_Id *uint `json:"medicine_id"` + Medicine *em.Medicine `json:"medicine,omitempty"` + MedicineMix_Id *uint `json:"medicineMix_id"` + MedicineMix *emm.MedicineMix `json:"medicineMix,omitempty"` + Usage uint8 `json:"usage"` + Interval uint8 `json:"interval"` + IntervalUnit_Code erc.TimeUnitCode `json:"intervalUnit_code"` } func (d PrescriptionItem) ToResponse() ResponseDto { resp := ResponseDto{ - Prescription_Id: d.Prescription_Id, - Prescription: d.Prescription, - IsMix: d.IsMix, - Medicine_Id: d.Medicine_Id, - Medicine: d.Medicine, - MedicineMix_Id: d.MedicineMix_Id, - MedicineMix: d.MedicineMix, - Usage: d.Usage, - Interval: d.Interval, + Prescription_Id: d.Prescription_Id, + Prescription: d.Prescription, + IsMix: d.IsMix, + Medicine_Id: d.Medicine_Id, + Medicine: d.Medicine, + MedicineMix_Id: d.MedicineMix_Id, + MedicineMix: d.MedicineMix, + Usage: d.Usage, + Interval: d.Interval, + IntervalUnit_Code: d.IntervalUnit_Code, } resp.Main = d.Main return resp diff --git a/internal/domain/main-entities/prescription-item/entity.go b/internal/domain/main-entities/prescription-item/entity.go index 3898e170..3c662c5c 100644 --- a/internal/domain/main-entities/prescription-item/entity.go +++ b/internal/domain/main-entities/prescription-item/entity.go @@ -5,18 +5,20 @@ import ( em "simrs-vx/internal/domain/main-entities/medicine" emm "simrs-vx/internal/domain/main-entities/medicine-mix" ep "simrs-vx/internal/domain/main-entities/prescription" + + erc "simrs-vx/internal/domain/references/common" ) type PrescriptionItem struct { - ecore.Main // adjust this according to the needs - Prescription_Id *uint `json:"prescription_id"` - Prescription *ep.Prescription `json:"prescription,omitempty" gorm:"foreignKey:Prescription_Id;references:Id"` - IsMix bool `json:"isMix"` - Medicine_Id *uint `json:"medicine_id"` - Medicine *em.Medicine `json:"medicine,omitempty" gorm:"foreignKey:Medicine_Id;references:Id"` - MedicineMix_Id *uint `json:"medicineMix_id"` - MedicineMix *emm.MedicineMix `json:"medicineMix,omitempty" gorm:"foreignKey:MedicineMix_Id;references:Id"` - Usage uint8 `json:"usage"` - Interval uint8 `json:"interval"` - // IntervalUnit_Code + ecore.Main // adjust this according to the needs + Prescription_Id *uint `json:"prescription_id"` + Prescription *ep.Prescription `json:"prescription,omitempty" gorm:"foreignKey:Prescription_Id;references:Id"` + IsMix bool `json:"isMix"` + Medicine_Id *uint `json:"medicine_id"` + Medicine *em.Medicine `json:"medicine,omitempty" gorm:"foreignKey:Medicine_Id;references:Id"` + MedicineMix_Id *uint `json:"medicineMix_id"` + MedicineMix *emm.MedicineMix `json:"medicineMix,omitempty" gorm:"foreignKey:MedicineMix_Id;references:Id"` + Usage uint8 `json:"usage"` + Interval uint8 `json:"interval"` + IntervalUnit_Code erc.TimeUnitCode `json:"intervalUnit_code"` } From e8ff57168c1af46627a29a4812a5c1d6dbb8e8d0 Mon Sep 17 00:00:00 2001 From: dpurbosakti Date: Tue, 16 Sep 2025 11:44:36 +0700 Subject: [PATCH 5/6] update serveral field on order tables --- cmd/main-migration/Makefile | 2 +- .../migrations/20250916043819.sql | 14 ++++++++++ cmd/main-migration/migrations/atlas.sum | 5 ++-- cmd/satusehat-migration/Makefile | 2 +- .../main-entities/device-order-item/dto.go | 4 +++ .../main-entities/device-order-item/entity.go | 1 + .../domain/main-entities/device-order/dto.go | 13 ++++++--- .../main-entities/device-order/entity.go | 9 ++++--- .../main-entities/material-order/dto.go | 13 ++++++--- .../main-entities/material-order/entity.go | 9 ++++--- .../main-entities/medication-item-dist/dto.go | 10 ++++--- .../medication-item-dist/entity.go | 8 ++++-- .../main-entities/medication-item/dto.go | 10 ++++--- .../main-entities/medication-item/entity.go | 3 ++- .../domain/main-entities/medication/dto.go | 27 +++++++++++-------- .../domain/main-entities/medication/entity.go | 15 ++++++----- .../main-entities/prescription-item/dto.go | 6 ++--- .../main-entities/prescription-item/entity.go | 2 +- 18 files changed, 105 insertions(+), 48 deletions(-) create mode 100644 cmd/main-migration/migrations/20250916043819.sql diff --git a/cmd/main-migration/Makefile b/cmd/main-migration/Makefile index 92a4be84..e83356e5 100644 --- a/cmd/main-migration/Makefile +++ b/cmd/main-migration/Makefile @@ -15,4 +15,4 @@ apply: ## Calculate the schema hash hash: - atlas schema hash --env $(ENV) + atlas migrate hash diff --git a/cmd/main-migration/migrations/20250916043819.sql b/cmd/main-migration/migrations/20250916043819.sql new file mode 100644 index 00000000..1abe147b --- /dev/null +++ b/cmd/main-migration/migrations/20250916043819.sql @@ -0,0 +1,14 @@ +-- Modify "DeviceOrder" table +ALTER TABLE "public"."DeviceOrder" ADD COLUMN "Status_Code" text NULL; +-- Modify "DeviceOrderItem" table +ALTER TABLE "public"."DeviceOrderItem" ADD COLUMN "Count" smallint NULL; +-- Modify "MaterialOrder" table +ALTER TABLE "public"."MaterialOrder" ADD COLUMN "Status_Code" text NULL; +-- Modify "Medication" table +ALTER TABLE "public"."Medication" ADD COLUMN "Status_Code" text NULL; +-- Modify "MedicationItem" table +ALTER TABLE "public"."MedicationItem" ALTER COLUMN "Usage" TYPE numeric, ADD COLUMN "IsRedeemed" boolean NULL; +-- Modify "PrescriptionItem" table +ALTER TABLE "public"."PrescriptionItem" ALTER COLUMN "Usage" TYPE numeric; +-- Modify "MedicationItemDist" table +ALTER TABLE "public"."MedicationItemDist" ALTER COLUMN "Remain" TYPE numeric, ADD COLUMN "Nurse_Id" bigint NULL, ADD CONSTRAINT "fk_MedicationItemDist_Nurse" FOREIGN KEY ("Nurse_Id") REFERENCES "public"."Nurse" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION; diff --git a/cmd/main-migration/migrations/atlas.sum b/cmd/main-migration/migrations/atlas.sum index 7bc09afb..fcc26fdd 100644 --- a/cmd/main-migration/migrations/atlas.sum +++ b/cmd/main-migration/migrations/atlas.sum @@ -1,4 +1,4 @@ -h1:vKW524Os6+DLuWTIk2ogb2LnlRoaYqgz1GLvvmc2KYA= +h1:lwrJz1Vor7muHsLHihYT704fcsjyX/JmBfRLfg+4PjI= 20250904105930.sql h1:MEM6blCgke9DzWQSTnLzasbPIrcHssNNrJqZpSkEo6k= 20250904141448.sql h1:J8cmYNk4ZrG9fhfbi2Z1IWz7YkfvhFqTzrLFo58BPY0= 20250908062237.sql h1:Pu23yEW/aKkwozHoOuROvHS/GK4ngARJGdO7FB7HZuI= @@ -6,4 +6,5 @@ h1:vKW524Os6+DLuWTIk2ogb2LnlRoaYqgz1GLvvmc2KYA= 20250908073811.sql h1:m2aNXfnGxnLq1+rVWrh4f60q7fhyhV3gEwNu/OIqQlE= 20250908073839.sql h1:cPk54xjLdMs26uY8ZHjNWLuyfAMzV7Zb0/9oJQrsw04= 20250910055902.sql h1:5xwjAV6QbtZT9empTJKfhyAjdknbHzb15B0Ku5dzqtQ= -20250915123412.sql h1:CndzsEFauRnieT/Qv/kqZ5Gr49g6f127Tq/fskHAPwg= +20250915123412.sql h1:D83xaU2YlDEd21HLup/YQpQ2easMToYCyy/oK6AFgQs= +20250916043819.sql h1:qcON0PZq3bYL0dWZdDMHEvK9C7oH4JIMh5Il+RWA3UY= diff --git a/cmd/satusehat-migration/Makefile b/cmd/satusehat-migration/Makefile index 92a4be84..e83356e5 100644 --- a/cmd/satusehat-migration/Makefile +++ b/cmd/satusehat-migration/Makefile @@ -15,4 +15,4 @@ apply: ## Calculate the schema hash hash: - atlas schema hash --env $(ENV) + atlas migrate hash diff --git a/internal/domain/main-entities/device-order-item/dto.go b/internal/domain/main-entities/device-order-item/dto.go index 8b29a332..3added12 100644 --- a/internal/domain/main-entities/device-order-item/dto.go +++ b/internal/domain/main-entities/device-order-item/dto.go @@ -9,6 +9,7 @@ import ( type CreateDto struct { DeviceOrder_Id *uint `json:"deviceOrder_id"` Device_Id *uint `json:"device_id"` + Count uint8 `json:"count"` } type ReadListDto struct { @@ -20,6 +21,7 @@ type ReadListDto struct { type FilterDto struct { DeviceOrder_Id *uint `json:"deviceOrder_id"` Device_Id *uint `json:"device_id"` + Count uint8 `json:"count"` Page int `json:"page"` PageSize int `json:"page_size"` @@ -50,6 +52,7 @@ type ResponseDto struct { DeviceOrder *edo.DeviceOrder `json:"deviceOrder,omitempty"` Device_Id *uint `json:"device_id"` Device *ed.Device `json:"device,omitempty"` + Count uint8 `json:"count"` } func (d DeviceOrderItem) ToResponse() ResponseDto { @@ -58,6 +61,7 @@ func (d DeviceOrderItem) ToResponse() ResponseDto { DeviceOrder: d.DeviceOrder, Device_Id: d.Device_Id, Device: d.Device, + Count: d.Count, } resp.Main = d.Main return resp diff --git a/internal/domain/main-entities/device-order-item/entity.go b/internal/domain/main-entities/device-order-item/entity.go index 536f0e13..196415af 100644 --- a/internal/domain/main-entities/device-order-item/entity.go +++ b/internal/domain/main-entities/device-order-item/entity.go @@ -12,4 +12,5 @@ type DeviceOrderItem struct { DeviceOrder *edo.DeviceOrder `json:"deviceOrder,omitempty" gorm:"foreignKey:DeviceOrder_Id;references:Id"` Device_Id *uint `json:"device_id"` Device *ed.Device `json:"device,omitempty" gorm:"foreignKey:Device_Id;references:Id"` + Count uint8 `json:"count"` } diff --git a/internal/domain/main-entities/device-order/dto.go b/internal/domain/main-entities/device-order/dto.go index cf2fc5ff..f26d1155 100644 --- a/internal/domain/main-entities/device-order/dto.go +++ b/internal/domain/main-entities/device-order/dto.go @@ -3,10 +3,12 @@ package deviceorder import ( ecore "simrs-vx/internal/domain/base-entities/core" ee "simrs-vx/internal/domain/main-entities/encounter" + erc "simrs-vx/internal/domain/references/common" ) type CreateDto struct { - Encounter_Id *uint `json:"encounter_id"` + Encounter_Id *uint `json:"encounter_id"` + Status_Code erc.DataStatusCode `json:"status_code"` } type ReadListDto struct { @@ -16,7 +18,8 @@ type ReadListDto struct { } type FilterDto struct { - Encounter_Id *uint `json:"encounter_id"` + Encounter_Id *uint `json:"encounter_id"` + Status_Code erc.DataStatusCode `json:"status_code"` Page int `json:"page"` PageSize int `json:"page_size"` @@ -43,14 +46,16 @@ type MetaDto struct { type ResponseDto struct { ecore.Main - Encounter_Id *uint `json:"encounter_id"` - Encounter *ee.Encounter `json:"encounter,omitempty"` + Encounter_Id *uint `json:"encounter_id"` + Encounter *ee.Encounter `json:"encounter,omitempty"` + Status_Code erc.DataStatusCode `json:"status_code"` } func (d DeviceOrder) ToResponse() ResponseDto { resp := ResponseDto{ Encounter_Id: d.Encounter_Id, Encounter: d.Encounter, + Status_Code: d.Status_Code, } resp.Main = d.Main return resp diff --git a/internal/domain/main-entities/device-order/entity.go b/internal/domain/main-entities/device-order/entity.go index b07067fc..79af88c2 100644 --- a/internal/domain/main-entities/device-order/entity.go +++ b/internal/domain/main-entities/device-order/entity.go @@ -3,10 +3,13 @@ package deviceorder import ( ecore "simrs-vx/internal/domain/base-entities/core" ee "simrs-vx/internal/domain/main-entities/encounter" + + erc "simrs-vx/internal/domain/references/common" ) type DeviceOrder struct { - ecore.Main // adjust this according to the needs - Encounter_Id *uint `json:"encounter_id"` - Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"` + ecore.Main // adjust this according to the needs + Encounter_Id *uint `json:"encounter_id"` + Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"` + Status_Code erc.DataStatusCode `json:"status_code"` } diff --git a/internal/domain/main-entities/material-order/dto.go b/internal/domain/main-entities/material-order/dto.go index 475ef7f8..849f887f 100644 --- a/internal/domain/main-entities/material-order/dto.go +++ b/internal/domain/main-entities/material-order/dto.go @@ -3,10 +3,12 @@ package materialorder import ( ecore "simrs-vx/internal/domain/base-entities/core" ee "simrs-vx/internal/domain/main-entities/encounter" + erc "simrs-vx/internal/domain/references/common" ) type CreateDto struct { - Encounter_Id *uint `json:"encounter_id"` + Encounter_Id *uint `json:"encounter_id"` + Status_Code erc.DataStatusCode `json:"status_code"` } type ReadListDto struct { @@ -16,7 +18,8 @@ type ReadListDto struct { } type FilterDto struct { - Encounter_Id *uint `json:"encounter_id"` + Encounter_Id *uint `json:"encounter_id"` + Status_Code erc.DataStatusCode `json:"status_code"` Page int `json:"page"` PageSize int `json:"page_size"` @@ -43,14 +46,16 @@ type MetaDto struct { type ResponseDto struct { ecore.Main - Encounter_Id *uint `json:"encounter_id"` - Encounter *ee.Encounter `json:"encounter,omitempty"` + Encounter_Id *uint `json:"encounter_id"` + Encounter *ee.Encounter `json:"encounter,omitempty"` + Status_Code erc.DataStatusCode `json:"status_code"` } func (d MaterialOrder) ToResponse() ResponseDto { resp := ResponseDto{ Encounter_Id: d.Encounter_Id, Encounter: d.Encounter, + Status_Code: d.Status_Code, } resp.Main = d.Main return resp diff --git a/internal/domain/main-entities/material-order/entity.go b/internal/domain/main-entities/material-order/entity.go index 566659d3..e306d372 100644 --- a/internal/domain/main-entities/material-order/entity.go +++ b/internal/domain/main-entities/material-order/entity.go @@ -3,10 +3,13 @@ package materialorder import ( ecore "simrs-vx/internal/domain/base-entities/core" ee "simrs-vx/internal/domain/main-entities/encounter" + + erc "simrs-vx/internal/domain/references/common" ) type MaterialOrder struct { - ecore.Main // adjust this according to the needs - Encounter_Id *uint `json:"encounter_id"` - Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"` + ecore.Main // adjust this according to the needs + Encounter_Id *uint `json:"encounter_id"` + Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"` + Status_Code erc.DataStatusCode `json:"status_code"` } diff --git a/internal/domain/main-entities/medication-item-dist/dto.go b/internal/domain/main-entities/medication-item-dist/dto.go index 05278d81..cf44fb50 100644 --- a/internal/domain/main-entities/medication-item-dist/dto.go +++ b/internal/domain/main-entities/medication-item-dist/dto.go @@ -9,7 +9,8 @@ import ( type CreateDto struct { MedicationItem_Id *uint `json:"medicationItem_id"` DateTime *time.Time `json:"dateTime"` - Remain *uint `json:"remain"` + Remain float64 `json:"remain"` + Nurse_Id *uint `json:"nurse_id"` } type ReadListDto struct { @@ -21,7 +22,8 @@ type ReadListDto struct { type FilterDto struct { MedicationItem_Id *uint `json:"medicationItem_id"` DateTime *time.Time `json:"dateTime"` - Remain *uint `json:"remain"` + Remain float64 `json:"remain"` + Nurse_Id *uint `json:"nurse_id"` Page int `json:"page"` PageSize int `json:"page_size"` @@ -51,7 +53,8 @@ type ResponseDto struct { MedicationItem_Id *uint `json:"medicationItem_id"` MedicationItem *emi.MedicationItem `json:"medicationItem,omitempty"` DateTime *time.Time `json:"dateTime"` - Remain *uint `json:"remain"` + Remain float64 `json:"remain"` + Nurse_Id *uint `json:"nurse_id"` } func (d MedicationItemDist) ToResponse() ResponseDto { @@ -60,6 +63,7 @@ func (d MedicationItemDist) ToResponse() ResponseDto { MedicationItem: d.MedicationItem, DateTime: d.DateTime, Remain: d.Remain, + Nurse_Id: d.Nurse_Id, } resp.Main = d.Main return resp diff --git a/internal/domain/main-entities/medication-item-dist/entity.go b/internal/domain/main-entities/medication-item-dist/entity.go index 5bd56912..99e16d48 100644 --- a/internal/domain/main-entities/medication-item-dist/entity.go +++ b/internal/domain/main-entities/medication-item-dist/entity.go @@ -1,9 +1,11 @@ package medicationitem import ( + "time" + ecore "simrs-vx/internal/domain/base-entities/core" emi "simrs-vx/internal/domain/main-entities/medication-item" - "time" + en "simrs-vx/internal/domain/main-entities/nurse" ) type MedicationItemDist struct { @@ -11,5 +13,7 @@ type MedicationItemDist struct { MedicationItem_Id *uint `json:"medicationItem_id"` MedicationItem *emi.MedicationItem `json:"medicationItem,omitempty" gorm:"foreignKey:MedicationItem_Id;references:Id"` DateTime *time.Time `json:"dateTime"` - Remain *uint `json:"remain"` + Remain float64 `json:"remain"` + Nurse_Id *uint `json:"nurse_id"` + Nurse *en.Nurse `json:"nurse,omitempty" gorm:"foreignKey:Nurse_Id;references:Id"` } diff --git a/internal/domain/main-entities/medication-item/dto.go b/internal/domain/main-entities/medication-item/dto.go index 59ae7688..00edb045 100644 --- a/internal/domain/main-entities/medication-item/dto.go +++ b/internal/domain/main-entities/medication-item/dto.go @@ -13,9 +13,10 @@ type CreateDto struct { IsMix bool `json:"isMix"` Medicine_Id *uint `json:"medicine_id"` MedicineMix_Id *uint `json:"medicineMix_id"` - Usage uint8 `json:"usage"` + Usage float64 `json:"usage"` Interval uint8 `json:"interval"` IntervalUnit_Code erc.TimeUnitCode `json:"intervalUnit_code"` + IsRedeemed bool `json:"isRedeemed"` } type ReadListDto struct { @@ -29,9 +30,10 @@ type FilterDto struct { IsMix bool `json:"isMix"` Medicine_Id *uint `json:"medicine_id"` MedicineMix_Id *uint `json:"medicineMix_id"` - Usage uint8 `json:"usage"` + Usage float64 `json:"usage"` Interval uint8 `json:"interval"` IntervalUnit_Code erc.TimeUnitCode `json:"intervalUnit_code"` + IsRedeemed bool `json:"isRedeemed"` Page int `json:"page"` PageSize int `json:"page_size"` @@ -65,9 +67,10 @@ type ResponseDto struct { Medicine *em.Medicine `json:"medicine,omitempty"` MedicineMix_Id *uint `json:"medicineMix_id"` MedicineMix *emm.MedicineMix `json:"medicineMix,omitempty"` - Usage uint8 `json:"usage"` + Usage float64 `json:"usage"` Interval uint8 `json:"interval"` IntervalUnit_Code erc.TimeUnitCode `json:"intervalUnit_code"` + IsRedeemed bool `json:"isRedeemed"` } func (d MedicationItem) ToResponse() ResponseDto { @@ -82,6 +85,7 @@ func (d MedicationItem) ToResponse() ResponseDto { Usage: d.Usage, Interval: d.Interval, IntervalUnit_Code: d.IntervalUnit_Code, + IsRedeemed: d.IsRedeemed, } resp.Main = d.Main return resp diff --git a/internal/domain/main-entities/medication-item/entity.go b/internal/domain/main-entities/medication-item/entity.go index ef7f20ea..671e96b3 100644 --- a/internal/domain/main-entities/medication-item/entity.go +++ b/internal/domain/main-entities/medication-item/entity.go @@ -18,7 +18,8 @@ type MedicationItem struct { Medicine *em.Medicine `json:"medicine,omitempty" gorm:"foreignKey:Medicine_Id;references:Id"` MedicineMix_Id *uint `json:"medicineMix_id"` MedicineMix *emm.MedicineMix `json:"medicineMix,omitempty" gorm:"foreignKey:MedicineMix_Id;references:Id"` - Usage uint8 `json:"usage"` + Usage float64 `json:"usage"` Interval uint8 `json:"interval"` IntervalUnit_Code erc.TimeUnitCode `json:"intervalUnit_code"` + IsRedeemed bool `json:"isRedeemed"` } diff --git a/internal/domain/main-entities/medication/dto.go b/internal/domain/main-entities/medication/dto.go index 1bc1c774..ec158df8 100644 --- a/internal/domain/main-entities/medication/dto.go +++ b/internal/domain/main-entities/medication/dto.go @@ -4,13 +4,15 @@ import ( ecore "simrs-vx/internal/domain/base-entities/core" ee "simrs-vx/internal/domain/main-entities/encounter" ep "simrs-vx/internal/domain/main-entities/pharmacist" + erc "simrs-vx/internal/domain/references/common" "time" ) type CreateDto struct { - Encounter_Id *uint `json:"encounter_id"` - IssuedAt *time.Time `json:"issuedAt"` - Pharmacist_Id *uint `json:"pharmacist_id"` + Encounter_Id *uint `json:"encounter_id"` + IssuedAt *time.Time `json:"issuedAt"` + Pharmacist_Id *uint `json:"pharmacist_id"` + Status_Code erc.DataStatusCode `json:"status_code"` } type ReadListDto struct { @@ -20,9 +22,10 @@ type ReadListDto struct { } type FilterDto struct { - Encounter_Id *uint `json:"encounter_id"` - IssuedAt *time.Time `json:"issuedAt"` - Pharmacist_Id *uint `json:"pharmacist_id"` + Encounter_Id *uint `json:"encounter_id"` + IssuedAt *time.Time `json:"issuedAt"` + Pharmacist_Id *uint `json:"pharmacist_id"` + Status_Code erc.DataStatusCode `json:"status_code"` Page int `json:"page"` PageSize int `json:"page_size"` @@ -49,11 +52,12 @@ type MetaDto struct { type ResponseDto struct { ecore.Main - Encounter_Id *uint `json:"encounter_id"` - Encounter *ee.Encounter `json:"encounter,omitempty"` - IssuedAt *time.Time `json:"issuedAt"` - Pharmacist_Id *uint `json:"pharmacist_id"` - Pharmacist *ep.Pharmacist `json:"pharmacist,omitempty"` + Encounter_Id *uint `json:"encounter_id"` + Encounter *ee.Encounter `json:"encounter,omitempty"` + IssuedAt *time.Time `json:"issuedAt"` + Pharmacist_Id *uint `json:"pharmacist_id"` + Pharmacist *ep.Pharmacist `json:"pharmacist,omitempty"` + Status_Code erc.DataStatusCode `json:"status_code"` } func (d Medication) ToResponse() ResponseDto { @@ -63,6 +67,7 @@ func (d Medication) ToResponse() ResponseDto { IssuedAt: d.IssuedAt, Pharmacist_Id: d.Pharmacist_Id, Pharmacist: d.Pharmacist, + Status_Code: d.Status_Code, } resp.Main = d.Main return resp diff --git a/internal/domain/main-entities/medication/entity.go b/internal/domain/main-entities/medication/entity.go index f18af23c..cc126de7 100644 --- a/internal/domain/main-entities/medication/entity.go +++ b/internal/domain/main-entities/medication/entity.go @@ -6,13 +6,16 @@ import ( ecore "simrs-vx/internal/domain/base-entities/core" ee "simrs-vx/internal/domain/main-entities/encounter" ep "simrs-vx/internal/domain/main-entities/pharmacist" + + erc "simrs-vx/internal/domain/references/common" ) type Medication struct { - ecore.Main // adjust this according to the needs - Encounter_Id *uint `json:"encounter_id"` - Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"` - IssuedAt *time.Time `json:"issuedAt"` - Pharmacist_Id *uint `json:"pharmacist_id"` - Pharmacist *ep.Pharmacist `json:"pharmacist,omitempty" gorm:"foreignKey:Pharmacist_Id;references:Id"` + ecore.Main // adjust this according to the needs + Encounter_Id *uint `json:"encounter_id"` + Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"` + IssuedAt *time.Time `json:"issuedAt"` + Pharmacist_Id *uint `json:"pharmacist_id"` + Pharmacist *ep.Pharmacist `json:"pharmacist,omitempty" gorm:"foreignKey:Pharmacist_Id;references:Id"` + Status_Code erc.DataStatusCode `json:"status_code"` } diff --git a/internal/domain/main-entities/prescription-item/dto.go b/internal/domain/main-entities/prescription-item/dto.go index a87daaae..f23a6610 100644 --- a/internal/domain/main-entities/prescription-item/dto.go +++ b/internal/domain/main-entities/prescription-item/dto.go @@ -13,7 +13,7 @@ type CreateDto struct { IsMix bool `json:"isMix"` Medicine_Id *uint `json:"medicine_id"` MedicineMix_Id *uint `json:"medicineMix_id"` - Usage uint8 `json:"usage"` + Usage float64 `json:"usage"` Interval uint8 `json:"interval"` IntervalUnit_Code erc.TimeUnitCode `json:"intervalUnit_code"` } @@ -29,7 +29,7 @@ type FilterDto struct { IsMix bool `json:"isMix"` Medicine_Id *uint `json:"medicine_id"` MedicineMix_Id *uint `json:"medicineMix_id"` - Usage uint8 `json:"usage"` + Usage float64 `json:"usage"` Interval uint8 `json:"interval"` IntervalUnit_Code erc.TimeUnitCode `json:"intervalUnit_code"` @@ -65,7 +65,7 @@ type ResponseDto struct { Medicine *em.Medicine `json:"medicine,omitempty"` MedicineMix_Id *uint `json:"medicineMix_id"` MedicineMix *emm.MedicineMix `json:"medicineMix,omitempty"` - Usage uint8 `json:"usage"` + Usage float64 `json:"usage"` Interval uint8 `json:"interval"` IntervalUnit_Code erc.TimeUnitCode `json:"intervalUnit_code"` } diff --git a/internal/domain/main-entities/prescription-item/entity.go b/internal/domain/main-entities/prescription-item/entity.go index 3c662c5c..89537496 100644 --- a/internal/domain/main-entities/prescription-item/entity.go +++ b/internal/domain/main-entities/prescription-item/entity.go @@ -18,7 +18,7 @@ type PrescriptionItem struct { Medicine *em.Medicine `json:"medicine,omitempty" gorm:"foreignKey:Medicine_Id;references:Id"` MedicineMix_Id *uint `json:"medicineMix_id"` MedicineMix *emm.MedicineMix `json:"medicineMix,omitempty" gorm:"foreignKey:MedicineMix_Id;references:Id"` - Usage uint8 `json:"usage"` + Usage float64 `json:"usage"` Interval uint8 `json:"interval"` IntervalUnit_Code erc.TimeUnitCode `json:"intervalUnit_code"` } From cb5b743beea975fe01707458d0ff99f62a66d3af Mon Sep 17 00:00:00 2001 From: dpurbosakti Date: Tue, 16 Sep 2025 17:59:33 +0700 Subject: [PATCH 6/6] wip --- .../main-entities/device-order/entity.go | 4 + .../main-entities/material-order/entity.go | 4 + .../main-entities/medication-item-dist/dto.go | 10 +++ .../domain/main-entities/medication/dto.go | 5 ++ .../domain/main-entities/medication/entity.go | 4 + .../main-handler/device-order/handler.go | 12 +++ .../interface/main-handler/main-handler.go | 49 ++++++++++-- .../main-handler/material-order/handler.go | 12 +++ .../medication-item-dist/handler.go | 25 ++++++- .../main-handler/medication-item/handler.go | 12 +++ .../main-handler/medication/handler.go | 25 ++++++- .../main-use-case/device-order-item/helper.go | 1 + .../main-use-case/device-order/case.go | 60 +++++++++++++++ .../main-use-case/device-order/helper.go | 1 + .../main-use-case/material-order/case.go | 62 ++++++++++++++++ .../main-use-case/material-order/helper.go | 1 + .../medication-item-dist/case.go | 74 +++++++++++++++++++ .../medication-item-dist/helper.go | 1 + .../main-use-case/medication-item/case.go | 52 +++++++++++++ .../main-use-case/medication-item/helper.go | 2 + .../use-case/main-use-case/medication/case.go | 72 ++++++++++++++++++ .../main-use-case/medication/helper.go | 35 +++++++++ internal/use-case/main-use-case/nurse/lib.go | 31 ++++++++ .../use-case/main-use-case/pharmacist/lib.go | 31 ++++++++ .../main-use-case/prescription-item/helper.go | 1 + 25 files changed, 579 insertions(+), 7 deletions(-) diff --git a/internal/domain/main-entities/device-order/entity.go b/internal/domain/main-entities/device-order/entity.go index 79af88c2..3b37669f 100644 --- a/internal/domain/main-entities/device-order/entity.go +++ b/internal/domain/main-entities/device-order/entity.go @@ -13,3 +13,7 @@ type DeviceOrder struct { Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"` Status_Code erc.DataStatusCode `json:"status_code"` } + +func (d DeviceOrder) IsCompleted() bool { + return d.Status_Code == erc.DSCDone +} diff --git a/internal/domain/main-entities/material-order/entity.go b/internal/domain/main-entities/material-order/entity.go index e306d372..b8a3b238 100644 --- a/internal/domain/main-entities/material-order/entity.go +++ b/internal/domain/main-entities/material-order/entity.go @@ -13,3 +13,7 @@ type MaterialOrder struct { Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"` Status_Code erc.DataStatusCode `json:"status_code"` } + +func (d MaterialOrder) IsCompleted() bool { + return d.Status_Code == erc.DSCDone +} diff --git a/internal/domain/main-entities/medication-item-dist/dto.go b/internal/domain/main-entities/medication-item-dist/dto.go index cf44fb50..8d5c43e1 100644 --- a/internal/domain/main-entities/medication-item-dist/dto.go +++ b/internal/domain/main-entities/medication-item-dist/dto.go @@ -3,6 +3,9 @@ package medicationitem import ( ecore "simrs-vx/internal/domain/base-entities/core" emi "simrs-vx/internal/domain/main-entities/medication-item" + + pa "simrs-vx/pkg/auth-helper" + "time" ) @@ -42,6 +45,13 @@ type DeleteDto struct { Id uint16 `json:"id"` } +type ConsumeDto struct { + Id uint16 `json:"id"` + Usage float64 `json:"usage"` + + pa.AuthInfo +} + type MetaDto struct { PageNumber int `json:"page_number"` PageSize int `json:"page_size"` diff --git a/internal/domain/main-entities/medication/dto.go b/internal/domain/main-entities/medication/dto.go index ec158df8..7242b9d5 100644 --- a/internal/domain/main-entities/medication/dto.go +++ b/internal/domain/main-entities/medication/dto.go @@ -5,7 +5,10 @@ import ( ee "simrs-vx/internal/domain/main-entities/encounter" ep "simrs-vx/internal/domain/main-entities/pharmacist" erc "simrs-vx/internal/domain/references/common" + "time" + + pa "simrs-vx/pkg/auth-helper" ) type CreateDto struct { @@ -33,6 +36,8 @@ type FilterDto struct { } type ReadDetailDto struct { Id uint16 `json:"id"` + + pa.AuthInfo } type UpdateDto struct { diff --git a/internal/domain/main-entities/medication/entity.go b/internal/domain/main-entities/medication/entity.go index cc126de7..0a59c27b 100644 --- a/internal/domain/main-entities/medication/entity.go +++ b/internal/domain/main-entities/medication/entity.go @@ -19,3 +19,7 @@ type Medication struct { Pharmacist *ep.Pharmacist `json:"pharmacist,omitempty" gorm:"foreignKey:Pharmacist_Id;references:Id"` Status_Code erc.DataStatusCode `json:"status_code"` } + +func (d Medication) IsCompleted() bool { + return d.Status_Code == erc.DSCDone +} diff --git a/internal/interface/main-handler/device-order/handler.go b/internal/interface/main-handler/device-order/handler.go index d9b55d6a..ca11ff90 100644 --- a/internal/interface/main-handler/device-order/handler.go +++ b/internal/interface/main-handler/device-order/handler.go @@ -69,3 +69,15 @@ func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) { res, err := u.Delete(dto) rw.DataResponse(w, res, err) } + +func (obj myBase) Complete(w http.ResponseWriter, r *http.Request) { + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id <= 0 { + return + } + + dto := e.ReadDetailDto{} + dto.Id = uint16(id) + res, err := u.Complete(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 db155f73..cc14eaf1 100644 --- a/internal/interface/main-handler/main-handler.go +++ b/internal/interface/main-handler/main-handler.go @@ -138,6 +138,50 @@ func SetRoutes() http.Handler { "DELETE /{id}": encounter.O.Delete, "PATCH /{id}/checkout": encounter.O.CheckOut, }) + hk.GroupRoutes("/v1/medication", r, auth.GuardMW, hk.MapHandlerFunc{ + "GET /": medication.O.GetList, + "GET /{id}": medication.O.GetDetail, + "POST /": medication.O.Create, + "PATCH /{id}": medication.O.Update, + "DELETE /{id}": medication.O.Delete, + "PATCH /{id}/complete": medication.O.Complete, + }) + + hk.GroupRoutes("/v1/medication-item", r, hk.MapHandlerFunc{ + "GET /": medicationitem.O.GetList, + "GET /{id}": medicationitem.O.GetDetail, + "POST /": medicationitem.O.Create, + "PATCH /{id}": medicationitem.O.Update, + "DELETE /{id}": medicationitem.O.Delete, + "PATCH /{id}/redeem": medicationitem.O.Redeem, + }) + + hk.GroupRoutes("/v1/medication-item-dist", r, auth.GuardMW, hk.MapHandlerFunc{ + "GET /": medicationitemdist.O.GetList, + "GET /{id}": medicationitemdist.O.GetDetail, + "POST /": medicationitemdist.O.Create, + "PATCH /{id}": medicationitemdist.O.Update, + "DELETE /{id}": medicationitemdist.O.Delete, + "PATCH /{id}/consume": medicationitemdist.O.Consume, + }) + + hk.GroupRoutes("/v1/device-order", r, hk.MapHandlerFunc{ + "GET /": deviceorder.O.GetList, + "GET /{id}": deviceorder.O.GetDetail, + "POST /": deviceorder.O.Create, + "PATCH /{id}": deviceorder.O.Update, + "DELETE /{id}": deviceorder.O.Delete, + "PATCH /{id}/complete": deviceorder.O.Complete, + }) + + hk.GroupRoutes("/v1/material-order", r, hk.MapHandlerFunc{ + "GET /": materialorder.O.GetList, + "GET /{id}": materialorder.O.GetDetail, + "POST /": materialorder.O.Create, + "PATCH /{id}": materialorder.O.Update, + "DELETE /{id}": materialorder.O.Delete, + "PATCH /{id}/complete": materialorder.O.Complete, + }) hc.RegCrud(r, "/v1/soapi", auth.GuardMW, soapi.O) hc.RegCrud(r, "/v1/adime", auth.GuardMW, adime.O) @@ -152,12 +196,7 @@ func SetRoutes() http.Handler { 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/medication", medication.O) - hc.RegCrud(r, "/v1/medication-item", medicationitem.O) - hc.RegCrud(r, "/v1/medication-item-dist", medicationitemdist.O) - hc.RegCrud(r, "/v1/device-order", deviceorder.O) hc.RegCrud(r, "/v1/device-order-item", deviceorderitem.O) - hc.RegCrud(r, "/v1/material-order", materialorder.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) diff --git a/internal/interface/main-handler/material-order/handler.go b/internal/interface/main-handler/material-order/handler.go index cfea48f7..eb717973 100644 --- a/internal/interface/main-handler/material-order/handler.go +++ b/internal/interface/main-handler/material-order/handler.go @@ -69,3 +69,15 @@ func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) { res, err := u.Delete(dto) rw.DataResponse(w, res, err) } + +func (obj myBase) Complete(w http.ResponseWriter, r *http.Request) { + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id <= 0 { + return + } + + dto := e.ReadDetailDto{} + dto.Id = uint16(id) + res, err := u.Complete(dto) + rw.DataResponse(w, res, err) +} diff --git a/internal/interface/main-handler/medication-item-dist/handler.go b/internal/interface/main-handler/medication-item-dist/handler.go index 956a98ae..6c4b659f 100644 --- a/internal/interface/main-handler/medication-item-dist/handler.go +++ b/internal/interface/main-handler/medication-item-dist/handler.go @@ -6,10 +6,12 @@ import ( rw "github.com/karincake/risoles" sf "github.com/karincake/semprit" - // ua "github.com/karincake/tumpeng/auth/svc" + pa "simrs-vx/pkg/auth-helper" e "simrs-vx/internal/domain/main-entities/medication-item-dist" u "simrs-vx/internal/use-case/main-use-case/medication-item-dist" + + d "github.com/karincake/dodol" ) type myBase struct{} @@ -69,3 +71,24 @@ func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) { res, err := u.Delete(dto) rw.DataResponse(w, res, err) } + +func (obj myBase) Consume(w http.ResponseWriter, r *http.Request) { + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id <= 0 { + return + } + + authInfo, err := pa.GetAuthInfo(r) + if err != nil { + rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil) + } + + dto := e.ConsumeDto{} + if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { + return + } + dto.AuthInfo = *authInfo + dto.Id = uint16(id) + res, err := u.Consume(dto) + rw.DataResponse(w, res, err) +} diff --git a/internal/interface/main-handler/medication-item/handler.go b/internal/interface/main-handler/medication-item/handler.go index b5a5e6ae..bccb9f4f 100644 --- a/internal/interface/main-handler/medication-item/handler.go +++ b/internal/interface/main-handler/medication-item/handler.go @@ -69,3 +69,15 @@ func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) { res, err := u.Delete(dto) rw.DataResponse(w, res, err) } + +func (obj myBase) Redeem(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.Redeem(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 269c2e6f..b847eb5b 100644 --- a/internal/interface/main-handler/medication/handler.go +++ b/internal/interface/main-handler/medication/handler.go @@ -6,10 +6,12 @@ import ( rw "github.com/karincake/risoles" sf "github.com/karincake/semprit" - // ua "github.com/karincake/tumpeng/auth/svc" + pa "simrs-vx/pkg/auth-helper" e "simrs-vx/internal/domain/main-entities/medication" u "simrs-vx/internal/use-case/main-use-case/medication" + + d "github.com/karincake/dodol" ) type myBase struct{} @@ -69,3 +71,24 @@ func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) { res, err := u.Delete(dto) rw.DataResponse(w, res, err) } + +func (obj myBase) Complete(w http.ResponseWriter, r *http.Request) { + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id <= 0 { + return + } + + authInfo, err := pa.GetAuthInfo(r) + if err != nil { + rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil) + } + + dto := e.ReadDetailDto{} + if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { + return + } + dto.AuthInfo = *authInfo + dto.Id = uint16(id) + res, err := u.Complete(dto) + rw.DataResponse(w, res, err) +} diff --git a/internal/use-case/main-use-case/device-order-item/helper.go b/internal/use-case/main-use-case/device-order-item/helper.go index d618afae..5c6a0e68 100644 --- a/internal/use-case/main-use-case/device-order-item/helper.go +++ b/internal/use-case/main-use-case/device-order-item/helper.go @@ -19,4 +19,5 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.DeviceOrderItem) { data.DeviceOrder_Id = inputSrc.DeviceOrder_Id data.Device_Id = inputSrc.Device_Id + data.Count = inputSrc.Count } 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 c4f1ebe5..96c510c0 100644 --- a/internal/use-case/main-use-case/device-order/case.go +++ b/internal/use-case/main-use-case/device-order/case.go @@ -1,10 +1,13 @@ package deviceorder import ( + "errors" "strconv" e "simrs-vx/internal/domain/main-entities/device-order" + erc "simrs-vx/internal/domain/references/common" + dg "github.com/karincake/apem/db-gorm-pg" d "github.com/karincake/dodol" @@ -187,6 +190,9 @@ func Update(input e.UpdateDto) (*d.Data, error) { return err } + if data.IsCompleted() { + return errors.New("data already completed") + } mwRunner := newMiddlewareRunner(&event, tx) mwRunner.setMwType(pu.MWTPre) // Run pre-middleware @@ -243,6 +249,9 @@ func Delete(input e.DeleteDto) (*d.Data, error) { return err } + if data.IsCompleted() { + return errors.New("data already completed") + } mwRunner := newMiddlewareRunner(&event, tx) mwRunner.setMwType(pu.MWTPre) // Run pre-middleware @@ -277,3 +286,54 @@ func Delete(input e.DeleteDto) (*d.Data, error) { }, nil } + +func Complete(input e.ReadDetailDto) (*d.Data, error) { + var data *e.DeviceOrder + 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 +} diff --git a/internal/use-case/main-use-case/device-order/helper.go b/internal/use-case/main-use-case/device-order/helper.go index 975ef50b..84a49fa2 100644 --- a/internal/use-case/main-use-case/device-order/helper.go +++ b/internal/use-case/main-use-case/device-order/helper.go @@ -18,4 +18,5 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.DeviceOrder) { } data.Encounter_Id = inputSrc.Encounter_Id + data.Status_Code = inputSrc.Status_Code } 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 f566015f..28f41704 100644 --- a/internal/use-case/main-use-case/material-order/case.go +++ b/internal/use-case/main-use-case/material-order/case.go @@ -1,10 +1,13 @@ package materialorder import ( + "errors" "strconv" e "simrs-vx/internal/domain/main-entities/material-order" + erc "simrs-vx/internal/domain/references/common" + dg "github.com/karincake/apem/db-gorm-pg" d "github.com/karincake/dodol" @@ -187,6 +190,10 @@ func Update(input e.UpdateDto) (*d.Data, error) { return err } + if data.IsCompleted() { + return errors.New("data already completed") + } + mwRunner := newMiddlewareRunner(&event, tx) mwRunner.setMwType(pu.MWTPre) // Run pre-middleware @@ -243,6 +250,10 @@ func Delete(input e.DeleteDto) (*d.Data, error) { return err } + if data.IsCompleted() { + return errors.New("data already completed") + } + mwRunner := newMiddlewareRunner(&event, tx) mwRunner.setMwType(pu.MWTPre) // Run pre-middleware @@ -277,3 +288,54 @@ func Delete(input e.DeleteDto) (*d.Data, error) { }, nil } + +func Complete(input e.ReadDetailDto) (*d.Data, error) { + var data *e.MaterialOrder + 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 +} diff --git a/internal/use-case/main-use-case/material-order/helper.go b/internal/use-case/main-use-case/material-order/helper.go index 565d2487..f5f67b1a 100644 --- a/internal/use-case/main-use-case/material-order/helper.go +++ b/internal/use-case/main-use-case/material-order/helper.go @@ -18,4 +18,5 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.MaterialOrder) { } data.Encounter_Id = inputSrc.Encounter_Id + data.Status_Code = inputSrc.Status_Code } diff --git a/internal/use-case/main-use-case/medication-item-dist/case.go b/internal/use-case/main-use-case/medication-item-dist/case.go index c2b87993..3c79b6a7 100644 --- a/internal/use-case/main-use-case/medication-item-dist/case.go +++ b/internal/use-case/main-use-case/medication-item-dist/case.go @@ -1,10 +1,13 @@ package medicationitemdist import ( + "errors" "strconv" e "simrs-vx/internal/domain/main-entities/medication-item-dist" + un "simrs-vx/internal/use-case/main-use-case/nurse" + dg "github.com/karincake/apem/db-gorm-pg" d "github.com/karincake/dodol" @@ -277,3 +280,74 @@ func Delete(input e.DeleteDto) (*d.Data, error) { }, nil } + +func Consume(input e.ConsumeDto) (*d.Data, error) { + rdDto := e.ReadDetailDto{Id: input.Id} + var data *e.MedicationItemDist + var err error + + event := pl.Event{ + Feature: "Consume", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "consume") + + err = dg.I.Transaction(func(tx *gorm.DB) error { + if !input.AuthInfo.IsNurse() { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "auth-forbidden", + Detail: "user position is not allowed", + Raw: errors.New("authentication failed"), + } + return pl.SetLogError(&event, input) + } + + nurse_id, err := un.GetIdByUserId(&input.AuthInfo.User_Id, &event, tx) + if err != nil { + return err + } + + if data, err = ReadDetailData(rdDto, &event, tx); err != nil { + return err + } + + if data.Remain <= 0 { + return errors.New("data already consumed") + } else if data.Remain < input.Usage { + return errors.New("data remain less than usage") + } + + data.Remain -= input.Usage + data.Nurse_Id = nurse_id + + 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": "updated", + }, + Data: data.ToResponse(), + }, nil +} diff --git a/internal/use-case/main-use-case/medication-item-dist/helper.go b/internal/use-case/main-use-case/medication-item-dist/helper.go index eadc8958..5b1b1d35 100644 --- a/internal/use-case/main-use-case/medication-item-dist/helper.go +++ b/internal/use-case/main-use-case/medication-item-dist/helper.go @@ -20,4 +20,5 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.MedicationItemDist) data.MedicationItem_Id = inputSrc.MedicationItem_Id data.DateTime = inputSrc.DateTime data.Remain = inputSrc.Remain + data.Nurse_Id = inputSrc.Nurse_Id } diff --git a/internal/use-case/main-use-case/medication-item/case.go b/internal/use-case/main-use-case/medication-item/case.go index 1573a5a7..b5c3a015 100644 --- a/internal/use-case/main-use-case/medication-item/case.go +++ b/internal/use-case/main-use-case/medication-item/case.go @@ -1,6 +1,7 @@ package medicationitem import ( + "errors" "strconv" e "simrs-vx/internal/domain/main-entities/medication-item" @@ -277,3 +278,54 @@ func Delete(input e.DeleteDto) (*d.Data, error) { }, nil } + +func Redeem(input e.ReadDetailDto) (*d.Data, error) { + var data *e.MedicationItem + var err error + + event := pl.Event{ + Feature: "Redeem", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "redeem") + + err = dg.I.Transaction(func(tx *gorm.DB) error { + data, err = ReadDetailData(input, &event, tx) + if err != nil { + return err + } + + if data.IsRedeemed { + return errors.New("data already redeemed") + } + + data.IsRedeemed = true + 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/medication-item/helper.go b/internal/use-case/main-use-case/medication-item/helper.go index 67b8a204..c3c07b36 100644 --- a/internal/use-case/main-use-case/medication-item/helper.go +++ b/internal/use-case/main-use-case/medication-item/helper.go @@ -23,4 +23,6 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.MedicationItem) { data.MedicineMix_Id = inputSrc.MedicineMix_Id data.Usage = inputSrc.Usage data.Interval = inputSrc.Interval + data.IntervalUnit_Code = inputSrc.IntervalUnit_Code + data.IsRedeemed = inputSrc.IsRedeemed } diff --git a/internal/use-case/main-use-case/medication/case.go b/internal/use-case/main-use-case/medication/case.go index df23a586..ec096f29 100644 --- a/internal/use-case/main-use-case/medication/case.go +++ b/internal/use-case/main-use-case/medication/case.go @@ -1,10 +1,15 @@ package medication import ( + "errors" "strconv" e "simrs-vx/internal/domain/main-entities/medication" + erc "simrs-vx/internal/domain/references/common" + + up "simrs-vx/internal/use-case/main-use-case/pharmacist" + dg "github.com/karincake/apem/db-gorm-pg" d "github.com/karincake/dodol" @@ -277,3 +282,70 @@ func Delete(input e.DeleteDto) (*d.Data, error) { }, nil } + +func Complete(input e.ReadDetailDto) (*d.Data, error) { + var data *e.Medication + 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") + } + + if !input.AuthInfo.IsPharmacist() { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "auth-forbidden", + Detail: "user position is not allowed", + Raw: errors.New("authentication failed"), + } + return pl.SetLogError(&event, input) + } + + pharmacist_id, err := up.GetIdByUserId(&input.AuthInfo.User_Id, &event, tx) + if err != nil { + return err + } + + data.Status_Code = erc.DSCDone + data.Pharmacist_Id = pharmacist_id + 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/medication/helper.go b/internal/use-case/main-use-case/medication/helper.go index f2d545ac..52676431 100644 --- a/internal/use-case/main-use-case/medication/helper.go +++ b/internal/use-case/main-use-case/medication/helper.go @@ -6,6 +6,10 @@ 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" ) func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Medication) { @@ -20,4 +24,35 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Medication) { data.Encounter_Id = inputSrc.Encounter_Id data.IssuedAt = inputSrc.IssuedAt data.Pharmacist_Id = inputSrc.Pharmacist_Id + 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 +// } + +// 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 +// } +// } + +// pl.SetLogInfo(event, nil, "complete") +// return nil +// } diff --git a/internal/use-case/main-use-case/nurse/lib.go b/internal/use-case/main-use-case/nurse/lib.go index d3c48f60..468b41c2 100644 --- a/internal/use-case/main-use-case/nurse/lib.go +++ b/internal/use-case/main-use-case/nurse/lib.go @@ -159,3 +159,34 @@ func DeleteData(data *e.Nurse, event *pl.Event, dbx ...*gorm.DB) error { pl.SetLogInfo(event, nil, "complete") return nil } + +func GetIdByUserId(user_id *uint, event *pl.Event, dbx ...*gorm.DB) (*uint, error) { + pl.SetLogInfo(event, nil, "started", "DBGetIdByUserId") + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + 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). + Scan(&nurse_id).Error + + if err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-get-fail", + Detail: "Database get failed", + Raw: err, + } + return nil, pl.SetLogError(event, user_id) + } + + pl.SetLogInfo(event, nil, "complete") + return &nurse_id, nil +} diff --git a/internal/use-case/main-use-case/pharmacist/lib.go b/internal/use-case/main-use-case/pharmacist/lib.go index 5559be6c..e9478d70 100644 --- a/internal/use-case/main-use-case/pharmacist/lib.go +++ b/internal/use-case/main-use-case/pharmacist/lib.go @@ -159,3 +159,34 @@ func DeleteData(data *e.Pharmacist, event *pl.Event, dbx ...*gorm.DB) error { pl.SetLogInfo(event, nil, "complete") return nil } + +func GetIdByUserId(user_id *uint, event *pl.Event, dbx ...*gorm.DB) (*uint, error) { + pl.SetLogInfo(event, nil, "started", "DBGetIdByUserId") + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + 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). + Scan(&pharmacist_id).Error + + if err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-get-fail", + Detail: "Database get failed", + Raw: err, + } + return nil, pl.SetLogError(event, user_id) + } + + pl.SetLogInfo(event, nil, "complete") + return &pharmacist_id, 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 e63ca8c7..000522d5 100644 --- a/internal/use-case/main-use-case/prescription-item/helper.go +++ b/internal/use-case/main-use-case/prescription-item/helper.go @@ -23,4 +23,5 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.PrescriptionItem) { data.MedicineMix_Id = inputSrc.MedicineMix_Id data.Usage = inputSrc.Usage data.Interval = inputSrc.Interval + data.IntervalUnit_Code = inputSrc.IntervalUnit_Code }