From da88637fe9ce23e618b3c3f19ecab82a4b518b00 Mon Sep 17 00:00:00 2001 From: dpurbosakti Date: Mon, 24 Nov 2025 12:21:17 +0700 Subject: [PATCH 01/38] feat (resume): wip --- assets/docs/resume.html | 432 ++++++++++++++++++ .../use-case/main-use-case/resume/case.go | 295 ++++++++++++ .../use-case/main-use-case/resume/helper.go | 22 + internal/use-case/main-use-case/resume/lib.go | 140 ++++++ .../main-use-case/resume/middleware-runner.go | 103 +++++ .../main-use-case/resume/middleware.go | 9 + .../use-case/main-use-case/resume/tycovar.go | 44 ++ .../main-use-case/unit-position/case.go | 2 +- 8 files changed, 1046 insertions(+), 1 deletion(-) create mode 100644 assets/docs/resume.html create mode 100644 internal/use-case/main-use-case/resume/case.go create mode 100644 internal/use-case/main-use-case/resume/helper.go create mode 100644 internal/use-case/main-use-case/resume/lib.go create mode 100644 internal/use-case/main-use-case/resume/middleware-runner.go create mode 100644 internal/use-case/main-use-case/resume/middleware.go create mode 100644 internal/use-case/main-use-case/resume/tycovar.go diff --git a/assets/docs/resume.html b/assets/docs/resume.html new file mode 100644 index 00000000..fdf47a2d --- /dev/null +++ b/assets/docs/resume.html @@ -0,0 +1,432 @@ + + + + + General Consent + + + + + + + + + + +
+ logo + +
+ PEMERINTAH PROVINSI JAWA TIMUR +
+
+ RUMAH SAKIT UMUM DAERAH Dr. SAIFUL ANWAR +
+
+ TERAKREDITASI KARS VERSI 2012 TINGKAT PARIPURNA +
+
+ Jl. Jaksa Agung Suprapto No. 2 MALANG 65111 +
+
Telp. (0341) 362101, Fax. (0341) 362110
+
Email: rsu-drsaifulanwar@jatimprov.go.id
+
Website: www.rsudsaifulanwar.jatimprov.go.id
+
+ logo +
+ +
+ +
+ IDENTITAS PASIEN +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ No. RM + : {{ .Repalcable }} + Kelas + : {{ .Repalcable }}
+ NIK + : {{ .Repalcable }} + Ruang/Klinik + : {{ .Repalcable }}
+ Nama + : {{ .Repalcable }} + DPJP + : {{ .Repalcable }}
+ Tempat/Tanggal Lahir + : {{ .Repalcable }}
+ Jenis Kelamin + : {{ .Repalcable }}
+ No. Telepon + : {{ .Repalcable }}
+ +
+

+ RESUME MEDIS +

+

Medical Discharge Summary

+ + +

(Diisi oleh Dokter Penanggung Jawab Pelayanan)

+ + + + + + + + + + + + + + + + + + + + + +
+ Tanggal Masuk + : {{ .Repalcable }}
+ Tanggal Keluar + : {{ .Repalcable }}
+ Diagnosis Masuk + : {{ .Repalcable }}
+ Diagnosis Keluar + : {{ .Repalcable }}
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ No + + Diagnosa + + Dasar Diagnosa + + Kode ICD-10 +
+ 1 + {{ .Repalcable }}{{ .Repalcable }}{{ .Repalcable }}
+ 2 + {{ .Repalcable }}{{ .Repalcable }}{{ .Repalcable }}
+ 3 + {{ .Repalcable }}{{ .Repalcable }}{{ .Repalcable }}
+ + + + + + + +

Kajian Awal Medis

+

(Diisi oleh Dokter Penanggung Jawab Pelayanan)

+ + + + + + + + + + + + + + + + + +
+ Keluhan Utama + : {{ .Repalcable }}
+ Riwayat Penyakit + : {{ .Repalcable }}
+ Pemeriksaan Fisik & Keadaan Umum + : {{ .Repalcable }}
+ +

Pemeriksaan Penunjang

+ + + + + + +
+ Pemeriksaan + : {{ .Repalcable }}
+ +

Tindakan Medis

+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ No + + Tindakan + + Dasar Tindakan + + Kode ICD 9-CM +
+ 1 + {{ .Repalcable }}{{ .Repalcable }}{{ .Repalcable }}
+ 2 + {{ .Repalcable }}{{ .Repalcable }}{{ .Repalcable }}
+ 3 + {{ .Repalcable }}{{ .Repalcable }}{{ .Repalcable }}
+ + + + + + + +
+ Keluhan Utama + : {{ .Repalcable }}
+ + + + + +

Konsultasi

+ + + + + + + + + + + + + + + + + + + + + +
+ No + + Konsultasi + + Jawaban Konsultasi +
+ 1 + {{ .Repalcable }}{{ .Repalcable }}
+ 2 + {{ .Repalcable }}{{ .Repalcable }}
+ 3 + {{ .Repalcable }}{{ .Repalcable }}
+ +

Terapi

+ + + + + + +
+ Alergi + : + Replace +
+ + + +

Obat yang diberikan

+ + + + + + + + + + + + + + + + + +
+ Terapi (Farmakologi & Non Farmakologi) Selawa Perawatan + + Terapi (Farmakologi & Non Farmakologi) Selawa Pulang +
{{ .Repalcable }}{{ .Repalcable }}
{{ .Repalcable }}{{ .Repalcable }}
{{ .Repalcable }}{{ .Repalcable }}
+ + + + + + +

Kondisi saat Pulang

+ + + + + + +
+ Keluhan Utama + : {{ .Repalcable }}
+ +
+ + + \ No newline at end of file diff --git a/internal/use-case/main-use-case/resume/case.go b/internal/use-case/main-use-case/resume/case.go new file mode 100644 index 00000000..79a2adf1 --- /dev/null +++ b/internal/use-case/main-use-case/resume/case.go @@ -0,0 +1,295 @@ +package resume + +import ( + "errors" + "strconv" + + // main entities + e "simrs-vx/internal/domain/main-entities/resume" + + ue "simrs-vx/internal/use-case/main-use-case/encounter" + + 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 = "resume" + +func Create(input e.CreateDto) (*d.Data, error) { + data := e.Resume{} + + event := pl.Event{ + Feature: "Create", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "create") + + 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 + } + + // check if encounter is done + if ue.IsDone(*input.Encounter_Id, &event, tx) { + return errors.New("encounter is already done") + } + + 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 ReadList(input e.ReadListDto) (*d.Data, error) { + var data *e.Resume + var dataList []e.Resume + 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 { + 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: e.ToResponseList(dataList), + }, nil +} + +func ReadDetail(input e.ReadDetailDto) (*d.Data, error) { + var data *e.Resume + 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 e.UpdateDto) (*d.Data, error) { + rdDto := e.ReadDetailDto{Id: input.Id} + var data *e.Resume + var err error + + event := pl.Event{ + Feature: "Update", + Source: source, + } + + // 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 + } + + mwRunner := newMiddlewareRunner(&event, tx) + mwRunner.setMwType(pu.MWTPre) + // Run pre-middleware + if err := mwRunner.RunUpdateMiddleware(readDetailPreMw, &rdDto, data); err != nil { + return err + } + + // check if encounter is done + if ue.IsDone(*input.Encounter_Id, &event, tx) { + return errors.New("encounter is already done") + } + + 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 e.DeleteDto) (*d.Data, error) { + rdDto := e.ReadDetailDto{Id: uint(input.Id)} + var data *e.Resume + 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 + +} diff --git a/internal/use-case/main-use-case/resume/helper.go b/internal/use-case/main-use-case/resume/helper.go new file mode 100644 index 00000000..18ff757c --- /dev/null +++ b/internal/use-case/main-use-case/resume/helper.go @@ -0,0 +1,22 @@ +/* +DESCRIPTION: +Any functions that are used internally by the use-case +*/ +package resume + +import ( + e "simrs-vx/internal/domain/main-entities/resume" +) + +func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Resume) { + var inputSrc *e.CreateDto + if inputT, ok := any(input).(*e.CreateDto); ok { + inputSrc = inputT + } else { + inputTemp := any(input).(*e.UpdateDto) + inputSrc = &inputTemp.CreateDto + } + + data.Encounter_Id = inputSrc.Encounter_Id + data.Value = inputSrc.Value +} diff --git a/internal/use-case/main-use-case/resume/lib.go b/internal/use-case/main-use-case/resume/lib.go new file mode 100644 index 00000000..16bb1afd --- /dev/null +++ b/internal/use-case/main-use-case/resume/lib.go @@ -0,0 +1,140 @@ +package resume + +import ( + "errors" + e "simrs-vx/internal/domain/main-entities/resume" + plh "simrs-vx/pkg/lib-helper" + pl "simrs-vx/pkg/logger" + pu "simrs-vx/pkg/use-case-helper" + + dg "github.com/karincake/apem/db-gorm-pg" + gh "github.com/karincake/getuk" + "gorm.io/gorm" +) + +func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Resume, error) { + pl.SetLogInfo(event, nil, "started", "DBCreate") + + data := e.Resume{} + setData(&input, &data) + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Create(&data).Error; err != nil { + return nil, plh.HandleCreateError(input, event, err) + } + + pl.SetLogInfo(event, nil, "complete") + return &data, nil +} + +func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Resume, *e.MetaDto, error) { + pl.SetLogInfo(event, input, "started", "DBReadList") + data := []e.Resume{} + pagination := gh.Pagination{} + count := int64(0) + meta := e.MetaDto{} + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + tx = tx. + Model(&e.Resume{}). + Scopes(gh.Preload(input.Includes)). + Scopes(gh.Filter(input.FilterDto)). + Count(&count). + Scopes(gh.Paginate(input, &pagination)). + Order("\"CreatedAt\" DESC") + + if err := tx.Find(&data).Error; err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return nil, &meta, nil + } + return nil, nil, plh.HandleListError(input, event, err) + } + + meta.Count = int(count) + meta.PageNumber = pagination.PageNumber + meta.PageSize = pagination.PageSize + + pl.SetLogInfo(event, nil, "complete") + return data, &meta, nil +} + +func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.Resume, error) { + pl.SetLogInfo(event, input, "started", "DBReadDetail") + data := e.Resume{} + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.First(&data, input.Id).Error; err != nil { + if processedErr := pu.HandleReadError(err, event, source, input.Id, data); processedErr != nil { + return nil, processedErr + } + } + + pl.SetLogInfo(event, nil, "complete") + return &data, nil +} + +func UpdateData(input e.UpdateDto, data *e.Resume, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, data, "started", "DBUpdate") + setData(&input, data) + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Save(&data).Error; err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-update-fail", + Detail: "Database update failed", + Raw: err, + } + return pl.SetLogError(event, input) + } + + pl.SetLogInfo(event, nil, "complete") + return nil +} + +func DeleteData(data *e.Resume, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, data, "started", "DBDelete") + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Delete(&data).Error; err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-delete-fail", + Detail: "Database delete failed", + Raw: err, + } + return pl.SetLogError(event, data) + } + + pl.SetLogInfo(event, nil, "complete") + return nil +} diff --git a/internal/use-case/main-use-case/resume/middleware-runner.go b/internal/use-case/main-use-case/resume/middleware-runner.go new file mode 100644 index 00000000..e7f4cade --- /dev/null +++ b/internal/use-case/main-use-case/resume/middleware-runner.go @@ -0,0 +1,103 @@ +package resume + +import ( + e "simrs-vx/internal/domain/main-entities/resume" + pl "simrs-vx/pkg/logger" + pu "simrs-vx/pkg/use-case-helper" + + "gorm.io/gorm" +) + +type middlewareRunner struct { + Event *pl.Event + Tx *gorm.DB + MwType pu.MWType +} + +// NewMiddlewareExecutor creates a new middleware executor +func newMiddlewareRunner(event *pl.Event, tx *gorm.DB) *middlewareRunner { + return &middlewareRunner{ + Event: event, + Tx: tx, + } +} + +// ExecuteCreateMiddleware executes create middleware +func (me *middlewareRunner) RunCreateMiddleware(middlewares []createMw, input *e.CreateDto, data *e.Resume) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) RunReadListMiddleware(middlewares []readListMw, input *e.ReadListDto, data *e.Resume) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) RunReadDetailMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.Resume) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) RunUpdateMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.Resume) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) RunDeleteMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.Resume) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) setMwType(mwType pu.MWType) { + me.MwType = mwType +} diff --git a/internal/use-case/main-use-case/resume/middleware.go b/internal/use-case/main-use-case/resume/middleware.go new file mode 100644 index 00000000..dc0aa8c9 --- /dev/null +++ b/internal/use-case/main-use-case/resume/middleware.go @@ -0,0 +1,9 @@ +package resume + +// example of middleware +// func init() { +// createPreMw = append(createPreMw, +// CreateMw{Name: "modif-input", Func: pm.ModifInput}, +// CreateMw{Name: "check-data", Func: pm.CheckData}, +// ) +// } diff --git a/internal/use-case/main-use-case/resume/tycovar.go b/internal/use-case/main-use-case/resume/tycovar.go new file mode 100644 index 00000000..13f36d2a --- /dev/null +++ b/internal/use-case/main-use-case/resume/tycovar.go @@ -0,0 +1,44 @@ +/* +DESCRIPTION: +A sample, part of the package that contains type, constants, and/or variables. + +In this sample it also provides type and variable regarding the needs of the +middleware to separate from main use-case which has the basic CRUD +functionality. The purpose of this is to make the code more maintainable. +*/ +package resume + +import ( + "gorm.io/gorm" + + e "simrs-vx/internal/domain/main-entities/resume" +) + +type createMw struct { + Name string + Func func(input *e.CreateDto, data *e.Resume, tx *gorm.DB) error +} + +type readListMw struct { + Name string + Func func(input *e.ReadListDto, data *e.Resume, tx *gorm.DB) error +} + +type readDetailMw struct { + Name string + Func func(input *e.ReadDetailDto, data *e.Resume, tx *gorm.DB) error +} + +type UpdateMw = readDetailMw +type DeleteMw = readDetailMw + +var createPreMw []createMw // preprocess middleware +var createPostMw []createMw // postprocess middleware +var readListPreMw []readListMw // .. +var readListPostMw []readListMw // .. +var readDetailPreMw []readDetailMw +var readDetailPostMw []readDetailMw +var updatePreMw []readDetailMw +var updatePostMw []readDetailMw +var deletePreMw []readDetailMw +var deletePostMw []readDetailMw diff --git a/internal/use-case/main-use-case/unit-position/case.go b/internal/use-case/main-use-case/unit-position/case.go index 47ea67cd..c472e90c 100644 --- a/internal/use-case/main-use-case/unit-position/case.go +++ b/internal/use-case/main-use-case/unit-position/case.go @@ -290,7 +290,7 @@ func Delete(input e.DeleteDto) (*d.Data, error) { func validateForeignKey(input e.CreateDto) error { // validate installation_id - if _, err := uu.ReadDetail(eu.ReadDetailDto{Code: &input.Code}); err != nil { + if _, err := uu.ReadDetail(eu.ReadDetailDto{Code: input.Unit_Code}); err != nil { return err } From 5322e986e4c7b4cbd19f03c686033915feaf1f86 Mon Sep 17 00:00:00 2001 From: dpurbosakti Date: Mon, 24 Nov 2025 17:13:40 +0700 Subject: [PATCH 02/38] feat (resume): add verify and validate, base value structure --- .../domain/main-entities/encounter/entity.go | 7 + internal/domain/main-entities/resume/dto.go | 119 ++++++++++++++++- .../domain/main-entities/resume/entity.go | 12 ++ .../interface/main-handler/main-handler.go | 10 ++ .../interface/main-handler/resume/handler.go | 121 ++++++++++++++++++ .../use-case/main-use-case/resume/case.go | 97 ++++++++++++++ .../use-case/main-use-case/resume/helper.go | 2 + 7 files changed, 362 insertions(+), 6 deletions(-) create mode 100644 internal/interface/main-handler/resume/handler.go diff --git a/internal/domain/main-entities/encounter/entity.go b/internal/domain/main-entities/encounter/entity.go index 61496f9e..f8f0c66f 100644 --- a/internal/domain/main-entities/encounter/entity.go +++ b/internal/domain/main-entities/encounter/entity.go @@ -82,3 +82,10 @@ type Encounter struct { func (d Encounter) IsDone() bool { return d.Status_Code == erc.DSCDone } + +func (d Encounter) IsSameResponsibleDoctor(input *string) bool { + if input == nil { + return false + } + return d.Responsible_Doctor_Code == input +} diff --git a/internal/domain/main-entities/resume/dto.go b/internal/domain/main-entities/resume/dto.go index ea9485d7..bf505d20 100644 --- a/internal/domain/main-entities/resume/dto.go +++ b/internal/domain/main-entities/resume/dto.go @@ -2,11 +2,19 @@ package resume import ( ecore "simrs-vx/internal/domain/base-entities/core" + "time" + + erc "simrs-vx/internal/domain/references/common" + + pa "simrs-vx/internal/lib/auth" ) type CreateDto struct { - Encounter_Id *uint `json:"encounter_id"` - Value *string `json:"value"` + Encounter_Id *uint `json:"encounter_id"` + Value *string `json:"value"` + Status_Code erc.DataVerifiedCode `json:"status_code"` + + pa.AuthInfo } type ReadListDto struct { @@ -16,7 +24,8 @@ type ReadListDto struct { } type FilterDto struct { - Encounter_Id *uint `json:"encounter-id"` + Encounter_Id *uint `json:"encounter-id"` + Doctor_Code *string `json:"doctor-code"` } type ReadDetailDto struct { @@ -30,6 +39,8 @@ type UpdateDto struct { type DeleteDto struct { Id uint `json:"id"` + + pa.AuthInfo } type MetaDto struct { @@ -40,16 +51,20 @@ type MetaDto struct { type ResponseDto struct { ecore.Main - Encounter_Id *uint `json:"encounter_id"` - Value *string `json:"value"` - FileUrl *string `json:"fileUrl"` + Encounter_Id *uint `json:"encounter_id"` + Doctor_Code *string `json:"doctor_code"` + Value *string `json:"value"` + FileUrl *string `json:"fileUrl"` + Status_Code erc.DataVerifiedCode `json:"status_code"` } func (d Resume) ToResponse() ResponseDto { resp := ResponseDto{ Encounter_Id: d.Encounter_Id, + Doctor_Code: d.Doctor_Code, Value: d.Value, FileUrl: d.FileUrl, + Status_Code: d.Status_Code, } resp.Main = d.Main return resp @@ -62,3 +77,95 @@ func ToResponseList(data []Resume) []ResponseDto { } return resp } + +// ValueDto is for resume value +type ValueDto struct { + Assessment Assessment `json:"assessment"` + Diagnosis Diagnosis `json:"diagnosis"` + Action Action `json:"action"` + Consultation Consultation `json:"consultation"` + Supporting SupportingExaminations `json:"supporting"` + Pharmacy PharmacyData `json:"pharmacy"` + Discharge DischargeCondition `json:"discharge"` + National NationalProgram `json:"national"` + Management Management `json:"management"` +} + +type Assessment struct { + StartedAt *time.Time `json:"startedAt` + FinishedAt *time.Time `json:"finishedAt` + Doctor_Code string `json:"doctor_code` + DiagnosisIn string `json:"diagnosesIn` + AmbulatoryIndication string `json:"ambulatoryIndication"` + MainComplaint string `json:"mainComplaint"` + PhysicalExamination string `json:"physicalExamination"` + MedicalHistory string `json:"medicalHistory"` + MedicalDiagnosis string `json:"medicalDiagnosis"` +} + +type Diagnosis struct { + PrimaryDiagnosis DiagnosisEntry `json:"primaryDiagnosis"` + SecondaryDiagnoses []DiagnosisEntry `json:"secondaryDiagnoses"` +} + +type DiagnosisEntry struct { + Diagnosis string `json:"diagnosis"` + ICD10 string `json:"icd_10"` + Basis string `json:"basis"` // Clinical basis of diagnosis / dasar diagnosa +} + +type Action struct { + PrimaryAction ActionEntry `json:"primaryAction"` + AdditionalActions []ActionEntry `json:"additionalActions"` + MedicalActions string `json:"medicalActions"` // free-text: "Tindakan Medis" +} + +type ActionEntry struct { + Action string `json:"action"` // Tindakan + ICD9 string `json:"icd_9"` // ICD-9 + Basis string `json:"basis"` // Dasar Tindakan +} + +type Consultation struct { + Consultations []ConsultationEntry `json:"consultations"` +} + +type ConsultationEntry struct { + Consultation string `json:"consultation"` // Konsultasi + ConsultationAnswer string `json:"consultationAnswer"` // Jawaban Konsultasi +} + +type SupportingExaminations struct { + Notes string `json:"notes"` // Free-text list of lab/imaging results +} + +type PharmacyData struct { + AllergySpecialConditions string `json:"allergySpecialConditions"` // Kelainan Khusus Alergi + OtherConditions string `json:"otherConditions"` // Kelainan Lain + TherapyDuringCare string `json:"therapyDuringCare"` // Terapi selama dirawat + TherapyAtDischarge string `json:"therapyAtDischarge"` // Terapi waktu pulang + FollowUpInstructions string `json:"followUpInstructions"` // Edukasi / Anjuran / Follow-up +} + +type DischargeCondition struct { + BloodPressureSystolic float64 `json:"bloodPressureSystolic"` // Tekanan Darah Sistol (mmHg) + BloodPressureDiastolic float64 `json:"bloodPressureDiastolic"` // Tekanan Darah Diastol (mmHg) + RespirationRate float64 `json:"respirationRate"` // Pernafasan (kali/menit) + HeartRate float64 `json:"heartRate"` // Denyut Jantung (kali/menit) + BodyTemperature float64 `json:"bodyTemperature"` // Suhu Tubuh (°C) + + ConsciousnessLevel string `json:"consciousnessLevel"` // Tingkat Kesadaran + PainScale int `json:"painScale"` // Skala Nyeri (0–10) +} + +type NationalProgram struct { + ProgramService string `json:"programService"` // e.g. "Antenatal Care" + ProgramServiceStatus string `json:"programServiceStatus"` // e.g. "Suspected" +} + +type Management struct { + NationalProgramService string `json:"nationalProgramService"` // e.g. selected program + FollowUpManagement string `json:"followUpManagement"` // e.g. further management plan + ConditionOnDischarge string `json:"conditionOnDischarge"` // e.g. "Stable" + DischargeMethod string `json:"dischargeMethod"` // e.g. "Discharged with Doctor's Approval" +} diff --git a/internal/domain/main-entities/resume/entity.go b/internal/domain/main-entities/resume/entity.go index 70050166..93a1d8cd 100644 --- a/internal/domain/main-entities/resume/entity.go +++ b/internal/domain/main-entities/resume/entity.go @@ -16,3 +16,15 @@ type Resume struct { FileUrl *string `json:"fileUrl" gorm:"size:1024"` Status_Code erc.DataVerifiedCode `json:"status_code" gorm:"not null;size:10"` } + +func (d Resume) IsNew() bool { + return d.Status_Code == erc.DVCNew +} + +func (d Resume) IsVerified() bool { + return d.Status_Code == erc.DVCVerified +} + +func (d Resume) IsValidated() bool { + return d.Status_Code == erc.DVCValidated +} diff --git a/internal/interface/main-handler/main-handler.go b/internal/interface/main-handler/main-handler.go index 56811194..1dc4c893 100644 --- a/internal/interface/main-handler/main-handler.go +++ b/internal/interface/main-handler/main-handler.go @@ -34,6 +34,7 @@ import ( prescription "simrs-vx/internal/interface/main-handler/prescription" prescriptionitem "simrs-vx/internal/interface/main-handler/prescription-item" responsibledoctorhist "simrs-vx/internal/interface/main-handler/responsible-doctor-hist" + resume "simrs-vx/internal/interface/main-handler/resume" sbar "simrs-vx/internal/interface/main-handler/sbar" soapi "simrs-vx/internal/interface/main-handler/soapi" uploadfile "simrs-vx/internal/interface/main-handler/upload-file" @@ -288,6 +289,15 @@ func SetRoutes() http.Handler { hc.RegCrud(r, "/v1/encounter-document", encounterdocument.O) hc.RegCrud(r, "/v1/general-consent", generalconsent.O) r.HandleFunc("POST /v1/generate-file", generatefile.Generate) + hk.GroupRoutes("/v1/resume", r, auth.GuardMW, hk.MapHandlerFunc{ + "POST /": resume.Create, + "GET /": resume.GetList, + "GET /{id}": resume.GetDetail, + "PATCH /{id}": resume.Update, + "DELETE /{id}": resume.Delete, + "PATCH /{id}/verify": resume.Verify, + "PATCH /{id}/validate": resume.Validate, + }) /******************** actor ********************/ hc.RegCrud(r, "/v1/person", person.O) diff --git a/internal/interface/main-handler/resume/handler.go b/internal/interface/main-handler/resume/handler.go new file mode 100644 index 00000000..5574bc7a --- /dev/null +++ b/internal/interface/main-handler/resume/handler.go @@ -0,0 +1,121 @@ +package resume + +import ( + "net/http" + + d "github.com/karincake/dodol" + rw "github.com/karincake/risoles" + sf "github.com/karincake/semprit" + + // ua "github.com/karincake/tumpeng/auth/svc" + + e "simrs-vx/internal/domain/main-entities/resume" + u "simrs-vx/internal/use-case/main-use-case/resume" + + erc "simrs-vx/internal/domain/references/common" + + pa "simrs-vx/internal/lib/auth" +) + +func Create(w http.ResponseWriter, r *http.Request) { + authInfo, err := pa.GetAuthInfo(r) + if err != nil { + rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil) + } + dto := e.CreateDto{} + if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { + return + } + + dto.AuthInfo = *authInfo + res, err := u.Create(dto) + rw.DataResponse(w, res, err) +} + +func GetList(w http.ResponseWriter, r *http.Request) { + dto := e.ReadListDto{} + sf.UrlQueryParam(&dto, *r.URL) + res, err := u.ReadList(dto) + rw.DataResponse(w, res, err) +} + +func GetDetail(w http.ResponseWriter, r *http.Request) { + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id <= 0 { + return + } + dto := e.ReadDetailDto{} + sf.UrlQueryParam(&dto, *r.URL) + dto.Id = uint(id) + res, err := u.ReadDetail(dto) + rw.DataResponse(w, res, err) +} + +func Update(w http.ResponseWriter, r *http.Request) { + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id <= 0 { + return + } + + dto := e.UpdateDto{} + if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { + return + } + dto.Id = uint(id) + res, err := u.Update(dto) + rw.DataResponse(w, res, err) +} + +func Delete(w http.ResponseWriter, r *http.Request) { + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id <= 0 { + return + } + + dto := e.DeleteDto{} + dto.Id = uint(id) + res, err := u.Delete(dto) + rw.DataResponse(w, res, err) +} + +func Verify(w http.ResponseWriter, r *http.Request) { + authInfo, err := pa.GetAuthInfo(r) + if err != nil { + rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil) + } + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id <= 0 { + return + } + + dto := e.UpdateDto{} + if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { + return + } + dto.Id = uint(id) + dto.Status_Code = erc.DVCVerified + dto.AuthInfo = *authInfo + res, err := u.UpdateStatusCode(dto) + rw.DataResponse(w, res, err) +} + +func Validate(w http.ResponseWriter, r *http.Request) { + authInfo, err := pa.GetAuthInfo(r) + if err != nil { + rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil) + } + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id <= 0 { + return + } + + dto := e.UpdateDto{} + if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { + return + } + dto.Id = uint(id) + dto.Status_Code = erc.DVCValidated + dto.AuthInfo = *authInfo + res, err := u.UpdateStatusCode(dto) + rw.DataResponse(w, res, err) +} diff --git a/internal/use-case/main-use-case/resume/case.go b/internal/use-case/main-use-case/resume/case.go index 79a2adf1..cbc472f9 100644 --- a/internal/use-case/main-use-case/resume/case.go +++ b/internal/use-case/main-use-case/resume/case.go @@ -4,7 +4,10 @@ import ( "errors" "strconv" + erc "simrs-vx/internal/domain/references/common" + // main entities + ee "simrs-vx/internal/domain/main-entities/encounter" e "simrs-vx/internal/domain/main-entities/resume" ue "simrs-vx/internal/use-case/main-use-case/encounter" @@ -31,6 +34,10 @@ func Create(input e.CreateDto) (*d.Data, error) { pl.SetLogInfo(&event, input, "started", "create") err := dg.I.Transaction(func(tx *gorm.DB) error { + if !input.AuthInfo.IsDoctor() { + return errors.New("user is not a doctor") + } + mwRunner := newMiddlewareRunner(&event, tx) mwRunner.setMwType(pu.MWTPre) // Run pre-middleware @@ -43,6 +50,7 @@ func Create(input e.CreateDto) (*d.Data, error) { return errors.New("encounter is already done") } + input.Status_Code = erc.DVCNew if resData, err := CreateData(input, &event, tx); err != nil { return err } else { @@ -188,6 +196,10 @@ func Update(input e.UpdateDto) (*d.Data, error) { pl.SetLogInfo(&event, input, "started", "update") err = dg.I.Transaction(func(tx *gorm.DB) error { + if !input.AuthInfo.IsDoctor() { + return errors.New("user is not a doctor") + } + pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail") if data, err = ReadDetailData(rdDto, &event, tx); err != nil { return err @@ -254,6 +266,10 @@ func Delete(input e.DeleteDto) (*d.Data, error) { pl.SetLogInfo(&event, input, "started", "delete") err = dg.I.Transaction(func(tx *gorm.DB) error { + if !input.AuthInfo.IsDoctor() { + return errors.New("user is not a doctor") + } + pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail") if data, err = ReadDetailData(rdDto, &event, tx); err != nil { return err @@ -293,3 +309,84 @@ func Delete(input e.DeleteDto) (*d.Data, error) { }, nil } + +func UpdateStatusCode(input e.UpdateDto) (*d.Data, error) { + rdDto := e.ReadDetailDto{Id: input.Id} + var data *e.Resume + var err error + + event := pl.Event{ + Feature: "UpdateStatusCode", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "updateStatusCode") + + err = dg.I.Transaction(func(tx *gorm.DB) error { + if !input.AuthInfo.IsDoctor() { + return errors.New("user is not a doctor") + } + + pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail") + if data, err = ReadDetailData(rdDto, &event, tx); err != nil { + return err + } + + enc, err := ue.ReadDetailData(ee.ReadDetailDto{Id: uint16(*data.Encounter_Id)}, &event, tx) + if err != nil { + return err + } + + // check if encounter is done + if enc.IsDone() { + return errors.New("encounter is already done") + } + + switch input.Status_Code { + case erc.DVCValidated: + if !enc.IsSameResponsibleDoctor(input.AuthInfo.Doctor_Code) { + return errors.New("validation doctor is not the same as encounter responsible doctor") + } + + if data.IsNew() { + return errors.New("resume need to be verified first") + } + if data.IsValidated() { + return errors.New("resume already validated") + } + data.Status_Code = erc.DVCValidated + err = tx.Save(&data).Error + if err != nil { + return err + } + case erc.DVCVerified: + if data.IsValidated() { + return errors.New("resume already validated") + } + if data.IsVerified() { + return errors.New("resume already verified") + } + data.Status_Code = erc.DVCVerified + err = tx.Save(&data).Error + if 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 +} diff --git a/internal/use-case/main-use-case/resume/helper.go b/internal/use-case/main-use-case/resume/helper.go index 18ff757c..edd45222 100644 --- a/internal/use-case/main-use-case/resume/helper.go +++ b/internal/use-case/main-use-case/resume/helper.go @@ -18,5 +18,7 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Resume) { } data.Encounter_Id = inputSrc.Encounter_Id + data.Doctor_Code = inputSrc.AuthInfo.Doctor_Code data.Value = inputSrc.Value + data.Status_Code = inputSrc.Status_Code } From 63f9d5512bd4760e2687518a3cffbcd21f53bd0a Mon Sep 17 00:00:00 2001 From: dpurbosakti Date: Tue, 25 Nov 2025 14:31:03 +0700 Subject: [PATCH 03/38] resume wip --- assets/docs/resume.html | 8 +++--- .../main-use-case/generate-file/tycovar.go | 27 +++++++++++++++++++ 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/assets/docs/resume.html b/assets/docs/resume.html index fdf47a2d..8cdca672 100644 --- a/assets/docs/resume.html +++ b/assets/docs/resume.html @@ -82,7 +82,7 @@ : {{ .Repalcable }} - Kelas + Ruang/Klinik : {{ .Repalcable }} @@ -94,7 +94,7 @@ : {{ .Repalcable }} - Ruang/Klinik + Kelas : {{ .Repalcable }} @@ -112,7 +112,7 @@ {{ .Repalcable }} - + @@ -324,7 +324,7 @@ diff --git a/internal/use-case/main-use-case/generate-file/tycovar.go b/internal/use-case/main-use-case/generate-file/tycovar.go index 2f6a0ced..2bbe9fbf 100644 --- a/internal/use-case/main-use-case/generate-file/tycovar.go +++ b/internal/use-case/main-use-case/generate-file/tycovar.go @@ -7,6 +7,8 @@ import ( erc "simrs-vx/internal/domain/references/common" ere "simrs-vx/internal/domain/references/encounter" + er "simrs-vx/internal/domain/main-entities/resume" + pu "simrs-vx/pkg/use-case-helper" ) @@ -32,6 +34,31 @@ type ControlLetterPDF struct { PrintDate string } +type ResumePDF struct { + MedicalRecord string + NIK string + Name string + BirthPlaceDate string + Gender string + Phone string + Class string + Unit string + Doctor_Name string + StartedDate string + FinishedDate string + DiagnosisIn string + DiagnosisOut string + Diagnosis []er.DiagnosisEntry + MainComplaint string + MedicalHistory string + PhysicalExamination string + SupportingExamination string + MedicalActions []er.ActionEntry + MedicalAction string + Consultations []er.ConsultationEntry + Allergy string +} + type GenerateDto struct { EntityType_Code ere.EntityTypeCode `json:"entityType_code" validate:"required"` Ref_Id *string `json:"ref_id" validate:"required"` From 8cf750c63f651cfd62e53b2f16d494e5aee73b1c Mon Sep 17 00:00:00 2001 From: dpurbosakti Date: Tue, 25 Nov 2025 15:52:07 +0700 Subject: [PATCH 04/38] wip --- .../domain/main-entities/person/entity.go | 60 ++++++ internal/domain/main-entities/resume/dto.go | 3 +- .../main-use-case/generate-file/case.go | 128 +---------- .../main-use-case/generate-file/helper.go | 203 ++++++++++++++++++ .../main-use-case/generate-file/tycovar.go | 4 +- internal/use-case/main-use-case/resume/lib.go | 2 +- pkg/conv-helper/conv-helper.go | 26 ++- pkg/use-case-helper/use-case-helper.go | 10 + 8 files changed, 305 insertions(+), 131 deletions(-) diff --git a/internal/domain/main-entities/person/entity.go b/internal/domain/main-entities/person/entity.go index 8d7f79a8..3c7d8629 100644 --- a/internal/domain/main-entities/person/entity.go +++ b/internal/domain/main-entities/person/entity.go @@ -10,6 +10,7 @@ import ( epi "simrs-vx/internal/domain/main-entities/person-insurance" epr "simrs-vx/internal/domain/main-entities/person-relative" er "simrs-vx/internal/domain/main-entities/regency" + "strings" erp "simrs-vx/internal/domain/references/person" @@ -58,3 +59,62 @@ func (d Person) IsSameResidentIdentityNumber(input *string) bool { } return d.ResidentIdentityNumber == input } + +func (d Person) GenderString() string { + if d.Gender_Code == nil { + return "" + } + switch *d.Gender_Code { + case erp.GCMale: + return "Laki-laki(L)" + case erp.GCFemale: + return "Perempuan(P)" + default: + return "" + } +} + +func (d Person) GetPhoneNumber() string { + if d.Contacts == nil { + return "" + } + for _, c := range *d.Contacts { + if c.Type_Code == erp.CTPhone || c.Type_Code == erp.CTMPhone { + return c.Value + } + } + return "" +} + +func (d Person) FullName() string { + name := strings.TrimSpace(d.Name) + if name == "" { + return "" + } + + parts := []string{} + + // Front title (dr., drs., etc) + if d.FrontTitle != nil { + ft := strings.TrimSpace(*d.FrontTitle) + if ft != "" { + parts = append(parts, ft) + } + } + + // Name (always included) + parts = append(parts, name) + + // Join front title + name + full := strings.Join(parts, " ") + + // End title → attach with comma + if d.EndTitle != nil { + et := strings.TrimSpace(*d.EndTitle) + if et != "" { + full = full + ", " + et + } + } + + return full +} diff --git a/internal/domain/main-entities/resume/dto.go b/internal/domain/main-entities/resume/dto.go index bf505d20..884b8e32 100644 --- a/internal/domain/main-entities/resume/dto.go +++ b/internal/domain/main-entities/resume/dto.go @@ -29,7 +29,8 @@ type FilterDto struct { } type ReadDetailDto struct { - Id uint `json:"id"` + Id uint `json:"id"` + Includes string `json:"includes"` } type UpdateDto struct { diff --git a/internal/use-case/main-use-case/generate-file/case.go b/internal/use-case/main-use-case/generate-file/case.go index 39cb2f02..7c657640 100644 --- a/internal/use-case/main-use-case/generate-file/case.go +++ b/internal/use-case/main-use-case/generate-file/case.go @@ -1,26 +1,14 @@ package generatefile import ( - "encoding/json" "errors" - evs "simrs-vx/internal/domain/bpjs-entities/vclaim-sep" - evscl "simrs-vx/internal/domain/bpjs-entities/vclaim-sep-control-letter" - egc "simrs-vx/internal/domain/main-entities/general-consent" - - uvs "simrs-vx/internal/use-case/bpjs-use-case/vclaim-sep" - uvscl "simrs-vx/internal/use-case/bpjs-use-case/vclaim-sep-control-letter" - ugc "simrs-vx/internal/use-case/main-use-case/general-consent" - - pc "simrs-vx/pkg/conv-helper" 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" ere "simrs-vx/internal/domain/references/encounter" ) @@ -32,133 +20,37 @@ func Generate(input GenerateDto) (*d.Data, error) { Source: source, } - var response ResponseDto + var ( + response *ResponseDto + err error + ) // Start log pl.SetLogInfo(&event, input, "started", "create") - err := dg.I.Transaction(func(tx *gorm.DB) error { + err = dg.I.Transaction(func(tx *gorm.DB) error { switch input.Type_Code { // general-consent case ere.DTCGC: - // get value from general consent by ref_id - gc, err := ugc.ReadDetailData(egc.ReadDetailDto{Id: uint(*pc.StringToUint64(*input.Ref_Id))}, &event) + response, err = generateGC(input, event, tx) if err != nil { return err } - if gc.FileUrl != nil { - if err := removeFile(string(input.EntityType_Code), *gc.FileUrl); err != nil { - return err - } - } - - // map template data - templateData := GeneralConsentPDF{} - if gc.Value != nil { - err := json.Unmarshal([]byte(*gc.Value), &templateData) - if err != nil { - event.ErrInfo = pl.ErrorInfo{ - Code: "data-unmarshal-fail", - Detail: err.Error(), - Raw: err, - } - return err - } - } else { - return errors.New("no value in this general consent") - } - - input.FormatType = erc.DFTCPDF - input.TemplateName = TDNGC - input.Encounter_Id = gc.Encounter_Id - templateData.Date = pu.FormatIndonesianDate(gc.CreatedAt) - - // generate file - urlPub, err := generateFile(input, templateData) - if err != nil { - return err - } - - gc.FileUrl = &urlPub - if err := dg.I.Save(&gc).Error; err != nil { - return err - } - - response = ResponseDto{ - FileUrl: urlPub, - } - // control-letter case ere.DTCVSCL: - // get value from control letter by ref_id - cl, err := uvscl.ReadDetailData(evscl.ReadDetailDto{Number: input.Ref_Id}, &event) - if err != nil { - if !pu.IsDataNotFoundError(err) { - return err - } - } - - if cl != nil && cl.FileUrl != nil { - if err := removeFile(string(input.EntityType_Code), *cl.FileUrl); err != nil { - return err - } - } - - // map template data - clData := VclaimControlLetter{} - if input.Data != nil { - err := json.Unmarshal([]byte(*input.Data), &clData) - if err != nil { - event.ErrInfo = pl.ErrorInfo{ - Code: "data-unmarshal-fail", - Detail: err.Error(), - Raw: err, - } - return err - } - } else { - return errors.New("there is no data to be used") - } - - if cl == nil { - createCL := evscl.CreateDto{ - VclaimSep_Number: &clData.VclaimSep.Number, - Number: &clData.Number, - Value: input.Data, - } - if cl, err = uvscl.CreateData(createCL, &event, tx); err != nil { - return err - } - - } - // get encounter id by vclaim sep number - vs, err := uvs.ReadDetailData(evs.ReadDetailDto{Number: &clData.VclaimSep.Number}, &event) + response, err = generateCL(input, event, tx) if err != nil { return err } - input.FormatType = erc.DFTCPDF - input.TemplateName = TDNCL - input.Encounter_Id = vs.Encounter_Id - input.UseA5Lanscape = true - - templateData := clData.generateTemplateData() - // generate file - urlPub, err := generateFile(input, templateData) + // resume + case ere.DTCResume: + response, err = generateResume(input, event, tx) if err != nil { return err } - cl.FileUrl = &urlPub - if err := tx.Save(&cl).Error; err != nil { - return err - } - - response = ResponseDto{ - FileUrl: urlPub, - } - default: return errors.New("invalid type code") } diff --git a/internal/use-case/main-use-case/generate-file/helper.go b/internal/use-case/main-use-case/generate-file/helper.go index 8cd3543f..e42fc13e 100644 --- a/internal/use-case/main-use-case/generate-file/helper.go +++ b/internal/use-case/main-use-case/generate-file/helper.go @@ -1,19 +1,36 @@ package generatefile import ( + "encoding/json" "errors" "fmt" "mime" "path/filepath" "time" + evs "simrs-vx/internal/domain/bpjs-entities/vclaim-sep" + evscl "simrs-vx/internal/domain/bpjs-entities/vclaim-sep-control-letter" + ee "simrs-vx/internal/domain/main-entities/encounter" + egc "simrs-vx/internal/domain/main-entities/general-consent" + er "simrs-vx/internal/domain/main-entities/resume" + + uvs "simrs-vx/internal/use-case/bpjs-use-case/vclaim-sep" + uvscl "simrs-vx/internal/use-case/bpjs-use-case/vclaim-sep-control-letter" + ue "simrs-vx/internal/use-case/main-use-case/encounter" + ugc "simrs-vx/internal/use-case/main-use-case/general-consent" + ur "simrs-vx/internal/use-case/main-use-case/resume" + erc "simrs-vx/internal/domain/references/common" docscfg "simrs-vx/internal/infra/docs-cfg" + pc "simrs-vx/pkg/conv-helper" pf "simrs-vx/pkg/file-helper" + pl "simrs-vx/pkg/logger" pm "simrs-vx/pkg/minio-helper" pp "simrs-vx/pkg/pdf-helper" pu "simrs-vx/pkg/use-case-helper" + + "gorm.io/gorm" ) // generate temporary file, upload to minio, generate public url, delete temporary file @@ -93,3 +110,189 @@ func removeFile(bucket, fileUrl string) error { } return nil } + +// generate general consent +func generateGC(input GenerateDto, event pl.Event, tx *gorm.DB) (*ResponseDto, error) { + // get value from general consent by ref_id + gc, err := ugc.ReadDetailData(egc.ReadDetailDto{Id: uint(*pc.StringToUint64(*input.Ref_Id))}, &event) + if err != nil { + return nil, err + } + + if gc.FileUrl != nil { + if err := removeFile(string(input.EntityType_Code), *gc.FileUrl); err != nil { + return nil, err + } + } + + // map template data + templateData := GeneralConsentPDF{} + if gc.Value != nil { + err := json.Unmarshal([]byte(*gc.Value), &templateData) + if err != nil { + event.ErrInfo = pl.ErrorInfo{ + Code: "data-unmarshal-fail", + Detail: err.Error(), + Raw: err, + } + return nil, err + } + } else { + return nil, errors.New("no value in this general consent") + } + + input.FormatType = erc.DFTCPDF + input.TemplateName = TDNGC + input.Encounter_Id = gc.Encounter_Id + templateData.Date = pu.FormatIndonesianDate(gc.CreatedAt) + + // generate file + urlPub, err := generateFile(input, templateData) + if err != nil { + return nil, err + } + + gc.FileUrl = &urlPub + if err := tx.Save(&gc).Error; err != nil { + return nil, err + } + + response := ResponseDto{ + FileUrl: urlPub, + } + + return &response, nil +} + +func generateCL(input GenerateDto, event pl.Event, tx *gorm.DB) (*ResponseDto, error) { + // get value from control letter by ref_id + cl, err := uvscl.ReadDetailData(evscl.ReadDetailDto{Number: input.Ref_Id}, &event) + if err != nil { + if !pu.IsDataNotFoundError(err) { + return nil, err + } + } + + if cl != nil && cl.FileUrl != nil { + if err := removeFile(string(input.EntityType_Code), *cl.FileUrl); err != nil { + return nil, err + } + } + + // map template data + clData := VclaimControlLetter{} + if input.Data != nil { + err := json.Unmarshal([]byte(*input.Data), &clData) + if err != nil { + event.ErrInfo = pl.ErrorInfo{ + Code: "data-unmarshal-fail", + Detail: err.Error(), + Raw: err, + } + return nil, err + } + } else { + return nil, errors.New("there is no data to be used") + } + + if cl == nil { + createCL := evscl.CreateDto{ + VclaimSep_Number: &clData.VclaimSep.Number, + Number: &clData.Number, + Value: input.Data, + } + if cl, err = uvscl.CreateData(createCL, &event, tx); err != nil { + return nil, err + } + + } + // get encounter id by vclaim sep number + vs, err := uvs.ReadDetailData(evs.ReadDetailDto{Number: &clData.VclaimSep.Number}, &event) + if err != nil { + return nil, err + } + + input.FormatType = erc.DFTCPDF + input.TemplateName = TDNCL + input.Encounter_Id = vs.Encounter_Id + input.UseA5Lanscape = true + + templateData := clData.generateTemplateData() + // generate file + urlPub, err := generateFile(input, templateData) + if err != nil { + return nil, err + } + + cl.FileUrl = &urlPub + if err := tx.Save(&cl).Error; err != nil { + return nil, err + } + + response := ResponseDto{ + FileUrl: urlPub, + } + + return &response, nil +} + +func generateResume(input GenerateDto, event pl.Event, tx *gorm.DB) (*ResponseDto, error) { + // get value from resume by ref_id + includes := "Doctor.Employee.Person" + r, err := ur.ReadDetailData(er.ReadDetailDto{Id: uint(*pc.StringToUint64(*input.Ref_Id)), Includes: includes}, &event) + if err != nil { + return nil, err + } + + if r.FileUrl != nil { + if err := removeFile(string(input.EntityType_Code), *r.FileUrl); err != nil { + return nil, err + } + } + + response := ResponseDto{ + FileUrl: "", + } + + return &response, nil +} + +func generateResumeTemplateData(resume er.Resume, event pl.Event, tx *gorm.DB) (*ResumePDF, error) { + // get encounter + includes := "Patient,Patient.Person,Patient.Person.BirthRegency,Patient.Person.Contacts" + encounter, err := ue.ReadDetailData(ee.ReadDetailDto{Id: uint16(*resume.Encounter_Id), Includes: includes}, &event) + if err != nil { + return nil, err + } + fmt.Println(encounter) + + // map template data + rData := er.ValueDto{} + if resume.Value != nil { + err := json.Unmarshal([]byte(*resume.Value), &rData) + if err != nil { + event.ErrInfo = pl.ErrorInfo{ + Code: "data-unmarshal-fail", + Detail: err.Error(), + Raw: err, + } + return nil, err + } + } else { + return nil, errors.New("there is no data to be used") + } + templateData := ResumePDF{} + templateData.MedicalRecord = *encounter.Patient.Number + templateData.NIK = *encounter.Patient.Person.ResidentIdentityNumber + templateData.Name = encounter.Patient.Person.Name + templateData.BirthPlaceDate = pu.FormatPlaceAndDate(encounter.Patient.Person.BirthRegency.Name, *encounter.Patient.Person.BirthDate) + templateData.Gender = encounter.Patient.Person.GenderString() + templateData.Phone = encounter.Patient.Person.GetPhoneNumber() + // templateData.Class = get from vclaim sep eg. III + // templateData.Unit = get from vclaim sep eg. R.KERINCI - KLS 3 + templateData.Doctor_Name = resume.Doctor.Employee.Person.FullName() + templateData.StartedAt = *pc.TimeToStringWithFormat(encounter.StartedAt, "") + templateData.FinishedAt = *pc.TimeToStringWithFormat(encounter.FinishedAt, "") + + return &templateData, nil +} diff --git a/internal/use-case/main-use-case/generate-file/tycovar.go b/internal/use-case/main-use-case/generate-file/tycovar.go index 2bbe9fbf..1dee32ff 100644 --- a/internal/use-case/main-use-case/generate-file/tycovar.go +++ b/internal/use-case/main-use-case/generate-file/tycovar.go @@ -44,8 +44,8 @@ type ResumePDF struct { Class string Unit string Doctor_Name string - StartedDate string - FinishedDate string + StartedAt string + FinishedAt string DiagnosisIn string DiagnosisOut string Diagnosis []er.DiagnosisEntry diff --git a/internal/use-case/main-use-case/resume/lib.go b/internal/use-case/main-use-case/resume/lib.go index 16bb1afd..02a2e27a 100644 --- a/internal/use-case/main-use-case/resume/lib.go +++ b/internal/use-case/main-use-case/resume/lib.go @@ -81,7 +81,7 @@ func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e tx = dg.I } - if err := tx.First(&data, input.Id).Error; err != nil { + if err := tx.Scopes(gh.Preload(input.Includes)).First(&data, input.Id).Error; err != nil { if processedErr := pu.HandleReadError(err, event, source, input.Id, data); processedErr != nil { return nil, processedErr } diff --git a/pkg/conv-helper/conv-helper.go b/pkg/conv-helper/conv-helper.go index 03063c74..9b9bc44d 100644 --- a/pkg/conv-helper/conv-helper.go +++ b/pkg/conv-helper/conv-helper.go @@ -8,6 +8,8 @@ import ( "gorm.io/gorm" ) +const StandartDateTimeFormat = "2006-01-02 15:04:05" + // check string pointer, if nil return default value func StrConvDefault(f *string, def string) string { if f == nil { @@ -96,20 +98,12 @@ func BoolToString(f *bool) *string { return &t } -func TimeToString(f *time.Time) *string { - if f == nil { - return nil - } - t := f.Format("2006-01-02 15:04:05") - return &t -} - // Handling gorm.DeletedAt func DeletedAtToString(deletedAt *gorm.DeletedAt) *string { if deletedAt == nil || !deletedAt.Valid { return nil } - return TimeToString(&deletedAt.Time) + return TimeToStringWithFormat(&deletedAt.Time, "") } func BoolToFloat64(b bool) float64 { @@ -151,3 +145,17 @@ func StringToUint64(s string) *uint64 { } return &u } + +func TimeToStringWithFormat(t *time.Time, format string) *string { + result := "" + if t == nil || t.IsZero() { + return &result + } + + if format == "" { + format = StandartDateTimeFormat + } + + result = t.Format(format) + return &result +} diff --git a/pkg/use-case-helper/use-case-helper.go b/pkg/use-case-helper/use-case-helper.go index 019f9773..7d0ec17f 100644 --- a/pkg/use-case-helper/use-case-helper.go +++ b/pkg/use-case-helper/use-case-helper.go @@ -208,3 +208,13 @@ func GetLastTwoPathSegments(s string) string { // fallback: return entire string if less than 2 segments return strings.Trim(path, "/") } + +func FormatPlaceAndDate(place string, t time.Time) string { + // Ensure place is uppercase + place = strings.ToUpper(strings.TrimSpace(place)) + + // Format date: DD-MM-YYYY + dateStr := t.Format("02-01-2006") + + return place + ", " + dateStr +} From 04add70ac5018780f859b1fd5356a6336e88abf2 Mon Sep 17 00:00:00 2001 From: dpurbosakti Date: Wed, 26 Nov 2025 17:23:48 +0700 Subject: [PATCH 05/38] feat (generate-file): resume table is done --- assets/docs/resume.html | 531 +++++++++++++----- internal/domain/main-entities/resume/dto.go | 10 +- .../interface/main-handler/resume/handler.go | 10 + .../main-use-case/generate-file/helper.go | 41 +- .../main-use-case/generate-file/tycovar.go | 13 + 5 files changed, 452 insertions(+), 153 deletions(-) diff --git a/assets/docs/resume.html b/assets/docs/resume.html index 8cdca672..db66314d 100644 --- a/assets/docs/resume.html +++ b/assets/docs/resume.html @@ -7,26 +7,40 @@ body { padding: 2rem 3rem; } + table { width: 100%; border-collapse: collapse } + td { vertical-align: top; } - .border-table, .border-table td, .border-table th { + + .border-table, + .border-table td, + .border-table th { border: 1px solid black; } - .section-title { + + .section-title { margin-top: 1rem; margin-bottom: 0rem; } - .data-label { + + .data-label { width: 9rem; } - .data-colon { - width: 0.1234rem; + + .data-colon { + width: 15px; padding-left: 10px; } + + .description-label { + font-size: 0.7rem; + margin: 0; + } + @@ -60,7 +74,7 @@
- Keluhan Utama + Tindakan Medis : {{ .Repalcable }}

- +
: - {{ .Repalcable }} + {{ .MedicalRecord }} Ruang/Klinik : - {{ .Repalcable }} + {{ .Unit }} NIK : - {{ .Repalcable }} + {{ .NIK }} Kelas : - {{ .Repalcable }} + {{ .Class }} Nama : - {{ .Repalcable }} + {{ .Name }} DPJP : - {{ .Repalcable }} + {{ .Doctor_Name }} - + @@ -121,21 +135,21 @@ Tempat/Tanggal Lahir : - {{ .Repalcable }} + {{ .BirthPlaceDate }} Jenis Kelamin : - {{ .Repalcable }} + {{ .Gender }} No. Telepon : - {{ .Repalcable }} + {{ .Phone }} @@ -165,32 +179,33 @@ Tanggal Masuk : - {{ .Repalcable }} + {{ .StartedAt }} Tanggal Keluar : - {{ .Repalcable }} + {{ .FinishedAt }} Diagnosis Masuk : - {{ .Repalcable }} + {{ .DiagnosisIn }} Diagnosis Keluar : - {{ .Repalcable }} + {{ .DiagnosisOut }} - +
+ - - - - - - - - - - - - - - - - - - -
No @@ -205,31 +220,46 @@ Kode ICD-10
- 1 - {{ .Repalcable }}{{ .Repalcable }}{{ .Repalcable }}
- 2 - {{ .Repalcable }}{{ .Repalcable }}{{ .Repalcable }}
- 3 - {{ .Repalcable }}{{ .Repalcable }}{{ .Repalcable }}
+ + + {{ $dataLen := len .Diagnosis }} + {{ if gt $dataLen 0 }} + + {{ range $index, $diagnosis := .Diagnosis }} + + {{ if eq $index 0 }}1{{ else if eq $index 1 }}2{{ else if eq $index 2 }}3{{ else if eq $index 3 }}4{{ else if eq $index 4 }}5{{ else }}{{ $index }}{{ end }} + {{ $diagnosis.DiagnosisName }} + {{ $diagnosis.Basis }} + {{ $diagnosis.ICD10 }} + + {{ end }} + + + {{ if eq $dataLen 1 }} + + 2 + + + + + {{ end }} + {{ else }} + + + 1 + + + + + + 2 + + + + + {{ end }} + + @@ -237,50 +267,54 @@ -

Kajian Awal Medis

+

Kajian Awal Medis

(Diisi oleh Dokter Penanggung Jawab Pelayanan)

- + ">(Diisi oleh Dokter Penanggung Jawab Pelayanan)

+ - + - + - +
Keluhan Utama : {{ .Repalcable }}{{ .MainComplaint }}
Riwayat Penyakit : {{ .Repalcable }}{{ .MedicalHistory }}
Pemeriksaan Fisik & Keadaan Umum : {{ .Repalcable }}{{ .PhysicalExamination }}
-

Pemeriksaan Penunjang

+

Pemeriksaan Penunjang

- +
Pemeriksaan : {{ .Repalcable }}{{ .SupportingExamination }}
-

Tindakan Medis

- +
+ + +

Tindakan Medis

+ + - - - - - - - - - - - - - - - - - - -
No @@ -295,31 +329,47 @@ Kode ICD 9-CM
- 1 - {{ .Repalcable }}{{ .Repalcable }}{{ .Repalcable }}
- 2 - {{ .Repalcable }}{{ .Repalcable }}{{ .Repalcable }}
- 3 - {{ .Repalcable }}{{ .Repalcable }}{{ .Repalcable }}
+ + + {{ $dataLen := len .MedicalActions }} + {{ if gt $dataLen 0 }} + + {{ range $index, $action := .MedicalActions }} + + {{ if eq $index 0 }}1{{ else if eq $index 1 }}2{{ else if eq $index 2 }}3{{ else if eq $index 3 }}4{{ else if eq $index 4 }}5{{ else }}{{ $index }}{{ end }} + {{ $action.Action }} + {{ $action.Basis }} + {{ $action.ICD9 }} + + {{ end }} + + + {{ if eq $dataLen 1 }} + + 2 + + + + + {{ end }} + {{ else }} + + + 1 + + + + + + 2 + + + + + {{ end }} + + + @@ -327,51 +377,53 @@ Tindakan Medis - +
: {{ .Repalcable }}{{ .MedicalAction }}
+ + +
+

Konsultasi

+
+ + + + + + + + + + {{ $dataLen := len .Consultations }} + {{ if gt $dataLen 0 }} + + {{ range $index, $consultation := .Consultations }} + + + + + + {{ end }} + + + {{ if eq $dataLen 1 }} + + {{ end }} + {{ else }} + + + + {{ end }} + +
NoKonsultasiJawaban Konsultasi
{{ if eq $index 0 }}1{{ else if eq $index 1 }}2{{ else if eq $index 2 }}3{{ else if eq $index 3 }}4{{ else if eq $index 4 }}5{{ else }}{{ $index }}{{ end }}{{ $consultation.Consultation }}{{ $consultation.ConsultationAnswer }}
2
1
2
+ + -

Konsultasi

- - - - - - - - - - - - - - - - - - - - - -
- No - - Konsultasi - - Jawaban Konsultasi -
- 1 - {{ .Repalcable }}{{ .Repalcable }}
- 2 - {{ .Repalcable }}{{ .Repalcable }}
- 3 - {{ .Repalcable }}{{ .Repalcable }}
- -

Terapi

+

Terapi

@@ -379,54 +431,241 @@ : - Replace + {{ .Allergy}}
- -

Obat yang diberikan

- +
- - - - - - - - - - - - - - + +
- Terapi (Farmakologi & Non Farmakologi) Selawa Perawatan - - Terapi (Farmakologi & Non Farmakologi) Selawa Pulang -
{{ .Repalcable }}{{ .Repalcable }}
{{ .Repalcable }}{{ .Repalcable }}
{{ .Repalcable }}{{ .Repalcable }} +

Obat yang diberikan

+ + + + + + + + + + + + + + + + + +
+ Terapi (Farmakologi & Non Farmakologi) Selawa Perawatan + + Terapi (Farmakologi & Non Farmakologi) Selawa Pulang +
{{ .NIK }}{{ .NIK }}
{{ .NIK }}{{ .NIK }}
{{ .NIK }}{{ .NIK }}
+
+ -

Kondisi saat Pulang

+

Kondisi saat Pulang

- + - + + + + + + + + + + + + + + + + + + + + +
- Keluhan Utama - Kesadaran : {{ .Repalcable }}{{ .ConsciousnessLevel }}
+ Tanda Vital +

Vital sign

+
:
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ Tekanan Darah +

Blood Pressure

+
: {{ .BloodPressure }} mmHg +
+ Suhu +

Temperatur

+
: {{ .BodyTemperature }} C +
+ Nadi +

Pulse

+
: {{ .HeartRate }} x/Menit
+
+ + + + + + + + + + + + + + +
+ Frekuensi Nafas +

Respiratory rate

+
: {{ .RespirationRate }}
+ Skala Nyeri +

Pain Scale

+
: {{ .PainScale }}
+
+ +
Keadaan Keluar: {{ .ConditionOnDischarge }}
Cara Keluar +

Patient discharge of hospital

+
:{{ .DischargeMethod }}
+ + + + + + + + + + + + + + + + + + + + + + + +
+

INSTRUKSI UNTUK TINDAK LANJUT

+

Follow up Consultation to

+
+

Kontrol Ke

+

Follow up Consultation to

+
+ + + + + + + + + + + + + + + + +
Fasyankes: {{ .NIK }}
Tanggal: {{ .NIK }}
Klinik: {{ .NIK }}
+
+

Dalam keadaan darurat dapat menghubungi

+

In case of emergencycontact

+
+

IGD

+

(Accident & Emergency Instalation)

+
+ + + + + + +
Telepon +

Phone

+
: (0341) 362101
+
+

EDUKASI & RENCANA TINDAK LANJUT

+

Follow up plan (if necessary)

+
+

+

(bila diperlukan)

+
+ + + + + + + + + + + + + +
+ Malang, {{ .Date }}
+ Dokter Penanggung Jawab Pelayanan +
+ ({{ .Doctor_Name }}) +
+
+

*) Data dapat berubah setelah pasien pulang sesuai prosedur

+ \ No newline at end of file diff --git a/internal/domain/main-entities/resume/dto.go b/internal/domain/main-entities/resume/dto.go index 884b8e32..76e959e5 100644 --- a/internal/domain/main-entities/resume/dto.go +++ b/internal/domain/main-entities/resume/dto.go @@ -96,7 +96,7 @@ type Assessment struct { StartedAt *time.Time `json:"startedAt` FinishedAt *time.Time `json:"finishedAt` Doctor_Code string `json:"doctor_code` - DiagnosisIn string `json:"diagnosesIn` + DiagnosisIn string `json:"diagnosisIn` AmbulatoryIndication string `json:"ambulatoryIndication"` MainComplaint string `json:"mainComplaint"` PhysicalExamination string `json:"physicalExamination"` @@ -106,13 +106,13 @@ type Assessment struct { type Diagnosis struct { PrimaryDiagnosis DiagnosisEntry `json:"primaryDiagnosis"` - SecondaryDiagnoses []DiagnosisEntry `json:"secondaryDiagnoses"` + SecondaryDiagnosis []DiagnosisEntry `json:"secondaryDiagnosis"` } type DiagnosisEntry struct { - Diagnosis string `json:"diagnosis"` - ICD10 string `json:"icd_10"` - Basis string `json:"basis"` // Clinical basis of diagnosis / dasar diagnosa + DiagnosisName string `json:"diagnosis"` + ICD10 string `json:"icd_10"` + Basis string `json:"basis"` // Clinical basis of diagnosis / dasar diagnosa } type Action struct { diff --git a/internal/interface/main-handler/resume/handler.go b/internal/interface/main-handler/resume/handler.go index 5574bc7a..9a59f5fd 100644 --- a/internal/interface/main-handler/resume/handler.go +++ b/internal/interface/main-handler/resume/handler.go @@ -52,6 +52,10 @@ func GetDetail(w http.ResponseWriter, r *http.Request) { } func Update(w http.ResponseWriter, r *http.Request) { + authInfo, err := pa.GetAuthInfo(r) + if err != nil { + rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil) + } id := rw.ValidateInt(w, "id", r.PathValue("id")) if id <= 0 { return @@ -62,11 +66,16 @@ func Update(w http.ResponseWriter, r *http.Request) { return } dto.Id = uint(id) + dto.AuthInfo = *authInfo res, err := u.Update(dto) rw.DataResponse(w, res, err) } func Delete(w http.ResponseWriter, r *http.Request) { + authInfo, err := pa.GetAuthInfo(r) + if err != nil { + rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil) + } id := rw.ValidateInt(w, "id", r.PathValue("id")) if id <= 0 { return @@ -74,6 +83,7 @@ func Delete(w http.ResponseWriter, r *http.Request) { dto := e.DeleteDto{} dto.Id = uint(id) + dto.AuthInfo = *authInfo res, err := u.Delete(dto) rw.DataResponse(w, res, err) } diff --git a/internal/use-case/main-use-case/generate-file/helper.go b/internal/use-case/main-use-case/generate-file/helper.go index e42fc13e..02800c3a 100644 --- a/internal/use-case/main-use-case/generate-file/helper.go +++ b/internal/use-case/main-use-case/generate-file/helper.go @@ -250,8 +250,28 @@ func generateResume(input GenerateDto, event pl.Event, tx *gorm.DB) (*ResponseDt } } + templateData, err := generateResumeTemplateData(*r, event, tx) + if err != nil { + return nil, err + } + + input.FormatType = erc.DFTCPDF + input.TemplateName = TDNR + input.Encounter_Id = r.Encounter_Id + + // generate file + urlPub, err := generateFile(input, templateData) + if err != nil { + return nil, err + } + + r.FileUrl = &urlPub + if err := tx.Save(&r).Error; err != nil { + return nil, err + } + response := ResponseDto{ - FileUrl: "", + FileUrl: urlPub, } return &response, nil @@ -264,7 +284,6 @@ func generateResumeTemplateData(resume er.Resume, event pl.Event, tx *gorm.DB) ( if err != nil { return nil, err } - fmt.Println(encounter) // map template data rData := er.ValueDto{} @@ -293,6 +312,24 @@ func generateResumeTemplateData(resume er.Resume, event pl.Event, tx *gorm.DB) ( templateData.Doctor_Name = resume.Doctor.Employee.Person.FullName() templateData.StartedAt = *pc.TimeToStringWithFormat(encounter.StartedAt, "") templateData.FinishedAt = *pc.TimeToStringWithFormat(encounter.FinishedAt, "") + templateData.DiagnosisIn = rData.Assessment.DiagnosisIn + templateData.Diagnosis = rData.Diagnosis.SecondaryDiagnosis + templateData.MainComplaint = rData.Assessment.MainComplaint + templateData.MedicalHistory = rData.Assessment.MedicalHistory + templateData.PhysicalExamination = rData.Assessment.PhysicalExamination + templateData.SupportingExamination = rData.Supporting.Notes + templateData.MedicalActions = rData.Action.AdditionalActions + templateData.MedicalAction = rData.Action.MedicalActions + templateData.Consultations = rData.Consultation.Consultations + templateData.Allergy = rData.Pharmacy.AllergySpecialConditions + templateData.ConsciousnessLevel = rData.Discharge.ConsciousnessLevel + templateData.BloodPressure = fmt.Sprintf("%.0f/%.0f", rData.Discharge.BloodPressureSystolic, rData.Discharge.BloodPressureDiastolic) + templateData.BodyTemperature = rData.Discharge.BodyTemperature + templateData.RespirationRate = rData.Discharge.RespirationRate + templateData.HeartRate = rData.Discharge.HeartRate + templateData.PainScale = rData.Discharge.PainScale + templateData.ConditionOnDischarge = rData.Management.ConditionOnDischarge + templateData.DischargeMethod = rData.Management.DischargeMethod return &templateData, nil } diff --git a/internal/use-case/main-use-case/generate-file/tycovar.go b/internal/use-case/main-use-case/generate-file/tycovar.go index 1dee32ff..d1d1ed6a 100644 --- a/internal/use-case/main-use-case/generate-file/tycovar.go +++ b/internal/use-case/main-use-case/generate-file/tycovar.go @@ -57,6 +57,18 @@ type ResumePDF struct { MedicalAction string Consultations []er.ConsultationEntry Allergy string + ConsciousnessLevel string + BloodPressure string + BodyTemperature float64 + RespirationRate float64 + HeartRate float64 + PainScale int + ConditionOnDischarge string + DischargeMethod string + // fasyankes + // date + // klinik + Date string } type GenerateDto struct { @@ -110,6 +122,7 @@ type TemplateDocsName string const ( TDNGC TemplateDocsName = "general-consent.html" TDNCL TemplateDocsName = "control-letter.html" + TDNR TemplateDocsName = "resume.html" ) func (v VclaimControlLetter) generateTemplateData() ControlLetterPDF { From abfbc568b03efcda6c77768a0924996d382346f4 Mon Sep 17 00:00:00 2001 From: dpurbosakti Date: Thu, 27 Nov 2025 13:30:45 +0700 Subject: [PATCH 06/38] feat (generate-file) hopefully resume.html doesnt make any trouble --- assets/docs/resume.html | 94 +++++++++++++------ internal/domain/main-entities/resume/dto.go | 10 ++ .../main-use-case/generate-file/helper.go | 2 + .../main-use-case/generate-file/tycovar.go | 1 + 4 files changed, 78 insertions(+), 29 deletions(-) diff --git a/assets/docs/resume.html b/assets/docs/resume.html index db66314d..4ad209ff 100644 --- a/assets/docs/resume.html +++ b/assets/docs/resume.html @@ -438,35 +438,55 @@ + + + + + + {{ end }} + {{ else }} + + + + + + + + + + {{ end }} + +
+

Obat yang diberikan

+ + + + + + + + + {{ $dataLen := len .Medications }} + + {{ if gt $dataLen 0 }} + + {{ range .Medications }} - + + + {{ end }} -
+ Terapi (Farmakologi & Non Farmakologi) Selama Perawatan + + Terapi (Farmakologi & Non Farmakologi) Waktu Pulang +
-

Obat yang diberikan

- - - - - - - - - - - - - - - - - -
- Terapi (Farmakologi & Non Farmakologi) Selawa Perawatan - - Terapi (Farmakologi & Non Farmakologi) Selawa Pulang -
{{ .NIK }}{{ .NIK }}
{{ .NIK }}{{ .NIK }}
{{ .NIK }}{{ .NIK }}
-
{{ .DuringTreatment }}{{ .AtDischarge }}
+ + {{ if eq $dataLen 1 }} +
  
  
  
+ + + @@ -501,7 +521,11 @@

Blood Pressure

: + {{ if and .BloodPressure (ne .BloodPressure "0/0") (ne .BloodPressure "") }} {{ .BloodPressure }} mmHg + {{ else }} + + {{ end }} @@ -512,7 +536,11 @@ : - {{ .BodyTemperature }} C + {{ if ne .BodyTemperature 0.0 }} + {{ .BodyTemperature }} C + {{ else }} + + {{ end }} @@ -521,7 +549,11 @@

Pulse

: - {{ .HeartRate }} x/Menit + {{ if ne .HeartRate 0.0 }} + {{ .HeartRate }} x/Menit + {{ else }} + + {{ end }} @@ -535,7 +567,11 @@ : - {{ .RespirationRate }} + {{ if ne .RespirationRate 0.0 }} + {{ .RespirationRate }} x/Menit + {{ else }} + + {{ end }} diff --git a/internal/domain/main-entities/resume/dto.go b/internal/domain/main-entities/resume/dto.go index 76e959e5..e7ddf09b 100644 --- a/internal/domain/main-entities/resume/dto.go +++ b/internal/domain/main-entities/resume/dto.go @@ -90,6 +90,7 @@ type ValueDto struct { Discharge DischargeCondition `json:"discharge"` National NationalProgram `json:"national"` Management Management `json:"management"` + Medication Medication `json:"medication"` } type Assessment struct { @@ -170,3 +171,12 @@ type Management struct { ConditionOnDischarge string `json:"conditionOnDischarge"` // e.g. "Stable" DischargeMethod string `json:"dischargeMethod"` // e.g. "Discharged with Doctor's Approval" } + +type MedicationEntry struct { + DuringTreatment string `json:"duringTreatment"` + AtDischarge string `json:"atDischarge"` +} + +type Medication struct { + Medications []MedicationEntry `json:"medications"` +} diff --git a/internal/use-case/main-use-case/generate-file/helper.go b/internal/use-case/main-use-case/generate-file/helper.go index 02800c3a..1f0d0bfd 100644 --- a/internal/use-case/main-use-case/generate-file/helper.go +++ b/internal/use-case/main-use-case/generate-file/helper.go @@ -330,6 +330,8 @@ func generateResumeTemplateData(resume er.Resume, event pl.Event, tx *gorm.DB) ( templateData.PainScale = rData.Discharge.PainScale templateData.ConditionOnDischarge = rData.Management.ConditionOnDischarge templateData.DischargeMethod = rData.Management.DischargeMethod + templateData.Medications = rData.Medication.Medications + templateData.Date = pu.GetTimeNow().Format("02-01-2006") return &templateData, nil } diff --git a/internal/use-case/main-use-case/generate-file/tycovar.go b/internal/use-case/main-use-case/generate-file/tycovar.go index d1d1ed6a..a242f476 100644 --- a/internal/use-case/main-use-case/generate-file/tycovar.go +++ b/internal/use-case/main-use-case/generate-file/tycovar.go @@ -65,6 +65,7 @@ type ResumePDF struct { PainScale int ConditionOnDischarge string DischargeMethod string + Medications []er.MedicationEntry // fasyankes // date // klinik From 2a393015635f30b428241495ce0ef32ed99fe54e Mon Sep 17 00:00:00 2001 From: dpurbosakti Date: Fri, 28 Nov 2025 16:10:35 +0700 Subject: [PATCH 07/38] feat (vclaim-sep): create, read, delete done --- cmd/bpjs-api/config.yml-example | 3 - cmd/main-api/config.yml-example | 3 - .../domain/bpjs-entities/vclaim-sep/dto.go | 141 +++++++++++++++++- .../bpjs-entities/vclaim-sep/entitiy.go | 1 + .../domain/main-entities/encounter/entity.go | 2 +- .../interface/bpjs-handler/bpjs-handler.go | 14 +- .../interface/main-handler/main-handler.go | 48 +++++- .../member/handler.go | 0 .../monitoring/handler.go | 0 .../reference/handler.go | 0 .../interface/main-handler/resume/handler.go | 6 - .../vclaim-sep-hist/handler.go | 0 .../vclaim-sep-print/handler.go | 0 .../vclaim-sep/handler.go | 56 ++++--- .../use-case/bpjs-plugin/vclaim-sep/plugin.go | 81 +++++++++- .../bpjs-plugin/vclaim-sep/tycovar.go | 2 + .../use-case/bpjs-use-case/vclaim-sep/case.go | 22 ++- .../use-case/bpjs-use-case/vclaim-sep/lib.go | 3 + .../vclaim-sep/middleware-runner.go | 2 +- .../bpjs-use-case/vclaim-sep/middleware.go | 7 +- .../bpjs-use-case/vclaim-sep/tycovar.go | 10 +- .../main-use-case/generate-file/helper.go | 4 + .../use-case/main-use-case/resume/case.go | 9 +- .../use-case/main-use-case/resume/helper.go | 4 +- 24 files changed, 343 insertions(+), 75 deletions(-) rename internal/interface/{bpjs-handler => main-handler}/member/handler.go (100%) rename internal/interface/{bpjs-handler => main-handler}/monitoring/handler.go (100%) rename internal/interface/{bpjs-handler => main-handler}/reference/handler.go (100%) rename internal/interface/{bpjs-handler => main-handler}/vclaim-sep-hist/handler.go (100%) rename internal/interface/{bpjs-handler => main-handler}/vclaim-sep-print/handler.go (100%) rename internal/interface/{bpjs-handler => main-handler}/vclaim-sep/handler.go (55%) diff --git a/cmd/bpjs-api/config.yml-example b/cmd/bpjs-api/config.yml-example index 60b1644c..dcea2f07 100644 --- a/cmd/bpjs-api/config.yml-example +++ b/cmd/bpjs-api/config.yml-example @@ -57,9 +57,6 @@ corsCfg: satuSehatCfg: host: localhost:8200 -bpjsCfg: - host: localhost:8200 - corsCfg: allowedOrigins: - http://example.com diff --git a/cmd/main-api/config.yml-example b/cmd/main-api/config.yml-example index 30351abf..3423b5d1 100644 --- a/cmd/main-api/config.yml-example +++ b/cmd/main-api/config.yml-example @@ -57,9 +57,6 @@ corsCfg: satuSehatCfg: host: localhost:8200 -bpjsCfg: - host: localhost:8200 - corsCfg: allowedOrigins: - http://example.com diff --git a/internal/domain/bpjs-entities/vclaim-sep/dto.go b/internal/domain/bpjs-entities/vclaim-sep/dto.go index 8a174688..2f4475b5 100644 --- a/internal/domain/bpjs-entities/vclaim-sep/dto.go +++ b/internal/domain/bpjs-entities/vclaim-sep/dto.go @@ -1,6 +1,7 @@ package vclaimsep import ( + "encoding/json" ecore "simrs-vx/internal/domain/base-entities/core" evsh "simrs-vx/internal/domain/bpjs-entities/vclaim-sep-hist" ) @@ -8,7 +9,7 @@ import ( type CreateDto struct { Encounter_Id *uint `json:"encounter_id"` Number *string `json:"number" validate:"maxLength=19"` - RequestPayload []byte `json:"requestPayload" validate:"maxLength=1024"` + RequestPayload string `json:"requestPayload" validate:"maxLength=1024"` VclaimSepHist evsh.CreateDto } @@ -25,8 +26,9 @@ type FilterDto struct { } type ReadDetailDto struct { - Id uint `json:"id"` - Number *string `json:"number"` + Id uint `json:"id"` + Number *string `json:"number"` + Encounter_Id *uint `json:"encounter_id"` } type UpdateDto struct { @@ -47,14 +49,16 @@ type MetaDto struct { type ResponseDto struct { ecore.Main - Encounter_Id *uint `json:"encounter_id"` - Number *string `json:"number"` + Encounter_Id *uint `json:"encounter_id"` + Number *string `json:"number"` + Detail *SepDetail `json:"detail,omitempty"` } func (d VclaimSep) ToResponse() ResponseDto { resp := ResponseDto{ Encounter_Id: d.Encounter_Id, Number: d.Number, + Detail: d.Detail, } resp.Main = d.Main return resp @@ -71,3 +75,130 @@ func ToResponseList(data []VclaimSep) []ResponseDto { func (c CreateDto) IsMessageSuccess() bool { return c.VclaimSepHist.Message == "Sukses" } + +func (c CreateDto) RequestPayloadIntoJson() ([]byte, error) { + payload := map[string]interface{}{} + err := json.Unmarshal([]byte(c.RequestPayload), &payload) + if err != nil { + return nil, err + } + return json.Marshal(payload) +} + +func (c CreateDto) RequestPayloadWithEncounterId() ([]byte, error) { + payload := map[string]interface{}{} + + err := json.Unmarshal([]byte(c.RequestPayload), &payload) + if err != nil { + return nil, err + } + + payload["encounter_id"] = c.Encounter_Id + + return json.Marshal(payload) +} + +type SepResponse struct { + MetaData MetaData `json:"metaData"` + Response *SepDetail `json:"response"` +} + +type MetaData struct { + Code string `json:"code"` + Message string `json:"message"` +} + +type SepDetail struct { + AssestmenPel AssestmenPel `json:"assestmenPel"` + Catatan string `json:"catatan"` + Cob string `json:"cob"` + Diagnosa string `json:"diagnosa"` + Dpjp Dpjp `json:"dpjp"` + ESep string `json:"eSEP"` + FlagProcedure FlagProcedure `json:"flagProcedure"` + Informasi any `json:"informasi"` // null = interface{} + JnsPelayanan string `json:"jnsPelayanan"` + Katarak string `json:"katarak"` + KdPenunjang KdPenunjang `json:"kdPenunjang"` + KdStatusKecelakaan string `json:"kdStatusKecelakaan"` + KelasRawat string `json:"kelasRawat"` + KlsRawat KlsRawat `json:"klsRawat"` + Kontrol Kontrol `json:"kontrol"` + LokasiKejadian LokasiKejadian `json:"lokasiKejadian"` + NmStatusKecelakaan string `json:"nmstatusKecelakaan"` + NoRujukan string `json:"noRujukan"` + NoSep string `json:"noSep"` + Penjamin any `json:"penjamin"` // null + Peserta Peserta `json:"peserta"` + Poli string `json:"poli"` + PoliEksekutif string `json:"poliEksekutif"` + TglSep string `json:"tglSep"` + TujuanKunj TujuanKunj `json:"tujuanKunj"` +} + +type AssestmenPel struct { + Kode string `json:"kode"` + Nama string `json:"nama"` +} + +type Dpjp struct { + KdDPJP string `json:"kdDPJP"` + NmDPJP string `json:"nmDPJP"` +} + +type FlagProcedure struct { + Kode string `json:"kode"` + Nama string `json:"nama"` +} + +type KdPenunjang struct { + Kode string `json:"kode"` + Nama string `json:"nama"` +} + +type KlsRawat struct { + KlsRawatHak string `json:"klsRawatHak"` + KlsRawatNaik *string `json:"klsRawatNaik"` // nullable + Pembiayaan *string `json:"pembiayaan"` // nullable + PenanggungJawab *string `json:"penanggungJawab"` // nullable +} + +type Kontrol struct { + KdDokter *string `json:"kdDokter"` // null + NmDokter *string `json:"nmDokter"` // null + NoSurat *string `json:"noSurat"` // null +} + +type LokasiKejadian struct { + KdKab *string `json:"kdKab"` + KdKec *string `json:"kdKec"` + KdProp *string `json:"kdProp"` + KetKejadian *string `json:"ketKejadian"` + Lokasi *string `json:"lokasi"` + TglKejadian *string `json:"tglKejadian"` +} + +type Peserta struct { + Asuransi any `json:"asuransi"` + HakKelas string `json:"hakKelas"` + JnsPeserta string `json:"jnsPeserta"` + Kelamin string `json:"kelamin"` + Nama string `json:"nama"` + NoKartu string `json:"noKartu"` + NoMR string `json:"noMr"` + TglLahir string `json:"tglLahir"` +} + +type TujuanKunj struct { + Kode string `json:"kode"` + Nama string `json:"nama"` +} + +type SepDeleteRequest struct { + Request struct { + TSep struct { + NoSep string `json:"noSep"` + User string `json:"user"` + } `json:"t_sep"` + } `json:"request"` +} diff --git a/internal/domain/bpjs-entities/vclaim-sep/entitiy.go b/internal/domain/bpjs-entities/vclaim-sep/entitiy.go index f175e4cb..6948d640 100644 --- a/internal/domain/bpjs-entities/vclaim-sep/entitiy.go +++ b/internal/domain/bpjs-entities/vclaim-sep/entitiy.go @@ -12,4 +12,5 @@ type VclaimSep struct { Number *string `json:"number" gorm:"unique;size:19"` Prints []*evsp.VclaimSepPrint `json:"prints,omitempty" gorm:"foreignKey:VclaimSep_Number;references:Number"` ControlLetters []*evscl.VclaimSepControlLetter `json:"controlLetters,omitempty" gorm:"foreignKey:VclaimSep_Number;references:Number"` + Detail *SepDetail `json:"detail,omitempty" gorm:"-"` } diff --git a/internal/domain/main-entities/encounter/entity.go b/internal/domain/main-entities/encounter/entity.go index a3908149..5584819b 100644 --- a/internal/domain/main-entities/encounter/entity.go +++ b/internal/domain/main-entities/encounter/entity.go @@ -87,5 +87,5 @@ func (d Encounter) IsSameResponsibleDoctor(input *string) bool { if input == nil { return false } - return d.Responsible_Doctor_Code == input + return *d.Responsible_Doctor_Code == *input } diff --git a/internal/interface/bpjs-handler/bpjs-handler.go b/internal/interface/bpjs-handler/bpjs-handler.go index 175bb667..4f000664 100644 --- a/internal/interface/bpjs-handler/bpjs-handler.go +++ b/internal/interface/bpjs-handler/bpjs-handler.go @@ -4,12 +4,12 @@ import ( "net/http" /******************** main / transaction ********************/ - member "simrs-vx/internal/interface/bpjs-handler/member" - monitoring "simrs-vx/internal/interface/bpjs-handler/monitoring" - reference "simrs-vx/internal/interface/bpjs-handler/reference" - vclaimsep "simrs-vx/internal/interface/bpjs-handler/vclaim-sep" - vclaimsephist "simrs-vx/internal/interface/bpjs-handler/vclaim-sep-hist" - vclaimsepprint "simrs-vx/internal/interface/bpjs-handler/vclaim-sep-print" + member "simrs-vx/internal/interface/main-handler/member" + monitoring "simrs-vx/internal/interface/main-handler/monitoring" + reference "simrs-vx/internal/interface/main-handler/reference" + vclaimsep "simrs-vx/internal/interface/main-handler/vclaim-sep" + vclaimsephist "simrs-vx/internal/interface/main-handler/vclaim-sep-hist" + vclaimsepprint "simrs-vx/internal/interface/main-handler/vclaim-sep-print" /******************** actor ********************/ @@ -49,7 +49,7 @@ func SetRoutes() http.Handler { hk.GroupRoutes("/v1/vclaim-sep", r, hk.MapHandlerFunc{ "POST /": vclaimsep.O.Create, - "PATCH /{id}": vclaimsep.O.Update, + "PATCH /{id}": vclaimsep.O.GetDetail, "DELETE /{id}": vclaimsep.O.Delete, }) diff --git a/internal/interface/main-handler/main-handler.go b/internal/interface/main-handler/main-handler.go index a4f6e382..d374a8a8 100644 --- a/internal/interface/main-handler/main-handler.go +++ b/internal/interface/main-handler/main-handler.go @@ -120,9 +120,17 @@ import ( regency "simrs-vx/internal/interface/main-handler/regency" village "simrs-vx/internal/interface/main-handler/village" - ///// Internal + /******************** Internal ********************/ validation "simrs-vx/internal/interface/main-handler/helper/validation" "simrs-vx/internal/interface/main-handler/home" + + /******************** BPJS ********************/ + member "simrs-vx/internal/interface/main-handler/member" + monitoring "simrs-vx/internal/interface/main-handler/monitoring" + reference "simrs-vx/internal/interface/main-handler/reference" + vclaimsep "simrs-vx/internal/interface/main-handler/vclaim-sep" + vclaimsephist "simrs-vx/internal/interface/main-handler/vclaim-sep-hist" + vclaimsepprint "simrs-vx/internal/interface/main-handler/vclaim-sep-print" ) // One place route to relatively easier to manage, ESPECIALLY in tracking @@ -138,6 +146,7 @@ func SetRoutes() http.Handler { a.RegisterExtCall(validation.RegisterValidation) a.RegisterExtCall(simgossync.SetConfig) a.RegisterExtCall(docscfg.ParseCfg) + a.RegisterExtCall(ibpjs.SetConfig) r := http.NewServeMux() @@ -371,6 +380,43 @@ func SetRoutes() http.Handler { hc.RegCrudByCode(r, "/v1/province", province.O) hc.RegCrudByCode(r, "/v1/postal-region", postalregion.O) + /******************** BPJS ********************/ + hk.GroupRoutes("/v1/vclaim-sep", r, hk.MapHandlerFunc{ + "POST /": vclaimsep.O.Create, + "GET /{id}": vclaimsep.O.GetDetail, + "DELETE /{id}": vclaimsep.O.Delete, + }) + + hk.GroupRoutes("/v1/vclaim-sep-hist", r, hk.MapHandlerFunc{ + "GET /": vclaimsephist.O.GetList, + }) + + hk.GroupRoutes("/v1/vclaim-sep-print", r, hk.MapHandlerFunc{ + "POST /": vclaimsepprint.O.Create, + }) + + hk.GroupRoutes("/v1/reference", r, hk.MapHandlerFunc{ + "GET /province": reference.GetListProvince, + "GET /regency/{provinceCode}": reference.GetListCities, + "GET /district/{regencyCode}": reference.GetListDistrict, + "GET /diagnose/{keyword}": reference.GetListDiagnose, + "GET /diagnose-prb": reference.GetListDiagnosePrb, + "GET /medicine-prb/{keyword}": reference.GetListMedicinePrb, + "GET /unit/{unitCode}": reference.GetListUnit, + "GET /healthcare/{healthcare}/{healthcareType}": reference.GetListHealthcare, + "GET /responsible-doctor/{serviceType}/{serviceDate}/{specialistCode}": reference.GetListDoctor, + }) + + hk.GroupRoutes("/v1/member", r, hk.MapHandlerFunc{ + "GET /bpjs/{cardNumber}/{sepDate}": member.GetListByBpjsNumber, + "GET /nik/{nik}/{sepDate}": member.GetListByNik, + }) + + hk.GroupRoutes("/v1/monitoring", r, hk.MapHandlerFunc{ + "GET /visit/{date}/{serviceType}": monitoring.GetListVisit, + "GET /hist/{cardNumber}/{startDate}/{endDate}": monitoring.GetListHist, + }) + ///// return cmw.SetCors(handlerlogger.SetLog(r)) } diff --git a/internal/interface/bpjs-handler/member/handler.go b/internal/interface/main-handler/member/handler.go similarity index 100% rename from internal/interface/bpjs-handler/member/handler.go rename to internal/interface/main-handler/member/handler.go diff --git a/internal/interface/bpjs-handler/monitoring/handler.go b/internal/interface/main-handler/monitoring/handler.go similarity index 100% rename from internal/interface/bpjs-handler/monitoring/handler.go rename to internal/interface/main-handler/monitoring/handler.go diff --git a/internal/interface/bpjs-handler/reference/handler.go b/internal/interface/main-handler/reference/handler.go similarity index 100% rename from internal/interface/bpjs-handler/reference/handler.go rename to internal/interface/main-handler/reference/handler.go diff --git a/internal/interface/main-handler/resume/handler.go b/internal/interface/main-handler/resume/handler.go index 9a59f5fd..24ac0b08 100644 --- a/internal/interface/main-handler/resume/handler.go +++ b/internal/interface/main-handler/resume/handler.go @@ -99,9 +99,6 @@ func Verify(w http.ResponseWriter, r *http.Request) { } dto := e.UpdateDto{} - if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { - return - } dto.Id = uint(id) dto.Status_Code = erc.DVCVerified dto.AuthInfo = *authInfo @@ -120,9 +117,6 @@ func Validate(w http.ResponseWriter, r *http.Request) { } dto := e.UpdateDto{} - if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { - return - } dto.Id = uint(id) dto.Status_Code = erc.DVCValidated dto.AuthInfo = *authInfo diff --git a/internal/interface/bpjs-handler/vclaim-sep-hist/handler.go b/internal/interface/main-handler/vclaim-sep-hist/handler.go similarity index 100% rename from internal/interface/bpjs-handler/vclaim-sep-hist/handler.go rename to internal/interface/main-handler/vclaim-sep-hist/handler.go diff --git a/internal/interface/bpjs-handler/vclaim-sep-print/handler.go b/internal/interface/main-handler/vclaim-sep-print/handler.go similarity index 100% rename from internal/interface/bpjs-handler/vclaim-sep-print/handler.go rename to internal/interface/main-handler/vclaim-sep-print/handler.go diff --git a/internal/interface/bpjs-handler/vclaim-sep/handler.go b/internal/interface/main-handler/vclaim-sep/handler.go similarity index 55% rename from internal/interface/bpjs-handler/vclaim-sep/handler.go rename to internal/interface/main-handler/vclaim-sep/handler.go index d40c76e9..ed11e257 100644 --- a/internal/interface/bpjs-handler/vclaim-sep/handler.go +++ b/internal/interface/main-handler/vclaim-sep/handler.go @@ -1,7 +1,6 @@ package vclaimsep import ( - "io" "net/http" rw "github.com/karincake/risoles" @@ -16,14 +15,9 @@ var O myBase func (obj myBase) Create(w http.ResponseWriter, r *http.Request) { dto := e.CreateDto{} - body, err := io.ReadAll(r.Body) - if err != nil { - http.Error(w, "failed to read body", http.StatusBadRequest) + if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { return } - defer r.Body.Close() - - dto.RequestPayload = body res, err := u.Create(dto) rw.DataResponse(w, res, err) } @@ -35,39 +29,39 @@ func (obj myBase) Create(w http.ResponseWriter, r *http.Request) { // rw.DataResponse(w, res, err) // } -// func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) { -// id := rw.ValidateInt(w, "id", r.PathValue("id")) -// if id <= 0 { +func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) { + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id <= 0 { + return + } + dto := e.ReadDetailDto{} + dto.Id = uint(id) + res, err := u.ReadDetail(dto) + rw.DataResponse(w, res, err) +} + +// func (obj myBase) Update(w http.ResponseWriter, r *http.Request) { +// number := rw.ValidateString(w, "number", r.PathValue("number")) +// if number != "" { // return // } -// dto := e.ReadDetailDto{} -// dto.Id = uint(id) -// res, err := u.ReadDetail(dto) + +// dto := e.UpdateDto{} +// if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { +// return +// } +// dto.Number = &number +// res, err := u.Update(dto) // rw.DataResponse(w, res, err) // } -func (obj myBase) Update(w http.ResponseWriter, r *http.Request) { - number := rw.ValidateString(w, "number", r.PathValue("number")) - if number != "" { - return - } - - dto := e.UpdateDto{} - if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { - return - } - dto.Number = &number - res, err := u.Update(dto) - rw.DataResponse(w, res, err) -} - func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) { - number := rw.ValidateString(w, "number", r.PathValue("number")) - if number != "" { + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id <= 0 { return } dto := e.DeleteDto{} - dto.Number = &number + dto.Id = uint(id) res, err := u.Delete(dto) rw.DataResponse(w, res, err) } diff --git a/internal/use-case/bpjs-plugin/vclaim-sep/plugin.go b/internal/use-case/bpjs-plugin/vclaim-sep/plugin.go index fd18763f..70097b74 100644 --- a/internal/use-case/bpjs-plugin/vclaim-sep/plugin.go +++ b/internal/use-case/bpjs-plugin/vclaim-sep/plugin.go @@ -14,7 +14,11 @@ import ( ) func CreateSep(input *e.CreateDto, data *e.VclaimSep, tx *gorm.DB) error { - req, err := http.NewRequest("POST", ibpjs.O.BaseUrl+"/sep", bytes.NewReader(input.RequestPayload)) + payload, err := input.RequestPayloadIntoJson() + if err != nil { + return err + } + req, err := http.NewRequest("POST", ibpjs.O.BaseUrl+"sep", bytes.NewBuffer(payload)) if err != nil { return err } @@ -43,7 +47,11 @@ func CreateSep(input *e.CreateDto, data *e.VclaimSep, tx *gorm.DB) error { } // Save request/response details in DTO for further use - input.VclaimSepHist.RequestPayload = string(input.RequestPayload) + reqPayload, err := input.RequestPayloadWithEncounterId() + if err != nil { + return err + } + input.VclaimSepHist.RequestPayload = string(reqPayload) input.VclaimSepHist.ResponseBody = string(body) input.VclaimSepHist.Message = msg input.Number = func() *string { @@ -56,3 +64,72 @@ func CreateSep(input *e.CreateDto, data *e.VclaimSep, tx *gorm.DB) error { return nil } + +func ReadDetailSep(input *e.ReadDetailDto, data *e.VclaimSep, tx *gorm.DB) error { + endpoint := fmt.Sprintf("sep/%s", *data.Number) + req, err := http.NewRequest("GET", ibpjs.O.BaseUrl+endpoint, nil) + if err != nil { + return err + } + req.Header.Set("Content-Type", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return err + } + + var detail e.SepResponse + if err := json.Unmarshal(body, &detail); err != nil { + return fmt.Errorf("failed to parse response JSON: %w", err) + } + + data.Detail = detail.Response + + return nil +} + +func DeleteSep(input *e.DeleteDto, data *e.VclaimSep, tx *gorm.DB) error { + payload := e.SepDeleteRequest{} + payload.Request.TSep.NoSep = *data.Number + payload.Request.TSep.User = "Coba Ws" + + jsonPayload, err := json.Marshal(payload) + if err != nil { + return err + } + + req, err := http.NewRequest("DELETE", ibpjs.O.BaseUrl+"sep", bytes.NewBuffer(jsonPayload)) + if err != nil { + return err + } + + req.Header.Set("Content-Type", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return err + } + + var detail e.SepResponse + if err := json.Unmarshal(body, &detail); err != nil { + return fmt.Errorf("failed to parse response JSON: %w", err) + } + + if detail.MetaData.Message == SepNotFound { + return fmt.Errorf("sep with number %s not found", *data.Number) + } + + return nil +} diff --git a/internal/use-case/bpjs-plugin/vclaim-sep/tycovar.go b/internal/use-case/bpjs-plugin/vclaim-sep/tycovar.go index f057726e..7c19c44c 100644 --- a/internal/use-case/bpjs-plugin/vclaim-sep/tycovar.go +++ b/internal/use-case/bpjs-plugin/vclaim-sep/tycovar.go @@ -10,3 +10,5 @@ type vclaimResponse struct { } `json:"sep"` } `json:"response"` } + +const SepNotFound = "Data Tidak Ditemukan" diff --git a/internal/use-case/bpjs-use-case/vclaim-sep/case.go b/internal/use-case/bpjs-use-case/vclaim-sep/case.go index ac72d648..1d0e4aab 100644 --- a/internal/use-case/bpjs-use-case/vclaim-sep/case.go +++ b/internal/use-case/bpjs-use-case/vclaim-sep/case.go @@ -1,6 +1,7 @@ package vclaimsep import ( + "fmt" "strconv" e "simrs-vx/internal/domain/bpjs-entities/vclaim-sep" @@ -31,6 +32,17 @@ func Create(input e.CreateDto) (*d.Data, error) { pl.SetLogInfo(&event, input, "started", "create") err := dg.I.Transaction(func(tx *gorm.DB) error { + rDto := e.ReadDetailDto{Encounter_Id: input.Encounter_Id} + if vSep, err := ReadDetailData(rDto, &event, tx); err != nil { + if !pu.IsDataNotFoundError(err) { + return err + } + + if vSep != nil { + return fmt.Errorf("sep with encounter id %d already exist with number %s", input.Encounter_Id, *vSep.Number) + } + } + mwRunner := newMiddlewareRunner(&event, tx) mwRunner.setMwType(pu.MWTPre) // Run pre-middleware @@ -38,12 +50,12 @@ func Create(input e.CreateDto) (*d.Data, error) { return err } - if _, err := uvsh.CreateData(input.VclaimSepHist, &event, tx); err != nil { + if _, err := uvsh.CreateData(input.VclaimSepHist, &event); err != nil { return err } if !input.IsMessageSuccess() { - return nil + return fmt.Errorf("%s", input.VclaimSepHist.Message) } if resData, err := CreateData(input, &event, tx); err != nil { @@ -234,7 +246,7 @@ func Update(input e.UpdateDto) (*d.Data, error) { } func Delete(input e.DeleteDto) (*d.Data, error) { - rdDto := e.ReadDetailDto{Number: input.Number} + rdDto := e.ReadDetailDto{Id: input.Id} var data *e.VclaimSep var err error @@ -255,7 +267,7 @@ func Delete(input e.DeleteDto) (*d.Data, error) { mwRunner := newMiddlewareRunner(&event, tx) mwRunner.setMwType(pu.MWTPre) // Run pre-middleware - if err := mwRunner.RunDeleteMiddleware(readDetailPreMw, &rdDto, data); err != nil { + if err := mwRunner.RunDeleteMiddleware(deletePreMw, &e.DeleteDto{}, data); err != nil { return err } @@ -265,7 +277,7 @@ func Delete(input e.DeleteDto) (*d.Data, error) { mwRunner.setMwType(pu.MWTPost) // Run post-middleware - if err := mwRunner.RunDeleteMiddleware(readDetailPostMw, &rdDto, data); err != nil { + if err := mwRunner.RunDeleteMiddleware(deletePostMw, &e.DeleteDto{}, data); err != nil { return err } diff --git a/internal/use-case/bpjs-use-case/vclaim-sep/lib.go b/internal/use-case/bpjs-use-case/vclaim-sep/lib.go index 817c357c..82da0d45 100644 --- a/internal/use-case/bpjs-use-case/vclaim-sep/lib.go +++ b/internal/use-case/bpjs-use-case/vclaim-sep/lib.go @@ -87,6 +87,9 @@ func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e if input.Id != 0 { tx = tx.Where("\"Id\" = ?", input.Id) } + if input.Encounter_Id != nil { + tx = tx.Where("\"Encounter_Id\" = ?", *input.Encounter_Id) + } if err := tx.First(&data).Error; err != nil { if processedErr := pu.HandleReadError(err, event, source, input.Id, data); processedErr != nil { diff --git a/internal/use-case/bpjs-use-case/vclaim-sep/middleware-runner.go b/internal/use-case/bpjs-use-case/vclaim-sep/middleware-runner.go index dee35276..8e8522a6 100644 --- a/internal/use-case/bpjs-use-case/vclaim-sep/middleware-runner.go +++ b/internal/use-case/bpjs-use-case/vclaim-sep/middleware-runner.go @@ -83,7 +83,7 @@ func (me *middlewareRunner) RunUpdateMiddleware(middlewares []readDetailMw, inpu return nil } -func (me *middlewareRunner) RunDeleteMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.VclaimSep) error { +func (me *middlewareRunner) RunDeleteMiddleware(middlewares []deleteMw, input *e.DeleteDto, data *e.VclaimSep) error { for _, middleware := range middlewares { logData := pu.GetLogData(input, data) diff --git a/internal/use-case/bpjs-use-case/vclaim-sep/middleware.go b/internal/use-case/bpjs-use-case/vclaim-sep/middleware.go index 1ad0a853..08caba00 100644 --- a/internal/use-case/bpjs-use-case/vclaim-sep/middleware.go +++ b/internal/use-case/bpjs-use-case/vclaim-sep/middleware.go @@ -9,5 +9,10 @@ func init() { createPreMw = append(createPreMw, createMw{Name: "create-sep", Func: pvs.CreateSep}, ) - + readDetailPostMw = append(readDetailPostMw, + readDetailMw{Name: "read-detail-sep", Func: pvs.ReadDetailSep}, + ) + deletePreMw = append(deletePreMw, + deleteMw{Name: "delete-sep", Func: pvs.DeleteSep}, + ) } diff --git a/internal/use-case/bpjs-use-case/vclaim-sep/tycovar.go b/internal/use-case/bpjs-use-case/vclaim-sep/tycovar.go index 932bc355..be3b5d11 100644 --- a/internal/use-case/bpjs-use-case/vclaim-sep/tycovar.go +++ b/internal/use-case/bpjs-use-case/vclaim-sep/tycovar.go @@ -29,8 +29,12 @@ type readDetailMw struct { Func func(input *e.ReadDetailDto, data *e.VclaimSep, tx *gorm.DB) error } +type deleteMw struct { + Name string + Func func(input *e.DeleteDto, data *e.VclaimSep, tx *gorm.DB) error +} + type UpdateMw = readDetailMw -type DeleteMw = readDetailMw var createPreMw []createMw // preprocess middleware var createPostMw []createMw // postprocess middleware @@ -40,5 +44,5 @@ var readDetailPreMw []readDetailMw var readDetailPostMw []readDetailMw var updatePreMw []readDetailMw var updatePostMw []readDetailMw -var deletePreMw []readDetailMw -var deletePostMw []readDetailMw +var deletePreMw []deleteMw +var deletePostMw []deleteMw diff --git a/internal/use-case/main-use-case/generate-file/helper.go b/internal/use-case/main-use-case/generate-file/helper.go index 1f0d0bfd..3a6c3480 100644 --- a/internal/use-case/main-use-case/generate-file/helper.go +++ b/internal/use-case/main-use-case/generate-file/helper.go @@ -244,6 +244,10 @@ func generateResume(input GenerateDto, event pl.Event, tx *gorm.DB) (*ResponseDt return nil, err } + if !r.IsValidated() { + return nil, errors.New("resume is not validated") + } + if r.FileUrl != nil { if err := removeFile(string(input.EntityType_Code), *r.FileUrl); err != nil { return nil, err diff --git a/internal/use-case/main-use-case/resume/case.go b/internal/use-case/main-use-case/resume/case.go index cbc472f9..eab70280 100644 --- a/internal/use-case/main-use-case/resume/case.go +++ b/internal/use-case/main-use-case/resume/case.go @@ -50,7 +50,6 @@ func Create(input e.CreateDto) (*d.Data, error) { return errors.New("encounter is already done") } - input.Status_Code = erc.DVCNew if resData, err := CreateData(input, &event, tx); err != nil { return err } else { @@ -345,16 +344,16 @@ func UpdateStatusCode(input e.UpdateDto) (*d.Data, error) { switch input.Status_Code { case erc.DVCValidated: - if !enc.IsSameResponsibleDoctor(input.AuthInfo.Doctor_Code) { - return errors.New("validation doctor is not the same as encounter responsible doctor") - } - if data.IsNew() { return errors.New("resume need to be verified first") } if data.IsValidated() { return errors.New("resume already validated") } + if !enc.IsSameResponsibleDoctor(input.AuthInfo.Doctor_Code) { + return errors.New("validation doctor is not the same as encounter responsible doctor") + } + data.Status_Code = erc.DVCValidated err = tx.Save(&data).Error if err != nil { diff --git a/internal/use-case/main-use-case/resume/helper.go b/internal/use-case/main-use-case/resume/helper.go index edd45222..794ae214 100644 --- a/internal/use-case/main-use-case/resume/helper.go +++ b/internal/use-case/main-use-case/resume/helper.go @@ -6,12 +6,15 @@ package resume import ( e "simrs-vx/internal/domain/main-entities/resume" + + erc "simrs-vx/internal/domain/references/common" ) func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Resume) { var inputSrc *e.CreateDto if inputT, ok := any(input).(*e.CreateDto); ok { inputSrc = inputT + data.Status_Code = erc.DVCNew } else { inputTemp := any(input).(*e.UpdateDto) inputSrc = &inputTemp.CreateDto @@ -20,5 +23,4 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Resume) { data.Encounter_Id = inputSrc.Encounter_Id data.Doctor_Code = inputSrc.AuthInfo.Doctor_Code data.Value = inputSrc.Value - data.Status_Code = inputSrc.Status_Code } From 6c07024eb17c401ef82aa2d066817591a75d1117 Mon Sep 17 00:00:00 2001 From: Andrian Roshandy Date: Sat, 29 Nov 2025 20:50:06 +0700 Subject: [PATCH 08/38] Merge from 'dev' --- internal/infra/sync-consumer-cfg/tycovar.go | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 internal/infra/sync-consumer-cfg/tycovar.go diff --git a/internal/infra/sync-consumer-cfg/tycovar.go b/internal/infra/sync-consumer-cfg/tycovar.go new file mode 100644 index 00000000..d2146c2b --- /dev/null +++ b/internal/infra/sync-consumer-cfg/tycovar.go @@ -0,0 +1,11 @@ +package synccfg + +var O SyncConsumerUrlCfg = SyncConsumerUrlCfg{} // old + +type SyncConsumerUrlCfg struct { + Prefix string `yaml:"prefix"` + TargetHost string `yaml:"targetHost"` + Enable bool `yaml:"enable"` + Source string `yaml:"source"` + SecretKey string `yaml:"secretKey"` +} From 2a979f60a6ba1fe314114efc831cbc9cf752a4fa Mon Sep 17 00:00:00 2001 From: dpurbosakti Date: Mon, 1 Dec 2025 12:43:23 +0700 Subject: [PATCH 09/38] feat (vclaim/bpjs/jkn): add several endpoint --- .../domain/bpjs-entities/control-plan/dto.go | 7 ++ .../bpjs-entities/control-plan/entity.go | 22 +++++ internal/domain/bpjs-entities/referral/dto.go | 5 + .../domain/bpjs-entities/referral/entity.go | 96 +++++++++++++++++++ .../main-handler/control-plan/handler.go | 32 +++++++ .../interface/main-handler/main-handler.go | 16 +++- .../interface/main-handler/member/handler.go | 8 +- .../main-handler/monitoring/handler.go | 10 +- .../main-handler/reference/handler.go | 20 ++-- .../main-handler/referral/handler.go | 22 +++++ .../main-handler/vclaim-sep/handler.go | 6 +- .../bpjs-plugin/control-plan/helper.go | 11 +++ .../bpjs-plugin/control-plan/plugin.go | 37 +++++++ .../use-case/bpjs-plugin/referral/helper.go | 11 +++ .../use-case/bpjs-plugin/referral/plugin.go | 37 +++++++ .../use-case/bpjs-plugin/vclaim-sep/plugin.go | 4 +- .../bpjs-use-case/control-plan/case.go | 50 ++++++++++ .../control-plan/middleware-runner.go | 42 ++++++++ .../bpjs-use-case/control-plan/middleware.go | 12 +++ .../bpjs-use-case/control-plan/tycovar.go | 18 ++++ .../use-case/bpjs-use-case/referral/case.go | 50 ++++++++++ .../referral/middleware-runner.go | 42 ++++++++ .../bpjs-use-case/referral/middleware.go | 12 +++ .../bpjs-use-case/referral/tycovar.go | 18 ++++ 24 files changed, 561 insertions(+), 27 deletions(-) create mode 100644 internal/domain/bpjs-entities/control-plan/dto.go create mode 100644 internal/domain/bpjs-entities/control-plan/entity.go create mode 100644 internal/domain/bpjs-entities/referral/dto.go create mode 100644 internal/domain/bpjs-entities/referral/entity.go create mode 100644 internal/interface/main-handler/control-plan/handler.go create mode 100644 internal/interface/main-handler/referral/handler.go create mode 100644 internal/use-case/bpjs-plugin/control-plan/helper.go create mode 100644 internal/use-case/bpjs-plugin/control-plan/plugin.go create mode 100644 internal/use-case/bpjs-plugin/referral/helper.go create mode 100644 internal/use-case/bpjs-plugin/referral/plugin.go create mode 100644 internal/use-case/bpjs-use-case/control-plan/case.go create mode 100644 internal/use-case/bpjs-use-case/control-plan/middleware-runner.go create mode 100644 internal/use-case/bpjs-use-case/control-plan/middleware.go create mode 100644 internal/use-case/bpjs-use-case/control-plan/tycovar.go create mode 100644 internal/use-case/bpjs-use-case/referral/case.go create mode 100644 internal/use-case/bpjs-use-case/referral/middleware-runner.go create mode 100644 internal/use-case/bpjs-use-case/referral/middleware.go create mode 100644 internal/use-case/bpjs-use-case/referral/tycovar.go diff --git a/internal/domain/bpjs-entities/control-plan/dto.go b/internal/domain/bpjs-entities/control-plan/dto.go new file mode 100644 index 00000000..2290707d --- /dev/null +++ b/internal/domain/bpjs-entities/control-plan/dto.go @@ -0,0 +1,7 @@ +package controlplan + +type ReadListDto struct { + PathValue1 string `json:"-"` // jenis kontrol + PathValue2 string `json:"-"` // kode poli + PathValue3 string `json:"-"` // tanggal +} diff --git a/internal/domain/bpjs-entities/control-plan/entity.go b/internal/domain/bpjs-entities/control-plan/entity.go new file mode 100644 index 00000000..1a07379a --- /dev/null +++ b/internal/domain/bpjs-entities/control-plan/entity.go @@ -0,0 +1,22 @@ +package controlplan + +type Response struct { + MetaData MetaData `json:"metaData"` + Response *ResponseItems `json:"response"` // nullable +} + +type MetaData struct { + Code string `json:"code"` + Message string `json:"message"` +} + +type ResponseItems struct { + List []DoctorSchedule `json:"list"` +} + +type DoctorSchedule struct { + JadwalPraktek string `json:"jadwalPraktek"` + Kapasitas string `json:"kapasitas"` + KodeDokter string `json:"kodeDokter"` + NamaDokter string `json:"namaDokter"` +} diff --git a/internal/domain/bpjs-entities/referral/dto.go b/internal/domain/bpjs-entities/referral/dto.go new file mode 100644 index 00000000..16113d24 --- /dev/null +++ b/internal/domain/bpjs-entities/referral/dto.go @@ -0,0 +1,5 @@ +package referral + +type ReadDetailDto struct { + Number *string `json:"number"` // nomor rujukan +} diff --git a/internal/domain/bpjs-entities/referral/entity.go b/internal/domain/bpjs-entities/referral/entity.go new file mode 100644 index 00000000..8977ee31 --- /dev/null +++ b/internal/domain/bpjs-entities/referral/entity.go @@ -0,0 +1,96 @@ +package referral + +type Response struct { + MetaData MetaData `json:"metaData"` + Response *ReferralDetail `json:"response"` // nullable +} + +type MetaData struct { + Code string `json:"code"` + Message string `json:"message"` +} + +type ReferralDetail struct { + AsalFaskes string `json:"asalFaskes"` + Rujukan RujukanDetail `json:"rujukan"` +} + +type RujukanDetail struct { + Diagnosa Diagnosa `json:"diagnosa"` + Keluhan *string `json:"keluhan"` // nullable + NoKunjungan string `json:"noKunjungan"` + Pelayanan Pelayanan `json:"pelayanan"` + Peserta Peserta `json:"peserta"` + PoliRujukan Poli `json:"poliRujukan"` + ProvPerujuk Provider `json:"provPerujuk"` + TglKunjungan string `json:"tglKunjungan"` +} + +type Diagnosa struct { + Kode string `json:"kode"` + Nama string `json:"nama"` +} + +type Pelayanan struct { + Kode string `json:"kode"` + Nama string `json:"nama"` +} + +type Peserta struct { + Cob Cob `json:"cob"` + HakKelas KeteranganKode `json:"hakKelas"` + Informasi Informasi `json:"informasi"` + JenisPeserta KeteranganKode `json:"jenisPeserta"` + Mr Mr `json:"mr"` + Nama string `json:"nama"` + Nik string `json:"nik"` + NoKartu string `json:"noKartu"` + Pisa string `json:"pisa"` + ProvUmum Provider `json:"provUmum"` + Sex string `json:"sex"` + StatusPeserta KeteranganKode `json:"statusPeserta"` + TglCetakKartu string `json:"tglCetakKartu"` + TglLahir string `json:"tglLahir"` + TglTAT string `json:"tglTAT"` + TglTMT string `json:"tglTMT"` + Umur Umur `json:"umur"` +} + +type Cob struct { + NmAsuransi *string `json:"nmAsuransi"` // nullable + NoAsuransi *string `json:"noAsuransi"` + TglTAT *string `json:"tglTAT"` + TglTMT *string `json:"tglTMT"` +} + +type KeteranganKode struct { + Keterangan string `json:"keterangan"` + Kode string `json:"kode"` +} + +type Informasi struct { + Dinsos *string `json:"dinsos"` + ESep *string `json:"eSEP"` + NoSKTM *string `json:"noSKTM"` + ProlanisPRB *string `json:"prolanisPRB"` +} + +type Mr struct { + NoMR string `json:"noMR"` + NoTelepon string `json:"noTelepon"` +} + +type Provider struct { + Kode string `json:"kdProvider" json:"kode"` // API sometimes uses different keys + NmProvider string `json:"nmProvider" json:"nama"` +} + +type Poli struct { + Kode string `json:"kode"` + Nama string `json:"nama"` +} + +type Umur struct { + UmurSaatPelayanan string `json:"umurSaatPelayanan"` + UmurSekarang string `json:"umurSekarang"` +} diff --git a/internal/interface/main-handler/control-plan/handler.go b/internal/interface/main-handler/control-plan/handler.go new file mode 100644 index 00000000..382af58d --- /dev/null +++ b/internal/interface/main-handler/control-plan/handler.go @@ -0,0 +1,32 @@ +package controlplan + +import ( + "net/http" + + e "simrs-vx/internal/domain/bpjs-entities/control-plan" + u "simrs-vx/internal/use-case/bpjs-use-case/control-plan" + + d "github.com/karincake/dodol" + rw "github.com/karincake/risoles" +) + +func GetList(w http.ResponseWriter, r *http.Request) { + dto := e.ReadListDto{} + pValue1 := rw.ValidateString(w, "controlType", r.PathValue("controlType")) + if pValue1 == "" { + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "controlType is required"}, nil) + } + pValue2 := rw.ValidateString(w, "polyCode", r.PathValue("polyCode")) + if pValue2 == "" { + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "polyCode is required"}, nil) + } + pValue3 := rw.ValidateString(w, "date", r.PathValue("date")) + if pValue3 == "" { + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "date is required"}, nil) + } + dto.PathValue1 = pValue1 + dto.PathValue2 = pValue2 + dto.PathValue3 = pValue3 + res, err := u.ReadList(dto) + rw.DataResponse(w, res, err) +} diff --git a/internal/interface/main-handler/main-handler.go b/internal/interface/main-handler/main-handler.go index d374a8a8..362a5e8a 100644 --- a/internal/interface/main-handler/main-handler.go +++ b/internal/interface/main-handler/main-handler.go @@ -125,9 +125,11 @@ import ( "simrs-vx/internal/interface/main-handler/home" /******************** BPJS ********************/ + controlplan "simrs-vx/internal/interface/main-handler/control-plan" member "simrs-vx/internal/interface/main-handler/member" monitoring "simrs-vx/internal/interface/main-handler/monitoring" reference "simrs-vx/internal/interface/main-handler/reference" + referral "simrs-vx/internal/interface/main-handler/referral" vclaimsep "simrs-vx/internal/interface/main-handler/vclaim-sep" vclaimsephist "simrs-vx/internal/interface/main-handler/vclaim-sep-hist" vclaimsepprint "simrs-vx/internal/interface/main-handler/vclaim-sep-print" @@ -382,9 +384,9 @@ func SetRoutes() http.Handler { /******************** BPJS ********************/ hk.GroupRoutes("/v1/vclaim-sep", r, hk.MapHandlerFunc{ - "POST /": vclaimsep.O.Create, - "GET /{id}": vclaimsep.O.GetDetail, - "DELETE /{id}": vclaimsep.O.Delete, + "POST /": vclaimsep.O.Create, + "GET /{number}": vclaimsep.O.GetDetail, + "DELETE /{number}": vclaimsep.O.Delete, }) hk.GroupRoutes("/v1/vclaim-sep-hist", r, hk.MapHandlerFunc{ @@ -417,6 +419,14 @@ func SetRoutes() http.Handler { "GET /hist/{cardNumber}/{startDate}/{endDate}": monitoring.GetListHist, }) + hk.GroupRoutes("/v1/control-plan", r, hk.MapHandlerFunc{ + "GET /{controlType}/{polyCode}/{date}": controlplan.GetList, + }) + + hk.GroupRoutes("/v1/referral", r, hk.MapHandlerFunc{ + "GET /{number}": referral.GetList, + }) + ///// return cmw.SetCors(handlerlogger.SetLog(r)) } diff --git a/internal/interface/main-handler/member/handler.go b/internal/interface/main-handler/member/handler.go index 80881ee3..3b4c3ba1 100644 --- a/internal/interface/main-handler/member/handler.go +++ b/internal/interface/main-handler/member/handler.go @@ -14,11 +14,11 @@ func GetListByBpjsNumber(w http.ResponseWriter, r *http.Request) { dto := e.ReadListDto{} pValue1 := rw.ValidateString(w, "cardNumber", r.PathValue("cardNumber")) if pValue1 == "" { - rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "cardNumber is required"}, nil) + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "cardNumber is required"}, nil) } pValue2 := rw.ValidateString(w, "sepDate", r.PathValue("sepDate")) if pValue2 == "" { - rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "sepDate is required"}, nil) + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "sepDate is required"}, nil) } dto.ReferenceType = e.RTBpjs dto.PathValue1 = pValue1 @@ -31,11 +31,11 @@ func GetListByNik(w http.ResponseWriter, r *http.Request) { dto := e.ReadListDto{} pValue1 := rw.ValidateString(w, "nik", r.PathValue("nik")) if pValue1 == "" { - rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "nik is required"}, nil) + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "nik is required"}, nil) } pValue2 := rw.ValidateString(w, "sepDate", r.PathValue("sepDate")) if pValue2 == "" { - rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "sepDate is required"}, nil) + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "sepDate is required"}, nil) } dto.ReferenceType = e.RTNik dto.PathValue1 = pValue1 diff --git a/internal/interface/main-handler/monitoring/handler.go b/internal/interface/main-handler/monitoring/handler.go index cf82a5b9..aa8acdf4 100644 --- a/internal/interface/main-handler/monitoring/handler.go +++ b/internal/interface/main-handler/monitoring/handler.go @@ -14,11 +14,11 @@ func GetListVisit(w http.ResponseWriter, r *http.Request) { dto := e.ReadListDto{} pValue1 := rw.ValidateString(w, "date", r.PathValue("date")) if pValue1 == "" { - rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "date is required"}, nil) + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "date is required"}, nil) } pValue2 := rw.ValidateString(w, "serviceType", r.PathValue("serviceType")) if pValue2 == "" { - rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "serviceType is required"}, nil) + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "serviceType is required"}, nil) } dto.ReferenceType = e.RTVisit dto.PathValue1 = pValue1 @@ -31,15 +31,15 @@ func GetListHist(w http.ResponseWriter, r *http.Request) { dto := e.ReadListDto{} pValue1 := rw.ValidateString(w, "cardNumber", r.PathValue("cardNumber")) if pValue1 == "" { - rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "cardNumber is required"}, nil) + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "cardNumber is required"}, nil) } pValue2 := rw.ValidateString(w, "startDate", r.PathValue("startDate")) if pValue2 == "" { - rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "startDate is required"}, nil) + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "startDate is required"}, nil) } pValue3 := rw.ValidateString(w, "endDate", r.PathValue("endDate")) if pValue3 == "" { - rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "endDate is required"}, nil) + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "endDate is required"}, nil) } dto.ReferenceType = e.RTHist dto.PathValue1 = pValue1 diff --git a/internal/interface/main-handler/reference/handler.go b/internal/interface/main-handler/reference/handler.go index fb972af1..b9948eb3 100644 --- a/internal/interface/main-handler/reference/handler.go +++ b/internal/interface/main-handler/reference/handler.go @@ -21,7 +21,7 @@ func GetListCities(w http.ResponseWriter, r *http.Request) { dto := e.ReadListDto{} pValue := rw.ValidateString(w, "provinceCode", r.PathValue("provinceCode")) if pValue == "" { - rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "provinceCode is required"}, nil) + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "provinceCode is required"}, nil) } dto.ReferenceType = e.RTCities dto.PathValue1 = pValue @@ -33,7 +33,7 @@ func GetListDistrict(w http.ResponseWriter, r *http.Request) { dto := e.ReadListDto{} pValue := rw.ValidateString(w, "regencyCode", r.PathValue("regencyCode")) if pValue == "" { - rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "regencyCode is required"}, nil) + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "regencyCode is required"}, nil) } dto.ReferenceType = e.RTDistrict dto.PathValue1 = pValue @@ -45,7 +45,7 @@ func GetListDiagnose(w http.ResponseWriter, r *http.Request) { dto := e.ReadListDto{} pValue := rw.ValidateString(w, "keyword", r.PathValue("keyword")) if pValue == "" { - rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "keyword is required"}, nil) + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "keyword is required"}, nil) } dto.ReferenceType = e.RTDiagnose dto.PathValue1 = pValue @@ -64,7 +64,7 @@ func GetListMedicinePrb(w http.ResponseWriter, r *http.Request) { dto := e.ReadListDto{} pValue := rw.ValidateString(w, "keyword", r.PathValue("keyword")) if pValue == "" { - rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "keyword is required"}, nil) + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "keyword is required"}, nil) } dto.ReferenceType = e.RTMedicinePrb dto.PathValue1 = pValue @@ -76,7 +76,7 @@ func GetListUnit(w http.ResponseWriter, r *http.Request) { dto := e.ReadListDto{} pValue := rw.ValidateString(w, "unitCode", r.PathValue("unitCode")) if pValue == "" { - rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "unitCode is required"}, nil) + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "unitCode is required"}, nil) } dto.ReferenceType = e.RTUnit dto.PathValue1 = pValue @@ -88,11 +88,11 @@ func GetListHealthcare(w http.ResponseWriter, r *http.Request) { dto := e.ReadListDto{} pValue1 := rw.ValidateString(w, "healthcare", r.PathValue("healthcare")) if pValue1 == "" { - rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "healthcare is required"}, nil) + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "healthcare is required"}, nil) } pValue2 := rw.ValidateString(w, "healthcareType", r.PathValue("healthcareType")) if pValue2 == "" { - rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "healthcareType is required"}, nil) + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "healthcareType is required"}, nil) } dto.ReferenceType = e.RTHealthcare dto.PathValue1 = pValue1 @@ -105,15 +105,15 @@ func GetListDoctor(w http.ResponseWriter, r *http.Request) { dto := e.ReadListDto{} pValue1 := rw.ValidateString(w, "serviceType", r.PathValue("serviceType")) if pValue1 == "" { - rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "serviceType is required"}, nil) + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "serviceType is required"}, nil) } pValue2 := rw.ValidateString(w, "serviceDate", r.PathValue("serviceDate")) if pValue2 == "" { - rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "serviceDate is required"}, nil) + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "serviceDate is required"}, nil) } pValue3 := rw.ValidateString(w, "specialistCode", r.PathValue("specialistCode")) if pValue3 == "" { - rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "specialistCode is required"}, nil) + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "specialistCode is required"}, nil) } dto.PathValue1 = pValue1 dto.PathValue2 = pValue2 diff --git a/internal/interface/main-handler/referral/handler.go b/internal/interface/main-handler/referral/handler.go new file mode 100644 index 00000000..94b66a78 --- /dev/null +++ b/internal/interface/main-handler/referral/handler.go @@ -0,0 +1,22 @@ +package referral + +import ( + "net/http" + + e "simrs-vx/internal/domain/bpjs-entities/referral" + u "simrs-vx/internal/use-case/bpjs-use-case/referral" + + d "github.com/karincake/dodol" + rw "github.com/karincake/risoles" +) + +func GetList(w http.ResponseWriter, r *http.Request) { + dto := e.ReadDetailDto{} + number := rw.ValidateString(w, "number", r.PathValue("number")) + if number == "" { + rw.WriteJSON(w, http.StatusBadRequest, d.IS{"message": "number is required"}, nil) + } + dto.Number = &number + res, err := u.ReadDetail(dto) + rw.DataResponse(w, res, err) +} diff --git a/internal/interface/main-handler/vclaim-sep/handler.go b/internal/interface/main-handler/vclaim-sep/handler.go index ed11e257..1529e2d8 100644 --- a/internal/interface/main-handler/vclaim-sep/handler.go +++ b/internal/interface/main-handler/vclaim-sep/handler.go @@ -30,12 +30,12 @@ func (obj myBase) Create(w http.ResponseWriter, r *http.Request) { // } func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) { - id := rw.ValidateInt(w, "id", r.PathValue("id")) - if id <= 0 { + number := rw.ValidateString(w, "number", r.PathValue("number")) + if number <= "" { return } dto := e.ReadDetailDto{} - dto.Id = uint(id) + dto.Number = &number res, err := u.ReadDetail(dto) rw.DataResponse(w, res, err) } diff --git a/internal/use-case/bpjs-plugin/control-plan/helper.go b/internal/use-case/bpjs-plugin/control-plan/helper.go new file mode 100644 index 00000000..15af7238 --- /dev/null +++ b/internal/use-case/bpjs-plugin/control-plan/helper.go @@ -0,0 +1,11 @@ +package controlplan + +import ( + "fmt" + e "simrs-vx/internal/domain/bpjs-entities/control-plan" + ibpjs "simrs-vx/internal/infra/bpjs" +) + +func endpointMapper(input *e.ReadListDto) string { + return fmt.Sprintf("%sRencanaKontrol/jadwalDokter?jeniskontrol=%s&kodepoli=%s&tanggalkontrol=%s", ibpjs.O.BaseUrl, input.PathValue1, input.PathValue2, input.PathValue3) +} diff --git a/internal/use-case/bpjs-plugin/control-plan/plugin.go b/internal/use-case/bpjs-plugin/control-plan/plugin.go new file mode 100644 index 00000000..276750ca --- /dev/null +++ b/internal/use-case/bpjs-plugin/control-plan/plugin.go @@ -0,0 +1,37 @@ +package controlplan + +import ( + "encoding/json" + "fmt" + "io" + "net/http" + e "simrs-vx/internal/domain/bpjs-entities/control-plan" + + "gorm.io/gorm" +) + +func ReadList(input *e.ReadListDto, data *e.Response, tx *gorm.DB) error { + endpoint := endpointMapper(input) + req, err := http.NewRequest("GET", endpoint, nil) + if err != nil { + return err + } + req.Header.Set("Content-Type", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return err + } + + if err := json.Unmarshal(body, &data); err != nil { + return fmt.Errorf("failed to parse response JSON: %w", err) + } + + return nil +} diff --git a/internal/use-case/bpjs-plugin/referral/helper.go b/internal/use-case/bpjs-plugin/referral/helper.go new file mode 100644 index 00000000..169834be --- /dev/null +++ b/internal/use-case/bpjs-plugin/referral/helper.go @@ -0,0 +1,11 @@ +package referral + +import ( + "fmt" + e "simrs-vx/internal/domain/bpjs-entities/referral" + ibpjs "simrs-vx/internal/infra/bpjs" +) + +func endpointMapper(input *e.ReadDetailDto) string { + return fmt.Sprintf("%sRujukan/RS/%s", ibpjs.O.BaseUrl, *input.Number) +} diff --git a/internal/use-case/bpjs-plugin/referral/plugin.go b/internal/use-case/bpjs-plugin/referral/plugin.go new file mode 100644 index 00000000..225181e4 --- /dev/null +++ b/internal/use-case/bpjs-plugin/referral/plugin.go @@ -0,0 +1,37 @@ +package referral + +import ( + "encoding/json" + "fmt" + "io" + "net/http" + e "simrs-vx/internal/domain/bpjs-entities/referral" + + "gorm.io/gorm" +) + +func ReadDetail(input *e.ReadDetailDto, data *e.Response, tx *gorm.DB) error { + endpoint := endpointMapper(input) + req, err := http.NewRequest("GET", endpoint, nil) + if err != nil { + return err + } + req.Header.Set("Content-Type", "application/json") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return err + } + + if err := json.Unmarshal(body, &data); err != nil { + return fmt.Errorf("failed to parse response JSON: %w", err) + } + + return nil +} diff --git a/internal/use-case/bpjs-plugin/vclaim-sep/plugin.go b/internal/use-case/bpjs-plugin/vclaim-sep/plugin.go index 70097b74..4588029f 100644 --- a/internal/use-case/bpjs-plugin/vclaim-sep/plugin.go +++ b/internal/use-case/bpjs-plugin/vclaim-sep/plugin.go @@ -66,7 +66,7 @@ func CreateSep(input *e.CreateDto, data *e.VclaimSep, tx *gorm.DB) error { } func ReadDetailSep(input *e.ReadDetailDto, data *e.VclaimSep, tx *gorm.DB) error { - endpoint := fmt.Sprintf("sep/%s", *data.Number) + endpoint := fmt.Sprintf("sep/%s", input.Number) req, err := http.NewRequest("GET", ibpjs.O.BaseUrl+endpoint, nil) if err != nil { return err @@ -96,7 +96,7 @@ func ReadDetailSep(input *e.ReadDetailDto, data *e.VclaimSep, tx *gorm.DB) error func DeleteSep(input *e.DeleteDto, data *e.VclaimSep, tx *gorm.DB) error { payload := e.SepDeleteRequest{} - payload.Request.TSep.NoSep = *data.Number + payload.Request.TSep.NoSep = *input.Number payload.Request.TSep.User = "Coba Ws" jsonPayload, err := json.Marshal(payload) diff --git a/internal/use-case/bpjs-use-case/control-plan/case.go b/internal/use-case/bpjs-use-case/control-plan/case.go new file mode 100644 index 00000000..764ea2ea --- /dev/null +++ b/internal/use-case/bpjs-use-case/control-plan/case.go @@ -0,0 +1,50 @@ +package controlplan + +import ( + e "simrs-vx/internal/domain/bpjs-entities/control-plan" + + dg "github.com/karincake/apem/db-gorm-pg" + + pl "simrs-vx/pkg/logger" + pu "simrs-vx/pkg/use-case-helper" + + "gorm.io/gorm" +) + +const source = "control-plan" + +func ReadList(input e.ReadListDto) (*e.Response, error) { + var data e.Response + 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 + } + + 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 &data, nil +} diff --git a/internal/use-case/bpjs-use-case/control-plan/middleware-runner.go b/internal/use-case/bpjs-use-case/control-plan/middleware-runner.go new file mode 100644 index 00000000..4c3db3d8 --- /dev/null +++ b/internal/use-case/bpjs-use-case/control-plan/middleware-runner.go @@ -0,0 +1,42 @@ +package controlplan + +import ( + e "simrs-vx/internal/domain/bpjs-entities/control-plan" + pl "simrs-vx/pkg/logger" + pu "simrs-vx/pkg/use-case-helper" + + "gorm.io/gorm" +) + +type middlewareRunner struct { + Event *pl.Event + Tx *gorm.DB + MwType pu.MWType +} + +// NewMiddlewareExecutor creates a new middleware executor +func newMiddlewareRunner(event *pl.Event, tx *gorm.DB) *middlewareRunner { + return &middlewareRunner{ + Event: event, + Tx: tx, + } +} + +func (me *middlewareRunner) RunReadListMiddleware(middlewares []readListMw, input *e.ReadListDto, data *e.Response) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) setMwType(mwType pu.MWType) { + me.MwType = mwType +} diff --git a/internal/use-case/bpjs-use-case/control-plan/middleware.go b/internal/use-case/bpjs-use-case/control-plan/middleware.go new file mode 100644 index 00000000..3478bb19 --- /dev/null +++ b/internal/use-case/bpjs-use-case/control-plan/middleware.go @@ -0,0 +1,12 @@ +package controlplan + +import ( + pcp "simrs-vx/internal/use-case/bpjs-plugin/control-plan" +) + +func init() { + readListPreMw = append(readListPreMw, + readListMw{Name: "readList-control-plan", Func: pcp.ReadList}, + ) + +} diff --git a/internal/use-case/bpjs-use-case/control-plan/tycovar.go b/internal/use-case/bpjs-use-case/control-plan/tycovar.go new file mode 100644 index 00000000..ea2b39a9 --- /dev/null +++ b/internal/use-case/bpjs-use-case/control-plan/tycovar.go @@ -0,0 +1,18 @@ +/* +member is peserta +*/ +package controlplan + +import ( + "gorm.io/gorm" + + e "simrs-vx/internal/domain/bpjs-entities/control-plan" +) + +type readListMw struct { + Name string + Func func(input *e.ReadListDto, data *e.Response, tx *gorm.DB) error +} + +var readListPreMw []readListMw // .. +var readListPostMw []readListMw // .. diff --git a/internal/use-case/bpjs-use-case/referral/case.go b/internal/use-case/bpjs-use-case/referral/case.go new file mode 100644 index 00000000..8818dc58 --- /dev/null +++ b/internal/use-case/bpjs-use-case/referral/case.go @@ -0,0 +1,50 @@ +package referral + +import ( + e "simrs-vx/internal/domain/bpjs-entities/referral" + + dg "github.com/karincake/apem/db-gorm-pg" + + pl "simrs-vx/pkg/logger" + pu "simrs-vx/pkg/use-case-helper" + + "gorm.io/gorm" +) + +const source = "referral" + +func ReadDetail(input e.ReadDetailDto) (*e.Response, error) { + var data e.Response + 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 + } + + 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 &data, nil +} diff --git a/internal/use-case/bpjs-use-case/referral/middleware-runner.go b/internal/use-case/bpjs-use-case/referral/middleware-runner.go new file mode 100644 index 00000000..10c26241 --- /dev/null +++ b/internal/use-case/bpjs-use-case/referral/middleware-runner.go @@ -0,0 +1,42 @@ +package referral + +import ( + e "simrs-vx/internal/domain/bpjs-entities/referral" + pl "simrs-vx/pkg/logger" + pu "simrs-vx/pkg/use-case-helper" + + "gorm.io/gorm" +) + +type middlewareRunner struct { + Event *pl.Event + Tx *gorm.DB + MwType pu.MWType +} + +// NewMiddlewareExecutor creates a new middleware executor +func newMiddlewareRunner(event *pl.Event, tx *gorm.DB) *middlewareRunner { + return &middlewareRunner{ + Event: event, + Tx: tx, + } +} + +func (me *middlewareRunner) RunReadDetailMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.Response) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) setMwType(mwType pu.MWType) { + me.MwType = mwType +} diff --git a/internal/use-case/bpjs-use-case/referral/middleware.go b/internal/use-case/bpjs-use-case/referral/middleware.go new file mode 100644 index 00000000..0296ae5a --- /dev/null +++ b/internal/use-case/bpjs-use-case/referral/middleware.go @@ -0,0 +1,12 @@ +package referral + +import ( + pr "simrs-vx/internal/use-case/bpjs-plugin/referral" +) + +func init() { + readDetailPreMw = append(readDetailPreMw, + readDetailMw{Name: "read-detail-referral", Func: pr.ReadDetail}, + ) + +} diff --git a/internal/use-case/bpjs-use-case/referral/tycovar.go b/internal/use-case/bpjs-use-case/referral/tycovar.go new file mode 100644 index 00000000..b1950977 --- /dev/null +++ b/internal/use-case/bpjs-use-case/referral/tycovar.go @@ -0,0 +1,18 @@ +/* +member is peserta +*/ +package referral + +import ( + "gorm.io/gorm" + + e "simrs-vx/internal/domain/bpjs-entities/referral" +) + +type readDetailMw struct { + Name string + Func func(input *e.ReadDetailDto, data *e.Response, tx *gorm.DB) error +} + +var readDetailPreMw []readDetailMw +var readDetailPostMw []readDetailMw From c3fae2ec52a48c68c83ac00945692ade377f0ba7 Mon Sep 17 00:00:00 2001 From: dpurbosakti Date: Mon, 1 Dec 2025 12:47:57 +0700 Subject: [PATCH 10/38] fix encounter id on read detail --- internal/use-case/main-use-case/generate-file/helper.go | 2 +- internal/use-case/main-use-case/resume/case.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/use-case/main-use-case/generate-file/helper.go b/internal/use-case/main-use-case/generate-file/helper.go index 3a6c3480..6edd34d8 100644 --- a/internal/use-case/main-use-case/generate-file/helper.go +++ b/internal/use-case/main-use-case/generate-file/helper.go @@ -284,7 +284,7 @@ func generateResume(input GenerateDto, event pl.Event, tx *gorm.DB) (*ResponseDt func generateResumeTemplateData(resume er.Resume, event pl.Event, tx *gorm.DB) (*ResumePDF, error) { // get encounter includes := "Patient,Patient.Person,Patient.Person.BirthRegency,Patient.Person.Contacts" - encounter, err := ue.ReadDetailData(ee.ReadDetailDto{Id: uint16(*resume.Encounter_Id), Includes: includes}, &event) + encounter, err := ue.ReadDetailData(ee.ReadDetailDto{Id: *resume.Encounter_Id, Includes: includes}, &event) if err != nil { return nil, err } diff --git a/internal/use-case/main-use-case/resume/case.go b/internal/use-case/main-use-case/resume/case.go index eab70280..8f771794 100644 --- a/internal/use-case/main-use-case/resume/case.go +++ b/internal/use-case/main-use-case/resume/case.go @@ -332,7 +332,7 @@ func UpdateStatusCode(input e.UpdateDto) (*d.Data, error) { return err } - enc, err := ue.ReadDetailData(ee.ReadDetailDto{Id: uint16(*data.Encounter_Id)}, &event, tx) + enc, err := ue.ReadDetailData(ee.ReadDetailDto{Id: *data.Encounter_Id}, &event, tx) if err != nil { return err } From ece6a0b7a5d6e7c613c3357b1f574470f3eb7275 Mon Sep 17 00:00:00 2001 From: dpurbosakti Date: Mon, 1 Dec 2025 15:14:20 +0700 Subject: [PATCH 11/38] add screening --- .../migrations/20251201081333.sql | 13 ++ cmd/main-migration/migrations/atlas.sum | 115 +++++++++--------- .../domain/main-entities/screening/dto.go | 86 +++++++++++++ .../domain/main-entities/screening/entity.go | 17 +++ .../domain/references/clinical/clinical.go | 4 + internal/interface/migration/main-entities.go | 2 + 6 files changed, 180 insertions(+), 57 deletions(-) create mode 100644 cmd/main-migration/migrations/20251201081333.sql create mode 100644 internal/domain/main-entities/screening/dto.go create mode 100644 internal/domain/main-entities/screening/entity.go diff --git a/cmd/main-migration/migrations/20251201081333.sql b/cmd/main-migration/migrations/20251201081333.sql new file mode 100644 index 00000000..876b32b7 --- /dev/null +++ b/cmd/main-migration/migrations/20251201081333.sql @@ -0,0 +1,13 @@ +-- Create "Screening" table +CREATE TABLE "public"."Screening" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "Encounter_Id" bigint NULL, + "Employee_Id" bigint NULL, + "Type" text NULL, + "Value" text NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "fk_Screening_Employee" FOREIGN KEY ("Employee_Id") REFERENCES "public"."Employee" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION +); diff --git a/cmd/main-migration/migrations/atlas.sum b/cmd/main-migration/migrations/atlas.sum index 449ff1d4..5753c626 100644 --- a/cmd/main-migration/migrations/atlas.sum +++ b/cmd/main-migration/migrations/atlas.sum @@ -1,4 +1,4 @@ -h1:Y8m8OmsumTaAfXfYYXHlZS0+OqbAqFfM3a55nmibOUE= +h1:6lWgIJo0vUBd7Bo4B3YMvyDpJsOTVzVfqRQ03ad9r1s= 20250904105930.sql h1:MEM6blCgke9DzWQSTnLzasbPIrcHssNNrJqZpSkEo6k= 20250904141448.sql h1:J8cmYNk4ZrG9fhfbi2Z1IWz7YkfvhFqTzrLFo58BPY0= 20250908062237.sql h1:Pu23yEW/aKkwozHoOuROvHS/GK4ngARJGdO7FB7HZuI= @@ -75,59 +75,60 @@ h1:Y8m8OmsumTaAfXfYYXHlZS0+OqbAqFfM3a55nmibOUE= 20251106040137.sql h1:ppcqkVoT0o9jZcjI/TN7LuaPxXhJQhnIXEJtloP/46o= 20251106041333.sql h1:2JkxyelQ/EeB+boL5bfpnzefw32ttEGKvKchtQjWmAU= 20251106042006.sql h1:ruppYa1kAJQUU3ufQBbKGMcXrGbGJJiRPclT+dNc/YQ= -20251106050412.sql h1:MiEMJ1HCFYnalKuq3Z38xJeogfBAMqsTv2sG4EF8dDw= -20251106063418.sql h1:y3veDJPjKekOWLCZek/LgQwXPRhZtOppTfUXiqoL95s= -20251106071906.sql h1:/TUZA3XpMY23qEJXdkTwlzrNMvSSl6JJniPcgAttBaw= -20251106073157.sql h1:78txeibJ602DMD7huD618ZSMt6phSRzDNPTlo0PGyrc= -20251106074218.sql h1:8Xz7WywrtUnSxOHhlal53gG9rE7r86LFUt5zBFe/mIs= -20251106081846.sql h1:jp91Bf5bxGXMiUB1VIuN6y768vb2iWwow44WfCE5J5k= -20251106082844.sql h1:RHYzRO4G1fSWwf+xc/3QezZ/Iil67cZPIgNpNz3TNhQ= -20251106090021.sql h1:dFDk6mq+zjbYWmfWIrHf9DiKvvoXHjrr0++zssMTWP8= -20251106144745.sql h1:aHcr23iBFqCHer5D/SsPMXBCLjGqUYvWYfRU8jSJgIw= -20251107012049.sql h1:hu/7NHhnAkT4xK0RNtqmMDdH1Bo5EZbl7itDRjiCT+g= -20251107064812.sql h1:sfCXDQYnMf0ddrQ9oYljWJLLSt9NJjJV6o8VS3p7aZE= -20251107064937.sql h1:DlYGJ9LZFwZyR7jBP5zaGB128aIc4HAixBKPYCz9EkY= -20251107071420.sql h1:ynCdZAd2utLl+FhtWZwtahNXgIVOvuk3s/rOq7lfXA4= -20251107074318.sql h1:WE9cPhibWtZ0dbu1VEGirTeY6ijFYGMNhHdBtM32kOc= -20251107075050.sql h1:8tvneruqdynDOaJK1+0z4CH7YXZStZpGdqwIeOMLik4= -20251107080604.sql h1:8c4jd4Tql7tcdhbI9NS0tgvN+ADu9FnCf8wMUbmW7A0= -20251107081830.sql h1:SAAe3lmsm9vGXuSEsDdl7ad0EAxP5CMmFRDEgp9M7yY= -20251107091033.sql h1:JLdX/u7GUdBfjrPrMSNAqc8HtSoj0YA9iW9Vc6FJZdw= -20251107091209.sql h1:CzhYtwAwT+GHrbqcagnJE+v3mbl/rObf1IJaLCKlzrs= -20251107091541.sql h1:+3ZyWJTftDY2JeWThXuIxGWpUBnyMPyOyY4jBjdWYJI= -20251110012217.sql h1:f4Z8TuGc+XMSJ+Ekn4/PeHRE2FlHWkc5gKPJB0hAX7c= -20251110012306.sql h1:ENPyI6Kjdk6qKJQb0yJ6MCTDPAmO1WD/uhKuCSl+jYo= -20251110052049.sql h1:OrQ0acnyoQLKnTitZfnBcVr5jDslF59OFLaqT7SpdVs= -20251110062042.sql h1:9KwldQt0NpVPR86L0T4hlkfHAGau+7CiZYgu5rF+yhg= -20251110063202.sql h1:A117DuZmZ6U0jWHA3DISnr+yvBjKIr1ObrUr047YezQ= -20251110063633.sql h1:qTiC0F19JnhUIXF4LGJQ21jEV6kKGyhTr1x2kimFqPQ= -20251110085551.sql h1:HZcJM0RSC6HBaUSjKBE8MgDG8Vn9f3LmwA/OnT9Cp7I= -20251110091516.sql h1:W3AQhQLgirEWuCObbLl+Prdrbq6k6EEY1xcoWsmbog4= -20251110091948.sql h1:3tsITMrZr/T+L4wqUMz8sHS229jCJl4T0Nu3dMccxH8= -20251110092729.sql h1:uU+k88RH/e0Ns4/SmJl03RVYPscBAPuiLfxR6CJqaf0= -20251110093522.sql h1:O7upSj8VNjzvroL4IU59bfxKATOkAVGBArcUbVNq9aM= -20251110100258.sql h1://JSArUMNI3/gAtYDx2VN94C198SFW0ANjgs+p6eCRM= -20251110100545.sql h1:ENPOqeJYRpMI4e8VCKwaQgaql8se6pIidAhG2cjskBg= -20251110155448.sql h1:VW9KE0jxWy4flZ28sdXmhY6JWd6eKAX/cVL8KWRVii4= -20251111072601.sql h1:99WWzGjcDDFNC2cHRfPu4MBLWNrgPMY5HAYUbmIcVRA= -20251111073546.sql h1:iIGwFNfUgStdczw/PXTH3SD84xAyxrbZICofc3M8TMk= -20251111074148.sql h1:mzkezSKwCV2bTZ/0BHiTCX5qAy4uHpwar1xzwAH15Ko= -20251111074652.sql h1:lYh4/3BHV24pgPC0pP4RUKb+XtL/6AsZGPItRpnzBiQ= -20251111082257.sql h1:+cIZ1lf8HYGSL6t6U88plLKk8nOO1YVdV7h3YOM84ds= -20251111111017.sql h1:xzlhR2xLfOj4ddYlesS+bpEeDrxiAf5ILNOspsbZjBU= -20251113101344.sql h1:vSzThY3p6XYTj0dJ2uFVkHmlytyrFAnGE58CJLx364I= -20251113120533.sql h1:lfjgdqRGo/EohrVw8sWlFbDjh3ASTsfQ6pr3qjafqvc= -20251114062746.sql h1:6DLYjfJ60PkAABZTXvOwSE+xrU25oyoX7gpYlBnA9cw= -20251117005942.sql h1:0XoJKca8IOaB9QKFVF/qPY7jKcIgh6m/LODQuE06SAs= -20251117075427.sql h1:LhY2urosfoSu1/vkHmgsNP4JA4DuWBs9gL59yMqcF8M= -20251118074929.sql h1:3RWBD6BziQVw6WSfthgoVuhTELHER9NrIuZm4hY/F1A= -20251119063438.sql h1:EVTG3ZrHjCmM95YPASZTRPiwHrG6e33A2vO4hLSAaBQ= -20251119065730.sql h1:s98wnZOCW6NbnwDS3H53XIQ60u6B9bDwBLNvy5+Rn64= -20251119072302.sql h1:ZL+VHekLYqgNtOFKlj02WHrAk11dtTxQkmyTKE8IOzY= -20251119072450.sql h1:SiJy2vpSvoPFw4J1SW7HjGSJzrqR62NsjRYAeabV+kc= -20251120005512.sql h1:hJUaWXYJ3HiSquBTw8OKhymjA4O43ehAMGfiOY8W87Q= -20251120074415.sql h1:dNmcqZHqfZwi/wtYvO/pSFgImN2scXL0p/7g0+HLp0s= -20251121033803.sql h1:onlddYGo+tQdGaEdJPqdsx3sncGnwEvqMSCksF6vjjI= -20251124071457.sql h1:ikQLIXFikUbkUd55uJBmEvqLGEC9t0db+Om4TQsWP7M= -20251125125303.sql h1:OLKbNPO36AHtIDursW9AeBvf60sahQKC1iOjHmpx0MA= -20251126064057.sql h1:6al3PTWbw/WGiBcrRrVWppOMLtG+eRaH/qSLbnmh1kQ= +20251106050412.sql h1:1002KYtHd8AwrQTMewbs/PPHDylHDghigE/3S7PVdMA= +20251106063418.sql h1:jPW/gBnbFl4RO39lQ0ZMDtYA6xbhyD6CgQupT50HmaY= +20251106071906.sql h1:leYGKxR3EQn794aOehf0sd/ZPmOnvBMZPy5/anGmRB4= +20251106073157.sql h1:KASMzjjjk5UB7Zj8lCRtM1utc4ZnDjlnpZbtTe3vONE= +20251106074218.sql h1:Z5q5deOvLaZDPhiVTN9st3/s56RepBa2YOyrMXBdj4A= +20251106081846.sql h1:P+VsWwhGt60adDIZuE/Aa38JVp/yX1rnsdpXpxASodw= +20251106082844.sql h1:Dmi5A8i9frQZvdXYPwc7f8CisZtBH8liSXq1rI6z1iM= +20251106090021.sql h1:4JwdKgO8T46YhyWVJUxpRIwudBDlG8QN1brSOYmgQ20= +20251106144745.sql h1:nqnQCzGrVJaq8ilOEOGXeRUL1dolj+OPWKuP8A92FRA= +20251107012049.sql h1:Pff4UqltGS3clSlGr0qq8CQM56L29wyxY0FC/N/YAhU= +20251107064812.sql h1:GB9a0ZfMYTIoGNmKUG+XcYUsTnRMFfT4/dAD71uCPc4= +20251107064937.sql h1:IC5pw1Ifj30hiE6dr5NMHXaSHoQI+vRd40N5ABgBHRI= +20251107071420.sql h1:9NO3iyLEXEtWa2kSRjM/8LyzuVIk6pdFL2SuheWjB08= +20251107074318.sql h1:7fHbSRrdjOmHh/xwnjCLwoiB5cW5zeH+uxLV0vZbkIA= +20251107075050.sql h1:np+3uTOnU9QNtK7Knaw8eRMhkyB9AwrtSNHphOBxbHY= +20251107080604.sql h1:cXDBLPJDVWLTG6yEJqkJsOQ7p7VYxLM2SY+mwO8qSHo= +20251107081830.sql h1:/S7OQZo4ZnK80t28g/JyiOTZtmWG/dP5Wg2zXNMQ/iE= +20251107091033.sql h1:/cbkF1nO/IjNSIfDJJx456KJtQ9rWFXOBFAkR/M2xiE= +20251107091209.sql h1:jrLQOUeV8ji2fg0pnEcs1bw4ANUxzTSMXC/rrHLIY+M= +20251107091541.sql h1:6UqbhQQRmzA2+eKu5lIvkwOkk+lH70QLZC8Pjpjcq68= +20251110012217.sql h1:C9HpX0iyHzKjyNv/5DSAn2MCHj6MX4p5UQ/NrY7QD0w= +20251110012306.sql h1:J54yb27d30LBbYp9n1P66gFVRlxPguKu0kxmWIBBG8g= +20251110052049.sql h1:232T2x8xTczJl9nk4jxJpZXhoOGYthhxjJ7nK8Jd8vg= +20251110062042.sql h1:WnfVUXrzYoj8qdkkjO9/JQQ8agGd4GfSHQdMjo7LDAg= +20251110063202.sql h1:hSzGfwVMWa6q3vwIQZUkxKgBNCzHjB+6GKy54zfV+oQ= +20251110063633.sql h1:/VpofIAqNS1CnazEnpW/+evbzn9Kew3xDW48r57M+Xg= +20251110085551.sql h1:bFZwSmfvVbTUr/enWB82WqjG88gpqcZ6s45btUvO0uo= +20251110091516.sql h1:KkJMwPQuaZQhiqnKrNQrgP12gw9rV8T3P2o3mtGTcvY= +20251110091948.sql h1:I4odAYrJdvNf1jPw6ppDC0XdI7v6vKBACg/ABwUgA7I= +20251110092729.sql h1:l1out8soEmVP6dNjaIOtGYo6QDcoJZRI8X1sjZ5ZGmo= +20251110093522.sql h1:nsz8jCxGjEdr/bz9g+4ozfZzIP803xONjVmucad1GMc= +20251110100258.sql h1:IBqt1VZj5WjQ+l9aAFGHOCCBtzb03KlLLihFLut7itg= +20251110100545.sql h1:6/LV7751iyKxE2xI6vO1zly+aHUwxXD/IBwLcVpKxqM= +20251110155448.sql h1:kFPobJB+cpflsXBAWUwy3lohuWvrb/VRlXnhJWl7i3Y= +20251111072601.sql h1:ch8F+yVhsSM5xY+TwMLY3PxdLa4Wuhtj76oyw79R7Js= +20251111073546.sql h1:cCv0NPscADAOBahRVqtDWFs6G2t7n+4a+RwlF8vk/c4= +20251111074148.sql h1:70TsV83u1gQ5TktI13K7NQiyCCa35Td2aR6CNtKUa4U= +20251111074652.sql h1:ddfQ/sRKMezPM75xBFTGytUQX5AwZ3znrJVpg73gKPA= +20251111082257.sql h1:ZsdLY1ROouos0l3oS0lkeSiuKLEUGbVvBhpcM2AVhkw= +20251111111017.sql h1:qrJ93dNtQwcuAvpsP/lAK/H63C4cinXrsVaPmWsTqkU= +20251113101344.sql h1:xaOZvAUP1fFfnO+syEFOzJUIg5lTfBe5AWHPbBWuCLA= +20251113120533.sql h1:f3/U1Ve2yF2zSMhkt+xtwF8wUYfUKYwgbNeGfE37EW4= +20251114062746.sql h1:FInLaEFQByESEwFJKuKnuUSTKmcDpi3ZXaxkKwz2+D8= +20251117005942.sql h1:wD3BWrUSmo1HlW16V3lkaBkJvbAZ0fNk77te7J9NhOc= +20251117075427.sql h1:TqU9VKZa3I8YNXUGQWY3WVBYN+1FvyyaKy0hB1jgAho= +20251118074929.sql h1:p1KsWqCuR1JXA/jVO5BmOhCcaQ8clT7t0YRszAhPFbg= +20251119063438.sql h1:NVGM0X/LHD37EaPl8SNzkNiZDJ7AB1QR+LLwLh6WRdg= +20251119065730.sql h1:U5lzk1WvMB0bw3kwckou7jkEt4bwdYItwHr2Vxqe7w4= +20251119072302.sql h1:qCuI2WMEMF/XNbjV+RXPjBnuCKLu1Fia+mR9HiLWBIs= +20251119072450.sql h1:Xg+bTwqGyKPNFEQhJylvpz1wifdfmDJvcAq6vmNf0Ng= +20251120005512.sql h1:Ek6qpacAI/qVuTYxKno+uJyzn7s5z9pf3t7VA8gTzm4= +20251120074415.sql h1:NNUeJVA03EeBHJhHqPXEZoDv/PnC6yK1/cRhmukyaJo= +20251121033803.sql h1:/vfvFX/3pzSCIHnSbMUT9EMBDykOpVkvyfeTEle9Vas= +20251124071457.sql h1:qg2dhCL9YwD13xnfJ175lW/p6MGfzFKaBqd908FByRc= +20251125125303.sql h1:4JSFv1Pmhbe9tqpLXgO63OwYnGsalStgUXKVWPyc1YE= +20251126064057.sql h1:vAdhz5Nn/gGJy0UKZAEldeXv8HpHtJU/t8ygDVIbTsU= +20251201081333.sql h1:1946fD7iMnf18FjYzVNoHu6suWSDMfjaF2R7jx5gjo0= diff --git a/internal/domain/main-entities/screening/dto.go b/internal/domain/main-entities/screening/dto.go new file mode 100644 index 00000000..5dfed2c7 --- /dev/null +++ b/internal/domain/main-entities/screening/dto.go @@ -0,0 +1,86 @@ +package screening + +import ( + // std + + // internal - lib + pa "simrs-vx/internal/lib/auth" + + // internal - domain - base-entities + ecore "simrs-vx/internal/domain/base-entities/core" + + // internal - domain - main-entities + eem "simrs-vx/internal/domain/main-entities/employee" + + erc "simrs-vx/internal/domain/references/clinical" +) + +type CreateDto struct { + Encounter_Id *uint `json:"encounter_id"` + Employee_Id *uint `json:"-"` + Type erc.ScreeningFormTypeCode `json:"type"` + Value *string `json:"value"` + + pa.AuthInfo +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Pagination ecore.Pagination +} + +type FilterDto struct { + Encounter_Id *uint `json:"encounter-id"` + Employee_Id *uint `json:"employee-id"` + Type erc.ScreeningFormTypeCode `json:"type"` + Value *string `json:"value"` +} + +type ReadDetailDto struct { + Id uint16 `json:"id"` +} + +type UpdateDto struct { + Id uint16 `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint16 `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.Main + Encounter_Id *uint `json:"encounter_id"` + Employee_Id *uint `json:"employee_id"` + Employee *eem.Employee `json:"employee,omitempty"` + Type erc.ScreeningFormTypeCode `json:"type"` + Value *string `json:"value"` +} + +func (d Screening) ToResponse() ResponseDto { + resp := ResponseDto{ + Encounter_Id: d.Encounter_Id, + Employee_Id: d.Employee_Id, + Employee: d.Employee, + Type: d.Type, + Value: d.Value, + } + resp.Main = d.Main + return resp +} + +func ToResponseList(data []Screening) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/screening/entity.go b/internal/domain/main-entities/screening/entity.go new file mode 100644 index 00000000..ebdb735b --- /dev/null +++ b/internal/domain/main-entities/screening/entity.go @@ -0,0 +1,17 @@ +package screening + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + eem "simrs-vx/internal/domain/main-entities/employee" + + erc "simrs-vx/internal/domain/references/clinical" +) + +type Screening struct { + ecore.Main // adjust this according to the needs + Encounter_Id *uint `json:"encounter_id"` + Employee_Id *uint `json:"employee_id"` + Employee *eem.Employee `json:"employee,omitempty" gorm:"foreignKey:Employee_Id;references:Id"` + Type erc.ScreeningFormTypeCode `json:"type"` + Value *string `json:"value"` +} diff --git a/internal/domain/references/clinical/clinical.go b/internal/domain/references/clinical/clinical.go index 30a4fe8a..4755eea1 100644 --- a/internal/domain/references/clinical/clinical.go +++ b/internal/domain/references/clinical/clinical.go @@ -22,6 +22,7 @@ type ( LearnMethodCode string LangClassCode string TranslatorSrcCode string + ScreeningFormTypeCode string ) const ( @@ -187,6 +188,9 @@ const ( TSCTeam TranslatorSrcCode = "team" // Tim Penerjemah TSCFamily TranslatorSrcCode = "family" // Keluarga + + SFTCA ScreeningFormTypeCode = "form-a" // Formu A + SFTCB ScreeningFormTypeCode = "form-b" // Formu B ) type Soapi struct { diff --git a/internal/interface/migration/main-entities.go b/internal/interface/migration/main-entities.go index 0b4a62fd..a59e9b2e 100644 --- a/internal/interface/migration/main-entities.go +++ b/internal/interface/migration/main-entities.go @@ -85,6 +85,7 @@ import ( resume "simrs-vx/internal/domain/main-entities/resume" room "simrs-vx/internal/domain/main-entities/room" sbar "simrs-vx/internal/domain/main-entities/sbar" + screening "simrs-vx/internal/domain/main-entities/screening" soapi "simrs-vx/internal/domain/main-entities/soapi" specialist "simrs-vx/internal/domain/main-entities/specialist" specialistintern "simrs-vx/internal/domain/main-entities/specialist-intern" @@ -217,5 +218,6 @@ func getMainEntities() []any { &vclaimsepcontrolletter.VclaimSepControlLetter{}, &resume.Resume{}, &vclaimreference.VclaimReference{}, + &screening.Screening{}, } } From 32461141ab6465ec6015bb996f4fe9c850147274 Mon Sep 17 00:00:00 2001 From: vanilia Date: Mon, 1 Dec 2025 16:26:45 +0700 Subject: [PATCH 12/38] add t_diagnosadanterapi and reference --- .../domain/references/clinical/clinical.go | 31 +++++++++++ .../t-diagnosadanterapi/entity.go | 51 +++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 internal/domain/simgos-entities/t-diagnosadanterapi/entity.go diff --git a/internal/domain/references/clinical/clinical.go b/internal/domain/references/clinical/clinical.go index 30a4fe8a..25619eab 100644 --- a/internal/domain/references/clinical/clinical.go +++ b/internal/domain/references/clinical/clinical.go @@ -311,3 +311,34 @@ type HeadToToe struct { Neuron string `json:"neuron,omitempty"` BodyOthers string `json:"body-others,omitempty"` } + +type SoapiSrc struct { + Id string `json:"id,omitempty"` + Code string `json:"code,omitempty"` + Name string `json:"name,omitempty"` + IndName string `json:"indName,omitempty"` +} + +type EarlyMedicValue struct { + Vaccinated bool `json:"vaccinated,omitempty"` + CaseStatus string `json:"case-status,omitempty"` + EncounterStatus string `json:"encounter-status,omitempty"` + PrimaryComplain string `json:"pri-complain,omitempty"` + CurrentDiseaseHistory string `json:"cur-disea-hist,omitempty"` + SpO2 int `json:"spo2,omitempty"` + SystolicBloodPressure int `json:"syst-bp,omitempty"` + DiastolicBloodPressure int `json:"diast-bp,omitempty"` + RespiratoryRate int `json:"resp-rate,omitempty"` + Pulse int `json:"pulse,omitempty"` + Weight int `json:"weight,omitempty"` + BloodType string `json:"blood-type,omitempty"` + Temperature int `json:"temp,omitempty"` + Height int `json:"height,omitempty"` + PhysicalExamination string `json:"physical-exam,omitempty"` + DiagnoseSrc []SoapiSrc `json:"diagnoseSrc,omitempty"` + ProcedureSrc []SoapiSrc `json:"procedureSrc,omitempty"` + EarlyMedicDiagnose string `json:"early-med-diag,omitempty"` + EarlyMedicPlan string `json:"early-med-plan,omitempty"` + Therapy string `json:"therapy,omitempty"` + ExpectedOutcome []SoapiSrc `json:"expected-outcome,omitempty"` +} diff --git a/internal/domain/simgos-entities/t-diagnosadanterapi/entity.go b/internal/domain/simgos-entities/t-diagnosadanterapi/entity.go new file mode 100644 index 00000000..76be4c0f --- /dev/null +++ b/internal/domain/simgos-entities/t-diagnosadanterapi/entity.go @@ -0,0 +1,51 @@ +package t_diagnosadanterapi + +import "time" + +type DiagnosaDanTerapi struct { + Idxterapi int64 `gorm:"column:idxterapi;primaryKey"` + Idxdaftar int64 `gorm:"column:idxdaftar"` + Nomr string `gorm:"column:nomr"` + Tanggal time.Time `gorm:"column:tanggal"` + TekananDarah string `gorm:"column:tekanan_darah"` + GolonganDarah string `gorm:"column:golongan_darah"` + TinggiBadan float64 `gorm:"column:tinggi_badan"` + BeratBadan float64 `gorm:"column:berat_badan"` + Diagnosa string `gorm:"column:diagnosa"` + Komplikasi string `gorm:"column:komplikasi"` + Terapi string `gorm:"column:terapi"` + Anamnesa string `gorm:"column:anamnesa"` + Kdpoly int `gorm:"column:kdpoly"` + Kddokter int `gorm:"column:kddokter"` + Kdtujuanrujuk int `gorm:"column:kdtujuanrujuk"` + Nip string `gorm:"column:nip"` + IcdCode string `gorm:"column:icd_code"` + KunjunganBl int16 `gorm:"column:kunjungan_bl"` + KasusBl int16 `gorm:"column:kasus_bl"` + Icdcm string `gorm:"column:icdcm"` + Icd9 string `gorm:"column:icd_9"` + Klb int16 `gorm:"column:klb"` + Bedah int16 `gorm:"column:bedah"` + Jenis int16 `gorm:"column:jenis"` + Perawat string `gorm:"column:perawat"` + Status string `gorm:"column:status"` + PemeriksaanFisik string `gorm:"column:pemeriksaan_fisik"` + RiwayatPasien string `gorm:"column:riwayat_pasien"` + TindakanMedis string `gorm:"column:tindakan_medis"` + Rajal int16 `gorm:"column:rajal"` + UserBatal string `gorm:"column:user_batal"` + TglBatal *time.Time `gorm:"column:tgl_batal"` + SudahVaksin string `gorm:"column:sudah_vaksin"` + CreatedAt time.Time `gorm:"column:created_at"` + DenyutJantung string `gorm:"column:denyut_jantung"` + Pernapasan string `gorm:"column:pernapasan"` + Suhu string `gorm:"column:suhu"` + Sp02 string `gorm:"column:sp02"` + TujuanPerawatan string `gorm:"column:tujuan_perawatan"` + TargetCapaian string `gorm:"column:target_capaian"` +} + +// TableName overrides the table name used by GORM +func (DiagnosaDanTerapi) TableName() string { + return "t_diagnosadanterapi" +} From c98385792a243db01388e98074b818ad701dab5d Mon Sep 17 00:00:00 2001 From: vanilia Date: Mon, 1 Dec 2025 16:35:20 +0700 Subject: [PATCH 13/38] add sync entities for soapi --- .../migrations/20251201093443.sql | 36 +++++++++++++++++++ .../migrations/atlas.sum | 5 +-- internal/domain/sync-entities/soapi/entity.go | 29 +++++++++++++++ .../migration/simgossync-entities.go | 4 +++ 4 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 cmd/simgos-sync-migration/migrations/20251201093443.sql create mode 100644 internal/domain/sync-entities/soapi/entity.go diff --git a/cmd/simgos-sync-migration/migrations/20251201093443.sql b/cmd/simgos-sync-migration/migrations/20251201093443.sql new file mode 100644 index 00000000..1ecce17e --- /dev/null +++ b/cmd/simgos-sync-migration/migrations/20251201093443.sql @@ -0,0 +1,36 @@ +-- Create "SoapiLink" table +CREATE TABLE "public"."SoapiLink" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "Simx_Id" bigint NULL, + "Simgos_Id" bigint NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "uni_SoapiLink_Simgos_Id" UNIQUE ("Simgos_Id"), + CONSTRAINT "uni_SoapiLink_Simx_Id" UNIQUE ("Simx_Id") +); +-- Create "SoapiSimgosLog" table +CREATE TABLE "public"."SoapiSimgosLog" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "Value" text NULL, + "Date" timestamptz NULL, + "Status" text NULL, + "ErrMessage" text NULL, + PRIMARY KEY ("Id") +); +-- Create "SoapiSimxLog" table +CREATE TABLE "public"."SoapiSimxLog" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "Value" text NULL, + "Date" timestamptz NULL, + "Status" text NULL, + "ErrMessage" text NULL, + PRIMARY KEY ("Id") +); diff --git a/cmd/simgos-sync-migration/migrations/atlas.sum b/cmd/simgos-sync-migration/migrations/atlas.sum index 497ac414..e82a5610 100644 --- a/cmd/simgos-sync-migration/migrations/atlas.sum +++ b/cmd/simgos-sync-migration/migrations/atlas.sum @@ -1,7 +1,8 @@ -h1:UdPzQZ17yyNN9HVuyrFFHj5KjLj4m6/e7s9frkdpQVU= +h1:6YZBXq/r79I5tuYyY1+CBzhZsSeukHSs8MyHCC5QuV4= 20251113035508.sql h1:rjDlu6yDdy5xv6nrCOr7NialrLSLT23pzduYNq29Hf0= 20251114071129.sql h1:Z0GQ5bJo3C+tplaWzxT8n3J9HLkEaVsRVp5nn7bmYow= 20251117041601.sql h1:l/RPG5mObqCSBjO4mzG+wTq2ieSycvlfOSz4czpUdWY= 20251118082246.sql h1:xLUwA+EvKWIg3X/TJvu7rqbtBzONiINfag5NJpMV29E= 20251118082915.sql h1:hP6FmUVFuADIN2cDg2Z1l7Wx7PQRb+IYQDvKD7J8VAM= -20251126115527.sql h1:+2bp2nWTTqaPpKKfy5ZYSr6b1nEUXFG3tIw4r3OEnAQ= +20251126115527.sql h1:Bvg+Y7k+h5s+/UaezUyJb7J7uzEJS7U5Z/RoCixcUtI= +20251201093443.sql h1:m18tksKG3OzbkxXkhfKUUqbkxnJ0VBPi3Cw34Tbywyc= diff --git a/internal/domain/sync-entities/soapi/entity.go b/internal/domain/sync-entities/soapi/entity.go new file mode 100644 index 00000000..0a1315c7 --- /dev/null +++ b/internal/domain/sync-entities/soapi/entity.go @@ -0,0 +1,29 @@ +package Soapi + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + erc "simrs-vx/internal/domain/references/common" + "time" +) + +type SoapiLink struct { + ecore.Main + Simx_Id uint `json:"simx_id" gorm:"unique"` + Simgos_Id uint `json:"simgos_id" gorm:"unique"` +} + +type SoapiSimxLog struct { + ecore.Main + Value *string `json:"value"` + Date *time.Time `json:"date"` + Status erc.ProcessStatusCode `json:"status"` + ErrMessage *string `json:"errMessage"` +} + +type SoapiSimgosLog struct { + ecore.Main + Value *string `json:"value"` + Date *time.Time `json:"date"` + Status erc.ProcessStatusCode `json:"status"` + ErrMessage *string `json:"errMessage"` +} diff --git a/internal/interface/migration/simgossync-entities.go b/internal/interface/migration/simgossync-entities.go index 7b37a842..2c479521 100644 --- a/internal/interface/migration/simgossync-entities.go +++ b/internal/interface/migration/simgossync-entities.go @@ -7,6 +7,7 @@ import ( installation "simrs-vx/internal/domain/sync-entities/installation" internalreference "simrs-vx/internal/domain/sync-entities/internal-reference" patient "simrs-vx/internal/domain/sync-entities/patient" + soapi "simrs-vx/internal/domain/sync-entities/soapi" specialist "simrs-vx/internal/domain/sync-entities/specialist" subspecialist "simrs-vx/internal/domain/sync-entities/subspecialist" unit "simrs-vx/internal/domain/sync-entities/unit" @@ -38,5 +39,8 @@ func getSyncEntities() []any { &internalreference.InternalReferenceLink{}, &internalreference.InternalReferenceSimxLog{}, &internalreference.InternalReferenceSimgosLog{}, + &soapi.SoapiLink{}, + &soapi.SoapiSimxLog{}, + &soapi.SoapiSimgosLog{}, } } From df3ed7919e53c491851ea926f46ac9cdb85cf194 Mon Sep 17 00:00:00 2001 From: vanilia Date: Mon, 1 Dec 2025 17:03:24 +0700 Subject: [PATCH 14/38] adjust diagnosaandterapi entity --- .../t-diagnosadanterapi/entity.go | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/internal/domain/simgos-entities/t-diagnosadanterapi/entity.go b/internal/domain/simgos-entities/t-diagnosadanterapi/entity.go index 76be4c0f..3c3c3e59 100644 --- a/internal/domain/simgos-entities/t-diagnosadanterapi/entity.go +++ b/internal/domain/simgos-entities/t-diagnosadanterapi/entity.go @@ -3,8 +3,8 @@ package t_diagnosadanterapi import "time" type DiagnosaDanTerapi struct { - Idxterapi int64 `gorm:"column:idxterapi;primaryKey"` - Idxdaftar int64 `gorm:"column:idxdaftar"` + Idxterapi uint `gorm:"column:idxterapi;primaryKey"` + Idxdaftar uint `gorm:"column:idxdaftar"` Nomr string `gorm:"column:nomr"` Tanggal time.Time `gorm:"column:tanggal"` TekananDarah string `gorm:"column:tekanan_darah"` @@ -15,24 +15,24 @@ type DiagnosaDanTerapi struct { Komplikasi string `gorm:"column:komplikasi"` Terapi string `gorm:"column:terapi"` Anamnesa string `gorm:"column:anamnesa"` - Kdpoly int `gorm:"column:kdpoly"` - Kddokter int `gorm:"column:kddokter"` - Kdtujuanrujuk int `gorm:"column:kdtujuanrujuk"` + Kdpoly uint `gorm:"column:kdpoly"` + Kddokter uint `gorm:"column:kddokter"` + Kdtujuanrujuk uint `gorm:"column:kdtujuanrujuk"` Nip string `gorm:"column:nip"` IcdCode string `gorm:"column:icd_code"` - KunjunganBl int16 `gorm:"column:kunjungan_bl"` - KasusBl int16 `gorm:"column:kasus_bl"` + KunjunganBl uint `gorm:"column:kunjungan_bl"` + KasusBl uint `gorm:"column:kasus_bl"` Icdcm string `gorm:"column:icdcm"` Icd9 string `gorm:"column:icd_9"` - Klb int16 `gorm:"column:klb"` - Bedah int16 `gorm:"column:bedah"` - Jenis int16 `gorm:"column:jenis"` + Klb uint `gorm:"column:klb"` + Bedah uint `gorm:"column:bedah"` + Jenis uint `gorm:"column:jenis"` Perawat string `gorm:"column:perawat"` Status string `gorm:"column:status"` PemeriksaanFisik string `gorm:"column:pemeriksaan_fisik"` RiwayatPasien string `gorm:"column:riwayat_pasien"` TindakanMedis string `gorm:"column:tindakan_medis"` - Rajal int16 `gorm:"column:rajal"` + Rajal uint `gorm:"column:rajal"` UserBatal string `gorm:"column:user_batal"` TglBatal *time.Time `gorm:"column:tgl_batal"` SudahVaksin string `gorm:"column:sudah_vaksin"` From 8306e1217e2db071f433d52fa7ce1090d13a9104 Mon Sep 17 00:00:00 2001 From: Munawwirul Jamal Date: Mon, 1 Dec 2025 17:47:59 +0700 Subject: [PATCH 15/38] feat/action-report: done --- .../migrations/20251201104439.sql | 19 ++ cmd/main-migration/migrations/atlas.sum | 5 +- .../domain/main-entities/action-report/dto.go | 89 ++++++ .../main-entities/action-report/entity.go | 45 +++ .../domain/references/clinical/clinical.go | 66 ++++ .../references/organization/organization.go | 5 + .../main-handler/action-report/handler.go | 80 +++++ .../interface/main-handler/main-handler.go | 2 + internal/interface/migration/main-entities.go | 2 + .../main-use-case/action-report/case.go | 295 ++++++++++++++++++ .../main-use-case/action-report/helper.go | 28 ++ .../main-use-case/action-report/lib.go | 140 +++++++++ .../action-report/middleware-runner.go | 103 ++++++ .../main-use-case/action-report/middleware.go | 9 + .../main-use-case/action-report/tycovar.go | 44 +++ 15 files changed, 930 insertions(+), 2 deletions(-) create mode 100644 cmd/main-migration/migrations/20251201104439.sql create mode 100644 internal/domain/main-entities/action-report/dto.go create mode 100644 internal/domain/main-entities/action-report/entity.go create mode 100644 internal/interface/main-handler/action-report/handler.go create mode 100644 internal/use-case/main-use-case/action-report/case.go create mode 100644 internal/use-case/main-use-case/action-report/helper.go create mode 100644 internal/use-case/main-use-case/action-report/lib.go create mode 100644 internal/use-case/main-use-case/action-report/middleware-runner.go create mode 100644 internal/use-case/main-use-case/action-report/middleware.go create mode 100644 internal/use-case/main-use-case/action-report/tycovar.go diff --git a/cmd/main-migration/migrations/20251201104439.sql b/cmd/main-migration/migrations/20251201104439.sql new file mode 100644 index 00000000..50f60b6b --- /dev/null +++ b/cmd/main-migration/migrations/20251201104439.sql @@ -0,0 +1,19 @@ +-- Create "ActionReport" table +CREATE TABLE "public"."ActionReport" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "Encounter_Id" bigint NULL, + "Date" character varying(20) NOT NULL, + "Doctor_Code" character varying(10) NULL, + "Operator_Employe_Id" bigint NULL, + "Assistant_Employe_Id" bigint NULL, + "Instrumentor_Employe_Id" bigint NULL, + "Diagnose" character varying(1024) NULL, + "Procedures" character varying(10240) NULL, + "Nurse_Code" character varying(10) NULL, + "Value" text NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "fk_ActionReport_Encounter" FOREIGN KEY ("Encounter_Id") REFERENCES "public"."Encounter" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION +); diff --git a/cmd/main-migration/migrations/atlas.sum b/cmd/main-migration/migrations/atlas.sum index 5753c626..c02dc2b8 100644 --- a/cmd/main-migration/migrations/atlas.sum +++ b/cmd/main-migration/migrations/atlas.sum @@ -1,4 +1,4 @@ -h1:6lWgIJo0vUBd7Bo4B3YMvyDpJsOTVzVfqRQ03ad9r1s= +h1:oIkzjGilKCqqfLGlvMc2I2WwJ8zQgdMeTWy25k1uaLI= 20250904105930.sql h1:MEM6blCgke9DzWQSTnLzasbPIrcHssNNrJqZpSkEo6k= 20250904141448.sql h1:J8cmYNk4ZrG9fhfbi2Z1IWz7YkfvhFqTzrLFo58BPY0= 20250908062237.sql h1:Pu23yEW/aKkwozHoOuROvHS/GK4ngARJGdO7FB7HZuI= @@ -131,4 +131,5 @@ h1:6lWgIJo0vUBd7Bo4B3YMvyDpJsOTVzVfqRQ03ad9r1s= 20251124071457.sql h1:qg2dhCL9YwD13xnfJ175lW/p6MGfzFKaBqd908FByRc= 20251125125303.sql h1:4JSFv1Pmhbe9tqpLXgO63OwYnGsalStgUXKVWPyc1YE= 20251126064057.sql h1:vAdhz5Nn/gGJy0UKZAEldeXv8HpHtJU/t8ygDVIbTsU= -20251201081333.sql h1:1946fD7iMnf18FjYzVNoHu6suWSDMfjaF2R7jx5gjo0= +20251201081333.sql h1:PoC8ADRdwDuohDTB74yW/DaB42igdYa4B6humbrEJBk= +20251201104439.sql h1:EIBP67qeQWEYMdMOM/gouXzkAM4R3vSkmuw4Fe8usOs= diff --git a/internal/domain/main-entities/action-report/dto.go b/internal/domain/main-entities/action-report/dto.go new file mode 100644 index 00000000..1edb4a73 --- /dev/null +++ b/internal/domain/main-entities/action-report/dto.go @@ -0,0 +1,89 @@ +package actionreport + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + ee "simrs-vx/internal/domain/main-entities/encounter" + + pa "simrs-vx/internal/lib/auth" +) + +type CreateDto struct { + Encounter_Id uint64 `json:"encounter_id"` + Date string `json:"date"` + Doctor_Code string `json:"doctor_code"` + Operator_Employe_Id *uint `json:"operator_employe_id"` + Assistant_Employe_Id *uint `json:"assistant_employe_id"` + Instrumentor_Employe_Id *uint `json:"instrumentor_employe_id"` + Diagnose *string `json:"diagnose"` + Nurse_Code *string `json:"nurse_code"` + Value string `json:"value"` + + pa.AuthInfo +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Pagination ecore.Pagination +} + +type FilterDto struct { + Encounter_Id *uint `json:"encounter-id"` +} + +type ReadDetailDto struct { + Id uint16 `json:"id"` +} + +type UpdateDto struct { + Id uint16 `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint16 `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.Main + Encounter_Id uint64 `json:"encounter_id"` + Encounter *ee.Encounter `json:"encounter,omitempty"` + Date string `json:"date"` + Doctor_Code string `json:"doctor_code"` + Operator_Employe_Id *uint `json:"operator_employe_id"` + Assistant_Employe_Id *uint `json:"assistant_employe_id"` + Instrumentor_Employe_Id *uint `json:"instrumentor_employe_id"` + Diagnose *string `json:"diagnose"` + Nurse_Code *string `json:"nurse_code"` + Value *string `json:"value"` +} + +func (d ActionReport) ToResponse() ResponseDto { + resp := ResponseDto{ + Encounter_Id: d.Encounter_Id, + Encounter: d.Encounter, + Date: d.Date, + Doctor_Code: d.Doctor_Code, + Operator_Employe_Id: d.Operator_Employe_Id, + Assistant_Employe_Id: d.Assistant_Employe_Id, + Instrumentor_Employe_Id: d.Instrumentor_Employe_Id, + Nurse_Code: d.Nurse_Code, + Value: &d.Value, + } + resp.Main = d.Main + return resp +} + +func ToResponseList(data []ActionReport) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/action-report/entity.go b/internal/domain/main-entities/action-report/entity.go new file mode 100644 index 00000000..3437136e --- /dev/null +++ b/internal/domain/main-entities/action-report/entity.go @@ -0,0 +1,45 @@ +package actionreport + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + ee "simrs-vx/internal/domain/main-entities/encounter" +) + +type ActionReport struct { + ecore.Main // adjust this according to the needs + Encounter_Id uint64 `json:"encounter_id" gorm:"foreignKey"` + Encounter *ee.Encounter `json:"doctor,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"` + Date string `json:"date" gorm:"not null;size:20"` + Doctor_Code string `json:"doctor_code" gorm:"size:10"` + Operator_Employe_Id *uint `json:"operator_employe_id"` + Assistant_Employe_Id *uint `json:"assistant_employe_id"` + Instrumentor_Employe_Id *uint `json:"instrumentor_employe_id"` + Diagnose *string `json:"diagnose" gorm:"size:1024"` + Procedures *string `json:"procedures" gorm:"size:10240"` + Nurse_Code *string `json:"nurse_code" gorm:"size:10"` + + Value string `json:"value"` + // SurgerySize_Code *string `json:"surgerySize_code" gorm:"size:10"` + // Billing_Code *string `json:"billing_code" gorm:"size:10"` + // SurgerySystem_Code *string `json:"surgerySystem_code" gorm:"size:10"` + // StartAt *string `json:"startAt" gorm:"size:20"` + // EndAt *string `json:"endAt" gorm:"size:20"` + // AnesthesiaStartAt *string `json:"anesthesiaStartAt" gorm:"size:20"` + // AnesthesiaEndAt *string `json:"anesthesiaEndAt" gorm:"size:20"` + // SurgeryType_Code *string `json:"surgeryType_code" gorm:"size:10"` + // SurgeryStage_Code *string `json:"surgeryStage_code" gorm:"size:10"` + // BornMortality_Code *string `json:"bornMortality_code" gorm:"size:10"` + // BornLocation_Code *string `json:"bornLocation_code" gorm:"size:10"` + // Weight *string `json:"weight" gorm:"size:10"` + // BornNotes *string `json:"bornNotes" gorm:"size:1024"` + // Description *string `json:"notes" gorm:"size:1024"` + // BleedingAmount *uint16 `json:"bleedingAmount" gorm:"size:10"` + // BloodInType_Code *string `json:"bloodInType_code" gorm:"size:10"` + // BloodInAmount *uint16 `json:"bloodInAmount" gorm:"size:10"` + // Brand *string `json:"brand" gorm:"size:100"` + // ImplantName *string `json:"implantName" gorm:"size:100"` + // ImplantRegisterNumber *string `json:"implantRegisterNumber" gorm:"size:100"` + // ImplantCompanionName *string `json:"implantCompanionName" gorm:"size:100"` + // SpecimentDest_Code *string `json:"specimentDest" gorm:"size:100"` + // TissueInfo *string `json:"tissueInfo" gorm:"size:100"` +} diff --git a/internal/domain/references/clinical/clinical.go b/internal/domain/references/clinical/clinical.go index 4755eea1..7a3a2ec1 100644 --- a/internal/domain/references/clinical/clinical.go +++ b/internal/domain/references/clinical/clinical.go @@ -23,6 +23,13 @@ type ( LangClassCode string TranslatorSrcCode string ScreeningFormTypeCode string + SurgerySizeCode string + SurgerySystemCode string + SurgeryTypeCode string + SurgeryStageCode string + BornMortalityCode string + BornLocationCode string + SpecimentDestCode string ) const ( @@ -191,6 +198,38 @@ const ( SFTCA ScreeningFormTypeCode = "form-a" // Formu A SFTCB ScreeningFormTypeCode = "form-b" // Formu B + + SSCSmall SurgerySizeCode = "" + SSCMedium SurgerySizeCode = "" + SSCLarge SurgerySizeCode = "" + SSCSpecial SurgerySizeCode = "" + + SSyCCito SurgerySystemCode = "" + SSyCUrgent SurgerySystemCode = "" + SSyCEfective SurgerySystemCode = "" + SSyCSpecial SurgerySystemCode = "" + + STCClean SurgeryTypeCode = "" + STCCleanCtm SurgeryTypeCode = "" + STCUncleanCtm SurgeryTypeCode = "" + STCUnclean SurgeryTypeCode = "" + + SStCFirst SurgeryStageCode = "" + SStCRepeat SurgeryStageCode = "" + + BMCAlive BornMortalityCode = "" + BMCDead BornMortalityCode = "" + + BLCExtMiw BornLocationCode = "" + BLCExtDoc BornLocationCode = "" + BLCTradMiw BornLocationCode = "" + BLCLocalMed BornLocationCode = "" + BLCExtParamedic BornLocationCode = "" + + SDCAp SpecimentDestCode = "" + SDCMicro SpecimentDestCode = "" + SDCLab SpecimentDestCode = "" + SDCNone SpecimentDestCode = "" ) type Soapi struct { @@ -315,3 +354,30 @@ type HeadToToe struct { Neuron string `json:"neuron,omitempty"` BodyOthers string `json:"body-others,omitempty"` } + +type RecordAction struct { + Procedures []string `json:"procedures"` + SurgerySize_Code *string `json:"surgerySize_code"` + Billing_Code *string `json:"billing_code"` + SurgerySystem_Code *string `json:"surgerySystem_code"` + StartAt *string `json:"startAt"` + EndAt *string `json:"endAt"` + AnesthesiaStartAt *string `json:"anesthesiaStartAt"` + AnesthesiaEndAt *string `json:"anesthesiaEndAt"` + SurgeryType_Code *string `json:"surgeryType_code"` + SurgeryStage_Code *string `json:"surgeryStage_code"` + BornMortality_Code *string `json:"bornMortality_code"` + BornLocation_Code *string `json:"bornLocation_code"` + Weight *string `json:"weight"` + BornNotes *string `json:"bornNotes" gorm:"size:1024"` + Description *string `json:"notes" gorm:"size:1024"` + BleedingAmount *uint16 `json:"bleedingAmount"` + BloodInType_Code *string `json:"bloodInType_code"` + BloodInAmount *uint16 `json:"bloodInAmount"` + Brand *string `json:"brand" gorm:"size:100"` + ImplantName *string `json:"implantName" gorm:"size:100"` + ImplantRegisterNumber *string `json:"implantRegisterNumber" gorm:"size:100"` + ImplantCompanionName *string `json:"implantCompanionName" gorm:"size:100"` + SpecimentDest_Code *string `json:"specimentDest" gorm:"size:100"` + TissueInfo []string `json:"tissueInfo" gorm:"size:100"` +} diff --git a/internal/domain/references/organization/organization.go b/internal/domain/references/organization/organization.go index e12531cd..5b2b4343 100644 --- a/internal/domain/references/organization/organization.go +++ b/internal/domain/references/organization/organization.go @@ -8,6 +8,7 @@ type ( InfraGroupCode string UnitTypeCode string DoctorFeeTypeCode string + ActionBillingCode string ) const ( @@ -62,4 +63,8 @@ const ( DFTCInp DoctorFeeTypeCode = "inpatient" // Rawat Inap DFTCEme DoctorFeeTypeCode = "emergency" // Darurat DFTCReh DoctorFeeTypeCode = "medic-rehab" // Rehab Medik + + ABCGeneral ActionBillingCode = "general" + ABCRegional ActionBillingCode = "regional" + ABCLocal ActionBillingCode = "local" ) diff --git a/internal/interface/main-handler/action-report/handler.go b/internal/interface/main-handler/action-report/handler.go new file mode 100644 index 00000000..0fdd1851 --- /dev/null +++ b/internal/interface/main-handler/action-report/handler.go @@ -0,0 +1,80 @@ +package soapi + +import ( + "net/http" + + rw "github.com/karincake/risoles" + sf "github.com/karincake/semprit" + + // ua "github.com/karincake/tumpeng/auth/svc" + + e "simrs-vx/internal/domain/main-entities/action-report" + u "simrs-vx/internal/use-case/main-use-case/action-report" + + pa "simrs-vx/internal/lib/auth" + + d "github.com/karincake/dodol" +) + +type myBase struct{} + +var O myBase + +func (obj myBase) Create(w http.ResponseWriter, r *http.Request) { + authInfo, err := pa.GetAuthInfo(r) + if err != nil { + rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil) + } + dto := e.CreateDto{} + if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { + return + } + dto.AuthInfo = *authInfo + res, err := u.Create(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) GetList(w http.ResponseWriter, r *http.Request) { + dto := e.ReadListDto{} + sf.UrlQueryParam(&dto, *r.URL) + res, err := u.ReadList(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) { + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id <= 0 { + return + } + dto := e.ReadDetailDto{} + dto.Id = uint16(id) + res, err := u.ReadDetail(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) Update(w http.ResponseWriter, r *http.Request) { + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id <= 0 { + return + } + + dto := e.UpdateDto{} + if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { + return + } + dto.Id = uint16(id) + res, err := u.Update(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) { + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id <= 0 { + return + } + + dto := e.DeleteDto{} + dto.Id = uint16(id) + res, err := u.Delete(dto) + rw.DataResponse(w, res, err) +} diff --git a/internal/interface/main-handler/main-handler.go b/internal/interface/main-handler/main-handler.go index 646bf053..dd025d0e 100644 --- a/internal/interface/main-handler/main-handler.go +++ b/internal/interface/main-handler/main-handler.go @@ -4,6 +4,7 @@ import ( "net/http" /******************** main / transaction ********************/ + actionreport "simrs-vx/internal/interface/main-handler/action-report" adime "simrs-vx/internal/interface/main-handler/adime" admemployeehist "simrs-vx/internal/interface/main-handler/adm-employee-hist" ambulancetransportrequest "simrs-vx/internal/interface/main-handler/ambulance-transport-req" @@ -171,6 +172,7 @@ func SetRoutes() http.Handler { hc.RegCrud(r, "/v1/sbar", auth.GuardMW, sbar.O) hc.RegCrud(r, "/v1/prescription-item", prescriptionitem.O) hc.RegCrud(r, "/v1/device-order-item", deviceorderitem.O) + hc.RegCrud(r, "/v1/action-report", auth.GuardMW, actionreport.O) hc.RegCrud(r, "/v1/material-order-item", materialorderitem.O) hk.GroupRoutes("/v1/encounter", r, auth.GuardMW, hk.MapHandlerFunc{ diff --git a/internal/interface/migration/main-entities.go b/internal/interface/migration/main-entities.go index a59e9b2e..bed0c18c 100644 --- a/internal/interface/migration/main-entities.go +++ b/internal/interface/migration/main-entities.go @@ -1,6 +1,7 @@ package migration import ( + actionreport "simrs-vx/internal/domain/main-entities/action-report" adime "simrs-vx/internal/domain/main-entities/adime" admemployeehist "simrs-vx/internal/domain/main-entities/adm-employee-hist" ambulancetransportreq "simrs-vx/internal/domain/main-entities/ambulance-transport-req" @@ -219,5 +220,6 @@ func getMainEntities() []any { &resume.Resume{}, &vclaimreference.VclaimReference{}, &screening.Screening{}, + &actionreport.ActionReport{}, } } diff --git a/internal/use-case/main-use-case/action-report/case.go b/internal/use-case/main-use-case/action-report/case.go new file mode 100644 index 00000000..2ae0f268 --- /dev/null +++ b/internal/use-case/main-use-case/action-report/case.go @@ -0,0 +1,295 @@ +package actionreport + +import ( + "errors" + "strconv" + + e "simrs-vx/internal/domain/main-entities/action-report" + + 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" +) + +const source = "action-report" + +func Create(input e.CreateDto) (*d.Data, error) { + data := e.ActionReport{} + + event := pl.Event{ + Feature: "Create", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "create") + + 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 !input.AuthInfo.IsDoctor() && !input.AuthInfo.IsNurse() { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "auth-forbidden", + Detail: "user position is not allowed", + Raw: errors.New("authentication failed"), + } + return pl.SetLogError(&event, input) + } + + if input.AuthInfo.Employee_Id != nil { + v := uint(*input.AuthInfo.Employee_Id) + input.Employee_Id = &v + } else { + input.Employee_Id = nil + } + + 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 ReadList(input e.ReadListDto) (*d.Data, error) { + var data *e.ActionReport + var dataList []e.ActionReport + 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 { + 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: e.ToResponseList(dataList), + }, nil +} + +func ReadDetail(input e.ReadDetailDto) (*d.Data, error) { + var data *e.ActionReport + 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 e.UpdateDto) (*d.Data, error) { + rdDto := e.ReadDetailDto{Id: input.Id} + var data *e.ActionReport + var err error + + event := pl.Event{ + Feature: "Update", + Source: source, + } + + // 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 + } + + 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 + } + + 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 e.DeleteDto) (*d.Data, error) { + rdDto := e.ReadDetailDto{Id: input.Id} + var data *e.ActionReport + 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 + +} diff --git a/internal/use-case/main-use-case/action-report/helper.go b/internal/use-case/main-use-case/action-report/helper.go new file mode 100644 index 00000000..efe4532e --- /dev/null +++ b/internal/use-case/main-use-case/action-report/helper.go @@ -0,0 +1,28 @@ +/* +DESCRIPTION: +Any functions that are used internally by the use-case +*/ +package actionreport + +import ( + e "simrs-vx/internal/domain/main-entities/action-report" +) + +func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.ActionReport) { + var inputSrc *e.CreateDto + if inputT, ok := any(input).(*e.CreateDto); ok { + inputSrc = inputT + } else { + inputTemp := any(input).(*e.UpdateDto) + inputSrc = &inputTemp.CreateDto + } + + data.Encounter_Id = inputSrc.Encounter_Id + data.Date = inputSrc.Date + data.Doctor_Code = inputSrc.Doctor_Code + data.Operator_Employe_Id = inputSrc.Operator_Employe_Id + data.Assistant_Employe_Id = inputSrc.Assistant_Employe_Id + data.Instrumentor_Employe_Id = inputSrc.Instrumentor_Employe_Id + data.Nurse_Code = inputSrc.Nurse_Code + data.Value = inputSrc.Value +} diff --git a/internal/use-case/main-use-case/action-report/lib.go b/internal/use-case/main-use-case/action-report/lib.go new file mode 100644 index 00000000..5a272cce --- /dev/null +++ b/internal/use-case/main-use-case/action-report/lib.go @@ -0,0 +1,140 @@ +package actionreport + +import ( + e "simrs-vx/internal/domain/main-entities/action-report" + + plh "simrs-vx/pkg/lib-helper" + pl "simrs-vx/pkg/logger" + pu "simrs-vx/pkg/use-case-helper" + + dg "github.com/karincake/apem/db-gorm-pg" + gh "github.com/karincake/getuk" + "gorm.io/gorm" +) + +func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.ActionReport, error) { + pl.SetLogInfo(event, nil, "started", "DBCreate") + + data := e.ActionReport{} + setData(&input, &data) + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Create(&data).Error; err != nil { + return nil, plh.HandleCreateError(input, event, err) + } + + pl.SetLogInfo(event, nil, "complete") + return &data, nil +} + +func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.ActionReport, *e.MetaDto, error) { + pl.SetLogInfo(event, input, "started", "DBReadList") + data := []e.ActionReport{} + pagination := gh.Pagination{} + count := int64(0) + meta := e.MetaDto{} + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + tx = tx. + Model(&e.ActionReport{}). + Scopes(gh.Preload(input.Includes)). + Scopes(gh.Filter(input.FilterDto)). + Count(&count). + Scopes(gh.Paginate(input, &pagination)). + Order("\"CreatedAt\" DESC") + + if err := tx.Find(&data).Error; err != nil { + if err == gorm.ErrRecordNotFound { + return nil, &meta, nil + } + return nil, nil, plh.HandleListError(input, event, err) + } + + meta.Count = int(count) + meta.PageNumber = pagination.PageNumber + meta.PageSize = pagination.PageSize + + pl.SetLogInfo(event, nil, "complete") + return data, &meta, nil +} + +func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.ActionReport, error) { + pl.SetLogInfo(event, input, "started", "DBReadDetail") + data := e.ActionReport{} + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.First(&data, input.Id).Error; err != nil { + if processedErr := pu.HandleReadError(err, event, source, input.Id, data); processedErr != nil { + return nil, processedErr + } + } + + pl.SetLogInfo(event, nil, "complete") + return &data, nil +} + +func UpdateData(input e.UpdateDto, data *e.ActionReport, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, data, "started", "DBUpdate") + setData(&input, data) + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Save(&data).Error; err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-update-fail", + Detail: "Database update failed", + Raw: err, + } + return pl.SetLogError(event, input) + } + + pl.SetLogInfo(event, nil, "complete") + return nil +} + +func DeleteData(data *e.ActionReport, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, data, "started", "DBDelete") + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Delete(&data).Error; err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-delete-fail", + Detail: "Database delete failed", + Raw: err, + } + return pl.SetLogError(event, data) + } + + pl.SetLogInfo(event, nil, "complete") + return nil +} diff --git a/internal/use-case/main-use-case/action-report/middleware-runner.go b/internal/use-case/main-use-case/action-report/middleware-runner.go new file mode 100644 index 00000000..e2544169 --- /dev/null +++ b/internal/use-case/main-use-case/action-report/middleware-runner.go @@ -0,0 +1,103 @@ +package actionreport + +import ( + e "simrs-vx/internal/domain/main-entities/action-report" + pl "simrs-vx/pkg/logger" + pu "simrs-vx/pkg/use-case-helper" + + "gorm.io/gorm" +) + +type middlewareRunner struct { + Event *pl.Event + Tx *gorm.DB + MwType pu.MWType +} + +// NewMiddlewareExecutor creates a new middleware executor +func newMiddlewareRunner(event *pl.Event, tx *gorm.DB) *middlewareRunner { + return &middlewareRunner{ + Event: event, + Tx: tx, + } +} + +// ExecuteCreateMiddleware executes create middleware +func (me *middlewareRunner) RunCreateMiddleware(middlewares []createMw, input *e.CreateDto, data *e.ActionReport) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) RunReadListMiddleware(middlewares []readListMw, input *e.ReadListDto, data *e.ActionReport) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) RunReadDetailMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.ActionReport) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) RunUpdateMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.ActionReport) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) RunDeleteMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.ActionReport) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) setMwType(mwType pu.MWType) { + me.MwType = mwType +} diff --git a/internal/use-case/main-use-case/action-report/middleware.go b/internal/use-case/main-use-case/action-report/middleware.go new file mode 100644 index 00000000..50254de2 --- /dev/null +++ b/internal/use-case/main-use-case/action-report/middleware.go @@ -0,0 +1,9 @@ +package actionreport + +// example of middleware +// func init() { +// createPreMw = append(createPreMw, +// CreateMw{Name: "modif-input", Func: pm.ModifInput}, +// CreateMw{Name: "check-data", Func: pm.CheckData}, +// ) +// } diff --git a/internal/use-case/main-use-case/action-report/tycovar.go b/internal/use-case/main-use-case/action-report/tycovar.go new file mode 100644 index 00000000..9eebfabd --- /dev/null +++ b/internal/use-case/main-use-case/action-report/tycovar.go @@ -0,0 +1,44 @@ +/* +DESCRIPTION: +A sample, part of the package that contains type, constants, and/or variables. + +In this sample it also provides type and variable regarding the needs of the +middleware to separate from main use-case which has the basic CRUD +functionality. The purpose of this is to make the code more maintainable. +*/ +package actionreport + +import ( + "gorm.io/gorm" + + e "simrs-vx/internal/domain/main-entities/action-report" +) + +type createMw struct { + Name string + Func func(input *e.CreateDto, data *e.ActionReport, tx *gorm.DB) error +} + +type readListMw struct { + Name string + Func func(input *e.ReadListDto, data *e.ActionReport, tx *gorm.DB) error +} + +type readDetailMw struct { + Name string + Func func(input *e.ReadDetailDto, data *e.ActionReport, tx *gorm.DB) error +} + +type UpdateMw = readDetailMw +type DeleteMw = readDetailMw + +var createPreMw []createMw // preprocess middleware +var createPostMw []createMw // postprocess middleware +var readListPreMw []readListMw // .. +var readListPostMw []readListMw // .. +var readDetailPreMw []readDetailMw +var readDetailPostMw []readDetailMw +var updatePreMw []readDetailMw +var updatePostMw []readDetailMw +var deletePreMw []readDetailMw +var deletePostMw []readDetailMw From 50db75e014b64cdda8a3df5176d61697ef2b2eb3 Mon Sep 17 00:00:00 2001 From: dpurbosakti Date: Mon, 1 Dec 2025 15:14:20 +0700 Subject: [PATCH 16/38] add screening --- .../migrations/20251201081333.sql | 13 ++ cmd/main-migration/migrations/atlas.sum | 115 +++++++++--------- .../domain/main-entities/screening/dto.go | 86 +++++++++++++ .../domain/main-entities/screening/entity.go | 17 +++ .../domain/references/clinical/clinical.go | 4 + internal/interface/migration/main-entities.go | 2 + 6 files changed, 180 insertions(+), 57 deletions(-) create mode 100644 cmd/main-migration/migrations/20251201081333.sql create mode 100644 internal/domain/main-entities/screening/dto.go create mode 100644 internal/domain/main-entities/screening/entity.go diff --git a/cmd/main-migration/migrations/20251201081333.sql b/cmd/main-migration/migrations/20251201081333.sql new file mode 100644 index 00000000..876b32b7 --- /dev/null +++ b/cmd/main-migration/migrations/20251201081333.sql @@ -0,0 +1,13 @@ +-- Create "Screening" table +CREATE TABLE "public"."Screening" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "Encounter_Id" bigint NULL, + "Employee_Id" bigint NULL, + "Type" text NULL, + "Value" text NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "fk_Screening_Employee" FOREIGN KEY ("Employee_Id") REFERENCES "public"."Employee" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION +); diff --git a/cmd/main-migration/migrations/atlas.sum b/cmd/main-migration/migrations/atlas.sum index 449ff1d4..b4c4fe05 100644 --- a/cmd/main-migration/migrations/atlas.sum +++ b/cmd/main-migration/migrations/atlas.sum @@ -1,4 +1,4 @@ -h1:Y8m8OmsumTaAfXfYYXHlZS0+OqbAqFfM3a55nmibOUE= +h1:fkwkWe2PSYaTNxdTEmwe747+bhXV+kOcly/gC7dq/Q8= 20250904105930.sql h1:MEM6blCgke9DzWQSTnLzasbPIrcHssNNrJqZpSkEo6k= 20250904141448.sql h1:J8cmYNk4ZrG9fhfbi2Z1IWz7YkfvhFqTzrLFo58BPY0= 20250908062237.sql h1:Pu23yEW/aKkwozHoOuROvHS/GK4ngARJGdO7FB7HZuI= @@ -75,59 +75,60 @@ h1:Y8m8OmsumTaAfXfYYXHlZS0+OqbAqFfM3a55nmibOUE= 20251106040137.sql h1:ppcqkVoT0o9jZcjI/TN7LuaPxXhJQhnIXEJtloP/46o= 20251106041333.sql h1:2JkxyelQ/EeB+boL5bfpnzefw32ttEGKvKchtQjWmAU= 20251106042006.sql h1:ruppYa1kAJQUU3ufQBbKGMcXrGbGJJiRPclT+dNc/YQ= -20251106050412.sql h1:MiEMJ1HCFYnalKuq3Z38xJeogfBAMqsTv2sG4EF8dDw= -20251106063418.sql h1:y3veDJPjKekOWLCZek/LgQwXPRhZtOppTfUXiqoL95s= -20251106071906.sql h1:/TUZA3XpMY23qEJXdkTwlzrNMvSSl6JJniPcgAttBaw= -20251106073157.sql h1:78txeibJ602DMD7huD618ZSMt6phSRzDNPTlo0PGyrc= -20251106074218.sql h1:8Xz7WywrtUnSxOHhlal53gG9rE7r86LFUt5zBFe/mIs= -20251106081846.sql h1:jp91Bf5bxGXMiUB1VIuN6y768vb2iWwow44WfCE5J5k= -20251106082844.sql h1:RHYzRO4G1fSWwf+xc/3QezZ/Iil67cZPIgNpNz3TNhQ= -20251106090021.sql h1:dFDk6mq+zjbYWmfWIrHf9DiKvvoXHjrr0++zssMTWP8= -20251106144745.sql h1:aHcr23iBFqCHer5D/SsPMXBCLjGqUYvWYfRU8jSJgIw= -20251107012049.sql h1:hu/7NHhnAkT4xK0RNtqmMDdH1Bo5EZbl7itDRjiCT+g= -20251107064812.sql h1:sfCXDQYnMf0ddrQ9oYljWJLLSt9NJjJV6o8VS3p7aZE= -20251107064937.sql h1:DlYGJ9LZFwZyR7jBP5zaGB128aIc4HAixBKPYCz9EkY= -20251107071420.sql h1:ynCdZAd2utLl+FhtWZwtahNXgIVOvuk3s/rOq7lfXA4= -20251107074318.sql h1:WE9cPhibWtZ0dbu1VEGirTeY6ijFYGMNhHdBtM32kOc= -20251107075050.sql h1:8tvneruqdynDOaJK1+0z4CH7YXZStZpGdqwIeOMLik4= -20251107080604.sql h1:8c4jd4Tql7tcdhbI9NS0tgvN+ADu9FnCf8wMUbmW7A0= -20251107081830.sql h1:SAAe3lmsm9vGXuSEsDdl7ad0EAxP5CMmFRDEgp9M7yY= -20251107091033.sql h1:JLdX/u7GUdBfjrPrMSNAqc8HtSoj0YA9iW9Vc6FJZdw= -20251107091209.sql h1:CzhYtwAwT+GHrbqcagnJE+v3mbl/rObf1IJaLCKlzrs= -20251107091541.sql h1:+3ZyWJTftDY2JeWThXuIxGWpUBnyMPyOyY4jBjdWYJI= -20251110012217.sql h1:f4Z8TuGc+XMSJ+Ekn4/PeHRE2FlHWkc5gKPJB0hAX7c= -20251110012306.sql h1:ENPyI6Kjdk6qKJQb0yJ6MCTDPAmO1WD/uhKuCSl+jYo= -20251110052049.sql h1:OrQ0acnyoQLKnTitZfnBcVr5jDslF59OFLaqT7SpdVs= -20251110062042.sql h1:9KwldQt0NpVPR86L0T4hlkfHAGau+7CiZYgu5rF+yhg= -20251110063202.sql h1:A117DuZmZ6U0jWHA3DISnr+yvBjKIr1ObrUr047YezQ= -20251110063633.sql h1:qTiC0F19JnhUIXF4LGJQ21jEV6kKGyhTr1x2kimFqPQ= -20251110085551.sql h1:HZcJM0RSC6HBaUSjKBE8MgDG8Vn9f3LmwA/OnT9Cp7I= -20251110091516.sql h1:W3AQhQLgirEWuCObbLl+Prdrbq6k6EEY1xcoWsmbog4= -20251110091948.sql h1:3tsITMrZr/T+L4wqUMz8sHS229jCJl4T0Nu3dMccxH8= -20251110092729.sql h1:uU+k88RH/e0Ns4/SmJl03RVYPscBAPuiLfxR6CJqaf0= -20251110093522.sql h1:O7upSj8VNjzvroL4IU59bfxKATOkAVGBArcUbVNq9aM= -20251110100258.sql h1://JSArUMNI3/gAtYDx2VN94C198SFW0ANjgs+p6eCRM= -20251110100545.sql h1:ENPOqeJYRpMI4e8VCKwaQgaql8se6pIidAhG2cjskBg= -20251110155448.sql h1:VW9KE0jxWy4flZ28sdXmhY6JWd6eKAX/cVL8KWRVii4= -20251111072601.sql h1:99WWzGjcDDFNC2cHRfPu4MBLWNrgPMY5HAYUbmIcVRA= -20251111073546.sql h1:iIGwFNfUgStdczw/PXTH3SD84xAyxrbZICofc3M8TMk= -20251111074148.sql h1:mzkezSKwCV2bTZ/0BHiTCX5qAy4uHpwar1xzwAH15Ko= -20251111074652.sql h1:lYh4/3BHV24pgPC0pP4RUKb+XtL/6AsZGPItRpnzBiQ= -20251111082257.sql h1:+cIZ1lf8HYGSL6t6U88plLKk8nOO1YVdV7h3YOM84ds= -20251111111017.sql h1:xzlhR2xLfOj4ddYlesS+bpEeDrxiAf5ILNOspsbZjBU= -20251113101344.sql h1:vSzThY3p6XYTj0dJ2uFVkHmlytyrFAnGE58CJLx364I= -20251113120533.sql h1:lfjgdqRGo/EohrVw8sWlFbDjh3ASTsfQ6pr3qjafqvc= -20251114062746.sql h1:6DLYjfJ60PkAABZTXvOwSE+xrU25oyoX7gpYlBnA9cw= -20251117005942.sql h1:0XoJKca8IOaB9QKFVF/qPY7jKcIgh6m/LODQuE06SAs= -20251117075427.sql h1:LhY2urosfoSu1/vkHmgsNP4JA4DuWBs9gL59yMqcF8M= -20251118074929.sql h1:3RWBD6BziQVw6WSfthgoVuhTELHER9NrIuZm4hY/F1A= -20251119063438.sql h1:EVTG3ZrHjCmM95YPASZTRPiwHrG6e33A2vO4hLSAaBQ= -20251119065730.sql h1:s98wnZOCW6NbnwDS3H53XIQ60u6B9bDwBLNvy5+Rn64= -20251119072302.sql h1:ZL+VHekLYqgNtOFKlj02WHrAk11dtTxQkmyTKE8IOzY= -20251119072450.sql h1:SiJy2vpSvoPFw4J1SW7HjGSJzrqR62NsjRYAeabV+kc= -20251120005512.sql h1:hJUaWXYJ3HiSquBTw8OKhymjA4O43ehAMGfiOY8W87Q= -20251120074415.sql h1:dNmcqZHqfZwi/wtYvO/pSFgImN2scXL0p/7g0+HLp0s= -20251121033803.sql h1:onlddYGo+tQdGaEdJPqdsx3sncGnwEvqMSCksF6vjjI= -20251124071457.sql h1:ikQLIXFikUbkUd55uJBmEvqLGEC9t0db+Om4TQsWP7M= -20251125125303.sql h1:OLKbNPO36AHtIDursW9AeBvf60sahQKC1iOjHmpx0MA= -20251126064057.sql h1:6al3PTWbw/WGiBcrRrVWppOMLtG+eRaH/qSLbnmh1kQ= +20251106050412.sql h1:1002KYtHd8AwrQTMewbs/PPHDylHDghigE/3S7PVdMA= +20251106063418.sql h1:jPW/gBnbFl4RO39lQ0ZMDtYA6xbhyD6CgQupT50HmaY= +20251106071906.sql h1:leYGKxR3EQn794aOehf0sd/ZPmOnvBMZPy5/anGmRB4= +20251106073157.sql h1:KASMzjjjk5UB7Zj8lCRtM1utc4ZnDjlnpZbtTe3vONE= +20251106074218.sql h1:Z5q5deOvLaZDPhiVTN9st3/s56RepBa2YOyrMXBdj4A= +20251106081846.sql h1:P+VsWwhGt60adDIZuE/Aa38JVp/yX1rnsdpXpxASodw= +20251106082844.sql h1:Dmi5A8i9frQZvdXYPwc7f8CisZtBH8liSXq1rI6z1iM= +20251106090021.sql h1:4JwdKgO8T46YhyWVJUxpRIwudBDlG8QN1brSOYmgQ20= +20251106144745.sql h1:nqnQCzGrVJaq8ilOEOGXeRUL1dolj+OPWKuP8A92FRA= +20251107012049.sql h1:Pff4UqltGS3clSlGr0qq8CQM56L29wyxY0FC/N/YAhU= +20251107064812.sql h1:GB9a0ZfMYTIoGNmKUG+XcYUsTnRMFfT4/dAD71uCPc4= +20251107064937.sql h1:IC5pw1Ifj30hiE6dr5NMHXaSHoQI+vRd40N5ABgBHRI= +20251107071420.sql h1:9NO3iyLEXEtWa2kSRjM/8LyzuVIk6pdFL2SuheWjB08= +20251107074318.sql h1:7fHbSRrdjOmHh/xwnjCLwoiB5cW5zeH+uxLV0vZbkIA= +20251107075050.sql h1:np+3uTOnU9QNtK7Knaw8eRMhkyB9AwrtSNHphOBxbHY= +20251107080604.sql h1:cXDBLPJDVWLTG6yEJqkJsOQ7p7VYxLM2SY+mwO8qSHo= +20251107081830.sql h1:/S7OQZo4ZnK80t28g/JyiOTZtmWG/dP5Wg2zXNMQ/iE= +20251107091033.sql h1:/cbkF1nO/IjNSIfDJJx456KJtQ9rWFXOBFAkR/M2xiE= +20251107091209.sql h1:jrLQOUeV8ji2fg0pnEcs1bw4ANUxzTSMXC/rrHLIY+M= +20251107091541.sql h1:6UqbhQQRmzA2+eKu5lIvkwOkk+lH70QLZC8Pjpjcq68= +20251110012217.sql h1:C9HpX0iyHzKjyNv/5DSAn2MCHj6MX4p5UQ/NrY7QD0w= +20251110012306.sql h1:J54yb27d30LBbYp9n1P66gFVRlxPguKu0kxmWIBBG8g= +20251110052049.sql h1:232T2x8xTczJl9nk4jxJpZXhoOGYthhxjJ7nK8Jd8vg= +20251110062042.sql h1:WnfVUXrzYoj8qdkkjO9/JQQ8agGd4GfSHQdMjo7LDAg= +20251110063202.sql h1:hSzGfwVMWa6q3vwIQZUkxKgBNCzHjB+6GKy54zfV+oQ= +20251110063633.sql h1:/VpofIAqNS1CnazEnpW/+evbzn9Kew3xDW48r57M+Xg= +20251110085551.sql h1:bFZwSmfvVbTUr/enWB82WqjG88gpqcZ6s45btUvO0uo= +20251110091516.sql h1:KkJMwPQuaZQhiqnKrNQrgP12gw9rV8T3P2o3mtGTcvY= +20251110091948.sql h1:I4odAYrJdvNf1jPw6ppDC0XdI7v6vKBACg/ABwUgA7I= +20251110092729.sql h1:l1out8soEmVP6dNjaIOtGYo6QDcoJZRI8X1sjZ5ZGmo= +20251110093522.sql h1:nsz8jCxGjEdr/bz9g+4ozfZzIP803xONjVmucad1GMc= +20251110100258.sql h1:IBqt1VZj5WjQ+l9aAFGHOCCBtzb03KlLLihFLut7itg= +20251110100545.sql h1:6/LV7751iyKxE2xI6vO1zly+aHUwxXD/IBwLcVpKxqM= +20251110155448.sql h1:kFPobJB+cpflsXBAWUwy3lohuWvrb/VRlXnhJWl7i3Y= +20251111072601.sql h1:ch8F+yVhsSM5xY+TwMLY3PxdLa4Wuhtj76oyw79R7Js= +20251111073546.sql h1:cCv0NPscADAOBahRVqtDWFs6G2t7n+4a+RwlF8vk/c4= +20251111074148.sql h1:70TsV83u1gQ5TktI13K7NQiyCCa35Td2aR6CNtKUa4U= +20251111074652.sql h1:ddfQ/sRKMezPM75xBFTGytUQX5AwZ3znrJVpg73gKPA= +20251111082257.sql h1:ZsdLY1ROouos0l3oS0lkeSiuKLEUGbVvBhpcM2AVhkw= +20251111111017.sql h1:qrJ93dNtQwcuAvpsP/lAK/H63C4cinXrsVaPmWsTqkU= +20251113101344.sql h1:xaOZvAUP1fFfnO+syEFOzJUIg5lTfBe5AWHPbBWuCLA= +20251113120533.sql h1:f3/U1Ve2yF2zSMhkt+xtwF8wUYfUKYwgbNeGfE37EW4= +20251114062746.sql h1:FInLaEFQByESEwFJKuKnuUSTKmcDpi3ZXaxkKwz2+D8= +20251117005942.sql h1:wD3BWrUSmo1HlW16V3lkaBkJvbAZ0fNk77te7J9NhOc= +20251117075427.sql h1:TqU9VKZa3I8YNXUGQWY3WVBYN+1FvyyaKy0hB1jgAho= +20251118074929.sql h1:p1KsWqCuR1JXA/jVO5BmOhCcaQ8clT7t0YRszAhPFbg= +20251119063438.sql h1:NVGM0X/LHD37EaPl8SNzkNiZDJ7AB1QR+LLwLh6WRdg= +20251119065730.sql h1:U5lzk1WvMB0bw3kwckou7jkEt4bwdYItwHr2Vxqe7w4= +20251119072302.sql h1:qCuI2WMEMF/XNbjV+RXPjBnuCKLu1Fia+mR9HiLWBIs= +20251119072450.sql h1:Xg+bTwqGyKPNFEQhJylvpz1wifdfmDJvcAq6vmNf0Ng= +20251120005512.sql h1:Ek6qpacAI/qVuTYxKno+uJyzn7s5z9pf3t7VA8gTzm4= +20251120074415.sql h1:NNUeJVA03EeBHJhHqPXEZoDv/PnC6yK1/cRhmukyaJo= +20251121033803.sql h1:/vfvFX/3pzSCIHnSbMUT9EMBDykOpVkvyfeTEle9Vas= +20251124071457.sql h1:qg2dhCL9YwD13xnfJ175lW/p6MGfzFKaBqd908FByRc= +20251125125303.sql h1:4JSFv1Pmhbe9tqpLXgO63OwYnGsalStgUXKVWPyc1YE= +20251126064057.sql h1:vAdhz5Nn/gGJy0UKZAEldeXv8HpHtJU/t8ygDVIbTsU= +20251201081333.sql h1:PoC8ADRdwDuohDTB74yW/DaB42igdYa4B6humbrEJBk= diff --git a/internal/domain/main-entities/screening/dto.go b/internal/domain/main-entities/screening/dto.go new file mode 100644 index 00000000..5dfed2c7 --- /dev/null +++ b/internal/domain/main-entities/screening/dto.go @@ -0,0 +1,86 @@ +package screening + +import ( + // std + + // internal - lib + pa "simrs-vx/internal/lib/auth" + + // internal - domain - base-entities + ecore "simrs-vx/internal/domain/base-entities/core" + + // internal - domain - main-entities + eem "simrs-vx/internal/domain/main-entities/employee" + + erc "simrs-vx/internal/domain/references/clinical" +) + +type CreateDto struct { + Encounter_Id *uint `json:"encounter_id"` + Employee_Id *uint `json:"-"` + Type erc.ScreeningFormTypeCode `json:"type"` + Value *string `json:"value"` + + pa.AuthInfo +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Pagination ecore.Pagination +} + +type FilterDto struct { + Encounter_Id *uint `json:"encounter-id"` + Employee_Id *uint `json:"employee-id"` + Type erc.ScreeningFormTypeCode `json:"type"` + Value *string `json:"value"` +} + +type ReadDetailDto struct { + Id uint16 `json:"id"` +} + +type UpdateDto struct { + Id uint16 `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint16 `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.Main + Encounter_Id *uint `json:"encounter_id"` + Employee_Id *uint `json:"employee_id"` + Employee *eem.Employee `json:"employee,omitempty"` + Type erc.ScreeningFormTypeCode `json:"type"` + Value *string `json:"value"` +} + +func (d Screening) ToResponse() ResponseDto { + resp := ResponseDto{ + Encounter_Id: d.Encounter_Id, + Employee_Id: d.Employee_Id, + Employee: d.Employee, + Type: d.Type, + Value: d.Value, + } + resp.Main = d.Main + return resp +} + +func ToResponseList(data []Screening) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/screening/entity.go b/internal/domain/main-entities/screening/entity.go new file mode 100644 index 00000000..ebdb735b --- /dev/null +++ b/internal/domain/main-entities/screening/entity.go @@ -0,0 +1,17 @@ +package screening + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + eem "simrs-vx/internal/domain/main-entities/employee" + + erc "simrs-vx/internal/domain/references/clinical" +) + +type Screening struct { + ecore.Main // adjust this according to the needs + Encounter_Id *uint `json:"encounter_id"` + Employee_Id *uint `json:"employee_id"` + Employee *eem.Employee `json:"employee,omitempty" gorm:"foreignKey:Employee_Id;references:Id"` + Type erc.ScreeningFormTypeCode `json:"type"` + Value *string `json:"value"` +} diff --git a/internal/domain/references/clinical/clinical.go b/internal/domain/references/clinical/clinical.go index 30a4fe8a..4755eea1 100644 --- a/internal/domain/references/clinical/clinical.go +++ b/internal/domain/references/clinical/clinical.go @@ -22,6 +22,7 @@ type ( LearnMethodCode string LangClassCode string TranslatorSrcCode string + ScreeningFormTypeCode string ) const ( @@ -187,6 +188,9 @@ const ( TSCTeam TranslatorSrcCode = "team" // Tim Penerjemah TSCFamily TranslatorSrcCode = "family" // Keluarga + + SFTCA ScreeningFormTypeCode = "form-a" // Formu A + SFTCB ScreeningFormTypeCode = "form-b" // Formu B ) type Soapi struct { diff --git a/internal/interface/migration/main-entities.go b/internal/interface/migration/main-entities.go index 0b4a62fd..a59e9b2e 100644 --- a/internal/interface/migration/main-entities.go +++ b/internal/interface/migration/main-entities.go @@ -85,6 +85,7 @@ import ( resume "simrs-vx/internal/domain/main-entities/resume" room "simrs-vx/internal/domain/main-entities/room" sbar "simrs-vx/internal/domain/main-entities/sbar" + screening "simrs-vx/internal/domain/main-entities/screening" soapi "simrs-vx/internal/domain/main-entities/soapi" specialist "simrs-vx/internal/domain/main-entities/specialist" specialistintern "simrs-vx/internal/domain/main-entities/specialist-intern" @@ -217,5 +218,6 @@ func getMainEntities() []any { &vclaimsepcontrolletter.VclaimSepControlLetter{}, &resume.Resume{}, &vclaimreference.VclaimReference{}, + &screening.Screening{}, } } From 4f6bc8da314809802b07305f851c8e2ebd59f12f Mon Sep 17 00:00:00 2001 From: Munawwirul Jamal Date: Mon, 1 Dec 2025 18:02:20 +0700 Subject: [PATCH 17/38] feat/action-report: migrated + finishing --- cmd/main-migration/migrations/atlas.sum | 7 ++----- internal/domain/main-entities/mcu-order-item/entity.go | 4 +++- internal/domain/references/clinical/clinical.go | 6 ------ 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/cmd/main-migration/migrations/atlas.sum b/cmd/main-migration/migrations/atlas.sum index bdc2efaf..8f71fcc5 100644 --- a/cmd/main-migration/migrations/atlas.sum +++ b/cmd/main-migration/migrations/atlas.sum @@ -1,8 +1,4 @@ -<<<<<<< HEAD -h1:oIkzjGilKCqqfLGlvMc2I2WwJ8zQgdMeTWy25k1uaLI= -======= -h1:fkwkWe2PSYaTNxdTEmwe747+bhXV+kOcly/gC7dq/Q8= ->>>>>>> migration +h1:NUsCmkoiBso9yZsv4HWrn3+woqMcFRFtgXKln5rY4pQ= 20250904105930.sql h1:MEM6blCgke9DzWQSTnLzasbPIrcHssNNrJqZpSkEo6k= 20250904141448.sql h1:J8cmYNk4ZrG9fhfbi2Z1IWz7YkfvhFqTzrLFo58BPY0= 20250908062237.sql h1:Pu23yEW/aKkwozHoOuROvHS/GK4ngARJGdO7FB7HZuI= @@ -136,3 +132,4 @@ h1:fkwkWe2PSYaTNxdTEmwe747+bhXV+kOcly/gC7dq/Q8= 20251125125303.sql h1:4JSFv1Pmhbe9tqpLXgO63OwYnGsalStgUXKVWPyc1YE= 20251126064057.sql h1:vAdhz5Nn/gGJy0UKZAEldeXv8HpHtJU/t8ygDVIbTsU= 20251201081333.sql h1:PoC8ADRdwDuohDTB74yW/DaB42igdYa4B6humbrEJBk= +20251201104439.sql h1:tpqdrOf9d2aGwZshqm62nG6SXnfVaO/g6A7z0efPS14= diff --git a/internal/domain/main-entities/mcu-order-item/entity.go b/internal/domain/main-entities/mcu-order-item/entity.go index 48a57bac..7d4d757d 100644 --- a/internal/domain/main-entities/mcu-order-item/entity.go +++ b/internal/domain/main-entities/mcu-order-item/entity.go @@ -4,12 +4,14 @@ import ( emo "simrs-vx/internal/domain/main-entities/mcu-order" emoib "simrs-vx/internal/domain/main-entities/mcu-order-item/base" + emosi "simrs-vx/internal/domain/main-entities/mcu-order-sub-item/base" erc "simrs-vx/internal/domain/references/common" ) type McuOrderItem struct { emoib.McuOrderItem - McuOrder *emo.McuOrder `json:"mcuOrder,omitempty" gorm:"foreignKey:McuOrder_Id;references:Id"` + McuOrder *emo.McuOrder `json:"mcuOrder,omitempty" gorm:"foreignKey:McuOrder_Id;references:Id"` + Items []*emosi.McuOrderSubItem `json:"items" gorm:"foreignKey:McuOrderItem_Id;references:Id"` } func (d McuOrderItem) IsCompleted() bool { diff --git a/internal/domain/references/clinical/clinical.go b/internal/domain/references/clinical/clinical.go index f6c1b572..7a3a2ec1 100644 --- a/internal/domain/references/clinical/clinical.go +++ b/internal/domain/references/clinical/clinical.go @@ -23,7 +23,6 @@ type ( LangClassCode string TranslatorSrcCode string ScreeningFormTypeCode string -<<<<<<< HEAD SurgerySizeCode string SurgerySystemCode string SurgeryTypeCode string @@ -31,8 +30,6 @@ type ( BornMortalityCode string BornLocationCode string SpecimentDestCode string -======= ->>>>>>> migration ) const ( @@ -201,7 +198,6 @@ const ( SFTCA ScreeningFormTypeCode = "form-a" // Formu A SFTCB ScreeningFormTypeCode = "form-b" // Formu B -<<<<<<< HEAD SSCSmall SurgerySizeCode = "" SSCMedium SurgerySizeCode = "" @@ -234,8 +230,6 @@ const ( SDCMicro SpecimentDestCode = "" SDCLab SpecimentDestCode = "" SDCNone SpecimentDestCode = "" -======= ->>>>>>> migration ) type Soapi struct { From b65c86750ab673866c46b21e7980e4d6c78e561d Mon Sep 17 00:00:00 2001 From: Munawwirul Jamal Date: Mon, 1 Dec 2025 18:39:28 +0700 Subject: [PATCH 18/38] feat/action-report: new migration --- .../migrations/20251201113804.sql | 2 ++ .../migrations/20251201113858.sql | 2 ++ cmd/main-migration/migrations/atlas.sum | 4 ++- .../domain/main-entities/action-report/dto.go | 29 ++++++++++--------- .../main-entities/action-report/entity.go | 12 ++++---- 5 files changed, 28 insertions(+), 21 deletions(-) create mode 100644 cmd/main-migration/migrations/20251201113804.sql create mode 100644 cmd/main-migration/migrations/20251201113858.sql diff --git a/cmd/main-migration/migrations/20251201113804.sql b/cmd/main-migration/migrations/20251201113804.sql new file mode 100644 index 00000000..0f5c5123 --- /dev/null +++ b/cmd/main-migration/migrations/20251201113804.sql @@ -0,0 +1,2 @@ +-- Modify "ActionReport" table +ALTER TABLE "public"."ActionReport" DROP COLUMN "Date", DROP COLUMN "Procedures"; diff --git a/cmd/main-migration/migrations/20251201113858.sql b/cmd/main-migration/migrations/20251201113858.sql new file mode 100644 index 00000000..fd6fddc9 --- /dev/null +++ b/cmd/main-migration/migrations/20251201113858.sql @@ -0,0 +1,2 @@ +-- Modify "ActionReport" table +ALTER TABLE "public"."ActionReport" ADD COLUMN "Date" timestamptz NOT NULL; diff --git a/cmd/main-migration/migrations/atlas.sum b/cmd/main-migration/migrations/atlas.sum index 8f71fcc5..db6de529 100644 --- a/cmd/main-migration/migrations/atlas.sum +++ b/cmd/main-migration/migrations/atlas.sum @@ -1,4 +1,4 @@ -h1:NUsCmkoiBso9yZsv4HWrn3+woqMcFRFtgXKln5rY4pQ= +h1:EpEYOCY46tEg91o5Y4scmFj3/yIyR311HaP95Ts3vus= 20250904105930.sql h1:MEM6blCgke9DzWQSTnLzasbPIrcHssNNrJqZpSkEo6k= 20250904141448.sql h1:J8cmYNk4ZrG9fhfbi2Z1IWz7YkfvhFqTzrLFo58BPY0= 20250908062237.sql h1:Pu23yEW/aKkwozHoOuROvHS/GK4ngARJGdO7FB7HZuI= @@ -133,3 +133,5 @@ h1:NUsCmkoiBso9yZsv4HWrn3+woqMcFRFtgXKln5rY4pQ= 20251126064057.sql h1:vAdhz5Nn/gGJy0UKZAEldeXv8HpHtJU/t8ygDVIbTsU= 20251201081333.sql h1:PoC8ADRdwDuohDTB74yW/DaB42igdYa4B6humbrEJBk= 20251201104439.sql h1:tpqdrOf9d2aGwZshqm62nG6SXnfVaO/g6A7z0efPS14= +20251201113804.sql h1:pR0nbmjJNDLi929vmGm2W9RKxLJ2iECzf2otO+JpKWA= +20251201113858.sql h1:JciS3xbCF94huB0qkGJ24YtS1a+nqV26hxzeKh2AOj0= diff --git a/internal/domain/main-entities/action-report/dto.go b/internal/domain/main-entities/action-report/dto.go index 1edb4a73..45c26d17 100644 --- a/internal/domain/main-entities/action-report/dto.go +++ b/internal/domain/main-entities/action-report/dto.go @@ -3,20 +3,21 @@ package actionreport import ( ecore "simrs-vx/internal/domain/base-entities/core" ee "simrs-vx/internal/domain/main-entities/encounter" + "time" pa "simrs-vx/internal/lib/auth" ) type CreateDto struct { - Encounter_Id uint64 `json:"encounter_id"` - Date string `json:"date"` - Doctor_Code string `json:"doctor_code"` - Operator_Employe_Id *uint `json:"operator_employe_id"` - Assistant_Employe_Id *uint `json:"assistant_employe_id"` - Instrumentor_Employe_Id *uint `json:"instrumentor_employe_id"` - Diagnose *string `json:"diagnose"` - Nurse_Code *string `json:"nurse_code"` - Value string `json:"value"` + Encounter_Id uint64 `json:"encounter_id" validate:"required"` + Date *time.Time `json:"date" validate:"required"` + Doctor_Code string `json:"doctor_code" validate:"required"` + Operator_Employe_Id uint `json:"operator_employe_id" validate:"required"` + Assistant_Employe_Id uint `json:"assistant_employe_id" validate:"required"` + Instrumentor_Employe_Id uint `json:"instrumentor_employe_id" validate:"required"` + Diagnose *string `json:"diagnose"` + Nurse_Code string `json:"nurse_code" validate:"required"` + Value string `json:"value" validate:"required"` pa.AuthInfo } @@ -54,13 +55,13 @@ type ResponseDto struct { ecore.Main Encounter_Id uint64 `json:"encounter_id"` Encounter *ee.Encounter `json:"encounter,omitempty"` - Date string `json:"date"` + Date *time.Time `json:"date"` Doctor_Code string `json:"doctor_code"` - Operator_Employe_Id *uint `json:"operator_employe_id"` - Assistant_Employe_Id *uint `json:"assistant_employe_id"` - Instrumentor_Employe_Id *uint `json:"instrumentor_employe_id"` + Operator_Employe_Id uint `json:"operator_employe_id"` + Assistant_Employe_Id uint `json:"assistant_employe_id"` + Instrumentor_Employe_Id uint `json:"instrumentor_employe_id"` Diagnose *string `json:"diagnose"` - Nurse_Code *string `json:"nurse_code"` + Nurse_Code string `json:"nurse_code"` Value *string `json:"value"` } diff --git a/internal/domain/main-entities/action-report/entity.go b/internal/domain/main-entities/action-report/entity.go index 3437136e..b3fc1956 100644 --- a/internal/domain/main-entities/action-report/entity.go +++ b/internal/domain/main-entities/action-report/entity.go @@ -3,20 +3,20 @@ package actionreport import ( ecore "simrs-vx/internal/domain/base-entities/core" ee "simrs-vx/internal/domain/main-entities/encounter" + "time" ) type ActionReport struct { ecore.Main // adjust this according to the needs Encounter_Id uint64 `json:"encounter_id" gorm:"foreignKey"` Encounter *ee.Encounter `json:"doctor,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"` - Date string `json:"date" gorm:"not null;size:20"` + Date *time.Time `json:"date" gorm:"not null;size:20"` Doctor_Code string `json:"doctor_code" gorm:"size:10"` - Operator_Employe_Id *uint `json:"operator_employe_id"` - Assistant_Employe_Id *uint `json:"assistant_employe_id"` - Instrumentor_Employe_Id *uint `json:"instrumentor_employe_id"` + Operator_Employe_Id uint `json:"operator_employe_id"` + Assistant_Employe_Id uint `json:"assistant_employe_id"` + Instrumentor_Employe_Id uint `json:"instrumentor_employe_id"` Diagnose *string `json:"diagnose" gorm:"size:1024"` - Procedures *string `json:"procedures" gorm:"size:10240"` - Nurse_Code *string `json:"nurse_code" gorm:"size:10"` + Nurse_Code string `json:"nurse_code" gorm:"size:10"` Value string `json:"value"` // SurgerySize_Code *string `json:"surgerySize_code" gorm:"size:10"` From 47d2e427c0d75a4e5f937291e4911194625530ea Mon Sep 17 00:00:00 2001 From: Munawwirul Jamal Date: Mon, 1 Dec 2025 18:49:54 +0700 Subject: [PATCH 19/38] feat/action-report: adjust table structure --- cmd/main-migration/migrations/20251201114751.sql | 2 ++ cmd/main-migration/migrations/20251201114913.sql | 2 ++ cmd/main-migration/migrations/atlas.sum | 8 +++++--- .../domain/main-entities/action-report/entity.go | 12 +++++++++--- 4 files changed, 18 insertions(+), 6 deletions(-) create mode 100644 cmd/main-migration/migrations/20251201114751.sql create mode 100644 cmd/main-migration/migrations/20251201114913.sql diff --git a/cmd/main-migration/migrations/20251201114751.sql b/cmd/main-migration/migrations/20251201114751.sql new file mode 100644 index 00000000..6611b811 --- /dev/null +++ b/cmd/main-migration/migrations/20251201114751.sql @@ -0,0 +1,2 @@ +-- Modify "ActionReport" table +ALTER TABLE "public"."ActionReport" ADD CONSTRAINT "fk_ActionReport_Instrumentor_Employe" FOREIGN KEY ("Instrumentor_Employe_Id") REFERENCES "public"."Employee" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION, ADD CONSTRAINT "fk_ActionReport_Nurse" FOREIGN KEY ("Nurse_Code") REFERENCES "public"."Nurse" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION, ADD CONSTRAINT "fk_ActionReport_Operator_Employe" FOREIGN KEY ("Operator_Employe_Id") REFERENCES "public"."Employee" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION; diff --git a/cmd/main-migration/migrations/20251201114913.sql b/cmd/main-migration/migrations/20251201114913.sql new file mode 100644 index 00000000..5155ed37 --- /dev/null +++ b/cmd/main-migration/migrations/20251201114913.sql @@ -0,0 +1,2 @@ +-- Modify "ActionReport" table +ALTER TABLE "public"."ActionReport" ADD CONSTRAINT "fk_ActionReport_Doctor" FOREIGN KEY ("Doctor_Code") REFERENCES "public"."Doctor" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION; diff --git a/cmd/main-migration/migrations/atlas.sum b/cmd/main-migration/migrations/atlas.sum index db6de529..51161909 100644 --- a/cmd/main-migration/migrations/atlas.sum +++ b/cmd/main-migration/migrations/atlas.sum @@ -1,4 +1,4 @@ -h1:EpEYOCY46tEg91o5Y4scmFj3/yIyR311HaP95Ts3vus= +h1:bYhAmgY4p8jgE8JpZ6YeJyS1iYCH2LEvDXW2PE+iZpc= 20250904105930.sql h1:MEM6blCgke9DzWQSTnLzasbPIrcHssNNrJqZpSkEo6k= 20250904141448.sql h1:J8cmYNk4ZrG9fhfbi2Z1IWz7YkfvhFqTzrLFo58BPY0= 20250908062237.sql h1:Pu23yEW/aKkwozHoOuROvHS/GK4ngARJGdO7FB7HZuI= @@ -133,5 +133,7 @@ h1:EpEYOCY46tEg91o5Y4scmFj3/yIyR311HaP95Ts3vus= 20251126064057.sql h1:vAdhz5Nn/gGJy0UKZAEldeXv8HpHtJU/t8ygDVIbTsU= 20251201081333.sql h1:PoC8ADRdwDuohDTB74yW/DaB42igdYa4B6humbrEJBk= 20251201104439.sql h1:tpqdrOf9d2aGwZshqm62nG6SXnfVaO/g6A7z0efPS14= -20251201113804.sql h1:pR0nbmjJNDLi929vmGm2W9RKxLJ2iECzf2otO+JpKWA= -20251201113858.sql h1:JciS3xbCF94huB0qkGJ24YtS1a+nqV26hxzeKh2AOj0= +20251201113804.sql h1:kIEmVoETJXBkab2Q+b3y/pP84eF8W2BdQ47amHCnc+c= +20251201113858.sql h1:KLXKZO5XTQPoEU0YLHE8Fhg9WPKpSN3wNgYPJ+RGFcg= +20251201114751.sql h1:QMcFLz4vr6lwQ03k0Wthhosce743DW9A3w6WJzfqjoU= +20251201114913.sql h1:GvRLyn62Z5CIckonFhtHOZKbJK43yyoCXUfFiADLiAo= diff --git a/internal/domain/main-entities/action-report/entity.go b/internal/domain/main-entities/action-report/entity.go index b3fc1956..8447a2e5 100644 --- a/internal/domain/main-entities/action-report/entity.go +++ b/internal/domain/main-entities/action-report/entity.go @@ -2,23 +2,29 @@ package actionreport import ( ecore "simrs-vx/internal/domain/base-entities/core" + ed "simrs-vx/internal/domain/main-entities/doctor" + eem "simrs-vx/internal/domain/main-entities/employee" ee "simrs-vx/internal/domain/main-entities/encounter" + en "simrs-vx/internal/domain/main-entities/nurse" "time" ) type ActionReport struct { ecore.Main // adjust this according to the needs Encounter_Id uint64 `json:"encounter_id" gorm:"foreignKey"` - Encounter *ee.Encounter `json:"doctor,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"` + Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"` Date *time.Time `json:"date" gorm:"not null;size:20"` Doctor_Code string `json:"doctor_code" gorm:"size:10"` + Doctor *ed.Doctor `json:"doctor,omitempty" gorm:"foreignKey:Doctor_Code;references:Code"` Operator_Employe_Id uint `json:"operator_employe_id"` + Operator_Employe *eem.Employee `json:"operator_employe,omitempty" gorm:"foreignKey:Operator_Employe_Id;references:Id"` Assistant_Employe_Id uint `json:"assistant_employe_id"` Instrumentor_Employe_Id uint `json:"instrumentor_employe_id"` + Instrumentor_Employe *eem.Employee `json:"instrumentor_employe,omitempty" gorm:"foreignKey:Instrumentor_Employe_Id;references:Id"` Diagnose *string `json:"diagnose" gorm:"size:1024"` Nurse_Code string `json:"nurse_code" gorm:"size:10"` - - Value string `json:"value"` + Nurse *en.Nurse `json:"nurse,omitempty" gorm:"foreignKey:Nurse_Code;references:Code"` + Value string `json:"value"` // SurgerySize_Code *string `json:"surgerySize_code" gorm:"size:10"` // Billing_Code *string `json:"billing_code" gorm:"size:10"` // SurgerySystem_Code *string `json:"surgerySystem_code" gorm:"size:10"` From 17bf6cd2ae0c3280435cf72c2fbf211c6dff3d20 Mon Sep 17 00:00:00 2001 From: Munawwirul Jamal Date: Mon, 1 Dec 2025 20:12:13 +0700 Subject: [PATCH 20/38] feat/mcu-order: wip --- .../mcu-order-sub-item/base/entity.go | 17 +++++++++++++++++ .../main-entities/mcu-order-sub-item/entity.go | 12 ++++-------- .../main-entities/mcu-src-category/dto.go | 10 +++++----- .../main-entities/mcu-src-category/entity.go | 2 +- internal/domain/references/clinical/clinical.go | 8 ++++++-- 5 files changed, 33 insertions(+), 16 deletions(-) create mode 100644 internal/domain/main-entities/mcu-order-sub-item/base/entity.go diff --git a/internal/domain/main-entities/mcu-order-sub-item/base/entity.go b/internal/domain/main-entities/mcu-order-sub-item/base/entity.go new file mode 100644 index 00000000..fea105a4 --- /dev/null +++ b/internal/domain/main-entities/mcu-order-sub-item/base/entity.go @@ -0,0 +1,17 @@ +package mcuordersubitem + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + emss "simrs-vx/internal/domain/main-entities/mcu-sub-src" + + erc "simrs-vx/internal/domain/references/common" +) + +type McuOrderSubItem struct { + ecore.Main // adjust this according to the needs + McuSubSrc_Code *string `json:"mcuSubSrc_code" gorm:"uniqueIndex:idx_order_sub_src"` + McuSubSrc *emss.McuSubSrc `json:"mcuSubSrc,omitempty" gorm:"foreignKey:McuSubSrc_Code;references:Code"` + McuOrderItem_Id *uint `json:"mcuOrderItem_id" gorm:"uniqueIndex:idx_order_sub_src"` + Result *string `json:"result"` + Status_Code erc.DataStatusCode `json:"status_code"` +} diff --git a/internal/domain/main-entities/mcu-order-sub-item/entity.go b/internal/domain/main-entities/mcu-order-sub-item/entity.go index a9bde496..990cd048 100644 --- a/internal/domain/main-entities/mcu-order-sub-item/entity.go +++ b/internal/domain/main-entities/mcu-order-sub-item/entity.go @@ -3,19 +3,15 @@ package mcuordersubitem import ( ecore "simrs-vx/internal/domain/base-entities/core" emoi "simrs-vx/internal/domain/main-entities/mcu-order-item" - emss "simrs-vx/internal/domain/main-entities/mcu-sub-src" + eb "simrs-vx/internal/domain/main-entities/mcu-order-sub-item/base" erc "simrs-vx/internal/domain/references/common" ) type McuOrderSubItem struct { - ecore.Main // adjust this according to the needs - McuSubSrc_Code *string `json:"mcuSubSrc_code" gorm:"uniqueIndex:idx_order_sub_src"` - McuSubSrc *emss.McuSubSrc `json:"mcuSubSrc,omitempty" gorm:"foreignKey:McuSubSrc_Code;references:Code"` - McuOrderItem_Id *uint `json:"mcuOrderItem_id" gorm:"uniqueIndex:idx_order_sub_src"` - McuOrderItem *emoi.McuOrderItem `json:"mcuOrderItem,omitempty" gorm:"foreignKey:McuOrderItem_Id;references:Id"` - Result *string `json:"result"` - Status_Code erc.DataStatusCode `json:"status_code"` + ecore.Main // adjust this according to the needs + eb.McuOrderSubItem + McuOrderItem *emoi.McuOrderItem `json:"mcuOrderItem,omitempty" gorm:"foreignKey:McuOrderItem_Id;references:Id"` } func (d McuOrderSubItem) IsCompleted() bool { diff --git a/internal/domain/main-entities/mcu-src-category/dto.go b/internal/domain/main-entities/mcu-src-category/dto.go index f9bb7d00..e1ef57d9 100644 --- a/internal/domain/main-entities/mcu-src-category/dto.go +++ b/internal/domain/main-entities/mcu-src-category/dto.go @@ -1,4 +1,4 @@ -package division +package mcusrccategory import ( ecore "simrs-vx/internal/domain/base-entities/core" @@ -20,10 +20,10 @@ type ReadListDto struct { } type FilterDto struct { - Code string `json:"code"` - Name string `json:"name"` - Scope_Code *erc.McuScopeCode `json:"scope-code"` - Search string `json:"search" gormhelper:"searchColumns=Code,Name"` + Code *string `json:"code"` + Name *string `json:"name"` + Scope_Code *string `json:"scope-code"` + Search string `json:"search" gormhelper:"searchColumns=Code,Name"` } type ReadDetailDto struct { diff --git a/internal/domain/main-entities/mcu-src-category/entity.go b/internal/domain/main-entities/mcu-src-category/entity.go index 8fc801b9..2175552c 100644 --- a/internal/domain/main-entities/mcu-src-category/entity.go +++ b/internal/domain/main-entities/mcu-src-category/entity.go @@ -1,4 +1,4 @@ -package division +package mcusrccategory import ( ecore "simrs-vx/internal/domain/base-entities/core" diff --git a/internal/domain/references/clinical/clinical.go b/internal/domain/references/clinical/clinical.go index 7a3a2ec1..43305a99 100644 --- a/internal/domain/references/clinical/clinical.go +++ b/internal/domain/references/clinical/clinical.go @@ -196,8 +196,12 @@ const ( TSCTeam TranslatorSrcCode = "team" // Tim Penerjemah TSCFamily TranslatorSrcCode = "family" // Keluarga - SFTCA ScreeningFormTypeCode = "form-a" // Formu A - SFTCB ScreeningFormTypeCode = "form-b" // Formu B + SFTCA ScreeningFormTypeCode = "form-a" // Formu A + SFTCB ScreeningFormTypeCode = "form-b" // Formu B + MSCRadiology McuScopeCode = "radiology" + MSCCpLab McuScopeCode = "cp-lab" + MSCMicroLab McuScopeCode = "micro-lab" + MSCApLab McuScopeCode = "ap-lab" SSCSmall SurgerySizeCode = "" SSCMedium SurgerySizeCode = "" From 5aa558e189439de3720db9023239e6ea6c3262b6 Mon Sep 17 00:00:00 2001 From: Munawwirul Jamal Date: Tue, 2 Dec 2025 09:34:51 +0700 Subject: [PATCH 21/38] dev: hotfix, doctor getdetail --- internal/domain/main-entities/doctor/dto.go | 1 + .../mcu-order-sub-item/base/entity.go | 15 +++++++++++++++ .../main-entities/mcu-order-sub-item/entity.go | 12 +++++------- internal/interface/main-handler/doctor/handler.go | 1 + internal/use-case/main-use-case/doctor/lib.go | 4 +++- 5 files changed, 25 insertions(+), 8 deletions(-) create mode 100644 internal/domain/main-entities/mcu-order-sub-item/base/entity.go diff --git a/internal/domain/main-entities/doctor/dto.go b/internal/domain/main-entities/doctor/dto.go index e3d1f3ee..c7eb0f6b 100644 --- a/internal/domain/main-entities/doctor/dto.go +++ b/internal/domain/main-entities/doctor/dto.go @@ -43,6 +43,7 @@ type ReadDetailDto struct { Employee_Id *uint `json:"employee_id"` IHS_Number *string `json:"ihs_number"` SIP_Number *string `json:"sip_number"` + Includes string `json:"includes"` } type UpdateDto struct { diff --git a/internal/domain/main-entities/mcu-order-sub-item/base/entity.go b/internal/domain/main-entities/mcu-order-sub-item/base/entity.go new file mode 100644 index 00000000..0022744b --- /dev/null +++ b/internal/domain/main-entities/mcu-order-sub-item/base/entity.go @@ -0,0 +1,15 @@ +package mcuordersubitem + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + + erc "simrs-vx/internal/domain/references/common" +) + +type McuOrderSubItem struct { + ecore.Main // adjust this according to the needs + McuSubSrc_Code *string `json:"mcuSubSrc_code" gorm:"uniqueIndex:idx_order_sub_src"` + McuOrderItem_Id *uint `json:"mcuOrderItem_id" gorm:"uniqueIndex:idx_order_sub_src"` + Result *string `json:"result"` + Status_Code erc.DataStatusCode `json:"status_code"` +} diff --git a/internal/domain/main-entities/mcu-order-sub-item/entity.go b/internal/domain/main-entities/mcu-order-sub-item/entity.go index a9bde496..b594a91b 100644 --- a/internal/domain/main-entities/mcu-order-sub-item/entity.go +++ b/internal/domain/main-entities/mcu-order-sub-item/entity.go @@ -5,17 +5,15 @@ import ( emoi "simrs-vx/internal/domain/main-entities/mcu-order-item" emss "simrs-vx/internal/domain/main-entities/mcu-sub-src" + emosi "simrs-vx/internal/domain/main-entities/mcu-order-sub-item/base" erc "simrs-vx/internal/domain/references/common" ) type McuOrderSubItem struct { - ecore.Main // adjust this according to the needs - McuSubSrc_Code *string `json:"mcuSubSrc_code" gorm:"uniqueIndex:idx_order_sub_src"` - McuSubSrc *emss.McuSubSrc `json:"mcuSubSrc,omitempty" gorm:"foreignKey:McuSubSrc_Code;references:Code"` - McuOrderItem_Id *uint `json:"mcuOrderItem_id" gorm:"uniqueIndex:idx_order_sub_src"` - McuOrderItem *emoi.McuOrderItem `json:"mcuOrderItem,omitempty" gorm:"foreignKey:McuOrderItem_Id;references:Id"` - Result *string `json:"result"` - Status_Code erc.DataStatusCode `json:"status_code"` + ecore.Main // adjust this according to the needs + McuSubSrc *emss.McuSubSrc `json:"mcuSubSrc,omitempty" gorm:"foreignKey:McuSubSrc_Code;references:Code"` + McuOrderItem *emoi.McuOrderItem `json:"mcuOrderItem,omitempty" gorm:"foreignKey:McuOrderItem_Id;references:Id"` + emosi.McuOrderSubItem } func (d McuOrderSubItem) IsCompleted() bool { diff --git a/internal/interface/main-handler/doctor/handler.go b/internal/interface/main-handler/doctor/handler.go index f62495d6..b700103a 100644 --- a/internal/interface/main-handler/doctor/handler.go +++ b/internal/interface/main-handler/doctor/handler.go @@ -38,6 +38,7 @@ func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) { return } dto := e.ReadDetailDto{} + sf.UrlQueryParam(&dto, *r.URL) dto.Code = &code res, err := u.ReadDetail(dto) rw.DataResponse(w, res, err) diff --git a/internal/use-case/main-use-case/doctor/lib.go b/internal/use-case/main-use-case/doctor/lib.go index 827802fa..9efe2239 100644 --- a/internal/use-case/main-use-case/doctor/lib.go +++ b/internal/use-case/main-use-case/doctor/lib.go @@ -1,6 +1,7 @@ package doctor import ( + "fmt" e "simrs-vx/internal/domain/main-entities/doctor" plh "simrs-vx/pkg/lib-helper" @@ -90,7 +91,8 @@ func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e if input.Code != nil { tx = tx.Where("\"Code\" = ?", input.Code) } - if err := tx.First(&data).Error; err != nil { + fmt.Println(input.Includes) + if err := tx.Scopes(gh.Preload(input.Includes)).First(&data).Error; err != nil { if processedErr := pu.HandleReadError(err, event, source, input.Id, data); processedErr != nil { return nil, processedErr } From 29d11c0e0089214cc8acbb5b184f0f3250b9a9e0 Mon Sep 17 00:00:00 2001 From: dpurbosakti Date: Tue, 2 Dec 2025 10:07:31 +0700 Subject: [PATCH 22/38] (screening): add file-url and status --- cmd/main-migration/migrations/20251202030445.sql | 2 ++ cmd/main-migration/migrations/atlas.sum | 5 +++-- internal/domain/main-entities/screening/entity.go | 3 +++ internal/domain/references/organization/organization.go | 1 + 4 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 cmd/main-migration/migrations/20251202030445.sql diff --git a/cmd/main-migration/migrations/20251202030445.sql b/cmd/main-migration/migrations/20251202030445.sql new file mode 100644 index 00000000..6026dd58 --- /dev/null +++ b/cmd/main-migration/migrations/20251202030445.sql @@ -0,0 +1,2 @@ +-- Modify "Screening" table +ALTER TABLE "public"."Screening" ADD COLUMN "Status" text NULL, ADD COLUMN "FileUrl" character varying(1024) NULL; diff --git a/cmd/main-migration/migrations/atlas.sum b/cmd/main-migration/migrations/atlas.sum index 5753c626..806ee054 100644 --- a/cmd/main-migration/migrations/atlas.sum +++ b/cmd/main-migration/migrations/atlas.sum @@ -1,4 +1,4 @@ -h1:6lWgIJo0vUBd7Bo4B3YMvyDpJsOTVzVfqRQ03ad9r1s= +h1:XoKMjGA4FCg2pZKaGZmX61liDEkRUDnYo+NyFKmtikw= 20250904105930.sql h1:MEM6blCgke9DzWQSTnLzasbPIrcHssNNrJqZpSkEo6k= 20250904141448.sql h1:J8cmYNk4ZrG9fhfbi2Z1IWz7YkfvhFqTzrLFo58BPY0= 20250908062237.sql h1:Pu23yEW/aKkwozHoOuROvHS/GK4ngARJGdO7FB7HZuI= @@ -131,4 +131,5 @@ h1:6lWgIJo0vUBd7Bo4B3YMvyDpJsOTVzVfqRQ03ad9r1s= 20251124071457.sql h1:qg2dhCL9YwD13xnfJ175lW/p6MGfzFKaBqd908FByRc= 20251125125303.sql h1:4JSFv1Pmhbe9tqpLXgO63OwYnGsalStgUXKVWPyc1YE= 20251126064057.sql h1:vAdhz5Nn/gGJy0UKZAEldeXv8HpHtJU/t8ygDVIbTsU= -20251201081333.sql h1:1946fD7iMnf18FjYzVNoHu6suWSDMfjaF2R7jx5gjo0= +20251201081333.sql h1:PoC8ADRdwDuohDTB74yW/DaB42igdYa4B6humbrEJBk= +20251202030445.sql h1:9VbV03AMtKKPagtLKl4+hZrE6mMFV6DG78Gn7QOsFXI= diff --git a/internal/domain/main-entities/screening/entity.go b/internal/domain/main-entities/screening/entity.go index ebdb735b..a6284c16 100644 --- a/internal/domain/main-entities/screening/entity.go +++ b/internal/domain/main-entities/screening/entity.go @@ -5,6 +5,7 @@ import ( eem "simrs-vx/internal/domain/main-entities/employee" erc "simrs-vx/internal/domain/references/clinical" + erco "simrs-vx/internal/domain/references/common" ) type Screening struct { @@ -13,5 +14,7 @@ type Screening struct { Employee_Id *uint `json:"employee_id"` Employee *eem.Employee `json:"employee,omitempty" gorm:"foreignKey:Employee_Id;references:Id"` Type erc.ScreeningFormTypeCode `json:"type"` + Status erco.DataVerifiedCode `json:"status"` Value *string `json:"value"` + FileUrl *string `json:"fileUrl" gorm:"size:1024"` } diff --git a/internal/domain/references/organization/organization.go b/internal/domain/references/organization/organization.go index e12531cd..e522a35e 100644 --- a/internal/domain/references/organization/organization.go +++ b/internal/domain/references/organization/organization.go @@ -24,6 +24,7 @@ const ( EPCLab EmployeePositionCode = "lab" // Laboran EPCPha EmployeePositionCode = "pha" // Farmasi EPCNom EmployeePositionCode = "nom" // Non Medic + EPCScr EmployeePositionCode = "scr" // Screening MPP // EPCPay EmployeePositionCode = "pay" // Pembayaran // EPCHur EmployeePositionCode = "hue" // Sumber Daya Manusia // EPCGea EmployeePositionCode = "gea" // Bagian Umum From f4f47118824bf1b6fbb3a21ec78d204c3b509404 Mon Sep 17 00:00:00 2001 From: Munawwirul Jamal Date: Tue, 2 Dec 2025 11:46:02 +0700 Subject: [PATCH 23/38] feat/mcu-order: adjust entity --- cmd/main-migration/migrations/20251202044430.sql | 2 ++ cmd/main-migration/migrations/atlas.sum | 8 +++++--- internal/domain/main-entities/item/dto.go | 4 ++++ internal/domain/main-entities/item/entity.go | 2 ++ 4 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 cmd/main-migration/migrations/20251202044430.sql diff --git a/cmd/main-migration/migrations/20251202044430.sql b/cmd/main-migration/migrations/20251202044430.sql new file mode 100644 index 00000000..308b72a7 --- /dev/null +++ b/cmd/main-migration/migrations/20251202044430.sql @@ -0,0 +1,2 @@ +-- Modify "Item" table +ALTER TABLE "public"."Item" ADD COLUMN "BuyingPrice" numeric NULL, ADD COLUMN "SellingPrice" numeric NULL; diff --git a/cmd/main-migration/migrations/atlas.sum b/cmd/main-migration/migrations/atlas.sum index 51161909..871cc312 100644 --- a/cmd/main-migration/migrations/atlas.sum +++ b/cmd/main-migration/migrations/atlas.sum @@ -1,4 +1,4 @@ -h1:bYhAmgY4p8jgE8JpZ6YeJyS1iYCH2LEvDXW2PE+iZpc= +h1:Ha8JZHXBp6W+fzzWOIT8TuDGwBAPu7d/JQa4hxKMCRw= 20250904105930.sql h1:MEM6blCgke9DzWQSTnLzasbPIrcHssNNrJqZpSkEo6k= 20250904141448.sql h1:J8cmYNk4ZrG9fhfbi2Z1IWz7YkfvhFqTzrLFo58BPY0= 20250908062237.sql h1:Pu23yEW/aKkwozHoOuROvHS/GK4ngARJGdO7FB7HZuI= @@ -135,5 +135,7 @@ h1:bYhAmgY4p8jgE8JpZ6YeJyS1iYCH2LEvDXW2PE+iZpc= 20251201104439.sql h1:tpqdrOf9d2aGwZshqm62nG6SXnfVaO/g6A7z0efPS14= 20251201113804.sql h1:kIEmVoETJXBkab2Q+b3y/pP84eF8W2BdQ47amHCnc+c= 20251201113858.sql h1:KLXKZO5XTQPoEU0YLHE8Fhg9WPKpSN3wNgYPJ+RGFcg= -20251201114751.sql h1:QMcFLz4vr6lwQ03k0Wthhosce743DW9A3w6WJzfqjoU= -20251201114913.sql h1:GvRLyn62Z5CIckonFhtHOZKbJK43yyoCXUfFiADLiAo= +20251201114751.sql h1:HM17diiPknfSHAmP+kJGP6GzToaPU9/NT+KQBpf3Jq0= +20251201114913.sql h1:gqucFgHFFLA6n/Rdz486cZH5xkaJuwefESLJMJLDue8= +20251202030445.sql h1:QWBVfTepT7DaXP5E0BYoxNM0JwKIQ2qIMXzI4kbz/qE= +20251202044430.sql h1:OC5NTh0Jf8NNLVTRIvNImPiaMqJfDWkksxWcKq3UjDE= diff --git a/internal/domain/main-entities/item/dto.go b/internal/domain/main-entities/item/dto.go index f20ce217..686a5c17 100644 --- a/internal/domain/main-entities/item/dto.go +++ b/internal/domain/main-entities/item/dto.go @@ -62,6 +62,8 @@ type ResponseDto struct { Uom *eu.Uom `json:"uom,omitempty"` Infra_Code *string `json:"infra_code"` Stock *int `json:"stock"` + BuyingPrice *float64 `json:"buyingPrice"` + SellingPrice *float64 `json:"sellingPrice"` } func (d Item) ToResponse() ResponseDto { @@ -73,6 +75,8 @@ func (d Item) ToResponse() ResponseDto { Uom: d.Uom, Infra_Code: d.Infra_Code, Stock: d.Stock, + BuyingPrice: d.BuyingPrice, + SellingPrice: d.SellingPrice, } resp.Main = d.Main return resp diff --git a/internal/domain/main-entities/item/entity.go b/internal/domain/main-entities/item/entity.go index fc721713..55ca2d18 100644 --- a/internal/domain/main-entities/item/entity.go +++ b/internal/domain/main-entities/item/entity.go @@ -16,4 +16,6 @@ type Item struct { Uom *eu.Uom `json:"uom,omitempty" gorm:"foreignKey:Uom_Code;references:Code"` Infra_Code *string `json:"infra_code" gorm:"size:10"` Stock *int `json:"stock"` + BuyingPrice *float64 `json:"buyingPrice"` + SellingPrice *float64 `json:"settlingPrice"` } From 050ba953e1df7fcedc3f1b352b5a3c3f31d579d7 Mon Sep 17 00:00:00 2001 From: dpurbosakti Date: Tue, 2 Dec 2025 13:42:55 +0700 Subject: [PATCH 24/38] update size type soapi --- cmd/main-migration/migrations/20251202064000.sql | 2 ++ cmd/main-migration/migrations/atlas.sum | 5 +++-- internal/domain/main-entities/soapi/entity.go | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) create mode 100644 cmd/main-migration/migrations/20251202064000.sql diff --git a/cmd/main-migration/migrations/20251202064000.sql b/cmd/main-migration/migrations/20251202064000.sql new file mode 100644 index 00000000..7fed5f08 --- /dev/null +++ b/cmd/main-migration/migrations/20251202064000.sql @@ -0,0 +1,2 @@ +-- Modify "Soapi" table +ALTER TABLE "public"."Soapi" ALTER COLUMN "TypeCode" TYPE character varying(15); diff --git a/cmd/main-migration/migrations/atlas.sum b/cmd/main-migration/migrations/atlas.sum index 871cc312..8db69226 100644 --- a/cmd/main-migration/migrations/atlas.sum +++ b/cmd/main-migration/migrations/atlas.sum @@ -1,4 +1,4 @@ -h1:Ha8JZHXBp6W+fzzWOIT8TuDGwBAPu7d/JQa4hxKMCRw= +h1:uY633gN3JQVVq1z4wKVtoTt3D/bOrBmBqSgjzNxIY7U= 20250904105930.sql h1:MEM6blCgke9DzWQSTnLzasbPIrcHssNNrJqZpSkEo6k= 20250904141448.sql h1:J8cmYNk4ZrG9fhfbi2Z1IWz7YkfvhFqTzrLFo58BPY0= 20250908062237.sql h1:Pu23yEW/aKkwozHoOuROvHS/GK4ngARJGdO7FB7HZuI= @@ -138,4 +138,5 @@ h1:Ha8JZHXBp6W+fzzWOIT8TuDGwBAPu7d/JQa4hxKMCRw= 20251201114751.sql h1:HM17diiPknfSHAmP+kJGP6GzToaPU9/NT+KQBpf3Jq0= 20251201114913.sql h1:gqucFgHFFLA6n/Rdz486cZH5xkaJuwefESLJMJLDue8= 20251202030445.sql h1:QWBVfTepT7DaXP5E0BYoxNM0JwKIQ2qIMXzI4kbz/qE= -20251202044430.sql h1:OC5NTh0Jf8NNLVTRIvNImPiaMqJfDWkksxWcKq3UjDE= +20251202044430.sql h1:4QZH9lz0GrQ9rzP1AJ+hJgGalNpp+8FCRckNK7xaTbU= +20251202064000.sql h1:CcrTalr9bg48srSwCzcswS/erCTD93y72+cINyrHp2o= diff --git a/internal/domain/main-entities/soapi/entity.go b/internal/domain/main-entities/soapi/entity.go index 7e457ca9..d67f692a 100644 --- a/internal/domain/main-entities/soapi/entity.go +++ b/internal/domain/main-entities/soapi/entity.go @@ -17,6 +17,6 @@ type Soapi struct { Employee_Id *uint `json:"employee_id"` Employee *eem.Employee `json:"employee,omitempty" gorm:"foreignKey:Employee_Id;references:Id"` Time *time.Time `json:"time"` - TypeCode erc.SoapiTypeCode `json:"type_code" gorm:"size:11"` + TypeCode erc.SoapiTypeCode `json:"type_code" gorm:"size:15"` Value *string `json:"value"` } From 2ebe23f943f50cfb5a4d7573729edf82918bce67 Mon Sep 17 00:00:00 2001 From: Munawwirul Jamal Date: Tue, 2 Dec 2025 11:46:02 +0700 Subject: [PATCH 25/38] feat/order-things: adjust mcu-order to pricing --- cmd/main-migration/migrations/20251202044430.sql | 2 ++ cmd/main-migration/migrations/atlas.sum | 8 +++++--- internal/domain/main-entities/item/dto.go | 4 ++++ internal/domain/main-entities/item/entity.go | 2 ++ .../use-case/main-use-case/mcu-order-item/case.go | 11 +++++------ 5 files changed, 18 insertions(+), 9 deletions(-) create mode 100644 cmd/main-migration/migrations/20251202044430.sql diff --git a/cmd/main-migration/migrations/20251202044430.sql b/cmd/main-migration/migrations/20251202044430.sql new file mode 100644 index 00000000..308b72a7 --- /dev/null +++ b/cmd/main-migration/migrations/20251202044430.sql @@ -0,0 +1,2 @@ +-- Modify "Item" table +ALTER TABLE "public"."Item" ADD COLUMN "BuyingPrice" numeric NULL, ADD COLUMN "SellingPrice" numeric NULL; diff --git a/cmd/main-migration/migrations/atlas.sum b/cmd/main-migration/migrations/atlas.sum index 51161909..871cc312 100644 --- a/cmd/main-migration/migrations/atlas.sum +++ b/cmd/main-migration/migrations/atlas.sum @@ -1,4 +1,4 @@ -h1:bYhAmgY4p8jgE8JpZ6YeJyS1iYCH2LEvDXW2PE+iZpc= +h1:Ha8JZHXBp6W+fzzWOIT8TuDGwBAPu7d/JQa4hxKMCRw= 20250904105930.sql h1:MEM6blCgke9DzWQSTnLzasbPIrcHssNNrJqZpSkEo6k= 20250904141448.sql h1:J8cmYNk4ZrG9fhfbi2Z1IWz7YkfvhFqTzrLFo58BPY0= 20250908062237.sql h1:Pu23yEW/aKkwozHoOuROvHS/GK4ngARJGdO7FB7HZuI= @@ -135,5 +135,7 @@ h1:bYhAmgY4p8jgE8JpZ6YeJyS1iYCH2LEvDXW2PE+iZpc= 20251201104439.sql h1:tpqdrOf9d2aGwZshqm62nG6SXnfVaO/g6A7z0efPS14= 20251201113804.sql h1:kIEmVoETJXBkab2Q+b3y/pP84eF8W2BdQ47amHCnc+c= 20251201113858.sql h1:KLXKZO5XTQPoEU0YLHE8Fhg9WPKpSN3wNgYPJ+RGFcg= -20251201114751.sql h1:QMcFLz4vr6lwQ03k0Wthhosce743DW9A3w6WJzfqjoU= -20251201114913.sql h1:GvRLyn62Z5CIckonFhtHOZKbJK43yyoCXUfFiADLiAo= +20251201114751.sql h1:HM17diiPknfSHAmP+kJGP6GzToaPU9/NT+KQBpf3Jq0= +20251201114913.sql h1:gqucFgHFFLA6n/Rdz486cZH5xkaJuwefESLJMJLDue8= +20251202030445.sql h1:QWBVfTepT7DaXP5E0BYoxNM0JwKIQ2qIMXzI4kbz/qE= +20251202044430.sql h1:OC5NTh0Jf8NNLVTRIvNImPiaMqJfDWkksxWcKq3UjDE= diff --git a/internal/domain/main-entities/item/dto.go b/internal/domain/main-entities/item/dto.go index f20ce217..686a5c17 100644 --- a/internal/domain/main-entities/item/dto.go +++ b/internal/domain/main-entities/item/dto.go @@ -62,6 +62,8 @@ type ResponseDto struct { Uom *eu.Uom `json:"uom,omitempty"` Infra_Code *string `json:"infra_code"` Stock *int `json:"stock"` + BuyingPrice *float64 `json:"buyingPrice"` + SellingPrice *float64 `json:"sellingPrice"` } func (d Item) ToResponse() ResponseDto { @@ -73,6 +75,8 @@ func (d Item) ToResponse() ResponseDto { Uom: d.Uom, Infra_Code: d.Infra_Code, Stock: d.Stock, + BuyingPrice: d.BuyingPrice, + SellingPrice: d.SellingPrice, } resp.Main = d.Main return resp diff --git a/internal/domain/main-entities/item/entity.go b/internal/domain/main-entities/item/entity.go index fc721713..55ca2d18 100644 --- a/internal/domain/main-entities/item/entity.go +++ b/internal/domain/main-entities/item/entity.go @@ -16,4 +16,6 @@ type Item struct { Uom *eu.Uom `json:"uom,omitempty" gorm:"foreignKey:Uom_Code;references:Code"` Infra_Code *string `json:"infra_code" gorm:"size:10"` Stock *int `json:"stock"` + BuyingPrice *float64 `json:"buyingPrice"` + SellingPrice *float64 `json:"settlingPrice"` } diff --git a/internal/use-case/main-use-case/mcu-order-item/case.go b/internal/use-case/main-use-case/mcu-order-item/case.go index 9037b771..e04feded 100644 --- a/internal/use-case/main-use-case/mcu-order-item/case.go +++ b/internal/use-case/main-use-case/mcu-order-item/case.go @@ -4,11 +4,7 @@ import ( "errors" "strconv" - e "simrs-vx/internal/domain/main-entities/mcu-order-item" - - umo "simrs-vx/internal/use-case/main-use-case/mcu-order" - - erc "simrs-vx/internal/domain/references/common" + "gorm.io/gorm" dg "github.com/karincake/apem/db-gorm-pg" d "github.com/karincake/dodol" @@ -16,7 +12,10 @@ import ( pl "simrs-vx/pkg/logger" pu "simrs-vx/pkg/use-case-helper" - "gorm.io/gorm" + e "simrs-vx/internal/domain/main-entities/mcu-order-item" + erc "simrs-vx/internal/domain/references/common" + + umo "simrs-vx/internal/use-case/main-use-case/mcu-order" ) const source = "mcu-order-item" From fd7609b080ee2e687f3da9145898627b546d06c6 Mon Sep 17 00:00:00 2001 From: dpurbosakti Date: Tue, 2 Dec 2025 14:14:05 +0700 Subject: [PATCH 26/38] add amb-resume into soapitypecode --- internal/domain/references/clinical/clinical.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/domain/references/clinical/clinical.go b/internal/domain/references/clinical/clinical.go index 43305a99..91642b1e 100644 --- a/internal/domain/references/clinical/clinical.go +++ b/internal/domain/references/clinical/clinical.go @@ -133,6 +133,7 @@ const ( STCDevRecord SoapiTypeCode = "dev-record" // Catatan Perkembangan STCKfrAdm SoapiTypeCode = "kfr-adm" // soapi untuk kfr STCKfrSeries SoapiTypeCode = "kfr-series" // soapi untuk kfr + STCAmbResume SoapiTypeCode = "amb-resume" // Rajal resume MATCChemo MedicalActionTypeCode = "chemo" MATCHemo MedicalActionTypeCode = "hemo" From ce8f3c35a097b22eaebd9eb21c524c429cf7fce5 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Tue, 2 Dec 2025 14:17:52 +0700 Subject: [PATCH 27/38] migration from server --- cmd/main-migration/migrations/atlas.sum | 132 ++++++++++++------------ 1 file changed, 66 insertions(+), 66 deletions(-) diff --git a/cmd/main-migration/migrations/atlas.sum b/cmd/main-migration/migrations/atlas.sum index 8db69226..f7e6e583 100644 --- a/cmd/main-migration/migrations/atlas.sum +++ b/cmd/main-migration/migrations/atlas.sum @@ -1,4 +1,4 @@ -h1:uY633gN3JQVVq1z4wKVtoTt3D/bOrBmBqSgjzNxIY7U= +h1:gwV43DB5Cr+YkOe2Y2ywd4ySwyrsK4y1yZ9nfSrSf7Q= 20250904105930.sql h1:MEM6blCgke9DzWQSTnLzasbPIrcHssNNrJqZpSkEo6k= 20250904141448.sql h1:J8cmYNk4ZrG9fhfbi2Z1IWz7YkfvhFqTzrLFo58BPY0= 20250908062237.sql h1:Pu23yEW/aKkwozHoOuROvHS/GK4ngARJGdO7FB7HZuI= @@ -75,68 +75,68 @@ h1:uY633gN3JQVVq1z4wKVtoTt3D/bOrBmBqSgjzNxIY7U= 20251106040137.sql h1:ppcqkVoT0o9jZcjI/TN7LuaPxXhJQhnIXEJtloP/46o= 20251106041333.sql h1:2JkxyelQ/EeB+boL5bfpnzefw32ttEGKvKchtQjWmAU= 20251106042006.sql h1:ruppYa1kAJQUU3ufQBbKGMcXrGbGJJiRPclT+dNc/YQ= -20251106050412.sql h1:1002KYtHd8AwrQTMewbs/PPHDylHDghigE/3S7PVdMA= -20251106063418.sql h1:jPW/gBnbFl4RO39lQ0ZMDtYA6xbhyD6CgQupT50HmaY= -20251106071906.sql h1:leYGKxR3EQn794aOehf0sd/ZPmOnvBMZPy5/anGmRB4= -20251106073157.sql h1:KASMzjjjk5UB7Zj8lCRtM1utc4ZnDjlnpZbtTe3vONE= -20251106074218.sql h1:Z5q5deOvLaZDPhiVTN9st3/s56RepBa2YOyrMXBdj4A= -20251106081846.sql h1:P+VsWwhGt60adDIZuE/Aa38JVp/yX1rnsdpXpxASodw= -20251106082844.sql h1:Dmi5A8i9frQZvdXYPwc7f8CisZtBH8liSXq1rI6z1iM= -20251106090021.sql h1:4JwdKgO8T46YhyWVJUxpRIwudBDlG8QN1brSOYmgQ20= -20251106144745.sql h1:nqnQCzGrVJaq8ilOEOGXeRUL1dolj+OPWKuP8A92FRA= -20251107012049.sql h1:Pff4UqltGS3clSlGr0qq8CQM56L29wyxY0FC/N/YAhU= -20251107064812.sql h1:GB9a0ZfMYTIoGNmKUG+XcYUsTnRMFfT4/dAD71uCPc4= -20251107064937.sql h1:IC5pw1Ifj30hiE6dr5NMHXaSHoQI+vRd40N5ABgBHRI= -20251107071420.sql h1:9NO3iyLEXEtWa2kSRjM/8LyzuVIk6pdFL2SuheWjB08= -20251107074318.sql h1:7fHbSRrdjOmHh/xwnjCLwoiB5cW5zeH+uxLV0vZbkIA= -20251107075050.sql h1:np+3uTOnU9QNtK7Knaw8eRMhkyB9AwrtSNHphOBxbHY= -20251107080604.sql h1:cXDBLPJDVWLTG6yEJqkJsOQ7p7VYxLM2SY+mwO8qSHo= -20251107081830.sql h1:/S7OQZo4ZnK80t28g/JyiOTZtmWG/dP5Wg2zXNMQ/iE= -20251107091033.sql h1:/cbkF1nO/IjNSIfDJJx456KJtQ9rWFXOBFAkR/M2xiE= -20251107091209.sql h1:jrLQOUeV8ji2fg0pnEcs1bw4ANUxzTSMXC/rrHLIY+M= -20251107091541.sql h1:6UqbhQQRmzA2+eKu5lIvkwOkk+lH70QLZC8Pjpjcq68= -20251110012217.sql h1:C9HpX0iyHzKjyNv/5DSAn2MCHj6MX4p5UQ/NrY7QD0w= -20251110012306.sql h1:J54yb27d30LBbYp9n1P66gFVRlxPguKu0kxmWIBBG8g= -20251110052049.sql h1:232T2x8xTczJl9nk4jxJpZXhoOGYthhxjJ7nK8Jd8vg= -20251110062042.sql h1:WnfVUXrzYoj8qdkkjO9/JQQ8agGd4GfSHQdMjo7LDAg= -20251110063202.sql h1:hSzGfwVMWa6q3vwIQZUkxKgBNCzHjB+6GKy54zfV+oQ= -20251110063633.sql h1:/VpofIAqNS1CnazEnpW/+evbzn9Kew3xDW48r57M+Xg= -20251110085551.sql h1:bFZwSmfvVbTUr/enWB82WqjG88gpqcZ6s45btUvO0uo= -20251110091516.sql h1:KkJMwPQuaZQhiqnKrNQrgP12gw9rV8T3P2o3mtGTcvY= -20251110091948.sql h1:I4odAYrJdvNf1jPw6ppDC0XdI7v6vKBACg/ABwUgA7I= -20251110092729.sql h1:l1out8soEmVP6dNjaIOtGYo6QDcoJZRI8X1sjZ5ZGmo= -20251110093522.sql h1:nsz8jCxGjEdr/bz9g+4ozfZzIP803xONjVmucad1GMc= -20251110100258.sql h1:IBqt1VZj5WjQ+l9aAFGHOCCBtzb03KlLLihFLut7itg= -20251110100545.sql h1:6/LV7751iyKxE2xI6vO1zly+aHUwxXD/IBwLcVpKxqM= -20251110155448.sql h1:kFPobJB+cpflsXBAWUwy3lohuWvrb/VRlXnhJWl7i3Y= -20251111072601.sql h1:ch8F+yVhsSM5xY+TwMLY3PxdLa4Wuhtj76oyw79R7Js= -20251111073546.sql h1:cCv0NPscADAOBahRVqtDWFs6G2t7n+4a+RwlF8vk/c4= -20251111074148.sql h1:70TsV83u1gQ5TktI13K7NQiyCCa35Td2aR6CNtKUa4U= -20251111074652.sql h1:ddfQ/sRKMezPM75xBFTGytUQX5AwZ3znrJVpg73gKPA= -20251111082257.sql h1:ZsdLY1ROouos0l3oS0lkeSiuKLEUGbVvBhpcM2AVhkw= -20251111111017.sql h1:qrJ93dNtQwcuAvpsP/lAK/H63C4cinXrsVaPmWsTqkU= -20251113101344.sql h1:xaOZvAUP1fFfnO+syEFOzJUIg5lTfBe5AWHPbBWuCLA= -20251113120533.sql h1:f3/U1Ve2yF2zSMhkt+xtwF8wUYfUKYwgbNeGfE37EW4= -20251114062746.sql h1:FInLaEFQByESEwFJKuKnuUSTKmcDpi3ZXaxkKwz2+D8= -20251117005942.sql h1:wD3BWrUSmo1HlW16V3lkaBkJvbAZ0fNk77te7J9NhOc= -20251117075427.sql h1:TqU9VKZa3I8YNXUGQWY3WVBYN+1FvyyaKy0hB1jgAho= -20251118074929.sql h1:p1KsWqCuR1JXA/jVO5BmOhCcaQ8clT7t0YRszAhPFbg= -20251119063438.sql h1:NVGM0X/LHD37EaPl8SNzkNiZDJ7AB1QR+LLwLh6WRdg= -20251119065730.sql h1:U5lzk1WvMB0bw3kwckou7jkEt4bwdYItwHr2Vxqe7w4= -20251119072302.sql h1:qCuI2WMEMF/XNbjV+RXPjBnuCKLu1Fia+mR9HiLWBIs= -20251119072450.sql h1:Xg+bTwqGyKPNFEQhJylvpz1wifdfmDJvcAq6vmNf0Ng= -20251120005512.sql h1:Ek6qpacAI/qVuTYxKno+uJyzn7s5z9pf3t7VA8gTzm4= -20251120074415.sql h1:NNUeJVA03EeBHJhHqPXEZoDv/PnC6yK1/cRhmukyaJo= -20251121033803.sql h1:/vfvFX/3pzSCIHnSbMUT9EMBDykOpVkvyfeTEle9Vas= -20251124071457.sql h1:qg2dhCL9YwD13xnfJ175lW/p6MGfzFKaBqd908FByRc= -20251125125303.sql h1:4JSFv1Pmhbe9tqpLXgO63OwYnGsalStgUXKVWPyc1YE= -20251126064057.sql h1:vAdhz5Nn/gGJy0UKZAEldeXv8HpHtJU/t8ygDVIbTsU= -20251201081333.sql h1:PoC8ADRdwDuohDTB74yW/DaB42igdYa4B6humbrEJBk= -20251201104439.sql h1:tpqdrOf9d2aGwZshqm62nG6SXnfVaO/g6A7z0efPS14= -20251201113804.sql h1:kIEmVoETJXBkab2Q+b3y/pP84eF8W2BdQ47amHCnc+c= -20251201113858.sql h1:KLXKZO5XTQPoEU0YLHE8Fhg9WPKpSN3wNgYPJ+RGFcg= -20251201114751.sql h1:HM17diiPknfSHAmP+kJGP6GzToaPU9/NT+KQBpf3Jq0= -20251201114913.sql h1:gqucFgHFFLA6n/Rdz486cZH5xkaJuwefESLJMJLDue8= -20251202030445.sql h1:QWBVfTepT7DaXP5E0BYoxNM0JwKIQ2qIMXzI4kbz/qE= -20251202044430.sql h1:4QZH9lz0GrQ9rzP1AJ+hJgGalNpp+8FCRckNK7xaTbU= -20251202064000.sql h1:CcrTalr9bg48srSwCzcswS/erCTD93y72+cINyrHp2o= +20251106050412.sql h1:MiEMJ1HCFYnalKuq3Z38xJeogfBAMqsTv2sG4EF8dDw= +20251106063418.sql h1:y3veDJPjKekOWLCZek/LgQwXPRhZtOppTfUXiqoL95s= +20251106071906.sql h1:/TUZA3XpMY23qEJXdkTwlzrNMvSSl6JJniPcgAttBaw= +20251106073157.sql h1:78txeibJ602DMD7huD618ZSMt6phSRzDNPTlo0PGyrc= +20251106074218.sql h1:8Xz7WywrtUnSxOHhlal53gG9rE7r86LFUt5zBFe/mIs= +20251106081846.sql h1:jp91Bf5bxGXMiUB1VIuN6y768vb2iWwow44WfCE5J5k= +20251106082844.sql h1:RHYzRO4G1fSWwf+xc/3QezZ/Iil67cZPIgNpNz3TNhQ= +20251106090021.sql h1:dFDk6mq+zjbYWmfWIrHf9DiKvvoXHjrr0++zssMTWP8= +20251106144745.sql h1:aHcr23iBFqCHer5D/SsPMXBCLjGqUYvWYfRU8jSJgIw= +20251107012049.sql h1:hu/7NHhnAkT4xK0RNtqmMDdH1Bo5EZbl7itDRjiCT+g= +20251107064812.sql h1:sfCXDQYnMf0ddrQ9oYljWJLLSt9NJjJV6o8VS3p7aZE= +20251107064937.sql h1:DlYGJ9LZFwZyR7jBP5zaGB128aIc4HAixBKPYCz9EkY= +20251107071420.sql h1:ynCdZAd2utLl+FhtWZwtahNXgIVOvuk3s/rOq7lfXA4= +20251107074318.sql h1:WE9cPhibWtZ0dbu1VEGirTeY6ijFYGMNhHdBtM32kOc= +20251107075050.sql h1:8tvneruqdynDOaJK1+0z4CH7YXZStZpGdqwIeOMLik4= +20251107080604.sql h1:8c4jd4Tql7tcdhbI9NS0tgvN+ADu9FnCf8wMUbmW7A0= +20251107081830.sql h1:SAAe3lmsm9vGXuSEsDdl7ad0EAxP5CMmFRDEgp9M7yY= +20251107091033.sql h1:JLdX/u7GUdBfjrPrMSNAqc8HtSoj0YA9iW9Vc6FJZdw= +20251107091209.sql h1:CzhYtwAwT+GHrbqcagnJE+v3mbl/rObf1IJaLCKlzrs= +20251107091541.sql h1:+3ZyWJTftDY2JeWThXuIxGWpUBnyMPyOyY4jBjdWYJI= +20251110012217.sql h1:f4Z8TuGc+XMSJ+Ekn4/PeHRE2FlHWkc5gKPJB0hAX7c= +20251110012306.sql h1:ENPyI6Kjdk6qKJQb0yJ6MCTDPAmO1WD/uhKuCSl+jYo= +20251110052049.sql h1:OrQ0acnyoQLKnTitZfnBcVr5jDslF59OFLaqT7SpdVs= +20251110062042.sql h1:9KwldQt0NpVPR86L0T4hlkfHAGau+7CiZYgu5rF+yhg= +20251110063202.sql h1:A117DuZmZ6U0jWHA3DISnr+yvBjKIr1ObrUr047YezQ= +20251110063633.sql h1:qTiC0F19JnhUIXF4LGJQ21jEV6kKGyhTr1x2kimFqPQ= +20251110085551.sql h1:HZcJM0RSC6HBaUSjKBE8MgDG8Vn9f3LmwA/OnT9Cp7I= +20251110091516.sql h1:W3AQhQLgirEWuCObbLl+Prdrbq6k6EEY1xcoWsmbog4= +20251110091948.sql h1:3tsITMrZr/T+L4wqUMz8sHS229jCJl4T0Nu3dMccxH8= +20251110092729.sql h1:uU+k88RH/e0Ns4/SmJl03RVYPscBAPuiLfxR6CJqaf0= +20251110093522.sql h1:O7upSj8VNjzvroL4IU59bfxKATOkAVGBArcUbVNq9aM= +20251110100258.sql h1://JSArUMNI3/gAtYDx2VN94C198SFW0ANjgs+p6eCRM= +20251110100545.sql h1:ENPOqeJYRpMI4e8VCKwaQgaql8se6pIidAhG2cjskBg= +20251110155448.sql h1:VW9KE0jxWy4flZ28sdXmhY6JWd6eKAX/cVL8KWRVii4= +20251111072601.sql h1:99WWzGjcDDFNC2cHRfPu4MBLWNrgPMY5HAYUbmIcVRA= +20251111073546.sql h1:iIGwFNfUgStdczw/PXTH3SD84xAyxrbZICofc3M8TMk= +20251111074148.sql h1:mzkezSKwCV2bTZ/0BHiTCX5qAy4uHpwar1xzwAH15Ko= +20251111074652.sql h1:lYh4/3BHV24pgPC0pP4RUKb+XtL/6AsZGPItRpnzBiQ= +20251111082257.sql h1:+cIZ1lf8HYGSL6t6U88plLKk8nOO1YVdV7h3YOM84ds= +20251111111017.sql h1:xzlhR2xLfOj4ddYlesS+bpEeDrxiAf5ILNOspsbZjBU= +20251113101344.sql h1:vSzThY3p6XYTj0dJ2uFVkHmlytyrFAnGE58CJLx364I= +20251113120533.sql h1:lfjgdqRGo/EohrVw8sWlFbDjh3ASTsfQ6pr3qjafqvc= +20251114062746.sql h1:6DLYjfJ60PkAABZTXvOwSE+xrU25oyoX7gpYlBnA9cw= +20251117005942.sql h1:0XoJKca8IOaB9QKFVF/qPY7jKcIgh6m/LODQuE06SAs= +20251117075427.sql h1:LhY2urosfoSu1/vkHmgsNP4JA4DuWBs9gL59yMqcF8M= +20251118074929.sql h1:3RWBD6BziQVw6WSfthgoVuhTELHER9NrIuZm4hY/F1A= +20251119063438.sql h1:EVTG3ZrHjCmM95YPASZTRPiwHrG6e33A2vO4hLSAaBQ= +20251119065730.sql h1:s98wnZOCW6NbnwDS3H53XIQ60u6B9bDwBLNvy5+Rn64= +20251119072302.sql h1:ZL+VHekLYqgNtOFKlj02WHrAk11dtTxQkmyTKE8IOzY= +20251119072450.sql h1:SiJy2vpSvoPFw4J1SW7HjGSJzrqR62NsjRYAeabV+kc= +20251120005512.sql h1:hJUaWXYJ3HiSquBTw8OKhymjA4O43ehAMGfiOY8W87Q= +20251120074415.sql h1:dNmcqZHqfZwi/wtYvO/pSFgImN2scXL0p/7g0+HLp0s= +20251121033803.sql h1:onlddYGo+tQdGaEdJPqdsx3sncGnwEvqMSCksF6vjjI= +20251124071457.sql h1:ikQLIXFikUbkUd55uJBmEvqLGEC9t0db+Om4TQsWP7M= +20251125125303.sql h1:OLKbNPO36AHtIDursW9AeBvf60sahQKC1iOjHmpx0MA= +20251126064057.sql h1:6al3PTWbw/WGiBcrRrVWppOMLtG+eRaH/qSLbnmh1kQ= +20251201081333.sql h1:dD+jcisoUYnxRYWdtVcnxbDeYjUW12/R/qarYQr+utg= +20251201104439.sql h1:h4tz5uetbCKeOI3agSVmAeh6jUfECYy0LhQ7HooYhzg= +20251201113804.sql h1:DdUzqfLdy4AUpVSRFDrIJXntGmtKgZrtvv8MAT4mMxs= +20251201113858.sql h1:XSpicm4aWjrfeY5EYIiw8Ios9v7BGfzZJxpW/57Qwqs= +20251201114751.sql h1:qx+ShdHLacVFcRwwGrW1zMKFHOjMGdnusk7CEfyV8ig= +20251201114913.sql h1:6l/m2/6fmTIjFmKio0QmB8oTwBDCHTIkbuYTODQ7Gwk= +20251202030445.sql h1:5+6ss5KdN6pll8Qtf0RGGyy/BURNO3dBgIBJOzDb624= +20251202044430.sql h1:nJtlQDGj7ZJtJ07NYcF41JCn9ck50GyDPoitTOe8P/s= +20251202064000.sql h1:yzSMOPZrpvQf+u6CxD6LwNySNH9Ip1u70UEf2vWI5w4= From 9698210fb2e2bbc4df73c21c55a651d66bd511c2 Mon Sep 17 00:00:00 2001 From: Munawwirul Jamal Date: Tue, 2 Dec 2025 20:16:42 +0700 Subject: [PATCH 28/38] feat/order-things: adjust entities --- .../migrations/20251202130629.sql | 101 ++++++++++++++++++ cmd/main-migration/migrations/atlas.sum | 4 +- .../device-package-item/device-package/dto.go | 63 +++++++++++ .../device-package/entity.go | 11 ++ .../main-entities/device-package-item/dto.go | 69 ++++++++++++ .../device-package-item/entity.go | 15 +++ .../main-entities/device-package/dto.go | 63 +++++++++++ .../main-entities/device-package/entity.go | 11 ++ internal/domain/main-entities/infra/dto.go | 29 ++--- internal/domain/main-entities/infra/entity.go | 22 ++-- .../main-entities/installation/entity.go | 2 +- .../material-package-item/dto.go | 69 ++++++++++++ .../material-package-item/entity.go | 15 +++ .../main-entities/material-package/dto.go | 63 +++++++++++ .../main-entities/material-package/entity.go | 11 ++ .../main-entities/procedure-room-order/dto.go | 70 ++++++++++++ .../procedure-room-order/entity.go | 13 +++ .../procedure-room/base/entity.go | 21 ++++ .../{room => procedure-room}/dto.go | 10 +- .../main-entities/procedure-room/entity.go | 17 +++ .../domain/main-entities/room/base/entity.go | 23 ---- internal/domain/main-entities/room/entity.go | 11 -- .../domain/main-entities/specialist/entity.go | 4 +- .../subspecialist/base/entity.go | 4 +- internal/domain/main-entities/unit/entity.go | 4 +- .../references/organization/organization.go | 20 ++-- internal/interface/migration/main-entities.go | 16 ++- 27 files changed, 680 insertions(+), 81 deletions(-) create mode 100644 cmd/main-migration/migrations/20251202130629.sql create mode 100644 internal/domain/main-entities/device-package-item/device-package/dto.go create mode 100644 internal/domain/main-entities/device-package-item/device-package/entity.go create mode 100644 internal/domain/main-entities/device-package-item/dto.go create mode 100644 internal/domain/main-entities/device-package-item/entity.go create mode 100644 internal/domain/main-entities/device-package/dto.go create mode 100644 internal/domain/main-entities/device-package/entity.go create mode 100644 internal/domain/main-entities/material-package-item/dto.go create mode 100644 internal/domain/main-entities/material-package-item/entity.go create mode 100644 internal/domain/main-entities/material-package/dto.go create mode 100644 internal/domain/main-entities/material-package/entity.go create mode 100644 internal/domain/main-entities/procedure-room-order/dto.go create mode 100644 internal/domain/main-entities/procedure-room-order/entity.go create mode 100644 internal/domain/main-entities/procedure-room/base/entity.go rename internal/domain/main-entities/{room => procedure-room}/dto.go (86%) create mode 100644 internal/domain/main-entities/procedure-room/entity.go delete mode 100644 internal/domain/main-entities/room/base/entity.go delete mode 100644 internal/domain/main-entities/room/entity.go diff --git a/cmd/main-migration/migrations/20251202130629.sql b/cmd/main-migration/migrations/20251202130629.sql new file mode 100644 index 00000000..88b685fe --- /dev/null +++ b/cmd/main-migration/migrations/20251202130629.sql @@ -0,0 +1,101 @@ +-- Modify "Consultation" table +ALTER TABLE "public"."Consultation" ALTER COLUMN "DstUnit_Code" TYPE character varying(20); +-- Modify "ControlLetter" table +ALTER TABLE "public"."ControlLetter" ALTER COLUMN "Unit_Code" TYPE character varying(20), ALTER COLUMN "Specialist_Code" TYPE character varying(20), ALTER COLUMN "Subspecialist_Code" TYPE character varying(20); +-- Modify "Encounter" table +ALTER TABLE "public"."Encounter" ALTER COLUMN "Specialist_Code" TYPE character varying(20), ALTER COLUMN "Subspecialist_Code" TYPE character varying(20), ALTER COLUMN "Unit_Code" TYPE character varying(20); +-- Modify "Chemo" table +ALTER TABLE "public"."Chemo" ALTER COLUMN "SrcUnit_Code" TYPE character varying(20); +-- Modify "Installation" table +ALTER TABLE "public"."Installation" ALTER COLUMN "Code" TYPE character varying(20); +-- Modify "InternalReference" table +ALTER TABLE "public"."InternalReference" ALTER COLUMN "Unit_Code" TYPE character varying(20); +-- Modify "PracticeSchedule" table +ALTER TABLE "public"."PracticeSchedule" ALTER COLUMN "Unit_Code" TYPE character varying(20); +-- Create "DevicePackage" table +CREATE TABLE "public"."DevicePackage" ( + "Id" serial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "Code" character varying(20) NOT NULL, + "Name" character varying(50) NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "uni_DevicePackage_Code" UNIQUE ("Code") +); +-- Create "DevicePackageItem" table +CREATE TABLE "public"."DevicePackageItem" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "DevicePackage_Code" character varying(20) NOT NULL, + "Device_Code" character varying(20) NOT NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "fk_DevicePackageItem_Device" FOREIGN KEY ("Device_Code") REFERENCES "public"."Device" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT "fk_DevicePackageItem_DevicePackage" FOREIGN KEY ("DevicePackage_Code") REFERENCES "public"."DevicePackage" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION +); +-- Create "MaterialPackage" table +CREATE TABLE "public"."MaterialPackage" ( + "Id" serial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "Code" character varying(20) NOT NULL, + "Name" character varying(50) NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "uni_MaterialPackage_Code" UNIQUE ("Code") +); +-- Create "MaterialPackageItem" table +CREATE TABLE "public"."MaterialPackageItem" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "MaterialPackage_Code" character varying(20) NOT NULL, + "Material_Code" character varying(20) NOT NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "fk_MaterialPackageItem_Material" FOREIGN KEY ("Material_Code") REFERENCES "public"."Material" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT "fk_MaterialPackageItem_MaterialPackage" FOREIGN KEY ("MaterialPackage_Code") REFERENCES "public"."MaterialPackage" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION +); +-- Modify "Infra" table +ALTER TABLE "public"."Infra" ALTER COLUMN "Code" TYPE character varying(20), ALTER COLUMN "InfraGroup_Code" TYPE character varying(20), ALTER COLUMN "Parent_Code" TYPE character varying(20); +-- Modify "Specialist" table +ALTER TABLE "public"."Specialist" ALTER COLUMN "Code" TYPE character varying(20), ALTER COLUMN "Unit_Code" TYPE character varying(20); +-- Modify "Subspecialist" table +ALTER TABLE "public"."Subspecialist" ALTER COLUMN "Code" TYPE character varying(20), ALTER COLUMN "Specialist_Code" TYPE character varying(20); +-- Modify "Unit" table +ALTER TABLE "public"."Unit" ALTER COLUMN "Code" TYPE character varying(20), ALTER COLUMN "Installation_Code" TYPE character varying(20); +-- Create "ProcedureRoom" table +CREATE TABLE "public"."ProcedureRoom" ( + "Id" serial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "Code" character varying(20) NULL, + "Infra_Code" character varying(20) NULL, + "Type_Code" character varying(10) NULL, + "Unit_Code" character varying(20) NULL, + "Specialist_Code" character varying(20) NULL, + "Subspecialist_Code" character varying(20) NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "uni_ProcedureRoom_Code" UNIQUE ("Code"), + CONSTRAINT "uni_ProcedureRoom_Infra_Code" UNIQUE ("Infra_Code"), + CONSTRAINT "fk_ProcedureRoom_Infra" FOREIGN KEY ("Infra_Code") REFERENCES "public"."Infra" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT "fk_ProcedureRoom_Specialist" FOREIGN KEY ("Specialist_Code") REFERENCES "public"."Specialist" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT "fk_ProcedureRoom_Subspecialist" FOREIGN KEY ("Subspecialist_Code") REFERENCES "public"."Subspecialist" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT "fk_ProcedureRoom_Unit" FOREIGN KEY ("Unit_Code") REFERENCES "public"."Unit" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION +); +-- Create "ProcedureRoomOrder" table +CREATE TABLE "public"."ProcedureRoomOrder" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "Encounter_Id" bigint NULL, + "Infra_Code" character varying(20) NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "fk_ProcedureRoomOrder_ProcedureRoom" FOREIGN KEY ("Infra_Code") REFERENCES "public"."ProcedureRoom" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION +); +-- Drop "Room" table +DROP TABLE "public"."Room"; diff --git a/cmd/main-migration/migrations/atlas.sum b/cmd/main-migration/migrations/atlas.sum index 11fba5b8..54858b7b 100644 --- a/cmd/main-migration/migrations/atlas.sum +++ b/cmd/main-migration/migrations/atlas.sum @@ -1,4 +1,4 @@ -h1:NjMnBBzNKOW7RxpS7I5LqVv+o/CxGkxhHt/B7CV4/tQ= +h1:cyae1SX3YSMX1LZLEsCFxcRKbVxpnp46BqFxWXJqKjs= 20250904105930.sql h1:MEM6blCgke9DzWQSTnLzasbPIrcHssNNrJqZpSkEo6k= 20250904141448.sql h1:J8cmYNk4ZrG9fhfbi2Z1IWz7YkfvhFqTzrLFo58BPY0= 20250908062237.sql h1:Pu23yEW/aKkwozHoOuROvHS/GK4ngARJGdO7FB7HZuI= @@ -140,4 +140,4 @@ h1:NjMnBBzNKOW7RxpS7I5LqVv+o/CxGkxhHt/B7CV4/tQ= 20251202030445.sql h1:QWBVfTepT7DaXP5E0BYoxNM0JwKIQ2qIMXzI4kbz/qE= 20251202044430.sql h1:4QZH9lz0GrQ9rzP1AJ+hJgGalNpp+8FCRckNK7xaTbU= 20251202064000.sql h1:/EN7sT1ol/91qW1aXWrzX+Mc3XOC/7f/LtfA0JRHpbg= -20251202122413.sql h1:uZpx6oC8BLTECZdMN69u+WTAAzdSWF70RGVB/pIxC84= +20251202130629.sql h1:LjBgQS8tKEwpC3WA0wGeO2Fs2L20kEOB6e5ljO4EdLM= diff --git a/internal/domain/main-entities/device-package-item/device-package/dto.go b/internal/domain/main-entities/device-package-item/device-package/dto.go new file mode 100644 index 00000000..26aad58a --- /dev/null +++ b/internal/domain/main-entities/device-package-item/device-package/dto.go @@ -0,0 +1,63 @@ +package devicepackage + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" +) + +type CreateDto struct { + Code string `json:"code" validate:"maxLength=20"` + Name string `json:"name" validate:"maxLength=50"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Pagination ecore.Pagination +} + +type FilterDto struct { + Code string `json:"code"` + Name string `json:"name"` +} + +type ReadDetailDto struct { + Id uint16 `json:"id"` +} + +type UpdateDto struct { + Id uint16 `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint16 `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.SmallMain + Code string `json:"code"` + Name string `json:"name"` +} + +func (d DevicePackage) ToResponse() ResponseDto { + resp := ResponseDto{ + Code: d.Code, + Name: d.Name, + } + resp.SmallMain = d.SmallMain + return resp +} + +func ToResponseList(data []DevicePackage) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/device-package-item/device-package/entity.go b/internal/domain/main-entities/device-package-item/device-package/entity.go new file mode 100644 index 00000000..1c03b44d --- /dev/null +++ b/internal/domain/main-entities/device-package-item/device-package/entity.go @@ -0,0 +1,11 @@ +package devicepackage + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" +) + +type DevicePackage struct { + ecore.SmallMain + Code string `json:"code" gorm:"unique;size:20;not null"` + Name string `json:"name" gorm:"size:50"` +} diff --git a/internal/domain/main-entities/device-package-item/dto.go b/internal/domain/main-entities/device-package-item/dto.go new file mode 100644 index 00000000..a0a224ba --- /dev/null +++ b/internal/domain/main-entities/device-package-item/dto.go @@ -0,0 +1,69 @@ +package devicepackage + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + ed "simrs-vx/internal/domain/main-entities/device" + edp "simrs-vx/internal/domain/main-entities/device-package" +) + +type CreateDto struct { + DevicePackage_Code string `json:"devicePackage_code" validate:"maxLength=20"` + Device_Code string `json:"code" validate:"maxLength=20"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Pagination ecore.Pagination +} + +type FilterDto struct { + DevicePackage_Code string `json:"devicePackage-code"` + Device_Code string `json:"code"` +} + +type ReadDetailDto struct { + Id uint `json:"id"` +} + +type UpdateDto struct { + Id uint `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.Main + DevicePackage_Code string `json:"devicePackage_code"` + DevicePackage *edp.DevicePackage `json:"devicePackage,omitempty"` + Device_Code string `json:"code"` + Device *ed.Device `json:"device,omitempty"` +} + +func (d DevicePackageItem) ToResponse() ResponseDto { + resp := ResponseDto{ + DevicePackage_Code: d.DevicePackage_Code, + DevicePackage: d.DevicePackage, + Device_Code: d.Device_Code, + Device: d.Device, + } + resp.Id = d.Id + return resp +} + +func ToResponseList(data []DevicePackageItem) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/device-package-item/entity.go b/internal/domain/main-entities/device-package-item/entity.go new file mode 100644 index 00000000..476e24e2 --- /dev/null +++ b/internal/domain/main-entities/device-package-item/entity.go @@ -0,0 +1,15 @@ +package devicepackage + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + ed "simrs-vx/internal/domain/main-entities/device" + edp "simrs-vx/internal/domain/main-entities/device-package" +) + +type DevicePackageItem struct { + ecore.Main + DevicePackage_Code string `json:"devicePackage_code" gorm:"size:20;not null"` + DevicePackage *edp.DevicePackage `json:"devicePackage" gorm:"foreignKey:DevicePackage_Code;references:Code"` + Device_Code string `json:"code" gorm:"size:20;not null"` + Device *ed.Device `json:"device" gorm:"foreignKey:Device_Code;references:Code"` +} diff --git a/internal/domain/main-entities/device-package/dto.go b/internal/domain/main-entities/device-package/dto.go new file mode 100644 index 00000000..26aad58a --- /dev/null +++ b/internal/domain/main-entities/device-package/dto.go @@ -0,0 +1,63 @@ +package devicepackage + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" +) + +type CreateDto struct { + Code string `json:"code" validate:"maxLength=20"` + Name string `json:"name" validate:"maxLength=50"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Pagination ecore.Pagination +} + +type FilterDto struct { + Code string `json:"code"` + Name string `json:"name"` +} + +type ReadDetailDto struct { + Id uint16 `json:"id"` +} + +type UpdateDto struct { + Id uint16 `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint16 `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.SmallMain + Code string `json:"code"` + Name string `json:"name"` +} + +func (d DevicePackage) ToResponse() ResponseDto { + resp := ResponseDto{ + Code: d.Code, + Name: d.Name, + } + resp.SmallMain = d.SmallMain + return resp +} + +func ToResponseList(data []DevicePackage) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/device-package/entity.go b/internal/domain/main-entities/device-package/entity.go new file mode 100644 index 00000000..1c03b44d --- /dev/null +++ b/internal/domain/main-entities/device-package/entity.go @@ -0,0 +1,11 @@ +package devicepackage + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" +) + +type DevicePackage struct { + ecore.SmallMain + Code string `json:"code" gorm:"unique;size:20;not null"` + Name string `json:"name" gorm:"size:50"` +} diff --git a/internal/domain/main-entities/infra/dto.go b/internal/domain/main-entities/infra/dto.go index dfe271e5..d12a0b89 100644 --- a/internal/domain/main-entities/infra/dto.go +++ b/internal/domain/main-entities/infra/dto.go @@ -3,7 +3,8 @@ package infra import ( ecore "simrs-vx/internal/domain/base-entities/core" ei "simrs-vx/internal/domain/main-entities/item" - erb "simrs-vx/internal/domain/main-entities/room/base" + + erb "simrs-vx/internal/domain/main-entities/procedure-room/base" ero "simrs-vx/internal/domain/references/organization" ) @@ -61,15 +62,15 @@ type MetaDto struct { type ResponseDto struct { ecore.SmallMain - Code string `json:"code"` - Name string `json:"name"` - InfraGroup_Code ero.InfraGroupCode `json:"infraGroup_code"` - Parent_Code *string `json:"parent_code"` - Parent *Infra `json:"parent,omitempty"` - Childrens []Infra `json:"childrens,omitempty"` - Item_Code *string `json:"item_code"` - Item *ei.Item `json:"item,omitempty"` - Rooms []erb.Basic `json:"rooms,omitempty"` + Code string `json:"code"` + Name string `json:"name"` + InfraGroup_Code ero.InfraGroupCode `json:"infraGroup_code"` + Parent_Code *string `json:"parent_code"` + Parent *Infra `json:"parent,omitempty"` + Childrens []Infra `json:"childrens,omitempty"` + Item_Code *string `json:"item_code"` + Item *ei.Item `json:"item,omitempty"` + ProcedureRooms []erb.ProcedureRoom `json:"rooms,omitempty"` } func (d Infra) ToResponse() ResponseDto { @@ -79,10 +80,10 @@ func (d Infra) ToResponse() ResponseDto { InfraGroup_Code: d.InfraGroup_Code, Parent_Code: d.Parent_Code, // Parent: d.Parent, - Childrens: d.Childrens, - Item_Code: d.Item_Code, - Item: d.Item, - Rooms: d.Rooms, + Childrens: d.Childrens, + Item_Code: d.Item_Code, + Item: d.Item, + ProcedureRooms: d.ProcedureRooms, } resp.SmallMain = d.SmallMain return resp diff --git a/internal/domain/main-entities/infra/entity.go b/internal/domain/main-entities/infra/entity.go index 51cc8eaa..8fe5cb52 100644 --- a/internal/domain/main-entities/infra/entity.go +++ b/internal/domain/main-entities/infra/entity.go @@ -4,20 +4,20 @@ import ( ecore "simrs-vx/internal/domain/base-entities/core" ei "simrs-vx/internal/domain/main-entities/item" - erb "simrs-vx/internal/domain/main-entities/room/base" + erb "simrs-vx/internal/domain/main-entities/procedure-room/base" ero "simrs-vx/internal/domain/references/organization" ) type Infra struct { - ecore.SmallMain // adjust this according to the needs - Code string `json:"code" gorm:"uniqueIndex;size:10;not null"` - Name string `json:"name" gorm:"size:50"` - InfraGroup_Code ero.InfraGroupCode `json:"infraGroup_code" gorm:"size:15"` - Parent_Code *string `json:"parent_code" gorm:"size:10"` - Parent *Infra `json:"parent" gorm:"foreignKey:Parent_Code;references:Code"` - Childrens []Infra `json:"childrens" gorm:"foreignKey:Parent_Code;references:Code"` - Item_Code *string `json:"item_code" gorm:"size:50"` - Item *ei.Item `json:"item,omitempty" gorm:"foreignKey:Item_Code;references:Code"` - Rooms []erb.Basic `json:"rooms" gorm:"foreignKey:Infra_Code;references:Code"` + ecore.SmallMain // adjust this according to the needs + Code string `json:"code" gorm:"uniqueIndex;size:20;not null"` + Name string `json:"name" gorm:"size:50"` + InfraGroup_Code ero.InfraGroupCode `json:"infraGroup_code" gorm:"size:20"` + Parent_Code *string `json:"parent_code" gorm:"size:20"` + Parent *Infra `json:"parent" gorm:"foreignKey:Parent_Code;references:Code"` + Childrens []Infra `json:"childrens" gorm:"foreignKey:Parent_Code;references:Code"` + Item_Code *string `json:"item_code" gorm:"size:50"` + Item *ei.Item `json:"item,omitempty" gorm:"foreignKey:Item_Code;references:Code"` + ProcedureRooms []erb.ProcedureRoom `json:"rooms" gorm:"foreignKey:Infra_Code;references:Code"` } diff --git a/internal/domain/main-entities/installation/entity.go b/internal/domain/main-entities/installation/entity.go index 5cc82430..6c3c0ecf 100644 --- a/internal/domain/main-entities/installation/entity.go +++ b/internal/domain/main-entities/installation/entity.go @@ -8,7 +8,7 @@ import ( type Installation struct { ecore.SmallMain // adjust this according to the needs - Code string `json:"code" gorm:"unique;size:10"` + Code string `json:"code" gorm:"unique;size:20"` Name string `json:"name" gorm:"size:50"` EncounterClass_Code ere.EncounterClassCode `json:"encounterClass_code" gorm:"size:10"` InstallationPositions []eipb.Basic `json:"installationPositions,omitempty" gorm:"foreignKey:Installation_Code;references:Code"` diff --git a/internal/domain/main-entities/material-package-item/dto.go b/internal/domain/main-entities/material-package-item/dto.go new file mode 100644 index 00000000..a9b11be6 --- /dev/null +++ b/internal/domain/main-entities/material-package-item/dto.go @@ -0,0 +1,69 @@ +package materialpackage + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + em "simrs-vx/internal/domain/main-entities/material" + emp "simrs-vx/internal/domain/main-entities/material-package" +) + +type CreateDto struct { + MaterialPackage_Code string `json:"materialPackage_code" validate:"maxLength=20"` + Material_Code string `json:"code" validate:"maxLength=20"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Pagination ecore.Pagination +} + +type FilterDto struct { + MaterialPackage_Code string `json:"materialPackage-code"` + Material_Code string `json:"code"` +} + +type ReadDetailDto struct { + Id uint `json:"id"` +} + +type UpdateDto struct { + Id uint `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.Main + MaterialPackage_Code string `json:"materialPackage_code"` + MaterialPackage *emp.MaterialPackage `json:"materialPackage,omitempty"` + Material_Code string `json:"code"` + Material *em.Material `json:"material,omitempty"` +} + +func (d MaterialPackageItem) ToResponse() ResponseDto { + resp := ResponseDto{ + MaterialPackage_Code: d.MaterialPackage_Code, + MaterialPackage: d.MaterialPackage, + Material_Code: d.Material_Code, + Material: d.Material, + } + resp.Id = d.Id + return resp +} + +func ToResponseList(data []MaterialPackageItem) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/material-package-item/entity.go b/internal/domain/main-entities/material-package-item/entity.go new file mode 100644 index 00000000..76378dc8 --- /dev/null +++ b/internal/domain/main-entities/material-package-item/entity.go @@ -0,0 +1,15 @@ +package materialpackage + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + em "simrs-vx/internal/domain/main-entities/material" + emp "simrs-vx/internal/domain/main-entities/material-package" +) + +type MaterialPackageItem struct { + ecore.Main + MaterialPackage_Code string `json:"materialPackage_code" gorm:"size:20;not null"` + MaterialPackage *emp.MaterialPackage `json:"materialPackage" gorm:"foreignKey:MaterialPackage_Code;references:Code"` + Material_Code string `json:"code" gorm:"size:20;not null"` + Material *em.Material `json:"material" gorm:"foreignKey:Material_Code;references:Code"` +} diff --git a/internal/domain/main-entities/material-package/dto.go b/internal/domain/main-entities/material-package/dto.go new file mode 100644 index 00000000..b81212e9 --- /dev/null +++ b/internal/domain/main-entities/material-package/dto.go @@ -0,0 +1,63 @@ +package materialpackage + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" +) + +type CreateDto struct { + Code string `json:"code" validate:"maxLength=20"` + Name string `json:"name" validate:"maxLength=50"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Pagination ecore.Pagination +} + +type FilterDto struct { + Code string `json:"code"` + Name string `json:"name"` +} + +type ReadDetailDto struct { + Id uint16 `json:"id"` +} + +type UpdateDto struct { + Id uint16 `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint16 `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.SmallMain + Code string `json:"code"` + Name string `json:"name"` +} + +func (d MaterialPackage) ToResponse() ResponseDto { + resp := ResponseDto{ + Code: d.Code, + Name: d.Name, + } + resp.SmallMain = d.SmallMain + return resp +} + +func ToResponseList(data []MaterialPackage) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/material-package/entity.go b/internal/domain/main-entities/material-package/entity.go new file mode 100644 index 00000000..4f3feeab --- /dev/null +++ b/internal/domain/main-entities/material-package/entity.go @@ -0,0 +1,11 @@ +package materialpackage + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" +) + +type MaterialPackage struct { + ecore.SmallMain + Code string `json:"code" gorm:"unique;size:20;not null"` + Name string `json:"name" gorm:"size:50"` +} diff --git a/internal/domain/main-entities/procedure-room-order/dto.go b/internal/domain/main-entities/procedure-room-order/dto.go new file mode 100644 index 00000000..d202f031 --- /dev/null +++ b/internal/domain/main-entities/procedure-room-order/dto.go @@ -0,0 +1,70 @@ +package procedureroomorder + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + ec "simrs-vx/internal/domain/main-entities/encounter" + epr "simrs-vx/internal/domain/main-entities/procedure-room" +) + +type CreateDto struct { + Encounter_Id uint64 `json:"encounter_id"` + Infra_Code string `json:"procedure"` + ProcedureRoom string `json:"procedureRoom"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Pagination ecore.Pagination +} + +type FilterDto struct { + Encounter_Id uint64 `json:"encounter-id"` + Infra_Code string `json:"procedure-code"` + ProcedureRoom string `json:"procedure-room"` +} + +type ReadDetailDto struct { + Id uint `json:"id"` +} + +type UpdateDto struct { + Id uint `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.Main + Encounter_Id uint64 `json:"encounter_id"` + Encounter *ec.Encounter `json:"encounter,omitempty"` + Infra_Code string `json:"procedure"` + ProcedureRoom *epr.ProcedureRoom `json:"procedureRoom,omitempty"` +} + +func (d ProcedureRoomOrder) ToResponse() ResponseDto { + resp := ResponseDto{ + Encounter_Id: d.Encounter_Id, + Infra_Code: d.Infra_Code, + // ProcedureRoom: d.ProcedureRoom, + } + resp.Id = d.Id + return resp +} + +func ToResponseList(data []ProcedureRoomOrder) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/procedure-room-order/entity.go b/internal/domain/main-entities/procedure-room-order/entity.go new file mode 100644 index 00000000..7e453410 --- /dev/null +++ b/internal/domain/main-entities/procedure-room-order/entity.go @@ -0,0 +1,13 @@ +package procedureroomorder + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + epr "simrs-vx/internal/domain/main-entities/procedure-room" +) + +type ProcedureRoomOrder struct { + ecore.Main + Encounter_Id uint64 `json:"encounter_id"` + Infra_Code string `json:"infra_code" gorm:"size:20"` + ProcedureRoom *epr.ProcedureRoom `json:"procedureRoom,omitempty" gorm:"foreignKey:Infra_Code;references:Code"` +} diff --git a/internal/domain/main-entities/procedure-room/base/entity.go b/internal/domain/main-entities/procedure-room/base/entity.go new file mode 100644 index 00000000..981dd4f2 --- /dev/null +++ b/internal/domain/main-entities/procedure-room/base/entity.go @@ -0,0 +1,21 @@ +package procedureroombase + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + ero "simrs-vx/internal/domain/references/organization" +) + +type ProcedureRoom struct { + ecore.SmallMain + Code string `json:"code" gorm:"unique;size:20"` // copied from infra code + Infra_Code *string `json:"infra_code" gorm:"size:20;unique"` + Type_Code *ero.ProdcedureRoomTypeCode `json:"type_code" gorm:"size:10"` + Unit_Code *string `json:"unit_code" gorm:"size:20"` + Specialist_Code *string `json:"specialist_code" gorm:"size:20"` + Subspecialist_Code *string `json:"subspecialist_code" gorm:"size:20"` +} + +// THIS IS ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ +// func (ProcedureRoom) TableName() string { +// return "Room" +// } diff --git a/internal/domain/main-entities/room/dto.go b/internal/domain/main-entities/procedure-room/dto.go similarity index 86% rename from internal/domain/main-entities/room/dto.go rename to internal/domain/main-entities/procedure-room/dto.go index 2ff41c3a..74320f3f 100644 --- a/internal/domain/main-entities/room/dto.go +++ b/internal/domain/main-entities/procedure-room/dto.go @@ -1,4 +1,4 @@ -package room +package procedureroom import ( ecore "simrs-vx/internal/domain/base-entities/core" @@ -10,6 +10,7 @@ import ( type CreateDto struct { Infra_Code *string `json:"infra_code"` + Type_Code string `json:"type_code"` Unit_Code *string `json:"unit_code"` Specialist_Code *string `json:"specialist_code"` Subspecialist_Code *string `json:"subspecialist_code"` @@ -23,6 +24,7 @@ type ReadListDto struct { type FilterDto struct { Infra_Code *string `json:"infra-code"` + Type_Code string `json:"type_code"` Unit_Code *string `json:"unit-code"` Specialist_Code *string `json:"specialist-code"` Subspecialist_Code *string `json:"subspecialist-code"` @@ -49,6 +51,7 @@ type MetaDto struct { type ResponseDto struct { ecore.SmallMain + Type_Code *string `json:"type_code"` Infra_Code *string `json:"infra_code"` Infra *ei.Infra `json:"infra,omitempty"` Unit_Code *string `json:"unit_code"` @@ -59,10 +62,11 @@ type ResponseDto struct { Subspecialist *ess.Subspecialist `json:"subspecialist,omitempty"` } -func (d Room) ToResponse() ResponseDto { +func (d ProcedureRoom) ToResponse() ResponseDto { resp := ResponseDto{ Infra_Code: d.Infra_Code, Infra: d.Infra, + Type_Code: (*string)(d.Type_Code), Unit_Code: d.Unit_Code, Unit: d.Unit, Specialist_Code: d.Specialist_Code, @@ -74,7 +78,7 @@ func (d Room) ToResponse() ResponseDto { return resp } -func ToResponseList(data []Room) []ResponseDto { +func ToResponseList(data []ProcedureRoom) []ResponseDto { resp := make([]ResponseDto, len(data)) for i, u := range data { resp[i] = u.ToResponse() diff --git a/internal/domain/main-entities/procedure-room/entity.go b/internal/domain/main-entities/procedure-room/entity.go new file mode 100644 index 00000000..9be3ac69 --- /dev/null +++ b/internal/domain/main-entities/procedure-room/entity.go @@ -0,0 +1,17 @@ +package procedureroom + +import ( + ei "simrs-vx/internal/domain/main-entities/infra" + ebase "simrs-vx/internal/domain/main-entities/procedure-room/base" + es "simrs-vx/internal/domain/main-entities/specialist" + ess "simrs-vx/internal/domain/main-entities/subspecialist" + eu "simrs-vx/internal/domain/main-entities/unit" +) + +type ProcedureRoom struct { + ebase.ProcedureRoom + Infra *ei.Infra `json:"infra,omitempty" gorm:"foreignKey:Infra_Code;references:Code"` + Unit *eu.Unit `json:"unit,omitempty" gorm:"foreignKey:Unit_Code;references:Code"` + Specialist *es.Specialist `json:"specialist,omitempty" gorm:"foreignKey:Specialist_Code;references:Code"` + Subspecialist *ess.Subspecialist `json:"subspecialist,omitempty" gorm:"foreignKey:Subspecialist_Code;references:Code"` +} diff --git a/internal/domain/main-entities/room/base/entity.go b/internal/domain/main-entities/room/base/entity.go deleted file mode 100644 index d5651ac9..00000000 --- a/internal/domain/main-entities/room/base/entity.go +++ /dev/null @@ -1,23 +0,0 @@ -package base - -import ( - ecore "simrs-vx/internal/domain/base-entities/core" - es "simrs-vx/internal/domain/main-entities/specialist" - ess "simrs-vx/internal/domain/main-entities/subspecialist" - eu "simrs-vx/internal/domain/main-entities/unit" -) - -type Basic struct { - ecore.SmallMain // adjust this according to the needs - Infra_Code *string `json:"infra_code" gorm:"size:10"` - Unit_Code *string `json:"unit_code" gorm:"size:10"` - Unit *eu.Unit `json:"unit,omitempty" gorm:"foreignKey:Unit_Code;references:Code"` - Specialist_Code *string `json:"specialist_code" gorm:"size:10"` - Specialist *es.Specialist `json:"specialist,omitempty" gorm:"foreignKey:Specialist_Code;references:Code"` - Subspecialist_Code *string `json:"subspecialist_code" gorm:"size:10"` - Subspecialist *ess.Subspecialist `json:"subspecialist,omitempty" gorm:"foreignKey:Subspecialist_Code;references:Code"` -} - -func (Basic) TableName() string { - return "Room" -} diff --git a/internal/domain/main-entities/room/entity.go b/internal/domain/main-entities/room/entity.go deleted file mode 100644 index 49fb8cc6..00000000 --- a/internal/domain/main-entities/room/entity.go +++ /dev/null @@ -1,11 +0,0 @@ -package room - -import ( - ei "simrs-vx/internal/domain/main-entities/infra" - ebase "simrs-vx/internal/domain/main-entities/room/base" -) - -type Room struct { - ebase.Basic - Infra *ei.Infra `json:"infra,omitempty" gorm:"foreignKey:Infra_Code;references:Code"` -} diff --git a/internal/domain/main-entities/specialist/entity.go b/internal/domain/main-entities/specialist/entity.go index 4fef90a5..0b5b7a5d 100644 --- a/internal/domain/main-entities/specialist/entity.go +++ b/internal/domain/main-entities/specialist/entity.go @@ -9,9 +9,9 @@ import ( type Specialist struct { ecore.SmallMain // adjust this according to the needs - Code string `json:"code" gorm:"unique;size:10"` + Code string `json:"code" gorm:"unique;size:20"` Name string `json:"name" gorm:"size:50"` - Unit_Code *string `json:"unit_code" gorm:"size:10"` + Unit_Code *string `json:"unit_code" gorm:"size:20"` Unit *eu.Unit `json:"unit,omitempty" gorm:"foreignKey:Unit_Code;references:Code"` SpecialistPositions []eub.Basic `json:"specialistPositions,omitempty" gorm:"foreignKey:Specialist_Code;references:Code"` Subspecialists []essb.Basic `json:"subspecialists,omitempty" gorm:"foreignKey:Specialist_Code;references:Code"` diff --git a/internal/domain/main-entities/subspecialist/base/entity.go b/internal/domain/main-entities/subspecialist/base/entity.go index a94fb76d..9fe77039 100644 --- a/internal/domain/main-entities/subspecialist/base/entity.go +++ b/internal/domain/main-entities/subspecialist/base/entity.go @@ -6,9 +6,9 @@ import ( type Basic struct { ecore.SmallMain // adjust this according to the needs - Code string `json:"code" gorm:"unique;size:10"` + Code string `json:"code" gorm:"unique;size:20"` Name string `json:"name" gorm:"size:50"` - Specialist_Code *string `json:"specialist_code" gorm:"size:10"` + Specialist_Code *string `json:"specialist_code" gorm:"size:20"` } func (Basic) TableName() string { diff --git a/internal/domain/main-entities/unit/entity.go b/internal/domain/main-entities/unit/entity.go index 97db9885..e8110db3 100644 --- a/internal/domain/main-entities/unit/entity.go +++ b/internal/domain/main-entities/unit/entity.go @@ -9,9 +9,9 @@ import ( type Unit struct { ecore.SmallMain // adjust this according to the needs - Installation_Code *string `json:"installation_code" gorm:"size:10"` + Installation_Code *string `json:"installation_code" gorm:"size:20"` Installation *ei.Installation `json:"installation" gorm:"foreignKey:Installation_Code;references:Code"` - Code string `json:"code" gorm:"unique;size:10"` + Code string `json:"code" gorm:"unique;size:20"` Name string `json:"name" gorm:"size:50"` Type_Code *ero.UnitTypeCode `json:"type_code"` UnitPositions []eub.Basic `json:"unitPositions,omitempty" gorm:"foreignKey:Unit_Code;references:Code"` diff --git a/internal/domain/references/organization/organization.go b/internal/domain/references/organization/organization.go index b39752d5..8ca55c93 100644 --- a/internal/domain/references/organization/organization.go +++ b/internal/domain/references/organization/organization.go @@ -1,14 +1,15 @@ package organization type ( - ContractPositionCode string - EmployeePositionCode string - InternPosisitionCode string - ItemGroupCode string - InfraGroupCode string - UnitTypeCode string - DoctorFeeTypeCode string - ActionBillingCode string + ContractPositionCode string + EmployeePositionCode string + InternPosisitionCode string + ItemGroupCode string + InfraGroupCode string + ProdcedureRoomTypeCode string + UnitTypeCode string + DoctorFeeTypeCode string + ActionBillingCode string ) const ( @@ -53,6 +54,9 @@ const ( IFGCCounter InfraGroupCode = "counter" // Counter IFGCPubScreen InfraGroupCode = "public-screen" // Public Screen + PRTLight ProdcedureRoomTypeCode = "light" // Ringan + PRTSurgery ProdcedureRoomTypeCode = "roomed" // Dikamarkan + UTCReg UnitTypeCode = "reg" // Registrasi UTCExa UnitTypeCode = "exa" // Pemeriksaan UTCPay UnitTypeCode = "pay" // Pembayaran diff --git a/internal/interface/migration/main-entities.go b/internal/interface/migration/main-entities.go index bed0c18c..0d118fae 100644 --- a/internal/interface/migration/main-entities.go +++ b/internal/interface/migration/main-entities.go @@ -19,6 +19,8 @@ import ( device "simrs-vx/internal/domain/main-entities/device" deviceorder "simrs-vx/internal/domain/main-entities/device-order" deviceorderitem "simrs-vx/internal/domain/main-entities/device-order-item" + devicepackage "simrs-vx/internal/domain/main-entities/device-package" + devicepackageitem "simrs-vx/internal/domain/main-entities/device-package-item" diagnosesrc "simrs-vx/internal/domain/main-entities/diagnose-src" district "simrs-vx/internal/domain/main-entities/district" division "simrs-vx/internal/domain/main-entities/division" @@ -46,6 +48,8 @@ import ( material "simrs-vx/internal/domain/main-entities/material" materialorder "simrs-vx/internal/domain/main-entities/material-order" materialorderitem "simrs-vx/internal/domain/main-entities/material-order-item" + materialpackage "simrs-vx/internal/domain/main-entities/material-package" + materialpackageitem "simrs-vx/internal/domain/main-entities/material-package-item" mcuorder "simrs-vx/internal/domain/main-entities/mcu-order" mcuorderitem "simrs-vx/internal/domain/main-entities/mcu-order-item" mcuordersubitem "simrs-vx/internal/domain/main-entities/mcu-order-sub-item" @@ -78,13 +82,14 @@ import ( practiceschedule "simrs-vx/internal/domain/main-entities/practice-schedule" prescription "simrs-vx/internal/domain/main-entities/prescription" prescriptionitem "simrs-vx/internal/domain/main-entities/prescription-item" + procedureroom "simrs-vx/internal/domain/main-entities/procedure-room" + procedureroomorder "simrs-vx/internal/domain/main-entities/procedure-room-order" proceduresrc "simrs-vx/internal/domain/main-entities/procedure-src" province "simrs-vx/internal/domain/main-entities/province" regency "simrs-vx/internal/domain/main-entities/regency" rehab "simrs-vx/internal/domain/main-entities/rehab" responsibledoctorhist "simrs-vx/internal/domain/main-entities/responsible-doctor-hist" resume "simrs-vx/internal/domain/main-entities/resume" - room "simrs-vx/internal/domain/main-entities/room" sbar "simrs-vx/internal/domain/main-entities/sbar" screening "simrs-vx/internal/domain/main-entities/screening" soapi "simrs-vx/internal/domain/main-entities/soapi" @@ -144,6 +149,7 @@ func getMainEntities() []any { &item.Item{}, &itemprice.ItemPrice{}, &infra.Infra{}, + &procedureroom.ProcedureRoom{}, &medicinegroup.MedicineGroup{}, &medicinemethod.MedicineMethod{}, &mcusrccategory.McuSrcCategory{}, @@ -163,13 +169,17 @@ func getMainEntities() []any { &personrelative.PersonRelative{}, &patient.Patient{}, &appointment.Appointment{}, + &devicepackage.DevicePackage{}, + &devicepackageitem.DevicePackageItem{}, + &materialpackage.MaterialPackage{}, + &materialpackageitem.MaterialPackageItem{}, + &vclaimsep.VclaimSep{}, &encounter.Encounter{}, &laborant.Laborant{}, &specialist.Specialist{}, &subspecialist.Subspecialist{}, &specialistintern.SpecialistIntern{}, - &room.Room{}, &soapi.Soapi{}, &sbar.Sbar{}, &adime.Adime{}, @@ -196,6 +206,8 @@ func getMainEntities() []any { &midwife.Midwife{}, &postalregion.PostalRegion{}, &internalreference.InternalReference{}, + &procedureroomorder.ProcedureRoomOrder{}, + &vclaimsephist.VclaimSepHist{}, &vclaimsepprint.VclaimSepPrint{}, &vehicle.Vehicle{}, From 51e25279854ee209d492f6d6e2d0034d73cf6e87 Mon Sep 17 00:00:00 2001 From: Munawwirul Jamal Date: Tue, 2 Dec 2025 20:16:42 +0700 Subject: [PATCH 29/38] feat/order-things: adjust entities --- .../migrations/20251202130629.sql | 101 ++++++++++++++++++ cmd/main-migration/migrations/atlas.sum | 4 +- .../device-package-item/device-package/dto.go | 63 +++++++++++ .../device-package/entity.go | 11 ++ .../main-entities/device-package-item/dto.go | 69 ++++++++++++ .../device-package-item/entity.go | 15 +++ .../main-entities/device-package/dto.go | 63 +++++++++++ .../main-entities/device-package/entity.go | 11 ++ internal/domain/main-entities/infra/dto.go | 33 +++--- internal/domain/main-entities/infra/entity.go | 22 ++-- .../domain/main-entities/installation/dto.go | 4 +- .../main-entities/installation/entity.go | 2 +- .../material-package-item/dto.go | 69 ++++++++++++ .../material-package-item/entity.go | 15 +++ .../main-entities/material-package/dto.go | 66 ++++++++++++ .../main-entities/material-package/entity.go | 11 ++ .../main-entities/procedure-room-order/dto.go | 70 ++++++++++++ .../procedure-room-order/entity.go | 13 +++ .../procedure-room/base/entity.go | 21 ++++ .../{room => procedure-room}/dto.go | 13 ++- .../main-entities/procedure-room/entity.go | 17 +++ .../domain/main-entities/room/base/entity.go | 23 ---- internal/domain/main-entities/room/entity.go | 11 -- .../domain/main-entities/specialist/entity.go | 4 +- .../subspecialist-position/dto.go | 2 +- .../subspecialist/base/entity.go | 4 +- .../domain/main-entities/subspecialist/dto.go | 2 +- internal/domain/main-entities/unit/dto.go | 2 +- internal/domain/main-entities/unit/entity.go | 4 +- .../references/organization/organization.go | 36 ++++--- internal/interface/migration/main-entities.go | 16 ++- 31 files changed, 701 insertions(+), 96 deletions(-) create mode 100644 cmd/main-migration/migrations/20251202130629.sql create mode 100644 internal/domain/main-entities/device-package-item/device-package/dto.go create mode 100644 internal/domain/main-entities/device-package-item/device-package/entity.go create mode 100644 internal/domain/main-entities/device-package-item/dto.go create mode 100644 internal/domain/main-entities/device-package-item/entity.go create mode 100644 internal/domain/main-entities/device-package/dto.go create mode 100644 internal/domain/main-entities/device-package/entity.go create mode 100644 internal/domain/main-entities/material-package-item/dto.go create mode 100644 internal/domain/main-entities/material-package-item/entity.go create mode 100644 internal/domain/main-entities/material-package/dto.go create mode 100644 internal/domain/main-entities/material-package/entity.go create mode 100644 internal/domain/main-entities/procedure-room-order/dto.go create mode 100644 internal/domain/main-entities/procedure-room-order/entity.go create mode 100644 internal/domain/main-entities/procedure-room/base/entity.go rename internal/domain/main-entities/{room => procedure-room}/dto.go (82%) create mode 100644 internal/domain/main-entities/procedure-room/entity.go delete mode 100644 internal/domain/main-entities/room/base/entity.go delete mode 100644 internal/domain/main-entities/room/entity.go diff --git a/cmd/main-migration/migrations/20251202130629.sql b/cmd/main-migration/migrations/20251202130629.sql new file mode 100644 index 00000000..88b685fe --- /dev/null +++ b/cmd/main-migration/migrations/20251202130629.sql @@ -0,0 +1,101 @@ +-- Modify "Consultation" table +ALTER TABLE "public"."Consultation" ALTER COLUMN "DstUnit_Code" TYPE character varying(20); +-- Modify "ControlLetter" table +ALTER TABLE "public"."ControlLetter" ALTER COLUMN "Unit_Code" TYPE character varying(20), ALTER COLUMN "Specialist_Code" TYPE character varying(20), ALTER COLUMN "Subspecialist_Code" TYPE character varying(20); +-- Modify "Encounter" table +ALTER TABLE "public"."Encounter" ALTER COLUMN "Specialist_Code" TYPE character varying(20), ALTER COLUMN "Subspecialist_Code" TYPE character varying(20), ALTER COLUMN "Unit_Code" TYPE character varying(20); +-- Modify "Chemo" table +ALTER TABLE "public"."Chemo" ALTER COLUMN "SrcUnit_Code" TYPE character varying(20); +-- Modify "Installation" table +ALTER TABLE "public"."Installation" ALTER COLUMN "Code" TYPE character varying(20); +-- Modify "InternalReference" table +ALTER TABLE "public"."InternalReference" ALTER COLUMN "Unit_Code" TYPE character varying(20); +-- Modify "PracticeSchedule" table +ALTER TABLE "public"."PracticeSchedule" ALTER COLUMN "Unit_Code" TYPE character varying(20); +-- Create "DevicePackage" table +CREATE TABLE "public"."DevicePackage" ( + "Id" serial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "Code" character varying(20) NOT NULL, + "Name" character varying(50) NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "uni_DevicePackage_Code" UNIQUE ("Code") +); +-- Create "DevicePackageItem" table +CREATE TABLE "public"."DevicePackageItem" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "DevicePackage_Code" character varying(20) NOT NULL, + "Device_Code" character varying(20) NOT NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "fk_DevicePackageItem_Device" FOREIGN KEY ("Device_Code") REFERENCES "public"."Device" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT "fk_DevicePackageItem_DevicePackage" FOREIGN KEY ("DevicePackage_Code") REFERENCES "public"."DevicePackage" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION +); +-- Create "MaterialPackage" table +CREATE TABLE "public"."MaterialPackage" ( + "Id" serial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "Code" character varying(20) NOT NULL, + "Name" character varying(50) NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "uni_MaterialPackage_Code" UNIQUE ("Code") +); +-- Create "MaterialPackageItem" table +CREATE TABLE "public"."MaterialPackageItem" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "MaterialPackage_Code" character varying(20) NOT NULL, + "Material_Code" character varying(20) NOT NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "fk_MaterialPackageItem_Material" FOREIGN KEY ("Material_Code") REFERENCES "public"."Material" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT "fk_MaterialPackageItem_MaterialPackage" FOREIGN KEY ("MaterialPackage_Code") REFERENCES "public"."MaterialPackage" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION +); +-- Modify "Infra" table +ALTER TABLE "public"."Infra" ALTER COLUMN "Code" TYPE character varying(20), ALTER COLUMN "InfraGroup_Code" TYPE character varying(20), ALTER COLUMN "Parent_Code" TYPE character varying(20); +-- Modify "Specialist" table +ALTER TABLE "public"."Specialist" ALTER COLUMN "Code" TYPE character varying(20), ALTER COLUMN "Unit_Code" TYPE character varying(20); +-- Modify "Subspecialist" table +ALTER TABLE "public"."Subspecialist" ALTER COLUMN "Code" TYPE character varying(20), ALTER COLUMN "Specialist_Code" TYPE character varying(20); +-- Modify "Unit" table +ALTER TABLE "public"."Unit" ALTER COLUMN "Code" TYPE character varying(20), ALTER COLUMN "Installation_Code" TYPE character varying(20); +-- Create "ProcedureRoom" table +CREATE TABLE "public"."ProcedureRoom" ( + "Id" serial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "Code" character varying(20) NULL, + "Infra_Code" character varying(20) NULL, + "Type_Code" character varying(10) NULL, + "Unit_Code" character varying(20) NULL, + "Specialist_Code" character varying(20) NULL, + "Subspecialist_Code" character varying(20) NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "uni_ProcedureRoom_Code" UNIQUE ("Code"), + CONSTRAINT "uni_ProcedureRoom_Infra_Code" UNIQUE ("Infra_Code"), + CONSTRAINT "fk_ProcedureRoom_Infra" FOREIGN KEY ("Infra_Code") REFERENCES "public"."Infra" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT "fk_ProcedureRoom_Specialist" FOREIGN KEY ("Specialist_Code") REFERENCES "public"."Specialist" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT "fk_ProcedureRoom_Subspecialist" FOREIGN KEY ("Subspecialist_Code") REFERENCES "public"."Subspecialist" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION, + CONSTRAINT "fk_ProcedureRoom_Unit" FOREIGN KEY ("Unit_Code") REFERENCES "public"."Unit" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION +); +-- Create "ProcedureRoomOrder" table +CREATE TABLE "public"."ProcedureRoomOrder" ( + "Id" bigserial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "Encounter_Id" bigint NULL, + "Infra_Code" character varying(20) NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "fk_ProcedureRoomOrder_ProcedureRoom" FOREIGN KEY ("Infra_Code") REFERENCES "public"."ProcedureRoom" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION +); +-- Drop "Room" table +DROP TABLE "public"."Room"; diff --git a/cmd/main-migration/migrations/atlas.sum b/cmd/main-migration/migrations/atlas.sum index 11fba5b8..54858b7b 100644 --- a/cmd/main-migration/migrations/atlas.sum +++ b/cmd/main-migration/migrations/atlas.sum @@ -1,4 +1,4 @@ -h1:NjMnBBzNKOW7RxpS7I5LqVv+o/CxGkxhHt/B7CV4/tQ= +h1:cyae1SX3YSMX1LZLEsCFxcRKbVxpnp46BqFxWXJqKjs= 20250904105930.sql h1:MEM6blCgke9DzWQSTnLzasbPIrcHssNNrJqZpSkEo6k= 20250904141448.sql h1:J8cmYNk4ZrG9fhfbi2Z1IWz7YkfvhFqTzrLFo58BPY0= 20250908062237.sql h1:Pu23yEW/aKkwozHoOuROvHS/GK4ngARJGdO7FB7HZuI= @@ -140,4 +140,4 @@ h1:NjMnBBzNKOW7RxpS7I5LqVv+o/CxGkxhHt/B7CV4/tQ= 20251202030445.sql h1:QWBVfTepT7DaXP5E0BYoxNM0JwKIQ2qIMXzI4kbz/qE= 20251202044430.sql h1:4QZH9lz0GrQ9rzP1AJ+hJgGalNpp+8FCRckNK7xaTbU= 20251202064000.sql h1:/EN7sT1ol/91qW1aXWrzX+Mc3XOC/7f/LtfA0JRHpbg= -20251202122413.sql h1:uZpx6oC8BLTECZdMN69u+WTAAzdSWF70RGVB/pIxC84= +20251202130629.sql h1:LjBgQS8tKEwpC3WA0wGeO2Fs2L20kEOB6e5ljO4EdLM= diff --git a/internal/domain/main-entities/device-package-item/device-package/dto.go b/internal/domain/main-entities/device-package-item/device-package/dto.go new file mode 100644 index 00000000..26aad58a --- /dev/null +++ b/internal/domain/main-entities/device-package-item/device-package/dto.go @@ -0,0 +1,63 @@ +package devicepackage + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" +) + +type CreateDto struct { + Code string `json:"code" validate:"maxLength=20"` + Name string `json:"name" validate:"maxLength=50"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Pagination ecore.Pagination +} + +type FilterDto struct { + Code string `json:"code"` + Name string `json:"name"` +} + +type ReadDetailDto struct { + Id uint16 `json:"id"` +} + +type UpdateDto struct { + Id uint16 `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint16 `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.SmallMain + Code string `json:"code"` + Name string `json:"name"` +} + +func (d DevicePackage) ToResponse() ResponseDto { + resp := ResponseDto{ + Code: d.Code, + Name: d.Name, + } + resp.SmallMain = d.SmallMain + return resp +} + +func ToResponseList(data []DevicePackage) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/device-package-item/device-package/entity.go b/internal/domain/main-entities/device-package-item/device-package/entity.go new file mode 100644 index 00000000..1c03b44d --- /dev/null +++ b/internal/domain/main-entities/device-package-item/device-package/entity.go @@ -0,0 +1,11 @@ +package devicepackage + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" +) + +type DevicePackage struct { + ecore.SmallMain + Code string `json:"code" gorm:"unique;size:20;not null"` + Name string `json:"name" gorm:"size:50"` +} diff --git a/internal/domain/main-entities/device-package-item/dto.go b/internal/domain/main-entities/device-package-item/dto.go new file mode 100644 index 00000000..a0a224ba --- /dev/null +++ b/internal/domain/main-entities/device-package-item/dto.go @@ -0,0 +1,69 @@ +package devicepackage + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + ed "simrs-vx/internal/domain/main-entities/device" + edp "simrs-vx/internal/domain/main-entities/device-package" +) + +type CreateDto struct { + DevicePackage_Code string `json:"devicePackage_code" validate:"maxLength=20"` + Device_Code string `json:"code" validate:"maxLength=20"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Pagination ecore.Pagination +} + +type FilterDto struct { + DevicePackage_Code string `json:"devicePackage-code"` + Device_Code string `json:"code"` +} + +type ReadDetailDto struct { + Id uint `json:"id"` +} + +type UpdateDto struct { + Id uint `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.Main + DevicePackage_Code string `json:"devicePackage_code"` + DevicePackage *edp.DevicePackage `json:"devicePackage,omitempty"` + Device_Code string `json:"code"` + Device *ed.Device `json:"device,omitempty"` +} + +func (d DevicePackageItem) ToResponse() ResponseDto { + resp := ResponseDto{ + DevicePackage_Code: d.DevicePackage_Code, + DevicePackage: d.DevicePackage, + Device_Code: d.Device_Code, + Device: d.Device, + } + resp.Id = d.Id + return resp +} + +func ToResponseList(data []DevicePackageItem) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/device-package-item/entity.go b/internal/domain/main-entities/device-package-item/entity.go new file mode 100644 index 00000000..476e24e2 --- /dev/null +++ b/internal/domain/main-entities/device-package-item/entity.go @@ -0,0 +1,15 @@ +package devicepackage + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + ed "simrs-vx/internal/domain/main-entities/device" + edp "simrs-vx/internal/domain/main-entities/device-package" +) + +type DevicePackageItem struct { + ecore.Main + DevicePackage_Code string `json:"devicePackage_code" gorm:"size:20;not null"` + DevicePackage *edp.DevicePackage `json:"devicePackage" gorm:"foreignKey:DevicePackage_Code;references:Code"` + Device_Code string `json:"code" gorm:"size:20;not null"` + Device *ed.Device `json:"device" gorm:"foreignKey:Device_Code;references:Code"` +} diff --git a/internal/domain/main-entities/device-package/dto.go b/internal/domain/main-entities/device-package/dto.go new file mode 100644 index 00000000..26aad58a --- /dev/null +++ b/internal/domain/main-entities/device-package/dto.go @@ -0,0 +1,63 @@ +package devicepackage + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" +) + +type CreateDto struct { + Code string `json:"code" validate:"maxLength=20"` + Name string `json:"name" validate:"maxLength=50"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Pagination ecore.Pagination +} + +type FilterDto struct { + Code string `json:"code"` + Name string `json:"name"` +} + +type ReadDetailDto struct { + Id uint16 `json:"id"` +} + +type UpdateDto struct { + Id uint16 `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint16 `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.SmallMain + Code string `json:"code"` + Name string `json:"name"` +} + +func (d DevicePackage) ToResponse() ResponseDto { + resp := ResponseDto{ + Code: d.Code, + Name: d.Name, + } + resp.SmallMain = d.SmallMain + return resp +} + +func ToResponseList(data []DevicePackage) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/device-package/entity.go b/internal/domain/main-entities/device-package/entity.go new file mode 100644 index 00000000..1c03b44d --- /dev/null +++ b/internal/domain/main-entities/device-package/entity.go @@ -0,0 +1,11 @@ +package devicepackage + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" +) + +type DevicePackage struct { + ecore.SmallMain + Code string `json:"code" gorm:"unique;size:20;not null"` + Name string `json:"name" gorm:"size:50"` +} diff --git a/internal/domain/main-entities/infra/dto.go b/internal/domain/main-entities/infra/dto.go index dfe271e5..f5cf5444 100644 --- a/internal/domain/main-entities/infra/dto.go +++ b/internal/domain/main-entities/infra/dto.go @@ -3,15 +3,16 @@ package infra import ( ecore "simrs-vx/internal/domain/base-entities/core" ei "simrs-vx/internal/domain/main-entities/item" - erb "simrs-vx/internal/domain/main-entities/room/base" + + erb "simrs-vx/internal/domain/main-entities/procedure-room/base" ero "simrs-vx/internal/domain/references/organization" ) type CreateDto struct { - Code string `json:"code" validate:"maxLength=10"` + Code string `json:"code" validate:"maxLength=20"` Name string `json:"name" validate:"maxLength=50"` - InfraGroup_Code ero.InfraGroupCode `json:"infraGroup_code" validate:"maxLength=15"` + InfraGroup_Code ero.InfraGroupCode `json:"infraGroup_code" validate:"maxLength=20"` Parent_Code *string `json:"parent_code"` Item_Code *string `json:"-"` Unit_Code *string `json:"unit_code"` @@ -61,15 +62,15 @@ type MetaDto struct { type ResponseDto struct { ecore.SmallMain - Code string `json:"code"` - Name string `json:"name"` - InfraGroup_Code ero.InfraGroupCode `json:"infraGroup_code"` - Parent_Code *string `json:"parent_code"` - Parent *Infra `json:"parent,omitempty"` - Childrens []Infra `json:"childrens,omitempty"` - Item_Code *string `json:"item_code"` - Item *ei.Item `json:"item,omitempty"` - Rooms []erb.Basic `json:"rooms,omitempty"` + Code string `json:"code"` + Name string `json:"name"` + InfraGroup_Code ero.InfraGroupCode `json:"infraGroup_code"` + Parent_Code *string `json:"parent_code"` + Parent *Infra `json:"parent,omitempty"` + Childrens []Infra `json:"childrens,omitempty"` + Item_Code *string `json:"item_code"` + Item *ei.Item `json:"item,omitempty"` + ProcedureRooms []erb.ProcedureRoom `json:"rooms,omitempty"` } func (d Infra) ToResponse() ResponseDto { @@ -79,10 +80,10 @@ func (d Infra) ToResponse() ResponseDto { InfraGroup_Code: d.InfraGroup_Code, Parent_Code: d.Parent_Code, // Parent: d.Parent, - Childrens: d.Childrens, - Item_Code: d.Item_Code, - Item: d.Item, - Rooms: d.Rooms, + Childrens: d.Childrens, + Item_Code: d.Item_Code, + Item: d.Item, + ProcedureRooms: d.ProcedureRooms, } resp.SmallMain = d.SmallMain return resp diff --git a/internal/domain/main-entities/infra/entity.go b/internal/domain/main-entities/infra/entity.go index 51cc8eaa..8fe5cb52 100644 --- a/internal/domain/main-entities/infra/entity.go +++ b/internal/domain/main-entities/infra/entity.go @@ -4,20 +4,20 @@ import ( ecore "simrs-vx/internal/domain/base-entities/core" ei "simrs-vx/internal/domain/main-entities/item" - erb "simrs-vx/internal/domain/main-entities/room/base" + erb "simrs-vx/internal/domain/main-entities/procedure-room/base" ero "simrs-vx/internal/domain/references/organization" ) type Infra struct { - ecore.SmallMain // adjust this according to the needs - Code string `json:"code" gorm:"uniqueIndex;size:10;not null"` - Name string `json:"name" gorm:"size:50"` - InfraGroup_Code ero.InfraGroupCode `json:"infraGroup_code" gorm:"size:15"` - Parent_Code *string `json:"parent_code" gorm:"size:10"` - Parent *Infra `json:"parent" gorm:"foreignKey:Parent_Code;references:Code"` - Childrens []Infra `json:"childrens" gorm:"foreignKey:Parent_Code;references:Code"` - Item_Code *string `json:"item_code" gorm:"size:50"` - Item *ei.Item `json:"item,omitempty" gorm:"foreignKey:Item_Code;references:Code"` - Rooms []erb.Basic `json:"rooms" gorm:"foreignKey:Infra_Code;references:Code"` + ecore.SmallMain // adjust this according to the needs + Code string `json:"code" gorm:"uniqueIndex;size:20;not null"` + Name string `json:"name" gorm:"size:50"` + InfraGroup_Code ero.InfraGroupCode `json:"infraGroup_code" gorm:"size:20"` + Parent_Code *string `json:"parent_code" gorm:"size:20"` + Parent *Infra `json:"parent" gorm:"foreignKey:Parent_Code;references:Code"` + Childrens []Infra `json:"childrens" gorm:"foreignKey:Parent_Code;references:Code"` + Item_Code *string `json:"item_code" gorm:"size:50"` + Item *ei.Item `json:"item,omitempty" gorm:"foreignKey:Item_Code;references:Code"` + ProcedureRooms []erb.ProcedureRoom `json:"rooms" gorm:"foreignKey:Infra_Code;references:Code"` } diff --git a/internal/domain/main-entities/installation/dto.go b/internal/domain/main-entities/installation/dto.go index 5cc0ed5c..bd6fcc0e 100644 --- a/internal/domain/main-entities/installation/dto.go +++ b/internal/domain/main-entities/installation/dto.go @@ -9,9 +9,9 @@ import ( type CreateDto struct { Id *uint `json:"id"` - Code *string `json:"code" validate:"maxLength=10"` + Code *string `json:"code" validate:"maxLength=20"` Name string `json:"name" validate:"maxLength=50"` - EncounterClass_Code ere.EncounterClassCode `json:"encounterClass_code" validate:"maxLength=10"` + EncounterClass_Code ere.EncounterClassCode `json:"encounterClass_code" validate:"maxLength=20"` } type ReadListDto struct { diff --git a/internal/domain/main-entities/installation/entity.go b/internal/domain/main-entities/installation/entity.go index 5cc82430..6c3c0ecf 100644 --- a/internal/domain/main-entities/installation/entity.go +++ b/internal/domain/main-entities/installation/entity.go @@ -8,7 +8,7 @@ import ( type Installation struct { ecore.SmallMain // adjust this according to the needs - Code string `json:"code" gorm:"unique;size:10"` + Code string `json:"code" gorm:"unique;size:20"` Name string `json:"name" gorm:"size:50"` EncounterClass_Code ere.EncounterClassCode `json:"encounterClass_code" gorm:"size:10"` InstallationPositions []eipb.Basic `json:"installationPositions,omitempty" gorm:"foreignKey:Installation_Code;references:Code"` diff --git a/internal/domain/main-entities/material-package-item/dto.go b/internal/domain/main-entities/material-package-item/dto.go new file mode 100644 index 00000000..a9b11be6 --- /dev/null +++ b/internal/domain/main-entities/material-package-item/dto.go @@ -0,0 +1,69 @@ +package materialpackage + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + em "simrs-vx/internal/domain/main-entities/material" + emp "simrs-vx/internal/domain/main-entities/material-package" +) + +type CreateDto struct { + MaterialPackage_Code string `json:"materialPackage_code" validate:"maxLength=20"` + Material_Code string `json:"code" validate:"maxLength=20"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Pagination ecore.Pagination +} + +type FilterDto struct { + MaterialPackage_Code string `json:"materialPackage-code"` + Material_Code string `json:"code"` +} + +type ReadDetailDto struct { + Id uint `json:"id"` +} + +type UpdateDto struct { + Id uint `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.Main + MaterialPackage_Code string `json:"materialPackage_code"` + MaterialPackage *emp.MaterialPackage `json:"materialPackage,omitempty"` + Material_Code string `json:"code"` + Material *em.Material `json:"material,omitempty"` +} + +func (d MaterialPackageItem) ToResponse() ResponseDto { + resp := ResponseDto{ + MaterialPackage_Code: d.MaterialPackage_Code, + MaterialPackage: d.MaterialPackage, + Material_Code: d.Material_Code, + Material: d.Material, + } + resp.Id = d.Id + return resp +} + +func ToResponseList(data []MaterialPackageItem) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/material-package-item/entity.go b/internal/domain/main-entities/material-package-item/entity.go new file mode 100644 index 00000000..76378dc8 --- /dev/null +++ b/internal/domain/main-entities/material-package-item/entity.go @@ -0,0 +1,15 @@ +package materialpackage + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + em "simrs-vx/internal/domain/main-entities/material" + emp "simrs-vx/internal/domain/main-entities/material-package" +) + +type MaterialPackageItem struct { + ecore.Main + MaterialPackage_Code string `json:"materialPackage_code" gorm:"size:20;not null"` + MaterialPackage *emp.MaterialPackage `json:"materialPackage" gorm:"foreignKey:MaterialPackage_Code;references:Code"` + Material_Code string `json:"code" gorm:"size:20;not null"` + Material *em.Material `json:"material" gorm:"foreignKey:Material_Code;references:Code"` +} diff --git a/internal/domain/main-entities/material-package/dto.go b/internal/domain/main-entities/material-package/dto.go new file mode 100644 index 00000000..51dc1ab1 --- /dev/null +++ b/internal/domain/main-entities/material-package/dto.go @@ -0,0 +1,66 @@ +package materialpackage + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" +) + +type CreateDto struct { + Code string `json:"code" validate:"maxLength=20"` + Name string `json:"name" validate:"maxLength=50"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Pagination ecore.Pagination + Sort string `json:"sort"` +} + +type FilterDto struct { + Code string `json:"code"` + Name string `json:"name"` +} + +type ReadDetailDto struct { + Id *uint16 `json:"id"` + Code *string `json:"code"` +} + +type UpdateDto struct { + Id uint16 `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id *uint16 `json:"id"` + Code *string `json:"code"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.SmallMain + Code string `json:"code"` + Name string `json:"name"` +} + +func (d MaterialPackage) ToResponse() ResponseDto { + resp := ResponseDto{ + Code: d.Code, + Name: d.Name, + } + resp.SmallMain = d.SmallMain + return resp +} + +func ToResponseList(data []MaterialPackage) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/material-package/entity.go b/internal/domain/main-entities/material-package/entity.go new file mode 100644 index 00000000..4f3feeab --- /dev/null +++ b/internal/domain/main-entities/material-package/entity.go @@ -0,0 +1,11 @@ +package materialpackage + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" +) + +type MaterialPackage struct { + ecore.SmallMain + Code string `json:"code" gorm:"unique;size:20;not null"` + Name string `json:"name" gorm:"size:50"` +} diff --git a/internal/domain/main-entities/procedure-room-order/dto.go b/internal/domain/main-entities/procedure-room-order/dto.go new file mode 100644 index 00000000..d202f031 --- /dev/null +++ b/internal/domain/main-entities/procedure-room-order/dto.go @@ -0,0 +1,70 @@ +package procedureroomorder + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + ec "simrs-vx/internal/domain/main-entities/encounter" + epr "simrs-vx/internal/domain/main-entities/procedure-room" +) + +type CreateDto struct { + Encounter_Id uint64 `json:"encounter_id"` + Infra_Code string `json:"procedure"` + ProcedureRoom string `json:"procedureRoom"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Pagination ecore.Pagination +} + +type FilterDto struct { + Encounter_Id uint64 `json:"encounter-id"` + Infra_Code string `json:"procedure-code"` + ProcedureRoom string `json:"procedure-room"` +} + +type ReadDetailDto struct { + Id uint `json:"id"` +} + +type UpdateDto struct { + Id uint `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.Main + Encounter_Id uint64 `json:"encounter_id"` + Encounter *ec.Encounter `json:"encounter,omitempty"` + Infra_Code string `json:"procedure"` + ProcedureRoom *epr.ProcedureRoom `json:"procedureRoom,omitempty"` +} + +func (d ProcedureRoomOrder) ToResponse() ResponseDto { + resp := ResponseDto{ + Encounter_Id: d.Encounter_Id, + Infra_Code: d.Infra_Code, + // ProcedureRoom: d.ProcedureRoom, + } + resp.Id = d.Id + return resp +} + +func ToResponseList(data []ProcedureRoomOrder) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/procedure-room-order/entity.go b/internal/domain/main-entities/procedure-room-order/entity.go new file mode 100644 index 00000000..7e453410 --- /dev/null +++ b/internal/domain/main-entities/procedure-room-order/entity.go @@ -0,0 +1,13 @@ +package procedureroomorder + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + epr "simrs-vx/internal/domain/main-entities/procedure-room" +) + +type ProcedureRoomOrder struct { + ecore.Main + Encounter_Id uint64 `json:"encounter_id"` + Infra_Code string `json:"infra_code" gorm:"size:20"` + ProcedureRoom *epr.ProcedureRoom `json:"procedureRoom,omitempty" gorm:"foreignKey:Infra_Code;references:Code"` +} diff --git a/internal/domain/main-entities/procedure-room/base/entity.go b/internal/domain/main-entities/procedure-room/base/entity.go new file mode 100644 index 00000000..981dd4f2 --- /dev/null +++ b/internal/domain/main-entities/procedure-room/base/entity.go @@ -0,0 +1,21 @@ +package procedureroombase + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + ero "simrs-vx/internal/domain/references/organization" +) + +type ProcedureRoom struct { + ecore.SmallMain + Code string `json:"code" gorm:"unique;size:20"` // copied from infra code + Infra_Code *string `json:"infra_code" gorm:"size:20;unique"` + Type_Code *ero.ProdcedureRoomTypeCode `json:"type_code" gorm:"size:10"` + Unit_Code *string `json:"unit_code" gorm:"size:20"` + Specialist_Code *string `json:"specialist_code" gorm:"size:20"` + Subspecialist_Code *string `json:"subspecialist_code" gorm:"size:20"` +} + +// THIS IS ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ +// func (ProcedureRoom) TableName() string { +// return "Room" +// } diff --git a/internal/domain/main-entities/room/dto.go b/internal/domain/main-entities/procedure-room/dto.go similarity index 82% rename from internal/domain/main-entities/room/dto.go rename to internal/domain/main-entities/procedure-room/dto.go index 2ff41c3a..373e6cd9 100644 --- a/internal/domain/main-entities/room/dto.go +++ b/internal/domain/main-entities/procedure-room/dto.go @@ -1,4 +1,4 @@ -package room +package procedureroom import ( ecore "simrs-vx/internal/domain/base-entities/core" @@ -9,7 +9,9 @@ import ( ) type CreateDto struct { + Code *string `json:"code"` Infra_Code *string `json:"infra_code"` + Type_Code string `json:"type_code"` Unit_Code *string `json:"unit_code"` Specialist_Code *string `json:"specialist_code"` Subspecialist_Code *string `json:"subspecialist_code"` @@ -23,6 +25,7 @@ type ReadListDto struct { type FilterDto struct { Infra_Code *string `json:"infra-code"` + Type_Code string `json:"type_code"` Unit_Code *string `json:"unit-code"` Specialist_Code *string `json:"specialist-code"` Subspecialist_Code *string `json:"subspecialist-code"` @@ -49,6 +52,8 @@ type MetaDto struct { type ResponseDto struct { ecore.SmallMain + Code string `json:"code"` + Type_Code *string `json:"type_code"` Infra_Code *string `json:"infra_code"` Infra *ei.Infra `json:"infra,omitempty"` Unit_Code *string `json:"unit_code"` @@ -59,10 +64,12 @@ type ResponseDto struct { Subspecialist *ess.Subspecialist `json:"subspecialist,omitempty"` } -func (d Room) ToResponse() ResponseDto { +func (d ProcedureRoom) ToResponse() ResponseDto { resp := ResponseDto{ + Code: d.Code, Infra_Code: d.Infra_Code, Infra: d.Infra, + Type_Code: (*string)(d.Type_Code), Unit_Code: d.Unit_Code, Unit: d.Unit, Specialist_Code: d.Specialist_Code, @@ -74,7 +81,7 @@ func (d Room) ToResponse() ResponseDto { return resp } -func ToResponseList(data []Room) []ResponseDto { +func ToResponseList(data []ProcedureRoom) []ResponseDto { resp := make([]ResponseDto, len(data)) for i, u := range data { resp[i] = u.ToResponse() diff --git a/internal/domain/main-entities/procedure-room/entity.go b/internal/domain/main-entities/procedure-room/entity.go new file mode 100644 index 00000000..9be3ac69 --- /dev/null +++ b/internal/domain/main-entities/procedure-room/entity.go @@ -0,0 +1,17 @@ +package procedureroom + +import ( + ei "simrs-vx/internal/domain/main-entities/infra" + ebase "simrs-vx/internal/domain/main-entities/procedure-room/base" + es "simrs-vx/internal/domain/main-entities/specialist" + ess "simrs-vx/internal/domain/main-entities/subspecialist" + eu "simrs-vx/internal/domain/main-entities/unit" +) + +type ProcedureRoom struct { + ebase.ProcedureRoom + Infra *ei.Infra `json:"infra,omitempty" gorm:"foreignKey:Infra_Code;references:Code"` + Unit *eu.Unit `json:"unit,omitempty" gorm:"foreignKey:Unit_Code;references:Code"` + Specialist *es.Specialist `json:"specialist,omitempty" gorm:"foreignKey:Specialist_Code;references:Code"` + Subspecialist *ess.Subspecialist `json:"subspecialist,omitempty" gorm:"foreignKey:Subspecialist_Code;references:Code"` +} diff --git a/internal/domain/main-entities/room/base/entity.go b/internal/domain/main-entities/room/base/entity.go deleted file mode 100644 index d5651ac9..00000000 --- a/internal/domain/main-entities/room/base/entity.go +++ /dev/null @@ -1,23 +0,0 @@ -package base - -import ( - ecore "simrs-vx/internal/domain/base-entities/core" - es "simrs-vx/internal/domain/main-entities/specialist" - ess "simrs-vx/internal/domain/main-entities/subspecialist" - eu "simrs-vx/internal/domain/main-entities/unit" -) - -type Basic struct { - ecore.SmallMain // adjust this according to the needs - Infra_Code *string `json:"infra_code" gorm:"size:10"` - Unit_Code *string `json:"unit_code" gorm:"size:10"` - Unit *eu.Unit `json:"unit,omitempty" gorm:"foreignKey:Unit_Code;references:Code"` - Specialist_Code *string `json:"specialist_code" gorm:"size:10"` - Specialist *es.Specialist `json:"specialist,omitempty" gorm:"foreignKey:Specialist_Code;references:Code"` - Subspecialist_Code *string `json:"subspecialist_code" gorm:"size:10"` - Subspecialist *ess.Subspecialist `json:"subspecialist,omitempty" gorm:"foreignKey:Subspecialist_Code;references:Code"` -} - -func (Basic) TableName() string { - return "Room" -} diff --git a/internal/domain/main-entities/room/entity.go b/internal/domain/main-entities/room/entity.go deleted file mode 100644 index 49fb8cc6..00000000 --- a/internal/domain/main-entities/room/entity.go +++ /dev/null @@ -1,11 +0,0 @@ -package room - -import ( - ei "simrs-vx/internal/domain/main-entities/infra" - ebase "simrs-vx/internal/domain/main-entities/room/base" -) - -type Room struct { - ebase.Basic - Infra *ei.Infra `json:"infra,omitempty" gorm:"foreignKey:Infra_Code;references:Code"` -} diff --git a/internal/domain/main-entities/specialist/entity.go b/internal/domain/main-entities/specialist/entity.go index 4fef90a5..0b5b7a5d 100644 --- a/internal/domain/main-entities/specialist/entity.go +++ b/internal/domain/main-entities/specialist/entity.go @@ -9,9 +9,9 @@ import ( type Specialist struct { ecore.SmallMain // adjust this according to the needs - Code string `json:"code" gorm:"unique;size:10"` + Code string `json:"code" gorm:"unique;size:20"` Name string `json:"name" gorm:"size:50"` - Unit_Code *string `json:"unit_code" gorm:"size:10"` + Unit_Code *string `json:"unit_code" gorm:"size:20"` Unit *eu.Unit `json:"unit,omitempty" gorm:"foreignKey:Unit_Code;references:Code"` SpecialistPositions []eub.Basic `json:"specialistPositions,omitempty" gorm:"foreignKey:Specialist_Code;references:Code"` Subspecialists []essb.Basic `json:"subspecialists,omitempty" gorm:"foreignKey:Specialist_Code;references:Code"` diff --git a/internal/domain/main-entities/subspecialist-position/dto.go b/internal/domain/main-entities/subspecialist-position/dto.go index 1c37a859..4918a8fe 100644 --- a/internal/domain/main-entities/subspecialist-position/dto.go +++ b/internal/domain/main-entities/subspecialist-position/dto.go @@ -8,7 +8,7 @@ import ( type CreateDto struct { Subspecialist_Code *string `json:"subspecialist_code" validate:"required"` - Code string `json:"code" validate:"maxLength=10;required"` + Code string `json:"code" validate:"maxLength=20;required"` Name string `json:"name" validate:"maxLength=30;required"` HeadStatus bool `json:"headStatus"` Employee_Id *uint `json:"employee_id"` diff --git a/internal/domain/main-entities/subspecialist/base/entity.go b/internal/domain/main-entities/subspecialist/base/entity.go index a94fb76d..9fe77039 100644 --- a/internal/domain/main-entities/subspecialist/base/entity.go +++ b/internal/domain/main-entities/subspecialist/base/entity.go @@ -6,9 +6,9 @@ import ( type Basic struct { ecore.SmallMain // adjust this according to the needs - Code string `json:"code" gorm:"unique;size:10"` + Code string `json:"code" gorm:"unique;size:20"` Name string `json:"name" gorm:"size:50"` - Specialist_Code *string `json:"specialist_code" gorm:"size:10"` + Specialist_Code *string `json:"specialist_code" gorm:"size:20"` } func (Basic) TableName() string { diff --git a/internal/domain/main-entities/subspecialist/dto.go b/internal/domain/main-entities/subspecialist/dto.go index 72959023..303da04f 100644 --- a/internal/domain/main-entities/subspecialist/dto.go +++ b/internal/domain/main-entities/subspecialist/dto.go @@ -8,7 +8,7 @@ import ( type CreateDto struct { Id *uint `json:"id"` - Code string `json:"code" validate:"maxLength=10"` + Code string `json:"code" validate:"maxLength=20"` Name string `json:"name" validate:"maxLength=50"` Specialist_Code *string `json:"specialist_code"` } diff --git a/internal/domain/main-entities/unit/dto.go b/internal/domain/main-entities/unit/dto.go index 7b071a84..76151cb7 100644 --- a/internal/domain/main-entities/unit/dto.go +++ b/internal/domain/main-entities/unit/dto.go @@ -9,7 +9,7 @@ import ( type CreateDto struct { Id *uint `json:"id"` Installation_Code *string `json:"installation_code"` - Code string `json:"code" validate:"maxLength=10"` + Code string `json:"code" validate:"maxLength=20"` Name string `json:"name" validate:"maxLength=50"` } diff --git a/internal/domain/main-entities/unit/entity.go b/internal/domain/main-entities/unit/entity.go index 97db9885..e8110db3 100644 --- a/internal/domain/main-entities/unit/entity.go +++ b/internal/domain/main-entities/unit/entity.go @@ -9,9 +9,9 @@ import ( type Unit struct { ecore.SmallMain // adjust this according to the needs - Installation_Code *string `json:"installation_code" gorm:"size:10"` + Installation_Code *string `json:"installation_code" gorm:"size:20"` Installation *ei.Installation `json:"installation" gorm:"foreignKey:Installation_Code;references:Code"` - Code string `json:"code" gorm:"unique;size:10"` + Code string `json:"code" gorm:"unique;size:20"` Name string `json:"name" gorm:"size:50"` Type_Code *ero.UnitTypeCode `json:"type_code"` UnitPositions []eub.Basic `json:"unitPositions,omitempty" gorm:"foreignKey:Unit_Code;references:Code"` diff --git a/internal/domain/references/organization/organization.go b/internal/domain/references/organization/organization.go index b39752d5..0647f88f 100644 --- a/internal/domain/references/organization/organization.go +++ b/internal/domain/references/organization/organization.go @@ -1,14 +1,15 @@ package organization type ( - ContractPositionCode string - EmployeePositionCode string - InternPosisitionCode string - ItemGroupCode string - InfraGroupCode string - UnitTypeCode string - DoctorFeeTypeCode string - ActionBillingCode string + ContractPositionCode string + EmployeePositionCode string + InternPosisitionCode string + ItemGroupCode string + InfraGroupCode string + ProdcedureRoomTypeCode string + UnitTypeCode string + DoctorFeeTypeCode string + ActionBillingCode string ) const ( @@ -44,14 +45,17 @@ const ( ITGCDocFee ItemGroupCode = "doctor-fee" ITGCMedAct ItemGroupCode = "medical-action" - IFGCBuilding InfraGroupCode = "building" // Bangunan - IFGCFloor InfraGroupCode = "floor" // Lantai - IFGCRoom InfraGroupCode = "room" // Ruang - IFGCChamber InfraGroupCode = "chamber" // Kamar - IFGCBed InfraGroupCode = "bed" // Ranjang - IFGCWarehouse InfraGroupCode = "warehouse" // Gudang/Depo - IFGCCounter InfraGroupCode = "counter" // Counter - IFGCPubScreen InfraGroupCode = "public-screen" // Public Screen + IFGCBuilding InfraGroupCode = "building" // Bangunan + IFGCFloor InfraGroupCode = "floor" // Lantai + IFGCProcedureRoom InfraGroupCode = "procedure-room" // Ruang Tindakan + IFGCChamber InfraGroupCode = "chamber" // Kamar + IFGCBed InfraGroupCode = "bed" // Ranjang + IFGCWarehouse InfraGroupCode = "warehouse" // Gudang/Depo + IFGCCounter InfraGroupCode = "counter" // Counter + IFGCPubScreen InfraGroupCode = "public-screen" // Public Screen + + PRTLight ProdcedureRoomTypeCode = "light" // Ringan + PRTSurgery ProdcedureRoomTypeCode = "roomed" // Dikamarkan UTCReg UnitTypeCode = "reg" // Registrasi UTCExa UnitTypeCode = "exa" // Pemeriksaan diff --git a/internal/interface/migration/main-entities.go b/internal/interface/migration/main-entities.go index bed0c18c..0d118fae 100644 --- a/internal/interface/migration/main-entities.go +++ b/internal/interface/migration/main-entities.go @@ -19,6 +19,8 @@ import ( device "simrs-vx/internal/domain/main-entities/device" deviceorder "simrs-vx/internal/domain/main-entities/device-order" deviceorderitem "simrs-vx/internal/domain/main-entities/device-order-item" + devicepackage "simrs-vx/internal/domain/main-entities/device-package" + devicepackageitem "simrs-vx/internal/domain/main-entities/device-package-item" diagnosesrc "simrs-vx/internal/domain/main-entities/diagnose-src" district "simrs-vx/internal/domain/main-entities/district" division "simrs-vx/internal/domain/main-entities/division" @@ -46,6 +48,8 @@ import ( material "simrs-vx/internal/domain/main-entities/material" materialorder "simrs-vx/internal/domain/main-entities/material-order" materialorderitem "simrs-vx/internal/domain/main-entities/material-order-item" + materialpackage "simrs-vx/internal/domain/main-entities/material-package" + materialpackageitem "simrs-vx/internal/domain/main-entities/material-package-item" mcuorder "simrs-vx/internal/domain/main-entities/mcu-order" mcuorderitem "simrs-vx/internal/domain/main-entities/mcu-order-item" mcuordersubitem "simrs-vx/internal/domain/main-entities/mcu-order-sub-item" @@ -78,13 +82,14 @@ import ( practiceschedule "simrs-vx/internal/domain/main-entities/practice-schedule" prescription "simrs-vx/internal/domain/main-entities/prescription" prescriptionitem "simrs-vx/internal/domain/main-entities/prescription-item" + procedureroom "simrs-vx/internal/domain/main-entities/procedure-room" + procedureroomorder "simrs-vx/internal/domain/main-entities/procedure-room-order" proceduresrc "simrs-vx/internal/domain/main-entities/procedure-src" province "simrs-vx/internal/domain/main-entities/province" regency "simrs-vx/internal/domain/main-entities/regency" rehab "simrs-vx/internal/domain/main-entities/rehab" responsibledoctorhist "simrs-vx/internal/domain/main-entities/responsible-doctor-hist" resume "simrs-vx/internal/domain/main-entities/resume" - room "simrs-vx/internal/domain/main-entities/room" sbar "simrs-vx/internal/domain/main-entities/sbar" screening "simrs-vx/internal/domain/main-entities/screening" soapi "simrs-vx/internal/domain/main-entities/soapi" @@ -144,6 +149,7 @@ func getMainEntities() []any { &item.Item{}, &itemprice.ItemPrice{}, &infra.Infra{}, + &procedureroom.ProcedureRoom{}, &medicinegroup.MedicineGroup{}, &medicinemethod.MedicineMethod{}, &mcusrccategory.McuSrcCategory{}, @@ -163,13 +169,17 @@ func getMainEntities() []any { &personrelative.PersonRelative{}, &patient.Patient{}, &appointment.Appointment{}, + &devicepackage.DevicePackage{}, + &devicepackageitem.DevicePackageItem{}, + &materialpackage.MaterialPackage{}, + &materialpackageitem.MaterialPackageItem{}, + &vclaimsep.VclaimSep{}, &encounter.Encounter{}, &laborant.Laborant{}, &specialist.Specialist{}, &subspecialist.Subspecialist{}, &specialistintern.SpecialistIntern{}, - &room.Room{}, &soapi.Soapi{}, &sbar.Sbar{}, &adime.Adime{}, @@ -196,6 +206,8 @@ func getMainEntities() []any { &midwife.Midwife{}, &postalregion.PostalRegion{}, &internalreference.InternalReference{}, + &procedureroomorder.ProcedureRoomOrder{}, + &vclaimsephist.VclaimSepHist{}, &vclaimsepprint.VclaimSepPrint{}, &vehicle.Vehicle{}, From 118aa098cecfc264f7c4620ca3569f62fb9db3fe Mon Sep 17 00:00:00 2001 From: Munawwirul Jamal Date: Tue, 2 Dec 2025 20:56:00 +0700 Subject: [PATCH 30/38] feat/order-things: adjust package-room case --- internal/use-case/main-use-case/infra/case.go | 6 ++--- .../use-case/main-use-case/infra/helper.go | 7 +++--- internal/use-case/main-use-case/infra/lib.go | 2 +- .../{room => procedure-room}/case.go | 16 +++++++------- .../{room => procedure-room}/helper.go | 7 +++--- .../{room => procedure-room}/lib.go | 22 +++++++++---------- .../middleware-runner.go | 14 ++++++------ .../{room => procedure-room}/middleware.go | 2 +- .../{room => procedure-room}/tycovar.go | 10 ++++----- 9 files changed, 44 insertions(+), 42 deletions(-) rename internal/use-case/main-use-case/{room => procedure-room}/case.go (95%) rename internal/use-case/main-use-case/{room => procedure-room}/helper.go (70%) rename internal/use-case/main-use-case/{room => procedure-room}/lib.go (84%) rename internal/use-case/main-use-case/{room => procedure-room}/middleware-runner.go (86%) rename internal/use-case/main-use-case/{room => procedure-room}/middleware.go (90%) rename internal/use-case/main-use-case/{room => procedure-room}/tycovar.go (74%) diff --git a/internal/use-case/main-use-case/infra/case.go b/internal/use-case/main-use-case/infra/case.go index 4771f3cb..f3ba3854 100644 --- a/internal/use-case/main-use-case/infra/case.go +++ b/internal/use-case/main-use-case/infra/case.go @@ -37,7 +37,7 @@ func Create(input e.CreateDto) (*d.Data, error) { return err } - if input.InfraGroup_Code == ero.IFGCRoom { + if input.InfraGroup_Code == ero.IFGCProcedureRoom { if input.Parent_Code == nil { event.Status = "failed" event.ErrInfo = pl.ErrorInfo{ @@ -58,9 +58,9 @@ func Create(input e.CreateDto) (*d.Data, error) { data = *resData } - if input.InfraGroup_Code == ero.IFGCRoom { + if input.InfraGroup_Code == ero.IFGCProcedureRoom { input.Infra_Code = &data.Code - if err := createRoom(&input, &event, tx); err != nil { + if err := createProcedureRoom(&input, &event, tx); err != nil { return err } } diff --git a/internal/use-case/main-use-case/infra/helper.go b/internal/use-case/main-use-case/infra/helper.go index 81de5389..27c5442c 100644 --- a/internal/use-case/main-use-case/infra/helper.go +++ b/internal/use-case/main-use-case/infra/helper.go @@ -7,10 +7,10 @@ package infra import ( e "simrs-vx/internal/domain/main-entities/infra" ei "simrs-vx/internal/domain/main-entities/item" - er "simrs-vx/internal/domain/main-entities/room" + er "simrs-vx/internal/domain/main-entities/procedure-room" ero "simrs-vx/internal/domain/references/organization" ui "simrs-vx/internal/use-case/main-use-case/item" - ur "simrs-vx/internal/use-case/main-use-case/room" + ur "simrs-vx/internal/use-case/main-use-case/procedure-room" pl "simrs-vx/pkg/logger" pu "simrs-vx/pkg/use-case-helper" @@ -53,8 +53,9 @@ func createItem(input *e.CreateDto, event *pl.Event, tx *gorm.DB) error { return nil } -func createRoom(input *e.CreateDto, event *pl.Event, tx *gorm.DB) error { +func createProcedureRoom(input *e.CreateDto, event *pl.Event, tx *gorm.DB) error { roomCreate := er.CreateDto{ + Code: input.Infra_Code, Infra_Code: input.Infra_Code, Unit_Code: input.Unit_Code, Specialist_Code: input.Specialist_Code, diff --git a/internal/use-case/main-use-case/infra/lib.go b/internal/use-case/main-use-case/infra/lib.go index 5e0592c3..cd97d735 100644 --- a/internal/use-case/main-use-case/infra/lib.go +++ b/internal/use-case/main-use-case/infra/lib.go @@ -129,7 +129,7 @@ func UpdateData(input e.UpdateDto, data *e.Infra, event *pl.Event, dbx ...*gorm. // data.Parent = nil data.Childrens = nil data.Item = nil - data.Rooms = nil + data.ProcedureRooms = nil if err := tx.Save(&data).Error; err != nil { event.Status = "failed" diff --git a/internal/use-case/main-use-case/room/case.go b/internal/use-case/main-use-case/procedure-room/case.go similarity index 95% rename from internal/use-case/main-use-case/room/case.go rename to internal/use-case/main-use-case/procedure-room/case.go index eeb1cce1..0378b759 100644 --- a/internal/use-case/main-use-case/room/case.go +++ b/internal/use-case/main-use-case/procedure-room/case.go @@ -1,7 +1,7 @@ -package room +package procedureroom import ( - e "simrs-vx/internal/domain/main-entities/room" + e "simrs-vx/internal/domain/main-entities/procedure-room" "strconv" dg "github.com/karincake/apem/db-gorm-pg" @@ -16,7 +16,7 @@ import ( const source = "specialist" func Create(input e.CreateDto) (*d.Data, error) { - data := e.Room{} + data := e.ProcedureRoom{} event := pl.Event{ Feature: "Create", @@ -66,8 +66,8 @@ func Create(input e.CreateDto) (*d.Data, error) { } func ReadList(input e.ReadListDto) (*d.Data, error) { - var data *e.Room - var dataList []e.Room + var data *e.ProcedureRoom + var dataList []e.ProcedureRoom var metaList *e.MetaDto var err error @@ -119,7 +119,7 @@ func ReadList(input e.ReadListDto) (*d.Data, error) { } func ReadDetail(input e.ReadDetailDto) (*d.Data, error) { - var data *e.Room + var data *e.ProcedureRoom var err error event := pl.Event{ @@ -167,7 +167,7 @@ func ReadDetail(input e.ReadDetailDto) (*d.Data, error) { func Update(input e.UpdateDto) (*d.Data, error) { rdDto := e.ReadDetailDto{Id: uint16(input.Id)} - var data *e.Room + var data *e.ProcedureRoom var err error event := pl.Event{ @@ -223,7 +223,7 @@ func Update(input e.UpdateDto) (*d.Data, error) { func Delete(input e.DeleteDto) (*d.Data, error) { rdDto := e.ReadDetailDto{Id: uint16(input.Id)} - var data *e.Room + var data *e.ProcedureRoom var err error event := pl.Event{ diff --git a/internal/use-case/main-use-case/room/helper.go b/internal/use-case/main-use-case/procedure-room/helper.go similarity index 70% rename from internal/use-case/main-use-case/room/helper.go rename to internal/use-case/main-use-case/procedure-room/helper.go index 5e97a653..0101efef 100644 --- a/internal/use-case/main-use-case/room/helper.go +++ b/internal/use-case/main-use-case/procedure-room/helper.go @@ -2,13 +2,13 @@ DESCRIPTION: Any functions that are used internally by the use-case */ -package room +package procedureroom import ( - e "simrs-vx/internal/domain/main-entities/room" + e "simrs-vx/internal/domain/main-entities/procedure-room" ) -func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Room) { +func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.ProcedureRoom) { var inputSrc *e.CreateDto if inputT, ok := any(input).(*e.CreateDto); ok { inputSrc = inputT @@ -17,6 +17,7 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Room) { inputSrc = &inputTemp.CreateDto } + data.Code = *inputSrc.Infra_Code data.Infra_Code = inputSrc.Infra_Code data.Unit_Code = inputSrc.Unit_Code data.Specialist_Code = inputSrc.Specialist_Code diff --git a/internal/use-case/main-use-case/room/lib.go b/internal/use-case/main-use-case/procedure-room/lib.go similarity index 84% rename from internal/use-case/main-use-case/room/lib.go rename to internal/use-case/main-use-case/procedure-room/lib.go index 5e586248..f9e46d17 100644 --- a/internal/use-case/main-use-case/room/lib.go +++ b/internal/use-case/main-use-case/procedure-room/lib.go @@ -1,7 +1,7 @@ -package room +package procedureroom import ( - e "simrs-vx/internal/domain/main-entities/room" + e "simrs-vx/internal/domain/main-entities/procedure-room" plh "simrs-vx/pkg/lib-helper" pl "simrs-vx/pkg/logger" @@ -12,10 +12,10 @@ import ( "gorm.io/gorm" ) -func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Room, error) { +func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.ProcedureRoom, error) { pl.SetLogInfo(event, nil, "started", "DBCreate") - data := e.Room{} + data := e.ProcedureRoom{} setData(&input, &data) var tx *gorm.DB @@ -33,9 +33,9 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Room, e return &data, nil } -func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Room, *e.MetaDto, error) { +func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.ProcedureRoom, *e.MetaDto, error) { pl.SetLogInfo(event, input, "started", "DBReadList") - data := []e.Room{} + data := []e.ProcedureRoom{} pagination := gh.Pagination{} count := int64(0) meta := e.MetaDto{} @@ -48,7 +48,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Ro } tx = tx. - Model(&e.Room{}). + Model(&e.ProcedureRoom{}). Scopes(gh.Preload(input.Includes)). Scopes(gh.Filter(input.FilterDto)). Count(&count). @@ -70,9 +70,9 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Ro return data, &meta, nil } -func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.Room, error) { +func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.ProcedureRoom, error) { pl.SetLogInfo(event, input, "started", "DBReadDetail") - data := e.Room{} + data := e.ProcedureRoom{} var tx *gorm.DB if len(dbx) > 0 { @@ -91,7 +91,7 @@ func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e return &data, nil } -func UpdateData(input e.UpdateDto, data *e.Room, event *pl.Event, dbx ...*gorm.DB) error { +func UpdateData(input e.UpdateDto, data *e.ProcedureRoom, event *pl.Event, dbx ...*gorm.DB) error { pl.SetLogInfo(event, data, "started", "DBUpdate") setData(&input, data) @@ -116,7 +116,7 @@ func UpdateData(input e.UpdateDto, data *e.Room, event *pl.Event, dbx ...*gorm.D return nil } -func DeleteData(data *e.Room, event *pl.Event, dbx ...*gorm.DB) error { +func DeleteData(data *e.ProcedureRoom, event *pl.Event, dbx ...*gorm.DB) error { pl.SetLogInfo(event, data, "started", "DBDelete") var tx *gorm.DB if len(dbx) > 0 { diff --git a/internal/use-case/main-use-case/room/middleware-runner.go b/internal/use-case/main-use-case/procedure-room/middleware-runner.go similarity index 86% rename from internal/use-case/main-use-case/room/middleware-runner.go rename to internal/use-case/main-use-case/procedure-room/middleware-runner.go index eaeb46fd..bc96f5c6 100644 --- a/internal/use-case/main-use-case/room/middleware-runner.go +++ b/internal/use-case/main-use-case/procedure-room/middleware-runner.go @@ -1,7 +1,7 @@ -package room +package procedureroom import ( - e "simrs-vx/internal/domain/main-entities/room" + e "simrs-vx/internal/domain/main-entities/procedure-room" pl "simrs-vx/pkg/logger" pu "simrs-vx/pkg/use-case-helper" @@ -23,7 +23,7 @@ func newMiddlewareRunner(event *pl.Event, tx *gorm.DB) *middlewareRunner { } // ExecuteCreateMiddleware executes create middleware -func (me *middlewareRunner) RunCreateMiddleware(middlewares []createMw, input *e.CreateDto, data *e.Room) error { +func (me *middlewareRunner) RunCreateMiddleware(middlewares []createMw, input *e.CreateDto, data *e.ProcedureRoom) error { for _, middleware := range middlewares { logData := pu.GetLogData(input, data) @@ -38,7 +38,7 @@ func (me *middlewareRunner) RunCreateMiddleware(middlewares []createMw, input *e return nil } -func (me *middlewareRunner) RunReadListMiddleware(middlewares []readListMw, input *e.ReadListDto, data *e.Room) error { +func (me *middlewareRunner) RunReadListMiddleware(middlewares []readListMw, input *e.ReadListDto, data *e.ProcedureRoom) error { for _, middleware := range middlewares { logData := pu.GetLogData(input, data) @@ -53,7 +53,7 @@ func (me *middlewareRunner) RunReadListMiddleware(middlewares []readListMw, inpu return nil } -func (me *middlewareRunner) RunReadDetailMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.Room) error { +func (me *middlewareRunner) RunReadDetailMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.ProcedureRoom) error { for _, middleware := range middlewares { logData := pu.GetLogData(input, data) @@ -68,7 +68,7 @@ func (me *middlewareRunner) RunReadDetailMiddleware(middlewares []readDetailMw, return nil } -func (me *middlewareRunner) RunUpdateMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.Room) error { +func (me *middlewareRunner) RunUpdateMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.ProcedureRoom) error { for _, middleware := range middlewares { logData := pu.GetLogData(input, data) @@ -83,7 +83,7 @@ func (me *middlewareRunner) RunUpdateMiddleware(middlewares []readDetailMw, inpu return nil } -func (me *middlewareRunner) RunDeleteMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.Room) error { +func (me *middlewareRunner) RunDeleteMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.ProcedureRoom) error { for _, middleware := range middlewares { logData := pu.GetLogData(input, data) diff --git a/internal/use-case/main-use-case/room/middleware.go b/internal/use-case/main-use-case/procedure-room/middleware.go similarity index 90% rename from internal/use-case/main-use-case/room/middleware.go rename to internal/use-case/main-use-case/procedure-room/middleware.go index 668f18e2..c30fa7b1 100644 --- a/internal/use-case/main-use-case/room/middleware.go +++ b/internal/use-case/main-use-case/procedure-room/middleware.go @@ -1,4 +1,4 @@ -package room +package procedureroom // example of middleware // func init() { diff --git a/internal/use-case/main-use-case/room/tycovar.go b/internal/use-case/main-use-case/procedure-room/tycovar.go similarity index 74% rename from internal/use-case/main-use-case/room/tycovar.go rename to internal/use-case/main-use-case/procedure-room/tycovar.go index 789e3f6f..ab9f660b 100644 --- a/internal/use-case/main-use-case/room/tycovar.go +++ b/internal/use-case/main-use-case/procedure-room/tycovar.go @@ -6,27 +6,27 @@ In this sample it also provides type and variable regarding the needs of the middleware to separate from main use-case which has the basic CRUD functionality. The purpose of this is to make the code more maintainable. */ -package room +package procedureroom import ( "gorm.io/gorm" - e "simrs-vx/internal/domain/main-entities/room" + e "simrs-vx/internal/domain/main-entities/procedure-room" ) type createMw struct { Name string - Func func(input *e.CreateDto, data *e.Room, tx *gorm.DB) error + Func func(input *e.CreateDto, data *e.ProcedureRoom, tx *gorm.DB) error } type readListMw struct { Name string - Func func(input *e.ReadListDto, data *e.Room, tx *gorm.DB) error + Func func(input *e.ReadListDto, data *e.ProcedureRoom, tx *gorm.DB) error } type readDetailMw struct { Name string - Func func(input *e.ReadDetailDto, data *e.Room, tx *gorm.DB) error + Func func(input *e.ReadDetailDto, data *e.ProcedureRoom, tx *gorm.DB) error } type UpdateMw = readDetailMw From 7d7c0aee1840ebc9f4c933d2bea836d96e13ed0b Mon Sep 17 00:00:00 2001 From: Munawwirul Jamal Date: Tue, 2 Dec 2025 21:35:08 +0700 Subject: [PATCH 31/38] order-things: added material-package flow --- .../interface/main-handler/main-handler.go | 2 + .../main-handler/material-package/handler.go | 71 +++++ .../main-use-case/material-package/case.go | 276 ++++++++++++++++++ .../main-use-case/material-package/helper.go | 22 ++ .../main-use-case/material-package/lib.go | 146 +++++++++ .../material-package/middleware-runner.go | 103 +++++++ .../material-package/middleware.go | 9 + .../main-use-case/material-package/tycovar.go | 44 +++ 8 files changed, 673 insertions(+) create mode 100644 internal/interface/main-handler/material-package/handler.go create mode 100644 internal/use-case/main-use-case/material-package/case.go create mode 100644 internal/use-case/main-use-case/material-package/helper.go create mode 100644 internal/use-case/main-use-case/material-package/lib.go create mode 100644 internal/use-case/main-use-case/material-package/middleware-runner.go create mode 100644 internal/use-case/main-use-case/material-package/middleware.go create mode 100644 internal/use-case/main-use-case/material-package/tycovar.go diff --git a/internal/interface/main-handler/main-handler.go b/internal/interface/main-handler/main-handler.go index dd025d0e..31b238ac 100644 --- a/internal/interface/main-handler/main-handler.go +++ b/internal/interface/main-handler/main-handler.go @@ -93,6 +93,7 @@ import ( itemprice "simrs-vx/internal/interface/main-handler/item-price" language "simrs-vx/internal/interface/main-handler/language" material "simrs-vx/internal/interface/main-handler/material" + materialpackage "simrs-vx/internal/interface/main-handler/material-package" mcusrc "simrs-vx/internal/interface/main-handler/mcu-src" mcusrccategory "simrs-vx/internal/interface/main-handler/mcu-src-category" mcusubsrc "simrs-vx/internal/interface/main-handler/mcu-sub-src" @@ -370,6 +371,7 @@ func SetRoutes() http.Handler { hc.RegCrudByCode(r, "/v1/medicine", medicine.O) hc.RegCrudByCode(r, "/v1/device", device.O) hc.RegCrudByCode(r, "/v1/material", material.O) + hc.RegCrudByCode(r, "/v1/material-package", materialpackage.O) hc.RegCrud(r, "/v1/doctor-fee", doctorfee.O) hc.RegCrudByCode(r, "/v1/medical-action-src", medicalactionsrc.O) hc.RegCrud(r, "/v1/medical-action-src-item", medicalactionsrcitem.O) diff --git a/internal/interface/main-handler/material-package/handler.go b/internal/interface/main-handler/material-package/handler.go new file mode 100644 index 00000000..609d983e --- /dev/null +++ b/internal/interface/main-handler/material-package/handler.go @@ -0,0 +1,71 @@ +package material + +import ( + "net/http" + + rw "github.com/karincake/risoles" + sf "github.com/karincake/semprit" + + // ua "github.com/karincake/tumpeng/auth/svc" + + e "simrs-vx/internal/domain/main-entities/material-package" + u "simrs-vx/internal/use-case/main-use-case/material-package" +) + +type myBase struct{} + +var O myBase + +func (obj myBase) Create(w http.ResponseWriter, r *http.Request) { + dto := e.CreateDto{} + if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { + return + } + res, err := u.Create(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) GetList(w http.ResponseWriter, r *http.Request) { + dto := e.ReadListDto{} + sf.UrlQueryParam(&dto, *r.URL) + res, err := u.ReadList(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) { + code := rw.ValidateString(w, "code", r.PathValue("code")) + if code == "" { + return + } + dto := e.ReadDetailDto{} + dto.Code = &code + res, err := u.ReadDetail(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) Update(w http.ResponseWriter, r *http.Request) { + code := rw.ValidateString(w, "code", r.PathValue("code")) + if code == "" { + return + } + + dto := e.UpdateDto{} + if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { + return + } + dto.Code = code + res, err := u.Update(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) { + code := rw.ValidateString(w, "code", r.PathValue("code")) + if code == "" { + return + } + + dto := e.DeleteDto{} + dto.Code = &code + res, err := u.Delete(dto) + rw.DataResponse(w, res, err) +} diff --git a/internal/use-case/main-use-case/material-package/case.go b/internal/use-case/main-use-case/material-package/case.go new file mode 100644 index 00000000..5e56517b --- /dev/null +++ b/internal/use-case/main-use-case/material-package/case.go @@ -0,0 +1,276 @@ +package materialpackage + +import ( + e "simrs-vx/internal/domain/main-entities/material-package" + "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" +) + +const source = "material" + +func Create(input e.CreateDto) (*d.Data, error) { + data := e.MaterialPackage{} + + event := pl.Event{ + Feature: "Create", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "create") + + 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 ReadList(input e.ReadListDto) (*d.Data, error) { + var data *e.MaterialPackage + var dataList []e.MaterialPackage + 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 { + 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: e.ToResponseList(dataList), + }, nil +} + +func ReadDetail(input e.ReadDetailDto) (*d.Data, error) { + var data *e.MaterialPackage + 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 e.UpdateDto) (*d.Data, error) { + rdDto := e.ReadDetailDto{Code: &input.Code} + var data *e.MaterialPackage + var err error + + event := pl.Event{ + Feature: "Update", + Source: source, + } + + // 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 + } + + 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 + } + + 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 e.DeleteDto) (*d.Data, error) { + rdDto := e.ReadDetailDto{Code: input.Code} + var data *e.MaterialPackage + 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 + +} diff --git a/internal/use-case/main-use-case/material-package/helper.go b/internal/use-case/main-use-case/material-package/helper.go new file mode 100644 index 00000000..7d8e7a9a --- /dev/null +++ b/internal/use-case/main-use-case/material-package/helper.go @@ -0,0 +1,22 @@ +/* +DESCRIPTION: +Any functions that are used internally by the use-case +*/ +package materialpackage + +import ( + e "simrs-vx/internal/domain/main-entities/material-package" +) + +func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.MaterialPackage) { + var inputSrc *e.CreateDto + if inputT, ok := any(input).(*e.CreateDto); ok { + inputSrc = inputT + } else { + inputTemp := any(input).(*e.UpdateDto) + inputSrc = &inputTemp.CreateDto + } + + data.Code = inputSrc.Code + data.Name = inputSrc.Name +} diff --git a/internal/use-case/main-use-case/material-package/lib.go b/internal/use-case/main-use-case/material-package/lib.go new file mode 100644 index 00000000..d4d6ac50 --- /dev/null +++ b/internal/use-case/main-use-case/material-package/lib.go @@ -0,0 +1,146 @@ +package materialpackage + +import ( + e "simrs-vx/internal/domain/main-entities/material-package" + + plh "simrs-vx/pkg/lib-helper" + pl "simrs-vx/pkg/logger" + pu "simrs-vx/pkg/use-case-helper" + + dg "github.com/karincake/apem/db-gorm-pg" + gh "github.com/karincake/getuk" + "gorm.io/gorm" +) + +func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.MaterialPackage, error) { + pl.SetLogInfo(event, nil, "started", "DBCreate") + + data := e.MaterialPackage{} + setData(&input, &data) + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Create(&data).Error; err != nil { + return nil, plh.HandleCreateError(input, event, err) + } + + pl.SetLogInfo(event, nil, "complete") + return &data, nil +} + +func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.MaterialPackage, *e.MetaDto, error) { + pl.SetLogInfo(event, input, "started", "DBReadList") + data := []e.MaterialPackage{} + pagination := gh.Pagination{} + count := int64(0) + meta := e.MetaDto{} + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + tx = tx. + Model(&e.MaterialPackage{}). + Scopes(gh.Preload(input.Includes)). + Scopes(gh.Filter(input.FilterDto)). + Count(&count). + Scopes(gh.Paginate(input, &pagination)). + Scopes(gh.Sort(input.Sort)) + + if err := tx.Find(&data).Error; err != nil { + if err == gorm.ErrRecordNotFound { + return nil, &meta, nil + } + return nil, nil, plh.HandleListError(input, event, err) + } + + meta.Count = int(count) + meta.PageNumber = pagination.PageNumber + meta.PageSize = pagination.PageSize + + pl.SetLogInfo(event, nil, "complete") + return data, &meta, nil +} + +func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.MaterialPackage, error) { + pl.SetLogInfo(event, input, "started", "DBReadDetail") + data := e.MaterialPackage{} + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if input.Code != nil { + tx = tx.Where("\"Code\" = ?", *input.Code) + } else { + tx = tx.Where("\"Id\" = ?", *input.Id) + } + + if err := tx.First(&data).Error; err != nil { + if processedErr := pu.HandleReadError(err, event, source, input.Id, data); processedErr != nil { + return nil, processedErr + } + } + + pl.SetLogInfo(event, nil, "complete") + return &data, nil +} + +func UpdateData(input e.UpdateDto, data *e.MaterialPackage, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, data, "started", "DBUpdate") + setData(&input, data) + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Save(&data).Error; err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-update-fail", + Detail: "Database update failed", + Raw: err, + } + return pl.SetLogError(event, input) + } + + pl.SetLogInfo(event, nil, "complete") + return nil +} + +func DeleteData(data *e.MaterialPackage, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, data, "started", "DBDelete") + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Delete(&data).Error; err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-delete-fail", + Detail: "Database delete failed", + Raw: err, + } + return pl.SetLogError(event, data) + } + + pl.SetLogInfo(event, nil, "complete") + return nil +} diff --git a/internal/use-case/main-use-case/material-package/middleware-runner.go b/internal/use-case/main-use-case/material-package/middleware-runner.go new file mode 100644 index 00000000..b1ea182c --- /dev/null +++ b/internal/use-case/main-use-case/material-package/middleware-runner.go @@ -0,0 +1,103 @@ +package materialpackage + +import ( + e "simrs-vx/internal/domain/main-entities/material-package" + pl "simrs-vx/pkg/logger" + pu "simrs-vx/pkg/use-case-helper" + + "gorm.io/gorm" +) + +type middlewareRunner struct { + Event *pl.Event + Tx *gorm.DB + MwType pu.MWType +} + +// NewMiddlewareExecutor creates a new middleware executor +func newMiddlewareRunner(event *pl.Event, tx *gorm.DB) *middlewareRunner { + return &middlewareRunner{ + Event: event, + Tx: tx, + } +} + +// ExecuteCreateMiddleware executes create middleware +func (me *middlewareRunner) RunCreateMiddleware(middlewares []createMw, input *e.CreateDto, data *e.MaterialPackage) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) RunReadListMiddleware(middlewares []readListMw, input *e.ReadListDto, data *e.MaterialPackage) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) RunReadDetailMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.MaterialPackage) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) RunUpdateMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.MaterialPackage) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) RunDeleteMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.MaterialPackage) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) setMwType(mwType pu.MWType) { + me.MwType = mwType +} diff --git a/internal/use-case/main-use-case/material-package/middleware.go b/internal/use-case/main-use-case/material-package/middleware.go new file mode 100644 index 00000000..85020e68 --- /dev/null +++ b/internal/use-case/main-use-case/material-package/middleware.go @@ -0,0 +1,9 @@ +package materialpackage + +// example of middleware +// func init() { +// createPreMw = append(createPreMw, +// CreateMw{Name: "modif-input", Func: pm.ModifInput}, +// CreateMw{Name: "check-data", Func: pm.CheckData}, +// ) +// } diff --git a/internal/use-case/main-use-case/material-package/tycovar.go b/internal/use-case/main-use-case/material-package/tycovar.go new file mode 100644 index 00000000..67aa3174 --- /dev/null +++ b/internal/use-case/main-use-case/material-package/tycovar.go @@ -0,0 +1,44 @@ +/* +DESCRIPTION: +A sample, part of the package that contains type, constants, and/or variables. + +In this sample it also provides type and variable regarding the needs of the +middleware to separate from main use-case which has the basic CRUD +functionality. The purpose of this is to make the code more maintainable. +*/ +package materialpackage + +import ( + "gorm.io/gorm" + + e "simrs-vx/internal/domain/main-entities/material-package" +) + +type createMw struct { + Name string + Func func(input *e.CreateDto, data *e.MaterialPackage, tx *gorm.DB) error +} + +type readListMw struct { + Name string + Func func(input *e.ReadListDto, data *e.MaterialPackage, tx *gorm.DB) error +} + +type readDetailMw struct { + Name string + Func func(input *e.ReadDetailDto, data *e.MaterialPackage, tx *gorm.DB) error +} + +type UpdateMw = readDetailMw +type DeleteMw = readDetailMw + +var createPreMw []createMw // preprocess middleware +var createPostMw []createMw // postprocess middleware +var readListPreMw []readListMw // .. +var readListPostMw []readListMw // .. +var readDetailPreMw []readDetailMw +var readDetailPostMw []readDetailMw +var updatePreMw []readDetailMw +var updatePostMw []readDetailMw +var deletePreMw []readDetailMw +var deletePostMw []readDetailMw From 83cdfcf0f846003685d67cb58a7a8223dbeef2d1 Mon Sep 17 00:00:00 2001 From: Munawwirul Jamal Date: Tue, 2 Dec 2025 22:30:03 +0700 Subject: [PATCH 32/38] feat/order-things: added material-package-item flow --- .../material-package-item/dto.go | 9 +- .../interface/main-handler/main-handler.go | 2 + .../material-package-item/handler.go | 71 +++++ .../material-package-item/case.go | 276 ++++++++++++++++++ .../material-package-item/helper.go | 22 ++ .../material-package-item/lib.go | 140 +++++++++ .../middleware-runner.go | 103 +++++++ .../material-package-item/middleware.go | 9 + .../material-package-item/tycovar.go | 44 +++ 9 files changed, 672 insertions(+), 4 deletions(-) create mode 100644 internal/interface/main-handler/material-package-item/handler.go create mode 100644 internal/use-case/main-use-case/material-package-item/case.go create mode 100644 internal/use-case/main-use-case/material-package-item/helper.go create mode 100644 internal/use-case/main-use-case/material-package-item/lib.go create mode 100644 internal/use-case/main-use-case/material-package-item/middleware-runner.go create mode 100644 internal/use-case/main-use-case/material-package-item/middleware.go create mode 100644 internal/use-case/main-use-case/material-package-item/tycovar.go diff --git a/internal/domain/main-entities/material-package-item/dto.go b/internal/domain/main-entities/material-package-item/dto.go index a9b11be6..fd282873 100644 --- a/internal/domain/main-entities/material-package-item/dto.go +++ b/internal/domain/main-entities/material-package-item/dto.go @@ -8,18 +8,19 @@ import ( type CreateDto struct { MaterialPackage_Code string `json:"materialPackage_code" validate:"maxLength=20"` - Material_Code string `json:"code" validate:"maxLength=20"` + Material_Code string `json:"material_code" validate:"maxLength=20"` } type ReadListDto struct { FilterDto Includes string `json:"includes"` Pagination ecore.Pagination + Sort string `json:"sort"` } type FilterDto struct { - MaterialPackage_Code string `json:"materialPackage-code"` - Material_Code string `json:"code"` + MaterialPackage_Code string `json:"material-package-code"` + Material_Code string `json:"material_code"` } type ReadDetailDto struct { @@ -45,7 +46,7 @@ type ResponseDto struct { ecore.Main MaterialPackage_Code string `json:"materialPackage_code"` MaterialPackage *emp.MaterialPackage `json:"materialPackage,omitempty"` - Material_Code string `json:"code"` + Material_Code string `json:"material_code"` Material *em.Material `json:"material,omitempty"` } diff --git a/internal/interface/main-handler/main-handler.go b/internal/interface/main-handler/main-handler.go index 31b238ac..8444aafc 100644 --- a/internal/interface/main-handler/main-handler.go +++ b/internal/interface/main-handler/main-handler.go @@ -94,6 +94,7 @@ import ( language "simrs-vx/internal/interface/main-handler/language" material "simrs-vx/internal/interface/main-handler/material" materialpackage "simrs-vx/internal/interface/main-handler/material-package" + materialpackageitem "simrs-vx/internal/interface/main-handler/material-package-item" mcusrc "simrs-vx/internal/interface/main-handler/mcu-src" mcusrccategory "simrs-vx/internal/interface/main-handler/mcu-src-category" mcusubsrc "simrs-vx/internal/interface/main-handler/mcu-sub-src" @@ -372,6 +373,7 @@ func SetRoutes() http.Handler { hc.RegCrudByCode(r, "/v1/device", device.O) hc.RegCrudByCode(r, "/v1/material", material.O) hc.RegCrudByCode(r, "/v1/material-package", materialpackage.O) + hc.RegCrud(r, "/v1/material-package-item", materialpackageitem.O) hc.RegCrud(r, "/v1/doctor-fee", doctorfee.O) hc.RegCrudByCode(r, "/v1/medical-action-src", medicalactionsrc.O) hc.RegCrud(r, "/v1/medical-action-src-item", medicalactionsrcitem.O) diff --git a/internal/interface/main-handler/material-package-item/handler.go b/internal/interface/main-handler/material-package-item/handler.go new file mode 100644 index 00000000..11deb6d9 --- /dev/null +++ b/internal/interface/main-handler/material-package-item/handler.go @@ -0,0 +1,71 @@ +package material + +import ( + "net/http" + + rw "github.com/karincake/risoles" + sf "github.com/karincake/semprit" + + // ua "github.com/karincake/tumpeng/auth/svc" + + e "simrs-vx/internal/domain/main-entities/material-package-item" + u "simrs-vx/internal/use-case/main-use-case/material-package-item" +) + +type myBase struct{} + +var O myBase + +func (obj myBase) Create(w http.ResponseWriter, r *http.Request) { + dto := e.CreateDto{} + if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { + return + } + res, err := u.Create(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) GetList(w http.ResponseWriter, r *http.Request) { + dto := e.ReadListDto{} + sf.UrlQueryParam(&dto, *r.URL) + res, err := u.ReadList(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) { + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id == 0 { + return + } + dto := e.ReadDetailDto{} + dto.Id = uint(id) + res, err := u.ReadDetail(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) Update(w http.ResponseWriter, r *http.Request) { + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id == 0 { + return + } + + dto := e.UpdateDto{} + if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { + return + } + dto.Id = uint(id) + res, err := u.Update(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) { + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id == 0 { + return + } + + dto := e.DeleteDto{} + dto.Id = uint(id) + res, err := u.Delete(dto) + rw.DataResponse(w, res, err) +} diff --git a/internal/use-case/main-use-case/material-package-item/case.go b/internal/use-case/main-use-case/material-package-item/case.go new file mode 100644 index 00000000..ecd891a6 --- /dev/null +++ b/internal/use-case/main-use-case/material-package-item/case.go @@ -0,0 +1,276 @@ +package materialpackageorder + +import ( + e "simrs-vx/internal/domain/main-entities/material-package-item" + "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" +) + +const source = "material" + +func Create(input e.CreateDto) (*d.Data, error) { + data := e.MaterialPackageItem{} + + event := pl.Event{ + Feature: "Create", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "create") + + 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 ReadList(input e.ReadListDto) (*d.Data, error) { + var data *e.MaterialPackageItem + var dataList []e.MaterialPackageItem + 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 { + 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: e.ToResponseList(dataList), + }, nil +} + +func ReadDetail(input e.ReadDetailDto) (*d.Data, error) { + var data *e.MaterialPackageItem + 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 e.UpdateDto) (*d.Data, error) { + rdDto := e.ReadDetailDto{Id: input.Id} + var data *e.MaterialPackageItem + var err error + + event := pl.Event{ + Feature: "Update", + Source: source, + } + + // 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 + } + + 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 + } + + 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 e.DeleteDto) (*d.Data, error) { + rdDto := e.ReadDetailDto{Id: input.Id} + var data *e.MaterialPackageItem + 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 + +} diff --git a/internal/use-case/main-use-case/material-package-item/helper.go b/internal/use-case/main-use-case/material-package-item/helper.go new file mode 100644 index 00000000..c175f776 --- /dev/null +++ b/internal/use-case/main-use-case/material-package-item/helper.go @@ -0,0 +1,22 @@ +/* +DESCRIPTION: +Any functions that are used internally by the use-case +*/ +package materialpackageorder + +import ( + e "simrs-vx/internal/domain/main-entities/material-package-item" +) + +func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.MaterialPackageItem) { + var inputSrc *e.CreateDto + if inputT, ok := any(input).(*e.CreateDto); ok { + inputSrc = inputT + } else { + inputTemp := any(input).(*e.UpdateDto) + inputSrc = &inputTemp.CreateDto + } + + data.MaterialPackage_Code = inputSrc.MaterialPackage_Code + data.Material_Code = inputSrc.Material_Code +} diff --git a/internal/use-case/main-use-case/material-package-item/lib.go b/internal/use-case/main-use-case/material-package-item/lib.go new file mode 100644 index 00000000..fc469249 --- /dev/null +++ b/internal/use-case/main-use-case/material-package-item/lib.go @@ -0,0 +1,140 @@ +package materialpackageorder + +import ( + e "simrs-vx/internal/domain/main-entities/material-package-item" + + plh "simrs-vx/pkg/lib-helper" + pl "simrs-vx/pkg/logger" + pu "simrs-vx/pkg/use-case-helper" + + dg "github.com/karincake/apem/db-gorm-pg" + gh "github.com/karincake/getuk" + "gorm.io/gorm" +) + +func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.MaterialPackageItem, error) { + pl.SetLogInfo(event, nil, "started", "DBCreate") + + data := e.MaterialPackageItem{} + setData(&input, &data) + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Create(&data).Error; err != nil { + return nil, plh.HandleCreateError(input, event, err) + } + + pl.SetLogInfo(event, nil, "complete") + return &data, nil +} + +func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.MaterialPackageItem, *e.MetaDto, error) { + pl.SetLogInfo(event, input, "started", "DBReadList") + data := []e.MaterialPackageItem{} + pagination := gh.Pagination{} + count := int64(0) + meta := e.MetaDto{} + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + tx = tx. + Model(&e.MaterialPackageItem{}). + Scopes(gh.Preload(input.Includes)). + Scopes(gh.Filter(input.FilterDto)). + Count(&count). + Scopes(gh.Paginate(input, &pagination)). + Scopes(gh.Sort(input.Sort)) + + if err := tx.Find(&data).Error; err != nil { + if err == gorm.ErrRecordNotFound { + return nil, &meta, nil + } + return nil, nil, plh.HandleListError(input, event, err) + } + + meta.Count = int(count) + meta.PageNumber = pagination.PageNumber + meta.PageSize = pagination.PageSize + + pl.SetLogInfo(event, nil, "complete") + return data, &meta, nil +} + +func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.MaterialPackageItem, error) { + pl.SetLogInfo(event, input, "started", "DBReadDetail") + data := e.MaterialPackageItem{} + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.First(&data, input.Id).Error; err != nil { + if processedErr := pu.HandleReadError(err, event, source, input.Id, data); processedErr != nil { + return nil, processedErr + } + } + + pl.SetLogInfo(event, nil, "complete") + return &data, nil +} + +func UpdateData(input e.UpdateDto, data *e.MaterialPackageItem, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, data, "started", "DBUpdate") + setData(&input, data) + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Save(&data).Error; err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-update-fail", + Detail: "Database update failed", + Raw: err, + } + return pl.SetLogError(event, input) + } + + pl.SetLogInfo(event, nil, "complete") + return nil +} + +func DeleteData(data *e.MaterialPackageItem, event *pl.Event, dbx ...*gorm.DB) error { + pl.SetLogInfo(event, data, "started", "DBDelete") + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Delete(&data).Error; err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-delete-fail", + Detail: "Database delete failed", + Raw: err, + } + return pl.SetLogError(event, data) + } + + pl.SetLogInfo(event, nil, "complete") + return nil +} diff --git a/internal/use-case/main-use-case/material-package-item/middleware-runner.go b/internal/use-case/main-use-case/material-package-item/middleware-runner.go new file mode 100644 index 00000000..09dfb39b --- /dev/null +++ b/internal/use-case/main-use-case/material-package-item/middleware-runner.go @@ -0,0 +1,103 @@ +package materialpackageorder + +import ( + e "simrs-vx/internal/domain/main-entities/material-package-item" + pl "simrs-vx/pkg/logger" + pu "simrs-vx/pkg/use-case-helper" + + "gorm.io/gorm" +) + +type middlewareRunner struct { + Event *pl.Event + Tx *gorm.DB + MwType pu.MWType +} + +// NewMiddlewareExecutor creates a new middleware executor +func newMiddlewareRunner(event *pl.Event, tx *gorm.DB) *middlewareRunner { + return &middlewareRunner{ + Event: event, + Tx: tx, + } +} + +// ExecuteCreateMiddleware executes create middleware +func (me *middlewareRunner) RunCreateMiddleware(middlewares []createMw, input *e.CreateDto, data *e.MaterialPackageItem) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) RunReadListMiddleware(middlewares []readListMw, input *e.ReadListDto, data *e.MaterialPackageItem) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) RunReadDetailMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.MaterialPackageItem) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) RunUpdateMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.MaterialPackageItem) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) RunDeleteMiddleware(middlewares []readDetailMw, input *e.ReadDetailDto, data *e.MaterialPackageItem) error { + for _, middleware := range middlewares { + logData := pu.GetLogData(input, data) + + pl.SetLogInfo(me.Event, logData, "started", middleware.Name) + + if err := middleware.Func(input, data, me.Tx); err != nil { + return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err) + } + + pl.SetLogInfo(me.Event, nil, "complete") + } + return nil +} + +func (me *middlewareRunner) setMwType(mwType pu.MWType) { + me.MwType = mwType +} diff --git a/internal/use-case/main-use-case/material-package-item/middleware.go b/internal/use-case/main-use-case/material-package-item/middleware.go new file mode 100644 index 00000000..1d1186af --- /dev/null +++ b/internal/use-case/main-use-case/material-package-item/middleware.go @@ -0,0 +1,9 @@ +package materialpackageorder + +// example of middleware +// func init() { +// createPreMw = append(createPreMw, +// CreateMw{Name: "modif-input", Func: pm.ModifInput}, +// CreateMw{Name: "check-data", Func: pm.CheckData}, +// ) +// } diff --git a/internal/use-case/main-use-case/material-package-item/tycovar.go b/internal/use-case/main-use-case/material-package-item/tycovar.go new file mode 100644 index 00000000..a7e239f1 --- /dev/null +++ b/internal/use-case/main-use-case/material-package-item/tycovar.go @@ -0,0 +1,44 @@ +/* +DESCRIPTION: +A sample, part of the package that contains type, constants, and/or variables. + +In this sample it also provides type and variable regarding the needs of the +middleware to separate from main use-case which has the basic CRUD +functionality. The purpose of this is to make the code more maintainable. +*/ +package materialpackageorder + +import ( + "gorm.io/gorm" + + e "simrs-vx/internal/domain/main-entities/material-package-item" +) + +type createMw struct { + Name string + Func func(input *e.CreateDto, data *e.MaterialPackageItem, tx *gorm.DB) error +} + +type readListMw struct { + Name string + Func func(input *e.ReadListDto, data *e.MaterialPackageItem, tx *gorm.DB) error +} + +type readDetailMw struct { + Name string + Func func(input *e.ReadDetailDto, data *e.MaterialPackageItem, tx *gorm.DB) error +} + +type UpdateMw = readDetailMw +type DeleteMw = readDetailMw + +var createPreMw []createMw // preprocess middleware +var createPostMw []createMw // postprocess middleware +var readListPreMw []readListMw // .. +var readListPostMw []readListMw // .. +var readDetailPreMw []readDetailMw +var readDetailPostMw []readDetailMw +var updatePreMw []readDetailMw +var updatePostMw []readDetailMw +var deletePreMw []readDetailMw +var deletePostMw []readDetailMw From aa79933dd91ff7a3594e39e4214dc333e12f2f91 Mon Sep 17 00:00:00 2001 From: Munawwirul Jamal Date: Tue, 2 Dec 2025 23:09:26 +0700 Subject: [PATCH 33/38] feat/order-things: adjust procedure-room order --- cmd/main-migration/migrations/20251202160848.sql | 2 ++ cmd/main-migration/migrations/atlas.sum | 5 +++-- .../domain/main-entities/procedure-room-order/entity.go | 9 ++++++--- 3 files changed, 11 insertions(+), 5 deletions(-) create mode 100644 cmd/main-migration/migrations/20251202160848.sql diff --git a/cmd/main-migration/migrations/20251202160848.sql b/cmd/main-migration/migrations/20251202160848.sql new file mode 100644 index 00000000..8d77fe04 --- /dev/null +++ b/cmd/main-migration/migrations/20251202160848.sql @@ -0,0 +1,2 @@ +-- Modify "ProcedureRoomOrder" table +ALTER TABLE "public"."ProcedureRoomOrder" ADD COLUMN "MaterialPackage_Code" character varying(20) NULL, ADD CONSTRAINT "fk_ProcedureRoomOrder_MaterialPackage" FOREIGN KEY ("MaterialPackage_Code") REFERENCES "public"."MaterialPackage" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION; diff --git a/cmd/main-migration/migrations/atlas.sum b/cmd/main-migration/migrations/atlas.sum index 54858b7b..d7d84cc6 100644 --- a/cmd/main-migration/migrations/atlas.sum +++ b/cmd/main-migration/migrations/atlas.sum @@ -1,4 +1,4 @@ -h1:cyae1SX3YSMX1LZLEsCFxcRKbVxpnp46BqFxWXJqKjs= +h1:Gt8/vjlUshOzs/MWOnRZfDnDn2lrMZE4rcVk5k41R+Y= 20250904105930.sql h1:MEM6blCgke9DzWQSTnLzasbPIrcHssNNrJqZpSkEo6k= 20250904141448.sql h1:J8cmYNk4ZrG9fhfbi2Z1IWz7YkfvhFqTzrLFo58BPY0= 20250908062237.sql h1:Pu23yEW/aKkwozHoOuROvHS/GK4ngARJGdO7FB7HZuI= @@ -140,4 +140,5 @@ h1:cyae1SX3YSMX1LZLEsCFxcRKbVxpnp46BqFxWXJqKjs= 20251202030445.sql h1:QWBVfTepT7DaXP5E0BYoxNM0JwKIQ2qIMXzI4kbz/qE= 20251202044430.sql h1:4QZH9lz0GrQ9rzP1AJ+hJgGalNpp+8FCRckNK7xaTbU= 20251202064000.sql h1:/EN7sT1ol/91qW1aXWrzX+Mc3XOC/7f/LtfA0JRHpbg= -20251202130629.sql h1:LjBgQS8tKEwpC3WA0wGeO2Fs2L20kEOB6e5ljO4EdLM= +20251202130629.sql h1:9mvalqfhqGCdkcJepJDzHprU2xb0i5sYys1Htf62ioo= +20251202160848.sql h1:TTy6DM7FI2+AyxY7mAFDEYVHE0484WKreRM4898rvOk= diff --git a/internal/domain/main-entities/procedure-room-order/entity.go b/internal/domain/main-entities/procedure-room-order/entity.go index 7e453410..c0fb846e 100644 --- a/internal/domain/main-entities/procedure-room-order/entity.go +++ b/internal/domain/main-entities/procedure-room-order/entity.go @@ -2,12 +2,15 @@ package procedureroomorder import ( ecore "simrs-vx/internal/domain/base-entities/core" + emp "simrs-vx/internal/domain/main-entities/material-package" epr "simrs-vx/internal/domain/main-entities/procedure-room" ) type ProcedureRoomOrder struct { ecore.Main - Encounter_Id uint64 `json:"encounter_id"` - Infra_Code string `json:"infra_code" gorm:"size:20"` - ProcedureRoom *epr.ProcedureRoom `json:"procedureRoom,omitempty" gorm:"foreignKey:Infra_Code;references:Code"` + Encounter_Id uint64 `json:"encounter_id"` + Infra_Code string `json:"infra_code" gorm:"size:20"` + ProcedureRoom *epr.ProcedureRoom `json:"procedureRoom,omitempty" gorm:"foreignKey:Infra_Code;references:Code"` + MaterialPackage_Code string `json:"materialPackageCode" gorm:"size:20"` + MaterialPackage *emp.MaterialPackage `json:"materialPackage,omitempty" gorm:"foreignKey:MaterialPackage_Code;references:Code"` } From cbff83e4dec35eca226e48a5adfae21334a43fe4 Mon Sep 17 00:00:00 2001 From: Munawwirul Jamal Date: Tue, 2 Dec 2025 23:14:53 +0700 Subject: [PATCH 34/38] feat/other-things: adjust const --- cmd/main-migration/migrations/atlas.sum | 4 ++-- internal/domain/references/organization/organization.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/main-migration/migrations/atlas.sum b/cmd/main-migration/migrations/atlas.sum index d7d84cc6..72d356db 100644 --- a/cmd/main-migration/migrations/atlas.sum +++ b/cmd/main-migration/migrations/atlas.sum @@ -1,4 +1,4 @@ -h1:Gt8/vjlUshOzs/MWOnRZfDnDn2lrMZE4rcVk5k41R+Y= +h1:2q1xxtaiHIoZtVnG80kXG6u4BZVgy44lTmW3zd6freo= 20250904105930.sql h1:MEM6blCgke9DzWQSTnLzasbPIrcHssNNrJqZpSkEo6k= 20250904141448.sql h1:J8cmYNk4ZrG9fhfbi2Z1IWz7YkfvhFqTzrLFo58BPY0= 20250908062237.sql h1:Pu23yEW/aKkwozHoOuROvHS/GK4ngARJGdO7FB7HZuI= @@ -141,4 +141,4 @@ h1:Gt8/vjlUshOzs/MWOnRZfDnDn2lrMZE4rcVk5k41R+Y= 20251202044430.sql h1:4QZH9lz0GrQ9rzP1AJ+hJgGalNpp+8FCRckNK7xaTbU= 20251202064000.sql h1:/EN7sT1ol/91qW1aXWrzX+Mc3XOC/7f/LtfA0JRHpbg= 20251202130629.sql h1:9mvalqfhqGCdkcJepJDzHprU2xb0i5sYys1Htf62ioo= -20251202160848.sql h1:TTy6DM7FI2+AyxY7mAFDEYVHE0484WKreRM4898rvOk= +20251202160848.sql h1:Kd2/TziKSMezrt4XgbjQcYvY/Lo9rX0qw7/Lz0/oyKk= diff --git a/internal/domain/references/organization/organization.go b/internal/domain/references/organization/organization.go index 0647f88f..d20b828e 100644 --- a/internal/domain/references/organization/organization.go +++ b/internal/domain/references/organization/organization.go @@ -54,8 +54,8 @@ const ( IFGCCounter InfraGroupCode = "counter" // Counter IFGCPubScreen InfraGroupCode = "public-screen" // Public Screen - PRTLight ProdcedureRoomTypeCode = "light" // Ringan - PRTSurgery ProdcedureRoomTypeCode = "roomed" // Dikamarkan + PRTCProcedure ProdcedureRoomTypeCode = "procedure" // Ringan + PRTCOperating ProdcedureRoomTypeCode = "operating" // Dikamarkan UTCReg UnitTypeCode = "reg" // Registrasi UTCExa UnitTypeCode = "exa" // Pemeriksaan From aa5a3d898a9f7367e94163ad71bc0fa03c8013fc Mon Sep 17 00:00:00 2001 From: Munawwirul Jamal Date: Tue, 2 Dec 2025 23:47:15 +0700 Subject: [PATCH 35/38] feat/order-things: adjust structure + tags --- .../migrations/20251202180207.sql | 2 ++ cmd/main-migration/migrations/atlas.sum | 3 ++- internal/domain/main-entities/infra/dto.go | 20 +++++++++---------- internal/domain/main-entities/infra/entity.go | 20 +++++++++---------- .../procedure-room-order/entity.go | 5 ++++- 5 files changed, 28 insertions(+), 22 deletions(-) create mode 100644 cmd/main-migration/migrations/20251202180207.sql diff --git a/cmd/main-migration/migrations/20251202180207.sql b/cmd/main-migration/migrations/20251202180207.sql new file mode 100644 index 00000000..32c5b1dc --- /dev/null +++ b/cmd/main-migration/migrations/20251202180207.sql @@ -0,0 +1,2 @@ +-- Modify "ProcedureRoomOrder" table +ALTER TABLE "public"."ProcedureRoomOrder" ADD COLUMN "Status_Code" character varying(20) NULL; diff --git a/cmd/main-migration/migrations/atlas.sum b/cmd/main-migration/migrations/atlas.sum index 72d356db..26c2bca0 100644 --- a/cmd/main-migration/migrations/atlas.sum +++ b/cmd/main-migration/migrations/atlas.sum @@ -1,4 +1,4 @@ -h1:2q1xxtaiHIoZtVnG80kXG6u4BZVgy44lTmW3zd6freo= +h1:fDxiVQJUurcI/J078Wz7tEKkfNwnI92Cs75Z34Eo9ZQ= 20250904105930.sql h1:MEM6blCgke9DzWQSTnLzasbPIrcHssNNrJqZpSkEo6k= 20250904141448.sql h1:J8cmYNk4ZrG9fhfbi2Z1IWz7YkfvhFqTzrLFo58BPY0= 20250908062237.sql h1:Pu23yEW/aKkwozHoOuROvHS/GK4ngARJGdO7FB7HZuI= @@ -142,3 +142,4 @@ h1:2q1xxtaiHIoZtVnG80kXG6u4BZVgy44lTmW3zd6freo= 20251202064000.sql h1:/EN7sT1ol/91qW1aXWrzX+Mc3XOC/7f/LtfA0JRHpbg= 20251202130629.sql h1:9mvalqfhqGCdkcJepJDzHprU2xb0i5sYys1Htf62ioo= 20251202160848.sql h1:Kd2/TziKSMezrt4XgbjQcYvY/Lo9rX0qw7/Lz0/oyKk= +20251202180207.sql h1:5WXemmJfgaV3BPuciiDhstKjjhSRCCxIxuPB8c7nc74= diff --git a/internal/domain/main-entities/infra/dto.go b/internal/domain/main-entities/infra/dto.go index f5cf5444..63c5d4a4 100644 --- a/internal/domain/main-entities/infra/dto.go +++ b/internal/domain/main-entities/infra/dto.go @@ -32,7 +32,7 @@ type ReadListDto struct { type FilterDto struct { Code string `json:"code"` Name string `json:"name"` - InfraGroup_Code ero.InfraGroupCode `json:"infraGroup-code"` + InfraGroup_Code ero.InfraGroupCode `json:"infra-group-code"` Parent_Code *string `json:"parent-code"` Item_Id *string `json:"item-code"` Search string `json:"search" gormhelper:"searchColumns=Code,Name"` @@ -62,15 +62,15 @@ type MetaDto struct { type ResponseDto struct { ecore.SmallMain - Code string `json:"code"` - Name string `json:"name"` - InfraGroup_Code ero.InfraGroupCode `json:"infraGroup_code"` - Parent_Code *string `json:"parent_code"` - Parent *Infra `json:"parent,omitempty"` - Childrens []Infra `json:"childrens,omitempty"` - Item_Code *string `json:"item_code"` - Item *ei.Item `json:"item,omitempty"` - ProcedureRooms []erb.ProcedureRoom `json:"rooms,omitempty"` + Code string `json:"code"` + Name string `json:"name"` + InfraGroup_Code ero.InfraGroupCode `json:"infraGroup_code"` + Parent_Code *string `json:"parent_code"` + Parent *Infra `json:"parent,omitempty"` + Childrens []Infra `json:"childrens,omitempty"` + Item_Code *string `json:"item_code"` + Item *ei.Item `json:"item,omitempty"` + ProcedureRooms *erb.ProcedureRoom `json:"rooms,omitempty"` } func (d Infra) ToResponse() ResponseDto { diff --git a/internal/domain/main-entities/infra/entity.go b/internal/domain/main-entities/infra/entity.go index 8fe5cb52..b9840db4 100644 --- a/internal/domain/main-entities/infra/entity.go +++ b/internal/domain/main-entities/infra/entity.go @@ -10,14 +10,14 @@ import ( ) type Infra struct { - ecore.SmallMain // adjust this according to the needs - Code string `json:"code" gorm:"uniqueIndex;size:20;not null"` - Name string `json:"name" gorm:"size:50"` - InfraGroup_Code ero.InfraGroupCode `json:"infraGroup_code" gorm:"size:20"` - Parent_Code *string `json:"parent_code" gorm:"size:20"` - Parent *Infra `json:"parent" gorm:"foreignKey:Parent_Code;references:Code"` - Childrens []Infra `json:"childrens" gorm:"foreignKey:Parent_Code;references:Code"` - Item_Code *string `json:"item_code" gorm:"size:50"` - Item *ei.Item `json:"item,omitempty" gorm:"foreignKey:Item_Code;references:Code"` - ProcedureRooms []erb.ProcedureRoom `json:"rooms" gorm:"foreignKey:Infra_Code;references:Code"` + ecore.SmallMain // adjust this according to the needs + Code string `json:"code" gorm:"uniqueIndex;size:20;not null"` + Name string `json:"name" gorm:"size:50"` + InfraGroup_Code ero.InfraGroupCode `json:"infraGroup_code" gorm:"size:20"` + Parent_Code *string `json:"parent_code" gorm:"size:20"` + Parent *Infra `json:"parent" gorm:"foreignKey:Parent_Code;references:Code"` + Childrens []Infra `json:"childrens" gorm:"foreignKey:Parent_Code;references:Code"` + Item_Code *string `json:"item_code" gorm:"size:50"` + Item *ei.Item `json:"item,omitempty" gorm:"foreignKey:Item_Code;references:Code"` + ProcedureRooms *erb.ProcedureRoom `json:"rooms" gorm:"foreignKey:Infra_Code;references:Code"` } diff --git a/internal/domain/main-entities/procedure-room-order/entity.go b/internal/domain/main-entities/procedure-room-order/entity.go index c0fb846e..7cb79120 100644 --- a/internal/domain/main-entities/procedure-room-order/entity.go +++ b/internal/domain/main-entities/procedure-room-order/entity.go @@ -1,6 +1,8 @@ package procedureroomorder import ( + erc "simrs-vx/internal/domain/references/common" + ecore "simrs-vx/internal/domain/base-entities/core" emp "simrs-vx/internal/domain/main-entities/material-package" epr "simrs-vx/internal/domain/main-entities/procedure-room" @@ -11,6 +13,7 @@ type ProcedureRoomOrder struct { Encounter_Id uint64 `json:"encounter_id"` Infra_Code string `json:"infra_code" gorm:"size:20"` ProcedureRoom *epr.ProcedureRoom `json:"procedureRoom,omitempty" gorm:"foreignKey:Infra_Code;references:Code"` - MaterialPackage_Code string `json:"materialPackageCode" gorm:"size:20"` + MaterialPackage_Code string `json:"materialPackage_code" gorm:"size:20"` MaterialPackage *emp.MaterialPackage `json:"materialPackage,omitempty" gorm:"foreignKey:MaterialPackage_Code;references:Code"` + Status_Code erc.DataStatusCode `json:"status_code" gorm:"size:20"` } From 9b8110f8fa95375254d49c83af1bf42cef9e96d0 Mon Sep 17 00:00:00 2001 From: Munawwirul Jamal Date: Wed, 3 Dec 2025 06:06:56 +0700 Subject: [PATCH 36/38] feat/order-things: entities adjustment --- .../material-package-item/dto.go | 3 + .../material-package-item/entity.go | 1 + .../procedure-room-order-item/dto.go | 68 +++++++++++++++++++ .../procedure-room-order-item/entity.go | 14 ++++ .../main-entities/procedure-room-order/dto.go | 38 ++++++----- .../procedure-room-order/entity.go | 2 +- 6 files changed, 108 insertions(+), 18 deletions(-) create mode 100644 internal/domain/main-entities/procedure-room-order-item/dto.go create mode 100644 internal/domain/main-entities/procedure-room-order-item/entity.go diff --git a/internal/domain/main-entities/material-package-item/dto.go b/internal/domain/main-entities/material-package-item/dto.go index fd282873..e642a015 100644 --- a/internal/domain/main-entities/material-package-item/dto.go +++ b/internal/domain/main-entities/material-package-item/dto.go @@ -9,6 +9,7 @@ import ( type CreateDto struct { MaterialPackage_Code string `json:"materialPackage_code" validate:"maxLength=20"` Material_Code string `json:"material_code" validate:"maxLength=20"` + Count uint16 `json:"count" validate:"required"` } type ReadListDto struct { @@ -48,6 +49,7 @@ type ResponseDto struct { MaterialPackage *emp.MaterialPackage `json:"materialPackage,omitempty"` Material_Code string `json:"material_code"` Material *em.Material `json:"material,omitempty"` + Count uint16 `json:"count"` } func (d MaterialPackageItem) ToResponse() ResponseDto { @@ -56,6 +58,7 @@ func (d MaterialPackageItem) ToResponse() ResponseDto { MaterialPackage: d.MaterialPackage, Material_Code: d.Material_Code, Material: d.Material, + Count: d.Count, } resp.Id = d.Id return resp diff --git a/internal/domain/main-entities/material-package-item/entity.go b/internal/domain/main-entities/material-package-item/entity.go index 76378dc8..52960935 100644 --- a/internal/domain/main-entities/material-package-item/entity.go +++ b/internal/domain/main-entities/material-package-item/entity.go @@ -12,4 +12,5 @@ type MaterialPackageItem struct { MaterialPackage *emp.MaterialPackage `json:"materialPackage" gorm:"foreignKey:MaterialPackage_Code;references:Code"` Material_Code string `json:"code" gorm:"size:20;not null"` Material *em.Material `json:"material" gorm:"foreignKey:Material_Code;references:Code"` + Count uint16 `json:"count" gorm:"not null"` } diff --git a/internal/domain/main-entities/procedure-room-order-item/dto.go b/internal/domain/main-entities/procedure-room-order-item/dto.go new file mode 100644 index 00000000..4e01fea9 --- /dev/null +++ b/internal/domain/main-entities/procedure-room-order-item/dto.go @@ -0,0 +1,68 @@ +package procedureroomorder + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + epr "simrs-vx/internal/domain/main-entities/procedure-room" +) + +type CreateDto struct { + Encounter_Id uint64 `json:"encounter_id" validate:"required"` + Infra_Code string `json:"infra_code" validate:"required"` + MaterialPackage_Code string `json:"materialPackage_code" validate:"required"` +} + +type ReadListDto struct { + FilterDto + Includes string `json:"includes"` + Pagination ecore.Pagination +} + +type FilterDto struct { + Encounter_Id uint64 `json:"encounter-id"` +} + +type ReadDetailDto struct { + Id uint64 `json:"id"` +} + +type UpdateDto struct { + Id uint64 `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint64 `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.BigMain + ProcedureRoomOrder_Id uint64 `json:"procedureRoomOrder_id"` + ProcedureRoom_Code string `json:"procedureRoom_code"` + ProcedureRoom *epr.ProcedureRoom `json:"procedureRoom,omitempty"` + Note string `json:"note"` +} + +func (d ProcedureRoomOrderItem) ToResponse() ResponseDto { + resp := ResponseDto{ + ProcedureRoomOrder_Id: d.ProcedureRoomOrder_Id, + ProcedureRoom_Code: d.ProcedureRoom_Code, + ProcedureRoom: d.ProcedureRoom, + Note: d.Note, + } + resp.Id = d.Id + return resp +} + +func ToResponseList(data []ProcedureRoomOrderItem) []ResponseDto { + resp := make([]ResponseDto, len(data)) + for i, u := range data { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/procedure-room-order-item/entity.go b/internal/domain/main-entities/procedure-room-order-item/entity.go new file mode 100644 index 00000000..4a737048 --- /dev/null +++ b/internal/domain/main-entities/procedure-room-order-item/entity.go @@ -0,0 +1,14 @@ +package procedureroomorder + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + epr "simrs-vx/internal/domain/main-entities/procedure-room" +) + +type ProcedureRoomOrderItem struct { + ecore.BigMain + ProcedureRoomOrder_Id uint64 `json:"procedureRoomOrder_id"` + ProcedureRoom_Code string `json:"procedureRoom_code" gorm:"size:20"` + ProcedureRoom *epr.ProcedureRoom `json:"procedureRoom,omitempty" gorm:"foreignKey:ProcedureRoom_Code;references:Code"` + Note string `json:"note" gorm:"size:255"` +} diff --git a/internal/domain/main-entities/procedure-room-order/dto.go b/internal/domain/main-entities/procedure-room-order/dto.go index d202f031..5810e756 100644 --- a/internal/domain/main-entities/procedure-room-order/dto.go +++ b/internal/domain/main-entities/procedure-room-order/dto.go @@ -3,13 +3,15 @@ package procedureroomorder import ( ecore "simrs-vx/internal/domain/base-entities/core" ec "simrs-vx/internal/domain/main-entities/encounter" + emp "simrs-vx/internal/domain/main-entities/material-package" epr "simrs-vx/internal/domain/main-entities/procedure-room" + erc "simrs-vx/internal/domain/references/common" ) type CreateDto struct { - Encounter_Id uint64 `json:"encounter_id"` - Infra_Code string `json:"procedure"` - ProcedureRoom string `json:"procedureRoom"` + Encounter_Id uint64 `json:"encounter_id" validate:"required"` + Infra_Code string `json:"infra_code" validate:"required"` + MaterialPackage_Code string `json:"materialPackage_code" validate:"required"` } type ReadListDto struct { @@ -19,22 +21,20 @@ type ReadListDto struct { } type FilterDto struct { - Encounter_Id uint64 `json:"encounter-id"` - Infra_Code string `json:"procedure-code"` - ProcedureRoom string `json:"procedure-room"` + Encounter_Id uint64 `json:"encounter-id"` } type ReadDetailDto struct { - Id uint `json:"id"` + Id uint64 `json:"id"` } type UpdateDto struct { - Id uint `json:"id"` + Id uint64 `json:"id"` CreateDto } type DeleteDto struct { - Id uint `json:"id"` + Id uint64 `json:"id"` } type MetaDto struct { @@ -44,18 +44,22 @@ type MetaDto struct { } type ResponseDto struct { - ecore.Main - Encounter_Id uint64 `json:"encounter_id"` - Encounter *ec.Encounter `json:"encounter,omitempty"` - Infra_Code string `json:"procedure"` - ProcedureRoom *epr.ProcedureRoom `json:"procedureRoom,omitempty"` + ecore.BigMain + Encounter_Id uint64 `json:"encounter_id"` + Encounter *ec.Encounter `json:"encounter,omitempty"` + Infra_Code string `json:"procedure"` + MaterialPackage_Code string `json:"materialPackage_code"` + Status_Code erc.DataStatusCode `json:"status_code"` + ProcedureRoom *epr.ProcedureRoom `json:"procedureRoom,omitempty"` + MaterialPackage *emp.MaterialPackage `json:"materialPackage,omitempty"` } func (d ProcedureRoomOrder) ToResponse() ResponseDto { resp := ResponseDto{ - Encounter_Id: d.Encounter_Id, - Infra_Code: d.Infra_Code, - // ProcedureRoom: d.ProcedureRoom, + Encounter_Id: d.Encounter_Id, + Infra_Code: d.Infra_Code, + MaterialPackage_Code: d.MaterialPackage_Code, + Status_Code: d.Status_Code, } resp.Id = d.Id return resp diff --git a/internal/domain/main-entities/procedure-room-order/entity.go b/internal/domain/main-entities/procedure-room-order/entity.go index 7cb79120..1ef7c178 100644 --- a/internal/domain/main-entities/procedure-room-order/entity.go +++ b/internal/domain/main-entities/procedure-room-order/entity.go @@ -9,7 +9,7 @@ import ( ) type ProcedureRoomOrder struct { - ecore.Main + ecore.BigMain Encounter_Id uint64 `json:"encounter_id"` Infra_Code string `json:"infra_code" gorm:"size:20"` ProcedureRoom *epr.ProcedureRoom `json:"procedureRoom,omitempty" gorm:"foreignKey:Infra_Code;references:Code"` From cc16b6f1cb5fe564aa71557a4d045dbd1aaa50dc Mon Sep 17 00:00:00 2001 From: dpurbosakti Date: Wed, 3 Dec 2025 10:19:36 +0700 Subject: [PATCH 37/38] add doctype screening --- internal/domain/references/encounter/encounter.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/domain/references/encounter/encounter.go b/internal/domain/references/encounter/encounter.go index 231baa9b..ad6abe05 100644 --- a/internal/domain/references/encounter/encounter.go +++ b/internal/domain/references/encounter/encounter.go @@ -123,6 +123,7 @@ const ( DTCGC DocTypeCode = "general-consent" DTCVSCL DocTypeCode = "vclaim-control-letter" // vclaim control letter DTCResume DocTypeCode = "resume" // Resume + DTCScreening DocTypeCode = "screening" // Screening ETCPerson EntityTypeCode = "person" ETCEncounter EntityTypeCode = "encounter" From da2bea83080eb67eea0c394c92674df71d3dbc71 Mon Sep 17 00:00:00 2001 From: vanilia Date: Wed, 3 Dec 2025 10:25:11 +0700 Subject: [PATCH 38/38] add t-rekammedik --- .../simgos-entities/t-rekammedik/entity.go | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 internal/domain/simgos-entities/t-rekammedik/entity.go diff --git a/internal/domain/simgos-entities/t-rekammedik/entity.go b/internal/domain/simgos-entities/t-rekammedik/entity.go new file mode 100644 index 00000000..5df0ec83 --- /dev/null +++ b/internal/domain/simgos-entities/t-rekammedik/entity.go @@ -0,0 +1,22 @@ +package t_rekammedik + +import "time" + +type TRekammedik struct { + TglKirim *time.Time `json:"tgl_kirim" gorm:"column:tgl_kirim"` + TglTerima *time.Time `json:"tgl_terima" gorm:"column:tgl_terima"` + Idxdaftar int `json:"idxdaftar" gorm:"column:idxdaftar"` + Kdpoly int `json:"kdpoly" gorm:"column:kdpoly"` + Pengirim string `json:"pengirim" gorm:"column:pengirim"` + Penerima string `json:"penerima" gorm:"column:penerima"` + Statusrm int `json:"statusrm" gorm:"column:statusrm"` + PenerimaPoly string `json:"penerima_poly" gorm:"column:penerima_poly"` + JamKirimRm string `json:"jam_kirim_rm" gorm:"column:jam_kirim_rm"` + JamTerimaRm string `json:"jam_terima_rm" gorm:"column:jam_terima_rm"` + PjBerkasRm string `json:"pj_berkas_rm" gorm:"column:pj_berkas_rm"` + StatusFisikBerkas string `json:"status_fisik_berkas" gorm:"column:status_fisik_berkas"` +} + +func (TRekammedik) TableName() string { + return "t_rekammedik" +}