bphtb.py 5.41 KB
import sys
from sqlalchemy import (
    Column,
    Integer,
    DateTime,
    String,
    Date,
    ForeignKey,
    func,
    )
from opensipkd.string import FixLength
from opensipkd.waktu import dmyhms
from opensipkd.bphtb.models.default import (
    Payment,
    Invoice,
    Perolehan,
    Customer,
    )
from opensipkd.bphtb.services.default.structure import INVOICE_ID
from iso8583_web.models.meta import Base as BaseConf
from opensipkd.iso8583.bjb.bphtb import Doc
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 (
    get_iso,
    get_channel_name_by_row,
    get_channel_info_by_iso,
    BaseApp,
    init_db as base_init_db,
    one_day,
    InvalidSource,
    )


class IsoPayment(Base):
    __tablename__ = 'bphtb_payment'
    __table_args__ = dict(schema='bphtb')
    id = Column(Integer, ForeignKey(Payment.id), primary_key=True)
    tgl = Column(DateTime(timezone=True), nullable=False)
    iso_request = Column(String(1024), nullable=False)
    transmission = Column(DateTime(timezone=True), nullable=False)
    settlement = Column(Date, nullable=False)
    stan = Column(Integer, nullable=False)
    invoice_id = Column(Integer, ForeignKey(Invoice.id), nullable=False)
    invoice_no = Column(String(32), nullable=False)
    ntb = Column(String(32), nullable=False)
    ntp = Column(String(32), nullable=False, unique=True)
    bank_id = Column(Integer)
    channel_id = Column(Integer)
    bank_ip = Column(String(15), nullable=False)


class App(BaseApp):
    conf_name = 'bphtb payment last date'
    report_orm = Bphtb
    va_product_code = '01'

    def __init__(self, argv):
        super().__init__(argv)
        if not self.pid:
            return
        self.base_q_inv = self.prod_session.query(Invoice)
        self.base_q_cust = self.prod_session.query(Customer)
        self.base_q_perolehan = self.prod_session.query(Perolehan)

    def get_last_time(self):  # Override
        s_tgl = self.last_pay.tanggal.strftime('%d-%m-%Y')
        s_jam = self.last_pay.jam.strftime('%H:%M:%S')
        return f'{s_tgl} {s_jam}'

    def get_filter_query(self, q):
        return q.filter(
                Payment.tanggal >= self.tgl_awal.date(),
                Payment.jam >= self.tgl_awal.time(),
                Payment.tanggal < self.tgl_akhir + one_day)

    def get_count(self) -> int:  # Override
        q = self.prod_session.query(func.count())
        q = self.get_filter_query(q)
        return q.scalar()

    def get_payment_query(self):  # Override
        q = self.prod_session.query(Payment)
        q = self.get_filter_query(q)
        return q.order_by(Payment.tanggal, Payment.jam)

    def get_iso_v1(self, pay):
        q = self.prod_session.query(IsoPayment).filter_by(id=pay.id)
        row = q.first()
        if not row:
            return
        iso = get_iso(row.iso_request, Doc, self.option.debug)
        info = get_channel_info_by_iso(iso)
        return info['bit_018'], info['channel'], iso.get_stan(), iso.get_ntb()

    def get_iso_v2(self):
        q = self.prod_session.query(Log).filter_by(
                mti='0210', bit_003=PAYMENT_CODE, bit_039='00')
        q = q.filter(func.trim(Log.bit_062) == self.invoice_id)
        q = q.order_by(Log.id.desc())
        row = q.first()
        if not row:
            return
        channel_id = row.bit_018.strip()
        channel_nama = get_channel_name_by_row(row)
        return channel_id, channel_nama, row.bit_011, row.bit_058.strip()

    def get_invoice(self, pay):
        q = self.base_q_inv.filter_by(id=pay.sspd_id)
        return q.first()

    def get_customer(self, inv):
        q = self.base_q_cust.filter_by(id=inv.ppat_id)
        return q.first()

    def get_perolehan(self, inv):
        q = self.base_q_perolehan.filter_by(id=inv.perolehan_id)
        return q.first()

    def create_data(self, pay):  # Override
        inv = self.get_invoice(pay)
        if not inv:
            msg = f'Field bphtb_bank.sspd_id {pay.sspd_id} tidak ada di '\
                   'field bphtb_sspd.id'
            raise InvalidSource(msg)
        cust = self.get_customer(inv)
        perolehan = self.get_perolehan(inv)
        invoice_id = FixLength(INVOICE_ID)
        invoice_id['Tahun'] = inv.tahun
        invoice_id['Kode'] = inv.kode
        invoice_id['SSPD No'] = inv.no_sspd
        self.invoice_id = invoice_id.get_raw()
        source = self.get_iso_v2()
        if source:
            channel_id, channel_nama, stan, ntb = source
        else:
            source = self.get_iso_v1(pay)
            if source:
                channel_id, channel_nama, stan, ntb = source
            else:
                stan = ntb = None
                channel_id = '0000'
                channel_nama = self.get_va_channel(pay.tanggal) or 'MANUAL'
        return dict(
            id=pay.id, stan=stan, ntb=ntb, tgl=pay.tanggal, jam=pay.jam,
            invoice_id=self.invoice_id, nop=pay.nop, wp_nama=pay.wp_nama,
            wp_alamat=pay.wp_alamat, op_alamat=inv.op_alamat, npop=pay.npop,
            bumi_luas=pay.bumi_luas, bng_luas=pay.bng_luas,
            nilai_bphtb=pay.bayar, jenis_perolehan=perolehan.nama,
            ppat=cust.nama.strip(), channel_id=channel_id,
            channel_nama=channel_nama)


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)