From 6be099fe2fbc767923d565ee0ed49d2ec1e3a251 Mon Sep 17 00:00:00 2001 From: ='fauz <='fauzgabriel@gmail.com> Date: Tue, 1 Jul 2025 14:47:09 +0700 Subject: [PATCH] Status Wilayah --- app/__pycache__/apiController.cpython-313.pyc | Bin 38786 -> 38677 bytes app/__pycache__/routes.cpython-313.pyc | Bin 16854 -> 17388 bytes app/apiController.py | 524 ++++++++++-------- app/routes.py | 11 +- templates/index.html | 136 +++-- 5 files changed, 378 insertions(+), 293 deletions(-) diff --git a/app/__pycache__/apiController.cpython-313.pyc b/app/__pycache__/apiController.cpython-313.pyc index e42f553ef72c39a4862fe5748409db2e0f9563fa..d7d30f6bea8cc0236303ace7f1f173a96b90ba87 100644 GIT binary patch literal 38677 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 delta 7842 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 IoJ|@30sNu(0RR91 delta 1762 zcmZWqeQZ-z6z^Sox6y8GHVW;!t!rOjyS}zt%gVZqu@44`#4sSi842L%Xfu|5ayv0W zhY(3n2WD`LC_2UXMFWE7iC>X8{!uh$jt{|1ki?*3LKHKiXpHfkyQzQpl6QK}`Tg#> z=bd}*>CL_D(xc2eQ&?y=;4^-2*Vd!K16C)Sc&qYEuBn@AYjjs$)M%V$Q8;N|s9(1j z8CQ`S&~FyZXUucZs;UawnH&@zk0`~T>4NU`aOaR1+}<;g=@CJ6Rl#n{e3#|OSTH;gEKY{uSQ2)|K8TXSO7dlrPA%Nrne;f zlf%gYQG@srJz3;oiD!s|>WacbeEgETo0?7qFz6{lM@U!C3k1W{4yfQ@-!LxaiM&UK%H1A7qPxnEY zqlT|S&w72G!^2oB3_F7?0^`mAUyJTE#e!>2m9>GXh`Iv21MxmtqkdP2 zY5Fs+1uVZ6of;QjI8~~#D!5kawA7(X?us9kQ>O9tXlL|TSu0}-Y%BNi`_ZvOf41Ds zayJrJfz$4gErsfCGCN6ZhF{$uvo1JYp@#o=c2;?I>48+Tf2e1mTXf@!$MDV6!Gzxh z0gsn$hLxVr_y%-l531#s73oY;$igVl;tld%1fGOGZz~et@J`})KCIMR)}i;G%s*1X zduVOX#`!)U`;;+bRc3N}c zE592#zxmH0XSZgDtAT~cyB(t`D=*!*>`4Im)6ybZ&eMaWw3scT3!(Sji zxyU;&*)?085on79_+I3lmAs`j`LHiSdu1aRk-M`h!4hz)D#D*Y&N-P2uO?inz9e%| z=B2mH#!7%1jq?4-yDVc3MrqHdqLg!Y%!hGCW7T{N@oyylWsLAYVi#mi8sc{r1vw!8 z-CQn&Cu{D=ee5t0cg~)eEK?mEh}*GKUyBFLhj7hL_+me7iaOy|+{fZzUmP=22N?04 zSq&pgeYJ{V19{}rVW_3?fX@KiK(|Le9junkYN|oBqNbVP$HhUHJQP~1<%p;8NBB_4 z`2vwzchzCEZj;B2Vwd5%#d+D%aNg4Jp*k_|g5~aAE3R0I#}- zWaF{RfOE&*l?d6!(fvEVVwgl5JeN3&B}mn&?0IZ8)tsW{K7yD5iW(e1{dTdA`faA} z)45t*4HUrDdNVG#QLplsk(!5G>bdrYH|6G0zubX43VH~D(EhX9VF-m z2{~o$OzT|s3NR1ZO4Ehzu2L9~-D|5Eao_7A2W t=u0e*@kwtDOJ< diff --git a/app/apiController.py b/app/apiController.py index 680b7a2..63e4220 100644 --- a/app/apiController.py +++ b/app/apiController.py @@ -51,48 +51,57 @@ class apiController: def getStatusKecamatan(conn,kode_prov, kode_kabkota, kode_kecamatan): cur = conn.cursor() SQL = """ - SELECT - tahun AS tahun, + SELECT + tahun as tahun, status as th, kode_provinsi, kabupaten_kota_kode, - kecamatan_kode, + kecamatan_kode, kecamatan_nama, - COUNT(DISTINCT kelurahan_desa_id) AS `COUNT_DISTINCT(kelurahan_desa_id)` - FROM ( - SELECT - wp.id AS provinsi_id, - wp.kode AS kode_provinsi, - wkk.id AS kabupaten_kota_id, - wkk.kode AS kabupaten_kota_kode, - wkk.nama AS kabupaten_kota_nama, - wk.id AS kecamatan_id, - wk.kode AS kecamatan_kode, - wk.nama AS kecamatan_nama, - wkd.id AS kelurahan_desa_id, - wkd.kode AS kelurahan_desa_kode, - wkd.nama AS kelurahan_desa_nama, - mid.status, - mid.tahun - FROM metrik_indeks_desa mid - INNER JOIN wil_desa wkd ON mid.desa_id = wkd.id - INNER JOIN wil_kecamatan wk ON wkd.kecamatan_id = wk.id - INNER JOIN wil_kabupatenkota wkk ON wk.kabupatenkota_id = wkk.id - INNER JOIN wil_provinsi wp ON wkk.provinsi_id = wp.id - WHERE mid.tahun = ( - SELECT MAX(tahun) FROM metrik_indeks_desa LIMIT 1 - ) - ) AS virtual_table - WHERE kode_provinsi = %s - AND kabupaten_kota_kode = %s + COUNT(distinct kelurahan_desa_id) as `COUNT_DISTINCT(kelurahan_desa_id)` + FROM + ( + SELECT + wp.id as provinsi_id, + wp.kode as kode_provinsi, + wkk.id as kabupaten_kota_id, + wkk.kode as kabupaten_kota_kode, + wkk.nama as kabupaten_kota_nama, + wk.id as kecamatan_id, + wk.kode as kecamatan_kode, + wk.nama as kecamatan_nama, + wd.id as kelurahan_desa_id, + wp.kode as kelurahan_desa_kode, + wk.nama as kelurahan_desa_nama, + mid.status, + mid.tahun + FROM + metrik_indeks_desa mid + JOIN wil_desa wd on + wd.kode_int = mid.kode_desa + JOIN wil_kecamatan wk on + wk.id = wd.kecamatan_id + JOIN wil_kabupatenkota wkk on + wkk.id = wk.kabupatenkota_id + JOIN wil_provinsi wp on + wp.id = wkk.provinsi_id + where + mid.tahun = ( + select + MAX(tahun) + from + metrik_indeks_desa + limit 1 ) ) as virtual_table + WHERE provinsi_id = %s AND kecamatan_kode = %s GROUP BY tahun, status, kode_provinsi, kabupaten_kota_kode, kecamatan_kode, kecamatan_nama ORDER BY kecamatan_kode DESC; - """ try: - cur.execute(SQL, (kode_prov, kode_kabkota, kode_kecamatan)) + cur.execute(SQL, (kode_prov, kode_kecamatan)) + print('status kecamtan :', cur._executed) except Exception as e: + print(e) return [] print(kode_prov, kode_kabkota, kode_kecamatan) result = cur.fetchall() @@ -140,11 +149,11 @@ class apiController: # select wp.id provinsi_id, wp.kode provinsi_kode, wp.nama provinsi_nama, # wkk.id kabupaten_kota_id, wkk.kode kabupaten_kota_kode, wkk.nama kabupaten_kota_nama, # wk.id kecamatan_id, wk.kode kecamatan_kode, wk.nama kecamatan_nama, - # wkd.id kelurahan_desa_id, wkd.kode kelurahan_desa_kode, wkd.nama kelurahan_desa_nama, + # wk.id kelurahan_desa_id, wk.kode kelurahan_desa_kode, wk.nama kelurahan_desa_nama, # mid.status, mid.status, mid.tahun # from metrik_indeks_desa mid - # inner join wil_desa wkd on mid.desa_id = wkd.id - # inner join wil_kecamatan wk on wkd.kecamatan_id = wk.id + # inner join wil_desa wkd on mid.desa_id = wk.id + # inner join wil_kecamatan wk on wk.kecamatan_id = wk.id # inner join wil_kabupatenkota wkk on wk.kabupatenkota_id = wkk.id # inner join wil_provinsi wp on wkk.provinsi_id = wp.id # where mid.tahun = (select max(tahun) from metrik_indeks_desa limit 1) @@ -172,16 +181,16 @@ class apiController: wp.kode AS kode_provinsi, wkk.kode AS kabupaten_kota_kode, wkk.nama AS kabupaten_kota_nama, - wkd.id AS kelurahan_desa_id, + wk.id AS kelurahan_desa_id, mid.status, mid.tahun FROM metrik_indeks_desa mid - INNER JOIN wil_desa wkd ON mid.desa_id = wkd.id - INNER JOIN wil_kecamatan wk ON wkd.kecamatan_id = wk.id - INNER JOIN wil_kabupatenkota wkk ON wk.kabupatenkota_id = wkk.id - INNER JOIN wil_provinsi wp ON wkk.provinsi_id = wp.id + JOIN wil_desa wd on wd.kode_int = mid.kode_desa + JOIN wil_kecamatan wk on wk.id = wd.kecamatan_id + JOIN wil_kabupatenkota wkk on wkk.id = wk.kabupatenkota_id + JOIN wil_provinsi wp on wp.id = wkk.provinsi_id WHERE mid.tahun = (SELECT MAX(tahun) FROM metrik_indeks_desa) - AND wp.kode = %s + AND wp.id = %s AND wkk.kode = %s ) AS filtered_data GROUP BY tahun, status, kode_provinsi, kabupaten_kota_kode, kabupaten_kota_nama; @@ -205,11 +214,11 @@ class apiController: # select wp.id provinsi_id, wp.kode kode_provinsi, # wkk.id kabupaten_kota_id, wkk.kode kabupaten_kota_kode, wkk.nama kabupaten_kota_nama, # wk.id kecamatan_id, wk.kode kecamatan_kode, wk.nama kecamatan_nama, - # wkd.id kelurahan_desa_id, wkd.kode kelurahan_desa_kode, wkd.nama kelurahan_desa_nama, + # wk.id kelurahan_desa_id, wk.kode kelurahan_desa_kode, wk.nama kelurahan_desa_nama, # mid.status, mid.status, mid.tahun # from metrik_indeks_desa mid - # inner join wil_desa wkd on mid.desa_id = wkd.id - # inner join wil_kecamatan wk on wkd.kecamatan_id = wk.id + # inner join wil_desa wkd on mid.desa_id = wk.id + # inner join wil_kecamatan wk on wk.kecamatan_id = wk.id # inner join wil_kabupatenkota wkk on wk.kabupatenkota_id = wkk.id # inner join wil_provinsi wp on wkk.provinsi_id = wp.id # where mid.tahun = (select max(tahun) from metrik_indeks_desa limit 1) @@ -235,13 +244,13 @@ class apiController: wp.id provinsi_id, wp.kode provinsi_kode, wp.nama provinsi_nama, wkk.id kabupaten_kota_id, wkk.kode kabupaten_kota_kode, wkk.nama kabupaten_kota_nama, wk.id kecamatan_id, wk.kode kecamatan_kode, wk.nama kecamatan_nama, - wkd.id kelurahan_desa_id, wkd.kode kelurahan_desa_kode, wkd.nama kelurahan_desa_nama, + wk.id kelurahan_desa_id, wk.kode kelurahan_desa_kode, wk.nama kelurahan_desa_nama, mb.jenis, mb.jumlah - from metric_bumdes mb - inner join wil_desa wkd on mb.kelurahan_desa_id = wkd.id - inner join wil_kecamatan wk on wkd.kecamatan_id = wk.id - inner join wil_kabupatenkota wkk on wk.kabupatenkota_id = wkk.id - inner join wil_provinsi wp on wkk.provinsi_id = wp.id + from metrik_bumdes mb + JOIN wil_desa wd on wd.kode_int = mb.kode_desa + JOIN wil_kecamatan wk on wk.id = wd.kecamatan_id + JOIN wil_kabupatenkota wkk on wkk.id = wk.kabupatenkota_id + JOIN wil_provinsi wp on wp.id = wkk.provinsi_id ) AS virtual_table GROUP BY jenis ORDER BY "SUM(jumlah)" DESC LIMIT 1000; """ @@ -259,13 +268,13 @@ class apiController: wp.id provinsi_id, wp.kode provinsi_kode, wp.nama provinsi_nama, wkk.id kabupaten_kota_id, wkk.kode kabupaten_kota_kode, wkk.nama kabupaten_kota_nama, wk.id kecamatan_id, wk.kode kecamatan_kode, wk.nama kecamatan_nama, - wkd.id kelurahan_desa_id, wkd.kode kelurahan_desa_kode, wkd.nama kelurahan_desa_nama, + wk.id kelurahan_desa_id, wk.kode kelurahan_desa_kode, wk.nama kelurahan_desa_nama, mpd.jenis_pendamping, mpd.jumlah from metric_pendamping_desa mpd - inner join wil_desa wkd on mpd.kelurahan_desa_id = wkd.id - inner join wil_kecamatan wk on wkd.kecamatan_id = wk.id - inner join wil_kabupatenkota wkk on wk.kabupatenkota_id = wkk.id - inner join wil_provinsi wp on wkk.provinsi_id = wp.id + JOIN wil_desa wd on wd.kode_int = mpd.kode_desa + JOIN wil_kecamatan wk on wk.id = wd.kecamatan_id + JOIN wil_kabupatenkota wkk on wkk.id = wk.kabupatenkota_id + JOIN wil_provinsi wp on wp.id = wkk.provinsi_id ) AS virtual_table GROUP BY jenis_pendamping ORDER BY "SUM(jumlah)" DESC LIMIT 1000; """ @@ -281,13 +290,13 @@ class apiController: wp.id provinsi_id, wp.kode provinsi_kode, wp.nama provinsi_nama, wkk.id kabupaten_kota_id, wkk.kode kabupaten_kota_kode, wkk.nama kabupaten_kota_nama, wk.id kecamatan_id, wk.kode kecamatan_kode, wk.nama kecamatan_nama, - wkd.id kelurahan_desa_id, wkd.kode kelurahan_desa_kode, wkd.nama kelurahan_desa_nama, + wk.id kelurahan_desa_id, wk.kode kelurahan_desa_kode, wk.nama kelurahan_desa_nama, mpd.jenis_pendamping, mpd.jumlah from metric_pendamping_desa mpd - INNER JOIN wil_desa wkd ON mdd.desa_id = wkd.id - INNER JOIN wil_kecamatan wk ON wkd.kecamatan_id = wk.id - INNER JOIN wil_kabupatenkota wkk ON wk.kabupatenkota_id = wkk.id - INNER JOIN wil_provinsi wp ON wkk.provinsi_id = wp.id + JOIN wil_desa wd on wd.kode_int = mpd.kode_desa + JOIN wil_kecamatan wk on wk.id = wd.kecamatan_id + JOIN wil_kabupatenkota wkk on wkk.id = wk.kabupatenkota_id + JOIN wil_provinsi wp on wp.id = wkk.provinsi_id WHERE wp.kode = %s ) AS virtual_table GROUP BY jenis_pendamping ORDER BY "SUM(jumlah)" DESC LIMIT 1000; @@ -300,7 +309,7 @@ class apiController: return result @staticmethod - def getPendampingPerDesa(conn): + def getPendampingPerDesa(conn, kode_desa): cur = conn.cursor() SQL = """ SELECT jenis_pendamping AS jenis_pendamping, SUM(jumlah) / COUNT(DISTINCT kabupaten_kota_id) AS "SUM(jumlah) / COUNT(DISTINCT kabupaten_kota_id)" @@ -308,19 +317,22 @@ class apiController: wp.id provinsi_id, wp.kode provinsi_kode, wp.nama provinsi_nama, wkk.id kabupaten_kota_id, wkk.kode kabupaten_kota_kode, wkk.nama kabupaten_kota_nama, wk.id kecamatan_id, wk.kode kecamatan_kode, wk.nama kecamatan_nama, - wkd.id kelurahan_desa_id, wkd.kode kelurahan_desa_kode, wkd.nama kelurahan_desa_nama, + wk.id kelurahan_desa_id, wk.kode kelurahan_desa_kode, wk.nama kelurahan_desa_nama, mpd.jenis_pendamping, mpd.jumlah from metric_pendamping_desa mpd - inner join wil_desa wkd on mpd.kelurahan_desa_id = wkd.id - inner join wil_kecamatan wk on wkd.kecamatan_id = wk.id - inner join wil_kabupatenkota wkk on wk.kabupatenkota_id = wkk.id - inner join wil_provinsi wp on wkk.provinsi_id = wp.id - ) AS virtual_table GROUP BY jenis_pendamping ORDER BY "SUM(jumlah) / COUNT(DISTINCT kabupaten_kota_id)" DESC + JOIN wil_desa wd on wd.kode_int = mpd.kode_desa + JOIN wil_kecamatan wk on wk.id = wd.kecamatan_id + JOIN wil_kabupatenkota wkk on wkk.id = wk.kabupatenkota_id + JOIN wil_provinsi wp on wp.id = wkk.provinsi_id + WHERE wk.kode = %s + ) AS virtual_table + GROUP BY jenis_pendamping ORDER BY "SUM(jumlah) / COUNT(DISTINCT kabupaten_kota_id)" DESC LIMIT 10000; """ try: cur.execute(SQL) except Exception as e: + print(e) return [] result = cur.fetchall() return result @@ -334,13 +346,13 @@ class apiController: wp.id provinsi_id, wp.kode provinsi_kode, wp.nama provinsi_nama, wkk.id kabupaten_kota_id, wkk.kode kabupaten_kota_kode, wkk.nama kabupaten_kota_nama, wk.id kecamatan_id, wk.kode kecamatan_kode, wk.nama kecamatan_nama, - wkd.id kelurahan_desa_id, wkd.kode kelurahan_desa_kode, wkd.nama kelurahan_desa_nama, + wk.id kelurahan_desa_id, wk.kode kelurahan_desa_kode, wk.nama kelurahan_desa_nama, mkd.jumlah from metric_koperasi_desa mkd - inner join wil_desa wkd on mkd.kelurahan_desa_id = wkd.id - inner join wil_kecamatan wk on wkd.kecamatan_id = wk.id - inner join wil_kabupatenkota wkk on wk.kabupatenkota_id = wkk.id - inner join wil_provinsi wp on wkk.provinsi_id = wp.id + JOIN wil_desa wd on wd.kode_int = mkd.kode_desa + JOIN wil_kecamatan wk on wk.id = wd.kecamatan_id + JOIN wil_kabupatenkota wkk on wkk.id = wk.kabupatenkota_id + JOIN wil_provinsi wp on wp.id = wkk.provinsi_id ) AS virtual_table; """ cur.execute(SQL) @@ -356,13 +368,13 @@ class apiController: wp.id provinsi_id, wp.kode provinsi_kode, wp.nama provinsi_nama, wkk.id kabupaten_kota_id, wkk.kode kabupaten_kota_kode, wkk.nama kabupaten_kota_nama, wk.id kecamatan_id, wk.kode kecamatan_kode, wk.nama kecamatan_nama, - wkd.id kelurahan_desa_id, wkd.kode kelurahan_desa_kode, wkd.nama kelurahan_desa_nama, + wk.id kelurahan_desa_id, wk.kode kelurahan_desa_kode, wk.nama kelurahan_desa_nama, mkd.jumlah from metric_koperasi_desa mkd - inner join wil_desa wkd on mkd.kelurahan_desa_id = wkd.id - inner join wil_kecamatan wk on wkd.kecamatan_id = wk.id - inner join wil_kabupatenkota wkk on wk.kabupatenkota_id = wkk.id - inner join wil_provinsi wp on wkk.provinsi_id = wp.id + JOIN wil_desa wd on wd.kode_int = mkd.kode_desa + JOIN wil_kecamatan wk on wk.id = wd.kecamatan_id + JOIN wil_kabupatenkota wkk on wkk.id = wk.kabupatenkota_id + JOIN wil_provinsi wp on wp.id = wkk.provinsi_id ) AS virtual_table WHERE jumlah = 0 LIMIT 50000; @@ -454,11 +466,11 @@ class apiController: # select wp.id provinsi_id, wp.kode provinsi_kode, wp.nama provinsi_nama, # wkk.id kabupaten_kota_id, wkk.kode kabupaten_kota_kode, wkk.nama kabupaten_kota_nama, # wk.id kecamatan_id, wk.kode kecamatan_kode, wk.nama kecamatan_nama, - # wkd.id kelurahan_desa_id, wkd.kode kelurahan_desa_kode, wkd.nama kelurahan_desa_nama, + # wk.id kelurahan_desa_id, wk.kode kelurahan_desa_kode, wk.nama kelurahan_desa_nama, # mid.status, mid.status, mid.tahun # from metrik_indeks_desa mid - # inner join wil_desa wkd on mid.desa_id = wkd.id - # inner join wil_kecamatan wk on wkd.kecamatan_id = wk.id + # inner join wil_desa wkd on mid.desa_id = wk.id + # inner join wil_kecamatan wk on wk.kecamatan_id = wk.id # inner join wil_kabupatenkota wkk on wk.kabupatenkota_id = wkk.id # inner join wil_provinsi wp on wkk.provinsi_id = wp.id # where mid.tahun = (select max(tahun) from metrik_indeks_desa limit 1) @@ -479,11 +491,11 @@ class apiController: # select wp.id provinsi_id, wp.kode kode_provinsi, # wkk.id kabupaten_kota_id, wkk.kode kabupaten_kota_kode, wkk.nama kabupaten_kota_nama, # wk.id kecamatan_id, wk.kode kecamatan_kode, wk.nama kecamatan_nama, - # wkd.id kelurahan_desa_id, wkd.kode kelurahan_desa_kode, wkd.nama kelurahan_desa_nama, + # wk.id kelurahan_desa_id, wk.kode kelurahan_desa_kode, wk.nama kelurahan_desa_nama, # mid.status, mid.status, mid.tahun # from metrik_indeks_desa mid - # inner join wil_desa wkd on mid.desa_id = wkd.id - # inner join wil_kecamatan wk on wkd.kecamatan_id = wk.id + # inner join wil_desa wkd on mid.desa_id = wk.id + # inner join wil_kecamatan wk on wk.kecamatan_id = wk.id # inner join wil_kabupatenkota wkk on wk.kabupatenkota_id = wkk.id # inner join wil_provinsi wp on wkk.provinsi_id = wp.id # where mid.tahun = (select max(tahun) from metrik_indeks_desa limit 1) @@ -512,11 +524,11 @@ class apiController: # select wp.id provinsi_id, wp.kode kode_provinsi, # wkk.id kabupaten_kota_id, wkk.kode kabupaten_kota_kode, wkk.nama kabupaten_kota_nama, # wk.id kecamatan_id, wk.kode kecamatan_kode, wk.nama kecamatan_nama, - # wkd.id kelurahan_desa_id, wkd.kode kelurahan_desa_kode, wkd.nama kelurahan_desa_nama, + # wk.id kelurahan_desa_id, wk.kode kelurahan_desa_kode, wk.nama kelurahan_desa_nama, # mid.status, mid.status, mid.tahun # from metrik_indeks_desa mid - # inner join wil_desa wkd on mid.desa_id = wkd.id - # inner join wil_kecamatan wk on wkd.kecamatan_id = wk.id + # inner join wil_desa wkd on mid.desa_id = wk.id + # inner join wil_kecamatan wk on wk.kecamatan_id = wk.id # inner join wil_kabupatenkota wkk on wk.kabupatenkota_id = wkk.id # inner join wil_provinsi wp on wkk.provinsi_id = wp.id # where mid.tahun = (select max(tahun) from metrik_indeks_desa limit 1) @@ -540,13 +552,13 @@ class apiController: wp.id provinsi_id, wp.kode provinsi_kode, wp.nama provinsi_nama, wkk.id kabupaten_kota_id, wkk.kode kabupaten_kota_kode, wkk.nama kabupaten_kota_nama, wk.id kecamatan_id, wk.kode kecamatan_kode, wk.nama kecamatan_nama, - wkd.id kelurahan_desa_id, wkd.kode kelurahan_desa_kode, wkd.nama kelurahan_desa_nama, + wk.id kelurahan_desa_id, wk.kode kelurahan_desa_kode, wk.nama kelurahan_desa_nama, mb.tipe, mb.jumlah from metrik_bumdes mb - inner join wil_desa wkd on mb.desa_id = wkd.id - inner join wil_kecamatan wk on wkd.kecamatan_id = wk.id - inner join wil_kabupatenkota wkk on wk.kabupatenkota_id = wkk.id - inner join wil_provinsi wp on wkk.provinsi_id = wp.id + JOIN wil_desa wd on wd.kode_int = mb.kode_desa + JOIN wil_kecamatan wk on wk.id = wd.kecamatan_id + JOIN wil_kabupatenkota wkk on wkk.id = wk.kabupatenkota_id + JOIN wil_provinsi wp on wp.id = wkk.provinsi_id WHERE wp.kode = %s ) AS virtual_table GROUP BY tipe ORDER BY "SUM(jumlah)" DESC LIMIT 1000; @@ -568,13 +580,13 @@ class apiController: select wp.id provinsi_id, wp.kode provinsi_kode, wp.nama provinsi_nama, wkk.id kabupaten_kota_id, wkk.kode kabupaten_kota_kode, wkk.nama kabupaten_kota_nama, wk.id kecamatan_id, wk.kode kecamatan_kode, wk.nama kecamatan_nama, - wkd.id kelurahan_desa_id, wkd.kode kelurahan_desa_kode, wkd.nama kelurahan_desa_nama, + wk.id kelurahan_desa_id, wk.kode kelurahan_desa_kode, wk.nama kelurahan_desa_nama, mid.idm, mid.status, mid.tahun from metrik_indeks_desa mid - inner join wil_desa wkd on mid.desa_id = wkd.id - inner join wil_kecamatan wk on wkd.kecamatan_id = wk.id - inner join wil_kabupatenkota wkk on wk.kabupatenkota_id = wkk.id - inner join wil_provinsi wp on wkk.provinsi_id = wp.id + JOIN wil_desa wd on wd.kode_int = mid.kode_desa + JOIN wil_kecamatan wk on wk.id = wd.kecamatan_id + JOIN wil_kabupatenkota wkk on wkk.id = wk.kabupatenkota_id + JOIN wil_provinsi wp on wp.id = wkk.provinsi_id where mid.tahun = (select max(tahun) from metrik_indeks_desa limit 1) ) AS virtual_table WHERE provinsi_kode = %s @@ -593,11 +605,11 @@ class apiController: # select wp.id provinsi_id, wp.kode kode_provinsi, # wkk.id kabupaten_kota_id, wkk.kode kabupaten_kota_kode, wkk.nama kabupaten_kota_nama, # wk.id kecamatan_id, wk.kode kecamatan_kode, wk.nama kecamatan_nama, - # wkd.id kelurahan_desa_id, wkd.kode kelurahan_desa_kode, wkd.nama kelurahan_desa_nama, + # wk.id kelurahan_desa_id, wk.kode kelurahan_desa_kode, wk.nama kelurahan_desa_nama, # mid.status, mid.status, mid.tahun # from metrik_indeks_desa mid - # inner join wil_desa wkd on mid.desa_id = wkd.id - # inner join wil_kecamatan wk on wkd.kecamatan_id = wk.id + # inner join wil_desa wkd on mid.desa_id = wk.id + # inner join wil_kecamatan wk on wk.kecamatan_id = wk.id # inner join wil_kabupatenkota wkk on wk.kabupatenkota_id = wkk.id # inner join wil_provinsi wp on wkk.provinsi_id = wp.id # where mid.tahun = (select max(tahun) from metrik_indeks_desa limit 1) @@ -619,10 +631,10 @@ class apiController: # WHEN mkd.jumlah > 0 THEN 'Kopmer' # ELSE 'Non Kopmer' # END AS status_koperasi, - # COUNT(DISTINCT wkd.id) AS jumlah_desa + # COUNT(DISTINCT wk.id) AS jumlah_desa # FROM metric_koperasi_desa mkd - # INNER JOIN wil_desa wkd ON mkd.kelurahan_desa_id = wkd.id - # INNER JOIN wil_kecamatan wk ON wkd.kecamatan_id = wk.id + # INNER JOIN wil_desa wkd ON mkd.kelurahan_desa_id = wk.id + # INNER JOIN wil_kecamatan wk ON wk.kecamatan_id = wk.id # INNER JOIN wil_kabupatenkota wkk ON wk.kabupatenkota_id = wkk.id # INNER JOIN wil_provinsi wp ON wkk.provinsi_id = wp.id # WHERE wp.kode = %s @@ -647,10 +659,10 @@ class apiController: SUM(mdd.salur_pagu) / 1000000000 AS serapan_per_1M, (SUM(mdd.salur_pagu) / NULLIF(SUM(mdd.pagu), 0)) * 100 AS persentase_serapan FROM metrik_dana_desa mdd - INNER JOIN wil_desa wkd ON mdd.desa_id = wkd.id - INNER JOIN wil_kecamatan wk ON wkd.kecamatan_id = wk.id - INNER JOIN wil_kabupatenkota wkk ON wk.kabupatenkota_id = wkk.id - INNER JOIN wil_provinsi wp ON wkk.provinsi_id = wp.id + JOIN wil_desa wd on wd.kode_int = mdd.kode_desa + JOIN wil_kecamatan wk on wk.id = wd.kecamatan_id + JOIN wil_kabupatenkota wkk on wkk.id = wk.kabupatenkota_id + JOIN wil_provinsi wp on wp.id = wkk.provinsi_id WHERE mdd.tahun = (SELECT tahun FROM latest_year) AND wp.kode = %s """ @@ -659,7 +671,46 @@ class apiController: for row in cur.fetchall(): total_serapan += row[1] return {'jumlah_per_m':toRupiah(row[0]), 'persentage':round(row[1],2)} - + @staticmethod + def getTotalDana(conn, level,kode_lvl): + print("data level:", level,kode_lvl) + cursor = conn.cursor() + level_conf = { + 'provinsi' : ('wil_provinsi','wp', 'kode'), + 'kabkota' : ('wil_kabupatenkota', 'wkk', 'kode'), + 'kecamatan' : ('wil_kecamatan', 'wk', 'kode'), + 'desa' : ('wil_desa', 'wd', 'kode') + } + + if level not in level_conf or not kode_lvl: + print('level tidak valid') + return + tabel,alias, key = level_conf[level] + query = f""" + WITH latest_year AS ( + SELECT MAX(tahun) AS tahun FROM metrik_dana_desa + ) + SELECT + SUM(mdd.pagu) AS serapan_per_1M + FROM metrik_dana_desa mdd + JOIN wil_desa wd on wd.kode_int = mdd.kode_desa + JOIN wil_kecamatan wk on wk.id = wd.kecamatan_id + JOIN wil_kabupatenkota wkk on wkk.id = wk.kabupatenkota_id + JOIN wil_provinsi wp on wp.id = wkk.provinsi_id + WHERE mdd.tahun = (SELECT tahun FROM latest_year) + AND {alias}.{key} = '{kode_lvl}' + """ + print("Query :", query) + try: + cursor.execute(query) + except Exception as e: + print(e) + return[] + + result = cursor.fetchone() + print("data:", query) + return result + @staticmethod # def getStatusKecamatan(conn, kode_prov, kode_kabkota, kode_kecamatan): # cur = conn.cursor() @@ -676,11 +727,11 @@ class apiController: # select wp.id provinsi_id, wp.kode kode_provinsi, # wkk.id kabupaten_kota_id, wkk.kode kabupaten_kota_kode, wkk.nama kabupaten_kota_nama, # wk.id kecamatan_id, wk.kode kecamatan_kode, wk.nama kecamatan_nama, - # wkd.id kelurahan_desa_id, wkd.kode kelurahan_desa_kode, wkd.nama kelurahan_desa_nama, + # wk.id kelurahan_desa_id, wk.kode kelurahan_desa_kode, wk.nama kelurahan_desa_nama, # mid.status, mid.status, mid.tahun # from metrik_indeks_desa mid - # inner join wil_desa wkd on mid.desa_id = wkd.id - # inner join wil_kecamatan wk on wkd.kecamatan_id = wk.id + # inner join wil_desa wkd on mid.desa_id = wk.id + # inner join wil_kecamatan wk on wk.kecamatan_id = wk.id # inner join wil_kabupatenkota wkk on wk.kabupatenkota_id = wkk.id # inner join wil_provinsi wp on wkk.provinsi_id = wp.id # where mid.tahun = (select max(tahun) from metrik_indeks_desa limit 1) @@ -703,26 +754,27 @@ class apiController: def getBumdesKab(conn, kode_kab): cur = conn.cursor() SQL = """ - SELECT jenis AS jenis, sum(jumlah) AS "SUM(jumlah)" - FROM (select - wp.id provinsi_id, wp.kode provinsi_kode, wp.nama provinsi_nama, - wkk.id kabupaten_kota_id, wkk.kode kabupaten_kota_kode, wkk.nama kabupaten_kota_nama, - wk.id kecamatan_id, wk.kode kecamatan_kode, wk.nama kecamatan_nama, - wkd.id kelurahan_desa_id, wkd.kode kelurahan_desa_kode, wkd.nama kelurahan_desa_nama, - mb.jenis, mb.jumlah - from metric_bumdes mb - inner join wil_desa wkd on mb.kelurahan_desa_id = wkd.id - inner join wil_kecamatan wk on wkd.kecamatan_id = wk.id - inner join wil_kabupatenkota wkk on wk.kabupatenkota_id = wkk.id - inner join wil_provinsi wp on wkk.provinsi_id = wp.id + SELECT jenis, sum(jumlah) AS "SUM(jumlah)" + FROM ( + SELECT + wp.id provinsi_id, wp.kode provinsi_kode, wp.nama provinsi_nama, + wkk.id kabupaten_kota_id, wkk.kode kabupaten_kota_kode, wkk.nama kabupaten_kota_nama, + wk.id kecamatan_id, wk.kode kecamatan_kode, wk.nama kecamatan_nama, + wk.id kelurahan_desa_id, wk.kode kelurahan_desa_kode, wk.nama kelurahan_desa_nama, + mb.tipe as jenis, mb.jumlah + FROM metrik_bumdes mb + JOIN wil_desa wd on wd.kode_int = mb.kode_desa + JOIN wil_kecamatan wk on wk.id = wd.kecamatan_id + JOIN wil_kabupatenkota wkk on wkk.id = wk.kabupatenkota_id + JOIN wil_provinsi wp on wp.id = wkk.provinsi_id WHERE wkk.kode = %s - ) AS virtual_table GROUP BY jenis ORDER BY "SUM(jumlah)" DESC - LIMIT 1000; + ) AS virtual_table GROUP BY jenis ORDER BY "SUM(jumlah)"; """ - try: - cur.execute(SQL, (kode_prov,)) - except Exception as e: - return [] + # try: + cur.execute(SQL, (kode_kab,)) + # except Exception as e: + # return [] + result = cur.fetchall() return result @@ -737,10 +789,10 @@ class apiController: SUM(mdd.salur_pagu) / 1000000000 AS serapan_per_1M, (SUM(mdd.salur_pagu) / NULLIF(SUM(mdd.pagu), 0)) * 100 AS persentase_serapan FROM metrik_dana_desa mdd - INNER JOIN wil_desa wkd ON mdd.desa_id = wkd.id - INNER JOIN wil_kecamatan wk ON wkd.kecamatan_id = wk.id - INNER JOIN wil_kabupatenkota wkk ON wk.kabupatenkota_id = wkk.id - INNER JOIN wil_provinsi wp ON wkk.provinsi_id = wp.id + JOIN wil_desa wd on wd.kode_int = mdd.kode_desa + JOIN wil_kecamatan wk on wk.id = wd.kecamatan_id + JOIN wil_kabupatenkota wkk on wkk.id = wk.kabupatenkota_id + JOIN wil_provinsi wp on wp.id = wkk.provinsi_id WHERE mdd.tahun = (SELECT tahun FROM latest_year) AND wkk.kode = %s """ @@ -764,13 +816,13 @@ class apiController: wp.id provinsi_id, wp.kode provinsi_kode, wp.nama provinsi_nama, wkk.id kabupaten_kota_id, wkk.kode kabupaten_kota_kode, wkk.nama kabupaten_kota_nama, wk.id kecamatan_id, wk.kode kecamatan_kode, wk.nama kecamatan_nama, - wkd.id kelurahan_desa_id, wkd.kode kelurahan_desa_kode, wkd.nama kelurahan_desa_nama, + wk.id kelurahan_desa_id, wk.kode kelurahan_desa_kode, wk.nama kelurahan_desa_nama, mpd.jenis_pendamping, mpd.jumlah from metric_pendamping_desa mpd - inner join wil_desa wkd on mpd.kelurahan_desa_id = wkd.id - inner join wil_kecamatan wk on wkd.kecamatan_id = wk.id - inner join wil_kabupatenkota wkk on wk.kabupatenkota_id = wkk.id - inner join wil_provinsi wp on wkk.provinsi_id = wp.id + JOIN wil_desa wd on wd.kode_int = mpd.kode_desa + JOIN wil_kecamatan wk on wk.id = wd.kecamatan_id + JOIN wil_kabupatenkota wkk on wkk.id = wk.kabupatenkota_id + JOIN wil_provinsi wp on wp.id = wkk.provinsi_id WHERE wkk.kode = %s ) AS virtual_table GROUP BY jenis_pendamping ORDER BY "SUM(jumlah)" DESC LIMIT 1000; @@ -791,12 +843,12 @@ class apiController: WHEN mkd.jumlah > 0 THEN 'Kopmer' ELSE 'Non Kopmer' END AS status_koperasi, - COUNT(DISTINCT wkd.id) AS jumlah_desa + COUNT(DISTINCT wk.id) AS jumlah_desa FROM metric_koperasi_desa mkd - INNER JOIN wil_desa wkd ON mkd.kelurahan_desa_id = wkd.id - INNER JOIN wil_kecamatan wk ON wkd.kecamatan_id = wk.id - INNER JOIN wil_kabupatenkota wkk ON wk.kabupatenkota_id = wkk.id - INNER JOIN wil_provinsi wp ON wkk.provinsi_id = wp.id + JOIN wil_desa wd on wd.kode_int = mkd.kode_desa + JOIN wil_kecamatan wk on wk.id = wd.kecamatan_id + JOIN wil_kabupatenkota wkk on wkk.id = wk.kabupatenkota_id + JOIN wil_provinsi wp on wp.id = wkk.provinsi_id WHERE wkk.kode = %s GROUP BY status_koperasi LIMIT 50000; @@ -816,21 +868,21 @@ class apiController: def getBumdesKec(conn, kode_kec): cur = conn.cursor() SQL = """ - SELECT jenis AS jenis, sum(jumlah) AS "SUM(jumlah)" - FROM (select - wp.id provinsi_id, wp.kode provinsi_kode, wp.nama provinsi_nama, - wkk.id kabupaten_kota_id, wkk.kode kabupaten_kota_kode, wkk.nama kabupaten_kota_nama, - wk.id kecamatan_id, wk.kode kecamatan_kode, wk.nama kecamatan_nama, - wkd.id kelurahan_desa_id, wkd.kode kelurahan_desa_kode, wkd.nama kelurahan_desa_nama, - mb.jenis, mb.jumlah - from metric_bumdes mb - inner join wil_desa wkd on mb.kelurahan_desa_id = wkd.id - inner join wil_kecamatan wk on wkd.kecamatan_id = wk.id - inner join wil_kabupatenkota wkk on wk.kabupatenkota_id = wkk.id - inner join wil_provinsi wp on wkk.provinsi_id = wp.id + SELECT jenis, sum(jumlah) AS "SUM(jumlah)" + FROM ( + SELECT + wp.id provinsi_id, wp.kode provinsi_kode, wp.nama provinsi_nama, + wkk.id kabupaten_kota_id, wkk.kode kabupaten_kota_kode, wkk.nama kabupaten_kota_nama, + wk.id kecamatan_id, wk.kode kecamatan_kode, wk.nama kecamatan_nama, + wk.id kelurahan_desa_id, wk.kode kelurahan_desa_kode, wk.nama kelurahan_desa_nama, + mb.tipe as jenis, mb.jumlah + FROM metrik_bumdes mb + JOIN wil_desa wd on wd.kode_int = mb.kode_desa + JOIN wil_kecamatan wk on wk.id = wd.kecamatan_id + JOIN wil_kabupatenkota wkk on wkk.id = wk.kabupatenkota_id + JOIN wil_provinsi wp on wp.id = wkk.provinsi_id WHERE wk.kode = %s - ) AS virtual_table GROUP BY jenis ORDER BY "SUM(jumlah)" DESC - LIMIT 1000; + ) AS virtual_table GROUP BY jenis ORDER BY "SUM(jumlah)"; """ try: cur.execute(SQL,(kode_kec,)) @@ -843,37 +895,22 @@ class apiController: def getTotalSerapanKec(conn, kode_kec): cur = conn.cursor() SQL = """ - SELECT - SUM(serapan) / 1000000000 AS serapan_per_1M, - (SUM(serapan) / NULLIF(SUM(pagu), 0)) * 100 AS persentase_serapan - FROM ( - SELECT - wp.id provinsi_id, wp.kode provinsi_kode, wp.nama provinsi_nama, - wkk.id kabupaten_kota_id, wkk.kode kabupaten_kota_kode, wkk.nama kabupaten_kota_nama, - wk.id kecamatan_id, wk.kode kecamatan_kode, wk.nama kecamatan_nama, - wkd.id kelurahan_desa_id, wkd.kode kelurahan_desa_kode, wkd.nama kelurahan_desa_nama, - mdd.pagu, salur_pagu, mdd.persen_serapan, mdd.tahun_anggaran - FROM metrik_dana_desa mdd - INNER JOIN wil_desa wkd ON mdd.kelurahan_desa_id = wkd.id - INNER JOIN wil_kecamatan wk ON wkd.kecamatan_id = wk.id - INNER JOIN wil_kabupatenkota wkk ON wk.kabupatenkota_id = wkk.id - INNER JOIN wil_provinsi wp ON wkk.provinsi_id = wp.id - WHERE wk.kode = %s - ) AS virtual_table - WHERE tahun_anggaran = 2024; + select + SUM(mdd.salur_pagu) serapan_per_milyar, + (SUM(mdd.salur_pagu) / NULLIF(SUM(mdd.pagu), 0)) * 100 AS persentase_serapan + from metrik_dana_desa mdd + join wil_desa as wd on wd.kode_int = mdd.kode_desa + JOIN wil_kecamatan AS wk ON wk.id = wd.kecamatan_id + JOIN wil_kabupatenkota AS wkk ON wkk.id = wk.kabupatenkota_id + JOIN wil_provinsi AS wp ON wp.id = wkk.provinsi_id + where wk.kode = %s """ try: cur.execute(SQL, (kode_kec,)) except Exception as e: return [] - - total_serapan = 0 - total_per_m = 0 - for row in cur.fetchall(): - total_serapan += row[1] or 0 - total_per_m += row[0] or 0 - - return {'jumlah_per_m':toRupiah(total_per_m), 'persentage':round(total_serapan,2)} + result = cur.fetchone() + return result @staticmethod def getPendampingPerKec(conn, kode_kec): cursor = conn.cursor() @@ -883,13 +920,13 @@ class apiController: wp.id provinsi_id, wp.kode provinsi_kode, wp.nama provinsi_nama, wkk.id kabupaten_kota_id, wkk.kode kabupaten_kota_kode, wkk.nama kabupaten_kota_nama, wk.id kecamatan_id, wk.kode kecamatan_kode, wk.nama kecamatan_nama, - wkd.id kelurahan_desa_id, wkd.kode kelurahan_desa_kode, wkd.nama kelurahan_desa_nama, + wk.id kelurahan_desa_id, wk.kode kelurahan_desa_kode, wk.nama kelurahan_desa_nama, mpd.jenis_pendamping, mpd.jumlah from metric_pendamping_desa mpd - inner join wil_desa wkd on mpd.kelurahan_desa_id = wkd.id - inner join wil_kecamatan wk on wkd.kecamatan_id = wk.id - inner join wil_kabupatenkota wkk on wk.kabupatenkota_id = wkk.id - inner join wil_provinsi wp on wkk.provinsi_id = wp.id + JOIN wil_desa wd on wd.kode_int = mpd.kode_desa + JOIN wil_kecamatan wk on wk.id = wd.kecamatan_id + JOIN wil_kabupatenkota wkk on wkk.id = wk.kabupatenkota_id + JOIN wil_provinsi wp on wp.id = wkk.provinsi_id WHERE wk.kode = %s ) AS virtual_table GROUP BY jenis_pendamping ORDER BY "SUM(jumlah)" DESC LIMIT 1000; @@ -910,12 +947,12 @@ class apiController: WHEN mkd.jumlah > 0 THEN 'Kopmer' ELSE 'Non Kopmer' END AS status_koperasi, - COUNT(DISTINCT wkd.id) AS jumlah_desa + COUNT(DISTINCT wk.id) AS jumlah_desa FROM metric_koperasi_desa mkd - INNER JOIN wil_desa wkd ON mkd.kelurahan_desa_id = wkd.id - INNER JOIN wil_kecamatan wk ON wkd.kecamatan_id = wk.id - INNER JOIN wil_kabupatenkota wkk ON wk.kabupatenkota_id = wkk.id - INNER JOIN wil_provinsi wp ON wkk.provinsi_id = wp.id + JOIN wil_desa wd on wd.kode_int = mkd.kode_desa + JOIN wil_kecamatan wk on wk.id = wd.kecamatan_id + JOIN wil_kabupatenkota wkk on wkk.id = wk.kabupatenkota_id + JOIN wil_provinsi wp on wp.id = wkk.provinsi_id WHERE wk.kode = %s GROUP BY status_koperasi LIMIT 50000; @@ -944,22 +981,21 @@ class apiController: select wp.id provinsi_id, wp.kode kode_provinsi, wkk.id kabupaten_kota_id, wkk.kode kabupaten_kota_kode, wkk.nama kabupaten_kota_nama, wk.id kecamatan_id, wk.kode kecamatan_kode, wk.nama kecamatan_nama, - wkd.id desa_id, wkd.kode kelurahan_desa_kode, wkd.nama kelurahan_desa_nama, + wk.id desa_id, wk.kode kelurahan_desa_kode, wk.nama kelurahan_desa_nama, mid.idm, mid.status, mid.tahun from metrik_indeks_desa mid - inner join wil_desa wkd on mid.desa_id = wkd.id - inner join wil_kecamatan wk on wkd.kecamatan_id = wk.id - inner join wil_kabupatenkota wkk on wk.kabupatenkota_id = wkk.id - inner join wil_provinsi wp on wkk.provinsi_id = wp.id + JOIN wil_desa wd on wd.kode_int = mid.kode_desa + JOIN wil_kecamatan wk on wk.id = wd.kecamatan_id + JOIN wil_kabupatenkota wkk on wkk.id = wk.kabupatenkota_id + JOIN wil_provinsi wp on wp.id = wkk.provinsi_id where mid.tahun = (select max(tahun) from metrik_indeks_desa limit 1) AND - wp.kode = %s AND - wkk.kode = %s AND - wk.kode = %s AND - wkd.kode = %s + wp.id = %s AND + wd.kode = %s ) AS virtual_table GROUP BY tahun, status,kode_provinsi, kelurahan_desa_kode,kelurahan_desa_nama ORDER BY status, kelurahan_desa_kode DESC """ - cur.execute(SQL, (kode_prov, kode_kabkota, kode_kecamatan, kode_desa,)) + cur.execute(SQL, (kode_prov,kode_desa,)) + print(cur._executed) result = cur.fetchall() return result @@ -972,19 +1008,21 @@ class apiController: wp.id provinsi_id, wp.kode provinsi_kode, wp.nama provinsi_nama, wkk.id kabupaten_kota_id, wkk.kode kabupaten_kota_kode, wkk.nama kabupaten_kota_nama, wk.id kecamatan_id, wk.kode kecamatan_kode, wk.nama kecamatan_nama, - wkd.id kelurahan_desa_id, wkd.kode kelurahan_desa_kode, wkd.nama kelurahan_desa_nama, - mb.jenis, mb.jumlah - from metric_bumdes mb - inner join wil_desa wkd on mb.kelurahan_desa_id = wkd.id - inner join wil_kecamatan wk on wkd.kecamatan_id = wk.id - inner join wil_kabupatenkota wkk on wk.kabupatenkota_id = wkk.id - inner join wil_provinsi wp on wkk.provinsi_id = wp.id - WHERE wkd.kode = %s + wk.id kelurahan_desa_id, wk.kode kelurahan_desa_kode, wk.nama kelurahan_desa_nama, + mb.tipe as jenis, mb.jumlah + from metrik_bumdes mb + JOIN wil_desa wd on wd.kode_int = mb.kode_desa + JOIN wil_kecamatan wk on wk.id = wd.kecamatan_id + JOIN wil_kabupatenkota wkk on wkk.id = wk.kabupatenkota_id + JOIN wil_provinsi wp on wp.id = wkk.provinsi_id + WHERE wd.kode = %s ) AS virtual_table GROUP BY jenis ORDER BY "SUM(jumlah)" DESC LIMIT 1000; """ - - cur.execute(SQL,(kode_desa,)) + try: + cur.execute(SQL,(kode_desa,)) + except Exception as e: + return [] result = cur.fetchall() return result @@ -992,27 +1030,29 @@ class apiController: def getTotalSerapanDesa(conn, kode_desa): cur = conn.cursor() SQL = """ - SELECT - SUM(serapan) / 1000000000 AS serapan_per_1M,pagu, - (SUM(serapan) / NULLIF(SUM(pagu), 0)) * 100 AS persentase_serapan - FROM ( - SELECT - wp.id provinsi_id, wp.kode provinsi_kode, wp.nama provinsi_nama, - wkk.id kabupaten_kota_id, wkk.kode kabupaten_kota_kode, wkk.nama kabupaten_kota_nama, - wk.id kecamatan_id, wk.kode kecamatan_kode, wk.nama kecamatan_nama, - wkd.id kelurahan_desa_id, wkd.kode kelurahan_desa_kode, wkd.nama kelurahan_desa_nama, - mdd.pagu, salur_pagu, mdd.persen_serapan, mdd.tahun_anggaran - FROM metrik_dana_desa mdd - INNER JOIN wil_desa wkd ON mdd.kelurahan_desa_id = wkd.id - INNER JOIN wil_kecamatan wk ON wkd.kecamatan_id = wk.id - INNER JOIN wil_kabupatenkota wkk ON wk.kabupatenkota_id = wkk.id - INNER JOIN wil_provinsi wp ON wkk.provinsi_id = wp.id - WHERE wkd.kode = %s - ) AS virtual_table - WHERE tahun_anggaran = 2024 - group by pagu; + SELECT + SUM(serapan) AS serapan_per_1M, + (SUM(serapan) / NULLIF(SUM(pagu), 0)) * 100 AS persentase_serapan + FROM ( + SELECT + wp.id provinsi_id, wp.kode provinsi_kode, wp.nama provinsi_nama, + wkk.id kabupaten_kota_id, wkk.kode kabupaten_kota_kode, wkk.nama kabupaten_kota_nama, + wk.id kecamatan_id, wk.kode kecamatan_kode, wk.nama kecamatan_nama, + wk.id kelurahan_desa_id, wk.kode kelurahan_desa_kode, wk.nama kelurahan_desa_nama, + mdd.pagu, salur_pagu as serapan, mdd.tahun as tahun_anggaran + FROM metrik_dana_desa mdd + JOIN wil_desa wd on wd.kode_int = mdd.kode_desa + JOIN wil_kecamatan wk on wk.id = wd.kecamatan_id + JOIN wil_kabupatenkota wkk on wkk.id = wk.kabupatenkota_id + JOIN wil_provinsi wp on wp.id = wkk.provinsi_id + WHERE wd.kode = %s + ) AS virtual_table """ - cur.execute(SQL, (kode_desa,)) + try: + cur.execute(SQL, (kode_desa,)) + except Exception as e: + print(e) + return [] result = cur.fetchall() return result @@ -1025,14 +1065,14 @@ class apiController: # wp.id provinsi_id, wp.kode provinsi_kode, wp.nama provinsi_nama, # wkk.id kabupaten_kota_id, wkk.kode kabupaten_kota_kode, wkk.nama kabupaten_kota_nama, # wk.id kecamatan_id, wk.kode kecamatan_kode, wk.nama kecamatan_nama, - # wkd.id kelurahan_desa_id, wkd.kode kelurahan_desa_kode, wkd.nama kelurahan_desa_nama, + # wk.id kelurahan_desa_id, wk.kode kelurahan_desa_kode, wk.nama kelurahan_desa_nama, # mpd.jenis_pendamping, mpd.jumlah # from metric_pendamping_desa mpd - # inner join wil_desa wkd on mpd.kelurahan_desa_id = wkd.id - # inner join wil_kecamatan wk on wkd.kecamatan_id = wk.id + # inner join wil_desa wkd on mpd.kelurahan_desa_id = wk.id + # inner join wil_kecamatan wk on wk.kecamatan_id = wk.id # inner join wil_kabupatenkota wkk on wk.kabupatenkota_id = wkk.id # inner join wil_provinsi wp on wkk.provinsi_id = wp.id - # WHERE wkd.kode = %s + # WHERE wk.kode = %s # ) AS virtual_table GROUP BY jenis_pendamping ORDER BY "SUM(jumlah)" DESC # LIMIT 1000; # """ @@ -1049,13 +1089,13 @@ class apiController: WHEN mkd.jumlah > 0 THEN 'Kopmer' ELSE 'Non Kopmer' END AS status_koperasi, - COUNT(DISTINCT wkd.id) AS jumlah_desa + COUNT(DISTINCT wk.id) AS jumlah_desa FROM metric_koperasi_desa mkd - INNER JOIN wil_desa wkd ON mkd.kelurahan_desa_id = wkd.id - INNER JOIN wil_kecamatan wk ON wkd.kecamatan_id = wk.id - INNER JOIN wil_kabupatenkota wkk ON wk.kabupatenkota_id = wkk.id - INNER JOIN wil_provinsi wp ON wkk.provinsi_id = wp.id - WHERE wkd.kode = %s + JOIN wil_desa wd on wd.kode_int = mkd.kode_desa + JOIN wil_kecamatan wk on wk.id = wd.kecamatan_id + JOIN wil_kabupatenkota wkk on wkk.id = wk.kabupatenkota_id + JOIN wil_provinsi wp on wp.id = wkk.provinsi_id + WHERE wk.kode = %s GROUP BY status_koperasi LIMIT 50000; """ diff --git a/app/routes.py b/app/routes.py index b9982b6..d092db8 100644 --- a/app/routes.py +++ b/app/routes.py @@ -31,7 +31,13 @@ def get_connection(): finally: if conn is not None and conn.is_connected(): conn.close() - + +@main.route('/api/status/danadesa//') +def get_total_dana_by_level(level,kode): + with get_connection() as conn: + result = apiController.getTotalDana(conn,level,kode ) + return jsonify(result) + #======================================================== # MAIN ROUTE #======================================================== @@ -243,7 +249,8 @@ def get_status_by_desa(kode_prov, kode_kabkota, kode_kecamatan, kode_desa): @main.route('/api/desa/koperasi/') def get_koperasi_by_desa(kode_desa): - data = apiController.getDesaDenganAtauTanpaKopmerDesa(conn, kode_desa) + with get_connection() as conn: + data = apiController.getDesaDenganAtauTanpaKopmerDesa(conn, kode_desa) return jsonify(data) @main.route('/api/desa/pendamping/') diff --git a/templates/index.html b/templates/index.html index 15abcc9..ddbbbb8 100644 --- a/templates/index.html +++ b/templates/index.html @@ -284,33 +284,27 @@ let klasifikasiHTML = "
  • Tidak ada data
  • "; if (Array.isArray(status?.[0])) { - indexDesaHTML = status[0] + provIndexDesaHTML = status[0] .map(d => `${d[1]}: ${d[4]} / `) .join(""); - bumdesHTML = status[1] + provBumdesHTML = status[1] .map(dt => `${dt[0]}:${dt[1]} / `) .join(""); - danadesaHTML = `Dana :${status[2].jumlah_per_m}, Persentase : ${status[2].persentage}%`; - serapanHTML = status[3] - .map(([jabatan, nilai]) => { - const alias = jabatan === 'Pendamping Lokal Desa' ? 'PLD' : - jabatan === 'Pendamping Desa' ? 'PD' : - jabatan; - return `${alias}: ${nilai}`; - }).join(""); - - koperasiHTML = status[4] + const raw = Number(status[5]); + provDanaTotalHTML = `Total : ${formatWithUnit(raw)}`; + provDanadesaHTML = `Total : ${status[2].jumlah_per_m}, Persentase : ${status[2].persentage}%`; + provKoperasiHTML = status[4] .map(dt => `${dt[0]}: ${dt[1]} / `) .join(""); } const popupContent = ` ${feature.properties.nama}
    Status Desa: -
  • IDM - ${indexDesaHTML}
  • -
  • BUM - ${bumdesHTML}
  • -
  • DD - ${danadesaHTML}
  • -
  • SERAPAN - ${serapanHTML}
  • -
  • KOPERASI - ${koperasiHTML}
  • +
  • IDM - ${provIndexDesaHTML}
  • +
  • BUM - ${provBumdesHTML}
  • +
  • DD - ${provDanaTotalHTML}
  • +
  • SERAPAN - ${provDanadesaHTML}
  • +
  • KOPERASI - ${provKoperasiHTML}
  • `; layer.bindPopup(popupContent).openPopup(e.latlng); @@ -322,15 +316,19 @@ let klasifikasiHTML = "
  • Tidak ada data
  • "; if (Array.isArray(status?.[0])) { - indexDesaHTML = status[0] + kabindexDesaHTML= status[0] .map(d => `${d[1]}: ${d[5]} / `) .join(""); - bumdesHTML = status[1] + kabbumdesHTML = status[1] .map(dt => `${dt[0]}:${dt[1]} / `) .join(""); - danadesaHTML = `Dana :${status[2].jumlah_per_m}, Persentase : ${status[2].persentage}%`; - serapanHTML = status[3] + + const raw = Number(status[5]); + kabdanaTotalHTML = `Total : ${formatWithUnit(raw)}`; + + kabdanadesaHTML = `Dana :${status[2].jumlah_per_m}, Persentase : ${status[2].persentage}%`; + kabserapanHTML = status[3] .map(([jabatan, nilai]) => { const alias = jabatan === 'Pendamping Lokal Desa' ? 'PLD' : jabatan === 'Pendamping Desa' ? 'PD' : @@ -338,18 +336,18 @@ return `${alias}: ${nilai} /`; }).join(""); - koperasiHTML = status[4] + kabkoperasiHTML = status[4] .map(dt => `${dt[0]}: ${dt[1]} / `) .join(""); } const popupContent = ` ${feature.properties.nama}
    Status Desa (Kabupaten): -
  • IDM - ${indexDesaHTML}
  • -
  • BUM - ${bumdesHTML}
  • -
  • DD - ${danadesaHTML}
  • -
  • SERAPAN - ${serapanHTML}
  • -
  • KOPERASI - ${koperasiHTML}
  • +
  • IDM - ${kabindexDesaHTML}
  • +
  • BUM - ${kabbumdesHTML}
  • +
  • DD - ${kabdanaTotalHTML}
  • +
  • SERAPAN - ${kabdanadesaHTML}
  • +
  • KOPERASI - ${kabkoperasiHTML}
  • `; layer.bindPopup(popupContent).openPopup(e.latlng); @@ -357,20 +355,25 @@ } else if (currentLevel === 'kecamatan'){ const province_code = localStorage.getItem('kode_provinsi') const region_code = localStorage.getItem('kode_kabupatenkota') - localStorage.setItem('kode_kecamatan',feature.properties.kode) + localStorage.setItem('kode_kecamatan',feature.properties.id) const status = await fetchStatusDesaByKecamatan(province_code, region_code, feature.properties.kode) let klasifikasiHTML = "
  • Tidak ada data
  • "; if (Array.isArray(status?.[0])) { - indexDesaHTML = status[0] + kecindexDesaHTML = status[0] .map(d => `${d[1]}: ${d[6]} / `) .join(""); - bumdesHTML = status[1] + kecbumdesHTML = status[1] .map(dt => `${dt[0]}:${dt[1]} / `) .join(""); - danadesaHTML = `Dana :${status[2].jumlah_per_m}, Persentase : ${status[2].persentage}%`; - serapanHTML = status[3] + + const raw = Number(status[5]); + kecdanaTotalHTML = `Total : ${formatWithUnit(raw)}`; + + kecdanadesaHTML = `Total: ${formatWithUnit(status[2][0])} / Persen: ${Math.round(status[2][1])}`; + + kecserapanHTML = status[3] .map(([jabatan, nilai]) => { const alias = jabatan === 'Pendamping Lokal Desa' ? 'PLD' : jabatan === 'Pendamping Desa' ? 'PD' : @@ -378,7 +381,7 @@ return `${alias}: ${nilai} /`; }).join(""); - koperasiHTML = status[4] + keckoperasiHTML = status[4] .map(dt => `${dt[0]}: ${dt[1]} / `) .join(""); } @@ -387,12 +390,11 @@ ` ${feature.properties.nama} Status Desa (Kecamatan): - Status Desa: -
  • IDM - ${indexDesaHTML}
  • -
  • BUM - ${bumdesHTML}
  • -
  • DD - ${danadesaHTML}
  • -
  • SERAPAN - ${serapanHTML}
  • -
  • KOPERASI - ${koperasiHTML}
  • +
  • IDM - ${kecindexDesaHTML}
  • +
  • BUM - ${kecbumdesHTML}
  • +
  • DD - ${kecdanaTotalHTML}
  • +
  • SERAPAN - ${kecdanadesaHTML}
  • +
  • KOPERASI - ${keckoperasiHTML}
  • ` layer.bindPopup(popupContent).openPopup(e.latlng); }else { @@ -400,19 +402,24 @@ const province_code = localStorage.getItem('kode_provinsi') const region_code = localStorage.getItem('kode_kabupatenkota') const district_code = localStorage.getItem('kode_kecamatan') - + console.log(province_code, region_code , district_code, feature.properties.kode) const status = await fetchStatusDesaByDesa(province_code, region_code , district_code, feature.properties.kode); let klasifikasiHTML = "
  • Tidak ada data
  • "; if (Array.isArray(status?.[0])) { indexDesaHTML = status[0] - .map(d => `${d[1]}: ${d[5]} / `) + .map(d => `${d[1]}`) .join(""); bumdesHTML = status[1] .map(dt => `${dt[0]}:${dt[1]} / `) .join(""); - danadesaHTML = `Dana :${status[2].jumlah_per_m}, Persentase : ${status[2].persentage}%`; + + const raw = Number(status[5]); + danaTotalHTML = `Total : ${formatWithUnit(raw)}`; + danadesaHTML = status[2].map(([serapan,persen]) => { + return `Nominal - ${formatWithUnit(serapan)} / Persen - ${Math.round(persen)}%`; + }); serapanHTML = status[3] .map(([jabatan, nilai]) => { const alias = jabatan === 'Pendamping Lokal Desa' ? 'PLD' : @@ -430,8 +437,8 @@ Status Desa (Desa):
  • IDM - ${indexDesaHTML}
  • BUM - ${bumdesHTML}
  • -
  • DD - ${danadesaHTML}
  • -
  • SERAPAN - ${serapanHTML}
  • +
  • DD - ${danaTotalHTML}
  • +
  • SERAPAN - ${danadesaHTML}
  • KOPERASI - ${koperasiHTML}
  • `; @@ -453,14 +460,35 @@ }); } + function formatWithUnit(value) { + const abs = Math.abs(value); + let scaled, unit; + + if (abs >= 1e12) { scaled = value / 1e12; unit = 'Triliun'; } + else if (abs >= 1e9) { scaled = value / 1e9; unit = 'Miliar'; } + else if (abs >= 1e6) { scaled = value / 1e6; unit = 'Juta'; } + else if (abs >= 1e3) { scaled = value / 1e3; unit = 'Ribu'; } + else { scaled = value; unit = ''; } + const formatted = scaled.toLocaleString('id-ID', { + minimumFractionDigits: unit ? 2 : 0, + maximumFractionDigits: unit ? 2 : 0 + }); + + return unit + ? `${formatted} ${unit}` + : formatted; + } + async function fetchStatusDesaByProvinsi(kodeProvinsi) { const url = `http://localhost:5000/api/status-provinsi/${kodeProvinsi}`; + const urltdd = `http://localhost:5000/api/status/danadesa/provinsi/${kodeProvinsi}`; const urldd = `http://localhost:5000/api/provinsi/serapan/${kodeProvinsi}`; const urlpd = `http://localhost:5000//api/provinsi/pendamping/${kodeProvinsi}` const urlkop = `http://localhost:5000//api/provinsi/koperasi/${kodeProvinsi}` const urlbd = `http://localhost:5000/api/provinsi/bumdes/${kodeProvinsi}`; try { const res = await fetch(url); + const tdd = await fetch(urltdd) const bumdes = await fetch(urlbd) const dd = await fetch(urldd) const pd = await fetch(urlpd) @@ -468,12 +496,13 @@ if (!res.ok && !bumdes.ok && !dd.ok) throw new Error(`HTTP ${res.status}`); const IPD = await res.json() + const dtdd = await tdd.json() const bd = await bumdes.json() const danadesa = await dd.json() const dtpd = await pd.json() const dtkop = await kop.json() - - return [IPD,bd, danadesa, dtpd, dtkop]; + console.log([IPD, bd, danadesa, dtpd, dtkop, dtdd]); + return [IPD, bd, danadesa, dtpd, dtkop, dtdd]; } catch (err) { console.error("Gagal ambil status desa:", err); return null; @@ -482,12 +511,14 @@ async function fetchStatusDesaByKabupatenkota(kode_prov, kode_kabkota) { const url = `http://localhost:5000/api/status-kabupatenkota/${kode_prov}/${kode_kabkota}` + const urltdd = `http://localhost:5000/api/status/danadesa/kabkota/${kode_kabkota}`; const urldd = `http://localhost:5000/api/kabkota/serapan/${kode_kabkota}`; const urlpd = `http://localhost:5000//api/kabkota/pendamping/${kode_kabkota}` const urlkop = `http://localhost:5000//api/kabkota/koperasi/${kode_kabkota}` const urlbd = `http://localhost:5000/api/kabkota/bumdes/${kode_kabkota}`; try{ const res = await fetch(url) + const tdd = await fetch(urltdd) const bumdes = await fetch(urlbd) const dd = await fetch(urldd) const pd = await fetch(urlpd) @@ -499,8 +530,9 @@ const danadesa = await dd.json() const dtpd = await pd.json() const dtkop = await kop.json() + const dttd = await tdd.json() - return [IPD,bd, danadesa, dtpd, dtkop]; + return [IPD,bd, danadesa, dtpd, dtkop,dttd]; }catch(err){ console.log(err) return null; @@ -509,12 +541,14 @@ async function fetchStatusDesaByKecamatan(province_code, region_code, district_code){ const url = `http://localhost:5000/api/status-kecamatan/${province_code}/${region_code}/${district_code}` + const urltdd = `http://localhost:5000/api/status/danadesa/kecamatan/${district_code}`; const urldd = `http://localhost:5000/api/kecamatan/serapan/${district_code}`; const urlpd = `http://localhost:5000//api/kecamatan/pendamping/${district_code}` const urlkop = `http://localhost:5000//api/kecamatan/koperasi/${district_code}` const urlbd = `http://localhost:5000/api/kecamatan/bumdes/${district_code}`; try { const res = await fetch(url) + const tdd = await fetch(urltdd) const bumdes = await fetch(urlbd) const dd = await fetch(urldd) const pd = await fetch(urlpd) @@ -526,8 +560,9 @@ const danadesa = await dd.json() const dtpd = await pd.json() const dtkop = await kop.json() + const dttd = await tdd.json() - return [IPD,bd, danadesa, dtpd, dtkop];; + return [IPD,bd, danadesa, dtpd, dtkop, dttd];; } catch (error) { console.log(error) return null @@ -536,12 +571,14 @@ async function fetchStatusDesaByDesa(province_code, region_code, district_code, village_code){ const url = `http://localhost:5000//api/desa/status/${province_code}/${region_code}/${district_code}/${village_code}` + const urltdd = `http://localhost:5000/api/status/danadesa/desa/${village_code}`; const urldd = `http://localhost:5000/api/desa/serapan/${village_code}`; const urlpd = `http://localhost:5000//api/desa/pendamping/${village_code}` const urlkop = `http://localhost:5000//api/desa/koperasi/${village_code}` const urlbd = `http://localhost:5000/api/desa/bumdes/${village_code}`; try { const res = await fetch(url) + const tdd = await fetch(urltdd) const bumdes = await fetch(urlbd) const dd = await fetch(urldd) const pd = await fetch(urlpd) @@ -553,8 +590,9 @@ const danadesa = await dd.json() const dtpd = await pd.json() const dtkop = await kop.json() + const dttd = await tdd.json() - return [IPD,bd, danadesa, dtpd, dtkop];; + return [IPD,bd, danadesa, dtpd, dtkop, dttd];; } catch (error) { console.log(error) return null