Commit a926cbbc by Owo Sugiana

Kali pertama

0 parents
dist
*egg-info
test-*
0.1.1 2019-07-10
----------------
- Bug fixed nomor urut pada AvailableInvoice.
0.1 2019-06-23
--------------
- Kali pertama
include *.txt devel.ini *.rst
recursive-include opensipkd *.py
recursive-include scripts *.py
Struktur Tabel BPHTB
====================
BPHTB adalah Bea Peralihan Hak atas Tanah dan Bangunan.
Paket ini selain berisi struktur tabel juga memuat query yang kerap digunakan
untuk proses:
1. inquiry (cek tagihan)
2. payment (pembayaran)
3. reversal (pembatalan pembayaran)
Uji Coba
--------
Buat file ``test-cilegon.ini`` seperti contoh berikut ini::
[main]
db_url = postgresql://sugiana:a@localhost/bphtb_cilegon
persen_denda = 2
Sesuaikanlah pada ``db_url``. Kemudian dapatkan daftar tagihan::
$ env/bin/bphtb_cilegon_available_invoice test-cilegon.ini
Nanti akan tampil seperti ini::
#1 10241 2019 36.72... ER*** Rp 1.465.200
#2 10356 2019 36.72... JU*** Rp 1.500.000
#3 10361 2019 36.72... MU*** Rp 1.500.000
Kolom kedua adalah Invoice ID atau sering disebut sebagai nomor bayar. Nomor
ini bekal untuk inquiry atau cek tagihan::
$ env/bin/bphtb_cilegon_inquiry test-cilegon.ini --invoice-id=10241
Untuk melanjutkan pembayaran tambahkan opsi ``--payment``::
$ env/bin/bphtb_cilegon_inquiry test-cilegon.ini --invoice-id=10241 --payment
Sedangkan untuk membatalkannya tambahkan opsi ``--reversal``::
$ env/bin/bphtb_cilegon_inquiry test-cilegon.ini --invoice-id=10241 --reversal
Selamat mencoba, semoga berhasil.
[main]
db_url = postgresql://username:password@localhost/database
persen_denda = 2
File mode changed
from sqlalchemy import (
Column,
Integer,
BigInteger,
Date,
Text,
Float,
String,
Boolean,
ForeignKey,
)
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class JenisTransaksi(Base):
__tablename__ = 's_jenistransaksi'
s_idjenistransaksi = Column(Integer, primary_key=True)
s_namajenistransaksi = Column(String(200), unique=True)
class User(Base):
__tablename__ = 's_users'
s_iduser = Column(Integer, primary_key=True)
s_idpejabat_idnotaris = Column(Text)
class Notaris(Base):
__tablename__ = 's_notaris'
s_idnotaris = Column(Integer, primary_key=True)
s_namanotaris = Column(Text, nullable=False)
s_alamatnotaris = Column(Text)
s_kodenotaris = Column(Text)
s_sknotaris = Column(String(50))
s_tgl1notaris = Column(Date)
s_tgl2notaris = Column(Date)
s_statusnotaris = Column(Integer)
class Spt(Base):
__tablename__ = 't_spt'
t_idspt = Column(Integer, primary_key=True)
t_kohirspt = Column(Integer)
t_kohirketetapanspt = Column(Integer)
t_tglprosesspt = Column(Date)
t_periodespt = Column(Integer, nullable=False)
t_idnotarisspt = Column(Integer)
t_objekspt = Column(Integer)
t_idtarifspt = Column(Integer)
t_ketetapanspt = Column(Integer)
t_tglketetapanspt = Column(Date)
t_tgljatuhtempospt = Column(Date, nullable=False)
t_nopbphtbsppt = Column(Text, nullable=False)
t_kodebayarbanksppt = Column(Text)
t_idjenistransaksi = Column(
Integer, ForeignKey(JenisTransaksi.s_idjenistransaksi), nullable=False)
t_idjenishaktanah = Column(Integer)
t_idrefspt = Column(Integer)
t_pejabatverifikasispt = Column(Integer)
t_dasarspt = Column(Integer)
t_totalspt = Column(BigInteger, nullable=False)
t_nilaitransaksispt = Column(BigInteger)
t_potonganspt = Column(Integer)
t_thnsppt = Column(Text)
t_persyaratan = Column(Text)
t_idjenisdoktanah = Column(Integer)
t_idsptsebelumnya = Column(Integer)
t_pejabatpendaftaranspt = Column(Integer)
t_idtarifbphtb = Column(Integer)
t_input_sismiop = Column(Integer)
t_iduser_sismiop = Column(Integer)
t_tglproses_sismiop = Column(Date)
t_tarif_pembagian_aphb_kali = Column(Integer)
t_tarif_pembagian_aphb_bagi = Column(Integer)
t_persenbphtb = Column(Float)
fr_tervalidasidua = Column(Integer)
t_potongan_waris_hibahwasiat = Column(Float)
t_sisa_potongan_npoptkp = Column(Float)
id_pendataan_old = Column(Integer)
ntpd = Column(String(100))
class DetailSpt(Base):
__tablename__ = 't_detailsptbphtb'
t_iddetailsptbphtb = Column(Integer, primary_key=True)
t_idspt = Column(Integer, ForeignKey(Spt.t_idspt), nullable=False)
t_namawppembeli = Column(Text, nullable=False)
t_nikwppembeli = Column(Text)
t_alamatwppembeli = Column(Text, nullable=False)
t_kecamatanwppembeli = Column(Text, nullable=False)
t_kelurahanwppembeli = Column(Text, nullable=False)
t_kabkotawppembeli = Column(Text, nullable=False)
t_telponwppembeli = Column(Text)
t_kodeposwppembeli = Column(Text)
t_npwpwppembeli = Column(Text)
t_namawppenjual = Column(Text)
t_nikwppenjual = Column(Text)
t_alamatwppenjual = Column(Text)
t_kecamatanwppenjual = Column(Text)
t_kelurahanwppenjual = Column(Text)
t_kabkotawppenjual = Column(Text)
t_telponwppenjual = Column(Text)
t_kodeposwppenjual = Column(Text)
t_npwpwppenjual = Column(Text)
t_luastanah = Column(Float)
t_njoptanah = Column(Integer)
t_luasbangunan = Column(Float)
t_njopbangunan = Column(Integer)
t_totalnjoptanah = Column(Integer)
t_totalnjopbangunan = Column(Integer)
t_grandtotalnjop = Column(Integer)
t_nosertifikathaktanah = Column(String(30))
t_kelurahanop = Column(String(30))
t_kecamatanop = Column(String(30))
t_ketwaris = Column(String(200))
t_terbukti = Column(String(10))
t_rtwppembeli = Column(Text)
t_rwwppembeli = Column(Text)
t_alamatop = Column(Text)
t_rtop = Column(String(3))
t_rwop = Column(String(3))
t_dokpersyaratan = Column(Text)
t_namasppt = Column(Text)
t_tglajb = Column(Date)
t_luastanahbpn = Column(Float)
t_luasbangunanbpn = Column(Float)
t_tglajbbaru = Column(Date)
t_noajbbaru = Column(Text)
t_statuspelaporannotaris = Column(Boolean)
t_tglpelaporannotaris = Column(Date)
t_kabupatenop = Column(Text)
t_rtwppenjual = Column(Text)
t_rwwppenjual = Column(Text)
t_nosertifikatbaru = Column(String(10))
t_tglsertifikatbaru = Column(Date)
t_inputbpn = Column(Boolean)
t_statuskonfirmasinotaris = Column(Boolean)
t_tglkonfirmasinotaris = Column(Date)
t_luastanah_sismiop = Column(Float)
t_luasbangunan_sismiop = Column(Float)
t_njoptanah_sismiop = Column(Integer)
t_njopbangunan_sismiop = Column(Integer)
t_grandtotalnjop_aphb = Column(Integer)
fr_luas_tanah_bpn = Column(Float)
fr_luas_bangunan_bpn = Column(Float)
fr_validasidua = Column(Integer)
t_namaibuwppembeli = Column(Text)
t_nosertifikattanah = Column(Text)
class Pembayaran(Base):
__tablename__ = 't_pembayaranspt'
t_idpembayaranspt = Column(Integer, primary_key=True)
t_idspt = Column(
Integer, ForeignKey(Spt.t_idspt), nullable=False)
t_kohirpembayaran = Column(Integer)
t_periodepembayaran = Column(Integer)
t_tanggalpembayaran = Column(Date, nullable=False)
t_objekspt = Column(Integer)
t_idnotaris = Column(Integer)
t_ketetapanspt = Column(Integer)
t_nilaipembayaranspt = Column(Integer, nullable=False)
t_idkorekspt = Column(Integer)
t_kodebayarspt = Column(Text)
t_verifikasispt = Column(Text)
t_tglverifikasispt = Column(Date)
t_pejabatverifikasispt = Column(Integer)
t_statusbayarspt = Column(Boolean, nullable=False)
t_kodebayarbanksppt = Column(Text, nullable=False)
t_dendabulan = Column(Integer)
t_pejabatpembayaranspt = Column(Integer)
t_idds = Column(Integer)
t_idpenerimasetoran = Column(Integer)
import sys
import locale
from time import time
from configparser import ConfigParser
from sqlalchemy import create_engine
from opensipkd.base.models import DBSession
from opensipkd.bphtb.cilegon.models import (
Spt,
DetailSpt,
)
import opensipkd.bphtb.cilegon.services
opensipkd.bphtb.cilegon.services.DBSession = DBSession
locale.setlocale(locale.LC_ALL, 'id_ID.utf8')
registry = dict()
Inquiry = opensipkd.bphtb.cilegon.services.Inquiry
def thousand(n):
return locale.format('%.0f', n, True)
class AvailableInvoice:
def __init__(self, count=10):
self.count = count
def run(self):
q_inv = DBSession.query(Spt).filter(Spt.t_totalspt > 0).\
order_by(Spt.t_periodespt.desc(), Spt.t_totalspt, Spt.t_idspt)
offset = -1
self.no = 0
awal = time()
while True:
offset += 1
inv = q_inv.offset(offset).limit(1).first()
if not inv:
break
self.row_handler(inv)
if time() - awal > 10:
break
if self.no == self.count:
break
def row_handler(self, inv):
inq = Inquiry(inv.t_idspt, registry['persen_denda'])
if not inq.total:
return
self.no += 1
nominal = thousand(inq.total)
q = DBSession.query(DetailSpt).filter_by(t_idspt=inv.t_idspt)
op = q.first()
msg = '#{} {} {} {} {} Rp {}'.format(
self.no, inv.t_idspt, inv.t_periodespt, inv.t_nopbphtbsppt,
op.t_namawppembeli, nominal)
print(msg)
def main(argv=sys.argv):
conf_file = argv[1]
conf = ConfigParser()
conf.read(conf_file)
db_url = conf.get('main', 'db_url')
engine = create_engine(db_url)
DBSession.configure(bind=engine)
registry['persen_denda'] = conf.getfloat('main', 'persen_denda')
a = AvailableInvoice()
a.run()
import sys
import locale
import transaction
from datetime import datetime
from configparser import ConfigParser
from optparse import OptionParser
from sqlalchemy import (
create_engine,
func,
)
from opensipkd.hitung import hitung_denda
from opensipkd.base.models import DBSession
from opensipkd.bphtb.cilegon.models import (
Spt,
DetailSpt,
Pembayaran,
)
import opensipkd.bphtb.cilegon.services
from opensipkd.bphtb.cilegon.services import (
Inquiry,
Reversal,
)
opensipkd.bphtb.cilegon.services.DBSession = DBSession
locale.setlocale(locale.LC_ALL, 'id_ID.utf8')
def thousand(n):
return locale.format('%.0f', n, True)
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', type='int')
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('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('Tahun Pajak', inq.get_tahun())
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)
DBSession.configure(bind=engine)
with transaction.manager:
inq = 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')
pay = inq.do_payment(ntb)
print(
'Berhasil dibayar dengan ID pembayaran {}'.format(
pay.t_idpembayaranspt))
if option.reversal:
rev = Reversal(invoice_id)
pay = rev.payment
if not pay:
print('Belum ada pembayaran, tidak ada yang perlu dibatalkan.')
return
if not pay.t_statusbayarspt:
print(
'ID Pembayaran {} sudah dibatalkan.'.format(
pay.t_idpembayaranspt))
return
rev.do_reversal()
print(
'ID Pembayaran {} berhasil dibatalkan'.format(
pay.t_idpembayaranspt))
from datetime import date
from sqlalchemy import func
from sqlalchemy.orm import sessionmaker
from opensipkd.bphtb.cilegon.models import (
Spt,
DetailSpt,
Pembayaran,
Notaris,
User,
)
from opensipkd.hitung import hitung_denda
DBSession = None # override, please
class Inquiry:
def __init__(self, invoice_id, persen_denda=2):
self.invoice_id = invoice_id
q = DBSession.query(Spt).filter_by(t_idspt=invoice_id)
self.invoice = q.first()
if not self.invoice:
return
self.profile = self.get_profile()
self.notaris = self.get_notaris()
self.total_bayar = self.get_payment_amount()
self.tagihan = self.invoice.t_totalspt
self.total = self.tagihan - self.total_bayar
if self.total <= 0:
self.total = 0
self.denda = 0
return
if not self.invoice.t_tgljatuhtempospt:
self.denda = 0
return
self.denda = hitung_denda(
self.tagihan, self.invoice.t_tgljatuhtempospt, persen_denda)
self.total = self.total - self.denda
def get_profile(self):
q = DBSession.query(DetailSpt).filter_by(t_idspt=self.invoice_id)
return q.first()
def get_notaris(self):
q = DBSession.query(User).filter_by(
s_iduser=self.invoice.t_idnotarisspt)
user = q.first()
if not user:
return
notaris_id = int(user.s_idpejabat_idnotaris)
q = DBSession.query(Notaris).filter_by(s_idnotaris=notaris_id)
return q.first()
def get_nop(self):
return self.invoice.t_nopbphtbsppt.replace('.', '')
def get_luas_tanah(self):
return self.profile.t_luastanah
def get_luas_bangunan(self):
return self.profile.t_luasbangunan
def get_npop(self):
return self.profile.t_grandtotalnjop
def get_jenis_perolehan_hak(self):
return self.invoice.t_idjenistransaksi
def get_nama_notaris(self):
if self.notaris:
return self.notaris.s_namanotaris
def get_nama(self):
return self.profile.t_namawppembeli
def get_npwp(self):
return self.profile.t_npwpwppembeli
def get_alamat_wp(self):
return self.profile.t_alamatwppembeli
def get_alamat_op(self):
return self.profile.t_alamatop
def get_kota_op(self):
return self.profile.t_kabupatenop
def get_kelurahan_wp(self):
return self.profile.t_kelurahanwppembeli
def get_kecamatan_wp(self):
return self.profile.t_kecamatanwppembeli
def get_rt_wp(self):
return self.profile.t_rtwppembeli
def get_rw_wp(self):
return self.profile.t_rwwppembeli
def get_kode_pos_wp(self):
return self.profile.t_kodeposwppembeli
def get_kelurahan_op(self):
return self.profile.t_kelurahanop
def get_kecamatan_op(self):
return self.profile.t_kecamatanop
def get_tahun(self):
return self.invoice.t_periodespt
def get_payment_amount(self):
q = DBSession.query(
func.sum(Pembayaran.t_nilaipembayaranspt).label('jml'))
q = q.filter_by(t_idspt=self.invoice_id, t_statusbayarspt=True)
row = q.first()
return row.jml or 0
def do_payment(self, ntb):
pay = Pembayaran(t_idspt=self.invoice_id)
pay.t_tanggalpembayaran = date.today()
pay.t_nilaipembayaranspt = self.total
pay.t_statusbayarspt = True
pay.t_kodebayarbanksppt = ntb
DBSession.add(pay)
DBSession.flush()
return pay
class Reversal:
def __init__(self, invoice_id):
self.invoice_id = invoice_id
self.payment = self.get_last_payment()
def get_last_payment(self):
q = DBSession.query(Pembayaran)
q = q.filter_by(t_idspt=self.invoice_id)
q = q.order_by(Pembayaran.t_idpembayaranspt.desc())
return q.first()
def do_reversal(self):
self.payment.t_tanggalpembayaran = None
self.payment.t_nilaipembayaranspt = 0
self.payment.t_statusbayarspt = False
DBSession.add(self.payment)
DBSession.flush()
import os
import setuptools
with open('README.rst') as f:
long_description = f.read()
with open('CHANGES.txt') as f:
CHANGES = f.read()
line = CHANGES.splitlines()[0]
version = line.split()[0]
requires = [
'sqlalchemy',
'opensipkd-base @ git+https://git.opensipkd.com/sugiana/opensipkd-base',
]
setuptools.setup(
name='opensipkd-bphtb-models',
version=version,
author='Owo Sugiana',
author_email='sugiana@gmail.com',
description='Struktur tabel ISO 8583',
long_description=long_description,
long_description_content_type='text/markdown',
license='PostgreSQL License',
install_requires=requires,
packages=setuptools.find_packages(),
classifiers=[
'Programming Language :: Python :: 3',
'Operating System :: OS Independent',
],
entry_points={
'console_scripts': [
'bphtb_cilegon_available_invoice = opensipkd.bphtb.cilegon.scripts.available_invoice:main',
'bphtb_cilegon_inquiry = opensipkd.bphtb.cilegon.scripts.inquiry:main',
]
},
)
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!