diff --git a/.vscode/launch.json b/.vscode/launch.json
index fddb0d29..6969b05e 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -14,6 +14,20 @@
"mode": "auto",
"program": "${workspaceFolder}/cmd/bpjs-api"
},
+ {
+ "name": "Launch Package simgos sync API",
+ "type": "go",
+ "request": "launch",
+ "mode": "auto",
+ "program": "${workspaceFolder}/cmd/simgos-sync-api"
+ },
+ {
+ "name": "Launch Package main sync API",
+ "type": "go",
+ "request": "launch",
+ "mode": "auto",
+ "program": "${workspaceFolder}/cmd/main-sync-api"
+ },
{
"name": "Launch Package migratioon",
"type": "go",
diff --git a/README-APP.md b/README-APP.md
index 4da56232..4a63384d 100644
--- a/README-APP.md
+++ b/README-APP.md
@@ -1,4 +1,16 @@
# APP DESIGN CONVENTION
+## Intro
+Uses Go Programming Language, with no framework.
+- Why no framework? Go's std libs are already powerfull which aligns with the philosophy of "do one thing well"
+- It's common in the Go community that "No framework is the best framework"
+
+Uses community standard layout for the project layout, can be viewed here:
+https://github.com/golang-standards/project-layout
+
+Uses Clean Architecture (later writen as CA) approach, can be viewed here:
+https://www.freecodecamp.org/news/a-quick-introduction-to-clean-architecture-990c014448d2
+
+Uses kebab-case for the directory naming
## Implementing Clean Architecture (later called CA) in the layout
1. The CA can be implemented simply by using directory structures to represent the layers
diff --git a/cmd/main-sync-api/config.yml-example b/cmd/main-sync-api/config.yml-example
new file mode 100644
index 00000000..edb5c84b
--- /dev/null
+++ b/cmd/main-sync-api/config.yml-example
@@ -0,0 +1,41 @@
+appCfg:
+ fullName: SIMRS Sync
+ codeName: simrs-sync
+ version: 0.1.0
+ env: development
+ lang: en
+
+dbCfg:
+ dsn:
+ maxOpenConns: 5
+ maxIdleConns: 5
+ maxIdleTime: 100
+
+multiDbCfg:
+ dbs :
+ - name: simrs_sync
+ dsn:
+ maxOpenConns: 5
+ maxIdleConns: 5
+ maxIdleTime: 100
+
+httpCfg:
+ host: 127.0.0.1
+ port: 8003
+
+loggerCfg:
+ hideTime: true
+ hideLevel: true
+
+langCfg:
+ active: en
+ path: ../../assets/language/en
+ fileName: data.json
+
+corsCfg:
+ allowedOrigin:
+ allowedMethod: GET, POST, PUT, PATCH, DELETE, OPTIONS
+
+syncUrlCfg:
+ target:
+ host:
\ No newline at end of file
diff --git a/cmd/main-sync-api/main.go b/cmd/main-sync-api/main.go
new file mode 100644
index 00000000..5bfdd36b
--- /dev/null
+++ b/cmd/main-sync-api/main.go
@@ -0,0 +1,15 @@
+package main
+
+import (
+ a "github.com/karincake/apem"
+
+ h "simrs-vx/internal/interface/main-sync-handler"
+
+ d "github.com/karincake/apem/db-gorm-pg"
+
+ l "github.com/karincake/apem/logger-zerolog"
+)
+
+func main() {
+ a.Run(h.SetRoutes(), &l.O, &d.O)
+}
diff --git a/cmd/simgos-sync-api/config.yml-example b/cmd/simgos-sync-api/config.yml-example
new file mode 100644
index 00000000..153be50e
--- /dev/null
+++ b/cmd/simgos-sync-api/config.yml-example
@@ -0,0 +1,41 @@
+appCfg:
+ fullName: SIMRS Sync
+ codeName: simrs-sync
+ version: 0.1.0
+ env: development
+ lang: en
+
+dbCfg:
+ dsn:
+ maxOpenConns: 5
+ maxIdleConns: 5
+ maxIdleTime: 100
+
+multiDbCfg:
+ dbs :
+ - name: simrs_sync
+ dsn:
+ maxOpenConns: 5
+ maxIdleConns: 5
+ maxIdleTime: 100
+
+httpCfg:
+ host: 127.0.0.1
+ port: 8002
+
+loggerCfg:
+ hideTime: true
+ hideLevel: true
+
+langCfg:
+ active: en
+ path: ../../assets/language/en
+ fileName: data.json
+
+corsCfg:
+ allowedOrigin:
+ allowedMethod: GET, POST, PUT, PATCH, DELETE, OPTIONS
+
+syncUrlCfg:
+ target:
+ host:
\ No newline at end of file
diff --git a/cmd/simgos-sync-api/main.go b/cmd/simgos-sync-api/main.go
new file mode 100644
index 00000000..ddb3897d
--- /dev/null
+++ b/cmd/simgos-sync-api/main.go
@@ -0,0 +1,15 @@
+package main
+
+import (
+ a "github.com/karincake/apem"
+
+ h "simrs-vx/internal/interface/simgos-sync-handler"
+
+ d "github.com/karincake/apem/db-gorm-pg"
+
+ l "github.com/karincake/apem/logger-zerolog"
+)
+
+func main() {
+ a.Run(h.SetRoutes(), &l.O, &d.O)
+}
diff --git a/internal/domain/main-entities/death-cause/dto.go b/internal/domain/main-entities/death-cause/dto.go
new file mode 100644
index 00000000..8781ace8
--- /dev/null
+++ b/internal/domain/main-entities/death-cause/dto.go
@@ -0,0 +1,62 @@
+package death_cause
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+)
+
+type CreateDto struct {
+ Encounter_Id *uint `json:"-"`
+ Value *string `json:"value"`
+}
+
+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 *uint `json:"encounter_id"`
+ Value *string `json:"value"`
+}
+
+func (d DeathCause) ToResponse() ResponseDto {
+ resp := ResponseDto{
+ Encounter_Id: d.Encounter_Id,
+ Value: d.Value,
+ }
+ resp.Main = d.Main
+ return resp
+}
+
+func ToResponseList(data []DeathCause) []ResponseDto {
+ resp := make([]ResponseDto, len(data))
+ for i, u := range data {
+ resp[i] = u.ToResponse()
+ }
+ return resp
+}
diff --git a/internal/domain/main-entities/division/dto.go b/internal/domain/main-entities/division/dto.go
index 95ea9119..38915b56 100644
--- a/internal/domain/main-entities/division/dto.go
+++ b/internal/domain/main-entities/division/dto.go
@@ -2,6 +2,7 @@ package division
import (
ecore "simrs-vx/internal/domain/base-entities/core"
+ edpb "simrs-vx/internal/domain/main-entities/division-position/base"
)
type CreateDto struct {
@@ -26,8 +27,9 @@ type FilterDto struct {
}
type ReadDetailDto struct {
- Id uint16 `json:"id"`
- Code *string `json:"code"`
+ Id uint16 `json:"id"`
+ Code *string `json:"code"`
+ Includes string `json:"includes"`
}
type UpdateDto struct {
@@ -47,20 +49,22 @@ type MetaDto struct {
type ResponseDto struct {
ecore.SmallMain
- Code string `json:"code"`
- Name string `json:"name"`
- Parent_Id *uint16 `json:"parent_id"`
- Parent *Division `json:"parent,omitempty"`
- Childrens []Division `json:"childrens,omitempty"`
+ Code string `json:"code"`
+ Name string `json:"name"`
+ Parent_Id *uint16 `json:"parent_id"`
+ Parent *Division `json:"parent,omitempty"`
+ Childrens []Division `json:"childrens,omitempty"`
+ DivisionPosition []edpb.Basic `json:"divisionPositions,omitempty"`
}
func (d Division) ToResponse() ResponseDto {
resp := ResponseDto{
- Code: d.Code,
- Name: d.Name,
- Parent_Id: d.Parent_Id,
- Parent: d.Parent,
- Childrens: d.Childrens,
+ Code: d.Code,
+ Name: d.Name,
+ Parent_Id: d.Parent_Id,
+ Parent: d.Parent,
+ Childrens: d.Childrens,
+ DivisionPosition: d.DivisionPositions,
}
resp.SmallMain = d.SmallMain
return resp
diff --git a/internal/domain/main-entities/doctor/dto.go b/internal/domain/main-entities/doctor/dto.go
index 62d5f5b4..0abcd99b 100644
--- a/internal/domain/main-entities/doctor/dto.go
+++ b/internal/domain/main-entities/doctor/dto.go
@@ -9,6 +9,7 @@ import (
)
type CreateDto struct {
+ Code *string `json:"code" validate:"maxLength=20"`
Employee_Id *uint `json:"employee_id"`
IHS_Number *string `json:"ihs_number"`
SIP_Number *string `json:"sip_number"`
@@ -24,6 +25,7 @@ type ReadListDto struct {
}
type FilterDto struct {
+ Code *string `json:"code"`
Employee_Id *uint `json:"employee-id"`
IHS_Number *string `json:"ihs-number" validate:"maxLength=20"`
SIP_Number *string `json:"sip-number" validate:"maxLength=20"`
@@ -34,6 +36,7 @@ type FilterDto struct {
type ReadDetailDto struct {
Id uint16 `json:"id"`
+ Code *string `json:"code"`
Employee_Id *uint `json:"employee_id"`
IHS_Number *string `json:"ihs_number"`
SIP_Number *string `json:"sip_number"`
@@ -56,6 +59,7 @@ type MetaDto struct {
type ResponseDto struct {
ecore.Main
+ Code *string `json:"code"`
Employee_Id *uint `json:"employee_id"`
Employee *ee.Employee `json:"employee,omitempty"`
IHS_Number *string `json:"ihs_number"`
@@ -70,6 +74,7 @@ type ResponseDto struct {
func (d Doctor) ToResponse() ResponseDto {
resp := ResponseDto{
+ Code: d.Code,
Employee_Id: d.Employee_Id,
Employee: d.Employee,
IHS_Number: d.IHS_Number,
diff --git a/internal/domain/main-entities/edu-assessment/dto.go b/internal/domain/main-entities/edu-assessment/dto.go
new file mode 100644
index 00000000..d476dd1a
--- /dev/null
+++ b/internal/domain/main-entities/edu-assessment/dto.go
@@ -0,0 +1,75 @@
+package edu_assessment
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ee "simrs-vx/internal/domain/main-entities/encounter"
+)
+
+type CreateDto struct {
+ Encounter_Id *uint `json:"encounter_id" validate:"required"`
+ GeneralEdus *string `json:"generalEdus"`
+ SpecialEdus *string `json:"specialEdus"`
+ Assessments *string `json:"assessments" validate:"required"`
+ Plan *string `json:"plan" validate:"required"`
+}
+
+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"`
+ Includes string `json:"includes"`
+}
+
+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" gorm:"not null"`
+ Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"`
+ GeneralEdus *string `json:"generalEdus"`
+ SpecialEdus *string `json:"specialEdus"`
+ Assessments *string `json:"assessments"`
+ Plan *string `json:"plan"`
+}
+
+func (d EduAssessment) ToResponse() ResponseDto {
+ resp := ResponseDto{
+ Encounter_Id: d.Encounter_Id,
+ Encounter: d.Encounter,
+ GeneralEdus: d.GeneralEdus,
+ SpecialEdus: d.SpecialEdus,
+ Assessments: d.Assessments,
+ Plan: d.Plan,
+ }
+ resp.Main = d.Main
+ return resp
+}
+
+func ToResponseList(data []EduAssessment) []ResponseDto {
+ resp := make([]ResponseDto, len(data))
+ for i, u := range data {
+ resp[i] = u.ToResponse()
+ }
+ return resp
+}
diff --git a/internal/domain/main-entities/employee/dto.go b/internal/domain/main-entities/employee/dto.go
index d11ccae0..85b7008a 100644
--- a/internal/domain/main-entities/employee/dto.go
+++ b/internal/domain/main-entities/employee/dto.go
@@ -6,13 +6,15 @@ import (
eu "simrs-vx/internal/domain/main-entities/user"
erc "simrs-vx/internal/domain/references/common"
+ erg "simrs-vx/internal/domain/references/organization"
)
type CreateDto struct {
- User_Id *uint `json:"user_id"`
- Person_Id *uint `json:"person_id"`
- Number *string `json:"number" validate:"maxLength=20"`
- Status_Code erc.ActiveStatusCode `json:"status_code" validate:"maxLength=10"`
+ User_Id *uint `json:"user_id"`
+ Person_Id *uint `json:"person_id"`
+ Number *string `json:"number" validate:"maxLength=20"`
+ Status_Code erc.ActiveStatusCode `json:"status_code" validate:"maxLength=10"`
+ Position_Code *erg.EmployeePositionCode `json:"position_code"`
}
type ReadListDto struct {
diff --git a/internal/domain/main-entities/encounter/dto.go b/internal/domain/main-entities/encounter/dto.go
index fe725b16..4a30281d 100644
--- a/internal/domain/main-entities/encounter/dto.go
+++ b/internal/domain/main-entities/encounter/dto.go
@@ -8,6 +8,7 @@ import (
ea "simrs-vx/internal/domain/main-entities/appointment"
ed "simrs-vx/internal/domain/main-entities/doctor"
ee "simrs-vx/internal/domain/main-entities/employee"
+ eir "simrs-vx/internal/domain/main-entities/internal-reference"
ep "simrs-vx/internal/domain/main-entities/patient"
es "simrs-vx/internal/domain/main-entities/specialist"
ess "simrs-vx/internal/domain/main-entities/subspecialist"
@@ -95,11 +96,13 @@ type MetaDto struct {
}
type DischargeDto struct {
Id uint `json:"id"`
- DischargeMethod_Code *ere.DischargeMethodCode `json:"dischargeMethod_code" validate:"maxLength=16"`
+ Discharge_Method_Code *ere.DischargeMethodCode `json:"discharge_method_code" validate:"maxLength=16"`
EarlyEducation *string `json:"earlyEducation"`
MedicalDischargeEducation *string `json:"medicalDischargeEducation"`
AdmDischargeEducation *string `json:"admDischargeEducation"`
DischargeReason *string `json:"dischargeReason"`
+ DeathCause *string `json:"deathCause"`
+ InternalReferences *[]eir.CreateDto `json:"internalReferences,omitempty"`
}
type ResponseDto struct {
diff --git a/internal/domain/main-entities/installation-position/dto.go b/internal/domain/main-entities/installation-position/dto.go
new file mode 100644
index 00000000..aada7443
--- /dev/null
+++ b/internal/domain/main-entities/installation-position/dto.go
@@ -0,0 +1,84 @@
+package installation_position
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ee "simrs-vx/internal/domain/main-entities/employee"
+ ei "simrs-vx/internal/domain/main-entities/installation"
+)
+
+type CreateDto struct {
+ Installation_Id *uint16 `json:"installation_id" validate:"required"`
+ Code string `json:"code" validate:"maxLength=10;required"`
+ Name string `json:"name" validate:"maxLength=30;required"`
+ HeadStatus bool `json:"headStatus"`
+ Employee_Id *uint `json:"employee_id"`
+}
+
+type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Sort string `json:"sort"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ Installation_Id *uint16 `json:"installation-id"`
+ Code string `json:"code"`
+ Name string `json:"name"`
+ HeadStatus *bool `json:"head-status"`
+ Employee_Id *uint `json:"employee-id"`
+ Search string `json:"search" gormhelper:"searchColumns=Code,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"`
+}
+
+type MetaDto struct {
+ PageNumber int `json:"page_number"`
+ PageSize int `json:"page_size"`
+ Count int `json:"count"`
+}
+
+type ResponseDto struct {
+ ecore.SmallMain
+ Installation_Id *uint16 `json:"installation_id"`
+ Installation *ei.Installation `json:"installation,omitempty"`
+ Code string `json:"code"`
+ Name string `json:"name"`
+ HeadStatus bool `json:"headStatus"`
+ Employee_Id *uint `json:"employee_id"`
+ Employee *ee.Employee `json:"employee,omitempty"`
+}
+
+func (d InstallationPosition) ToResponse() ResponseDto {
+ resp := ResponseDto{
+ Installation_Id: d.Installation_Id,
+ Installation: d.Installation,
+ Code: d.Code,
+ Name: d.Name,
+ HeadStatus: d.HeadStatus,
+ Employee_Id: d.Employee_Id,
+ Employee: d.Employee,
+ }
+ resp.SmallMain = d.SmallMain
+ return resp
+}
+
+func ToResponseList(data []InstallationPosition) []ResponseDto {
+ resp := make([]ResponseDto, len(data))
+ for i, u := range data {
+ resp[i] = u.ToResponse()
+ }
+ return resp
+}
diff --git a/internal/domain/main-entities/installation/dto.go b/internal/domain/main-entities/installation/dto.go
index 55981981..302025d8 100644
--- a/internal/domain/main-entities/installation/dto.go
+++ b/internal/domain/main-entities/installation/dto.go
@@ -2,6 +2,7 @@ package installation
import (
ecore "simrs-vx/internal/domain/base-entities/core"
+ eipb "simrs-vx/internal/domain/main-entities/installation-position/base"
ere "simrs-vx/internal/domain/references/encounter"
)
@@ -27,8 +28,9 @@ type FilterDto struct {
}
type ReadDetailDto struct {
- Id uint16 `json:"id"`
- Code *string `json:"code"`
+ Id uint16 `json:"id"`
+ Code *string `json:"code"`
+ Includes string `json:"includes"`
}
type UpdateDto struct {
@@ -48,16 +50,18 @@ type MetaDto struct {
type ResponseDto struct {
ecore.SmallMain
- Code string `json:"code"`
- Name string `json:"name"`
- EncounterClass_Code ere.EncounterClassCode `json:"encounterClass_code"`
+ Code string `json:"code"`
+ Name string `json:"name"`
+ EncounterClass_Code ere.EncounterClassCode `json:"encounterClass_code"`
+ InstallationPositions []eipb.Basic `json:"installationPositions,omitempty"`
}
func (d Installation) ToResponse() ResponseDto {
resp := ResponseDto{
- Code: d.Code,
- Name: d.Name,
- EncounterClass_Code: d.EncounterClass_Code,
+ Code: d.Code,
+ Name: d.Name,
+ EncounterClass_Code: d.EncounterClass_Code,
+ InstallationPositions: d.InstallationPositions,
}
resp.SmallMain = d.SmallMain
return resp
diff --git a/internal/domain/main-entities/laborant/dto.go b/internal/domain/main-entities/laborant/dto.go
index 4397d2f1..e5fdb550 100644
--- a/internal/domain/main-entities/laborant/dto.go
+++ b/internal/domain/main-entities/laborant/dto.go
@@ -6,6 +6,7 @@ import (
)
type CreateDto struct {
+ Code *string `json:"code" validate:"maxLength=20"`
Employee_Id *uint `json:"employee_id"`
IHS_Number *string `json:"ihs_number" validate:"maxLength=20"`
}
@@ -17,12 +18,14 @@ type ReadListDto struct {
}
type FilterDto struct {
+ Code *string `json:"code"`
Employee_Id *uint `json:"employee-id"`
IHS_Number *string `json:"ihs-number"`
}
type ReadDetailDto struct {
Id uint16 `json:"id"`
+ Code *string `json:"code"`
Employee_Id *uint `json:"employee_id"`
IHS_Number *string `json:"ihs_number"`
}
@@ -44,6 +47,7 @@ type MetaDto struct {
type ResponseDto struct {
ecore.Main
+ Code *string `json:"code"`
Employee_Id *uint `json:"employee_id"`
Employee *ee.Employee `json:"employee,omitempty"`
IHS_Number *string `json:"ihs_number"`
@@ -51,6 +55,7 @@ type ResponseDto struct {
func (d Laborant) ToResponse() ResponseDto {
resp := ResponseDto{
+ Code: d.Code,
Employee_Id: d.Employee_Id,
Employee: d.Employee,
IHS_Number: d.IHS_Number,
diff --git a/internal/domain/main-entities/midwife/dto.go b/internal/domain/main-entities/midwife/dto.go
index d1adfdaf..ed01a36b 100644
--- a/internal/domain/main-entities/midwife/dto.go
+++ b/internal/domain/main-entities/midwife/dto.go
@@ -6,6 +6,7 @@ import (
)
type CreateDto struct {
+ Code *string `json:"code" validate:"maxLength=20"`
Employee_Id *uint `json:"employee_id"`
IHS_Number *string `json:"ihs_number" validate:"maxLength=20"`
}
@@ -17,12 +18,14 @@ type ReadListDto struct {
}
type FilterDto struct {
+ Code *string `json:"code"`
Employee_Id *uint `json:"employee_id"`
IHS_Number *string `json:"ihs_number"`
}
type ReadDetailDto struct {
Id uint16 `json:"id"`
+ Code *string `json:"code"`
Employee_Id *uint `json:"employee_id"`
IHS_Number *string `json:"ihs_number"`
}
@@ -44,6 +47,7 @@ type MetaDto struct {
type ResponseDto struct {
ecore.Main
+ Code *string `json:"code"`
Employee_Id *uint `json:"employee_id"`
Employee *ee.Employee `json:"employee,omitempty"`
IHS_Number *string `json:"ihs_number"`
@@ -51,6 +55,7 @@ type ResponseDto struct {
func (d Midwife) ToResponse() ResponseDto {
resp := ResponseDto{
+ Code: d.Code,
Employee_Id: d.Employee_Id,
Employee: d.Employee,
IHS_Number: d.IHS_Number,
diff --git a/internal/domain/main-entities/nurse/dto.go b/internal/domain/main-entities/nurse/dto.go
index 1707f212..7b7b283c 100644
--- a/internal/domain/main-entities/nurse/dto.go
+++ b/internal/domain/main-entities/nurse/dto.go
@@ -8,6 +8,7 @@ import (
)
type CreateDto struct {
+ Code *string `json:"code" validate:"maxLength=20"`
Employee_Id *uint `json:"employee_id"`
IHS_Number *string `json:"ihs_number" validate:"maxLength=20"`
Unit_Id *uint16 `json:"unit_id"`
@@ -21,6 +22,7 @@ type ReadListDto struct {
}
type FilterDto struct {
+ Code *string `json:"code"`
Employee_Id *uint `json:"employee-id"`
IHS_Number *string `json:"ihs-number"`
Unit_Id *uint16 `json:"unit-id"`
@@ -28,6 +30,7 @@ type FilterDto struct {
}
type ReadDetailDto struct {
Id uint16 `json:"id"`
+ Code *string `json:"code"`
Employee_Id *uint `json:"employee_id"`
IHS_Number *string `json:"ihs_number"`
}
@@ -49,6 +52,7 @@ type MetaDto struct {
type ResponseDto struct {
ecore.Main
+ Code *string `json:"code"`
Employee_Id *uint `json:"employee_id"`
Employee *ee.Employee `json:"employee,omitempty"`
IHS_Number *string `json:"ihs_number"`
@@ -60,6 +64,7 @@ type ResponseDto struct {
func (d Nurse) ToResponse() ResponseDto {
resp := ResponseDto{
+ Code: d.Code,
Employee_Id: d.Employee_Id,
Employee: d.Employee,
IHS_Number: d.IHS_Number,
diff --git a/internal/domain/main-entities/nutritionist/dto.go b/internal/domain/main-entities/nutritionist/dto.go
index df6365bf..832d6873 100644
--- a/internal/domain/main-entities/nutritionist/dto.go
+++ b/internal/domain/main-entities/nutritionist/dto.go
@@ -6,6 +6,7 @@ import (
)
type CreateDto struct {
+ Code *string `json:"code" validate:"maxLength=20"`
Employee_Id *uint `json:"employee_id"`
IHS_Number *string `json:"ihs_number" validate:"maxLength=20"`
}
@@ -17,12 +18,14 @@ type ReadListDto struct {
}
type FilterDto struct {
+ Code *string `json:"code"`
Employee_Id *uint `json:"employee-id"`
IHS_Number *string `json:"ihs-number"`
}
type ReadDetailDto struct {
Id uint16 `json:"id"`
+ Code *string `json:"code"`
Employee_Id *uint `json:"employee_id"`
IHS_Number *string `json:"ihs_number"`
}
@@ -44,6 +47,7 @@ type MetaDto struct {
type ResponseDto struct {
ecore.Main
+ Code *string `json:"code"`
Employee_Id *uint `json:"employee_id"`
Employee *ee.Employee `json:"employee,omitempty"`
IHS_Number *string `json:"ihs_number"`
@@ -51,6 +55,7 @@ type ResponseDto struct {
func (d Nutritionist) ToResponse() ResponseDto {
resp := ResponseDto{
+ Code: d.Code,
Employee_Id: d.Employee_Id,
Employee: d.Employee,
IHS_Number: d.IHS_Number,
diff --git a/internal/domain/main-entities/patient/dto.go b/internal/domain/main-entities/patient/dto.go
index 00134b6e..4927a50e 100644
--- a/internal/domain/main-entities/patient/dto.go
+++ b/internal/domain/main-entities/patient/dto.go
@@ -57,8 +57,8 @@ type DeleteDto struct {
}
type SearchDto struct {
- Search string `json:"search"`
- Mode SearchMode `json:"mode"`
+ Search string `json:"search"`
+ Pagination ecore.Pagination
}
type UploadDto struct {
diff --git a/internal/domain/main-entities/pharmacist/dto.go b/internal/domain/main-entities/pharmacist/dto.go
index 4a04f8d2..ded53ac8 100644
--- a/internal/domain/main-entities/pharmacist/dto.go
+++ b/internal/domain/main-entities/pharmacist/dto.go
@@ -6,6 +6,7 @@ import (
)
type CreateDto struct {
+ Code *string `json:"code" validate:"maxLength=20"`
Employee_Id *uint `json:"employee_id"`
IHS_Number *string `json:"ihs_number" validate:"maxLength=20"`
}
@@ -17,12 +18,14 @@ type ReadListDto struct {
}
type FilterDto struct {
+ Code *string `json:"code"`
Employee_Id *uint `json:"employee-id"`
IHS_Number *string `json:"ihs-number"`
}
type ReadDetailDto struct {
Id uint16 `json:"id"`
+ Code *string `json:"code"`
Employee_Id *uint `json:"employee_id"`
IHS_Number *string `json:"ihs_number"`
}
@@ -44,6 +47,7 @@ type MetaDto struct {
type ResponseDto struct {
ecore.Main
+ Code *string `json:"code"`
Employee_Id *uint `json:"employee_id"`
Employee *ee.Employee `json:"employee,omitempty"`
IHS_Number *string `json:"ihs_number"`
@@ -51,6 +55,7 @@ type ResponseDto struct {
func (d Pharmacist) ToResponse() ResponseDto {
resp := ResponseDto{
+ Code: d.Code,
Employee_Id: d.Employee_Id,
Employee: d.Employee,
IHS_Number: d.IHS_Number,
diff --git a/internal/domain/main-entities/specialist-position/dto.go b/internal/domain/main-entities/specialist-position/dto.go
new file mode 100644
index 00000000..0641fb12
--- /dev/null
+++ b/internal/domain/main-entities/specialist-position/dto.go
@@ -0,0 +1,84 @@
+package specialist_position
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ee "simrs-vx/internal/domain/main-entities/employee"
+ es "simrs-vx/internal/domain/main-entities/specialist"
+)
+
+type CreateDto struct {
+ Specialist_Id *uint16 `json:"specialist_id" validate:"required"`
+ Code string `json:"code" validate:"maxLength=10;required"`
+ Name string `json:"name" validate:"maxLength=30;required"`
+ HeadStatus bool `json:"headStatus"`
+ Employee_Id *uint `json:"employee_id"`
+}
+
+type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Sort string `json:"sort"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ Specialist_Id *uint16 `json:"specialist-id"`
+ Code string `json:"code"`
+ Name string `json:"name"`
+ HeadStatus *bool `json:"head-status"`
+ Employee_Id *uint `json:"employee-id"`
+ Search string `json:"search" gormhelper:"searchColumns=Code,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"`
+}
+
+type MetaDto struct {
+ PageNumber int `json:"page_number"`
+ PageSize int `json:"page_size"`
+ Count int `json:"count"`
+}
+
+type ResponseDto struct {
+ ecore.SmallMain
+ Specialist_Id *uint16 `json:"specialist_id"`
+ Specialist *es.Specialist `json:"specialist,omitempty"`
+ Code string `json:"code"`
+ Name string `json:"name"`
+ HeadStatus bool `json:"headStatus"`
+ Employee_Id *uint `json:"employee_id"`
+ Employee *ee.Employee `json:"employee,omitempty"`
+}
+
+func (d SpecialistPosition) ToResponse() ResponseDto {
+ resp := ResponseDto{
+ Specialist_Id: d.Specialist_Id,
+ Specialist: d.Specialist,
+ Code: d.Code,
+ Name: d.Name,
+ HeadStatus: d.HeadStatus,
+ Employee_Id: d.Employee_Id,
+ Employee: d.Employee,
+ }
+ resp.SmallMain = d.SmallMain
+ return resp
+}
+
+func ToResponseList(data []SpecialistPosition) []ResponseDto {
+ resp := make([]ResponseDto, len(data))
+ for i, u := range data {
+ resp[i] = u.ToResponse()
+ }
+ return resp
+}
diff --git a/internal/domain/main-entities/specialist/dto.go b/internal/domain/main-entities/specialist/dto.go
index f1338c19..3fa6bf5e 100644
--- a/internal/domain/main-entities/specialist/dto.go
+++ b/internal/domain/main-entities/specialist/dto.go
@@ -2,6 +2,7 @@ package specialist
import (
ecore "simrs-vx/internal/domain/base-entities/core"
+ espb "simrs-vx/internal/domain/main-entities/specialist-position/base"
)
type CreateDto struct {
@@ -25,8 +26,9 @@ type FilterDto struct {
}
type ReadDetailDto struct {
- Id uint16 `json:"id"`
- Code *string `json:"code"`
+ Id uint16 `json:"id"`
+ Code *string `json:"code"`
+ Includes string `json:"includes"`
}
type UpdateDto struct {
@@ -46,16 +48,18 @@ type MetaDto struct {
type ResponseDto struct {
ecore.SmallMain
- Code string `json:"code"`
- Name string `json:"name"`
- Unit_Id *uint16 `json:"unit_id"`
+ Code string `json:"code"`
+ Name string `json:"name"`
+ Unit_Id *uint16 `json:"unit_id"`
+ SpecialistPositions []espb.Basic `json:"specialistPositions,omitempty"`
}
func (d Specialist) ToResponse() ResponseDto {
resp := ResponseDto{
- Code: d.Code,
- Name: d.Name,
- Unit_Id: d.Unit_Id,
+ Code: d.Code,
+ Name: d.Name,
+ Unit_Id: d.Unit_Id,
+ SpecialistPositions: d.SpecialistPositions,
}
resp.SmallMain = d.SmallMain
return resp
diff --git a/internal/domain/main-entities/subspecialist-position/dto.go b/internal/domain/main-entities/subspecialist-position/dto.go
new file mode 100644
index 00000000..3c65841e
--- /dev/null
+++ b/internal/domain/main-entities/subspecialist-position/dto.go
@@ -0,0 +1,84 @@
+package subspecialist_position
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ee "simrs-vx/internal/domain/main-entities/employee"
+ es "simrs-vx/internal/domain/main-entities/subspecialist"
+)
+
+type CreateDto struct {
+ Subspecialist_Id *uint16 `json:"subspecialist_id" validate:"required"`
+ Code string `json:"code" validate:"maxLength=10;required"`
+ Name string `json:"name" validate:"maxLength=30;required"`
+ HeadStatus bool `json:"headStatus"`
+ Employee_Id *uint `json:"employee_id"`
+}
+
+type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Sort string `json:"sort"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ Subspecialist_Id *uint16 `json:"subspecialist-id"`
+ Code string `json:"code"`
+ Name string `json:"name"`
+ HeadStatus *bool `json:"head-status"`
+ Employee_Id *uint `json:"employee-id"`
+ Search string `json:"search" gormhelper:"searchColumns=Code,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"`
+}
+
+type MetaDto struct {
+ PageNumber int `json:"page_number"`
+ PageSize int `json:"page_size"`
+ Count int `json:"count"`
+}
+
+type ResponseDto struct {
+ ecore.SmallMain
+ Subspecialist_Id *uint16 `json:"subspecialist_id"`
+ Subspecialist *es.Subspecialist `json:"subspecialist,omitempty"`
+ Code string `json:"code"`
+ Name string `json:"name"`
+ HeadStatus bool `json:"headStatus"`
+ Employee_Id *uint `json:"employee_id"`
+ Employee *ee.Employee `json:"employee,omitempty"`
+}
+
+func (d SubspecialistPosition) ToResponse() ResponseDto {
+ resp := ResponseDto{
+ Subspecialist_Id: d.Subspecialist_Id,
+ Subspecialist: d.Subspecialist,
+ Code: d.Code,
+ Name: d.Name,
+ HeadStatus: d.HeadStatus,
+ Employee_Id: d.Employee_Id,
+ Employee: d.Employee,
+ }
+ resp.SmallMain = d.SmallMain
+ return resp
+}
+
+func ToResponseList(data []SubspecialistPosition) []ResponseDto {
+ resp := make([]ResponseDto, len(data))
+ for i, u := range data {
+ resp[i] = u.ToResponse()
+ }
+ return resp
+}
diff --git a/internal/domain/main-entities/subspecialist/dto.go b/internal/domain/main-entities/subspecialist/dto.go
index e28f96ae..ed0c97aa 100644
--- a/internal/domain/main-entities/subspecialist/dto.go
+++ b/internal/domain/main-entities/subspecialist/dto.go
@@ -2,6 +2,7 @@ package subspecialist
import (
ecore "simrs-vx/internal/domain/base-entities/core"
+ espb "simrs-vx/internal/domain/main-entities/subspecialist-position/base"
)
type CreateDto struct {
@@ -25,8 +26,9 @@ type FilterDto struct {
}
type ReadDetailDto struct {
- Id uint16 `json:"id"`
- Code *string `json:"code"`
+ Id uint16 `json:"id"`
+ Code *string `json:"code"`
+ Includes string `json:"includes"`
}
type UpdateDto struct {
@@ -46,9 +48,10 @@ type MetaDto struct {
type ResponseDto struct {
ecore.SmallMain
- Code string `json:"code"`
- Name string `json:"name"`
- Specialist_Id *uint16 `json:"specialist_id"`
+ Code string `json:"code"`
+ Name string `json:"name"`
+ Specialist_Id *uint16 `json:"specialist_id"`
+ Subspecialist []espb.Basic `json:"subspecialistPositions,omitempty"`
}
func (d Subspecialist) ToResponse() ResponseDto {
@@ -56,6 +59,7 @@ func (d Subspecialist) ToResponse() ResponseDto {
Code: d.Code,
Name: d.Name,
Specialist_Id: d.Specialist_Id,
+ Subspecialist: d.SubspecialistPositions,
}
resp.SmallMain = d.SmallMain
return resp
diff --git a/internal/domain/main-entities/unit-position/dto.go b/internal/domain/main-entities/unit-position/dto.go
new file mode 100644
index 00000000..cc52c493
--- /dev/null
+++ b/internal/domain/main-entities/unit-position/dto.go
@@ -0,0 +1,84 @@
+package unit_position
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ee "simrs-vx/internal/domain/main-entities/employee"
+ eu "simrs-vx/internal/domain/main-entities/unit"
+)
+
+type CreateDto struct {
+ Unit_Id *uint16 `json:"unit_id" validate:"required"`
+ Code string `json:"code" validate:"maxLength=10;required"`
+ Name string `json:"name" validate:"maxLength=30;required"`
+ HeadStatus bool `json:"headStatus"`
+ Employee_Id *uint `json:"employee_id"`
+}
+
+type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Sort string `json:"sort"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ Unit_Id *uint16 `json:"unit-id"`
+ Code string `json:"code"`
+ Name string `json:"name"`
+ HeadStatus *bool `json:"head-status"`
+ Employee_Id *uint `json:"employee-id"`
+ Search string `json:"search" gormhelper:"searchColumns=Code,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"`
+}
+
+type MetaDto struct {
+ PageNumber int `json:"page_number"`
+ PageSize int `json:"page_size"`
+ Count int `json:"count"`
+}
+
+type ResponseDto struct {
+ ecore.SmallMain
+ Unit_Id *uint16 `json:"unit_id"`
+ Unit *eu.Unit `json:"unit,omitempty"`
+ Code string `json:"code"`
+ Name string `json:"name"`
+ HeadStatus bool `json:"headStatus"`
+ Employee_Id *uint `json:"employee_id"`
+ Employee *ee.Employee `json:"employee,omitempty"`
+}
+
+func (d UnitPosition) ToResponse() ResponseDto {
+ resp := ResponseDto{
+ Unit_Id: d.Unit_Id,
+ Unit: d.Unit,
+ Code: d.Code,
+ Name: d.Name,
+ HeadStatus: d.HeadStatus,
+ Employee_Id: d.Employee_Id,
+ Employee: d.Employee,
+ }
+ resp.SmallMain = d.SmallMain
+ return resp
+}
+
+func ToResponseList(data []UnitPosition) []ResponseDto {
+ resp := make([]ResponseDto, len(data))
+ for i, u := range data {
+ resp[i] = u.ToResponse()
+ }
+ return resp
+}
diff --git a/internal/domain/main-entities/unit/dto.go b/internal/domain/main-entities/unit/dto.go
index 10960609..ce1dd505 100644
--- a/internal/domain/main-entities/unit/dto.go
+++ b/internal/domain/main-entities/unit/dto.go
@@ -3,6 +3,7 @@ package unit
import (
ecore "simrs-vx/internal/domain/base-entities/core"
ei "simrs-vx/internal/domain/main-entities/installation"
+ eipb "simrs-vx/internal/domain/main-entities/unit-position/base"
)
type CreateDto struct {
@@ -29,6 +30,7 @@ type ReadDetailDto struct {
Id uint16 `json:"id"`
Installation_Id *uint16 `json:"installation_id"`
Code *string `json:"code"`
+ Includes string `json:"includes"`
}
type UpdateDto struct {
@@ -50,8 +52,9 @@ type ResponseDto struct {
ecore.SmallMain
Installation_Id *uint16 `json:"installation_id"`
Installation *ei.Installation
- Code string `json:"code"`
- Name string `json:"name"`
+ Code string `json:"code"`
+ Name string `json:"name"`
+ UnitPositions []eipb.Basic `json:"unitPositions,omitempty"`
}
func (d Unit) ToResponse() ResponseDto {
@@ -59,6 +62,7 @@ func (d Unit) ToResponse() ResponseDto {
Installation_Id: d.Installation_Id,
Code: d.Code,
Name: d.Name,
+ UnitPositions: d.UnitPositions,
}
resp.SmallMain = d.SmallMain
if d.Installation != nil {
diff --git a/internal/domain/main-entities/user/dto.go b/internal/domain/main-entities/user/dto.go
index b06a4bb0..c3a84737 100644
--- a/internal/domain/main-entities/user/dto.go
+++ b/internal/domain/main-entities/user/dto.go
@@ -20,6 +20,7 @@ type CreateDto struct {
Person *ep.UpdateDto `json:"person"`
PersonAddresses []epa.UpdateDto `json:"personAddresses"`
PersonContacts []epc.UpdateDto `json:"personContacts"`
+ Code *string `json:"code" validate:"maxLength=20"`
Employee *EmployeUpdateDto `json:"employee"`
IHS_Number *string `json:"ihs_number" validate:"maxLength=20"`
SIP_Number *string `json:"sip_number" validate:"maxLength=20"`
diff --git a/internal/domain/simgos-sync-entities/.keep b/internal/domain/simgos-sync-entities/.keep
new file mode 100644
index 00000000..e69de29b
diff --git a/internal/infra/sync-cfg/sync-cfg.go b/internal/infra/sync-cfg/sync-cfg.go
new file mode 100644
index 00000000..0368a7c4
--- /dev/null
+++ b/internal/infra/sync-cfg/sync-cfg.go
@@ -0,0 +1,14 @@
+package synccfg
+
+import (
+ a "github.com/karincake/apem"
+ lo "github.com/karincake/apem/loggero"
+)
+
+func SetConfig() {
+ a.ParseSingleCfg(&O)
+ if O.Host == "" || O.Target == "" {
+ panic("sync url config host or target empty")
+ }
+ lo.I.Println("sync url config loaded, status: DONE!!")
+}
diff --git a/internal/infra/sync-cfg/tycovar.go b/internal/infra/sync-cfg/tycovar.go
new file mode 100644
index 00000000..9bb59f3d
--- /dev/null
+++ b/internal/infra/sync-cfg/tycovar.go
@@ -0,0 +1,8 @@
+package synccfg
+
+var O SyncUrlCfg = SyncUrlCfg{}
+
+type SyncUrlCfg struct {
+ Target string `yaml:"target"`
+ Host string `yaml:"host"`
+}
diff --git a/internal/interface/main-handler/division/handler.go b/internal/interface/main-handler/division/handler.go
index 94940f55..ee4cbea5 100644
--- a/internal/interface/main-handler/division/handler.go
+++ b/internal/interface/main-handler/division/handler.go
@@ -37,7 +37,9 @@ func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) {
if id <= 0 {
return
}
+
dto := e.ReadDetailDto{}
+ sf.UrlQueryParam(&dto, *r.URL)
dto.Id = uint16(id)
res, err := u.ReadDetail(dto)
rw.DataResponse(w, res, err)
diff --git a/internal/interface/main-handler/edu-assessment/handler.go b/internal/interface/main-handler/edu-assessment/handler.go
new file mode 100644
index 00000000..9d06d434
--- /dev/null
+++ b/internal/interface/main-handler/edu-assessment/handler.go
@@ -0,0 +1,74 @@
+package internal_reference
+
+import (
+ "net/http"
+
+ e "simrs-vx/internal/domain/main-entities/edu-assessment"
+ u "simrs-vx/internal/use-case/main-use-case/edu-assessment"
+
+ rw "github.com/karincake/risoles"
+ sf "github.com/karincake/semprit"
+)
+
+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{}
+ sf.UrlQueryParam(&dto, *r.URL)
+
+ 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/encounter/handler.go b/internal/interface/main-handler/encounter/handler.go
index 96063298..df3320ef 100644
--- a/internal/interface/main-handler/encounter/handler.go
+++ b/internal/interface/main-handler/encounter/handler.go
@@ -12,7 +12,6 @@ import (
u "simrs-vx/internal/use-case/main-use-case/encounter"
erc "simrs-vx/internal/domain/references/common"
-
pa "simrs-vx/pkg/auth-helper"
d "github.com/karincake/dodol"
@@ -88,9 +87,16 @@ func (obj myBase) CheckOut(w http.ResponseWriter, r *http.Request) {
if id <= 0 {
return
}
+
if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
return
}
+
+ // validate request body
+ if valid := validateRequestCheckout(w, dto); !valid {
+ return
+ }
+
dto.Id = uint(id)
res, err := u.CheckOut(dto)
rw.DataResponse(w, res, err)
diff --git a/internal/interface/main-handler/encounter/request-validation.go b/internal/interface/main-handler/encounter/request-validation.go
new file mode 100644
index 00000000..182dd12e
--- /dev/null
+++ b/internal/interface/main-handler/encounter/request-validation.go
@@ -0,0 +1,53 @@
+package encounter
+
+import (
+ "fmt"
+ "net/http"
+ e "simrs-vx/internal/domain/main-entities/encounter"
+ ere "simrs-vx/internal/domain/references/encounter"
+
+ d "github.com/karincake/dodol"
+ rw "github.com/karincake/risoles"
+)
+
+func validateRequestCheckout(w http.ResponseWriter, i e.DischargeDto) (valid bool) {
+ const dataValidationFail = ""
+
+ switch *i.Discharge_Method_Code {
+ case ere.DMCDeath:
+ if i.DeathCause == nil {
+ rw.DataResponse(w, nil, d.FieldError{
+ Code: dataValidationFail,
+ Message: "deathCause required if discharge_method_code is death",
+ })
+ return
+ }
+ case ere.DMCConsulPoly, ere.DMCConsulExecutive:
+ if i.InternalReferences == nil {
+ rw.DataResponse(w, nil, d.FieldError{
+ Code: dataValidationFail,
+ Message: fmt.Sprintf("internalReferences required if discharge_method_code is %s", *i.Discharge_Method_Code),
+ })
+ return
+ }
+
+ for _, v := range *i.InternalReferences {
+ if v.Unit_Id == nil {
+ rw.DataResponse(w, nil, d.FieldError{
+ Code: dataValidationFail,
+ Message: "internalReferences.unit_id required",
+ })
+ return
+ }
+
+ if v.Doctor_Id == nil {
+ rw.DataResponse(w, nil, d.FieldError{
+ Code: dataValidationFail,
+ Message: "internalReferences.doctor_id required",
+ })
+ return
+ }
+ }
+ }
+ return true
+}
diff --git a/internal/interface/main-handler/installation-position/handler.go b/internal/interface/main-handler/installation-position/handler.go
new file mode 100644
index 00000000..59f35340
--- /dev/null
+++ b/internal/interface/main-handler/installation-position/handler.go
@@ -0,0 +1,71 @@
+package installation_position
+
+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/installation-position"
+ u "simrs-vx/internal/use-case/main-use-case/installation-position"
+)
+
+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 = 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/installation/handler.go b/internal/interface/main-handler/installation/handler.go
index dd5903f8..26885689 100644
--- a/internal/interface/main-handler/installation/handler.go
+++ b/internal/interface/main-handler/installation/handler.go
@@ -38,6 +38,8 @@ func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) {
return
}
dto := e.ReadDetailDto{}
+
+ sf.UrlQueryParam(&dto, *r.URL)
dto.Id = uint16(id)
res, err := u.ReadDetail(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 c53e8795..6a98487f 100644
--- a/internal/interface/main-handler/main-handler.go
+++ b/internal/interface/main-handler/main-handler.go
@@ -66,9 +66,11 @@ import (
division "simrs-vx/internal/interface/main-handler/division"
divisionposition "simrs-vx/internal/interface/main-handler/division-position"
doctorfee "simrs-vx/internal/interface/main-handler/doctor-fee"
+ eduassesment "simrs-vx/internal/interface/main-handler/edu-assessment"
ethnic "simrs-vx/internal/interface/main-handler/ethnic"
infra "simrs-vx/internal/interface/main-handler/infra"
installation "simrs-vx/internal/interface/main-handler/installation"
+ installationposition "simrs-vx/internal/interface/main-handler/installation-position"
insurancecompany "simrs-vx/internal/interface/main-handler/insurance-company"
item "simrs-vx/internal/interface/main-handler/item"
itemprice "simrs-vx/internal/interface/main-handler/item-price"
@@ -85,8 +87,11 @@ import (
pharmacycompany "simrs-vx/internal/interface/main-handler/pharmacy-company"
proceduresrc "simrs-vx/internal/interface/main-handler/procedure-src"
specialist "simrs-vx/internal/interface/main-handler/specialist"
+ specialistposition "simrs-vx/internal/interface/main-handler/specialist-position"
subspecialist "simrs-vx/internal/interface/main-handler/subspecialist"
+ subspecialistposition "simrs-vx/internal/interface/main-handler/subspecialist-position"
unit "simrs-vx/internal/interface/main-handler/unit"
+ unitposition "simrs-vx/internal/interface/main-handler/unit-position"
uom "simrs-vx/internal/interface/main-handler/uom"
vehicle "simrs-vx/internal/interface/main-handler/vehicle"
vehiclehist "simrs-vx/internal/interface/main-handler/vehicle-hist"
@@ -269,7 +274,7 @@ func SetRoutes() http.Handler {
"PATCH /{id}": patient.O.Update,
"DELETE /{id}": patient.O.Delete,
"GET /search/{keyword}": patient.O.Search,
- "GET /by-resident-identity": patient.O.SearchByResidentIdentity,
+ "GET /by-resident-identity": patient.O.SearchByResidentIdentityNumber,
"POST /{id}/upload": patient.O.Upload,
})
@@ -303,6 +308,11 @@ func SetRoutes() http.Handler {
hc.RegCrud(r, "/v1/mcu-sub-src", mcusubsrc.O)
hc.RegCrud(r, "/v1/vehicle", vehicle.O)
hc.RegCrud(r, "/v1/vehicle-hist", vehiclehist.O)
+ hc.RegCrud(r, "/v1/edu-assessment", eduassesment.O)
+ hc.RegCrud(r, "/v1/installation-position", installationposition.O)
+ hc.RegCrud(r, "/v1/unit-position", unitposition.O)
+ hc.RegCrud(r, "/v1/specialist-position", specialistposition.O)
+ hc.RegCrud(r, "/v1/subspecialist-position", subspecialistposition.O)
hc.RegCrud(r, "/v1/village", village.O)
hc.RegCrud(r, "/v1/district", district.O)
diff --git a/internal/interface/main-handler/patient/handler.go b/internal/interface/main-handler/patient/handler.go
index 2c5fcb5b..1d02d8d7 100644
--- a/internal/interface/main-handler/patient/handler.go
+++ b/internal/interface/main-handler/patient/handler.go
@@ -76,21 +76,22 @@ func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) {
func (obj myBase) Search(w http.ResponseWriter, r *http.Request) {
dto := e.SearchDto{}
+
+ sf.UrlQueryParam(&dto, *r.URL)
keyword := rw.ValidateString(w, "keyword", r.PathValue("keyword"))
if keyword == "" {
rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "keyword is required"}, nil)
}
- dto.Mode = e.SMIdent
+
dto.Search = keyword
res, err := u.Search(dto)
rw.DataResponse(w, res, err)
}
-func (obj myBase) SearchByResidentIdentity(w http.ResponseWriter, r *http.Request) {
+func (obj myBase) SearchByResidentIdentityNumber(w http.ResponseWriter, r *http.Request) {
dto := e.SearchDto{}
sf.UrlQueryParam(&dto, *r.URL)
- dto.Mode = e.SMNik
- res, err := u.Search(dto)
+ res, err := u.SearchByResidentIdentityNumber(dto)
rw.DataResponse(w, res, err)
}
diff --git a/internal/interface/main-handler/specialist-position/handler.go b/internal/interface/main-handler/specialist-position/handler.go
new file mode 100644
index 00000000..d16c2c7e
--- /dev/null
+++ b/internal/interface/main-handler/specialist-position/handler.go
@@ -0,0 +1,71 @@
+package divisionposition
+
+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/specialist-position"
+ u "simrs-vx/internal/use-case/main-use-case/specialist-position"
+)
+
+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 = 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/specialist/handler.go b/internal/interface/main-handler/specialist/handler.go
index 561d07d0..d3a074d8 100644
--- a/internal/interface/main-handler/specialist/handler.go
+++ b/internal/interface/main-handler/specialist/handler.go
@@ -38,6 +38,8 @@ func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) {
return
}
dto := e.ReadDetailDto{}
+
+ sf.UrlQueryParam(&dto, *r.URL)
dto.Id = uint16(id)
res, err := u.ReadDetail(dto)
rw.DataResponse(w, res, err)
diff --git a/internal/interface/main-handler/subspecialist-position/handler.go b/internal/interface/main-handler/subspecialist-position/handler.go
new file mode 100644
index 00000000..d8e27b14
--- /dev/null
+++ b/internal/interface/main-handler/subspecialist-position/handler.go
@@ -0,0 +1,71 @@
+package divisionposition
+
+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/subspecialist-position"
+ u "simrs-vx/internal/use-case/main-use-case/subspecialist-position"
+)
+
+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 = 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/subspecialist/handler.go b/internal/interface/main-handler/subspecialist/handler.go
index d639c115..c4b933b4 100644
--- a/internal/interface/main-handler/subspecialist/handler.go
+++ b/internal/interface/main-handler/subspecialist/handler.go
@@ -38,6 +38,8 @@ func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) {
return
}
dto := e.ReadDetailDto{}
+
+ sf.UrlQueryParam(&dto, *r.URL)
dto.Id = uint16(id)
res, err := u.ReadDetail(dto)
rw.DataResponse(w, res, err)
diff --git a/internal/interface/main-handler/unit-position/handler.go b/internal/interface/main-handler/unit-position/handler.go
new file mode 100644
index 00000000..82b89465
--- /dev/null
+++ b/internal/interface/main-handler/unit-position/handler.go
@@ -0,0 +1,71 @@
+package unit_position
+
+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/unit-position"
+ u "simrs-vx/internal/use-case/main-use-case/unit-position"
+)
+
+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 = 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/unit/handler.go b/internal/interface/main-handler/unit/handler.go
index 0abc9a21..a94ce74e 100644
--- a/internal/interface/main-handler/unit/handler.go
+++ b/internal/interface/main-handler/unit/handler.go
@@ -38,6 +38,8 @@ func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) {
return
}
dto := e.ReadDetailDto{}
+
+ sf.UrlQueryParam(&dto, *r.URL)
dto.Id = uint16(id)
res, err := u.ReadDetail(dto)
rw.DataResponse(w, res, err)
diff --git a/internal/interface/main-sync-handler/main-sync-handler.go b/internal/interface/main-sync-handler/main-sync-handler.go
new file mode 100644
index 00000000..c8ba5144
--- /dev/null
+++ b/internal/interface/main-sync-handler/main-sync-handler.go
@@ -0,0 +1,36 @@
+package mainsynchandler
+
+import (
+ "net/http"
+
+ /******************** infra ********************/
+ gs "simrs-vx/internal/infra/gorm-setting"
+ synccfg "simrs-vx/internal/infra/sync-cfg"
+
+ /******************** pkg ********************/
+ cmw "simrs-vx/pkg/cors-manager-mw"
+ lh "simrs-vx/pkg/lang-helper"
+ handlerlogger "simrs-vx/pkg/middleware/handler-logger"
+ zlc "simrs-vx/pkg/zerolog-ctx"
+
+ /******************** external ********************/
+ a "github.com/karincake/apem"
+
+ /******************** internal ********************/
+ "simrs-vx/internal/interface/main-handler/home"
+)
+
+func SetRoutes() http.Handler {
+ ///
+ a.RegisterExtCall(gs.Adjust)
+ a.RegisterExtCall(zlc.Adjust)
+ a.RegisterExtCall(lh.Populate)
+ a.RegisterExtCall(synccfg.SetConfig)
+
+ r := http.NewServeMux()
+
+ /******************** Main ********************/
+ r.HandleFunc("/", home.Home)
+
+ return cmw.SetCors(handlerlogger.SetLog(r))
+}
diff --git a/internal/interface/simgos-sync-handler/simgos-sync-handler.go b/internal/interface/simgos-sync-handler/simgos-sync-handler.go
new file mode 100644
index 00000000..f51106a9
--- /dev/null
+++ b/internal/interface/simgos-sync-handler/simgos-sync-handler.go
@@ -0,0 +1,36 @@
+package simgossynchandler
+
+import (
+ "net/http"
+
+ /******************** infra ********************/
+ gs "simrs-vx/internal/infra/gorm-setting"
+ synccfg "simrs-vx/internal/infra/sync-cfg"
+
+ /******************** pkg ********************/
+ cmw "simrs-vx/pkg/cors-manager-mw"
+ lh "simrs-vx/pkg/lang-helper"
+ handlerlogger "simrs-vx/pkg/middleware/handler-logger"
+ zlc "simrs-vx/pkg/zerolog-ctx"
+
+ /******************** external ********************/
+ a "github.com/karincake/apem"
+
+ /******************** internal ********************/
+ "simrs-vx/internal/interface/main-handler/home"
+)
+
+func SetRoutes() http.Handler {
+ ///
+ a.RegisterExtCall(gs.Adjust)
+ a.RegisterExtCall(zlc.Adjust)
+ a.RegisterExtCall(lh.Populate)
+ a.RegisterExtCall(synccfg.SetConfig)
+
+ r := http.NewServeMux()
+
+ /******************** Main ********************/
+ r.HandleFunc("/", home.Home)
+
+ return cmw.SetCors(handlerlogger.SetLog(r))
+}
diff --git a/internal/use-case/main-sync-case/.keep b/internal/use-case/main-sync-case/.keep
new file mode 100644
index 00000000..e69de29b
diff --git a/internal/use-case/main-use-case/ambulance-transport-req/case.go b/internal/use-case/main-use-case/ambulance-transport-req/case.go
index 712d6241..6810fe83 100644
--- a/internal/use-case/main-use-case/ambulance-transport-req/case.go
+++ b/internal/use-case/main-use-case/ambulance-transport-req/case.go
@@ -1,4 +1,4 @@
-package ambulancetransport
+package ambulance_transport_req
import (
"errors"
diff --git a/internal/use-case/main-use-case/ambulance-transport-req/helper.go b/internal/use-case/main-use-case/ambulance-transport-req/helper.go
index 3c739eb0..9ad4122d 100644
--- a/internal/use-case/main-use-case/ambulance-transport-req/helper.go
+++ b/internal/use-case/main-use-case/ambulance-transport-req/helper.go
@@ -2,7 +2,7 @@
DESCRIPTION:
Any functions that are used internally by the use-case
*/
-package ambulancetransport
+package ambulance_transport_req
import (
"errors"
diff --git a/internal/use-case/main-use-case/ambulance-transport-req/lib.go b/internal/use-case/main-use-case/ambulance-transport-req/lib.go
index e8555a6f..eca1c5b9 100644
--- a/internal/use-case/main-use-case/ambulance-transport-req/lib.go
+++ b/internal/use-case/main-use-case/ambulance-transport-req/lib.go
@@ -1,4 +1,4 @@
-package ambulancetransport
+package ambulance_transport_req
import (
"errors"
diff --git a/internal/use-case/main-use-case/ambulance-transport-req/middleware-runner.go b/internal/use-case/main-use-case/ambulance-transport-req/middleware-runner.go
index b98c497d..18937f5c 100644
--- a/internal/use-case/main-use-case/ambulance-transport-req/middleware-runner.go
+++ b/internal/use-case/main-use-case/ambulance-transport-req/middleware-runner.go
@@ -1,4 +1,4 @@
-package ambulancetransport
+package ambulance_transport_req
import (
atr "simrs-vx/internal/domain/main-entities/ambulance-transport-req"
diff --git a/internal/use-case/main-use-case/ambulance-transport-req/middleware.go b/internal/use-case/main-use-case/ambulance-transport-req/middleware.go
index 847aa3dd..cc1f7c3e 100644
--- a/internal/use-case/main-use-case/ambulance-transport-req/middleware.go
+++ b/internal/use-case/main-use-case/ambulance-transport-req/middleware.go
@@ -1,4 +1,4 @@
-package ambulancetransport
+package ambulance_transport_req
// example of middleware
// func init() {
diff --git a/internal/use-case/main-use-case/ambulance-transport-req/tycovar.go b/internal/use-case/main-use-case/ambulance-transport-req/tycovar.go
index 5d3ac027..54f8f604 100644
--- a/internal/use-case/main-use-case/ambulance-transport-req/tycovar.go
+++ b/internal/use-case/main-use-case/ambulance-transport-req/tycovar.go
@@ -6,7 +6,7 @@ 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 ambulancetransport
+package ambulance_transport_req
import (
"gorm.io/gorm"
diff --git a/internal/use-case/main-use-case/authentication/case.go b/internal/use-case/main-use-case/authentication/case.go
index ffefa7ef..5b9952a3 100644
--- a/internal/use-case/main-use-case/authentication/case.go
+++ b/internal/use-case/main-use-case/authentication/case.go
@@ -120,10 +120,10 @@ func GenToken(input eu.LoginDto) (*d.Data, error) {
outputData["employee_id"] = employee.Id
role = append(role, "emp-"+string(*employee.Position_Code))
- if employee.Division_Code != nil {
- atClaims["employee_division_code"] = employee.Division_Code
- outputData["employee_division_code"] = employee.Division_Code
- }
+ //if employee.Division_Code != nil {
+ // atClaims["employee_division_code"] = employee.Division_Code
+ // outputData["employee_division_code"] = employee.Division_Code
+ //}
// employee position
if employee.Id > 0 && employee.Position_Code != nil {
@@ -155,12 +155,44 @@ func GenToken(input eu.LoginDto) (*d.Data, error) {
atClaims["nurse_id"] = nurse.Id
outputData["nurse_id"] = nurse.Id
}
+
+ errorGetPosition := d.FieldErrors{"authentication": d.FieldError{Code: "auth-getData-failed", Message: el.GenMessage("auth-getData-failed")}}
+
// division position
- divsionPositions, err := getDivisionPosition(employee.Id)
+ divisionPositions, err := getDivisionPosition(employee.Id)
if err != nil {
- return nil, d.FieldErrors{"authentication": d.FieldError{Code: "auth-getData-failed", Message: el.GenMessage("auth-getData-failed")}}
+ return nil, errorGetPosition
}
- role = append(role, divsionPositions...)
+
+ // installation position
+ installationPositions, err := getInstallationPosition(employee.Id)
+ if err != nil {
+ return nil, errorGetPosition
+ }
+
+ // unit position
+ unitPositions, err := getUnitPosition(employee.Id)
+ if err != nil {
+ return nil, errorGetPosition
+ }
+
+ // specialist position
+ specialistPositions, err := getSpecialistPosition(employee.Id)
+ if err != nil {
+ return nil, errorGetPosition
+ }
+
+ // subspecialist position
+ subspecialistPositions, err := getSubspecialistPosition(employee.Id)
+ if err != nil {
+ return nil, errorGetPosition
+ }
+
+ role = append(role, divisionPositions...)
+ role = append(role, installationPositions...)
+ role = append(role, unitPositions...)
+ role = append(role, specialistPositions...)
+ role = append(role, subspecialistPositions...)
// atClaims["division_positions"] = divsionPositions
// outputData["division_positions"] = divsionPositions
}
diff --git a/internal/use-case/main-use-case/authentication/helper.go b/internal/use-case/main-use-case/authentication/helper.go
index c4e67200..87473386 100644
--- a/internal/use-case/main-use-case/authentication/helper.go
+++ b/internal/use-case/main-use-case/authentication/helper.go
@@ -2,9 +2,18 @@ package authentication
import (
edp "simrs-vx/internal/domain/main-entities/division-position"
+ eip "simrs-vx/internal/domain/main-entities/installation-position"
+ esp "simrs-vx/internal/domain/main-entities/specialist-position"
+ essp "simrs-vx/internal/domain/main-entities/subspecialist-position"
+ eup "simrs-vx/internal/domain/main-entities/unit-position"
+
+ udp "simrs-vx/internal/use-case/main-use-case/division-position"
+ uip "simrs-vx/internal/use-case/main-use-case/installation-position"
+ usp "simrs-vx/internal/use-case/main-use-case/specialist-position"
+ ussp "simrs-vx/internal/use-case/main-use-case/subspecialist-position"
+ uup "simrs-vx/internal/use-case/main-use-case/unit-position"
dg "github.com/karincake/apem/db-gorm-pg"
- "gorm.io/gorm"
)
// just return the error code
@@ -34,21 +43,129 @@ func getDivisionPosition(employee_id uint) ([]string, error) {
// return result, errors.New("no employee found")
// }
- var divisionPositions []edp.DivisionPosition
- err := dg.I.
- Preload("Division").
- Where("\"Employee_Id\" = ?", employee_id).
- Find(&divisionPositions).Error
+ //var divisionPositions []edp.DivisionPosition
+ //err := dg.I.
+ // Preload("Division").
+ // Where("\"Employee_Id\" = ?", employee_id).
+ // Find(&divisionPositions).Error
+ //if err != nil {
+ // if err == gorm.ErrRecordNotFound {
+ // return result, nil
+ // }
+ // return result, err
+ //}
+
+ // get data division_position based on employee_id
+ dataDivisionPosition, err := udp.ReadList(edp.ReadListDto{
+ FilterDto: edp.FilterDto{Employee_Id: &employee_id},
+ Includes: "division"})
if err != nil {
- if err == gorm.ErrRecordNotFound {
- return result, nil
- }
- return result, err
+ return nil, err
}
- for _, dp := range divisionPositions {
- if dp.Division != nil {
- result = append(result, "div-"+dp.Division.Code+"-"+dp.Code)
+ if list, ok := dataDivisionPosition.Data.([]edp.ResponseDto); ok {
+ if len(list) > 0 {
+ for _, dp := range list {
+ if dp.Division != nil {
+ result = append(result, "div-"+dp.Division.Code+"-"+dp.Code)
+ }
+ }
+ }
+ }
+
+ return result, nil
+}
+
+func getInstallationPosition(employeeId uint) ([]string, error) {
+ var result []string
+
+ // get data unit_position based on employee_id
+ dataInstallationPosition, err := uip.ReadList(eip.ReadListDto{
+ FilterDto: eip.FilterDto{Employee_Id: &employeeId},
+ Includes: "installation"})
+ if err != nil {
+ return nil, err
+ }
+
+ if list, ok := dataInstallationPosition.Data.([]eip.ResponseDto); ok {
+ if len(list) > 0 {
+ for _, dp := range list {
+ if dp.Installation != nil {
+ result = append(result, "inst-"+dp.Installation.Code+"-"+dp.Code)
+ }
+ }
+ }
+ }
+
+ return result, nil
+}
+
+func getUnitPosition(employeeId uint) ([]string, error) {
+ var result []string
+
+ // get data unit_position based on employee_id
+ dataUnitPosition, err := uup.ReadList(eup.ReadListDto{
+ FilterDto: eup.FilterDto{Employee_Id: &employeeId},
+ Includes: "unit"})
+ if err != nil {
+ return nil, err
+ }
+
+ if list, ok := dataUnitPosition.Data.([]eup.ResponseDto); ok {
+ if len(list) > 0 {
+ for _, dp := range list {
+ if dp.Unit != nil {
+ result = append(result, "unit-"+dp.Unit.Code+"-"+dp.Code)
+ }
+ }
+ }
+ }
+
+ return result, nil
+}
+
+func getSpecialistPosition(employeeId uint) ([]string, error) {
+ var result []string
+
+ // get data unit_position based on employee_id
+ dataSpecialistPosition, err := usp.ReadList(esp.ReadListDto{
+ FilterDto: esp.FilterDto{Employee_Id: &employeeId},
+ Includes: "specialist"})
+ if err != nil {
+ return nil, err
+ }
+
+ if list, ok := dataSpecialistPosition.Data.([]esp.ResponseDto); ok {
+ if len(list) > 0 {
+ for _, dp := range list {
+ if dp.Specialist != nil {
+ result = append(result, "spec-"+dp.Specialist.Code+"-"+dp.Code)
+ }
+ }
+ }
+ }
+
+ return result, nil
+}
+
+func getSubspecialistPosition(employeeId uint) ([]string, error) {
+ var result []string
+
+ // get data unit_position based on employee_id
+ dataSubspecialistPosition, err := ussp.ReadList(essp.ReadListDto{
+ FilterDto: essp.FilterDto{Employee_Id: &employeeId},
+ Includes: "subspecialist"})
+ if err != nil {
+ return nil, err
+ }
+
+ if list, ok := dataSubspecialistPosition.Data.([]essp.ResponseDto); ok {
+ if len(list) > 0 {
+ for _, dp := range list {
+ if dp.Subspecialist != nil {
+ result = append(result, "subspec-"+dp.Subspecialist.Code+"-"+dp.Code)
+ }
+ }
}
}
diff --git a/internal/use-case/main-use-case/death-cause/case.go b/internal/use-case/main-use-case/death-cause/case.go
new file mode 100644
index 00000000..484c0f66
--- /dev/null
+++ b/internal/use-case/main-use-case/death-cause/case.go
@@ -0,0 +1,228 @@
+package deathcause
+
+import (
+
+ // main entities
+ edc "simrs-vx/internal/domain/main-entities/death-cause"
+ "strconv"
+
+ pl "simrs-vx/pkg/logger"
+ pu "simrs-vx/pkg/use-case-helper"
+
+ dg "github.com/karincake/apem/db-gorm-pg"
+ d "github.com/karincake/dodol"
+ "gorm.io/gorm"
+)
+
+const source = "death-cause"
+
+func Create(input edc.CreateDto) (*d.Data, error) {
+ data := edc.DeathCause{}
+
+ 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 edc.ReadListDto) (*d.Data, error) {
+ var data *edc.DeathCause
+ var dataList []edc.DeathCause
+ var metaList *edc.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: edc.ToResponseList(dataList),
+ }, nil
+}
+
+func ReadDetail(input edc.ReadDetailDto) (*d.Data, error) {
+ var data *edc.DeathCause
+ 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 edc.UpdateDto) (*d.Data, error) {
+ rdDto := edc.ReadDetailDto{Id: input.Id}
+ var data *edc.DeathCause
+ 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
+ }
+
+ // 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
+
+}
diff --git a/internal/use-case/main-use-case/death-cause/helper.go b/internal/use-case/main-use-case/death-cause/helper.go
new file mode 100644
index 00000000..c655a966
--- /dev/null
+++ b/internal/use-case/main-use-case/death-cause/helper.go
@@ -0,0 +1,22 @@
+/*
+DESCRIPTION:
+Any functions that are used internally by the use-case
+*/
+package deathcause
+
+import (
+ e "simrs-vx/internal/domain/main-entities/death-cause"
+)
+
+func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.DeathCause) {
+ 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/death-cause/lib.go b/internal/use-case/main-use-case/death-cause/lib.go
new file mode 100644
index 00000000..9f1d548b
--- /dev/null
+++ b/internal/use-case/main-use-case/death-cause/lib.go
@@ -0,0 +1,140 @@
+package deathcause
+
+import (
+ "errors"
+ e "simrs-vx/internal/domain/main-entities/death-cause"
+ 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.DeathCause, error) {
+ pl.SetLogInfo(event, nil, "started", "DBCreate")
+
+ data := e.DeathCause{}
+ 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.DeathCause, *e.MetaDto, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadList")
+ data := []e.DeathCause{}
+ 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.DeathCause{}).
+ 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.DeathCause, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadDetail")
+ data := e.DeathCause{}
+
+ 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.DeathCause, 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.DeathCause, 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/death-cause/middleware-runner.go b/internal/use-case/main-use-case/death-cause/middleware-runner.go
new file mode 100644
index 00000000..3b0b1aa0
--- /dev/null
+++ b/internal/use-case/main-use-case/death-cause/middleware-runner.go
@@ -0,0 +1,103 @@
+package deathcause
+
+import (
+ e "simrs-vx/internal/domain/main-entities/death-cause"
+ 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.DeathCause) 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.DeathCause) 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.DeathCause) 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.DeathCause) 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.DeathCause) 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/death-cause/middleware.go b/internal/use-case/main-use-case/death-cause/middleware.go
new file mode 100644
index 00000000..845ec256
--- /dev/null
+++ b/internal/use-case/main-use-case/death-cause/middleware.go
@@ -0,0 +1,9 @@
+package deathcause
+
+// 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/death-cause/tycovar.go b/internal/use-case/main-use-case/death-cause/tycovar.go
new file mode 100644
index 00000000..9cfe21a6
--- /dev/null
+++ b/internal/use-case/main-use-case/death-cause/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 deathcause
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/main-entities/death-cause"
+)
+
+type createMw struct {
+ Name string
+ Func func(input *e.CreateDto, data *e.DeathCause, tx *gorm.DB) error
+}
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.DeathCause, tx *gorm.DB) error
+}
+
+type readDetailMw struct {
+ Name string
+ Func func(input *e.ReadDetailDto, data *e.DeathCause, 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/division/lib.go b/internal/use-case/main-use-case/division/lib.go
index 828395e7..56ce34f7 100644
--- a/internal/use-case/main-use-case/division/lib.go
+++ b/internal/use-case/main-use-case/division/lib.go
@@ -91,7 +91,9 @@ 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/internal/use-case/main-use-case/doctor/helper.go b/internal/use-case/main-use-case/doctor/helper.go
index 8077b92f..b62045c7 100644
--- a/internal/use-case/main-use-case/doctor/helper.go
+++ b/internal/use-case/main-use-case/doctor/helper.go
@@ -17,6 +17,7 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Doctor) {
inputSrc = &inputTemp.CreateDto
}
+ data.Code = inputSrc.Code
data.Employee_Id = inputSrc.Employee_Id
data.IHS_Number = inputSrc.IHS_Number
data.SIP_Number = inputSrc.SIP_Number
diff --git a/internal/use-case/main-use-case/edu-assessment/case.go b/internal/use-case/main-use-case/edu-assessment/case.go
new file mode 100644
index 00000000..230f0679
--- /dev/null
+++ b/internal/use-case/main-use-case/edu-assessment/case.go
@@ -0,0 +1,284 @@
+package edu_assessment
+
+import (
+ e "simrs-vx/internal/domain/main-entities/edu-assessment"
+ ee "simrs-vx/internal/domain/main-entities/encounter"
+ "strconv"
+
+ 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 = "edu-assessment"
+
+func Create(input e.CreateDto) (*d.Data, error) {
+ data := e.EduAssessment{}
+
+ 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
+ }
+
+ // validate encounter_id
+ _, err := ue.ReadDetail(ee.ReadDetailDto{Id: uint16(*input.Encounter_Id)})
+ if 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.EduAssessment
+ var dataList []e.EduAssessment
+ 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.EduAssessment
+ 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.EduAssessment
+ 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.EduAssessment
+ 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/edu-assessment/helper.go b/internal/use-case/main-use-case/edu-assessment/helper.go
new file mode 100644
index 00000000..9363a91a
--- /dev/null
+++ b/internal/use-case/main-use-case/edu-assessment/helper.go
@@ -0,0 +1,25 @@
+/*
+DESCRIPTION:
+Any functions that are used internally by the use-case
+*/
+package edu_assessment
+
+import (
+ e "simrs-vx/internal/domain/main-entities/edu-assessment"
+)
+
+func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.EduAssessment) {
+ 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.GeneralEdus = inputSrc.GeneralEdus
+ data.SpecialEdus = inputSrc.SpecialEdus
+ data.Assessments = inputSrc.Assessments
+ data.Plan = inputSrc.Plan
+}
diff --git a/internal/use-case/main-use-case/edu-assessment/lib.go b/internal/use-case/main-use-case/edu-assessment/lib.go
new file mode 100644
index 00000000..fd2d0b22
--- /dev/null
+++ b/internal/use-case/main-use-case/edu-assessment/lib.go
@@ -0,0 +1,144 @@
+package edu_assessment
+
+import (
+ "errors"
+ e "simrs-vx/internal/domain/main-entities/edu-assessment"
+ 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.EduAssessment, error) {
+ pl.SetLogInfo(event, nil, "started", "DBCreate")
+
+ data := e.EduAssessment{}
+ 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.EduAssessment, *e.MetaDto, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadList")
+ data := []e.EduAssessment{}
+ 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.EduAssessment{}).
+ 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.EduAssessment, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadDetail")
+ data := e.EduAssessment{}
+
+ var tx *gorm.DB
+ if len(dbx) > 0 {
+ tx = dbx[0]
+ } else {
+ tx = dg.I
+ }
+
+ 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
+ }
+ }
+
+ pl.SetLogInfo(event, nil, "complete")
+ return &data, nil
+}
+
+func UpdateData(input e.UpdateDto, data *e.EduAssessment, 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.EduAssessment, 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/edu-assessment/middleware-runner.go b/internal/use-case/main-use-case/edu-assessment/middleware-runner.go
new file mode 100644
index 00000000..8d92aaf9
--- /dev/null
+++ b/internal/use-case/main-use-case/edu-assessment/middleware-runner.go
@@ -0,0 +1,103 @@
+package edu_assessment
+
+import (
+ e "simrs-vx/internal/domain/main-entities/edu-assessment"
+ 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.EduAssessment) 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.EduAssessment) 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.EduAssessment) 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.EduAssessment) 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.EduAssessment) 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/edu-assessment/middleware.go b/internal/use-case/main-use-case/edu-assessment/middleware.go
new file mode 100644
index 00000000..dd5ea973
--- /dev/null
+++ b/internal/use-case/main-use-case/edu-assessment/middleware.go
@@ -0,0 +1,9 @@
+package edu_assessment
+
+// 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/edu-assessment/tycovar.go b/internal/use-case/main-use-case/edu-assessment/tycovar.go
new file mode 100644
index 00000000..02f3b131
--- /dev/null
+++ b/internal/use-case/main-use-case/edu-assessment/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 edu_assessment
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/main-entities/edu-assessment"
+)
+
+type createMw struct {
+ Name string
+ Func func(input *e.CreateDto, data *e.EduAssessment, tx *gorm.DB) error
+}
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.EduAssessment, tx *gorm.DB) error
+}
+
+type readDetailMw struct {
+ Name string
+ Func func(input *e.ReadDetailDto, data *e.EduAssessment, 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/employee/helper.go b/internal/use-case/main-use-case/employee/helper.go
index 252d35eb..e13ce535 100644
--- a/internal/use-case/main-use-case/employee/helper.go
+++ b/internal/use-case/main-use-case/employee/helper.go
@@ -19,9 +19,9 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Employee) {
data.User_Id = inputSrc.User_Id
data.Person_Id = inputSrc.Person_Id
- data.Division_Code = inputSrc.Division_Code
data.Number = inputSrc.Number
data.Status_Code = inputSrc.Status_Code
+ data.Position_Code = inputSrc.Position_Code
}
// func createUser(input *e.CreateDto, event *pl.Event, tx *gorm.DB) error {
diff --git a/internal/use-case/main-use-case/encounter/case.go b/internal/use-case/main-use-case/encounter/case.go
index fad183f6..04eedfff 100644
--- a/internal/use-case/main-use-case/encounter/case.go
+++ b/internal/use-case/main-use-case/encounter/case.go
@@ -6,6 +6,7 @@ import (
ea "simrs-vx/internal/domain/main-entities/ambulatory"
ec "simrs-vx/internal/domain/main-entities/chemo"
+ edc "simrs-vx/internal/domain/main-entities/death-cause"
ee "simrs-vx/internal/domain/main-entities/emergency"
eem "simrs-vx/internal/domain/main-entities/employee"
e "simrs-vx/internal/domain/main-entities/encounter"
@@ -13,6 +14,7 @@ import (
ua "simrs-vx/internal/use-case/main-use-case/ambulatory"
uc "simrs-vx/internal/use-case/main-use-case/chemo"
+ udc "simrs-vx/internal/use-case/main-use-case/death-cause"
ue "simrs-vx/internal/use-case/main-use-case/emergency"
uem "simrs-vx/internal/use-case/main-use-case/employee"
ui "simrs-vx/internal/use-case/main-use-case/inpatient"
@@ -20,12 +22,12 @@ import (
erc "simrs-vx/internal/domain/references/common"
ere "simrs-vx/internal/domain/references/encounter"
- 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"
+ dg "github.com/karincake/apem/db-gorm-pg"
+ d "github.com/karincake/dodol"
+
"gorm.io/gorm"
)
@@ -393,6 +395,7 @@ func CheckOut(input e.DischargeDto) (*d.Data, error) {
}
return pl.SetLogError(&event, input)
}
+
if err := checkSoapiByDocExists(data.Id, &event, tx); err != nil {
return err
}
@@ -411,6 +414,19 @@ func CheckOut(input e.DischargeDto) (*d.Data, error) {
}
}
+ switch *input.Discharge_Method_Code {
+ case ere.DMCDeath:
+ // insert data death-cause
+ if _, err = udc.CreateData(edc.CreateDto{Encounter_Id: &input.Id, Value: input.DeathCause}, &event, tx); err != nil {
+ return err
+ }
+ case ere.DMCConsulPoly, ere.DMCConsulExecutive:
+ // bulk insert internal-references
+ if err = createInternalReferences(input, &event, tx); err != nil {
+ return err
+ }
+ }
+
pl.SetLogInfo(&event, nil, "complete")
return nil
diff --git a/internal/use-case/main-use-case/encounter/helper.go b/internal/use-case/main-use-case/encounter/helper.go
index 34e076f1..41fd6a51 100644
--- a/internal/use-case/main-use-case/encounter/helper.go
+++ b/internal/use-case/main-use-case/encounter/helper.go
@@ -7,7 +7,9 @@ package encounter
import (
"errors"
"fmt"
+ uir "simrs-vx/internal/use-case/main-use-case/internal-reference"
"strings"
+ "time"
"gorm.io/gorm"
@@ -15,6 +17,7 @@ import (
pu "simrs-vx/pkg/use-case-helper"
edo "simrs-vx/internal/domain/main-entities/device-order"
+ ed "simrs-vx/internal/domain/main-entities/doctor"
emo "simrs-vx/internal/domain/main-entities/material-order"
emco "simrs-vx/internal/domain/main-entities/mcu-order"
em "simrs-vx/internal/domain/main-entities/medication"
@@ -23,6 +26,7 @@ import (
emmi "simrs-vx/internal/domain/main-entities/medicine-mix-item"
ep "simrs-vx/internal/domain/main-entities/prescription"
epi "simrs-vx/internal/domain/main-entities/prescription-item"
+ eu "simrs-vx/internal/domain/main-entities/unit"
// udo "simrs-vx/internal/use-case/main-use-case/device-order"
es "simrs-vx/internal/domain/main-entities/soapi"
@@ -77,12 +81,15 @@ func setDataUpdate(src e.UpdateDto, dst *e.Encounter) {
}
func setDataDischarge(src e.DischargeDto, dst *e.Encounter) {
- dst.Discharge_Method_Code = src.DischargeMethod_Code
+ dst.Discharge_Method_Code = src.Discharge_Method_Code
dst.EarlyEducation = src.EarlyEducation
dst.MedicalDischargeEducation = src.MedicalDischargeEducation
dst.AdmDischargeEducation = src.AdmDischargeEducation
dst.DischargeReason = src.DischargeReason
dst.Status_Code = erc.DSCDone
+
+ now := time.Now()
+ dst.Discharge_Date = &now
}
func checkSoapiByDocExists(encounter_id uint, event *pl.Event, tx *gorm.DB) error {
@@ -135,7 +142,9 @@ func createMedication(encounter_id uint, event *pl.Event, tx *gorm.DB) error {
return err
}
- prescriptionItem, _, err := upi.ReadListData(epi.ReadListDto{FilterDto: epi.FilterDto{Prescription_Id: &prescription.Id}}, event, tx)
+ prescriptionItem, _, err := upi.ReadListData(epi.ReadListDto{
+ FilterDto: epi.FilterDto{Prescription_Id: &prescription.Id},
+ Includes: "medicineMix,medicineMix-MixItems"}, event, tx)
if err != nil {
return err
}
@@ -317,3 +326,97 @@ func getMcuOrders(encounter_id uint, event *pl.Event, tx *gorm.DB) error {
func setDataUpdateStatus(src e.UpdateStatusDto, dst *e.Encounter) {
dst.Status_Code = src.StatusCode
}
+
+func createInternalReferences(input e.DischargeDto, event *pl.Event, tx *gorm.DB) error {
+ unitIDs := make(map[uint16]struct{})
+ doctorIDs := make(map[uint]struct{})
+
+ for _, ref := range *input.InternalReferences {
+ if ref.Unit_Id != nil {
+ unitIDs[*ref.Unit_Id] = struct{}{}
+ }
+ if ref.Doctor_Id != nil {
+ doctorIDs[*ref.Doctor_Id] = struct{}{}
+ }
+ }
+
+ // validate unitIds
+ if len(unitIDs) > 0 {
+ var ids []uint16
+ for id := range unitIDs {
+ ids = append(ids, id)
+ }
+
+ units, err := getUnits(ids, event, tx)
+ if err != nil {
+ return fmt.Errorf("failed to fetch units: %w", err)
+ }
+ if len(units) != len(ids) {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-validation-fail",
+ Detail: "unit_id not found",
+ }
+ return pl.SetLogError(event, nil)
+ }
+ }
+
+ // validate doctorIds
+ if len(doctorIDs) > 0 {
+ var ids []uint
+ for id := range doctorIDs {
+ ids = append(ids, id)
+ }
+
+ doctors, err := getDoctors(ids, event, tx)
+ if err != nil {
+ return fmt.Errorf("failed to fetch doctors: %w", err)
+ }
+ if len(doctors) != len(ids) {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-validation-fail",
+ Detail: "doctor_id not found",
+ }
+ return pl.SetLogError(event, nil)
+ }
+ }
+
+ if err := uir.CreateBulkData(*input.InternalReferences, input.Id, event, tx); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func getUnits(unitIds []uint16, event *pl.Event, tx *gorm.DB) ([]eu.Unit, error) {
+ pl.SetLogInfo(event, nil, "started", "getUnits")
+ var units []eu.Unit
+ err := tx.Where("\"Id\" IN ?", unitIds).Find(&units).Error
+ if err != nil {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-get-fail",
+ Detail: "get units",
+ Raw: err,
+ }
+ return nil, pl.SetLogError(event, nil)
+ }
+ return units, nil
+}
+
+func getDoctors(doctorIds []uint, event *pl.Event, tx *gorm.DB) ([]ed.Doctor, error) {
+ pl.SetLogInfo(event, nil, "started", "getDoctors")
+ var doctors []ed.Doctor
+ err := tx.Where("\"Id\" IN ?", doctorIds).Find(&doctors).Error
+ if err != nil {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-get-fail",
+ Detail: "get doctors",
+ Raw: err,
+ }
+ return nil, pl.SetLogError(event, nil)
+ }
+ return doctors, nil
+}
diff --git a/internal/use-case/main-use-case/installation-position/case.go b/internal/use-case/main-use-case/installation-position/case.go
new file mode 100644
index 00000000..f9458c0b
--- /dev/null
+++ b/internal/use-case/main-use-case/installation-position/case.go
@@ -0,0 +1,302 @@
+package installation_position
+
+import (
+ ee "simrs-vx/internal/domain/main-entities/employee"
+ ei "simrs-vx/internal/domain/main-entities/installation"
+ e "simrs-vx/internal/domain/main-entities/installation-position"
+ "strconv"
+
+ ue "simrs-vx/internal/use-case/main-use-case/employee"
+ ui "simrs-vx/internal/use-case/main-use-case/installation"
+
+ 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 = "installation-position"
+
+func Create(input e.CreateDto) (*d.Data, error) {
+ data := e.InstallationPosition{}
+
+ 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 err := validateForeignKey(input); 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.InstallationPosition
+ var dataList []e.InstallationPosition
+ 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.InstallationPosition
+ 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.InstallationPosition
+ 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 := validateForeignKey(input.CreateDto); 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.InstallationPosition
+ 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
+
+}
+
+func validateForeignKey(input e.CreateDto) error {
+ // validate installation_id
+ if _, err := ui.ReadDetail(ei.ReadDetailDto{Id: *input.Installation_Id}); err != nil {
+ return err
+ }
+
+ // validate employee_Id
+ if _, err := ue.ReadDetail(ee.ReadDetailDto{Id: uint16(*input.Employee_Id)}); err != nil {
+ return err
+ }
+ return nil
+}
diff --git a/internal/use-case/main-use-case/installation-position/helper.go b/internal/use-case/main-use-case/installation-position/helper.go
new file mode 100644
index 00000000..640993c8
--- /dev/null
+++ b/internal/use-case/main-use-case/installation-position/helper.go
@@ -0,0 +1,25 @@
+/*
+DESCRIPTION:
+Any functions that are used internally by the use-case
+*/
+package installation_position
+
+import (
+ e "simrs-vx/internal/domain/main-entities/installation-position"
+)
+
+func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.InstallationPosition) {
+ var inputSrc *e.CreateDto
+ if inputT, ok := any(input).(*e.CreateDto); ok {
+ inputSrc = inputT
+ } else {
+ inputTemp := any(input).(*e.UpdateDto)
+ inputSrc = &inputTemp.CreateDto
+ }
+
+ data.Installation_Id = inputSrc.Installation_Id
+ data.Code = inputSrc.Code
+ data.Name = inputSrc.Name
+ data.HeadStatus = inputSrc.HeadStatus
+ data.Employee_Id = inputSrc.Employee_Id
+}
diff --git a/internal/use-case/main-use-case/installation-position/lib.go b/internal/use-case/main-use-case/installation-position/lib.go
new file mode 100644
index 00000000..bb33356f
--- /dev/null
+++ b/internal/use-case/main-use-case/installation-position/lib.go
@@ -0,0 +1,156 @@
+package installation_position
+
+import (
+ "errors"
+ e "simrs-vx/internal/domain/main-entities/installation-position"
+
+ 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.InstallationPosition, error) {
+ pl.SetLogInfo(event, nil, "started", "DBCreate")
+
+ data := e.InstallationPosition{}
+ 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.InstallationPosition, *e.MetaDto, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadList")
+ data := []e.InstallationPosition{}
+ 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.InstallationPosition{}).
+ 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 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.InstallationPosition, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadDetail")
+ data := e.InstallationPosition{}
+
+ var tx, getData *gorm.DB
+ if len(dbx) > 0 {
+ tx = dbx[0]
+ } else {
+ tx = dg.I
+ }
+
+ switch {
+ case input.Id != 0:
+ getData = tx.First(&data, input.Id)
+ case input.Code != nil && *input.Code != "":
+ getData = tx.Where("code = ?", *input.Code).First(&data)
+ default:
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-read-detail-fail",
+ Detail: "either Id or Code must be provided",
+ }
+
+ return nil, pl.SetLogError(event, nil)
+ }
+
+ if err := getData.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.InstallationPosition, 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.InstallationPosition, 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/installation-position/middleware-runner.go b/internal/use-case/main-use-case/installation-position/middleware-runner.go
new file mode 100644
index 00000000..f59aedd9
--- /dev/null
+++ b/internal/use-case/main-use-case/installation-position/middleware-runner.go
@@ -0,0 +1,103 @@
+package installation_position
+
+import (
+ e "simrs-vx/internal/domain/main-entities/installation-position"
+ 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.InstallationPosition) 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.InstallationPosition) 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.InstallationPosition) 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.InstallationPosition) 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.InstallationPosition) 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/installation-position/middleware.go b/internal/use-case/main-use-case/installation-position/middleware.go
new file mode 100644
index 00000000..ed9aac6e
--- /dev/null
+++ b/internal/use-case/main-use-case/installation-position/middleware.go
@@ -0,0 +1,9 @@
+package installation_position
+
+// 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/installation-position/tycovar.go b/internal/use-case/main-use-case/installation-position/tycovar.go
new file mode 100644
index 00000000..38807df3
--- /dev/null
+++ b/internal/use-case/main-use-case/installation-position/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 installation_position
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/main-entities/installation-position"
+)
+
+type createMw struct {
+ Name string
+ Func func(input *e.CreateDto, data *e.InstallationPosition, tx *gorm.DB) error
+}
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.InstallationPosition, tx *gorm.DB) error
+}
+
+type readDetailMw struct {
+ Name string
+ Func func(input *e.ReadDetailDto, data *e.InstallationPosition, 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/installation/lib.go b/internal/use-case/main-use-case/installation/lib.go
index fd0158ee..82130c32 100644
--- a/internal/use-case/main-use-case/installation/lib.go
+++ b/internal/use-case/main-use-case/installation/lib.go
@@ -81,7 +81,9 @@ 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/internal/use-case/main-use-case/internal-reference/case.go b/internal/use-case/main-use-case/internal-reference/case.go
index 1681bf26..bfd9550f 100644
--- a/internal/use-case/main-use-case/internal-reference/case.go
+++ b/internal/use-case/main-use-case/internal-reference/case.go
@@ -1,19 +1,9 @@
package internal_reference
import (
-
- // main entities
- ed "simrs-vx/internal/domain/main-entities/doctor"
- ee "simrs-vx/internal/domain/main-entities/encounter"
eir "simrs-vx/internal/domain/main-entities/internal-reference"
- eu "simrs-vx/internal/domain/main-entities/unit"
"strconv"
- // main use case
- ud "simrs-vx/internal/use-case/main-use-case/doctor"
- ue "simrs-vx/internal/use-case/main-use-case/encounter"
- uu "simrs-vx/internal/use-case/main-use-case/unit"
-
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -43,11 +33,6 @@ func Create(input eir.CreateDto) (*d.Data, error) {
return err
}
- // Validate Request
- if err := validateRequest(input); err != nil {
- return err
- }
-
if resData, err := CreateData(input, &event, tx); err != nil {
return err
} else {
@@ -179,29 +164,6 @@ func ReadDetail(input eir.ReadDetailDto) (*d.Data, error) {
}, nil
}
-func validateRequest(input eir.CreateDto) (err error) {
-
- // Validate Encounter Id
- _, err = ue.ReadDetail(ee.ReadDetailDto{Id: uint16(*input.Encounter_Id)})
- if err != nil {
- return err
- }
-
- // Validate Unit Id
- _, err = uu.ReadDetail(eu.ReadDetailDto{Id: *input.Unit_Id})
- if err != nil {
- return err
- }
-
- // Validate Doctor Id
- _, err = ud.ReadDetail(ed.ReadDetailDto{Id: uint16(*input.Doctor_Id)})
- if err != nil {
- return err
- }
-
- return
-}
-
func Update(input eir.UpdateDto) (*d.Data, error) {
rdDto := eir.ReadDetailDto{Id: input.Id}
var data *eir.InternalReference
@@ -228,21 +190,10 @@ func Update(input eir.UpdateDto) (*d.Data, error) {
return err
}
- // Validate Request
- if err := validateRequest(input.CreateDto); err != nil {
- return err
- }
-
if err := UpdateData(input, data, &event, tx); err != nil {
return err
}
- // Get Updated Data
- rdDto.Includes = "encounter,unit,doctor"
- if data, err = ReadDetailData(rdDto, &event, tx); err != nil {
- return err
- }
-
pl.SetLogInfo(&event, nil, "complete")
mwRunner.setMwType(pu.MWTPost)
diff --git a/internal/use-case/main-use-case/internal-reference/helper.go b/internal/use-case/main-use-case/internal-reference/helper.go
index aaef382a..dbd92f73 100644
--- a/internal/use-case/main-use-case/internal-reference/helper.go
+++ b/internal/use-case/main-use-case/internal-reference/helper.go
@@ -21,3 +21,17 @@ func setData[T *ir.CreateDto | *ir.UpdateDto](input T, data *ir.InternalReferenc
data.Unit_Id = inputSrc.Unit_Id
data.Doctor_Id = inputSrc.Doctor_Id
}
+
+func setBulkData(input []ir.CreateDto, encounterId uint) []ir.InternalReference {
+ var data []ir.InternalReference
+
+ for _, v := range input {
+ data = append(data, ir.InternalReference{
+ Encounter_Id: &encounterId,
+ Unit_Id: v.Unit_Id,
+ Doctor_Id: v.Doctor_Id,
+ })
+ }
+
+ return data
+}
diff --git a/internal/use-case/main-use-case/internal-reference/lib.go b/internal/use-case/main-use-case/internal-reference/lib.go
index a50d594c..bf852dc6 100644
--- a/internal/use-case/main-use-case/internal-reference/lib.go
+++ b/internal/use-case/main-use-case/internal-reference/lib.go
@@ -142,3 +142,23 @@ func DeleteData(data *eir.InternalReference, event *pl.Event, dbx ...*gorm.DB) e
pl.SetLogInfo(event, nil, "complete")
return nil
}
+
+func CreateBulkData(input []eir.CreateDto, encounterId uint, event *pl.Event, dbx ...*gorm.DB) error {
+ pl.SetLogInfo(event, nil, "started", "DBCreate")
+
+ data := setBulkData(input, encounterId)
+
+ var tx *gorm.DB
+ if len(dbx) > 0 {
+ tx = dbx[0]
+ } else {
+ tx = dg.I
+ }
+
+ if err := tx.Create(&data).Error; err != nil {
+ return plh.HandleCreateError(input, event, err)
+ }
+
+ pl.SetLogInfo(event, nil, "complete")
+ return nil
+}
diff --git a/internal/use-case/main-use-case/laborant/helper.go b/internal/use-case/main-use-case/laborant/helper.go
index 8619f7e6..8a053b90 100644
--- a/internal/use-case/main-use-case/laborant/helper.go
+++ b/internal/use-case/main-use-case/laborant/helper.go
@@ -17,6 +17,7 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Laborant) {
inputSrc = &inputTemp.CreateDto
}
+ data.Code = inputSrc.Code
data.Employee_Id = inputSrc.Employee_Id
data.IHS_Number = inputSrc.IHS_Number
}
diff --git a/internal/use-case/main-use-case/midwife/helper.go b/internal/use-case/main-use-case/midwife/helper.go
index 5be74b86..e63f0e6f 100644
--- a/internal/use-case/main-use-case/midwife/helper.go
+++ b/internal/use-case/main-use-case/midwife/helper.go
@@ -17,6 +17,7 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Midwife) {
inputSrc = &inputTemp.CreateDto
}
+ data.Code = inputSrc.Code
data.Employee_Id = inputSrc.Employee_Id
data.IHS_Number = inputSrc.IHS_Number
}
diff --git a/internal/use-case/main-use-case/nurse/helper.go b/internal/use-case/main-use-case/nurse/helper.go
index 5ecb6f20..003230b3 100644
--- a/internal/use-case/main-use-case/nurse/helper.go
+++ b/internal/use-case/main-use-case/nurse/helper.go
@@ -17,6 +17,7 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Nurse) {
inputSrc = &inputTemp.CreateDto
}
+ data.Code = inputSrc.Code
data.Employee_Id = inputSrc.Employee_Id
data.IHS_Number = inputSrc.IHS_Number
data.Unit_Id = inputSrc.Unit_Id
diff --git a/internal/use-case/main-use-case/nutritionist/helper.go b/internal/use-case/main-use-case/nutritionist/helper.go
index 4ff20809..028b2dc3 100644
--- a/internal/use-case/main-use-case/nutritionist/helper.go
+++ b/internal/use-case/main-use-case/nutritionist/helper.go
@@ -17,6 +17,7 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Nutritionist) {
inputSrc = &inputTemp.CreateDto
}
+ data.Code = inputSrc.Code
data.Employee_Id = inputSrc.Employee_Id
data.IHS_Number = inputSrc.IHS_Number
}
diff --git a/internal/use-case/main-use-case/patient/case.go b/internal/use-case/main-use-case/patient/case.go
index fd17d7fb..b52215ac 100644
--- a/internal/use-case/main-use-case/patient/case.go
+++ b/internal/use-case/main-use-case/patient/case.go
@@ -352,18 +352,18 @@ func Delete(input e.DeleteDto) (*d.Data, error) {
}
-func Search(input e.SearchDto) (*d.Data, error) {
+func SearchByResidentIdentityNumber(input e.SearchDto) (*d.Data, error) {
var data *e.Patient
var err error
event := pl.Event{
- Feature: "Search",
+ Feature: "Search By Resident Identity Number",
Source: source,
}
// Start log
pl.SetLogInfo(&event, input, "started", "search")
- if data, err = SearchData(input, &event); err != nil {
+ if data, err = SearchDataByRIN(input, &event); err != nil {
return nil, err
}
@@ -377,6 +377,46 @@ func Search(input e.SearchDto) (*d.Data, error) {
}, nil
}
+func Search(input e.SearchDto) (*d.Data, error) {
+ var dataList []e.Patient
+ var metaList *e.MetaDto
+ var err error
+
+ event := pl.Event{
+ Feature: "Search",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "readList")
+
+ err = dg.I.Transaction(func(tx *gorm.DB) error {
+
+ if dataList, metaList, err = SearchData(input, &event, tx); err != nil {
+ return err
+ }
+
+ return nil
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &d.Data{
+ Meta: d.IS{
+ "source": source,
+ "structure": "list-data",
+ "status": "fetched",
+ "page_number": strconv.Itoa(metaList.PageNumber),
+ "page_size": strconv.Itoa(metaList.PageSize),
+ "record_totalCount": strconv.Itoa(metaList.Count),
+ "record_currentCount": strconv.Itoa(len(dataList)),
+ },
+ Data: e.ToResponseList(dataList),
+ }, nil
+}
+
func Upload(input e.UploadDto) (*d.Data, error) {
rdDto := e.ReadDetailDto{Id: uint16(input.Id)}
var data *e.Patient
diff --git a/internal/use-case/main-use-case/patient/lib.go b/internal/use-case/main-use-case/patient/lib.go
index f35e3853..36c9d416 100644
--- a/internal/use-case/main-use-case/patient/lib.go
+++ b/internal/use-case/main-use-case/patient/lib.go
@@ -154,11 +154,11 @@ func DeleteData(data *e.Patient, event *pl.Event, dbx ...*gorm.DB) error {
return nil
}
-func SearchData(input e.SearchDto, event *pl.Event, dbx ...*gorm.DB) (*e.Patient, error) {
+// Search By Resident Identity Number
+func SearchDataByRIN(input e.SearchDto, event *pl.Event, dbx ...*gorm.DB) (*e.Patient, error) {
pl.SetLogInfo(event, input, "started", "DBSearch")
- var patient e.Patient
- var err error
+ var data e.Patient
var tx *gorm.DB
if len(dbx) > 0 {
@@ -174,27 +174,60 @@ func SearchData(input e.SearchDto, event *pl.Event, dbx ...*gorm.DB) (*e.Patient
Preload("Person.Relatives").
Preload("Person.Insurances")
- switch input.Mode {
- case e.SMIdent:
- // Search by patient number OR person's resident identity number (exact match) OR person's name (partial match)
- err = tx.Joins("JOIN \"Person\" ON \"Patient\".\"Person_Id\" = \"Person\".\"Id\"").
- Where("\"Patient\".\"Number\" = ? OR \"Person\".\"ResidentIdentityNumber\" = ? OR \"Person\".\"Name\" ILIKE ?",
- input.Search, input.Search, "%"+input.Search+"%").
- First(&patient).Error
- case e.SMNik:
- // Search by patient person's resident identity number (exact match)
- err = tx.Joins("JOIN \"Person\" ON \"Patient\".\"Person_Id\" = \"Person\".\"Id\"").
- Where("\"Person\".\"ResidentIdentityNumber\" = ?",
- input.Search).
- First(&patient).Error
- }
+ // Search by patient person's resident identity number (exact match)
+ err := tx.Joins("JOIN \"Person\" ON \"Patient\".\"Person_Id\" = \"Person\".\"Id\"").
+ Where("\"Person\".\"ResidentIdentityNumber\" = ?",
+ input.Search).
+ First(&data).Error
if err != nil {
- if processedErr := pu.HandleSearchError(err, event, source, input.Search, patient); processedErr != nil {
+ if processedErr := pu.HandleSearchError(err, event, source, input.Search, data); processedErr != nil {
return nil, processedErr
}
}
pl.SetLogInfo(event, nil, "complete")
- return &patient, nil
+ return &data, nil
+}
+
+func SearchData(input e.SearchDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Patient, *e.MetaDto, error) {
+ pl.SetLogInfo(event, input, "started", "DBSearch")
+
+ var data []e.Patient
+ pagination := gh.Pagination{}
+ count := int64(0)
+ meta := e.MetaDto{}
+
+ var tx *gorm.DB
+ if len(dbx) > 0 {
+ tx = dbx[0]
+ } else {
+ tx = dg.I
+ }
+
+ // Preload associations for complete data
+ tx = tx.Preload(clause.Associations)
+ tx = tx.Preload("Person.Addresses").
+ Preload("Person.Contacts").
+ Preload("Person.Relatives").
+ Preload("Person.Insurances")
+
+ // Search by patient number OR person's resident identity number (exact match) OR person's name (partial match)
+ tx = tx.Joins("JOIN \"Person\" ON \"Patient\".\"Person_Id\" = \"Person\".\"Id\"").
+ Where("\"Patient\".\"Number\" ILIKE ? OR \"Person\".\"ResidentIdentityNumber\" ILIKE ? OR \"Person\".\"Name\" ILIKE ?",
+ "%"+input.Search+"%", "%"+input.Search+"%", "%"+input.Search+"%")
+ err := tx.Scopes(gh.Paginate(input, &pagination)).Find(&data).Error
+
+ if err != nil {
+ if processedErr := pu.HandleSearchError(err, event, source, input.Search, data); processedErr != nil {
+ return nil, nil, processedErr
+ }
+ }
+
+ meta.Count = int(count)
+ meta.PageNumber = pagination.PageNumber
+ meta.PageSize = pagination.PageSize
+
+ pl.SetLogInfo(event, nil, "complete")
+ return data, &meta, nil
}
diff --git a/internal/use-case/main-use-case/pharmacist/helper.go b/internal/use-case/main-use-case/pharmacist/helper.go
index deb230cf..c17fa8a2 100644
--- a/internal/use-case/main-use-case/pharmacist/helper.go
+++ b/internal/use-case/main-use-case/pharmacist/helper.go
@@ -17,6 +17,7 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Pharmacist) {
inputSrc = &inputTemp.CreateDto
}
+ data.Code = inputSrc.Code
data.Employee_Id = inputSrc.Employee_Id
data.IHS_Number = inputSrc.IHS_Number
}
diff --git a/internal/use-case/main-use-case/specialist-position/case.go b/internal/use-case/main-use-case/specialist-position/case.go
new file mode 100644
index 00000000..c3c469e6
--- /dev/null
+++ b/internal/use-case/main-use-case/specialist-position/case.go
@@ -0,0 +1,302 @@
+package specialist_position
+
+import (
+ ee "simrs-vx/internal/domain/main-entities/employee"
+ es "simrs-vx/internal/domain/main-entities/specialist"
+ e "simrs-vx/internal/domain/main-entities/specialist-position"
+ "strconv"
+
+ ue "simrs-vx/internal/use-case/main-use-case/employee"
+ us "simrs-vx/internal/use-case/main-use-case/specialist"
+
+ 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 = "specialist-position"
+
+func Create(input e.CreateDto) (*d.Data, error) {
+ data := e.SpecialistPosition{}
+
+ 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 err := validateForeignKey(input); 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.SpecialistPosition
+ var dataList []e.SpecialistPosition
+ 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.SpecialistPosition
+ 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.SpecialistPosition
+ 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 := validateForeignKey(input.CreateDto); 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.SpecialistPosition
+ 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
+
+}
+
+func validateForeignKey(input e.CreateDto) error {
+ // validate installation_id
+ if _, err := us.ReadDetail(es.ReadDetailDto{Id: *input.Specialist_Id}); err != nil {
+ return err
+ }
+
+ // validate employee_Id
+ if _, err := ue.ReadDetail(ee.ReadDetailDto{Id: uint16(*input.Employee_Id)}); err != nil {
+ return err
+ }
+ return nil
+}
diff --git a/internal/use-case/main-use-case/specialist-position/helper.go b/internal/use-case/main-use-case/specialist-position/helper.go
new file mode 100644
index 00000000..6c3d6434
--- /dev/null
+++ b/internal/use-case/main-use-case/specialist-position/helper.go
@@ -0,0 +1,25 @@
+/*
+DESCRIPTION:
+Any functions that are used internally by the use-case
+*/
+package specialist_position
+
+import (
+ e "simrs-vx/internal/domain/main-entities/specialist-position"
+)
+
+func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.SpecialistPosition) {
+ var inputSrc *e.CreateDto
+ if inputT, ok := any(input).(*e.CreateDto); ok {
+ inputSrc = inputT
+ } else {
+ inputTemp := any(input).(*e.UpdateDto)
+ inputSrc = &inputTemp.CreateDto
+ }
+
+ data.Specialist_Id = inputSrc.Specialist_Id
+ data.Code = inputSrc.Code
+ data.Name = inputSrc.Name
+ data.HeadStatus = inputSrc.HeadStatus
+ data.Employee_Id = inputSrc.Employee_Id
+}
diff --git a/internal/use-case/main-use-case/specialist-position/lib.go b/internal/use-case/main-use-case/specialist-position/lib.go
new file mode 100644
index 00000000..3ae54f50
--- /dev/null
+++ b/internal/use-case/main-use-case/specialist-position/lib.go
@@ -0,0 +1,156 @@
+package specialist_position
+
+import (
+ "errors"
+ e "simrs-vx/internal/domain/main-entities/specialist-position"
+
+ 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.SpecialistPosition, error) {
+ pl.SetLogInfo(event, nil, "started", "DBCreate")
+
+ data := e.SpecialistPosition{}
+ 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.SpecialistPosition, *e.MetaDto, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadList")
+ data := []e.SpecialistPosition{}
+ 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.SpecialistPosition{}).
+ 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 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.SpecialistPosition, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadDetail")
+ data := e.SpecialistPosition{}
+
+ var tx, getData *gorm.DB
+ if len(dbx) > 0 {
+ tx = dbx[0]
+ } else {
+ tx = dg.I
+ }
+
+ switch {
+ case input.Id != 0:
+ getData = tx.First(&data, input.Id)
+ case input.Code != nil && *input.Code != "":
+ getData = tx.Where("code = ?", *input.Code).First(&data)
+ default:
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-read-detail-fail",
+ Detail: "either Id or Code must be provided",
+ }
+
+ return nil, pl.SetLogError(event, nil)
+ }
+
+ if err := getData.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.SpecialistPosition, 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.SpecialistPosition, 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/specialist-position/middleware-runner.go b/internal/use-case/main-use-case/specialist-position/middleware-runner.go
new file mode 100644
index 00000000..cade8cf9
--- /dev/null
+++ b/internal/use-case/main-use-case/specialist-position/middleware-runner.go
@@ -0,0 +1,103 @@
+package specialist_position
+
+import (
+ e "simrs-vx/internal/domain/main-entities/specialist-position"
+ 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.SpecialistPosition) 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.SpecialistPosition) 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.SpecialistPosition) 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.SpecialistPosition) 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.SpecialistPosition) 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/specialist-position/middleware.go b/internal/use-case/main-use-case/specialist-position/middleware.go
new file mode 100644
index 00000000..9e3bc169
--- /dev/null
+++ b/internal/use-case/main-use-case/specialist-position/middleware.go
@@ -0,0 +1,9 @@
+package specialist_position
+
+// 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/specialist-position/tycovar.go b/internal/use-case/main-use-case/specialist-position/tycovar.go
new file mode 100644
index 00000000..4cf93b3b
--- /dev/null
+++ b/internal/use-case/main-use-case/specialist-position/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 specialist_position
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/main-entities/specialist-position"
+)
+
+type createMw struct {
+ Name string
+ Func func(input *e.CreateDto, data *e.SpecialistPosition, tx *gorm.DB) error
+}
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.SpecialistPosition, tx *gorm.DB) error
+}
+
+type readDetailMw struct {
+ Name string
+ Func func(input *e.ReadDetailDto, data *e.SpecialistPosition, 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/specialist/lib.go b/internal/use-case/main-use-case/specialist/lib.go
index 10f62ced..3e35d004 100644
--- a/internal/use-case/main-use-case/specialist/lib.go
+++ b/internal/use-case/main-use-case/specialist/lib.go
@@ -81,7 +81,9 @@ 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/internal/use-case/main-use-case/subspecialist-position/case.go b/internal/use-case/main-use-case/subspecialist-position/case.go
new file mode 100644
index 00000000..d954427a
--- /dev/null
+++ b/internal/use-case/main-use-case/subspecialist-position/case.go
@@ -0,0 +1,302 @@
+package subspecialist_position
+
+import (
+ ee "simrs-vx/internal/domain/main-entities/employee"
+ es "simrs-vx/internal/domain/main-entities/subspecialist"
+ e "simrs-vx/internal/domain/main-entities/subspecialist-position"
+ "strconv"
+
+ ue "simrs-vx/internal/use-case/main-use-case/employee"
+ us "simrs-vx/internal/use-case/main-use-case/subspecialist"
+
+ 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 = "subspecialist-position"
+
+func Create(input e.CreateDto) (*d.Data, error) {
+ data := e.SubspecialistPosition{}
+
+ 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 err := validateForeignKey(input); 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.SubspecialistPosition
+ var dataList []e.SubspecialistPosition
+ 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.SubspecialistPosition
+ 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.SubspecialistPosition
+ 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 := validateForeignKey(input.CreateDto); 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.SubspecialistPosition
+ 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
+
+}
+
+func validateForeignKey(input e.CreateDto) error {
+ // validate installation_id
+ if _, err := us.ReadDetail(es.ReadDetailDto{Id: *input.Subspecialist_Id}); err != nil {
+ return err
+ }
+
+ // validate employee_Id
+ if _, err := ue.ReadDetail(ee.ReadDetailDto{Id: uint16(*input.Employee_Id)}); err != nil {
+ return err
+ }
+ return nil
+}
diff --git a/internal/use-case/main-use-case/subspecialist-position/helper.go b/internal/use-case/main-use-case/subspecialist-position/helper.go
new file mode 100644
index 00000000..1f4c9b2b
--- /dev/null
+++ b/internal/use-case/main-use-case/subspecialist-position/helper.go
@@ -0,0 +1,25 @@
+/*
+DESCRIPTION:
+Any functions that are used internally by the use-case
+*/
+package subspecialist_position
+
+import (
+ e "simrs-vx/internal/domain/main-entities/subspecialist-position"
+)
+
+func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.SubspecialistPosition) {
+ var inputSrc *e.CreateDto
+ if inputT, ok := any(input).(*e.CreateDto); ok {
+ inputSrc = inputT
+ } else {
+ inputTemp := any(input).(*e.UpdateDto)
+ inputSrc = &inputTemp.CreateDto
+ }
+
+ data.Subspecialist_Id = inputSrc.Subspecialist_Id
+ data.Code = inputSrc.Code
+ data.Name = inputSrc.Name
+ data.HeadStatus = inputSrc.HeadStatus
+ data.Employee_Id = inputSrc.Employee_Id
+}
diff --git a/internal/use-case/main-use-case/subspecialist-position/lib.go b/internal/use-case/main-use-case/subspecialist-position/lib.go
new file mode 100644
index 00000000..136e982e
--- /dev/null
+++ b/internal/use-case/main-use-case/subspecialist-position/lib.go
@@ -0,0 +1,156 @@
+package subspecialist_position
+
+import (
+ "errors"
+ e "simrs-vx/internal/domain/main-entities/subspecialist-position"
+
+ 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.SubspecialistPosition, error) {
+ pl.SetLogInfo(event, nil, "started", "DBCreate")
+
+ data := e.SubspecialistPosition{}
+ 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.SubspecialistPosition, *e.MetaDto, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadList")
+ data := []e.SubspecialistPosition{}
+ 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.SubspecialistPosition{}).
+ 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 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.SubspecialistPosition, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadDetail")
+ data := e.SubspecialistPosition{}
+
+ var tx, getData *gorm.DB
+ if len(dbx) > 0 {
+ tx = dbx[0]
+ } else {
+ tx = dg.I
+ }
+
+ switch {
+ case input.Id != 0:
+ getData = tx.First(&data, input.Id)
+ case input.Code != nil && *input.Code != "":
+ getData = tx.Where("code = ?", *input.Code).First(&data)
+ default:
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-read-detail-fail",
+ Detail: "either Id or Code must be provided",
+ }
+
+ return nil, pl.SetLogError(event, nil)
+ }
+
+ if err := getData.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.SubspecialistPosition, 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.SubspecialistPosition, 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/subspecialist-position/middleware-runner.go b/internal/use-case/main-use-case/subspecialist-position/middleware-runner.go
new file mode 100644
index 00000000..66c3d013
--- /dev/null
+++ b/internal/use-case/main-use-case/subspecialist-position/middleware-runner.go
@@ -0,0 +1,103 @@
+package subspecialist_position
+
+import (
+ e "simrs-vx/internal/domain/main-entities/subspecialist-position"
+ 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.SubspecialistPosition) 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.SubspecialistPosition) 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.SubspecialistPosition) 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.SubspecialistPosition) 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.SubspecialistPosition) 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/subspecialist-position/middleware.go b/internal/use-case/main-use-case/subspecialist-position/middleware.go
new file mode 100644
index 00000000..e7cafc86
--- /dev/null
+++ b/internal/use-case/main-use-case/subspecialist-position/middleware.go
@@ -0,0 +1,9 @@
+package subspecialist_position
+
+// 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/subspecialist-position/tycovar.go b/internal/use-case/main-use-case/subspecialist-position/tycovar.go
new file mode 100644
index 00000000..e2cd8acd
--- /dev/null
+++ b/internal/use-case/main-use-case/subspecialist-position/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 subspecialist_position
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/main-entities/subspecialist-position"
+)
+
+type createMw struct {
+ Name string
+ Func func(input *e.CreateDto, data *e.SubspecialistPosition, tx *gorm.DB) error
+}
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.SubspecialistPosition, tx *gorm.DB) error
+}
+
+type readDetailMw struct {
+ Name string
+ Func func(input *e.ReadDetailDto, data *e.SubspecialistPosition, 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/subspecialist/lib.go b/internal/use-case/main-use-case/subspecialist/lib.go
index 5843086f..46ec11f2 100644
--- a/internal/use-case/main-use-case/subspecialist/lib.go
+++ b/internal/use-case/main-use-case/subspecialist/lib.go
@@ -81,7 +81,9 @@ 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/internal/use-case/main-use-case/unit-position/case.go b/internal/use-case/main-use-case/unit-position/case.go
new file mode 100644
index 00000000..f3bd2840
--- /dev/null
+++ b/internal/use-case/main-use-case/unit-position/case.go
@@ -0,0 +1,302 @@
+package unit_position
+
+import (
+ ee "simrs-vx/internal/domain/main-entities/employee"
+ eu "simrs-vx/internal/domain/main-entities/unit"
+ e "simrs-vx/internal/domain/main-entities/unit-position"
+ "strconv"
+
+ ue "simrs-vx/internal/use-case/main-use-case/employee"
+ uu "simrs-vx/internal/use-case/main-use-case/unit"
+
+ 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 = "unit-position"
+
+func Create(input e.CreateDto) (*d.Data, error) {
+ data := e.UnitPosition{}
+
+ 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 err := validateForeignKey(input); 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.UnitPosition
+ var dataList []e.UnitPosition
+ 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.UnitPosition
+ 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.UnitPosition
+ 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 := validateForeignKey(input.CreateDto); 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.UnitPosition
+ 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
+
+}
+
+func validateForeignKey(input e.CreateDto) error {
+ // validate installation_id
+ if _, err := uu.ReadDetail(eu.ReadDetailDto{Id: *input.Unit_Id}); err != nil {
+ return err
+ }
+
+ // validate employee_Id
+ if _, err := ue.ReadDetail(ee.ReadDetailDto{Id: uint16(*input.Employee_Id)}); err != nil {
+ return err
+ }
+ return nil
+}
diff --git a/internal/use-case/main-use-case/unit-position/helper.go b/internal/use-case/main-use-case/unit-position/helper.go
new file mode 100644
index 00000000..c1db758d
--- /dev/null
+++ b/internal/use-case/main-use-case/unit-position/helper.go
@@ -0,0 +1,25 @@
+/*
+DESCRIPTION:
+Any functions that are used internally by the use-case
+*/
+package unit_position
+
+import (
+ e "simrs-vx/internal/domain/main-entities/unit-position"
+)
+
+func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.UnitPosition) {
+ var inputSrc *e.CreateDto
+ if inputT, ok := any(input).(*e.CreateDto); ok {
+ inputSrc = inputT
+ } else {
+ inputTemp := any(input).(*e.UpdateDto)
+ inputSrc = &inputTemp.CreateDto
+ }
+
+ data.Unit_Id = inputSrc.Unit_Id
+ data.Code = inputSrc.Code
+ data.Name = inputSrc.Name
+ data.HeadStatus = inputSrc.HeadStatus
+ data.Employee_Id = inputSrc.Employee_Id
+}
diff --git a/internal/use-case/main-use-case/unit-position/lib.go b/internal/use-case/main-use-case/unit-position/lib.go
new file mode 100644
index 00000000..c58edd4e
--- /dev/null
+++ b/internal/use-case/main-use-case/unit-position/lib.go
@@ -0,0 +1,156 @@
+package unit_position
+
+import (
+ "errors"
+ e "simrs-vx/internal/domain/main-entities/unit-position"
+
+ 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.UnitPosition, error) {
+ pl.SetLogInfo(event, nil, "started", "DBCreate")
+
+ data := e.UnitPosition{}
+ 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.UnitPosition, *e.MetaDto, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadList")
+ data := []e.UnitPosition{}
+ 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.UnitPosition{}).
+ 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 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.UnitPosition, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadDetail")
+ data := e.UnitPosition{}
+
+ var tx, getData *gorm.DB
+ if len(dbx) > 0 {
+ tx = dbx[0]
+ } else {
+ tx = dg.I
+ }
+
+ switch {
+ case input.Id != 0:
+ getData = tx.First(&data, input.Id)
+ case input.Code != nil && *input.Code != "":
+ getData = tx.Where("code = ?", *input.Code).First(&data)
+ default:
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-read-detail-fail",
+ Detail: "either Id or Code must be provided",
+ }
+
+ return nil, pl.SetLogError(event, nil)
+ }
+
+ if err := getData.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.UnitPosition, 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.UnitPosition, 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/unit-position/middleware-runner.go b/internal/use-case/main-use-case/unit-position/middleware-runner.go
new file mode 100644
index 00000000..73092025
--- /dev/null
+++ b/internal/use-case/main-use-case/unit-position/middleware-runner.go
@@ -0,0 +1,103 @@
+package unit_position
+
+import (
+ e "simrs-vx/internal/domain/main-entities/unit-position"
+ 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.UnitPosition) 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.UnitPosition) 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.UnitPosition) 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.UnitPosition) 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.UnitPosition) 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/unit-position/middleware.go b/internal/use-case/main-use-case/unit-position/middleware.go
new file mode 100644
index 00000000..44c1e396
--- /dev/null
+++ b/internal/use-case/main-use-case/unit-position/middleware.go
@@ -0,0 +1,9 @@
+package unit_position
+
+// 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/unit-position/tycovar.go b/internal/use-case/main-use-case/unit-position/tycovar.go
new file mode 100644
index 00000000..451d6445
--- /dev/null
+++ b/internal/use-case/main-use-case/unit-position/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 unit_position
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/main-entities/unit-position"
+)
+
+type createMw struct {
+ Name string
+ Func func(input *e.CreateDto, data *e.UnitPosition, tx *gorm.DB) error
+}
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.UnitPosition, tx *gorm.DB) error
+}
+
+type readDetailMw struct {
+ Name string
+ Func func(input *e.ReadDetailDto, data *e.UnitPosition, 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/lib.go b/internal/use-case/main-use-case/unit/lib.go
index c79c1373..1a3e5652 100644
--- a/internal/use-case/main-use-case/unit/lib.go
+++ b/internal/use-case/main-use-case/unit/lib.go
@@ -81,7 +81,9 @@ 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/internal/use-case/main-use-case/user/case.go b/internal/use-case/main-use-case/user/case.go
index 7d2053de..8e452e62 100644
--- a/internal/use-case/main-use-case/user/case.go
+++ b/internal/use-case/main-use-case/user/case.go
@@ -9,6 +9,7 @@ import (
ed "simrs-vx/internal/domain/main-entities/doctor"
ee "simrs-vx/internal/domain/main-entities/employee"
el "simrs-vx/internal/domain/main-entities/laborant"
+ emw "simrs-vx/internal/domain/main-entities/midwife"
en "simrs-vx/internal/domain/main-entities/nurse"
et "simrs-vx/internal/domain/main-entities/nutritionist"
ep "simrs-vx/internal/domain/main-entities/pharmacist"
@@ -18,6 +19,7 @@ import (
ud "simrs-vx/internal/use-case/main-use-case/doctor"
ue "simrs-vx/internal/use-case/main-use-case/employee"
ul "simrs-vx/internal/use-case/main-use-case/laborant"
+ umw "simrs-vx/internal/use-case/main-use-case/midwife"
un "simrs-vx/internal/use-case/main-use-case/nurse"
ut "simrs-vx/internal/use-case/main-use-case/nutritionist"
upe "simrs-vx/internal/use-case/main-use-case/person"
@@ -106,6 +108,7 @@ func Create(input e.CreateDto) (*d.Data, error) {
switch input.Employee.Position_Code {
case ero.EPCDoc:
createDoc := ed.CreateDto{
+ Code: input.Code,
Employee_Id: &employeeData.Id,
IHS_Number: input.IHS_Number,
SIP_Number: input.SIP_Number,
@@ -118,6 +121,7 @@ func Create(input e.CreateDto) (*d.Data, error) {
}
case ero.EPCNur:
createNurse := en.CreateDto{
+ Code: input.Code,
Employee_Id: &employeeData.Id,
IHS_Number: input.IHS_Number,
Unit_Id: input.Unit_Id,
@@ -128,6 +132,7 @@ func Create(input e.CreateDto) (*d.Data, error) {
}
case ero.EPCNut:
createNutritionist := et.CreateDto{
+ Code: input.Code,
Employee_Id: &employeeData.Id,
IHS_Number: input.IHS_Number,
}
@@ -136,6 +141,7 @@ func Create(input e.CreateDto) (*d.Data, error) {
}
case ero.EPCPha:
createPharmacist := ep.CreateDto{
+ Code: input.Code,
Employee_Id: &employeeData.Id,
IHS_Number: input.IHS_Number,
}
@@ -144,12 +150,22 @@ func Create(input e.CreateDto) (*d.Data, error) {
}
case ero.EPCLab:
createLaborant := el.CreateDto{
+ Code: input.Code,
Employee_Id: &employeeData.Id,
IHS_Number: input.IHS_Number,
}
if _, err := ul.CreateData(createLaborant, &event, tx); err != nil {
return err
}
+ case ero.EPCMwi:
+ createMidWife := emw.CreateDto{
+ Code: input.Code,
+ Employee_Id: &employeeData.Id,
+ IHS_Number: input.IHS_Number,
+ }
+ if _, err := umw.CreateData(createMidWife, &event, tx); err != nil {
+ return err
+ }
default:
return errors.New("invalid employee position")
}
@@ -380,6 +396,7 @@ func Update(input e.UpdateDto) (*d.Data, error) {
return err
}
createDoc := ed.CreateDto{
+ Code: input.Code,
Employee_Id: &employeeData.Id,
IHS_Number: input.IHS_Number,
SIP_Number: input.SIP_Number,
@@ -402,6 +419,7 @@ func Update(input e.UpdateDto) (*d.Data, error) {
return err
}
createNur := en.CreateDto{
+ Code: input.Code,
Employee_Id: &employeeData.Id,
IHS_Number: input.IHS_Number,
}
@@ -422,6 +440,7 @@ func Update(input e.UpdateDto) (*d.Data, error) {
return err
}
createNut := et.CreateDto{
+ Code: input.Code,
Employee_Id: &employeeData.Id,
IHS_Number: input.IHS_Number,
}
@@ -442,6 +461,7 @@ func Update(input e.UpdateDto) (*d.Data, error) {
return err
}
createPha := ep.CreateDto{
+ Code: input.Code,
Employee_Id: &employeeData.Id,
IHS_Number: input.IHS_Number,
}
@@ -462,6 +482,7 @@ func Update(input e.UpdateDto) (*d.Data, error) {
return err
}
createLab := el.CreateDto{
+ Code: input.Code,
Employee_Id: &employeeData.Id,
IHS_Number: input.IHS_Number,
}
@@ -475,6 +496,27 @@ func Update(input e.UpdateDto) (*d.Data, error) {
if _, err := ul.CreateData(createLab, &event, tx); err != nil {
return err
}
+ case ero.EPCMwi:
+ readMidWife := emw.ReadDetailDto{Employee_Id: &employeeData.Id}
+ readMidWifeData, err := umw.ReadDetailData(readMidWife, &event, tx)
+ if err != nil {
+ return err
+ }
+ createMidWife := emw.CreateDto{
+ Code: input.Code,
+ Employee_Id: &employeeData.Id,
+ IHS_Number: input.IHS_Number,
+ }
+ if readMidWifeData != nil {
+ if err := umw.UpdateData(emw.UpdateDto{CreateDto: createMidWife}, readMidWifeData, &event, tx); err != nil {
+ return err
+ }
+ return nil
+ }
+
+ if _, err := umw.CreateData(createMidWife, &event, tx); err != nil {
+ return err
+ }
default:
return errors.New("invalid employee position")
}
diff --git a/internal/use-case/main-use-case/user/helper.go b/internal/use-case/main-use-case/user/helper.go
index 1663bb24..acb32331 100644
--- a/internal/use-case/main-use-case/user/helper.go
+++ b/internal/use-case/main-use-case/user/helper.go
@@ -46,9 +46,9 @@ func setDataEmployeeUpdate(src e.EmployeUpdateDto) ee.UpdateDto {
CreateDto: ee.CreateDto{
User_Id: src.User_Id,
Person_Id: src.Person_Id,
- Division_Code: src.Division_Code,
Number: src.Number,
Status_Code: src.Status_Code,
+ Position_Code: &src.Position_Code,
},
}
}
diff --git a/internal/use-case/simgos-sync-case/.keep b/internal/use-case/simgos-sync-case/.keep
new file mode 100644
index 00000000..e69de29b