feat (patient): add search by identifier and nik only

This commit is contained in:
dpurbosakti
2025-10-17 13:04:43 +07:00
parent 1b6b5a73b4
commit 319da694af
5 changed files with 54 additions and 17 deletions
+2 -1
View File
@@ -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 {
@@ -0,0 +1,8 @@
package patient
type SearchMode string
const (
SMNik SearchMode = "resident-identity"
SMIdent SearchMode = "identifier"
)
@@ -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 ********************/
@@ -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)
}
+21 -9
View File
@@ -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 {