dashboard.py 16.2 KB
import logging
from datetime import timedelta, datetime

from tangsel.tools import get_settings, date_from_str, ymd, dmy, tampil_bulan
from pyramid.view import view_config
from sqlalchemy import func, and_

from . import BaseView
from ..models import Kecamatan, Kelurahan, PbbmDBSession, PembayaranSppt, Sppt
from tangsel.base.models import UserArea, ResDesa, UserGroup, Group

log = logging.getLogger(__name__)


class View(BaseView):
    def get_kelurahan(self):
        kelurahans = Kelurahan.query(). \
                    filter_by(kd_kecamatan=self.ses['kd_kecamatan']). \
                    order_by('kd_kelurahan').all()

        if self.req.user :
            kecamatan = self.ses['kd_kecamatan']
            kelurahan = self.ses['kd_kelurahan']
            data_awal = UserArea.user_desa(self.req.user.id).all()

        if data_awal :
            kdkec = tuple(k.kode[6:9] for k in data_awal if hasattr(k, 'kode') and k.kode)
            kdkel = tuple(k.kode[10:13] for k in data_awal if hasattr(k, 'kode') and k.kode)
            iddesa = tuple(k.desa_id for k in data_awal if hasattr(k, 'desa_id') and k.desa_id)

            if hasattr(data_awal[0], 'group_name') and data_awal[0].group_name in ('PBBM UPT'):
                kelurahans = Kelurahan.query(). \
                    filter(Kelurahan.kd_kecamatan == kecamatan). \
                    order_by('kd_kecamatan','kd_kelurahan').all()
                    
            elif hasattr(data_awal[0], 'group_name') and data_awal[0].group_name in ('PBBM Kecamatan'):
                self.ses['kd_kecamatan'] = kdkec[0]
                kelurahans = Kelurahan.query(). \
                    filter(Kelurahan.kd_kecamatan.in_(kdkec)). \
                    order_by('kd_kecamatan','kd_kelurahan').all()
            else:
                user = UserArea.allow_area(self.req.user.id, iddesa)
                if user :
                    kecamatan = kdkec
                    self.ses['kd_kecamatan'] = kdkec[0]
                    kelurahan = kdkel
                    self.ses['kd_kelurahan'] = kdkel[0]
                    kelurahans = Kelurahan.query(). \
                        filter(and_(Kelurahan.kd_kecamatan.in_(kecamatan), Kelurahan.kd_kelurahan.in_(kelurahan))). \
                        order_by('kd_kecamatan','kd_kelurahan').all()
        else:
            kelurahans = Kelurahan.query(). \
                filter_by(kd_kecamatan=self.ses['kd_kecamatan']). \
                order_by('kd_kelurahan').all()
                
        return kelurahans

    @view_config(route_name='pbbm-dashboard', renderer='templates/dashboard.pt')
    def view_list(self):
        settings = get_settings()
        # eis_page_size = 'eis_page_size' in settings and int(settings['eis_page_size']) or 10
        # pages = int(round(Kecamatan.query().count() / float(eis_page_size) + 0.49))
        eis_interval = 'eis_interval' in settings and int(
            settings['eis_interval']) or 5000
        reload = 'eis_reload' in settings and int(
            settings['eis_reload']) or 3600000
        kecamatans = Kecamatan.query().order_by('kd_kecamatan').all()
        if self.req.user :  
            kecamatan = self.ses['kd_kecamatan']
            data_awal = UserArea.user_desa(self.req.user.id).all()

        if data_awal :
            kdkec = tuple(k.kode[6:9] for k in data_awal if hasattr(k, 'kode') and k.kode)
            kdkel = tuple(k.kode[10:13] for k in data_awal if hasattr(k, 'kode') and k.kode)
            iddesa = tuple(k.desa_id for k in data_awal if hasattr(k, 'desa_id') and k.desa_id)

            if hasattr(data_awal[0], 'group_name') and data_awal[0].group_name in ('PBBM UPT'):
                kecamatans = Kecamatan.query(). \
                    filter(Kecamatan.kd_kecamatan.in_(kdkec)). \
                    order_by('kd_kecamatan').all()
                    
            elif hasattr(data_awal[0], 'group_name') and data_awal[0].group_name in ('PBBM Kecamatan'):
                self.ses['kd_kecamatan'] = kdkec[0]
                kecamatans = Kecamatan.query(). \
                    filter(Kecamatan.kd_kecamatan.in_(kdkec)). \
                    order_by('kd_kecamatan').all()
            else:
                user = UserArea.allow_area(self.req.user.id, iddesa)
                if user :
                    kecamatan = kdkec
                    self.ses['kd_kecamatan'] = kdkec[0]
                    
                    kecamatans = Kecamatan.query(). \
                        filter(Kecamatan.kd_kecamatan.in_(kecamatan)). \
                        order_by('kd_kecamatan').all()

        return dict(kecamatans=kecamatans,
                    tgl=dmy(self.now),
                    nama_bulan=tampil_bulan(
                        datetime.now().date().month).upper(),
                    kelurahans=self.get_kelurahan(),
                    interval=eis_interval,
                    reload=reload)
        # return {"reload": 1000}

    def get_realisasi(self):
        tahun = str(self.ses["tahun"])
        query = PbbmDBSession.query(func.sum(PembayaranSppt.jml_sppt_yg_dibayar).label('bayar'),
                                    func.sum(PembayaranSppt.denda_sppt).label('denda'))
        qry = query.filter(
            PembayaranSppt.tgl_pembayaran_sppt.between(
                date_from_str(f'{tahun}-01-01'),
                date_from_str(f'{tahun}-12-31')))
        row = qry.filter(PembayaranSppt.thn_pajak_sppt == tahun).first()
        a_bayar = row and row.bayar or 0
        a_denda = row and row.denda or 0
        sum_pokok = a_bayar #- a_denda
        sum_denda = a_denda
        row = qry.filter(PembayaranSppt.thn_pajak_sppt < tahun).first()
        a_bayar = row and row.bayar or 0
        a_denda = row and row.denda or 0
        sum_piutang = a_bayar #- a_denda
        sum_denda += a_denda

        query2 = PbbmDBSession.query(
            func.sum(Sppt.pbb_yg_harus_dibayar_sppt).label('ketetapan'))
        row2 = query2.filter(Sppt.thn_pajak_sppt == tahun,
                             Sppt.status_pembayaran_sppt != '2').first()
        a_ketetapan = row2 and row2.ketetapan or 0

        return {"sum_pokok": sum_pokok,
                "sum_piutang": sum_piutang,
                "sum_denda": sum_denda,
                "sum_target": a_ketetapan,
                }

    def get_harian(self):

        # amt_tahun = amt_bulan = amt_minggu = amt_hari = amt_ke
        # tetapan = 0
        amt_realisasi = amt_piutang = amt_denda = 0
        # now = datetime.now()
        # # if devel():
        tahun = str(self.ses["tahun"])
        # now = date_from_str(f'{tahun}-01-10')
        tgl = ymd(self.now)
        akhir = date_from_str(tgl)

        # hitung ketetapan tahun berjalan
        # qry = PbbmDBSession.query(func.sum(Sppt.pbb_yg_harus_dibayar_sppt).label('ketetapan')). \
        #     filter(Sppt.thn_pajak_sppt == tgl[:4],
        #            Sppt.status_pembayaran_sppt != '2')
        # row = self.filter_area(qry).first()
        # amt_ketetapan = row.ketetapan or 0
        # amt_ketetapan = locale.format("%d", amt_ketetapan, grouping=True)
        #
        awal = date_from_str(f"{tahun}-01-01")
        log.debug(awal)

        # hitung realisasi tahun pajak berjalan
        query = PbbmDBSession.query(func.sum(PembayaranSppt.jml_sppt_yg_dibayar).label('bayar'),
                                    func.sum(PembayaranSppt.denda_sppt).label('denda'))
        qry = query.filter(PembayaranSppt.tgl_pembayaran_sppt.between(awal, akhir),
                           PembayaranSppt.thn_pajak_sppt == tahun)
        amt_realisasi = self.filtered(qry)
        #
        # hitung realisasi piutang tahun pajak lalu
        qry = query.filter(PembayaranSppt.tgl_pembayaran_sppt.between(awal, akhir),
                           PembayaranSppt.thn_pajak_sppt < tahun)
        amt_piutang = self.filtered(qry)

        #
        # hitung realisasi denda
        qry = query.filter(
            PembayaranSppt.tgl_pembayaran_sppt.between(awal, akhir))
        bayar, denda = self.filter_number(qry)
        amt_denda = denda
        #
        # hitung realisasi tahunan
        # qry = query.filter(PembayaranSppt.tgl_pembayaran_sppt.between(awal, akhir))
        amt_tahun = amt_realisasi + amt_piutang

        # hitung realisasi bulanan
        awal = date_from_str("%s-01" % tgl[:7])
        qry = query.filter(
            PembayaranSppt.tgl_pembayaran_sppt.between(awal, akhir))
        amt_bulan = self.filtered(qry)
        # hitung realisasi harian
        qry = query.filter(PembayaranSppt.tgl_pembayaran_sppt == akhir)
        amt_hari = self.filtered(qry)
        # hitung minggu
        awal = akhir - timedelta(days=akhir.isoweekday())
        qry = query.filter(
            PembayaranSppt.tgl_pembayaran_sppt.between(awal, akhir))
        amt_minggu = self.filtered(qry)

        return dict(
            amt_tahun=amt_tahun,
            amt_bulan=amt_bulan,
            amt_minggu=amt_minggu,
            amt_hari=amt_hari,
            # ketetapan=amt_ketetapan,
            # realisasi=amt_realisasi,
            # piutang=amt_piutang,
            # denda=amt_denda
        )

    def get_table(self):
        awal = ymd(self.now)
        awal = date_from_str(awal)
        akhir = self.now + timedelta(days=1)
        ket = PbbmDBSession.query(
            func.count(Sppt.pbb_yg_harus_dibayar_sppt).label("cnt"),
            func.sum(Sppt.pbb_yg_harus_dibayar_sppt).label("ketetapan")). \
            filter(Sppt.thn_pajak_sppt == str(self.tahun)). \
            filter(Sppt.status_pembayaran_sppt != '2')
        real = PbbmDBSession.query(
            func.count(PembayaranSppt.jml_sppt_yg_dibayar).label("cnt"),
            func.sum(PembayaranSppt.jml_sppt_yg_dibayar).label("bayar"),
            func.sum(PembayaranSppt.denda_sppt).label("denda")). \
            filter(PembayaranSppt.thn_pajak_sppt == str(self.tahun))

        qry_today = PbbmDBSession.query(
            func.count(PembayaranSppt.jml_sppt_yg_dibayar).label("cnt"),
            func.sum(PembayaranSppt.jml_sppt_yg_dibayar).label("bayar"),
            func.sum(PembayaranSppt.denda_sppt).label("denda")) \
            .filter(PembayaranSppt.thn_pajak_sppt == str(self.tahun),
                    PembayaranSppt.tgl_pembayaran_sppt == awal)
        first = date_from_str(f"{self.tahun}-01-01")
        qry_piutang = PbbmDBSession.query(
            func.count(PembayaranSppt.jml_sppt_yg_dibayar).label("cnt"),
            func.sum(PembayaranSppt.jml_sppt_yg_dibayar).label("bayar"),
            func.sum(PembayaranSppt.denda_sppt).label("denda")) \
            .filter(PembayaranSppt.thn_pajak_sppt < str(self.tahun)) \
            .filter(PembayaranSppt.tgl_pembayaran_sppt.between(first, akhir))

        if self.kd_kecamatan != "000":
            areas = PbbmDBSession.query(
                func.concat(Kelurahan.kd_kecamatan, func.concat('.', Kelurahan.kd_kelurahan)).label(
                    "kode"),
                Kelurahan.nm_kelurahan.label("nama")).filter_by(kd_kecamatan=self.kd_kecamatan). \
                order_by('kd_kelurahan')
        else:
            areas = PbbmDBSession.query(Kecamatan.kd_kecamatan.label("kode"),
                                        Kecamatan.nm_kecamatan.label("nama")).\
                order_by('kd_kecamatan')
        result = []
        for area in areas:
            if self.kd_kecamatan == "000":
                ketetapan = ket.filter(Sppt.kd_kecamatan == area.kode).first()
                realisasi = real.filter(
                    PembayaranSppt.kd_kecamatan == area.kode).first()
                today = qry_today.filter(
                    PembayaranSppt.kd_kecamatan == area.kode).first()
                piutang = qry_piutang.filter(
                    PembayaranSppt.kd_kecamatan == area.kode).first()
            else:
                ketetapan = ket.filter(Sppt.kd_kecamatan == self.kd_kecamatan,
                                       Sppt.kd_kelurahan == area.kode[-3:]).first()
                realisasi = real.filter(PembayaranSppt.kd_kecamatan == self.kd_kecamatan,
                                        PembayaranSppt.kd_kelurahan == area.kode[-3:]).first()
                today = qry_today.filter(PembayaranSppt.kd_kecamatan == self.kd_kecamatan,
                                         PembayaranSppt.kd_kelurahan == area.kode[-3:]).first()
                piutang = qry_piutang.filter(PembayaranSppt.kd_kecamatan == self.kd_kecamatan,
                                             PembayaranSppt.kd_kelurahan == area.kode[-3:]).first()

            a_bayar = realisasi and realisasi.bayar or 0
            a_denda = realisasi and realisasi.denda or 0
            today_bayar = today and today.bayar or 0
            today_denda = today and today.denda or 0
            piutang_bayar = piutang and piutang.bayar or 0
            piutang_denda = piutang and piutang.denda or 0
            piutang_jml = piutang_bayar - piutang_denda
            denda_jml = a_denda + piutang_denda
            result.append({"kode": area.kode, "nama": area.nama,
                           "sppt_cnt": ketetapan and ketetapan.cnt or 0,
                           "sppt_jml": ketetapan and ketetapan.ketetapan or 0,
                           "today_cnt": today and today.cnt or 0,
                           "today_jml": today_bayar,#- today_denda,
                           "realisasi_cnt": realisasi and realisasi.cnt or 0,
                           "realisasi_jml": a_bayar, #- a_denda,
                           "piutang_jml": piutang_jml,
                           "denda_jml": denda_jml
                           })
        return result

    def get_series(self):
        tahun = str(self.ses["tahun"])
        tgl = ymd(self.now)
        akhir = date_from_str(tgl)
        result = []
        for series in range(29):
            tanggal = akhir - timedelta(days=30 - series)

            qry_row = PbbmDBSession.query(
                func.count(PembayaranSppt.jml_sppt_yg_dibayar).label("cnt"),
                func.sum(PembayaranSppt.jml_sppt_yg_dibayar).label("bayar"),
                func.sum(PembayaranSppt.denda_sppt).label("denda")) \
                .filter(PembayaranSppt.tgl_pembayaran_sppt == tanggal)

            if self.kd_kecamatan == "000":
                row = qry_row.first()
            else:
                row = qry_row.filter(
                    PembayaranSppt.kd_kecamatan == self.kd_kecamatan).first()

            if row:
                cnt = row and row.cnt or 0
                bayar = row and row.bayar or 0
                denda = row and row.denda or 0

                result.append(
                    {"tanggal": ymd(tanggal), "cnt": cnt, "bayar": bayar,
                     "denda": denda, "pokok": bayar - denda})
            else:
                result.append(
                    {"tanggal": ymd(tanggal), "cnt": 0, "bayar": 0,
                     "denda": 0, "pokok": 0})
        return result

    @view_config(route_name='pbbm-dashboard-act', renderer='json')
    def view_act(self):
        settings = get_settings()
        # eis_page_size = 'eis_page_size' in settings and int(settings['eis_page_size']) or 10
        # pages = int(round(Kecamatan.query().count() / float(eis_page_size) + 0.49))
        # eis_interval = 'eis_interval' in settings and int(settings['eis_interval']) or 5000
        # reload = 'eis_reload' in settings and int(settings['eis_reload']) or 3600000
        # result = dict(interval=eis_interval,
        #               reload=reload)
        url_dict = self.req.matchdict
        act = url_dict["act"]
        if act == "realisasi":
            return self.get_realisasi()
        elif act == "harian":
            return self.get_harian()
        elif act == "area":
            kelurahans = self.get_kelurahan()
            values = {}
            for k in kelurahans:
                values[k.kd_kelurahan] = k.nm_kelurahan
            log.debug(kelurahans)
            return {"default": self.kd_kelurahan,
                    "kelurahans": values}  # {"kelurahans": kelurahans.to_dict() }
        elif act == "table":
            return self.get_table()
        elif act == "series":
            return self.get_series()