/* 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 }