diff --git a/internal/domain/main-entities/patient/dto.go b/internal/domain/main-entities/patient/dto.go index 1374eb97..00134b6e 100644 --- a/internal/domain/main-entities/patient/dto.go +++ b/internal/domain/main-entities/patient/dto.go @@ -57,7 +57,8 @@ type DeleteDto struct { } type SearchDto struct { - Search string `json:"search"` + Search string `json:"search"` + Mode SearchMode `json:"mode"` } type UploadDto struct { diff --git a/internal/domain/main-entities/patient/tycovar.go b/internal/domain/main-entities/patient/tycovar.go new file mode 100644 index 00000000..aa419b57 --- /dev/null +++ b/internal/domain/main-entities/patient/tycovar.go @@ -0,0 +1,8 @@ +package patient + +type SearchMode string + +const ( + SMNik SearchMode = "resident-identity" + SMIdent SearchMode = "identifier" +) diff --git a/internal/interface/main-handler/main-handler.go b/internal/interface/main-handler/main-handler.go index 3a7f0374..bc4b0fa0 100644 --- a/internal/interface/main-handler/main-handler.go +++ b/internal/interface/main-handler/main-handler.go @@ -260,13 +260,14 @@ func SetRoutes() http.Handler { "PATCH /{id}/active": user.O.Active, }) hk.GroupRoutes("/v1/patient", r, hk.MapHandlerFunc{ - "GET /": patient.O.GetList, - "GET /{id}": patient.O.GetDetail, - "POST /": patient.O.Create, - "PATCH /{id}": patient.O.Update, - "DELETE /{id}": patient.O.Delete, - "GET /by-identifier": patient.O.Search, - "POST /{id}/upload": patient.O.Upload, + "GET /": patient.O.GetList, + "GET /{id}": patient.O.GetDetail, + "POST /": patient.O.Create, + "PATCH /{id}": patient.O.Update, + "DELETE /{id}": patient.O.Delete, + "GET /search/{keyword}": patient.O.Search, + "GET /by-resident-identity": patient.O.SearchByResidentIdentity, + "POST /{id}/upload": patient.O.Upload, }) /******************** sources ********************/ diff --git a/internal/interface/main-handler/patient/handler.go b/internal/interface/main-handler/patient/handler.go index 1bcdacee..2c5fcb5b 100644 --- a/internal/interface/main-handler/patient/handler.go +++ b/internal/interface/main-handler/patient/handler.go @@ -12,6 +12,8 @@ import ( u "simrs-vx/internal/use-case/main-use-case/patient" ere "simrs-vx/internal/domain/references/encounter" + + d "github.com/karincake/dodol" ) type myBase struct{} @@ -73,8 +75,21 @@ func (obj myBase) Delete(w http.ResponseWriter, r *http.Request) { } func (obj myBase) Search(w http.ResponseWriter, r *http.Request) { + dto := e.SearchDto{} + keyword := rw.ValidateString(w, "keyword", r.PathValue("keyword")) + if keyword == "" { + rw.WriteJSON(w, http.StatusUnauthorized, d.IS{"message": "keyword is required"}, nil) + } + dto.Mode = e.SMIdent + dto.Search = keyword + res, err := u.Search(dto) + rw.DataResponse(w, res, err) +} + +func (obj myBase) SearchByResidentIdentity(w http.ResponseWriter, r *http.Request) { dto := e.SearchDto{} sf.UrlQueryParam(&dto, *r.URL) + dto.Mode = e.SMNik res, err := u.Search(dto) rw.DataResponse(w, res, err) } diff --git a/internal/use-case/main-use-case/patient/lib.go b/internal/use-case/main-use-case/patient/lib.go index e126ec0d..f35e3853 100644 --- a/internal/use-case/main-use-case/patient/lib.go +++ b/internal/use-case/main-use-case/patient/lib.go @@ -91,7 +91,8 @@ func ReadDetailData(input e.ReadDetailDto, event *pl.Event, dbx ...*gorm.DB) (*e Preload("Person.Contacts"). Preload("Person.Relatives.Village.District.Regency.Province"). Preload("Person.Addresses.Village.District.Regency.Province"). - Preload("Person.Addresses.PostalRegion.Village.District.Regency.Province") + Preload("Person.Addresses.PostalRegion.Village.District.Regency.Province"). + Preload("Person.Insurances.InsuranceCompany") if err := tx.First(&data, input.Id).Error; err != nil { if processedErr := pu.HandleReadError(err, event, source, input.Id, data); processedErr != nil { @@ -157,6 +158,7 @@ func SearchData(input e.SearchDto, event *pl.Event, dbx ...*gorm.DB) (*e.Patient pl.SetLogInfo(event, input, "started", "DBSearch") var patient e.Patient + var err error var tx *gorm.DB if len(dbx) > 0 { @@ -167,15 +169,25 @@ func SearchData(input e.SearchDto, event *pl.Event, dbx ...*gorm.DB) (*e.Patient // Preload associations for complete data tx = tx.Preload(clause.Associations) - tx = tx.Preload("Person.Addresses") - tx = tx.Preload("Person.Contacts") - tx = tx.Preload("Person.Relatives") + 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) - err := tx.Joins("JOIN \"Person\" ON \"Patient\".\"Person_Id\" = \"Person\".\"Id\""). - Where("\"Patient\".\"Number\" = ? OR \"Person\".\"ResidentIdentityNumber\" = ?", - input.Search, input.Search). - First(&patient).Error + switch input.Mode { + case e.SMIdent: + // Search by patient number OR person's resident identity number (exact match) OR person's name (partial match) + err = tx.Joins("JOIN \"Person\" ON \"Patient\".\"Person_Id\" = \"Person\".\"Id\""). + Where("\"Patient\".\"Number\" = ? OR \"Person\".\"ResidentIdentityNumber\" = ? OR \"Person\".\"Name\" ILIKE ?", + input.Search, input.Search, "%"+input.Search+"%"). + First(&patient).Error + case e.SMNik: + // Search by patient person's resident identity number (exact match) + err = tx.Joins("JOIN \"Person\" ON \"Patient\".\"Person_Id\" = \"Person\".\"Id\""). + Where("\"Person\".\"ResidentIdentityNumber\" = ?", + input.Search). + First(&patient).Error + } if err != nil { if processedErr := pu.HandleSearchError(err, event, source, input.Search, patient); processedErr != nil {