Commit b0dacb88 by Owo Sugiana

Tambah PBB

1 parent 29d42c43
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 0.1 2-4-2021
------------ ------------
- Kali pertama - Kali pertama
...@@ -46,7 +46,7 @@ Lalu buat file konfigurasi bernama ``pad.ini``:: ...@@ -46,7 +46,7 @@ Lalu buat file konfigurasi bernama ``pad.ini``::
Buat tabel yang dibutuhkan di database ``payment_report``:: Buat tabel yang dibutuhkan di database ``payment_report``::
$ ~/env/bin/pad_report_init_db pad.ini $ ~/env/bin/payment_report_init_db pad.ini
Kemudian buat file ``/etc/cron.d/payment-report`` berikut ini:: Kemudian buat file ``/etc/cron.d/payment-report`` berikut ini::
...@@ -80,10 +80,6 @@ Lalu buat file konfigurasi bernama ``bphtb.ini``:: ...@@ -80,10 +80,6 @@ Lalu buat file konfigurasi bernama ``bphtb.ini``::
pid_file = /home/sugiana/tmp/bphtb-report.pid pid_file = /home/sugiana/tmp/bphtb-report.pid
log_file = /home/sugiana/log/bphtb-report.log log_file = /home/sugiana/log/bphtb-report.log
Buat tabel yang dibutuhkan di database ``payment_report``::
$ ~/env/bin/bphtb_report_init_db bphtb.ini
Kemudian di file ``/etc/cron.d/payment-report`` tambahkan:: Kemudian di file ``/etc/cron.d/payment-report`` tambahkan::
*/5 * * * * sugiana cd /home/sugiana/payment-report && ../env/bin/bphtb_report bphtb.ini */5 * * * * sugiana cd /home/sugiana/payment-report && ../env/bin/bphtb_report bphtb.ini
...@@ -91,4 +87,49 @@ Kemudian di file ``/etc/cron.d/payment-report`` tambahkan:: ...@@ -91,4 +87,49 @@ Kemudian di file ``/etc/cron.d/payment-report`` tambahkan::
Lalu pantau log-nya. Jika sudah ada penampakan lihat hasilnya di tabel ``bphtb_report``. Lalu pantau log-nya. Jika sudah ada penampakan lihat hasilnya di tabel ``bphtb_report``.
BPHTB Versi 2
-------------
Yang dimaksud versi 2 di sini adalah tidak lagi mencatat ISO8583 di tabel
``bphtb.bphtb_payment`` dan ``bphtb.bphtb_reversal`` melainkan sepenuhnya di
tabel ``log_iso``. Jika tabel ini sudah ada maka script sebelumnya yaitu
``bin/bphtb_report`` cukup dijalankan sekali saja, tidak perlu ditaruh di cron.
Lalu beri hak akses ke tabel ``log_iso``::
GRANT SELECT ON log_iso TO report;
Kemudian di file ``/etc/cron.d/payment-report`` menjadi begini::
*/5 * * * * sugiana cd /home/sugiana/payment-report && ../env/bin/bphtb2_report bphtb.ini
Ya, tidak ada perubahan dengan file konfigurasi. Semoga berhasil.
PBB
---
Berikan hak akses yang diperlukan user ``report``::
$ sudo su - postgres -c "psql pbb"
GRANT SELECT ON pembayaran_sppt TO report;
GRANT USAGE ON SCHEMA pbb TO report;
GRANT SELECT ON pbb.inquiry TO report;
GRANT SELECT ON pbb.payment TO report;
GRANT SELECT ON pbb.reversal TO report;
Lalu buat file konfigurasi bernama ``pbb.ini``::
[main]
module = opensipkd.iso8583.bjb.bphtb.default
db_url = postgresql://report:password@localhost:5434/pbb
report_db_url = postgresql://report:password@localhost:5434/payment_report
pid_file = /home/sugiana/tmp/pbb-report.pid
log_file = /home/sugiana/log/pbb-report.log
Kemudian di file ``/etc/cron.d/payment-report`` tambahkan::
*/5 * * * * sugiana cd /home/sugiana/payment-report && ../env/bin/pbb_report pbb.ini
Lalu pantau log-nya. Jika sudah ada penampakan lihat hasilnya di tabel ``pbb_report``.
...@@ -94,3 +94,48 @@ class Bphtb(Base): ...@@ -94,3 +94,48 @@ class Bphtb(Base):
__table_args__ = ( __table_args__ = (
UniqueConstraint('stan', 'ntb'), UniqueConstraint('stan', 'ntb'),
) )
class Pbb(Base):
__tablename__ = 'pbb_report'
id = Column(Integer, primary_key=True)
# Bit 11
stan = Column(String(6), nullable=False)
# Bit 48
ntb = Column(String(32), nullable=False)
# Bit 62 / Invoice ID
kd_propinsi = Column(String(2), nullable=False)
# Bit 62 / Invoice ID
kd_dati2 = Column(String(2), nullable=False)
# Bit 62 / Invoice ID
kd_kecamatan = Column(String(3), nullable=False)
# Bit 62 / Invoice ID
kd_kelurahan = Column(String(3), nullable=False)
# Bit 62 / Invoice ID
kd_blok = Column(String(3), nullable=False)
# Bit 62 / Invoice ID
no_urut = Column(String(4), nullable=False)
# Bit 62 / Invoice ID
kd_jns_op = Column(String(1), nullable=False)
# Bit 62 / Invoice ID
thn_pajak_sppt = Column(String(4), nullable=False)
# Field pembayaran_sppt.pembayaran_sppt_ke
pembayaran_sppt_ke = Column(Integer, nullable=False)
# Bit 4
jml_sppt_yg_dibayar = Column(Integer, nullable=False)
# Bit 7 / Transmission Date
tgl_pembayaran_sppt = Column(Date, nullable=False)
# Bit 7 / Transmission DateTime
tgl_rekam_byr_sppt = Column(DateTime(timezone=True), nullable=False)
# Bit 62 / Invoice Profile
nm_wp_sppt = Column(String(30), nullable=False)
# Bit 18
channel_kode = Column(String(4), nullable=False)
# Bit 41 / 42 / 43
channel_nama = Column(String(32), nullable=False)
# Bit 107
user_id = Column(String(8), nullable=False)
tgl_batal = Column(DateTime(timezone=True))
__table_args__ = dict(
UniqueConstraint('stan', 'ntb'),
)
import sys
import transaction
from opensipkd.waktu import dmyhms
from opensipkd.bphtb.models.default import Perolehan
from opensipkd.bphtb.services.base import get_db_session
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 App(BaseApp):
field_invoice_id = 'bit_062'
field_ntb = 'bit_058'
report_orm = Bphtb
log_orm = Log
def __init__(self, argv):
super().__init__(argv)
if not self.pid:
return
self.base_q_perolehan = self.prod_session.query(Perolehan)
def get_db_session(self): # Override
return get_db_session()
def run_payment(self): # Override
last = self.get_last_id('bphtb2 payment last id')
q_iso = self.prod_session.query(Log).filter_by(
mti='0210', bit_003=PAYMENT_CODE, bit_039='00').filter(
Log.id > last.as_int())
for row_iso in q_iso.order_by(Log.id):
if self.get_report(row_iso):
continue
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 = row_iso.bit_047_data
q = self.base_q_perolehan.filter_by(id=p['Jenis Perolehan Hak'])
perolehan = q.first()
rpt = Bphtb(
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'])
last.nilai = str(row_iso.id)
print(f'last.nilai {last.nilai}')
with transaction.manager:
self.rpt_session.add(rpt)
self.rpt_session.add(last)
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)
...@@ -8,6 +8,7 @@ from datetime import ( ...@@ -8,6 +8,7 @@ from datetime import (
) )
from argparse import ArgumentParser from argparse import ArgumentParser
from configparser import ConfigParser from configparser import ConfigParser
from ISO8583.ISO8583 import BitNotSet
from sqlalchemy import create_engine from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker from sqlalchemy.orm import sessionmaker
import transaction import transaction
...@@ -15,6 +16,7 @@ from zope.sqlalchemy import register ...@@ -15,6 +16,7 @@ from zope.sqlalchemy import register
from opensipkd.waktu import dmyhms from opensipkd.waktu import dmyhms
from iso8583_web.models.conf import Conf as BaseConf from iso8583_web.models.conf import Conf as BaseConf
from opensipkd.iso8583.bjb.scripts.common import get_module_object from opensipkd.iso8583.bjb.scripts.common import get_module_object
from ..models import Base
log_format = '%(asctime)s %(levelname)s %(message)s' log_format = '%(asctime)s %(levelname)s %(message)s'
...@@ -76,23 +78,15 @@ def get_iso(raw, iso_class, debug=False): ...@@ -76,23 +78,15 @@ def get_iso(raw, iso_class, debug=False):
return iso return iso
def get_keys(iso): def get_channel_name(bit_018, bit_041, bit_042, bit_043):
return dict( bit_018 = bit_018.strip()
nomor_bayar=iso.get_invoice_id().strip(), bit_041 = bit_041.strip()
stan=iso.get_stan().strip(), bit_042 = bit_042.strip()
ntb=iso.get_ntb().strip(), bit_043 = bit_043.strip()
channel=get_channel_name(iso)) if bit_018 in BIT_18_NAMES:
return BIT_18_NAMES[bit_018]
if bit_018 != '6025':
def get_channel_name(iso):
channel_id = iso.get_channel().strip()
if channel_id in BIT_18_NAMES:
return BIT_18_NAMES[channel_id]
if channel_id != '6025':
return '' return ''
bit_041 = iso.getBit(41).strip()
bit_042 = iso.getBit(42).strip()
bit_043 = iso.getBit(43).strip()
if bit_042 in ('TOKOPEDIA', 'BUKALAPAK', 'MASAGO'): if bit_042 in ('TOKOPEDIA', 'BUKALAPAK', 'MASAGO'):
return bit_042 return bit_042
if bit_042 == 'NG': if bit_042 == 'NG':
...@@ -102,6 +96,26 @@ def get_channel_name(iso): ...@@ -102,6 +96,26 @@ def get_channel_name(iso):
return 'LAINNYA' return 'LAINNYA'
def get_channel_name_by_iso(iso):
try:
return get_channel_name(
iso.getBit(18), iso.getBit(41), iso.getBit(42), iso.getBit(43))
except BitNotSet:
return 'LAINNYA'
def get_channel_name_by_row(row):
return get_channel_name(row.bit_018, row.bit_041, row.bit_042, row.bit_043)
def get_keys(iso):
return dict(
nomor_bayar=iso.get_invoice_id().strip(),
stan=iso.get_stan().strip(),
ntb=iso.get_ntb().strip(),
channel=get_channel_name_by_iso(iso))
def create_log(log_file): def create_log(log_file):
file_handler = logging.FileHandler(log_file) file_handler = logging.FileHandler(log_file)
file_handler.setFormatter(formatter) file_handler.setFormatter(formatter)
...@@ -172,10 +186,8 @@ def make_pid_file(filename): ...@@ -172,10 +186,8 @@ def make_pid_file(filename):
return write_pid_file(filename) return write_pid_file(filename)
class App: class BaseApp:
iso_class = None # Override, please
report_orm = None # Override, please report_orm = None # Override, please
iso_reversal_orm = None # Override, please
def __init__(self, argv): def __init__(self, argv):
self.option = get_option(argv) self.option = get_option(argv)
...@@ -187,10 +199,9 @@ class App: ...@@ -187,10 +199,9 @@ class App:
return return
self.log = create_log(cf['log_file']) self.log = create_log(cf['log_file'])
module_name = cf['module'] module_name = cf['module']
module = get_module_object(module_name) self.module = get_module_object(module_name)
module_conf = dict(cf) module_conf = dict(cf)
module.init(module_conf) self.module.init(module_conf)
iso = self.iso_class()
self.prod_session = self.get_db_session() self.prod_session = self.get_db_session()
self.prod_session.bind.echo = self.option.debug_sql self.prod_session.bind.echo = self.option.debug_sql
engine = create_engine(cf['report_db_url'], echo=self.option.debug_sql) engine = create_engine(cf['report_db_url'], echo=self.option.debug_sql)
...@@ -206,18 +217,38 @@ class App: ...@@ -206,18 +217,38 @@ class App:
q = self.rpt_session.query(Conf).filter_by(nama=nama) q = self.rpt_session.query(Conf).filter_by(nama=nama)
return q.first() return q.first()
def get_report(self, iso): def get_report(self, stan, ntb):
d = get_keys(iso) q = self.base_q_report.filter_by(stan=stan, ntb=ntb)
q = self.base_q_report.filter_by(stan=d['stan'], ntb=d['ntb'])
return q.first() return q.first()
def run_payment(self): # Override, please def run_payment(self): # Override, please
pass pass
def run_reversal(self, conf_name): # Override, please def run_reversal(self): # Override, please
pass
def run(self):
if not self.pid:
return
self.run_payment()
self.run_reversal()
# Tanpa tabel log_iso
class App(BaseApp):
iso_class = None # Override, please
iso_reversal_orm = None # Override, please
def get_report(self, iso): # Override
d = get_keys(iso)
return super().get_report(d['stan'], d['ntb'])
def run_reversal(self, conf_name): # Override
last = self.get_last_id(conf_name) last = self.get_last_id(conf_name)
q = self.prod_session.query(self.iso_reversal_orm).filter( q = self.prod_session.query(self.iso_reversal_orm).filter(
self.iso_reversal_orm.tgl > last.as_datetime()) self.iso_reversal_orm.tgl > last.as_datetime())
iso_class = self.module.Doc()
for row in q.order_by(self.iso_reversal_orm.tgl): for row in q.order_by(self.iso_reversal_orm.tgl):
iso = get_iso(row.iso_request, self.iso_class, self.option.debug) iso = get_iso(row.iso_request, self.iso_class, self.option.debug)
rpt = self.get_report(iso) rpt = self.get_report(iso)
...@@ -233,19 +264,66 @@ class App: ...@@ -233,19 +264,66 @@ class App:
self.rpt_session.add(rpt) self.rpt_session.add(rpt)
self.rpt_session.add(last) self.rpt_session.add(last)
def run(self):
self.run_payment() # Dengan tabel log_iso
self.run_reversal()
class App2(BaseApp):
log_orm = None # Override, please
field_invoice_id = None # Override, please
field_ntb = None # Override, please
def get_stan(self, row):
return row.bit_011.strip()
def get_invoice_id(self, row):
s = getattr(row, self.field_invoice_id)
return s.strip()
def get_ntb(self, row):
s = getattr(row, self.field_ntb)
return s.strip()
def get_report(self, row): # Override
stan = self.get_stan(row)
ntb = self.get_ntb(row)
return super().get_report(stan, ntb)
def get_keys(self, row):
return dict(
nomor_bayar=self.get_invoice_id(row),
stan=self.get_stan(row),
ntb=self.get_ntb(row),
channel=get_channel_name_by_row(row))
def run_reversal(self, conf_name): # Override
last = self.get_last_id(conf_name)
q = self.prod_session.query(self.log_orm).filter_by(
mti='0410', bit_039='00').filter(
self.log_orm.id > last.id)
for row in q.order_by(self.log_orm.id):
rpt = self.get_report(row)
if not rpt or rpt.tgl_batal:
continue
rpt.tgl_batal = row.created
s_tgl = dmyhms(row.created)
last.nilai = row.id
d = self.get_keys(row)
self.log.info(
f'Tgl batal {s_tgl}, Nomor bayar {d["nomor_bayar"]}, '
f'STAN {d["stan"]}, NTB {d["ntb"]}, Channel {d["channel"]}')
with transaction.manager:
self.rpt_session.add(rpt)
self.rpt_session.add(last)
def init_db(metadata_rpt, metadata_conf, argv=sys.argv[1:]): def init_db(argv=sys.argv[1:]):
conf_file = argv[0] conf_file = argv[0]
conf = ConfigParser() conf = ConfigParser()
conf.read(conf_file) conf.read(conf_file)
db_url = conf.get('main', 'report_db_url') db_url = conf.get('main', 'report_db_url')
engine = create_engine(db_url, echo=True) engine = create_engine(db_url, echo=True)
metadata_rpt.create_all(engine) Base.metadata.create_all(engine)
metadata_conf.create_all(engine) BaseConf.metadata.create_all(engine)
factory = sessionmaker(bind=engine) factory = sessionmaker(bind=engine)
my_registry['db_session'] = db_session = factory() my_registry['db_session'] = db_session = factory()
register(db_session) register(db_session)
......
...@@ -3,3 +3,9 @@ pad payment last id,0,pad_payment.id terakhir yang diproses ...@@ -3,3 +3,9 @@ pad payment last id,0,pad_payment.id terakhir yang diproses
pad reversal last date,1-1-2000 00:00:00,pad_reversal.tgl terakhir yang diproses pad reversal last date,1-1-2000 00:00:00,pad_reversal.tgl terakhir yang diproses
bphtb payment last id,0,bphtb.bphtb_payment.id terakhir yang diproses bphtb payment last id,0,bphtb.bphtb_payment.id terakhir yang diproses
bphtb reversal last date,1-1-2000 00:00:00,bphtb.bphtb_reversal.tgl terakhir yang diproses bphtb 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 reversal last id,0,log_iso.id terakhir yang diproses
pbb payment last id,0,inquiry.id 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 reversal last id,0,log_iso.id terakhir yang diproses
import sys
import transaction
from opensipkd.string import (
FixLength,
DateTimeVar,
)
from opensipkd.waktu import (
dmyhms,
create_datetime,
)
from sismiop.models.default import PembayaranSppt
from sismiop.services.base import get_db_session
from opensipkd.iso8583.bjb.pbb import Doc
from opensipkd.iso8583.bjb.pbb.structure import (
INVOICE_ID,
INVOICE_PROFILE,
)
from ..models import Pbb
from .common import (
get_iso,
get_keys,
App as BaseApp,
)
def get_inv_id(iso):
inv_id = FixLength(INVOICE_ID)
inv_id.set_raw(iso.get_invoice_id())
return inv_id
def get_profile(iso):
p = FixLength(INVOICE_PROFILE)
p.set_raw(iso.get_invoice_profile())
return p
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']))
class App(BaseApp):
iso_class = Doc
report_orm = Pbb
def __init__(self, argv):
super().__init__(argv)
if not self.pid:
return
d = self.module.Doc()
self.iso_inquiry_orm = d.iso_inquiry_model
self.iso_payment_orm = d.iso_payment_model
self.iso_reversal_orm = d.iso_reversal_model
self.base_q_iso = self.prod_session.query(
self.iso_payment_orm, self.iso_inquiry_orm).filter(
self.iso_payment_orm.inquiry_id == self.iso_inquiry_orm.id)
self.base_q_psppt = self.prod_session.query(PembayaranSppt)
def get_db_session(self): # Override
return get_db_session()
def get_psppt(self, p):
q = self.base_q_psppt.filter_by(
kd_propinsi=p['Propinsi'],
kd_dati2=p['Kabupaten'],
kd_kecamatan=p['Kecamatan'],
kd_kelurahan=p['Kelurahan'],
kd_blok=p['Blok'],
no_urut=p['Urut'],
kd_jns_op=p['Jenis'],
thn_pajak_sppt=p['Tahun']).order_by(
PembayaranSppt.pembayaran_sppt_ke.desc())
return q.first()
def __run_payment(self):
last = self.get_last_id('pbb payment last id')
q_iso = self.base_q_iso.filter(self.iso_inquiry_orm.id > last.as_int())
q_iso = q_iso.order_by(self.iso_inquiry_orm.id)
found = False
for row_pay, row_inq in q_iso.limit(1000):
iso = get_iso(row_pay.iso_request, Doc, self.option.debug)
if self.get_report(iso):
continue
d = get_keys(iso)
tgl_bayar = get_tgl_bayar(iso, row_inq.tgl.year)
s_tgl = dmyhms(tgl_bayar)
self.log.info(
f'Tgl bayar {s_tgl}, Nomor bayar {d["nomor_bayar"]}, '
f'STAN {d["stan"]}, NTB {d["ntb"]}, Channel {d["channel"]}')
inv_id = get_inv_id(iso)
p = get_profile(iso)
psppt = self.get_psppt(p)
rpt = Pbb(
stan=d['stan'], ntb=d['ntb'], kd_propinsi=p['Propinsi'],
kd_dati2=p['Kabupaten'], kd_kecamatan=p['Kecamatan'],
kd_kelurahan=p['Kelurahan'], kd_blok=p['Blok'],
no_urut=p['Urut'], kd_jns_op=p['Jenis'],
thn_pajak_sppt=p['Tahun'],
pembayaran_sppt_ke=psppt.pembayaran_sppt_ke,
jml_sppt_yg_dibayar=iso.get_amount(),
tgl_pembayaran_sppt=tgl_bayar.date(),
tgl_rekam_byr_sppt=tgl_bayar,
nm_wp_sppt=p['Nama'],
channel_kode=iso.get_channel().strip(),
channel_nama=d['channel'],
user_id=iso.getBit(107))
last.nilai = str(row_inq.id)
print(f'last.nilai {last.nilai}')
with transaction.manager:
self.rpt_session.add(rpt)
self.rpt_session.add(last)
found = True
return found
def run_payment(self): # Override
while True:
found = self.__run_payment()
if not found:
break
def run_reversal(self): # Override
super().run_reversal('pbb reversal last date')
def main(argv=sys.argv[1:]):
app = App(argv)
app.run()
...@@ -34,9 +34,10 @@ setup( ...@@ -34,9 +34,10 @@ setup(
zip_safe=False, zip_safe=False,
entry_points={ entry_points={
'console_scripts': [ 'console_scripts': [
'bphtb_report_init_db = payment_report.scripts.bphtb:init_db', 'payment_report_init_db = payment_report.scripts.common:init_db',
'pad_report_init_db = payment_report.scripts.pad:init_db', 'pbb_report = payment_report.scripts.pbb:main',
'bphtb_report = payment_report.scripts.bphtb:main', 'bphtb_report = payment_report.scripts.bphtb:main',
'bphtb2_report = payment_report.scripts.bphtb2:main',
'pad_report = payment_report.scripts.pad:main', 'pad_report = payment_report.scripts.pad:main',
], ],
} }
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!