Commit 63779a0d by Owo Sugiana

PBB berbasis tabel pembayaran_sppt

1 parent 4b8a1a59
0.3.3 18-5-2022 2.0 2022-05-18
---------------
- Script baru WEBR yang belum menggunakan tabel ISO8583
0.3.2 6-3-2022
-------------- --------------
- Script baru WEBR yang tidak mengaitkan dengan tabel ar_payment karena - Perbedaan utama dari versi 0.x adalah kini berangkat dari tabel aslinya dan
transaksi melalui web service (Kota Tangerang Selatan) bukan dari tabel ISO8583 karena sudah memperhatikan channel MANUAL (input
manual pembayaran)
0.3.1 3-3-2022
--------------
- Tambah PAD JSON (PT POS)
0.3 28-2-2022
-------------
- Tambah baris models pada file konfigurasi sebagai pengganti module
- Perbaikan pada BPHTB terkait tabel bphtb_perolehan yang berbeda schema
- Tambah BPHTB JSON (PT POS)
- Tambah PBB JSON (PT POS)
0.2.1 23-12-2021
----------------
- Tambah WEBR
0.2 4-12-2021
-------------
- Tambah field jenis_pajak untuk PAD
- Script baru PAD yang tidak lagi membaca tabel pad_payment sebagai catatan
ISO8583 melainkan dari tabel log_iso dan log_pad.
- Penggunaan pkgutil agar fleksibel saat pip install -e
0.1.5 16-6-2021
---------------
- Bug fixed saat tabel pembayaran_sppt tidak memiliki field discount
- Log PBB disertai nilai bit terkait untuk memudahkan analisa nama channel
0.1.4 27-5-2021
---------------
- Tambah channel BAYARIN
0.1.3 30-4-2021
---------------
- Tambah channel Virtual Account PBB
- Tambah channel POSPBB
- Tambah opsi --update-from-id dan --update-from-date
- Perbaikan channel
0.1.2 13-4-2021
---------------
- Penambahan models pada konfigurasi PBB yang berisi nama modul untuk ORM Sppt
dan PembayaranSppt
- Penambahan field pada PBB
- Pada PBB field user_id boleh NULL
0.1.1 3-4-2021
--------------
- Tambah PBB
- Tidak ada lagi bin/pad_report_init_db dan bin/bphtb_report_init_db, sebagai
gantinya adalah bin/payment_report_init_db.
- Tambah BPHTB "versi 2" yang hanya menggunakan tabel log_iso ketimbang tabel
bphtb_payment.
0.1 2-4-2021
------------
- Kali pertama
...@@ -66,17 +66,16 @@ class Pad(Base, Common): ...@@ -66,17 +66,16 @@ class Pad(Base, Common):
class Webr(Base, Common): class Webr(Base, Common):
__tablename__ = 'webr_report' __tablename__ = 'webr_report'
# webr.ar_payment.id
id = Column(Integer, primary_key=True) id = Column(Integer, primary_key=True)
# Bit 11 # Bit 11
stan = Column(String(6), nullable=False) stan = Column(String(6))
# Bit 48 # Bit 48
ntb = Column(String(32), nullable=False) ntb = Column(String(32))
# log_iso.created # log_iso.created
tgl = Column(Date, nullable=False) tgl = Column(Date, nullable=False)
# log_iso.created # log_iso.created
jam = Column(Time, nullable=False) jam = Column(Time, nullable=False)
# webr.ar_payment.id
payment_id = Column(Integer, nullable=False)
# Bit 61 # Bit 61
nomor_bayar = Column(String(16), nullable=False) nomor_bayar = Column(String(16), nullable=False)
# webr.ar_invoice.subjek_nama # webr.ar_invoice.subjek_nama
...@@ -93,9 +92,6 @@ class Webr(Base, Common): ...@@ -93,9 +92,6 @@ class Webr(Base, Common):
channel_name = Column(String(32), nullable=False) channel_name = Column(String(32), nullable=False)
# pad_reversal.tgl # pad_reversal.tgl
tgl_batal = Column(DateTime(timezone=True)) tgl_batal = Column(DateTime(timezone=True))
__table_args__ = (
UniqueConstraint('stan', 'ntb'),
)
class Bphtb(Base, Common): class Bphtb(Base, Common):
...@@ -146,30 +142,30 @@ class Pbb(Base, Common): ...@@ -146,30 +142,30 @@ class Pbb(Base, Common):
__tablename__ = 'pbb_report' __tablename__ = 'pbb_report'
id = Column(Integer, primary_key=True) id = Column(Integer, primary_key=True)
# Bit 11 # Bit 11
stan = Column(String(6), nullable=False) stan = Column(String(6))
# Bit 48 # Bit 48
ntb = Column(String(32), nullable=False) ntb = Column(String(32))
# Bit 62 / Invoice ID # Field pembayaran_sppt.kd_propinsi
kd_propinsi = Column(String(2), nullable=False) kd_propinsi = Column(String(2), nullable=False)
# Bit 62 / Invoice ID # Field pembayaran_sppt.kd_dati2
kd_dati2 = Column(String(2), nullable=False) kd_dati2 = Column(String(2), nullable=False)
# Bit 62 / Invoice ID # Field pembayaran_sppt.kd_kecamatan
kd_kecamatan = Column(String(3), nullable=False) kd_kecamatan = Column(String(3), nullable=False)
# Bit 62 / Invoice ID # Field pembayaran_sppt.kd_kelurahan
kd_kelurahan = Column(String(3), nullable=False) kd_kelurahan = Column(String(3), nullable=False)
# Bit 62 / Invoice ID # Field pembayaran_sppt.kd_blok
kd_blok = Column(String(3), nullable=False) kd_blok = Column(String(3), nullable=False)
# Bit 62 / Invoice ID # Field pembayaran_sppt.no_urut
no_urut = Column(String(4), nullable=False) no_urut = Column(String(4), nullable=False)
# Bit 62 / Invoice ID # Field pembayaran_sppt.kd_jns_op
kd_jns_op = Column(String(1), nullable=False) kd_jns_op = Column(String(1), nullable=False)
# Bit 62 / Invoice ID # Field pembayaran_sppt.thn_pajak_sppt
thn_pajak_sppt = Column(String(4), nullable=False) thn_pajak_sppt = Column(String(4), nullable=False)
# Field sppt.pbb_yg_harus_dibayar_sppt
pbb_yg_harus_dibayar_sppt = Column(Float, nullable=False)
# Field pembayaran_sppt.pembayaran_sppt_ke # Field pembayaran_sppt.pembayaran_sppt_ke
pembayaran_sppt_ke = Column(Integer, nullable=False) pembayaran_sppt_ke = Column(Integer, nullable=False)
# Bit 4 # Field sppt.pbb_yg_harus_dibayar_sppt
pbb_yg_harus_dibayar_sppt = Column(Float, nullable=False)
# Field pembayaran_sppt.jml_sppt_yg_dibayar
jml_sppt_yg_dibayar = Column(BigInteger, nullable=False) jml_sppt_yg_dibayar = Column(BigInteger, nullable=False)
# Field pembayaran_sppt.denda_sppt # Field pembayaran_sppt.denda_sppt
denda_sppt = Column(BigInteger, nullable=False) denda_sppt = Column(BigInteger, nullable=False)
...@@ -193,5 +189,8 @@ class Pbb(Base, Common): ...@@ -193,5 +189,8 @@ class Pbb(Base, Common):
bank_id = Column(String(4)) bank_id = Column(String(4))
tgl_batal = Column(DateTime(timezone=True)) tgl_batal = Column(DateTime(timezone=True))
__table_args__ = dict( __table_args__ = dict(
UniqueConstraint('stan', 'ntb'), UniqueConstraint(
'kd_propinsi', 'kd_dati2', 'kd_kecamatan', 'kd_kelurahan',
'kd_blok', 'no_urut', 'kd_jns_op', 'thn_pajak_sppt'),
) )
...@@ -228,8 +228,6 @@ def make_pid_file(filename): ...@@ -228,8 +228,6 @@ def make_pid_file(filename):
class BaseApp: class BaseApp:
report_orm = None # Override, please
def __init__(self, argv): def __init__(self, argv):
self.option = get_option(argv) self.option = get_option(argv)
cp = ConfigParser() cp = ConfigParser()
...@@ -247,7 +245,6 @@ class BaseApp: ...@@ -247,7 +245,6 @@ class BaseApp:
factory = self.get_factory('report_db_url') factory = self.get_factory('report_db_url')
self.rpt_session = factory() self.rpt_session = factory()
register(self.rpt_session) register(self.rpt_session)
self.base_q_report = self.rpt_session.query(self.report_orm)
def get_factory(self, name): def get_factory(self, name):
db_url = self.conf[name] db_url = self.conf[name]
......
...@@ -5,7 +5,6 @@ pad json payment last id,0,pad_payment.id terakhir yang diproses ...@@ -5,7 +5,6 @@ pad json payment last id,0,pad_payment.id terakhir yang diproses
pad json reversal last date,1-1-2000 00:00:00,pad_reversal.tgl terakhir yang diproses pad json reversal last date,1-1-2000 00:00:00,pad_reversal.tgl terakhir yang diproses
pad2 payment last id,0,log_iso.id terakhir yang diproses pad2 payment last id,0,log_iso.id terakhir yang diproses
pad2 reversal last id,0,log_iso.id terakhir yang diproses pad2 reversal last id,0,log_iso.id terakhir yang diproses
webr0 payment last id,0,webr.ar_payment.id terakhir yang diproses
webr payment last id,0,log_iso.id terakhir yang diproses webr payment last id,0,log_iso.id terakhir yang diproses
webr2 payment last id,0,log_iso.id terakhir yang diproses webr2 payment last id,0,log_iso.id terakhir yang diproses
webr2 reversal last id,0,log_iso.id terakhir yang diproses webr2 reversal last id,0,log_iso.id terakhir yang diproses
...@@ -15,7 +14,7 @@ bphtb json payment last id,0,bphtb.bphtb_payment.id terakhir yang diproses ...@@ -15,7 +14,7 @@ bphtb json payment last id,0,bphtb.bphtb_payment.id terakhir yang diproses
bphtb json reversal last date,1-1-2000 00:00:00,bphtb.bphtb_reversal.tgl terakhir yang diproses bphtb json reversal last date,1-1-2000 00:00:00,bphtb.bphtb_reversal.tgl terakhir yang diproses
bphtb2 payment last id,0,log_iso.id terakhir yang diproses bphtb2 payment last id,0,log_iso.id terakhir yang diproses
bphtb2 reversal last id,0,log_iso.id terakhir yang diproses bphtb2 reversal last id,0,log_iso.id terakhir yang diproses
pbb payment last id,0,inquiry.id terakhir yang diproses pbb payment last date,1-1-2000,pembayaran_sppt.tgl_rekam_byr_sppt terakhir yang diproses
pbb reversal last date,1-1-2000 00:00:00,reversal.tgl terakhir yang diproses pbb reversal last date,1-1-2000 00:00:00,reversal.tgl terakhir yang diproses
pbb2 payment last id,0,log_iso.id terakhir yang diproses pbb2 payment last id,0,log_iso.id terakhir yang diproses
pbb2 reversal last id,0,log_iso.id terakhir yang diproses pbb2 reversal last id,0,log_iso.id terakhir yang diproses
......
import sys import sys
from datetime import (
datetime,
date,
timedelta,
)
from ISO8583.ISO8583 import BitNotSet from ISO8583.ISO8583 import BitNotSet
from sqlalchemy import func
import transaction import transaction
from sismiop.services.base import get_id
from opensipkd.string import ( from opensipkd.string import (
FixLength, FixLength,
DateTimeVar, DateTimeVar,
...@@ -8,7 +15,6 @@ from opensipkd.string import ( ...@@ -8,7 +15,6 @@ from opensipkd.string import (
from opensipkd.waktu import ( from opensipkd.waktu import (
dmyhms, dmyhms,
create_datetime, create_datetime,
date_from_str,
) )
from opensipkd.iso8583.bjb.scripts.common import get_module_object from opensipkd.iso8583.bjb.scripts.common import get_module_object
from opensipkd.iso8583.bjb.pbb.default import Doc from opensipkd.iso8583.bjb.pbb.default import Doc
...@@ -16,15 +22,17 @@ from opensipkd.iso8583.bjb.pbb.structure import INVOICE_PROFILE ...@@ -16,15 +22,17 @@ from opensipkd.iso8583.bjb.pbb.structure import INVOICE_PROFILE
from ..models import Pbb from ..models import Pbb
from .common import ( from .common import (
get_iso, get_iso,
get_keys, get_channel_info_by_iso,
App as BaseApp, BaseApp,
) )
ERR_PSPPT_NOT_FOUND = 'Tgl {tgl_bayar} SPPT ID {invoice_id} '\ ERR_SPPT_NOT_FOUND = 'SPPT ID {invoice_id} tidak ada di tabel sppt'
'tidak ada di pembayaran_sppt'
ERR_SPPT_NOT_FOUND = 'Tgl {tgl_bayar} SPPT ID {invoice_id}'\ one_second = timedelta(1/24/60/60)
'tidak ada di tabel sppt' one_day = timedelta(1)
row_limit = 1000
def get_profile(iso): def get_profile(iso):
...@@ -37,21 +45,13 @@ def get_profile(iso): ...@@ -37,21 +45,13 @@ def get_profile(iso):
def get_nama_wp(iso, sppt): def get_nama_wp(iso, sppt):
if iso:
p = get_profile(iso) p = get_profile(iso)
if p: if p:
return p['Nama'] return p['Nama']
return sppt.nm_wp_sppt return sppt.nm_wp_sppt
def get_tgl_bayar(iso, year):
raw = iso.get_value(7)
t = DateTimeVar()
t.set_raw(raw)
return create_datetime(
year, int(t['month']), int(t['day']), int(t['hour']),
int(t['minute']), int(t['second']))
def get_user_id(iso): def get_user_id(iso):
try: try:
return iso.getBit(107) return iso.getBit(107)
...@@ -59,10 +59,16 @@ def get_user_id(iso): ...@@ -59,10 +59,16 @@ def get_user_id(iso):
return return
class App(BaseApp): def data_pkeys(psppt):
iso_class = Doc return dict(
report_orm = Pbb 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)
class App(BaseApp):
def __init__(self, argv): def __init__(self, argv):
super().__init__(argv) super().__init__(argv)
if not self.pid: if not self.pid:
...@@ -75,27 +81,13 @@ class App(BaseApp): ...@@ -75,27 +81,13 @@ class App(BaseApp):
self.iso_payment_orm, self.iso_inquiry_orm).filter( self.iso_payment_orm, self.iso_inquiry_orm).filter(
self.iso_payment_orm.inquiry_id == self.iso_inquiry_orm.id) self.iso_payment_orm.inquiry_id == self.iso_inquiry_orm.id)
self.models = get_module_object(self.conf['models']) self.models = get_module_object(self.conf['models'])
self.PembayaranSppt = self.models.PembayaranSppt self.Psppt = self.models.PembayaranSppt
self.Sppt = self.models.Sppt self.Sppt = self.models.Sppt
self.base_q_psppt = self.prod_session.query(self.PembayaranSppt)
self.base_q_sppt = self.prod_session.query(self.Sppt) self.base_q_sppt = self.prod_session.query(self.Sppt)
def get_iso_reversal_orm(self): # Override def get_iso_reversal_orm(self): # Override
return self.iso_reversal_orm return self.iso_reversal_orm
def get_psppt(self, pay):
q = self.base_q_psppt.filter_by(
kd_propinsi=pay.propinsi,
kd_dati2=pay.kabupaten,
kd_kecamatan=pay.kecamatan,
kd_kelurahan=pay.kelurahan,
kd_blok=pay.blok,
no_urut=pay.urut,
kd_jns_op=pay.jenis,
thn_pajak_sppt=str(pay.tahun),
pembayaran_sppt_ke=pay.ke)
return q.first()
def get_sppt(self, psppt): def get_sppt(self, psppt):
q = self.base_q_sppt.filter_by( q = self.base_q_sppt.filter_by(
kd_propinsi=psppt.kd_propinsi, kd_propinsi=psppt.kd_propinsi,
...@@ -108,121 +100,160 @@ class App(BaseApp): ...@@ -108,121 +100,160 @@ class App(BaseApp):
thn_pajak_sppt=psppt.thn_pajak_sppt) thn_pajak_sppt=psppt.thn_pajak_sppt)
return q.first() return q.first()
def __get_query_iso(self, last_id): def create_data(self, psppt, row_pay, iso):
q_iso = self.base_q_iso.filter(self.iso_inquiry_orm.id > last_id)
return q_iso.order_by(self.iso_inquiry_orm.id)
def __log_psppt_not_found(self, s_tgl, d):
msg = ERR_PSPPT_NOT_FOUND.format(
tgl_bayar=s_tgl, invoice_id=d['nomor_bayar'])
self.log.error(msg)
def __log_sppt_not_found(self, s_tgl, d):
msg = ERR_SPPT_NOT_FOUND.format(
tgl_bayar=s_tgl, invoice_id=d['nomor_bayar'])
self.log.error(msg)
def __log_progress(self, s_tgl, d):
self.log.info(f'Tgl bayar {s_tgl}, {d}')
def __create_data(self, row_inq, iso, d, tgl_bayar, psppt):
sppt = self.get_sppt(psppt) sppt = self.get_sppt(psppt)
if not sppt: if not sppt:
self.__log_sppt_not_found(tgl_bayar, d) invoice_id = get_id(psppt)
msg = ERR_SPPT_NOT_FOUND.format(invoice_id=invoice_id)
self.log.error(msg)
return return
nama_wp = get_nama_wp(iso, sppt) nama_wp = get_nama_wp(iso, sppt)
user_id = get_user_id(iso) bank_id = iso and iso.get_bank_id() or None
user_id = iso and get_user_id(iso) or None
discount = hasattr(psppt, 'discount') and psppt.discount or None discount = hasattr(psppt, 'discount') and psppt.discount or None
stan = iso and iso.get_stan() or None
ntb = iso and iso.get_ntb() or None
channel_kode = iso and iso.get_channel().strip() or \
(row_pay and row_pay.channel) or '0000'
return dict( return dict(
stan=d['stan'], ntb=d['ntb'], stan=stan, ntb=ntb, jml_sppt_yg_dibayar=psppt.jml_sppt_yg_dibayar,
kd_propinsi=psppt.kd_propinsi, kd_dati2=psppt.kd_dati2, denda_sppt=psppt.denda_sppt, discount=discount,
kd_kecamatan=psppt.kd_kecamatan, kd_kelurahan=psppt.kd_kelurahan, tgl_pembayaran_sppt=psppt.tgl_pembayaran_sppt.date(),
kd_blok=psppt.kd_blok, no_urut=psppt.no_urut, tgl_rekam_byr_sppt=psppt.tgl_rekam_byr_sppt,
kd_jns_op=psppt.kd_jns_op, thn_pajak_sppt=psppt.thn_pajak_sppt, nm_wp_sppt=nama_wp, channel_kode=channel_kode,
pembayaran_sppt_ke=psppt.pembayaran_sppt_ke, bank_id=bank_id, user_id=user_id,
jml_sppt_yg_dibayar=iso.get_amount(), pbb_yg_harus_dibayar_sppt=sppt.pbb_yg_harus_dibayar_sppt)
denda_sppt=psppt.denda_sppt, tgl_pembayaran_sppt=tgl_bayar.date(),
tgl_rekam_byr_sppt=tgl_bayar, nm_wp_sppt=nama_wp, def get_iso_row(self, psppt):
channel_kode=iso.get_channel().strip(), channel_nama=d['channel'], iso_pay = self.iso_payment_orm
user_id=user_id, iso_inq = self.iso_inquiry_orm
pbb_yg_harus_dibayar_sppt=sppt.pbb_yg_harus_dibayar_sppt, q = self.base_q_iso.filter_by(
tgl_inquiry=row_inq.tgl, discount=discount, bank_id=d['bit_32']) propinsi=psppt.kd_propinsi,
kabupaten=psppt.kd_dati2,
def __run_payment(self): kecamatan=psppt.kd_kecamatan,
last = self.get_last_id('pbb payment last id') kelurahan=psppt.kd_kelurahan,
q_iso = self.__get_query_iso(last.as_int()) blok=psppt.kd_blok,
found = False urut=psppt.no_urut,
for row_pay, row_inq in q_iso.limit(1000): jenis=psppt.kd_jns_op,
tahun=psppt.thn_pajak_sppt,
ke=psppt.pembayaran_sppt_ke)
q = q.order_by(iso_inq.id.desc())
return q.first()
def get_channel(self, psppt):
row_pay = self.get_iso_row(psppt)
if row_pay:
row_pay, row_inq = row_pay
iso = get_iso(row_pay.iso_request, Doc, self.option.debug) iso = get_iso(row_pay.iso_request, Doc, self.option.debug)
if self.get_report(iso): info = get_channel_info_by_iso(iso)
continue if psppt.tgl_rekam_byr_sppt.date() != row_inq.tgl.date():
d = get_keys(iso) raise TglTidakSama
tgl_bayar = get_tgl_bayar(iso, row_inq.tgl.year) return info['channel'], row_pay, row_inq, iso
s_tgl = dmyhms(tgl_bayar) return 'MANUAL', None, None, None
psppt = self.get_psppt(row_pay)
if not psppt: def get_report(self, psppt):
self.__log_psppt_not_found(s_tgl, d) q = self.rpt_session.query(Pbb).filter_by(
continue kd_propinsi=psppt.kd_propinsi,
self.__log_progress(s_tgl, d) kd_dati2=psppt.kd_dati2,
d = self.__create_data(row_inq, iso, d, tgl_bayar, psppt) kd_kecamatan=psppt.kd_kecamatan,
if d: kd_kelurahan=psppt.kd_kelurahan,
rpt = Pbb(**d) kd_blok=psppt.kd_blok,
last.nilai = str(row_inq.id) 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)
return q.first()
def update_last(self):
self.last.nilai = dmyhms(self.last_psppt.tgl_rekam_byr_sppt)
with transaction.manager: with transaction.manager:
self.rpt_session.add(rpt) self.rpt_session.add(self.last)
self.rpt_session.add(last)
found = True def __main_log_msg(self, no, psppt, d):
return found invoice_id = get_id(psppt)
tgl = psppt.tgl_rekam_byr_sppt.strftime('%d-%m-%Y %H:%M:%S')
return f'#{no}/{self.count} '\
f'ID {invoice_id} ke {psppt.pembayaran_sppt_ke}, '\
f'Tgl bayar {tgl}, Channel {d["channel_nama"]}'
def __update_from_id(self): def update_from_date(self):
q_iso = self.__get_query_iso(self.last_id) q = self.prod_session.query(self.Psppt).filter(
self.Psppt.tgl_rekam_byr_sppt > self.tgl_awal,
self.Psppt.tgl_rekam_byr_sppt < self.tgl_akhir)
q = q.order_by(self.Psppt.tgl_rekam_byr_sppt)
self.last_psppt = None
no = self.offset
found = False found = False
for row_pay, row_inq in q_iso.limit(1000): for psppt in q.offset(self.offset).limit(row_limit):
iso = get_iso(row_pay.iso_request, Doc, self.option.debug) found = True
d = get_keys(iso) no += 1
tgl_bayar = get_tgl_bayar(iso, row_inq.tgl.year) channel_nama, row_pay, row_inq, iso = self.get_channel(psppt)
s_tgl = dmyhms(tgl_bayar) d = dict(channel_nama=channel_nama)
psppt = self.get_psppt(row_pay) if iso:
if not psppt: if psppt.tgl_rekam_byr_sppt.date() != row_inq.tgl.date():
self.__log_psppt_not_found(s_tgl, d) raise TglTidakSama
d['tgl_inquiry'] = row_inq.tgl
msg = self.__main_log_msg(no, psppt, d)
if iso:
msg = f'{msg}, STAN {iso.get_stan()}, NTB {iso.get_ntb()}'
if not psppt.jml_sppt_yg_dibayar:
self.log.warning(
f'{msg}, field jml_sppt_yg_dibayar 0, abaikan')
continue continue
self.__log_progress(s_tgl, d) self.log.info(msg)
d = self.__create_data(row_inq, iso, d, tgl_bayar, psppt) data = self.create_data(psppt, row_pay, iso)
if d: d.update(data)
rpt = self.get_report(iso) rpt = self.get_report(psppt)
if not rpt: if rpt:
rpt = Pbb()
rpt.from_dict(d) rpt.from_dict(d)
else:
pkeys = data_pkeys(psppt)
d.update(pkeys)
rpt = Pbb(**d)
with transaction.manager: with transaction.manager:
self.rpt_session.add(rpt) self.rpt_session.add(rpt)
found = True self.last_psppt = psppt
self.last_id = row_inq.id self.offset += row_limit
return found return found
def get_count(self):
q = self.prod_session.query(func.count()).filter(
self.Psppt.tgl_rekam_byr_sppt > self.tgl_awal,
self.Psppt.tgl_rekam_byr_sppt < self.tgl_akhir)
return q.scalar()
def run_payment(self): # Override def run_payment(self): # Override
self.last = None
self.offset = 0
if self.option.update_from_id: if self.option.update_from_id:
self.last_id = self.option.update_from_id raise UpdateFromIdNotImplemented
func = self.__update_from_id if self.option.update_from_date:
elif self.option.update_from_date: t = self.option.update_from_date.split(',')
tgl = date_from_str(self.option.update_from_date) awal = datetime.strptime(t[0], '%d-%m-%Y')
q = self.prod_session.query(self.iso_inquiry_orm).filter( self.tgl_awal = datetime(awal.year, awal.month, awal.day)
self.iso_inquiry_orm.tgl >= tgl).order_by( self.tgl_awal -= one_second
self.iso_inquiry_orm.id) if t[1:]:
row = q.first() self.tgl_akhir = datetime.strptime(t[1], '%d-%m-%Y').date()
self.last_id = row.id - 1 else:
func = self.__update_from_id self.tgl_akhir = date.today()
self.tgl_akhir += one_day
else: else:
func = self.__run_payment self.last = self.get_last_id('pbb payment last date')
self.tgl_awal = self.last.as_datetime()
self.tgl_akhir = date.today() + one_day()
self.count = self.get_count()
while True: while True:
found = func() found = self.update_from_date()
if not found: if not found:
break break
if self.last:
self.update_last()
def get_doc_for_reversal(self, row): def get_doc_for_reversal(self, row):
return Doc return Doc
def run_reversal(self): # Override def run_reversal(self): # Override
super().run_reversal('pbb reversal last date') pass
def main(argv=sys.argv[1:]): def main(argv=sys.argv[1:]):
......
from datetime import (
datetime,
date,
time as mktime,
)
#################
# Compare value #
#################
MIDNIGHT_TIME = mktime(0, 0, 0)
def split_time(t):
if isinstance(t, datetime):
return t.date(), t.time()
return t, MIDNIGHT_TIME
def is_same(a, b):
if a == b:
return True
if not (isinstance(a, date) or isinstance(a, datetime)):
return False
date_a, time_a = split_time(a)
date_b, time_b = split_time(b)
if date_a != date_b:
return False
if isinstance(a, date) or isinstance(b, date):
return True
if time_a == time_b:
return True
return False
import sys import sys
from datetime import datetime
from sqlalchemy.exc import ProgrammingError from sqlalchemy.exc import ProgrammingError
import transaction import transaction
from opensipkd.waktu import dmyhms from opensipkd.waktu import dmyhms
...@@ -6,98 +7,122 @@ from opensipkd.webr.models.default import ( ...@@ -6,98 +7,122 @@ from opensipkd.webr.models.default import (
Payment, Payment,
Invoice, Invoice,
) )
from iso8583_web.models.meta import Base as BaseConf
from opensipkd.iso8583.bjb.webr.structure import PAYMENT_CODE from opensipkd.iso8583.bjb.webr.structure import PAYMENT_CODE
from opensipkd.iso8583.bjb.webr.models import ( from opensipkd.iso8583.bjb.webr.models import (
LogMixin, LogMixin,
Log, Log,
) )
from iso8583_web.models.meta import Base as BaseConf
from ..models import ( from ..models import (
Base, Base,
Webr, Webr,
) )
from .common import ( from .common import (
App2 as BaseApp, BaseApp,
init_db as base_init_db, init_db as base_init_db,
BIT_18_NAMES,
get_channel_name_by_row,
) )
ERR_NOT_FOUND = 'Tgl {tgl_bayar} nomor bayar {invoice_id} tidak ada'
class AlternativeLog(Base, LogMixin): class AlternativeLog(Base, LogMixin):
__table_args__ = dict(schema='webr') __table_args__ = dict(schema='webr')
class App(BaseApp): class App(BaseApp):
field_invoice_id = 'bit_061'
field_ntb = 'bit_048'
report_orm = Webr
log_orm = Log
def __init__(self, argv): def __init__(self, argv):
super().__init__(argv) super().__init__(argv)
if not self.pid: if not self.pid:
return return
self.base_q_iso_resp = self.prod_session.query(Log) self.base_q_pay = self.prod_session.query(Payment, Invoice).filter(
Payment.ar_invoice_id == Invoice.id)
self.base_q_iso = self.prod_session.query(Log)
try: try:
self.base_q_iso_resp.first() self.base_q_iso.first()
self.IsoLog = Log
except ProgrammingError: except ProgrammingError:
self.prod_session.rollback() self.prod_session.rollback()
self.base_q_iso_resp = self.prod_session.query(AlternativeLog) self.base_q_iso = self.prod_session.query(AlternativeLog)
self.base_q_iso_resp = self.base_q_iso_resp.filter_by( self.IsoLog = AlternativeLog
mti='0210', bit_003=PAYMENT_CODE) self.base_q_iso = self.base_q_iso.filter_by(
self.base_q_pay = self.prod_session.query(Payment, Invoice).filter( mti='0210', bit_003=PAYMENT_CODE, bit_039='00')
Payment.ar_invoice_id == Invoice.id)
def get_pay(self, d): def get_channel(self, pay, inv):
q_pay = self.base_q_pay.filter(Invoice.kode == d['nomor_bayar']) if not pay.bank_id:
return q_pay.order_by(Payment.id.desc()).first() return '0000', 'MANUAL', None
nomor_bayar = inv.kode
q = self.base_q_iso.filter(self.IsoLog.bit_061.like(f'{nomor_bayar}%'))
iso = q.first()
if not iso:
name = BIT_18_NAMES[str(pay.channel_id)]
return pay.channel_id, name, None
name = get_channel_name_by_row(iso)
return iso.bit_018, name, iso
def is_iso_resp_ok(self, iso_req): def update_last(self, pay):
q = self.base_q_iso_resp.filter_by( self.last_id = pay.id
bit_011=iso_req.bit_011, bit_048=iso_req.bit_048) self.last.nilai = str(pay.id)
iso_resp = q.order_by(Log.id.desc()).first() with transaction.manager:
return iso_resp and iso_resp.bit_039 == '00' self.rpt_session.add(self.last)
def run_payment(self): def update_from_id(self):
last = self.get_last_id('webr payment last id') q_pay = self.base_q_pay.filter(Payment.id > self.last_id)
q_iso_req = self.prod_session.query(Log).filter_by( no = 0
mti='0200', bit_003=PAYMENT_CODE).filter( for pay, inv in q_pay.order_by(Payment.id).limit(1000):
Log.id > last.as_int()) no += 1
for iso_req in q_iso_req.order_by(Log.id): channel_id, channel_name, iso = self.get_channel(pay, inv)
if self.get_report(iso_req): nomor_bayar = inv.kode
continue tgl_bayar = pay.created.date()
if not self.is_iso_resp_ok(iso_req): s_tgl = dmyhms(pay.created)
continue stan = iso and iso.bit_011 or None
d = self.get_keys(iso_req) ntb = pay.ntb and pay.ntb.strip() or None
tgl_bayar = iso_req.created.date() msg = f'#{no} ID {pay.id}, Tgl bayar {s_tgl}, '\
pay = self.get_pay(d) f'Nomor bayar {nomor_bayar}, Channel {channel_name}'
if not pay: if iso:
msg = ERR_NOT_FOUND.format( msg = f'{msg}, STAN {stan}, NTB {ntb}'
tgl_bayar=tgl_bayar, invoice_id=d['nomor_bayar']) if not pay.bayar:
self.log.error(msg) self.log.warning(f'{msg}, field bayar 0, abaikan')
self.last and self.update_last(pay)
continue continue
pay, inv = pay self.log.info(msg)
s_tgl = dmyhms(iso_req.created) d = dict(
self.log.info( stan=stan, ntb=ntb, tgl=tgl_bayar, jam=pay.created.time(),
f'Tgl bayar {s_tgl}, Nomor bayar {d["nomor_bayar"]}, ' nomor_bayar=nomor_bayar, nama_wp=inv.subjek_nama,
f'STAN {d["stan"]}, NTB {d["ntb"]}, Channel {d["channel"]}') pokok=inv.jumlah-inv.bunga, denda=pay.bunga,
rpt = Webr( jml_bayar=pay.bayar, channel_id=channel_id,
stan=d['stan'], ntb=d['ntb'], tgl=tgl_bayar, channel_name=channel_name)
jam=iso_req.created.time(), payment_id=pay.id, q = self.rpt_session.query(Webr).filter_by(id=pay.id)
nomor_bayar=d['nomor_bayar'], rpt = q.first()
nama_wp=inv.subjek_nama, pokok=inv.jumlah-inv.bunga, if rpt:
denda=pay.bunga, jml_bayar=pay.bayar, rpt.from_dict(d)
channel_id=iso_req.bit_018.strip(), else:
channel_name=d['channel']) d['id'] = pay.id
last.nilai = str(iso_req.id) rpt = Webr(**d)
self.last_id = pay.id
with transaction.manager: with transaction.manager:
self.rpt_session.add(rpt) self.rpt_session.add(rpt)
if self.last:
self.last.nilai = str(pay.id)
self.rpt_session.add(last) self.rpt_session.add(last)
return no
def run_reversal(self): # Override def run_payment(self): # Override
super().run_reversal('webr reversal last id') self.last = None
if self.option.update_from_id:
self.last_id = self.option.update_from_id
elif self.option.update_from_date:
tgl = datetime.strptime(self.option.update_from_date, '%d-%m-%Y')
q = self.prod_session.query(Payment).filter(
Payment.created >= tgl).order_by(Payment.id)
row = q.first()
self.last_id = row.id - 1
else:
self.last = self.get_last_id('webr payment last id')
self.last_id = self.last.as_int()
while True:
found = self.update_from_id()
if not found:
break
def main(argv=sys.argv[1:]): def main(argv=sys.argv[1:]):
......
import sys
import transaction
from opensipkd.waktu import dmyhms
from opensipkd.webr.models.default import (
Payment,
Invoice,
)
from iso8583_web.models.meta import Base as BaseConf
from opensipkd.iso8583.bjb.webr.models import Log
from ..models import (
Base,
Webr,
)
from .common import (
BaseApp,
init_db as base_init_db,
BIT_18_NAMES,
)
class App(BaseApp):
report_orm = Webr
def __init__(self, argv):
super().__init__(argv)
if not self.pid:
return
self.base_q_pay = self.prod_session.query(Payment, Invoice).filter(
Payment.ar_invoice_id == Invoice.id)
def tgl_awal_log_iso(self):
q = self.prod_session.query(Log).order_by(Log.id)
row = q.first()
return row.created.date()
def run_payment(self):
tgl = self.tgl_awal_log_iso()
last = self.get_last_id('webr0 payment last id')
q_pay = self.base_q_pay.filter(
Payment.created < tgl, Payment.id > last.as_int())
rpt_id = 0
for pay, inv in q_pay.order_by(Payment.id):
rpt_id += 1
if not pay.channel_id: # Biasanya hasil test
continue
nomor_bayar = inv.kode
tgl_bayar = pay.created.date()
s_tgl = dmyhms(pay.created)
stan = pay.created.strftime('%H%M%S')
channel_id = str(pay.channel_id)
channel = BIT_18_NAMES[channel_id]
self.log.info(
f'Tgl bayar {s_tgl}, Nomor bayar {nomor_bayar}, '
f'STAN {stan}, NTB {pay.ntb}, Channel {channel}')
rpt = Webr(
id=rpt_id, stan=stan, ntb=pay.ntb, tgl=tgl_bayar,
jam=pay.created.time(), payment_id=pay.id,
nomor_bayar=nomor_bayar, nama_wp=inv.subjek_nama,
pokok=inv.jumlah-inv.bunga, denda=pay.bunga,
jml_bayar=pay.bayar, channel_id=channel_id,
channel_name=channel)
last.nilai = str(pay.id)
with transaction.manager:
self.rpt_session.add(rpt)
self.rpt_session.add(last)
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)
...@@ -45,7 +45,6 @@ setup( ...@@ -45,7 +45,6 @@ setup(
'pad_report = payment_report.scripts.pad:main', 'pad_report = payment_report.scripts.pad:main',
'pad_json_report = payment_report.scripts.pad_json:main', 'pad_json_report = payment_report.scripts.pad_json:main',
'pad2_report = payment_report.scripts.pad2:main', 'pad2_report = payment_report.scripts.pad2:main',
'webr0_report = payment_report.scripts.webr0:main',
'webr_report = payment_report.scripts.webr:main', 'webr_report = payment_report.scripts.webr:main',
'webr2_report = payment_report.scripts.webr2:main', 'webr2_report = payment_report.scripts.webr2:main',
], ],
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!