242 lines
7.8 KiB
Go
242 lines
7.8 KiB
Go
package http
|
|
|
|
import (
|
|
"errors"
|
|
"net/http"
|
|
"regexp"
|
|
"strings"
|
|
"time"
|
|
|
|
"primaya-api/cpone-middleware/internal/repository"
|
|
)
|
|
|
|
var (
|
|
spaces = regexp.MustCompile(`\s+`)
|
|
nonAlphaNumber = regexp.MustCompile(`[^A-Za-z0-9]`)
|
|
nonDigit = regexp.MustCompile(`\D`)
|
|
ktpNumber = regexp.MustCompile(`^\d{16}$`)
|
|
emailAddress = regexp.MustCompile(`^[^\s@]+@[^\s@]+\.[^\s@]+$`)
|
|
)
|
|
|
|
type MedrecResponse struct {
|
|
Success bool `json:"success"`
|
|
Status string `json:"status"`
|
|
Message string `json:"message"`
|
|
Data any `json:"data"`
|
|
}
|
|
|
|
func (h Handler) StoreMedrec(w http.ResponseWriter, r *http.Request) {
|
|
payload, _ := decodeJSONObject(r)
|
|
params, message := validateMedrec(payload)
|
|
if message != "" {
|
|
writeMedrecResponse(w, http.StatusUnprocessableEntity, false, "validation_error", message, nil)
|
|
return
|
|
}
|
|
params.HospitalCode = h.hospitalCode
|
|
|
|
outcome, err := h.patientRepository(r.Context()).StoreMedrec(r.Context(), params)
|
|
if err != nil {
|
|
var validationErr repository.ValidationError
|
|
if errors.As(err, &validationErr) {
|
|
writeMedrecResponse(w, http.StatusUnprocessableEntity, false, "validation_error", validationErr.Message, nil)
|
|
return
|
|
}
|
|
writeMedrecResponse(w, http.StatusInternalServerError, false, "error", err.Error(), nil)
|
|
return
|
|
}
|
|
|
|
writeMedrecResponse(w, outcome.HTTPStatus, outcome.Success, outcome.Status, outcome.Message, outcome.Data)
|
|
}
|
|
|
|
func validateMedrec(payload map[string]any) (repository.MedrecParams, string) {
|
|
name, message := requiredString(payload, "nama", 255, "Nama pasien wajib diisi")
|
|
if message != "" {
|
|
return repository.MedrecParams{}, message
|
|
}
|
|
gender, message := requiredString(payload, "jenis_kelamin", 0, "Jenis kelamin wajib diisi")
|
|
if message != "" {
|
|
return repository.MedrecParams{}, message
|
|
}
|
|
if gender != "L" && gender != "P" && gender != "l" && gender != "p" {
|
|
return repository.MedrecParams{}, "Jenis kelamin harus L atau P"
|
|
}
|
|
|
|
dateOfBirth, message := requiredString(payload, "tgl_lahir", 0, "Tanggal lahir wajib diisi")
|
|
if message != "" {
|
|
return repository.MedrecParams{}, message
|
|
}
|
|
jakarta, err := time.LoadLocation("Asia/Jakarta")
|
|
if err != nil {
|
|
return repository.MedrecParams{}, err.Error()
|
|
}
|
|
birthDate, err := time.ParseInLocation("2006-01-02", dateOfBirth, jakarta)
|
|
if err != nil || birthDate.Format("2006-01-02") != dateOfBirth {
|
|
return repository.MedrecParams{}, "Tanggal lahir harus format Y-m-d"
|
|
}
|
|
now := time.Now().In(jakarta)
|
|
today := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, jakarta)
|
|
if birthDate.After(today) {
|
|
return repository.MedrecParams{}, "Tanggal lahir tidak boleh lebih dari hari ini"
|
|
}
|
|
|
|
identityType, present, message := optionalString(payload, "jenis_nomer_sosial", 20)
|
|
if message != "" {
|
|
return repository.MedrecParams{}, message
|
|
}
|
|
if !present || identityType == "" {
|
|
identityType = "KTP"
|
|
}
|
|
identityNumber, identityPresent, message := optionalString(payload, "nomer_sosial", 50)
|
|
if message != "" {
|
|
return repository.MedrecParams{}, message
|
|
}
|
|
nik, nikPresent, message := optionalString(payload, "nik", 50)
|
|
if message != "" {
|
|
return repository.MedrecParams{}, message
|
|
}
|
|
if !identityPresent || identityNumber == "" {
|
|
if nikPresent {
|
|
identityNumber = nik
|
|
}
|
|
}
|
|
|
|
phone, phonePresent, message := optionalString(payload, "telepon", 30)
|
|
if message != "" {
|
|
return repository.MedrecParams{}, message
|
|
}
|
|
mobile, mobilePresent, message := optionalString(payload, "ponsel", 30)
|
|
if message != "" {
|
|
return repository.MedrecParams{}, message
|
|
}
|
|
if !phonePresent && !mobilePresent {
|
|
return repository.MedrecParams{}, "Telepon atau ponsel wajib diisi"
|
|
}
|
|
|
|
email, _, message := optionalString(payload, "email", 255)
|
|
if message != "" {
|
|
return repository.MedrecParams{}, message
|
|
}
|
|
if email != "" && !emailAddress.MatchString(strings.TrimSpace(email)) {
|
|
return repository.MedrecParams{}, "The email must be a valid email address."
|
|
}
|
|
|
|
placeOfBirth, message := optionalMedrecString(payload, "tempat_lahir", 100)
|
|
if message != "" {
|
|
return repository.MedrecParams{}, message
|
|
}
|
|
address, message := optionalMedrecString(payload, "alamat", 500)
|
|
if message != "" {
|
|
return repository.MedrecParams{}, message
|
|
}
|
|
province, message := optionalMedrecString(payload, "propinsi", 50)
|
|
if message != "" {
|
|
return repository.MedrecParams{}, message
|
|
}
|
|
city, message := optionalMedrecString(payload, "kabupaten", 50)
|
|
if message != "" {
|
|
return repository.MedrecParams{}, message
|
|
}
|
|
district, message := optionalMedrecString(payload, "kecamatan", 50)
|
|
if message != "" {
|
|
return repository.MedrecParams{}, message
|
|
}
|
|
village, message := optionalMedrecString(payload, "kelurahan", 50)
|
|
if message != "" {
|
|
return repository.MedrecParams{}, message
|
|
}
|
|
postalCode, message := optionalMedrecString(payload, "kode_pos", 20)
|
|
if message != "" {
|
|
return repository.MedrecParams{}, message
|
|
}
|
|
companyID, message := optionalMedrecString(payload, "perusahaan_id", 50)
|
|
if message != "" {
|
|
return repository.MedrecParams{}, message
|
|
}
|
|
employeeID, message := optionalMedrecString(payload, "nik_karyawan", 50)
|
|
if message != "" {
|
|
return repository.MedrecParams{}, message
|
|
}
|
|
dependantID, message := optionalMedrecString(payload, "dependant_id", 4)
|
|
if message != "" {
|
|
return repository.MedrecParams{}, message
|
|
}
|
|
employeeName, message := optionalMedrecString(payload, "nama_karyawan", 100)
|
|
if message != "" {
|
|
return repository.MedrecParams{}, message
|
|
}
|
|
channel, channelPresent, message := optionalString(payload, "channel", 50)
|
|
if message != "" {
|
|
return repository.MedrecParams{}, message
|
|
}
|
|
if !channelPresent || channel == "" {
|
|
channel = "CPONE"
|
|
}
|
|
|
|
identityType = normalizeText(identityType)
|
|
identityNumber = normalizeIdentity(identityNumber)
|
|
if identityNumber == "" {
|
|
return repository.MedrecParams{}, "NIK/nomer_sosial wajib diisi"
|
|
}
|
|
if identityType == "KTP" && !ktpNumber.MatchString(identityNumber) {
|
|
return repository.MedrecParams{}, "NIK/KTP harus 16 digit angka"
|
|
}
|
|
|
|
phone = normalizePhone(phone)
|
|
mobile = normalizePhone(mobile)
|
|
if phone == "" && mobile == "" {
|
|
return repository.MedrecParams{}, "Telepon atau ponsel wajib diisi"
|
|
}
|
|
|
|
return repository.MedrecParams{
|
|
Name: normalizeName(name),
|
|
Gender: normalizeText(gender),
|
|
DateOfBirth: birthDate,
|
|
IdentityType: identityType,
|
|
IdentityNumber: identityNumber,
|
|
Phone: phone,
|
|
Mobile: mobile,
|
|
Email: strings.ToLower(strings.TrimSpace(email)),
|
|
PlaceOfBirth: normalizeName(placeOfBirth),
|
|
Address: strings.TrimSpace(address),
|
|
Province: strings.TrimSpace(province),
|
|
City: strings.TrimSpace(city),
|
|
District: strings.TrimSpace(district),
|
|
Village: strings.TrimSpace(village),
|
|
PostalCode: strings.TrimSpace(postalCode),
|
|
CompanyID: strings.TrimSpace(companyID),
|
|
EmployeeID: strings.TrimSpace(employeeID),
|
|
DependantID: strings.TrimSpace(dependantID),
|
|
EmployeeName: strings.TrimSpace(employeeName),
|
|
Channel: normalizeText(channel),
|
|
}, ""
|
|
}
|
|
|
|
func optionalMedrecString(payload map[string]any, key string, maxLength int) (string, string) {
|
|
value, _, message := optionalString(payload, key, maxLength)
|
|
return value, message
|
|
}
|
|
|
|
func normalizeName(value string) string {
|
|
return strings.ToUpper(strings.TrimSpace(spaces.ReplaceAllString(value, " ")))
|
|
}
|
|
|
|
func normalizeText(value string) string {
|
|
return strings.ToUpper(strings.TrimSpace(value))
|
|
}
|
|
|
|
func normalizeIdentity(value string) string {
|
|
return strings.ToUpper(nonAlphaNumber.ReplaceAllString(value, ""))
|
|
}
|
|
|
|
func normalizePhone(value string) string {
|
|
phone := nonDigit.ReplaceAllString(value, "")
|
|
if strings.HasPrefix(phone, "62") {
|
|
return "0" + strings.TrimPrefix(phone, "62")
|
|
}
|
|
return phone
|
|
}
|
|
|
|
func writeMedrecResponse(w http.ResponseWriter, statusCode int, success bool, status, message string, data any) {
|
|
WriteJSON(w, statusCode, MedrecResponse{Success: success, Status: status, Message: message, Data: data})
|
|
}
|