va_pbb.py 6.76 KB
import sys
from sqlalchemy import (
    Column,
    Integer,
    )
import transaction
from opensipkd.waktu import (
    dmyhms,
    create_datetime,
    date_from_str,
    )
from sismiop.models.default import PembayaranSppt as BasePsppt
from sismiop.services.base import (
    get_id,
    )
from opensipkd.iso8583.bjb.scripts.common import get_module_object
from ..models import Pbb
from .common import (
    get_iso,
    get_keys,
    BaseApp,
    )


NIP_PENCATAT = '222222222'
CHANNEL_KODE = '7001'
CHANNEL_NAMA = 'VA'
LAST_CONF = 'va pbb last id'
ERR_NOT_FOUND = 'SPPT ID {invoice_id} tidak ada di sppt'


class PembayaranSppt(BasePsppt):
    __table_args__ = dict(extend_existing=True)
    id = Column(Integer, nullable=False)
    user_id = Column(Integer)


def get_tgl_bayar(row):
    t = row.tgl_rekam_byr_sppt
    return create_datetime(t.year, t.month, t.day, t.hour, t.minute, t.second)


class App(BaseApp):
    report_orm = Pbb

    def __init__(self, argv):
        super().__init__(argv)
        if not self.pid:
            return
        self.models = get_module_object(self.conf['models'])
        self.Sppt = self.models.Sppt
        self.base_q_psppt = self.prod_session.query(PembayaranSppt).filter_by(
                                nip_rekam_byr_sppt=NIP_PENCATAT)
        self.base_q_sppt = self.prod_session.query(self.Sppt)

    def get_sppt(self, psppt):
        q = self.base_q_sppt.filter_by(
                kd_propinsi=psppt.kd_propinsi,
                kd_dati2=psppt.kd_dati2,
                kd_kecamatan=psppt.kd_kecamatan,
                kd_kelurahan=psppt.kd_kelurahan,
                kd_blok=psppt.kd_blok,
                no_urut=psppt.no_urut,
                kd_jns_op=psppt.kd_jns_op,
                thn_pajak_sppt=psppt.thn_pajak_sppt)
        return q.first()

    def __get_query_psppt(self, last_id):
        q = self.base_q_psppt.filter(PembayaranSppt.id > last_id)
        return q.order_by(PembayaranSppt.id)

    def __log_not_found(self, sppt_id):
        msg = ERR_NOT_FOUND.format(invoice_id=sppt_id)
        self.log.error(msg)

    def __log_progress(self, row, sppt_id):
        s_tgl = dmyhms(row.tgl_rekam_byr_sppt)
        self.log.info(
            f'Tgl bayar {s_tgl}, Nomor bayar {sppt_id}, '
            f'pembayaran ke {row.pembayaran_sppt_ke}, ID {row.id}, '
            f'jml_sppt_yg_dibayar {row.jml_sppt_yg_dibayar}')

    def __run_payment(self):
        last = self.get_last_id(LAST_CONF)
        q_psppt = self.__get_query_psppt(last.as_int())
        found = False
        for psppt in q_psppt.limit(1000):
            stan = psppt.tgl_pembayaran_sppt.strftime('%y%m%d')
            ntb = f'{CHANNEL_NAMA}-{psppt.id}'
            if self.get_report(stan, ntb):
                continue
            sppt_id = get_id(psppt)
            sppt = self.get_sppt(psppt)
            if not sppt:
                self.__log_not_found(sppt_id)
                continue
            tgl_bayar = get_tgl_bayar(psppt)
            user_id = str(psppt.user_id)
            disc = psppt.discount or 0
            self.__log_progress(psppt, sppt_id)
            rpt = Pbb(
                    stan=stan, ntb=ntb, kd_propinsi=psppt.kd_propinsi,
                    kd_dati2=psppt.kd_dati2, kd_kecamatan=psppt.kd_kecamatan,
                    kd_kelurahan=psppt.kd_kelurahan, kd_blok=psppt.kd_blok,
                    no_urut=psppt.no_urut, kd_jns_op=psppt.kd_jns_op,
                    thn_pajak_sppt=psppt.thn_pajak_sppt,
                    pembayaran_sppt_ke=psppt.pembayaran_sppt_ke,
                    jml_sppt_yg_dibayar=psppt.jml_sppt_yg_dibayar,
                    denda_sppt=psppt.denda_sppt,
                    tgl_pembayaran_sppt=psppt.tgl_pembayaran_sppt,
                    tgl_rekam_byr_sppt=psppt.tgl_rekam_byr_sppt,
                    nm_wp_sppt=sppt.nm_wp_sppt, channel_kode=CHANNEL_KODE,
                    channel_nama=CHANNEL_NAMA, user_id=user_id,
                    pbb_yg_harus_dibayar_sppt=sppt.pbb_yg_harus_dibayar_sppt,
                    tgl_inquiry=tgl_bayar, discount=disc)
            last.nilai = str(psppt.id)
            with transaction.manager:
                self.rpt_session.add(rpt)
                self.rpt_session.add(last)
            found = True
        return found

    def __update_from_id(self):
        q_psppt = self.__get_query_psppt(self.last_id)
        found = False
        for psppt in q_psppt.limit(1000):
            sppt_id = get_id(psppt)
            sppt = self.get_sppt(psppt)
            if not sppt:
                self.__log_not_found(sppt_id)
                continue
            stan = psppt.tgl_pembayaran_sppt.strftime('%y%m%d')
            ntb = f'{CHANNEL_NAMA}-{psppt.id}'
            tgl_bayar = get_tgl_bayar(psppt)
            user_id = str(psppt.user_id)
            disc = psppt.discount or 0
            rpt = self.get_report(stan, ntb)
            if not rpt:
                rpt = Pbb()
            self.__log_progress(psppt, sppt_id)
            d = dict(
                    stan=stan, ntb=ntb, kd_propinsi=psppt.kd_propinsi,
                    kd_dati2=psppt.kd_dati2, kd_kecamatan=psppt.kd_kecamatan,
                    kd_kelurahan=psppt.kd_kelurahan, kd_blok=psppt.kd_blok,
                    no_urut=psppt.no_urut, kd_jns_op=psppt.kd_jns_op,
                    thn_pajak_sppt=psppt.thn_pajak_sppt,
                    pembayaran_sppt_ke=psppt.pembayaran_sppt_ke,
                    jml_sppt_yg_dibayar=psppt.jml_sppt_yg_dibayar,
                    denda_sppt=psppt.denda_sppt,
                    tgl_pembayaran_sppt=psppt.tgl_pembayaran_sppt,
                    tgl_rekam_byr_sppt=psppt.tgl_rekam_byr_sppt,
                    nm_wp_sppt=sppt.nm_wp_sppt, channel_kode=CHANNEL_KODE,
                    channel_nama=CHANNEL_NAMA, user_id=user_id,
                    pbb_yg_harus_dibayar_sppt=sppt.pbb_yg_harus_dibayar_sppt,
                    tgl_inquiry=tgl_bayar, discount=disc)
            rpt.from_dict(d)
            with transaction.manager:
                self.rpt_session.add(rpt)
            found = True
            self.last_id = psppt.id
        return found

    def run_payment(self):  # Override
        if self.option.update_from_id:
            self.last_id = self.option.update_from_id
            func = self.__update_from_id
        elif self.option.update_from_date:
            tgl = date_from_str(self.option.update_from_date)
            q = self.prod_session.query(PembayaranSppt).filter(
                    PembayaranSppt.tgl_rekam_byr_sppt >= tgl).order_by(
                    PembayaranSppt.tgl_rekam_byr_sppt)
            row = q.first()
            self.last_id = row.id - 1
            func = self.__update_from_id
        else:
            func = self.__run_payment
        while True:
            found = func()
            if not found:
                break


def main(argv=sys.argv[1:]):
    app = App(argv)
    app.run()