pembayaran_dph.py 8.94 KB
from datetime import datetime

from tangsel.models import Base, DBSession, StandarModel
from sqlalchemy import (
    Column, String, DateTime, Integer, BigInteger, and_, func, UniqueConstraint, )
from sqlalchemy.sql import select

from tangsel.tools.pbb import query_nop
from .sppt import SpptMaster
from ..models import Kelurahan, Kecamatan, Sppt, PembayaranSppt
from ..tools import FixNop, hitung_denda, FixBayar


class PembayaranDph(Base, StandarModel, SpptMaster):
    __tablename__ = 'pembayaran_dph'
    __table_args__ = (  # (
        UniqueConstraint('kd_propinsi', 'kd_dati2', 'kd_kecamatan', 'kd_kelurahan',
                         'kd_blok', 'no_urut', 'kd_jns_op', 'thn_pajak_sppt', 'pembayaran_ke',
                         name="pembayaran_dph_ux"
                         ),
        #     PBBM_ARGS
    )
    kd_propinsi = Column(String(2))
    kd_dati2 = Column(String(2))
    kd_kecamatan = Column(String(3))
    kd_kelurahan = Column(String(3))
    kd_blok = Column(String(3))
    no_urut = Column(String(4))
    kd_jns_op = Column(String(1))
    thn_pajak_sppt = Column(String(4))
    pembayaran_ke = Column(Integer)
    denda = Column(BigInteger)
    bayar = Column(BigInteger)
    tgl_pembayaran = Column(DateTime(timezone=False))
    tgl_rekam_byr = Column(DateTime(timezone=False))
    nip_rekam_byr = Column(String(18))
    posted = Column(Integer)
    departemen_id = Column(Integer)
    user_id = Column(Integer)

    @classmethod
    def query(cls):
        return DBSession.query(cls)

    @classmethod
    def query_id(cls, id):
        fx_bayar = FixBayar(id)
        return cls.query().filter(
            cls.kd_propinsi == fx_bayar["kd_propinsi"],
            cls.kd_dati2 == fx_bayar["kd_dati2"],
            cls.kd_kecamatan == fx_bayar["kd_kecamatan"],
            cls.kd_kelurahan == fx_bayar["kd_kelurahan"],
            cls.kd_blok == fx_bayar["kd_blok"],
            cls.no_urut == fx_bayar["no_urut"],
            cls.kd_jns_op == fx_bayar["kd_jns_op"],
            cls.thn_pajak_sppt == fx_bayar["thn_pajak_sppt"],
            cls.pembayaran_ke == fx_bayar["pembayaran_sppt_ke"])

    @classmethod
    def query_nop(cls, nop):
        fx_nop = FixNop(nop)
        return cls.query(). \
            filter(cls.kd_propinsi == fx_nop["kd_propinsi"],
                   cls.kd_dati2 == fx_nop["kd_dati2"],
                   cls.kd_kecamatan == fx_nop["kd_kecamatan"],
                   cls.kd_kelurahan == fx_nop["kd_kelurahan"],
                   cls.kd_blok == fx_nop["kd_blok"],
                   cls.no_urut == fx_nop["no_urut"],
                   cls.kd_jns_op == fx_nop["kd_jns_op"])

    @classmethod
    def query_bayar(cls, nop, tahun):
        fx_nop = FixNop(nop)
        q = DBSession.query(func.sum(cls.denda).label("denda"),
                            func.sum(cls.bayar).label("bayar"),
                            func.max(cls.pembayaran_ke).label("ke")). \
            filter(cls.kd_propinsi == fx_nop["kd_propinsi"],
                   cls.kd_dati2 == fx_nop["kd_dati2"],
                   cls.kd_kecamatan == fx_nop["kd_kecamatan"],
                   cls.kd_kelurahan == fx_nop["kd_kelurahan"],
                   cls.kd_blok == fx_nop["kd_blok"],
                   cls.no_urut == fx_nop["no_urut"],
                   cls.kd_jns_op == fx_nop["kd_jns_op"],
                   cls.thn_pajak_sppt == tahun)
        if not q:
            return
        return q

    @classmethod
    def query_ke(cls, nop, tahun, ke):
        sid = "".join([nop, tahun, ke.zfill(3)])
        return cls.query_id(sid)

    @classmethod
    def save(cls, values, row):
        fx_nop = FixNop(values['nop'])
        if not row:
            row = cls()
            row_pembayaran = DBSession.query(func.max(cls.pembayaran_ke).label('ke')). \
                filter(cls.kd_propinsi == fx_nop['kd_propinsi'],
                       cls.kd_dati2 == fx_nop['kd_dati2'],
                       cls.kd_kecamatan == fx_nop['kd_kecamatan'],
                       cls.kd_kelurahan == fx_nop['kd_kelurahan'],
                       cls.kd_blok == fx_nop['kd_blok'],
                       cls.no_urut == fx_nop['no_urut'],
                       cls.kd_jns_op == fx_nop['kd_jns_op'],
                       cls.thn_pajak == values['thn_pajak']).first()
            if row_pembayaran and row_pembayaran.ke:
                values['pembayaran_ke'] = row.ke + 1
            else:
                values['pembayaran_ke'] = 1
        sppt = cls.piutang(values['nop'], values["tahun",])
        values.update(sppt["sppt"].to_dict())
        row.from_dict(values)
        if not row.kd_kanwil:
            row.kd_kanwil = '00'
            row.kd_kantor = '00'
            row.kd_tp = '00'
        row.kd_propinsi = fx_nop['kd_propinsi']
        row.kd_dati2 = fx_nop['kd_dati2']
        # row.kd_kecamatan == fx_nop['kd_kecamatan']
        # row.kd_kelurahan == fx_nop['kd_kelurahan']
        # row.kd_blok == fx_nop['kd_blok']
        # row.no_urut == fx_nop['no_urut']
        # row.kd_jns_op == fx_nop['kd_jns_op']

        DBSession.add(row)
        DBSession.flush()
        return row

    @classmethod
    def reversal(cls, id):
        q = cls.query_id(id)
        row = q.first()
        if row:
            row.denda = 0
            row.bayar = 0
            DBSession.add(row)
            DBSession.flush()
            return row

    @classmethod
    def piutang(cls, nop, tahun, tanggal=datetime.now().date()):
        row = Sppt.query_nop_thn(nop, tahun). \
            filter(Sppt.status_pembayaran_sppt < '2').first()
        if not row:
            return

        if row.status_pembayaran_sppt == 1:
            return dict(sppt=row,
                        status=1,
                        pokok=row.pbb_yg_harus_dibayar_sppt)

        pokok = row.pbb_yg_harus_dibayar_sppt
        jatuh_tempo = row.tgl_jatuh_tempo_sppt
        thn_pajak_sppt = row.thn_pajak_sppt
        if isinstance(jatuh_tempo, datetime):
            jatuh_tempo = jatuh_tempo.date()
        bayar = PembayaranSppt.query_bayar(nop, tahun).first()
        ke = 1

        if bayar.bayar or bayar.denda or bayar.ke:
            pokok -= (bayar.bayar - bayar.denda)
            ke = bayar.ke + 1
            return dict(sppt=row,
                        status=1,
                        pokok=pokok)
        else:
            bayar = cls.query_bayar(nop, tahun).first()
            if bayar.bayar or bayar.denda or bayar.ke:
                pokok -= float(bayar.bayar - bayar.denda)
                ke = bayar.ke + 1
                if pokok < 1:
                    return dict(sppt=row,
                                status=1,
                                pokok=pokok)

        denda = hitung_denda(pokok, jatuh_tempo, tanggal)

        return dict(sppt=row,
                    pokok=pokok,
                    denda=denda,
                    jatuh_tempo=jatuh_tempo,
                    ke=ke)

    @classmethod
    def rekap(cls, dt_awal, dt_akhir):
        data_kec = select([cls.kd_kecamatan.label('kode'),
                           Kecamatan.nm_kecamatan.label('uraian'),
                           func.count(cls.kd_kecamatan).label('jumlah'),
                           func.sum(cls.bayar).label('bayar'),
                           func.sum(cls.denda).label('denda'),
                           ]). \
            where(and_(cls.kd_kecamatan == Kecamatan.kd_kecamatan,
                       cls.tgl_pembayaran.between(dt_awal, dt_akhir))). \
            group_by(cls.kd_kecamatan,
                     Kecamatan.nm_kecamatan)

        data_kel = select([func.concat(cls.kd_kecamatan, func.concat(".",
                                                                     cls.kd_kelurahan).label(
            'kode')),
            Kelurahan.nm_kelurahan.label('uraian'),
            func.count(cls.kd_kelurahan).label('jumlah'),
            func.sum(cls.bayar).label('bayar'),
            func.sum(cls.denda).label('denda'),
        ]). \
            where(and_(cls.kd_kecamatan == Kelurahan.kd_kecamatan,
                       cls.kd_kelurahan == Kelurahan.kd_kelurahan,
                       cls.tgl_pembayaran.between(dt_awal, dt_akhir))). \
            group_by(cls.kd_kecamatan,
                     cls.kd_kelurahan,
                     Kelurahan.nm_kelurahan)

        query_union = data_kec.union(data_kel).alias('query_union')

        return query_union

    @classmethod
    def query_register(cls):
        qry_nop = query_nop(cls)
        return DBSession.query(qry_nop.label("nop"), cls.thn_pajak_sppt.label("tahun"),
                               cls.nm_wp_sppt.label("nama"),
                               cls.pbb_yg_harus_dibayar_sppt.label("pokok"),
                               cls.denda.label('denda'),
                               cls.bayar.label('bayar'),
                               cls.tgl_pembayaran.label('tgl_pembayaran'),
                               )