init
This commit is contained in:
commit
9837cbf7cf
1
.env.example
Normal file
1
.env.example
Normal file
@ -0,0 +1 @@
|
||||
JWT_SALT=
|
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
.env
|
||||
.vscode
|
||||
tmp
|
212
foo.txt
Normal file
212
foo.txt
Normal file
@ -0,0 +1,212 @@
|
||||
[
|
||||
{
|
||||
"message": "No rekam medis 000000001 sudah ada, maka no rekam medis diganti dengan 00064483",
|
||||
"no_rm": "000000001",
|
||||
"status": "WARNING"
|
||||
},
|
||||
{
|
||||
"message": "Terjadi kesalahan sistem, gagal mendapatakan data pasien no rows in result set",
|
||||
"no_rm": "00064483",
|
||||
"status": "CRITICAL"
|
||||
},
|
||||
{
|
||||
"message": "Terjadi kesalahan sistem, gagal mendapatakan data pasien dengan BPJS no rows in result set",
|
||||
"no_rm": "00064483",
|
||||
"status": "CRITICAL"
|
||||
},
|
||||
{
|
||||
"message": "Terjadi kesalahan sistem, gagal saat import pasien dengan ERROR: INSERT has more target columns than expressions (SQLSTATE 42601)",
|
||||
"no_rm": "00064483",
|
||||
"status": "CRITICAL"
|
||||
},
|
||||
{
|
||||
"message": "No rekam medis 00000001 sudah ada, maka no rekam medis diganti dengan 00064483",
|
||||
"no_rm": "00000001",
|
||||
"status": "WARNING"
|
||||
},
|
||||
{
|
||||
"message": "Terjadi kesalahan sistem, gagal saat import pasien dengan ERROR: INSERT has more target columns than expressions (SQLSTATE 42601)",
|
||||
"no_rm": "00064483",
|
||||
"status": "CRITICAL"
|
||||
},
|
||||
{
|
||||
"message": "No rekam medis 00000002 sudah ada, maka no rekam medis diganti dengan 00064483",
|
||||
"no_rm": "00000002",
|
||||
"status": "WARNING"
|
||||
},
|
||||
{
|
||||
"message": "Terjadi kesalahan sistem, gagal mendapatakan data pasien dengan BPJS no rows in result set",
|
||||
"no_rm": "00064483",
|
||||
"status": "CRITICAL"
|
||||
},
|
||||
{
|
||||
"message": "Terjadi kesalahan sistem, gagal saat import pasien dengan ERROR: INSERT has more target columns than expressions (SQLSTATE 42601)",
|
||||
"no_rm": "00064483",
|
||||
"status": "CRITICAL"
|
||||
},
|
||||
{
|
||||
"message": "No rekam medis 00000003 sudah ada, maka no rekam medis diganti dengan 00064483",
|
||||
"no_rm": "00000003",
|
||||
"status": "WARNING"
|
||||
},
|
||||
{
|
||||
"message": "Terjadi kesalahan sistem, gagal saat import pasien dengan ERROR: INSERT has more target columns than expressions (SQLSTATE 42601)",
|
||||
"no_rm": "00064483",
|
||||
"status": "CRITICAL"
|
||||
},
|
||||
{
|
||||
"message": "No rekam medis 00000004 sudah ada, maka no rekam medis diganti dengan 00064483",
|
||||
"no_rm": "00000004",
|
||||
"status": "WARNING"
|
||||
},
|
||||
{
|
||||
"message": "Terjadi kesalahan sistem, gagal saat import pasien dengan ERROR: INSERT has more target columns than expressions (SQLSTATE 42601)",
|
||||
"no_rm": "00064483",
|
||||
"status": "CRITICAL"
|
||||
},
|
||||
{
|
||||
"message": "No rekam medis 00000005 sudah ada, maka no rekam medis diganti dengan 00064483",
|
||||
"no_rm": "00000005",
|
||||
"status": "WARNING"
|
||||
},
|
||||
{
|
||||
"message": "Terjadi kesalahan sistem, gagal saat import pasien dengan ERROR: INSERT has more target columns than expressions (SQLSTATE 42601)",
|
||||
"no_rm": "00064483",
|
||||
"status": "CRITICAL"
|
||||
},
|
||||
{
|
||||
"message": "No rekam medis 00000006 sudah ada, maka no rekam medis diganti dengan 00064483",
|
||||
"no_rm": "00000006",
|
||||
"status": "WARNING"
|
||||
},
|
||||
{
|
||||
"message": "Terjadi kesalahan sistem, gagal saat import pasien dengan ERROR: INSERT has more target columns than expressions (SQLSTATE 42601)",
|
||||
"no_rm": "00064483",
|
||||
"status": "CRITICAL"
|
||||
},
|
||||
{
|
||||
"message": "No rekam medis 00000007 sudah ada, maka no rekam medis diganti dengan 00064483",
|
||||
"no_rm": "00000007",
|
||||
"status": "WARNING"
|
||||
},
|
||||
{
|
||||
"message": "Terjadi kesalahan sistem, gagal saat import pasien dengan ERROR: INSERT has more target columns than expressions (SQLSTATE 42601)",
|
||||
"no_rm": "00064483",
|
||||
"status": "CRITICAL"
|
||||
},
|
||||
{
|
||||
"message": "No rekam medis 00000008 sudah ada, maka no rekam medis diganti dengan 00064483",
|
||||
"no_rm": "00000008",
|
||||
"status": "WARNING"
|
||||
},
|
||||
{
|
||||
"message": "Terjadi kesalahan sistem, gagal saat import pasien dengan ERROR: INSERT has more target columns than expressions (SQLSTATE 42601)",
|
||||
"no_rm": "00064483",
|
||||
"status": "CRITICAL"
|
||||
},
|
||||
{
|
||||
"message": "No rekam medis 00000009 sudah ada, maka no rekam medis diganti dengan 00064483",
|
||||
"no_rm": "00000009",
|
||||
"status": "WARNING"
|
||||
},
|
||||
{
|
||||
"message": "Terjadi kesalahan sistem, gagal saat import pasien dengan ERROR: INSERT has more target columns than expressions (SQLSTATE 42601)",
|
||||
"no_rm": "00064483",
|
||||
"status": "CRITICAL"
|
||||
},
|
||||
{
|
||||
"message": "No rekam medis 00000010 sudah ada, maka no rekam medis diganti dengan 00064483",
|
||||
"no_rm": "00000010",
|
||||
"status": "WARNING"
|
||||
},
|
||||
{
|
||||
"message": "Terjadi kesalahan sistem, gagal mendapatakan data pasien dengan BPJS no rows in result set",
|
||||
"no_rm": "00064483",
|
||||
"status": "CRITICAL"
|
||||
},
|
||||
{
|
||||
"message": "Terjadi kesalahan sistem, gagal saat import pasien dengan ERROR: INSERT has more target columns than expressions (SQLSTATE 42601)",
|
||||
"no_rm": "00064483",
|
||||
"status": "CRITICAL"
|
||||
},
|
||||
{
|
||||
"message": "No rekam medis 00000011 sudah ada, maka no rekam medis diganti dengan 00064483",
|
||||
"no_rm": "00000011",
|
||||
"status": "WARNING"
|
||||
},
|
||||
{
|
||||
"message": "Terjadi kesalahan sistem, gagal mendapatakan data pasien no rows in result set",
|
||||
"no_rm": "00064483",
|
||||
"status": "CRITICAL"
|
||||
},
|
||||
{
|
||||
"message": "Terjadi kesalahan sistem, gagal mendapatakan data pasien dengan BPJS no rows in result set",
|
||||
"no_rm": "00064483",
|
||||
"status": "CRITICAL"
|
||||
},
|
||||
{
|
||||
"message": "Terjadi kesalahan sistem, gagal saat import pasien dengan ERROR: INSERT has more target columns than expressions (SQLSTATE 42601)",
|
||||
"no_rm": "00064483",
|
||||
"status": "CRITICAL"
|
||||
},
|
||||
{
|
||||
"message": "No rekam medis 00000012 sudah ada, maka no rekam medis diganti dengan 00064483",
|
||||
"no_rm": "00000012",
|
||||
"status": "WARNING"
|
||||
},
|
||||
{
|
||||
"message": "Terjadi kesalahan sistem, gagal saat import pasien dengan ERROR: INSERT has more target columns than expressions (SQLSTATE 42601)",
|
||||
"no_rm": "00064483",
|
||||
"status": "CRITICAL"
|
||||
},
|
||||
{
|
||||
"message": "No rekam medis 00000013 sudah ada, maka no rekam medis diganti dengan 00064483",
|
||||
"no_rm": "00000013",
|
||||
"status": "WARNING"
|
||||
},
|
||||
{
|
||||
"message": "Terjadi kesalahan sistem, gagal saat import pasien dengan ERROR: INSERT has more target columns than expressions (SQLSTATE 42601)",
|
||||
"no_rm": "00064483",
|
||||
"status": "CRITICAL"
|
||||
},
|
||||
{
|
||||
"message": "No rekam medis 00000014 sudah ada, maka no rekam medis diganti dengan 00064483",
|
||||
"no_rm": "00000014",
|
||||
"status": "WARNING"
|
||||
},
|
||||
{
|
||||
"message": "Terjadi kesalahan sistem, gagal mendapatakan data pasien no rows in result set",
|
||||
"no_rm": "00064483",
|
||||
"status": "CRITICAL"
|
||||
},
|
||||
{
|
||||
"message": "Terjadi kesalahan sistem, gagal mendapatakan data pasien dengan BPJS no rows in result set",
|
||||
"no_rm": "00064483",
|
||||
"status": "CRITICAL"
|
||||
},
|
||||
{
|
||||
"message": "Terjadi kesalahan sistem, gagal saat import pasien dengan ERROR: INSERT has more target columns than expressions (SQLSTATE 42601)",
|
||||
"no_rm": "00064483",
|
||||
"status": "CRITICAL"
|
||||
},
|
||||
{
|
||||
"message": "No rekam medis 00000015 sudah ada, maka no rekam medis diganti dengan 00064483",
|
||||
"no_rm": "00000015",
|
||||
"status": "WARNING"
|
||||
},
|
||||
{
|
||||
"message": "Terjadi kesalahan sistem, gagal saat import pasien dengan ERROR: INSERT has more target columns than expressions (SQLSTATE 42601)",
|
||||
"no_rm": "00064483",
|
||||
"status": "CRITICAL"
|
||||
},
|
||||
{
|
||||
"message": "No rekam medis 00000016 sudah ada, maka no rekam medis diganti dengan 00064483",
|
||||
"no_rm": "00000016",
|
||||
"status": "WARNING"
|
||||
},
|
||||
{
|
||||
"message": "Terjadi kesalahan sistem, gagal saat import pasien dengan ERROR: INSERT has more target columns than expressions (SQLSTATE 42601)",
|
||||
"no_rm": "00064483",
|
||||
"status": "CRITICAL"
|
||||
}
|
||||
]
|
28
go.mod
Normal file
28
go.mod
Normal file
@ -0,0 +1,28 @@
|
||||
module git.nochill.in/nochill/excel_import_playground
|
||||
|
||||
go 1.21.6
|
||||
|
||||
require (
|
||||
github.com/golang-jwt/jwt/v5 v5.2.0
|
||||
github.com/gorilla/mux v1.8.1
|
||||
github.com/henvic/pgq v0.0.2
|
||||
github.com/jackc/pgx/v5 v5.5.3
|
||||
github.com/joho/godotenv v1.5.1
|
||||
github.com/xuri/excelize/v2 v2.8.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 // indirect
|
||||
github.com/jackc/puddle/v2 v2.2.1 // indirect
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
|
||||
github.com/richardlehane/mscfb v1.0.4 // indirect
|
||||
github.com/richardlehane/msoleps v1.0.3 // indirect
|
||||
github.com/stretchr/testify v1.8.4 // indirect
|
||||
github.com/xuri/efp v0.0.0-20230802181842-ad255f2331ca // indirect
|
||||
github.com/xuri/nfp v0.0.0-20230819163627-dc951e3ffe1a // indirect
|
||||
golang.org/x/crypto v0.19.0 // indirect
|
||||
golang.org/x/net v0.21.0 // indirect
|
||||
golang.org/x/sync v0.1.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
)
|
94
go.sum
Normal file
94
go.sum
Normal file
@ -0,0 +1,94 @@
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
||||
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
||||
github.com/henvic/pgq v0.0.2 h1:4q/G/cW7zpxpwq672Xuh7BkcKcXonZJ6b9kR8ub3EwQ=
|
||||
github.com/henvic/pgq v0.0.2/go.mod h1:1Q6dKMwtbe2glBXlusJvNZnJrvgbwub/KcfiB/7UXA4=
|
||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 h1:L0QtFUgDarD7Fpv9jeVMgy/+Ec0mtnmYuImjTz6dtDA=
|
||||
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||
github.com/jackc/pgx/v5 v5.5.3 h1:Ces6/M3wbDXYpM8JyyPD57ivTtJACFZJd885pdIaV2s=
|
||||
github.com/jackc/pgx/v5 v5.5.3/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A=
|
||||
github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
|
||||
github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/richardlehane/mscfb v1.0.4 h1:WULscsljNPConisD5hR0+OyZjwK46Pfyr6mPu5ZawpM=
|
||||
github.com/richardlehane/mscfb v1.0.4/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk=
|
||||
github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
|
||||
github.com/richardlehane/msoleps v1.0.3 h1:aznSZzrwYRl3rLKRT3gUk9am7T/mLNSnJINvN0AQoVM=
|
||||
github.com/richardlehane/msoleps v1.0.3/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/xuri/efp v0.0.0-20230802181842-ad255f2331ca h1:uvPMDVyP7PXMMioYdyPH+0O+Ta/UO1WFfNYMO3Wz0eg=
|
||||
github.com/xuri/efp v0.0.0-20230802181842-ad255f2331ca/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI=
|
||||
github.com/xuri/excelize/v2 v2.8.0 h1:Vd4Qy809fupgp1v7X+nCS/MioeQmYVVzi495UCTqB7U=
|
||||
github.com/xuri/excelize/v2 v2.8.0/go.mod h1:6iA2edBTKxKbZAa7X5bDhcCg51xdOn1Ar5sfoXRGrQg=
|
||||
github.com/xuri/nfp v0.0.0-20230819163627-dc951e3ffe1a h1:Mw2VNrNNNjDtw68VsEj2+st+oCSn4Uz7vZw6TbhcV1o=
|
||||
github.com/xuri/nfp v0.0.0-20230819163627-dc951e3ffe1a/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
|
||||
golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo=
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/image v0.11.0 h1:ds2RoQvBvYTiJkwpSFDwCcDFNX7DqjL2WsUgTNk0Ooo=
|
||||
golang.org/x/image v0.11.0/go.mod h1:bglhjqbqVuEb9e9+eNR45Jfu7D+T4Qan+NhQk8Ck2P8=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
|
||||
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
136
internal/excel.go
Normal file
136
internal/excel.go
Normal file
@ -0,0 +1,136 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"time"
|
||||
)
|
||||
|
||||
type EnumObject struct {
|
||||
ID int `json:"id"`
|
||||
Label string `json:"label"`
|
||||
}
|
||||
|
||||
var Agama = []EnumObject{
|
||||
{ID: 1, Label: "Islam"},
|
||||
{ID: 2, Label: "Kristen (Protestan)"},
|
||||
{ID: 3, Label: "Katolik"},
|
||||
{ID: 4, Label: "Hindu"},
|
||||
{ID: 5, Label: "Buddha"},
|
||||
{ID: 6, Label: "Konghucu"},
|
||||
{ID: 7, Label: "Penghayat"},
|
||||
{ID: 8, Label: "Lain-lain"},
|
||||
}
|
||||
var Pendidikan = []EnumObject{
|
||||
{ID: 1, Label: "Tidak sekolah"},
|
||||
{ID: 2, Label: "SD"},
|
||||
{ID: 3, Label: "SLTP sederajat"},
|
||||
{ID: 4, Label: "SLTA sederajat"},
|
||||
{ID: 5, Label: "D1-D3 sederajat"},
|
||||
{ID: 6, Label: "D4"}, // Note: There was a duplicate ID for D4 and S1
|
||||
{ID: 6, Label: "S1"}, // Note: There was a duplicate ID for D4 and S1
|
||||
{ID: 7, Label: "S2"},
|
||||
{ID: 8, Label: "S3"},
|
||||
}
|
||||
|
||||
var StatusKawin = []EnumObject{
|
||||
{ID: 1, Label: "Belum Kawin"},
|
||||
{ID: 2, Label: "Kawin"},
|
||||
{ID: 3, Label: "Cerai Hidup"},
|
||||
{ID: 4, Label: "Cerai Mati"},
|
||||
}
|
||||
|
||||
var Pekerjaan = []EnumObject{
|
||||
{ID: 1, Label: "Tidak bekerja"},
|
||||
{ID: 2, Label: "PNS"},
|
||||
{ID: 3, Label: "TNI/POLRI"},
|
||||
{ID: 4, Label: "BUMN"},
|
||||
{ID: 5, Label: "Pegawai Swasta/Wirausaha"},
|
||||
{ID: 6, Label: "Lain-lain"},
|
||||
}
|
||||
|
||||
// export const importDataPasienSchema = z.object({
|
||||
// no_rekammedis: z.string(),
|
||||
// nama_pasien: z.string(),
|
||||
// no_ktp: z.string().nullish(),
|
||||
// no_bpjs: z.string().nullish(),
|
||||
// tgl_lahir: z.date(),
|
||||
// kelamin: z.number(),
|
||||
// kebangsaan: z.string().nullish(),
|
||||
// agama: z.string().nullish().transform(val => Agama.find(x => x.label === val)?.id),
|
||||
// suku: z.string().nullish(),
|
||||
// pendidikan: z.coerce.number().nullish(),
|
||||
// pekerjaan: z.string().nullish().transform(val => Pekerjaan.find(x => x.label === val)?.id),
|
||||
// hp: z.coerce.string().nullish().transform(val => validatePhoneRegex(val?.replace(/\s+/g, ''))),
|
||||
// email: z.string().nullish(),
|
||||
// status_nikah: z.string().nullish().transform(val => StatusKawin.find(x => x.label === val)?.id),
|
||||
// provinsi: z.string().nullish(),
|
||||
// kabupaten: z.string().nullish(),
|
||||
// kecamatan: z.string().nullish(),
|
||||
// kelurahan: z.string().nullish(),
|
||||
// kodepos: z.string().nullish(),
|
||||
// namajalan: z.string().nullish(),
|
||||
// hp_penjamin: z.coerce.string().nullish().transform(val => validatePhoneRegex(val?.replace(/\s+/g, ''))),
|
||||
// namapenjamin: z.string().nullish(),
|
||||
// ktp_penjamin: z.coerce.string().nullish(),
|
||||
// hubungan_penjamin: z.coerce.number().nullish(),
|
||||
// pendidikan_penjamin: z.string().nullish().transform(val => Pendidikan.find(x => x.label === val)?.id),
|
||||
// alamat_penjamin: z.string().nullish(),
|
||||
// }).transform(({
|
||||
// no_rekammedis,
|
||||
// nama_pasien,
|
||||
// no_ktp,
|
||||
// no_bpjs,
|
||||
// tgl_lahir,
|
||||
// kelamin,
|
||||
// status_nikah,
|
||||
// namajalan,
|
||||
// hp,
|
||||
// pendidikan_penjamin,
|
||||
// ...rest
|
||||
// }) => ({
|
||||
// noRm: no_rekammedis,
|
||||
// namaPasien: nama_pasien,
|
||||
// nik: no_ktp,
|
||||
// noKartuPesertaBPJS: no_bpjs,
|
||||
// tanggalLahir: tgl_lahir,
|
||||
// jenisKelamin: kelamin,
|
||||
// statusPernikahan: status_nikah,
|
||||
// pendidikanPenjamin: pendidikan_penjamin,
|
||||
// noHp: hp,
|
||||
// nama_jalan: namajalan,
|
||||
// ...rest
|
||||
// }))
|
||||
|
||||
type Patient struct {
|
||||
NoRekamMedis string `json:"no_rekammedis"`
|
||||
NamaPasien string `json:"nama_pasien"`
|
||||
NoKTP *string `json:"no_ktp"` // Nullable string
|
||||
NoBPJS *string `json:"no_bpjs"` // Nullable string
|
||||
TglLahir time.Time `json:"tgl_lahir"`
|
||||
Kelamin int `json:"kelamin"`
|
||||
Kebangsaan *string `json:"kebangsaan"` // Nullable string
|
||||
Agama *int `json:"agama"` // Assuming Agama is an enum, and you'll convert from string to enum ID
|
||||
Suku *string `json:"suku"` // Nullable string
|
||||
Pendidikan *int `json:"pendidikan"` // Nullable int
|
||||
Pekerjaan *int `json:"pekerjaan"` // Assuming Pekerjaan is an enum, and you'll convert from string to enum ID
|
||||
HP *string `json:"hp"` // Nullable string, assume validation happens elsewhere
|
||||
Email *string `json:"email"` // Nullable string
|
||||
StatusNikah *int `json:"status_nikah"` // Assuming StatusKawin is an enum, and you'll convert from string to enum ID
|
||||
Provinsi *string `json:"provinsi"` // Nullable string
|
||||
Kabupaten *string `json:"kabupaten"` // Nullable string
|
||||
Kecamatan *string `json:"kecamatan"` // Nullable string
|
||||
Kelurahan *string `json:"kelurahan"` // Nullable string
|
||||
Kodepos *string `json:"kodepos"` // Nullable string
|
||||
NamaJalan *string `json:"namajalan"` // Nullable string
|
||||
HPPenjamin *string `json:"hp_penjamin"` // Nullable string, assume validation happens elsewhere
|
||||
NamaPenjamin *string `json:"namapenjamin"` // Nullable string
|
||||
KTPPenjamin *string `json:"ktp_penjamin"` // Nullable string
|
||||
HubunganPenjamin *int `json:"hubungan_penjamin"` // Nullable int
|
||||
PendidikanPenjamin *int `json:"pendidikan_penjamin"` // Assuming Pendidikan is an enum, and you'll convert from string to enum ID
|
||||
AlamatPenjamin *string `json:"alamat_penjamin"` // Nullable string
|
||||
}
|
||||
|
||||
func FindValueByLabel(arr []EnumObject, s string) EnumObject {
|
||||
idx := slices.IndexFunc(arr, func(c EnumObject) bool { return c.Label == s })
|
||||
return arr[idx]
|
||||
}
|
63
internal/jwt.go
Normal file
63
internal/jwt.go
Normal file
@ -0,0 +1,63 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
)
|
||||
|
||||
type JwtPayload struct {
|
||||
UserId float64 `json:"id"`
|
||||
NamaLengkap string `json:"nama_lengkap"`
|
||||
NotesId string `json:"notes_id"`
|
||||
FasyankesId float64 `json:"fasyankes_id"`
|
||||
Email string `json:"email"`
|
||||
UserType float64 `json:"user_type"`
|
||||
PPKPelayanan interface{} `json:"ppk_pelayanan"`
|
||||
AlamatFasyankes interface{} `json:"alamat_fasyankes"`
|
||||
}
|
||||
|
||||
func GetPayloadFromContext(ctx context.Context) *JwtPayload {
|
||||
payload, ok := ctx.Value(UserContext).(JwtPayload)
|
||||
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &payload
|
||||
}
|
||||
|
||||
func ParseJWT(s string) JwtPayload {
|
||||
salt := os.Getenv("JWT_SALT")
|
||||
mySecretKey := []byte(salt)
|
||||
|
||||
// Parse the token
|
||||
token, err := jwt.Parse(s, func(token *jwt.Token) (interface{}, error) {
|
||||
return mySecretKey, nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
claims, valid := token.Claims.(jwt.MapClaims)
|
||||
if !valid && !token.Valid {
|
||||
log.Fatal("Invalid token")
|
||||
}
|
||||
|
||||
data := claims["user"].(map[string]interface{})
|
||||
|
||||
parsedToken := JwtPayload{
|
||||
UserId: data["id"].(float64),
|
||||
NamaLengkap: data["namaLengkap"].(string),
|
||||
NotesId: data["notesId"].(string),
|
||||
FasyankesId: data["fasyankesId"].(float64),
|
||||
Email: data["email"].(string),
|
||||
UserType: data["userType"].(float64),
|
||||
PPKPelayanan: data["ppkPelayanan"],
|
||||
AlamatFasyankes: data["alamatFasyankes"],
|
||||
}
|
||||
return parsedToken
|
||||
}
|
26
internal/middleware.go
Normal file
26
internal/middleware.go
Normal file
@ -0,0 +1,26 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type contextKey string
|
||||
|
||||
const UserContext contextKey = "user"
|
||||
|
||||
func AuthMiddleware(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
authHeader := r.Header.Get("Authorization")
|
||||
if authHeader == "" {
|
||||
http.Error(w, "Authorization header is required", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
authToken := strings.Split(authHeader, "Bearer ")[1]
|
||||
ctx := context.WithValue(r.Context(), UserContext, ParseJWT(authToken))
|
||||
req := r.WithContext(ctx)
|
||||
next.ServeHTTP(w, req)
|
||||
})
|
||||
}
|
16
internal/parse_excel.go
Normal file
16
internal/parse_excel.go
Normal file
@ -0,0 +1,16 @@
|
||||
package internal
|
||||
|
||||
import "reflect"
|
||||
|
||||
func ParseExcelValueType[T interface{}](s string) T {
|
||||
var i T
|
||||
|
||||
t := reflect.TypeOf(i)
|
||||
|
||||
switch t.Kind() {
|
||||
case reflect.String:
|
||||
return reflect.ValueOf(s).Convert(t).Interface().(T)
|
||||
}
|
||||
|
||||
return i
|
||||
}
|
53
internal/repository/alamat.repository.go
Normal file
53
internal/repository/alamat.repository.go
Normal file
@ -0,0 +1,53 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.nochill.in/nochill/excel_import_playground/model"
|
||||
"github.com/jackc/pgx/v5"
|
||||
)
|
||||
|
||||
func (q *Queries) CreateAlamat(ctx context.Context, arg model.Alamat) (model.Alamat, error) {
|
||||
createAlamatQuery := `
|
||||
INSERT INTO "Alamat" (
|
||||
kategori,
|
||||
negara,
|
||||
provinsi,
|
||||
kabupaten,
|
||||
kecamatan,
|
||||
kelurahan,
|
||||
kode_pos,
|
||||
nama_jalan,
|
||||
rt,
|
||||
rw,
|
||||
no_hp,
|
||||
no_telpon,
|
||||
pasen_id,
|
||||
status,
|
||||
created_at,
|
||||
updated_at,
|
||||
) VALUES ($1,, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17)
|
||||
RETURNING *
|
||||
`
|
||||
|
||||
row, _ := q.db.Query(ctx, createAlamatQuery,
|
||||
arg.Kategori,
|
||||
arg.Negara,
|
||||
arg.Provinsi,
|
||||
arg.Kabupaten,
|
||||
arg.Kecamatan,
|
||||
arg.Kelurahan,
|
||||
arg.Kode_pos,
|
||||
arg.Nama_jalan,
|
||||
arg.Rt,
|
||||
arg.Rw,
|
||||
arg.No_hp,
|
||||
arg.No_telpon,
|
||||
arg.Pasien_id,
|
||||
arg.Status,
|
||||
)
|
||||
|
||||
result, err := pgx.CollectExactlyOneRow[model.Alamat](row, pgx.RowToStructByName[model.Alamat])
|
||||
|
||||
return result, err
|
||||
}
|
55
internal/repository/db.go
Normal file
55
internal/repository/db.go
Normal file
@ -0,0 +1,55 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.nochill.in/nochill/excel_import_playground/model"
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgconn"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
)
|
||||
|
||||
type Querier interface {
|
||||
FindLastPatientInCertainFasyankes(ctx context.Context, fasyankes_id int32) (model.Patient, error)
|
||||
FindPatientByNoRm(ctx context.Context, noRm string) (model.Patient, error)
|
||||
FindPatientByNik(ctx context.Context, nik string) (model.Patient, error)
|
||||
FindPatientByBPJSCode(ctx context.Context, BPJSCode string) (model.Patient, error)
|
||||
UpdatePatientNik(ctx context.Context, nik *string, patientId int32) error
|
||||
UpdatePatient(ctx context.Context, arg UpdatePatientParams, patientId int32) (model.Patient, error)
|
||||
// UpdatePatient(ctx context.Context, patientId int32, arg UpdatePatientParams) (model.Patient, error)
|
||||
GenerateNoRm(ctx context.Context, fasyankesId int32) (string, error)
|
||||
CreateKeluarga(ctx context.Context, arg model.Keluarga) (model.Keluarga, error)
|
||||
CreateAlamat(ctx context.Context, arg model.Alamat) (model.Alamat, error)
|
||||
FindWilayahByName(ctx context.Context, name string) (model.Wilayah, error)
|
||||
}
|
||||
|
||||
type DBTX interface {
|
||||
Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error)
|
||||
Query(context.Context, string, ...interface{}) (pgx.Rows, error)
|
||||
QueryRow(context.Context, string, ...interface{}) pgx.Row
|
||||
}
|
||||
|
||||
type Queries struct {
|
||||
db DBTX
|
||||
}
|
||||
|
||||
type UpdateableField[T any] struct {
|
||||
IsFilled bool `default:"false"`
|
||||
Value T `default:"nil"`
|
||||
}
|
||||
|
||||
func New(db DBTX) *Queries {
|
||||
return &Queries{db: db}
|
||||
}
|
||||
|
||||
func NewTx(db DBTX) *Queries {
|
||||
return &Queries{db: db}
|
||||
}
|
||||
|
||||
func (q *Queries) WithTx(tx pgx.Tx) *Queries {
|
||||
return &Queries{
|
||||
db: tx,
|
||||
}
|
||||
}
|
||||
|
||||
var DbPool *pgxpool.Pool
|
46
internal/repository/keluarga.repository.go
Normal file
46
internal/repository/keluarga.repository.go
Normal file
@ -0,0 +1,46 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.nochill.in/nochill/excel_import_playground/model"
|
||||
"github.com/jackc/pgx/v5"
|
||||
)
|
||||
|
||||
func (q *Queries) CreateKeluarga(ctx context.Context, arg model.Keluarga) (model.Keluarga, error) {
|
||||
createKeluargaQuery := `
|
||||
INSERT INTO "Keluarga"(
|
||||
pasien_id,
|
||||
nama,
|
||||
hubungan,
|
||||
no_identitas,
|
||||
no_hp,
|
||||
kota_lahir,
|
||||
alamat,
|
||||
tanggal_lahir,
|
||||
jenis_kelamin,
|
||||
pendidikan,
|
||||
pekerjaan,
|
||||
email,
|
||||
) VALUES ( $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
|
||||
`
|
||||
|
||||
row, _ := q.db.Query(ctx, createKeluargaQuery,
|
||||
arg.PasienId,
|
||||
arg.Nama,
|
||||
arg.Hubungan,
|
||||
arg.NoIdentitas,
|
||||
arg.NoHp,
|
||||
arg.KotaLahir,
|
||||
arg.Alamat,
|
||||
arg.TanggalLahir,
|
||||
arg.JenisKelamin,
|
||||
arg.Pendidikan,
|
||||
arg.Pekerjaan,
|
||||
arg.Email,
|
||||
)
|
||||
|
||||
result, err := pgx.CollectExactlyOneRow[model.Keluarga](row, pgx.RowToStructByName[model.Keluarga])
|
||||
|
||||
return result, err
|
||||
}
|
485
internal/repository/patient.repository.go
Normal file
485
internal/repository/patient.repository.go
Normal file
@ -0,0 +1,485 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.nochill.in/nochill/excel_import_playground/model"
|
||||
"git.nochill.in/nochill/excel_import_playground/util"
|
||||
"github.com/henvic/pgq"
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
func (q *Queries) FindLastPatientInCertainFasyankes(ctx context.Context, fasyankes_id int32) (model.Patient, error) {
|
||||
findLastPasienQuery := `
|
||||
SELECT * FROM "Pasien" p
|
||||
WHERE fasyankes_id = $1
|
||||
ORDER BY p.id DESC
|
||||
LIMIT(1)
|
||||
`
|
||||
row, _ := q.db.Query(ctx, findLastPasienQuery, fasyankes_id)
|
||||
result, err := pgx.CollectExactlyOneRow[model.Patient](row, pgx.RowToStructByName[model.Patient])
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (q *Queries) FindPatientByBPJSCode(ctx context.Context, BPJSCode string) (model.Patient, error) {
|
||||
findPatientByBPJSCode := `
|
||||
SELECT * FROM "Pasien" p
|
||||
WHERE no_kartu_peserta_bpjs = $1
|
||||
`
|
||||
|
||||
row, _ := q.db.Query(ctx, findPatientByBPJSCode, BPJSCode)
|
||||
result, err := pgx.CollectExactlyOneRow[model.Patient](row, pgx.RowToStructByName[model.Patient])
|
||||
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (q *Queries) FindPatientByNoRm(ctx context.Context, noRm string) (model.Patient, error) {
|
||||
findPasienByNoRmQuery := `
|
||||
SELECT * FROM "Pasien" p
|
||||
WHERE no_rm = $1
|
||||
`
|
||||
row, _ := q.db.Query(ctx, findPasienByNoRmQuery, noRm)
|
||||
result, err := pgx.CollectExactlyOneRow[model.Patient](row, pgx.RowToStructByName[model.Patient])
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (q *Queries) FindPatientByNik(ctx context.Context, nik string) (model.Patient, error) {
|
||||
findPasienByNikQuery := `
|
||||
SELECT * FROM "Pasien" p
|
||||
WHERE nik = $1
|
||||
`
|
||||
row, _ := q.db.Query(ctx, findPasienByNikQuery, nik)
|
||||
result, err := pgx.CollectExactlyOneRow[model.Patient](row, pgx.RowToStructByName[model.Patient])
|
||||
return result, err
|
||||
}
|
||||
|
||||
type UpdatePatientParams struct {
|
||||
NoRm UpdateableField[string] `json:"no_rm" db:"no_rm"`
|
||||
NamaPasien UpdateableField[string] `json:"nama_pasien" db:"nama_pasien"`
|
||||
JenisIdentitas UpdateableField[pgtype.Int4] `json:"jenis_identitas" db:"jenis_identitas"`
|
||||
NoIdentitas UpdateableField[pgtype.Text] `json:"no_identitas" db:"no_identitas"`
|
||||
FotoProfil UpdateableField[pgtype.Text] `json:"foto_profil" db:"foto_profil"`
|
||||
FotoKtp UpdateableField[pgtype.Text] `json:"foto_ktp" db:"foto_ktp"`
|
||||
KotaLahir UpdateableField[pgtype.Int4] `json:"kota_lahir" db:"kota_lahir"`
|
||||
TanggalLahir UpdateableField[time.Time] `json:"tanggal_lahir" db:"tanggal_lahir"`
|
||||
JenisKelamin UpdateableField[pgtype.Int4] `json:"jenis_kelamin" db:"jenis_kelamin"`
|
||||
Suku UpdateableField[pgtype.Int4] `json:"suku" db:"suku"`
|
||||
Agama UpdateableField[pgtype.Int4] `json:"agama" db:"agama"`
|
||||
Kebangsaan UpdateableField[pgtype.Int4] `json:"kebangsaan" db:"kebangsaan"`
|
||||
Bahasa UpdateableField[pgtype.Int4] `json:"bahasa" db:"bahasa"`
|
||||
Pendidikan UpdateableField[pgtype.Int4] `json:"pendidikan" db:"pendidikan"`
|
||||
StatusPerkawinan UpdateableField[pgtype.Int4] `json:"status_perkawinan" db:"status_perkawinan"`
|
||||
Email UpdateableField[pgtype.Text] `json:"email" db:"email"`
|
||||
Pekerjaan UpdateableField[pgtype.Int4] `json:"pekerjaan" db:"pekerjaan"`
|
||||
NoHp UpdateableField[pgtype.Text] `json:"no_hp" db:"no_hp"`
|
||||
IsDeleted UpdateableField[bool] `json:"is_deleted" db:"is_deleted"`
|
||||
FasyankesID UpdateableField[int] `json:"fasyankes_id" db:"fasyankes_id"`
|
||||
Nik UpdateableField[pgtype.Text] `json:"nik" db:"nik"`
|
||||
NoKk UpdateableField[pgtype.Text] `json:"no_kk" db:"no_kk"`
|
||||
NoKartuPesertaBPJS UpdateableField[pgtype.Text] `json:"no_kartu_peserta_bpjs" db:"no_kartu_peserta_bpjs"`
|
||||
UpdateBy int `json:"update_by" db:"update_by"`
|
||||
}
|
||||
|
||||
func (q *Queries) UpdatePatient(ctx context.Context, arg UpdatePatientParams, patientId int32) (model.Patient, error) {
|
||||
builder := pgq.Update("\"Pasien\"").Set("update_by", arg.UpdateBy).Set("updated_at", time.Now().UTC())
|
||||
|
||||
if arg.NoRm.IsFilled {
|
||||
builder.Set("no_rm", arg.NoRm.Value)
|
||||
}
|
||||
if arg.NamaPasien.IsFilled {
|
||||
builder = builder.Set("nama_pasien", arg.NamaPasien.Value)
|
||||
}
|
||||
if arg.JenisIdentitas.IsFilled {
|
||||
builder = builder.Set("jenis_identitas", arg.JenisIdentitas.Value)
|
||||
}
|
||||
if arg.NoIdentitas.IsFilled {
|
||||
builder = builder.Set("no_identitas", arg.NoIdentitas.Value)
|
||||
}
|
||||
if arg.FotoProfil.IsFilled {
|
||||
builder = builder.Set("foto_profil", arg.FotoProfil.Value)
|
||||
}
|
||||
if arg.FotoKtp.IsFilled {
|
||||
builder = builder.Set("foto_ktp", arg.FotoKtp.Value)
|
||||
}
|
||||
if arg.KotaLahir.IsFilled {
|
||||
builder = builder.Set("kota_lahir", arg.KotaLahir.Value)
|
||||
}
|
||||
if arg.TanggalLahir.IsFilled {
|
||||
builder = builder.Set("tanggal_lahir", arg.TanggalLahir.Value)
|
||||
}
|
||||
if arg.JenisKelamin.IsFilled {
|
||||
builder = builder.Set("jenis_kelamin", arg.JenisKelamin.Value)
|
||||
}
|
||||
if arg.Suku.IsFilled {
|
||||
builder = builder.Set("suku", arg.Suku.Value)
|
||||
}
|
||||
if arg.Agama.IsFilled {
|
||||
builder = builder.Set("agama", arg.Agama.Value)
|
||||
}
|
||||
if arg.Kebangsaan.IsFilled {
|
||||
builder = builder.Set("kebangsaan", arg.Kebangsaan.Value)
|
||||
}
|
||||
if arg.Bahasa.IsFilled {
|
||||
builder = builder.Set("bahasa", arg.Bahasa.Value)
|
||||
}
|
||||
if arg.Pendidikan.IsFilled {
|
||||
builder = builder.Set("pendidikan", arg.Pendidikan.Value)
|
||||
}
|
||||
if arg.StatusPerkawinan.IsFilled {
|
||||
builder = builder.Set("status_perkawinan", arg.StatusPerkawinan.Value)
|
||||
}
|
||||
if arg.Email.IsFilled {
|
||||
builder = builder.Set("email", arg.Email.Value)
|
||||
}
|
||||
if arg.Pekerjaan.IsFilled {
|
||||
builder = builder.Set("pekerjaan", arg.Pekerjaan.Value)
|
||||
}
|
||||
if arg.NoHp.IsFilled {
|
||||
builder = builder.Set("no_hp", arg.NoHp.Value)
|
||||
}
|
||||
if arg.IsDeleted.IsFilled {
|
||||
builder = builder.Set("is_deleted", arg.IsDeleted.Value)
|
||||
}
|
||||
if arg.FasyankesID.IsFilled {
|
||||
builder = builder.Set("fasyankes_id", arg.FasyankesID.Value)
|
||||
}
|
||||
if arg.Nik.IsFilled {
|
||||
builder = builder.Set("nik", arg.Nik.Value)
|
||||
}
|
||||
if arg.NoKk.IsFilled {
|
||||
builder = builder.Set("no_kk", arg.NoKk.Value)
|
||||
}
|
||||
if arg.NoKartuPesertaBPJS.IsFilled {
|
||||
builder = builder.Set("no_kartu_peserta_bpjs", arg.NoKartuPesertaBPJS.Value)
|
||||
}
|
||||
|
||||
query, args, err := builder.Where(pgq.Eq{"id": patientId}).Suffix("RETURNING *").SQL()
|
||||
|
||||
if err != nil {
|
||||
return model.Patient{}, err
|
||||
}
|
||||
|
||||
row, _ := q.db.Query(ctx, query, args...)
|
||||
result, err := pgx.CollectExactlyOneRow[model.Patient](row, pgx.RowToStructByName[model.Patient])
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (q *Queries) UpdatePatientNik(ctx context.Context, nik *string, patientId int32) error {
|
||||
updatePatientQuery := `
|
||||
UPDATE "Pasien" p
|
||||
SET nik = $1
|
||||
WHERE id = $2
|
||||
`
|
||||
|
||||
_, err := q.db.Exec(ctx, updatePatientQuery, nik, patientId)
|
||||
return err
|
||||
|
||||
}
|
||||
|
||||
// type UpdatePatientParams struct {
|
||||
// NoRm string `json:"no_rm" db:"no_rm"`
|
||||
// NamaPasien string `json:"nama_pasien" db:"nama_pasien"`
|
||||
// JenisIdentitas pgtype.Int4 `json:"jenis_identitas" db:"jenis_identitas"`
|
||||
// NoIdentitas pgtype.Text `json:"no_identitas" db:"no_identitas"`
|
||||
// FotoProfil pgtype.Text `json:"foto_profil" db:"foto_profil"`
|
||||
// FotoKtp pgtype.Text `json:"foto_ktp" db:"foto_ktp"`
|
||||
// KotaLahir pgtype.Int4 `json:"kota_lahir" db:"kota_lahir"`
|
||||
// TanggalLahir *time.Time `json:"tanggal_lahir" db:"tanggal_lahir"`
|
||||
// JenisKelamin pgtype.Int4 `json:"jenis_kelamin" db:"jenis_kelamin"`
|
||||
// Suku pgtype.Int4 `json:"suku" db:"suku"`
|
||||
// Agama pgtype.Int4 `json:"agama" db:"agama"`
|
||||
// Kebangsaan pgtype.Int4 `json:"kebangsaan" db:"kebangsaan"`
|
||||
// Bahasa pgtype.Int4 `json:"bahasa" db:"bahasa"`
|
||||
// Pendidikan pgtype.Int4 `json:"pendidikan" db:"pendidikan"`
|
||||
// StatusPerkawinan pgtype.Int4 `json:"status_perkawinan" db:"status_perkawinan"`
|
||||
// Email pgtype.Text `json:"email" db:"email"`
|
||||
// Pekerjaan pgtype.Int4 `json:"pekerjaan" db:"pekerjaan"`
|
||||
// NoHp pgtype.Text `json:"no_hp" db:"no_hp"`
|
||||
// IsDeleted *bool `json:"is_deleted" db:"is_deleted"`
|
||||
// FasyankesID int `json:"fasyankes_id" db:"fasyankes_id"`
|
||||
// Nik pgtype.Text `json:"nik" db:"nik"`
|
||||
// NoKk pgtype.Text `json:"no_kk" db:"no_kk"`
|
||||
// NoKartuPesertaBPJS pgtype.Text `json:"no_kartu_peserta_bpjs" db:"no_kartu_peserta_bpjs"`
|
||||
// UpdateBy int `json:"update_by" db:"update_by"`
|
||||
// UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
|
||||
// }
|
||||
|
||||
// func (q *Queries) UpdatePatient(ctx context.Context, patientId int32, arg UpdatePatientParams) (model.Patient, error) {
|
||||
// updatePatientQuery := `
|
||||
// UPDATE "Pasien" p
|
||||
// SET
|
||||
// no_rm = $1,
|
||||
// nama_pasien = $2,
|
||||
// jenis_identitas = $3,
|
||||
// no_identitas = $4,
|
||||
// foto_profil = $5,
|
||||
// foto_ktp = $6,
|
||||
// kota_lahir = $7,
|
||||
// tanggal_lahir = $8,
|
||||
// jenis_kelamin = $9,
|
||||
// suku = $10,
|
||||
// agama = $11,
|
||||
// kebangsaan = $12,
|
||||
// bahasa = $13,
|
||||
// pendidikan = $14,
|
||||
// status_perkawinan = $15,
|
||||
// email = $16,
|
||||
// pekerjaan = $17,
|
||||
// no_hp = $18,
|
||||
// is_deleted = $19,
|
||||
// fasyankes_id = $20,
|
||||
// nik = $21,
|
||||
// no_kk = $22,
|
||||
// no_kartu_peserta_bpjs = $23,
|
||||
// update_by = $24,
|
||||
// updated_at = $25
|
||||
// WHERE id = $26
|
||||
// `
|
||||
|
||||
// row, _ := q.db.Query(ctx, updatePatientQuery,
|
||||
// arg.NoRm,
|
||||
// arg.NamaPasien,
|
||||
// arg.JenisIdentitas,
|
||||
// arg.NoIdentitas,
|
||||
// arg.FotoProfil,
|
||||
// arg.FotoKtp,
|
||||
// arg.KotaLahir,
|
||||
// arg.TanggalLahir,
|
||||
// arg.JenisKelamin,
|
||||
// arg.Suku,
|
||||
// arg.Agama,
|
||||
// arg.Kebangsaan,
|
||||
// arg.Bahasa,
|
||||
// arg.Pendidikan,
|
||||
// arg.StatusPerkawinan,
|
||||
// arg.Email,
|
||||
// arg.Pekerjaan,
|
||||
// arg.NoHp,
|
||||
// arg.IsDeleted,
|
||||
// arg.FasyankesID,
|
||||
// arg.Nik,
|
||||
// arg.NoKk,
|
||||
// arg.NoKartuPesertaBPJS,
|
||||
// arg.UpdateBy,
|
||||
// arg.UpdatedAt,
|
||||
// patientId,
|
||||
// )
|
||||
|
||||
// result, err := pgx.CollectExactlyOneRow[model.Patient](row, pgx.RowToStructByName[model.Patient])
|
||||
|
||||
// return result, err
|
||||
// }
|
||||
|
||||
func (q *Queries) CreatePatient(ctx context.Context, arg model.Patient) (model.Patient, error) {
|
||||
createPasienQuery := `
|
||||
INSERT INTO "Pasien"(
|
||||
no_rm,
|
||||
nama_pasien,
|
||||
jenis_identitas,
|
||||
no_identitas,
|
||||
foto_profil,
|
||||
foto_ktp,
|
||||
kota_lahir,
|
||||
tanggal_lahir,
|
||||
jenis_kelamin,
|
||||
suku,
|
||||
agama,
|
||||
kebangsaan,
|
||||
bahasa,
|
||||
pendidikan,
|
||||
status_perkawinan,
|
||||
email,
|
||||
pekerjaan,
|
||||
no_hp,
|
||||
is_deleted,
|
||||
fasyankes_id,
|
||||
nik,
|
||||
no_kk,
|
||||
no_kartu_peserta_bpjs,
|
||||
create_by,
|
||||
update_by
|
||||
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16)
|
||||
RETURNING *;
|
||||
`
|
||||
|
||||
row, _ := q.db.Query(ctx, createPasienQuery,
|
||||
arg.NoRm,
|
||||
arg.NamaPasien,
|
||||
arg.JenisIdentitas,
|
||||
arg.NoIdentitas,
|
||||
arg.FotoProfil,
|
||||
arg.FotoKtp,
|
||||
arg.KotaLahir,
|
||||
arg.TanggalLahir,
|
||||
arg.JenisKelamin,
|
||||
arg.Suku,
|
||||
arg.Agama,
|
||||
arg.Kebangsaan,
|
||||
arg.Bahasa,
|
||||
arg.Pendidikan,
|
||||
arg.StatusPerkawinan,
|
||||
arg.Email,
|
||||
arg.Pekerjaan,
|
||||
arg.NoHp,
|
||||
arg.IsDeleted,
|
||||
arg.FasyankesID,
|
||||
arg.Nik,
|
||||
arg.NoKk,
|
||||
arg.NoKartuPesertaBPJS,
|
||||
arg.CreateBy,
|
||||
arg.UpdateBy,
|
||||
arg.CreatedAt,
|
||||
arg.UpdatedAt,
|
||||
)
|
||||
|
||||
result, err := pgx.CollectExactlyOneRow[model.Patient](row, pgx.RowToStructByName[model.Patient])
|
||||
|
||||
return result, err
|
||||
}
|
||||
|
||||
type ImportDataPasienParams struct {
|
||||
NoRekamMedis string
|
||||
NamaPasien string
|
||||
Nik pgtype.Text
|
||||
NoBPJS pgtype.Text
|
||||
TpLahir pgtype.Text
|
||||
TglLahir time.Time
|
||||
Kelamin int8
|
||||
Kebangsaan *int8
|
||||
Agama *int8
|
||||
Suku *int32
|
||||
Pendidikan *int8
|
||||
Pekerjaan *int8
|
||||
Hp pgtype.Text
|
||||
Email pgtype.Text
|
||||
StatusNikah *int8
|
||||
Provinsi *string
|
||||
Kabupaten *int32
|
||||
Kecamatan *int32
|
||||
Kelurahan *int32
|
||||
Kodepos *int32
|
||||
NamaJalan pgtype.Text
|
||||
HpPenjamin pgtype.Text
|
||||
NamaPenjamin pgtype.Text
|
||||
KtpPenjamin pgtype.Text
|
||||
HubunganPenjamin *int8
|
||||
PendidikanPenjamin *int8
|
||||
AlamatPenjamin pgtype.Text
|
||||
}
|
||||
|
||||
func (store *SQLStore) ImportPatientTx(ctx context.Context, params ImportDataPasienParams) error {
|
||||
err := store.execTx(ctx, func(q *Queries) error {
|
||||
var err error
|
||||
|
||||
tempNilInt := int8(util.NilIntVal)
|
||||
|
||||
if params.Pendidikan == nil {
|
||||
params.Pendidikan = &tempNilInt
|
||||
}
|
||||
|
||||
if params.Agama == nil {
|
||||
params.Agama = &tempNilInt
|
||||
}
|
||||
|
||||
if params.Pekerjaan == nil {
|
||||
params.Pekerjaan = &tempNilInt
|
||||
}
|
||||
|
||||
if params.StatusNikah == nil {
|
||||
params.StatusNikah = &tempNilInt
|
||||
}
|
||||
|
||||
patient, err := q.CreatePatient(ctx, model.Patient{
|
||||
NoRm: params.NoRekamMedis,
|
||||
NamaPasien: params.NamaPasien,
|
||||
Pendidikan: pgtype.Int4{Valid: params.Pendidikan != nil, Int32: int32(*params.Pendidikan)},
|
||||
TanggalLahir: params.TglLahir,
|
||||
Nik: params.Nik,
|
||||
Agama: pgtype.Int4{Valid: params.Agama != nil, Int32: int32(*params.Agama)},
|
||||
NoHp: params.Hp,
|
||||
Pekerjaan: pgtype.Int4{Valid: params.Pekerjaan != nil, Int32: int32(*params.Agama)},
|
||||
Email: params.Email,
|
||||
NoKartuPesertaBPJS: params.NoBPJS,
|
||||
JenisKelamin: params.Kelamin,
|
||||
StatusPerkawinan: pgtype.Int4{Valid: params.StatusNikah != nil, Int32: int32(*params.StatusNikah)},
|
||||
IsDeleted: false,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if params.NamaJalan.Valid {
|
||||
var provinsi_id *int32
|
||||
provinsi, err := q.FindWilayahByName(ctx, *params.Provinsi)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if provinsi.Id == 0 {
|
||||
provinsi_id = nil
|
||||
} else {
|
||||
provinsi_id = &provinsi.Id
|
||||
}
|
||||
|
||||
_, err = q.CreateAlamat(ctx, model.Alamat{
|
||||
Provinsi: provinsi_id,
|
||||
Nama_jalan: ¶ms.NamaJalan.String,
|
||||
Pasien_id: int32(patient.ID),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if params.HubunganPenjamin != nil && params.NamaPenjamin.Valid {
|
||||
_, err = q.CreateKeluarga(ctx, model.Keluarga{
|
||||
Id: int32(patient.ID),
|
||||
Nama: ¶ms.NamaPenjamin.String,
|
||||
Hubungan: params.HubunganPenjamin,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (q *Queries) GenerateNoRm(ctx context.Context, fasyankesId int32) (string, error) {
|
||||
lastPasien, err := q.FindLastPatientInCertainFasyankes(ctx, fasyankesId)
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return genNoRm(&lastPasien.NoRm), nil
|
||||
}
|
||||
|
||||
func genNoRm(lastNoRm *string) string {
|
||||
var tempNoRm string
|
||||
|
||||
if lastNoRm != nil {
|
||||
tempNoRm = *lastNoRm
|
||||
} else {
|
||||
tempNoRm = "1"
|
||||
}
|
||||
|
||||
length := strings.IndexFunc(tempNoRm, func(r rune) bool {
|
||||
return r != '0'
|
||||
})
|
||||
|
||||
return util.Pad(tempNoRm, int32(length))
|
||||
}
|
||||
|
||||
// func FindPatientBy
|
43
internal/repository/store.go
Normal file
43
internal/repository/store.go
Normal file
@ -0,0 +1,43 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
)
|
||||
|
||||
type Store interface {
|
||||
Querier
|
||||
ImportPatientTx(ctx context.Context, params ImportDataPasienParams) error
|
||||
}
|
||||
|
||||
type SQLStore struct {
|
||||
*Queries
|
||||
pool *pgxpool.Pool
|
||||
}
|
||||
|
||||
func NewStore(pool *pgxpool.Pool) Store {
|
||||
return &SQLStore{
|
||||
pool: pool,
|
||||
Queries: New(pool),
|
||||
}
|
||||
}
|
||||
|
||||
// TRANSACTION QUERY FUNCTION
|
||||
func (store *SQLStore) execTx(ctx context.Context, fn func(*Queries) error) error {
|
||||
tx, err := store.pool.Begin(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
q := NewTx(tx)
|
||||
err = fn(q)
|
||||
if err != nil {
|
||||
if rbErr := tx.Rollback(ctx); rbErr != nil {
|
||||
return fmt.Errorf("tx err: %v, rb err : %v", err, rbErr)
|
||||
}
|
||||
return err
|
||||
}
|
||||
return tx.Commit(ctx)
|
||||
}
|
20
internal/repository/wilayah.repository.go
Normal file
20
internal/repository/wilayah.repository.go
Normal file
@ -0,0 +1,20 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.nochill.in/nochill/excel_import_playground/model"
|
||||
"github.com/jackc/pgx/v5"
|
||||
)
|
||||
|
||||
func (q *Queries) FindWilayahByName(ctx context.Context, name string) (model.Wilayah, error) {
|
||||
findWilayaByNameQuery := `
|
||||
SELECT * FROM "Wilayah"
|
||||
WHERE NamaWilayah = $1
|
||||
`
|
||||
|
||||
row, _ := q.db.Query(ctx, findWilayaByNameQuery, name)
|
||||
result, err := pgx.CollectExactlyOneRow[model.Wilayah](row, pgx.RowToStructByName[model.Wilayah])
|
||||
|
||||
return result, err
|
||||
}
|
333
internal/rest/handler.go
Normal file
333
internal/rest/handler.go
Normal file
@ -0,0 +1,333 @@
|
||||
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/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 {
|
||||
errorMsg = append(errorMsg, map[string]any{
|
||||
"no_rm": value.NoRekamMedis,
|
||||
"status": "CRITICAL",
|
||||
"message": fmt.Sprintf("Terjadi kesalahan sistem, mencari data pasien %v", err),
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
||||
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 {
|
||||
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.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",
|
||||
"message": fmt.Sprintf("NIK kembar dengan pasien: %s, mohon dicek kembali current user: %v", patient.NoRm, value),
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if value.NoBPJS.Valid {
|
||||
patient, err := repository.Store.FindPatientByBPJSCode(s.Store, r.Context(), value.NoBPJS.String)
|
||||
|
||||
if err != nil {
|
||||
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),
|
||||
})
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
errorMsg = append(errorMsg, map[string]any{
|
||||
"no_rm": value.NoRekamMedis,
|
||||
"status": "WARNING",
|
||||
"message": fmt.Sprintf("No KartuBPJS ada yang sama dengan pasien: %s, mohon dicek kembali. current user: %v", patient.NoRm, value),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
err = repository.Store.ImportPatientTx(s.Store, r.Context(), value)
|
||||
|
||||
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",
|
||||
|
||||
// "contentType": contentType,
|
||||
// "patient": tempArr,
|
||||
"errorData": errorMsg,
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
}
|
15
internal/rest/server.go
Normal file
15
internal/rest/server.go
Normal file
@ -0,0 +1,15 @@
|
||||
package rest
|
||||
|
||||
import "git.nochill.in/nochill/excel_import_playground/internal/repository"
|
||||
|
||||
type Server struct {
|
||||
Store repository.Store
|
||||
}
|
||||
|
||||
func NewServer(store repository.Store) (*Server, error) {
|
||||
server := &Server{
|
||||
Store: store,
|
||||
}
|
||||
|
||||
return server, nil
|
||||
}
|
115
main.go
Normal file
115
main.go
Normal file
@ -0,0 +1,115 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"runtime"
|
||||
"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/internal/rest"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
"github.com/joho/godotenv"
|
||||
)
|
||||
|
||||
func main() {
|
||||
runtime.GOMAXPROCS(5)
|
||||
var wait time.Duration
|
||||
flag.DurationVar(&wait, "graceful-timeout", time.Second*15, "the duration for which the server gracefully wait for existing connections to finish - e.g. 15s or 1m")
|
||||
flag.Parse()
|
||||
|
||||
err := godotenv.Load()
|
||||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
|
||||
_ = os.Getenv("JWT_SALT")
|
||||
DATABASE_URL := os.Getenv("DATABASE_URL")
|
||||
APP_HOST := os.Getenv("APP_HOST")
|
||||
|
||||
poolConfig, err := pgxpool.ParseConfig(DATABASE_URL)
|
||||
if err != nil {
|
||||
log.Fatal("ENV DATABASE_URL NOT FOUND", err)
|
||||
}
|
||||
dbConn, err := pgxpool.NewWithConfig(context.Background(), poolConfig)
|
||||
|
||||
if err != nil {
|
||||
log.Fatal("cannot connect to db: ", err)
|
||||
}
|
||||
|
||||
store := repository.NewStore(dbConn)
|
||||
|
||||
server, err := rest.NewServer(store)
|
||||
|
||||
if err != nil {
|
||||
log.Fatal("Somethng wrong while try to start Server", err)
|
||||
}
|
||||
|
||||
r := mux.NewRouter()
|
||||
r.Use(internal.AuthMiddleware)
|
||||
r.HandleFunc("/", homeRoute).Methods("GET")
|
||||
r.HandleFunc("/import-pasien", server.ImportPatientHandler).Methods("POST")
|
||||
r.HandleFunc("/update-pasien/{id}", server.UpdatePatient).Methods("PATCH")
|
||||
|
||||
// r.HandleFunc("/foo", fooHandler).Methods(http.MethodGet, http.MethodPut, http.MethodPatch, http.MethodOptions)
|
||||
// r.Use(mux.CORSMethodMiddleware(r))
|
||||
|
||||
// val := internal.FindValueByLabel("PNS")
|
||||
|
||||
// fmt.Println(val.ID)
|
||||
|
||||
srv := &http.Server{
|
||||
Handler: r,
|
||||
Addr: APP_HOST,
|
||||
// Good practice: enforce timeouts for servers you create!
|
||||
WriteTimeout: 15 * time.Second,
|
||||
ReadTimeout: 15 * time.Second,
|
||||
}
|
||||
|
||||
go func() {
|
||||
host := fmt.Sprintf("Server running on %s", APP_HOST)
|
||||
fmt.Println(host)
|
||||
if err := srv.ListenAndServe(); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
}()
|
||||
|
||||
c := make(chan os.Signal, 1)
|
||||
// We'll accept graceful shutdowns when quit via SIGINT (Ctrl+C)
|
||||
// SIGKILL, SIGQUIT or SIGTERM (Ctrl+/) will not be caught.
|
||||
signal.Notify(c, os.Interrupt)
|
||||
|
||||
// Block until we receive our signal.
|
||||
<-c
|
||||
|
||||
// Create a deadline to wait for.
|
||||
ctx, cancel := context.WithTimeout(context.Background(), wait)
|
||||
defer repository.DbPool.Close()
|
||||
defer cancel()
|
||||
// Doesn't block if no connections, but will otherwise wait
|
||||
// until the timeout deadline.
|
||||
srv.Shutdown(ctx)
|
||||
// Optionally, you could run srv.Shutdown in a goroutine and block on
|
||||
// <-ctx.Done() if your application should wait for other services
|
||||
// to finalize based on context cancellation.
|
||||
log.Println("shutting down")
|
||||
os.Exit(0)
|
||||
|
||||
}
|
||||
|
||||
func homeRoute(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
res := map[string]any{
|
||||
"halo": "halo",
|
||||
}
|
||||
json.NewEncoder(w).Encode(res)
|
||||
|
||||
}
|
24
model/alamat.go
Normal file
24
model/alamat.go
Normal file
@ -0,0 +1,24 @@
|
||||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
type Alamat struct {
|
||||
Id *int32 `json:"id,omitempty"`
|
||||
Kategori *int32 `json:"kategori,omitempty"`
|
||||
Negara *int32 `json:"negara,omitempty"`
|
||||
Provinsi *int32 `json:"provinsi,omitempty"`
|
||||
Kabupaten *int32 `json:"kabupaten,omitempty"`
|
||||
Kecamatan *int32 `json:"kecamatan,omitempty"`
|
||||
Kelurahan *int32 `json:"kelurahan,omitempty"`
|
||||
Kode_pos *string `json:"kode_pos,omitempty"`
|
||||
Nama_jalan *string `json:"nama_jalan,omitempty"`
|
||||
Rt *string `json:"rt,omitempty"`
|
||||
Rw *string `json:"rw,omitempty"`
|
||||
No_hp *string `json:"no_hp,omitempty"`
|
||||
No_telpon *string `json:"no_telpon,omitempty"`
|
||||
Pasien_id int32 `json:"pasen_id"`
|
||||
Status *bool `json:"status,omitempty"`
|
||||
Created_at time.Time `json:"created_at"`
|
||||
Updated_at time.Time `json:"updated_at"`
|
||||
Is_deleted *bool `json:"is_deleted,omitempty"`
|
||||
}
|
1
model/db.go
Normal file
1
model/db.go
Normal file
@ -0,0 +1 @@
|
||||
package model
|
19
model/keluarga.go
Normal file
19
model/keluarga.go
Normal file
@ -0,0 +1,19 @@
|
||||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
type Keluarga struct {
|
||||
Id int32 `json:"id"`
|
||||
PasienId int32 `json:"pasien_id"`
|
||||
Nama *string `json:"nama,omitempty"`
|
||||
Hubungan *int8 `json:"hubungan,omitempty"`
|
||||
NoIdentitas *string `json:"no_identitas,omitempty"`
|
||||
NoHp *string `json:"no_hp,omitempty"`
|
||||
KotaLahir *int32 `json:"kota_lahir,omitempty"`
|
||||
Alamat *string `json:"alamat,omitempty"`
|
||||
TanggalLahir time.Time `json:"tanggal_lahir,omitempty"`
|
||||
JenisKelamin *int32 `json:"jenis_kelamin,omitempty"`
|
||||
Pendidikan *int32 `json:"pendidikan,omitempty"`
|
||||
Pekerjaan *int32 `json:"pekerjaan,omitempty"`
|
||||
Email *string `json:"email,omitempty"`
|
||||
}
|
38
model/patient.go
Normal file
38
model/patient.go
Normal file
@ -0,0 +1,38 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
)
|
||||
|
||||
type Patient struct {
|
||||
ID int `json:"id" db:"id"`
|
||||
NoRm string `json:"no_rm" db:"no_rm"`
|
||||
NamaPasien string `json:"nama_pasien" db:"nama_pasien"`
|
||||
JenisIdentitas pgtype.Int4 `json:"jenis_identitas" db:"jenis_identitas"`
|
||||
NoIdentitas pgtype.Text `json:"no_identitas" db:"no_identitas"`
|
||||
FotoProfil pgtype.Text `json:"foto_profil" db:"foto_profil"`
|
||||
FotoKtp pgtype.Text `json:"foto_ktp" db:"foto_ktp"`
|
||||
KotaLahir pgtype.Int4 `json:"kota_lahir" db:"kota_lahir"`
|
||||
TanggalLahir time.Time `json:"tanggal_lahir" db:"tanggal_lahir"`
|
||||
JenisKelamin int8 `json:"jenis_kelamin" db:"jenis_kelamin"`
|
||||
Suku pgtype.Int4 `json:"suku" db:"suku"`
|
||||
Agama pgtype.Int4 `json:"agama" db:"agama"`
|
||||
Kebangsaan pgtype.Int4 `json:"kebangsaan" db:"kebangsaan"`
|
||||
Bahasa pgtype.Int4 `json:"bahasa" db:"bahasa"`
|
||||
Pendidikan pgtype.Int4 `json:"pendidikan" db:"pendidikan"`
|
||||
StatusPerkawinan pgtype.Int4 `json:"status_perkawinan" db:"status_perkawinan"`
|
||||
Email pgtype.Text `json:"email" db:"email"`
|
||||
Pekerjaan pgtype.Int4 `json:"pekerjaan" db:"pekerjaan"`
|
||||
NoHp pgtype.Text `json:"no_hp" db:"no_hp"`
|
||||
IsDeleted bool `json:"is_deleted" db:"is_deleted"`
|
||||
FasyankesID int `json:"fasyankes_id" db:"fasyankes_id"`
|
||||
Nik pgtype.Text `json:"nik" db:"nik"`
|
||||
NoKk pgtype.Text `json:"no_kk" db:"no_kk"`
|
||||
NoKartuPesertaBPJS pgtype.Text `json:"no_kartu_peserta_bpjs" db:"no_kartu_peserta_bpjs"`
|
||||
CreateBy int `json:"create_by" db:"create_by"`
|
||||
UpdateBy int `json:"update_by" db:"update_by"`
|
||||
CreatedAt time.Time `json:"created_at" db:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
|
||||
}
|
9
model/wilayah.go
Normal file
9
model/wilayah.go
Normal file
@ -0,0 +1,9 @@
|
||||
package model
|
||||
|
||||
type Wilayah struct {
|
||||
Id int32
|
||||
KodeWilayah string
|
||||
NamaWilayah string
|
||||
KodeBPJS *string
|
||||
NamaBPJS *string
|
||||
}
|
53
util/common.go
Normal file
53
util/common.go
Normal file
@ -0,0 +1,53 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const TIME_PARSE_LAYOUT = "2/1/2006"
|
||||
const NilIntVal = int8(0)
|
||||
|
||||
func StringToIntPtr[T int8 | int32 | int64](s string) *T {
|
||||
var val T
|
||||
switch any(val).(type) {
|
||||
case int8, int32, int64:
|
||||
num, err := strconv.ParseInt(s, 10, 64)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
switch any(val).(type) {
|
||||
case int8:
|
||||
val := int8(num)
|
||||
return any(&val).(*T)
|
||||
case int32:
|
||||
val := int32(num)
|
||||
return any(&val).(*T)
|
||||
case int64:
|
||||
val := int64(num)
|
||||
return any(&val).(*T)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
default:
|
||||
fmt.Printf("Unsupported type: %s\n", reflect.TypeOf(val).Name())
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func StringToStringPtr(s string) *string {
|
||||
if s == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &s
|
||||
}
|
||||
|
||||
func Pad(numStr string, size int32) string {
|
||||
for int32(len(numStr)) < size {
|
||||
numStr = "0" + numStr
|
||||
}
|
||||
|
||||
return numStr
|
||||
}
|
Loading…
Reference in New Issue
Block a user