From a8f9dcf73814bf014f555da68f1ace111f58c398 Mon Sep 17 00:00:00 2001 From: dpurbosakti Date: Wed, 20 Aug 2025 13:07:56 +0700 Subject: [PATCH] feat (crud): add division, division-position --- ...{20250819053416.sql => 20250820052409.sql} | 11 + cmd/migration/migrations/20250820055632.sql | 12 + cmd/migration/migrations/atlas.sum | 5 +- .../main-entities/division-position/dto.go | 68 +++ .../main-entities/division-position/entity.go | 14 + internal/domain/main-entities/division/dto.go | 68 +++ .../domain/main-entities/division/entity.go | 12 + .../domain/references/encounter/encounter.go | 44 ++ .../references/examination/examination.go | 44 -- .../main-handler/division-position/handler.go | 71 +++ .../main-handler/division/handler.go | 71 +++ .../interface/main-handler/main-handler.go | 6 + internal/interface/migration/migration.go | 4 + .../main-use-case/division-position/case.go | 452 ++++++++++++++++++ .../main-use-case/division-position/helper.go | 23 + .../main-use-case/division-position/lib.go | 98 ++++ .../division-position/tycovar.go | 32 ++ .../use-case/main-use-case/division/case.go | 452 ++++++++++++++++++ .../use-case/main-use-case/division/helper.go | 23 + .../use-case/main-use-case/division/lib.go | 98 ++++ .../main-use-case/division/tycovar.go | 32 ++ 21 files changed, 1594 insertions(+), 46 deletions(-) rename cmd/migration/migrations/{20250819053416.sql => 20250820052409.sql} (61%) create mode 100644 cmd/migration/migrations/20250820055632.sql create mode 100644 internal/domain/main-entities/division-position/dto.go create mode 100644 internal/domain/main-entities/division-position/entity.go create mode 100644 internal/domain/main-entities/division/dto.go create mode 100644 internal/domain/main-entities/division/entity.go create mode 100644 internal/domain/references/encounter/encounter.go delete mode 100644 internal/domain/references/examination/examination.go create mode 100644 internal/interface/main-handler/division-position/handler.go create mode 100644 internal/interface/main-handler/division/handler.go create mode 100644 internal/use-case/main-use-case/division-position/case.go create mode 100644 internal/use-case/main-use-case/division-position/helper.go create mode 100644 internal/use-case/main-use-case/division-position/lib.go create mode 100644 internal/use-case/main-use-case/division-position/tycovar.go create mode 100644 internal/use-case/main-use-case/division/case.go create mode 100644 internal/use-case/main-use-case/division/helper.go create mode 100644 internal/use-case/main-use-case/division/lib.go create mode 100644 internal/use-case/main-use-case/division/tycovar.go diff --git a/cmd/migration/migrations/20250819053416.sql b/cmd/migration/migrations/20250820052409.sql similarity index 61% rename from cmd/migration/migrations/20250819053416.sql rename to cmd/migration/migrations/20250820052409.sql index fa94170a..b3df477e 100644 --- a/cmd/migration/migrations/20250819053416.sql +++ b/cmd/migration/migrations/20250820052409.sql @@ -1,3 +1,14 @@ +-- Create "Division" table +CREATE TABLE "public"."Division" ( + "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") +); -- Create "User" table CREATE TABLE "public"."User" ( "Id" bigserial NOT NULL, diff --git a/cmd/migration/migrations/20250820055632.sql b/cmd/migration/migrations/20250820055632.sql new file mode 100644 index 00000000..9e9369be --- /dev/null +++ b/cmd/migration/migrations/20250820055632.sql @@ -0,0 +1,12 @@ +-- Create "DivisionPosition" table +CREATE TABLE "public"."DivisionPosition" ( + "Id" serial NOT NULL, + "CreatedAt" timestamptz NULL, + "UpdatedAt" timestamptz NULL, + "DeletedAt" timestamptz NULL, + "Division_Id" integer NULL, + "Code" character varying(10) NULL, + "Name" character varying(50) NULL, + PRIMARY KEY ("Id"), + CONSTRAINT "fk_DivisionPosition_Division" FOREIGN KEY ("Division_Id") REFERENCES "public"."Division" ("Id") ON UPDATE NO ACTION ON DELETE NO ACTION +); diff --git a/cmd/migration/migrations/atlas.sum b/cmd/migration/migrations/atlas.sum index d8fcc6bb..d9bda753 100644 --- a/cmd/migration/migrations/atlas.sum +++ b/cmd/migration/migrations/atlas.sum @@ -1,2 +1,3 @@ -h1:TslQ6d3/z4H6DQJvWAGwP3IVSAr/qYOosLEmorZhYx0= -20250819053416.sql h1:kYIqQm8dEYH+feZEHrCekuEvwKl3h1W4zlIpPAWn3W8= +h1:RD9Yp8yQFfSKnSkmgYm47Q47Dn3FmZvYDCeNIiVKU1w= +20250820052409.sql h1:W2zifi3eF+hG0fHvIrY15dH82WO/4QPGdZOEUkgKlAg= +20250820055632.sql h1:sPoDUmT4aZV4qiaq63ssIcoevr3N2WAjRcU1c+Kz6kc= diff --git a/internal/domain/main-entities/division-position/dto.go b/internal/domain/main-entities/division-position/dto.go new file mode 100644 index 00000000..3847d332 --- /dev/null +++ b/internal/domain/main-entities/division-position/dto.go @@ -0,0 +1,68 @@ +package divisionposition + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" +) + +type CreateDto struct { + Division_Id *uint16 `json:"division_id"` + Code string `json:"code"` + Name string `json:"name"` +} + +type ReadListDto struct { + Division_Id *uint16 `json:"division_id"` + Code string `json:"code"` + Name string `json:"name"` + + Page int `json:"page"` + PageSize int `json:"page_size"` + NoPagination int `json:"no_pagination"` +} + +type ReadDetailDto struct { + Id uint16 `json:"id"` + Division_Id *uint16 `json:"division_id"` + Code string `json:"code"` + Name string `json:"name"` +} + +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 + Division_Id *uint16 `json:"division_id"` + Code string `json:"code"` + Name string `json:"name"` +} + +func (d DivisionPosition) ToResponse() ResponseDto { + resp := ResponseDto{ + Division_Id: d.Division_Id, + Code: d.Code, + Name: d.Name, + } + resp.SmallMain = d.SmallMain + return resp +} + +func ToResponseList(users []DivisionPosition) []ResponseDto { + resp := make([]ResponseDto, len(users)) + for i, u := range users { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/division-position/entity.go b/internal/domain/main-entities/division-position/entity.go new file mode 100644 index 00000000..88311e96 --- /dev/null +++ b/internal/domain/main-entities/division-position/entity.go @@ -0,0 +1,14 @@ +package divisionposition + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" + ed "simrs-vx/internal/domain/main-entities/division" +) + +type DivisionPosition struct { + ecore.SmallMain // adjust this according to the needs + Division_Id *uint16 `json:"division_id"` + Division *ed.Division `json:"division" gorm:"foreignKey:Division_Id"` + Code string `json:"code" gorm:"size:10"` + Name string `json:"name" gorm:"size:50"` +} diff --git a/internal/domain/main-entities/division/dto.go b/internal/domain/main-entities/division/dto.go new file mode 100644 index 00000000..3d369cdf --- /dev/null +++ b/internal/domain/main-entities/division/dto.go @@ -0,0 +1,68 @@ +package division + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" +) + +type CreateDto struct { + Code string `json:"code"` + Name string `json:"name"` + Parent_Id *int16 `json:"parent_id"` +} + +type ReadListDto struct { + Code string `json:"code"` + Name string `json:"name"` + Parent_Id *int16 `json:"parent_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"` + Name string `json:"name"` + Parent_Id *int16 `json:"parent_id"` +} + +type UpdateDto struct { + Id uint16 `json:"id"` + CreateDto +} + +type DeleteDto struct { + Id uint16 `json:"id"` +} + +type MetaDto struct { + PageNumber int `json:"page_number"` + PageSize int `json:"page_size"` + Count int `json:"count"` +} + +type ResponseDto struct { + ecore.SmallMain + Code string `json:"code"` + Name string `json:"name"` + Parent_Id *int16 `json:"parent_id"` +} + +func (d Division) ToResponse() ResponseDto { + resp := ResponseDto{ + Code: d.Code, + Name: d.Name, + Parent_Id: d.Parent_Id, + } + resp.SmallMain = d.SmallMain + return resp +} + +func ToResponseList(users []Division) []ResponseDto { + resp := make([]ResponseDto, len(users)) + for i, u := range users { + resp[i] = u.ToResponse() + } + return resp +} diff --git a/internal/domain/main-entities/division/entity.go b/internal/domain/main-entities/division/entity.go new file mode 100644 index 00000000..55918a8d --- /dev/null +++ b/internal/domain/main-entities/division/entity.go @@ -0,0 +1,12 @@ +package division + +import ( + ecore "simrs-vx/internal/domain/base-entities/core" +) + +type Division struct { + ecore.SmallMain // adjust this according to the needs + Code string `json:"code" gorm:"size:10"` + Name string `json:"name" gorm:"size:50"` + Parent_Id *int16 `json:"parent_id"` +} diff --git a/internal/domain/references/encounter/encounter.go b/internal/domain/references/encounter/encounter.go new file mode 100644 index 00000000..9ffa168d --- /dev/null +++ b/internal/domain/references/encounter/encounter.go @@ -0,0 +1,44 @@ +package encounter + +type ( + EncounterStatus string + EncounterClass string + EmergencyClass string + InpatientClass string +) + +const ( + EncounterStatusNew EncounterStatus = "new" + EncounterStatusNurse EncounterStatus = "nurse assessment" + EncounterStatusDoctor EncounterStatus = "doctor assessment" + EncounterStatusDone EncounterStatus = "done" + EncounterStatusCancel EncounterStatus = "canceled" +) +const ( + IGD EmergencyClass = "igd" + Ponek EmergencyClass = "ponek" +) +const ( + ECAmbulatory EncounterClass = "ambulatory" + ECInpatient EncounterClass = "inpatient" + ECEmergency EncounterClass = "emergency" + ECRadiology EncounterClass = "radiology" +) + +func (ec EncounterClass) Code() string { + switch ec { + case ECAmbulatory: + return "AMB" + case ECInpatient: + return "IMP" + case ECEmergency: + return "EMER" + default: + return "UNKNOWN" + } +} + +const ( + ICU InpatientClass = "ICU" + NonICU InpatientClass = "non ICU" +) diff --git a/internal/domain/references/examination/examination.go b/internal/domain/references/examination/examination.go deleted file mode 100644 index 4ca227db..00000000 --- a/internal/domain/references/examination/examination.go +++ /dev/null @@ -1,44 +0,0 @@ -package examination - -type ( - ExaminationStatus string - ExaminationClass string - EmergencyClass string - InpatientClass string -) - -const ( - ExaminationStatusNew ExaminationStatus = "new" - ExaminationStatusNurse ExaminationStatus = "nurse assessment" - ExaminationStatusDoctor ExaminationStatus = "doctor assessment" - ExaminationStatusDone ExaminationStatus = "done" - ExaminationStatusCancel ExaminationStatus = "canceled" -) -const ( - IGD EmergencyClass = "igd" - Ponek EmergencyClass = "ponek" -) -const ( - ECAmbulatory ExaminationClass = "ambulatory" - ECInpatient ExaminationClass = "inpatient" - ECEmergency ExaminationClass = "emergency" - ECRadiology ExaminationClass = "radiology" -) - -func (ec ExaminationClass) Code() string { - switch ec { - case ECAmbulatory: - return "AMB" - case ECInpatient: - return "IMP" - case ECEmergency: - return "EMER" - default: - return "UNKNOWN" - } -} - -const ( - ICU InpatientClass = "ICU" - NonICU InpatientClass = "non ICU" -) diff --git a/internal/interface/main-handler/division-position/handler.go b/internal/interface/main-handler/division-position/handler.go new file mode 100644 index 00000000..180b96ea --- /dev/null +++ b/internal/interface/main-handler/division-position/handler.go @@ -0,0 +1,71 @@ +package divisionposition + +import ( + "net/http" + + rw "github.com/karincake/risoles" + sf "github.com/karincake/semprit" + + // ua "github.com/karincake/tumpeng/auth/svc" + + e "simrs-vx/internal/domain/main-entities/division-position" + u "simrs-vx/internal/use-case/main-use-case/division-position" +) + +type myBase struct{} + +var O myBase + +func (obj myBase) Create(w http.ResponseWriter, r *http.Request) { + dto := e.CreateDto{} + if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { + return + } + res, err := u.Create(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) GetList(w http.ResponseWriter, r *http.Request) { + dto := e.ReadListDto{} + sf.UrlQueryParam(&dto, *r.URL) + res, err := u.ReadList(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) GetDetail(w http.ResponseWriter, r *http.Request) { + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id <= 0 { + return + } + dto := e.ReadDetailDto{} + dto.Id = uint16(id) + res, err := u.ReadDetail(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) Update(w http.ResponseWriter, r *http.Request) { + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id <= 0 { + return + } + + dto := e.UpdateDto{} + if res := rw.ValidateStructByIOR(w, r.Body, &dto); !res { + return + } + dto.Id = uint16(id) + res, err := u.Update(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) { + id := rw.ValidateInt(w, "id", r.PathValue("id")) + if id <= 0 { + return + } + + dto := e.DeleteDto{} + dto.Id = uint16(id) + res, err := u.Delete(dto) + rw.DataResponse(w, res, err) +} diff --git a/internal/interface/main-handler/division/handler.go b/internal/interface/main-handler/division/handler.go new file mode 100644 index 00000000..94940f55 --- /dev/null +++ b/internal/interface/main-handler/division/handler.go @@ -0,0 +1,71 @@ +package division + +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/division" + u "simrs-vx/internal/use-case/main-use-case/division" +) + +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/main-handler.go b/internal/interface/main-handler/main-handler.go index 8d0efe0f..22f8453b 100644 --- a/internal/interface/main-handler/main-handler.go +++ b/internal/interface/main-handler/main-handler.go @@ -21,6 +21,10 @@ import ( lh "simrs-vx/pkg/lang-helper" handlerlogger "simrs-vx/pkg/middleware/handler-logger" + /******************** sources ********************/ + division "simrs-vx/internal/interface/main-handler/division" + divisionposition "simrs-vx/internal/interface/main-handler/division-position" + ///// Internal "simrs-vx/internal/interface/main-handler/home" ) @@ -42,6 +46,8 @@ func SetRoutes() http.Handler { hk.Route("POST /v1/authentication/logout", r, auth.GuardMW, auth.Logout) hc.RegCrud(r, "/v1/user", user.O) + hc.RegCrud(r, "/v1/division", division.O) + hc.RegCrud(r, "/v1/division-position", divisionposition.O) ///// return cmw.SetCors(handlerlogger.SetLog(r)) diff --git a/internal/interface/migration/migration.go b/internal/interface/migration/migration.go index 8a22efb0..8396c8a6 100644 --- a/internal/interface/migration/migration.go +++ b/internal/interface/migration/migration.go @@ -5,6 +5,8 @@ import ( "io" "os" "os/exec" + ed "simrs-vx/internal/domain/main-entities/division" + edp "simrs-vx/internal/domain/main-entities/division-position" eu "simrs-vx/internal/domain/main-entities/user" "ariga.io/atlas-provider-gorm/gormschema" @@ -41,6 +43,8 @@ func Loader() { func GetEntities() []any { return []any{ &eu.User{}, + &ed.Division{}, + &edp.DivisionPosition{}, } } diff --git a/internal/use-case/main-use-case/division-position/case.go b/internal/use-case/main-use-case/division-position/case.go new file mode 100644 index 00000000..46d5d80f --- /dev/null +++ b/internal/use-case/main-use-case/division-position/case.go @@ -0,0 +1,452 @@ +package divisionposition + +import ( + "fmt" + e "simrs-vx/internal/domain/main-entities/division-position" + "strconv" + + dg "github.com/karincake/apem/db-gorm-pg" + d "github.com/karincake/dodol" + + pl "simrs-vx/pkg/logger" + + "gorm.io/gorm" +) + +const source = "division-position" + +func Create(input e.CreateDto) (*d.Data, error) { + data := e.DivisionPosition{} + + setData(&input, &data) + + event := pl.Event{ + Feature: "Create", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "create") + + err := dg.I.Transaction(func(tx *gorm.DB) error { + for i := range createPreMw { + mwName := fmt.Sprintf("createPreMw[%d]", i) + + pl.SetLogInfo(&event, data, "started", mwName) + + if err := createPreMw[i](&input, &data, tx); err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "MW_PRE_FAILED", // TODO: add to lang json + Detail: fmt.Sprintf("Pre-middleware %s failed", mwName), + Raw: err, + } + return pl.SetLogError(event, data) + } + + pl.SetLogInfo(&event, nil, "complete") + } + + pl.SetLogInfo(&event, data, "started", "DBCreate") + _, err := CreateData(&data, tx) + if err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-create-fail", + Detail: "Database insert failed", + Raw: err, + } + return pl.SetLogError(event, data) + } + + pl.SetLogInfo(&event, nil, "complete") + + for i := range createPostMw { + mwName := fmt.Sprintf("createPostMw[%d]", i) + + pl.SetLogInfo(&event, input, "started", mwName) + if err := createPostMw[i](&input, &data, tx); err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "MW_POST_FAILED", // TODO: add to lang json + Detail: fmt.Sprintf("Post-middleware %s failed", mwName), + Raw: err, + } + return pl.SetLogError(event, data) + } + } + + 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.DivisionPosition + var dataList []e.DivisionPosition + 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 { + for i := range readListPreMw { + mwName := fmt.Sprintf("readListPreMw[%d]", i) + + pl.SetLogInfo(&event, input, "started", mwName) + + if err := readListPreMw[i](&input, data, tx); err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "MW_PRE_FAILED", // TODO: add to lang json + Detail: fmt.Sprintf("Pre-middleware %s failed", mwName), + Raw: err, + } + return pl.SetLogError(event, input) + } + + pl.SetLogInfo(&event, nil, "complete") + } + + pl.SetLogInfo(&event, input, "started", "DBReadList") + dataList, metaList, err = ReadListData(input, tx) + if err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-read-list-fail", + Detail: "Database read list failed", + Raw: err, + } + return pl.SetLogError(event, input) + } + + pl.SetLogInfo(&event, nil, "complete") + + for i := range readListPostMw { + mwName := fmt.Sprintf("readListPostMw[%d]", i) + + pl.SetLogInfo(&event, input, "started", mwName) + + if err := readListPostMw[i](&input, data, tx); err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "MW_POST_FAILED", // TODO: add to lang json + Detail: fmt.Sprintf("Post-middleware %s failed", mwName), + Raw: err, + } + return pl.SetLogError(event, input) + } + + pl.SetLogInfo(&event, nil, "complete") + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "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.DivisionPosition + 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 { + for i := range readDetailPreMw { + mwName := fmt.Sprintf("readDetailPreMw[%d]", i) + + pl.SetLogInfo(&event, input, "started", mwName) + + if err := readDetailPreMw[i](&input, data, tx); err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "MW_PRE_FAILED", // TODO: add to lang json + Detail: fmt.Sprintf("Pre-middleware %s failed", mwName), + Raw: err, + } + return pl.SetLogError(event, input) + } + + pl.SetLogInfo(&event, nil, "complete") + } + + pl.SetLogInfo(&event, input, "started", "DBReadDetail") + data, err = ReadDetailData(input, tx) + if err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-read-detail-fail", + Detail: "Database read detail failed", + Raw: err, + } + return pl.SetLogError(event, input) + } + + pl.SetLogInfo(&event, nil, "complete") + + for i := range readDetailPostMw { + mwName := fmt.Sprintf("readDetailPostMw[%d]", i) + + pl.SetLogInfo(&event, data, "started", mwName) + + if err := readDetailPostMw[i](&input, data, tx); err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "MW_POST_FAILED", // TODO: add to lang json + Detail: fmt.Sprintf("Post-middleware %s failed", mwName), + Raw: err, + } + return pl.SetLogError(event, data) + } + + pl.SetLogInfo(&event, nil, "complete") + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "single-data", + "status": "fetched", + }, + Data: data.ToResponse(), + }, nil +} + +func Update(input e.UpdateDto) (*d.Data, error) { + rdDto := e.ReadDetailDto{Id: input.Id} + var data *e.DivisionPosition + 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") + data, err = ReadDetailData(rdDto, tx) + if err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-read-detail-fail", + Detail: "Database read detail failed", + Raw: err, + } + return pl.SetLogError(event, rdDto) + } + + pl.SetLogInfo(&event, input, "started", "setUpdate") + setData(&input, data) + + for i := range updatePreMw { + mwName := fmt.Sprintf("updatePreMw[%d]", i) + + pl.SetLogInfo(&event, data, "started", mwName) + + if err := updatePreMw[i](&rdDto, data, tx); err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "MW_PRE_FAILED", // TODO: add to lang json + Detail: fmt.Sprintf("Pre-middleware %s failed", mwName), + Raw: err, + } + return pl.SetLogError(event, data) + } + + pl.SetLogInfo(&event, nil, "complete") + } + + pl.SetLogInfo(&event, data, "started", "DBUpdate") + if err := UpdateData(*data, tx); err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-update-fail", + Detail: "Database update failed", + Raw: err, + } + return pl.SetLogError(event, data) + } + + pl.SetLogInfo(&event, nil, "complete") + + for i := range updatePostMw { + mwName := fmt.Sprintf("updatePostMw[%d]", i) + + pl.SetLogInfo(&event, data, "started", mwName) + + if err := updatePostMw[i](&rdDto, data, tx); err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "MW_POST_FAILED", // TODO: add to lang json + Detail: fmt.Sprintf("Post-middleware %s failed", mwName), + Raw: err, + } + return pl.SetLogError(event, data) + } + + pl.SetLogInfo(&event, nil, "complete") + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "single-data", + "status": "updated", + }, + Data: data.ToResponse(), + }, nil + +} + +func Delete(input e.DeleteDto) (*d.Data, error) { + rdDto := e.ReadDetailDto{Id: input.Id} + var data *e.DivisionPosition + 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") + data, err = ReadDetailData(rdDto, tx) + if err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-read-detail-fail", + Detail: "Database read detail failed", + Raw: err, + } + return pl.SetLogError(event, rdDto) + } + + pl.SetLogInfo(&event, nil, "complete") + + for i := range deletePreMw { + mwName := fmt.Sprintf("deletePreMw[%d]", i) + + pl.SetLogInfo(&event, data, "started", mwName) + + if err := deletePreMw[i](&rdDto, data, tx); err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "MW_PRE_FAILED", // TODO: add to lang json + Detail: fmt.Sprintf("Pre-middleware %s failed", mwName), + Raw: err, + } + return pl.SetLogError(event, data) + } + + pl.SetLogInfo(&event, nil, "complete") + } + + pl.SetLogInfo(&event, data, "started", "DBDelete") + if err := DeleteData(data, tx); 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") + + for i := range deletePostMw { + mwName := fmt.Sprintf("deletePostMw[%d]", i) + + pl.SetLogInfo(&event, data, "started", mwName) + + if err := deletePostMw[i](&rdDto, data, tx); err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "MW_POST_FAILED", // TODO: add to lang json + Detail: fmt.Sprintf("Post-middleware %s failed", mwName), + Raw: err, + } + return pl.SetLogError(event, data) + } + + pl.SetLogInfo(&event, nil, "complete") + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "single-data", + "status": "deleted", + }, + Data: data.ToResponse(), + }, nil + +} diff --git a/internal/use-case/main-use-case/division-position/helper.go b/internal/use-case/main-use-case/division-position/helper.go new file mode 100644 index 00000000..f353a9ea --- /dev/null +++ b/internal/use-case/main-use-case/division-position/helper.go @@ -0,0 +1,23 @@ +/* +DESCRIPTION: +Any functions that are used internally by the use-case +*/ +package divisionposition + +import ( + e "simrs-vx/internal/domain/main-entities/division-position" +) + +func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.DivisionPosition) { + var inputSrc *e.CreateDto + if inputT, ok := any(input).(*e.CreateDto); ok { + inputSrc = inputT + } else { + inputTemp := any(input).(*e.UpdateDto) + inputSrc = &inputTemp.CreateDto + } + + data.Division_Id = inputSrc.Division_Id + data.Code = inputSrc.Code + data.Name = inputSrc.Name +} diff --git a/internal/use-case/main-use-case/division-position/lib.go b/internal/use-case/main-use-case/division-position/lib.go new file mode 100644 index 00000000..60648199 --- /dev/null +++ b/internal/use-case/main-use-case/division-position/lib.go @@ -0,0 +1,98 @@ +package divisionposition + +import ( + e "simrs-vx/internal/domain/main-entities/division-position" + + dg "github.com/karincake/apem/db-gorm-pg" + gh "github.com/karincake/getuk" + "gorm.io/gorm" +) + +func CreateData(input *e.DivisionPosition, dbx ...*gorm.DB) (*e.DivisionPosition, error) { + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Create(&input).Error; err != nil { + return nil, err + } + + return input, nil +} + +func ReadListData(input e.ReadListDto, dbx ...*gorm.DB) ([]e.DivisionPosition, *e.MetaDto, error) { + data := []e.DivisionPosition{} + pagination := gh.Pagination{} + count := int64(0) + meta := e.MetaDto{} + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + tx = tx. + Model(&e.DivisionPosition{}). + // Joins("Patient"). // if needed + // Preload("Patient"). // if needed + Scopes(gh.Filter(input)). + 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 + } + return nil, nil, err + + } + meta.Count = int(count) + meta.PageNumber = pagination.PageNumber + meta.PageSize = pagination.PageSize + return data, &meta, nil +} + +func ReadDetailData(input e.ReadDetailDto, dbx ...*gorm.DB) (*e.DivisionPosition, error) { + data := e.DivisionPosition{} + + 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 { + return nil, err + } + + return &data, nil +} + +func UpdateData(input e.DivisionPosition, dbx ...*gorm.DB) error { + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + return tx.Save(&input).Error +} + +func DeleteData(input *e.DivisionPosition, dbx ...*gorm.DB) error { + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + return tx.Delete(input).Error +} diff --git a/internal/use-case/main-use-case/division-position/tycovar.go b/internal/use-case/main-use-case/division-position/tycovar.go new file mode 100644 index 00000000..0684de01 --- /dev/null +++ b/internal/use-case/main-use-case/division-position/tycovar.go @@ -0,0 +1,32 @@ +/* +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 divisionposition + +import ( + "gorm.io/gorm" + + e "simrs-vx/internal/domain/main-entities/division-position" +) + +type createMw func(input *e.CreateDto, data *e.DivisionPosition, tx *gorm.DB) error +type readListMw func(input *e.ReadListDto, data *e.DivisionPosition, tx *gorm.DB) error +type readDetailMw func(input *e.ReadDetailDto, data *e.DivisionPosition, tx *gorm.DB) error +type updateMw func(input *e.ReadDetailDto, data *e.DivisionPosition, tx *gorm.DB) error +type deleteMw func(input *e.ReadDetailDto, data *e.DivisionPosition, tx *gorm.DB) error + +var createPreMw []createMw // preprocess middleware +var createPostMw []createMw // postprocess middleware +var readListPreMw []readListMw // .. +var readListPostMw []readListMw // .. +var readDetailPreMw []readDetailMw +var readDetailPostMw []readDetailMw +var updatePreMw []readDetailMw +var updatePostMw []readDetailMw +var deletePreMw []readDetailMw +var deletePostMw []readDetailMw diff --git a/internal/use-case/main-use-case/division/case.go b/internal/use-case/main-use-case/division/case.go new file mode 100644 index 00000000..9b0aa8b5 --- /dev/null +++ b/internal/use-case/main-use-case/division/case.go @@ -0,0 +1,452 @@ +package division + +import ( + "fmt" + e "simrs-vx/internal/domain/main-entities/division" + "strconv" + + dg "github.com/karincake/apem/db-gorm-pg" + d "github.com/karincake/dodol" + + pl "simrs-vx/pkg/logger" + + "gorm.io/gorm" +) + +const source = "division" + +func Create(input e.CreateDto) (*d.Data, error) { + data := e.Division{} + + setData(&input, &data) + + event := pl.Event{ + Feature: "Create", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "create") + + err := dg.I.Transaction(func(tx *gorm.DB) error { + for i := range createPreMw { + mwName := fmt.Sprintf("createPreMw[%d]", i) + + pl.SetLogInfo(&event, data, "started", mwName) + + if err := createPreMw[i](&input, &data, tx); err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "MW_PRE_FAILED", // TODO: add to lang json + Detail: fmt.Sprintf("Pre-middleware %s failed", mwName), + Raw: err, + } + return pl.SetLogError(event, data) + } + + pl.SetLogInfo(&event, nil, "complete") + } + + pl.SetLogInfo(&event, data, "started", "DBCreate") + _, err := CreateData(&data, tx) + if err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-create-fail", + Detail: "Database insert failed", + Raw: err, + } + return pl.SetLogError(event, data) + } + + pl.SetLogInfo(&event, nil, "complete") + + for i := range createPostMw { + mwName := fmt.Sprintf("createPostMw[%d]", i) + + pl.SetLogInfo(&event, input, "started", mwName) + if err := createPostMw[i](&input, &data, tx); err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "MW_POST_FAILED", // TODO: add to lang json + Detail: fmt.Sprintf("Post-middleware %s failed", mwName), + Raw: err, + } + return pl.SetLogError(event, data) + } + } + + 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.Division + var dataList []e.Division + 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 { + for i := range readListPreMw { + mwName := fmt.Sprintf("readListPreMw[%d]", i) + + pl.SetLogInfo(&event, input, "started", mwName) + + if err := readListPreMw[i](&input, data, tx); err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "MW_PRE_FAILED", // TODO: add to lang json + Detail: fmt.Sprintf("Pre-middleware %s failed", mwName), + Raw: err, + } + return pl.SetLogError(event, input) + } + + pl.SetLogInfo(&event, nil, "complete") + } + + pl.SetLogInfo(&event, input, "started", "DBReadList") + dataList, metaList, err = ReadListData(input, tx) + if err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-read-list-fail", + Detail: "Database read list failed", + Raw: err, + } + return pl.SetLogError(event, input) + } + + pl.SetLogInfo(&event, nil, "complete") + + for i := range readListPostMw { + mwName := fmt.Sprintf("readListPostMw[%d]", i) + + pl.SetLogInfo(&event, input, "started", mwName) + + if err := readListPostMw[i](&input, data, tx); err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "MW_POST_FAILED", // TODO: add to lang json + Detail: fmt.Sprintf("Post-middleware %s failed", mwName), + Raw: err, + } + return pl.SetLogError(event, input) + } + + pl.SetLogInfo(&event, nil, "complete") + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "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.Division + 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 { + for i := range readDetailPreMw { + mwName := fmt.Sprintf("readDetailPreMw[%d]", i) + + pl.SetLogInfo(&event, input, "started", mwName) + + if err := readDetailPreMw[i](&input, data, tx); err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "MW_PRE_FAILED", // TODO: add to lang json + Detail: fmt.Sprintf("Pre-middleware %s failed", mwName), + Raw: err, + } + return pl.SetLogError(event, input) + } + + pl.SetLogInfo(&event, nil, "complete") + } + + pl.SetLogInfo(&event, input, "started", "DBReadDetail") + data, err = ReadDetailData(input, tx) + if err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-read-detail-fail", + Detail: "Database read detail failed", + Raw: err, + } + return pl.SetLogError(event, input) + } + + pl.SetLogInfo(&event, nil, "complete") + + for i := range readDetailPostMw { + mwName := fmt.Sprintf("readDetailPostMw[%d]", i) + + pl.SetLogInfo(&event, data, "started", mwName) + + if err := readDetailPostMw[i](&input, data, tx); err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "MW_POST_FAILED", // TODO: add to lang json + Detail: fmt.Sprintf("Post-middleware %s failed", mwName), + Raw: err, + } + return pl.SetLogError(event, data) + } + + pl.SetLogInfo(&event, nil, "complete") + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "single-data", + "status": "fetched", + }, + Data: data.ToResponse(), + }, nil +} + +func Update(input e.UpdateDto) (*d.Data, error) { + rdDto := e.ReadDetailDto{Id: input.Id} + var data *e.Division + 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") + data, err = ReadDetailData(rdDto, tx) + if err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-read-detail-fail", + Detail: "Database read detail failed", + Raw: err, + } + return pl.SetLogError(event, rdDto) + } + + pl.SetLogInfo(&event, input, "started", "setUpdate") + setData(&input, data) + + for i := range updatePreMw { + mwName := fmt.Sprintf("updatePreMw[%d]", i) + + pl.SetLogInfo(&event, data, "started", mwName) + + if err := updatePreMw[i](&rdDto, data, tx); err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "MW_PRE_FAILED", // TODO: add to lang json + Detail: fmt.Sprintf("Pre-middleware %s failed", mwName), + Raw: err, + } + return pl.SetLogError(event, data) + } + + pl.SetLogInfo(&event, nil, "complete") + } + + pl.SetLogInfo(&event, data, "started", "DBUpdate") + if err := UpdateData(*data, tx); err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-update-fail", + Detail: "Database update failed", + Raw: err, + } + return pl.SetLogError(event, data) + } + + pl.SetLogInfo(&event, nil, "complete") + + for i := range updatePostMw { + mwName := fmt.Sprintf("updatePostMw[%d]", i) + + pl.SetLogInfo(&event, data, "started", mwName) + + if err := updatePostMw[i](&rdDto, data, tx); err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "MW_POST_FAILED", // TODO: add to lang json + Detail: fmt.Sprintf("Post-middleware %s failed", mwName), + Raw: err, + } + return pl.SetLogError(event, data) + } + + pl.SetLogInfo(&event, nil, "complete") + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "single-data", + "status": "updated", + }, + Data: data.ToResponse(), + }, nil + +} + +func Delete(input e.DeleteDto) (*d.Data, error) { + rdDto := e.ReadDetailDto{Id: input.Id} + var data *e.Division + 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") + data, err = ReadDetailData(rdDto, tx) + if err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "data-read-detail-fail", + Detail: "Database read detail failed", + Raw: err, + } + return pl.SetLogError(event, rdDto) + } + + pl.SetLogInfo(&event, nil, "complete") + + for i := range deletePreMw { + mwName := fmt.Sprintf("deletePreMw[%d]", i) + + pl.SetLogInfo(&event, data, "started", mwName) + + if err := deletePreMw[i](&rdDto, data, tx); err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "MW_PRE_FAILED", // TODO: add to lang json + Detail: fmt.Sprintf("Pre-middleware %s failed", mwName), + Raw: err, + } + return pl.SetLogError(event, data) + } + + pl.SetLogInfo(&event, nil, "complete") + } + + pl.SetLogInfo(&event, data, "started", "DBDelete") + if err := DeleteData(data, tx); 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") + + for i := range deletePostMw { + mwName := fmt.Sprintf("deletePostMw[%d]", i) + + pl.SetLogInfo(&event, data, "started", mwName) + + if err := deletePostMw[i](&rdDto, data, tx); err != nil { + event.Status = "failed" + event.ErrInfo = pl.ErrorInfo{ + Code: "MW_POST_FAILED", // TODO: add to lang json + Detail: fmt.Sprintf("Post-middleware %s failed", mwName), + Raw: err, + } + return pl.SetLogError(event, data) + } + + pl.SetLogInfo(&event, nil, "complete") + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "single-data", + "status": "deleted", + }, + Data: data.ToResponse(), + }, nil + +} diff --git a/internal/use-case/main-use-case/division/helper.go b/internal/use-case/main-use-case/division/helper.go new file mode 100644 index 00000000..c0341ee0 --- /dev/null +++ b/internal/use-case/main-use-case/division/helper.go @@ -0,0 +1,23 @@ +/* +DESCRIPTION: +Any functions that are used internally by the use-case +*/ +package division + +import ( + e "simrs-vx/internal/domain/main-entities/division" +) + +func setData[T *e.CreateDto | *e.UpdateDto](input T, data *e.Division) { + 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.Parent_Id = inputSrc.Parent_Id +} diff --git a/internal/use-case/main-use-case/division/lib.go b/internal/use-case/main-use-case/division/lib.go new file mode 100644 index 00000000..1b13bcf5 --- /dev/null +++ b/internal/use-case/main-use-case/division/lib.go @@ -0,0 +1,98 @@ +package division + +import ( + e "simrs-vx/internal/domain/main-entities/division" + + dg "github.com/karincake/apem/db-gorm-pg" + gh "github.com/karincake/getuk" + "gorm.io/gorm" +) + +func CreateData(input *e.Division, dbx ...*gorm.DB) (*e.Division, error) { + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + if err := tx.Create(&input).Error; err != nil { + return nil, err + } + + return input, nil +} + +func ReadListData(input e.ReadListDto, dbx ...*gorm.DB) ([]e.Division, *e.MetaDto, error) { + data := []e.Division{} + pagination := gh.Pagination{} + count := int64(0) + meta := e.MetaDto{} + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + tx = tx. + Model(&e.Division{}). + // Joins("Patient"). // if needed + // Preload("Patient"). // if needed + Scopes(gh.Filter(input)). + 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 + } + return nil, nil, err + + } + meta.Count = int(count) + meta.PageNumber = pagination.PageNumber + meta.PageSize = pagination.PageSize + return data, &meta, nil +} + +func ReadDetailData(input e.ReadDetailDto, dbx ...*gorm.DB) (*e.Division, error) { + data := e.Division{} + + 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 { + return nil, err + } + + return &data, nil +} + +func UpdateData(input e.Division, dbx ...*gorm.DB) error { + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + return tx.Save(&input).Error +} + +func DeleteData(input *e.Division, dbx ...*gorm.DB) error { + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + return tx.Delete(input).Error +} diff --git a/internal/use-case/main-use-case/division/tycovar.go b/internal/use-case/main-use-case/division/tycovar.go new file mode 100644 index 00000000..ba4154f2 --- /dev/null +++ b/internal/use-case/main-use-case/division/tycovar.go @@ -0,0 +1,32 @@ +/* +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 division + +import ( + "gorm.io/gorm" + + e "simrs-vx/internal/domain/main-entities/division" +) + +type createMw func(input *e.CreateDto, data *e.Division, tx *gorm.DB) error +type readListMw func(input *e.ReadListDto, data *e.Division, tx *gorm.DB) error +type readDetailMw func(input *e.ReadDetailDto, data *e.Division, tx *gorm.DB) error +type updateMw func(input *e.ReadDetailDto, data *e.Division, tx *gorm.DB) error +type deleteMw func(input *e.ReadDetailDto, data *e.Division, tx *gorm.DB) error + +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