realisasi_all_report.py 20 KB
import math
import os
from datetime import datetime

from tangsel.base import get_params
#from py3o.template import Template
from pyramid.httpexceptions import HTTPNotFound
from pyramid.view import (
    view_config,
)
from sqlalchemy import func, and_, literal_column
from sqlalchemy.sql import select

from ..models import PbbmDBSession
from ..models import (
    PembayaranSppt, Kecamatan, Kelurahan, Sppt
)
from ..tools import (
    csv_response,
    dMy,
    thousand,
    BUKUS,
    odt_export
)
from ..views import (BaseView)


class ViewRpt(BaseView):
    @view_config(route_name='pbbm-realisasi-all-rpt', renderer='csv')
    def view_rpt(self):
        request = self.req
        ses = request.session
        params = request.params
        url_dict = request.matchdict
        buku_min = BUKUS[self.buku][1]
        buku_max = BUKUS[self.buku][2]
        uid = request.user.id
        tgl = datetime.now().strftime('%d-%m-%Y')

        lalu = select(PembayaranSppt.kd_propinsi,
                       PembayaranSppt.kd_dati2,
                       PembayaranSppt.kd_kecamatan,
                       PembayaranSppt.kd_kelurahan,
                       PembayaranSppt.kd_blok,
                       PembayaranSppt.no_urut,
                       PembayaranSppt.kd_jns_op,
                       PembayaranSppt.thn_pajak_sppt.label('tahun'),
                       literal_column("'0'").label("nama"),
                       literal_column("0").label("qty_pokok"),
                       literal_column("0").label("amt_pokok"),
                       func.count(PembayaranSppt.kd_propinsi).label('qty_lalu'),
                       func.sum(PembayaranSppt.jml_sppt_yg_dibayar).label('amt_lalu'),
                       literal_column("0").label("qty_kini"),
                       literal_column("0").label("amt_kini"),
                       )

        kini = select(PembayaranSppt.kd_propinsi,
                       PembayaranSppt.kd_dati2,
                       PembayaranSppt.kd_kecamatan,
                       PembayaranSppt.kd_kelurahan,
                       PembayaranSppt.kd_blok,
                       PembayaranSppt.no_urut,
                       PembayaranSppt.kd_jns_op,
                       PembayaranSppt.thn_pajak_sppt.label('tahun'),
                       literal_column("'0'").label("nama"),
                       literal_column("0").label("qty_pokok"),
                       literal_column("0").label("amt_pokok"),
                       literal_column("0").label("qty_lalu"),
                       literal_column("0").label("amt_lalu"),
                       func.count(PembayaranSppt.kd_propinsi).label('qty_kini'),
                       func.sum(PembayaranSppt.jml_sppt_yg_dibayar).label('amt_kini'), )

        sppt = select(Sppt.kd_propinsi, Sppt.kd_dati2,
                       Sppt.kd_kecamatan, Sppt.kd_kelurahan,
                       Sppt.kd_blok, Sppt.no_urut, Sppt.kd_jns_op,
                       Sppt.thn_pajak_sppt.label('tahun'),
                       Sppt.nm_wp_sppt.label('nama'),
                       literal_column("1").label("qty_pokok"),
                       Sppt.pbb_yg_harus_dibayar_sppt.label("amt_pokok"),
                       literal_column("0").label("qty_lalu"),
                       literal_column("0").label("amt_lalu"),
                       literal_column("0").label("qty_kini"),
                       literal_column("0").label("amt_kini"),
                       )

        if url_dict['rpt'] == 'csv':
            query = query_reg(self, request, ses, lalu, kini, sppt, buku_min, buku_max)
            row = query.first()
            header = row._mapping.keys()
            rows = []
            for item in query.all():
                qty_jml = int(item[4]) + int(item[6])
                amt_jml = int(item[5]) + int(item[7])
                prsn_jml = round(float(amt_jml / item[3]) * 100)
                qty_sisa = int(item[2]) - int(item[4]) - int(item[6])
                amt_sisa = int(item[3]) - int(item[5]) - int(item[7])
                prsn_sisa = round(float(amt_sisa / item[3]) * 100)
                items = item[0], item[1], item[2], item[3], item[4], item[5], item[6], item[
                    7], qty_jml, amt_jml, prsn_jml, qty_sisa, amt_sisa, prsn_sisa
                rows.append(list(items))

            filename = 'realisasi_report.csv'
            value = {
                'header': header,
                'rows': rows,
            }
            return csv_response(request, value, filename)

        ####### UNTUK MENAMPILKAN REPORT ODTNYA BUKA PAGAR #######
        if url_dict['rpt'] == 'pdf':
            class Item(object):
                pass

            row = query_reg(self, request, ses, lalu, kini, sppt, buku_min, buku_max)
            if not row:
                raise HTTPNotFound
            _here = os.path.dirname(__file__)  # get current folder -> views
            path = os.path.dirname(_here)  # mundur 1 level
            path = os.path.join(path, 'reports/')
            jenis = os.path.splitext('realisasi_report.odt')[0]

            tmp = get_params("temp_dir", '/tmp')
            file = os.path.join(tmp, jenis + '_pbbm')

            template = Template(path + jenis + '.odt', file + '.odt')

            documents = list()
            amt_pokok_jml = 0
            amt_pokok_jml = 0
            amt_lalu_jml = 0
            amt_kini_jml = 0
            amt_jml_jml = 0
            sisa_jml = 0
            prsn_jml = 0

            for dt in row:
                document = Item()
                document.kode = dt.kode
                document.nama = dt.nama
                document.qty_pokok = dt.qty_pokok
                document.amt_pokok = thousand(dt.amt_pokok)
                document.qty_lalu = dt.qty_lalu
                document.amt_lalu = thousand(dt.amt_lalu)
                document.qty_kini = dt.qty_kini
                document.amt_kini = thousand(dt.amt_kini)
                qty_jml = int(dt.qty_kini) + int(dt.qty_lalu)
                amt_jml = int(dt.amt_kini) + int(dt.amt_lalu)
                prsn_jml = round(float((dt.amt_kini + dt.amt_lalu) / dt.amt_pokok) * 100)
                qty_sisa = int(dt.qty_pokok) - int(dt.qty_kini) - int(dt.qty_lalu)
                amt_sisa = int(dt.amt_pokok) - int(dt.amt_kini) - int(dt.amt_lalu)
                prsn_sisa = round(float(amt_sisa / dt.amt_pokok) * 100)
                document.qty_jml = qty_jml
                document.amt_jml = thousand(amt_jml)
                document.prsn_jml = prsn_jml
                document.qty_sisa = qty_sisa
                document.amt_sisa = thousand(amt_sisa)
                document.prsn_sisa = prsn_sisa

                amt_pokok_jml = amt_pokok_jml + dt.amt_pokok
                amt_lalu_jml = amt_lalu_jml + dt.amt_lalu
                amt_kini_jml = amt_kini_jml + dt.amt_kini
                amt_jml_jml = amt_jml_jml + amt_jml
                sisa_jml = sisa_jml + amt_sisa
                # prsn_jml      = prsn_jml + prsn_sisa

                documents.append(document)

            item = Item()
            item.company = request.company
            item.departement = request.departement
            item.address = request.address
            item.tahun = request.session['tahun']
            kecamatan_nm = PbbmDBSession.query(Kecamatan.nm_kecamatan).select_from(Kecamatan). \
                filter(Kecamatan.kd_kecamatan == ses['kd_kecamatan']).first()
            kelurahan_nm = PbbmDBSession.query(Kelurahan.nm_kelurahan).select_from(Kelurahan). \
                filter(Kelurahan.kd_kelurahan == ses['kd_kelurahan']).first()
            item.kd_kecamatan = ses['kd_kecamatan']
            item.kd_kelurahan = ses['kd_kelurahan']
            item.kecamatan = kecamatan_nm
            item.kelurahan = kelurahan_nm
            item.tanggal = tgl
            item.amt_pokok_jml = thousand(amt_pokok_jml)
            item.amt_lalu_jml = thousand(amt_lalu_jml)
            item.amt_kini_jml = thousand(amt_kini_jml)
            item.amt_jml_jml = thousand(amt_jml_jml)
            item.sisa_jml = thousand(sisa_jml)
            tprsnjml = (sisa_jml / amt_pokok_jml) * 100
            item.prsn_jml = math.floor(tprsnjml)
            item.tanggal_awal = dMy(ses['dt_awal'])
            item.tanggal_akhir = dMy(ses['dt_akhir'])

            data = {}
            data['documents'] = documents
            data['item'] = item
            # data['document'] = document
            template.render(data)

            ext = 'pdf'
            odt = odt_export(request, file, ext)
            if not odt:
                raise HTTPNotFound
            else:
                return odt


