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" } 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), Channel: normalizeText(channel), }, "" } 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}) }