Commit 9260c86c by Owo Sugiana

Tambah tangerang_kabupaten

1 parent 76a4efa9
dist dist
build
*egg-info *egg-info
test-* test-*
0.2 2020-05-09
--------------
- Konfigurasi kini memuat nama modul
- Tambah modul tangerang_kabupaten
0.1.3 2020-01-14 0.1.3 2020-01-14
---------------- ----------------
- get_last_payment() memperhatikan status pembayaran. - get_last_payment() memperhatikan status pembayaran.
......
Struktur Tabel BPHTB Struktur Tabel BPHTB
==================== ====================
BPHTB adalah Bea Peralihan Hak atas Tanah dan Bangunan. BPHTB adalah Bea Perolehan Hak atas Tanah dan Bangunan.
Paket ini selain berisi struktur tabel juga memuat query yang kerap digunakan Paket ini selain berisi struktur tabel juga memuat query yang kerap digunakan
untuk proses: untuk proses:
1. inquiry (cek tagihan) 1. Inquiry (cek tagihan)
2. payment (pembayaran) 2. Payment (pembayaran)
3. reversal (pembatalan pembayaran) 3. Reversal (pembatalan pembayaran)
Uji Coba Uji Coba
-------- --------
...@@ -16,12 +16,13 @@ Uji Coba ...@@ -16,12 +16,13 @@ Uji Coba
Buat file ``test-cilegon.ini`` seperti contoh berikut ini:: Buat file ``test-cilegon.ini`` seperti contoh berikut ini::
[main] [main]
db_url = postgresql://sugiana:a@localhost/bphtb_cilegon module = cilegon
db_url = postgresql://user:pass@localhost/db
persen_denda = 2 persen_denda = 2
Sesuaikanlah pada ``db_url``. Kemudian dapatkan daftar tagihan:: Sesuaikanlah pada ``db_url``. Kemudian dapatkan daftar tagihan::
$ env/bin/bphtb_cilegon_available_invoice test-cilegon.ini $ ~/env/bin/bphtb_available_invoice test-cilegon.ini
Nanti akan tampil seperti ini:: Nanti akan tampil seperti ini::
...@@ -32,14 +33,14 @@ Nanti akan tampil seperti ini:: ...@@ -32,14 +33,14 @@ Nanti akan tampil seperti ini::
Kolom kedua adalah Invoice ID atau sering disebut sebagai nomor bayar. Nomor Kolom kedua adalah Invoice ID atau sering disebut sebagai nomor bayar. Nomor
ini bekal untuk inquiry atau cek tagihan:: ini bekal untuk inquiry atau cek tagihan::
$ env/bin/bphtb_cilegon_inquiry test-cilegon.ini --invoice-id=10241 $ ~/env/bin/bphtb_inquiry test-cilegon.ini --invoice-id=10241
Untuk melanjutkan pembayaran tambahkan opsi ``--payment``:: Untuk melanjutkan pembayaran tambahkan opsi ``--payment``::
$ env/bin/bphtb_cilegon_inquiry test-cilegon.ini --invoice-id=10241 --payment $ ~/env/bin/bphtb_inquiry test-cilegon.ini --invoice-id=10241 --payment
Sedangkan untuk membatalkannya tambahkan opsi ``--reversal``:: Sedangkan untuk membatalkannya tambahkan opsi ``--reversal``::
$ env/bin/bphtb_cilegon_inquiry test-cilegon.ini --invoice-id=10241 --reversal $ ~/env/bin/bphtb_inquiry test-cilegon.ini --invoice-id=10241 --reversal
Selamat mencoba, semoga berhasil. Selamat mencoba, semoga berhasil.
[main] [main]
module = tangerang_kabupaten
db_url = postgresql://username:password@localhost/database db_url = postgresql://username:password@localhost/database
persen_denda = 2 persen_denda = 2
from datetime import date from datetime import date
from sqlalchemy import func from sqlalchemy import (
from sqlalchemy.orm import sessionmaker func,
from opensipkd.bphtb.cilegon.models import ( or_,
)
from opensipkd.hitung import (
hitung_denda,
round_up,
)
from opensipkd.string.money import thousand
from ..services import AvailableInvoice as BaseAvailableInvoice
from .models import (
Spt, Spt,
DetailSpt, DetailSpt,
Pembayaran, Pembayaran,
...@@ -9,15 +17,23 @@ from opensipkd.bphtb.cilegon.models import ( ...@@ -9,15 +17,23 @@ from opensipkd.bphtb.cilegon.models import (
Notaris, Notaris,
User, User,
) )
from opensipkd.hitung import hitung_denda
DBSession = None # override, please DBSession = None # override, please
def get_db_session():
return DBSession
class Inquiry: class Inquiry:
def __init__(self, invoice_id, persen_denda=2): def __init__(self, invoice_id, persen_denda=2, tgl_bayar=None):
self.invoice_id = invoice_id self.invoice_id = invoice_id
self.persen_denda = persen_denda
if tgl_bayar:
self.tgl_bayar = tgl_bayar
else:
self.tgl_bayar = date.today()
q = DBSession.query(Pembayaran).filter_by( q = DBSession.query(Pembayaran).filter_by(
t_kodebayarbanksppt=invoice_id).order_by( t_kodebayarbanksppt=invoice_id).order_by(
Pembayaran.t_idpembayaranspt) Pembayaran.t_idpembayaranspt)
...@@ -34,22 +50,32 @@ class Inquiry: ...@@ -34,22 +50,32 @@ class Inquiry:
self.pemeriksaan = q.first() self.pemeriksaan = q.first()
self.profile = self.get_profile() self.profile = self.get_profile()
self.notaris = self.get_notaris() self.notaris = self.get_notaris()
self.hitung()
def hitung(self):
self.total_bayar = self.get_payment_amount() self.total_bayar = self.get_payment_amount()
self.total = self.tagihan = self.denda = self.bln_tunggakan = \
self.discount = 0
if self.payment.t_statusbayarspt: if self.payment.t_statusbayarspt:
self.tagihan = self.denda = self.total = 0
return return
self.tagihan = self.invoice.t_totalspt self.tagihan = self.invoice.t_totalspt
self.total = self.tagihan - self.total_bayar self.total = self.tagihan - self.total_bayar
if self.total <= 0: if self.total <= 0:
self.total = 0 self.total = 0
self.denda = 0
return
if not self.invoice.t_tgljatuhtempospt:
self.denda = 0
return return
self.denda = hitung_denda( self.hitung_denda()
self.tagihan, self.invoice.t_tgljatuhtempospt, persen_denda) self.hitung_discount()
self.total = self.total - self.denda self.total = self.total + self.denda - self.discount
def hitung_denda(self):
if self.invoice.t_tgljatuhtempospt:
self.bln_tunggakan, denda = hitung_denda(
self.tagihan, self.invoice.t_tgljatuhtempospt,
self.persen_denda, self.tgl_bayar)
self.denda = round_up(denda)
def hitung_discount(self):
self.discount = 0
def get_profile(self): def get_profile(self):
q = DBSession.query(DetailSpt).filter_by(t_idspt=self.invoice.t_idspt) q = DBSession.query(DetailSpt).filter_by(t_idspt=self.invoice.t_idspt)
...@@ -110,6 +136,9 @@ class Inquiry: ...@@ -110,6 +136,9 @@ class Inquiry:
def get_alamat_op(self): def get_alamat_op(self):
return self.profile.t_alamatop return self.profile.t_alamatop
def get_kota_wp(self):
pass
def get_kota_op(self): def get_kota_op(self):
return self.profile.t_kabupatenop return self.profile.t_kabupatenop
...@@ -145,11 +174,10 @@ class Inquiry: ...@@ -145,11 +174,10 @@ class Inquiry:
return row.jml or 0 return row.jml or 0
def do_payment(self, ntb): def do_payment(self, ntb):
self.payment.t_tanggalpembayaran = date.today() self.payment.t_tanggalpembayaran = self.tgl_bayar
self.payment.t_nilaipembayaranspt = self.total self.payment.t_nilaipembayaranspt = self.total
self.payment.t_statusbayarspt = True self.payment.t_statusbayarspt = True
DBSession.add(self.payment) DBSession.add(self.payment)
DBSession.flush()
return self.payment return self.payment
...@@ -171,4 +199,41 @@ class Reversal: ...@@ -171,4 +199,41 @@ class Reversal:
self.payment.t_nilaipembayaranspt = 0 self.payment.t_nilaipembayaranspt = 0
self.payment.t_statusbayarspt = False self.payment.t_statusbayarspt = False
DBSession.add(self.payment) DBSession.add(self.payment)
DBSession.flush()
class AvailableInvoice(BaseAvailableInvoice):
def get_query(self):
q = DBSession.query(
Pembayaran.t_kodebayarbanksppt, Spt.t_tgljatuhtempospt).\
filter(
Pembayaran.t_idspt==Spt.t_idspt,
or_(Pembayaran.t_statusbayarspt==None,
Pembayaran.t_statusbayarspt==False))
if self.option.tahun:
q = q.filter(Spt.t_periodespt==self.option.tahun)
if self.option.belum_jatuh_tempo or self.option.lewat_jatuh_tempo:
q = q.filter(Spt.t_tgljatuhtempospt != None)
kini = date.today()
if self.option.belum_jatuh_tempo:
q = q.filter(Spt.t_tgljatuhtempospt >= kini)
else:
q = q.filter(Spt.t_tgljatuhtempospt < kini)
print('jatuh tempo')
return q.order_by(Pembayaran.t_idpembayaranspt.desc())
def get_message(self, row):
inq = Inquiry(row.t_kodebayarbanksppt, self.persen_denda)
if not inq.total:
return
msg = '{} {} {} {}'.format(
inq.invoice_id, inq.get_tahun(), inq.get_nop(),
inq.get_nama())
if inq.total_bayar:
msg = '{} Rp {} - Rp {} = Rp {}'.format(
msg, thousand(inq.tagihan), thousand(inq.total_bayar),
thousand(inq.total))
else:
msg = '{} Rp {}'.format(msg, thousand(inq.total))
if row.t_tgljatuhtempospt:
return '{} jatuh tempo {}'.format(msg, row.t_tgl_jatuhtempospt)
return msg
import sys
from configparser import ConfigParser
from argparse import ArgumentParser
from optparse import OptionParser
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
def get_option(argv):
default_count = 10
help_count = 'default {}'.format(default_count)
pars = ArgumentParser()
pars.add_argument('conf')
pars.add_argument('--tahun', type=int)
pars.add_argument('--belum-jatuh-tempo', action='store_true')
pars.add_argument('--lewat-jatuh-tempo', action='store_true')
pars.add_argument(
'--count', type=int, default=default_count, help=help_count)
return pars.parse_args(argv)
def main(argv=sys.argv):
option = get_option(argv[1:])
conf = ConfigParser()
conf.read(option.conf)
module_name = conf.get('main', 'module')
module = __import__('opensipkd.bphtb.' + module_name + '.services')
area_module = getattr(module.bphtb, module_name)
services_module = getattr(area_module, 'services')
AvailableInvoice = services_module.AvailableInvoice
db_url = conf.get('main', 'db_url')
persen_denda = conf.getfloat('main', 'persen_denda')
engine = create_engine(db_url)
session_factory = sessionmaker(bind=engine)
services_module.DBSession = session_factory()
a = AvailableInvoice(persen_denda, option)
a.show()
import sys
from datetime import datetime
from configparser import ConfigParser
from optparse import OptionParser
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
import transaction
from zope.sqlalchemy import register
from opensipkd.string.money import thousand
def show_val(label, value):
print('{}: {}'.format(label, value))
def show_rp(label, value):
show_val(label, 'Rp {}'.format(thousand(value)))
def get_option(argv):
pars = OptionParser()
pars.add_option('-i', '--invoice-id')
pars.add_option('', '--payment', action='store_true')
pars.add_option('', '--reversal', action='store_true')
return pars.parse_args(argv)
def show(inq):
show_val('Invoice ID', inq.invoice_id)
show_val('Luas Tanah', inq.get_luas_tanah())
show_val('Luas Bangunan', inq.get_luas_bangunan())
show_rp('NPOP', inq.get_npop())
show_val('Jenis Perolehan Hak', inq.get_jenis_perolehan_hak())
show_val('Alamat Objek Pajak', inq.get_alamat_op())
show_val('Kelurahan Objek Pajak', inq.get_kelurahan_op())
show_val('Kecamatan Objek Pajak', inq.get_kecamatan_op())
show_val('Kota Objek Pajak', inq.get_kota_op())
show_val('NOP', inq.get_nop())
show_rp('Tagihan', inq.tagihan)
show_rp('Denda', inq.denda)
show_rp('Discount', inq.discount)
show_rp('Total Bayar', inq.total_bayar)
show_rp('Total Tagihan', inq.total)
show_val('Nama Notaris', inq.get_nama_notaris())
show_val('Nama Wajib Pajak', inq.get_nama())
show_val('NPWP', inq.get_npwp())
show_val('Alamat Wajib Pajak', inq.get_alamat_wp())
show_val('Kelurahan Wajib Pajak', inq.get_kelurahan_wp())
show_val('Kecamatan Wajib Pajak', inq.get_kecamatan_wp())
show_val('RT Wajib Pajak', inq.get_rt_wp())
show_val('RW Wajib Pajak', inq.get_rw_wp())
show_val('Kode Pos Wajib Pajak', inq.get_kode_pos_wp())
show_val('Kota Wajib Pajak', inq.get_kota_wp())
show_val('Tahun Pajak', inq.get_tahun())
show_val('Is Available', inq.is_available())
def show_pkey_values(row):
print('Primary key tabel {}:'.format(row.__table__.name))
for c in row.__table__.columns:
if c.primary_key:
val = getattr(row, c.name)
show_val(' '+c.name, val)
def main(argv=sys.argv):
option, remain = get_option(argv[1:])
conf_file = remain[0]
invoice_id = option.invoice_id
conf = ConfigParser()
conf.read(conf_file)
db_url = conf.get('main', 'db_url')
engine = create_engine(db_url)
module_name = conf.get('main', 'module')
module = __import__('opensipkd.bphtb.' + module_name + '.services')
area_module = getattr(module.bphtb, module_name)
services_module = getattr(area_module, 'services')
AvailableInvoice = services_module.AvailableInvoice
session_factory = sessionmaker(bind=engine)
services_module.DBSession = session_factory()
register(services_module.DBSession)
inq = services_module.Inquiry(
invoice_id, conf.getfloat('main', 'persen_denda'))
if not inq.invoice:
print('Invoice ID {} tidak ada.'.format(invoice_id))
return
show(inq)
if option.payment:
if not inq.total:
print('Tidak ada tagihan, tidak ada yang perlu dibayar.')
return
ntb = datetime.now().strftime('%y%m%d%H%M%S')
with transaction.manager:
pay = inq.do_payment(ntb)
show_pkey_values(pay)
print('Berhasil dibayar')
if option.reversal:
rev = services_module.Reversal(invoice_id)
pay = rev.payment
if not pay:
print('Pembayaran tidak ditemukan, tidak ada yang perlu dibatalkan.')
return
with transaction.manager:
rev.do_reversal()
show_pkey_values(pay)
print('Berhasil dibatalkan')
from time import time
class AvailableInvoice:
def __init__(self, persen_denda=2, option=None):
self.option = option
self.count = option and option.count or 10
self.persen_denda = persen_denda
def show(self):
offset = -1
count = 0
max_count_length = len(str(self.count))
q = self.get_query()
awal = time()
while True:
if time() - awal > 10:
break
offset += 1
row = q.offset(offset).first()
if not row:
break
msg = self.get_message(row)
if not msg:
continue
count += 1
no = str(count).zfill(max_count_length)
msg = '#{}/{} {}'.format(no, self.count, msg)
print(msg)
if count == self.count:
break
def get_query(self):
pass
def get_message(self, row):
pass
# Nomor Objek Pajak
NOP = [
('Propinsi', 2, 'N'),
('Kabupaten', 2, 'N'),
('Kecamatan', 3, 'N'),
('Kelurahan', 3, 'N'),
('Blok', 3, 'N'),
('Urut', 4, 'N'),
('Jenis', 1, 'N'),
]
from datetime import datetime
from sqlalchemy import (
Column,
String,
Integer,
Date,
DateTime,
Time,
Text,
Float,
ForeignKey,
ForeignKeyConstraint,
UniqueConstraint,
)
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class Provinsi(Base):
__tablename__ = 'ref_propinsi'
kd_propinsi = Column(String(2), primary_key=True)
nm_propinsi = Column(String(30), nullable=False)
__table_args__ = dict(schema='pbb')
class Kabupaten(Base):
__tablename__ = 'ref_dati2'
kd_propinsi = Column(
String(2), ForeignKey(Provinsi.kd_propinsi), primary_key=True)
kd_dati2 = Column(String(2), primary_key=True)
nm_dati2 = Column(String(30), nullable=False)
__table_args__ = dict(schema='pbb')
class Kecamatan(Base):
__tablename__ = 'ref_kecamatan'
kd_propinsi = Column(String(2), primary_key=True)
kd_dati2 = Column(String(2), primary_key=True)
kd_kecamatan = Column(String(3), primary_key=True)
nm_kecamatan = Column(String(30), nullable=False)
__table_args__ = (
ForeignKeyConstraint([
kd_propinsi, kd_dati2],
[Kabupaten.kd_propinsi, Kabupaten.kd_dati2]),
dict(schema='pbb'))
class Kelurahan(Base):
__tablename__ = 'ref_kelurahan'
kd_propinsi = Column(String(2), primary_key=True)
kd_dati2 = Column(String(2), primary_key=True)
kd_kecamatan = Column(String(3), primary_key=True)
kd_kelurahan = Column(String(3), primary_key=True)
kd_sektor = Column(String(2), nullable=False)
nm_kelurahan = Column(String(30), nullable=False)
no_kelurahan = Column(Integer)
kd_pos_kelurahan = Column(String(5))
__table_args__ = (
ForeignKeyConstraint(
[kd_propinsi, kd_dati2, kd_kecamatan],
[Kecamatan.kd_propinsi, Kecamatan.kd_dati2,
Kecamatan.kd_kecamatan]),
dict(schema='pbb'))
class Customer(Base):
__tablename__ = 'bphtb_ppat'
id = Column(Integer, primary_key=True)
kode = Column(String(6), unique=True)
nama = Column(String(50))
alamat = Column(String(150))
kelurahan = Column(String(50))
kecamatan = Column(String(50))
kota = Column(String(50))
wilayah_kerja = Column(String(50))
kd_wilayah = Column(String(4))
no_telp = Column(String(50))
no_fax = Column(String(50))
no_sk = Column(String(50), unique=True)
tgl_sk = Column(Date)
create_uid = Column(String(20))
update_uid = Column(String(20))
created = Column(DateTime)
updated = Column(DateTime)
npwp = Column(String(20))
pejabat_id = Column(Integer)
__table_args__ = dict(schema='bphtb')
class Perolehan(Base):
__tablename__ = 'bphtb_perolehan'
id = Column(Integer, primary_key=True)
nama = Column(String(100), nullable=False)
npoptkp = Column(Integer, nullable=False)
pengurang = Column(Integer)
singkatan = Column(String(20))
__table_args__ = dict(schema='bphtb')
class Invoice(Base):
__tablename__ = 'bphtb_sspd'
id = Column(Integer, primary_key=True)
tahun = Column(Integer, nullable=False)
kode = Column(String(1), nullable=False)
no_sspd = Column(Integer, nullable=False)
ppat_id = Column(Integer, ForeignKey(Customer.id))
wp_nama = Column(String(50), nullable=False)
wp_npwp = Column(String(50), nullable=False)
wp_alamat = Column(String(100), nullable=False)
wp_blok_kav = Column(String(100), nullable=False)
wp_kelurahan = Column(String(30), nullable=False)
wp_rt = Column(String(3), nullable=False)
wp_rw = Column(String(3), nullable=False)
wp_kecamatan = Column(String(30), nullable=False)
wp_kota = Column(String(30), nullable=False)
wp_provinsi = Column(String(30), nullable=False)
wp_identitas = Column(String(50), nullable=False)
wp_identitaskd = Column(String(50))
tgl_transaksi = Column(Date, nullable=False)
kd_propinsi = Column(String(2), nullable=False)
kd_dati2 = Column(String(2), nullable=False)
kd_kecamatan = Column(String(3), nullable=False)
kd_kelurahan = Column(String(3), nullable=False)
kd_blok = Column(String(3), nullable=False)
no_urut = Column(String(4), nullable=False)
kd_jns_op = Column(String(1), nullable=False)
thn_pajak_sppt = Column(String(4), nullable=False)
op_alamat = Column(String(100), nullable=False)
op_blok_kav = Column(String(100), nullable=False)
op_rt = Column(String(3), nullable=False)
op_rw = Column(String(3), nullable=False)
bumi_luas = Column(Integer, nullable=False)
bumi_njop = Column(Integer, nullable=False)
bng_luas = Column(Integer, nullable=False)
bng_njop = Column(Integer, nullable=False)
no_sertifikat = Column(Text)
njop = Column(Integer, nullable=False)
perolehan_id = Column(Integer, ForeignKey(Perolehan.id), nullable=False)
npop = Column(Integer, nullable=False)
npoptkp = Column(Integer, nullable=False)
tarif = Column(Float, nullable=False)
terhutang = Column(Integer, nullable=False)
bagian = Column(Integer, nullable=False)
pembagi = Column(Integer, nullable=False)
tarif_pengurang = Column(Integer, nullable=False)
pengurang = Column(Integer, nullable=False)
bphtb_sudah_dibayarkan = Column(Integer, nullable=False)
denda = Column(Integer, nullable=False)
restitusi = Column(Integer, nullable=False)
bphtb_harus_dibayarkan = Column(Integer, nullable=False)
status_pembayaran = Column(Integer, nullable=False)
dasar_id = Column(Integer, nullable=False)
create_uid = Column(String(20))
update_uid = Column(String(20))
created = Column(DateTime, nullable=False)
updated = Column(DateTime, nullable=False)
header_id = Column(Integer, nullable=False)
tgl_print = Column(DateTime)
tgl_approval = Column(DateTime)
file1 = Column(String(150))
file2 = Column(String(150))
file3 = Column(String(150))
file4 = Column(String(150))
file5 = Column(String(150))
wp_kdpos = Column(String(5))
file6 = Column(String(150))
file7 = Column(String(150))
file8 = Column(String(150))
file9 = Column(String(150))
file10 = Column(String(150))
keterangan = Column(String(100))
status_daftar = Column(Integer)
persen_pengurang_sendiri = Column(Integer)
pp_nomor_pengurang_sendiri = Column(String(50))
no_ajb = Column(String(50))
tgl_ajb = Column(DateTime)
wp_nama_asal = Column(String(50))
jml_pph = Column(Float)
tgl_pph = Column(DateTime)
posted = Column(Integer)
pos_tp_id = Column(Integer)
status_validasi = Column(Integer)
status_bpn = Column(Integer)
tgl_jatuh_tempo = Column(DateTime)
verifikasi_uid = Column(String(20))
verifikasi_date = Column(DateTime)
pbb_nop = Column(String(24))
verifikasi_bphtb_uid = Column(String(20))
verifikasi_bphtb_date = Column(DateTime)
hasil_penelitian = Column(String(20))
no_sk = Column(String(20))
pengurangan_sk = Column(String(20))
pengurangan_jatuh_tempo_tgl = Column(DateTime)
pengurangan_sk_tgl = Column(DateTime)
ketetapan_no = Column(String(20))
ketetapan_tgl = Column(DateTime)
ketetapan_atas_sspd_no = Column(String(20))
ketetapan_jatuh_tempo_tgl = Column(DateTime)
pembayaran_ke = Column(Integer, nullable=False)
mutasi_penuh = Column(Integer)
npopkp = Column(Integer)
harga_transaksi = Column(Integer)
npoptkp_sudah_didapat = Column(Integer)
wp_handphone = Column(String(15))
wp_npwp_asal = Column(String(50))
bng_luas_beban = Column(Integer, nullable=False)
bng_njop_beban = Column(Integer, nullable=False)
bumi_luas_beban = Column(Integer, nullable=False)
bumi_njop_beban = Column(Integer, nullable=False)
bphtb_sudah_dibayarkan_tgl = Column(Date)
wp_identitas_asal = Column(String(25))
wp_identitaskd_asal = Column(String(25))
wp_alamat_asal = Column(String(25))
wp_blok_kav_asal = Column(String(25))
wp_rt_asal = Column(String(3))
wp_rw_asal = Column(String(3))
wp_provinsi_asal = Column(String(30))
wp_kota_asal = Column(String(30))
wp_kecamatan_asal = Column(String(30))
wp_kelurahan_asal = Column(String(30))
wp_kdpos_asal = Column(String(30))
wp_status_hak_id = Column(Integer)
no_transaksi = Column(String(50))
no_sequence = Column(String(50))
__table_args__ = (
UniqueConstraint('tahun', 'kode', 'no_sspd'),
dict(schema='bphtb'))
class Payment(Base):
__tablename__ = 'bphtb_bank'
id = Column(Integer, primary_key=True)
tanggal = Column(Date, nullable=False)
jam = Column(Time, nullable=False)
seq = Column(Integer, nullable=False)
transno = Column(String(20), nullable=False)
cabang = Column(String(5))
users = Column(String(10))
bankid = Column(Integer, nullable=False)
txs = Column(String(5), nullable=False)
sspd_id = Column(Integer)
nop = Column(String(50), nullable=False)
tahun = Column(Integer)
kd_propinsi = Column(String(2))
kd_dati2 = Column(String(2))
kd_kecamatan = Column(String(3))
kd_kelurahan = Column(String(3))
kd_blok = Column(String(3))
no_urut = Column(String(4))
kd_jns_op = Column(String(1))
thn_pajak_sppt = Column(String(4))
wp_nama = Column(String(50), nullable=False)
wp_alamat = Column(String(100))
wp_blok_kav = Column(String(100))
wp_rt = Column(String(3))
wp_rw = Column(String(3))
wp_kelurahan = Column(String(30))
wp_kecamatan = Column(String(30))
wp_kota = Column(String(30))
wp_provinsi = Column(String(50))
wp_kdpos = Column(String(5))
wp_identitas = Column(String(50))
wp_identitaskd = Column(String(50))
wp_npwp = Column(String(50))
notaris = Column(String(50))
bumi_luas = Column(Integer)
bumi_njop = Column(Integer)
bng_luas = Column(Integer)
bng_njop = Column(Integer)
npop = Column(Integer)
bayar = Column(Integer)
denda = Column(Integer)
bphtbjeniskd = Column(Integer)
is_validated = Column(Integer)
no_tagihan = Column(String(50))
catatan = Column(String(255))
kd_kanwil = Column(String(2))
kd_kantor = Column(String(2))
kd_bank_tunggal = Column(String(2))
kd_bank_persepsi = Column(String(2))
wp_propinsi = Column(String(100))
pembayaran_ke = Column(Integer, nullable=False)
__table_args__ = (
UniqueConstraint('tanggal', 'jam', 'seq', 'transno'),
dict(schema='bphtb'))
class IsoPayment(Base):
__tablename__ = 'bphtb_payment'
id = Column(Integer, ForeignKey(Payment.id), primary_key=True)
tgl = Column(DateTime(timezone=True), nullable=False, default=datetime.now)
iso_request = Column(String(1024), nullable=False)
transmission = Column(DateTime(timezone=True), nullable=False)
settlement = Column(Date, nullable=False)
stan = Column(Integer, nullable=False)
invoice_id = Column(Integer, ForeignKey(Invoice.id), nullable=False)
invoice_no = Column(String(32), nullable=False)
ntb = Column(String(32), nullable=False)
ntp = Column(String(32), nullable=False, unique=True)
bank_id = Column(Integer)
channel_id = Column(Integer)
bank_ip = Column(String(15), nullable=False)
class IsoReversal(Base):
__tablename__ = 'bphtb_reversal'
id = Column(Integer, ForeignKey(IsoPayment.id), primary_key=True)
tgl = Column(DateTime(timezone=True), nullable=False)
iso_request = Column(String(1024), nullable=False)
class Config(Base):
__tablename__ = 'bphtb_config'
id = Column(Integer, primary_key=True)
nama = Column(String(32), nullable=False, unique=True)
nilai = Column(String(10), nullable=False)
from datetime import (
date,
datetime,
)
from sqlalchemy import func
from opensipkd.hitung import (
hitung_denda,
round_up,
)
from opensipkd.string import FixLength
from opensipkd.string.money import thousand
from ..services import AvailableInvoice as BaseAvailableInvoice
from ..structure import NOP
from .structure import (
INVOICE_ID,
INVOICE_ID_LENGTH,
INVOICE_ID_V2,
)
from .models import (
Invoice,
Payment,
Config,
Customer,
Kecamatan,
Kelurahan,
)
DBSession = None # override, please
def get_db_session():
return DBSession
class Common:
def __init__(self, invoice_id):
self.invoice_id = invoice_id
is_v1 = len(invoice_id) == INVOICE_ID_LENGTH
if is_v1:
self.invoice_struct = FixLength(INVOICE_ID)
else:
self.invoice_struct = FixLength(INVOICE_ID_V2)
self.invoice_struct.set_raw(invoice_id)
self.tahun = self.invoice_struct['Tahun']
if not is_v1:
self.tahun = '20' + self.tahun
self.tahun = int(self.tahun)
q = self.query_invoice()
self.invoice = q.first()
def query_invoice(self):
kode = int(self.invoice_struct['Kode'])
kode = str(kode)
return DBSession.query(Invoice).filter_by(
tahun=self.tahun, kode=kode, no_sspd=self.invoice_struct['SSPD No'])
def is_paid(self):
return self.invoice.status_pembayaran == 1
def do_payment(self):
self.invoice.status_pembayaran = 1
DBSession.add(self.invoice)
def do_reversal(self):
self.invoice.status_pembayaran = 0
DBSession.add(self.invoice)
def is_available(self):
return self.invoice.status_pembayaran == 0
def status_pembayaran(self):
return self.invoice.status_pembayaran
class Inquiry(Common):
def __init__(self, invoice_id, persen_denda=2, tgl_bayar=None):
Common.__init__(self, invoice_id)
self.persen_denda = persen_denda
if tgl_bayar:
self.tgl_bayar = tgl_bayar
else:
self.tgl_bayar = datetime.now()
self.notaris = self.get_notaris()
self.kelurahan = self.get_kelurahan()
self.kecamatan = self.get_kecamatan()
self.nop_struct = FixLength(NOP)
self.nop_struct.from_dict({
'Propinsi': self.invoice.kd_propinsi,
'Kabupaten': self.invoice.kd_dati2,
'Kecamatan': self.invoice.kd_kecamatan,
'Kelurahan': self.invoice.kd_kelurahan,
'Blok': self.invoice.kd_blok,
'Urut': self.invoice.no_urut,
'Jenis': self.invoice.kd_jns_op,
})
self.hitung()
self.paid = self.is_paid() or self.total < 1
def hitung(self):
self.total_bayar = self.get_payment_amount()
self.tagihan = self.invoice.bphtb_harus_dibayarkan - self.total_bayar
self.total = self.denda = self.discount = 0
if self.tagihan < 1:
self.tagihan = self.total = 0
return
self.tagihan = round_up(self.tagihan)
self.hitung_denda()
self.hitung_discount()
self.total = self.tagihan + self.denda - self.discount
def hitung_denda(self):
if isinstance(self.tgl_bayar, datetime):
tgl_bayar = self.tgl_bayar.date()
else:
tgl_bayar = self.tgl_bayar
self.bln_tunggakan, denda = hitung_denda(
self.tagihan, self.invoice.tgl_jatuh_tempo, self.persen_denda,
tgl_bayar)
self.denda = round_up(denda)
def hitung_discount(self):
self.discount = 0
def get_nop(self):
return self.invoice and self.nop_struct.get_raw() or ''
def get_profile(self):
q = DBSession.query(DetailSpt).filter_by(t_idspt=self.invoice.t_idspt)
return q.first()
def get_kecamatan(self):
q = DBSession.query(Kecamatan).filter_by(
kd_propinsi=self.invoice.kd_propinsi,
kd_dati2=self.invoice.kd_dati2,
kd_kecamatan=self.invoice.kd_kecamatan)
return q.first()
def get_kelurahan(self):
q = DBSession.query(Kelurahan).filter_by(
kd_propinsi=self.invoice.kd_propinsi,
kd_dati2=self.invoice.kd_dati2,
kd_kecamatan=self.invoice.kd_kecamatan,
kd_kelurahan=self.invoice.kd_kelurahan)
return q.first()
def get_notaris(self):
q = DBSession.query(Customer).filter_by(id=self.invoice.ppat_id)
return q.first()
def get_luas_tanah(self):
return self.invoice.bumi_luas
def get_luas_bangunan(self):
return self.invoice.bng_luas
def get_npop(self):
return self.invoice.npop
def get_jenis_perolehan_hak(self):
return self.invoice.perolehan_id
def get_nama_notaris(self):
if self.notaris:
return self.notaris.nama
def get_nama(self): # Nama Wajib Pajak
return self.invoice.wp_nama
def get_npwp(self):
return self.invoice.wp_npwp
def get_alamat_wp(self):
return self.invoice.wp_alamat
def get_alamat_op(self):
return self.invoice.op_alamat
def get_kota_op(self):
pass
def get_kota_wp(self):
return self.invoice.wp_kota
def get_kelurahan_wp(self):
return self.invoice.wp_kelurahan
def get_kecamatan_wp(self):
return self.invoice.wp_kecamatan
def get_rt_wp(self):
return self.invoice.wp_rt
def get_rw_wp(self):
return self.invoice.wp_rw
def get_kode_pos_wp(self):
return self.invoice.wp_kdpos and self.invoice.wp_kdpos.strip() or None
def get_identitas_wp(self):
return self.invoice.wp_identitas
def get_kelurahan_op(self):
return self.kelurahan and self.kelurahan.nm_kelurahan or None
def get_kecamatan_op(self):
return self.kecamatan and self.kecamatan.nm_kecamatan or None
def get_tahun(self):
return self.invoice.tahun
def get_jatuh_tempo(self):
if self.invoice.tgl_jatuh_tempo:
return self.invoice.tgl_jatuh_tempo.date()
def get_payment_amount(self):
q = DBSession.query(func.sum(Payment.bayar).label('total_bayar')).\
filter_by(sspd_id=self.invoice.id)
row = q.first()
return row.total_bayar or 0
def get_pay_seq(self):
q = DBSession.query(Payment).filter_by(sspd_id=self.invoice.id)
pay = q.first()
return pay and pay.pembayaran_ke + 1 or 1
# Override
def do_payment(self, ntb, bank_id=110, bit037=None, bit107=None):
Common.do_payment(self)
cust = self.get_notaris()
pay_seq = self.get_pay_seq()
inv = self.invoice
tgl_catat = datetime.now()
if not bit037:
s = tgl_catat.strftime('%Y%m%d%H%M%S')
bit037 = s[2:]
if bit107:
cabang = bit107[:4]
users = bit107[4:]
else:
cabang = users = None
pay = Payment(
tanggal=tgl_catat.date(), jam=tgl_catat.time(), seq=bit037,
transno=ntb, cabang=cabang, users=users, bankid=bank_id,
txs=inv.kode, sspd_id=inv.id, nop=self.get_nop(),
tahun=inv.tahun, kd_propinsi=inv.kd_propinsi,
kd_dati2=inv.kd_dati2, kd_kecamatan=inv.kd_kecamatan,
kd_kelurahan=inv.kd_kelurahan, kd_blok=inv.kd_blok,
no_urut=inv.no_urut, kd_jns_op=inv.kd_jns_op,
thn_pajak_sppt=inv.thn_pajak_sppt, wp_nama=inv.wp_nama,
wp_alamat=inv.wp_alamat, wp_blok_kav=inv.wp_blok_kav,
wp_rt=inv.wp_rt, wp_rw=inv.wp_rw,
wp_kelurahan=inv.wp_kelurahan, wp_kecamatan=inv.wp_kecamatan,
wp_kota=inv.wp_kota, wp_provinsi=inv.wp_provinsi,
wp_kdpos=inv.wp_kdpos, wp_identitas=inv.wp_identitas,
wp_identitaskd=inv.wp_identitaskd, wp_npwp=inv.wp_npwp,
notaris=cust.nama, bumi_luas=inv.bumi_luas,
bumi_njop=inv.bumi_njop, bng_luas=inv.bng_luas,
bng_njop=inv.bng_njop, npop=inv.npop, bayar=self.total,
denda=self.denda, bphtbjeniskd=inv.perolehan_id,
no_tagihan=self.invoice_id, pembayaran_ke=pay_seq)
DBSession.add(pay)
DBSession.flush()
return pay
class Reversal(Common):
def __init__(self, invoice_id):
Common.__init__(self, invoice_id)
self.payment = None
if not self.invoice:
return
if not self.is_available():
self.payment = self.invoice and self.get_last_payment()
def get_last_payment(self):
q = DBSession.query(Payment).filter_by(sspd_id=self.invoice.id).\
order_by(Payment.id.desc())
return q.first()
def do_reversal(self): # Override
Common.do_reversal(self)
self.payment.bayar = self.payment.denda = 0
DBSession.add(self.payment)
DBSession.flush()
class AvailableInvoice(BaseAvailableInvoice):
def get_query(self):
q = DBSession.query(Config).filter_by(nama='prefix kode bayar')
conf = q.first()
self.prefix = conf.nilai
q = DBSession.query(Invoice).filter_by(status_pembayaran=0)
if self.option.tahun:
q = q.filter_by(tahun=self.option.tahun)
if self.option.belum_jatuh_tempo or self.option.lewat_jatuh_tempo:
q = q.filter(Invoice.tgl_jatuh_tempo != None)
kini = date.today()
if self.option.belum_jatuh_tempo:
q = q.filter(Invoice.tgl_jatuh_tempo >= kini)
else:
q = q.filter(Invoice.tgl_jatuh_tempo < kini)
return q.order_by(Invoice.id.desc())
def get_message(self, row):
invoice_id_struct = FixLength(INVOICE_ID)
invoice_id_struct_v2 = FixLength(INVOICE_ID_V2)
invoice_id_struct_v2.set_raw(self.prefix)
invoice_id_struct['Tahun'] = row.tahun
invoice_id_struct_v2['Tahun'] = str(row.tahun)[2:4]
invoice_id_struct['Kode'] = invoice_id_struct_v2['Kode'] = \
row.kode.zfill(2)
invoice_id_struct['SSPD No'] = invoice_id_struct_v2['SSPD No'] = \
row.no_sspd
invoice_id = invoice_id_struct.get_raw()
invoice_id_v2 = invoice_id_struct_v2.get_raw()
inq = Inquiry(invoice_id, self.persen_denda)
inq = Inquiry(invoice_id_v2, self.persen_denda) # make sure
if inq.total < 1:
return
total = thousand(inq.total).rjust(11)
msg = '{id} {id_v2} Rp {total}'.format(
id=invoice_id, total=total, id_v2=invoice_id_v2)
if row.tgl_jatuh_tempo:
return '{} jatuh tempo {}'.format(
msg, row.tgl_jatuh_tempo.strftime('%d-%m-%Y'))
return msg
INVOICE_ID = [
['Tahun', 4, 'N'],
['Kode', 2, 'N'],
['SSPD No', 6, 'N'],
]
INVOICE_ID_LENGTH = 0
for nama, size, tipe in INVOICE_ID:
INVOICE_ID_LENGTH += size
INVOICE_ID_V2 = [
['Provinsi', 2, 'N'],
['Kabupaten', 2, 'N'],
['Jenis Pajak', 2, 'N'],
['Tahun', 2, 'N'],
['Kode', 2, 'N'],
['SSPD No', 6, 'N'],
]
INVOICE_ID_LENGTH_V2 = 0
for nama, size, tipe in INVOICE_ID_V2:
INVOICE_ID_LENGTH_V2 += size
...@@ -33,8 +33,8 @@ setuptools.setup( ...@@ -33,8 +33,8 @@ setuptools.setup(
], ],
entry_points={ entry_points={
'console_scripts': [ 'console_scripts': [
'bphtb_cilegon_available_invoice = opensipkd.bphtb.cilegon.scripts.available_invoice:main', 'bphtb_available_invoice = opensipkd.bphtb.scripts.available_invoice:main',
'bphtb_cilegon_inquiry = opensipkd.bphtb.cilegon.scripts.inquiry:main', 'bphtb_inquiry = opensipkd.bphtb.scripts.inquiry:main',
] ]
}, },
) )
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!