feat: add lab package registration endpoint
This commit is contained in:
@@ -19,6 +19,7 @@ type LayananRepository interface {
|
||||
type LabRegistrationRepository interface {
|
||||
RegisterLab(ctx context.Context, params repository.LabRegistrationParams) (repository.LabRegistrationOutcome, error)
|
||||
AddLabServices(ctx context.Context, regID string, params repository.AddLabServicesParams) (repository.LabRegistrationOutcome, error)
|
||||
AddLabPackage(ctx context.Context, regID string, params repository.AddLabPackageParams) (repository.LabRegistrationOutcome, error)
|
||||
}
|
||||
|
||||
type PatientRepository interface {
|
||||
|
||||
84
internal/http/lab_package.go
Normal file
84
internal/http/lab_package.go
Normal file
@@ -0,0 +1,84 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
"primaya-api/cpone-middleware/internal/repository"
|
||||
)
|
||||
|
||||
var labIdentifier = regexp.MustCompile(`^[A-Za-z0-9-]+$`)
|
||||
|
||||
func (h Handler) AddLabPackage(w http.ResponseWriter, r *http.Request) {
|
||||
regID := strings.TrimSpace(r.PathValue("regId"))
|
||||
if regID == "" || utf8.RuneCountInString(regID) > 50 || !labIdentifier.MatchString(regID) {
|
||||
writeLabResponse(w, http.StatusUnprocessableEntity, false, "validation_error", "Nomor registrasi laboratorium hanya boleh berisi huruf, angka, dan tanda hubung", nil)
|
||||
return
|
||||
}
|
||||
payload, _ := decodeJSONObject(r)
|
||||
params, message := validateAddLabPackage(payload)
|
||||
if message != "" {
|
||||
writeLabResponse(w, http.StatusUnprocessableEntity, false, "validation_error", message, nil)
|
||||
return
|
||||
}
|
||||
outcome, err := h.labRepo.AddLabPackage(r.Context(), strings.ToUpper(regID), params)
|
||||
if err != nil {
|
||||
if validationMessage, ok := asValidationError(err); ok {
|
||||
writeLabResponse(w, http.StatusUnprocessableEntity, false, "validation_error", validationMessage, nil)
|
||||
return
|
||||
}
|
||||
writeLabResponse(w, http.StatusInternalServerError, false, "error", err.Error(), nil)
|
||||
return
|
||||
}
|
||||
writeLabResponse(w, outcome.HTTPStatus, outcome.Success, outcome.Status, outcome.Message, outcome.Data)
|
||||
}
|
||||
|
||||
func validateAddLabPackage(payload map[string]any) (repository.AddLabPackageParams, string) {
|
||||
packageID, message := requiredString(payload, "paket_id", 50, "Paket ID wajib diisi")
|
||||
if message != "" {
|
||||
return repository.AddLabPackageParams{}, message
|
||||
}
|
||||
packageID = strings.ToUpper(strings.TrimSpace(packageID))
|
||||
if !labIdentifier.MatchString(packageID) {
|
||||
return repository.AddLabPackageParams{}, "Paket ID hanya boleh berisi huruf, angka, dan tanda hubung"
|
||||
}
|
||||
cito := false
|
||||
if value, present := nullableValue(payload, "cito"); present {
|
||||
var valid bool
|
||||
cito, valid = parseLaravelBoolean(value)
|
||||
if !valid {
|
||||
return repository.AddLabPackageParams{}, "The cito field must be true or false."
|
||||
}
|
||||
}
|
||||
markup := 0.0
|
||||
if value, present := nullableValue(payload, "markup_cito"); present {
|
||||
var valid bool
|
||||
markup, valid = parseNumeric(value)
|
||||
if !valid {
|
||||
return repository.AddLabPackageParams{}, "The markup cito must be a number."
|
||||
}
|
||||
if markup < 0 || markup > 100 {
|
||||
return repository.AddLabPackageParams{}, "The markup cito must be between 0 and 100."
|
||||
}
|
||||
}
|
||||
if !cito {
|
||||
markup = 0
|
||||
}
|
||||
notes, _, message := optionalString(payload, "catatan", 500)
|
||||
if message != "" {
|
||||
return repository.AddLabPackageParams{}, message
|
||||
}
|
||||
channel, present, message := optionalString(payload, "channel", 50)
|
||||
if message != "" {
|
||||
return repository.AddLabPackageParams{}, message
|
||||
}
|
||||
if !present {
|
||||
channel = "CPONE"
|
||||
}
|
||||
return repository.AddLabPackageParams{
|
||||
PackageID: packageID, Cito: cito, MarkupCito: markup,
|
||||
Notes: strings.TrimSpace(notes), Channel: strings.ToUpper(strings.TrimSpace(channel)),
|
||||
}, ""
|
||||
}
|
||||
50
internal/http/lab_package_test.go
Normal file
50
internal/http/lab_package_test.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"primaya-api/cpone-middleware/internal/repository"
|
||||
)
|
||||
|
||||
func TestAddLabPackageValidPayload(t *testing.T) {
|
||||
repo := &fakeLabRegistrationRepository{outcome: repository.LabRegistrationOutcome{
|
||||
HTTPStatus: 201, Success: true, Status: "package_added",
|
||||
Message: "Paket dispenser berhasil ditambahkan ke registrasi laboratorium",
|
||||
}}
|
||||
handler := Handler{labRepo: repo}
|
||||
request := httptest.NewRequest(http.MethodPost, "/packages", strings.NewReader(`{"paket_id":"disp-260800011","cito":true,"markup_cito":"10","catatan":" test ","channel":"cpone"}`))
|
||||
request.SetPathValue("regId", "lab-2608210003")
|
||||
recorder := httptest.NewRecorder()
|
||||
handler.AddLabPackage(recorder, request)
|
||||
if recorder.Code != http.StatusCreated {
|
||||
t.Fatalf("status=%d body=%s", recorder.Code, recorder.Body.String())
|
||||
}
|
||||
if repo.regID != "LAB-2608210003" || repo.packageParams.PackageID != "DISP-260800011" || !repo.packageParams.Cito || repo.packageParams.MarkupCito != 10 || repo.packageParams.Notes != "test" || repo.packageParams.Channel != "CPONE" {
|
||||
t.Fatalf("unexpected repository call: reg=%q params=%+v", repo.regID, repo.packageParams)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAddLabPackageValidation(t *testing.T) {
|
||||
tests := []struct{ name, regID, body, message string }{
|
||||
{"invalid registration", "LAB/1", `{"paket_id":"DISP-1"}`, "Nomor registrasi laboratorium hanya boleh berisi huruf, angka, dan tanda hubung"},
|
||||
{"missing package", "LAB-1", `{}`, "Paket ID wajib diisi"},
|
||||
{"invalid package", "LAB-1", `{"paket_id":"DISP/1"}`, "Paket ID hanya boleh berisi huruf, angka, dan tanda hubung"},
|
||||
{"invalid cito", "LAB-1", `{"paket_id":"DISP-1","cito":"true"}`, "The cito field must be true or false."},
|
||||
{"invalid markup", "LAB-1", `{"paket_id":"DISP-1","markup_cito":101}`, "The markup cito must be between 0 and 100."},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
handler := Handler{labRepo: &fakeLabRegistrationRepository{}}
|
||||
request := httptest.NewRequest(http.MethodPost, "/packages", strings.NewReader(test.body))
|
||||
request.SetPathValue("regId", test.regID)
|
||||
recorder := httptest.NewRecorder()
|
||||
handler.AddLabPackage(recorder, request)
|
||||
if recorder.Code != 422 || !strings.Contains(recorder.Body.String(), test.message) {
|
||||
t.Fatalf("status=%d body=%s", recorder.Code, recorder.Body.String())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -13,11 +13,12 @@ import (
|
||||
)
|
||||
|
||||
type fakeLabRegistrationRepository struct {
|
||||
outcome repository.LabRegistrationOutcome
|
||||
err error
|
||||
params repository.LabRegistrationParams
|
||||
addParams repository.AddLabServicesParams
|
||||
regID string
|
||||
outcome repository.LabRegistrationOutcome
|
||||
err error
|
||||
params repository.LabRegistrationParams
|
||||
addParams repository.AddLabServicesParams
|
||||
packageParams repository.AddLabPackageParams
|
||||
regID string
|
||||
}
|
||||
|
||||
func (f *fakeLabRegistrationRepository) RegisterLab(_ context.Context, params repository.LabRegistrationParams) (repository.LabRegistrationOutcome, error) {
|
||||
@@ -31,6 +32,12 @@ func (f *fakeLabRegistrationRepository) AddLabServices(_ context.Context, regID
|
||||
return f.outcome, f.err
|
||||
}
|
||||
|
||||
func (f *fakeLabRegistrationRepository) AddLabPackage(_ context.Context, regID string, params repository.AddLabPackageParams) (repository.LabRegistrationOutcome, error) {
|
||||
f.regID = regID
|
||||
f.packageParams = params
|
||||
return f.outcome, f.err
|
||||
}
|
||||
|
||||
func TestRegisterLabValidPayloadAndResponseParity(t *testing.T) {
|
||||
doctorID := "DR01"
|
||||
registrationType := int64(3)
|
||||
|
||||
Reference in New Issue
Block a user