feat (encounter): create-with-patient wip

This commit is contained in:
dpurbosakti
2025-12-11 15:29:01 +07:00
parent 4172ecc427
commit 2e70cd727c
7 changed files with 218 additions and 10 deletions
@@ -22,12 +22,14 @@ import (
edc "simrs-vx/internal/domain/main-entities/death-cause"
e "simrs-vx/internal/domain/main-entities/encounter"
eir "simrs-vx/internal/domain/main-entities/internal-reference"
ep "simrs-vx/internal/domain/main-entities/patient"
es "simrs-vx/internal/domain/main-entities/soapi"
esync "simrs-vx/internal/domain/sync-entities/log"
uv "simrs-vx/internal/use-case/bpjs-use-case/vclaim-reference"
udc "simrs-vx/internal/use-case/main-use-case/death-cause"
uir "simrs-vx/internal/use-case/main-use-case/internal-reference"
up "simrs-vx/internal/use-case/main-use-case/patient"
us "simrs-vx/internal/use-case/main-use-case/soapi"
)
@@ -1075,3 +1077,144 @@ func validateAuth(a auth.AuthInfo, roleAllowed []string, action string, event *p
return nil
}
func CreateWithPatient(input e.CreateWithPatientDto) (*d.Data, error) {
var (
data e.Encounter
recentSoapiDataforCopy []es.CreateDto
err error
)
event := pl.Event{
Feature: "Create",
Source: source,
}
// Start log
pl.SetLogInfo(&event, input, "started", "create")
roleAllowed := []string{string(erg.EPCReg)}
err = validateAuth(input.Encounter.AuthInfo, roleAllowed, "create-encounter", &event)
if err != nil {
return nil, err
}
// validate rehab by bpjs
if input.Encounter.RefTypeCode == ere.RTCBpjs &&
input.Encounter.Class_Code == ere.ECAmbulatory &&
ere.AmbulatoryClassCode(*input.Encounter.SubClass_Code) == ere.ACCRehab {
// get latest rehab data
recentRehabData, err := getLatestRehabData(input.Encounter, &event)
if err != nil {
return nil, err
}
// If recentRehabData is nil, then visitMode_Code = "adm"
if recentRehabData != nil {
// If recentRehabData is not nil, determine the visitMode_Code:
// If the mode is "series", verify whether the visit count still remains
// and whether the series has not expired.
// If visitMode is "series", then get encounterAdm
input.Encounter.VisitMode_Code, input.Encounter.RecentEncounterAdm, err = determineVisitMode(recentRehabData, input.Encounter, &event)
if err != nil {
return nil, err
}
} else {
input.Encounter.VisitMode_Code = ere.VMCAdm
}
// When visitMode_Code is "series", load the associated SOAPI record to copy its values.
if input.Encounter.VisitMode_Code == ere.VMCSeries {
// get data soapi
recentSoapiDataforCopy, err = getSoapiEncounterAdm(*input.Encounter.RecentEncounterAdm, &event)
if err != nil {
return nil, err
}
}
}
// check if patient is new in the hospital
input.Encounter.NewStatus, err = identifyPatientStatus(input.Encounter)
if err != nil {
return nil, err
}
input.Encounter.Adm_Employee_Id = input.Encounter.AuthInfo.Employee_Id
mwRunner := newMiddlewareRunner(&event, input.Encounter.Sync)
err = dg.I.Transaction(func(tx *gorm.DB) error {
// create patient
var patientId uint
patientData, err := up.Create(input.Patient, tx)
if err != nil {
return err
}
if patientData != nil {
patientId = patientData.Data.(*ep.Patient).Id
}
// create encounter
input.Encounter.Patient_Id = &patientId
if resData, err := CreateData(input.Encounter, &event, tx); err != nil {
return err
} else {
data = *resData
input.Encounter.Id = data.Id
}
// insert ambulatory/emergency/inpatient
err = insertdataClassCode(input.Encounter, recentSoapiDataforCopy, &event, tx)
if err != nil {
return err
}
// insert vclaimReference
if vr := input.Encounter.VclaimReference; vr != nil {
t, _ := time.Parse("2006-01-02", vr.TglRujukan)
_, err = uv.CreateData(ev.CreateDto{
Encounter_Id: &data.Id,
Date: &t,
SrcCode: input.Encounter.Ref_Number,
SrcName: input.Encounter.RefSource_Name,
Number: &vr.NoSep}, &event, tx)
if err != nil {
return err
}
}
dataEncounter, err := ReadDetailData(e.ReadDetailDto{
Id: data.Id,
Includes: "Adm_Employee.User,Adm_Employee.Person," +
"Patient.Person.Relatives," +
"Patient.Person.VclaimMember,VclaimReference," +
"Patient.Person.Contacts,Patient.Person.Addresses"},
&event, tx)
if err != nil {
return err
}
mwRunner.setMwType(pu.MWTPre)
// Run pre-middleware
if err := mwRunner.RunCreateWithPatientMiddleware(createWithPatientPreMw, dataEncounter); err != nil {
return err
}
return nil
})
if err = runLogMiddleware(err, input, mwRunner); err != nil {
return nil, err
}
pl.SetLogInfo(&event, nil, "complete")
return &d.Data{
Meta: d.II{
"source": source,
"structure": "single-data",
"status": "created",
},
Data: data.ToResponse(),
}, nil
}
@@ -259,3 +259,22 @@ func (me *middlewareRunner) RunCancelSwitchUnitMiddleware(middleware cancelSwitc
func (me *middlewareRunner) setMwType(mwType pu.MWType) {
me.MwType = mwType
}
func (me *middlewareRunner) RunCreateWithPatientMiddleware(middlewares []createWithPatientMw, input *e.Encounter) error {
if !me.SyncOn {
return nil
}
for _, middleware := range middlewares {
logData := pu.GetLogData(input, nil)
pl.SetLogInfo(me.Event, logData, "started", middleware.Name)
if err := middleware.Func(input); err != nil {
return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err)
}
pl.SetLogInfo(me.Event, nil, "complete")
}
return nil
}
@@ -74,6 +74,11 @@ type cancelSwitchUnitMw struct {
Func func(input *e.ApproveCancelUnitDto) error
}
type createWithPatientMw struct {
Name string
Func func(input *e.Encounter) error
}
type UpdateMw = updateMw
type DeleteMw = deleteMw
@@ -94,3 +99,5 @@ var updatestatusEncounter []updateStatusMw
var requestSwitchEncounter requestSwitchUnitMw
var approveSwitchEncounter approveSwitchUnitMw
var cancelSwitchEncounter cancelSwitchUnitMw
var createWithPatientPreMw []createWithPatientMw
var createWithPatientPostMw []createWithPatientMw
+17 -10
View File
@@ -27,7 +27,7 @@ import (
const source = "patient"
func Create(input e.CreateDto) (*d.Data, error) {
func Create(input e.CreateDto, dbx ...*gorm.DB) (*d.Data, error) {
data := e.Patient{}
event := pl.Event{
@@ -35,6 +35,13 @@ func Create(input e.CreateDto) (*d.Data, error) {
Source: source,
}
var tx *gorm.DB
if len(dbx) > 0 {
tx = dbx[0]
} else {
tx = dg.I
}
// Start log
pl.SetLogInfo(&event, input, "started", "create")
mwRunner := newMiddlewareRunner(&event, input.Sync)
@@ -51,7 +58,7 @@ func Create(input e.CreateDto) (*d.Data, error) {
input.RegisteredBy_User_Name = &input.AuthInfo.User_Name
err := dg.I.Transaction(func(tx *gorm.DB) error {
err := tx.Transaction(func(tx1 *gorm.DB) error {
mwRunner.setMwType(pu.MWTPre)
// Run pre-middleware
if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil {
@@ -65,14 +72,14 @@ func Create(input e.CreateDto) (*d.Data, error) {
}
input.Number = nomr
if person_id, err := upe.CreateOrUpdatePerson(input.Person, &event, tx); err != nil {
if person_id, err := upe.CreateOrUpdatePerson(input.Person, &event, tx1); err != nil {
return err
} else {
input.Person_Id = person_id
}
if input.Person.VclaimMember_CardNumber != nil && input.Person.ResidentIdentityNumber != nil {
if err := uvm.CreateOrUpdateData(evm.CreateDto{CardNumber: input.Person.VclaimMember_CardNumber, Person_Id: input.Person_Id}, &event, tx); err != nil {
if err := uvm.CreateOrUpdateData(evm.CreateDto{CardNumber: input.Person.VclaimMember_CardNumber, Person_Id: input.Person_Id}, &event, tx1); err != nil {
return err
}
}
@@ -80,38 +87,38 @@ func Create(input e.CreateDto) (*d.Data, error) {
for idx := range input.PersonAddresses {
input.PersonAddresses[idx].Person_Id = *input.Person_Id
}
if err := upa.CreateOrUpdateBatch(input.PersonAddresses, &event, tx); err != nil {
if err := upa.CreateOrUpdateBatch(input.PersonAddresses, &event, tx1); err != nil {
return err
}
for idx := range input.PersonContacts {
input.PersonContacts[idx].Person_Id = *input.Person_Id
}
if err := upc.CreateOrUpdateBatch(input.PersonContacts, &event, tx); err != nil {
if err := upc.CreateOrUpdateBatch(input.PersonContacts, &event, tx1); err != nil {
return err
}
for idx := range input.PersonRelatives {
input.PersonRelatives[idx].Person_Id = *input.Person_Id
}
if err := upr.CreateOrUpdateBatch(input.PersonRelatives, &event, tx); err != nil {
if err := upr.CreateOrUpdateBatch(input.PersonRelatives, &event, tx1); err != nil {
return err
}
for idx := range input.PersonInsurances {
input.PersonInsurances[idx].Person_Id = *input.Person_Id
}
if err := upi.CreateOrUpdateBatch(input.PersonInsurances, &event, tx); err != nil {
if err := upi.CreateOrUpdateBatch(input.PersonInsurances, &event, tx1); err != nil {
return err
}
if resData, err := CreateData(input, &event, tx); err != nil {
if resData, err := CreateData(input, &event, tx1); err != nil {
return err
} else {
data = *resData
}
dataPatient, err := ReadDetailData(e.ReadDetailDto{Id: uint16(data.Id)}, &event, tx)
dataPatient, err := ReadDetailData(e.ReadDetailDto{Id: uint16(data.Id)}, &event, tx1)
if err != nil {
return err
}