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 )
}