Files
cpone_midleware/internal/http/registration.go

205 lines
7.6 KiB
Go

package http
import (
"errors"
"net/http"
"strings"
"time"
"primaya-api/cpone-middleware/internal/repository"
)
func (h Handler) RegisterPatient(w http.ResponseWriter, r *http.Request) {
payload, err := decodeJSONObject(r)
if err != nil {
writeRegistrationResponse(w, http.StatusUnprocessableEntity, false, "validation_error", "Payload harus berupa object JSON", nil)
return
}
params, message := validateRegistration(payload, h.departmentID)
if message != "" {
writeRegistrationResponse(w, http.StatusUnprocessableEntity, false, "validation_error", message, nil)
return
}
outcome, err := h.registrationRepository(r.Context()).RegisterPatient(r.Context(), params)
if err != nil {
var validationErr repository.ValidationError
if errors.As(err, &validationErr) {
writeRegistrationResponse(w, http.StatusUnprocessableEntity, false, "validation_error", validationErr.Message, nil)
return
}
writeRegistrationResponse(w, http.StatusInternalServerError, false, "error", err.Error(), nil)
return
}
writeRegistrationResponse(w, outcome.HTTPStatus, outcome.Success, outcome.Status, outcome.Message, outcome.Data)
}
func validateRegistration(payload map[string]any, configuredDepartment string) (repository.RegistrationParams, string) {
medrecID, _, message := optionalString(payload, "medrec_id", 50)
if message != "" {
return repository.RegistrationParams{}, message
}
nik, _, message := optionalString(payload, "nik", 50)
if message != "" {
return repository.RegistrationParams{}, message
}
birthDateText, birthPresent, message := optionalString(payload, "tgl_lahir", 10)
if message != "" {
return repository.RegistrationParams{}, message
}
if strings.TrimSpace(medrecID) == "" && (!birthPresent || strings.TrimSpace(nik) == "") {
return repository.RegistrationParams{}, "nik dan tgl_lahir wajib diisi jika medrec_id belum tersedia"
}
jakarta, err := time.LoadLocation("Asia/Jakarta")
if err != nil {
return repository.RegistrationParams{}, err.Error()
}
var birthDate time.Time
if birthPresent && strings.TrimSpace(birthDateText) != "" {
birthDate, err = time.ParseInLocation("2006-01-02", birthDateText, jakarta)
if err != nil {
return repository.RegistrationParams{}, "tgl_lahir harus format Y-m-d"
}
}
registrationDateText, present, message := optionalString(payload, "tanggal", 10)
if message != "" {
return repository.RegistrationParams{}, message
}
registrationDate := time.Now().In(jakarta)
if present && strings.TrimSpace(registrationDateText) != "" {
registrationDate, err = time.ParseInLocation("2006-01-02", registrationDateText, jakarta)
if err != nil {
return repository.RegistrationParams{}, "tanggal harus format Y-m-d"
}
}
departmentID, present, message := optionalString(payload, "departemen_id", 50)
if message != "" {
return repository.RegistrationParams{}, message
}
if !present || strings.TrimSpace(departmentID) == "" {
departmentID = configuredDepartment
}
if strings.TrimSpace(departmentID) == "" {
return repository.RegistrationParams{}, "departemen_id wajib diisi atau dikonfigurasi di middleware"
}
doctorID, _, message := optionalString(payload, "dokter_id", 50)
if message != "" {
return repository.RegistrationParams{}, message
}
patientType, message := optionalInteger(payload, "jenis_pasien_id", 0)
if message != "" {
return repository.RegistrationParams{}, message
}
registrationType, message := optionalInteger(payload, "jenis_reg_id", 2)
if message != "" {
return repository.RegistrationParams{}, message
}
tariffPeriod, message := optionalInteger(payload, "periode_tarif_id", 0)
if message != "" {
return repository.RegistrationParams{}, message
}
groupTariff, message := optionalInteger(payload, "group_tarif_id", 0)
if message != "" {
return repository.RegistrationParams{}, message
}
companyID, _, message := optionalString(payload, "perusahaan_id", 50)
if message != "" {
return repository.RegistrationParams{}, message
}
insuranceID, _, message := optionalString(payload, "asuransi_id", 50)
if message != "" {
return repository.RegistrationParams{}, message
}
providerID, _, message := optionalString(payload, "provider_id", 50)
if message != "" {
return repository.RegistrationParams{}, message
}
policyNumber, _, message := optionalString(payload, "nomer_polis", 100)
if message != "" {
return repository.RegistrationParams{}, message
}
guaranteeNumber, _, message := optionalString(payload, "nomer_jaminan", 100)
if message != "" {
return repository.RegistrationParams{}, message
}
entryCode, _, message := optionalString(payload, "kode_masuk_id", 50)
if message != "" {
return repository.RegistrationParams{}, message
}
classID, present, message := optionalString(payload, "kelas_id", 50)
if message != "" {
return repository.RegistrationParams{}, message
}
if !present || strings.TrimSpace(classID) == "" {
classID = "Default"
}
notes, _, message := optionalString(payload, "catatan", 500)
if message != "" {
return repository.RegistrationParams{}, message
}
channel, present, message := optionalString(payload, "channel", 50)
if message != "" {
return repository.RegistrationParams{}, message
}
if !present || strings.TrimSpace(channel) == "" {
channel = "CPONE"
}
referrer, _, message := optionalString(payload, "perujuk", 150)
if message != "" {
return repository.RegistrationParams{}, message
}
employeeID, _, message := optionalString(payload, "nik_karyawan", 100)
if message != "" {
return repository.RegistrationParams{}, message
}
employeeName, _, message := optionalString(payload, "nama_karyawan", 150)
if message != "" {
return repository.RegistrationParams{}, message
}
packageID, packagePresent, message := optionalString(payload, "kode_paket", 50)
if message != "" {
return repository.RegistrationParams{}, message
}
if !packagePresent || strings.TrimSpace(packageID) == "" {
packageID, _, message = optionalString(payload, "paket_id", 50)
if message != "" {
return repository.RegistrationParams{}, message
}
}
packageID = strings.ToUpper(strings.TrimSpace(packageID))
if packageID != "" && !labIdentifier.MatchString(packageID) {
return repository.RegistrationParams{}, "kode_paket hanya boleh berisi huruf, angka, dan tanda hubung"
}
return repository.RegistrationParams{
MedrecID: strings.TrimSpace(medrecID), NIK: normalizeIdentity(nik), BirthDate: birthDate,
RegistrationDate: registrationDate, DepartmentID: strings.TrimSpace(departmentID),
DoctorID: strings.TrimSpace(doctorID), PatientTypeID: patientType, RegistrationType: registrationType,
TariffPeriodID: tariffPeriod, CompanyID: strings.TrimSpace(companyID), InsuranceID: strings.TrimSpace(insuranceID),
GroupTariffID: groupTariff, ProviderID: strings.TrimSpace(providerID), PolicyNumber: strings.TrimSpace(policyNumber),
GuaranteeNumber: strings.TrimSpace(guaranteeNumber), EntryCode: strings.TrimSpace(entryCode), ClassID: strings.TrimSpace(classID),
Notes: strings.TrimSpace(notes), Referrer: strings.TrimSpace(referrer), EmployeeID: strings.TrimSpace(employeeID), EmployeeName: strings.TrimSpace(employeeName), Channel: normalizeText(channel), PackageID: packageID,
}, ""
}
func optionalInteger(payload map[string]any, key string, fallback int64) (int64, string) {
value, present := payload[key]
if !present || isLaravelEmpty(value) {
return fallback, ""
}
number, ok := parseInteger(value)
if !ok || number < 0 {
return 0, key + " harus berupa angka"
}
return number, ""
}
func writeRegistrationResponse(w http.ResponseWriter, statusCode int, success bool, status, message string, data any) {
WriteJSON(w, statusCode, MedrecResponse{Success: success, Status: status, Message: message, Data: data})
}