add switch poly and spprove
This commit is contained in:
No files matched your search
@@ -2,7 +2,7 @@ package encounter
|
||||
|
||||
import (
|
||||
"errors"
|
||||
authhelper "simrs-vx/internal/lib/auth"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
@@ -17,28 +17,18 @@ import (
|
||||
ere "simrs-vx/internal/domain/references/encounter"
|
||||
|
||||
eaeh "simrs-vx/internal/domain/main-entities/adm-employee-hist"
|
||||
ea "simrs-vx/internal/domain/main-entities/ambulatory"
|
||||
ec "simrs-vx/internal/domain/main-entities/chemo"
|
||||
edc "simrs-vx/internal/domain/main-entities/death-cause"
|
||||
ed "simrs-vx/internal/domain/main-entities/doctor"
|
||||
ee "simrs-vx/internal/domain/main-entities/emergency"
|
||||
eem "simrs-vx/internal/domain/main-entities/employee"
|
||||
e "simrs-vx/internal/domain/main-entities/encounter"
|
||||
ei "simrs-vx/internal/domain/main-entities/inpatient"
|
||||
er "simrs-vx/internal/domain/main-entities/rehab"
|
||||
eir "simrs-vx/internal/domain/main-entities/internal-reference"
|
||||
erdh "simrs-vx/internal/domain/main-entities/responsible-doctor-hist"
|
||||
es "simrs-vx/internal/domain/main-entities/soapi"
|
||||
|
||||
uaeh "simrs-vx/internal/use-case/main-use-case/adm-employee-hist"
|
||||
ua "simrs-vx/internal/use-case/main-use-case/ambulatory"
|
||||
uc "simrs-vx/internal/use-case/main-use-case/chemo"
|
||||
udc "simrs-vx/internal/use-case/main-use-case/death-cause"
|
||||
ud "simrs-vx/internal/use-case/main-use-case/doctor"
|
||||
ue "simrs-vx/internal/use-case/main-use-case/emergency"
|
||||
uem "simrs-vx/internal/use-case/main-use-case/employee"
|
||||
ui "simrs-vx/internal/use-case/main-use-case/inpatient"
|
||||
ur "simrs-vx/internal/use-case/main-use-case/rehab"
|
||||
us "simrs-vx/internal/use-case/main-use-case/soapi"
|
||||
uir "simrs-vx/internal/use-case/main-use-case/internal-reference"
|
||||
urdh "simrs-vx/internal/use-case/main-use-case/responsible-doctor-hist"
|
||||
)
|
||||
|
||||
const source = "encounter"
|
||||
@@ -46,8 +36,11 @@ const source = "encounter"
|
||||
var now = time.Now()
|
||||
|
||||
func Create(input e.CreateDto) (*d.Data, error) {
|
||||
data := e.Encounter{}
|
||||
createSoapi := []es.CreateDto{}
|
||||
var (
|
||||
data e.Encounter
|
||||
recentSoapiDataforCopy []es.CreateDto
|
||||
err error
|
||||
)
|
||||
|
||||
event := pl.Event{
|
||||
Feature: "Create",
|
||||
@@ -57,51 +50,36 @@ func Create(input e.CreateDto) (*d.Data, error) {
|
||||
// Start log
|
||||
pl.SetLogInfo(&event, input, "started", "create")
|
||||
|
||||
// validate SubClass
|
||||
var subCode interface{}
|
||||
subCode, err := verifyClassCode(input)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// verify whether the allocated visit count has not exceeded the limit
|
||||
if input.Class_Code == ere.ECAmbulatory && subCode.(ere.AmbulatoryClassCode) == ere.ACCRehab &&
|
||||
*input.VisitMode_Code == ere.VMCSeries {
|
||||
|
||||
dataEncounter, valid, err := verifyAllocatedVisitCount(input, &event)
|
||||
// validate rehab bpjs
|
||||
if input.RefTypeCode == ere.RTCBpjs && input.Class_Code == ere.ECAmbulatory && ere.AmbulatoryClassCode(*input.SubClass_Code) == ere.ACCRehab {
|
||||
// identify visit mode from latest rehab data
|
||||
recentRehabData, err := identifyVisitModeCode(input, &event)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !valid {
|
||||
event.Status = "failed"
|
||||
event.ErrInfo = pl.ErrorInfo{
|
||||
Code: "visit-limit-exceeded",
|
||||
Detail: "Encounter has exceeded the allowed number of visits",
|
||||
Raw: errors.New("visit count exceeds allowed limit"),
|
||||
if recentRehabData != nil {
|
||||
// determine VisitModeCode
|
||||
input.VisitMode_Code, *input.RecentEncounterAdm, err = determineVisitMode(recentRehabData, input, &event)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, pl.SetLogError(&event, input)
|
||||
} else {
|
||||
input.VisitMode_Code = ere.VMCAdm
|
||||
}
|
||||
|
||||
// get data soapi
|
||||
createSoapi, err = getSoapiEncounterAdm(dataEncounter, &event)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
// if visitMode_Code is series, then get data soapi for copy
|
||||
if input.VisitMode_Code == ere.VMCSeries {
|
||||
// get data soapi
|
||||
recentSoapiDataforCopy, err = getSoapiEncounterAdm(*input.RecentEncounterAdm, &event)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check if patient is new in the hospital
|
||||
dataPatient, err := ReadList(e.ReadListDto{
|
||||
FilterDto: e.FilterDto{Patient_Id: input.Patient_Id},
|
||||
AuthInfo: authhelper.AuthInfo{User_Id: input.User_Id}})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if list, ok := dataPatient.Data.([]e.ResponseDto); ok {
|
||||
if len(list) < 1 {
|
||||
input.NewStatus = true
|
||||
}
|
||||
}
|
||||
input.NewStatus, err = identifyPatientStatus(input)
|
||||
|
||||
err = dg.I.Transaction(func(tx *gorm.DB) error {
|
||||
mwRunner := newMiddlewareRunner(&event, tx)
|
||||
@@ -122,72 +100,18 @@ func Create(input e.CreateDto) (*d.Data, error) {
|
||||
return err
|
||||
} else {
|
||||
data = *resData
|
||||
input.Id = data.Id
|
||||
}
|
||||
|
||||
switch input.Class_Code {
|
||||
case ere.ECAmbulatory:
|
||||
subCodeAmbulatory := subCode.(ere.AmbulatoryClassCode)
|
||||
ambCreate := ea.CreateDto{
|
||||
Encounter_Id: &data.Id,
|
||||
Class_Code: subCodeAmbulatory,
|
||||
}
|
||||
_, err = ua.CreateData(ambCreate, &event, tx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if subCodeAmbulatory == ere.ACCChemo {
|
||||
chemoCreate := ec.CreateDto{
|
||||
Encounter_Id: &data.Id,
|
||||
Status_Code: erc.DVCNew,
|
||||
SrcUnit_Id: input.Unit_Id,
|
||||
}
|
||||
_, err = uc.CreateData(chemoCreate, &event, tx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if subCodeAmbulatory == ere.ACCRehab && *input.VisitMode_Code == ere.VMCAdm {
|
||||
// create data rehab
|
||||
if _, err = ur.CreateData(er.CreateDto{
|
||||
Encounter_Id: &data.Id,
|
||||
AllocatedVisitCount: input.AllocatedVisitCount}, &event, tx); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if subCodeAmbulatory == ere.ACCRehab && *input.VisitMode_Code == ere.VMCSeries {
|
||||
// Insert Soapi
|
||||
if err = us.CreateBulkData(createSoapi, data.Id, &event, tx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
case ere.ECEmergency:
|
||||
emerCreate := ee.CreateDto{
|
||||
Encounter_Id: &data.Id,
|
||||
Class_Code: subCode.(ere.EmergencyClassCode),
|
||||
}
|
||||
_, err = ue.CreateData(emerCreate, &event, tx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case ere.ECInpatient:
|
||||
inpCreate := ei.CreateDto{
|
||||
Encounter_Id: &data.Id,
|
||||
Class_Code: subCode.(ere.InpatientClassCode),
|
||||
Infra_Id: input.Infra_Id,
|
||||
}
|
||||
_, err = ui.CreateData(inpCreate, &event, tx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return errors.New("invalid encounter class code")
|
||||
// insert ambulatory/emergency/inpatient
|
||||
err = insertdataClassCode(input, recentSoapiDataforCopy, &event, tx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// insert adm_employee_hist
|
||||
if _, err := uaeh.CreateData(eaeh.CreateDto{
|
||||
Encounter_Id: &data.Main.Id,
|
||||
Encounter_Id: &data.Id,
|
||||
Employee_Id: data.Adm_Employee_Id,
|
||||
StartedAt: &now}, &event, tx); err != nil {
|
||||
return err
|
||||
@@ -469,10 +393,15 @@ func CheckOut(input e.DischargeDto) (*d.Data, error) {
|
||||
|
||||
if data.Ambulatory != nil && (data.Ambulatory.Class_Code == ere.ACCReg || data.Ambulatory.Class_Code == ere.ACCRehab) {
|
||||
// validate if soapi exist
|
||||
err = getSoapiByTypeCode(input.Id, *data.Ambulatory, &event, "check-out")
|
||||
if err != nil {
|
||||
if err = getSoapiByTypeCode(data, &event, "check-out"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// verify and update rehabData if visit count has reached the allowed limit
|
||||
if err = verifyRehabLimit(data, &event, tx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
} else {
|
||||
// chemo TBC
|
||||
if err := checkSoapiByDocExists(data.Id, &event, tx); err != nil {
|
||||
@@ -495,27 +424,22 @@ func CheckOut(input e.DischargeDto) (*d.Data, error) {
|
||||
}
|
||||
|
||||
// update finishedAt in latest responsible_doctor_hist
|
||||
if err = updateLatestResponsibleDoctorHist(e.CheckinDto{Id: input.Id, StartedAt: &now}, &event, tx); err != nil {
|
||||
if err = updateLatestResponsibleDoctorHist(e.CheckinDto{Id: input.Id, FinishedAt: &now}, &event, tx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update finishedAt in latest adm_employee_hist
|
||||
if err = updateLatestAdmEmployeeHist(e.CheckinDto{Id: input.Id, StartedAt: &now}, &event, tx); err != nil {
|
||||
if err = updateLatestAdmEmployeeHist(e.CheckinDto{Id: input.Id, FinishedAt: &now}, &event, tx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// insert data death-cause
|
||||
if *input.Discharge_Method_Code == ere.DMCDeath {
|
||||
// insert data death-cause
|
||||
if _, err = udc.CreateData(edc.CreateDto{Encounter_Id: &input.Id, Value: input.DeathCause}, &event, tx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
//// bulk insert internal-references
|
||||
//if err = createInternalReferences(input, &event, tx); err != nil {
|
||||
// return err
|
||||
//}
|
||||
|
||||
pl.SetLogInfo(&event, nil, "complete")
|
||||
|
||||
return nil
|
||||
@@ -642,13 +566,13 @@ func CheckIn(input e.CheckinDto) (*d.Data, error) {
|
||||
|
||||
// validate if soapi exist
|
||||
if data.Ambulatory != nil && (data.Ambulatory.Class_Code == ere.ACCReg || data.Ambulatory.Class_Code == ere.ACCRehab) {
|
||||
err = getSoapiByTypeCode(input.Id, *data.Ambulatory, &event, "check-in")
|
||||
err = getSoapiByTypeCode(data, &event, "check-in")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Insert responsible_doctor_hist if responsible_doctor_id has changed && update latest history
|
||||
// Upsert responsible_doctor_hist if responsible_doctor_id has changed
|
||||
if data.Responsible_Doctor_Id == nil || *input.Responsible_Doctor_Id != *data.Responsible_Doctor_Id {
|
||||
// upsert responsibleDoctorHist
|
||||
if err = upsertResponsibleDoctorHist(erdh.CreateDto{
|
||||
@@ -660,7 +584,7 @@ func CheckIn(input e.CheckinDto) (*d.Data, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Insert adm_employee_hist if adm_employee_id has changed && update latest history
|
||||
// Upsert adm_employee_hist if adm_employee_id has changed
|
||||
if input.Adm_Employee_Id != nil && *input.Adm_Employee_Id != *data.Adm_Employee_Id {
|
||||
// upsert admEmployeeHist
|
||||
if err = upsertAdmEmployeeHist(eaeh.CreateDto{
|
||||
@@ -677,14 +601,6 @@ func CheckIn(input e.CheckinDto) (*d.Data, error) {
|
||||
return err
|
||||
}
|
||||
|
||||
if data.Ambulatory.Class_Code == ere.ACCRehab {
|
||||
if err := updateRehabDoctor(er.UpdateDto{CreateDto: er.CreateDto{
|
||||
Encounter_Id: &data.Id,
|
||||
}}, &event, tx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
pl.SetLogInfo(&event, nil, "complete")
|
||||
|
||||
return nil
|
||||
@@ -704,43 +620,205 @@ func CheckIn(input e.CheckinDto) (*d.Data, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func validateForeignKey(input e.CheckinDto) error {
|
||||
// validate employee_Id
|
||||
if input.Adm_Employee_Id != nil {
|
||||
if _, err := uem.ReadDetail(eem.ReadDetailDto{Id: uint16(*input.Adm_Employee_Id)}); err != nil {
|
||||
func RequestSwitchUnit(input e.SwitchUnitDto) (*d.Data, error) {
|
||||
rdDto := e.ReadDetailDto{Id: uint16(input.Id), Includes: "Responsible_Doctor"}
|
||||
var data *e.Encounter
|
||||
var err error
|
||||
|
||||
event := pl.Event{
|
||||
Feature: "RequestSwitchUnit",
|
||||
Source: source,
|
||||
}
|
||||
|
||||
// Start log
|
||||
pl.SetLogInfo(&event, input, "started", "checkOut")
|
||||
|
||||
unitIDs := make(map[uint16]struct{})
|
||||
doctorIDs := make(map[uint]struct{})
|
||||
for _, ref := range *input.InternalReferences {
|
||||
if ref.Unit_Id != nil {
|
||||
unitIDs[*ref.Unit_Id] = struct{}{}
|
||||
}
|
||||
if ref.Doctor_Id != nil {
|
||||
doctorIDs[*ref.Doctor_Id] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
// validate unit
|
||||
if err = validateUnitIds(unitIDs, &event); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// validate doctor
|
||||
if err = validateDoctorIds(doctorIDs, &event); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
// validate doctor_id
|
||||
if input.Responsible_Doctor_Id != nil {
|
||||
if _, err := ud.ReadDetail(ed.ReadDetailDto{Id: uint16(*input.Responsible_Doctor_Id)}); err != nil {
|
||||
//if data.IsDone() {
|
||||
// event.Status = "failed"
|
||||
// event.ErrInfo = pl.ErrorInfo{
|
||||
// Code: "data-state-mismatch",
|
||||
// Detail: "encounter is done",
|
||||
// Raw: errors.New("encounter is done"),
|
||||
// }
|
||||
// return pl.SetLogError(&event, input)
|
||||
//}
|
||||
|
||||
// verify Soapi exist for current responsible doctor
|
||||
dataSoapi, err := getSoapiByResponsibleDoctor(*data, &event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(dataSoapi) < 1 {
|
||||
event.Status = "failed"
|
||||
event.ErrInfo = pl.ErrorInfo{
|
||||
Code: "missing-soapi",
|
||||
Detail: fmt.Sprintf("Missing soapi from latest responsible doctor"),
|
||||
}
|
||||
return pl.SetLogError(&event, input)
|
||||
}
|
||||
|
||||
// bulk internal references
|
||||
if err := uir.CreateBulkData(*input.InternalReferences, input.Id, &event, tx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pl.SetLogInfo(&event, nil, "complete")
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nil
|
||||
return &d.Data{
|
||||
Meta: d.IS{
|
||||
"source": source,
|
||||
"structure": "single-data",
|
||||
"status": "requestSwitchUnit",
|
||||
},
|
||||
Data: data.ToResponse(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func verifyClassCode(input e.CreateDto) (subCode interface{}, err error) {
|
||||
switch input.Class_Code {
|
||||
case ere.ECAmbulatory:
|
||||
subCode, err = ua.CheckClassCode(input.SubClass_Code)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case ere.ECEmergency:
|
||||
subCode, err = ue.CheckClassCode(input.SubClass_Code)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case ere.ECInpatient:
|
||||
subCode, err = ui.CheckClassCode(input.SubClass_Code)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
default:
|
||||
return nil, errors.New("invalid encounter class code")
|
||||
func ApproveSwitchUnit(input e.ApproveUnitDto) (*d.Data, error) {
|
||||
rdDto := e.ReadDetailDto{Id: uint16(input.Id), Includes: "Responsible_Doctor"}
|
||||
var data *e.Encounter
|
||||
var err error
|
||||
|
||||
event := pl.Event{
|
||||
Feature: "ApproveSwitchUnit",
|
||||
Source: source,
|
||||
}
|
||||
return
|
||||
|
||||
// Start log
|
||||
pl.SetLogInfo(&event, input, "started", "approveSwitchUnit")
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// get internal reference
|
||||
irData, err := uir.ReadDetailData(eir.ReadDetailDto{
|
||||
Id: input.InternalReferences_Id, Includes: "Doctor"}, &event, tx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if *irData.Status_Code != erc.DACNew {
|
||||
event.Status = "failed"
|
||||
event.ErrInfo = pl.ErrorInfo{
|
||||
Code: "data-state-mismatch",
|
||||
Detail: "internal references is approve",
|
||||
Raw: errors.New("internal references is approve"),
|
||||
}
|
||||
return pl.SetLogError(&event, input)
|
||||
}
|
||||
|
||||
//if data.IsDone() {
|
||||
// event.Status = "failed"
|
||||
// event.ErrInfo = pl.ErrorInfo{
|
||||
// Code: "data-state-mismatch",
|
||||
// Detail: "encounter is done",
|
||||
// Raw: errors.New("encounter is done"),
|
||||
// }
|
||||
// return pl.SetLogError(&event, input)
|
||||
//}
|
||||
|
||||
// verify Soapi exist for current responsible doctor
|
||||
dataSoapi, err := getSoapiByResponsibleDoctor(*data, &event)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(dataSoapi) < 1 {
|
||||
event.Status = "failed"
|
||||
event.ErrInfo = pl.ErrorInfo{
|
||||
Code: "missing-soapi",
|
||||
Detail: fmt.Sprintf("Missing soapi from latest responsible doctor"),
|
||||
}
|
||||
return pl.SetLogError(&event, input)
|
||||
}
|
||||
|
||||
// update internal reference
|
||||
if err = uir.UpdateData(eir.UpdateDto{
|
||||
Id: input.InternalReferences_Id,
|
||||
CreateDto: eir.CreateDto{
|
||||
Encounter_Id: &input.Id,
|
||||
Doctor_Id: irData.Doctor_Id,
|
||||
Unit_Id: irData.Unit_Id,
|
||||
Status_Code: erc.DACApproved,
|
||||
}}, irData, &event, tx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update encounter
|
||||
if err = updateEncounterApproveSwitchUnit(*irData, &event, tx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update latest responsible doctor hist
|
||||
if err = updateLatestResponsibleDoctorHist(e.CheckinDto{Id: input.Id, FinishedAt: &now}, &event, tx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// create responsible doctor based on internal reference data
|
||||
if _, err = urdh.CreateData(erdh.CreateDto{
|
||||
Encounter_Id: &input.Id,
|
||||
Doctor_Id: irData.Doctor_Id,
|
||||
StartedAt: &now,
|
||||
}, &event, tx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update data response
|
||||
data.Responsible_Doctor_Id = irData.Doctor_Id
|
||||
data.Unit = irData.Unit
|
||||
data.Specialist_Id = irData.Doctor.Specialist_Id
|
||||
data.Subspecialist_Id = irData.Doctor.Subspecialist_Id
|
||||
|
||||
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
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user