346 lines
10 KiB
Go
346 lines
10 KiB
Go
package rest
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"git.nochill.in/nochill/excel_import_playground/internal"
|
|
"git.nochill.in/nochill/excel_import_playground/internal/repository"
|
|
"git.nochill.in/nochill/excel_import_playground/util"
|
|
"github.com/gorilla/mux"
|
|
"github.com/jackc/pgx/v5"
|
|
"github.com/jackc/pgx/v5/pgtype"
|
|
"github.com/xuri/excelize/v2"
|
|
)
|
|
|
|
func (s *Server) ImportPatientHandler(w http.ResponseWriter, r *http.Request) {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
currentUser := internal.GetPayloadFromContext(r.Context())
|
|
|
|
file, header, err := r.FormFile("file")
|
|
|
|
if err != nil {
|
|
http.Error(w, "Invalid file", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
if !strings.HasSuffix(header.Filename, ".xlsx") && !strings.HasSuffix(header.Filename, ".xls") {
|
|
http.Error(w, "File is not an .xlsx or xls file", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
if header.Size > 30<<20 {
|
|
http.Error(w, "The uploaded file is too large.", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
buffer := make([]byte, 512) // Create a buffer to store the file header
|
|
if _, err = file.Read(buffer); err != nil {
|
|
http.Error(w, "Could not read file", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
// contentType := http.DetectContentType(buffer)
|
|
// Reset the read pointer of the file
|
|
if _, err = file.Seek(0, 0); err != nil {
|
|
http.Error(w, "Could not read file", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
f, err := excelize.OpenReader(file)
|
|
if err != nil {
|
|
http.Error(w, "Error opening Excel file", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
defer f.Close()
|
|
|
|
rows, err := f.GetRows("PRODUCTION Pasien Setio")
|
|
|
|
if err != nil {
|
|
json.NewEncoder(w).Encode(err)
|
|
return
|
|
}
|
|
|
|
// _, err = repository.Store.FindLastPatientInCertainFasyankes(s.Store, r.Context(), 2)
|
|
|
|
if err != nil {
|
|
w.WriteHeader(500)
|
|
log.Println(err)
|
|
json.NewEncoder(w).Encode(err)
|
|
return
|
|
}
|
|
|
|
// tempArr := make([]repository.ImportDataPasienParams, len(rows)-1)
|
|
var errorMsg []interface{}
|
|
// var wg = &sync.WaitGroup{}
|
|
|
|
for idx, row := range rows {
|
|
// wg.Add(1)
|
|
// go func(idx int, row []string) {
|
|
if idx >= 1 {
|
|
if row[0] == "" || row[1] == "" {
|
|
errorMsg = append(errorMsg, map[string]any{
|
|
"baris": idx + 1,
|
|
"status": "CRITICAL",
|
|
"error_message": "kolom A 'no_rekam medis' dan kolom B 'nama_pasien' wajib diisi",
|
|
})
|
|
return
|
|
}
|
|
|
|
tanggalLahir, err := time.Parse(util.TIME_PARSE_LAYOUT, row[5])
|
|
if err != nil {
|
|
errorMsg = append(errorMsg, map[string]any{
|
|
"baris": idx + 1,
|
|
"status": "CRITICAL",
|
|
"error_message": "tanggal lahir wajib diisi",
|
|
})
|
|
return
|
|
}
|
|
|
|
kelamin, err := strconv.Atoi(row[6])
|
|
if err != nil {
|
|
log.Printf("row 6: %s, err: %v", row[6], err)
|
|
return
|
|
}
|
|
|
|
value := repository.ImportDataPasienParams{
|
|
NoRekamMedis: row[0],
|
|
NamaPasien: row[1],
|
|
NoKTP: pgtype.Text{String: row[2], Valid: len(row[2]) > 0},
|
|
NoBPJS: pgtype.Text{String: row[3], Valid: len(row[3]) > 0},
|
|
TempatLahir: pgtype.Int4{Int32: 0, Valid: false},
|
|
TglLahir: tanggalLahir,
|
|
Kelamin: int8(kelamin),
|
|
Kebangsaan: pgtype.Int4{Int32: util.StringToInt[int32](row[7]), Valid: util.StringToInt[int32](row[7]) > 0},
|
|
Agama: pgtype.Int4{Int32: util.StringToInt[int32](row[8]), Valid: util.StringToInt[int32](row[8]) > 0},
|
|
Suku: pgtype.Int4{Int32: util.StringToInt[int32](row[9]), Valid: util.StringToInt[int32](row[9]) > 0},
|
|
Pendidikan: pgtype.Int4{Int32: util.StringToInt[int32](row[10]), Valid: util.StringToInt[int32](row[10]) > 0},
|
|
Pekerjaan: pgtype.Int4{Int32: util.StringToInt[int32](row[11]), Valid: util.StringToInt[int32](row[11]) > 0},
|
|
Hp: pgtype.Text{String: row[12], Valid: len(row[12]) > 0},
|
|
Email: pgtype.Text{String: row[13], Valid: len(row[13]) > 0},
|
|
StatusKawin: pgtype.Int4{Int32: util.StringToInt[int32](row[14]), Valid: util.StringToInt[int32](row[14]) > 0},
|
|
Provinsi: pgtype.Text{String: row[15], Valid: len(row[15]) > 0},
|
|
NamaJalan: pgtype.Text{String: row[16], Valid: len(row[16]) > 0},
|
|
NamaPenjamin: pgtype.Text{String: row[17], Valid: len(row[17]) > 0},
|
|
NikPenjamin: pgtype.Text{String: row[18], Valid: len(row[18]) > 0},
|
|
HubunganPenjamin: pgtype.Int2{Int16: util.StringToInt[int16](row[8]), Valid: util.StringToInt[int16](row[8]) > 0},
|
|
HpPenjamin: pgtype.Text{String: row[20], Valid: len(row[20]) > 0},
|
|
}
|
|
|
|
patientExist, err := repository.Store.FindPatientByNoRm(s.Store, r.Context(), value.NoRekamMedis)
|
|
|
|
if err != nil {
|
|
if err != pgx.ErrNoRows {
|
|
errorMsg = append(errorMsg, map[string]any{
|
|
"no_rm": value.NoRekamMedis,
|
|
"status": "CRITICAL",
|
|
"message": fmt.Sprintf("Terjadi kesalahan sistem, mencari data pasien %v", err),
|
|
})
|
|
return
|
|
}
|
|
}
|
|
|
|
if patientExist.NoRm != "" {
|
|
if value.NoRekamMedis == patientExist.NoRm {
|
|
updatedNoRekamMedis, err := repository.Store.GenerateNoRm(s.Store, r.Context(), int32(currentUser.FasyankesId))
|
|
if err != nil {
|
|
errorMsg = append(errorMsg, map[string]any{
|
|
"no_rm": value.NoRekamMedis,
|
|
"status": "CRITICAL",
|
|
"message": fmt.Sprintf("Terjadi kesalahan sistem, gagal generate NoRM %v", err),
|
|
})
|
|
return
|
|
}
|
|
|
|
errorMsg = append(errorMsg, map[string]any{
|
|
"no_rm": value.NoRekamMedis,
|
|
"status": "WARNING",
|
|
"message": fmt.Sprintf("No rekam medis %s sudah ada, maka no rekam medis diganti dengan %s", value.NoRekamMedis, updatedNoRekamMedis),
|
|
})
|
|
|
|
value.NoRekamMedis = updatedNoRekamMedis
|
|
}
|
|
}
|
|
|
|
if value.NoKTP.Valid {
|
|
patient, err := repository.Store.FindPatientByNik(s.Store, r.Context(), value.NoKTP.String)
|
|
|
|
if err != nil {
|
|
if err != pgx.ErrNoRows {
|
|
errorMsg = append(errorMsg, map[string]any{
|
|
"no_rm": value.NoRekamMedis,
|
|
"status": "CRITICAL",
|
|
"message": fmt.Sprintf("Terjadi kesalahan sistem, gagal mendapatakan data pasien %v", err),
|
|
})
|
|
}
|
|
}
|
|
|
|
if value.NoKTP.String == patient.Nik.String {
|
|
if patient.TanggalLahir.Before(value.TglLahir) {
|
|
value.NoKTP.Valid = false
|
|
} else {
|
|
_, err := repository.Store.UpdatePatient(s.Store, r.Context(), repository.UpdatePatientParams{
|
|
Nik: repository.UpdateableField[pgtype.Text]{IsFilled: true, Value: pgtype.Text{Valid: false, String: ""}},
|
|
}, int32(patient.ID))
|
|
if err != nil {
|
|
errorMsg = append(errorMsg, map[string]any{
|
|
"no_rm": value.NoRekamMedis,
|
|
"status": "CRITICAL",
|
|
"message": fmt.Sprintf("Terjadi kesalahan sistem, gagal mendapatakan update pasien lama karena NIK sama %v", err),
|
|
})
|
|
|
|
return
|
|
}
|
|
|
|
errorMsg = append(errorMsg, map[string]any{
|
|
"no_rm": value.NoRekamMedis,
|
|
"status": "WARNING",
|
|
"message": fmt.Sprintf("NIK kembar dengan pasien yang ada di sistem noRm: %s %s, mohon dicek kembali current user: %v"),
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
if value.NoBPJS.Valid {
|
|
patient, err := repository.Store.FindPatientByBPJSCode(s.Store, r.Context(), value.NoBPJS.String)
|
|
|
|
if err != nil {
|
|
if err != pgx.ErrNoRows {
|
|
errorMsg = append(errorMsg, map[string]any{
|
|
"no_rm": value.NoRekamMedis,
|
|
"status": "CRITICAL",
|
|
"message": fmt.Sprintf("Terjadi kesalahan sistem, gagal mendapatakan data pasien dengan BPJS %v", err),
|
|
})
|
|
}
|
|
}
|
|
|
|
if patient.ID != 0 {
|
|
if patient.TanggalLahir.Before(value.TglLahir) {
|
|
value.NoBPJS = pgtype.Text{Valid: false, String: ""}
|
|
} else {
|
|
_, err := repository.Store.UpdatePatient(
|
|
s.Store,
|
|
r.Context(),
|
|
repository.UpdatePatientParams{
|
|
NoKartuPesertaBPJS: repository.UpdateableField[pgtype.Text]{IsFilled: true, Value: pgtype.Text{Valid: false, String: ""}},
|
|
},
|
|
int32(patient.ID),
|
|
)
|
|
|
|
if err != nil {
|
|
errorMsg = append(errorMsg, map[string]any{
|
|
"no_rm": value.NoRekamMedis,
|
|
"status": "CRITICAL",
|
|
"message": fmt.Sprintf("Terjadi kesalahan sistem, gagal mendapatakan update pasien dengan BPJS %v", err),
|
|
})
|
|
}
|
|
return
|
|
}
|
|
|
|
errorMsg = append(errorMsg, map[string]any{
|
|
"no_rm": value.NoRekamMedis,
|
|
"status": "WARNING",
|
|
"message": fmt.Sprintf("No KartuBPJS ada yang sama dengan pasien dengan no rm yang ada di sistem: noRm: %s noBpjs: %s, mohon dicek kembali, NO BPJS pasien import: %s",
|
|
patient.NoRm, patient.NoKartuPesertaBPJS.String, value.NoBPJS.String,
|
|
),
|
|
})
|
|
}
|
|
}
|
|
|
|
err = repository.Store.ImportPatientTx(s.Store, r.Context(), value, int32(currentUser.UserId), int32(currentUser.FasyankesId))
|
|
|
|
if err != nil {
|
|
errorMsg = append(errorMsg, map[string]any{
|
|
"no_rm": value.NoRekamMedis,
|
|
"status": "CRITICAL",
|
|
"message": fmt.Sprintf("Terjadi kesalahan sistem, gagal saat import pasien dengan %v", err),
|
|
})
|
|
|
|
return
|
|
}
|
|
|
|
}
|
|
// wg.Done()
|
|
// }(idx, row)
|
|
}
|
|
|
|
// wg.Wait()
|
|
|
|
if len(errorMsg) > 0 {
|
|
jsonMarshal, _ := json.MarshalIndent(errorMsg, "", " ")
|
|
if err := os.WriteFile("foo.txt", []byte(jsonMarshal), 0666); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
|
|
a := map[string]any{
|
|
"halo": "halo",
|
|
"file": "foo.txt",
|
|
|
|
// "contentType": contentType,
|
|
// "patient": tempArr,
|
|
// "errorData": errorMsg,
|
|
}
|
|
|
|
w.WriteHeader(200)
|
|
|
|
json.NewEncoder(w).Encode(a)
|
|
|
|
}
|
|
|
|
func validateFile(r *http.Request) error {
|
|
|
|
return nil
|
|
}
|
|
|
|
type updatePatientParams struct {
|
|
NamaPasien string `json:"patient_name"`
|
|
}
|
|
|
|
func (s *Server) UpdatePatient(w http.ResponseWriter, r *http.Request) {
|
|
vars := mux.Vars(r)
|
|
var req updatePatientParams
|
|
|
|
idParams, ok := vars["id"]
|
|
|
|
if !ok {
|
|
fmt.Println("id is missing in parameters")
|
|
}
|
|
|
|
id, err := strconv.Atoi(idParams)
|
|
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
json.NewEncoder(w).Encode(err)
|
|
return
|
|
}
|
|
|
|
err = json.NewDecoder(r.Body).Decode(&req)
|
|
|
|
if err != nil {
|
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
updatedUser, err := repository.Store.UpdatePatient(s.Store, r.Context(), repository.UpdatePatientParams{
|
|
NamaPasien: repository.UpdateableField[string]{IsFilled: true, Value: req.NamaPasien},
|
|
}, int32(id))
|
|
|
|
if err != nil {
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
json.NewEncoder(w).Encode(updatedUser)
|
|
|
|
}
|