Commit 1b5b288c by Owo Sugiana

Tambah channel VA dan QRIS

1 parent 38f5b1c2
2.0 2022-05-18 2.0 2022-07-17
-------------- --------------
- Perbedaan utama dari versi 0.x adalah kini berangkat dari tabel aslinya dan - Perbedaan utama dari versi 0.x adalah kini berangkat dari tabel aslinya dan
bukan dari tabel ISO8583 karena sudah memperhatikan channel MANUAL (input bukan dari tabel ISO8583 karena sudah memperhatikan channel MANUAL (input
manual pembayaran) manual pembayaran)
- Memahami channel VA dan QRIS
[main] [main]
models = opensipkd.bphtb.models.default models = opensipkd.bphtb.models.default
db_url = postgresql://user:pass@localhost/db db_url = postgresql://user:pass@localhost/db
#va_db_url = postgresql://user:pass@localhost/db
report_db_url = postgresql://user:pass@localhost/db report_db_url = postgresql://user:pass@localhost/db
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
[main] [main]
models = opensipkd.pad.models.default models = opensipkd.pad.models.default
db_url = postgresql://user:pass@localhost/db db_url = postgresql://user:pass@localhost/db
#va_db_url = postgresql://user:pass@localhost/db
report_db_url = postgresql://user:pass@localhost/db report_db_url = postgresql://user:pass@localhost/db
pid_file = /home/sugiana/tmp/pad-report.pid pid_file = /home/sugiana/tmp/pad-report.pid
log_file = /home/sugiana/log/pad-report.log log_file = /home/sugiana/log/pad-report.log
...@@ -16,6 +16,12 @@ Base = declarative_base() ...@@ -16,6 +16,12 @@ Base = declarative_base()
class Common: class Common:
def to_dict(self):
values = {}
for column in self.__table__.columns:
values[column.name] = getattr(self, column.name)
return values
def from_dict(self, values): def from_dict(self, values):
for column in self.__table__.columns: for column in self.__table__.columns:
if column.name in values: if column.name in values:
...@@ -24,25 +30,24 @@ class Common: ...@@ -24,25 +30,24 @@ class Common:
class Pad(Base, Common): class Pad(Base, Common):
__tablename__ = 'pad_report' __tablename__ = 'pad_report'
# pad.pad_sspd.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))
# pad.pad_sspd.create_date / log_iso.created # pad.pad_sspd.create_date / log_iso.created
tgl = Column(Date, nullable=False) tgl = Column(Date, nullable=False)
# pad.pad_sspd.sspdjam / log_iso.created # pad.pad_sspd.sspdjam / log_iso.created
jam = Column(Time, nullable=False) jam = Column(Time, nullable=False)
# pad.pad_sspd.id
sspd_id = Column(Integer, nullable=False)
# Bit 61 # Bit 61
nomor_bayar = Column(String(16), nullable=False) nomor_bayar = Column(String(16), nullable=False)
# pad.pad_usaha.usahanm # pad.pad_usaha.usahanm
jenis_pajak = Column(String(32), nullable=False) jenis_pajak = Column(String(64), nullable=False)
# pad.pad_pajak.masapajak # pad.pad_pajak.masapajak
masa_pajak = Column(Integer, nullable=False) masa_pajak = Column(Integer, nullable=False)
# pad.pad_customer.npwpd # pad.pad_customer.npwpd
npwpd = Column(String(17), nullable=False) npwpd = Column(String(17))
# pad.pad_customer.customernm # pad.pad_customer.customernm
nama_wp = Column(String(150), nullable=False) nama_wp = Column(String(150), nullable=False)
# pad.pad_sspd.jml_bayar - pad.pad_sspd.denda # pad.pad_sspd.jml_bayar - pad.pad_sspd.denda
...@@ -59,9 +64,6 @@ class Pad(Base, Common): ...@@ -59,9 +64,6 @@ class Pad(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 Webr(Base, Common): class Webr(Base, Common):
...@@ -90,17 +92,17 @@ class Webr(Base, Common): ...@@ -90,17 +92,17 @@ class Webr(Base, Common):
channel_id = Column(String(4), nullable=False) channel_id = Column(String(4), nullable=False)
# Bit 41 / 42 / 43 # Bit 41 / 42 / 43
channel_name = Column(String(32), nullable=False) channel_name = Column(String(32), nullable=False)
# pad_reversal.tgl
tgl_batal = Column(DateTime(timezone=True)) tgl_batal = Column(DateTime(timezone=True))
class Bphtb(Base, Common): class Bphtb(Base, Common):
__tablename__ = 'bphtb_report' __tablename__ = 'bphtb_report'
# bphtb.bphtb_bank.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 58 # Bit 58
ntb = Column(String(32), nullable=False) ntb = Column(String(32))
# bphtb.bphtb_bank.tanggal # bphtb.bphtb_bank.tanggal
tgl = Column(Date, nullable=False) tgl = Column(Date, nullable=False)
# bphtb.bphtb_bank.jam # bphtb.bphtb_bank.jam
...@@ -133,9 +135,6 @@ class Bphtb(Base, Common): ...@@ -133,9 +135,6 @@ class Bphtb(Base, Common):
channel_nama = Column(String(32), nullable=False) channel_nama = Column(String(32), nullable=False)
# bphtb.bphtb_reversal.tgl # bphtb.bphtb_reversal.tgl
tgl_batal = Column(DateTime(timezone=True)) tgl_batal = Column(DateTime(timezone=True))
__table_args__ = (
UniqueConstraint('stan', 'ntb'),
)
class Pbb(Base, Common): class Pbb(Base, Common):
......
...@@ -6,8 +6,9 @@ from sqlalchemy import ( ...@@ -6,8 +6,9 @@ from sqlalchemy import (
String, String,
Date, Date,
ForeignKey, ForeignKey,
func,
) )
import transaction from opensipkd.string import FixLength
from opensipkd.waktu import dmyhms from opensipkd.waktu import dmyhms
from opensipkd.bphtb.models.default import ( from opensipkd.bphtb.models.default import (
Payment, Payment,
...@@ -15,17 +16,23 @@ from opensipkd.bphtb.models.default import ( ...@@ -15,17 +16,23 @@ from opensipkd.bphtb.models.default import (
Perolehan, Perolehan,
Customer, Customer,
) )
from opensipkd.bphtb.services.default.structure import INVOICE_ID
from iso8583_web.models.meta import Base as BaseConf from iso8583_web.models.meta import Base as BaseConf
from opensipkd.iso8583.bjb.bphtb import Doc 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 ( from ..models import (
Base, Base,
Bphtb, Bphtb,
) )
from .common import ( from .common import (
get_iso, get_iso,
get_keys, get_channel_name_by_row,
App as BaseApp, get_channel_info_by_iso,
BaseApp,
init_db as base_init_db, init_db as base_init_db,
one_day,
InvalidSource,
) )
...@@ -47,70 +54,105 @@ class IsoPayment(Base): ...@@ -47,70 +54,105 @@ class IsoPayment(Base):
bank_ip = Column(String(15), nullable=False) bank_ip = Column(String(15), nullable=False)
class IsoReversal(Base):
__tablename__ = 'bphtb_reversal'
__table_args__ = dict(schema='public')
id = Column(Integer, ForeignKey(IsoPayment.id), primary_key=True)
tgl = Column(DateTime(timezone=True), nullable=False)
iso_request = Column(String(1024), nullable=False)
class App(BaseApp): class App(BaseApp):
iso_class = Doc conf_name = 'bphtb payment last date'
report_orm = Bphtb report_orm = Bphtb
va_product_code = '01'
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_inv = self.prod_session.query( self.base_q_inv = self.prod_session.query(Invoice)
Invoice, Customer, Perolehan).filter( self.base_q_cust = self.prod_session.query(Customer)
Invoice.ppat_id == Customer.id, self.base_q_perolehan = self.prod_session.query(Perolehan)
Invoice.perolehan_id == Perolehan.id)
def get_last_time(self): # Override
def run_payment(self): # Override s_tgl = self.last_pay.tanggal.strftime('%d-%m-%Y')
last = self.get_last_id('bphtb payment last id') s_jam = self.last_pay.jam.strftime('%H:%M:%S')
q_iso = self.prod_session.query(IsoPayment, Payment).filter( return f'{s_tgl} {s_jam}'
IsoPayment.id == Payment.id,
IsoPayment.id > last.as_int()) def get_filter_query(self, q):
for row_iso, row_pay in q_iso.order_by(IsoPayment.id): return q.filter(
if row_iso.iso_request[0] == '{': Payment.tanggal >= self.tgl_awal.date(),
last.nilai = str(row_iso.id) Payment.jam >= self.tgl_awal.time(),
with transaction.manager: Payment.tanggal < self.tgl_akhir + one_day)
self.rpt_session.add(last)
continue def get_count(self) -> int: # Override
iso = get_iso(row_iso.iso_request, Doc, self.option.debug) q = self.prod_session.query(func.count())
if self.get_report(iso): q = self.get_filter_query(q)
continue return q.scalar()
tgl_bayar = row_iso.tgl.date()
q_inv = self.base_q_inv.filter(Invoice.id == row_pay.sspd_id) def get_payment_query(self): # Override
inv, ppat, perolehan = q_inv.first() q = self.prod_session.query(Payment)
d = get_keys(iso) q = self.get_filter_query(q)
s_tgl = dmyhms(row_iso.tgl) return q.order_by(Payment.tanggal, Payment.jam)
self.log.info(
f'Tgl bayar {s_tgl}, Nomor bayar {d["nomor_bayar"]}, ' def get_iso_v1(self, pay):
f'STAN {d["stan"]}, NTB {d["ntb"]}, Channel {d["channel"]}') q = self.prod_session.query(IsoPayment).filter_by(id=pay.id)
rpt = Bphtb( row = q.first()
stan=d['stan'], ntb=d['ntb'], tgl=tgl_bayar, if not row:
jam=row_iso.tgl.time(), return
invoice_id=iso.get_invoice_id().strip(), iso = get_iso(row.iso_request, Doc, self.option.debug)
nop=row_pay.nop, wp_nama=row_pay.wp_nama, info = get_channel_info_by_iso(iso)
wp_alamat=row_pay.wp_alamat, op_alamat=inv.op_alamat, return info['bit_018'], info['channel'], iso.get_stan(), iso.get_ntb()
npop=row_pay.npop, bumi_luas=row_pay.bumi_luas,
bng_luas=row_pay.bng_luas, nilai_bphtb=row_pay.bayar, def get_iso_v2(self):
jenis_perolehan=perolehan.nama, ppat=ppat.nama, q = self.prod_session.query(Log).filter_by(
channel_id=iso.get_channel().strip(), mti='0210', bit_003=PAYMENT_CODE, bit_039='00')
channel_nama=d['channel']) q = q.filter(func.trim(Log.bit_062) == self.invoice_id)
last.nilai = str(row_iso.id) q = q.order_by(Log.id.desc())
with transaction.manager: row = q.first()
self.rpt_session.add(rpt) if not row:
self.rpt_session.add(last) return
channel_id = row.bit_018.strip()
def get_iso_reversal_orm(self): # Override channel_nama = get_channel_name_by_row(row)
return IsoReversal return channel_id, channel_nama, row.bit_011, row.bit_058.strip()
def run_reversal(self): # Override def get_invoice(self, pay):
super().run_reversal('bphtb reversal last date') 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:]): def main(argv=sys.argv[1:]):
......
import sys
from sqlalchemy.exc import ProgrammingError
import transaction
from opensipkd.waktu import (
dmyhms,
date_from_str,
)
from opensipkd.bphtb.models.perolehan import PerolehanMixin
from opensipkd.bphtb.models.default import Perolehan
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 AlternativePerolehan(Base, PerolehanMixin):
__table_args__ = dict(schema='public')
def error(s):
print(s)
sys.exit()
class App(BaseApp):
field_invoice_id = 'bit_062'
field_ntb = 'bit_058'
report_orm = Bphtb
def __init__(self, argv):
super().__init__(argv)
if not self.pid:
return
self.base_q_perolehan = self.prod_session.query(Perolehan)
with transaction.manager:
try:
self.base_q_perolehan.first()
except ProgrammingError:
self.prod_session.rollback()
self.base_q_perolehan = self.prod_session.query(
AlternativePerolehan)
def get_log_orm(self): # Override
return Log
def __create_data(self, row_iso):
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 = eval(row_iso.bit_047_data)
q = self.base_q_perolehan.filter_by(id=p['Jenis Perolehan Hak'])
perolehan = q.first()
return dict(
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'])
def __get_query_iso(self, last_id):
return self.prod_session.query(Log).filter_by(
mti='0210', bit_003=PAYMENT_CODE, bit_039='00').filter(
Log.id > last_id)
def __run_payment(self):
last = self.get_last_id('bphtb2 payment last id')
q_iso = self.__get_query_iso(last.as_int())
found = False
for row_iso in q_iso.order_by(Log.id).limit(1000):
if self.get_report(row_iso):
last.nilai = str(row_iso.id)
with transaction.manager:
self.rpt_session.add(last)
continue
data = self.__create_data(row_iso)
rpt = Bphtb(**data)
last.nilai = str(row_iso.id)
with transaction.manager:
self.rpt_session.add(rpt)
self.rpt_session.add(last)
found = True
return found
def __update_from_id(self):
q_iso = self.__get_query_iso(self.last_id)
found = False
for row_iso in q_iso.order_by(Log.id).limit(1000):
rpt = self.get_report(row_iso)
if not rpt:
rpt = Bphtb()
data = self.__create_data(row_iso)
rpt.from_dict(data)
with transaction.manager:
self.rpt_session.add(rpt)
self.last_id = row_iso.id
found = True
return found
def run_payment(self): # Override
if self.option.update_from_id:
self.last_id = self.option.update_from_id
func = self.__update_from_id
elif self.option.update_from_date:
tgl = date_from_str(self.option.update_from_date)
q = self.prod_session.query(Log).filter(Log.created >= tgl)
q = q.order_by(Log.id)
row = q.first()
if not row:
error('Kosong')
self.last_id = row.id - 1
func = self.__update_from_id
else:
func = self.__run_payment
while True:
found = func()
if not found:
break
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)
nama,nilai,keterangan nama,nilai,keterangan
pad payment last id,0,pad_payment.id terakhir yang diproses pad payment last date,1-1-2000 00:00:00,pad.pad_sspd.sspdtgl 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
pad json payment last id,0,pad_payment.id terakhir yang diproses 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 webr payment last date,1-1-2000 00:00:00,webr.ar_payment.created terakhir yang diproses
pad2 reversal last id,0,log_iso.id terakhir yang diproses bphtb payment last date,01-01-2000 00:00:00,bphtb.bphtb_bank.tanggal 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 reversal last id,0,log_iso.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 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
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 date,1-1-2000,pembayaran_sppt.tgl_rekam_byr_sppt 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
pbb2 payment last id,0,log_iso.id terakhir yang diproses
pbb2 reversal last id,0,log_iso.id terakhir yang diproses
va pbb last id,0,pembayaran_sppt.id terakhir yang diproses
import sys import sys
from datetime import timedelta from datetime import (
import transaction date,
from opensipkd.waktu import ( datetime,
dmyhms,
date_from_str,
) )
from sqlalchemy import func
from opensipkd.string import FixLength
from opensipkd.waktu import dmyhms
from opensipkd.pad.models.default import ( from opensipkd.pad.models.default import (
Payment,
IsoPayment, IsoPayment,
IsoReversal,
) )
from iso8583_web.models.meta import Base as BaseConf from iso8583_web.models.meta import Base as BaseConf
from opensipkd.iso8583.bjb.pad.structure import PAYMENT_CODE
from opensipkd.iso8583.bjb.pad.doc import Doc as BjbDoc from opensipkd.iso8583.bjb.pad.doc import Doc as BjbDoc
from opensipkd.iso8583.bjb.pad.models import Log
from opensipkd.iso8583.multi.doc import Doc as MultiDoc from opensipkd.iso8583.multi.doc import Doc as MultiDoc
from ..models import ( from ..models import (
Base, Base,
...@@ -18,22 +21,25 @@ from ..models import ( ...@@ -18,22 +21,25 @@ from ..models import (
) )
from .common import ( from .common import (
get_iso, get_iso,
get_keys, get_channel_info_by_iso,
App as BaseApp, get_channel_name_by_row,
BaseApp,
init_db as base_init_db, init_db as base_init_db,
one_day,
) )
BankHandlers = { BankHandlers = {
8: MultiDoc, 8: MultiDoc,
14: MultiDoc, 14: MultiDoc,
110: BjbDoc, 110: BjbDoc,
700: MultiDoc} 700: MultiDoc}
ERR_NOT_FOUND = 'Tgl {tgl_bayar} pad.pad_sspd.spt_id {invoice_id} tidak ada'
class App(BaseApp): class App(BaseApp):
conf_name = 'pad payment last date'
report_orm = Pad report_orm = Pad
va_product_code = '10'
def __init__(self, argv): def __init__(self, argv):
super().__init__(argv) super().__init__(argv)
...@@ -53,132 +59,83 @@ class App(BaseApp): ...@@ -53,132 +59,83 @@ class App(BaseApp):
Invoice.customer_usaha_id == CustomerUsaha.id, Invoice.customer_usaha_id == CustomerUsaha.id,
CustomerUsaha.customer_id == Customer.id, CustomerUsaha.customer_id == Customer.id,
Usaha.id == Pajak.usaha_id,) Usaha.id == Pajak.usaha_id,)
self.base_q_iso = self.prod_session.query(IsoPayment) self.base_q_log = self.prod_session.query(Log).filter_by(
mti='0210', bit_003=PAYMENT_CODE, bit_039='00')
def get_pay(self, row): def get_pay_date(self): # Override
tgl_bayar = row.tgl.date() return self.last_pay.sspdtgl.date()
Payment = self.models.Payment
q_pay = self.base_q_pay.filter_by(spt_id=row.invoice_id).filter(
Payment.create_date >= tgl_bayar,
Payment.create_date < tgl_bayar + timedelta(1))
q_pay = q_pay.order_by(Payment.id.desc())
return q_pay.first()
def __get_query_iso(self, last_id): def get_last_time(self): # Override
q_iso = self.base_q_iso.filter(IsoPayment.id > last_id) return dmyhms(self.last_pay.sspdtgl)
return q_iso.order_by(IsoPayment.id)
def __create_data(self, row, pay, iso, d, tgl_bayar): def get_filter_query(self, q):
Invoice = self.models.Invoice return q.filter(
q_inv = self.base_q_inv.filter(Invoice.id == pay.spt_id) Payment.sspdtgl >= self.tgl_awal,
inv, pajak, cust, usaha = q_inv.first() Payment.sspdtgl < self.tgl_akhir + one_day)
return dict(
stan=d['stan'], ntb=d['ntb'], tgl=tgl_bayar, def get_count(self): # Override
jam=row.tgl.time(), sspd_id=pay.id, q = self.prod_session.query(func.count())
nomor_bayar=iso.get_invoice_id().strip(), q = self.get_filter_query(q)
jenis_pajak=usaha.usahanm.strip(), return q.scalar()
masa_pajak=pajak.masapajak, npwpd=cust.npwpd,
nama_wp=cust.customernm, pokok=pay.jml_bayar-pay.denda, def get_payment_query(self): # Override
denda=pay.denda, jml_bayar=pay.jml_bayar, q = self.prod_session.query(Payment)
channel_id=iso.get_channel().strip(), q = self.get_filter_query(q)
channel_name=d['channel'], bank_id=iso.get_bank_id()) return q.order_by(Payment.sspdtgl)
def __log_progress(self, s_tgl, d): def get_iso_v1(self, pay):
self.log.info(f'Tgl bayar {s_tgl}, {d}') q = self.prod_session.query(IsoPayment).filter_by(id=pay.id)
row = q.first()
def __run_payment(self): if not row:
last = self.get_last_id('pad payment last id') return
q_iso = self.__get_query_iso(last.as_int())
found = False
for row in q_iso.order_by(IsoPayment.id).limit(1000):
if row.iso_request[0] == '{':
last.nilai = str(row.id)
with transaction.manager:
self.rpt_session.add(last)
continue
Doc = BankHandlers[row.bank_id]
iso = get_iso(row.iso_request, Doc, self.option.debug)
if self.get_report(iso):
continue
pay = self.get_pay(row)
tgl_bayar = row.tgl.date()
if not pay:
msg = ERR_NOT_FOUND.format(
tgl_bayar=tgl_bayar, invoice_id=row.invoice_id)
self.log.error(msg)
continue
d = get_keys(iso)
s_tgl = dmyhms(row.tgl)
data = self.__create_data(row, pay, iso, d, tgl_bayar)
self.__log_progress(s_tgl, data)
rpt = Pad(**data)
last.nilai = str(row.id)
with transaction.manager:
self.rpt_session.add(rpt)
self.rpt_session.add(last)
found = True
return found
def __update_from_id(self):
q_iso = self.__get_query_iso(self.last_id)
found = False
for row in q_iso.order_by(IsoPayment.id).limit(1000):
if row.iso_request[0] == '{':
last.nilai = str(row.id)
with transaction.manager:
self.rpt_session.add(last)
Doc = BankHandlers[row.bank_id] Doc = BankHandlers[row.bank_id]
iso = get_iso(row.iso_request, Doc, self.option.debug) iso = get_iso(row.iso_request, Doc, self.option.debug)
tgl_bayar = row.tgl.date() info = get_channel_info_by_iso(iso)
pay = self.get_pay(row) return info.get('bit_018', '0000'), info['channel'], iso.get_stan(), \
rpt = self.get_report(iso) iso.get_ntb(), row.bank_id
if not rpt:
if not pay: def get_iso_v2(self):
msg = ERR_NOT_FOUND.format( q = self.base_q_log.filter(func.trim(Log.bit_061) == self.invoice_id)
tgl_bayar=tgl_bayar, invoice_id=row.invoice_id) q = q.order_by(Log.id.desc())
self.log.error(msg)
continue
rpt = Pad()
d = get_keys(iso)
s_tgl = dmyhms(row.tgl)
data = self.__create_data(row, pay, iso, d, tgl_bayar)
self.__log_progress(s_tgl, data)
rpt.from_dict(data)
with transaction.manager:
self.rpt_session.add(rpt)
found = True
self.last_id = row.id
return found
def run_payment(self): # Override
if self.option.update_from_id:
self.last_id = self.option.update_from_id
func = self.__update_from_id
elif self.option.update_from_date:
tgl = date_from_str(self.option.update_from_date)
q = self.prod_session.query(IsoPayment).filter(
IsoPayment.tgl >= tgl).order_by(
IsoPayment.id)
row = q.first() row = q.first()
self.last_id = row.id - 1 if not row:
func = self.__update_from_id 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_048.strip(), int(row.bit_032)
def create_data(self, pay): # Override
Invoice = self.models.Invoice
q_inv = self.base_q_inv.filter(Invoice.id == pay.spt_id)
inv, pajak, cust, usaha = q_inv.first()
invoice_id = FixLength(self.service.INVOICE_ID)
invoice_id['Tahun'] = inv.tahun
invoice_id['SptNo'] = inv.sptno
prefix = getattr(self.service, 'PREFIX')
if prefix:
invoice_id['Prefix'] = prefix
self.invoice_id = invoice_id.get_raw()
source = self.get_iso_v2()
if source:
channel_id, channel_name, stan, ntb, bank_id = source
else: else:
func = self.__run_payment source = self.get_iso_v1(pay)
while True: if source:
found = func() channel_id, channel_name, stan, ntb, bank_id = source
if not found: else:
break stan = ntb = bank_id = None
channel_id = '0000'
def get_iso_reversal_orm(self): # Override tgl = pay.sspdtgl.date()
return IsoReversal channel_name = self.get_va_channel(tgl) or 'MANUAL'
return dict(
def get_doc_for_reversal(self, row): # Override id=pay.id, stan=stan, ntb=ntb, tgl=pay.sspdtgl.date(),
q = self.prod_session.query(IsoPayment).filter_by(id=row.id) jam=pay.sspdtgl.time(), nomor_bayar=invoice_id.get_raw(),
iso_pay = q.first() jenis_pajak=usaha.usahanm.strip(), masa_pajak=pajak.masapajak,
return BankHandlers[iso_pay.bank_id] npwpd=cust.npwpd, nama_wp=cust.customernm,
pokok=pay.jml_bayar-pay.denda, denda=pay.denda,
def run_reversal(self): # Override jml_bayar=pay.jml_bayar, channel_id=channel_id,
super().run_reversal('pad reversal last date') channel_name=channel_name, bank_id=bank_id)
def main(argv=sys.argv[1:]): def main(argv=sys.argv[1:]):
......
import sys
import transaction
from opensipkd.waktu import dmyhms
from opensipkd.pad.models.default import (
Payment,
Invoice,
Pajak,
CustomerUsaha,
Customer,
Usaha,
)
from opensipkd.iso8583.bjb.pad.structure import PAYMENT_CODE
from opensipkd.iso8583.bjb.pad.models import (
Log,
PadLog,
)
from iso8583_web.models.meta import Base as BaseConf
from ..models import (
Base,
Pad,
)
from .common import (
App2 as BaseApp,
init_db as base_init_db,
)
ERR_NOT_FOUND = 'Tgl {tgl_bayar} nomor bayar {invoice_id} tidak ada'
class App(BaseApp):
field_invoice_id = 'bit_061'
field_ntb = 'bit_048'
report_orm = Pad
log_orm = Log
def __init__(self, argv):
super().__init__(argv)
if not self.pid:
return
self.base_q_iso_resp = self.prod_session.query(Log).filter_by(
mti='0210', bit_003=PAYMENT_CODE)
self.base_q_pay = self.prod_session.query(Payment).filter(
PadLog.sspd_id == Payment.id)
self.base_q_inv = self.prod_session.query(
Invoice, Pajak, Customer, Usaha)
self.base_q_inv = self.base_q_inv.filter(
Invoice.pajak_id == Pajak.id,
Invoice.customer_usaha_id == CustomerUsaha.id,
CustomerUsaha.customer_id == Customer.id,
Usaha.id == Pajak.usaha_id,)
def get_pay(self, iso_req):
q_pay = self.base_q_pay.filter(PadLog.id == iso_req.id)
return q_pay.first()
def is_iso_resp_ok(self, iso_req):
q = self.base_q_iso_resp.filter_by(
bit_011=iso_req.bit_011, bit_048=iso_req.bit_048)
iso_resp = q.order_by(Log.id.desc()).first()
return iso_resp and iso_resp.bit_039 == '00'
def run_payment(self):
last = self.get_last_id('pad2 payment last id')
q_iso_req = self.prod_session.query(Log).filter_by(
mti='0200', bit_003=PAYMENT_CODE).filter(
Log.id > last.as_int())
for iso_req in q_iso_req.order_by(Log.id):
if self.get_report(iso_req):
continue
if not self.is_iso_resp_ok(iso_req):
continue
d = self.get_keys(iso_req)
tgl_bayar = iso_req.created.date()
pay = self.get_pay(iso_req)
if not pay:
msg = ERR_NOT_FOUND.format(
tgl_bayar=tgl_bayar, invoice_id=d['nomor_bayar'])
self.log.error(msg)
continue
s_tgl = dmyhms(iso_req.created)
q_inv = self.base_q_inv.filter(Invoice.id == pay.spt_id)
inv, pajak, cust, usaha = q_inv.first()
self.log.info(
f'Tgl bayar {s_tgl}, Nomor bayar {d["nomor_bayar"]}, '
f'Jenis Pajak {usaha.usahanm.strip()},'
f'STAN {d["stan"]}, NTB {d["ntb"]}, Channel {d["channel"]}')
rpt = Pad(
stan=d['stan'], ntb=d['ntb'], tgl=tgl_bayar,
jam=iso_req.created.time(), sspd_id=pay.id,
nomor_bayar=d['nomor_bayar'],
jenis_pajak=usaha.usahanm.strip(),
masa_pajak=pajak.masapajak, npwpd=cust.npwpd,
nama_wp=cust.customernm, pokok=pay.jml_bayar-pay.denda,
denda=pay.denda, jml_bayar=pay.jml_bayar,
channel_id=iso_req.bit_018.strip(),
channel_name=d['channel'])
last.nilai = str(iso_req.id)
with transaction.manager:
self.rpt_session.add(rpt)
self.rpt_session.add(last)
def run_reversal(self): # Override
super().run_reversal('pad2 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)
from datetime import ( from datetime import (
datetime, datetime,
date, date,
time as mktime, time,
) )
from decimal import Decimal
################# #################
# Compare value # # Compare value #
################# #################
MIDNIGHT_TIME = mktime(0, 0, 0) MIDNIGHT_TIME = time(0, 0, 0)
def split_time(t): def split_time(t) -> tuple:
if isinstance(t, datetime): if isinstance(t, datetime):
return t.date(), t.time() return t.date(), t.time()
return t, MIDNIGHT_TIME return t, MIDNIGHT_TIME
def is_same(a, b): def is_same(a, b) -> bool:
if a == b: if a == b:
return True return True
if not (isinstance(a, date) or isinstance(a, datetime)): if not (isinstance(a, date) or isinstance(a, datetime)):
...@@ -31,3 +32,59 @@ def is_same(a, b): ...@@ -31,3 +32,59 @@ def is_same(a, b):
if time_a == time_b: if time_a == time_b:
return True return True
return False return False
################
# Plain Object #
################
def date_str(v):
return f'{v.year}-{v.month:02}-{v.day:02}'
def time_str(v):
return f'{v.hour:02}:{v.minute:02}:{v.second:02}'
def datetime_str(v):
s_date = date_str(v)
s_time = time_str(v)
return f'{s_date} {s_time}'
def plain_value(v):
if isinstance(v, str):
return v
if isinstance(v, datetime):
return datetime_str(v)
if isinstance(v, date):
return date_str(v)
if isinstance(v, Decimal):
return float(v)
if isinstance(v, time):
return time_str(v)
return v
def plain_values(d):
r = dict()
for key in d:
v = d[key]
r[str(key)] = plain_value(v)
return r
def update(source: dict, target: dict):
target_update = dict()
log_msg = []
for field in target:
if field not in source:
continue
source_value = source[field]
target_value = target[field]
if not is_same(source_value, target_value):
target_update[field] = source_value
log_source_value = plain_value(source_value)
log_target_value = plain_value(target_value)
log_msg.append('{f} {t} to be {s}'.format(
f=field, t=[log_target_value], s=[log_source_value]))
return target_update, log_msg
import sys
from sqlalchemy import (
Column,
Integer,
)
import transaction
from opensipkd.waktu import (
dmyhms,
create_datetime,
date_from_str,
)
from sismiop.models.default import PembayaranSppt as BasePsppt
from sismiop.services.base import (
get_id,
)
from opensipkd.iso8583.bjb.scripts.common import get_module_object
from ..models import Pbb
from .common import (
get_iso,
get_keys,
BaseApp,
)
NIP_PENCATAT = '222222222'
CHANNEL_KODE = '7001'
CHANNEL_NAMA = 'VA'
LAST_CONF = 'va pbb last id'
ERR_NOT_FOUND = 'SPPT ID {invoice_id} tidak ada di sppt'
class PembayaranSppt(BasePsppt):
__table_args__ = dict(extend_existing=True)
id = Column(Integer, nullable=False)
user_id = Column(Integer)
def get_tgl_bayar(row):
t = row.tgl_rekam_byr_sppt
return create_datetime(t.year, t.month, t.day, t.hour, t.minute, t.second)
class App(BaseApp):
report_orm = Pbb
def __init__(self, argv):
super().__init__(argv)
if not self.pid:
return
self.models = get_module_object(self.conf['models'])
self.Sppt = self.models.Sppt
self.base_q_psppt = self.prod_session.query(PembayaranSppt).filter_by(
nip_rekam_byr_sppt=NIP_PENCATAT)
self.base_q_sppt = self.prod_session.query(self.Sppt)
def get_sppt(self, psppt):
q = self.base_q_sppt.filter_by(
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)
return q.first()
def __get_query_psppt(self, last_id):
q = self.base_q_psppt.filter(PembayaranSppt.id > last_id)
return q.order_by(PembayaranSppt.id)
def __log_not_found(self, sppt_id):
msg = ERR_NOT_FOUND.format(invoice_id=sppt_id)
self.log.error(msg)
def __log_progress(self, row, sppt_id):
s_tgl = dmyhms(row.tgl_rekam_byr_sppt)
self.log.info(
f'Tgl bayar {s_tgl}, Nomor bayar {sppt_id}, '
f'pembayaran ke {row.pembayaran_sppt_ke}, ID {row.id}, '
f'jml_sppt_yg_dibayar {row.jml_sppt_yg_dibayar}')
def __run_payment(self):
last = self.get_last_id(LAST_CONF)
q_psppt = self.__get_query_psppt(last.as_int())
found = False
for psppt in q_psppt.limit(1000):
stan = psppt.tgl_pembayaran_sppt.strftime('%y%m%d')
ntb = f'{CHANNEL_NAMA}-{psppt.id}'
if self.get_report(stan, ntb):
continue
sppt_id = get_id(psppt)
sppt = self.get_sppt(psppt)
if not sppt:
self.__log_not_found(sppt_id)
continue
tgl_bayar = get_tgl_bayar(psppt)
user_id = str(psppt.user_id)
disc = psppt.discount or 0
self.__log_progress(psppt, sppt_id)
rpt = Pbb(
stan=stan, ntb=ntb, 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,
jml_sppt_yg_dibayar=psppt.jml_sppt_yg_dibayar,
denda_sppt=psppt.denda_sppt,
tgl_pembayaran_sppt=psppt.tgl_pembayaran_sppt,
tgl_rekam_byr_sppt=psppt.tgl_rekam_byr_sppt,
nm_wp_sppt=sppt.nm_wp_sppt, channel_kode=CHANNEL_KODE,
channel_nama=CHANNEL_NAMA, user_id=user_id,
pbb_yg_harus_dibayar_sppt=sppt.pbb_yg_harus_dibayar_sppt,
tgl_inquiry=tgl_bayar, discount=disc)
last.nilai = str(psppt.id)
with transaction.manager:
self.rpt_session.add(rpt)
self.rpt_session.add(last)
found = True
return found
def __update_from_id(self):
q_psppt = self.__get_query_psppt(self.last_id)
found = False
for psppt in q_psppt.limit(1000):
sppt_id = get_id(psppt)
sppt = self.get_sppt(psppt)
if not sppt:
self.__log_not_found(sppt_id)
continue
stan = psppt.tgl_pembayaran_sppt.strftime('%y%m%d')
ntb = f'{CHANNEL_NAMA}-{psppt.id}'
tgl_bayar = get_tgl_bayar(psppt)
user_id = str(psppt.user_id)
disc = psppt.discount or 0
rpt = self.get_report(stan, ntb)
if not rpt:
rpt = Pbb()
self.__log_progress(psppt, sppt_id)
d = dict(
stan=stan, ntb=ntb, 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,
jml_sppt_yg_dibayar=psppt.jml_sppt_yg_dibayar,
denda_sppt=psppt.denda_sppt,
tgl_pembayaran_sppt=psppt.tgl_pembayaran_sppt,
tgl_rekam_byr_sppt=psppt.tgl_rekam_byr_sppt,
nm_wp_sppt=sppt.nm_wp_sppt, channel_kode=CHANNEL_KODE,
channel_nama=CHANNEL_NAMA, user_id=user_id,
pbb_yg_harus_dibayar_sppt=sppt.pbb_yg_harus_dibayar_sppt,
tgl_inquiry=tgl_bayar, discount=disc)
rpt.from_dict(d)
with transaction.manager:
self.rpt_session.add(rpt)
found = True
self.last_id = psppt.id
return found
def run_payment(self): # Override
if self.option.update_from_id:
self.last_id = self.option.update_from_id
func = self.__update_from_id
elif self.option.update_from_date:
tgl = date_from_str(self.option.update_from_date)
q = self.prod_session.query(PembayaranSppt).filter(
PembayaranSppt.tgl_rekam_byr_sppt >= tgl).order_by(
PembayaranSppt.tgl_rekam_byr_sppt)
row = q.first()
self.last_id = row.id - 1
func = self.__update_from_id
else:
func = self.__run_payment
while True:
found = func()
if not found:
break
def main(argv=sys.argv[1:]):
app = App(argv)
app.run()
import sys import sys
from datetime import datetime from datetime import (
date,
datetime,
)
from sqlalchemy import func
from sqlalchemy.exc import ProgrammingError from sqlalchemy.exc import ProgrammingError
import transaction import transaction
from opensipkd.waktu import dmyhms from opensipkd.waktu import dmyhms
...@@ -22,6 +26,7 @@ from .common import ( ...@@ -22,6 +26,7 @@ from .common import (
init_db as base_init_db, init_db as base_init_db,
BIT_18_NAMES, BIT_18_NAMES,
get_channel_name_by_row, get_channel_name_by_row,
one_day,
) )
...@@ -30,12 +35,16 @@ class AlternativeLog(Base, LogMixin): ...@@ -30,12 +35,16 @@ class AlternativeLog(Base, LogMixin):
class App(BaseApp): class App(BaseApp):
conf_name = 'webr payment last date'
report_orm = Webr
product_code = '30'
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_pay = self.prod_session.query(Payment, Invoice).filter( self.base_q_pay = self.prod_session.query(Payment)
Payment.ar_invoice_id == Invoice.id) self.base_q_inv = self.prod_session.query(Invoice)
self.base_q_iso = self.prod_session.query(Log) self.base_q_iso = self.prod_session.query(Log)
try: try:
self.base_q_iso.first() self.base_q_iso.first()
...@@ -47,82 +56,49 @@ class App(BaseApp): ...@@ -47,82 +56,49 @@ class App(BaseApp):
self.base_q_iso = self.base_q_iso.filter_by( self.base_q_iso = self.base_q_iso.filter_by(
mti='0210', bit_003=PAYMENT_CODE, bit_039='00') mti='0210', bit_003=PAYMENT_CODE, bit_039='00')
def get_channel(self, pay, inv): def get_iso(self, inv):
if not pay.bank_id: q = self.base_q_iso.filter(func.trim(self.IsoLog.bit_061) == inv.kode)
return '0000', 'MANUAL', None return q.first()
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 update_last(self, pay):
self.last_id = pay.id
self.last.nilai = str(pay.id)
with transaction.manager:
self.rpt_session.add(self.last)
def update_from_id(self): def create_data(self, pay): # Override
q_pay = self.base_q_pay.filter(Payment.id > self.last_id) q = self.base_q_inv.filter_by(id=pay.ar_invoice_id)
no = 0 inv = q.first()
for pay, inv in q_pay.order_by(Payment.id).limit(1000): self.invoice_id = inv.kode
no += 1 iso = self.get_iso(pay)
channel_id, channel_name, iso = self.get_channel(pay, inv) if iso:
nomor_bayar = inv.kode channel_id = iso.bit_018.strip()
tgl_bayar = pay.created.date() channel_name = get_channel_name_by_row(iso)
s_tgl = dmyhms(pay.created) elif pay.bank_id:
channel_id = str(pay.channel_id)
channel_name = BIT_18_NAMES[channel_id]
else:
channel_id = '0000'
channel_name = self.get_va_channel(pay.created.date()) or 'MANUAL'
stan = iso and iso.bit_011 or None stan = iso and iso.bit_011 or None
ntb = pay.ntb and pay.ntb.strip() or None ntb = pay.ntb and pay.ntb.strip() or None
msg = f'#{no} ID {pay.id}, Tgl bayar {s_tgl}, '\ return dict(
f'Nomor bayar {nomor_bayar}, Channel {channel_name}' id=pay.id, stan=stan, ntb=ntb, tgl=pay.created.date(),
if iso: jam=pay.created.time(), nomor_bayar=self.invoice_id,
msg = f'{msg}, STAN {stan}, NTB {ntb}' nama_wp=inv.subjek_nama, pokok=inv.jumlah-inv.bunga,
if not pay.bayar: denda=pay.bunga, jml_bayar=pay.bayar, channel_id=channel_id,
self.log.warning(f'{msg}, field bayar 0, abaikan')
self.last and self.update_last(pay)
continue
self.log.info(msg)
d = dict(
stan=stan, ntb=ntb, tgl=tgl_bayar, jam=pay.created.time(),
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_name) channel_name=channel_name)
q = self.rpt_session.query(Webr).filter_by(id=pay.id)
rpt = q.first()
if rpt:
rpt.from_dict(d)
else:
d['id'] = pay.id
rpt = Webr(**d)
self.last_id = pay.id
with transaction.manager:
self.rpt_session.add(rpt)
if self.last:
self.last.nilai = str(pay.id)
self.rpt_session.add(last)
return no
def run_payment(self): # Override def get_last_time(self): # Override
self.last = None return dmyhms(self.last_pay.created)
if self.option.update_from_id:
self.last_id = self.option.update_from_id def get_filter_query(self, q):
elif self.option.update_from_date: return q.filter(
tgl = datetime.strptime(self.option.update_from_date, '%d-%m-%Y') Payment.created >= self.tgl_awal,
q = self.prod_session.query(Payment).filter( Payment.created < self.tgl_akhir + one_day)
Payment.created >= tgl).order_by(Payment.id)
row = q.first() def get_count(self): # Override
self.last_id = row.id - 1 q = self.prod_session.query(func.count())
else: q = self.get_filter_query(q)
self.last = self.get_last_id('webr payment last id') return q.scalar()
self.last_id = self.last.as_int()
while True: def get_payment_query(self): # Override
found = self.update_from_id() q = self.get_filter_query(self.base_q_pay)
if not found: return q.order_by(Payment.created)
break
def main(argv=sys.argv[1:]): def main(argv=sys.argv[1:]):
......
import sys
from sqlalchemy.exc import ProgrammingError
import transaction
from opensipkd.waktu import dmyhms
from opensipkd.iso8583.bjb.webr.structure import PAYMENT_CODE
from opensipkd.iso8583.bjb.webr.models import (
LogMixin,
Log,
)
from iso8583_web.models.meta import Base as BaseConf
from ..models import (
Base,
Webr,
)
from .common import (
App2 as BaseApp,
init_db as base_init_db,
)
ERR_NOT_FOUND = 'Tgl {tgl_bayar} nomor bayar {invoice_id} tidak ada'
class AlternativeLog(Base, LogMixin):
__table_args__ = dict(schema='webr')
class App(BaseApp):
field_invoice_id = 'bit_061'
field_ntb = 'bit_048'
report_orm = Webr
def __init__(self, argv):
super().__init__(argv)
if not self.pid:
return
self.base_q_iso_resp = self.prod_session.query(Log)
self.log_orm = Log
try:
self.base_q_iso_resp.first()
except ProgrammingError:
self.prod_session.rollback()
self.base_q_iso_resp = self.prod_session.query(AlternativeLog)
self.log_orm = AlternativeLog
self.base_q_iso_resp = self.base_q_iso_resp.filter_by(
mti='0210', bit_003=PAYMENT_CODE)
def is_iso_resp_ok(self, iso_req):
q = self.base_q_iso_resp.filter_by(
bit_011=iso_req.bit_011, bit_048=iso_req.bit_048)
iso_resp = q.order_by(Log.id.desc()).first()
return iso_resp and iso_resp.bit_039 == '00'
def run_payment(self):
last = self.get_last_id('webr2 payment last id')
q_iso_req = self.prod_session.query(Log).filter_by(
mti='0210', bit_003=PAYMENT_CODE).filter(
Log.id > last.as_int())
for iso_req in q_iso_req.order_by(Log.id):
if self.get_report(iso_req):
continue
if not self.is_iso_resp_ok(iso_req):
continue
d = self.get_keys(iso_req)
tgl_bayar = iso_req.created.date()
s_tgl = dmyhms(iso_req.created)
self.log.info(
f'Tgl bayar {s_tgl}, Nomor bayar {d["nomor_bayar"]}, '
f'STAN {d["stan"]}, NTB {d["ntb"]}, Channel {d["channel"]}')
rpt = Webr(
stan=d['stan'], ntb=d['ntb'], tgl=tgl_bayar,
jam=iso_req.created.time(), payment_id=iso_req.id,
nomor_bayar=d['nomor_bayar'],
nama_wp=iso_req.bit_062_data['Nama Penyetor'],
pokok=iso_req.bit_004,
denda=0, jml_bayar=iso_req.bit_004,
channel_id=iso_req.bit_018.strip(),
channel_name=d['channel'])
last.nilai = str(iso_req.id)
with transaction.manager:
self.rpt_session.add(rpt)
self.rpt_session.add(last)
def get_log_orm(self): # Override
return self.log_orm
def run_reversal(self): # Override
super().run_reversal('webr2 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)
[main] [main]
models = sismiop.models.default models = sismiop.models.default
db_url = postgresql://user:pass@localhost/db db_url = postgresql://user:pass@localhost/db
#h2h_db_url = postgresql://user:pass@localhost/db
#va_db_url = postgresql://user:pass@localhost/db
report_db_url = postgresql://user:pass@localhost/db report_db_url = postgresql://user:pass@localhost/db
pid_file = /home/sugiana/tmp/pbb-report.pid pid_file = /home/sugiana/tmp/pbb-report.pid
log_file = /home/sugiana/log/pbb-report.log log_file = /home/sugiana/log/pbb-report.log
......
...@@ -37,15 +37,11 @@ setup( ...@@ -37,15 +37,11 @@ setup(
'payment_report_init_db = payment_report.scripts.common:init_db', 'payment_report_init_db = payment_report.scripts.common:init_db',
'pbb_report = payment_report.scripts.pbb:main', 'pbb_report = payment_report.scripts.pbb:main',
'pbb_json_report = payment_report.scripts.pbb_json:main', 'pbb_json_report = payment_report.scripts.pbb_json:main',
'va_pbb_report = payment_report.scripts.va_pbb:main',
'bphtb_report = payment_report.scripts.bphtb:main', 'bphtb_report = payment_report.scripts.bphtb:main',
'bphtb_json_report = payment_report.scripts.bphtb_json:main', 'bphtb_json_report = payment_report.scripts.bphtb_json:main',
'bphtb2_report = payment_report.scripts.bphtb2:main',
'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',
'webr_report = payment_report.scripts.webr:main', 'webr_report = payment_report.scripts.webr:main',
'webr2_report = payment_report.scripts.webr2:main',
], ],
} }
) )
[main] [main]
db_url = postgresql://user:pass@localhost/db db_url = postgresql://user:pass@localhost/db
#va_db_url = postgresql://user:pass@localhost/db
report_db_url = postgresql://user:pass@localhost/db report_db_url = postgresql://user:pass@localhost/db
pid_file = /home/sugiana/tmp/webr-report.pid pid_file = /home/sugiana/tmp/webr-report.pid
log_file = /home/sugiana/log/webr-report.log log_file = /home/sugiana/log/webr-report.log
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!