505 lines
12 KiB
Go
505 lines
12 KiB
Go
package patient
|
|
|
|
import (
|
|
"errors"
|
|
"strconv"
|
|
|
|
pl "simrs-vx/pkg/logger"
|
|
pu "simrs-vx/pkg/use-case-helper"
|
|
|
|
dg "github.com/karincake/apem/db-gorm-pg"
|
|
d "github.com/karincake/dodol"
|
|
"gorm.io/gorm"
|
|
|
|
erc "simrs-vx/internal/domain/references/common"
|
|
|
|
evm "simrs-vx/internal/domain/bpjs-entities/vclaim-member"
|
|
e "simrs-vx/internal/domain/main-entities/patient"
|
|
esync "simrs-vx/internal/domain/sync-entities/log"
|
|
|
|
uvm "simrs-vx/internal/use-case/bpjs-use-case/vclaim-member"
|
|
upe "simrs-vx/internal/use-case/main-use-case/person"
|
|
upa "simrs-vx/internal/use-case/main-use-case/person-address"
|
|
upc "simrs-vx/internal/use-case/main-use-case/person-contact"
|
|
upi "simrs-vx/internal/use-case/main-use-case/person-insurance"
|
|
upr "simrs-vx/internal/use-case/main-use-case/person-relative"
|
|
)
|
|
|
|
const source = "patient"
|
|
|
|
func Create(input e.CreateDto, dbx ...*gorm.DB) (*d.Data, error) {
|
|
data := e.Patient{}
|
|
|
|
event := pl.Event{
|
|
Feature: "Create",
|
|
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)
|
|
|
|
if !input.AuthInfo.IsReg() && !input.AuthInfo.IsSys() {
|
|
event.Status = "failed"
|
|
event.ErrInfo = pl.ErrorInfo{
|
|
Code: "auth-forbidden",
|
|
Detail: "user role is not allowed to create patient, only 'reg' position is allowed",
|
|
Raw: errors.New("authentication failed"),
|
|
}
|
|
return nil, pl.SetLogError(&event, input)
|
|
}
|
|
|
|
input.RegisteredBy_User_Name = &input.AuthInfo.User_Name
|
|
|
|
err := tx.Transaction(func(tx1 *gorm.DB) error {
|
|
mwRunner.setMwType(pu.MWTPre)
|
|
// Run pre-middleware
|
|
if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil {
|
|
return err
|
|
}
|
|
|
|
// Run pre-middleware -> Generate number
|
|
nomr, err := mwRunner.RunGenerateNumberMiddleware(generatePatientNumber)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
input.Number = nomr
|
|
|
|
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, tx1); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
for idx := range input.PersonAddresses {
|
|
input.PersonAddresses[idx].Person_Id = *input.Person_Id
|
|
}
|
|
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, 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, 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, tx1); err != nil {
|
|
return err
|
|
}
|
|
|
|
if resData, err := CreateData(input, &event, tx1); err != nil {
|
|
return err
|
|
} else {
|
|
data = *resData
|
|
}
|
|
|
|
dataPatient, err := ReadDetailData(e.ReadDetailDto{Id: uint16(data.Id)}, &event, tx1)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
mwRunner.setMwType(pu.MWTPost)
|
|
// Run post-middleware
|
|
if err := mwRunner.RunCreateSyncMiddleware(createSimxSyncMw, dataPatient); 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
|
|
}
|
|
|
|
func ReadList(input e.ReadListDto) (*d.Data, error) {
|
|
var dataList []e.Patient
|
|
var metaList *e.MetaDto
|
|
var err error
|
|
|
|
event := pl.Event{
|
|
Feature: "ReadList",
|
|
Source: source,
|
|
}
|
|
|
|
// Start log
|
|
pl.SetLogInfo(&event, input, "started", "readList")
|
|
|
|
err = dg.I.Transaction(func(tx *gorm.DB) error {
|
|
if dataList, metaList, err = ReadListData(input, &event, tx); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
})
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &d.Data{
|
|
Meta: d.IS{
|
|
"source": source,
|
|
"structure": "list-data",
|
|
"status": "fetched",
|
|
"page_number": strconv.Itoa(metaList.PageNumber),
|
|
"page_size": strconv.Itoa(metaList.PageSize),
|
|
"record_totalCount": strconv.Itoa(metaList.Count),
|
|
"record_currentCount": strconv.Itoa(len(dataList)),
|
|
},
|
|
Data: e.ToResponseList(dataList),
|
|
}, nil
|
|
}
|
|
|
|
func ReadDetail(input e.ReadDetailDto) (*d.Data, error) {
|
|
var data *e.Patient
|
|
var err error
|
|
|
|
event := pl.Event{
|
|
Feature: "ReadDetail",
|
|
Source: source,
|
|
}
|
|
|
|
// Start log
|
|
pl.SetLogInfo(&event, input, "started", "readDetail")
|
|
|
|
err = dg.I.Transaction(func(tx *gorm.DB) error {
|
|
if data, err = ReadDetailData(input, &event, tx); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
})
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &d.Data{
|
|
Meta: d.IS{
|
|
"source": source,
|
|
"structure": "single-data",
|
|
"status": "fetched",
|
|
},
|
|
Data: data.ToResponse(),
|
|
}, nil
|
|
}
|
|
|
|
func Update(input e.UpdateDto) (*d.Data, error) {
|
|
rdDto := e.ReadDetailDto{Id: uint16(input.Id)}
|
|
var data *e.Patient
|
|
var err error
|
|
|
|
event := pl.Event{
|
|
Feature: "Update",
|
|
Source: source,
|
|
}
|
|
|
|
// Start log
|
|
pl.SetLogInfo(&event, input, "started", "update")
|
|
mwRunner := newMiddlewareRunner(&event, input.Sync)
|
|
|
|
if !input.AuthInfo.IsReg() && !input.AuthInfo.IsSys() {
|
|
event.Status = "failed"
|
|
event.ErrInfo = pl.ErrorInfo{
|
|
Code: "auth-forbidden",
|
|
Detail: "user role is not allowed to create patient, only 'reg' position is allowed",
|
|
Raw: errors.New("authentication failed"),
|
|
}
|
|
return nil, pl.SetLogError(&event, input)
|
|
}
|
|
|
|
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 person_id, err := upe.CreateOrUpdatePerson(input.Person, &event, tx); err != nil {
|
|
return err
|
|
} else {
|
|
input.Person_Id = person_id
|
|
}
|
|
|
|
for idx := range input.PersonAddresses {
|
|
input.PersonAddresses[idx].Person_Id = *input.Person_Id
|
|
}
|
|
if err := upa.CreateOrUpdateBatch(input.PersonAddresses, &event, tx); 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 {
|
|
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 {
|
|
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 {
|
|
return err
|
|
}
|
|
|
|
if err := UpdateData(input, data, &event, tx); err != nil {
|
|
return err
|
|
}
|
|
|
|
dataPatient, err := ReadDetailData(e.ReadDetailDto{Id: uint16(data.Id)}, &event, tx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
mwRunner.setMwType(pu.MWTPre)
|
|
// Run post-middleware
|
|
if err := mwRunner.RunUpdateMiddleware(updatePreMw, dataPatient); 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.IS{
|
|
"source": source,
|
|
"structure": "single-data",
|
|
"status": "updated",
|
|
},
|
|
Data: data.ToResponse(),
|
|
}, nil
|
|
|
|
}
|
|
|
|
func Delete(input e.DeleteDto) (*d.Data, error) {
|
|
rdDto := e.ReadDetailDto{Id: uint16(input.Id)}
|
|
var data *e.Patient
|
|
var err error
|
|
|
|
event := pl.Event{
|
|
Feature: "Delete",
|
|
Source: source,
|
|
}
|
|
|
|
// Start log
|
|
pl.SetLogInfo(&event, input, "started", "delete")
|
|
mwRunner := newMiddlewareRunner(&event, input.Sync)
|
|
|
|
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
|
|
}
|
|
|
|
// Delete Patient
|
|
if err := DeleteData(data, &event, tx); err != nil {
|
|
return err
|
|
}
|
|
|
|
// Delete PersonInsurance
|
|
if insurance := data.Person.Insurances; insurance != nil && len(*insurance) > 0 {
|
|
if err = upi.DeleteMultipleData(data.Person_Id, &event, tx); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
// Delete PersonRelative
|
|
if relative := data.Person.Relatives; relative != nil && len(*relative) > 0 {
|
|
if err = upr.DeleteMultipleData(data.Person_Id, &event, tx); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
// Delete PersonContacts
|
|
if contact := data.Person.Contacts; contact != nil && len(*contact) > 0 {
|
|
if err = upc.DeleteMultipleData(data.Person_Id, &event, tx); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
// Delete PersonAddress
|
|
if address := data.Person.Addresses; address != nil && len(*address) > 0 {
|
|
if err = upa.DeleteMultipleData(data.Person_Id, &event, tx); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
// Delete VclaimMember
|
|
if vclaim := data.Person.VclaimMember; vclaim != nil {
|
|
if err = uvm.DeleteData(vclaim, &event, tx); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
// Delete Person
|
|
if err = upe.DeleteData(data.Person, &event, tx); err != nil {
|
|
return err
|
|
}
|
|
|
|
mwRunner.setMwType(pu.MWTPre)
|
|
// Run post-middleware
|
|
if err := mwRunner.RunDeleteMiddleware(deletePreMw, &input); 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.IS{
|
|
"source": source,
|
|
"structure": "single-data",
|
|
"status": "deleted",
|
|
},
|
|
Data: data.ToResponse(),
|
|
}, nil
|
|
|
|
}
|
|
|
|
func SearchByResidentIdentityNumber(input e.SearchDto) (*d.Data, error) {
|
|
var data *e.Patient
|
|
var err error
|
|
|
|
event := pl.Event{
|
|
Feature: "Search By Resident Identity Number",
|
|
Source: source,
|
|
}
|
|
|
|
// Start log
|
|
pl.SetLogInfo(&event, input, "started", "search")
|
|
if data, err = SearchDataByRIN(input, &event); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &d.Data{
|
|
Meta: d.IS{
|
|
"source": source,
|
|
"structure": "single-data",
|
|
"status": "fetched",
|
|
},
|
|
Data: data.ToResponse(),
|
|
}, nil
|
|
}
|
|
|
|
func Search(input e.SearchDto) (*d.Data, error) {
|
|
var dataList []e.Patient
|
|
var metaList *e.MetaDto
|
|
var err error
|
|
|
|
event := pl.Event{
|
|
Feature: "Search",
|
|
Source: source,
|
|
}
|
|
|
|
// Start log
|
|
pl.SetLogInfo(&event, input, "started", "readList")
|
|
|
|
err = dg.I.Transaction(func(tx *gorm.DB) error {
|
|
|
|
if dataList, metaList, err = SearchData(input, &event, tx); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
})
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &d.Data{
|
|
Meta: d.IS{
|
|
"source": source,
|
|
"structure": "list-data",
|
|
"status": "fetched",
|
|
"page_number": strconv.Itoa(metaList.PageNumber),
|
|
"page_size": strconv.Itoa(metaList.PageSize),
|
|
"record_totalCount": strconv.Itoa(metaList.Count),
|
|
"record_currentCount": strconv.Itoa(len(dataList)),
|
|
},
|
|
Data: e.ToResponseList(dataList),
|
|
}, nil
|
|
}
|
|
|
|
func runLogMiddleware(err error, input any, mwRunner *middlewareRunner) error {
|
|
var errMsg string
|
|
inputLog := esync.SimxLogDto{
|
|
Payload: input,
|
|
Method: erc.CCCreate,
|
|
}
|
|
|
|
if err != nil {
|
|
// Run log-middleware
|
|
errMsg = err.Error()
|
|
inputLog.ErrMessage = &errMsg
|
|
inputLog.IsSuccess = false
|
|
|
|
// create log failed
|
|
if errMiddleware := mwRunner.RunCreateLogMiddleware(createSimxLogMw, &inputLog); errMiddleware != nil {
|
|
return errMiddleware
|
|
}
|
|
return err
|
|
}
|
|
|
|
// create log success
|
|
inputLog.IsSuccess = true
|
|
if err = mwRunner.RunCreateLogMiddleware(createSimxLogMw, &inputLog); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|