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/20250904045113.sql b/cmd/migration/migrations/20250904045113.sql deleted file mode 100644 index cbdcca65..00000000 --- a/cmd/migration/migrations/20250904045113.sql +++ /dev/null @@ -1,12 +0,0 @@ --- Create "Laborant" table -CREATE TABLE "public"."Laborant" ( - "Id" serial NOT NULL, - "CreatedAt" timestamptz NULL, - "UpdatedAt" timestamptz NULL, - "DeletedAt" timestamptz NULL, - "Code" character varying(10) NULL, - "Name" character varying(50) NULL, - "Parent_Id" smallint NULL, - PRIMARY KEY ("Id"), - CONSTRAINT "uni_Laborant_Code" UNIQUE ("Code") -); diff --git a/cmd/migration/migrations/20250904045250.sql b/cmd/migration/migrations/20250904045250.sql deleted file mode 100644 index ce493659..00000000 --- a/cmd/migration/migrations/20250904045250.sql +++ /dev/null @@ -1,2 +0,0 @@ --- Modify "Patient" table -ALTER TABLE "public"."Patient" ADD CONSTRAINT "uni_Patient_Number" UNIQUE ("Number"); diff --git a/cmd/migration/migrations/20250904050121.sql b/cmd/migration/migrations/20250904050121.sql deleted file mode 100644 index 40202be4..00000000 --- a/cmd/migration/migrations/20250904050121.sql +++ /dev/null @@ -1,2 +0,0 @@ --- Modify "Laborant" table -ALTER TABLE "public"."Laborant" ALTER COLUMN "Id" TYPE bigint, DROP COLUMN "Code", DROP COLUMN "Name", DROP COLUMN "Parent_Id", ADD COLUMN "Employee_Id" bigint NULL, ADD COLUMN "IHS_Number" character varying(20) NULL, ADD CONSTRAINT "fk_Laborant_Employee" FOREIGN KEY ("Employee_Id") REFERENCES "public"."Employee" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION; diff --git a/cmd/migration/migrations/20250829081952.sql b/cmd/migration/migrations/20250904105930.sql similarity index 70% rename from cmd/migration/migrations/20250829081952.sql rename to cmd/migration/migrations/20250904105930.sql index c74cb017..39175bfb 100644 --- a/cmd/migration/migrations/20250829081952.sql +++ b/cmd/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/migration/migrations/20250904141448.sql b/cmd/migration/migrations/20250904141448.sql new file mode 100644 index 00000000..56a113ca --- /dev/null +++ b/cmd/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/migration/migrations/atlas.sum b/cmd/migration/migrations/atlas.sum index 97320192..10859e9b 100644 --- a/cmd/migration/migrations/atlas.sum +++ b/cmd/migration/migrations/atlas.sum @@ -1,13 +1,3 @@ -h1:6MHXV9+frKLPEcCO0gFFKAXHpOQ9N2XozZ+BKsjEyPk= -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:4i/3uJdYiAuKZ6upRK+xXUHBN7xHSK8G5QjaDkQt8E8= -20250904045113.sql h1:/LPs3tJWaQgK2HHdFHjSE/65GQ17rXgQ9NhTlgCiDVo= -20250904045250.sql h1:drbQ0H80dgxnQ26AMfPBwV8wwAOuzSBnoodHwdwV7cI= -20250904050121.sql h1:5AcfudjmiD3Z7wtRcw8i74ryUsMsMfcssnk0CyABvAE= +h1:G2T3Gv3jMXqZDaBw/lSU8IhowMI3z//r+ZtHxndsLc4= +20250904105930.sql h1:Vv4vCurl7m7/ZB6TjRpkubHpQ4RYwSUn0QHdzfoGpzY= +20250904141448.sql h1:FYCHH9Os4KkrZMDu/jR8FMP+wLMRW+Mb0PkLU/9BRDg= diff --git a/internal/domain/main-entities/doctor/dto.go b/internal/domain/main-entities/doctor/dto.go index f016cc1f..3d744a32 100644 --- a/internal/domain/main-entities/doctor/dto.go +++ b/internal/domain/main-entities/doctor/dto.go @@ -3,14 +3,18 @@ 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 { @@ -20,10 +24,12 @@ type ReadListDto struct { } 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"` + 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"` Page int `json:"page"` PageSize int `json:"page_size"` @@ -54,22 +60,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/employee/dto.go b/internal/domain/main-entities/employee/dto.go index 371d82a1..762e72a4 100644 --- a/internal/domain/main-entities/employee/dto.go +++ b/internal/domain/main-entities/employee/dto.go @@ -4,27 +4,16 @@ 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 { @@ -34,12 +23,11 @@ type ReadListDto struct { } 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"` + 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"` Page int `json:"page"` PageSize int `json:"page_size"` @@ -70,15 +58,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 +74,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 +90,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..8113fc96 100644 --- a/internal/domain/main-entities/employee/entity.go +++ b/internal/domain/main-entities/employee/entity.go @@ -6,18 +6,16 @@ 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" ) 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"` + 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..49a3b987 100644 --- a/internal/domain/main-entities/encounter/dto.go +++ b/internal/domain/main-entities/encounter/dto.go @@ -4,6 +4,8 @@ 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" + es "simrs-vx/internal/domain/main-entities/specialist" + ess "simrs-vx/internal/domain/main-entities/subspecialist" eu "simrs-vx/internal/domain/main-entities/unit" ere "simrs-vx/internal/domain/references/encounter" "time" @@ -15,6 +17,8 @@ type CreateDto struct { 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"` Assignment_Doctor_Id *uint `json:"assignment_doctor_id"` Responsible_Doctor_Id *uint `json:"responsible_doctor_id"` @@ -23,9 +27,24 @@ type CreateDto struct { } type ReadListDto struct { - Code string `json:"code"` - Name string `json:"name"` - Parent_Id *int16 `json:"parent_id"` + FilterDto + Includes string `json:"includes"` + Preloads []string `json:"-"` +} + +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"` + 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"` Page int `json:"page"` PageSize int `json:"page_size"` @@ -61,6 +80,10 @@ type ResponseDto struct { 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"` Assignment_Doctor_Id *uint `json:"assignment_doctor_id"` @@ -79,6 +102,10 @@ func (d Encounter) ToResponse() ResponseDto { 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, Assignment_Doctor_Id: d.Assignment_Doctor_Id, Assignment_Doctor: d.Assignment_Doctor, diff --git a/internal/domain/main-entities/encounter/entity.go b/internal/domain/main-entities/encounter/entity.go index 258c6354..95d2cac7 100644 --- a/internal/domain/main-entities/encounter/entity.go +++ b/internal/domain/main-entities/encounter/entity.go @@ -4,6 +4,8 @@ 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" + es "simrs-vx/internal/domain/main-entities/specialist" + ess "simrs-vx/internal/domain/main-entities/subspecialist" eu "simrs-vx/internal/domain/main-entities/unit" ere "simrs-vx/internal/domain/references/encounter" "time" @@ -17,6 +19,10 @@ type Encounter struct { 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"` Assignment_Doctor_Id *uint `json:"assignment_doctor_id"` Assignment_Doctor *ed.Doctor `json:"assignment_doctor,omitempty" gorm:"foreignKey:Assignment_Doctor_Id;references:Id"` diff --git a/internal/domain/main-entities/infra/dto.go b/internal/domain/main-entities/infra/dto.go index 07dae72a..69531f5f 100644 --- a/internal/domain/main-entities/infra/dto.go +++ b/internal/domain/main-entities/infra/dto.go @@ -8,11 +8,15 @@ import ( ) 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=10"` + 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 { diff --git a/internal/domain/main-entities/laborant/entity.go b/internal/domain/main-entities/laborant/entity.go index 82870b06..eeb63bef 100644 --- a/internal/domain/main-entities/laborant/entity.go +++ b/internal/domain/main-entities/laborant/entity.go @@ -9,5 +9,5 @@ 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:"size:20"` + 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..f59d2ee5 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,6 +11,7 @@ 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 { @@ -22,6 +24,7 @@ type FilterDto struct { Employee_Id *uint `json:"employee_id"` IHS_Number *string `json:"ihs_number"` Unit_Id *uint16 `json:"unit_id"` + Infra_Id *uint16 `json:"infra_id"` Page int `json:"page"` PageSize int `json:"page_size"` @@ -55,6 +58,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 +69,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/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 e3f5a622..02e9b0e7 100644 --- a/internal/domain/main-entities/patient/dto.go +++ b/internal/domain/main-entities/patient/dto.go @@ -7,7 +7,6 @@ import ( epc "simrs-vx/internal/domain/main-entities/person-contact" epr "simrs-vx/internal/domain/main-entities/person-relative" erc "simrs-vx/internal/domain/references/common" - ero "simrs-vx/internal/domain/references/organization" "time" ) @@ -28,12 +27,10 @@ type ReadListDto struct { } 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"` + Person_Id *uint `json:"person_id"` + 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"` 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/room/dto.go b/internal/domain/main-entities/room/dto.go new file mode 100644 index 00000000..eff76d0a --- /dev/null +++ b/internal/domain/main-entities/room/dto.go @@ -0,0 +1,87 @@ +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"` + Preloads []string `json:"-"` +} + +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"` + + Page int `json:"page"` + PageSize int `json:"page_size"` + NoPagination int `json:"no_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.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..bcc02aeb --- /dev/null +++ b/internal/domain/main-entities/room/entity.go @@ -0,0 +1,21 @@ +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 Room struct { + ecore.SmallMain // adjust this according to the needs + Infra_Id *uint16 `json:"infra_id"` + Infra *ei.Infra `json:"infra,omitempty" gorm:"foreignKey: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"` +} 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..87044ba7 --- /dev/null +++ b/internal/domain/main-entities/specialist-intern/dto.go @@ -0,0 +1,88 @@ +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"` + Preloads []string `json:"-"` +} + +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"` + + Page int `json:"page"` + PageSize int `json:"page_size"` + NoPagination int `json:"no_pagination"` +} + +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..ac10b720 --- /dev/null +++ b/internal/domain/main-entities/specialist/dto.go @@ -0,0 +1,72 @@ +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"` + Preloads []string `json:"-"` +} + +type FilterDto struct { + Code string `json:"code"` + Name string `json:"name"` + Unit_Id *uint16 `json:"unit_id"` + + Page int `json:"page"` + PageSize int `json:"page_size"` + NoPagination int `json:"no_pagination"` +} + +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..cf387146 --- /dev/null +++ b/internal/domain/main-entities/subspecialist/dto.go @@ -0,0 +1,72 @@ +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"` + Preloads []string `json:"-"` +} + +type FilterDto struct { + Code *string `json:"code"` + Name *string `json:"name"` + Specialist_Id *uint16 `json:"specialist_id"` + + Page int `json:"page"` + PageSize int `json:"page_size"` + NoPagination int `json:"no_pagination"` +} + +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/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/user/dto.go b/internal/domain/main-entities/user/dto.go index 26233c81..47b50dca 100644 --- a/internal/domain/main-entities/user/dto.go +++ b/internal/domain/main-entities/user/dto.go @@ -2,14 +2,30 @@ package user import ( 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" "time" ) 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"` + Position_Code ero.UserPosisitionCode `json:"position_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 { @@ -68,6 +84,15 @@ 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"` + 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..43669663 100644 --- a/internal/domain/main-entities/user/entity.go +++ b/internal/domain/main-entities/user/entity.go @@ -3,16 +3,18 @@ package user import ( ecore "simrs-vx/internal/domain/base-entities/core" erc "simrs-vx/internal/domain/references/common" + ero "simrs-vx/internal/domain/references/organization" "time" ) 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.UserPosisitionCode `json:"position_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/references/organization/organization.go b/internal/domain/references/organization/organization.go index 5c86ba51..30aa25b5 100644 --- a/internal/domain/references/organization/organization.go +++ b/internal/domain/references/organization/organization.go @@ -1,22 +1,23 @@ package organization type ( - EmployeePosisitionCode string - ItemGroupCode string - InfraGroupCode string - UnitTypeCode string - DoctorFeeTypeCode string + UserPosisitionCode string + ItemGroupCode string + InfraGroupCode string + UnitTypeCode string + DoctorFeeTypeCode string ) 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 + UPCDoc UserPosisitionCode = "doctor" // Dokter + UPCNur UserPosisitionCode = "nurse" // Perawat + UPCNut UserPosisitionCode = "nutritionist" // Ahli gizi + UPCLab UserPosisitionCode = "laborant" // Laboran + UPCPha UserPosisitionCode = "pharmacy" // Farmasi + UPCPay UserPosisitionCode = "payment" // Pembayaran + UPCPav UserPosisitionCode = "payment-verificator" // Konfirmasi pembayaran + UPCMan UserPosisitionCode = "management" // Manajemen + UPCInt UserPosisitionCode = "specialist-intern" // PPDS ITGCInfra ItemGroupCode = "infra" ITGCMedicine ItemGroupCode = "medicine" diff --git a/internal/domain/references/person/person.go b/internal/domain/references/person/person.go index dd41bd25..d21399d2 100644 --- a/internal/domain/references/person/person.go +++ b/internal/domain/references/person/person.go @@ -111,180 +111,180 @@ const ( RCOther RelationshipCode = "other" // Lainnya ) -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/interface/main-handler/main-handler.go b/internal/interface/main-handler/main-handler.go index 80aa4df4..476dacc7 100644 --- a/internal/interface/main-handler/main-handler.go +++ b/internal/interface/main-handler/main-handler.go @@ -60,6 +60,8 @@ 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" @@ -148,6 +150,8 @@ 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/village", village.O) hc.RegCrud(r, "/v1/district", district.O) 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/migration/migration.go b/internal/interface/migration/migration.go index 3c33be2c..ee3cf1fc 100644 --- a/internal/interface/migration/migration.go +++ b/internal/interface/migration/migration.go @@ -46,6 +46,10 @@ import ( 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" + 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" @@ -129,6 +133,10 @@ func GetEntities() []any { &patient.Patient{}, &encounter.Encounter{}, &laborant.Laborant{}, + &specialist.Specialist{}, + &subspecialist.Subspecialist{}, + &specialistintern.SpecialistIntern{}, + &room.Room{}, } } 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/employee/case.go b/internal/use-case/main-use-case/employee/case.go index a6c16652..030374f0 100644 --- a/internal/use-case/main-use-case/employee/case.go +++ b/internal/use-case/main-use-case/employee/case.go @@ -1,26 +1,9 @@ package employee import ( - "errors" "strconv" - ed "simrs-vx/internal/domain/main-entities/doctor" e "simrs-vx/internal/domain/main-entities/employee" - el "simrs-vx/internal/domain/main-entities/laborant" - 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" - ul "simrs-vx/internal/use-case/main-use-case/laborant" - 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" @@ -42,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) @@ -52,83 +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 - } - case ero.EPCLab: - createLaborant := el.CreateDto{ - Employee_Id: &data.Id, - IHS_Number: input.IHS_Number, - } - if _, err := ul.CreateData(createLaborant, &event, tx); err != nil { - return err - } - default: - return errors.New("invalid employee position") - } - mwRunner.setMwType(pu.MWTPost) // Run post-middleware if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil { @@ -282,137 +188,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 - } - case ero.EPCLab: - readLab := el.ReadDetailDto{Employee_Id: &data.Id} - readLabData, err := ul.ReadDetailData(readLab, &event, tx) - if err != nil { - return err - } - createLab := el.CreateDto{ - Employee_Id: &data.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 - } - 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/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..377fdfb8 100644 --- a/internal/use-case/main-use-case/employee/lib.go +++ b/internal/use-case/main-use-case/employee/lib.go @@ -102,7 +102,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 +172,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/infra/case.go b/internal/use-case/main-use-case/infra/case.go index e95e09d3..26f9d319 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 { 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/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/person/helper.go b/internal/use-case/main-use-case/person/helper.go index 65f6bdb8..a2588c0e 100644 --- a/internal/use-case/main-use-case/person/helper.go +++ b/internal/use-case/main-use-case/person/helper.go @@ -24,10 +24,12 @@ 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.Ethnic_Code = inputSrc.Ethnic_Code + data.Language_Code = inputSrc.Language_Code } 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..c14fbbe9 --- /dev/null +++ b/internal/use-case/main-use-case/room/case.go @@ -0,0 +1,278 @@ +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 len(input.Includes) > 0 { + input.Preloads = pu.GetPreloads(input.Includes) + } + 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), + }, + 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..f8943263 --- /dev/null +++ b/internal/use-case/main-use-case/room/lib.go @@ -0,0 +1,155 @@ +package room + +import ( + e "simrs-vx/internal/domain/main-entities/room" + 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 { + 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 +} + +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 + } + + if len(input.Preloads) > 0 { + for _, preload := range input.Preloads { + tx = tx.Preload(preload) + } + } + + tx = tx. + Model(&e.Room{}). + 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 == 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.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/specialist-intern/case.go b/internal/use-case/main-use-case/specialist-intern/case.go new file mode 100644 index 00000000..ad71627b --- /dev/null +++ b/internal/use-case/main-use-case/specialist-intern/case.go @@ -0,0 +1,278 @@ +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 len(input.Includes) > 0 { + input.Preloads = pu.GetPreloads(input.Includes) + } + 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), + }, + 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..81c0f0a9 --- /dev/null +++ b/internal/use-case/main-use-case/specialist-intern/lib.go @@ -0,0 +1,162 @@ +package specialistintern + +import ( + e "simrs-vx/internal/domain/main-entities/specialist-intern" + 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 { + 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 +} + +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 + } + + if len(input.Preloads) > 0 { + for _, preload := range input.Preloads { + tx = tx.Preload(preload) + } + } + + tx = tx. + Model(&e.SpecialistIntern{}). + 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 == 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.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..1ede6556 --- /dev/null +++ b/internal/use-case/main-use-case/specialist/case.go @@ -0,0 +1,278 @@ +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 len(input.Includes) > 0 { + input.Preloads = pu.GetPreloads(input.Includes) + } + 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), + }, + 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..5d31ea56 --- /dev/null +++ b/internal/use-case/main-use-case/specialist/lib.go @@ -0,0 +1,155 @@ +package specialist + +import ( + e "simrs-vx/internal/domain/main-entities/specialist" + 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 { + 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 +} + +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 + } + + if len(input.Preloads) > 0 { + for _, preload := range input.Preloads { + tx = tx.Preload(preload) + } + } + + tx = tx. + Model(&e.Specialist{}). + 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 == 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.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..66df538b --- /dev/null +++ b/internal/use-case/main-use-case/subspecialist/case.go @@ -0,0 +1,278 @@ +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 len(input.Includes) > 0 { + input.Preloads = pu.GetPreloads(input.Includes) + } + 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), + }, + 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..49c87685 --- /dev/null +++ b/internal/use-case/main-use-case/subspecialist/lib.go @@ -0,0 +1,155 @@ +package subspecialist + +import ( + e "simrs-vx/internal/domain/main-entities/subspecialist" + 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 { + 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 +} + +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 + } + + if len(input.Preloads) > 0 { + for _, preload := range input.Preloads { + tx = tx.Preload(preload) + } + } + + tx = tx. + Model(&e.Subspecialist{}). + 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 == 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.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/user/case.go b/internal/use-case/main-use-case/user/case.go index c4f55985..ae1e8464 100644 --- a/internal/use-case/main-use-case/user/case.go +++ b/internal/use-case/main-use-case/user/case.go @@ -1,12 +1,33 @@ 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" + 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" + 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 +57,103 @@ 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 + } + default: + return errors.New("invalid employee position") + } + mwRunner.setMwType(pu.MWTPost) // Run post-middleware if err := mwRunner.RunCreateMiddleware(createPostMw, &input, &data); err != nil { @@ -192,10 +304,180 @@ 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 + } + 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 +}