Files
simrsx-be/internal/use-case/main-use-case/encounter/helper.go
T
2025-09-17 16:35:07 +07:00

208 lines
6.1 KiB
Go

/*
DESCRIPTION:
Any functions that are used internally by the use-case
*/
package encounter
import (
"errors"
e "simrs-vx/internal/domain/main-entities/encounter"
es "simrs-vx/internal/domain/main-entities/soapi"
em "simrs-vx/internal/domain/main-entities/medication"
emei "simrs-vx/internal/domain/main-entities/medication-item"
emi "simrs-vx/internal/domain/main-entities/medicine-mix"
emmi "simrs-vx/internal/domain/main-entities/medicine-mix-item"
ep "simrs-vx/internal/domain/main-entities/prescription"
epi "simrs-vx/internal/domain/main-entities/prescription-item"
um "simrs-vx/internal/use-case/main-use-case/medication"
umei "simrs-vx/internal/use-case/main-use-case/medication-item"
umi "simrs-vx/internal/use-case/main-use-case/medicine-mix"
ummi "simrs-vx/internal/use-case/main-use-case/medicine-mix-item"
up "simrs-vx/internal/use-case/main-use-case/prescription"
upi "simrs-vx/internal/use-case/main-use-case/prescription-item"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
erc "simrs-vx/internal/domain/references/common"
ero "simrs-vx/internal/domain/references/organization"
"gorm.io/gorm"
)
func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Encounter) {
var inputSrc *e.CreateDto
if inputT, ok := any(input).(*e.CreateDto); ok {
inputSrc = inputT
} else {
inputTemp := any(input).(*e.UpdateDto)
inputSrc = &inputTemp.CreateDto
}
data.Patient_Id = inputSrc.Patient_Id
data.RegisteredAt = inputSrc.RegisteredAt
data.Class_Code = inputSrc.Class_Code
data.Unit_Id = inputSrc.Unit_Id
data.Specialist_Id = inputSrc.Specialist_Id
data.Subspecialist_Id = inputSrc.Subspecialist_Id
data.VisitDate = inputSrc.VisitDate
data.Appointment_Doctor_Id = inputSrc.Appointment_Doctor_Id
data.Responsible_Doctor_Id = inputSrc.Responsible_Doctor_Id
data.RefSource_Name = inputSrc.RefSource_Name
data.Appointment_Id = inputSrc.Appointment_Id
data.Status_Code = erc.DSCNew
}
func setDataUpdate(src e.UpdateDto, dst *e.Encounter) {
dst.Appointment_Doctor_Id = src.Appointment_Doctor_Id
dst.Responsible_Doctor_Id = src.Responsible_Doctor_Id
dst.Unit_Id = src.Unit_Id
dst.Specialist_Id = src.Specialist_Id
dst.Subspecialist_Id = src.Subspecialist_Id
dst.VisitDate = src.VisitDate
}
func setDataDischarge(src e.DischargeDto, dst *e.Encounter) {
dst.DischargeMethod_Code = src.DischargeMethod_Code
dst.EarlyEducation = src.EarlyEducation
dst.MedicalDischargeEducation = src.MedicalDischargeEducation
dst.AdmDischargeEducation = src.AdmDischargeEducation
dst.DischargeReason = src.DischargeReason
dst.Status_Code = erc.DSCDone
}
func checkSoapiByDocExists(encounter_id uint, event *pl.Event, tx *gorm.DB) error {
pl.SetLogInfo(event, nil, "started", "checkSoapiByDocExists")
var soapies []es.Soapi
err := tx.
Preload("Employee").
Preload("Employee.User").
Where("\"Encounter_Id\" = ?", encounter_id).Find(&soapies).Error
if err != nil {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-get-fail",
Detail: "get soapi failed",
Raw: err,
}
return pl.SetLogError(event, nil)
}
if len(soapies) == 0 {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-notFound",
Detail: "no soapi found for encounter",
Raw: errors.New("soapi not found"),
}
return pl.SetLogError(event, nil)
}
for _, s := range soapies {
if s.Employee != nil && s.Employee.User != nil && s.Employee.User.Position_Code == ero.UPCDoc {
return nil
}
}
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-update-fail",
Detail: "no soapi written by a doctor found",
Raw: errors.New("all soapi employees are not doctors"),
}
return pl.SetLogError(event, nil)
}
func createMedication(encounter_id uint, event *pl.Event, tx *gorm.DB) error {
pl.SetLogInfo(event, nil, "started", "createMedication")
prescription, err := up.ReadDetailData(ep.ReadDetailDto{Encounter_Id: &encounter_id}, event, tx)
if err != nil {
return err
}
prescriptionItem, _, err := upi.ReadListData(epi.ReadListDto{FilterDto: epi.FilterDto{Prescription_Id: &prescription.Id}}, event, tx)
if err != nil {
return err
}
if len(prescriptionItem) == 0 {
return nil
}
medicationCreate := em.CreateDto{
Encounter_Id: &encounter_id,
IssuedAt: pu.GetTimeNow(),
}
medication, err := um.CreateData(medicationCreate, event, tx)
if err != nil {
return err
}
for _, prescriptionItem := range prescriptionItem {
if prescriptionItem.IsMix {
medMix_id, err := createMedicineMixAndItem(*prescriptionItem.MedicineMix, event, tx)
if err != nil {
return err
}
prescriptionItem.MedicineMix_Id = medMix_id
}
err := createMedicationItem(medication.Id, prescriptionItem, event, tx)
if err != nil {
return err
}
}
return nil
}
func createMedicineMixAndItem(input emi.MedicineMix, event *pl.Event, tx *gorm.DB) (*uint, error) {
pl.SetLogInfo(event, nil, "started", "createMedicineMix")
medicineMixCreate := emi.CreateDto{
Name: input.Name,
}
medicineMix, err := umi.CreateData(medicineMixCreate, event, tx)
if err != nil {
return nil, err
}
// recreate medicineMixItem with new medicineMix_id to keep medMixItem remain the same for prescriptionItem that is created
for _, medicineMixItem := range input.MixItems {
medicineMixItemCreate := emmi.CreateDto{
MedicineMix_Id: &medicineMix.Id,
Medicine_Id: medicineMixItem.Medicine_Id,
Dose: medicineMixItem.Dose,
}
_, err := ummi.CreateData(medicineMixItemCreate, event, tx)
if err != nil {
return nil, err
}
}
return &medicineMix.Id, nil
}
func createMedicationItem(medication_id uint, input epi.PrescriptionItem, event *pl.Event, tx *gorm.DB) error {
pl.SetLogInfo(event, nil, "started", "createMedicationItem")
medicationItemCreate := emei.CreateDto{
Medication_Id: &medication_id,
IsMix: input.IsMix,
Medicine_Id: input.Medicine_Id,
MedicineMix_Id: input.MedicineMix_Id,
Usage: input.Usage,
Interval: input.Interval,
IntervalUnit_Code: input.IntervalUnit_Code,
Quantity: input.Quantity,
}
_, err := umei.CreateData(medicationItemCreate, event, tx)
if err != nil {
return err
}
return nil
}