From 810b1eec671a8007b1d3573d4c4176cd84210cce Mon Sep 17 00:00:00 2001 From: shani Date: Sun, 19 May 2024 00:17:08 +0700 Subject: [PATCH] feat: get patients --- main.go | 1 + model/dto/request.go | 9 ++++ model/dto/response.go | 17 ++++++-- src/handler/handler.go | 5 +-- src/handler/patient_handler.go | 64 +++++++++++++++++++++++++++- src/repository/patient_repository.go | 57 +++++++++++++++++++++++++ src/repository/repository.go | 1 + src/usecase/patient_usecase.go | 21 ++++++++- src/usecase/usecase.go | 1 + 9 files changed, 165 insertions(+), 11 deletions(-) diff --git a/main.go b/main.go index d8f18a1..7c78bbd 100644 --- a/main.go +++ b/main.go @@ -107,6 +107,7 @@ func main() { authorized.POST("/v1/medical/patient", patientHandler.CreatePatient) + authorized.GET("/v1/medical/patient", patientHandler.GetPatients) r.Run() } diff --git a/model/dto/request.go b/model/dto/request.go index d50b340..65e926a 100644 --- a/model/dto/request.go +++ b/model/dto/request.go @@ -43,3 +43,12 @@ type RequestCreatePatient struct { Gender string `json:"gender"` IdentityCardScanImg string `json:"identityCardScanImg"` } + +type RequestGetPatients struct { + IdentityNumber *int + Limit int + Offset int + Name *string + PhoneNumber *int + CreatedAt string +} \ No newline at end of file diff --git a/model/dto/response.go b/model/dto/response.go index 16632b3..82272b8 100644 --- a/model/dto/response.go +++ b/model/dto/response.go @@ -6,8 +6,17 @@ type ResponseStatusAndMessage struct { } type UserDTO struct { - UserId string `json:"userId"` - NIP int64 `json:"nip"` - Name string `json:"name"` - CreatedAt string `json:"createdAt"` + UserId string `json:"userId"` + NIP int64 `json:"nip"` + Name string `json:"name"` + CreatedAt string `json:"createdAt"` +} + +type PatientDTO struct { + IdentityNumber int `json:"identityNumber"` + PhoneNumber string `json:"phoneNumber"` + Name string `json:"name"` + BirthDate string `json:"birthDate"` + Gender string `json:"gender"` + CreatedAt string `json:"createdAt"` } \ No newline at end of file diff --git a/src/handler/handler.go b/src/handler/handler.go index e1c5506..926258f 100644 --- a/src/handler/handler.go +++ b/src/handler/handler.go @@ -16,12 +16,9 @@ type NurseHandlerInterface interface { DeleteNurse(c *gin.Context) GetUsers(c *gin.Context) AddAccess(c *gin.Context) - // UpdateNurse(c *gin.Context) - // DeleteNurse(c *gin.Context) - // GetNurses(c *gin.Context) } type PatientHandlerInterface interface { CreatePatient(c *gin.Context) -// GetPatient(c *gin.Context) + GetPatients(c *gin.Context) } \ No newline at end of file diff --git a/src/handler/patient_handler.go b/src/handler/patient_handler.go index b0b9216..e654db2 100644 --- a/src/handler/patient_handler.go +++ b/src/handler/patient_handler.go @@ -5,7 +5,9 @@ import ( "health-record/model/dto" "health-record/src/usecase" "log" + "net/http" "net/url" + "strconv" "strings" "github.com/gin-gonic/gin" @@ -38,7 +40,7 @@ func (h *PatientHandler) CreatePatient(c *gin.Context) { } //error 409 - exist, err := h.iPatientUsecase.GetPatientByIdentityNumber(request.IdentityNumber) + exist, _ := h.iPatientUsecase.GetPatientByIdentityNumber(request.IdentityNumber) if(exist) { log.Println("Register patient bad request >> GetPatientByIdentityNumber") c.JSON(409, gin.H{"status": "bad request", "message": "IdentityNumber already registered"}) @@ -61,6 +63,66 @@ func (h *PatientHandler) CreatePatient(c *gin.Context) { }) } +func (h *PatientHandler) GetPatients(c *gin.Context) { + query := c.Request.URL.Query() + params := parseQueryParams(query) + + patients, err := h.iPatientUsecase.GetPatients(params) + + + if err != nil { + log.Println("get patients server error ", err) + c.JSON(500, gin.H{"status": "internal server error", "message": err}) + return + } + + if len(patients) < 1 {patients = []dto.PatientDTO{}} + c.JSON(http.StatusOK, gin.H{"message": "success", "data": patients}) + +} + + +func parseQueryParams(query url.Values) dto.RequestGetPatients { + params := dto.RequestGetPatients{ + Limit: 5, + Offset: 0, + } + + if identityNumber := query.Get("identityNumber"); identityNumber != "" { + if id, err := strconv.Atoi(identityNumber); err == nil { + params.IdentityNumber = &id + } + } + + if limit := query.Get("limit"); limit != "" { + if l, err := strconv.Atoi(limit); err == nil { + params.Limit = l + } + } + + if offset := query.Get("offset"); offset != "" { + if o, err := strconv.Atoi(offset); err == nil { + params.Offset = o + } + } + + if name := query.Get("name"); name != "" { + params.Name = &name + } + + if phoneNumber := query.Get("phoneNumber"); phoneNumber != "" { + if phoneNumber, err := strconv.Atoi(phoneNumber); err == nil { + params.PhoneNumber = &phoneNumber + } + } + + if createdAt := query.Get("createdAt"); createdAt == "asc" || createdAt == "desc" { + params.CreatedAt = createdAt + } + + return params +} + func ValidateRegisterPatientRequest(request dto.RequestCreatePatient) error { if !is16DigitInteger(request.IdentityNumber) { return errors.New("invalid IdentityNumber") diff --git a/src/repository/patient_repository.go b/src/repository/patient_repository.go index b4f71fd..7720ccd 100644 --- a/src/repository/patient_repository.go +++ b/src/repository/patient_repository.go @@ -3,8 +3,10 @@ package repository import ( "context" "database/sql" + "fmt" "health-record/model/database" "health-record/model/dto" + "strconv" "time" ) @@ -51,3 +53,58 @@ func (r *PatientRepository) GetPatientByIdentityNumber(ctx context.Context, iden } return response, nil } + +func (ur *PatientRepository) GetPatients(ctx context.Context, param dto.RequestGetPatients) ([]dto.PatientDTO, error) { + query := "SELECT identity_number, name, phone_number, birth_date, gender, created_at FROM patients WHERE 1=1" + + var args []interface{} + + if param.IdentityNumber != nil { + query += " AND identity_number = $" + strconv.Itoa(len(args)+1) + args = append(args, strconv.Itoa(*param.IdentityNumber)) + } + + if param.Name != nil { + query += " AND LOWER(name) LIKE LOWER($" + strconv.Itoa(len(args)+1) + ")" + args = append(args, "%"+*param.Name+"%") + } + + if param.PhoneNumber != nil { + query += " AND phone_number LIKE $" + strconv.Itoa(len(args)+1) + args = append(args, "%"+strconv.Itoa(*param.PhoneNumber)+"%") + } + + if param.CreatedAt == "asc" || param.CreatedAt == "desc" { + query += fmt.Sprintf(" ORDER BY created_at %s", param.CreatedAt) + } + + query += fmt.Sprintf(" LIMIT %d OFFSET %d", param.Limit, param.Offset) + + rows, err := ur.db.QueryContext(ctx, query, args...) + if err != nil { + return nil, err + } + defer rows.Close() + + var patients []dto.PatientDTO + for rows.Next() { + var ptn dto.PatientDTO + if err := rows.Scan( + &ptn.IdentityNumber, + &ptn.Name, + &ptn.PhoneNumber, + &ptn.BirthDate, + &ptn.Gender, + &ptn.CreatedAt); err != nil { + return nil, err + } + + patients = append(patients, ptn) + } + + if err := rows.Err(); err != nil { + return nil, err + } + + return patients, nil +} \ No newline at end of file diff --git a/src/repository/repository.go b/src/repository/repository.go index 2c1955e..dcf3e9c 100644 --- a/src/repository/repository.go +++ b/src/repository/repository.go @@ -24,4 +24,5 @@ type NurseRepositoryInterface interface { type PatientRepositoryInterface interface { CreatePatient(ctx context.Context, request dto.RequestCreatePatient) (err error) GetPatientByIdentityNumber(ctx context.Context, identityNumber int) (database.Patient, error) + GetPatients(ctx context.Context, params dto.RequestGetPatients) ([]dto.PatientDTO, error) } diff --git a/src/usecase/patient_usecase.go b/src/usecase/patient_usecase.go index 384df27..4dc933b 100644 --- a/src/usecase/patient_usecase.go +++ b/src/usecase/patient_usecase.go @@ -7,7 +7,7 @@ import ( ) type PatientUsecase struct { - iPatientRepository repository.PatientRepositoryInterface + iPatientRepository repository.PatientRepositoryInterface } func NewPatientUsecase( @@ -28,4 +28,21 @@ func (u *PatientUsecase) GetPatientByIdentityNumber(identityNumber int) (bool, e return false, err } return true, nil -} \ No newline at end of file +} + +func (uc *PatientUsecase) GetPatients(request dto.RequestGetPatients) ([]dto.PatientDTO, error) { + params := dto.RequestGetPatients{ + Limit: request.Limit, + Offset: request.Offset, + IdentityNumber: request.IdentityNumber, + Name: request.Name, + PhoneNumber: request.PhoneNumber, + CreatedAt: request.CreatedAt, + } + + response, err := uc.iPatientRepository.GetPatients(context.TODO(), params) + + + return response, err +} + diff --git a/src/usecase/usecase.go b/src/usecase/usecase.go index 9445d82..8fdc8f2 100644 --- a/src/usecase/usecase.go +++ b/src/usecase/usecase.go @@ -25,5 +25,6 @@ type NurseUsecaseInterface interface { type PatientUsecaseInterface interface { RegisterPatient(dto.RequestCreatePatient) (error) GetPatientByIdentityNumber(identityNumber int) (bool, error) + GetPatients(request dto.RequestGetPatients) ([]dto.PatientDTO, error) }