only_h2h.py 4.37 KB
import requests
from sqlalchemy import func
import transaction
from opensipkd.waktu import dmyhms
from opensipkd.string import FixLength
from sismiop.services.base import INVOICE_ID
from opensipkd.iso8583.bjb.pbb.structure import (
    PAYMENT_CODE,
    INVOICE_PROFILE,
    )
from opensipkd.iso8583.bjb.models import Log
from payment_report.scripts.tools import (
    plain_values,
    update,
    )
from payment_report.scripts.common import (
    InvalidSource,
    one_day,
    get_channel_name_by_row,
    row_limit,
    )


class Handler:
    def __init__(self, parent):
        self.parent = parent

    def filter_tgl(self, q):
        q = q.filter(
                Log.created >= self.parent.tgl_awal,
                Log.created < self.parent.tgl_akhir + one_day,
                Log.bits.op('->>')('3') == PAYMENT_CODE,
                Log.bits.op('->>')('39') == '00')
        return q.filter_by(mti='0210')

    def get_payment_query(self):
        q = self.parent.h2h_session.query(Log)
        return self.filter_tgl(q).order_by(Log.id)

    def get_count(self):  # dipanggil parent
        q = self.parent.h2h_session.query(func.count(Log.id))
        q = self.filter_tgl(q)
        return q.scalar()

    def get_last_time(self):  # dipanggil parent
        return dmyhms(self.parent.last_pay.created)

    def get_report(self, pay):
        session = self.parent.get_session_for_save()
        q = session.query(self.parent.report_orm).filter_by(id=pay.id)
        return q.first()

    def create_data(self, pay):
        channel_nama = get_channel_name_by_row(pay.bits)
        channel_kode = pay.bits['18'] or '0000'
        profile = pay.bits_data['62']
        inv_id = FixLength(INVOICE_ID)
        inv_id.set_raw(pay.bits['61'])
        return dict(
            id=pay.id, kd_propinsi=inv_id['Propinsi'],
            kd_dati2=inv_id['Kabupaten'], kd_kecamatan=inv_id['Kecamatan'],
            kd_kelurahan=inv_id['Kelurahan'], kd_blok=inv_id['Blok'],
            no_urut=inv_id['Urut'], kd_jns_op=inv_id['Jenis'],
            thn_pajak_sppt=inv_id['Tahun'], pembayaran_sppt_ke=1,
            stan=pay.bits['11'], ntb=pay.bits['48'],
            jml_sppt_yg_dibayar=float(pay.bits['4']),
            denda_sppt=float(profile['Denda']),
            discount=float(profile['Discount']),
            tgl_pembayaran_sppt=pay.created.date(),
            tgl_rekam_byr_sppt=pay.created, nm_wp_sppt=profile['Nama'],
            channel_kode=channel_kode, channel_nama=channel_nama,
            bank_id=pay.bits['32'], user_id=pay.bits['107'],
            pbb_yg_harus_dibayar_sppt=float(profile['Tagihan']))

    def update_from_date(self):
        q = self.get_payment_query()
        no = self.parent.offset
        found = False
        for pay in q.offset(self.parent.offset).limit(row_limit):
            found = True
            self.parent.invoice_id = pay.bits['61'].strip()
            no += 1
            try:
                source = self.create_data(pay)
                d = plain_values(source)
                rpt = self.get_report(pay)
                if rpt:
                    target = rpt.to_dict()
                    target_update, log_msg = update(source, target)
                    if target_update:
                        s = ', '.join(log_msg)
                        msg = f'UPDATE {d} change {s}'
                        rpt.from_dict(target_update)
                    else:
                        msg = f'ALREADY SAME {d}'
                        rpt = None
                        if self.parent.count == 1 and self.parent.last:
                            print(msg)
                            print('Log yang sama, abaikan.')
                            return
                else:
                    msg = f'INSERT {d}'
                    rpt = self.parent.report_orm(**source)
                msg = f'{self.parent.get_prefix_log()} {msg}'
                log_method = self.parent.log.info
            except InvalidSource as e:
                msg = str(e)
                log_method = self.parent.log.warning
                rpt = None
            e = self.parent.get_estimate(no)
            log_method(f'#{no}/{self.parent.count} {msg}, estimate {e}')
            if rpt:
                session = self.parent.get_session_for_save()
                with transaction.manager:
                    session.add(rpt)
            self.parent.last_pay = pay
        self.parent.offset += row_limit
        return found