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 ( )
2024-03-06 09:15:08 +07:00
rows , err := f . GetRows ( "PRODUCTION Pasien Setio" )
2024-02-22 10:43:39 +07:00
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 { }
2024-03-06 09:15:08 +07:00
// var wg = &sync.WaitGroup{}
2024-02-22 10:43:39 +07:00
for idx , row := range rows {
2024-03-06 09:15:08 +07:00
// wg.Add(1)
// go func(idx int, row []string) {
2024-02-22 10:43:39 +07:00
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" ,
} )
2024-03-06 09:15:08 +07:00
return
2024-02-22 10:43:39 +07:00
}
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" ,
} )
2024-03-06 09:15:08 +07:00
return
2024-02-22 10:43:39 +07:00
}
kelamin , err := strconv . Atoi ( row [ 6 ] )
if err != nil {
log . Printf ( "row 6: %s, err: %v" , row [ 6 ] , err )
2024-03-06 09:15:08 +07:00
return
2024-02-22 10:43:39 +07:00
}
value := repository . ImportDataPasienParams {
2024-03-06 09:15:08 +07:00
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 } ,
2024-02-22 10:43:39 +07:00
}
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 ) ,
} )
2024-03-06 09:15:08 +07:00
return
2024-02-23 14:10:40 +07:00
}
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 ) ,
} )
2024-03-06 09:15:08 +07:00
return
2024-02-22 10:43:39 +07:00
}
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
}
}
2024-03-06 09:15:08 +07:00
if value . NoKTP . Valid {
patient , err := repository . Store . FindPatientByNik ( s . Store , r . Context ( ) , value . NoKTP . String )
2024-02-22 10:43:39 +07:00
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
}
2024-03-06 09:15:08 +07:00
if value . NoKTP . String == patient . Nik . String {
2024-02-22 10:43:39 +07:00
if patient . TanggalLahir . Before ( value . TglLahir ) {
2024-03-06 09:15:08 +07:00
value . NoKTP . Valid = false
2024-02-22 10:43:39 +07:00
} 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 ) ,
} )
2024-03-06 09:15:08 +07:00
return
2024-02-22 10:43:39 +07:00
}
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 ) ,
} )
}
2024-03-06 09:15:08 +07:00
return
2024-02-22 10:43:39 +07:00
}
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 ) ,
} )
2024-03-06 09:15:08 +07:00
return
2024-02-22 10:43:39 +07:00
}
}
2024-03-06 09:15:08 +07:00
// wg.Done()
// }(idx, row)
2024-02-22 10:43:39 +07:00
}
2024-03-06 09:15:08 +07:00
// wg.Wait()
2024-02-22 10:43:39 +07:00
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 )
}