tangkab.py 5.7 KB
from datetime import timedelta
import requests
from sqlalchemy import func
import transaction
from opensipkd.waktu import (
    dmyhms,
    as_timezone,
    )
from opensipkd.string import FixLength
from sismiop.services.base import INVOICE_ID
from opensipkd.iso8583.bjb.pbb.structure import (
    PAYMENT_CODE,
    INVOICE_PROFILE,
    )
from payment_report.scripts.tools import (
    plain_values,
    update,
    )
from payment_report.scripts.common import (
    get_channel_name,
    row_limit,
    )


def to_str(t):
    s = dmyhms(t)
    return f'{s}.{t.microsecond}'


class Handler:
    def __init__(self, parent):
        self.parent = parent
        self.parent.conf_name = 'pbb log table last date'

    def get_count(self):  # dipanggil parent
        cursor = self.parent.odbc_conn.cursor()
        tgl_akhir = self.parent.tgl_akhir + timedelta(1)
        cursor.execute(
            "SELECT * FROM THOSTISO WHERE H3 = ? AND "
            "HDATE BETWEEN ? AND ? ORDER BY HDATE",
            (PAYMENT_CODE, self.parent.tgl_awal, tgl_akhir))
        self.rows = []
        fieldnames = []
        for row in cursor.fetchall():
            if not fieldnames:
                fieldnames = [info[0] for info in row.cursor_description]
            d = dict([(x, row[fieldnames.index(x)]) for x in fieldnames])
            self.rows.append(d)
        return len(self.rows)

    def get_report(self, pay):
        session = self.parent.get_session_for_save()
        q = session.query(self.parent.report_orm).filter_by(
                tgl_rekam_byr_sppt=pay['HDATE'])
        return q.first()

    def query_payment(self, d):
        session = self.parent.get_session_for_save()
        return session.query(self.parent.report_orm).filter_by(
                kd_propinsi=d['kd_propinsi'], kd_dati2=d['kd_dati2'],
                kd_kecamatan=d['kd_kecamatan'], kd_kelurahan=d['kd_kelurahan'],
                kd_blok=d['kd_blok'], no_urut=d['no_urut'],
                kd_jns_op=d['kd_jns_op'], thn_pajak_sppt=d['thn_pajak_sppt'],
                pembayaran_sppt_ke=d['pembayaran_sppt_ke'])

    def create_data_(self, pay):
        channel_nama = get_channel_name(
            pay['H18'], pay['H32'], pay['H41'], pay.get('H42', ''),
            pay.get('H43', ''))
        channel_kode = pay['H18'] or '0000'
        profile = FixLength(INVOICE_PROFILE)
        profile.set_raw(pay['H62'])
        inv_id = FixLength(INVOICE_ID)
        inv_id.set_raw(pay['H61'])
        return dict(
            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['H11'], ntb=pay['H48'],
            jml_sppt_yg_dibayar=float(pay['H4']),
            denda_sppt=float(profile['Denda'] or 0),
            discount=float(profile['Discount'] or 0),
            tgl_pembayaran_sppt=pay['HDATE'].date(),
            tgl_rekam_byr_sppt=pay['HDATE'], nm_wp_sppt=profile['Nama'],
            channel_kode=channel_kode, channel_nama=channel_nama,
            bank_id=pay['H32'], user_id=pay['H107'],
            pbb_yg_harus_dibayar_sppt=float(profile['Tagihan']))

    def create_data(self, pay):
        if pay['MTI'] == '0400':
            source = dict(jml_sppt_yg_dibayar=0, denda_sppt=0, discount=0)
        else:
            source = self.create_data_(pay)
        log_data = plain_values(source)
        return source, log_data

    def save(self, pay, rpt, q_old_payment):
        session = self.parent.get_session_for_save()
        with transaction.manager:
            q_old_payment and q_old_payment.delete()
            rpt and session.add(rpt)
            if self.parent.last:
                self.parent.last.nilai = to_str(pay['HDATE'])
                session.add(self.parent.last)

    def update_from_date(self):  # Overwrite
        no = 0
        for pay in self.rows:
            no += 1
            if not (
                    (pay['MTI'] == '0210' and pay['H39'] == '00') or
                    pay['MTI'] == '0400'):
                print(f'#{no} {pay["HDATE"]} bukan payment')
                continue
            source, log_data = self.create_data(pay)
            rpt = self.get_report(pay)
            q_old_payment = None
            if rpt:
                target = rpt.to_dict()
                target_update, log_msg = update(source, target)
                if target_update:
                    s = ', '.join(log_msg)
                    msg = f'UPDATE {log_data} change {s}'
                    rpt.from_dict(target_update)
                else:
                    msg = f'ALREADY SAME {log_data}'
                    rpt = None
                    if self.parent.count == 1 and self.parent.last:
                        print(msg)
                        print('Log yang sama, abaikan.')
                        return
            elif pay['MTI'] == '0210':
                q = self.query_payment(source)
                old_pay = q.first()
                hdate = as_timezone(pay['HDATE'])
                msg = f'INSERT {log_data}'
                rpt = self.parent.report_orm(**source)
                if old_pay:
                    if old_pay.tgl_rekam_byr_sppt < hdate:
                        q_old_payment = q
                    else:
                        msg = f'sudah ada yang baru di {hdate}'
                        rpt = None
            invoice_id = pay['H61'].strip()
            msg = f'Invoice ID {invoice_id} {msg}'
            e = self.parent.get_estimate(no)
            msg = f'#{no}/{self.parent.count} {msg}, estimate {e}'
            self.parent.log.info(msg)
            self.save(pay, rpt, q_old_payment)