on going chemo plan

This commit is contained in:
vanilia
2025-12-09 15:07:01 +07:00
parent 69cfda6f63
commit be34c66ffd
4 changed files with 172 additions and 43 deletions
@@ -1,17 +1,17 @@
package chemo_plan
import (
erc "simrs-vx/internal/domain/references/common"
ere "simrs-vx/internal/domain/references/encounter"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
"strconv"
dg "github.com/karincake/apem/db-gorm-pg"
d "github.com/karincake/dodol"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
"gorm.io/gorm"
erc "simrs-vx/internal/domain/references/common"
e "simrs-vx/internal/domain/main-entities/chemo-plan"
ep "simrs-vx/internal/domain/main-entities/chemo-protocol"
)
@@ -266,12 +266,33 @@ func Fail(input e.FailDto) (*d.Data, error) {
// 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
}
if data, err = ReadDetailData(rdDto, &event); err != nil {
return nil, err
}
dataSoapi, err := getSoapiByEncounterId(*data.Encounter_Id, &event)
if err != nil {
return nil, err
}
if dataSoapi != nil && len(*dataSoapi) > 0 {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "soapi-exist",
Detail: "cancel soapi to proceed",
}
return nil, pl.SetLogError(&event, data)
}
if data.Status != ere.SPCPlanned {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "invalid-chemo-status",
Detail: "only chemo plans with status 'planned' can be deleted.",
}
}
err = dg.I.Transaction(func(tx *gorm.DB) error {
if err := UpdateData(data, &event, tx); err != nil {
return err
}
@@ -6,12 +6,21 @@ package chemo_plan
import (
"encoding/json"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
"time"
dg "github.com/karincake/apem/db-gorm-pg"
ere "simrs-vx/internal/domain/references/encounter"
e "simrs-vx/internal/domain/main-entities/chemo-plan"
ep "simrs-vx/internal/domain/main-entities/chemo-protocol"
ere "simrs-vx/internal/domain/references/encounter"
"time"
es "simrs-vx/internal/domain/main-entities/soapi"
)
var now = time.Now()
func setDataCreate(input *ep.CreateDto) (data []e.ChemoPlan) {
for _, c := range *input.ChemoPlans {
data = append(data, e.ChemoPlan{
@@ -22,14 +31,10 @@ func setDataCreate(input *ep.CreateDto) (data []e.ChemoPlan) {
PlanDate: c.PlanDate,
})
}
status := ere.SPCPlanned
data[0].Status = status
return
}
func setDataUpdate(data *e.ChemoPlan) {
now := time.Now()
data.RealizationDate = &now
status := ere.SPCComplete
@@ -42,5 +47,36 @@ func setDatafail(input e.FailDto, data *e.ChemoPlan) {
var reasons []e.FailReason
_ := json.Unmarshal(data.Re)
if data.Reasons != nil {
json.Unmarshal([]byte(*data.Reasons), &reasons)
}
reasons = append(reasons, e.FailReason{
FailReason: input.Reasons,
Date: &now,
})
if b, err := json.Marshal(reasons); err == nil {
jsonStr := string(b)
data.Reasons = &jsonStr
}
}
func getSoapiByEncounterId(encounterId uint, event *pl.Event) (*[]es.Soapi, error) {
pl.SetLogInfo(event, encounterId, "started", "DBReadDetail")
var data []es.Soapi
var tx = dg.I
if err := tx.
Model(&es.Soapi{}).
Where(`"Encounter_Id" = ?`, encounterId).
Find(&data).Error; err != nil {
if processedErr := pu.HandleReadError(err, event, source, encounterId, data); processedErr != nil {
return nil, processedErr
}
}
pl.SetLogInfo(event, nil, "complete")
return &data, nil
}
@@ -7,7 +7,6 @@ package encounter
import (
"errors"
"fmt"
"strings"
"time"
@@ -27,6 +26,7 @@ import (
ea "simrs-vx/internal/domain/main-entities/ambulatory"
ec "simrs-vx/internal/domain/main-entities/chemo"
ecpl "simrs-vx/internal/domain/main-entities/chemo-plan"
ecp "simrs-vx/internal/domain/main-entities/chemo-protocol"
edo "simrs-vx/internal/domain/main-entities/device-order"
ed "simrs-vx/internal/domain/main-entities/doctor"
ee "simrs-vx/internal/domain/main-entities/emergency"
@@ -663,6 +663,20 @@ func insertDataSubClassAmbulatory(input e.CreateDto, soapiData []es.CreateDto, e
switch {
case subCode == ere.ACCChemo:
// validate if encounter Chemo valid
chemoProtoc, err := validateChemoAdm(*input.Patient_Id, event)
if err != nil {
return err
}
if chemoProtoc == nil {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-not-found",
Detail: "chemo plan not found",
}
}
chemoCreate := ec.CreateDto{
Encounter_Id: &input.Id,
Status_Code: erc.DVCVerified,
@@ -677,7 +691,7 @@ func insertDataSubClassAmbulatory(input e.CreateDto, soapiData []es.CreateDto, e
}
// set chemo-plan to planned
_, err = updateChemoPlan(*input.Patient_Id, event, tx)
err = updateChemoPlan(chemoProtoc, event, tx)
if err != nil {
return err
}
@@ -875,10 +889,8 @@ func validateDoctorCodes(doctorCodes map[string]struct{}, event *pl.Event) error
return nil
}
func updateChemoPlan(patientId uint, event *pl.Event, dbx ...*gorm.DB) (*ecpl.ChemoPlan, error) {
func updateChemoPlan(data *ecpl.ChemoPlan, event *pl.Event, dbx ...*gorm.DB) error {
pl.SetLogInfo(event, nil, "started", "getChemoFromEncounter")
data := ecpl.ChemoPlan{}
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
@@ -886,20 +898,65 @@ func updateChemoPlan(patientId uint, event *pl.Event, dbx ...*gorm.DB) (*ecpl.Ch
tx = dg.I
}
tx = tx.Model(&ecpl.ChemoPlan{}).
Joins(`"ChemoProtocol" cp ON cp."Id" = "ChemoPlan"."Protocol_Id"`).
Where(`cp."Patient_Id" = ? AND ("ChemoPlan"."Status" IS NULL OR "ChemoPlan"."Status" = ?)`, patientId, ere.SPCSchedule).
Order(`"Id" ASC`).
Limit(1).First(&data)
if err := tx.Error; err != nil {
return nil, err
if err := tx.Model(&data).Update(`"Status"`, ere.SPCPlanned).Error; err != nil {
return err
}
if err := tx.Model(&data).Update(`"Status"`, ere.SPCPlanned).Error; err != nil {
pl.SetLogInfo(event, nil, "complete")
return nil
}
func getChemoProtocol(patientId uint, event *pl.Event) (*ecp.ChemoProtocol, error) {
pl.SetLogInfo(event, nil, "started", "getChemoProtocol")
data := ecp.ChemoProtocol{}
var tx = dg.I
tx = tx.Model(&ecp.ChemoProtocol{}).
Joins(`"ChemoPlan" cp ON cp."Protocol_Id" = "ChemoProtocol"."Id"`).
Where(`"Patient.Id" = ? AND cp."Status" IS NULL`, patientId).
Preload("ChemoPlans", func(db *gorm.DB) *gorm.DB {
return tx.Order(`"Id" ASC`).Limit(1)
}).
First(&data)
if err := tx.Error; err != nil {
return nil, err
}
pl.SetLogInfo(event, nil, "complete")
return &data, nil
}
func validateChemoAdm(patientId uint, event *pl.Event) (*ecpl.ChemoPlan, error) {
// get chemo protocol
chemo, err := getChemoProtocol(patientId, event)
if err != nil {
return nil, err
}
if chemo.Status_Code != erc.DVCVerified {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-not-match",
Detail: fmt.Sprintf("protocol chemo not yet verified"),
}
return nil, pl.SetLogError(event, chemo)
}
if now.Before(*chemo.StartDate) || now.After(*chemo.EndDate) {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "invalid-date-range",
Detail: "chemo cannot be performed because the current date is outside the allowed treatment window.",
}
return nil, pl.SetLogError(event, chemo)
}
if chemo.ChemoPlans == nil || len(*chemo.ChemoPlans) == 0 {
return nil, nil
}
// Return the first chemo plan
return &(*chemo.ChemoPlans)[0], nil
}
+27 -12
View File
@@ -77,20 +77,10 @@ func validateIfEncounterIsChemo(encounterId uint, event *pl.Event) (*ecpl.ChemoP
return nil, pl.SetLogError(event, nil)
}
if chemo.Status_Code != erc.DVCVerified {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-not-match",
Detail: fmt.Sprintf("protocol chemo not yet verified"),
}
if err = chemoProtocoValidation(chemo, event); err != nil {
}
now := time.Now()
if now.Before(*chemo.StartDate) || now.After(*chemo.EndDate) {
return nil, nil
}
// --- 3. Must have at least one ChemoPlan ---
if chemo.ChemoPlans == nil || len(*chemo.ChemoPlans) == 0 {
return nil, nil
}
@@ -99,6 +89,31 @@ func validateIfEncounterIsChemo(encounterId uint, event *pl.Event) (*ecpl.ChemoP
return &(*chemo.ChemoPlans)[0], nil
}
func chemoProtocoValidation(chemo *ecp.ChemoProtocol, event *pl.Event) error {
if chemo.Status_Code != erc.DVCVerified {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-not-match",
Detail: fmt.Sprintf("protocol chemo not yet verified"),
}
return pl.SetLogError(event, chemo)
}
now := time.Now()
if now.Before(*chemo.StartDate) || now.After(*chemo.EndDate) {
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "invalid-date-range",
Detail: "chemo cannot be performed because the current date is outside the allowed treatment window.",
}
return pl.SetLogError(event, chemo)
}
return nil
}
func getEncounter(encounterId uint, event *pl.Event) (*ee.Encounter, error) {
pl.SetLogInfo(event, nil, "started", "getEncounter")
data := ee.Encounter{}