go_import_excel_pg/internal/rest/handler.go

346 lines
10 KiB
Go
Raw Normal View History

2024-02-22 10:43:39 +07:00
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"
2024-02-23 14:10:40 +07:00
"github.com/jackc/pgx/v5"
2024-02-22 10:43:39 +07:00
"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("import data pasien")
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{}
for idx, row := range rows {
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",
})
continue
}
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",
})
continue
}
kelamin, err := strconv.Atoi(row[6])
if err != nil {
log.Printf("row 6: %s, err: %v", row[6], err)
continue
}
value := repository.ImportDataPasienParams{
NoRekamMedis: row[0],
NamaPasien: row[1],
Nik: pgtype.Text{String: row[2], Valid: len(row[2]) > 0},
NoBPJS: pgtype.Text{String: row[3], Valid: len(row[3]) > 0},
TpLahir: pgtype.Text{String: row[4], Valid: len(row[4]) > 0},
TglLahir: tanggalLahir,
Kelamin: int8(kelamin),
Kebangsaan: util.StringToIntPtr[int8](row[6]),
Agama: util.StringToIntPtr[int8](row[7]),
Suku: util.StringToIntPtr[int32](row[8]),
Pendidikan: util.StringToIntPtr[int8](row[9]),
Pekerjaan: util.StringToIntPtr[int8](row[10]),
Hp: pgtype.Text{String: row[11], Valid: len(row[11]) > 0},
Email: pgtype.Text{String: row[12], Valid: len(row[12]) > 0},
StatusNikah: util.StringToIntPtr[int8](row[13]),
Provinsi: util.StringToStringPtr(row[14]),
Kabupaten: util.StringToIntPtr[int32](row[15]),
Kecamatan: util.StringToIntPtr[int32](row[16]),
Kelurahan: util.StringToIntPtr[int32](row[17]),
Kodepos: util.StringToIntPtr[int32](row[18]),
NamaJalan: pgtype.Text{String: row[19], Valid: len(row[19]) > 0},
HpPenjamin: pgtype.Text{String: row[20], Valid: len(row[20]) > 0},
NamaPenjamin: pgtype.Text{String: row[21], Valid: len(row[21]) > 0},
KtpPenjamin: pgtype.Text{String: row[22], Valid: len(row[22]) > 0},
HubunganPenjamin: util.StringToIntPtr[int8](row[23]),
PendidikanPenjamin: util.StringToIntPtr[int8](row[24]),
AlamatPenjamin: pgtype.Text{String: row[25], Valid: len(row[25]) > 0},
}
patientExist, err := repository.Store.FindPatientByNoRm(s.Store, r.Context(), value.NoRekamMedis)
if err != nil {
2024-02-23 14:10:40 +07:00
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),
})
continue
}
2024-02-22 10:43:39 +07:00
}
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),
})
continue
}
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.Nik.Valid {
patient, err := repository.Store.FindPatientByNik(s.Store, r.Context(), value.Nik.String)
if err != nil {
2024-02-23 14:10:40 +07:00
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),
})
}
2024-02-22 10:43:39 +07:00
}
if value.Nik.String == patient.Nik.String {
if patient.TanggalLahir.Before(value.TglLahir) {
value.Nik.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),
})
continue
}
errorMsg = append(errorMsg, map[string]any{
"no_rm": value.NoRekamMedis,
"status": "WARNING",
2024-02-23 14:10:40 +07:00
"message": fmt.Sprintf("NIK kembar dengan pasien yang ada di sistem noRm: %s %s, mohon dicek kembali current user: %v"),
2024-02-22 10:43:39 +07:00
})
}
}
}
if value.NoBPJS.Valid {
patient, err := repository.Store.FindPatientByBPJSCode(s.Store, r.Context(), value.NoBPJS.String)
if err != nil {
2024-02-23 14:10:40 +07:00
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),
})
}
2024-02-22 10:43:39 +07:00
}
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),
})
}
continue
}
errorMsg = append(errorMsg, map[string]any{
2024-02-23 14:10:40 +07:00
"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,
),
2024-02-22 10:43:39 +07:00
})
}
}
2024-02-23 14:10:40 +07:00
err = repository.Store.ImportPatientTx(s.Store, r.Context(), value, int32(currentUser.UserId), int32(currentUser.FasyankesId))
2024-02-22 10:43:39 +07:00
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),
})
continue
}
}
}
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",
2024-02-23 14:10:40 +07:00
"file": "foo.txt",
2024-02-22 10:43:39 +07:00
// "contentType": contentType,
// "patient": tempArr,
2024-02-23 14:10:40 +07:00
// "errorData": errorMsg,
2024-02-22 10:43:39 +07:00
}
2024-02-23 14:10:40 +07:00
w.WriteHeader(200)
2024-02-22 10:43:39 +07:00
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)
}