##########
# query   #
##########

def query_reg(self, request, ses, lalu, kini, sppt, buku_min, buku_max):
    if ses['kd_kecamatan'] == '000':
        sppt = sppt.where(and_(Sppt.thn_pajak_sppt == str(ses['tahun']),
                               Sppt.status_pembayaran_sppt < '2',
                               Sppt.pbb_yg_harus_dibayar_sppt.between(buku_min, buku_max))
                          )
        kini = kini.where(and_(PembayaranSppt.thn_pajak_sppt == str(ses['tahun']),
                               PembayaranSppt.tgl_pembayaran_sppt >= self.dt_awal,
                               PembayaranSppt.tgl_pembayaran_sppt <= self.dt_akhir, )). \
            group_by(PembayaranSppt.kd_propinsi,
                     PembayaranSppt.kd_dati2,
                     PembayaranSppt.kd_kecamatan,
                     PembayaranSppt.kd_kelurahan,
                     PembayaranSppt.kd_blok,
                     PembayaranSppt.no_urut,
                     PembayaranSppt.kd_jns_op,
                     PembayaranSppt.thn_pajak_sppt, ). \
            having(func.sum(PembayaranSppt.jml_sppt_yg_dibayar).between(buku_min, buku_max))
        lalu = lalu.where(and_(PembayaranSppt.thn_pajak_sppt == str(ses['tahun']),
                               PembayaranSppt.tgl_pembayaran_sppt < self.dt_awal, )). \
            group_by(PembayaranSppt.kd_propinsi,
                     PembayaranSppt.kd_dati2,
                     PembayaranSppt.kd_kecamatan,
                     PembayaranSppt.kd_kelurahan,
                     PembayaranSppt.kd_blok,
                     PembayaranSppt.no_urut,
                     PembayaranSppt.kd_jns_op,
                     PembayaranSppt.thn_pajak_sppt, ). \
            having(func.sum(PembayaranSppt.jml_sppt_yg_dibayar).between(buku_min, buku_max))
        query_join = sppt.union(lalu.union(kini)).alias('query_join')
        query = PbbmDBSession.query(Kecamatan.kd_kecamatan.label('kode'),
                                    Kecamatan.nm_kecamatan.label('nama'),
                                    func.sum(query_join.c.qty_pokok).label('qty_pokok'),
                                    func.sum(query_join.c.amt_pokok).label('amt_pokok'),
                                    func.sum(query_join.c.qty_lalu).label('qty_lalu'),
                                    func.sum(query_join.c.amt_lalu).label('amt_lalu'),
                                    func.sum(query_join.c.qty_kini).label('qty_kini'),
                                    func.sum(query_join.c.amt_kini).label('amt_kini'),
                                    literal_column('0').label('qty_jml'),
                                    literal_column('0').label('amt_jml'),
                                    literal_column('0').label('prsn_jml'),
                                    literal_column('0').label('qty_sisa'),
                                    literal_column('0').label('amt_sisa'),
                                    literal_column('0').label('prsn_sisa')
                                    ). \
            join(query_join, and_(
            Kecamatan.kd_kecamatan == query_join.c.kd_kecamatan)). \
            group_by(Kecamatan.kd_kecamatan, Kecamatan.nm_kecamatan). \
            order_by(Kecamatan.kd_kecamatan)

        return query

    elif ses['kd_kelurahan'] == '000':
        sppt = sppt.where(and_(Sppt.thn_pajak_sppt == str(ses['tahun']),
                               Sppt.status_pembayaran_sppt < '2',
                               Sppt.kd_kecamatan == ses['kd_kecamatan'],
                               Sppt.pbb_yg_harus_dibayar_sppt.between(buku_min, buku_max))
                          )
        kini = kini.where(and_(PembayaranSppt.thn_pajak_sppt == str(ses['tahun']),
                               PembayaranSppt.kd_kecamatan == ses['kd_kecamatan'],
                               PembayaranSppt.tgl_pembayaran_sppt.between(self.dt_awal,
                                                                          self.dt_akhir, ))). \
            group_by(PembayaranSppt.kd_propinsi,
                     PembayaranSppt.kd_dati2,
                     PembayaranSppt.kd_kecamatan,
                     PembayaranSppt.kd_kelurahan,
                     PembayaranSppt.kd_blok,
                     PembayaranSppt.no_urut,
                     PembayaranSppt.kd_jns_op,
                     PembayaranSppt.thn_pajak_sppt, ). \
            having(func.sum(PembayaranSppt.jml_sppt_yg_dibayar).between(buku_min, buku_max))
        lalu = lalu.where(and_(PembayaranSppt.thn_pajak_sppt == str(ses['tahun']),
                               PembayaranSppt.kd_kecamatan == ses['kd_kecamatan'],
                               PembayaranSppt.tgl_pembayaran_sppt < self.dt_awal, )). \
            group_by(PembayaranSppt.kd_propinsi,
                     PembayaranSppt.kd_dati2,
                     PembayaranSppt.kd_kecamatan,
                     PembayaranSppt.kd_kelurahan,
                     PembayaranSppt.kd_blok,
                     PembayaranSppt.no_urut,
                     PembayaranSppt.kd_jns_op,
                     PembayaranSppt.thn_pajak_sppt, ). \
            having(func.sum(PembayaranSppt.jml_sppt_yg_dibayar).between(buku_min, buku_max))
        query_join = sppt.union(lalu.union(kini)).alias('query_join')
        query = PbbmDBSession.query(Kelurahan.kd_kelurahan.label('kode'),
                                    Kelurahan.nm_kelurahan.label('nama'),
                                    func.sum(query_join.c.qty_pokok).label('qty_pokok'),
                                    func.sum(query_join.c.amt_pokok).label('amt_pokok'),
                                    func.sum(query_join.c.qty_lalu).label('qty_lalu'),
                                    func.sum(query_join.c.amt_lalu).label('amt_lalu'),
                                    func.sum(query_join.c.qty_kini).label('qty_kini'),
                                    func.sum(query_join.c.amt_kini).label('amt_kini'),
                                    literal_column('0').label('qty_jml'),
                                    literal_column('0').label('amt_jml'),
                                    literal_column('0').label('prsn_jml'),
                                    literal_column('0').label('qty_sisa'),
                                    literal_column('0').label('amt_sisa'),
                                    literal_column('0').label('prsn_sisa')
                                    ). \
            join(query_join, and_(
            Kelurahan.kd_kecamatan == query_join.c.kd_kecamatan,
            Kelurahan.kd_kelurahan == query_join.c.kd_kelurahan)). \
            group_by(Kelurahan.kd_kecamatan, Kelurahan.kd_kelurahan, Kelurahan.nm_kelurahan).\
            order_by(Kelurahan.kd_kecamatan, Kelurahan.kd_kelurahan)

        return query


    else:
        qry_sub = PbbmDBSession.query(PembayaranSppt.kd_propinsi,
                                      PembayaranSppt.kd_dati2,
                                      PembayaranSppt.kd_kecamatan,
                                      PembayaranSppt.kd_kelurahan,
                                      PembayaranSppt.kd_blok,
                                      PembayaranSppt.no_urut,
                                      PembayaranSppt.kd_jns_op,
                                      PembayaranSppt.thn_pajak_sppt,
                                      func.count(PembayaranSppt.kd_propinsi).label('qty'),
                                      func.sum(PembayaranSppt.jml_sppt_yg_dibayar -
                                               PembayaranSppt.denda_sppt).label('amt')). \
            group_by(PembayaranSppt.kd_propinsi,
                     PembayaranSppt.kd_dati2,
                     PembayaranSppt.kd_kecamatan,
                     PembayaranSppt.kd_kelurahan,
                     PembayaranSppt.kd_blok,
                     PembayaranSppt.no_urut,
                     PembayaranSppt.kd_jns_op,
                     PembayaranSppt.thn_pajak_sppt, )

        lalu_qry = qry_sub.filter(and_(PembayaranSppt.thn_pajak_sppt == str(ses['tahun']),
                                       PembayaranSppt.kd_kecamatan == ses['kd_kecamatan'],
                                       PembayaranSppt.kd_kelurahan == ses['kd_kelurahan'],
                                       PembayaranSppt.tgl_pembayaran_sppt < self.dt_awal, )).subquery()

        kini_qry = qry_sub.filter(and_(PembayaranSppt.thn_pajak_sppt == str(ses['tahun']),
                                       PembayaranSppt.kd_kecamatan == ses['kd_kecamatan'],
                                       PembayaranSppt.kd_kelurahan == ses['kd_kelurahan'],
                                       PembayaranSppt.tgl_pembayaran_sppt.between(self.dt_awal,
                                                                                  self.dt_akhir))).subquery()

        query = PbbmDBSession.query(func.concat(Sppt.kd_blok,
                                                func.concat(".",
                                                            func.concat(Sppt.no_urut,
                                                                        func.concat(".",
                                                                                    Sppt.kd_jns_op)))).label(
            'kode'),
            Sppt.nm_wp_sppt.label('nama'),
            literal_column('1').label('qty_pokok'),
            Sppt.pbb_yg_harus_dibayar_sppt.label('amt_pokok'),
            func.coalesce(lalu_qry.c.qty, 0).label('qty_lalu'),
            func.coalesce(lalu_qry.c.amt, 0).label('amt_lalu'),
            func.coalesce(kini_qry.c.qty, 0).label('qty_kini'),
            func.coalesce(kini_qry.c.amt, 0).label('amt_kini'),
            literal_column('0').label('qty_jml'),
            literal_column('0').label('amt_jml'),
            literal_column('0').label('prsn_jml'),
            literal_column('0').label('qty_sisa'),
            literal_column('0').label('amt_sisa'),
            literal_column('0').label('prsn_sisa')
        ). \
            filter(Sppt.thn_pajak_sppt == str(ses['tahun']),
                   Sppt.status_pembayaran_sppt < '2',
                   Sppt.kd_kecamatan == ses['kd_kecamatan'],
                   Sppt.kd_kelurahan == ses['kd_kelurahan'],
                   Sppt.status_pembayaran_sppt != '2',
                   Sppt.pbb_yg_harus_dibayar_sppt.between(buku_min, buku_max),
                   ). \
            outerjoin(lalu_qry, and_(
            Sppt.kd_propinsi == lalu_qry.c.kd_propinsi,
            Sppt.kd_dati2 == lalu_qry.c.kd_dati2,
            Sppt.kd_kecamatan == lalu_qry.c.kd_kecamatan,
            Sppt.kd_kelurahan == lalu_qry.c.kd_kelurahan,
            Sppt.kd_blok == lalu_qry.c.kd_blok,
            Sppt.no_urut == lalu_qry.c.no_urut,
            Sppt.kd_jns_op == lalu_qry.c.kd_jns_op,
            Sppt.thn_pajak_sppt == lalu_qry.c.thn_pajak_sppt,
        )). \
            outerjoin(kini_qry, and_(
            Sppt.kd_propinsi == kini_qry.c.kd_propinsi,
            Sppt.kd_dati2 == kini_qry.c.kd_dati2,
            Sppt.kd_kecamatan == kini_qry.c.kd_kecamatan,
            Sppt.kd_kelurahan == kini_qry.c.kd_kelurahan,
            Sppt.kd_blok == kini_qry.c.kd_blok,
            Sppt.no_urut == kini_qry.c.no_urut,
            Sppt.kd_jns_op == kini_qry.c.kd_jns_op,
            Sppt.thn_pajak_sppt == kini_qry.c.thn_pajak_sppt,
        ))
        return query