diff --git a/internal/domain/main-entities/patient/dto.go b/internal/domain/main-entities/patient/dto.go index 00134b6e..4927a50e 100644 --- a/internal/domain/main-entities/patient/dto.go +++ b/internal/domain/main-entities/patient/dto.go @@ -57,8 +57,8 @@ type DeleteDto struct { } type SearchDto struct { - Search string `json:"search"` - Mode SearchMode `json:"mode"` + Search string `json:"search"` + Pagination ecore.Pagination } type UploadDto struct { diff --git a/internal/interface/main-handler/main-handler.go b/internal/interface/main-handler/main-handler.go index 690a830a..6a98487f 100644 --- a/internal/interface/main-handler/main-handler.go +++ b/internal/interface/main-handler/main-handler.go @@ -274,7 +274,7 @@ func SetRoutes() http.Handler { "PATCH /{id}": patient.O.Update, "DELETE /{id}": patient.O.Delete, "GET /search/{keyword}": patient.O.Search, - "GET /by-resident-identity": patient.O.SearchByResidentIdentity, + "GET /by-resident-identity": patient.O.SearchByResidentIdentityNumber, "POST /{id}/upload": patient.O.Upload, }) diff --git a/internal/interface/main-handler/patient/handler.go b/internal/interface/main-handler/patient/handler.go index 2c5fcb5b..1d02d8d7 100644 --- a/internal/interface/main-handler/patient/handler.go +++ b/internal/interface/main-handler/patient/handler.go @@ -76,21 +76,22 @@ func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) { func (obj myBase) Search(w http.ResponseWriter, r *http.Request) { dto := e.SearchDto{} + + sf.UrlQueryParam(&dto, *r.URL) keyword := rw.ValidateString(w, "keyword", r.PathValue("keyword")) if keyword == "" { rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "keyword is required"}, nil) } - dto.Mode = e.SMIdent + dto.Search = keyword res, err := u.Search(dto) rw.DataResponse(w, res, err) } -func (obj myBase) SearchByResidentIdentity(w http.ResponseWriter, r *http.Request) { +func (obj myBase) SearchByResidentIdentityNumber(w http.ResponseWriter, r *http.Request) { dto := e.SearchDto{} sf.UrlQueryParam(&dto, *r.URL) - dto.Mode = e.SMNik - res, err := u.Search(dto) + res, err := u.SearchByResidentIdentityNumber(dto) rw.DataResponse(w, res, err) } diff --git a/internal/use-case/main-use-case/patient/case.go b/internal/use-case/main-use-case/patient/case.go index fd17d7fb..b52215ac 100644 --- a/internal/use-case/main-use-case/patient/case.go +++ b/internal/use-case/main-use-case/patient/case.go @@ -352,18 +352,18 @@ func Delete(input e.DeleteDto) (*d.Data, error) { } -func Search(input e.SearchDto) (*d.Data, error) { +func SearchByResidentIdentityNumber(input e.SearchDto) (*d.Data, error) { var data *e.Patient var err error event := pl.Event{ - Feature: "Search", + Feature: "Search By Resident Identity Number", Source: source, } // Start log pl.SetLogInfo(&event, input, "started", "search") - if data, err = SearchData(input, &event); err != nil { + if data, err = SearchDataByRIN(input, &event); err != nil { return nil, err } @@ -377,6 +377,46 @@ func Search(input e.SearchDto) (*d.Data, error) { }, nil } +func Search(input e.SearchDto) (*d.Data, error) { + var dataList []e.Patient + var metaList *e.MetaDto + var err error + + event := pl.Event{ + Feature: "Search", + Source: source, + } + + // Start log + pl.SetLogInfo(&event, input, "started", "readList") + + err = dg.I.Transaction(func(tx *gorm.DB) error { + + if dataList, metaList, err = SearchData(input, &event, tx); err != nil { + return err + } + + return nil + }) + + if err != nil { + return nil, err + } + + return &d.Data{ + Meta: d.IS{ + "source": source, + "structure": "list-data", + "status": "fetched", + "page_number": strconv.Itoa(metaList.PageNumber), + "page_size": strconv.Itoa(metaList.PageSize), + "record_totalCount": strconv.Itoa(metaList.Count), + "record_currentCount": strconv.Itoa(len(dataList)), + }, + Data: e.ToResponseList(dataList), + }, nil +} + func Upload(input e.UploadDto) (*d.Data, error) { rdDto := e.ReadDetailDto{Id: uint16(input.Id)} var data *e.Patient diff --git a/internal/use-case/main-use-case/patient/lib.go b/internal/use-case/main-use-case/patient/lib.go index f35e3853..36c9d416 100644 --- a/internal/use-case/main-use-case/patient/lib.go +++ b/internal/use-case/main-use-case/patient/lib.go @@ -154,11 +154,11 @@ func DeleteData(data *e.Patient, event *pl.Event, dbx ...*gorm.DB) error { return nil } -func SearchData(input e.SearchDto, event *pl.Event, dbx ...*gorm.DB) (*e.Patient, error) { +// Search By Resident Identity Number +func SearchDataByRIN(input e.SearchDto, event *pl.Event, dbx ...*gorm.DB) (*e.Patient, error) { pl.SetLogInfo(event, input, "started", "DBSearch") - var patient e.Patient - var err error + var data e.Patient var tx *gorm.DB if len(dbx) > 0 { @@ -174,27 +174,60 @@ func SearchData(input e.SearchDto, event *pl.Event, dbx ...*gorm.DB) (*e.Patient Preload("Person.Relatives"). Preload("Person.Insurances") - switch input.Mode { - case e.SMIdent: - // Search by patient number OR person's resident identity number (exact match) OR person's name (partial match) - err = tx.Joins("JOIN \"Person\" ON \"Patient\".\"Person_Id\" = \"Person\".\"Id\""). - Where("\"Patient\".\"Number\" = ? OR \"Person\".\"ResidentIdentityNumber\" = ? OR \"Person\".\"Name\" ILIKE ?", - input.Search, input.Search, "%"+input.Search+"%"). - First(&patient).Error - case e.SMNik: - // Search by patient person's resident identity number (exact match) - err = tx.Joins("JOIN \"Person\" ON \"Patient\".\"Person_Id\" = \"Person\".\"Id\""). - Where("\"Person\".\"ResidentIdentityNumber\" = ?", - input.Search). - First(&patient).Error - } + // Search by patient person's resident identity number (exact match) + err := tx.Joins("JOIN \"Person\" ON \"Patient\".\"Person_Id\" = \"Person\".\"Id\""). + Where("\"Person\".\"ResidentIdentityNumber\" = ?", + input.Search). + First(&data).Error if err != nil { - if processedErr := pu.HandleSearchError(err, event, source, input.Search, patient); processedErr != nil { + if processedErr := pu.HandleSearchError(err, event, source, input.Search, data); processedErr != nil { return nil, processedErr } } pl.SetLogInfo(event, nil, "complete") - return &patient, nil + return &data, nil +} + +func SearchData(input e.SearchDto, event *pl.Event, dbx ...*gorm.DB) ([]e.Patient, *e.MetaDto, error) { + pl.SetLogInfo(event, input, "started", "DBSearch") + + var data []e.Patient + pagination := gh.Pagination{} + count := int64(0) + meta := e.MetaDto{} + + var tx *gorm.DB + if len(dbx) > 0 { + tx = dbx[0] + } else { + tx = dg.I + } + + // Preload associations for complete data + tx = tx.Preload(clause.Associations) + tx = tx.Preload("Person.Addresses"). + Preload("Person.Contacts"). + Preload("Person.Relatives"). + Preload("Person.Insurances") + + // Search by patient number OR person's resident identity number (exact match) OR person's name (partial match) + tx = tx.Joins("JOIN \"Person\" ON \"Patient\".\"Person_Id\" = \"Person\".\"Id\""). + Where("\"Patient\".\"Number\" ILIKE ? OR \"Person\".\"ResidentIdentityNumber\" ILIKE ? OR \"Person\".\"Name\" ILIKE ?", + "%"+input.Search+"%", "%"+input.Search+"%", "%"+input.Search+"%") + err := tx.Scopes(gh.Paginate(input, &pagination)).Find(&data).Error + + if err != nil { + if processedErr := pu.HandleSearchError(err, event, source, input.Search, data); processedErr != nil { + return nil, nil, processedErr + } + } + + meta.Count = int(count) + meta.PageNumber = pagination.PageNumber + meta.PageSize = pagination.PageSize + + pl.SetLogInfo(event, nil, "complete") + return data, &meta, nil }