bphtb2.py 4.7 KB
import sys
from sqlalchemy.exc import ProgrammingError
import transaction
from opensipkd.waktu import (
    dmyhms,
    date_from_str,
    )
from opensipkd.bphtb.models.perolehan import PerolehanMixin
from opensipkd.bphtb.models.default import Perolehan
from iso8583_web.models.meta import Base as BaseConf
from opensipkd.iso8583.bjb.bphtb.structure import PAYMENT_CODE
from opensipkd.iso8583.bjb.bphtb.models import Log
from ..models import (
    Base,
    Bphtb,
    )
from .common import (
    App2 as BaseApp,
    init_db as base_init_db,
    )


class AlternativePerolehan(Base, PerolehanMixin):
    __table_args__ = dict(schema='public')


def error(s):
    print(s)
    sys.exit()


class App(BaseApp):
    field_invoice_id = 'bit_062'
    field_ntb = 'bit_058'
    report_orm = Bphtb

    def __init__(self, argv):
        super().__init__(argv)
        if not self.pid:
            return
        self.base_q_perolehan = self.prod_session.query(Perolehan)
        with transaction.manager:
            try:
                self.base_q_perolehan.first()
            except ProgrammingError:
                self.prod_session.rollback()
                self.base_q_perolehan = self.prod_session.query(
                        AlternativePerolehan)

    def get_log_orm(self):  # Override
        return Log

    def __create_data(self, row_iso):
        tgl_bayar = row_iso.created.date()
        d = self.get_keys(row_iso)
        s_tgl = dmyhms(row_iso.created)
        self.log.info(
            f'Tgl bayar {s_tgl}, Nomor bayar {d["nomor_bayar"]}, '
            f'STAN {d["stan"]}, NTB {d["ntb"]}, Channel {d["channel"]}')
        p = eval(row_iso.bit_047_data)
        q = self.base_q_perolehan.filter_by(id=p['Jenis Perolehan Hak'])
        perolehan = q.first()
        return dict(
            stan=d['stan'], ntb=d['ntb'], tgl=tgl_bayar,
            jam=row_iso.created.time(),
            invoice_id=row_iso.bit_062.strip(),
            nop=row_iso.bit_061.strip(),
            wp_nama=p['Nama Wajib Pajak'],
            wp_alamat=p['Alamat WP'],
            op_alamat=p['Alamat OP'],
            npop=p['NPOP'],
            bumi_luas=p['Luas Tanah'],
            bng_luas=p['Luas Bangunan'],
            nilai_bphtb=float(row_iso.bit_004),
            jenis_perolehan=perolehan.nama,
            ppat=p['Nama Notaris'],
            channel_id=row_iso.bit_018.strip(),
            channel_nama=d['channel'])

    def __get_query_iso(self, last_id):
        return self.prod_session.query(Log).filter_by(
                mti='0210', bit_003=PAYMENT_CODE, bit_039='00').filter(
                Log.id > last_id)

    def __run_payment(self):
        last = self.get_last_id('bphtb2 payment last id')
        q_iso = self.__get_query_iso(last.as_int())
        found = False
        for row_iso in q_iso.order_by(Log.id).limit(1000):
            if self.get_report(row_iso):
                last.nilai = str(row_iso.id)
                with transaction.manager:
                    self.rpt_session.add(last)
                continue
            data = self.__create_data(row_iso)
            rpt = Bphtb(**data)
            last.nilai = str(row_iso.id)
            with transaction.manager:
                self.rpt_session.add(rpt)
                self.rpt_session.add(last)
            found = True
        return found

    def __update_from_id(self):
        q_iso = self.__get_query_iso(self.last_id)
        found = False
        for row_iso in q_iso.order_by(Log.id).limit(1000):
            rpt = self.get_report(row_iso)
            if not rpt:
                rpt = Bphtb()
            data = self.__create_data(row_iso)
            rpt.from_dict(data)
            with transaction.manager:
                self.rpt_session.add(rpt)
            self.last_id = row_iso.id
            found = True
        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(Log).filter(Log.created >= tgl)
            q = q.order_by(Log.id)
            row = q.first()
            if not row:
                error('Kosong')
            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 run_reversal(self):  # Override
        super().run_reversal('bphtb2 reversal last id')


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


def init_db(argv=sys.argv[1:]):
    base_init_db(Base.metadata, BaseConf.metadata, argv)