Files
simrsx-be/internal/use-case/main-use-case/ambulance-transport-req/case.go
T
2025-10-22 09:03:19 +07:00

399 lines
9.4 KiB
Go

package ambulance_transport_req
import (
"errors"
"strconv"
// main entities
eatr "simrs-vx/internal/domain/main-entities/ambulance-transport-req"
edis "simrs-vx/internal/domain/main-entities/district"
ep "simrs-vx/internal/domain/main-entities/patient"
epro "simrs-vx/internal/domain/main-entities/province"
ereg "simrs-vx/internal/domain/main-entities/regency"
evil "simrs-vx/internal/domain/main-entities/village"
// main use case
udis "simrs-vx/internal/use-case/main-use-case/district"
up "simrs-vx/internal/use-case/main-use-case/patient"
upro "simrs-vx/internal/use-case/main-use-case/province"
ureg "simrs-vx/internal/use-case/main-use-case/regency"
uvil "simrs-vx/internal/use-case/main-use-case/village"
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"
)
const source = "ambulance-transport-req"
func Create(input eatr.CreateDto) (*d.Data, error) {
data := eatr.AmbulanceTransportReq{}
event := pl.Event{
Feature: "Create",
Source: source,
}
// Start log
pl.SetLogInfo(&event, input, "started", "create")
// validate request code value
if err := validateRequestCode(&input, &event); err != nil {
return nil, err
}
// validateForeignKeys ensures that all foreign key references in the given input
// exist in their respective tables. It returns an error if any referenced record
// is missing or invalid.
if err := validateForeignKeys(input, &event); err != nil {
return nil, err
}
err := dg.I.Transaction(func(tx *gorm.DB) error {
mwRunner := newMiddlewareRunner(&event, tx)
mwRunner.setMwType(pu.MWTPre)
// Run pre-middleware
if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil {
return err
}
if resData, err := CreateData(input, &event, tx); err != nil {
return err
} else {
data = *resData
}
mwRunner.setMwType(pu.MWTPost)
// Run post-middleware
if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil {
return err
}
pl.SetLogInfo(&event, nil, "complete")
return nil
})
if err != nil {
return nil, err
}
return &d.Data{
Meta: d.II{
"source": source,
"structure": "single-data",
"status": "created",
},
Data: data.ToResponse(),
}, nil
}
func validateForeignKeys(input eatr.CreateDto, event *pl.Event) (err error) {
// Validate Patient Id
if input.Patient_Id != nil {
_, err = up.ReadDetail(ep.ReadDetailDto{Id: uint16(*input.Patient_Id)})
if err != nil {
return err
}
}
event.Status = "failed"
event.ErrInfo = pl.ErrorInfo{
Code: "data-not-found",
}
// Validate Province Code
if input.Province_Code != nil {
dataProvince, err := upro.ReadList(epro.ReadListDto{FilterDto: epro.FilterDto{Code: *input.Province_Code}})
if err != nil {
return err
}
if list, ok := dataProvince.Data.([]epro.ResponseDto); ok {
if len(list) < 1 {
event.ErrInfo.Detail = "province_code not found"
event.ErrInfo.Raw = errors.New("province_code not found")
return pl.SetLogError(event, input)
}
}
}
// Validate Regency Code
if input.Regency_Code != nil {
dataRegency, err := ureg.ReadList(ereg.ReadListDto{FilterDto: ereg.FilterDto{Code: *input.Regency_Code}})
if err != nil {
return err
}
if list, ok := dataRegency.Data.([]ereg.ResponseDto); ok {
if len(list) < 1 {
event.ErrInfo.Detail = "regency_code not found"
event.ErrInfo.Raw = errors.New("regency_code not found")
return pl.SetLogError(event, input)
}
}
}
// Validate District Code
if input.District_Code != nil {
dataDistrict, err := udis.ReadList(edis.ReadListDto{FilterDto: edis.FilterDto{Code: *input.District_Code}})
if err != nil {
return err
}
if list, ok := dataDistrict.Data.([]edis.ResponseDto); ok {
if len(list) < 1 {
event.ErrInfo.Detail = "district_code not found"
event.ErrInfo.Raw = errors.New("district_code not found")
return pl.SetLogError(event, input)
}
}
}
// Validate Village Code
if input.Village_Code != nil {
dataVillage, err := uvil.ReadList(evil.ReadListDto{FilterDto: evil.FilterDto{Code: *input.Village_Code}})
if err != nil {
return err
}
if list, ok := dataVillage.Data.([]evil.ResponseDto); ok {
if len(list) < 1 {
event.ErrInfo.Detail = "village_code not found"
event.ErrInfo.Raw = errors.New("village_code not found")
return pl.SetLogError(event, input)
}
}
}
return
}
func ReadList(input eatr.ReadListDto) (*d.Data, error) {
var data *eatr.AmbulanceTransportReq
var dataList []eatr.AmbulanceTransportReq
var metaList *eatr.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 {
mwRunner := newMiddlewareRunner(&event, tx)
mwRunner.setMwType(pu.MWTPre)
// Run pre-middleware
if err := mwRunner.RunReadListMiddleware(readListPreMw, &input, data); err != nil {
return err
}
if dataList, metaList, err = ReadListData(input, &event, tx); err != nil {
return err
}
mwRunner.setMwType(pu.MWTPost)
// Run post-middleware
if err := mwRunner.RunReadListMiddleware(readListPostMw, &input, data); 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: eatr.ToResponseList(dataList),
}, nil
}
func ReadDetail(input eatr.ReadDetailDto) (*d.Data, error) {
var data *eatr.AmbulanceTransportReq
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 {
mwRunner := newMiddlewareRunner(&event, tx)
mwRunner.setMwType(pu.MWTPre)
// Run pre-middleware
if err := mwRunner.RunReadDetailMiddleware(readDetailPreMw, &input, data); err != nil {
return err
}
if data, err = ReadDetailData(input, &event, tx); err != nil {
return err
}
mwRunner.setMwType(pu.MWTPost)
// Run post-middleware
if err := mwRunner.RunReadDetailMiddleware(readDetailPostMw, &input, data); 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 eatr.UpdateDto) (*d.Data, error) {
rdDto := eatr.ReadDetailDto{Id: input.Id}
var data *eatr.AmbulanceTransportReq
var err error
event := pl.Event{
Feature: "Update",
Source: source,
}
// Start log
pl.SetLogInfo(&event, input, "started", "update")
// validate request code value
if err := validateRequestCode(&input.CreateDto, &event); err != nil {
return nil, err
}
// validateForeignKeys ensures that all foreign key references in the given input
// exist in their respective tables. It returns an error if any referenced record
// is missing or invalid.
if err := validateForeignKeys(input.CreateDto, &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
}
mwRunner := newMiddlewareRunner(&event, tx)
mwRunner.setMwType(pu.MWTPre)
// Run pre-middleware
if err := mwRunner.RunUpdateMiddleware(readDetailPreMw, &rdDto, data); err != nil {
return err
}
if err := UpdateData(input, data, &event, tx); err != nil {
return err
}
// Get Updated Data
if data, err = ReadDetailData(rdDto, &event, tx); err != nil {
return err
}
pl.SetLogInfo(&event, nil, "complete")
mwRunner.setMwType(pu.MWTPost)
// Run post-middleware
if err := mwRunner.RunUpdateMiddleware(readDetailPostMw, &rdDto, data); err != nil {
return err
}
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
}
func Delete(input eatr.DeleteDto) (*d.Data, error) {
rdDto := eatr.ReadDetailDto{Id: input.Id}
var data *eatr.AmbulanceTransportReq
var err error
event := pl.Event{
Feature: "Delete",
Source: source,
}
// Start log
pl.SetLogInfo(&event, input, "started", "delete")
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
}
mwRunner := newMiddlewareRunner(&event, tx)
mwRunner.setMwType(pu.MWTPre)
// Run pre-middleware
if err := mwRunner.RunDeleteMiddleware(readDetailPreMw, &rdDto, data); err != nil {
return err
}
if err := DeleteData(data, &event, tx); err != nil {
return err
}
mwRunner.setMwType(pu.MWTPost)
// Run post-middleware
if err := mwRunner.RunDeleteMiddleware(readDetailPostMw, &rdDto, data); err != nil {
return err
}
return nil
})
if err != nil {
return nil, err
}
return &d.Data{
Meta: d.IS{
"source": source,
"structure": "single-data",
"status": "deleted",
},
Data: data.ToResponse(),
}, nil
}