diff --git a/.gitignore b/.gitignore
index 286b9405..7800ac94 100644
--- a/.gitignore
+++ b/.gitignore
@@ -27,8 +27,9 @@ go.work.sum
# env file
.env
config.yml
-cmd/migration/atlas.hcl
+**/atlas.hcl
+!**/atlas.hcl.example
# Editor/IDE
-# .idea/
+.idea/
.vscode/*
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 7098c42c..fddb0d29 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -7,6 +7,13 @@
"mode": "auto",
"program": "${workspaceFolder}/cmd/main-api"
},
+ {
+ "name": "Launch Package bpjs API",
+ "type": "go",
+ "request": "launch",
+ "mode": "auto",
+ "program": "${workspaceFolder}/cmd/bpjs-api"
+ },
{
"name": "Launch Package migratioon",
"type": "go",
diff --git a/README-APP.md b/README-APP.md
index a31fed54..4da56232 100644
--- a/README-APP.md
+++ b/README-APP.md
@@ -1 +1,38 @@
-# APP DESIGN CONVENTION
\ No newline at end of file
+# APP DESIGN CONVENTION
+
+## Implementing Clean Architecture (later called CA) in the layout
+1. The CA can be implemented simply by using directory structures to represent the layers
+2. The CA directories will be inside the "internal" directory due to its nature that the codes inside it is basically intended for the business model
+3. The CA will have the following directories:
+ 1. `domain`, with sub-directories:
+ 1. `references`, for common type, const, variabel
+ 2. `main-entities`, for the main models
+ 3. `bpjs-entities`, for the bpjs models. Good to know that this was intitially added but later being stripped for its busines model. This still can be unstriped later.
+ 4. `satusehat-entities`, for the satusehat models
+ 5. ...
+ 2. `application`, with sub-directories:
+ 1. `helpers`, some general helper
+ 2. `main-cases`, for the main flows
+ 3. `bpjs-cases`, the expansion flows for the bpjs
+ 4. `satusehat-cases`, the expansion flows for the satusehat
+ 5. ...
+ 3. `interface`, with sub-directories:
+ 1. `main-handler`
+ 2. `jkn-handler`
+ 3. `main-migration`
+ 4. `satusehat-migration`
+ 5. ....
+ 4. `infra` has no specific-grouping directories, instead, it will have several directories related to each purpose directly like:
+ 1. `jkn`, to connect with jkn service
+ 2. `satusehat`, to connect with satusehat service and satusehat local db
+ 3. `minio`, to connect with minio service
+ 4. ....
+4. Several used libraries might have their own infra-purposed feature which will be outside the infra directory.
+
+## ERD to Entity
+All of the MainERD, SSERD, and ExtRefERD will be the entities in the implementation. There will be at least 2 databases: main and satusehat. bpjs is still in the consideration.
+
+## Middlewared Use-Case
+1. To make the applcation have more dynamic flows, each use-case can implement the midlewared model
+2. The idea is to make its basic process of use case clean, adding more flows can be done outside it
+3. This method relatively makes the code easier to maintain in the future
diff --git a/README.md b/README.md
index a186c2f0..93fd84c7 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,55 @@
-# SIMRS-VX
+# RSSA SIMRS-VX BACKEND
+Or in english Hospital Information Management System (HIMS), is a system that
+manages the information of the hospitals and the patients.
+
+## Stacks
+- Language : Golang
+ Link: https://go.dev
+- Framework : No Framework
+ Why? Go (Golang) applications often do not require full-fledged frameworks
+ due to several key aspects of the language and its ecosystem:
+ - Comprehensive Standard Library: Go's standard library is exceptionally
+ robust and provides much of the functionality that would typically be found
+ in frameworks in other languages.
+ - Simplicity and Explicit Design: Go emphasizes simplicity and clarity.
+ Frameworks often introduce a degree of "magic" or hidden complexity
+ through inversion of control, where the framework dictates the
+ application's flow
+ - Modular Libraries: Instead of a single, all-encompassing framework, the Go
+ community favors small, modular libraries that perform specific tasks well.
+ - Performance and Efficiency: Go is designed for performance and efficiency.
+ Frameworks can sometimes introduce performance overhead due to their layers
+ of abstraction.
+
+ So? No framewok is the best framework.
+- Database : PostgreSQL
+ Link: https://www.postgresql.org
+- Cache : Redis
+ Link: https://redis.io
+- File Server : Minio
+ Link: https://www.min.io
+
+## Libraries
+- Routing Helper: Apem
+ Link: https://github.com/karincake/apem
+- ORM: GORM
+ Link: https://gorm.io
+- Database Migration: Atlas
+ Link: https://atlasgo.io/guides/orms/gorm/program
+
+## Others
+- Project Layout: Golang Standards Project Layout
+ Link: https://github.com/golang-standards/project-layout
+- Architecture: Clean Architecture
+ Link: https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html
+
+## Commands
+- Main api:
+ - go to the ./cmd/main-api
+ - run `go run .` to run in debug mode
+ - run `go build` to build the binary
+- Main migration:
+ - go to the ./cmd/main-migration
+ - run `go run .` to run in debug mode
+ - run `go build` to build the binary
diff --git a/assets/language/en/data.json b/assets/language/en/data.json
index be5c94c1..ffea29e2 100644
--- a/assets/language/en/data.json
+++ b/assets/language/en/data.json
@@ -14,6 +14,7 @@
"auth-login-unverified": "login failed, account is not verified",
"auth-logout-success": "logout success",
"auth-reject-suspend": "restricted for suspended account",
+ "auth-getData-failed": "failed to get user data",
"balance-exceeded": "must not exceeds balance",
@@ -26,6 +27,7 @@
"data-notFound": "data or resource can not be found",
"data-notFound-condition": "\"%v\" with %v \"%v\" can not be found",
"data-get-fail": "get data failed, %v",
+ "data-get-invalid-relation": "database get failed, invalid relation",
"data-update-fail": "failed to update data",
"data-delete-success": "data has been deleted",
"data-delete-fail": "failed to delete data",
@@ -39,6 +41,7 @@
"data-state-mismatch": "\"%v\" is not in \"%v\" state",
"data-duplicate": "duplicate data",
"data-payment-fail": "failed to create payment",
+ "data-handled-mismatch": "data handled by different user/person",
"expired": "is expired",
"registered": "is already registered",
diff --git a/cmd/migration/config.yml-example b/cmd/bpjs-api/config.yml-example
similarity index 57%
rename from cmd/migration/config.yml-example
rename to cmd/bpjs-api/config.yml-example
index 19893fd7..60b1644c 100644
--- a/cmd/migration/config.yml-example
+++ b/cmd/bpjs-api/config.yml-example
@@ -15,6 +15,20 @@ dbCfg:
maxIdleConns: 5
maxIdleTime: 100
+multiDbCfg:
+ - dbs :
+ name:
+ dsn:
+ maxOpenConns:
+ maxIdleConns:
+ maxIdleTime:
+ - bpjs
+ name: bpjs
+ dsn:
+ maxOpenConns:
+ maxIdleConns:
+ maxIdleTime:
+
loggerCfg:
hideTime:
hideLevel:
@@ -41,7 +55,15 @@ corsCfg:
allowedMethod:
satuSehatCfg:
- host: localhsot:8200
+ host: localhost:8200
bpjsCfg:
- host: localhsot:8200
+ host: localhost:8200
+
+corsCfg:
+ allowedOrigins:
+ - http://example.com
+ allowedMethod:
+
+bpjsCfg:
+ baseUrl:
\ No newline at end of file
diff --git a/cmd/bpjs-api/main.go b/cmd/bpjs-api/main.go
new file mode 100644
index 00000000..e1cb2468
--- /dev/null
+++ b/cmd/bpjs-api/main.go
@@ -0,0 +1,14 @@
+package main
+
+import (
+ a "github.com/karincake/apem"
+ d "github.com/karincake/apem/db-gorm-pg"
+ l "github.com/karincake/apem/logger-zerolog"
+ m "github.com/karincake/apem/ms-redis"
+
+ h "simrs-vx/internal/interface/bpjs-handler"
+)
+
+func main() {
+ a.Run(h.SetRoutes(), &l.O, &m.O, &d.O)
+}
diff --git a/cmd/main-api/config.yml-example b/cmd/main-api/config.yml-example
index aaf986f0..f131a725 100644
--- a/cmd/main-api/config.yml-example
+++ b/cmd/main-api/config.yml-example
@@ -15,11 +15,19 @@ dbCfg:
maxIdleConns: 5
maxIdleTime: 100
-ssDbCfg:
- dsn:
- maxOpenConns: 5
- maxIdleConns: 5
- maxIdleTime: 100
+multiDbCfg:
+ - dbs :
+ name:
+ dsn:
+ maxOpenConns:
+ maxIdleConns:
+ maxIdleTime:
+ - bpjs
+ name: bpjs
+ dsn:
+ maxOpenConns:
+ maxIdleConns:
+ maxIdleTime:
loggerCfg:
hideTime:
diff --git a/cmd/main-migration/Makefile b/cmd/main-migration/Makefile
new file mode 100644
index 00000000..e83356e5
--- /dev/null
+++ b/cmd/main-migration/Makefile
@@ -0,0 +1,18 @@
+# Makefile for Atlas migrations
+
+# Default environment
+ENV ?= gorm
+
+.PHONY: diff apply hash
+
+## Generate a new migration diff
+diff:
+ atlas migrate diff --env $(ENV)
+
+## Apply migrations to the database
+apply:
+ atlas migrate apply --env $(ENV)
+
+## Calculate the schema hash
+hash:
+ atlas migrate hash
diff --git a/cmd/main-migration/README-ATLAS.MD b/cmd/main-migration/README-ATLAS.MD
new file mode 100644
index 00000000..da249823
--- /dev/null
+++ b/cmd/main-migration/README-ATLAS.MD
@@ -0,0 +1,59 @@
+# Database Migration with Atlas
+
+This project uses [Atlas](https://atlasgo.io/) for database schema management and migrations.
+
+## ๐ Prerequisites
+
+1. **Download and Install Atlas CLI**
+ Run the following command in PowerShell or Git Bash:
+
+ ```sh
+ curl -sSf https://atlasgo.sh | sh
+ ```
+ Verify installation:
+
+ ```sh
+ atlas version
+ ```
+
+2. Install GORM Provider
+ Run inside your Go project:
+
+ ```sh
+ go get -u ariga.io/atlas-provider-gorm
+ ```
+
+3. Create atlas.hcl configuration file
+ Just create an atlas.hcl file in your project root as example given at atlas.hcl.example
+4. Create migrations folder
+ ```sh
+ mkdir migrations
+ ```
+5. Usage
+You can use the provided Makefile for common commands:
+
+ Generate a migration diff
+ ```sh
+ make diff
+ ```
+
+ Apply migrations
+ ```sh
+ make apply
+ ```
+
+ Compute schema hash
+ ```sh
+ make hash
+ ```
+
+ If you donโt have make installed, you can run the Atlas commands directly:
+ ```sh
+ atlas migrate diff --env gorm
+ ```
+ ```sh
+ atlas migrate apply --env gorm
+ ```
+ ```sh
+ atlas migrate hash
+ ```
\ No newline at end of file
diff --git a/cmd/migration/atlas.hcl.example b/cmd/main-migration/atlas.hcl.example
similarity index 100%
rename from cmd/migration/atlas.hcl.example
rename to cmd/main-migration/atlas.hcl.example
diff --git a/cmd/migration/migration.go b/cmd/main-migration/migration.go
similarity index 81%
rename from cmd/migration/migration.go
rename to cmd/main-migration/migration.go
index c225edf1..dd28a55f 100644
--- a/cmd/migration/migration.go
+++ b/cmd/main-migration/migration.go
@@ -5,5 +5,5 @@ import (
)
func main() {
- m.Migrate()
+ m.Migrate(m.Main)
}
diff --git a/cmd/migration/migrations/20250829081952.sql b/cmd/main-migration/migrations/20250904105930.sql
similarity index 70%
rename from cmd/migration/migrations/20250829081952.sql
rename to cmd/main-migration/migrations/20250904105930.sql
index c74cb017..39175bfb 100644
--- a/cmd/migration/migrations/20250829081952.sql
+++ b/cmd/main-migration/migrations/20250904105930.sql
@@ -10,6 +10,29 @@ CREATE TABLE "public"."DiagnoseSrc" (
PRIMARY KEY ("Id"),
CONSTRAINT "uni_DiagnoseSrc_Code" UNIQUE ("Code")
);
+-- Create "PharmacyCompany" table
+CREATE TABLE "public"."PharmacyCompany" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Code" character varying(20) NULL,
+ "Name" character varying(100) NULL,
+ "Regency_Code" character varying(4) NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "uni_PharmacyCompany_Code" UNIQUE ("Code")
+);
+-- Create "Uom" table
+CREATE TABLE "public"."Uom" (
+ "Id" serial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Code" character varying(10) NULL,
+ "Name" character varying(50) NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "uni_Uom_Code" UNIQUE ("Code")
+);
-- Create "Counter" table
CREATE TABLE "public"."Counter" (
"Id" serial NOT NULL,
@@ -25,68 +48,6 @@ CREATE TABLE "public"."Counter" (
PRIMARY KEY ("Id"),
CONSTRAINT "uni_Counter_Code" UNIQUE ("Code")
);
--- Create "McuSrcCategory" table
-CREATE TABLE "public"."McuSrcCategory" (
- "Id" serial NOT NULL,
- "CreatedAt" timestamptz NULL,
- "UpdatedAt" timestamptz NULL,
- "DeletedAt" timestamptz NULL,
- "Code" character varying(20) NULL,
- "Name" character varying(50) NULL,
- "Scope_Code" character varying(10) NULL,
- PRIMARY KEY ("Id"),
- CONSTRAINT "uni_McuSrcCategory_Code" UNIQUE ("Code")
-);
--- Create "McuSrc" table
-CREATE TABLE "public"."McuSrc" (
- "Id" serial NOT NULL,
- "CreatedAt" timestamptz NULL,
- "UpdatedAt" timestamptz NULL,
- "DeletedAt" timestamptz NULL,
- "Code" character varying(20) NULL,
- "Name" character varying(50) NULL,
- "CheckupCategory_Code" character varying(20) NULL,
- PRIMARY KEY ("Id"),
- CONSTRAINT "uni_McuSrc_Code" UNIQUE ("Code")
-);
--- Create "Uom" table
-CREATE TABLE "public"."Uom" (
- "Id" serial NOT NULL,
- "CreatedAt" timestamptz NULL,
- "UpdatedAt" timestamptz NULL,
- "DeletedAt" timestamptz NULL,
- "Code" character varying(10) NULL,
- "Name" character varying(50) NULL,
- PRIMARY KEY ("Id"),
- CONSTRAINT "uni_Uom_Code" UNIQUE ("Code")
-);
--- Create "PharmacyCompany" table
-CREATE TABLE "public"."PharmacyCompany" (
- "Id" bigserial NOT NULL,
- "CreatedAt" timestamptz NULL,
- "UpdatedAt" timestamptz NULL,
- "DeletedAt" timestamptz NULL,
- "Code" character varying(20) NULL,
- "Name" character varying(100) NULL,
- "Regency_Code" character varying(4) NULL,
- PRIMARY KEY ("Id"),
- CONSTRAINT "uni_PharmacyCompany_Code" UNIQUE ("Code")
-);
--- Create "User" table
-CREATE TABLE "public"."User" (
- "Id" bigserial NOT NULL,
- "CreatedAt" timestamptz NULL,
- "UpdatedAt" timestamptz NULL,
- "DeletedAt" timestamptz NULL,
- "Name" character varying(25) NOT NULL,
- "Password" character varying(255) NOT NULL,
- "Status_Code" character varying(10) NOT NULL,
- "FailedLoginCount" smallint NULL,
- "LoginAttemptCount" bigint NULL,
- "LastSuccessLogin" timestamptz NULL,
- "LastAllowdLogin" timestamptz NULL,
- PRIMARY KEY ("Id")
-);
-- Create "Item" table
CREATE TABLE "public"."Item" (
"Id" bigserial NOT NULL,
@@ -112,7 +73,7 @@ CREATE TABLE "public"."Infra" (
"Code" character varying(10) NULL,
"Name" character varying(50) NULL,
"InfraGroup_Code" character varying(10) NULL,
- "Parent_Id" smallint NULL,
+ "Parent_Id" integer NULL,
"Item_Id" bigint NULL,
PRIMARY KEY ("Id"),
CONSTRAINT "uni_Infra_Code" UNIQUE ("Code"),
@@ -125,7 +86,7 @@ CREATE TABLE "public"."Device" (
"UpdatedAt" timestamptz NULL,
"DeletedAt" timestamptz NULL,
"Code" character varying(10) NULL,
- "Name" character varying(50) NULL,
+ "Name" character varying(50) NOT NULL,
"Uom_Code" character varying(10) NULL,
"Infra_Id" integer NULL,
"Item_Id" bigint NULL,
@@ -188,6 +149,73 @@ CREATE TABLE "public"."DivisionPosition" (
CONSTRAINT "uni_DivisionPosition_Code" UNIQUE ("Code"),
CONSTRAINT "fk_DivisionPosition_Division" FOREIGN KEY ("Division_Id") REFERENCES "public"."Division" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
);
+-- Create "Ethnic" table
+CREATE TABLE "public"."Ethnic" (
+ "Id" serial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Code" character varying(20) NULL,
+ "Name" character varying(50) NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "uni_Ethnic_Code" UNIQUE ("Code")
+);
+-- Create "Language" table
+CREATE TABLE "public"."Language" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Code" character varying(10) NULL,
+ "Name" character varying(50) NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "uni_Language_Code" UNIQUE ("Code")
+);
+-- Create "Person" table
+CREATE TABLE "public"."Person" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Name" character varying(150) NOT NULL,
+ "FrontTitle" character varying(50) NULL,
+ "EndTitle" character varying(50) NULL,
+ "BirthDate" timestamptz NULL,
+ "BirthRegency_Code" character varying(4) NULL,
+ "Gender_Code" character varying(10) NULL,
+ "ResidentIdentityNumber" character varying(16) NULL,
+ "PassportNumber" character varying(20) NULL,
+ "DrivingLicenseNumber" character varying(20) NULL,
+ "Religion_Code" character varying(10) NULL,
+ "Education_Code" character varying(10) NULL,
+ "Ocupation_Code" character varying(15) NULL,
+ "Ocupation_Name" character varying(50) NULL,
+ "Ethnic_Code" character varying(20) NULL,
+ "Language_Code" character varying(10) NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "uni_Person_DrivingLicenseNumber" UNIQUE ("DrivingLicenseNumber"),
+ CONSTRAINT "uni_Person_PassportNumber" UNIQUE ("PassportNumber"),
+ CONSTRAINT "uni_Person_ResidentIdentityNumber" UNIQUE ("ResidentIdentityNumber"),
+ CONSTRAINT "fk_Person_Ethnic" FOREIGN KEY ("Ethnic_Code") REFERENCES "public"."Ethnic" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_Person_Language" FOREIGN KEY ("Language_Code") REFERENCES "public"."Language" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
+-- Create "User" table
+CREATE TABLE "public"."User" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Name" character varying(25) NOT NULL,
+ "Password" character varying(255) NOT NULL,
+ "Status_Code" character varying(10) NOT NULL,
+ "FailedLoginCount" smallint NULL,
+ "Position_Code" character varying(20) NOT NULL,
+ "LoginAttemptCount" bigint NULL,
+ "LastSuccessLogin" timestamptz NULL,
+ "LastAllowdLogin" timestamptz NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "uni_User_Name" UNIQUE ("Name")
+);
-- Create "Employee" table
CREATE TABLE "public"."Employee" (
"Id" bigserial NOT NULL,
@@ -196,12 +224,13 @@ CREATE TABLE "public"."Employee" (
"DeletedAt" timestamptz NULL,
"User_Id" bigint NULL,
"Person_Id" bigint NULL,
- "Position_Code" character varying(20) NOT NULL,
"Division_Code" character varying(10) NULL,
"Number" character varying(20) NULL,
"Status_Code" character varying(10) NOT NULL,
PRIMARY KEY ("Id"),
- CONSTRAINT "fk_Employee_Division" FOREIGN KEY ("Division_Code") REFERENCES "public"."Division" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION
+ CONSTRAINT "fk_Employee_Division" FOREIGN KEY ("Division_Code") REFERENCES "public"."Division" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_Employee_Person" FOREIGN KEY ("Person_Id") REFERENCES "public"."Person" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_Employee_User" FOREIGN KEY ("User_Id") REFERENCES "public"."User" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
);
-- Create "Installation" table
CREATE TABLE "public"."Installation" (
@@ -224,10 +253,37 @@ CREATE TABLE "public"."Unit" (
"Installation_Id" integer NULL,
"Code" character varying(10) NULL,
"Name" character varying(50) NULL,
+ "Type_Code" text NULL,
PRIMARY KEY ("Id"),
CONSTRAINT "uni_Unit_Code" UNIQUE ("Code"),
CONSTRAINT "fk_Unit_Installation" FOREIGN KEY ("Installation_Id") REFERENCES "public"."Installation" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
);
+-- Create "Specialist" table
+CREATE TABLE "public"."Specialist" (
+ "Id" serial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Code" character varying(10) NULL,
+ "Name" character varying(50) NULL,
+ "Unit_Id" integer NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "uni_Specialist_Code" UNIQUE ("Code"),
+ CONSTRAINT "fk_Specialist_Unit" FOREIGN KEY ("Unit_Id") REFERENCES "public"."Unit" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
+-- Create "Subspecialist" table
+CREATE TABLE "public"."Subspecialist" (
+ "Id" serial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Code" character varying(10) NULL,
+ "Name" character varying(50) NULL,
+ "Specialist_Id" integer NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "uni_Subspecialist_Code" UNIQUE ("Code"),
+ CONSTRAINT "fk_Subspecialist_Specialist" FOREIGN KEY ("Specialist_Id") REFERENCES "public"."Specialist" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
-- Create "Doctor" table
CREATE TABLE "public"."Doctor" (
"Id" bigserial NOT NULL,
@@ -237,9 +293,13 @@ CREATE TABLE "public"."Doctor" (
"Employee_Id" bigint NULL,
"IHS_Number" character varying(20) NULL,
"SIP_Number" character varying(20) NULL,
- "Unit_Id" bigint NULL,
+ "Unit_Id" integer NULL,
+ "Specialist_Id" integer NULL,
+ "Subspecialist_Id" integer NULL,
PRIMARY KEY ("Id"),
CONSTRAINT "fk_Doctor_Employee" FOREIGN KEY ("Employee_Id") REFERENCES "public"."Employee" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_Doctor_Specialist" FOREIGN KEY ("Specialist_Id") REFERENCES "public"."Specialist" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_Doctor_Subspecialist" FOREIGN KEY ("Subspecialist_Id") REFERENCES "public"."Subspecialist" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT "fk_Doctor_Unit" FOREIGN KEY ("Unit_Id") REFERENCES "public"."Unit" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
);
-- Create "DoctorFee" table
@@ -256,6 +316,45 @@ CREATE TABLE "public"."DoctorFee" (
CONSTRAINT "fk_DoctorFee_Doctor" FOREIGN KEY ("Doctor_Id") REFERENCES "public"."Doctor" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT "fk_DoctorFee_Item" FOREIGN KEY ("Item_Id") REFERENCES "public"."Item" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
);
+-- Create "Patient" table
+CREATE TABLE "public"."Patient" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Person_Id" bigint NULL,
+ "RegisteredAt" timestamptz NULL,
+ "Status_Code" character varying(10) NOT NULL,
+ "Number" character varying(15) NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "uni_Patient_Number" UNIQUE ("Number"),
+ CONSTRAINT "fk_Patient_Person" FOREIGN KEY ("Person_Id") REFERENCES "public"."Person" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
+-- Create "Encounter" table
+CREATE TABLE "public"."Encounter" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Patient_Id" bigint NULL,
+ "RegisteredAt" timestamptz NULL,
+ "Class_Code" character varying(10) NOT NULL,
+ "Unit_Id" bigint NULL,
+ "Specialist_Id" integer NULL,
+ "Subspecialist_Id" integer NULL,
+ "VisitDate" timestamptz NULL,
+ "Assignment_Doctor_Id" bigint NULL,
+ "Responsible_Doctor_Id" bigint NULL,
+ "DischardeMethod_Code" character varying(10) NULL,
+ "RefSource_Name" character varying(100) NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "fk_Encounter_Assignment_Doctor" FOREIGN KEY ("Assignment_Doctor_Id") REFERENCES "public"."Doctor" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_Encounter_Patient" FOREIGN KEY ("Patient_Id") REFERENCES "public"."Patient" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_Encounter_Responsible_Doctor" FOREIGN KEY ("Responsible_Doctor_Id") REFERENCES "public"."Doctor" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_Encounter_Specialist" FOREIGN KEY ("Specialist_Id") REFERENCES "public"."Specialist" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_Encounter_Subspecialist" FOREIGN KEY ("Subspecialist_Id") REFERENCES "public"."Subspecialist" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_Encounter_Unit" FOREIGN KEY ("Unit_Id") REFERENCES "public"."Unit" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
-- Create "InsuranceCompany" table
CREATE TABLE "public"."InsuranceCompany" (
"Id" serial NOT NULL,
@@ -284,6 +383,17 @@ CREATE TABLE "public"."ItemPrice" (
CONSTRAINT "fk_ItemPrice_InsuranceCompany" FOREIGN KEY ("InsuranceCompany_Code") REFERENCES "public"."InsuranceCompany" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT "fk_ItemPrice_Item" FOREIGN KEY ("Item_Id") REFERENCES "public"."Item" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
);
+-- Create "Laborant" table
+CREATE TABLE "public"."Laborant" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Employee_Id" bigint NULL,
+ "IHS_Number" character varying(20) NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "fk_Laborant_Employee" FOREIGN KEY ("Employee_Id") REFERENCES "public"."Employee" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
-- Create "Material" table
CREATE TABLE "public"."Material" (
"Id" bigserial NOT NULL,
@@ -302,6 +412,31 @@ CREATE TABLE "public"."Material" (
CONSTRAINT "fk_Material_Item" FOREIGN KEY ("Item_Id") REFERENCES "public"."Item" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT "fk_Material_Uom" FOREIGN KEY ("Uom_Code") REFERENCES "public"."Uom" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION
);
+-- Create "McuSrcCategory" table
+CREATE TABLE "public"."McuSrcCategory" (
+ "Id" serial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Code" character varying(20) NULL,
+ "Name" character varying(50) NULL,
+ "Scope_Code" character varying(10) NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "uni_McuSrcCategory_Code" UNIQUE ("Code")
+);
+-- Create "McuSrc" table
+CREATE TABLE "public"."McuSrc" (
+ "Id" serial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Code" character varying(20) NULL,
+ "Name" character varying(50) NULL,
+ "CheckupCategory_Code" character varying(20) NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "uni_McuSrc_Code" UNIQUE ("Code"),
+ CONSTRAINT "fk_McuSrc_CheckupCategory" FOREIGN KEY ("CheckupCategory_Code") REFERENCES "public"."McuSrcCategory" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
-- Create "MedicalActionSrc" table
CREATE TABLE "public"."MedicalActionSrc" (
"Id" bigserial NOT NULL,
@@ -347,8 +482,8 @@ CREATE TABLE "public"."MedicineGroup" (
"CreatedAt" timestamptz NULL,
"UpdatedAt" timestamptz NULL,
"DeletedAt" timestamptz NULL,
- "Code" character varying(50) NULL,
- "Name" character varying(100) NULL,
+ "Code" character varying(10) NULL,
+ "Name" character varying(50) NULL,
PRIMARY KEY ("Id"),
CONSTRAINT "uni_MedicineGroup_Code" UNIQUE ("Code")
);
@@ -358,8 +493,8 @@ CREATE TABLE "public"."MedicineMethod" (
"CreatedAt" timestamptz NULL,
"UpdatedAt" timestamptz NULL,
"DeletedAt" timestamptz NULL,
- "Code" character varying(50) NULL,
- "Name" character varying(100) NULL,
+ "Code" character varying(10) NULL,
+ "Name" character varying(50) NULL,
PRIMARY KEY ("Id"),
CONSTRAINT "uni_MedicineMethod_Code" UNIQUE ("Code")
);
@@ -416,8 +551,12 @@ CREATE TABLE "public"."Nurse" (
"DeletedAt" timestamptz NULL,
"Employee_Id" bigint NULL,
"IHS_Number" character varying(20) NULL,
+ "Unit_Id" integer NULL,
+ "Infra_Id" integer NULL,
PRIMARY KEY ("Id"),
- CONSTRAINT "fk_Nurse_Employee" FOREIGN KEY ("Employee_Id") REFERENCES "public"."Employee" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
+ CONSTRAINT "fk_Nurse_Employee" FOREIGN KEY ("Employee_Id") REFERENCES "public"."Employee" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_Nurse_Infra" FOREIGN KEY ("Infra_Id") REFERENCES "public"."Infra" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_Nurse_Unit" FOREIGN KEY ("Unit_Id") REFERENCES "public"."Unit" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
);
-- Create "Nutritionist" table
CREATE TABLE "public"."Nutritionist" (
@@ -430,36 +569,6 @@ CREATE TABLE "public"."Nutritionist" (
PRIMARY KEY ("Id"),
CONSTRAINT "fk_Nutritionist_Employee" FOREIGN KEY ("Employee_Id") REFERENCES "public"."Employee" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
);
--- Create "Ethnic" table
-CREATE TABLE "public"."Ethnic" (
- "Id" serial NOT NULL,
- "CreatedAt" timestamptz NULL,
- "UpdatedAt" timestamptz NULL,
- "DeletedAt" timestamptz NULL,
- "Code" character varying(20) NULL,
- "Name" character varying(50) NULL,
- PRIMARY KEY ("Id"),
- CONSTRAINT "uni_Ethnic_Code" UNIQUE ("Code")
-);
--- Create "Person" table
-CREATE TABLE "public"."Person" (
- "Id" bigserial NOT NULL,
- "CreatedAt" timestamptz NULL,
- "UpdatedAt" timestamptz NULL,
- "DeletedAt" timestamptz NULL,
- "Name" character varying(150) NOT NULL,
- "BirthDate" timestamptz NULL,
- "BirthRegency_Code" character varying(4) NULL,
- "Gender_Code" character varying(10) NULL,
- "ResidentIdentityNumber" character varying(16) NULL,
- "Religion_Code" character varying(10) NULL,
- "Education_Code" character varying(10) NULL,
- "Ocupation_Code" character varying(15) NULL,
- "Ocupation_Name" character varying(50) NULL,
- "Ethnic_Code" character varying(20) NULL,
- PRIMARY KEY ("Id"),
- CONSTRAINT "fk_Person_Ethnic" FOREIGN KEY ("Ethnic_Code") REFERENCES "public"."Ethnic" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION
-);
-- Create "PersonAddress" table
CREATE TABLE "public"."PersonAddress" (
"Id" bigserial NOT NULL,
@@ -486,6 +595,36 @@ CREATE TABLE "public"."PersonContact" (
PRIMARY KEY ("Id"),
CONSTRAINT "fk_Person_Contacts" FOREIGN KEY ("Person_Id") REFERENCES "public"."Person" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
);
+-- Create "Village" table
+CREATE TABLE "public"."Village" (
+ "Id" bigserial NOT NULL,
+ "District_Code" character varying(6) NULL,
+ "Code" character varying(10) NULL,
+ "Name" character varying(50) NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "uni_Village_Code" UNIQUE ("Code"),
+ CONSTRAINT "fk_District_Villages" FOREIGN KEY ("District_Code") REFERENCES "public"."District" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
+-- Create "PersonRelative" table
+CREATE TABLE "public"."PersonRelative" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Person_Id" bigint NULL,
+ "Relationship_Code" character varying(100) NOT NULL,
+ "Name" character varying(100) NULL,
+ "Address" character varying(100) NULL,
+ "Village_Code" character varying(10) NULL,
+ "Gender_Code" character varying(10) NULL,
+ "PhoneNumber" character varying(30) NULL,
+ "Education_Code" character varying(10) NULL,
+ "Occupation_Code" character varying(10) NULL,
+ "Occupation_Name" character varying(50) NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "fk_PersonRelative_Village" FOREIGN KEY ("Village_Code") REFERENCES "public"."Village" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_Person_Relatives" FOREIGN KEY ("Person_Id") REFERENCES "public"."Person" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
-- Create "Pharmacist" table
CREATE TABLE "public"."Pharmacist" (
"Id" bigserial NOT NULL,
@@ -512,13 +651,35 @@ CREATE TABLE "public"."PracticeSchedule" (
CONSTRAINT "fk_PracticeSchedule_Doctor" FOREIGN KEY ("Doctor_Id") REFERENCES "public"."Doctor" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT "fk_PracticeSchedule_Unit" FOREIGN KEY ("Unit_Code") REFERENCES "public"."Unit" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION
);
--- Create "Village" table
-CREATE TABLE "public"."Village" (
- "Id" bigserial NOT NULL,
- "District_Code" character varying(6) NULL,
- "Code" character varying(10) NULL,
- "Name" character varying(50) NULL,
+-- Create "Room" table
+CREATE TABLE "public"."Room" (
+ "Id" serial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Infra_Id" integer NULL,
+ "Unit_Id" integer NULL,
+ "Specialist_Id" integer NULL,
+ "Subspecialist_Id" integer NULL,
PRIMARY KEY ("Id"),
- CONSTRAINT "uni_Village_Code" UNIQUE ("Code"),
- CONSTRAINT "fk_District_Villages" FOREIGN KEY ("District_Code") REFERENCES "public"."District" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION
+ CONSTRAINT "fk_Room_Infra" FOREIGN KEY ("Infra_Id") REFERENCES "public"."Infra" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_Room_Specialist" FOREIGN KEY ("Specialist_Id") REFERENCES "public"."Specialist" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_Room_Subspecialist" FOREIGN KEY ("Subspecialist_Id") REFERENCES "public"."Subspecialist" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_Room_Unit" FOREIGN KEY ("Unit_Id") REFERENCES "public"."Unit" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
+-- Create "SpecialistIntern" table
+CREATE TABLE "public"."SpecialistIntern" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Person_Id" bigint NULL,
+ "Specialist_Id" integer NULL,
+ "Subspecialist_Id" integer NULL,
+ "User_Id" bigint NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "fk_SpecialistIntern_Person" FOREIGN KEY ("Person_Id") REFERENCES "public"."Person" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_SpecialistIntern_Specialist" FOREIGN KEY ("Specialist_Id") REFERENCES "public"."Specialist" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_SpecialistIntern_Subspecialist" FOREIGN KEY ("Subspecialist_Id") REFERENCES "public"."Subspecialist" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_SpecialistIntern_User" FOREIGN KEY ("User_Id") REFERENCES "public"."User" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
);
diff --git a/cmd/main-migration/migrations/20250904141448.sql b/cmd/main-migration/migrations/20250904141448.sql
new file mode 100644
index 00000000..56a113ca
--- /dev/null
+++ b/cmd/main-migration/migrations/20250904141448.sql
@@ -0,0 +1,10 @@
+-- Modify "Doctor" table
+ALTER TABLE "public"."Doctor" ADD CONSTRAINT "uni_Doctor_IHS_Number" UNIQUE ("IHS_Number"), ADD CONSTRAINT "uni_Doctor_SIP_Number" UNIQUE ("SIP_Number");
+-- Modify "Laborant" table
+ALTER TABLE "public"."Laborant" ADD CONSTRAINT "uni_Laborant_IHS_Number" UNIQUE ("IHS_Number");
+-- Modify "Nurse" table
+ALTER TABLE "public"."Nurse" ADD CONSTRAINT "uni_Nurse_IHS_Number" UNIQUE ("IHS_Number");
+-- Modify "Nutritionist" table
+ALTER TABLE "public"."Nutritionist" ADD CONSTRAINT "uni_Nutritionist_IHS_Number" UNIQUE ("IHS_Number");
+-- Modify "Pharmacist" table
+ALTER TABLE "public"."Pharmacist" ADD CONSTRAINT "uni_Pharmacist_IHS_Number" UNIQUE ("IHS_Number");
diff --git a/cmd/main-migration/migrations/20250908062237.sql b/cmd/main-migration/migrations/20250908062237.sql
new file mode 100644
index 00000000..cc509de4
--- /dev/null
+++ b/cmd/main-migration/migrations/20250908062237.sql
@@ -0,0 +1,96 @@
+-- Create "Appointment" table
+CREATE TABLE "public"."Appointment" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "PracticeSchedule_Id" bigint NULL,
+ "Patient_Id" bigint NULL,
+ "Person_ResidentIdentityNumber" character varying(16) NULL,
+ "Person_Name" character varying(100) NULL,
+ "Person_PhoneNumber" character varying(30) NULL,
+ "PaymentMethod_Code" character varying(10) NULL,
+ "RefNumber" character varying(20) NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "fk_Appointment_Patient" FOREIGN KEY ("Patient_Id") REFERENCES "public"."Patient" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_Appointment_PracticeSchedule" FOREIGN KEY ("PracticeSchedule_Id") REFERENCES "public"."PracticeSchedule" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
+-- Modify "Encounter" table
+ALTER TABLE "public"."Encounter" ADD COLUMN "Appointment_Doctor_Id" bigint NULL, ADD COLUMN "Appointment_Id" bigint NULL, ADD COLUMN "EarlyEducation" text NULL, ADD COLUMN "MedicalDischargeEducation" text NULL, ADD COLUMN "AdmDischargeEducation" text NULL, ADD COLUMN "DischargeReason" text NULL, ADD CONSTRAINT "fk_Encounter_Appointment" FOREIGN KEY ("Appointment_Id") REFERENCES "public"."Appointment" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION, ADD CONSTRAINT "fk_Encounter_Appointment_Doctor" FOREIGN KEY ("Appointment_Doctor_Id") REFERENCES "public"."Doctor" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION;
+-- Create "Adime" table
+CREATE TABLE "public"."Adime" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Encounter_Id" bigint NULL,
+ "Employee_Id" bigint NULL,
+ "Time" timestamptz NULL,
+ "Value" text NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "fk_Adime_Employee" FOREIGN KEY ("Employee_Id") REFERENCES "public"."Employee" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_Adime_Encounter" FOREIGN KEY ("Encounter_Id") REFERENCES "public"."Encounter" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
+-- Create "Ambulatory" table
+CREATE TABLE "public"."Ambulatory" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Encounter_Id" bigint NULL,
+ "Class_Code" character varying(10) NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "fk_Ambulatory_Encounter" FOREIGN KEY ("Encounter_Id") REFERENCES "public"."Encounter" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
+-- Create "Emergency" table
+CREATE TABLE "public"."Emergency" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Encounter_Id" bigint NULL,
+ "Class_Code" character varying(10) NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "fk_Emergency_Encounter" FOREIGN KEY ("Encounter_Id") REFERENCES "public"."Encounter" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
+-- Create "Inpatient" table
+CREATE TABLE "public"."Inpatient" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Encounter_Id" bigint NULL,
+ "Class_Code" character varying(10) NULL,
+ "Infra_Id" integer NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "fk_Inpatient_Encounter" FOREIGN KEY ("Encounter_Id") REFERENCES "public"."Encounter" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_Inpatient_Infra" FOREIGN KEY ("Infra_Id") REFERENCES "public"."Infra" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
+-- Create "Sbar" table
+CREATE TABLE "public"."Sbar" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Encounter_Id" bigint NULL,
+ "Employee_Id" bigint NULL,
+ "Time" timestamptz NULL,
+ "Value" text NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "fk_Sbar_Employee" FOREIGN KEY ("Employee_Id") REFERENCES "public"."Employee" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_Sbar_Encounter" FOREIGN KEY ("Encounter_Id") REFERENCES "public"."Encounter" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
+-- Create "Soapi" table
+CREATE TABLE "public"."Soapi" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Encounter_Id" bigint NULL,
+ "Employee_Id" bigint NULL,
+ "Time" timestamptz NULL,
+ "Value" text NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "fk_Soapi_Employee" FOREIGN KEY ("Employee_Id") REFERENCES "public"."Employee" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_Soapi_Encounter" FOREIGN KEY ("Encounter_Id") REFERENCES "public"."Encounter" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
diff --git a/cmd/main-migration/migrations/20250908062323.sql b/cmd/main-migration/migrations/20250908062323.sql
new file mode 100644
index 00000000..cc63543f
--- /dev/null
+++ b/cmd/main-migration/migrations/20250908062323.sql
@@ -0,0 +1,2 @@
+-- Modify "Encounter" table
+ALTER TABLE "public"."Encounter" DROP COLUMN "Assignment_Doctor_Id";
diff --git a/cmd/main-migration/migrations/20250908073811.sql b/cmd/main-migration/migrations/20250908073811.sql
new file mode 100644
index 00000000..ead1e965
--- /dev/null
+++ b/cmd/main-migration/migrations/20250908073811.sql
@@ -0,0 +1,2 @@
+-- Modify "Encounter" table
+ALTER TABLE "public"."Encounter" ADD COLUMN "DischargeMethod_Code" character varying(10) NULL;
diff --git a/cmd/main-migration/migrations/20250908073839.sql b/cmd/main-migration/migrations/20250908073839.sql
new file mode 100644
index 00000000..43710589
--- /dev/null
+++ b/cmd/main-migration/migrations/20250908073839.sql
@@ -0,0 +1,2 @@
+-- Modify "Encounter" table
+ALTER TABLE "public"."Encounter" DROP COLUMN "DischardeMethod_Code";
diff --git a/cmd/main-migration/migrations/20250910055902.sql b/cmd/main-migration/migrations/20250910055902.sql
new file mode 100644
index 00000000..19583065
--- /dev/null
+++ b/cmd/main-migration/migrations/20250910055902.sql
@@ -0,0 +1,2 @@
+-- Modify "Encounter" table
+ALTER TABLE "public"."Encounter" ADD COLUMN "Status_Code" character varying(10) NULL;
diff --git a/cmd/main-migration/migrations/20250915123412.sql b/cmd/main-migration/migrations/20250915123412.sql
new file mode 100644
index 00000000..5bb948f0
--- /dev/null
+++ b/cmd/main-migration/migrations/20250915123412.sql
@@ -0,0 +1,146 @@
+-- Create "DeviceOrder" table
+CREATE TABLE "public"."DeviceOrder" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Encounter_Id" bigint NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "fk_DeviceOrder_Encounter" FOREIGN KEY ("Encounter_Id") REFERENCES "public"."Encounter" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
+-- Create "DeviceOrderItem" table
+CREATE TABLE "public"."DeviceOrderItem" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "DeviceOrder_Id" bigint NULL,
+ "Device_Id" bigint NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "fk_DeviceOrderItem_Device" FOREIGN KEY ("Device_Id") REFERENCES "public"."Device" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_DeviceOrderItem_DeviceOrder" FOREIGN KEY ("DeviceOrder_Id") REFERENCES "public"."DeviceOrder" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
+-- Create "MaterialOrder" table
+CREATE TABLE "public"."MaterialOrder" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Encounter_Id" bigint NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "fk_MaterialOrder_Encounter" FOREIGN KEY ("Encounter_Id") REFERENCES "public"."Encounter" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
+-- Create "MaterialOrderItem" table
+CREATE TABLE "public"."MaterialOrderItem" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "MaterialOrder_Id" bigint NULL,
+ "Material_Id" bigint NULL,
+ "Count" integer NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "fk_MaterialOrderItem_Material" FOREIGN KEY ("Material_Id") REFERENCES "public"."Material" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_MaterialOrderItem_MaterialOrder" FOREIGN KEY ("MaterialOrder_Id") REFERENCES "public"."MaterialOrder" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
+-- Create "McuOrder" table
+CREATE TABLE "public"."McuOrder" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Encounter_Id" bigint NULL,
+ "Status_Code" character varying(10) NOT NULL,
+ "Doctor_Id" bigint NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "fk_McuOrder_Doctor" FOREIGN KEY ("Doctor_Id") REFERENCES "public"."Doctor" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_McuOrder_Encounter" FOREIGN KEY ("Encounter_Id") REFERENCES "public"."Encounter" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
+-- Create "McuOrderItem" table
+CREATE TABLE "public"."McuOrderItem" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "McuOrder_Id" bigint NULL,
+ "McuSrc_Id" bigint NULL,
+ "Result" text NULL,
+ "Status_Code" text NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "fk_McuOrderItem_McuOrder" FOREIGN KEY ("McuOrder_Id") REFERENCES "public"."McuOrder" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_McuOrderItem_McuSrc" FOREIGN KEY ("McuSrc_Id") REFERENCES "public"."McuSrc" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
+-- Create "Medication" table
+CREATE TABLE "public"."Medication" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Encounter_Id" bigint NULL,
+ "IssuedAt" timestamptz NULL,
+ "Pharmacist_Id" bigint NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "fk_Medication_Encounter" FOREIGN KEY ("Encounter_Id") REFERENCES "public"."Encounter" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_Medication_Pharmacist" FOREIGN KEY ("Pharmacist_Id") REFERENCES "public"."Pharmacist" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
+-- Create "MedicationItem" table
+CREATE TABLE "public"."MedicationItem" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Medication_Id" bigint NULL,
+ "IsMix" boolean NULL,
+ "Medicine_Id" bigint NULL,
+ "MedicineMix_Id" bigint NULL,
+ "Usage" smallint NULL,
+ "Interval" smallint NULL,
+ "IntervalUnit_Code" text NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "fk_MedicationItem_Medication" FOREIGN KEY ("Medication_Id") REFERENCES "public"."Medication" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_MedicationItem_Medicine" FOREIGN KEY ("Medicine_Id") REFERENCES "public"."Medicine" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_MedicationItem_MedicineMix" FOREIGN KEY ("MedicineMix_Id") REFERENCES "public"."MedicineMix" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
+-- Create "MedicationItemDist" table
+CREATE TABLE "public"."MedicationItemDist" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "MedicationItem_Id" bigint NULL,
+ "DateTime" timestamptz NULL,
+ "Remain" bigint NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "fk_MedicationItemDist_MedicationItem" FOREIGN KEY ("MedicationItem_Id") REFERENCES "public"."MedicationItem" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
+-- Create "Prescription" table
+CREATE TABLE "public"."Prescription" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Encounter_Id" bigint NULL,
+ "Doctor_Id" bigint NULL,
+ "IssuedAt" timestamptz NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "fk_Prescription_Doctor" FOREIGN KEY ("Doctor_Id") REFERENCES "public"."Doctor" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_Prescription_Encounter" FOREIGN KEY ("Encounter_Id") REFERENCES "public"."Encounter" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
+-- Create "PrescriptionItem" table
+CREATE TABLE "public"."PrescriptionItem" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Prescription_Id" bigint NULL,
+ "IsMix" boolean NULL,
+ "Medicine_Id" bigint NULL,
+ "MedicineMix_Id" bigint NULL,
+ "Usage" smallint NULL,
+ "Interval" smallint NULL,
+ "IntervalUnit_Code" text NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "fk_PrescriptionItem_Medicine" FOREIGN KEY ("Medicine_Id") REFERENCES "public"."Medicine" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_PrescriptionItem_MedicineMix" FOREIGN KEY ("MedicineMix_Id") REFERENCES "public"."MedicineMix" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_PrescriptionItem_Prescription" FOREIGN KEY ("Prescription_Id") REFERENCES "public"."Prescription" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
diff --git a/cmd/main-migration/migrations/20250916043819.sql b/cmd/main-migration/migrations/20250916043819.sql
new file mode 100644
index 00000000..1abe147b
--- /dev/null
+++ b/cmd/main-migration/migrations/20250916043819.sql
@@ -0,0 +1,14 @@
+-- Modify "DeviceOrder" table
+ALTER TABLE "public"."DeviceOrder" ADD COLUMN "Status_Code" text NULL;
+-- Modify "DeviceOrderItem" table
+ALTER TABLE "public"."DeviceOrderItem" ADD COLUMN "Count" smallint NULL;
+-- Modify "MaterialOrder" table
+ALTER TABLE "public"."MaterialOrder" ADD COLUMN "Status_Code" text NULL;
+-- Modify "Medication" table
+ALTER TABLE "public"."Medication" ADD COLUMN "Status_Code" text NULL;
+-- Modify "MedicationItem" table
+ALTER TABLE "public"."MedicationItem" ALTER COLUMN "Usage" TYPE numeric, ADD COLUMN "IsRedeemed" boolean NULL;
+-- Modify "PrescriptionItem" table
+ALTER TABLE "public"."PrescriptionItem" ALTER COLUMN "Usage" TYPE numeric;
+-- Modify "MedicationItemDist" table
+ALTER TABLE "public"."MedicationItemDist" ALTER COLUMN "Remain" TYPE numeric, ADD COLUMN "Nurse_Id" bigint NULL, ADD CONSTRAINT "fk_MedicationItemDist_Nurse" FOREIGN KEY ("Nurse_Id") REFERENCES "public"."Nurse" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION;
diff --git a/cmd/main-migration/migrations/20250917040616.sql b/cmd/main-migration/migrations/20250917040616.sql
new file mode 100644
index 00000000..71fc13e7
--- /dev/null
+++ b/cmd/main-migration/migrations/20250917040616.sql
@@ -0,0 +1,8 @@
+-- Modify "MedicationItem" table
+ALTER TABLE "public"."MedicationItem" ADD COLUMN "Quantity" numeric NULL;
+-- Modify "MedicineMix" table
+ALTER TABLE "public"."MedicineMix" ADD COLUMN "Note" text NULL;
+-- Modify "Prescription" table
+ALTER TABLE "public"."Prescription" ADD COLUMN "Status_Code" text NULL;
+-- Modify "PrescriptionItem" table
+ALTER TABLE "public"."PrescriptionItem" ADD COLUMN "Quantity" numeric NULL;
diff --git a/cmd/main-migration/migrations/20250917040751.sql b/cmd/main-migration/migrations/20250917040751.sql
new file mode 100644
index 00000000..0b8f243b
--- /dev/null
+++ b/cmd/main-migration/migrations/20250917040751.sql
@@ -0,0 +1,2 @@
+-- Modify "MedicationItem" table
+ALTER TABLE "public"."MedicationItem" ADD COLUMN "Note" character varying(1024) NULL;
diff --git a/cmd/main-migration/migrations/20250917045138.sql b/cmd/main-migration/migrations/20250917045138.sql
new file mode 100644
index 00000000..b40ade76
--- /dev/null
+++ b/cmd/main-migration/migrations/20250917045138.sql
@@ -0,0 +1,2 @@
+-- Modify "MedicineMixItem" table
+ALTER TABLE "public"."MedicineMixItem" DROP CONSTRAINT "fk_MedicineMixItem_MedicineMix", ADD CONSTRAINT "fk_MedicineMix_MixItems" FOREIGN KEY ("MedicineMix_Id") REFERENCES "public"."MedicineMix" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION;
diff --git a/cmd/main-migration/migrations/20250917093645.sql b/cmd/main-migration/migrations/20250917093645.sql
new file mode 100644
index 00000000..b0922c6a
--- /dev/null
+++ b/cmd/main-migration/migrations/20250917093645.sql
@@ -0,0 +1,4 @@
+-- Modify "MedicineMix" table
+ALTER TABLE "public"."MedicineMix" DROP COLUMN "Note";
+-- Modify "MedicineMixItem" table
+ALTER TABLE "public"."MedicineMixItem" ADD COLUMN "Note" text NULL;
diff --git a/cmd/main-migration/migrations/20250918073552.sql b/cmd/main-migration/migrations/20250918073552.sql
new file mode 100644
index 00000000..1b45e5d4
--- /dev/null
+++ b/cmd/main-migration/migrations/20250918073552.sql
@@ -0,0 +1,10 @@
+-- Modify "McuOrder" table
+ALTER TABLE "public"."McuOrder" ADD COLUMN "SpecimenPickTime" timestamptz NULL, ADD COLUMN "ExaminationDate" timestamptz NULL, ADD COLUMN "Number" smallint NULL, ADD COLUMN "Temperature" numeric NULL, ADD COLUMN "McuUrgencyLevel_Code" character varying(10) NOT NULL;
+-- Modify "McuOrderItem" table
+ALTER TABLE "public"."McuOrderItem" ADD COLUMN "ExaminationDate" timestamptz NULL;
+-- Create index "idx_order_src" to table: "McuOrderItem"
+CREATE UNIQUE INDEX "idx_order_src" ON "public"."McuOrderItem" ("McuOrder_Id", "McuSrc_Id");
+-- Modify "PersonRelative" table
+ALTER TABLE "public"."PersonRelative" ADD COLUMN "Responsible" boolean NULL;
+-- Modify "McuSrc" table
+ALTER TABLE "public"."McuSrc" ALTER COLUMN "Id" TYPE bigint, ADD COLUMN "Item_Id" bigint NULL, ADD CONSTRAINT "fk_McuSrc_Item" FOREIGN KEY ("Item_Id") REFERENCES "public"."Item" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION;
diff --git a/cmd/main-migration/migrations/20250918073742.sql b/cmd/main-migration/migrations/20250918073742.sql
new file mode 100644
index 00000000..28611d73
--- /dev/null
+++ b/cmd/main-migration/migrations/20250918073742.sql
@@ -0,0 +1,31 @@
+-- Create "McuSubSrc" table
+CREATE TABLE "public"."McuSubSrc" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Code" character varying(20) NULL,
+ "Name" character varying(50) NULL,
+ "McuSrc_Id" bigint NULL,
+ "Item_Id" bigint NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "uni_McuSubSrc_Code" UNIQUE ("Code"),
+ CONSTRAINT "fk_McuSubSrc_Item" FOREIGN KEY ("Item_Id") REFERENCES "public"."Item" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_McuSubSrc_McuSrc" FOREIGN KEY ("McuSrc_Id") REFERENCES "public"."McuSrc" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
+-- Create "McuOrderSubItem" table
+CREATE TABLE "public"."McuOrderSubItem" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "McuSubSrc_Id" bigint NULL,
+ "McuOrderItem_Id" bigint NULL,
+ "Result" text NULL,
+ "Status_Code" text NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "fk_McuOrderSubItem_McuOrderItem" FOREIGN KEY ("McuOrderItem_Id") REFERENCES "public"."McuOrderItem" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_McuOrderSubItem_McuSubSrc" FOREIGN KEY ("McuSubSrc_Id") REFERENCES "public"."McuSubSrc" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
+-- Create index "idx_order_sub_src" to table: "McuOrderSubItem"
+CREATE UNIQUE INDEX "idx_order_sub_src" ON "public"."McuOrderSubItem" ("McuSubSrc_Id", "McuOrderItem_Id");
diff --git a/cmd/main-migration/migrations/20250918074745.sql b/cmd/main-migration/migrations/20250918074745.sql
new file mode 100644
index 00000000..365227cb
--- /dev/null
+++ b/cmd/main-migration/migrations/20250918074745.sql
@@ -0,0 +1,2 @@
+-- Modify "McuOrder" table
+ALTER TABLE "public"."McuOrder" ALTER COLUMN "McuUrgencyLevel_Code" TYPE character varying(15);
diff --git a/cmd/main-migration/migrations/20250923025134.sql b/cmd/main-migration/migrations/20250923025134.sql
new file mode 100644
index 00000000..57a04744
--- /dev/null
+++ b/cmd/main-migration/migrations/20250923025134.sql
@@ -0,0 +1,17 @@
+-- Create "Consultation" table
+CREATE TABLE "public"."Consultation" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Encounter_Id" bigint NULL,
+ "Case" character varying(2048) NULL,
+ "Solution" character varying(2048) NULL,
+ "Unit_Id" bigint NULL,
+ "Doctor_Id" bigint NULL,
+ "RepliedAt" timestamptz NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "fk_Consultation_Doctor" FOREIGN KEY ("Doctor_Id") REFERENCES "public"."Doctor" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_Consultation_Encounter" FOREIGN KEY ("Encounter_Id") REFERENCES "public"."Encounter" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_Consultation_Unit" FOREIGN KEY ("Unit_Id") REFERENCES "public"."Unit" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
diff --git a/cmd/main-migration/migrations/20250924051317.sql b/cmd/main-migration/migrations/20250924051317.sql
new file mode 100644
index 00000000..f0f58947
--- /dev/null
+++ b/cmd/main-migration/migrations/20250924051317.sql
@@ -0,0 +1,2 @@
+-- Modify "Person" table
+ALTER TABLE "public"."Person" ADD COLUMN "ResidentIdentityFileUrl" character varying(1024) NULL, ADD COLUMN "PassportFileUrl" character varying(1024) NULL, ADD COLUMN "DrivingLicenseFileUrl" character varying(1024) NULL, ADD COLUMN "FamilyIdentityFileUrl" character varying(1024) NULL;
diff --git a/cmd/main-migration/migrations/20250929034321.sql b/cmd/main-migration/migrations/20250929034321.sql
new file mode 100644
index 00000000..bfdc5021
--- /dev/null
+++ b/cmd/main-migration/migrations/20250929034321.sql
@@ -0,0 +1,2 @@
+-- Modify "Soapi" table
+ALTER TABLE "public"."Soapi" ADD COLUMN "TypeCode" text NULL;
diff --git a/cmd/main-migration/migrations/20250929034428.sql b/cmd/main-migration/migrations/20250929034428.sql
new file mode 100644
index 00000000..84a214a5
--- /dev/null
+++ b/cmd/main-migration/migrations/20250929034428.sql
@@ -0,0 +1,2 @@
+-- Modify "Soapi" table
+ALTER TABLE "public"."Soapi" ALTER COLUMN "TypeCode" TYPE character varying(11);
diff --git a/cmd/main-migration/migrations/20250930025550.sql b/cmd/main-migration/migrations/20250930025550.sql
new file mode 100644
index 00000000..cb24b7fc
--- /dev/null
+++ b/cmd/main-migration/migrations/20250930025550.sql
@@ -0,0 +1,6 @@
+-- Modify "MedicationItem" table
+ALTER TABLE "public"."MedicationItem" ALTER COLUMN "Usage" TYPE character varying(255), ADD COLUMN "Frequency" integer NULL, ADD COLUMN "Dose" numeric NULL;
+-- Modify "PrescriptionItem" table
+ALTER TABLE "public"."PrescriptionItem" ALTER COLUMN "Usage" TYPE character varying(255), ADD COLUMN "Frequency" integer NULL, ADD COLUMN "Dose" numeric NULL;
+-- Modify "MedicineMix" table
+ALTER TABLE "public"."MedicineMix" ADD COLUMN "Uom_Code" character varying(10) NULL, ADD CONSTRAINT "fk_MedicineMix_Uom" FOREIGN KEY ("Uom_Code") REFERENCES "public"."Uom" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION;
diff --git a/cmd/main-migration/migrations/20250930140351.sql b/cmd/main-migration/migrations/20250930140351.sql
new file mode 100644
index 00000000..c98fd12a
--- /dev/null
+++ b/cmd/main-migration/migrations/20250930140351.sql
@@ -0,0 +1,4 @@
+-- Rename a column from "CheckupCategory_Code" to "McuSrcCategory_Code"
+ALTER TABLE "public"."McuSrc" RENAME COLUMN "CheckupCategory_Code" TO "McuSrcCategory_Code";
+-- Modify "McuSrc" table
+ALTER TABLE "public"."McuSrc" DROP CONSTRAINT "fk_McuSrc_CheckupCategory", ADD CONSTRAINT "fk_McuSrc_McuSrcCategory" FOREIGN KEY ("McuSrcCategory_Code") REFERENCES "public"."McuSrcCategory" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION;
diff --git a/cmd/main-migration/migrations/20251002085604.sql b/cmd/main-migration/migrations/20251002085604.sql
new file mode 100644
index 00000000..e215cd13
--- /dev/null
+++ b/cmd/main-migration/migrations/20251002085604.sql
@@ -0,0 +1,2 @@
+-- Modify "Division" table
+ALTER TABLE "public"."Division" ALTER COLUMN "Parent_Id" TYPE integer, ADD CONSTRAINT "fk_Division_Childrens" FOREIGN KEY ("Parent_Id") REFERENCES "public"."Division" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION;
diff --git a/cmd/main-migration/migrations/20251003032030.sql b/cmd/main-migration/migrations/20251003032030.sql
new file mode 100644
index 00000000..2bdf73ba
--- /dev/null
+++ b/cmd/main-migration/migrations/20251003032030.sql
@@ -0,0 +1,6 @@
+-- Modify "Infra" table
+ALTER TABLE "public"."Infra" ADD CONSTRAINT "fk_Infra_Childrens" FOREIGN KEY ("Parent_Id") REFERENCES "public"."Infra" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION;
+-- Modify "DeviceOrder" table
+ALTER TABLE "public"."DeviceOrder" ADD COLUMN "Doctor_Id" bigint NULL, ADD CONSTRAINT "fk_DeviceOrder_Doctor" FOREIGN KEY ("Doctor_Id") REFERENCES "public"."Doctor" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION;
+-- Modify "MaterialOrder" table
+ALTER TABLE "public"."MaterialOrder" ADD COLUMN "Doctor_Id" bigint NULL, ADD CONSTRAINT "fk_MaterialOrder_Doctor" FOREIGN KEY ("Doctor_Id") REFERENCES "public"."Doctor" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION;
diff --git a/cmd/main-migration/migrations/20251005060450.sql b/cmd/main-migration/migrations/20251005060450.sql
new file mode 100644
index 00000000..7ec05f92
--- /dev/null
+++ b/cmd/main-migration/migrations/20251005060450.sql
@@ -0,0 +1,24 @@
+-- Modify "Person" table
+ALTER TABLE "public"."Person" ADD COLUMN "Nationality" text NULL;
+-- Create "Chemo" table
+CREATE TABLE "public"."Chemo" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Encounter_Id" bigint NULL,
+ "Status_Code" text NULL,
+ "VerifiedAt" timestamptz NULL,
+ "VerifiedBy_User_Id" bigint NULL,
+ "SrcUnit_Id" bigint NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "fk_Chemo_Encounter" FOREIGN KEY ("Encounter_Id") REFERENCES "public"."Encounter" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_Chemo_SrcUnit" FOREIGN KEY ("SrcUnit_Id") REFERENCES "public"."Unit" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_Chemo_VerifiedBy" FOREIGN KEY ("VerifiedBy_User_Id") REFERENCES "public"."User" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
+-- Rename a column from "Unit_Id" to "DstUnit_Id"
+ALTER TABLE "public"."Consultation" RENAME COLUMN "Unit_Id" TO "DstUnit_Id";
+-- Rename a column from "Doctor_Id" to "DstDoctor_Id"
+ALTER TABLE "public"."Consultation" RENAME COLUMN "Doctor_Id" TO "DstDoctor_Id";
+-- Modify "Consultation" table
+ALTER TABLE "public"."Consultation" DROP CONSTRAINT "fk_Consultation_Doctor", DROP CONSTRAINT "fk_Consultation_Unit", DROP COLUMN "Case", ALTER COLUMN "Solution" TYPE character varying(10240), ADD COLUMN "Date" timestamptz NULL, ADD COLUMN "Problem" character varying(10240) NULL, ADD CONSTRAINT "fk_Consultation_DstDoctor" FOREIGN KEY ("DstDoctor_Id") REFERENCES "public"."Doctor" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION, ADD CONSTRAINT "fk_Consultation_DstUnit" FOREIGN KEY ("DstUnit_Id") REFERENCES "public"."Unit" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION;
diff --git a/cmd/main-migration/migrations/20251006041122.sql b/cmd/main-migration/migrations/20251006041122.sql
new file mode 100644
index 00000000..24ace4a9
--- /dev/null
+++ b/cmd/main-migration/migrations/20251006041122.sql
@@ -0,0 +1,2 @@
+-- Modify "DivisionPosition" table
+ALTER TABLE "public"."DivisionPosition" ADD COLUMN "Employee_Id" bigint NULL, ADD CONSTRAINT "fk_DivisionPosition_Employee" FOREIGN KEY ("Employee_Id") REFERENCES "public"."Employee" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION;
diff --git a/cmd/main-migration/migrations/20251006045658.sql b/cmd/main-migration/migrations/20251006045658.sql
new file mode 100644
index 00000000..a8c3a4d7
--- /dev/null
+++ b/cmd/main-migration/migrations/20251006045658.sql
@@ -0,0 +1,2 @@
+-- Modify "Person" table
+ALTER TABLE "public"."Person" ADD COLUMN "CommunicationIssueStatus" boolean NULL, ADD COLUMN "Disabillity" character varying(100) NULL;
diff --git a/cmd/main-migration/migrations/20251006045928.sql b/cmd/main-migration/migrations/20251006045928.sql
new file mode 100644
index 00000000..f495a26d
--- /dev/null
+++ b/cmd/main-migration/migrations/20251006045928.sql
@@ -0,0 +1,2 @@
+-- Rename a column from "Disabillity" to "Disability"
+ALTER TABLE "public"."Person" RENAME COLUMN "Disabillity" TO "Disability";
diff --git a/cmd/main-migration/migrations/20251007022859.sql b/cmd/main-migration/migrations/20251007022859.sql
new file mode 100644
index 00000000..03b0890b
--- /dev/null
+++ b/cmd/main-migration/migrations/20251007022859.sql
@@ -0,0 +1,2 @@
+-- Modify "Patient" table
+ALTER TABLE "public"."Patient" ADD COLUMN "NewBornStatus" boolean NULL;
diff --git a/cmd/main-migration/migrations/20251008031337.sql b/cmd/main-migration/migrations/20251008031337.sql
new file mode 100644
index 00000000..fd2aff8a
--- /dev/null
+++ b/cmd/main-migration/migrations/20251008031337.sql
@@ -0,0 +1,2 @@
+-- Modify "PersonAddress" table
+ALTER TABLE "public"."PersonAddress" ADD COLUMN "PostalCode" character varying(6) NULL;
diff --git a/cmd/main-migration/migrations/20251008031554.sql b/cmd/main-migration/migrations/20251008031554.sql
new file mode 100644
index 00000000..58cee318
--- /dev/null
+++ b/cmd/main-migration/migrations/20251008031554.sql
@@ -0,0 +1,12 @@
+-- Create "Midwife" table
+CREATE TABLE "public"."Midwife" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Employee_Id" bigint NULL,
+ "IHS_Number" character varying(20) NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "uni_Midwife_IHS_Number" UNIQUE ("IHS_Number"),
+ CONSTRAINT "fk_Midwife_Employee" FOREIGN KEY ("Employee_Id") REFERENCES "public"."Employee" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
diff --git a/cmd/main-migration/migrations/20251008052346.sql b/cmd/main-migration/migrations/20251008052346.sql
new file mode 100644
index 00000000..d664f92d
--- /dev/null
+++ b/cmd/main-migration/migrations/20251008052346.sql
@@ -0,0 +1,2 @@
+-- Modify "DivisionPosition" table
+ALTER TABLE "public"."DivisionPosition" ADD COLUMN "HeadStatus" boolean NULL;
diff --git a/cmd/main-migration/migrations/20251008073620.sql b/cmd/main-migration/migrations/20251008073620.sql
new file mode 100644
index 00000000..f3d9cf60
--- /dev/null
+++ b/cmd/main-migration/migrations/20251008073620.sql
@@ -0,0 +1,2 @@
+-- Modify "Infra" table
+ALTER TABLE "public"."Infra" ALTER COLUMN "InfraGroup_Code" TYPE character varying(15);
diff --git a/cmd/main-migration/migrations/20251009042854.sql b/cmd/main-migration/migrations/20251009042854.sql
new file mode 100644
index 00000000..c8b5ec23
--- /dev/null
+++ b/cmd/main-migration/migrations/20251009042854.sql
@@ -0,0 +1,9 @@
+-- Create "PostalCode" table
+CREATE TABLE "public"."PostalCode" (
+ "Id" bigserial NOT NULL,
+ "Code" character varying(5) NULL,
+ "Village_Code" character varying(10) NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "uni_PostalCode_Code" UNIQUE ("Code"),
+ CONSTRAINT "fk_Village_PostalCodes" FOREIGN KEY ("Village_Code") REFERENCES "public"."Village" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
diff --git a/cmd/main-migration/migrations/20251009052657.sql b/cmd/main-migration/migrations/20251009052657.sql
new file mode 100644
index 00000000..5655a577
--- /dev/null
+++ b/cmd/main-migration/migrations/20251009052657.sql
@@ -0,0 +1,8 @@
+-- Modify "Regency" table
+ALTER TABLE "public"."Regency" DROP CONSTRAINT "fk_Province_Regencies", ALTER COLUMN "Id" TYPE bigint, ADD CONSTRAINT "fk_Regency_Province" FOREIGN KEY ("Province_Code") REFERENCES "public"."Province" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION;
+-- Modify "District" table
+ALTER TABLE "public"."District" DROP CONSTRAINT "fk_Regency_Districts", ADD CONSTRAINT "fk_District_Regency" FOREIGN KEY ("Regency_Code") REFERENCES "public"."Regency" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION;
+-- Modify "Village" table
+ALTER TABLE "public"."Village" DROP CONSTRAINT "fk_District_Villages", ADD CONSTRAINT "fk_Village_District" FOREIGN KEY ("District_Code") REFERENCES "public"."District" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION;
+-- Modify "PostalCode" table
+ALTER TABLE "public"."PostalCode" DROP CONSTRAINT "fk_Village_PostalCodes", ADD CONSTRAINT "fk_PostalCode_Village" FOREIGN KEY ("Village_Code") REFERENCES "public"."Village" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION;
diff --git a/cmd/main-migration/migrations/20251010031743.sql b/cmd/main-migration/migrations/20251010031743.sql
new file mode 100644
index 00000000..1dea016a
--- /dev/null
+++ b/cmd/main-migration/migrations/20251010031743.sql
@@ -0,0 +1,6 @@
+-- Modify "Person" table
+ALTER TABLE "public"."Person" ADD CONSTRAINT "fk_Person_BirthRegency" FOREIGN KEY ("BirthRegency_Code") REFERENCES "public"."Regency" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION;
+-- Rename a column from "PostalCode" to "PostalCode_Code"
+ALTER TABLE "public"."PersonAddress" RENAME COLUMN "PostalCode" TO "PostalCode_Code";
+-- Modify "PersonAddress" table
+ALTER TABLE "public"."PersonAddress" ADD CONSTRAINT "fk_PersonAddress_PostalCode" FOREIGN KEY ("PostalCode_Code") REFERENCES "public"."PostalCode" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION;
diff --git a/cmd/main-migration/migrations/20251010070721.sql b/cmd/main-migration/migrations/20251010070721.sql
new file mode 100644
index 00000000..ee030931
--- /dev/null
+++ b/cmd/main-migration/migrations/20251010070721.sql
@@ -0,0 +1,15 @@
+-- Create "PostalRegion" table
+CREATE TABLE "public"."PostalRegion" (
+ "Id" bigserial NOT NULL,
+ "Village_Code" character varying(10) NULL,
+ "Code" character varying(5) NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "uni_PostalRegion_Code" UNIQUE ("Code"),
+ CONSTRAINT "fk_PostalRegion_Village" FOREIGN KEY ("Village_Code") REFERENCES "public"."Village" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
+-- Rename a column from "PostalCode_Code" to "PostalRegion_Code"
+ALTER TABLE "public"."PersonAddress" RENAME COLUMN "PostalCode_Code" TO "PostalRegion_Code";
+-- Modify "PersonAddress" table
+ALTER TABLE "public"."PersonAddress" DROP CONSTRAINT "fk_PersonAddress_PostalCode", ADD COLUMN "LocationType_Code" character varying(10) NULL, ADD CONSTRAINT "fk_PersonAddress_PostalRegion" FOREIGN KEY ("PostalRegion_Code") REFERENCES "public"."PostalRegion" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION;
+-- Drop "PostalCode" table
+DROP TABLE "public"."PostalCode";
diff --git a/cmd/main-migration/migrations/20251010072711.sql b/cmd/main-migration/migrations/20251010072711.sql
new file mode 100644
index 00000000..f4b24a4f
--- /dev/null
+++ b/cmd/main-migration/migrations/20251010072711.sql
@@ -0,0 +1,2 @@
+-- Modify "PersonAddress" table
+ALTER TABLE "public"."PersonAddress" ADD CONSTRAINT "fk_PersonAddress_Village" FOREIGN KEY ("Village_Code") REFERENCES "public"."Village" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION;
diff --git a/cmd/main-migration/migrations/20251013044536.sql b/cmd/main-migration/migrations/20251013044536.sql
new file mode 100644
index 00000000..84bdf0b0
--- /dev/null
+++ b/cmd/main-migration/migrations/20251013044536.sql
@@ -0,0 +1,14 @@
+-- Create "CheckoutPolies" table
+CREATE TABLE "public"."CheckoutPolies" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Encounter_Id" bigint NULL,
+ "Unit_Id" integer NULL,
+ "Doctor_Id" bigint NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "fk_CheckoutPolies_Doctor" FOREIGN KEY ("Doctor_Id") REFERENCES "public"."Doctor" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_CheckoutPolies_Encounter" FOREIGN KEY ("Encounter_Id") REFERENCES "public"."Encounter" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_CheckoutPolies_Unit" FOREIGN KEY ("Unit_Id") REFERENCES "public"."Unit" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
diff --git a/cmd/main-migration/migrations/20251013051438.sql b/cmd/main-migration/migrations/20251013051438.sql
new file mode 100644
index 00000000..791f3384
--- /dev/null
+++ b/cmd/main-migration/migrations/20251013051438.sql
@@ -0,0 +1,2 @@
+-- Modify "Encounter" table
+ALTER TABLE "public"."Encounter" ALTER COLUMN "DischargeMethod_Code" TYPE character varying(16);
diff --git a/cmd/main-migration/migrations/20251013081808.sql b/cmd/main-migration/migrations/20251013081808.sql
new file mode 100644
index 00000000..03bf02ce
--- /dev/null
+++ b/cmd/main-migration/migrations/20251013081808.sql
@@ -0,0 +1,16 @@
+-- Create "InternalReference" table
+CREATE TABLE "public"."InternalReference" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Encounter_Id" bigint NULL,
+ "Unit_Id" integer NULL,
+ "Doctor_Id" bigint NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "fk_InternalReference_Doctor" FOREIGN KEY ("Doctor_Id") REFERENCES "public"."Doctor" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_InternalReference_Encounter" FOREIGN KEY ("Encounter_Id") REFERENCES "public"."Encounter" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_InternalReference_Unit" FOREIGN KEY ("Unit_Id") REFERENCES "public"."Unit" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
+-- Drop "CheckoutPolies" table
+DROP TABLE "public"."CheckoutPolies";
diff --git a/cmd/main-migration/migrations/20251014060047.sql b/cmd/main-migration/migrations/20251014060047.sql
new file mode 100644
index 00000000..1d13853a
--- /dev/null
+++ b/cmd/main-migration/migrations/20251014060047.sql
@@ -0,0 +1,36 @@
+-- Create "VClaimSepHist" table
+CREATE TABLE "public"."VClaimSepHist" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "RequestPayload" text NULL,
+ "ResponseBody" text NULL,
+ "Message" text NULL,
+ PRIMARY KEY ("Id")
+);
+-- Modify "Encounter" table
+ALTER TABLE "public"."Encounter" ADD COLUMN "PaymentMethod_Code" character varying(10) NULL, ADD COLUMN "InsuranceCompany_Id" bigint NULL, ADD COLUMN "Member_Number" character varying(20) NULL, ADD COLUMN "Ref_Number" character varying(20) NULL, ADD COLUMN "Trx_Number" character varying(20) NULL, ADD COLUMN "Adm_Employee_Id" bigint NULL, ADD CONSTRAINT "uni_Encounter_Member_Number" UNIQUE ("Member_Number"), ADD CONSTRAINT "uni_Encounter_Ref_Number" UNIQUE ("Ref_Number"), ADD CONSTRAINT "uni_Encounter_Trx_Number" UNIQUE ("Trx_Number"), ADD CONSTRAINT "fk_Encounter_Adm_Employee" FOREIGN KEY ("Adm_Employee_Id") REFERENCES "public"."Employee" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION, ADD CONSTRAINT "fk_Encounter_InsuranceCompany" FOREIGN KEY ("InsuranceCompany_Id") REFERENCES "public"."InsuranceCompany" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION;
+-- Create "VClaimSep" table
+CREATE TABLE "public"."VClaimSep" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Encounter_Id" bigint NULL,
+ "Number" character varying(19) NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "uni_VClaimSep_Number" UNIQUE ("Number"),
+ CONSTRAINT "fk_Encounter_VclaimSep" FOREIGN KEY ("Encounter_Id") REFERENCES "public"."Encounter" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
+-- Create "VClaimSepPrint" table
+CREATE TABLE "public"."VClaimSepPrint" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "VclaimSep_Number" character varying(19) NULL,
+ "Counter" bigint NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "fk_VClaimSepPrint_VclaimSep" FOREIGN KEY ("VclaimSep_Number") REFERENCES "public"."VClaimSep" ("Number") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
diff --git a/cmd/main-migration/migrations/20251014063537.sql b/cmd/main-migration/migrations/20251014063537.sql
new file mode 100644
index 00000000..7b77b3d9
--- /dev/null
+++ b/cmd/main-migration/migrations/20251014063537.sql
@@ -0,0 +1,16 @@
+-- Create "VclaimSep" table
+CREATE TABLE "public"."VclaimSep" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Encounter_Id" bigint NULL,
+ "Number" character varying(19) NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "uni_VclaimSep_Number" UNIQUE ("Number"),
+ CONSTRAINT "fk_Encounter_VclaimSep" FOREIGN KEY ("Encounter_Id") REFERENCES "public"."Encounter" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
+-- Modify "VClaimSepPrint" table
+ALTER TABLE "public"."VClaimSepPrint" DROP CONSTRAINT "fk_VClaimSepPrint_VclaimSep", ADD CONSTRAINT "fk_VClaimSepPrint_VclaimSep" FOREIGN KEY ("VclaimSep_Number") REFERENCES "public"."VclaimSep" ("Number") ON UPDATE NO ACTION ON DELETE NO ACTION;
+-- Drop "VClaimSep" table
+DROP TABLE "public"."VClaimSep";
diff --git a/cmd/main-migration/migrations/20251014063720.sql b/cmd/main-migration/migrations/20251014063720.sql
new file mode 100644
index 00000000..0763c12b
--- /dev/null
+++ b/cmd/main-migration/migrations/20251014063720.sql
@@ -0,0 +1,26 @@
+-- Create "VclaimSepHist" table
+CREATE TABLE "public"."VclaimSepHist" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "RequestPayload" text NULL,
+ "ResponseBody" text NULL,
+ "Message" text NULL,
+ PRIMARY KEY ("Id")
+);
+-- Create "VclaimSepPrint" table
+CREATE TABLE "public"."VclaimSepPrint" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "VclaimSep_Number" character varying(19) NULL,
+ "Counter" bigint NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "fk_VclaimSepPrint_VclaimSep" FOREIGN KEY ("VclaimSep_Number") REFERENCES "public"."VclaimSep" ("Number") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
+-- Drop "VClaimSepHist" table
+DROP TABLE "public"."VClaimSepHist";
+-- Drop "VClaimSepPrint" table
+DROP TABLE "public"."VClaimSepPrint";
diff --git a/cmd/main-migration/migrations/20251015045455.sql b/cmd/main-migration/migrations/20251015045455.sql
new file mode 100644
index 00000000..f2b6be7a
--- /dev/null
+++ b/cmd/main-migration/migrations/20251015045455.sql
@@ -0,0 +1,2 @@
+-- Modify "Chemo" table
+ALTER TABLE "public"."Chemo" ADD COLUMN "ClassCode" text NULL;
diff --git a/cmd/main-migration/migrations/20251016010845.sql b/cmd/main-migration/migrations/20251016010845.sql
new file mode 100644
index 00000000..edbbb414
--- /dev/null
+++ b/cmd/main-migration/migrations/20251016010845.sql
@@ -0,0 +1,2 @@
+-- Rename a column from "ClassCode" to "Class_Code"
+ALTER TABLE "public"."Chemo" RENAME COLUMN "ClassCode" TO "Class_Code";
diff --git a/cmd/main-migration/migrations/20251016011023.sql b/cmd/main-migration/migrations/20251016011023.sql
new file mode 100644
index 00000000..12e51e7d
--- /dev/null
+++ b/cmd/main-migration/migrations/20251016011023.sql
@@ -0,0 +1,17 @@
+-- Create "PersonInsurance" table
+CREATE TABLE "public"."PersonInsurance" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Person_Id" bigint NULL,
+ "InsuranceCompany_Id" bigint NULL,
+ "Ref_Number" character varying(20) NULL,
+ "DefaultStatus" boolean NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "uni_PersonInsurance_Ref_Number" UNIQUE ("Ref_Number"),
+ CONSTRAINT "fk_PersonInsurance_InsuranceCompany" FOREIGN KEY ("InsuranceCompany_Id") REFERENCES "public"."InsuranceCompany" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_Person_Insurances" FOREIGN KEY ("Person_Id") REFERENCES "public"."Person" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
+-- Create index "idx_person_insurance" to table: "PersonInsurance"
+CREATE UNIQUE INDEX "idx_person_insurance" ON "public"."PersonInsurance" ("Person_Id", "DefaultStatus");
diff --git a/cmd/main-migration/migrations/20251016062912.sql b/cmd/main-migration/migrations/20251016062912.sql
new file mode 100644
index 00000000..b9208471
--- /dev/null
+++ b/cmd/main-migration/migrations/20251016062912.sql
@@ -0,0 +1,54 @@
+-- Create "AmbulanceTransportReq" table
+CREATE TABLE "public"."AmbulanceTransportReq" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Patient_Id" bigint NULL,
+ "Diagnoses" character varying(1024) NULL,
+ "RequestData" timestamptz NULL,
+ "UsageDate" timestamptz NULL,
+ "Address" character varying(100) NULL,
+ "RtRw" character varying(10) NULL,
+ "Province_Code" character varying(2) NULL,
+ "Regency_Code" character varying(4) NULL,
+ "District_Code" character varying(6) NULL,
+ "Village_Code" character varying(10) NULL,
+ "Facility_Code" character varying(10) NULL,
+ "Needs_Code" character varying(10) NULL,
+ "Contact_Name" character varying(100) NULL,
+ "Contact_Relationship_Code" character varying(10) NULL,
+ "Contact_PhoneNumber" character varying(20) NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "fk_AmbulanceTransportReq_District" FOREIGN KEY ("District_Code") REFERENCES "public"."District" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_AmbulanceTransportReq_Patient" FOREIGN KEY ("Patient_Id") REFERENCES "public"."Patient" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_AmbulanceTransportReq_Province" FOREIGN KEY ("Province_Code") REFERENCES "public"."Province" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_AmbulanceTransportReq_Regency" FOREIGN KEY ("Regency_Code") REFERENCES "public"."Regency" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_AmbulanceTransportReq_Village" FOREIGN KEY ("Village_Code") REFERENCES "public"."Village" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
+-- Create "Vehicle" table
+CREATE TABLE "public"."Vehicle" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Type_Code" text NULL,
+ "PoliceNumber" text NULL,
+ "FrameNumber" text NULL,
+ "RegNumber" text NULL,
+ "AvailableStatus" boolean NULL,
+ PRIMARY KEY ("Id")
+);
+-- Create "VehicleHist" table
+CREATE TABLE "public"."VehicleHist" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Vehicle_Id" bigint NULL,
+ "Date" timestamptz NULL,
+ "Data" text NULL,
+ "Crud_Code" text NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "fk_VehicleHist_Vehicle" FOREIGN KEY ("Vehicle_Id") REFERENCES "public"."Vehicle" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
diff --git a/cmd/main-migration/migrations/20251017060617.sql b/cmd/main-migration/migrations/20251017060617.sql
new file mode 100644
index 00000000..8e3acbd2
--- /dev/null
+++ b/cmd/main-migration/migrations/20251017060617.sql
@@ -0,0 +1,2 @@
+-- Modify "MedicalActionSrc" table
+ALTER TABLE "public"."MedicalActionSrc" ADD COLUMN "Type_Code" character varying(20) NULL;
diff --git a/cmd/main-migration/migrations/20251017082207.sql b/cmd/main-migration/migrations/20251017082207.sql
new file mode 100644
index 00000000..732c8d71
--- /dev/null
+++ b/cmd/main-migration/migrations/20251017082207.sql
@@ -0,0 +1,2 @@
+-- Modify "Item" table
+ALTER TABLE "public"."Item" ALTER COLUMN "ItemGroup_Code" TYPE character varying(15);
diff --git a/cmd/main-migration/migrations/20251018032635.sql b/cmd/main-migration/migrations/20251018032635.sql
new file mode 100644
index 00000000..d8c5a2c9
--- /dev/null
+++ b/cmd/main-migration/migrations/20251018032635.sql
@@ -0,0 +1,4 @@
+-- Modify "Employee" table
+ALTER TABLE "public"."Employee" ADD COLUMN "Position_Code" character varying(20) NULL;
+-- Rename a column from "Position_Code" to "ContractPosition_Code"
+ALTER TABLE "public"."User" RENAME COLUMN "Position_Code" TO "ContractPosition_Code";
diff --git a/cmd/main-migration/migrations/20251018040322.sql b/cmd/main-migration/migrations/20251018040322.sql
new file mode 100644
index 00000000..d35e9199
--- /dev/null
+++ b/cmd/main-migration/migrations/20251018040322.sql
@@ -0,0 +1,13 @@
+-- Create "Intern" table
+CREATE TABLE "public"."Intern" (
+ "Id" bigserial NOT NULL,
+ "CreatedAt" timestamptz NULL,
+ "UpdatedAt" timestamptz NULL,
+ "DeletedAt" timestamptz NULL,
+ "Person_Id" bigint NULL,
+ "Position_Code" character varying(20) NULL,
+ "User_Id" bigint NULL,
+ PRIMARY KEY ("Id"),
+ CONSTRAINT "fk_Intern_Person" FOREIGN KEY ("Person_Id") REFERENCES "public"."Person" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
+ CONSTRAINT "fk_Intern_User" FOREIGN KEY ("User_Id") REFERENCES "public"."User" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
+);
diff --git a/cmd/main-migration/migrations/atlas.sum b/cmd/main-migration/migrations/atlas.sum
new file mode 100644
index 00000000..bf732e89
--- /dev/null
+++ b/cmd/main-migration/migrations/atlas.sum
@@ -0,0 +1,53 @@
+h1:S3ggQSrIa2Lwhkx+yWmD9N2hZxRuVwCMZcEpsk83PJY=
+20250904105930.sql h1:MEM6blCgke9DzWQSTnLzasbPIrcHssNNrJqZpSkEo6k=
+20250904141448.sql h1:J8cmYNk4ZrG9fhfbi2Z1IWz7YkfvhFqTzrLFo58BPY0=
+20250908062237.sql h1:Pu23yEW/aKkwozHoOuROvHS/GK4ngARJGdO7FB7HZuI=
+20250908062323.sql h1:oXl6Z143tOpIl4EfP4B8JNU8LrMvVmHEtCgAfiB4gs8=
+20250908073811.sql h1:m2aNXfnGxnLq1+rVWrh4f60q7fhyhV3gEwNu/OIqQlE=
+20250908073839.sql h1:cPk54xjLdMs26uY8ZHjNWLuyfAMzV7Zb0/9oJQrsw04=
+20250910055902.sql h1:5xwjAV6QbtZT9empTJKfhyAjdknbHzb15B0Ku5dzqtQ=
+20250915123412.sql h1:D83xaU2YlDEd21HLup/YQpQ2easMToYCyy/oK6AFgQs=
+20250916043819.sql h1:ekoTJsBqQZ8G8n0qJ03d13+eoNoc7sAUEQGA5D/CCxk=
+20250917040616.sql h1:zoCnmcXuM7AVv85SmN7RmFglCgJnoDmpRWExH0LAc9Q=
+20250917040751.sql h1:J1xyRrh32y1+lezwAyNwPcUQ6ABBSgbvzNLva4SVdQU=
+20250917045138.sql h1:jKe1Z0uOLG4SGBYM+S/3P+/zMPztmgoderD5swnMuCg=
+20250917093645.sql h1:cNI3Pbz1R3LxvIXLuexafJFCXUXrmuFCgXXJ2sG+FW0=
+20250918073552.sql h1:RJ1SvMzP6aeWnoPVD3eVAmIQOkcp6Php8z3QRri6v4g=
+20250918073742.sql h1:+cEsnJTJFybe2fR69ZoOiX2R6c6iITl4m6WTZ1hjyzY=
+20250918074745.sql h1:2hNVQCXF/dVYXAh+T/7oBFgERGWxzVb2FXJjwkFWGCI=
+20250923025134.sql h1:Ykz/qpHiGDXPsCsWTjydQFVSibZP2D+h2fIeb2h2JGA=
+20250924051317.sql h1:yQuW6SwJxIOM5fcxeAaie5lSm1oLysU/C2hH2xNCVoQ=
+20250929034321.sql h1:101FJ8VH12mrZWlt/X1gvKUGOhoiF8tFbjiapAjnHzg=
+20250929034428.sql h1:i+pROD9p+g5dOmmZma6WF/0Hw5g3Ha28NN85iTo1K34=
+20250930025550.sql h1:+F+CsCUXD/ql0tHGEow70GhPBX1ZybVn+bh/T4YMh7Y=
+20250930140351.sql h1:9AAEG1AnOAH+o0+oHL5G7I8vqlWOhwRlCGyyCpT/y1Q=
+20251002085604.sql h1:3xZ68eYp4urXRnvotNH1XvG2mYOSDV/j3zHEZ/txg5E=
+20251003032030.sql h1:HB+mQ2lXMNomHDpaRhB/9IwYI9/YiDO5eOJ+nAQH/jw=
+20251005060450.sql h1:LbtCE2b+8osM3CvnmQJH1uCPtn+d7WchsslBOz8bL3Q=
+20251006041122.sql h1:MlS7f21z06sutnf9dIekt5fuHJr4lgcQ4uCuCXAGsfc=
+20251006045658.sql h1:3FmGCPCzjgMPdWDRodZTsx3KVaodd9zB9ilib69aewk=
+20251006045928.sql h1:Z5g31PmnzNwk/OKdODcxZGm8fjJQdMFK32Xfnt3bRHg=
+20251007022859.sql h1:FO03zEfaNEk/aXwY81d5Lp3MoBB9kPQuXlXJ4BPiSR8=
+20251008031337.sql h1:l+sxUAGvcTfj3I6kAFHo+T6AYodC9k9GkR+jaKO2xXc=
+20251008031554.sql h1:AqrVfIhSzY3PCy8ZlP5W91wn2iznfIuj5qQfubp6/94=
+20251008052346.sql h1:nxnXmooIJ6r1mmzwnw+6efxLfc/k9h2aE6RMptPRons=
+20251008073620.sql h1:6YsJp1W4SmQJ1lxpqF27BBlDC1zqhw7Yhc7pLzQTY6M=
+20251009042854.sql h1:nkBV+R6j0fg7/JY6wH3eb5Vv0asJLnXmb6lINfT/GLQ=
+20251009052657.sql h1:EPvdsib5rzCGPryd10HShGKvFPwM/R5S2lIVwtYxpms=
+20251010031743.sql h1:T8IZmx8/btRFKLzTe78MzcBsPJNodnLvB0tby9QkirQ=
+20251010070721.sql h1:5NQUk/yOV6sABLCB7swx++YIOyJe6MnU+yt1nRzde5w=
+20251010072711.sql h1:ZJNqR2piyu8xJhBvVABSlnGEoKSKae3wuEs+wshPe4k=
+20251013044536.sql h1:0Xjw8fNILiT8nnfrJDZgQnPf3dntmIoilbapnih8AE4=
+20251013051438.sql h1:lfSuw5mgJnePBJamvhZ81osFIouXeiIEiSZ/evdwo48=
+20251013081808.sql h1:ijgjNX08G6GBjA/ks8EKtb7P7Y7Cg7zbhqEOruGnv6M=
+20251014060047.sql h1:0jqj49WTtneEIMQDBoo4c095ZGi8sCrA8NnHBrPU6D8=
+20251014063537.sql h1:VZLXol0PTsTW21Epg6vBPsztWkDtcxup9F/z88EGgIg=
+20251014063720.sql h1:2HVUyCV0ud3BJJDH2GEKZN/+IWLFPCsN1KqhP6csO14=
+20251015045455.sql h1:MeLWmMhAOAz8b15Dd7IAQnt6JxjSml02XCXK22C0Lpg=
+20251016010845.sql h1:4BncQdDOasRZJkzVJrSJJA7091A9VPNVx/faUCUPhBM=
+20251016011023.sql h1:9JB9eFZKURK5RoCVDKR6glSvdJ8NTXrN7K/4q51zkz4=
+20251016062912.sql h1:ACNn0fe+EMqUt3hoY+Dr3uqAV/QICBa1+mIW7fUc9Fk=
+20251017060617.sql h1:4T3t9ifWrEQTPMSM0XJ98pF7Qdt+UfgtMui17bhrnWI=
+20251017082207.sql h1:8vLG1l/saRRMHXkyA4nelJyjaSddhZd6r7R+Uo4JS/c=
+20251018032635.sql h1:UltiY1Jm1KjAyBx/oRbhKzwEl3Aqh3o+eaOIfWdroJ8=
+20251018040322.sql h1:24VgOPgO2pxfwTcAv7xCv8BHiRPqmIbHUCXNLyvrGfc=
diff --git a/cmd/migration/migrations/20250901073356.sql b/cmd/migration/migrations/20250901073356.sql
deleted file mode 100644
index 4ffe005f..00000000
--- a/cmd/migration/migrations/20250901073356.sql
+++ /dev/null
@@ -1,6 +0,0 @@
--- Modify "Infra" table
-ALTER TABLE "public"."Infra" ALTER COLUMN "Parent_Id" TYPE integer;
--- Modify "User" table
-ALTER TABLE "public"."User" ADD CONSTRAINT "uni_User_Name" UNIQUE ("Name");
--- Modify "Employee" table
-ALTER TABLE "public"."Employee" ADD CONSTRAINT "fk_Employee_Person" FOREIGN KEY ("Person_Id") REFERENCES "public"."Person" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION, ADD CONSTRAINT "fk_Employee_User" FOREIGN KEY ("User_Id") REFERENCES "public"."User" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION;
diff --git a/cmd/migration/migrations/20250901080035.sql b/cmd/migration/migrations/20250901080035.sql
deleted file mode 100644
index 8b41cd0d..00000000
--- a/cmd/migration/migrations/20250901080035.sql
+++ /dev/null
@@ -1,2 +0,0 @@
--- Modify "McuSrc" table
-ALTER TABLE "public"."McuSrc" ADD CONSTRAINT "fk_McuSrc_CheckupCategory" FOREIGN KEY ("CheckupCategory_Code") REFERENCES "public"."McuSrcCategory" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION;
diff --git a/cmd/migration/migrations/20250901105703.sql b/cmd/migration/migrations/20250901105703.sql
deleted file mode 100644
index e9c47a1a..00000000
--- a/cmd/migration/migrations/20250901105703.sql
+++ /dev/null
@@ -1,2 +0,0 @@
--- Modify "Person" table
-ALTER TABLE "public"."Person" ADD COLUMN "FrontTitle" character varying(50) NULL, ADD COLUMN "EndTitle" character varying(50) NULL;
diff --git a/cmd/migration/migrations/20250902052320.sql b/cmd/migration/migrations/20250902052320.sql
deleted file mode 100644
index 44605a16..00000000
--- a/cmd/migration/migrations/20250902052320.sql
+++ /dev/null
@@ -1,13 +0,0 @@
--- Create "Language" table
-CREATE TABLE "public"."Language" (
- "Id" bigserial NOT NULL,
- "CreatedAt" timestamptz NULL,
- "UpdatedAt" timestamptz NULL,
- "DeletedAt" timestamptz NULL,
- "Code" character varying(10) NULL,
- "Name" character varying(50) NULL,
- PRIMARY KEY ("Id"),
- CONSTRAINT "uni_Language_Code" UNIQUE ("Code")
-);
--- Modify "Person" table
-ALTER TABLE "public"."Person" ADD COLUMN "PassportNumber" character varying(20) NULL, ADD COLUMN "DrivingLicenseNumber" character varying(20) NULL, ADD COLUMN "Language_Code" character varying(10) NULL, ADD CONSTRAINT "fk_Person_Language" FOREIGN KEY ("Language_Code") REFERENCES "public"."Language" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION;
diff --git a/cmd/migration/migrations/20250902063217.sql b/cmd/migration/migrations/20250902063217.sql
deleted file mode 100644
index 9231a697..00000000
--- a/cmd/migration/migrations/20250902063217.sql
+++ /dev/null
@@ -1,20 +0,0 @@
--- Create "PersonRelative" table
-CREATE TABLE "public"."PersonRelative" (
- "Id" bigserial NOT NULL,
- "CreatedAt" timestamptz NULL,
- "UpdatedAt" timestamptz NULL,
- "DeletedAt" timestamptz NULL,
- "Person_Id" bigint NULL,
- "Relationship_Code" character varying(100) NOT NULL,
- "Name" character varying(100) NULL,
- "Address" character varying(100) NULL,
- "Village_Code" character varying(10) NULL,
- "Gender_Code" character varying(10) NULL,
- "PhoneNumber" character varying(30) NULL,
- "Education_Code" character varying(10) NULL,
- "Occupation_Code" character varying(10) NULL,
- "Occupation_Name" character varying(50) NULL,
- PRIMARY KEY ("Id"),
- CONSTRAINT "fk_PersonRelative_Village" FOREIGN KEY ("Village_Code") REFERENCES "public"."Village" ("Code") ON UPDATE NO ACTION ON DELETE NO ACTION,
- CONSTRAINT "fk_Person_Relatives" FOREIGN KEY ("Person_Id") REFERENCES "public"."Person" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
-);
diff --git a/cmd/migration/migrations/20250902105300.sql b/cmd/migration/migrations/20250902105300.sql
deleted file mode 100644
index 8401f8ba..00000000
--- a/cmd/migration/migrations/20250902105300.sql
+++ /dev/null
@@ -1,13 +0,0 @@
--- Create "Patient" table
-CREATE TABLE "public"."Patient" (
- "Id" bigserial NOT NULL,
- "CreatedAt" timestamptz NULL,
- "UpdatedAt" timestamptz NULL,
- "DeletedAt" timestamptz NULL,
- "Person_Id" bigint NULL,
- "RegisteredAt" timestamptz NULL,
- "Status_Code" character varying(10) NOT NULL,
- "Number" character varying(15) NULL,
- PRIMARY KEY ("Id"),
- CONSTRAINT "fk_Patient_Person" FOREIGN KEY ("Person_Id") REFERENCES "public"."Person" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
-);
diff --git a/cmd/migration/migrations/20250903041718.sql b/cmd/migration/migrations/20250903041718.sql
deleted file mode 100644
index 53986785..00000000
--- a/cmd/migration/migrations/20250903041718.sql
+++ /dev/null
@@ -1,6 +0,0 @@
--- Modify "Device" table
-ALTER TABLE "public"."Device" ALTER COLUMN "Name" SET NOT NULL;
--- Modify "Person" table
-ALTER TABLE "public"."Person" ADD CONSTRAINT "uni_Person_DrivingLicenseNumber" UNIQUE ("DrivingLicenseNumber"), ADD CONSTRAINT "uni_Person_PassportNumber" UNIQUE ("PassportNumber"), ADD CONSTRAINT "uni_Person_ResidentIdentityNumber" UNIQUE ("ResidentIdentityNumber");
--- Modify "Nurse" table
-ALTER TABLE "public"."Nurse" ADD COLUMN "Unit_Id" integer NULL, ADD CONSTRAINT "fk_Nurse_Unit" FOREIGN KEY ("Unit_Id") REFERENCES "public"."Unit" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION;
diff --git a/cmd/migration/migrations/20250903073200.sql b/cmd/migration/migrations/20250903073200.sql
deleted file mode 100644
index 9d6923a7..00000000
--- a/cmd/migration/migrations/20250903073200.sql
+++ /dev/null
@@ -1,25 +0,0 @@
--- Modify "MedicineGroup" table
-ALTER TABLE "public"."MedicineGroup" ALTER COLUMN "Code" TYPE character varying(10), ALTER COLUMN "Name" TYPE character varying(50);
--- Modify "MedicineMethod" table
-ALTER TABLE "public"."MedicineMethod" ALTER COLUMN "Code" TYPE character varying(10), ALTER COLUMN "Name" TYPE character varying(50);
--- Create "Encounter" table
-CREATE TABLE "public"."Encounter" (
- "Id" bigserial NOT NULL,
- "CreatedAt" timestamptz NULL,
- "UpdatedAt" timestamptz NULL,
- "DeletedAt" timestamptz NULL,
- "Patient_Id" bigint NULL,
- "RegisteredAt" timestamptz NULL,
- "Class_Code" character varying(10) NOT NULL,
- "Unit_Id" bigint NULL,
- "VisitDate" timestamptz NULL,
- "Assignment_Doctor_Id" bigint NULL,
- "Responsible_Doctor_Id" bigint NULL,
- "DischardeMethod_Code" character varying(10) NULL,
- "RefSource_Name" character varying(100) NULL,
- PRIMARY KEY ("Id"),
- CONSTRAINT "fk_Encounter_Assignment_Doctor" FOREIGN KEY ("Assignment_Doctor_Id") REFERENCES "public"."Doctor" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
- CONSTRAINT "fk_Encounter_Patient" FOREIGN KEY ("Patient_Id") REFERENCES "public"."Patient" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
- CONSTRAINT "fk_Encounter_Responsible_Doctor" FOREIGN KEY ("Responsible_Doctor_Id") REFERENCES "public"."Doctor" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION,
- CONSTRAINT "fk_Encounter_Unit" FOREIGN KEY ("Unit_Id") REFERENCES "public"."Unit" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION
-);
diff --git a/cmd/migration/migrations/atlas.sum b/cmd/migration/migrations/atlas.sum
deleted file mode 100644
index 8b56b6fa..00000000
--- a/cmd/migration/migrations/atlas.sum
+++ /dev/null
@@ -1,10 +0,0 @@
-h1:179RYs36FGTJB7o/kUCO3K612TUM4fbHOaI3UBdlmlU=
-20250829081952.sql h1:YMsYq3uPsx70EjWSGfYnVRR5GV0q1fRGIszYZAWzXNo=
-20250901073356.sql h1:jjd5TLs+Pyi0u3SrOM+aNTbHxSJboXgcOz/L4bkYx+c=
-20250901080035.sql h1:LWa3X0NWjalVcxNbk5HaHj1Oqu60/AQabi0jBmCeQBI=
-20250901105703.sql h1:2h2B/wOFM0826sBXQutTtq24C+5duLqi4zEFOdbPsCI=
-20250902052320.sql h1:+tWdeS4NorPj5WdKHMirBfP4EeS01wyyfdT03DBMmcI=
-20250902063217.sql h1:wYFIrAIp1RczNvzlmu8jP8P1J7xEXqgDLKDUNBbkt84=
-20250902105300.sql h1:6N2SDYK3a6djaO6u468E/DrDR9kM+uYoJvNlTFon6bY=
-20250903041718.sql h1:ZiaacurDuBwWaI348Sjo7VZ6rSsj9TLTkudiRv05C/w=
-20250903073200.sql h1:Tnxfz/3JjvrwPie2FYuhmfo5xFNeQV1lH+qbBJjpm5g=
diff --git a/cmd/satusehat-migration/Makefile b/cmd/satusehat-migration/Makefile
new file mode 100644
index 00000000..e83356e5
--- /dev/null
+++ b/cmd/satusehat-migration/Makefile
@@ -0,0 +1,18 @@
+# Makefile for Atlas migrations
+
+# Default environment
+ENV ?= gorm
+
+.PHONY: diff apply hash
+
+## Generate a new migration diff
+diff:
+ atlas migrate diff --env $(ENV)
+
+## Apply migrations to the database
+apply:
+ atlas migrate apply --env $(ENV)
+
+## Calculate the schema hash
+hash:
+ atlas migrate hash
diff --git a/cmd/satusehat-migration/README-ATLAS.MD b/cmd/satusehat-migration/README-ATLAS.MD
new file mode 100644
index 00000000..da249823
--- /dev/null
+++ b/cmd/satusehat-migration/README-ATLAS.MD
@@ -0,0 +1,59 @@
+# Database Migration with Atlas
+
+This project uses [Atlas](https://atlasgo.io/) for database schema management and migrations.
+
+## ๐ Prerequisites
+
+1. **Download and Install Atlas CLI**
+ Run the following command in PowerShell or Git Bash:
+
+ ```sh
+ curl -sSf https://atlasgo.sh | sh
+ ```
+ Verify installation:
+
+ ```sh
+ atlas version
+ ```
+
+2. Install GORM Provider
+ Run inside your Go project:
+
+ ```sh
+ go get -u ariga.io/atlas-provider-gorm
+ ```
+
+3. Create atlas.hcl configuration file
+ Just create an atlas.hcl file in your project root as example given at atlas.hcl.example
+4. Create migrations folder
+ ```sh
+ mkdir migrations
+ ```
+5. Usage
+You can use the provided Makefile for common commands:
+
+ Generate a migration diff
+ ```sh
+ make diff
+ ```
+
+ Apply migrations
+ ```sh
+ make apply
+ ```
+
+ Compute schema hash
+ ```sh
+ make hash
+ ```
+
+ If you donโt have make installed, you can run the Atlas commands directly:
+ ```sh
+ atlas migrate diff --env gorm
+ ```
+ ```sh
+ atlas migrate apply --env gorm
+ ```
+ ```sh
+ atlas migrate hash
+ ```
\ No newline at end of file
diff --git a/cmd/satusehat-migration/atlas.hcl.example b/cmd/satusehat-migration/atlas.hcl.example
new file mode 100644
index 00000000..857d1352
--- /dev/null
+++ b/cmd/satusehat-migration/atlas.hcl.example
@@ -0,0 +1,22 @@
+data "external_schema" "gorm" {
+ program = [
+ "go",
+ "run",
+ "-mod=mod",
+ ".",
+ ]
+}
+
+env "gorm" {
+ src = data.external_schema.gorm.url
+ dev = "" // dsn db to check the diff
+ migration {
+ dir = "file://migrations"
+ }
+ url = "" // dsn db to apply
+ format {
+ migrate {
+ diff = "{{ sql . \" \" }}"
+ }
+ }
+}
\ No newline at end of file
diff --git a/cmd/satusehat-migration/migration.go b/cmd/satusehat-migration/migration.go
new file mode 100644
index 00000000..e426633e
--- /dev/null
+++ b/cmd/satusehat-migration/migration.go
@@ -0,0 +1,9 @@
+package main
+
+import (
+ m "simrs-vx/internal/interface/migration"
+)
+
+func main() {
+ m.Migrate(m.SatuSehat)
+}
diff --git a/go.mod b/go.mod
index da8ef314..132d6e88 100644
--- a/go.mod
+++ b/go.mod
@@ -8,44 +8,57 @@ require (
ariga.io/atlas-provider-gorm v0.5.6
github.com/golang-jwt/jwt v3.2.2+incompatible
github.com/google/uuid v1.6.0
- github.com/karincake/apem v0.0.16-h
+ github.com/jackc/pgx/v5 v5.5.5
+ github.com/karincake/apem v0.0.17
github.com/karincake/dodol v0.0.1
- github.com/karincake/getuk v0.1.0
+ github.com/karincake/getuk v0.3.1
github.com/karincake/hongkue v0.0.4
github.com/karincake/lepet v0.0.1
github.com/karincake/risoles v0.0.3
- github.com/karincake/semprit v0.0.3
+ github.com/karincake/semprit v0.0.6
+ github.com/karincake/serabi v0.0.14
+ github.com/minio/minio-go/v7 v7.0.95
github.com/rs/zerolog v1.33.0
golang.org/x/crypto v0.41.0
- gorm.io/driver/postgres v1.5.11
gorm.io/gorm v1.25.12
)
require (
ariga.io/atlas v0.36.2-0.20250806044935-5bb51a0a956e // indirect
+ github.com/dustin/go-humanize v1.0.1 // indirect
+ github.com/go-ini/ini v1.67.0 // indirect
github.com/go-redis/redis v6.15.9+incompatible // indirect
github.com/go-sql-driver/mysql v1.7.0 // indirect
+ github.com/goccy/go-json v0.10.5 // indirect
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
github.com/golang-sql/sqlexp v0.1.0 // indirect
github.com/google/go-cmp v0.7.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
- github.com/jackc/pgx/v5 v5.5.5 // indirect
github.com/jackc/puddle/v2 v2.2.1 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
- github.com/karincake/serabi v0.0.14 // indirect
+ github.com/karincake/pentol v0.0.3 // indirect
+ github.com/klauspost/compress v1.18.0 // indirect
+ github.com/klauspost/cpuid/v2 v2.2.11 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mattn/go-sqlite3 v1.14.28 // indirect
github.com/microsoft/go-mssqldb v1.7.2 // indirect
+ github.com/minio/crc64nvme v1.0.2 // indirect
+ github.com/minio/md5-simd v1.1.2 // indirect
github.com/nxadm/tail v1.4.11 // indirect
+ github.com/philhofer/fwd v1.2.0 // indirect
+ github.com/rs/xid v1.6.0 // indirect
+ github.com/tinylib/msgp v1.3.0 // indirect
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect
+ golang.org/x/net v0.42.0 // indirect
golang.org/x/sync v0.16.0 // indirect
golang.org/x/sys v0.35.0 // indirect
golang.org/x/text v0.28.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gorm.io/driver/mysql v1.5.7 // indirect
+ gorm.io/driver/postgres v1.5.11 // indirect
gorm.io/driver/sqlite v1.5.7 // indirect
gorm.io/driver/sqlserver v1.5.4 // indirect
)
diff --git a/go.sum b/go.sum
index 8982eb2b..555dac70 100644
--- a/go.sum
+++ b/go.sum
@@ -25,12 +25,18 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko=
github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
+github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
+github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
+github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
+github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg=
github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
+github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
+github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
@@ -69,22 +75,29 @@ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
-github.com/karincake/apem v0.0.16-h h1:rfO444oDG4cWFf0PjUshA+0U8KI/u067Va273WeJhpU=
-github.com/karincake/apem v0.0.16-h/go.mod h1:cQP2sJfDrLRIiwWoaLWw/z8uAya+DWu/FpmYeinMQXM=
+github.com/karincake/apem v0.0.17 h1:y3WXCr9GWLFFFH4Qyq/VWlWWpijHh5zpTc3Lm96twa4=
+github.com/karincake/apem v0.0.17/go.mod h1:cQP2sJfDrLRIiwWoaLWw/z8uAya+DWu/FpmYeinMQXM=
github.com/karincake/dodol v0.0.1 h1:jUXmJh1r0Ei4fmHPZ6IUkoplW/V9d27L63JEl6zudL0=
github.com/karincake/dodol v0.0.1/go.mod h1:2f1NcvkvY0J3GMUkwILNDYVvRUpz0W3lpPp/Ha/Ld24=
-github.com/karincake/getuk v0.1.0 h1:jcIsASrr0UDE528GN7Ua6n9UFyRgUypsWh8Or8wzCO0=
-github.com/karincake/getuk v0.1.0/go.mod h1:NVnvxSGAkQ/xuq99FzWACvY5efyKPLFla1cKB8czm7c=
+github.com/karincake/getuk v0.3.1 h1:yRqBTrwpnjYcZD3gPDoSxFlsLgI9/GKCr3ZCsS4TtYQ=
+github.com/karincake/getuk v0.3.1/go.mod h1:NVnvxSGAkQ/xuq99FzWACvY5efyKPLFla1cKB8czm7c=
github.com/karincake/hongkue v0.0.4 h1:oWthq6cDg5DvDm1Z3e7mCLOATQf+oAdtHxN9OPnCfA8=
github.com/karincake/hongkue v0.0.4/go.mod h1:YVi5Lyh3DE+GRHx2OSODOr7FwvLi8U4idvcPHO7yeag=
github.com/karincake/lepet v0.0.1 h1:eq/cwn5BBg0jWZ1c/MmvhFIBma0zBpVs2LwkfDOncy4=
github.com/karincake/lepet v0.0.1/go.mod h1:U84w7olXO3BPJw2Hu6MBonFmJmPKaFjtyAj1HTu3z1A=
+github.com/karincake/pentol v0.0.3 h1:NgiR101yZuqZjYT7LiUkOgsFS+OzUHxceBpL9RbAXeg=
+github.com/karincake/pentol v0.0.3/go.mod h1:6F2jlwLkVtNuC0nW/gfdU+B9bZoiIVN+IEdB2WIlKgQ=
github.com/karincake/risoles v0.0.3 h1:7VBShf2yC6NqD0PotQcb0i8Xe6mJeTRrHnE0qzKf7NU=
github.com/karincake/risoles v0.0.3/go.mod h1:u4YS+rPp92ODTbGC4RUx4DxKoThnmPjBl1CNdnmKD/c=
-github.com/karincake/semprit v0.0.3 h1:znleGRu73xrHk6a70+jRQgVh9VF3TAhttQz6vfgNdyM=
-github.com/karincake/semprit v0.0.3/go.mod h1:nLtNmWlHkxMKG0IMzqnnfkn1L/RVYGXVW3LchfYQMu8=
+github.com/karincake/semprit v0.0.6 h1:TvY9Np2jEmbGcucbxBO7GzdZ9AiIhSVe5+ki1rgoocE=
+github.com/karincake/semprit v0.0.6/go.mod h1:pZ63Q2WHw3mrsRPm6LSx999tRD+N8eYzpfN/vP3aEoQ=
github.com/karincake/serabi v0.0.14 h1:yK3nBLRXdoUNSUDIfbZqIQxnZ6U6Ij5QEO8d5QzZzsw=
github.com/karincake/serabi v0.0.14/go.mod h1:GcnPBWb+UotDxvb/a2CKwourCEyVIL4P9+YxVmZ5zgk=
+github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
+github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
+github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
+github.com/klauspost/cpuid/v2 v2.2.11 h1:0OwqZRYI2rFrjS4kvkDnqJkKHdHaRnCm68/DY4OxRzU=
+github.com/klauspost/cpuid/v2 v2.2.11/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@@ -100,6 +113,12 @@ github.com/mattn/go-sqlite3 v1.14.28 h1:ThEiQrnbtumT+QMknw63Befp/ce/nUPgBPMlRFEu
github.com/mattn/go-sqlite3 v1.14.28/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/microsoft/go-mssqldb v1.7.2 h1:CHkFJiObW7ItKTJfHo1QX7QBBD1iV+mn1eOyRP3b/PA=
github.com/microsoft/go-mssqldb v1.7.2/go.mod h1:kOvZKUdrhhFQmxLZqbwUV0rHkNkZpthMITIb2Ko1IoA=
+github.com/minio/crc64nvme v1.0.2 h1:6uO1UxGAD+kwqWWp7mBFsi5gAse66C4NXO8cmcVculg=
+github.com/minio/crc64nvme v1.0.2/go.mod h1:eVfm2fAzLlxMdUGc0EEBGSMmPwmXD5XiNRpnu9J3bvg=
+github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
+github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
+github.com/minio/minio-go/v7 v7.0.95 h1:ywOUPg+PebTMTzn9VDsoFJy32ZuARN9zhB+K3IYEvYU=
+github.com/minio/minio-go/v7 v7.0.95/go.mod h1:wOOX3uxS334vImCNRVyIDdXX9OsXDm89ToynKgqUKlo=
github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8=
github.com/montanaflynn/stats v0.7.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY=
@@ -108,6 +127,8 @@ github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk=
github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0=
+github.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM=
+github.com/philhofer/fwd v1.2.0/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
@@ -117,6 +138,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
+github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU=
+github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -131,6 +154,8 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+github.com/tinylib/msgp v1.3.0 h1:ULuf7GPooDaIlbyvgAxBV/FI7ynli6LZ1/nVUNu+0ww=
+github.com/tinylib/msgp v1.3.0/go.mod h1:ykjzy2wzgrlvpDCRc4LA8UXy6D8bzMSuAF3WD57Gok0=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
diff --git a/internal/domain/base-entities/core/dto.go b/internal/domain/base-entities/core/dto.go
new file mode 100644
index 00000000..a325bd15
--- /dev/null
+++ b/internal/domain/base-entities/core/dto.go
@@ -0,0 +1,7 @@
+package core
+
+type Pagination struct {
+ PageNumber int `json:"page-number"`
+ PageSize int `json:"page-size"`
+ PageNoLimit bool `json:"page-no-limit"`
+}
diff --git a/internal/domain/bpjs-entities/member/dto.go b/internal/domain/bpjs-entities/member/dto.go
new file mode 100644
index 00000000..f9c95655
--- /dev/null
+++ b/internal/domain/bpjs-entities/member/dto.go
@@ -0,0 +1,15 @@
+package member
+
+type ReadListDto struct {
+ ReferenceType ReferenceType `json:"-"`
+ PathValue1 string `json:"-"`
+ PathValue2 string `json:"-"`
+ PathValue3 string `json:"-"`
+}
+
+type ReferenceType string
+
+const (
+ RTNik ReferenceType = "nik"
+ RTBpjs ReferenceType = "bpjs"
+)
diff --git a/internal/domain/bpjs-entities/member/entity.go b/internal/domain/bpjs-entities/member/entity.go
new file mode 100644
index 00000000..b6c4f0d7
--- /dev/null
+++ b/internal/domain/bpjs-entities/member/entity.go
@@ -0,0 +1,78 @@
+package member
+
+type Response struct {
+ MetaData *MetaData `json:"metaData"`
+ Response *BPJSDataRes `json:"response"`
+}
+
+type MetaData struct {
+ Code string `json:"code"`
+ Message string `json:"message"`
+}
+
+type BPJSDataRes struct {
+ Peserta *Peserta `json:"peserta"`
+}
+
+type Peserta struct {
+ Cob *COB `json:"cob"`
+ HakKelas *HakKelas `json:"hakKelas"`
+ Informasi *Informasi `json:"informasi"`
+ JenisPeserta *JenisPeserta `json:"jenisPeserta"`
+ Mr *MR `json:"mr"`
+ Nama *string `json:"nama"`
+ Nik *string `json:"nik"`
+ NoKartu *string `json:"noKartu"`
+ Pisa *string `json:"pisa"`
+ ProvUmum *ProvUmum `json:"provUmum"`
+ Sex *string `json:"sex"`
+ StatusPeserta *StatusPeserta `json:"statusPeserta"`
+ TglCetakKartu *string `json:"tglCetakKartu"`
+ TglLahir *string `json:"tglLahir"`
+ TglTAT *string `json:"tglTAT"`
+ TglTMT *string `json:"tglTMT"`
+ Umur *Umur `json:"umur"`
+}
+
+type COB struct {
+ NmAsuransi *string `json:"nmAsuransi"`
+ NoAsuransi *string `json:"noAsuransi"`
+ TglTAT *string `json:"tglTAT"`
+ TglTMT *string `json:"tglTMT"`
+}
+
+type HakKelas struct {
+ Keterangan *string `json:"keterangan"`
+ Kode *string `json:"kode"`
+}
+
+type Informasi struct {
+ Dinsos *string `json:"dinsos"`
+ NoSKTM *string `json:"noSKTM"`
+ ProlanisPRB *string `json:"prolanisPRB"`
+}
+
+type JenisPeserta struct {
+ Keterangan *string `json:"keterangan"`
+ Kode *string `json:"kode"`
+}
+
+type MR struct {
+ NoMR *string `json:"noMR"`
+ NoTelepon *string `json:"noTelepon"`
+}
+
+type ProvUmum struct {
+ KdProvider *string `json:"kdProvider"`
+ NmProvider *string `json:"nmProvider"`
+}
+
+type StatusPeserta struct {
+ Keterangan *string `json:"keterangan"`
+ Kode *string `json:"kode"`
+}
+
+type Umur struct {
+ UmurSaatPelayanan *string `json:"umurSaatPelayanan"`
+ UmurSekarang *string `json:"umurSekarang"`
+}
diff --git a/internal/domain/bpjs-entities/monitoring/dto.go b/internal/domain/bpjs-entities/monitoring/dto.go
new file mode 100644
index 00000000..c5c1e0d1
--- /dev/null
+++ b/internal/domain/bpjs-entities/monitoring/dto.go
@@ -0,0 +1,15 @@
+package monitoring
+
+type ReadListDto struct {
+ ReferenceType ReferenceType `json:"-"`
+ PathValue1 string `json:"-"`
+ PathValue2 string `json:"-"`
+ PathValue3 string `json:"-"`
+}
+
+type ReferenceType string
+
+const (
+ RTVisit ReferenceType = "visit"
+ RTHist ReferenceType = "hist"
+)
diff --git a/internal/domain/bpjs-entities/monitoring/entity.go b/internal/domain/bpjs-entities/monitoring/entity.go
new file mode 100644
index 00000000..eb604942
--- /dev/null
+++ b/internal/domain/bpjs-entities/monitoring/entity.go
@@ -0,0 +1,43 @@
+package monitoring
+
+type Response struct {
+ MetaData MetaData `json:"metaData"`
+ Response *BPJSDataRes `json:"response"`
+}
+
+type MetaData struct {
+ Code string `json:"code"`
+ Message string `json:"message"`
+}
+
+type BPJSDataRes struct {
+ Sep []Sep `json:"sep"`
+ Histori []Histori `json:"histori"`
+}
+
+type Sep struct {
+ Diagnosa string `json:"diagnosa"`
+ JnsPelayanan string `json:"jnsPelayanan"`
+ KelasRawat string `json:"kelasRawat"`
+ Nama string `json:"nama"`
+ NoKartu string `json:"noKartu"`
+ NoSep string `json:"noSep"`
+ NoRujukan string `json:"noRujukan"`
+ Poli *string `json:"poli"`
+ TglPlgSep string `json:"tglPlgSep"`
+ TglSep string `json:"tglSep"`
+}
+
+type Histori struct {
+ Diagnosa string `json:"diagnosa"`
+ JnsPelayanan string `json:"jnsPelayanan"`
+ KelasRawat *string `json:"kelasRawat"`
+ NamaPeserta string `json:"namaPeserta"`
+ NoKartu string `json:"noKartu"`
+ NoSep string `json:"noSep"`
+ NoRujukan string `json:"noRujukan"`
+ Poli string `json:"poli"`
+ PpkPelayanan string `json:"ppkPelayanan"`
+ TglPlgSep string `json:"tglPlgSep"`
+ TglSep string `json:"tglSep"`
+}
diff --git a/internal/domain/bpjs-entities/reference/dto.go b/internal/domain/bpjs-entities/reference/dto.go
new file mode 100644
index 00000000..9be2ab5b
--- /dev/null
+++ b/internal/domain/bpjs-entities/reference/dto.go
@@ -0,0 +1,22 @@
+package reference
+
+type ReadListDto struct {
+ ReferenceType ReferenceType `json:"-"`
+ PathValue1 string `json:"-"`
+ PathValue2 string `json:"-"`
+ PathValue3 string `json:"-"`
+}
+
+type ReferenceType string
+
+const (
+ RTProvince ReferenceType = "province"
+ RTDistrict ReferenceType = "district"
+ RTCities ReferenceType = "cities"
+ RTDiagnose ReferenceType = "diagnose"
+ RTDiagnosePrb ReferenceType = "diagnose-prb"
+ RTMedicinePrb ReferenceType = "medicine-prb"
+ RTUnit ReferenceType = "unit"
+ RTHealthcare ReferenceType = "healthcare"
+ RTDoctor ReferenceType = "doctor"
+)
diff --git a/internal/domain/bpjs-entities/reference/entity.go b/internal/domain/bpjs-entities/reference/entity.go
new file mode 100644
index 00000000..bfcbb66e
--- /dev/null
+++ b/internal/domain/bpjs-entities/reference/entity.go
@@ -0,0 +1,23 @@
+package reference
+
+type Response struct {
+ MetaData MetaData `json:"metaData"`
+ Response *CodeNameList `json:"response"` // pointer to handle possible null
+}
+
+type MetaData struct {
+ Code string `json:"code"`
+ Message string `json:"message"`
+}
+
+type CodeNameList struct {
+ List []CodeName `json:"list,omitempty"`
+ Diagnosa []CodeName `json:"diagnosa,omitempty"`
+ Poli []CodeName `json:"poli,omitempty"`
+ Faskes []CodeName `json:"faskes,omitempty"`
+}
+
+type CodeName struct {
+ Kode string `json:"kode"`
+ Nama string `json:"nama"`
+}
diff --git a/internal/domain/bpjs-entities/vclaim-sep-hist/dto.go b/internal/domain/bpjs-entities/vclaim-sep-hist/dto.go
new file mode 100644
index 00000000..d58eaf6e
--- /dev/null
+++ b/internal/domain/bpjs-entities/vclaim-sep-hist/dto.go
@@ -0,0 +1,68 @@
+package vclaimsephist
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+)
+
+type CreateDto struct {
+ RequestPayload string `json:"requestPayload"`
+ ResponseBody string `json:"responseBody"`
+ Message string `json:"message"`
+}
+
+type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Sort string `json:"sort"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ RequestPayload *string `json:"requestPayload"`
+ ResponseBody *string `json:"responseBody"`
+ Message *string `json:"message"`
+}
+
+type ReadDetailDto struct {
+ Id uint `json:"id"`
+}
+
+type UpdateDto struct {
+ Id uint `json:"id"`
+ CreateDto
+}
+
+type DeleteDto struct {
+ Id uint `json:"id"`
+}
+
+type MetaDto struct {
+ PageNumber int `json:"page_number"`
+ PageSize int `json:"page_size"`
+ Count int `json:"count"`
+}
+
+type ResponseDto struct {
+ ecore.Main
+ RequestPayload *string `json:"requestPayload"`
+ ResponseBody *string `json:"responseBody"`
+ Message *string `json:"message"`
+}
+
+func (d VclaimSepHist) ToResponse() ResponseDto {
+ resp := ResponseDto{
+ RequestPayload: d.RequestPayload,
+ ResponseBody: d.ResponseBody,
+ Message: d.Message,
+ }
+ resp.Main = d.Main
+ return resp
+}
+
+func ToResponseList(data []VclaimSepHist) []ResponseDto {
+ resp := make([]ResponseDto, len(data))
+ for i, u := range data {
+ resp[i] = u.ToResponse()
+ }
+ return resp
+}
diff --git a/internal/domain/bpjs-entities/vclaim-sep-hist/entitiy.go b/internal/domain/bpjs-entities/vclaim-sep-hist/entitiy.go
new file mode 100644
index 00000000..46880159
--- /dev/null
+++ b/internal/domain/bpjs-entities/vclaim-sep-hist/entitiy.go
@@ -0,0 +1,12 @@
+package vclaimsephist
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+)
+
+type VclaimSepHist struct {
+ ecore.Main
+ RequestPayload *string `json:"requestPayload"`
+ ResponseBody *string `json:"responseBody"`
+ Message *string `json:"message"`
+}
diff --git a/internal/domain/bpjs-entities/vclaim-sep-print/dto.go b/internal/domain/bpjs-entities/vclaim-sep-print/dto.go
new file mode 100644
index 00000000..17650e40
--- /dev/null
+++ b/internal/domain/bpjs-entities/vclaim-sep-print/dto.go
@@ -0,0 +1,62 @@
+package vclaimsepprint
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+)
+
+type CreateDto struct {
+ VclaimSep_Number *string `json:"vclaimSep_number"`
+}
+
+type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Sort string `json:"sort"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ VclaimSep_Number *string `json:"vclaimSep_number"`
+}
+
+type ReadDetailDto struct {
+ Id uint `json:"id"`
+}
+
+type UpdateDto struct {
+ Id uint `json:"id"`
+ CreateDto
+}
+
+type DeleteDto struct {
+ Id uint `json:"id"`
+}
+
+type MetaDto struct {
+ PageNumber int `json:"page_number"`
+ PageSize int `json:"page_size"`
+ Count int `json:"count"`
+}
+
+type ResponseDto struct {
+ ecore.Main
+ VclaimSep_Number *string `json:"vclaimSep_number"`
+ Counter *uint `json:"counter"`
+}
+
+func (d VclaimSepPrint) ToResponse() ResponseDto {
+ resp := ResponseDto{
+ VclaimSep_Number: d.VclaimSep_Number,
+ Counter: d.Counter,
+ }
+ resp.Main = d.Main
+ return resp
+}
+
+func ToResponseList(data []VclaimSepPrint) []ResponseDto {
+ resp := make([]ResponseDto, len(data))
+ for i, u := range data {
+ resp[i] = u.ToResponse()
+ }
+ return resp
+}
diff --git a/internal/domain/bpjs-entities/vclaim-sep-print/entity.go b/internal/domain/bpjs-entities/vclaim-sep-print/entity.go
new file mode 100644
index 00000000..1bd5e9fc
--- /dev/null
+++ b/internal/domain/bpjs-entities/vclaim-sep-print/entity.go
@@ -0,0 +1,13 @@
+package vclaimsepprint
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ evs "simrs-vx/internal/domain/bpjs-entities/vclaim-sep"
+)
+
+type VclaimSepPrint struct {
+ ecore.Main
+ VclaimSep_Number *string `json:"vclaimSep_number"`
+ VclaimSep *evs.VclaimSep `json:"vclaimSep,omitempty" gorm:"foreignKey:VclaimSep_Number;references:Number"`
+ Counter *uint `json:"counter"`
+}
diff --git a/internal/domain/bpjs-entities/vclaim-sep/dto.go b/internal/domain/bpjs-entities/vclaim-sep/dto.go
new file mode 100644
index 00000000..8a174688
--- /dev/null
+++ b/internal/domain/bpjs-entities/vclaim-sep/dto.go
@@ -0,0 +1,73 @@
+package vclaimsep
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ evsh "simrs-vx/internal/domain/bpjs-entities/vclaim-sep-hist"
+)
+
+type CreateDto struct {
+ Encounter_Id *uint `json:"encounter_id"`
+ Number *string `json:"number" validate:"maxLength=19"`
+ RequestPayload []byte `json:"requestPayload" validate:"maxLength=1024"`
+
+ VclaimSepHist evsh.CreateDto
+}
+
+type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Sort string `json:"sort"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ Number *string `json:"number"`
+}
+
+type ReadDetailDto struct {
+ Id uint `json:"id"`
+ Number *string `json:"number"`
+}
+
+type UpdateDto struct {
+ Id uint `json:"id"`
+ CreateDto
+}
+
+type DeleteDto struct {
+ Id uint `json:"id"`
+ Number *string `json:"number"`
+}
+
+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"`
+ Number *string `json:"number"`
+}
+
+func (d VclaimSep) ToResponse() ResponseDto {
+ resp := ResponseDto{
+ Encounter_Id: d.Encounter_Id,
+ Number: d.Number,
+ }
+ resp.Main = d.Main
+ return resp
+}
+
+func ToResponseList(data []VclaimSep) []ResponseDto {
+ resp := make([]ResponseDto, len(data))
+ for i, u := range data {
+ resp[i] = u.ToResponse()
+ }
+ return resp
+}
+
+func (c CreateDto) IsMessageSuccess() bool {
+ return c.VclaimSepHist.Message == "Sukses"
+}
diff --git a/internal/domain/bpjs-entities/vclaim-sep/entitiy.go b/internal/domain/bpjs-entities/vclaim-sep/entitiy.go
new file mode 100644
index 00000000..e23106d8
--- /dev/null
+++ b/internal/domain/bpjs-entities/vclaim-sep/entitiy.go
@@ -0,0 +1,11 @@
+package vclaimsep
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+)
+
+type VclaimSep struct {
+ ecore.Main
+ Encounter_Id *uint `json:"encounter_id"`
+ Number *string `json:"number" gorm:"unique;size:19"`
+}
diff --git a/internal/domain/main-entities/adime/dto.go b/internal/domain/main-entities/adime/dto.go
new file mode 100644
index 00000000..49257154
--- /dev/null
+++ b/internal/domain/main-entities/adime/dto.go
@@ -0,0 +1,83 @@
+package adime
+
+import (
+ "time"
+
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ eem "simrs-vx/internal/domain/main-entities/employee"
+ ee "simrs-vx/internal/domain/main-entities/encounter"
+
+ pa "simrs-vx/pkg/auth-helper"
+)
+
+type CreateDto struct {
+ Encounter_Id *uint `json:"encounter_id"`
+ Employee_Id *uint `json:"-"`
+ Time *time.Time `json:"time"`
+ Value *string `json:"value"`
+
+ pa.AuthInfo
+}
+
+type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ Encounter_Id *uint `json:"encounter-id"`
+ Employee_Id *uint `json:"employee-id"`
+ Time *time.Time `json:"time"`
+ Value *string `json:"value"`
+}
+
+type ReadDetailDto struct {
+ Id uint16 `json:"id"`
+}
+
+type UpdateDto struct {
+ Id uint16 `json:"id"`
+ CreateDto
+}
+
+type DeleteDto struct {
+ Id uint16 `json:"id"`
+}
+
+type MetaDto struct {
+ PageNumber int `json:"page_number"`
+ PageSize int `json:"page_size"`
+ Count int `json:"count"`
+}
+
+type ResponseDto struct {
+ ecore.Main
+ Encounter_Id *uint `json:"encounter_id"`
+ Encounter *ee.Encounter `json:"encounter,omitempty"`
+ Employee_Id *uint `json:"employee_id"`
+ Employee *eem.Employee `json:"employee,omitempty"`
+ Time *time.Time `json:"time"`
+ Value *string `json:"value"`
+}
+
+func (d Adime) ToResponse() ResponseDto {
+ resp := ResponseDto{
+ Encounter_Id: d.Encounter_Id,
+ Encounter: d.Encounter,
+ Employee_Id: d.Employee_Id,
+ Employee: d.Employee,
+ Time: d.Time,
+ Value: d.Value,
+ }
+ resp.Main = d.Main
+ return resp
+}
+
+func ToResponseList(data []Adime) []ResponseDto {
+ resp := make([]ResponseDto, len(data))
+ for i, u := range data {
+ resp[i] = u.ToResponse()
+ }
+ return resp
+}
diff --git a/internal/domain/main-entities/adime/entity.go b/internal/domain/main-entities/adime/entity.go
new file mode 100644
index 00000000..35fa7276
--- /dev/null
+++ b/internal/domain/main-entities/adime/entity.go
@@ -0,0 +1,18 @@
+package adime
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ eem "simrs-vx/internal/domain/main-entities/employee"
+ ee "simrs-vx/internal/domain/main-entities/encounter"
+ "time"
+)
+
+type Adime struct {
+ ecore.Main // adjust this according to the needs
+ Encounter_Id *uint `json:"encounter_id"`
+ Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"`
+ Employee_Id *uint `json:"employee_id"`
+ Employee *eem.Employee `json:"employee,omitempty" gorm:"foreignKey:Employee_Id;references:Id"`
+ Time *time.Time `json:"time"`
+ Value *string `json:"value"`
+}
diff --git a/internal/domain/main-entities/ambulance-transport-req/entity.go b/internal/domain/main-entities/ambulance-transport-req/entity.go
new file mode 100644
index 00000000..4392c4f6
--- /dev/null
+++ b/internal/domain/main-entities/ambulance-transport-req/entity.go
@@ -0,0 +1,45 @@
+package ambulance_transport_req
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ eds "simrs-vx/internal/domain/main-entities/district"
+ ept "simrs-vx/internal/domain/main-entities/patient"
+ epr "simrs-vx/internal/domain/main-entities/province"
+ erg "simrs-vx/internal/domain/main-entities/regency"
+ evl "simrs-vx/internal/domain/main-entities/village"
+ "time"
+
+ eren "simrs-vx/internal/domain/references/encounter"
+ erp "simrs-vx/internal/domain/references/person"
+)
+
+type AmbulanceTransportReq struct {
+ ecore.Main
+ Patient_Id *uint `json:"patient_id"`
+ Patient *ept.Patient `json:"patient,omitempty" gorm:"foreignKey:Patient_Id;references:Id"`
+
+ Diagnoses *string `json:"diagnoses" gorm:"size:1024"`
+ RequestData *time.Time `json:"requestData"`
+ UsageDate *time.Time `json:"usageDate"`
+
+ Address *string `json:"address" gorm:"size:100"`
+ RtRw *string `json:"rtRw" gorm:"size:10"`
+
+ Province_Code *string `json:"province_code" gorm:"size:2"`
+ Province *epr.Province `json:"province,omitempty" gorm:"foreignKey:Province_Code;references:Code"`
+
+ Regency_Code *string `json:"regency_code" gorm:"size:4"`
+ Regency *erg.Regency `json:"regency,omitempty" gorm:"foreignKey:Regency_Code;references:Code"`
+
+ District_Code *string `json:"district_code" gorm:"size:6"`
+ District *eds.District `json:"district,omitempty" gorm:"foreignKey:District_Code;references:Code"`
+
+ Village_Code *string `json:"village_code" gorm:"size:10"`
+ Village *evl.Village `json:"village,omitempty" gorm:"foreignKey:Village_Code;references:Code"`
+
+ Facility_Code *eren.AmbulanceFacilityCode `json:"facility_code" gorm:"size:10"`
+ Needs_Code *eren.AmbulanceNeedsCode `json:"needs_code" gorm:"size:10"`
+ Contact_Name *string `json:"contact_name" gorm:"size:100"`
+ Contact_Relationship_Code *erp.RelationshipCode `json:"contact_relationship_code" gorm:"size:10"`
+ Contact_PhoneNumber *string `json:"contact_phoneNumber" gorm:"size:20"`
+}
diff --git a/internal/domain/main-entities/ambulatory/dto.go b/internal/domain/main-entities/ambulatory/dto.go
new file mode 100644
index 00000000..455f7f02
--- /dev/null
+++ b/internal/domain/main-entities/ambulatory/dto.go
@@ -0,0 +1,63 @@
+package ambulatory
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ee "simrs-vx/internal/domain/main-entities/encounter"
+ ere "simrs-vx/internal/domain/references/encounter"
+)
+
+type CreateDto struct {
+ Encounter_Id *uint `json:"encounter_id"`
+ Class_Code ere.AmbulatoryClassCode `json:"class_code" validate:"maxLength=10"`
+}
+
+type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ Encounter_Id *uint `json:"encounter-id"`
+ Class_Code ere.AmbulatoryClassCode `json:"class-code"`
+}
+
+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"`
+ Encounter *ee.Encounter `json:"encounter,omitempty"`
+ Class_Code ere.AmbulatoryClassCode `json:"class_code"`
+}
+
+func (d Ambulatory) ToResponse() ResponseDto {
+ resp := ResponseDto{}
+ resp.Main = d.Main
+ return resp
+}
+
+func ToResponseList(data []Ambulatory) []ResponseDto {
+ resp := make([]ResponseDto, len(data))
+ for i, u := range data {
+ resp[i] = u.ToResponse()
+ }
+ return resp
+}
diff --git a/internal/domain/main-entities/ambulatory/entity.go b/internal/domain/main-entities/ambulatory/entity.go
new file mode 100644
index 00000000..58a9810e
--- /dev/null
+++ b/internal/domain/main-entities/ambulatory/entity.go
@@ -0,0 +1,15 @@
+package ambulatory
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ee "simrs-vx/internal/domain/main-entities/encounter"
+
+ ere "simrs-vx/internal/domain/references/encounter"
+)
+
+type Ambulatory struct {
+ ecore.Main // adjust this according to the needs
+ Encounter_Id *uint `json:"encounter_id"`
+ Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"`
+ Class_Code ere.AmbulatoryClassCode `json:"class_code" gorm:"size:10"`
+}
diff --git a/internal/domain/main-entities/appointment/dto.go b/internal/domain/main-entities/appointment/dto.go
new file mode 100644
index 00000000..3f7fcea9
--- /dev/null
+++ b/internal/domain/main-entities/appointment/dto.go
@@ -0,0 +1,85 @@
+package appointment
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ep "simrs-vx/internal/domain/main-entities/patient"
+ eps "simrs-vx/internal/domain/main-entities/practice-schedule"
+ erc "simrs-vx/internal/domain/references/common"
+)
+
+type CreateDto struct {
+ PracticeSchedule_Id *uint `json:"practiceSchedule_id"`
+ Patient_Id *uint `json:"patient_id"`
+ Person_ResidentIdentityNumber string `json:"person_residentIdentityNumber"`
+ Person_Name string `json:"person_name"`
+ Person_PhoneNumber string `json:"person_phoneNumber"`
+ PaymentMethod_Code erc.PaymentMethodCode `json:"paymentMethod_code"`
+ RefNumber string `json:"refNumber"`
+}
+
+type ReadListDto struct {
+ PracticeSchedule_Id *uint `json:"practiceSchedule-id"`
+ Patient_Id *uint `json:"patient-id"`
+ Person_ResidentIdentityNumber string `json:"person-residentIdentityNumber"`
+ Person_Name string `json:"person-name"`
+ Person_PhoneNumber string `json:"person-phoneNumber"`
+ PaymentMethod_Code erc.PaymentMethodCode `json:"paymentMethod-code"`
+ RefNumber string `json:"refNumber"`
+ Pagination ecore.Pagination
+}
+
+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
+ PracticeSchedule_Id *uint `json:"practiceSchedule_id"`
+ PracticeSchedule *eps.PracticeSchedule `json:"practiceSchedule,omitempty"`
+ Patient_Id *uint `json:"patient_id"`
+ Patient *ep.Patient `json:"patient,omitempty"`
+ Person_ResidentIdentityNumber string `json:"person_residentIdentityNumber"`
+ Person_Name string `json:"person_name"`
+ Person_PhoneNumber string `json:"person_phoneNumber"`
+ PaymentMethod_Code erc.PaymentMethodCode `json:"paymentMethod_code"`
+ RefNumber string `json:"refNumber"`
+}
+
+func (d Appointment) ToResponse() ResponseDto {
+ resp := ResponseDto{
+ PracticeSchedule_Id: d.PracticeSchedule_Id,
+ PracticeSchedule: d.PracticeSchedule,
+ Patient_Id: d.Patient_Id,
+ Patient: d.Patient,
+ Person_ResidentIdentityNumber: d.Person_ResidentIdentityNumber,
+ Person_Name: d.Person_Name,
+ Person_PhoneNumber: d.Person_PhoneNumber,
+ PaymentMethod_Code: d.PaymentMethod_Code,
+ RefNumber: d.RefNumber,
+ }
+ resp.Main = d.Main
+ return resp
+}
+
+func ToResponseList(data []Appointment) []ResponseDto {
+ resp := make([]ResponseDto, len(data))
+ for i, u := range data {
+ resp[i] = u.ToResponse()
+ }
+ return resp
+}
diff --git a/internal/domain/main-entities/appointment/entity.go b/internal/domain/main-entities/appointment/entity.go
new file mode 100644
index 00000000..fada15ac
--- /dev/null
+++ b/internal/domain/main-entities/appointment/entity.go
@@ -0,0 +1,21 @@
+package appointment
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ep "simrs-vx/internal/domain/main-entities/patient"
+ eps "simrs-vx/internal/domain/main-entities/practice-schedule"
+ erc "simrs-vx/internal/domain/references/common"
+)
+
+type Appointment struct {
+ ecore.Main // adjust this according to the needs
+ PracticeSchedule_Id *uint `json:"practiceSchedule_id"`
+ PracticeSchedule *eps.PracticeSchedule `json:"practiceSchedule,omitempty" gorm:"foreignKey:PracticeSchedule_Id;references:Id"`
+ Patient_Id *uint `json:"patient_id"`
+ Patient *ep.Patient `json:"patient,omitempty" gorm:"foreignKey:Patient_Id;references:Id"`
+ Person_ResidentIdentityNumber string `json:"person_residentIdentityNumber" gorm:"size:16"`
+ Person_Name string `json:"person_name" gorm:"size:100"`
+ Person_PhoneNumber string `json:"person_phoneNumber" gorm:"size:30"`
+ PaymentMethod_Code erc.PaymentMethodCode `json:"paymentMethod_code" gorm:"size:10"`
+ RefNumber string `json:"refNumber" gorm:"size:20"`
+}
diff --git a/internal/domain/main-entities/chemo/dto.go b/internal/domain/main-entities/chemo/dto.go
new file mode 100644
index 00000000..19e5f803
--- /dev/null
+++ b/internal/domain/main-entities/chemo/dto.go
@@ -0,0 +1,94 @@
+package chemo
+
+import (
+ "time"
+
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ee "simrs-vx/internal/domain/main-entities/encounter"
+ eun "simrs-vx/internal/domain/main-entities/unit"
+ eus "simrs-vx/internal/domain/main-entities/user"
+
+ erc "simrs-vx/internal/domain/references/common"
+
+ pa "simrs-vx/pkg/auth-helper"
+)
+
+type CreateDto struct {
+ Encounter_Id *uint `json:"encounter_id"`
+ Status_Code erc.DataVerifiedCode `json:"status_code"`
+ SrcUnit_Id *uint `json:"srcUnit_id"`
+}
+
+type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ Encounter_Id *uint `json:"encounter-id"`
+ Status_Code *erc.DataVerifiedCode `json:"status-code"`
+ VerifiedBy_User_Id *uint `json:"verifiedBy-user-id"`
+ SrcUnit_Id *uint `json:"srcUnit-id"`
+}
+
+type ReadDetailDto struct {
+ Id uint16 `json:"id"`
+}
+
+type UpdateDto struct {
+ Id uint16 `json:"id"`
+ CreateDto
+}
+
+type DeleteDto struct {
+ Id uint16 `json:"id"`
+}
+
+type VerifyDto struct {
+ Id uint16 `json:"id"`
+ Status_Code erc.DataVerifiedCode `json:"status_code"`
+
+ pa.AuthInfo
+}
+
+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"`
+ Encounter *ee.Encounter `json:"encounter,omitempty"`
+ Status_Code erc.DataVerifiedCode `json:"status_code"`
+ VerifiedAt *time.Time `json:"verifiedAt"`
+ VerifiedBy_User_Id *uint `json:"verifiedBy_user_id"`
+ VerifiedBy *eus.User `json:"verifiedBy,omitempty"`
+ SrcUnit_Id *uint `json:"srcUnit_id"`
+ SrcUnit *eun.Unit `json:"srcUnit,omitempty"`
+}
+
+func (d Chemo) ToResponse() ResponseDto {
+ resp := ResponseDto{
+ Encounter_Id: d.Encounter_Id,
+ Encounter: d.Encounter,
+ Status_Code: d.Status_Code,
+ VerifiedAt: d.VerifiedAt,
+ VerifiedBy_User_Id: d.VerifiedBy_User_Id,
+ VerifiedBy: d.VerifiedBy,
+ SrcUnit_Id: d.SrcUnit_Id,
+ SrcUnit: d.SrcUnit,
+ }
+ resp.Main = d.Main
+ return resp
+}
+
+func ToResponseList(data []Chemo) []ResponseDto {
+ resp := make([]ResponseDto, len(data))
+ for i, u := range data {
+ resp[i] = u.ToResponse()
+ }
+ return resp
+}
diff --git a/internal/domain/main-entities/chemo/entity.go b/internal/domain/main-entities/chemo/entity.go
new file mode 100644
index 00000000..4052ea72
--- /dev/null
+++ b/internal/domain/main-entities/chemo/entity.go
@@ -0,0 +1,26 @@
+package chemo
+
+import (
+ "time"
+
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ee "simrs-vx/internal/domain/main-entities/encounter"
+ eun "simrs-vx/internal/domain/main-entities/unit"
+ eus "simrs-vx/internal/domain/main-entities/user"
+
+ erc "simrs-vx/internal/domain/references/common"
+ ere "simrs-vx/internal/domain/references/encounter"
+)
+
+type Chemo struct {
+ ecore.Main // adjust this according to the needs
+ Encounter_Id *uint `json:"encounter_id"`
+ Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"`
+ Status_Code erc.DataVerifiedCode `json:"status_code"`
+ VerifiedAt *time.Time `json:"verifiedAt"`
+ VerifiedBy_User_Id *uint `json:"verifiedBy_user_id"`
+ VerifiedBy *eus.User `json:"verifiedBy,omitempty" gorm:"foreignKey:VerifiedBy_User_Id;references:Id"`
+ SrcUnit_Id *uint `json:"src_unit_id"`
+ SrcUnit *eun.Unit `json:"src_unit,omitempty" gorm:"foreignKey:SrcUnit_Id;references:Id"`
+ Class_Code ere.ChemoClassCode `json:"class_code"`
+}
diff --git a/internal/domain/main-entities/consultation/dto.go b/internal/domain/main-entities/consultation/dto.go
new file mode 100644
index 00000000..1b0e3cc5
--- /dev/null
+++ b/internal/domain/main-entities/consultation/dto.go
@@ -0,0 +1,95 @@
+package consultation
+
+import (
+ "time"
+
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ed "simrs-vx/internal/domain/main-entities/doctor"
+ ee "simrs-vx/internal/domain/main-entities/encounter"
+ eu "simrs-vx/internal/domain/main-entities/unit"
+
+ pa "simrs-vx/pkg/auth-helper"
+)
+
+type CreateDto struct {
+ Encounter_Id *uint `json:"encounter_id"`
+ Date *time.Time `json:"date"`
+ Problem *string `json:"problem" validate:"maxLength=10240"`
+ DstUnit_Id *uint `json:"dstUnit_id"`
+}
+
+type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ Encounter_Id *uint `json:"encounter-id"`
+ DstUnit_Id *uint `json:"dstUnit-id"`
+ DstDoctor_Id *uint `json:"dstDoctor-id"`
+}
+
+type ReadDetailDto struct {
+ Id uint16 `json:"id"`
+}
+
+type UpdateDto struct {
+ Id uint `json:"id"`
+ CreateDto
+}
+
+type DeleteDto struct {
+ Id uint `json:"id"`
+}
+
+type ReplyDto struct {
+ Id uint `json:"id"`
+ Solution *string `json:"solution"`
+
+ pa.AuthInfo
+}
+
+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"`
+ Encounter *ee.Encounter `json:"encounter,omitempty"`
+ Date *time.Time `json:"date"`
+ Problem *string `json:"problem"`
+ Solution *string `json:"solution"`
+ DstUnit_Id *uint `json:"dstUnit_id"`
+ DstUnit *eu.Unit `json:"dstUnit,omitempty"`
+ DstDoctor_Id *uint `json:"dstDoctor_id"`
+ DstDoctor *ed.Doctor `json:"dstDoctor,omitempty"`
+ RepliedAt *time.Time `json:"repliedAt"`
+}
+
+func (d Consultation) ToResponse() ResponseDto {
+ resp := ResponseDto{
+ Encounter_Id: d.Encounter_Id,
+ Encounter: d.Encounter,
+ Date: d.Date,
+ Problem: d.Problem,
+ Solution: d.Solution,
+ DstUnit_Id: d.DstUnit_Id,
+ DstUnit: d.DstUnit,
+ DstDoctor_Id: d.DstDoctor_Id,
+ DstDoctor: d.DstDoctor,
+ }
+ resp.Main = d.Main
+ return resp
+}
+
+func ToResponseList(data []Consultation) []ResponseDto {
+ resp := make([]ResponseDto, len(data))
+ for i, u := range data {
+ resp[i] = u.ToResponse()
+ }
+ return resp
+}
diff --git a/internal/domain/main-entities/consultation/entity.go b/internal/domain/main-entities/consultation/entity.go
new file mode 100644
index 00000000..2fda8bd0
--- /dev/null
+++ b/internal/domain/main-entities/consultation/entity.go
@@ -0,0 +1,25 @@
+package consultation
+
+import (
+ "time"
+
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ed "simrs-vx/internal/domain/main-entities/doctor"
+ ee "simrs-vx/internal/domain/main-entities/encounter"
+ eu "simrs-vx/internal/domain/main-entities/unit"
+)
+
+type Consultation struct {
+ ecore.Main // adjust this according to the needs
+ Encounter_Id *uint `json:"encounter_id"`
+ Encounter *ee.Encounter `json:"encounter" gorm:"foreignKey:Encounter_Id;references:Id"`
+ Date *time.Time `json:"date"`
+
+ Problem *string `json:"case" gorm:"size:10240"`
+ Solution *string `json:"solution" gorm:"size:10240"`
+ DstUnit_Id *uint `json:"dstUnit_id"`
+ DstUnit *eu.Unit `json:"dstUnit" gorm:"foreignKey:DstUnit_Id;references:Id"`
+ DstDoctor_Id *uint `json:"dstDoctor_id"`
+ DstDoctor *ed.Doctor `json:"dstDoctor" gorm:"foreignKey:DstDoctor_Id;references:Id"`
+ RepliedAt *time.Time `json:"repliedAt"`
+}
diff --git a/internal/domain/main-entities/counter/dto.go b/internal/domain/main-entities/counter/dto.go
index 58e1a1d0..ad11f7a0 100644
--- a/internal/domain/main-entities/counter/dto.go
+++ b/internal/domain/main-entities/counter/dto.go
@@ -17,13 +17,10 @@ type ReadListDto struct {
Code string `json:"code"`
Name string `json:"name"`
Number uint8 `json:"number"`
- Parent_Id *uint16 `json:"parent_id"`
- Type_Code string `json:"type_code"`
- Queue_Code string `json:"queue_code"`
-
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+ Parent_Id *uint16 `json:"parent-id"`
+ Type_Code string `json:"type-code"`
+ Queue_Code string `json:"queue-code"`
+ Pagination ecore.Pagination
}
type ReadDetailDto struct {
diff --git a/internal/domain/main-entities/device-order-item/dto.go b/internal/domain/main-entities/device-order-item/dto.go
new file mode 100644
index 00000000..e89d5fad
--- /dev/null
+++ b/internal/domain/main-entities/device-order-item/dto.go
@@ -0,0 +1,72 @@
+package deviceorderitem
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ed "simrs-vx/internal/domain/main-entities/device"
+ edo "simrs-vx/internal/domain/main-entities/device-order"
+)
+
+type CreateDto struct {
+ DeviceOrder_Id *uint `json:"deviceOrder_id"`
+ Device_Id *uint `json:"device_id"`
+ Count uint8 `json:"count"`
+}
+
+type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ DeviceOrder_Id *uint `json:"deviceOrder-id"`
+ Device_Id *uint `json:"device-id"`
+ Count uint8 `json:"count"`
+}
+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
+ DeviceOrder_Id *uint `json:"deviceOrder_id"`
+ DeviceOrder *edo.DeviceOrder `json:"deviceOrder,omitempty"`
+ Device_Id *uint `json:"device_id"`
+ Device *ed.Device `json:"device,omitempty"`
+ Count uint8 `json:"count"`
+}
+
+func (d DeviceOrderItem) ToResponse() ResponseDto {
+ resp := ResponseDto{
+ DeviceOrder_Id: d.DeviceOrder_Id,
+ DeviceOrder: d.DeviceOrder,
+ Device_Id: d.Device_Id,
+ Device: d.Device,
+ Count: d.Count,
+ }
+ resp.Main = d.Main
+ return resp
+}
+
+func ToResponseList(data []DeviceOrderItem) []ResponseDto {
+ resp := make([]ResponseDto, len(data))
+ for i, u := range data {
+ resp[i] = u.ToResponse()
+ }
+ return resp
+}
diff --git a/internal/domain/main-entities/device-order-item/entity.go b/internal/domain/main-entities/device-order-item/entity.go
new file mode 100644
index 00000000..196415af
--- /dev/null
+++ b/internal/domain/main-entities/device-order-item/entity.go
@@ -0,0 +1,16 @@
+package deviceorderitem
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ed "simrs-vx/internal/domain/main-entities/device"
+ edo "simrs-vx/internal/domain/main-entities/device-order"
+)
+
+type DeviceOrderItem struct {
+ ecore.Main // adjust this according to the needs
+ DeviceOrder_Id *uint `json:"deviceOrder_id"`
+ DeviceOrder *edo.DeviceOrder `json:"deviceOrder,omitempty" gorm:"foreignKey:DeviceOrder_Id;references:Id"`
+ Device_Id *uint `json:"device_id"`
+ Device *ed.Device `json:"device,omitempty" gorm:"foreignKey:Device_Id;references:Id"`
+ Count uint8 `json:"count"`
+}
diff --git a/internal/domain/main-entities/device-order/dto.go b/internal/domain/main-entities/device-order/dto.go
new file mode 100644
index 00000000..01ef34b2
--- /dev/null
+++ b/internal/domain/main-entities/device-order/dto.go
@@ -0,0 +1,78 @@
+package deviceorder
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ed "simrs-vx/internal/domain/main-entities/doctor"
+ ee "simrs-vx/internal/domain/main-entities/encounter"
+
+ erc "simrs-vx/internal/domain/references/common"
+
+ pa "simrs-vx/pkg/auth-helper"
+)
+
+type CreateDto struct {
+ Encounter_Id *uint `json:"encounter_id"`
+ Status_Code erc.DataStatusCode `json:"status_code"`
+ Doctor_Id *uint `json:"doctor_id"`
+
+ pa.AuthInfo
+}
+
+type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ Encounter_Id *uint `json:"encounter-id"`
+ Status_Code erc.DataStatusCode `json:"status-code"`
+ Doctor_Id *uint `json:"doctor-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"`
+ Encounter *ee.Encounter `json:"encounter,omitempty"`
+ Doctor_Id *uint `json:"doctor_id"`
+ Doctor *ed.Doctor `json:"doctor,omitempty"`
+ Status_Code erc.DataStatusCode `json:"status_code"`
+}
+
+func (d DeviceOrder) ToResponse() ResponseDto {
+ resp := ResponseDto{
+ Encounter_Id: d.Encounter_Id,
+ Encounter: d.Encounter,
+ Doctor_Id: d.Doctor_Id,
+ Doctor: d.Doctor,
+ Status_Code: d.Status_Code,
+ }
+ resp.Main = d.Main
+ return resp
+}
+
+func ToResponseList(data []DeviceOrder) []ResponseDto {
+ resp := make([]ResponseDto, len(data))
+ for i, u := range data {
+ resp[i] = u.ToResponse()
+ }
+ return resp
+}
diff --git a/internal/domain/main-entities/device-order/entity.go b/internal/domain/main-entities/device-order/entity.go
new file mode 100644
index 00000000..7f693518
--- /dev/null
+++ b/internal/domain/main-entities/device-order/entity.go
@@ -0,0 +1,26 @@
+package deviceorder
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ed "simrs-vx/internal/domain/main-entities/doctor"
+ ee "simrs-vx/internal/domain/main-entities/encounter"
+
+ erc "simrs-vx/internal/domain/references/common"
+)
+
+type DeviceOrder struct {
+ ecore.Main // adjust this according to the needs
+ Encounter_Id *uint `json:"encounter_id"`
+ Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"`
+ Doctor_Id *uint `json:"doctor_id"`
+ Doctor *ed.Doctor `json:"doctor,omitempty" gorm:"foreignKey:Doctor_Id;references:Id"`
+ Status_Code erc.DataStatusCode `json:"status_code"`
+}
+
+func (d DeviceOrder) IsCompleted() bool {
+ return d.Status_Code == erc.DSCDone
+}
+
+func (d DeviceOrder) IsSameDoctor(doctor_id *uint) bool {
+ return d.Doctor_Id == doctor_id
+}
diff --git a/internal/domain/main-entities/device/dto.go b/internal/domain/main-entities/device/dto.go
index dcc115c6..1c874576 100644
--- a/internal/domain/main-entities/device/dto.go
+++ b/internal/domain/main-entities/device/dto.go
@@ -17,20 +17,18 @@ type CreateDto struct {
type ReadListDto struct {
FilterDto
- Includes string `json:"includes"`
- Preloads []string `json:"-"`
+ Includes string `json:"includes"`
+ Sort string `json:"sort"`
+ Pagination ecore.Pagination
}
type FilterDto struct {
Code string `json:"code"`
Name string `json:"name"`
- Uom_Code string `json:"uom_code"`
- Infra_Id *uint16 `json:"infra_id"`
- Item_Id *uint `json:"item_id"`
-
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+ Uom_Code string `json:"uom-code"`
+ Infra_Id *uint16 `json:"infra-id"`
+ Item_Id *uint `json:"item-id"`
+ Search string `json:"search" gormhelper:"searchColumns=Code,Name"`
}
type ReadDetailDto struct {
diff --git a/internal/domain/main-entities/diagnose-src/dto.go b/internal/domain/main-entities/diagnose-src/dto.go
index 7b11f8b8..6266484a 100644
--- a/internal/domain/main-entities/diagnose-src/dto.go
+++ b/internal/domain/main-entities/diagnose-src/dto.go
@@ -11,13 +11,17 @@ type CreateDto struct {
}
type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Sort string `json:"sort"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
Code string `json:"code"`
Name string `json:"name"`
IndName string `json:"indName"`
-
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+ Search string `json:"search" gormhelper:"searchColumns=Code,Name"`
}
type ReadDetailDto struct {
diff --git a/internal/domain/main-entities/district/base/entity.go b/internal/domain/main-entities/district/base/entity.go
new file mode 100644
index 00000000..40af0fc3
--- /dev/null
+++ b/internal/domain/main-entities/district/base/entity.go
@@ -0,0 +1,12 @@
+package base
+
+type Basic struct {
+ Id uint32 `json:"id" gorm:"primaryKey"`
+ Regency_Code string `json:"regency_code" gorm:"size:4"`
+ Code string `json:"code" gorm:"unique;size:6"` // NOTE: THE PROPER SIZE IS 6
+ Name string `json:"name" gorm:"size:50"`
+}
+
+func (Basic) TableName() string {
+ return "District"
+}
diff --git a/internal/domain/main-entities/district/dto.go b/internal/domain/main-entities/district/dto.go
index 57f41892..ae818d45 100644
--- a/internal/domain/main-entities/district/dto.go
+++ b/internal/domain/main-entities/district/dto.go
@@ -1,6 +1,11 @@
package district
-import ev "simrs-vx/internal/domain/main-entities/village"
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ edb "simrs-vx/internal/domain/main-entities/district/base"
+ er "simrs-vx/internal/domain/main-entities/regency"
+ evb "simrs-vx/internal/domain/main-entities/village/base"
+)
type CreateDto struct {
Regency_Code string `json:"regency_code" validate:"numeric;maxLength=4"`
@@ -9,13 +14,17 @@ type CreateDto struct {
}
type ReadListDto struct {
- Regency_Code string `json:"regency_code"`
+ FilterDto
+ Includes string `json:"includes"`
+ Sort string `json:"sort"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ Regency_Code string `json:"regency-code"`
Code string `json:"code"`
Name string `json:"name"`
-
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+ Search string `json:"search" gormhelper:"searchColumns=Code,Name"`
}
type ReadDetailDto struct {
@@ -39,11 +48,9 @@ type MetaDto struct {
}
type ResponseDto struct {
- Id uint32 `json:"id"`
- Regency_Code string `json:"regency_code"`
- Code string `json:"code"`
- Name string `json:"name"`
- Villages []*ev.Village `json:"villages,omitempty"`
+ edb.Basic
+ Regency *er.Regency `json:"regency,omitempty"`
+ Villages []*evb.Basic `json:"villages,omitempty"`
}
func (d District) ToResponse() ResponseDto {
diff --git a/internal/domain/main-entities/district/entity.go b/internal/domain/main-entities/district/entity.go
index a3ad27e7..b9cb89c3 100644
--- a/internal/domain/main-entities/district/entity.go
+++ b/internal/domain/main-entities/district/entity.go
@@ -1,11 +1,13 @@
package district
-import ev "simrs-vx/internal/domain/main-entities/village"
+import (
+ edb "simrs-vx/internal/domain/main-entities/district/base"
+ er "simrs-vx/internal/domain/main-entities/regency"
+ evb "simrs-vx/internal/domain/main-entities/village/base"
+)
type District struct {
- Id uint32 `json:"id" gorm:"primaryKey"`
- Regency_Code string `json:"regency_code" gorm:"size:4"`
- Code string `json:"code" gorm:"unique;size:6"` // NOTE: THE PROPER SIZE IS 6
- Name string `json:"name" gorm:"size:50"`
- Villages []*ev.Village `json:"villages,omitempty" gorm:"foreignKey:District_Code;references:Code"`
+ edb.Basic
+ Regency *er.Regency `json:"regency,omitempty" gorm:"foreignKey:Regency_Code;references:Code"`
+ Villages []*evb.Basic `json:"villages,omitempty" gorm:"foreignKey:District_Code;references:Code"`
}
diff --git a/internal/domain/main-entities/division-position/dto.go b/internal/domain/main-entities/division-position/dto.go
index 592985fe..b93e0e98 100644
--- a/internal/domain/main-entities/division-position/dto.go
+++ b/internal/domain/main-entities/division-position/dto.go
@@ -3,28 +3,31 @@ package divisionposition
import (
ecore "simrs-vx/internal/domain/base-entities/core"
ed "simrs-vx/internal/domain/main-entities/division"
+ ee "simrs-vx/internal/domain/main-entities/employee"
)
type CreateDto struct {
Division_Id *uint16 `json:"division_id"`
Code string `json:"code" validate:"maxLength=10"`
Name string `json:"name" validate:"maxLength=50"`
+ HeadStatus bool `json:"headStatus"`
+ Employee_Id *uint `json:"employee_id"`
}
type ReadListDto struct {
FilterDto
- Includes string `json:"includes"`
- Preloads []string `json:"-"`
+ Includes string `json:"includes"`
+ Sort string `json:"sort"`
+ Pagination ecore.Pagination
}
type FilterDto struct {
- Division_Id *uint16 `json:"division_id"`
+ Division_Id *uint16 `json:"division-id"`
Code string `json:"code"`
Name string `json:"name"`
-
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+ HeadStatus *bool `json:"head-status"`
+ Employee_Id *uint `json:"employee-id"`
+ Search string `json:"search" gormhelper:"searchColumns=Code,Name"`
}
type ReadDetailDto struct {
@@ -53,6 +56,9 @@ type ResponseDto struct {
Division *ed.Division `json:"division,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 DivisionPosition) ToResponse() ResponseDto {
@@ -60,6 +66,9 @@ func (d DivisionPosition) ToResponse() ResponseDto {
Division_Id: d.Division_Id,
Code: d.Code,
Name: d.Name,
+ HeadStatus: d.HeadStatus,
+ Employee_Id: d.Employee_Id,
+ Employee: d.Employee,
}
resp.SmallMain = d.SmallMain
if d.Division != nil {
diff --git a/internal/domain/main-entities/division-position/entity.go b/internal/domain/main-entities/division-position/entity.go
index 6ff32055..5bb3160a 100644
--- a/internal/domain/main-entities/division-position/entity.go
+++ b/internal/domain/main-entities/division-position/entity.go
@@ -3,6 +3,7 @@ package divisionposition
import (
ecore "simrs-vx/internal/domain/base-entities/core"
ed "simrs-vx/internal/domain/main-entities/division"
+ ee "simrs-vx/internal/domain/main-entities/employee"
)
type DivisionPosition struct {
@@ -11,4 +12,7 @@ type DivisionPosition struct {
Division *ed.Division `json:"division" gorm:"foreignKey:Division_Id"`
Code string `json:"code" gorm:"unique;size:10"`
Name string `json:"name" gorm:"size:50"`
+ HeadStatus bool `json:"headStatus"`
+ Employee_Id *uint `json:"employee_id"`
+ Employee *ee.Employee `json:"employee,omitempty" gorm:"foreignKey:Employee_Id;references:Id"`
}
diff --git a/internal/domain/main-entities/division/dto.go b/internal/domain/main-entities/division/dto.go
index e8ba2d97..95ea9119 100644
--- a/internal/domain/main-entities/division/dto.go
+++ b/internal/domain/main-entities/division/dto.go
@@ -5,19 +5,24 @@ import (
)
type CreateDto struct {
- Code string `json:"code" validate:"maxLength=10"`
- Name string `json:"name" validate:"maxLength=50"`
- Parent_Id *int16 `json:"parent_id"`
+ Code string `json:"code" validate:"maxLength=10"`
+ Name string `json:"name" validate:"maxLength=50"`
+ Parent_Id *uint16 `json:"parent_id"`
}
type ReadListDto struct {
- Code string `json:"code"`
- Name string `json:"name"`
- Parent_Id *int16 `json:"parent_id"`
+ FilterDto
+ Includes string `json:"includes"`
+ Sort string `json:"sort"`
+ Pagination ecore.Pagination
+ OnlyHaveChildren bool `json:"only-have-children"`
+}
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+type FilterDto struct {
+ Code string `json:"code"`
+ Name string `json:"name"`
+ Parent_Id *uint16 `json:"parent-id"`
+ Search string `json:"search" gormhelper:"searchColumns=Code,Name"`
}
type ReadDetailDto struct {
@@ -42,9 +47,11 @@ type MetaDto struct {
type ResponseDto struct {
ecore.SmallMain
- Code string `json:"code"`
- Name string `json:"name"`
- Parent_Id *int16 `json:"parent_id"`
+ Code string `json:"code"`
+ Name string `json:"name"`
+ Parent_Id *uint16 `json:"parent_id"`
+ Parent *Division `json:"parent,omitempty"`
+ Childrens []Division `json:"childrens,omitempty"`
}
func (d Division) ToResponse() ResponseDto {
@@ -52,6 +59,8 @@ func (d Division) ToResponse() ResponseDto {
Code: d.Code,
Name: d.Name,
Parent_Id: d.Parent_Id,
+ Parent: d.Parent,
+ Childrens: d.Childrens,
}
resp.SmallMain = d.SmallMain
return resp
diff --git a/internal/domain/main-entities/division/entity.go b/internal/domain/main-entities/division/entity.go
index 7d3bc65d..470fab0d 100644
--- a/internal/domain/main-entities/division/entity.go
+++ b/internal/domain/main-entities/division/entity.go
@@ -5,8 +5,10 @@ import (
)
type Division struct {
- ecore.SmallMain // adjust this according to the needs
- Code string `json:"code" gorm:"unique;size:10"`
- Name string `json:"name" gorm:"size:50"`
- Parent_Id *int16 `json:"parent_id"`
+ ecore.SmallMain // adjust this according to the needs
+ Code string `json:"code" gorm:"unique;size:10"`
+ Name string `json:"name" gorm:"size:50"`
+ Parent_Id *uint16 `json:"parent_id"`
+ Parent *Division `json:"parent" gorm:"foreignKey:Parent_Id;references:Id"`
+ Childrens []Division `json:"childrens" gorm:"foreignKey:Parent_Id"` // may need references to self
}
diff --git a/internal/domain/main-entities/doctor-fee/dto.go b/internal/domain/main-entities/doctor-fee/dto.go
index 9e22d4d2..baaf5cbf 100644
--- a/internal/domain/main-entities/doctor-fee/dto.go
+++ b/internal/domain/main-entities/doctor-fee/dto.go
@@ -16,19 +16,15 @@ type CreateDto struct {
type ReadListDto struct {
FilterDto
- Includes string `json:"includes"`
- Preloads []string `json:"-"`
+ Includes string `json:"includes"`
+ Pagination ecore.Pagination
}
type FilterDto struct {
- Doctor_Id *uint `json:"doctor_id"`
- FeeType_Code *ero.DoctorFeeTypeCode `json:"feeType_code"`
+ Doctor_Id *uint `json:"doctor-id"`
+ FeeType_Code *ero.DoctorFeeTypeCode `json:"feeType-code"`
Price *float64 `json:"price"`
- Item_Id *uint `json:"item_id"`
-
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+ Item_Id *uint `json:"item-id"`
}
type ReadDetailDto struct {
diff --git a/internal/domain/main-entities/doctor/dto.go b/internal/domain/main-entities/doctor/dto.go
index f016cc1f..62d5f5b4 100644
--- a/internal/domain/main-entities/doctor/dto.go
+++ b/internal/domain/main-entities/doctor/dto.go
@@ -3,31 +3,33 @@ package doctor
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"
+ ess "simrs-vx/internal/domain/main-entities/subspecialist"
eu "simrs-vx/internal/domain/main-entities/unit"
)
type CreateDto struct {
- Employee_Id *uint `json:"employee_id"`
- IHS_Number *string `json:"ihs_number"`
- SIP_Number *string `json:"sip_number"`
- Unit_Id *uint `json:"unit_id"`
+ Employee_Id *uint `json:"employee_id"`
+ IHS_Number *string `json:"ihs_number"`
+ SIP_Number *string `json:"sip_number"`
+ Unit_Id *uint16 `json:"unit_id"`
+ Specialist_Id *uint16 `json:"specialist_id"`
+ Subspecialist_Id *uint16 `json:"subspecialist_id"`
}
type ReadListDto struct {
FilterDto
- Includes string `json:"includes"`
- Preloads []string `json:"-"`
+ Includes string `json:"includes"`
+ Pagination ecore.Pagination
}
type FilterDto struct {
- Employee_Id *uint `json:"employee_id"`
- IHS_Number *string `json:"ihs_number" validate:"maxLength=20"`
- SIP_Number *string `json:"sip_number" validate:"maxLength=20"`
- Unit_Id *uint `json:"unit_id"`
-
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+ Employee_Id *uint `json:"employee-id"`
+ IHS_Number *string `json:"ihs-number" validate:"maxLength=20"`
+ SIP_Number *string `json:"sip-number" validate:"maxLength=20"`
+ Unit_Id *uint `json:"unit-id"`
+ Specialist_Id *uint16 `json:"specialist-id"`
+ Subspecialist_Id *uint16 `json:"subspecialist-id"`
}
type ReadDetailDto struct {
@@ -54,22 +56,30 @@ type MetaDto struct {
type ResponseDto struct {
ecore.Main
- Employee_Id *uint `json:"employee_id"`
- Employee *ee.Employee `json:"employee,omitempty"`
- IHS_Number *string `json:"ihs_number"`
- SIP_Number *string `json:"sip_number"`
- Unit_Id *uint `json:"unit_id"`
- Unit *eu.Unit `json:"unit,omitempty"`
+ Employee_Id *uint `json:"employee_id"`
+ Employee *ee.Employee `json:"employee,omitempty"`
+ IHS_Number *string `json:"ihs_number"`
+ SIP_Number *string `json:"sip_number"`
+ Unit_Id *uint16 `json:"unit_id"`
+ Unit *eu.Unit `json:"unit,omitempty"`
+ Specialist_Id *uint16 `json:"specialist_id"`
+ Specialist *es.Specialist `json:"specialist,omitempty" `
+ Subspecialist_Id *uint16 `json:"subspecialist_id"`
+ Subspecialist *ess.Subspecialist `json:"subspecialist,omitempty"`
}
func (d Doctor) ToResponse() ResponseDto {
resp := ResponseDto{
- Employee_Id: d.Employee_Id,
- Employee: d.Employee,
- IHS_Number: d.IHS_Number,
- SIP_Number: d.SIP_Number,
- Unit_Id: d.Unit_Id,
- Unit: d.Unit,
+ Employee_Id: d.Employee_Id,
+ Employee: d.Employee,
+ IHS_Number: d.IHS_Number,
+ SIP_Number: d.SIP_Number,
+ Unit_Id: d.Unit_Id,
+ Unit: d.Unit,
+ Specialist_Id: d.Specialist_Id,
+ Specialist: d.Specialist,
+ Subspecialist_Id: d.Subspecialist_Id,
+ Subspecialist: d.Subspecialist,
}
resp.Main = d.Main
return resp
diff --git a/internal/domain/main-entities/doctor/entity.go b/internal/domain/main-entities/doctor/entity.go
index f73356ea..cf952380 100644
--- a/internal/domain/main-entities/doctor/entity.go
+++ b/internal/domain/main-entities/doctor/entity.go
@@ -3,15 +3,21 @@ package doctor
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"
+ ess "simrs-vx/internal/domain/main-entities/subspecialist"
eu "simrs-vx/internal/domain/main-entities/unit"
)
type Doctor struct {
- ecore.Main // adjust this according to the needs
- Employee_Id *uint `json:"employee_id"`
- Employee *ee.Employee `json:"employee,omitempty" gorm:"foreignKey:Employee_Id;references:Id"`
- IHS_Number *string `json:"ihs_number" gorm:"size:20"`
- SIP_Number *string `json:"sip_number" gorm:"size:20"`
- Unit_Id *uint `json:"unit_id"`
- Unit *eu.Unit `json:"unit,omitempty" gorm:"foreignKey:Unit_Id;references:Id"`
+ ecore.Main // adjust this according to the needs
+ Employee_Id *uint `json:"employee_id"`
+ Employee *ee.Employee `json:"employee,omitempty" gorm:"foreignKey:Employee_Id;references:Id"`
+ IHS_Number *string `json:"ihs_number" gorm:"unique;size:20"`
+ SIP_Number *string `json:"sip_number" gorm:"unique;size:20"`
+ Unit_Id *uint16 `json:"unit_id"`
+ Unit *eu.Unit `json:"unit,omitempty" gorm:"foreignKey:Unit_Id;references:Id"`
+ Specialist_Id *uint16 `json:"specialist_id"`
+ Specialist *es.Specialist `json:"specialist,omitempty" gorm:"foreignKey:Specialist_Id"`
+ Subspecialist_Id *uint16 `json:"subspecialist_id"`
+ Subspecialist *ess.Subspecialist `json:"subspecialist,omitempty" gorm:"foreignKey:Subspecialist_Id"`
}
diff --git a/internal/domain/main-entities/emergency/dto.go b/internal/domain/main-entities/emergency/dto.go
new file mode 100644
index 00000000..99628b88
--- /dev/null
+++ b/internal/domain/main-entities/emergency/dto.go
@@ -0,0 +1,63 @@
+package emergency
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ee "simrs-vx/internal/domain/main-entities/encounter"
+ ere "simrs-vx/internal/domain/references/encounter"
+)
+
+type CreateDto struct {
+ Encounter_Id *uint `json:"encounter_id"`
+ Class_Code ere.EmergencyClassCode `json:"class_code" validate:"maxLength=10"`
+}
+
+type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ Encounter_Id *uint `json:"encounter-id"`
+ Class_Code ere.EmergencyClassCode `json:"class-code"`
+}
+
+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"`
+ Encounter *ee.Encounter `json:"encounter,omitempty"`
+ Class_Code ere.EmergencyClassCode `json:"class_code"`
+}
+
+func (d Emergency) ToResponse() ResponseDto {
+ resp := ResponseDto{}
+ resp.Main = d.Main
+ return resp
+}
+
+func ToResponseList(data []Emergency) []ResponseDto {
+ resp := make([]ResponseDto, len(data))
+ for i, u := range data {
+ resp[i] = u.ToResponse()
+ }
+ return resp
+}
diff --git a/internal/domain/main-entities/emergency/entity.go b/internal/domain/main-entities/emergency/entity.go
new file mode 100644
index 00000000..1e6fb078
--- /dev/null
+++ b/internal/domain/main-entities/emergency/entity.go
@@ -0,0 +1,15 @@
+package emergency
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ee "simrs-vx/internal/domain/main-entities/encounter"
+
+ ere "simrs-vx/internal/domain/references/encounter"
+)
+
+type Emergency struct {
+ ecore.Main // adjust this according to the needs
+ Encounter_Id *uint `json:"encounter_id"`
+ Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"`
+ Class_Code ere.EmergencyClassCode `json:"class_code" gorm:"size:10"`
+}
diff --git a/internal/domain/main-entities/employee/dto.go b/internal/domain/main-entities/employee/dto.go
index 371d82a1..00891cc6 100644
--- a/internal/domain/main-entities/employee/dto.go
+++ b/internal/domain/main-entities/employee/dto.go
@@ -4,46 +4,31 @@ import (
ecore "simrs-vx/internal/domain/base-entities/core"
ed "simrs-vx/internal/domain/main-entities/division"
ep "simrs-vx/internal/domain/main-entities/person"
- epa "simrs-vx/internal/domain/main-entities/person-address"
- epc "simrs-vx/internal/domain/main-entities/person-contact"
eu "simrs-vx/internal/domain/main-entities/user"
+
erc "simrs-vx/internal/domain/references/common"
- ero "simrs-vx/internal/domain/references/organization"
)
type CreateDto struct {
- User_Id *uint `json:"user_id"`
- User *eu.CreateDto `json:"user"`
- Person_Id *uint `json:"-"`
- Person *ep.UpdateDto `json:"person"`
- PersonAddresses []epa.UpdateDto `json:"personAddresses"`
- PersonContacts []epc.UpdateDto `json:"personContacts"`
- Position_Code ero.EmployeePosisitionCode `json:"position_code" validate:"maxLength=20"`
- Division_Code *string `json:"division_code"`
- Number *string `json:"number" validate:"maxLength=20"`
- Status_Code erc.ActiveStatusCode `json:"status_code" validate:"maxLength=10"`
- IHS_Number *string `json:"ihs_number"`
- SIP_Number *string `json:"sip_number"`
- Unit_Id *uint `json:"unit_id"`
+ User_Id *uint `json:"user_id"`
+ Person_Id *uint `json:"person_id"`
+ Division_Code *string `json:"division_code"`
+ Number *string `json:"number" validate:"maxLength=20"`
+ Status_Code erc.ActiveStatusCode `json:"status_code" validate:"maxLength=10"`
}
type ReadListDto struct {
FilterDto
- Includes string `json:"includes"`
- Preloads []string `json:"-"`
+ Includes string `json:"includes"`
+ Pagination ecore.Pagination
}
type FilterDto struct {
- User_Id *uint `json:"user_id"`
- Person_Id *uint `json:"person_id"`
- Position_Code ero.EmployeePosisitionCode `json:"position_code"`
- Division_Code *string `json:"division_code"`
- Number *string `json:"number"`
- Status_Code erc.ActiveStatusCode `json:"status_code"`
-
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+ User_Id *uint `json:"user-id"`
+ Person_Id *uint `json:"person-id"`
+ Division_Code *string `json:"division-code"`
+ Number *string `json:"number"`
+ Status_Code erc.ActiveStatusCode `json:"status-code"`
}
type ReadDetailDto struct {
@@ -70,15 +55,14 @@ type MetaDto struct {
type ResponseDto struct {
ecore.Main
- User_Id *uint `json:"user_id"`
- User *eu.User `json:"user,omitempty"`
- Person_Id *uint `json:"person_id"`
- Person *ep.Person `json:"person,omitempty"`
- Position_Code ero.EmployeePosisitionCode `json:"position_code"`
- Division_Code *string `json:"division_code"`
- Division *ed.Division `json:"division,omitempty"`
- Number *string `json:"number"`
- Status_Code erc.ActiveStatusCode `json:"status_code"`
+ User_Id *uint `json:"user_id"`
+ User *eu.User `json:"user,omitempty"`
+ Person_Id *uint `json:"person_id"`
+ Person *ep.Person `json:"person,omitempty"`
+ Division_Code *string `json:"division_code"`
+ Division *ed.Division `json:"division,omitempty"`
+ Number *string `json:"number"`
+ Status_Code erc.ActiveStatusCode `json:"status_code"`
}
func (d Employee) ToResponse() ResponseDto {
@@ -87,7 +71,6 @@ func (d Employee) ToResponse() ResponseDto {
User: d.User,
Person_Id: d.Person_Id,
Person: d.Person,
- Position_Code: d.Position_Code,
Division_Code: d.Division_Code,
Division: d.Division,
Number: d.Number,
@@ -104,9 +87,3 @@ func ToResponseList(data []Employee) []ResponseDto {
}
return resp
}
-
-func (c CreateDto) Sanitize() CreateDto {
- sanitized := c
- sanitized.User.Password = "[REDACTED]"
- return sanitized
-}
diff --git a/internal/domain/main-entities/employee/entity.go b/internal/domain/main-entities/employee/entity.go
index 24687262..2e8cd953 100644
--- a/internal/domain/main-entities/employee/entity.go
+++ b/internal/domain/main-entities/employee/entity.go
@@ -6,18 +6,18 @@ import (
ep "simrs-vx/internal/domain/main-entities/person"
eu "simrs-vx/internal/domain/main-entities/user"
erc "simrs-vx/internal/domain/references/common"
- ero "simrs-vx/internal/domain/references/organization"
+ erg "simrs-vx/internal/domain/references/organization"
)
type Employee struct {
- ecore.Main // adjust this according to the needs
- User_Id *uint `json:"user_id"`
- User *eu.User `json:"user,omitempty" gorm:"foreignKey:User_Id;references:Id"`
- Person_Id *uint `json:"person_id"`
- Person *ep.Person `json:"person,omitempty" gorm:"foreignKey:Person_Id;references:Id"`
- Position_Code ero.EmployeePosisitionCode `json:"position_code" gorm:"not null;size:20"`
- Division_Code *string `json:"division_code"`
- Division *ed.Division `json:"division,omitempty" gorm:"foreignKey:Division_Code;references:Code"`
- Number *string `json:"number" gorm:"size:20"`
- Status_Code erc.ActiveStatusCode `json:"status_code" gorm:"not null;size:10"`
+ ecore.Main // adjust this according to the needs
+ User_Id *uint `json:"user_id"`
+ User *eu.User `json:"user,omitempty" gorm:"foreignKey:User_Id;references:Id"`
+ Person_Id *uint `json:"person_id"`
+ Person *ep.Person `json:"person,omitempty" gorm:"foreignKey:Person_Id;references:Id"`
+ Position_Code *erg.EmployeePosisitionCode `json:"position_code" gorm:"size:20"`
+ Division_Code *string `json:"division_code"`
+ Division *ed.Division `json:"division,omitempty" gorm:"foreignKey:Division_Code;references:Code"`
+ Number *string `json:"number" gorm:"size:20"`
+ Status_Code erc.ActiveStatusCode `json:"status_code" gorm:"not null;size:10"`
}
diff --git a/internal/domain/main-entities/encounter/dto.go b/internal/domain/main-entities/encounter/dto.go
index b959fb38..73a9ec5b 100644
--- a/internal/domain/main-entities/encounter/dto.go
+++ b/internal/domain/main-entities/encounter/dto.go
@@ -1,42 +1,76 @@
package encounter
import (
- ecore "simrs-vx/internal/domain/base-entities/core"
- ed "simrs-vx/internal/domain/main-entities/doctor"
- ep "simrs-vx/internal/domain/main-entities/patient"
- eu "simrs-vx/internal/domain/main-entities/unit"
- ere "simrs-vx/internal/domain/references/encounter"
"time"
+
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ evs "simrs-vx/internal/domain/bpjs-entities/vclaim-sep"
+ ea "simrs-vx/internal/domain/main-entities/appointment"
+ ed "simrs-vx/internal/domain/main-entities/doctor"
+ ee "simrs-vx/internal/domain/main-entities/employee"
+ ep "simrs-vx/internal/domain/main-entities/patient"
+ es "simrs-vx/internal/domain/main-entities/specialist"
+ ess "simrs-vx/internal/domain/main-entities/subspecialist"
+ eu "simrs-vx/internal/domain/main-entities/unit"
+
+ erc "simrs-vx/internal/domain/references/common"
+ ere "simrs-vx/internal/domain/references/encounter"
+
+ pa "simrs-vx/pkg/auth-helper"
)
type CreateDto struct {
- Patient_Id *uint `json:"patient_id"`
- Patient *ep.Patient `json:"patient,omitempty"`
- RegisteredAt *time.Time `json:"registeredAt"`
- Class_Code ere.EncounterClassCode `json:"class_code" validate:"maxLength=10"`
- Unit_Id *uint `json:"unit_id"`
- VisitDate time.Time `json:"visitDate"`
- Assignment_Doctor_Id *uint `json:"assignment_doctor_id"`
- Responsible_Doctor_Id *uint `json:"responsible_doctor_id"`
- DischardeMethod_Code ere.DischargeMethodCode `json:"dischardeMethod_code" validate:"maxLength=10"`
- RefSource_Name *string `json:"refSource_name" validate:"maxLength=100"`
+ Patient_Id *uint `json:"patient_id"`
+ RegisteredAt *time.Time `json:"registeredAt"`
+ Class_Code ere.EncounterClassCode `json:"class_code" validate:"maxLength=10"`
+ SubClass_Code *string `json:"subClass_code" validate:"maxLength=10"` // for sub
+ Infra_Id *uint16 `json:"infra_id"` // for inpatient
+ Unit_Id *uint `json:"unit_id"`
+ Specialist_Id *uint16 `json:"specialist_id"`
+ Subspecialist_Id *uint16 `json:"subspecialist_id"`
+ VisitDate time.Time `json:"visitDate"`
+ PaymentMethod_Code erc.PaymentMethodCode `json:"paymentMethod_code" gorm:"size:10"`
+ InsuranceCompany_Id *uint `json:"insuranceCompany_id"`
+ Member_Number *string `json:"member_number" validate:"maxLength=20"`
+ Ref_Number *string `json:"ref_number" validate:"maxLength=20"`
+ Trx_Number *string `json:"trx_number" validate:"maxLength=20"`
+ Appointment_Doctor_Id *uint `json:"appointment_doctor_id"`
+ Adm_Employee_Id *uint `json:"-"`
+ Responsible_Doctor_Id *uint `json:"responsible_doctor_id"`
+ RefSource_Name *string `json:"refSource_name" validate:"maxLength=100"`
+ Appointment_Id *uint `json:"appointment_id"`
+
+ pa.AuthInfo
}
type ReadListDto struct {
- Code string `json:"code"`
- Name string `json:"name"`
- Parent_Id *int16 `json:"parent_id"`
+ FilterDto
+ Includes string `json:"includes"`
+ Pagination ecore.Pagination
+}
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+type FilterDto struct {
+ Patient_Id *uint `json:"patient-id"`
+ Patient *ep.Patient `json:"patient,omitempty"`
+ RegisteredAt *time.Time `json:"registeredAt"`
+ Class_Code ere.EncounterClassCode `json:"class-code" validate:"maxLength=10"`
+ Unit_Id *uint `json:"unit-id"`
+ Specialist_Id *uint16 `json:"specialist-id"`
+ Subspecialist_Id *uint16 `json:"subspecialist-id"`
+ VisitDate time.Time `json:"visitDate"`
+ Appoinment_Doctor_Id *uint `json:"appointment-doctor-id"`
+ Responsible_Doctor_Id *uint `json:"responsible-doctor-id"`
+ DischargeMethod_Code ere.DischargeMethodCode `json:"dischargeMethod-code" validate:"maxLength=10"`
+ RefSource_Name *string `json:"refSource-name" validate:"maxLength=100"`
+ Appointment_Id *uint `json:"appointment-id"`
+ EarlyEducation *string `json:"earlyEducation"`
+ MedicalDischargeEducation *string `json:"medicalDischargeEducation"`
+ AdmDischargeEducation *string `json:"admDischargeEducation"`
+ DischargeReason *string `json:"dischargeReason"`
}
type ReadDetailDto struct {
- Id uint16 `json:"id"`
- Code string `json:"code"`
- Name string `json:"name"`
- Parent_Id *int16 `json:"parent_id"`
+ Id uint16 `json:"id"`
}
type UpdateDto struct {
@@ -44,6 +78,11 @@ type UpdateDto struct {
CreateDto
}
+type UpdateStatusDto struct {
+ Id uint16 `json:"id"`
+ StatusCode erc.DataStatusCode `json:"status_code"`
+}
+
type DeleteDto struct {
Id uint16 `json:"id"`
}
@@ -53,39 +92,85 @@ type MetaDto struct {
PageSize int `json:"page_size"`
Count int `json:"count"`
}
+type DischargeDto struct {
+ Id uint `json:"id"`
+ DischargeMethod_Code *ere.DischargeMethodCode `json:"dischargeMethod_code" validate:"maxLength=16"`
+ EarlyEducation *string `json:"earlyEducation"`
+ MedicalDischargeEducation *string `json:"medicalDischargeEducation"`
+ AdmDischargeEducation *string `json:"admDischargeEducation"`
+ DischargeReason *string `json:"dischargeReason"`
+}
type ResponseDto struct {
ecore.Main
- Patient_Id *uint `json:"patient_id"`
- Patient *ep.Patient `json:"patient,omitempty"`
- RegisteredAt *time.Time `json:"registeredAt"`
- Class_Code ere.EncounterClassCode `json:"class_code"`
- Unit_Id *uint `json:"unit_id"`
- Unit *eu.Unit `json:"unit,omitempty"`
- VisitDate time.Time `json:"visitDate"`
- Assignment_Doctor_Id *uint `json:"assignment_doctor_id"`
- Assignment_Doctor *ed.Doctor `json:"assignment_doctor,omitempty"`
- Responsible_Doctor_Id *uint `json:"responsible_doctor_id"`
- Responsible_Doctor *ed.Doctor `json:"responsible_doctor,omitempty"`
- DischardeMethod_Code ere.DischargeMethodCode `json:"dischardeMethod_code`
- RefSource_Name *string `json:"refSource_name"`
+ Patient_Id *uint `json:"patient_id"`
+ Patient *ep.Patient `json:"patient,omitempty"`
+ RegisteredAt *time.Time `json:"registeredAt"`
+ Class_Code ere.EncounterClassCode `json:"class_code"`
+ Unit_Id *uint `json:"unit_id"`
+ Specialist_Id *uint16 `json:"specialist_id"`
+ Specialist *es.Specialist `json:"specialist,omitempty"`
+ Subspecialist_Id *uint16 `json:"subspecialist_id"`
+ Subspecialist *ess.Subspecialist `json:"subspecialist,omitempty"`
+ Unit *eu.Unit `json:"unit,omitempty"`
+ VisitDate time.Time `json:"visitDate"`
+ PaymentMethod_Code erc.PaymentMethodCode `json:"paymentMethod_code"`
+ InsuranceCompany_Id *uint `json:"insuranceCompany_id"`
+ Member_Number *string `json:"member_number"`
+ Ref_Number *string `json:"ref_number"`
+ Trx_Number *string `json:"trx_number"`
+ Appointment_Doctor_Id *uint `json:"assignment_doctor_id"`
+ Appointment_Doctor *ed.Doctor `json:"assignment_doctor,omitempty"`
+ Responsible_Doctor_Id *uint `json:"responsible_doctor_id"`
+ Responsible_Doctor *ed.Doctor `json:"responsible_doctor,omitempty"`
+ Adm_Employee_Id *uint `json:"adm_employee_id"`
+ Adm_Employee *ee.Employee `json:"adm_employee,omitempty"`
+ DischargeMethod_Code *ere.DischargeMethodCode `json:"dischargeMethod_code"`
+ RefSource_Name *string `json:"refSource_name"`
+ Appointment_Id *uint `json:"appointment_id"`
+ Appointment *ea.Appointment `json:"appointment,omitempty"`
+ EarlyEducation *string `json:"earlyEducation"`
+ MedicalDischargeEducation *string `json:"medicalDischargeEducation"`
+ AdmDischargeEducation *string `json:"admDischargeEducation"`
+ DischargeReason *string `json:"dischargeReason"`
+ Status_Code erc.DataStatusCode `json:"status_code"`
+ VclaimSep *evs.VclaimSep `json:"vclaimSep,omitempty"`
}
func (d Encounter) ToResponse() ResponseDto {
resp := ResponseDto{
- Patient_Id: d.Patient_Id,
- Patient: d.Patient,
- RegisteredAt: d.RegisteredAt,
- Class_Code: d.Class_Code,
- Unit_Id: d.Unit_Id,
- Unit: d.Unit,
- VisitDate: d.VisitDate,
- Assignment_Doctor_Id: d.Assignment_Doctor_Id,
- Assignment_Doctor: d.Assignment_Doctor,
- Responsible_Doctor_Id: d.Responsible_Doctor_Id,
- Responsible_Doctor: d.Responsible_Doctor,
- DischardeMethod_Code: d.DischardeMethod_Code,
- RefSource_Name: d.RefSource_Name,
+ Patient_Id: d.Patient_Id,
+ Patient: d.Patient,
+ RegisteredAt: d.RegisteredAt,
+ Class_Code: d.Class_Code,
+ Unit_Id: d.Unit_Id,
+ Unit: d.Unit,
+ Specialist_Id: d.Specialist_Id,
+ Specialist: d.Specialist,
+ Subspecialist_Id: d.Subspecialist_Id,
+ Subspecialist: d.Subspecialist,
+ VisitDate: d.VisitDate,
+ PaymentMethod_Code: d.PaymentMethod_Code,
+ InsuranceCompany_Id: d.InsuranceCompany_Id,
+ Member_Number: d.Member_Number,
+ Ref_Number: d.Ref_Number,
+ Trx_Number: d.Trx_Number,
+ Appointment_Doctor_Id: d.Appointment_Doctor_Id,
+ Appointment_Doctor: d.Appointment_Doctor,
+ Adm_Employee_Id: d.Adm_Employee_Id,
+ Adm_Employee: d.Adm_Employee,
+ Responsible_Doctor_Id: d.Responsible_Doctor_Id,
+ Responsible_Doctor: d.Responsible_Doctor,
+ DischargeMethod_Code: d.DischargeMethod_Code,
+ RefSource_Name: d.RefSource_Name,
+ Appointment_Id: d.Appointment_Id,
+ Appointment: d.Appointment,
+ EarlyEducation: d.EarlyEducation,
+ MedicalDischargeEducation: d.MedicalDischargeEducation,
+ AdmDischargeEducation: d.AdmDischargeEducation,
+ DischargeReason: d.DischargeReason,
+ Status_Code: d.Status_Code,
+ VclaimSep: d.VclaimSep,
}
resp.Main = d.Main
return resp
diff --git a/internal/domain/main-entities/encounter/entity.go b/internal/domain/main-entities/encounter/entity.go
index 258c6354..528f28ae 100644
--- a/internal/domain/main-entities/encounter/entity.go
+++ b/internal/domain/main-entities/encounter/entity.go
@@ -2,26 +2,58 @@ package encounter
import (
ecore "simrs-vx/internal/domain/base-entities/core"
+ evs "simrs-vx/internal/domain/bpjs-entities/vclaim-sep"
+ ea "simrs-vx/internal/domain/main-entities/appointment"
ed "simrs-vx/internal/domain/main-entities/doctor"
+ ee "simrs-vx/internal/domain/main-entities/employee"
+ ei "simrs-vx/internal/domain/main-entities/insurance-company"
ep "simrs-vx/internal/domain/main-entities/patient"
+ es "simrs-vx/internal/domain/main-entities/specialist"
+ ess "simrs-vx/internal/domain/main-entities/subspecialist"
eu "simrs-vx/internal/domain/main-entities/unit"
+
+ erc "simrs-vx/internal/domain/references/common"
ere "simrs-vx/internal/domain/references/encounter"
"time"
)
type Encounter struct {
- ecore.Main // adjust this according to the needs
- Patient_Id *uint `json:"patient_id"`
- Patient *ep.Patient `json:"patient,omitempty" gorm:"foreignKey:Patient_Id;references:Id"`
- RegisteredAt *time.Time `json:"registeredAt"`
- Class_Code ere.EncounterClassCode `json:"class_code" gorm:"not null;size:10"`
- Unit_Id *uint `json:"unit_id"`
- Unit *eu.Unit `json:"unit,omitempty" gorm:"foreignKey:Unit_Id;references:Id"`
- VisitDate time.Time `json:"visitDate"`
- Assignment_Doctor_Id *uint `json:"assignment_doctor_id"`
- Assignment_Doctor *ed.Doctor `json:"assignment_doctor,omitempty" gorm:"foreignKey:Assignment_Doctor_Id;references:Id"`
- Responsible_Doctor_Id *uint `json:"responsible_doctor_id"`
- Responsible_Doctor *ed.Doctor `json:"responsible_doctor,omitempty" gorm:"foreignKey:Responsible_Doctor_Id;references:Id"`
- DischardeMethod_Code ere.DischargeMethodCode `json:"dischardeMethod_code" gorm:"size:10"`
- RefSource_Name *string `json:"refSource_name" gorm:"size:100"`
+ ecore.Main // adjust this according to the needs
+ Patient_Id *uint `json:"patient_id"`
+ Patient *ep.Patient `json:"patient,omitempty" gorm:"foreignKey:Patient_Id;references:Id"`
+ RegisteredAt *time.Time `json:"registeredAt"`
+ Class_Code ere.EncounterClassCode `json:"class_code" gorm:"not null;size:10"`
+ Unit_Id *uint `json:"unit_id"`
+ Unit *eu.Unit `json:"unit,omitempty" gorm:"foreignKey:Unit_Id;references:Id"`
+ Specialist_Id *uint16 `json:"specialist_id"`
+ Specialist *es.Specialist `json:"specialist,omitempty" gorm:"foreignKey:Specialist_Id;references:Id"`
+ Subspecialist_Id *uint16 `json:"subspecialist_id"`
+ Subspecialist *ess.Subspecialist `json:"subspecialist,omitempty" gorm:"foreignKey:Subspecialist_Id;references:Id"`
+ VisitDate time.Time `json:"visitDate"`
+ PaymentMethod_Code erc.PaymentMethodCode `json:"paymentMethod_code" gorm:"size:10"`
+ InsuranceCompany_Id *uint `json:"insuranceCompany_id"`
+ InsuranceCompany *ei.InsuranceCompany `json:"insuranceCompany,omitempty" gorm:"foreignKey:InsuranceCompany_Id;references:Id"`
+ Member_Number *string `json:"memberNumber" gorm:"unique;size:20"`
+ Ref_Number *string `json:"refNumber" gorm:"unique;size:20"`
+ Trx_Number *string `json:"trxNumber" gorm:"unique;size:20"`
+ Appointment_Doctor_Id *uint `json:"appointment_doctor_id"`
+ Appointment_Doctor *ed.Doctor `json:"appointment_doctor,omitempty" gorm:"foreignKey:Appointment_Doctor_Id;references:Id"`
+ Adm_Employee_Id *uint `json:"adm_employee_id"`
+ Adm_Employee *ee.Employee `json:"adm_employee,omitempty" gorm:"foreignKey:Adm_Employee_Id;references:Id"`
+ Responsible_Doctor_Id *uint `json:"responsible_doctor_id"`
+ Responsible_Doctor *ed.Doctor `json:"responsible_doctor,omitempty" gorm:"foreignKey:Responsible_Doctor_Id;references:Id"`
+ DischargeMethod_Code *ere.DischargeMethodCode `json:"dischargeMethod_code" gorm:"size:16"`
+ RefSource_Name *string `json:"refSource_name" gorm:"size:100"`
+ Appointment_Id *uint `json:"appointment_id"`
+ Appointment *ea.Appointment `json:"appointment,omitempty" gorm:"foreignKey:Appointment_Id;references:Id"`
+ EarlyEducation *string `json:"earlyEducation"`
+ MedicalDischargeEducation *string `json:"medicalDischargeEducation"`
+ AdmDischargeEducation *string `json:"admDischargeEducation"`
+ DischargeReason *string `json:"dischargeReason"`
+ Status_Code erc.DataStatusCode `json:"status_code" gorm:"size:10"`
+ VclaimSep *evs.VclaimSep `json:"vclaimSep,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"`
+}
+
+func (d Encounter) IsDone() bool {
+ return d.Status_Code == erc.DSCDone
}
diff --git a/internal/domain/main-entities/ethnic/dto.go b/internal/domain/main-entities/ethnic/dto.go
index 8b14fde1..a8277e27 100644
--- a/internal/domain/main-entities/ethnic/dto.go
+++ b/internal/domain/main-entities/ethnic/dto.go
@@ -10,12 +10,16 @@ type CreateDto struct {
}
type ReadListDto struct {
- Code string `json:"code"`
- Name string `json:"name"`
+ FilterDto
+ Includes string `json:"includes"`
+ Sort string `json:"sort"`
+ Pagination ecore.Pagination
+}
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+type FilterDto struct {
+ Code string `json:"code"`
+ Name string `json:"name"`
+ Search string `json:"search" gormhelper:"searchColumns=Code,Name"`
}
type ReadDetailDto struct {
diff --git a/internal/domain/main-entities/infra/dto.go b/internal/domain/main-entities/infra/dto.go
index 07dae72a..de566fad 100644
--- a/internal/domain/main-entities/infra/dto.go
+++ b/internal/domain/main-entities/infra/dto.go
@@ -3,34 +3,38 @@ package infra
import (
ecore "simrs-vx/internal/domain/base-entities/core"
ei "simrs-vx/internal/domain/main-entities/item"
+ erb "simrs-vx/internal/domain/main-entities/room/base"
ero "simrs-vx/internal/domain/references/organization"
)
type CreateDto struct {
- Code string `json:"code" validate:"maxLength=10"`
- Name string `json:"name" validate:"maxLength=50"`
- InfraGroup_Code ero.InfraGroupCode `json:"infraGroup_code" validate:"maxLength=10"`
- Parent_Id *uint16 `json:"parent_id"`
- Item_Id *uint `json:"item_id"`
+ Code string `json:"code" validate:"maxLength=10"`
+ Name string `json:"name" validate:"maxLength=50"`
+ InfraGroup_Code ero.InfraGroupCode `json:"infraGroup_code" validate:"maxLength=15"`
+ Parent_Id *uint16 `json:"parent_id"`
+ Item_Id *uint `json:"item_id"`
+ Unit_Id *uint16 `json:"unit_id"`
+ Specialist_Id *uint16 `json:"specialist_id"`
+ Subspecialist_Id *uint16 `json:"subspecialist_id"`
+ Infra_Id *uint16 `json:"-"` // for room
}
type ReadListDto struct {
FilterDto
- Includes string `json:"includes"`
- Preloads []string `json:"-"`
+ Includes string `json:"includes"`
+ Sort string `json:"sort"`
+ Pagination ecore.Pagination
+ OnlyHaveChildren bool `json:"only-have-children"`
}
type FilterDto struct {
Code string `json:"code"`
Name string `json:"name"`
- InfraGroup_Code ero.InfraGroupCode `json:"infraGroup_code"`
- Parent_Id *uint16 `json:"parent_id"`
- Item_Id *uint `json:"item_id"`
-
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+ InfraGroup_Code ero.InfraGroupCode `json:"infraGroup-code"`
+ Parent_Id *uint16 `json:"parent-id"`
+ Item_Id *uint `json:"item-id"`
+ Search string `json:"search" gormhelper:"searchColumns=Code,Name"`
}
type ReadDetailDto struct {
@@ -60,8 +64,11 @@ type ResponseDto struct {
Name string `json:"name"`
InfraGroup_Code ero.InfraGroupCode `json:"infraGroup_code"`
Parent_Id *uint16 `json:"parent_id"`
+ Parent *Infra `json:"parent,omitempty"`
+ Childrens []Infra `json:"childrens,omitempty"`
Item_Id *uint `json:"item_id"`
Item *ei.Item `json:"item,omitempty"`
+ Rooms []erb.Basic `json:"rooms,omitempty"`
}
func (d Infra) ToResponse() ResponseDto {
@@ -70,8 +77,11 @@ func (d Infra) ToResponse() ResponseDto {
Name: d.Name,
InfraGroup_Code: d.InfraGroup_Code,
Parent_Id: d.Parent_Id,
+ Parent: d.Parent,
+ Childrens: d.Childrens,
Item_Id: d.Item_Id,
Item: d.Item,
+ Rooms: d.Rooms,
}
resp.SmallMain = d.SmallMain
return resp
diff --git a/internal/domain/main-entities/infra/entity.go b/internal/domain/main-entities/infra/entity.go
index a7d2e6d4..3d8c6f99 100644
--- a/internal/domain/main-entities/infra/entity.go
+++ b/internal/domain/main-entities/infra/entity.go
@@ -3,6 +3,7 @@ package infra
import (
ecore "simrs-vx/internal/domain/base-entities/core"
ei "simrs-vx/internal/domain/main-entities/item"
+ erb "simrs-vx/internal/domain/main-entities/room/base"
ero "simrs-vx/internal/domain/references/organization"
)
@@ -11,8 +12,11 @@ type Infra struct {
ecore.SmallMain // adjust this according to the needs
Code string `json:"code" gorm:"unique;size:10"`
Name string `json:"name" gorm:"size:50"`
- InfraGroup_Code ero.InfraGroupCode `json:"infraGroup_code" gorm:"size:10"`
+ InfraGroup_Code ero.InfraGroupCode `json:"infraGroup_code" gorm:"size:15"`
Parent_Id *uint16 `json:"parent_id"`
+ Parent *Infra `json:"parent" gorm:"foreignKey:Parent_Id;references:Id"`
+ Childrens []Infra `json:"childrens" gorm:"foreignKey:Parent_Id"` // may need references to self
Item_Id *uint `json:"item_id"`
Item *ei.Item `json:"item,omitempty" gorm:"foreignKey:Item_Id;references:Id"`
+ Rooms []erb.Basic `json:"rooms" gorm:"foreignKey:Infra_Id"`
}
diff --git a/internal/domain/main-entities/inpatient/dto.go b/internal/domain/main-entities/inpatient/dto.go
new file mode 100644
index 00000000..d92232dd
--- /dev/null
+++ b/internal/domain/main-entities/inpatient/dto.go
@@ -0,0 +1,75 @@
+package inpatient
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ee "simrs-vx/internal/domain/main-entities/encounter"
+ ei "simrs-vx/internal/domain/main-entities/infra"
+
+ ere "simrs-vx/internal/domain/references/encounter"
+)
+
+type CreateDto struct {
+ Encounter_Id *uint `json:"encounter_id"`
+ Class_Code ere.InpatientClassCode `json:"class_code" validate:"maxLength=10"`
+ Infra_Id *uint16 `json:"infra_id"`
+}
+
+type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ Encounter_Id *uint `json:"encounter-id"`
+ Class_Code ere.InpatientClassCode `json:"class-code"`
+ Infra_Id *uint16 `json:"infra-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"`
+ Encounter *ee.Encounter `json:"encounter,omitempty"`
+ Class_Code ere.InpatientClassCode `json:"class_code"`
+ Infra_Id *uint16 `json:"infra_id"`
+ Infra *ei.Infra `json:"infra,omitempty"`
+}
+
+func (d Inpatient) ToResponse() ResponseDto {
+ resp := ResponseDto{
+ Encounter_Id: d.Encounter_Id,
+ Encounter: d.Encounter,
+ Class_Code: d.Class_Code,
+ Infra_Id: d.Infra_Id,
+ Infra: d.Infra,
+ }
+ resp.Main = d.Main
+ return resp
+}
+
+func ToResponseList(data []Inpatient) []ResponseDto {
+ resp := make([]ResponseDto, len(data))
+ for i, u := range data {
+ resp[i] = u.ToResponse()
+ }
+ return resp
+}
diff --git a/internal/domain/main-entities/inpatient/entity.go b/internal/domain/main-entities/inpatient/entity.go
new file mode 100644
index 00000000..328f5d12
--- /dev/null
+++ b/internal/domain/main-entities/inpatient/entity.go
@@ -0,0 +1,18 @@
+package inpatient
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ee "simrs-vx/internal/domain/main-entities/encounter"
+ ei "simrs-vx/internal/domain/main-entities/infra"
+
+ ere "simrs-vx/internal/domain/references/encounter"
+)
+
+type Inpatient struct {
+ ecore.Main // adjust this according to the needs
+ Encounter_Id *uint `json:"encounter_id"`
+ Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"`
+ Class_Code ere.InpatientClassCode `json:"class_code" gorm:"size:10"`
+ Infra_Id *uint16 `json:"infra_id"`
+ Infra *ei.Infra `json:"infra,omitempty" gorm:"foreignKey:Infra_Id;references:Id"`
+}
diff --git a/internal/domain/main-entities/installation/dto.go b/internal/domain/main-entities/installation/dto.go
index 15377317..55981981 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"
+
ere "simrs-vx/internal/domain/references/encounter"
)
@@ -12,13 +13,17 @@ type CreateDto struct {
}
type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Sort string `json:"sort"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
Code string `json:"code"`
Name string `json:"name"`
- EncounterClass_Code ere.EncounterClassCode `json:"encounterClass_code"`
-
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+ EncounterClass_Code ere.EncounterClassCode `json:"encounterClass-code"`
+ Search string `json:"search" gormhelper:"searchColumns=Code,Name"`
}
type ReadDetailDto struct {
diff --git a/internal/domain/main-entities/insurance-company/dto.go b/internal/domain/main-entities/insurance-company/dto.go
index 4ca58076..e4104bf7 100644
--- a/internal/domain/main-entities/insurance-company/dto.go
+++ b/internal/domain/main-entities/insurance-company/dto.go
@@ -15,20 +15,18 @@ type CreateDto struct {
type ReadListDto struct {
FilterDto
- Includes string `json:"includes"`
- Preloads []string `json:"-"`
+ Includes string `json:"includes"`
+ Sort string `json:"sort"`
+ Pagination ecore.Pagination
}
type FilterDto struct {
Code string `json:"code"`
Name string `json:"name"`
- Regency_Code *string `json:"regency_code"`
+ Regency_Code *string `json:"regency-code"`
Address string `json:"address"`
PhoneNumber string `json:"phoneNumber"`
-
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+ Search string `json:"search" gormhelper:"searchColumns=Code,Name"`
}
type ReadDetailDto struct {
diff --git a/internal/domain/main-entities/intern/dto.go b/internal/domain/main-entities/intern/dto.go
new file mode 100644
index 00000000..b8c60aee
--- /dev/null
+++ b/internal/domain/main-entities/intern/dto.go
@@ -0,0 +1,81 @@
+package intern
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ep "simrs-vx/internal/domain/main-entities/person"
+ es "simrs-vx/internal/domain/main-entities/specialist"
+ ess "simrs-vx/internal/domain/main-entities/subspecialist"
+ eu "simrs-vx/internal/domain/main-entities/user"
+)
+
+type CreateDto struct {
+ Person_Id *uint `json:"person_id"`
+ Specialist_Id *uint16 `json:"specialist_id"`
+ Subspecialist_Id *uint16 `json:"subspecialist_id"`
+ User_Id *uint `json:"user_id"`
+}
+
+type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Preloads []string `json:"-"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ Person_Id *uint `json:"person_id"`
+ Specialist_Id *uint16 `json:"specialist_id"`
+ Subspecialist_Id *uint16 `json:"subspecialist_id"`
+ User_Id *uint `json:"user_id"`
+}
+
+type ReadDetailDto struct {
+ Id uint16 `json:"id"`
+ User_Id *uint `json:"user_id"`
+}
+
+type UpdateDto struct {
+ Id uint `json:"id"`
+ CreateDto
+}
+
+type DeleteDto struct {
+ Id uint `json:"id"`
+}
+
+type MetaDto struct {
+ PageNumber int `json:"page_number"`
+ PageSize int `json:"page_size"`
+ Count int `json:"count"`
+}
+
+type ResponseDto struct {
+ ecore.Main
+ Person_Id *uint `json:"person_id"`
+ Person *ep.Person `json:"person,omitempty"`
+ Specialist_Id *uint16 `json:"specialist_id"`
+ Specialist *es.Specialist `json:"specialist,omitempty"`
+ Subspecialist_Id *uint16 `json:"subspecialist_id"`
+ Subspecialist *ess.Subspecialist `json:"subspecialist,omitempty"`
+ User_Id *uint `json:"user_id"`
+ User *eu.User `json:"user,omitempty"`
+}
+
+func (d Intern) ToResponse() ResponseDto {
+ resp := ResponseDto{
+ Person_Id: d.Person_Id,
+ Person: d.Person,
+ User_Id: d.User_Id,
+ User: d.User,
+ }
+ resp.Main = d.Main
+ return resp
+}
+
+func ToResponseList(data []Intern) []ResponseDto {
+ resp := make([]ResponseDto, len(data))
+ for i, u := range data {
+ resp[i] = u.ToResponse()
+ }
+ return resp
+}
diff --git a/internal/domain/main-entities/intern/entity.go b/internal/domain/main-entities/intern/entity.go
new file mode 100644
index 00000000..5ac2df49
--- /dev/null
+++ b/internal/domain/main-entities/intern/entity.go
@@ -0,0 +1,17 @@
+package intern
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ep "simrs-vx/internal/domain/main-entities/person"
+ eu "simrs-vx/internal/domain/main-entities/user"
+ erg "simrs-vx/internal/domain/references/organization"
+)
+
+type Intern struct {
+ ecore.Main // adjust this according to the needs
+ Person_Id *uint `json:"person_id"`
+ Person *ep.Person `json:"person,omitempty" gorm:"foreignKey:Person_Id"`
+ Position_Code *erg.InternPosisitionCode `json:"position_code" gorm:"size:20"`
+ User_Id *uint `json:"user_id"`
+ User *eu.User `json:"user,omitempty" gorm:"foreignKey:User_Id"`
+}
diff --git a/internal/domain/main-entities/internal-reference/dto.go b/internal/domain/main-entities/internal-reference/dto.go
new file mode 100644
index 00000000..6c71e6f1
--- /dev/null
+++ b/internal/domain/main-entities/internal-reference/dto.go
@@ -0,0 +1,77 @@
+package internal_reference
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ed "simrs-vx/internal/domain/main-entities/doctor"
+ ee "simrs-vx/internal/domain/main-entities/encounter"
+ eu "simrs-vx/internal/domain/main-entities/unit"
+)
+
+type CreateDto struct {
+ Encounter_Id *uint `json:"encounter_id"`
+ Unit_Id *uint16 `json:"unit_id"`
+ Doctor_Id *uint `json:"doctor_Id"`
+}
+
+type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ Encounter_Id *uint `json:"encounter-id"`
+ Unit_Id *uint `json:"unit-id"`
+ Doctor_Id *uint `json:"doctor-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"`
+ Encounter *ee.Encounter `json:"encounter,omitempty"`
+ Unit_Id *uint16 `json:"unit_id"`
+ Unit *eu.Unit `json:"unit,omitempty"`
+ Doctor_Id *uint `json:"doctor_id"`
+ Doctor *ed.Doctor `json:"doctor,omitempty"`
+}
+
+func (d InternalReference) ToResponse() ResponseDto {
+ resp := ResponseDto{
+ Encounter_Id: d.Encounter_Id,
+ Encounter: d.Encounter,
+ Unit_Id: d.Unit_Id,
+ Unit: d.Unit,
+ Doctor_Id: d.Doctor_Id,
+ Doctor: d.Doctor,
+ }
+ resp.Main = d.Main
+ return resp
+}
+
+func ToResponseList(data []InternalReference) []ResponseDto {
+ resp := make([]ResponseDto, len(data))
+ for i, u := range data {
+ resp[i] = u.ToResponse()
+ }
+ return resp
+}
diff --git a/internal/domain/main-entities/internal-reference/entity.go b/internal/domain/main-entities/internal-reference/entity.go
new file mode 100644
index 00000000..56dcdc19
--- /dev/null
+++ b/internal/domain/main-entities/internal-reference/entity.go
@@ -0,0 +1,18 @@
+package internal_reference
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ed "simrs-vx/internal/domain/main-entities/doctor"
+ ee "simrs-vx/internal/domain/main-entities/encounter"
+ eu "simrs-vx/internal/domain/main-entities/unit"
+)
+
+type InternalReference struct {
+ ecore.Main
+ Encounter_Id *uint `json:"encounter_id"`
+ Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"`
+ Unit_Id *uint16 `json:"unit_id"`
+ Unit *eu.Unit `json:"unit,omitempty" gorm:"foreignKey:Unit_Id;references:Id"`
+ Doctor_Id *uint `json:"doctor_id"`
+ Doctor *ed.Doctor `json:"doctor,omitempty" gorm:"foreignKey:Doctor_Id;references:Id"`
+}
diff --git a/internal/domain/main-entities/item-price/dto.go b/internal/domain/main-entities/item-price/dto.go
index b4740788..5adde2e1 100644
--- a/internal/domain/main-entities/item-price/dto.go
+++ b/internal/domain/main-entities/item-price/dto.go
@@ -14,18 +14,14 @@ type CreateDto struct {
type ReadListDto struct {
FilterDto
- Includes string `json:"includes"`
- Preloads []string `json:"-"`
+ Includes string `json:"includes"`
+ Pagination ecore.Pagination
}
type FilterDto struct {
- Item_Id *uint `json:"item_id"`
+ Item_Id *uint `json:"item-id"`
Price float64 `json:"price"`
- InsuranceCompany_Code *string `json:"insuranceCompany_code"`
-
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+ InsuranceCompany_Code *string `json:"insuranceCompany-code"`
}
type ReadDetailDto struct {
Id uint16 `json:"id"`
diff --git a/internal/domain/main-entities/item/dto.go b/internal/domain/main-entities/item/dto.go
index 6c364828..22be4c1a 100644
--- a/internal/domain/main-entities/item/dto.go
+++ b/internal/domain/main-entities/item/dto.go
@@ -17,21 +17,19 @@ type CreateDto struct {
type ReadListDto struct {
FilterDto
- Includes string `json:"includes"`
- Preloads []string `json:"-"`
+ Includes string `json:"includes"`
+ Sort string `json:"sort"`
+ Pagination ecore.Pagination
}
type FilterDto struct {
Code string `json:"code"`
Name string `json:"name"`
- ItemGroup_Code ero.ItemGroupCode `json:"itemGroup_code"`
- Uom_Code *string `json:"uom_code"`
- Infra_Id *uint16 `json:"infra_id"`
+ ItemGroup_Code ero.ItemGroupCode `json:"itemGroup-code"`
+ Uom_Code *string `json:"uom-code"`
+ Infra_Id *uint16 `json:"infra-id"`
Stock *int `json:"stock"`
-
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+ Search string `json:"search" gormhelper:"searchColumns=Code,Name"`
}
type ReadDetailDto struct {
diff --git a/internal/domain/main-entities/item/entity.go b/internal/domain/main-entities/item/entity.go
index 9ac471ad..e0ff4e21 100644
--- a/internal/domain/main-entities/item/entity.go
+++ b/internal/domain/main-entities/item/entity.go
@@ -11,7 +11,7 @@ type Item struct {
ecore.Main // adjust this according to the needs
Code string `json:"code" gorm:"unique;size:50"`
Name string `json:"name" gorm:"size:100"`
- ItemGroup_Code ero.ItemGroupCode `json:"itemGroup_code" gorm:"size:10"`
+ ItemGroup_Code ero.ItemGroupCode `json:"itemGroup_code" gorm:"size:15"`
Uom_Code *string `json:"uom_code" gorm:"size:10"`
Uom *eu.Uom `json:"uom,omitempty" gorm:"foreignKey:Uom_Code;references:Code"`
Infra_Id *uint16 `json:"infra_id"`
diff --git a/internal/domain/main-entities/laborant/dto.go b/internal/domain/main-entities/laborant/dto.go
new file mode 100644
index 00000000..4397d2f1
--- /dev/null
+++ b/internal/domain/main-entities/laborant/dto.go
@@ -0,0 +1,68 @@
+package laborant
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ee "simrs-vx/internal/domain/main-entities/employee"
+)
+
+type CreateDto struct {
+ Employee_Id *uint `json:"employee_id"`
+ IHS_Number *string `json:"ihs_number" validate:"maxLength=20"`
+}
+
+type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ Employee_Id *uint `json:"employee-id"`
+ IHS_Number *string `json:"ihs-number"`
+}
+
+type ReadDetailDto struct {
+ Id uint16 `json:"id"`
+ Employee_Id *uint `json:"employee_id"`
+ IHS_Number *string `json:"ihs_number"`
+}
+
+type UpdateDto struct {
+ Id uint `json:"id"`
+ CreateDto
+}
+
+type DeleteDto struct {
+ Id uint `json:"id"`
+}
+
+type MetaDto struct {
+ PageNumber int `json:"page_number"`
+ PageSize int `json:"page_size"`
+ Count int `json:"count"`
+}
+
+type ResponseDto struct {
+ ecore.Main
+ Employee_Id *uint `json:"employee_id"`
+ Employee *ee.Employee `json:"employee,omitempty"`
+ IHS_Number *string `json:"ihs_number"`
+}
+
+func (d Laborant) ToResponse() ResponseDto {
+ resp := ResponseDto{
+ Employee_Id: d.Employee_Id,
+ Employee: d.Employee,
+ IHS_Number: d.IHS_Number,
+ }
+ resp.Main = d.Main
+ return resp
+}
+
+func ToResponseList(data []Laborant) []ResponseDto {
+ resp := make([]ResponseDto, len(data))
+ for i, u := range data {
+ resp[i] = u.ToResponse()
+ }
+ return resp
+}
diff --git a/internal/domain/main-entities/laborant/entity.go b/internal/domain/main-entities/laborant/entity.go
new file mode 100644
index 00000000..eeb63bef
--- /dev/null
+++ b/internal/domain/main-entities/laborant/entity.go
@@ -0,0 +1,13 @@
+package laborant
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ee "simrs-vx/internal/domain/main-entities/employee"
+)
+
+type Laborant struct {
+ ecore.Main // adjust this according to the needs
+ Employee_Id *uint `json:"employee_id"`
+ Employee *ee.Employee `json:"employee,omitempty" gorm:"foreignKey:Employee_Id;references:Id"`
+ IHS_Number *string `json:"ihs_number" gorm:"unique;size:20"`
+}
diff --git a/internal/domain/main-entities/language/dto.go b/internal/domain/main-entities/language/dto.go
index 563b5205..069fbf50 100644
--- a/internal/domain/main-entities/language/dto.go
+++ b/internal/domain/main-entities/language/dto.go
@@ -10,12 +10,16 @@ type CreateDto struct {
}
type ReadListDto struct {
- Code string `json:"code"`
- Name string `json:"name"`
+ FilterDto
+ Includes string `json:"includes"`
+ Sort string `json:"sort"`
+ Pagination ecore.Pagination
+}
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+type FilterDto struct {
+ Code string `json:"code"`
+ Name string `json:"name"`
+ Search string `json:"search" gormhelper:"searchColumns=Code,Name"`
}
type ReadDetailDto struct {
diff --git a/internal/domain/main-entities/material-order-item/dto.go b/internal/domain/main-entities/material-order-item/dto.go
new file mode 100644
index 00000000..b76792bf
--- /dev/null
+++ b/internal/domain/main-entities/material-order-item/dto.go
@@ -0,0 +1,72 @@
+package materialorderitem
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ em "simrs-vx/internal/domain/main-entities/material"
+ emo "simrs-vx/internal/domain/main-entities/material-order"
+)
+
+type CreateDto struct {
+ MaterialOrder_Id *uint `json:"materialOrder_id"`
+ Material_Id *uint `json:"material_id"`
+ Count *uint16 `json:"count"`
+}
+
+type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ MaterialOrder_Id *uint `json:"materialOrder-id"`
+ Material_Id *uint `json:"material-id"`
+ Count *uint16 `json:"count"`
+}
+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
+ MaterialOrder_Id *uint `json:"materialOrder_id"`
+ MaterialOrder *emo.MaterialOrder `json:"materialOrder,omitempty"`
+ Material_Id *uint `json:"material_id"`
+ Material *em.Material `json:"material,omitempty"`
+ Count *uint16 `json:"count"`
+}
+
+func (d MaterialOrderItem) ToResponse() ResponseDto {
+ resp := ResponseDto{
+ MaterialOrder_Id: d.MaterialOrder_Id,
+ MaterialOrder: d.MaterialOrder,
+ Material_Id: d.Material_Id,
+ Material: d.Material,
+ Count: d.Count,
+ }
+ resp.Main = d.Main
+ return resp
+}
+
+func ToResponseList(data []MaterialOrderItem) []ResponseDto {
+ resp := make([]ResponseDto, len(data))
+ for i, u := range data {
+ resp[i] = u.ToResponse()
+ }
+ return resp
+}
diff --git a/internal/domain/main-entities/material-order-item/entity.go b/internal/domain/main-entities/material-order-item/entity.go
new file mode 100644
index 00000000..432a36b9
--- /dev/null
+++ b/internal/domain/main-entities/material-order-item/entity.go
@@ -0,0 +1,16 @@
+package materialorderitem
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ em "simrs-vx/internal/domain/main-entities/material"
+ emo "simrs-vx/internal/domain/main-entities/material-order"
+)
+
+type MaterialOrderItem struct {
+ ecore.Main // adjust this according to the needs
+ MaterialOrder_Id *uint `json:"materialOrder_id"`
+ MaterialOrder *emo.MaterialOrder `json:"materialOrder,omitempty" gorm:"foreignKey:MaterialOrder_Id;references:Id"`
+ Material_Id *uint `json:"material_id"`
+ Material *em.Material `json:"material,omitempty" gorm:"foreignKey:Material_Id;references:Id"`
+ Count *uint16 `json:"count"`
+}
diff --git a/internal/domain/main-entities/material-order/dto.go b/internal/domain/main-entities/material-order/dto.go
new file mode 100644
index 00000000..5485d2dd
--- /dev/null
+++ b/internal/domain/main-entities/material-order/dto.go
@@ -0,0 +1,77 @@
+package materialorder
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ed "simrs-vx/internal/domain/main-entities/doctor"
+ ee "simrs-vx/internal/domain/main-entities/encounter"
+
+ erc "simrs-vx/internal/domain/references/common"
+
+ pa "simrs-vx/pkg/auth-helper"
+)
+
+type CreateDto struct {
+ Encounter_Id *uint `json:"encounter_id"`
+ Status_Code erc.DataStatusCode `json:"status_code"`
+ Doctor_Id *uint `json:"doctor_id"`
+
+ pa.AuthInfo
+}
+
+type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ Encounter_Id *uint `json:"encounter-id"`
+ Status_Code erc.DataStatusCode `json:"status_code"`
+}
+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"`
+ Encounter *ee.Encounter `json:"encounter,omitempty"`
+ Doctor_Id *uint `json:"doctor_id"`
+ Doctor *ed.Doctor `json:"doctor,omitempty"`
+ Status_Code erc.DataStatusCode `json:"status_code"`
+}
+
+func (d MaterialOrder) ToResponse() ResponseDto {
+ resp := ResponseDto{
+ Encounter_Id: d.Encounter_Id,
+ Encounter: d.Encounter,
+ Doctor_Id: d.Doctor_Id,
+ Doctor: d.Doctor,
+ Status_Code: d.Status_Code,
+ }
+ resp.Main = d.Main
+ return resp
+}
+
+func ToResponseList(data []MaterialOrder) []ResponseDto {
+ resp := make([]ResponseDto, len(data))
+ for i, u := range data {
+ resp[i] = u.ToResponse()
+ }
+ return resp
+}
diff --git a/internal/domain/main-entities/material-order/entity.go b/internal/domain/main-entities/material-order/entity.go
new file mode 100644
index 00000000..27b5c011
--- /dev/null
+++ b/internal/domain/main-entities/material-order/entity.go
@@ -0,0 +1,26 @@
+package materialorder
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ed "simrs-vx/internal/domain/main-entities/doctor"
+ ee "simrs-vx/internal/domain/main-entities/encounter"
+
+ erc "simrs-vx/internal/domain/references/common"
+)
+
+type MaterialOrder struct {
+ ecore.Main // adjust this according to the needs
+ Encounter_Id *uint `json:"encounter_id"`
+ Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"`
+ Doctor_Id *uint `json:"doctor_id"`
+ Doctor *ed.Doctor `json:"doctor,omitempty" gorm:"foreignKey:Doctor_Id;references:Id"`
+ Status_Code erc.DataStatusCode `json:"status_code"`
+}
+
+func (d MaterialOrder) IsCompleted() bool {
+ return d.Status_Code == erc.DSCDone
+}
+
+func (d MaterialOrder) IsSameDoctor(doctor_id *uint) bool {
+ return d.Doctor_Id == doctor_id
+}
diff --git a/internal/domain/main-entities/material/dto.go b/internal/domain/main-entities/material/dto.go
index 9ae830f9..18a93723 100644
--- a/internal/domain/main-entities/material/dto.go
+++ b/internal/domain/main-entities/material/dto.go
@@ -18,21 +18,19 @@ type CreateDto struct {
type ReadListDto struct {
FilterDto
- Includes string `json:"includes"`
- Preloads []string `json:"-"`
+ Includes string `json:"includes"`
+ Sort string `json:"sort"`
+ Pagination ecore.Pagination
}
type FilterDto struct {
Code string `json:"code"`
Name string `json:"name"`
- Uom_Code string `json:"uom_code"`
- Infra_Id *uint16 `json:"infra_id"`
+ Uom_Code string `json:"uom-code"`
+ Infra_Id *uint16 `json:"infra-id"`
Stock *int `json:"stock"`
- Item_Id *uint `json:"item_id"`
-
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+ Item_Id *uint `json:"item-id"`
+ Search string `json:"search" gormhelper:"searchColumns=Code,Name"`
}
type ReadDetailDto struct {
diff --git a/internal/domain/main-entities/mcu-order-item/dto.go b/internal/domain/main-entities/mcu-order-item/dto.go
new file mode 100644
index 00000000..64e56a85
--- /dev/null
+++ b/internal/domain/main-entities/mcu-order-item/dto.go
@@ -0,0 +1,86 @@
+package mcuorderitem
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ emo "simrs-vx/internal/domain/main-entities/mcu-order"
+ ems "simrs-vx/internal/domain/main-entities/mcu-src"
+ erc "simrs-vx/internal/domain/references/common"
+ "time"
+)
+
+type CreateDto struct {
+ McuOrder_Id *uint `json:"mcuOrder_id"`
+ McuSrc_Id *uint `json:"mcuSrc_id"`
+ Result *string `json:"result"`
+ Status_Code erc.DataStatusCode `json:"status_code"`
+ ExaminationDate *time.Time `json:"examinationDate"`
+}
+
+type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ McuOrder_Id *uint `json:"mcuOrder-id"`
+ McuSrc_Id *uint `json:"mcuSrc-id"`
+ Result *string `json:"result"`
+ Status_Code erc.DataStatusCode `json:"status-code"`
+}
+type ReadDetailDto struct {
+ Id uint `json:"id"`
+}
+
+type UpdateDto struct {
+ Id uint `json:"id"`
+ CreateDto
+}
+
+type DeleteDto struct {
+ Id uint `json:"id"`
+}
+
+type SetScheduleDto struct {
+ Id uint `json:"id"`
+ ExaminationDate *time.Time `json:"examinationDate"`
+}
+
+type MetaDto struct {
+ PageNumber int `json:"page_number"`
+ PageSize int `json:"page_size"`
+ Count int `json:"count"`
+}
+
+type ResponseDto struct {
+ ecore.Main
+ McuOrder_Id *uint `json:"mcuOrder_id"`
+ McuOrder *emo.McuOrder `json:"mcuOrder,omitempty"`
+ McuSrc_Id *uint `json:"mcuSrc_id"`
+ McuSrc *ems.McuSrc `json:"mcuSrc,omitempty"`
+ Result *string `json:"result"`
+ Status_Code erc.DataStatusCode `json:"status_code"`
+ ExaminationDate *time.Time `json:"examinationDate"`
+}
+
+func (d McuOrderItem) ToResponse() ResponseDto {
+ resp := ResponseDto{
+ McuOrder_Id: d.McuOrder_Id,
+ McuOrder: d.McuOrder,
+ McuSrc_Id: d.McuSrc_Id,
+ McuSrc: d.McuSrc,
+ Result: d.Result,
+ Status_Code: d.Status_Code,
+ ExaminationDate: d.ExaminationDate,
+ }
+ resp.Main = d.Main
+ return resp
+}
+
+func ToResponseList(data []McuOrderItem) []ResponseDto {
+ resp := make([]ResponseDto, len(data))
+ for i, u := range data {
+ resp[i] = u.ToResponse()
+ }
+ return resp
+}
diff --git a/internal/domain/main-entities/mcu-order-item/entity.go b/internal/domain/main-entities/mcu-order-item/entity.go
new file mode 100644
index 00000000..6a4441d0
--- /dev/null
+++ b/internal/domain/main-entities/mcu-order-item/entity.go
@@ -0,0 +1,25 @@
+package mcuorderitem
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ emo "simrs-vx/internal/domain/main-entities/mcu-order"
+ ems "simrs-vx/internal/domain/main-entities/mcu-src"
+ "time"
+
+ erc "simrs-vx/internal/domain/references/common"
+)
+
+type McuOrderItem struct {
+ ecore.Main // adjust this according to the needs
+ McuOrder_Id *uint `json:"mcuOrder_id" gorm:"uniqueIndex:idx_order_src"`
+ McuOrder *emo.McuOrder `json:"mcuOrder,omitempty" gorm:"foreignKey:McuOrder_Id;references:Id"`
+ McuSrc_Id *uint `json:"mcuSrc_id" gorm:"uniqueIndex:idx_order_src"`
+ McuSrc *ems.McuSrc `json:"mcuSrc,omitempty" gorm:"foreignKey:McuSrc_Id;references:Id"`
+ ExaminationDate *time.Time `json:"examinationDate"`
+ Result *string `json:"result"`
+ Status_Code erc.DataStatusCode `json:"status_code"`
+}
+
+func (d McuOrderItem) IsCompleted() bool {
+ return d.Status_Code == erc.DSCDone
+}
diff --git a/internal/domain/main-entities/mcu-order-sub-item/dto.go b/internal/domain/main-entities/mcu-order-sub-item/dto.go
new file mode 100644
index 00000000..615b0ee9
--- /dev/null
+++ b/internal/domain/main-entities/mcu-order-sub-item/dto.go
@@ -0,0 +1,77 @@
+package mcuordersubitem
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ emoi "simrs-vx/internal/domain/main-entities/mcu-order-item"
+ emss "simrs-vx/internal/domain/main-entities/mcu-sub-src"
+ erc "simrs-vx/internal/domain/references/common"
+)
+
+type CreateDto struct {
+ McuSubSrc_Id *uint `json:"mcuSubSrc_id"`
+ McuOrderItem_Id *uint `json:"mcuOrderItem_id"`
+ Result *string `json:"result"`
+ Status_Code erc.DataStatusCode `json:"status_code"`
+}
+
+type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ McuOrder_Id *uint `json:"mcuOrder-id"`
+ McuSrc_Id *uint `json:"mcuSrc-id"`
+ Result *string `json:"result"`
+ Status_Code erc.DataStatusCode `json:"status-code"`
+}
+type ReadDetailDto struct {
+ Id uint `json:"id"`
+}
+
+type UpdateDto struct {
+ Id uint `json:"id"`
+ CreateDto
+}
+
+type DeleteDto struct {
+ Id uint `json:"id"`
+}
+
+type MetaDto struct {
+ PageNumber int `json:"page_number"`
+ PageSize int `json:"page_size"`
+ Count int `json:"count"`
+}
+
+type ResponseDto struct {
+ ecore.Main
+ McuSubSrc_Id *uint `json:"mcuSubSrc_id"`
+ McuSubSrc *emss.McuSubSrc `json:"mcuSubSrc,omitempty"`
+ McuOrderItem_Id *uint `json:"mcuOrderItem_id"`
+ McuOrderItem *emoi.McuOrderItem `json:"mcuOrderItem,omitempty"`
+ Result *string `json:"result"`
+ Status_Code erc.DataStatusCode `json:"status_code"`
+}
+
+func (d McuOrderSubItem) ToResponse() ResponseDto {
+ resp := ResponseDto{
+ McuSubSrc_Id: d.McuSubSrc_Id,
+ McuSubSrc: d.McuSubSrc,
+ McuOrderItem_Id: d.McuOrderItem_Id,
+ McuOrderItem: d.McuOrderItem,
+ Result: d.Result,
+ Status_Code: d.Status_Code,
+ }
+ resp.Main = d.Main
+ return resp
+}
+
+func ToResponseList(data []McuOrderSubItem) []ResponseDto {
+ resp := make([]ResponseDto, len(data))
+ for i, u := range data {
+ resp[i] = u.ToResponse()
+ }
+ return resp
+}
diff --git a/internal/domain/main-entities/mcu-order-sub-item/entity.go b/internal/domain/main-entities/mcu-order-sub-item/entity.go
new file mode 100644
index 00000000..83ae4d53
--- /dev/null
+++ b/internal/domain/main-entities/mcu-order-sub-item/entity.go
@@ -0,0 +1,23 @@
+package mcuordersubitem
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ emoi "simrs-vx/internal/domain/main-entities/mcu-order-item"
+ emss "simrs-vx/internal/domain/main-entities/mcu-sub-src"
+
+ erc "simrs-vx/internal/domain/references/common"
+)
+
+type McuOrderSubItem struct {
+ ecore.Main // adjust this according to the needs
+ McuSubSrc_Id *uint `json:"mcuSubSrc_id" gorm:"uniqueIndex:idx_order_sub_src"`
+ McuSubSrc *emss.McuSubSrc `json:"mcuSubSrc,omitempty" gorm:"foreignKey:McuSubSrc_Id;references:Id"`
+ McuOrderItem_Id *uint `json:"mcuOrderItem_id" gorm:"uniqueIndex:idx_order_sub_src"`
+ McuOrderItem *emoi.McuOrderItem `json:"mcuOrderItem,omitempty" gorm:"foreignKey:McuOrderItem_Id;references:Id"`
+ Result *string `json:"result"`
+ Status_Code erc.DataStatusCode `json:"status_code"`
+}
+
+func (d McuOrderSubItem) IsCompleted() bool {
+ return d.Status_Code == erc.DSCDone
+}
diff --git a/internal/domain/main-entities/mcu-order/dto.go b/internal/domain/main-entities/mcu-order/dto.go
new file mode 100644
index 00000000..caf3ef58
--- /dev/null
+++ b/internal/domain/main-entities/mcu-order/dto.go
@@ -0,0 +1,104 @@
+package mcuorder
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ed "simrs-vx/internal/domain/main-entities/doctor"
+ ee "simrs-vx/internal/domain/main-entities/encounter"
+ "time"
+
+ ercl "simrs-vx/internal/domain/references/clinical"
+ erc "simrs-vx/internal/domain/references/common"
+
+ pa "simrs-vx/pkg/auth-helper"
+)
+
+type CreateDto struct {
+ Encounter_Id *uint `json:"encounter_id"`
+ Status_Code erc.DataStatusCode `json:"status_code" gorm:"not null;size:10"`
+ Doctor_Id *uint `json:"doctor_id"`
+ SpecimenPickTime *time.Time `json:"specimenPickTime"`
+ ExaminationDate *time.Time `json:"examinationDate"`
+ Number uint8 `json:"number"`
+ Temperature float64 `json:"temperature"`
+ McuUrgencyLevel_Code ercl.McuUrgencyLevelCode `json:"mcuUrgencyLevel_code""`
+
+ pa.AuthInfo
+}
+
+type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ Encounter_Id *uint `json:"encounter-id"`
+ Status_Code erc.DataStatusCode `json:"status-code" gorm:"not null;size:10"`
+ Doctor_Id *uint `json:"doctor-id"`
+ SpecimenPickTime *time.Time `json:"specimenPickTime"`
+ ExaminationDate *time.Time `json:"examinationDate"`
+ Number uint8 `json:"number"`
+ Temperature float64 `json:"temperature"`
+ McuUrgencyLevel_Code ercl.McuUrgencyLevelCode `json:"mcuUrgencyLevel-code""`
+}
+type ReadDetailDto struct {
+ Id uint `json:"id"`
+}
+
+type UpdateDto struct {
+ Id uint `json:"id"`
+ CreateDto
+}
+
+type DeleteDto struct {
+ Id uint `json:"id"`
+}
+
+type SetScheduleDto struct {
+ Id uint `json:"id"`
+ ExaminationDate *time.Time `json:"examinationDate"`
+}
+
+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"`
+ Encounter *ee.Encounter `json:"encounter,omitempty"`
+ Status_Code erc.DataStatusCode `json:"status_code" gorm:"not null;size:10"`
+ Doctor_Id *uint `json:"doctor_id"`
+ Doctor *ed.Doctor `json:"doctor,omitempty"`
+ SpecimenPickTime *time.Time `json:"specimenPickTime"`
+ ExaminationDate *time.Time `json:"examinationDate"`
+ Number uint8 `json:"number"`
+ Temperature float64 `json:"temperature"`
+ McuUrgencyLevel_Code ercl.McuUrgencyLevelCode `json:"mcuUrgencyLevel_code""`
+}
+
+func (d McuOrder) ToResponse() ResponseDto {
+ resp := ResponseDto{
+ Encounter_Id: d.Encounter_Id,
+ Encounter: d.Encounter,
+ Status_Code: d.Status_Code,
+ Doctor_Id: d.Doctor_Id,
+ Doctor: d.Doctor,
+ SpecimenPickTime: d.SpecimenPickTime,
+ ExaminationDate: d.ExaminationDate,
+ Number: d.Number,
+ Temperature: d.Temperature,
+ McuUrgencyLevel_Code: d.McuUrgencyLevel_Code,
+ }
+ resp.Main = d.Main
+ return resp
+}
+
+func ToResponseList(data []McuOrder) []ResponseDto {
+ resp := make([]ResponseDto, len(data))
+ for i, u := range data {
+ resp[i] = u.ToResponse()
+ }
+ return resp
+}
diff --git a/internal/domain/main-entities/mcu-order/entity.go b/internal/domain/main-entities/mcu-order/entity.go
new file mode 100644
index 00000000..1c72a2ba
--- /dev/null
+++ b/internal/domain/main-entities/mcu-order/entity.go
@@ -0,0 +1,33 @@
+package mcuorder
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ed "simrs-vx/internal/domain/main-entities/doctor"
+ ee "simrs-vx/internal/domain/main-entities/encounter"
+ "time"
+
+ ercl "simrs-vx/internal/domain/references/clinical"
+ erc "simrs-vx/internal/domain/references/common"
+)
+
+type McuOrder struct {
+ ecore.Main // adjust this according to the needs
+ Encounter_Id *uint `json:"encounter_id"`
+ Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"`
+ Status_Code erc.DataStatusCode `json:"status_code" gorm:"not null;size:10"`
+ Doctor_Id *uint `json:"doctor_id"`
+ Doctor *ed.Doctor `json:"doctor,omitempty" gorm:"foreignKey:Doctor_Id;references:Id"`
+ SpecimenPickTime *time.Time `json:"specimenPickTime"`
+ ExaminationDate *time.Time `json:"examinationDate"`
+ Number uint8 `json:"number"`
+ Temperature float64 `json:"temperature"`
+ McuUrgencyLevel_Code ercl.McuUrgencyLevelCode `json:"mcuUrgencyLevel_code" gorm:"not null;size:15"`
+}
+
+func (d McuOrder) IsCompleted() bool {
+ return d.Status_Code == erc.DSCDone
+}
+
+func (d McuOrder) IsSameDoctor(doctor_id *uint) bool {
+ return d.Doctor_Id == doctor_id
+}
diff --git a/internal/domain/main-entities/mcu-src-category/dto.go b/internal/domain/main-entities/mcu-src-category/dto.go
index 03e7cf79..278c5e5c 100644
--- a/internal/domain/main-entities/mcu-src-category/dto.go
+++ b/internal/domain/main-entities/mcu-src-category/dto.go
@@ -2,6 +2,7 @@ package division
import (
ecore "simrs-vx/internal/domain/base-entities/core"
+
ere "simrs-vx/internal/domain/references/encounter"
)
@@ -12,13 +13,17 @@ type CreateDto struct {
}
type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Sort string `json:"sort"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
Code string `json:"code"`
Name string `json:"name"`
- Scope_Code *ere.CheckupScopeCode `json:"scope_code"`
-
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+ Scope_Code *ere.CheckupScopeCode `json:"scope-code"`
+ Search string `json:"search" gormhelper:"searchColumns=Code,Name"`
}
type ReadDetailDto struct {
diff --git a/internal/domain/main-entities/mcu-src/dto.go b/internal/domain/main-entities/mcu-src/dto.go
index 26d76102..96586057 100644
--- a/internal/domain/main-entities/mcu-src/dto.go
+++ b/internal/domain/main-entities/mcu-src/dto.go
@@ -2,28 +2,28 @@ package mcusrc
import (
ecore "simrs-vx/internal/domain/base-entities/core"
+ ei "simrs-vx/internal/domain/main-entities/item"
)
type CreateDto struct {
- Code string `json:"code" validate:"maxLength=20"`
- Name string `json:"name" validate:"maxLength=50"`
- CheckupCategory_Code *string `json:"checkupCategory_code" validate:"maxLength=20"`
+ Code string `json:"code" validate:"maxLength=20"`
+ Name string `json:"name" validate:"maxLength=50"`
+ McuSrcCategory_Code *string `json:"mcuSrcCategory_code" validate:"maxLength=20"`
+ Item_Id *uint `json:"item_id"`
}
type ReadListDto struct {
FilterDto
- Includes string `json:"includes"`
- Preloads []string `json:"-"`
+ Includes string `json:"includes"`
+ Sort string `json:"sort"`
+ Pagination ecore.Pagination
}
type FilterDto struct {
- Code string `json:"code"`
- Name string `json:"name"`
- CheckupCategory_Code *string `json:"checkupCategory_code"`
-
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+ Code string `json:"code"`
+ Name string `json:"name"`
+ McuSrcCategory_Code *string `json:"mcuSrcCategory-code"`
+ Search string `json:"search" gormhelper:"searchColumns=Code,Name"`
}
type ReadDetailDto struct {
@@ -47,19 +47,23 @@ type MetaDto struct {
}
type ResponseDto struct {
- ecore.SmallMain
- Code string `json:"code"`
- Name string `json:"name"`
- CheckupCategory_Code *string `json:"checkupCategory_code"`
+ ecore.Main
+ Code string `json:"code"`
+ Name string `json:"name"`
+ McuSrcCategory_Code *string `json:"mcuSrcCategory_code"`
+ Item_Id *uint `json:"item_id"`
+ Item *ei.Item `json:"item,omitempty"`
}
func (d McuSrc) ToResponse() ResponseDto {
resp := ResponseDto{
- Code: d.Code,
- Name: d.Name,
- CheckupCategory_Code: d.CheckupCategory_Code,
+ Code: d.Code,
+ Name: d.Name,
+ McuSrcCategory_Code: d.McuSrcCategory_Code,
+ Item_Id: d.Item_Id,
+ Item: d.Item,
}
- resp.SmallMain = d.SmallMain
+ resp.Main = d.Main
return resp
}
diff --git a/internal/domain/main-entities/mcu-src/entity.go b/internal/domain/main-entities/mcu-src/entity.go
index cdd8356f..d3f4fca1 100644
--- a/internal/domain/main-entities/mcu-src/entity.go
+++ b/internal/domain/main-entities/mcu-src/entity.go
@@ -2,13 +2,16 @@ package mcusrc
import (
ecore "simrs-vx/internal/domain/base-entities/core"
+ ei "simrs-vx/internal/domain/main-entities/item"
emsc "simrs-vx/internal/domain/main-entities/mcu-src-category"
)
type McuSrc struct {
- ecore.SmallMain // adjust this according to the needs
- Code string `json:"code" gorm:"unique;size:20"`
- Name string `json:"name" gorm:"size:50"`
- CheckupCategory_Code *string `json:"checkupCategory_code" gorm:"size:20"`
- CheckupCategory *emsc.McuSrcCategory `json:"checkupCategory,omitempty" gorm:"foreignKey:CheckupCategory_Code;references:Code"`
+ ecore.Main // adjust this according to the needs
+ Code string `json:"code" gorm:"unique;size:20"`
+ Name string `json:"name" gorm:"size:50"`
+ McuSrcCategory_Code *string `json:"mcuSrcCategory_code" gorm:"size:20"`
+ McuSrcCategory *emsc.McuSrcCategory `json:"mcuSrcCategory,omitempty" gorm:"foreignKey:McuSrcCategory_Code;references:Code"`
+ Item_Id *uint `json:"item_id"`
+ Item *ei.Item `json:"item,omitempty" gorm:"foreignKey:Item_Id;references:Id"`
}
diff --git a/internal/domain/main-entities/mcu-sub-src/dto.go b/internal/domain/main-entities/mcu-sub-src/dto.go
new file mode 100644
index 00000000..f1b6d3bb
--- /dev/null
+++ b/internal/domain/main-entities/mcu-sub-src/dto.go
@@ -0,0 +1,79 @@
+package mcusubsrc
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ei "simrs-vx/internal/domain/main-entities/item"
+ ems "simrs-vx/internal/domain/main-entities/mcu-src"
+)
+
+type CreateDto struct {
+ Code string `json:"code" validate:"maxLength=20"`
+ Name string `json:"name" validate:"maxLength=50"`
+ McuSrc_Id *uint `json:"mcuSrc_id"`
+ Item_Id *uint `json:"item_id"`
+}
+
+type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Sort string `json:"sort"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ Code string `json:"code"`
+ Name string `json:"name"`
+ CheckupCategory_Code *string `json:"checkupCategory-code"`
+ 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.Main
+ Code string `json:"code"`
+ Name string `json:"name"`
+ McuSrc_Id *uint `json:"mcuSrc_id"`
+ McuSrc *ems.McuSrc `json:"mcuSrc,omitempty"`
+ Item_Id *uint `json:"item_id"`
+ Item *ei.Item `json:"item,omitempty"`
+}
+
+func (d McuSubSrc) ToResponse() ResponseDto {
+ resp := ResponseDto{
+ Code: d.Code,
+ Name: d.Name,
+ McuSrc_Id: d.McuSrc_Id,
+ McuSrc: d.McuSrc,
+ Item_Id: d.Item_Id,
+ Item: d.Item,
+ }
+ resp.Main = d.Main
+ return resp
+}
+
+func ToResponseList(data []McuSubSrc) []ResponseDto {
+ resp := make([]ResponseDto, len(data))
+ for i, u := range data {
+ resp[i] = u.ToResponse()
+ }
+ return resp
+}
diff --git a/internal/domain/main-entities/mcu-sub-src/entity.go b/internal/domain/main-entities/mcu-sub-src/entity.go
new file mode 100644
index 00000000..02559abb
--- /dev/null
+++ b/internal/domain/main-entities/mcu-sub-src/entity.go
@@ -0,0 +1,17 @@
+package mcusubsrc
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ei "simrs-vx/internal/domain/main-entities/item"
+ ems "simrs-vx/internal/domain/main-entities/mcu-src"
+)
+
+type McuSubSrc struct {
+ ecore.Main // adjust this according to the needs
+ Code string `json:"code" gorm:"unique;size:20"`
+ Name string `json:"name" gorm:"size:50"`
+ McuSrc_Id *uint `json:"mcuSrc_id"`
+ McuSrc *ems.McuSrc `json:"mcuSrc,omitempty" gorm:"foreignKey:McuSrc_Id;references:Id"`
+ Item_Id *uint `json:"item_id"`
+ Item *ei.Item `json:"item,omitempty" gorm:"foreignKey:Item_Id;references:Id"`
+}
diff --git a/internal/domain/main-entities/medical-action-src-item/dto.go b/internal/domain/main-entities/medical-action-src-item/dto.go
index 75836c14..540a6ca5 100644
--- a/internal/domain/main-entities/medical-action-src-item/dto.go
+++ b/internal/domain/main-entities/medical-action-src-item/dto.go
@@ -15,18 +15,14 @@ type CreateDto struct {
type ReadListDto struct {
FilterDto
- Includes string `json:"includes"`
- Preloads []string `json:"-"`
+ Includes string `json:"includes"`
+ Pagination ecore.Pagination
}
type FilterDto struct {
- MedicalActionSrc_Id *uint `json:"medicalActionSrc_id"`
- ProcedureSrc_Id *uint `json:"procedureSrc_id"`
- Item_Id *uint `json:"item_id"`
-
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+ MedicalActionSrc_Id *uint `json:"medicalActionSrc-id"`
+ ProcedureSrc_Id *uint `json:"procedureSrc-id"`
+ Item_Id *uint `json:"item-id"`
}
type ReadDetailDto struct {
diff --git a/internal/domain/main-entities/medical-action-src/dto.go b/internal/domain/main-entities/medical-action-src/dto.go
index e902a1e8..32e248d8 100644
--- a/internal/domain/main-entities/medical-action-src/dto.go
+++ b/internal/domain/main-entities/medical-action-src/dto.go
@@ -6,25 +6,25 @@ import (
)
type CreateDto struct {
- Code string `json:"code" validate:"maxLength=20"`
- Name string `json:"name" validate:"maxLength=50"`
- Item_Id *uint `json:"item_id"`
+ Code string `json:"code" validate:"maxLength=20"`
+ Name string `json:"name" validate:"maxLength=50"`
+ Type_Code string `json:"type_code" validate:"maxLength=20"`
+ Item_Id *uint `json:"item_id"`
}
type ReadListDto struct {
FilterDto
- Includes string `json:"includes"`
- Preloads []string `json:"-"`
+ Includes string `json:"includes"`
+ Sort string `json:"sort"`
+ Pagination ecore.Pagination
}
type FilterDto struct {
- Code string `json:"code"`
- Name string `json:"name"`
- Item_Id *uint `json:"item_id"`
-
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+ Code string `json:"code"`
+ Name string `json:"name"`
+ Type_Code string `json:"type_code"`
+ Item_Id *uint `json:"item-id"`
+ Search string `json:"search" gormhelper:"searchColumns=Code,Name"`
}
type ReadDetailDto struct {
@@ -49,18 +49,20 @@ type MetaDto struct {
type ResponseDto struct {
ecore.Main
- Code string `json:"code"`
- Name string `json:"name"`
- Item_Id *uint `json:"item_id"`
- Item *ei.Item `json:"item,omitempty"`
+ Code string `json:"code"`
+ Name string `json:"name"`
+ Type_Code string `json:"type_code"`
+ Item_Id *uint `json:"item_id"`
+ Item *ei.Item `json:"item,omitempty"`
}
func (d MedicalActionSrc) ToResponse() ResponseDto {
resp := ResponseDto{
- Code: d.Code,
- Name: d.Name,
- Item_Id: d.Item_Id,
- Item: d.Item,
+ Code: d.Code,
+ Name: d.Name,
+ Type_Code: d.Type_Code,
+ Item_Id: d.Item_Id,
+ Item: d.Item,
}
resp.Main = d.Main
return resp
diff --git a/internal/domain/main-entities/medical-action-src/entity.go b/internal/domain/main-entities/medical-action-src/entity.go
index fbbbdb28..60f15816 100644
--- a/internal/domain/main-entities/medical-action-src/entity.go
+++ b/internal/domain/main-entities/medical-action-src/entity.go
@@ -9,6 +9,7 @@ type MedicalActionSrc struct {
ecore.Main // adjust this according to the needs
Code string `json:"code" gorm:"unique;size:20"`
Name string `json:"name" gorm:"size:50"`
+ Type_Code string `json:"type_code" gorm:"size:20"`
Item_Id *uint `json:"item_id"`
Item *ei.Item `json:"item,omitempty" gorm:"foreignKey:Item_Id;references:Id"`
}
diff --git a/internal/domain/main-entities/medication-item-dist/dto.go b/internal/domain/main-entities/medication-item-dist/dto.go
new file mode 100644
index 00000000..9790895a
--- /dev/null
+++ b/internal/domain/main-entities/medication-item-dist/dto.go
@@ -0,0 +1,84 @@
+package medicationitem
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ emi "simrs-vx/internal/domain/main-entities/medication-item"
+
+ pa "simrs-vx/pkg/auth-helper"
+
+ "time"
+)
+
+type CreateDto struct {
+ MedicationItem_Id *uint `json:"medicationItem_id"`
+ DateTime *time.Time `json:"dateTime"`
+ Remain float64 `json:"remain"`
+ Nurse_Id *uint `json:"nurse_id"`
+}
+
+type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ MedicationItem_Id *uint `json:"medicationItem-id"`
+ DateTime *time.Time `json:"dateTime"`
+ Remain float64 `json:"remain"`
+ Nurse_Id *uint `json:"nurse-id"`
+}
+type ReadDetailDto struct {
+ Id uint16 `json:"id"`
+}
+
+type UpdateDto struct {
+ Id uint16 `json:"id"`
+ CreateDto
+}
+
+type DeleteDto struct {
+ Id uint16 `json:"id"`
+}
+
+type ConsumeDto struct {
+ Id uint16 `json:"id"`
+ Usage float64 `json:"usage"`
+
+ pa.AuthInfo
+}
+
+type MetaDto struct {
+ PageNumber int `json:"page_number"`
+ PageSize int `json:"page_size"`
+ Count int `json:"count"`
+}
+
+type ResponseDto struct {
+ ecore.Main
+ MedicationItem_Id *uint `json:"medicationItem_id"`
+ MedicationItem *emi.MedicationItem `json:"medicationItem,omitempty"`
+ DateTime *time.Time `json:"dateTime"`
+ Remain float64 `json:"remain"`
+ Nurse_Id *uint `json:"nurse_id"`
+}
+
+func (d MedicationItemDist) ToResponse() ResponseDto {
+ resp := ResponseDto{
+ MedicationItem_Id: d.MedicationItem_Id,
+ MedicationItem: d.MedicationItem,
+ DateTime: d.DateTime,
+ Remain: d.Remain,
+ Nurse_Id: d.Nurse_Id,
+ }
+ resp.Main = d.Main
+ return resp
+}
+
+func ToResponseList(data []MedicationItemDist) []ResponseDto {
+ resp := make([]ResponseDto, len(data))
+ for i, u := range data {
+ resp[i] = u.ToResponse()
+ }
+ return resp
+}
diff --git a/internal/domain/main-entities/medication-item-dist/entity.go b/internal/domain/main-entities/medication-item-dist/entity.go
new file mode 100644
index 00000000..99e16d48
--- /dev/null
+++ b/internal/domain/main-entities/medication-item-dist/entity.go
@@ -0,0 +1,19 @@
+package medicationitem
+
+import (
+ "time"
+
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ emi "simrs-vx/internal/domain/main-entities/medication-item"
+ en "simrs-vx/internal/domain/main-entities/nurse"
+)
+
+type MedicationItemDist struct {
+ ecore.Main // adjust this according to the needs
+ MedicationItem_Id *uint `json:"medicationItem_id"`
+ MedicationItem *emi.MedicationItem `json:"medicationItem,omitempty" gorm:"foreignKey:MedicationItem_Id;references:Id"`
+ DateTime *time.Time `json:"dateTime"`
+ Remain float64 `json:"remain"`
+ Nurse_Id *uint `json:"nurse_id"`
+ Nurse *en.Nurse `json:"nurse,omitempty" gorm:"foreignKey:Nurse_Id;references:Id"`
+}
diff --git a/internal/domain/main-entities/medication-item/dto.go b/internal/domain/main-entities/medication-item/dto.go
new file mode 100644
index 00000000..26a5b35e
--- /dev/null
+++ b/internal/domain/main-entities/medication-item/dto.go
@@ -0,0 +1,109 @@
+package medicationitem
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ eme "simrs-vx/internal/domain/main-entities/medication"
+ em "simrs-vx/internal/domain/main-entities/medicine"
+ emm "simrs-vx/internal/domain/main-entities/medicine-mix"
+
+ erc "simrs-vx/internal/domain/references/common"
+)
+
+type CreateDto struct {
+ Medication_Id *uint `json:"medication_id"`
+ IsMix bool `json:"isMix"`
+ Medicine_Id *uint `json:"medicine_id"`
+ MedicineMix_Id *uint `json:"medicineMix_id"`
+ Frequency *uint16 `json:"frequency"`
+ Dose float64 `json:"dose"`
+ Usage string `json:"usage"`
+ Interval uint8 `json:"interval"`
+ IntervalUnit_Code erc.TimeUnitCode `json:"intervalUnit_code"`
+ IsRedeemed bool `json:"isRedeemed"`
+ Quantity float64 `json:"quantity"`
+ Note *string `json:"note" gorm:"size:1024"`
+ IntervalMultiplier *uint16 `json:"intervalMultiplier"`
+}
+
+type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Preloads []string `json:"-"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ Medication_Id *uint `json:"medication-id"`
+ IsMix bool `json:"isMix"`
+ Medicine_Id *uint `json:"medicine-id"`
+ MedicineMix_Id *uint `json:"medicineMix-id"`
+ Usage float64 `json:"usage"`
+ Interval uint8 `json:"interval"`
+ IntervalUnit_Code erc.TimeUnitCode `json:"intervalUnit-code"`
+ IsRedeemed bool `json:"isRedeemed"`
+ Quantity float64 `json:"quantity"`
+ Note *string `json:"note" gorm:"size:1024"`
+}
+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
+ Medication_Id *uint `json:"medication_id"`
+ Medication *eme.Medication `json:"medication,omitempty"`
+ IsMix bool `json:"isMix"`
+ Medicine_Id *uint `json:"medicine_id"`
+ Medicine *em.Medicine `json:"medicine,omitempty"`
+ MedicineMix_Id *uint `json:"medicineMix_id"`
+ MedicineMix *emm.MedicineMix `json:"medicineMix,omitempty"`
+ Usage string `json:"usage"`
+ Interval uint8 `json:"interval"`
+ IntervalUnit_Code erc.TimeUnitCode `json:"intervalUnit_code"`
+ IsRedeemed bool `json:"isRedeemed"`
+ Quantity float64 `json:"quantity"`
+ Note *string `json:"note" gorm:"size:1024"`
+}
+
+func (d MedicationItem) ToResponse() ResponseDto {
+ resp := ResponseDto{
+ Medication_Id: d.Medication_Id,
+ Medication: d.Medication,
+ IsMix: d.IsMix,
+ Medicine_Id: d.Medicine_Id,
+ Medicine: d.Medicine,
+ MedicineMix_Id: d.MedicineMix_Id,
+ MedicineMix: d.MedicineMix,
+ Usage: d.Usage,
+ Interval: d.Interval,
+ IntervalUnit_Code: d.IntervalUnit_Code,
+ IsRedeemed: d.IsRedeemed,
+ Quantity: d.Quantity,
+ Note: d.Note,
+ }
+ resp.Main = d.Main
+ return resp
+}
+
+func ToResponseList(data []MedicationItem) []ResponseDto {
+ resp := make([]ResponseDto, len(data))
+ for i, u := range data {
+ resp[i] = u.ToResponse()
+ }
+ return resp
+}
diff --git a/internal/domain/main-entities/medication-item/entity.go b/internal/domain/main-entities/medication-item/entity.go
new file mode 100644
index 00000000..ffef0761
--- /dev/null
+++ b/internal/domain/main-entities/medication-item/entity.go
@@ -0,0 +1,29 @@
+package medicationitem
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ eme "simrs-vx/internal/domain/main-entities/medication"
+ em "simrs-vx/internal/domain/main-entities/medicine"
+ emm "simrs-vx/internal/domain/main-entities/medicine-mix"
+
+ erc "simrs-vx/internal/domain/references/common"
+)
+
+type MedicationItem struct {
+ ecore.Main // adjust this according to the needs
+ Medication_Id *uint `json:"medication_id"`
+ Medication *eme.Medication `json:"medication,omitempty" gorm:"foreignKey:Medication_Id;references:Id"`
+ IsMix bool `json:"isMix"`
+ Medicine_Id *uint `json:"medicine_id"`
+ Medicine *em.Medicine `json:"medicine,omitempty" gorm:"foreignKey:Medicine_Id;references:Id"`
+ MedicineMix_Id *uint `json:"medicineMix_id"`
+ MedicineMix *emm.MedicineMix `json:"medicineMix,omitempty" gorm:"foreignKey:MedicineMix_Id;references:Id"`
+ Frequency *uint16 `json:"frequency"`
+ Dose float64 `json:"dose"`
+ Usage string `json:"usage" gorm:"size:255"`
+ Interval uint8 `json:"interval"`
+ IntervalUnit_Code erc.TimeUnitCode `json:"intervalUnit_code"`
+ IsRedeemed bool `json:"isRedeemed"`
+ Quantity float64 `json:"quantity"`
+ Note *string `json:"note" gorm:"size:1024"`
+}
diff --git a/internal/domain/main-entities/medication/dto.go b/internal/domain/main-entities/medication/dto.go
new file mode 100644
index 00000000..c2cf9d14
--- /dev/null
+++ b/internal/domain/main-entities/medication/dto.go
@@ -0,0 +1,85 @@
+package medication
+
+import (
+ "time"
+
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ee "simrs-vx/internal/domain/main-entities/encounter"
+ ep "simrs-vx/internal/domain/main-entities/pharmacist"
+
+ erc "simrs-vx/internal/domain/references/common"
+
+ pa "simrs-vx/pkg/auth-helper"
+)
+
+type CreateDto struct {
+ Encounter_Id *uint `json:"encounter_id"`
+ IssuedAt *time.Time `json:"issuedAt"`
+ Pharmacist_Id *uint `json:"pharmacist_id"`
+ Status_Code erc.DataStatusCode `json:"status_code"`
+}
+
+type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ Encounter_Id *uint `json:"encounter-id"`
+ IssuedAt *time.Time `json:"issuedAt"`
+ Pharmacist_Id *uint `json:"pharmacist-id"`
+ Status_Code erc.DataStatusCode `json:"status-code"`
+}
+type ReadDetailDto struct {
+ Id uint `json:"id"`
+ Encounter_Id *uint `json:"encounter_id"`
+
+ pa.AuthInfo
+}
+
+type UpdateDto struct {
+ Id uint `json:"id"`
+ CreateDto
+}
+
+type DeleteDto struct {
+ Id uint `json:"id"`
+}
+
+type MetaDto struct {
+ PageNumber int `json:"page_number"`
+ PageSize int `json:"page_size"`
+ Count int `json:"count"`
+}
+
+type ResponseDto struct {
+ ecore.Main
+ Encounter_Id *uint `json:"encounter_id"`
+ Encounter *ee.Encounter `json:"encounter,omitempty"`
+ IssuedAt *time.Time `json:"issuedAt"`
+ Pharmacist_Id *uint `json:"pharmacist_id"`
+ Pharmacist *ep.Pharmacist `json:"pharmacist,omitempty"`
+ Status_Code erc.DataStatusCode `json:"status_code"`
+}
+
+func (d Medication) ToResponse() ResponseDto {
+ resp := ResponseDto{
+ Encounter_Id: d.Encounter_Id,
+ Encounter: d.Encounter,
+ IssuedAt: d.IssuedAt,
+ Pharmacist_Id: d.Pharmacist_Id,
+ Pharmacist: d.Pharmacist,
+ Status_Code: d.Status_Code,
+ }
+ resp.Main = d.Main
+ return resp
+}
+
+func ToResponseList(data []Medication) []ResponseDto {
+ resp := make([]ResponseDto, len(data))
+ for i, u := range data {
+ resp[i] = u.ToResponse()
+ }
+ return resp
+}
diff --git a/internal/domain/main-entities/medication/entity.go b/internal/domain/main-entities/medication/entity.go
new file mode 100644
index 00000000..0a59c27b
--- /dev/null
+++ b/internal/domain/main-entities/medication/entity.go
@@ -0,0 +1,25 @@
+package medication
+
+import (
+ "time"
+
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ee "simrs-vx/internal/domain/main-entities/encounter"
+ ep "simrs-vx/internal/domain/main-entities/pharmacist"
+
+ erc "simrs-vx/internal/domain/references/common"
+)
+
+type Medication struct {
+ ecore.Main // adjust this according to the needs
+ Encounter_Id *uint `json:"encounter_id"`
+ Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"`
+ IssuedAt *time.Time `json:"issuedAt"`
+ Pharmacist_Id *uint `json:"pharmacist_id"`
+ Pharmacist *ep.Pharmacist `json:"pharmacist,omitempty" gorm:"foreignKey:Pharmacist_Id;references:Id"`
+ Status_Code erc.DataStatusCode `json:"status_code"`
+}
+
+func (d Medication) IsCompleted() bool {
+ return d.Status_Code == erc.DSCDone
+}
diff --git a/internal/domain/main-entities/medicine-group/dto.go b/internal/domain/main-entities/medicine-group/dto.go
index 88de7c21..1f71debe 100644
--- a/internal/domain/main-entities/medicine-group/dto.go
+++ b/internal/domain/main-entities/medicine-group/dto.go
@@ -10,12 +10,16 @@ type CreateDto struct {
}
type ReadListDto struct {
- Code string `json:"code"`
- Name string `json:"name"`
+ FilterDto
+ Includes string `json:"includes"`
+ Sort string `json:"sort"`
+ Pagination ecore.Pagination
+}
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+type FilterDto struct {
+ Code string `json:"code"`
+ Name string `json:"name"`
+ Search string `json:"search" gormhelper:"searchColumns=Code,Name"`
}
type ReadDetailDto struct {
diff --git a/internal/domain/main-entities/medicine-method/dto.go b/internal/domain/main-entities/medicine-method/dto.go
index 5df40a7a..4840fd27 100644
--- a/internal/domain/main-entities/medicine-method/dto.go
+++ b/internal/domain/main-entities/medicine-method/dto.go
@@ -10,12 +10,16 @@ type CreateDto struct {
}
type ReadListDto struct {
- Code string `json:"code"`
- Name string `json:"name"`
+ FilterDto
+ Includes string `json:"includes"`
+ Sort string `json:"sort"`
+ Pagination ecore.Pagination
+}
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+type FilterDto struct {
+ Code string `json:"code"`
+ Name string `json:"name"`
+ Search string `json:"search" gormhelper:"searchColumns=Code,Name"`
}
type ReadDetailDto struct {
diff --git a/internal/domain/main-entities/medicine-mix-item/dto.go b/internal/domain/main-entities/medicine-mix-item/dto.go
index dbcbce21..e834e7ec 100644
--- a/internal/domain/main-entities/medicine-mix-item/dto.go
+++ b/internal/domain/main-entities/medicine-mix-item/dto.go
@@ -3,29 +3,26 @@ package medicinemixitem
import (
ecore "simrs-vx/internal/domain/base-entities/core"
em "simrs-vx/internal/domain/main-entities/medicine"
- emm "simrs-vx/internal/domain/main-entities/medicine-mix"
)
type CreateDto struct {
- MedicineMix_Id *uint `json:"medicineMix_id"`
- Medicine_Id *uint `json:"medicine_id"`
- Dose *uint8 `json:"dose"`
+ MedicineMix_Id *uint `json:"medicineMix_id"`
+ Medicine_Id *uint `json:"medicine_id"`
+ Dose *uint8 `json:"dose"`
+ Note *string `json:"note" gom:"size:1024"`
}
type ReadListDto struct {
FilterDto
- Includes string `json:"includes"`
- Preloads []string `json:"-"`
+ Includes string `json:"includes"`
+ Pagination ecore.Pagination
}
type FilterDto struct {
- MedicineMix_Id *uint `json:"medicineMix_id"`
- Medicine_Id *uint `json:"medicine_id"`
- Dose *uint8 `json:"dose"`
-
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+ MedicineMix_Id *uint `json:"medicineMix-id"`
+ Medicine_Id *uint `json:"medicine-id"`
+ Dose *uint8 `json:"dose"`
+ Note *string `json:"note" gom:"size:1024"`
}
type ReadDetailDto struct {
@@ -49,20 +46,20 @@ type MetaDto struct {
type ResponseDto struct {
ecore.Main
- MedicineMix_Id *uint `json:"medicineMix_id"`
- MedicineMix *emm.MedicineMix `json:"medicineMix,omitempty"`
- Medicine_Id *uint `json:"medicine_id"`
- Medicine *em.Medicine `json:"medicine,omitempty"`
- Dose *uint8 `json:"dose"`
+ MedicineMix_Id *uint `json:"medicineMix_id"`
+ Medicine_Id *uint `json:"medicine_id"`
+ Medicine *em.Medicine `json:"medicine,omitempty"`
+ Dose *uint8 `json:"dose"`
+ Note *string `json:"note" gom:"size:1024"`
}
func (d MedicineMixItem) ToResponse() ResponseDto {
resp := ResponseDto{
MedicineMix_Id: d.MedicineMix_Id,
- MedicineMix: d.MedicineMix,
Medicine_Id: d.Medicine_Id,
Medicine: d.Medicine,
Dose: d.Dose,
+ Note: d.Note,
}
resp.Main = d.Main
return resp
diff --git a/internal/domain/main-entities/medicine-mix-item/entity.go b/internal/domain/main-entities/medicine-mix-item/entity.go
index 7c456fcb..a642fce0 100644
--- a/internal/domain/main-entities/medicine-mix-item/entity.go
+++ b/internal/domain/main-entities/medicine-mix-item/entity.go
@@ -3,14 +3,13 @@ package medicinemixitem
import (
ecore "simrs-vx/internal/domain/base-entities/core"
em "simrs-vx/internal/domain/main-entities/medicine"
- emm "simrs-vx/internal/domain/main-entities/medicine-mix"
)
type MedicineMixItem struct {
- ecore.Main // adjust this according to the needs
- MedicineMix_Id *uint `json:"medicineMix_id"`
- MedicineMix *emm.MedicineMix `json:"medicineMix,omitempty" gorm:"foreignKey:MedicineMix_Id;references:Id"`
- Medicine_Id *uint `json:"medicine_id"`
- Medicine *em.Medicine `json:"medicine,omitempty" gorm:"foreignKey:Medicine_Id;references:Id"`
- Dose *uint8 `json:"dose"`
+ ecore.Main // adjust this according to the needs
+ MedicineMix_Id *uint `json:"medicineMix_id"`
+ Medicine_Id *uint `json:"medicine_id"`
+ Medicine *em.Medicine `json:"medicine,omitempty" gorm:"foreignKey:Medicine_Id;references:Id"`
+ Dose *uint8 `json:"dose"`
+ Note *string `json:"note" gom:"size:1024"`
}
diff --git a/internal/domain/main-entities/medicine-mix/dto.go b/internal/domain/main-entities/medicine-mix/dto.go
index b9fc656e..6cb8cb1a 100644
--- a/internal/domain/main-entities/medicine-mix/dto.go
+++ b/internal/domain/main-entities/medicine-mix/dto.go
@@ -2,18 +2,19 @@ package medicinemix
import (
ecore "simrs-vx/internal/domain/base-entities/core"
+
+ emmi "simrs-vx/internal/domain/main-entities/medicine-mix-item"
)
type CreateDto struct {
- Name string `json:"name" validate:"maxLength=50"`
+ Name string `json:"name" validate:"maxLength=50"`
+ Uom_Code *string `json:"uom_code" validate:"maxLength=10"`
}
type ReadListDto struct {
- Name string `json:"name"`
-
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+ Name string `json:"name"`
+ Uom_Code *string `json:"uom-code"`
+ Pagination ecore.Pagination
}
type ReadDetailDto struct {
@@ -37,12 +38,16 @@ type MetaDto struct {
type ResponseDto struct {
ecore.Main
- Name string `json:"name"`
+ Name string `json:"name"`
+ Uom_Code *string `json:"uom_code"`
+ MixItems []*emmi.MedicineMixItem `json:"mixItems"`
}
func (d MedicineMix) ToResponse() ResponseDto {
resp := ResponseDto{
- Name: d.Name,
+ Name: d.Name,
+ Uom_Code: d.Uom_Code,
+ MixItems: d.MixItems,
}
resp.Main = d.Main
return resp
diff --git a/internal/domain/main-entities/medicine-mix/entity.go b/internal/domain/main-entities/medicine-mix/entity.go
index 3670c6d6..1b9edd4f 100644
--- a/internal/domain/main-entities/medicine-mix/entity.go
+++ b/internal/domain/main-entities/medicine-mix/entity.go
@@ -2,9 +2,14 @@ package medicinemix
import (
ecore "simrs-vx/internal/domain/base-entities/core"
+ emmi "simrs-vx/internal/domain/main-entities/medicine-mix-item"
+ eu "simrs-vx/internal/domain/main-entities/uom"
)
type MedicineMix struct {
- ecore.Main // adjust this according to the needs
- Name string `json:"name" gorm:"size:50"`
+ ecore.Main // adjust this according to the needs
+ Name string `json:"name" gorm:"size:50"`
+ Uom_Code *string `json:"uom_code" gorm:"size:10"`
+ Uom *eu.Uom `json:"uom" gorm:"foreignKey:Uom_Code;references:Code"`
+ MixItems []*emmi.MedicineMixItem `json:"mixItems" gorm:"foreignKey:MedicineMix_Id;references:Id"`
}
diff --git a/internal/domain/main-entities/medicine/dto.go b/internal/domain/main-entities/medicine/dto.go
index 9e63c9ae..82431fc1 100644
--- a/internal/domain/main-entities/medicine/dto.go
+++ b/internal/domain/main-entities/medicine/dto.go
@@ -23,24 +23,22 @@ type CreateDto struct {
type ReadListDto struct {
FilterDto
- Includes string `json:"includes"`
- Preloads []string `json:"-"`
+ Includes string `json:"includes"`
+ Sort string `json:"sort"`
+ Pagination ecore.Pagination
}
type FilterDto struct {
Code string `json:"code"`
Name string `json:"name"`
- MedicineGroup_Code *string `json:"medicineGroup_code"`
- MedicineMethod_Code *string `json:"medicineMethod_code"`
- Uom_Code *string `json:"uom_code"`
+ MedicineGroup_Code *string `json:"medicineGroup-code"`
+ MedicineMethod_Code *string `json:"medicineMethod-code"`
+ Uom_Code *string `json:"uom-code"`
Dose uint8 `json:"dose"`
- Infra_Id *uint16 `json:"infra_id"`
+ Infra_Id *uint16 `json:"infra-id"`
Stock *int `json:"stock"`
- Item_Id *uint `json:"item_id"`
-
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+ Item_Id *uint `json:"item-id"`
+ Search string `json:"search" gormhelper:"searchColumns=Code,Name"`
}
type ReadDetailDto struct {
diff --git a/internal/domain/main-entities/midwife/dto.go b/internal/domain/main-entities/midwife/dto.go
new file mode 100644
index 00000000..d1adfdaf
--- /dev/null
+++ b/internal/domain/main-entities/midwife/dto.go
@@ -0,0 +1,68 @@
+package midwife
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ee "simrs-vx/internal/domain/main-entities/employee"
+)
+
+type CreateDto struct {
+ Employee_Id *uint `json:"employee_id"`
+ IHS_Number *string `json:"ihs_number" validate:"maxLength=20"`
+}
+
+type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ Employee_Id *uint `json:"employee_id"`
+ IHS_Number *string `json:"ihs_number"`
+}
+
+type ReadDetailDto struct {
+ Id uint16 `json:"id"`
+ Employee_Id *uint `json:"employee_id"`
+ IHS_Number *string `json:"ihs_number"`
+}
+
+type UpdateDto struct {
+ Id uint `json:"id"`
+ CreateDto
+}
+
+type DeleteDto struct {
+ Id uint `json:"id"`
+}
+
+type MetaDto struct {
+ PageNumber int `json:"page_number"`
+ PageSize int `json:"page_size"`
+ Count int `json:"count"`
+}
+
+type ResponseDto struct {
+ ecore.Main
+ Employee_Id *uint `json:"employee_id"`
+ Employee *ee.Employee `json:"employee,omitempty"`
+ IHS_Number *string `json:"ihs_number"`
+}
+
+func (d Midwife) ToResponse() ResponseDto {
+ resp := ResponseDto{
+ Employee_Id: d.Employee_Id,
+ Employee: d.Employee,
+ IHS_Number: d.IHS_Number,
+ }
+ resp.Main = d.Main
+ return resp
+}
+
+func ToResponseList(data []Midwife) []ResponseDto {
+ resp := make([]ResponseDto, len(data))
+ for i, u := range data {
+ resp[i] = u.ToResponse()
+ }
+ return resp
+}
diff --git a/internal/domain/main-entities/midwife/entity.go b/internal/domain/main-entities/midwife/entity.go
new file mode 100644
index 00000000..f98ba553
--- /dev/null
+++ b/internal/domain/main-entities/midwife/entity.go
@@ -0,0 +1,13 @@
+package midwife
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ee "simrs-vx/internal/domain/main-entities/employee"
+)
+
+type Midwife struct {
+ ecore.Main // adjust this according to the needs
+ Employee_Id *uint `json:"employee_id"`
+ Employee *ee.Employee `json:"employee,omitempty" gorm:"foreignKey:Employee_Id;references:Id"`
+ IHS_Number *string `json:"ihs_number" gorm:"unique;size:20"`
+}
diff --git a/internal/domain/main-entities/nurse/dto.go b/internal/domain/main-entities/nurse/dto.go
index 224cb0d5..1707f212 100644
--- a/internal/domain/main-entities/nurse/dto.go
+++ b/internal/domain/main-entities/nurse/dto.go
@@ -3,6 +3,7 @@ package nurse
import (
ecore "simrs-vx/internal/domain/base-entities/core"
ee "simrs-vx/internal/domain/main-entities/employee"
+ ei "simrs-vx/internal/domain/main-entities/infra"
eu "simrs-vx/internal/domain/main-entities/unit"
)
@@ -10,22 +11,20 @@ type CreateDto struct {
Employee_Id *uint `json:"employee_id"`
IHS_Number *string `json:"ihs_number" validate:"maxLength=20"`
Unit_Id *uint16 `json:"unit_id"`
+ Infra_Id *uint16 `json:"infra_id"`
}
type ReadListDto struct {
FilterDto
- Includes string `json:"includes"`
- Preloads []string `json:"-"`
+ Includes string `json:"includes"`
+ Pagination ecore.Pagination
}
type FilterDto struct {
- Employee_Id *uint `json:"employee_id"`
- IHS_Number *string `json:"ihs_number"`
- Unit_Id *uint16 `json:"unit_id"`
-
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+ Employee_Id *uint `json:"employee-id"`
+ IHS_Number *string `json:"ihs-number"`
+ Unit_Id *uint16 `json:"unit-id"`
+ Infra_Id *uint16 `json:"infra-id"`
}
type ReadDetailDto struct {
Id uint16 `json:"id"`
@@ -55,6 +54,8 @@ type ResponseDto struct {
IHS_Number *string `json:"ihs_number"`
Unit_Id *uint16 `json:"unit_id"`
Unit *eu.Unit `json:"unit,omitempty"`
+ Infra_Id *uint16 `json:"infra_id"`
+ Infra *ei.Infra `json:"infra,omitempty"`
}
func (d Nurse) ToResponse() ResponseDto {
@@ -64,6 +65,8 @@ func (d Nurse) ToResponse() ResponseDto {
IHS_Number: d.IHS_Number,
Unit_Id: d.Unit_Id,
Unit: d.Unit,
+ Infra_Id: d.Infra_Id,
+ Infra: d.Infra,
}
resp.Main = d.Main
return resp
diff --git a/internal/domain/main-entities/nurse/entity.go b/internal/domain/main-entities/nurse/entity.go
index dc39ae9f..c3332c45 100644
--- a/internal/domain/main-entities/nurse/entity.go
+++ b/internal/domain/main-entities/nurse/entity.go
@@ -3,6 +3,7 @@ package nurse
import (
ecore "simrs-vx/internal/domain/base-entities/core"
ee "simrs-vx/internal/domain/main-entities/employee"
+ ei "simrs-vx/internal/domain/main-entities/infra"
eu "simrs-vx/internal/domain/main-entities/unit"
)
@@ -10,7 +11,9 @@ type Nurse struct {
ecore.Main // adjust this according to the needs
Employee_Id *uint `json:"employee_id"`
Employee *ee.Employee `json:"employee,omitempty" gorm:"foreignKey:Employee_Id;references:Id"`
- IHS_Number *string `json:"ihs_number" gorm:"size:20"`
+ IHS_Number *string `json:"ihs_number" gorm:"unique;size:20"`
Unit_Id *uint16 `json:"unit_id"`
Unit *eu.Unit `json:"unit,omitempty" gorm:"foreignKey:Unit_Id;references:Id"`
+ Infra_Id *uint16 `json:"infra_id"`
+ Infra *ei.Infra `json:"infra,omitempty" gorm:"foreignKey:Infra_Id;references:Id"`
}
diff --git a/internal/domain/main-entities/nutritionist/dto.go b/internal/domain/main-entities/nutritionist/dto.go
index 7f8c2229..df6365bf 100644
--- a/internal/domain/main-entities/nutritionist/dto.go
+++ b/internal/domain/main-entities/nutritionist/dto.go
@@ -12,17 +12,13 @@ type CreateDto struct {
type ReadListDto struct {
FilterDto
- Includes string `json:"includes"`
- Preloads []string `json:"-"`
+ Includes string `json:"includes"`
+ Pagination ecore.Pagination
}
type FilterDto struct {
- Employee_Id *uint `json:"employee_id"`
- IHS_Number *string `json:"ihs_number"`
-
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+ Employee_Id *uint `json:"employee-id"`
+ IHS_Number *string `json:"ihs-number"`
}
type ReadDetailDto struct {
diff --git a/internal/domain/main-entities/nutritionist/entity.go b/internal/domain/main-entities/nutritionist/entity.go
index 8956b8b4..be431f66 100644
--- a/internal/domain/main-entities/nutritionist/entity.go
+++ b/internal/domain/main-entities/nutritionist/entity.go
@@ -9,5 +9,5 @@ type Nutritionist struct {
ecore.Main // adjust this according to the needs
Employee_Id *uint `json:"employee_id"`
Employee *ee.Employee `json:"employee,omitempty" gorm:"foreignKey:Employee_Id;references:Id"`
- IHS_Number *string `json:"ihs_number" gorm:"size:20"`
+ IHS_Number *string `json:"ihs_number" gorm:"unique;size:20"`
}
diff --git a/internal/domain/main-entities/patient/dto.go b/internal/domain/main-entities/patient/dto.go
index c0eee96a..00134b6e 100644
--- a/internal/domain/main-entities/patient/dto.go
+++ b/internal/domain/main-entities/patient/dto.go
@@ -1,43 +1,44 @@
package patient
import (
+ "mime/multipart"
+ "time"
+
ecore "simrs-vx/internal/domain/base-entities/core"
ep "simrs-vx/internal/domain/main-entities/person"
epa "simrs-vx/internal/domain/main-entities/person-address"
epc "simrs-vx/internal/domain/main-entities/person-contact"
+ epi "simrs-vx/internal/domain/main-entities/person-insurance"
epr "simrs-vx/internal/domain/main-entities/person-relative"
+
erc "simrs-vx/internal/domain/references/common"
- ero "simrs-vx/internal/domain/references/organization"
- "time"
+ ere "simrs-vx/internal/domain/references/encounter"
)
type CreateDto struct {
- Person_Id *uint `json:"-"`
- Person *ep.UpdateDto `json:"person"`
- PersonAddresses []epa.UpdateDto `json:"personAddresses"`
- PersonContacts []epc.UpdateDto `json:"personContacts"`
- PersonRelatives []epr.UpdateDto `json:"personRelatives"`
- RegisteredAt *time.Time `json:"registeredAt"`
- Status_Code erc.ActiveStatusCode `json:"status_code" validate:"maxLength=10"`
+ Person_Id *uint `json:"-"`
+ Person *ep.UpdateDto `json:"person"`
+ NewBornStatus bool `json:"newBornStatus"`
+ PersonAddresses []epa.UpdateDto `json:"personAddresses"`
+ PersonContacts []epc.UpdateDto `json:"personContacts"`
+ PersonRelatives []epr.UpdateDto `json:"personRelatives"`
+ PersonInsurances []epi.UpdateDto `json:"personInsurances"`
+ RegisteredAt *time.Time `json:"registeredAt"`
+ Status_Code erc.ActiveStatusCode `json:"status_code" validate:"maxLength=10"`
}
type ReadListDto struct {
FilterDto
- Includes string `json:"includes"`
- Preloads []string `json:"-"`
+ Includes string `json:"includes"`
+ Pagination ecore.Pagination
}
type FilterDto struct {
- Person_Id *uint `json:"person_id"`
- Position_Code ero.EmployeePosisitionCode `json:"position_code"`
- Division_Code *string `json:"division_code"`
- RegisteredAt *time.Time `json:"registeredAt"`
- Status_Code erc.ActiveStatusCode `json:"status_code"`
- Number *string `json:"number"`
-
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+ Person_Id *uint `json:"person-id"`
+ NewBornStatus *bool `json:"newBornStatus"`
+ RegisteredAt *time.Time `json:"registeredAt"`
+ Status_Code erc.ActiveStatusCode `json:"status-code"`
+ Number *string `json:"number"`
}
type ReadDetailDto struct {
@@ -55,6 +56,22 @@ type DeleteDto struct {
Id uint `json:"id"`
}
+type SearchDto struct {
+ Search string `json:"search"`
+ Mode SearchMode `json:"mode"`
+}
+
+type UploadDto struct {
+ Id uint `json:"-"`
+ Code ere.UploadCode `json:"-"`
+ File multipart.File `json:"-"`
+ FileHeader *multipart.FileHeader `json:"-"`
+ Filename string `json:"-"`
+ Size int64 `json:"-"`
+ MimeType string `json:"-"`
+ MedRecNumber string `json:"-"`
+}
+
type MetaDto struct {
PageNumber int `json:"page_number"`
PageSize int `json:"page_size"`
@@ -63,20 +80,22 @@ type MetaDto struct {
type ResponseDto struct {
ecore.Main
- Person_Id *uint `json:"person_id"`
- Person *ep.Person `json:"person,omitempty"`
- RegisteredAt *time.Time `json:"registeredAt"`
- Status_Code erc.ActiveStatusCode `json:"status_code"`
- Number *string `json:"number"`
+ Person_Id *uint `json:"person_id"`
+ Person *ep.Person `json:"person,omitempty"`
+ NewBornStatus bool `json:"newBornStatus"`
+ RegisteredAt *time.Time `json:"registeredAt"`
+ Status_Code erc.ActiveStatusCode `json:"status_code"`
+ Number *string `json:"number"`
}
func (d Patient) ToResponse() ResponseDto {
resp := ResponseDto{
- Person_Id: d.Person_Id,
- Person: d.Person,
- RegisteredAt: d.RegisteredAt,
- Status_Code: d.Status_Code,
- Number: d.Number,
+ Person_Id: d.Person_Id,
+ Person: d.Person,
+ NewBornStatus: d.NewBornStatus,
+ RegisteredAt: d.RegisteredAt,
+ Status_Code: d.Status_Code,
+ Number: d.Number,
}
resp.Main = d.Main
return resp
diff --git a/internal/domain/main-entities/patient/entity.go b/internal/domain/main-entities/patient/entity.go
index fbe4647a..491140cd 100644
--- a/internal/domain/main-entities/patient/entity.go
+++ b/internal/domain/main-entities/patient/entity.go
@@ -8,10 +8,11 @@ import (
)
type Patient struct {
- ecore.Main // adjust this according to the needs
- Person_Id *uint `json:"person_id"`
- Person *ep.Person `json:"person,omitempty" gorm:"foreignKey:Person_Id;references:Id"`
- RegisteredAt *time.Time `json:"registeredAt"`
- Status_Code erc.ActiveStatusCode `json:"status_code" gorm:"not null;size:10"`
- Number *string `json:"number" gorm:"size:15"`
+ ecore.Main // adjust this according to the needs
+ Person_Id *uint `json:"person_id"`
+ Person *ep.Person `json:"person,omitempty" gorm:"foreignKey:Person_Id;references:Id"`
+ NewBornStatus bool `json:"newBornStatus"`
+ RegisteredAt *time.Time `json:"registeredAt"`
+ Status_Code erc.ActiveStatusCode `json:"status_code" gorm:"not null;size:10"`
+ Number *string `json:"number" gorm:"unique;size:15"`
}
diff --git a/internal/domain/main-entities/patient/tycovar.go b/internal/domain/main-entities/patient/tycovar.go
new file mode 100644
index 00000000..aa419b57
--- /dev/null
+++ b/internal/domain/main-entities/patient/tycovar.go
@@ -0,0 +1,8 @@
+package patient
+
+type SearchMode string
+
+const (
+ SMNik SearchMode = "resident-identity"
+ SMIdent SearchMode = "identifier"
+)
diff --git a/internal/domain/main-entities/person-address/dto.go b/internal/domain/main-entities/person-address/dto.go
index 5f5dad52..64be2822 100644
--- a/internal/domain/main-entities/person-address/dto.go
+++ b/internal/domain/main-entities/person-address/dto.go
@@ -2,20 +2,24 @@ package personaddress
import (
ecore "simrs-vx/internal/domain/base-entities/core"
+ epr "simrs-vx/internal/domain/main-entities/postal-region"
+ ev "simrs-vx/internal/domain/main-entities/village"
+
+ erp "simrs-vx/internal/domain/references/person"
)
type CreateDto struct {
- Person_Id uint `json:"person_id"`
- Address string `json:"address" validate:"maxLength=150"`
- Rt string `json:"rt" validate:"maxLength=2"`
- Rw string `json:"rw" validate:"maxLength=2"`
- Village_Code string `json:"village_code" validate:"maxLength=10"`
+ Person_Id uint `json:"person_id"`
+ LocationType_Code erp.AddressLocationTypeCode `json:"locationType_code" validate:"maxLength=10"`
+ Address string `json:"address" validate:"maxLength=150"`
+ Rt string `json:"rt" validate:"maxLength=2"`
+ Rw string `json:"rw" validate:"maxLength=2"`
+ PostalRegion_Code *string `json:"postalRegion_code" validate:"maxLength=6"`
+ Village_Code *string `json:"village_code" validate:"maxLength=10"`
}
type ReadListDto struct {
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+ Pagination ecore.Pagination
}
type ReadDetailDto struct {
@@ -40,20 +44,28 @@ type MetaDto struct {
type ResponseDto struct {
ecore.Main
- Person_Id uint `json:"person_id"`
- Address string `json:"address"`
- Rt string `json:"rt"`
- Rw string `json:"rw"`
- Village_Code string `json:"village_code"`
+ Person_Id uint `json:"person_id"`
+ LocationType_Code erp.AddressLocationTypeCode `json:"locationType_code"`
+ Address string `json:"address"`
+ Rt string `json:"rt"`
+ Rw string `json:"rw"`
+ PostalRegion_Code *string `json:"postalRegion_code"`
+ PostalRegion *epr.PostalRegion `json:"postalRegion,omitempty"`
+ Village_Code *string `json:"village_code"`
+ Village *ev.Village `json:"village,omitempty"`
}
func (d PersonAddress) ToResponse() ResponseDto {
resp := ResponseDto{
- Person_Id: d.Person_Id,
- Address: d.Address,
- Rt: d.Rt,
- Rw: d.Rw,
- Village_Code: d.Village_Code,
+ Person_Id: d.Person_Id,
+ LocationType_Code: d.LocationType_Code,
+ Address: d.Address,
+ Rt: d.Rt,
+ Rw: d.Rw,
+ PostalRegion_Code: d.PostalRegion_Code,
+ PostalRegion: d.PostalRegion,
+ Village_Code: d.Village_Code,
+ Village: d.Village,
}
resp.Main = d.Main
return resp
diff --git a/internal/domain/main-entities/person-address/entity.go b/internal/domain/main-entities/person-address/entity.go
index 960b32a9..65d71912 100644
--- a/internal/domain/main-entities/person-address/entity.go
+++ b/internal/domain/main-entities/person-address/entity.go
@@ -2,13 +2,21 @@ package personaddress
import (
ecore "simrs-vx/internal/domain/base-entities/core"
+ epr "simrs-vx/internal/domain/main-entities/postal-region"
+ ev "simrs-vx/internal/domain/main-entities/village"
+
+ erp "simrs-vx/internal/domain/references/person"
)
type PersonAddress struct {
- ecore.Main // adjust this according to the needs
- Person_Id uint `json:"person_id"`
- Address string `json:"address" gorm:"size:150"`
- Rt string `json:"rt" gorm:"size:2"`
- Rw string `json:"rw" gorm:"size:2"`
- Village_Code string `json:"village_code" gorm:"size:10"`
+ ecore.Main // adjust this according to the needs
+ Person_Id uint `json:"person_id"`
+ Address string `json:"address" gorm:"size:150"`
+ LocationType_Code erp.AddressLocationTypeCode `json:"locationType_code" gorm:"size:10"`
+ Rt string `json:"rt" gorm:"size:2"`
+ Rw string `json:"rw" gorm:"size:2"`
+ PostalRegion_Code *string `json:"postalRegion_code" gorm:"size:6"`
+ PostalRegion *epr.PostalRegion `json:"postalRegion,omitempty" gorm:"foreignKey:PostalRegion_Code;references:Code"`
+ Village_Code *string `json:"village_code" gorm:"size:10"`
+ Village *ev.Village `json:"village,omitempty" gorm:"foreignKey:Village_Code;references:Code"`
}
diff --git a/internal/domain/main-entities/person-contact/dto.go b/internal/domain/main-entities/person-contact/dto.go
index c2b684e2..577d3776 100644
--- a/internal/domain/main-entities/person-contact/dto.go
+++ b/internal/domain/main-entities/person-contact/dto.go
@@ -12,9 +12,7 @@ type CreateDto struct {
}
type ReadListDto struct {
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+ Pagination ecore.Pagination
}
type ReadDetailDto struct {
diff --git a/internal/domain/main-entities/person-insurance/dto.go b/internal/domain/main-entities/person-insurance/dto.go
new file mode 100644
index 00000000..e811023d
--- /dev/null
+++ b/internal/domain/main-entities/person-insurance/dto.go
@@ -0,0 +1,75 @@
+package personinsurance
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ei "simrs-vx/internal/domain/main-entities/insurance-company"
+)
+
+type CreateDto struct {
+ Person_Id uint `json:"person_id"`
+ InsuranceCompany_Id *uint `json:"insurance_id"`
+ Ref_Number *string `json:"ref_number" gorm:"unique;size:20"`
+ DefaultStatus *bool `json:"default_status" gorm:"uniqueIndex:idx_person_insurance"`
+}
+
+type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Sort string `json:"sort"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ Person_Id *uint `json:"person-id"`
+ InsuranceCompany_Id *uint `json:"insurance-company-id"`
+ Ref_Number *string `json:"ref-number"`
+ DefaultStatus *bool `json:"default-status"`
+}
+
+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
+ Person_Id *uint `json:"person_id"`
+ InsuranceCompany_Id *uint `json:"insuranceCompany_id"`
+ InsuranceCompany *ei.InsuranceCompany `json:"insuranceCompany,omitempty"`
+ Ref_Number *string `json:"ref_number"`
+ DefaultStatus *bool `json:"defaultStatus"`
+}
+
+func (d PersonInsurance) ToResponse() ResponseDto {
+ resp := ResponseDto{
+ Person_Id: d.Person_Id,
+ InsuranceCompany_Id: d.InsuranceCompany_Id,
+ InsuranceCompany: d.InsuranceCompany,
+ Ref_Number: d.Ref_Number,
+ DefaultStatus: d.DefaultStatus,
+ }
+ resp.Main = d.Main
+ return resp
+}
+
+func ToResponseList(data []PersonInsurance) []ResponseDto {
+ resp := make([]ResponseDto, len(data))
+ for i, u := range data {
+ resp[i] = u.ToResponse()
+ }
+ return resp
+}
diff --git a/internal/domain/main-entities/person-insurance/entity.go b/internal/domain/main-entities/person-insurance/entity.go
new file mode 100644
index 00000000..64057835
--- /dev/null
+++ b/internal/domain/main-entities/person-insurance/entity.go
@@ -0,0 +1,15 @@
+package personinsurance
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ei "simrs-vx/internal/domain/main-entities/insurance-company"
+)
+
+type PersonInsurance struct {
+ ecore.Main
+ Person_Id *uint `json:"person_id" gorm:"uniqueIndex:idx_person_insurance"`
+ InsuranceCompany_Id *uint `json:"insurance_id"`
+ InsuranceCompany *ei.InsuranceCompany `json:"insurance,omitempty" gorm:"foreignKey:InsuranceCompany_Id;references:Id"`
+ Ref_Number *string `json:"ref_number" gorm:"unique;size:20"`
+ DefaultStatus *bool `json:"default_status" gorm:"uniqueIndex:idx_person_insurance"`
+}
diff --git a/internal/domain/main-entities/person-relative/dto.go b/internal/domain/main-entities/person-relative/dto.go
index 4b870771..f56e68c7 100644
--- a/internal/domain/main-entities/person-relative/dto.go
+++ b/internal/domain/main-entities/person-relative/dto.go
@@ -17,30 +17,28 @@ type CreateDto struct {
Education_Code *erp.EducationCode `json:"education_code" validate:"maxLength=10"`
Occupation_Code *erp.OcupationCode `json:"occupation_code" validate:"maxLength=10"`
Occupation_Name *string `json:"occupation_name" validate:"maxLength=50"`
+ Responsible bool `json:"responsible"`
}
type ReadListDto struct {
FilterDto
- Includes string `json:"includes"`
- Preloads []string `json:"-"`
+ Includes string `json:"includes"`
+ Preloads []string `json:"-"`
+ Pagination ecore.Pagination
}
type FilterDto struct {
- Person_Id uint `json:"person_id"`
- Relationship_Code erp.RelationshipCode `json:"relationship_code" `
+ Person_Id uint `json:"person-id"`
+ Relationship_Code erp.RelationshipCode `json:"relationship-code" `
Name *string `json:"name"`
Address *string `json:"address"`
- Village_Code *string `json:"village_code"`
- Village *ev.Village `json:"village,omitempty"`
- Gender_Code *erp.GenderCode `json:"gender_code"`
+ Village_Code *string `json:"village-code"`
+ Gender_Code *erp.GenderCode `json:"gender-code"`
PhoneNumber *string `json:"phoneNumber"`
- Education_Code *erp.EducationCode `json:"education_code"`
- Occupation_Code *erp.OcupationCode `json:"occupation_code"`
- Occupation_Name *string `json:"occupation_name"`
-
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+ Education_Code *erp.EducationCode `json:"education-code"`
+ Occupation_Code *erp.OcupationCode `json:"occupation-code"`
+ Occupation_Name *string `json:"occupation-name"`
+ Responsible bool `json:"responsible"`
}
type ReadDetailDto struct {
@@ -78,10 +76,24 @@ type ResponseDto struct {
Education_Code *erp.EducationCode `json:"education_code"`
Occupation_Code *erp.OcupationCode `json:"occupation_code"`
Occupation_Name *string `json:"occupation_name"`
+ Responsible bool `json:"responsible"`
}
func (d *PersonRelative) ToResponse() ResponseDto {
- resp := ResponseDto{}
+ resp := ResponseDto{
+ Person_Id: d.Person_Id,
+ Relationship_Code: d.Relationship_Code,
+ Name: d.Name,
+ Address: d.Address,
+ Village_Code: d.Village_Code,
+ Village: d.Village,
+ Gender_Code: d.Gender_Code,
+ PhoneNumber: d.PhoneNumber,
+ Education_Code: d.Education_Code,
+ Occupation_Code: d.Occupation_Code,
+ Occupation_Name: d.Occupation_Name,
+ Responsible: d.Responsible,
+ }
resp.Main = d.Main
return resp
}
diff --git a/internal/domain/main-entities/person-relative/entity.go b/internal/domain/main-entities/person-relative/entity.go
index 9b67bd0b..3f83aa23 100644
--- a/internal/domain/main-entities/person-relative/entity.go
+++ b/internal/domain/main-entities/person-relative/entity.go
@@ -19,4 +19,5 @@ type PersonRelative struct {
Education_Code *erp.EducationCode `json:"education_code" gorm:"size:10"`
Occupation_Code *erp.OcupationCode `json:"occupation_code" gorm:"size:10"`
Occupation_Name *string `json:"occupation_name" gorm:"size:50"`
+ Responsible bool `json:"responsible"`
}
diff --git a/internal/domain/main-entities/person/dto.go b/internal/domain/main-entities/person/dto.go
index bab22944..7fb6a235 100644
--- a/internal/domain/main-entities/person/dto.go
+++ b/internal/domain/main-entities/person/dto.go
@@ -1,59 +1,64 @@
package person
import (
+ "time"
+
ecore "simrs-vx/internal/domain/base-entities/core"
ee "simrs-vx/internal/domain/main-entities/ethnic"
epa "simrs-vx/internal/domain/main-entities/person-address"
epc "simrs-vx/internal/domain/main-entities/person-contact"
epr "simrs-vx/internal/domain/main-entities/person-relative"
+ er "simrs-vx/internal/domain/main-entities/regency"
+
erp "simrs-vx/internal/domain/references/person"
- "time"
)
type CreateDto struct {
- Name string `json:"name" validate:"maxLength=150"`
- FrontTitle *string `json:"frontTitle" validate:"maxLength=50"`
- EndTitle *string `json:"endTitle" validate:"maxLength=50"`
- BirthDate *time.Time `json:"birthDate,omitempty"`
- BirthRegency_Code *string `json:"birthRegency_code" validate:"maxLength=4"`
- Gender_Code *erp.GenderCode `json:"gender_code"`
- ResidentIdentityNumber *string `json:"residentIdentityNumber" validate:"nik;maxLength=16"`
- PassportNumber *string `json:"passportNumber" validate:"maxLength=20"`
- DrivingLicenseNumber *string `json:"drivingLicenseNumber" validate:"maxLength=20"`
- Religion_Code *erp.ReligionCode `json:"religion_code" validate:"maxLength=10"`
- Education_Code *erp.EducationCode `json:"education_code" validate:"maxLength=10"`
- Ocupation_Code *erp.OcupationCode `json:"occupation_code" validate:"maxLength=15"`
- Ocupation_Name *string `json:"occupation_name" validate:"maxLength=50"`
- Ethnic_Code *string `json:"ethnic_code" validate:"maxLength=20"`
- Language_Code *string `json:"language_code" validate:"maxLength=10"`
+ Name string `json:"name" validate:"maxLength=150"`
+ FrontTitle *string `json:"frontTitle" validate:"maxLength=50"`
+ EndTitle *string `json:"endTitle" validate:"maxLength=50"`
+ BirthDate *time.Time `json:"birthDate,omitempty"`
+ BirthRegency_Code *string `json:"birthRegency_code" validate:"maxLength=4"`
+ Gender_Code *erp.GenderCode `json:"gender_code"`
+ ResidentIdentityNumber *string `json:"residentIdentityNumber" validate:"nik;maxLength=16"`
+ PassportNumber *string `json:"passportNumber" validate:"maxLength=20"`
+ DrivingLicenseNumber *string `json:"drivingLicenseNumber" validate:"maxLength=20"`
+ Religion_Code *erp.ReligionCode `json:"religion_code" validate:"maxLength=10"`
+ Education_Code *erp.EducationCode `json:"education_code" validate:"maxLength=10"`
+ Ocupation_Code *erp.OcupationCode `json:"occupation_code" validate:"maxLength=15"`
+ Ocupation_Name *string `json:"occupation_name" validate:"maxLength=50"`
+ Nationality *string `json:"nationality" validate:"maxLength=50"`
+ Ethnic_Code *string `json:"ethnic_code" validate:"maxLength=20"`
+ Language_Code *string `json:"language_code" validate:"maxLength=10"`
+ CommunicationIssueStatus bool `json:"communicationIssueStatus"`
+ Disability *string `json:"disability" validate:"maxLength=100"`
}
type ReadListDto struct {
FilterDto
- Includes string `json:"includes"`
- Preloads []string `json:"-"`
+ Includes string `json:"includes"`
+ Pagination ecore.Pagination
}
type FilterDto struct {
- Name string `json:"name"`
- FrontTitle *string `json:"frontTitle"`
- EndTitle *string `json:"endTitle"`
- BirthDate *time.Time `json:"birthDate,omitempty"`
- BirthRegency_Code *string `json:"birthRegency_code"`
- Gender_Code *erp.GenderCode `json:"gender_code"`
- ResidentIdentityNumber *string `json:"residentIdentityNumber"`
- PassportNumber *string `json:"passportNumber"`
- DrivingLicenseNumber *string `json:"drivingLicenseNumber"`
- Religion_Code *erp.ReligionCode `json:"religion_code"`
- Education_Code *erp.EducationCode `json:"education_code"`
- Ocupation_Code *erp.OcupationCode `json:"occupation_code"`
- Ocupation_Name *string `json:"occupation_name"`
- Ethnic_Code *string `json:"ethnic_code"`
- Language_Code *string `json:"language_code"`
-
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+ Name string `json:"name"`
+ FrontTitle *string `json:"frontTitle"`
+ EndTitle *string `json:"endTitle"`
+ BirthDate *time.Time `json:"birthDate,omitempty"`
+ BirthRegency_Code *string `json:"birthRegency-code"`
+ Gender_Code *erp.GenderCode `json:"gender-code"`
+ ResidentIdentityNumber *string `json:"residentIdentityNumber"`
+ PassportNumber *string `json:"passportNumber"`
+ DrivingLicenseNumber *string `json:"drivingLicenseNumber"`
+ Religion_Code *erp.ReligionCode `json:"religion-code"`
+ Education_Code *erp.EducationCode `json:"education-code"`
+ Ocupation_Code *erp.OcupationCode `json:"occupation-code"`
+ Ocupation_Name *string `json:"occupation-name"`
+ Nationality *string `json:"nationality"`
+ Ethnic_Code *string `json:"ethnic-code"`
+ Language_Code *string `json:"language-code"`
+ CommunicationIssueStatus bool `json:"communicationIssueStatus"`
+ Disability *string `json:"disability"`
}
type ReadDetailDto struct {
@@ -81,48 +86,64 @@ type MetaDto struct {
type ResponseDto struct {
ecore.Main
- Name string `json:"name"`
- FrontTitle *string `json:"frontTitle"`
- EndTitle *string `json:"endTitle"`
- BirthDate *time.Time `json:"birthDate,omitempty"`
- BirthRegency_Code *string `json:"birthRegency_code"`
- Gender_Code *erp.GenderCode `json:"gender_code"`
- ResidentIdentityNumber *string `json:"residentIdentityNumber"`
- PassportNumber *string `json:"passportNumber"`
- DrivingLicenseNumber *string `json:"drivingLicenseNumber"`
- Religion_Code *erp.ReligionCode `json:"religion_code"`
- Education_Code *erp.EducationCode `json:"education_code"`
- Ocupation_Code *erp.OcupationCode `json:"occupation_code"`
- Ocupation_Name *string `json:"occupation_name"`
- Ethnic_Code *string `json:"ethnic_code"`
- Ethnic *ee.Ethnic `json:"ethnic,omitempty"`
- Addresses *[]epa.PersonAddress `json:"addresses,omitempty"`
- Contacts *[]epc.PersonContact `json:"contacts,omitempty"`
- Relatives *[]epr.PersonRelative `json:"relatives,omitempty"`
- Language_Code *string `json:"language_code"`
+ Name string `json:"name"`
+ FrontTitle *string `json:"frontTitle"`
+ EndTitle *string `json:"endTitle"`
+ BirthDate *time.Time `json:"birthDate,omitempty"`
+ BirthRegency_Code *string `json:"birthRegency_code"`
+ BirthRegency *er.Regency `json:"birthRegency,omitempty"`
+ Gender_Code *erp.GenderCode `json:"gender_code"`
+ ResidentIdentityNumber *string `json:"residentIdentityNumber"`
+ PassportNumber *string `json:"passportNumber"`
+ DrivingLicenseNumber *string `json:"drivingLicenseNumber"`
+ Religion_Code *erp.ReligionCode `json:"religion_code"`
+ Education_Code *erp.EducationCode `json:"education_code"`
+ Ocupation_Code *erp.OcupationCode `json:"occupation_code"`
+ Ocupation_Name *string `json:"occupation_name"`
+ Nationality *string `json:"nationality"`
+ Ethnic_Code *string `json:"ethnic_code"`
+ Ethnic *ee.Ethnic `json:"ethnic,omitempty"`
+ Addresses *[]epa.PersonAddress `json:"addresses,omitempty"`
+ Contacts *[]epc.PersonContact `json:"contacts,omitempty"`
+ Relatives *[]epr.PersonRelative `json:"relatives,omitempty"`
+ Language_Code *string `json:"language_code"`
+ CommunicationIssueStatus bool `json:"communicationIssueStatus"`
+ Disability *string `json:"disability"`
+ ResidentIdentityFileUrl *string `json:"residentIdentityFileUrl"`
+ PassportFileUrl *string `json:"passportFileUrl"`
+ DrivingLicenseFileUrl *string `json:"drivingLicenseFileUrl"`
+ FamilyIdentityFileUrl *string `json:"familyIdentityFileUrl"`
}
func (d *Person) ToResponse() ResponseDto {
resp := ResponseDto{
- Name: d.Name,
- FrontTitle: d.FrontTitle,
- EndTitle: d.EndTitle,
- BirthDate: d.BirthDate,
- BirthRegency_Code: d.BirthRegency_Code,
- Gender_Code: d.Gender_Code,
- ResidentIdentityNumber: d.ResidentIdentityNumber,
- PassportNumber: d.PassportNumber,
- DrivingLicenseNumber: d.DrivingLicenseNumber,
- Religion_Code: d.Religion_Code,
- Education_Code: d.Education_Code,
- Ocupation_Code: d.Ocupation_Code,
- Ocupation_Name: d.Ocupation_Name,
- Ethnic_Code: d.Ethnic_Code,
- Ethnic: d.Ethnic,
- Addresses: d.Addresses,
- Contacts: d.Contacts,
- Relatives: d.Relatives,
- Language_Code: d.Language_Code,
+ Name: d.Name,
+ FrontTitle: d.FrontTitle,
+ EndTitle: d.EndTitle,
+ BirthDate: d.BirthDate,
+ BirthRegency_Code: d.BirthRegency_Code,
+ BirthRegency: d.BirthRegency,
+ Gender_Code: d.Gender_Code,
+ ResidentIdentityNumber: d.ResidentIdentityNumber,
+ PassportNumber: d.PassportNumber,
+ DrivingLicenseNumber: d.DrivingLicenseNumber,
+ Religion_Code: d.Religion_Code,
+ Education_Code: d.Education_Code,
+ Ocupation_Code: d.Ocupation_Code,
+ Ocupation_Name: d.Ocupation_Name,
+ Nationality: d.Nationality,
+ Ethnic_Code: d.Ethnic_Code,
+ Ethnic: d.Ethnic,
+ Addresses: d.Addresses,
+ Contacts: d.Contacts,
+ Relatives: d.Relatives,
+ Language_Code: d.Language_Code,
+ CommunicationIssueStatus: d.CommunicationIssueStatus,
+ Disability: d.Disability,
+ ResidentIdentityFileUrl: d.ResidentIdentityFileUrl,
+ PassportFileUrl: d.PassportFileUrl,
+ DrivingLicenseFileUrl: d.DrivingLicenseFileUrl,
+ FamilyIdentityFileUrl: d.FamilyIdentityFileUrl,
}
resp.Main = d.Main
return resp
diff --git a/internal/domain/main-entities/person/entity.go b/internal/domain/main-entities/person/entity.go
index eb3bab27..8932ca1b 100644
--- a/internal/domain/main-entities/person/entity.go
+++ b/internal/domain/main-entities/person/entity.go
@@ -6,34 +6,46 @@ import (
el "simrs-vx/internal/domain/main-entities/language"
epa "simrs-vx/internal/domain/main-entities/person-address"
epc "simrs-vx/internal/domain/main-entities/person-contact"
+ epi "simrs-vx/internal/domain/main-entities/person-insurance"
epr "simrs-vx/internal/domain/main-entities/person-relative"
+ er "simrs-vx/internal/domain/main-entities/regency"
+
erp "simrs-vx/internal/domain/references/person"
"time"
)
type Person struct {
- ecore.Main // adjust this according to the needs
- Name string `json:"name" gorm:"not null;size:150"`
- FrontTitle *string `json:"frontTitle" gorm:"size:50"`
- EndTitle *string `json:"endTitle" gorm:"size:50"`
- BirthDate *time.Time `json:"birthDate,omitempty"`
- BirthRegency_Code *string `json:"birthRegency_code" gorm:"size:4"`
- Gender_Code *erp.GenderCode `json:"gender_code" gorm:"size:10"`
- ResidentIdentityNumber *string `json:"residentIdentityNumber" gorm:"unique;size:16"`
- PassportNumber *string `json:"passportNumber" gorm:"unique;size:20"`
- DrivingLicenseNumber *string `json:"drivingLicenseNumber" gorm:"unique;size:20"`
- Religion_Code *erp.ReligionCode `json:"religion_code" gorm:"size:10"`
- Education_Code *erp.EducationCode `json:"education_code" gorm:"size:10"`
- Ocupation_Code *erp.OcupationCode `json:"occupation_code" gorm:"size:15"`
- Ocupation_Name *string `json:"occupation_name" gorm:"size:50"`
- Ethnic_Code *string `json:"ethnic_code" gorm:"size:20"`
- Ethnic *ee.Ethnic `json:"ethnic,omitempty" gorm:"foreignKey:Ethnic_Code;references:Code"`
- Addresses *[]epa.PersonAddress `json:"addresses" gorm:"foreignKey:Person_Id"`
- Contacts *[]epc.PersonContact `json:"contacts" gorm:"foreignKey:Person_Id"`
- Relatives *[]epr.PersonRelative `json:"relatives" gorm:"foreignKey:Person_Id"`
- Language_Code *string `json:"language_code" gorm:"size:10"`
- Language *el.Language `json:"language,omitempty" gorm:"foreignKey:Language_Code;references:Code"`
+ ecore.Main // adjust this according to the needs
+ Name string `json:"name" gorm:"not null;size:150"`
+ FrontTitle *string `json:"frontTitle" gorm:"size:50"`
+ EndTitle *string `json:"endTitle" gorm:"size:50"`
+ BirthDate *time.Time `json:"birthDate,omitempty"`
+ BirthRegency_Code *string `json:"birthRegency_code" gorm:"size:4"`
+ BirthRegency *er.Regency `json:"birthRegency,omitempty" gorm:"foreignKey:BirthRegency_Code;references:Code"`
+ Gender_Code *erp.GenderCode `json:"gender_code" gorm:"size:10"`
+ ResidentIdentityNumber *string `json:"residentIdentityNumber" gorm:"unique;size:16"`
+ PassportNumber *string `json:"passportNumber" gorm:"unique;size:20"`
+ DrivingLicenseNumber *string `json:"drivingLicenseNumber" gorm:"unique;size:20"`
+ Religion_Code *erp.ReligionCode `json:"religion_code" gorm:"size:10"`
+ Education_Code *erp.EducationCode `json:"education_code" gorm:"size:10"`
+ Ocupation_Code *erp.OcupationCode `json:"occupation_code" gorm:"size:15"`
+ Ocupation_Name *string `json:"occupation_name" gorm:"size:50"`
+ Nationality *string `json:"nationality": gorm:"size:50"`
+ Ethnic_Code *string `json:"ethnic_code" gorm:"size:20"`
+ Ethnic *ee.Ethnic `json:"ethnic,omitempty" gorm:"foreignKey:Ethnic_Code;references:Code"`
+ Language_Code *string `json:"language_code" gorm:"size:10"`
+ Language *el.Language `json:"language,omitempty" gorm:"foreignKey:Language_Code;references:Code"`
+ CommunicationIssueStatus bool `json:"communicationIssueStatus"`
+ Disability *string `json:"disability" gorm:"size:100"`
+ ResidentIdentityFileUrl *string `json:"residentIdentityFileUrl" gorm:"size:1024"`
+ PassportFileUrl *string `json:"passportFileUrl" gorm:"size:1024"`
+ DrivingLicenseFileUrl *string `json:"drivingLicenseFileUrl" gorm:"size:1024"`
+ FamilyIdentityFileUrl *string `json:"familyIdentityFileUrl" gorm:"size:1024"`
+ Addresses *[]epa.PersonAddress `json:"addresses" gorm:"foreignKey:Person_Id"`
+ Contacts *[]epc.PersonContact `json:"contacts" gorm:"foreignKey:Person_Id"`
+ Relatives *[]epr.PersonRelative `json:"relatives" gorm:"foreignKey:Person_Id"`
+ Insurances *[]epi.PersonInsurance `json:"insurances" gorm:"foreignKey:Person_Id"`
}
func (d Person) IsSameResidentIdentityNumber(input *string) bool {
diff --git a/internal/domain/main-entities/pharmacist/dto.go b/internal/domain/main-entities/pharmacist/dto.go
index 39ba0d85..4a04f8d2 100644
--- a/internal/domain/main-entities/pharmacist/dto.go
+++ b/internal/domain/main-entities/pharmacist/dto.go
@@ -12,17 +12,13 @@ type CreateDto struct {
type ReadListDto struct {
FilterDto
- Includes string `json:"includes"`
- Preloads []string `json:"-"`
+ Includes string `json:"includes"`
+ Pagination ecore.Pagination
}
type FilterDto struct {
- Employee_Id *uint `json:"employee_id"`
- IHS_Number *string `json:"ihs_number"`
-
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+ Employee_Id *uint `json:"employee-id"`
+ IHS_Number *string `json:"ihs-number"`
}
type ReadDetailDto struct {
diff --git a/internal/domain/main-entities/pharmacist/entity.go b/internal/domain/main-entities/pharmacist/entity.go
index 352fa9ba..318cc97e 100644
--- a/internal/domain/main-entities/pharmacist/entity.go
+++ b/internal/domain/main-entities/pharmacist/entity.go
@@ -9,5 +9,5 @@ type Pharmacist struct {
ecore.Main // adjust this according to the needs
Employee_Id *uint `json:"employee_id"`
Employee *ee.Employee `json:"employee,omitempty" gorm:"foreignKey:Employee_Id;references:Id"`
- IHS_Number *string `json:"ihs_number" gorm:"size:20"`
+ IHS_Number *string `json:"ihs_number" gorm:"unique;size:20"`
}
diff --git a/internal/domain/main-entities/pharmacy-company/dto.go b/internal/domain/main-entities/pharmacy-company/dto.go
index 138c58ad..2bb7e1ac 100644
--- a/internal/domain/main-entities/pharmacy-company/dto.go
+++ b/internal/domain/main-entities/pharmacy-company/dto.go
@@ -11,13 +11,17 @@ type CreateDto struct {
}
type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Sort string `json:"sort"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
Code string `json:"code"`
Name string `json:"name"`
- Regency_Code string `json:"regency_code"`
-
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+ Regency_Code string `json:"regency-code"`
+ Search string `json:"search" gormhelper:"searchColumns=Code,Name"`
}
type ReadDetailDto struct {
diff --git a/internal/domain/main-entities/postal-region/base/entity.go b/internal/domain/main-entities/postal-region/base/entity.go
new file mode 100644
index 00000000..6cec2766
--- /dev/null
+++ b/internal/domain/main-entities/postal-region/base/entity.go
@@ -0,0 +1,11 @@
+package base
+
+type Basic struct {
+ Id uint32 `json:"id" gorm:"primaryKey"`
+ Village_Code string `json:"village_code" gorm:"size:10"`
+ Code string `json:"code" gorm:"unique;size:5"`
+}
+
+func (Basic) TableName() string {
+ return "PostalRegion"
+}
diff --git a/internal/domain/main-entities/postal-region/dto.go b/internal/domain/main-entities/postal-region/dto.go
new file mode 100644
index 00000000..bc3a0fdc
--- /dev/null
+++ b/internal/domain/main-entities/postal-region/dto.go
@@ -0,0 +1,69 @@
+package postalregion
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ev "simrs-vx/internal/domain/main-entities/village"
+)
+
+type CreateDto struct {
+ Code string `json:"code" validate:"numeric;maxLength=5"`
+ Village_Code string `json:"village_code" validate:"numeric;maxLength=10"`
+}
+
+type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Sort string `json:"sort"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ Village_Code string `json:"village-code"`
+ Code string `json:"code"`
+ Search string `json:"search" gormhelper:"searchColumns=Code"`
+}
+
+type ReadDetailDto struct {
+ Id uint32 `json:"id"`
+ Code *string `json:"code"`
+}
+
+type UpdateDto struct {
+ Id uint32 `json:"id"`
+ CreateDto
+}
+
+type DeleteDto struct {
+ Id uint32 `json:"id"`
+}
+
+type MetaDto struct {
+ PageNumber int `json:"page_number"`
+ PageSize int `json:"page_size"`
+ Count int `json:"count"`
+}
+
+type ResponseDto struct {
+ Id uint32 `json:"id"`
+ Village_Code string `json:"village_code"`
+ Village *ev.Village `json:"village,omitempty"`
+ Code string `json:"code"`
+}
+
+func (d PostalRegion) ToResponse() ResponseDto {
+ resp := ResponseDto{
+ Id: d.Id,
+ Village_Code: d.Village_Code,
+ Village: d.Village,
+ Code: d.Code,
+ }
+ return resp
+}
+
+func ToResponseList(data []PostalRegion) []ResponseDto {
+ resp := make([]ResponseDto, len(data))
+ for i, u := range data {
+ resp[i] = u.ToResponse()
+ }
+ return resp
+}
diff --git a/internal/domain/main-entities/postal-region/entity.go b/internal/domain/main-entities/postal-region/entity.go
new file mode 100644
index 00000000..43f5971f
--- /dev/null
+++ b/internal/domain/main-entities/postal-region/entity.go
@@ -0,0 +1,11 @@
+package postalregion
+
+import (
+ ep "simrs-vx/internal/domain/main-entities/postal-region/base"
+ ev "simrs-vx/internal/domain/main-entities/village"
+)
+
+type PostalRegion struct {
+ ep.Basic
+ Village *ev.Village `json:"village,omitempty" gorm:"foreignKey:Village_Code;references:Code"`
+}
diff --git a/internal/domain/main-entities/practice-schedule/dto.go b/internal/domain/main-entities/practice-schedule/dto.go
index 505d793e..00eea2ad 100644
--- a/internal/domain/main-entities/practice-schedule/dto.go
+++ b/internal/domain/main-entities/practice-schedule/dto.go
@@ -15,20 +15,16 @@ type CreateDto struct {
type ReadListDto struct {
FilterDto
- Includes string `json:"includes"`
- Preloads []string `json:"-"`
+ Includes string `json:"includes"`
+ Pagination ecore.Pagination
}
type FilterDto struct {
- Doctor_Id *uint `json:"doctor_id"`
- Unit_Code *string `json:"unit_code"`
- Day_Code *erc.DayCode `json:"day_code"`
+ Doctor_Id *uint `json:"doctor-id"`
+ Unit_Code *string `json:"unit-code"`
+ Day_Code *erc.DayCode `json:"day-code"`
StartTime *string `json:"startTime"`
EndTime *string `json:"endTime"`
-
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
}
type ReadDetailDto struct {
diff --git a/internal/domain/main-entities/prescription-item/dto.go b/internal/domain/main-entities/prescription-item/dto.go
new file mode 100644
index 00000000..64b5f78f
--- /dev/null
+++ b/internal/domain/main-entities/prescription-item/dto.go
@@ -0,0 +1,104 @@
+package prescriptionitem
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ em "simrs-vx/internal/domain/main-entities/medicine"
+ emm "simrs-vx/internal/domain/main-entities/medicine-mix"
+ ep "simrs-vx/internal/domain/main-entities/prescription"
+
+ erc "simrs-vx/internal/domain/references/common"
+)
+
+type CreateDto struct {
+ Prescription_Id *uint `json:"prescription_id"`
+ IsMix bool `json:"isMix"`
+ Medicine_Id *uint `json:"medicine_id"`
+ MedicineMix_Id *uint `json:"medicineMix_id"`
+ Frequency *uint16 `json:"frequency" validate:"required"`
+ Dose float64 `json:"dose" validate:"required"`
+ Usage string `json:"usage"`
+ Interval uint8 `json:"interval"`
+ IntervalUnit_Code erc.TimeUnitCode `json:"intervalUnit_code"`
+ IntervalMultiplier *uint16 `json:"intervalMultiplier" validate:"required"`
+ Quantity float64 `json:"quantity"`
+}
+
+type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ Prescription_Id *uint `json:"prescription-id"`
+ IsMix bool `json:"isMix"`
+ Medicine_Id *uint `json:"medicine-id"`
+ MedicineMix_Id *uint `json:"medicineMix-id"`
+ Usage float64 `json:"usage"`
+ Interval uint8 `json:"interval"`
+ IntervalUnit_Code erc.TimeUnitCode `json:"intervalUnit-code"`
+ Quantity float64 `json:"quantity"`
+}
+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
+ Prescription_Id *uint `json:"prescription_id"`
+ Prescription *ep.Prescription `json:"prescription,omitempty"`
+ IsMix bool `json:"isMix"`
+ Medicine_Id *uint `json:"medicine_id"`
+ Medicine *em.Medicine `json:"medicine,omitempty"`
+ MedicineMix_Id *uint `json:"medicineMix_id"`
+ MedicineMix *emm.MedicineMix `json:"medicineMix,omitempty"`
+ Frequency *uint16 `json:"frequency"`
+ Dose float64 `json:"dose"`
+ Usage string `json:"usage"`
+ Interval uint8 `json:"interval"`
+ IntervalUnit_Code erc.TimeUnitCode `json:"intervalUnit_code"`
+ Quantity float64 `json:"quantity"`
+}
+
+func (d PrescriptionItem) ToResponse() ResponseDto {
+ resp := ResponseDto{
+ Prescription_Id: d.Prescription_Id,
+ Prescription: d.Prescription,
+ IsMix: d.IsMix,
+ Medicine_Id: d.Medicine_Id,
+ Medicine: d.Medicine,
+ MedicineMix_Id: d.MedicineMix_Id,
+ MedicineMix: d.MedicineMix,
+ Frequency: d.Frequency,
+ Dose: d.Dose,
+ Usage: d.Usage,
+ Interval: d.Interval,
+ IntervalUnit_Code: d.IntervalUnit_Code,
+ Quantity: d.Quantity,
+ }
+ resp.Main = d.Main
+ return resp
+}
+
+func ToResponseList(data []PrescriptionItem) []ResponseDto {
+ resp := make([]ResponseDto, len(data))
+ for i, u := range data {
+ resp[i] = u.ToResponse()
+ }
+ return resp
+}
diff --git a/internal/domain/main-entities/prescription-item/entity.go b/internal/domain/main-entities/prescription-item/entity.go
new file mode 100644
index 00000000..33696385
--- /dev/null
+++ b/internal/domain/main-entities/prescription-item/entity.go
@@ -0,0 +1,27 @@
+package prescriptionitem
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ em "simrs-vx/internal/domain/main-entities/medicine"
+ emm "simrs-vx/internal/domain/main-entities/medicine-mix"
+ ep "simrs-vx/internal/domain/main-entities/prescription"
+
+ erc "simrs-vx/internal/domain/references/common"
+)
+
+type PrescriptionItem struct {
+ ecore.Main // adjust this according to the needs
+ Prescription_Id *uint `json:"prescription_id"`
+ Prescription *ep.Prescription `json:"prescription,omitempty" gorm:"foreignKey:Prescription_Id;references:Id"`
+ IsMix bool `json:"isMix"`
+ Medicine_Id *uint `json:"medicine_id"`
+ Medicine *em.Medicine `json:"medicine,omitempty" gorm:"foreignKey:Medicine_Id;references:Id"`
+ MedicineMix_Id *uint `json:"medicineMix_id"`
+ MedicineMix *emm.MedicineMix `json:"medicineMix,omitempty" gorm:"foreignKey:MedicineMix_Id;references:Id"`
+ Frequency *uint16 `json:"frequency"`
+ Dose float64 `json:"dose"`
+ Usage string `json:"usage" gorm:"size:255"`
+ Interval uint8 `json:"interval"`
+ IntervalUnit_Code erc.TimeUnitCode `json:"intervalUnit_code"`
+ Quantity float64 `json:"quantity"`
+}
diff --git a/internal/domain/main-entities/prescription/dto.go b/internal/domain/main-entities/prescription/dto.go
new file mode 100644
index 00000000..431f1e2d
--- /dev/null
+++ b/internal/domain/main-entities/prescription/dto.go
@@ -0,0 +1,81 @@
+package prescription
+
+import (
+ "time"
+
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ed "simrs-vx/internal/domain/main-entities/doctor"
+ ee "simrs-vx/internal/domain/main-entities/encounter"
+
+ erc "simrs-vx/internal/domain/references/common"
+)
+
+type CreateDto struct {
+ Encounter_Id *uint `json:"encounter_id"`
+ Doctor_Id *uint `json:"doctor_id"`
+ IssuedAt *time.Time `json:"issuedAt"`
+ Status_Code erc.DataStatusCode `json:"status_code"`
+}
+
+type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ Encounter_Id *uint `json:"encounter-id"`
+ Doctor_Id *uint `json:"doctor-id"`
+ IssuedAt *time.Time `json:"issuedAt"`
+ Status_Code *erc.DataStatusCode `json:"status-code"`
+}
+type ReadDetailDto struct {
+ Id uint `json:"id"`
+ Encounter_Id *uint `json:"encounter_id"`
+}
+
+type UpdateDto struct {
+ Id uint `json:"id"`
+ CreateDto
+}
+
+type DeleteDto struct {
+ Id uint `json:"id"`
+}
+
+type MetaDto struct {
+ PageNumber int `json:"page_number"`
+ PageSize int `json:"page_size"`
+ Count int `json:"count"`
+}
+
+type ResponseDto struct {
+ ecore.Main
+ Encounter_Id *uint `json:"encounter_id"`
+ Encounter *ee.Encounter `json:"encounter,omitempty"`
+ Doctor_Id *uint `json:"doctor_id"`
+ Doctor *ed.Doctor `json:"doctor,omitempty"`
+ IssuedAt *time.Time `json:"issuedAt"`
+ Status_Code erc.DataStatusCode `json:"status_code"`
+}
+
+func (d Prescription) ToResponse() ResponseDto {
+ resp := ResponseDto{
+ Encounter_Id: d.Encounter_Id,
+ Encounter: d.Encounter,
+ Doctor_Id: d.Doctor_Id,
+ Doctor: d.Doctor,
+ IssuedAt: d.IssuedAt,
+ Status_Code: d.Status_Code,
+ }
+ resp.Main = d.Main
+ return resp
+}
+
+func ToResponseList(data []Prescription) []ResponseDto {
+ resp := make([]ResponseDto, len(data))
+ for i, u := range data {
+ resp[i] = u.ToResponse()
+ }
+ return resp
+}
diff --git a/internal/domain/main-entities/prescription/entity.go b/internal/domain/main-entities/prescription/entity.go
new file mode 100644
index 00000000..bdc2d2fb
--- /dev/null
+++ b/internal/domain/main-entities/prescription/entity.go
@@ -0,0 +1,25 @@
+package prescription
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ed "simrs-vx/internal/domain/main-entities/doctor"
+ ee "simrs-vx/internal/domain/main-entities/encounter"
+
+ "time"
+
+ erc "simrs-vx/internal/domain/references/common"
+)
+
+type Prescription struct {
+ ecore.Main // adjust this according to the needs
+ Encounter_Id *uint `json:"encounter_id"`
+ Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"`
+ Doctor_Id *uint `json:"doctor_id"`
+ Doctor *ed.Doctor `json:"doctor,omitempty" gorm:"foreignKey:Doctor_Id;references:Id"`
+ IssuedAt *time.Time `json:"issuedAt"`
+ Status_Code erc.DataStatusCode `json:"status_code"`
+}
+
+func (d Prescription) IsApproved() bool {
+ return d.Status_Code == erc.DSCDone
+}
diff --git a/internal/domain/main-entities/procedure-src/dto.go b/internal/domain/main-entities/procedure-src/dto.go
index 8dd97f1e..477a9885 100644
--- a/internal/domain/main-entities/procedure-src/dto.go
+++ b/internal/domain/main-entities/procedure-src/dto.go
@@ -11,13 +11,17 @@ type CreateDto struct {
}
type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Sort string `json:"sort"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
Code string `json:"code"`
Name string `json:"name"`
IndName string `json:"indName"`
-
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+ Search string `json:"search" gormhelper:"searchColumns=Code,Name"`
}
type ReadDetailDto struct {
diff --git a/internal/domain/main-entities/province/dto.go b/internal/domain/main-entities/province/dto.go
index 5bd519a8..a7cc5a70 100644
--- a/internal/domain/main-entities/province/dto.go
+++ b/internal/domain/main-entities/province/dto.go
@@ -1,17 +1,26 @@
package province
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ erb "simrs-vx/internal/domain/main-entities/regency/base"
+)
+
type CreateDto struct {
Code string `json:"code" validate:"required;minLength=2;maxLength=2"`
Name string `json:"name" validate:"required;maxLength=10"`
}
type ReadListDto struct {
- Code string `json:"code"`
- Name string `json:"name"`
+ FilterDto
+ Includes string `json:"includes"`
+ Sort string `json:"sort"`
+ Pagination ecore.Pagination
+}
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+type FilterDto struct {
+ Code string `json:"code"`
+ Name string `json:"name"`
+ Search string `json:"search" gormhelper:"searchColumns=Code,Name"`
}
type ReadDetailDto struct {
@@ -35,16 +44,18 @@ type MetaDto struct {
}
type ResponseDto struct {
- Id int16 `json:"id"`
- Code string `json:"code"`
- Name string `json:"name"`
+ Id int16 `json:"id"`
+ Code string `json:"code"`
+ Name string `json:"name"`
+ Regencies []erb.Basic `json:"regencies,omitempty"`
}
func (d Province) ToResponse() ResponseDto {
resp := ResponseDto{
- Id: d.Id,
- Code: d.Code,
- Name: d.Name,
+ Id: d.Id,
+ Code: d.Code,
+ Name: d.Name,
+ Regencies: d.Regencies,
}
return resp
}
diff --git a/internal/domain/main-entities/province/entity.go b/internal/domain/main-entities/province/entity.go
index ab024b22..198cf4a4 100644
--- a/internal/domain/main-entities/province/entity.go
+++ b/internal/domain/main-entities/province/entity.go
@@ -1,10 +1,10 @@
package province
-import er "simrs-vx/internal/domain/main-entities/regency"
+import erb "simrs-vx/internal/domain/main-entities/regency/base"
type Province struct {
- Id int16 `json:"id" gorm:"primaryKey"`
- Code string `json:"code" gorm:"unique;size:2"`
- Name string `json:"name" gorm:"size:50"`
- Regencies []*er.Regency `json:"regencies,omitempty" gorm:"foreignKey:Province_Code;references:Code"`
+ Id int16 `json:"id" gorm:"primaryKey"`
+ Code string `json:"code" gorm:"unique;size:2"`
+ Name string `json:"name" gorm:"size:50"`
+ Regencies []erb.Basic `json:"regencies,omitempty" gorm:"foreignKey:Province_Code;references:Code"`
}
diff --git a/internal/domain/main-entities/regency/base/entitiy.go b/internal/domain/main-entities/regency/base/entitiy.go
new file mode 100644
index 00000000..9e824923
--- /dev/null
+++ b/internal/domain/main-entities/regency/base/entitiy.go
@@ -0,0 +1,12 @@
+package base
+
+type Basic struct {
+ Id uint32 `json:"id" gorm:"primaryKey"`
+ Province_Code string `json:"province_code" gorm:"size:2"`
+ Code string `json:"code" gorm:"unique;size:4"`
+ Name string `json:"name" gorm:"size:50"`
+}
+
+func (Basic) TableName() string {
+ return "Regency"
+}
diff --git a/internal/domain/main-entities/regency/dto.go b/internal/domain/main-entities/regency/dto.go
index 7fb7546b..40682f43 100644
--- a/internal/domain/main-entities/regency/dto.go
+++ b/internal/domain/main-entities/regency/dto.go
@@ -1,6 +1,11 @@
package regency
-import ed "simrs-vx/internal/domain/main-entities/district"
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ edb "simrs-vx/internal/domain/main-entities/district/base"
+ ep "simrs-vx/internal/domain/main-entities/province"
+ erb "simrs-vx/internal/domain/main-entities/regency/base"
+)
type CreateDto struct {
Province_Code string `json:"province_code" validate:"numeric;maxLength=2"`
@@ -9,13 +14,17 @@ type CreateDto struct {
}
type ReadListDto struct {
- Province_Code string `json:"province_code"`
+ FilterDto
+ Includes string `json:"includes"`
+ Sort string `json:"sort"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ Province_Code string `json:"province-code"`
Code string `json:"code"`
Name string `json:"name"`
-
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+ Search string `json:"search" gormhelper:"searchColumns=Code,Name"`
}
type ReadDetailDto struct {
@@ -39,15 +48,17 @@ type MetaDto struct {
}
type ResponseDto struct {
- Id uint16 `json:"id"`
- Province_Code string `json:"province_code"`
- Code string `json:"code"`
- Name string `json:"name"`
- Districts []*ed.District `json:"districts,omitempty"`
+ erb.Basic
+ Province *ep.Province `json:"province,omitempty"`
+ Districts []*edb.Basic `json:"districts,omitempty"`
}
func (d Regency) ToResponse() ResponseDto {
- resp := ResponseDto(d)
+ resp := ResponseDto{
+ Basic: d.Basic,
+ Province: d.Province,
+ Districts: d.Districts,
+ }
return resp
}
diff --git a/internal/domain/main-entities/regency/entity.go b/internal/domain/main-entities/regency/entity.go
index 3bdcf934..bf58e37b 100644
--- a/internal/domain/main-entities/regency/entity.go
+++ b/internal/domain/main-entities/regency/entity.go
@@ -1,11 +1,13 @@
package regency
-import ed "simrs-vx/internal/domain/main-entities/district"
+import (
+ edb "simrs-vx/internal/domain/main-entities/district/base"
+ ep "simrs-vx/internal/domain/main-entities/province"
+ erb "simrs-vx/internal/domain/main-entities/regency/base"
+)
type Regency struct {
- Id uint16 `json:"id" gorm:"primaryKey"`
- Province_Code string `json:"province_code" gorm:"size:2"`
- Code string `json:"code" gorm:"unique;size:4"`
- Name string `json:"name" gorm:"size:50"`
- Districts []*ed.District `json:"districts,omitempty" gorm:"foreignKey:Regency_Code;references:Code"`
+ erb.Basic
+ Province *ep.Province `json:"province,omitempty" gorm:"foreignKey:Province_Code;references:Code"`
+ Districts []*edb.Basic `json:"districts,omitempty" gorm:"foreignKey:Regency_Code;references:Code"`
}
diff --git a/internal/domain/main-entities/room/base/entity.go b/internal/domain/main-entities/room/base/entity.go
new file mode 100644
index 00000000..e45a441d
--- /dev/null
+++ b/internal/domain/main-entities/room/base/entity.go
@@ -0,0 +1,23 @@
+package base
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ es "simrs-vx/internal/domain/main-entities/specialist"
+ ess "simrs-vx/internal/domain/main-entities/subspecialist"
+ eu "simrs-vx/internal/domain/main-entities/unit"
+)
+
+type Basic struct {
+ ecore.SmallMain // adjust this according to the needs
+ Infra_Id *uint16 `json:"infra_id"`
+ Unit_Id *uint16 `json:"unit_id"`
+ Unit *eu.Unit `json:"unit,omitempty" gorm:"foreignKey:Unit_Id"`
+ Specialist_Id *uint16 `json:"specialist_id"`
+ Specialist *es.Specialist `json:"specialist,omitempty" gorm:"foreignKey:Specialist_Id"`
+ Subspecialist_Id *uint16 `json:"subspecialist_id"`
+ Subspecialist *ess.Subspecialist `json:"subspecialist,omitempty" gorm:"foreignKey:Subspecialist_Id"`
+}
+
+func (Basic) TableName() string {
+ return "Room"
+}
diff --git a/internal/domain/main-entities/room/dto.go b/internal/domain/main-entities/room/dto.go
new file mode 100644
index 00000000..0ca2e8d4
--- /dev/null
+++ b/internal/domain/main-entities/room/dto.go
@@ -0,0 +1,83 @@
+package room
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ei "simrs-vx/internal/domain/main-entities/infra"
+ es "simrs-vx/internal/domain/main-entities/specialist"
+ ess "simrs-vx/internal/domain/main-entities/subspecialist"
+ eu "simrs-vx/internal/domain/main-entities/unit"
+)
+
+type CreateDto struct {
+ Infra_Id *uint16 `json:"infra_id"`
+ Unit_Id *uint16 `json:"unit_id"`
+ Specialist_Id *uint16 `json:"specialist_id"`
+ Subspecialist_Id *uint16 `json:"subspecialist_id"`
+}
+
+type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ Infra_Id *uint16 `json:"infra-id"`
+ Unit_Id *uint16 `json:"unit-id"`
+ Specialist_Id *uint16 `json:"specialist-id"`
+ Subspecialist_Id *uint16 `json:"subspecialist-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.SmallMain
+ Infra_Id *uint16 `json:"infra_id"`
+ Infra *ei.Infra `json:"infra,omitempty"`
+ Unit_Id *uint16 `json:"unit_id"`
+ Unit *eu.Unit `json:"unit,omitempty"`
+ Specialist_Id *uint16 `json:"specialist_id"`
+ Specialist *es.Specialist `json:"specialist,omitempty"`
+ Subspecialist_Id *uint16 `json:"subspecialist_id"`
+ Subspecialist *ess.Subspecialist `json:"subspecialist,omitempty"`
+}
+
+func (d Room) ToResponse() ResponseDto {
+ resp := ResponseDto{
+ Infra_Id: d.Infra_Id,
+ Infra: d.Infra,
+ Unit_Id: d.Unit_Id,
+ Unit: d.Unit,
+ Specialist_Id: d.Specialist_Id,
+ Specialist: d.Specialist,
+ Subspecialist_Id: d.Subspecialist_Id,
+ Subspecialist: d.Subspecialist,
+ }
+ resp.SmallMain = d.SmallMain
+ return resp
+}
+
+func ToResponseList(data []Room) []ResponseDto {
+ resp := make([]ResponseDto, len(data))
+ for i, u := range data {
+ resp[i] = u.ToResponse()
+ }
+ return resp
+}
diff --git a/internal/domain/main-entities/room/entity.go b/internal/domain/main-entities/room/entity.go
new file mode 100644
index 00000000..346c7741
--- /dev/null
+++ b/internal/domain/main-entities/room/entity.go
@@ -0,0 +1,11 @@
+package room
+
+import (
+ ei "simrs-vx/internal/domain/main-entities/infra"
+ ebase "simrs-vx/internal/domain/main-entities/room/base"
+)
+
+type Room struct {
+ ebase.Basic
+ Infra *ei.Infra `json:"infra,omitempty" gorm:"foreignKey:Infra_Id"`
+}
diff --git a/internal/domain/main-entities/sbar/dto.go b/internal/domain/main-entities/sbar/dto.go
new file mode 100644
index 00000000..46cf69a8
--- /dev/null
+++ b/internal/domain/main-entities/sbar/dto.go
@@ -0,0 +1,83 @@
+package sbar
+
+import (
+ "time"
+
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ eem "simrs-vx/internal/domain/main-entities/employee"
+ ee "simrs-vx/internal/domain/main-entities/encounter"
+
+ pa "simrs-vx/pkg/auth-helper"
+)
+
+type CreateDto struct {
+ Encounter_Id *uint `json:"encounter_id"`
+ Employee_Id *uint `json:"-"`
+ Time *time.Time `json:"time"`
+ Value *string `json:"value"`
+
+ pa.AuthInfo
+}
+
+type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ Encounter_Id *uint `json:"encounter-id"`
+ Employee_Id *uint `json:"employee-id"`
+ Time *time.Time `json:"time"`
+ Value *string `json:"value"`
+}
+
+type ReadDetailDto struct {
+ Id uint16 `json:"id"`
+}
+
+type UpdateDto struct {
+ Id uint16 `json:"id"`
+ CreateDto
+}
+
+type DeleteDto struct {
+ Id uint16 `json:"id"`
+}
+
+type MetaDto struct {
+ PageNumber int `json:"page_number"`
+ PageSize int `json:"page_size"`
+ Count int `json:"count"`
+}
+
+type ResponseDto struct {
+ ecore.Main
+ Encounter_Id *uint `json:"encounter_id"`
+ Encounter *ee.Encounter `json:"encounter,omitempty"`
+ Employee_Id *uint `json:"employee_id"`
+ Employee *eem.Employee `json:"employee,omitempty"`
+ Time *time.Time `json:"time"`
+ Value *string `json:"value"`
+}
+
+func (d Sbar) ToResponse() ResponseDto {
+ resp := ResponseDto{
+ Encounter_Id: d.Encounter_Id,
+ Encounter: d.Encounter,
+ Employee_Id: d.Employee_Id,
+ Employee: d.Employee,
+ Time: d.Time,
+ Value: d.Value,
+ }
+ resp.Main = d.Main
+ return resp
+}
+
+func ToResponseList(data []Sbar) []ResponseDto {
+ resp := make([]ResponseDto, len(data))
+ for i, u := range data {
+ resp[i] = u.ToResponse()
+ }
+ return resp
+}
diff --git a/internal/domain/main-entities/sbar/entity.go b/internal/domain/main-entities/sbar/entity.go
new file mode 100644
index 00000000..62303f05
--- /dev/null
+++ b/internal/domain/main-entities/sbar/entity.go
@@ -0,0 +1,18 @@
+package sbar
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ eem "simrs-vx/internal/domain/main-entities/employee"
+ ee "simrs-vx/internal/domain/main-entities/encounter"
+ "time"
+)
+
+type Sbar struct {
+ ecore.Main // adjust this according to the needs
+ Encounter_Id *uint `json:"encounter_id"`
+ Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"`
+ Employee_Id *uint `json:"employee_id"`
+ Employee *eem.Employee `json:"employee,omitempty" gorm:"foreignKey:Employee_Id;references:Id"`
+ Time *time.Time `json:"time"`
+ Value *string `json:"value"`
+}
diff --git a/internal/domain/main-entities/soapi/dto.go b/internal/domain/main-entities/soapi/dto.go
new file mode 100644
index 00000000..418a7fb8
--- /dev/null
+++ b/internal/domain/main-entities/soapi/dto.go
@@ -0,0 +1,89 @@
+package soapi
+
+import (
+ "time"
+
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ eem "simrs-vx/internal/domain/main-entities/employee"
+ ee "simrs-vx/internal/domain/main-entities/encounter"
+
+ erc "simrs-vx/internal/domain/references/clinical"
+
+ pa "simrs-vx/pkg/auth-helper"
+)
+
+type CreateDto struct {
+ Encounter_Id *uint `json:"encounter_id"`
+ Employee_Id *uint `json:"-"`
+ Time *time.Time `json:"time"`
+ TypeCode erc.SoapiTypeCode `json:"typeCode"`
+ Value *string `json:"value"`
+
+ pa.AuthInfo
+}
+
+type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ Encounter_Id *uint `json:"encounter-id"`
+ Employee_Id *uint `json:"employee-id"`
+ Time *time.Time `json:"time"`
+ TypeCode erc.SoapiTypeCode `json:"typeCode"`
+ Value *string `json:"value"`
+}
+
+type ReadDetailDto struct {
+ Id uint16 `json:"id"`
+}
+
+type UpdateDto struct {
+ Id uint16 `json:"id"`
+ CreateDto
+}
+
+type DeleteDto struct {
+ Id uint16 `json:"id"`
+}
+
+type MetaDto struct {
+ PageNumber int `json:"page_number"`
+ PageSize int `json:"page_size"`
+ Count int `json:"count"`
+}
+
+type ResponseDto struct {
+ ecore.Main
+ Encounter_Id *uint `json:"encounter_id"`
+ Encounter *ee.Encounter `json:"encounter,omitempty"`
+ Employee_Id *uint `json:"employee_id"`
+ Employee *eem.Employee `json:"employee,omitempty"`
+ Time *time.Time `json:"time"`
+ TypeCode erc.SoapiTypeCode `json:"typeCode"`
+ Value *string `json:"value"`
+}
+
+func (d Soapi) ToResponse() ResponseDto {
+ resp := ResponseDto{
+ Encounter_Id: d.Encounter_Id,
+ Encounter: d.Encounter,
+ Employee_Id: d.Employee_Id,
+ Employee: d.Employee,
+ Time: d.Time,
+ TypeCode: d.TypeCode,
+ Value: d.Value,
+ }
+ resp.Main = d.Main
+ return resp
+}
+
+func ToResponseList(data []Soapi) []ResponseDto {
+ resp := make([]ResponseDto, len(data))
+ for i, u := range data {
+ resp[i] = u.ToResponse()
+ }
+ return resp
+}
diff --git a/internal/domain/main-entities/soapi/entity.go b/internal/domain/main-entities/soapi/entity.go
new file mode 100644
index 00000000..7e457ca9
--- /dev/null
+++ b/internal/domain/main-entities/soapi/entity.go
@@ -0,0 +1,22 @@
+package soapi
+
+import (
+ "time"
+
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ eem "simrs-vx/internal/domain/main-entities/employee"
+ ee "simrs-vx/internal/domain/main-entities/encounter"
+
+ erc "simrs-vx/internal/domain/references/clinical"
+)
+
+type Soapi struct {
+ ecore.Main // adjust this according to the needs
+ Encounter_Id *uint `json:"encounter_id"`
+ Encounter *ee.Encounter `json:"encounter,omitempty" gorm:"foreignKey:Encounter_Id;references:Id"`
+ Employee_Id *uint `json:"employee_id"`
+ Employee *eem.Employee `json:"employee,omitempty" gorm:"foreignKey:Employee_Id;references:Id"`
+ Time *time.Time `json:"time"`
+ TypeCode erc.SoapiTypeCode `json:"type_code" gorm:"size:11"`
+ Value *string `json:"value"`
+}
diff --git a/internal/domain/main-entities/specialist-intern/dto.go b/internal/domain/main-entities/specialist-intern/dto.go
new file mode 100644
index 00000000..2d01c861
--- /dev/null
+++ b/internal/domain/main-entities/specialist-intern/dto.go
@@ -0,0 +1,84 @@
+package specialistintern
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ep "simrs-vx/internal/domain/main-entities/person"
+ es "simrs-vx/internal/domain/main-entities/specialist"
+ ess "simrs-vx/internal/domain/main-entities/subspecialist"
+ eu "simrs-vx/internal/domain/main-entities/user"
+)
+
+type CreateDto struct {
+ Person_Id *uint `json:"person_id"`
+ Specialist_Id *uint16 `json:"specialist_id"`
+ Subspecialist_Id *uint16 `json:"subspecialist_id"`
+ User_Id *uint `json:"user_id"`
+}
+
+type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ Person_Id *uint `json:"person-id"`
+ Specialist_Id *uint16 `json:"specialist-id"`
+ Subspecialist_Id *uint16 `json:"subspecialist-id"`
+ User_Id *uint `json:"user-id"`
+}
+
+type ReadDetailDto struct {
+ Id uint16 `json:"id"`
+ User_Id *uint `json:"user_id"`
+}
+
+type UpdateDto struct {
+ Id uint `json:"id"`
+ CreateDto
+}
+
+type DeleteDto struct {
+ Id uint `json:"id"`
+}
+
+type MetaDto struct {
+ PageNumber int `json:"page_number"`
+ PageSize int `json:"page_size"`
+ Count int `json:"count"`
+}
+
+type ResponseDto struct {
+ ecore.Main
+ Person_Id *uint `json:"person_id"`
+ Person *ep.Person `json:"person,omitempty"`
+ Specialist_Id *uint16 `json:"specialist_id"`
+ Specialist *es.Specialist `json:"specialist,omitempty"`
+ Subspecialist_Id *uint16 `json:"subspecialist_id"`
+ Subspecialist *ess.Subspecialist `json:"subspecialist,omitempty"`
+ User_Id *uint `json:"user_id"`
+ User *eu.User `json:"user,omitempty"`
+}
+
+func (d SpecialistIntern) ToResponse() ResponseDto {
+ resp := ResponseDto{
+ Person_Id: d.Person_Id,
+ Person: d.Person,
+ Specialist_Id: d.Specialist_Id,
+ Specialist: d.Specialist,
+ Subspecialist_Id: d.Subspecialist_Id,
+ Subspecialist: d.Subspecialist,
+ User_Id: d.User_Id,
+ User: d.User,
+ }
+ resp.Main = d.Main
+ return resp
+}
+
+func ToResponseList(data []SpecialistIntern) []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-intern/entity.go b/internal/domain/main-entities/specialist-intern/entity.go
new file mode 100644
index 00000000..9df0ed53
--- /dev/null
+++ b/internal/domain/main-entities/specialist-intern/entity.go
@@ -0,0 +1,21 @@
+package specialistintern
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ep "simrs-vx/internal/domain/main-entities/person"
+ es "simrs-vx/internal/domain/main-entities/specialist"
+ ess "simrs-vx/internal/domain/main-entities/subspecialist"
+ eu "simrs-vx/internal/domain/main-entities/user"
+)
+
+type SpecialistIntern struct {
+ ecore.Main // adjust this according to the needs
+ Person_Id *uint `json:"person_id"`
+ Person *ep.Person `json:"person,omitempty" gorm:"foreignKey:Person_Id"`
+ Specialist_Id *uint16 `json:"specialist_id"`
+ Specialist *es.Specialist `json:"specialist,omitempty" gorm:"foreignKey:Specialist_Id"`
+ Subspecialist_Id *uint16 `json:"subspecialist_id"`
+ Subspecialist *ess.Subspecialist `json:"subspecialist,omitempty" gorm:"foreignKey:Subspecialist_Id"`
+ User_Id *uint `json:"user_id"`
+ User *eu.User `json:"user,omitempty" gorm:"foreignKey:User_Id"`
+}
diff --git a/internal/domain/main-entities/specialist/dto.go b/internal/domain/main-entities/specialist/dto.go
new file mode 100644
index 00000000..f1338c19
--- /dev/null
+++ b/internal/domain/main-entities/specialist/dto.go
@@ -0,0 +1,70 @@
+package specialist
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+)
+
+type CreateDto struct {
+ Code string `json:"code" validate:"maxLength=10"`
+ Name string `json:"name" validate:"maxLength=50"`
+ Unit_Id *uint16 `json:"unit_id"`
+}
+
+type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Sort string `json:"sort"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ Code string `json:"code"`
+ Name string `json:"name"`
+ Unit_Id *uint16 `json:"unit-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
+ Code string `json:"code"`
+ Name string `json:"name"`
+ Unit_Id *uint16 `json:"unit_id"`
+}
+
+func (d Specialist) ToResponse() ResponseDto {
+ resp := ResponseDto{
+ Code: d.Code,
+ Name: d.Name,
+ Unit_Id: d.Unit_Id,
+ }
+ resp.SmallMain = d.SmallMain
+ return resp
+}
+
+func ToResponseList(data []Specialist) []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/entity.go b/internal/domain/main-entities/specialist/entity.go
new file mode 100644
index 00000000..3cea2ebd
--- /dev/null
+++ b/internal/domain/main-entities/specialist/entity.go
@@ -0,0 +1,14 @@
+package specialist
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ eu "simrs-vx/internal/domain/main-entities/unit"
+)
+
+type Specialist struct {
+ ecore.SmallMain // adjust this according to the needs
+ Code string `json:"code" gorm:"unique;size:10"`
+ Name string `json:"name" gorm:"size:50"`
+ Unit_Id *uint16 `json:"unit_id"`
+ Unit *eu.Unit `json:"unit,omitempty" gorm:"foreignKey:Unit_Id"`
+}
diff --git a/internal/domain/main-entities/subspecialist/dto.go b/internal/domain/main-entities/subspecialist/dto.go
new file mode 100644
index 00000000..e28f96ae
--- /dev/null
+++ b/internal/domain/main-entities/subspecialist/dto.go
@@ -0,0 +1,70 @@
+package subspecialist
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+)
+
+type CreateDto struct {
+ Code string `json:"code" validate:"maxLength=10"`
+ Name string `json:"name" validate:"maxLength=50"`
+ Specialist_Id *uint16 `json:"specialist_id"`
+}
+
+type ReadListDto struct {
+ FilterDto
+ Includes string `json:"includes"`
+ Sort string `json:"sort"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ Code *string `json:"code"`
+ Name *string `json:"name"`
+ Specialist_Id *uint16 `json:"specialist-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
+ Code string `json:"code"`
+ Name string `json:"name"`
+ Specialist_Id *uint16 `json:"specialist_id"`
+}
+
+func (d Subspecialist) ToResponse() ResponseDto {
+ resp := ResponseDto{
+ Code: d.Code,
+ Name: d.Name,
+ Specialist_Id: d.Specialist_Id,
+ }
+ resp.SmallMain = d.SmallMain
+ return resp
+}
+
+func ToResponseList(data []Subspecialist) []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/entity.go b/internal/domain/main-entities/subspecialist/entity.go
new file mode 100644
index 00000000..5de27442
--- /dev/null
+++ b/internal/domain/main-entities/subspecialist/entity.go
@@ -0,0 +1,14 @@
+package subspecialist
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ es "simrs-vx/internal/domain/main-entities/specialist"
+)
+
+type Subspecialist struct {
+ ecore.SmallMain // adjust this according to the needs
+ Code string `json:"code" gorm:"unique;size:10"`
+ Name string `json:"name" gorm:"size:50"`
+ Specialist_Id *uint16 `json:"specialist_id"`
+ Specialist *es.Specialist `json:"specialist,omitempty" gorm:"foreignKey:Specialist_Id"`
+}
diff --git a/internal/domain/main-entities/unit/dto.go b/internal/domain/main-entities/unit/dto.go
index e3521eb5..10960609 100644
--- a/internal/domain/main-entities/unit/dto.go
+++ b/internal/domain/main-entities/unit/dto.go
@@ -13,18 +13,16 @@ type CreateDto struct {
type ReadListDto struct {
FilterDto
- Includes string `json:"includes"`
- Preloads []string `json:"-"`
+ Includes string `json:"includes"`
+ Sort string `json:"sort"`
+ Pagination ecore.Pagination
}
type FilterDto struct {
- Installation_Id *uint16 `json:"installation_id"`
+ Installation_Id *uint16 `json:"installation-id"`
Code string `json:"code"`
Name string `json:"name"`
-
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+ Search string `json:"search" gormhelper:"searchColumns=Code,Name"`
}
type ReadDetailDto struct {
diff --git a/internal/domain/main-entities/unit/entity.go b/internal/domain/main-entities/unit/entity.go
index 3b93475f..c86ad822 100644
--- a/internal/domain/main-entities/unit/entity.go
+++ b/internal/domain/main-entities/unit/entity.go
@@ -3,12 +3,14 @@ package unit
import (
ecore "simrs-vx/internal/domain/base-entities/core"
ei "simrs-vx/internal/domain/main-entities/installation"
+ ero "simrs-vx/internal/domain/references/organization"
)
type Unit struct {
- ecore.SmallMain // adjust this according to the needs
- Installation_Id *uint16 `json:"installation_id"`
- Installation *ei.Installation `json:"installation" gorm:"foreignKey:Installation_Id"`
- Code string `json:"code" gorm:"unique;size:10"`
- Name string `json:"name" gorm:"size:50"`
+ ecore.SmallMain // adjust this according to the needs
+ Installation_Id *uint16 `json:"installation_id"`
+ Installation *ei.Installation `json:"installation" gorm:"foreignKey:Installation_Id"`
+ Code string `json:"code" gorm:"unique;size:10"`
+ Name string `json:"name" gorm:"size:50"`
+ Type_Code *ero.UnitTypeCode `json:"type_code"`
}
diff --git a/internal/domain/main-entities/uom/dto.go b/internal/domain/main-entities/uom/dto.go
index 348fb7fd..4feb5746 100644
--- a/internal/domain/main-entities/uom/dto.go
+++ b/internal/domain/main-entities/uom/dto.go
@@ -10,12 +10,16 @@ type CreateDto struct {
}
type ReadListDto struct {
- Code string `json:"code"`
- Name string `json:"name"`
+ FilterDto
+ Includes string `json:"includes"`
+ Sort string `json:"sort"`
+ Pagination ecore.Pagination
+}
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+type FilterDto struct {
+ Code string `json:"code"`
+ Name string `json:"name"`
+ Search string `json:"search" gormhelper:"searchColumns=Code,Name"`
}
type ReadDetailDto struct {
diff --git a/internal/domain/main-entities/user/dto.go b/internal/domain/main-entities/user/dto.go
index 26233c81..093a597e 100644
--- a/internal/domain/main-entities/user/dto.go
+++ b/internal/domain/main-entities/user/dto.go
@@ -1,24 +1,39 @@
package user
import (
- ecore "simrs-vx/internal/domain/base-entities/core"
- erc "simrs-vx/internal/domain/references/common"
"time"
+
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ep "simrs-vx/internal/domain/main-entities/person"
+ epa "simrs-vx/internal/domain/main-entities/person-address"
+ epc "simrs-vx/internal/domain/main-entities/person-contact"
+
+ erc "simrs-vx/internal/domain/references/common"
+ ero "simrs-vx/internal/domain/references/organization"
)
type CreateDto struct {
- Name string `json:"name" validate:"maxLength=25"`
- Password string `json:"password" validate:"maxLength=255"`
- Status_Code erc.UserStatusCode `json:"status_code" validate:"maxLength=10"`
+ Name string `json:"name" validate:"maxLength=25"`
+ Password string `json:"password" validate:"maxLength=255"`
+ Status_Code erc.UserStatusCode `json:"status_code" validate:"maxLength=10"`
+ ContractPosition_Code ero.ContractPositionCode `json:"contractPosition_code" validate:"maxLength=20"`
+ Person_Id *uint `json:"-"`
+ Person *ep.UpdateDto `json:"person"`
+ PersonAddresses []epa.UpdateDto `json:"personAddresses"`
+ PersonContacts []epc.UpdateDto `json:"personContacts"`
+ Employee *EmployeUpdateDto `json:"employee"`
+ IHS_Number *string `json:"ihs_number" validate:"maxLength=20"`
+ SIP_Number *string `json:"sip_number" validate:"maxLength=20"`
+ Unit_Id *uint16 `json:"unit_id"`
+ Infra_Id *uint16 `json:"infra_id"`
+ Specialist_Id *uint16 `json:"specialist_id"`
+ Subspecialist_Id *uint16 `json:"subspecialist_id"`
}
type ReadListDto struct {
Name string `json:"name"`
- Status_Code erc.UserStatusCode `json:"status_code"`
-
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+ Status_Code erc.UserStatusCode `json:"status-code"`
+ Pagination ecore.Pagination
}
type ReadDetailDto struct {
@@ -68,6 +83,16 @@ func (d *User) ToResponse() ResponseDto {
return resp
}
+type EmployeUpdateDto struct {
+ Id uint `json:"id"`
+ User_Id *uint `json:"-"`
+ Person_Id *uint `json:"-"`
+ Division_Code *string `json:"division_code"`
+ Number *string `json:"number" validate:"maxLength=20"`
+ Position_Code ero.EmployeePosisitionCode `json:"status_code" validate:"maxLength=10"`
+ Status_Code erc.ActiveStatusCode `json:"status_code" validate:"maxLength=10"`
+}
+
func ToResponseList(data []User) []ResponseDto {
resp := make([]ResponseDto, len(data))
for i, u := range data {
diff --git a/internal/domain/main-entities/user/entity.go b/internal/domain/main-entities/user/entity.go
index 3ad46b9d..7a644262 100644
--- a/internal/domain/main-entities/user/entity.go
+++ b/internal/domain/main-entities/user/entity.go
@@ -1,18 +1,22 @@
package user
import (
+ "time"
+
ecore "simrs-vx/internal/domain/base-entities/core"
erc "simrs-vx/internal/domain/references/common"
- "time"
+ ero "simrs-vx/internal/domain/references/organization"
)
type User struct {
- ecore.Main // adjust this according to the needs
- Name string `json:"name" gorm:"unique;not null;size:25"`
- Password string `json:"password" gorm:"not null;size:255"`
- Status_Code erc.UserStatusCode `json:"status_code" gorm:"not null;size:10"`
- FailedLoginCount uint8 `json:"failedLoginCount" gorm:"type:smallint"`
- LoginAttemptCount int `json:"-"`
- LastSuccessLogin *time.Time `json:"lastSuccessLogin,omitempty"`
- LastAllowdLogin *time.Time `json:"lastAllowdLogin,omitempty"`
+ ecore.Main // adjust this according to the needs
+ Name string `json:"name" gorm:"unique;not null;size:25"`
+ Password string `json:"password" gorm:"not null;size:255"`
+ Status_Code erc.UserStatusCode `json:"status_code" gorm:"not null;size:10"`
+ FailedLoginCount uint8 `json:"failedLoginCount" gorm:"type:smallint"`
+ // Position_Code ero.EmployeePosisitionCode `json:"position_code" gorm:"not null;size:20"`
+ ContractPosition_Code ero.ContractPositionCode `json:"contractPosition_Code" gorm:"not null;size:20"`
+ LoginAttemptCount int `json:"-"`
+ LastSuccessLogin *time.Time `json:"lastSuccessLogin,omitempty"`
+ LastAllowdLogin *time.Time `json:"lastAllowdLogin,omitempty"`
}
diff --git a/internal/domain/main-entities/vehicle-hist/entity.go b/internal/domain/main-entities/vehicle-hist/entity.go
new file mode 100644
index 00000000..0d91267d
--- /dev/null
+++ b/internal/domain/main-entities/vehicle-hist/entity.go
@@ -0,0 +1,17 @@
+package vehicle_hist
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ev "simrs-vx/internal/domain/main-entities/vehicle"
+ erc "simrs-vx/internal/domain/references/common"
+ "time"
+)
+
+type VehicleHist struct {
+ ecore.Main // adjust this according to the needs
+ Vehicle_Id *uint `json:"vehicle_id"`
+ Vehicle *ev.Vehicle `json:"vehicle,omitempty" gorm:"foreignKey:Vehicle_Id;references:Id"`
+ Date *time.Time `json:"date"`
+ Data *string `json:"data"`
+ Crud_Code *erc.CrudCode `json:"crud_code"`
+}
diff --git a/internal/domain/main-entities/vehicle/entity.go b/internal/domain/main-entities/vehicle/entity.go
new file mode 100644
index 00000000..89661781
--- /dev/null
+++ b/internal/domain/main-entities/vehicle/entity.go
@@ -0,0 +1,15 @@
+package vehicle
+
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ercl "simrs-vx/internal/domain/references/clinical"
+)
+
+type Vehicle struct {
+ ecore.Main // adjust this according to the needs
+ Type_Code *ercl.VehicleTypeCode `json:"type_code"`
+ PoliceNumber *string `json:"policeNumber"`
+ FrameNumber *string `json:"frameNumber"`
+ RegNumber *string `json:"regNumber"`
+ AvailableStatus bool `json:"availableStatus"`
+}
diff --git a/internal/domain/main-entities/village/base/entity.go b/internal/domain/main-entities/village/base/entity.go
new file mode 100644
index 00000000..97f5347f
--- /dev/null
+++ b/internal/domain/main-entities/village/base/entity.go
@@ -0,0 +1,12 @@
+package base
+
+type Basic struct {
+ Id uint32 `json:"id" gorm:"primaryKey"`
+ District_Code string `json:"district_code" gorm:"size:6"`
+ Code string `json:"code" gorm:"unique;size:10"`
+ Name string `json:"name" gorm:"size:50"`
+}
+
+func (Basic) TableName() string {
+ return "Village"
+}
diff --git a/internal/domain/main-entities/village/dto.go b/internal/domain/main-entities/village/dto.go
index 968784ee..bfa8cfc3 100644
--- a/internal/domain/main-entities/village/dto.go
+++ b/internal/domain/main-entities/village/dto.go
@@ -1,5 +1,12 @@
package village
+import (
+ ecore "simrs-vx/internal/domain/base-entities/core"
+ ed "simrs-vx/internal/domain/main-entities/district"
+ epb "simrs-vx/internal/domain/main-entities/postal-region/base"
+ evb "simrs-vx/internal/domain/main-entities/village/base"
+)
+
type CreateDto struct {
District_Code string `json:"district_code" validate:"numeric;maxLength=6"`
Code string `json:"code" validate:"numeric;maxLength=10"`
@@ -7,13 +14,17 @@ type CreateDto struct {
}
type ReadListDto struct {
- District_Code string `json:"district_code"`
+ FilterDto
+ Includes string `json:"includes"`
+ Sort string `json:"sort"`
+ Pagination ecore.Pagination
+}
+
+type FilterDto struct {
+ District_Code string `json:"district-code"`
Code string `json:"code"`
Name string `json:"name"`
-
- Page int `json:"page"`
- PageSize int `json:"page_size"`
- NoPagination int `json:"no_pagination"`
+ Search string `json:"search" gormhelper:"searchColumns=Code,Name"`
}
type ReadDetailDto struct {
@@ -37,14 +48,17 @@ type MetaDto struct {
}
type ResponseDto struct {
- Id uint32 `json:"id"`
- District_Code string `json:"district_code"`
- Code string `json:"code"`
- Name string `json:"name"`
+ evb.Basic
+ District *ed.District `json:"district,omitempty"`
+ PostalRegions []epb.Basic `json:"postalRegions,omitempty"`
}
func (d Village) ToResponse() ResponseDto {
- resp := ResponseDto(d)
+ resp := ResponseDto{
+ Basic: d.Basic,
+ District: d.District,
+ PostalRegions: d.PostalRegions,
+ }
return resp
}
diff --git a/internal/domain/main-entities/village/entity.go b/internal/domain/main-entities/village/entity.go
index aae0caf5..ca5fb4af 100644
--- a/internal/domain/main-entities/village/entity.go
+++ b/internal/domain/main-entities/village/entity.go
@@ -1,8 +1,13 @@
package village
+import (
+ ed "simrs-vx/internal/domain/main-entities/district"
+ epb "simrs-vx/internal/domain/main-entities/postal-region/base"
+ evb "simrs-vx/internal/domain/main-entities/village/base"
+)
+
type Village struct {
- Id uint32 `json:"id" gorm:"primaryKey"`
- District_Code string `json:"district_code" gorm:"size:6"` // NOT: THE PROPER SIZE IS 6
- Code string `json:"code" gorm:"unique;size:10"`
- Name string `json:"name" gorm:"size:50"`
+ evb.Basic
+ District *ed.District `json:"district,omitempty" gorm:"foreignKey:District_Code;references:Code"`
+ PostalRegions []epb.Basic `json:"postalRegions,omitempty" gorm:"foreignKey:Village_Code;references:Code"`
}
diff --git a/internal/domain/references/clinical/clinical.go b/internal/domain/references/clinical/clinical.go
index 3998811b..47872aa5 100644
--- a/internal/domain/references/clinical/clinical.go
+++ b/internal/domain/references/clinical/clinical.go
@@ -1,38 +1,232 @@
+// Package clinical mostly about SOAPI
package clinical
type (
- SubjectCode string
- ObjectCode string
- AssessmentCode string
- InstructionCode string
+ SubjectCode string
+ ObjectCode string
+ AssessmentCode string
+ PlanCode string
+ InstructionCode string
+ HeadToToeCode string
+ McuUrgencyLevelCode string
+ SoapiTypeCode string
+ MedicalAction string
+ VehicleTypeCode string
)
const (
- SCPrimaryComplaint SubjectCode = "pri-compl" // Keluhan Utama
- SCSecComplaint SubjectCode = "sec-compl" // Secondary Complaint
+ SCPrimaryComplain SubjectCode = "pri-complain" // Keluhan Utama
+ SCSecComplain SubjectCode = "sec-complain" // Secondary Complaint
SCCurrentDiseaseHistory SubjectCode = "cur-disea-hist" // Current Disease History
SCPastDiseaseHistory SubjectCode = "pas-disea-hist" // Past Disease History
SCFamilyDiseaseHistory SubjectCode = "fam-disea-hist" // Family Disease History
SCAllergyHistory SubjectCode = "alg-hist" // Allergic History
SCAllergyReaction SubjectCode = "alg-react" // Allergic Reaction
SCMedicationHistory SubjectCode = "med-hist" // Medication History
+ SCBloodType SubjectCode = "blood-type" // Blood Type
- OCConsciousnessLevel ObjectCode = "consc-level" // Tingkat Kesadaran
- OCConsciousnessLevelDet ObjectCode = "consc-level-det" // Detail Tingkat Kesadaran
- OCSystolicBloodPressure ObjectCode = "syst-bp" // Tekanan Darah Systolic
- OCDiastolicBloodPressure ObjectCode = "diast-bp" // Tekanan Darah Diastolic
- OCHeartRate ObjectCode = "hear-rt" // Detak Jantung
- OCTemperature ObjectCode = "temp" // Suhu
- OCSpO2 ObjectCode = "spo2" // SpO2
- OCWeight ObjectCode = "weight" // Berat Badan
- OCHeight ObjectCode = "height" // Tinggi Badan
+ OCConsciousnessLevel ObjectCode = "consc-level" // Tingkat Kesadaran
+ OCConsciousnessLevelDet ObjectCode = "consc-level-det" // Detail Tingkat Kesadaran
+ OCSystolicBloodPressure ObjectCode = "syst-bp" // Tekanan Darah Systolic
+ OCDiastolicBloodPressure ObjectCode = "diast-bp" // Tekanan Darah Diastolic
+ OCPulse ObjectCode = "pulse" // Nadi
+ OCRespiratoryRate ObjectCode = "resp-rate" // Pernafasan
+ OCHeartRate ObjectCode = "hear-rt" // Detak Jantung
+ OCNeuroCranialis ObjectCode = "neuro-cranialis" // Neurologist Cranialist
+ OCSensoris ObjectCode = "sensoris" // Sensoris
+ OCReflectFisio ObjectCode = "reflect-fisio" // Refleks Fisiologi
+ OCReflectPato ObjectCode = "reflect-pato" // Refleks Patologi
+ OCAutonomNeuron ObjectCode = "autonom-neuron" // Saraf Otonom
+ OCNeckRom ObjectCode = "neck-rom" // ROM Leher
+ OCBodyRom ObjectCode = "body-rom" // ROM Batang Tubuh
+ OCAgaRom ObjectCode = "aga-rom" // ROM AGA
+ OCAgbRom ObjectCode = "agb-rom" // ROM AGB
+ OCNeckMmt ObjectCode = "neck-mmt" // MMT Leher
+ OCBodyMmt ObjectCode = "body-mmt" // MMT Batang Tubuh
+ OCAgaMmt ObjectCode = "aga-mmt" // MMT AGA
+ OCAgbMmt ObjectCode = "agb-mmt" // MMT AGB
+ OCLocalis ObjectCode = "localis" // Status Lokalis
+ OCMedicalTrouble ObjectCode = "medical-trouble" // Masalah Medis
+ OCRehabMedicTrouble ObjectCode = "rehab-medic-trouble" // Masalah Rehab Medik
+ OCTemperature ObjectCode = "temp" // Suhu
+ OCSpO2 ObjectCode = "spo2" // SpO2
+ OCWeight ObjectCode = "weight" // Berat Badan
+ OCHeight ObjectCode = "height" // Tinggi Badan
+ OCHeadToToe ObjectCode = "head-to-toe" // Kepala Sampai Kaki
ACEarlyDiag AssessmentCode = "early-diag" // Diagnosis Awal
ACLateDiag AssessmentCode = "late-diag" // Diagnosis Akhir
ACSecDiag AssessmentCode = "sec-diag" // Diagnosis Sekunder
- ICDetail InstructionCode = "detail" // Detail instruksi
- ICMedAct InstructionCode = "med-act" // Tindakan medis
- ICMedication InstructionCode = "medication" // Obat
- ICMaterial InstructionCode = "material" // BMHP
+ PCPlan PlanCode = "plan" // Rencana
+
+ ICDetail InstructionCode = "detail" // Detail Instruksi
+ ICMedAct InstructionCode = "medical-act" // Tindakan Medis
+ ICSupExam InstructionCode = "supporting-exam" // Pemeriksaan Penunjang
+ ICTherapy InstructionCode = "therapy" // Terapi
+ ICMedication InstructionCode = "medication" // Obat
+ ICMaterial InstructionCode = "material" // BMHP
+ ICREhabProg InstructionCode = "rehab-program" // Program Rehab
+ ICPhyMod InstructionCode = "physic-modal" // Modalitas Fisik
+ ICExcercise InstructionCode = "exercise" // Latihan
+ ICOrtPro InstructionCode = "ortes-protesa" // Ortesa Protesa
+ ICEducation InstructionCode = "education" // Edukasi
+ ICOther InstructionCode = "other" // Lain-lain
+
+ HTTHead HeadToToeCode = "head"
+ HTTEye HeadToToeCode = "eye"
+ HTTEar HeadToToeCode = "ear"
+ HTTNose HeadToToeCode = "nose"
+ HTTMouthThroat HeadToToeCode = "mouth-throat"
+ HTTHeadOthers HeadToToeCode = "head-others"
+ HTTThorax HeadToToeCode = "thorax"
+ HTTHeart HeadToToeCode = "heart"
+ HTTLung HeadToToeCode = "lung"
+ HTTAbdomen HeadToToeCode = "abdomen"
+ HTTLiver HeadToToeCode = "liver"
+ HTTBack HeadToToeCode = "back"
+ HTTEkstremitas HeadToToeCode = "ekstremitas"
+ HTTGender HeadToToeCode = "gender"
+ HTTRectum HeadToToeCode = "rectum"
+ HTTNeuron HeadToToeCode = "neuron"
+ HTTBodyOthers HeadToToeCode = "body-others"
+
+ MULCCITO McuUrgencyLevelCode = "cito" // CITO
+ MULCCITOIGD McuUrgencyLevelCode = "cito-igd" // CITO IGD
+ MULCPonek McuUrgencyLevelCode = "ponek" // PONEK
+ MULCBG McuUrgencyLevelCode = "blood-gas" // Analisa Gas Darah
+ MULCPF McuUrgencyLevelCode = "priority-form" // Form Prioritas
+ MULCRT McuUrgencyLevelCode = "routine" // Pemeriksaan Rutin
+
+ STCEarlyNurse SoapiTypeCode = "early-nurse" // Kajian Awal Medis
+ STCEEarlyMedic SoapiTypeCode = "early-medic" // Kajian Awal Rehab Medis
+ STCEarlyRehab SoapiTypeCode = "early-rehab" // Kajian Awal Rehab Medik
+ STCFunc SoapiTypeCode = "function" // Assessment Fungsi
+ STCProgress SoapiTypeCode = "progress" // CPPT
+
+ MAChemo MedicalAction = "chemo"
+ MAHemo MedicalAction = "hemo"
+ MAThalasemia MedicalAction = "thalasemia"
+ MAEchocardio MedicalAction = "echocardio"
+ MASpirometry MedicalAction = "spirometry"
+
+ VTCAmbulance VehicleTypeCode = "ambulance" // Ambulans
+ VTCTransport VehicleTypeCode = "transport" // Transport
+ VTCHearse VehicleTypeCode = "hearse" // Jenazah
)
+
+type Soapi struct {
+ Subject SubjectSection `json:"subject"`
+ Object ObjectSection `json:"object"`
+ Assessment AssessmentSection `json:"assessment"`
+ Plan string `json:"plan"`
+ Instruction InstructionSection `json:"instruction"`
+}
+
+// ---------------- SUBJECT ----------------
+type SubjectSection struct {
+ Note string `json:"note,omitempty"`
+ PrimComplain string `json:"prim-compl,omitempty"`
+ SecComplainQ string `json:"sec-compl,omitempty"`
+ PrimaryComplain string `json:"pri-complain,omitempty"`
+ SecondaryComplain string `json:"sec-complain,omitempty"`
+ CurrentDiseaseHistory string `json:"cur-disea-hist,omitempty"`
+ PastDiseaseHistory string `json:"pas-disea-hist,omitempty"`
+ FamilyDiseaseHistory string `json:"fam-disea-hist,omitempty"`
+ AllergyHistory string `json:"alg-hist,omitempty"`
+ AllergyReaction string `json:"alg-react,omitempty"`
+ MedicationHistory string `json:"med-hist,omitempty"`
+ BloodType string `json:"blood-type,omitempty"`
+}
+
+// ---------------- OBJECT ----------------
+type ObjectSection struct {
+ Note string `json:"note,omitempty"`
+ ConsciousnessLevel string `json:"consc-level,omitempty"`
+ ConsciousnessLevelDet string `json:"consc-level-det,omitempty"`
+ SystolicBloodPressure string `json:"syst-bp,omitempty"`
+ DiastolicBloodPressure string `json:"diast-bp,omitempty"`
+ Pulse string `json:"pulse,omitempty"`
+ RespiratoryRate string `json:"resp-rate,omitempty"`
+ HeartRate string `json:"hear-rt,omitempty"`
+ NeuroCranialis string `json:"neuro-cranialis,omitempty"`
+ Sensoris string `json:"sensoris,omitempty"`
+ ReflectFisio string `json:"reflect-fisio,omitempty"`
+ ReflectPato string `json:"reflect-pato,omitempty"`
+ AutonomNeuron string `json:"autonom-neuron,omitempty"`
+ NeckRom string `json:"neck-rom,omitempty"`
+ BodyRom string `json:"body-rom,omitempty"`
+ AgaRom string `json:"aga-rom,omitempty"`
+ AgbRom string `json:"agb-rom,omitempty"`
+ NeckMmt string `json:"neck-mmt,omitempty"`
+ BodyMmt string `json:"body-mmt,omitempty"`
+ AgaMmt string `json:"aga-mmt,omitempty"`
+ AgbMmt string `json:"agb-mmt,omitempty"`
+ Localis string `json:"localis,omitempty"`
+ MedicalTrouble string `json:"medical-trouble,omitempty"`
+ RehabMedicTrouble string `json:"rehab-medic-trouble,omitempty"`
+ Temperature string `json:"temp,omitempty"`
+ SpO2 string `json:"spo2,omitempty"`
+ Weight string `json:"weight,omitempty"`
+ Height string `json:"height,omitempty"`
+ HeadToToe HeadToToe `json:"head-to-toe,omitempty"`
+}
+
+// ---------------- ASSESSMENT ----------------
+type AssessmentSection struct {
+ EarlyDiagnosis DiagnosisDetail `json:"early-diag,omitempty"`
+ LateDiagnosis DiagnosisDetail `json:"late-diag,omitempty"`
+ SecondaryDiag DiagnosisDetail `json:"sec-diag,omitempty"`
+}
+
+// nested object {note, codes}
+type DiagnosisDetail struct {
+ Note string `json:"note,omitempty"`
+ Codes []CodeWithName `json:"codes,omitempty"`
+}
+
+// ---------------- INSTRUCTION ----------------
+type InstructionSection struct {
+ Detail string `json:"detail,omitempty"`
+ MedicalAction CodesWithNote `json:"medical-act,omitempty"`
+ SupportingExam []CodeWithName `json:"supporting-exam,omitempty"`
+ Therapy string `json:"therapy,omitempty"`
+ Medication []CodeWithName `json:"medication,omitempty"`
+ Material []CodeWithName `json:"material,omitempty"`
+ RehabProgram string `json:"rehab-program,omitempty"`
+ PhysicModal string `json:"physic-modal,omitempty"`
+ Exercise string `json:"exercise,omitempty"`
+ OrtesProsthesis string `json:"ortes-protesa,omitempty"`
+ Education string `json:"education,omitempty"`
+ Other string `json:"other,omitempty"`
+}
+
+// ---------------- CODES ----------------
+type CodeWithName struct {
+ Code string `json:"code,omitempty"`
+ Name string `json:"name,omitempty"`
+}
+type CodesWithNote struct {
+ Note string `json:"note,omitempty"`
+ Codes []CodeWithName `json:"codes,omitempty"`
+}
+
+type HeadToToe struct {
+ Head string `json:"head,omitempty"`
+ Eye string `json:"eye,omitempty"`
+ Ear string `json:"ear,omitempty"`
+ Nose string `json:"nose,omitempty"`
+ MouthThroat string `json:"mouth-throat,omitempty"`
+ HeadOthers string `json:"head-others,omitempty"`
+ Thorax string `json:"thorax,omitempty"`
+ Heart string `json:"heart,omitempty"`
+ Lung string `json:"lung,omitempty"`
+ Abdomen string `json:"abdomen,omitempty"`
+ Liver string `json:"liver,omitempty"`
+ Back string `json:"back,omitempty"`
+ Ekstremitas string `json:"ekstremitas,omitempty"`
+ Gender string `json:"gender,omitempty"`
+ Rectum string `json:"rectum,omitempty"`
+ Neuron string `json:"neuron,omitempty"`
+ BodyOthers string `json:"body-others,omitempty"`
+}
diff --git a/internal/domain/references/common/common.go b/internal/domain/references/common/common.go
index d60ee8a3..9e532b14 100644
--- a/internal/domain/references/common/common.go
+++ b/internal/domain/references/common/common.go
@@ -1,17 +1,20 @@
package common
type (
- YaTidakCode byte
- SudahBelumCode byte
- AktifSimpelCode byte
- AktifAdvanceCode byte
- TersediaCode byte
- DayCode byte
- ActiveStatusCode string
- DataStatusCode string
- UserStatusCode string
- TimeUnitCode string
- PaymentMethodCode string
+ YaTidakCode byte
+ SudahBelumCode byte
+ AktifSimpelCode byte
+ AktifAdvanceCode byte
+ TersediaCode byte
+ DayCode byte
+ ActiveStatusCode string
+ DataStatusCode string
+ UserStatusCode string
+ TimeUnitCode string
+ PaymentMethodCode string
+ DataAvailabilityCode string
+ DataVerifiedCode string
+ CrudCode string
)
const (
@@ -61,6 +64,14 @@ const (
DSCRejected DataStatusCode = "rejected" // Ditolak
DSCSkipped DataStatusCode = "skipped" // Dilewati
+ DACReview DataAvailabilityCode = "review" // Konfirmasi
+ DACAvailable DataAvailabilityCode = "available" // Tersedia
+ DACUnavailable DataAvailabilityCode = "unavailable" // Tidak Tersedia
+
+ DVCNew DataVerifiedCode = "new" // Baru
+ DVCVerified DataVerifiedCode = "verified" // Terverifikasi
+ DVCRejected DataVerifiedCode = "rejected" // Ditolak
+
USCNew UserStatusCode = "new" // Baru
USCActive UserStatusCode = "active" // Aktif
USCInactive UserStatusCode = "inactive" // Tidak aktif
@@ -81,6 +92,10 @@ const (
PMCInsurance PaymentMethodCode = "insurance" // Asuransi
PMCMembership PaymentMethodCode = "membership" // Member
+ CCCreate CrudCode = "c" // Create
+ CCRead CrudCode = "r" // Read
+ CCUpdate CrudCode = "u" // Update
+ CCDelete CrudCode = "d" // Delete
)
func GetDayCodes() map[DayCode]string {
diff --git a/internal/domain/references/encounter/encounter.go b/internal/domain/references/encounter/encounter.go
index 00b01236..5b9515ec 100644
--- a/internal/domain/references/encounter/encounter.go
+++ b/internal/domain/references/encounter/encounter.go
@@ -1,25 +1,26 @@
package encounter
type (
- EncounterClassCode string
- QueueStatusCode string
- DischargeMethodCode string
- TransportationCode string
- PersonConditionCode string
- EmergencyClassCode string
- OutpatientClassCode string
- CheckupScopeCode string
+ EncounterClassCode string
+ QueueStatusCode string
+ DischargeMethodCode string
+ TransportationCode string
+ PersonConditionCode string
+ EmergencyClassCode string
+ OutpatientClassCode string
+ CheckupScopeCode string
+ AmbulatoryClassCode string
+ InpatientClassCode string
+ UploadCode string
+ ChemoClassCode string
+ AmbulanceFacilityCode string
+ AmbulanceNeedsCode string
)
const (
- ECOutpatient EncounterClassCode = "outpatient"
- ECAmbulatory EncounterClassCode = "ambulatory"
- ECEmergency EncounterClassCode = "emergency"
- ECInpatient EncounterClassCode = "inpatient"
- ECDraft EncounterClassCode = "draft"
- ECDone EncounterClassCode = "done"
- ECCancel EncounterClassCode = "cancel"
- ECSkip EncounterClassCode = "skip"
+ ECAmbulatory EncounterClassCode = "ambulatory" // Rawat Jalan
+ ECEmergency EncounterClassCode = "emergency" // Gawat Darurat
+ ECInpatient EncounterClassCode = "inpatient" // Rawat Inap
QSCWait QueueStatusCode = "wait" // Tunggu
QSCProc QueueStatusCode = "proc" // Proses
@@ -27,19 +28,29 @@ const (
QSCCancel QueueStatusCode = "cancel" // Dibatalkan
QSCSkip QueueStatusCode = "skip" // Dilewati
- DMCHome DischargeMethodCode = "home" // Rumah
- DMCHomeReq DischargeMethodCode = "home-request" // Rumah (Dibutuhkan)
+ DMCHome DischargeMethodCode = "home" // Pulang
+ DMCHomeReq DischargeMethodCode = "home-request" // Pulang Atas Permintaan Sendiri
+ DMCConsulBack DischargeMethodCode = "consul-back" // Konsultasi Balik / Lanjutan
+ DMCConsulPoly DischargeMethodCode = "consul-poly" // Konsultasi Poliklinik Lain
+ DMCConsulExecutive DischargeMethodCode = "consul-executive" // Konsultasi Antar Dokter Eksekutif
+ DMCConsulChDay DischargeMethodCode = "consul-ch-day" // Konsultasi Hari Lain
+ DMCEmergency DischargeMethodCode = "emergency" // Rujuk IGD
+ DMCEmergencyCovid DischargeMethodCode = "emergency-covid" // Rujuk IGD Covid
+ DMCInpatient DischargeMethodCode = "inpatient" // Rujuk Rawat Inap
+ DMCExtRef DischargeMethodCode = "external" // Rujuk Faskes Lain
+ DMCDeath DischargeMethodCode = "death" // Meninggal
+ DMCDeathOnArrival DischargeMethodCode = "death-on-arrival" // Meninggal Saat Tiba
- TCAmbulance TransportationCode = "ambulance"
- TCCar TransportationCode = "car"
- TCMotorCycle TransportationCode = "motor-cycle"
- TCOther TransportationCode = "other"
+ TCAmbulance TransportationCode = "ambulance" // Ambulans
+ TCCar TransportationCode = "car" // Mobil
+ TCMotorCycle TransportationCode = "motor-cycle" // Motor
+ TCOther TransportationCode = "other" // Lainnya
PCCRes PersonConditionCode = "res" // Resutiasi
PCCEmg PersonConditionCode = "emg" // Darurat
PCCUrg PersonConditionCode = "urg" // Mendesak
PCCLurg PersonConditionCode = "lurg" // Kurang mendesak
- PCCNurg PersonConditionCode = "nurg" //
+ PCCNurg PersonConditionCode = "nurg" // Mendesak
PCCDoa PersonConditionCode = "doa" // Meninggal saat tiba
ECCEmg EmergencyClassCode = "emg" // Darurat/Emergency biasa
@@ -55,11 +66,35 @@ const (
CSCPLab CheckupScopeCode = "pa-lab" // Patology Anatomy Laboratorium
CSCRad CheckupScopeCode = "radiology" // Radiology
+ ACCReg AmbulatoryClassCode = "reg" // Regular
+ ACCRme AmbulatoryClassCode = "rme" // Rehab Medik
+ ACCCad AmbulatoryClassCode = "chemo-adm" // Chemotherapy
+ ACCCac AmbulatoryClassCode = "chemo-act" // Chemotherapy
+
+ ICCIp InpatientClassCode = "ip" // Regular Rawat Inap
+ ICCICU InpatientClassCode = "icu" // ICU
+ ICCHCU InpatientClassCode = "hcu" // HCU
+ ICCVK InpatientClassCode = "vk" // Verlos kamer
+
+ UCPRN UploadCode = "person-resident-number" // Person Resident Number
+ UCPDL UploadCode = "person-driver-license" // Person Driver License
+ UCPP UploadCode = "person-passport" // Person Passport
+ UCPFC UploadCode = "person-family-card" // Person Family Card
+ UCMIR UploadCode = "mcu-item-result" // Mcu Item Result
+
+ CCCAdm ChemoClassCode = "adm" // Administrasi
+ CCCAct ChemoClassCode = "act" // Tindakan
+
+ AFCStd AmbulanceFacilityCode = "std" // Standar
+ AFCIcu AmbulanceFacilityCode = "icu" // ICU
+
+ ANCAssist AmbulanceNeedsCode = "assist" // Dengan Pendampingan
+ ANCNonassist AmbulanceNeedsCode = "non-assist" // Tanpa Pendampingan
)
func (ec EncounterClassCode) Code() string {
switch ec {
- case ECAmbulatory, ECOutpatient:
+ case ECAmbulatory:
return "AMB"
case ECInpatient:
return "IMP"
@@ -69,3 +104,12 @@ func (ec EncounterClassCode) Code() string {
return "UNKNOWN"
}
}
+
+func IsValidUploadCode(code UploadCode) bool {
+ switch UploadCode(code) {
+ case UCPRN, UCPDL, UCPP, UCPFC, UCMIR:
+ return true
+ default:
+ return false
+ }
+}
diff --git a/internal/domain/references/organization/organization.go b/internal/domain/references/organization/organization.go
index 5c86ba51..f2482e9a 100644
--- a/internal/domain/references/organization/organization.go
+++ b/internal/domain/references/organization/organization.go
@@ -1,7 +1,9 @@
package organization
type (
+ ContractPositionCode string
EmployeePosisitionCode string
+ InternPosisitionCode string
ItemGroupCode string
InfraGroupCode string
UnitTypeCode string
@@ -9,14 +11,23 @@ type (
)
const (
- EPCDoc EmployeePosisitionCode = "doctor" // Dokter
- EPCNur EmployeePosisitionCode = "nurse" // Perawat
- EPCNut EmployeePosisitionCode = "nutritionist" // Ahli gizi
- EPCLab EmployeePosisitionCode = "laborant" // Laboran
- EPCPha EmployeePosisitionCode = "pharmacy" // Farmasi
- EPCPay EmployeePosisitionCode = "payment" // Pembayaran
- EPCPav EmployeePosisitionCode = "payment-verificator" // Konfirmasi pembayaran
- EPCMan EmployeePosisitionCode = "management" // Manajemen
+ CSCEmp ContractPositionCode = "employee" // Pegawai
+ CSCSpi ContractPositionCode = "intern" // PPDS
+
+ EPCReg EmployeePosisitionCode = "registration" // Admisi/Pendaftaran
+ EPCNur EmployeePosisitionCode = "nurse" // Perawat
+ EPCDoc EmployeePosisitionCode = "doctor" // Dokter
+ EPCNut EmployeePosisitionCode = "nutritionist" // Ahli gizi
+ EPCMwi EmployeePosisitionCode = "mid-wife" // Bidan
+ EPCLab EmployeePosisitionCode = "laborant" // Laboran
+ EPCPha EmployeePosisitionCode = "pharmacy" // Farmasi
+ EPCPay EmployeePosisitionCode = "payment" // Pembayaran
+ EPCHur EmployeePosisitionCode = "human-resource" // Sumber Daya Manusia
+ EPCGea EmployeePosisitionCode = "general-affair" // Bagian Umum
+ EPCMan EmployeePosisitionCode = "management" // Manajemen
+
+ IPCSpecialist = "specialist-intern"
+ IPCNurse = "nurse-intern"
ITGCInfra ItemGroupCode = "infra"
ITGCMedicine ItemGroupCode = "medicine"
diff --git a/internal/domain/references/person/person.go b/internal/domain/references/person/person.go
index dd41bd25..02d0f97e 100644
--- a/internal/domain/references/person/person.go
+++ b/internal/domain/references/person/person.go
@@ -12,6 +12,7 @@ type (
RelativeCode string
ContactTypeCode string
RelationshipCode string
+ AddressLocationTypeCode string
)
const (
@@ -109,182 +110,185 @@ const (
RCNephew RelationshipCode = "nephew" // Keponakan
RCGdChild RelationshipCode = "gd-child" // Cucu
RCOther RelationshipCode = "other" // Lainnya
+
+ ALTCIdn AddressLocationTypeCode = "identity" // Sesuai Identitas
+ ALTCDom AddressLocationTypeCode = "domicile" // Sesuai Domisili
)
-func GetGenderCodes() map[GenderCode]string {
- return map[GenderCode]string{
- GCMale: "Laki-laki",
- GCFemale: "Perempuan",
- GCNotStated: "Tidak disebutkan",
- GCUnknown: "Tidak diketahui",
- }
-}
+// func GetGenderCodes() map[GenderCode]string {
+// return map[GenderCode]string{
+// GCMale: "Laki-laki",
+// GCFemale: "Perempuan",
+// GCNotStated: "Tidak disebutkan",
+// GCUnknown: "Tidak diketahui",
+// }
+// }
-func GetBloodTypeCodes() map[BloodTypeCode]string {
- return map[BloodTypeCode]string{
- BTCAPositive: "A Positive",
- BTCANegative: "A Negative",
- BTCABPositive: "AB Positive",
- BTCABNegative: "AB Negative",
- BTCBPositive: "B Positive",
- BTCBNegative: "B Negative",
- BTCOPositive: "O Positive",
- BTCONegative: "O Negative",
- }
-}
+// func GetBloodTypeCodes() map[BloodTypeCode]string {
+// return map[BloodTypeCode]string{
+// BTCAPositive: "A Positive",
+// BTCANegative: "A Negative",
+// BTCABPositive: "AB Positive",
+// BTCABNegative: "AB Negative",
+// BTCBPositive: "B Positive",
+// BTCBNegative: "B Negative",
+// BTCOPositive: "O Positive",
+// BTCONegative: "O Negative",
+// }
+// }
-func GetMaritalStatusCodes() map[MaritalStatusCode]string {
- return map[MaritalStatusCode]string{
- MSCBelumKawin: "Belum Kawin",
- MSCKawin: "Kawin",
- MSCCeraiHidup: "Cerai Hidup",
- MSCCeraiMati: "Cerai Mati",
- }
-}
+// func GetMaritalStatusCodes() map[MaritalStatusCode]string {
+// return map[MaritalStatusCode]string{
+// MSCBelumKawin: "Belum Kawin",
+// MSCKawin: "Kawin",
+// MSCCeraiHidup: "Cerai Hidup",
+// MSCCeraiMati: "Cerai Mati",
+// }
+// }
-func GetReligionCodes() map[ReligionCode]string {
- return map[ReligionCode]string{
- RCIslam: "Islam",
- RCProtestan: "Kristen (Protestan)",
- RCKatolik: "Katolik",
- RCHindu: "Hindu",
- RCBudha: "Budha",
- RCKonghucu: "Konghucu",
- }
-}
+// func GetReligionCodes() map[ReligionCode]string {
+// return map[ReligionCode]string{
+// RCIslam: "Islam",
+// RCProtestan: "Kristen (Protestan)",
+// RCKatolik: "Katolik",
+// RCHindu: "Hindu",
+// RCBudha: "Budha",
+// RCKonghucu: "Konghucu",
+// }
+// }
-func GetEducationCodes() map[EducationCode]string {
- return map[EducationCode]string{
- ECTS: "Tidak Sekolah",
- ECTK: "TK",
- ECSD: "SD",
- ECSLTP: "SMP sederajat",
- ECSLTA: "SMP sederajat",
- ECD1: "D1 sederajat",
- ECD2: "D2 sederajat",
- ECD3: "D3 sederajat",
- ECD4: "D4 sederajat",
- ECS1: "S1",
- ECS2: "S3",
- ECS3: "S3",
- }
-}
+// func GetEducationCodes() map[EducationCode]string {
+// return map[EducationCode]string{
+// ECTS: "Tidak Sekolah",
+// ECTK: "TK",
+// ECSD: "SD",
+// ECSLTP: "SMP sederajat",
+// ECSLTA: "SMP sederajat",
+// ECD1: "D1 sederajat",
+// ECD2: "D2 sederajat",
+// ECD3: "D3 sederajat",
+// ECD4: "D4 sederajat",
+// ECS1: "S1",
+// ECS2: "S3",
+// ECS3: "S3",
+// }
+// }
-func GetOcupationCodes() map[OcupationCode]string {
- return map[OcupationCode]string{
- OCTidakBekerja: "Tidak Bekerja",
- OCPns: "PNS",
- OCTniPolisi: "Polisi",
- OCTni: "TNI",
- OCGuru: "Guru",
- OCWiraswasta: "Wiraswasta",
- OCKarySwasta: "Kary Swasta",
- OCLainlain: "Lain-lain",
- }
-}
+// func GetOcupationCodes() map[OcupationCode]string {
+// return map[OcupationCode]string{
+// OCTidakBekerja: "Tidak Bekerja",
+// OCPns: "PNS",
+// OCTniPolisi: "Polisi",
+// OCTni: "TNI",
+// OCGuru: "Guru",
+// OCWiraswasta: "Wiraswasta",
+// OCKarySwasta: "Kary Swasta",
+// OCLainlain: "Lain-lain",
+// }
+// }
-func GetAgeGroupCodes() map[AgeGroupCode]string {
- return map[AgeGroupCode]string{
- AGCEUnknown: "unknown",
- AGCLTE5: "<=5",
- AGCEU19: "6-19",
- AGCEU29: "20-29",
- AGCEU39: "30-39",
- AGCEU49: "40-49",
- AGCEU59: "50-59",
- AGCGE60: ">=60",
- }
-}
+// func GetAgeGroupCodes() map[AgeGroupCode]string {
+// return map[AgeGroupCode]string{
+// AGCEUnknown: "unknown",
+// AGCLTE5: "<=5",
+// AGCEU19: "6-19",
+// AGCEU29: "20-29",
+// AGCEU39: "30-39",
+// AGCEU49: "40-49",
+// AGCEU59: "50-59",
+// AGCGE60: ">=60",
+// }
+// }
-func GetAgeGroupForMedicineCodes() map[AgeGroupForMedicineCode]string {
- return map[AgeGroupForMedicineCode]string{
- AGMCNew: "new-born",
- AGMCInfant: "infant",
- AGMCToddler: "toddler",
- AGMCKid: "kid",
- AGMCAdult: "adult",
- }
-}
+// func GetAgeGroupForMedicineCodes() map[AgeGroupForMedicineCode]string {
+// return map[AgeGroupForMedicineCode]string{
+// AGMCNew: "new-born",
+// AGMCInfant: "infant",
+// AGMCToddler: "toddler",
+// AGMCKid: "kid",
+// AGMCAdult: "adult",
+// }
+// }
-func GetRelativeCodes() map[RelativeCode]string {
- return map[RelativeCode]string{
- RCMSuami: "Suami",
- RCMIstri: "Istri",
- RCMAnak: "Anak",
- RCMMenantu: "Menantu",
- RCMCucu: "Cucu",
- RCMOrangTua: "Orang Tua",
- RCMMertua: "Mertua",
- RCMAdik: "Adik",
- RCMKeponakan: "Keponakan",
- RCMKakak: "Kakak",
- RCMPaman: "Paman",
- RCMBibi: "Bibi",
- RCMPamanKakek: "Kakek",
- RCMPamanNenek: "Nenek",
- }
-}
+// func GetRelativeCodes() map[RelativeCode]string {
+// return map[RelativeCode]string{
+// RCMSuami: "Suami",
+// RCMIstri: "Istri",
+// RCMAnak: "Anak",
+// RCMMenantu: "Menantu",
+// RCMCucu: "Cucu",
+// RCMOrangTua: "Orang Tua",
+// RCMMertua: "Mertua",
+// RCMAdik: "Adik",
+// RCMKeponakan: "Keponakan",
+// RCMKakak: "Kakak",
+// RCMPaman: "Paman",
+// RCMBibi: "Bibi",
+// RCMPamanKakek: "Kakek",
+// RCMPamanNenek: "Nenek",
+// }
+// }
-func GetContactTypeCodes() map[ContactTypeCode]string {
- return map[ContactTypeCode]string{
- CTPhone: "Telepon",
- CTMPhone: "Telepon Seluler",
- CTEmail: "Email",
- CTFax: "Fax",
- }
-}
+// func GetContactTypeCodes() map[ContactTypeCode]string {
+// return map[ContactTypeCode]string{
+// CTPhone: "Telepon",
+// CTMPhone: "Telepon Seluler",
+// CTEmail: "Email",
+// CTFax: "Fax",
+// }
+// }
-func GetRelationshipCodes() map[RelationshipCode]string {
- return map[RelationshipCode]string{
- RCMother: "Ibu",
- RCFather: "Ayah",
- RCUncle: "Paman",
- RCAunt: "Bibi",
- RCSibling: "Saudara",
- RCGdMother: "Nenek",
- RCGdFather: "Kakek",
- RCChild: "Anak",
- RCNephew: "Keponakan",
- RCGdChild: "Cucu",
- RCOther: "Lainnya",
- }
-}
+// func GetRelationshipCodes() map[RelationshipCode]string {
+// return map[RelationshipCode]string{
+// RCMother: "Ibu",
+// RCFather: "Ayah",
+// RCUncle: "Paman",
+// RCAunt: "Bibi",
+// RCSibling: "Saudara",
+// RCGdMother: "Nenek",
+// RCGdFather: "Kakek",
+// RCChild: "Anak",
+// RCNephew: "Keponakan",
+// RCGdChild: "Cucu",
+// RCOther: "Lainnya",
+// }
+// }
-func (obj GenderCode) String() string {
- return GetGenderCodes()[obj]
-}
+// func (obj GenderCode) String() string {
+// return GetGenderCodes()[obj]
+// }
-func (obj BloodTypeCode) String() string {
- return GetBloodTypeCodes()[obj]
-}
+// func (obj BloodTypeCode) String() string {
+// return GetBloodTypeCodes()[obj]
+// }
-func (obj MaritalStatusCode) String() string {
- return GetMaritalStatusCodes()[obj]
-}
+// func (obj MaritalStatusCode) String() string {
+// return GetMaritalStatusCodes()[obj]
+// }
-func (obj ReligionCode) String() string {
- return GetReligionCodes()[obj]
-}
-func (obj EducationCode) String() string {
- return GetEducationCodes()[obj]
-}
+// func (obj ReligionCode) String() string {
+// return GetReligionCodes()[obj]
+// }
+// func (obj EducationCode) String() string {
+// return GetEducationCodes()[obj]
+// }
-func (obj OcupationCode) String() string {
- return GetOcupationCodes()[obj]
-}
+// func (obj OcupationCode) String() string {
+// return GetOcupationCodes()[obj]
+// }
-func (obj AgeGroupCode) String() string {
- return GetAgeGroupCodes()[obj]
-}
+// func (obj AgeGroupCode) String() string {
+// return GetAgeGroupCodes()[obj]
+// }
-func (obj RelativeCode) String() string {
- return GetRelativeCodes()[obj]
-}
+// func (obj RelativeCode) String() string {
+// return GetRelativeCodes()[obj]
+// }
-func (obj ContactTypeCode) String() string {
- return GetContactTypeCodes()[obj]
-}
+// func (obj ContactTypeCode) String() string {
+// return GetContactTypeCodes()[obj]
+// }
-func (obj RelationshipCode) String() string {
- return GetRelationshipCodes()[obj]
-}
+// func (obj RelationshipCode) String() string {
+// return GetRelationshipCodes()[obj]
+// }
diff --git a/internal/domain/satusehat-entities/patient/entity.go b/internal/domain/satusehat-entities/patient/entity.go
new file mode 100644
index 00000000..21c6075b
--- /dev/null
+++ b/internal/domain/satusehat-entities/patient/entity.go
@@ -0,0 +1,92 @@
+package patient
+
+type Patient struct {
+ ResourceType string `json:"resourceType"`
+ // Meta Meta `json:"meta"`
+ // Identifier []Identifier `json:"identifier"`
+ Active bool `json:"active"`
+ // Name []HumanName `json:"name"`
+ // Telecom []ContactPoint `json:"telecom"`
+ Gender string `json:"gender" gorm:"size:10"`
+ BirthDate string `json:"birthDate"`
+ DeceasedBool bool `json:"deceasedBoolean"`
+ // Address []Address `json:"address"`
+ // MaritalStatus MaritalStatus `json:"maritalStatus"`
+ MultipleBirthInteger int `json:"multipleBirthInteger"`
+ // Contact []Contact `json:"contact"`
+ // Communication []Communication `json:"communication"`
+ // Extension []Extension `json:"extension"`
+}
+
+type Meta struct {
+ Profile []string `json:"profile"`
+}
+
+type Identifier struct {
+ Use string `json:"use"`
+ System string `json:"system"`
+ Value string `json:"value"`
+}
+
+type HumanName struct {
+ Use string `json:"use"`
+ Text string `json:"text"`
+}
+
+type ContactPoint struct {
+ System string `json:"system"`
+ Value string `json:"value"`
+ Use string `json:"use"`
+}
+
+type Address struct {
+ Use string `json:"use"`
+ Line []string `json:"line"`
+ City string `json:"city"`
+ PostalCode string `json:"postalCode"`
+ Country string `json:"country"`
+ Extension []Extension `json:"extension"`
+}
+
+type Extension struct {
+ URL string `json:"url"`
+ Extension []SubExtension `json:"extension,omitempty"`
+ ValueCode string `json:"valueCode,omitempty"`
+ ValueAddress *Address `json:"valueAddress,omitempty"`
+}
+
+type SubExtension struct {
+ URL string `json:"url"`
+ ValueCode string `json:"valueCode"`
+}
+
+type MaritalStatus struct {
+ Coding []Coding `json:"coding"`
+ Text string `json:"text"`
+}
+
+type Coding struct {
+ System string `json:"system"`
+ Code string `json:"code"`
+ Display string `json:"display,omitempty"`
+}
+
+type Contact struct {
+ Relationship []Relationship `json:"relationship"`
+ Name HumanName `json:"name"`
+ Telecom []ContactPoint `json:"telecom"`
+}
+
+type Relationship struct {
+ Coding []Coding `json:"coding"`
+}
+
+type Communication struct {
+ Language Language `json:"language"`
+ Preferred bool `json:"preferred"`
+}
+
+type Language struct {
+ Coding []Coding `json:"coding"`
+ Text string `json:"text"`
+}
diff --git a/internal/infra/bpjs/bpjs.go b/internal/infra/bpjs/bpjs.go
new file mode 100644
index 00000000..36935c74
--- /dev/null
+++ b/internal/infra/bpjs/bpjs.go
@@ -0,0 +1,14 @@
+package bpjs
+
+import (
+ a "github.com/karincake/apem"
+ lo "github.com/karincake/apem/loggero"
+)
+
+func SetConfig() {
+ a.ParseSingleCfg(&O)
+ if O.BaseUrl == "" {
+ panic("config bpjs base url empty")
+ }
+ lo.I.Println("Bpjs config loaded, status: DONE!!")
+}
diff --git a/internal/infra/bpjs/tycovar.go b/internal/infra/bpjs/tycovar.go
new file mode 100644
index 00000000..54e45a63
--- /dev/null
+++ b/internal/infra/bpjs/tycovar.go
@@ -0,0 +1,7 @@
+package bpjs
+
+var O BpjsCfg = BpjsCfg{}
+
+type BpjsCfg struct {
+ BaseUrl string `yaml:"baseUrl"`
+}
diff --git a/internal/infra/minio/minio.go b/internal/infra/minio/minio.go
new file mode 100644
index 00000000..e403b964
--- /dev/null
+++ b/internal/infra/minio/minio.go
@@ -0,0 +1,79 @@
+package minio
+
+import (
+ "errors"
+
+ a "github.com/karincake/apem"
+ lo "github.com/karincake/apem/loggero"
+ "github.com/minio/minio-go/v7"
+ "github.com/minio/minio-go/v7/pkg/credentials"
+)
+
+var O MinioCfg = MinioCfg{}
+var I *minio.Client
+
+type MinioCfg struct {
+ Endpoint string
+ Region string
+ AccessKey string `yaml:"accessKey"`
+ SecretKey string `yaml:"secretKey"`
+ UseSsl bool `yaml:"useSsl"`
+ BucketName []string `yaml:"bucketName"`
+}
+
+type ResponsePostPolicy struct {
+ Url string `json:"url"`
+ FormData map[string]string `json:"form-data"`
+}
+
+func (c MinioCfg) GetRegion() string {
+ return c.Region
+}
+
+func (c MinioCfg) GetEndpoint() string {
+ return c.Endpoint
+}
+
+func (c MinioCfg) GetUseSsl() bool {
+ return c.UseSsl
+}
+
+func (c MinioCfg) GetBucketName() []string {
+ return c.BucketName
+}
+
+// connect db
+func Connect() {
+ a.ParseSingleCfg(&O)
+ NewClient(&O)
+ if I == nil {
+ panic("minio client is nil")
+ }
+ lo.I.Println("Instantiation for object storage service using Minio, status: DONE!!")
+}
+
+func NewClient(cfg *MinioCfg) error {
+ // Initialize minio client object.
+ endpoint := cfg.Endpoint
+ if endpoint == "" {
+ return errors.New("config minio endpoint empty")
+ }
+ accessKey := cfg.AccessKey
+ if accessKey == "" {
+ return errors.New("config minio access key empty")
+ }
+ secretKey := cfg.SecretKey
+ if secretKey == "" {
+ return errors.New("config minio secret key empty")
+ }
+ useSSL := cfg.UseSsl
+ minioClient, err := minio.New(endpoint, &minio.Options{
+ Creds: credentials.NewStaticV4(accessKey, secretKey, ""),
+ Secure: useSSL,
+ })
+ if err != nil {
+ return err
+ }
+ I = minioClient
+ return nil
+}
diff --git a/internal/infra/ss-db/ss-db.go b/internal/infra/ss-db/ss-db.go
index 3c239540..f63c4b44 100644
--- a/internal/infra/ss-db/ss-db.go
+++ b/internal/infra/ss-db/ss-db.go
@@ -1,36 +1,9 @@
package ssdb
import (
- "log"
-
- a "github.com/karincake/apem"
- lo "github.com/karincake/apem/loggero"
- "gorm.io/driver/postgres"
- "gorm.io/gorm"
- "gorm.io/gorm/schema"
+ dg "github.com/karincake/apem/db-gorm-pg"
)
-func Init() {
- SetConfig()
- NewInstance()
-}
-
-func SetConfig() {
- a.ParseSingleCfg(&Cfg)
-}
-
-func NewInstance() {
- // create database connection
- db, err := gorm.Open(postgres.Open(Cfg.Dsn), &gorm.Config{
- NamingStrategy: schema.NamingStrategy{
- SingularTable: true,
- NoLowerCase: true,
- },
- })
- if err != nil {
- log.Fatal(err)
- }
-
- SSDb = db
- lo.I.Println("Instantiation for satu-sehat database-connetion using db-gorm-pg, status: DONE!!")
+func SetInstance() {
+ I = dg.IS["satusehat"]
}
diff --git a/internal/infra/ss-db/tycovar.go b/internal/infra/ss-db/tycovar.go
index ff084508..55fc90fd 100644
--- a/internal/infra/ss-db/tycovar.go
+++ b/internal/infra/ss-db/tycovar.go
@@ -2,12 +2,4 @@ package ssdb
import "gorm.io/gorm"
-type SsDbCfg struct {
- Dsn string
- MaxOpenConns int `yaml:"maxOpenConns"`
- MaxIdleConns int `yaml:"maxIdleConns"`
- MaxIdleTime int `yaml:"maxIdleTime"`
-}
-
-var Cfg SsDbCfg = SsDbCfg{}
-var SSDb *gorm.DB
+var I *gorm.DB
diff --git a/internal/interface/bpjs-handler/bpjs-handler.go b/internal/interface/bpjs-handler/bpjs-handler.go
new file mode 100644
index 00000000..175bb667
--- /dev/null
+++ b/internal/interface/bpjs-handler/bpjs-handler.go
@@ -0,0 +1,91 @@
+package bpjshandler
+
+import (
+ "net/http"
+
+ /******************** main / transaction ********************/
+ member "simrs-vx/internal/interface/bpjs-handler/member"
+ monitoring "simrs-vx/internal/interface/bpjs-handler/monitoring"
+ reference "simrs-vx/internal/interface/bpjs-handler/reference"
+ vclaimsep "simrs-vx/internal/interface/bpjs-handler/vclaim-sep"
+ vclaimsephist "simrs-vx/internal/interface/bpjs-handler/vclaim-sep-hist"
+ vclaimsepprint "simrs-vx/internal/interface/bpjs-handler/vclaim-sep-print"
+
+ /******************** actor ********************/
+
+ /******************** external ********************/
+ a "github.com/karincake/apem"
+ hk "github.com/karincake/hongkue"
+
+ /******************** infra ********************/
+ ibpjs "simrs-vx/internal/infra/bpjs"
+ gs "simrs-vx/internal/infra/gorm-setting"
+
+ /******************** 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"
+
+ /******************** sources ********************/
+ ///// Internal
+ validation "simrs-vx/internal/interface/main-handler/helper/validation"
+ "simrs-vx/internal/interface/main-handler/home"
+)
+
+// One place route to relatively easier to manage, ESPECIALLY in tracking
+func SetRoutes() http.Handler {
+ /////
+ a.RegisterExtCall(gs.Adjust)
+ a.RegisterExtCall(zlc.Adjust)
+ a.RegisterExtCall(lh.Populate)
+ a.RegisterExtCall(ibpjs.SetConfig)
+ a.RegisterExtCall(validation.RegisterValidation)
+
+ r := http.NewServeMux()
+
+ /******************** Main ********************/
+ r.HandleFunc("/", home.Home)
+
+ hk.GroupRoutes("/v1/vclaim-sep", r, hk.MapHandlerFunc{
+ "POST /": vclaimsep.O.Create,
+ "PATCH /{id}": vclaimsep.O.Update,
+ "DELETE /{id}": vclaimsep.O.Delete,
+ })
+
+ hk.GroupRoutes("/v1/vclaim-sep-hist", r, hk.MapHandlerFunc{
+ "GET /": vclaimsephist.O.GetList,
+ })
+
+ hk.GroupRoutes("/v1/vclaim-sep-print", r, hk.MapHandlerFunc{
+ "POST /": vclaimsepprint.O.Create,
+ })
+
+ hk.GroupRoutes("/v1/reference", r, hk.MapHandlerFunc{
+ "GET /province": reference.GetListProvince,
+ "GET /regency/{provinceCode}": reference.GetListCities,
+ "GET /district/{regencyCode}": reference.GetListDistrict,
+ "GET /diagnose/{keyword}": reference.GetListDiagnose,
+ "GET /diagnose-prb": reference.GetListDiagnosePrb,
+ "GET /medicine-prb/{keyword}": reference.GetListMedicinePrb,
+ "GET /unit/{unitCode}": reference.GetListUnit,
+ "GET /healthcare/{healthcare}/{healthcareType}": reference.GetListHealthcare,
+ "GET /responsible-doctor/{serviceType}/{serviceDate}/{specialistCode}": reference.GetListDoctor,
+ })
+
+ hk.GroupRoutes("/v1/member", r, hk.MapHandlerFunc{
+ "GET /bpjs/{cardNumber}/{sepDate}": member.GetListByBpjsNumber,
+ "GET /nik/{nik}/{sepDate}": member.GetListByNik,
+ })
+
+ hk.GroupRoutes("/v1/monitoring", r, hk.MapHandlerFunc{
+ "GET /visit/{date}/{serviceType}": monitoring.GetListVisit,
+ "GET /hist/{cardNumber}/{startDate}/{endDate}": monitoring.GetListHist,
+ })
+
+ /******************** actor ********************/
+
+ /******************** sources ********************/
+
+ return cmw.SetCors(handlerlogger.SetLog(r))
+}
diff --git a/internal/interface/bpjs-handler/member/handler.go b/internal/interface/bpjs-handler/member/handler.go
new file mode 100644
index 00000000..80881ee3
--- /dev/null
+++ b/internal/interface/bpjs-handler/member/handler.go
@@ -0,0 +1,45 @@
+package member
+
+import (
+ "net/http"
+
+ e "simrs-vx/internal/domain/bpjs-entities/member"
+ u "simrs-vx/internal/use-case/bpjs-use-case/member"
+
+ d "github.com/karincake/dodol"
+ rw "github.com/karincake/risoles"
+)
+
+func GetListByBpjsNumber(w http.ResponseWriter, r *http.Request) {
+ dto := e.ReadListDto{}
+ pValue1 := rw.ValidateString(w, "cardNumber", r.PathValue("cardNumber"))
+ if pValue1 == "" {
+ rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "cardNumber is required"}, nil)
+ }
+ pValue2 := rw.ValidateString(w, "sepDate", r.PathValue("sepDate"))
+ if pValue2 == "" {
+ rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "sepDate is required"}, nil)
+ }
+ dto.ReferenceType = e.RTBpjs
+ dto.PathValue1 = pValue1
+ dto.PathValue2 = pValue2
+ res, err := u.ReadList(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func GetListByNik(w http.ResponseWriter, r *http.Request) {
+ dto := e.ReadListDto{}
+ pValue1 := rw.ValidateString(w, "nik", r.PathValue("nik"))
+ if pValue1 == "" {
+ rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "nik is required"}, nil)
+ }
+ pValue2 := rw.ValidateString(w, "sepDate", r.PathValue("sepDate"))
+ if pValue2 == "" {
+ rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "sepDate is required"}, nil)
+ }
+ dto.ReferenceType = e.RTNik
+ dto.PathValue1 = pValue1
+ dto.PathValue2 = pValue2
+ res, err := u.ReadList(dto)
+ rw.DataResponse(w, res, err)
+}
diff --git a/internal/interface/bpjs-handler/monitoring/handler.go b/internal/interface/bpjs-handler/monitoring/handler.go
new file mode 100644
index 00000000..cf82a5b9
--- /dev/null
+++ b/internal/interface/bpjs-handler/monitoring/handler.go
@@ -0,0 +1,50 @@
+package monitoring
+
+import (
+ "net/http"
+
+ e "simrs-vx/internal/domain/bpjs-entities/monitoring"
+ u "simrs-vx/internal/use-case/bpjs-use-case/monitoring"
+
+ d "github.com/karincake/dodol"
+ rw "github.com/karincake/risoles"
+)
+
+func GetListVisit(w http.ResponseWriter, r *http.Request) {
+ dto := e.ReadListDto{}
+ pValue1 := rw.ValidateString(w, "date", r.PathValue("date"))
+ if pValue1 == "" {
+ rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "date is required"}, nil)
+ }
+ pValue2 := rw.ValidateString(w, "serviceType", r.PathValue("serviceType"))
+ if pValue2 == "" {
+ rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "serviceType is required"}, nil)
+ }
+ dto.ReferenceType = e.RTVisit
+ dto.PathValue1 = pValue1
+ dto.PathValue2 = pValue2
+ res, err := u.ReadList(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func GetListHist(w http.ResponseWriter, r *http.Request) {
+ dto := e.ReadListDto{}
+ pValue1 := rw.ValidateString(w, "cardNumber", r.PathValue("cardNumber"))
+ if pValue1 == "" {
+ rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "cardNumber is required"}, nil)
+ }
+ pValue2 := rw.ValidateString(w, "startDate", r.PathValue("startDate"))
+ if pValue2 == "" {
+ rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "startDate is required"}, nil)
+ }
+ pValue3 := rw.ValidateString(w, "endDate", r.PathValue("endDate"))
+ if pValue3 == "" {
+ rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "endDate is required"}, nil)
+ }
+ dto.ReferenceType = e.RTHist
+ dto.PathValue1 = pValue1
+ dto.PathValue2 = pValue2
+ dto.PathValue3 = pValue3
+ res, err := u.ReadList(dto)
+ rw.DataResponse(w, res, err)
+}
diff --git a/internal/interface/bpjs-handler/reference/handler.go b/internal/interface/bpjs-handler/reference/handler.go
new file mode 100644
index 00000000..fb972af1
--- /dev/null
+++ b/internal/interface/bpjs-handler/reference/handler.go
@@ -0,0 +1,124 @@
+package reference
+
+import (
+ "net/http"
+
+ e "simrs-vx/internal/domain/bpjs-entities/reference"
+ u "simrs-vx/internal/use-case/bpjs-use-case/reference"
+
+ d "github.com/karincake/dodol"
+ rw "github.com/karincake/risoles"
+)
+
+func GetListProvince(w http.ResponseWriter, r *http.Request) {
+ dto := e.ReadListDto{}
+ dto.ReferenceType = e.RTProvince
+ res, err := u.ReadList(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func GetListCities(w http.ResponseWriter, r *http.Request) {
+ dto := e.ReadListDto{}
+ pValue := rw.ValidateString(w, "provinceCode", r.PathValue("provinceCode"))
+ if pValue == "" {
+ rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "provinceCode is required"}, nil)
+ }
+ dto.ReferenceType = e.RTCities
+ dto.PathValue1 = pValue
+ res, err := u.ReadList(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func GetListDistrict(w http.ResponseWriter, r *http.Request) {
+ dto := e.ReadListDto{}
+ pValue := rw.ValidateString(w, "regencyCode", r.PathValue("regencyCode"))
+ if pValue == "" {
+ rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "regencyCode is required"}, nil)
+ }
+ dto.ReferenceType = e.RTDistrict
+ dto.PathValue1 = pValue
+ res, err := u.ReadList(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func GetListDiagnose(w http.ResponseWriter, r *http.Request) {
+ dto := e.ReadListDto{}
+ pValue := rw.ValidateString(w, "keyword", r.PathValue("keyword"))
+ if pValue == "" {
+ rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "keyword is required"}, nil)
+ }
+ dto.ReferenceType = e.RTDiagnose
+ dto.PathValue1 = pValue
+ res, err := u.ReadList(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func GetListDiagnosePrb(w http.ResponseWriter, r *http.Request) {
+ dto := e.ReadListDto{}
+ dto.ReferenceType = e.RTDiagnosePrb
+ res, err := u.ReadList(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func GetListMedicinePrb(w http.ResponseWriter, r *http.Request) {
+ dto := e.ReadListDto{}
+ pValue := rw.ValidateString(w, "keyword", r.PathValue("keyword"))
+ if pValue == "" {
+ rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "keyword is required"}, nil)
+ }
+ dto.ReferenceType = e.RTMedicinePrb
+ dto.PathValue1 = pValue
+ res, err := u.ReadList(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func GetListUnit(w http.ResponseWriter, r *http.Request) {
+ dto := e.ReadListDto{}
+ pValue := rw.ValidateString(w, "unitCode", r.PathValue("unitCode"))
+ if pValue == "" {
+ rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "unitCode is required"}, nil)
+ }
+ dto.ReferenceType = e.RTUnit
+ dto.PathValue1 = pValue
+ res, err := u.ReadList(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func GetListHealthcare(w http.ResponseWriter, r *http.Request) {
+ dto := e.ReadListDto{}
+ pValue1 := rw.ValidateString(w, "healthcare", r.PathValue("healthcare"))
+ if pValue1 == "" {
+ rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "healthcare is required"}, nil)
+ }
+ pValue2 := rw.ValidateString(w, "healthcareType", r.PathValue("healthcareType"))
+ if pValue2 == "" {
+ rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "healthcareType is required"}, nil)
+ }
+ dto.ReferenceType = e.RTHealthcare
+ dto.PathValue1 = pValue1
+ dto.PathValue2 = pValue2
+ res, err := u.ReadList(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func GetListDoctor(w http.ResponseWriter, r *http.Request) {
+ dto := e.ReadListDto{}
+ pValue1 := rw.ValidateString(w, "serviceType", r.PathValue("serviceType"))
+ if pValue1 == "" {
+ rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "serviceType is required"}, nil)
+ }
+ pValue2 := rw.ValidateString(w, "serviceDate", r.PathValue("serviceDate"))
+ if pValue2 == "" {
+ rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "serviceDate is required"}, nil)
+ }
+ pValue3 := rw.ValidateString(w, "specialistCode", r.PathValue("specialistCode"))
+ if pValue3 == "" {
+ rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "specialistCode is required"}, nil)
+ }
+ dto.PathValue1 = pValue1
+ dto.PathValue2 = pValue2
+ dto.PathValue3 = pValue3
+ dto.ReferenceType = e.RTDoctor
+ res, err := u.ReadList(dto)
+ rw.DataResponse(w, res, err)
+}
diff --git a/internal/interface/bpjs-handler/vclaim-sep-hist/handler.go b/internal/interface/bpjs-handler/vclaim-sep-hist/handler.go
new file mode 100644
index 00000000..73c2c4e2
--- /dev/null
+++ b/internal/interface/bpjs-handler/vclaim-sep-hist/handler.go
@@ -0,0 +1,22 @@
+package vclaimsephist
+
+import (
+ "net/http"
+
+ e "simrs-vx/internal/domain/bpjs-entities/vclaim-sep-hist"
+ u "simrs-vx/internal/use-case/bpjs-use-case/vclaim-sep-hist"
+
+ rw "github.com/karincake/risoles"
+ sf "github.com/karincake/semprit"
+)
+
+type myBase struct{}
+
+var O myBase
+
+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)
+}
diff --git a/internal/interface/bpjs-handler/vclaim-sep-print/handler.go b/internal/interface/bpjs-handler/vclaim-sep-print/handler.go
new file mode 100644
index 00000000..838bc65b
--- /dev/null
+++ b/internal/interface/bpjs-handler/vclaim-sep-print/handler.go
@@ -0,0 +1,23 @@
+package vclaimsepprint
+
+import (
+ "net/http"
+
+ e "simrs-vx/internal/domain/bpjs-entities/vclaim-sep-print"
+ u "simrs-vx/internal/use-case/bpjs-use-case/vclaim-sep-print"
+
+ rw "github.com/karincake/risoles"
+)
+
+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)
+}
diff --git a/internal/interface/bpjs-handler/vclaim-sep/handler.go b/internal/interface/bpjs-handler/vclaim-sep/handler.go
new file mode 100644
index 00000000..d40c76e9
--- /dev/null
+++ b/internal/interface/bpjs-handler/vclaim-sep/handler.go
@@ -0,0 +1,73 @@
+package vclaimsep
+
+import (
+ "io"
+ "net/http"
+
+ rw "github.com/karincake/risoles"
+
+ e "simrs-vx/internal/domain/bpjs-entities/vclaim-sep"
+ u "simrs-vx/internal/use-case/bpjs-use-case/vclaim-sep"
+)
+
+type myBase struct{}
+
+var O myBase
+
+func (obj myBase) Create(w http.ResponseWriter, r *http.Request) {
+ dto := e.CreateDto{}
+ body, err := io.ReadAll(r.Body)
+ if err != nil {
+ http.Error(w, "failed to read body", http.StatusBadRequest)
+ return
+ }
+ defer r.Body.Close()
+
+ dto.RequestPayload = body
+ res, err := u.Create(dto)
+ rw.DataResponse(w, res, err)
+}
+
+// func (obj myBase) GetList(w http.ResponseWriter, r *http.Request) {
+// dto := e.ReadListDto{}
+// sf.UrlQueryParam(&dto, *r.URL)
+// res, err := u.ReadList(dto)
+// rw.DataResponse(w, res, err)
+// }
+
+// func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) {
+// id := rw.ValidateInt(w, "id", r.PathValue("id"))
+// if id <= 0 {
+// return
+// }
+// dto := e.ReadDetailDto{}
+// dto.Id = uint(id)
+// res, err := u.ReadDetail(dto)
+// rw.DataResponse(w, res, err)
+// }
+
+func (obj myBase) Update(w http.ResponseWriter, r *http.Request) {
+ number := rw.ValidateString(w, "number", r.PathValue("number"))
+ if number != "" {
+ return
+ }
+
+ dto := e.UpdateDto{}
+ if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
+ return
+ }
+ dto.Number = &number
+ res, err := u.Update(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) {
+ number := rw.ValidateString(w, "number", r.PathValue("number"))
+ if number != "" {
+ return
+ }
+ dto := e.DeleteDto{}
+ dto.Number = &number
+ res, err := u.Delete(dto)
+ rw.DataResponse(w, res, err)
+}
diff --git a/internal/interface/main-handler/adime/handler.go b/internal/interface/main-handler/adime/handler.go
new file mode 100644
index 00000000..9eabb0af
--- /dev/null
+++ b/internal/interface/main-handler/adime/handler.go
@@ -0,0 +1,80 @@
+package adime
+
+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/adime"
+ u "simrs-vx/internal/use-case/main-use-case/adime"
+
+ pa "simrs-vx/pkg/auth-helper"
+
+ d "github.com/karincake/dodol"
+)
+
+type myBase struct{}
+
+var O myBase
+
+func (obj myBase) Create(w http.ResponseWriter, r *http.Request) {
+ authInfo, err := pa.GetAuthInfo(r)
+ if err != nil {
+ rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil)
+ }
+ dto := e.CreateDto{}
+ if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
+ return
+ }
+ dto.AuthInfo = *authInfo
+ res, err := u.Create(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) GetList(w http.ResponseWriter, r *http.Request) {
+ dto := e.ReadListDto{}
+ sf.UrlQueryParam(&dto, *r.URL)
+ res, err := u.ReadList(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+ dto := e.ReadDetailDto{}
+ dto.Id = uint16(id)
+ res, err := u.ReadDetail(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) Update(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+
+ dto := e.UpdateDto{}
+ if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
+ return
+ }
+ dto.Id = uint16(id)
+ res, err := u.Update(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+
+ dto := e.DeleteDto{}
+ dto.Id = uint16(id)
+ res, err := u.Delete(dto)
+ rw.DataResponse(w, res, err)
+}
diff --git a/internal/interface/main-handler/authentication/authentication.go b/internal/interface/main-handler/authentication/handler.go
similarity index 83%
rename from internal/interface/main-handler/authentication/authentication.go
rename to internal/interface/main-handler/authentication/handler.go
index 37b84346..01d4fb89 100644
--- a/internal/interface/main-handler/authentication/authentication.go
+++ b/internal/interface/main-handler/authentication/handler.go
@@ -9,16 +9,10 @@ import (
m "simrs-vx/internal/domain/main-entities/user"
s "simrs-vx/internal/use-case/main-use-case/authentication"
+
+ pa "simrs-vx/pkg/auth-helper"
)
-type authKey string
-
-const akInfo authKey = "authInfo"
-
-type AuthKey struct{}
-
-// var Position m.Position
-
func Login(w http.ResponseWriter, r *http.Request) {
var input m.LoginDto
if !(rw.ValidateStructByIOR(w, r.Body, &input)) {
@@ -35,12 +29,12 @@ func Login(w http.ResponseWriter, r *http.Request) {
}
func Logout(w http.ResponseWriter, r *http.Request) {
- ctxVal := r.Context().Value(AuthKey{})
+ ctxVal := r.Context().Value(pa.AuthKey{})
if ctxVal == nil {
rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "logout skiped. the request is done wihtout authorization."}, nil)
return
}
- authInfo := ctxVal.(*s.AuthInfo)
+ authInfo := ctxVal.(*pa.AuthInfo)
s.RevokeToken(authInfo.Uuid)
rw.WriteJSON(w, http.StatusOK, d.IS{"message": "logged out"}, nil)
}
@@ -52,7 +46,7 @@ func GuardMW(next http.Handler) http.Handler {
rw.WriteJSON(w, http.StatusUnauthorized, err.(d.FieldError), nil)
return
}
- ctx := context.WithValue(r.Context(), AuthKey{}, accessDetail)
+ ctx := context.WithValue(r.Context(), pa.AuthKey{}, accessDetail)
next.ServeHTTP(w, r.WithContext(ctx))
})
}
diff --git a/internal/interface/main-handler/chemo/handler.go b/internal/interface/main-handler/chemo/handler.go
new file mode 100644
index 00000000..ee8c0435
--- /dev/null
+++ b/internal/interface/main-handler/chemo/handler.go
@@ -0,0 +1,114 @@
+package chemo
+
+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/chemo"
+
+ erc "simrs-vx/internal/domain/references/common"
+
+ u "simrs-vx/internal/use-case/main-use-case/chemo"
+
+ pa "simrs-vx/pkg/auth-helper"
+
+ d "github.com/karincake/dodol"
+)
+
+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)
+}
+
+func (obj myBase) Verify(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+
+ dto := e.VerifyDto{}
+ dto.Id = uint16(id)
+ authInfo, err := pa.GetAuthInfo(r)
+ if err != nil {
+ rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil)
+ }
+ dto.AuthInfo = *authInfo
+ dto.Status_Code = erc.DVCVerified
+ res, err := u.Verify(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) Reject(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+
+ dto := e.VerifyDto{}
+ dto.Id = uint16(id)
+ authInfo, err := pa.GetAuthInfo(r)
+ if err != nil {
+ rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil)
+ }
+ dto.AuthInfo = *authInfo
+ dto.Status_Code = erc.DVCRejected
+ res, err := u.Verify(dto)
+ rw.DataResponse(w, res, err)
+}
diff --git a/internal/interface/main-handler/consultation/handler.go b/internal/interface/main-handler/consultation/handler.go
new file mode 100644
index 00000000..2be1cbdd
--- /dev/null
+++ b/internal/interface/main-handler/consultation/handler.go
@@ -0,0 +1,97 @@
+package device
+
+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/consultation"
+ u "simrs-vx/internal/use-case/main-use-case/consultation"
+
+ pa "simrs-vx/pkg/auth-helper"
+
+ d "github.com/karincake/dodol"
+)
+
+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 = uint(id)
+ res, err := u.Update(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+
+ dto := e.DeleteDto{}
+ dto.Id = uint(id)
+ res, err := u.Delete(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) Reply(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+
+ authInfo, err := pa.GetAuthInfo(r)
+ if err != nil {
+ rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil)
+ }
+
+ dto := e.ReplyDto{}
+
+ if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
+ return
+ }
+ dto.AuthInfo = *authInfo
+ dto.Id = uint(id)
+ res, err := u.Reply(dto)
+ rw.DataResponse(w, res, err)
+}
diff --git a/internal/interface/main-handler/device-order-item/handler.go b/internal/interface/main-handler/device-order-item/handler.go
new file mode 100644
index 00000000..42dfd510
--- /dev/null
+++ b/internal/interface/main-handler/device-order-item/handler.go
@@ -0,0 +1,71 @@
+package deviceorderitem
+
+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/device-order-item"
+ u "simrs-vx/internal/use-case/main-use-case/device-order-item"
+)
+
+type myBase struct{}
+
+var O myBase
+
+func (obj myBase) Create(w http.ResponseWriter, r *http.Request) {
+ dto := e.CreateDto{}
+ if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
+ return
+ }
+ res, err := u.Create(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) GetList(w http.ResponseWriter, r *http.Request) {
+ dto := e.ReadListDto{}
+ sf.UrlQueryParam(&dto, *r.URL)
+ res, err := u.ReadList(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+ dto := e.ReadDetailDto{}
+ dto.Id = 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/device-order/handler.go b/internal/interface/main-handler/device-order/handler.go
new file mode 100644
index 00000000..42135e58
--- /dev/null
+++ b/internal/interface/main-handler/device-order/handler.go
@@ -0,0 +1,96 @@
+package deviceorder
+
+import (
+ "net/http"
+
+ rw "github.com/karincake/risoles"
+ sf "github.com/karincake/semprit"
+
+ e "simrs-vx/internal/domain/main-entities/device-order"
+ u "simrs-vx/internal/use-case/main-use-case/device-order"
+
+ pa "simrs-vx/pkg/auth-helper"
+
+ d "github.com/karincake/dodol"
+)
+
+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
+ }
+
+ authInfo, err := pa.GetAuthInfo(r)
+ if err != nil {
+ rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil)
+ }
+ dto.AuthInfo = *authInfo
+ res, err := u.Create(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) GetList(w http.ResponseWriter, r *http.Request) {
+ dto := e.ReadListDto{}
+ sf.UrlQueryParam(&dto, *r.URL)
+ res, err := u.ReadList(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+ dto := e.ReadDetailDto{}
+ dto.Id = uint16(id)
+ res, err := u.ReadDetail(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) Update(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+
+ dto := e.UpdateDto{}
+ if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
+ return
+ }
+ dto.Id = uint16(id)
+ authInfo, err := pa.GetAuthInfo(r)
+ if err != nil {
+ rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil)
+ }
+ dto.AuthInfo = *authInfo
+ 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)
+}
+
+func (obj myBase) Complete(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.Complete(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 01350b87..09191c96 100644
--- a/internal/interface/main-handler/encounter/handler.go
+++ b/internal/interface/main-handler/encounter/handler.go
@@ -10,6 +10,12 @@ import (
e "simrs-vx/internal/domain/main-entities/encounter"
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"
)
type myBase struct{}
@@ -17,10 +23,15 @@ type myBase struct{}
var O myBase
func (obj myBase) Create(w http.ResponseWriter, r *http.Request) {
+ authInfo, err := pa.GetAuthInfo(r)
+ if err != nil {
+ rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil)
+ }
dto := e.CreateDto{}
if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
return
}
+ dto.AuthInfo = *authInfo
res, err := u.Create(dto)
rw.DataResponse(w, res, err)
}
@@ -69,3 +80,77 @@ func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) {
res, err := u.Delete(dto)
rw.DataResponse(w, res, err)
}
+
+func (obj myBase) CheckOut(w http.ResponseWriter, r *http.Request) {
+ dto := e.DischargeDto{}
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+ if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
+ return
+ }
+ dto.Id = uint(id)
+ res, err := u.CheckOut(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) Process(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+
+ dto := e.UpdateStatusDto{
+ Id: uint16(id),
+ StatusCode: erc.DSCProcess,
+ }
+
+ res, err := u.UpdateStatusCode(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) Cancel(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+
+ dto := e.UpdateStatusDto{
+ Id: uint16(id),
+ StatusCode: erc.DSCCancel,
+ }
+
+ res, err := u.UpdateStatusCode(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) Reject(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+
+ dto := e.UpdateStatusDto{
+ Id: uint16(id),
+ StatusCode: erc.DSCRejected,
+ }
+
+ res, err := u.UpdateStatusCode(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) Skip(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+
+ dto := e.UpdateStatusDto{
+ Id: uint16(id),
+ StatusCode: erc.DSCSkipped,
+ }
+
+ res, err := u.UpdateStatusCode(dto)
+ rw.DataResponse(w, res, err)
+}
diff --git a/internal/interface/main-handler/internal-reference/handler.go b/internal/interface/main-handler/internal-reference/handler.go
new file mode 100644
index 00000000..c46c974d
--- /dev/null
+++ b/internal/interface/main-handler/internal-reference/handler.go
@@ -0,0 +1,72 @@
+package internal_reference
+
+import (
+ "net/http"
+
+ eir "simrs-vx/internal/domain/main-entities/internal-reference"
+ uir "simrs-vx/internal/use-case/main-use-case/internal-reference"
+
+ 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 := eir.CreateDto{}
+ if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
+ return
+ }
+
+ res, err := uir.Create(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) GetList(w http.ResponseWriter, r *http.Request) {
+ dto := eir.ReadListDto{}
+ sf.UrlQueryParam(&dto, *r.URL)
+ res, err := uir.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 := eir.ReadDetailDto{}
+ sf.UrlQueryParam(&dto, *r.URL)
+ dto.Id = uint16(id)
+ res, err := uir.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 := eir.UpdateDto{}
+ if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
+ return
+ }
+ dto.Id = uint16(id)
+ res, err := uir.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 := eir.DeleteDto{}
+ dto.Id = uint16(id)
+ res, err := uir.Delete(dto)
+ rw.DataResponse(w, res, err)
+}
diff --git a/internal/interface/main-handler/main-handler.go b/internal/interface/main-handler/main-handler.go
index 87c17f91..d141b469 100644
--- a/internal/interface/main-handler/main-handler.go
+++ b/internal/interface/main-handler/main-handler.go
@@ -4,12 +4,30 @@ import (
"net/http"
/******************** main / transaction ********************/
+ adime "simrs-vx/internal/interface/main-handler/adime"
auth "simrs-vx/internal/interface/main-handler/authentication"
+ chemo "simrs-vx/internal/interface/main-handler/chemo"
+ consultation "simrs-vx/internal/interface/main-handler/consultation"
counter "simrs-vx/internal/interface/main-handler/counter"
+ deviceorder "simrs-vx/internal/interface/main-handler/device-order"
+ deviceorderitem "simrs-vx/internal/interface/main-handler/device-order-item"
encounter "simrs-vx/internal/interface/main-handler/encounter"
+ internalreference "simrs-vx/internal/interface/main-handler/internal-reference"
+ materialorder "simrs-vx/internal/interface/main-handler/material-order"
+ materialorderitem "simrs-vx/internal/interface/main-handler/material-order-item"
+ mcuorder "simrs-vx/internal/interface/main-handler/mcu-order"
+ mcuorderitem "simrs-vx/internal/interface/main-handler/mcu-order-item"
+ mcuordersubitem "simrs-vx/internal/interface/main-handler/mcu-order-sub-item"
+ medication "simrs-vx/internal/interface/main-handler/medication"
+ medicationitem "simrs-vx/internal/interface/main-handler/medication-item"
+ medicationitemdist "simrs-vx/internal/interface/main-handler/medication-item-dist"
medicicinemix "simrs-vx/internal/interface/main-handler/medicine-mix"
medicicinemixitem "simrs-vx/internal/interface/main-handler/medicine-mix-item"
practiceschedule "simrs-vx/internal/interface/main-handler/practice-schedule"
+ prescription "simrs-vx/internal/interface/main-handler/prescription"
+ prescriptionitem "simrs-vx/internal/interface/main-handler/prescription-item"
+ sbar "simrs-vx/internal/interface/main-handler/sbar"
+ soapi "simrs-vx/internal/interface/main-handler/soapi"
/******************** actor ********************/
doctor "simrs-vx/internal/interface/main-handler/doctor"
@@ -20,6 +38,7 @@ import (
person "simrs-vx/internal/interface/main-handler/person"
personaddress "simrs-vx/internal/interface/main-handler/person-address"
personcontact "simrs-vx/internal/interface/main-handler/person-contact"
+ personinsurance "simrs-vx/internal/interface/main-handler/person-insurance"
pharmacist "simrs-vx/internal/interface/main-handler/pharmacist"
user "simrs-vx/internal/interface/main-handler/user"
@@ -29,6 +48,7 @@ import (
/******************** infra ********************/
gs "simrs-vx/internal/infra/gorm-setting"
+ minio "simrs-vx/internal/infra/minio"
ssdb "simrs-vx/internal/infra/ss-db"
/******************** pkg ********************/
@@ -36,6 +56,7 @@ import (
hc "simrs-vx/pkg/handler-crud-helper"
lh "simrs-vx/pkg/lang-helper"
handlerlogger "simrs-vx/pkg/middleware/handler-logger"
+ mh "simrs-vx/pkg/minio-helper"
zlc "simrs-vx/pkg/zerolog-ctx"
/******************** sources ********************/
@@ -54,6 +75,7 @@ import (
material "simrs-vx/internal/interface/main-handler/material"
mcusrc "simrs-vx/internal/interface/main-handler/mcu-src"
mcusrccategory "simrs-vx/internal/interface/main-handler/mcu-src-category"
+ mcusubsrc "simrs-vx/internal/interface/main-handler/mcu-sub-src"
medicalactionsrc "simrs-vx/internal/interface/main-handler/medical-action-src"
medicalactionsrcitem "simrs-vx/internal/interface/main-handler/medical-action-src-item"
medicine "simrs-vx/internal/interface/main-handler/medicine"
@@ -61,10 +83,13 @@ import (
medicinemethod "simrs-vx/internal/interface/main-handler/medicine-method"
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"
+ subspecialist "simrs-vx/internal/interface/main-handler/subspecialist"
unit "simrs-vx/internal/interface/main-handler/unit"
uom "simrs-vx/internal/interface/main-handler/uom"
district "simrs-vx/internal/interface/main-handler/district"
+ postalregion "simrs-vx/internal/interface/main-handler/postal-region"
province "simrs-vx/internal/interface/main-handler/province"
regency "simrs-vx/internal/interface/main-handler/regency"
village "simrs-vx/internal/interface/main-handler/village"
@@ -79,8 +104,10 @@ func SetRoutes() http.Handler {
/////
a.RegisterExtCall(gs.Adjust)
a.RegisterExtCall(zlc.Adjust)
- a.RegisterExtCall(ssdb.Init)
+ a.RegisterExtCall(ssdb.SetInstance)
a.RegisterExtCall(lh.Populate)
+ a.RegisterExtCall(minio.Connect)
+ a.RegisterExtCall(mh.I.SetClient)
a.RegisterExtCall(validation.RegisterValidation)
r := http.NewServeMux()
@@ -94,9 +121,134 @@ func SetRoutes() http.Handler {
hc.RegCrud(r, "/v1/counter", counter.O)
hc.RegCrud(r, "/v1/medicine-mix", medicicinemix.O)
hc.RegCrud(r, "/v1/medicine-mix-item", medicicinemixitem.O)
- hc.RegCrud(r, "/v1/encounter", encounter.O)
+ hc.RegCrud(r, "/v1/soapi", auth.GuardMW, soapi.O)
+ hc.RegCrud(r, "/v1/adime", auth.GuardMW, adime.O)
+ hc.RegCrud(r, "/v1/sbar", auth.GuardMW, sbar.O)
+ hc.RegCrud(r, "/v1/prescription-item", prescriptionitem.O)
+ hc.RegCrud(r, "/v1/device-order-item", deviceorderitem.O)
+ hc.RegCrud(r, "/v1/material-order-item", materialorderitem.O)
+ hk.GroupRoutes("/v1/mcu-order", r, auth.GuardMW, hk.MapHandlerFunc{
+ "GET /": mcuorder.O.GetList,
+ "GET /{id}": mcuorder.O.GetDetail,
+ "POST /": mcuorder.O.Create,
+ "PATCH /{id}": mcuorder.O.Update,
+ "DELETE /{id}": mcuorder.O.Delete,
+ "PATCH /{id}/complete": mcuorder.O.Complete,
+ "PATCH /{id}/set-schedule": mcuorder.O.SetSchedule,
+ })
+ hk.GroupRoutes("/v1/mcu-order-item", r, hk.MapHandlerFunc{
+ "GET /": mcuorderitem.O.GetList,
+ "GET /{id}": mcuorderitem.O.GetDetail,
+ "POST /": mcuorderitem.O.Create,
+ "PATCH /{id}": mcuorderitem.O.Update,
+ "DELETE /{id}": mcuorderitem.O.Delete,
+ "PATCH /{id}/complete": mcuorderitem.O.Complete,
+ "PATCH /{id}/set-schedule": mcuorderitem.O.SetSchedule,
+ })
+ hk.GroupRoutes("/v1/prescription", r, hk.MapHandlerFunc{
+ "GET /": prescription.O.GetList,
+ "GET /{id}": prescription.O.GetDetail,
+ "POST /": prescription.O.Create,
+ "PATCH /{id}": prescription.O.Update,
+ "DELETE /{id}": prescription.O.Delete,
+ "PATCH /{id}/approve": prescription.O.Approve,
+ })
+ hk.GroupRoutes("/v1/mcu-order-sub-item", r, hk.MapHandlerFunc{
+ "GET /": mcuordersubitem.O.GetList,
+ "GET /{id}": mcuordersubitem.O.GetDetail,
+ "POST /": mcuordersubitem.O.Create,
+ "PATCH /{id}": mcuordersubitem.O.Update,
+ "DELETE /{id}": mcuordersubitem.O.Delete,
+ "PATCH /{id}/complete": mcuordersubitem.O.Complete,
+ })
+ hk.GroupRoutes("/v1/encounter", r, auth.GuardMW, hk.MapHandlerFunc{
+ "GET /": encounter.O.GetList,
+ "GET /{id}": encounter.O.GetDetail,
+ "POST /": encounter.O.Create,
+ "PATCH /{id}": encounter.O.Update,
+ "DELETE /{id}": encounter.O.Delete,
+ "PATCH /{id}/checkout": encounter.O.CheckOut,
+ "PATCH /{id}/proccess": encounter.O.Process,
+ "PATCH /{id}/cancel": encounter.O.Cancel,
+ "PATCH /{id}/reject": encounter.O.Reject,
+ "PATCH /{id}/skip": encounter.O.Skip,
+ })
+ hk.GroupRoutes("/v1/medication", r, auth.GuardMW, hk.MapHandlerFunc{
+ "GET /": medication.O.GetList,
+ "GET /{id}": medication.O.GetDetail,
+ "POST /": medication.O.Create,
+ "PATCH /{id}": medication.O.Update,
+ "DELETE /{id}": medication.O.Delete,
+ "PATCH /{id}/complete": medication.O.Complete,
+ })
+
+ hk.GroupRoutes("/v1/medication-item", r, hk.MapHandlerFunc{
+ "GET /": medicationitem.O.GetList,
+ "GET /{id}": medicationitem.O.GetDetail,
+ "POST /": medicationitem.O.Create,
+ "PATCH /{id}": medicationitem.O.Update,
+ "DELETE /{id}": medicationitem.O.Delete,
+ "PATCH /{id}/redeem": medicationitem.O.Redeem,
+ })
+
+ hk.GroupRoutes("/v1/medication-item-dist", r, auth.GuardMW, hk.MapHandlerFunc{
+ "GET /": medicationitemdist.O.GetList,
+ "GET /{id}": medicationitemdist.O.GetDetail,
+ "POST /": medicationitemdist.O.Create,
+ "PATCH /{id}": medicationitemdist.O.Update,
+ "DELETE /{id}": medicationitemdist.O.Delete,
+ "PATCH /{id}/consume": medicationitemdist.O.Consume,
+ })
+
+ hk.GroupRoutes("/v1/device-order", r, auth.GuardMW, hk.MapHandlerFunc{
+ "GET /": deviceorder.O.GetList,
+ "GET /{id}": deviceorder.O.GetDetail,
+ "POST /": deviceorder.O.Create,
+ "PATCH /{id}": deviceorder.O.Update,
+ "DELETE /{id}": deviceorder.O.Delete,
+ "PATCH /{id}/complete": deviceorder.O.Complete,
+ })
+
+ hk.GroupRoutes("/v1/material-order", r, auth.GuardMW, hk.MapHandlerFunc{
+ "GET /": materialorder.O.GetList,
+ "GET /{id}": materialorder.O.GetDetail,
+ "POST /": materialorder.O.Create,
+ "PATCH /{id}": materialorder.O.Update,
+ "DELETE /{id}": materialorder.O.Delete,
+ "PATCH /{id}/complete": materialorder.O.Complete,
+ })
+
+ hk.GroupRoutes("/v1/consultation", r, auth.GuardMW, hk.MapHandlerFunc{
+ "GET /": consultation.O.GetList,
+ "GET /{id}": consultation.O.GetDetail,
+ "POST /": consultation.O.Create,
+ "PATCH /{id}": consultation.O.Update,
+ "DELETE /{id}": consultation.O.Delete,
+ "PATCH /{id}/reply": consultation.O.Reply,
+ })
+
+ hk.GroupRoutes("/v1/chemo", r, auth.GuardMW, hk.MapHandlerFunc{
+ "GET /": chemo.O.GetList,
+ "GET /{id}": chemo.O.GetDetail,
+ "POST /": chemo.O.Create,
+ "PATCH /{id}": chemo.O.Update,
+ "DELETE /{id}": chemo.O.Delete,
+ "PATCH /{id}/verify": chemo.O.Verify,
+ "PATCH /{id}/reject": chemo.O.Reject,
+ })
+
+ hc.RegCrud(r, "/v1/internal-reference", internalreference.O)
/******************** actor ********************/
+ hc.RegCrud(r, "/v1/person", person.O)
+ hc.RegCrud(r, "/v1/person-address", personaddress.O)
+ hc.RegCrud(r, "/v1/person-contact", personcontact.O)
+ hc.RegCrud(r, "/v1/person-insurance", personinsurance.O)
+ hc.RegCrud(r, "/v1/employee", employee.O)
+ hc.RegCrud(r, "/v1/doctor", doctor.O)
+ hc.RegCrud(r, "/v1/nurse", nurse.O)
+ hc.RegCrud(r, "/v1/nutritionist", nutritionist.O)
+ hc.RegCrud(r, "/v1/pharmacist", pharmacist.O)
hk.GroupRoutes("/v1/user", r, hk.MapHandlerFunc{
"GET /": user.O.GetList,
"GET /{id}": user.O.GetDetail,
@@ -106,15 +258,16 @@ func SetRoutes() http.Handler {
"PATCH /{id}/block": user.O.Block,
"PATCH /{id}/active": user.O.Active,
})
- hc.RegCrud(r, "/v1/person", person.O)
- hc.RegCrud(r, "/v1/person-address", personaddress.O)
- hc.RegCrud(r, "/v1/person-contact", personcontact.O)
- hc.RegCrud(r, "/v1/employee", employee.O)
- hc.RegCrud(r, "/v1/doctor", doctor.O)
- hc.RegCrud(r, "/v1/nurse", nurse.O)
- hc.RegCrud(r, "/v1/nutritionist", nutritionist.O)
- hc.RegCrud(r, "/v1/pharmacist", pharmacist.O)
- hc.RegCrud(r, "/v1/patient", patient.O)
+ hk.GroupRoutes("/v1/patient", r, hk.MapHandlerFunc{
+ "GET /": patient.O.GetList,
+ "GET /{id}": patient.O.GetDetail,
+ "POST /": patient.O.Create,
+ "PATCH /{id}": patient.O.Update,
+ "DELETE /{id}": patient.O.Delete,
+ "GET /search/{keyword}": patient.O.Search,
+ "GET /by-resident-identity": patient.O.SearchByResidentIdentity,
+ "POST /{id}/upload": patient.O.Upload,
+ })
/******************** sources ********************/
hc.RegCrud(r, "/v1/division", division.O)
@@ -141,11 +294,15 @@ func SetRoutes() http.Handler {
hc.RegCrud(r, "/v1/medical-action-src", medicalactionsrc.O)
hc.RegCrud(r, "/v1/medical-action-src-item", medicalactionsrcitem.O)
hc.RegCrud(r, "/v1/language", language.O)
+ hc.RegCrud(r, "/v1/specialist", specialist.O)
+ hc.RegCrud(r, "/v1/subspecialist", subspecialist.O)
+ hc.RegCrud(r, "/v1/mcu-sub-src", mcusubsrc.O)
hc.RegCrud(r, "/v1/village", village.O)
hc.RegCrud(r, "/v1/district", district.O)
hc.RegCrud(r, "/v1/regency", regency.O)
hc.RegCrud(r, "/v1/province", province.O)
+ hc.RegCrud(r, "/v1/postal-region", postalregion.O)
/////
return cmw.SetCors(handlerlogger.SetLog(r))
diff --git a/internal/interface/main-handler/material-order-item/handler.go b/internal/interface/main-handler/material-order-item/handler.go
new file mode 100644
index 00000000..3b25f1d3
--- /dev/null
+++ b/internal/interface/main-handler/material-order-item/handler.go
@@ -0,0 +1,71 @@
+package materialorderitem
+
+import (
+ "net/http"
+
+ rw "github.com/karincake/risoles"
+ sf "github.com/karincake/semprit"
+
+ // ua "github.com/karincake/tumpeng/auth/svc"
+
+ e "simrs-vx/internal/domain/main-entities/material-order-item"
+ u "simrs-vx/internal/use-case/main-use-case/material-order-item"
+)
+
+type myBase struct{}
+
+var O myBase
+
+func (obj myBase) Create(w http.ResponseWriter, r *http.Request) {
+ dto := e.CreateDto{}
+ if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
+ return
+ }
+ res, err := u.Create(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) GetList(w http.ResponseWriter, r *http.Request) {
+ dto := e.ReadListDto{}
+ sf.UrlQueryParam(&dto, *r.URL)
+ res, err := u.ReadList(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+ dto := e.ReadDetailDto{}
+ dto.Id = 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/material-order/handler.go b/internal/interface/main-handler/material-order/handler.go
new file mode 100644
index 00000000..ae8777cb
--- /dev/null
+++ b/internal/interface/main-handler/material-order/handler.go
@@ -0,0 +1,97 @@
+package materialorder
+
+import (
+ "net/http"
+
+ rw "github.com/karincake/risoles"
+ sf "github.com/karincake/semprit"
+
+ // ua "github.com/karincake/tumpeng/auth/svc"
+
+ e "simrs-vx/internal/domain/main-entities/material-order"
+ u "simrs-vx/internal/use-case/main-use-case/material-order"
+
+ pa "simrs-vx/pkg/auth-helper"
+
+ d "github.com/karincake/dodol"
+)
+
+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
+ }
+ authInfo, err := pa.GetAuthInfo(r)
+ if err != nil {
+ rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil)
+ }
+ dto.AuthInfo = *authInfo
+ res, err := u.Create(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) GetList(w http.ResponseWriter, r *http.Request) {
+ dto := e.ReadListDto{}
+ sf.UrlQueryParam(&dto, *r.URL)
+ res, err := u.ReadList(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+ dto := e.ReadDetailDto{}
+ dto.Id = uint16(id)
+ res, err := u.ReadDetail(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) Update(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+
+ dto := e.UpdateDto{}
+ if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
+ return
+ }
+ authInfo, err := pa.GetAuthInfo(r)
+ if err != nil {
+ rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil)
+ }
+ dto.AuthInfo = *authInfo
+ 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)
+}
+
+func (obj myBase) Complete(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.Complete(dto)
+ rw.DataResponse(w, res, err)
+}
diff --git a/internal/interface/main-handler/mcu-order-item/handler.go b/internal/interface/main-handler/mcu-order-item/handler.go
new file mode 100644
index 00000000..75f5ad6a
--- /dev/null
+++ b/internal/interface/main-handler/mcu-order-item/handler.go
@@ -0,0 +1,98 @@
+package mcuorderitem
+
+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/mcu-order-item"
+ u "simrs-vx/internal/use-case/main-use-case/mcu-order-item"
+)
+
+type myBase struct{}
+
+var O myBase
+
+func (obj myBase) Create(w http.ResponseWriter, r *http.Request) {
+ dto := e.CreateDto{}
+ if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
+ return
+ }
+ res, err := u.Create(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) GetList(w http.ResponseWriter, r *http.Request) {
+ dto := e.ReadListDto{}
+ sf.UrlQueryParam(&dto, *r.URL)
+ res, err := u.ReadList(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+ dto := e.ReadDetailDto{}
+ dto.Id = uint(id)
+ res, err := u.ReadDetail(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) Update(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+
+ dto := e.UpdateDto{}
+ if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
+ return
+ }
+ dto.Id = uint(id)
+ res, err := u.Update(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+
+ dto := e.DeleteDto{}
+ dto.Id = uint(id)
+ res, err := u.Delete(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) Complete(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+
+ dto := e.ReadDetailDto{}
+ dto.Id = uint(id)
+ res, err := u.Complete(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) SetSchedule(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+
+ dto := e.SetScheduleDto{}
+ if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
+ return
+ }
+ dto.Id = uint(id)
+ res, err := u.SetSchedule(dto)
+ rw.DataResponse(w, res, err)
+}
diff --git a/internal/interface/main-handler/mcu-order-sub-item/handler.go b/internal/interface/main-handler/mcu-order-sub-item/handler.go
new file mode 100644
index 00000000..8e8f8c79
--- /dev/null
+++ b/internal/interface/main-handler/mcu-order-sub-item/handler.go
@@ -0,0 +1,83 @@
+package mcuordersubitem
+
+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/mcu-order-sub-item"
+ u "simrs-vx/internal/use-case/main-use-case/mcu-order-sub-item"
+)
+
+type myBase struct{}
+
+var O myBase
+
+func (obj myBase) Create(w http.ResponseWriter, r *http.Request) {
+ dto := e.CreateDto{}
+ if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
+ return
+ }
+ res, err := u.Create(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) GetList(w http.ResponseWriter, r *http.Request) {
+ dto := e.ReadListDto{}
+ sf.UrlQueryParam(&dto, *r.URL)
+ res, err := u.ReadList(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+ dto := e.ReadDetailDto{}
+ dto.Id = uint(id)
+ res, err := u.ReadDetail(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) Update(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+
+ dto := e.UpdateDto{}
+ if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
+ return
+ }
+ dto.Id = uint(id)
+ res, err := u.Update(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+
+ dto := e.DeleteDto{}
+ dto.Id = uint(id)
+ res, err := u.Delete(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) Complete(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+
+ dto := e.ReadDetailDto{}
+ dto.Id = uint(id)
+ res, err := u.Complete(dto)
+ rw.DataResponse(w, res, err)
+}
diff --git a/internal/interface/main-handler/mcu-order/handler.go b/internal/interface/main-handler/mcu-order/handler.go
new file mode 100644
index 00000000..bcd07a05
--- /dev/null
+++ b/internal/interface/main-handler/mcu-order/handler.go
@@ -0,0 +1,112 @@
+package mcuorder
+
+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/mcu-order"
+ u "simrs-vx/internal/use-case/main-use-case/mcu-order"
+
+ pa "simrs-vx/pkg/auth-helper"
+
+ d "github.com/karincake/dodol"
+)
+
+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
+ }
+ authInfo, err := pa.GetAuthInfo(r)
+ if err != nil {
+ rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil)
+ }
+ dto.AuthInfo = *authInfo
+ res, err := u.Create(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) GetList(w http.ResponseWriter, r *http.Request) {
+ dto := e.ReadListDto{}
+ sf.UrlQueryParam(&dto, *r.URL)
+ res, err := u.ReadList(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+ dto := e.ReadDetailDto{}
+ dto.Id = uint(id)
+ res, err := u.ReadDetail(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) Update(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+
+ dto := e.UpdateDto{}
+ if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
+ return
+ }
+ authInfo, err := pa.GetAuthInfo(r)
+ if err != nil {
+ rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil)
+ }
+ dto.AuthInfo = *authInfo
+ dto.Id = uint(id)
+ res, err := u.Update(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+
+ dto := e.DeleteDto{}
+ dto.Id = uint(id)
+ res, err := u.Delete(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) Complete(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+
+ dto := e.ReadDetailDto{}
+ dto.Id = uint(id)
+ res, err := u.Complete(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) SetSchedule(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+
+ dto := e.SetScheduleDto{}
+ if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
+ return
+ }
+ dto.Id = uint(id)
+ res, err := u.SetSchedule(dto)
+ rw.DataResponse(w, res, err)
+}
diff --git a/internal/interface/main-handler/mcu-sub-src/handler.go b/internal/interface/main-handler/mcu-sub-src/handler.go
new file mode 100644
index 00000000..949be715
--- /dev/null
+++ b/internal/interface/main-handler/mcu-sub-src/handler.go
@@ -0,0 +1,71 @@
+package mcusubsrc
+
+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/mcu-sub-src"
+ u "simrs-vx/internal/use-case/main-use-case/mcu-sub-src"
+)
+
+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/medication-item-dist/handler.go b/internal/interface/main-handler/medication-item-dist/handler.go
new file mode 100644
index 00000000..6c4b659f
--- /dev/null
+++ b/internal/interface/main-handler/medication-item-dist/handler.go
@@ -0,0 +1,94 @@
+package medicationitemdist
+
+import (
+ "net/http"
+
+ rw "github.com/karincake/risoles"
+ sf "github.com/karincake/semprit"
+
+ pa "simrs-vx/pkg/auth-helper"
+
+ e "simrs-vx/internal/domain/main-entities/medication-item-dist"
+ u "simrs-vx/internal/use-case/main-use-case/medication-item-dist"
+
+ d "github.com/karincake/dodol"
+)
+
+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)
+}
+
+func (obj myBase) Consume(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+
+ authInfo, err := pa.GetAuthInfo(r)
+ if err != nil {
+ rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil)
+ }
+
+ dto := e.ConsumeDto{}
+ if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
+ return
+ }
+ dto.AuthInfo = *authInfo
+ dto.Id = uint16(id)
+ res, err := u.Consume(dto)
+ rw.DataResponse(w, res, err)
+}
diff --git a/internal/interface/main-handler/medication-item/handler.go b/internal/interface/main-handler/medication-item/handler.go
new file mode 100644
index 00000000..bccb9f4f
--- /dev/null
+++ b/internal/interface/main-handler/medication-item/handler.go
@@ -0,0 +1,83 @@
+package medicationitem
+
+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/medication-item"
+ u "simrs-vx/internal/use-case/main-use-case/medication-item"
+)
+
+type myBase struct{}
+
+var O myBase
+
+func (obj myBase) Create(w http.ResponseWriter, r *http.Request) {
+ dto := e.CreateDto{}
+ if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
+ return
+ }
+ res, err := u.Create(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) GetList(w http.ResponseWriter, r *http.Request) {
+ dto := e.ReadListDto{}
+ sf.UrlQueryParam(&dto, *r.URL)
+ res, err := u.ReadList(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+ dto := e.ReadDetailDto{}
+ dto.Id = 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)
+}
+
+func (obj myBase) Redeem(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.Redeem(dto)
+ rw.DataResponse(w, res, err)
+}
diff --git a/internal/interface/main-handler/medication/handler.go b/internal/interface/main-handler/medication/handler.go
new file mode 100644
index 00000000..272eae56
--- /dev/null
+++ b/internal/interface/main-handler/medication/handler.go
@@ -0,0 +1,91 @@
+package medication
+
+import (
+ "net/http"
+
+ rw "github.com/karincake/risoles"
+ sf "github.com/karincake/semprit"
+
+ pa "simrs-vx/pkg/auth-helper"
+
+ e "simrs-vx/internal/domain/main-entities/medication"
+ u "simrs-vx/internal/use-case/main-use-case/medication"
+
+ d "github.com/karincake/dodol"
+)
+
+type myBase struct{}
+
+var O myBase
+
+func (obj myBase) Create(w http.ResponseWriter, r *http.Request) {
+ dto := e.CreateDto{}
+ if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
+ return
+ }
+ res, err := u.Create(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) GetList(w http.ResponseWriter, r *http.Request) {
+ dto := e.ReadListDto{}
+ sf.UrlQueryParam(&dto, *r.URL)
+ res, err := u.ReadList(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+ dto := e.ReadDetailDto{}
+ dto.Id = uint(id)
+ res, err := u.ReadDetail(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) Update(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+
+ dto := e.UpdateDto{}
+ if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
+ return
+ }
+ dto.Id = uint(id)
+ res, err := u.Update(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+
+ dto := e.DeleteDto{}
+ dto.Id = uint(id)
+ res, err := u.Delete(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) Complete(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+
+ authInfo, err := pa.GetAuthInfo(r)
+ if err != nil {
+ rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil)
+ }
+
+ dto := e.ReadDetailDto{}
+ dto.AuthInfo = *authInfo
+ dto.Id = uint(id)
+ res, err := u.Complete(dto)
+ rw.DataResponse(w, res, err)
+}
diff --git a/internal/interface/main-handler/patient/handler.go b/internal/interface/main-handler/patient/handler.go
index 57771b56..2c5fcb5b 100644
--- a/internal/interface/main-handler/patient/handler.go
+++ b/internal/interface/main-handler/patient/handler.go
@@ -10,6 +10,10 @@ import (
e "simrs-vx/internal/domain/main-entities/patient"
u "simrs-vx/internal/use-case/main-use-case/patient"
+
+ ere "simrs-vx/internal/domain/references/encounter"
+
+ d "github.com/karincake/dodol"
)
type myBase struct{}
@@ -69,3 +73,57 @@ func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) {
res, err := u.Delete(dto)
rw.DataResponse(w, res, err)
}
+
+func (obj myBase) Search(w http.ResponseWriter, r *http.Request) {
+ dto := e.SearchDto{}
+ 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) {
+ dto := e.SearchDto{}
+ sf.UrlQueryParam(&dto, *r.URL)
+ dto.Mode = e.SMNik
+ res, err := u.Search(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) Upload(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+
+ err := r.ParseMultipartForm(10 << 20) // 10 MB
+ if err != nil {
+ rw.DataResponse(w, nil, err)
+ return
+ }
+
+ code := r.FormValue("code")
+
+ file, header, err := r.FormFile("content")
+ if err != nil {
+ rw.DataResponse(w, nil, err)
+ return
+ }
+ defer file.Close()
+
+ dto := e.UploadDto{}
+ dto.Id = uint(id)
+ dto.Code = ere.UploadCode(code)
+ dto.File = file
+ dto.FileHeader = header
+ dto.Filename = header.Filename
+ dto.Size = header.Size
+ dto.MimeType = header.Header.Get("Content-Type")
+
+ res, err := u.Upload(dto)
+ rw.DataResponse(w, res, err)
+}
diff --git a/internal/interface/main-handler/person-insurance/handler.go b/internal/interface/main-handler/person-insurance/handler.go
new file mode 100644
index 00000000..d5e42f7b
--- /dev/null
+++ b/internal/interface/main-handler/person-insurance/handler.go
@@ -0,0 +1,71 @@
+package personinsurance
+
+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/person-insurance"
+ u "simrs-vx/internal/use-case/main-use-case/person-insurance"
+)
+
+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/postal-region/handler.go b/internal/interface/main-handler/postal-region/handler.go
new file mode 100644
index 00000000..baf3b2d6
--- /dev/null
+++ b/internal/interface/main-handler/postal-region/handler.go
@@ -0,0 +1,71 @@
+package postalregion
+
+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/postal-region"
+ u "simrs-vx/internal/use-case/main-use-case/postal-region"
+)
+
+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 = uint32(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 = uint32(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 = uint32(id)
+ res, err := u.Delete(dto)
+ rw.DataResponse(w, res, err)
+}
diff --git a/internal/interface/main-handler/prescription-item/handler.go b/internal/interface/main-handler/prescription-item/handler.go
new file mode 100644
index 00000000..faab4849
--- /dev/null
+++ b/internal/interface/main-handler/prescription-item/handler.go
@@ -0,0 +1,71 @@
+package prescriptionitem
+
+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/prescription-item"
+ u "simrs-vx/internal/use-case/main-use-case/prescription-item"
+)
+
+type myBase struct{}
+
+var O myBase
+
+func (obj myBase) Create(w http.ResponseWriter, r *http.Request) {
+ dto := e.CreateDto{}
+ if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
+ return
+ }
+ res, err := u.Create(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) GetList(w http.ResponseWriter, r *http.Request) {
+ dto := e.ReadListDto{}
+ sf.UrlQueryParam(&dto, *r.URL)
+ res, err := u.ReadList(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+ dto := e.ReadDetailDto{}
+ dto.Id = 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/prescription/handler.go b/internal/interface/main-handler/prescription/handler.go
new file mode 100644
index 00000000..fe73e3fe
--- /dev/null
+++ b/internal/interface/main-handler/prescription/handler.go
@@ -0,0 +1,83 @@
+package prescription
+
+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/prescription"
+ u "simrs-vx/internal/use-case/main-use-case/prescription"
+)
+
+type myBase struct{}
+
+var O myBase
+
+func (obj myBase) Create(w http.ResponseWriter, r *http.Request) {
+ dto := e.CreateDto{}
+ if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
+ return
+ }
+ res, err := u.Create(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) GetList(w http.ResponseWriter, r *http.Request) {
+ dto := e.ReadListDto{}
+ sf.UrlQueryParam(&dto, *r.URL)
+ res, err := u.ReadList(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+ dto := e.ReadDetailDto{}
+ dto.Id = uint(id)
+ res, err := u.ReadDetail(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) Update(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+
+ dto := e.UpdateDto{}
+ if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
+ return
+ }
+ dto.Id = uint(id)
+ res, err := u.Update(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+
+ dto := e.DeleteDto{}
+ dto.Id = uint(id)
+ res, err := u.Delete(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) Approve(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+
+ dto := e.ReadDetailDto{}
+ dto.Id = uint(id)
+ res, err := u.Approve(dto)
+ rw.DataResponse(w, res, err)
+}
diff --git a/internal/interface/main-handler/sbar/handler.go b/internal/interface/main-handler/sbar/handler.go
new file mode 100644
index 00000000..7fac1e00
--- /dev/null
+++ b/internal/interface/main-handler/sbar/handler.go
@@ -0,0 +1,80 @@
+package sbar
+
+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/sbar"
+ u "simrs-vx/internal/use-case/main-use-case/sbar"
+
+ pa "simrs-vx/pkg/auth-helper"
+
+ d "github.com/karincake/dodol"
+)
+
+type myBase struct{}
+
+var O myBase
+
+func (obj myBase) Create(w http.ResponseWriter, r *http.Request) {
+ authInfo, err := pa.GetAuthInfo(r)
+ if err != nil {
+ rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil)
+ }
+ dto := e.CreateDto{}
+ if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
+ return
+ }
+ dto.AuthInfo = *authInfo
+ res, err := u.Create(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) GetList(w http.ResponseWriter, r *http.Request) {
+ dto := e.ReadListDto{}
+ sf.UrlQueryParam(&dto, *r.URL)
+ res, err := u.ReadList(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+ dto := e.ReadDetailDto{}
+ dto.Id = uint16(id)
+ res, err := u.ReadDetail(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) Update(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+
+ dto := e.UpdateDto{}
+ if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
+ return
+ }
+ dto.Id = uint16(id)
+ res, err := u.Update(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+
+ dto := e.DeleteDto{}
+ dto.Id = uint16(id)
+ res, err := u.Delete(dto)
+ rw.DataResponse(w, res, err)
+}
diff --git a/internal/interface/main-handler/soapi/handler.go b/internal/interface/main-handler/soapi/handler.go
new file mode 100644
index 00000000..f5446b82
--- /dev/null
+++ b/internal/interface/main-handler/soapi/handler.go
@@ -0,0 +1,80 @@
+package soapi
+
+import (
+ "net/http"
+
+ rw "github.com/karincake/risoles"
+ sf "github.com/karincake/semprit"
+
+ // ua "github.com/karincake/tumpeng/auth/svc"
+
+ e "simrs-vx/internal/domain/main-entities/soapi"
+ u "simrs-vx/internal/use-case/main-use-case/soapi"
+
+ pa "simrs-vx/pkg/auth-helper"
+
+ d "github.com/karincake/dodol"
+)
+
+type myBase struct{}
+
+var O myBase
+
+func (obj myBase) Create(w http.ResponseWriter, r *http.Request) {
+ authInfo, err := pa.GetAuthInfo(r)
+ if err != nil {
+ rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": err.Error()}, nil)
+ }
+ dto := e.CreateDto{}
+ if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
+ return
+ }
+ dto.AuthInfo = *authInfo
+ res, err := u.Create(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) GetList(w http.ResponseWriter, r *http.Request) {
+ dto := e.ReadListDto{}
+ sf.UrlQueryParam(&dto, *r.URL)
+ res, err := u.ReadList(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+ dto := e.ReadDetailDto{}
+ dto.Id = uint16(id)
+ res, err := u.ReadDetail(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) Update(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+
+ dto := e.UpdateDto{}
+ if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res {
+ return
+ }
+ dto.Id = uint16(id)
+ res, err := u.Update(dto)
+ rw.DataResponse(w, res, err)
+}
+
+func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) {
+ id := rw.ValidateInt(w, "id", r.PathValue("id"))
+ if id <= 0 {
+ return
+ }
+
+ dto := e.DeleteDto{}
+ dto.Id = uint16(id)
+ res, err := u.Delete(dto)
+ rw.DataResponse(w, res, err)
+}
diff --git a/internal/interface/main-handler/specialist/handler.go b/internal/interface/main-handler/specialist/handler.go
new file mode 100644
index 00000000..561d07d0
--- /dev/null
+++ b/internal/interface/main-handler/specialist/handler.go
@@ -0,0 +1,71 @@
+package specialist
+
+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"
+ u "simrs-vx/internal/use-case/main-use-case/specialist"
+)
+
+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
new file mode 100644
index 00000000..d639c115
--- /dev/null
+++ b/internal/interface/main-handler/subspecialist/handler.go
@@ -0,0 +1,71 @@
+package subspecialist
+
+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"
+ u "simrs-vx/internal/use-case/main-use-case/subspecialist"
+)
+
+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/upload/handler.go b/internal/interface/main-handler/upload/handler.go
new file mode 100644
index 00000000..0cff949e
--- /dev/null
+++ b/internal/interface/main-handler/upload/handler.go
@@ -0,0 +1,56 @@
+package upload
+
+// "net/http"
+
+// uh "simrs-vx/pkg/upload-helper"
+
+// uploadHandler handles single file upload requests
+// func uploadHandler(w http.ResponseWriter, r *http.Request) {
+
+// if r.Method == "OPTIONS" {
+// w.WriteHeader(http.StatusNoContent)
+// return
+// }
+
+// if r.Method != "POST" {
+// writeJSONResponse(w, http.StatusMethodNotAllowed, uh.UploadResponse{
+// Success: false,
+// Message: "Method not allowed. Use POST.",
+// })
+// return
+// }
+
+// // Parse multipart form (32MB max memory)
+// err := r.ParseMultipartForm(32 << 20)
+// if err != nil {
+// writeJSONResponse(w, http.StatusBadRequest, uh.UploadResponse{
+// Success: false,
+// Message: "Failed to parse multipart form",
+// })
+// return
+// }
+
+// // Get file from form
+// file, header, err := r.FormFile("file")
+// if err != nil {
+// writeJSONResponse(w, http.StatusBadRequest, uh.UploadResponse{
+// Success: false,
+// Message: "No file uploaded or invalid file field name. Use 'file' as field name.",
+// })
+// return
+// }
+// defer file.Close()
+
+// // Upload file
+// response, err := service.UploadFile(file, header.Filename, header.Size)
+// if err != nil {
+// writeJSONResponse(w, http.StatusInternalServerError, *response)
+// return
+// }
+
+// if response.Success {
+// writeJSONResponse(w, http.StatusOK, *response)
+// } else {
+// writeJSONResponse(w, http.StatusBadRequest, *response)
+// }
+// }
diff --git a/internal/interface/migration/main-entities.go b/internal/interface/migration/main-entities.go
new file mode 100644
index 00000000..131b2972
--- /dev/null
+++ b/internal/interface/migration/main-entities.go
@@ -0,0 +1,175 @@
+package migration
+
+import (
+ adime "simrs-vx/internal/domain/main-entities/adime"
+ ambulancetransportreq "simrs-vx/internal/domain/main-entities/ambulance-transport-req"
+ ambulatory "simrs-vx/internal/domain/main-entities/ambulatory"
+ appointment "simrs-vx/internal/domain/main-entities/appointment"
+ chemo "simrs-vx/internal/domain/main-entities/chemo"
+ consultation "simrs-vx/internal/domain/main-entities/consultation"
+ counter "simrs-vx/internal/domain/main-entities/counter"
+ device "simrs-vx/internal/domain/main-entities/device"
+ deviceorder "simrs-vx/internal/domain/main-entities/device-order"
+ deviceorderitem "simrs-vx/internal/domain/main-entities/device-order-item"
+ diagnosesrc "simrs-vx/internal/domain/main-entities/diagnose-src"
+ district "simrs-vx/internal/domain/main-entities/district"
+ division "simrs-vx/internal/domain/main-entities/division"
+ divisionposition "simrs-vx/internal/domain/main-entities/division-position"
+ doctor "simrs-vx/internal/domain/main-entities/doctor"
+ doctorfee "simrs-vx/internal/domain/main-entities/doctor-fee"
+ emergency "simrs-vx/internal/domain/main-entities/emergency"
+ employee "simrs-vx/internal/domain/main-entities/employee"
+ encounter "simrs-vx/internal/domain/main-entities/encounter"
+ ethnic "simrs-vx/internal/domain/main-entities/ethnic"
+ infra "simrs-vx/internal/domain/main-entities/infra"
+ inpatient "simrs-vx/internal/domain/main-entities/inpatient"
+ installation "simrs-vx/internal/domain/main-entities/installation"
+ insurancecompany "simrs-vx/internal/domain/main-entities/insurance-company"
+ intern "simrs-vx/internal/domain/main-entities/intern"
+ internalreference "simrs-vx/internal/domain/main-entities/internal-reference"
+ item "simrs-vx/internal/domain/main-entities/item"
+ itemprice "simrs-vx/internal/domain/main-entities/item-price"
+ laborant "simrs-vx/internal/domain/main-entities/laborant"
+ language "simrs-vx/internal/domain/main-entities/language"
+ material "simrs-vx/internal/domain/main-entities/material"
+ materialorder "simrs-vx/internal/domain/main-entities/material-order"
+ materialorderitem "simrs-vx/internal/domain/main-entities/material-order-item"
+ mcuorder "simrs-vx/internal/domain/main-entities/mcu-order"
+ mcuorderitem "simrs-vx/internal/domain/main-entities/mcu-order-item"
+ mcuordersubitem "simrs-vx/internal/domain/main-entities/mcu-order-sub-item"
+ mcusrc "simrs-vx/internal/domain/main-entities/mcu-src"
+ mcusrccategory "simrs-vx/internal/domain/main-entities/mcu-src-category"
+ mcusubsrc "simrs-vx/internal/domain/main-entities/mcu-sub-src"
+ medicalactionsrc "simrs-vx/internal/domain/main-entities/medical-action-src"
+ medicalactionsrcitem "simrs-vx/internal/domain/main-entities/medical-action-src-item"
+ medication "simrs-vx/internal/domain/main-entities/medication"
+ medicationitem "simrs-vx/internal/domain/main-entities/medication-item"
+ medicationitemdist "simrs-vx/internal/domain/main-entities/medication-item-dist"
+ medicine "simrs-vx/internal/domain/main-entities/medicine"
+ medicinegroup "simrs-vx/internal/domain/main-entities/medicine-group"
+ medicinemethod "simrs-vx/internal/domain/main-entities/medicine-method"
+ medicinemix "simrs-vx/internal/domain/main-entities/medicine-mix"
+ medicinemixitem "simrs-vx/internal/domain/main-entities/medicine-mix-item"
+ midwife "simrs-vx/internal/domain/main-entities/midwife"
+ nurse "simrs-vx/internal/domain/main-entities/nurse"
+ nutritionist "simrs-vx/internal/domain/main-entities/nutritionist"
+ patient "simrs-vx/internal/domain/main-entities/patient"
+ person "simrs-vx/internal/domain/main-entities/person"
+ personaddress "simrs-vx/internal/domain/main-entities/person-address"
+ personcontact "simrs-vx/internal/domain/main-entities/person-contact"
+ personinsurance "simrs-vx/internal/domain/main-entities/person-insurance"
+ personrelative "simrs-vx/internal/domain/main-entities/person-relative"
+ pharmacist "simrs-vx/internal/domain/main-entities/pharmacist"
+ pharmacycompany "simrs-vx/internal/domain/main-entities/pharmacy-company"
+ postalregion "simrs-vx/internal/domain/main-entities/postal-region"
+ practiceschedule "simrs-vx/internal/domain/main-entities/practice-schedule"
+ prescription "simrs-vx/internal/domain/main-entities/prescription"
+ prescriptionitem "simrs-vx/internal/domain/main-entities/prescription-item"
+ proceduresrc "simrs-vx/internal/domain/main-entities/procedure-src"
+ province "simrs-vx/internal/domain/main-entities/province"
+ regency "simrs-vx/internal/domain/main-entities/regency"
+ room "simrs-vx/internal/domain/main-entities/room"
+ sbar "simrs-vx/internal/domain/main-entities/sbar"
+ soapi "simrs-vx/internal/domain/main-entities/soapi"
+ specialist "simrs-vx/internal/domain/main-entities/specialist"
+ specialistintern "simrs-vx/internal/domain/main-entities/specialist-intern"
+ subspecialist "simrs-vx/internal/domain/main-entities/subspecialist"
+ unit "simrs-vx/internal/domain/main-entities/unit"
+ uom "simrs-vx/internal/domain/main-entities/uom"
+ user "simrs-vx/internal/domain/main-entities/user"
+ vehicle "simrs-vx/internal/domain/main-entities/vehicle"
+ vehiclehist "simrs-vx/internal/domain/main-entities/vehicle-hist"
+ village "simrs-vx/internal/domain/main-entities/village"
+
+ ///BPJS
+ vclaimsep "simrs-vx/internal/domain/bpjs-entities/vclaim-sep"
+ vclaimsephist "simrs-vx/internal/domain/bpjs-entities/vclaim-sep-hist"
+ vclaimsepprint "simrs-vx/internal/domain/bpjs-entities/vclaim-sep-print"
+)
+
+func getMainEntities() []any {
+ return []any{
+ &user.User{},
+ &division.Division{},
+ &divisionposition.DivisionPosition{},
+ &installation.Installation{},
+ &unit.Unit{},
+ &village.Village{},
+ &district.District{},
+ ®ency.Regency{},
+ &province.Province{},
+ &person.Person{},
+ &personaddress.PersonAddress{},
+ &personcontact.PersonContact{},
+ &personinsurance.PersonInsurance{},
+ &pharmacycompany.PharmacyCompany{},
+ &diagnosesrc.DiagnoseSrc{},
+ &proceduresrc.ProcedureSrc{},
+ &employee.Employee{},
+ &intern.Intern{},
+ &doctor.Doctor{},
+ &nurse.Nurse{},
+ &nutritionist.Nutritionist{},
+ &pharmacist.Pharmacist{},
+ &counter.Counter{},
+ &practiceschedule.PracticeSchedule{},
+ &uom.Uom{},
+ &item.Item{},
+ &itemprice.ItemPrice{},
+ &infra.Infra{},
+ &medicinegroup.MedicineGroup{},
+ &medicinemethod.MedicineMethod{},
+ &mcusrccategory.McuSrcCategory{},
+ &mcusrc.McuSrc{},
+ ðnic.Ethnic{},
+ &insurancecompany.InsuranceCompany{},
+ &medicine.Medicine{},
+ &medicinemix.MedicineMix{},
+ &medicinemixitem.MedicineMixItem{},
+ &medicalactionsrc.MedicalActionSrc{},
+ &medicalactionsrcitem.MedicalActionSrcItem{},
+ &material.Material{},
+ &device.Device{},
+ &doctorfee.DoctorFee{},
+ &language.Language{},
+ &personrelative.PersonRelative{},
+ &patient.Patient{},
+ &appointment.Appointment{},
+ &vclaimsep.VclaimSep{},
+ &encounter.Encounter{},
+ &laborant.Laborant{},
+ &specialist.Specialist{},
+ &subspecialist.Subspecialist{},
+ &specialistintern.SpecialistIntern{},
+ &room.Room{},
+ &soapi.Soapi{},
+ &sbar.Sbar{},
+ &adime.Adime{},
+ &emergency.Emergency{},
+ &inpatient.Inpatient{},
+ &ambulatory.Ambulatory{},
+ &prescription.Prescription{},
+ &prescriptionitem.PrescriptionItem{},
+ &medication.Medication{},
+ &medicationitem.MedicationItem{},
+ &medicationitemdist.MedicationItemDist{},
+ &deviceorder.DeviceOrder{},
+ &deviceorderitem.DeviceOrderItem{},
+ &materialorder.MaterialOrder{},
+ &materialorderitem.MaterialOrderItem{},
+ &mcuorder.McuOrder{},
+ &mcuorderitem.McuOrderItem{},
+ &mcusubsrc.McuSubSrc{},
+ &mcuordersubitem.McuOrderSubItem{},
+ &consultation.Consultation{},
+ &chemo.Chemo{},
+ &midwife.Midwife{},
+ &postalregion.PostalRegion{},
+ &internalreference.InternalReference{},
+ &vclaimsephist.VclaimSepHist{},
+ &vclaimsepprint.VclaimSepPrint{},
+ &vehicle.Vehicle{},
+ &vehiclehist.VehicleHist{},
+ &ambulancetransportreq.AmbulanceTransportReq{},
+ }
+}
diff --git a/internal/interface/migration/migration.go b/internal/interface/migration/migration.go
index 2f6f0d50..6cec68dc 100644
--- a/internal/interface/migration/migration.go
+++ b/internal/interface/migration/migration.go
@@ -4,76 +4,20 @@ import (
"fmt"
"io"
"os"
- "os/exec"
- counter "simrs-vx/internal/domain/main-entities/counter"
- device "simrs-vx/internal/domain/main-entities/device"
- diagnosesrc "simrs-vx/internal/domain/main-entities/diagnose-src"
- district "simrs-vx/internal/domain/main-entities/district"
- division "simrs-vx/internal/domain/main-entities/division"
- divisionposition "simrs-vx/internal/domain/main-entities/division-position"
- doctor "simrs-vx/internal/domain/main-entities/doctor"
- doctorfee "simrs-vx/internal/domain/main-entities/doctor-fee"
- employee "simrs-vx/internal/domain/main-entities/employee"
- encounter "simrs-vx/internal/domain/main-entities/encounter"
- ethnic "simrs-vx/internal/domain/main-entities/ethnic"
- infra "simrs-vx/internal/domain/main-entities/infra"
- installation "simrs-vx/internal/domain/main-entities/installation"
- insurancecompany "simrs-vx/internal/domain/main-entities/insurance-company"
- item "simrs-vx/internal/domain/main-entities/item"
- itemprice "simrs-vx/internal/domain/main-entities/item-price"
- language "simrs-vx/internal/domain/main-entities/language"
- material "simrs-vx/internal/domain/main-entities/material"
- mcusrc "simrs-vx/internal/domain/main-entities/mcu-src"
- mcusrccategory "simrs-vx/internal/domain/main-entities/mcu-src-category"
- medicalactionsrc "simrs-vx/internal/domain/main-entities/medical-action-src"
- medicalactionsrcitem "simrs-vx/internal/domain/main-entities/medical-action-src-item"
- medicine "simrs-vx/internal/domain/main-entities/medicine"
- medicinegroup "simrs-vx/internal/domain/main-entities/medicine-group"
- medicinemethod "simrs-vx/internal/domain/main-entities/medicine-method"
- medicinemix "simrs-vx/internal/domain/main-entities/medicine-mix"
- medicinemixitem "simrs-vx/internal/domain/main-entities/medicine-mix-item"
- nurse "simrs-vx/internal/domain/main-entities/nurse"
- nutritionist "simrs-vx/internal/domain/main-entities/nutritionist"
- patient "simrs-vx/internal/domain/main-entities/patient"
- person "simrs-vx/internal/domain/main-entities/person"
- personaddress "simrs-vx/internal/domain/main-entities/person-address"
- personcontact "simrs-vx/internal/domain/main-entities/person-contact"
- personrelative "simrs-vx/internal/domain/main-entities/person-relative"
- pharmacist "simrs-vx/internal/domain/main-entities/pharmacist"
- pharmacycompany "simrs-vx/internal/domain/main-entities/pharmacy-company"
- practiceschedule "simrs-vx/internal/domain/main-entities/practice-schedule"
- proceduresrc "simrs-vx/internal/domain/main-entities/procedure-src"
- province "simrs-vx/internal/domain/main-entities/province"
- regency "simrs-vx/internal/domain/main-entities/regency"
- unit "simrs-vx/internal/domain/main-entities/unit"
- uom "simrs-vx/internal/domain/main-entities/uom"
- user "simrs-vx/internal/domain/main-entities/user"
- village "simrs-vx/internal/domain/main-entities/village"
"ariga.io/atlas-provider-gorm/gormschema"
"gorm.io/gorm"
"gorm.io/gorm/schema"
)
-type Config struct {
- DbCfg DbConf `yaml:"dbCfg"`
-}
-
-type DbConf struct {
- DSN string `yaml:"dsn"`
- MaxOpenConns int `yaml:"maxOpenConns"`
- MaxIdleConns int `yaml:"maxIdleConns"`
- MaxIdleTime int `yaml:"maxIdleTime"`
-}
-
-func Loader() {
+func loader(input string) {
gormCfg := &gorm.Config{
NamingStrategy: schema.NamingStrategy{
SingularTable: true,
NoLowerCase: true,
},
}
- stmts, err := gormschema.New("postgres", gormschema.WithConfig(gormCfg)).Load(GetEntities()...)
+ stmts, err := gormschema.New("postgres", gormschema.WithConfig(gormCfg)).Load(getEntities(input)...)
if err != nil {
fmt.Fprintf(os.Stderr, "failed to load gorm schema: %v\n", err)
os.Exit(1)
@@ -81,79 +25,17 @@ func Loader() {
_, _ = io.WriteString(os.Stdout, stmts)
}
-func GetEntities() []any {
- return []any{
- &user.User{},
- &division.Division{},
- &divisionposition.DivisionPosition{},
- &installation.Installation{},
- &unit.Unit{},
- &village.Village{},
- &district.District{},
- ®ency.Regency{},
- &province.Province{},
- &person.Person{},
- &personaddress.PersonAddress{},
- &personcontact.PersonContact{},
- &pharmacycompany.PharmacyCompany{},
- &diagnosesrc.DiagnoseSrc{},
- &proceduresrc.ProcedureSrc{},
- &employee.Employee{},
- &doctor.Doctor{},
- &nurse.Nurse{},
- &nutritionist.Nutritionist{},
- &pharmacist.Pharmacist{},
- &counter.Counter{},
- &practiceschedule.PracticeSchedule{},
- &uom.Uom{},
- &item.Item{},
- &itemprice.ItemPrice{},
- &infra.Infra{},
- &medicinegroup.MedicineGroup{},
- &medicinemethod.MedicineMethod{},
- &mcusrccategory.McuSrcCategory{},
- &mcusrc.McuSrc{},
- ðnic.Ethnic{},
- &insurancecompany.InsuranceCompany{},
- &medicine.Medicine{},
- &medicinemix.MedicineMix{},
- &medicinemixitem.MedicineMixItem{},
- &medicalactionsrc.MedicalActionSrc{},
- &medicalactionsrcitem.MedicalActionSrcItem{},
- &material.Material{},
- &device.Device{},
- &doctorfee.DoctorFee{},
- &language.Language{},
- &personrelative.PersonRelative{},
- &patient.Patient{},
- &encounter.Encounter{},
+func getEntities(input string) []any {
+ switch input {
+ case "main":
+ return getMainEntities()
+ case "satusehat":
+ return getSatuSehatEntities()
}
+ return nil
}
-func runAtlas(args ...string) error {
- cmd := exec.Command("atlas", args...)
- cmd.Stdout = os.Stdout
- cmd.Stderr = os.Stderr
- return cmd.Run()
-}
-
-func logMsg(msg string) {
- fmt.Fprintln(os.Stderr, msg)
-}
-
-func Migrate() {
- Loader()
- logMsg("Running atlas migrate diff...")
- if err := runAtlas("migrate", "diff", "--env", "gorm"); err != nil {
- logMsg(fmt.Sprintf("Failed to run diff: %v", err))
- return
- }
-
- logMsg("Running atlas migrate apply...")
- if err := runAtlas("migrate", "apply", "--env", "gorm"); err != nil {
- logMsg(fmt.Sprintf("Failed to run apply: %v", err))
- return
- }
-
- logMsg("Migration complete")
+func Migrate(input string) {
+ loader(input)
+
}
diff --git a/internal/interface/migration/satusehat-entities.go b/internal/interface/migration/satusehat-entities.go
new file mode 100644
index 00000000..02d4aa94
--- /dev/null
+++ b/internal/interface/migration/satusehat-entities.go
@@ -0,0 +1,11 @@
+package migration
+
+import (
+ patient "simrs-vx/internal/domain/satusehat-entities/patient"
+)
+
+func getSatuSehatEntities() []any {
+ return []any{
+ &patient.Patient{},
+ }
+}
diff --git a/internal/interface/migration/tycovar.go b/internal/interface/migration/tycovar.go
new file mode 100644
index 00000000..f86f855d
--- /dev/null
+++ b/internal/interface/migration/tycovar.go
@@ -0,0 +1,7 @@
+/* Package migration is used to migrate the database */
+package migration
+
+const (
+ Main = "main"
+ SatuSehat = "satusehat"
+)
diff --git a/internal/use-case/bpjs-plugin/member/helper.go b/internal/use-case/bpjs-plugin/member/helper.go
new file mode 100644
index 00000000..f5e2bc0e
--- /dev/null
+++ b/internal/use-case/bpjs-plugin/member/helper.go
@@ -0,0 +1,18 @@
+package member
+
+import (
+ "fmt"
+ e "simrs-vx/internal/domain/bpjs-entities/member"
+ ibpjs "simrs-vx/internal/infra/bpjs"
+)
+
+func endpointMapper(input *e.ReadListDto) string {
+ switch input.ReferenceType {
+ case e.RTBpjs:
+ return fmt.Sprintf("%speserta/nokartu?noKartu=%s&tglpelayanan=%s", ibpjs.O.BaseUrl, input.PathValue1, input.PathValue2)
+ case e.RTNik:
+ return fmt.Sprintf("%speserta/nik?nik=%s&tglpelayanan=%s", ibpjs.O.BaseUrl, input.PathValue1, input.PathValue2)
+ default:
+ return ""
+ }
+}
diff --git a/internal/use-case/bpjs-plugin/member/plugin.go b/internal/use-case/bpjs-plugin/member/plugin.go
new file mode 100644
index 00000000..7610a5ac
--- /dev/null
+++ b/internal/use-case/bpjs-plugin/member/plugin.go
@@ -0,0 +1,37 @@
+package member
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "net/http"
+ e "simrs-vx/internal/domain/bpjs-entities/member"
+
+ "gorm.io/gorm"
+)
+
+func ReadList(input *e.ReadListDto, data *e.Response, tx *gorm.DB) error {
+ endpoint := endpointMapper(input)
+ req, err := http.NewRequest("GET", endpoint, nil)
+ if err != nil {
+ return err
+ }
+ req.Header.Set("Content-Type", "application/json")
+
+ resp, err := http.DefaultClient.Do(req)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+
+ body, err := io.ReadAll(resp.Body)
+ if err != nil {
+ return err
+ }
+
+ if err := json.Unmarshal(body, &data); err != nil {
+ return fmt.Errorf("failed to parse response JSON: %w", err)
+ }
+
+ return nil
+}
diff --git a/internal/use-case/bpjs-plugin/monitoring/helper.go b/internal/use-case/bpjs-plugin/monitoring/helper.go
new file mode 100644
index 00000000..8f6d2c88
--- /dev/null
+++ b/internal/use-case/bpjs-plugin/monitoring/helper.go
@@ -0,0 +1,18 @@
+package monitoring
+
+import (
+ "fmt"
+ e "simrs-vx/internal/domain/bpjs-entities/monitoring"
+ ibpjs "simrs-vx/internal/infra/bpjs"
+)
+
+func endpointMapper(input *e.ReadListDto) string {
+ switch input.ReferenceType {
+ case e.RTHist:
+ return fmt.Sprintf("%smonitoring/history/%s?tglawal=%s&tglakhir=%s", ibpjs.O.BaseUrl, input.PathValue1, input.PathValue2, input.PathValue3)
+ case e.RTVisit:
+ return fmt.Sprintf("%smonitoring/kunjungan?tglpelayanan=%s&jnspelayanan=%s", ibpjs.O.BaseUrl, input.PathValue1, input.PathValue2)
+ default:
+ return ""
+ }
+}
diff --git a/internal/use-case/bpjs-plugin/monitoring/plugin.go b/internal/use-case/bpjs-plugin/monitoring/plugin.go
new file mode 100644
index 00000000..2450e4e9
--- /dev/null
+++ b/internal/use-case/bpjs-plugin/monitoring/plugin.go
@@ -0,0 +1,37 @@
+package monitoring
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "net/http"
+ e "simrs-vx/internal/domain/bpjs-entities/monitoring"
+
+ "gorm.io/gorm"
+)
+
+func ReadList(input *e.ReadListDto, data *e.Response, tx *gorm.DB) error {
+ endpoint := endpointMapper(input)
+ req, err := http.NewRequest("GET", endpoint, nil)
+ if err != nil {
+ return err
+ }
+ req.Header.Set("Content-Type", "application/json")
+
+ resp, err := http.DefaultClient.Do(req)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+
+ body, err := io.ReadAll(resp.Body)
+ if err != nil {
+ return err
+ }
+
+ if err := json.Unmarshal(body, &data); err != nil {
+ return fmt.Errorf("failed to parse response JSON: %w", err)
+ }
+
+ return nil
+}
diff --git a/internal/use-case/bpjs-plugin/reference/helper.go b/internal/use-case/bpjs-plugin/reference/helper.go
new file mode 100644
index 00000000..3e87089b
--- /dev/null
+++ b/internal/use-case/bpjs-plugin/reference/helper.go
@@ -0,0 +1,32 @@
+package reference
+
+import (
+ "fmt"
+ e "simrs-vx/internal/domain/bpjs-entities/reference"
+ ibpjs "simrs-vx/internal/infra/bpjs"
+)
+
+func endpointMapper(input *e.ReadListDto) string {
+ switch input.ReferenceType {
+ case e.RTProvince:
+ return ibpjs.O.BaseUrl + "provinces"
+ case e.RTCities:
+ return ibpjs.O.BaseUrl + "cities/" + input.PathValue1
+ case e.RTDistrict:
+ return ibpjs.O.BaseUrl + "districts/" + input.PathValue1
+ case e.RTDiagnose:
+ return ibpjs.O.BaseUrl + "diagnosa/" + input.PathValue1
+ case e.RTDiagnosePrb:
+ return ibpjs.O.BaseUrl + "diagnosaprb"
+ case e.RTMedicinePrb:
+ return ibpjs.O.BaseUrl + "obatprb/" + input.PathValue1
+ case e.RTUnit:
+ return ibpjs.O.BaseUrl + "referensi/poli/" + input.PathValue1
+ case e.RTHealthcare:
+ return fmt.Sprintf("%sreferensi/faskes?faskes=%s&jenis-faskes=%s", ibpjs.O.BaseUrl, input.PathValue1, input.PathValue2)
+ case e.RTDoctor:
+ return fmt.Sprintf("%sreferensi/dokter-dpjp?jenis-pelayanan=%s&tgl-pelayanan=%s&kode-spesialis=%s", ibpjs.O.BaseUrl, input.PathValue1, input.PathValue2, input.PathValue3)
+ default:
+ return ""
+ }
+}
diff --git a/internal/use-case/bpjs-plugin/reference/plugin.go b/internal/use-case/bpjs-plugin/reference/plugin.go
new file mode 100644
index 00000000..f4d4098e
--- /dev/null
+++ b/internal/use-case/bpjs-plugin/reference/plugin.go
@@ -0,0 +1,37 @@
+package reference
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "net/http"
+ e "simrs-vx/internal/domain/bpjs-entities/reference"
+
+ "gorm.io/gorm"
+)
+
+func ReadList(input *e.ReadListDto, data *e.Response, tx *gorm.DB) error {
+ endpoint := endpointMapper(input)
+ req, err := http.NewRequest("GET", endpoint, nil)
+ if err != nil {
+ return err
+ }
+ req.Header.Set("Content-Type", "application/json")
+
+ resp, err := http.DefaultClient.Do(req)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+
+ body, err := io.ReadAll(resp.Body)
+ if err != nil {
+ return err
+ }
+
+ if err := json.Unmarshal(body, &data); err != nil {
+ return fmt.Errorf("failed to parse response JSON: %w", err)
+ }
+
+ return nil
+}
diff --git a/internal/use-case/bpjs-plugin/vclaim-sep/plugin.go b/internal/use-case/bpjs-plugin/vclaim-sep/plugin.go
new file mode 100644
index 00000000..fd18763f
--- /dev/null
+++ b/internal/use-case/bpjs-plugin/vclaim-sep/plugin.go
@@ -0,0 +1,58 @@
+package vclaimsep
+
+import (
+ "bytes"
+ "encoding/json"
+ "fmt"
+ "io"
+ "net/http"
+ e "simrs-vx/internal/domain/bpjs-entities/vclaim-sep"
+
+ ibpjs "simrs-vx/internal/infra/bpjs"
+
+ "gorm.io/gorm"
+)
+
+func CreateSep(input *e.CreateDto, data *e.VclaimSep, tx *gorm.DB) error {
+ req, err := http.NewRequest("POST", ibpjs.O.BaseUrl+"/sep", bytes.NewReader(input.RequestPayload))
+ if err != nil {
+ return err
+ }
+ req.Header.Set("Content-Type", "application/json")
+
+ resp, err := http.DefaultClient.Do(req)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+
+ body, err := io.ReadAll(resp.Body)
+ if err != nil {
+ return err
+ }
+
+ var vresp vclaimResponse
+ if err := json.Unmarshal(body, &vresp); err != nil {
+ return fmt.Errorf("failed to parse response JSON: %w", err)
+ }
+
+ msg := vresp.MetaData.Message
+
+ if err := json.Unmarshal(body, data); err != nil {
+ return fmt.Errorf("failed to unmarshal into VclaimSep: %w", err)
+ }
+
+ // Save request/response details in DTO for further use
+ input.VclaimSepHist.RequestPayload = string(input.RequestPayload)
+ input.VclaimSepHist.ResponseBody = string(body)
+ input.VclaimSepHist.Message = msg
+ input.Number = func() *string {
+ number := ""
+ if vresp.Response != nil && vresp.Response.Sep != nil {
+ number = vresp.Response.Sep.NoSep
+ }
+ return &number
+ }()
+
+ return nil
+}
diff --git a/internal/use-case/bpjs-plugin/vclaim-sep/tycovar.go b/internal/use-case/bpjs-plugin/vclaim-sep/tycovar.go
new file mode 100644
index 00000000..f057726e
--- /dev/null
+++ b/internal/use-case/bpjs-plugin/vclaim-sep/tycovar.go
@@ -0,0 +1,12 @@
+package vclaimsep
+
+type vclaimResponse struct {
+ MetaData struct {
+ Message string `json:"message"`
+ } `json:"metaData"`
+ Response *struct {
+ Sep *struct {
+ NoSep string `json:"noSep"`
+ } `json:"sep"`
+ } `json:"response"`
+}
diff --git a/internal/use-case/bpjs-use-case/member/case.go b/internal/use-case/bpjs-use-case/member/case.go
new file mode 100644
index 00000000..7c50ea76
--- /dev/null
+++ b/internal/use-case/bpjs-use-case/member/case.go
@@ -0,0 +1,50 @@
+package member
+
+import (
+ e "simrs-vx/internal/domain/bpjs-entities/member"
+
+ dg "github.com/karincake/apem/db-gorm-pg"
+
+ pl "simrs-vx/pkg/logger"
+ pu "simrs-vx/pkg/use-case-helper"
+
+ "gorm.io/gorm"
+)
+
+const source = "member"
+
+func ReadList(input e.ReadListDto) (*e.Response, error) {
+ var data e.Response
+ var err error
+
+ event := pl.Event{
+ Feature: "ReadList",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "readList")
+
+ err = dg.I.Transaction(func(tx *gorm.DB) error {
+ mwRunner := newMiddlewareRunner(&event, tx)
+ mwRunner.setMwType(pu.MWTPre)
+ // Run pre-middleware
+ if err := mwRunner.RunReadListMiddleware(readListPreMw, &input, &data); err != nil {
+ return err
+ }
+
+ mwRunner.setMwType(pu.MWTPost)
+ // Run post-middleware
+ if err := mwRunner.RunReadListMiddleware(readListPostMw, &input, &data); err != nil {
+ return err
+ }
+
+ return nil
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &data, nil
+}
diff --git a/internal/use-case/bpjs-use-case/member/middleware-runner.go b/internal/use-case/bpjs-use-case/member/middleware-runner.go
new file mode 100644
index 00000000..71061a1b
--- /dev/null
+++ b/internal/use-case/bpjs-use-case/member/middleware-runner.go
@@ -0,0 +1,42 @@
+package member
+
+import (
+ e "simrs-vx/internal/domain/bpjs-entities/member"
+ pl "simrs-vx/pkg/logger"
+ pu "simrs-vx/pkg/use-case-helper"
+
+ "gorm.io/gorm"
+)
+
+type middlewareRunner struct {
+ Event *pl.Event
+ Tx *gorm.DB
+ MwType pu.MWType
+}
+
+// NewMiddlewareExecutor creates a new middleware executor
+func newMiddlewareRunner(event *pl.Event, tx *gorm.DB) *middlewareRunner {
+ return &middlewareRunner{
+ Event: event,
+ Tx: tx,
+ }
+}
+
+func (me *middlewareRunner) RunReadListMiddleware(middlewares []readListMw, input *e.ReadListDto, data *e.Response) error {
+ for _, middleware := range middlewares {
+ logData := pu.GetLogData(input, data)
+
+ pl.SetLogInfo(me.Event, logData, "started", middleware.Name)
+
+ if err := middleware.Func(input, data, me.Tx); err != nil {
+ return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err)
+ }
+
+ pl.SetLogInfo(me.Event, nil, "complete")
+ }
+ return nil
+}
+
+func (me *middlewareRunner) setMwType(mwType pu.MWType) {
+ me.MwType = mwType
+}
diff --git a/internal/use-case/bpjs-use-case/member/middleware.go b/internal/use-case/bpjs-use-case/member/middleware.go
new file mode 100644
index 00000000..e2fd5584
--- /dev/null
+++ b/internal/use-case/bpjs-use-case/member/middleware.go
@@ -0,0 +1,12 @@
+package member
+
+import (
+ pm "simrs-vx/internal/use-case/bpjs-plugin/member"
+)
+
+func init() {
+ readListPreMw = append(readListPreMw,
+ readListMw{Name: "readList-member", Func: pm.ReadList},
+ )
+
+}
diff --git a/internal/use-case/bpjs-use-case/member/tycovar.go b/internal/use-case/bpjs-use-case/member/tycovar.go
new file mode 100644
index 00000000..7d04363f
--- /dev/null
+++ b/internal/use-case/bpjs-use-case/member/tycovar.go
@@ -0,0 +1,18 @@
+/*
+member is peserta
+*/
+package member
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/bpjs-entities/member"
+)
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.Response, tx *gorm.DB) error
+}
+
+var readListPreMw []readListMw // ..
+var readListPostMw []readListMw // ..
diff --git a/internal/use-case/bpjs-use-case/monitoring/case.go b/internal/use-case/bpjs-use-case/monitoring/case.go
new file mode 100644
index 00000000..43109cca
--- /dev/null
+++ b/internal/use-case/bpjs-use-case/monitoring/case.go
@@ -0,0 +1,50 @@
+package monitoring
+
+import (
+ e "simrs-vx/internal/domain/bpjs-entities/monitoring"
+
+ dg "github.com/karincake/apem/db-gorm-pg"
+
+ pl "simrs-vx/pkg/logger"
+ pu "simrs-vx/pkg/use-case-helper"
+
+ "gorm.io/gorm"
+)
+
+const source = "monitoring"
+
+func ReadList(input e.ReadListDto) (*e.Response, error) {
+ var data e.Response
+ var err error
+
+ event := pl.Event{
+ Feature: "ReadList",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "readList")
+
+ err = dg.I.Transaction(func(tx *gorm.DB) error {
+ mwRunner := newMiddlewareRunner(&event, tx)
+ mwRunner.setMwType(pu.MWTPre)
+ // Run pre-middleware
+ if err := mwRunner.RunReadListMiddleware(readListPreMw, &input, &data); err != nil {
+ return err
+ }
+
+ mwRunner.setMwType(pu.MWTPost)
+ // Run post-middleware
+ if err := mwRunner.RunReadListMiddleware(readListPostMw, &input, &data); err != nil {
+ return err
+ }
+
+ return nil
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &data, nil
+}
diff --git a/internal/use-case/bpjs-use-case/monitoring/middleware-runner.go b/internal/use-case/bpjs-use-case/monitoring/middleware-runner.go
new file mode 100644
index 00000000..49bc5efe
--- /dev/null
+++ b/internal/use-case/bpjs-use-case/monitoring/middleware-runner.go
@@ -0,0 +1,42 @@
+package monitoring
+
+import (
+ e "simrs-vx/internal/domain/bpjs-entities/monitoring"
+ pl "simrs-vx/pkg/logger"
+ pu "simrs-vx/pkg/use-case-helper"
+
+ "gorm.io/gorm"
+)
+
+type middlewareRunner struct {
+ Event *pl.Event
+ Tx *gorm.DB
+ MwType pu.MWType
+}
+
+// NewMiddlewareExecutor creates a new middleware executor
+func newMiddlewareRunner(event *pl.Event, tx *gorm.DB) *middlewareRunner {
+ return &middlewareRunner{
+ Event: event,
+ Tx: tx,
+ }
+}
+
+func (me *middlewareRunner) RunReadListMiddleware(middlewares []readListMw, input *e.ReadListDto, data *e.Response) error {
+ for _, middleware := range middlewares {
+ logData := pu.GetLogData(input, data)
+
+ pl.SetLogInfo(me.Event, logData, "started", middleware.Name)
+
+ if err := middleware.Func(input, data, me.Tx); err != nil {
+ return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err)
+ }
+
+ pl.SetLogInfo(me.Event, nil, "complete")
+ }
+ return nil
+}
+
+func (me *middlewareRunner) setMwType(mwType pu.MWType) {
+ me.MwType = mwType
+}
diff --git a/internal/use-case/bpjs-use-case/monitoring/middleware.go b/internal/use-case/bpjs-use-case/monitoring/middleware.go
new file mode 100644
index 00000000..d5e77655
--- /dev/null
+++ b/internal/use-case/bpjs-use-case/monitoring/middleware.go
@@ -0,0 +1,12 @@
+package monitoring
+
+import (
+ pm "simrs-vx/internal/use-case/bpjs-plugin/monitoring"
+)
+
+func init() {
+ readListPreMw = append(readListPreMw,
+ readListMw{Name: "readList-monitoring", Func: pm.ReadList},
+ )
+
+}
diff --git a/internal/use-case/bpjs-use-case/monitoring/tycovar.go b/internal/use-case/bpjs-use-case/monitoring/tycovar.go
new file mode 100644
index 00000000..463109c7
--- /dev/null
+++ b/internal/use-case/bpjs-use-case/monitoring/tycovar.go
@@ -0,0 +1,18 @@
+/*
+member is peserta
+*/
+package monitoring
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/bpjs-entities/monitoring"
+)
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.Response, tx *gorm.DB) error
+}
+
+var readListPreMw []readListMw // ..
+var readListPostMw []readListMw // ..
diff --git a/internal/use-case/bpjs-use-case/reference/case.go b/internal/use-case/bpjs-use-case/reference/case.go
new file mode 100644
index 00000000..bc9bb5d6
--- /dev/null
+++ b/internal/use-case/bpjs-use-case/reference/case.go
@@ -0,0 +1,50 @@
+package reference
+
+import (
+ e "simrs-vx/internal/domain/bpjs-entities/reference"
+
+ dg "github.com/karincake/apem/db-gorm-pg"
+
+ pl "simrs-vx/pkg/logger"
+ pu "simrs-vx/pkg/use-case-helper"
+
+ "gorm.io/gorm"
+)
+
+const source = "reference"
+
+func ReadList(input e.ReadListDto) (*e.Response, error) {
+ var data e.Response
+ var err error
+
+ event := pl.Event{
+ Feature: "ReadList",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "readList")
+
+ err = dg.I.Transaction(func(tx *gorm.DB) error {
+ mwRunner := newMiddlewareRunner(&event, tx)
+ mwRunner.setMwType(pu.MWTPre)
+ // Run pre-middleware
+ if err := mwRunner.RunReadListMiddleware(readListPreMw, &input, &data); err != nil {
+ return err
+ }
+
+ mwRunner.setMwType(pu.MWTPost)
+ // Run post-middleware
+ if err := mwRunner.RunReadListMiddleware(readListPostMw, &input, &data); err != nil {
+ return err
+ }
+
+ return nil
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &data, nil
+}
diff --git a/internal/use-case/bpjs-use-case/reference/middleware-runner.go b/internal/use-case/bpjs-use-case/reference/middleware-runner.go
new file mode 100644
index 00000000..0d13c083
--- /dev/null
+++ b/internal/use-case/bpjs-use-case/reference/middleware-runner.go
@@ -0,0 +1,42 @@
+package reference
+
+import (
+ e "simrs-vx/internal/domain/bpjs-entities/reference"
+ pl "simrs-vx/pkg/logger"
+ pu "simrs-vx/pkg/use-case-helper"
+
+ "gorm.io/gorm"
+)
+
+type middlewareRunner struct {
+ Event *pl.Event
+ Tx *gorm.DB
+ MwType pu.MWType
+}
+
+// NewMiddlewareExecutor creates a new middleware executor
+func newMiddlewareRunner(event *pl.Event, tx *gorm.DB) *middlewareRunner {
+ return &middlewareRunner{
+ Event: event,
+ Tx: tx,
+ }
+}
+
+func (me *middlewareRunner) RunReadListMiddleware(middlewares []readListMw, input *e.ReadListDto, data *e.Response) error {
+ for _, middleware := range middlewares {
+ logData := pu.GetLogData(input, data)
+
+ pl.SetLogInfo(me.Event, logData, "started", middleware.Name)
+
+ if err := middleware.Func(input, data, me.Tx); err != nil {
+ return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err)
+ }
+
+ pl.SetLogInfo(me.Event, nil, "complete")
+ }
+ return nil
+}
+
+func (me *middlewareRunner) setMwType(mwType pu.MWType) {
+ me.MwType = mwType
+}
diff --git a/internal/use-case/bpjs-use-case/reference/middleware.go b/internal/use-case/bpjs-use-case/reference/middleware.go
new file mode 100644
index 00000000..f7680ffd
--- /dev/null
+++ b/internal/use-case/bpjs-use-case/reference/middleware.go
@@ -0,0 +1,12 @@
+package reference
+
+import (
+ pr "simrs-vx/internal/use-case/bpjs-plugin/reference"
+)
+
+func init() {
+ readListPreMw = append(readListPreMw,
+ readListMw{Name: "readList-reference", Func: pr.ReadList},
+ )
+
+}
diff --git a/internal/use-case/bpjs-use-case/reference/tycovar.go b/internal/use-case/bpjs-use-case/reference/tycovar.go
new file mode 100644
index 00000000..51df4160
--- /dev/null
+++ b/internal/use-case/bpjs-use-case/reference/tycovar.go
@@ -0,0 +1,23 @@
+/*
+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 reference
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/bpjs-entities/reference"
+)
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.Response, tx *gorm.DB) error
+}
+
+var readListPreMw []readListMw // ..
+var readListPostMw []readListMw // ..
diff --git a/internal/use-case/bpjs-use-case/vclaim-sep-hist/case.go b/internal/use-case/bpjs-use-case/vclaim-sep-hist/case.go
new file mode 100644
index 00000000..0d2e77d0
--- /dev/null
+++ b/internal/use-case/bpjs-use-case/vclaim-sep-hist/case.go
@@ -0,0 +1,277 @@
+package vclaimsephist
+
+import (
+ "strconv"
+
+ e "simrs-vx/internal/domain/bpjs-entities/vclaim-sep-hist"
+
+ 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 = "vclaim-sep-hist"
+
+func Create(input e.CreateDto) (*d.Data, error) {
+ data := e.VclaimSepHist{}
+
+ event := pl.Event{
+ Feature: "Create",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "create")
+
+ err := dg.I.Transaction(func(tx *gorm.DB) error {
+ mwRunner := newMiddlewareRunner(&event, tx)
+ mwRunner.setMwType(pu.MWTPre)
+ // Run pre-middleware
+ if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil {
+ return err
+ }
+
+ if resData, err := CreateData(input, &event, tx); err != nil {
+ return err
+ } else {
+ data = *resData
+ }
+
+ mwRunner.setMwType(pu.MWTPost)
+ // Run post-middleware
+ if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil {
+ return err
+ }
+
+ pl.SetLogInfo(&event, nil, "complete")
+
+ return nil
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &d.Data{
+ Meta: d.II{
+ "source": source,
+ "structure": "single-data",
+ "status": "created",
+ },
+ Data: data.ToResponse(),
+ }, nil
+}
+
+func ReadList(input e.ReadListDto) (*d.Data, error) {
+ var data *e.VclaimSepHist
+ var dataList []e.VclaimSepHist
+ 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.VclaimSepHist
+ 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.VclaimSepHist
+ 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.VclaimSepHist
+ 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/bpjs-use-case/vclaim-sep-hist/helper.go b/internal/use-case/bpjs-use-case/vclaim-sep-hist/helper.go
new file mode 100644
index 00000000..038983bb
--- /dev/null
+++ b/internal/use-case/bpjs-use-case/vclaim-sep-hist/helper.go
@@ -0,0 +1,23 @@
+/*
+DESCRIPTION:
+Any functions that are used internally by the use-case
+*/
+package vclaimsephist
+
+import (
+ e "simrs-vx/internal/domain/bpjs-entities/vclaim-sep-hist"
+)
+
+func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.VclaimSepHist) {
+ var inputSrc *e.CreateDto
+ if inputT, ok := any(input).(*e.CreateDto); ok {
+ inputSrc = inputT
+ } else {
+ inputTemp := any(input).(*e.UpdateDto)
+ inputSrc = &inputTemp.CreateDto
+ }
+
+ data.RequestPayload = &inputSrc.RequestPayload
+ data.ResponseBody = &inputSrc.ResponseBody
+ data.Message = &inputSrc.Message
+}
diff --git a/internal/use-case/bpjs-use-case/vclaim-sep-hist/lib.go b/internal/use-case/bpjs-use-case/vclaim-sep-hist/lib.go
new file mode 100644
index 00000000..13104e36
--- /dev/null
+++ b/internal/use-case/bpjs-use-case/vclaim-sep-hist/lib.go
@@ -0,0 +1,140 @@
+package vclaimsephist
+
+import (
+ e "simrs-vx/internal/domain/bpjs-entities/vclaim-sep-hist"
+
+ 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.VclaimSepHist, error) {
+ pl.SetLogInfo(event, nil, "started", "DBCreate")
+
+ data := e.VclaimSepHist{}
+ 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.VclaimSepHist, *e.MetaDto, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadList")
+ data := []e.VclaimSepHist{}
+ 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.VclaimSepHist{}).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
+ Count(&count).
+ Scopes(gh.Paginate(input, &pagination)).
+ Scopes(gh.Sort(input.Sort))
+
+ if err := tx.Find(&data).Error; err != nil {
+ if err == gorm.ErrRecordNotFound {
+ return nil, &meta, nil
+ }
+ return nil, nil, plh.HandleListError(input, event, err)
+ }
+
+ meta.Count = int(count)
+ meta.PageNumber = pagination.PageNumber
+ meta.PageSize = pagination.PageSize
+
+ pl.SetLogInfo(event, nil, "complete")
+ return data, &meta, nil
+}
+
+func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.VclaimSepHist, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadDetail")
+ data := e.VclaimSepHist{}
+
+ 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.VclaimSepHist, 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.VclaimSepHist, 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/bpjs-use-case/vclaim-sep-hist/middleware-runner.go b/internal/use-case/bpjs-use-case/vclaim-sep-hist/middleware-runner.go
new file mode 100644
index 00000000..315a358e
--- /dev/null
+++ b/internal/use-case/bpjs-use-case/vclaim-sep-hist/middleware-runner.go
@@ -0,0 +1,103 @@
+package vclaimsephist
+
+import (
+ e "simrs-vx/internal/domain/bpjs-entities/vclaim-sep-hist"
+ 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.VclaimSepHist) 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.VclaimSepHist) 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.VclaimSepHist) 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.VclaimSepHist) 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.VclaimSepHist) error {
+ for _, middleware := range middlewares {
+ logData := pu.GetLogData(input, data)
+
+ pl.SetLogInfo(me.Event, logData, "started", middleware.Name)
+
+ if err := middleware.Func(input, data, me.Tx); err != nil {
+ return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err)
+ }
+
+ pl.SetLogInfo(me.Event, nil, "complete")
+ }
+ return nil
+}
+
+func (me *middlewareRunner) setMwType(mwType pu.MWType) {
+ me.MwType = mwType
+}
diff --git a/internal/use-case/bpjs-use-case/vclaim-sep-hist/middleware.go b/internal/use-case/bpjs-use-case/vclaim-sep-hist/middleware.go
new file mode 100644
index 00000000..16cf95b9
--- /dev/null
+++ b/internal/use-case/bpjs-use-case/vclaim-sep-hist/middleware.go
@@ -0,0 +1,9 @@
+package vclaimsephist
+
+// 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/bpjs-use-case/vclaim-sep-hist/tycovar.go b/internal/use-case/bpjs-use-case/vclaim-sep-hist/tycovar.go
new file mode 100644
index 00000000..f525303a
--- /dev/null
+++ b/internal/use-case/bpjs-use-case/vclaim-sep-hist/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 vclaimsephist
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/bpjs-entities/vclaim-sep-hist"
+)
+
+type createMw struct {
+ Name string
+ Func func(input *e.CreateDto, data *e.VclaimSepHist, tx *gorm.DB) error
+}
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.VclaimSepHist, tx *gorm.DB) error
+}
+
+type readDetailMw struct {
+ Name string
+ Func func(input *e.ReadDetailDto, data *e.VclaimSepHist, 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/bpjs-use-case/vclaim-sep-print/case.go b/internal/use-case/bpjs-use-case/vclaim-sep-print/case.go
new file mode 100644
index 00000000..e1f26e10
--- /dev/null
+++ b/internal/use-case/bpjs-use-case/vclaim-sep-print/case.go
@@ -0,0 +1,277 @@
+package vclaimsepprint
+
+import (
+ "strconv"
+
+ e "simrs-vx/internal/domain/bpjs-entities/vclaim-sep-print"
+
+ 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 = "vclaim-sep-print"
+
+func Create(input e.CreateDto) (*d.Data, error) {
+ data := e.VclaimSepPrint{}
+
+ event := pl.Event{
+ Feature: "Create",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "create")
+
+ err := dg.I.Transaction(func(tx *gorm.DB) error {
+ mwRunner := newMiddlewareRunner(&event, tx)
+ mwRunner.setMwType(pu.MWTPre)
+ // Run pre-middleware
+ if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil {
+ return err
+ }
+
+ if resData, err := CreateData(input, &event, tx); err != nil {
+ return err
+ } else {
+ data = *resData
+ }
+
+ mwRunner.setMwType(pu.MWTPost)
+ // Run post-middleware
+ if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil {
+ return err
+ }
+
+ pl.SetLogInfo(&event, nil, "complete")
+
+ return nil
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &d.Data{
+ Meta: d.II{
+ "source": source,
+ "structure": "single-data",
+ "status": "created",
+ },
+ Data: data.ToResponse(),
+ }, nil
+}
+
+func ReadList(input e.ReadListDto) (*d.Data, error) {
+ var data *e.VclaimSepPrint
+ var dataList []e.VclaimSepPrint
+ 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.VclaimSepPrint
+ 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.VclaimSepPrint
+ 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.VclaimSepPrint
+ 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/bpjs-use-case/vclaim-sep-print/helper.go b/internal/use-case/bpjs-use-case/vclaim-sep-print/helper.go
new file mode 100644
index 00000000..5a89f7a9
--- /dev/null
+++ b/internal/use-case/bpjs-use-case/vclaim-sep-print/helper.go
@@ -0,0 +1,21 @@
+/*
+DESCRIPTION:
+Any functions that are used internally by the use-case
+*/
+package vclaimsepprint
+
+import (
+ e "simrs-vx/internal/domain/bpjs-entities/vclaim-sep-print"
+)
+
+func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.VclaimSepPrint) {
+ var inputSrc *e.CreateDto
+ if inputT, ok := any(input).(*e.CreateDto); ok {
+ inputSrc = inputT
+ } else {
+ inputTemp := any(input).(*e.UpdateDto)
+ inputSrc = &inputTemp.CreateDto
+ }
+
+ data.VclaimSep_Number = inputSrc.VclaimSep_Number
+}
diff --git a/internal/use-case/bpjs-use-case/vclaim-sep-print/lib.go b/internal/use-case/bpjs-use-case/vclaim-sep-print/lib.go
new file mode 100644
index 00000000..12bdad69
--- /dev/null
+++ b/internal/use-case/bpjs-use-case/vclaim-sep-print/lib.go
@@ -0,0 +1,148 @@
+package vclaimsepprint
+
+import (
+ e "simrs-vx/internal/domain/bpjs-entities/vclaim-sep-print"
+
+ 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.VclaimSepPrint, error) {
+ pl.SetLogInfo(event, nil, "started", "DBCreate")
+
+ data := e.VclaimSepPrint{}
+ var maxCounter uint
+
+ var tx *gorm.DB
+ if len(dbx) > 0 {
+ tx = dbx[0]
+ } else {
+ tx = dg.I
+ }
+
+ err := tx.Model(&data).
+ Where("VclaimSep_Number = ?", input.VclaimSep_Number).
+ Select("COALESCE(MAX(Counter), 0)").
+ Scan(&maxCounter).Error
+ if err != nil {
+ return nil, err
+ }
+
+ 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.VclaimSepPrint, *e.MetaDto, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadList")
+ data := []e.VclaimSepPrint{}
+ 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.VclaimSepPrint{}).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
+ Count(&count).
+ Scopes(gh.Paginate(input, &pagination)).
+ Scopes(gh.Sort(input.Sort))
+
+ if err := tx.Find(&data).Error; err != nil {
+ if err == gorm.ErrRecordNotFound {
+ return nil, &meta, nil
+ }
+ return nil, nil, plh.HandleListError(input, event, err)
+ }
+
+ meta.Count = int(count)
+ meta.PageNumber = pagination.PageNumber
+ meta.PageSize = pagination.PageSize
+
+ pl.SetLogInfo(event, nil, "complete")
+ return data, &meta, nil
+}
+
+func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.VclaimSepPrint, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadDetail")
+ data := e.VclaimSepPrint{}
+
+ 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.VclaimSepPrint, 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.VclaimSepPrint, 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/bpjs-use-case/vclaim-sep-print/middleware-runner.go b/internal/use-case/bpjs-use-case/vclaim-sep-print/middleware-runner.go
new file mode 100644
index 00000000..47db3773
--- /dev/null
+++ b/internal/use-case/bpjs-use-case/vclaim-sep-print/middleware-runner.go
@@ -0,0 +1,103 @@
+package vclaimsepprint
+
+import (
+ e "simrs-vx/internal/domain/bpjs-entities/vclaim-sep-print"
+ 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.VclaimSepPrint) 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.VclaimSepPrint) 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.VclaimSepPrint) 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.VclaimSepPrint) 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.VclaimSepPrint) error {
+ for _, middleware := range middlewares {
+ logData := pu.GetLogData(input, data)
+
+ pl.SetLogInfo(me.Event, logData, "started", middleware.Name)
+
+ if err := middleware.Func(input, data, me.Tx); err != nil {
+ return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err)
+ }
+
+ pl.SetLogInfo(me.Event, nil, "complete")
+ }
+ return nil
+}
+
+func (me *middlewareRunner) setMwType(mwType pu.MWType) {
+ me.MwType = mwType
+}
diff --git a/internal/use-case/bpjs-use-case/vclaim-sep-print/middleware.go b/internal/use-case/bpjs-use-case/vclaim-sep-print/middleware.go
new file mode 100644
index 00000000..ae857af4
--- /dev/null
+++ b/internal/use-case/bpjs-use-case/vclaim-sep-print/middleware.go
@@ -0,0 +1,9 @@
+package vclaimsepprint
+
+// 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/bpjs-use-case/vclaim-sep-print/tycovar.go b/internal/use-case/bpjs-use-case/vclaim-sep-print/tycovar.go
new file mode 100644
index 00000000..9566a7e0
--- /dev/null
+++ b/internal/use-case/bpjs-use-case/vclaim-sep-print/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 vclaimsepprint
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/bpjs-entities/vclaim-sep-print"
+)
+
+type createMw struct {
+ Name string
+ Func func(input *e.CreateDto, data *e.VclaimSepPrint, tx *gorm.DB) error
+}
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.VclaimSepPrint, tx *gorm.DB) error
+}
+
+type readDetailMw struct {
+ Name string
+ Func func(input *e.ReadDetailDto, data *e.VclaimSepPrint, 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/bpjs-use-case/vclaim-sep/case.go b/internal/use-case/bpjs-use-case/vclaim-sep/case.go
new file mode 100644
index 00000000..ac72d648
--- /dev/null
+++ b/internal/use-case/bpjs-use-case/vclaim-sep/case.go
@@ -0,0 +1,288 @@
+package vclaimsep
+
+import (
+ "strconv"
+
+ e "simrs-vx/internal/domain/bpjs-entities/vclaim-sep"
+ // evsh "simrs-vx/internal/domain/bpjs-entities/vclaim-sep-hist"
+
+ uvsh "simrs-vx/internal/use-case/bpjs-use-case/vclaim-sep-hist"
+
+ 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 = "vclaim-sep"
+
+func Create(input e.CreateDto) (*d.Data, error) {
+ data := e.VclaimSep{}
+
+ 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 := uvsh.CreateData(input.VclaimSepHist, &event, tx); err != nil {
+ return err
+ }
+
+ if !input.IsMessageSuccess() {
+ return nil
+ }
+
+ if resData, err := CreateData(input, &event, tx); err != nil {
+ return err
+ } else {
+ data = *resData
+ }
+
+ mwRunner.setMwType(pu.MWTPost)
+ // Run post-middleware
+ if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil {
+ return err
+ }
+
+ pl.SetLogInfo(&event, nil, "complete")
+
+ return nil
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &d.Data{
+ Meta: d.II{
+ "source": source,
+ "structure": "single-data",
+ "status": "created",
+ },
+ Data: data.ToResponse(),
+ }, nil
+}
+
+func ReadList(input e.ReadListDto) (*d.Data, error) {
+ var data *e.VclaimSep
+ var dataList []e.VclaimSep
+ 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.VclaimSep
+ 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{Number: input.Number}
+ var data *e.VclaimSep
+ 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{Number: input.Number}
+ var data *e.VclaimSep
+ 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/bpjs-use-case/vclaim-sep/helper.go b/internal/use-case/bpjs-use-case/vclaim-sep/helper.go
new file mode 100644
index 00000000..7760d854
--- /dev/null
+++ b/internal/use-case/bpjs-use-case/vclaim-sep/helper.go
@@ -0,0 +1,22 @@
+/*
+DESCRIPTION:
+Any functions that are used internally by the use-case
+*/
+package vclaimsep
+
+import (
+ e "simrs-vx/internal/domain/bpjs-entities/vclaim-sep"
+)
+
+func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.VclaimSep) {
+ 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.Number = inputSrc.Number
+}
diff --git a/internal/use-case/bpjs-use-case/vclaim-sep/lib.go b/internal/use-case/bpjs-use-case/vclaim-sep/lib.go
new file mode 100644
index 00000000..817c357c
--- /dev/null
+++ b/internal/use-case/bpjs-use-case/vclaim-sep/lib.go
@@ -0,0 +1,147 @@
+package vclaimsep
+
+import (
+ e "simrs-vx/internal/domain/bpjs-entities/vclaim-sep"
+
+ 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.VclaimSep, error) {
+ pl.SetLogInfo(event, nil, "started", "DBCreate")
+
+ data := e.VclaimSep{}
+ 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.VclaimSep, *e.MetaDto, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadList")
+ data := []e.VclaimSep{}
+ 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.VclaimSep{}).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
+ Count(&count).
+ Scopes(gh.Paginate(input, &pagination)).
+ Scopes(gh.Sort(input.Sort))
+
+ if err := tx.Find(&data).Error; err != nil {
+ if err == gorm.ErrRecordNotFound {
+ return nil, &meta, nil
+ }
+ return nil, nil, plh.HandleListError(input, event, err)
+ }
+
+ meta.Count = int(count)
+ meta.PageNumber = pagination.PageNumber
+ meta.PageSize = pagination.PageSize
+
+ pl.SetLogInfo(event, nil, "complete")
+ return data, &meta, nil
+}
+
+func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.VclaimSep, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadDetail")
+ data := e.VclaimSep{}
+
+ var tx *gorm.DB
+ if len(dbx) > 0 {
+ tx = dbx[0]
+ } else {
+ tx = dg.I
+ }
+
+ if input.Number != nil {
+ tx = tx.Where("\"Number\" = ?", *input.Number)
+ }
+ if input.Id != 0 {
+ tx = tx.Where("\"Id\" = ?", input.Id)
+ }
+
+ if err := tx.First(&data).Error; err != nil {
+ if processedErr := pu.HandleReadError(err, event, source, input.Id, data); processedErr != nil {
+ return nil, processedErr
+ }
+ }
+
+ pl.SetLogInfo(event, nil, "complete")
+ return &data, nil
+}
+
+func UpdateData(input e.UpdateDto, data *e.VclaimSep, 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.VclaimSep, 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/bpjs-use-case/vclaim-sep/middleware-runner.go b/internal/use-case/bpjs-use-case/vclaim-sep/middleware-runner.go
new file mode 100644
index 00000000..dee35276
--- /dev/null
+++ b/internal/use-case/bpjs-use-case/vclaim-sep/middleware-runner.go
@@ -0,0 +1,103 @@
+package vclaimsep
+
+import (
+ e "simrs-vx/internal/domain/bpjs-entities/vclaim-sep"
+ 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.VclaimSep) 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.VclaimSep) 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.VclaimSep) 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.VclaimSep) 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.VclaimSep) error {
+ for _, middleware := range middlewares {
+ logData := pu.GetLogData(input, data)
+
+ pl.SetLogInfo(me.Event, logData, "started", middleware.Name)
+
+ if err := middleware.Func(input, data, me.Tx); err != nil {
+ return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err)
+ }
+
+ pl.SetLogInfo(me.Event, nil, "complete")
+ }
+ return nil
+}
+
+func (me *middlewareRunner) setMwType(mwType pu.MWType) {
+ me.MwType = mwType
+}
diff --git a/internal/use-case/bpjs-use-case/vclaim-sep/middleware.go b/internal/use-case/bpjs-use-case/vclaim-sep/middleware.go
new file mode 100644
index 00000000..1ad0a853
--- /dev/null
+++ b/internal/use-case/bpjs-use-case/vclaim-sep/middleware.go
@@ -0,0 +1,13 @@
+package vclaimsep
+
+import (
+ pvs "simrs-vx/internal/use-case/bpjs-plugin/vclaim-sep"
+)
+
+// example of middleware
+func init() {
+ createPreMw = append(createPreMw,
+ createMw{Name: "create-sep", Func: pvs.CreateSep},
+ )
+
+}
diff --git a/internal/use-case/bpjs-use-case/vclaim-sep/tycovar.go b/internal/use-case/bpjs-use-case/vclaim-sep/tycovar.go
new file mode 100644
index 00000000..932bc355
--- /dev/null
+++ b/internal/use-case/bpjs-use-case/vclaim-sep/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 vclaimsep
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/bpjs-entities/vclaim-sep"
+)
+
+type createMw struct {
+ Name string
+ Func func(input *e.CreateDto, data *e.VclaimSep, tx *gorm.DB) error
+}
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.VclaimSep, tx *gorm.DB) error
+}
+
+type readDetailMw struct {
+ Name string
+ Func func(input *e.ReadDetailDto, data *e.VclaimSep, 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/adime/case.go b/internal/use-case/main-use-case/adime/case.go
new file mode 100644
index 00000000..01d101ae
--- /dev/null
+++ b/internal/use-case/main-use-case/adime/case.go
@@ -0,0 +1,296 @@
+package adime
+
+import (
+ "errors"
+ "strconv"
+
+ e "simrs-vx/internal/domain/main-entities/adime"
+ ee "simrs-vx/internal/domain/main-entities/employee"
+
+ ue "simrs-vx/internal/use-case/main-use-case/employee"
+
+ 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 = "adime"
+
+func Create(input e.CreateDto) (*d.Data, error) {
+ data := e.Adime{}
+
+ event := pl.Event{
+ Feature: "Create",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "create")
+
+ err := dg.I.Transaction(func(tx *gorm.DB) error {
+ mwRunner := newMiddlewareRunner(&event, tx)
+ mwRunner.setMwType(pu.MWTPre)
+ // Run pre-middleware
+ if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil {
+ return err
+ }
+
+ if !input.AuthInfo.IsDoctor() && !input.AuthInfo.IsNurse() {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "auth-forbidden",
+ Detail: "user position is not allowed",
+ Raw: errors.New("authentication failed"),
+ }
+ return pl.SetLogError(&event, input)
+ }
+
+ employee, err := ue.ReadDetailData(ee.ReadDetailDto{User_Id: &input.AuthInfo.User_Id}, &event, tx)
+ if err != nil {
+ return err
+ }
+ input.Employee_Id = &employee.Id
+ 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.Adime
+ var dataList []e.Adime
+ 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.Adime
+ 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.Adime
+ 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.Adime
+ 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/adime/helper.go b/internal/use-case/main-use-case/adime/helper.go
new file mode 100644
index 00000000..ab6a16c9
--- /dev/null
+++ b/internal/use-case/main-use-case/adime/helper.go
@@ -0,0 +1,24 @@
+/*
+DESCRIPTION:
+Any functions that are used internally by the use-case
+*/
+package adime
+
+import (
+ e "simrs-vx/internal/domain/main-entities/adime"
+)
+
+func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Adime) {
+ 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.Employee_Id = inputSrc.Employee_Id
+ data.Time = inputSrc.Time
+ data.Value = inputSrc.Value
+}
diff --git a/internal/use-case/main-use-case/adime/lib.go b/internal/use-case/main-use-case/adime/lib.go
new file mode 100644
index 00000000..f198829d
--- /dev/null
+++ b/internal/use-case/main-use-case/adime/lib.go
@@ -0,0 +1,140 @@
+package adime
+
+import (
+ e "simrs-vx/internal/domain/main-entities/adime"
+
+ 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.Adime, error) {
+ pl.SetLogInfo(event, nil, "started", "DBCreate")
+
+ data := e.Adime{}
+ 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.Adime, *e.MetaDto, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadList")
+ data := []e.Adime{}
+ 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.Adime{}).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
+ Count(&count).
+ Scopes(gh.Paginate(input, &pagination)).
+ Order("\"CreatedAt\" DESC")
+
+ if err := tx.Find(&data).Error; err != nil {
+ if err == gorm.ErrRecordNotFound {
+ return nil, &meta, nil
+ }
+ return nil, nil, plh.HandleListError(input, event, err)
+ }
+
+ meta.Count = int(count)
+ meta.PageNumber = pagination.PageNumber
+ meta.PageSize = pagination.PageSize
+
+ pl.SetLogInfo(event, nil, "complete")
+ return data, &meta, nil
+}
+
+func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.Adime, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadDetail")
+ data := e.Adime{}
+
+ 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.Adime, 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.Adime, 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/adime/middleware-runner.go b/internal/use-case/main-use-case/adime/middleware-runner.go
new file mode 100644
index 00000000..5081ea55
--- /dev/null
+++ b/internal/use-case/main-use-case/adime/middleware-runner.go
@@ -0,0 +1,103 @@
+package adime
+
+import (
+ e "simrs-vx/internal/domain/main-entities/adime"
+ 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.Adime) 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.Adime) 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.Adime) 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.Adime) 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.Adime) 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/adime/middleware.go b/internal/use-case/main-use-case/adime/middleware.go
new file mode 100644
index 00000000..eb7de7a4
--- /dev/null
+++ b/internal/use-case/main-use-case/adime/middleware.go
@@ -0,0 +1,9 @@
+package adime
+
+// 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/adime/tycovar.go b/internal/use-case/main-use-case/adime/tycovar.go
new file mode 100644
index 00000000..bb12cce1
--- /dev/null
+++ b/internal/use-case/main-use-case/adime/tycovar.go
@@ -0,0 +1,36 @@
+package adime
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/main-entities/adime"
+)
+
+type createMw struct {
+ Name string
+ Func func(input *e.CreateDto, data *e.Adime, tx *gorm.DB) error
+}
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.Adime, tx *gorm.DB) error
+}
+
+type readDetailMw struct {
+ Name string
+ Func func(input *e.ReadDetailDto, data *e.Adime, 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/ambulatory/case.go b/internal/use-case/main-use-case/ambulatory/case.go
new file mode 100644
index 00000000..7a2bef47
--- /dev/null
+++ b/internal/use-case/main-use-case/ambulatory/case.go
@@ -0,0 +1,276 @@
+package ambulatory
+
+import (
+ e "simrs-vx/internal/domain/main-entities/ambulatory"
+ "strconv"
+
+ dg "github.com/karincake/apem/db-gorm-pg"
+ d "github.com/karincake/dodol"
+
+ pl "simrs-vx/pkg/logger"
+ pu "simrs-vx/pkg/use-case-helper"
+
+ "gorm.io/gorm"
+)
+
+const source = "ambulatory"
+
+func Create(input e.CreateDto) (*d.Data, error) {
+ data := e.Ambulatory{}
+
+ event := pl.Event{
+ Feature: "Create",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "create")
+
+ err := dg.I.Transaction(func(tx *gorm.DB) error {
+ mwRunner := newMiddlewareRunner(&event, tx)
+ mwRunner.setMwType(pu.MWTPre)
+ // Run pre-middleware
+ if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil {
+ return err
+ }
+
+ if resData, err := CreateData(input, &event, tx); err != nil {
+ return err
+ } else {
+ data = *resData
+ }
+
+ mwRunner.setMwType(pu.MWTPost)
+ // Run post-middleware
+ if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil {
+ return err
+ }
+
+ pl.SetLogInfo(&event, nil, "complete")
+
+ return nil
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &d.Data{
+ Meta: d.II{
+ "source": source,
+ "structure": "single-data",
+ "status": "created",
+ },
+ Data: data.ToResponse(),
+ }, nil
+}
+
+func ReadList(input e.ReadListDto) (*d.Data, error) {
+ var data *e.Ambulatory
+ var dataList []e.Ambulatory
+ 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.Ambulatory
+ 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: uint16(input.Id)}
+ var data *e.Ambulatory
+ 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: uint16(input.Id)}
+ var data *e.Ambulatory
+ 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/ambulatory/helper.go b/internal/use-case/main-use-case/ambulatory/helper.go
new file mode 100644
index 00000000..f78f0b65
--- /dev/null
+++ b/internal/use-case/main-use-case/ambulatory/helper.go
@@ -0,0 +1,38 @@
+/*
+DESCRIPTION:
+Any functions that are used internally by the use-case
+*/
+package ambulatory
+
+import (
+ "errors"
+ e "simrs-vx/internal/domain/main-entities/ambulatory"
+
+ ere "simrs-vx/internal/domain/references/encounter"
+)
+
+func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Ambulatory) {
+ 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.Class_Code = inputSrc.Class_Code
+}
+
+func CheckClassCode(input *string) (ere.AmbulatoryClassCode, error) {
+ if input != nil {
+ subCode := ere.AmbulatoryClassCode(*input)
+ switch subCode {
+ case ere.ACCReg, ere.ACCRme, ere.ACCCad, ere.ACCCac:
+ return subCode, nil
+ default:
+ return "", errors.New("unknown sub class code")
+ }
+ }
+ return "", errors.New("sub class code is nil")
+}
diff --git a/internal/use-case/main-use-case/ambulatory/lib.go b/internal/use-case/main-use-case/ambulatory/lib.go
new file mode 100644
index 00000000..6b89b0c7
--- /dev/null
+++ b/internal/use-case/main-use-case/ambulatory/lib.go
@@ -0,0 +1,140 @@
+package ambulatory
+
+import (
+ e "simrs-vx/internal/domain/main-entities/ambulatory"
+
+ 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.Ambulatory, error) {
+ pl.SetLogInfo(event, nil, "started", "DBCreate")
+
+ data := e.Ambulatory{}
+ 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.Ambulatory, *e.MetaDto, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadList")
+ data := []e.Ambulatory{}
+ 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.Ambulatory{}).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
+ Count(&count).
+ Scopes(gh.Paginate(input, &pagination)).
+ Order("\"CreatedAt\" DESC")
+
+ if err := tx.Find(&data).Error; err != nil {
+ if err == gorm.ErrRecordNotFound {
+ return nil, &meta, nil
+ }
+ return nil, nil, plh.HandleListError(input, event, err)
+ }
+
+ meta.Count = int(count)
+ meta.PageNumber = pagination.PageNumber
+ meta.PageSize = pagination.PageSize
+
+ pl.SetLogInfo(event, nil, "complete")
+ return data, &meta, nil
+}
+
+func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.Ambulatory, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadDetail")
+ data := e.Ambulatory{}
+
+ 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.Ambulatory, 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.Ambulatory, 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/ambulatory/middleware-runner.go b/internal/use-case/main-use-case/ambulatory/middleware-runner.go
new file mode 100644
index 00000000..292e6602
--- /dev/null
+++ b/internal/use-case/main-use-case/ambulatory/middleware-runner.go
@@ -0,0 +1,103 @@
+package ambulatory
+
+import (
+ e "simrs-vx/internal/domain/main-entities/ambulatory"
+ 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.Ambulatory) 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.Ambulatory) 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.Ambulatory) 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.Ambulatory) 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.Ambulatory) 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/ambulatory/middleware.go b/internal/use-case/main-use-case/ambulatory/middleware.go
new file mode 100644
index 00000000..4bb381e4
--- /dev/null
+++ b/internal/use-case/main-use-case/ambulatory/middleware.go
@@ -0,0 +1,9 @@
+package ambulatory
+
+// 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/ambulatory/tycovar.go b/internal/use-case/main-use-case/ambulatory/tycovar.go
new file mode 100644
index 00000000..81239c8d
--- /dev/null
+++ b/internal/use-case/main-use-case/ambulatory/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 ambulatory
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/main-entities/ambulatory"
+)
+
+type createMw struct {
+ Name string
+ Func func(input *e.CreateDto, data *e.Ambulatory, tx *gorm.DB) error
+}
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.Ambulatory, tx *gorm.DB) error
+}
+
+type readDetailMw struct {
+ Name string
+ Func func(input *e.ReadDetailDto, data *e.Ambulatory, 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/authentication/case.go b/internal/use-case/main-use-case/authentication/case.go
index 70925827..b6e9f2f4 100644
--- a/internal/use-case/main-use-case/authentication/case.go
+++ b/internal/use-case/main-use-case/authentication/case.go
@@ -9,18 +9,19 @@ import (
"github.com/golang-jwt/jwt"
"github.com/google/uuid"
- dg "github.com/karincake/apem/db-gorm-pg"
- d "github.com/karincake/dodol"
- l "github.com/karincake/lepet"
- a "github.com/karincake/apem"
- ms "github.com/karincake/apem/ms-redis"
+ eu "simrs-vx/internal/domain/main-entities/user"
+ erc "simrs-vx/internal/domain/references/common"
+ pa "simrs-vx/pkg/auth-helper"
el "simrs-vx/pkg/logger"
p "simrs-vx/pkg/password"
- mu "simrs-vx/internal/domain/main-entities/user"
- erc "simrs-vx/internal/domain/references/common"
+ a "github.com/karincake/apem"
+ dg "github.com/karincake/apem/db-gorm-pg"
+ ms "github.com/karincake/apem/ms-redis"
+ d "github.com/karincake/dodol"
+ l "github.com/karincake/lepet"
)
var authCfg AuthCfg
@@ -31,13 +32,13 @@ func init() {
// Generates token and store in redis at one place
// just return the error code
-func GenToken(input mu.LoginDto) (*d.Data, error) {
+func GenToken(input eu.LoginDto) (*d.Data, error) {
// Get User
- user := &mu.User{Name: input.Name}
+ user := &eu.User{Name: input.Name}
// if input.Position_Code != "" {
// user.Position_Code = input.Position_Code
// }
- if errCode := GetAndCheck(user, user); errCode != "" {
+ if errCode := getAndCheck(user, user); errCode != "" {
return nil, d.FieldErrors{"authentication": d.FieldError{Code: errCode, Message: el.GenMessage(errCode)}}
}
@@ -71,6 +72,11 @@ func GenToken(input mu.LoginDto) (*d.Data, error) {
return nil, d.FieldErrors{"authentication": d.FieldError{Code: "auth-login-unverified", Message: el.GenMessage("auth-login-unverified")}}
}
+ userDivisionPositions, err := getDivisionPosition(user.Id)
+ if err != nil {
+ return nil, d.FieldErrors{"authentication": d.FieldError{Code: "auth-getData-failed", Message: el.GenMessage("auth-getData-failed")}}
+ }
+
// Access token prep
id, err := uuid.NewRandom()
if err != nil {
@@ -84,20 +90,14 @@ func GenToken(input mu.LoginDto) (*d.Data, error) {
atExpires := time.Now().Add(duration).Unix()
atSecretKey := authCfg.AtSecretKey
- // extra
- // if input.Position_Code == "doc" {
-
- // }
-
// Creating Access Token
atClaims := jwt.MapClaims{}
atClaims["user_id"] = user.Id
atClaims["user_name"] = user.Name
- // atClaims["user_email"] = user.Email
- // atClaims["user_position_code"] = user.Position_Code
- // atClaims["user_ref_id"] = user.Ref_Id
+ atClaims["user_position_code"] = user.Position_Code
atClaims["exp"] = atExpires
atClaims["uuid"] = aUuid
+ atClaims["user_division_positions"] = userDivisionPositions
at := jwt.NewWithClaims(jwt.SigningMethodHS256, atClaims)
ats, err := at.SignedString([]byte(atSecretKey))
if err != nil {
@@ -126,12 +126,11 @@ func GenToken(input mu.LoginDto) (*d.Data, error) {
"status": "verified",
},
Data: d.II{
- "user_id": strconv.Itoa(int(user.Id)),
- "user_name": user.Name,
- // "user_email": user.Email,
- // "user_position_code": user.Position_Code,
- // "user_ref_id": user.Ref_Id,
- "accessToken": ats,
+ "user_id": strconv.Itoa(int(user.Id)),
+ "user_name": user.Name,
+ "user_position_code": user.Position_Code,
+ "accessToken": ats,
+ "user_division_positions": userDivisionPositions,
},
}, nil
}
@@ -167,7 +166,7 @@ func VerifyToken(r *http.Request, tokenType TokenType) (data *jwt.Token, errCode
return token, "", ""
}
-func ExtractToken(r *http.Request, tokenType TokenType) (data *AuthInfo, err error) {
+func ExtractToken(r *http.Request, tokenType TokenType) (data *pa.AuthInfo, err error) {
token, errCode, errDetail := VerifyToken(r, tokenType)
if errCode != "" {
return nil, d.FieldError{Code: errCode, Message: el.GenMessage(errCode, errDetail)}
@@ -187,26 +186,41 @@ func ExtractToken(r *http.Request, tokenType TokenType) (data *AuthInfo, err err
return nil, d.FieldError{Code: "token-unidentified", Message: el.GenMessage("token-unidentified")}
}
user_name := fmt.Sprintf("%v", claims["user_name"])
- // user_email := ""
- // if v, exist := claims["user_email"]; exist && v != nil {
- // user_email = v.(string)
- // }
- // ref_id := 0
- // if v, exist := claims["user_ref_id"]; exist && v != nil {
- // tmp := v.(float64)
- // ref_id = int(tmp)
- // }
- // position_code := ""
- // if v, exist := claims["user_position_code"]; exist && v != nil {
- // position_code = v.(string)
- // }
- data = &AuthInfo{
- Uuid: accessUuid,
- User_Id: int(user_id),
- User_Name: user_name,
- // User_Email: user_email,
- // User_Ref_Id: ref_id,
- // User_Position_Code: position_code,
+
+ var userDivisionPositions []pa.DivisionPosition
+ raw := claims["user_division_positions"]
+ if raw == nil {
+ fmt.Println("No user_division_positions found in claims")
+ } else {
+ list, ok := raw.([]interface{})
+ if !ok {
+ fmt.Printf("user_division_positions is not []interface{}, but %T\n", raw)
+ } else {
+ fmt.Printf("Found %d division positions\n", len(list))
+ for i, item := range list {
+ if m, ok := item.(map[string]interface{}); ok {
+ fmt.Printf("Item %d: %v\n", i, m)
+ dp := pa.DivisionPosition{
+ Division_Code: fmt.Sprintf("%v", m["division_code"]),
+ DivisionPosition_Code: fmt.Sprintf("%v", m["divisionPosition_code"]),
+ }
+ userDivisionPositions = append(userDivisionPositions, dp)
+ } else {
+ fmt.Printf("Item %d not map[string]interface{} but %T\n", i, item)
+ }
+ }
+ }
+ }
+ position_code := ""
+ if v, exist := claims["user_position_code"]; exist && v != nil {
+ position_code = v.(string)
+ }
+ data = &pa.AuthInfo{
+ Uuid: accessUuid,
+ User_Id: uint(user_id),
+ User_Name: user_name,
+ User_Position_Code: position_code,
+ User_DivisionPositions: userDivisionPositions,
}
return
}
diff --git a/internal/use-case/main-use-case/authentication/helper.go b/internal/use-case/main-use-case/authentication/helper.go
index de618b5c..50b0c8fd 100644
--- a/internal/use-case/main-use-case/authentication/helper.go
+++ b/internal/use-case/main-use-case/authentication/helper.go
@@ -1,11 +1,18 @@
package authentication
import (
+ "errors"
+ edp "simrs-vx/internal/domain/main-entities/division-position"
+ ee "simrs-vx/internal/domain/main-entities/employee"
+
+ pa "simrs-vx/pkg/auth-helper"
+
dg "github.com/karincake/apem/db-gorm-pg"
+ "gorm.io/gorm"
)
// just return the error code
-func GetAndCheck(input, condition any) (eCode string) {
+func getAndCheck(input, condition any) (eCode string) {
result := dg.I.Where(condition).Find(&input)
if result.Error != nil {
return "fetch-fail"
@@ -16,6 +23,44 @@ func GetAndCheck(input, condition any) (eCode string) {
return ""
}
-func GetDocName(id uint) string {
+func getDocName(id uint) string {
return "authentication"
}
+
+func getDivisionPosition(user_id uint) ([]pa.DivisionPosition, error) {
+ var result []pa.DivisionPosition
+
+ var employee ee.Employee
+ if err := dg.I.Where("\"User_Id\" = ?", user_id).First(&employee).Error; err != nil {
+ if err == gorm.ErrRecordNotFound {
+ return result, nil
+ }
+ return result, errors.New("no employee found")
+ }
+
+ 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
+ }
+
+ for _, dp := range divisionPositions {
+ result = append(result, pa.DivisionPosition{
+ Division_Code: func() string {
+ if dp.Division != nil {
+ return dp.Division.Code
+ }
+ return ""
+ }(),
+ DivisionPosition_Code: dp.Code,
+ })
+ }
+
+ return result, nil
+}
diff --git a/internal/use-case/main-use-case/authentication/tycovar.go b/internal/use-case/main-use-case/authentication/tycovar.go
index d4d5b5ea..c1b11420 100644
--- a/internal/use-case/main-use-case/authentication/tycovar.go
+++ b/internal/use-case/main-use-case/authentication/tycovar.go
@@ -5,15 +5,6 @@ type TokenType string
const AccessToken = "Access"
const RefreshToken = "Refresh"
-type AuthInfo struct {
- Uuid string
- User_Id int
- User_Name string
- // User_Email string
- // User_Ref_Id int
- // User_Position_Code string
-}
-
type AuthCfg struct {
AtSecretKey string `yaml:"atSecretKey"`
RtSecretKey string `yaml:"rtSecretKey"`
diff --git a/internal/use-case/main-use-case/chemo/case.go b/internal/use-case/main-use-case/chemo/case.go
new file mode 100644
index 00000000..541faa04
--- /dev/null
+++ b/internal/use-case/main-use-case/chemo/case.go
@@ -0,0 +1,343 @@
+package chemo
+
+import (
+ "errors"
+ "strconv"
+
+ e "simrs-vx/internal/domain/main-entities/chemo"
+
+ erc "simrs-vx/internal/domain/references/common"
+
+ 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 = "division"
+
+func Create(input e.CreateDto) (*d.Data, error) {
+ data := e.Chemo{}
+
+ event := pl.Event{
+ Feature: "Create",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "create")
+
+ err := dg.I.Transaction(func(tx *gorm.DB) error {
+ mwRunner := newMiddlewareRunner(&event, tx)
+ mwRunner.setMwType(pu.MWTPre)
+ // Run pre-middleware
+ if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil {
+ return err
+ }
+
+ if resData, err := CreateData(input, &event, tx); err != nil {
+ return err
+ } else {
+ data = *resData
+ }
+
+ mwRunner.setMwType(pu.MWTPost)
+ // Run post-middleware
+ if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil {
+ return err
+ }
+
+ pl.SetLogInfo(&event, nil, "complete")
+
+ return nil
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &d.Data{
+ Meta: d.II{
+ "source": source,
+ "structure": "single-data",
+ "status": "created",
+ },
+ Data: data.ToResponse(),
+ }, nil
+}
+
+func ReadList(input e.ReadListDto) (*d.Data, error) {
+ var data *e.Chemo
+ var dataList []e.Chemo
+ 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.Chemo
+ 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.Chemo
+ 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.Chemo
+ 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 Verify(input e.VerifyDto) (*d.Data, error) {
+ rdDto := e.ReadDetailDto{Id: input.Id}
+ var data *e.Chemo
+ var err error
+
+ event := pl.Event{
+ Feature: "Verify",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "verify")
+
+ err = dg.I.Transaction(func(tx *gorm.DB) error {
+ pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail")
+ if data, err = ReadDetailData(rdDto, &event, tx); err != nil {
+ return err
+ }
+
+ if data.Status_Code != erc.DVCNew {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-state-mismatch",
+ Detail: "data is not new",
+ Raw: errors.New("data is not new"),
+ }
+ return pl.SetLogError(&event, input)
+ }
+
+ data.VerifiedAt = pu.GetTimeNow()
+ data.Status_Code = input.Status_Code
+ data.VerifiedBy_User_Id = &input.AuthInfo.User_Id
+
+ err = tx.Save(&data).Error
+ if 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
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &d.Data{
+ Meta: d.IS{
+ "source": source,
+ "structure": "single-data",
+ "status": "verify",
+ },
+ Data: data.ToResponse(),
+ }, nil
+}
diff --git a/internal/use-case/main-use-case/chemo/helper.go b/internal/use-case/main-use-case/chemo/helper.go
new file mode 100644
index 00000000..bb60a39b
--- /dev/null
+++ b/internal/use-case/main-use-case/chemo/helper.go
@@ -0,0 +1,23 @@
+/*
+DESCRIPTION:
+Any functions that are used internally by the use-case
+*/
+package chemo
+
+import (
+ e "simrs-vx/internal/domain/main-entities/chemo"
+)
+
+func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Chemo) {
+ 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.Status_Code = inputSrc.Status_Code
+ data.SrcUnit_Id = inputSrc.SrcUnit_Id
+}
diff --git a/internal/use-case/main-use-case/chemo/lib.go b/internal/use-case/main-use-case/chemo/lib.go
new file mode 100644
index 00000000..39679170
--- /dev/null
+++ b/internal/use-case/main-use-case/chemo/lib.go
@@ -0,0 +1,140 @@
+package chemo
+
+import (
+ e "simrs-vx/internal/domain/main-entities/chemo"
+
+ 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.Chemo, error) {
+ pl.SetLogInfo(event, nil, "started", "DBCreate")
+
+ data := e.Chemo{}
+ 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.Chemo, *e.MetaDto, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadList")
+ data := []e.Chemo{}
+ 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.Chemo{}).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
+ Count(&count).
+ Scopes(gh.Paginate(input, &pagination)).
+ Order("\"CreatedAt\" DESC")
+
+ if err := tx.Find(&data).Error; err != nil {
+ if err == gorm.ErrRecordNotFound {
+ return nil, &meta, nil
+ }
+ return nil, nil, plh.HandleListError(input, event, err)
+ }
+
+ meta.Count = int(count)
+ meta.PageNumber = pagination.PageNumber
+ meta.PageSize = pagination.PageSize
+
+ pl.SetLogInfo(event, nil, "complete")
+ return data, &meta, nil
+}
+
+func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.Chemo, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadDetail")
+ data := e.Chemo{}
+
+ 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.Chemo, 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.Chemo, 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/chemo/middleware-runner.go b/internal/use-case/main-use-case/chemo/middleware-runner.go
new file mode 100644
index 00000000..a29ded7a
--- /dev/null
+++ b/internal/use-case/main-use-case/chemo/middleware-runner.go
@@ -0,0 +1,103 @@
+package chemo
+
+import (
+ e "simrs-vx/internal/domain/main-entities/chemo"
+ 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.Chemo) 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.Chemo) 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.Chemo) 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.Chemo) 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.Chemo) 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/chemo/middleware.go b/internal/use-case/main-use-case/chemo/middleware.go
new file mode 100644
index 00000000..df8c0bc3
--- /dev/null
+++ b/internal/use-case/main-use-case/chemo/middleware.go
@@ -0,0 +1,9 @@
+package chemo
+
+// 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/chemo/tycovar.go b/internal/use-case/main-use-case/chemo/tycovar.go
new file mode 100644
index 00000000..857871c9
--- /dev/null
+++ b/internal/use-case/main-use-case/chemo/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 chemo
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/main-entities/chemo"
+)
+
+type createMw struct {
+ Name string
+ Func func(input *e.CreateDto, data *e.Chemo, tx *gorm.DB) error
+}
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.Chemo, tx *gorm.DB) error
+}
+
+type readDetailMw struct {
+ Name string
+ Func func(input *e.ReadDetailDto, data *e.Chemo, 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/consultation/case.go b/internal/use-case/main-use-case/consultation/case.go
new file mode 100644
index 00000000..3cda31d9
--- /dev/null
+++ b/internal/use-case/main-use-case/consultation/case.go
@@ -0,0 +1,364 @@
+package consultation
+
+import (
+ "errors"
+ "strconv"
+
+ e "simrs-vx/internal/domain/main-entities/consultation"
+ ue "simrs-vx/internal/use-case/main-use-case/encounter"
+
+ ud "simrs-vx/internal/use-case/main-use-case/doctor"
+
+ 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 = "consultation"
+
+func Create(input e.CreateDto) (*d.Data, error) {
+ data := e.Consultation{}
+
+ event := pl.Event{
+ Feature: "Create",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "create")
+
+ err := dg.I.Transaction(func(tx *gorm.DB) error {
+ mwRunner := newMiddlewareRunner(&event, tx)
+ mwRunner.setMwType(pu.MWTPre)
+ // Run pre-middleware
+ if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil {
+ return err
+ }
+
+ // check if encounter is done
+ if ue.IsDone(*input.Encounter_Id, &event, tx) {
+ return errors.New("encounter is already done")
+ }
+
+ if resData, err := CreateData(input, &event, tx); err != nil {
+ return err
+ } else {
+ data = *resData
+ }
+
+ mwRunner.setMwType(pu.MWTPost)
+ // Run post-middleware
+ if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil {
+ return err
+ }
+
+ pl.SetLogInfo(&event, nil, "complete")
+
+ return nil
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &d.Data{
+ Meta: d.II{
+ "source": source,
+ "structure": "single-data",
+ "status": "created",
+ },
+ Data: data.ToResponse(),
+ }, nil
+}
+
+func ReadList(input e.ReadListDto) (*d.Data, error) {
+ var data *e.Consultation
+ var dataList []e.Consultation
+ 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.Consultation
+ 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: uint16(input.Id)}
+ var data *e.Consultation
+ 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: uint16(input.Id)}
+ var data *e.Consultation
+ 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 Reply(input e.ReplyDto) (*d.Data, error) {
+ rdDto := e.ReadDetailDto{Id: uint16(input.Id)}
+ var data *e.Consultation
+ var err error
+
+ event := pl.Event{
+ Feature: "Reply",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "reply")
+
+ err = dg.I.Transaction(func(tx *gorm.DB) error {
+ pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail")
+ if data, err = ReadDetailData(rdDto, &event, tx); err != nil {
+ return err
+ }
+
+ if !input.AuthInfo.IsDoctor() {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "auth-forbidden",
+ Detail: "user position is not allowed",
+ Raw: errors.New("authentication failed"),
+ }
+ return pl.SetLogError(&event, input)
+ }
+
+ doctor_id, err := ud.GetIdByUserId(&input.AuthInfo.User_Id, &event, tx)
+ if err != nil {
+ return err
+ }
+
+ if data.DstDoctor_Id != nil && data.DstDoctor_Id != doctor_id {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-handled-mismatch",
+ Detail: "data handled by different user/person",
+ Raw: errors.New("data handled by different user/person"),
+ }
+ return pl.SetLogError(&event, input)
+ }
+
+ data.DstDoctor_Id = doctor_id
+ data.Solution = input.Solution
+ data.RepliedAt = pu.GetTimeNow()
+ err = tx.Save(&data).Error
+ if 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
+ })
+
+ 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/consultation/helper.go b/internal/use-case/main-use-case/consultation/helper.go
new file mode 100644
index 00000000..519c3c91
--- /dev/null
+++ b/internal/use-case/main-use-case/consultation/helper.go
@@ -0,0 +1,24 @@
+/*
+DESCRIPTION:
+Any functions that are used internally by the use-case
+*/
+package consultation
+
+import (
+ e "simrs-vx/internal/domain/main-entities/consultation"
+)
+
+func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Consultation) {
+ var inputSrc *e.CreateDto
+ if inputT, ok := any(input).(*e.CreateDto); ok {
+ inputSrc = inputT
+ } else {
+ inputTemp := any(input).(*e.UpdateDto)
+ inputSrc = &inputTemp.CreateDto
+ }
+
+ data.Encounter_Id = inputSrc.Encounter_Id
+ data.Date = inputSrc.Date
+ data.Problem = inputSrc.Problem
+ data.DstUnit_Id = inputSrc.DstUnit_Id
+}
diff --git a/internal/use-case/main-use-case/consultation/lib.go b/internal/use-case/main-use-case/consultation/lib.go
new file mode 100644
index 00000000..4ff9e7e2
--- /dev/null
+++ b/internal/use-case/main-use-case/consultation/lib.go
@@ -0,0 +1,140 @@
+package consultation
+
+import (
+ e "simrs-vx/internal/domain/main-entities/consultation"
+
+ 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.Consultation, error) {
+ pl.SetLogInfo(event, nil, "started", "DBCreate")
+
+ data := e.Consultation{}
+ 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.Consultation, *e.MetaDto, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadList")
+ data := []e.Consultation{}
+ 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.Consultation{}).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
+ Count(&count).
+ Scopes(gh.Paginate(input, &pagination)).
+ Order("\"CreatedAt\" DESC")
+
+ if err := tx.Find(&data).Error; err != nil {
+ if err == gorm.ErrRecordNotFound {
+ return nil, &meta, nil
+ }
+ return nil, nil, plh.HandleListError(input, event, err)
+ }
+
+ meta.Count = int(count)
+ meta.PageNumber = pagination.PageNumber
+ meta.PageSize = pagination.PageSize
+
+ pl.SetLogInfo(event, nil, "complete")
+ return data, &meta, nil
+}
+
+func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.Consultation, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadDetail")
+ data := e.Consultation{}
+
+ 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.Consultation, 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.Consultation, 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/consultation/middleware-runner.go b/internal/use-case/main-use-case/consultation/middleware-runner.go
new file mode 100644
index 00000000..30b354c5
--- /dev/null
+++ b/internal/use-case/main-use-case/consultation/middleware-runner.go
@@ -0,0 +1,103 @@
+package consultation
+
+import (
+ e "simrs-vx/internal/domain/main-entities/consultation"
+ 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.Consultation) 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.Consultation) 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.Consultation) 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.Consultation) 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.Consultation) 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/consultation/middleware.go b/internal/use-case/main-use-case/consultation/middleware.go
new file mode 100644
index 00000000..cabd7683
--- /dev/null
+++ b/internal/use-case/main-use-case/consultation/middleware.go
@@ -0,0 +1,9 @@
+package consultation
+
+// 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/consultation/tycovar.go b/internal/use-case/main-use-case/consultation/tycovar.go
new file mode 100644
index 00000000..fdf26fc4
--- /dev/null
+++ b/internal/use-case/main-use-case/consultation/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 consultation
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/main-entities/consultation"
+)
+
+type createMw struct {
+ Name string
+ Func func(input *e.CreateDto, data *e.Consultation, tx *gorm.DB) error
+}
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.Consultation, tx *gorm.DB) error
+}
+
+type readDetailMw struct {
+ Name string
+ Func func(input *e.ReadDetailDto, data *e.Consultation, 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/counter/case.go b/internal/use-case/main-use-case/counter/case.go
index bfc24194..dcf70781 100644
--- a/internal/use-case/main-use-case/counter/case.go
+++ b/internal/use-case/main-use-case/counter/case.go
@@ -106,12 +106,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
diff --git a/internal/use-case/main-use-case/counter/lib.go b/internal/use-case/main-use-case/counter/lib.go
index 64b22b0f..022fa622 100644
--- a/internal/use-case/main-use-case/counter/lib.go
+++ b/internal/use-case/main-use-case/counter/lib.go
@@ -2,6 +2,8 @@ package counter
import (
e "simrs-vx/internal/domain/main-entities/counter"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Counter
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -58,19 +54,13 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Co
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-get-fail",
- Detail: "Database get failed",
- Raw: err,
- }
- return nil, nil, pl.SetLogError(event, input)
-
+ return nil, nil, plh.HandleListError(input, event, err)
}
+
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
diff --git a/internal/use-case/main-use-case/device-order-item/case.go b/internal/use-case/main-use-case/device-order-item/case.go
new file mode 100644
index 00000000..1765e52a
--- /dev/null
+++ b/internal/use-case/main-use-case/device-order-item/case.go
@@ -0,0 +1,277 @@
+package deviceorderitem
+
+import (
+ "strconv"
+
+ e "simrs-vx/internal/domain/main-entities/device-order-item"
+
+ 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 = "device-order-item"
+
+func Create(input e.CreateDto) (*d.Data, error) {
+ data := e.DeviceOrderItem{}
+
+ event := pl.Event{
+ Feature: "Create",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "create")
+
+ err := dg.I.Transaction(func(tx *gorm.DB) error {
+ mwRunner := newMiddlewareRunner(&event, tx)
+ mwRunner.setMwType(pu.MWTPre)
+ // Run pre-middleware
+ if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil {
+ return err
+ }
+
+ if resData, err := CreateData(input, &event, tx); err != nil {
+ return err
+ } else {
+ data = *resData
+ }
+
+ mwRunner.setMwType(pu.MWTPost)
+ // Run post-middleware
+ if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil {
+ return err
+ }
+
+ pl.SetLogInfo(&event, nil, "complete")
+
+ return nil
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &d.Data{
+ Meta: d.II{
+ "source": source,
+ "structure": "single-data",
+ "status": "created",
+ },
+ Data: data.ToResponse(),
+ }, nil
+}
+
+func ReadList(input e.ReadListDto) (*d.Data, error) {
+ var data *e.DeviceOrderItem
+ var dataList []e.DeviceOrderItem
+ 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.DeviceOrderItem
+ 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.DeviceOrderItem
+ 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.DeviceOrderItem
+ 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/device-order-item/helper.go b/internal/use-case/main-use-case/device-order-item/helper.go
new file mode 100644
index 00000000..5c6a0e68
--- /dev/null
+++ b/internal/use-case/main-use-case/device-order-item/helper.go
@@ -0,0 +1,23 @@
+/*
+DESCRIPTION:
+Any functions that are used internally by the use-case
+*/
+package deviceorderitem
+
+import (
+ e "simrs-vx/internal/domain/main-entities/device-order-item"
+)
+
+func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.DeviceOrderItem) {
+ var inputSrc *e.CreateDto
+ if inputT, ok := any(input).(*e.CreateDto); ok {
+ inputSrc = inputT
+ } else {
+ inputTemp := any(input).(*e.UpdateDto)
+ inputSrc = &inputTemp.CreateDto
+ }
+
+ data.DeviceOrder_Id = inputSrc.DeviceOrder_Id
+ data.Device_Id = inputSrc.Device_Id
+ data.Count = inputSrc.Count
+}
diff --git a/internal/use-case/main-use-case/device-order-item/lib.go b/internal/use-case/main-use-case/device-order-item/lib.go
new file mode 100644
index 00000000..70ccc5d7
--- /dev/null
+++ b/internal/use-case/main-use-case/device-order-item/lib.go
@@ -0,0 +1,140 @@
+package deviceorderitem
+
+import (
+ e "simrs-vx/internal/domain/main-entities/device-order-item"
+
+ plh "simrs-vx/pkg/lib-helper"
+ pl "simrs-vx/pkg/logger"
+ pu "simrs-vx/pkg/use-case-helper"
+
+ dg "github.com/karincake/apem/db-gorm-pg"
+ gh "github.com/karincake/getuk"
+ "gorm.io/gorm"
+)
+
+func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.DeviceOrderItem, error) {
+ pl.SetLogInfo(event, nil, "started", "DBCreate")
+
+ data := e.DeviceOrderItem{}
+ 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.DeviceOrderItem, *e.MetaDto, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadList")
+ data := []e.DeviceOrderItem{}
+ 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.DeviceOrderItem{}).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
+ Count(&count).
+ Scopes(gh.Paginate(input, &pagination)).
+ Order("\"CreatedAt\" DESC")
+
+ if err := tx.Find(&data).Error; err != nil {
+ if err == gorm.ErrRecordNotFound {
+ return nil, &meta, nil
+ }
+ return nil, nil, plh.HandleListError(input, event, err)
+ }
+
+ meta.Count = int(count)
+ meta.PageNumber = pagination.PageNumber
+ meta.PageSize = pagination.PageSize
+
+ pl.SetLogInfo(event, nil, "complete")
+ return data, &meta, nil
+}
+
+func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.DeviceOrderItem, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadDetail")
+ data := e.DeviceOrderItem{}
+
+ 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.DeviceOrderItem, 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.DeviceOrderItem, 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/device-order-item/middleware-runner.go b/internal/use-case/main-use-case/device-order-item/middleware-runner.go
new file mode 100644
index 00000000..6722ef63
--- /dev/null
+++ b/internal/use-case/main-use-case/device-order-item/middleware-runner.go
@@ -0,0 +1,103 @@
+package deviceorderitem
+
+import (
+ e "simrs-vx/internal/domain/main-entities/device-order-item"
+ pl "simrs-vx/pkg/logger"
+ pu "simrs-vx/pkg/use-case-helper"
+
+ "gorm.io/gorm"
+)
+
+type middlewareRunner struct {
+ Event *pl.Event
+ Tx *gorm.DB
+ MwType pu.MWType
+}
+
+// NewMiddlewareExecutor creates a new middleware executor
+func newMiddlewareRunner(event *pl.Event, tx *gorm.DB) *middlewareRunner {
+ return &middlewareRunner{
+ Event: event,
+ Tx: tx,
+ }
+}
+
+// ExecuteCreateMiddleware executes create middleware
+func (me *middlewareRunner) RunCreateMiddleware(middlewares []createMw, input *e.CreateDto, data *e.DeviceOrderItem) 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.DeviceOrderItem) 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.DeviceOrderItem) 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.DeviceOrderItem) 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.DeviceOrderItem) 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/device-order-item/middleware.go b/internal/use-case/main-use-case/device-order-item/middleware.go
new file mode 100644
index 00000000..c43a462b
--- /dev/null
+++ b/internal/use-case/main-use-case/device-order-item/middleware.go
@@ -0,0 +1,9 @@
+package deviceorderitem
+
+// 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/device-order-item/tycovar.go b/internal/use-case/main-use-case/device-order-item/tycovar.go
new file mode 100644
index 00000000..b5801749
--- /dev/null
+++ b/internal/use-case/main-use-case/device-order-item/tycovar.go
@@ -0,0 +1,44 @@
+/*
+DESCRIPTION:
+A sample, part of the package that contains type, constants, and/or variables.
+
+In this sample it also provides type and variable regarding the needs of the
+middleware to separate from main use-case which has the basic CRUD
+functionality. The purpose of this is to make the code more maintainable.
+*/
+package deviceorderitem
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/main-entities/device-order-item"
+)
+
+type createMw struct {
+ Name string
+ Func func(input *e.CreateDto, data *e.DeviceOrderItem, tx *gorm.DB) error
+}
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.DeviceOrderItem, tx *gorm.DB) error
+}
+
+type readDetailMw struct {
+ Name string
+ Func func(input *e.ReadDetailDto, data *e.DeviceOrderItem, 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/device-order/case.go b/internal/use-case/main-use-case/device-order/case.go
new file mode 100644
index 00000000..89466ead
--- /dev/null
+++ b/internal/use-case/main-use-case/device-order/case.go
@@ -0,0 +1,391 @@
+package deviceorder
+
+import (
+ "errors"
+ "strconv"
+
+ e "simrs-vx/internal/domain/main-entities/device-order"
+
+ ud "simrs-vx/internal/use-case/main-use-case/doctor"
+ ue "simrs-vx/internal/use-case/main-use-case/encounter"
+
+ erc "simrs-vx/internal/domain/references/common"
+
+ 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 = "device-order"
+
+func Create(input e.CreateDto) (*d.Data, error) {
+ data := e.DeviceOrder{}
+
+ event := pl.Event{
+ Feature: "Create",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "create")
+
+ err := dg.I.Transaction(func(tx *gorm.DB) error {
+ mwRunner := newMiddlewareRunner(&event, tx)
+ mwRunner.setMwType(pu.MWTPre)
+ // Run pre-middleware
+ if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil {
+ return err
+ }
+
+ // check if encounter is done
+ if ue.IsDone(*input.Encounter_Id, &event, tx) {
+ return errors.New("encounter is already done")
+ }
+
+ if data.IsCompleted() {
+ return errors.New("data already completed")
+ }
+
+ if !input.AuthInfo.IsDoctor() {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "auth-forbidden",
+ Detail: "user position is not allowed",
+ Raw: errors.New("authentication failed"),
+ }
+ return pl.SetLogError(&event, input)
+ }
+
+ doctor_id, err := ud.GetIdByUserId(&input.AuthInfo.User_Id, &event, tx)
+ if err != nil {
+ return err
+ }
+ input.Doctor_Id = doctor_id
+
+ 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.DeviceOrder
+ var dataList []e.DeviceOrder
+ 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.DeviceOrder
+ 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.DeviceOrder
+ 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
+ }
+
+ if data.IsCompleted() {
+ return errors.New("data already completed")
+ }
+ mwRunner := newMiddlewareRunner(&event, tx)
+ mwRunner.setMwType(pu.MWTPre)
+ // Run pre-middleware
+ if err := mwRunner.RunUpdateMiddleware(readDetailPreMw, &rdDto, data); err != nil {
+ return err
+ }
+
+ if !input.AuthInfo.IsDoctor() {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "auth-forbidden",
+ Detail: "user position is not allowed",
+ Raw: errors.New("authentication failed"),
+ }
+ return pl.SetLogError(&event, input)
+ }
+
+ doctor_id, err := ud.GetIdByUserId(&input.AuthInfo.User_Id, &event, tx)
+ if err != nil {
+ return err
+ }
+ if !data.IsSameDoctor(doctor_id) {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "auth-forbidden",
+ Detail: "doctor is not the same as the data",
+ Raw: errors.New("authentication failed"),
+ }
+ return pl.SetLogError(&event, input)
+ }
+
+ input.Doctor_Id = doctor_id
+
+ 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.DeviceOrder
+ 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
+ }
+
+ if data.IsCompleted() {
+ return errors.New("data already completed")
+ }
+ 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 Complete(input e.ReadDetailDto) (*d.Data, error) {
+ var data *e.DeviceOrder
+ var err error
+
+ event := pl.Event{
+ Feature: "Complete",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "complete")
+
+ err = dg.I.Transaction(func(tx *gorm.DB) error {
+ data, err = ReadDetailData(input, &event, tx)
+ if err != nil {
+ return err
+ }
+
+ if data.IsCompleted() {
+ return errors.New("data already completed")
+ }
+
+ data.Status_Code = erc.DSCDone
+ 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
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &d.Data{
+ Meta: d.IS{
+ "source": source,
+ "structure": "single-data",
+ "status": "fetched",
+ },
+ Data: data.ToResponse(),
+ }, nil
+}
diff --git a/internal/use-case/main-use-case/device-order/helper.go b/internal/use-case/main-use-case/device-order/helper.go
new file mode 100644
index 00000000..3be32a7a
--- /dev/null
+++ b/internal/use-case/main-use-case/device-order/helper.go
@@ -0,0 +1,25 @@
+/*
+DESCRIPTION:
+Any functions that are used internally by the use-case
+*/
+package deviceorder
+
+import (
+ e "simrs-vx/internal/domain/main-entities/device-order"
+
+ erc "simrs-vx/internal/domain/references/common"
+)
+
+func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.DeviceOrder) {
+ var inputSrc *e.CreateDto
+ if inputT, ok := any(input).(*e.CreateDto); ok {
+ inputSrc = inputT
+ data.Status_Code = erc.DSCNew
+ } else {
+ inputTemp := any(input).(*e.UpdateDto)
+ inputSrc = &inputTemp.CreateDto
+ }
+
+ data.Encounter_Id = inputSrc.Encounter_Id
+ data.Doctor_Id = inputSrc.Doctor_Id
+}
diff --git a/internal/use-case/main-use-case/device-order/lib.go b/internal/use-case/main-use-case/device-order/lib.go
new file mode 100644
index 00000000..996dfc86
--- /dev/null
+++ b/internal/use-case/main-use-case/device-order/lib.go
@@ -0,0 +1,140 @@
+package deviceorder
+
+import (
+ e "simrs-vx/internal/domain/main-entities/device-order"
+
+ 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.DeviceOrder, error) {
+ pl.SetLogInfo(event, nil, "started", "DBCreate")
+
+ data := e.DeviceOrder{}
+ 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.DeviceOrder, *e.MetaDto, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadList")
+ data := []e.DeviceOrder{}
+ 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.DeviceOrder{}).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
+ Count(&count).
+ Scopes(gh.Paginate(input, &pagination)).
+ Order("\"CreatedAt\" DESC")
+
+ if err := tx.Find(&data).Error; err != nil {
+ if err == gorm.ErrRecordNotFound {
+ return nil, &meta, nil
+ }
+ return nil, nil, plh.HandleListError(input, event, err)
+ }
+
+ meta.Count = int(count)
+ meta.PageNumber = pagination.PageNumber
+ meta.PageSize = pagination.PageSize
+
+ pl.SetLogInfo(event, nil, "complete")
+ return data, &meta, nil
+}
+
+func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.DeviceOrder, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadDetail")
+ data := e.DeviceOrder{}
+
+ 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.DeviceOrder, 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.DeviceOrder, 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/device-order/middleware-runner.go b/internal/use-case/main-use-case/device-order/middleware-runner.go
new file mode 100644
index 00000000..7628d931
--- /dev/null
+++ b/internal/use-case/main-use-case/device-order/middleware-runner.go
@@ -0,0 +1,103 @@
+package deviceorder
+
+import (
+ e "simrs-vx/internal/domain/main-entities/device-order"
+ 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.DeviceOrder) 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.DeviceOrder) 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.DeviceOrder) 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.DeviceOrder) 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.DeviceOrder) 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/device-order/middleware.go b/internal/use-case/main-use-case/device-order/middleware.go
new file mode 100644
index 00000000..a8765213
--- /dev/null
+++ b/internal/use-case/main-use-case/device-order/middleware.go
@@ -0,0 +1,9 @@
+package deviceorder
+
+// 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/device-order/tycovar.go b/internal/use-case/main-use-case/device-order/tycovar.go
new file mode 100644
index 00000000..9faa49d6
--- /dev/null
+++ b/internal/use-case/main-use-case/device-order/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 deviceorder
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/main-entities/device-order"
+)
+
+type createMw struct {
+ Name string
+ Func func(input *e.CreateDto, data *e.DeviceOrder, tx *gorm.DB) error
+}
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.DeviceOrder, tx *gorm.DB) error
+}
+
+type readDetailMw struct {
+ Name string
+ Func func(input *e.ReadDetailDto, data *e.DeviceOrder, 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/device/case.go b/internal/use-case/main-use-case/device/case.go
index 5c5c9b73..ff548a4b 100644
--- a/internal/use-case/main-use-case/device/case.go
+++ b/internal/use-case/main-use-case/device/case.go
@@ -90,9 +90,6 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
return err
}
- if len(input.Includes) > 0 {
- input.Preloads = pu.GetPreloads(input.Includes)
- }
if dataList, metaList, err = ReadListData(input, &event, tx); err != nil {
return err
}
@@ -112,12 +109,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
diff --git a/internal/use-case/main-use-case/device/helper.go b/internal/use-case/main-use-case/device/helper.go
index 63d51664..08964464 100644
--- a/internal/use-case/main-use-case/device/helper.go
+++ b/internal/use-case/main-use-case/device/helper.go
@@ -31,6 +31,7 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Device) {
data.Name = inputSrc.Name
data.Uom_Code = inputSrc.Uom_Code
data.Item_Id = inputSrc.Item_Id
+ data.Infra_Id = inputSrc.Infra_Id
}
func createItem(input *e.CreateDto, event *pl.Event, tx *gorm.DB) error {
diff --git a/internal/use-case/main-use-case/device/lib.go b/internal/use-case/main-use-case/device/lib.go
index 22c233b6..664db248 100644
--- a/internal/use-case/main-use-case/device/lib.go
+++ b/internal/use-case/main-use-case/device/lib.go
@@ -2,6 +2,8 @@ package device
import (
e "simrs-vx/internal/domain/main-entities/device"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Device,
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -51,32 +47,21 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.De
tx = dg.I
}
- if len(input.Preloads) > 0 {
- for _, preload := range input.Preloads {
- tx = tx.Preload(preload)
- }
- }
-
tx = tx.
Model(&e.Device{}).
+ Scopes(gh.Preload(input.Includes)).
Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
- Order("\"CreatedAt\" DESC")
+ Scopes(gh.Sort(input.Sort))
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-get-fail",
- Detail: "Database get failed",
- Raw: err,
- }
- return nil, nil, pl.SetLogError(event, input)
-
+ return nil, nil, plh.HandleListError(input, event, err)
}
+
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
diff --git a/internal/use-case/main-use-case/diagnose-src/case.go b/internal/use-case/main-use-case/diagnose-src/case.go
index 6fc921e4..184e68a8 100644
--- a/internal/use-case/main-use-case/diagnose-src/case.go
+++ b/internal/use-case/main-use-case/diagnose-src/case.go
@@ -106,12 +106,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
diff --git a/internal/use-case/main-use-case/diagnose-src/lib.go b/internal/use-case/main-use-case/diagnose-src/lib.go
index 344e36ef..d45f6bb3 100644
--- a/internal/use-case/main-use-case/diagnose-src/lib.go
+++ b/internal/use-case/main-use-case/diagnose-src/lib.go
@@ -2,6 +2,8 @@ package diagnosesrc
import (
e "simrs-vx/internal/domain/main-entities/diagnose-src"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Diagnos
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -53,24 +49,19 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Di
tx = tx.
Model(&e.DiagnoseSrc{}).
- Scopes(gh.Filter(input)).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
- Order("\"CreatedAt\" DESC")
+ Scopes(gh.Sort(input.Sort))
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-get-fail",
- Detail: "Database get failed",
- Raw: err,
- }
- return nil, nil, pl.SetLogError(event, input)
-
+ return nil, nil, plh.HandleListError(input, event, err)
}
+
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
diff --git a/internal/use-case/main-use-case/district/case.go b/internal/use-case/main-use-case/district/case.go
index 1770e6f2..b7a4b1a0 100644
--- a/internal/use-case/main-use-case/district/case.go
+++ b/internal/use-case/main-use-case/district/case.go
@@ -106,12 +106,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
diff --git a/internal/use-case/main-use-case/district/lib.go b/internal/use-case/main-use-case/district/lib.go
index ba98ad06..4c8ac32f 100644
--- a/internal/use-case/main-use-case/district/lib.go
+++ b/internal/use-case/main-use-case/district/lib.go
@@ -2,6 +2,8 @@ package district
import (
e "simrs-vx/internal/domain/main-entities/district"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Distric
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -53,23 +49,19 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Di
tx = tx.
Model(&e.District{}).
- Scopes(gh.Filter(input)).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
Count(&count).
- Scopes(gh.Paginate(input, &pagination))
+ Scopes(gh.Paginate(input, &pagination)).
+ Scopes(gh.Sort(input.Sort))
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-get-fail",
- Detail: "Database get failed",
- Raw: err,
- }
- return nil, nil, pl.SetLogError(event, input)
-
+ return nil, nil, plh.HandleListError(input, event, err)
}
+
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
diff --git a/internal/use-case/main-use-case/division-position/case.go b/internal/use-case/main-use-case/division-position/case.go
index 2fbb0c3b..159e9edc 100644
--- a/internal/use-case/main-use-case/division-position/case.go
+++ b/internal/use-case/main-use-case/division-position/case.go
@@ -87,9 +87,6 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
return err
}
- if len(input.Includes) > 0 {
- input.Preloads = pu.GetPreloads(input.Includes)
- }
if dataList, metaList, err = ReadListData(input, &event, tx); err != nil {
return err
}
@@ -109,12 +106,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
diff --git a/internal/use-case/main-use-case/division-position/helper.go b/internal/use-case/main-use-case/division-position/helper.go
index f353a9ea..482dbc4e 100644
--- a/internal/use-case/main-use-case/division-position/helper.go
+++ b/internal/use-case/main-use-case/division-position/helper.go
@@ -20,4 +20,6 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.DivisionPosition) {
data.Division_Id = inputSrc.Division_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/division-position/lib.go b/internal/use-case/main-use-case/division-position/lib.go
index c59506c0..d1327d47 100644
--- a/internal/use-case/main-use-case/division-position/lib.go
+++ b/internal/use-case/main-use-case/division-position/lib.go
@@ -2,6 +2,8 @@ package divisionposition
import (
e "simrs-vx/internal/domain/main-entities/division-position"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Divisio
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -51,33 +47,21 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Di
tx = dg.I
}
- if len(input.Preloads) > 0 {
- for _, preload := range input.Preloads {
- tx = tx.Preload(preload)
- }
- }
-
tx = tx.
Model(&e.DivisionPosition{}).
- Preload("Division").
+ Scopes(gh.Preload(input.Includes)).
Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
- Order("\"CreatedAt\" DESC")
+ Scopes(gh.Sort(input.Sort))
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-get-fail",
- Detail: "Database get failed",
- Raw: err,
- }
- return nil, nil, pl.SetLogError(event, input)
-
+ return nil, nil, plh.HandleListError(input, event, err)
}
+
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
diff --git a/internal/use-case/main-use-case/division/case.go b/internal/use-case/main-use-case/division/case.go
index bf1b94fe..daabd2f8 100644
--- a/internal/use-case/main-use-case/division/case.go
+++ b/internal/use-case/main-use-case/division/case.go
@@ -106,12 +106,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
diff --git a/internal/use-case/main-use-case/division/lib.go b/internal/use-case/main-use-case/division/lib.go
index ad9de8ef..828395e7 100644
--- a/internal/use-case/main-use-case/division/lib.go
+++ b/internal/use-case/main-use-case/division/lib.go
@@ -2,6 +2,8 @@ package division
import (
e "simrs-vx/internal/domain/main-entities/division"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Divisio
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -51,26 +47,31 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Di
tx = dg.I
}
+ if input.OnlyHaveChildren {
+ tx = tx.Where(`
+ EXISTS (
+ SELECT 1
+ FROM "Division" c
+ WHERE c."Parent_Id" = "Division"."Id"
+ )
+ `)
+ }
+
tx = tx.
Model(&e.Division{}).
- Scopes(gh.Filter(input)).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
- Order("\"CreatedAt\" DESC")
+ Scopes(gh.Sort(input.Sort))
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-get-fail",
- Detail: "Database get failed",
- Raw: err,
- }
- return nil, nil, pl.SetLogError(event, input)
-
+ return nil, nil, plh.HandleListError(input, event, err)
}
+
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
diff --git a/internal/use-case/main-use-case/doctor-fee/case.go b/internal/use-case/main-use-case/doctor-fee/case.go
index cce2ae5f..94b57da5 100644
--- a/internal/use-case/main-use-case/doctor-fee/case.go
+++ b/internal/use-case/main-use-case/doctor-fee/case.go
@@ -87,9 +87,6 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
return err
}
- if len(input.Includes) > 0 {
- input.Preloads = pu.GetPreloads(input.Includes)
- }
if dataList, metaList, err = ReadListData(input, &event, tx); err != nil {
return err
}
@@ -109,12 +106,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
diff --git a/internal/use-case/main-use-case/doctor-fee/lib.go b/internal/use-case/main-use-case/doctor-fee/lib.go
index ef4629f5..e657537a 100644
--- a/internal/use-case/main-use-case/doctor-fee/lib.go
+++ b/internal/use-case/main-use-case/doctor-fee/lib.go
@@ -2,6 +2,8 @@ package doctorfee
import (
e "simrs-vx/internal/domain/main-entities/doctor-fee"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.DoctorF
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -51,32 +47,21 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Do
tx = dg.I
}
- if len(input.Preloads) > 0 {
- for _, preload := range input.Preloads {
- tx = tx.Preload(preload)
- }
- }
-
tx = tx.
Model(&e.DoctorFee{}).
+ Scopes(gh.Preload(input.Includes)).
Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-get-fail",
- Detail: "Database get failed",
- Raw: err,
- }
- return nil, nil, pl.SetLogError(event, input)
-
+ return nil, nil, plh.HandleListError(input, event, err)
}
+
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
diff --git a/internal/use-case/main-use-case/doctor/case.go b/internal/use-case/main-use-case/doctor/case.go
index 19088c61..74337056 100644
--- a/internal/use-case/main-use-case/doctor/case.go
+++ b/internal/use-case/main-use-case/doctor/case.go
@@ -87,9 +87,6 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
return err
}
- if len(input.Includes) > 0 {
- input.Preloads = pu.GetPreloads(input.Includes)
- }
if dataList, metaList, err = ReadListData(input, &event, tx); err != nil {
return err
}
@@ -109,12 +106,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
diff --git a/internal/use-case/main-use-case/doctor/helper.go b/internal/use-case/main-use-case/doctor/helper.go
index c6898db6..8077b92f 100644
--- a/internal/use-case/main-use-case/doctor/helper.go
+++ b/internal/use-case/main-use-case/doctor/helper.go
@@ -21,4 +21,6 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Doctor) {
data.IHS_Number = inputSrc.IHS_Number
data.SIP_Number = inputSrc.SIP_Number
data.Unit_Id = inputSrc.Unit_Id
+ data.Specialist_Id = inputSrc.Specialist_Id
+ data.Subspecialist_Id = inputSrc.Subspecialist_Id
}
diff --git a/internal/use-case/main-use-case/doctor/lib.go b/internal/use-case/main-use-case/doctor/lib.go
index 4383c666..3355bb3c 100644
--- a/internal/use-case/main-use-case/doctor/lib.go
+++ b/internal/use-case/main-use-case/doctor/lib.go
@@ -2,6 +2,8 @@ package doctor
import (
e "simrs-vx/internal/domain/main-entities/doctor"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Doctor,
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -51,32 +47,21 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Do
tx = dg.I
}
- if len(input.Preloads) > 0 {
- for _, preload := range input.Preloads {
- tx = tx.Preload(preload)
- }
- }
-
tx = tx.
Model(&e.Doctor{}).
+ Scopes(gh.Preload(input.Includes)).
Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-get-fail",
- Detail: "Database get failed",
- Raw: err,
- }
- return nil, nil, pl.SetLogError(event, input)
-
+ return nil, nil, plh.HandleListError(input, event, err)
}
+
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
@@ -159,3 +144,34 @@ func DeleteData(data *e.Doctor, event *pl.Event, dbx ...*gorm.DB) error {
pl.SetLogInfo(event, nil, "complete")
return nil
}
+
+func GetIdByUserId(user_id *uint, event *pl.Event, dbx ...*gorm.DB) (*uint, error) {
+ pl.SetLogInfo(event, nil, "started", "DBGetIdByUserId")
+ var tx *gorm.DB
+ if len(dbx) > 0 {
+ tx = dbx[0]
+ } else {
+ tx = dg.I
+ }
+
+ var doctor_id uint
+
+ err := tx.Model(&e.Doctor{}).
+ Select("\"Doctor\".\"Id\" as doctor_id").
+ Joins("JOIN \"Employee\" as e ON e.\"Id\" = \"Doctor\".\"Employee_Id\"").
+ Where("e.\"User_Id\" = ?", user_id).
+ Scan(&doctor_id).Error
+
+ if err != nil {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-get-fail",
+ Detail: "Database get failed",
+ Raw: err,
+ }
+ return nil, pl.SetLogError(event, user_id)
+ }
+
+ pl.SetLogInfo(event, nil, "complete")
+ return &doctor_id, nil
+}
diff --git a/internal/use-case/main-use-case/emergency/case.go b/internal/use-case/main-use-case/emergency/case.go
new file mode 100644
index 00000000..88f662db
--- /dev/null
+++ b/internal/use-case/main-use-case/emergency/case.go
@@ -0,0 +1,276 @@
+package emergency
+
+import (
+ e "simrs-vx/internal/domain/main-entities/emergency"
+ "strconv"
+
+ dg "github.com/karincake/apem/db-gorm-pg"
+ d "github.com/karincake/dodol"
+
+ pl "simrs-vx/pkg/logger"
+ pu "simrs-vx/pkg/use-case-helper"
+
+ "gorm.io/gorm"
+)
+
+const source = "emergency"
+
+func Create(input e.CreateDto) (*d.Data, error) {
+ data := e.Emergency{}
+
+ event := pl.Event{
+ Feature: "Create",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "create")
+
+ err := dg.I.Transaction(func(tx *gorm.DB) error {
+ mwRunner := newMiddlewareRunner(&event, tx)
+ mwRunner.setMwType(pu.MWTPre)
+ // Run pre-middleware
+ if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil {
+ return err
+ }
+
+ if resData, err := CreateData(input, &event, tx); err != nil {
+ return err
+ } else {
+ data = *resData
+ }
+
+ mwRunner.setMwType(pu.MWTPost)
+ // Run post-middleware
+ if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil {
+ return err
+ }
+
+ pl.SetLogInfo(&event, nil, "complete")
+
+ return nil
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &d.Data{
+ Meta: d.II{
+ "source": source,
+ "structure": "single-data",
+ "status": "created",
+ },
+ Data: data.ToResponse(),
+ }, nil
+}
+
+func ReadList(input e.ReadListDto) (*d.Data, error) {
+ var data *e.Emergency
+ var dataList []e.Emergency
+ 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.Emergency
+ 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: uint16(input.Id)}
+ var data *e.Emergency
+ 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: uint16(input.Id)}
+ var data *e.Emergency
+ 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/emergency/helper.go b/internal/use-case/main-use-case/emergency/helper.go
new file mode 100644
index 00000000..00cde658
--- /dev/null
+++ b/internal/use-case/main-use-case/emergency/helper.go
@@ -0,0 +1,38 @@
+/*
+DESCRIPTION:
+Any functions that are used internally by the use-case
+*/
+package emergency
+
+import (
+ "errors"
+ e "simrs-vx/internal/domain/main-entities/emergency"
+
+ ere "simrs-vx/internal/domain/references/encounter"
+)
+
+func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Emergency) {
+ 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.Class_Code = inputSrc.Class_Code
+}
+
+func CheckClassCode(input *string) (ere.EmergencyClassCode, error) {
+ if input != nil {
+ subCode := ere.EmergencyClassCode(*input)
+ switch subCode {
+ case ere.ECCEmg, ere.ECCEon:
+ return subCode, nil
+ default:
+ return "", errors.New("unknown sub class code")
+ }
+ }
+ return "", errors.New("sub class code is nil")
+}
diff --git a/internal/use-case/main-use-case/emergency/lib.go b/internal/use-case/main-use-case/emergency/lib.go
new file mode 100644
index 00000000..df7812f4
--- /dev/null
+++ b/internal/use-case/main-use-case/emergency/lib.go
@@ -0,0 +1,140 @@
+package emergency
+
+import (
+ e "simrs-vx/internal/domain/main-entities/emergency"
+
+ 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.Emergency, error) {
+ pl.SetLogInfo(event, nil, "started", "DBCreate")
+
+ data := e.Emergency{}
+ 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.Emergency, *e.MetaDto, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadList")
+ data := []e.Emergency{}
+ 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.Emergency{}).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
+ Count(&count).
+ Scopes(gh.Paginate(input, &pagination)).
+ Order("\"CreatedAt\" DESC")
+
+ if err := tx.Find(&data).Error; err != nil {
+ if err == gorm.ErrRecordNotFound {
+ return nil, &meta, nil
+ }
+ return nil, nil, plh.HandleListError(input, event, err)
+ }
+
+ meta.Count = int(count)
+ meta.PageNumber = pagination.PageNumber
+ meta.PageSize = pagination.PageSize
+
+ pl.SetLogInfo(event, nil, "complete")
+ return data, &meta, nil
+}
+
+func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.Emergency, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadDetail")
+ data := e.Emergency{}
+
+ 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.Emergency, 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.Emergency, 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/emergency/middleware-runner.go b/internal/use-case/main-use-case/emergency/middleware-runner.go
new file mode 100644
index 00000000..121d1b79
--- /dev/null
+++ b/internal/use-case/main-use-case/emergency/middleware-runner.go
@@ -0,0 +1,103 @@
+package emergency
+
+import (
+ e "simrs-vx/internal/domain/main-entities/emergency"
+ 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.Emergency) 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.Emergency) 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.Emergency) 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.Emergency) 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.Emergency) 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/emergency/middleware.go b/internal/use-case/main-use-case/emergency/middleware.go
new file mode 100644
index 00000000..3ad52516
--- /dev/null
+++ b/internal/use-case/main-use-case/emergency/middleware.go
@@ -0,0 +1,9 @@
+package emergency
+
+// 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/emergency/tycovar.go b/internal/use-case/main-use-case/emergency/tycovar.go
new file mode 100644
index 00000000..e057fa29
--- /dev/null
+++ b/internal/use-case/main-use-case/emergency/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 emergency
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/main-entities/emergency"
+)
+
+type createMw struct {
+ Name string
+ Func func(input *e.CreateDto, data *e.Emergency, tx *gorm.DB) error
+}
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.Emergency, tx *gorm.DB) error
+}
+
+type readDetailMw struct {
+ Name string
+ Func func(input *e.ReadDetailDto, data *e.Emergency, 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/case.go b/internal/use-case/main-use-case/employee/case.go
index 7a489ec8..b59eae18 100644
--- a/internal/use-case/main-use-case/employee/case.go
+++ b/internal/use-case/main-use-case/employee/case.go
@@ -3,21 +3,7 @@ package employee
import (
"strconv"
- ed "simrs-vx/internal/domain/main-entities/doctor"
e "simrs-vx/internal/domain/main-entities/employee"
- en "simrs-vx/internal/domain/main-entities/nurse"
- et "simrs-vx/internal/domain/main-entities/nutritionist"
- ep "simrs-vx/internal/domain/main-entities/pharmacist"
-
- ud "simrs-vx/internal/use-case/main-use-case/doctor"
- 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"
- upa "simrs-vx/internal/use-case/main-use-case/person-address"
- upc "simrs-vx/internal/use-case/main-use-case/person-contact"
- up "simrs-vx/internal/use-case/main-use-case/pharmacist"
-
- ero "simrs-vx/internal/domain/references/organization"
dg "github.com/karincake/apem/db-gorm-pg"
d "github.com/karincake/dodol"
@@ -39,7 +25,7 @@ func Create(input e.CreateDto) (*d.Data, error) {
}
// Start log
- pl.SetLogInfo(&event, input.Sanitize(), "started", "create")
+ pl.SetLogInfo(&event, input, "started", "create")
err := dg.I.Transaction(func(tx *gorm.DB) error {
mwRunner := newMiddlewareRunner(&event, tx)
@@ -49,73 +35,6 @@ func Create(input e.CreateDto) (*d.Data, error) {
return err
}
- if person_id, err := upe.CreateOrUpdatePerson(input.Person, &event, tx); err != nil {
- return err
- } else {
- input.Person_Id = person_id
- }
-
- for idx := range input.PersonAddresses {
- input.PersonAddresses[idx].Person_Id = *input.Person_Id
- }
- if err := upa.CreateOrUpdateBatch(input.PersonAddresses, &event, tx); err != nil {
- return err
- }
-
- for idx := range input.PersonContacts {
- input.PersonContacts[idx].Person_Id = *input.Person_Id
- }
- if err := upc.CreateOrUpdateBatch(input.PersonContacts, &event, tx); err != nil {
- return err
- }
-
- if err := createUser(&input, &event, tx); err != nil {
- return err
- }
-
- if resData, err := CreateData(input, &event, tx); err != nil {
- return err
- } else {
- data = *resData
- }
-
- switch input.Position_Code {
- case ero.EPCDoc:
- createDoc := ed.CreateDto{
- Employee_Id: &data.Id,
- IHS_Number: input.IHS_Number,
- SIP_Number: input.SIP_Number,
- Unit_Id: input.Unit_Id,
- }
- if _, err := ud.CreateData(createDoc, &event, tx); err != nil {
- return err
- }
- case ero.EPCNur:
- createNurse := en.CreateDto{
- Employee_Id: &data.Id,
- IHS_Number: input.IHS_Number,
- }
- if _, err := un.CreateData(createNurse, &event, tx); err != nil {
- return err
- }
- case ero.EPCNut:
- createNutritionist := et.CreateDto{
- Employee_Id: &data.Id,
- IHS_Number: input.IHS_Number,
- }
- if _, err := ut.CreateData(createNutritionist, &event, tx); err != nil {
- return err
- }
- case ero.EPCPha:
- createPharmacist := ep.CreateDto{
- Employee_Id: &data.Id,
- IHS_Number: input.IHS_Number,
- }
- if _, err := up.CreateData(createPharmacist, &event, tx); err != nil {
- return err
- }
- }
-
mwRunner.setMwType(pu.MWTPost)
// Run post-middleware
if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil {
@@ -163,9 +82,6 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
return err
}
- if len(input.Includes) > 0 {
- input.Preloads = pu.GetPreloads(input.Includes)
- }
if dataList, metaList, err = ReadListData(input, &event, tx); err != nil {
return err
}
@@ -185,12 +101,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
@@ -269,115 +186,10 @@ func Update(input e.UpdateDto) (*d.Data, error) {
return err
}
- if person_id, err := upe.CreateOrUpdatePerson(input.Person, &event, tx); err != nil {
- return err
- } else {
- input.Person_Id = person_id
- }
-
- for idx := range input.PersonAddresses {
- input.PersonAddresses[idx].Person_Id = *input.Person_Id
- }
- if err := upa.CreateOrUpdateBatch(input.PersonAddresses, &event, tx); err != nil {
- return err
- }
-
- for idx := range input.PersonContacts {
- input.PersonContacts[idx].Person_Id = *input.Person_Id
- }
- if err := upc.CreateOrUpdateBatch(input.PersonContacts, &event, tx); err != nil {
- return err
- }
-
if err := UpdateData(input, data, &event, tx); err != nil {
return err
}
- switch input.Position_Code {
- case ero.EPCDoc:
- readDoc := ed.ReadDetailDto{Employee_Id: &data.Id}
- readDocData, err := ud.ReadDetailData(readDoc, &event, tx)
- if err != nil {
- return err
- }
- createDoc := ed.CreateDto{
- Employee_Id: &data.Id,
- IHS_Number: input.IHS_Number,
- SIP_Number: input.SIP_Number,
- Unit_Id: input.Unit_Id,
- }
- if readDocData != nil {
- if err := ud.UpdateData(ed.UpdateDto{CreateDto: createDoc}, readDocData, &event, tx); err != nil {
- return err
- }
- return nil
- }
-
- if _, err := ud.CreateData(createDoc, &event, tx); err != nil {
- return err
- }
- case ero.EPCNur:
- readNur := en.ReadDetailDto{Employee_Id: &data.Id}
- readNurData, err := un.ReadDetailData(readNur, &event, tx)
- if err != nil {
- return err
- }
- createNur := en.CreateDto{
- Employee_Id: &data.Id,
- IHS_Number: input.IHS_Number,
- }
- if readNurData != nil {
- if err := un.UpdateData(en.UpdateDto{CreateDto: createNur}, readNurData, &event, tx); err != nil {
- return err
- }
- return nil
- }
-
- if _, err := un.CreateData(createNur, &event, tx); err != nil {
- return err
- }
- case ero.EPCNut:
- readNut := et.ReadDetailDto{Employee_Id: &data.Id}
- readNutData, err := ut.ReadDetailData(readNut, &event, tx)
- if err != nil {
- return err
- }
- createNut := et.CreateDto{
- Employee_Id: &data.Id,
- IHS_Number: input.IHS_Number,
- }
- if readNutData != nil {
- if err := ut.UpdateData(et.UpdateDto{CreateDto: createNut}, readNutData, &event, tx); err != nil {
- return err
- }
- return nil
- }
-
- if _, err := ut.CreateData(createNut, &event, tx); err != nil {
- return err
- }
- case ero.EPCPha:
- readPha := ep.ReadDetailDto{Employee_Id: &data.Id}
- readPhaData, err := up.ReadDetailData(readPha, &event, tx)
- if err != nil {
- return err
- }
- createPha := ep.CreateDto{
- Employee_Id: &data.Id,
- IHS_Number: input.IHS_Number,
- }
- if readPhaData != nil {
- if err := up.UpdateData(ep.UpdateDto{CreateDto: createPha}, readPhaData, &event, tx); err != nil {
- return err
- }
- return nil
- }
-
- if _, err := up.CreateData(createPha, &event, tx); err != nil {
- return err
- }
- }
-
pl.SetLogInfo(&event, nil, "complete")
mwRunner.setMwType(pu.MWTPost)
diff --git a/internal/use-case/main-use-case/employee/helper.go b/internal/use-case/main-use-case/employee/helper.go
index 949a4729..252d35eb 100644
--- a/internal/use-case/main-use-case/employee/helper.go
+++ b/internal/use-case/main-use-case/employee/helper.go
@@ -5,46 +5,39 @@ Any functions that are used internally by the use-case
package employee
import (
- "errors"
e "simrs-vx/internal/domain/main-entities/employee"
-
- uu "simrs-vx/internal/use-case/main-use-case/user"
- pl "simrs-vx/pkg/logger"
-
- "gorm.io/gorm"
)
func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Employee) {
var inputSrc *e.CreateDto
if inputT, ok := any(input).(*e.CreateDto); ok {
inputSrc = inputT
- data.User_Id = inputSrc.User_Id
} else {
inputTemp := any(input).(*e.UpdateDto)
inputSrc = &inputTemp.CreateDto
}
+ data.User_Id = inputSrc.User_Id
data.Person_Id = inputSrc.Person_Id
- data.Position_Code = inputSrc.Position_Code
data.Division_Code = inputSrc.Division_Code
data.Number = inputSrc.Number
data.Status_Code = inputSrc.Status_Code
}
-func createUser(input *e.CreateDto, event *pl.Event, tx *gorm.DB) error {
- if input.User == nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "user request is required",
- Raw: errors.New("user request is required"),
- }
- return pl.SetLogError(event, input)
- }
- user, err := uu.CreateData(*input.User, event, tx)
- if err != nil {
- return err
- }
- input.User_Id = &user.Id
- return nil
-}
+// func createUser(input *e.CreateDto, event *pl.Event, tx *gorm.DB) error {
+// if input.User == nil {
+// event.Status = "failed"
+// event.ErrInfo = pl.ErrorInfo{
+// Code: "data-create-fail",
+// Detail: "user request is required",
+// Raw: errors.New("user request is required"),
+// }
+// return pl.SetLogError(event, input)
+// }
+// user, err := uu.CreateData(*input.User, event, tx)
+// if err != nil {
+// return err
+// }
+// input.User_Id = &user.Id
+// return nil
+// }
diff --git a/internal/use-case/main-use-case/employee/lib.go b/internal/use-case/main-use-case/employee/lib.go
index 857c7d87..e36dacee 100644
--- a/internal/use-case/main-use-case/employee/lib.go
+++ b/internal/use-case/main-use-case/employee/lib.go
@@ -2,6 +2,8 @@ package employee
import (
e "simrs-vx/internal/domain/main-entities/employee"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -25,13 +27,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Employe
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -52,32 +48,21 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Em
tx = dg.I
}
- if len(input.Preloads) > 0 {
- for _, preload := range input.Preloads {
- tx = tx.Preload(preload)
- }
- }
-
tx = tx.
Model(&e.Employee{}).
+ Scopes(gh.Preload(input.Includes)).
Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-get-fail",
- Detail: "Database get failed",
- Raw: err,
- }
- return nil, nil, pl.SetLogError(event, input)
-
+ return nil, nil, plh.HandleListError(input, event, err)
}
+
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
@@ -102,7 +87,20 @@ func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e
tx = tx.Preload("Person.Contacts")
tx = tx.Preload("Person.Relatives")
- if err := tx.First(&data, input.Id).Error; err != nil {
+ if input.User_Id != nil {
+ tx = tx.Where("\"User_Id\" = ?", *input.User_Id)
+ }
+ if input.Person_Id != nil {
+ tx = tx.Where("\"Person_Id\" = ?", *input.Person_Id)
+ }
+ if input.Number != nil {
+ tx = tx.Where("\"Number\" = ?", *input.Number)
+ }
+ if input.Id != 0 {
+ tx = tx.Where("\"Id\" = ?", input.Id)
+ }
+
+ if err := tx.First(&data).Error; err != nil {
if processedErr := pu.HandleReadError(err, event, source, input.Id, data); processedErr != nil {
return nil, processedErr
}
@@ -159,3 +157,55 @@ func DeleteData(data *e.Employee, event *pl.Event, dbx ...*gorm.DB) error {
pl.SetLogInfo(event, nil, "complete")
return nil
}
+
+func CreateOrUpdate(input e.UpdateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Employee, error) {
+ pl.SetLogInfo(event, nil, "started", "DBCreateOrUpdate")
+
+ var tx *gorm.DB
+ if len(dbx) > 0 {
+ tx = dbx[0]
+ } else {
+ tx = dg.I
+ }
+
+ data := e.Employee{}
+
+ if input.Id > 0 {
+ if err := tx.Where("\"Id\" = ? AND \"User_Id\" = ?", input.Id, input.User_Id).First(&data).Error; err == nil {
+ setData(&input, &data)
+ 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 nil, pl.SetLogError(event, input)
+ }
+ return &data, nil
+ } else if err != gorm.ErrRecordNotFound {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-get-fail",
+ Detail: "Database get failed",
+ Raw: err,
+ }
+ return nil, pl.SetLogError(event, input)
+ }
+ return nil, nil
+ }
+
+ setData(&input, &data)
+ if err := tx.Create(&data).Error; err != nil {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-create-fail",
+ Detail: "Database insert failed",
+ Raw: err,
+ }
+ return nil, pl.SetLogError(event, input)
+ }
+
+ pl.SetLogInfo(event, nil, "complete")
+ return &data, nil
+}
diff --git a/internal/use-case/main-use-case/encounter/case.go b/internal/use-case/main-use-case/encounter/case.go
index 32c630f7..fad183f6 100644
--- a/internal/use-case/main-use-case/encounter/case.go
+++ b/internal/use-case/main-use-case/encounter/case.go
@@ -1,9 +1,25 @@
package encounter
import (
- e "simrs-vx/internal/domain/main-entities/encounter"
+ "errors"
"strconv"
+ ea "simrs-vx/internal/domain/main-entities/ambulatory"
+ ec "simrs-vx/internal/domain/main-entities/chemo"
+ ee "simrs-vx/internal/domain/main-entities/emergency"
+ eem "simrs-vx/internal/domain/main-entities/employee"
+ e "simrs-vx/internal/domain/main-entities/encounter"
+ ei "simrs-vx/internal/domain/main-entities/inpatient"
+
+ ua "simrs-vx/internal/use-case/main-use-case/ambulatory"
+ uc "simrs-vx/internal/use-case/main-use-case/chemo"
+ 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"
+
+ 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"
@@ -34,12 +50,76 @@ func Create(input e.CreateDto) (*d.Data, error) {
return err
}
+ if emp, err := uem.ReadDetailData(eem.ReadDetailDto{User_Id: &input.AuthInfo.User_Id}, &event, tx); err != nil {
+ return err
+ } else {
+ input.Adm_Employee_Id = &emp.Id
+ }
+
if resData, err := CreateData(input, &event, tx); err != nil {
return err
} else {
data = *resData
}
+ switch input.Class_Code {
+ case ere.ECAmbulatory:
+ subCode, err := ua.CheckClassCode(input.SubClass_Code)
+ if err != nil {
+ return err
+ }
+ ambCreate := ea.CreateDto{
+ Encounter_Id: &data.Id,
+ Class_Code: subCode,
+ }
+ _, err = ua.CreateData(ambCreate, &event, tx)
+ if err != nil {
+ return err
+ }
+
+ if subCode == ere.ACCCac || subCode == ere.ACCCad {
+ chemoCreate := ec.CreateDto{
+ Encounter_Id: &data.Id,
+ Status_Code: erc.DVCNew,
+ SrcUnit_Id: input.Unit_Id,
+ }
+
+ _, err = uc.CreateData(chemoCreate, &event, tx)
+ if err != nil {
+ return err
+ }
+ }
+ case ere.ECEmergency:
+ subCode, err := ue.CheckClassCode(input.SubClass_Code)
+ if err != nil {
+ return err
+ }
+ emerCreate := ee.CreateDto{
+ Encounter_Id: &data.Id,
+ Class_Code: subCode,
+ }
+ _, err = ue.CreateData(emerCreate, &event, tx)
+ if err != nil {
+ return err
+ }
+ case ere.ECInpatient:
+ subCode, err := ui.CheckClassCode(input.SubClass_Code)
+ if err != nil {
+ return err
+ }
+ inpCreate := ei.CreateDto{
+ Encounter_Id: &data.Id,
+ Class_Code: subCode,
+ Infra_Id: input.Infra_Id,
+ }
+ _, err = ui.CreateData(inpCreate, &event, tx)
+ if err != nil {
+ return err
+ }
+ default:
+ return errors.New("invalid encounter class code")
+ }
+
mwRunner.setMwType(pu.MWTPost)
// Run post-middleware
if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil {
@@ -106,12 +186,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
@@ -165,7 +246,7 @@ func ReadDetail(input e.ReadDetailDto) (*d.Data, error) {
}
func Update(input e.UpdateDto) (*d.Data, error) {
- rdDto := e.ReadDetailDto{Id: input.Id}
+ rdDto := e.ReadDetailDto{Id: uint16(input.Id)}
var data *e.Encounter
var err error
@@ -183,6 +264,16 @@ func Update(input e.UpdateDto) (*d.Data, error) {
return err
}
+ if data.IsDone() {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-state-mismatch",
+ Detail: "encounter is done",
+ Raw: errors.New("encounter is done"),
+ }
+ return pl.SetLogError(&event, input)
+ }
+
mwRunner := newMiddlewareRunner(&event, tx)
mwRunner.setMwType(pu.MWTPre)
// Run pre-middleware
@@ -221,7 +312,7 @@ func Update(input e.UpdateDto) (*d.Data, error) {
}
func Delete(input e.DeleteDto) (*d.Data, error) {
- rdDto := e.ReadDetailDto{Id: input.Id}
+ rdDto := e.ReadDetailDto{Id: uint16(input.Id)}
var data *e.Encounter
var err error
@@ -273,3 +364,134 @@ func Delete(input e.DeleteDto) (*d.Data, error) {
}, nil
}
+
+func CheckOut(input e.DischargeDto) (*d.Data, error) {
+ rdDto := e.ReadDetailDto{Id: uint16(input.Id)}
+ var data *e.Encounter
+ var err error
+
+ event := pl.Event{
+ Feature: "CheckOut",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "checkOut")
+
+ err = dg.I.Transaction(func(tx *gorm.DB) error {
+ pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail")
+ if data, err = ReadDetailData(rdDto, &event, tx); err != nil {
+ return err
+ }
+
+ if data.IsDone() {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-state-mismatch",
+ Detail: "encounter is done",
+ Raw: errors.New("encounter is done"),
+ }
+ return pl.SetLogError(&event, input)
+ }
+ if err := checkSoapiByDocExists(data.Id, &event, tx); err != nil {
+ return err
+ }
+
+ if err := updateDischargeData(input, data, &event, tx); err != nil {
+ return err
+ }
+
+ if err := checkNewOrdersExist(data.Id, &event, tx); err != nil {
+ return err
+ }
+
+ if err := createMedication(data.Id, &event, tx); err != nil {
+ if !pu.IsDataNotFoundError(err) {
+ return err
+ }
+ }
+
+ pl.SetLogInfo(&event, nil, "complete")
+
+ return nil
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &d.Data{
+ Meta: d.IS{
+ "source": source,
+ "structure": "single-data",
+ "status": "checkOut",
+ },
+ Data: data.ToResponse(),
+ }, nil
+}
+
+func UpdateStatusCode(input e.UpdateStatusDto) (*d.Data, error) {
+ rdDto := e.ReadDetailDto{Id: input.Id}
+ var data *e.Encounter
+ var err error
+
+ event := pl.Event{
+ Feature: "Update Status Code",
+ 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
+ }
+
+ if data.IsDone() {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-state-mismatch",
+ Detail: "encounter is done",
+ Raw: errors.New("encounter is done"),
+ }
+ return pl.SetLogError(&event, input)
+ }
+
+ mwRunner := newMiddlewareRunner(&event, tx)
+ mwRunner.setMwType(pu.MWTPre)
+ // Run pre-middleware
+ if err := mwRunner.RunUpdateMiddleware(readDetailPreMw, &rdDto, data); err != nil {
+ return err
+ }
+
+ if err := UpdateStatusData(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
+
+}
diff --git a/internal/use-case/main-use-case/encounter/helper.go b/internal/use-case/main-use-case/encounter/helper.go
index ede229f4..e0d209db 100644
--- a/internal/use-case/main-use-case/encounter/helper.go
+++ b/internal/use-case/main-use-case/encounter/helper.go
@@ -5,7 +5,38 @@ Any functions that are used internally by the use-case
package encounter
import (
+ "errors"
+ "fmt"
+ "strings"
+
e "simrs-vx/internal/domain/main-entities/encounter"
+ es "simrs-vx/internal/domain/main-entities/soapi"
+
+ edo "simrs-vx/internal/domain/main-entities/device-order"
+ 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"
+ emei "simrs-vx/internal/domain/main-entities/medication-item"
+ emi "simrs-vx/internal/domain/main-entities/medicine-mix"
+ 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"
+
+ // udo "simrs-vx/internal/use-case/main-use-case/device-order"
+ um "simrs-vx/internal/use-case/main-use-case/medication"
+ umei "simrs-vx/internal/use-case/main-use-case/medication-item"
+ umi "simrs-vx/internal/use-case/main-use-case/medicine-mix"
+ ummi "simrs-vx/internal/use-case/main-use-case/medicine-mix-item"
+ up "simrs-vx/internal/use-case/main-use-case/prescription"
+ upi "simrs-vx/internal/use-case/main-use-case/prescription-item"
+
+ pl "simrs-vx/pkg/logger"
+ pu "simrs-vx/pkg/use-case-helper"
+
+ erc "simrs-vx/internal/domain/references/common"
+ erg "simrs-vx/internal/domain/references/organization"
+
+ "gorm.io/gorm"
)
func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Encounter) {
@@ -21,9 +52,269 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Encounter) {
data.RegisteredAt = inputSrc.RegisteredAt
data.Class_Code = inputSrc.Class_Code
data.Unit_Id = inputSrc.Unit_Id
+ data.Specialist_Id = inputSrc.Specialist_Id
+ data.Subspecialist_Id = inputSrc.Subspecialist_Id
data.VisitDate = inputSrc.VisitDate
- data.Assignment_Doctor_Id = inputSrc.Assignment_Doctor_Id
+ data.PaymentMethod_Code = inputSrc.PaymentMethod_Code
+ data.InsuranceCompany_Id = inputSrc.InsuranceCompany_Id
+ data.Member_Number = inputSrc.Member_Number
+ data.Ref_Number = inputSrc.Ref_Number
+ data.Trx_Number = inputSrc.Trx_Number
+ data.Appointment_Doctor_Id = inputSrc.Appointment_Doctor_Id
+ data.Adm_Employee_Id = inputSrc.Adm_Employee_Id
data.Responsible_Doctor_Id = inputSrc.Responsible_Doctor_Id
- data.DischardeMethod_Code = inputSrc.DischardeMethod_Code
data.RefSource_Name = inputSrc.RefSource_Name
+ data.Appointment_Id = inputSrc.Appointment_Id
+ data.Status_Code = erc.DSCProcess
+}
+
+func setDataUpdate(src e.UpdateDto, dst *e.Encounter) {
+ dst.Appointment_Doctor_Id = src.Appointment_Doctor_Id
+ dst.Responsible_Doctor_Id = src.Responsible_Doctor_Id
+ dst.Unit_Id = src.Unit_Id
+ dst.Specialist_Id = src.Specialist_Id
+ dst.Subspecialist_Id = src.Subspecialist_Id
+ dst.VisitDate = src.VisitDate
+}
+
+func setDataDischarge(src e.DischargeDto, dst *e.Encounter) {
+ dst.DischargeMethod_Code = src.DischargeMethod_Code
+ dst.EarlyEducation = src.EarlyEducation
+ dst.MedicalDischargeEducation = src.MedicalDischargeEducation
+ dst.AdmDischargeEducation = src.AdmDischargeEducation
+ dst.DischargeReason = src.DischargeReason
+ dst.Status_Code = erc.DSCDone
+}
+
+func checkSoapiByDocExists(encounter_id uint, event *pl.Event, tx *gorm.DB) error {
+ pl.SetLogInfo(event, nil, "started", "checkSoapiByDocExists")
+ var soapies []es.Soapi
+ err := tx.
+ Preload("Employee").
+ Preload("Employee.User").
+ Where("\"Encounter_Id\" = ?", encounter_id).Find(&soapies).Error
+ if err != nil {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-get-fail",
+ Detail: "get soapi failed",
+ Raw: err,
+ }
+ return pl.SetLogError(event, nil)
+ }
+
+ if len(soapies) == 0 {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-notFound",
+ Detail: "no soapi found for encounter",
+ Raw: errors.New("soapi not found"),
+ }
+ return pl.SetLogError(event, nil)
+ }
+
+ for _, s := range soapies {
+ if s.Employee != nil && s.Employee.User != nil && s.Employee.Position_Code == erg.UPCDoc {
+ return nil
+ }
+ }
+
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-update-fail",
+ Detail: "no soapi written by a doctor found",
+ Raw: errors.New("all soapi employees are not doctors"),
+ }
+ return pl.SetLogError(event, nil)
+}
+
+func createMedication(encounter_id uint, event *pl.Event, tx *gorm.DB) error {
+ pl.SetLogInfo(event, nil, "started", "createMedication")
+
+ prescription, err := up.ReadDetailData(ep.ReadDetailDto{Encounter_Id: &encounter_id}, event, tx)
+ if err != nil {
+ return err
+ }
+
+ prescriptionItem, _, err := upi.ReadListData(epi.ReadListDto{FilterDto: epi.FilterDto{Prescription_Id: &prescription.Id}}, event, tx)
+ if err != nil {
+ return err
+ }
+
+ if len(prescriptionItem) == 0 {
+ return nil
+ }
+
+ medicationCreate := em.CreateDto{
+ Encounter_Id: &encounter_id,
+ IssuedAt: pu.GetTimeNow(),
+ Status_Code: erc.DSCNew,
+ }
+ medication, err := um.CreateData(medicationCreate, event, tx)
+ if err != nil {
+ return err
+ }
+
+ for _, prescriptionItem := range prescriptionItem {
+ if prescriptionItem.IsMix {
+ medMix_id, err := createMedicineMixAndItem(*prescriptionItem.MedicineMix, event, tx)
+ if err != nil {
+ return err
+ }
+ prescriptionItem.MedicineMix_Id = medMix_id
+ }
+ err := createMedicationItem(medication.Id, prescriptionItem, event, tx)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func createMedicineMixAndItem(input emi.MedicineMix, event *pl.Event, tx *gorm.DB) (*uint, error) {
+ pl.SetLogInfo(event, nil, "started", "createMedicineMix")
+
+ medicineMixCreate := emi.CreateDto{
+ Name: input.Name,
+ Uom_Code: input.Uom_Code,
+ }
+ medicineMix, err := umi.CreateData(medicineMixCreate, event, tx)
+ if err != nil {
+ return nil, err
+ }
+
+ // recreate medicineMixItem with new medicineMix_id to keep medMixItem remain the same for prescriptionItem that is created
+ for _, medicineMixItem := range input.MixItems {
+ medicineMixItemCreate := emmi.CreateDto{
+ MedicineMix_Id: &medicineMix.Id,
+ Medicine_Id: medicineMixItem.Medicine_Id,
+ Dose: medicineMixItem.Dose,
+ }
+ _, err := ummi.CreateData(medicineMixItemCreate, event, tx)
+ if err != nil {
+ return nil, err
+ }
+
+ }
+ return &medicineMix.Id, nil
+}
+
+func createMedicationItem(medication_id uint, input epi.PrescriptionItem, event *pl.Event, tx *gorm.DB) error {
+ pl.SetLogInfo(event, nil, "started", "createMedicationItem")
+
+ medicationItemCreate := emei.CreateDto{
+ Medication_Id: &medication_id,
+ IsMix: input.IsMix,
+ Medicine_Id: input.Medicine_Id,
+ MedicineMix_Id: input.MedicineMix_Id,
+ Usage: input.Usage,
+ Interval: input.Interval,
+ IntervalUnit_Code: input.IntervalUnit_Code,
+ Quantity: input.Quantity,
+ }
+
+ _, err := umei.CreateData(medicationItemCreate, event, tx)
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func checkNewOrdersExist(encounter_id uint, event *pl.Event, tx *gorm.DB) error {
+ pl.SetLogInfo(event, nil, "started", "CheckNewOrdersExist")
+ var errs []string
+ if err := getDeviceOrders(encounter_id, event, tx); err != nil {
+ errs = append(errs, err.Error())
+ }
+
+ if err := getMaterialOrders(encounter_id, event, tx); err != nil {
+ errs = append(errs, err.Error())
+ }
+
+ if err := getMcuOrders(encounter_id, event, tx); err != nil {
+ errs = append(errs, err.Error())
+ }
+
+ if len(errs) > 0 {
+ return fmt.Errorf("encounter has open orders: %s", strings.Join(errs, "; "))
+ }
+
+ return nil
+}
+
+func getDeviceOrders(encounter_id uint, event *pl.Event, tx *gorm.DB) error {
+ pl.SetLogInfo(event, nil, "started", "getDeviceOrders")
+ var orders []edo.DeviceOrder
+ err := tx.Where("\"Encounter_Id\" = ? AND \"Status_Code\" = ?", encounter_id, erc.DSCNew).Find(&orders).Error
+ if err != nil {
+ if err == gorm.ErrRecordNotFound {
+ return nil
+ }
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-get-fail",
+ Detail: "get device order failed",
+ Raw: err,
+ }
+ return pl.SetLogError(event, nil)
+ }
+
+ if len(orders) > 0 {
+ return fmt.Errorf("encounter has %d device orders", len(orders))
+ }
+
+ return nil
+}
+
+func getMaterialOrders(encounter_id uint, event *pl.Event, tx *gorm.DB) error {
+ pl.SetLogInfo(event, nil, "started", "getMaterialOrders")
+ var orders []emo.MaterialOrder
+ err := tx.Where("\"Encounter_Id\" = ? AND \"Status_Code\" = ?", encounter_id, erc.DSCNew).Find(&orders).Error
+ if err != nil {
+ if err == gorm.ErrRecordNotFound {
+ return nil
+ }
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-get-fail",
+ Detail: "get material order failed",
+ Raw: err,
+ }
+ return pl.SetLogError(event, nil)
+ }
+
+ if len(orders) > 0 {
+ return fmt.Errorf("encounter has %d material orders", len(orders))
+ }
+
+ return nil
+}
+
+func getMcuOrders(encounter_id uint, event *pl.Event, tx *gorm.DB) error {
+ pl.SetLogInfo(event, nil, "started", "getMcuOrders")
+ var orders []emco.McuOrder
+ err := tx.Where("\"Encounter_Id\" = ? AND \"Status_Code\" = ?", encounter_id, erc.DSCNew).Find(&orders).Error
+ if err != nil {
+ if err == gorm.ErrRecordNotFound {
+ return nil
+ }
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-get-fail",
+ Detail: "get mcu order failed",
+ Raw: err,
+ }
+ return pl.SetLogError(event, nil)
+ }
+
+ if len(orders) > 0 {
+ return fmt.Errorf("encounter has %d mcu orders", len(orders))
+ }
+
+ return nil
+}
+
+func setDataUpdateStatus(src e.UpdateStatusDto, dst *e.Encounter) {
+ dst.Status_Code = src.StatusCode
}
diff --git a/internal/use-case/main-use-case/encounter/lib.go b/internal/use-case/main-use-case/encounter/lib.go
index dec500de..2f4d69fa 100644
--- a/internal/use-case/main-use-case/encounter/lib.go
+++ b/internal/use-case/main-use-case/encounter/lib.go
@@ -2,6 +2,8 @@ package encounter
import (
e "simrs-vx/internal/domain/main-entities/encounter"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Encount
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -53,24 +49,19 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.En
tx = tx.
Model(&e.Encounter{}).
- Scopes(gh.Filter(input)).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-get-fail",
- Detail: "Database get failed",
- Raw: err,
- }
- return nil, nil, pl.SetLogError(event, input)
-
+ return nil, nil, plh.HandleListError(input, event, err)
}
+
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
@@ -102,7 +93,7 @@ func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e
func UpdateData(input e.UpdateDto, data *e.Encounter, event *pl.Event, dbx ...*gorm.DB) error {
pl.SetLogInfo(event, data, "started", "DBUpdate")
- setData(&input, data)
+ setDataUpdate(input, data)
var tx *gorm.DB
if len(dbx) > 0 {
@@ -147,3 +138,77 @@ func DeleteData(data *e.Encounter, event *pl.Event, dbx ...*gorm.DB) error {
pl.SetLogInfo(event, nil, "complete")
return nil
}
+
+func updateDischargeData(input e.DischargeDto, data *e.Encounter, event *pl.Event, dbx ...*gorm.DB) error {
+ pl.SetLogInfo(event, data, "started", "DBUpdateDischarge")
+ setDataDischarge(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 IsDone(encounter_id uint, event *pl.Event, dbx ...*gorm.DB) bool {
+ pl.SetLogInfo(event, nil, "started", "DBIsDone")
+ var tx *gorm.DB
+ if len(dbx) > 0 {
+ tx = dbx[0]
+ } else {
+ tx = dg.I
+ }
+
+ var data e.Encounter
+ if err := tx.Where("\"Id\" = ?", encounter_id).First(&data).Error; err != nil {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-get-fail",
+ Detail: "Database get failed",
+ Raw: err,
+ }
+ return false
+ }
+
+ pl.SetLogInfo(event, nil, "complete")
+ return data.IsDone()
+}
+
+func UpdateStatusData(input e.UpdateStatusDto, data *e.Encounter, event *pl.Event, dbx ...*gorm.DB) error {
+ pl.SetLogInfo(event, data, "started", "DBUpdate")
+ setDataUpdateStatus(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
+}
diff --git a/internal/use-case/main-use-case/ethnic/case.go b/internal/use-case/main-use-case/ethnic/case.go
index adf50f44..c8ca95a1 100644
--- a/internal/use-case/main-use-case/ethnic/case.go
+++ b/internal/use-case/main-use-case/ethnic/case.go
@@ -106,12 +106,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
diff --git a/internal/use-case/main-use-case/ethnic/lib.go b/internal/use-case/main-use-case/ethnic/lib.go
index 96921640..0bc91e3f 100644
--- a/internal/use-case/main-use-case/ethnic/lib.go
+++ b/internal/use-case/main-use-case/ethnic/lib.go
@@ -2,6 +2,8 @@ package ethnic
import (
e "simrs-vx/internal/domain/main-entities/ethnic"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Ethnic,
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -53,24 +49,19 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Et
tx = tx.
Model(&e.Ethnic{}).
- Scopes(gh.Filter(input)).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
- Order("\"CreatedAt\" DESC")
+ Scopes(gh.Sort(input.Sort))
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-get-fail",
- Detail: "Database get failed",
- Raw: err,
- }
- return nil, nil, pl.SetLogError(event, input)
-
+ return nil, nil, plh.HandleListError(input, event, err)
}
+
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
diff --git a/internal/use-case/main-use-case/infra/case.go b/internal/use-case/main-use-case/infra/case.go
index e95e09d3..7c227e8b 100644
--- a/internal/use-case/main-use-case/infra/case.go
+++ b/internal/use-case/main-use-case/infra/case.go
@@ -58,6 +58,13 @@ func Create(input e.CreateDto) (*d.Data, error) {
data = *resData
}
+ if input.InfraGroup_Code == ero.IFGCRoom {
+ input.Infra_Id = &data.Id
+ if err := createRoom(&input, &event, tx); err != nil {
+ return err
+ }
+ }
+
mwRunner.setMwType(pu.MWTPost)
// Run post-middleware
if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil {
@@ -105,9 +112,6 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
return err
}
- if len(input.Includes) > 0 {
- input.Preloads = pu.GetPreloads(input.Includes)
- }
if dataList, metaList, err = ReadListData(input, &event, tx); err != nil {
return err
}
@@ -127,12 +131,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
diff --git a/internal/use-case/main-use-case/infra/helper.go b/internal/use-case/main-use-case/infra/helper.go
index 00057eee..35388c85 100644
--- a/internal/use-case/main-use-case/infra/helper.go
+++ b/internal/use-case/main-use-case/infra/helper.go
@@ -7,8 +7,10 @@ package infra
import (
e "simrs-vx/internal/domain/main-entities/infra"
ei "simrs-vx/internal/domain/main-entities/item"
+ er "simrs-vx/internal/domain/main-entities/room"
ero "simrs-vx/internal/domain/references/organization"
ui "simrs-vx/internal/use-case/main-use-case/item"
+ ur "simrs-vx/internal/use-case/main-use-case/room"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -36,7 +38,11 @@ func createItem(input *e.CreateDto, event *pl.Event, tx *gorm.DB) error {
Code: pu.AddPrefix("inf-", input.Code),
Name: input.Name,
ItemGroup_Code: ero.ITGCInfra,
- Infra_Id: input.Parent_Id,
+ Uom_Code: func() *string {
+ tmp := "unit"
+ return &tmp
+ }(),
+ Infra_Id: input.Parent_Id,
}
item, err := ui.CreateData(itemCreate, event, tx)
if err != nil {
@@ -46,3 +52,17 @@ func createItem(input *e.CreateDto, event *pl.Event, tx *gorm.DB) error {
input.Item_Id = &item.Id
return nil
}
+
+func createRoom(input *e.CreateDto, event *pl.Event, tx *gorm.DB) error {
+ roomCreate := er.CreateDto{
+ Infra_Id: input.Infra_Id,
+ Unit_Id: input.Unit_Id,
+ Specialist_Id: input.Specialist_Id,
+ Subspecialist_Id: input.Subspecialist_Id,
+ }
+ _, err := ur.CreateData(roomCreate, event, tx)
+ if err != nil {
+ return err
+ }
+ return nil
+}
diff --git a/internal/use-case/main-use-case/infra/lib.go b/internal/use-case/main-use-case/infra/lib.go
index d4ec76d0..234104bb 100644
--- a/internal/use-case/main-use-case/infra/lib.go
+++ b/internal/use-case/main-use-case/infra/lib.go
@@ -2,6 +2,8 @@ package infra
import (
e "simrs-vx/internal/domain/main-entities/infra"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Infra,
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -51,32 +47,31 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.In
tx = dg.I
}
- if len(input.Preloads) > 0 {
- for _, preload := range input.Preloads {
- tx = tx.Preload(preload)
- }
+ if input.OnlyHaveChildren {
+ tx = tx.Where(`
+ EXISTS (
+ SELECT 1
+ FROM "Infra" c
+ WHERE c."Parent_Id" = "Infra"."Id"
+ )
+ `)
}
tx = tx.
Model(&e.Infra{}).
+ Scopes(gh.Preload(input.Includes)).
Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
- Order("\"CreatedAt\" DESC")
+ Scopes(gh.Sort(input.Sort))
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-get-fail",
- Detail: "Database get failed",
- Raw: err,
- }
- return nil, nil, pl.SetLogError(event, input)
-
+ return nil, nil, plh.HandleListError(input, event, err)
}
+
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
@@ -96,6 +91,14 @@ func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e
tx = dg.I
}
+ tx = tx.Preload("Parent").
+ Preload("Childrens").
+ Preload("Item").
+ Preload("Rooms").
+ Preload("Rooms.Specialist").
+ Preload("Rooms.Subspecialist").
+ Preload("Rooms.Unit")
+
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
@@ -116,6 +119,10 @@ func UpdateData(input e.UpdateDto, data *e.Infra, event *pl.Event, dbx ...*gorm.
} else {
tx = dg.I
}
+ data.Parent = nil
+ data.Childrens = nil
+ data.Item = nil
+ data.Rooms = nil
if err := tx.Save(&data).Error; err != nil {
event.Status = "failed"
diff --git a/internal/use-case/main-use-case/inpatient/case.go b/internal/use-case/main-use-case/inpatient/case.go
new file mode 100644
index 00000000..05982b0d
--- /dev/null
+++ b/internal/use-case/main-use-case/inpatient/case.go
@@ -0,0 +1,276 @@
+package inpatient
+
+import (
+ e "simrs-vx/internal/domain/main-entities/inpatient"
+ "strconv"
+
+ dg "github.com/karincake/apem/db-gorm-pg"
+ d "github.com/karincake/dodol"
+
+ pl "simrs-vx/pkg/logger"
+ pu "simrs-vx/pkg/use-case-helper"
+
+ "gorm.io/gorm"
+)
+
+const source = "ambulatory"
+
+func Create(input e.CreateDto) (*d.Data, error) {
+ data := e.Inpatient{}
+
+ event := pl.Event{
+ Feature: "Create",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "create")
+
+ err := dg.I.Transaction(func(tx *gorm.DB) error {
+ mwRunner := newMiddlewareRunner(&event, tx)
+ mwRunner.setMwType(pu.MWTPre)
+ // Run pre-middleware
+ if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil {
+ return err
+ }
+
+ if resData, err := CreateData(input, &event, tx); err != nil {
+ return err
+ } else {
+ data = *resData
+ }
+
+ mwRunner.setMwType(pu.MWTPost)
+ // Run post-middleware
+ if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil {
+ return err
+ }
+
+ pl.SetLogInfo(&event, nil, "complete")
+
+ return nil
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &d.Data{
+ Meta: d.II{
+ "source": source,
+ "structure": "single-data",
+ "status": "created",
+ },
+ Data: data.ToResponse(),
+ }, nil
+}
+
+func ReadList(input e.ReadListDto) (*d.Data, error) {
+ var data *e.Inpatient
+ var dataList []e.Inpatient
+ 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.Inpatient
+ 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: uint16(input.Id)}
+ var data *e.Inpatient
+ 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: uint16(input.Id)}
+ var data *e.Inpatient
+ 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/inpatient/helper.go b/internal/use-case/main-use-case/inpatient/helper.go
new file mode 100644
index 00000000..45014af1
--- /dev/null
+++ b/internal/use-case/main-use-case/inpatient/helper.go
@@ -0,0 +1,38 @@
+/*
+DESCRIPTION:
+Any functions that are used internally by the use-case
+*/
+package inpatient
+
+import (
+ "errors"
+ e "simrs-vx/internal/domain/main-entities/inpatient"
+
+ ere "simrs-vx/internal/domain/references/encounter"
+)
+
+func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Inpatient) {
+ 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.Class_Code = inputSrc.Class_Code
+}
+
+func CheckClassCode(input *string) (ere.InpatientClassCode, error) {
+ if input != nil {
+ subCode := ere.InpatientClassCode(*input)
+ switch subCode {
+ case ere.ICCHCU, ere.ICCICU, ere.ICCVK, ere.ICCIp:
+ return subCode, nil
+ default:
+ return "", errors.New("unknown sub class code")
+ }
+ }
+ return "", errors.New("sub class code is nil")
+}
diff --git a/internal/use-case/main-use-case/inpatient/lib.go b/internal/use-case/main-use-case/inpatient/lib.go
new file mode 100644
index 00000000..157fe511
--- /dev/null
+++ b/internal/use-case/main-use-case/inpatient/lib.go
@@ -0,0 +1,140 @@
+package inpatient
+
+import (
+ e "simrs-vx/internal/domain/main-entities/inpatient"
+
+ 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.Inpatient, error) {
+ pl.SetLogInfo(event, nil, "started", "DBCreate")
+
+ data := e.Inpatient{}
+ 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.Inpatient, *e.MetaDto, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadList")
+ data := []e.Inpatient{}
+ 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.Inpatient{}).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
+ Count(&count).
+ Scopes(gh.Paginate(input, &pagination)).
+ Order("\"CreatedAt\" DESC")
+
+ if err := tx.Find(&data).Error; err != nil {
+ if err == gorm.ErrRecordNotFound {
+ return nil, &meta, nil
+ }
+ return nil, nil, plh.HandleListError(input, event, err)
+ }
+
+ meta.Count = int(count)
+ meta.PageNumber = pagination.PageNumber
+ meta.PageSize = pagination.PageSize
+
+ pl.SetLogInfo(event, nil, "complete")
+ return data, &meta, nil
+}
+
+func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.Inpatient, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadDetail")
+ data := e.Inpatient{}
+
+ 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.Inpatient, 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.Inpatient, 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/inpatient/middleware-runner.go b/internal/use-case/main-use-case/inpatient/middleware-runner.go
new file mode 100644
index 00000000..5f771f5a
--- /dev/null
+++ b/internal/use-case/main-use-case/inpatient/middleware-runner.go
@@ -0,0 +1,103 @@
+package inpatient
+
+import (
+ e "simrs-vx/internal/domain/main-entities/inpatient"
+ 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.Inpatient) 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.Inpatient) 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.Inpatient) 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.Inpatient) 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.Inpatient) 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/inpatient/middleware.go b/internal/use-case/main-use-case/inpatient/middleware.go
new file mode 100644
index 00000000..017be42d
--- /dev/null
+++ b/internal/use-case/main-use-case/inpatient/middleware.go
@@ -0,0 +1,9 @@
+package inpatient
+
+// 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/inpatient/tycovar.go b/internal/use-case/main-use-case/inpatient/tycovar.go
new file mode 100644
index 00000000..209477ff
--- /dev/null
+++ b/internal/use-case/main-use-case/inpatient/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 inpatient
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/main-entities/inpatient"
+)
+
+type createMw struct {
+ Name string
+ Func func(input *e.CreateDto, data *e.Inpatient, tx *gorm.DB) error
+}
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.Inpatient, tx *gorm.DB) error
+}
+
+type readDetailMw struct {
+ Name string
+ Func func(input *e.ReadDetailDto, data *e.Inpatient, 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/case.go b/internal/use-case/main-use-case/installation/case.go
index 6de77882..5e1339da 100644
--- a/internal/use-case/main-use-case/installation/case.go
+++ b/internal/use-case/main-use-case/installation/case.go
@@ -106,12 +106,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
diff --git a/internal/use-case/main-use-case/installation/lib.go b/internal/use-case/main-use-case/installation/lib.go
index 0cd9a6dc..fd0158ee 100644
--- a/internal/use-case/main-use-case/installation/lib.go
+++ b/internal/use-case/main-use-case/installation/lib.go
@@ -2,6 +2,8 @@ package installation
import (
e "simrs-vx/internal/domain/main-entities/installation"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Install
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -53,24 +49,19 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.In
tx = tx.
Model(&e.Installation{}).
- Scopes(gh.Filter(input)).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
- Order("\"CreatedAt\" DESC")
+ Scopes(gh.Sort(input.Sort))
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-get-fail",
- Detail: "Database get failed",
- Raw: err,
- }
- return nil, nil, pl.SetLogError(event, input)
-
+ return nil, nil, plh.HandleListError(input, event, err)
}
+
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
diff --git a/internal/use-case/main-use-case/insurance-company/case.go b/internal/use-case/main-use-case/insurance-company/case.go
index a981339d..29aed939 100644
--- a/internal/use-case/main-use-case/insurance-company/case.go
+++ b/internal/use-case/main-use-case/insurance-company/case.go
@@ -87,9 +87,6 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
return err
}
- if len(input.Includes) > 0 {
- input.Preloads = pu.GetPreloads(input.Includes)
- }
if dataList, metaList, err = ReadListData(input, &event, tx); err != nil {
return err
}
@@ -109,12 +106,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
diff --git a/internal/use-case/main-use-case/insurance-company/lib.go b/internal/use-case/main-use-case/insurance-company/lib.go
index 15073715..262a99d9 100644
--- a/internal/use-case/main-use-case/insurance-company/lib.go
+++ b/internal/use-case/main-use-case/insurance-company/lib.go
@@ -2,6 +2,8 @@ package insurancecompany
import (
e "simrs-vx/internal/domain/main-entities/insurance-company"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Insuran
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -51,32 +47,21 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.In
tx = dg.I
}
- if len(input.Preloads) > 0 {
- for _, preload := range input.Preloads {
- tx = tx.Preload(preload)
- }
- }
-
tx = tx.
Model(&e.InsuranceCompany{}).
+ Scopes(gh.Preload(input.Includes)).
Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
- Order("\"CreatedAt\" DESC")
+ Scopes(gh.Sort(input.Sort))
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-get-fail",
- Detail: "Database get failed",
- Raw: err,
- }
- return nil, nil, pl.SetLogError(event, input)
-
+ return nil, nil, plh.HandleListError(input, event, err)
}
+
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
diff --git a/internal/use-case/main-use-case/internal-reference/case.go b/internal/use-case/main-use-case/internal-reference/case.go
new file mode 100644
index 00000000..1681bf26
--- /dev/null
+++ b/internal/use-case/main-use-case/internal-reference/case.go
@@ -0,0 +1,324 @@
+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"
+
+ dg "github.com/karincake/apem/db-gorm-pg"
+ d "github.com/karincake/dodol"
+ "gorm.io/gorm"
+)
+
+const source = "internal-reference"
+
+func Create(input eir.CreateDto) (*d.Data, error) {
+ data := eir.InternalReference{}
+
+ 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 Request
+ if err := validateRequest(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 eir.ReadListDto) (*d.Data, error) {
+ var data *eir.InternalReference
+ var dataList []eir.InternalReference
+ var metaList *eir.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: eir.ToResponseList(dataList),
+ }, nil
+}
+
+func ReadDetail(input eir.ReadDetailDto) (*d.Data, error) {
+ var data *eir.InternalReference
+ 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 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
+ 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
+ }
+
+ // 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)
+ // 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 eir.DeleteDto) (*d.Data, error) {
+ rdDto := eir.ReadDetailDto{Id: input.Id}
+ var data *eir.InternalReference
+ 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/internal-reference/helper.go b/internal/use-case/main-use-case/internal-reference/helper.go
new file mode 100644
index 00000000..aaef382a
--- /dev/null
+++ b/internal/use-case/main-use-case/internal-reference/helper.go
@@ -0,0 +1,23 @@
+/*
+DESCRIPTION:
+Any functions that are used internally by the use-case
+*/
+package internal_reference
+
+import (
+ ir "simrs-vx/internal/domain/main-entities/internal-reference"
+)
+
+func setData[T *ir.CreateDto | *ir.UpdateDto](input T, data *ir.InternalReference) {
+ var inputSrc *ir.CreateDto
+ if inputT, ok := any(input).(*ir.CreateDto); ok {
+ inputSrc = inputT
+ } else {
+ inputTemp := any(input).(*ir.UpdateDto)
+ inputSrc = &inputTemp.CreateDto
+ }
+
+ data.Encounter_Id = inputSrc.Encounter_Id
+ data.Unit_Id = inputSrc.Unit_Id
+ data.Doctor_Id = inputSrc.Doctor_Id
+}
diff --git a/internal/use-case/main-use-case/internal-reference/lib.go b/internal/use-case/main-use-case/internal-reference/lib.go
new file mode 100644
index 00000000..a50d594c
--- /dev/null
+++ b/internal/use-case/main-use-case/internal-reference/lib.go
@@ -0,0 +1,144 @@
+package internal_reference
+
+import (
+ "errors"
+ eir "simrs-vx/internal/domain/main-entities/internal-reference"
+ 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 eir.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*eir.InternalReference, error) {
+ pl.SetLogInfo(event, nil, "started", "DBCreate")
+
+ data := eir.InternalReference{}
+ 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 eir.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]eir.InternalReference, *eir.MetaDto, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadList")
+ data := []eir.InternalReference{}
+ pagination := gh.Pagination{}
+ count := int64(0)
+ meta := eir.MetaDto{}
+
+ var tx *gorm.DB
+ if len(dbx) > 0 {
+ tx = dbx[0]
+ } else {
+ tx = dg.I
+ }
+
+ tx = tx.
+ Model(&eir.InternalReference{}).
+ 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 eir.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*eir.InternalReference, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadDetail")
+ data := eir.InternalReference{}
+
+ 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 eir.UpdateDto, data *eir.InternalReference, 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 *eir.InternalReference, 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/internal-reference/middleware-runner.go b/internal/use-case/main-use-case/internal-reference/middleware-runner.go
new file mode 100644
index 00000000..f677b66f
--- /dev/null
+++ b/internal/use-case/main-use-case/internal-reference/middleware-runner.go
@@ -0,0 +1,103 @@
+package internal_reference
+
+import (
+ ir "simrs-vx/internal/domain/main-entities/internal-reference"
+ 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 *ir.CreateDto, data *ir.InternalReference) 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 *ir.ReadListDto, data *ir.InternalReference) 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 *ir.ReadDetailDto, data *ir.InternalReference) 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 *ir.ReadDetailDto, data *ir.InternalReference) 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 *ir.ReadDetailDto, data *ir.InternalReference) 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/internal-reference/middleware.go b/internal/use-case/main-use-case/internal-reference/middleware.go
new file mode 100644
index 00000000..2afd1eaf
--- /dev/null
+++ b/internal/use-case/main-use-case/internal-reference/middleware.go
@@ -0,0 +1,9 @@
+package internal_reference
+
+// 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/internal-reference/tycovar.go b/internal/use-case/main-use-case/internal-reference/tycovar.go
new file mode 100644
index 00000000..10efa497
--- /dev/null
+++ b/internal/use-case/main-use-case/internal-reference/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 internal_reference
+
+import (
+ "gorm.io/gorm"
+
+ ir "simrs-vx/internal/domain/main-entities/internal-reference"
+)
+
+type createMw struct {
+ Name string
+ Func func(input *ir.CreateDto, data *ir.InternalReference, tx *gorm.DB) error
+}
+
+type readListMw struct {
+ Name string
+ Func func(input *ir.ReadListDto, data *ir.InternalReference, tx *gorm.DB) error
+}
+
+type readDetailMw struct {
+ Name string
+ Func func(input *ir.ReadDetailDto, data *ir.InternalReference, 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/item-price/case.go b/internal/use-case/main-use-case/item-price/case.go
index a40f9142..e6be1800 100644
--- a/internal/use-case/main-use-case/item-price/case.go
+++ b/internal/use-case/main-use-case/item-price/case.go
@@ -87,9 +87,6 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
return err
}
- if len(input.Includes) > 0 {
- input.Preloads = pu.GetPreloads(input.Includes)
- }
if dataList, metaList, err = ReadListData(input, &event, tx); err != nil {
return err
}
@@ -109,12 +106,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
diff --git a/internal/use-case/main-use-case/item-price/lib.go b/internal/use-case/main-use-case/item-price/lib.go
index 8d61f2f8..91744132 100644
--- a/internal/use-case/main-use-case/item-price/lib.go
+++ b/internal/use-case/main-use-case/item-price/lib.go
@@ -2,6 +2,8 @@ package itemprice
import (
e "simrs-vx/internal/domain/main-entities/item-price"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.ItemPri
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -51,32 +47,21 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.It
tx = dg.I
}
- if len(input.Preloads) > 0 {
- for _, preload := range input.Preloads {
- tx = tx.Preload(preload)
- }
- }
-
tx = tx.
Model(&e.ItemPrice{}).
+ Scopes(gh.Preload(input.Includes)).
Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-get-fail",
- Detail: "Database get failed",
- Raw: err,
- }
- return nil, nil, pl.SetLogError(event, input)
-
+ return nil, nil, plh.HandleListError(input, event, err)
}
+
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
diff --git a/internal/use-case/main-use-case/item/case.go b/internal/use-case/main-use-case/item/case.go
index 67027fa8..914d777f 100644
--- a/internal/use-case/main-use-case/item/case.go
+++ b/internal/use-case/main-use-case/item/case.go
@@ -87,9 +87,6 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
return err
}
- if len(input.Includes) > 0 {
- input.Preloads = pu.GetPreloads(input.Includes)
- }
if dataList, metaList, err = ReadListData(input, &event, tx); err != nil {
return err
}
@@ -109,12 +106,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
diff --git a/internal/use-case/main-use-case/item/lib.go b/internal/use-case/main-use-case/item/lib.go
index b62e1c3a..56c4c915 100644
--- a/internal/use-case/main-use-case/item/lib.go
+++ b/internal/use-case/main-use-case/item/lib.go
@@ -2,6 +2,8 @@ package item
import (
e "simrs-vx/internal/domain/main-entities/item"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Item, e
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -51,32 +47,21 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.It
tx = dg.I
}
- if len(input.Preloads) > 0 {
- for _, preload := range input.Preloads {
- tx = tx.Preload(preload)
- }
- }
-
tx = tx.
Model(&e.Item{}).
+ Scopes(gh.Preload(input.Includes)).
Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
- Order("\"CreatedAt\" DESC")
+ Scopes(gh.Sort(input.Sort))
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-get-fail",
- Detail: "Database get failed",
- Raw: err,
- }
- return nil, nil, pl.SetLogError(event, input)
-
+ return nil, nil, plh.HandleListError(input, event, err)
}
+
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
diff --git a/internal/use-case/main-use-case/laborant/case.go b/internal/use-case/main-use-case/laborant/case.go
new file mode 100644
index 00000000..f8696b9a
--- /dev/null
+++ b/internal/use-case/main-use-case/laborant/case.go
@@ -0,0 +1,276 @@
+package laborant
+
+import (
+ e "simrs-vx/internal/domain/main-entities/laborant"
+ "strconv"
+
+ dg "github.com/karincake/apem/db-gorm-pg"
+ d "github.com/karincake/dodol"
+
+ pl "simrs-vx/pkg/logger"
+ pu "simrs-vx/pkg/use-case-helper"
+
+ "gorm.io/gorm"
+)
+
+const source = "nutritionist"
+
+func Create(input e.CreateDto) (*d.Data, error) {
+ data := e.Laborant{}
+
+ event := pl.Event{
+ Feature: "Create",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "create")
+
+ err := dg.I.Transaction(func(tx *gorm.DB) error {
+ mwRunner := newMiddlewareRunner(&event, tx)
+ mwRunner.setMwType(pu.MWTPre)
+ // Run pre-middleware
+ if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil {
+ return err
+ }
+
+ if resData, err := CreateData(input, &event, tx); err != nil {
+ return err
+ } else {
+ data = *resData
+ }
+
+ mwRunner.setMwType(pu.MWTPost)
+ // Run post-middleware
+ if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil {
+ return err
+ }
+
+ pl.SetLogInfo(&event, nil, "complete")
+
+ return nil
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &d.Data{
+ Meta: d.II{
+ "source": source,
+ "structure": "single-data",
+ "status": "created",
+ },
+ Data: data.ToResponse(),
+ }, nil
+}
+
+func ReadList(input e.ReadListDto) (*d.Data, error) {
+ var data *e.Laborant
+ var dataList []e.Laborant
+ 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.Laborant
+ 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: uint16(input.Id)}
+ var data *e.Laborant
+ 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: uint16(input.Id)}
+ var data *e.Laborant
+ 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/laborant/helper.go b/internal/use-case/main-use-case/laborant/helper.go
new file mode 100644
index 00000000..8619f7e6
--- /dev/null
+++ b/internal/use-case/main-use-case/laborant/helper.go
@@ -0,0 +1,22 @@
+/*
+DESCRIPTION:
+Any functions that are used internally by the use-case
+*/
+package laborant
+
+import (
+ e "simrs-vx/internal/domain/main-entities/laborant"
+)
+
+func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Laborant) {
+ var inputSrc *e.CreateDto
+ if inputT, ok := any(input).(*e.CreateDto); ok {
+ inputSrc = inputT
+ } else {
+ inputTemp := any(input).(*e.UpdateDto)
+ inputSrc = &inputTemp.CreateDto
+ }
+
+ data.Employee_Id = inputSrc.Employee_Id
+ data.IHS_Number = inputSrc.IHS_Number
+}
diff --git a/internal/use-case/main-use-case/laborant/lib.go b/internal/use-case/main-use-case/laborant/lib.go
new file mode 100644
index 00000000..efe8bb37
--- /dev/null
+++ b/internal/use-case/main-use-case/laborant/lib.go
@@ -0,0 +1,146 @@
+package laborant
+
+import (
+ e "simrs-vx/internal/domain/main-entities/laborant"
+
+ 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.Laborant, error) {
+ pl.SetLogInfo(event, nil, "started", "DBCreate")
+
+ data := e.Laborant{}
+ 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.Laborant, *e.MetaDto, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadList")
+ data := []e.Laborant{}
+ 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.Laborant{}).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
+ Count(&count).
+ Scopes(gh.Paginate(input, &pagination)).
+ Order("\"CreatedAt\" DESC")
+
+ if err := tx.Find(&data).Error; err != nil {
+ if err == gorm.ErrRecordNotFound {
+ return nil, &meta, nil
+ }
+ return nil, nil, plh.HandleListError(input, event, err)
+ }
+
+ meta.Count = int(count)
+ meta.PageNumber = pagination.PageNumber
+ meta.PageSize = pagination.PageSize
+
+ pl.SetLogInfo(event, nil, "complete")
+ return data, &meta, nil
+}
+
+func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.Laborant, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadDetail")
+ data := e.Laborant{}
+
+ var tx *gorm.DB
+ if len(dbx) > 0 {
+ tx = dbx[0]
+ } else {
+ tx = dg.I
+ }
+
+ if input.Employee_Id != nil {
+ tx = tx.Where("\"Employee_Id\" = ?", *input.Employee_Id)
+ }
+ if input.Id > 0 {
+ tx = tx.Where("\"Id\" = ?", input.Id)
+ }
+ if err := tx.First(&data).Error; err != nil {
+ if processedErr := pu.HandleReadError(err, event, source, input.Id, data); processedErr != nil {
+ return nil, processedErr
+ }
+ }
+
+ pl.SetLogInfo(event, nil, "complete")
+ return &data, nil
+}
+
+func UpdateData(input e.UpdateDto, data *e.Laborant, 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.Laborant, 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/laborant/middleware-runner.go b/internal/use-case/main-use-case/laborant/middleware-runner.go
new file mode 100644
index 00000000..e037afc7
--- /dev/null
+++ b/internal/use-case/main-use-case/laborant/middleware-runner.go
@@ -0,0 +1,103 @@
+package laborant
+
+import (
+ e "simrs-vx/internal/domain/main-entities/laborant"
+ 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.Laborant) 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.Laborant) 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.Laborant) 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.Laborant) 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.Laborant) 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/laborant/middleware.go b/internal/use-case/main-use-case/laborant/middleware.go
new file mode 100644
index 00000000..b0eb6830
--- /dev/null
+++ b/internal/use-case/main-use-case/laborant/middleware.go
@@ -0,0 +1,9 @@
+package laborant
+
+// 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/laborant/tycovar.go b/internal/use-case/main-use-case/laborant/tycovar.go
new file mode 100644
index 00000000..41768ca7
--- /dev/null
+++ b/internal/use-case/main-use-case/laborant/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 laborant
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/main-entities/laborant"
+)
+
+type createMw struct {
+ Name string
+ Func func(input *e.CreateDto, data *e.Laborant, tx *gorm.DB) error
+}
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.Laborant, tx *gorm.DB) error
+}
+
+type readDetailMw struct {
+ Name string
+ Func func(input *e.ReadDetailDto, data *e.Laborant, 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/language/case.go b/internal/use-case/main-use-case/language/case.go
index 142e14af..885bcfeb 100644
--- a/internal/use-case/main-use-case/language/case.go
+++ b/internal/use-case/main-use-case/language/case.go
@@ -106,12 +106,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
diff --git a/internal/use-case/main-use-case/language/lib.go b/internal/use-case/main-use-case/language/lib.go
index 65a2ed08..11992794 100644
--- a/internal/use-case/main-use-case/language/lib.go
+++ b/internal/use-case/main-use-case/language/lib.go
@@ -2,6 +2,8 @@ package language
import (
e "simrs-vx/internal/domain/main-entities/language"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Languag
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -53,24 +49,19 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.La
tx = tx.
Model(&e.Language{}).
- Scopes(gh.Filter(input)).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
- Order("\"CreatedAt\" DESC")
+ Scopes(gh.Sort(input.Sort))
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-get-fail",
- Detail: "Database get failed",
- Raw: err,
- }
- return nil, nil, pl.SetLogError(event, input)
-
+ return nil, nil, plh.HandleListError(input, event, err)
}
+
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
diff --git a/internal/use-case/main-use-case/material-order-item/case.go b/internal/use-case/main-use-case/material-order-item/case.go
new file mode 100644
index 00000000..d1e3ffe8
--- /dev/null
+++ b/internal/use-case/main-use-case/material-order-item/case.go
@@ -0,0 +1,285 @@
+package materialorderitem
+
+import (
+ "errors"
+ "strconv"
+
+ e "simrs-vx/internal/domain/main-entities/material-order-item"
+
+ umo "simrs-vx/internal/use-case/main-use-case/material-order"
+
+ dg "github.com/karincake/apem/db-gorm-pg"
+ d "github.com/karincake/dodol"
+
+ pl "simrs-vx/pkg/logger"
+ pu "simrs-vx/pkg/use-case-helper"
+
+ "gorm.io/gorm"
+)
+
+const source = "material-order-item"
+
+func Create(input e.CreateDto) (*d.Data, error) {
+ data := e.MaterialOrderItem{}
+
+ event := pl.Event{
+ Feature: "Create",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "create")
+
+ err := dg.I.Transaction(func(tx *gorm.DB) error {
+ mwRunner := newMiddlewareRunner(&event, tx)
+ mwRunner.setMwType(pu.MWTPre)
+ // Run pre-middleware
+ if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil {
+ return err
+ }
+
+ // check if materialOrder is done
+ if umo.IsCompleted(*input.MaterialOrder_Id, &event, tx) {
+ return errors.New("materialOrder is already done")
+ }
+
+ if resData, err := CreateData(input, &event, tx); err != nil {
+ return err
+ } else {
+ data = *resData
+ }
+
+ mwRunner.setMwType(pu.MWTPost)
+ // Run post-middleware
+ if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil {
+ return err
+ }
+
+ pl.SetLogInfo(&event, nil, "complete")
+
+ return nil
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &d.Data{
+ Meta: d.II{
+ "source": source,
+ "structure": "single-data",
+ "status": "created",
+ },
+ Data: data.ToResponse(),
+ }, nil
+}
+
+func ReadList(input e.ReadListDto) (*d.Data, error) {
+ var data *e.MaterialOrderItem
+ var dataList []e.MaterialOrderItem
+ 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.MaterialOrderItem
+ 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.MaterialOrderItem
+ 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.MaterialOrderItem
+ var err error
+
+ event := pl.Event{
+ Feature: "Delete",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "delete")
+
+ err = dg.I.Transaction(func(tx *gorm.DB) error {
+ pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail")
+ if data, err = ReadDetailData(rdDto, &event, tx); err != nil {
+ return err
+ }
+
+ mwRunner := newMiddlewareRunner(&event, tx)
+ mwRunner.setMwType(pu.MWTPre)
+ // Run pre-middleware
+ if err := mwRunner.RunDeleteMiddleware(readDetailPreMw, &rdDto, data); err != nil {
+ return err
+ }
+
+ if err := DeleteData(data, &event, tx); err != nil {
+ return err
+ }
+
+ mwRunner.setMwType(pu.MWTPost)
+ // Run post-middleware
+ if err := mwRunner.RunDeleteMiddleware(readDetailPostMw, &rdDto, data); err != nil {
+ return err
+ }
+
+ return nil
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &d.Data{
+ Meta: d.IS{
+ "source": source,
+ "structure": "single-data",
+ "status": "deleted",
+ },
+ Data: data.ToResponse(),
+ }, nil
+
+}
diff --git a/internal/use-case/main-use-case/material-order-item/helper.go b/internal/use-case/main-use-case/material-order-item/helper.go
new file mode 100644
index 00000000..25e89a21
--- /dev/null
+++ b/internal/use-case/main-use-case/material-order-item/helper.go
@@ -0,0 +1,23 @@
+/*
+DESCRIPTION:
+Any functions that are used internally by the use-case
+*/
+package materialorderitem
+
+import (
+ e "simrs-vx/internal/domain/main-entities/material-order-item"
+)
+
+func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.MaterialOrderItem) {
+ var inputSrc *e.CreateDto
+ if inputT, ok := any(input).(*e.CreateDto); ok {
+ inputSrc = inputT
+ } else {
+ inputTemp := any(input).(*e.UpdateDto)
+ inputSrc = &inputTemp.CreateDto
+ }
+
+ data.MaterialOrder_Id = inputSrc.MaterialOrder_Id
+ data.Material_Id = inputSrc.Material_Id
+ data.Count = inputSrc.Count
+}
diff --git a/internal/use-case/main-use-case/material-order-item/lib.go b/internal/use-case/main-use-case/material-order-item/lib.go
new file mode 100644
index 00000000..f6533ecb
--- /dev/null
+++ b/internal/use-case/main-use-case/material-order-item/lib.go
@@ -0,0 +1,140 @@
+package materialorderitem
+
+import (
+ e "simrs-vx/internal/domain/main-entities/material-order-item"
+
+ plh "simrs-vx/pkg/lib-helper"
+ pl "simrs-vx/pkg/logger"
+ pu "simrs-vx/pkg/use-case-helper"
+
+ dg "github.com/karincake/apem/db-gorm-pg"
+ gh "github.com/karincake/getuk"
+ "gorm.io/gorm"
+)
+
+func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.MaterialOrderItem, error) {
+ pl.SetLogInfo(event, nil, "started", "DBCreate")
+
+ data := e.MaterialOrderItem{}
+ 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.MaterialOrderItem, *e.MetaDto, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadList")
+ data := []e.MaterialOrderItem{}
+ 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.MaterialOrderItem{}).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
+ Count(&count).
+ Scopes(gh.Paginate(input, &pagination)).
+ Order("\"CreatedAt\" DESC")
+
+ if err := tx.Find(&data).Error; err != nil {
+ if err == gorm.ErrRecordNotFound {
+ return nil, &meta, nil
+ }
+ return nil, nil, plh.HandleListError(input, event, err)
+ }
+
+ meta.Count = int(count)
+ meta.PageNumber = pagination.PageNumber
+ meta.PageSize = pagination.PageSize
+
+ pl.SetLogInfo(event, nil, "complete")
+ return data, &meta, nil
+}
+
+func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.MaterialOrderItem, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadDetail")
+ data := e.MaterialOrderItem{}
+
+ 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.MaterialOrderItem, 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.MaterialOrderItem, event *pl.Event, dbx ...*gorm.DB) error {
+ pl.SetLogInfo(event, data, "started", "DBDelete")
+ var tx *gorm.DB
+ if len(dbx) > 0 {
+ tx = dbx[0]
+ } else {
+ tx = dg.I
+ }
+
+ if err := tx.Delete(&data).Error; err != nil {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-delete-fail",
+ Detail: "Database delete failed",
+ Raw: err,
+ }
+ return pl.SetLogError(event, data)
+ }
+
+ pl.SetLogInfo(event, nil, "complete")
+ return nil
+}
diff --git a/internal/use-case/main-use-case/material-order-item/middleware-runner.go b/internal/use-case/main-use-case/material-order-item/middleware-runner.go
new file mode 100644
index 00000000..4cb38f03
--- /dev/null
+++ b/internal/use-case/main-use-case/material-order-item/middleware-runner.go
@@ -0,0 +1,103 @@
+package materialorderitem
+
+import (
+ e "simrs-vx/internal/domain/main-entities/material-order-item"
+ pl "simrs-vx/pkg/logger"
+ pu "simrs-vx/pkg/use-case-helper"
+
+ "gorm.io/gorm"
+)
+
+type middlewareRunner struct {
+ Event *pl.Event
+ Tx *gorm.DB
+ MwType pu.MWType
+}
+
+// NewMiddlewareExecutor creates a new middleware executor
+func newMiddlewareRunner(event *pl.Event, tx *gorm.DB) *middlewareRunner {
+ return &middlewareRunner{
+ Event: event,
+ Tx: tx,
+ }
+}
+
+// ExecuteCreateMiddleware executes create middleware
+func (me *middlewareRunner) RunCreateMiddleware(middlewares []createMw, input *e.CreateDto, data *e.MaterialOrderItem) 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.MaterialOrderItem) 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.MaterialOrderItem) 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.MaterialOrderItem) 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.MaterialOrderItem) error {
+ for _, middleware := range middlewares {
+ logData := pu.GetLogData(input, data)
+
+ pl.SetLogInfo(me.Event, logData, "started", middleware.Name)
+
+ if err := middleware.Func(input, data, me.Tx); err != nil {
+ return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err)
+ }
+
+ pl.SetLogInfo(me.Event, nil, "complete")
+ }
+ return nil
+}
+
+func (me *middlewareRunner) setMwType(mwType pu.MWType) {
+ me.MwType = mwType
+}
diff --git a/internal/use-case/main-use-case/material-order-item/middleware.go b/internal/use-case/main-use-case/material-order-item/middleware.go
new file mode 100644
index 00000000..1ed7165d
--- /dev/null
+++ b/internal/use-case/main-use-case/material-order-item/middleware.go
@@ -0,0 +1,9 @@
+package materialorderitem
+
+// example of middleware
+// func init() {
+// createPreMw = append(createPreMw,
+// CreateMw{Name: "modif-input", Func: pm.ModifInput},
+// CreateMw{Name: "check-data", Func: pm.CheckData},
+// )
+// }
diff --git a/internal/use-case/main-use-case/material-order-item/tycovar.go b/internal/use-case/main-use-case/material-order-item/tycovar.go
new file mode 100644
index 00000000..adad9821
--- /dev/null
+++ b/internal/use-case/main-use-case/material-order-item/tycovar.go
@@ -0,0 +1,44 @@
+/*
+DESCRIPTION:
+A sample, part of the package that contains type, constants, and/or variables.
+
+In this sample it also provides type and variable regarding the needs of the
+middleware to separate from main use-case which has the basic CRUD
+functionality. The purpose of this is to make the code more maintainable.
+*/
+package materialorderitem
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/main-entities/material-order-item"
+)
+
+type createMw struct {
+ Name string
+ Func func(input *e.CreateDto, data *e.MaterialOrderItem, tx *gorm.DB) error
+}
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.MaterialOrderItem, tx *gorm.DB) error
+}
+
+type readDetailMw struct {
+ Name string
+ Func func(input *e.ReadDetailDto, data *e.MaterialOrderItem, 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/material-order/case.go b/internal/use-case/main-use-case/material-order/case.go
new file mode 100644
index 00000000..713f64c0
--- /dev/null
+++ b/internal/use-case/main-use-case/material-order/case.go
@@ -0,0 +1,390 @@
+package materialorder
+
+import (
+ "errors"
+ "strconv"
+
+ e "simrs-vx/internal/domain/main-entities/material-order"
+
+ ud "simrs-vx/internal/use-case/main-use-case/doctor"
+ ue "simrs-vx/internal/use-case/main-use-case/encounter"
+
+ erc "simrs-vx/internal/domain/references/common"
+
+ dg "github.com/karincake/apem/db-gorm-pg"
+ d "github.com/karincake/dodol"
+
+ pl "simrs-vx/pkg/logger"
+ pu "simrs-vx/pkg/use-case-helper"
+
+ "gorm.io/gorm"
+)
+
+const source = "material-order"
+
+func Create(input e.CreateDto) (*d.Data, error) {
+ data := e.MaterialOrder{}
+
+ event := pl.Event{
+ Feature: "Create",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "create")
+
+ err := dg.I.Transaction(func(tx *gorm.DB) error {
+ mwRunner := newMiddlewareRunner(&event, tx)
+ mwRunner.setMwType(pu.MWTPre)
+ // Run pre-middleware
+ if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil {
+ return err
+ }
+
+ // check if encounter is done
+ if ue.IsDone(*input.Encounter_Id, &event, tx) {
+ return errors.New("encounter is already done")
+ }
+
+ if !input.AuthInfo.IsDoctor() {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "auth-forbidden",
+ Detail: "user position is not allowed",
+ Raw: errors.New("authentication failed"),
+ }
+ return pl.SetLogError(&event, input)
+ }
+
+ doctor_id, err := ud.GetIdByUserId(&input.AuthInfo.User_Id, &event, tx)
+ if err != nil {
+ return err
+ }
+ input.Doctor_Id = doctor_id
+
+ 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.MaterialOrder
+ var dataList []e.MaterialOrder
+ 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.MaterialOrder
+ 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.MaterialOrder
+ 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
+ }
+
+ if data.IsCompleted() {
+ return errors.New("data already completed")
+ }
+
+ mwRunner := newMiddlewareRunner(&event, tx)
+ mwRunner.setMwType(pu.MWTPre)
+ // Run pre-middleware
+ if err := mwRunner.RunUpdateMiddleware(readDetailPreMw, &rdDto, data); err != nil {
+ return err
+ }
+
+ if !input.AuthInfo.IsDoctor() {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "auth-forbidden",
+ Detail: "user position is not allowed",
+ Raw: errors.New("authentication failed"),
+ }
+ return pl.SetLogError(&event, input)
+ }
+
+ doctor_id, err := ud.GetIdByUserId(&input.AuthInfo.User_Id, &event, tx)
+ if err != nil {
+ return err
+ }
+
+ if !data.IsSameDoctor(doctor_id) {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "auth-forbidden",
+ Detail: "doctor is not the same as the data",
+ Raw: errors.New("authentication failed"),
+ }
+ return pl.SetLogError(&event, input)
+ }
+
+ input.Doctor_Id = doctor_id
+
+ 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.MaterialOrder
+ 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
+ }
+
+ if data.IsCompleted() {
+ return errors.New("data already completed")
+ }
+
+ 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 Complete(input e.ReadDetailDto) (*d.Data, error) {
+ var data *e.MaterialOrder
+ var err error
+
+ event := pl.Event{
+ Feature: "Complete",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "complete")
+
+ err = dg.I.Transaction(func(tx *gorm.DB) error {
+ data, err = ReadDetailData(input, &event, tx)
+ if err != nil {
+ return err
+ }
+
+ if data.IsCompleted() {
+ return errors.New("data already completed")
+ }
+
+ data.Status_Code = erc.DSCDone
+ 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
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &d.Data{
+ Meta: d.IS{
+ "source": source,
+ "structure": "single-data",
+ "status": "fetched",
+ },
+ Data: data.ToResponse(),
+ }, nil
+}
diff --git a/internal/use-case/main-use-case/material-order/helper.go b/internal/use-case/main-use-case/material-order/helper.go
new file mode 100644
index 00000000..fe0862e9
--- /dev/null
+++ b/internal/use-case/main-use-case/material-order/helper.go
@@ -0,0 +1,25 @@
+/*
+DESCRIPTION:
+Any functions that are used internally by the use-case
+*/
+package materialorder
+
+import (
+ e "simrs-vx/internal/domain/main-entities/material-order"
+
+ erc "simrs-vx/internal/domain/references/common"
+)
+
+func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.MaterialOrder) {
+ var inputSrc *e.CreateDto
+ if inputT, ok := any(input).(*e.CreateDto); ok {
+ inputSrc = inputT
+ data.Status_Code = erc.DSCNew
+ } else {
+ inputTemp := any(input).(*e.UpdateDto)
+ inputSrc = &inputTemp.CreateDto
+ }
+
+ data.Encounter_Id = inputSrc.Encounter_Id
+ data.Doctor_Id = inputSrc.Doctor_Id
+}
diff --git a/internal/use-case/main-use-case/material-order/lib.go b/internal/use-case/main-use-case/material-order/lib.go
new file mode 100644
index 00000000..c38e9fa6
--- /dev/null
+++ b/internal/use-case/main-use-case/material-order/lib.go
@@ -0,0 +1,164 @@
+package materialorder
+
+import (
+ e "simrs-vx/internal/domain/main-entities/material-order"
+
+ 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.MaterialOrder, error) {
+ pl.SetLogInfo(event, nil, "started", "DBCreate")
+
+ data := e.MaterialOrder{}
+ 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.MaterialOrder, *e.MetaDto, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadList")
+ data := []e.MaterialOrder{}
+ 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.MaterialOrder{}).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
+ Count(&count).
+ Scopes(gh.Paginate(input, &pagination)).
+ Order("\"CreatedAt\" DESC")
+
+ if err := tx.Find(&data).Error; err != nil {
+ if err == gorm.ErrRecordNotFound {
+ return nil, &meta, nil
+ }
+ return nil, nil, plh.HandleListError(input, event, err)
+ }
+
+ meta.Count = int(count)
+ meta.PageNumber = pagination.PageNumber
+ meta.PageSize = pagination.PageSize
+
+ pl.SetLogInfo(event, nil, "complete")
+ return data, &meta, nil
+}
+
+func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.MaterialOrder, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadDetail")
+ data := e.MaterialOrder{}
+
+ 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.MaterialOrder, 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.MaterialOrder, 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
+}
+
+func IsCompleted(materialOrder_id uint, event *pl.Event, dbx ...*gorm.DB) bool {
+ pl.SetLogInfo(event, nil, "started", "DBIsCompleted")
+ var tx *gorm.DB
+ if len(dbx) > 0 {
+ tx = dbx[0]
+ } else {
+ tx = dg.I
+ }
+
+ var data e.MaterialOrder
+ if err := tx.Where("\"Id\" = ?", materialOrder_id).First(&data).Error; err != nil {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-get-fail",
+ Detail: "Database get failed",
+ Raw: err,
+ }
+ return false
+ }
+
+ pl.SetLogInfo(event, nil, "complete")
+ return data.IsCompleted()
+}
diff --git a/internal/use-case/main-use-case/material-order/middleware-runner.go b/internal/use-case/main-use-case/material-order/middleware-runner.go
new file mode 100644
index 00000000..0e872c9e
--- /dev/null
+++ b/internal/use-case/main-use-case/material-order/middleware-runner.go
@@ -0,0 +1,103 @@
+package materialorder
+
+import (
+ e "simrs-vx/internal/domain/main-entities/material-order"
+ 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.MaterialOrder) 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.MaterialOrder) 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.MaterialOrder) 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.MaterialOrder) 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.MaterialOrder) error {
+ for _, middleware := range middlewares {
+ logData := pu.GetLogData(input, data)
+
+ pl.SetLogInfo(me.Event, logData, "started", middleware.Name)
+
+ if err := middleware.Func(input, data, me.Tx); err != nil {
+ return pu.HandleMiddlewareError(me.Event, string(me.MwType), middleware.Name, logData, err)
+ }
+
+ pl.SetLogInfo(me.Event, nil, "complete")
+ }
+ return nil
+}
+
+func (me *middlewareRunner) setMwType(mwType pu.MWType) {
+ me.MwType = mwType
+}
diff --git a/internal/use-case/main-use-case/material-order/middleware.go b/internal/use-case/main-use-case/material-order/middleware.go
new file mode 100644
index 00000000..e6bb67d6
--- /dev/null
+++ b/internal/use-case/main-use-case/material-order/middleware.go
@@ -0,0 +1,9 @@
+package materialorder
+
+// example of middleware
+// func init() {
+// createPreMw = append(createPreMw,
+// CreateMw{Name: "modif-input", Func: pm.ModifInput},
+// CreateMw{Name: "check-data", Func: pm.CheckData},
+// )
+// }
diff --git a/internal/use-case/main-use-case/material-order/tycovar.go b/internal/use-case/main-use-case/material-order/tycovar.go
new file mode 100644
index 00000000..5aaff1ce
--- /dev/null
+++ b/internal/use-case/main-use-case/material-order/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 materialorder
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/main-entities/material-order"
+)
+
+type createMw struct {
+ Name string
+ Func func(input *e.CreateDto, data *e.MaterialOrder, tx *gorm.DB) error
+}
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.MaterialOrder, tx *gorm.DB) error
+}
+
+type readDetailMw struct {
+ Name string
+ Func func(input *e.ReadDetailDto, data *e.MaterialOrder, 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/material/case.go b/internal/use-case/main-use-case/material/case.go
index 87b8be9c..42346dc6 100644
--- a/internal/use-case/main-use-case/material/case.go
+++ b/internal/use-case/main-use-case/material/case.go
@@ -90,9 +90,6 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
return err
}
- if len(input.Includes) > 0 {
- input.Preloads = pu.GetPreloads(input.Includes)
- }
if dataList, metaList, err = ReadListData(input, &event, tx); err != nil {
return err
}
@@ -112,12 +109,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
diff --git a/internal/use-case/main-use-case/material/helper.go b/internal/use-case/main-use-case/material/helper.go
index ce0d8a2e..9cfefe27 100644
--- a/internal/use-case/main-use-case/material/helper.go
+++ b/internal/use-case/main-use-case/material/helper.go
@@ -31,6 +31,7 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Material) {
data.Uom_Code = inputSrc.Uom_Code
data.Stock = inputSrc.Stock
data.Item_Id = inputSrc.Item_Id
+ data.Infra_Id = inputSrc.Infra_Id
}
func createItem(input *e.CreateDto, event *pl.Event, tx *gorm.DB) error {
diff --git a/internal/use-case/main-use-case/material/lib.go b/internal/use-case/main-use-case/material/lib.go
index f1a3f40b..3f9adc9a 100644
--- a/internal/use-case/main-use-case/material/lib.go
+++ b/internal/use-case/main-use-case/material/lib.go
@@ -2,6 +2,8 @@ package material
import (
e "simrs-vx/internal/domain/main-entities/material"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Materia
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -51,32 +47,21 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Ma
tx = dg.I
}
- if len(input.Preloads) > 0 {
- for _, preload := range input.Preloads {
- tx = tx.Preload(preload)
- }
- }
-
tx = tx.
Model(&e.Material{}).
+ Scopes(gh.Preload(input.Includes)).
Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
- Order("\"CreatedAt\" DESC")
+ Scopes(gh.Sort(input.Sort))
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-get-fail",
- Detail: "Database get failed",
- Raw: err,
- }
- return nil, nil, pl.SetLogError(event, input)
-
+ return nil, nil, plh.HandleListError(input, event, err)
}
+
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
diff --git a/internal/use-case/main-use-case/mcu-order-item/case.go b/internal/use-case/main-use-case/mcu-order-item/case.go
new file mode 100644
index 00000000..9037b771
--- /dev/null
+++ b/internal/use-case/main-use-case/mcu-order-item/case.go
@@ -0,0 +1,397 @@
+package mcuorderitem
+
+import (
+ "errors"
+ "strconv"
+
+ e "simrs-vx/internal/domain/main-entities/mcu-order-item"
+
+ umo "simrs-vx/internal/use-case/main-use-case/mcu-order"
+
+ erc "simrs-vx/internal/domain/references/common"
+
+ 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 = "mcu-order-item"
+
+func Create(input e.CreateDto) (*d.Data, error) {
+ data := e.McuOrderItem{}
+
+ event := pl.Event{
+ Feature: "Create",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "create")
+
+ err := dg.I.Transaction(func(tx *gorm.DB) error {
+ mwRunner := newMiddlewareRunner(&event, tx)
+ mwRunner.setMwType(pu.MWTPre)
+ // Run pre-middleware
+ if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil {
+ return err
+ }
+
+ // check if mcuOrder is done
+ if umo.IsCompleted(*input.McuOrder_Id, &event, tx) {
+ return errors.New("mcuOrder is already done")
+ }
+
+ if resData, err := CreateData(input, &event, tx); err != nil {
+ return err
+ } else {
+ data = *resData
+ }
+
+ mwRunner.setMwType(pu.MWTPost)
+ // Run post-middleware
+ if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil {
+ return err
+ }
+
+ pl.SetLogInfo(&event, nil, "complete")
+
+ return nil
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &d.Data{
+ Meta: d.II{
+ "source": source,
+ "structure": "single-data",
+ "status": "created",
+ },
+ Data: data.ToResponse(),
+ }, nil
+}
+
+func ReadList(input e.ReadListDto) (*d.Data, error) {
+ var data *e.McuOrderItem
+ var dataList []e.McuOrderItem
+ 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.McuOrderItem
+ 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.McuOrderItem
+ 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.McuOrderItem
+ 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 Complete(input e.ReadDetailDto) (*d.Data, error) {
+ var data *e.McuOrderItem
+ var err error
+
+ event := pl.Event{
+ Feature: "Complete",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "complete")
+
+ err = dg.I.Transaction(func(tx *gorm.DB) error {
+ data, err = ReadDetailData(input, &event, tx)
+ if err != nil {
+ return err
+ }
+
+ if data.IsCompleted() {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-state-mismatch",
+ Detail: "mcuOrderItem is already completed",
+ Raw: errors.New("mcuOrderItem is already completed"),
+ }
+ return pl.SetLogError(&event, input)
+ }
+
+ data.Status_Code = erc.DSCDone
+ 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
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &d.Data{
+ Meta: d.IS{
+ "source": source,
+ "structure": "single-data",
+ "status": "fetched",
+ },
+ Data: data.ToResponse(),
+ }, nil
+}
+
+func SetSchedule(input e.SetScheduleDto) (*d.Data, error) {
+ rdDto := e.ReadDetailDto{Id: input.Id}
+ var data *e.McuOrderItem
+ var err error
+
+ event := pl.Event{
+ Feature: "SetSchedule",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "setSchedule")
+
+ err = dg.I.Transaction(func(tx *gorm.DB) error {
+ pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail")
+ data, err = ReadDetailData(rdDto, &event, tx)
+ if err != nil {
+ return err
+ }
+ if data.IsCompleted() {
+ return errors.New("data already completed")
+ }
+
+ data.ExaminationDate = input.ExaminationDate
+ 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
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &d.Data{
+ Meta: d.IS{
+ "source": source,
+ "structure": "single-data",
+ "status": "setSchedule",
+ },
+ Data: data.ToResponse(),
+ }, nil
+}
diff --git a/internal/use-case/main-use-case/mcu-order-item/helper.go b/internal/use-case/main-use-case/mcu-order-item/helper.go
new file mode 100644
index 00000000..a2694ecd
--- /dev/null
+++ b/internal/use-case/main-use-case/mcu-order-item/helper.go
@@ -0,0 +1,25 @@
+/*
+DESCRIPTION:
+Any functions that are used internally by the use-case
+*/
+package mcuorderitem
+
+import (
+ e "simrs-vx/internal/domain/main-entities/mcu-order-item"
+)
+
+func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.McuOrderItem) {
+ var inputSrc *e.CreateDto
+ if inputT, ok := any(input).(*e.CreateDto); ok {
+ inputSrc = inputT
+ } else {
+ inputTemp := any(input).(*e.UpdateDto)
+ inputSrc = &inputTemp.CreateDto
+ }
+
+ data.McuOrder_Id = inputSrc.McuOrder_Id
+ data.McuSrc_Id = inputSrc.McuSrc_Id
+ data.Result = inputSrc.Result
+ data.Status_Code = inputSrc.Status_Code
+ data.ExaminationDate = inputSrc.ExaminationDate
+}
diff --git a/internal/use-case/main-use-case/mcu-order-item/lib.go b/internal/use-case/main-use-case/mcu-order-item/lib.go
new file mode 100644
index 00000000..e53f1c2f
--- /dev/null
+++ b/internal/use-case/main-use-case/mcu-order-item/lib.go
@@ -0,0 +1,164 @@
+package mcuorderitem
+
+import (
+ e "simrs-vx/internal/domain/main-entities/mcu-order-item"
+
+ plh "simrs-vx/pkg/lib-helper"
+ pl "simrs-vx/pkg/logger"
+ pu "simrs-vx/pkg/use-case-helper"
+
+ dg "github.com/karincake/apem/db-gorm-pg"
+ gh "github.com/karincake/getuk"
+ "gorm.io/gorm"
+)
+
+func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.McuOrderItem, error) {
+ pl.SetLogInfo(event, nil, "started", "DBCreate")
+
+ data := e.McuOrderItem{}
+ 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.McuOrderItem, *e.MetaDto, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadList")
+ data := []e.McuOrderItem{}
+ 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.McuOrderItem{}).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
+ Count(&count).
+ Scopes(gh.Paginate(input, &pagination)).
+ Order("\"CreatedAt\" DESC")
+
+ if err := tx.Find(&data).Error; err != nil {
+ if err == gorm.ErrRecordNotFound {
+ return nil, &meta, nil
+ }
+ return nil, nil, plh.HandleListError(input, event, err)
+ }
+
+ meta.Count = int(count)
+ meta.PageNumber = pagination.PageNumber
+ meta.PageSize = pagination.PageSize
+
+ pl.SetLogInfo(event, nil, "complete")
+ return data, &meta, nil
+}
+
+func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.McuOrderItem, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadDetail")
+ data := e.McuOrderItem{}
+
+ 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.McuOrderItem, 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.McuOrderItem, 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
+}
+
+func IsCompleted(mcuOrderItem_id uint, event *pl.Event, dbx ...*gorm.DB) bool {
+ pl.SetLogInfo(event, nil, "started", "DBIsCompleted")
+ var tx *gorm.DB
+ if len(dbx) > 0 {
+ tx = dbx[0]
+ } else {
+ tx = dg.I
+ }
+
+ var data e.McuOrderItem
+ if err := tx.Where("\"Id\" = ?", mcuOrderItem_id).First(&data).Error; err != nil {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-get-fail",
+ Detail: "Database get failed",
+ Raw: err,
+ }
+ return false
+ }
+
+ pl.SetLogInfo(event, nil, "complete")
+ return data.IsCompleted()
+}
diff --git a/internal/use-case/main-use-case/mcu-order-item/middleware-runner.go b/internal/use-case/main-use-case/mcu-order-item/middleware-runner.go
new file mode 100644
index 00000000..d80da394
--- /dev/null
+++ b/internal/use-case/main-use-case/mcu-order-item/middleware-runner.go
@@ -0,0 +1,103 @@
+package mcuorderitem
+
+import (
+ e "simrs-vx/internal/domain/main-entities/mcu-order-item"
+ pl "simrs-vx/pkg/logger"
+ pu "simrs-vx/pkg/use-case-helper"
+
+ "gorm.io/gorm"
+)
+
+type middlewareRunner struct {
+ Event *pl.Event
+ Tx *gorm.DB
+ MwType pu.MWType
+}
+
+// NewMiddlewareExecutor creates a new middleware executor
+func newMiddlewareRunner(event *pl.Event, tx *gorm.DB) *middlewareRunner {
+ return &middlewareRunner{
+ Event: event,
+ Tx: tx,
+ }
+}
+
+// ExecuteCreateMiddleware executes create middleware
+func (me *middlewareRunner) RunCreateMiddleware(middlewares []createMw, input *e.CreateDto, data *e.McuOrderItem) 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.McuOrderItem) 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.McuOrderItem) 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.McuOrderItem) 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.McuOrderItem) 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/mcu-order-item/middleware.go b/internal/use-case/main-use-case/mcu-order-item/middleware.go
new file mode 100644
index 00000000..33e97e3d
--- /dev/null
+++ b/internal/use-case/main-use-case/mcu-order-item/middleware.go
@@ -0,0 +1,9 @@
+package mcuorderitem
+
+// 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/mcu-order-item/tycovar.go b/internal/use-case/main-use-case/mcu-order-item/tycovar.go
new file mode 100644
index 00000000..4e3f10b2
--- /dev/null
+++ b/internal/use-case/main-use-case/mcu-order-item/tycovar.go
@@ -0,0 +1,44 @@
+/*
+DESCRIPTION:
+A sample, part of the package that contains type, constants, and/or variables.
+
+In this sample it also provides type and variable regarding the needs of the
+middleware to separate from main use-case which has the basic CRUD
+functionality. The purpose of this is to make the code more maintainable.
+*/
+package mcuorderitem
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/main-entities/mcu-order-item"
+)
+
+type createMw struct {
+ Name string
+ Func func(input *e.CreateDto, data *e.McuOrderItem, tx *gorm.DB) error
+}
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.McuOrderItem, tx *gorm.DB) error
+}
+
+type readDetailMw struct {
+ Name string
+ Func func(input *e.ReadDetailDto, data *e.McuOrderItem, 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/mcu-order-sub-item/case.go b/internal/use-case/main-use-case/mcu-order-sub-item/case.go
new file mode 100644
index 00000000..b2676390
--- /dev/null
+++ b/internal/use-case/main-use-case/mcu-order-sub-item/case.go
@@ -0,0 +1,344 @@
+package mcuordersubitem
+
+import (
+ "errors"
+ "strconv"
+
+ e "simrs-vx/internal/domain/main-entities/mcu-order-sub-item"
+
+ umoi "simrs-vx/internal/use-case/main-use-case/mcu-order-item"
+
+ erc "simrs-vx/internal/domain/references/common"
+
+ 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 = "mcu-order-sub-item"
+
+func Create(input e.CreateDto) (*d.Data, error) {
+ data := e.McuOrderSubItem{}
+
+ event := pl.Event{
+ Feature: "Create",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "create")
+
+ err := dg.I.Transaction(func(tx *gorm.DB) error {
+ mwRunner := newMiddlewareRunner(&event, tx)
+ mwRunner.setMwType(pu.MWTPre)
+ // Run pre-middleware
+ if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil {
+ return err
+ }
+
+ // check if mcuOrderItem is done
+ if umoi.IsCompleted(*input.McuOrderItem_Id, &event, tx) {
+ return errors.New("mcuOrderItem is already done")
+ }
+
+ if resData, err := CreateData(input, &event, tx); err != nil {
+ return err
+ } else {
+ data = *resData
+ }
+
+ mwRunner.setMwType(pu.MWTPost)
+ // Run post-middleware
+ if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil {
+ return err
+ }
+
+ pl.SetLogInfo(&event, nil, "complete")
+
+ return nil
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &d.Data{
+ Meta: d.II{
+ "source": source,
+ "structure": "single-data",
+ "status": "created",
+ },
+ Data: data.ToResponse(),
+ }, nil
+}
+
+func ReadList(input e.ReadListDto) (*d.Data, error) {
+ var data *e.McuOrderSubItem
+ var dataList []e.McuOrderSubItem
+ 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.McuOrderSubItem
+ 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.McuOrderSubItem
+ 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.McuOrderSubItem
+ 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 Complete(input e.ReadDetailDto) (*d.Data, error) {
+ var data *e.McuOrderSubItem
+ var err error
+
+ event := pl.Event{
+ Feature: "Complete",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "complete")
+
+ err = dg.I.Transaction(func(tx *gorm.DB) error {
+ data, err = ReadDetailData(input, &event, tx)
+ if err != nil {
+ return err
+ }
+
+ if data.IsCompleted() {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-state-mismatch",
+ Detail: "mcuOrderSubItem is already completed",
+ Raw: errors.New("mcuOrderSubItem is already completed"),
+ }
+ return pl.SetLogError(&event, input)
+ }
+
+ data.Status_Code = erc.DSCDone
+ 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
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &d.Data{
+ Meta: d.IS{
+ "source": source,
+ "structure": "single-data",
+ "status": "fetched",
+ },
+ Data: data.ToResponse(),
+ }, nil
+}
diff --git a/internal/use-case/main-use-case/mcu-order-sub-item/helper.go b/internal/use-case/main-use-case/mcu-order-sub-item/helper.go
new file mode 100644
index 00000000..f8d9c30f
--- /dev/null
+++ b/internal/use-case/main-use-case/mcu-order-sub-item/helper.go
@@ -0,0 +1,24 @@
+/*
+DESCRIPTION:
+Any functions that are used internally by the use-case
+*/
+package mcuordersubitem
+
+import (
+ e "simrs-vx/internal/domain/main-entities/mcu-order-sub-item"
+)
+
+func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.McuOrderSubItem) {
+ var inputSrc *e.CreateDto
+ if inputT, ok := any(input).(*e.CreateDto); ok {
+ inputSrc = inputT
+ } else {
+ inputTemp := any(input).(*e.UpdateDto)
+ inputSrc = &inputTemp.CreateDto
+ }
+
+ data.McuSubSrc_Id = inputSrc.McuSubSrc_Id
+ data.McuOrderItem_Id = inputSrc.McuOrderItem_Id
+ data.Result = inputSrc.Result
+ data.Status_Code = inputSrc.Status_Code
+}
diff --git a/internal/use-case/main-use-case/mcu-order-sub-item/lib.go b/internal/use-case/main-use-case/mcu-order-sub-item/lib.go
new file mode 100644
index 00000000..d7073573
--- /dev/null
+++ b/internal/use-case/main-use-case/mcu-order-sub-item/lib.go
@@ -0,0 +1,140 @@
+package mcuordersubitem
+
+import (
+ e "simrs-vx/internal/domain/main-entities/mcu-order-sub-item"
+
+ plh "simrs-vx/pkg/lib-helper"
+ pl "simrs-vx/pkg/logger"
+ pu "simrs-vx/pkg/use-case-helper"
+
+ dg "github.com/karincake/apem/db-gorm-pg"
+ gh "github.com/karincake/getuk"
+ "gorm.io/gorm"
+)
+
+func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.McuOrderSubItem, error) {
+ pl.SetLogInfo(event, nil, "started", "DBCreate")
+
+ data := e.McuOrderSubItem{}
+ 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.McuOrderSubItem, *e.MetaDto, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadList")
+ data := []e.McuOrderSubItem{}
+ 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.McuOrderSubItem{}).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
+ Count(&count).
+ Scopes(gh.Paginate(input, &pagination)).
+ Order("\"CreatedAt\" DESC")
+
+ if err := tx.Find(&data).Error; err != nil {
+ if err == gorm.ErrRecordNotFound {
+ return nil, &meta, nil
+ }
+ return nil, nil, plh.HandleListError(input, event, err)
+ }
+
+ meta.Count = int(count)
+ meta.PageNumber = pagination.PageNumber
+ meta.PageSize = pagination.PageSize
+
+ pl.SetLogInfo(event, nil, "complete")
+ return data, &meta, nil
+}
+
+func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.McuOrderSubItem, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadDetail")
+ data := e.McuOrderSubItem{}
+
+ 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.McuOrderSubItem, 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.McuOrderSubItem, 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/mcu-order-sub-item/middleware-runner.go b/internal/use-case/main-use-case/mcu-order-sub-item/middleware-runner.go
new file mode 100644
index 00000000..04b7323f
--- /dev/null
+++ b/internal/use-case/main-use-case/mcu-order-sub-item/middleware-runner.go
@@ -0,0 +1,103 @@
+package mcuordersubitem
+
+import (
+ e "simrs-vx/internal/domain/main-entities/mcu-order-sub-item"
+ pl "simrs-vx/pkg/logger"
+ pu "simrs-vx/pkg/use-case-helper"
+
+ "gorm.io/gorm"
+)
+
+type middlewareRunner struct {
+ Event *pl.Event
+ Tx *gorm.DB
+ MwType pu.MWType
+}
+
+// NewMiddlewareExecutor creates a new middleware executor
+func newMiddlewareRunner(event *pl.Event, tx *gorm.DB) *middlewareRunner {
+ return &middlewareRunner{
+ Event: event,
+ Tx: tx,
+ }
+}
+
+// ExecuteCreateMiddleware executes create middleware
+func (me *middlewareRunner) RunCreateMiddleware(middlewares []createMw, input *e.CreateDto, data *e.McuOrderSubItem) 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.McuOrderSubItem) 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.McuOrderSubItem) 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.McuOrderSubItem) 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.McuOrderSubItem) 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/mcu-order-sub-item/middleware.go b/internal/use-case/main-use-case/mcu-order-sub-item/middleware.go
new file mode 100644
index 00000000..8dda3302
--- /dev/null
+++ b/internal/use-case/main-use-case/mcu-order-sub-item/middleware.go
@@ -0,0 +1,9 @@
+package mcuordersubitem
+
+// 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/mcu-order-sub-item/tycovar.go b/internal/use-case/main-use-case/mcu-order-sub-item/tycovar.go
new file mode 100644
index 00000000..58b67a88
--- /dev/null
+++ b/internal/use-case/main-use-case/mcu-order-sub-item/tycovar.go
@@ -0,0 +1,44 @@
+/*
+DESCRIPTION:
+A sample, part of the package that contains type, constants, and/or variables.
+
+In this sample it also provides type and variable regarding the needs of the
+middleware to separate from main use-case which has the basic CRUD
+functionality. The purpose of this is to make the code more maintainable.
+*/
+package mcuordersubitem
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/main-entities/mcu-order-sub-item"
+)
+
+type createMw struct {
+ Name string
+ Func func(input *e.CreateDto, data *e.McuOrderSubItem, tx *gorm.DB) error
+}
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.McuOrderSubItem, tx *gorm.DB) error
+}
+
+type readDetailMw struct {
+ Name string
+ Func func(input *e.ReadDetailDto, data *e.McuOrderSubItem, 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/mcu-order/case.go b/internal/use-case/main-use-case/mcu-order/case.go
new file mode 100644
index 00000000..19b34cbe
--- /dev/null
+++ b/internal/use-case/main-use-case/mcu-order/case.go
@@ -0,0 +1,439 @@
+package mcuorder
+
+import (
+ "errors"
+ "strconv"
+
+ e "simrs-vx/internal/domain/main-entities/mcu-order"
+
+ ud "simrs-vx/internal/use-case/main-use-case/doctor"
+ ue "simrs-vx/internal/use-case/main-use-case/encounter"
+
+ erc "simrs-vx/internal/domain/references/common"
+
+ 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 = "mcu-order"
+
+func Create(input e.CreateDto) (*d.Data, error) {
+ data := e.McuOrder{}
+
+ event := pl.Event{
+ Feature: "Create",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "create")
+
+ err := dg.I.Transaction(func(tx *gorm.DB) error {
+ mwRunner := newMiddlewareRunner(&event, tx)
+ mwRunner.setMwType(pu.MWTPre)
+ // Run pre-middleware
+ if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil {
+ return err
+ }
+
+ // check if encounter is done
+ if ue.IsDone(*input.Encounter_Id, &event, tx) {
+ return errors.New("encounter is already done")
+ }
+
+ if !input.AuthInfo.IsDoctor() {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "auth-forbidden",
+ Detail: "user position is not allowed",
+ Raw: errors.New("authentication failed"),
+ }
+ return pl.SetLogError(&event, input)
+ }
+
+ doctor_id, err := ud.GetIdByUserId(&input.AuthInfo.User_Id, &event, tx)
+ if err != nil {
+ return err
+ }
+ input.Doctor_Id = doctor_id
+
+ 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.McuOrder
+ var dataList []e.McuOrder
+ 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.McuOrder
+ 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.McuOrder
+ 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
+ }
+
+ if data.IsCompleted() {
+ return errors.New("data already completed")
+ }
+
+ mwRunner := newMiddlewareRunner(&event, tx)
+ mwRunner.setMwType(pu.MWTPre)
+ // Run pre-middleware
+ if err := mwRunner.RunUpdateMiddleware(readDetailPreMw, &rdDto, data); err != nil {
+ return err
+ }
+
+ if !input.AuthInfo.IsDoctor() {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "auth-forbidden",
+ Detail: "user position is not allowed",
+ Raw: errors.New("authentication failed"),
+ }
+ return pl.SetLogError(&event, input)
+ }
+
+ doctor_id, err := ud.GetIdByUserId(&input.AuthInfo.User_Id, &event, tx)
+ if err != nil {
+ return err
+ }
+
+ if !data.IsSameDoctor(doctor_id) {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "auth-forbidden",
+ Detail: "doctor is not the same as the data",
+ Raw: errors.New("authentication failed"),
+ }
+ return pl.SetLogError(&event, input)
+ }
+
+ input.Doctor_Id = doctor_id
+
+ 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.McuOrder
+ 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 Complete(input e.ReadDetailDto) (*d.Data, error) {
+ var data *e.McuOrder
+ var err error
+
+ event := pl.Event{
+ Feature: "Complete",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "complete")
+
+ err = dg.I.Transaction(func(tx *gorm.DB) error {
+ data, err = ReadDetailData(input, &event, tx)
+ if err != nil {
+ return err
+ }
+
+ if data.IsCompleted() {
+ return errors.New("data already completed")
+ }
+
+ data.Status_Code = erc.DSCDone
+ 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
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &d.Data{
+ Meta: d.IS{
+ "source": source,
+ "structure": "single-data",
+ "status": "fetched",
+ },
+ Data: data.ToResponse(),
+ }, nil
+}
+
+func SetSchedule(input e.SetScheduleDto) (*d.Data, error) {
+ rdDto := e.ReadDetailDto{Id: input.Id}
+ var data *e.McuOrder
+ var err error
+
+ event := pl.Event{
+ Feature: "SetSchedule",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "setSchedule")
+
+ err = dg.I.Transaction(func(tx *gorm.DB) error {
+ pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail")
+ data, err = ReadDetailData(rdDto, &event, tx)
+ if err != nil {
+ return err
+ }
+ if data.IsCompleted() {
+ return errors.New("data already completed")
+ }
+
+ data.ExaminationDate = input.ExaminationDate
+ 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
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &d.Data{
+ Meta: d.IS{
+ "source": source,
+ "structure": "single-data",
+ "status": "setSchedule",
+ },
+ Data: data.ToResponse(),
+ }, nil
+}
diff --git a/internal/use-case/main-use-case/mcu-order/helper.go b/internal/use-case/main-use-case/mcu-order/helper.go
new file mode 100644
index 00000000..8c7115b6
--- /dev/null
+++ b/internal/use-case/main-use-case/mcu-order/helper.go
@@ -0,0 +1,31 @@
+/*
+DESCRIPTION:
+Any functions that are used internally by the use-case
+*/
+package mcuorder
+
+import (
+ e "simrs-vx/internal/domain/main-entities/mcu-order"
+
+ erc "simrs-vx/internal/domain/references/common"
+)
+
+func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.McuOrder) {
+ var inputSrc *e.CreateDto
+ if inputT, ok := any(input).(*e.CreateDto); ok {
+ inputSrc = inputT
+ data.Status_Code = erc.DSCNew
+ } else {
+ inputTemp := any(input).(*e.UpdateDto)
+ inputSrc = &inputTemp.CreateDto
+ }
+
+ data.Encounter_Id = inputSrc.Encounter_Id
+ data.Doctor_Id = inputSrc.Doctor_Id
+ data.SpecimenPickTime = inputSrc.SpecimenPickTime
+ data.ExaminationDate = inputSrc.ExaminationDate
+ data.Number = inputSrc.Number
+ data.Temperature = inputSrc.Temperature
+ data.McuUrgencyLevel_Code = inputSrc.McuUrgencyLevel_Code
+ data.Doctor_Id = inputSrc.Doctor_Id
+}
diff --git a/internal/use-case/main-use-case/mcu-order/lib.go b/internal/use-case/main-use-case/mcu-order/lib.go
new file mode 100644
index 00000000..ccb63db9
--- /dev/null
+++ b/internal/use-case/main-use-case/mcu-order/lib.go
@@ -0,0 +1,164 @@
+package mcuorder
+
+import (
+ e "simrs-vx/internal/domain/main-entities/mcu-order"
+
+ 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.McuOrder, error) {
+ pl.SetLogInfo(event, nil, "started", "DBCreate")
+
+ data := e.McuOrder{}
+ 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.McuOrder, *e.MetaDto, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadList")
+ data := []e.McuOrder{}
+ 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.McuOrder{}).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
+ Count(&count).
+ Scopes(gh.Paginate(input, &pagination)).
+ Order("\"CreatedAt\" DESC")
+
+ if err := tx.Find(&data).Error; err != nil {
+ if err == gorm.ErrRecordNotFound {
+ return nil, &meta, nil
+ }
+ return nil, nil, plh.HandleListError(input, event, err)
+ }
+
+ meta.Count = int(count)
+ meta.PageNumber = pagination.PageNumber
+ meta.PageSize = pagination.PageSize
+
+ pl.SetLogInfo(event, nil, "complete")
+ return data, &meta, nil
+}
+
+func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.McuOrder, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadDetail")
+ data := e.McuOrder{}
+
+ 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.McuOrder, 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.McuOrder, 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
+}
+
+func IsCompleted(mcuOrder_id uint, event *pl.Event, dbx ...*gorm.DB) bool {
+ pl.SetLogInfo(event, nil, "started", "DBIsCompleted")
+ var tx *gorm.DB
+ if len(dbx) > 0 {
+ tx = dbx[0]
+ } else {
+ tx = dg.I
+ }
+
+ var data e.McuOrder
+ if err := tx.Where("\"Id\" = ?", mcuOrder_id).First(&data).Error; err != nil {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-get-fail",
+ Detail: "Database get failed",
+ Raw: err,
+ }
+ return false
+ }
+
+ pl.SetLogInfo(event, nil, "complete")
+ return data.IsCompleted()
+}
diff --git a/internal/use-case/main-use-case/mcu-order/middleware-runner.go b/internal/use-case/main-use-case/mcu-order/middleware-runner.go
new file mode 100644
index 00000000..00db4da6
--- /dev/null
+++ b/internal/use-case/main-use-case/mcu-order/middleware-runner.go
@@ -0,0 +1,103 @@
+package mcuorder
+
+import (
+ e "simrs-vx/internal/domain/main-entities/mcu-order"
+ 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.McuOrder) 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.McuOrder) 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.McuOrder) 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.McuOrder) 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.McuOrder) 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/mcu-order/middleware.go b/internal/use-case/main-use-case/mcu-order/middleware.go
new file mode 100644
index 00000000..7c033a49
--- /dev/null
+++ b/internal/use-case/main-use-case/mcu-order/middleware.go
@@ -0,0 +1,9 @@
+package mcuorder
+
+// 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/mcu-order/tycovar.go b/internal/use-case/main-use-case/mcu-order/tycovar.go
new file mode 100644
index 00000000..a4c8de62
--- /dev/null
+++ b/internal/use-case/main-use-case/mcu-order/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 mcuorder
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/main-entities/mcu-order"
+)
+
+type createMw struct {
+ Name string
+ Func func(input *e.CreateDto, data *e.McuOrder, tx *gorm.DB) error
+}
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.McuOrder, tx *gorm.DB) error
+}
+
+type readDetailMw struct {
+ Name string
+ Func func(input *e.ReadDetailDto, data *e.McuOrder, 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/mcu-src-category/case.go b/internal/use-case/main-use-case/mcu-src-category/case.go
index 004d97f2..c105603c 100644
--- a/internal/use-case/main-use-case/mcu-src-category/case.go
+++ b/internal/use-case/main-use-case/mcu-src-category/case.go
@@ -106,12 +106,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
diff --git a/internal/use-case/main-use-case/mcu-src-category/lib.go b/internal/use-case/main-use-case/mcu-src-category/lib.go
index d62184d1..0cd44cfd 100644
--- a/internal/use-case/main-use-case/mcu-src-category/lib.go
+++ b/internal/use-case/main-use-case/mcu-src-category/lib.go
@@ -2,6 +2,8 @@ package mcusrccategory
import (
e "simrs-vx/internal/domain/main-entities/mcu-src-category"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.McuSrcC
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -53,24 +49,19 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Mc
tx = tx.
Model(&e.McuSrcCategory{}).
- Scopes(gh.Filter(input)).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
- Order("\"CreatedAt\" DESC")
+ Scopes(gh.Sort(input.Sort))
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-get-fail",
- Detail: "Database get failed",
- Raw: err,
- }
- return nil, nil, pl.SetLogError(event, input)
-
+ return nil, nil, plh.HandleListError(input, event, err)
}
+
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
diff --git a/internal/use-case/main-use-case/mcu-src/case.go b/internal/use-case/main-use-case/mcu-src/case.go
index ae7a1860..564a582b 100644
--- a/internal/use-case/main-use-case/mcu-src/case.go
+++ b/internal/use-case/main-use-case/mcu-src/case.go
@@ -34,6 +34,10 @@ func Create(input e.CreateDto) (*d.Data, error) {
return err
}
+ if err := createItem(&input, &event, tx); err != nil {
+ return err
+ }
+
if resData, err := CreateData(input, &event, tx); err != nil {
return err
} else {
@@ -87,9 +91,6 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
return err
}
- if len(input.Includes) > 0 {
- input.Preloads = pu.GetPreloads(input.Includes)
- }
if dataList, metaList, err = ReadListData(input, &event, tx); err != nil {
return err
}
@@ -109,12 +110,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
diff --git a/internal/use-case/main-use-case/mcu-src/helper.go b/internal/use-case/main-use-case/mcu-src/helper.go
index 820dbfa7..9d808ca8 100644
--- a/internal/use-case/main-use-case/mcu-src/helper.go
+++ b/internal/use-case/main-use-case/mcu-src/helper.go
@@ -5,7 +5,17 @@ Any functions that are used internally by the use-case
package mcusrc
import (
+ ei "simrs-vx/internal/domain/main-entities/item"
e "simrs-vx/internal/domain/main-entities/mcu-src"
+
+ ui "simrs-vx/internal/use-case/main-use-case/item"
+
+ pl "simrs-vx/pkg/logger"
+ pu "simrs-vx/pkg/use-case-helper"
+
+ ero "simrs-vx/internal/domain/references/organization"
+
+ "gorm.io/gorm"
)
func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.McuSrc) {
@@ -19,5 +29,22 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.McuSrc) {
data.Code = inputSrc.Code
data.Name = inputSrc.Name
- data.CheckupCategory_Code = inputSrc.CheckupCategory_Code
+ data.McuSrcCategory_Code = inputSrc.McuSrcCategory_Code
+}
+
+func createItem(input *e.CreateDto, event *pl.Event, tx *gorm.DB) error {
+ itemCreate := ei.CreateDto{
+ Code: pu.AddPrefix("mcu-", input.Code),
+ Name: input.Name,
+ ItemGroup_Code: ero.ITGCMCU,
+ // Uom_Code: &input.Uom_Code,
+ // Infra_Id: input.Infra_Id,
+ }
+ item, err := ui.CreateData(itemCreate, event, tx)
+ if err != nil {
+ return err
+ }
+
+ input.Item_Id = &item.Id
+ return nil
}
diff --git a/internal/use-case/main-use-case/mcu-src/lib.go b/internal/use-case/main-use-case/mcu-src/lib.go
index e7e76041..e74d5ce8 100644
--- a/internal/use-case/main-use-case/mcu-src/lib.go
+++ b/internal/use-case/main-use-case/mcu-src/lib.go
@@ -2,6 +2,8 @@ package mcusrc
import (
e "simrs-vx/internal/domain/main-entities/mcu-src"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.McuSrc,
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -51,32 +47,21 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Mc
tx = dg.I
}
- if len(input.Preloads) > 0 {
- for _, preload := range input.Preloads {
- tx = tx.Preload(preload)
- }
- }
-
tx = tx.
Model(&e.McuSrc{}).
+ Scopes(gh.Preload(input.Includes)).
Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
- Order("\"CreatedAt\" DESC")
+ Scopes(gh.Sort(input.Sort))
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-get-fail",
- Detail: "Database get failed",
- Raw: err,
- }
- return nil, nil, pl.SetLogError(event, input)
-
+ return nil, nil, plh.HandleListError(input, event, err)
}
+
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
diff --git a/internal/use-case/main-use-case/mcu-sub-src/case.go b/internal/use-case/main-use-case/mcu-sub-src/case.go
new file mode 100644
index 00000000..ba533bc4
--- /dev/null
+++ b/internal/use-case/main-use-case/mcu-sub-src/case.go
@@ -0,0 +1,280 @@
+package mcusubsrc
+
+import (
+ e "simrs-vx/internal/domain/main-entities/mcu-sub-src"
+ "strconv"
+
+ dg "github.com/karincake/apem/db-gorm-pg"
+ d "github.com/karincake/dodol"
+
+ pl "simrs-vx/pkg/logger"
+ pu "simrs-vx/pkg/use-case-helper"
+
+ "gorm.io/gorm"
+)
+
+const source = "mcu-sub-src"
+
+func Create(input e.CreateDto) (*d.Data, error) {
+ data := e.McuSubSrc{}
+
+ 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 := createItem(&input, &event, tx); 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.McuSubSrc
+ var dataList []e.McuSubSrc
+ 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.McuSubSrc
+ 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.McuSubSrc
+ 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.McuSubSrc
+ 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/mcu-sub-src/helper.go b/internal/use-case/main-use-case/mcu-sub-src/helper.go
new file mode 100644
index 00000000..95444d5a
--- /dev/null
+++ b/internal/use-case/main-use-case/mcu-sub-src/helper.go
@@ -0,0 +1,51 @@
+/*
+DESCRIPTION:
+Any functions that are used internally by the use-case
+*/
+package mcusubsrc
+
+import (
+ ei "simrs-vx/internal/domain/main-entities/item"
+ e "simrs-vx/internal/domain/main-entities/mcu-sub-src"
+
+ ui "simrs-vx/internal/use-case/main-use-case/item"
+
+ pl "simrs-vx/pkg/logger"
+ pu "simrs-vx/pkg/use-case-helper"
+
+ ero "simrs-vx/internal/domain/references/organization"
+
+ "gorm.io/gorm"
+)
+
+func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.McuSubSrc) {
+ var inputSrc *e.CreateDto
+ if inputT, ok := any(input).(*e.CreateDto); ok {
+ inputSrc = inputT
+ } else {
+ inputTemp := any(input).(*e.UpdateDto)
+ inputSrc = &inputTemp.CreateDto
+ }
+
+ data.Code = inputSrc.Code
+ data.Name = inputSrc.Name
+ data.McuSrc_Id = inputSrc.McuSrc_Id
+ data.Item_Id = inputSrc.Item_Id
+}
+
+func createItem(input *e.CreateDto, event *pl.Event, tx *gorm.DB) error {
+ itemCreate := ei.CreateDto{
+ Code: pu.AddPrefix("mcuSub-", input.Code),
+ Name: input.Name,
+ ItemGroup_Code: ero.ITGCMCUSub,
+ // Uom_Code: &input.Uom_Code,
+ // Infra_Id: input.Infra_Id,
+ }
+ item, err := ui.CreateData(itemCreate, event, tx)
+ if err != nil {
+ return err
+ }
+
+ input.Item_Id = &item.Id
+ return nil
+}
diff --git a/internal/use-case/main-use-case/mcu-sub-src/lib.go b/internal/use-case/main-use-case/mcu-sub-src/lib.go
new file mode 100644
index 00000000..96684fef
--- /dev/null
+++ b/internal/use-case/main-use-case/mcu-sub-src/lib.go
@@ -0,0 +1,140 @@
+package mcusubsrc
+
+import (
+ e "simrs-vx/internal/domain/main-entities/mcu-sub-src"
+
+ 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.McuSubSrc, error) {
+ pl.SetLogInfo(event, nil, "started", "DBCreate")
+
+ data := e.McuSubSrc{}
+ 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.McuSubSrc, *e.MetaDto, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadList")
+ data := []e.McuSubSrc{}
+ 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.McuSubSrc{}).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
+ Count(&count).
+ Scopes(gh.Paginate(input, &pagination)).
+ Scopes(gh.Sort(input.Sort))
+
+ if err := tx.Find(&data).Error; err != nil {
+ if err == gorm.ErrRecordNotFound {
+ return nil, &meta, nil
+ }
+ return nil, nil, plh.HandleListError(input, event, err)
+ }
+
+ meta.Count = int(count)
+ meta.PageNumber = pagination.PageNumber
+ meta.PageSize = pagination.PageSize
+
+ pl.SetLogInfo(event, nil, "complete")
+ return data, &meta, nil
+}
+
+func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.McuSubSrc, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadDetail")
+ data := e.McuSubSrc{}
+
+ 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.McuSubSrc, 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.McuSubSrc, 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/mcu-sub-src/middleware-runner.go b/internal/use-case/main-use-case/mcu-sub-src/middleware-runner.go
new file mode 100644
index 00000000..89d328ed
--- /dev/null
+++ b/internal/use-case/main-use-case/mcu-sub-src/middleware-runner.go
@@ -0,0 +1,103 @@
+package mcusubsrc
+
+import (
+ e "simrs-vx/internal/domain/main-entities/mcu-sub-src"
+ 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.McuSubSrc) 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.McuSubSrc) 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.McuSubSrc) 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.McuSubSrc) 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.McuSubSrc) 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/mcu-sub-src/middleware.go b/internal/use-case/main-use-case/mcu-sub-src/middleware.go
new file mode 100644
index 00000000..a58ac781
--- /dev/null
+++ b/internal/use-case/main-use-case/mcu-sub-src/middleware.go
@@ -0,0 +1,9 @@
+package mcusubsrc
+
+// 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/mcu-sub-src/tycovar.go b/internal/use-case/main-use-case/mcu-sub-src/tycovar.go
new file mode 100644
index 00000000..7522ada4
--- /dev/null
+++ b/internal/use-case/main-use-case/mcu-sub-src/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 mcusubsrc
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/main-entities/mcu-sub-src"
+)
+
+type createMw struct {
+ Name string
+ Func func(input *e.CreateDto, data *e.McuSubSrc, tx *gorm.DB) error
+}
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.McuSubSrc, tx *gorm.DB) error
+}
+
+type readDetailMw struct {
+ Name string
+ Func func(input *e.ReadDetailDto, data *e.McuSubSrc, 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/medical-action-src-item/case.go b/internal/use-case/main-use-case/medical-action-src-item/case.go
index 2efdca2c..7a1eefb7 100644
--- a/internal/use-case/main-use-case/medical-action-src-item/case.go
+++ b/internal/use-case/main-use-case/medical-action-src-item/case.go
@@ -87,9 +87,6 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
return err
}
- if len(input.Includes) > 0 {
- input.Preloads = pu.GetPreloads(input.Includes)
- }
if dataList, metaList, err = ReadListData(input, &event, tx); err != nil {
return err
}
@@ -109,12 +106,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
diff --git a/internal/use-case/main-use-case/medical-action-src-item/lib.go b/internal/use-case/main-use-case/medical-action-src-item/lib.go
index 02d81f6c..723e615d 100644
--- a/internal/use-case/main-use-case/medical-action-src-item/lib.go
+++ b/internal/use-case/main-use-case/medical-action-src-item/lib.go
@@ -2,6 +2,8 @@ package medicalactionsrcitem
import (
e "simrs-vx/internal/domain/main-entities/medical-action-src-item"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Medical
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -51,32 +47,21 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Me
tx = dg.I
}
- if len(input.Preloads) > 0 {
- for _, preload := range input.Preloads {
- tx = tx.Preload(preload)
- }
- }
-
tx = tx.
Model(&e.MedicalActionSrcItem{}).
+ Scopes(gh.Preload(input.Includes)).
Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-get-fail",
- Detail: "Database get failed",
- Raw: err,
- }
- return nil, nil, pl.SetLogError(event, input)
-
+ return nil, nil, plh.HandleListError(input, event, err)
}
+
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
diff --git a/internal/use-case/main-use-case/medical-action-src/case.go b/internal/use-case/main-use-case/medical-action-src/case.go
index 1c0fe565..cd42766c 100644
--- a/internal/use-case/main-use-case/medical-action-src/case.go
+++ b/internal/use-case/main-use-case/medical-action-src/case.go
@@ -34,6 +34,9 @@ func Create(input e.CreateDto) (*d.Data, error) {
return err
}
+ if err := createItem(&input, &event, tx); err != nil {
+ return err
+ }
if resData, err := CreateData(input, &event, tx); err != nil {
return err
} else {
@@ -87,9 +90,6 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
return err
}
- if len(input.Includes) > 0 {
- input.Preloads = pu.GetPreloads(input.Includes)
- }
if dataList, metaList, err = ReadListData(input, &event, tx); err != nil {
return err
}
@@ -109,12 +109,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
diff --git a/internal/use-case/main-use-case/medical-action-src/helper.go b/internal/use-case/main-use-case/medical-action-src/helper.go
index 22c0d26d..c955274d 100644
--- a/internal/use-case/main-use-case/medical-action-src/helper.go
+++ b/internal/use-case/main-use-case/medical-action-src/helper.go
@@ -5,7 +5,17 @@ Any functions that are used internally by the use-case
package medicalactionsrc
import (
+ ei "simrs-vx/internal/domain/main-entities/item"
e "simrs-vx/internal/domain/main-entities/medical-action-src"
+
+ ero "simrs-vx/internal/domain/references/organization"
+
+ ui "simrs-vx/internal/use-case/main-use-case/item"
+
+ pl "simrs-vx/pkg/logger"
+ pu "simrs-vx/pkg/use-case-helper"
+
+ "gorm.io/gorm"
)
func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.MedicalActionSrc) {
@@ -19,5 +29,21 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.MedicalActionSrc) {
data.Code = inputSrc.Code
data.Name = inputSrc.Name
+ data.Type_Code = inputSrc.Type_Code
data.Item_Id = inputSrc.Item_Id
}
+
+func createItem(input *e.CreateDto, event *pl.Event, tx *gorm.DB) error {
+ itemCreate := ei.CreateDto{
+ Code: pu.AddPrefix("medAct-", input.Code),
+ Name: input.Name,
+ ItemGroup_Code: ero.ITGCMedAct,
+ }
+ item, err := ui.CreateData(itemCreate, event, tx)
+ if err != nil {
+ return err
+ }
+
+ input.Item_Id = &item.Id
+ return nil
+}
diff --git a/internal/use-case/main-use-case/medical-action-src/lib.go b/internal/use-case/main-use-case/medical-action-src/lib.go
index 5bef2fca..31492861 100644
--- a/internal/use-case/main-use-case/medical-action-src/lib.go
+++ b/internal/use-case/main-use-case/medical-action-src/lib.go
@@ -2,6 +2,8 @@ package medicalactionsrc
import (
e "simrs-vx/internal/domain/main-entities/medical-action-src"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Medical
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -51,32 +47,21 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Me
tx = dg.I
}
- if len(input.Preloads) > 0 {
- for _, preload := range input.Preloads {
- tx = tx.Preload(preload)
- }
- }
-
tx = tx.
Model(&e.MedicalActionSrc{}).
+ Scopes(gh.Preload(input.Includes)).
Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
- Order("\"CreatedAt\" DESC")
+ Scopes(gh.Sort(input.Sort))
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-get-fail",
- Detail: "Database get failed",
- Raw: err,
- }
- return nil, nil, pl.SetLogError(event, input)
-
+ return nil, nil, plh.HandleListError(input, event, err)
}
+
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
diff --git a/internal/use-case/main-use-case/medication-item-dist/case.go b/internal/use-case/main-use-case/medication-item-dist/case.go
new file mode 100644
index 00000000..ff54c775
--- /dev/null
+++ b/internal/use-case/main-use-case/medication-item-dist/case.go
@@ -0,0 +1,351 @@
+package medicationitemdist
+
+import (
+ "errors"
+ "strconv"
+
+ e "simrs-vx/internal/domain/main-entities/medication-item-dist"
+
+ un "simrs-vx/internal/use-case/main-use-case/nurse"
+
+ 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 = "medication-item-dist"
+
+func Create(input e.CreateDto) (*d.Data, error) {
+ data := e.MedicationItemDist{}
+
+ event := pl.Event{
+ Feature: "Create",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "create")
+
+ err := dg.I.Transaction(func(tx *gorm.DB) error {
+ mwRunner := newMiddlewareRunner(&event, tx)
+ mwRunner.setMwType(pu.MWTPre)
+ // Run pre-middleware
+ if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil {
+ return err
+ }
+
+ if resData, err := CreateData(input, &event, tx); err != nil {
+ return err
+ } else {
+ data = *resData
+ }
+
+ mwRunner.setMwType(pu.MWTPost)
+ // Run post-middleware
+ if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil {
+ return err
+ }
+
+ pl.SetLogInfo(&event, nil, "complete")
+
+ return nil
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &d.Data{
+ Meta: d.II{
+ "source": source,
+ "structure": "single-data",
+ "status": "created",
+ },
+ Data: data.ToResponse(),
+ }, nil
+}
+
+func ReadList(input e.ReadListDto) (*d.Data, error) {
+ var data *e.MedicationItemDist
+ var dataList []e.MedicationItemDist
+ 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.MedicationItemDist
+ 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.MedicationItemDist
+ 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.MedicationItemDist
+ 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 Consume(input e.ConsumeDto) (*d.Data, error) {
+ rdDto := e.ReadDetailDto{Id: input.Id}
+ var data *e.MedicationItemDist
+ var err error
+
+ event := pl.Event{
+ Feature: "Consume",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "consume")
+
+ err = dg.I.Transaction(func(tx *gorm.DB) error {
+ if !input.AuthInfo.IsNurse() {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "auth-forbidden",
+ Detail: "user position is not allowed",
+ Raw: errors.New("authentication failed"),
+ }
+ return pl.SetLogError(&event, input)
+ }
+
+ nurse_id, err := un.GetIdByUserId(&input.AuthInfo.User_Id, &event, tx)
+ if err != nil {
+ return err
+ }
+
+ if data, err = ReadDetailData(rdDto, &event, tx); err != nil {
+ return err
+ }
+
+ if data.Remain <= 0 {
+ return errors.New("data already consumed")
+ } else if data.Remain < input.Usage {
+ return errors.New("data remain less than usage")
+ }
+
+ data.Remain -= input.Usage
+ data.Nurse_Id = nurse_id
+
+ 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
+ })
+
+ 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/medication-item-dist/helper.go b/internal/use-case/main-use-case/medication-item-dist/helper.go
new file mode 100644
index 00000000..5b1b1d35
--- /dev/null
+++ b/internal/use-case/main-use-case/medication-item-dist/helper.go
@@ -0,0 +1,24 @@
+/*
+DESCRIPTION:
+Any functions that are used internally by the use-case
+*/
+package medicationitemdist
+
+import (
+ e "simrs-vx/internal/domain/main-entities/medication-item-dist"
+)
+
+func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.MedicationItemDist) {
+ var inputSrc *e.CreateDto
+ if inputT, ok := any(input).(*e.CreateDto); ok {
+ inputSrc = inputT
+ } else {
+ inputTemp := any(input).(*e.UpdateDto)
+ inputSrc = &inputTemp.CreateDto
+ }
+
+ data.MedicationItem_Id = inputSrc.MedicationItem_Id
+ data.DateTime = inputSrc.DateTime
+ data.Remain = inputSrc.Remain
+ data.Nurse_Id = inputSrc.Nurse_Id
+}
diff --git a/internal/use-case/main-use-case/medication-item-dist/lib.go b/internal/use-case/main-use-case/medication-item-dist/lib.go
new file mode 100644
index 00000000..88638d2f
--- /dev/null
+++ b/internal/use-case/main-use-case/medication-item-dist/lib.go
@@ -0,0 +1,140 @@
+package medicationitemdist
+
+import (
+ e "simrs-vx/internal/domain/main-entities/medication-item-dist"
+
+ 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.MedicationItemDist, error) {
+ pl.SetLogInfo(event, nil, "started", "DBCreate")
+
+ data := e.MedicationItemDist{}
+ 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.MedicationItemDist, *e.MetaDto, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadList")
+ data := []e.MedicationItemDist{}
+ 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.MedicationItemDist{}).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
+ Count(&count).
+ Scopes(gh.Paginate(input, &pagination)).
+ Order("\"CreatedAt\" DESC")
+
+ if err := tx.Find(&data).Error; err != nil {
+ if err == gorm.ErrRecordNotFound {
+ return nil, &meta, nil
+ }
+ return nil, nil, plh.HandleListError(input, event, err)
+ }
+
+ meta.Count = int(count)
+ meta.PageNumber = pagination.PageNumber
+ meta.PageSize = pagination.PageSize
+
+ pl.SetLogInfo(event, nil, "complete")
+ return data, &meta, nil
+}
+
+func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.MedicationItemDist, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadDetail")
+ data := e.MedicationItemDist{}
+
+ 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.MedicationItemDist, 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.MedicationItemDist, 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/medication-item-dist/middleware-runner.go b/internal/use-case/main-use-case/medication-item-dist/middleware-runner.go
new file mode 100644
index 00000000..8dc45e4f
--- /dev/null
+++ b/internal/use-case/main-use-case/medication-item-dist/middleware-runner.go
@@ -0,0 +1,103 @@
+package medicationitemdist
+
+import (
+ e "simrs-vx/internal/domain/main-entities/medication-item-dist"
+ 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.MedicationItemDist) 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.MedicationItemDist) 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.MedicationItemDist) 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.MedicationItemDist) 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.MedicationItemDist) 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/medication-item-dist/middleware.go b/internal/use-case/main-use-case/medication-item-dist/middleware.go
new file mode 100644
index 00000000..e519da96
--- /dev/null
+++ b/internal/use-case/main-use-case/medication-item-dist/middleware.go
@@ -0,0 +1,9 @@
+package medicationitemdist
+
+// 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/medication-item-dist/tycovar.go b/internal/use-case/main-use-case/medication-item-dist/tycovar.go
new file mode 100644
index 00000000..38334e8b
--- /dev/null
+++ b/internal/use-case/main-use-case/medication-item-dist/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 medicationitemdist
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/main-entities/medication-item-dist"
+)
+
+type createMw struct {
+ Name string
+ Func func(input *e.CreateDto, data *e.MedicationItemDist, tx *gorm.DB) error
+}
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.MedicationItemDist, tx *gorm.DB) error
+}
+
+type readDetailMw struct {
+ Name string
+ Func func(input *e.ReadDetailDto, data *e.MedicationItemDist, 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/medication-item/case.go b/internal/use-case/main-use-case/medication-item/case.go
new file mode 100644
index 00000000..0e04b6b0
--- /dev/null
+++ b/internal/use-case/main-use-case/medication-item/case.go
@@ -0,0 +1,329 @@
+package medicationitem
+
+import (
+ "errors"
+ "strconv"
+
+ e "simrs-vx/internal/domain/main-entities/medication-item"
+
+ 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 = "medication-item"
+
+func Create(input e.CreateDto) (*d.Data, error) {
+ data := e.MedicationItem{}
+
+ event := pl.Event{
+ Feature: "Create",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "create")
+
+ err := dg.I.Transaction(func(tx *gorm.DB) error {
+ mwRunner := newMiddlewareRunner(&event, tx)
+ mwRunner.setMwType(pu.MWTPre)
+ // Run pre-middleware
+ if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil {
+ return err
+ }
+
+ if resData, err := CreateData(input, &event, tx); err != nil {
+ return err
+ } else {
+ data = *resData
+ }
+
+ mwRunner.setMwType(pu.MWTPost)
+ // Run post-middleware
+ if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil {
+ return err
+ }
+
+ pl.SetLogInfo(&event, nil, "complete")
+
+ return nil
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &d.Data{
+ Meta: d.II{
+ "source": source,
+ "structure": "single-data",
+ "status": "created",
+ },
+ Data: data.ToResponse(),
+ }, nil
+}
+
+func ReadList(input e.ReadListDto) (*d.Data, error) {
+ var data *e.MedicationItem
+ var dataList []e.MedicationItem
+ 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.MedicationItem
+ 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.MedicationItem
+ 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.MedicationItem
+ 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 Redeem(input e.ReadDetailDto) (*d.Data, error) {
+ var data *e.MedicationItem
+ var err error
+
+ event := pl.Event{
+ Feature: "Redeem",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "redeem")
+
+ err = dg.I.Transaction(func(tx *gorm.DB) error {
+ data, err = ReadDetailData(input, &event, tx)
+ if err != nil {
+ return err
+ }
+
+ if data.IsRedeemed {
+ return errors.New("data already redeemed")
+ }
+
+ data.IsRedeemed = true
+ 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
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &d.Data{
+ Meta: d.IS{
+ "source": source,
+ "structure": "single-data",
+ "status": "fetched",
+ },
+ Data: data.ToResponse(),
+ }, nil
+}
diff --git a/internal/use-case/main-use-case/medication-item/helper.go b/internal/use-case/main-use-case/medication-item/helper.go
new file mode 100644
index 00000000..dcee2cac
--- /dev/null
+++ b/internal/use-case/main-use-case/medication-item/helper.go
@@ -0,0 +1,43 @@
+/*
+DESCRIPTION:
+Any functions that are used internally by the use-case
+*/
+package medicationitem
+
+import (
+ e "simrs-vx/internal/domain/main-entities/medication-item"
+)
+
+func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.MedicationItem) {
+ var inputSrc *e.CreateDto
+ if inputT, ok := any(input).(*e.CreateDto); ok {
+ inputSrc = inputT
+ } else {
+ inputTemp := any(input).(*e.UpdateDto)
+ inputSrc = &inputTemp.CreateDto
+ }
+
+ data.Medication_Id = inputSrc.Medication_Id
+ data.IsMix = inputSrc.IsMix
+ data.Medicine_Id = inputSrc.Medicine_Id
+ data.MedicineMix_Id = inputSrc.MedicineMix_Id
+ data.Frequency = inputSrc.Frequency
+ data.Dose = inputSrc.Dose
+ data.Usage = inputSrc.Usage
+ data.Interval = inputSrc.Interval
+ data.IntervalUnit_Code = inputSrc.IntervalUnit_Code
+ data.IsRedeemed = inputSrc.IsRedeemed
+ data.Quantity = inputSrc.Quantity
+ data.Note = inputSrc.Note
+
+ if inputSrc.IntervalMultiplier != nil {
+ data.Quantity = countQty(*inputSrc)
+ }
+}
+
+func countQty(input e.CreateDto) float64 {
+ if input.Frequency != nil && input.Dose != 0 && input.IntervalMultiplier != nil {
+ return (float64(*input.Frequency) * float64(input.Dose)) * float64(*input.IntervalMultiplier)
+ }
+ return 0
+}
diff --git a/internal/use-case/main-use-case/medication-item/lib.go b/internal/use-case/main-use-case/medication-item/lib.go
new file mode 100644
index 00000000..f918878b
--- /dev/null
+++ b/internal/use-case/main-use-case/medication-item/lib.go
@@ -0,0 +1,140 @@
+package medicationitem
+
+import (
+ e "simrs-vx/internal/domain/main-entities/medication-item"
+
+ plh "simrs-vx/pkg/lib-helper"
+ pl "simrs-vx/pkg/logger"
+ pu "simrs-vx/pkg/use-case-helper"
+
+ dg "github.com/karincake/apem/db-gorm-pg"
+ gh "github.com/karincake/getuk"
+ "gorm.io/gorm"
+)
+
+func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.MedicationItem, error) {
+ pl.SetLogInfo(event, nil, "started", "DBCreate")
+
+ data := e.MedicationItem{}
+ 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.MedicationItem, *e.MetaDto, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadList")
+ data := []e.MedicationItem{}
+ 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.MedicationItem{}).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
+ Count(&count).
+ Scopes(gh.Paginate(input, &pagination)).
+ Order("\"CreatedAt\" DESC")
+
+ if err := tx.Find(&data).Error; err != nil {
+ if err == gorm.ErrRecordNotFound {
+ return nil, &meta, nil
+ }
+ return nil, nil, plh.HandleListError(input, event, err)
+ }
+
+ meta.Count = int(count)
+ meta.PageNumber = pagination.PageNumber
+ meta.PageSize = pagination.PageSize
+
+ pl.SetLogInfo(event, nil, "complete")
+ return data, &meta, nil
+}
+
+func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.MedicationItem, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadDetail")
+ data := e.MedicationItem{}
+
+ 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.MedicationItem, 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.MedicationItem, 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/medication-item/middleware-runner.go b/internal/use-case/main-use-case/medication-item/middleware-runner.go
new file mode 100644
index 00000000..875f8235
--- /dev/null
+++ b/internal/use-case/main-use-case/medication-item/middleware-runner.go
@@ -0,0 +1,103 @@
+package medicationitem
+
+import (
+ e "simrs-vx/internal/domain/main-entities/medication-item"
+ pl "simrs-vx/pkg/logger"
+ pu "simrs-vx/pkg/use-case-helper"
+
+ "gorm.io/gorm"
+)
+
+type middlewareRunner struct {
+ Event *pl.Event
+ Tx *gorm.DB
+ MwType pu.MWType
+}
+
+// NewMiddlewareExecutor creates a new middleware executor
+func newMiddlewareRunner(event *pl.Event, tx *gorm.DB) *middlewareRunner {
+ return &middlewareRunner{
+ Event: event,
+ Tx: tx,
+ }
+}
+
+// ExecuteCreateMiddleware executes create middleware
+func (me *middlewareRunner) RunCreateMiddleware(middlewares []createMw, input *e.CreateDto, data *e.MedicationItem) 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.MedicationItem) 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.MedicationItem) 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.MedicationItem) 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.MedicationItem) 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/medication-item/middleware.go b/internal/use-case/main-use-case/medication-item/middleware.go
new file mode 100644
index 00000000..5fa37ffe
--- /dev/null
+++ b/internal/use-case/main-use-case/medication-item/middleware.go
@@ -0,0 +1,9 @@
+package medicationitem
+
+// 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/medication-item/tycovar.go b/internal/use-case/main-use-case/medication-item/tycovar.go
new file mode 100644
index 00000000..04d1d95b
--- /dev/null
+++ b/internal/use-case/main-use-case/medication-item/tycovar.go
@@ -0,0 +1,44 @@
+/*
+DESCRIPTION:
+A sample, part of the package that contains type, constants, and/or variables.
+
+In this sample it also provides type and variable regarding the needs of the
+middleware to separate from main use-case which has the basic CRUD
+functionality. The purpose of this is to make the code more maintainable.
+*/
+package medicationitem
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/main-entities/medication-item"
+)
+
+type createMw struct {
+ Name string
+ Func func(input *e.CreateDto, data *e.MedicationItem, tx *gorm.DB) error
+}
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.MedicationItem, tx *gorm.DB) error
+}
+
+type readDetailMw struct {
+ Name string
+ Func func(input *e.ReadDetailDto, data *e.MedicationItem, 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/medication/case.go b/internal/use-case/main-use-case/medication/case.go
new file mode 100644
index 00000000..652f2010
--- /dev/null
+++ b/internal/use-case/main-use-case/medication/case.go
@@ -0,0 +1,353 @@
+package medication
+
+import (
+ "errors"
+ "strconv"
+
+ e "simrs-vx/internal/domain/main-entities/medication"
+
+ erc "simrs-vx/internal/domain/references/common"
+
+ up "simrs-vx/internal/use-case/main-use-case/pharmacist"
+
+ 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 = "medication"
+
+func Create(input e.CreateDto) (*d.Data, error) {
+ data := e.Medication{}
+
+ event := pl.Event{
+ Feature: "Create",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "create")
+
+ err := dg.I.Transaction(func(tx *gorm.DB) error {
+ mwRunner := newMiddlewareRunner(&event, tx)
+ mwRunner.setMwType(pu.MWTPre)
+ // Run pre-middleware
+ if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil {
+ return err
+ }
+
+ if resData, err := CreateData(input, &event, tx); err != nil {
+ return err
+ } else {
+ data = *resData
+ }
+
+ mwRunner.setMwType(pu.MWTPost)
+ // Run post-middleware
+ if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil {
+ return err
+ }
+
+ pl.SetLogInfo(&event, nil, "complete")
+
+ return nil
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &d.Data{
+ Meta: d.II{
+ "source": source,
+ "structure": "single-data",
+ "status": "created",
+ },
+ Data: data.ToResponse(),
+ }, nil
+}
+
+func ReadList(input e.ReadListDto) (*d.Data, error) {
+ var data *e.Medication
+ var dataList []e.Medication
+ 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.Medication
+ 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.Medication
+ 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.Medication
+ 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 Complete(input e.ReadDetailDto) (*d.Data, error) {
+ var data *e.Medication
+ var err error
+
+ event := pl.Event{
+ Feature: "Complete",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "complete")
+
+ err = dg.I.Transaction(func(tx *gorm.DB) error {
+ data, err = ReadDetailData(input, &event, tx)
+ if err != nil {
+ return err
+ }
+
+ if data.IsCompleted() {
+ return errors.New("data already completed")
+ }
+
+ if !input.AuthInfo.IsPharmacist() {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "auth-forbidden",
+ Detail: "user position is not allowed",
+ Raw: errors.New("authentication failed"),
+ }
+ return pl.SetLogError(&event, input)
+ }
+
+ pharmacist_id, err := up.GetIdByUserId(&input.AuthInfo.User_Id, &event, tx)
+ if err != nil {
+ return err
+ }
+
+ data.Status_Code = erc.DSCDone
+ data.Pharmacist_Id = pharmacist_id
+ 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)
+ }
+
+ if err := createMedicationItemDist(&data.Id, &event, tx); err != nil {
+ return err
+ }
+
+ pl.SetLogInfo(&event, nil, "complete")
+ return nil
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &d.Data{
+ Meta: d.IS{
+ "source": source,
+ "structure": "single-data",
+ "status": "fetched",
+ },
+ Data: data.ToResponse(),
+ }, nil
+}
diff --git a/internal/use-case/main-use-case/medication/helper.go b/internal/use-case/main-use-case/medication/helper.go
new file mode 100644
index 00000000..63290cb1
--- /dev/null
+++ b/internal/use-case/main-use-case/medication/helper.go
@@ -0,0 +1,66 @@
+/*
+DESCRIPTION:
+Any functions that are used internally by the use-case
+*/
+package medication
+
+import (
+ e "simrs-vx/internal/domain/main-entities/medication"
+ emi "simrs-vx/internal/domain/main-entities/medication-item"
+ emid "simrs-vx/internal/domain/main-entities/medication-item-dist"
+ umi "simrs-vx/internal/use-case/main-use-case/medication-item"
+ umid "simrs-vx/internal/use-case/main-use-case/medication-item-dist"
+
+ pl "simrs-vx/pkg/logger"
+ pu "simrs-vx/pkg/use-case-helper"
+
+ dg "github.com/karincake/apem/db-gorm-pg"
+
+ "gorm.io/gorm"
+)
+
+func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Medication) {
+ 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.IssuedAt = inputSrc.IssuedAt
+ data.Pharmacist_Id = inputSrc.Pharmacist_Id
+ data.Status_Code = inputSrc.Status_Code
+}
+
+func createMedicationItemDist(medication_id *uint, event *pl.Event, dbx ...*gorm.DB) error {
+ pl.SetLogInfo(event, nil, "started", "createMedicationItemDist")
+ var tx *gorm.DB
+ if len(dbx) > 0 {
+ tx = dbx[0]
+ } else {
+ tx = dg.I
+ }
+
+ filterMI := emi.ReadListDto{FilterDto: emi.FilterDto{Medication_Id: medication_id, IsRedeemed: true}, Preloads: []string{"MedicineMix"}}
+ medicationItemList, _, err := umi.ReadListData(filterMI, event, tx)
+ if err != nil {
+ return err
+ }
+ // Nurse id isn't set here because it will be set when medItemDist is consumed by the nurse who is logged in and performing the consume action, so it isn't needed here.
+ for _, medicationItem := range medicationItemList {
+ midCreate := emid.CreateDto{
+ MedicationItem_Id: &medicationItem.Id,
+ DateTime: pu.GetTimeNow(),
+ Remain: medicationItem.Quantity,
+ }
+ if _, err := umid.CreateData(midCreate, event, tx); err != nil {
+ return err
+ }
+
+ }
+
+ pl.SetLogInfo(event, nil, "complete")
+ return nil
+}
diff --git a/internal/use-case/main-use-case/medication/lib.go b/internal/use-case/main-use-case/medication/lib.go
new file mode 100644
index 00000000..b11e7f6a
--- /dev/null
+++ b/internal/use-case/main-use-case/medication/lib.go
@@ -0,0 +1,148 @@
+package medication
+
+import (
+ e "simrs-vx/internal/domain/main-entities/medication"
+
+ 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.Medication, error) {
+ pl.SetLogInfo(event, nil, "started", "DBCreate")
+
+ data := e.Medication{}
+ 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.Medication, *e.MetaDto, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadList")
+ data := []e.Medication{}
+ 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.Medication{}).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
+ Count(&count).
+ Scopes(gh.Paginate(input, &pagination)).
+ Order("\"CreatedAt\" DESC")
+
+ if err := tx.Find(&data).Error; err != nil {
+ if err == gorm.ErrRecordNotFound {
+ return nil, &meta, nil
+ }
+ return nil, nil, plh.HandleListError(input, event, err)
+ }
+
+ meta.Count = int(count)
+ meta.PageNumber = pagination.PageNumber
+ meta.PageSize = pagination.PageSize
+
+ pl.SetLogInfo(event, nil, "complete")
+ return data, &meta, nil
+}
+
+func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.Medication, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadDetail")
+ data := e.Medication{}
+
+ var tx *gorm.DB
+ if len(dbx) > 0 {
+ tx = dbx[0]
+ } else {
+ tx = dg.I
+ }
+
+ if input.Encounter_Id != nil {
+ tx = tx.Where("\"Encounter_Id\" = ?", *input.Encounter_Id)
+ }
+
+ if input.Id != 0 {
+ tx = tx.Where("\"Id\" = ?", input.Id)
+ }
+
+ if err := tx.First(&data).Error; err != nil {
+ if processedErr := pu.HandleReadError(err, event, source, input.Id, data); processedErr != nil {
+ return nil, processedErr
+ }
+ }
+
+ pl.SetLogInfo(event, nil, "complete")
+ return &data, nil
+}
+
+func UpdateData(input e.UpdateDto, data *e.Medication, 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.Medication, 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/medication/middleware-runner.go b/internal/use-case/main-use-case/medication/middleware-runner.go
new file mode 100644
index 00000000..88d9b728
--- /dev/null
+++ b/internal/use-case/main-use-case/medication/middleware-runner.go
@@ -0,0 +1,103 @@
+package medication
+
+import (
+ e "simrs-vx/internal/domain/main-entities/medication"
+ 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.Medication) 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.Medication) 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.Medication) 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.Medication) 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.Medication) 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/medication/middleware.go b/internal/use-case/main-use-case/medication/middleware.go
new file mode 100644
index 00000000..0eac76a7
--- /dev/null
+++ b/internal/use-case/main-use-case/medication/middleware.go
@@ -0,0 +1,9 @@
+package medication
+
+// 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/medication/tycovar.go b/internal/use-case/main-use-case/medication/tycovar.go
new file mode 100644
index 00000000..5c9cbd8b
--- /dev/null
+++ b/internal/use-case/main-use-case/medication/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 medication
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/main-entities/medication"
+)
+
+type createMw struct {
+ Name string
+ Func func(input *e.CreateDto, data *e.Medication, tx *gorm.DB) error
+}
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.Medication, tx *gorm.DB) error
+}
+
+type readDetailMw struct {
+ Name string
+ Func func(input *e.ReadDetailDto, data *e.Medication, 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/medicine-group/case.go b/internal/use-case/main-use-case/medicine-group/case.go
index 66fe35b8..180c6e00 100644
--- a/internal/use-case/main-use-case/medicine-group/case.go
+++ b/internal/use-case/main-use-case/medicine-group/case.go
@@ -106,12 +106,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
diff --git a/internal/use-case/main-use-case/medicine-group/lib.go b/internal/use-case/main-use-case/medicine-group/lib.go
index 6388544c..9c3214a9 100644
--- a/internal/use-case/main-use-case/medicine-group/lib.go
+++ b/internal/use-case/main-use-case/medicine-group/lib.go
@@ -2,6 +2,8 @@ package medicinegroup
import (
e "simrs-vx/internal/domain/main-entities/medicine-group"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Medicin
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -53,24 +49,19 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Me
tx = tx.
Model(&e.MedicineGroup{}).
- Scopes(gh.Filter(input)).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
- Order("\"CreatedAt\" DESC")
+ Scopes(gh.Sort(input.Sort))
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-get-fail",
- Detail: "Database get failed",
- Raw: err,
- }
- return nil, nil, pl.SetLogError(event, input)
-
+ return nil, nil, plh.HandleListError(input, event, err)
}
+
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
diff --git a/internal/use-case/main-use-case/medicine-method/case.go b/internal/use-case/main-use-case/medicine-method/case.go
index 2a672f80..012b77b0 100644
--- a/internal/use-case/main-use-case/medicine-method/case.go
+++ b/internal/use-case/main-use-case/medicine-method/case.go
@@ -106,12 +106,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
diff --git a/internal/use-case/main-use-case/medicine-method/lib.go b/internal/use-case/main-use-case/medicine-method/lib.go
index 8e11d043..a9206cbe 100644
--- a/internal/use-case/main-use-case/medicine-method/lib.go
+++ b/internal/use-case/main-use-case/medicine-method/lib.go
@@ -2,6 +2,8 @@ package medicinemethod
import (
e "simrs-vx/internal/domain/main-entities/medicine-method"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Medicin
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -53,24 +49,19 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Me
tx = tx.
Model(&e.MedicineMethod{}).
- Scopes(gh.Filter(input)).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
- Order("\"CreatedAt\" DESC")
+ Scopes(gh.Sort(input.Sort))
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-get-fail",
- Detail: "Database get failed",
- Raw: err,
- }
- return nil, nil, pl.SetLogError(event, input)
-
+ return nil, nil, plh.HandleListError(input, event, err)
}
+
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
diff --git a/internal/use-case/main-use-case/medicine-mix-item/case.go b/internal/use-case/main-use-case/medicine-mix-item/case.go
index 42145947..6dbb8331 100644
--- a/internal/use-case/main-use-case/medicine-mix-item/case.go
+++ b/internal/use-case/main-use-case/medicine-mix-item/case.go
@@ -87,9 +87,6 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
return err
}
- if len(input.Includes) > 0 {
- input.Preloads = pu.GetPreloads(input.Includes)
- }
if dataList, metaList, err = ReadListData(input, &event, tx); err != nil {
return err
}
@@ -109,12 +106,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
diff --git a/internal/use-case/main-use-case/medicine-mix-item/helper.go b/internal/use-case/main-use-case/medicine-mix-item/helper.go
index d4ac8020..0a64f30c 100644
--- a/internal/use-case/main-use-case/medicine-mix-item/helper.go
+++ b/internal/use-case/main-use-case/medicine-mix-item/helper.go
@@ -20,4 +20,5 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.MedicineMixItem) {
data.MedicineMix_Id = inputSrc.MedicineMix_Id
data.Medicine_Id = inputSrc.Medicine_Id
data.Dose = inputSrc.Dose
+ data.Note = inputSrc.Note
}
diff --git a/internal/use-case/main-use-case/medicine-mix-item/lib.go b/internal/use-case/main-use-case/medicine-mix-item/lib.go
index 3bea8e9c..8851cc5d 100644
--- a/internal/use-case/main-use-case/medicine-mix-item/lib.go
+++ b/internal/use-case/main-use-case/medicine-mix-item/lib.go
@@ -2,6 +2,8 @@ package medicinemixitem
import (
e "simrs-vx/internal/domain/main-entities/medicine-mix-item"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Medicin
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -51,32 +47,21 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Me
tx = dg.I
}
- if len(input.Preloads) > 0 {
- for _, preload := range input.Preloads {
- tx = tx.Preload(preload)
- }
- }
-
tx = tx.
Model(&e.MedicineMixItem{}).
+ Scopes(gh.Preload(input.Includes)).
Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-get-fail",
- Detail: "Database get failed",
- Raw: err,
- }
- return nil, nil, pl.SetLogError(event, input)
-
+ return nil, nil, plh.HandleListError(input, event, err)
}
+
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
diff --git a/internal/use-case/main-use-case/medicine-mix/case.go b/internal/use-case/main-use-case/medicine-mix/case.go
index 13602162..c48a1e17 100644
--- a/internal/use-case/main-use-case/medicine-mix/case.go
+++ b/internal/use-case/main-use-case/medicine-mix/case.go
@@ -106,12 +106,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
diff --git a/internal/use-case/main-use-case/medicine-mix/helper.go b/internal/use-case/main-use-case/medicine-mix/helper.go
index bd0892e0..1427fa49 100644
--- a/internal/use-case/main-use-case/medicine-mix/helper.go
+++ b/internal/use-case/main-use-case/medicine-mix/helper.go
@@ -18,4 +18,5 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.MedicineMix) {
}
data.Name = inputSrc.Name
+ data.Uom_Code = inputSrc.Uom_Code
}
diff --git a/internal/use-case/main-use-case/medicine-mix/lib.go b/internal/use-case/main-use-case/medicine-mix/lib.go
index 2c20870c..329ec556 100644
--- a/internal/use-case/main-use-case/medicine-mix/lib.go
+++ b/internal/use-case/main-use-case/medicine-mix/lib.go
@@ -2,6 +2,8 @@ package medicinemix
import (
e "simrs-vx/internal/domain/main-entities/medicine-mix"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Medicin
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -51,6 +47,8 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Me
tx = dg.I
}
+ tx = tx.Preload("MixItems")
+
tx = tx.
Model(&e.MedicineMix{}).
Scopes(gh.Filter(input)).
@@ -58,7 +56,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Me
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
@@ -90,6 +88,8 @@ func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e
tx = dg.I
}
+ tx = tx.Preload("MixItems")
+
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
diff --git a/internal/use-case/main-use-case/medicine/case.go b/internal/use-case/main-use-case/medicine/case.go
index aa970478..5855d33c 100644
--- a/internal/use-case/main-use-case/medicine/case.go
+++ b/internal/use-case/main-use-case/medicine/case.go
@@ -90,9 +90,6 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
return err
}
- if len(input.Includes) > 0 {
- input.Preloads = pu.GetPreloads(input.Includes)
- }
if dataList, metaList, err = ReadListData(input, &event, tx); err != nil {
return err
}
@@ -112,12 +109,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
diff --git a/internal/use-case/main-use-case/medicine/lib.go b/internal/use-case/main-use-case/medicine/lib.go
index c7295e10..3b9d2fa1 100644
--- a/internal/use-case/main-use-case/medicine/lib.go
+++ b/internal/use-case/main-use-case/medicine/lib.go
@@ -2,6 +2,8 @@ package medicine
import (
e "simrs-vx/internal/domain/main-entities/medicine"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Medicin
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -51,32 +47,21 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Me
tx = dg.I
}
- if len(input.Preloads) > 0 {
- for _, preload := range input.Preloads {
- tx = tx.Preload(preload)
- }
- }
-
tx = tx.
Model(&e.Medicine{}).
+ Scopes(gh.Preload(input.Includes)).
Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
- Order("\"CreatedAt\" DESC")
+ Scopes(gh.Sort(input.Sort))
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-get-fail",
- Detail: "Database get failed",
- Raw: err,
- }
- return nil, nil, pl.SetLogError(event, input)
-
+ return nil, nil, plh.HandleListError(input, event, err)
}
+
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
diff --git a/internal/use-case/main-use-case/midwife/case.go b/internal/use-case/main-use-case/midwife/case.go
new file mode 100644
index 00000000..42047c6e
--- /dev/null
+++ b/internal/use-case/main-use-case/midwife/case.go
@@ -0,0 +1,276 @@
+package midwife
+
+import (
+ e "simrs-vx/internal/domain/main-entities/midwife"
+ "strconv"
+
+ dg "github.com/karincake/apem/db-gorm-pg"
+ d "github.com/karincake/dodol"
+
+ pl "simrs-vx/pkg/logger"
+ pu "simrs-vx/pkg/use-case-helper"
+
+ "gorm.io/gorm"
+)
+
+const source = "midwife"
+
+func Create(input e.CreateDto) (*d.Data, error) {
+ data := e.Midwife{}
+
+ event := pl.Event{
+ Feature: "Create",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "create")
+
+ err := dg.I.Transaction(func(tx *gorm.DB) error {
+ mwRunner := newMiddlewareRunner(&event, tx)
+ mwRunner.setMwType(pu.MWTPre)
+ // Run pre-middleware
+ if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil {
+ return err
+ }
+
+ if resData, err := CreateData(input, &event, tx); err != nil {
+ return err
+ } else {
+ data = *resData
+ }
+
+ mwRunner.setMwType(pu.MWTPost)
+ // Run post-middleware
+ if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil {
+ return err
+ }
+
+ pl.SetLogInfo(&event, nil, "complete")
+
+ return nil
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &d.Data{
+ Meta: d.II{
+ "source": source,
+ "structure": "single-data",
+ "status": "created",
+ },
+ Data: data.ToResponse(),
+ }, nil
+}
+
+func ReadList(input e.ReadListDto) (*d.Data, error) {
+ var data *e.Midwife
+ var dataList []e.Midwife
+ 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.Midwife
+ 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: uint16(input.Id)}
+ var data *e.Midwife
+ 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: uint16(input.Id)}
+ var data *e.Midwife
+ 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/midwife/helper.go b/internal/use-case/main-use-case/midwife/helper.go
new file mode 100644
index 00000000..5be74b86
--- /dev/null
+++ b/internal/use-case/main-use-case/midwife/helper.go
@@ -0,0 +1,22 @@
+/*
+DESCRIPTION:
+Any functions that are used internally by the use-case
+*/
+package midwife
+
+import (
+ e "simrs-vx/internal/domain/main-entities/midwife"
+)
+
+func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Midwife) {
+ var inputSrc *e.CreateDto
+ if inputT, ok := any(input).(*e.CreateDto); ok {
+ inputSrc = inputT
+ } else {
+ inputTemp := any(input).(*e.UpdateDto)
+ inputSrc = &inputTemp.CreateDto
+ }
+
+ data.Employee_Id = inputSrc.Employee_Id
+ data.IHS_Number = inputSrc.IHS_Number
+}
diff --git a/internal/use-case/main-use-case/midwife/lib.go b/internal/use-case/main-use-case/midwife/lib.go
new file mode 100644
index 00000000..5e247c34
--- /dev/null
+++ b/internal/use-case/main-use-case/midwife/lib.go
@@ -0,0 +1,146 @@
+package midwife
+
+import (
+ e "simrs-vx/internal/domain/main-entities/midwife"
+
+ 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.Midwife, error) {
+ pl.SetLogInfo(event, nil, "started", "DBCreate")
+
+ data := e.Midwife{}
+ 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.Midwife, *e.MetaDto, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadList")
+ data := []e.Midwife{}
+ 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.Midwife{}).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
+ Count(&count).
+ Scopes(gh.Paginate(input, &pagination)).
+ Order("\"CreatedAt\" DESC")
+
+ if err := tx.Find(&data).Error; err != nil {
+ if err == gorm.ErrRecordNotFound {
+ return nil, &meta, nil
+ }
+ return nil, nil, plh.HandleListError(input, event, err)
+ }
+
+ meta.Count = int(count)
+ meta.PageNumber = pagination.PageNumber
+ meta.PageSize = pagination.PageSize
+
+ pl.SetLogInfo(event, nil, "complete")
+ return data, &meta, nil
+}
+
+func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.Midwife, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadDetail")
+ data := e.Midwife{}
+
+ var tx *gorm.DB
+ if len(dbx) > 0 {
+ tx = dbx[0]
+ } else {
+ tx = dg.I
+ }
+
+ if input.Employee_Id != nil {
+ tx = tx.Where("\"Employee_Id\" = ?", *input.Employee_Id)
+ }
+ if input.Id > 0 {
+ tx = tx.Where("\"Id\" = ?", input.Id)
+ }
+ if err := tx.First(&data).Error; err != nil {
+ if processedErr := pu.HandleReadError(err, event, source, input.Id, data); processedErr != nil {
+ return nil, processedErr
+ }
+ }
+
+ pl.SetLogInfo(event, nil, "complete")
+ return &data, nil
+}
+
+func UpdateData(input e.UpdateDto, data *e.Midwife, 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.Midwife, 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/midwife/middleware-runner.go b/internal/use-case/main-use-case/midwife/middleware-runner.go
new file mode 100644
index 00000000..dae4e27b
--- /dev/null
+++ b/internal/use-case/main-use-case/midwife/middleware-runner.go
@@ -0,0 +1,103 @@
+package midwife
+
+import (
+ e "simrs-vx/internal/domain/main-entities/midwife"
+ 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.Midwife) 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.Midwife) 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.Midwife) 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.Midwife) 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.Midwife) 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/midwife/middleware.go b/internal/use-case/main-use-case/midwife/middleware.go
new file mode 100644
index 00000000..c7afa001
--- /dev/null
+++ b/internal/use-case/main-use-case/midwife/middleware.go
@@ -0,0 +1,9 @@
+package midwife
+
+// 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/midwife/tycovar.go b/internal/use-case/main-use-case/midwife/tycovar.go
new file mode 100644
index 00000000..953d8e20
--- /dev/null
+++ b/internal/use-case/main-use-case/midwife/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 midwife
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/main-entities/midwife"
+)
+
+type createMw struct {
+ Name string
+ Func func(input *e.CreateDto, data *e.Midwife, tx *gorm.DB) error
+}
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.Midwife, tx *gorm.DB) error
+}
+
+type readDetailMw struct {
+ Name string
+ Func func(input *e.ReadDetailDto, data *e.Midwife, 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/nurse/case.go b/internal/use-case/main-use-case/nurse/case.go
index 509be4dd..6201e15b 100644
--- a/internal/use-case/main-use-case/nurse/case.go
+++ b/internal/use-case/main-use-case/nurse/case.go
@@ -87,9 +87,6 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
return err
}
- if len(input.Includes) > 0 {
- input.Preloads = pu.GetPreloads(input.Includes)
- }
if dataList, metaList, err = ReadListData(input, &event, tx); err != nil {
return err
}
@@ -109,12 +106,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
diff --git a/internal/use-case/main-use-case/nurse/helper.go b/internal/use-case/main-use-case/nurse/helper.go
index d746e18e..5ecb6f20 100644
--- a/internal/use-case/main-use-case/nurse/helper.go
+++ b/internal/use-case/main-use-case/nurse/helper.go
@@ -20,4 +20,5 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Nurse) {
data.Employee_Id = inputSrc.Employee_Id
data.IHS_Number = inputSrc.IHS_Number
data.Unit_Id = inputSrc.Unit_Id
+ data.Infra_Id = inputSrc.Infra_Id
}
diff --git a/internal/use-case/main-use-case/nurse/lib.go b/internal/use-case/main-use-case/nurse/lib.go
index 723829b6..a59cc692 100644
--- a/internal/use-case/main-use-case/nurse/lib.go
+++ b/internal/use-case/main-use-case/nurse/lib.go
@@ -2,6 +2,8 @@ package nurse
import (
e "simrs-vx/internal/domain/main-entities/nurse"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Nurse,
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -51,32 +47,21 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Nu
tx = dg.I
}
- if len(input.Preloads) > 0 {
- for _, preload := range input.Preloads {
- tx = tx.Preload(preload)
- }
- }
-
tx = tx.
Model(&e.Nurse{}).
+ Scopes(gh.Preload(input.Includes)).
Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-get-fail",
- Detail: "Database get failed",
- Raw: err,
- }
- return nil, nil, pl.SetLogError(event, input)
-
+ return nil, nil, plh.HandleListError(input, event, err)
}
+
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
@@ -159,3 +144,34 @@ func DeleteData(data *e.Nurse, event *pl.Event, dbx ...*gorm.DB) error {
pl.SetLogInfo(event, nil, "complete")
return nil
}
+
+func GetIdByUserId(user_id *uint, event *pl.Event, dbx ...*gorm.DB) (*uint, error) {
+ pl.SetLogInfo(event, nil, "started", "DBGetIdByUserId")
+ var tx *gorm.DB
+ if len(dbx) > 0 {
+ tx = dbx[0]
+ } else {
+ tx = dg.I
+ }
+
+ var nurse_id uint
+
+ err := tx.Model(&e.Nurse{}).
+ Select("\"Nurse\".\"Id\" as nurse_id").
+ Joins("JOIN \"Employee\" AS e ON e.\"Id\" = \"Nurse\".\"Employee_Id\"").
+ Where("e.\"User_Id\" = ?", user_id).
+ Scan(&nurse_id).Error
+
+ if err != nil {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-get-fail",
+ Detail: "Database get failed",
+ Raw: err,
+ }
+ return nil, pl.SetLogError(event, user_id)
+ }
+
+ pl.SetLogInfo(event, nil, "complete")
+ return &nurse_id, nil
+}
diff --git a/internal/use-case/main-use-case/nutritionist/case.go b/internal/use-case/main-use-case/nutritionist/case.go
index f584f005..8be3a320 100644
--- a/internal/use-case/main-use-case/nutritionist/case.go
+++ b/internal/use-case/main-use-case/nutritionist/case.go
@@ -87,9 +87,6 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
return err
}
- if len(input.Includes) > 0 {
- input.Preloads = pu.GetPreloads(input.Includes)
- }
if dataList, metaList, err = ReadListData(input, &event, tx); err != nil {
return err
}
@@ -109,12 +106,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
diff --git a/internal/use-case/main-use-case/nutritionist/lib.go b/internal/use-case/main-use-case/nutritionist/lib.go
index 211e3718..1f7c72b3 100644
--- a/internal/use-case/main-use-case/nutritionist/lib.go
+++ b/internal/use-case/main-use-case/nutritionist/lib.go
@@ -2,6 +2,8 @@ package nutritionist
import (
e "simrs-vx/internal/domain/main-entities/nutritionist"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Nutriti
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -51,32 +47,21 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Nu
tx = dg.I
}
- if len(input.Preloads) > 0 {
- for _, preload := range input.Preloads {
- tx = tx.Preload(preload)
- }
- }
-
tx = tx.
Model(&e.Nutritionist{}).
+ Scopes(gh.Preload(input.Includes)).
Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-get-fail",
- Detail: "Database get failed",
- Raw: err,
- }
- return nil, nil, pl.SetLogError(event, input)
-
+ return nil, nil, plh.HandleListError(input, event, err)
}
+
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
diff --git a/internal/use-case/main-use-case/patient/case.go b/internal/use-case/main-use-case/patient/case.go
index e942536b..fd17d7fb 100644
--- a/internal/use-case/main-use-case/patient/case.go
+++ b/internal/use-case/main-use-case/patient/case.go
@@ -1,6 +1,7 @@
package patient
import (
+ "errors"
"strconv"
e "simrs-vx/internal/domain/main-entities/patient"
@@ -8,8 +9,11 @@ import (
upe "simrs-vx/internal/use-case/main-use-case/person"
upa "simrs-vx/internal/use-case/main-use-case/person-address"
upc "simrs-vx/internal/use-case/main-use-case/person-contact"
+ upi "simrs-vx/internal/use-case/main-use-case/person-insurance"
upr "simrs-vx/internal/use-case/main-use-case/person-relative"
+ ere "simrs-vx/internal/domain/references/encounter"
+
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -44,6 +48,7 @@ func Create(input e.CreateDto) (*d.Data, error) {
} else {
input.Person_Id = person_id
}
+
for idx := range input.PersonAddresses {
input.PersonAddresses[idx].Person_Id = *input.Person_Id
}
@@ -65,6 +70,13 @@ func Create(input e.CreateDto) (*d.Data, error) {
return err
}
+ for idx := range input.PersonInsurances {
+ input.PersonInsurances[idx].Person_Id = *input.Person_Id
+ }
+ if err := upi.CreateOrUpdateBatch(input.PersonInsurances, &event, tx); err != nil {
+ return err
+ }
+
if resData, err := CreateData(input, &event, tx); err != nil {
return err
} else {
@@ -118,9 +130,6 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
return err
}
- if len(input.Includes) > 0 {
- input.Preloads = pu.GetPreloads(input.Includes)
- }
if dataList, metaList, err = ReadListData(input, &event, tx); err != nil {
return err
}
@@ -140,12 +149,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
@@ -251,6 +261,13 @@ func Update(input e.UpdateDto) (*d.Data, error) {
return err
}
+ for idx := range input.PersonInsurances {
+ input.PersonInsurances[idx].Person_Id = *input.Person_Id
+ }
+ if err := upi.CreateOrUpdateBatch(input.PersonInsurances, &event, tx); err != nil {
+ return err
+ }
+
if err := UpdateData(input, data, &event, tx); err != nil {
return err
}
@@ -334,3 +351,118 @@ func Delete(input e.DeleteDto) (*d.Data, error) {
}, nil
}
+
+func Search(input e.SearchDto) (*d.Data, error) {
+ var data *e.Patient
+ var err error
+
+ event := pl.Event{
+ Feature: "Search",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "search")
+ if data, err = SearchData(input, &event); err != nil {
+ return nil, err
+ }
+
+ return &d.Data{
+ Meta: d.IS{
+ "source": source,
+ "structure": "single-data",
+ "status": "fetched",
+ },
+ Data: data.ToResponse(),
+ }, nil
+}
+
+func Upload(input e.UploadDto) (*d.Data, error) {
+ rdDto := e.ReadDetailDto{Id: uint16(input.Id)}
+ var data *e.Patient
+ var err error
+
+ event := pl.Event{
+ Feature: "Upload",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "upload")
+
+ err = dg.I.Transaction(func(tx *gorm.DB) error {
+ if !ere.IsValidUploadCode(input.Code) {
+ return errors.New("invalid upload code")
+ }
+
+ pl.SetLogInfo(&event, rdDto, "started", "DBReadDetail")
+ if data, err = ReadDetailData(rdDto, &event, tx); err != nil {
+ return err
+ }
+
+ if data.Person == nil {
+ return errors.New("person not found")
+ }
+
+ person := data.Person
+
+ input.MedRecNumber = *data.Number
+ pubUrl, err := uploadAndGenerateFileUrl(input, &event)
+ if err != nil {
+ event.Action = ""
+ }
+
+ fileUrl := ""
+ switch input.Code {
+ case ere.UCPRN:
+ if person.ResidentIdentityFileUrl != nil {
+ fileUrl = *person.ResidentIdentityFileUrl
+ }
+ person.ResidentIdentityFileUrl = &pubUrl
+ case ere.UCPDL:
+ if person.DrivingLicenseFileUrl != nil {
+ fileUrl = *person.DrivingLicenseFileUrl
+ }
+ person.DrivingLicenseFileUrl = &pubUrl
+ case ere.UCPP:
+ if person.PassportFileUrl != nil {
+ fileUrl = *person.PassportFileUrl
+ }
+ person.PassportFileUrl = &pubUrl
+ case ere.UCPFC:
+ if person.FamilyIdentityFileUrl != nil {
+ fileUrl = *person.FamilyIdentityFileUrl
+ }
+ person.FamilyIdentityFileUrl = &pubUrl
+ default:
+ return errors.New("invalid upload code")
+ }
+
+ if fileUrl != "" {
+ if err := removeUploadedFile(string(input.Code), fileUrl, &event); err != nil {
+ return err
+ }
+ }
+
+ if err := tx.Save(&person).Error; err != nil {
+ return err
+ }
+
+ pl.SetLogInfo(&event, nil, "complete")
+
+ return nil
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &d.Data{
+ Meta: d.IS{
+ "source": source,
+ "structure": "single-data",
+ "status": "uploaded",
+ },
+ Data: data.ToResponse(),
+ }, nil
+}
diff --git a/internal/use-case/main-use-case/patient/helper.go b/internal/use-case/main-use-case/patient/helper.go
index 09f94ef6..8abfeaf3 100644
--- a/internal/use-case/main-use-case/patient/helper.go
+++ b/internal/use-case/main-use-case/patient/helper.go
@@ -6,8 +6,16 @@ package patient
import (
"fmt"
- e "simrs-vx/internal/domain/main-entities/patient"
+ "path/filepath"
"strconv"
+ "strings"
+ "time"
+
+ e "simrs-vx/internal/domain/main-entities/patient"
+
+ pl "simrs-vx/pkg/logger"
+ pmh "simrs-vx/pkg/minio-helper"
+ puh "simrs-vx/pkg/upload-helper"
dg "github.com/karincake/apem/db-gorm-pg"
)
@@ -32,6 +40,7 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Patient) error {
data.Person_Id = inputSrc.Person_Id
data.RegisteredAt = inputSrc.RegisteredAt
data.Status_Code = inputSrc.Status_Code
+ data.NewBornStatus = inputSrc.NewBornStatus
return nil
}
@@ -81,3 +90,48 @@ func GenerateNextMedicalRecordNumber() (string, error) {
return fmt.Sprintf(format, nextInt), nil
}
+
+func uploadAndGenerateFileUrl(input e.UploadDto, event *pl.Event) (string, error) {
+ pl.SetLogInfo(event, input, "started", "uploadAndGenerateFileUrl")
+ bucket := string(input.Code)
+ ext := strings.ToLower(filepath.Ext(input.Filename))
+
+ if !puh.IsValidFileType(ext, bucket) {
+ return "", fmt.Errorf("invalid file type: %s", input.Filename)
+ }
+ objectName := fmt.Sprintf("%s%d%s", input.MedRecNumber, time.Now().UnixNano(), ext)
+
+ uploadInput := pmh.UploadReaderInput{
+ BucketName: bucket,
+ Name: objectName,
+ File: input.File,
+ Size: input.Size,
+ ContentType: input.MimeType,
+ }
+
+ _, err := pmh.I.PutObject(uploadInput)
+ if err != nil {
+ return "", err
+ }
+
+ // Build URL for access
+ publicUrl := pmh.I.GenerateUrl(bucket, objectName)
+
+ pl.SetLogInfo(event, nil, "complete")
+ return publicUrl, nil
+}
+
+func removeUploadedFile(bucket, fileUrl string, event *pl.Event) error {
+ pl.SetLogInfo(event, nil, "started", "removeUploadedFile")
+ filename, err := pmh.GetFilename(fileUrl)
+ if err != nil {
+ return err
+ }
+
+ err = pmh.I.RemoveObject(bucket, filename)
+ if err != nil {
+ return err
+ }
+ pl.SetLogInfo(event, nil, "complete")
+ return nil
+}
diff --git a/internal/use-case/main-use-case/patient/lib.go b/internal/use-case/main-use-case/patient/lib.go
index 2a5d70e6..f35e3853 100644
--- a/internal/use-case/main-use-case/patient/lib.go
+++ b/internal/use-case/main-use-case/patient/lib.go
@@ -2,6 +2,8 @@ package patient
import (
e "simrs-vx/internal/domain/main-entities/patient"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -27,13 +29,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Patient
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -54,32 +50,21 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Pa
tx = dg.I
}
- if len(input.Preloads) > 0 {
- for _, preload := range input.Preloads {
- tx = tx.Preload(preload)
- }
- }
-
tx = tx.
Model(&e.Patient{}).
+ Scopes(gh.Preload(input.Includes)).
Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-get-fail",
- Detail: "Database get failed",
- Raw: err,
- }
- return nil, nil, pl.SetLogError(event, input)
-
+ return nil, nil, plh.HandleListError(input, event, err)
}
+
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
@@ -100,9 +85,14 @@ func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e
}
tx = tx.Preload(clause.Associations)
- tx = tx.Preload("Person.Addresses")
- tx = tx.Preload("Person.Contacts")
- tx = tx.Preload("Person.Relatives")
+ tx = tx.Preload("Person.BirthRegency.Province").
+ Preload("Person.Ethnic").
+ Preload("Person.Language").
+ Preload("Person.Contacts").
+ Preload("Person.Relatives.Village.District.Regency.Province").
+ Preload("Person.Addresses.Village.District.Regency.Province").
+ Preload("Person.Addresses.PostalRegion.Village.District.Regency.Province").
+ Preload("Person.Insurances.InsuranceCompany")
if err := tx.First(&data, input.Id).Error; err != nil {
if processedErr := pu.HandleReadError(err, event, source, input.Id, data); processedErr != nil {
@@ -163,3 +153,48 @@ func DeleteData(data *e.Patient, event *pl.Event, dbx ...*gorm.DB) error {
pl.SetLogInfo(event, nil, "complete")
return nil
}
+
+func SearchData(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 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")
+
+ 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
+ }
+
+ if err != nil {
+ if processedErr := pu.HandleSearchError(err, event, source, input.Search, patient); processedErr != nil {
+ return nil, processedErr
+ }
+ }
+
+ pl.SetLogInfo(event, nil, "complete")
+ return &patient, nil
+}
diff --git a/internal/use-case/main-use-case/person-address/case.go b/internal/use-case/main-use-case/person-address/case.go
index 1f354661..38353ae9 100644
--- a/internal/use-case/main-use-case/person-address/case.go
+++ b/internal/use-case/main-use-case/person-address/case.go
@@ -106,12 +106,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
diff --git a/internal/use-case/main-use-case/person-address/helper.go b/internal/use-case/main-use-case/person-address/helper.go
index a09c7b57..f9b880b7 100644
--- a/internal/use-case/main-use-case/person-address/helper.go
+++ b/internal/use-case/main-use-case/person-address/helper.go
@@ -18,8 +18,10 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.PersonAddress) {
}
data.Person_Id = inputSrc.Person_Id
+ data.LocationType_Code = inputSrc.LocationType_Code
data.Address = inputSrc.Address
data.Rt = inputSrc.Rt
data.Rw = inputSrc.Rw
data.Village_Code = inputSrc.Village_Code
+ data.PostalRegion_Code = inputSrc.PostalRegion_Code
}
diff --git a/internal/use-case/main-use-case/person-address/lib.go b/internal/use-case/main-use-case/person-address/lib.go
index 0743f427..d0a581bd 100644
--- a/internal/use-case/main-use-case/person-address/lib.go
+++ b/internal/use-case/main-use-case/person-address/lib.go
@@ -2,6 +2,8 @@ package personaddress
import (
e "simrs-vx/internal/domain/main-entities/person-address"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.PersonA
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -58,7 +54,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Pe
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
diff --git a/internal/use-case/main-use-case/person-contact/case.go b/internal/use-case/main-use-case/person-contact/case.go
index 10bf8408..5f37388b 100644
--- a/internal/use-case/main-use-case/person-contact/case.go
+++ b/internal/use-case/main-use-case/person-contact/case.go
@@ -106,12 +106,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
diff --git a/internal/use-case/main-use-case/person-contact/lib.go b/internal/use-case/main-use-case/person-contact/lib.go
index 9e61bb59..034800a4 100644
--- a/internal/use-case/main-use-case/person-contact/lib.go
+++ b/internal/use-case/main-use-case/person-contact/lib.go
@@ -2,6 +2,8 @@ package personcontact
import (
e "simrs-vx/internal/domain/main-entities/person-contact"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.PersonC
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -58,7 +54,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Pe
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
diff --git a/internal/use-case/main-use-case/person-insurance/case.go b/internal/use-case/main-use-case/person-insurance/case.go
new file mode 100644
index 00000000..e9595137
--- /dev/null
+++ b/internal/use-case/main-use-case/person-insurance/case.go
@@ -0,0 +1,276 @@
+package personinsurance
+
+import (
+ e "simrs-vx/internal/domain/main-entities/person-insurance"
+ "strconv"
+
+ dg "github.com/karincake/apem/db-gorm-pg"
+ d "github.com/karincake/dodol"
+
+ pl "simrs-vx/pkg/logger"
+ pu "simrs-vx/pkg/use-case-helper"
+
+ "gorm.io/gorm"
+)
+
+const source = "person-insurance"
+
+func Create(input e.CreateDto) (*d.Data, error) {
+ data := e.PersonInsurance{}
+
+ event := pl.Event{
+ Feature: "Create",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "create")
+
+ err := dg.I.Transaction(func(tx *gorm.DB) error {
+ mwRunner := newMiddlewareRunner(&event, tx)
+ mwRunner.setMwType(pu.MWTPre)
+ // Run pre-middleware
+ if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil {
+ return err
+ }
+
+ if resData, err := CreateData(input, &event, tx); err != nil {
+ return err
+ } else {
+ data = *resData
+ }
+
+ mwRunner.setMwType(pu.MWTPost)
+ // Run post-middleware
+ if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil {
+ return err
+ }
+
+ pl.SetLogInfo(&event, nil, "complete")
+
+ return nil
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &d.Data{
+ Meta: d.II{
+ "source": source,
+ "structure": "single-data",
+ "status": "created",
+ },
+ Data: data.ToResponse(),
+ }, nil
+}
+
+func ReadList(input e.ReadListDto) (*d.Data, error) {
+ var data *e.PersonInsurance
+ var dataList []e.PersonInsurance
+ 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.PersonInsurance
+ 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.PersonInsurance
+ 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.PersonInsurance
+ 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/person-insurance/helper.go b/internal/use-case/main-use-case/person-insurance/helper.go
new file mode 100644
index 00000000..e9352119
--- /dev/null
+++ b/internal/use-case/main-use-case/person-insurance/helper.go
@@ -0,0 +1,24 @@
+/*
+DESCRIPTION:
+Any functions that are used internally by the use-case
+*/
+package personinsurance
+
+import (
+ e "simrs-vx/internal/domain/main-entities/person-insurance"
+)
+
+func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.PersonInsurance) {
+ var inputSrc *e.CreateDto
+ if inputT, ok := any(input).(*e.CreateDto); ok {
+ inputSrc = inputT
+ } else {
+ inputTemp := any(input).(*e.UpdateDto)
+ inputSrc = &inputTemp.CreateDto
+ }
+
+ data.Person_Id = &inputSrc.Person_Id
+ data.InsuranceCompany_Id = inputSrc.InsuranceCompany_Id
+ data.Ref_Number = inputSrc.Ref_Number
+ data.DefaultStatus = inputSrc.DefaultStatus
+}
diff --git a/internal/use-case/main-use-case/person-insurance/lib.go b/internal/use-case/main-use-case/person-insurance/lib.go
new file mode 100644
index 00000000..86c6dc83
--- /dev/null
+++ b/internal/use-case/main-use-case/person-insurance/lib.go
@@ -0,0 +1,193 @@
+package personinsurance
+
+import (
+ e "simrs-vx/internal/domain/main-entities/person-insurance"
+
+ 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.PersonInsurance, error) {
+ pl.SetLogInfo(event, nil, "started", "DBCreate")
+
+ data := e.PersonInsurance{}
+ 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.PersonInsurance, *e.MetaDto, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadList")
+ data := []e.PersonInsurance{}
+ 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.PersonInsurance{}).
+ Scopes(gh.Filter(input)).
+ Count(&count).
+ Scopes(gh.Paginate(input, &pagination)).
+ Order("\"CreatedAt\" DESC")
+
+ if err := tx.Find(&data).Error; err != nil {
+ if err == gorm.ErrRecordNotFound {
+ return nil, &meta, nil
+ }
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-get-fail",
+ Detail: "Database get failed",
+ Raw: err,
+ }
+ return nil, nil, pl.SetLogError(event, input)
+
+ }
+ 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.PersonInsurance, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadDetail")
+ data := e.PersonInsurance{}
+
+ 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.PersonInsurance, 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.PersonInsurance, 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
+}
+
+func CreateOrUpdateBatch(input []e.UpdateDto, event *pl.Event, tx ...*gorm.DB) error {
+ var data = make([]e.PersonInsurance, len(input))
+ var dbx *gorm.DB
+ if len(tx) > 0 {
+ dbx = tx[0]
+ } else {
+ dbx = dg.I
+ }
+
+ for idx := range input {
+ if input[idx].Id > 0 {
+ if err := dbx.Where("\"Id\" = ? AND \"Person_Id\" = ?", input[idx].Id, input[idx].Person_Id).First(&data[idx]).Error; err == nil {
+ setData(&input[idx], &data[idx])
+ if err := dbx.Save(&data[idx]).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)
+ }
+ } else if err != gorm.ErrRecordNotFound {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-get-fail",
+ Detail: "Database get failed",
+ Raw: err,
+ }
+ return pl.SetLogError(event, input)
+ }
+ continue
+ }
+ setData(&input[idx], &data[idx])
+ if err := dbx.Create(&data[idx]).Error; err != nil {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-create-fail",
+ Detail: "Database insert failed",
+ Raw: err,
+ }
+ return pl.SetLogError(event, input)
+ }
+ }
+
+ return nil
+}
diff --git a/internal/use-case/main-use-case/person-insurance/middleware-runner.go b/internal/use-case/main-use-case/person-insurance/middleware-runner.go
new file mode 100644
index 00000000..ce9ff869
--- /dev/null
+++ b/internal/use-case/main-use-case/person-insurance/middleware-runner.go
@@ -0,0 +1,103 @@
+package personinsurance
+
+import (
+ e "simrs-vx/internal/domain/main-entities/person-insurance"
+ 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.PersonInsurance) 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.PersonInsurance) 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.PersonInsurance) 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.PersonInsurance) 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.PersonInsurance) 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/person-insurance/middleware.go b/internal/use-case/main-use-case/person-insurance/middleware.go
new file mode 100644
index 00000000..a190f067
--- /dev/null
+++ b/internal/use-case/main-use-case/person-insurance/middleware.go
@@ -0,0 +1,9 @@
+package personinsurance
+
+// 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/person-insurance/tycovar.go b/internal/use-case/main-use-case/person-insurance/tycovar.go
new file mode 100644
index 00000000..2cc94930
--- /dev/null
+++ b/internal/use-case/main-use-case/person-insurance/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 personinsurance
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/main-entities/person-insurance"
+)
+
+type createMw struct {
+ Name string
+ Func func(input *e.CreateDto, data *e.PersonInsurance, tx *gorm.DB) error
+}
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.PersonInsurance, tx *gorm.DB) error
+}
+
+type readDetailMw struct {
+ Name string
+ Func func(input *e.ReadDetailDto, data *e.PersonInsurance, 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/person-relative/case.go b/internal/use-case/main-use-case/person-relative/case.go
index ab68bbef..929d0817 100644
--- a/internal/use-case/main-use-case/person-relative/case.go
+++ b/internal/use-case/main-use-case/person-relative/case.go
@@ -106,12 +106,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
diff --git a/internal/use-case/main-use-case/person-relative/helper.go b/internal/use-case/main-use-case/person-relative/helper.go
index 48883d5a..b0624521 100644
--- a/internal/use-case/main-use-case/person-relative/helper.go
+++ b/internal/use-case/main-use-case/person-relative/helper.go
@@ -27,4 +27,5 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.PersonRelative) {
data.Education_Code = inputSrc.Education_Code
data.Occupation_Code = inputSrc.Occupation_Code
data.Occupation_Name = inputSrc.Occupation_Name
+ data.Responsible = inputSrc.Responsible
}
diff --git a/internal/use-case/main-use-case/person-relative/lib.go b/internal/use-case/main-use-case/person-relative/lib.go
index 872ad321..28e12e2b 100644
--- a/internal/use-case/main-use-case/person-relative/lib.go
+++ b/internal/use-case/main-use-case/person-relative/lib.go
@@ -2,6 +2,8 @@ package personrelative
import (
e "simrs-vx/internal/domain/main-entities/person-relative"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.PersonR
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -58,7 +54,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Pe
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
diff --git a/internal/use-case/main-use-case/person/case.go b/internal/use-case/main-use-case/person/case.go
index e0395bd9..1d9d94c8 100644
--- a/internal/use-case/main-use-case/person/case.go
+++ b/internal/use-case/main-use-case/person/case.go
@@ -87,9 +87,6 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
return err
}
- if len(input.Includes) > 0 {
- input.Preloads = pu.GetPreloads(input.Includes)
- }
if dataList, metaList, err = ReadListData(input, &event, tx); err != nil {
return err
}
@@ -109,12 +106,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
diff --git a/internal/use-case/main-use-case/person/helper.go b/internal/use-case/main-use-case/person/helper.go
index 65f6bdb8..61a2f18c 100644
--- a/internal/use-case/main-use-case/person/helper.go
+++ b/internal/use-case/main-use-case/person/helper.go
@@ -24,10 +24,15 @@ func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Person) {
data.BirthRegency_Code = inputSrc.BirthRegency_Code
data.Gender_Code = inputSrc.Gender_Code
data.ResidentIdentityNumber = inputSrc.ResidentIdentityNumber
+ data.DrivingLicenseNumber = inputSrc.DrivingLicenseNumber
data.PassportNumber = inputSrc.PassportNumber
data.Religion_Code = inputSrc.Religion_Code
data.Education_Code = inputSrc.Education_Code
data.Ocupation_Code = inputSrc.Ocupation_Code
data.Ocupation_Name = inputSrc.Ocupation_Name
+ data.Nationality = inputSrc.Nationality
data.Ethnic_Code = inputSrc.Ethnic_Code
+ data.Language_Code = inputSrc.Language_Code
+ data.CommunicationIssueStatus = inputSrc.CommunicationIssueStatus
+ data.Disability = inputSrc.Disability
}
diff --git a/internal/use-case/main-use-case/person/lib.go b/internal/use-case/main-use-case/person/lib.go
index 17380cb2..a49fdd00 100644
--- a/internal/use-case/main-use-case/person/lib.go
+++ b/internal/use-case/main-use-case/person/lib.go
@@ -2,10 +2,13 @@ package person
import (
"errors"
+ "strconv"
+
e "simrs-vx/internal/domain/main-entities/person"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
- "strconv"
dg "github.com/karincake/apem/db-gorm-pg"
d "github.com/karincake/dodol"
@@ -27,13 +30,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Person,
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -54,32 +51,21 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Pe
tx = dg.I
}
- if len(input.Preloads) > 0 {
- for _, preload := range input.Preloads {
- tx = tx.Preload(preload)
- }
- }
-
tx = tx.
Model(&e.Person{}).
+ Scopes(gh.Preload(input.Includes)).
Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-get-fail",
- Detail: "Database get failed",
- Raw: err,
- }
- return nil, nil, pl.SetLogError(event, input)
-
+ return nil, nil, plh.HandleListError(input, event, err)
}
+
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
diff --git a/internal/use-case/main-use-case/pharmacist/case.go b/internal/use-case/main-use-case/pharmacist/case.go
index cdc8503f..132987be 100644
--- a/internal/use-case/main-use-case/pharmacist/case.go
+++ b/internal/use-case/main-use-case/pharmacist/case.go
@@ -87,9 +87,6 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
return err
}
- if len(input.Includes) > 0 {
- input.Preloads = pu.GetPreloads(input.Includes)
- }
if dataList, metaList, err = ReadListData(input, &event, tx); err != nil {
return err
}
@@ -109,12 +106,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
diff --git a/internal/use-case/main-use-case/pharmacist/lib.go b/internal/use-case/main-use-case/pharmacist/lib.go
index fb6d5168..365ba118 100644
--- a/internal/use-case/main-use-case/pharmacist/lib.go
+++ b/internal/use-case/main-use-case/pharmacist/lib.go
@@ -2,6 +2,8 @@ package pharmacist
import (
e "simrs-vx/internal/domain/main-entities/pharmacist"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Pharmac
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -51,32 +47,21 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Ph
tx = dg.I
}
- if len(input.Preloads) > 0 {
- for _, preload := range input.Preloads {
- tx = tx.Preload(preload)
- }
- }
-
tx = tx.
Model(&e.Pharmacist{}).
+ Scopes(gh.Preload(input.Includes)).
Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-get-fail",
- Detail: "Database get failed",
- Raw: err,
- }
- return nil, nil, pl.SetLogError(event, input)
-
+ return nil, nil, plh.HandleListError(input, event, err)
}
+
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
@@ -159,3 +144,34 @@ func DeleteData(data *e.Pharmacist, event *pl.Event, dbx ...*gorm.DB) error {
pl.SetLogInfo(event, nil, "complete")
return nil
}
+
+func GetIdByUserId(user_id *uint, event *pl.Event, dbx ...*gorm.DB) (*uint, error) {
+ pl.SetLogInfo(event, nil, "started", "DBGetIdByUserId")
+ var tx *gorm.DB
+ if len(dbx) > 0 {
+ tx = dbx[0]
+ } else {
+ tx = dg.I
+ }
+
+ var pharmacist_id uint
+
+ err := tx.Model(&e.Pharmacist{}).
+ Select("\"Pharmacist\".\"Id\" as pharmacist_id").
+ Joins("JOIN \"Employee\" as e ON e.\"Id\" = \"Pharmacist\".\"Employee_Id\"").
+ Where("e.\"User_Id\" = ?", user_id).
+ Scan(&pharmacist_id).Error
+
+ if err != nil {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-get-fail",
+ Detail: "Database get failed",
+ Raw: err,
+ }
+ return nil, pl.SetLogError(event, user_id)
+ }
+
+ pl.SetLogInfo(event, nil, "complete")
+ return &pharmacist_id, nil
+}
diff --git a/internal/use-case/main-use-case/pharmacy-company/case.go b/internal/use-case/main-use-case/pharmacy-company/case.go
index bf22d56d..cce54750 100644
--- a/internal/use-case/main-use-case/pharmacy-company/case.go
+++ b/internal/use-case/main-use-case/pharmacy-company/case.go
@@ -106,12 +106,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
diff --git a/internal/use-case/main-use-case/pharmacy-company/lib.go b/internal/use-case/main-use-case/pharmacy-company/lib.go
index f4eca38e..08b0ff64 100644
--- a/internal/use-case/main-use-case/pharmacy-company/lib.go
+++ b/internal/use-case/main-use-case/pharmacy-company/lib.go
@@ -2,6 +2,8 @@ package pharmacycompany
import (
e "simrs-vx/internal/domain/main-entities/pharmacy-company"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Pharmac
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -53,24 +49,19 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Ph
tx = tx.
Model(&e.PharmacyCompany{}).
- Scopes(gh.Filter(input)).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
- Order("\"CreatedAt\" DESC")
+ Scopes(gh.Sort(input.Sort))
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-get-fail",
- Detail: "Database get failed",
- Raw: err,
- }
- return nil, nil, pl.SetLogError(event, input)
-
+ return nil, nil, plh.HandleListError(input, event, err)
}
+
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
diff --git a/internal/use-case/main-use-case/postal-region/case.go b/internal/use-case/main-use-case/postal-region/case.go
new file mode 100644
index 00000000..513b0d49
--- /dev/null
+++ b/internal/use-case/main-use-case/postal-region/case.go
@@ -0,0 +1,276 @@
+package postalregion
+
+import (
+ e "simrs-vx/internal/domain/main-entities/postal-region"
+ "strconv"
+
+ dg "github.com/karincake/apem/db-gorm-pg"
+ d "github.com/karincake/dodol"
+
+ pl "simrs-vx/pkg/logger"
+ pu "simrs-vx/pkg/use-case-helper"
+
+ "gorm.io/gorm"
+)
+
+const source = "postal-region"
+
+func Create(input e.CreateDto) (*d.Data, error) {
+ data := e.PostalRegion{}
+
+ event := pl.Event{
+ Feature: "Create",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "create")
+
+ err := dg.I.Transaction(func(tx *gorm.DB) error {
+ mwRunner := newMiddlewareRunner(&event, tx)
+ mwRunner.setMwType(pu.MWTPre)
+ // Run pre-middleware
+ if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil {
+ return err
+ }
+
+ if resData, err := CreateData(input, &event, tx); err != nil {
+ return err
+ } else {
+ data = *resData
+ }
+
+ mwRunner.setMwType(pu.MWTPost)
+ // Run post-middleware
+ if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil {
+ return err
+ }
+
+ pl.SetLogInfo(&event, nil, "complete")
+
+ return nil
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &d.Data{
+ Meta: d.II{
+ "source": source,
+ "structure": "single-data",
+ "status": "created",
+ },
+ Data: data.ToResponse(),
+ }, nil
+}
+
+func ReadList(input e.ReadListDto) (*d.Data, error) {
+ var data *e.PostalRegion
+ var dataList []e.PostalRegion
+ 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.PostalRegion
+ 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.PostalRegion
+ 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.PostalRegion
+ 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/postal-region/helper.go b/internal/use-case/main-use-case/postal-region/helper.go
new file mode 100644
index 00000000..65114fbe
--- /dev/null
+++ b/internal/use-case/main-use-case/postal-region/helper.go
@@ -0,0 +1,21 @@
+/*
+DESCRIPTION:
+Any functions that are used internally by the use-case
+*/
+package postalregion
+
+import (
+ e "simrs-vx/internal/domain/main-entities/postal-region"
+)
+
+func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.PostalRegion) {
+ var inputSrc *e.CreateDto
+ if inputT, ok := any(input).(*e.CreateDto); ok {
+ inputSrc = inputT
+ } else {
+ inputTemp := any(input).(*e.UpdateDto)
+ inputSrc = &inputTemp.CreateDto
+ }
+ data.Village_Code = inputSrc.Village_Code
+ data.Code = inputSrc.Code
+}
diff --git a/internal/use-case/main-use-case/postal-region/lib.go b/internal/use-case/main-use-case/postal-region/lib.go
new file mode 100644
index 00000000..53070293
--- /dev/null
+++ b/internal/use-case/main-use-case/postal-region/lib.go
@@ -0,0 +1,145 @@
+package postalregion
+
+import (
+ e "simrs-vx/internal/domain/main-entities/postal-region"
+
+ 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.PostalRegion, error) {
+ pl.SetLogInfo(event, nil, "started", "DBCreate")
+
+ data := e.PostalRegion{}
+ 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.PostalRegion, *e.MetaDto, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadList")
+ data := []e.PostalRegion{}
+ 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.PostalRegion{}).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
+ Count(&count).
+ Scopes(gh.Paginate(input, &pagination)).
+ Scopes(gh.Sort(input.Sort))
+
+ if err := tx.Find(&data).Error; err != nil {
+ if err == gorm.ErrRecordNotFound {
+ return nil, &meta, nil
+ }
+ return nil, nil, plh.HandleListError(input, event, err)
+ }
+
+ meta.Count = int(count)
+ meta.PageNumber = pagination.PageNumber
+ meta.PageSize = pagination.PageSize
+
+ pl.SetLogInfo(event, nil, "complete")
+ return data, &meta, nil
+}
+
+func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.PostalRegion, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadDetail")
+ data := e.PostalRegion{}
+
+ var tx *gorm.DB
+ if len(dbx) > 0 {
+ tx = dbx[0]
+ } else {
+ tx = dg.I
+ }
+
+ tx = tx.Preload("Village").
+ Preload("Village.District").
+ Preload("Village.District.Regency").
+ Preload("Village.District.Regency.Province")
+
+ 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.PostalRegion, 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.PostalRegion, 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/postal-region/middleware-runner.go b/internal/use-case/main-use-case/postal-region/middleware-runner.go
new file mode 100644
index 00000000..8686be7d
--- /dev/null
+++ b/internal/use-case/main-use-case/postal-region/middleware-runner.go
@@ -0,0 +1,103 @@
+package postalregion
+
+import (
+ e "simrs-vx/internal/domain/main-entities/postal-region"
+ 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.PostalRegion) 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.PostalRegion) 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.PostalRegion) 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.PostalRegion) 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.PostalRegion) 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/postal-region/middleware.go b/internal/use-case/main-use-case/postal-region/middleware.go
new file mode 100644
index 00000000..d96a57d3
--- /dev/null
+++ b/internal/use-case/main-use-case/postal-region/middleware.go
@@ -0,0 +1,9 @@
+package postalregion
+
+// 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/postal-region/tycovar.go b/internal/use-case/main-use-case/postal-region/tycovar.go
new file mode 100644
index 00000000..71278f43
--- /dev/null
+++ b/internal/use-case/main-use-case/postal-region/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 postalregion
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/main-entities/postal-region"
+)
+
+type createMw struct {
+ Name string
+ Func func(input *e.CreateDto, data *e.PostalRegion, tx *gorm.DB) error
+}
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.PostalRegion, tx *gorm.DB) error
+}
+
+type readDetailMw struct {
+ Name string
+ Func func(input *e.ReadDetailDto, data *e.PostalRegion, 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/practice-schedule/case.go b/internal/use-case/main-use-case/practice-schedule/case.go
index 223d97ec..47ae2a8e 100644
--- a/internal/use-case/main-use-case/practice-schedule/case.go
+++ b/internal/use-case/main-use-case/practice-schedule/case.go
@@ -87,9 +87,6 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
return err
}
- if len(input.Includes) > 0 {
- input.Preloads = pu.GetPreloads(input.Includes)
- }
if dataList, metaList, err = ReadListData(input, &event, tx); err != nil {
return err
}
@@ -109,12 +106,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
diff --git a/internal/use-case/main-use-case/practice-schedule/lib.go b/internal/use-case/main-use-case/practice-schedule/lib.go
index 1d5e34ac..1f373ece 100644
--- a/internal/use-case/main-use-case/practice-schedule/lib.go
+++ b/internal/use-case/main-use-case/practice-schedule/lib.go
@@ -2,6 +2,8 @@ package practiceschedule
import (
e "simrs-vx/internal/domain/main-entities/practice-schedule"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Practic
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -51,32 +47,21 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Pr
tx = dg.I
}
- if len(input.Preloads) > 0 {
- for _, preload := range input.Preloads {
- tx = tx.Preload(preload)
- }
- }
-
tx = tx.
Model(&e.PracticeSchedule{}).
+ Scopes(gh.Preload(input.Includes)).
Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-get-fail",
- Detail: "Database get failed",
- Raw: err,
- }
- return nil, nil, pl.SetLogError(event, input)
-
+ return nil, nil, plh.HandleListError(input, event, err)
}
+
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
diff --git a/internal/use-case/main-use-case/prescription-item/case.go b/internal/use-case/main-use-case/prescription-item/case.go
new file mode 100644
index 00000000..f8111454
--- /dev/null
+++ b/internal/use-case/main-use-case/prescription-item/case.go
@@ -0,0 +1,279 @@
+package prescriptionitem
+
+import (
+ "strconv"
+
+ e "simrs-vx/internal/domain/main-entities/prescription-item"
+
+ 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 = "prescription-item"
+
+func Create(input e.CreateDto) (*d.Data, error) {
+ data := e.PrescriptionItem{}
+
+ 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
+ }
+
+ input.Quantity = countQty(input)
+
+ 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.PrescriptionItem
+ var dataList []e.PrescriptionItem
+ 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.PrescriptionItem
+ 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.PrescriptionItem
+ 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.PrescriptionItem
+ 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/prescription-item/helper.go b/internal/use-case/main-use-case/prescription-item/helper.go
new file mode 100644
index 00000000..3f627ddf
--- /dev/null
+++ b/internal/use-case/main-use-case/prescription-item/helper.go
@@ -0,0 +1,37 @@
+/*
+DESCRIPTION:
+Any functions that are used internally by the use-case
+*/
+package prescriptionitem
+
+import (
+ e "simrs-vx/internal/domain/main-entities/prescription-item"
+)
+
+func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.PrescriptionItem) {
+ var inputSrc *e.CreateDto
+ if inputT, ok := any(input).(*e.CreateDto); ok {
+ inputSrc = inputT
+ } else {
+ inputTemp := any(input).(*e.UpdateDto)
+ inputSrc = &inputTemp.CreateDto
+ }
+
+ data.Prescription_Id = inputSrc.Prescription_Id
+ data.IsMix = inputSrc.IsMix
+ data.Medicine_Id = inputSrc.Medicine_Id
+ data.MedicineMix_Id = inputSrc.MedicineMix_Id
+ data.Frequency = inputSrc.Frequency
+ data.Dose = inputSrc.Dose
+ data.Usage = inputSrc.Usage
+ data.Interval = inputSrc.Interval
+ data.IntervalUnit_Code = inputSrc.IntervalUnit_Code
+ data.Quantity = inputSrc.Quantity
+}
+
+func countQty(input e.CreateDto) float64 {
+ if input.Frequency != nil && input.Dose != 0 && input.IntervalMultiplier != nil {
+ return (float64(*input.Frequency) * float64(input.Dose)) * float64(*input.IntervalMultiplier)
+ }
+ return 0
+}
diff --git a/internal/use-case/main-use-case/prescription-item/lib.go b/internal/use-case/main-use-case/prescription-item/lib.go
new file mode 100644
index 00000000..aa6f97bf
--- /dev/null
+++ b/internal/use-case/main-use-case/prescription-item/lib.go
@@ -0,0 +1,142 @@
+package prescriptionitem
+
+import (
+ e "simrs-vx/internal/domain/main-entities/prescription-item"
+
+ plh "simrs-vx/pkg/lib-helper"
+ pl "simrs-vx/pkg/logger"
+ pu "simrs-vx/pkg/use-case-helper"
+
+ dg "github.com/karincake/apem/db-gorm-pg"
+ gh "github.com/karincake/getuk"
+ "gorm.io/gorm"
+)
+
+func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.PrescriptionItem, error) {
+ pl.SetLogInfo(event, nil, "started", "DBCreate")
+
+ data := e.PrescriptionItem{}
+ 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.PrescriptionItem, *e.MetaDto, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadList")
+ data := []e.PrescriptionItem{}
+ 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.PrescriptionItem{}).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
+ Count(&count).
+ Scopes(gh.Paginate(input, &pagination)).
+ Order("\"CreatedAt\" DESC")
+
+ if err := tx.Find(&data).Error; err != nil {
+ if err == gorm.ErrRecordNotFound {
+ return nil, &meta, nil
+ }
+ return nil, nil, plh.HandleListError(input, event, err)
+ }
+
+ meta.Count = int(count)
+ meta.PageNumber = pagination.PageNumber
+ meta.PageSize = pagination.PageSize
+
+ pl.SetLogInfo(event, nil, "complete")
+ return data, &meta, nil
+}
+
+func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.PrescriptionItem, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadDetail")
+ data := e.PrescriptionItem{}
+
+ var tx *gorm.DB
+ if len(dbx) > 0 {
+ tx = dbx[0]
+ } else {
+ tx = dg.I
+ }
+
+ tx = tx.Preload("MedicineMix").Preload("MedicineMix.MixItems")
+
+ 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.PrescriptionItem, 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.PrescriptionItem, 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/prescription-item/middleware-runner.go b/internal/use-case/main-use-case/prescription-item/middleware-runner.go
new file mode 100644
index 00000000..04d5aa00
--- /dev/null
+++ b/internal/use-case/main-use-case/prescription-item/middleware-runner.go
@@ -0,0 +1,103 @@
+package prescriptionitem
+
+import (
+ e "simrs-vx/internal/domain/main-entities/prescription-item"
+ pl "simrs-vx/pkg/logger"
+ pu "simrs-vx/pkg/use-case-helper"
+
+ "gorm.io/gorm"
+)
+
+type middlewareRunner struct {
+ Event *pl.Event
+ Tx *gorm.DB
+ MwType pu.MWType
+}
+
+// NewMiddlewareExecutor creates a new middleware executor
+func newMiddlewareRunner(event *pl.Event, tx *gorm.DB) *middlewareRunner {
+ return &middlewareRunner{
+ Event: event,
+ Tx: tx,
+ }
+}
+
+// ExecuteCreateMiddleware executes create middleware
+func (me *middlewareRunner) RunCreateMiddleware(middlewares []createMw, input *e.CreateDto, data *e.PrescriptionItem) 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.PrescriptionItem) 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.PrescriptionItem) 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.PrescriptionItem) 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.PrescriptionItem) 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/prescription-item/middleware.go b/internal/use-case/main-use-case/prescription-item/middleware.go
new file mode 100644
index 00000000..23d4fe7a
--- /dev/null
+++ b/internal/use-case/main-use-case/prescription-item/middleware.go
@@ -0,0 +1,9 @@
+package prescriptionitem
+
+// 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/prescription-item/tycovar.go b/internal/use-case/main-use-case/prescription-item/tycovar.go
new file mode 100644
index 00000000..9ec60a94
--- /dev/null
+++ b/internal/use-case/main-use-case/prescription-item/tycovar.go
@@ -0,0 +1,44 @@
+/*
+DESCRIPTION:
+A sample, part of the package that contains type, constants, and/or variables.
+
+In this sample it also provides type and variable regarding the needs of the
+middleware to separate from main use-case which has the basic CRUD
+functionality. The purpose of this is to make the code more maintainable.
+*/
+package prescriptionitem
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/main-entities/prescription-item"
+)
+
+type createMw struct {
+ Name string
+ Func func(input *e.CreateDto, data *e.PrescriptionItem, tx *gorm.DB) error
+}
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.PrescriptionItem, tx *gorm.DB) error
+}
+
+type readDetailMw struct {
+ Name string
+ Func func(input *e.ReadDetailDto, data *e.PrescriptionItem, 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/prescription/case.go b/internal/use-case/main-use-case/prescription/case.go
new file mode 100644
index 00000000..fa68ec44
--- /dev/null
+++ b/internal/use-case/main-use-case/prescription/case.go
@@ -0,0 +1,343 @@
+package prescription
+
+import (
+ "errors"
+ "strconv"
+
+ e "simrs-vx/internal/domain/main-entities/prescription"
+
+ erc "simrs-vx/internal/domain/references/common"
+
+ 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 = "prescription"
+
+func Create(input e.CreateDto) (*d.Data, error) {
+ data := e.Prescription{}
+
+ event := pl.Event{
+ Feature: "Create",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "create")
+
+ err := dg.I.Transaction(func(tx *gorm.DB) error {
+ mwRunner := newMiddlewareRunner(&event, tx)
+ mwRunner.setMwType(pu.MWTPre)
+ // Run pre-middleware
+ if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil {
+ return err
+ }
+
+ if resData, err := CreateData(input, &event, tx); err != nil {
+ return err
+ } else {
+ data = *resData
+ }
+
+ mwRunner.setMwType(pu.MWTPost)
+ // Run post-middleware
+ if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil {
+ return err
+ }
+
+ pl.SetLogInfo(&event, nil, "complete")
+
+ return nil
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &d.Data{
+ Meta: d.II{
+ "source": source,
+ "structure": "single-data",
+ "status": "created",
+ },
+ Data: data.ToResponse(),
+ }, nil
+}
+
+func ReadList(input e.ReadListDto) (*d.Data, error) {
+ var data *e.Prescription
+ var dataList []e.Prescription
+ 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.Prescription
+ 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.Prescription
+ 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.Prescription
+ 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 Approve(input e.ReadDetailDto) (*d.Data, error) {
+ var data *e.Prescription
+ var err error
+
+ event := pl.Event{
+ Feature: "Approve",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "approve")
+
+ err = dg.I.Transaction(func(tx *gorm.DB) error {
+ data, err = ReadDetailData(input, &event, tx)
+ if err != nil {
+ return err
+ }
+
+ if data.IsApproved() {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-state-mismatch",
+ Detail: "prescription is already approved",
+ Raw: errors.New("prescription is already approved"),
+ }
+ return pl.SetLogError(&event, input)
+ }
+
+ data.Status_Code = erc.DSCDone
+ 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)
+ }
+
+ if err := createMedication(input.Id, &event, tx); err != nil {
+ return err
+ }
+
+ pl.SetLogInfo(&event, nil, "complete")
+
+ return nil
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &d.Data{
+ Meta: d.IS{
+ "source": source,
+ "structure": "single-data",
+ "status": "approved",
+ },
+ Data: data.ToResponse(),
+ }, nil
+
+}
diff --git a/internal/use-case/main-use-case/prescription/helper.go b/internal/use-case/main-use-case/prescription/helper.go
new file mode 100644
index 00000000..8b85884a
--- /dev/null
+++ b/internal/use-case/main-use-case/prescription/helper.go
@@ -0,0 +1,136 @@
+/*
+DESCRIPTION:
+Any functions that are used internally by the use-case
+*/
+package prescription
+
+import (
+ em "simrs-vx/internal/domain/main-entities/medication"
+ emei "simrs-vx/internal/domain/main-entities/medication-item"
+ emi "simrs-vx/internal/domain/main-entities/medicine-mix"
+ emmi "simrs-vx/internal/domain/main-entities/medicine-mix-item"
+ e "simrs-vx/internal/domain/main-entities/prescription"
+ epi "simrs-vx/internal/domain/main-entities/prescription-item"
+
+ erc "simrs-vx/internal/domain/references/common"
+
+ um "simrs-vx/internal/use-case/main-use-case/medication"
+ umei "simrs-vx/internal/use-case/main-use-case/medication-item"
+ umi "simrs-vx/internal/use-case/main-use-case/medicine-mix"
+ ummi "simrs-vx/internal/use-case/main-use-case/medicine-mix-item"
+ upi "simrs-vx/internal/use-case/main-use-case/prescription-item"
+
+ pl "simrs-vx/pkg/logger"
+ pu "simrs-vx/pkg/use-case-helper"
+
+ "gorm.io/gorm"
+)
+
+func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Prescription) {
+ var inputSrc *e.CreateDto
+ if inputT, ok := any(input).(*e.CreateDto); ok {
+ inputSrc = inputT
+ data.Status_Code = erc.DSCNew
+ } else {
+ inputTemp := any(input).(*e.UpdateDto)
+ inputSrc = &inputTemp.CreateDto
+ }
+
+ data.Encounter_Id = inputSrc.Encounter_Id
+ data.Doctor_Id = inputSrc.Doctor_Id
+ data.IssuedAt = inputSrc.IssuedAt
+}
+
+func createMedication(prescription_id uint, event *pl.Event, tx *gorm.DB) error {
+ pl.SetLogInfo(event, nil, "started", "createMedication")
+
+ prescription, err := ReadDetailData(e.ReadDetailDto{Id: prescription_id}, event, tx)
+ if err != nil {
+ return err
+ }
+
+ prescriptionItem, _, err := upi.ReadListData(epi.ReadListDto{FilterDto: epi.FilterDto{Prescription_Id: &prescription.Id}}, event, tx)
+ if err != nil {
+ return err
+ }
+
+ if len(prescriptionItem) == 0 {
+ return nil
+ }
+
+ medicationCreate := em.CreateDto{
+ Encounter_Id: prescription.Encounter_Id,
+ IssuedAt: pu.GetTimeNow(),
+ }
+ medication, err := um.CreateData(medicationCreate, event, tx)
+ if err != nil {
+ return err
+ }
+
+ for _, prescriptionItem := range prescriptionItem {
+ if prescriptionItem.IsMix {
+ medMix_id, err := createMedicineMixAndItem(*prescriptionItem.MedicineMix, event, tx)
+ if err != nil {
+ return err
+ }
+ prescriptionItem.MedicineMix_Id = medMix_id
+ }
+ err := createMedicationItem(medication.Id, prescriptionItem, event, tx)
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func createMedicineMixAndItem(input emi.MedicineMix, event *pl.Event, tx *gorm.DB) (*uint, error) {
+ pl.SetLogInfo(event, nil, "started", "createMedicineMix")
+
+ medicineMixCreate := emi.CreateDto{
+ Name: input.Name,
+ Uom_Code: input.Uom_Code,
+ }
+ medicineMix, err := umi.CreateData(medicineMixCreate, event, tx)
+ if err != nil {
+ return nil, err
+ }
+
+ // recreate medicineMixItem with new medicineMix_id to keep medMixItem remain the same for prescriptionItem that is created
+ for _, medicineMixItem := range input.MixItems {
+ medicineMixItemCreate := emmi.CreateDto{
+ MedicineMix_Id: &medicineMix.Id,
+ Medicine_Id: medicineMixItem.Medicine_Id,
+ Dose: medicineMixItem.Dose,
+ }
+ _, err := ummi.CreateData(medicineMixItemCreate, event, tx)
+ if err != nil {
+ return nil, err
+ }
+
+ }
+ return &medicineMix.Id, nil
+}
+
+func createMedicationItem(medication_id uint, input epi.PrescriptionItem, event *pl.Event, tx *gorm.DB) error {
+ pl.SetLogInfo(event, nil, "started", "createMedicationItem")
+
+ medicationItemCreate := emei.CreateDto{
+ Medication_Id: &medication_id,
+ IsMix: input.IsMix,
+ Medicine_Id: input.Medicine_Id,
+ MedicineMix_Id: input.MedicineMix_Id,
+ Frequency: input.Frequency,
+ Dose: input.Dose,
+ Usage: input.Usage,
+ Interval: input.Interval,
+ IntervalUnit_Code: input.IntervalUnit_Code,
+ Quantity: input.Quantity,
+ }
+
+ _, err := umei.CreateData(medicationItemCreate, event, tx)
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
diff --git a/internal/use-case/main-use-case/prescription/lib.go b/internal/use-case/main-use-case/prescription/lib.go
new file mode 100644
index 00000000..013952f8
--- /dev/null
+++ b/internal/use-case/main-use-case/prescription/lib.go
@@ -0,0 +1,148 @@
+package prescription
+
+import (
+ e "simrs-vx/internal/domain/main-entities/prescription"
+
+ 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.Prescription, error) {
+ pl.SetLogInfo(event, nil, "started", "DBCreate")
+
+ data := e.Prescription{}
+ 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.Prescription, *e.MetaDto, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadList")
+ data := []e.Prescription{}
+ 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.Prescription{}).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
+ Count(&count).
+ Scopes(gh.Paginate(input, &pagination)).
+ Order("\"CreatedAt\" DESC")
+
+ if err := tx.Find(&data).Error; err != nil {
+ if err == gorm.ErrRecordNotFound {
+ return nil, &meta, nil
+ }
+ return nil, nil, plh.HandleListError(input, event, err)
+ }
+
+ meta.Count = int(count)
+ meta.PageNumber = pagination.PageNumber
+ meta.PageSize = pagination.PageSize
+
+ pl.SetLogInfo(event, nil, "complete")
+ return data, &meta, nil
+}
+
+func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.Prescription, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadDetail")
+ data := e.Prescription{}
+
+ var tx *gorm.DB
+ if len(dbx) > 0 {
+ tx = dbx[0]
+ } else {
+ tx = dg.I
+ }
+
+ if input.Encounter_Id != nil {
+ tx = tx.Where("\"Encounter_Id\" = ?", *input.Encounter_Id)
+ }
+
+ if input.Id != 0 {
+ tx = tx.Where("\"Id\" = ?", input.Id)
+ }
+
+ if err := tx.First(&data).Error; err != nil {
+ if processedErr := pu.HandleReadError(err, event, source, input.Id, data); processedErr != nil {
+ return nil, processedErr
+ }
+ }
+
+ pl.SetLogInfo(event, nil, "complete")
+ return &data, nil
+}
+
+func UpdateData(input e.UpdateDto, data *e.Prescription, 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.Prescription, 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/prescription/middleware-runner.go b/internal/use-case/main-use-case/prescription/middleware-runner.go
new file mode 100644
index 00000000..e5ccb023
--- /dev/null
+++ b/internal/use-case/main-use-case/prescription/middleware-runner.go
@@ -0,0 +1,103 @@
+package prescription
+
+import (
+ e "simrs-vx/internal/domain/main-entities/prescription"
+ 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.Prescription) 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.Prescription) 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.Prescription) 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.Prescription) 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.Prescription) 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/prescription/middleware.go b/internal/use-case/main-use-case/prescription/middleware.go
new file mode 100644
index 00000000..6a61bfc6
--- /dev/null
+++ b/internal/use-case/main-use-case/prescription/middleware.go
@@ -0,0 +1,9 @@
+package prescription
+
+// 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/prescription/tycovar.go b/internal/use-case/main-use-case/prescription/tycovar.go
new file mode 100644
index 00000000..ab938fce
--- /dev/null
+++ b/internal/use-case/main-use-case/prescription/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 prescription
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/main-entities/prescription"
+)
+
+type createMw struct {
+ Name string
+ Func func(input *e.CreateDto, data *e.Prescription, tx *gorm.DB) error
+}
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.Prescription, tx *gorm.DB) error
+}
+
+type readDetailMw struct {
+ Name string
+ Func func(input *e.ReadDetailDto, data *e.Prescription, 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/procedure-src/case.go b/internal/use-case/main-use-case/procedure-src/case.go
index d7b116c0..1b91f6bb 100644
--- a/internal/use-case/main-use-case/procedure-src/case.go
+++ b/internal/use-case/main-use-case/procedure-src/case.go
@@ -106,12 +106,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
diff --git a/internal/use-case/main-use-case/procedure-src/lib.go b/internal/use-case/main-use-case/procedure-src/lib.go
index b1b1b01f..5e0e9685 100644
--- a/internal/use-case/main-use-case/procedure-src/lib.go
+++ b/internal/use-case/main-use-case/procedure-src/lib.go
@@ -2,6 +2,8 @@ package proceduresrc
import (
e "simrs-vx/internal/domain/main-entities/procedure-src"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Procedu
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -53,24 +49,19 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Pr
tx = tx.
Model(&e.ProcedureSrc{}).
- Scopes(gh.Filter(input)).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
- Order("\"CreatedAt\" DESC")
+ Scopes(gh.Sort(input.Sort))
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-get-fail",
- Detail: "Database get failed",
- Raw: err,
- }
- return nil, nil, pl.SetLogError(event, input)
-
+ return nil, nil, plh.HandleListError(input, event, err)
}
+
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
diff --git a/internal/use-case/main-use-case/province/case.go b/internal/use-case/main-use-case/province/case.go
index c8705614..50d5e7ab 100644
--- a/internal/use-case/main-use-case/province/case.go
+++ b/internal/use-case/main-use-case/province/case.go
@@ -106,12 +106,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
diff --git a/internal/use-case/main-use-case/province/lib.go b/internal/use-case/main-use-case/province/lib.go
index b84db301..84b06235 100644
--- a/internal/use-case/main-use-case/province/lib.go
+++ b/internal/use-case/main-use-case/province/lib.go
@@ -2,6 +2,8 @@ package province
import (
e "simrs-vx/internal/domain/main-entities/province"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Provinc
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -53,23 +49,19 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Pr
tx = tx.
Model(&e.Province{}).
- Scopes(gh.Filter(input)).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
Count(&count).
- Scopes(gh.Paginate(input, &pagination))
+ Scopes(gh.Paginate(input, &pagination)).
+ Scopes(gh.Sort(input.Sort))
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-get-fail",
- Detail: "Database get failed",
- Raw: err,
- }
- return nil, nil, pl.SetLogError(event, input)
-
+ return nil, nil, plh.HandleListError(input, event, err)
}
+
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
diff --git a/internal/use-case/main-use-case/regency/case.go b/internal/use-case/main-use-case/regency/case.go
index a0836549..c6ed4b4f 100644
--- a/internal/use-case/main-use-case/regency/case.go
+++ b/internal/use-case/main-use-case/regency/case.go
@@ -106,12 +106,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
diff --git a/internal/use-case/main-use-case/regency/lib.go b/internal/use-case/main-use-case/regency/lib.go
index c098aabd..e59dae52 100644
--- a/internal/use-case/main-use-case/regency/lib.go
+++ b/internal/use-case/main-use-case/regency/lib.go
@@ -2,6 +2,8 @@ package regency
import (
e "simrs-vx/internal/domain/main-entities/regency"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Regency
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -53,23 +49,19 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Re
tx = tx.
Model(&e.Regency{}).
- Scopes(gh.Filter(input)).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
Count(&count).
- Scopes(gh.Paginate(input, &pagination))
+ Scopes(gh.Paginate(input, &pagination)).
+ Scopes(gh.Sort(input.Sort))
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-get-fail",
- Detail: "Database get failed",
- Raw: err,
- }
- return nil, nil, pl.SetLogError(event, input)
-
+ return nil, nil, plh.HandleListError(input, event, err)
}
+
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
diff --git a/internal/use-case/main-use-case/room/case.go b/internal/use-case/main-use-case/room/case.go
new file mode 100644
index 00000000..eeb1cce1
--- /dev/null
+++ b/internal/use-case/main-use-case/room/case.go
@@ -0,0 +1,276 @@
+package room
+
+import (
+ e "simrs-vx/internal/domain/main-entities/room"
+ "strconv"
+
+ dg "github.com/karincake/apem/db-gorm-pg"
+ d "github.com/karincake/dodol"
+
+ pl "simrs-vx/pkg/logger"
+ pu "simrs-vx/pkg/use-case-helper"
+
+ "gorm.io/gorm"
+)
+
+const source = "specialist"
+
+func Create(input e.CreateDto) (*d.Data, error) {
+ data := e.Room{}
+
+ event := pl.Event{
+ Feature: "Create",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "create")
+
+ err := dg.I.Transaction(func(tx *gorm.DB) error {
+ mwRunner := newMiddlewareRunner(&event, tx)
+ mwRunner.setMwType(pu.MWTPre)
+ // Run pre-middleware
+ if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil {
+ return err
+ }
+
+ if resData, err := CreateData(input, &event, tx); err != nil {
+ return err
+ } else {
+ data = *resData
+ }
+
+ mwRunner.setMwType(pu.MWTPost)
+ // Run post-middleware
+ if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil {
+ return err
+ }
+
+ pl.SetLogInfo(&event, nil, "complete")
+
+ return nil
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &d.Data{
+ Meta: d.II{
+ "source": source,
+ "structure": "single-data",
+ "status": "created",
+ },
+ Data: data.ToResponse(),
+ }, nil
+}
+
+func ReadList(input e.ReadListDto) (*d.Data, error) {
+ var data *e.Room
+ var dataList []e.Room
+ 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.Room
+ 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: uint16(input.Id)}
+ var data *e.Room
+ 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: uint16(input.Id)}
+ var data *e.Room
+ 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/room/helper.go b/internal/use-case/main-use-case/room/helper.go
new file mode 100644
index 00000000..cc64e8c5
--- /dev/null
+++ b/internal/use-case/main-use-case/room/helper.go
@@ -0,0 +1,24 @@
+/*
+DESCRIPTION:
+Any functions that are used internally by the use-case
+*/
+package room
+
+import (
+ e "simrs-vx/internal/domain/main-entities/room"
+)
+
+func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Room) {
+ var inputSrc *e.CreateDto
+ if inputT, ok := any(input).(*e.CreateDto); ok {
+ inputSrc = inputT
+ } else {
+ inputTemp := any(input).(*e.UpdateDto)
+ inputSrc = &inputTemp.CreateDto
+ }
+
+ data.Infra_Id = inputSrc.Infra_Id
+ data.Unit_Id = inputSrc.Unit_Id
+ data.Specialist_Id = inputSrc.Specialist_Id
+ data.Subspecialist_Id = inputSrc.Subspecialist_Id
+}
diff --git a/internal/use-case/main-use-case/room/lib.go b/internal/use-case/main-use-case/room/lib.go
new file mode 100644
index 00000000..5e586248
--- /dev/null
+++ b/internal/use-case/main-use-case/room/lib.go
@@ -0,0 +1,140 @@
+package room
+
+import (
+ e "simrs-vx/internal/domain/main-entities/room"
+
+ 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.Room, error) {
+ pl.SetLogInfo(event, nil, "started", "DBCreate")
+
+ data := e.Room{}
+ 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.Room, *e.MetaDto, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadList")
+ data := []e.Room{}
+ 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.Room{}).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
+ Count(&count).
+ Scopes(gh.Paginate(input, &pagination)).
+ Order("\"CreatedAt\" DESC")
+
+ if err := tx.Find(&data).Error; err != nil {
+ if err == gorm.ErrRecordNotFound {
+ return nil, &meta, nil
+ }
+ return nil, nil, plh.HandleListError(input, event, err)
+ }
+
+ meta.Count = int(count)
+ meta.PageNumber = pagination.PageNumber
+ meta.PageSize = pagination.PageSize
+
+ pl.SetLogInfo(event, nil, "complete")
+ return data, &meta, nil
+}
+
+func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.Room, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadDetail")
+ data := e.Room{}
+
+ 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.Room, 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.Room, 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/room/middleware-runner.go b/internal/use-case/main-use-case/room/middleware-runner.go
new file mode 100644
index 00000000..eaeb46fd
--- /dev/null
+++ b/internal/use-case/main-use-case/room/middleware-runner.go
@@ -0,0 +1,103 @@
+package room
+
+import (
+ e "simrs-vx/internal/domain/main-entities/room"
+ 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.Room) 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.Room) 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.Room) 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.Room) 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.Room) 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/room/middleware.go b/internal/use-case/main-use-case/room/middleware.go
new file mode 100644
index 00000000..668f18e2
--- /dev/null
+++ b/internal/use-case/main-use-case/room/middleware.go
@@ -0,0 +1,9 @@
+package room
+
+// 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/room/tycovar.go b/internal/use-case/main-use-case/room/tycovar.go
new file mode 100644
index 00000000..789e3f6f
--- /dev/null
+++ b/internal/use-case/main-use-case/room/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 room
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/main-entities/room"
+)
+
+type createMw struct {
+ Name string
+ Func func(input *e.CreateDto, data *e.Room, tx *gorm.DB) error
+}
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.Room, tx *gorm.DB) error
+}
+
+type readDetailMw struct {
+ Name string
+ Func func(input *e.ReadDetailDto, data *e.Room, 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/sbar/case.go b/internal/use-case/main-use-case/sbar/case.go
new file mode 100644
index 00000000..6c92f2b0
--- /dev/null
+++ b/internal/use-case/main-use-case/sbar/case.go
@@ -0,0 +1,296 @@
+package sbar
+
+import (
+ "errors"
+ "strconv"
+
+ ee "simrs-vx/internal/domain/main-entities/employee"
+ e "simrs-vx/internal/domain/main-entities/sbar"
+
+ ue "simrs-vx/internal/use-case/main-use-case/employee"
+
+ 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 = "sbar"
+
+func Create(input e.CreateDto) (*d.Data, error) {
+ data := e.Sbar{}
+
+ event := pl.Event{
+ Feature: "Create",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "create")
+
+ err := dg.I.Transaction(func(tx *gorm.DB) error {
+ mwRunner := newMiddlewareRunner(&event, tx)
+ mwRunner.setMwType(pu.MWTPre)
+ // Run pre-middleware
+ if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil {
+ return err
+ }
+
+ if !input.AuthInfo.IsDoctor() && !input.AuthInfo.IsNurse() {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "auth-forbidden",
+ Detail: "user position is not allowed",
+ Raw: errors.New("authentication failed"),
+ }
+ return pl.SetLogError(&event, input)
+ }
+
+ employee, err := ue.ReadDetailData(ee.ReadDetailDto{User_Id: &input.AuthInfo.User_Id}, &event, tx)
+ if err != nil {
+ return err
+ }
+ input.Employee_Id = &employee.Id
+ 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.Sbar
+ var dataList []e.Sbar
+ 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.Sbar
+ 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.Sbar
+ 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.Sbar
+ 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/sbar/helper.go b/internal/use-case/main-use-case/sbar/helper.go
new file mode 100644
index 00000000..06eefec6
--- /dev/null
+++ b/internal/use-case/main-use-case/sbar/helper.go
@@ -0,0 +1,24 @@
+/*
+DESCRIPTION:
+Any functions that are used internally by the use-case
+*/
+package sbar
+
+import (
+ e "simrs-vx/internal/domain/main-entities/sbar"
+)
+
+func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Sbar) {
+ 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.Employee_Id = inputSrc.Employee_Id
+ data.Time = inputSrc.Time
+ data.Value = inputSrc.Value
+}
diff --git a/internal/use-case/main-use-case/sbar/lib.go b/internal/use-case/main-use-case/sbar/lib.go
new file mode 100644
index 00000000..6d7b57b7
--- /dev/null
+++ b/internal/use-case/main-use-case/sbar/lib.go
@@ -0,0 +1,140 @@
+package sbar
+
+import (
+ e "simrs-vx/internal/domain/main-entities/sbar"
+
+ 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.Sbar, error) {
+ pl.SetLogInfo(event, nil, "started", "DBCreate")
+
+ data := e.Sbar{}
+ 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.Sbar, *e.MetaDto, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadList")
+ data := []e.Sbar{}
+ 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.Sbar{}).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
+ Count(&count).
+ Scopes(gh.Paginate(input, &pagination)).
+ Order("\"CreatedAt\" DESC")
+
+ if err := tx.Find(&data).Error; err != nil {
+ if err == gorm.ErrRecordNotFound {
+ return nil, &meta, nil
+ }
+ return nil, nil, plh.HandleListError(input, event, err)
+ }
+
+ meta.Count = int(count)
+ meta.PageNumber = pagination.PageNumber
+ meta.PageSize = pagination.PageSize
+
+ pl.SetLogInfo(event, nil, "complete")
+ return data, &meta, nil
+}
+
+func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.Sbar, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadDetail")
+ data := e.Sbar{}
+
+ 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.Sbar, 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.Sbar, 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/sbar/middleware-runner.go b/internal/use-case/main-use-case/sbar/middleware-runner.go
new file mode 100644
index 00000000..a628d1b0
--- /dev/null
+++ b/internal/use-case/main-use-case/sbar/middleware-runner.go
@@ -0,0 +1,103 @@
+package sbar
+
+import (
+ e "simrs-vx/internal/domain/main-entities/sbar"
+ 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.Sbar) 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.Sbar) 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.Sbar) 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.Sbar) 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.Sbar) 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/sbar/middleware.go b/internal/use-case/main-use-case/sbar/middleware.go
new file mode 100644
index 00000000..6ed8e657
--- /dev/null
+++ b/internal/use-case/main-use-case/sbar/middleware.go
@@ -0,0 +1,9 @@
+package sbar
+
+// 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/sbar/tycovar.go b/internal/use-case/main-use-case/sbar/tycovar.go
new file mode 100644
index 00000000..dda3872a
--- /dev/null
+++ b/internal/use-case/main-use-case/sbar/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 sbar
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/main-entities/sbar"
+)
+
+type createMw struct {
+ Name string
+ Func func(input *e.CreateDto, data *e.Sbar, tx *gorm.DB) error
+}
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.Sbar, tx *gorm.DB) error
+}
+
+type readDetailMw struct {
+ Name string
+ Func func(input *e.ReadDetailDto, data *e.Sbar, 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/soapi/case.go b/internal/use-case/main-use-case/soapi/case.go
new file mode 100644
index 00000000..fd06e140
--- /dev/null
+++ b/internal/use-case/main-use-case/soapi/case.go
@@ -0,0 +1,296 @@
+package soapi
+
+import (
+ "errors"
+ "strconv"
+
+ ee "simrs-vx/internal/domain/main-entities/employee"
+ e "simrs-vx/internal/domain/main-entities/soapi"
+
+ ue "simrs-vx/internal/use-case/main-use-case/employee"
+
+ 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 = "soapi"
+
+func Create(input e.CreateDto) (*d.Data, error) {
+ data := e.Soapi{}
+
+ event := pl.Event{
+ Feature: "Create",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "create")
+
+ err := dg.I.Transaction(func(tx *gorm.DB) error {
+ mwRunner := newMiddlewareRunner(&event, tx)
+ mwRunner.setMwType(pu.MWTPre)
+ // Run pre-middleware
+ if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil {
+ return err
+ }
+
+ if !input.AuthInfo.IsDoctor() && !input.AuthInfo.IsNurse() {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "auth-forbidden",
+ Detail: "user position is not allowed",
+ Raw: errors.New("authentication failed"),
+ }
+ return pl.SetLogError(&event, input)
+ }
+
+ employee, err := ue.ReadDetailData(ee.ReadDetailDto{User_Id: &input.AuthInfo.User_Id}, &event, tx)
+ if err != nil {
+ return err
+ }
+ input.Employee_Id = &employee.Id
+ 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.Soapi
+ var dataList []e.Soapi
+ 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.Soapi
+ 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.Soapi
+ 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.Soapi
+ 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/soapi/helper.go b/internal/use-case/main-use-case/soapi/helper.go
new file mode 100644
index 00000000..5a94848a
--- /dev/null
+++ b/internal/use-case/main-use-case/soapi/helper.go
@@ -0,0 +1,25 @@
+/*
+DESCRIPTION:
+Any functions that are used internally by the use-case
+*/
+package soapi
+
+import (
+ e "simrs-vx/internal/domain/main-entities/soapi"
+)
+
+func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Soapi) {
+ 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.Employee_Id = inputSrc.Employee_Id
+ data.Time = inputSrc.Time
+ data.TypeCode = inputSrc.TypeCode
+ data.Value = inputSrc.Value
+}
diff --git a/internal/use-case/main-use-case/soapi/lib.go b/internal/use-case/main-use-case/soapi/lib.go
new file mode 100644
index 00000000..7e551505
--- /dev/null
+++ b/internal/use-case/main-use-case/soapi/lib.go
@@ -0,0 +1,140 @@
+package soapi
+
+import (
+ e "simrs-vx/internal/domain/main-entities/soapi"
+
+ 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.Soapi, error) {
+ pl.SetLogInfo(event, nil, "started", "DBCreate")
+
+ data := e.Soapi{}
+ 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.Soapi, *e.MetaDto, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadList")
+ data := []e.Soapi{}
+ 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.Soapi{}).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
+ Count(&count).
+ Scopes(gh.Paginate(input, &pagination)).
+ Order("\"CreatedAt\" DESC")
+
+ if err := tx.Find(&data).Error; err != nil {
+ if err == gorm.ErrRecordNotFound {
+ return nil, &meta, nil
+ }
+ return nil, nil, plh.HandleListError(input, event, err)
+ }
+
+ meta.Count = int(count)
+ meta.PageNumber = pagination.PageNumber
+ meta.PageSize = pagination.PageSize
+
+ pl.SetLogInfo(event, nil, "complete")
+ return data, &meta, nil
+}
+
+func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.Soapi, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadDetail")
+ data := e.Soapi{}
+
+ 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.Soapi, 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.Soapi, 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/soapi/middleware-runner.go b/internal/use-case/main-use-case/soapi/middleware-runner.go
new file mode 100644
index 00000000..a840a33a
--- /dev/null
+++ b/internal/use-case/main-use-case/soapi/middleware-runner.go
@@ -0,0 +1,103 @@
+package soapi
+
+import (
+ e "simrs-vx/internal/domain/main-entities/soapi"
+ 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.Soapi) 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.Soapi) 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.Soapi) 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.Soapi) 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.Soapi) 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/soapi/middleware.go b/internal/use-case/main-use-case/soapi/middleware.go
new file mode 100644
index 00000000..f2fecda5
--- /dev/null
+++ b/internal/use-case/main-use-case/soapi/middleware.go
@@ -0,0 +1,9 @@
+package soapi
+
+// 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/soapi/tycovar.go b/internal/use-case/main-use-case/soapi/tycovar.go
new file mode 100644
index 00000000..956193a4
--- /dev/null
+++ b/internal/use-case/main-use-case/soapi/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 soapi
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/main-entities/soapi"
+)
+
+type createMw struct {
+ Name string
+ Func func(input *e.CreateDto, data *e.Soapi, tx *gorm.DB) error
+}
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.Soapi, tx *gorm.DB) error
+}
+
+type readDetailMw struct {
+ Name string
+ Func func(input *e.ReadDetailDto, data *e.Soapi, 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-intern/case.go b/internal/use-case/main-use-case/specialist-intern/case.go
new file mode 100644
index 00000000..f737b5ee
--- /dev/null
+++ b/internal/use-case/main-use-case/specialist-intern/case.go
@@ -0,0 +1,276 @@
+package specialistintern
+
+import (
+ e "simrs-vx/internal/domain/main-entities/specialist-intern"
+ "strconv"
+
+ dg "github.com/karincake/apem/db-gorm-pg"
+ d "github.com/karincake/dodol"
+
+ pl "simrs-vx/pkg/logger"
+ pu "simrs-vx/pkg/use-case-helper"
+
+ "gorm.io/gorm"
+)
+
+const source = "specialist-intern"
+
+func Create(input e.CreateDto) (*d.Data, error) {
+ data := e.SpecialistIntern{}
+
+ event := pl.Event{
+ Feature: "Create",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "create")
+
+ err := dg.I.Transaction(func(tx *gorm.DB) error {
+ mwRunner := newMiddlewareRunner(&event, tx)
+ mwRunner.setMwType(pu.MWTPre)
+ // Run pre-middleware
+ if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil {
+ return err
+ }
+
+ if resData, err := CreateData(input, &event, tx); err != nil {
+ return err
+ } else {
+ data = *resData
+ }
+
+ mwRunner.setMwType(pu.MWTPost)
+ // Run post-middleware
+ if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil {
+ return err
+ }
+
+ pl.SetLogInfo(&event, nil, "complete")
+
+ return nil
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &d.Data{
+ Meta: d.II{
+ "source": source,
+ "structure": "single-data",
+ "status": "created",
+ },
+ Data: data.ToResponse(),
+ }, nil
+}
+
+func ReadList(input e.ReadListDto) (*d.Data, error) {
+ var data *e.SpecialistIntern
+ var dataList []e.SpecialistIntern
+ 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.SpecialistIntern
+ 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: uint16(input.Id)}
+ var data *e.SpecialistIntern
+ 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: uint16(input.Id)}
+ var data *e.SpecialistIntern
+ 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/specialist-intern/helper.go b/internal/use-case/main-use-case/specialist-intern/helper.go
new file mode 100644
index 00000000..36b989d8
--- /dev/null
+++ b/internal/use-case/main-use-case/specialist-intern/helper.go
@@ -0,0 +1,24 @@
+/*
+DESCRIPTION:
+Any functions that are used internally by the use-case
+*/
+package specialistintern
+
+import (
+ e "simrs-vx/internal/domain/main-entities/specialist-intern"
+)
+
+func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.SpecialistIntern) {
+ var inputSrc *e.CreateDto
+ if inputT, ok := any(input).(*e.CreateDto); ok {
+ inputSrc = inputT
+ } else {
+ inputTemp := any(input).(*e.UpdateDto)
+ inputSrc = &inputTemp.CreateDto
+ }
+
+ data.Person_Id = inputSrc.Person_Id
+ data.Specialist_Id = inputSrc.Specialist_Id
+ data.Subspecialist_Id = inputSrc.Subspecialist_Id
+ data.User_Id = inputSrc.User_Id
+}
diff --git a/internal/use-case/main-use-case/specialist-intern/lib.go b/internal/use-case/main-use-case/specialist-intern/lib.go
new file mode 100644
index 00000000..03e8a67a
--- /dev/null
+++ b/internal/use-case/main-use-case/specialist-intern/lib.go
@@ -0,0 +1,147 @@
+package specialistintern
+
+import (
+ e "simrs-vx/internal/domain/main-entities/specialist-intern"
+
+ 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.SpecialistIntern, error) {
+ pl.SetLogInfo(event, nil, "started", "DBCreate")
+
+ data := e.SpecialistIntern{}
+ 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.SpecialistIntern, *e.MetaDto, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadList")
+ data := []e.SpecialistIntern{}
+ 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.SpecialistIntern{}).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
+ Count(&count).
+ Scopes(gh.Paginate(input, &pagination)).
+ Order("\"CreatedAt\" DESC")
+
+ if err := tx.Find(&data).Error; err != nil {
+ if err == gorm.ErrRecordNotFound {
+ return nil, &meta, nil
+ }
+ return nil, nil, plh.HandleListError(input, event, err)
+ }
+
+ meta.Count = int(count)
+ meta.PageNumber = pagination.PageNumber
+ meta.PageSize = pagination.PageSize
+
+ pl.SetLogInfo(event, nil, "complete")
+ return data, &meta, nil
+}
+
+func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.SpecialistIntern, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadDetail")
+ data := e.SpecialistIntern{}
+
+ var tx *gorm.DB
+ if len(dbx) > 0 {
+ tx = dbx[0]
+ } else {
+ tx = dg.I
+ }
+
+ if input.User_Id != nil {
+ tx = tx.Where("\"User_Id\" = ?", *input.User_Id)
+ }
+ if input.Id > 0 {
+ tx = tx.Where("\"Id\" = ?", input.Id)
+ }
+
+ if err := tx.First(&data).Error; err != nil {
+ if processedErr := pu.HandleReadError(err, event, source, input.Id, data); processedErr != nil {
+ return nil, processedErr
+ }
+ }
+
+ pl.SetLogInfo(event, nil, "complete")
+ return &data, nil
+}
+
+func UpdateData(input e.UpdateDto, data *e.SpecialistIntern, 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.SpecialistIntern, 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-intern/middleware-runner.go b/internal/use-case/main-use-case/specialist-intern/middleware-runner.go
new file mode 100644
index 00000000..1852f4aa
--- /dev/null
+++ b/internal/use-case/main-use-case/specialist-intern/middleware-runner.go
@@ -0,0 +1,103 @@
+package specialistintern
+
+import (
+ e "simrs-vx/internal/domain/main-entities/specialist-intern"
+ 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.SpecialistIntern) 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.SpecialistIntern) 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.SpecialistIntern) 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.SpecialistIntern) 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.SpecialistIntern) 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-intern/middleware.go b/internal/use-case/main-use-case/specialist-intern/middleware.go
new file mode 100644
index 00000000..4e36b0be
--- /dev/null
+++ b/internal/use-case/main-use-case/specialist-intern/middleware.go
@@ -0,0 +1,9 @@
+package specialistintern
+
+// 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-intern/tycovar.go b/internal/use-case/main-use-case/specialist-intern/tycovar.go
new file mode 100644
index 00000000..8edef033
--- /dev/null
+++ b/internal/use-case/main-use-case/specialist-intern/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 specialistintern
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/main-entities/specialist-intern"
+)
+
+type createMw struct {
+ Name string
+ Func func(input *e.CreateDto, data *e.SpecialistIntern, tx *gorm.DB) error
+}
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.SpecialistIntern, tx *gorm.DB) error
+}
+
+type readDetailMw struct {
+ Name string
+ Func func(input *e.ReadDetailDto, data *e.SpecialistIntern, 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/case.go b/internal/use-case/main-use-case/specialist/case.go
new file mode 100644
index 00000000..229544be
--- /dev/null
+++ b/internal/use-case/main-use-case/specialist/case.go
@@ -0,0 +1,276 @@
+package specialist
+
+import (
+ e "simrs-vx/internal/domain/main-entities/specialist"
+ "strconv"
+
+ dg "github.com/karincake/apem/db-gorm-pg"
+ d "github.com/karincake/dodol"
+
+ pl "simrs-vx/pkg/logger"
+ pu "simrs-vx/pkg/use-case-helper"
+
+ "gorm.io/gorm"
+)
+
+const source = "specialist"
+
+func Create(input e.CreateDto) (*d.Data, error) {
+ data := e.Specialist{}
+
+ event := pl.Event{
+ Feature: "Create",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "create")
+
+ err := dg.I.Transaction(func(tx *gorm.DB) error {
+ mwRunner := newMiddlewareRunner(&event, tx)
+ mwRunner.setMwType(pu.MWTPre)
+ // Run pre-middleware
+ if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil {
+ return err
+ }
+
+ if resData, err := CreateData(input, &event, tx); err != nil {
+ return err
+ } else {
+ data = *resData
+ }
+
+ mwRunner.setMwType(pu.MWTPost)
+ // Run post-middleware
+ if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil {
+ return err
+ }
+
+ pl.SetLogInfo(&event, nil, "complete")
+
+ return nil
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &d.Data{
+ Meta: d.II{
+ "source": source,
+ "structure": "single-data",
+ "status": "created",
+ },
+ Data: data.ToResponse(),
+ }, nil
+}
+
+func ReadList(input e.ReadListDto) (*d.Data, error) {
+ var data *e.Specialist
+ var dataList []e.Specialist
+ 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.Specialist
+ 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: uint16(input.Id)}
+ var data *e.Specialist
+ 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: uint16(input.Id)}
+ var data *e.Specialist
+ 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/specialist/helper.go b/internal/use-case/main-use-case/specialist/helper.go
new file mode 100644
index 00000000..9c1e42fc
--- /dev/null
+++ b/internal/use-case/main-use-case/specialist/helper.go
@@ -0,0 +1,23 @@
+/*
+DESCRIPTION:
+Any functions that are used internally by the use-case
+*/
+package specialist
+
+import (
+ e "simrs-vx/internal/domain/main-entities/specialist"
+)
+
+func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Specialist) {
+ var inputSrc *e.CreateDto
+ if inputT, ok := any(input).(*e.CreateDto); ok {
+ inputSrc = inputT
+ } else {
+ inputTemp := any(input).(*e.UpdateDto)
+ inputSrc = &inputTemp.CreateDto
+ }
+
+ data.Code = inputSrc.Code
+ data.Name = inputSrc.Name
+ data.Unit_Id = inputSrc.Unit_Id
+}
diff --git a/internal/use-case/main-use-case/specialist/lib.go b/internal/use-case/main-use-case/specialist/lib.go
new file mode 100644
index 00000000..10f62ced
--- /dev/null
+++ b/internal/use-case/main-use-case/specialist/lib.go
@@ -0,0 +1,140 @@
+package specialist
+
+import (
+ e "simrs-vx/internal/domain/main-entities/specialist"
+
+ 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.Specialist, error) {
+ pl.SetLogInfo(event, nil, "started", "DBCreate")
+
+ data := e.Specialist{}
+ 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.Specialist, *e.MetaDto, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadList")
+ data := []e.Specialist{}
+ 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.Specialist{}).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
+ Count(&count).
+ Scopes(gh.Paginate(input, &pagination)).
+ Scopes(gh.Sort(input.Sort))
+
+ if err := tx.Find(&data).Error; err != nil {
+ if err == gorm.ErrRecordNotFound {
+ return nil, &meta, nil
+ }
+ return nil, nil, plh.HandleListError(input, event, err)
+ }
+
+ meta.Count = int(count)
+ meta.PageNumber = pagination.PageNumber
+ meta.PageSize = pagination.PageSize
+
+ pl.SetLogInfo(event, nil, "complete")
+ return data, &meta, nil
+}
+
+func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.Specialist, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadDetail")
+ data := e.Specialist{}
+
+ 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.Specialist, 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.Specialist, 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/middleware-runner.go b/internal/use-case/main-use-case/specialist/middleware-runner.go
new file mode 100644
index 00000000..4aa6cdd4
--- /dev/null
+++ b/internal/use-case/main-use-case/specialist/middleware-runner.go
@@ -0,0 +1,103 @@
+package specialist
+
+import (
+ e "simrs-vx/internal/domain/main-entities/specialist"
+ 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.Specialist) 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.Specialist) 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.Specialist) 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.Specialist) 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.Specialist) 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/middleware.go b/internal/use-case/main-use-case/specialist/middleware.go
new file mode 100644
index 00000000..298e51a8
--- /dev/null
+++ b/internal/use-case/main-use-case/specialist/middleware.go
@@ -0,0 +1,9 @@
+package specialist
+
+// 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/tycovar.go b/internal/use-case/main-use-case/specialist/tycovar.go
new file mode 100644
index 00000000..16fa50b0
--- /dev/null
+++ b/internal/use-case/main-use-case/specialist/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
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/main-entities/specialist"
+)
+
+type createMw struct {
+ Name string
+ Func func(input *e.CreateDto, data *e.Specialist, tx *gorm.DB) error
+}
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.Specialist, tx *gorm.DB) error
+}
+
+type readDetailMw struct {
+ Name string
+ Func func(input *e.ReadDetailDto, data *e.Specialist, 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/case.go b/internal/use-case/main-use-case/subspecialist/case.go
new file mode 100644
index 00000000..50498b2a
--- /dev/null
+++ b/internal/use-case/main-use-case/subspecialist/case.go
@@ -0,0 +1,276 @@
+package subspecialist
+
+import (
+ e "simrs-vx/internal/domain/main-entities/subspecialist"
+ "strconv"
+
+ dg "github.com/karincake/apem/db-gorm-pg"
+ d "github.com/karincake/dodol"
+
+ pl "simrs-vx/pkg/logger"
+ pu "simrs-vx/pkg/use-case-helper"
+
+ "gorm.io/gorm"
+)
+
+const source = "specialist"
+
+func Create(input e.CreateDto) (*d.Data, error) {
+ data := e.Subspecialist{}
+
+ event := pl.Event{
+ Feature: "Create",
+ Source: source,
+ }
+
+ // Start log
+ pl.SetLogInfo(&event, input, "started", "create")
+
+ err := dg.I.Transaction(func(tx *gorm.DB) error {
+ mwRunner := newMiddlewareRunner(&event, tx)
+ mwRunner.setMwType(pu.MWTPre)
+ // Run pre-middleware
+ if err := mwRunner.RunCreateMiddleware(createPreMw, &input, &data); err != nil {
+ return err
+ }
+
+ if resData, err := CreateData(input, &event, tx); err != nil {
+ return err
+ } else {
+ data = *resData
+ }
+
+ mwRunner.setMwType(pu.MWTPost)
+ // Run post-middleware
+ if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil {
+ return err
+ }
+
+ pl.SetLogInfo(&event, nil, "complete")
+
+ return nil
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &d.Data{
+ Meta: d.II{
+ "source": source,
+ "structure": "single-data",
+ "status": "created",
+ },
+ Data: data.ToResponse(),
+ }, nil
+}
+
+func ReadList(input e.ReadListDto) (*d.Data, error) {
+ var data *e.Subspecialist
+ var dataList []e.Subspecialist
+ 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.Subspecialist
+ 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: uint16(input.Id)}
+ var data *e.Subspecialist
+ 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: uint16(input.Id)}
+ var data *e.Subspecialist
+ 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/subspecialist/helper.go b/internal/use-case/main-use-case/subspecialist/helper.go
new file mode 100644
index 00000000..5d04093f
--- /dev/null
+++ b/internal/use-case/main-use-case/subspecialist/helper.go
@@ -0,0 +1,23 @@
+/*
+DESCRIPTION:
+Any functions that are used internally by the use-case
+*/
+package subspecialist
+
+import (
+ e "simrs-vx/internal/domain/main-entities/subspecialist"
+)
+
+func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Subspecialist) {
+ var inputSrc *e.CreateDto
+ if inputT, ok := any(input).(*e.CreateDto); ok {
+ inputSrc = inputT
+ } else {
+ inputTemp := any(input).(*e.UpdateDto)
+ inputSrc = &inputTemp.CreateDto
+ }
+
+ data.Code = inputSrc.Code
+ data.Name = inputSrc.Name
+ data.Specialist_Id = inputSrc.Specialist_Id
+}
diff --git a/internal/use-case/main-use-case/subspecialist/lib.go b/internal/use-case/main-use-case/subspecialist/lib.go
new file mode 100644
index 00000000..5843086f
--- /dev/null
+++ b/internal/use-case/main-use-case/subspecialist/lib.go
@@ -0,0 +1,140 @@
+package subspecialist
+
+import (
+ e "simrs-vx/internal/domain/main-entities/subspecialist"
+
+ 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.Subspecialist, error) {
+ pl.SetLogInfo(event, nil, "started", "DBCreate")
+
+ data := e.Subspecialist{}
+ 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.Subspecialist, *e.MetaDto, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadList")
+ data := []e.Subspecialist{}
+ 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.Subspecialist{}).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
+ Count(&count).
+ Scopes(gh.Paginate(input, &pagination)).
+ Scopes(gh.Sort(input.Sort))
+
+ if err := tx.Find(&data).Error; err != nil {
+ if err == gorm.ErrRecordNotFound {
+ return nil, &meta, nil
+ }
+ return nil, nil, plh.HandleListError(input, event, err)
+ }
+
+ meta.Count = int(count)
+ meta.PageNumber = pagination.PageNumber
+ meta.PageSize = pagination.PageSize
+
+ pl.SetLogInfo(event, nil, "complete")
+ return data, &meta, nil
+}
+
+func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e.Subspecialist, error) {
+ pl.SetLogInfo(event, input, "started", "DBReadDetail")
+ data := e.Subspecialist{}
+
+ 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.Subspecialist, 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.Subspecialist, 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/middleware-runner.go b/internal/use-case/main-use-case/subspecialist/middleware-runner.go
new file mode 100644
index 00000000..c7e5f285
--- /dev/null
+++ b/internal/use-case/main-use-case/subspecialist/middleware-runner.go
@@ -0,0 +1,103 @@
+package subspecialist
+
+import (
+ e "simrs-vx/internal/domain/main-entities/subspecialist"
+ 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.Subspecialist) 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.Subspecialist) 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.Subspecialist) 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.Subspecialist) 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.Subspecialist) 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/middleware.go b/internal/use-case/main-use-case/subspecialist/middleware.go
new file mode 100644
index 00000000..ad2ba452
--- /dev/null
+++ b/internal/use-case/main-use-case/subspecialist/middleware.go
@@ -0,0 +1,9 @@
+package subspecialist
+
+// 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/tycovar.go b/internal/use-case/main-use-case/subspecialist/tycovar.go
new file mode 100644
index 00000000..ed4540b8
--- /dev/null
+++ b/internal/use-case/main-use-case/subspecialist/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
+
+import (
+ "gorm.io/gorm"
+
+ e "simrs-vx/internal/domain/main-entities/subspecialist"
+)
+
+type createMw struct {
+ Name string
+ Func func(input *e.CreateDto, data *e.Subspecialist, tx *gorm.DB) error
+}
+
+type readListMw struct {
+ Name string
+ Func func(input *e.ReadListDto, data *e.Subspecialist, tx *gorm.DB) error
+}
+
+type readDetailMw struct {
+ Name string
+ Func func(input *e.ReadDetailDto, data *e.Subspecialist, 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/case.go b/internal/use-case/main-use-case/unit/case.go
index beb91f7b..e11dbd21 100644
--- a/internal/use-case/main-use-case/unit/case.go
+++ b/internal/use-case/main-use-case/unit/case.go
@@ -87,9 +87,6 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
return err
}
- if len(input.Includes) > 0 {
- input.Preloads = pu.GetPreloads(input.Includes)
- }
if dataList, metaList, err = ReadListData(input, &event, tx); err != nil {
return err
}
@@ -109,12 +106,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
diff --git a/internal/use-case/main-use-case/unit/lib.go b/internal/use-case/main-use-case/unit/lib.go
index f43530dc..c79c1373 100644
--- a/internal/use-case/main-use-case/unit/lib.go
+++ b/internal/use-case/main-use-case/unit/lib.go
@@ -2,6 +2,8 @@ package unit
import (
e "simrs-vx/internal/domain/main-entities/unit"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Unit, e
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -51,33 +47,21 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Un
tx = dg.I
}
- if len(input.Preloads) > 0 {
- for _, preload := range input.Preloads {
- tx = tx.Preload(preload)
- }
- }
-
tx = tx.
Model(&e.Unit{}).
- Preload("Installation").
+ Scopes(gh.Preload(input.Includes)).
Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
- Order("\"CreatedAt\" DESC")
+ Scopes(gh.Sort(input.Sort))
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-get-fail",
- Detail: "Database get failed",
- Raw: err,
- }
- return nil, nil, pl.SetLogError(event, input)
-
+ return nil, nil, plh.HandleListError(input, event, err)
}
+
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
diff --git a/internal/use-case/main-use-case/uom/case.go b/internal/use-case/main-use-case/uom/case.go
index 786d4b7e..29c4516b 100644
--- a/internal/use-case/main-use-case/uom/case.go
+++ b/internal/use-case/main-use-case/uom/case.go
@@ -106,12 +106,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
diff --git a/internal/use-case/main-use-case/uom/lib.go b/internal/use-case/main-use-case/uom/lib.go
index 655be4cd..05c22be1 100644
--- a/internal/use-case/main-use-case/uom/lib.go
+++ b/internal/use-case/main-use-case/uom/lib.go
@@ -2,6 +2,8 @@ package uom
import (
e "simrs-vx/internal/domain/main-entities/uom"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Uom, er
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -53,24 +49,19 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Uo
tx = tx.
Model(&e.Uom{}).
- Scopes(gh.Filter(input)).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
Count(&count).
Scopes(gh.Paginate(input, &pagination)).
- Order("\"CreatedAt\" DESC")
+ Scopes(gh.Sort(input.Sort))
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-get-fail",
- Detail: "Database get failed",
- Raw: err,
- }
- return nil, nil, pl.SetLogError(event, input)
-
+ return nil, nil, plh.HandleListError(input, event, err)
}
+
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
diff --git a/internal/use-case/main-use-case/user/case.go b/internal/use-case/main-use-case/user/case.go
index c4f55985..ba5859ee 100644
--- a/internal/use-case/main-use-case/user/case.go
+++ b/internal/use-case/main-use-case/user/case.go
@@ -1,12 +1,35 @@
package user
import (
+ "errors"
"strconv"
"gorm.io/gorm"
+ ed "simrs-vx/internal/domain/main-entities/doctor"
+ ee "simrs-vx/internal/domain/main-entities/employee"
+ el "simrs-vx/internal/domain/main-entities/laborant"
+ em "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"
+ esi "simrs-vx/internal/domain/main-entities/specialist-intern"
e "simrs-vx/internal/domain/main-entities/user"
+
+ 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"
+ um "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"
+ upa "simrs-vx/internal/use-case/main-use-case/person-address"
+ upc "simrs-vx/internal/use-case/main-use-case/person-contact"
+ up "simrs-vx/internal/use-case/main-use-case/pharmacist"
+ usi "simrs-vx/internal/use-case/main-use-case/specialist-intern"
+
erc "simrs-vx/internal/domain/references/common"
+ ero "simrs-vx/internal/domain/references/organization"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -36,12 +59,113 @@ func Create(input e.CreateDto) (*d.Data, error) {
return err
}
+ if person_id, err := upe.CreateOrUpdatePerson(input.Person, &event, tx); err != nil {
+ return err
+ } else {
+ input.Person_Id = person_id
+ }
+
+ for idx := range input.PersonAddresses {
+ input.PersonAddresses[idx].Person_Id = *input.Person_Id
+ }
+ if err := upa.CreateOrUpdateBatch(input.PersonAddresses, &event, tx); err != nil {
+ return err
+ }
+
+ for idx := range input.PersonContacts {
+ input.PersonContacts[idx].Person_Id = *input.Person_Id
+ }
+ if err := upc.CreateOrUpdateBatch(input.PersonContacts, &event, tx); err != nil {
+ return err
+ }
+
if resData, err := CreateData(input, &event, tx); err != nil {
return err
} else {
data = *resData
}
+ if input.Position_Code == ero.UPCInt {
+ createInt := esi.CreateDto{
+ Person_Id: input.Person_Id,
+ Specialist_Id: input.Specialist_Id,
+ Subspecialist_Id: input.Subspecialist_Id,
+ User_Id: &data.Id,
+ }
+ if _, err := usi.CreateData(createInt, &event, tx); err != nil {
+ return err
+ }
+ return nil
+ }
+
+ input.Employee.User_Id = &data.Id
+ input.Employee.Person_Id = input.Person_Id
+ employeeData, err := ue.CreateOrUpdate(setDataEmployeeUpdate(*input.Employee), &event, tx)
+ if err != nil {
+ return err
+ }
+
+ switch input.Position_Code {
+ case ero.UPCDoc:
+ createDoc := ed.CreateDto{
+ Employee_Id: &employeeData.Id,
+ IHS_Number: input.IHS_Number,
+ SIP_Number: input.SIP_Number,
+ Unit_Id: input.Unit_Id,
+ Specialist_Id: input.Specialist_Id,
+ Subspecialist_Id: input.Subspecialist_Id,
+ }
+ if _, err := ud.CreateData(createDoc, &event, tx); err != nil {
+ return err
+ }
+ case ero.UPCNur:
+ createNurse := en.CreateDto{
+ Employee_Id: &employeeData.Id,
+ IHS_Number: input.IHS_Number,
+ Unit_Id: input.Unit_Id,
+ Infra_Id: input.Infra_Id,
+ }
+ if _, err := un.CreateData(createNurse, &event, tx); err != nil {
+ return err
+ }
+ case ero.UPCNut:
+ createNutritionist := et.CreateDto{
+ Employee_Id: &employeeData.Id,
+ IHS_Number: input.IHS_Number,
+ }
+ if _, err := ut.CreateData(createNutritionist, &event, tx); err != nil {
+ return err
+ }
+ case ero.UPCPha:
+ createPharmacist := ep.CreateDto{
+ Employee_Id: &employeeData.Id,
+ IHS_Number: input.IHS_Number,
+ }
+ if _, err := up.CreateData(createPharmacist, &event, tx); err != nil {
+ return err
+ }
+ case ero.UPCLab:
+ createLaborant := el.CreateDto{
+ Employee_Id: &employeeData.Id,
+ IHS_Number: input.IHS_Number,
+ }
+ if _, err := ul.CreateData(createLaborant, &event, tx); err != nil {
+ return err
+ }
+ case ero.UPCMwi:
+ createMidwife := em.CreateDto{
+ Employee_Id: &employeeData.Id,
+ IHS_Number: input.IHS_Number,
+ }
+ if _, err := um.CreateData(em.CreateDto(createMidwife), &event, tx); err != nil {
+ return err
+ }
+ case ero.UPCReg, ero.UPCHur, ero.UPCGea, ero.UPCMan:
+ // do nothing
+ default:
+ return errors.New("invalid employee position")
+ }
+
mwRunner.setMwType(pu.MWTPost)
// Run post-middleware
if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil {
@@ -108,12 +232,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
@@ -192,10 +317,202 @@ func Update(input e.UpdateDto) (*d.Data, error) {
return err
}
+ person_id, err := getPersonIdByUserId(data.Id, input.Position_Code, &event, tx)
+ if err != nil {
+ return err
+ } else {
+ input.Person.Id = *person_id
+ }
+
+ if person_id, err := upe.CreateOrUpdatePerson(input.Person, &event, tx); err != nil {
+ return err
+ } else {
+ input.Person_Id = person_id
+ }
+
+ for idx := range input.PersonAddresses {
+ input.PersonAddresses[idx].Person_Id = *input.Person_Id
+ }
+ if err := upa.CreateOrUpdateBatch(input.PersonAddresses, &event, tx); err != nil {
+ return err
+ }
+
+ for idx := range input.PersonContacts {
+ input.PersonContacts[idx].Person_Id = *input.Person_Id
+ }
+ if err := upc.CreateOrUpdateBatch(input.PersonContacts, &event, tx); err != nil {
+ return err
+ }
+
if err := UpdateData(input, data, &event, tx); err != nil {
return err
}
+ if input.Position_Code == ero.UPCInt {
+ readInt := esi.ReadDetailDto{User_Id: &data.Id}
+ readIntData, err := usi.ReadDetailData(readInt, &event, tx)
+ if err != nil {
+ return err
+ }
+ createInt := esi.CreateDto{
+ User_Id: &data.Id,
+ Person_Id: input.Person_Id,
+ Specialist_Id: input.Specialist_Id,
+ Subspecialist_Id: input.Subspecialist_Id,
+ }
+ if readIntData != nil {
+ if err := usi.UpdateData(esi.UpdateDto{CreateDto: createInt}, readIntData, &event, tx); err != nil {
+ return err
+ }
+ return nil
+ }
+
+ if _, err := usi.CreateData(createInt, &event, tx); err != nil {
+ return err
+ }
+ }
+
+ input.Employee.User_Id = &data.Id
+ input.Employee.Person_Id = input.Person_Id
+ employeeData, err := ue.ReadDetailData(ee.ReadDetailDto{User_Id: &data.Id}, &event, tx)
+ if err != nil {
+ return err
+ }
+
+ err = ue.UpdateData(setDataEmployeeUpdate(*input.Employee), employeeData, &event, tx)
+ if err != nil {
+ return err
+ }
+
+ switch input.Position_Code {
+ case ero.UPCDoc:
+ readDoc := ed.ReadDetailDto{Employee_Id: &employeeData.Id}
+ readDocData, err := ud.ReadDetailData(readDoc, &event, tx)
+ if err != nil {
+ return err
+ }
+ createDoc := ed.CreateDto{
+ Employee_Id: &employeeData.Id,
+ IHS_Number: input.IHS_Number,
+ SIP_Number: input.SIP_Number,
+ Unit_Id: input.Unit_Id,
+ }
+ if readDocData != nil {
+ if err := ud.UpdateData(ed.UpdateDto{CreateDto: createDoc}, readDocData, &event, tx); err != nil {
+ return err
+ }
+ return nil
+ }
+
+ if _, err := ud.CreateData(createDoc, &event, tx); err != nil {
+ return err
+ }
+ case ero.UPCNur:
+ readNur := en.ReadDetailDto{Employee_Id: &employeeData.Id}
+ readNurData, err := un.ReadDetailData(readNur, &event, tx)
+ if err != nil {
+ return err
+ }
+ createNur := en.CreateDto{
+ Employee_Id: &employeeData.Id,
+ IHS_Number: input.IHS_Number,
+ }
+ if readNurData != nil {
+ if err := un.UpdateData(en.UpdateDto{CreateDto: createNur}, readNurData, &event, tx); err != nil {
+ return err
+ }
+ return nil
+ }
+
+ if _, err := un.CreateData(createNur, &event, tx); err != nil {
+ return err
+ }
+ case ero.UPCNut:
+ readNut := et.ReadDetailDto{Employee_Id: &employeeData.Id}
+ readNutData, err := ut.ReadDetailData(readNut, &event, tx)
+ if err != nil {
+ return err
+ }
+ createNut := et.CreateDto{
+ Employee_Id: &employeeData.Id,
+ IHS_Number: input.IHS_Number,
+ }
+ if readNutData != nil {
+ if err := ut.UpdateData(et.UpdateDto{CreateDto: createNut}, readNutData, &event, tx); err != nil {
+ return err
+ }
+ return nil
+ }
+
+ if _, err := ut.CreateData(createNut, &event, tx); err != nil {
+ return err
+ }
+ case ero.UPCPha:
+ readPha := ep.ReadDetailDto{Employee_Id: &employeeData.Id}
+ readPhaData, err := up.ReadDetailData(readPha, &event, tx)
+ if err != nil {
+ return err
+ }
+ createPha := ep.CreateDto{
+ Employee_Id: &employeeData.Id,
+ IHS_Number: input.IHS_Number,
+ }
+ if readPhaData != nil {
+ if err := up.UpdateData(ep.UpdateDto{CreateDto: createPha}, readPhaData, &event, tx); err != nil {
+ return err
+ }
+ return nil
+ }
+
+ if _, err := up.CreateData(createPha, &event, tx); err != nil {
+ return err
+ }
+ case ero.UPCLab:
+ readLab := el.ReadDetailDto{Employee_Id: &employeeData.Id}
+ readLabData, err := ul.ReadDetailData(readLab, &event, tx)
+ if err != nil {
+ return err
+ }
+ createLab := el.CreateDto{
+ Employee_Id: &employeeData.Id,
+ IHS_Number: input.IHS_Number,
+ }
+ if readLabData != nil {
+ if err := ul.UpdateData(el.UpdateDto{CreateDto: createLab}, readLabData, &event, tx); err != nil {
+ return err
+ }
+ return nil
+ }
+
+ if _, err := ul.CreateData(createLab, &event, tx); err != nil {
+ return err
+ }
+ case ero.UPCMwi:
+ readMidwife := em.ReadDetailDto{Employee_Id: &employeeData.Id}
+ readMidwifeData, err := um.ReadDetailData(readMidwife, &event, tx)
+ if err != nil {
+ return err
+ }
+ createMidwife := em.CreateDto{
+ Employee_Id: &employeeData.Id,
+ IHS_Number: input.IHS_Number,
+ }
+ if readMidwifeData != nil {
+ if err := um.UpdateData(em.UpdateDto{CreateDto: createMidwife}, readMidwifeData, &event, tx); err != nil {
+ return err
+ }
+ return nil
+ }
+
+ if _, err := um.CreateData(createMidwife, &event, tx); err != nil {
+ return err
+ }
+ case ero.UPCReg, ero.UPCHur, ero.UPCGea, ero.UPCMan:
+ // do nothing
+ default:
+ return errors.New("invalid employee position")
+ }
+
pl.SetLogInfo(&event, nil, "complete")
mwRunner.setMwType(pu.MWTPost)
diff --git a/internal/use-case/main-use-case/user/helper.go b/internal/use-case/main-use-case/user/helper.go
index 37815b51..111d333f 100644
--- a/internal/use-case/main-use-case/user/helper.go
+++ b/internal/use-case/main-use-case/user/helper.go
@@ -5,9 +5,20 @@ Any functions that are used internally by the use-case
package user
import (
+ "errors"
+ ee "simrs-vx/internal/domain/main-entities/employee"
+ esi "simrs-vx/internal/domain/main-entities/specialist-intern"
e "simrs-vx/internal/domain/main-entities/user"
+ ue "simrs-vx/internal/use-case/main-use-case/employee"
+ usi "simrs-vx/internal/use-case/main-use-case/specialist-intern"
+
+ ero "simrs-vx/internal/domain/references/organization"
+
+ pl "simrs-vx/pkg/logger"
p "simrs-vx/pkg/password"
+
+ "gorm.io/gorm"
)
func setCreate(src e.CreateDto, dst *e.User) error {
@@ -19,12 +30,47 @@ func setCreate(src e.CreateDto, dst *e.User) error {
dst.Name = src.Name
dst.Password = pass
dst.Status_Code = src.Status_Code
+ dst.Position_Code = src.Position_Code
return nil
}
func setUpdate(src e.UpdateDto, dst *e.User) {
- dst.Name = src.Name
dst.Status_Code = src.Status_Code
+ dst.Position_Code = src.Position_Code
}
+
+func setDataEmployeeUpdate(src e.EmployeUpdateDto) ee.UpdateDto {
+ return ee.UpdateDto{
+ Id: src.Id,
+ 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,
+ },
+ }
+}
+
+func getPersonIdByUserId(userId uint, positionCode ero.UserPosisitionCode, event *pl.Event, tx *gorm.DB) (*uint, error) {
+ pl.SetLogInfo(event, nil, "started", "DBGetPersonIdByUserId")
+ if positionCode == ero.UPCInt {
+ specInt, err := usi.ReadDetailData(esi.ReadDetailDto{User_Id: &userId}, event, tx)
+ if err != nil {
+ return nil, err
+ }
+ if specInt.Person_Id == nil {
+ return nil, errors.New("person id not found")
+ }
+ return specInt.Person_Id, nil
+ }
+
+ emp, err := ue.ReadDetailData(ee.ReadDetailDto{User_Id: &userId}, event, tx)
+ if err != nil {
+ return nil, err
+ }
+
+ return emp.Person_Id, nil
+}
diff --git a/internal/use-case/main-use-case/user/lib.go b/internal/use-case/main-use-case/user/lib.go
index 0af63c75..fdb670dc 100644
--- a/internal/use-case/main-use-case/user/lib.go
+++ b/internal/use-case/main-use-case/user/lib.go
@@ -2,6 +2,8 @@ package user
import (
e "simrs-vx/internal/domain/main-entities/user"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.User, e
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -58,7 +54,7 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Us
Scopes(gh.Paginate(input, &pagination)).
Order("\"CreatedAt\" DESC")
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
diff --git a/internal/use-case/main-use-case/village/case.go b/internal/use-case/main-use-case/village/case.go
index dbdeb33d..787fdb12 100644
--- a/internal/use-case/main-use-case/village/case.go
+++ b/internal/use-case/main-use-case/village/case.go
@@ -106,12 +106,13 @@ func ReadList(input e.ReadListDto) (*d.Data, error) {
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),
+ "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
diff --git a/internal/use-case/main-use-case/village/lib.go b/internal/use-case/main-use-case/village/lib.go
index c67f3ac4..21ca8e6c 100644
--- a/internal/use-case/main-use-case/village/lib.go
+++ b/internal/use-case/main-use-case/village/lib.go
@@ -2,6 +2,8 @@ package village
import (
e "simrs-vx/internal/domain/main-entities/village"
+
+ plh "simrs-vx/pkg/lib-helper"
pl "simrs-vx/pkg/logger"
pu "simrs-vx/pkg/use-case-helper"
@@ -24,13 +26,7 @@ func CreateData(input e.CreateDto, event *pl.Event, dbx ...*gorm.DB) (*e.Village
}
if err := tx.Create(&data).Error; err != nil {
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-create-fail",
- Detail: "Database insert failed",
- Raw: err,
- }
- return nil, pl.SetLogError(event, input)
+ return nil, plh.HandleCreateError(input, event, err)
}
pl.SetLogInfo(event, nil, "complete")
@@ -53,23 +49,19 @@ func ReadListData(input e.ReadListDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Vi
tx = tx.
Model(&e.Village{}).
- Scopes(gh.Filter(input)).
+ Scopes(gh.Preload(input.Includes)).
+ Scopes(gh.Filter(input.FilterDto)).
Count(&count).
- Scopes(gh.Paginate(input, &pagination))
+ Scopes(gh.Paginate(input, &pagination)).
+ Scopes(gh.Sort(input.Sort))
- if err := tx.Debug().Find(&data).Error; err != nil {
+ if err := tx.Find(&data).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return nil, &meta, nil
}
- event.Status = "failed"
- event.ErrInfo = pl.ErrorInfo{
- Code: "data-get-fail",
- Detail: "Database get failed",
- Raw: err,
- }
- return nil, nil, pl.SetLogError(event, input)
-
+ return nil, nil, plh.HandleListError(input, event, err)
}
+
meta.Count = int(count)
meta.PageNumber = pagination.PageNumber
meta.PageSize = pagination.PageSize
diff --git a/pkg/auth-helper/auth-helper.go b/pkg/auth-helper/auth-helper.go
new file mode 100644
index 00000000..934d8d61
--- /dev/null
+++ b/pkg/auth-helper/auth-helper.go
@@ -0,0 +1,15 @@
+package authhelper
+
+import (
+ "errors"
+ "net/http"
+)
+
+func GetAuthInfo(r *http.Request) (*AuthInfo, error) {
+ ctxVal := r.Context().Value(AuthKey{})
+ if ctxVal == nil {
+ return nil, errors.New("can't get auth info")
+ }
+ authInfo := ctxVal.(*AuthInfo)
+ return authInfo, nil
+}
diff --git a/pkg/auth-helper/tycovar.go b/pkg/auth-helper/tycovar.go
new file mode 100644
index 00000000..288c9d21
--- /dev/null
+++ b/pkg/auth-helper/tycovar.go
@@ -0,0 +1,52 @@
+package authhelper
+
+import (
+ ero "simrs-vx/internal/domain/references/organization"
+)
+
+type AuthKey struct{}
+
+type AuthInfo struct {
+ Uuid string
+ User_Id uint
+ User_Name string
+ User_DivisionPositions []DivisionPosition
+ User_Position_Code string
+}
+
+type DivisionPosition struct {
+ Division_Code string `json:"division_code"`
+ DivisionPosition_Code string `json:"divisionPosition_code"`
+}
+
+func (a AuthInfo) IsDoctor() bool {
+ return a.User_Position_Code == string(ero.UPCDoc)
+}
+
+func (a AuthInfo) IsNurse() bool {
+ return a.User_Position_Code == string(ero.UPCNur)
+}
+
+func (a AuthInfo) IsNutritionist() bool {
+ return a.User_Position_Code == string(ero.UPCNut)
+}
+
+func (a AuthInfo) IsLaborant() bool {
+ return a.User_Position_Code == string(ero.UPCLab)
+}
+
+func (a AuthInfo) IsPharmacist() bool {
+ return a.User_Position_Code == string(ero.UPCPha)
+}
+
+func (a AuthInfo) IsPayment() bool {
+ return a.User_Position_Code == string(ero.UPCPay)
+}
+
+func (a AuthInfo) IsManagement() bool {
+ return a.User_Position_Code == string(ero.UPCMan)
+}
+
+func (a AuthInfo) IsSpecialistIntern() bool {
+ return a.User_Position_Code == string(ero.UPCInt)
+}
diff --git a/pkg/lib-helper/lib-helper.go b/pkg/lib-helper/lib-helper.go
new file mode 100644
index 00000000..fcced797
--- /dev/null
+++ b/pkg/lib-helper/lib-helper.go
@@ -0,0 +1,167 @@
+package libhelper
+
+import (
+ "fmt"
+ "regexp"
+ pl "simrs-vx/pkg/logger"
+ "strings"
+ "unicode"
+
+ "github.com/jackc/pgx/v5/pgconn"
+ "gorm.io/gorm"
+)
+
+func SearchCodeOrName(search string, tx *gorm.DB) *gorm.DB {
+ if search != "" {
+ tx = tx.Where("\"Code\" ILIKE ? OR \"Name\" ILIKE ?", "%"+search+"%", "%"+search+"%")
+ }
+
+ return tx
+}
+
+func Sort(sort string, tx *gorm.DB) *gorm.DB {
+ if sort == "" {
+ return tx
+ }
+
+ pairs := strings.Split(sort, ",")
+ for _, pair := range pairs {
+ parts := strings.Split(strings.TrimSpace(pair), ":")
+ if len(parts) != 2 {
+ continue // skip invalid format
+ }
+
+ field := strings.TrimSpace(parts[0])
+ direction := strings.ToUpper(strings.TrimSpace(parts[1]))
+
+ if direction != "ASC" && direction != "DESC" {
+ continue
+ }
+
+ field = normalizeColumnName(field)
+
+ tx = tx.Order(fmt.Sprintf("\"%s\" %s", field, direction))
+ }
+
+ return tx
+}
+
+func normalizeColumnName(input string) string {
+ if input == "" {
+ return input
+ }
+
+ input = strings.ReplaceAll(input, "-", "_")
+
+ runes := []rune(input)
+ var out []rune
+ upperNext := true
+ for _, r := range runes {
+ if r == '_' {
+ out = append(out, r)
+ upperNext = true
+ continue
+ }
+ if upperNext {
+ out = append(out, unicode.ToUpper(r))
+ upperNext = false
+ } else {
+ out = append(out, r)
+ }
+ }
+ return string(out)
+}
+
+func HandleCreateError(input any, event *pl.Event, err error) error {
+ e, ok := err.(*pgconn.PgError)
+ if !ok {
+ // fallback if it's not a pg error
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-create-fail",
+ Detail: fmt.Sprintf("Database insert failed: %s", err.Error()),
+ Raw: err,
+ }
+ return pl.SetLogError(event, input)
+ }
+
+ switch e.Code {
+ case "23505": // unique_violation
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-create-duplicate",
+ Detail: fmt.Sprintf("Duplicate value violates unique constraint: %s", e.ConstraintName),
+ Raw: err,
+ }
+ return pl.SetLogError(event, input)
+
+ case "23503": // foreign_key_violation
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-create-fkViolation",
+ Detail: fmt.Sprintf("Foreign key constraint '%s' violated. Please check related record exists.", e.ConstraintName),
+ Raw: err,
+ }
+ return pl.SetLogError(event, input)
+
+ default:
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-create-fail",
+ Detail: fmt.Sprintf("Database insert failed: %s", e.Message),
+ Raw: err,
+ }
+ return pl.SetLogError(event, input)
+ }
+}
+
+func HandleListError(input any, event *pl.Event, err error) error {
+ if err == nil {
+ return nil
+ }
+
+ e, ok := err.(*pgconn.PgError)
+ if !ok {
+ // fallback if it's not a pg error
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-list-fail",
+ Detail: fmt.Sprintf("database list failed: %s", err.Error()),
+ Raw: err,
+ }
+ return pl.SetLogError(event, input)
+ }
+
+ re := regexp.MustCompile(`^([^:]+):\s*unsupported relations for schema\s+(\S+)`)
+ if matches := re.FindStringSubmatch(e.Message); len(matches) == 3 {
+ relation := strings.TrimSpace(matches[1])
+ schema := strings.TrimSpace(matches[2])
+
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "invalid-relation",
+ Detail: fmt.Sprintf("Invalid relation '%s' for schema '%s' โ check the relation name.", relation, schema),
+ Raw: e,
+ }
+ return pl.SetLogError(event, input)
+ }
+
+ if strings.Contains(e.Message, "unsupported relations for schema") {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "invalid-relation",
+ Detail: fmt.Sprintf("Unsupported relation detected: %s", e.Message),
+ Raw: e,
+ }
+ return pl.SetLogError(event, input)
+ }
+
+ // Generic pg error fallback
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "pg-error",
+ Detail: fmt.Sprintf("PostgreSQL error: %s", e.Message),
+ Raw: e,
+ }
+ return pl.SetLogError(event, input)
+}
diff --git a/pkg/minio-helper/minio-helper.go b/pkg/minio-helper/minio-helper.go
new file mode 100644
index 00000000..15c52ca5
--- /dev/null
+++ b/pkg/minio-helper/minio-helper.go
@@ -0,0 +1,176 @@
+package miniohelper
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "net/url"
+ "path"
+
+ m "simrs-vx/internal/infra/minio"
+
+ "github.com/minio/minio-go/v7"
+)
+
+type minioRepository struct {
+ client *minio.Client
+}
+
+var I minioRepository = minioRepository{}
+
+func (repo *minioRepository) SetClient() {
+ repo.client = m.I
+}
+
+// Check exist bucket if not exist create Bucket
+func (repo *minioRepository) createBucket(bucketName string, region string) error {
+ exist, err := repo.client.BucketExists(context.Background(), bucketName)
+ if err != nil {
+ return err
+ }
+ if !exist {
+ // create bucket
+ if err := repo.client.MakeBucket(context.Background(), bucketName, minio.MakeBucketOptions{Region: region}); err != nil {
+ return err
+ }
+
+ // set bucket policy to public read
+ policy := fmt.Sprintf(`{
+ "Version": "2012-10-17",
+ "Statement": [
+ {
+ "Effect": "Allow",
+ "Principal": {"AWS": ["*"]},
+ "Action": ["s3:GetObject"],
+ "Resource": ["arn:aws:s3:::%s/*"]
+ }
+ ]
+ }`, bucketName)
+
+ if err := repo.client.SetBucketPolicy(context.Background(), bucketName, policy); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+// Upload file reader to MinIO
+func (repo *minioRepository) PutObject(input UploadReaderInput) (*minio.UploadInfo, error) {
+ if err := repo.createBucket(input.BucketName, m.O.GetRegion()); err != nil {
+ return nil, err
+ }
+ options := minio.PutObjectOptions{
+ ContentType: input.ContentType,
+ UserMetadata: map[string]string{"x-amz-acl": "public-read"},
+ }
+
+ uploadInfo, err := repo.client.PutObject(context.Background(), input.BucketName, input.Name, input.File, input.Size, options)
+ if err != nil {
+ return nil, err
+ }
+
+ return &uploadInfo, err
+}
+
+// Upload file path to MinIO
+func (repo *minioRepository) FPutObject(input UploadPathInput) (*minio.UploadInfo, error) {
+ if err := repo.createBucket(input.BucketName, m.O.GetRegion()); err != nil {
+ return nil, err
+ }
+ options := minio.PutObjectOptions{
+ ContentType: input.ContentType,
+ UserMetadata: map[string]string{"x-amz-acl": "public-read"},
+ }
+
+ uploadInfo, err := repo.client.FPutObject(context.Background(), input.BucketName, input.Name, input.Path, options)
+ if err != nil {
+ return nil, err
+ }
+
+ return &uploadInfo, err
+}
+
+// Move file from old to new MinIO path
+func (repo *minioRepository) MoveObject(src minio.CopySrcOptions, dst minio.CopyDestOptions) (*minio.UploadInfo, error) {
+ uploadInfo, err := repo.client.CopyObject(context.Background(), dst, src)
+ if err != nil {
+ return nil, err
+ }
+ if err := repo.RemoveObject(src.Bucket, src.Object); err != nil {
+ return nil, err
+ }
+ return &uploadInfo, err
+}
+
+// Generatet public link MinIO
+func (repo *minioRepository) GenerateUrl(bucket, object string) string {
+ mode := "http"
+ if m.O.GetUseSsl() {
+ mode = "https"
+ }
+ return fmt.Sprintf("%s://%s/%s/%s", mode, m.O.GetEndpoint(), bucket, object)
+}
+
+// Download file from MinIO
+func (repo *minioRepository) GetObject(bucket string, fileName string) (*minio.Object, error) {
+ object, err := repo.client.GetObject(context.Background(), bucket, fileName, minio.GetObjectOptions{})
+ if err != nil {
+ return nil, err
+ }
+ return object, nil
+}
+
+// Delete file from MinIO
+func (repo *minioRepository) RemoveObject(bucket string, fileName string) error {
+ if err := repo.client.RemoveObject(context.Background(), bucket, fileName, minio.RemoveObjectOptions{}); err != nil {
+ return err
+ }
+ return nil
+}
+
+// create presigned url to post object with custom policy
+func (repo *minioRepository) GeneratePresignedPost(policy *minio.PostPolicy) (*url.URL, map[string]string, error) {
+ presignedUrl, formData, err := repo.client.PresignedPostPolicy(context.Background(), policy)
+ if err != nil {
+ return nil, nil, err
+ }
+ return presignedUrl, formData, nil
+}
+
+// create presigned url to get object
+func (repo *minioRepository) GeneratePresignedGetObject(input PresignedGetInput) (*url.URL, error) {
+ presignedUrl, err := repo.client.PresignedGetObject(context.Background(), input.Bucket, input.Object, input.Expiry, input.ReqParams)
+ if err != nil {
+ return nil, err
+ }
+ return presignedUrl, nil
+}
+
+func getBucketName(idx int) string {
+ return m.O.GetBucketName()[idx]
+}
+
+func GetBucketPatient() (string, error) {
+ bucketName := getBucketName(0)
+ if bucketName == "" {
+ return "", errors.New("bucket name unknown")
+ }
+ return bucketName, nil
+}
+
+func GetEndpointUrl(bucket string) string {
+ mode := "http"
+ if m.O.GetUseSsl() {
+ mode = "https"
+ }
+ return fmt.Sprintf("%s://%s/%s", mode, m.O.GetEndpoint(), bucket)
+}
+
+func GetFilename(rawUrl string) (string, error) {
+ parsed, err := url.Parse(rawUrl)
+ if err != nil {
+ return "", err
+ }
+ return path.Base(parsed.Path), nil
+}
diff --git a/pkg/minio-helper/tycovar.go b/pkg/minio-helper/tycovar.go
new file mode 100644
index 00000000..a9ac20dc
--- /dev/null
+++ b/pkg/minio-helper/tycovar.go
@@ -0,0 +1,29 @@
+package miniohelper
+
+import (
+ "io"
+ "net/url"
+ "time"
+)
+
+type UploadReaderInput struct {
+ File io.Reader
+ Name string
+ Size int64
+ ContentType string
+ BucketName string
+}
+
+type UploadPathInput struct {
+ BucketName string
+ ContentType string
+ Name string
+ Path string
+}
+
+type PresignedGetInput struct {
+ Bucket string
+ Object string
+ Expiry time.Duration
+ ReqParams url.Values
+}
diff --git a/pkg/upload-helper/tycovar.go b/pkg/upload-helper/tycovar.go
new file mode 100644
index 00000000..09142c1b
--- /dev/null
+++ b/pkg/upload-helper/tycovar.go
@@ -0,0 +1,16 @@
+package uploadhelper
+
+type UploadResponse struct {
+ Success bool `json:"success"`
+ Message string `json:"message"`
+ URL string `json:"url,omitempty"`
+ FileName string `json:"filename,omitempty"`
+}
+
+type MultipleUploadResponse struct {
+ Success bool `json:"success"`
+ Message string `json:"message"`
+ TotalFiles int `json:"total_files"`
+ SuccessCount int `json:"success_count"`
+ Results []UploadResponse `json:"results"`
+}
diff --git a/pkg/upload-helper/upload-helper.go b/pkg/upload-helper/upload-helper.go
new file mode 100644
index 00000000..0ce72ff1
--- /dev/null
+++ b/pkg/upload-helper/upload-helper.go
@@ -0,0 +1,74 @@
+package uploadhelper
+
+import (
+ "fmt"
+ "path/filepath"
+ "strings"
+
+ ere "simrs-vx/internal/domain/references/encounter"
+)
+
+func getBucketForType(docType string) (string, error) {
+ switch strings.ToLower(docType) {
+ case "resident", "resident-number", "ktp":
+ return string(ere.UCPRN), nil
+ case "driver-license", "sim", "license":
+ return string(ere.UCPDL), nil
+ case "passport", "paspor":
+ return string(ere.UCPP), nil
+ case "family-card", "kk", "family":
+ return string(ere.UCPFC), nil
+ case "mcu", "medical", "mcu-result":
+ return string(ere.UCMIR), nil
+ default:
+ return "", fmt.Errorf("unknown document type: %s", docType)
+ }
+}
+
+// getValidFileTypesForBucket returns allowed file types for each bucket
+func getValidFileTypesForBucket(bucketName string) []string {
+ switch bucketName {
+ case string(ere.UCPRN), string(ere.UCPDL), string(ere.UCPP), string(ere.UCPFC):
+ return []string{".jpg", ".jpeg", ".png", ".pdf", ".gif"}
+ case string(ere.UCMIR):
+ return []string{".jpg", ".jpeg", ".png", ".pdf", ".gif", ".doc", ".docx", ".xls", ".xlsx"}
+ default:
+ return []string{".jpg", ".jpeg", ".png", ".pdf"}
+ }
+}
+
+// isValidFileType checks if the uploaded file type is allowed for the specific bucket
+func IsValidFileType(ext, bucketName string) bool {
+ allowedTypes := getValidFileTypesForBucket(bucketName)
+
+ for _, allowedExt := range allowedTypes {
+ if ext == allowedExt {
+ return true
+ }
+ }
+ return false
+}
+
+// getContentType determines the content type based on file extension
+func getContentType(filename string) string {
+ switch strings.ToLower(filepath.Ext(filename)) {
+ case ".jpg", ".jpeg":
+ return "image/jpeg"
+ case ".png":
+ return "image/png"
+ case ".pdf":
+ return "application/pdf"
+ case ".gif":
+ return "image/gif"
+ case ".doc":
+ return "application/msword"
+ case ".docx":
+ return "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
+ case ".xls":
+ return "application/vnd.ms-excel"
+ case ".xlsx":
+ return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
+ default:
+ return "application/octet-stream"
+ }
+}
diff --git a/pkg/use-case-helper/use-case-helper.go b/pkg/use-case-helper/use-case-helper.go
index beb369c1..8c41266f 100644
--- a/pkg/use-case-helper/use-case-helper.go
+++ b/pkg/use-case-helper/use-case-helper.go
@@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"strings"
+ "time"
pl "simrs-vx/pkg/logger"
@@ -52,6 +53,31 @@ func HandleReadError(err error, event *pl.Event, itemType string, id interface{}
return pl.SetLogError(event, nil)
}
+func HandleSearchError(err error, event *pl.Event, itemType string, query interface{}, data any) error {
+ if err == nil {
+ pl.SetLogInfo(event, data, "complete")
+ return nil
+ }
+
+ if errors.Is(err, gorm.ErrRecordNotFound) {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-notFound",
+ Detail: fmt.Sprintf("%s with query '%v' not found", itemType, query),
+ Raw: err,
+ }
+ } else {
+ event.Status = "failed"
+ event.ErrInfo = pl.ErrorInfo{
+ Code: "data-search-fail",
+ Detail: fmt.Sprintf("%s search failed", itemType),
+ Raw: err,
+ }
+ }
+
+ return pl.SetLogError(event, nil)
+}
+
func GetMiddlewareErrorCode(mwType MWType) string {
if strings.Contains(string(mwType), "Pre") {
return "MW_PRE_FAILED"
@@ -77,6 +103,13 @@ func HandleMiddlewareError(event *pl.Event, mwType, mwName string, logData inter
return pl.SetLogError(event, logData)
}
+func IsDataNotFoundError(err error) bool {
+ if err == nil {
+ return false
+ }
+ return strings.Contains(err.Error(), "code: data-notFound")
+}
+
func AddPrefix(prefix string, str string) string {
return prefix + str
}
@@ -85,7 +118,11 @@ func GetPreloads(input string) []string {
result := []string{}
parts := strings.Split(input, ",")
for _, p := range parts {
- result = append(result, kebabToPascal(p))
+ subParts := strings.Split(p, "-")
+ for i := range subParts {
+ subParts[i] = kebabToPascal(subParts[i])
+ }
+ result = append(result, strings.Join(subParts, "."))
}
return result
}
@@ -101,3 +138,8 @@ func kebabToPascal(input string) string {
}
return strings.Join(parts, "")
}
+
+func GetTimeNow() *time.Time {
+ tmp := time.Now()
+ return &tmp
+}